Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: airoha: driver fixes & improvements

Merge series from Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>:

This patch series greatly improve airoha snfi driver and fix a
number of serious bugs.

Fixed bugs:
* Fix reading/writing of flashes with more than one plane per lun
* Fill the buffer with 0xff before writing
* Fix reading of flashes supporting continuous reading mode
* Fix error paths

Improvements:
* Add support of dual/quad wires spi modes in exec_op(). This also
fix flash reading/writing if dirmap can't be created.
* Support of dualio/quadio flash reading commands
* Remove dirty hack that reads flash page settings from SNFI registers
during driver startup
* Add support of EN7523 SoC

Patched kernel tests:

root@OpenWrt:/lib/modules/6.6.79# insmod mtd_oobtest.ko dev=1
[ 263.191711]
[ 263.193218] =================================================
[ 263.199014] mtd_oobtest: MTD device: 1
[ 263.202768] mtd_oobtest: MTD device size 268304384, eraseblock size 131072, page size 2048, count of eraseblocks 2047, pages per eraseblock 64, OOB size 128
[ 263.216791] mtd_test: scanning for bad eraseblocks
[ 263.221956] mtd_test: scanned 2047 eraseblocks, 0 are bad
[ 263.227361] mtd_oobtest: test 1 of 5
[ 265.077216] mtd_oobtest: writing OOBs of whole device
[ 265.121767] mtd_oobtest: written up to eraseblock 0
[ 275.174147] mtd_oobtest: written up to eraseblock 256
[ 285.210279] mtd_oobtest: written up to eraseblock 512
[ 295.241724] mtd_oobtest: written up to eraseblock 768
[ 305.280167] mtd_oobtest: written up to eraseblock 1024
[ 315.326883] mtd_oobtest: written up to eraseblock 1280
[ 325.364049] mtd_oobtest: written up to eraseblock 1536
[ 335.398609] mtd_oobtest: written up to eraseblock 1792
[ 345.358981] mtd_oobtest: written 2047 eraseblocks
[ 345.363694] mtd_oobtest: verifying all eraseblocks
[ 345.386088] mtd_oobtest: verified up to eraseblock 0
[ 349.830833] mtd_oobtest: verified up to eraseblock 256
[ 354.276245] mtd_oobtest: verified up to eraseblock 512
[ 358.721496] mtd_oobtest: verified up to eraseblock 768
[ 363.166881] mtd_oobtest: verified up to eraseblock 1024
[ 367.612694] mtd_oobtest: verified up to eraseblock 1280
[ 372.058211] mtd_oobtest: verified up to eraseblock 1536
[ 376.503820] mtd_oobtest: verified up to eraseblock 1792
[ 380.914843] mtd_oobtest: verified 2047 eraseblocks
[ 380.919660] mtd_oobtest: test 2 of 5
[ 384.202620] mtd_oobtest: writing OOBs of whole device
[ 384.247584] mtd_oobtest: written up to eraseblock 0
[ 394.305121] mtd_oobtest: written up to eraseblock 256
[ 404.342199] mtd_oobtest: written up to eraseblock 512
[ 414.374204] mtd_oobtest: written up to eraseblock 768
[ 424.409891] mtd_oobtest: written up to eraseblock 1024
[ 434.453378] mtd_oobtest: written up to eraseblock 1280
[ 444.494321] mtd_oobtest: written up to eraseblock 1536
[ 454.534480] mtd_oobtest: written up to eraseblock 1792
[ 464.490962] mtd_oobtest: written 2047 eraseblocks
[ 464.495681] mtd_oobtest: verifying all eraseblocks
[ 464.518015] mtd_oobtest: verified up to eraseblock 0
[ 468.955635] mtd_oobtest: verified up to eraseblock 256
[ 473.395502] mtd_oobtest: verified up to eraseblock 512
[ 477.834373] mtd_oobtest: verified up to eraseblock 768
[ 482.272717] mtd_oobtest: verified up to eraseblock 1024
[ 486.712148] mtd_oobtest: verified up to eraseblock 1280
[ 491.150704] mtd_oobtest: verified up to eraseblock 1536
[ 495.589439] mtd_oobtest: verified up to eraseblock 1792
[ 499.993138] mtd_oobtest: verified 2047 eraseblocks
[ 499.997951] mtd_oobtest: test 3 of 5
[ 503.404228] mtd_oobtest: writing OOBs of whole device
[ 503.448822] mtd_oobtest: written up to eraseblock 0
[ 513.480773] mtd_oobtest: written up to eraseblock 256
[ 523.489361] mtd_oobtest: written up to eraseblock 512
[ 533.506896] mtd_oobtest: written up to eraseblock 768
[ 543.506268] mtd_oobtest: written up to eraseblock 1024
[ 553.506503] mtd_oobtest: written up to eraseblock 1280
[ 563.511266] mtd_oobtest: written up to eraseblock 1536
[ 573.519567] mtd_oobtest: written up to eraseblock 1792
[ 583.455111] mtd_oobtest: written 2047 eraseblocks
[ 583.459837] mtd_oobtest: verifying all eraseblocks
[ 583.499358] mtd_oobtest: verified up to eraseblock 0
[ 592.382953] mtd_oobtest: verified up to eraseblock 256
[ 601.267297] mtd_oobtest: verified up to eraseblock 512
[ 610.150907] mtd_oobtest: verified up to eraseblock 768
[ 619.034702] mtd_oobtest: verified up to eraseblock 1024
[ 627.919683] mtd_oobtest: verified up to eraseblock 1280
[ 636.821168] mtd_oobtest: verified up to eraseblock 1536
[ 645.705487] mtd_oobtest: verified up to eraseblock 1792
[ 654.520336] mtd_oobtest: verified 2047 eraseblocks
[ 654.525134] mtd_oobtest: test 4 of 5
[ 657.578146] mtd_oobtest: attempting to start write past end of OOB
[ 657.584336] mtd_oobtest: an error is expected...
[ 657.588974] mtd_oobtest: error occurred as expected
[ 657.593848] mtd_oobtest: attempting to start read past end of OOB
[ 657.599953] mtd_oobtest: an error is expected...
[ 657.604569] mtd_oobtest: error occurred as expected
[ 657.609450] mtd_oobtest: attempting to write past end of device
[ 657.615367] mtd_oobtest: an error is expected...
[ 657.619990] mtd_oobtest: error occurred as expected
[ 657.624864] mtd_oobtest: attempting to read past end of device
[ 657.630715] mtd_oobtest: an error is expected...
[ 657.635333] mtd_oobtest: error occurred as expected
[ 657.641043] mtd_oobtest: attempting to write past end of device
[ 657.646966] mtd_oobtest: an error is expected...
[ 657.651574] mtd_oobtest: error occurred as expected
[ 657.656451] mtd_oobtest: attempting to read past end of device
[ 657.662277] mtd_oobtest: an error is expected...
[ 657.666901] mtd_oobtest: error occurred as expected
[ 657.671774] mtd_oobtest: test 5 of 5
[ 659.382333] mtd_oobtest: writing OOBs of whole device
[ 659.388056] mtd_oobtest: written up to eraseblock 0
[ 659.393526] mtd_oobtest: written up to eraseblock 0
[ 659.704525] mtd_oobtest: written up to eraseblock 256
[ 659.710187] mtd_oobtest: written up to eraseblock 256
[ 660.021093] mtd_oobtest: written up to eraseblock 512
[ 660.026752] mtd_oobtest: written up to eraseblock 512
[ 660.338427] mtd_oobtest: written up to eraseblock 768
[ 660.344048] mtd_oobtest: written up to eraseblock 768
[ 660.655718] mtd_oobtest: written up to eraseblock 1024
[ 660.661462] mtd_oobtest: written up to eraseblock 1024
[ 660.970676] mtd_oobtest: written up to eraseblock 1280
[ 660.976386] mtd_oobtest: written up to eraseblock 1280
[ 661.286858] mtd_oobtest: written up to eraseblock 1536
[ 661.292587] mtd_oobtest: written up to eraseblock 1536
[ 661.605397] mtd_oobtest: written up to eraseblock 1792
[ 661.611142] mtd_oobtest: written up to eraseblock 1792
[ 661.918754] mtd_oobtest: written 2046 eraseblocks
[ 661.923458] mtd_oobtest: verifying all eraseblocks
[ 661.928812] mtd_oobtest: verified up to eraseblock 0
[ 662.072499] mtd_oobtest: verified up to eraseblock 256
[ 662.216152] mtd_oobtest: verified up to eraseblock 512
[ 662.359956] mtd_oobtest: verified up to eraseblock 768
[ 662.503238] mtd_oobtest: verified up to eraseblock 1024
[ 662.646847] mtd_oobtest: verified up to eraseblock 1280
[ 662.790603] mtd_oobtest: verified up to eraseblock 1536
[ 662.934269] mtd_oobtest: verified up to eraseblock 1792
[ 663.076329] mtd_oobtest: verified 2046 eraseblocks
[ 663.081114] mtd_oobtest: finished with 0 errors
[ 663.085647] =================================================

