1129203Scognet// SPDX-License-Identifier: GPL-2.0 2129203Scognet/* 3129203Scognet * Copyright 2019 NXP 4129203Scognet * Copyright 2022 Purism 5129203Scognet * Peng Fan <peng.fan@nxp.com> 6129203Scognet */ 7129203Scognet 8129203Scognet#include <common.h> 9129203Scognet#include <clk.h> 10129203Scognet#include <clk-uclass.h> 11129203Scognet#include <dm.h> 12129203Scognet#include <log.h> 13129203Scognet#include <asm/arch/clock.h> 14129203Scognet#include <asm/arch/imx-regs.h> 15129203Scognet#include <dt-bindings/clock/imx8mq-clock.h> 16129203Scognet 17129203Scognet#include "clk.h" 18129203Scognet 19129203Scognetstatic const char *const pll_ref_sels[] = { "clock-osc-25m", "clock-osc-27m", "clock-phy-27m", "dummy", }; 20129203Scognetstatic const char *const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; 21129203Scognetstatic const char *const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; 22129203Scognetstatic const char *const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; 23129203Scognetstatic const char *const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; 24129203Scognetstatic const char *const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; 25129203Scognetstatic const char *const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; 26129203Scognet 27129203Scognetstatic const char *const imx8mq_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; 28129203Scognetstatic const char *const imx8mq_a53_sels[] = {"clock-osc-25m", "arm_pll_out", "sys_pll2_500m", 29129203Scognet "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", 30129203Scognet "audio_pll1_out", "sys_pll3_out", }; 31129203Scognet 32129203Scognetstatic const char *const imx8mq_ahb_sels[] = {"clock-osc-25m", "sys_pll1_133m", "sys_pll1_800m", 33129203Scognet "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out", 34129203Scognet "audio_pll1_out", "video_pll1_out", }; 35129203Scognet 36129203Scognetstatic const char *const imx8mq_dram_alt_sels[] = {"osc_25m", "sys_pll1_800m", "sys_pll1_100m", 37129203Scognet "sys_pll2_500m", "sys_pll2_250m", 38129203Scognet "sys_pll1_400m", "audio_pll1_out", "sys_pll1_266m", } ; 39129203Scognet 40129203Scognetstatic const char * const imx8mq_dram_apb_sels[] = {"osc_25m", "sys_pll2_200m", "sys_pll1_40m", 41129203Scognet "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", 42129203Scognet "sys_pll2_250m", "audio_pll2_out", }; 43129203Scognet 44129203Scognetstatic const char *const imx8mq_enet_axi_sels[] = {"clock-osc-25m", "sys_pll1_266m", "sys_pll1_800m", 45129203Scognet "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", 46129203Scognet "video_pll1_out", "sys_pll3_out", }; 47129203Scognet 48129203Scognetstatic const char *const imx8mq_enet_ref_sels[] = {"clock-osc-25m", "sys_pll2_125m", "sys_pll2_50m", 49129203Scognet "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", 50129203Scognet "video_pll1_out", "clk_ext4", }; 51129203Scognet 52129203Scognetstatic const char *const imx8mq_enet_timer_sels[] = {"clock-osc-25m", "sys_pll2_100m", "audio_pll1_out", 53129203Scognet "clk_ext1", "clk_ext2", "clk_ext3", "clk_ext4", 54129203Scognet "video_pll1_out", }; 55129203Scognet 56129203Scognetstatic const char *const imx8mq_enet_phy_sels[] = {"clock-osc-25m", "sys_pll2_50m", "sys_pll2_125m", 57129203Scognet "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out", 58129203Scognet "audio_pll2_out", }; 59129203Scognet 60129203Scognetstatic const char *const imx8mq_nand_usdhc_sels[] = {"clock-osc-25m", "sys_pll1_266m", "sys_pll1_800m", 61129203Scognet "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", 62129203Scognet "sys_pll2_250m", "audio_pll1_out", }; 63129203Scognet 64static const char *const imx8mq_usb_bus_sels[] = {"clock-osc-25m", "sys_pll2_500m", "sys_pll1_800m", 65 "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", 66 "clk_ext4", "audio_pll2_out", }; 67 68static const char *const imx8mq_usdhc1_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll1_800m", 69 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", 70 "audio_pll2_out", "sys_pll1_100m", }; 71 72static const char *const imx8mq_usdhc2_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll1_800m", 73 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", 74 "audio_pll2_out", "sys_pll1_100m", }; 75 76static const char *const imx8mq_i2c1_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m", 77 "sys_pll3_out", "audio_pll1_out", "video_pll1_out", 78 "audio_pll2_out", "sys_pll1_133m", }; 79 80static const char *const imx8mq_i2c2_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m", 81 "sys_pll3_out", "audio_pll1_out", "video_pll1_out", 82 "audio_pll2_out", "sys_pll1_133m", }; 83 84static const char *const imx8mq_i2c3_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m", 85 "sys_pll3_out", "audio_pll1_out", "video_pll1_out", 86 "audio_pll2_out", "sys_pll1_133m", }; 87 88static const char *const imx8mq_i2c4_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m", 89 "sys_pll3_out", "audio_pll1_out", "video_pll1_out", 90 "audio_pll2_out", "sys_pll1_133m", }; 91 92static const char *const imx8mq_uart1_sels[] = {"clock-osc-25m", "sys_pll1_80m", "sys_pll2_200m", 93 "sys_pll2_100m", "sys_pll3_out", "clk_ext2", 94 "clk_ext4", "audio_pll2_out", }; 95 96static const char *const imx8mq_uart2_sels[] = {"clock-osc-25m", "sys_pll1_80m", "sys_pll2_200m", 97 "sys_pll2_100m", "sys_pll3_out", "clk_ext2", 98 "clk_ext3", "audio_pll2_out", }; 99 100static const char *const imx8mq_uart3_sels[] = {"clock-osc-25m", "sys_pll1_80m", "sys_pll2_200m", 101 "sys_pll2_100m", "sys_pll3_out", "clk_ext2", 102 "clk_ext4", "audio_pll2_out", }; 103 104static const char *const imx8mq_uart4_sels[] = {"clock-osc-25m", "sys_pll1_80m", "sys_pll2_200m", 105 "sys_pll2_100m", "sys_pll3_out", "clk_ext2", 106 "clk_ext3", "audio_pll2_out", }; 107 108static const char *const imx8mq_wdog_sels[] = {"clock-osc-25m", "sys_pll1_133m", "sys_pll1_160m", 109 "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", 110 "sys_pll1_80m", "sys_pll2_166m", }; 111 112static const char *const imx8mq_qspi_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll2_333m", 113 "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", 114 "sys_pll3_out", "sys_pll1_100m", }; 115 116static const char *const imx8mq_usb_core_sels[] = {"clock-osc-25m", "sys_pll1_100m", "sys_pll1_40m", 117 "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", 118 "clk_ext3", "audio_pll2_out", }; 119 120static const char *const imx8mq_usb_phy_sels[] = {"clock-osc-25m", "sys_pll1_100m", "sys_pll1_40m", 121 "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", 122 "clk_ext3", "audio_pll2_out", }; 123 124static const char *const imx8mq_ecspi1_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m", 125 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", 126 "sys_pll2_250m", "audio_pll2_out", }; 127 128static const char *const imx8mq_ecspi2_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m", 129 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", 130 "sys_pll2_250m", "audio_pll2_out", }; 131 132static const char *const imx8mq_ecspi3_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m", 133 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", 134 "sys_pll2_250m", "audio_pll2_out", }; 135 136static const char *const imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; 137 138static const char *const pllout_monitor_sels[] = {"clock-osc-25m", "clock-osc-27m", "clock-phy-27m", 139 "dummy", "clock-ckil", "audio_pll1_out_monitor", 140 "audio_pll2_out_monitor", "gpu_pll_out_monitor", 141 "vpu_pll_out_monitor", "video_pll1_out_monitor", 142 "arm_pll_out_monitor", "sys_pll1_out_monitor", 143 "sys_pll2_out_monitor", "sys_pll3_out_monitor", 144 "video_pll2_out_monitor", "dram_pll_out_monitor", }; 145 146static int imx8mq_clk_probe(struct udevice *dev) 147{ 148 void __iomem *base; 149 150 base = (void *)ANATOP_BASE_ADDR; 151 152 clk_dm(IMX8MQ_CLK_32K, clk_register_fixed_rate(NULL, "ckil", 32768)); 153 clk_dm(IMX8MQ_CLK_27M, clk_register_fixed_rate(NULL, "clock-osc-27m", 27000000)); 154 155 clk_dm(IMX8MQ_DRAM_PLL1_REF_SEL, 156 imx_clk_mux("dram_pll_ref_sel", base + 0x60, 0, 2, 157 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 158 clk_dm(IMX8MQ_ARM_PLL_REF_SEL, 159 imx_clk_mux("arm_pll_ref_sel", base + 0x28, 0, 2, 160 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 161 clk_dm(IMX8MQ_GPU_PLL_REF_SEL, 162 imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 0, 2, 163 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 164 clk_dm(IMX8MQ_VPU_PLL_REF_SEL, 165 imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 0, 2, 166 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 167 clk_dm(IMX8MQ_SYS3_PLL1_REF_SEL, 168 imx_clk_mux("sys3_pll_ref_sel", base + 0x48, 0, 2, 169 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 170 clk_dm(IMX8MQ_AUDIO_PLL1_REF_SEL, 171 imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, 172 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 173 clk_dm(IMX8MQ_AUDIO_PLL2_REF_SEL, 174 imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 0, 2, 175 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 176 clk_dm(IMX8MQ_VIDEO_PLL1_REF_SEL, 177 imx_clk_mux("video_pll1_ref_sel", base + 0x10, 0, 2, 178 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 179 clk_dm(IMX8MQ_VIDEO2_PLL1_REF_SEL, 180 imx_clk_mux("video_pll2_ref_sel", base + 0x54, 0, 2, 181 pll_ref_sels, ARRAY_SIZE(pll_ref_sels))); 182 183 clk_dm(IMX8MQ_ARM_PLL, 184 imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", 185 base + 0x28, &imx_1416x_pll)); 186 clk_dm(IMX8MQ_GPU_PLL, 187 imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", 188 base + 0x18, &imx_1416x_pll)); 189 clk_dm(IMX8MQ_VPU_PLL, 190 imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", 191 base + 0x20, &imx_1416x_pll)); 192 193 clk_dm(IMX8MQ_SYS1_PLL1, 194 clk_register_fixed_rate(NULL, "sys1_pll", 800000000)); 195 clk_dm(IMX8MQ_SYS2_PLL1, 196 clk_register_fixed_rate(NULL, "sys2_pll", 1000000000)); 197 clk_dm(IMX8MQ_SYS2_PLL1, 198 clk_register_fixed_rate(NULL, "sys3_pll", 1000000000)); 199 clk_dm(IMX8MQ_AUDIO_PLL1, 200 imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", 201 base + 0x0, &imx_1443x_pll)); 202 clk_dm(IMX8MQ_AUDIO_PLL2, 203 imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", 204 base + 0x8, &imx_1443x_pll)); 205 clk_dm(IMX8MQ_VIDEO_PLL1, 206 imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", 207 base + 0x10, &imx_1443x_pll)); 208 209 /* PLL bypass out */ 210 clk_dm(IMX8MQ_ARM_PLL_BYPASS, 211 imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 4, 1, 212 arm_pll_bypass_sels, 213 ARRAY_SIZE(arm_pll_bypass_sels), 214 CLK_SET_RATE_PARENT)); 215 clk_dm(IMX8MQ_GPU_PLL_BYPASS, 216 imx_clk_mux_flags("gpu_pll_bypass", base + 0x18, 4, 1, 217 gpu_pll_bypass_sels, 218 ARRAY_SIZE(gpu_pll_bypass_sels), 219 CLK_SET_RATE_PARENT)); 220 clk_dm(IMX8MQ_VPU_PLL_BYPASS, 221 imx_clk_mux_flags("vpu_pll_bypass", base + 0x20, 4, 1, 222 vpu_pll_bypass_sels, 223 ARRAY_SIZE(vpu_pll_bypass_sels), 224 CLK_SET_RATE_PARENT)); 225 clk_dm(IMX8MQ_AUDIO_PLL1_BYPASS, 226 imx_clk_mux_flags("audio_pll1_bypass", base + 0x0, 4, 1, 227 audio_pll1_bypass_sels, 228 ARRAY_SIZE(audio_pll1_bypass_sels), 229 CLK_SET_RATE_PARENT)); 230 clk_dm(IMX8MQ_AUDIO_PLL2_BYPASS, 231 imx_clk_mux_flags("audio_pll2_bypass", base + 0x8, 4, 1, 232 audio_pll2_bypass_sels, 233 ARRAY_SIZE(audio_pll2_bypass_sels), 234 CLK_SET_RATE_PARENT)); 235 clk_dm(IMX8MQ_VIDEO_PLL1_BYPASS, 236 imx_clk_mux_flags("video_pll1_bypass", base + 0x10, 4, 1, 237 video_pll1_bypass_sels, 238 ARRAY_SIZE(video_pll1_bypass_sels), 239 CLK_SET_RATE_PARENT)); 240 241 /* PLL out gate */ 242 clk_dm(IMX8MQ_DRAM_PLL_OUT, 243 imx_clk_gate("dram_pll_out", "dram_pll_ref_sel", 244 base + 0x60, 13)); 245 clk_dm(IMX8MQ_ARM_PLL_OUT, 246 imx_clk_gate("arm_pll_out", "arm_pll_bypass", 247 base + 0x28, 11)); 248 clk_dm(IMX8MQ_GPU_PLL_OUT, 249 imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", 250 base + 0x18, 11)); 251 clk_dm(IMX8MQ_VPU_PLL_OUT, 252 imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", 253 base + 0x20, 11)); 254 clk_dm(IMX8MQ_AUDIO_PLL1_OUT, 255 imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", 256 base + 0x0, 11)); 257 clk_dm(IMX8MQ_AUDIO_PLL2_OUT, 258 imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", 259 base + 0x8, 11)); 260 clk_dm(IMX8MQ_VIDEO_PLL1_OUT, 261 imx_clk_gate("video_pll1_out", "video_pll1_bypass", 262 base + 0x10, 11)); 263 264 clk_dm(IMX8MQ_SYS1_PLL_OUT, 265 imx_clk_gate("sys_pll1_out", "sys1_pll", 266 base + 0x30, 11)); 267 clk_dm(IMX8MQ_SYS2_PLL_OUT, 268 imx_clk_gate("sys_pll2_out", "sys2_pll", 269 base + 0x3c, 11)); 270 clk_dm(IMX8MQ_SYS3_PLL_OUT, 271 imx_clk_gate("sys_pll3_out", "sys3_pll", 272 base + 0x48, 11)); 273 clk_dm(IMX8MQ_VIDEO2_PLL_OUT, 274 imx_clk_gate("video_pll2_out", "video_pll2_ref_sel", 275 base + 0x54, 11)); 276 277 /* SYS PLL fixed output */ 278 clk_dm(IMX8MQ_SYS1_PLL_40M, 279 imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20)); 280 clk_dm(IMX8MQ_SYS1_PLL_80M, 281 imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10)); 282 clk_dm(IMX8MQ_SYS1_PLL_100M, 283 imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8)); 284 clk_dm(IMX8MQ_SYS1_PLL_133M, 285 imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6)); 286 clk_dm(IMX8MQ_SYS1_PLL_160M, 287 imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5)); 288 clk_dm(IMX8MQ_SYS1_PLL_200M, 289 imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4)); 290 clk_dm(IMX8MQ_SYS1_PLL_266M, 291 imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3)); 292 clk_dm(IMX8MQ_SYS1_PLL_400M, 293 imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2)); 294 clk_dm(IMX8MQ_SYS1_PLL_800M, 295 imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1)); 296 297 clk_dm(IMX8MQ_SYS2_PLL_50M, 298 imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20)); 299 clk_dm(IMX8MQ_SYS2_PLL_100M, 300 imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10)); 301 clk_dm(IMX8MQ_SYS2_PLL_125M, 302 imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8)); 303 clk_dm(IMX8MQ_SYS2_PLL_166M, 304 imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6)); 305 clk_dm(IMX8MQ_SYS2_PLL_200M, 306 imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5)); 307 clk_dm(IMX8MQ_SYS2_PLL_250M, 308 imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4)); 309 clk_dm(IMX8MQ_SYS2_PLL_333M, 310 imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3)); 311 clk_dm(IMX8MQ_SYS2_PLL_500M, 312 imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2)); 313 clk_dm(IMX8MQ_SYS2_PLL_1000M, 314 imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1)); 315 316 clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL1_DIV, 317 imx_clk_divider("audio_pll1_out_monitor", "audio_pll1_bypass", base + 0x78, 0, 3)); 318 clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL2_DIV, 319 imx_clk_divider("audio_pll2_out_monitor", "audio_pll2_bypass", base + 0x78, 4, 3)); 320 clk_dm(IMX8MQ_CLK_MON_VIDEO_PLL1_DIV, 321 imx_clk_divider("video_pll1_out_monitor", "video_pll1_bypass", base + 0x78, 8, 3)); 322 clk_dm(IMX8MQ_CLK_MON_GPU_PLL_DIV, 323 imx_clk_divider("gpu_pll_out_monitor", "gpu_pll_bypass", base + 0x78, 12, 3)); 324 clk_dm(IMX8MQ_CLK_MON_VPU_PLL_DIV, 325 imx_clk_divider("vpu_pll_out_monitor", "vpu_pll_bypass", base + 0x78, 16, 3)); 326 clk_dm(IMX8MQ_CLK_MON_ARM_PLL_DIV, 327 imx_clk_divider("arm_pll_out_monitor", "arm_pll_bypass", base + 0x78, 20, 3)); 328 clk_dm(IMX8MQ_CLK_MON_SYS_PLL1_DIV, 329 imx_clk_divider("sys_pll1_out_monitor", "sys_pll1_out", base + 0x7c, 0, 3)); 330 clk_dm(IMX8MQ_CLK_MON_SYS_PLL2_DIV, 331 imx_clk_divider("sys_pll2_out_monitor", "sys_pll2_out", base + 0x7c, 4, 3)); 332 clk_dm(IMX8MQ_CLK_MON_SYS_PLL3_DIV, 333 imx_clk_divider("sys_pll3_out_monitor", "sys_pll3_out", base + 0x7c, 8, 3)); 334 clk_dm(IMX8MQ_CLK_MON_DRAM_PLL_DIV, 335 imx_clk_divider("dram_pll_out_monitor", "dram_pll_out", base + 0x7c, 12, 3)); 336 clk_dm(IMX8MQ_CLK_MON_VIDEO_PLL2_DIV, 337 imx_clk_divider("video_pll2_out_monitor", "video_pll2_out", base + 0x7c, 16, 3)); 338 clk_dm(IMX8MQ_CLK_MON_SEL, 339 imx_clk_mux_flags("pllout_monitor_sel", base + 0x74, 0, 4, 340 pllout_monitor_sels, 341 ARRAY_SIZE(pllout_monitor_sels), 342 CLK_SET_RATE_PARENT)); 343 clk_dm(IMX8MQ_CLK_MON_CLK2_OUT, 344 imx_clk_gate4("pllout_monitor_clk2", "pllout_monitor_sel", base + 0x74, 4)); 345 346 base = dev_read_addr_ptr(dev); 347 if (!base) { 348 printf("%s : base failed\n", __func__); 349 return -EINVAL; 350 } 351 352 clk_dm(IMX8MQ_CLK_A53_SRC, 353 imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, 354 imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels))); 355 clk_dm(IMX8MQ_CLK_A53_CG, 356 imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28)); 357 clk_dm(IMX8MQ_CLK_A53_DIV, 358 imx_clk_divider2("arm_a53_div", "arm_a53_cg", 359 base + 0x8000, 0, 3)); 360 clk_dm(IMX8MQ_CLK_A53_CORE, 361 imx_clk_mux2("arm_a53_src", base + 0x9880, 24, 1, 362 imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels))); 363 364 clk_dm(IMX8MQ_CLK_AHB, 365 imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels, 366 base + 0x9000)); 367 clk_dm(IMX8MQ_CLK_IPG_ROOT, 368 imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1)); 369 370 clk_dm(IMX8MQ_CLK_ENET_AXI, 371 imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels, 372 base + 0x8880)); 373 clk_dm(IMX8MQ_CLK_NAND_USDHC_BUS, 374 imx8m_clk_composite_critical("nand_usdhc_bus", 375 imx8mq_nand_usdhc_sels, 376 base + 0x8900)); 377 clk_dm(IMX8MQ_CLK_USB_BUS, 378 imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80)); 379 380 /* DRAM */ 381 clk_dm(IMX8MQ_CLK_DRAM_CORE, 382 imx_clk_mux2("dram_core_clk", base + 0x9800, 24, 1, 383 imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels))); 384 clk_dm(IMX8MQ_CLK_DRAM_ALT, 385 imx8m_clk_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000)); 386 clk_dm(IMX8MQ_CLK_DRAM_APB, 387 imx8m_clk_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080)); 388 389 /* IP */ 390 clk_dm(IMX8MQ_CLK_USDHC1, 391 imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels, 392 base + 0xac00)); 393 clk_dm(IMX8MQ_CLK_USDHC2, 394 imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels, 395 base + 0xac80)); 396 clk_dm(IMX8MQ_CLK_I2C1, 397 imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00)); 398 clk_dm(IMX8MQ_CLK_I2C2, 399 imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80)); 400 clk_dm(IMX8MQ_CLK_I2C3, 401 imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00)); 402 clk_dm(IMX8MQ_CLK_I2C4, 403 imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80)); 404 clk_dm(IMX8MQ_CLK_WDOG, 405 imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900)); 406 clk_dm(IMX8MQ_CLK_UART1, 407 imx8m_clk_composite("uart1", imx8mq_uart1_sels, base + 0xaf00)); 408 clk_dm(IMX8MQ_CLK_UART2, 409 imx8m_clk_composite("uart2", imx8mq_uart2_sels, base + 0xaf80)); 410 clk_dm(IMX8MQ_CLK_UART3, 411 imx8m_clk_composite("uart3", imx8mq_uart3_sels, base + 0xb000)); 412 clk_dm(IMX8MQ_CLK_UART4, 413 imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080)); 414 clk_dm(IMX8MQ_CLK_QSPI, 415 imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80)); 416 clk_dm(IMX8MQ_CLK_USB_CORE_REF, 417 imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100)); 418 clk_dm(IMX8MQ_CLK_USB_PHY_REF, 419 imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180)); 420 clk_dm(IMX8MQ_CLK_ECSPI1, 421 imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280)); 422 clk_dm(IMX8MQ_CLK_ECSPI2, 423 imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300)); 424 clk_dm(IMX8MQ_CLK_ECSPI3, 425 imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180)); 426 427 clk_dm(IMX8MQ_CLK_ECSPI1_ROOT, 428 imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0)); 429 clk_dm(IMX8MQ_CLK_ECSPI2_ROOT, 430 imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0)); 431 clk_dm(IMX8MQ_CLK_ECSPI3_ROOT, 432 imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0)); 433 clk_dm(IMX8MQ_CLK_I2C1_ROOT, 434 imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); 435 clk_dm(IMX8MQ_CLK_I2C2_ROOT, 436 imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0)); 437 clk_dm(IMX8MQ_CLK_I2C3_ROOT, 438 imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0)); 439 clk_dm(IMX8MQ_CLK_I2C4_ROOT, 440 imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0)); 441 clk_dm(IMX8MQ_CLK_UART1_ROOT, 442 imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0)); 443 clk_dm(IMX8MQ_CLK_UART2_ROOT, 444 imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0)); 445 clk_dm(IMX8MQ_CLK_UART3_ROOT, 446 imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0)); 447 clk_dm(IMX8MQ_CLK_UART4_ROOT, 448 imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0)); 449 clk_dm(IMX8MQ_CLK_OCOTP_ROOT, 450 imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0)); 451 clk_dm(IMX8MQ_CLK_USDHC1_ROOT, 452 imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0)); 453 clk_dm(IMX8MQ_CLK_USDHC2_ROOT, 454 imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0)); 455 clk_dm(IMX8MQ_CLK_WDOG1_ROOT, 456 imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0)); 457 clk_dm(IMX8MQ_CLK_WDOG2_ROOT, 458 imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0)); 459 clk_dm(IMX8MQ_CLK_WDOG3_ROOT, 460 imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0)); 461 clk_dm(IMX8MQ_CLK_QSPI_ROOT, 462 imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); 463 clk_dm(IMX8MQ_CLK_USB1_CTRL_ROOT, 464 imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0)); 465 clk_dm(IMX8MQ_CLK_USB2_CTRL_ROOT, 466 imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0)); 467 clk_dm(IMX8MQ_CLK_USB1_PHY_ROOT, 468 imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0)); 469 clk_dm(IMX8MQ_CLK_USB2_PHY_ROOT, 470 imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0)); 471 472 clk_dm(IMX8MQ_CLK_ENET_REF, 473 imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels, 474 base + 0xa980)); 475 clk_dm(IMX8MQ_CLK_ENET_TIMER, 476 imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels, 477 base + 0xaa00)); 478 clk_dm(IMX8MQ_CLK_ENET_PHY_REF, 479 imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels, 480 base + 0xaa80)); 481 clk_dm(IMX8MQ_CLK_ENET1_ROOT, 482 imx_clk_gate4("enet1_root_clk", "enet_axi", 483 base + 0x40a0, 0)); 484 485 clk_dm(IMX8MQ_CLK_DRAM_ALT_ROOT, 486 imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4)); 487 488 return 0; 489} 490 491static const struct udevice_id imx8mq_clk_ids[] = { 492 { .compatible = "fsl,imx8mq-ccm" }, 493 { }, 494}; 495 496U_BOOT_DRIVER(imx8mq_clk) = { 497 .name = "clk_imx8mq", 498 .id = UCLASS_CLK, 499 .of_match = imx8mq_clk_ids, 500 .ops = &ccf_clk_ops, 501 .probe = imx8mq_clk_probe, 502 .flags = DM_FLAG_PRE_RELOC, 503}; 504