Skip to content

Commit e974872

Browse files
committed
Merge tag 'renesas-clk-for-v5.16-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into clk-renesas
Pull Renesas clk driver updates from Geert Uytterhoeven: - Add TPU (PWM), and Z (Cortex-A76) clocks on Renesas R-Car V3U - Add Ethernet clocks on Renesas RZ/G2L * tag 'renesas-clk-for-v5.16-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers: clk: renesas: r8a779a0: Add Z0 and Z1 clock support clk: renesas: r9a07g044: Add GbEthernet clock/reset clk: renesas: rzg2l: Add support to handle coupled clocks clk: renesas: r9a07g044: Add ethernet clock sources clk: renesas: rzg2l: Add support to handle MUX clocks clk: renesas: r8a779a0: Add TPU clock clk: renesas: rzg2l: Fix clk status function clk: renesas: r9a07g044: Mark IA55_CLK and DMAC_ACLK critical
2 parents 6880fa6 + cc3e8f9 commit e974872

File tree

4 files changed

+309
-3
lines changed

4 files changed

+309
-3
lines changed

drivers/clk/renesas/r8a779a0-cpg-mssr.c

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ enum rcar_r8a779a0_clk_types {
3333
CLK_TYPE_R8A779A0_PLL1,
3434
CLK_TYPE_R8A779A0_PLL2X_3X, /* PLL[23][01] */
3535
CLK_TYPE_R8A779A0_PLL5,
36+
CLK_TYPE_R8A779A0_Z,
3637
CLK_TYPE_R8A779A0_SD,
3738
CLK_TYPE_R8A779A0_MDSEL, /* Select parent/divider using mode pin */
3839
CLK_TYPE_R8A779A0_OSC, /* OSC EXTAL predivider and fixed divider */
@@ -84,6 +85,10 @@ enum clk_ids {
8485
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_PLL2X_3X, CLK_MAIN, \
8586
.offset = _offset)
8687

88+
#define DEF_Z(_name, _id, _parent, _div, _offset) \
89+
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_Z, _parent, .div = _div, \
90+
.offset = _offset)
91+
8792
#define DEF_SD(_name, _id, _parent, _offset) \
8893
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_SD, _parent, .offset = _offset)
8994

@@ -122,6 +127,8 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
122127
DEF_RATE(".oco", CLK_OCO, 32768),
123128

124129
/* Core Clock Outputs */
130+
DEF_Z("z0", R8A779A0_CLK_Z0, CLK_PLL20, 2, 0),
131+
DEF_Z("z1", R8A779A0_CLK_Z1, CLK_PLL21, 2, 8),
125132
DEF_FIXED("zx", R8A779A0_CLK_ZX, CLK_PLL20_DIV2, 2, 1),
126133
DEF_FIXED("s1d1", R8A779A0_CLK_S1D1, CLK_S1, 1, 1),
127134
DEF_FIXED("s1d2", R8A779A0_CLK_S1D2, CLK_S1, 2, 1),
@@ -205,6 +212,7 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
205212
DEF_MOD("tmu2", 715, R8A779A0_CLK_S1D4),
206213
DEF_MOD("tmu3", 716, R8A779A0_CLK_S1D4),
207214
DEF_MOD("tmu4", 717, R8A779A0_CLK_S1D4),
215+
DEF_MOD("tpu0", 718, R8A779A0_CLK_S1D8),
208216
DEF_MOD("vin00", 730, R8A779A0_CLK_S1D1),
209217
DEF_MOD("vin01", 731, R8A779A0_CLK_S1D1),
210218
DEF_MOD("vin02", 800, R8A779A0_CLK_S1D1),
@@ -259,6 +267,153 @@ static const struct rcar_r8a779a0_cpg_pll_config *cpg_pll_config __initdata;
259267
static unsigned int cpg_clk_extalr __initdata;
260268
static u32 cpg_mode __initdata;
261269

