diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2017-03-21 04:38:22 -0400 |
---|---|---|
committer | Michael Turquette <mturquette@baylibre.com> | 2017-04-12 12:51:31 -0400 |
commit | ee249cbe42f19a7edac0e8cbb95064845e2e5218 (patch) | |
tree | ee5b271043670ee82d5f62876dd77563cbb2f0f3 /drivers/clk/zte | |
parent | 5790d801762c588c63b41fbdbdb8295cfd6036e6 (diff) |
clk: zte: pd_bit is not 0 on zx296718
The bit 0 of PLL_CFG0 register is not powerdown on zx296718, but part of
of postdiv2 field. The consequence is that functions like hw_to_idx()
and zx_pll_enable() will end up tampering the postdiv2 of the PLL.
Let's fix it by defining pd_bit 0xff which is obviously invalid for a
bit position and having PLL driver check the validity before operating
on the bit.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Jun Nie <jun.nie@linaro.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Michael Turquette <mturquette@baylibre.com>
Diffstat (limited to 'drivers/clk/zte')
-rw-r--r-- | drivers/clk/zte/clk.c | 12 | ||||
-rw-r--r-- | drivers/clk/zte/clk.h | 6 |
2 files changed, 16 insertions, 2 deletions
diff --git a/drivers/clk/zte/clk.c b/drivers/clk/zte/clk.c index 878d879b23ff..b82031766ffa 100644 --- a/drivers/clk/zte/clk.c +++ b/drivers/clk/zte/clk.c | |||
@@ -52,7 +52,10 @@ static int hw_to_idx(struct clk_zx_pll *zx_pll) | |||
52 | 52 | ||
53 | /* For matching the value in lookup table */ | 53 | /* For matching the value in lookup table */ |
54 | hw_cfg0 &= ~BIT(zx_pll->lock_bit); | 54 | hw_cfg0 &= ~BIT(zx_pll->lock_bit); |
55 | hw_cfg0 |= BIT(zx_pll->pd_bit); | 55 | |
56 | /* Check availability of pd_bit */ | ||
57 | if (zx_pll->pd_bit < 32) | ||
58 | hw_cfg0 |= BIT(zx_pll->pd_bit); | ||
56 | 59 | ||
57 | for (i = 0; i < zx_pll->count; i++) { | 60 | for (i = 0; i < zx_pll->count; i++) { |
58 | if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1) | 61 | if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1) |
@@ -108,6 +111,10 @@ static int zx_pll_enable(struct clk_hw *hw) | |||
108 | struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); | 111 | struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); |
109 | u32 reg; | 112 | u32 reg; |
110 | 113 | ||
114 | /* If pd_bit is not available, simply return success. */ | ||
115 | if (zx_pll->pd_bit > 31) | ||
116 | return 0; | ||
117 | |||
111 | reg = readl_relaxed(zx_pll->reg_base); | 118 | reg = readl_relaxed(zx_pll->reg_base); |
112 | writel_relaxed(reg & ~BIT(zx_pll->pd_bit), zx_pll->reg_base); | 119 | writel_relaxed(reg & ~BIT(zx_pll->pd_bit), zx_pll->reg_base); |
113 | 120 | ||
@@ -120,6 +127,9 @@ static void zx_pll_disable(struct clk_hw *hw) | |||
120 | struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); | 127 | struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); |
121 | u32 reg; | 128 | u32 reg; |
122 | 129 | ||
130 | if (zx_pll->pd_bit > 31) | ||
131 | return; | ||
132 | |||
123 | reg = readl_relaxed(zx_pll->reg_base); | 133 | reg = readl_relaxed(zx_pll->reg_base); |
124 | writel_relaxed(reg | BIT(zx_pll->pd_bit), zx_pll->reg_base); | 134 | writel_relaxed(reg | BIT(zx_pll->pd_bit), zx_pll->reg_base); |
125 | } | 135 | } |
diff --git a/drivers/clk/zte/clk.h b/drivers/clk/zte/clk.h index 84a55a3e2bd4..4df0f121b56d 100644 --- a/drivers/clk/zte/clk.h +++ b/drivers/clk/zte/clk.h | |||
@@ -66,8 +66,12 @@ struct clk_zx_pll { | |||
66 | CLK_GET_RATE_NOCACHE), \ | 66 | CLK_GET_RATE_NOCACHE), \ |
67 | } | 67 | } |
68 | 68 | ||
69 | /* | ||
70 | * The pd_bit is not available on ZX296718, so let's pass something | ||
71 | * bigger than 31, e.g. 0xff, to indicate that. | ||
72 | */ | ||
69 | #define ZX296718_PLL(_name, _parent, _reg, _table) \ | 73 | #define ZX296718_PLL(_name, _parent, _reg, _table) \ |
70 | ZX_PLL(_name, _parent, _reg, _table, 0, 30) | 74 | ZX_PLL(_name, _parent, _reg, _table, 0xff, 30) |
71 | 75 | ||
72 | struct zx_clk_gate { | 76 | struct zx_clk_gate { |
73 | struct clk_gate gate; | 77 | struct clk_gate gate; |