root@OpenWrt:/lib/modules/6.6.79# insmod mtd_pagetest.ko dev=1
[ 1142.213082]
[ 1142.214590] =================================================
[ 1142.220433] mtd_pagetest: MTD device: 1
[ 1142.224278] mtd_pagetest: MTD device size 268304384, eraseblock size 131072, page size 2048, count of eraseblocks 2047, pages per eraseblock 64, OOB size 128
[ 1142.238388] mtd_test: scanning for bad eraseblocks
[ 1142.243536] mtd_test: scanned 2047 eraseblocks, 0 are bad
[ 1142.248935] mtd_pagetest: erasing whole device
[ 1143.962562] mtd_pagetest: erased 2047 eraseblocks
[ 1143.967301] mtd_pagetest: writing whole device
[ 1144.011729] mtd_pagetest: written up to eraseblock 0
[ 1154.137933] mtd_pagetest: written up to eraseblock 256
[ 1164.265201] mtd_pagetest: written up to eraseblock 512
[ 1174.393365] mtd_pagetest: written up to eraseblock 768
[ 1184.525700] mtd_pagetest: written up to eraseblock 1024
[ 1194.650920] mtd_pagetest: written up to eraseblock 1280
[ 1204.773676] mtd_pagetest: written up to eraseblock 1536
[ 1214.896934] mtd_pagetest: written up to eraseblock 1792
[ 1224.942600] mtd_pagetest: written 2047 eraseblocks
[ 1224.947410] mtd_pagetest: verifying all eraseblocks
[ 1225.053133] mtd_pagetest: verified up to eraseblock 0
[ 1250.760034] mtd_pagetest: verified up to eraseblock 256
[ 1276.448242] mtd_pagetest: verified up to eraseblock 512
[ 1302.138825] mtd_pagetest: verified up to eraseblock 768
[ 1327.824020] mtd_pagetest: verified up to eraseblock 1024
[ 1353.532178] mtd_pagetest: verified up to eraseblock 1280
[ 1379.234385] mtd_pagetest: verified up to eraseblock 1536
[ 1404.943865] mtd_pagetest: verified up to eraseblock 1792
[ 1430.468816] mtd_pagetest: verified 2047 eraseblocks
[ 1430.473702] mtd_pagetest: crosstest
[ 1430.477717] mtd_pagetest: reading page at 0x0
[ 1430.482328] mtd_pagetest: reading page at 0xffdf800
[ 1430.487469] mtd_pagetest: reading page at 0x0
[ 1430.492084] mtd_pagetest: verifying pages read at 0x0 match
[ 1430.497668] mtd_pagetest: crosstest ok
[ 1430.501409] mtd_pagetest: erasecrosstest
[ 1430.505323] mtd_pagetest: erasing block 0
[ 1430.511511] mtd_pagetest: writing 1st page of block 0
[ 1430.517166] mtd_pagetest: reading 1st page of block 0
[ 1430.522505] mtd_pagetest: verifying 1st page of block 0
[ 1430.527739] mtd_pagetest: erasing block 0
[ 1430.532565] mtd_pagetest: writing 1st page of block 0
[ 1430.538229] mtd_pagetest: erasing block 2046
[ 1430.544181] mtd_pagetest: reading 1st page of block 0
[ 1430.549498] mtd_pagetest: verifying 1st page of block 0
[ 1430.554718] mtd_pagetest: erasecrosstest ok
[ 1430.558900] mtd_pagetest: erasetest
[ 1430.562381] mtd_pagetest: erasing block 0
[ 1430.567208] mtd_pagetest: writing 1st page of block 0
[ 1430.572858] mtd_pagetest: erasing block 0
[ 1430.577680] mtd_pagetest: reading 1st page of block 0
[ 1430.582990] mtd_pagetest: verifying 1st page of block 0 is all 0xff
[ 1430.589279] mtd_pagetest: erasetest ok
[ 1430.593023] mtd_pagetest: finished with 0 errors
[ 1430.597651] =================================================

