spi: kirkwood_spi: implement workaround for FE-9144572
Subsystems (2)
PATCH 1/1 spi: kirkwood_spi: implement workaround for FE-9144572
Erratum NO. FE-9144572: The device SPI interface supports frequencies of up to 50 MHz. However, due to this erratum, when the device core clock is 250 MHz and the SPI interfaces is configured for 50MHz SPI clock and CPOL=CPHA=1 there might occur data corruption on reads from the SPI device.
Implement the workaround by setting the TMISO_SAMPLE value to 0x2 in the timing1 register.
---
arch/arm/include/asm/arch-mvebu/spi.h | 6 ++++ drivers/spi/kirkwood_spi.c | 62 +++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-)
arch/arm/include/asm/arch-mvebu/spi.h +6 -0
@@ -57,6 +57,12 @@ struct kwspi_registers {#define KWSPI_TXLSBF (1 << 13)#define KWSPI_RXLSBF (1 << 14) +/* Timing Parameters 1 Register */ +#define KW_SPI_TMISO_SAMPLE_OFFSET 6 +#define KW_SPI_TMISO_SAMPLE_MASK (0x3 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_1 (1 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_2 (2 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KWSPI_IRQUNMASK 1/* unmask SPI interrupt */ #define KWSPI_IRQMASK 0/* mask SPI interrupt */ #define KWSPI_SMEMRDIRQ 1/* SerMem data xfer ready irq */
drivers/spi/kirkwood_spi.c +59 -3
91 lines not on this page · raw message
Signature · 1 line
2.14.2
PATCH 1/1 spi: kirkwood_spi: implement workaround for FE-9144572
Quoted 11 lines · Chris Packham
Erratum NO. FE-9144572: The device SPI interface supports frequencies of up to 50 MHz. However, due to this erratum, when the device core clock is 250 MHz and the SPI interfaces is configured for 50MHz SPI clock and CPOL=CPHA=1 there might occur data corruption on reads from the SPI device.
Implement the workaround by setting the
TMISO_SAMPLEvalue to0x2in the timing1 register.Signed-off-by Chris Packham <[email protected]>---
I've based this as much as I can on the equivalent implementation in the Linux kernel[1], but there are differences in the u-boot spi infrastructure that means I can't be as specific when qualifying whether the workaround is needed.
[1] - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-orion.c#n248
Quoted 124 lines
arch/arm/include/asm/arch-mvebu/spi.h | 6 ++++ drivers/spi/kirkwood_spi.c | 62 +++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-)arch/arm/include/asm/arch-mvebu/spi.h +6
-0@@ -57,6 +57,12 @@ struct kwspi_registers {#define KWSPI_TXLSBF (1 << 13)#define KWSPI_RXLSBF (1 << 14) +/* Timing Parameters 1 Register */ +#define KW_SPI_TMISO_SAMPLE_OFFSET 6 +#define KW_SPI_TMISO_SAMPLE_MASK (0x3 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_1 (1 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_2 (2 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KWSPI_IRQUNMASK 1/* unmask SPI interrupt */ #define KWSPI_IRQMASK 0/* mask SPI interrupt */ #define KWSPI_SMEMRDIRQ 1/* SerMem data xfer ready irq */ drivers/spi/kirkwood_spi.c +59
-4@@ -243,6 +243,16 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,/* Here now the DM part */ +enum mvebu_spi_type { +ORION_SPI , +ARMADA_SPI , +}; + +struct mvebu_spi_dev { +enum mvebu_spi_type typ; +bool is_errata_50mhz_ac; +}; +struct mvebu_spi_platdata {struct kwspi_registers *spireg; };@@ -269,10 +279,30 @@ static int mvebu_spi_set_speed(struct udevice *bus, uint hz)return 0 ; } +static void +mvebu_spi_50mhz_ac_timing_erratum (struct udevice *bus,uint mode) +{ +struct mvebu_spi_platdata *plat =dev_get_platdata (bus); +struct kwspi_registers *reg = plat->spireg; +u32 data =readl (®->timing1); + + data &= ~KW_SPI_TMISO_SAMPLE_MASK ; + +if (CONFIG_SYS_TCLK ==250000000 && + mode &SPI_CPOL && + mode &SPI_CPHA ) + data |=KW_SPI_TMISO_SAMPLE_2 ; +else + data |=KW_SPI_TMISO_SAMPLE_1 ; + +writel (data, ®->timing1); +} +static int mvebu_spi_set_mode (struct udevice *bus,uint mode) {struct mvebu_spi_platdata *plat =dev_get_platdata (bus);struct kwspi_registers *reg = plat->spireg; +const struct mvebu_spi_dev *drvdata;u32 data =readl (®->cfg); data &= ~(KWSPI_CPHA |KWSPI_CPOL |KWSPI_RXLSBF |KWSPI_TXLSBF );@@ -286,6 +316,10 @@ static int mvebu_spi_set_mode(struct udevice *bus, uint mode)writel (data, ®->cfg); + drvdata = (struct mvebu_spi_dev *)dev_get_driver_data (bus); +if (drvdata->is_errata_50mhz_ac) +mvebu_spi_50mhz_ac_timing_erratum (bus, mode); +return 0 ; }@@ -343,10 +377,32 @@ static const struct dm_spi_ops mvebu_spi_ops = {*/ }; +static const struct mvebu_spi_dev armada_xp_spi_dev_data = { + .typ =ARMADA_SPI , +}; + +static const struct mvebu_spi_dev armada_375_spi_dev_data = { + .typ =ARMADA_SPI , +}; + +static const struct mvebu_spi_dev armada_380_spi_dev_data = { + .typ =ARMADA_SPI , + .is_errata_50mhz_ac = true, +}; +static const struct udevice_id mvebu_spi_ids[] = { - { .compatible ="marvell,armada-375-spi" }, - { .compatible ="marvell,armada-380-spi" }, - { .compatible ="marvell,armada-xp-spi" }, + { + .compatible ="marvell,armada-375-spi" , + .data = (ulong)&armada_375_spi_dev_data + }, + { + .compatible ="marvell,armada-380-spi" , + .data = (ulong)&armada_380_spi_dev_data + }, + { + .compatible ="marvell,armada-xp-spi" , + .data = (ulong)&armada_xp_spi_dev_data + }, { } }; --2.14.2
PATCH 1/1 spi: kirkwood_spi: implement workaround for FE-9144572
In reply to Chris PackhamQuoted 123 lines · Chris Packham
Erratum NO. FE-9144572: The device SPI interface supports frequencies of up to 50 MHz. However, due to this erratum, when the device core clock is 250 MHz and the SPI interfaces is configured for 50MHz SPI clock and CPOL=CPHA=1 there might occur data corruption on reads from the SPI device.
Implement the workaround by setting the
TMISO_SAMPLEvalue to0x2in the timing1 register.Signed-off-by Chris Packham <[email protected]>---
arch/arm/include/asm/arch-mvebu/spi.h | 6 ++++ drivers/spi/kirkwood_spi.c | 62 +++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-)arch/arm/include/asm/arch-mvebu/spi.h +6
-0@@ -57,6 +57,12 @@ struct kwspi_registers {#define KWSPI_TXLSBF (1 << 13)#define KWSPI_RXLSBF (1 << 14) +/* Timing Parameters 1 Register */ +#define KW_SPI_TMISO_SAMPLE_OFFSET 6 +#define KW_SPI_TMISO_SAMPLE_MASK (0x3 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_1 (1 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_2 (2 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KWSPI_IRQUNMASK 1/* unmask SPI interrupt */ #define KWSPI_IRQMASK 0/* mask SPI interrupt */ #define KWSPI_SMEMRDIRQ 1/* SerMem data xfer ready irq */ drivers/spi/kirkwood_spi.c +52
-3@@ -243,6 +243,16 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,/* Here now the DM part */ +enum mvebu_spi_type { +ORION_SPI , +ARMADA_SPI , +}; + +struct mvebu_spi_dev { +enum mvebu_spi_type typ; +bool is_errata_50mhz_ac; +}; +struct mvebu_spi_platdata {struct kwspi_registers *spireg; };@@ -269,10 +279,30 @@ static int mvebu_spi_set_speed(struct udevice *bus, uint hz)return 0 ; } +static void +mvebu_spi_50mhz_ac_timing_erratum (struct udevice *bus,uint mode) +{ +struct mvebu_spi_platdata *plat =dev_get_platdata (bus); +struct kwspi_registers *reg = plat->spireg; +u32 data =readl (®->timing1); + + data &= ~KW_SPI_TMISO_SAMPLE_MASK ; + +if (CONFIG_SYS_TCLK ==250000000 && + mode &SPI_CPOL && + mode &SPI_CPHA ) + data |=KW_SPI_TMISO_SAMPLE_2 ; +else + data |=KW_SPI_TMISO_SAMPLE_1 ; + +writel (data, ®->timing1); +} +static int mvebu_spi_set_mode (struct udevice *bus,uint mode) {struct mvebu_spi_platdata *plat =dev_get_platdata (bus);struct kwspi_registers *reg = plat->spireg; +const struct mvebu_spi_dev *drvdata;u32 data =readl (®->cfg); data &= ~(KWSPI_CPHA |KWSPI_CPOL |KWSPI_RXLSBF |KWSPI_TXLSBF );@@ -286,6 +316,10 @@ static int mvebu_spi_set_mode(struct udevice *bus, uint mode)writel (data, ®->cfg); + drvdata = (struct mvebu_spi_dev *)dev_get_driver_data (bus); +if (drvdata->is_errata_50mhz_ac) +mvebu_spi_50mhz_ac_timing_erratum (bus, mode); +return 0 ; }@@ -343,10 +377,32 @@ static const struct dm_spi_ops mvebu_spi_ops = {*/ }; +static const struct mvebu_spi_dev armada_xp_spi_dev_data = { + .typ =ARMADA_SPI , +}; + +static const struct mvebu_spi_dev armada_375_spi_dev_data = { + .typ =ARMADA_SPI , +}; + +static const struct mvebu_spi_dev armada_380_spi_dev_data = { + .typ =ARMADA_SPI , + .is_errata_50mhz_ac = true, +}; +static const struct udevice_id mvebu_spi_ids[] = { - { .compatible ="marvell,armada-375-spi" }, - { .compatible ="marvell,armada-380-spi" }, - { .compatible ="marvell,armada-xp-spi" }, + { + .compatible ="marvell,armada-375-spi" , + .data = (ulong)&armada_375_spi_dev_data + }, + {
drivers/spi/kirkwood_spi.c static const struct dm_spi_ops mvebu_spi_ops = { · line 408
Quoted 10 lines
drivers/spi/kirkwood_spi.c +7
-0+ .compatible = "marvell,armada-380-spi", + .data = (ulong)&armada_380_spi_dev_data + }, + { + .compatible = "marvell,armada-xp-spi", + .data = (ulong)&armada_xp_spi_dev_data + }, { } };
Thanks,
Stefan
PATCH 1/1 spi: kirkwood_spi: implement workaround for FE-9144572
In reply to Chris PackhamQuoted 38 lines · Chris Packham
Erratum NO. FE-9144572: The device SPI interface supports frequencies of up to 50 MHz. However, due to this erratum, when the device core clock is 250 MHz and the SPI interfaces is configured for 50MHz SPI clock and CPOL=CPHA=1 there might occur data corruption on reads from the SPI device.
Implement the workaround by setting the
TMISO_SAMPLEvalue to0x2in the timing1 register.Signed-off-by Chris Packham <[email protected]>---
arch/arm/include/asm/arch-mvebu/spi.h | 6 ++++ drivers/spi/kirkwood_spi.c | 62 +++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-)arch/arm/include/asm/arch-mvebu/spi.h +6
-0@@ -57,6 +57,12 @@ struct kwspi_registers {#define KWSPI_TXLSBF (1 << 13)#define KWSPI_RXLSBF (1 << 14) +/* Timing Parameters 1 Register */ +#define KW_SPI_TMISO_SAMPLE_OFFSET 6 +#define KW_SPI_TMISO_SAMPLE_MASK (0x3 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_1 (1 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_2 (2 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KWSPI_IRQUNMASK 1/* unmask SPI interrupt */ #define KWSPI_IRQMASK 0/* mask SPI interrupt */ #define KWSPI_SMEMRDIRQ 1/* SerMem data xfer ready irq */ drivers/spi/kirkwood_spi.c +0
-0
drivers/spi/kirkwood_spi.c int spi_xfer(struct spi_slave *slave, unsigned int bitlen, · line 247
Quoted 5 lines
drivers/spi/kirkwood_spi.c +2
-0@@ -243,6 +243,16 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,/* Here now the DM part */ +enum mvebu_spi_type { +ORION_SPI ,
This is never used, since there is a separate driver in orion - any plan to merge them as single driver? otherwise it's no need.
Quoted 12 lines
drivers/spi/kirkwood_spi.c +8
-0+ ARMADA_SPI, +}; + +struct mvebu_spi_dev { +enum mvebu_spi_type typ; +bool is_errata_50mhz_ac; +}; +struct mvebu_spi_platdata {struct kwspi_registers *spireg; };
drivers/spi/kirkwood_spi.c static int mvebu_spi_set_speed(struct udevice *bus, uint hz) · line 288
Quoted 10 lines
drivers/spi/kirkwood_spi.c +7
-0@@ -269,10 +279,30 @@ static int mvebu_spi_set_speed(struct udevice *bus, uint hz)return 0 ; } +static void +mvebu_spi_50mhz_ac_timing_erratum (struct udevice *bus,uint mode) +{ +struct mvebu_spi_platdata *plat =dev_get_platdata (bus); +struct kwspi_registers *reg = plat->spireg; +u32 data =readl (®->timing1); +
Better to have description of errata.
thanks!
Signature · 4 lines
Jagan Teki Free Software Engineer | www.openedev.com U-Boot, Linux | Upstream Maintainer Hyderabad, India.
PATCH 1/1 spi: kirkwood_spi: implement workaround for FE-9144572
Quoted 40 lines · Jagan Teki
Quoted 39 lines · Chris Packham
Erratum NO. FE-9144572: The device SPI interface supports frequencies of up to 50 MHz. However, due to this erratum, when the device core clock is 250 MHz and the SPI interfaces is configured for 50MHz SPI clock and CPOL=CPHA=1 there might occur data corruption on reads from the SPI device.
Implement the workaround by setting the
TMISO_SAMPLEvalue to0x2in the timing1 register.Signed-off-by Chris Packham <[email protected]>---
arch/arm/include/asm/arch-mvebu/spi.h | 6 ++++ drivers/spi/kirkwood_spi.c | 62 +++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-)arch/arm/include/asm/arch-mvebu/spi.h +6
-0@@ -57,6 +57,12 @@ struct kwspi_registers {#define KWSPI_TXLSBF (1 << 13)#define KWSPI_RXLSBF (1 << 14) +/* Timing Parameters 1 Register */ +#define KW_SPI_TMISO_SAMPLE_OFFSET 6 +#define KW_SPI_TMISO_SAMPLE_MASK (0x3 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_1 (1 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KW_SPI_TMISO_SAMPLE_2 (2 << KW_SPI_TMISO_SAMPLE_OFFSET) +#define KWSPI_IRQUNMASK 1/* unmask SPI interrupt */ #define KWSPI_IRQMASK 0/* mask SPI interrupt */ #define KWSPI_SMEMRDIRQ 1/* SerMem data xfer ready irq */ drivers/spi/kirkwood_spi.c +0
-0@@ -243,6 +243,16 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
Quoted 8 lines
drivers/spi/kirkwood_spi.c int spi_xfer(struct spi_slave *slave, unsigned int bitlen, · line 247
Quoted 4 lines
drivers/spi/kirkwood_spi.c +2
-0/* Here now the DM part */ +enum mvebu_spi_type { +ORION_SPI ,This is never used, since there is a separate driver in orion - any plan to merge them as single driver? otherwise it's no need.
I actually do have access to some Kirkwood hardware. But a distinct lack of round tuits to port it to master/DM/etc.
For now I'll drop the type. It can be added back if/when a user emerges.
Quoted 15 lines
Quoted 15 lines
drivers/spi/kirkwood_spi.c +8
-0+ ARMADA_SPI, +}; + +struct mvebu_spi_dev { +enum mvebu_spi_type typ; +bool is_errata_50mhz_ac; +}; +struct mvebu_spi_platdata {struct kwspi_registers *spireg; };@@ -269,10 +279,30 @@ static int mvebu_spi_set_speed(struct udevice *bus, uint hz)return 0 ; }
Quoted 10 lines
drivers/spi/kirkwood_spi.c static int mvebu_spi_set_speed(struct udevice *bus, uint hz) · line 288
Quoted 7 lines
drivers/spi/kirkwood_spi.c +7
-0+static void +mvebu_spi_50mhz_ac_timing_erratum (struct udevice *bus,uint mode) +{ +struct mvebu_spi_platdata *plat =dev_get_platdata (bus); +struct kwspi_registers *reg = plat->spireg; +u32 data =readl (®->timing1); +Better to have description of errata.
Will add in v2.
Quoted 6 lines
thanks!
--
Jagan Teki
Free Software Engineer | www.openedev.com
U-Boot, Linux | Upstream Maintainer
Hyderabad, India.