aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMike Turquette <mturquette@ti.com>2011-10-26 16:59:49 -0500
committerZiyann <jaraidaniel@gmail.com>2014-10-01 12:55:34 +0200
commit332a7b2777f6b61e3ccde4e10c6f7112764768b1 (patch)
tree9b0c717d9f1b629625f264a1204cfdaed91edfb0 /arch
parent344c95e917fa6737933d90032f49a18591f30e58 (diff)
downloadkernel_samsung_tuna-332a7b2777f6b61e3ccde4e10c6f7112764768b1.zip
kernel_samsung_tuna-332a7b2777f6b61e3ccde4e10c6f7112764768b1.tar.gz
kernel_samsung_tuna-332a7b2777f6b61e3ccde4e10c6f7112764768b1.tar.bz2
omap: clock: bypassed DPLL clkout recalc
The output clocks for bypassed DPLLs follow the bypass rate without MN dividers applied. Simply using omap2_clksel_recalc for the recalc function of these clocks will cause the bypassed rates to have the divider programmed in HW to be applied to that rate, which is wrong. Patch introduces a new recalc function meant to handle these clocks specifically, and replaces the .recalc function pointer of each of the affected clocks. Change-Id: I9546868fb4a656e18206f3ea82b5caa6316e0b73 Signed-off-by: Mike Turquette <mturquette@ti.com> Signed-off-by: Margarita Olaya <magi.olaya@ti.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c42
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c41
3 files changed, 63 insertions, 21 deletions
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 3f90cad..c8d6f52 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -60,6 +60,7 @@ u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
unsigned long omap3_dpll_recalc(struct clk *clk);
unsigned long omap3_clkoutx2_recalc(struct clk *clk);
+unsigned long omap3_clkout_mn_recalc(struct clk *clk);
void omap3_dpll_allow_idle(struct clk *clk);
void omap3_dpll_deny_idle(struct clk *clk);
u32 omap3_dpll_autoidle_read(struct clk *clk);
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index f06eedd..b95bd2e 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -334,7 +334,7 @@ static struct clk dpll_abe_m2x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -405,7 +405,7 @@ static struct clk dpll_abe_m3x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M3_DPLL_ABE,
.clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -480,7 +480,7 @@ static struct clk dpll_core_m6x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M6_DPLL_CORE,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -512,7 +512,7 @@ static struct clk dpll_core_m2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_CORE,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap4_core_dpll_m2_set_rate,
@@ -534,7 +534,7 @@ static struct clk dpll_core_m5x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M5_DPLL_CORE,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -613,7 +613,7 @@ static struct clk dpll_core_m4x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M4_DPLL_CORE,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -640,7 +640,7 @@ static struct clk dpll_abe_m2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -655,7 +655,7 @@ static struct clk dpll_core_m3x2_ck = {
.ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DIV_M3_DPLL_CORE,
.enable_bit = OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -668,7 +668,7 @@ static struct clk dpll_core_m7x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M7_DPLL_CORE,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -745,7 +745,7 @@ static struct clk dpll_iva_m4x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M4_DPLL_IVA,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -758,7 +758,7 @@ static struct clk dpll_iva_m5x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M5_DPLL_IVA,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -808,7 +808,7 @@ static struct clk dpll_mpu_m2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -894,7 +894,7 @@ static struct clk dpll_per_m2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -922,7 +922,7 @@ static struct clk dpll_per_m2x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -937,7 +937,7 @@ static struct clk dpll_per_m3x2_ck = {
.ops = &clkops_omap4_dflt_wait,
.enable_reg = OMAP4430_CM_DIV_M3_DPLL_PER,
.enable_bit = OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -950,7 +950,7 @@ static struct clk dpll_per_m4x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M4_DPLL_PER,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -963,7 +963,7 @@ static struct clk dpll_per_m5x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M5_DPLL_PER,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -976,7 +976,7 @@ static struct clk dpll_per_m6x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M6_DPLL_PER,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -989,7 +989,7 @@ static struct clk dpll_per_m7x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M7_DPLL_PER,
.clksel_mask = OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -1049,7 +1049,7 @@ static struct clk dpll_unipro_m2x2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_UNIPRO,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
@@ -1127,7 +1127,7 @@ static struct clk dpll_usb_m2_ck = {
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_USB,
.clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK,
.ops = &clkops_omap4_dpllmx_ops,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap3_clkout_mn_recalc,
.speculate = &omap2_clksel_speculate,
.round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate,
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index ff4a10b..94dbf1b 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -688,3 +688,44 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
rate = clk->parent->rate * 2;
return rate;
}
+
+/**
+ * omap3_clkoutx2_mn_recalc - recalculate rate for DPLL clock outputs
+ * @clk: DPLL clock output
+ *
+ * Look up parent DPLL and if it is locked then recalculate rate via the usual
+ * clksel method; if it is bypassed then take the bypass clock rate.
+ */
+unsigned long omap3_clkout_mn_recalc(struct clk *clk)
+{
+ const struct dpll_data *dd;
+ unsigned long rate;
+ u32 v;
+ struct clk *pclk;
+
+ /* Walk up the parents of clk, looking for a DPLL */
+ pclk = clk->parent;
+ while (pclk && !pclk->dpll_data)
+ pclk = pclk->parent;
+
+ /* clk does not have a DPLL as a parent? */
+ WARN_ON(!pclk);
+
+ if (pclk)
+ dd = pclk->dpll_data;
+ else {
+ pr_err("%s: pclk is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ WARN_ON(!dd->enable_mask);
+
+ v = __raw_readl(dd->control_reg) & dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+ if (v == OMAP3XXX_EN_DPLL_LOCKED)
+ rate = omap2_clksel_recalc(clk);
+ else
+ rate = dd->clk_bypass->rate;
+
+ return rate;
+}