diff mbox

[1/3] mfd: cros ec: spi: Add delay for raising CS

Message ID 1384770649-8593-1-git-send-email-treding@nvidia.com
State Superseded, archived
Headers show

Commit Message

Thierry Reding Nov. 18, 2013, 10:30 a.m. UTC
From: Rhyland Klein <rklein@nvidia.com>

The EC has specific timing it requires. Add support for an optional delay
after raising CS to fix timing issues. This is configurable based on
a DT property "google,cros-ec-spi-msg-delay".

If this property isn't set, then no delay will be added. However, if set
it will cause a delay equal to the value passed to it to be inserted at
the end of a transaction.

Signed-off-by: Rhyland Klein <rklein@nvidia.com>
Reviewed-by: Bernie Thompson <bhthompson@chromium.org>
Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 Documentation/devicetree/bindings/mfd/cros-ec.txt |  4 +++
 drivers/mfd/cros_ec_spi.c                         | 30 +++++++++++++++++++++++
 2 files changed, 34 insertions(+)

Comments

Lee Jones Nov. 18, 2013, 10:42 a.m. UTC | #1
On Mon, 18 Nov 2013, Thierry Reding wrote:

> The dev_cont() symbol doesn't exist, so replace it with pr_cont(). While
> at it, also append a newline to the debug output to make it look nicer.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/mfd/cros_ec_spi.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Applied, thanks.
Lee Jones Nov. 18, 2013, 10:43 a.m. UTC | #2
On Mon, 18 Nov 2013, Thierry Reding wrote:

> From: Derek Basehore <dbasehore@chromium.org>
> 
> 50 us is not a long enough delay between EC transactions. At least 70 us
> are needed for the 16 MHz STM32L part. Increase the delay to 200 us for
> an extra safety margin.
> 
> Signed-off-by: Derek Basehore <dbasehore@chromium.org>
> Reviewed-by: Randall Spangler <rspangler@chromium.org>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/mfd/cros_ec_spi.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)

As I'm sure you've tested this and you didn't notice any new undue
latency, I'll apply the patch, thanks.
Mark Rutland Nov. 18, 2013, 11:48 a.m. UTC | #3
On Mon, Nov 18, 2013 at 10:30:47AM +0000, Thierry Reding wrote:
> From: Rhyland Klein <rklein@nvidia.com>
> 
> The EC has specific timing it requires. Add support for an optional delay
> after raising CS to fix timing issues. This is configurable based on
> a DT property "google,cros-ec-spi-msg-delay".
> 
> If this property isn't set, then no delay will be added. However, if set
> it will cause a delay equal to the value passed to it to be inserted at
> the end of a transaction.
> 
> Signed-off-by: Rhyland Klein <rklein@nvidia.com>
> Reviewed-by: Bernie Thompson <bhthompson@chromium.org>
> Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  Documentation/devicetree/bindings/mfd/cros-ec.txt |  4 +++
>  drivers/mfd/cros_ec_spi.c                         | 30 +++++++++++++++++++++++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/cros-ec.txt b/Documentation/devicetree/bindings/mfd/cros-ec.txt
> index 5f229c5f6da9..fb3034a87ae0 100644
> --- a/Documentation/devicetree/bindings/mfd/cros-ec.txt
> +++ b/Documentation/devicetree/bindings/mfd/cros-ec.txt
> @@ -17,6 +17,10 @@ Required properties (SPI):
>  - compatible: "google,cros-ec-spi"
>  - reg: SPI chip select
>  
> +Optional properties (SPI):
> +- google,cros-ec-spi-msg-delay: This property is how long of a delay, in usecs,
> +  to use on the last transfer of a message, to force time between transactions.
> +

Lose the "This property is", that's obvious from the structure of the
document.

It would be nice to have an explanation in the binding document as to
_why_ you might want to do this (e.g. the HW expects the rising edge to
come some number of uS after the data, if it comes too early it
explodes).

Otherwise this looks fine to me.

Thanks,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
dbasehore . Nov. 18, 2013, 6:55 p.m. UTC | #4
We haven't had any issues with this patch and we've had it in our tree
for a while.

I also stress tested the patch by repeatedly reading over the spi a lot.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lee Jones Nov. 18, 2013, 7:01 p.m. UTC | #5
On Mon, 18 Nov 2013, dbasehore . wrote:

> We haven't had any issues with this patch and we've had it in our tree
> for a while.
> 
> I also stress tested the patch by repeatedly reading over the spi a lot.

