diff mbox

i2c: exynos5: simplify timings calculation

Message ID 1487868446-5339-1-git-send-email-a.hajda@samsung.com
State Accepted
Headers show

Commit Message

Andrzej Hajda Feb. 23, 2017, 4:47 p.m. UTC
Instead of using cryptic loop direct calculation of timings
can be used.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/i2c/busses/i2c-exynos5.c | 40 ++++++++++++++--------------------------
 1 file changed, 14 insertions(+), 26 deletions(-)

Comments

Andrzej Hajda April 3, 2017, 10:06 a.m. UTC | #1
Hi Wolfram,

Gently ping.

Regards
Andrzej

On 23.02.2017 17:47, Andrzej Hajda wrote:
> Instead of using cryptic loop direct calculation of timings
> can be used.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/i2c/busses/i2c-exynos5.c | 40 ++++++++++++++--------------------------
>  1 file changed, 14 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
> index cbd93ce..04127b8 100644
> --- a/drivers/i2c/busses/i2c-exynos5.c
> +++ b/drivers/i2c/busses/i2c-exynos5.c
> @@ -292,9 +292,9 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode)
>  	unsigned int t_sr_release;
>  	unsigned int t_ftl_cycle;
>  	unsigned int clkin = clk_get_rate(i2c->clk);
> -	unsigned int div, utemp0 = 0, utemp1 = 0, clk_cycle;
>  	unsigned int op_clk = (mode == HSI2C_HIGH_SPD) ?
>  				i2c->hs_clock : i2c->fs_clock;
> +	int div, clk_cycle, temp;
>  
>  	/*
>  	 * In case of HSI2C controller in Exynos5 series
> @@ -305,33 +305,21 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode)
>  	 * FPCLK / FI2C =
>  	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + FLT_CYCLE
>  	 *
> -	 * utemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
> -	 * utemp1 = (TSCLK_L + TSCLK_H + 2)
> +	 * clk_cycle := TSCLK_L + TSCLK_H
> +	 * temp := (CLK_DIV + 1) * (clk_cycle + 2)
> +	 *
> +	 * Constraints: 4 <= temp, 0 <= CLK_DIV < 256, 2 <= clk_cycle <= 510
> +	 *
>  	 */
>  	t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
> -	utemp0 = (clkin / op_clk) - 8;
> -
> -	if (i2c->variant->hw == HSI2C_EXYNOS7)
> -		utemp0 -= t_ftl_cycle;
> -	else
> -		utemp0 -= 2 * t_ftl_cycle;
> -
> -	/* CLK_DIV max is 256 */
> -	for (div = 0; div < 256; div++) {
> -		utemp1 = utemp0 / (div + 1);
> -
> -		/*
> -		 * SCL_L and SCL_H each has max value of 255
> -		 * Hence, For the clk_cycle to the have right value
> -		 * utemp1 has to be less then 512 and more than 4.
> -		 */
> -		if ((utemp1 < 512) && (utemp1 > 4)) {
> -			clk_cycle = utemp1 - 2;
> -			break;
> -		} else if (div == 255) {
> -			dev_warn(i2c->dev, "Failed to calculate divisor");
> -			return -EINVAL;
> -		}
> +	temp = clkin / op_clk - 8 - t_ftl_cycle;
> +	if (i2c->variant->hw != HSI2C_EXYNOS7)
> +		temp -= t_ftl_cycle;
> +	div = temp / 512;
> +	clk_cycle = temp / (div + 1) - 2;
> +	if (temp < 4 || div >= 256 || clk_cycle < 2) {
> +		dev_warn(i2c->dev, "Failed to calculate divisor");
> +		return -EINVAL;
>  	}
>  
>  	t_scl_l = clk_cycle / 2;


--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andrzej Hajda April 14, 2017, 9:24 a.m. UTC | #2
Hi Wolfram,

Ping, 7 weeks passed.

Regards
Andrzej


On 23.02.2017 17:47, Andrzej Hajda wrote:
> Instead of using cryptic loop direct calculation of timings
> can be used.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/i2c/busses/i2c-exynos5.c | 40 ++++++++++++++--------------------------
>  1 file changed, 14 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
> index cbd93ce..04127b8 100644
> --- a/drivers/i2c/busses/i2c-exynos5.c
> +++ b/drivers/i2c/busses/i2c-exynos5.c
> @@ -292,9 +292,9 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode)
>  	unsigned int t_sr_release;
>  	unsigned int t_ftl_cycle;
>  	unsigned int clkin = clk_get_rate(i2c->clk);
> -	unsigned int div, utemp0 = 0, utemp1 = 0, clk_cycle;
>  	unsigned int op_clk = (mode == HSI2C_HIGH_SPD) ?
>  				i2c->hs_clock : i2c->fs_clock;
> +	int div, clk_cycle, temp;
>  
>  	/*
>  	 * In case of HSI2C controller in Exynos5 series
> @@ -305,33 +305,21 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode)
>  	 * FPCLK / FI2C =
>  	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + FLT_CYCLE
>  	 *
> -	 * utemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
> -	 * utemp1 = (TSCLK_L + TSCLK_H + 2)
> +	 * clk_cycle := TSCLK_L + TSCLK_H
> +	 * temp := (CLK_DIV + 1) * (clk_cycle + 2)
> +	 *
> +	 * Constraints: 4 <= temp, 0 <= CLK_DIV < 256, 2 <= clk_cycle <= 510
> +	 *
>  	 */
>  	t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
> -	utemp0 = (clkin / op_clk) - 8;
> -
> -	if (i2c->variant->hw == HSI2C_EXYNOS7)
> -		utemp0 -= t_ftl_cycle;
> -	else
> -		utemp0 -= 2 * t_ftl_cycle;
> -
> -	/* CLK_DIV max is 256 */
> -	for (div = 0; div < 256; div++) {
> -		utemp1 = utemp0 / (div + 1);
> -
> -		/*
> -		 * SCL_L and SCL_H each has max value of 255
> -		 * Hence, For the clk_cycle to the have right value
> -		 * utemp1 has to be less then 512 and more than 4.
> -		 */
> -		if ((utemp1 < 512) && (utemp1 > 4)) {
> -			clk_cycle = utemp1 - 2;
> -			break;
> -		} else if (div == 255) {
> -			dev_warn(i2c->dev, "Failed to calculate divisor");
> -			return -EINVAL;
> -		}
> +	temp = clkin / op_clk - 8 - t_ftl_cycle;
> +	if (i2c->variant->hw != HSI2C_EXYNOS7)
> +		temp -= t_ftl_cycle;
> +	div = temp / 512;
> +	clk_cycle = temp / (div + 1) - 2;
> +	if (temp < 4 || div >= 256 || clk_cycle < 2) {
> +		dev_warn(i2c->dev, "Failed to calculate divisor");
> +		return -EINVAL;
>  	}
>  
>  	t_scl_l = clk_cycle / 2;


--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wolfram Sang April 19, 2017, 7:17 p.m. UTC | #3
On Fri, Apr 14, 2017 at 11:24:16AM +0200, Andrzej Hajda wrote:
> Hi Wolfram,
> 
> Ping, 7 weeks passed.

Known issue, there are not enough reviewers for I2C for a timely
response. I was hoping for some tags from other users of this hardware,
but that didn't happen. And I don't know this hardware, at all. So, I'll
apply your patches early in the next cycle, and we will see what happens
once they are in -next. Best would be if you could find other people to
donate tags.

Thanks,

   Wolfram
Javier Martinez Canillas April 19, 2017, 7:36 p.m. UTC | #4
Hello Wolfram,

On 04/19/2017 03:17 PM, Wolfram Sang wrote:
> On Fri, Apr 14, 2017 at 11:24:16AM +0200, Andrzej Hajda wrote:
>> Hi Wolfram,
>>
>> Ping, 7 weeks passed.
> 
> Known issue, there are not enough reviewers for I2C for a timely
> response. I was hoping for some tags from other users of this hardware,
> but that didn't happen. And I don't know this hardware, at all. So, I'll
> apply your patches early in the next cycle, and we will see what happens
> once they are in -next. Best would be if you could find other people to
> donate tags.
>

I got a try to this patch on an Exynos5800 Peach Pi Chromebook and all
the I2C devices are working properly, so:

Tested-by: Javier Martinez Canillas <javier@osg.samsung.com>

> Thanks,
> 
>    Wolfram
> 

Best regards,
Wolfram Sang April 19, 2017, 7:42 p.m. UTC | #5
On Wed, Apr 19, 2017 at 03:36:39PM -0400, Javier Martinez Canillas wrote:
> Hello Wolfram,
> 
> On 04/19/2017 03:17 PM, Wolfram Sang wrote:
> > On Fri, Apr 14, 2017 at 11:24:16AM +0200, Andrzej Hajda wrote:
> >> Hi Wolfram,
> >>
> >> Ping, 7 weeks passed.
> > 
> > Known issue, there are not enough reviewers for I2C for a timely
> > response. I was hoping for some tags from other users of this hardware,
> > but that didn't happen. And I don't know this hardware, at all. So, I'll
> > apply your patches early in the next cycle, and we will see what happens
> > once they are in -next. Best would be if you could find other people to
> > donate tags.
> >
> 
> I got a try to this patch on an Exynos5800 Peach Pi Chromebook and all
> the I2C devices are working properly, so:
> 
> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com>

Cool, can you test his other patches as well?

http://patchwork.ozlabs.org/project/linux-i2c/list/?submitter=47122
Andi Shyti April 20, 2017, 12:45 a.m. UTC | #6
Hi Andrzej,

> > Ping, 7 weeks passed.
> 
> Known issue, there are not enough reviewers for I2C for a timely
> response. I was hoping for some tags from other users of this hardware,
> but that didn't happen. And I don't know this hardware, at all. So, I'll
> apply your patches early in the next cycle, and we will see what happens
> once they are in -next. Best would be if you could find other people to
> donate tags.

I'm sorry, I forgot to reply to this patch, I actually reviewed
and tested it among all your i2c patches (that's why I asked you
on IRC to add me in Cc to all your i2c patches).

So you can add also my

Reviewed-by: Andi Shyti <andi.shyti@samsung.com>

Andi
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wolfram Sang April 20, 2017, 6:42 a.m. UTC | #7
> I'm sorry, I forgot to reply to this patch, I actually reviewed
> and tested it among all your i2c patches

You mean you reviewed all his i2c patches? If so, could you add the tag
per patch. This way, patchwork will automatically collect them for me
and display the tag count in the list of patches.
Wolfram Sang April 21, 2017, 12:04 p.m. UTC | #8
On Thu, Feb 23, 2017 at 05:47:26PM +0100, Andrzej Hajda wrote:
> Instead of using cryptic loop direct calculation of timings
> can be used.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>

Applied to for-next, thanks!
Andi Shyti April 24, 2017, 2:07 a.m. UTC | #9
Hi Wolfram,

> > I'm sorry, I forgot to reply to this patch, I actually reviewed
> > and tested it among all your i2c patches
> 
> You mean you reviewed all his i2c patches? If so, could you add the tag
> per patch. This way, patchwork will automatically collect them for me
> and display the tag count in the list of patches.

yes, I reviewed, tested and used all the patches that Andrzej
has recently sent to the i2c-exynos driver. For all of them I
replied with my Reviewed-by, apparently I forgot to send the
reply to this one.

Andi
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index cbd93ce..04127b8 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -292,9 +292,9 @@  static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode)
 	unsigned int t_sr_release;
 	unsigned int t_ftl_cycle;
 	unsigned int clkin = clk_get_rate(i2c->clk);
