Clock support for rk3066,rk3188 and rk3288
Subsystems (5)
Heiko Stübner
maintainerv4 cover Clock support for rk3066,rk3188 and rk3288
This series adds a clock driver infrastructure for Rockchip SoCs in general and clock-definitions for the RK3188 and RK3288 in particular.
The previous attempt to define parts separately in the devicetree did not really fit with the clock structure, which became apparent with more knowledge about the clock tree.
The whole structure should support Rockchip SoCs at least down to the RK28xx (ARM9) which all share a very similar setup of their clock controllers in PLL, divider and gate handling as well as the included softreset parts.
A big change is the move from declaring all mux/dividers/gates individually to declaring them as composite clock branches, making the code better readable and making it possible to keep clocks together in a more natural order.
The changes under drivers/clk apply cleanly to clk-next but the changes in arm/boot/dts require patches from arm-soc, so in the unlikely case of this making it in before the merge window the dts patches should go through arm-soc (or should do so anyway, as they do not directly depend on the drivers/clk changes)
changes since v3:
- add rk3288 clock controller
- add reset controller ids
- fix some incorrect values in rk3188-cru and export some more clocks
- fold new rk3066 clock tree into the rk3188 one, as can be easily seen the differences are not really big between them
- expand the composite fix description to highlight the underlying issue changes since v2:
- drop the special cpuclk type until coordinated range changes matured, as mentioned in the Samsung cpufreq thread.
- add the patch from Boris BREZILLON that reenables correct rate calculations in composite clocks
- change pll handling to better handle the pll output mux and also the enabling/disabling of the pll clock
- change core code to handle composite clock branches instead of individual basic clock definitions
- use the newly defined GRF syscon instead of mapping a grf register individually
changes since v1:
- adapt to apply on current clk-next branch
- add saradc clock
- add rk3188a cru, which has a slightly different handling of one pll value (bwadj)
Boris BREZILLON (1):
clk: composite: support determine_rate using rate_ops->round_rate +
mux_ops->set_parent
Heiko Stuebner (12):
clk: composite: allow read-only clocks
clk: rockchip: add basic infrastructure for clock branches
clk: rockchip: add clock type for pll clocks and pll used on rk3066
clk: rockchip: add reset controller
dt-bindings: add documentation for rk3188 clock and reset unit
clk: rockchip: add clock driver for rk3188 and rk3066 clocks
ARM: rockchip: Select ARCH_HAS_RESET_CONTROLLER
ARM: dts: rockchip: add cru nodes and update device clocks to use it
ARM: dts: rockchip: move oscillator input clock into main dtsi
arm: dts: rockchip: remove obsolete clock gate definitions
clk: rockchip: add clock controller for rk3288
dt-bindings: add documentation for rk3288 cru
.../bindings/clock/rockchip,rk3188-cru.txt | 61 ++ .../bindings/clock/rockchip,rk3288-cru.txt | 61 ++ .../devicetree/bindings/clock/rockchip.txt | 3 + arch/arm/boot/dts/rk3066a-clocks.dtsi | 299 --------- arch/arm/boot/dts/rk3066a.dtsi | 30 +- arch/arm/boot/dts/rk3188-clocks.dtsi | 289 --------- arch/arm/boot/dts/rk3188.dtsi | 19 +- arch/arm/boot/dts/rk3xxx.dtsi | 22 +- arch/arm/mach-rockchip/Kconfig | 1 + drivers/clk/clk-composite.c | 60 +- drivers/clk/rockchip/Makefile | 6 + drivers/clk/rockchip/clk-pll.c | 431 +++++++++++++ drivers/clk/rockchip/clk-rk3188.c | 672 +++++++++++++++++++ drivers/clk/rockchip/clk-rk3288.c | 717 +++++++++++++++++++++ drivers/clk/rockchip/clk.c | 237 +++++++ drivers/clk/rockchip/clk.h | 347 ++++++++++ drivers/clk/rockchip/softrst.c | 115 ++++ include/dt-bindings/clock/rk3066a-cru.h | 35 + include/dt-bindings/clock/rk3188-cru-common.h | 249 +++++++ include/dt-bindings/clock/rk3188-cru.h | 51 ++ include/dt-bindings/clock/rk3288-cru.h | 278 ++++++++ 21 files changed, 3365 insertions(+), 618 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3188-cru.txt create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt delete mode 100644 arch/arm/boot/dts/rk3066a-clocks.dtsi delete mode 100644 arch/arm/boot/dts/rk3188-clocks.dtsi create mode 100644 drivers/clk/rockchip/clk-pll.c create mode 100644 drivers/clk/rockchip/clk-rk3188.c create mode 100644 drivers/clk/rockchip/clk-rk3288.c create mode 100644 drivers/clk/rockchip/clk.c create mode 100644 drivers/clk/rockchip/clk.h create mode 100644 drivers/clk/rockchip/softrst.c create mode 100644 include/dt-bindings/clock/rk3066a-cru.h create mode 100644 include/dt-bindings/clock/rk3188-cru-common.h create mode 100644 include/dt-bindings/clock/rk3188-cru.h create mode 100644 include/dt-bindings/clock/rk3288-cru.h
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 1/13 clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent
From: Boris BREZILLON <[email protected]>
In case the rate_hw does not implement determine_rate, but only round_rate we fallback to best_parent selection if mux_hw is present and support reparenting.
This also fixes a rate calculation problem when using the standard div and mux ops, as in this case currently only the mux->determine_rate is used in the composite rate calculation.
So when for example the composite clock has two parents at 600 and 800MHz, the requested rate is 75MHz, which the divider could provide, without this change the rate would be set 600MHz ignoring the divider completely. This may be way out of spec for the component.
--- drivers/clk/clk-composite.c | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-)
drivers/clk/clk-composite.c +50 -1
@@ -64,11 +64,59 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,const struct clk_ops *mux_ops = composite->mux_ops;struct clk_hw *rate_hw = composite->rate_hw;struct clk_hw *mux_hw = composite->mux_hw; +struct clk *parent; +unsigned long parent_rate; +long tmp_rate, best_rate; +unsigned long rate_diff; +unsigned long best_rate_diff =ULONG_MAX ; +int i;if (rate_hw && rate_ops && rate_ops->determine_rate) { rate_hw->clk = hw->clk;return rate_ops->determine_rate (rate_hw, rate, best_parent_rate, best_parent_p); + }else if (rate_hw && rate_ops && rate_ops->round_rate && + mux_hw && mux_ops && mux_ops->set_parent) { + *best_parent_p =NULL ; + +if (__clk_get_flags (hw->clk) &CLK_SET_RATE_NO_REPARENT ) { + *best_parent_p =clk_get_parent (mux_hw->clk); + *best_parent_rate =__clk_get_rate (*best_parent_p); + +return rate_ops->round_rate (rate_hw, rate, + best_parent_rate); + } + +for (i =0 ; i <__clk_get_num_parents (mux_hw->clk); i++) { + parent =clk_get_parent_by_index (mux_hw->clk, i); +if (!parent) +continue ; + + parent_rate =__clk_get_rate (parent); + + tmp_rate = rate_ops->round_rate (rate_hw, rate, + &parent_rate); +if (tmp_rate <0 ) +continue ; + +if (tmp_rate < rate) + rate_diff = rate - tmp_rate; +else + rate_diff = tmp_rate - rate; + +if (!rate_diff || !*best_parent_p + || best_rate_diff > rate_diff) { + *best_parent_p = parent; + *best_parent_rate = parent_rate; + best_rate_diff = rate_diff; + best_rate = tmp_rate; + } + +if (!rate_diff) +return rate; + } + +return best_rate; }else if (mux_hw && mux_ops && mux_ops->determine_rate) { mux_hw->clk = hw->clk; return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
@@ -196,7 +244,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->rate_hw = rate_hw; composite->rate_ops = rate_ops; clk_composite_ops->recalc_rate = clk_composite_recalc_rate; -if (rate_ops->determine_rate) +if (rate_ops->determine_rate || + (rate_ops->round_rate && clk_composite_ops->set_parent)) clk_composite_ops->determine_rate = clk_composite_determine_rate; }
Signature · 1 line
1.9.0
PATCH v4 1/13 clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent
Hi Heiko,
Seems to be good, tested on stih416 board.
Only small remarks below
Best Regards
Gabriel.
Quoted 59 lines · Heiko St?bner
From: Boris BREZILLON <[email protected]>
In case the
rate_hwdoes not implementdetermine_rate, but onlyround_ratewe fallback tobest_parentselection ifmux_hwis present and support reparenting.Signed-off-by Boris BREZILLON <[email protected]>This also fixes a rate calculation problem when using the standard div and mux ops, as in this case currently only the
mux->determine_rateis used in the composite rate calculation.
So when for example the composite clock has two parents at 600 and 800MHz, the requested rate is 75MHz, which the divider could provide, without this change the rate would be set 600MHz ignoring the divider completely. This may be way out of spec for the component.[fixed the output to actually return a rate instead of the diff]Signed-off-by Heiko Stuebner <[email protected]>--- drivers/clk/clk-composite.c | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-)drivers/clk/clk-composite.c +24
-0@@ -64,11 +64,59 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,const struct clk_ops *mux_ops = composite->mux_ops;struct clk_hw *rate_hw = composite->rate_hw;struct clk_hw *mux_hw = composite->mux_hw; +struct clk *parent; +unsigned long parent_rate; +long tmp_rate, best_rate; +unsigned long rate_diff; +unsigned long best_rate_diff =ULONG_MAX ; +int i;if (rate_hw && rate_ops && rate_ops->determine_rate) { rate_hw->clk = hw->clk;return rate_ops->determine_rate (rate_hw, rate, best_parent_rate, best_parent_p); + }else if (rate_hw && rate_ops && rate_ops->round_rate && + mux_hw && mux_ops && mux_ops->set_parent) { + *best_parent_p =NULL ; + +if (__clk_get_flags (hw->clk) &CLK_SET_RATE_NO_REPARENT ) { + *best_parent_p =clk_get_parent (mux_hw->clk); + *best_parent_rate =__clk_get_rate (*best_parent_p); + +return rate_ops->round_rate (rate_hw, rate, + best_parent_rate); + } + +for (i =0 ; i <__clk_get_num_parents (mux_hw->clk); i++) { + parent =clk_get_parent_by_index (mux_hw->clk, i); +if (!parent) +continue ; + + parent_rate =__clk_get_rate (parent);
drivers/clk/clk-composite.c static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate, · line 105
Quoted 10 lines
drivers/clk/clk-composite.c +10
-0+ + tmp_rate = rate_ops->round_rate (rate_hw, rate, + &parent_rate); +if (tmp_rate <0 ) +continue ; + +if (tmp_rate < rate) + rate_diff = rate - tmp_rate; +else + rate_diff = tmp_rate - rate;
rate_dif = abs(rate - tmp_rate) is not better ?
Quoted 4 lines
drivers/clk/clk-composite.c +4
-0+ +if (!rate_diff || !*best_parent_p + || best_rate_diff > rate_diff) { + *best_parent_p = parent;
drivers/clk/clk-composite.c static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate, · line 119
Quoted 10 lines
drivers/clk/clk-composite.c +10
-0+ *best_parent_rate = parent_rate; + best_rate_diff = rate_diff; + best_rate = tmp_rate; + } + +if (!rate_diff) +return rate; + } + +return best_rate;
warning compilation: 'best_rate' may be used uninitialized in this function
Quoted 22 lines
drivers/clk/clk-composite.c +2
-2}else if (mux_hw && mux_ops && mux_ops->determine_rate) { mux_hw->clk = hw->clk; return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,@@ -196,7 +244,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->rate_hw = rate_hw; composite->rate_ops = rate_ops; clk_composite_ops->recalc_rate = clk_composite_recalc_rate; -if (rate_ops->determine_rate) +if (rate_ops->determine_rate || + (rate_ops->round_rate && clk_composite_ops->set_parent)) clk_composite_ops->determine_rate = clk_composite_determine_rate; } --1.9.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Heiko Stübner
maintainerPATCH v4 1/13 clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent
In case the rate_hw does not implement determine_rate, but only round_rate we fallback to best_parent selection if mux_hw is present and support reparenting.
This also fixes a rate calculation problem when using the standard div and mux ops, as in this case currently only the mux->determine_rate is used in the composite rate calculation.
So when for example the composite clock has two parents at 600 and 800MHz, the requested rate is 75MHz, which the divider could provide, without this change the rate would be set 600MHz ignoring the divider completely. This may be way out of spec for the component.
---
changes since v4:
- address comments from Gabriel Fernandez
- use abs()
- init best_rate
drivers/clk/clk-composite.c | 48 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)
drivers/clk/clk-composite.c +47 -1
@@ -64,11 +64,56 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,const struct clk_ops *mux_ops = composite->mux_ops;struct clk_hw *rate_hw = composite->rate_hw;struct clk_hw *mux_hw = composite->mux_hw; +struct clk *parent; +unsigned long parent_rate; +long tmp_rate, best_rate =0 ; +unsigned long rate_diff; +unsigned long best_rate_diff =ULONG_MAX ; +int i;if (rate_hw && rate_ops && rate_ops->determine_rate) { rate_hw->clk = hw->clk;return rate_ops->determine_rate (rate_hw, rate, best_parent_rate, best_parent_p); + }else if (rate_hw && rate_ops && rate_ops->round_rate && + mux_hw && mux_ops && mux_ops->set_parent) { + *best_parent_p =NULL ; + +if (__clk_get_flags (hw->clk) &CLK_SET_RATE_NO_REPARENT ) { + *best_parent_p =clk_get_parent (mux_hw->clk); + *best_parent_rate =__clk_get_rate (*best_parent_p); + +return rate_ops->round_rate (rate_hw, rate, + best_parent_rate); + } + +for (i =0 ; i <__clk_get_num_parents (mux_hw->clk); i++) { + parent =clk_get_parent_by_index (mux_hw->clk, i); +if (!parent) +continue ; + + parent_rate =__clk_get_rate (parent); + + tmp_rate = rate_ops->round_rate (rate_hw, rate, + &parent_rate); +if (tmp_rate <0 ) +continue ; + + rate_diff =abs (rate - tmp_rate); + +if (!rate_diff || !*best_parent_p + || best_rate_diff > rate_diff) { + *best_parent_p = parent; + *best_parent_rate = parent_rate; + best_rate_diff = rate_diff; + best_rate = tmp_rate; + } + +if (!rate_diff) +return rate; + } + +return best_rate; }else if (mux_hw && mux_ops && mux_ops->determine_rate) { mux_hw->clk = hw->clk; return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
@@ -196,7 +241,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->rate_hw = rate_hw; composite->rate_ops = rate_ops; clk_composite_ops->recalc_rate = clk_composite_recalc_rate; -if (rate_ops->determine_rate) +if (rate_ops->determine_rate || + (rate_ops->round_rate && clk_composite_ops->set_parent)) clk_composite_ops->determine_rate = clk_composite_determine_rate; }
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 1/13 clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent
In reply to Gabriel FernandezFrom: Boris BREZILLON <[email protected]>
In case the rate_hw does not implement determine_rate, but only round_rate we fallback to best_parent selection if mux_hw is present and support reparenting.
This also fixes a rate calculation problem when using the standard div and mux ops, as in this case currently only the mux->determine_rate is used in the composite rate calculation.
So when for example the composite clock has two parents at 600 and 800MHz, the requested rate is 75MHz, which the divider could provide, without this change the rate would be set 600MHz ignoring the divider completely. This may be way out of spec for the component.
---
changes since v4.1:
- forgot the From override, Boris is the original author
changes since v4:
- address comments from Gabriel Fernandez
- use abs()
- init best_rate
drivers/clk/clk-composite.c | 48 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)
drivers/clk/clk-composite.c +47 -1
@@ -64,11 +64,56 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,const struct clk_ops *mux_ops = composite->mux_ops;struct clk_hw *rate_hw = composite->rate_hw;struct clk_hw *mux_hw = composite->mux_hw; +struct clk *parent; +unsigned long parent_rate; +long tmp_rate, best_rate =0 ; +unsigned long rate_diff; +unsigned long best_rate_diff =ULONG_MAX ; +int i;if (rate_hw && rate_ops && rate_ops->determine_rate) { rate_hw->clk = hw->clk;return rate_ops->determine_rate (rate_hw, rate, best_parent_rate, best_parent_p); + }else if (rate_hw && rate_ops && rate_ops->round_rate && + mux_hw && mux_ops && mux_ops->set_parent) { + *best_parent_p =NULL ; + +if (__clk_get_flags (hw->clk) &CLK_SET_RATE_NO_REPARENT ) { + *best_parent_p =clk_get_parent (mux_hw->clk); + *best_parent_rate =__clk_get_rate (*best_parent_p); + +return rate_ops->round_rate (rate_hw, rate, + best_parent_rate); + } + +for (i =0 ; i <__clk_get_num_parents (mux_hw->clk); i++) { + parent =clk_get_parent_by_index (mux_hw->clk, i); +if (!parent) +continue ; + + parent_rate =__clk_get_rate (parent); + + tmp_rate = rate_ops->round_rate (rate_hw, rate, + &parent_rate); +if (tmp_rate <0 ) +continue ; + + rate_diff =abs (rate - tmp_rate); + +if (!rate_diff || !*best_parent_p + || best_rate_diff > rate_diff) { + *best_parent_p = parent; + *best_parent_rate = parent_rate; + best_rate_diff = rate_diff; + best_rate = tmp_rate; + } + +if (!rate_diff) +return rate; + } + +return best_rate; }else if (mux_hw && mux_ops && mux_ops->determine_rate) { mux_hw->clk = hw->clk; return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
@@ -196,7 +241,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->rate_hw = rate_hw; composite->rate_ops = rate_ops; clk_composite_ops->recalc_rate = clk_composite_recalc_rate; -if (rate_ops->determine_rate) +if (rate_ops->determine_rate || + (rate_ops->round_rate && clk_composite_ops->set_parent)) clk_composite_ops->determine_rate = clk_composite_determine_rate; }
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 2/13 clk: composite: allow read-only clocks
In reply to Heiko StübnerThis allows readl-only composite clocks by making mux_ops->set_parent and divider_ops->round_rate/set_rate optional.
--- drivers/clk/clk-composite.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/clk/clk-composite.c +3 -6
@@ -210,7 +210,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name, clk_composite_ops = &composite->ops;if (mux_hw && mux_ops) { -if (!mux_ops->get_parent || !mux_ops->set_parent) { +if (!mux_ops->get_parent) { clk =ERR_PTR (-EINVAL ); goto err; }
@@ -218,7 +218,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->mux_hw = mux_hw; composite->mux_ops = mux_ops; clk_composite_ops->get_parent = clk_composite_get_parent; - clk_composite_ops->set_parent = clk_composite_set_parent; +if (mux_ops->set_parent) + clk_composite_ops->set_parent = clk_composite_set_parent;if (mux_ops->determine_rate) clk_composite_ops->determine_rate = clk_composite_determine_rate; }
@@ -235,10 +236,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name,if (rate_ops->set_rate) { clk_composite_ops->set_rate = clk_composite_set_rate; } - }else { -WARN (rate_ops->set_rate, -"%s: missing round_rate op is required\n" , - __func__); } composite->rate_hw = rate_hw;
Signature · 1 line
1.9.0
PATCH v4 2/13 clk: composite: allow read-only clocks
Quoting Heiko St?bner (2014-06-22 13:43:35)
Quoted 32 lines
This allows readl-only composite clocks by making
mux_ops->set_parentand divider_ops->round_rate/set_rate optional.Signed-off-by Heiko Stuebner <[email protected]>--- drivers/clk/clk-composite.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)drivers/clk/clk-composite.c +3
-2@@ -210,7 +210,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name, clk_composite_ops = &composite->ops;if (mux_hw && mux_ops) { -if (!mux_ops->get_parent || !mux_ops->set_parent) { +if (!mux_ops->get_parent) { clk =ERR_PTR (-EINVAL ); goto err; }@@ -218,7 +218,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->mux_hw = mux_hw; composite->mux_ops = mux_ops; clk_composite_ops->get_parent = clk_composite_get_parent; - clk_composite_ops->set_parent = clk_composite_set_parent; +if (mux_ops->set_parent) + clk_composite_ops->set_parent = clk_composite_set_parent;if (mux_ops->determine_rate) clk_composite_ops->determine_rate = clk_composite_determine_rate; }
drivers/clk/clk-composite.c struct clk *clk_register_composite(struct device *dev, const char *name, · line 241
Quoted 7 lines
drivers/clk/clk-composite.c +0
-4@@ -235,10 +236,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name,if (rate_ops->set_rate) { clk_composite_ops->set_rate = clk_composite_set_rate; } - }else { -WARN (rate_ops->set_rate, -"%s: missing round_rate op is required\n" , - __func__);
Getting rid of this WARN isn't such a great solution. How about rolling in the following cleanup?
Quoted 1 line
From
03a08d7e746aedc6ce99228d629752f241383e7fMon Sep 17 00:00:00 2001
From: Mike Turquette <[email protected]>
Date: Tue, 1 Jul 2014 12:11:38 -0700
Subject: [PATCH] clk: composite: improve rate_hw sanity check logic
The function pointer population and sanity checking logic got a bit ugly with the advent of the .determine_rate callback. Clean it up.
--- drivers/clk/clk-composite.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
drivers/clk/clk-composite.c +16 -10
@@ -226,21 +226,27 @@ struct clk *clk_register_composite(struct device *dev, const char *name, clk =ERR_PTR (-EINVAL ); goto err; } + clk_composite_ops->recalc_rate = clk_composite_recalc_rate; -/* .round_rate is a prerequisite for .set_rate */ -if (rate_ops->round_rate) { - clk_composite_ops->round_rate = clk_composite_round_rate; -if (rate_ops->set_rate) { - clk_composite_ops->set_rate = clk_composite_set_rate; - } +if (rate_ops->determine_rate) + clk_composite_ops->determine_rate = + clk_composite_determine_rate; +else if (rate_ops->round_rate) + clk_composite_ops->round_rate = + clk_composite_round_rate; + +/* .set_rate requires either .round_rate or .determine_rate */ +if (rate_ops->set_rate) { +if (rate_ops->determine_rate || rate_ops->round_rate) + clk_composite_ops->set_rate = + clk_composite_set_rate; +else +WARN (1 ,"%s: missing round_rate op is required\n" , + __func__); } composite->rate_hw = rate_hw; composite->rate_ops = rate_ops; - clk_composite_ops->recalc_rate = clk_composite_recalc_rate; -if (rate_ops->determine_rate || - (rate_ops->round_rate && clk_composite_ops->set_parent)) - clk_composite_ops->determine_rate = clk_composite_determine_rate; }if (gate_hw && gate_ops) {
Signature · 1 line
1.8.3.2
Heiko Stübner
maintainerPATCH v4 3/13 clk: rockchip: add basic infrastructure for clock branches
In reply to Heiko StübnerThis adds infrastructure for registering clock branches. On Rockchip SoCs most clock branches are a combination of mux,divider and gate components, thus a composite clock is used when appropriate.
Clock branches are supposed to be declared in an array using the COMPOSITE* or MUX, etc makros defined in the header and then registered using rockchip_clk_register_branches.
--- drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk.c | 202 ++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 250 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 453 insertions(+) create mode 100644 drivers/clk/rockchip/clk.c create mode 100644 drivers/clk/rockchip/clk.h
drivers/clk/rockchip/Makefile +1 -0
@@ -3,3 +3,4 @@ # obj-y += clk-rockchip.o +obj-y += clk.o
drivers/clk/rockchip/clk.c new file +202 -0
202 lines not on this page · raw message
drivers/clk/rockchip/clk.h new file +250 -0
250 lines not on this page · raw message
Signature · 1 line
1.9.0
PATCH v4 3/13 clk: rockchip: add basic infrastructure for clock branches
Quoting Heiko St?bner (2014-06-22 13:44:07)
drivers/clk/rockchip/clk.c line 133
Quoted 5 lines
drivers/clk/rockchip/clk.c new file +5
-0+void __init rockchip_clk_register_branches ( +struct rockchip_clk_branch *list, +unsigned int nr_clk) +{ +struct clk *clk;
clk should be initialized to NULL here, otherwise I get a warning down below ...
Quoted 51 lines
drivers/clk/rockchip/clk.c new file +51
-0+unsigned int idx; +unsigned long flags; + +for (idx =0 ; idx < nr_clk; idx++, list++) { + flags = list->flags; + +/* catch simple muxes */ +switch (list->branch_type) { +case branch_mux: + clk =clk_register_mux (NULL , list->name, + list->parent_names, list->num_parents, + flags, reg_base + list->muxdiv_offset, + list->mux_shift, list->mux_width, + list->mux_flags, &clk_lock); +break ; +case branch_divider: +if (list->div_table) + clk =clk_register_divider_table (NULL , + list->name, list->parent_names[0 ], + flags, reg_base + list->muxdiv_offset, + list->div_shift, list->div_width, + list->div_flags, list->div_table, + &clk_lock); +else + clk =clk_register_divider (NULL , list->name, + list->parent_names[0 ], flags, + reg_base + list->muxdiv_offset, + list->div_shift, list->div_width, + list->div_flags, &clk_lock); +break ; +case branch_fraction_divider: +/* unimplemented */ +continue ; +break ; +case branch_gate: + flags |=CLK_SET_RATE_PARENT ; + +/* keep all gates untouched for now */ + flags |=CLK_IGNORE_UNUSED ; + + clk =clk_register_gate (NULL , list->name, + list->parent_names[0 ], flags, + reg_base + list->gate_offset, + list->gate_shift, list->gate_flags, &clk_lock); +break ; +case branch_composite: +/* keep all gates untouched for now */ + flags |=CLK_IGNORE_UNUSED ; + + clk = rockchip_clk_register_branch(list->name, + list->parent_names, list->num_parents,
drivers/clk/rockchip/clk.c line 194
Quoted 10 lines
drivers/clk/rockchip/clk.c new file +10
-0+ reg_base, list->muxdiv_offset, list->mux_shift, + list->mux_width, list->mux_flags, + list->div_shift, list->div_width, + list->div_flags, list->div_table, + list->gate_offset, list->gate_shift, + list->gate_flags, flags, &clk_lock); +break ; + } + +if (IS_ERR (clk)) {
... here. gcc throws:
"""drivers/clk/rockchip/clk.c: In function ?rockchip_clk_register_branches?:include/linux/err.h:35:22: warning: ?clk? may be used uninitialized in this function [-Wmaybe-uninitialized]
return IS_ERR_VALUE((unsigned long)ptr);
"""
Regards,
Mike
Quoted 268 lines
drivers/clk/rockchip/clk.c new file +8
-0+pr_err ("%s: failed to register clock %s: %ld\n" , + __func__, list->name,PTR_ERR (clk)); +continue ; + } + +rockchip_clk_add_lookup (clk, list->id); + } +}drivers/clk/rockchip/clk.h new file +250
-0@@ -0,0 +1,250 @@ +/* +* Copyright (c) 2014 MundoReader S.L. +* Author: Heiko Stuebner <[email protected]> +* +* based on +* +* samsung/clk.h +* Copyright (c) 2013 Samsung Electronics Co., Ltd. +* Copyright (c) 2013 Linaro Ltd. +* Author: Thomas Abraham <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef CLK_ROCKCHIP_CLK_H +#define CLK_ROCKCHIP_CLK_H + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> + +#define HIWORD_UPDATE (val, mask, shift) \ + ((val) << (shift) | (mask) << ((shift) + 16)) + +/* register positions shared by RK2928, RK3066 and RK3188 */ +#define RK2928_PLL_CON (x) (x * 0x4) +#define RK2928_MODE_CON 0x40 +#define RK2928_CLKSEL_CON (x) (x * 0x4 + 0x44) +#define RK2928_CLKGATE_CON (x) (x * 0x4 + 0xd0) +#define RK2928_GLB_SRST_FST 0x100 +#define RK2928_GLB_SRST_SND 0x104 +#define RK2928_SOFTRST_CON (x) (x * 0x4 + 0x110) +#define RK2928_MISC_CON 0x134 + +#define PNAME (x) static const char *x[] __initconst + +enum rockchip_clk_branch_type { + branch_composite, + branch_mux, + branch_divider, + branch_fraction_divider, + branch_gate, +}; + +struct rockchip_clk_branch { +unsigned int id; +enum rockchip_clk_branch_type branch_type; +const char *name; +const char **parent_names; +u8 num_parents; +unsigned long flags; +int muxdiv_offset; +u8 mux_shift; +u8 mux_width; +u8 mux_flags; +u8 div_shift; +u8 div_width; +u8 div_flags; +struct clk_div_table *div_table; +int gate_offset; +u8 gate_shift; +u8 gate_flags; +}; + +#define COMPOSITE (_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ + df, go, gs, gf) \ + { \ + .id = _id, \ + .branch_type = branch_composite, \ + .name = cname, \ + .parent_names = pnames, \ + .num_parents = ARRAY_SIZE(pnames), \ + .flags = f, \ + .muxdiv_offset = mo, \ + .mux_shift = ms, \ + .mux_width = mw, \ + .mux_flags = mf, \ + .div_shift = ds, \ + .div_width = dw, \ + .div_flags = df, \ + .gate_offset = go, \ + .gate_shift = gs, \ + .gate_flags = gf, \ + } + +#define COMPOSITE_NOMUX (_id, cname, pname, f, mo, ds, dw, df, \ + go, gs, gf) \ + { \ + .id = _id, \ + .branch_type = branch_composite, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .muxdiv_offset = mo, \ + .div_shift = ds, \ + .div_width = dw, \ + .div_flags = df, \ + .gate_offset = go, \ + .gate_shift = gs, \ + .gate_flags = gf, \ + } + +#define COMPOSITE_NOMUX_DIVTBL (_id, cname, pname, f, mo, ds, dw,\ + df, dt, go, gs, gf) \ + { \ + .id = _id, \ + .branch_type = branch_composite, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .muxdiv_offset = mo, \ + .div_shift = ds, \ + .div_width = dw, \ + .div_flags = df, \ + .div_table = dt, \ + .gate_offset = go, \ + .gate_shift = gs, \ + .gate_flags = gf, \ + } + +#define COMPOSITE_NODIV (_id, cname, pnames, f, mo, ms, mw, mf, \ + go, gs, gf) \ + { \ + .id = _id, \ + .branch_type = branch_composite, \ + .name = cname, \ + .parent_names = pnames, \ + .num_parents = ARRAY_SIZE(pnames), \ + .flags = f, \ + .muxdiv_offset = mo, \ + .mux_shift = ms, \ + .mux_width = mw, \ + .mux_flags = mf, \ + .gate_offset = go, \ + .gate_shift = gs, \ + .gate_flags = gf, \ + } + +#define COMPOSITE_NOGATE (_id, cname, pnames, f, mo, ms, mw, mf, \ + ds, dw, df) \ + { \ + .id = _id, \ + .branch_type = branch_composite, \ + .name = cname, \ + .parent_names = pnames, \ + .num_parents = ARRAY_SIZE(pnames), \ + .flags = f, \ + .muxdiv_offset = mo, \ + .mux_shift = ms, \ + .mux_width = mw, \ + .mux_flags = mf, \ + .div_shift = ds, \ + .div_width = dw, \ + .div_flags = df, \ + .gate_offset = -1, \ + } + +#define COMPOSITE_FRAC (_id, cname, pname, f, mo, df, go, gs, gf)\ + { \ + .id = _id, \ + .branch_type = branch_fraction_divider, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .muxdiv_offset = mo, \ + .div_shift = 16, \ + .div_width = 16, \ + .div_flags = df, \ + .gate_offset = go, \ + .gate_shift = gs, \ + .gate_flags = gf, \ + } + +#define MUX (_id, cname, pnames, f, o, s, w, mf) \ + { \ + .id = _id, \ + .branch_type = branch_mux, \ + .name = cname, \ + .parent_names = pnames, \ + .num_parents = ARRAY_SIZE(pnames), \ + .flags = f, \ + .muxdiv_offset = o, \ + .mux_shift = s, \ + .mux_width = w, \ + .mux_flags = mf, \ + .gate_offset = -1, \ + } + +#define DIV (_id, cname, pname, f, o, s, w, df) \ + { \ + .id = _id, \ + .branch_type = branch_divider, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .muxdiv_offset = o, \ + .div_shift = s, \ + .div_width = w, \ + .div_flags = df, \ + .gate_offset = -1, \ + } + +#define DIVTBL (_id, cname, pname, f, o, s, w, df, dt) \ + { \ + .id = _id, \ + .branch_type = branch_divider, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .muxdiv_offset = o, \ + .div_shift = s, \ + .div_width = w, \ + .div_flags = df, \ + .div_table = dt, \ + } + +#define GATE (_id, cname, pname, f, o, b, gf) \ + { \ + .id = _id, \ + .branch_type = branch_gate, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .gate_offset = o, \ + .gate_shift = b, \ + .gate_flags = gf, \ + } + + +void rockchip_clk_init (struct device_node *np,void __iomem *base, +unsigned long nr_clks); +void rockchip_clk_add_lookup (struct clk *clk,unsigned int id); +void rockchip_clk_register_branches (struct rockchip_clk_branch *clk_list, +unsigned int nr_clk); + +#endif Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 4/13 clk: rockchip: add clock type for pll clocks and pll used on rk3066
In reply to Heiko StübnerAll known Rockchip SoCs down to the RK28xx (ARM9) use a similar pattern to handle their plls:
|--\
xin32k ----------------|mux\
xin24m -----| pll |----|pll|--- pll output
\---------------|src/
|--/The pll output is sourced from 1 of 3 sources, the actual pll being one of them. To change the pll frequency it is imperative to remux it to another source beforehand. This is done by adding a clock-listener to the pll that handles the remuxing before and after the rate change.
The output mux is implemented as a separate clock to make use of already existing common-clock features for disabling the pll if one of the other two sources is used.
--- drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk-pll.c | 431 +++++++++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.c | 35 ++++ drivers/clk/rockchip/clk.h | 74 +++++++ 4 files changed, 541 insertions(+) create mode 100644 drivers/clk/rockchip/clk-pll.c
drivers/clk/rockchip/Makefile +1 -0
@@ -4,3 +4,4 @@ obj-y += clk-rockchip.o obj-y += clk.o +obj-y += clk-pll.o
drivers/clk/rockchip/clk-pll.c new file +431 -0
431 lines not on this page · raw message
drivers/clk/rockchip/clk.c +35 -0
@@ -23,6 +23,8 @@#include <linux/slab.h> #include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> #include "clk.h" /**
@@ -105,11 +107,15 @@ static DEFINE_SPINLOCK(clk_lock);static struct clk **clk_table;static void __iomem *reg_base;static struct clk_onecell_data clk_data; +static struct device_node *cru_node; +static struct regmap *grf;void __init rockchip_clk_init (struct device_node *np,void __iomem *base,unsigned long nr_clks) { reg_base = base; + cru_node = np; + grf =ERR_PTR (-EPROBE_DEFER ); clk_table =kcalloc (nr_clks,sizeof (struct clk *),GFP_KERNEL );if (!clk_table)
@@ -120,12 +126,41 @@ void __init rockchip_clk_init(struct device_node *np, void __iomem *base,of_clk_add_provider (np, of_clk_src_onecell_get, &clk_data); } +struct regmap *rockchip_clk_get_grf (void ) +{ +if (IS_ERR (grf)) + grf =syscon_regmap_lookup_by_phandle (cru_node,"rockchip,grf" ); +return grf; +} +void rockchip_clk_add_lookup (struct clk *clk,unsigned int id) {if (clk_table && id) clk_table[id] = clk; } +void __init rockchip_clk_register_plls (struct rockchip_pll_clock *list, +unsigned int nr_pll,int grf_lock_offset) +{ +struct clk *clk; +int idx; + +for (idx =0 ; idx < nr_pll; idx++, list++) { + clk =rockchip_clk_register_pll (list->type, list->name, + list->parent_names, list->num_parents, + reg_base, list->con_offset, grf_lock_offset, + list->lock_shift, list->mode_offset, + list->mode_shift, list->rate_table, &clk_lock); +if (IS_ERR (clk)) { +pr_err ("%s: failed to register clock %s\n" , __func__, + list->name); +continue ; + } + +rockchip_clk_add_lookup (clk, list->id); + } +} +void __init rockchip_clk_register_branches (struct rockchip_clk_branch *list,unsigned int nr_clk)
drivers/clk/rockchip/clk.h +74 -0
88 lines not on this page · raw message
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 5/13 clk: rockchip: add reset controller
In reply to Heiko StübnerAll Rockchip SoCs at least down to the ARM9-based RK28xx include the reset- controller for SoC peripherals in their clock controller.
While the older SoCs (ARM9 and Cortex-A8) use a regular scheme to change register values, the Cortex-A9 SoCs use a hiword-mask making locking unecessary. To be compatible with both schemes the reset controller takes a flag to decide which scheme to use, similar to the other HIWORD_MASK flags used in the clock framework.
--- drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk.h | 14 +++++ drivers/clk/rockchip/softrst.c | 115 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 drivers/clk/rockchip/softrst.c
drivers/clk/rockchip/Makefile +1 -0
@@ -5,3 +5,4 @@ obj-y += clk-rockchip.o obj-y += clk.o obj-y += clk-pll.o +obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
drivers/clk/rockchip/clk.h +14 -0
@@ -321,4 +321,18 @@ void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,void rockchip_clk_register_plls (struct rockchip_pll_clock *pll_list,unsigned int nr_pll,int grf_lock_offset); +#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) + +#ifdef CONFIG_RESET_CONTROLLER +void rockchip_register_softrst (struct device_node *np, +unsigned int num_regs, +void __iomem *base,u8 flags); +#else +static inline void rockchip_register_softrst (struct device_node *np, +unsigned int num_regs, +void __iomem *base,u8 flags) +{ +} +#endif +#endif
drivers/clk/rockchip/softrst.c new file +115 -0
115 lines not on this page · raw message
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 6/13 dt-bindings: add documentation for rk3188 clock and reset unit
In reply to Heiko StübnerThis add bindings documentation for the clock and reset unit found on rk3188 and rk3066 SoCs from Rockchip.
Also deprecate the old gate clock binding, as these shouldn't be used in the future.
--- .../bindings/clock/rockchip,rk3188-cru.txt | 61 ++++++++++++++++++++++ .../devicetree/bindings/clock/rockchip.txt | 3 ++ 2 files changed, 64 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3188-cru.txt
Documentation/devicetree/bindings/clock/rockchip,rk3188-cru.txt new file +61 -0
@@ -0,0 +1,61 @@ +* Rockchip RK3188/RK3066 Clock and Reset Unit + +The RK3188/RK3066 clock controller generates and supplies clock to various +controllers within the SoC and also implements a reset controller for SoC +peripherals. + +Required Properties: + +- compatible: should be "rockchip,rk3188-cru", "rockchip,rk3188a-cru" or + "rockchip,rk3066a-cru" +- reg: physical base address of the controller and length of memory mapped + region. +- #clock-cells: should be 1. +- #reset-cells: should be 1. + +Optional Properties: + +- rockchip,grf: phandle to the syscon managing the "general register files" + If missing pll rates are not changable, due to the missing pll lock status. + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. All available clocks are defined as +preprocessor macros in the dt-bindings/clock/rk3188-cru.h and +dt-bindings/clock/rk3066-cru.h headers and can be used in device tree sources. +Similar macros exist for the reset sources in these files. + +External clocks: + +There are several clocks that are generated outside the SoC. It is expected +that they are defined using standard clock bindings with following +clock-output-names: + - "xin24m" - crystal input - required, + - "xin32k" - rtc clock - optional, + - "xin27m" - 27mhz crystal input on rk3066 - optional, + - "ext_hsadc" - external HSADC clock - optional, + - "ext_cif0" - external camera clock - optional, + - "ext_rmii" - external RMII clock - optional, + - "ext_jtag" - externalJTAG clock - optional + +Example: Clock controller node: + + cru: cru at 20000000 { + compatible = "rockchip,rk3188-cru"; + reg = <0x20000000 0x1000>; + rockchip,grf = <&grf>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + +Example: UART controller node that consumes the clock generated by the clock + controller: + + uart0: serial at 10124000 { + compatible = "snps,dw-apb-uart"; + reg = <0x10124000 0x400>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&cru SCLK_UART0>; + };
Documentation/devicetree/bindings/clock/rockchip.txt +3 -0
@@ -6,6 +6,9 @@ This binding uses the common clock binding[1]. == Gate clocks == +These bindings are deprecated! +Please use the soc specific CRU bindings instead. + The gate registers form a continuos block which makes the dt node structure a matter of taste, as either all gates can be put into one gate clock spanning all registers or they can be divided into
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 7/13 clk: rockchip: add clock driver for rk3188 and rk3066 clocks
In reply to Heiko StübnerThis adds a clock driver that handles the specific muxes, dividers and gates of rk3188 and rk3066 SoCs.
The structure of the clock list resembles the arrangement of their counterparts in the clock architecture diagrams found in the SoC documentation.
Clocks exported to the clock provider are currently limited to well known or measured ones. So additional clock exports may be necessary in the future.
--- drivers/clk/rockchip/Makefile | 2 + drivers/clk/rockchip/clk-rk3188.c | 672 ++++++++++++++++++++++++++ include/dt-bindings/clock/rk3066a-cru.h | 35 ++ include/dt-bindings/clock/rk3188-cru-common.h | 249 ++++++++++ include/dt-bindings/clock/rk3188-cru.h | 51 ++ 5 files changed, 1009 insertions(+) create mode 100644 drivers/clk/rockchip/clk-rk3188.c create mode 100644 include/dt-bindings/clock/rk3066a-cru.h create mode 100644 include/dt-bindings/clock/rk3188-cru-common.h create mode 100644 include/dt-bindings/clock/rk3188-cru.h
drivers/clk/rockchip/Makefile +2 -0
@@ -6,3 +6,5 @@ obj-y += clk-rockchip.o obj-y += clk.o obj-y += clk-pll.o obj-$(CONFIG_RESET_CONTROLLER) += softrst.o + +obj-y += clk-rk3188.o
drivers/clk/rockchip/clk-rk3188.c new file +672 -0
672 lines not on this page · raw message
include/dt-bindings/clock/rk3066a-cru.h new file +35 -0
@@ -0,0 +1,35 @@ +/* +* Copyright (c) 2014 MundoReader S.L. +* Author: Heiko Stuebner <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <dt-bindings/clock/rk3188-cru-common.h> + +/* soft-reset indices */ +#define SRST_SRST1 0 +#define SRST_SRST2 1 + +#define SRST_L2MEM 18 +#define SRST_I2S0 23 +#define SRST_I2S1 24 +#define SRST_I2S2 25 +#define SRST_TIMER2 29 + +#define SRST_GPIO4 36 +#define SRST_GPIO6 38 + +#define SRST_TSADC 92 + +#define SRST_HDMI 96 +#define SRST_HDMI_APB 97 +#define SRST_CIF1 111
include/dt-bindings/clock/rk3188-cru-common.h new file +249 -0
249 lines not on this page · raw message
include/dt-bindings/clock/rk3188-cru.h new file +51 -0
51 lines not on this page · raw message
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 8/13 ARM: rockchip: Select ARCH_HAS_RESET_CONTROLLER
In reply to Heiko StübnerAll known Rockchip SoCs have a reset controller in their CRUs, so it's helpful to have the reset controller framework selected by default, only be deselected by the user in special cases.
--- arch/arm/mach-rockchip/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-rockchip/Kconfig +1 -0
@@ -2,6 +2,7 @@ config ARCH_ROCKCHIP bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7 select PINCTRL select PINCTRL_ROCKCHIP + select ARCH_HAS_RESET_CONTROLLER select ARCH_REQUIRE_GPIOLIB select ARM_GIC select CACHE_L2X0
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 9/13 ARM: dts: rockchip: add cru nodes and update device clocks to use it
In reply to Heiko StübnerThis adds a node for the clock and reset unit on rk3188 and rk3066 SoCs and also updates the device nodes retrieve their clocks from there, instead of the previous gate clock nodes.
--- arch/arm/boot/dts/rk3066a.dtsi | 29 ++++++++++++++++++++--------- arch/arm/boot/dts/rk3188.dtsi | 18 ++++++++++++++---- arch/arm/boot/dts/rk3xxx.dtsi | 16 ++++++++-------- 3 files changed, 42 insertions(+), 21 deletions(-)
arch/arm/boot/dts/rk3066a.dtsi +20 -9
@@ -15,6 +15,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/clock/rk3066a-cru.h> #include "rk3xxx.dtsi" #include "rk3066a-clocks.dtsi"
@@ -45,7 +46,7 @@ compatible = "snps,dw-apb-timer-osc"; reg = <0x20038000 0x100>; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates1 0>, <&clk_gates7 7>; + clocks = <&cru SCLK_TIMER0>, <&cru PCLK_TIMER0>; clock-names = "timer", "pclk"; };
@@ -53,7 +54,7 @@ compatible = "snps,dw-apb-timer-osc"; reg = <0x2003a000 0x100>; interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates1 1>, <&clk_gates7 8>; + clocks = <&cru SCLK_TIMER1>, <&cru PCLK_TIMER1>; clock-names = "timer", "pclk"; };
@@ -61,7 +62,7 @@ compatible = "snps,dw-apb-timer-osc"; reg = <0x2000e000 0x100>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates1 2>, <&clk_gates7 9>; + clocks = <&cru SCLK_TIMER2>, <&cru PCLK_TIMER2>; clock-names = "timer", "pclk"; };
@@ -78,6 +79,16 @@ }; }; + cru: cru at 20000000 { + compatible = "rockchip,rk3066a-cru"; + reg = <0x20000000 0x1000>; + + #clock-cells = <1>; + #reset-cells = <1>; + + rockchip,grf = <&grf>; + }; + pinctrl at 20008000 { compatible = "rockchip,rk3066a-pinctrl"; rockchip,grf = <&grf>;
@@ -89,7 +100,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x20034000 0x100>; interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 9>; + clocks = <&cru PCLK_GPIO0>; gpio-controller; #gpio-cells = <2>;
@@ -102,7 +113,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x2003c000 0x100>; interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 10>; + clocks = <&cru PCLK_GPIO1>; gpio-controller; #gpio-cells = <2>;
@@ -115,7 +126,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x2003e000 0x100>; interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 11>; + clocks = <&cru PCLK_GPIO2>; gpio-controller; #gpio-cells = <2>;
@@ -128,7 +139,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x20080000 0x100>; interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 12>; + clocks = <&cru PCLK_GPIO3>; gpio-controller; #gpio-cells = <2>;
@@ -141,7 +152,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x20084000 0x100>; interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 13>; + clocks = <&cru PCLK_GPIO4>; gpio-controller; #gpio-cells = <2>;
@@ -154,7 +165,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x2000a000 0x100>; interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 15>; + clocks = <&cru PCLK_GPIO6>; gpio-controller; #gpio-cells = <2>;
arch/arm/boot/dts/rk3188.dtsi +14 -4
@@ -15,6 +15,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/clock/rk3188-cru.h> #include "rk3xxx.dtsi" #include "rk3188-clocks.dtsi"
@@ -74,6 +75,15 @@ }; }; + cru: cru at 20000000 { + compatible = "rockchip,rk3188-cru"; + reg = <0x20000000 0x1000>; + rockchip,grf = <&grf>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + pinctrl at 20008000 { compatible = "rockchip,rk3188-pinctrl"; rockchip,grf = <&grf>;
@@ -87,7 +97,7 @@ compatible = "rockchip,rk3188-gpio-bank0"; reg = <0x2000a000 0x100>; interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 9>; + clocks = <&cru PCLK_GPIO0>; gpio-controller; #gpio-cells = <2>;
@@ -100,7 +110,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x2003c000 0x100>; interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 10>; + clocks = <&cru PCLK_GPIO1>; gpio-controller; #gpio-cells = <2>;
@@ -113,7 +123,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x2003e000 0x100>; interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 11>; + clocks = <&cru PCLK_GPIO2>; gpio-controller; #gpio-cells = <2>;
@@ -126,7 +136,7 @@ compatible = "rockchip,gpio-bank"; reg = <0x20080000 0x100>; interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_gates8 12>; + clocks = <&cru PCLK_GPIO3>; gpio-controller; #gpio-cells = <2>;
arch/arm/boot/dts/rk3xxx.dtsi +8 -8
@@ -60,14 +60,14 @@ compatible = "arm,cortex-a9-global-timer"; reg = <0x1013c200 0x20>; interrupts = <GIC_PPI 11 0x304>; - clocks = <&dummy150m>; + clocks = <&cru CORE_PERI>; }; local-timer at 1013c600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x1013c600 0x20>; interrupts = <GIC_PPI 13 0x304>; - clocks = <&dummy150m>; + clocks = <&cru CORE_PERI>; }; uart0: serial at 10124000 {
@@ -76,7 +76,7 @@ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <1>; - clocks = <&clk_gates1 8>; + clocks = <&cru SCLK_UART0>; status = "disabled"; };
@@ -86,7 +86,7 @@ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <1>; - clocks = <&clk_gates1 10>; + clocks = <&cru SCLK_UART1>; status = "disabled"; };
@@ -96,7 +96,7 @@ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <1>; - clocks = <&clk_gates1 12>; + clocks = <&cru SCLK_UART2>; status = "disabled"; };
@@ -106,7 +106,7 @@ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <1>; - clocks = <&clk_gates1 14>; + clocks = <&cru SCLK_UART3>; status = "disabled"; };
@@ -117,7 +117,7 @@ #address-cells = <1>; #size-cells = <0>; - clocks = <&clk_gates5 10>, <&clk_gates2 11>; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; clock-names = "biu", "ciu"; status = "disabled";
@@ -130,7 +130,7 @@ #address-cells = <1>; #size-cells = <0>; - clocks = <&clk_gates5 11>, <&clk_gates2 13>; + clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>; clock-names = "biu", "ciu"; status = "disabled";
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 10/13 ARM: dts: rockchip: move oscillator input clock into main dtsi
In reply to Heiko StübnerThe clock definitions get a lot shorter due to the soc clocks being handled by rk3188-cru and only the input clock remains. These can not simply live in the main rk3xxx.dtsi without affecting readability.
--- arch/arm/boot/dts/rk3066a-clocks.dtsi | 6 ------ arch/arm/boot/dts/rk3188-clocks.dtsi | 6 ------ arch/arm/boot/dts/rk3xxx.dtsi | 6 ++++++ 3 files changed, 6 insertions(+), 12 deletions(-)
arch/arm/boot/dts/rk3066a-clocks.dtsi +0 -6
@@ -31,12 +31,6 @@ #clock-cells = <0>; }; - xin24m: xin24m { - compatible = "fixed-clock"; - clock-frequency = <24000000>; - #clock-cells = <0>; - }; - dummy48m: dummy48m { compatible = "fixed-clock"; clock-frequency = <48000000>;
arch/arm/boot/dts/rk3188-clocks.dtsi +0 -6
@@ -31,12 +31,6 @@ #clock-cells = <0>; }; - xin24m: xin24m { - compatible = "fixed-clock"; - clock-frequency = <24000000>; - #clock-cells = <0>; - }; - dummy48m: dummy48m { compatible = "fixed-clock"; clock-frequency = <48000000>;
arch/arm/boot/dts/rk3xxx.dtsi +6 -0
@@ -26,6 +26,12 @@ compatible = "simple-bus"; ranges; + xin24m: xin24m { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + #clock-cells = <0>; + }; + scu at 1013c000 { compatible = "arm,cortex-a9-scu"; reg = <0x1013c000 0x100>;
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 11/13 arm: dts: rockchip: remove obsolete clock gate definitions
In reply to Heiko StübnerThe clock and reset unit is now provided by the rk3188-cru clock driver and thus the old style definitions of the gate clocks can go away.
--- arch/arm/boot/dts/rk3066a-clocks.dtsi | 293 ---------------------------------- arch/arm/boot/dts/rk3066a.dtsi | 1 - arch/arm/boot/dts/rk3188-clocks.dtsi | 283 -------------------------------- arch/arm/boot/dts/rk3188.dtsi | 1 - 4 files changed, 578 deletions(-) delete mode 100644 arch/arm/boot/dts/rk3066a-clocks.dtsi delete mode 100644 arch/arm/boot/dts/rk3188-clocks.dtsi
arch/arm/boot/dts/rk3066a-clocks.dtsi deleted +0 -293
@@ -1,293 +0,0 @@ -/* - * Copyright (c) 2013 MundoReader S.L. - * Author: Heiko Stuebner <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/ { - clocks { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - /* - * This is a dummy clock, to be used as placeholder on - * other mux clocks when a specific parent clock is not - * yet implemented. It should be dropped when the driver - * is complete. - */ - dummy: dummy { - compatible = "fixed-clock"; - clock-frequency = <0>; - #clock-cells = <0>; - }; - - dummy48m: dummy48m { - compatible = "fixed-clock"; - clock-frequency = <48000000>; - #clock-cells = <0>; - }; - - dummy150m: dummy150m { - compatible = "fixed-clock"; - clock-frequency = <150000000>; - #clock-cells = <0>; - }; - - clk_gates0: gate-clk at 200000d0 { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000d0 0x4>; - clocks = <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>; - - clock-output-names = - "gate_core_periph", "gate_cpu_gpll", - "gate_ddrphy", "gate_aclk_cpu", - "gate_hclk_cpu", "gate_pclk_cpu", - "gate_atclk_cpu", "gate_i2s0", - "gate_i2s0_frac", "gate_i2s1", - "gate_i2s1_frac", "gate_i2s2", - "gate_i2s2_frac", "gate_spdif", - "gate_spdif_frac", "gate_testclk"; - - #clock-cells = <1>; - }; - - clk_gates1: gate-clk at 200000d4 { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000d4 0x4>; - clocks = <&xin24m>, <&xin24m>, - <&xin24m>, <&dummy>, - <&dummy>, <&xin24m>, - <&xin24m>, <&dummy>, - <&xin24m>, <&dummy>, - <&xin24m>, <&dummy>, - <&xin24m>, <&dummy>, - <&xin24m>, <&dummy>; - - clock-output-names = - "gate_timer0", "gate_timer1", - "gate_timer2", "gate_jtag", - "gate_aclk_lcdc1_src", "gate_otgphy0", - "gate_otgphy1", "gate_ddr_gpll", - "gate_uart0", "gate_frac_uart0", - "gate_uart1", "gate_frac_uart1", - "gate_uart2", "gate_frac_uart2", - "gate_uart3", "gate_frac_uart3"; - - #clock-cells = <1>; - }; - - clk_gates2: gate-clk at 200000d8 { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000d8 0x4>; - clocks = <&clk_gates2 1>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&clk_gates2 3>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy48m>, - <&dummy>, <&dummy48m>, - <&dummy>, <&dummy>; - - clock-output-names = - "gate_periph_src", "gate_aclk_periph", - "gate_hclk_periph", "gate_pclk_periph", - "gate_smc", "gate_mac", - "gate_hsadc", "gate_hsadc_frac", - "gate_saradc", "gate_spi0", - "gate_spi1", "gate_mmc0", - "gate_mac_lbtest", "gate_mmc1", - "gate_emmc", "gate_tsadc"; - - #clock-cells = <1>; - }; - - clk_gates3: gate-clk at 200000dc { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000dc 0x4>; - clocks = <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>, <&dummy>; - - clock-output-names = - "gate_aclk_lcdc0_src", "gate_dclk_lcdc0", - "gate_dclk_lcdc1", "gate_pclkin_cif0", - "gate_pclkin_cif1", "reserved", - "reserved", "gate_cif0_out", - "gate_cif1_out", "gate_aclk_vepu", - "gate_hclk_vepu", "gate_aclk_vdpu", - "gate_hclk_vdpu", "gate_gpu_src", - "reserved", "gate_xin27m"; - - #clock-cells = <1>; - }; - - clk_gates4: gate-clk at 200000e0 { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000e0 0x4>; - clocks = <&clk_gates2 2>, <&clk_gates2 3>, - <&clk_gates2 1>, <&clk_gates2 1>, - <&clk_gates2 1>, <&clk_gates2 2>, - <&clk_gates2 2>, <&clk_gates2 2>, - <&clk_gates0 4>, <&clk_gates0 4>, - <&clk_gates0 3>, <&clk_gates0 3>, - <&clk_gates0 3>, <&clk_gates2 3>, - <&clk_gates0 4>; - - clock-output-names = - "gate_hclk_peri_axi_matrix", "gate_pclk_peri_axi_matrix", - "gate_aclk_cpu_peri", "gate_aclk_peri_axi_matrix", - "gate_aclk_pei_niu", "gate_hclk_usb_peri", - "gate_hclk_peri_ahb_arbi", "gate_hclk_emem_peri", - "gate_hclk_cpubus", "gate_hclk_ahb2apb", - "gate_aclk_strc_sys", "gate_aclk_l2mem_con", - "gate_aclk_intmem", "gate_pclk_tsadc", - "gate_hclk_hdmi"; - - #clock-cells = <1>; - }; - - clk_gates5: gate-clk at 200000e4 { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000e4 0x4>; - clocks = <&clk_gates0 3>, <&clk_gates2 1>, - <&clk_gates0 5>, <&clk_gates0 5>, - <&clk_gates0 5>, <&clk_gates0 5>, - <&clk_gates0 4>, <&clk_gates0 5>, - <&clk_gates2 1>, <&clk_gates2 2>, - <&clk_gates2 2>, <&clk_gates2 2>, - <&clk_gates2 2>, <&clk_gates4 5>, - <&clk_gates4 5>, <&dummy>; - - clock-output-names = - "gate_aclk_dmac1", "gate_aclk_dmac2", - "gate_pclk_efuse", "gate_pclk_tzpc", - "gate_pclk_grf", "gate_pclk_pmu", - "gate_hclk_rom", "gate_pclk_ddrupctl", - "gate_aclk_smc", "gate_hclk_nandc", - "gate_hclk_mmc0", "gate_hclk_mmc1", - "gate_hclk_emmc", "gate_hclk_otg0", - "gate_hclk_otg1", "gate_aclk_gpu"; - - #clock-cells = <1>; - }; - - clk_gates6: gate-clk at 200000e8 { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000e8 0x4>; - clocks = <&clk_gates3 0>, <&clk_gates0 4>, - <&clk_gates0 4>, <&clk_gates1 4>, - <&clk_gates0 4>, <&clk_gates3 0>, - <&clk_gates0 4>, <&clk_gates1 4>, - <&clk_gates3 0>, <&clk_gates0 4>, - <&clk_gates0 4>, <&clk_gates1 4>, - <&clk_gates0 4>, <&clk_gates3 0>, - <&dummy>, <&dummy>; - - clock-output-names = - "gate_aclk_lcdc0", "gate_hclk_lcdc0", - "gate_hclk_lcdc1", "gate_aclk_lcdc1", - "gate_hclk_cif0", "gate_aclk_cif0", - "gate_hclk_cif1", "gate_aclk_cif1", - "gate_aclk_ipp", "gate_hclk_ipp", - "gate_hclk_rga", "gate_aclk_rga", - "gate_hclk_vio_bus", "gate_aclk_vio0", - "gate_aclk_vcodec", "gate_shclk_vio_h2h"; - - #clock-cells = <1>; - }; - - clk_gates7: gate-clk at 200000ec { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000ec 0x4>; - clocks = <&clk_gates2 2>, <&clk_gates0 4>, - <&clk_gates0 4>, <&clk_gates0 4>, - <&clk_gates0 4>, <&clk_gates2 2>, - <&clk_gates2 2>, <&clk_gates0 5>, - <&clk_gates0 5>, <&clk_gates0 5>, - <&clk_gates0 5>, <&clk_gates2 3>, - <&clk_gates2 3>, <&clk_gates2 3>, - <&clk_gates2 3>, <&clk_gates2 3>; - - clock-output-names = - "gate_hclk_emac", "gate_hclk_spdif", - "gate_hclk_i2s0_2ch", "gate_hclk_i2s1_2ch", - "gate_hclk_i2s_8ch", "gate_hclk_hsadc", - "gate_hclk_pidf", "gate_pclk_timer0", - "gate_pclk_timer1", "gate_pclk_timer2", - "gate_pclk_pwm01", "gate_pclk_pwm23", - "gate_pclk_spi0", "gate_pclk_spi1", - "gate_pclk_saradc", "gate_pclk_wdt"; - - #clock-cells = <1>; - }; - - clk_gates8: gate-clk at 200000f0 { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000f0 0x4>; - clocks = <&clk_gates0 5>, <&clk_gates0 5>, - <&clk_gates2 3>, <&clk_gates2 3>, - <&clk_gates0 5>, <&clk_gates0 5>, - <&clk_gates2 3>, <&clk_gates2 3>, - <&clk_gates2 3>, <&clk_gates0 5>, - <&clk_gates0 5>, <&clk_gates0 5>, - <&clk_gates2 3>, <&clk_gates2 3>, - <&dummy>, <&clk_gates0 5>; - - clock-output-names = - "gate_pclk_uart0", "gate_pclk_uart1", - "gate_pclk_uart2", "gate_pclk_uart3", - "gate_pclk_i2c0", "gate_pclk_i2c1", - "gate_pclk_i2c2", "gate_pclk_i2c3", - "gate_pclk_i2c4", "gate_pclk_gpio0", - "gate_pclk_gpio1", "gate_pclk_gpio2", - "gate_pclk_gpio3", "gate_pclk_gpio4", - "reserved", "gate_pclk_gpio6"; - - #clock-cells = <1>; - }; - - clk_gates9: gate-clk at 200000f4 { - compatible = "rockchip,rk2928-gate-clk"; - reg = <0x200000f4 0x4>; - clocks = <&dummy>, <&clk_gates0 5>, - <&dummy>, <&dummy>, - <&dummy>, <&clk_gates1 4>, - <&clk_gates0 5>, <&dummy>, - <&dummy>, <&dummy>, - <&dummy>; - - clock-output-names = - "gate_clk_core_dbg", "gate_pclk_dbg", - "gate_clk_trace", "gate_atclk", - "gate_clk_l2c", "gate_aclk_vio1", - "gate_pclk_publ", "gate_aclk_intmem0", - "gate_aclk_intmem1", "gate_aclk_intmem2", - "gate_aclk_intmem3"; - - #clock-cells = <1>; - }; - }; - -};
arch/arm/boot/dts/rk3066a.dtsi +0 -1
@@ -17,7 +17,6 @@ #include <dt-bindings/pinctrl/rockchip.h> #include <dt-bindings/clock/rk3066a-cru.h> #include "rk3xxx.dtsi" -#include "rk3066a-clocks.dtsi" / { compatible = "rockchip,rk3066a";
arch/arm/boot/dts/rk3188-clocks.dtsi deleted +0 -283
283 lines not on this page · raw message
arch/arm/boot/dts/rk3188.dtsi +0 -1
@@ -17,7 +17,6 @@ #include <dt-bindings/pinctrl/rockchip.h> #include <dt-bindings/clock/rk3188-cru.h> #include "rk3xxx.dtsi" -#include "rk3188-clocks.dtsi" / { compatible = "rockchip,rk3188";
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 12/13 clk: rockchip: add clock controller for rk3288
In reply to Heiko StübnerAdd the clock tree definition for the new rk3288 SoC.
--- drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk-rk3288.c | 717 +++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 9 + include/dt-bindings/clock/rk3288-cru.h | 278 +++++++++++++ 4 files changed, 1005 insertions(+) create mode 100644 drivers/clk/rockchip/clk-rk3288.c create mode 100644 include/dt-bindings/clock/rk3288-cru.h
drivers/clk/rockchip/Makefile +1 -0
@@ -8,3 +8,4 @@ obj-y += clk-pll.o obj-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-y += clk-rk3188.o +obj-y += clk-rk3288.o
drivers/clk/rockchip/clk-rk3288.c new file +717 -0
717 lines not on this page · raw message
drivers/clk/rockchip/clk.h +9 -0
@@ -40,6 +40,15 @@#define RK2928_SOFTRST_CON (x) (x * 0x4 + 0x110)#define RK2928_MISC_CON 0x134 +#define RK3288_PLL_CON (x) RK2928_PLL_CON(x) +#define RK3288_MODE_CON 0x50 +#define RK3288_CLKSEL_CON (x) (x * 0x4 + 0x60) +#define RK3288_CLKGATE_CON (x) (x * 0x4 + 0x160) +#define RK3288_GLB_SRST_FST 0x1b0 +#define RK3288_GLB_SRST_SND 0x1b4 +#define RK3288_SOFTRST_CON (x) (x * 0x4 + 0x1b8) +#define RK3288_MISC_CON 0x1e8 +enum rockchip_pll_type { pll_rk3066, };
include/dt-bindings/clock/rk3288-cru.h new file +278 -0
278 lines not on this page · raw message
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH v4 13/13 dt-bindings: add documentation for rk3288 cru
In reply to Heiko StübnerThis adds the dt-binding documentation for the clock and reset unit found on Rockchip rk3288 SoCs.
--- .../bindings/clock/rockchip,rk3288-cru.txt | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt new file +61 -0
@@ -0,0 +1,61 @@ +* Rockchip RK3288 Clock and Reset Unit + +The RK3288 clock controller generates and supplies clock to various +controllers within the SoC and also implements a reset controller for SoC +peripherals. + +Required Properties: + +- compatible: should be "rockchip,rk3288-cru" +- reg: physical base address of the controller and length of memory mapped + region. +- #clock-cells: should be 1. +- #reset-cells: should be 1. + +Optional Properties: + +- rockchip,grf: phandle to the syscon managing the "general register files" + If missing pll rates are not changable, due to the missing pll lock status. + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. All available clocks are defined as +preprocessor macros in the dt-bindings/clock/rk3288-cru.h headers and can be +used in device tree sources. Similar macros exist for the reset sources in +these files. + +External clocks: + +There are several clocks that are generated outside the SoC. It is expected +that they are defined using standard clock bindings with following +clock-output-names: + - "xin24m" - crystal input - required, + - "xin32k" - rtc clock - optional, + - "ext_i2s" - external I2S clock - optional, + - "ext_hsadc" - external HSADC clock - optional, + - "ext_edp_24m" - external display port clock - optional, + - "ext_vip" - external VIP clock - optional, + - "ext_isp" - external ISP clock - optional, + - "ext_jtag" - external JTAG clock - optional + +Example: Clock controller node: + + cru: cru at 20000000 { + compatible = "rockchip,rk3188-cru"; + reg = <0x20000000 0x1000>; + rockchip,grf = <&grf>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + +Example: UART controller node that consumes the clock generated by the clock + controller: + + uart0: serial at 10124000 { + compatible = "snps,dw-apb-uart"; + reg = <0x10124000 0x400>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&cru SCLK_UART0>; + };
Signature · 1 line
1.9.0
v4 cover Clock support for rk3066,rk3188 and rk3288
In reply to Heiko StübnerHi Heiko,
Quoted 17 lines · Heiko St?bner
This series adds a clock driver infrastructure for Rockchip SoCs in general and clock-definitions for the RK3188 and RK3288 in particular.
The previous attempt to define parts separately in the devicetree did not really fit with the clock structure, which became apparent with more knowledge about the clock tree.
The whole structure should support Rockchip SoCs at least down to the RK28xx (ARM9) which all share a very similar setup of their clock controllers in PLL, divider and gate handling as well as the included softreset parts.
A big change is the move from declaring all mux/dividers/gates individually to declaring them as composite clock branches, making the code better readable and making it possible to keep clocks together in a more natural order.
Quoted 5 lines
The changes under
drivers/clkapply cleanly to clk-next but the changes in arm/boot/dts require patches from arm-soc, so in the unlikely case of this making it in before the merge window the dts patches should go through arm-soc (or should do so anyway, as they do not directly depend on thedrivers/clkchanges)
Series:
on Radxa Rock (RK3188).
Cheers,
Max