Skip to contentSkip to conversation

DaVinci SPI: Fix SPI clock prescale factor computation

PATCH New [email protected] 2 participants 4 messages Apr 26, 2010 – May 31, 2010 4 messages not in the archive SPI

lore
Share & tools
lore
#3 lore raw

PATCH 1/1 DaVinci SPI: Fix SPI clock prescale factor computation

In reply to a message not in the archive

From: Thomas Koeller <[email protected]>

Computation of the clock prescaler value returned bogus results if the requested SPI clock was impossible to set. It now sets either the maximum or minimum clock frequency, as appropriate.

---
 drivers/spi/davinci_spi.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +9 -3
index 956f617..02e1a76 100644
@@ -153,7 +153,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
 	struct davinci_spi *davinci_spi;
 	struct davinci_spi_platform_data *pdata;
 	u8 bits_per_word = 0;
-	u32 hz = 0, prescale;
+	u32 hz = 0, prescale = 0, clkspeed;
 
 	davinci_spi = spi_master_get_devdata(spi->master);
 	pdata = davinci_spi->pdata;
@@ -190,10 +190,16 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
 	set_fmt_bits(davinci_spi->base, bits_per_word & 0x1f,
 			spi->chip_select);
 
-	prescale = ((clk_get_rate(davinci_spi->clk) / hz) - 1) & 0xff;
+	clkspeed = clk_get_rate(davinci_spi->clk);
+	if (hz > clkspeed / 2)
+		prescale = 1 << 8;
+	if (hz < clkspeed / 256)
+		prescale = 255 << 8;
+	if (!prescale)
+		prescale = ((clkspeed / hz - 1) << 8) & 0x0000ff00;
 
 	clear_fmt_bits(davinci_spi->base, 0x0000ff00, spi->chip_select);
-	set_fmt_bits(davinci_spi->base, prescale << 8, spi->chip_select);
+	set_fmt_bits(davinci_spi->base, prescale, spi->chip_select);
 
 	return 0;
 }
Signature · 4 lines
1.7.0.3


------------------------------------------------------------------------------
#5 lore raw
In reply to a message not in the archive
Quoted 26 lines · On Mon, Apr 26, 2010 at 3:01 AM, <thomas.koeller-x9WYMywdo8BF6kxbq+BtvQ@public…

From: Thomas Koeller <[email protected]>

Computation of the clock prescaler value returned bogus results if the requested SPI clock was impossible to set. It now sets either the maximum or minimum clock frequency, as appropriate.

---
 drivers/spi/davinci_spi.c |   12 +++++++++---

 1 files changed, 9 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +1 -1
index 956f617..02e1a76 100644
@@ -153,7 +153,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
        struct davinci_spi *davinci_spi;
        struct davinci_spi_platform_data *pdata;
        u8 bits_per_word = 0;
-       u32 hz = 0, prescale;
+       u32 hz = 0, prescale = 0, clkspeed;
 
        davinci_spi = spi_master_get_devdata(spi->master);
        pdata = davinci_spi->pdata;
@@ -190,10 +190,16 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
        set_fmt_bits(davinci_spi->base, bits_per_word & 0x1f,

drivers/spi/davinci_spi.c static int davinci_spi_setup_transfer(struct spi_device *spi, · line 199

Quoted 10 lines
drivers/spi/davinci_spi.c +7 -1
                        spi->chip_select);
 
-       prescale = ((clk_get_rate(davinci_spi->clk) / hz) - 1) & 0xff;
+       clkspeed = clk_get_rate(davinci_spi->clk);
+       if (hz > clkspeed / 2)
+               prescale = 1 << 8;
+       if (hz < clkspeed / 256)
+               prescale = 255 << 8;
+       if (!prescale)
+               prescale = ((clkspeed / hz - 1) << 8) & 0x0000ff00;

Is be appropriate to WARN_ON() or WARN_ONCE() when the clamp condition occurs? Particularly the condition where the minimum clock speed is higher that the requested clock.

I'd also consider an if / else if / else structure for readability and clarity.

g.

------------------------------------------------------------------------------

#7 lore raw

PATCH 1/1 DaVinci SPI: Fix SPI clock prescale factor computation

In reply to a message not in the archive

From: Thomas Koeller <[email protected]>

Computation of the clock prescaler value returned bogus results if the requested SPI clock was impossible to set. It now sets either the maximum or minimum clock frequency, as appropriate.

---
 drivers/spi/davinci_spi.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +0 -0
index 956f617..5c69d78 100644
@@ -153,7 +153,7 @@ static int davinci_spi_setup_transfer(struct spi_device 

*spi,
struct davinci_spi *davinci_spi;
struct davinci_spi_platform_data *pdata;
u8 bits_per_word = 0;
- u32 hz = 0, prescale;
+ u32 hz = 0, prescale, clkspeed;

davinci_spi = spi_master_get_devdata(spi->master);
pdata = davinci_spi->pdata;
@@ -190,10 +190,16 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
set_fmt_bits(davinci_spi->base, bits_per_word & 0x1f,
spi->chip_select);

- prescale = ((clk_get_rate(davinci_spi->clk) / hz) - 1) & 0xff;
+ clkspeed = clk_get_rate(davinci_spi->clk);
+ if (WARN_ON(hz > clkspeed / 2))
+ prescale = 1 << 8;
+ else if (WARN_ON(hz < clkspeed / 256))
+ prescale = 255 << 8;
+ else
+ prescale = ((clkspeed / hz - 1) << 8) & 0x0000ff00;

clear_fmt_bits(davinci_spi->base, 0x0000ff00, spi->chip_select);
- set_fmt_bits(davinci_spi->base, prescale << 8, spi->chip_select);
+ set_fmt_bits(davinci_spi->base, prescale, spi->chip_select);

return 0;
}

Signature · 4 lines
1.7.0.3


------------------------------------------------------------------------------