All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Heiko Stübner" <heiko@sntech.de>
To: Stephen Boyd <sboyd@codeaurora.org>
Cc: Xing Zheng <zhengxing@rock-chips.com>,
	linux-rockchip@lists.infradead.org,
	Michael Turquette <mturquette@baylibre.com>,
	linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 4/9] clk: rockchip: add new clock type and controller for rk3036
Date: Thu, 01 Oct 2015 01:32:19 +0200	[thread overview]
Message-ID: <4123121.bNYOPIrL2s@diego> (raw)
In-Reply-To: <20150922231900.GL23081@codeaurora.org>

Hi Stephen,

Am Dienstag, 22. September 2015, 16:19:00 schrieb Stephen Boyd:
> On 09/23, Heiko St=FCbner wrote:
> > Am Dienstag, 22. September 2015, 15:41:25 schrieb Stephen Boyd:
> > > On 09/17, Xing Zheng wrote:
> > > > +
> > > > +static void rockchip_rk3036_pll_init(struct clk_hw *hw)
> > >=20
> > > init ops are "discouraged". Could we do this through assigned
> > > rates instead?
> >=20
> > really? According to Mike that was a valid use-case when we looked =
for an
> > initial place for that on the rk3288 :-) .
>=20
> A comment in clk.c indicates init ops are discouraged. Maybe this
> is a valid use-case on other platforms so it was allowed, but
> pretty much every time we see a new init op we have to think
> about it and justify it. Hooray!

for the rk3288-variant Mike said
"Looks good to me. I think rk3xxx might be the first user of the .init
callback!" [0]
so it looks like he was convinced of our reasoning at the time :-) .


[0] http://lists.infradead.org/pipermail/linux-rockchip/2014-November/0=
01570.html


> > > > +{
> > > > +=09struct rockchip_clk_pll *pll =3D to_rockchip_clk_pll(hw);
> > > > +=09const struct rockchip_pll_rate_table *rate;
> > > > +=09unsigned int fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac=
;
> > > > +=09unsigned long drate;
> > > > +=09u32 pllcon;
> > > > +
> > > > +=09if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
> > > > +=09=09return;
> > >=20
> > > I don't understand what this one does though. This check isn't in=

> > > the set rate ops.
> >=20
> > And it shouldn't be :-)
> >=20
> > The issue this whole thing is trying to solve is aligning the pll s=
ettings
> > which what we have in the rate table, not what the bootloader set.
> >=20
> > For example the bootloader could set up a pll at 594MHz with one se=
t of
> > parameters and after some time - when you don't want to exchange
> > bootloaders on shipping devices anymore - it comes to light that a
> > different set of parameters for the same frequency produces for exa=
mple a
> > more stable hdmi signal [I think that was the main reason for the i=
nitial
> > change].
> >=20
> > So we're not changing the frequency x -> y, which could be easily d=
one
> > [and is done already] via assigned-rates, but instead
> >=20
> > =09x {params a,b,c} -> x {params d,e,f}
> >=20
> > so the rate itself stays the same, only the frequency generation is=

> > adapted.
> Ok. It would be nice if this sort of information was made into a
> comment and put in the code. Or at least the commit text for the
> change.
>=20
> And is there any reason that we need to get the parent clock and
> parent rate to align the PLL settings?
> It would be nice if we
> avoided using clk_* APIs in here, by extracting the pll set rate
> code into another function that we can call from init to make the
> values the same without all the fallback to old rates, etc.

I guess you want Xing Zheng to change his pll code somewhat like the
following, right? While starting off as proof-of-concept, that change
below actually does work quite nicely on rk3288 boards.

---------------- 8< --------------------
From: Heiko Stuebner <heiko@sntech.de>
Subject: [PATCH] clk: rockchip: don't use clk_ APIs in the pll init-cal=
lback

Separate the update of pll registers from the actual set_rate function
so that the init callback does not need to access clk-API functions.

As we now have separated the getting and setting of the pll parameters
we can also directly use these new functions in other places too.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/rockchip/clk-pll.c | 135 ++++++++++++++++++++++-----------=
--------
 1 file changed, 74 insertions(+), 61 deletions(-)

diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-=
pll.c
index 7737a1d..4881eb8 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -126,11 +126,32 @@ static int rockchip_pll_wait_lock(struct rockchip=
_clk_pll *pll)
 #define RK3066_PLLCON3_PWRDOWN=09=09(1 << 1)
 #define RK3066_PLLCON3_BYPASS=09=09(1 << 0)
=20
+static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pl=
l,
+=09=09=09=09=09struct rockchip_pll_rate_table *rate)
+{
+=09u32 pllcon;
+
+=09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
+=09rate->nr =3D ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
+=09=09=09=09& RK3066_PLLCON0_NR_MASK) + 1;
+=09rate->no =3D ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
+=09=09=09=09& RK3066_PLLCON0_OD_MASK) + 1;
+
+=09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
+=09rate->nf =3D ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
+=09=09=09=09& RK3066_PLLCON1_NF_MASK) + 1;
+
+=09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
+=09rate->nb =3D ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
+=09=09=09=09& RK3066_PLLCON2_NB_MASK) + 1;
+}
+
 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw=
