All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Boyd <sboyd@codeaurora.org>
To: Abhishek Sahu <absahu@codeaurora.org>
Cc: andy.gross@linaro.org, david.brown@linaro.org,
	robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
	ijc+devicetree@hellion.org.uk, mturquette@baylibre.com,
	galak@codeaurora.org, pradeepb@codeaurora.org,
	mmcclint@codeaurora.org, varada@codeaurora.org,
	sricharan@codeaurora.org, architt@codeaurora.org,
	ntelkar@codeaurora.org, linux-arm-msm@vger.kernel.org,
	linux-soc@vger.kernel.org, linux-clk@vger.kernel.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v2 1/5] clk: qcom: ipq4019: Added the clock nodes and operations for pll
Date: Mon, 15 Aug 2016 15:19:56 -0700	[thread overview]
Message-ID: <20160815221956.GJ361@codeaurora.org> (raw)
In-Reply-To: <1466516962-18087-2-git-send-email-absahu@codeaurora.org>

On 06/21, Abhishek Sahu wrote:
> The current ipq4019 clock driver registered the PLL clocks and
> dividers as fixed clock. These fixed clock needs to be removed
> from driver probe function and same need to be registered with
> clock framework. These PLL clocks should be programmed only
> once and the same are being programmed already by the boot
> loader so the set rate operation is not required for these
> clocks. Only the rate can be calculated by clock operations
> in clock driver file so this patch adds the same.
> 
> The PLL takes the reference clock from XO and generates the
> intermediate VCO frequency. This VCO frequency will be divided
> down by different PLL internal dividers. Some of the PLL
> internal dividers are fixed while other are programmable.
> 
> This patch does the following changes.
> 1. Operation for calculating PLL intermediate VCO frequency by
>    reading the reference clock divider and feedback divider from
>    register. Since VCO frequency falls outside the limit of
>    unsigned long for IPQ4019, so this operation will return the
>    VCO frequency in KHz.
> 
> 2. Operation for calculating the internal PLL divider clock
>    frequency. Clock Divider node should give either fixed
>    divider value or divider table(maps the register divider
>    value to actual divider value).
> 
> 3. Adds and registers clock nodes for VCO(APPS DDR PLL and FE
>    PLL) and PLL internal dividers(SDCC, FEPLL 500 Mhz, FEPLL
>    200 Mhz, FEPLL 125 Mhz, FEPLL 125 Mhz with delay,
>    programmable WCSS 2G and 5G).
> 
> 4. Changes the regmap limit from 0x2DFFF to 0x2FFFF for
>    supporting the PLL registers read.
> 
> 5. Changes the fixed clock name to have consistency in all
>    clock names
> 
> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>

Thanks for fixing this up, just some minor things to fix.

> diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c
> index 3cd1af0..17ca6d3 100644
> --- a/drivers/clk/qcom/gcc-ipq4019.c
> +++ b/drivers/clk/qcom/gcc-ipq4019.c
> @@ -20,6 +20,11 @@
>  #include <linux/clk-provider.h>
>  #include <linux/regmap.h>
>  #include <linux/reset-controller.h>
> +#include <linux/clk.h>

Is this include used?

> +#include <linux/delay.h>

Is this include used?

> +#include <linux/bitops.h>
> +#include <linux/math64.h>
> +#include <asm/div64.h>

Are both includes needed?

