diff mbox

[v3] spi: dts: sun4i: Add support for hardware-based wait time between words

Message ID 1450047853-9005-1-git-send-email-mweseloh42@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Marcus Weseloh Dec. 13, 2015, 11:04 p.m. UTC
Adds a new property "spi-word-wait-ns" to the spi-bus binding that allows
SPI slave devices to set a hardware based wait time between the
transmission of words. Also modifies the sun4i SPI master driver to make
use of the new property. This specific SPI controller needs 3 clock
cycles to set up the delay, which makes the minimum non-zero wait time
on this hardware 4 clock cycles.

Signed-off-by: Marcus Weseloh <mweseloh42@gmail.com>
---
Changes from v1:
 * renamed the property for more clarity
 * wait time is set in nanoseconds instead of number of clock cycles
 * transparently handle the 3 setup clock cycles

Changes from v2:
 * fixed typo in comment
 * moved parameter to spi-bus binding, dropping the vendor prefix
 * changed commit summary and description to reflect the changes
---
 Documentation/devicetree/bindings/spi/spi-bus.txt |  2 ++
 drivers/spi/spi-sun4i.c                           | 23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+)

Comments

Mark Brown Dec. 13, 2015, 11:08 p.m. UTC | #1
On Mon, Dec 14, 2015 at 12:04:11AM +0100, Marcus Weseloh wrote:
> Adds a new property "spi-word-wait-ns" to the spi-bus binding that allows

Please don't bury patches in reply to existing serieses, it makes it
hard to follow what's going on with regard to which versions are current
and so on.
Marcus Weseloh Dec. 13, 2015, 11:23 p.m. UTC | #2
2015-12-14 0:08 GMT+01:00 Mark Brown <broonie@kernel.org>:
> Please don't bury patches in reply to existing serieses, it makes it
> hard to follow what's going on with regard to which versions are current
> and so on.

Thanks for the pointer, I will send patches like you ask from now on.
Should I resend the patch?

Cheers,

   Marcus
Rob Herring (Arm) Dec. 14, 2015, 1:29 a.m. UTC | #3
On Mon, Dec 14, 2015 at 12:04:11AM +0100, Marcus Weseloh wrote:
> Adds a new property "spi-word-wait-ns" to the spi-bus binding that allows
> SPI slave devices to set a hardware based wait time between the
> transmission of words. Also modifies the sun4i SPI master driver to make
> use of the new property. This specific SPI controller needs 3 clock
> cycles to set up the delay, which makes the minimum non-zero wait time
> on this hardware 4 clock cycles.
> 
> Signed-off-by: Marcus Weseloh <mweseloh42@gmail.com>
> ---
> Changes from v1:
>  * renamed the property for more clarity
>  * wait time is set in nanoseconds instead of number of clock cycles
>  * transparently handle the 3 setup clock cycles
> 
> Changes from v2:
>  * fixed typo in comment
>  * moved parameter to spi-bus binding, dropping the vendor prefix
>  * changed commit summary and description to reflect the changes
> ---
>  Documentation/devicetree/bindings/spi/spi-bus.txt |  2 ++
>  drivers/spi/spi-sun4i.c                           | 23 +++++++++++++++++++++++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
> index bbaa857..2d6034f 100644
> --- a/Documentation/devicetree/bindings/spi/spi-bus.txt
> +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
> @@ -61,6 +61,8 @@ contain the following properties.
>                        used for MOSI. Defaults to 1 if not present.
>  - spi-rx-bus-width - (optional) The bus width(number of data wires) that
>                        used for MISO. Defaults to 1 if not present.
> +- spi-word-wait-ns - (optional) Hardware based delay between transmission of
> +                      words in nanoseconds

Could be a software delay if the h/w doesn't support delays.

>  Some SPI controllers and devices support Dual and Quad SPI transfer mode.
>  It allows data in the SPI system to be transferred in 2 wires(DUAL) or 4 wires(QUAD).
> diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
> index f60a6d6..73995a1 100644
> --- a/drivers/spi/spi-sun4i.c
> +++ b/drivers/spi/spi-sun4i.c
> @@ -19,6 +19,7 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/of.h>
>  
>  #include <linux/spi/spi.h>
>  
> @@ -173,6 +174,9 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  	unsigned int tx_len = 0;
>  	int ret = 0;
>  	u32 reg;
> +	u32 wait_ns = 0;
> +	int wait_clk = 0;
> +	int clk_ns = 0;
>  
>  	/* We don't support transfer larger than the FIFO */
>  	if (tfr->len > SUN4I_FIFO_DEPTH)
> @@ -261,6 +265,25 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  
>  	sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg);
>  
> +	/* Setup wait time between words */
> +	of_property_read_u32(spi->dev.of_node, "spi-word-wait-ns",
> +			     &wait_ns);

Read this in probe and save the value rather than fetching every 
transfer.