Okay, thanks for letting me know.
Thierry Reding Nov. 19, 2013, 8:42 a.m. UTC | #6
On Mon, Nov 18, 2013 at 11:48:10AM +0000, Mark Rutland wrote:
> On Mon, Nov 18, 2013 at 10:30:47AM +0000, Thierry Reding wrote:
> > From: Rhyland Klein <rklein@nvidia.com>
> > 
> > The EC has specific timing it requires. Add support for an optional delay
> > after raising CS to fix timing issues. This is configurable based on
> > a DT property "google,cros-ec-spi-msg-delay".
> > 
> > If this property isn't set, then no delay will be added. However, if set
> > it will cause a delay equal to the value passed to it to be inserted at
> > the end of a transaction.
> > 
> > Signed-off-by: Rhyland Klein <rklein@nvidia.com>
> > Reviewed-by: Bernie Thompson <bhthompson@chromium.org>
> > Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
> > Cc: Rob Herring <rob.herring@calxeda.com>
> > Cc: Pawel Moll <pawel.moll@arm.com>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> > Signed-off-by: Thierry Reding <treding@nvidia.com>
> > ---
> >  Documentation/devicetree/bindings/mfd/cros-ec.txt |  4 +++
> >  drivers/mfd/cros_ec_spi.c                         | 30 +++++++++++++++++++++++
> >  2 files changed, 34 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/mfd/cros-ec.txt b/Documentation/devicetree/bindings/mfd/cros-ec.txt
> > index 5f229c5f6da9..fb3034a87ae0 100644
> > --- a/Documentation/devicetree/bindings/mfd/cros-ec.txt
> > +++ b/Documentation/devicetree/bindings/mfd/cros-ec.txt
> > @@ -17,6 +17,10 @@ Required properties (SPI):
> >  - compatible: "google,cros-ec-spi"
> >  - reg: SPI chip select
> >  
> > +Optional properties (SPI):
> > +- google,cros-ec-spi-msg-delay: This property is how long of a delay, in usecs,
> > +  to use on the last transfer of a message, to force time between transactions.
> > +
> 
> Lose the "This property is", that's obvious from the structure of the
> document.

Will do.

> It would be nice to have an explanation in the binding document as to
> _why_ you might want to do this (e.g. the HW expects the rising edge to
> come some number of uS after the data, if it comes too early it
> explodes).

From what I can tell, this might differ on the exact variant of the EC,
but generally it seems that when the interval between two transactions
isn't long enough the EC won't be able to respond properly in time and
cause subsequent transactions to hang. Perhaps Rhyland, Bernie or Andrew
are more familiar with the details and therefore can provide a better or
more accurate explanation.

> Otherwise this looks fine to me.

Thanks,
Thierry
Rhyland Klein Nov. 19, 2013, 5:06 p.m. UTC | #7
On 11/19/2013 3:42 AM, Thierry Reding wrote:
> * PGP Signed by an unknown key
> 
> On Mon, Nov 18, 2013 at 11:48:10AM +0000, Mark Rutland wrote:
>> On Mon, Nov 18, 2013 at 10:30:47AM +0000, Thierry Reding wrote:
>>> From: Rhyland Klein <rklein@nvidia.com>
>>>
>>> The EC has specific timing it requires. Add support for an optional delay
>>> after raising CS to fix timing issues. This is configurable based on
>>> a DT property "google,cros-ec-spi-msg-delay".
>>>
>>> If this property isn't set, then no delay will be added. However, if set
>>> it will cause a delay equal to the value passed to it to be inserted at
>>> the end of a transaction.
>>>
>>> Signed-off-by: Rhyland Klein <rklein@nvidia.com>
>>> Reviewed-by: Bernie Thompson <bhthompson@chromium.org>
>>> Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
>>> Cc: Rob Herring <rob.herring@calxeda.com>
>>> Cc: Pawel Moll <pawel.moll@arm.com>
>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
>>> Signed-off-by: Thierry Reding <treding@nvidia.com>
>>> ---
>>>  Documentation/devicetree/bindings/mfd/cros-ec.txt |  4 +++
>>>  drivers/mfd/cros_ec_spi.c                         | 30 +++++++++++++++++++++++
>>>  2 files changed, 34 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/mfd/cros-ec.txt b/Documentation/devicetree/bindings/mfd/cros-ec.txt
>>> index 5f229c5f6da9..fb3034a87ae0 100644
>>> --- a/Documentation/devicetree/bindings/mfd/cros-ec.txt
>>> +++ b/Documentation/devicetree/bindings/mfd/cros-ec.txt
>>> @@ -17,6 +17,10 @@ Required properties (SPI):
>>>  - compatible: "google,cros-ec-spi"
>>>  - reg: SPI chip select
>>>  
>>> +Optional properties (SPI):
>>> +- google,cros-ec-spi-msg-delay: This property is how long of a delay, in usecs,
>>> +  to use on the last transfer of a message, to force time between transactions.
>>> +
>>
>> Lose the "This property is", that's obvious from the structure of the
>> document.
> 
> Will do.
> 
>> It would be nice to have an explanation in the binding document as to
>> _why_ you might want to do this (e.g. the HW expects the rising edge to
>> come some number of uS after the data, if it comes too early it
>> explodes).
> 
> From what I can tell, this might differ on the exact variant of the EC,
> but generally it seems that when the interval between two transactions
> isn't long enough the EC won't be able to respond properly in time and
> cause subsequent transactions to hang. Perhaps Rhyland, Bernie or Andrew
> are more familiar with the details and therefore can provide a better or
> more accurate explanation.