,
 =09=09=09=09=09=09     unsigned long prate)
 {
 =09struct rockchip_clk_pll *pll =3D to_rockchip_clk_pll(hw);
-=09u64 nf, nr, no, rate64 =3D prate;
+=09struct rockchip_pll_rate_table cur;
+=09u64 rate64 =3D prate;
 =09u32 pllcon;
=20
 =09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
@@ -140,53 +161,31 @@ static unsigned long rockchip_rk3066_pll_recalc_r=
ate(struct clk_hw *hw,
 =09=09return prate;
 =09}
=20
-=09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
-=09nf =3D (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK=
;
-
-=09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
-=09nr =3D (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK=
;
-=09no =3D (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK=
;
+=09rockchip_rk3066_pll_get_params(pll, &cur);
=20
-=09rate64 *=3D (nf + 1);
-=09do_div(rate64, nr + 1);
-=09do_div(rate64, no + 1);
+=09rate64 *=3D cur.nf;
+=09do_div(rate64, cur.nr);
+=09do_div(rate64, cur.no);
=20
 =09return (unsigned long)rate64;
 }
=20
-static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned lo=
ng drate,
-=09=09=09=09=09unsigned long prate)
+static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll=
,
+=09=09=09=09const struct rockchip_pll_rate_table *rate)
 {
-=09struct rockchip_clk_pll *pll =3D to_rockchip_clk_pll(hw);
-=09const struct rockchip_pll_rate_table *rate;
-=09unsigned long old_rate =3D rockchip_rk3066_pll_recalc_rate(hw, prat=
e);
-=09struct regmap *grf =3D rockchip_clk_get_grf();
-=09struct clk_mux *pll_mux =3D &pll->pll_mux;
 =09const struct clk_ops *pll_mux_ops =3D pll->pll_mux_ops;
+=09struct clk_mux *pll_mux =3D &pll->pll_mux;
+=09struct rockchip_pll_rate_table cur;
 =09int rate_change_remuxed =3D 0;
 =09int cur_parent;
 =09int ret;
=20
-=09if (IS_ERR(grf)) {
-=09=09pr_debug("%s: grf regmap not available, aborting rate change\n",=

-=09=09=09 __func__);
-=09=09return PTR_ERR(grf);
-=09}
-
-=09pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu=
\n",
-=09=09 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
-
-=09/* Get required rate settings from table */
-=09rate =3D rockchip_get_pll_settings(pll, drate);
-=09if (!rate) {
-=09=09pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-=09=09=09drate, clk_hw_get_name(hw));
-=09=09return -EINVAL;
-=09}
-
 =09pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
 =09=09 __func__, rate->rate, rate->nr, rate->no, rate->nf);
