summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/renesas/Kconfig6
-rw-r--r--drivers/clk/renesas/clk-rcar-gen3.c109
-rw-r--r--drivers/clk/renesas/r8a779a0-cpg-mssr.c20
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.h28
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.c2
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.h28
6 files changed, 138 insertions, 55 deletions
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index d58e897ca1..b51837a8e7 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -45,13 +45,13 @@ config CLK_R8A7794
Enable this to support the clocks on Renesas R8A7794 SoC.
config CLK_RCAR_GEN3
- bool "Renesas RCar Gen3 clock driver"
- def_bool y if RCAR_GEN3
+ bool "Renesas RCar Gen3 and Gen4 clock driver"
+ def_bool y if RCAR_64
depends on CLK_RENESAS
select CLK_RCAR_CPG_LIB
select DM_RESET
help
- Enable this to support the clocks on Renesas RCar Gen3 SoC.
+ Enable this to support the clocks on Renesas RCar Gen3 and Gen4 SoCs.
config CLK_R8A774A1
bool "Renesas R8A774A1 clock driver"
diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c
index 1697867ff0..c8a5512b65 100644
--- a/drivers/clk/renesas/clk-rcar-gen3.c
+++ b/drivers/clk/renesas/clk-rcar-gen3.c
@@ -35,10 +35,16 @@
#define CPG_PLL2CR 0x002c
#define CPG_PLL4CR 0x01f4
-static const struct clk_div_table cpg_rpcsrc_div_table[] = {
+#define SD0CKCR1 0x08a4
+
+static const struct clk_div_table gen3_cpg_rpcsrc_div_table[] = {
{ 2, 5 }, { 3, 6 }, { 0, 0 },
};
+static const struct clk_div_table gen4_cpg_rpcsrc_div_table[] = {
+ { 0, 4 }, { 1, 6 }, { 2, 5 }, { 3, 6 }, { 0, 0 },
+};
+
static const struct clk_div_table r8a77970_cpg_sd0h_div_table[] = {
{ 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 },
{ 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 },
@@ -181,8 +187,10 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
struct cpg_mssr_info *info = priv->info;
struct clk parent;
const struct cpg_core_clk *core;
- const struct rcar_gen3_cpg_pll_config *pll_config =
- priv->cpg_pll_config;
+ const struct rcar_gen3_cpg_pll_config *gen3_pll_config =
+ priv->gen3_cpg_pll_config;
+ const struct rcar_gen4_cpg_pll_config *gen4_pll_config =
+ priv->gen4_cpg_pll_config;
u32 value, div;
u64 rate = 0;
u8 shift;
@@ -227,7 +235,7 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
case CLK_TYPE_GEN3_MAIN:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
- 0, 1, pll_config->extal_div,
+ 0, 1, gen3_pll_config->extal_div,
"MAIN");
case CLK_TYPE_GEN3_PLL0:
@@ -236,8 +244,9 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
case CLK_TYPE_GEN3_PLL1:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
- 0, pll_config->pll1_mult,
- pll_config->pll1_div, "PLL1");
+ 0, gen3_pll_config->pll1_mult,
+ gen3_pll_config->pll1_div,
+ "PLL1");
case CLK_TYPE_GEN3_PLL2:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
@@ -245,8 +254,9 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
case CLK_TYPE_GEN3_PLL3:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
- 0, pll_config->pll3_mult,
- pll_config->pll3_div, "PLL3");
+ 0, gen3_pll_config->pll3_mult,
+ gen3_pll_config->pll3_div,
+ "PLL3");
case CLK_TYPE_GEN3_PLL4:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
@@ -254,25 +264,48 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
case CLK_TYPE_GEN4_MAIN:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
- 0, 1, pll_config->extal_div,
- "V3U_MAIN");
+ 0, 1, gen4_pll_config->extal_div,
+ "MAIN");
case CLK_TYPE_GEN4_PLL1:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
- 0, pll_config->pll1_mult,
- pll_config->pll1_div,
- "V3U_PLL1");
+ 0, gen4_pll_config->pll1_mult,
+ gen4_pll_config->pll1_div,
+ "PLL1");
+
+ case CLK_TYPE_GEN4_PLL2:
+ return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
+ 0, gen4_pll_config->pll2_mult,
+ gen4_pll_config->pll2_div,
+ "PLL2");
case CLK_TYPE_GEN4_PLL2X_3X:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
- core->offset, 0, 0,
- "V3U_PLL2X_3X");
+ core->offset, 0, 0, "PLL2X_3X");
+
+ case CLK_TYPE_GEN4_PLL3:
+ return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
+ 0, gen4_pll_config->pll3_mult,
+ gen4_pll_config->pll3_div,
+ "PLL3");
+
+ case CLK_TYPE_GEN4_PLL4:
+ return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
+ 0, gen4_pll_config->pll4_mult,
+ gen4_pll_config->pll4_div,
+ "PLL4");
case CLK_TYPE_GEN4_PLL5:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
- 0, pll_config->pll5_mult,
- pll_config->pll5_div,
- "V3U_PLL5");
+ 0, gen4_pll_config->pll5_mult,
+ gen4_pll_config->pll5_div,
+ "PLL5");
+
+ case CLK_TYPE_GEN4_PLL6:
+ return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
+ 0, gen4_pll_config->pll6_mult,
+ gen4_pll_config->pll6_div,
+ "PLL6");
case CLK_TYPE_FF:
return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
@@ -288,6 +321,13 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
div, rate);
return rate;
+ case CLK_TYPE_GEN4_SDSRC:
+ div = ((readl(priv->base + SD0CKCR1) >> 29) & 0x03) + 4;
+ rate = gen3_clk_get_rate64(&parent) / div;
+ debug("%s[%i] SDSRC clk: parent=%i div=%u => rate=%llu\n",
+ __func__, __LINE__, core->parent, div, rate);
+ return rate;
+
case CLK_TYPE_GEN3_SDH: /* Fixed factor 1:1 */
fallthrough;
case CLK_TYPE_GEN4_SDH: /* Fixed factor 1:1 */
@@ -321,7 +361,16 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
gen3_clk_get_rate64(&parent),
priv->base + CPG_RPCCKCR,
CPG_RPCCKCR_DIV_POST_MASK,
- cpg_rpcsrc_div_table, "RPCSRC");
+ gen3_cpg_rpcsrc_div_table,
+ "RPCSRC");
+
+ case CLK_TYPE_GEN4_RPCSRC:
+ return rcar_clk_get_rate64_div_table(core->parent,
+ gen3_clk_get_rate64(&parent),
+ priv->base + CPG_RPCCKCR,
+ CPG_RPCCKCR_DIV_POST_MASK,
+ gen4_cpg_rpcsrc_div_table,
+ "RPCSRC");
case CLK_TYPE_GEN3_D3_RPCSRC:
case CLK_TYPE_GEN3_E3_RPCSRC:
@@ -409,6 +458,7 @@ static int gen3_clk_probe(struct udevice *dev)
struct gen3_clk_priv *priv = dev_get_priv(dev);
struct cpg_mssr_info *info =
(struct cpg_mssr_info *)dev_get_driver_data(dev);
+ const void *pll_config;
fdt_addr_t rst_base;
int ret;
@@ -427,21 +477,24 @@ static int gen3_clk_probe(struct udevice *dev)
priv->cpg_mode = readl(rst_base + info->reset_modemr_offset);
- priv->cpg_pll_config =
- (struct rcar_gen3_cpg_pll_config *)info->get_pll_config(priv->cpg_mode);
- if (!priv->cpg_pll_config->extal_div)
- return -EINVAL;
+ pll_config = info->get_pll_config(priv->cpg_mode);
if (info->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
priv->info->status_regs = mstpsr;
priv->info->control_regs = smstpcr;
priv->info->reset_regs = srcr;
priv->info->reset_clear_regs = srstclr;
- } else if (info->reg_layout == CLK_REG_LAYOUT_RCAR_V3U) {
- priv->info->status_regs = mstpsr_for_v3u;
- priv->info->control_regs = mstpcr_for_v3u;
- priv->info->reset_regs = srcr_for_v3u;
- priv->info->reset_clear_regs = srstclr_for_v3u;
+ priv->gen3_cpg_pll_config = pll_config;
+ if (!priv->gen3_cpg_pll_config->extal_div)
+ return -EINVAL;
+ } else if (info->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
+ priv->info->status_regs = mstpsr_for_gen4;
+ priv->info->control_regs = mstpcr_for_gen4;
+ priv->info->reset_regs = srcr_for_gen4;
+ priv->info->reset_clear_regs = srstclr_for_gen4;
+ priv->gen4_cpg_pll_config = pll_config;
+ if (!priv->gen4_cpg_pll_config->extal_div)
+ return -EINVAL;
} else {
return -EINVAL;
}
diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
index a9c941b6db..6b7ec36ab0 100644
--- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
@@ -232,11 +232,10 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] = {
/*
* CPG Clock Data
*/
-
/*
* MD EXTAL PLL1 PLL20 PLL30 PLL4 PLL5 OSC
* 14 13 (MHz) 21 31
- * --------------------------------------------------------
+ * ----------------------------------------------------------------
* 0 0 16.66 x 1 x128 x216 x128 x144 x192 /16
* 0 1 20 x 1 x106 x180 x106 x120 x160 /19
* 1 0 Prohibited setting
@@ -244,13 +243,12 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] = {
*/
#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \
(((md) & BIT(13)) >> 13))
-
-static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[4] = {
- /* EXTAL div PLL1 mult/div Not used OSC prediv PLL5 mult/div */
- { 1, 128, 1, 128, 1, 16, 192, 1, },
- { 1, 106, 1, 106, 1, 19, 160, 1, },
- { 0, 0, 0, 0, 0, 0, 0, 0, },
- { 2, 128, 1, 128, 1, 32, 192, 1, },
+static const struct rcar_gen4_cpg_pll_config cpg_pll_configs[4] = {
+ /* EXTAL div PLL1 mult/div PLL2 mult/div PLL3 mult/div PLL4 mult/div PLL5 mult/div PLL6 mult/div OSC prediv */
+ { 1, 128, 1, 0, 0, 0, 0, 144, 1, 192, 1, 0, 0, 16, },
+ { 1, 106, 1, 0, 0, 0, 0, 120, 1, 160, 1, 0, 0, 19, },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+ { 2, 128, 1, 0, 0, 0, 0, 144, 1, 192, 1, 0, 0, 32, },
};
/*
@@ -292,13 +290,13 @@ static const struct cpg_mssr_info r8a779a0_cpg_mssr_info = {
.mstp_table = r8a779a0_mstp_table,
.mstp_table_size = ARRAY_SIZE(r8a779a0_mstp_table),
.reset_node = "renesas,r8a779a0-rst",
- .reset_modemr_offset = 0x00,
+ .reset_modemr_offset = CPG_RST_MODEMR0,
.extalr_node = "extalr",
.mod_clk_base = MOD_CLK_BASE,
.clk_extal_id = CLK_EXTAL,
.clk_extalr_id = CLK_EXTALR,
.get_pll_config = r8a779a0_get_pll_config,
- .reg_layout = CLK_REG_LAYOUT_RCAR_V3U,
+ .reg_layout = CLK_REG_LAYOUT_RCAR_GEN4,
};
static const struct udevice_id r8a779a0_cpg_ids[] = {
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
index 894e376549..06318c81ac 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -34,8 +34,13 @@ enum rcar_gen3_clk_types {
CLK_TYPE_GEN4_MAIN,
CLK_TYPE_GEN4_PLL1,
- CLK_TYPE_GEN4_PLL2X_3X, /* PLL[23][01] */
+ CLK_TYPE_GEN4_PLL2,
+ CLK_TYPE_GEN4_PLL2X_3X, /* R8A779A0 only */
+ CLK_TYPE_GEN4_PLL3,
CLK_TYPE_GEN4_PLL5,
+ CLK_TYPE_GEN4_PLL4,
+ CLK_TYPE_GEN4_PLL6,
+ CLK_TYPE_GEN4_SDSRC,
CLK_TYPE_GEN4_SDH,
CLK_TYPE_GEN4_SD,
CLK_TYPE_GEN4_MDSEL, /* Select parent/divider using mode pin */
@@ -107,11 +112,27 @@ struct rcar_gen3_cpg_pll_config {
u8 pll3_mult;
u8 pll3_div;
u8 osc_prediv;
+};
+
+struct rcar_gen4_cpg_pll_config {
+ u8 extal_div;
+ u8 pll1_mult;
+ u8 pll1_div;
+ u8 pll2_mult;
+ u8 pll2_div;
+ u8 pll3_mult;
+ u8 pll3_div;
+ u8 pll4_mult;
+ u8 pll4_div;
u8 pll5_mult;
u8 pll5_div;
+ u8 pll6_mult;
+ u8 pll6_div;
+ u8 osc_prediv;
};
#define CPG_RST_MODEMR 0x060
+#define CPG_RST_MODEMR0 0x000
#define CPG_SDCKCR_STPnHCK BIT(9)
#define CPG_SDCKCR_STPnCK BIT(8)
@@ -133,7 +154,10 @@ struct gen3_clk_priv {
struct clk clk_extal;
struct clk clk_extalr;
u32 cpg_mode;
- const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
+ union {
+ const struct rcar_gen3_cpg_pll_config *gen3_cpg_pll_config;
+ const struct rcar_gen4_cpg_pll_config *gen4_cpg_pll_config;
+ };
};
int gen3_cpg_bind(struct udevice *parent);
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index e0895d2c2f..10bd54d600 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -128,7 +128,7 @@ int renesas_clk_remove(void __iomem *base, struct cpg_mssr_info *info)
info->mstp_table[i].sdis,
info->mstp_table[i].sen);
- if (info->reg_layout == CLK_REG_LAYOUT_RCAR_V3U)
+ if (info->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4)
continue;
clrsetbits_le32(base + RMSTPCR(i),
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index 519f88548f..71e409f3eb 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -17,7 +17,7 @@
enum clk_reg_layout {
CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0,
- CLK_REG_LAYOUT_RCAR_V3U,
+ CLK_REG_LAYOUT_RCAR_GEN4,
};
struct cpg_mssr_info {
@@ -134,7 +134,7 @@ int renesas_clk_remove(void __iomem *base, struct cpg_mssr_info *info);
* Module Standby and Software Reset register offets.
*
* If the registers exist, these are valid for SH-Mobile, R-Mobile,
- * R-Car Gen2, R-Car Gen3, and RZ/G1.
+ * R-Car Gen2, R-Car Gen3, R-Car Gen4 and RZ/G1.
* These are NOT valid for R-Car Gen1 and RZ/A1!
*/
@@ -147,9 +147,11 @@ static const u16 mstpsr[] = {
0x9A0, 0x9A4, 0x9A8, 0x9AC,
};
-static const u16 mstpsr_for_v3u[] = {
+static const u16 mstpsr_for_gen4[] = {
0x2E00, 0x2E04, 0x2E08, 0x2E0C, 0x2E10, 0x2E14, 0x2E18, 0x2E1C,
- 0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38,
+ 0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38, 0x2E3C,
+ 0x2E40, 0x2E44, 0x2E48, 0x2E4C, 0x2E50, 0x2E54, 0x2E58, 0x2E5C,
+ 0x2E60, 0x2E64, 0x2E68, 0x2E6C,
};
/*
@@ -161,9 +163,11 @@ static const u16 smstpcr[] = {
0x990, 0x994, 0x998, 0x99C,
};
-static const u16 mstpcr_for_v3u[] = {
+static const u16 mstpcr_for_gen4[] = {
0x2D00, 0x2D04, 0x2D08, 0x2D0C, 0x2D10, 0x2D14, 0x2D18, 0x2D1C,
- 0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38,
+ 0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38, 0x2D3C,
+ 0x2D40, 0x2D44, 0x2D48, 0x2D4C, 0x2D50, 0x2D54, 0x2D58, 0x2D5C,
+ 0x2D60, 0x2D64, 0x2D68, 0x2D6C,
};
/*
@@ -175,9 +179,11 @@ static const u16 srcr[] = {
0x920, 0x924, 0x928, 0x92C,
};
-static const u16 srcr_for_v3u[] = {
+static const u16 srcr_for_gen4[] = {
0x2C00, 0x2C04, 0x2C08, 0x2C0C, 0x2C10, 0x2C14, 0x2C18, 0x2C1C,
- 0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38,
+ 0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38, 0x2C3C,
+ 0x2C40, 0x2C44, 0x2C48, 0x2C4C, 0x2C50, 0x2C54, 0x2C58, 0x2C5C,
+ 0x2C60, 0x2C64, 0x2C68, 0x2C6C,
};
/* Realtime Module Stop Control Register offsets */
@@ -193,9 +199,11 @@ static const u16 srstclr[] = {
0x960, 0x964, 0x968, 0x96C,
};
-static const u16 srstclr_for_v3u[] = {
+static const u16 srstclr_for_gen4[] = {
0x2C80, 0x2C84, 0x2C88, 0x2C8C, 0x2C90, 0x2C94, 0x2C98, 0x2C9C,
- 0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8,
+ 0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8, 0x2CBC,
+ 0x2CC0, 0x2CC4, 0x2CC8, 0x2CCC, 0x2CD0, 0x2CD4, 0x2CD8, 0x2CDC,
+ 0x2CE0, 0x2CE4, 0x2CE8, 0x2CEC,
};
#endif /* __DRIVERS_CLK_RENESAS_CPG_MSSR__ */