All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wolfgang Grandegger <wg@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 3/3] fsl_i2c: Impl. AN2919, rev 5 to calculate FDR/DFSR
Date: Mon, 21 Sep 2009 12:53:36 +0200	[thread overview]
Message-ID: <4AB75B30.4030004@denx.de> (raw)
In-Reply-To: <1253178437-32398-3-git-send-email-Joakim.Tjernlund@transmode.se>

Hi Joakim,

Joakim Tjernlund wrote:
> The latest AN2919 has changed the way FDR/DFSR should be calculated.
> Update the driver according to spec. However, Condition 2
> is not accounted for as it is not clear how to do so.

I compared rev. 5 of AN2919 with rev. 3 and, as you pointed out, it puts
additional constraints on how to select dfsr and fdr. Especially dfsr
should not exceed a certain, frequency dependent value: dfsr <= 50 /
period-in-ns. Therefore, I expected problems with divider values from
the table which high dfsr values. I did your "=> date;date;date;date"
test on a MPC8548 board using dfsr=43 and fdr=7 but it did not fail.
According to the rev. 5, dfsr is not allowed to be greater than 8.
Your patch works fine on this board as well. I have no time for a more
thorough testing with different CPUs and frequencies. Anyhow...

> Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>

I realized some minor coding style issues, though. See below.

