devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Trent Piepho <tpiepho@impinj.com>
To: "baolin.wang@linaro.org" <baolin.wang@linaro.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"robh+dt@kernel.org" <robh+dt@kernel.org>,
	"orsonzhai@gmail.com" <orsonzhai@gmail.com>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"zhang.lyra@gmail.com" <zhang.lyra@gmail.com>,
	"broonie@kernel.org" <broonie@kernel.org>,
	"mark.rutland@arm.com" <mark.rutland@arm.com>,
	"linux-spi@vger.kernel.org" <linux-spi@vger.kernel.org>,
	"lanqing.liu@spreadtrum.com" <lanqing.liu@spreadtrum.com>
Subject: Re: [PATCH 2/2] spi: sprd: Add SPI driver for Spreadtrum SC9860
Date: Wed, 8 Aug 2018 19:08:57 +0000	[thread overview]
Message-ID: <1533755337.2283.280.camel@impinj.com> (raw)
In-Reply-To: <CAMz4kuJrzaZn9560tF73a-WPNhhRj5S2ezTKr0HHpcGRXMw-Ew@mail.gmail.com>

On Wed, 2018-08-08 at 11:19 +0800, Baolin Wang wrote:
> On 8 August 2018 at 01:10, Trent Piepho <tpiepho@impinj.com> wrote:
> > On Tue, 2018-08-07 at 18:43 +0800, Baolin Wang wrote:
> > > 
> > > +static u32 sprd_spi_transfer_max_timeout(struct sprd_spi *ss,
> > > +                                      struct spi_transfer *t)
> > > +{
> > > +     /*
> > > +      * The time spent on transmission of the full FIFO data is the maximum
> > > +      * SPI transmission time.
> > > +      */
> > > +     u32 size = t->bits_per_word * SPRD_SPI_FIFO_SIZE;
> > > +     u32 bit_time_us = SPRD_SPI_HZ / t->speed_hz + 1;

There's another flaw here in that the transfer speed, t->speed_hz,
might not be exactly what is used, due to limitations of the clock
divider.  It would be better to find the actual SPI clock used, then
use that in the calculations.

> > > +     u32 total_time_us = size * bit_time_us;
> > > +     /*
> > > +      * There is an interval between data and the data in our SPI hardware,
> > > +      * so the total transmission time need add the interval time.
> > > +      *
> > > +      * The inteval calculation formula:
> > > +      * interval time (source clock cycles) = interval * 4 + 10.
> > > +      */
> > > +     u32 interval_cycle = SPRD_SPI_FIFO_SIZE * ((ss->interval << 2) + 10);
> > > +     u32 interval_time_us = interval_cycle * SPRD_SPI_HZ / ss->src_clk + 1;
> > 
> > If interval is greater than 31, this will overflow.
> 
> Usually we will not set such a big value for interval,  but this is a
> risk like you said. So we will check and limit the interval value to
> make sure the formula will not overflow.
> 

Better would be to limit the inter word delay to whatever maximum value
your hardware supports, and then write code that can calculate that
without error.

> > > +static void sprd_spi_set_speed(struct sprd_spi *ss, u32 speed_hz)
> > > +{
> > > +     /*
> > > +      * From SPI datasheet, the prescale calculation formula:
> > > +      * prescale = SPI source clock / (2 * SPI_freq) - 1;
> > > +      */
> > > +     u32 clk_div = ss->src_clk / (speed_hz << 1) - 1;
> > 
> > You should probably round up here.  The convention is to use the
> > closest speed less than equal to the requested speed, but since this is
> > a divider, rounding it down will select the next highest speed.
> 
> Per the datasheet, we do not need round up/down the speed. Since our
> hardware can handle the clock calculated by the above formula if the
> requested speed is in the normal region (less than ->max_speed_hz).

That is not what I mean.  Let me explain differently.

An integer divider like this can not produce any frequency exactly. 
Consider if src_clk is 10 MHz.  A clk_div value of 0 produces a 5 MHz
SPI clock.  A clk_div value of 1 produces a 2.5 MHz SPI clock.

What if the transfer requests a SPI clock of 3 MHz?

Your math above will produce a SPI clock of 5 MHz, faster than
requested.  This is not the convention in Linux SPI masters.  You
should instead of have chosen a clk_div value of 1 to get a SPI clock
of 2.5 MHz, the closest clock possible that is not greater than the
requested value.

To do this, round up.

clk_div = DIV_ROUND_UP(ss->src_clk, speed_hz * 2) - 1;

> 

  reply	other threads:[~2018-08-08 19:08 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-07 10:43 [PATCH 1/2] dt-bindings: spi: Add Spreadtrum SPI controller documentation Baolin Wang
2018-08-07 10:43 ` [PATCH 2/2] spi: sprd: Add SPI driver for Spreadtrum SC9860 Baolin Wang
2018-08-07 14:24   ` Mark Brown
2018-08-08  2:45     ` Baolin Wang
2018-08-08  9:31       ` Mark Brown
2018-08-08  9:33         ` Baolin Wang
2018-08-07 17:10   ` Trent Piepho
2018-08-08  3:19     ` Baolin Wang
2018-08-08 19:08       ` Trent Piepho [this message]
2018-08-09  3:23         ` Baolin Wang
2018-08-07 13:41 ` [PATCH 1/2] dt-bindings: spi: Add Spreadtrum SPI controller documentation Mark Brown
2018-08-08  2:26   ` Baolin Wang
2018-08-08  9:50     ` Mark Brown
2018-08-08 10:35       ` Baolin Wang
2018-08-08 10:54         ` Mark Brown
2018-08-08 11:07           ` Baolin Wang
2018-08-08 18:57           ` Trent Piepho
2018-08-09  3:03             ` Baolin Wang
2018-08-14 20:27               ` Rob Herring
2018-08-15  2:17                 ` Baolin Wang
2018-08-14 20:21 ` Rob Herring
2018-08-15  1:44   ` Baolin Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1533755337.2283.280.camel@impinj.com \
    --to=tpiepho@impinj.com \
    --cc=baolin.wang@linaro.org \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=lanqing.liu@spreadtrum.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=orsonzhai@gmail.com \
    --cc=robh+dt@kernel.org \
    --cc=zhang.lyra@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).