Exynos clock clean-up for 3.12
Subsystems (6)
cover Exynos clock clean-up for 3.12
This series fixes various functional and non-functional (e.g. stylistic) issues in Common Clock Framework drivers for Samsung Exynos SoCs. See particular patches for more detailed descriptions.
Tomasz Figa (16):
pwm: samsung: Update DT bindings documentation to cover clocks
ARM: dts: exynos4: Specify PWM clocks in PWM node
clocksource: samsung_pwm_timer: Get clock from device tree
clk: samsung: exynos4: Use separate aliases for cpufreq related clocks
clk: samsung: Modify _get_rate() helper to use __clk_lookup()
clk: samsung: exynos4: Remove unused static clkdev aliases
clk: samsung: exynos4: Remove checks for DT node
clk: samsung: exynos4: Rename exynos4_plls to exynos4x12_plls
clk: samsung: pll: Use new registration method for PLL45xx
clk: samsung: pll: Add support for rate configuration of PLL45xx
clk: samsung: pll: Use new registration method for PLL46xx
clk: samsung: pll: Add support for rate configuration of PLL46xx
clk: samsung: exynos4: Reorder registration of mout_vpllsrc
clk: samsung: exynos4: Register PLL rate tables for Exynos4210
clk: samsung: exynos4: Register PLL rate tables for Exynos4x12
clk: samsung: exynos5250: Simplify registration of PLL rate tables
.../devicetree/bindings/pwm/pwm-samsung.txt | 12 + arch/arm/boot/dts/exynos4.dtsi | 2 + drivers/clk/samsung/clk-exynos4.c | 539 ++++++++++++--------- drivers/clk/samsung/clk-exynos5250.c | 12 +- drivers/clk/samsung/clk-exynos5440.c | 2 +- drivers/clk/samsung/clk-pll.c | 284 ++++++++--- drivers/clk/samsung/clk-pll.h | 59 ++- drivers/clk/samsung/clk.c | 10 +- drivers/clocksource/samsung_pwm_timer.c | 12 +- 9 files changed, 601 insertions(+), 331 deletions(-)
Signature · 1 line
1.8.3.2
PATCH 1/16 pwm: samsung: Update DT bindings documentation to cover clocks
PWM driver consumes at least one and up to three clocks, which need to be specified in device tree when used. This patch updates bindings documentation to add information about clocks.
--- Documentation/devicetree/bindings/pwm/pwm-samsung.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+)
Documentation/devicetree/bindings/pwm/pwm-samsung.txt +12 -0
@@ -19,6 +19,16 @@ Required properties: - reg: base address and size of register area - interrupts: list of timer interrupts (one interrupt per timer, starting at timer 0) +- clock-names: should contain all following required clock names: + - "timers" - PWM base clock used to generate PWM signals, + and any subset of following optional clock names: + - "pwm-tclk0" - first external PWM clock source, + - "pwm-tclk1" - second external PWM clock source. + Note that not all IP variants allow using all external clock sources. + Refer to SoC documentation to learn which clock source configurations + are available. +- clocks: should contain clock specifiers of all clocks, which input names + have been specified in clock-names property, in same order. - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED.
@@ -34,6 +44,8 @@ Example: reg = <0x7f006000 0x1000>; interrupt-parent = <&vic0>; interrupts = <23>, <24>, <25>, <27>, <28>; + clocks = <&clock 67>; + clock-names = "timers"; samsung,pwm-outputs = <0>, <1>; #pwm-cells = <3>; }
Signature · 1 line
1.8.3.2
PATCH 1/16 pwm: samsung: Update DT bindings documentation to cover clocks
Quoted 5 lines · Tomasz Figa
PWM driver consumes at least one and up to three clocks, which need to be specified in device tree when used. This patch updates bindings documentation to add information about clocks.
Documentation/devicetree/bindings/pwm/pwm-samsung.txt Required properties: · line 29
Quoted 9 lines
Documentation/devicetree/bindings/pwm/pwm-samsung.txt +8
-0+- clock-names: should contain all following required clock names: + - "timers" - PWM base clock used to generate PWM signals, + and any subset of following optional clock names: + - "pwm-tclk0" - first external PWM clock source, + - "pwm-tclk1" - second external PWM clock source. + Note that not all IP variants allow using all external clock sources. + Refer to SoC documentation to learn which clock source configurations + are available.
It might be nice to explicitly enumerate which variants (or rather, I suppose which exact compatible values) support which optional clocks. However, I suppose it's fine to just say "go read the HW manual" instead.
So, this patch,
(although this patch isn't backwards-compatible since before now, DT nodes didn't need to provide any entries in clocks)
PATCH 1/16 pwm: samsung: Update DT bindings documentation to cover clocks
Quoted 8 lines · On Tuesday 20 of August 2013 14:34:30 Stephen Warren wrote:
Quoted 7 lines · Tomasz Figa
PWM driver consumes at least one and up to three clocks, which need to be specified in device tree when used. This patch updates bindings documentation to add information about clocks.
Documentation/devicetree/bindings/pwm/pwm-samsung.txt +0
-0
Quoted 13 lines
Quoted 8 lines
+- clock-names: should contain all following required clock names:
Documentation/devicetree/bindings/pwm/pwm-samsung.txt +5
-0+ - "timers" - PWM base clock used to generate PWM signals, + and any subset of following optional clock names: + - "pwm-tclk0" - first external PWM clock source, + - "pwm-tclk1" - second external PWM clock source. + Note that not all IP variants allow using all external clocksources. + Refer to SoC documentation to learn which clock source configurations + are available.
It might be nice to explicitly enumerate which variants (or rather, I suppose which exact compatible values) support which optional clocks. However, I suppose it's fine to just say "go read the HW manual" instead.
I don't have enough information about some of the variants, so I decided to put it this way, instead of making an incomplete list or speculating about things.
Quoted 2 lines
So, this patch,
Acked-by Stephen Warren <[email protected]>
Thanks.
Quoted 2 lines
(although this patch isn't backwards-compatible since before now, DT nodes didn't need to provide any entries in clocks)
The thing is that the clocks were supposed to be there from the beginning, but in a hurry I forgot to specify them in original bindings documentation and things were running over compatibility clkdev aliases anyway, so nobody (including me) noticed.
Best regards,
Tomasz
PATCH 2/16 ARM: dts: exynos4: Specify PWM clocks in PWM node
In reply to Tomasz FigaSince pwm-samsung bindings require at least one clock to be specified, this patch adds the missing clocks and clock-names properties to specify clocks used by PWM block on Exynos4 SoCs.
--- arch/arm/boot/dts/exynos4.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/boot/dts/exynos4.dtsi +2 -0
@@ -448,6 +448,8 @@ compatible = "samsung,exynos4210-pwm"; reg = <0x139D0000 0x1000>; interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>; + clocks = <&clock 336>; + clock-names = "timers"; #pwm-cells = <2>; status = "disabled"; };
Signature · 1 line
1.8.3.2
PATCH 3/16 clocksource: samsung_pwm_timer: Get clock from device tree
In reply to Tomasz FigaWhen booting with device tree static clkdev aliases should not be used. This patch modifies the samsung_pwm_timer driver to use DT-based clock lookup when booting with device tree.
--- drivers/clocksource/samsung_pwm_timer.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/clocksource/samsung_pwm_timer.c +8 -4
@@ -368,10 +368,6 @@ static void __init samsung_clocksource_init(void)static void __init samsung_timer_resources (void ) { - pwm.timerclk =clk_get (NULL ,"timers" ); -if (IS_ERR (pwm.timerclk)) -panic ("failed to get timers clock for timer" ); -clk_prepare_enable (pwm.timerclk); pwm.tcnt_max = (1UL << pwm.variant.bits) -1 ;
@@ -416,6 +412,10 @@ void __init samsung_pwm_clocksource_init(void __iomem *base,memcpy (&pwm.variant, variant,sizeof (pwm.variant));memcpy (pwm.irq, irqs,SAMSUNG_PWM_NUM *sizeof (*irqs)); + pwm.timerclk =clk_get (NULL ,"timers" ); +if (IS_ERR (pwm.timerclk)) +panic ("failed to get timers clock for timer" ); +_samsung_pwm_clocksource_init (); }
@@ -447,6 +447,10 @@ static void __init samsung_pwm_alloc(struct device_node *np,return ; } + pwm.timerclk =of_clk_get_by_name (np,"timers" ); +if (IS_ERR (pwm.timerclk)) +panic ("failed to get timers clock for timer" ); +_samsung_pwm_clocksource_init (); }
Signature · 1 line
1.8.3.2
PATCH 4/16 clk: samsung: exynos4: Use separate aliases for cpufreq related clocks
In reply to Tomasz FigaExynos cpufreq driver is the only remaining piece of code that needs static clkdev aliases for operation, because it can not do device tree based clock lookups yet.
This patch moves clock alias definitions for those clocks to separate arrays that can be used with samsung_clk_register_alias() helper.
--- drivers/clk/samsung/clk-exynos4.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
drivers/clk/samsung/clk-exynos4.c +27 -8
@@ -392,9 +392,8 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {MUX (none,"mout_g2d" , mout_g2d_p,E4210_SRC_IMAGE ,8 ,1 ),MUX (none,"mout_fimd1" , group1_p4210,E4210_SRC_LCD1 ,0 ,4 ),MUX (none,"mout_mipi1" , group1_p4210,E4210_SRC_LCD1 ,12 ,4 ), -MUX_A (sclk_mpll,"sclk_mpll" , mout_mpll_p,SRC_CPU ,8 ,1 ,"mout_mpll" ), -MUX_A (mout_core,"mout_core" , mout_core_p4210, -SRC_CPU ,16 ,1 ,"moutcore" ), +MUX (sclk_mpll,"sclk_mpll" , mout_mpll_p,SRC_CPU ,8 ,1 ), +MUX (mout_core,"mout_core" , mout_core_p4210,SRC_CPU ,16 ,1 ),MUX_A (sclk_vpll,"sclk_vpll" , sclk_vpll_p4210,SRC_TOP0 ,8 ,1 ,"sclk_vpll" ), MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4),
@@ -431,8 +430,8 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {/* list of mux clocks supported in exynos4x12 soc */ static struct samsung_mux_clock exynos4x12_mux_clks[]__initdata = { -MUX_A (mout_mpll_user_c,"mout_mpll_user_c" , mout_mpll_user_p4x12, -SRC_CPU ,24 ,1 ,"mout_mpll" ), +MUX (mout_mpll_user_c,"mout_mpll_user_c" , mout_mpll_user_p4x12, +SRC_CPU ,24 ,1 ),MUX (none,"mout_aclk266_gps" , aclk_p4412,SRC_TOP1 ,4 ,1 ),MUX (none,"mout_aclk400_mcuisp" , aclk_p4412,SRC_TOP1 ,8 ,1 ), MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12,
@@ -456,8 +455,7 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { SRC_DMC, 12, 1, "sclk_mpll"),MUX_A (sclk_vpll,"sclk_vpll" , mout_vpll_p,SRC_TOP0 ,8 ,1 ,"sclk_vpll" ), -MUX_A (mout_core,"mout_core" , mout_core_p4x12, -SRC_CPU ,16 ,1 ,"moutcore" ), +MUX (mout_core,"mout_core" , mout_core_p4x12,SRC_CPU ,16 ,1 ),MUX (mout_fimc0,"mout_fimc0" , group1_p4x12,SRC_CAM ,0 ,4 ),MUX (mout_fimc1,"mout_fimc1" , group1_p4x12,SRC_CAM ,4 ,4 ), MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4),
@@ -545,7 +543,7 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {DIV (none,"div_spi_pre2" ,"div_spi2" ,DIV_PERIL2 ,8 ,8 ),DIV (none,"div_audio1" ,"mout_audio1" ,DIV_PERIL4 ,0 ,4 ),DIV (none,"div_audio2" ,"mout_audio2" ,DIV_PERIL4 ,16 ,4 ), -DIV_A (arm_clk,"arm_clk" ,"div_core2" ,DIV_CPU0 ,28 ,3 ,"armclk" ), +DIV (arm_clk,"arm_clk" ,"div_core2" ,DIV_CPU0 ,28 ,3 ),DIV_A (sclk_apll,"sclk_apll" ,"mout_apll" ,DIV_CPU0 ,24 ,3 ,"sclk_apll" ), DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4,
@@ -930,6 +928,20 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { GATE(tmu_apbif, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0, 0), }; +static struct samsung_clock_alias exynos4_aliases[]__initdata = { +ALIAS (mout_core,NULL ,"moutcore" ), +ALIAS (arm_clk,NULL ,"armclk" ), +ALIAS (sclk_apll,NULL ,"mout_apll" ), +}; + +static struct samsung_clock_alias exynos4210_aliases[]__initdata = { +ALIAS (sclk_mpll,NULL ,"mout_mpll" ), +}; + +static struct samsung_clock_alias exynos4x12_aliases[]__initdata = { +ALIAS (mout_mpll_user_c,NULL ,"mout_mpll" ), +}; +/* * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit * resides in chipid register space, outside of the clock controller memory
@@ -1065,6 +1077,8 @@ static void __init exynos4_clk_init(struct device_node *np, ARRAY_SIZE(exynos4210_div_clks));samsung_clk_register_gate (exynos4210_gate_clks,ARRAY_SIZE (exynos4210_gate_clks)); +samsung_clk_register_alias (exynos4210_aliases, +ARRAY_SIZE (exynos4210_aliases)); }else {samsung_clk_register_mux (exynos4x12_mux_clks,ARRAY_SIZE (exynos4x12_mux_clks));
@@ -1072,8 +1086,13 @@ static void __init exynos4_clk_init(struct device_node *np, ARRAY_SIZE(exynos4x12_div_clks));samsung_clk_register_gate (exynos4x12_gate_clks,ARRAY_SIZE (exynos4x12_gate_clks)); +samsung_clk_register_alias (exynos4x12_aliases, +ARRAY_SIZE (exynos4x12_aliases)); } +samsung_clk_register_alias (exynos4_aliases, +ARRAY_SIZE (exynos4_aliases)); + pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
Signature · 1 line
1.8.3.2
PATCH 5/16 clk: samsung: Modify _get_rate() helper to use __clk_lookup()
In reply to Tomasz FigaThere is no need to use clkdev inside the clock driver to retrieve the clocks for internal use. Instead __clk_lookup() helper can be used to look up clocks by their platform name.
This patch modifies the behavior of _get_rate() helper to look up clocks by platform name and adjusts all users of it to pass platform names instead of clkdev aliases.
--- drivers/clk/samsung/clk-exynos4.c | 4 ++-- drivers/clk/samsung/clk-exynos5440.c | 2 +- drivers/clk/samsung/clk.c | 10 ++++------ 3 files changed, 7 insertions(+), 9 deletions(-)
drivers/clk/samsung/clk-exynos4.c +2 -2
@@ -1096,9 +1096,9 @@ static void __init exynos4_clk_init(struct device_node *np,pr_info ("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n" , exynos4_soc ==EXYNOS4210 ?"Exynos4210" :"Exynos4x12" , -_get_rate ("sclk_apll" ),_get_rate ("mout_mpll" ), +_get_rate ("sclk_apll" ),_get_rate ("sclk_mpll" ),_get_rate ("sclk_epll" ),_get_rate ("sclk_vpll" ), -_get_rate ("armclk" )); +_get_rate ("arm_clk" )); }
drivers/clk/samsung/clk-exynos5440.c +1 -1
@@ -132,7 +132,7 @@ static void __init exynos5440_clk_init(struct device_node *np)samsung_clk_register_gate (exynos5440_gate_clks,ARRAY_SIZE (exynos5440_gate_clks)); -pr_info ("Exynos5440: arm_clk = %ldHz\n" ,_get_rate ("armclk" )); +pr_info ("Exynos5440: arm_clk = %ldHz\n" ,_get_rate ("arm_clk" ));pr_info ("exynos5440 clock initialization complete\n" ); }CLK_OF_DECLARE (exynos5440_clk,"samsung,exynos5440-clock" , exynos5440_clk_init);
drivers/clk/samsung/clk.c +4 -6
@@ -307,14 +307,12 @@ void __init samsung_clk_of_register_fixed_ext(unsigned long _get_rate (const char *clk_name) {struct clk *clk; -unsigned long rate; - clk =clk_get (NULL , clk_name); -if (IS_ERR (clk)) { + clk =__clk_lookup (clk_name); +if (!clk) {pr_err ("%s: could not find clock %s\n" , __func__, clk_name);return 0 ; } - rate =clk_get_rate (clk); -clk_put (clk); -return rate; + +return clk_get_rate (clk); }
Signature · 1 line
1.8.3.2
PATCH 6/16 clk: samsung: exynos4: Remove unused static clkdev aliases
In reply to Tomasz FigaSince Exynos does not support legacy non-DT boot anymore, most of clock lookups happen using device tree, so most of static clkdev aliases are no longer necessary. This patch removes them.
--- drivers/clk/samsung/clk-exynos4.c | 356 ++++++++++++++++++-------------------- 1 file changed, 172 insertions(+), 184 deletions(-)
drivers/clk/samsung/clk-exynos4.c +172 -184
@@ -374,7 +374,7 @@ static struct samsung_mux_clock exynos4_mux_clks[] __initdata = { CLK_SET_RATE_PARENT, 0),MUX (none,"mout_spdif" , mout_spdif_p,SRC_PERIL1 ,8 ,2 ),MUX (none,"mout_onenand1" , mout_onenand1_p,SRC_TOP0 ,0 ,1 ), -MUX_A (sclk_epll,"sclk_epll" , mout_epll_p,SRC_TOP0 ,4 ,1 ,"sclk_epll" ), +MUX (sclk_epll,"sclk_epll" , mout_epll_p,SRC_TOP0 ,4 ,1 ), MUX(none, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1), };
@@ -394,8 +394,7 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {MUX (none,"mout_mipi1" , group1_p4210,E4210_SRC_LCD1 ,12 ,4 ),MUX (sclk_mpll,"sclk_mpll" , mout_mpll_p,SRC_CPU ,8 ,1 ),MUX (mout_core,"mout_core" , mout_core_p4210,SRC_CPU ,16 ,1 ), -MUX_A (sclk_vpll,"sclk_vpll" , sclk_vpll_p4210, -SRC_TOP0 ,8 ,1 ,"sclk_vpll" ), +MUX (sclk_vpll,"sclk_vpll" , sclk_vpll_p4210,SRC_TOP0 ,8 ,1 ),MUX (mout_fimc0,"mout_fimc0" , group1_p4210,SRC_CAM ,0 ,4 ),MUX (mout_fimc1,"mout_fimc1" , group1_p4210,SRC_CAM ,4 ,4 ), MUX(mout_fimc2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4),
@@ -451,10 +450,8 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {MUX (none,"mout_jpeg0" , sclk_ampll_p4x12,E4X12_SRC_CAM1 ,0 ,1 ),MUX (none,"mout_jpeg1" , sclk_evpll_p,E4X12_SRC_CAM1 ,4 ,1 ),MUX (none,"mout_jpeg" , mout_jpeg_p,E4X12_SRC_CAM1 ,8 ,1 ), -MUX_A (sclk_mpll,"sclk_mpll" , mout_mpll_p, -SRC_DMC ,12 ,1 ,"sclk_mpll" ), -MUX_A (sclk_vpll,"sclk_vpll" , mout_vpll_p, -SRC_TOP0 ,8 ,1 ,"sclk_vpll" ), +MUX (sclk_mpll,"sclk_mpll" , mout_mpll_p,SRC_DMC ,12 ,1 ), +MUX (sclk_vpll,"sclk_vpll" , mout_vpll_p,SRC_TOP0 ,8 ,1 ),MUX (mout_core,"mout_core" , mout_core_p4x12,SRC_CPU ,16 ,1 ),MUX (mout_fimc0,"mout_fimc0" , group1_p4x12,SRC_CAM ,0 ,4 ), MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4),
@@ -544,8 +541,7 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {DIV (none,"div_audio1" ,"mout_audio1" ,DIV_PERIL4 ,0 ,4 ),DIV (none,"div_audio2" ,"mout_audio2" ,DIV_PERIL4 ,16 ,4 ),DIV (arm_clk,"arm_clk" ,"div_core2" ,DIV_CPU0 ,28 ,3 ), -DIV_A (sclk_apll,"sclk_apll" ,"mout_apll" , -DIV_CPU0 ,24 ,3 ,"sclk_apll" ), +DIV (sclk_apll,"sclk_apll" ,"mout_apll" ,DIV_CPU0 ,24 ,3 ),DIV_F (none,"div_mipi_pre0" ,"div_mipi0" ,DIV_LCD0 ,20 ,4 ,CLK_SET_RATE_PARENT ,0 ), DIV_F(none, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8,
@@ -634,160 +630,147 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = { CLK_SET_RATE_PARENT, 0),GATE (sclk_audio1,"sclk_audio1" ,"div_audio1" ,SRC_MASK_PERIL1 ,0 ,CLK_SET_RATE_PARENT ,0 ), -GATE_D (vp,"s5p-mixer" ,"vp" ,"aclk160" ,GATE_IP_TV ,0 ,0 ,0 ), -GATE_D (mixer,"s5p-mixer" ,"mixer" ,"aclk160" ,GATE_IP_TV ,1 ,0 ,0 ), -GATE_D (hdmi,"exynos4-hdmi" ,"hdmi" ,"aclk160" ,GATE_IP_TV ,3 ,0 ,0 ), -GATE_A (pwm,"pwm" ,"aclk100" ,GATE_IP_PERIL ,24 ,0 ,0 ,"timers" ), -GATE_A (sdmmc4,"sdmmc4" ,"aclk133" ,GATE_IP_FSYS ,9 ,0 ,0 ,"biu" ), -GATE_A (usb_host,"usb_host" ,"aclk133" , -GATE_IP_FSYS ,12 ,0 ,0 ,"usbhost" ), -GATE_DA (sclk_fimc0,"exynos4-fimc.0" ,"sclk_fimc0" ,"div_fimc0" , -SRC_MASK_CAM ,0 ,CLK_SET_RATE_PARENT ,0 ,"sclk_fimc" ), -GATE_DA (sclk_fimc1,"exynos4-fimc.1" ,"sclk_fimc1" ,"div_fimc1" , -SRC_MASK_CAM ,4 ,CLK_SET_RATE_PARENT ,0 ,"sclk_fimc" ), -GATE_DA (sclk_fimc2,"exynos4-fimc.2" ,"sclk_fimc2" ,"div_fimc2" , -SRC_MASK_CAM ,8 ,CLK_SET_RATE_PARENT ,0 ,"sclk_fimc" ), -GATE_DA (sclk_fimc3,"exynos4-fimc.3" ,"sclk_fimc3" ,"div_fimc3" , -SRC_MASK_CAM ,12 ,CLK_SET_RATE_PARENT ,0 ,"sclk_fimc" ), -GATE_DA (sclk_csis0,"s5p-mipi-csis.0" ,"sclk_csis0" ,"div_csis0" , -SRC_MASK_CAM ,24 ,CLK_SET_RATE_PARENT ,0 ,"sclk_csis" ), -GATE_DA (sclk_csis1,"s5p-mipi-csis.1" ,"sclk_csis1" ,"div_csis1" , -SRC_MASK_CAM ,28 ,CLK_SET_RATE_PARENT ,0 ,"sclk_csis" ), -GATE_DA (sclk_fimd0,"exynos4-fb.0" ,"sclk_fimd0" ,"div_fimd0" , -SRC_MASK_LCD0 ,0 ,CLK_SET_RATE_PARENT ,0 ,"sclk_fimd" ), -GATE_DA (sclk_mmc0,"exynos4-sdhci.0" ,"sclk_mmc0" ,"div_mmc_pre0" , -SRC_MASK_FSYS ,0 ,CLK_SET_RATE_PARENT ,0 , -"mmc_busclk.2" ), -GATE_DA (sclk_mmc1,"exynos4-sdhci.1" ,"sclk_mmc1" ,"div_mmc_pre1" , -SRC_MASK_FSYS ,4 ,CLK_SET_RATE_PARENT ,0 , -"mmc_busclk.2" ), -GATE_DA (sclk_mmc2,"exynos4-sdhci.2" ,"sclk_mmc2" ,"div_mmc_pre2" , -SRC_MASK_FSYS ,8 ,CLK_SET_RATE_PARENT ,0 , -"mmc_busclk.2" ), -GATE_DA (sclk_mmc3,"exynos4-sdhci.3" ,"sclk_mmc3" ,"div_mmc_pre3" , -SRC_MASK_FSYS ,12 ,CLK_SET_RATE_PARENT ,0 , -"mmc_busclk.2" ), -GATE_DA (sclk_mmc4,NULL ,"sclk_mmc4" ,"div_mmc_pre4" , -SRC_MASK_FSYS ,16 ,CLK_SET_RATE_PARENT ,0 ,"ciu" ), -GATE_DA (sclk_uart0,"exynos4210-uart.0" ,"uclk0" ,"div_uart0" , -SRC_MASK_PERIL0 ,0 ,CLK_SET_RATE_PARENT , -0 ,"clk_uart_baud0" ), -GATE_DA (sclk_uart1,"exynos4210-uart.1" ,"uclk1" ,"div_uart1" , -SRC_MASK_PERIL0 ,4 ,CLK_SET_RATE_PARENT , -0 ,"clk_uart_baud0" ), -GATE_DA (sclk_uart2,"exynos4210-uart.2" ,"uclk2" ,"div_uart2" , -SRC_MASK_PERIL0 ,8 ,CLK_SET_RATE_PARENT , -0 ,"clk_uart_baud0" ), -GATE_DA (sclk_uart3,"exynos4210-uart.3" ,"uclk3" ,"div_uart3" , -SRC_MASK_PERIL0 ,12 ,CLK_SET_RATE_PARENT , -0 ,"clk_uart_baud0" ), -GATE_DA (sclk_uart4,"exynos4210-uart.4" ,"uclk4" ,"div_uart4" , -SRC_MASK_PERIL0 ,16 ,CLK_SET_RATE_PARENT , -0 ,"clk_uart_baud0" ), +GATE (vp,"vp" ,"aclk160" ,GATE_IP_TV ,0 ,0 ,0 ), +GATE (mixer,"mixer" ,"aclk160" ,GATE_IP_TV ,1 ,0 ,0 ), +GATE (hdmi,"hdmi" ,"aclk160" ,GATE_IP_TV ,3 ,0 ,0 ), +GATE (pwm,"pwm" ,"aclk100" ,GATE_IP_PERIL ,24 ,0 ,0 ), +GATE (sdmmc4,"sdmmc4" ,"aclk133" ,GATE_IP_FSYS ,9 ,0 ,0 ), +GATE (usb_host,"usb_host" ,"aclk133" ,GATE_IP_FSYS ,12 ,0 ,0 ), +GATE (sclk_fimc0,"sclk_fimc0" ,"div_fimc0" ,SRC_MASK_CAM ,0 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_fimc1,"sclk_fimc1" ,"div_fimc1" ,SRC_MASK_CAM ,4 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_fimc2,"sclk_fimc2" ,"div_fimc2" ,SRC_MASK_CAM ,8 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_fimc3,"sclk_fimc3" ,"div_fimc3" ,SRC_MASK_CAM ,12 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_csis0,"sclk_csis0" ,"div_csis0" ,SRC_MASK_CAM ,24 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_csis1,"sclk_csis1" ,"div_csis1" ,SRC_MASK_CAM ,28 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_fimd0,"sclk_fimd0" ,"div_fimd0" ,SRC_MASK_LCD0 ,0 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_mmc0,"sclk_mmc0" ,"div_mmc_pre0" ,SRC_MASK_FSYS ,0 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_mmc1,"sclk_mmc1" ,"div_mmc_pre1" ,SRC_MASK_FSYS ,4 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_mmc2,"sclk_mmc2" ,"div_mmc_pre2" ,SRC_MASK_FSYS ,8 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_mmc3,"sclk_mmc3" ,"div_mmc_pre3" ,SRC_MASK_FSYS ,12 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_mmc4,"sclk_mmc4" ,"div_mmc_pre4" ,SRC_MASK_FSYS ,16 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_uart0,"uclk0" ,"div_uart0" ,SRC_MASK_PERIL0 ,0 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_uart1,"uclk1" ,"div_uart1" ,SRC_MASK_PERIL0 ,4 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_uart2,"uclk2" ,"div_uart2" ,SRC_MASK_PERIL0 ,8 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_uart3,"uclk3" ,"div_uart3" ,SRC_MASK_PERIL0 ,12 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_uart4,"uclk4" ,"div_uart4" ,SRC_MASK_PERIL0 ,16 , +CLK_SET_RATE_PARENT ,0 ),GATE (sclk_audio2,"sclk_audio2" ,"div_audio2" ,SRC_MASK_PERIL1 ,4 ,CLK_SET_RATE_PARENT ,0 ), -GATE_DA (sclk_spi0,"exynos4210-spi.0" ,"sclk_spi0" ,"div_spi_pre0" , -SRC_MASK_PERIL1 ,16 ,CLK_SET_RATE_PARENT , -0 ,"spi_busclk0" ), -GATE_DA (sclk_spi1,"exynos4210-spi.1" ,"sclk_spi1" ,"div_spi_pre1" , -SRC_MASK_PERIL1 ,20 ,CLK_SET_RATE_PARENT , -0 ,"spi_busclk0" ), -GATE_DA (sclk_spi2,"exynos4210-spi.2" ,"sclk_spi2" ,"div_spi_pre2" , -SRC_MASK_PERIL1 ,24 ,CLK_SET_RATE_PARENT , -0 ,"spi_busclk0" ), -GATE_DA (fimc0,"exynos4-fimc.0" ,"fimc0" ,"aclk160" , -GATE_IP_CAM ,0 ,0 ,0 ,"fimc" ), -GATE_DA (fimc1,"exynos4-fimc.1" ,"fimc1" ,"aclk160" , -GATE_IP_CAM ,1 ,0 ,0 ,"fimc" ), -GATE_DA (fimc2,"exynos4-fimc.2" ,"fimc2" ,"aclk160" , -GATE_IP_CAM ,2 ,0 ,0 ,"fimc" ), -GATE_DA (fimc3,"exynos4-fimc.3" ,"fimc3" ,"aclk160" , -GATE_IP_CAM ,3 ,0 ,0 ,"fimc" ), -GATE_DA (csis0,"s5p-mipi-csis.0" ,"csis0" ,"aclk160" , -GATE_IP_CAM ,4 ,0 ,0 ,"fimc" ), -GATE_DA (csis1,"s5p-mipi-csis.1" ,"csis1" ,"aclk160" , -GATE_IP_CAM ,5 ,0 ,0 ,"fimc" ), -GATE_DA (smmu_fimc0,"exynos-sysmmu.5" ,"smmu_fimc0" ,"aclk160" , -GATE_IP_CAM ,7 ,0 ,0 ,"sysmmu" ), -GATE_DA (smmu_fimc1,"exynos-sysmmu.6" ,"smmu_fimc1" ,"aclk160" , -GATE_IP_CAM ,8 ,0 ,0 ,"sysmmu" ), -GATE_DA (smmu_fimc2,"exynos-sysmmu.7" ,"smmu_fimc2" ,"aclk160" , -GATE_IP_CAM ,9 ,0 ,0 ,"sysmmu" ), -GATE_DA (smmu_fimc3,"exynos-sysmmu.8" ,"smmu_fimc3" ,"aclk160" , -GATE_IP_CAM ,10 ,0 ,0 ,"sysmmu" ), -GATE_DA (smmu_jpeg,"exynos-sysmmu.3" ,"smmu_jpeg" ,"aclk160" , -GATE_IP_CAM ,11 ,0 ,0 ,"sysmmu" ), +GATE (sclk_spi0,"sclk_spi0" ,"div_spi_pre0" ,SRC_MASK_PERIL1 ,16 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_spi1,"sclk_spi1" ,"div_spi_pre1" ,SRC_MASK_PERIL1 ,20 , +CLK_SET_RATE_PARENT ,0 ), +GATE (sclk_spi2,"sclk_spi2" ,"div_spi_pre2" ,SRC_MASK_PERIL1 ,24 , +CLK_SET_RATE_PARENT ,0 ), +GATE (fimc0,"fimc0" ,"aclk160" ,GATE_IP_CAM ,0 , +0 ,0 ), +GATE (fimc1,"fimc1" ,"aclk160" ,GATE_IP_CAM ,1 , +0 ,0 ), +GATE (fimc2,"fimc2" ,"aclk160" ,GATE_IP_CAM ,2 , +0 ,0 ), +GATE (fimc3,"fimc3" ,"aclk160" ,GATE_IP_CAM ,3 , +0 ,0 ), +GATE (csis0,"csis0" ,"aclk160" ,GATE_IP_CAM ,4 , +0 ,0 ), +GATE (csis1,"csis1" ,"aclk160" ,GATE_IP_CAM ,5 , +0 ,0 ), +GATE (smmu_fimc0,"smmu_fimc0" ,"aclk160" ,GATE_IP_CAM ,7 , +0 ,0 ), +GATE (smmu_fimc1,"smmu_fimc1" ,"aclk160" ,GATE_IP_CAM ,8 , +0 ,0 ), +GATE (smmu_fimc2,"smmu_fimc2" ,"aclk160" ,GATE_IP_CAM ,9 , +0 ,0 ), +GATE (smmu_fimc3,"smmu_fimc3" ,"aclk160" ,GATE_IP_CAM ,10 , +0 ,0 ), +GATE (smmu_jpeg,"smmu_jpeg" ,"aclk160" ,GATE_IP_CAM ,11 , +0 ,0 ),GATE (pixelasyncm0,"pxl_async0" ,"aclk160" ,GATE_IP_CAM ,17 ,0 ,0 ),GATE (pixelasyncm1,"pxl_async1" ,"aclk160" ,GATE_IP_CAM ,18 ,0 ,0 ), -GATE_DA (smmu_tv,"exynos-sysmmu.2" ,"smmu_tv" ,"aclk160" , -GATE_IP_TV ,4 ,0 ,0 ,"sysmmu" ), -GATE_DA (mfc,"s5p-mfc" ,"mfc" ,"aclk100" ,GATE_IP_MFC ,0 ,0 ,0 ,"mfc" ), -GATE_DA (smmu_mfcl,"exynos-sysmmu.0" ,"smmu_mfcl" ,"aclk100" , -GATE_IP_MFC ,1 ,0 ,0 ,"sysmmu" ), -GATE_DA (smmu_mfcr,"exynos-sysmmu.1" ,"smmu_mfcr" ,"aclk100" , -GATE_IP_MFC ,2 ,0 ,0 ,"sysmmu" ), -GATE_DA (fimd0,"exynos4-fb.0" ,"fimd0" ,"aclk160" , -GATE_IP_LCD0 ,0 ,0 ,0 ,"fimd" ), -GATE_DA (smmu_fimd0,"exynos-sysmmu.10" ,"smmu_fimd0" ,"aclk160" , -GATE_IP_LCD0 ,4 ,0 ,0 ,"sysmmu" ), -GATE_DA (pdma0,"dma-pl330.0" ,"pdma0" ,"aclk133" , -GATE_IP_FSYS ,0 ,0 ,0 ,"dma" ), -GATE_DA (pdma1,"dma-pl330.1" ,"pdma1" ,"aclk133" , -GATE_IP_FSYS ,1 ,0 ,0 ,"dma" ), -GATE_DA (sdmmc0,"exynos4-sdhci.0" ,"sdmmc0" ,"aclk133" , -GATE_IP_FSYS ,5 ,0 ,0 ,"hsmmc" ), -GATE_DA (sdmmc1,"exynos4-sdhci.1" ,"sdmmc1" ,"aclk133" , -GATE_IP_FSYS ,6 ,0 ,0 ,"hsmmc" ), -GATE_DA (sdmmc2,"exynos4-sdhci.2" ,"sdmmc2" ,"aclk133" , -GATE_IP_FSYS ,7 ,0 ,0 ,"hsmmc" ), -GATE_DA (sdmmc3,"exynos4-sdhci.3" ,"sdmmc3" ,"aclk133" , -GATE_IP_FSYS ,8 ,0 ,0 ,"hsmmc" ), -GATE_DA (uart0,"exynos4210-uart.0" ,"uart0" ,"aclk100" , -GATE_IP_PERIL ,0 ,0 ,0 ,"uart" ), -GATE_DA (uart1,"exynos4210-uart.1" ,"uart1" ,"aclk100" , -GATE_IP_PERIL ,1 ,0 ,0 ,"uart" ), -GATE_DA (uart2,"exynos4210-uart.2" ,"uart2" ,"aclk100" , -GATE_IP_PERIL ,2 ,0 ,0 ,"uart" ), -GATE_DA (uart3,"exynos4210-uart.3" ,"uart3" ,"aclk100" , -GATE_IP_PERIL ,3 ,0 ,0 ,"uart" ), -GATE_DA (uart4,"exynos4210-uart.4" ,"uart4" ,"aclk100" , -GATE_IP_PERIL ,4 ,0 ,0 ,"uart" ), -GATE_DA (i2c0,"s3c2440-i2c.0" ,"i2c0" ,"aclk100" , -GATE_IP_PERIL ,6 ,0 ,0 ,"i2c" ), -GATE_DA (i2c1,"s3c2440-i2c.1" ,"i2c1" ,"aclk100" , -GATE_IP_PERIL ,7 ,0 ,0 ,"i2c" ), -GATE_DA (i2c2,"s3c2440-i2c.2" ,"i2c2" ,"aclk100" , -GATE_IP_PERIL ,8 ,0 ,0 ,"i2c" ), -GATE_DA (i2c3,"s3c2440-i2c.3" ,"i2c3" ,"aclk100" , -GATE_IP_PERIL ,9 ,0 ,0 ,"i2c" ), -GATE_DA (i2c4,"s3c2440-i2c.4" ,"i2c4" ,"aclk100" , -GATE_IP_PERIL ,10 ,0 ,0 ,"i2c" ), -GATE_DA (i2c5,"s3c2440-i2c.5" ,"i2c5" ,"aclk100" , -GATE_IP_PERIL ,11 ,0 ,0 ,"i2c" ), -GATE_DA (i2c6,"s3c2440-i2c.6" ,"i2c6" ,"aclk100" , -GATE_IP_PERIL ,12 ,0 ,0 ,"i2c" ), -GATE_DA (i2c7,"s3c2440-i2c.7" ,"i2c7" ,"aclk100" , -GATE_IP_PERIL ,13 ,0 ,0 ,"i2c" ), -GATE_DA (i2c_hdmi,"s3c2440-hdmiphy-i2c" ,"i2c-hdmi" ,"aclk100" , -GATE_IP_PERIL ,14 ,0 ,0 ,"i2c" ), -GATE_DA (spi0,"exynos4210-spi.0" ,"spi0" ,"aclk100" , -GATE_IP_PERIL ,16 ,0 ,0 ,"spi" ), -GATE_DA (spi1,"exynos4210-spi.1" ,"spi1" ,"aclk100" , -GATE_IP_PERIL ,17 ,0 ,0 ,"spi" ), -GATE_DA (spi2,"exynos4210-spi.2" ,"spi2" ,"aclk100" , -GATE_IP_PERIL ,18 ,0 ,0 ,"spi" ), -GATE_DA (i2s1,"samsung-i2s.1" ,"i2s1" ,"aclk100" , -GATE_IP_PERIL ,20 ,0 ,0 ,"iis" ), -GATE_DA (i2s2,"samsung-i2s.2" ,"i2s2" ,"aclk100" , -GATE_IP_PERIL ,21 ,0 ,0 ,"iis" ), -GATE_DA (pcm1,"samsung-pcm.1" ,"pcm1" ,"aclk100" , -GATE_IP_PERIL ,22 ,0 ,0 ,"pcm" ), -GATE_DA (pcm2,"samsung-pcm.2" ,"pcm2" ,"aclk100" , -GATE_IP_PERIL ,23 ,0 ,0 ,"pcm" ), -GATE_DA (spdif,"samsung-spdif" ,"spdif" ,"aclk100" , -GATE_IP_PERIL ,26 ,0 ,0 ,"spdif" ), -GATE_DA (ac97,"samsung-ac97" ,"ac97" ,"aclk100" , - GATE_IP_PERIL, 27, 0, 0, "ac97"), +GATE (smmu_tv,"smmu_tv" ,"aclk160" ,GATE_IP_TV ,4 , +0 ,0 ), +GATE (mfc,"mfc" ,"aclk100" ,GATE_IP_MFC ,0 ,0 ,0 ), +GATE (smmu_mfcl,"smmu_mfcl" ,"aclk100" ,GATE_IP_MFC ,1 , +0 ,0 ), +GATE (smmu_mfcr,"smmu_mfcr" ,"aclk100" ,GATE_IP_MFC ,2 , +0 ,0 ), +GATE (fimd0,"fimd0" ,"aclk160" ,GATE_IP_LCD0 ,0 , +0 ,0 ), +GATE (smmu_fimd0,"smmu_fimd0" ,"aclk160" ,GATE_IP_LCD0 ,4 , +0 ,0 ), +GATE (pdma0,"pdma0" ,"aclk133" ,GATE_IP_FSYS ,0 , +0 ,0 ), +GATE (pdma1,"pdma1" ,"aclk133" ,GATE_IP_FSYS ,1 , +0 ,0 ), +GATE (sdmmc0,"sdmmc0" ,"aclk133" ,GATE_IP_FSYS ,5 , +0 ,0 ), +GATE (sdmmc1,"sdmmc1" ,"aclk133" ,GATE_IP_FSYS ,6 , +0 ,0 ), +GATE (sdmmc2,"sdmmc2" ,"aclk133" ,GATE_IP_FSYS ,7 , +0 ,0 ), +GATE (sdmmc3,"sdmmc3" ,"aclk133" ,GATE_IP_FSYS ,8 , +0 ,0 ), +GATE (uart0,"uart0" ,"aclk100" ,GATE_IP_PERIL ,0 , +0 ,0 ), +GATE (uart1,"uart1" ,"aclk100" ,GATE_IP_PERIL ,1 , +0 ,0 ), +GATE (uart2,"uart2" ,"aclk100" ,GATE_IP_PERIL ,2 , +0 ,0 ), +GATE (uart3,"uart3" ,"aclk100" ,GATE_IP_PERIL ,3 , +0 ,0 ), +GATE (uart4,"uart4" ,"aclk100" ,GATE_IP_PERIL ,4 , +0 ,0 ), +GATE (i2c0,"i2c0" ,"aclk100" ,GATE_IP_PERIL ,6 , +0 ,0 ), +GATE (i2c1,"i2c1" ,"aclk100" ,GATE_IP_PERIL ,7 , +0 ,0 ), +GATE (i2c2,"i2c2" ,"aclk100" ,GATE_IP_PERIL ,8 , +0 ,0 ), +GATE (i2c3,"i2c3" ,"aclk100" ,GATE_IP_PERIL ,9 , +0 ,0 ), +GATE (i2c4,"i2c4" ,"aclk100" ,GATE_IP_PERIL ,10 , +0 ,0 ), +GATE (i2c5,"i2c5" ,"aclk100" ,GATE_IP_PERIL ,11 , +0 ,0 ), +GATE (i2c6,"i2c6" ,"aclk100" ,GATE_IP_PERIL ,12 , +0 ,0 ), +GATE (i2c7,"i2c7" ,"aclk100" ,GATE_IP_PERIL ,13 , +0 ,0 ), +GATE (i2c_hdmi,"i2c-hdmi" ,"aclk100" ,GATE_IP_PERIL ,14 , +0 ,0 ), +GATE (spi0,"spi0" ,"aclk100" ,GATE_IP_PERIL ,16 , +0 ,0 ), +GATE (spi1,"spi1" ,"aclk100" ,GATE_IP_PERIL ,17 , +0 ,0 ), +GATE (spi2,"spi2" ,"aclk100" ,GATE_IP_PERIL ,18 , +0 ,0 ), +GATE (i2s1,"i2s1" ,"aclk100" ,GATE_IP_PERIL ,20 , +0 ,0 ), +GATE (i2s2,"i2s2" ,"aclk100" ,GATE_IP_PERIL ,21 , +0 ,0 ), +GATE (pcm1,"pcm1" ,"aclk100" ,GATE_IP_PERIL ,22 , +0 ,0 ), +GATE (pcm2,"pcm2" ,"aclk100" ,GATE_IP_PERIL ,23 , +0 ,0 ), +GATE (spdif,"spdif" ,"aclk100" ,GATE_IP_PERIL ,26 , +0 ,0 ), +GATE (ac97,"ac97" ,"aclk100" ,GATE_IP_PERIL ,27 , + 0, 0), };/* list of gate clocks supported in exynos4210 soc */
@@ -816,13 +799,18 @@ static struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),GATE (sclk_mixer,"sclk_mixer" ,"mout_mixer" ,SRC_MASK_TV ,4 ,0 ,0 ),GATE (sclk_dac,"sclk_dac" ,"mout_dac" ,SRC_MASK_TV ,8 ,0 ,0 ), -GATE_A (tsadc,"tsadc" ,"aclk100" ,GATE_IP_PERIL ,15 ,0 ,0 ,"adc" ), -GATE_A (mct,"mct" ,"aclk100" ,E4210_GATE_IP_PERIR ,13 ,0 ,0 ,"mct" ), -GATE_A (wdt,"watchdog" ,"aclk100" ,E4210_GATE_IP_PERIR ,14 ,0 ,0 ,"watchdog" ), -GATE_A (rtc,"rtc" ,"aclk100" ,E4210_GATE_IP_PERIR ,15 ,0 ,0 ,"rtc" ), -GATE_A (keyif,"keyif" ,"aclk100" ,E4210_GATE_IP_PERIR ,16 ,0 ,0 ,"keypad" ), -GATE_DA (sclk_fimd1,"exynos4-fb.1" ,"sclk_fimd1" ,"div_fimd1" , -E4210_SRC_MASK_LCD1 ,0 ,CLK_SET_RATE_PARENT ,0 ,"sclk_fimd" ), +GATE (tsadc,"tsadc" ,"aclk100" ,GATE_IP_PERIL ,15 , +0 ,0 ), +GATE (mct,"mct" ,"aclk100" ,E4210_GATE_IP_PERIR ,13 , +0 ,0 ), +GATE (wdt,"watchdog" ,"aclk100" ,E4210_GATE_IP_PERIR ,14 , +0 ,0 ), +GATE (rtc,"rtc" ,"aclk100" ,E4210_GATE_IP_PERIR ,15 , +0 ,0 ), +GATE (keyif,"keyif" ,"aclk100" ,E4210_GATE_IP_PERIR ,16 , +0 ,0 ), +GATE (sclk_fimd1,"sclk_fimd1" ,"div_fimd1" ,E4210_SRC_MASK_LCD1 ,0 , +CLK_SET_RATE_PARENT ,0 ), GATE(tmu_apbif, "tmu_apbif", "aclk100", E4210_GATE_IP_PERIR, 17, 0, 0), };
@@ -846,10 +834,11 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),GATE (smmu_rotator,"smmu_rotator" ,"aclk200" ,E4X12_GATE_IP_IMAGE ,4 ,0 ,0 ), -GATE_A (mct,"mct" ,"aclk100" ,E4X12_GATE_IP_PERIR ,13 ,0 ,0 ,"mct" ), -GATE_A (rtc,"rtc" ,"aclk100" ,E4X12_GATE_IP_PERIR ,15 ,0 ,0 ,"rtc" ), -GATE_A (keyif,"keyif" ,"aclk100" , -E4X12_GATE_IP_PERIR ,16 ,0 ,0 ,"keypad" ), +GATE (mct,"mct" ,"aclk100" ,E4X12_GATE_IP_PERIR ,13 , +0 ,0 ), +GATE (rtc,"rtc" ,"aclk100" ,E4X12_GATE_IP_PERIR ,15 , +0 ,0 ), +GATE (keyif,"keyif" ,"aclk100" ,E4X12_GATE_IP_PERIR ,16 ,0 ,0 ),GATE (sclk_pwm_isp,"sclk_pwm_isp" ,"div_pwm_isp" ,E4X12_SRC_MASK_ISP ,0 ,CLK_SET_RATE_PARENT ,0 ), GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre",
@@ -866,12 +855,11 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { E4X12_GATE_IP_ISP, 2, 0, 0),GATE (uart_isp_sclk,"uart_isp_sclk" ,"sclk_uart_isp" ,E4X12_GATE_IP_ISP ,3 ,0 ,0 ), -GATE_A (wdt,"watchdog" ,"aclk100" , -E4X12_GATE_IP_PERIR ,14 ,0 ,0 ,"watchdog" ), -GATE_DA (pcm0,"samsung-pcm.0" ,"pcm0" ,"aclk100" , -E4X12_GATE_IP_MAUDIO ,2 ,0 ,0 ,"pcm" ), -GATE_DA (i2s0,"samsung-i2s.0" ,"i2s0" ,"aclk100" , -E4X12_GATE_IP_MAUDIO ,3 ,0 ,0 ,"iis" ), +GATE (wdt,"watchdog" ,"aclk100" ,E4X12_GATE_IP_PERIR ,14 ,0 ,0 ), +GATE (pcm0,"pcm0" ,"aclk100" ,E4X12_GATE_IP_MAUDIO ,2 , +0 ,0 ), +GATE (i2s0,"i2s0" ,"aclk100" ,E4X12_GATE_IP_MAUDIO ,3 , +0 ,0 ),GATE (fimc_isp,"isp" ,"aclk200" ,E4X12_GATE_ISP0 ,0 ,CLK_IGNORE_UNUSED |CLK_GET_RATE_NOCACHE ,0 ), GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1,
@@ -1001,14 +989,14 @@ static struct of_device_id ext_clk_match[] __initdata = { };static struct samsung_pll_clock exynos4_plls[nr_plls]__initdata = { - [apll] =PLL_A (pll_35xx, fout_apll,"fout_apll" ,"fin_pll" ,APLL_LOCK , -APLL_CON0 ,"fout_apll" ,NULL ), - [mpll] =PLL_A (pll_35xx, fout_mpll,"fout_mpll" ,"fin_pll" , -E4X12_MPLL_LOCK ,E4X12_MPLL_CON0 ,"fout_mpll" ,NULL ), - [epll] =PLL_A (pll_36xx, fout_epll,"fout_epll" ,"fin_pll" ,EPLL_LOCK , -EPLL_CON0 ,"fout_epll" ,NULL ), - [vpll] =PLL_A (pll_36xx, fout_vpll,"fout_vpll" ,"fin_pll" ,VPLL_LOCK , -VPLL_CON0 ,"fout_vpll" ,NULL ), + [apll] =PLL (pll_35xx, fout_apll,"fout_apll" ,"fin_pll" , +APLL_LOCK ,APLL_CON0 ,NULL ), + [mpll] =PLL (pll_35xx, fout_mpll,"fout_mpll" ,"fin_pll" , +E4X12_MPLL_LOCK ,E4X12_MPLL_CON0 ,NULL ), + [epll] =PLL (pll_36xx, fout_epll,"fout_epll" ,"fin_pll" , +EPLL_LOCK ,EPLL_CON0 ,NULL ), + [vpll] =PLL (pll_36xx, fout_vpll,"fout_vpll" ,"fin_pll" , +VPLL_LOCK ,VPLL_CON0 ,NULL ), };/* register exynos4 clocks */
Signature · 1 line
1.8.3.2
PATCH 7/16 clk: samsung: exynos4: Remove checks for DT node
In reply to Tomasz FigaExynos 4 supports only DT based bootup, so non-DT cases does not need to be handled anymore.
--- drivers/clk/samsung/clk-exynos4.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
drivers/clk/samsung/clk-exynos4.c +4 -7
@@ -1006,11 +1006,9 @@ static void __init exynos4_clk_init(struct device_node *np, {struct clk *apll, *mpll, *epll, *vpll; -if (np) { - reg_base =of_iomap (np,0 ); -if (!reg_base) -panic ("%s: failed to map registers\n" , __func__); - } + reg_base =of_iomap (np,0 ); +if (!reg_base) +panic ("%s: failed to map registers\n" , __func__);if (exynos4_soc ==EXYNOS4210 ) samsung_clk_init(np, reg_base, nr_clks,
@@ -1021,8 +1019,7 @@ static void __init exynos4_clk_init(struct device_node *np, exynos4_clk_regs,ARRAY_SIZE (exynos4_clk_regs), exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save)); -if (np) -samsung_clk_of_register_fixed_ext (exynos4_fixed_rate_ext_clks, +samsung_clk_of_register_fixed_ext (exynos4_fixed_rate_ext_clks,ARRAY_SIZE (exynos4_fixed_rate_ext_clks), ext_clk_match);
Signature · 1 line
1.8.3.2
PATCH 8/16 clk: samsung: exynos4: Rename exynos4_plls to exynos4x12_plls
In reply to Tomasz FigaThis array defines PLLs specific to Exynos 4x12 SoCs and not for all Exynos 4 SoCs, so the name should represent that.
--- drivers/clk/samsung/clk-exynos4.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/samsung/clk-exynos4.c +3 -3
@@ -988,7 +988,7 @@ static struct of_device_id ext_clk_match[] __initdata = { {}, }; -static struct samsung_pll_clock exynos4_plls[nr_plls]__initdata = { +static struct samsung_pll_clock exynos4x12_plls[nr_plls]__initdata = { [apll] =PLL (pll_35xx, fout_apll,"fout_apll" ,"fin_pll" ,APLL_LOCK ,APLL_CON0 ,NULL ), [mpll] = PLL(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
@@ -1040,8 +1040,8 @@ static void __init exynos4_clk_init(struct device_node *np,samsung_clk_add_lookup (epll, fout_epll);samsung_clk_add_lookup (vpll, fout_vpll); }else { -samsung_clk_register_pll (exynos4_plls, -ARRAY_SIZE (exynos4_plls), reg_base); +samsung_clk_register_pll (exynos4x12_plls, +ARRAY_SIZE (exynos4x12_plls), reg_base); } samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
Signature · 1 line
1.8.3.2
PATCH 9/16 clk: samsung: pll: Use new registration method for PLL45xx
In reply to Tomasz FigaThis patch modifies PLL45xx support code and its users to use the recently introduced common PLL registration helper.
--- drivers/clk/samsung/clk-exynos4.c | 18 ++++++++------ drivers/clk/samsung/clk-pll.c | 52 +++++---------------------------------- drivers/clk/samsung/clk-pll.h | 12 +++------ 3 files changed, 20 insertions(+), 62 deletions(-)
drivers/clk/samsung/clk-exynos4.c +11 -7
@@ -104,6 +104,7 @@#define DIV_DMC1 0x10504#define GATE_IP_DMC 0x10900#define APLL_LOCK 0x14000 +#define E4210_MPLL_LOCK 0x14008#define APLL_CON0 0x14100#define E4210_MPLL_CON0 0x14108#define SRC_CPU 0x14200
@@ -988,6 +989,13 @@ static struct of_device_id ext_clk_match[] __initdata = { {}, }; +static struct __initdata samsung_pll_clock exynos4210_plls[nr_plls] = { + [apll] =PLL_A (pll_4508, fout_apll,"fout_apll" ,"fin_pll" ,APLL_LOCK , +APLL_CON0 ,"fout_apll" ,NULL ), + [mpll] =PLL_A (pll_4508, fout_mpll,"fout_mpll" ,"fin_pll" , +E4210_MPLL_LOCK ,E4210_MPLL_CON0 ,"fout_mpll" ,NULL ), +}; +static struct samsung_pll_clock exynos4x12_plls[nr_plls]__initdata = { [apll] =PLL (pll_35xx, fout_apll,"fout_apll" ,"fin_pll" ,APLL_LOCK ,APLL_CON0 ,NULL ),
@@ -1004,7 +1012,7 @@ static void __init exynos4_clk_init(struct device_node *np,enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom) { - struct clk *apll, *mpll, *epll, *vpll; + struct clk *epll, *vpll; reg_base =of_iomap (np,0 );if (!reg_base)
@@ -1026,17 +1034,13 @@ static void __init exynos4_clk_init(struct device_node *np,exynos4_clk_register_finpll (xom);if (exynos4_soc ==EXYNOS4210 ) { - apll =samsung_clk_register_pll45xx ("fout_apll" ,"fin_pll" , - reg_base +APLL_CON0 , pll_4508); - mpll =samsung_clk_register_pll45xx ("fout_mpll" ,"fin_pll" , - reg_base +E4210_MPLL_CON0 , pll_4508); +samsung_clk_register_pll (exynos4210_plls, +ARRAY_SIZE (exynos4210_plls), reg_base); epll =samsung_clk_register_pll46xx ("fout_epll" ,"fin_pll" , reg_base +EPLL_CON0 , pll_4600); vpll =samsung_clk_register_pll46xx ("fout_vpll" ,"mout_vpllsrc" , reg_base +VPLL_CON0 , pll_4650c); -samsung_clk_add_lookup (apll, fout_apll); -samsung_clk_add_lookup (mpll, fout_mpll);samsung_clk_add_lookup (epll, fout_epll);samsung_clk_add_lookup (vpll, fout_vpll); }else {
drivers/clk/samsung/clk-pll.c +6 -46
73 lines not on this page · raw message
drivers/clk/samsung/clk-pll.h +3 -9
@@ -17,6 +17,9 @@ enum samsung_pll_type { pll_36xx, pll_2550, pll_2650, + pll_4500, + pll_4502, + pll_4508 };#define PLL_35XX_RATE (_rate, _m, _p, _s) \
@@ -46,21 +49,12 @@ struct samsung_pll_rate_table {unsigned int kdiv; }; -enum pll45xx_type { - pll_4500, - pll_4502, - pll_4508 -}; -enum pll46xx_type { pll_4600, pll_4650, pll_4650c, }; -extern struct clk *__init samsung_clk_register_pll45xx (const char *name, -const char *pname,const void __iomem *con_reg, -enum pll45xx_type type);extern struct clk *__init samsung_clk_register_pll46xx (const char *name,const char *pname,const void __iomem *con_reg,enum pll46xx_type type);
Signature · 1 line
1.8.3.2
PATCH 9/16 clk: samsung: pll: Use new registration method for PLL45xx
Quoted 3 lines
};
+static struct
__initdatasamsung_pll_clockexynos4210_plls[nr_plls] = {
NIT: __initdata should be at last.
Quoted 161 lines
drivers/clk/samsung/clk-exynos4.c +9
-7+ [apll] =PLL_A (pll_4508, fout_apll,"fout_apll" ,"fin_pll" ,APLL_LOCK , + APLL_CON0, "fout_apll", NULL), + [mpll] =PLL_A (pll_4508, fout_mpll,"fout_mpll" ,"fin_pll" , + E4210_MPLL_LOCK, E4210_MPLL_CON0, "fout_mpll", NULL), +}; +static struct samsung_pll_clock exynos4x12_plls[nr_plls]__initdata = { [apll] =PLL (pll_35xx, fout_apll,"fout_apll" ,"fin_pll" ,APLL_LOCK ,APLL_CON0 ,NULL ),@@ -1004,7 +1012,7 @@ static void __init exynos4_clk_init(struct device_node *np,enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom) { - struct clk *apll, *mpll, *epll, *vpll; + struct clk *epll, *vpll; reg_base =of_iomap (np,0 );if (!reg_base)@@ -1026,17 +1034,13 @@ static void __init exynos4_clk_init(struct device_node *np,exynos4_clk_register_finpll (xom);if (exynos4_soc ==EXYNOS4210 ) { - apll =samsung_clk_register_pll45xx ("fout_apll" ,"fin_pll" , - reg_base +APLL_CON0 , pll_4508); - mpll =samsung_clk_register_pll45xx ("fout_mpll" ,"fin_pll" , - reg_base +E4210_MPLL_CON0 , pll_4508); +samsung_clk_register_pll (exynos4210_plls, +ARRAY_SIZE (exynos4210_plls), reg_base); epll =samsung_clk_register_pll46xx ("fout_epll" ,"fin_pll" , reg_base +EPLL_CON0 , pll_4600); vpll =samsung_clk_register_pll46xx ("fout_vpll" ,"mout_vpllsrc" , reg_base +VPLL_CON0 , pll_4650c); -samsung_clk_add_lookup (apll, fout_apll); -samsung_clk_add_lookup (mpll, fout_mpll);samsung_clk_add_lookup (epll, fout_epll);samsung_clk_add_lookup (vpll, fout_vpll); }else {drivers/clk/samsung/clk-pll.c +6
-46@@ -280,18 +280,10 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {#define PLL45XX_PDIV_SHIFT (8)#define PLL45XX_SDIV_SHIFT (0) -struct samsung_clk_pll45xx { -struct clk_hw hw; -enum pll45xx_type type; -const void __iomem *con_reg; -}; - -#define to_clk_pll45xx (_hw) container_of(_hw, struct samsung_clk_pll45xx, hw) -static unsigned long samsung_pll45xx_recalc_rate (struct clk_hw *hw,unsigned long parent_rate) { -struct samsung_clk_pll45xx *pll =to_clk_pll45xx (hw); +struct samsung_clk_pll *pll =to_clk_pll (hw);u32 mdiv, pdiv, sdiv, pll_con;u64 fvco = parent_rate;@@ -313,43 +305,6 @@ static const struct clk_ops samsung_pll45xx_clk_ops = { .recalc_rate = samsung_pll45xx_recalc_rate, }; -struct clk *__init samsung_clk_register_pll45xx (const char *name, -const char *pname,const void __iomem *con_reg, -enum pll45xx_type type) -{ -struct samsung_clk_pll45xx *pll; -struct clk *clk; -struct clk_init_data init; - - pll =kzalloc (sizeof (*pll),GFP_KERNEL ); -if (!pll) { -pr_err ("%s: could not allocate pll clk %s\n" , __func__, name); -return NULL ; - } - - init.name = name; - init.ops = &samsung_pll45xx_clk_ops; - init.flags =CLK_GET_RATE_NOCACHE ; - init.parent_names = &pname; - init.num_parents =1 ; - - pll->hw.init = &init; - pll->con_reg = con_reg; - pll->type = type; - - clk =clk_register (NULL , &pll->hw); -if (IS_ERR (clk)) { -pr_err ("%s: failed to register pll clock %s\n" , __func__, - name); -kfree (pll); - } - -if (clk_register_clkdev (clk, name,NULL )) -pr_err ("%s: failed to register lookup for %s" , __func__, name); - -return clk; -} -/* * PLL46xx Clock Type */ @@ -724,6 +679,11 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,else init.ops = &samsung_pll35xx_clk_ops;break ; +case pll_4500: +case pll_4502: +case pll_4508: + init.ops = &samsung_pll45xx_clk_ops; +break ;/* clk_ops for 36xx and 2650 are similar */ case pll_36xx:case pll_2650:drivers/clk/samsung/clk-pll.h +3
-10@@ -17,6 +17,9 @@ enum samsung_pll_type { pll_36xx, pll_2550, pll_2650, + pll_4500, + pll_4502, + pll_4508 };#define PLL_35XX_RATE (_rate, _m, _p, _s) \@@ -46,21 +49,12 @@ struct samsung_pll_rate_table {unsigned int kdiv; }; -enum pll45xx_type { - pll_4500, - pll_4502, - pll_4508 -}; -enum pll46xx_type { pll_4600, pll_4650, pll_4650c, }; -extern struct clk *__init samsung_clk_register_pll45xx (const char *name, -const char *pname,const void __iomem *con_reg, -enum pll45xx_type type);extern struct clk *__init samsung_clk_register_pll46xx (const char *name,const char *pname,const void __iomem *con_reg,enum pll46xx_type type); --1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 9/16 clk: samsung: pll: Use new registration method for PLL45xx
Quoted 5 lines · Yadwinder Singh Brar
Quoted 3 lines
};
+static struct
__initdatasamsung_pll_clockexynos4210_plls[nr_plls] = {NIT:
__initdatashould be at last.
It's helpful if you only quote as much of the patch as you need to in order to reply to it; it wasn't obvious in your message that you had no comments on the rest of the patch that you quoted, so people have to scroll through it looking carefully for any other comments.
PATCH 10/16 clk: samsung: pll: Add support for rate configuration of PLL45xx
In reply to Tomasz FigaThis patch implements round_rate and set_rate callbacks of PLL45xx driver to allow reconfiguration of PLL at runtime.
--- drivers/clk/samsung/clk-pll.c | 109 +++++++++++++++++++++++++++++++++++++++++- drivers/clk/samsung/clk-pll.h | 10 ++++ 2 files changed, 118 insertions(+), 1 deletion(-)
drivers/clk/samsung/clk-pll.c +108 -1
@@ -10,9 +10,12 @@*/ #include <linux/errno.h> +#include <linux/hrtimer.h> #include "clk.h" #include "clk-pll.h" +#define PLL_TIMEOUT_MS 10 +struct samsung_clk_pll {struct clk_hw hw;void __iomem *lock_reg;
@@ -272,13 +275,20 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {/* * PLL45xx Clock Type */ +#define PLL4502_LOCK_FACTOR 400 +#define PLL4508_LOCK_FACTOR 240#define PLL45XX_MDIV_MASK (0x3FF)#define PLL45XX_PDIV_MASK (0x3F)#define PLL45XX_SDIV_MASK (0x7) +#define PLL45XX_AFC_MASK (0x1F)#define PLL45XX_MDIV_SHIFT (16)#define PLL45XX_PDIV_SHIFT (8)#define PLL45XX_SDIV_SHIFT (0) +#define PLL45XX_AFC_SHIFT (0) + +#define PLL45XX_ENABLE BIT(31) +#define PLL45XX_LOCKED BIT(29)static unsigned long samsung_pll45xx_recalc_rate (struct clk_hw *hw,unsigned long parent_rate)
@@ -301,8 +311,100 @@ static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,return (unsigned long )fvco; } +static bool samsung_pll45xx_mp_change (u32 pll_con0,u32 pll_con1, +const struct samsung_pll_rate_table *rate) +{ +u32 old_mdiv, old_pdiv, old_afc; + + old_mdiv = (pll_con0 >>PLL45XX_MDIV_SHIFT ) &PLL45XX_MDIV_MASK ; + old_pdiv = (pll_con0 >>PLL45XX_PDIV_SHIFT ) &PLL45XX_PDIV_MASK ; + old_afc = (pll_con1 >>PLL45XX_AFC_SHIFT ) &PLL45XX_AFC_MASK ; + +return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv); +} + +static int samsung_pll45xx_set_rate (struct clk_hw *hw,unsigned long drate, +unsigned long prate) +{ +struct samsung_clk_pll *pll =to_clk_pll (hw); +const struct samsung_pll_rate_table *rate; +u32 con0, con1; +ktime_t start; + +/* Get required rate settings from table */ + rate =samsung_get_pll_settings (pll, drate); +if (!rate) { +pr_err ("%s: Invalid rate : %lu for pll clk %s\n" , __func__, + drate,__clk_get_name (hw->clk)); +return -EINVAL ; + } + + con0 =__raw_readl (pll->con_reg); + con1 =__raw_readl (pll->con_reg +0x4 ); + +if (!(samsung_pll45xx_mp_change (con0, con1, rate))) { +/* If only s change, change just s value only*/ + con0 &= ~(PLL45XX_SDIV_MASK <<PLL45XX_SDIV_SHIFT ); + con0 |= rate->sdiv <<PLL45XX_SDIV_SHIFT ; +__raw_writel (con0, pll->con_reg); + +return 0 ; + } + +/* Set PLL PMS values. */ + con0 &= ~((PLL45XX_MDIV_MASK <<PLL45XX_MDIV_SHIFT ) | + (PLL45XX_PDIV_MASK <<PLL45XX_PDIV_SHIFT ) | + (PLL45XX_SDIV_MASK <<PLL45XX_SDIV_SHIFT )); + con0 |= (rate->mdiv <<PLL45XX_MDIV_SHIFT ) | + (rate->pdiv <<PLL45XX_PDIV_SHIFT ) | + (rate->sdiv <<PLL45XX_SDIV_SHIFT ); + +/* Set PLL AFC value. */ + con1 =__raw_readl (pll->con_reg +0x4 ); + con1 &= ~(PLL45XX_AFC_MASK <<PLL45XX_AFC_SHIFT ); + con1 |= (rate->afc <<PLL45XX_AFC_SHIFT ); + +/* Set PLL lock time. */ +switch (pll->type) { +case pll_4502: +__raw_writel (rate->pdiv *PLL4502_LOCK_FACTOR , pll->lock_reg); +break ; +case pll_4508: +__raw_writel (rate->pdiv *PLL4508_LOCK_FACTOR , pll->lock_reg); +break ; +default : +break ; + }; + +/* Set new configuration. */ +__raw_writel (con1, pll->con_reg +0x4 ); +__raw_writel (con0, pll->con_reg); + +/* Wait for locking. */ + start =ktime_get (); +while (!(__raw_readl (pll->con_reg) &PLL45XX_LOCKED )) { +ktime_t delta =ktime_sub (ktime_get (), start); + +if (ktime_to_ms (delta) >PLL_TIMEOUT_MS ) { +pr_err ("%s: could not lock PLL %s\n" , + __func__,__clk_get_name (hw->clk)); +return -EFAULT ; + } + +cpu_relax (); + } + +return 0 ; +} +static const struct clk_ops samsung_pll45xx_clk_ops = { .recalc_rate = samsung_pll45xx_recalc_rate, + .round_rate = samsung_pll_round_rate, + .set_rate = samsung_pll45xx_set_rate, +}; + +static const struct clk_ops samsung_pll45xx_clk_min_ops = { + .recalc_rate = samsung_pll45xx_recalc_rate, };/*
@@ -680,9 +782,14 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk, init.ops = &samsung_pll35xx_clk_ops;break ;case pll_4500: + init.ops = &samsung_pll45xx_clk_min_ops; +break ;case pll_4502:case pll_4508: - init.ops = &samsung_pll45xx_clk_ops; +if (!pll->rate_table) + init.ops = &samsung_pll45xx_clk_min_ops; +else + init.ops = &samsung_pll45xx_clk_ops;break ;/* clk_ops for 36xx and 2650 are similar */ case pll_36xx:
drivers/clk/samsung/clk-pll.h +10 -0
@@ -39,6 +39,15 @@ enum samsung_pll_type { .kdiv = (_k), \ } +#define PLL_45XX_RATE (_rate, _m, _p, _s, _afc) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + .afc = (_afc), \ + } +/* NOTE: Rate table should be kept sorted in descending order. */ struct samsung_pll_rate_table {
@@ -47,6 +56,7 @@ struct samsung_pll_rate_table {unsigned int mdiv;unsigned int sdiv;unsigned int kdiv; +unsigned int afc; };enum pll46xx_type {
Signature · 1 line
1.8.3.2
PATCH 10/16 clk: samsung: pll: Add support for rate configuration of PLL45xx
Hi Tomasz,
Quoted 50 lines · Tomasz Figa
This patch implements
round_rateandset_ratecallbacks of PLL45xx driver to allow reconfiguration of PLL at runtime.Signed-off-by Tomasz Figa <[email protected]>Signed-off-by Kyungmin Park <[email protected]>--- drivers/clk/samsung/clk-pll.c | 109 +++++++++++++++++++++++++++++++++++++++++- drivers/clk/samsung/clk-pll.h | 10 ++++ 2 files changed, 118 insertions(+), 1 deletion(-)drivers/clk/samsung/clk-pll.c +10
-0@@ -10,9 +10,12 @@*/ #include <linux/errno.h> +#include <linux/hrtimer.h> #include "clk.h" #include "clk-pll.h" +#define PLL_TIMEOUT_MS 10 +struct samsung_clk_pll {struct clk_hw hw;void __iomem *lock_reg;@@ -272,13 +275,20 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {/* * PLL45xx Clock Type */ +#define PLL4502_LOCK_FACTOR 400 +#define PLL4508_LOCK_FACTOR 240#define PLL45XX_MDIV_MASK (0x3FF)#define PLL45XX_PDIV_MASK (0x3F)#define PLL45XX_SDIV_MASK (0x7) +#define PLL45XX_AFC_MASK (0x1F)#define PLL45XX_MDIV_SHIFT (16)#define PLL45XX_PDIV_SHIFT (8)#define PLL45XX_SDIV_SHIFT (0) +#define PLL45XX_AFC_SHIFT (0) + +#define PLL45XX_ENABLE BIT(31) +#define PLL45XX_LOCKED BIT(29)static unsigned long samsung_pll45xx_recalc_rate (struct clk_hw *hw,unsigned long parent_rate)@@ -301,8 +311,100 @@ static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,return (unsigned long )fvco;
drivers/clk/samsung/clk-pll.c static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw, · line 321
Quoted 10 lines
drivers/clk/samsung/clk-pll.c +8
-0} +static bool samsung_pll45xx_mp_change (u32 pll_con0,u32 pll_con1, +const struct samsung_pll_rate_table *rate) +{ +u32 old_mdiv, old_pdiv, old_afc; + + old_mdiv = (pll_con0 >>PLL45XX_MDIV_SHIFT ) &PLL45XX_MDIV_MASK ; + old_pdiv = (pll_con0 >>PLL45XX_PDIV_SHIFT ) &PLL45XX_PDIV_MASK ; + old_afc = (pll_con1 >>PLL45XX_AFC_SHIFT ) &PLL45XX_AFC_MASK ;
old_afc doesn't required in this function.
Quoted 35 lines
drivers/clk/samsung/clk-pll.c +35
-0+ +return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv); +} + +static int samsung_pll45xx_set_rate (struct clk_hw *hw,unsigned long drate, +unsigned long prate) +{ +struct samsung_clk_pll *pll =to_clk_pll (hw); +const struct samsung_pll_rate_table *rate; +u32 con0, con1; +ktime_t start; + +/* Get required rate settings from table */ + rate =samsung_get_pll_settings (pll, drate); +if (!rate) { +pr_err ("%s: Invalid rate : %lu for pll clk %s\n" , __func__, + drate,__clk_get_name (hw->clk)); +return -EINVAL ; + } + + con0 =__raw_readl (pll->con_reg); + con1 =__raw_readl (pll->con_reg +0x4 ); + +if (!(samsung_pll45xx_mp_change (con0, con1, rate))) { +/* If only s change, change just s value only*/ + con0 &= ~(PLL45XX_SDIV_MASK <<PLL45XX_SDIV_SHIFT ); + con0 |= rate->sdiv <<PLL45XX_SDIV_SHIFT ; +__raw_writel (con0, pll->con_reg); + +return 0 ; + } + +/* Set PLL PMS values. */ + con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) | + (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
drivers/clk/samsung/clk-pll.c static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw, · line 366
Quoted 10 lines
drivers/clk/samsung/clk-pll.c +10
-0+ (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT)); + con0 |= (rate->mdiv <<PLL45XX_MDIV_SHIFT ) | + (rate->pdiv <<PLL45XX_PDIV_SHIFT ) | + (rate->sdiv <<PLL45XX_SDIV_SHIFT ); + +/* Set PLL AFC value. */ + con1 =__raw_readl (pll->con_reg +0x4 ); + con1 &= ~(PLL45XX_AFC_MASK <<PLL45XX_AFC_SHIFT ); + con1 |= (rate->afc <<PLL45XX_AFC_SHIFT ); +
Do we need to take care of AFC_ENB also, if we are using AFC ?
Regards,
Yadwinder
PATCH 10/16 clk: samsung: pll: Add support for rate configuration of PLL45xx
Quoted 73 lines · On Wednesday 21 of August 2013 17:48:44 Yadwinder Singh Brar wrote:
Hi Tomasz,
Quoted 70 lines · Tomasz Figa
This patch implements
round_rateandset_ratecallbacks of PLL45xx driver to allow reconfiguration of PLL at runtime.Signed-off-by Tomasz Figa <[email protected]>Signed-off-by Kyungmin Park <[email protected]>---
drivers/clk/samsung/clk-pll.c | 109 +++++++++++++++++++++++++++++++++++++++++- drivers/clk/samsung/clk-pll.h | 10 ++++ 2 files changed, 118 insertions(+), 1 deletion(-)(quoted diff) +0
-0
b/drivers/clk/samsung/clk-pll.cindex b0398d2..cb971cb 100644drivers/clk/samsung/clk-pll.c +3
-0@@ -10,9 +10,12 @@*/ #include <linux/errno.h> +#include <linux/hrtimer.h> #include "clk.h" #include "clk-pll.h" +#define PLL_TIMEOUT_MS 10 +struct
samsung_clk_pll{struct clk_hw hw; void __iomem *lock_reg;drivers/clk/samsung/clk-pll.c +0
-0@@ -272,13 +275,20 @@ static const struct clk_ops
samsung_pll36xx_clk_min_ops= {>
/** PLL45xx Clock Type
*/drivers/clk/samsung/clk-pll.c +7
-0+#define PLL4502_LOCK_FACTOR 400 +#define PLL4508_LOCK_FACTOR 240#define PLL45XX_MDIV_MASK (0x3FF)#define PLL45XX_PDIV_MASK (0x3F)#define PLL45XX_SDIV_MASK (0x7) +#define PLL45XX_AFC_MASK (0x1F)#define PLL45XX_MDIV_SHIFT (16)#define PLL45XX_PDIV_SHIFT (8)#define PLL45XX_SDIV_SHIFT (0) +#define PLL45XX_AFC_SHIFT (0) + +#define PLL45XX_ENABLE BIT(31) +#define PLL45XX_LOCKED BIT(29)static unsigned long samsung_pll45xx_recalc_rate (struct clk_hw *hw,unsigned long parent_rate)@@ -301,8 +311,100 @@ static unsigned longsamsung_pll45xx_recalc_rate(struct
clk_hw*hw,>return (unsigned long)fvco;}
Quoted 15 lines
Quoted 10 lines
drivers/clk/samsung/clk-pll.c +2
-0+static bool samsung_pll45xx_mp_change (u32 pll_con0,u32 pll_con1, + const struct samsung_pll_rate_table*rate) +{
drivers/clk/samsung/clk-pll.c +3
-0+u32 old_mdiv, old_pdiv, old_afc; + + old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) &
PLL45XX_MDIV_MASK;
+old_pdiv= (pll_con0>>PLL45XX_PDIV_SHIFT) &PLL45XX_PDIV_MASK;
+old_afc= (pll_con1>>PLL45XX_AFC_SHIFT) &PLL45XX_AFC_MASK;
old_afcdoesn't required in this function.Quoted 2 lines
drivers/clk/samsung/clk-pll.c +2
-0+ +return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv);
Actually it should be included in the comparison above. Thanks for spotting.
Quoted 37 lines
Quoted 37 lines
drivers/clk/samsung/clk-pll.c +3
-0+} + +static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned longdrate, + unsigned long prate)
drivers/clk/samsung/clk-pll.c +10
-0+{ +struct samsung_clk_pll *pll =to_clk_pll (hw); +const struct samsung_pll_rate_table *rate; +u32 con0, con1; +ktime_t start; + +/* Get required rate settings from table */ + rate =samsung_get_pll_settings (pll, drate); +if (!rate) { + pr_err("%s: Invalid rate : %lu for pll clk %s\n",
__func__, + drate,__clk_get_name(hw->clk));drivers/clk/samsung/clk-pll.c +22
-0+return -EINVAL ; + } + + con0 =__raw_readl (pll->con_reg); + con1 =__raw_readl (pll->con_reg +0x4 ); + +if (!(samsung_pll45xx_mp_change (con0, con1, rate))) { +/* If only s change, change just s value only*/ + con0 &= ~(PLL45XX_SDIV_MASK <<PLL45XX_SDIV_SHIFT ); + con0 |= rate->sdiv <<PLL45XX_SDIV_SHIFT ; +__raw_writel (con0, pll->con_reg); + +return 0 ; + } + +/* Set PLL PMS values. */ + con0 &= ~((PLL45XX_MDIV_MASK <<PLL45XX_MDIV_SHIFT ) | + (PLL45XX_PDIV_MASK <<PLL45XX_PDIV_SHIFT ) | + (PLL45XX_SDIV_MASK <<PLL45XX_SDIV_SHIFT )); + con0 |= (rate->mdiv <<PLL45XX_MDIV_SHIFT ) | + (rate->pdiv <<PLL45XX_PDIV_SHIFT ) | + (rate->sdiv <<PLL45XX_SDIV_SHIFT );
Quoted 8 lines
drivers/clk/samsung/clk-pll.c static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw, · line 366
Quoted 6 lines
drivers/clk/samsung/clk-pll.c +6
-0+ +/* Set PLL AFC value. */ + con1 =__raw_readl (pll->con_reg +0x4 ); + con1 &= ~(PLL45XX_AFC_MASK <<PLL45XX_AFC_SHIFT ); + con1 |= (rate->afc <<PLL45XX_AFC_SHIFT ); +Do we need to take care of
AFC_ENBalso, if we are using AFC ?
I'm not really sure. The original vendor code seems to not touch this bit at all, assuming that it has been configured by the bootloader.
We should take care for the AFC coefficient, though, as AFC might have been enabled at bootup.
I'd like to hear an opinion from someone from SLSI. Kukjin, Jingoo, do you know anything about this?
Best regards,
Tomasz
PATCH 11/16 clk: samsung: pll: Use new registration method for PLL46xx
In reply to Tomasz FigaThis patch modifies PLL46xx support code and its users to use the recently introduced common PLL registration helper.
--- drivers/clk/samsung/clk-exynos4.c | 13 +++------- drivers/clk/samsung/clk-pll.c | 52 +++++---------------------------------- drivers/clk/samsung/clk-pll.h | 14 +++-------- 3 files changed, 14 insertions(+), 65 deletions(-)
drivers/clk/samsung/clk-exynos4.c +4 -9
@@ -994,6 +994,10 @@ static struct __initdata samsung_pll_clock exynos4210_plls[nr_plls] = { APLL_CON0, "fout_apll", NULL), [mpll] =PLL_A (pll_4508, fout_mpll,"fout_mpll" ,"fin_pll" , E4210_MPLL_LOCK, E4210_MPLL_CON0, "fout_mpll", NULL), + [epll] =PLL_A (pll_4600, fout_epll,"fout_epll" ,"fin_pll" ,EPLL_LOCK , + EPLL_CON0, "fout_epll", NULL), + [vpll] =PLL_A (pll_4650c, fout_vpll,"fout_vpll" ,"mout_vpllsrc" , + VPLL_LOCK, VPLL_CON0, "fout_vpll", NULL), };static struct samsung_pll_clock exynos4x12_plls[nr_plls]__initdata = {
@@ -1012,8 +1016,6 @@ static void __init exynos4_clk_init(struct device_node *np,enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom) { - struct clk *epll, *vpll; - reg_base =of_iomap (np,0 );if (!reg_base)panic ("%s: failed to map registers\n" , __func__);
@@ -1036,13 +1038,6 @@ static void __init exynos4_clk_init(struct device_node *np,if (exynos4_soc ==EXYNOS4210 ) {samsung_clk_register_pll (exynos4210_plls,ARRAY_SIZE (exynos4210_plls), reg_base); - epll =samsung_clk_register_pll46xx ("fout_epll" ,"fin_pll" , - reg_base +EPLL_CON0 , pll_4600); - vpll =samsung_clk_register_pll46xx ("fout_vpll" ,"mout_vpllsrc" , - reg_base +VPLL_CON0 , pll_4650c); - -samsung_clk_add_lookup (epll, fout_epll); -samsung_clk_add_lookup (vpll, fout_vpll); }else {samsung_clk_register_pll (exynos4x12_plls,ARRAY_SIZE (exynos4x12_plls), reg_base);
drivers/clk/samsung/clk-pll.c +6 -46
73 lines not on this page · raw message
drivers/clk/samsung/clk-pll.h +4 -10
@@ -19,7 +19,10 @@ enum samsung_pll_type { pll_2650, pll_4500, pll_4502, - pll_4508 + pll_4508, + pll_4600, + pll_4650, + pll_4650c, };#define PLL_35XX_RATE (_rate, _m, _p, _s) \
@@ -59,15 +62,6 @@ struct samsung_pll_rate_table {unsigned int afc; }; -enum pll46xx_type { - pll_4600, - pll_4650, - pll_4650c, -}; - -extern struct clk *__init samsung_clk_register_pll46xx (const char *name, -const char *pname,const void __iomem *con_reg, -enum pll46xx_type type);extern struct clk *samsung_clk_register_pll6552 (const char *name,const char *pname,void __iomem *base); extern struct clk *samsung_clk_register_pll6553(const char *name,
Signature · 1 line
1.8.3.2
PATCH 12/16 clk: samsung: pll: Add support for rate configuration of PLL46xx
In reply to Tomasz FigaThis patch implements round_rate and set_rate callbacks of PLL46xx driver to allow reconfiguration of PLL at runtime.
--- drivers/clk/samsung/clk-pll.c | 111 +++++++++++++++++++++++++++++++++++++++++- drivers/clk/samsung/clk-pll.h | 25 ++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-)
drivers/clk/samsung/clk-pll.c +110 -1
@@ -410,10 +410,13 @@ static const struct clk_ops samsung_pll45xx_clk_min_ops = {/* * PLL46xx Clock Type */ +#define PLL46XX_LOCK_FACTOR 3000 +#define PLL46XX_VSEL_MASK (1)#define PLL46XX_MDIV_MASK (0x1FF)#define PLL46XX_PDIV_MASK (0x3F)#define PLL46XX_SDIV_MASK (0x7) +#define PLL46XX_VSEL_SHIFT (27)#define PLL46XX_MDIV_SHIFT (16)#define PLL46XX_PDIV_SHIFT (8)#define PLL46XX_SDIV_SHIFT (0)
@@ -421,6 +424,15 @@ static const struct clk_ops samsung_pll45xx_clk_min_ops = {#define PLL46XX_KDIV_MASK (0xFFFF)#define PLL4650C_KDIV_MASK (0xFFF)#define PLL46XX_KDIV_SHIFT (0) +#define PLL46XX_MFR_MASK (0x3F) +#define PLL46XX_MRR_MASK (0x1F) +#define PLL46XX_KDIV_SHIFT (0) +#define PLL46XX_MFR_SHIFT (16) +#define PLL46XX_MRR_SHIFT (24) + +#define PLL46XX_ENABLE BIT(31) +#define PLL46XX_LOCKED BIT(29) +#define PLL46XX_VSEL BIT(27)static unsigned long samsung_pll46xx_recalc_rate (struct clk_hw *hw,unsigned long parent_rate)
@@ -445,8 +457,102 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,return (unsigned long )fvco; } +static bool samsung_pll46xx_mpk_change (u32 pll_con0,u32 pll_con1, +const struct samsung_pll_rate_table *rate) +{ +u32 old_mdiv, old_pdiv, old_kdiv; + + old_mdiv = (pll_con0 >>PLL46XX_MDIV_SHIFT ) &PLL46XX_MDIV_MASK ; + old_pdiv = (pll_con0 >>PLL46XX_PDIV_SHIFT ) &PLL46XX_PDIV_MASK ; + old_kdiv = (pll_con1 >>PLL46XX_KDIV_SHIFT ) &PLL46XX_KDIV_MASK ; + +return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv + || old_kdiv != rate->kdiv); +} + +static int samsung_pll46xx_set_rate (struct clk_hw *hw,unsigned long drate, +unsigned long prate) +{ +struct samsung_clk_pll *pll =to_clk_pll (hw); +const struct samsung_pll_rate_table *rate; +u32 con0, con1, lock; +ktime_t start; + +/* Get required rate settings from table */ + rate =samsung_get_pll_settings (pll, drate); +if (!rate) { +pr_err ("%s: Invalid rate : %lu for pll clk %s\n" , __func__, + drate,__clk_get_name (hw->clk)); +return -EINVAL ; + } + + con0 =__raw_readl (pll->con_reg); + con1 =__raw_readl (pll->con_reg +0x4 ); + +if (!(samsung_pll46xx_mpk_change (con0, con1, rate))) { +/* If only s change, change just s value only*/ + con0 &= ~(PLL46XX_SDIV_MASK <<PLL46XX_SDIV_SHIFT ); + con0 |= rate->sdiv <<PLL46XX_SDIV_SHIFT ; +__raw_writel (con0, pll->con_reg); + +return 0 ; + } + +/* Set PLL lock time. */ + lock = rate->pdiv *PLL46XX_LOCK_FACTOR ; +if (lock >0xffff ) +/* Maximum lock time bitfield is 16-bit. */ + lock =0xffff ; + +/* Set PLL PMS and VSEL values. */ + con0 &= ~((PLL46XX_MDIV_MASK <<PLL46XX_MDIV_SHIFT ) | + (PLL46XX_PDIV_MASK <<PLL46XX_PDIV_SHIFT ) | + (PLL46XX_SDIV_MASK <<PLL46XX_SDIV_SHIFT ) | + (PLL46XX_VSEL_MASK <<PLL46XX_VSEL_SHIFT )); + con0 |= (rate->mdiv <<PLL46XX_MDIV_SHIFT ) | + (rate->pdiv <<PLL46XX_PDIV_SHIFT ) | + (rate->sdiv <<PLL46XX_SDIV_SHIFT ) | + (rate->vsel <<PLL46XX_VSEL_SHIFT ); + +/* Set PLL AFC, MFR and MRR values. */ + con1 =__raw_readl (pll->con_reg +0x4 ); + con1 &= ~((PLL46XX_KDIV_MASK <<PLL46XX_KDIV_SHIFT ) | + (PLL46XX_MFR_MASK <<PLL46XX_MFR_SHIFT ) | + (PLL46XX_MRR_MASK <<PLL46XX_MRR_SHIFT )); + con1 |= (rate->kdiv <<PLL46XX_KDIV_SHIFT ) | + (rate->mfr <<PLL46XX_MFR_SHIFT ) | + (rate->mrr <<PLL46XX_MRR_SHIFT ); + +/* Write configuration to PLL */ +__raw_writel (lock, pll->lock_reg); +__raw_writel (con0, pll->con_reg); +__raw_writel (con1, pll->con_reg +0x4 ); + +/* Wait for locking. */ + start =ktime_get (); +while (!(__raw_readl (pll->con_reg) &PLL46XX_LOCKED )) { +ktime_t delta =ktime_sub (ktime_get (), start); + +if (ktime_to_ms (delta) >PLL_TIMEOUT_MS ) { +pr_err ("%s: could not lock PLL %s\n" , + __func__,__clk_get_name (hw->clk)); +return -EFAULT ; + } + +cpu_relax (); + } + +return 0 ; +} +static const struct clk_ops samsung_pll46xx_clk_ops = { .recalc_rate = samsung_pll46xx_recalc_rate, + .round_rate = samsung_pll_round_rate, + .set_rate = samsung_pll46xx_set_rate, +}; + +static const struct clk_ops samsung_pll46xx_clk_min_ops = { + .recalc_rate = samsung_pll46xx_recalc_rate, };/*
@@ -757,7 +863,10 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,case pll_4600:case pll_4650:case pll_4650c: - init.ops = &samsung_pll46xx_clk_ops; +if (!pll->rate_table) + init.ops = &samsung_pll46xx_clk_min_ops; +else + init.ops = &samsung_pll46xx_clk_ops;break ;default : pr_warn("%s: Unknown pll type for pll clk %s\n",
drivers/clk/samsung/clk-pll.h +25 -0
@@ -51,6 +51,28 @@ enum samsung_pll_type { .afc = (_afc), \ } +#define PLL_4600_RATE (_rate, _m, _p, _s, _k, _vsel) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + .kdiv = (_k), \ + .vsel = (_vsel), \ + } + +#define PLL_4650_RATE (_rate, _m, _p, _s, _k, _mfr, _mrr, _vsel) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + .kdiv = (_k), \ + .mfr = (_mfr), \ + .mrr = (_mrr), \ + .vsel = (_vsel), \ + } +/* NOTE: Rate table should be kept sorted in descending order. */ struct samsung_pll_rate_table {
@@ -60,6 +82,9 @@ struct samsung_pll_rate_table {unsigned int sdiv;unsigned int kdiv;unsigned int afc; +unsigned int mfr; +unsigned int mrr; +unsigned int vsel; }; extern struct clk *samsung_clk_register_pll6552(const char *name,
Signature · 1 line
1.8.3.2
PATCH 12/16 clk: samsung: pll: Add support for rate configuration of PLL46xx
drivers/clk/samsung/clk-pll.c static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, · line 517
Quoted 6 lines
drivers/clk/samsung/clk-pll.c +6
-0+ con0 |= (rate->mdiv <<PLL46XX_MDIV_SHIFT ) | + (rate->pdiv <<PLL46XX_PDIV_SHIFT ) | + (rate->sdiv <<PLL46XX_SDIV_SHIFT ) | + (rate->vsel <<PLL46XX_VSEL_SHIFT ); + +/* Set PLL AFC, MFR and MRR values. */
This comments seems to be miss match with below code.
Quoted 8 lines
drivers/clk/samsung/clk-pll.c +8
-0+ con1 =__raw_readl (pll->con_reg +0x4 ); + con1 &= ~((PLL46XX_KDIV_MASK <<PLL46XX_KDIV_SHIFT ) | + (PLL46XX_MFR_MASK <<PLL46XX_MFR_SHIFT ) | + (PLL46XX_MRR_MASK <<PLL46XX_MRR_SHIFT )); + con1 |= (rate->kdiv <<PLL46XX_KDIV_SHIFT ) | + (rate->mfr <<PLL46XX_MFR_SHIFT ) | + (rate->mrr <<PLL46XX_MRR_SHIFT ); +
<snip>
Quoted 32 lines
drivers/clk/samsung/clk-pll.h +22
-0@@ -51,6 +51,28 @@ enum samsung_pll_type { .afc = (_afc), \ } +#define PLL_4600_RATE (_rate, _m, _p, _s, _k, _vsel) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + .kdiv = (_k), \ + .vsel = (_vsel), \ + } + +#define PLL_4650_RATE (_rate, _m, _p, _s, _k, _mfr, _mrr, _vsel) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + .kdiv = (_k), \ + .mfr = (_mfr), \ + .mrr = (_mrr), \ + .vsel = (_vsel), \ + } +/* NOTE: Rate table should be kept sorted in descending order. */ struct samsung_pll_rate_table {
drivers/clk/samsung/clk-pll.h struct samsung_pll_rate_table { · line 89
Quoted 8 lines
drivers/clk/samsung/clk-pll.h +3
-0@@ -60,6 +82,9 @@ struct samsung_pll_rate_table {unsigned int sdiv;unsigned int kdiv;unsigned int afc; +unsigned int mfr; +unsigned int mrr; +unsigned int vsel; };
This struct seems to be expanding too much.
Can we re-think on options for using bit map same as register definition? It can reduce code in set_rate also little bit.
Regards,
Yadwinder
PATCH 12/16 clk: samsung: pll: Add support for rate configuration of PLL46xx
Quoted 8 lines · On Wednesday 21 of August 2013 18:02:16 Yadwinder Singh Brar wrote:
drivers/clk/samsung/clk-pll.c static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, · line 517
Quoted 6 lines
drivers/clk/samsung/clk-pll.c +6
-0+ con0 |= (rate->mdiv <<PLL46XX_MDIV_SHIFT ) | + (rate->pdiv <<PLL46XX_PDIV_SHIFT ) | + (rate->sdiv <<PLL46XX_SDIV_SHIFT ) | + (rate->vsel <<PLL46XX_VSEL_SHIFT ); + +/* Set PLL AFC, MFR and MRR values. */ This comments seems to be miss match with below code.
Hmm, looks like a copy/paste error. Thanks for spotting.
Quoted 51 lines
Quoted 8 lines
drivers/clk/samsung/clk-pll.c +8
-0+ con1 =__raw_readl (pll->con_reg +0x4 ); + con1 &= ~((PLL46XX_KDIV_MASK <<PLL46XX_KDIV_SHIFT ) | + (PLL46XX_MFR_MASK <<PLL46XX_MFR_SHIFT ) | + (PLL46XX_MRR_MASK <<PLL46XX_MRR_SHIFT )); + con1 |= (rate->kdiv <<PLL46XX_KDIV_SHIFT ) | + (rate->mfr <<PLL46XX_MFR_SHIFT ) | + (rate->mrr <<PLL46XX_MRR_SHIFT ); +<snip>
Quoted 40 lines
drivers/clk/samsung/clk-pll.h +11
-0@@ -51,6 +51,28 @@ enum samsung_pll_type { .afc = (_afc), \ } +#define PLL_4600_RATE (_rate, _m, _p, _s, _k, _vsel) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + .kdiv = (_k), \ + .vsel = (_vsel), \ + } + +#define PLL_4650_RATE (_rate, _m, _p, _s, _k, _mfr, _mrr, _vsel)\ + { \ +
.rate = (_rate), \ +
.mdiv = (_m), \ +
.pdiv = (_p), \ +.sdiv = (_s), \ + .kdiv = (_k), \ + .mfr= (
_mfr), \ + .mrr =
(_mrr), \ + .vsel =
(_vsel), \ + }drivers/clk/samsung/clk-pll.h +1
-0+/* NOTE: Rate table should be kept sorted in descending order. */ struct samsung_pll_rate_table {@@ -60,6 +82,9 @@ struct samsung_pll_rate_table {unsigned int sdiv;unsigned int kdiv;unsigned int afc;
Quoted 7 lines
Quoted 5 lines
drivers/clk/samsung/clk-pll.h +3
-0+unsigned int mfr; +unsigned int mrr; +unsigned int vsel;};
This struct seems to be expanding too much.
I don't think it's a problem. How many bytes such tables can occupy in a system?
Quoted 2 lines
Can we re-think on options for using bit map same as register definition? It can reduce code in
set_ratealso little bit.
IMHO it is more clear what the code does when accessing a single coefficient at once.
In addition you still would need to preserve bitfields that are not changed by the driver and also unpack some of the coefficients anyway, like pdiv that is used to calculate lock time.
Best regards,
Tomasz
PATCH 12/16 clk: samsung: pll: Add support for rate configuration of PLL46xx
Quoted 46 lines
Quoted 46 lines
<snip>
Quoted 44 lines
drivers/clk/samsung/clk-pll.h +11
-0@@ -51,6 +51,28 @@ enum samsung_pll_type { .afc = (_afc), \ } +#define PLL_4600_RATE (_rate, _m, _p, _s, _k, _vsel) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + .kdiv = (_k), \ + .vsel = (_vsel), \ + } + +#define PLL_4650_RATE (_rate, _m, _p, _s, _k, _mfr, _mrr, _vsel)\ + { \ +
.rate = (_rate), \ +
.mdiv = (_m), \ +
.pdiv = (_p), \ +.sdiv = (_s), \ + .kdiv = (_k), \ + .mfr= (
_mfr), \ + .mrr =
(_mrr), \ + .vsel =
(_vsel), \ + }drivers/clk/samsung/clk-pll.h +4
-0+/* NOTE: Rate table should be kept sorted in descending order. */ struct samsung_pll_rate_table {@@ -60,6 +82,9 @@ struct samsung_pll_rate_table {unsigned int sdiv;unsigned int kdiv;unsigned int afc; +unsigned int mfr; +unsigned int mrr; +unsigned int vsel;
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
};
This struct seems to be expanding too much.
I don't think it's a problem. How many bytes such tables can occupy in a system?
no doubt comparing with memory size its negligible..
but comparing only struct size and coding lines it seems costlier :) .
Quoted 8 lines
Quoted 2 lines
Can we re-think on options for using bit map same as register definition? It can reduce code in
set_ratealso little bit.IMHO it is more clear what the code does when accessing a single coefficient at once.
In addition you still would need to preserve bitfields that are not changed by the driver
Sorry, I can't see any such problem, it will OR only the required bits.
Quoted 2 lines
and also unpack some of the coefficients anyway, like pdiv that is used to calculate lock time.
Agree, but cases of unpacking will always be less than cases of shifting and packing.
Anyways, its only MHO :).
Regards,
Yadwinder
PATCH 13/16 clk: samsung: exynos4: Reorder registration of mout_vpllsrc
In reply to Tomasz FigaSince PLL input frequency must be known before PLL registration, mout_vpllsrc clock which is a reference clock of VPLL must be registered before VPLL.
This patch reorders clock registration to register mout_vpllsrc before VPLL.
--- drivers/clk/samsung/clk-exynos4.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/clk/samsung/clk-exynos4.c +7 -1
@@ -380,12 +380,15 @@ static struct samsung_mux_clock exynos4_mux_clks[] __initdata = { };/* list of mux clocks supported in exynos4210 soc */ +static struct samsung_mux_clock exynos4210_mux_early[]__initdata = { +MUX (none,"mout_vpllsrc" , mout_vpllsrc_p,SRC_TOP1 ,0 ,1 ), +}; +static struct samsung_mux_clock exynos4210_mux_clks[]__initdata = {MUX (none,"mout_aclk200" , sclk_ampll_p4210,SRC_TOP0 ,12 ,1 ),MUX (none,"mout_aclk100" , sclk_ampll_p4210,SRC_TOP0 ,16 ,1 ),MUX (none,"mout_aclk160" , sclk_ampll_p4210,SRC_TOP0 ,20 ,1 ),MUX (none,"mout_aclk133" , sclk_ampll_p4210,SRC_TOP0 ,24 ,1 ), -MUX (none,"mout_vpllsrc" , mout_vpllsrc_p,SRC_TOP1 ,0 ,1 ),MUX (none,"mout_mixer" , mout_mixer_p4210,SRC_TV ,4 ,1 ),MUX (none,"mout_dac" , mout_dac_p4210,SRC_TV ,8 ,1 ),MUX (none,"mout_g2d0" , sclk_ampll_p4210,E4210_SRC_IMAGE ,0 ,1 ),
@@ -1036,6 +1039,9 @@ static void __init exynos4_clk_init(struct device_node *np,exynos4_clk_register_finpll (xom);if (exynos4_soc ==EXYNOS4210 ) { +samsung_clk_register_mux (exynos4210_mux_early, +ARRAY_SIZE (exynos4210_mux_early)); +samsung_clk_register_pll (exynos4210_plls,ARRAY_SIZE (exynos4210_plls), reg_base); }else {
Signature · 1 line
1.8.3.2
PATCH 14/16 clk: samsung: exynos4: Register PLL rate tables for Exynos4210
In reply to Tomasz FigaThis patch adds rate tables for PLLs that can be reconfigured at runtime for Exynos4210 SoCs. Provided tables contain PLL coefficients for input clock of 24 MHz and so are registered only in this case. MPLL does not need runtime reconfiguration and so table for it is not provided.
--- drivers/clk/samsung/clk-exynos4.c | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
drivers/clk/samsung/clk-exynos4.c +45 -0
@@ -992,6 +992,40 @@ static struct of_device_id ext_clk_match[] __initdata = { {}, }; +/* PLLs PMS values */ +static struct samsung_pll_rate_table exynos4210_apll_rates[] = { +PLL_45XX_RATE (1200000000 ,150 ,3 ,1 ,28 ), +PLL_45XX_RATE (1000000000 ,250 ,6 ,1 ,28 ), +PLL_45XX_RATE (800000000 ,200 ,6 ,1 ,28 ), +PLL_45XX_RATE (666857142 ,389 ,14 ,1 ,13 ), +PLL_45XX_RATE (600000000 ,100 ,4 ,1 ,13 ), +PLL_45XX_RATE (533000000 ,533 ,24 ,1 ,5 ), +PLL_45XX_RATE (500000000 ,250 ,6 ,2 ,28 ), +PLL_45XX_RATE (400000000 ,200 ,6 ,2 ,28 ), +PLL_45XX_RATE (200000000 ,200 ,6 ,3 ,28 ), + {/* sentinel */ } +}; + +static struct samsung_pll_rate_table exynos4210_epll_rates[] = { +PLL_4600_RATE (192000000 ,48 ,3 ,1 ,0 ,0 ), +PLL_4600_RATE (180633605 ,45 ,3 ,1 ,10381 ,0 ), +PLL_4600_RATE (180000000 ,45 ,3 ,1 ,0 ,0 ), +PLL_4600_RATE (73727996 ,73 ,3 ,3 ,47710 ,1 ), +PLL_4600_RATE (67737602 ,90 ,4 ,3 ,20762 ,1 ), +PLL_4600_RATE (49151992 ,49 ,3 ,3 ,9961 ,0 ), +PLL_4600_RATE (45158401 ,45 ,3 ,3 ,10381 ,0 ), + {/* sentinel */ } +}; + +static struct samsung_pll_rate_table exynos4210_vpll_rates[] = { +PLL_4650_RATE (360000000 ,44 ,3 ,0 ,1024 ,0 ,14 ,0 ), +PLL_4650_RATE (324000000 ,53 ,2 ,1 ,1024 ,1 ,1 ,1 ), +PLL_4650_RATE (259617187 ,63 ,3 ,1 ,1950 ,0 ,20 ,1 ), +PLL_4650_RATE (110000000 ,53 ,3 ,2 ,2048 ,0 ,17 ,0 ), +PLL_4650_RATE (55360351 ,53 ,3 ,3 ,2417 ,0 ,17 ,0 ), + {/* sentinel */ } +}; +static struct __initdata samsung_pll_clock exynos4210_plls[nr_plls] = { [apll] =PLL_A (pll_4508, fout_apll,"fout_apll" ,"fin_pll" ,APLL_LOCK ,APLL_CON0 ,"fout_apll" ,NULL ),
@@ -1042,6 +1076,17 @@ static void __init exynos4_clk_init(struct device_node *np,samsung_clk_register_mux (exynos4210_mux_early,ARRAY_SIZE (exynos4210_mux_early)); +if (_get_rate ("fin_pll" ) ==24000000 ) { + exynos4210_plls[apll].rate_table = + exynos4210_apll_rates; + exynos4210_plls[epll].rate_table = + exynos4210_epll_rates; + } + +if (_get_rate ("mout_vpllsrc" ) ==24000000 ) + exynos4210_plls[vpll].rate_table = + exynos4210_vpll_rates; +samsung_clk_register_pll (exynos4210_plls,ARRAY_SIZE (exynos4210_plls), reg_base); }else {
Signature · 1 line
1.8.3.2
PATCH 14/16 clk: samsung: exynos4: Register PLL rate tables for Exynos4210
Quoted 16 lines · Tomasz Figa
This patch adds rate tables for PLLs that can be reconfigured at runtime for Exynos4210 SoCs. Provided tables contain PLL coefficients for input clock of 24 MHz and so are registered only in this case. MPLL does not need runtime reconfiguration and so table for it is not provided.
Signed-off-by Tomasz Figa <[email protected]>Signed-off-by Kyungmin Park <[email protected]>--- drivers/clk/samsung/clk-exynos4.c | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)drivers/clk/samsung/clk-exynos4.c +0
-0
drivers/clk/samsung/clk-exynos4.c static struct of_device_id ext_clk_match[] __initdata = { · line 997
Quoted 6 lines
drivers/clk/samsung/clk-exynos4.c +3
-0@@ -992,6 +992,40 @@ static struct of_device_id ext_clk_match[] __initdata = { {}, }; +/* PLLs PMS values */ +static struct samsung_pll_rate_table exynos4210_apll_rates[] = { +PLL_45XX_RATE (1200000000 ,150 ,3 ,1 ,28 ),
All these tables in this patch as well as next patch can be __initdata
Regards,
Yadwinder
PATCH 14/16 clk: samsung: exynos4: Register PLL rate tables for Exynos4210
Quoted 24 lines · On Wednesday 21 of August 2013 18:04:07 Yadwinder Singh Brar wrote:
Quoted 23 lines · Tomasz Figa
This patch adds rate tables for PLLs that can be reconfigured at runtime
for Exynos4210 SoCs. Provided tables contain PLL coefficients for input clock of 24 MHz and so are registered only in this case. MPLL does
not need runtime reconfiguration and so table for it is not provided.Signed-off-by Tomasz Figa <[email protected]>Signed-off-by Kyungmin Park <[email protected]>---
drivers/clk/samsung/clk-exynos4.c | 45+++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
(quoted diff) +0
-0
b/drivers/clk/samsung/clk-exynos4.cindex 34474ce..e18cfae 100644drivers/clk/samsung/clk-exynos4.c +0
-0@@ -992,6 +992,40 @@ static struct of_device_id ext_clk_match[]
__initdata= {>{},
Quoted 7 lines
drivers/clk/samsung/clk-exynos4.c static struct of_device_id ext_clk_match[] __initdata = { · line 997
Quoted 5 lines
};
drivers/clk/samsung/clk-exynos4.c +3
-0+/* PLLs PMS values */ +static struct samsung_pll_rate_table exynos4210_apll_rates[] = { +PLL_45XX_RATE (1200000000 ,150 ,3 ,1 ,28 ),All these tables in this patch as well as next patch can be
__initdata
Right, I forgot to mark them as such. Thanks for spotting.
Best regards,
Tomasz
PATCH 15/16 clk: samsung: exynos4: Register PLL rate tables for Exynos4x12
In reply to Tomasz FigaThis patch adds rate tables for PLLs that can be reconfigured at runtime for Exynos4x12 SoCs. Provided tables contain PLL coefficients for input clock of 24 MHz and so are registered only in this case. MPLL does not need runtime reconfiguration and so table for it is not provided.
--- drivers/clk/samsung/clk-exynos4.c | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
drivers/clk/samsung/clk-exynos4.c +49 -0
@@ -1026,6 +1026,46 @@ static struct samsung_pll_rate_table exynos4210_vpll_rates[] = { {/* sentinel */ } }; +static struct samsung_pll_rate_table exynos4x12_apll_rates[] = { +PLL_35XX_RATE (1500000000 ,250 ,4 ,0 ), +PLL_35XX_RATE (1400000000 ,175 ,3 ,0 ), +PLL_35XX_RATE (1300000000 ,325 ,6 ,0 ), +PLL_35XX_RATE (1200000000 ,200 ,4 ,0 ), +PLL_35XX_RATE (1100000000 ,275 ,6 ,0 ), +PLL_35XX_RATE (1000000000 ,125 ,3 ,0 ), +PLL_35XX_RATE (900000000 ,150 ,4 ,0 ), +PLL_35XX_RATE (800000000 ,100 ,3 ,0 ), +PLL_35XX_RATE (700000000 ,175 ,3 ,1 ), +PLL_35XX_RATE (600000000 ,200 ,4 ,1 ), +PLL_35XX_RATE (500000000 ,125 ,3 ,1 ), +PLL_35XX_RATE (400000000 ,100 ,3 ,1 ), +PLL_35XX_RATE (300000000 ,200 ,4 ,2 ), +PLL_35XX_RATE (200000000 ,100 ,3 ,2 ), + {/* sentinel */ } +}; + +static struct samsung_pll_rate_table exynos4x12_epll_rates[] = { +PLL_36XX_RATE (192000000 ,48 ,3 ,1 ,0 ), +PLL_36XX_RATE (180633605 ,45 ,3 ,1 ,10381 ), +PLL_36XX_RATE (180000000 ,45 ,3 ,1 ,0 ), +PLL_36XX_RATE (73727996 ,73 ,3 ,3 ,47710 ), +PLL_36XX_RATE (67737602 ,90 ,4 ,3 ,20762 ), +PLL_36XX_RATE (49151992 ,49 ,3 ,3 ,9961 ), +PLL_36XX_RATE (45158401 ,45 ,3 ,3 ,10381 ), + {/* sentinel */ } +}; + +static struct samsung_pll_rate_table exynos4x12_vpll_rates[] = { +PLL_36XX_RATE (533000000 ,133 ,3 ,1 ,16384 ), +PLL_36XX_RATE (440000000 ,110 ,3 ,1 ,0 ), +PLL_36XX_RATE (350000000 ,175 ,3 ,2 ,0 ), +PLL_36XX_RATE (266000000 ,133 ,3 ,2 ,0 ), +PLL_36XX_RATE (160000000 ,160 ,3 ,3 ,0 ), +PLL_36XX_RATE (106031250 ,53 ,3 ,2 ,1024 ), +PLL_36XX_RATE (53015625 ,53 ,3 ,3 ,1024 ), + {/* sentinel */ } +}; +static struct __initdata samsung_pll_clock exynos4210_plls[nr_plls] = { [apll] =PLL_A (pll_4508, fout_apll,"fout_apll" ,"fin_pll" ,APLL_LOCK ,APLL_CON0 ,"fout_apll" ,NULL ),
@@ -1090,6 +1130,15 @@ static void __init exynos4_clk_init(struct device_node *np,samsung_clk_register_pll (exynos4210_plls,ARRAY_SIZE (exynos4210_plls), reg_base); }else { +if (_get_rate ("fin_pll" ) ==24000000 ) { + exynos4x12_plls[apll].rate_table = + exynos4x12_apll_rates; + exynos4x12_plls[epll].rate_table = + exynos4x12_epll_rates; + exynos4x12_plls[vpll].rate_table = + exynos4x12_vpll_rates; + } +samsung_clk_register_pll (exynos4x12_plls,ARRAY_SIZE (exynos4x12_plls), reg_base); }
Signature · 1 line
1.8.3.2
PATCH 16/16 clk: samsung: exynos5250: Simplify registration of PLL rate tables
In reply to Tomasz FigaSince the _get_rate() helper has been modified to use __clk_lookup() internally, checking of PLL input rates can be done using it and so the registration code can be simplified.
--- drivers/clk/samsung/clk-exynos5250.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
drivers/clk/samsung/clk-exynos5250.c +2 -10
@@ -543,8 +543,6 @@ static struct of_device_id ext_clk_match[] __initdata = {static void __init exynos5250_clk_init (struct device_node *np) {void __iomem *reg_base; -struct clk *vpllsrc; -unsigned long fin_pll_rate, mout_vpllsrc_rate =0 ;if (np) { reg_base =of_iomap (np,0 );
@@ -563,16 +561,10 @@ static void __init exynos5250_clk_init(struct device_node *np)samsung_clk_register_mux (exynos5250_pll_pmux_clks,ARRAY_SIZE (exynos5250_pll_pmux_clks)); - fin_pll_rate =_get_rate ("fin_pll" ); - -if (fin_pll_rate ==24 *MHZ ) +if (_get_rate ("fin_pll" ) ==24 *MHZ ) exynos5250_plls[epll].rate_table = epll_24mhz_tbl; - vpllsrc =__clk_lookup ("mout_vpllsrc" ); -if (vpllsrc) - mout_vpllsrc_rate =clk_get_rate (vpllsrc); - -if (mout_vpllsrc_rate ==24 *MHZ ) +if (_get_rate ("mout_vpllsrc" ) ==24 *MHZ ) exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl; samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
Signature · 1 line
1.8.3.2