270+
/*
271+
* Z0 Clock & Z1 Clock
272+
*/
273+
#define CPG_FRQCRB 0x00000804
274+
#define CPG_FRQCRB_KICK BIT(31)
275+
#define CPG_FRQCRC 0x00000808
276+
277+
struct cpg_z_clk {
278+
struct clk_hw hw;
279+
void __iomem *reg;
280+
void __iomem *kick_reg;
281+
unsigned long max_rate; /* Maximum rate for normal mode */
282+
unsigned int fixed_div;
283+
u32 mask;
284+
};
285+
286+
#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw)
287+
288+
static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
289+
unsigned long parent_rate)
290+
{
291+
struct cpg_z_clk *zclk = to_z_clk(hw);
292+
unsigned int mult;
293+
u32 val;
294+
295+
val = readl(zclk->reg) & zclk->mask;
296+
mult = 32 - (val >> __ffs(zclk->mask));
297+
298+
return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult,
299+
32 * zclk->fixed_div);
300+
}
301+
302+
static int cpg_z_clk_determine_rate(struct clk_hw *hw,
303+
struct clk_rate_request *req)
304+
{
305+
struct cpg_z_clk *zclk = to_z_clk(hw);
306+
unsigned int min_mult, max_mult, mult;
307+
unsigned long rate, prate;
308+
309+
rate = min(req->rate, req->max_rate);
310+
if (rate <= zclk->max_rate) {
311+
/* Set parent rate to initial value for normal modes */
312+
prate = zclk->max_rate;
313+
} else {
314+
/* Set increased parent rate for boost modes */
315+
prate = rate;
316+
}
317+
req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
318+
prate * zclk->fixed_div);
319+
320+
prate = req->best_parent_rate / zclk->fixed_div;
321+
min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL);
322+
max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL);
323+
if (max_mult < min_mult)
324+
return -EINVAL;
325+
326+
mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate);
327+
mult = clamp(mult, min_mult, max_mult);
328+
329+
req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32);
330+
return 0;
331+
}
332+
333+
static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
334+
unsigned long parent_rate)
335+
{
336+
struct cpg_z_clk *zclk = to_z_clk(hw);
337+
unsigned int mult;
338+
unsigned int i;
339+
340+
mult = DIV64_U64_ROUND_CLOSEST(rate * 32ULL * zclk->fixed_div,
341+
parent_rate);
342+
mult = clamp(mult, 1U, 32U);
343+
344+
if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
345+
return -EBUSY;
346+
347+
cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask));
348+
349+
/*
350+
* Set KICK bit in FRQCRB to update hardware setting and wait for
351+
* clock change completion.
352+
*/
353+
cpg_reg_modify(zclk->kick_reg, 0, CPG_FRQCRB_KICK);
354+
355+
/*
356+
* Note: There is no HW information about the worst case latency.
357+
*
358+
* Using experimental measurements, it seems that no more than
359+
* ~10 iterations are needed, independently of the CPU rate.
360+
* Since this value might be dependent on external xtal rate, pll1
361+
* rate or even the other emulation clocks rate, use 1000 as a
362+
* "super" safe value.
363+
*/
364+
for (i = 1000; i; i--) {
365+
if (!(readl(zclk->kick_reg) & CPG_FRQCRB_KICK))
366+
return 0;
367+
368+
cpu_relax();
369+
}
370+
371+
return -ETIMEDOUT;
372+
}
373+
374+
static const struct clk_ops cpg_z_clk_ops = {
375+
.recalc_rate = cpg_z_clk_recalc_rate,
376+
.determine_rate = cpg_z_clk_determine_rate,
377+
.set_rate = cpg_z_clk_set_rate,
378+
};
379+
380+
static struct clk * __init cpg_z_clk_register(const char *name,
381+
const char *parent_name,
382+
void __iomem *reg,
383+
unsigned int div,
384+
unsigned int offset)
385+
{
386+
struct clk_init_data init = {};
387+
struct cpg_z_clk *zclk;
388+
struct clk *clk;
389+
390+
zclk = kzalloc(sizeof(*zclk), GFP_KERNEL);
391+
if (!zclk)
392+
return ERR_PTR(-ENOMEM);
393+
394+
init.name = name;
395+
init.ops = &cpg_z_clk_ops;
396+
init.flags = CLK_SET_RATE_PARENT;
397+
init.parent_names = &parent_name;
398+
init.num_parents = 1;
399+
400+
zclk->reg = reg + CPG_FRQCRC;
401+
zclk->kick_reg = reg + CPG_FRQCRB;
402+
zclk->hw.init = &init;
403+
zclk->mask = GENMASK(offset + 4, offset);
404+
zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */
405+
406+
clk = clk_register(NULL, &zclk->hw);
407+
if (IS_ERR(clk)) {
408+
kfree(zclk);
409+
return clk;
410+
}
411+
412+
zclk->max_rate = clk_hw_get_rate(clk_hw_get_parent(&zclk->hw)) /
413+
zclk->fixed_div;
414+
return clk;
415+
}
416+
262417
static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
263418
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
264419
struct clk **clks, void __iomem *base,
@@ -293,6 +448,10 @@ static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
293448
div = cpg_pll_config->pll5_div;
294449
break;
295450