=20
+=09rockchip_rk3066_pll_get_params(pll, &cur);
+=09cur.rate =3D 0;
+
 =09cur_parent =3D pll_mux_ops->get_parent(&pll_mux->hw);
 =09if (cur_parent =3D=3D PLL_MODE_NORM) {
 =09=09pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
@@ -219,9 +218,9 @@ static int rockchip_rk3066_pll_set_rate(struct clk_=
hw *hw, unsigned long drate,
 =09/* wait for the pll to lock */
 =09ret =3D rockchip_pll_wait_lock(pll);
 =09if (ret) {
-=09=09pr_warn("%s: pll did not lock, trying to restore old rate %lu\n"=
,
-=09=09=09__func__, old_rate);
-=09=09rockchip_rk3066_pll_set_rate(hw, old_rate, prate);
+=09=09pr_warn("%s: pll update unsucessful, trying to restore old param=
s\n",
+=09=09=09__func__);
+=09=09rockchip_rk3066_pll_set_params(pll, &cur);
 =09}
=20
 =09if (rate_change_remuxed)
@@ -230,6 +229,34 @@ static int rockchip_rk3066_pll_set_rate(struct clk=
_hw *hw, unsigned long drate,
 =09return ret;
 }
=20
+static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned lo=
ng drate,
+=09=09=09=09=09unsigned long prate)
+{
+=09struct rockchip_clk_pll *pll =3D to_rockchip_clk_pll(hw);
+=09const struct rockchip_pll_rate_table *rate;
+=09unsigned long old_rate =3D rockchip_rk3066_pll_recalc_rate(hw, prat=
e);
+=09struct regmap *grf =3D rockchip_clk_get_grf();
+
+=09if (IS_ERR(grf)) {
+=09=09pr_debug("%s: grf regmap not available, aborting rate change\n",=

+=09=09=09 __func__);
+=09=09return PTR_ERR(grf);
+=09}
+
+=09pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu=
\n",
+=09=09 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
+
+=09/* Get required rate settings from table */
+=09rate =3D rockchip_get_pll_settings(pll, drate);
+=09if (!rate) {
+=09=09pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+=09=09=09drate, clk_hw_get_name(hw));
+=09=09return -EINVAL;
+=09}
+
+=09return rockchip_rk3066_pll_set_params(pll, rate);
+}
+
 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
 {
 =09struct rockchip_clk_pll *pll =3D to_rockchip_clk_pll(hw);
@@ -261,9 +288,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw =
*hw)
 {
 =09struct rockchip_clk_pll *pll =3D to_rockchip_clk_pll(hw);
 =09const struct rockchip_pll_rate_table *rate;
-=09unsigned int nf, nr, no, nb;
+=09struct rockchip_pll_rate_table cur;
 =09unsigned long drate;
-=09u32 pllcon;
=20
 =09if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
 =09=09return;
@@ -275,34 +301,21 @@ static void rockchip_rk3066_pll_init(struct clk_h=
w *hw)
 =09if (!rate)
 =09=09return;
=20
-=09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
-=09nr =3D ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MAS=
K) + 1;
-=09no =3D ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MAS=
K) + 1;
-
-=09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
-=09nf =3D ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MAS=
K) + 1;
-
-=09pllcon =3D readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
-=09nb =3D ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MAS=
K) + 1;
+=09rockchip_rk3066_pll_get_params(pll, &cur);
=20
 =09pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:=
%d)\n",
-=09=09 __func__, clk_hw_get_name(hw), drate, rate->nr, nr,
-=09=09rate->no, no, rate->nf, nf, rate->nb, nb);
-=09if (rate->nr !=3D nr || rate->no !=3D no || rate->nf !=3D nf
-=09=09=09=09=09     || rate->nb !=3D nb) {
-=09=09struct clk_hw *parent =3D clk_hw_get_parent(hw);
-=09=09unsigned long prate;
-
-=09=09if (!parent) {
-=09=09=09pr_warn("%s: parent of %s not available\n",
-=09=09=09=09__func__, clk_hw_get_name(hw));
+=09=09 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
+=09=09 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
+=09if (rate->nr !=3D cur.nr || rate->no !=3D cur.no || rate->nf !=3D c=
ur.nf
+=09=09=09=09=09=09     || rate->nb !=3D cur.nb) {
+=09=09struct regmap *grf =3D rockchip_clk_get_grf();
+
+=09=09if (IS_ERR(grf))
 =09=09=09return;
-=09=09}
=20
 =09=09pr_debug("%s: pll %s: rate params do not match rate table, adjus=
ting\n",
 =09=09=09 __func__, clk_hw_get_name(hw));
-=09=09prate =3D clk_hw_get_rate(parent);
-=09=09rockchip_rk3066_pll_set_rate(hw, drate, prate);
+=09=09rockchip_rk3066_pll_set_params(pll, rate);
 =09}
 }
=20
--=20
2.5.3
---------------- 8< --------------------

Heiko

WARNING: multiple messages have this Message-ID (diff)
From: "Heiko Stübner" <heiko@sntech.de>
To: Stephen Boyd <sboyd@codeaurora.org>
Cc: Xing Zheng <zhengxing@rock-chips.com>,
	linux-rockchip@lists.infradead.org,
	Michael Turquette <mturquette@baylibre.com>,
	linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 4/9] clk: rockchip: add new clock type and controller for rk3036
Date: Thu, 01 Oct 2015 01:32:19 +0200	[thread overview]
Message-ID: <4123121.bNYOPIrL2s@diego> (raw)
In-Reply-To: <20150922231900.GL23081@codeaurora.org>

Hi Stephen,

Am Dienstag, 22. September 2015, 16:19:00 schrieb Stephen Boyd:
> On 09/23, Heiko Stübner wrote:
> > Am Dienstag, 22. September 2015, 15:41:25 schrieb Stephen Boyd:
> > > On 09/17, Xing Zheng wrote:
> > > > +
> > > > +static void rockchip_rk3036_pll_init(struct clk_hw *hw)
> > > 
> > > init ops are "discouraged". Could we do this through assigned
> > > rates instead?
> > 
> > really? According to Mike that was a valid use-case when we looked for an
> > initial place for that on the rk3288 :-) .
> 
> A comment in clk.c indicates init ops are discouraged. Maybe this
> is a valid use-case on other platforms so it was allowed, but
> pretty much every time we see a new init op we have to think
> about it and justify it. Hooray!

