All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
To: Felipe Balbi <balbi@ti.com>, wsa@the-dreams.de
Cc: Nishanth Menon <nm@ti.com>, Dave Gerlach <d-gerlach@ti.com>,
	Tony Lindgren <tony@atomide.com>,
	linux-i2c@vger.kernel.org,
	Linux OMAP Mailing List <linux-omap@vger.kernel.org>,
	Linux ARM Kernel Mailing List
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v2] i2c: omap: improve duty cycle on SCL
Date: Wed, 17 Jun 2015 21:00:53 +0200	[thread overview]
Message-ID: <5581C3E5.6020109@gmail.com> (raw)
In-Reply-To: <1434565751-14944-1-git-send-email-balbi@ti.com>

Hi!

On 17/06/15 20:29, Felipe Balbi wrote:
> -		if (dev->speed > 400 ||
> -			       dev->flags & OMAP_I2C_FLAG_FORCE_19200_INT_CLK)
> -			internal_clk = 19200;

Let's compare, what it waas before in this case...

> -		else if (dev->speed > 100)
> -			internal_clk = 9600;
> -		else
> -			internal_clk = 4000;
> +		if (dev->flags & OMAP_I2C_FLAG_FORCE_19200_INT_CLK ||
> +				dev->speed > 400) {
> +			internal_clk = 1920000;

Seems that it should be 19200000? Because...

> +			internal_clk_period = NSECS_PER_SEC /
> +				internal_clk; /* ns */

520

> +		} else {
> +			internal_clk = 12000000;
> +			internal_clk_period = NSECS_PER_SEC /
> +				internal_clk; /* ns */
> +		}
> +
>  		fclk = clk_get(dev->dev, "fck");
> -		fclk_rate = clk_get_rate(fclk) / 1000;
> +		fclk_rate = clk_get_rate(fclk);
>  		clk_put(fclk);
>  
>  		/* Compute prescaler divisor */
>  		psc = fclk_rate / internal_clk;
>  		psc = psc - 1;
>  
> +		/*
> +		 * Here's the tricky part, we want to make sure our duty cycle
> +		 * is as close to 50% as possible. In order to achieve that, we
> +		 * will first figure out what's the period on chosen scl is,
> +		 * then divide that by two and calculate SCLL and SCLH based on
> +		 * that.
> +		 *
> +		 * SCLL and SCLH equations are as folows:
> +		 *
> +		 * SCLL = (tLow / iclk_period) - 7;
> +		 * SCLH = (tHigh / iclk_period) - 5;
> +		 *
> +		 * Where iclk_period is period of Internal Clock.
> +		 *
> +		 * tLow and tHigh will be basically half of scl_period where
> +		 * possible as long as we can match I2C spec's minimum limits
> +		 * for them.
> +		 */
> +		scl_period = NSECS_PER_SEC / (dev->speed * 1000);
> +
>  		/* If configured for High Speed */
>  		if (dev->speed > 400) {
> -			unsigned long scl;
> +			unsigned long fs_period;
> +
> +			/*
> +			 * first phase of HS mode is up to
> +			 * 400kHz so we will use that.
> +			 */
> +			fs_period = NSECS_PER_SEC / 400000;
>  
>  			/* For first phase of HS mode */
> -			scl = internal_clk / 400;

scl=19200/400=48

> -			fsscll = scl - (scl / 3) - 7;
fsscll=48-16-7=25
> -			fssclh = (scl / 3) - 5;
fssclh=16-5=11
> +			fsscll = DIV_ROUND_UP(fs_period >> 1,
> +					internal_clk_period) - 7;
> +			fssclh = (fs_period >> 1) / internal_clk_period - 5;

And with your patch:
fsscll=ROUND_UP(1250/520)-7=-4
fssclh=1250/520-5=-3

Alex.

WARNING: multiple messages have this Message-ID (diff)
From: alexander.sverdlin@gmail.com (Alexander Sverdlin)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2] i2c: omap: improve duty cycle on SCL
Date: Wed, 17 Jun 2015 21:00:53 +0200	[thread overview]
Message-ID: <5581C3E5.6020109@gmail.com> (raw)
In-Reply-To: <1434565751-14944-1-git-send-email-balbi@ti.com>

