All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
@ 2015-08-01 22:06 ` Hermann Kraus
  0 siblings, 0 replies; 10+ messages in thread
From: Hermann Kraus @ 2015-08-01 22:06 UTC (permalink / raw)
  To: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Brown,
	Maxime Ripard

Use requested bit rate instead of maximum possible and correctly calculate
the divider.

There are two different maximum bitrates. "max_speed_hz" which is the  
maximum
for a given SPI device and "speed_hz" in "struct spi_transfer" which is  
the rate
used for this transfer. If "speed_hz" is non-zero it must be used.
The divider must be calculated by calling ilog2 only once, because this  
function
truncates the fractional part. Calling it twice increases the error so  
much that
certain bit rates which are available from the hardware can't be reached by
the kernel.
The result of this calculation must be checked to fit into the register  
size
instead of being truncated silently.

Signed-off-by: Hermann Kraus <hermr2d2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
  drivers/spi/spi-sun4i.c | 16 ++++++++++++----
  drivers/spi/spi-sun6i.c | 16 ++++++++++++----
  2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index fbb0a4d..82d717d 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -173,6 +173,7 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	unsigned int tx_len = 0;
  	int ret = 0;
  	u32 reg;
+	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

  	/* We don't support transfer larger than the FIFO */
  	if (tfr->len > SUN4I_FIFO_DEPTH)
@@ -229,8 +230,8 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -248,14 +249,21 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * speed_hz);
  	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / speed_hz + 1);
+		if (div & ~SUN4I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN4I_CLK_CTL_CDR1(div);
  	}

diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index ac48f59..c3870be 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -163,6 +163,7 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	unsigned int tx_len = 0;
  	int ret = 0;
  	u32 reg;
+	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

  	/* We don't support transfer larger than the FIFO */
  	if (tfr->len > SUN6I_FIFO_DEPTH)
@@ -217,8 +218,8 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -236,14 +237,21 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * speed_hz);
  	if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / speed_hz + 1);
+		if (div & ~SUN6I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN6I_CLK_CTL_CDR1(div);
  	}

-- 
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
@ 2015-08-01 22:06 ` Hermann Kraus
  0 siblings, 0 replies; 10+ messages in thread
From: Hermann Kraus @ 2015-08-01 22:06 UTC (permalink / raw)
  To: linux-arm-kernel

Use requested bit rate instead of maximum possible and correctly calculate
the divider.

There are two different maximum bitrates. "max_speed_hz" which is the  
maximum
for a given SPI device and "speed_hz" in "struct spi_transfer" which is  
the rate
used for this transfer. If "speed_hz" is non-zero it must be used.
The divider must be calculated by calling ilog2 only once, because this  
function
truncates the fractional part. Calling it twice increases the error so  
much that
certain bit rates which are available from the hardware can't be reached by
the kernel.
The result of this calculation must be checked to fit into the register  
size
instead of being truncated silently.

Signed-off-by: Hermann Kraus <hermr2d2@gmail.com>
---
  drivers/spi/spi-sun4i.c | 16 ++++++++++++----
  drivers/spi/spi-sun6i.c | 16 ++++++++++++----
  2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index fbb0a4d..82d717d 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -173,6 +173,7 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	unsigned int tx_len = 0;
  	int ret = 0;
  	u32 reg;
+	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

  	/* We don't support transfer larger than the FIFO */
  	if (tfr->len > SUN4I_FIFO_DEPTH)
@@ -229,8 +230,8 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -248,14 +249,21 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * speed_hz);
  	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / speed_hz + 1);
+		if (div & ~SUN4I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN4I_CLK_CTL_CDR1(div);
  	}

diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index ac48f59..c3870be 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -163,6 +163,7 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	unsigned int tx_len = 0;
  	int ret = 0;
  	u32 reg;
+	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

  	/* We don't support transfer larger than the FIFO */
  	if (tfr->len > SUN6I_FIFO_DEPTH)
@@ -217,8 +218,8 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -236,14 +237,21 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * speed_hz);
  	if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / speed_hz + 1);
+		if (div & ~SUN6I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN6I_CLK_CTL_CDR1(div);
  	}

-- 
2.1.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
  2015-08-01 22:06 ` Hermann Kraus
@ 2015-08-04 17:19   ` Mark Brown
  -1 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2015-08-04 17:19 UTC (permalink / raw)
  To: Hermann Kraus
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Maxime Ripard

[-- Attachment #1: Type: text/plain, Size: 367 bytes --]

On Sun, Aug 02, 2015 at 12:06:31AM +0200, Hermann Kraus wrote:

> +	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

You don't need to do this anyway since the framework will always ensure
that speed_hz is set so you can just use it unconditionally but in
general please don't use the ternery operator unless it's adding
something, it's not a legibility triumph.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
@ 2015-08-04 17:19   ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2015-08-04 17:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Aug 02, 2015 at 12:06:31AM +0200, Hermann Kraus wrote:

> +	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

You don't need to do this anyway since the framework will always ensure
that speed_hz is set so you can just use it unconditionally but in
general please don't use the ternery operator unless it's adding
something, it's not a legibility triumph.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/c2012e8d/attachment.sig>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
  2015-08-04 17:19   ` Mark Brown
@ 2015-08-06 20:51       ` Hermann Kraus
  -1 siblings, 0 replies; 10+ messages in thread
From: Hermann Kraus @ 2015-08-06 20:51 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Maxime Ripard

Use requested bit rate instead of maximum possible and correctly calculate
the divider.

There are two different maximum bitrates. "max_speed_hz" which is the
maximum for a given SPI device and "speed_hz" in "struct spi_transfer"
which is the rate used for this transfer. "speed_hz" must always be
used as the actual transfer rate.
The divider must be calculated by calling ilog2 only once, because this
function truncates the fractional part. Calling it twice increases
the error so much that certain bit rates which are available from the
hardware can't be reached by the kernel.
The result of this calculation must be checked to fit into the register
size instead of being truncated silently.

Signed-off-by: Hermann Kraus <hermr2d2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---

Changes to v1: Unconditionally use tfr->speed_hz as requested by Mark  
Brown.


  drivers/spi/spi-sun4i.c | 15 +++++++++++----
  drivers/spi/spi-sun6i.c | 15 +++++++++++----
  2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index fbb0a4d..729d70b 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -229,8 +229,8 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * tfr->speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * tfr->speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -248,14 +248,21 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * tfr->speed_hz);
  	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / tfr->speed_hz + 1);