for the rk3288-variant Mike said
"Looks good to me. I think rk3xxx might be the first user of the .init
callback!" [0]
so it looks like he was convinced of our reasoning at the time :-) .


[0] http://lists.infradead.org/pipermail/linux-rockchip/2014-November/001570.html


> > > > +{
> > > > +	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
> > > > +	const struct rockchip_pll_rate_table *rate;
> > > > +	unsigned int fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac;
> > > > +	unsigned long drate;
> > > > +	u32 pllcon;
> > > > +
> > > > +	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
> > > > +		return;
> > > 
> > > I don't understand what this one does though. This check isn't in
> > > the set rate ops.
> > 
> > And it shouldn't be :-)
> > 
> > The issue this whole thing is trying to solve is aligning the pll settings
> > which what we have in the rate table, not what the bootloader set.
> > 
> > For example the bootloader could set up a pll at 594MHz with one set of
> > parameters and after some time - when you don't want to exchange
> > bootloaders on shipping devices anymore - it comes to light that a
> > different set of parameters for the same frequency produces for example a
> > more stable hdmi signal [I think that was the main reason for the initial
> > change].
> > 
> > So we're not changing the frequency x -> y, which could be easily done
> > [and is done already] via assigned-rates, but instead
> > 
> > 	x {params a,b,c} -> x {params d,e,f}
> > 
> > so the rate itself stays the same, only the frequency generation is
> > adapted.
> Ok. It would be nice if this sort of information was made into a
> comment and put in the code. Or at least the commit text for the
> change.
> 
> And is there any reason that we need to get the parent clock and
> parent rate to align the PLL settings?
> It would be nice if we
> avoided using clk_* APIs in here, by extracting the pll set rate
> code into another function that we can call from init to make the
> values the same without all the fallback to old rates, etc.

I guess you want Xing Zheng to change his pll code somewhat like the
following, right? While starting off as proof-of-concept, that change
below actually does work quite nicely on rk3288 boards.

---------------- 8< --------------------
From: Heiko Stuebner <heiko@sntech.de>
Subject: [PATCH] clk: rockchip: don't use clk_ APIs in the pll init-callback

Separate the update of pll registers from the actual set_rate function
so that the init callback does not need to access clk-API functions.

As we now have separated the getting and setting of the pll parameters
we can also directly use these new functions in other places too.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/rockchip/clk-pll.c | 135 ++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 61 deletions(-)

diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 7737a1d..4881eb8 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -126,11 +126,32 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 #define RK3066_PLLCON3_PWRDOWN		(1 << 1)
 #define RK3066_PLLCON3_BYPASS		(1 << 0)
 
+static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
+					struct rockchip_pll_rate_table *rate)
+{
+	u32 pllcon;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
+	rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
+				& RK3066_PLLCON0_NR_MASK) + 1;
+	rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
+				& RK3066_PLLCON0_OD_MASK) + 1;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
+	rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
+				& RK3066_PLLCON1_NF_MASK) + 1;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
+	rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
+				& RK3066_PLLCON2_NB_MASK) + 1;
+}
+
 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
 						     unsigned long prate)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
-	u64 nf, nr, no, rate64 = prate;
+	struct rockchip_pll_rate_table cur;
+	u64 rate64 = prate;
 	u32 pllcon;
 
 	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
@@ -140,53 +161,31 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
 		return prate;
 	}
 
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
-	nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK;
-
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
-	nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK;
-	no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK;
+	rockchip_rk3066_pll_get_params(pll, &cur);
 
-	rate64 *= (nf + 1);
-	do_div(rate64, nr + 1);
-	do_div(rate64, no + 1);
+	rate64 *= cur.nf;
+	do_div(rate64, cur.nr);
+	do_div(rate64, cur.no);
 
 	return (unsigned long)rate64;
 }
 