> +	if (wait_ns) {
> +		/* The wait time is set in SPI_CLK cycles. The SPI hardware
> +		 * needs 3 additional cycles to setup the wait counter, so
> +		 * the minimum delay time is 4 cycles.
> +		 */
> +		clk_ns = DIV_ROUND_UP(1000000000, tfr->speed_hz);
> +		wait_clk = DIV_ROUND_UP(wait_ns, clk_ns) - 3;
> +		if (wait_clk < 1) {
> +			wait_clk = 1;
> +			dev_info(&spi->dev,
> +				 "using minimum of 4 word wait cycles (%uns)",
> +				 4 * clk_ns);
> +		}
> +	}
> +	sun4i_spi_write(sspi, SUN4I_WAIT_REG, (u16)wait_clk);
> +
>  	/* Setup the transfer now... */
>  	if (sspi->tx_buf)
>  		tx_len = tfr->len;
> -- 
> 1.9.1
>
Marcus Weseloh Dec. 14, 2015, 7:31 a.m. UTC | #4
Hi,

2015-12-14 2:29 GMT+01:00 Rob Herring <robh@kernel.org>:
> On Mon, Dec 14, 2015 at 12:04:11AM +0100, Marcus Weseloh wrote:
>> Adds a new property "spi-word-wait-ns" to the spi-bus binding that allows
[...]
>> diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
>> index bbaa857..2d6034f 100644
>> --- a/Documentation/devicetree/bindings/spi/spi-bus.txt
>> +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
>> @@ -61,6 +61,8 @@ contain the following properties.
>>                        used for MOSI. Defaults to 1 if not present.
>>  - spi-rx-bus-width - (optional) The bus width(number of data wires) that
>>                        used for MISO. Defaults to 1 if not present.
>> +- spi-word-wait-ns - (optional) Hardware based delay between transmission of
>> +                      words in nanoseconds
>
> Could be a software delay if the h/w doesn't support delays.

Of course, I was still trapped in my sun4i specific thinking. Will
remove the hardware reference.

[...]
>> +     /* Setup wait time between words */
>> +     of_property_read_u32(spi->dev.of_node, "spi-word-wait-ns",
>> +                          &wait_ns);
>
> Read this in probe and save the value rather than fetching every
> transfer.

But this is a slave property I'm using here. If I read and store it in
probe in the spi-sun4i driver, I won't have access to the slave node
property, will I?

Cheers,

    Marcus
Marcus Weseloh Dec. 14, 2015, 8:08 a.m. UTC | #5
2015-12-14 8:31 GMT+01:00 Marcus Weseloh <mweseloh42@gmail.com>:
> [...]
>>> +     /* Setup wait time between words */
>>> +     of_property_read_u32(spi->dev.of_node, "spi-word-wait-ns",
>>> +                          &wait_ns);
>>
>> Read this in probe and save the value rather than fetching every
>> transfer.
>
> But this is a slave property I'm using here. If I read and store it in
> probe in the spi-sun4i driver, I won't have access to the slave node
> property, will I?

Sorry, I think I get it now. I would need to read the value in SPI
core, when the slave device gets probed. I will send an updated patch.

Thanks,

    Marcus
Mark Brown Dec. 14, 2015, 10:57 a.m. UTC | #6
On Mon, Dec 14, 2015 at 12:23:29AM +0100, Marcus Weseloh wrote:

> Should I resend the patch?

No, it's OK.
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
index bbaa857..2d6034f 100644
--- a/Documentation/devicetree/bindings/spi/spi-bus.txt
+++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
@@ -61,6 +61,8 @@  contain the following properties.
                       used for MOSI. Defaults to 1 if not present.
 - spi-rx-bus-width - (optional) The bus width(number of data wires) that
                       used for MISO. Defaults to 1 if not present.
+- spi-word-wait-ns - (optional) Hardware based delay between transmission of
+                      words in nanoseconds
 
 Some SPI controllers and devices support Dual and Quad SPI transfer mode.
 It allows data in the SPI system to be transferred in 2 wires(DUAL) or 4 wires(QUAD).
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index f60a6d6..73995a1 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -19,6 +19,7 @@ 
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
 
 #include <linux/spi/spi.h>
 
@@ -173,6 +174,9 @@  static int sun4i_spi_transfer_one(struct spi_master *master,
 	unsigned int tx_len = 0;
 	int ret = 0;
 	u32 reg;
+	u32 wait_ns = 0;
+	int wait_clk = 0;
+	int clk_ns = 0;
 
 	/* We don't support transfer larger than the FIFO */
 	if (tfr->len > SUN4I_FIFO_DEPTH)
@@ -261,6 +265,25 @@  static int sun4i_spi_transfer_one(struct spi_master *master,
 
 	sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg);
 
+	/* Setup wait time between words */
+	of_property_read_u32(spi->dev.of_node, "spi-word-wait-ns",
+			     &wait_ns);
+	if (wait_ns) {
+		/* The wait time is set in SPI_CLK cycles. The SPI hardware
+		 * needs 3 additional cycles to setup the wait counter, so
+		 * the minimum delay time is 4 cycles.
+		 */
+		clk_ns = DIV_ROUND_UP(1000000000, tfr->speed_hz);
+		wait_clk = DIV_ROUND_UP(wait_ns, clk_ns) - 3;
+		if (wait_clk < 1) {
+			wait_clk = 1;
+			dev_info(&spi->dev,
+				 "using minimum of 4 word wait cycles (%uns)",
+				 4 * clk_ns);
+		}
+	}
+	sun4i_spi_write(sspi, SUN4I_WAIT_REG, (u16)wait_clk);
+
 	/* Setup the transfer now... */
 	if (sspi->tx_buf)
 		tx_len = tfr->len;