-	unsigned int div, utemp0 = 0, utemp1 = 0, clk_cycle;
 	unsigned int op_clk = (mode == HSI2C_HIGH_SPD) ?
 				i2c->hs_clock : i2c->fs_clock;
+	int div, clk_cycle, temp;
 
 	/*
 	 * In case of HSI2C controller in Exynos5 series
@@ -305,33 +305,21 @@  static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode)
 	 * FPCLK / FI2C =
 	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + FLT_CYCLE
 	 *
-	 * utemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
-	 * utemp1 = (TSCLK_L + TSCLK_H + 2)
+	 * clk_cycle := TSCLK_L + TSCLK_H
+	 * temp := (CLK_DIV + 1) * (clk_cycle + 2)
+	 *
+	 * Constraints: 4 <= temp, 0 <= CLK_DIV < 256, 2 <= clk_cycle <= 510
+	 *
 	 */
 	t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
-	utemp0 = (clkin / op_clk) - 8;
-
-	if (i2c->variant->hw == HSI2C_EXYNOS7)
-		utemp0 -= t_ftl_cycle;
-	else
-		utemp0 -= 2 * t_ftl_cycle;
-
-	/* CLK_DIV max is 256 */
-	for (div = 0; div < 256; div++) {
-		utemp1 = utemp0 / (div + 1);
-
-		/*
-		 * SCL_L and SCL_H each has max value of 255
-		 * Hence, For the clk_cycle to the have right value
-		 * utemp1 has to be less then 512 and more than 4.
-		 */
-		if ((utemp1 < 512) && (utemp1 > 4)) {
-			clk_cycle = utemp1 - 2;
-			break;
-		} else if (div == 255) {
-			dev_warn(i2c->dev, "Failed to calculate divisor");
-			return -EINVAL;
-		}
+	temp = clkin / op_clk - 8 - t_ftl_cycle;
+	if (i2c->variant->hw != HSI2C_EXYNOS7)
+		temp -= t_ftl_cycle;
+	div = temp / 512;
+	clk_cycle = temp / (div + 1) - 2;
+	if (temp < 4 || div >= 256 || clk_cycle < 2) {
+		dev_warn(i2c->dev, "Failed to calculate divisor");
+		return -EINVAL;
 	}
 
 	t_scl_l = clk_cycle / 2;