451+
case CLK_TYPE_R8A779A0_Z:
452+
return cpg_z_clk_register(core->name, __clk_get_name(parent),
453+
base, core->div, core->offset);
454+
296455
case CLK_TYPE_R8A779A0_SD:
297456
return cpg_sd_clk_register(core->name, base, core->offset,
298457
__clk_get_name(parent), notifiers,

drivers/clk/renesas/r9a07g044-cpg.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ enum clk_ids {
3535
CLK_PLL3_DIV4,
3636
CLK_PLL4,
3737
CLK_PLL5,
38-
CLK_PLL5_DIV2,
38+
CLK_PLL5_FOUT3,
39+
CLK_PLL5_250,
3940
CLK_PLL6,
41+
CLK_PLL6_250,
4042
CLK_P1_DIV2,
4143

4244
/* Module Clocks */
@@ -53,6 +55,9 @@ static const struct clk_div_table dtable_1_32[] = {
5355
{0, 0},
5456
};
5557

58+
/* Mux clock tables */
59+
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
60+
5661
static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
5762
/* External Clock Inputs */
5863
DEF_INPUT("extal", CLK_EXTAL),
@@ -64,6 +69,11 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
6469
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 133, 2),
6570
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 133, 2),
6671

72+
DEF_FIXED(".pll5", CLK_PLL5, CLK_EXTAL, 125, 1),
73+
DEF_FIXED(".pll5_fout3", CLK_PLL5_FOUT3, CLK_PLL5, 1, 6),
74+
75+
DEF_FIXED(".pll6", CLK_PLL6, CLK_EXTAL, 125, 6),
76+
6777
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
6878
DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16),
6979
DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20),
@@ -73,6 +83,9 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
7383
DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2),
7484
DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4),
7585

86+
DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2),
87+
DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2),
88+
7689
/* Core output clk */
7790
DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1),
7891
DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A,
@@ -84,6 +97,10 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
8497
DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2),
8598
DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2,
8699
DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
100+
DEF_FIXED("M0", R9A07G044_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
101+
DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1),
102+
DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2,
103+
sel_pll6_2, ARRAY_SIZE(sel_pll6_2), 0, CLK_MUX_HIWORD_MASK),
87104
};
88105

89106
static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
@@ -121,6 +138,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
121138
0x578, 2),
122139
DEF_MOD("usb_pclk", R9A07G044_USB_PCLK, R9A07G044_CLK_P1,
123140
0x578, 3),
141+
DEF_COUPLED("eth0_axi", R9A07G044_ETH0_CLK_AXI, R9A07G044_CLK_M0,
142+
0x57c, 0),
143+
DEF_COUPLED("eth0_chi", R9A07G044_ETH0_CLK_CHI, R9A07G044_CLK_ZT,
144+
0x57c, 0),
145+
DEF_COUPLED("eth1_axi", R9A07G044_ETH1_CLK_AXI, R9A07G044_CLK_M0,
146+
0x57c, 1),
147+
DEF_COUPLED("eth1_chi", R9A07G044_ETH1_CLK_CHI, R9A07G044_CLK_ZT,
148+
0x57c, 1),
124149
DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0,
125150
0x580, 0),
126151
DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0,
@@ -165,6 +190,8 @@ static struct rzg2l_reset r9a07g044_resets[] = {
165190
DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1),
166191
DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2),
167192
DEF_RST(R9A07G044_USB_PRESETN, 0x878, 3),
193+
DEF_RST(R9A07G044_ETH0_RST_HW_N, 0x87c, 0),
194+
DEF_RST(R9A07G044_ETH1_RST_HW_N, 0x87c, 1),
168195
DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0),
169196
DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1),
170197
DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2),
@@ -186,6 +213,8 @@ static struct rzg2l_reset r9a07g044_resets[] = {
186213

187214
static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
188215
MOD_CLK_BASE + R9A07G044_GIC600_GICCLK,
216+
MOD_CLK_BASE + R9A07G044_IA55_CLK,
217+
MOD_CLK_BASE + R9A07G044_DMAC_ACLK,
189218
};
190219

191220
const struct rzg2l_cpg_info r9a07g044_cpg_info = {

0 commit comments

Comments
 (0)