> @@ -40,6 +55,20 @@ enum {
>  	P_DDRPLLAPSS,
>  };
>  
> +struct clk_pll_vco {
> +	u32 fdbkdiv_shift;
> +	u32 fdbkdiv_width;
> +	struct clk_regmap_div cdiv;
> +};
> +
> +struct clk_pll_div {
> +	u32 fixed_div;
> +	const u8 *parent_map;
> +	struct clk_regmap_div cdiv;
> +	const struct clk_div_table *div_table;
> +	const struct freq_tbl *freq_tbl;
> +};
> +
>  static struct parent_map gcc_xo_200_500_map[] = {
>  	{ P_XO, 0 },
>  	{ P_FEPLL200, 1 },
> @@ -48,8 +77,8 @@ static struct parent_map gcc_xo_200_500_map[] = {
>  
>  static const char * const gcc_xo_200_500[] = {
>  	"xo",
> -	"fepll200",
> -	"fepll500",
> +	"gcc_fepll200_clk",
> +	"gcc_fepll500_clk",
>  };
>  
>  static struct parent_map gcc_xo_200_map[] = {
> @@ -59,7 +88,7 @@ static struct parent_map gcc_xo_200_map[] = {
>  
>  static const char * const gcc_xo_200[] = {
>  	"xo",
> -	"fepll200",
> +	"gcc_fepll200_clk",
>  };
>  
>  static struct parent_map gcc_xo_200_spi_map[] = {
> @@ -69,7 +98,7 @@ static struct parent_map gcc_xo_200_spi_map[] = {
>  
>  static const char * const gcc_xo_200_spi[] = {
>  	"xo",
> -	"fepll200",
> +	"gcc_fepll200_clk",
>  };
>  
>  static struct parent_map gcc_xo_sdcc1_500_map[] = {
> @@ -80,8 +109,8 @@ static struct parent_map gcc_xo_sdcc1_500_map[] = {
>  
>  static const char * const gcc_xo_sdcc1_500[] = {
>  	"xo",
> -	"ddrpll",
> -	"fepll500",
> +	"gcc_apps_sdcc_clk",
> +	"gcc_fepll500_clk",
>  };
>  
>  static struct parent_map gcc_xo_wcss2g_map[] = {
> @@ -91,7 +120,7 @@ static struct parent_map gcc_xo_wcss2g_map[] = {
>  
>  static const char * const gcc_xo_wcss2g[] = {
>  	"xo",
> -	"fepllwcss2g",
> +	"gcc_fepllwcss2g_clk",
>  };
>  
>  static struct parent_map gcc_xo_wcss5g_map[] = {
> @@ -101,7 +130,7 @@ static struct parent_map gcc_xo_wcss5g_map[] = {
>  
>  static const char * const gcc_xo_wcss5g[] = {
>  	"xo",
> -	"fepllwcss5g",
> +	"gcc_fepllwcss5g_clk",
>  };
>  
>  static struct parent_map gcc_xo_125_dly_map[] = {
> @@ -111,7 +140,7 @@ static struct parent_map gcc_xo_125_dly_map[] = {
>  
>  static const char * const gcc_xo_125_dly[] = {
>  	"xo",
> -	"fepll125dly",
> +	"gcc_fepll125dly_clk",
>  };
>  
>  static struct parent_map gcc_xo_ddr_500_200_map[] = {
> @@ -123,8 +152,8 @@ static struct parent_map gcc_xo_ddr_500_200_map[] = {
>  
>  static const char * const gcc_xo_ddr_500_200[] = {
>  	"xo",
> -	"fepll200",
> -	"fepll500",
> +	"gcc_fepll200_clk",
> +	"gcc_fepll500_clk",
>  	"ddrpllapss",
>  };

Was it necessary to change all these names? The gcc_ prefix
doesn't seem to be adding much besides noise to this patch.

>  
> @@ -506,7 +535,7 @@ static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = {
>  	F(25000000,  P_FEPLL500,		1,  1, 20),
>  	F(50000000,  P_FEPLL500,		1,  1, 10),
>  	F(100000000, P_FEPLL500,		1,  1, 5),
> -	F(193000000, P_DDRPLL,		1,  0, 0),
> +	F(190000000, P_DDRPLL,		1,  0, 0),

This looks like an unrelated bug fix.

>  	{ }
>  };
>  
> @@ -658,7 +687,7 @@ static struct clk_branch gcc_crypto_axi_clk = {
>  		.hw.init = &(struct clk_init_data){
>  			.name = "gcc_crypto_axi_clk",
>  			.parent_names = (const char *[]){
> -				"fepll125",
> +				"gcc_fepll125_clk",
>  			},
>  			.num_parents = 1,
>  			.ops = &clk_branch2_ops,
> @@ -675,7 +704,7 @@ static struct clk_branch gcc_crypto_clk = {
>  		.hw.init = &(struct clk_init_data){
>  			.name = "gcc_crypto_clk",
>  			.parent_names = (const char *[]){
> -				"fepll125",
> +				"gcc_fepll125_clk",
>  			},
>  			.num_parents = 1,
>  			.ops = &clk_branch2_ops,
> @@ -709,7 +738,7 @@ static struct clk_branch gcc_imem_axi_clk = {
>  		.hw.init = &(struct clk_init_data){
>  			.name = "gcc_imem_axi_clk",
>  			.parent_names = (const char *[]){
> -				"fepll200",
> +				"gcc_fepll200_clk",
>  			},
>  			.num_parents = 1,
>  			.ops = &clk_branch2_ops,
> @@ -773,7 +802,7 @@ static struct clk_branch gcc_pcie_axi_s_clk = {
>  		.hw.init = &(struct clk_init_data){
>  			.name = "gcc_pcie_axi_s_clk",
>  			.parent_names = (const char *[]){
> -				"fepll200",
> +				"gcc_fepll200_clk",
>  			},
>  			.num_parents = 1,
>  			.ops = &clk_branch2_ops,
> @@ -955,7 +984,7 @@ static struct clk_branch gcc_usb3_master_clk = {
>  		.hw.init = &(struct clk_init_data){
>  			.name = "gcc_usb3_master_clk",
>  			.parent_names = (const char *[]){
> -				"fepll125",
> +				"gcc_fepll125_clk",
>  			},
>  			.num_parents = 1,
>  			.ops = &clk_branch2_ops,
> @@ -1155,6 +1184,238 @@ static struct clk_branch gcc_wcss5g_rtc_clk = {
>  	},
>  };
>  
> +/*
> + * Calculates the rate from parent rate and divider and round the rate
> + * in Mhz. This function takes the parent rate in Khz and returns the
> + * rate in Hz.
> + */
> +static unsigned long clk_calc_divider_rate(unsigned long parent_rate,
> +				unsigned int div)
> +{
> +	u64 rate = parent_rate;
> +
> +	do_div(rate, div);
> +
> +	/*
> +	 * This rate is in KHz so divide with 1000 and multiply with 1000000

s/KHz/kHz/

> +	 * to get the rate in Hz.
> +	 */
> +	do_div(rate, 1000);
> +	rate *= 1000000;
> +
> +	return (unsigned long)rate;

Unnecessary cast, please remove.

> +}
> +
> +/*
> + * Calculates the VCO rate for PLL.
> + * VCO rate value is greater than unsigned long limit. Since this is an
> + * intermediate clock node for actual PLL dividers, so it returns the
> + * rate in Khz. The child nodes will return the value in Hz after its
> + * divide operation.
> + */
> +static unsigned long clk_regmap_vco_recalc_rate(struct clk_hw *hw,
> +						unsigned long parent_rate)
> +{
> +	struct clk_pll_vco *rcg = to_clk_pll_vco(hw);
> +	u32 fdbkdiv, refclkdiv, cdiv;
> +	u64 vco;
> +
> +	regmap_read(rcg->cdiv.clkr.regmap, rcg->cdiv.reg, &cdiv);
> +	refclkdiv = (cdiv >> rcg->cdiv.shift) & (BIT(rcg->cdiv.width) - 1);
> +	fdbkdiv = (cdiv >> rcg->fdbkdiv_shift) & (BIT(rcg->fdbkdiv_width) - 1);
> +
> +	vco = parent_rate;
> +	do_div(vco, refclkdiv);
> +	do_div(vco, 1000);
> +	vco *= 2;
> +	vco *= fdbkdiv;
> +
> +	return (unsigned long)vco;

unnecessary cast.

> +}
> +
> +const struct clk_ops clk_regmap_vco_ops = {

static?

> +	.recalc_rate = clk_regmap_vco_recalc_rate,
> +};
> +
> +static struct clk_pll_vco gcc_apps_ddrpll_vco = {
> +	.fdbkdiv_shift = 16,
> +	.fdbkdiv_width = 8,
> +	.cdiv.reg = 0x2E020,

lowercase hex please.

> +	.cdiv.shift = 24,
> +	.cdiv.width = 5,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_apps_ddrpll_vco",
> +			.parent_names = (const char *[]){
> +				"xo",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_vco_ops,
> +		},
> +	},
> +};
> +
> +static struct clk_pll_vco gcc_fepll_vco = {
> +	.fdbkdiv_shift = 16,
> +	.fdbkdiv_width = 8,
> +	.cdiv.reg = 0x2F020,
> +	.cdiv.shift = 24,
> +	.cdiv.width = 5,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_fepll_vco",
> +			.parent_names = (const char *[]){
> +				"xo",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_vco_ops,
> +		},
> +	},
> +};
> +
> +/* Calculates the rate for PLL divider.

Style nit, /* goes on its own line

> + * If the divider value is not fixed then it gets the actual divider value
> + * from divider table. Then, it calculate the clock rate by dividing the
> + * parent rate with actual divider value.
> + */
> +static unsigned long clk_regmap_clk_div_recalc_rate(struct clk_hw *hw,
> +					   unsigned long parent_rate)
> +{
> +	struct clk_pll_div *rcg = to_clk_pll_div(hw);
> +	u32 cdiv, pre_div = 1;
> +	const struct clk_div_table *clkt;
> +
> +	if (rcg->fixed_div) {
> +		pre_div = rcg->fixed_div;
> +	} else {
> +		regmap_read(rcg->cdiv.clkr.regmap, rcg->cdiv.reg, &cdiv);
> +		cdiv = (cdiv >> rcg->cdiv.shift) & (BIT(rcg->cdiv.width) - 1);
> +
> +		for (clkt = rcg->div_table; clkt->div; clkt++) {
> +			if (clkt->val == cdiv)
> +				pre_div = clkt->div;
> +		}
> +	}
> +
> +	return clk_calc_divider_rate(parent_rate, pre_div);
> +};
> +
> +const struct clk_ops clk_regmap_clk_div_ops = {

static?

> +	.recalc_rate = clk_regmap_clk_div_recalc_rate,
> +};
> +
> +static struct clk_pll_div gcc_apps_sdcc_clk = {
> +	.fixed_div = 28,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_apps_sdcc_clk",
> +			.parent_names = (const char *[]){
> +				"gcc_apps_ddrpll_vco",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_clk_div_ops,
> +		},
> +	},
> +};
> +
> +static struct clk_pll_div gcc_fepll125_clk = {
> +	.fixed_div = 32,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_fepll125_clk",
> +			.parent_names = (const char *[]){
> +				"gcc_fepll_vco",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_clk_div_ops,
> +		},
> +	},
> +};
> +
> +static struct clk_pll_div gcc_fepll125dly_clk = {
> +	.fixed_div = 32,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_fepll125dly_clk",
> +			.parent_names = (const char *[]){
> +				"gcc_fepll_vco",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_clk_div_ops,
> +		},
> +	},
> +};
> +
> +static struct clk_pll_div gcc_fepll200_clk = {
> +	.fixed_div = 20,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_fepll200_clk",
> +			.parent_names = (const char *[]){
> +				"gcc_fepll_vco",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_clk_div_ops,
> +		},
> +	},
> +};
> +
> +static struct clk_pll_div gcc_fepll500_clk = {
> +	.fixed_div = 8,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_fepll500_clk",
> +			.parent_names = (const char *[]){
> +				"gcc_fepll_vco",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_clk_div_ops,
> +		},
> +	},
> +};
> +
> +static const struct clk_div_table fepllwcss_clk_div_table[] = {
> +	{0, 15},
> +	{1, 16},
> +	{2, 18},
> +	{3, 20},

Nitpick: Please add some spaces here

	{ 0, 15 },

> +	{},
> +};
> +
> +static struct clk_pll_div gcc_fepllwcss2g_clk = {
> +	.cdiv.reg = 0x2F020,
> +	.cdiv.shift = 8,
> +	.cdiv.width = 2,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_fepllwcss2g_clk",
> +			.parent_names = (const char *[]){
> +				"gcc_fepll_vco",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_clk_div_ops,
> +		},
> +	},
> +	.div_table = fepllwcss_clk_div_table
> +};
> +
> +static struct clk_pll_div gcc_fepllwcss5g_clk = {
> +	.cdiv.reg = 0x2F020,
> +	.cdiv.shift = 12,
> +	.cdiv.width = 2,
> +	.cdiv.clkr = {
> +		.hw.init = &(struct clk_init_data){
> +			.name = "gcc_fepllwcss5g_clk",
> +			.parent_names = (const char *[]){
> +				"gcc_fepll_vco",
> +			},
> +			.num_parents = 1,
> +			.ops = &clk_regmap_clk_div_ops,
> +		},
> +	},
> +	.div_table = fepllwcss_clk_div_table
> +};
> +
>  static struct clk_regmap *gcc_ipq4019_clocks[] = {
>  	[AUDIO_CLK_SRC] = &audio_clk_src.clkr,
>  	[BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
> @@ -1215,6 +1476,15 @@ static struct clk_regmap *gcc_ipq4019_clocks[] = {
>  	[GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr,
>  	[GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr,
>  	[GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr,
> +	[GCC_APPS_DDRPLL_VCO] = &gcc_apps_ddrpll_vco.cdiv.clkr,
> +	[GCC_FEPLL_VCO] = &gcc_fepll_vco.cdiv.clkr,
> +	[GCC_SDCC_PLLDIV_CLK] = &gcc_apps_sdcc_clk.cdiv.clkr,
> +	[GCC_FEPLL125_CLK] = &gcc_fepll125_clk.cdiv.clkr,
> +	[GCC_FEPLL125DLY_CLK] = &gcc_fepll125dly_clk.cdiv.clkr,
> +	[GCC_FEPLL200_CLK] = &gcc_fepll200_clk.cdiv.clkr,
> +	[GCC_FEPLL500_CLK] = &gcc_fepll500_clk.cdiv.clkr,
> +	[GCC_FEPLL_WCSS2G_CLK] = &gcc_fepllwcss2g_clk.cdiv.clkr,
> +	[GCC_FEPLL_WCSS5G_CLK] = &gcc_fepllwcss5g_clk.cdiv.clkr,
>  };
>  
>  static const struct qcom_reset_map gcc_ipq4019_resets[] = {
> @@ -1295,7 +1565,7 @@ static const struct regmap_config gcc_ipq4019_regmap_config = {
>  	.reg_bits	= 32,
>  	.reg_stride	= 4,
>  	.val_bits	= 32,
> -	.max_register	= 0x2dfff,
> +	.max_register	= 0x2FFFF,

Lowercase.

>  	.fast_io	= true,
>  };

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

  reply	other threads:[~2016-08-15 22:19 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-21 13:49 [PATCH v2 0/5] Patches for QCOM IPQ4019 clock driver Abhishek Sahu
     [not found] ` <1466516962-18087-1-git-send-email-absahu-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-06-21 13:49   ` [PATCH v2 1/5] clk: qcom: ipq4019: Added the clock nodes and operations for pll Abhishek Sahu
2016-06-21 13:49     ` Abhishek Sahu
2016-08-15 22:19     ` Stephen Boyd [this message]
2016-06-21 13:49 ` [PATCH v2 2/5] clk: qcom: ipq4019: Added the apss cpu pll divider clock node Abhishek Sahu
     [not found]   ` <1466516962-18087-3-git-send-email-absahu-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-08-15 22:31     ` Stephen Boyd
2016-08-15 22:31       ` Stephen Boyd
2016-06-21 13:49 ` [PATCH v2 3/5] clk: qcom: ipq4019: Added the nodes for pcnoc Abhishek Sahu
2016-08-15 22:27   ` Stephen Boyd
2016-06-21 13:49 ` [PATCH v2 4/5] clk: qcom: ipq4019: Added the all frequencies for apps cpu Abhishek Sahu
2016-08-15 22:24   ` Stephen Boyd
2016-06-21 13:49 ` [PATCH v2 5/5] clk: qcom: ipq4019: Added the cpu clock frequency change notifier Abhishek Sahu
     [not found]   ` <1466516962-18087-6-git-send-email-absahu-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-08-15 22:26     ` Stephen Boyd
2016-08-15 22:26       ` Stephen Boyd

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=20160815221956.GJ361@codeaurora.org \
    --to=sboyd@codeaurora.org \
    --cc=absahu@codeaurora.org \
    --cc=andy.gross@linaro.org \
    --cc=architt@codeaurora.org \
    --cc=david.brown@linaro.org \
    --cc=devicetree@vger.kernel.org \
    --cc=galak@codeaurora.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-soc@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mmcclint@codeaurora.org \
    --cc=mturquette@baylibre.com \
    --cc=ntelkar@codeaurora.org \
    --cc=pawel.moll@arm.com \
    --cc=pradeepb@codeaurora.org \
    --cc=robh+dt@kernel.org \
    --cc=sricharan@codeaurora.org \
    --cc=varada@codeaurora.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.