root@OpenWrt:/lib/modules/6.6.79# insmod mtd_readtest.ko dev=1
[ 1478.691648]
[ 1478.693158] =================================================
[ 1478.698981] mtd_readtest: MTD device: 1
[ 1478.702829] mtd_readtest: MTD device size 268304384, eraseblock size 131072, page size 2048, count of eraseblocks 2047, pages per eraseblock 64, OOB size 128
[ 1478.716939] mtd_test: scanning for bad eraseblocks
[ 1478.722072] mtd_test: scanned 2047 eraseblocks, 0 are bad
[ 1478.727475] mtd_readtest: testing page read
[ 1548.352125] mtd_readtest: finished
[ 1548.355553] =================================================

root@OpenWrt:/lib/modules/6.6.79# insmod mtd_speedtest.ko dev=1
[ 1617.353002]
[ 1617.354511] =================================================
[ 1617.360332] mtd_speedtest: MTD device: 1
[ 1617.364258] mtd_speedtest: MTD device size 268304384, eraseblock size 131072, page size 2048, count of eraseblocks 2047, pages per eraseblock 64, OOB size 128
[ 1617.380150] mtd_test: scanning for bad eraseblocks
[ 1617.385428] mtd_test: scanned 2047 eraseblocks, 0 are bad
[ 1621.021861] mtd_speedtest: testing eraseblock write speed
[ 1700.915306] mtd_speedtest: eraseblock write speed is 3279 KiB/s
[ 1700.921250] mtd_speedtest: testing eraseblock read speed
[ 1734.931886] mtd_speedtest: eraseblock read speed is 7705 KiB/s
[ 1738.682742] mtd_speedtest: testing page write speed
[ 1818.818644] mtd_speedtest: page write speed is 3269 KiB/s
[ 1818.824058] mtd_speedtest: testing page read speed
[ 1852.913595] mtd_speedtest: page read speed is 7687 KiB/s
[ 1856.674492] mtd_speedtest: testing 2 page write speed
[ 1936.437284] mtd_speedtest: 2 page write speed is 3285 KiB/s
[ 1936.442869] mtd_speedtest: testing 2 page read speed
[ 1970.498124] mtd_speedtest: 2 page read speed is 7694 KiB/s
[ 1970.503624] mtd_speedtest: Testing erase speed
[ 1974.343389] mtd_speedtest: erase speed is 68316 KiB/s
[ 1974.348479] mtd_speedtest: Testing 2x multi-block erase speed
[ 1976.068855] mtd_speedtest: 2x multi-block erase speed is 152811 KiB/s
[ 1976.075309] mtd_speedtest: Testing 4x multi-block erase speed
[ 1977.790232] mtd_speedtest: 4x multi-block erase speed is 153301 KiB/s
[ 1977.796693] mtd_speedtest: Testing 8x multi-block erase speed
[ 1979.511905] mtd_speedtest: 8x multi-block erase speed is 153273 KiB/s
[ 1979.518367] mtd_speedtest: Testing 16x multi-block erase speed
[ 1981.230700] mtd_speedtest: 16x multi-block erase speed is 153539 KiB/s
[ 1981.237249] mtd_speedtest: Testing 32x multi-block erase speed
[ 1982.948381] mtd_speedtest: 32x multi-block erase speed is 153648 KiB/s
[ 1982.954918] mtd_speedtest: Testing 64x multi-block erase speed
[ 1984.665992] mtd_speedtest: 64x multi-block erase speed is 153655 KiB/s
[ 1984.672531] mtd_speedtest: finished
[ 1984.676054] =================================================

root@OpenWrt:/lib/modules/6.6.79# insmod mtd_stresstest.ko dev=1
[ 2190.651750]
[ 2190.653263] =================================================
[ 2190.659087] mtd_stresstest: MTD device: 1
[ 2190.663105] mtd_stresstest: MTD device size 268304384, eraseblock size 131072, page size 2048, count of eraseblocks 2047, pages per eraseblock 64, OOB size 128
[ 2190.679846] mtd_test: scanning for bad eraseblocks
[ 2190.684981] mtd_test: scanned 2047 eraseblocks, 0 are bad
[ 2190.690389] mtd_stresstest: doing operations
[ 2190.694655] mtd_stresstest: 0 operations done
[ 2214.262705] mtd_stresstest: 1024 operations done
[ 2239.019612] mtd_stresstest: 2048 operations done
[ 2262.820899] mtd_stresstest: 3072 operations done
[ 2285.061376] mtd_stresstest: 4096 operations done
[ 2308.297322] mtd_stresstest: 5120 operations done
[ 2330.530459] mtd_stresstest: 6144 operations done
[ 2352.651759] mtd_stresstest: 7168 operations done
[ 2375.188275] mtd_stresstest: 8192 operations done
[ 2397.738174] mtd_stresstest: 9216 operations done
[ 2414.792572] mtd_stresstest: finished, 10000 operations done
[ 2414.798257] =================================================

Speed test of original driver (with patch to fix support of flashes
with more than one plane per lun)

root@OpenWrt:/lib/modules/6.6.79# insmod mtd_speedtest.ko dev=1
[ 2894.142208]
[ 2894.143719] =================================================
[ 2894.149556] mtd_speedtest: MTD device: 1
[ 2894.153486] mtd_speedtest: MTD device size 268304384, eraseblock size 131072, page size 2048, count of eraseblocks 2047, pages per eraseblock 64, OOB size 128
[ 2894.168888] mtd_test: scanning for bad eraseblocks
[ 2894.174023] mtd_test: scanned 2047 eraseblocks, 0 are bad
[ 2897.500416] mtd_speedtest: testing eraseblock write speed
[ 2977.807233] mtd_speedtest: eraseblock write speed is 3262 KiB/s
[ 2977.813171] mtd_speedtest: testing eraseblock read speed
[ 3013.906597] mtd_speedtest: eraseblock read speed is 7260 KiB/s
[ 3017.440320] mtd_speedtest: testing page write speed
[ 3097.833394] mtd_speedtest: page write speed is 3259 KiB/s
[ 3097.838812] mtd_speedtest: testing page read speed
[ 3134.004981] mtd_speedtest: page read speed is 7245 KiB/s
[ 3137.538423] mtd_speedtest: testing 2 page write speed
[ 3217.906288] mtd_speedtest: 2 page write speed is 3260 KiB/s
[ 3217.911883] mtd_speedtest: testing 2 page read speed
[ 3254.049757] mtd_speedtest: 2 page read speed is 7251 KiB/s
[ 3254.055254] mtd_speedtest: Testing erase speed
[ 3257.599146] mtd_speedtest: erase speed is 74027 KiB/s
[ 3257.604213] mtd_speedtest: Testing 2x multi-block erase speed
[ 3259.320945] mtd_speedtest: 2x multi-block erase speed is 153139 KiB/s
[ 3259.327413] mtd_speedtest: Testing 4x multi-block erase speed
[ 3261.044585] mtd_speedtest: 4x multi-block erase speed is 153098 KiB/s
[ 3261.051047] mtd_speedtest: Testing 8x multi-block erase speed
[ 3262.786520] mtd_speedtest: 8x multi-block erase speed is 151479 KiB/s
[ 3262.792979] mtd_speedtest: Testing 16x multi-block erase speed
[ 3264.509898] mtd_speedtest: 16x multi-block erase speed is 153130 KiB/s
[ 3264.516454] mtd_speedtest: Testing 32x multi-block erase speed
[ 3266.233403] mtd_speedtest: 32x multi-block erase speed is 153125 KiB/s
[ 3266.239961] mtd_speedtest: Testing 64x multi-block erase speed
[ 3267.957985] mtd_speedtest: 64x multi-block erase speed is 153029 KiB/s
[ 3267.964525] mtd_speedtest: finished
[ 3267.968039] =================================================

