1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2021 Linaro Ltd. 4 * Author: Sam Protsenko <semen.protsenko@linaro.org> 5 * 6 * Common Clock Framework support for Exynos850 SoC. 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/clk-provider.h> 11 #include <linux/of.h> 12 #include <linux/of_address.h> 13 #include <linux/of_device.h> 14 #include <linux/platform_device.h> 15 16 #include <dt-bindings/clock/exynos850.h> 17 18 #include "clk.h" 19 20 /* Gate register bits */ 21 #define GATE_MANUAL BIT(20) 22 #define GATE_ENABLE_HWACG BIT(28) 23 24 /* Gate register offsets range */ 25 #define GATE_OFF_START 0x2000 26 #define GATE_OFF_END 0x2fff 27 28 /** 29 * exynos850_init_clocks - Set clocks initial configuration 30 * @np: CMU device tree node with "reg" property (CMU addr) 31 * @reg_offs: Register offsets array for clocks to init 32 * @reg_offs_len: Number of register offsets in reg_offs array 33 * 34 * Set manual control mode for all gate clocks. 35 */ 36 static void __init exynos850_init_clocks(struct device_node *np, 37 const unsigned long *reg_offs, size_t reg_offs_len) 38 { 39 void __iomem *reg_base; 40 size_t i; 41 42 reg_base = of_iomap(np, 0); 43 if (!reg_base) 44 panic("%s: failed to map registers\n", __func__); 45 46 for (i = 0; i < reg_offs_len; ++i) { 47 void __iomem *reg = reg_base + reg_offs[i]; 48 u32 val; 49 50 /* Modify only gate clock registers */ 51 if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END) 52 continue; 53 54 val = readl(reg); 55 val |= GATE_MANUAL; 56 val &= ~GATE_ENABLE_HWACG; 57 writel(val, reg); 58 } 59 60 iounmap(reg_base); 61 } 62 63 /* ---- CMU_TOP ------------------------------------------------------------- */ 64 65 /* Register Offset definitions for CMU_TOP (0x120e0000) */ 66 #define PLL_LOCKTIME_PLL_MMC 0x0000 67 #define PLL_LOCKTIME_PLL_SHARED0 0x0004 68 #define PLL_LOCKTIME_PLL_SHARED1 0x0008 69 #define PLL_CON0_PLL_MMC 0x0100 70 #define PLL_CON3_PLL_MMC 0x010c 71 #define PLL_CON0_PLL_SHARED0 0x0140 72 #define PLL_CON3_PLL_SHARED0 0x014c 73 #define PLL_CON0_PLL_SHARED1 0x0180 74 #define PLL_CON3_PLL_SHARED1 0x018c 75 #define CLK_CON_MUX_MUX_CLKCMU_APM_BUS 0x1000 76 #define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS 0x1014 77 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI 0x1018 78 #define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD 0x101c 79 #define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS 0x1020 80 #define CLK_CON_MUX_MUX_CLKCMU_DPU 0x1034 81 #define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS 0x103c 82 #define CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD 0x1040 83 #define CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD 0x1044 84 #define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS 0x1070 85 #define CLK_CON_MUX_MUX_CLKCMU_PERI_IP 0x1074 86 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART 0x1078 87 #define CLK_CON_DIV_CLKCMU_APM_BUS 0x180c 88 #define CLK_CON_DIV_CLKCMU_CORE_BUS 0x1820 89 #define CLK_CON_DIV_CLKCMU_CORE_CCI 0x1824 90 #define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD 0x1828 91 #define CLK_CON_DIV_CLKCMU_CORE_SSS 0x182c 92 #define CLK_CON_DIV_CLKCMU_DPU 0x1840 93 #define CLK_CON_DIV_CLKCMU_HSI_BUS 0x1848 94 #define CLK_CON_DIV_CLKCMU_HSI_MMC_CARD 0x184c 95 #define CLK_CON_DIV_CLKCMU_HSI_USB20DRD 0x1850 96 #define CLK_CON_DIV_CLKCMU_PERI_BUS 0x187c 97 #define CLK_CON_DIV_CLKCMU_PERI_IP 0x1880 98 #define CLK_CON_DIV_CLKCMU_PERI_UART 0x1884 99 #define CLK_CON_DIV_PLL_SHARED0_DIV2 0x188c 100 #define CLK_CON_DIV_PLL_SHARED0_DIV3 0x1890 101 #define CLK_CON_DIV_PLL_SHARED0_DIV4 0x1894 102 #define CLK_CON_DIV_PLL_SHARED1_DIV2 0x1898 103 #define CLK_CON_DIV_PLL_SHARED1_DIV3 0x189c 104 #define CLK_CON_DIV_PLL_SHARED1_DIV4 0x18a0 105 #define CLK_CON_GAT_GATE_CLKCMU_APM_BUS 0x2008 106 #define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS 0x201c 107 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI 0x2020 108 #define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD 0x2024 109 #define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS 0x2028 110 #define CLK_CON_GAT_GATE_CLKCMU_DPU 0x203c 111 #define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS 0x2044 112 #define CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD 0x2048 113 #define CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD 0x204c 114 #define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS 0x2080 115 #define CLK_CON_GAT_GATE_CLKCMU_PERI_IP 0x2084 116 #define CLK_CON_GAT_GATE_CLKCMU_PERI_UART 0x2088 117 118 static const unsigned long top_clk_regs[] __initconst = { 119 PLL_LOCKTIME_PLL_MMC, 120 PLL_LOCKTIME_PLL_SHARED0, 121 PLL_LOCKTIME_PLL_SHARED1, 122 PLL_CON0_PLL_MMC, 123 PLL_CON3_PLL_MMC, 124 PLL_CON0_PLL_SHARED0, 125 PLL_CON3_PLL_SHARED0, 126 PLL_CON0_PLL_SHARED1, 127 PLL_CON3_PLL_SHARED1, 128 CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 129 CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 130 CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 131 CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, 132 CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 133 CLK_CON_MUX_MUX_CLKCMU_DPU, 134 CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 135 CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, 136 CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 137 CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 138 CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 139 CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 140 CLK_CON_DIV_CLKCMU_APM_BUS, 141 CLK_CON_DIV_CLKCMU_CORE_BUS, 142 CLK_CON_DIV_CLKCMU_CORE_CCI, 143 CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, 144 CLK_CON_DIV_CLKCMU_CORE_SSS, 145 CLK_CON_DIV_CLKCMU_DPU, 146 CLK_CON_DIV_CLKCMU_HSI_BUS, 147 CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, 148 CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 149 CLK_CON_DIV_CLKCMU_PERI_BUS, 150 CLK_CON_DIV_CLKCMU_PERI_IP, 151 CLK_CON_DIV_CLKCMU_PERI_UART, 152 CLK_CON_DIV_PLL_SHARED0_DIV2, 153 CLK_CON_DIV_PLL_SHARED0_DIV3, 154 CLK_CON_DIV_PLL_SHARED0_DIV4, 155 CLK_CON_DIV_PLL_SHARED1_DIV2, 156 CLK_CON_DIV_PLL_SHARED1_DIV3, 157 CLK_CON_DIV_PLL_SHARED1_DIV4, 158 CLK_CON_GAT_GATE_CLKCMU_APM_BUS, 159 CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 160 CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 161 CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, 162 CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 163 CLK_CON_GAT_GATE_CLKCMU_DPU, 164 CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 165 CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, 166 CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 167 CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 168 CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 169 CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 170 }; 171 172 /* 173 * Do not provide PLL tables to core PLLs, as MANUAL_PLL_CTRL bit is not set 174 * for those PLLs by default, so set_rate operation would fail. 175 */ 176 static const struct samsung_pll_clock top_pll_clks[] __initconst = { 177 /* CMU_TOP_PURECLKCOMP */ 178 PLL(pll_0822x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk", 179 PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, 180 NULL), 181 PLL(pll_0822x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk", 182 PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, 183 NULL), 184 PLL(pll_0831x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk", 185 PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL), 186 }; 187 188 /* List of parent clocks for Muxes in CMU_TOP */ 189 PNAME(mout_shared0_pll_p) = { "oscclk", "fout_shared0_pll" }; 190 PNAME(mout_shared1_pll_p) = { "oscclk", "fout_shared1_pll" }; 191 PNAME(mout_mmc_pll_p) = { "oscclk", "fout_mmc_pll" }; 192 /* List of parent clocks for Muxes in CMU_TOP: for CMU_APM */ 193 PNAME(mout_clkcmu_apm_bus_p) = { "dout_shared0_div4", "pll_shared1_div4" }; 194 /* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */ 195 PNAME(mout_core_bus_p) = { "dout_shared1_div2", "dout_shared0_div3", 196 "dout_shared1_div3", "dout_shared0_div4" }; 197 PNAME(mout_core_cci_p) = { "dout_shared0_div2", "dout_shared1_div2", 198 "dout_shared0_div3", "dout_shared1_div3" }; 199 PNAME(mout_core_mmc_embd_p) = { "oscclk", "dout_shared0_div2", 200 "dout_shared1_div2", "dout_shared0_div3", 201 "dout_shared1_div3", "mout_mmc_pll", 202 "oscclk", "oscclk" }; 203 PNAME(mout_core_sss_p) = { "dout_shared0_div3", "dout_shared1_div3", 204 "dout_shared0_div4", "dout_shared1_div4" }; 205 /* List of parent clocks for Muxes in CMU_TOP: for CMU_HSI */ 206 PNAME(mout_hsi_bus_p) = { "dout_shared0_div2", "dout_shared1_div2" }; 207 PNAME(mout_hsi_mmc_card_p) = { "oscclk", "dout_shared0_div2", 208 "dout_shared1_div2", "dout_shared0_div3", 209 "dout_shared1_div3", "mout_mmc_pll", 210 "oscclk", "oscclk" }; 211 PNAME(mout_hsi_usb20drd_p) = { "oscclk", "dout_shared0_div4", 212 "dout_shared1_div4", "oscclk" }; 213 /* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */ 214 PNAME(mout_peri_bus_p) = { "dout_shared0_div4", "dout_shared1_div4" }; 215 PNAME(mout_peri_uart_p) = { "oscclk", "dout_shared0_div4", 216 "dout_shared1_div4", "oscclk" }; 217 PNAME(mout_peri_ip_p) = { "oscclk", "dout_shared0_div4", 218 "dout_shared1_div4", "oscclk" }; 219 220 /* List of parent clocks for Muxes in CMU_TOP: for CMU_DPU */ 221 PNAME(mout_dpu_p) = { "dout_shared0_div3", "dout_shared1_div3", 222 "dout_shared0_div4", "dout_shared1_div4" }; 223 224 static const struct samsung_mux_clock top_mux_clks[] __initconst = { 225 /* CMU_TOP_PURECLKCOMP */ 226 MUX(CLK_MOUT_SHARED0_PLL, "mout_shared0_pll", mout_shared0_pll_p, 227 PLL_CON0_PLL_SHARED0, 4, 1), 228 MUX(CLK_MOUT_SHARED1_PLL, "mout_shared1_pll", mout_shared1_pll_p, 229 PLL_CON0_PLL_SHARED1, 4, 1), 230 MUX(CLK_MOUT_MMC_PLL, "mout_mmc_pll", mout_mmc_pll_p, 231 PLL_CON0_PLL_MMC, 4, 1), 232 233 /* APM */ 234 MUX(CLK_MOUT_CLKCMU_APM_BUS, "mout_clkcmu_apm_bus", 235 mout_clkcmu_apm_bus_p, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 0, 1), 236 237 /* CORE */ 238 MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p, 239 CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2), 240 MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p, 241 CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2), 242 MUX(CLK_MOUT_CORE_MMC_EMBD, "mout_core_mmc_embd", mout_core_mmc_embd_p, 243 CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, 0, 3), 244 MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p, 245 CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2), 246 247 /* DPU */ 248 MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p, 249 CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2), 250 251 /* HSI */ 252 MUX(CLK_MOUT_HSI_BUS, "mout_hsi_bus", mout_hsi_bus_p, 253 CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 0, 1), 254 MUX(CLK_MOUT_HSI_MMC_CARD, "mout_hsi_mmc_card", mout_hsi_mmc_card_p, 255 CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, 0, 3), 256 MUX(CLK_MOUT_HSI_USB20DRD, "mout_hsi_usb20drd", mout_hsi_usb20drd_p, 257 CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 0, 2), 258 259 /* PERI */ 260 MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p, 261 CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1), 262 MUX(CLK_MOUT_PERI_UART, "mout_peri_uart", mout_peri_uart_p, 263 CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 0, 2), 264 MUX(CLK_MOUT_PERI_IP, "mout_peri_ip", mout_peri_ip_p, 265 CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 0, 2), 266 }; 267 268 static const struct samsung_div_clock top_div_clks[] __initconst = { 269 /* CMU_TOP_PURECLKCOMP */ 270 DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "mout_shared0_pll", 271 CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2), 272 DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "mout_shared0_pll", 273 CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1), 274 DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "mout_shared1_pll", 275 CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2), 276 DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "mout_shared1_pll", 277 CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1), 278 DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2", 279 CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1), 280 DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2", 281 CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1), 282 283 /* APM */ 284 DIV(CLK_DOUT_CLKCMU_APM_BUS, "dout_clkcmu_apm_bus", 285 "gout_clkcmu_apm_bus", CLK_CON_DIV_CLKCMU_APM_BUS, 0, 3), 286 287 /* CORE */ 288 DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus", 289 CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4), 290 DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci", 291 CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 4), 292 DIV(CLK_DOUT_CORE_MMC_EMBD, "dout_core_mmc_embd", "gout_core_mmc_embd", 293 CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, 0, 9), 294 DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss", 295 CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4), 296 297 /* DPU */ 298 DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu", 299 CLK_CON_DIV_CLKCMU_DPU, 0, 4), 300 301 /* HSI */ 302 DIV(CLK_DOUT_HSI_BUS, "dout_hsi_bus", "gout_hsi_bus", 303 CLK_CON_DIV_CLKCMU_HSI_BUS, 0, 4), 304 DIV(CLK_DOUT_HSI_MMC_CARD, "dout_hsi_mmc_card", "gout_hsi_mmc_card", 305 CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, 0, 9), 306 DIV(CLK_DOUT_HSI_USB20DRD, "dout_hsi_usb20drd", "gout_hsi_usb20drd", 307 CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 0, 4), 308 309 /* PERI */ 310 DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus", 311 CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4), 312 DIV(CLK_DOUT_PERI_UART, "dout_peri_uart", "gout_peri_uart", 313 CLK_CON_DIV_CLKCMU_PERI_UART, 0, 4), 314 DIV(CLK_DOUT_PERI_IP, "dout_peri_ip", "gout_peri_ip", 315 CLK_CON_DIV_CLKCMU_PERI_IP, 0, 4), 316 }; 317 318 static const struct samsung_gate_clock top_gate_clks[] __initconst = { 319 /* CORE */ 320 GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus", 321 CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0), 322 GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci", 323 CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0), 324 GATE(CLK_GOUT_CORE_MMC_EMBD, "gout_core_mmc_embd", "mout_core_mmc_embd", 325 CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, 21, 0, 0), 326 GATE(CLK_GOUT_CORE_SSS, "gout_core_sss", "mout_core_sss", 327 CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 21, 0, 0), 328 329 /* APM */ 330 GATE(CLK_GOUT_CLKCMU_APM_BUS, "gout_clkcmu_apm_bus", 331 "mout_clkcmu_apm_bus", CLK_CON_GAT_GATE_CLKCMU_APM_BUS, 21, 0, 0), 332 333 /* DPU */ 334 GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu", 335 CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0), 336 337 /* HSI */ 338 GATE(CLK_GOUT_HSI_BUS, "gout_hsi_bus", "mout_hsi_bus", 339 CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 21, 0, 0), 340 GATE(CLK_GOUT_HSI_MMC_CARD, "gout_hsi_mmc_card", "mout_hsi_mmc_card", 341 CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, 21, 0, 0), 342 GATE(CLK_GOUT_HSI_USB20DRD, "gout_hsi_usb20drd", "mout_hsi_usb20drd", 343 CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 21, 0, 0), 344 345 /* PERI */ 346 GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus", 347 CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0), 348 GATE(CLK_GOUT_PERI_UART, "gout_peri_uart", "mout_peri_uart", 349 CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 21, 0, 0), 350 GATE(CLK_GOUT_PERI_IP, "gout_peri_ip", "mout_peri_ip", 351 CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 21, 0, 0), 352 }; 353 354 static const struct samsung_cmu_info top_cmu_info __initconst = { 355 .pll_clks = top_pll_clks, 356 .nr_pll_clks = ARRAY_SIZE(top_pll_clks), 357 .mux_clks = top_mux_clks, 358 .nr_mux_clks = ARRAY_SIZE(top_mux_clks), 359 .div_clks = top_div_clks, 360 .nr_div_clks = ARRAY_SIZE(top_div_clks), 361 .gate_clks = top_gate_clks, 362 .nr_gate_clks = ARRAY_SIZE(top_gate_clks), 363 .nr_clk_ids = TOP_NR_CLK, 364 .clk_regs = top_clk_regs, 365 .nr_clk_regs = ARRAY_SIZE(top_clk_regs), 366 }; 367 368 static void __init exynos850_cmu_top_init(struct device_node *np) 369 { 370 exynos850_init_clocks(np, top_clk_regs, ARRAY_SIZE(top_clk_regs)); 371 samsung_cmu_register_one(np, &top_cmu_info); 372 } 373 374 CLK_OF_DECLARE(exynos850_cmu_top, "samsung,exynos850-cmu-top", 375 exynos850_cmu_top_init); 376 377 /* ---- CMU_APM ------------------------------------------------------------- */ 378 379 /* Register Offset definitions for CMU_APM (0x11800000) */ 380 #define PLL_CON0_MUX_CLKCMU_APM_BUS_USER 0x0600 381 #define PLL_CON0_MUX_CLK_RCO_APM_I3C_USER 0x0610 382 #define PLL_CON0_MUX_CLK_RCO_APM_USER 0x0620 383 #define PLL_CON0_MUX_DLL_USER 0x0630 384 #define CLK_CON_MUX_MUX_CLKCMU_CHUB_BUS 0x1000 385 #define CLK_CON_MUX_MUX_CLK_APM_BUS 0x1004 386 #define CLK_CON_MUX_MUX_CLK_APM_I3C 0x1008 387 #define CLK_CON_DIV_CLKCMU_CHUB_BUS 0x1800 388 #define CLK_CON_DIV_DIV_CLK_APM_BUS 0x1804 389 #define CLK_CON_DIV_DIV_CLK_APM_I3C 0x1808 390 #define CLK_CON_GAT_CLKCMU_CMGP_BUS 0x2000 391 #define CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS 0x2014 392 #define CLK_CON_GAT_GOUT_APM_APBIF_RTC_PCLK 0x2024 393 #define CLK_CON_GAT_GOUT_APM_APBIF_TOP_RTC_PCLK 0x2028 394 #define CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_PCLK 0x2034 395 #define CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_SCLK 0x2038 396 #define CLK_CON_GAT_GOUT_APM_SPEEDY_APM_PCLK 0x20bc 397 398 static const unsigned long apm_clk_regs[] __initconst = { 399 PLL_CON0_MUX_CLKCMU_APM_BUS_USER, 400 PLL_CON0_MUX_CLK_RCO_APM_I3C_USER, 401 PLL_CON0_MUX_CLK_RCO_APM_USER, 402 PLL_CON0_MUX_DLL_USER, 403 CLK_CON_MUX_MUX_CLKCMU_CHUB_BUS, 404 CLK_CON_MUX_MUX_CLK_APM_BUS, 405 CLK_CON_MUX_MUX_CLK_APM_I3C, 406 CLK_CON_DIV_CLKCMU_CHUB_BUS, 407 CLK_CON_DIV_DIV_CLK_APM_BUS, 408 CLK_CON_DIV_DIV_CLK_APM_I3C, 409 CLK_CON_GAT_CLKCMU_CMGP_BUS, 410 CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS, 411 CLK_CON_GAT_GOUT_APM_APBIF_RTC_PCLK, 412 CLK_CON_GAT_GOUT_APM_APBIF_TOP_RTC_PCLK, 413 CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_PCLK, 414 CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_SCLK, 415 CLK_CON_GAT_GOUT_APM_SPEEDY_APM_PCLK, 416 }; 417 418 /* List of parent clocks for Muxes in CMU_APM */ 419 PNAME(mout_apm_bus_user_p) = { "oscclk_rco_apm", "dout_clkcmu_apm_bus" }; 420 PNAME(mout_rco_apm_i3c_user_p) = { "oscclk_rco_apm", "clk_rco_i3c_pmic" }; 421 PNAME(mout_rco_apm_user_p) = { "oscclk_rco_apm", "clk_rco_apm__alv" }; 422 PNAME(mout_dll_user_p) = { "oscclk_rco_apm", "clk_dll_dco" }; 423 PNAME(mout_clkcmu_chub_bus_p) = { "mout_apm_bus_user", "mout_dll_user" }; 424 PNAME(mout_apm_bus_p) = { "mout_rco_apm_user", "mout_apm_bus_user", 425 "mout_dll_user", "oscclk_rco_apm" }; 426 PNAME(mout_apm_i3c_p) = { "dout_apm_i3c", "mout_rco_apm_i3c_user" }; 427 428 static const struct samsung_fixed_rate_clock apm_fixed_clks[] __initconst = { 429 FRATE(CLK_RCO_I3C_PMIC, "clk_rco_i3c_pmic", NULL, 0, 491520000), 430 FRATE(OSCCLK_RCO_APM, "oscclk_rco_apm", NULL, 0, 24576000), 431 FRATE(CLK_RCO_APM__ALV, "clk_rco_apm__alv", NULL, 0, 49152000), 432 FRATE(CLK_DLL_DCO, "clk_dll_dco", NULL, 0, 360000000), 433 }; 434 435 static const struct samsung_mux_clock apm_mux_clks[] __initconst = { 436 MUX(CLK_MOUT_APM_BUS_USER, "mout_apm_bus_user", mout_apm_bus_user_p, 437 PLL_CON0_MUX_CLKCMU_APM_BUS_USER, 4, 1), 438 MUX(CLK_MOUT_RCO_APM_I3C_USER, "mout_rco_apm_i3c_user", 439 mout_rco_apm_i3c_user_p, PLL_CON0_MUX_CLK_RCO_APM_I3C_USER, 4, 1), 440 MUX(CLK_MOUT_RCO_APM_USER, "mout_rco_apm_user", mout_rco_apm_user_p, 441 PLL_CON0_MUX_CLK_RCO_APM_USER, 4, 1), 442 MUX(CLK_MOUT_DLL_USER, "mout_dll_user", mout_dll_user_p, 443 PLL_CON0_MUX_DLL_USER, 4, 1), 444 MUX(CLK_MOUT_CLKCMU_CHUB_BUS, "mout_clkcmu_chub_bus", 445 mout_clkcmu_chub_bus_p, CLK_CON_MUX_MUX_CLKCMU_CHUB_BUS, 0, 1), 446 MUX(CLK_MOUT_APM_BUS, "mout_apm_bus", mout_apm_bus_p, 447 CLK_CON_MUX_MUX_CLK_APM_BUS, 0, 2), 448 MUX(CLK_MOUT_APM_I3C, "mout_apm_i3c", mout_apm_i3c_p, 449 CLK_CON_MUX_MUX_CLK_APM_I3C, 0, 1), 450 }; 451 452 static const struct samsung_div_clock apm_div_clks[] __initconst = { 453 DIV(CLK_DOUT_CLKCMU_CHUB_BUS, "dout_clkcmu_chub_bus", 454 "gout_clkcmu_chub_bus", 455 CLK_CON_DIV_CLKCMU_CHUB_BUS, 0, 3), 456 DIV(CLK_DOUT_APM_BUS, "dout_apm_bus", "mout_apm_bus", 457 CLK_CON_DIV_DIV_CLK_APM_BUS, 0, 3), 458 DIV(CLK_DOUT_APM_I3C, "dout_apm_i3c", "mout_apm_bus", 459 CLK_CON_DIV_DIV_CLK_APM_I3C, 0, 3), 460 }; 461 462 static const struct samsung_gate_clock apm_gate_clks[] __initconst = { 463 GATE(CLK_GOUT_CLKCMU_CMGP_BUS, "gout_clkcmu_cmgp_bus", "dout_apm_bus", 464 CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, 0, 0), 465 GATE(CLK_GOUT_CLKCMU_CHUB_BUS, "gout_clkcmu_chub_bus", 466 "mout_clkcmu_chub_bus", 467 CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS, 21, 0, 0), 468 GATE(CLK_GOUT_RTC_PCLK, "gout_rtc_pclk", "dout_apm_bus", 469 CLK_CON_GAT_GOUT_APM_APBIF_RTC_PCLK, 21, 0, 0), 470 GATE(CLK_GOUT_TOP_RTC_PCLK, "gout_top_rtc_pclk", "dout_apm_bus", 471 CLK_CON_GAT_GOUT_APM_APBIF_TOP_RTC_PCLK, 21, 0, 0), 472 GATE(CLK_GOUT_I3C_PCLK, "gout_i3c_pclk", "dout_apm_bus", 473 CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_PCLK, 21, 0, 0), 474 GATE(CLK_GOUT_I3C_SCLK, "gout_i3c_sclk", "mout_apm_i3c", 475 CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_SCLK, 21, 0, 0), 476 GATE(CLK_GOUT_SPEEDY_PCLK, "gout_speedy_pclk", "dout_apm_bus", 477 CLK_CON_GAT_GOUT_APM_SPEEDY_APM_PCLK, 21, 0, 0), 478 }; 479 480 static const struct samsung_cmu_info apm_cmu_info __initconst = { 481 .mux_clks = apm_mux_clks, 482 .nr_mux_clks = ARRAY_SIZE(apm_mux_clks), 483 .div_clks = apm_div_clks, 484 .nr_div_clks = ARRAY_SIZE(apm_div_clks), 485 .gate_clks = apm_gate_clks, 486 .nr_gate_clks = ARRAY_SIZE(apm_gate_clks), 487 .fixed_clks = apm_fixed_clks, 488 .nr_fixed_clks = ARRAY_SIZE(apm_fixed_clks), 489 .nr_clk_ids = APM_NR_CLK, 490 .clk_regs = apm_clk_regs, 491 .nr_clk_regs = ARRAY_SIZE(apm_clk_regs), 492 .clk_name = "dout_clkcmu_apm_bus", 493 }; 494 495 /* ---- CMU_HSI ------------------------------------------------------------- */ 496 497 /* Register Offset definitions for CMU_HSI (0x13400000) */ 498 #define PLL_CON0_MUX_CLKCMU_HSI_BUS_USER 0x0600 499 #define PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER 0x0610 500 #define PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER 0x0620 501 #define CLK_CON_MUX_MUX_CLK_HSI_RTC 0x1000 502 #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV 0x2008 503 #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50 0x200c 504 #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26 0x2010 505 #define CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK 0x2018 506 #define CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK 0x2024 507 #define CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN 0x2028 508 #define CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK 0x2038 509 #define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20 0x203c 510 #define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY 0x2040 511 512 static const unsigned long hsi_clk_regs[] __initconst = { 513 PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, 514 PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER, 515 PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER, 516 CLK_CON_MUX_MUX_CLK_HSI_RTC, 517 CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 518 CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 519 CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 520 CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 521 CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 522 CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 523 CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 524 CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, 525 CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, 526 }; 527 528 /* List of parent clocks for Muxes in CMU_PERI */ 529 PNAME(mout_hsi_bus_user_p) = { "oscclk", "dout_hsi_bus" }; 530 PNAME(mout_hsi_mmc_card_user_p) = { "oscclk", "dout_hsi_mmc_card" }; 531 PNAME(mout_hsi_usb20drd_user_p) = { "oscclk", "dout_hsi_usb20drd" }; 532 PNAME(mout_hsi_rtc_p) = { "rtcclk", "oscclk" }; 533 534 static const struct samsung_mux_clock hsi_mux_clks[] __initconst = { 535 MUX(CLK_MOUT_HSI_BUS_USER, "mout_hsi_bus_user", mout_hsi_bus_user_p, 536 PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, 4, 1), 537 MUX_F(CLK_MOUT_HSI_MMC_CARD_USER, "mout_hsi_mmc_card_user", 538 mout_hsi_mmc_card_user_p, PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER, 539 4, 1, CLK_SET_RATE_PARENT, 0), 540 MUX(CLK_MOUT_HSI_USB20DRD_USER, "mout_hsi_usb20drd_user", 541 mout_hsi_usb20drd_user_p, PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER, 542 4, 1), 543 MUX(CLK_MOUT_HSI_RTC, "mout_hsi_rtc", mout_hsi_rtc_p, 544 CLK_CON_MUX_MUX_CLK_HSI_RTC, 0, 1), 545 }; 546 547 static const struct samsung_gate_clock hsi_gate_clks[] __initconst = { 548 GATE(CLK_GOUT_USB_RTC_CLK, "gout_usb_rtc", "mout_hsi_rtc", 549 CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 21, 0, 0), 550 GATE(CLK_GOUT_USB_REF_CLK, "gout_usb_ref", "mout_hsi_usb20drd_user", 551 CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 21, 0, 0), 552 GATE(CLK_GOUT_USB_PHY_REF_CLK, "gout_usb_phy_ref", "oscclk", 553 CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 21, 0, 0), 554 GATE(CLK_GOUT_GPIO_HSI_PCLK, "gout_gpio_hsi_pclk", "mout_hsi_bus_user", 555 CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 21, 0, 0), 556 GATE(CLK_GOUT_MMC_CARD_ACLK, "gout_mmc_card_aclk", "mout_hsi_bus_user", 557 CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 21, 0, 0), 558 GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin", 559 "mout_hsi_mmc_card_user", 560 CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 21, CLK_SET_RATE_PARENT, 0), 561 GATE(CLK_GOUT_SYSREG_HSI_PCLK, "gout_sysreg_hsi_pclk", 562 "mout_hsi_bus_user", 563 CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 21, 0, 0), 564 GATE(CLK_GOUT_USB_PHY_ACLK, "gout_usb_phy_aclk", "mout_hsi_bus_user", 565 CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, 21, 0, 0), 566 GATE(CLK_GOUT_USB_BUS_EARLY_CLK, "gout_usb_bus_early", 567 "mout_hsi_bus_user", 568 CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, 21, 0, 0), 569 }; 570 571 static const struct samsung_cmu_info hsi_cmu_info __initconst = { 572 .mux_clks = hsi_mux_clks, 573 .nr_mux_clks = ARRAY_SIZE(hsi_mux_clks), 574 .gate_clks = hsi_gate_clks, 575 .nr_gate_clks = ARRAY_SIZE(hsi_gate_clks), 576 .nr_clk_ids = HSI_NR_CLK, 577 .clk_regs = hsi_clk_regs, 578 .nr_clk_regs = ARRAY_SIZE(hsi_clk_regs), 579 .clk_name = "dout_hsi_bus", 580 }; 581 582 /* ---- CMU_PERI ------------------------------------------------------------ */ 583 584 /* Register Offset definitions for CMU_PERI (0x10030000) */ 585 #define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER 0x0600 586 #define PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER 0x0610 587 #define PLL_CON0_MUX_CLKCMU_PERI_SPI_USER 0x0620 588 #define PLL_CON0_MUX_CLKCMU_PERI_UART_USER 0x0630 589 #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0 0x1800 590 #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1 0x1804 591 #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2 0x1808 592 #define CLK_CON_DIV_DIV_CLK_PERI_SPI_0 0x180c 593 #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0 0x200c 594 #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1 0x2010 595 #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2 0x2014 596 #define CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK 0x2020 597 #define CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK 0x2024 598 #define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK 0x2028 599 #define CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK 0x202c 600 #define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK 0x2030 601 #define CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK 0x2034 602 #define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK 0x2038 603 #define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK 0x203c 604 #define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK 0x2040 605 #define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK 0x2044 606 #define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK 0x2048 607 #define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK 0x204c 608 #define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK 0x2050 609 #define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK 0x2054 610 #define CLK_CON_GAT_GOUT_PERI_MCT_PCLK 0x205c 611 #define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK 0x2064 612 #define CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK 0x209c 613 #define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK 0x20a0 614 #define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK 0x20a4 615 #define CLK_CON_GAT_GOUT_PERI_UART_IPCLK 0x20a8 616 #define CLK_CON_GAT_GOUT_PERI_UART_PCLK 0x20ac 617 #define CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK 0x20b0 618 #define CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK 0x20b4 619 620 static const unsigned long peri_clk_regs[] __initconst = { 621 PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 622 PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 623 PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 624 PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 625 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, 626 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 627 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 628 CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 629 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, 630 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, 631 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, 632 CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 633 CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, 634 CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 635 CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, 636 CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 637 CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, 638 CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 639 CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 640 CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 641 CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 642 CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 643 CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 644 CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 645 CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 646 CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 647 CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 648 CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 649 CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 650 CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 651 CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 652 CLK_CON_GAT_GOUT_PERI_UART_PCLK, 653 CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 654 CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 655 }; 656 657 /* List of parent clocks for Muxes in CMU_PERI */ 658 PNAME(mout_peri_bus_user_p) = { "oscclk", "dout_peri_bus" }; 659 PNAME(mout_peri_uart_user_p) = { "oscclk", "dout_peri_uart" }; 660 PNAME(mout_peri_hsi2c_user_p) = { "oscclk", "dout_peri_ip" }; 661 PNAME(mout_peri_spi_user_p) = { "oscclk", "dout_peri_ip" }; 662 663 static const struct samsung_mux_clock peri_mux_clks[] __initconst = { 664 MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p, 665 PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1), 666 MUX(CLK_MOUT_PERI_UART_USER, "mout_peri_uart_user", 667 mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1), 668 MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user", 669 mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1), 670 MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p, 671 PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1), 672 }; 673 674 static const struct samsung_div_clock peri_div_clks[] __initconst = { 675 DIV(CLK_DOUT_PERI_HSI2C0, "dout_peri_hsi2c0", "gout_peri_hsi2c0", 676 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, 0, 5), 677 DIV(CLK_DOUT_PERI_HSI2C1, "dout_peri_hsi2c1", "gout_peri_hsi2c1", 678 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5), 679 DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2", 680 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5), 681 DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user", 682 CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5), 683 }; 684 685 static const struct samsung_gate_clock peri_gate_clks[] __initconst = { 686 GATE(CLK_GOUT_PERI_HSI2C0, "gout_peri_hsi2c0", "mout_peri_hsi2c_user", 687 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, 21, 0, 0), 688 GATE(CLK_GOUT_PERI_HSI2C1, "gout_peri_hsi2c1", "mout_peri_hsi2c_user", 689 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, 21, 0, 0), 690 GATE(CLK_GOUT_PERI_HSI2C2, "gout_peri_hsi2c2", "mout_peri_hsi2c_user", 691 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, 21, 0, 0), 692 GATE(CLK_GOUT_HSI2C0_IPCLK, "gout_hsi2c0_ipclk", "dout_peri_hsi2c0", 693 CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, 21, 0, 0), 694 GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user", 695 CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0), 696 GATE(CLK_GOUT_HSI2C1_IPCLK, "gout_hsi2c1_ipclk", "dout_peri_hsi2c1", 697 CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, 21, 0, 0), 698 GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user", 699 CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0), 700 GATE(CLK_GOUT_HSI2C2_IPCLK, "gout_hsi2c2_ipclk", "dout_peri_hsi2c2", 701 CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, 21, 0, 0), 702 GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user", 703 CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0), 704 GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user", 705 CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0), 706 GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user", 707 CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0), 708 GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user", 709 CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0), 710 GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user", 711 CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0), 712 GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user", 713 CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0), 714 GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user", 715 CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0), 716 GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user", 717 CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0), 718 GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user", 719 CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0), 720 GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk", 721 "mout_peri_bus_user", 722 CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0), 723 GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0", 724 CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0), 725 GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user", 726 CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0), 727 GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk", 728 "mout_peri_bus_user", 729 CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0), 730 GATE(CLK_GOUT_UART_IPCLK, "gout_uart_ipclk", "mout_peri_uart_user", 731 CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 21, 0, 0), 732 GATE(CLK_GOUT_UART_PCLK, "gout_uart_pclk", "mout_peri_bus_user", 733 CLK_CON_GAT_GOUT_PERI_UART_PCLK, 21, 0, 0), 734 GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user", 735 CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 21, 0, 0), 736 GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user", 737 CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 21, 0, 0), 738 GATE(CLK_GOUT_GPIO_PERI_PCLK, "gout_gpio_peri_pclk", 739 "mout_peri_bus_user", 740 CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 21, 0, 0), 741 }; 742 743 static const struct samsung_cmu_info peri_cmu_info __initconst = { 744 .mux_clks = peri_mux_clks, 745 .nr_mux_clks = ARRAY_SIZE(peri_mux_clks), 746 .div_clks = peri_div_clks, 747 .nr_div_clks = ARRAY_SIZE(peri_div_clks), 748 .gate_clks = peri_gate_clks, 749 .nr_gate_clks = ARRAY_SIZE(peri_gate_clks), 750 .nr_clk_ids = PERI_NR_CLK, 751 .clk_regs = peri_clk_regs, 752 .nr_clk_regs = ARRAY_SIZE(peri_clk_regs), 753 .clk_name = "dout_peri_bus", 754 }; 755 756 /* ---- CMU_CORE ------------------------------------------------------------ */ 757 758 /* Register Offset definitions for CMU_CORE (0x12000000) */ 759 #define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER 0x0600 760 #define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER 0x0610 761 #define PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER 0x0620 762 #define PLL_CON0_MUX_CLKCMU_CORE_SSS_USER 0x0630 763 #define CLK_CON_MUX_MUX_CLK_CORE_GIC 0x1000 764 #define CLK_CON_DIV_DIV_CLK_CORE_BUSP 0x1800 765 #define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK 0x2038 766 #define CLK_CON_GAT_GOUT_CORE_GIC_CLK 0x2040 767 #define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK 0x20e8 768 #define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN 0x20ec 769 #define CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK 0x2128 770 #define CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK 0x212c 771 772 static const unsigned long core_clk_regs[] __initconst = { 773 PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 774 PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 775 PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER, 776 PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, 777 CLK_CON_MUX_MUX_CLK_CORE_GIC, 778 CLK_CON_DIV_DIV_CLK_CORE_BUSP, 779 CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 780 CLK_CON_GAT_GOUT_CORE_GIC_CLK, 781 CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 782 CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN, 783 CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 784 CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 785 }; 786 787 /* List of parent clocks for Muxes in CMU_CORE */ 788 PNAME(mout_core_bus_user_p) = { "oscclk", "dout_core_bus" }; 789 PNAME(mout_core_cci_user_p) = { "oscclk", "dout_core_cci" }; 790 PNAME(mout_core_mmc_embd_user_p) = { "oscclk", "dout_core_mmc_embd" }; 791 PNAME(mout_core_sss_user_p) = { "oscclk", "dout_core_sss" }; 792 PNAME(mout_core_gic_p) = { "dout_core_busp", "oscclk" }; 793 794 static const struct samsung_mux_clock core_mux_clks[] __initconst = { 795 MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p, 796 PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1), 797 MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p, 798 PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1), 799 MUX_F(CLK_MOUT_CORE_MMC_EMBD_USER, "mout_core_mmc_embd_user", 800 mout_core_mmc_embd_user_p, PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER, 801 4, 1, CLK_SET_RATE_PARENT, 0), 802 MUX(CLK_MOUT_CORE_SSS_USER, "mout_core_sss_user", mout_core_sss_user_p, 803 PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, 4, 1), 804 MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p, 805 CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1), 806 }; 807 808 static const struct samsung_div_clock core_div_clks[] __initconst = { 809 DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user", 810 CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2), 811 }; 812 813 static const struct samsung_gate_clock core_gate_clks[] __initconst = { 814 GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user", 815 CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, 0, 0), 816 GATE(CLK_GOUT_GIC_CLK, "gout_gic_clk", "mout_core_gic", 817 CLK_CON_GAT_GOUT_CORE_GIC_CLK, 21, 0, 0), 818 GATE(CLK_GOUT_MMC_EMBD_ACLK, "gout_mmc_embd_aclk", "dout_core_busp", 819 CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 21, 0, 0), 820 GATE(CLK_GOUT_MMC_EMBD_SDCLKIN, "gout_mmc_embd_sdclkin", 821 "mout_core_mmc_embd_user", CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN, 822 21, CLK_SET_RATE_PARENT, 0), 823 GATE(CLK_GOUT_SSS_ACLK, "gout_sss_aclk", "mout_core_sss_user", 824 CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 21, 0, 0), 825 GATE(CLK_GOUT_SSS_PCLK, "gout_sss_pclk", "dout_core_busp", 826 CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 21, 0, 0), 827 }; 828 829 static const struct samsung_cmu_info core_cmu_info __initconst = { 830 .mux_clks = core_mux_clks, 831 .nr_mux_clks = ARRAY_SIZE(core_mux_clks), 832 .div_clks = core_div_clks, 833 .nr_div_clks = ARRAY_SIZE(core_div_clks), 834 .gate_clks = core_gate_clks, 835 .nr_gate_clks = ARRAY_SIZE(core_gate_clks), 836 .nr_clk_ids = CORE_NR_CLK, 837 .clk_regs = core_clk_regs, 838 .nr_clk_regs = ARRAY_SIZE(core_clk_regs), 839 .clk_name = "dout_core_bus", 840 }; 841 842 /* ---- CMU_DPU ------------------------------------------------------------- */ 843 844 /* Register Offset definitions for CMU_DPU (0x13000000) */ 845 #define PLL_CON0_MUX_CLKCMU_DPU_USER 0x0600 846 #define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800 847 #define CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK 0x2004 848 #define CLK_CON_GAT_GOUT_DPU_ACLK_DECON0 0x2010 849 #define CLK_CON_GAT_GOUT_DPU_ACLK_DMA 0x2014 850 #define CLK_CON_GAT_GOUT_DPU_ACLK_DPP 0x2018 851 #define CLK_CON_GAT_GOUT_DPU_PPMU_ACLK 0x2028 852 #define CLK_CON_GAT_GOUT_DPU_PPMU_PCLK 0x202c 853 #define CLK_CON_GAT_GOUT_DPU_SMMU_CLK 0x2038 854 #define CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK 0x203c 855 856 static const unsigned long dpu_clk_regs[] __initconst = { 857 PLL_CON0_MUX_CLKCMU_DPU_USER, 858 CLK_CON_DIV_DIV_CLK_DPU_BUSP, 859 CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 860 CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 861 CLK_CON_GAT_GOUT_DPU_ACLK_DMA, 862 CLK_CON_GAT_GOUT_DPU_ACLK_DPP, 863 CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, 864 CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, 865 CLK_CON_GAT_GOUT_DPU_SMMU_CLK, 866 CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, 867 }; 868 869 /* List of parent clocks for Muxes in CMU_CORE */ 870 PNAME(mout_dpu_user_p) = { "oscclk", "dout_dpu" }; 871 872 static const struct samsung_mux_clock dpu_mux_clks[] __initconst = { 873 MUX(CLK_MOUT_DPU_USER, "mout_dpu_user", mout_dpu_user_p, 874 PLL_CON0_MUX_CLKCMU_DPU_USER, 4, 1), 875 }; 876 877 static const struct samsung_div_clock dpu_div_clks[] __initconst = { 878 DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_user", 879 CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3), 880 }; 881 882 static const struct samsung_gate_clock dpu_gate_clks[] __initconst = { 883 GATE(CLK_GOUT_DPU_CMU_DPU_PCLK, "gout_dpu_cmu_dpu_pclk", 884 "dout_dpu_busp", CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 21, 0, 0), 885 GATE(CLK_GOUT_DPU_DECON0_ACLK, "gout_dpu_decon0_aclk", "mout_dpu_user", 886 CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 21, 0, 0), 887 GATE(CLK_GOUT_DPU_DMA_ACLK, "gout_dpu_dma_aclk", "mout_dpu_user", 888 CLK_CON_GAT_GOUT_DPU_ACLK_DMA, 21, 0, 0), 889 GATE(CLK_GOUT_DPU_DPP_ACLK, "gout_dpu_dpp_aclk", "mout_dpu_user", 890 CLK_CON_GAT_GOUT_DPU_ACLK_DPP, 21, 0, 0), 891 GATE(CLK_GOUT_DPU_PPMU_ACLK, "gout_dpu_ppmu_aclk", "mout_dpu_user", 892 CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, 21, 0, 0), 893 GATE(CLK_GOUT_DPU_PPMU_PCLK, "gout_dpu_ppmu_pclk", "dout_dpu_busp", 894 CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, 21, 0, 0), 895 GATE(CLK_GOUT_DPU_SMMU_CLK, "gout_dpu_smmu_clk", "mout_dpu_user", 896 CLK_CON_GAT_GOUT_DPU_SMMU_CLK, 21, 0, 0), 897 GATE(CLK_GOUT_DPU_SYSREG_PCLK, "gout_dpu_sysreg_pclk", "dout_dpu_busp", 898 CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, 21, 0, 0), 899 }; 900 901 static const struct samsung_cmu_info dpu_cmu_info __initconst = { 902 .mux_clks = dpu_mux_clks, 903 .nr_mux_clks = ARRAY_SIZE(dpu_mux_clks), 904 .div_clks = dpu_div_clks, 905 .nr_div_clks = ARRAY_SIZE(dpu_div_clks), 906 .gate_clks = dpu_gate_clks, 907 .nr_gate_clks = ARRAY_SIZE(dpu_gate_clks), 908 .nr_clk_ids = DPU_NR_CLK, 909 .clk_regs = dpu_clk_regs, 910 .nr_clk_regs = ARRAY_SIZE(dpu_clk_regs), 911 .clk_name = "dout_dpu", 912 }; 913 914 /* ---- platform_driver ----------------------------------------------------- */ 915 916 static int __init exynos850_cmu_probe(struct platform_device *pdev) 917 { 918 const struct samsung_cmu_info *info; 919 struct device *dev = &pdev->dev; 920 struct device_node *np = dev->of_node; 921 922 info = of_device_get_match_data(dev); 923 exynos850_init_clocks(np, info->clk_regs, info->nr_clk_regs); 924 samsung_cmu_register_one(np, info); 925 926 /* Keep bus clock running, so it's possible to access CMU registers */ 927 if (info->clk_name) { 928 struct clk *bus_clk; 929 930 bus_clk = clk_get(dev, info->clk_name); 931 if (IS_ERR(bus_clk)) { 932 pr_err("%s: could not find bus clock %s; err = %ld\n", 933 __func__, info->clk_name, PTR_ERR(bus_clk)); 934 } else { 935 clk_prepare_enable(bus_clk); 936 } 937 } 938 939 return 0; 940 } 941 942 static const struct of_device_id exynos850_cmu_of_match[] = { 943 { 944 .compatible = "samsung,exynos850-cmu-apm", 945 .data = &apm_cmu_info, 946 }, { 947 .compatible = "samsung,exynos850-cmu-hsi", 948 .data = &hsi_cmu_info, 949 }, { 950 .compatible = "samsung,exynos850-cmu-peri", 951 .data = &peri_cmu_info, 952 }, { 953 .compatible = "samsung,exynos850-cmu-core", 954 .data = &core_cmu_info, 955 }, { 956 .compatible = "samsung,exynos850-cmu-dpu", 957 .data = &dpu_cmu_info, 958 }, { 959 }, 960 }; 961 962 static struct platform_driver exynos850_cmu_driver __refdata = { 963 .driver = { 964 .name = "exynos850-cmu", 965 .of_match_table = exynos850_cmu_of_match, 966 .suppress_bind_attrs = true, 967 }, 968 .probe = exynos850_cmu_probe, 969 }; 970 971 static int __init exynos850_cmu_init(void) 972 { 973 return platform_driver_register(&exynos850_cmu_driver); 974 } 975 core_initcall(exynos850_cmu_init); 976