linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] sunxi factors clock predivider handling
@ 2016-04-19 16:47 Vishnu Patekar
  2016-04-19 16:47 ` [PATCH v2] clk: sunxi: predivider handling for factors clock Vishnu Patekar
  0 siblings, 1 reply; 8+ messages in thread
From: Vishnu Patekar @ 2016-04-19 16:47 UTC (permalink / raw)
  To: maxime.ripard, emilio, wens
  Cc: sboyd, linux-arm-kernel, linux-kernel, linux-sunxi

For allwinner A31 ahb1 and a83t ahb1 clocks have predivider for certain parent.

Currently, it's being handled in clock specific functions. 

A83t ahb1 and a31 ahb1 are similar clocks except a83t parent index 0b10 and 0b11
are pll6/prediv and a31 ahb1 parent index 0x11 is pll6/prediv.
with only this change, code duplication was needed.

To handle this, this patch adds predivider table with parent index, prediv 
shift and width, parents with predivider will have nonzero width.

Rate adjustment is moved from clock specific recalc function to generic factors
recalc. clock specific recalc was currently used only by a31 ahb1.

For getter, it differentiates parents with prediv, with non-zero prediv width.

I've tested this patch on a83t bpi-m3 board. I do not have a31 device.
As there are dependencies on other a83t patches, a83t changes are not included
in this patch, It'll be included in separate patch.


v1->v2 Changes:
1. As 'kbuild test robot' reported build failure due to dependency on patches,
Combined two patches in v1 into single patch.


Vishnu Patekar (1):
  clk: sunxi: predivider handling for factors clock

 drivers/clk/sunxi/clk-factors.c | 31 +++++++++++++++----------------
 drivers/clk/sunxi/clk-factors.h | 10 +++++++++-
 drivers/clk/sunxi/clk-sunxi.c   | 31 +++++++++----------------------
 3 files changed, 33 insertions(+), 39 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2] clk: sunxi: predivider handling for factors clock
  2016-04-19 16:47 [PATCH v2] sunxi factors clock predivider handling Vishnu Patekar
@ 2016-04-19 16:47 ` Vishnu Patekar
  2016-04-25 14:51   ` Chen-Yu Tsai
  2016-05-02 11:13   ` Maxime Ripard
  0 siblings, 2 replies; 8+ messages in thread
From: Vishnu Patekar @ 2016-04-19 16:47 UTC (permalink / raw)
  To: maxime.ripard, emilio, wens
  Cc: sboyd, linux-arm-kernel, linux-kernel, linux-sunxi

For A31 ahb1 and a83t ahb1 clocks have predivider for certain parent.
To handle this, this patch adds predivider table with parent index,
prediv shift and width, parents with predivider will have nonzero width.

Rate adjustment is moved from clock specific recalc function to generic
factors recalc. Also, adds prediv table for a31.

Signed-off-by: Vishnu Patekar <vishnupatekar0510@gmail.com>
---
 drivers/clk/sunxi/clk-factors.c | 31 +++++++++++++++----------------
 drivers/clk/sunxi/clk-factors.h | 10 +++++++++-
 drivers/clk/sunxi/clk-sunxi.c   | 31 +++++++++----------------------
 3 files changed, 33 insertions(+), 39 deletions(-)

diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index ddefe96..8f3b637 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -45,10 +45,12 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
 	u8 n = 1, k = 0, p = 0, m = 0;
+	u8 par_index = 0;
 	u32 reg;
 	unsigned long rate;
 	struct clk_factors *factors = to_clk_factors(hw);
 	const struct clk_factors_config *config = factors->config;
+	const struct clk_factors_prediv *prediv = factors->prediv_config;
 
 	/* Fetch the register value */
 	reg = readl(factors->reg);
@@ -63,24 +65,16 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
 	if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
 		p = FACTOR_GET(config->pshift, config->pwidth, reg);
 