+		if (div & ~SUN4I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN4I_CLK_CTL_CDR1(div);
  	}

diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index ac48f59..2d3dcda 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -217,8 +217,8 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * tfr->speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * tfr->speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -236,14 +236,21 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * tfr->speed_hz);
  	if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / tfr->speed_hz + 1);
+		if (div & ~SUN6I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN6I_CLK_CTL_CDR1(div);
  	}

-- 
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
@ 2015-08-06 20:51       ` Hermann Kraus
  0 siblings, 0 replies; 10+ messages in thread
From: Hermann Kraus @ 2015-08-06 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

Use requested bit rate instead of maximum possible and correctly calculate
the divider.

There are two different maximum bitrates. "max_speed_hz" which is the
maximum for a given SPI device and "speed_hz" in "struct spi_transfer"
which is the rate used for this transfer. "speed_hz" must always be
used as the actual transfer rate.
The divider must be calculated by calling ilog2 only once, because this
function truncates the fractional part. Calling it twice increases
the error so much that certain bit rates which are available from the
hardware can't be reached by the kernel.
The result of this calculation must be checked to fit into the register
size instead of being truncated silently.

Signed-off-by: Hermann Kraus <hermr2d2@gmail.com>
---

Changes to v1: Unconditionally use tfr->speed_hz as requested by Mark  
Brown.


  drivers/spi/spi-sun4i.c | 15 +++++++++++----
  drivers/spi/spi-sun6i.c | 15 +++++++++++----
  2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index fbb0a4d..729d70b 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -229,8 +229,8 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * tfr->speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * tfr->speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -248,14 +248,21 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * tfr->speed_hz);
  	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / tfr->speed_hz + 1);
+		if (div & ~SUN4I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN4I_CLK_CTL_CDR1(div);
  	}

diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index ac48f59..2d3dcda 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -217,8 +217,8 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * tfr->speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * tfr->speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -236,14 +236,21 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * tfr->speed_hz);
  	if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / tfr->speed_hz + 1);
+		if (div & ~SUN6I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN6I_CLK_CTL_CDR1(div);
  	}

-- 
2.1.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
  2015-08-06 20:51       ` Hermann Kraus
@ 2015-08-07 13:14         ` Mark Brown
  -1 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2015-08-07 13:14 UTC (permalink / raw)
  To: Hermann Kraus
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Maxime Ripard

[-- Attachment #1: Type: text/plain, Size: 329 bytes --]

On Thu, Aug 06, 2015 at 10:51:10PM +0200, Hermann Kraus wrote:
> Use requested bit rate instead of maximum possible and correctly calculate
> the divider.

Please don't put things like "Re: " at the start of subject lines for
patch submissions, it makes it look like a reply to an existing thread
rather than a patch submission.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
@ 2015-08-07 13:14         ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2015-08-07 13:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Aug 06, 2015 at 10:51:10PM +0200, Hermann Kraus wrote:
> Use requested bit rate instead of maximum possible and correctly calculate
> the divider.

Please don't put things like "Re: " at the start of subject lines for
patch submissions, it makes it look like a reply to an existing thread
rather than a patch submission.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/bc88d35c/attachment.sig>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
  2015-08-06 20:51       ` Hermann Kraus
@ 2015-08-07 13:16         ` Mark Brown
  -1 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2015-08-07 13:16 UTC (permalink / raw)
  To: Hermann Kraus
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Maxime Ripard

[-- Attachment #1: Type: text/plain, Size: 222 bytes --]

On Thu, Aug 06, 2015 at 10:51:10PM +0200, Hermann Kraus wrote:
> Use requested bit rate instead of maximum possible and correctly calculate
> the divider.

This doesn't apply against current code, please check and resend.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
@ 2015-08-07 13:16         ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2015-08-07 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Aug 06, 2015 at 10:51:10PM +0200, Hermann Kraus wrote:
> Use requested bit rate instead of maximum possible and correctly calculate
> the divider.

This doesn't apply against current code, please check and resend.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/d45010eb/attachment.sig>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-08-07 13:16 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-01 22:06 [PATCH] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation Hermann Kraus
2015-08-01 22:06 ` Hermann Kraus
2015-08-04 17:19 ` Mark Brown
2015-08-04 17:19   ` Mark Brown
     [not found]   ` <20150804171931.GZ20873-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2015-08-06 20:51     ` [PATCH v2] " Hermann Kraus
2015-08-06 20:51       ` Hermann Kraus
2015-08-07 13:14       ` Mark Brown
2015-08-07 13:14         ` Mark Brown
2015-08-07 13:16       ` Mark Brown
2015-08-07 13:16         ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.