u-boot/drivers/spi
Rasmus Villemoes 391c40048b mpc8xxx_spi: always use 8-bit characters, don't read or write garbage
There are a few problems with the current driver.

First, it unconditionally reads from dout/writes to din whether or not
those pointers are NULL. So for example a simple "sf probe" ends up
writing four bytes at address 0:

=> md.l 0x0 8
00000000: 45454545 45454545 05050505 05050505    EEEEEEEE........
00000010: 00000000 00000000 07070707 07070707    ................
=> sf probe 0
mpc8xxx_spi_xfer: slave spi@7000:0 dout 0FB53618 din 00000000 bitlen 8
mpc8xxx_spi_xfer: slave spi@7000:0 dout 00000000 din 0FB536B8 bitlen 48
SF: Detected s25sl032p with page size 256 Bytes, erase size 64 KiB, total 4 MiB
=> md.l 0x0 8
00000000: ff000000 45454545 05050505 05050505    ....EEEE........
00000010: 00000000 00000000 07070707 07070707    ................

(here I've change the first debug statement to a printf, and made it
print the din/dout pointers rather than the uints they point at).

Second, as we can also see above, it always writes a full 32 bits,
even if a smaller amount was requested. So for example

=> mw.l $loadaddr 0xaabbccdd 8
=> md.l $loadaddr 8
02000000: aabbccdd aabbccdd aabbccdd aabbccdd    ................
02000010: aabbccdd aabbccdd aabbccdd aabbccdd    ................
=> sf read $loadaddr 0x400 6
device 0 offset 0x400, size 0x6
mpc8xxx_spi_xfer: slave spi@7000:0 dout 0FB536E8 din 00000000 bitlen 40
mpc8xxx_spi_xfer: slave spi@7000:0 dout 00000000 din 02000000 bitlen 48
SF: 6 bytes @ 0x400 Read: OK
=> sf read 0x02000010 0x400 8
device 0 offset 0x400, size 0x8
mpc8xxx_spi_xfer: slave spi@7000:0 dout 0FB53848 din 00000000 bitlen 40
mpc8xxx_spi_xfer: slave spi@7000:0 dout 00000000 din 02000010 bitlen 64
SF: 8 bytes @ 0x400 Read: OK
=> md.l $loadaddr 8
02000000: 45454545 45450000 aabbccdd aabbccdd    EEEEEE..........
02000010: 45454545 45454545 aabbccdd aabbccdd    EEEEEEEE........

Finally, when the bitlen is 24 mod 32 (e.g. requesting to read 3 or 7
bytes), the last three bytes and up being the wrong ones, since the
driver does a full 32 bit read and then shifts the wrong byte out:

=> mw.l $loadaddr 0xaabbccdd 4
=> md.l $loadaddr 4
02000000: aabbccdd aabbccdd aabbccdd aabbccdd    ................
=> sf read $loadaddr 0x444 10
device 0 offset 0x444, size 0x10
mpc8xxx_spi_xfer: slave spi@7000:0 dout 0FB536E8 din 00000000 bitlen 40
mpc8xxx_spi_xfer: slave spi@7000:0 dout 00000000 din 02000000 bitlen 128
SF: 16 bytes @ 0x444 Read: OK
=> md.l $loadaddr 4
02000000: 552d426f 6f742032 3031392e 30342d30    U-Boot 2019.04-0
=> mw.l $loadaddr 0xaabbccdd 4
=> sf read $loadaddr 0x444 0xb
device 0 offset 0x444, size 0xb
mpc8xxx_spi_xfer: slave spi@7000:0 dout 0FB536E8 din 00000000 bitlen 40
mpc8xxx_spi_xfer: slave spi@7000:0 dout 00000000 din 02000000 bitlen 88
SF: 11 bytes @ 0x444 Read: OK
=> md.l $loadaddr 4
02000000: 552d426f 6f742032 31392e00 aabbccdd    U-Boot 219......

Fix all of that by always using a character size of 8, and reject
transfers that are not a whole number of bytes. While it ends being
more work for the CPU, we're mostly bounded by the speed of the SPI
bus, and we avoid writing to the mode register in every loop.

Based on work by Klaus H. Sørensen.

