Skip to contentSkip to conversation

omap2_mcspi.c: Clock divider range check wrong for OMAP3

PATCH In review Scott Ellis 3 participants 3 messages Mar 8, 2010 SPI

lore
Share & tools
lore
#0 lore raw

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
index fe1b56d..a73127b 100644
@@ -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;
                }
 
#1 lore raw
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 0x0C not 0x0F. 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.

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

#2 lore raw
In reply to Scott Ellis
Quoted 8 lines · Scott Ellis
drivers/spi/omap2_mcspi.c +0 -0
index fe1b56d..a73127b 100644
@@ -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