1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * RZ/G3L CPG driver 4 * 5 * Copyright (C) 2026 Renesas Electronics Corp. 6 */ 7 8 #include <linux/clk-provider.h> 9 #include <linux/device.h> 10 #include <linux/init.h> 11 #include <linux/kernel.h> 12 13 #include <dt-bindings/clock/renesas,r9a08g046-cpg.h> 14 15 #include "rzg2l-cpg.h" 16 17 /* RZ/G3L Specific registers. */ 18 #define G3L_CPG_PL2_DDIV (0x204) 19 #define G3L_CPG_PL3_DDIV (0x208) 20 #define G3L_CLKDIVSTATUS (0x280) 21 22 /* RZ/G3L Specific division configuration. */ 23 #define G3L_DIVPL2A DDIV_PACK(G3L_CPG_PL2_DDIV, 0, 2) 24 #define G3L_DIVPL2B DDIV_PACK(G3L_CPG_PL2_DDIV, 4, 2) 25 #define G3L_DIVPL3A DDIV_PACK(G3L_CPG_PL3_DDIV, 0, 2) 26 27 /* RZ/G3L Clock status configuration. */ 28 #define G3L_DIVPL2A_STS DDIV_PACK(G3L_CLKDIVSTATUS, 4, 1) 29 #define G3L_DIVPL2B_STS DDIV_PACK(G3L_CLKDIVSTATUS, 5, 1) 30 #define G3L_DIVPL3A_STS DDIV_PACK(G3L_CLKDIVSTATUS, 8, 1) 31 32 enum clk_ids { 33 /* Core Clock Outputs exported to DT */ 34 LAST_DT_CORE_CLK = R9A08G046_USB_SCLK, 35 36 /* External Input Clocks */ 37 CLK_EXTAL, 38 CLK_ETH0_TXC_TX_CLK_IN, 39 CLK_ETH0_RXC_RX_CLK_IN, 40 CLK_ETH1_TXC_TX_CLK_IN, 41 CLK_ETH1_RXC_RX_CLK_IN, 42 43 /* Internal Core Clocks */ 44 CLK_PLL2, 45 CLK_PLL2_DIV2, 46 CLK_PLL3, 47 CLK_PLL3_DIV2, 48 49 /* Module Clocks */ 50 MOD_CLK_BASE, 51 }; 52 53 /* Divider tables */ 54 static const struct clk_div_table dtable_4_128[] = { 55 { 0, 4 }, 56 { 1, 8 }, 57 { 2, 16 }, 58 { 3, 128 }, 59 { 0, 0 }, 60 }; 61 62 static const struct clk_div_table dtable_8_256[] = { 63 { 0, 8 }, 64 { 1, 16 }, 65 { 2, 32 }, 66 { 3, 256 }, 67 { 0, 0 }, 68 }; 69 70 static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { 71 /* External Clock Inputs */ 72 DEF_INPUT("extal", CLK_EXTAL), 73 DEF_INPUT("eth0_txc_tx_clk", CLK_ETH0_TXC_TX_CLK_IN), 74 DEF_INPUT("eth0_rxc_rx_clk", CLK_ETH0_RXC_RX_CLK_IN), 75 DEF_INPUT("eth1_txc_tx_clk", CLK_ETH1_TXC_TX_CLK_IN), 76 DEF_INPUT("eth1_rxc_rx_clk", CLK_ETH1_RXC_RX_CLK_IN), 77 78 /* Internal Core Clocks */ 79 DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3), 80 DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3), 81 DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2), 82 DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2), 83 84 /* Core output clk */ 85 DEF_G3S_DIV("P0", R9A08G046_CLK_P0, CLK_PLL2_DIV2, G3L_DIVPL2B, G3L_DIVPL2B_STS, 86 dtable_8_256, 0, 0, 0, NULL), 87 DEF_G3S_DIV("P1", R9A08G046_CLK_P1, CLK_PLL3_DIV2, G3L_DIVPL3A, G3L_DIVPL3A_STS, 88 dtable_4_128, 0, 0, 0, NULL), 89 DEF_G3S_DIV("P3", R9A08G046_CLK_P3, CLK_PLL2_DIV2, G3L_DIVPL2A, G3L_DIVPL2A_STS, 90 dtable_4_128, 0, 0, 0, NULL), 91 }; 92 93 static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { 94 DEF_MOD("gic_gicclk", R9A08G046_GIC600_GICCLK, R9A08G046_CLK_P1, 0x514, 0, 95 MSTOP(BUS_PERI_COM, BIT(12))), 96 DEF_MOD("ia55_pclk", R9A08G046_IA55_PCLK, R9A08G046_CLK_P0, 0x518, 0, 97 MSTOP(BUS_PERI_CPU, BIT(13))), 98 DEF_MOD("ia55_clk", R9A08G046_IA55_CLK, R9A08G046_CLK_P1, 0x518, 1, 99 MSTOP(BUS_PERI_CPU, BIT(13))), 100 DEF_MOD("dmac_aclk", R9A08G046_DMAC_ACLK, R9A08G046_CLK_P3, 0x52c, 0, 101 MSTOP(BUS_REG1, BIT(2))), 102 DEF_MOD("dmac_pclk", R9A08G046_DMAC_PCLK, R9A08G046_CLK_P3, 0x52c, 1, 103 MSTOP(BUS_REG1, BIT(3))), 104 DEF_MOD("scif0_clk_pck", R9A08G046_SCIF0_CLK_PCK, R9A08G046_CLK_P0, 0x584, 0, 105 MSTOP(BUS_MCPU2, BIT(1))), 106 }; 107 108 static const struct rzg2l_reset r9a08g046_resets[] = { 109 DEF_RST(R9A08G046_GIC600_GICRESET_N, 0x814, 0), 110 DEF_RST(R9A08G046_GIC600_DBG_GICRESET_N, 0x814, 1), 111 DEF_RST(R9A08G046_IA55_RESETN, 0x818, 0), 112 DEF_RST(R9A08G046_DMAC_ARESETN, 0x82c, 0), 113 DEF_RST(R9A08G046_DMAC_RST_ASYNC, 0x82c, 1), 114 DEF_RST(R9A08G046_SCIF0_RST_SYSTEM_N, 0x884, 0), 115 }; 116 117 static const unsigned int r9a08g046_crit_mod_clks[] __initconst = { 118 MOD_CLK_BASE + R9A08G046_GIC600_GICCLK, 119 MOD_CLK_BASE + R9A08G046_IA55_CLK, 120 MOD_CLK_BASE + R9A08G046_DMAC_ACLK, 121 }; 122 123 static const unsigned int r9a08g046_crit_resets[] = { 124 R9A08G046_DMAC_ARESETN, 125 R9A08G046_DMAC_RST_ASYNC, 126 }; 127 128 const struct rzg2l_cpg_info r9a08g046_cpg_info = { 129 /* Core Clocks */ 130 .core_clks = r9a08g046_core_clks, 131 .num_core_clks = ARRAY_SIZE(r9a08g046_core_clks), 132 .last_dt_core_clk = LAST_DT_CORE_CLK, 133 .num_total_core_clks = MOD_CLK_BASE, 134 135 /* Critical Module Clocks */ 136 .crit_mod_clks = r9a08g046_crit_mod_clks, 137 .num_crit_mod_clks = ARRAY_SIZE(r9a08g046_crit_mod_clks), 138 139 /* Module Clocks */ 140 .mod_clks = r9a08g046_mod_clks, 141 .num_mod_clks = ARRAY_SIZE(r9a08g046_mod_clks), 142 .num_hw_mod_clks = R9A08G046_BSC_X_BCK_BSC + 1, 143 144 /* Resets */ 145 .resets = r9a08g046_resets, 146 .num_resets = R9A08G046_BSC_X_PRESET_BSC + 1, /* Last reset ID + 1 */ 147 148 /* Critical Resets */ 149 .crit_resets = r9a08g046_crit_resets, 150 .num_crit_resets = ARRAY_SIZE(r9a08g046_crit_resets), 151 152 .has_clk_mon_regs = true, 153 }; 154