-static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
-					unsigned long prate)
+static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
+				const struct rockchip_pll_rate_table *rate)
 {
-	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
-	const struct rockchip_pll_rate_table *rate;
-	unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
-	struct regmap *grf = rockchip_clk_get_grf();
-	struct clk_mux *pll_mux = &pll->pll_mux;
 	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+	struct clk_mux *pll_mux = &pll->pll_mux;
+	struct rockchip_pll_rate_table cur;
 	int rate_change_remuxed = 0;
 	int cur_parent;
 	int ret;
 
-	if (IS_ERR(grf)) {
-		pr_debug("%s: grf regmap not available, aborting rate change\n",
-			 __func__);
-		return PTR_ERR(grf);
-	}
-
-	pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
-		 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
-
-	/* Get required rate settings from table */
-	rate = rockchip_get_pll_settings(pll, drate);
-	if (!rate) {
-		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, clk_hw_get_name(hw));
-		return -EINVAL;
-	}
-
 	pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
 		 __func__, rate->rate, rate->nr, rate->no, rate->nf);
 
+	rockchip_rk3066_pll_get_params(pll, &cur);
+	cur.rate = 0;
+
 	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
 	if (cur_parent == PLL_MODE_NORM) {
 		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
@@ -219,9 +218,9 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 	/* wait for the pll to lock */
 	ret = rockchip_pll_wait_lock(pll);
 	if (ret) {
-		pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
-			__func__, old_rate);
-		rockchip_rk3066_pll_set_rate(hw, old_rate, prate);
+		pr_warn("%s: pll update unsucessful, trying to restore old params\n",
+			__func__);
+		rockchip_rk3066_pll_set_params(pll, &cur);
 	}
 
 	if (rate_change_remuxed)
@@ -230,6 +229,34 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 	return ret;
 }
 
+static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+	unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
+	struct regmap *grf = rockchip_clk_get_grf();
+
+	if (IS_ERR(grf)) {
+		pr_debug("%s: grf regmap not available, aborting rate change\n",
+			 __func__);
+		return PTR_ERR(grf);
+	}
+
+	pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
+		 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
+
+	/* Get required rate settings from table */
+	rate = rockchip_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, clk_hw_get_name(hw));
+		return -EINVAL;
+	}
+
+	return rockchip_rk3066_pll_set_params(pll, rate);
+}
+
 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
@@ -261,9 +288,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 	const struct rockchip_pll_rate_table *rate;
-	unsigned int nf, nr, no, nb;
+	struct rockchip_pll_rate_table cur;
 	unsigned long drate;
-	u32 pllcon;
 
 	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
 		return;
@@ -275,34 +301,21 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
 	if (!rate)
 		return;
 
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
-	nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
-	no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
-
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
-	nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
-
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
-	nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1;
+	rockchip_rk3066_pll_get_params(pll, &cur);
 
 	pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
-		 __func__, clk_hw_get_name(hw), drate, rate->nr, nr,
-		rate->no, no, rate->nf, nf, rate->nb, nb);
-	if (rate->nr != nr || rate->no != no || rate->nf != nf
-					     || rate->nb != nb) {
-		struct clk_hw *parent = clk_hw_get_parent(hw);
-		unsigned long prate;
-
-		if (!parent) {
-			pr_warn("%s: parent of %s not available\n",
-				__func__, clk_hw_get_name(hw));
+		 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
+		 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
+	if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
+						     || rate->nb != cur.nb) {
+		struct regmap *grf = rockchip_clk_get_grf();
+
+		if (IS_ERR(grf))
 			return;
-		}
 
 		pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
 			 __func__, clk_hw_get_name(hw));
-		prate = clk_hw_get_rate(parent);
-		rockchip_rk3066_pll_set_rate(hw, drate, prate);
+		rockchip_rk3066_pll_set_params(pll, rate);
 	}
 }
 
-- 
2.5.3
---------------- 8< --------------------

Heiko

WARNING: multiple messages have this Message-ID (diff)
From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 4/9] clk: rockchip: add new clock type and controller for rk3036
Date: Thu, 01 Oct 2015 01:32:19 +0200	[thread overview]
Message-ID: <4123121.bNYOPIrL2s@diego> (raw)
In-Reply-To: <20150922231900.GL23081@codeaurora.org>

Hi Stephen,

Am Dienstag, 22. September 2015, 16:19:00 schrieb Stephen Boyd:
> On 09/23, Heiko St?bner wrote:
> > Am Dienstag, 22. September 2015, 15:41:25 schrieb Stephen Boyd:
> > > On 09/17, Xing Zheng wrote:
> > > > +
> > > > +static void rockchip_rk3036_pll_init(struct clk_hw *hw)
> > > 
> > > init ops are "discouraged". Could we do this through assigned
> > > rates instead?
> > 
> > really? According to Mike that was a valid use-case when we looked for an
> > initial place for that on the rk3288 :-) .
> 
> A comment in clk.c indicates init ops are discouraged. Maybe this
> is a valid use-case on other platforms so it was allowed, but
> pretty much every time we see a new init op we have to think
> about it and justify it. Hooray!