> ---
>  drivers/i2c/fsl_i2c.c |   90 ++++++++++++++++++++++++++++++-------------------
>  1 files changed, 55 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
> index 0c5f6be..78f21c7 100644
> --- a/drivers/i2c/fsl_i2c.c
> +++ b/drivers/i2c/fsl_i2c.c
> @@ -100,29 +100,9 @@ static const struct fsl_i2c *i2c_dev[2] = {
>   */
>  static const struct {
>  	unsigned short divider;
> -#ifdef __PPC__
> -	u8 dfsr;
> -#endif
>  	u8 fdr;
>  } fsl_i2c_speed_map[] = {
> -#ifdef __PPC__
> -	{160, 1, 32}, {192, 1, 33}, {224, 1, 34}, {256, 1, 35},
> -	{288, 1, 0}, {320, 1, 1}, {352, 6, 1}, {384, 1, 2}, {416, 6, 2},
> -	{448, 1, 38}, {480, 1, 3}, {512, 1, 39}, {544, 11, 3}, {576, 1, 4},
> -	{608, 22, 3}, {640, 1, 5}, {672, 32, 3}, {704, 11, 5}, {736, 43, 3},
> -	{768, 1, 6}, {800, 54, 3}, {832, 11, 6}, {896, 1, 42}, {960, 1, 7},
> -	{1024, 1, 43}, {1088, 22, 7}, {1152, 1, 8}, {1216, 43, 7}, {1280, 1, 9},
> -	{1408, 22, 9}, {1536, 1, 10}, {1664, 22, 10}, {1792, 1, 46},
> -	{1920, 1, 11}, {2048, 1, 47}, {2176, 43, 11}, {2304, 1, 12},
> -	{2560, 1, 13}, {2816, 43, 13}, {3072, 1, 14}, {3328, 43, 14},
> -	{3584, 1, 50}, {3840, 1, 15}, {4096, 1, 51}, {4608, 1, 16},
> -	{5120, 1, 17}, {6144, 1, 18}, {7168, 1, 54}, {7680, 1, 19},
> -	{8192, 1, 55}, {9216, 1, 20}, {10240, 1, 21}, {12288, 1, 22},
> -	{14336, 1, 58}, {15360, 1, 23}, {16384, 1, 59}, {18432, 1, 24},
> -	{20480, 1, 25}, {24576, 1, 26}, {28672, 1, 62}, {30720, 1, 27},
> -	{32768, 1, 63}, {36864, 1, 28}, {40960, 1, 29}, {49152, 1, 30},
> -	{61440, 1, 31}, {-1, 1, 31}
> -#elif defined(__M68K__)
> +#ifdef __M68K__
>  	{20, 32}, {22, 33}, {24, 34}, {26, 35},
>  	{28, 0}, {28, 36}, {30, 1}, {32, 37},
>  	{34, 2}, {36, 38}, {40, 3}, {40, 39},
> @@ -158,7 +138,6 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
>  	unsigned int i2c_clk, unsigned int speed)
>  {
>  	unsigned short divider = min(i2c_clk / speed, (unsigned short) -1);
> -	unsigned int i;
>  
>  	/*
>  	 * We want to choose an FDR/DFSR that generates an I2C bus speed that
> @@ -166,31 +145,72 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
>  	 * want the first divider that is equal to or greater than the
>  	 * calculated divider.
>  	 */
> -
> -	for (i = 0; i < ARRAY_SIZE(fsl_i2c_speed_map); i++)
> -		if (fsl_i2c_speed_map[i].divider >= divider) {
> -			u8 fdr;
>  #ifdef __PPC__
> -			u8 dfsr;
> +	u8 dfsr, fdr = 0x31; /* Default if no FDR found */
> +	/* a, b and dfsr matches identifiers A,B and C respectively in AN2919 */
> +	unsigned short a, b, ga, gb;
> +	unsigned long c_div, est_div;
> +
>  #ifdef CONFIG_FSL_I2C_CUSTOM_DFSR
> -			dfsr = CONFIG_FSL_I2C_CUSTOM_DFSR;
> +	dfsr = CONFIG_FSL_I2C_CUSTOM_DFSR;
>  #else
> -			dfsr = fsl_i2c_speed_map[i].dfsr;
> -#endif
> -			writeb(dfsr, &dev->dfsrr);	/* set default filter */
> +	/* Condition 1: dfsr <= 50/T */
> +	dfsr = (5 * (i2c_clk / 1000)) / 100000;
>  #endif
>  #ifdef CONFIG_FSL_I2C_CUSTOM_FDR
> -			fdr = CONFIG_FSL_I2C_CUSTOM_FDR;
> -			speed = i2c_clk / divider; /* Fake something */
> +	fdr = CONFIG_FSL_I2C_CUSTOM_FDR;
> +	speed = i2c_clk / divider; /* Fake something */
>  #else
> +	debug("Requested speed:%d, i2c_clk:%d\n", speed, i2c_clk);
> +	if (!dfsr)
> +		dfsr = 1;
> +
> +	est_div = ~0;
> +	for (ga = 0x4, a = 10; a <= 30; ga++, a += 2) {
> +		for (gb = 0; gb < 8; gb++) {
> +			b = 16 << gb;
> +			c_div = b * (a + ((3*dfsr)/b)*2);

Please use spaces around "/" and "*".

> +			if ((c_div > divider) && (c_div < est_div)) {
> +				unsigned short bin_gb, bin_ga;
> +
> +				est_div = c_div;
> +				bin_gb = gb << 2;
> +				bin_ga = (ga & 0x3) | ((ga & 0x4) << 3);
> +				fdr = bin_gb | bin_ga;
> +				speed = i2c_clk / est_div;
> +				debug("FDR:0x%.2x, div:%ld, ga:0x%x, gb:0x%x, "
> +				      "a:%d, b:%d, speed:%d\n",
> +				      fdr, est_div, ga, gb, a, b, speed);
> +				/* Condition 2 not accounted for */
> +				debug("Tr <= %d ns\n", 

Please remove trailing white space.

Wolfgang.

  parent reply	other threads:[~2009-09-21 10:53 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-17  9:07 [U-Boot] [PATCH 1/3] fsl_i2c: Wait for STOP condition to propagate Joakim Tjernlund
2009-09-17  9:07 ` [U-Boot] [PATCH 2/3] fsl_i2c: Add CONFIG_FSL_I2C_CUSTOM_{DFSR/FDR} Joakim Tjernlund
2009-09-17  9:07   ` [U-Boot] [PATCH 3/3] fsl_i2c: Impl. AN2919, rev 5 to calculate FDR/DFSR Joakim Tjernlund
2009-09-17 12:04     ` Heiko Schocher
2009-09-21 10:53     ` Wolfgang Grandegger [this message]
2009-09-21 11:34       ` Joakim Tjernlund
2009-09-21 11:59         ` Wolfgang Grandegger
2009-09-21 12:30           ` Joakim Tjernlund
2009-09-17 12:03   ` [U-Boot] [PATCH 2/3] fsl_i2c: Add CONFIG_FSL_I2C_CUSTOM_{DFSR/FDR} Heiko Schocher
2009-09-17 14:38   ` Timur Tabi
2009-09-17 18:11     ` Joakim Tjernlund
2009-09-17 12:03 ` [U-Boot] [PATCH 1/3] fsl_i2c: Wait for STOP condition to propagate Heiko Schocher
2009-09-17 12:37   ` Joakim Tjernlund
2009-09-22 20:57 ` Wolfgang Denk
2009-09-23  7:58   ` Joakim Tjernlund
2009-09-23  9:02     ` Heiko Schocher
2009-09-23  9:14       ` Joakim Tjernlund
2009-09-23 12:19         ` Heiko Schocher

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=4AB75B30.4030004@denx.de \
    --to=wg@denx.de \
    --cc=u-boot@lists.denx.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.