It looks like a patched driver is a bit faster

write speed: 3260 KiB/s vs 3277 KiB/s
read speed: 7252 KiB/s vs 7695 KiB/s

+299 -257
+267 -248
drivers/spi/spi-airoha-snfi.c
··· 147 147 #define SPI_NFI_CUS_SEC_SIZE_EN BIT(16) 148 148 149 149 #define REG_SPI_NFI_RD_CTL2 0x0510 150 + #define SPI_NFI_DATA_READ_CMD GENMASK(7, 0) 151 + 150 152 #define REG_SPI_NFI_RD_CTL3 0x0514 151 153 152 154 #define REG_SPI_NFI_PG_CTL1 0x0524 ··· 181 179 #define SPI_NAND_OP_READ_FROM_CACHE_SINGLE 0x03 182 180 #define SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST 0x0b 183 181 #define SPI_NAND_OP_READ_FROM_CACHE_DUAL 0x3b 182 + #define SPI_NAND_OP_READ_FROM_CACHE_DUALIO 0xbb 184 183 #define SPI_NAND_OP_READ_FROM_CACHE_QUAD 0x6b 184 + #define SPI_NAND_OP_READ_FROM_CACHE_QUADIO 0xeb 185 185 #define SPI_NAND_OP_WRITE_ENABLE 0x06 186 186 #define SPI_NAND_OP_WRITE_DISABLE 0x04 187 187 #define SPI_NAND_OP_PROGRAM_LOAD_SINGLE 0x02 ··· 195 191 #define SPI_NAND_OP_BLOCK_ERASE 0xd8 196 192 #define SPI_NAND_OP_RESET 0xff 197 193 #define SPI_NAND_OP_DIE_SELECT 0xc2 194 + 195 + /* SNAND FIFO commands */ 196 + #define SNAND_FIFO_TX_BUSWIDTH_SINGLE 0x08 197 + #define SNAND_FIFO_TX_BUSWIDTH_DUAL 0x09 198 + #define SNAND_FIFO_TX_BUSWIDTH_QUAD 0x0a 199 + #define SNAND_FIFO_RX_BUSWIDTH_SINGLE 0x0c 200 + #define SNAND_FIFO_RX_BUSWIDTH_DUAL 0x0e 201 + #define SNAND_FIFO_RX_BUSWIDTH_QUAD 0x0f 198 202 199 203 #define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256) 200 204 #define SPI_MAX_TRANSFER_SIZE 511 ··· 223 211 struct regmap *regmap_ctrl; 224 212 struct regmap *regmap_nfi; 225 213 struct clk *spi_clk; 226 - 227 - struct { 228 - size_t page_size; 229 - size_t sec_size; 230 - u8 sec_num; 231 - u8 spare_size; 232 - } nfi_cfg; 233 214 }; 234 215 235 216 static int airoha_snand_set_fifo_op(struct airoha_snand_ctrl *as_ctrl, ··· 392 387 return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0); 393 388 } 394 389 395 - static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd, 396 - const u8 *data, int len) 390 + static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, 391 + const u8 *data, int len, int buswidth) 397 392 { 398 393 int i, data_len; 394 + u8 cmd; 395 + 396 + switch (buswidth) { 397 + case 0: 398 + case 1: 399 + cmd = SNAND_FIFO_TX_BUSWIDTH_SINGLE; 400 + break; 401 + case 2: 402 + cmd = SNAND_FIFO_TX_BUSWIDTH_DUAL; 403 + break; 404 + case 4: 405 + cmd = SNAND_FIFO_TX_BUSWIDTH_QUAD; 406 + break; 407 + default: 408 + return -EINVAL; 409 + } 399 410 400 411 for (i = 0; i < len; i += data_len) { 401 412 int err; ··· 430 409 return 0; 431 410 } 432 411 433 - static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data, 434 - int len) 412 + static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, 413 + u8 *data, int len, int buswidth) 435 414 { 436 415 int i, data_len; 416 + u8 cmd; 417 + 418 + switch (buswidth) { 419 + case 0: 420 + case 1: 421 + cmd = SNAND_FIFO_RX_BUSWIDTH_SINGLE; 422 + break; 423 + case 2: 424 + cmd = SNAND_FIFO_RX_BUSWIDTH_DUAL; 425 + break; 426 + case 4: 427 + cmd = SNAND_FIFO_RX_BUSWIDTH_QUAD; 428 + break; 429 + default: 430 + return -EINVAL; 431 + } 437 432 438 433 for (i = 0; i < len; i += data_len) { 439 434 int err; 440 435 441 436 data_len = min(len - i, SPI_MAX_TRANSFER_SIZE); 442 - err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len); 437 + err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len); 443 438 if (err) 444 439 return err; 445 440 ··· 481 444 /* Enable DMA */ 482 445 return regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR_EN, 483 446 SPI_NFI_ALL_IRQ_EN, SPI_NFI_AHB_DONE_EN); 484 - } 485 - 486 - static int airoha_snand_nfi_config(struct airoha_snand_ctrl *as_ctrl) 487 - { 488 - int err; 489 - u32 val; 490 - 491 - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, 492 - SPI_NFI_FIFO_FLUSH | SPI_NFI_RST); 493 - if (err) 494 - return err; 495 - 496 - /* auto FDM */ 497 - err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 498 - SPI_NFI_AUTO_FDM_EN); 499 - if (err) 500 - return err; 501 - 502 - /* HW ECC */ 503 - err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 504 - SPI_NFI_HW_ECC_EN); 505 - if (err) 506 - return err; 507 - 508 - /* DMA Burst */ 509 - err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 510 - SPI_NFI_DMA_BURST_EN); 511 - if (err) 512 - return err; 513 - 514 - /* page format */ 515 - switch (as_ctrl->nfi_cfg.spare_size) { 516 - case 26: 517 - val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x1); 518 - break; 519 - case 27: 520 - val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x2); 521 - break; 522 - case 28: 523 - val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x3); 524 - break; 525 - default: 526 - val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x0); 527 - break; 528 - } 529 - 530 - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT, 531 - SPI_NFI_SPARE_SIZE, val); 532 - if (err) 533 - return err; 534 - 535 - switch (as_ctrl->nfi_cfg.page_size) { 536 - case 2048: 537 - val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x1); 538 - break; 539 - case 4096: 540 - val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x2); 541 - break; 542 - default: 543 - val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x0); 544 - break; 545 - } 546 - 547 - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT, 548 - SPI_NFI_PAGE_SIZE, val); 549 - if (err) 550 - return err; 551 - 552 - /* sec num */ 553 - val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num); 554 - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, 555 - SPI_NFI_SEC_NUM, val); 556 - if (err) 557 - return err; 558 - 559 - /* enable cust sec size */ 560 - err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, 561 - SPI_NFI_CUS_SEC_SIZE_EN); 562 - if (err) 563 - return err; 564 - 565 - /* set cust sec size */ 566 - val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, as_ctrl->nfi_cfg.sec_size); 567 - return regmap_update_bits(as_ctrl->regmap_nfi, 568 - REG_SPI_NFI_SECCUS_SIZE, 569 - SPI_NFI_CUS_SEC_SIZE, val); 570 447 } 571 448 572 449 static bool airoha_snand_is_page_ops(const struct spi_mem_op *op) ··· 515 564 } 516 565 } 517 566 518 - static int airoha_snand_adjust_op_size(struct spi_mem *mem, 519 - struct spi_mem_op *op) 520 - { 521 - size_t max_len; 522 - 523 - if (airoha_snand_is_page_ops(op)) { 524 - struct airoha_snand_ctrl *as_ctrl; 525 - 526 - as_ctrl = spi_controller_get_devdata(mem->spi->controller); 527 - max_len = as_ctrl->nfi_cfg.sec_size; 528 - max_len += as_ctrl->nfi_cfg.spare_size; 529 - max_len *= as_ctrl->nfi_cfg.sec_num; 530 - 531 - if (op->data.nbytes > max_len) 532 - op->data.nbytes = max_len; 533 - } else { 534 - max_len = 1 + op->addr.nbytes + op->dummy.nbytes; 535 - if (max_len >= 160) 536 - return -EOPNOTSUPP; 537 - 538 - if (op->data.nbytes > 160 - max_len) 539 - op->data.nbytes = 160 - max_len; 540 - } 541 - 542 - return 0; 543 - } 544 - 545 567 static bool airoha_snand_supports_op(struct spi_mem *mem, 546 568 const struct spi_mem_op *op) 547 569 { ··· 542 618 if (desc->info.offset + desc->info.length > U32_MAX) 543 619 return -EINVAL; 544 620 621 + /* continuous reading is not supported */ 622 + if (desc->info.length > SPI_NAND_CACHE_SIZE) 623 + return -E2BIG; 624 + 545 625 if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl)) 546 626 return -EOPNOTSUPP; 547 627 ··· 555 627 static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, 556 628 u64 offs, size_t len, void *buf) 557 629 { 558 - struct spi_mem_op *op = &desc->info.op_tmpl; 559 630 struct spi_device *spi = desc->mem->spi; 560 631 struct airoha_snand_ctrl *as_ctrl; 561 632 u8 *txrx_buf = spi_get_ctldata(spi); 562 633 dma_addr_t dma_addr; 563 - u32 val, rd_mode; 634 + u32 val, rd_mode, opcode; 635 + size_t bytes; 564 636 int err; 565 637 566 - switch (op->cmd.opcode) { 638 + as_ctrl = spi_controller_get_devdata(spi->controller); 639 + 640 + /* minimum oob size is 64 */ 641 + bytes = round_up(offs + len, 64); 642 + 643 + /* 644 + * DUALIO and QUADIO opcodes are not supported by the spi controller, 645 + * replace them with supported opcodes. 646 + */ 647 + opcode = desc->info.op_tmpl.cmd.opcode; 648 + switch (opcode) { 649 + case SPI_NAND_OP_READ_FROM_CACHE_SINGLE: 650 + case SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST: 651 + rd_mode = 0; 652 + break; 567 653 case SPI_NAND_OP_READ_FROM_CACHE_DUAL: 654 + case SPI_NAND_OP_READ_FROM_CACHE_DUALIO: 655 + opcode = SPI_NAND_OP_READ_FROM_CACHE_DUAL; 568 656 rd_mode = 1; 569 657 break; 570 658 case SPI_NAND_OP_READ_FROM_CACHE_QUAD: 659 + case SPI_NAND_OP_READ_FROM_CACHE_QUADIO: 660 + opcode = SPI_NAND_OP_READ_FROM_CACHE_QUAD; 571 661 rd_mode = 2; 572 662 break; 573 663 default: 574 - rd_mode = 0; 575 - break; 664 + /* unknown opcode */ 665 + return -EOPNOTSUPP; 576 666 } 577 667 578 - as_ctrl = spi_controller_get_devdata(spi->controller); 579 668 err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA); 580 669 if (err < 0) 581 670 return err; 582 671 583 - err = airoha_snand_nfi_config(as_ctrl); 672 + /* NFI reset */ 673 + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, 674 + SPI_NFI_FIFO_FLUSH | SPI_NFI_RST); 584 675 if (err) 585 - return err; 676 + goto error_dma_mode_off; 677 + 678 + /* NFI configure: 679 + * - No AutoFDM (custom sector size (SECCUS) register will be used) 680 + * - No SoC's hardware ECC (flash internal ECC will be used) 681 + * - Use burst mode (faster, but requires 16 byte alignment for addresses) 682 + * - Setup for reading (SPI_NFI_READ_MODE) 683 + * - Setup reading command: FIELD_PREP(SPI_NFI_OPMODE, 6) 684 + * - Use DMA instead of PIO for data reading 685 + */ 686 + err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 687 + SPI_NFI_DMA_MODE | 688 + SPI_NFI_READ_MODE | 689 + SPI_NFI_DMA_BURST_EN | 690 + SPI_NFI_HW_ECC_EN | 691 + SPI_NFI_AUTO_FDM_EN | 692 + SPI_NFI_OPMODE, 693 + SPI_NFI_DMA_MODE | 694 + SPI_NFI_READ_MODE | 695 + SPI_NFI_DMA_BURST_EN | 696 + FIELD_PREP(SPI_NFI_OPMODE, 6)); 697 + if (err) 698 + goto error_dma_mode_off; 699 + 700 + /* Set number of sector will be read */ 701 + err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, 702 + SPI_NFI_SEC_NUM, 703 + FIELD_PREP(SPI_NFI_SEC_NUM, 1)); 704 + if (err) 705 + goto error_dma_mode_off; 706 + 707 + /* Set custom sector size */ 708 + err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, 709 + SPI_NFI_CUS_SEC_SIZE | 710 + SPI_NFI_CUS_SEC_SIZE_EN, 711 + FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, bytes) | 712 + SPI_NFI_CUS_SEC_SIZE_EN); 713 + if (err) 714 + goto error_dma_mode_off; 586 715 587 716 dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, 588 717 DMA_FROM_DEVICE); 589 718 err = dma_mapping_error(as_ctrl->dev, dma_addr); 590 719 if (err) 591 - return err; 720 + goto error_dma_mode_off; 592 721 593 722 /* set dma addr */ 594 723 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, ··· 653 668 if (err) 654 669 goto error_dma_unmap; 655 670 656 - /* set cust sec size */ 657 - val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num; 658 - val = FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, val); 671 + /* 672 + * Setup transfer length 673 + * --------------------- 674 + * The following rule MUST be met: 675 + * transfer_length = 676 + * = NFI_SNF_MISC_CTL2.read_data_byte_number = 677 + * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size 678 + */ 659 679 err = regmap_update_bits(as_ctrl->regmap_nfi, 660 680 REG_SPI_NFI_SNF_MISC_CTL2, 661 - SPI_NFI_READ_DATA_BYTE_NUM, val); 681 + SPI_NFI_READ_DATA_BYTE_NUM, 682 + FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, bytes)); 662 683 if (err) 663 684 goto error_dma_unmap; 664 685 665 686 /* set read command */ 666 687 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2, 667 - op->cmd.opcode); 688 + FIELD_PREP(SPI_NFI_DATA_READ_CMD, opcode)); 668 689 if (err) 669 690 goto error_dma_unmap; 670 691 ··· 680 689 if (err) 681 690 goto error_dma_unmap; 682 691 683 - /* set read addr */ 684 - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0); 685 - if (err) 686 - goto error_dma_unmap; 687 - 688 - /* set nfi read */ 689 - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 690 - SPI_NFI_OPMODE, 691 - FIELD_PREP(SPI_NFI_OPMODE, 6)); 692 - if (err) 693 - goto error_dma_unmap; 694 - 695 - err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 696 - SPI_NFI_READ_MODE | SPI_NFI_DMA_MODE); 692 + /* set read addr: zero page offset + descriptor read offset */ 693 + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 694 + desc->info.offset); 697 695 if (err) 698 696 goto error_dma_unmap; 699 697 ··· 690 710 if (err) 691 711 goto error_dma_unmap; 692 712 693 - /* trigger dma start read */ 713 + /* trigger dma reading */ 694 714 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, 695 715 SPI_NFI_RD_TRIG); 696 716 if (err) ··· 740 760 error_dma_unmap: 741 761 dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, 742 762 DMA_FROM_DEVICE); 763 + error_dma_mode_off: 764 + airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); 743 765 return err; 744 766 } 745 767 746 768 static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, 747 769 u64 offs, size_t len, const void *buf) 748 770 { 749 - struct spi_mem_op *op = &desc->info.op_tmpl; 750 771 struct spi_device *spi = desc->mem->spi; 751 772 u8 *txrx_buf = spi_get_ctldata(spi); 752 773 struct airoha_snand_ctrl *as_ctrl; 753 774 dma_addr_t dma_addr; 754 - u32 wr_mode, val; 775 + u32 wr_mode, val, opcode; 776 + size_t bytes; 755 777 int err; 756 778 757 779 as_ctrl = spi_controller_get_devdata(spi->controller); 758 - err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); 780 + 781 + /* minimum oob size is 64 */ 782 + bytes = round_up(offs + len, 64); 783 + 784 + opcode = desc->info.op_tmpl.cmd.opcode; 785 + switch (opcode) { 786 + case SPI_NAND_OP_PROGRAM_LOAD_SINGLE: 787 + case SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE: 788 + wr_mode = 0; 789 + break; 790 + case SPI_NAND_OP_PROGRAM_LOAD_QUAD: 791 + case SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD: 792 + wr_mode = 2; 793 + break; 794 + default: 795 + /* unknown opcode */ 796 + return -EOPNOTSUPP; 797 + } 798 + 799 + if (offs > 0) 800 + memset(txrx_buf, 0xff, offs); 801 + memcpy(txrx_buf + offs, buf, len); 802 + if (bytes > offs + len) 803 + memset(txrx_buf + offs + len, 0xff, bytes - offs - len); 804 + 805 + err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA); 759 806 if (err < 0) 760 807 return err; 761 808 762 - memcpy(txrx_buf + offs, buf, len); 809 + /* NFI reset */ 810 + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, 811 + SPI_NFI_FIFO_FLUSH | SPI_NFI_RST); 812 + if (err) 813 + goto error_dma_mode_off; 814 + 815 + /* 816 + * NFI configure: 817 + * - No AutoFDM (custom sector size (SECCUS) register will be used) 818 + * - No SoC's hardware ECC (flash internal ECC will be used) 819 + * - Use burst mode (faster, but requires 16 byte alignment for addresses) 820 + * - Setup for writing (SPI_NFI_READ_MODE bit is cleared) 821 + * - Setup writing command: FIELD_PREP(SPI_NFI_OPMODE, 3) 822 + * - Use DMA instead of PIO for data writing 823 + */ 824 + err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 825 + SPI_NFI_DMA_MODE | 826 + SPI_NFI_READ_MODE | 827 + SPI_NFI_DMA_BURST_EN | 828 + SPI_NFI_HW_ECC_EN | 829 + SPI_NFI_AUTO_FDM_EN | 830 + SPI_NFI_OPMODE, 831 + SPI_NFI_DMA_MODE | 832 + SPI_NFI_DMA_BURST_EN | 833 + FIELD_PREP(SPI_NFI_OPMODE, 3)); 834 + if (err) 835 + goto error_dma_mode_off; 836 + 837 + /* Set number of sector will be written */ 838 + err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, 839 + SPI_NFI_SEC_NUM, 840 + FIELD_PREP(SPI_NFI_SEC_NUM, 1)); 841 + if (err) 842 + goto error_dma_mode_off; 843 + 844 + /* Set custom sector size */ 845 + err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, 846 + SPI_NFI_CUS_SEC_SIZE | 847 + SPI_NFI_CUS_SEC_SIZE_EN, 848 + FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, bytes) | 849 + SPI_NFI_CUS_SEC_SIZE_EN); 850 + if (err) 851 + goto error_dma_mode_off; 852 + 763 853 dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, 764 854 DMA_TO_DEVICE); 765 855 err = dma_mapping_error(as_ctrl->dev, dma_addr); 766 856 if (err) 767 - return err; 857 + goto error_dma_mode_off; 768 858 769 - err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA); 770 - if (err < 0) 771 - goto error_dma_unmap; 772 - 773 - err = airoha_snand_nfi_config(as_ctrl); 774 - if (err) 775 - goto error_dma_unmap; 776 - 777 - if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD || 778 - op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD) 779 - wr_mode = BIT(1); 780 - else 781 - wr_mode = 0; 782 - 859 + /* set dma addr */ 783 860 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, 784 861 dma_addr); 785 862 if (err) 786 863 goto error_dma_unmap; 787 864 788 - val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, 789 - as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num); 865 + /* 866 + * Setup transfer length 867 + * --------------------- 868 + * The following rule MUST be met: 869 + * transfer_length = 870 + * = NFI_SNF_MISC_CTL2.write_data_byte_number = 871 + * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size 872 + */ 790 873 err = regmap_update_bits(as_ctrl->regmap_nfi, 791 874 REG_SPI_NFI_SNF_MISC_CTL2, 792 - SPI_NFI_PROG_LOAD_BYTE_NUM, val); 875 + SPI_NFI_PROG_LOAD_BYTE_NUM, 876 + FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, bytes)); 793 877 if (err) 794 878 goto error_dma_unmap; 795 879 880 + /* set write command */ 796 881 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1, 797 - FIELD_PREP(SPI_NFI_PG_LOAD_CMD, 798 - op->cmd.opcode)); 882 + FIELD_PREP(SPI_NFI_PG_LOAD_CMD, opcode)); 799 883 if (err) 800 884 goto error_dma_unmap; 801 885 886 + /* set write mode */ 802 887 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL, 803 888 FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode)); 804 889 if (err) 805 890 goto error_dma_unmap; 806 891 807 - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0); 808 - if (err) 809 - goto error_dma_unmap; 810 - 811 - err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 812 - SPI_NFI_READ_MODE); 813 - if (err) 814 - goto error_dma_unmap; 815 - 816 - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 817 - SPI_NFI_OPMODE, 818 - FIELD_PREP(SPI_NFI_OPMODE, 3)); 819 - if (err) 820 - goto error_dma_unmap; 821 - 822 - err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, 823 - SPI_NFI_DMA_MODE); 892 + /* set write addr: zero page offset + descriptor write offset */ 893 + err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 894 + desc->info.offset); 824 895 if (err) 825 896 goto error_dma_unmap; 826 897 ··· 879 848 if (err) 880 849 goto error_dma_unmap; 881 850 851 + /* trigger dma writing */ 882 852 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, 883 853 SPI_NFI_WR_TRIG); 884 854 if (err) ··· 924 892 error_dma_unmap: 925 893 dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, 926 894 DMA_TO_DEVICE); 895 + error_dma_mode_off: 896 + airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); 927 897 return err; 928 898 } 929 899 930 900 static int airoha_snand_exec_op(struct spi_mem *mem, 931 901 const struct spi_mem_op *op) 932 902 { 933 - u8 data[8], cmd, opcode = op->cmd.opcode; 934 903 struct airoha_snand_ctrl *as_ctrl; 904 + int op_len, addr_len, dummy_len; 905 + u8 buf[20], *data; 935 906 int i, err; 936 907 937 908 as_ctrl = spi_controller_get_devdata(mem->spi->controller); 909 + 910 + op_len = op->cmd.nbytes; 911 + addr_len = op->addr.nbytes; 912 + dummy_len = op->dummy.nbytes; 913 + 914 + if (op_len + dummy_len + addr_len > sizeof(buf)) 915 + return -EIO; 916 + 917 + data = buf; 918 + for (i = 0; i < op_len; i++) 919 + *data++ = op->cmd.opcode >> (8 * (op_len - i - 1)); 920 + for (i = 0; i < addr_len; i++) 921 + *data++ = op->addr.val >> (8 * (addr_len - i - 1)); 922 + for (i = 0; i < dummy_len; i++) 923 + *data++ = 0xff; 938 924 939 925 /* switch to manual mode */ 940 926 err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); ··· 964 914 return err; 965 915 966 916 /* opcode */ 967 - err = airoha_snand_write_data(as_ctrl, 0x8, &opcode, sizeof(opcode)); 917 + data = buf; 918 + err = airoha_snand_write_data(as_ctrl, data, op_len, 919 + op->cmd.buswidth); 968 920 if (err) 969 921 return err; 970 922 971 923 /* addr part */ 972 - cmd = opcode == SPI_NAND_OP_GET_FEATURE ? 0x11 : 0x8; 973 - put_unaligned_be64(op->addr.val, data); 974 - 975 - for (i = ARRAY_SIZE(data) - op->addr.nbytes; 976 - i < ARRAY_SIZE(data); i++) { 977 - err = airoha_snand_write_data(as_ctrl, cmd, &data[i], 978 - sizeof(data[0])); 924 + data += op_len; 925 + if (addr_len) { 926 + err = airoha_snand_write_data(as_ctrl, data, addr_len, 927 + op->addr.buswidth); 979 928 if (err) 980 929 return err; 981 930 } 982 931 983 932 /* dummy */ 984 - data[0] = 0xff; 985 - for (i = 0; i < op->dummy.nbytes; i++) { 986 - err = airoha_snand_write_data(as_ctrl, 0x8, &data[0], 987 - sizeof(data[0])); 933 + data += addr_len; 934 + if (dummy_len) { 935 + err = airoha_snand_write_data(as_ctrl, data, dummy_len, 936 + op->dummy.buswidth); 988 937 if (err) 989 938 return err; 990 939 } 991 940 992 941 /* data */ 993 - if (op->data.dir == SPI_MEM_DATA_IN) { 994 - err = airoha_snand_read_data(as_ctrl, op->data.buf.in, 995 - op->data.nbytes); 996 - if (err) 997 - return err; 998 - } else { 999 - err = airoha_snand_write_data(as_ctrl, 0x8, op->data.buf.out, 1000 - op->data.nbytes); 942 + if (op->data.nbytes) { 943 + if (op->data.dir == SPI_MEM_DATA_IN) 944 + err = airoha_snand_read_data(as_ctrl, op->data.buf.in, 945 + op->data.nbytes, 946 + op->data.buswidth); 947 + else 948 + err = airoha_snand_write_data(as_ctrl, op->data.buf.out, 949 + op->data.nbytes, 950 + op->data.buswidth); 1001 951 if (err) 1002 952 return err; 1003 953 } ··· 1006 956 } 1007 957 1008 958 static const struct spi_controller_mem_ops airoha_snand_mem_ops = { 1009 - .adjust_op_size = airoha_snand_adjust_op_size, 1010 959 .supports_op = airoha_snand_supports_op, 1011 960 .exec_op = airoha_snand_exec_op, 1012 961 .dirmap_create = airoha_snand_dirmap_create, ··· 1028 979 spi_set_ctldata(spi, txrx_buf); 1029 980 1030 981 return 0; 1031 - } 1032 - 1033 - static int airoha_snand_nfi_setup(struct airoha_snand_ctrl *as_ctrl) 1034 - { 1035 - u32 val, sec_size, sec_num; 1036 - int err; 1037 - 1038 - err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, &val); 1039 - if (err) 1040 - return err; 1041 - 1042 - sec_num = FIELD_GET(SPI_NFI_SEC_NUM, val); 1043 - 1044 - err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, &val); 1045 - if (err) 1046 - return err; 1047 - 1048 - sec_size = FIELD_GET(SPI_NFI_CUS_SEC_SIZE, val); 1049 - 1050 - /* init default value */ 1051 - as_ctrl->nfi_cfg.sec_size = sec_size; 1052 - as_ctrl->nfi_cfg.sec_num = sec_num; 1053 - as_ctrl->nfi_cfg.page_size = round_down(sec_size * sec_num, 1024); 1054 - as_ctrl->nfi_cfg.spare_size = 16; 1055 - 1056 - err = airoha_snand_nfi_init(as_ctrl); 1057 - if (err) 1058 - return err; 1059 - 1060 - return airoha_snand_nfi_config(as_ctrl); 1061 982 } 1062 983 1063 984 static const struct regmap_config spi_ctrl_regmap_config = { ··· 1103 1084 ctrl->setup = airoha_snand_setup; 1104 1085 device_set_node(&ctrl->dev, dev_fwnode(dev)); 1105 1086 1106 - err = airoha_snand_nfi_setup(as_ctrl); 1087 + err = airoha_snand_nfi_init(as_ctrl); 1107 1088 if (err) 1108 1089 return err; 1109 1090
+2 -2
drivers/spi/spi-amlogic-spifc-a4.c
··· 286 286 287 287 for (i = 0; i <= LANE_MAX; i++) { 288 288 if (buswidth == 1 << i) { 289 - conf = i << __bf_shf(mask); 289 + conf = i << __ffs(mask); 290 290 return regmap_update_bits(sfc->regmap_base, SFC_SPI_CFG, 291 291 mask, conf); 292 292 } ··· 566 566 if (!op->data.nbytes) 567 567 goto end_xfer; 568 568 569 - conf = (op->data.nbytes >> RAW_SIZE_BW) << __bf_shf(RAW_EXT_SIZE); 569 + conf = (op->data.nbytes >> RAW_SIZE_BW) << __ffs(RAW_EXT_SIZE); 570 570 ret = regmap_update_bits(sfc->regmap_base, SFC_SPI_CFG, RAW_EXT_SIZE, conf); 571 571 if (ret) 572 572 goto err_out;
+3 -2
drivers/spi/spi-cadence-quadspi.c
··· 1995 1995 if (cqspi->use_direct_mode) { 1996 1996 ret = cqspi_request_mmap_dma(cqspi); 1997 1997 if (ret == -EPROBE_DEFER) 1998 - goto probe_setup_failed; 1998 + goto probe_dma_failed; 1999 1999 } 2000 2000 2001 2001 if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { ··· 2019 2019 2020 2020 return 0; 2021 2021 probe_setup_failed: 2022 - cqspi_controller_enable(cqspi, 0); 2023 2022 if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) 2024 2023 pm_runtime_disable(dev); 2024 + probe_dma_failed: 2025 + cqspi_controller_enable(cqspi, 0); 2025 2026 probe_reset_failed: 2026 2027 if (cqspi->is_jh7110) 2027 2028 cqspi_jh7110_disable_clk(pdev, cqspi);
+27 -5
drivers/spi/spi-nxp-fspi.c
··· 404 404 #define FSPI_NEED_INIT BIT(0) 405 405 #define FSPI_DTR_MODE BIT(1) 406 406 int flags; 407 + /* save the previous operation clock rate */ 408 + unsigned long pre_op_rate; 409 + /* the max clock rate fspi output to device */ 410 + unsigned long max_rate; 407 411 }; 408 412 409 413 static inline int needs_ip_only(struct nxp_fspi *f) ··· 689 685 * change the mode back to mode 0. 690 686 */ 691 687 reg = fspi_readl(f, f->iobase + FSPI_MCR0); 692 - if (op_is_dtr) 688 + if (op_is_dtr) { 693 689 reg |= FSPI_MCR0_RXCLKSRC(3); 694 - else /*select mode 0 */ 690 + f->max_rate = 166000000; 691 + } else { /*select mode 0 */ 695 692 reg &= ~FSPI_MCR0_RXCLKSRC(3); 693 + f->max_rate = 66000000; 694 + } 696 695 fspi_writel(f, reg, f->iobase + FSPI_MCR0); 697 696 } 698 697 ··· 726 719 0, POLL_TOUT, true); 727 720 if (ret) 728 721 dev_warn(f->dev, "DLL lock failed, please fix it!\n"); 722 + 723 + /* 724 + * For ERR050272, DLL lock status bit is not accurate, 725 + * wait for 4us more as a workaround. 726 + */ 727 + udelay(4); 729 728 } 730 729 731 730 /* ··· 793 780 uint64_t size_kb; 794 781 795 782 /* 796 - * Return, if previously selected target device is same as current 797 - * requested target device. Also the DTR or STR mode do not change. 783 + * Return when following condition all meet, 784 + * 1, if previously selected target device is same as current 785 + * requested target device. 786 + * 2, the DTR or STR mode do not change. 787 + * 3, previous operation max rate equals current one. 788 + * 789 + * For other case, need to re-config. 798 790 */ 799 791 if ((f->selected == spi_get_chipselect(spi, 0)) && 800 - (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr)) 792 + (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr) && 793 + (f->pre_op_rate == op->max_freq)) 801 794 return; 802 795 803 796 /* Reset FLSHxxCR0 registers */ ··· 821 802 dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0)); 822 803 823 804 nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr); 805 + rate = min(f->max_rate, op->max_freq); 824 806 825 807 if (op_is_dtr) { 826 808 f->flags |= FSPI_DTR_MODE; ··· 851 831 nxp_fspi_dll_calibration(f); 852 832 else 853 833 nxp_fspi_dll_override(f); 834 + 835 + f->pre_op_rate = op->max_freq; 854 836 855 837 f->selected = spi_get_chipselect(spi, 0); 856 838 }