Skip to content

Commit 6edfa11

Browse files
author
Sylwester Nawrocki
committed
clk: samsung: Add enable/disable operation for PLL36XX clocks
The existing enable/disable ops for PLL35XX are made more generic and used also for PLL36XX. This fixes issues in the kernel with PLL36XX PLLs when the PLL has not been already enabled by bootloader. Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com> Tested-by: Chanwoo Choi <cw00.choi@samsung.com> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
1 parent ce3bb8f commit 6edfa11

File tree

1 file changed

+50
-37
lines changed

1 file changed

+50
-37
lines changed

drivers/clk/samsung/clk-pll.c

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ struct samsung_clk_pll {
2323
struct clk_hw hw;
2424
void __iomem *lock_reg;
2525
void __iomem *con_reg;
26+
/* PLL enable control bit offset in @con_reg register */
27+
unsigned short enable_offs;
28+
/* PLL lock status bit offset in @con_reg register */
29+
unsigned short lock_offs;
2630
enum samsung_pll_type type;
2731
unsigned int rate_count;
2832
const struct samsung_pll_rate_table *rate_table;
@@ -61,6 +65,34 @@ static long samsung_pll_round_rate(struct clk_hw *hw,
6165
return rate_table[i - 1].rate;
6266
}
6367

68+
static int samsung_pll3xxx_enable(struct clk_hw *hw)
69+
{
70+
struct samsung_clk_pll *pll = to_clk_pll(hw);
71+
u32 tmp;
72+
73+
tmp = readl_relaxed(pll->con_reg);
74+
tmp |= BIT(pll->enable_offs);
75+
writel_relaxed(tmp, pll->con_reg);
76+
77+
/* wait lock time */
78+
do {
79+
cpu_relax();
80+
tmp = readl_relaxed(pll->con_reg);
81+
} while (!(tmp & BIT(pll->lock_offs)));
82+
83+
return 0;
84+
}
85+
86+
static void samsung_pll3xxx_disable(struct clk_hw *hw)
87+
{
88+
struct samsung_clk_pll *pll = to_clk_pll(hw);
89+
u32 tmp;
90+
91+
tmp = readl_relaxed(pll->con_reg);
92+
tmp &= ~BIT(pll->enable_offs);
93+
writel_relaxed(tmp, pll->con_reg);
94+
}
95+
6496
/*
6597
* PLL2126 Clock Type
6698
*/
@@ -142,34 +174,6 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
142174
#define PLL35XX_LOCK_STAT_SHIFT (29)
143175
#define PLL35XX_ENABLE_SHIFT (31)
144176

145-
static int samsung_pll35xx_enable(struct clk_hw *hw)
146-
{
147-
struct samsung_clk_pll *pll = to_clk_pll(hw);
148-
u32 tmp;
149-
150-
tmp = readl_relaxed(pll->con_reg);
151-
tmp |= BIT(PLL35XX_ENABLE_SHIFT);
152-
writel_relaxed(tmp, pll->con_reg);
153-
154-
/* wait_lock_time */
155-
do {
156-
cpu_relax();
157-
tmp = readl_relaxed(pll->con_reg);
158-
} while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT)));
159-
160-
return 0;
161-
}
162-
163-
static void samsung_pll35xx_disable(struct clk_hw *hw)
164-
{
165-
struct samsung_clk_pll *pll = to_clk_pll(hw);
166-
u32 tmp;
167-
168-
tmp = readl_relaxed(pll->con_reg);
169-
tmp &= ~BIT(PLL35XX_ENABLE_SHIFT);
170-
writel_relaxed(tmp, pll->con_reg);
171-
}
172-
173177
static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
174178
unsigned long parent_rate)
175179
{
@@ -238,12 +242,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
238242
(rate->sdiv << PLL35XX_SDIV_SHIFT);
239243
writel_relaxed(tmp, pll->con_reg);
240244

241-
/* wait_lock_time if enabled */
242-
if (tmp & BIT(PLL35XX_ENABLE_SHIFT)) {
245+
/* Wait until the PLL is locked if it is enabled. */
246+
if (tmp & BIT(pll->enable_offs)) {
243247
do {
244248
cpu_relax();
245249
tmp = readl_relaxed(pll->con_reg);
246-
} while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT)));
250+
} while (!(tmp & BIT(pll->lock_offs)));
247251
}
248252
return 0;
249253
}
@@ -252,8 +256,8 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
252256
.recalc_rate = samsung_pll35xx_recalc_rate,
253257
.round_rate = samsung_pll_round_rate,
254258
.set_rate = samsung_pll35xx_set_rate,
255-
.enable = samsung_pll35xx_enable,
256-
.disable = samsung_pll35xx_disable,
259+
.enable = samsung_pll3xxx_enable,
260+
.disable = samsung_pll3xxx_disable,
257261
};
258262

259263
static const struct clk_ops samsung_pll35xx_clk_min_ops = {
@@ -275,6 +279,7 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = {
275279
#define PLL36XX_SDIV_SHIFT (0)
276280
#define PLL36XX_KDIV_SHIFT (0)
277281
#define PLL36XX_LOCK_STAT_SHIFT (29)
282+
#define PLL36XX_ENABLE_SHIFT (31)
278283

279284
static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
280285
unsigned long parent_rate)
@@ -354,10 +359,12 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
354359
writel_relaxed(pll_con1, pll->con_reg + 4);
355360

356361
/* wait_lock_time */
357-
do {
358-
cpu_relax();
359-
tmp = readl_relaxed(pll->con_reg);
360-
} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
362+
if (pll_con0 & BIT(pll->enable_offs)) {
363+
do {
364+
cpu_relax();
365+
tmp = readl_relaxed(pll->con_reg);
366+
} while (!(tmp & BIT(pll->lock_offs)));
367+
}
361368

362369
return 0;
363370
}
@@ -366,6 +373,8 @@ static const struct clk_ops samsung_pll36xx_clk_ops = {
366373
.recalc_rate = samsung_pll36xx_recalc_rate,
367374
.set_rate = samsung_pll36xx_set_rate,
368375
.round_rate = samsung_pll_round_rate,
376+
.enable = samsung_pll3xxx_enable,
377+
.disable = samsung_pll3xxx_disable,
369378
};
370379

371380
static const struct clk_ops samsung_pll36xx_clk_min_ops = {
@@ -1287,6 +1296,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
12871296
case pll_1450x:
12881297
case pll_1451x:
12891298
case pll_1452x:
1299+
pll->enable_offs = PLL35XX_ENABLE_SHIFT;
1300+
pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
12901301
if (!pll->rate_table)
12911302
init.ops = &samsung_pll35xx_clk_min_ops;
12921303
else
@@ -1305,6 +1316,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
13051316
/* clk_ops for 36xx and 2650 are similar */
13061317
case pll_36xx:
13071318
case pll_2650:
1319+
pll->enable_offs = PLL36XX_ENABLE_SHIFT;
1320+
pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
13081321
if (!pll->rate_table)
13091322
init.ops = &samsung_pll36xx_clk_min_ops;
13101323
else

0 commit comments

Comments
 (0)