@@ -35,6 +35,7 @@ config CLK_RENESAS
select CLK_R9A07G043 if ARCH_R9A07G043
select CLK_R9A07G044 if ARCH_R9A07G044
select CLK_R9A07G054 if ARCH_R9A07G054
+ select CLK_R9A09G011 if ARCH_R9A09G011
select CLK_SH73A0 if ARCH_SH73A0
if CLK_RENESAS
@@ -170,6 +171,10 @@ config CLK_R9A07G054
bool "RZ/V2L clock support" if COMPILE_TEST
select CLK_RZG2L
+config CLK_R9A09G011
+ bool "RZ/V2M clock support" if COMPILE_TEST
+ select CLK_RZG2L
+
config CLK_SH73A0
bool "SH-Mobile AG5 clock support" if COMPILE_TEST
select CLK_RENESAS_CPG_MSTP
@@ -32,6 +32,7 @@ obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
obj-$(CONFIG_CLK_R9A07G043) += r9a07g043-cpg.o
obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o
obj-$(CONFIG_CLK_R9A07G054) += r9a07g044-cpg.o
+obj-$(CONFIG_CLK_R9A09G011) += r9a09g011-cpg.o
obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o
# Family
new file mode 100644
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/V2M Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2022 Renesas Electronics Corp.
+ *
+ * Based on r9a07g044-cpg.c
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/clock/r9a09g011-cpg.h>
+
+#include "rzg2l-cpg.h"
+
+#define RZV2M_SAMPLL4_CLK1 0x104
+#define RZV2M_SAMPLL4_CLK2 0x108
+
+#define PLL4_CONF (RZV2M_SAMPLL4_CLK1 << 22 | RZV2M_SAMPLL4_CLK2 << 12)
+
+#define DIV_A DDIV_PACK(0x200, 0, 3)
+#define DIV_B DDIV_PACK(0x204, 0, 2)
+#define DIV_E DDIV_PACK(0x204, 8, 1)
+#define DIV_W DDIV_PACK(0x328, 0, 3)
+
+#define SEL_B SEL_PLL_PACK(0x214, 0, 1)
+#define SEL_E SEL_PLL_PACK(0x214, 2, 1)
+#define SEL_W0 SEL_PLL_PACK(0x32C, 0, 1)
+
+enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = 0,
+
+ /* External Input Clocks */
+ CLK_EXTAL,
+
+ /* Internal Core Clocks */
+ CLK_MAIN,
+ CLK_MAIN_24,
+ CLK_MAIN_2,
+ CLK_PLL1,
+ CLK_PLL2,
+ CLK_PLL2_800,
+ CLK_PLL2_400,
+ CLK_PLL2_200,
+ CLK_PLL2_100,
+ CLK_PLL4,
+ CLK_DIV_A,
+ CLK_DIV_B,
+ CLK_DIV_E,
+ CLK_DIV_W,
+ CLK_SEL_B,
+ CLK_SEL_B_D2,
+ CLK_SEL_E,
+ CLK_SEL_W0,
+
+ /* Module Clocks */
+ MOD_CLK_BASE
+};
+
+/* Divider tables */
+static const struct clk_div_table dtable_diva[] = {
+ {0, 1},
+ {1, 2},
+ {2, 3},
+ {3, 4},
+ {4, 6},
+ {5, 12},
+ {6, 24},
+ {0, 0},
+};
+
+static const struct clk_div_table dtable_divb[] = {
+ {0, 1},
+ {1, 2},
+ {2, 4},
+ {3, 8},
+ {0, 0},
+};
+
+static const struct clk_div_table dtable_divw[] = {
+ {0, 6},
+ {1, 7},
+ {2, 8},
+ {3, 9},
+ {4, 10},
+ {5, 11},
+ {6, 12},
+ {0, 0},
+};
+
+/* Mux clock tables */
+static const char * const sel_b[] = { ".main", ".divb" };
+static const char * const sel_e[] = { ".main", ".dive" };
+static const char * const sel_w[] = { ".main", ".divw" };
+
+static const struct cpg_core_clk r9a09g011_core_clks[] __initconst = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+
+ /* Internal Core Clocks */
+ DEF_FIXED(".main", CLK_MAIN, CLK_EXTAL, 1, 1),
+ DEF_FIXED(".main_24", CLK_MAIN_24, CLK_MAIN, 1, 2),
+ DEF_FIXED(".main_2", CLK_MAIN_2, CLK_MAIN, 1, 24),
+ DEF_FIXED(".pll1", CLK_PLL1, CLK_MAIN_2, 498, 1),
+ DEF_FIXED(".pll2", CLK_PLL2, CLK_MAIN_2, 800, 1),
+ DEF_FIXED(".pll2_800", CLK_PLL2_800, CLK_PLL2, 1, 2),
+ DEF_FIXED(".pll2_400", CLK_PLL2_400, CLK_PLL2_800, 1, 2),
+ DEF_FIXED(".pll2_200", CLK_PLL2_200, CLK_PLL2_800, 1, 4),
+ DEF_FIXED(".pll2_100", CLK_PLL2_100, CLK_PLL2_800, 1, 8),
+ DEF_SAMPLL(".pll4", CLK_PLL4, CLK_MAIN_2, PLL4_CONF),
+
+ DEF_DIV_RO(".diva", CLK_DIV_A, CLK_PLL1, DIV_A, dtable_diva),
+ DEF_DIV_RO(".divb", CLK_DIV_B, CLK_PLL2_400, DIV_B, dtable_divb),
+ DEF_DIV_RO(".dive", CLK_DIV_E, CLK_PLL2_100, DIV_E, NULL),
+ DEF_DIV_RO(".divw", CLK_DIV_W, CLK_PLL4, DIV_W, dtable_divw),
+
+ DEF_MUX_RO(".selb", CLK_SEL_B, SEL_B, sel_b),
+ DEF_MUX_RO(".sele", CLK_SEL_E, SEL_E, sel_e),
+ DEF_MUX(".selw0", CLK_SEL_W0, SEL_W0, sel_w),
+
+ DEF_FIXED(".selb_d2", CLK_SEL_B_D2, CLK_SEL_B, 1, 2),
+};
+
+static const struct rzg2l_mod_clk r9a09g011_mod_clks[] __initconst = {
+ DEF_MOD("gic", R9A09G011_GIC_CLK, CLK_SEL_B_D2, 0x400, 5),
+ DEF_MOD("syc_cnt_clk", R9A09G011_SYC_CNT_CLK, CLK_MAIN_24, 0x41c, 12),
+ DEF_MOD("urt_pclk", R9A09G011_URT_PCLK, CLK_SEL_E, 0x438, 4),
+ DEF_MOD("urt0_clk", R9A09G011_URT0_CLK, CLK_SEL_W0, 0x438, 5),
+ DEF_MOD("ca53", R9A09G011_CA53_CLK, CLK_DIV_A, 0x448, 0),
+};
+
+static const struct rzg2l_reset r9a09g011_resets[] = {
+ DEF_RST_MON(R9A09G011_SYC_RST_N, 0x610, 9, 13),
+};
+
+static const unsigned int r9a09g011_crit_mod_clks[] __initconst = {
+ MOD_CLK_BASE + R9A09G011_CA53_CLK,
+ MOD_CLK_BASE + R9A09G011_GIC_CLK,
+ MOD_CLK_BASE + R9A09G011_SYC_CNT_CLK,
+ MOD_CLK_BASE + R9A09G011_URT_PCLK,
+};
+
+const struct rzg2l_cpg_info r9a09g011_cpg_info = {
+ /* Core Clocks */
+ .core_clks = r9a09g011_core_clks,
+ .num_core_clks = ARRAY_SIZE(r9a09g011_core_clks),
+ .last_dt_core_clk = LAST_DT_CORE_CLK,
+ .num_total_core_clks = MOD_CLK_BASE,
+
+ /* Critical Module Clocks */
+ .crit_mod_clks = r9a09g011_crit_mod_clks,
+ .num_crit_mod_clks = ARRAY_SIZE(r9a09g011_crit_mod_clks),
+
+ /* Module Clocks */
+ .mod_clks = r9a09g011_mod_clks,
+ .num_mod_clks = ARRAY_SIZE(r9a09g011_mod_clks),
+ .num_hw_mod_clks = R9A09G011_CA53_CLK + 1,
+
+ /* Resets */
+ .resets = r9a09g011_resets,
+ .num_resets = ARRAY_SIZE(r9a09g011_resets),
+
+ .has_clk_mon_regs = false,
+};
@@ -976,6 +976,12 @@ static const struct of_device_id rzg2l_cpg_match[] = {
.compatible = "renesas,r9a07g054-cpg",
.data = &r9a07g054_cpg_info,
},
+#endif
+#ifdef CONFIG_CLK_R9A09G011
+ {
+ .compatible = "renesas,r9a09g011-cpg",
+ .data = &r9a09g011_cpg_info,
+ },
#endif
{ /* sentinel */ }
};
@@ -225,5 +225,6 @@ struct rzg2l_cpg_info {
extern const struct rzg2l_cpg_info r9a07g043_cpg_info;
extern const struct rzg2l_cpg_info r9a07g044_cpg_info;
extern const struct rzg2l_cpg_info r9a07g054_cpg_info;
+extern const struct rzg2l_cpg_info r9a09g011_cpg_info;
#endif