This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[PATCH] DM81XX: use one clock cycle granularity to set SPI clock speed

Hello,

We are publishing this patch here because the linux GIT tree associated with this SoC (http://arago-project.org/git/projects/?p=linux-omap3.git;a=summary) has no mailing list for discussing patches (as far as we know). We hope it will be useful to others and be eventually merged in TI's source tree.

Regards
--
Delio Brignoli

Author: Stephen <sgturner@audioscience.com>
Date:   Tue Dec 11 14:21:38 2012 -0800

    use TI81XX one clock cycle granularity to set SPI clock speed.

diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 06f586e..79f24b9 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -90,11 +90,21 @@
 #define OMAP2_MCSPI_CHCONF_TURBO       BIT(19)
 #define OMAP2_MCSPI_CHCONF_FORCE       BIT(20)
 
+#if defined(CONFIG_ARCH_TI81XX)
+// additional CHCONF bits that are TI81XX specific
+#define OMAP2_MCSPI_CHCONF_TCS_MASK    (0x03 << 25)
+#define OMAP2_MCSPI_CHCONF_CLKG                BIT(29)
+#endif
+
 #define OMAP2_MCSPI_CHSTAT_RXS         BIT(0)
 #define OMAP2_MCSPI_CHSTAT_TXS         BIT(1)
 #define OMAP2_MCSPI_CHSTAT_EOT         BIT(2)
 
 #define OMAP2_MCSPI_CHCTRL_EN          BIT(0)
+#if defined(CONFIG_ARCH_TI81XX)
+// additional CHCTRL bits that are TI81XX specific
+#define OMAP2_MCSPI_CHCTRL_EXTCLK_MASK (0xFF << 8)
+#endif
 
 #define OMAP2_MCSPI_WAKEUPENABLE_WKEN  BIT(0)
 
@@ -229,9 +239,12 @@ static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
 
 static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable)
 {
-       u32 l;
+       u32 l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
 
-       l = enable ? OMAP2_MCSPI_CHCTRL_EN : 0;
+       /*l = enable ? OMAP2_MCSPI_CHCTRL_EN : 0;*/
+       l &= ~OMAP2_MCSPI_CHCTRL_EN;
+       if (enable )
+               l |= OMAP2_MCSPI_CHCTRL_EN;
        mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, l);
        /* Flash post-writes */
        mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
@@ -663,6 +676,9 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
        struct omap2_mcspi *mcspi;
        struct spi_master *spi_cntrl;
        u32 l = 0, div = 0;
+       #if defined(CONFIG_ARCH_TI81XX)
+       u32 ctrl_reg=0;
+       #endif
        u8 word_len = spi->bits_per_word;
        u32 speed_hz = spi->max_speed_hz;
 
@@ -677,12 +693,25 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
        if (t && t->speed_hz)
                speed_hz = t->speed_hz;
 
+       #if defined(CONFIG_ARCH_TI81XX)
+       /* use "one clock cycle granularity" to program SPI clock */
+       if (speed_hz) {
+               div = (OMAP2_MCSPI_MAX_FREQ/speed_hz)-1;
+               /* if we are in-between frequencies then use next highest divider */
+               if((OMAP2_MCSPI_MAX_FREQ % speed_hz) !=0 )
+                       div++;
+               if(div > 0xFFF)
+                       div = 0xFFF;
+       } else
+               div = 0xFFF;    /* divide by 4096 */
+       #else /* use default "power of 2 granularity" to program SPI clock */
        if (speed_hz) {
                while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div))
                                        > speed_hz)
                        div++;
        } else
                div = 15;
+       #endif
 
        l = mcspi_cached_chconf0(spi);
 
@@ -702,9 +731,20 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
        else
                l &= ~OMAP2_MCSPI_CHCONF_EPOL;
 
+       #if defined(CONFIG_ARCH_TI81XX)
+       /* use "one clock cycle granularity" to program SPI clock */
+       l |= OMAP2_MCSPI_CHCONF_CLKG;
+       l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK;
+       l |= ((div & 0xF) << 2);
+       ctrl_reg = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
+       ctrl_reg &= ~OMAP2_MCSPI_CHCTRL_EXTCLK_MASK;
+       ctrl_reg |= ((div >> 4) <<8 );
+       mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, ctrl_reg);
+       #else
        /* set clock divisor */
        l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK;
        l |= div << 2;
+       #endif
 
        /* set SPI mode 0..3 */
        if (spi->mode & SPI_CPOL)
@@ -716,6 +756,10 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
        else
                l &= ~OMAP2_MCSPI_CHCONF_PHA;
 
+       #if defined(CONFIG_ARCH_TI81XX)
+       l &= ~OMAP2_MCSPI_CHCONF_TCS_MASK;      /* set num clk cycles between CS active and 1st edge of clock to 0.5 */
+       #endif
+
        mcspi_write_chconf0(spi, l);
 
        dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",