omap2_mcspi.c: Clock divider range check wrong for OMAP3
PATCH 1/1 omap2_mcspi.c: Clock divider range check wrong for OMAP3
The clock divider range check is wrong for the OMAP3.
The MCSPI_CHxCONF.CLKD register field has a max value 0x0C not 0x0F. Reference was the OMAP3 TRM Rev. D manual.
I don't know whether the old value was correct for OMAP24xxx boards so I put in some #ifdef stuff. Maybe someone with access to the OMAP24xxx manual could check if that is necessary.
drivers/spi/omap2_mcspi.c | 24 +++++++++++++++++------- 1 files changed, 17 insertions(+), 7 deletions(-)
drivers/spi/omap2_mcspi.c +17 -7
@@ -38,8 +38,17 @@#include <plat/dma.h> #include <plat/clock.h> +#if defined(CONFIG_ARCH_OMAP3 ) || defined(CONFIG_ARCH_OMAP4 ) +#define OMAP2_MCSPI_MAX_CLK_DIV 12 +#else +/* could be 12 for OMAP24xxx also, no docs to check */ +#define OMAP2_MCSPI_MAX_CLK_DIV 15 +#endif #define OMAP2_MCSPI_MAX_FREQ 48000000 +#define OMAP2_MCSPI_MIN_FREQ (OMAP2_MCSPI_MAX_FREQ \ + / (1 << OMAP2_MCSPI_MAX_CLK_DIV)) +/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */ #define OMAP2_MCSPI_MAX_CTRL 4
@@ -588,11 +597,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, cs->word_len = word_len;if (spi->max_speed_hz) { -while (div <=15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div)) - > spi->max_speed_hz) +while (div <=OMAP2_MCSPI_MAX_CLK_DIV && + (OMAP2_MCSPI_MAX_FREQ / (1 << div)) > spi->max_speed_hz) div++; - }else - div =15 ; + }else { + div =OMAP2_MCSPI_MAX_CLK_DIV ; + } l =mcspi_cached_chconf0 (spi);
@@ -917,10 +927,10 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) t->bits_per_word);return -EINVAL ; } -if (t->speed_hz && t->speed_hz <OMAP2_MCSPI_MAX_FREQ /(1 <<16 )) { -dev_dbg (&spi->dev,"%d Hz max exceeds %d\n" , +if (t->speed_hz && t->speed_hz <OMAP2_MCSPI_MIN_FREQ ) { +dev_dbg (&spi->dev,"%d Hz slower then hardware minimum %d\n" , t->speed_hz, -OMAP2_MCSPI_MAX_FREQ /(1 <<16 )); +OMAP2_MCSPI_MIN_FREQ );return -EINVAL ; }
Quoted 6 lines · Scott Ellis
The clock divider range check is wrong for the OMAP3.
The MCSPI_CHxCONF.CLKD register field has a max value
0x0Cnot0x0F. Reference was the OMAP3 TRM Rev. D manual.
Quoted 6 lines
I don't know whether the old value was correct for OMAP24xxx boards so I put in some #ifdef stuff. Maybe someone with access to the OMAP24xxx manual could check if that is necessary.
Signed-off-by Scott Ellis <[email protected]>
I took a look at current 34xx TRM (Rev Z) and 2430 TRM (Rev Z again). You're right in that the 3430 has a max value of 0x0C for this field.
The 2430 TRM says 0x0F is valid for the corresponding field there.
Not really sure what is the correct value, but at least the documentation says you're right.
Hope this helps.
- Anand
Quoted 8 lines · Scott Ellis
drivers/spi/omap2_mcspi.c +0
-0@@ -38,8 +38,17 @@#include <plat/dma.h> #include <plat/clock.h>
drivers/spi/omap2_mcspi.c line 50
Quoted 10 lines
drivers/spi/omap2_mcspi.c +8
-0+#if defined(CONFIG_ARCH_OMAP3 ) || defined(CONFIG_ARCH_OMAP4 ) +#define OMAP2_MCSPI_MAX_CLK_DIV 12 +#else +/* could be 12 for OMAP24xxx also, no docs to check */ +#define OMAP2_MCSPI_MAX_CLK_DIV 15 +#endif #define OMAP2_MCSPI_MAX_FREQ 48000000 +#define OMAP2_MCSPI_MIN_FREQ (OMAP2_MCSPI_MAX_FREQ \ + / (1 << OMAP2_MCSPI_MAX_CLK_DIV))
please don't break multi-omap builds. Pass this constant using platform_data.
Signature · 1 line
balbi