All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Heiko Stübner" <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
To: linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	James Liao <jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Cc: Matthias Brugger
	<matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Mike Turquette
	<mturquette-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Ricky Liang <jcliang-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>,
	Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Sascha Hauer <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH] clk: mediatek: Add MT8173 MMPLL change rate support
Date: Tue, 07 Jul 2015 10:58:45 +0200	[thread overview]
Message-ID: <57452978.oOaMP89yJM@diego> (raw)
In-Reply-To: <1433222760-5924-1-git-send-email-jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

Hi James,

Am Dienstag, 2. Juni 2015, 13:26:00 schrieb James Liao:
> MT8173 MMPLL frequency settings are different from common PLLs.
> It needs different post divider settings for some ranges of frequency.
> This patch add support for MT8173 MMPLL frequency setting, includes:
> 
> 1. Add div-rate table for PLLs.
> 2. Increase the max ost divider setting from 3 (/8) to 4 (/16).
> 3. Write postdiv and pcw settings at the same time.
> 
> Signed-off-by: James Liao <jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/clk/mediatek/clk-mt8173.c | 24 +++++++++++++++++++++---
>  drivers/clk/mediatek/clk-mtk.h    |  1 +
>  drivers/clk/mediatek/clk-pll.c    | 37
> +++++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 15
> deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8173.c
> b/drivers/clk/mediatek/clk-mt8173.c index 357b080..821de7d 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -779,8 +779,9 @@ CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg",
> mtk_pericfg_init);
> 
>  #define CON0_MT8173_RST_BAR	BIT(24)
> 
> -#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,
> _pd_reg, _pd_shift, \ -			_tuner_reg, _pcw_reg, _pcw_shift) { \
> +#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
> +			_pcw_shift, _div_rate) {			\
>  		.id = _id,						\
>  		.name = _name,						\
>  		.reg = _reg,						\
> @@ -795,14 +796,31 @@ CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg",
> mtk_pericfg_init); .tuner_reg = _tuner_reg,				\
>  		.pcw_reg = _pcw_reg,					\
>  		.pcw_shift = _pcw_shift,				\
> +		.div_rate = _div_rate,					\
>  	}
> 
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
> +			_pcw_shift)					\
> +		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
> +			NULL)
> +
> +const unsigned long mmpll_div_rate[] = {

static?

> +	MT8173_PLL_FMAX,
> +	1000000000,
> +	702000000,
> +	253500000,
> +	126750000,
> +	0,

it's more common to label sentinel entries (the 0 marking the end) with
	/* sentinel */
instead of value 0.


If I'm reading the code correctly, this is a mapping divider -> frequency, 
right? So it may be nice to make this a bit more explicit, like:

struct mtk_pll_div_table {
	unsigned int    freq;
	unsigned int    div;
};

static const struct mtk_pll_div_table mmpll_div_rate[] = {
	{ .freq = MT8173_PLL_FMAX, .div = 0 },
	{ .freq = 1000000000, .div = 1 },
	{ .freq = 702000000, .div = 2 },
	{ .freq = 253500000, .div = 3 },
	{ .freq = 126750000, .div = 4 },
	{ /* sentinel */ },
};


> +};
> +
>  static const struct mtk_pll_data plls[] = {
>  	PLL(CLK_APMIXED_ARMCA15PLL, "armca15pll", 0x200, 0x20c, 0x00000001, 0, 
21,
> 0x204, 24, 0x0, 0x204, 0), PLL(CLK_APMIXED_ARMCA7PLL, "armca7pll", 0x210,
> 0x21c, 0x00000001, 0, 21, 0x214, 24, 0x0, 0x214, 0),
> PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000101, HAVE_RST_BAR,
> 21, 0x220, 4, 0x0, 0x224, 0), PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x230,
> 0x23c, 0xfe000001, HAVE_RST_BAR, 7, 0x230, 4, 0x0, 0x234, 14),
> -	PLL(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244,
> 24, 0x0, 0x244, 0), +	PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c,
> 0x00000001, 0, 21, 0x244, 24, 0x0, 0x244, 0, mmpll_div_rate),
> PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0x00000001, 0, 21, 0x250,
> 4, 0x0, 0x254, 0), PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x260, 0x26c,
> 0x00000001, 0, 21, 0x260, 4, 0x0, 0x264, 0), PLL(CLK_APMIXED_TVDPLL,
> "tvdpll", 0x270, 0x27c, 0x00000001, 0, 21, 0x270, 4, 0x0, 0x274, 0), diff
> --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 61035b9..645af7c 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -150,6 +150,7 @@ struct mtk_pll_data {
>  	int pcwbits;
>  	uint32_t pcw_reg;
>  	int pcw_shift;
> +	const unsigned long *div_rate;
>  };
> 
>  void __init mtk_clk_register_plls(struct device_node *node,
> diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
> index 44409e9..4680a09 100644
> --- a/drivers/clk/mediatek/clk-pll.c
> +++ b/drivers/clk/mediatek/clk-pll.c
> @@ -90,20 +90,23 @@ static unsigned long __mtk_pll_recalc_rate(struct
> mtk_clk_pll *pll, u32 fin, static void mtk_pll_set_rate_regs(struct
> mtk_clk_pll *pll, u32 pcw, int postdiv)
>  {

-------------

> -	u32 con1, pd, val;
> +	u32 con1, val;
>  	int pll_en;
> 
> -	/* set postdiv */
> -	pd = readl(pll->pd_addr);
> -	pd &= ~(POSTDIV_MASK << pll->data->pd_shift);
> -	pd |= (ffs(postdiv) - 1) << pll->data->pd_shift;
> -	writel(pd, pll->pd_addr);
> -
>  	pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN;
> 
> -	/* set pcw */
> -	val = readl(pll->pcw_addr);
> +	/* set postdiv */
> +	val = readl(pll->pd_addr);
> +	val &= ~(POSTDIV_MASK << pll->data->pd_shift);
> +	val |= (ffs(postdiv) - 1) << pll->data->pd_shift;
> +
> +	/* postdiv and pcw need to set at the same time if on same register */
> +	if (pll->pd_addr != pll->pcw_addr) {
> +		writel(val, pll->pd_addr);
> +		val = readl(pll->pcw_addr);
> +	}
> 
> +	/* set pcw */
>  	val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
>  			pll->data->pcw_shift);
>  	val |= pcw << pll->data->pcw_shift;

This whole block probably wants to be a separate patch ;-) .

While it may not affect previous pll implementations, it changes how register 
accesses are handled and should not hide in another patch.



> @@ -135,16 +138,26 @@ static void mtk_pll_calc_values(struct mtk_clk_pll
> *pll, u32 *pcw, u32 *postdiv, u32 freq, u32 fin)
>  {
>  	unsigned long fmin = 1000 * MHZ;
> +	const unsigned long *div_rate = pll->data->div_rate;
>  	u64 _pcw;
>  	u32 val;
> 
>  	if (freq > pll->data->fmax)
>  		freq = pll->data->fmax;
> 
> -	for (val = 0; val < 4; val++) {
> +	if (div_rate) {
> +		for (val = 1; div_rate[val] != 0; val++) {
> +			if (freq > div_rate[val])
> +				break;
> +		}
> +		val--;

if you're changing the table struct, this of course also would need to be 
adapted.


Hmm, what I don't understand is, what does MT8173_PLL_FMAX in the table, if 
you ignore it here all the time?

So the table should probably look more like [when using the concept from 
above]

static const struct mtk_pll_div_table mmpll_div_rate[] = {
	{ .freq = 1000000000, .div = 0 },
	{ .freq = 702000000, .div = 1 },
	{ .freq = 253500000, .div = 2 },
	{ .freq = 126750000, .div = 3 },
	{ /* sentinel */ },
};


>  		*postdiv = 1 << val;
> -		if (freq * *postdiv >= fmin)
> -			break;
> +	} else {
> +		for (val = 0; val < 5; val++) {
> +			*postdiv = 1 << val;
> +			if ((u64)freq * *postdiv >= fmin)
> +				break;
> +		}
>  	}
> 
>  	/* _pcw = freq * postdiv / fin * 2^pcwfbits */


Heiko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] clk: mediatek: Add MT8173 MMPLL change rate support
Date: Tue, 07 Jul 2015 10:58:45 +0200	[thread overview]
Message-ID: <57452978.oOaMP89yJM@diego> (raw)
In-Reply-To: <1433222760-5924-1-git-send-email-jamesjj.liao@mediatek.com>

Hi James,

Am Dienstag, 2. Juni 2015, 13:26:00 schrieb James Liao:
> MT8173 MMPLL frequency settings are different from common PLLs.
> It needs different post divider settings for some ranges of frequency.
> This patch add support for MT8173 MMPLL frequency setting, includes:
> 
> 1. Add div-rate table for PLLs.
> 2. Increase the max ost divider setting from 3 (/8) to 4 (/16).
> 3. Write postdiv and pcw settings at the same time.
> 
> Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mt8173.c | 24 +++++++++++++++++++++---
>  drivers/clk/mediatek/clk-mtk.h    |  1 +
>  drivers/clk/mediatek/clk-pll.c    | 37
> +++++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 15
> deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8173.c
> b/drivers/clk/mediatek/clk-mt8173.c index 357b080..821de7d 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -779,8 +779,9 @@ CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg",
> mtk_pericfg_init);
> 
>  #define CON0_MT8173_RST_BAR	BIT(24)
> 
> -#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,
> _pd_reg, _pd_shift, \ -			_tuner_reg, _pcw_reg, _pcw_shift) { \
> +#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
> +			_pcw_shift, _div_rate) {			\
>  		.id = _id,						\
>  		.name = _name,						\
>  		.reg = _reg,						\
> @@ -795,14 +796,31 @@ CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg",
> mtk_pericfg_init); .tuner_reg = _tuner_reg,				\
>  		.pcw_reg = _pcw_reg,					\
>  		.pcw_shift = _pcw_shift,				\
> +		.div_rate = _div_rate,					\
>  	}
> 
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
> +			_pcw_shift)					\
> +		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
> +			NULL)
> +
> +const unsigned long mmpll_div_rate[] = {

static?

> +	MT8173_PLL_FMAX,
> +	1000000000,
> +	702000000,
> +	253500000,
> +	126750000,
> +	0,

it's more common to label sentinel entries (the 0 marking the end) with
	/* sentinel */
instead of value 0.


If I'm reading the code correctly, this is a mapping divider -> frequency, 
right? So it may be nice to make this a bit more explicit, like:

struct mtk_pll_div_table {
	unsigned int    freq;
	unsigned int    div;
};

static const struct mtk_pll_div_table mmpll_div_rate[] = {
	{ .freq = MT8173_PLL_FMAX, .div = 0 },
	{ .freq = 1000000000, .div = 1 },
	{ .freq = 702000000, .div = 2 },
	{ .freq = 253500000, .div = 3 },
	{ .freq = 126750000, .div = 4 },
	{ /* sentinel */ },
};


> +};
> +
>  static const struct mtk_pll_data plls[] = {
>  	PLL(CLK_APMIXED_ARMCA15PLL, "armca15pll", 0x200, 0x20c, 0x00000001, 0, 
21,
> 0x204, 24, 0x0, 0x204, 0), PLL(CLK_APMIXED_ARMCA7PLL, "armca7pll", 0x210,
> 0x21c, 0x00000001, 0, 21, 0x214, 24, 0x0, 0x214, 0),
> PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000101, HAVE_RST_BAR,
> 21, 0x220, 4, 0x0, 0x224, 0), PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x230,
> 0x23c, 0xfe000001, HAVE_RST_BAR, 7, 0x230, 4, 0x0, 0x234, 14),
> -	PLL(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244,
> 24, 0x0, 0x244, 0), +	PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c,
> 0x00000001, 0, 21, 0x244, 24, 0x0, 0x244, 0, mmpll_div_rate),
> PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0x00000001, 0, 21, 0x250,
> 4, 0x0, 0x254, 0), PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x260, 0x26c,
> 0x00000001, 0, 21, 0x260, 4, 0x0, 0x264, 0), PLL(CLK_APMIXED_TVDPLL,
> "tvdpll", 0x270, 0x27c, 0x00000001, 0, 21, 0x270, 4, 0x0, 0x274, 0), diff
> --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 61035b9..645af7c 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -150,6 +150,7 @@ struct mtk_pll_data {
>  	int pcwbits;
>  	uint32_t pcw_reg;
>  	int pcw_shift;
> +	const unsigned long *div_rate;
>  };
> 
>  void __init mtk_clk_register_plls(struct device_node *node,
> diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
> index 44409e9..4680a09 100644
> --- a/drivers/clk/mediatek/clk-pll.c
> +++ b/drivers/clk/mediatek/clk-pll.c
> @@ -90,20 +90,23 @@ static unsigned long __mtk_pll_recalc_rate(struct
> mtk_clk_pll *pll, u32 fin, static void mtk_pll_set_rate_regs(struct
> mtk_clk_pll *pll, u32 pcw, int postdiv)
>  {

-------------

> -	u32 con1, pd, val;
> +	u32 con1, val;
>  	int pll_en;
> 
> -	/* set postdiv */
> -	pd = readl(pll->pd_addr);
> -	pd &= ~(POSTDIV_MASK << pll->data->pd_shift);
> -	pd |= (ffs(postdiv) - 1) << pll->data->pd_shift;
> -	writel(pd, pll->pd_addr);
> -
>  	pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN;
> 
> -	/* set pcw */
> -	val = readl(pll->pcw_addr);
> +	/* set postdiv */
> +	val = readl(pll->pd_addr);
> +	val &= ~(POSTDIV_MASK << pll->data->pd_shift);
> +	val |= (ffs(postdiv) - 1) << pll->data->pd_shift;
> +
> +	/* postdiv and pcw need to set at the same time if on same register */
> +	if (pll->pd_addr != pll->pcw_addr) {
> +		writel(val, pll->pd_addr);
> +		val = readl(pll->pcw_addr);
> +	}
> 
> +	/* set pcw */
>  	val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
>  			pll->data->pcw_shift);
>  	val |= pcw << pll->data->pcw_shift;

This whole block probably wants to be a separate patch ;-) .

While it may not affect previous pll implementations, it changes how register 
accesses are handled and should not hide in another patch.



> @@ -135,16 +138,26 @@ static void mtk_pll_calc_values(struct mtk_clk_pll
> *pll, u32 *pcw, u32 *postdiv, u32 freq, u32 fin)
>  {
>  	unsigned long fmin = 1000 * MHZ;
> +	const unsigned long *div_rate = pll->data->div_rate;
>  	u64 _pcw;
>  	u32 val;
> 
>  	if (freq > pll->data->fmax)
>  		freq = pll->data->fmax;
> 
> -	for (val = 0; val < 4; val++) {
> +	if (div_rate) {
> +		for (val = 1; div_rate[val] != 0; val++) {
> +			if (freq > div_rate[val])
> +				break;
> +		}
> +		val--;

if you're changing the table struct, this of course also would need to be 
adapted.


Hmm, what I don't understand is, what does MT8173_PLL_FMAX in the table, if 
you ignore it here all the time?

So the table should probably look more like [when using the concept from 
above]

static const struct mtk_pll_div_table mmpll_div_rate[] = {
	{ .freq = 1000000000, .div = 0 },
	{ .freq = 702000000, .div = 1 },
	{ .freq = 253500000, .div = 2 },
	{ .freq = 126750000, .div = 3 },
	{ /* sentinel */ },
};


>  		*postdiv = 1 << val;
> -		if (freq * *postdiv >= fmin)
> -			break;
> +	} else {
> +		for (val = 0; val < 5; val++) {
> +			*postdiv = 1 << val;
> +			if ((u64)freq * *postdiv >= fmin)
> +				break;
> +		}
>  	}
> 
>  	/* _pcw = freq * postdiv / fin * 2^pcwfbits */


Heiko

WARNING: multiple messages have this Message-ID (diff)
From: "Heiko Stübner" <heiko@sntech.de>
To: linux-mediatek@lists.infradead.org,
	James Liao <jamesjj.liao@mediatek.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>,
	Mike Turquette <mturquette@linaro.org>,
	Stephen Boyd <sboyd@codeaurora.org>,
	devicetree@vger.kernel.org, srv_heupstream@mediatek.com,
	linux-kernel@vger.kernel.org, Ricky Liang <jcliang@chromium.org>,
	Rob Herring <robh+dt@kernel.org>,
	Sascha Hauer <kernel@pengutronix.de>,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] clk: mediatek: Add MT8173 MMPLL change rate support
Date: Tue, 07 Jul 2015 10:58:45 +0200	[thread overview]
Message-ID: <57452978.oOaMP89yJM@diego> (raw)
In-Reply-To: <1433222760-5924-1-git-send-email-jamesjj.liao@mediatek.com>

Hi James,

Am Dienstag, 2. Juni 2015, 13:26:00 schrieb James Liao:
> MT8173 MMPLL frequency settings are different from common PLLs.
> It needs different post divider settings for some ranges of frequency.
> This patch add support for MT8173 MMPLL frequency setting, includes:
> 
> 1. Add div-rate table for PLLs.
> 2. Increase the max ost divider setting from 3 (/8) to 4 (/16).
> 3. Write postdiv and pcw settings at the same time.
> 
> Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mt8173.c | 24 +++++++++++++++++++++---
>  drivers/clk/mediatek/clk-mtk.h    |  1 +
>  drivers/clk/mediatek/clk-pll.c    | 37
> +++++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 15
> deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8173.c
> b/drivers/clk/mediatek/clk-mt8173.c index 357b080..821de7d 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -779,8 +779,9 @@ CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg",
> mtk_pericfg_init);
> 
>  #define CON0_MT8173_RST_BAR	BIT(24)
> 
> -#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,
> _pd_reg, _pd_shift, \ -			_tuner_reg, _pcw_reg, _pcw_shift) { \
> +#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
> +			_pcw_shift, _div_rate) {			\
>  		.id = _id,						\
>  		.name = _name,						\
>  		.reg = _reg,						\
> @@ -795,14 +796,31 @@ CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg",
> mtk_pericfg_init); .tuner_reg = _tuner_reg,				\
>  		.pcw_reg = _pcw_reg,					\
>  		.pcw_shift = _pcw_shift,				\
> +		.div_rate = _div_rate,					\
>  	}
> 
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
> +			_pcw_shift)					\
> +		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
> +			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
> +			NULL)
> +
> +const unsigned long mmpll_div_rate[] = {

static?

> +	MT8173_PLL_FMAX,
> +	1000000000,
> +	702000000,
> +	253500000,
> +	126750000,
> +	0,

it's more common to label sentinel entries (the 0 marking the end) with
	/* sentinel */
instead of value 0.


If I'm reading the code correctly, this is a mapping divider -> frequency, 
right? So it may be nice to make this a bit more explicit, like:

struct mtk_pll_div_table {
	unsigned int    freq;
	unsigned int    div;
};

static const struct mtk_pll_div_table mmpll_div_rate[] = {
	{ .freq = MT8173_PLL_FMAX, .div = 0 },
	{ .freq = 1000000000, .div = 1 },
	{ .freq = 702000000, .div = 2 },
	{ .freq = 253500000, .div = 3 },
	{ .freq = 126750000, .div = 4 },
	{ /* sentinel */ },
};


> +};
> +
>  static const struct mtk_pll_data plls[] = {
>  	PLL(CLK_APMIXED_ARMCA15PLL, "armca15pll", 0x200, 0x20c, 0x00000001, 0, 
21,
> 0x204, 24, 0x0, 0x204, 0), PLL(CLK_APMIXED_ARMCA7PLL, "armca7pll", 0x210,
> 0x21c, 0x00000001, 0, 21, 0x214, 24, 0x0, 0x214, 0),
> PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000101, HAVE_RST_BAR,
> 21, 0x220, 4, 0x0, 0x224, 0), PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x230,
> 0x23c, 0xfe000001, HAVE_RST_BAR, 7, 0x230, 4, 0x0, 0x234, 14),
> -	PLL(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244,
> 24, 0x0, 0x244, 0), +	PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c,
> 0x00000001, 0, 21, 0x244, 24, 0x0, 0x244, 0, mmpll_div_rate),
> PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0x00000001, 0, 21, 0x250,
> 4, 0x0, 0x254, 0), PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x260, 0x26c,
> 0x00000001, 0, 21, 0x260, 4, 0x0, 0x264, 0), PLL(CLK_APMIXED_TVDPLL,
> "tvdpll", 0x270, 0x27c, 0x00000001, 0, 21, 0x270, 4, 0x0, 0x274, 0), diff
> --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 61035b9..645af7c 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -150,6 +150,7 @@ struct mtk_pll_data {
>  	int pcwbits;
>  	uint32_t pcw_reg;
>  	int pcw_shift;
> +	const unsigned long *div_rate;
>  };
> 
>  void __init mtk_clk_register_plls(struct device_node *node,
> diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
> index 44409e9..4680a09 100644
> --- a/drivers/clk/mediatek/clk-pll.c
> +++ b/drivers/clk/mediatek/clk-pll.c
> @@ -90,20 +90,23 @@ static unsigned long __mtk_pll_recalc_rate(struct
> mtk_clk_pll *pll, u32 fin, static void mtk_pll_set_rate_regs(struct
> mtk_clk_pll *pll, u32 pcw, int postdiv)
>  {

-------------

> -	u32 con1, pd, val;
> +	u32 con1, val;
>  	int pll_en;
> 
> -	/* set postdiv */
> -	pd = readl(pll->pd_addr);
> -	pd &= ~(POSTDIV_MASK << pll->data->pd_shift);
> -	pd |= (ffs(postdiv) - 1) << pll->data->pd_shift;
> -	writel(pd, pll->pd_addr);
> -
>  	pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN;
> 
> -	/* set pcw */
> -	val = readl(pll->pcw_addr);
> +	/* set postdiv */
> +	val = readl(pll->pd_addr);
> +	val &= ~(POSTDIV_MASK << pll->data->pd_shift);
> +	val |= (ffs(postdiv) - 1) << pll->data->pd_shift;
> +
> +	/* postdiv and pcw need to set at the same time if on same register */
> +	if (pll->pd_addr != pll->pcw_addr) {
> +		writel(val, pll->pd_addr);
> +		val = readl(pll->pcw_addr);
> +	}
> 
> +	/* set pcw */
>  	val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
>  			pll->data->pcw_shift);
>  	val |= pcw << pll->data->pcw_shift;

This whole block probably wants to be a separate patch ;-) .

While it may not affect previous pll implementations, it changes how register 
accesses are handled and should not hide in another patch.



> @@ -135,16 +138,26 @@ static void mtk_pll_calc_values(struct mtk_clk_pll
> *pll, u32 *pcw, u32 *postdiv, u32 freq, u32 fin)
>  {
>  	unsigned long fmin = 1000 * MHZ;
> +	const unsigned long *div_rate = pll->data->div_rate;
>  	u64 _pcw;
>  	u32 val;
> 
>  	if (freq > pll->data->fmax)
>  		freq = pll->data->fmax;
> 
> -	for (val = 0; val < 4; val++) {
> +	if (div_rate) {
> +		for (val = 1; div_rate[val] != 0; val++) {
> +			if (freq > div_rate[val])
> +				break;
> +		}
> +		val--;

if you're changing the table struct, this of course also would need to be 
adapted.


Hmm, what I don't understand is, what does MT8173_PLL_FMAX in the table, if 
you ignore it here all the time?

So the table should probably look more like [when using the concept from 
above]

static const struct mtk_pll_div_table mmpll_div_rate[] = {
	{ .freq = 1000000000, .div = 0 },
	{ .freq = 702000000, .div = 1 },
	{ .freq = 253500000, .div = 2 },
	{ .freq = 126750000, .div = 3 },
	{ /* sentinel */ },
};


>  		*postdiv = 1 << val;
> -		if (freq * *postdiv >= fmin)
> -			break;
> +	} else {
> +		for (val = 0; val < 5; val++) {
> +			*postdiv = 1 << val;
> +			if ((u64)freq * *postdiv >= fmin)
> +				break;
> +		}
>  	}
> 
>  	/* _pcw = freq * postdiv / fin * 2^pcwfbits */


Heiko

  parent reply	other threads:[~2015-07-07  8:58 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-02  5:26 [PATCH] clk: mediatek: Add MT8173 MMPLL change rate support James Liao
2015-06-02  5:26 ` James Liao
2015-06-02  5:26 ` James Liao
2015-07-07  7:17 ` James Liao
2015-07-07  7:17   ` James Liao
2015-07-07  7:17   ` James Liao
     [not found] ` <1433222760-5924-1-git-send-email-jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
2015-07-07  8:58   ` Heiko Stübner [this message]
2015-07-07  8:58     ` Heiko Stübner
2015-07-07  8:58     ` Heiko Stübner
2015-07-07  9:28     ` James Liao
2015-07-07  9:28       ` James Liao
2015-07-07  9:28       ` James Liao
2015-07-07  9:34       ` Heiko Stübner
2015-07-07  9:34         ` Heiko Stübner
2015-07-07  9:48         ` James Liao
2015-07-07  9:48           ` James Liao
2015-07-07  9:48           ` James Liao
2015-07-07 10:46           ` Heiko Stübner
2015-07-07 10:46             ` Heiko Stübner
2015-07-07 10:46             ` Heiko Stübner

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=57452978.oOaMP89yJM@diego \
    --to=heiko-4mtyjxux2i+zqb+pc5nmwq@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org \
    --cc=jcliang-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
    --cc=kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=mturquette-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=srv_heupstream-NuS5LvNUpcJWk0Htik3J/w@public.gmane.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.