for the rk3288-variant Mike said
"Looks good to me. I think rk3xxx might be the first user of the .init
callback!" [0]
so it looks like he was convinced of our reasoning at the time :-) .


[0] http://lists.infradead.org/pipermail/linux-rockchip/2014-November/001570.html


> > > > +{
> > > > +	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
> > > > +	const struct rockchip_pll_rate_table *rate;
> > > > +	unsigned int fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac;
> > > > +	unsigned long drate;
> > > > +	u32 pllcon;
> > > > +
> > > > +	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
> > > > +		return;
> > > 
> > > I don't understand what this one does though. This check isn't in
> > > the set rate ops.
> > 
> > And it shouldn't be :-)
> > 
> > The issue this whole thing is trying to solve is aligning the pll settings
> > which what we have in the rate table, not what the bootloader set.
> > 
> > For example the bootloader could set up a pll at 594MHz with one set of
> > parameters and after some time - when you don't want to exchange
> > bootloaders on shipping devices anymore - it comes to light that a
> > different set of parameters for the same frequency produces for example a
> > more stable hdmi signal [I think that was the main reason for the initial
> > change].
> > 
> > So we're not changing the frequency x -> y, which could be easily done
> > [and is done already] via assigned-rates, but instead
> > 
> > 	x {params a,b,c} -> x {params d,e,f}
> > 
> > so the rate itself stays the same, only the frequency generation is
> > adapted.
> Ok. It would be nice if this sort of information was made into a
> comment and put in the code. Or at least the commit text for the
> change.
> 
> And is there any reason that we need to get the parent clock and
> parent rate to align the PLL settings?
> It would be nice if we
> avoided using clk_* APIs in here, by extracting the pll set rate
> code into another function that we can call from init to make the
> values the same without all the fallback to old rates, etc.

I guess you want Xing Zheng to change his pll code somewhat like the
following, right? While starting off as proof-of-concept, that change
below actually does work quite nicely on rk3288 boards.

---------------- 8< --------------------
From: Heiko Stuebner <heiko@sntech.de>
Subject: [PATCH] clk: rockchip: don't use clk_ APIs in the pll init-callback

Separate the update of pll registers from the actual set_rate function
so that the init callback does not need to access clk-API functions.

As we now have separated the getting and setting of the pll parameters
we can also directly use these new functions in other places too.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/rockchip/clk-pll.c | 135 ++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 61 deletions(-)

diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 7737a1d..4881eb8 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -126,11 +126,32 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 #define RK3066_PLLCON3_PWRDOWN		(1 << 1)
 #define RK3066_PLLCON3_BYPASS		(1 << 0)
 
+static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
+					struct rockchip_pll_rate_table *rate)
+{
+	u32 pllcon;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
+	rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
+				& RK3066_PLLCON0_NR_MASK) + 1;
+	rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
+				& RK3066_PLLCON0_OD_MASK) + 1;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
+	rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
+				& RK3066_PLLCON1_NF_MASK) + 1;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
+	rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
+				& RK3066_PLLCON2_NB_MASK) + 1;
+}
+
 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
 						     unsigned long prate)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
-	u64 nf, nr, no, rate64 = prate;
+	struct rockchip_pll_rate_table cur;
+	u64 rate64 = prate;
 	u32 pllcon;
 
 	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
@@ -140,53 +161,31 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
 		return prate;
 	}
 
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
-	nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK;
-
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
-	nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK;
-	no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK;
+	rockchip_rk3066_pll_get_params(pll, &cur);
 
-	rate64 *= (nf + 1);
-	do_div(rate64, nr + 1);
-	do_div(rate64, no + 1);
+	rate64 *= cur.nf;
+	do_div(rate64, cur.nr);
+	do_div(rate64, cur.no);
 
 	return (unsigned long)rate64;
 }
 
-static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
-					unsigned long prate)
+static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
+				const struct rockchip_pll_rate_table *rate)
 {
-	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
-	const struct rockchip_pll_rate_table *rate;
-	unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
-	struct regmap *grf = rockchip_clk_get_grf();
-	struct clk_mux *pll_mux = &pll->pll_mux;
 	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+	struct clk_mux *pll_mux = &pll->pll_mux;
+	struct rockchip_pll_rate_table cur;
 	int rate_change_remuxed = 0;
 	int cur_parent;
 	int ret;
 
-	if (IS_ERR(grf)) {
-		pr_debug("%s: grf regmap not available, aborting rate change\n",
-			 __func__);
-		return PTR_ERR(grf);
-	}
-
-	pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
-		 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
-
-	/* Get required rate settings from table */
-	rate = rockchip_get_pll_settings(pll, drate);
-	if (!rate) {
-		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, clk_hw_get_name(hw));
-		return -EINVAL;
-	}
-
 	pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
 		 __func__, rate->rate, rate->nr, rate->no, rate->nf);
 
