1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * StarFive JH7110 System Clock Driver |
4 | * |
5 | * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk> |
6 | * Copyright (C) 2022 StarFive Technology Co., Ltd. |
7 | */ |
8 | |
9 | #include <linux/auxiliary_bus.h> |
10 | #include <linux/clk.h> |
11 | #include <linux/clk-provider.h> |
12 | #include <linux/init.h> |
13 | #include <linux/io.h> |
14 | #include <linux/platform_device.h> |
15 | #include <linux/slab.h> |
16 | |
17 | #include <soc/starfive/reset-starfive-jh71x0.h> |
18 | |
19 | #include <dt-bindings/clock/starfive,jh7110-crg.h> |
20 | |
21 | #include "clk-starfive-jh7110.h" |
22 | |
23 | /* external clocks */ |
24 | #define JH7110_SYSCLK_OSC (JH7110_SYSCLK_END + 0) |
25 | #define JH7110_SYSCLK_GMAC1_RMII_REFIN (JH7110_SYSCLK_END + 1) |
26 | #define JH7110_SYSCLK_GMAC1_RGMII_RXIN (JH7110_SYSCLK_END + 2) |
27 | #define JH7110_SYSCLK_I2STX_BCLK_EXT (JH7110_SYSCLK_END + 3) |
28 | #define JH7110_SYSCLK_I2STX_LRCK_EXT (JH7110_SYSCLK_END + 4) |
29 | #define JH7110_SYSCLK_I2SRX_BCLK_EXT (JH7110_SYSCLK_END + 5) |
30 | #define JH7110_SYSCLK_I2SRX_LRCK_EXT (JH7110_SYSCLK_END + 6) |
31 | #define JH7110_SYSCLK_TDM_EXT (JH7110_SYSCLK_END + 7) |
32 | #define JH7110_SYSCLK_MCLK_EXT (JH7110_SYSCLK_END + 8) |
33 | #define JH7110_SYSCLK_PLL0_OUT (JH7110_SYSCLK_END + 9) |
34 | #define JH7110_SYSCLK_PLL1_OUT (JH7110_SYSCLK_END + 10) |
35 | #define JH7110_SYSCLK_PLL2_OUT (JH7110_SYSCLK_END + 11) |
36 | |
37 | static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = { |
38 | /* root */ |
39 | JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root" , 0, 2, |
40 | JH7110_SYSCLK_OSC, |
41 | JH7110_SYSCLK_PLL0_OUT), |
42 | JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core" , 7, JH7110_SYSCLK_CPU_ROOT), |
43 | JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus" , 2, JH7110_SYSCLK_CPU_CORE), |
44 | JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root" , 0, 2, |
45 | JH7110_SYSCLK_PLL2_OUT, |
46 | JH7110_SYSCLK_PLL1_OUT), |
47 | JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root" , 2, 2, |
48 | JH7110_SYSCLK_PLL0_OUT, |
49 | JH7110_SYSCLK_PLL2_OUT), |
50 | JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root" , 0, 2, |
51 | JH7110_SYSCLK_OSC, |
52 | JH7110_SYSCLK_PLL2_OUT), |
53 | JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus" , 3, JH7110_SYSCLK_BUS_ROOT), |
54 | JH71X0__DIV(JH7110_SYSCLK_AXI_CFG0, "axi_cfg0" , 3, JH7110_SYSCLK_BUS_ROOT), |
55 | JH71X0__DIV(JH7110_SYSCLK_STG_AXIAHB, "stg_axiahb" , 2, JH7110_SYSCLK_AXI_CFG0), |
56 | JH71X0_GATE(JH7110_SYSCLK_AHB0, "ahb0" , CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB), |
57 | JH71X0_GATE(JH7110_SYSCLK_AHB1, "ahb1" , CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB), |
58 | JH71X0__DIV(JH7110_SYSCLK_APB_BUS, "apb_bus" , 8, JH7110_SYSCLK_STG_AXIAHB), |
59 | JH71X0_GATE(JH7110_SYSCLK_APB0, "apb0" , CLK_IS_CRITICAL, JH7110_SYSCLK_APB_BUS), |
60 | JH71X0__DIV(JH7110_SYSCLK_PLL0_DIV2, "pll0_div2" , 2, JH7110_SYSCLK_PLL0_OUT), |
61 | JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV2, "pll1_div2" , 2, JH7110_SYSCLK_PLL1_OUT), |
62 | JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2" , 2, JH7110_SYSCLK_PLL2_OUT), |
63 | JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root" , 8, JH7110_SYSCLK_PLL2_OUT), |
64 | JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner" , 64, JH7110_SYSCLK_AUDIO_ROOT), |
65 | JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk" , 0, 2, |
66 | JH7110_SYSCLK_MCLK_INNER, |
67 | JH7110_SYSCLK_MCLK_EXT), |
68 | JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out" , 0, JH7110_SYSCLK_MCLK_INNER), |
69 | JH71X0_MDIV(JH7110_SYSCLK_ISP_2X, "isp_2x" , 8, 2, |
70 | JH7110_SYSCLK_PLL2_OUT, |
71 | JH7110_SYSCLK_PLL1_OUT), |
72 | JH71X0__DIV(JH7110_SYSCLK_ISP_AXI, "isp_axi" , 4, JH7110_SYSCLK_ISP_2X), |
73 | JH71X0_GDIV(JH7110_SYSCLK_GCLK0, "gclk0" , 0, 62, JH7110_SYSCLK_PLL0_DIV2), |
74 | JH71X0_GDIV(JH7110_SYSCLK_GCLK1, "gclk1" , 0, 62, JH7110_SYSCLK_PLL1_DIV2), |
75 | JH71X0_GDIV(JH7110_SYSCLK_GCLK2, "gclk2" , 0, 62, JH7110_SYSCLK_PLL2_DIV2), |
76 | /* cores */ |
77 | JH71X0_GATE(JH7110_SYSCLK_CORE, "core" , CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE), |
78 | JH71X0_GATE(JH7110_SYSCLK_CORE1, "core1" , CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE), |
79 | JH71X0_GATE(JH7110_SYSCLK_CORE2, "core2" , CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE), |
80 | JH71X0_GATE(JH7110_SYSCLK_CORE3, "core3" , CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE), |
81 | JH71X0_GATE(JH7110_SYSCLK_CORE4, "core4" , CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE), |
82 | JH71X0_GATE(JH7110_SYSCLK_DEBUG, "debug" , 0, JH7110_SYSCLK_CPU_BUS), |
83 | JH71X0__DIV(JH7110_SYSCLK_RTC_TOGGLE, "rtc_toggle" , 6, JH7110_SYSCLK_OSC), |
84 | JH71X0_GATE(JH7110_SYSCLK_TRACE0, "trace0" , 0, JH7110_SYSCLK_CPU_CORE), |
85 | JH71X0_GATE(JH7110_SYSCLK_TRACE1, "trace1" , 0, JH7110_SYSCLK_CPU_CORE), |
86 | JH71X0_GATE(JH7110_SYSCLK_TRACE2, "trace2" , 0, JH7110_SYSCLK_CPU_CORE), |
87 | JH71X0_GATE(JH7110_SYSCLK_TRACE3, "trace3" , 0, JH7110_SYSCLK_CPU_CORE), |
88 | JH71X0_GATE(JH7110_SYSCLK_TRACE4, "trace4" , 0, JH7110_SYSCLK_CPU_CORE), |
89 | JH71X0_GATE(JH7110_SYSCLK_TRACE_COM, "trace_com" , 0, JH7110_SYSCLK_CPU_BUS), |
90 | /* noc */ |
91 | JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_CPU_AXI, "noc_bus_cpu_axi" , CLK_IS_CRITICAL, |
92 | JH7110_SYSCLK_CPU_BUS), |
93 | JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI, "noc_bus_axicfg0_axi" , CLK_IS_CRITICAL, |
94 | JH7110_SYSCLK_AXI_CFG0), |
95 | /* ddr */ |
96 | JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2" , 2, JH7110_SYSCLK_OSC), |
97 | JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4" , 2, JH7110_SYSCLK_PLL1_DIV2), |
98 | JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8" , 2, JH7110_SYSCLK_PLL1_DIV4), |
99 | JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus" , 0, 4, |
100 | JH7110_SYSCLK_OSC_DIV2, |
101 | JH7110_SYSCLK_PLL1_DIV2, |
102 | JH7110_SYSCLK_PLL1_DIV4, |
103 | JH7110_SYSCLK_PLL1_DIV8), |
104 | JH71X0_GATE(JH7110_SYSCLK_DDR_AXI, "ddr_axi" , CLK_IS_CRITICAL, JH7110_SYSCLK_DDR_BUS), |
105 | /* gpu */ |
106 | JH71X0__DIV(JH7110_SYSCLK_GPU_CORE, "gpu_core" , 7, JH7110_SYSCLK_GPU_ROOT), |
107 | JH71X0_GATE(JH7110_SYSCLK_GPU_CORE_CLK, "gpu_core_clk" , 0, JH7110_SYSCLK_GPU_CORE), |
108 | JH71X0_GATE(JH7110_SYSCLK_GPU_SYS_CLK, "gpu_sys_clk" , 0, JH7110_SYSCLK_ISP_AXI), |
109 | JH71X0_GATE(JH7110_SYSCLK_GPU_APB, "gpu_apb" , 0, JH7110_SYSCLK_APB_BUS), |
110 | JH71X0_GDIV(JH7110_SYSCLK_GPU_RTC_TOGGLE, "gpu_rtc_toggle" , 0, 12, JH7110_SYSCLK_OSC), |
111 | JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_GPU_AXI, "noc_bus_gpu_axi" , 0, JH7110_SYSCLK_GPU_CORE), |
112 | /* isp */ |
113 | JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_CORE, "isp_top_core" , 0, JH7110_SYSCLK_ISP_2X), |
114 | JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_AXI, "isp_top_axi" , 0, JH7110_SYSCLK_ISP_AXI), |
115 | JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_ISP_AXI, "noc_bus_isp_axi" , CLK_IS_CRITICAL, |
116 | JH7110_SYSCLK_ISP_AXI), |
117 | /* hifi4 */ |
118 | JH71X0__DIV(JH7110_SYSCLK_HIFI4_CORE, "hifi4_core" , 15, JH7110_SYSCLK_BUS_ROOT), |
119 | JH71X0__DIV(JH7110_SYSCLK_HIFI4_AXI, "hifi4_axi" , 2, JH7110_SYSCLK_HIFI4_CORE), |
120 | /* axi_cfg1 */ |
121 | JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_MAIN, "axi_cfg1_main" , CLK_IS_CRITICAL, |
122 | JH7110_SYSCLK_ISP_AXI), |
123 | JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_AHB, "axi_cfg1_ahb" , CLK_IS_CRITICAL, |
124 | JH7110_SYSCLK_AHB0), |
125 | /* vout */ |
126 | JH71X0_GATE(JH7110_SYSCLK_VOUT_SRC, "vout_src" , 0, JH7110_SYSCLK_PLL2_OUT), |
127 | JH71X0__DIV(JH7110_SYSCLK_VOUT_AXI, "vout_axi" , 7, JH7110_SYSCLK_PLL2_OUT), |
128 | JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_DISP_AXI, "noc_bus_disp_axi" , 0, JH7110_SYSCLK_VOUT_AXI), |
129 | JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AHB, "vout_top_ahb" , 0, JH7110_SYSCLK_AHB1), |
130 | JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AXI, "vout_top_axi" , 0, JH7110_SYSCLK_VOUT_AXI), |
131 | JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK, "vout_top_hdmitx0_mclk" , 0, |
132 | JH7110_SYSCLK_MCLK), |
133 | JH71X0__DIV(JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF, "vout_top_mipiphy_ref" , 2, |
134 | JH7110_SYSCLK_OSC), |
135 | /* jpegc */ |
136 | JH71X0__DIV(JH7110_SYSCLK_JPEGC_AXI, "jpegc_axi" , 16, JH7110_SYSCLK_PLL2_OUT), |
137 | JH71X0_GATE(JH7110_SYSCLK_CODAJ12_AXI, "codaj12_axi" , 0, JH7110_SYSCLK_JPEGC_AXI), |
138 | JH71X0_GDIV(JH7110_SYSCLK_CODAJ12_CORE, "codaj12_core" , 0, 16, JH7110_SYSCLK_PLL2_OUT), |
139 | JH71X0_GATE(JH7110_SYSCLK_CODAJ12_APB, "codaj12_apb" , 0, JH7110_SYSCLK_APB_BUS), |
140 | /* vdec */ |
141 | JH71X0__DIV(JH7110_SYSCLK_VDEC_AXI, "vdec_axi" , 7, JH7110_SYSCLK_BUS_ROOT), |
142 | JH71X0_GATE(JH7110_SYSCLK_WAVE511_AXI, "wave511_axi" , 0, JH7110_SYSCLK_VDEC_AXI), |
143 | JH71X0_GDIV(JH7110_SYSCLK_WAVE511_BPU, "wave511_bpu" , 0, 7, JH7110_SYSCLK_BUS_ROOT), |
144 | JH71X0_GDIV(JH7110_SYSCLK_WAVE511_VCE, "wave511_vce" , 0, 7, JH7110_SYSCLK_PLL0_OUT), |
145 | JH71X0_GATE(JH7110_SYSCLK_WAVE511_APB, "wave511_apb" , 0, JH7110_SYSCLK_APB_BUS), |
146 | JH71X0_GATE(JH7110_SYSCLK_VDEC_JPG, "vdec_jpg" , 0, JH7110_SYSCLK_JPEGC_AXI), |
147 | JH71X0_GATE(JH7110_SYSCLK_VDEC_MAIN, "vdec_main" , 0, JH7110_SYSCLK_VDEC_AXI), |
148 | JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VDEC_AXI, "noc_bus_vdec_axi" , 0, JH7110_SYSCLK_VDEC_AXI), |
149 | /* venc */ |
150 | JH71X0__DIV(JH7110_SYSCLK_VENC_AXI, "venc_axi" , 15, JH7110_SYSCLK_PLL2_OUT), |
151 | JH71X0_GATE(JH7110_SYSCLK_WAVE420L_AXI, "wave420l_axi" , 0, JH7110_SYSCLK_VENC_AXI), |
152 | JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_BPU, "wave420l_bpu" , 0, 15, JH7110_SYSCLK_PLL2_OUT), |
153 | JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_VCE, "wave420l_vce" , 0, 15, JH7110_SYSCLK_PLL2_OUT), |
154 | JH71X0_GATE(JH7110_SYSCLK_WAVE420L_APB, "wave420l_apb" , 0, JH7110_SYSCLK_APB_BUS), |
155 | JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VENC_AXI, "noc_bus_venc_axi" , 0, JH7110_SYSCLK_VENC_AXI), |
156 | /* axi_cfg0 */ |
157 | JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN_DIV, "axi_cfg0_main_div" , CLK_IS_CRITICAL, |
158 | JH7110_SYSCLK_AHB1), |
159 | JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN, "axi_cfg0_main" , CLK_IS_CRITICAL, |
160 | JH7110_SYSCLK_AXI_CFG0), |
161 | JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_HIFI4, "axi_cfg0_hifi4" , CLK_IS_CRITICAL, |
162 | JH7110_SYSCLK_HIFI4_AXI), |
163 | /* intmem */ |
164 | JH71X0_GATE(JH7110_SYSCLK_AXIMEM2_AXI, "aximem2_axi" , 0, JH7110_SYSCLK_AXI_CFG0), |
165 | /* qspi */ |
166 | JH71X0_GATE(JH7110_SYSCLK_QSPI_AHB, "qspi_ahb" , 0, JH7110_SYSCLK_AHB1), |
167 | JH71X0_GATE(JH7110_SYSCLK_QSPI_APB, "qspi_apb" , 0, JH7110_SYSCLK_APB_BUS), |
168 | JH71X0__DIV(JH7110_SYSCLK_QSPI_REF_SRC, "qspi_ref_src" , 16, JH7110_SYSCLK_PLL0_OUT), |
169 | JH71X0_GMUX(JH7110_SYSCLK_QSPI_REF, "qspi_ref" , 0, 2, |
170 | JH7110_SYSCLK_OSC, |
171 | JH7110_SYSCLK_QSPI_REF_SRC), |
172 | /* sdio */ |
173 | JH71X0_GATE(JH7110_SYSCLK_SDIO0_AHB, "sdio0_ahb" , 0, JH7110_SYSCLK_AHB0), |
174 | JH71X0_GATE(JH7110_SYSCLK_SDIO1_AHB, "sdio1_ahb" , 0, JH7110_SYSCLK_AHB0), |
175 | JH71X0_GDIV(JH7110_SYSCLK_SDIO0_SDCARD, "sdio0_sdcard" , 0, 15, JH7110_SYSCLK_AXI_CFG0), |
176 | JH71X0_GDIV(JH7110_SYSCLK_SDIO1_SDCARD, "sdio1_sdcard" , 0, 15, JH7110_SYSCLK_AXI_CFG0), |
177 | /* stg */ |
178 | JH71X0__DIV(JH7110_SYSCLK_USB_125M, "usb_125m" , 15, JH7110_SYSCLK_PLL0_OUT), |
179 | JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_STG_AXI, "noc_bus_stg_axi" , CLK_IS_CRITICAL, |
180 | JH7110_SYSCLK_NOCSTG_BUS), |
181 | /* gmac1 */ |
182 | JH71X0_GATE(JH7110_SYSCLK_GMAC1_AHB, "gmac1_ahb" , 0, JH7110_SYSCLK_AHB0), |
183 | JH71X0_GATE(JH7110_SYSCLK_GMAC1_AXI, "gmac1_axi" , 0, JH7110_SYSCLK_STG_AXIAHB), |
184 | JH71X0__DIV(JH7110_SYSCLK_GMAC_SRC, "gmac_src" , 7, JH7110_SYSCLK_PLL0_OUT), |
185 | JH71X0__DIV(JH7110_SYSCLK_GMAC1_GTXCLK, "gmac1_gtxclk" , 15, JH7110_SYSCLK_PLL0_OUT), |
186 | JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx" , 30, |
187 | JH7110_SYSCLK_GMAC1_RMII_REFIN), |
188 | JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp" , 0, 31, JH7110_SYSCLK_GMAC_SRC), |
189 | JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx" , 0, 2, |
190 | JH7110_SYSCLK_GMAC1_RGMII_RXIN, |
191 | JH7110_SYSCLK_GMAC1_RMII_RTX), |
192 | JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv" , JH7110_SYSCLK_GMAC1_RX), |
193 | JH71X0_GMUX(JH7110_SYSCLK_GMAC1_TX, "gmac1_tx" , |
194 | CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2, |
195 | JH7110_SYSCLK_GMAC1_GTXCLK, |
196 | JH7110_SYSCLK_GMAC1_RMII_RTX), |
197 | JH71X0__INV(JH7110_SYSCLK_GMAC1_TX_INV, "gmac1_tx_inv" , JH7110_SYSCLK_GMAC1_TX), |
198 | JH71X0_GATE(JH7110_SYSCLK_GMAC1_GTXC, "gmac1_gtxc" , 0, JH7110_SYSCLK_GMAC1_GTXCLK), |
199 | /* gmac0 */ |
200 | JH71X0_GDIV(JH7110_SYSCLK_GMAC0_GTXCLK, "gmac0_gtxclk" , 0, 15, JH7110_SYSCLK_PLL0_OUT), |
201 | JH71X0_GDIV(JH7110_SYSCLK_GMAC0_PTP, "gmac0_ptp" , 0, 31, JH7110_SYSCLK_GMAC_SRC), |
202 | JH71X0_GDIV(JH7110_SYSCLK_GMAC_PHY, "gmac_phy" , 0, 31, JH7110_SYSCLK_GMAC_SRC), |
203 | JH71X0_GATE(JH7110_SYSCLK_GMAC0_GTXC, "gmac0_gtxc" , 0, JH7110_SYSCLK_GMAC0_GTXCLK), |
204 | /* apb misc */ |
205 | JH71X0_GATE(JH7110_SYSCLK_IOMUX_APB, "iomux_apb" , 0, JH7110_SYSCLK_APB_BUS), |
206 | JH71X0_GATE(JH7110_SYSCLK_MAILBOX_APB, "mailbox_apb" , 0, JH7110_SYSCLK_APB_BUS), |
207 | JH71X0_GATE(JH7110_SYSCLK_INT_CTRL_APB, "int_ctrl_apb" , 0, JH7110_SYSCLK_APB_BUS), |
208 | /* can0 */ |
209 | JH71X0_GATE(JH7110_SYSCLK_CAN0_APB, "can0_apb" , 0, JH7110_SYSCLK_APB_BUS), |
210 | JH71X0_GDIV(JH7110_SYSCLK_CAN0_TIMER, "can0_timer" , 0, 24, JH7110_SYSCLK_OSC), |
211 | JH71X0_GDIV(JH7110_SYSCLK_CAN0_CAN, "can0_can" , 0, 63, JH7110_SYSCLK_PERH_ROOT), |
212 | /* can1 */ |
213 | JH71X0_GATE(JH7110_SYSCLK_CAN1_APB, "can1_apb" , 0, JH7110_SYSCLK_APB_BUS), |
214 | JH71X0_GDIV(JH7110_SYSCLK_CAN1_TIMER, "can1_timer" , 0, 24, JH7110_SYSCLK_OSC), |
215 | JH71X0_GDIV(JH7110_SYSCLK_CAN1_CAN, "can1_can" , 0, 63, JH7110_SYSCLK_PERH_ROOT), |
216 | /* pwm */ |
217 | JH71X0_GATE(JH7110_SYSCLK_PWM_APB, "pwm_apb" , 0, JH7110_SYSCLK_APB_BUS), |
218 | /* wdt */ |
219 | JH71X0_GATE(JH7110_SYSCLK_WDT_APB, "wdt_apb" , 0, JH7110_SYSCLK_APB_BUS), |
220 | JH71X0_GATE(JH7110_SYSCLK_WDT_CORE, "wdt_core" , 0, JH7110_SYSCLK_OSC), |
221 | /* timer */ |
222 | JH71X0_GATE(JH7110_SYSCLK_TIMER_APB, "timer_apb" , 0, JH7110_SYSCLK_APB_BUS), |
223 | JH71X0_GATE(JH7110_SYSCLK_TIMER0, "timer0" , 0, JH7110_SYSCLK_OSC), |
224 | JH71X0_GATE(JH7110_SYSCLK_TIMER1, "timer1" , 0, JH7110_SYSCLK_OSC), |
225 | JH71X0_GATE(JH7110_SYSCLK_TIMER2, "timer2" , 0, JH7110_SYSCLK_OSC), |
226 | JH71X0_GATE(JH7110_SYSCLK_TIMER3, "timer3" , 0, JH7110_SYSCLK_OSC), |
227 | /* temp sensor */ |
228 | JH71X0_GATE(JH7110_SYSCLK_TEMP_APB, "temp_apb" , 0, JH7110_SYSCLK_APB_BUS), |
229 | JH71X0_GDIV(JH7110_SYSCLK_TEMP_CORE, "temp_core" , 0, 24, JH7110_SYSCLK_OSC), |
230 | /* spi */ |
231 | JH71X0_GATE(JH7110_SYSCLK_SPI0_APB, "spi0_apb" , 0, JH7110_SYSCLK_APB0), |
232 | JH71X0_GATE(JH7110_SYSCLK_SPI1_APB, "spi1_apb" , 0, JH7110_SYSCLK_APB0), |
233 | JH71X0_GATE(JH7110_SYSCLK_SPI2_APB, "spi2_apb" , 0, JH7110_SYSCLK_APB0), |
234 | JH71X0_GATE(JH7110_SYSCLK_SPI3_APB, "spi3_apb" , 0, JH7110_SYSCLK_APB_BUS), |
235 | JH71X0_GATE(JH7110_SYSCLK_SPI4_APB, "spi4_apb" , 0, JH7110_SYSCLK_APB_BUS), |
236 | JH71X0_GATE(JH7110_SYSCLK_SPI5_APB, "spi5_apb" , 0, JH7110_SYSCLK_APB_BUS), |
237 | JH71X0_GATE(JH7110_SYSCLK_SPI6_APB, "spi6_apb" , 0, JH7110_SYSCLK_APB_BUS), |
238 | /* i2c */ |
239 | JH71X0_GATE(JH7110_SYSCLK_I2C0_APB, "i2c0_apb" , 0, JH7110_SYSCLK_APB0), |
240 | JH71X0_GATE(JH7110_SYSCLK_I2C1_APB, "i2c1_apb" , 0, JH7110_SYSCLK_APB0), |
241 | JH71X0_GATE(JH7110_SYSCLK_I2C2_APB, "i2c2_apb" , 0, JH7110_SYSCLK_APB0), |
242 | JH71X0_GATE(JH7110_SYSCLK_I2C3_APB, "i2c3_apb" , 0, JH7110_SYSCLK_APB_BUS), |
243 | JH71X0_GATE(JH7110_SYSCLK_I2C4_APB, "i2c4_apb" , 0, JH7110_SYSCLK_APB_BUS), |
244 | JH71X0_GATE(JH7110_SYSCLK_I2C5_APB, "i2c5_apb" , 0, JH7110_SYSCLK_APB_BUS), |
245 | JH71X0_GATE(JH7110_SYSCLK_I2C6_APB, "i2c6_apb" , 0, JH7110_SYSCLK_APB_BUS), |
246 | /* uart */ |
247 | JH71X0_GATE(JH7110_SYSCLK_UART0_APB, "uart0_apb" , 0, JH7110_SYSCLK_APB0), |
248 | JH71X0_GATE(JH7110_SYSCLK_UART0_CORE, "uart0_core" , 0, JH7110_SYSCLK_OSC), |
249 | JH71X0_GATE(JH7110_SYSCLK_UART1_APB, "uart1_apb" , 0, JH7110_SYSCLK_APB0), |
250 | JH71X0_GATE(JH7110_SYSCLK_UART1_CORE, "uart1_core" , 0, JH7110_SYSCLK_OSC), |
251 | JH71X0_GATE(JH7110_SYSCLK_UART2_APB, "uart2_apb" , 0, JH7110_SYSCLK_APB0), |
252 | JH71X0_GATE(JH7110_SYSCLK_UART2_CORE, "uart2_core" , 0, JH7110_SYSCLK_OSC), |
253 | JH71X0_GATE(JH7110_SYSCLK_UART3_APB, "uart3_apb" , 0, JH7110_SYSCLK_APB0), |
254 | JH71X0_GDIV(JH7110_SYSCLK_UART3_CORE, "uart3_core" , 0, 10, JH7110_SYSCLK_PERH_ROOT), |
255 | JH71X0_GATE(JH7110_SYSCLK_UART4_APB, "uart4_apb" , 0, JH7110_SYSCLK_APB0), |
256 | JH71X0_GDIV(JH7110_SYSCLK_UART4_CORE, "uart4_core" , 0, 10, JH7110_SYSCLK_PERH_ROOT), |
257 | JH71X0_GATE(JH7110_SYSCLK_UART5_APB, "uart5_apb" , 0, JH7110_SYSCLK_APB0), |
258 | JH71X0_GDIV(JH7110_SYSCLK_UART5_CORE, "uart5_core" , 0, 10, JH7110_SYSCLK_PERH_ROOT), |
259 | /* pwmdac */ |
260 | JH71X0_GATE(JH7110_SYSCLK_PWMDAC_APB, "pwmdac_apb" , 0, JH7110_SYSCLK_APB0), |
261 | JH71X0_GDIV(JH7110_SYSCLK_PWMDAC_CORE, "pwmdac_core" , 0, 256, JH7110_SYSCLK_AUDIO_ROOT), |
262 | /* spdif */ |
263 | JH71X0_GATE(JH7110_SYSCLK_SPDIF_APB, "spdif_apb" , 0, JH7110_SYSCLK_APB0), |
264 | JH71X0_GATE(JH7110_SYSCLK_SPDIF_CORE, "spdif_core" , 0, JH7110_SYSCLK_MCLK), |
265 | /* i2stx0 */ |
266 | JH71X0_GATE(JH7110_SYSCLK_I2STX0_APB, "i2stx0_apb" , 0, JH7110_SYSCLK_APB0), |
267 | JH71X0_GDIV(JH7110_SYSCLK_I2STX0_BCLK_MST, "i2stx0_bclk_mst" , 0, 32, JH7110_SYSCLK_MCLK), |
268 | JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_MST_INV, "i2stx0_bclk_mst_inv" , |
269 | JH7110_SYSCLK_I2STX0_BCLK_MST), |
270 | JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst" , 64, 2, |
271 | JH7110_SYSCLK_I2STX0_BCLK_MST_INV, |
272 | JH7110_SYSCLK_I2STX0_BCLK_MST), |
273 | JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk" , 0, 2, |
274 | JH7110_SYSCLK_I2STX0_BCLK_MST, |
275 | JH7110_SYSCLK_I2STX_BCLK_EXT), |
276 | JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv" , JH7110_SYSCLK_I2STX0_BCLK), |
277 | JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck" , 0, 2, |
278 | JH7110_SYSCLK_I2STX0_LRCK_MST, |
279 | JH7110_SYSCLK_I2STX_LRCK_EXT), |
280 | /* i2stx1 */ |
281 | JH71X0_GATE(JH7110_SYSCLK_I2STX1_APB, "i2stx1_apb" , 0, JH7110_SYSCLK_APB0), |
282 | JH71X0_GDIV(JH7110_SYSCLK_I2STX1_BCLK_MST, "i2stx1_bclk_mst" , 0, 32, JH7110_SYSCLK_MCLK), |
283 | JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_MST_INV, "i2stx1_bclk_mst_inv" , |
284 | JH7110_SYSCLK_I2STX1_BCLK_MST), |
285 | JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst" , 64, 2, |
286 | JH7110_SYSCLK_I2STX1_BCLK_MST_INV, |
287 | JH7110_SYSCLK_I2STX1_BCLK_MST), |
288 | JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk" , 0, 2, |
289 | JH7110_SYSCLK_I2STX1_BCLK_MST, |
290 | JH7110_SYSCLK_I2STX_BCLK_EXT), |
291 | JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv" , JH7110_SYSCLK_I2STX1_BCLK), |
292 | JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck" , 0, 2, |
293 | JH7110_SYSCLK_I2STX1_LRCK_MST, |
294 | JH7110_SYSCLK_I2STX_LRCK_EXT), |
295 | /* i2srx */ |
296 | JH71X0_GATE(JH7110_SYSCLK_I2SRX_APB, "i2srx_apb" , 0, JH7110_SYSCLK_APB0), |
297 | JH71X0_GDIV(JH7110_SYSCLK_I2SRX_BCLK_MST, "i2srx_bclk_mst" , 0, 32, JH7110_SYSCLK_MCLK), |
298 | JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_MST_INV, "i2srx_bclk_mst_inv" , |
299 | JH7110_SYSCLK_I2SRX_BCLK_MST), |
300 | JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst" , 64, 2, |
301 | JH7110_SYSCLK_I2SRX_BCLK_MST_INV, |
302 | JH7110_SYSCLK_I2SRX_BCLK_MST), |
303 | JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk" , 0, 2, |
304 | JH7110_SYSCLK_I2SRX_BCLK_MST, |
305 | JH7110_SYSCLK_I2SRX_BCLK_EXT), |
306 | JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv" , JH7110_SYSCLK_I2SRX_BCLK), |
307 | JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck" , 0, 2, |
308 | JH7110_SYSCLK_I2SRX_LRCK_MST, |
309 | JH7110_SYSCLK_I2SRX_LRCK_EXT), |
310 | /* pdm */ |
311 | JH71X0_GDIV(JH7110_SYSCLK_PDM_DMIC, "pdm_dmic" , 0, 64, JH7110_SYSCLK_MCLK), |
312 | JH71X0_GATE(JH7110_SYSCLK_PDM_APB, "pdm_apb" , 0, JH7110_SYSCLK_APB0), |
313 | /* tdm */ |
314 | JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb" , 0, JH7110_SYSCLK_AHB0), |
315 | JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb" , 0, JH7110_SYSCLK_APB0), |
316 | JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal" , 0, 64, JH7110_SYSCLK_MCLK), |
317 | JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm" , 0, 2, |
318 | JH7110_SYSCLK_TDM_INTERNAL, |
319 | JH7110_SYSCLK_TDM_EXT), |
320 | JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv" , JH7110_SYSCLK_TDM_TDM), |
321 | /* jtag */ |
322 | JH71X0__DIV(JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG, "jtag_certification_trng" , 4, |
323 | JH7110_SYSCLK_OSC), |
324 | }; |
325 | |
326 | static struct clk_hw *jh7110_sysclk_get(struct of_phandle_args *clkspec, void *data) |
327 | { |
328 | struct jh71x0_clk_priv *priv = data; |
329 | unsigned int idx = clkspec->args[0]; |
330 | |
331 | if (idx < JH7110_SYSCLK_END) |
332 | return &priv->reg[idx].hw; |
333 | |
334 | return ERR_PTR(error: -EINVAL); |
335 | } |
336 | |
337 | static void jh7110_reset_unregister_adev(void *_adev) |
338 | { |
339 | struct auxiliary_device *adev = _adev; |
340 | |
341 | auxiliary_device_delete(auxdev: adev); |
342 | auxiliary_device_uninit(auxdev: adev); |
343 | } |
344 | |
345 | static void jh7110_reset_adev_release(struct device *dev) |
346 | { |
347 | struct auxiliary_device *adev = to_auxiliary_dev(dev); |
348 | struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev); |
349 | |
350 | kfree(objp: rdev); |
351 | } |
352 | |
353 | int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv, |
354 | const char *adev_name, |
355 | u32 adev_id) |
356 | { |
357 | struct jh71x0_reset_adev *rdev; |
358 | struct auxiliary_device *adev; |
359 | int ret; |
360 | |
361 | rdev = kzalloc(size: sizeof(*rdev), GFP_KERNEL); |
362 | if (!rdev) |
363 | return -ENOMEM; |
364 | |
365 | rdev->base = priv->base; |
366 | |
367 | adev = &rdev->adev; |
368 | adev->name = adev_name; |
369 | adev->dev.parent = priv->dev; |
370 | adev->dev.release = jh7110_reset_adev_release; |
371 | adev->id = adev_id; |
372 | |
373 | ret = auxiliary_device_init(auxdev: adev); |
374 | if (ret) |
375 | return ret; |
376 | |
377 | ret = auxiliary_device_add(adev); |
378 | if (ret) { |
379 | auxiliary_device_uninit(auxdev: adev); |
380 | return ret; |
381 | } |
382 | |
383 | return devm_add_action_or_reset(priv->dev, |
384 | jh7110_reset_unregister_adev, adev); |
385 | } |
386 | EXPORT_SYMBOL_GPL(jh7110_reset_controller_register); |
387 | |
388 | static int __init jh7110_syscrg_probe(struct platform_device *pdev) |
389 | { |
390 | struct jh71x0_clk_priv *priv; |
391 | unsigned int idx; |
392 | int ret; |
393 | struct clk *pllclk; |
394 | |
395 | priv = devm_kzalloc(dev: &pdev->dev, |
396 | struct_size(priv, reg, JH7110_SYSCLK_END), |
397 | GFP_KERNEL); |
398 | if (!priv) |
399 | return -ENOMEM; |
400 | |
401 | spin_lock_init(&priv->rmw_lock); |
402 | priv->dev = &pdev->dev; |
403 | priv->base = devm_platform_ioremap_resource(pdev, index: 0); |
404 | if (IS_ERR(ptr: priv->base)) |
405 | return PTR_ERR(ptr: priv->base); |
406 | |
407 | /* Use fixed factor clocks if can not get the PLL clocks from DTS */ |
408 | pllclk = clk_get(dev: priv->dev, id: "pll0_out" ); |
409 | if (IS_ERR(ptr: pllclk)) { |
410 | /* 24MHz -> 1000.0MHz */ |
411 | priv->pll[0] = devm_clk_hw_register_fixed_factor(dev: priv->dev, name: "pll0_out" , |
412 | parent_name: "osc" , flags: 0, mult: 125, div: 3); |
413 | if (IS_ERR(ptr: priv->pll[0])) |
414 | return PTR_ERR(ptr: priv->pll[0]); |
415 | } else { |
416 | clk_put(clk: pllclk); |
417 | priv->pll[0] = NULL; |
418 | } |
419 | |
420 | pllclk = clk_get(dev: priv->dev, id: "pll1_out" ); |
421 | if (IS_ERR(ptr: pllclk)) { |
422 | /* 24MHz -> 1066.0MHz */ |
423 | priv->pll[1] = devm_clk_hw_register_fixed_factor(dev: priv->dev, name: "pll1_out" , |
424 | parent_name: "osc" , flags: 0, mult: 533, div: 12); |
425 | if (IS_ERR(ptr: priv->pll[1])) |
426 | return PTR_ERR(ptr: priv->pll[1]); |
427 | } else { |
428 | clk_put(clk: pllclk); |
429 | priv->pll[1] = NULL; |
430 | } |
431 | |
432 | pllclk = clk_get(dev: priv->dev, id: "pll2_out" ); |
433 | if (IS_ERR(ptr: pllclk)) { |
434 | /* 24MHz -> 1188.0MHz */ |
435 | priv->pll[2] = devm_clk_hw_register_fixed_factor(dev: priv->dev, name: "pll2_out" , |
436 | parent_name: "osc" , flags: 0, mult: 99, div: 2); |
437 | if (IS_ERR(ptr: priv->pll[2])) |
438 | return PTR_ERR(ptr: priv->pll[2]); |
439 | } else { |
440 | clk_put(clk: pllclk); |
441 | priv->pll[2] = NULL; |
442 | } |
443 | |
444 | for (idx = 0; idx < JH7110_SYSCLK_END; idx++) { |
445 | u32 max = jh7110_sysclk_data[idx].max; |
446 | struct clk_parent_data parents[4] = {}; |
447 | struct clk_init_data init = { |
448 | .name = jh7110_sysclk_data[idx].name, |
449 | .ops = starfive_jh71x0_clk_ops(max), |
450 | .parent_data = parents, |
451 | .num_parents = |
452 | ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1, |
453 | .flags = jh7110_sysclk_data[idx].flags, |
454 | }; |
455 | struct jh71x0_clk *clk = &priv->reg[idx]; |
456 | unsigned int i; |
457 | |
458 | for (i = 0; i < init.num_parents; i++) { |
459 | unsigned int pidx = jh7110_sysclk_data[idx].parents[i]; |
460 | |
461 | if (pidx < JH7110_SYSCLK_END) |
462 | parents[i].hw = &priv->reg[pidx].hw; |
463 | else if (pidx == JH7110_SYSCLK_OSC) |
464 | parents[i].fw_name = "osc" ; |
465 | else if (pidx == JH7110_SYSCLK_GMAC1_RMII_REFIN) |
466 | parents[i].fw_name = "gmac1_rmii_refin" ; |
467 | else if (pidx == JH7110_SYSCLK_GMAC1_RGMII_RXIN) |
468 | parents[i].fw_name = "gmac1_rgmii_rxin" ; |
469 | else if (pidx == JH7110_SYSCLK_I2STX_BCLK_EXT) |
470 | parents[i].fw_name = "i2stx_bclk_ext" ; |
471 | else if (pidx == JH7110_SYSCLK_I2STX_LRCK_EXT) |
472 | parents[i].fw_name = "i2stx_lrck_ext" ; |
473 | else if (pidx == JH7110_SYSCLK_I2SRX_BCLK_EXT) |
474 | parents[i].fw_name = "i2srx_bclk_ext" ; |
475 | else if (pidx == JH7110_SYSCLK_I2SRX_LRCK_EXT) |
476 | parents[i].fw_name = "i2srx_lrck_ext" ; |
477 | else if (pidx == JH7110_SYSCLK_TDM_EXT) |
478 | parents[i].fw_name = "tdm_ext" ; |
479 | else if (pidx == JH7110_SYSCLK_MCLK_EXT) |
480 | parents[i].fw_name = "mclk_ext" ; |
481 | else if (pidx == JH7110_SYSCLK_PLL0_OUT && !priv->pll[0]) |
482 | parents[i].fw_name = "pll0_out" ; |
483 | else if (pidx == JH7110_SYSCLK_PLL1_OUT && !priv->pll[1]) |
484 | parents[i].fw_name = "pll1_out" ; |
485 | else if (pidx == JH7110_SYSCLK_PLL2_OUT && !priv->pll[2]) |
486 | parents[i].fw_name = "pll2_out" ; |
487 | else |
488 | parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT]; |
489 | } |
490 | |
491 | clk->hw.init = &init; |
492 | clk->idx = idx; |
493 | clk->max_div = max & JH71X0_CLK_DIV_MASK; |
494 | |
495 | ret = devm_clk_hw_register(dev: &pdev->dev, hw: &clk->hw); |
496 | if (ret) |
497 | return ret; |
498 | } |
499 | |
500 | ret = devm_of_clk_add_hw_provider(dev: &pdev->dev, get: jh7110_sysclk_get, data: priv); |
501 | if (ret) |
502 | return ret; |
503 | |
504 | return jh7110_reset_controller_register(priv, "rst-sys" , 0); |
505 | } |
506 | |
507 | static const struct of_device_id jh7110_syscrg_match[] = { |
508 | { .compatible = "starfive,jh7110-syscrg" }, |
509 | { /* sentinel */ } |
510 | }; |
511 | |
512 | static struct platform_driver jh7110_syscrg_driver = { |
513 | .driver = { |
514 | .name = "clk-starfive-jh7110-sys" , |
515 | .of_match_table = jh7110_syscrg_match, |
516 | .suppress_bind_attrs = true, |
517 | }, |
518 | }; |
519 | builtin_platform_driver_probe(jh7110_syscrg_driver, jh7110_syscrg_probe); |
520 | |