Hi!

On 17/06/15 20:29, Felipe Balbi wrote:
> -		if (dev->speed > 400 ||
> -			       dev->flags & OMAP_I2C_FLAG_FORCE_19200_INT_CLK)
> -			internal_clk = 19200;

Let's compare, what it waas before in this case...

> -		else if (dev->speed > 100)
> -			internal_clk = 9600;
> -		else
> -			internal_clk = 4000;
> +		if (dev->flags & OMAP_I2C_FLAG_FORCE_19200_INT_CLK ||
> +				dev->speed > 400) {
> +			internal_clk = 1920000;

Seems that it should be 19200000? Because...

> +			internal_clk_period = NSECS_PER_SEC /
> +				internal_clk; /* ns */

520

> +		} else {
> +			internal_clk = 12000000;
> +			internal_clk_period = NSECS_PER_SEC /
> +				internal_clk; /* ns */
> +		}
> +
>  		fclk = clk_get(dev->dev, "fck");
> -		fclk_rate = clk_get_rate(fclk) / 1000;
> +		fclk_rate = clk_get_rate(fclk);
>  		clk_put(fclk);
>  
>  		/* Compute prescaler divisor */
>  		psc = fclk_rate / internal_clk;
>  		psc = psc - 1;
>  
> +		/*
> +		 * Here's the tricky part, we want to make sure our duty cycle
> +		 * is as close to 50% as possible. In order to achieve that, we
> +		 * will first figure out what's the period on chosen scl is,
> +		 * then divide that by two and calculate SCLL and SCLH based on
> +		 * that.
> +		 *
> +		 * SCLL and SCLH equations are as folows:
> +		 *
> +		 * SCLL = (tLow / iclk_period) - 7;
> +		 * SCLH = (tHigh / iclk_period) - 5;
> +		 *
> +		 * Where iclk_period is period of Internal Clock.
> +		 *
> +		 * tLow and tHigh will be basically half of scl_period where
> +		 * possible as long as we can match I2C spec's minimum limits
> +		 * for them.
> +		 */
> +		scl_period = NSECS_PER_SEC / (dev->speed * 1000);
> +
>  		/* If configured for High Speed */
>  		if (dev->speed > 400) {
> -			unsigned long scl;
> +			unsigned long fs_period;
> +
> +			/*
> +			 * first phase of HS mode is up to
> +			 * 400kHz so we will use that.
> +			 */
> +			fs_period = NSECS_PER_SEC / 400000;
>  
>  			/* For first phase of HS mode */
> -			scl = internal_clk / 400;

scl=19200/400=48

> -			fsscll = scl - (scl / 3) - 7;
fsscll=48-16-7=25
> -			fssclh = (scl / 3) - 5;
fssclh=16-5=11
> +			fsscll = DIV_ROUND_UP(fs_period >> 1,
> +					internal_clk_period) - 7;
> +			fssclh = (fs_period >> 1) / internal_clk_period - 5;

And with your patch:
fsscll=ROUND_UP(1250/520)-7=-4
fssclh=1250/520-5=-3

Alex.

  reply	other threads:[~2015-06-17 19:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-17 18:29 [PATCH v2] i2c: omap: improve duty cycle on SCL Felipe Balbi
2015-06-17 18:29 ` Felipe Balbi
2015-06-17 19:00 ` Alexander Sverdlin [this message]
2015-06-17 19:00   ` Alexander Sverdlin
     [not found]   ` <5581C3E5.6020109-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-06-17 19:00     ` Felipe Balbi
2015-06-17 19:00       ` Felipe Balbi

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=5581C3E5.6020109@gmail.com \
    --to=alexander.sverdlin@gmail.com \
    --cc=balbi@ti.com \
    --cc=d-gerlach@ti.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=nm@ti.com \
    --cc=tony@atomide.com \
    --cc=wsa@the-dreams.de \
    /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 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.