+	rockchip_rk3066_pll_get_params(pll, &cur);
+	cur.rate = 0;
+
 	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
 	if (cur_parent == PLL_MODE_NORM) {
 		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
@@ -219,9 +218,9 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 	/* wait for the pll to lock */
 	ret = rockchip_pll_wait_lock(pll);
 	if (ret) {
-		pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
-			__func__, old_rate);
-		rockchip_rk3066_pll_set_rate(hw, old_rate, prate);
+		pr_warn("%s: pll update unsucessful, trying to restore old params\n",
+			__func__);
+		rockchip_rk3066_pll_set_params(pll, &cur);
 	}
 
 	if (rate_change_remuxed)
@@ -230,6 +229,34 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 	return ret;
 }
 
+static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+	unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
+	struct regmap *grf = rockchip_clk_get_grf();
+
+	if (IS_ERR(grf)) {
+		pr_debug("%s: grf regmap not available, aborting rate change\n",
+			 __func__);
+		return PTR_ERR(grf);
+	}
+
+	pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
+		 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
+
+	/* Get required rate settings from table */
+	rate = rockchip_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, clk_hw_get_name(hw));
+		return -EINVAL;
+	}
+
+	return rockchip_rk3066_pll_set_params(pll, rate);
+}
+
 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
@@ -261,9 +288,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 	const struct rockchip_pll_rate_table *rate;
-	unsigned int nf, nr, no, nb;
+	struct rockchip_pll_rate_table cur;
 	unsigned long drate;
-	u32 pllcon;
 
 	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
 		return;
@@ -275,34 +301,21 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
 	if (!rate)
 		return;
 
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
-	nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
-	no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
-
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
-	nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
-
-	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
-	nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1;
+	rockchip_rk3066_pll_get_params(pll, &cur);
 
 	pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
-		 __func__, clk_hw_get_name(hw), drate, rate->nr, nr,
-		rate->no, no, rate->nf, nf, rate->nb, nb);
-	if (rate->nr != nr || rate->no != no || rate->nf != nf
-					     || rate->nb != nb) {
-		struct clk_hw *parent = clk_hw_get_parent(hw);
-		unsigned long prate;
-
-		if (!parent) {
-			pr_warn("%s: parent of %s not available\n",
-				__func__, clk_hw_get_name(hw));
+		 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
+		 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
+	if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
+						     || rate->nb != cur.nb) {
+		struct regmap *grf = rockchip_clk_get_grf();
+
+		if (IS_ERR(grf))
 			return;
-		}
 
 		pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
 			 __func__, clk_hw_get_name(hw));
-		prate = clk_hw_get_rate(parent);
-		rockchip_rk3066_pll_set_rate(hw, drate, prate);
+		rockchip_rk3066_pll_set_params(pll, rate);
 	}
 }
 
-- 
2.5.3
---------------- 8< --------------------