I believe this explanation is correct. As I recall, I think adding this
delay helped stabilize communication with the EC, where before sometimes
transactions would time out.

-rhyland

> 
>> Otherwise this looks fine to me.
> 
> Thanks,
> Thierry
> 
> * Unknown Key
> * 0x7F3EB3A1
>
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/mfd/cros-ec.txt b/Documentation/devicetree/bindings/mfd/cros-ec.txt
index 5f229c5f6da9..fb3034a87ae0 100644
--- a/Documentation/devicetree/bindings/mfd/cros-ec.txt
+++ b/Documentation/devicetree/bindings/mfd/cros-ec.txt
@@ -17,6 +17,10 @@  Required properties (SPI):
 - compatible: "google,cros-ec-spi"
 - reg: SPI chip select
 
+Optional properties (SPI):
+- google,cros-ec-spi-msg-delay: This property is how long of a delay, in usecs,
+  to use on the last transfer of a message, to force time between transactions.
+
 Required properties (LPC):
 - compatible: "google,cros-ec-lpc"
 - reg: List of (IO address, size) pairs defining the interface uses
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c
index 367ccb58ecb1..d05349a7381e 100644
--- a/drivers/mfd/cros_ec_spi.c
+++ b/drivers/mfd/cros_ec_spi.c
@@ -18,6 +18,7 @@ 
 #include <linux/module.h>
 #include <linux/mfd/cros_ec.h>
 #include <linux/mfd/cros_ec_commands.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
@@ -61,10 +62,13 @@ 
  * @spi: SPI device we are connected to
  * @last_transfer_ns: time that we last finished a transfer, or 0 if there
  *	if no record
+ * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that
+ *      is sent when we want to turn off CS at the end of a transaction.
  */
 struct cros_ec_spi {
 	struct spi_device *spi;
 	s64 last_transfer_ns;
+	unsigned int end_of_msg_delay;
 };
 
 static void debug_packet(struct device *dev, const char *name, u8 *ptr,
@@ -235,6 +239,17 @@  static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
 
 	/* turn off CS */
 	spi_message_init(&msg);
+
+	if (ec_spi->end_of_msg_delay) {
+		/*
+		 * Add delay for last transaction, to ensure the rising edge
+		 * doesn't come too soon after the end of the data.
+		 */
+		memset(&trans, '\0', sizeof(trans));
+		trans.delay_usecs = ec_spi->end_of_msg_delay;
+		spi_message_add_tail(&trans, &msg);
+	}
+
 	final_ret = spi_sync(ec_spi->spi, &msg);
 	ktime_get_ts(&ts);
 	ec_spi->last_transfer_ns = timespec_to_ns(&ts);
@@ -281,6 +296,17 @@  static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
 	return 0;
 }
 
+static void cros_ec_probe_spi_dt(struct cros_ec_spi *ec_spi, struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	u32 val;
+	int ret;
+
+	ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val);
+	if (!ret)
+		ec_spi->end_of_msg_delay = val;
+}
+
 static int cros_ec_probe_spi(struct spi_device *spi)
 {
 	struct device *dev = &spi->dev;
@@ -302,6 +328,10 @@  static int cros_ec_probe_spi(struct spi_device *spi)
 	if (!ec_dev)
 		return -ENOMEM;
 
+	/* Check for any DT properties */
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+		cros_ec_probe_spi_dt(ec_spi, dev);
+
 	spi_set_drvdata(spi, ec_dev);
 	ec_dev->name = "SPI";
 	ec_dev->dev = dev;