Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2021 Dávid Virág <virag.david003@gmail.com>
0004  * Author: Dávid Virág <virag.david003@gmail.com>
0005  *
0006  * Common Clock Framework support for Exynos7885 SoC.
0007  */
0008 
0009 #include <linux/clk.h>
0010 #include <linux/clk-provider.h>
0011 #include <linux/of.h>
0012 #include <linux/of_device.h>
0013 #include <linux/platform_device.h>
0014 
0015 #include <dt-bindings/clock/exynos7885.h>
0016 
0017 #include "clk.h"
0018 #include "clk-exynos-arm64.h"
0019 
0020 /* ---- CMU_TOP ------------------------------------------------------------- */
0021 
0022 /* Register Offset definitions for CMU_TOP (0x12060000) */
0023 #define PLL_LOCKTIME_PLL_SHARED0        0x0000
0024 #define PLL_LOCKTIME_PLL_SHARED1        0x0004
0025 #define PLL_CON0_PLL_SHARED0            0x0100
0026 #define PLL_CON0_PLL_SHARED1            0x0120
0027 #define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS     0x1014
0028 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI     0x1018
0029 #define CLK_CON_MUX_MUX_CLKCMU_CORE_G3D     0x101c
0030 #define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS     0x1058
0031 #define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0    0x105c
0032 #define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1    0x1060
0033 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART0   0x1064
0034 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART1   0x1068
0035 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART2   0x106c
0036 #define CLK_CON_MUX_MUX_CLKCMU_PERI_USI0    0x1070
0037 #define CLK_CON_MUX_MUX_CLKCMU_PERI_USI1    0x1074
0038 #define CLK_CON_MUX_MUX_CLKCMU_PERI_USI2    0x1078
0039 #define CLK_CON_DIV_CLKCMU_CORE_BUS     0x181c
0040 #define CLK_CON_DIV_CLKCMU_CORE_CCI     0x1820
0041 #define CLK_CON_DIV_CLKCMU_CORE_G3D     0x1824
0042 #define CLK_CON_DIV_CLKCMU_PERI_BUS     0x1874
0043 #define CLK_CON_DIV_CLKCMU_PERI_SPI0        0x1878
0044 #define CLK_CON_DIV_CLKCMU_PERI_SPI1        0x187c
0045 #define CLK_CON_DIV_CLKCMU_PERI_UART0       0x1880
0046 #define CLK_CON_DIV_CLKCMU_PERI_UART1       0x1884
0047 #define CLK_CON_DIV_CLKCMU_PERI_UART2       0x1888
0048 #define CLK_CON_DIV_CLKCMU_PERI_USI0        0x188c
0049 #define CLK_CON_DIV_CLKCMU_PERI_USI1        0x1890
0050 #define CLK_CON_DIV_CLKCMU_PERI_USI2        0x1894
0051 #define CLK_CON_DIV_PLL_SHARED0_DIV2        0x189c
0052 #define CLK_CON_DIV_PLL_SHARED0_DIV3        0x18a0
0053 #define CLK_CON_DIV_PLL_SHARED0_DIV4        0x18a4
0054 #define CLK_CON_DIV_PLL_SHARED0_DIV5        0x18a8
0055 #define CLK_CON_DIV_PLL_SHARED1_DIV2        0x18ac
0056 #define CLK_CON_DIV_PLL_SHARED1_DIV3        0x18b0
0057 #define CLK_CON_DIV_PLL_SHARED1_DIV4        0x18b4
0058 #define CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1 0x2004
0059 #define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS    0x201c
0060 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI    0x2020
0061 #define CLK_CON_GAT_GATE_CLKCMU_CORE_G3D    0x2024
0062 #define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS    0x207c
0063 #define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0   0x2080
0064 #define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1   0x2084
0065 #define CLK_CON_GAT_GATE_CLKCMU_PERI_UART0  0x2088
0066 #define CLK_CON_GAT_GATE_CLKCMU_PERI_UART2  0x208c
0067 #define CLK_CON_GAT_GATE_CLKCMU_PERI_USI0   0x2090
0068 #define CLK_CON_GAT_GATE_CLKCMU_PERI_USI1   0x2094
0069 #define CLK_CON_GAT_GATE_CLKCMU_PERI_USI2   0x2098
0070 
0071 static const unsigned long top_clk_regs[] __initconst = {
0072     PLL_LOCKTIME_PLL_SHARED0,
0073     PLL_LOCKTIME_PLL_SHARED1,
0074     PLL_CON0_PLL_SHARED0,
0075     PLL_CON0_PLL_SHARED1,
0076     CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
0077     CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
0078     CLK_CON_MUX_MUX_CLKCMU_CORE_G3D,
0079     CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
0080     CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0,
0081     CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1,
0082     CLK_CON_MUX_MUX_CLKCMU_PERI_UART0,
0083     CLK_CON_MUX_MUX_CLKCMU_PERI_UART1,
0084     CLK_CON_MUX_MUX_CLKCMU_PERI_UART2,
0085     CLK_CON_MUX_MUX_CLKCMU_PERI_USI0,
0086     CLK_CON_MUX_MUX_CLKCMU_PERI_USI1,
0087     CLK_CON_MUX_MUX_CLKCMU_PERI_USI2,
0088     CLK_CON_DIV_CLKCMU_CORE_BUS,
0089     CLK_CON_DIV_CLKCMU_CORE_CCI,
0090     CLK_CON_DIV_CLKCMU_CORE_G3D,
0091     CLK_CON_DIV_CLKCMU_PERI_BUS,
0092     CLK_CON_DIV_CLKCMU_PERI_SPI0,
0093     CLK_CON_DIV_CLKCMU_PERI_SPI1,
0094     CLK_CON_DIV_CLKCMU_PERI_UART0,
0095     CLK_CON_DIV_CLKCMU_PERI_UART1,
0096     CLK_CON_DIV_CLKCMU_PERI_UART2,
0097     CLK_CON_DIV_CLKCMU_PERI_USI0,
0098     CLK_CON_DIV_CLKCMU_PERI_USI1,
0099     CLK_CON_DIV_CLKCMU_PERI_USI2,
0100     CLK_CON_DIV_PLL_SHARED0_DIV2,
0101     CLK_CON_DIV_PLL_SHARED0_DIV3,
0102     CLK_CON_DIV_PLL_SHARED0_DIV4,
0103     CLK_CON_DIV_PLL_SHARED0_DIV5,
0104     CLK_CON_DIV_PLL_SHARED1_DIV2,
0105     CLK_CON_DIV_PLL_SHARED1_DIV3,
0106     CLK_CON_DIV_PLL_SHARED1_DIV4,
0107     CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1,
0108     CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
0109     CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
0110     CLK_CON_GAT_GATE_CLKCMU_CORE_G3D,
0111     CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
0112     CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0,
0113     CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1,
0114     CLK_CON_GAT_GATE_CLKCMU_PERI_UART0,
0115     CLK_CON_GAT_GATE_CLKCMU_PERI_UART2,
0116     CLK_CON_GAT_GATE_CLKCMU_PERI_USI0,
0117     CLK_CON_GAT_GATE_CLKCMU_PERI_USI1,
0118     CLK_CON_GAT_GATE_CLKCMU_PERI_USI2,
0119 };
0120 
0121 static const struct samsung_pll_clock top_pll_clks[] __initconst = {
0122     PLL(pll_1417x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
0123         PLL_LOCKTIME_PLL_SHARED0, PLL_CON0_PLL_SHARED0,
0124         NULL),
0125     PLL(pll_1417x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
0126         PLL_LOCKTIME_PLL_SHARED1, PLL_CON0_PLL_SHARED1,
0127         NULL),
0128 };
0129 
0130 /* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
0131 PNAME(mout_core_bus_p)      = { "dout_shared0_div2", "dout_shared1_div2",
0132                     "dout_shared0_div3", "dout_shared0_div3" };
0133 PNAME(mout_core_cci_p)      = { "dout_shared0_div2", "dout_shared1_div2",
0134                     "dout_shared0_div3", "dout_shared0_div3" };
0135 PNAME(mout_core_g3d_p)      = { "dout_shared0_div2", "dout_shared1_div2",
0136                     "dout_shared0_div3", "dout_shared0_div3" };
0137 
0138 /* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
0139 PNAME(mout_peri_bus_p)      = { "dout_shared0_div4", "dout_shared1_div4" };
0140 PNAME(mout_peri_spi0_p)     = { "oscclk", "dout_shared0_div4" };
0141 PNAME(mout_peri_spi1_p)     = { "oscclk", "dout_shared0_div4" };
0142 PNAME(mout_peri_uart0_p)    = { "oscclk", "dout_shared0_div4" };
0143 PNAME(mout_peri_uart1_p)    = { "oscclk", "dout_shared0_div4" };
0144 PNAME(mout_peri_uart2_p)    = { "oscclk", "dout_shared0_div4" };
0145 PNAME(mout_peri_usi0_p)     = { "oscclk", "dout_shared0_div4" };
0146 PNAME(mout_peri_usi1_p)     = { "oscclk", "dout_shared0_div4" };
0147 PNAME(mout_peri_usi2_p)     = { "oscclk", "dout_shared0_div4" };
0148 
0149 static const struct samsung_mux_clock top_mux_clks[] __initconst = {
0150     /* CORE */
0151     MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
0152         CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2),
0153     MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p,
0154         CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2),
0155     MUX(CLK_MOUT_CORE_G3D, "mout_core_g3d", mout_core_g3d_p,
0156         CLK_CON_MUX_MUX_CLKCMU_CORE_G3D, 0, 2),
0157 
0158     /* PERI */
0159     MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p,
0160         CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1),
0161     MUX(CLK_MOUT_PERI_SPI0, "mout_peri_spi0", mout_peri_spi0_p,
0162         CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0, 0, 1),
0163     MUX(CLK_MOUT_PERI_SPI1, "mout_peri_spi1", mout_peri_spi1_p,
0164         CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1, 0, 1),
0165     MUX(CLK_MOUT_PERI_UART0, "mout_peri_uart0", mout_peri_uart0_p,
0166         CLK_CON_MUX_MUX_CLKCMU_PERI_UART0, 0, 1),
0167     MUX(CLK_MOUT_PERI_UART1, "mout_peri_uart1", mout_peri_uart1_p,
0168         CLK_CON_MUX_MUX_CLKCMU_PERI_UART1, 0, 1),
0169     MUX(CLK_MOUT_PERI_UART2, "mout_peri_uart2", mout_peri_uart2_p,
0170         CLK_CON_MUX_MUX_CLKCMU_PERI_UART2, 0, 1),
0171     MUX(CLK_MOUT_PERI_USI0, "mout_peri_usi0", mout_peri_usi0_p,
0172         CLK_CON_MUX_MUX_CLKCMU_PERI_USI0, 0, 1),
0173     MUX(CLK_MOUT_PERI_USI1, "mout_peri_usi1", mout_peri_usi1_p,
0174         CLK_CON_MUX_MUX_CLKCMU_PERI_USI1, 0, 1),
0175     MUX(CLK_MOUT_PERI_USI2, "mout_peri_usi2", mout_peri_usi2_p,
0176         CLK_CON_MUX_MUX_CLKCMU_PERI_USI2, 0, 1),
0177 };
0178 
0179 static const struct samsung_div_clock top_div_clks[] __initconst = {
0180     /* TOP */
0181     DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "fout_shared0_pll",
0182         CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
0183     DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll",
0184         CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
0185     DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll",
0186         CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
0187     DIV(CLK_DOUT_SHARED0_DIV5, "dout_shared0_div5", "fout_shared0_pll",
0188         CLK_CON_DIV_PLL_SHARED0_DIV5, 0, 3),
0189     DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "fout_shared1_pll",
0190         CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
0191     DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll",
0192         CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
0193     DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll",
0194         CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
0195 
0196     /* CORE */
0197     DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus",
0198         CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 3),
0199     DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci",
0200         CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 3),
0201     DIV(CLK_DOUT_CORE_G3D, "dout_core_g3d", "gout_core_g3d",
0202         CLK_CON_DIV_CLKCMU_CORE_G3D, 0, 3),
0203 
0204     /* PERI */
0205     DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus",
0206         CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4),
0207     DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "gout_peri_spi0",
0208         CLK_CON_DIV_CLKCMU_PERI_SPI0, 0, 6),
0209     DIV(CLK_DOUT_PERI_SPI1, "dout_peri_spi1", "gout_peri_spi1",
0210         CLK_CON_DIV_CLKCMU_PERI_SPI1, 0, 6),
0211     DIV(CLK_DOUT_PERI_UART0, "dout_peri_uart0", "gout_peri_uart0",
0212         CLK_CON_DIV_CLKCMU_PERI_UART0, 0, 4),
0213     DIV(CLK_DOUT_PERI_UART1, "dout_peri_uart1", "gout_peri_uart1",
0214         CLK_CON_DIV_CLKCMU_PERI_UART1, 0, 4),
0215     DIV(CLK_DOUT_PERI_UART2, "dout_peri_uart2", "gout_peri_uart2",
0216         CLK_CON_DIV_CLKCMU_PERI_UART2, 0, 4),
0217     DIV(CLK_DOUT_PERI_USI0, "dout_peri_usi0", "gout_peri_usi0",
0218         CLK_CON_DIV_CLKCMU_PERI_USI0, 0, 4),
0219     DIV(CLK_DOUT_PERI_USI1, "dout_peri_usi1", "gout_peri_usi1",
0220         CLK_CON_DIV_CLKCMU_PERI_USI1, 0, 4),
0221     DIV(CLK_DOUT_PERI_USI2, "dout_peri_usi2", "gout_peri_usi2",
0222         CLK_CON_DIV_CLKCMU_PERI_USI2, 0, 4),
0223 };
0224 
0225 static const struct samsung_gate_clock top_gate_clks[] __initconst = {
0226     /* CORE */
0227     GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus",
0228          CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0),
0229     GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci",
0230          CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0),
0231     GATE(CLK_GOUT_CORE_G3D, "gout_core_g3d", "mout_core_g3d",
0232          CLK_CON_GAT_GATE_CLKCMU_CORE_G3D, 21, 0, 0),
0233 
0234     /* PERI */
0235     GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus",
0236          CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0),
0237     GATE(CLK_GOUT_PERI_SPI0, "gout_peri_spi0", "mout_peri_spi0",
0238          CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0, 21, 0, 0),
0239     GATE(CLK_GOUT_PERI_SPI1, "gout_peri_spi1", "mout_peri_spi1",
0240          CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1, 21, 0, 0),
0241     GATE(CLK_GOUT_PERI_UART0, "gout_peri_uart0", "mout_peri_uart0",
0242          CLK_CON_GAT_GATE_CLKCMU_PERI_UART0, 21, 0, 0),
0243     GATE(CLK_GOUT_PERI_UART1, "gout_peri_uart1", "mout_peri_uart1",
0244          CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1, 21, 0, 0),
0245     GATE(CLK_GOUT_PERI_UART2, "gout_peri_uart2", "mout_peri_uart2",
0246          CLK_CON_GAT_GATE_CLKCMU_PERI_UART2, 21, 0, 0),
0247     GATE(CLK_GOUT_PERI_USI0, "gout_peri_usi0", "mout_peri_usi0",
0248          CLK_CON_GAT_GATE_CLKCMU_PERI_USI0, 21, 0, 0),
0249     GATE(CLK_GOUT_PERI_USI1, "gout_peri_usi1", "mout_peri_usi1",
0250          CLK_CON_GAT_GATE_CLKCMU_PERI_USI1, 21, 0, 0),
0251     GATE(CLK_GOUT_PERI_USI2, "gout_peri_usi2", "mout_peri_usi2",
0252          CLK_CON_GAT_GATE_CLKCMU_PERI_USI2, 21, 0, 0),
0253 };
0254 
0255 static const struct samsung_cmu_info top_cmu_info __initconst = {
0256     .pll_clks       = top_pll_clks,
0257     .nr_pll_clks        = ARRAY_SIZE(top_pll_clks),
0258     .mux_clks       = top_mux_clks,
0259     .nr_mux_clks        = ARRAY_SIZE(top_mux_clks),
0260     .div_clks       = top_div_clks,
0261     .nr_div_clks        = ARRAY_SIZE(top_div_clks),
0262     .gate_clks      = top_gate_clks,
0263     .nr_gate_clks       = ARRAY_SIZE(top_gate_clks),
0264     .nr_clk_ids     = TOP_NR_CLK,
0265     .clk_regs       = top_clk_regs,
0266     .nr_clk_regs        = ARRAY_SIZE(top_clk_regs),
0267 };
0268 
0269 static void __init exynos7885_cmu_top_init(struct device_node *np)
0270 {
0271     exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
0272 }
0273 
0274 /* Register CMU_TOP early, as it's a dependency for other early domains */
0275 CLK_OF_DECLARE(exynos7885_cmu_top, "samsung,exynos7885-cmu-top",
0276            exynos7885_cmu_top_init);
0277 
0278 /* ---- CMU_PERI ------------------------------------------------------------ */
0279 
0280 /* Register Offset definitions for CMU_PERI (0x10010000) */
0281 #define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER   0x0100
0282 #define PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER  0x0120
0283 #define PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER  0x0140
0284 #define PLL_CON0_MUX_CLKCMU_PERI_UART0_USER 0x0160
0285 #define PLL_CON0_MUX_CLKCMU_PERI_UART1_USER 0x0180
0286 #define PLL_CON0_MUX_CLKCMU_PERI_UART2_USER 0x01a0
0287 #define PLL_CON0_MUX_CLKCMU_PERI_USI0_USER  0x01c0
0288 #define PLL_CON0_MUX_CLKCMU_PERI_USI1_USER  0x01e0
0289 #define PLL_CON0_MUX_CLKCMU_PERI_USI2_USER  0x0200
0290 #define CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK 0x2024
0291 #define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK  0x2028
0292 #define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK  0x202c
0293 #define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK  0x2030
0294 #define CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK  0x2034
0295 #define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK    0x2038
0296 #define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK    0x203c
0297 #define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK    0x2040
0298 #define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK    0x2044
0299 #define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK    0x2048
0300 #define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK    0x204c
0301 #define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK    0x2050
0302 #define CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK    0x2054
0303 #define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK    0x2058
0304 #define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK    0x205c
0305 #define CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK 0x2060
0306 #define CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK    0x2064
0307 #define CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK 0x2068
0308 #define CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK   0x206c
0309 #define CLK_CON_GAT_GOUT_PERI_UART_0_PCLK   0x2070
0310 #define CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK   0x2074
0311 #define CLK_CON_GAT_GOUT_PERI_UART_1_PCLK   0x2078
0312 #define CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK   0x207c
0313 #define CLK_CON_GAT_GOUT_PERI_UART_2_PCLK   0x2080
0314 #define CLK_CON_GAT_GOUT_PERI_USI0_PCLK     0x2084
0315 #define CLK_CON_GAT_GOUT_PERI_USI0_SCLK     0x2088
0316 #define CLK_CON_GAT_GOUT_PERI_USI1_PCLK     0x208c
0317 #define CLK_CON_GAT_GOUT_PERI_USI1_SCLK     0x2090
0318 #define CLK_CON_GAT_GOUT_PERI_USI2_PCLK     0x2094
0319 #define CLK_CON_GAT_GOUT_PERI_USI2_SCLK     0x2098
0320 #define CLK_CON_GAT_GOUT_PERI_MCT_PCLK      0x20a0
0321 #define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK  0x20b0
0322 #define CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK 0x20b4
0323 #define CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK 0x20b8
0324 
0325 static const unsigned long peri_clk_regs[] __initconst = {
0326     PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
0327     PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER,
0328     PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER,
0329     PLL_CON0_MUX_CLKCMU_PERI_UART0_USER,
0330     PLL_CON0_MUX_CLKCMU_PERI_UART1_USER,
0331     PLL_CON0_MUX_CLKCMU_PERI_UART2_USER,
0332     PLL_CON0_MUX_CLKCMU_PERI_USI0_USER,
0333     PLL_CON0_MUX_CLKCMU_PERI_USI1_USER,
0334     PLL_CON0_MUX_CLKCMU_PERI_USI2_USER,
0335     CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK,
0336     CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK,
0337     CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK,
0338     CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK,
0339     CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK,
0340     CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK,
0341     CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK,
0342     CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK,
0343     CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK,
0344     CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK,
0345     CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK,
0346     CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK,
0347     CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK,
0348     CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK,
0349     CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK,
0350     CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK,
0351     CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK,
0352     CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK,
0353     CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK,
0354     CLK_CON_GAT_GOUT_PERI_UART_0_PCLK,
0355     CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK,
0356     CLK_CON_GAT_GOUT_PERI_UART_1_PCLK,
0357     CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK,
0358     CLK_CON_GAT_GOUT_PERI_UART_2_PCLK,
0359     CLK_CON_GAT_GOUT_PERI_USI0_PCLK,
0360     CLK_CON_GAT_GOUT_PERI_USI0_SCLK,
0361     CLK_CON_GAT_GOUT_PERI_USI1_PCLK,
0362     CLK_CON_GAT_GOUT_PERI_USI1_SCLK,
0363     CLK_CON_GAT_GOUT_PERI_USI2_PCLK,
0364     CLK_CON_GAT_GOUT_PERI_USI2_SCLK,
0365     CLK_CON_GAT_GOUT_PERI_MCT_PCLK,
0366     CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK,
0367     CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK,
0368     CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK,
0369 };
0370 
0371 /* List of parent clocks for Muxes in CMU_PERI */
0372 PNAME(mout_peri_bus_user_p) = { "oscclk", "dout_peri_bus" };
0373 PNAME(mout_peri_spi0_user_p)    = { "oscclk", "dout_peri_spi0" };
0374 PNAME(mout_peri_spi1_user_p)    = { "oscclk", "dout_peri_spi1" };
0375 PNAME(mout_peri_uart0_user_p)   = { "oscclk", "dout_peri_uart0" };
0376 PNAME(mout_peri_uart1_user_p)   = { "oscclk", "dout_peri_uart1" };
0377 PNAME(mout_peri_uart2_user_p)   = { "oscclk", "dout_peri_uart2" };
0378 PNAME(mout_peri_usi0_user_p)    = { "oscclk", "dout_peri_usi0" };
0379 PNAME(mout_peri_usi1_user_p)    = { "oscclk", "dout_peri_usi1" };
0380 PNAME(mout_peri_usi2_user_p)    = { "oscclk", "dout_peri_usi2" };
0381 
0382 static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
0383     MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p,
0384         PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1),
0385     MUX(CLK_MOUT_PERI_SPI0_USER, "mout_peri_spi0_user", mout_peri_spi0_user_p,
0386         PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER, 4, 1),
0387     MUX(CLK_MOUT_PERI_SPI1_USER, "mout_peri_spi1_user", mout_peri_spi1_user_p,
0388         PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER, 4, 1),
0389     MUX(CLK_MOUT_PERI_UART0_USER, "mout_peri_uart0_user",
0390         mout_peri_uart0_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART0_USER, 4, 1),
0391     MUX(CLK_MOUT_PERI_UART1_USER, "mout_peri_uart1_user",
0392         mout_peri_uart1_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART1_USER, 4, 1),
0393     MUX(CLK_MOUT_PERI_UART2_USER, "mout_peri_uart2_user",
0394         mout_peri_uart2_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART2_USER, 4, 1),
0395     MUX(CLK_MOUT_PERI_USI0_USER, "mout_peri_usi0_user",
0396         mout_peri_usi0_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI0_USER, 4, 1),
0397     MUX(CLK_MOUT_PERI_USI1_USER, "mout_peri_usi1_user",
0398         mout_peri_usi1_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI1_USER, 4, 1),
0399     MUX(CLK_MOUT_PERI_USI2_USER, "mout_peri_usi2_user",
0400         mout_peri_usi2_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI2_USER, 4, 1),
0401 };
0402 
0403 static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
0404     /* TODO: Should be enabled in GPIO driver (or made CLK_IS_CRITICAL) */
0405     GATE(CLK_GOUT_GPIO_TOP_PCLK, "gout_gpio_top_pclk",
0406          "mout_peri_bus_user",
0407          CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK, 21, CLK_IGNORE_UNUSED, 0),
0408     GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user",
0409          CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0),
0410     GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user",
0411          CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0),
0412     GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user",
0413          CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0),
0414     GATE(CLK_GOUT_HSI2C3_PCLK, "gout_hsi2c3_pclk", "mout_peri_bus_user",
0415          CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK, 21, 0, 0),
0416     GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user",
0417          CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0),
0418     GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user",
0419          CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0),
0420     GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user",
0421          CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0),
0422     GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user",
0423          CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0),
0424     GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user",
0425          CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0),
0426     GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user",
0427          CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0),
0428     GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user",
0429          CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0),
0430     GATE(CLK_GOUT_I2C7_PCLK, "gout_i2c7_pclk", "mout_peri_bus_user",
0431          CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK, 21, 0, 0),
0432     GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk",
0433          "mout_peri_bus_user",
0434          CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0),
0435     GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user",
0436          CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0),
0437     GATE(CLK_GOUT_SPI0_EXT_CLK, "gout_spi0_ipclk", "mout_peri_spi0_user",
0438          CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK, 21, 0, 0),
0439     GATE(CLK_GOUT_SPI1_PCLK, "gout_spi1_pclk", "mout_peri_bus_user",
0440          CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK, 21, 0, 0),
0441     GATE(CLK_GOUT_SPI1_EXT_CLK, "gout_spi1_ipclk", "mout_peri_spi1_user",
0442          CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK, 21, 0, 0),
0443     GATE(CLK_GOUT_UART0_EXT_UCLK, "gout_uart0_ext_uclk", "mout_peri_uart0_user",
0444          CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK, 21, 0, 0),
0445     GATE(CLK_GOUT_UART0_PCLK, "gout_uart0_pclk", "mout_peri_bus_user",
0446          CLK_CON_GAT_GOUT_PERI_UART_0_PCLK, 21, 0, 0),
0447     GATE(CLK_GOUT_UART1_EXT_UCLK, "gout_uart1_ext_uclk", "mout_peri_uart1_user",
0448          CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK, 21, 0, 0),
0449     GATE(CLK_GOUT_UART1_PCLK, "gout_uart1_pclk", "mout_peri_bus_user",
0450          CLK_CON_GAT_GOUT_PERI_UART_1_PCLK, 21, 0, 0),
0451     GATE(CLK_GOUT_UART2_EXT_UCLK, "gout_uart2_ext_uclk", "mout_peri_uart2_user",
0452          CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK, 21, 0, 0),
0453     GATE(CLK_GOUT_UART2_PCLK, "gout_uart2_pclk", "mout_peri_bus_user",
0454          CLK_CON_GAT_GOUT_PERI_UART_2_PCLK, 21, 0, 0),
0455     GATE(CLK_GOUT_USI0_PCLK, "gout_usi0_pclk", "mout_peri_bus_user",
0456          CLK_CON_GAT_GOUT_PERI_USI0_PCLK, 21, 0, 0),
0457     GATE(CLK_GOUT_USI0_SCLK, "gout_usi0_sclk", "mout_peri_usi0_user",
0458          CLK_CON_GAT_GOUT_PERI_USI0_SCLK, 21, 0, 0),
0459     GATE(CLK_GOUT_USI1_PCLK, "gout_usi1_pclk", "mout_peri_bus_user",
0460          CLK_CON_GAT_GOUT_PERI_USI1_PCLK, 21, 0, 0),
0461     GATE(CLK_GOUT_USI1_SCLK, "gout_usi1_sclk", "mout_peri_usi1_user",
0462          CLK_CON_GAT_GOUT_PERI_USI1_SCLK, 21, 0, 0),
0463     GATE(CLK_GOUT_USI2_PCLK, "gout_usi2_pclk", "mout_peri_bus_user",
0464          CLK_CON_GAT_GOUT_PERI_USI2_PCLK, 21, 0, 0),
0465     GATE(CLK_GOUT_USI2_SCLK, "gout_usi2_sclk", "mout_peri_usi2_user",
0466          CLK_CON_GAT_GOUT_PERI_USI2_SCLK, 21, 0, 0),
0467     GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user",
0468          CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0),
0469     GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk",
0470          "mout_peri_bus_user",
0471          CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0),
0472     GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user",
0473          CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK, 21, 0, 0),
0474     GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user",
0475          CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK, 21, 0, 0),
0476 };
0477 
0478 static const struct samsung_cmu_info peri_cmu_info __initconst = {
0479     .mux_clks       = peri_mux_clks,
0480     .nr_mux_clks        = ARRAY_SIZE(peri_mux_clks),
0481     .gate_clks      = peri_gate_clks,
0482     .nr_gate_clks       = ARRAY_SIZE(peri_gate_clks),
0483     .nr_clk_ids     = PERI_NR_CLK,
0484     .clk_regs       = peri_clk_regs,
0485     .nr_clk_regs        = ARRAY_SIZE(peri_clk_regs),
0486     .clk_name       = "dout_peri_bus",
0487 };
0488 
0489 static void __init exynos7885_cmu_peri_init(struct device_node *np)
0490 {
0491     exynos_arm64_register_cmu(NULL, np, &peri_cmu_info);
0492 }
0493 
0494 /* Register CMU_PERI early, as it's needed for MCT timer */
0495 CLK_OF_DECLARE(exynos7885_cmu_peri, "samsung,exynos7885-cmu-peri",
0496            exynos7885_cmu_peri_init);
0497 
0498 /* ---- CMU_CORE ------------------------------------------------------------ */
0499 
0500 /* Register Offset definitions for CMU_CORE (0x12000000) */
0501 #define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER   0x0100
0502 #define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER   0x0120
0503 #define PLL_CON0_MUX_CLKCMU_CORE_G3D_USER   0x0140
0504 #define CLK_CON_MUX_MUX_CLK_CORE_GIC        0x1000
0505 #define CLK_CON_DIV_DIV_CLK_CORE_BUSP       0x1800
0506 #define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK  0x2054
0507 #define CLK_CON_GAT_GOUT_CORE_GIC400_CLK    0x2058
0508 
0509 static const unsigned long core_clk_regs[] __initconst = {
0510     PLL_CON0_MUX_CLKCMU_CORE_BUS_USER,
0511     PLL_CON0_MUX_CLKCMU_CORE_CCI_USER,
0512     PLL_CON0_MUX_CLKCMU_CORE_G3D_USER,
0513     CLK_CON_MUX_MUX_CLK_CORE_GIC,
0514     CLK_CON_DIV_DIV_CLK_CORE_BUSP,
0515     CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK,
0516     CLK_CON_GAT_GOUT_CORE_GIC400_CLK,
0517 };
0518 
0519 /* List of parent clocks for Muxes in CMU_CORE */
0520 PNAME(mout_core_bus_user_p)     = { "oscclk", "dout_core_bus" };
0521 PNAME(mout_core_cci_user_p)     = { "oscclk", "dout_core_cci" };
0522 PNAME(mout_core_g3d_user_p)     = { "oscclk", "dout_core_g3d" };
0523 PNAME(mout_core_gic_p)          = { "dout_core_busp", "oscclk" };
0524 
0525 static const struct samsung_mux_clock core_mux_clks[] __initconst = {
0526     MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p,
0527         PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1),
0528     MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p,
0529         PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1),
0530     MUX(CLK_MOUT_CORE_G3D_USER, "mout_core_g3d_user", mout_core_g3d_user_p,
0531         PLL_CON0_MUX_CLKCMU_CORE_G3D_USER, 4, 1),
0532     MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p,
0533         CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1),
0534 };
0535 
0536 static const struct samsung_div_clock core_div_clks[] __initconst = {
0537     DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user",
0538         CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2),
0539 };
0540 
0541 static const struct samsung_gate_clock core_gate_clks[] __initconst = {
0542     /* CCI (interconnect) clock must be always running */
0543     GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user",
0544          CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, CLK_IS_CRITICAL, 0),
0545     /* GIC (interrupt controller) clock must be always running */
0546     GATE(CLK_GOUT_GIC400_CLK, "gout_gic400_clk", "mout_core_gic",
0547          CLK_CON_GAT_GOUT_CORE_GIC400_CLK, 21, CLK_IS_CRITICAL, 0),
0548 };
0549 
0550 static const struct samsung_cmu_info core_cmu_info __initconst = {
0551     .mux_clks       = core_mux_clks,
0552     .nr_mux_clks        = ARRAY_SIZE(core_mux_clks),
0553     .div_clks       = core_div_clks,
0554     .nr_div_clks        = ARRAY_SIZE(core_div_clks),
0555     .gate_clks      = core_gate_clks,
0556     .nr_gate_clks       = ARRAY_SIZE(core_gate_clks),
0557     .nr_clk_ids     = CORE_NR_CLK,
0558     .clk_regs       = core_clk_regs,
0559     .nr_clk_regs        = ARRAY_SIZE(core_clk_regs),
0560     .clk_name       = "dout_core_bus",
0561 };
0562 
0563 /* ---- platform_driver ----------------------------------------------------- */
0564 
0565 static int __init exynos7885_cmu_probe(struct platform_device *pdev)
0566 {
0567     const struct samsung_cmu_info *info;
0568     struct device *dev = &pdev->dev;
0569 
0570     info = of_device_get_match_data(dev);
0571     exynos_arm64_register_cmu(dev, dev->of_node, info);
0572 
0573     return 0;
0574 }
0575 
0576 static const struct of_device_id exynos7885_cmu_of_match[] = {
0577     {
0578         .compatible = "samsung,exynos7885-cmu-core",
0579         .data = &core_cmu_info,
0580     }, {
0581     },
0582 };
0583 
0584 static struct platform_driver exynos7885_cmu_driver __refdata = {
0585     .driver = {
0586         .name = "exynos7885-cmu",
0587         .of_match_table = exynos7885_cmu_of_match,
0588         .suppress_bind_attrs = true,
0589     },
0590     .probe = exynos7885_cmu_probe,
0591 };
0592 
0593 static int __init exynos7885_cmu_init(void)
0594 {
0595     return platform_driver_register(&exynos7885_cmu_driver);
0596 }
0597 core_initcall(exynos7885_cmu_init);