Heiko

  reply	other threads:[~2015-09-30 23:32 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-17  8:28 [PATCH v2 0/9] Build and support rk3036 SoC platform Xing Zheng
2015-09-17  8:28 ` Xing Zheng
2015-09-17  8:28 ` [rtc-linux] " Xing Zheng
2015-09-17  8:28 ` Xing Zheng
     [not found] ` <1442478540-15068-1-git-send-email-zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
2015-09-17  8:28   ` [PATCH v2 1/9] ARM: dts: rockchip: add core rk3036 dts Xing Zheng
2015-09-17  8:28     ` Xing Zheng
2015-09-17  8:28     ` Xing Zheng
2015-09-17  9:18     ` Heiko Stübner
2015-09-17  9:18       ` Heiko Stübner
2015-09-24  2:18       ` Xing Zheng
2015-09-24  2:18         ` Xing Zheng
2015-09-24  2:18         ` Xing Zheng
2015-09-17  8:28   ` [PATCH v2 2/9] clk: rockchip: add dt-binding header for rk3036 Xing Zheng
2015-09-17  8:28     ` Xing Zheng
     [not found]     ` <1442478540-15068-3-git-send-email-zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
2015-09-17  9:25       ` Heiko Stübner
2015-09-17  9:25         ` Heiko Stübner
2015-09-24  2:17         ` Xing Zheng
2015-09-24  2:17           ` Xing Zheng
2015-09-17 10:32   ` [PATCH v2 5/9] dt-bindings: add documentation of rk3036 clock controller Xing Zheng
2015-09-17 10:32     ` Xing Zheng
2015-09-17 10:32     ` Xing Zheng
     [not found]     ` <1442485969-1733-1-git-send-email-zhengxing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
2015-09-17 15:09       ` Heiko Stübner
2015-09-17 15:09         ` Heiko Stübner
2015-09-17 15:09         ` Heiko Stübner
2015-09-24  3:42         ` Xing Zheng
2015-09-24  3:42           ` Xing Zheng
2015-09-17  8:28 ` [PATCH v2 3/9] clk: rockchip: add clock controller for rk3036 Xing Zheng
2015-09-17  8:28   ` Xing Zheng
2015-09-17  8:28   ` Xing Zheng
2015-09-17  9:47   ` Heiko Stübner
2015-09-17  9:47     ` Heiko Stübner
2015-09-24  3:04     ` Xing Zheng
2015-09-24  3:04       ` Xing Zheng
2015-09-24  3:04       ` Xing Zheng
2015-09-24  3:31       ` Xing Zheng
2015-09-24  3:31         ` Xing Zheng
2015-10-07 10:24         ` Heiko Stuebner
2015-10-07 10:24           ` Heiko Stuebner
2015-10-07 10:24           ` Heiko Stuebner
2015-09-17  8:28 ` [PATCH v2 4/9] clk: rockchip: add new clock type and " Xing Zheng
2015-09-17  8:28   ` Xing Zheng
2015-09-17  8:28   ` Xing Zheng
2015-09-17  9:54   ` Heiko Stübner
2015-09-17  9:54     ` Heiko Stübner
2015-09-17  9:54     ` Heiko Stübner
2015-09-22 22:41   ` Stephen Boyd
2015-09-22 22:41     ` Stephen Boyd
2015-09-22 22:58     ` Heiko Stübner
2015-09-22 22:58       ` Heiko Stübner
2015-09-22 23:19       ` Stephen Boyd
2015-09-22 23:19         ` Stephen Boyd
2015-09-30 23:32         ` Heiko Stübner [this message]
2015-09-30 23:32           ` Heiko Stübner
2015-09-30 23:32           ` Heiko Stübner
2015-10-01  0:51           ` Stephen Boyd
2015-10-01  0:51             ` Stephen Boyd
2015-09-17  9:59 ` [PATCH v2 0/9] Build and support rk3036 SoC platform Heiko Stübner
2015-09-17  9:59   ` Heiko Stübner
2015-09-17  9:59   ` [rtc-linux] " Heiko Stübner
2015-09-17 10:34 ` [PATCH v2 6/9] pinctrl: rockchip: add support for the rk3036 Xing Zheng
2015-09-17 10:34   ` Xing Zheng
2015-09-17 12:47   ` Heiko Stübner
2015-09-17 12:47     ` Heiko Stübner
2015-09-17 10:37 ` [PATCH v2 7/9] rockchip: make sure timer5 is enabled on rk3036 platforms Xing Zheng
2015-09-17 10:37   ` Xing Zheng
2015-09-17 15:05   ` Heiko Stübner
2015-09-17 15:05     ` Heiko Stübner
2015-09-28 12:25     ` Xing Zheng
2015-09-28 12:25       ` Xing Zheng
2015-09-28 12:44       ` Heiko Stübner
2015-09-28 12:44         ` Heiko Stübner
2015-09-28 12:53         ` Xing Zheng
2015-09-28 12:53           ` Xing Zheng
2015-09-17 10:38 ` [PATCH v2 8/9] ARM: rockchip: add support smp for rk3036 Xing Zheng
2015-09-17 10:38   ` Xing Zheng
2015-09-17 20:15   ` Heiko Stübner
2015-09-17 20:15     ` Heiko Stübner
2015-09-28 11:50     ` Xing Zheng
2015-09-28 11:50       ` Xing Zheng
2015-09-17 10:39 ` [rtc-linux] [PATCH v2 9/9] rtc: hym8563: make sure hym8563 can be normal work Xing Zheng
2015-09-17 10:39   ` Xing Zheng
2015-09-17 12:07   ` [rtc-linux] " Heiko Stübner
2015-09-17 12:07     ` Heiko Stübner
2015-09-17 12:31     ` [rtc-linux] " Alexandre Belloni
2015-09-17 12:31       ` Alexandre Belloni
2015-09-17 12:44       ` [rtc-linux] " Xing Zheng
2015-09-17 12:44         ` Xing Zheng

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=4123121.bNYOPIrL2s@diego \
    --to=heiko@sntech.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mturquette@baylibre.com \
    --cc=sboyd@codeaurora.org \
    --cc=zhengxing@rock-chips.com \
    /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.