-	if (factors->recalc) {
-		struct factors_request factors_req = {
-			.parent_rate = parent_rate,
-			.n = n,
-			.k = k,
-			.m = m,
-			.p = p,
-		};
-
+	if (prediv) {
 		/* get mux details from mux clk structure */
 		if (factors->mux)
-			factors_req.parent_index =
-				(reg >> factors->mux->shift) &
-				factors->mux->mask;
-
-		factors->recalc(&factors_req);
+			par_index = (reg >> factors->mux->shift) &
+					factors->mux->mask;
 
-		return factors_req.rate;
+		if (prediv[par_index].width != SUNXI_FACTORS_NOT_APPLICABLE) {
+			m = FACTOR_GET(prediv[par_index].shift,
+				prediv[par_index].width, reg);
+		}
 	}
 
 	/* Calculate the rate */
@@ -102,8 +96,12 @@ static int clk_factors_determine_rate(struct clk_hw *hw,
 	for (i = 0; i < num_parents; i++) {
 		struct factors_request factors_req = {
 			.rate = req->rate,
-			.parent_index = i,
 		};
+
+		if (factors->prediv_config)
+			factors_req.prediv_width =
+						factors->prediv_config[i].width;
+
 		parent = clk_hw_get_parent_by_index(hw, i);
 		if (!parent)
 			continue;
@@ -211,6 +209,7 @@ struct clk *sunxi_factors_register(struct device_node *node,
 	/* set up factors properties */
 	factors->reg = reg;
 	factors->config = data->table;
+	factors->prediv_config = data->prediv_table;
 	factors->get_factors = data->getter;
 	factors->recalc = data->recalc;
 	factors->lock = lock;
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
index 1e63c5b..b1b7745 100644
--- a/drivers/clk/sunxi/clk-factors.h
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -18,10 +18,16 @@ struct clk_factors_config {
 	u8 n_start;
 };
 
+struct clk_factors_prediv {
+	u8 parent_index;
+	u8 shift;
+	u8 width;
+};
+
 struct factors_request {
 	unsigned long rate;
 	unsigned long parent_rate;
-	u8 parent_index;
+	u8 prediv_width;
 	u8 n;
 	u8 k;
 	u8 m;
@@ -33,6 +39,7 @@ struct factors_data {
 	int mux;
 	int muxmask;
 	const struct clk_factors_config *table;
+	const struct clk_factors_prediv *prediv_table;
 	void (*getter)(struct factors_request *req);
 	void (*recalc)(struct factors_request *req);
 	const char *name;
@@ -42,6 +49,7 @@ struct clk_factors {
 	struct clk_hw hw;
 	void __iomem *reg;
 	const struct clk_factors_config *config;
+	const struct clk_factors_prediv *prediv_config;
 	void (*get_factors)(struct factors_request *req);
 	void (*recalc)(struct factors_request *req);
 	spinlock_t *lock;
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 91de0a0..5a5f26b 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -282,8 +282,6 @@ static void sun5i_a13_get_ahb_factors(struct factors_request *req)
 	req->p = div;
 }
 
-#define SUN6I_AHB1_PARENT_PLL6	3
-
 /**
  * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB
  * AHB rate is calculated as follows
@@ -307,7 +305,7 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
 	div = DIV_ROUND_UP(req->parent_rate, req->rate);
 
 	/* calculate pre-divider if parent is pll6 */
-	if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) {
+	if (req->prediv_width) {
 		if (div < 4)
 			calcp = 0;
 		else if (div / 2 < 4)
@@ -329,22 +327,6 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
 }
 
 /**
- * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and
- *			 parent index
- */
-static void sun6i_ahb1_recalc(struct factors_request *req)
-{
-	req->rate = req->parent_rate;
-
-	/* apply pre-divider first if parent is pll6 */
-	if (req->parent_index == SUN6I_AHB1_PARENT_PLL6)
-		req->rate /= req->m + 1;
-
-	/* clk divider */
-	req->rate >>= req->p;
-}
-
-/**
  * sun4i_get_apb1_factors() - calculates m, p factors for APB1
  * APB1 rate is calculated as follows
  * rate = (parent_rate >> p) / (m + 1);
@@ -474,12 +456,17 @@ static const struct clk_factors_config sun5i_a13_ahb_config = {
 };
 
 static const struct clk_factors_config sun6i_ahb1_config = {
-	.mshift = 6,
-	.mwidth = 2,
 	.pshift = 4,
 	.pwidth = 2,
 };
 
+static const struct clk_factors_prediv sun6i_ahb1_prediv[] = {
+	{.parent_index = 0, .shift = 0, .width = 0 },	/* LOSC  */
+	{.parent_index = 1, .shift = 0, .width = 0 },	/* OSC24MHz */
+	{.parent_index = 2, .shift = 0, .width = 0 },	/* AXI */
+	{.parent_index = 3, .shift = 6, .width = 2 }	/* PLL6/Pre_div */
+};
+
 static const struct clk_factors_config sun4i_apb1_config = {
 	.mshift = 0,
 	.mwidth = 5,
@@ -551,8 +538,8 @@ static const struct factors_data sun6i_ahb1_data __initconst = {
 	.mux = 12,
 	.muxmask = BIT(1) | BIT(0),
 	.table = &sun6i_ahb1_config,
+	.prediv_table = sun6i_ahb1_prediv,
 	.getter = sun6i_get_ahb1_factors,
-	.recalc = sun6i_ahb1_recalc,
 };
 
 static const struct factors_data sun4i_apb1_data __initconst = {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
  2016-04-19 16:47 ` [PATCH v2] clk: sunxi: predivider handling for factors clock Vishnu Patekar
@ 2016-04-25 14:51   ` Chen-Yu Tsai
  2016-04-26 17:55     ` Vishnu Patekar
  2016-05-02 11:13   ` Maxime Ripard
  1 sibling, 1 reply; 8+ messages in thread
From: Chen-Yu Tsai @ 2016-04-25 14:51 UTC (permalink / raw)
  To: Vishnu Patekar
  Cc: Maxime Ripard, Emilio Lopez, Chen-Yu Tsai, Stephen Boyd,
	linux-arm-kernel, linux-kernel, linux-sunxi

Hi,

On Wed, Apr 20, 2016 at 12:47 AM, Vishnu Patekar
<vishnupatekar0510@gmail.com> wrote:
> For A31 ahb1 and a83t ahb1 clocks have predivider for certain parent.
> To handle this, this patch adds predivider table with parent index,
> prediv shift and width, parents with predivider will have nonzero width.
>
> Rate adjustment is moved from clock specific recalc function to generic
> factors recalc. Also, adds prediv table for a31.
>
> Signed-off-by: Vishnu Patekar <vishnupatekar0510@gmail.com>
> ---
>  drivers/clk/sunxi/clk-factors.c | 31 +++++++++++++++----------------
>  drivers/clk/sunxi/clk-factors.h | 10 +++++++++-
>  drivers/clk/sunxi/clk-sunxi.c   | 31 +++++++++----------------------
>  3 files changed, 33 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
> index ddefe96..8f3b637 100644
> --- a/drivers/clk/sunxi/clk-factors.c
> +++ b/drivers/clk/sunxi/clk-factors.c
> @@ -45,10 +45,12 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
>                                              unsigned long parent_rate)
>  {
>         u8 n = 1, k = 0, p = 0, m = 0;
> +       u8 par_index = 0;
>         u32 reg;
>         unsigned long rate;
>         struct clk_factors *factors = to_clk_factors(hw);
>         const struct clk_factors_config *config = factors->config;
> +       const struct clk_factors_prediv *prediv = factors->prediv_config;
>
>         /* Fetch the register value */
>         reg = readl(factors->reg);
> @@ -63,24 +65,16 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
>         if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
>                 p = FACTOR_GET(config->pshift, config->pwidth, reg);
>
> -       if (factors->recalc) {
> -               struct factors_request factors_req = {
> -                       .parent_rate = parent_rate,
> -                       .n = n,
> -                       .k = k,
> -                       .m = m,
> -                       .p = p,
> -               };
> -
> +       if (prediv) {
>                 /* get mux details from mux clk structure */
>                 if (factors->mux)
> -                       factors_req.parent_index =
> -                               (reg >> factors->mux->shift) &
> -                               factors->mux->mask;
> -
> -               factors->recalc(&factors_req);
> +                       par_index = (reg >> factors->mux->shift) &
> +                                       factors->mux->mask;
>
> -               return factors_req.rate;
> +               if (prediv[par_index].width != SUNXI_FACTORS_NOT_APPLICABLE) {
> +                       m = FACTOR_GET(prediv[par_index].shift,
> +                               prediv[par_index].width, reg);
> +               }
>         }
>
>         /* Calculate the rate */
> @@ -102,8 +96,12 @@ static int clk_factors_determine_rate(struct clk_hw *hw,
>         for (i = 0; i < num_parents; i++) {
>                 struct factors_request factors_req = {
>                         .rate = req->rate,
> -                       .parent_index = i,
>                 };
> +
> +               if (factors->prediv_config)
> +                       factors_req.prediv_width =
> +                                               factors->prediv_config[i].width;
> +
>                 parent = clk_hw_get_parent_by_index(hw, i);
>                 if (!parent)
>                         continue;
> @@ -211,6 +209,7 @@ struct clk *sunxi_factors_register(struct device_node *node,
>         /* set up factors properties */
>         factors->reg = reg;
>         factors->config = data->table;
> +       factors->prediv_config = data->prediv_table;
>         factors->get_factors = data->getter;
>         factors->recalc = data->recalc;
>         factors->lock = lock;
> diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
> index 1e63c5b..b1b7745 100644
> --- a/drivers/clk/sunxi/clk-factors.h
> +++ b/drivers/clk/sunxi/clk-factors.h
> @@ -18,10 +18,16 @@ struct clk_factors_config {
>         u8 n_start;
>  };
>
> +struct clk_factors_prediv {
> +       u8 parent_index;
> +       u8 shift;
> +       u8 width;
> +};
> +
>  struct factors_request {
>         unsigned long rate;
>         unsigned long parent_rate;
> -       u8 parent_index;
> +       u8 prediv_width;
>         u8 n;
>         u8 k;
>         u8 m;
> @@ -33,6 +39,7 @@ struct factors_data {
>         int mux;
>         int muxmask;
>         const struct clk_factors_config *table;
> +       const struct clk_factors_prediv *prediv_table;
>         void (*getter)(struct factors_request *req);
>         void (*recalc)(struct factors_request *req);

You removed usage of this callback. Please remove it from the data structures
as well, so no one assumes it's still applicable.

>         const char *name;
> @@ -42,6 +49,7 @@ struct clk_factors {
>         struct clk_hw hw;
>         void __iomem *reg;
>         const struct clk_factors_config *config;
> +       const struct clk_factors_prediv *prediv_config;
>         void (*get_factors)(struct factors_request *req);
>         void (*recalc)(struct factors_request *req);
>         spinlock_t *lock;
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 91de0a0..5a5f26b 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -282,8 +282,6 @@ static void sun5i_a13_get_ahb_factors(struct factors_request *req)
>         req->p = div;
>  }
>
> -#define SUN6I_AHB1_PARENT_PLL6 3
> -
>  /**
>   * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB
>   * AHB rate is calculated as follows
> @@ -307,7 +305,7 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
>         div = DIV_ROUND_UP(req->parent_rate, req->rate);
>
>         /* calculate pre-divider if parent is pll6 */
> -       if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) {
> +       if (req->prediv_width) {
>                 if (div < 4)
>                         calcp = 0;
>                 else if (div / 2 < 4)
> @@ -329,22 +327,6 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
>  }
>
>  /**
> - * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and
> - *                      parent index
> - */
> -static void sun6i_ahb1_recalc(struct factors_request *req)
> -{
> -       req->rate = req->parent_rate;
> -
> -       /* apply pre-divider first if parent is pll6 */
> -       if (req->parent_index == SUN6I_AHB1_PARENT_PLL6)
> -               req->rate /= req->m + 1;
> -
> -       /* clk divider */
> -       req->rate >>= req->p;
> -}
> -
> -/**
>   * sun4i_get_apb1_factors() - calculates m, p factors for APB1
>   * APB1 rate is calculated as follows
>   * rate = (parent_rate >> p) / (m + 1);
> @@ -474,12 +456,17 @@ static const struct clk_factors_config sun5i_a13_ahb_config = {
>  };
>
>  static const struct clk_factors_config sun6i_ahb1_config = {
> -       .mshift = 6,
> -       .mwidth = 2,
>         .pshift = 4,
>         .pwidth = 2,
>  };
>
> +static const struct clk_factors_prediv sun6i_ahb1_prediv[] = {
> +       {.parent_index = 0, .shift = 0, .width = 0 },   /* LOSC  */
> +       {.parent_index = 1, .shift = 0, .width = 0 },   /* OSC24MHz */
> +       {.parent_index = 2, .shift = 0, .width = 0 },   /* AXI */
> +       {.parent_index = 3, .shift = 6, .width = 2 }    /* PLL6/Pre_div */

           ^ a space here would be nice.                         ^
spaces around here too.

> +};
> +
>  static const struct clk_factors_config sun4i_apb1_config = {
>         .mshift = 0,
>         .mwidth = 5,
> @@ -551,8 +538,8 @@ static const struct factors_data sun6i_ahb1_data __initconst = {
>         .mux = 12,
>         .muxmask = BIT(1) | BIT(0),
>         .table = &sun6i_ahb1_config,
> +       .prediv_table = sun6i_ahb1_prediv,
>         .getter = sun6i_get_ahb1_factors,
> -       .recalc = sun6i_ahb1_recalc,
>  };
>
>  static const struct factors_data sun4i_apb1_data __initconst = {
> --
> 1.9.1
>

The rest looks good.

Regards
ChenYu

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
  2016-04-25 14:51   ` Chen-Yu Tsai
@ 2016-04-26 17:55     ` Vishnu Patekar
  0 siblings, 0 replies; 8+ messages in thread
From: Vishnu Patekar @ 2016-04-26 17:55 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Emilio Lopez, Stephen Boyd, linux-arm-kernel,
	linux-kernel, linux-sunxi

Hello Wens,

On Mon, Apr 25, 2016 at 10:51 PM, Chen-Yu Tsai <wens@csie.org> wrote:
> Hi,
>
> On Wed, Apr 20, 2016 at 12:47 AM, Vishnu Patekar
> <vishnupatekar0510@gmail.com> wrote:
>> For A31 ahb1 and a83t ahb1 clocks have predivider for certain parent.
>> To handle this, this patch adds predivider table with parent index,
>> prediv shift and width, parents with predivider will have nonzero width.
>>
>> Rate adjustment is moved from clock specific recalc function to generic
>> factors recalc. Also, adds prediv table for a31.
>>
>> Signed-off-by: Vishnu Patekar <vishnupatekar0510@gmail.com>
>> ---
>>  drivers/clk/sunxi/clk-factors.c | 31 +++++++++++++++----------------
>>  drivers/clk/sunxi/clk-factors.h | 10 +++++++++-
>>  drivers/clk/sunxi/clk-sunxi.c   | 31 +++++++++----------------------
>>  3 files changed, 33 insertions(+), 39 deletions(-)
>>
>> diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
>> index ddefe96..8f3b637 100644
>> --- a/drivers/clk/sunxi/clk-factors.c
>> +++ b/drivers/clk/sunxi/clk-factors.c
>> @@ -45,10 +45,12 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
>>                                              unsigned long parent_rate)
>>  {
>>         u8 n = 1, k = 0, p = 0, m = 0;
>> +       u8 par_index = 0;
>>         u32 reg;
>>         unsigned long rate;
>>         struct clk_factors *factors = to_clk_factors(hw);
>>         const struct clk_factors_config *config = factors->config;
>> +       const struct clk_factors_prediv *prediv = factors->prediv_config;
>>
>>         /* Fetch the register value */
>>         reg = readl(factors->reg);
>> @@ -63,24 +65,16 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
>>         if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
>>                 p = FACTOR_GET(config->pshift, config->pwidth, reg);
>>
>> -       if (factors->recalc) {
>> -               struct factors_request factors_req = {
>> -                       .parent_rate = parent_rate,
>> -                       .n = n,
>> -                       .k = k,
>> -                       .m = m,
>> -                       .p = p,
>> -               };
>> -
>> +       if (prediv) {
>>                 /* get mux details from mux clk structure */
>>                 if (factors->mux)
>> -                       factors_req.parent_index =
>> -                               (reg >> factors->mux->shift) &
>> -                               factors->mux->mask;
>> -
>> -               factors->recalc(&factors_req);
>> +                       par_index = (reg >> factors->mux->shift) &
>> +                                       factors->mux->mask;
>>
>> -               return factors_req.rate;
>> +               if (prediv[par_index].width != SUNXI_FACTORS_NOT_APPLICABLE) {
>> +                       m = FACTOR_GET(prediv[par_index].shift,
>> +                               prediv[par_index].width, reg);
>> +               }
>>         }
>>
>>         /* Calculate the rate */
>> @@ -102,8 +96,12 @@ static int clk_factors_determine_rate(struct clk_hw *hw,
>>         for (i = 0; i < num_parents; i++) {
>>                 struct factors_request factors_req = {
>>                         .rate = req->rate,
>> -                       .parent_index = i,
>>                 };
>> +
>> +               if (factors->prediv_config)
>> +                       factors_req.prediv_width =
>> +                                               factors->prediv_config[i].width;
>> +
>>                 parent = clk_hw_get_parent_by_index(hw, i);
>>                 if (!parent)
>>                         continue;
>> @@ -211,6 +209,7 @@ struct clk *sunxi_factors_register(struct device_node *node,
>>         /* set up factors properties */
>>         factors->reg = reg;
>>         factors->config = data->table;
>> +       factors->prediv_config = data->prediv_table;
>>         factors->get_factors = data->getter;
>>         factors->recalc = data->recalc;
>>         factors->lock = lock;
>> diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
>> index 1e63c5b..b1b7745 100644
>> --- a/drivers/clk/sunxi/clk-factors.h
>> +++ b/drivers/clk/sunxi/clk-factors.h
>> @@ -18,10 +18,16 @@ struct clk_factors_config {
>>         u8 n_start;
>>  };
>>
>> +struct clk_factors_prediv {
>> +       u8 parent_index;
>> +       u8 shift;
>> +       u8 width;
>> +};
>> +
>>  struct factors_request {
>>         unsigned long rate;
>>         unsigned long parent_rate;
>> -       u8 parent_index;
>> +       u8 prediv_width;
>>         u8 n;
>>         u8 k;
>>         u8 m;
>> @@ -33,6 +39,7 @@ struct factors_data {
>>         int mux;
>>         int muxmask;
>>         const struct clk_factors_config *table;
>> +       const struct clk_factors_prediv *prediv_table;
>>         void (*getter)(struct factors_request *req);
>>         void (*recalc)(struct factors_request *req);
>
> You removed usage of this callback. Please remove it from the data structures
> as well, so no one assumes it's still applicable.
Okie, I'll remove it.
>
>>         const char *name;
>> @@ -42,6 +49,7 @@ struct clk_factors {
>>         struct clk_hw hw;
>>         void __iomem *reg;
>>         const struct clk_factors_config *config;
>> +       const struct clk_factors_prediv *prediv_config;
>>         void (*get_factors)(struct factors_request *req);
>>         void (*recalc)(struct factors_request *req);
>>         spinlock_t *lock;
>> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
>> index 91de0a0..5a5f26b 100644
>> --- a/drivers/clk/sunxi/clk-sunxi.c
>> +++ b/drivers/clk/sunxi/clk-sunxi.c
>> @@ -282,8 +282,6 @@ static void sun5i_a13_get_ahb_factors(struct factors_request *req)
>>         req->p = div;
>>  }
>>
>> -#define SUN6I_AHB1_PARENT_PLL6 3
>> -
>>  /**
>>   * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB
>>   * AHB rate is calculated as follows
>> @@ -307,7 +305,7 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
>>         div = DIV_ROUND_UP(req->parent_rate, req->rate);
>>
>>         /* calculate pre-divider if parent is pll6 */
>> -       if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) {
>> +       if (req->prediv_width) {
>>                 if (div < 4)
>>                         calcp = 0;
>>                 else if (div / 2 < 4)
>> @@ -329,22 +327,6 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
>>  }
>>
>>  /**
>> - * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and
>> - *                      parent index
>> - */
>> -static void sun6i_ahb1_recalc(struct factors_request *req)
>> -{
>> -       req->rate = req->parent_rate;
>> -
>> -       /* apply pre-divider first if parent is pll6 */
>> -       if (req->parent_index == SUN6I_AHB1_PARENT_PLL6)
>> -               req->rate /= req->m + 1;
>> -
>> -       /* clk divider */
>> -       req->rate >>= req->p;
>> -}
>> -
>> -/**
>>   * sun4i_get_apb1_factors() - calculates m, p factors for APB1
>>   * APB1 rate is calculated as follows
>>   * rate = (parent_rate >> p) / (m + 1);
>> @@ -474,12 +456,17 @@ static const struct clk_factors_config sun5i_a13_ahb_config = {
>>  };
>>
>>  static const struct clk_factors_config sun6i_ahb1_config = {
>> -       .mshift = 6,
>> -       .mwidth = 2,
>>         .pshift = 4,
>>         .pwidth = 2,
>>  };
>>
>> +static const struct clk_factors_prediv sun6i_ahb1_prediv[] = {
>> +       {.parent_index = 0, .shift = 0, .width = 0 },   /* LOSC  */
>> +       {.parent_index = 1, .shift = 0, .width = 0 },   /* OSC24MHz */
>> +       {.parent_index = 2, .shift = 0, .width = 0 },   /* AXI */
>> +       {.parent_index = 3, .shift = 6, .width = 2 }    /* PLL6/Pre_div */
>
>            ^ a space here would be nice.                         ^
> spaces around here too.
Okie.
>
>> +};
>> +
>>  static const struct clk_factors_config sun4i_apb1_config = {
>>         .mshift = 0,
>>         .mwidth = 5,
>> @@ -551,8 +538,8 @@ static const struct factors_data sun6i_ahb1_data __initconst = {
>>         .mux = 12,
>>         .muxmask = BIT(1) | BIT(0),
>>         .table = &sun6i_ahb1_config,
>> +       .prediv_table = sun6i_ahb1_prediv,
>>         .getter = sun6i_get_ahb1_factors,
>> -       .recalc = sun6i_ahb1_recalc,
>>  };
>>
>>  static const struct factors_data sun4i_apb1_data __initconst = {
>> --
>> 1.9.1
>>
>
> The rest looks good.
Thanks for the review.
>
> Regards
> ChenYu

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
  2016-04-19 16:47 ` [PATCH v2] clk: sunxi: predivider handling for factors clock Vishnu Patekar
  2016-04-25 14:51   ` Chen-Yu Tsai
@ 2016-05-02 11:13   ` Maxime Ripard
       [not found]     ` <CAEzqOZvnKKNs_sXUJrwTykA5mzwKMg+HpaFcKgBTFr+utT4qQg@mail.gmail.com>
  1 sibling, 1 reply; 8+ messages in thread
From: Maxime Ripard @ 2016-05-02 11:13 UTC (permalink / raw)
  To: Vishnu Patekar
  Cc: emilio, wens, sboyd, linux-arm-kernel, linux-kernel, linux-sunxi

[-- Attachment #1: Type: text/plain, Size: 5438 bytes --]

Hi,

On Wed, Apr 20, 2016 at 12:47:46AM +0800, Vishnu Patekar wrote:
> For A31 ahb1 and a83t ahb1 clocks have predivider for certain parent.
> To handle this, this patch adds predivider table with parent index,
> prediv shift and width, parents with predivider will have nonzero width.
> 
> Rate adjustment is moved from clock specific recalc function to generic
> factors recalc. Also, adds prediv table for a31.
> 
> Signed-off-by: Vishnu Patekar <vishnupatekar0510@gmail.com>
> ---
>  drivers/clk/sunxi/clk-factors.c | 31 +++++++++++++++----------------
>  drivers/clk/sunxi/clk-factors.h | 10 +++++++++-
>  drivers/clk/sunxi/clk-sunxi.c   | 31 +++++++++----------------------
>  3 files changed, 33 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
> index ddefe96..8f3b637 100644
> --- a/drivers/clk/sunxi/clk-factors.c
> +++ b/drivers/clk/sunxi/clk-factors.c
> @@ -45,10 +45,12 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
>  					     unsigned long parent_rate)
>  {
>  	u8 n = 1, k = 0, p = 0, m = 0;
> +	u8 par_index = 0;
>  	u32 reg;
>  	unsigned long rate;
>  	struct clk_factors *factors = to_clk_factors(hw);
>  	const struct clk_factors_config *config = factors->config;
> +	const struct clk_factors_prediv *prediv = factors->prediv_config;
>  
>  	/* Fetch the register value */
>  	reg = readl(factors->reg);
> @@ -63,24 +65,16 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
>  	if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
>  		p = FACTOR_GET(config->pshift, config->pwidth, reg);
>  
> -	if (factors->recalc) {
> -		struct factors_request factors_req = {
> -			.parent_rate = parent_rate,
> -			.n = n,
> -			.k = k,
> -			.m = m,
> -			.p = p,
> -		};
> -
> +	if (prediv) {
>  		/* get mux details from mux clk structure */
>  		if (factors->mux)
> -			factors_req.parent_index =
> -				(reg >> factors->mux->shift) &
> -				factors->mux->mask;
> -
> -		factors->recalc(&factors_req);
> +			par_index = (reg >> factors->mux->shift) &
> +					factors->mux->mask;
>  
> -		return factors_req.rate;
> +		if (prediv[par_index].width != SUNXI_FACTORS_NOT_APPLICABLE) {
> +			m = FACTOR_GET(prediv[par_index].shift,
> +				prediv[par_index].width, reg);
> +		}
>  	}
>  
>  	/* Calculate the rate */
> @@ -102,8 +96,12 @@ static int clk_factors_determine_rate(struct clk_hw *hw,
>  	for (i = 0; i < num_parents; i++) {
>  		struct factors_request factors_req = {
>  			.rate = req->rate,
> -			.parent_index = i,
>  		};
> +
> +		if (factors->prediv_config)
> +			factors_req.prediv_width =
> +						factors->prediv_config[i].width;
> +
>  		parent = clk_hw_get_parent_by_index(hw, i);
>  		if (!parent)
>  			continue;
> @@ -211,6 +209,7 @@ struct clk *sunxi_factors_register(struct device_node *node,
>  	/* set up factors properties */
>  	factors->reg = reg;
>  	factors->config = data->table;
> +	factors->prediv_config = data->prediv_table;
>  	factors->get_factors = data->getter;
>  	factors->recalc = data->recalc;
>  	factors->lock = lock;
> diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
> index 1e63c5b..b1b7745 100644
> --- a/drivers/clk/sunxi/clk-factors.h
> +++ b/drivers/clk/sunxi/clk-factors.h
> @@ -18,10 +18,16 @@ struct clk_factors_config {
>  	u8 n_start;
>  };
>  
> +struct clk_factors_prediv {
> +	u8 parent_index;
> +	u8 shift;
> +	u8 width;
> +};
> +
>  struct factors_request {
>  	unsigned long rate;
>  	unsigned long parent_rate;
> -	u8 parent_index;
> +	u8 prediv_width;
>  	u8 n;
>  	u8 k;
>  	u8 m;
> @@ -33,6 +39,7 @@ struct factors_data {
>  	int mux;
>  	int muxmask;
>  	const struct clk_factors_config *table;
> +	const struct clk_factors_prediv *prediv_table;
>  	void (*getter)(struct factors_request *req);
>  	void (*recalc)(struct factors_request *req);
>  	const char *name;
> @@ -42,6 +49,7 @@ struct clk_factors {
>  	struct clk_hw hw;
>  	void __iomem *reg;
>  	const struct clk_factors_config *config;
> +	const struct clk_factors_prediv *prediv_config;
>  	void (*get_factors)(struct factors_request *req);
>  	void (*recalc)(struct factors_request *req);
>  	spinlock_t *lock;
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 91de0a0..5a5f26b 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -282,8 +282,6 @@ static void sun5i_a13_get_ahb_factors(struct factors_request *req)
>  	req->p = div;
>  }
>  
> -#define SUN6I_AHB1_PARENT_PLL6	3
> -
>  /**
>   * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB
>   * AHB rate is calculated as follows
> @@ -307,7 +305,7 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
>  	div = DIV_ROUND_UP(req->parent_rate, req->rate);
>  
>  	/* calculate pre-divider if parent is pll6 */
> -	if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) {
> +	if (req->prediv_width) {
>  		if (div < 4)
>  			calcp = 0;
>  		else if (div / 2 < 4)

You should also remove that code from that function. Now that the core
can tell the pre-divider configuration, it can adjust the parent rate
so that you don't have to care anymore.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
       [not found]     ` <CAEzqOZvnKKNs_sXUJrwTykA5mzwKMg+HpaFcKgBTFr+utT4qQg@mail.gmail.com>
@ 2016-05-30 18:45       ` Maxime Ripard
  2016-05-31  8:39         ` Jean-Francois Moine
  0 siblings, 1 reply; 8+ messages in thread
From: Maxime Ripard @ 2016-05-30 18:45 UTC (permalink / raw)
  To: Vishnu Patekar
  Cc: linux-arm-kernel, linux-sunxi, wens, sboyd, emilio, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1602 bytes --]

Hi Vishnu,

On Mon, May 16, 2016 at 07:28:42AM +0800, Vishnu Patekar wrote:
> > > @@ -307,7 +305,7 @@ static void sun6i_get_ahb1_factors(struct factors_request *req)
> > >       div = DIV_ROUND_UP(req->parent_rate, req->rate);
> > >
> > >       /* calculate pre-divider if parent is pll6 */
> > > -     if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) {
> > > +     if (req->prediv_width) {
> > >               if (div < 4)
> > >                       calcp = 0;
> > >               else if (div / 2 < 4)
> >
> > You should also remove that code from that function. Now that the core
> > can tell the pre-divider configuration, it can adjust the parent rate
> > so that you don't have to care anymore.
>
> We still need to get m factor when it's called from set_rate and
> determine_rate.
> 
> Sorry, I did not your "that code from that function" meaning. I assumed
> you're talking about m factor in sun6i_get_ahb1_factors.

Sorry for the late answer.

I don't know if you've seen it, but I have been working on a new clock
framework.

I went over all the A83T clocks, and most of them could be
covered. The issue only lies in the PLLs and their additional 1-bit
dividers.

If we just choos to ignore (one of) them, it should be pretty trivial
to implement with the current clock classes we have.

There's also the current assumption that there's a single parent that
has a pre-divider, but that can easily be fixed by setting up an
array.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
  2016-05-30 18:45       ` Maxime Ripard
@ 2016-05-31  8:39         ` Jean-Francois Moine
  2016-05-31  8:59           ` Maxime Ripard
  0 siblings, 1 reply; 8+ messages in thread
From: Jean-Francois Moine @ 2016-05-31  8:39 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Vishnu Patekar, emilio, sboyd, wens, linux-kernel, linux-sunxi,
	linux-arm-kernel

On Mon, 30 May 2016 20:45:32 +0200
Maxime Ripard <maxime.ripard@free-electrons.com> wrote:

> I went over all the A83T clocks, and most of them could be
> covered. The issue only lies in the PLLs and their additional 1-bit
> dividers.
> 
> If we just choos to ignore (one of) them, it should be pretty trivial
> to implement with the current clock classes we have.

Hi Maxime,

I already did the job for all the A83T clocks.
It is not fully tested yet, but, to be sure we are on the same way,
I am sending a RFC series.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
  2016-05-31  8:39         ` Jean-Francois Moine
@ 2016-05-31  8:59           ` Maxime Ripard
  0 siblings, 0 replies; 8+ messages in thread
From: Maxime Ripard @ 2016-05-31  8:59 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Vishnu Patekar, emilio, sboyd, wens, linux-kernel, linux-sunxi,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 778 bytes --]

On Tue, May 31, 2016 at 10:39:05AM +0200, Jean-Francois Moine wrote:
> On Mon, 30 May 2016 20:45:32 +0200
> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
> 
> > I went over all the A83T clocks, and most of them could be
> > covered. The issue only lies in the PLLs and their additional 1-bit
> > dividers.
> > 
> > If we just choos to ignore (one of) them, it should be pretty trivial
> > to implement with the current clock classes we have.
> 
> Hi Maxime,
> 
> I already did the job for all the A83T clocks.
> It is not fully tested yet, but, to be sure we are on the same way,
> I am sending a RFC series.

Awesome, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-05-31  8:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-19 16:47 [PATCH v2] sunxi factors clock predivider handling Vishnu Patekar
2016-04-19 16:47 ` [PATCH v2] clk: sunxi: predivider handling for factors clock Vishnu Patekar
2016-04-25 14:51   ` Chen-Yu Tsai
2016-04-26 17:55     ` Vishnu Patekar
2016-05-02 11:13   ` Maxime Ripard
     [not found]     ` <CAEzqOZvnKKNs_sXUJrwTykA5mzwKMg+HpaFcKgBTFr+utT4qQg@mail.gmail.com>
2016-05-30 18:45       ` Maxime Ripard
2016-05-31  8:39         ` Jean-Francois Moine
2016-05-31  8:59           ` Maxime Ripard

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).