Cc: Klaus H. Sorensen <khso@prevas.dk>
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
2020-03-31 10:06:53 -04:00
..
altera_spi.c SPDX: Convert all of our single license tags to Linux Kernel style 2018-05-07 09:34:12 -04:00
atcspi200_spi.c spi: atcspi200: Change include order 2019-05-09 00:42:55 +05:30
ath79_spi.c common: Move clock functions into a new file 2020-01-17 13:27:29 -05:00
atmel-quadspi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
atmel_spi.c dm: gpio: Allow control of GPIO uclass in SPL 2019-12-15 08:52:29 +08:00
atmel_spi.h Revert "spi: atmel: Drop non-dm code" 2018-04-07 09:19:00 -04:00
bcm63xx_hsspi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
bcm63xx_spi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
bcmstb_spi.c board: arm: Add support for Broadcom BCM7445 2018-07-10 16:55:57 -04:00
cadence_qspi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
cadence_qspi.h spi: cadence-qspi: Add direct mode support 2020-01-27 22:27:22 +05:30
cadence_qspi_apb.c spi: cadence-qspi: Add support for Cadence Octal SPI controller 2020-01-27 22:27:22 +05:30
cf_spi.c drivers: spi: cf_spi: convert to driver model 2019-05-24 08:11:57 -04:00
davinci_spi.c spi: Remove unused spi_init 2018-11-27 21:06:53 +05:30
designware_spi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
exynos_spi.c common: Move get_ticks() function out of common.h 2019-12-02 18:23:13 -05:00
fsl_dspi.c spi: fsl_dspi fix to stop extra transmissions 2019-04-12 11:24:24 +05:30
fsl_espi.c spi: Remove unused spi_init 2018-11-27 21:06:53 +05:30
fsl_qspi.c spi: fsl_qspi: Add support for QSPI on iMX7ULP 2019-10-08 16:36:37 +02:00
fsl_qspi.h SPDX: Convert all of our single license tags to Linux Kernel style 2018-05-07 09:34:12 -04:00
ich.c spi: ich: Drop while loop in hardware sequencing erase case 2020-02-04 01:19:28 +08:00
ich.h spi: ich: Add Apollo Lake support 2019-12-15 11:44:24 +08:00
Kconfig spi: nxp_fspi: new driver for the FlexSPI controller 2020-01-27 22:27:21 +05:30
kirkwood_spi.c km/spi: remove deprecated SPI flash driver code for KM Kirkwood boards 2019-07-11 10:58:03 +02:00
lpc32xx_ssp.c spi: Remove unused spi_init 2018-11-27 21:06:53 +05:30
Makefile spi: nxp_fspi: new driver for the FlexSPI controller 2020-01-27 22:27:21 +05:30
meson_spifc.c spi: Add Amlogic Meson SPI Flash Controller driver 2018-11-24 14:41:12 +05:30
mpc8xx_spi.c spi, mpc8xx: migrate to DM_SPI 2018-12-03 10:44:10 -05:00
mpc8xxx_spi.c mpc8xxx_spi: always use 8-bit characters, don't read or write garbage 2020-03-31 10:06:53 -04:00
mscc_bb_spi.c mips: spi: mscc: Add fast bitbang SPI driver 2019-01-16 13:56:43 +01:00
mt7621_spi.c spi: mt7621-spi: restore default register value after each xfer 2019-10-25 17:20:44 +02:00
mtk_snfi_spi.c spi: add spi-mem driver for MediaTek MT7629 SoC 2019-07-25 18:52:12 +05:30
mvebu_a3700_spi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
mxc_spi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
mxs_spi.c common: Move ARM cache operations out of common.h 2019-12-02 18:24:58 -05:00
nxp_fspi.c dm: core: Drop the inclusion of linux/compat.h in dm.h 2020-02-05 21:48:22 -07:00
omap3_spi.c spi: omap3: fix set_wordlen() reading from incorrect address for CHCONF 2019-02-28 14:21:46 -05:00
pic32_spi.c SPDX: Convert all of our single license tags to Linux Kernel style 2018-05-07 09:34:12 -04:00
pl022_spi.c dm: platform_data: spi: s/pl022_spi.h/spi_pl022.h 2018-11-27 21:06:46 +05:30
renesas_rpc_spi.c spi: rpc: Add support for operation without clock framework 2019-05-07 05:41:32 +02:00
rk_spi.c spi: rk: Limit transfers to (64K - 1) bytes 2019-12-27 17:47:26 +05:30
rk_spi.h SPDX: Convert all of our single license tags to Linux Kernel style 2018-05-07 09:34:12 -04:00
sandbox_spi.c spi: Add support for memory-mapped flash 2019-11-03 07:20:26 +08:00
sh_qspi.c spi: Remove unused spi_init 2018-11-27 21:06:53 +05:30
sh_spi.c spi: Remove unused spi_init 2018-11-27 21:06:53 +05:30
sh_spi.h SPDX: Convert all of our single license tags to Linux Kernel style 2018-05-07 09:34:12 -04:00
soft_spi.c spi: soft_spi: Fix data abort if slave is not probed 2019-09-16 08:09:22 +05:30
soft_spi_legacy.c spi: Remove unused spi_init 2018-11-27 21:06:53 +05:30
spi-emul-uclass.c SPDX: Convert all of our single license tags to Linux Kernel style 2018-05-07 09:34:12 -04:00
spi-mem-nodm.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
spi-mem.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
spi-sifive.c spi: Add SiFive SPI driver 2019-07-18 17:11:16 +05:30
spi-sunxi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
spi-uclass.c mtd: spi-nor-core: Add octal mode support 2020-01-27 22:27:22 +05:30
spi.c SPDX: Convert all of our single license tags to Linux Kernel style 2018-05-07 09:34:12 -04:00
stm32_qspi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
stm32_spi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
tegra20_sflash.c common: Move get_ticks() function out of common.h 2019-12-02 18:23:13 -05:00
tegra20_slink.c common: Move get_ticks() function out of common.h 2019-12-02 18:23:13 -05:00
tegra114_spi.c common: Move get_ticks() function out of common.h 2019-12-02 18:23:13 -05:00
tegra210_qspi.c common: Move get_ticks() function out of common.h 2019-12-02 18:23:13 -05:00
tegra_spi.h SPDX: Convert all of our single license tags to Linux Kernel style 2018-05-07 09:34:12 -04:00
ti_qspi.c dm: core: Require users of devres to include the header 2020-02-05 19:33:46 -07:00
uniphier_spi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00
xilinx_spi.c spi: xilinx_spi: convert to livetree 2018-07-16 14:01:20 +05:30
zynq_qspi.c spi: zynq_qspi: Fixed incorrect return value error 2018-06-25 14:13:57 +05:30
zynq_spi.c common: Move get_ticks() function out of common.h 2019-12-02 18:23:13 -05:00
zynqmp_gqspi.c dm: core: Create a new header file for 'compat' features 2020-02-05 19:33:46 -07:00