All of lore.kernel.org
 help / color / mirror / Atom feed
From: maxime.ripard@free-electrons.com (Maxime Ripard)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2] clk: sunxi: predivider handling for factors clock
Date: Mon, 2 May 2016 13:13:37 +0200	[thread overview]
Message-ID: <20160502111337.GR17159@lukather> (raw)
In-Reply-To: <1461084466-20889-2-git-send-email-vishnupatekar0510@gmail.com>

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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160502/7d4f7805/attachment.sig>

WARNING: multiple messages have this Message-ID (diff)
From: Maxime Ripard <maxime.ripard@free-electrons.com>
To: Vishnu Patekar <vishnupatekar0510@gmail.com>
Cc: emilio@elopez.com.ar, wens@csie.org, sboyd@codeaurora.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com
Subject: Re: [PATCH v2] clk: sunxi: predivider handling for factors clock
Date: Mon, 2 May 2016 13:13:37 +0200	[thread overview]
Message-ID: <20160502111337.GR17159@lukather> (raw)
In-Reply-To: <1461084466-20889-2-git-send-email-vishnupatekar0510@gmail.com>

[-- 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 --]

  parent reply	other threads:[~2016-05-02 11:13 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-19 16:47 [PATCH v2] sunxi factors clock predivider handling Vishnu Patekar
2016-04-19 16:47 ` Vishnu Patekar
2016-04-19 16:47 ` [PATCH v2] clk: sunxi: predivider handling for factors clock Vishnu Patekar
2016-04-19 16:47   ` Vishnu Patekar
2016-04-25 14:51   ` Chen-Yu Tsai
2016-04-25 14:51     ` Chen-Yu Tsai
2016-04-26 17:55     ` Vishnu Patekar
2016-04-26 17:55       ` Vishnu Patekar
2016-05-02 11:13   ` Maxime Ripard [this message]
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-30 18:45         ` Maxime Ripard
2016-05-31  8:39         ` Jean-Francois Moine
2016-05-31  8:39           ` Jean-Francois Moine
2016-05-31  8:59           ` Maxime Ripard
2016-05-31  8:59             ` Maxime Ripard

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=20160502111337.GR17159@lukather \
    --to=maxime.ripard@free-electrons.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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.