aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/renesas/r8a774c0-cpg-mssr.c5
-rw-r--r--drivers/clk/renesas/r8a77980-cpg-mssr.c8
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.c147
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.h4
4 files changed, 146 insertions, 18 deletions
diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
index 4f3111b3113e..aeadb4d66f3e 100644
--- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
@@ -122,6 +122,11 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
122}; 122};
123 123
124static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = { 124static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
125 DEF_MOD("tmu4", 121, R8A774C0_CLK_S0D6C),
126 DEF_MOD("tmu3", 122, R8A774C0_CLK_S3D2C),
127 DEF_MOD("tmu2", 123, R8A774C0_CLK_S3D2C),
128 DEF_MOD("tmu1", 124, R8A774C0_CLK_S3D2C),
129 DEF_MOD("tmu0", 125, R8A774C0_CLK_CP),
125 DEF_MOD("scif5", 202, R8A774C0_CLK_S3D4C), 130 DEF_MOD("scif5", 202, R8A774C0_CLK_S3D4C),
126 DEF_MOD("scif4", 203, R8A774C0_CLK_S3D4C), 131 DEF_MOD("scif4", 203, R8A774C0_CLK_S3D4C),
127 DEF_MOD("scif3", 204, R8A774C0_CLK_S3D4C), 132 DEF_MOD("scif3", 204, R8A774C0_CLK_S3D4C),
diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
index 25a3083b6764..f9e07fcc0d96 100644
--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
@@ -41,6 +41,7 @@ enum clk_ids {
41 CLK_S2, 41 CLK_S2,
42 CLK_S3, 42 CLK_S3,
43 CLK_SDSRC, 43 CLK_SDSRC,
44 CLK_RPCSRC,
44 CLK_OCO, 45 CLK_OCO,
45 46
46 /* Module Clocks */ 47 /* Module Clocks */
@@ -65,8 +66,14 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
65 DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), 66 DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
66 DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), 67 DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
67 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), 68 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
69 DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
68 DEF_RATE(".oco", CLK_OCO, 32768), 70 DEF_RATE(".oco", CLK_OCO, 32768),
69 71
72 DEF_BASE("rpc", R8A77980_CLK_RPC, CLK_TYPE_GEN3_RPC,
73 CLK_RPCSRC),
74 DEF_BASE("rpcd2", R8A77980_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
75 R8A77980_CLK_RPC),
76
70 /* Core Clock Outputs */ 77 /* Core Clock Outputs */
71 DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), 78 DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
72 DEF_FIXED("ztrd2", R8A77980_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), 79 DEF_FIXED("ztrd2", R8A77980_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
@@ -164,6 +171,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
164 DEF_MOD("gpio1", 911, R8A77980_CLK_CP), 171 DEF_MOD("gpio1", 911, R8A77980_CLK_CP),
165 DEF_MOD("gpio0", 912, R8A77980_CLK_CP), 172 DEF_MOD("gpio0", 912, R8A77980_CLK_CP),
166 DEF_MOD("can-fd", 914, R8A77980_CLK_S3D2), 173 DEF_MOD("can-fd", 914, R8A77980_CLK_S3D2),
174 DEF_MOD("rpc-if", 917, R8A77980_CLK_RPC),
167 DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6), 175 DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6),
168 DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6), 176 DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6),
169 DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2), 177 DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2),
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index be2ccbd6d623..9a8071a8114d 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -30,6 +30,21 @@
30 30
31#define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */ 31#define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */
32 32
33static spinlock_t cpg_lock;
34
35static void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set)
36{
37 unsigned long flags;
38 u32 val;
39
40 spin_lock_irqsave(&cpg_lock, flags);
41 val = readl(reg);
42 val &= ~clear;
43 val |= set;
44 writel(val, reg);
45 spin_unlock_irqrestore(&cpg_lock, flags);
46};
47
33struct cpg_simple_notifier { 48struct cpg_simple_notifier {
34 struct notifier_block nb; 49 struct notifier_block nb;
35 void __iomem *reg; 50 void __iomem *reg;
@@ -118,7 +133,6 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
118 struct cpg_z_clk *zclk = to_z_clk(hw); 133 struct cpg_z_clk *zclk = to_z_clk(hw);
119 unsigned int mult; 134 unsigned int mult;
120 unsigned int i; 135 unsigned int i;
121 u32 val, kick;
122 136
123 /* Factor of 2 is for fixed divider */ 137 /* Factor of 2 is for fixed divider */
124 mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate); 138 mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate);
@@ -127,17 +141,14 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
127 if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) 141 if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
128 return -EBUSY; 142 return -EBUSY;
129 143
130 val = readl(zclk->reg) & ~zclk->mask; 144 cpg_reg_modify(zclk->reg, zclk->mask,
131 val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask; 145 ((32 - mult) << __ffs(zclk->mask)) & zclk->mask);
132 writel(val, zclk->reg);
133 146
134 /* 147 /*
135 * Set KICK bit in FRQCRB to update hardware setting and wait for 148 * Set KICK bit in FRQCRB to update hardware setting and wait for
136 * clock change completion. 149 * clock change completion.
137 */ 150 */
138 kick = readl(zclk->kick_reg); 151 cpg_reg_modify(zclk->kick_reg, 0, CPG_FRQCRB_KICK);
139 kick |= CPG_FRQCRB_KICK;
140 writel(kick, zclk->kick_reg);
141 152
142 /* 153 /*
143 * Note: There is no HW information about the worst case latency. 154 * Note: There is no HW information about the worst case latency.
@@ -266,12 +277,10 @@ static const struct sd_div_table cpg_sd_div_table[] = {
266static int cpg_sd_clock_enable(struct clk_hw *hw) 277static int cpg_sd_clock_enable(struct clk_hw *hw)
267{ 278{
268 struct sd_clock *clock = to_sd_clock(hw); 279 struct sd_clock *clock = to_sd_clock(hw);
269 u32 val = readl(clock->csn.reg);
270
271 val &= ~(CPG_SD_STP_MASK);
272 val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK;
273 280
274 writel(val, clock->csn.reg); 281 cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK,
282 clock->div_table[clock->cur_div_idx].val &
283 CPG_SD_STP_MASK);
275 284
276 return 0; 285 return 0;
277} 286}
@@ -280,7 +289,7 @@ static void cpg_sd_clock_disable(struct clk_hw *hw)
280{ 289{
281 struct sd_clock *clock = to_sd_clock(hw); 290 struct sd_clock *clock = to_sd_clock(hw);
282 291
283 writel(readl(clock->csn.reg) | CPG_SD_STP_MASK, clock->csn.reg); 292 cpg_reg_modify(clock->csn.reg, 0, CPG_SD_STP_MASK);
284} 293}
285 294
286static int cpg_sd_clock_is_enabled(struct clk_hw *hw) 295static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
@@ -327,7 +336,6 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
327{ 336{
328 struct sd_clock *clock = to_sd_clock(hw); 337 struct sd_clock *clock = to_sd_clock(hw);
329 unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); 338 unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate);
330 u32 val;
331 unsigned int i; 339 unsigned int i;
332 340
333 for (i = 0; i < clock->div_num; i++) 341 for (i = 0; i < clock->div_num; i++)
@@ -339,10 +347,9 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
339 347
340 clock->cur_div_idx = i; 348 clock->cur_div_idx = i;
341 349
342 val = readl(clock->csn.reg); 350 cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK | CPG_SD_FC_MASK,
343 val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); 351 clock->div_table[i].val &
344 val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); 352 (CPG_SD_STP_MASK | CPG_SD_FC_MASK));
345 writel(val, clock->csn.reg);
346 353
347 return 0; 354 return 0;
348} 355}
@@ -415,6 +422,92 @@ free_clock:
415 return clk; 422 return clk;
416} 423}
417 424
425struct rpc_clock {
426 struct clk_divider div;
427 struct clk_gate gate;
428 /*
429 * One notifier covers both RPC and RPCD2 clocks as they are both
430 * controlled by the same RPCCKCR register...
431 */
432 struct cpg_simple_notifier csn;
433};
434
435static const struct clk_div_table cpg_rpcsrc_div_table[] = {
436 { 2, 5 }, { 3, 6 }, { 0, 0 },
437};
438
439static const struct clk_div_table cpg_rpc_div_table[] = {
440 { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 },
441};
442
443static struct clk * __init cpg_rpc_clk_register(const char *name,
444 void __iomem *base, const char *parent_name,
445 struct raw_notifier_head *notifiers)
446{
447 struct rpc_clock *rpc;
448 struct clk *clk;
449
450 rpc = kzalloc(sizeof(*rpc), GFP_KERNEL);
451 if (!rpc)
452 return ERR_PTR(-ENOMEM);
453
454 rpc->div.reg = base + CPG_RPCCKCR;
455 rpc->div.width = 3;
456 rpc->div.table = cpg_rpc_div_table;
457 rpc->div.lock = &cpg_lock;
458
459 rpc->gate.reg = base + CPG_RPCCKCR;
460 rpc->gate.bit_idx = 8;
461 rpc->gate.flags = CLK_GATE_SET_TO_DISABLE;
462 rpc->gate.lock = &cpg_lock;
463
464 rpc->csn.reg = base + CPG_RPCCKCR;
465
466 clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
467 &rpc->div.hw, &clk_divider_ops,
468 &rpc->gate.hw, &clk_gate_ops, 0);
469 if (IS_ERR(clk)) {
470 kfree(rpc);
471 return clk;
472 }
473
474 cpg_simple_notifier_register(notifiers, &rpc->csn);
475 return clk;
476}
477
478struct rpcd2_clock {
479 struct clk_fixed_factor fixed;
480 struct clk_gate gate;
481};
482
483static struct clk * __init cpg_rpcd2_clk_register(const char *name,
484 void __iomem *base,
485 const char *parent_name)
486{
487 struct rpcd2_clock *rpcd2;
488 struct clk *clk;
489
490 rpcd2 = kzalloc(sizeof(*rpcd2), GFP_KERNEL);
491 if (!rpcd2)
492 return ERR_PTR(-ENOMEM);
493
494 rpcd2->fixed.mult = 1;
495 rpcd2->fixed.div = 2;
496
497 rpcd2->gate.reg = base + CPG_RPCCKCR;
498 rpcd2->gate.bit_idx = 9;
499 rpcd2->gate.flags = CLK_GATE_SET_TO_DISABLE;
500 rpcd2->gate.lock = &cpg_lock;
501
502 clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
503 &rpcd2->fixed.hw, &clk_fixed_factor_ops,
504 &rpcd2->gate.hw, &clk_gate_ops, 0);
505 if (IS_ERR(clk))
506 kfree(rpcd2);
507
508 return clk;
509}
510
418 511
419static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata; 512static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata;
420static unsigned int cpg_clk_extalr __initdata; 513static unsigned int cpg_clk_extalr __initdata;
@@ -593,6 +686,21 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
593 } 686 }
594 break; 687 break;
595 688
689 case CLK_TYPE_GEN3_RPCSRC:
690 return clk_register_divider_table(NULL, core->name,
691 __clk_get_name(parent), 0,
692 base + CPG_RPCCKCR, 3, 2, 0,
693 cpg_rpcsrc_div_table,
694 &cpg_lock);
695
696 case CLK_TYPE_GEN3_RPC:
697 return cpg_rpc_clk_register(core->name, base,
698 __clk_get_name(parent), notifiers);
699
700 case CLK_TYPE_GEN3_RPCD2:
701 return cpg_rpcd2_clk_register(core->name, base,
702 __clk_get_name(parent));
703
596 default: 704 default:
597 return ERR_PTR(-EINVAL); 705 return ERR_PTR(-EINVAL);
598 } 706 }
@@ -613,5 +721,8 @@ int __init rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
613 if (attr) 721 if (attr)
614 cpg_quirks = (uintptr_t)attr->data; 722 cpg_quirks = (uintptr_t)attr->data;
615 pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks); 723 pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks);
724
725 spin_lock_init(&cpg_lock);
726
616 return 0; 727 return 0;
617} 728}
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
index f4fb6cf16688..eac1b057455a 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -23,6 +23,9 @@ enum rcar_gen3_clk_types {
23 CLK_TYPE_GEN3_Z2, 23 CLK_TYPE_GEN3_Z2,
24 CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */ 24 CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */
25 CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */ 25 CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */
26 CLK_TYPE_GEN3_RPCSRC,
27 CLK_TYPE_GEN3_RPC,
28 CLK_TYPE_GEN3_RPCD2,
26 29
27 /* SoC specific definitions start here */ 30 /* SoC specific definitions start here */
28 CLK_TYPE_GEN3_SOC_BASE, 31 CLK_TYPE_GEN3_SOC_BASE,
@@ -57,6 +60,7 @@ struct rcar_gen3_cpg_pll_config {
57 u8 osc_prediv; 60 u8 osc_prediv;
58}; 61};
59 62
63#define CPG_RPCCKCR 0x238
60#define CPG_RCKCR 0x240 64#define CPG_RCKCR 0x240
61 65
62struct clk *rcar_gen3_cpg_clk_register(struct device *dev, 66struct clk *rcar_gen3_cpg_clk_register(struct device *dev,