1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2017 NXP 4 * 5 * Peng Fan <peng.fan (at) nxp.com> 6 */ 7 8 #include <common.h> 9 #include <asm/arch/clock.h> 10 #include <asm/arch/imx-regs.h> 11 #include <asm/io.h> 12 #include <errno.h> 13 14 static struct ccm_reg *ccm_reg = (struct ccm_reg *)CCM_BASE_ADDR; 15 16 static struct clk_root_map root_array[] = { 17 {ARM_A53_CLK_ROOT, CORE_CLOCK_SLICE, 0, 18 {OSC_25M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK, 19 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, 20 SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL3_CLK} 21 }, 22 {ARM_M4_CLK_ROOT, CORE_CLOCK_SLICE, 1, 23 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_250M_CLK, 24 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, 25 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK} 26 }, 27 {VPU_A53_CLK_ROOT, CORE_CLOCK_SLICE, 2, 28 {OSC_25M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK, 29 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, 30 SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, VPU_PLL_CLK} 31 }, 32 {GPU_CORE_CLK_ROOT, CORE_CLOCK_SLICE, 3, 33 {OSC_25M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, 34 SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, 35 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} 36 }, 37 {GPU_SHADER_CLK_ROOT, CORE_CLOCK_SLICE, 4, 38 {OSC_25M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, 39 SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, 40 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} 41 }, 42 {MAIN_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 0, 43 {OSC_25M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL1_800M_CLK, 44 SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_1000M_CLK, 45 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL1_100M_CLK} 46 }, 47 {ENET_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 1, 48 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, 49 SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, 50 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK} 51 }, 52 {NAND_USDHC_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 2, 53 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, 54 SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_133M_CLK, 55 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL1_CLK} 56 }, 57 {VPU_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 3, 58 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, VPU_PLL_CLK, 59 AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, 60 SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_100M_CLK} 61 }, 62 {DISPLAY_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 4, 63 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK, 64 SYSTEM_PLL3_CLK, SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, 65 EXT_CLK_1, EXT_CLK_4} 66 }, 67 {DISPLAY_APB_CLK_ROOT, BUS_CLOCK_SLICE, 5, 68 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK, 69 SYSTEM_PLL3_CLK, SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, 70 EXT_CLK_1, EXT_CLK_3} 71 }, 72 {DISPLAY_RTRM_CLK_ROOT, BUS_CLOCK_SLICE, 6, 73 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_200M_CLK, 74 SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, 75 EXT_CLK_2, EXT_CLK_3} 76 }, 77 {USB_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 7, 78 {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK, 79 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, 80 EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} 81 }, 82 {GPU_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 8, 83 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK, 84 SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, 85 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} 86 }, 87 {GPU_AHB_CLK_ROOT, BUS_CLOCK_SLICE, 9, 88 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK, 89 SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, 90 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} 91 }, 92 {NOC_CLK_ROOT, BUS_CLOCK_SLICE, 10, 93 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL3_CLK, 94 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_500M_CLK, 95 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} 96 }, 97 {NOC_APB_CLK_ROOT, BUS_CLOCK_SLICE, 11, 98 {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL3_CLK, 99 SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_200M_CLK, 100 SYSTEM_PLL1_800M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} 101 }, 102 {AHB_CLK_ROOT, AHB_CLOCK_SLICE, 0, 103 {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_800M_CLK, 104 SYSTEM_PLL1_400M_CLK, SYSTEM_PLL2_125M_CLK, 105 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} 106 }, 107 {IPG_CLK_ROOT, IPG_CLOCK_SLICE, 0, 108 {} 109 }, 110 {AUDIO_AHB_CLK_ROOT, AHB_CLOCK_SLICE, 1, 111 {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK, 112 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_166M_CLK, 113 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} 114 }, 115 {MIPI_DSI_ESC_RX_CLK_ROOT, AHB_CLOCK_SLICE, 2, 116 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_40M_CLK, 117 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 118 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL1_CLK }, 119 }, 120 {DRAM_ALT_CLK_ROOT, IP_CLOCK_SLICE, 0, 121 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL1_100M_CLK, 122 SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_250M_CLK, 123 SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL1_266M_CLK} 124 }, 125 {DRAM_APB_CLK_ROOT, IP_CLOCK_SLICE, 1, 126 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, 127 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, 128 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} 129 }, 130 {VPU_G1_CLK_ROOT, IP_CLOCK_SLICE, 2, 131 {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, 132 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_100M_CLK, 133 SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK} 134 }, 135 {VPU_G2_CLK_ROOT, IP_CLOCK_SLICE, 3, 136 {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, 137 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_100M_CLK, 138 SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK} 139 }, 140 {DISPLAY_DTRC_CLK_ROOT, IP_CLOCK_SLICE, 4, 141 {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, 142 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_160M_CLK, 143 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK} 144 }, 145 {DISPLAY_DC8000_CLK_ROOT, IP_CLOCK_SLICE, 5, 146 {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, 147 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_160M_CLK, 148 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK} 149 }, 150 {PCIE1_CTRL_CLK_ROOT, IP_CLOCK_SLICE, 6, 151 {OSC_25M_CLK, SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, 152 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, 153 SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL3_CLK} 154 }, 155 {PCIE1_PHY_CLK_ROOT, IP_CLOCK_SLICE, 7, 156 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_500M_CLK, 157 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4, 158 SYSTEM_PLL1_400M_CLK} 159 }, 160 {PCIE1_AUX_CLK_ROOT, IP_CLOCK_SLICE, 8, 161 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_50M_CLK, 162 SYSTEM_PLL3_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, 163 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_200M_CLK} 164 }, 165 {DC_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 9, 166 {OSC_25M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, 167 AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, 168 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} 169 }, 170 {LCDIF_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 10, 171 {OSC_25M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, 172 AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, 173 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} 174 }, 175 {SAI1_CLK_ROOT, IP_CLOCK_SLICE, 11, 176 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, 177 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, 178 OSC_27M_CLK, EXT_CLK_1, EXT_CLK_2} 179 }, 180 {SAI2_CLK_ROOT, IP_CLOCK_SLICE, 12, 181 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, 182 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, 183 OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3} 184 }, 185 {SAI3_CLK_ROOT, IP_CLOCK_SLICE, 13, 186 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, 187 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, 188 OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4} 189 }, 190 {SAI4_CLK_ROOT, IP_CLOCK_SLICE, 14, 191 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, 192 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, 193 OSC_27M_CLK, EXT_CLK_1, EXT_CLK_2} 194 }, 195 {SAI5_CLK_ROOT, IP_CLOCK_SLICE, 15, 196 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, 197 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, 198 OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3} 199 }, 200 {SAI6_CLK_ROOT, IP_CLOCK_SLICE, 16, 201 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, 202 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, 203 OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4} 204 }, 205 {SPDIF1_CLK_ROOT, IP_CLOCK_SLICE, 17, 206 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, 207 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, 208 OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3} 209 }, 210 {SPDIF2_CLK_ROOT, IP_CLOCK_SLICE, 18, 211 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, 212 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, 213 OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4} 214 }, 215 {ENET_REF_CLK_ROOT, IP_CLOCK_SLICE, 19, 216 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_50M_CLK, 217 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, 218 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, EXT_CLK_4} 219 }, 220 {ENET_TIMER_CLK_ROOT, IP_CLOCK_SLICE, 20, 221 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, AUDIO_PLL1_CLK, 222 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4, 223 VIDEO_PLL_CLK} 224 }, 225 {ENET_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 21, 226 {OSC_25M_CLK, SYSTEM_PLL2_50M_CLK, SYSTEM_PLL2_125M_CLK, 227 SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_500M_CLK, 228 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} 229 }, 230 {NAND_CLK_ROOT, IP_CLOCK_SLICE, 22, 231 {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, AUDIO_PLL1_CLK, 232 SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK, 233 SYSTEM_PLL2_250M_CLK, VIDEO_PLL_CLK} 234 }, 235 {QSPI_CLK_ROOT, IP_CLOCK_SLICE, 23, 236 {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, 237 SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK, 238 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK} 239 }, 240 {USDHC1_CLK_ROOT, IP_CLOCK_SLICE, 24, 241 {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, 242 SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK, 243 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK} 244 }, 245 {USDHC2_CLK_ROOT, IP_CLOCK_SLICE, 25, 246 {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, 247 SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK, 248 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK} 249 }, 250 {I2C1_CLK_ROOT, IP_CLOCK_SLICE, 26, 251 {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, 252 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, 253 AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} 254 }, 255 {I2C2_CLK_ROOT, IP_CLOCK_SLICE, 27, 256 {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, 257 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, 258 AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} 259 }, 260 {I2C3_CLK_ROOT, IP_CLOCK_SLICE, 28, 261 {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, 262 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, 263 AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} 264 }, 265 {I2C4_CLK_ROOT, IP_CLOCK_SLICE, 29, 266 {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, 267 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, 268 AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} 269 }, 270 {UART1_CLK_ROOT, IP_CLOCK_SLICE, 30, 271 {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, 272 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, 273 EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} 274 }, 275 {UART2_CLK_ROOT, IP_CLOCK_SLICE, 31, 276 {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, 277 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, 278 EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} 279 }, 280 {UART3_CLK_ROOT, IP_CLOCK_SLICE, 32, 281 {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, 282 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, 283 EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} 284 }, 285 {UART4_CLK_ROOT, IP_CLOCK_SLICE, 33, 286 {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, 287 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, 288 EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} 289 }, 290 {USB_CORE_REF_CLK_ROOT, IP_CLOCK_SLICE, 34, 291 {OSC_25M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK, 292 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, 293 EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} 294 }, 295 {USB_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 35, 296 {OSC_25M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK, 297 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, 298 EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} 299 }, 300 {GIC_CLK_ROOT, IP_CLOCK_SLICE, 36, 301 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, 302 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_800M_CLK, 303 EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} 304 }, 305 {ECSPI1_CLK_ROOT, IP_CLOCK_SLICE, 37, 306 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, 307 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, 308 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} 309 }, 310 {ECSPI2_CLK_ROOT, IP_CLOCK_SLICE, 38, 311 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, 312 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, 313 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} 314 }, 315 {PWM1_CLK_ROOT, IP_CLOCK_SLICE, 39, 316 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, 317 SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, 318 SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} 319 }, 320 {PWM2_CLK_ROOT, IP_CLOCK_SLICE, 40, 321 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, 322 SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, 323 SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} 324 }, 325 {PWM3_CLK_ROOT, IP_CLOCK_SLICE, 41, 326 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, 327 SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, 328 SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} 329 }, 330 {PWM4_CLK_ROOT, IP_CLOCK_SLICE, 42, 331 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, 332 SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, 333 SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} 334 }, 335 {GPT1_CLK_ROOT, IP_CLOCK_SLICE, 43, 336 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, 337 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, 338 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1} 339 }, 340 {GPT2_CLK_ROOT, IP_CLOCK_SLICE, 44, 341 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, 342 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, 343 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2} 344 }, 345 {GPT3_CLK_ROOT, IP_CLOCK_SLICE, 45, 346 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, 347 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, 348 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3} 349 }, 350 {GPT4_CLK_ROOT, IP_CLOCK_SLICE, 46, 351 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, 352 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, 353 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1} 354 }, 355 {GPT5_CLK_ROOT, IP_CLOCK_SLICE, 47, 356 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, 357 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, 358 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2} 359 }, 360 {GPT6_CLK_ROOT, IP_CLOCK_SLICE, 48, 361 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, 362 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, 363 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3} 364 }, 365 {TRACE_CLK_ROOT, IP_CLOCK_SLICE, 49, 366 {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK, 367 VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK, 368 SYSTEM_PLL3_CLK, EXT_CLK_1, EXT_CLK_3} 369 }, 370 {WDOG_CLK_ROOT, IP_CLOCK_SLICE, 50, 371 {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK, 372 VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK, 373 SYSTEM_PLL3_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_166M_CLK} 374 }, 375 {WRCLK_CLK_ROOT, IP_CLOCK_SLICE, 51, 376 {OSC_25M_CLK, SYSTEM_PLL1_40M_CLK, VPU_PLL_CLK, 377 SYSTEM_PLL3_CLK, SYSTEM_PLL2_200M_CLK, 378 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_100M_CLK} 379 }, 380 {IPP_DO_CLKO1, IP_CLOCK_SLICE, 52, 381 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, OSC_27M_CLK, 382 SYSTEM_PLL1_200M_CLK, AUDIO_PLL2_CLK, 383 SYSTEM_PLL2_500M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_80M_CLK} 384 }, 385 {IPP_DO_CLKO2, IP_CLOCK_SLICE, 53, 386 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_400M_CLK, 387 SYSTEM_PLL2_166M_CLK, SYSTEM_PLL3_CLK, 388 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, OSC_32K_CLK} 389 }, 390 {MIPI_DSI_CORE_CLK_ROOT, IP_CLOCK_SLICE, 54, 391 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, 392 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 393 SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} 394 }, 395 {MIPI_DSI_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 55, 396 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK, 397 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 398 EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} 399 }, 400 {MIPI_DSI_DBI_CLK_ROOT, IP_CLOCK_SLICE, 56, 401 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_100M_CLK, 402 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 403 SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} 404 }, 405 {OLD_MIPI_DSI_ESC_CLK_ROOT, IP_CLOCK_SLICE, 57, 406 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, 407 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 408 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} 409 }, 410 {MIPI_CSI1_CORE_CLK_ROOT, IP_CLOCK_SLICE, 58, 411 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, 412 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 413 SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} 414 }, 415 {MIPI_CSI1_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 59, 416 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK, 417 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 418 EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} 419 }, 420 {MIPI_CSI1_ESC_CLK_ROOT, IP_CLOCK_SLICE, 60, 421 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, 422 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 423 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} 424 }, 425 {MIPI_CSI2_CORE_CLK_ROOT, IP_CLOCK_SLICE, 61, 426 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, 427 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 428 SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} 429 }, 430 {MIPI_CSI2_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 62, 431 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK, 432 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 433 EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} 434 }, 435 {MIPI_CSI2_ESC_CLK_ROOT, IP_CLOCK_SLICE, 63, 436 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, 437 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 438 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} 439 }, 440 {PCIE2_CTRL_CLK_ROOT, IP_CLOCK_SLICE, 64, 441 {OSC_25M_CLK, SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, 442 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, 443 SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL3_CLK} 444 }, 445 {PCIE2_PHY_CLK_ROOT, IP_CLOCK_SLICE, 65, 446 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_500M_CLK, 447 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, 448 EXT_CLK_4, SYSTEM_PLL1_400M_CLK} 449 }, 450 {PCIE2_AUX_CLK_ROOT, IP_CLOCK_SLICE, 66, 451 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_50M_CLK, 452 SYSTEM_PLL3_CLK, SYSTEM_PLL2_100M_CLK, 453 SYSTEM_PLL1_80M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_200M_CLK} 454 }, 455 {ECSPI3_CLK_ROOT, IP_CLOCK_SLICE, 67, 456 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, 457 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, 458 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} 459 }, 460 {OLD_MIPI_DSI_ESC_RX_ROOT, IP_CLOCK_SLICE, 68, 461 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, 462 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, 463 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK}, 464 }, 465 {DISPLAY_HDMI_CLK_ROOT, IP_CLOCK_SLICE, 69, 466 {OSC_25M_CLK, SYSTEM_PLL1_200M_CLK, SYSTEM_PLL2_200M_CLK, 467 VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, 468 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} 469 }, 470 {DRAM_SEL_CFG, DRAM_SEL_CLOCK_SLICE, 0, 471 {DRAM_PLL1_CLK} 472 }, 473 {CORE_SEL_CFG, CORE_SEL_CLOCK_SLICE, 0, 474 {DRAM_PLL1_CLK} 475 }, 476 }; 477 478 static int select(enum clk_root_index clock_id) 479 { 480 int i, size; 481 struct clk_root_map *p = root_array; 482 483 size = ARRAY_SIZE(root_array); 484 485 for (i = 0; i < size; i++, p++) { 486 if (clock_id == p->entry) 487 return i; 488 } 489 490 return -EINVAL; 491 } 492 493 static void __iomem *get_clk_root_target(enum clk_slice_type slice_type, 494 u32 slice_index) 495 { 496 void __iomem *clk_root_target; 497 498 switch (slice_type) { 499 case CORE_CLOCK_SLICE: 500 clk_root_target = 501 (void __iomem *)&ccm_reg->core_root[slice_index]; 502 break; 503 case BUS_CLOCK_SLICE: 504 clk_root_target = 505 (void __iomem *)&ccm_reg->bus_root[slice_index]; 506 break; 507 case IP_CLOCK_SLICE: 508 clk_root_target = 509 (void __iomem *)&ccm_reg->ip_root[slice_index]; 510 break; 511 case AHB_CLOCK_SLICE: 512 clk_root_target = 513 (void __iomem *)&ccm_reg->ahb_ipg_root[slice_index * 2]; 514 break; 515 case IPG_CLOCK_SLICE: 516 clk_root_target = 517 (void __iomem *)&ccm_reg->ahb_ipg_root[slice_index * 2 + 1]; 518 break; 519 case CORE_SEL_CLOCK_SLICE: 520 clk_root_target = (void __iomem *)&ccm_reg->core_sel; 521 break; 522 case DRAM_SEL_CLOCK_SLICE: 523 clk_root_target = (void __iomem *)&ccm_reg->dram_sel; 524 break; 525 default: 526 return NULL; 527 } 528 529 return clk_root_target; 530 } 531 532 int clock_get_target_val(enum clk_root_index clock_id, u32 *val) 533 { 534 int root_entry; 535 struct clk_root_map *p; 536 void __iomem *clk_root_target; 537 538 if (clock_id >= CLK_ROOT_MAX) 539 return -EINVAL; 540 541 root_entry = select(clock_id); 542 if (root_entry < 0) 543 return -EINVAL; 544 545 p = &root_array[root_entry]; 546 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); 547 if (!clk_root_target) 548 return -EINVAL; 549 550 *val = readl(clk_root_target); 551 552 return 0; 553 } 554 555 int clock_set_target_val(enum clk_root_index clock_id, u32 val) 556 { 557 int root_entry; 558 struct clk_root_map *p; 559 void __iomem *clk_root_target; 560 561 if (clock_id >= CLK_ROOT_MAX) 562 return -EINVAL; 563 564 root_entry = select(clock_id); 565 if (root_entry < 0) 566 return -EINVAL; 567 568 p = &root_array[root_entry]; 569 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); 570 if (!clk_root_target) 571 return -EINVAL; 572 573 writel(val, clk_root_target); 574 575 return 0; 576 } 577 578 int clock_root_enabled(enum clk_root_index clock_id) 579 { 580 void __iomem *clk_root_target; 581 u32 slice_index, slice_type; 582 u32 val; 583 int root_entry; 584 585 if (clock_id >= CLK_ROOT_MAX) 586 return -EINVAL; 587 588 root_entry = select(clock_id); 589 if (root_entry < 0) 590 return -EINVAL; 591 592 slice_type = root_array[root_entry].slice_type; 593 slice_index = root_array[root_entry].slice_index; 594 595 if ((slice_type == IPG_CLOCK_SLICE) || 596 (slice_type == DRAM_SEL_CLOCK_SLICE) || 597 (slice_type == CORE_SEL_CLOCK_SLICE)) { 598 /* 599 * Not supported, from CCM doc 600 * TODO 601 */ 602 return 0; 603 } 604 605 clk_root_target = get_clk_root_target(slice_type, slice_index); 606 if (!clk_root_target) 607 return -EINVAL; 608 609 val = readl(clk_root_target); 610 611 return (val & CLK_ROOT_ON) ? 1 : 0; 612 } 613 614 /* CCGR CLK gate operation */ 615 int clock_enable(enum clk_ccgr_index index, bool enable) 616 { 617 void __iomem *ccgr; 618 619 if (index >= CCGR_MAX) 620 return -EINVAL; 621 622 if (enable) 623 ccgr = (void __iomem *)&ccm_reg->ccgr_array[index].ccgr_set; 624 else 625 ccgr = (void __iomem *)&ccm_reg->ccgr_array[index].ccgr_clr; 626 627 writel(CCGR_CLK_ON_MASK, ccgr); 628 629 return 0; 630 } 631 632 int clock_get_prediv(enum clk_root_index clock_id, enum root_pre_div *pre_div) 633 { 634 u32 val; 635 int root_entry; 636 struct clk_root_map *p; 637 void __iomem *clk_root_target; 638 639 if (clock_id >= CLK_ROOT_MAX) 640 return -EINVAL; 641 642 root_entry = select(clock_id); 643 if (root_entry < 0) 644 return -EINVAL; 645 646 p = &root_array[root_entry]; 647 648 if ((p->slice_type == CORE_CLOCK_SLICE) || 649 (p->slice_type == IPG_CLOCK_SLICE) || 650 (p->slice_type == CORE_SEL_CLOCK_SLICE) || 651 (p->slice_type == DRAM_SEL_CLOCK_SLICE)) { 652 *pre_div = 0; 653 return 0; 654 } 655 656 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); 657 if (!clk_root_target) 658 return -EINVAL; 659 660 val = readl(clk_root_target); 661 val &= CLK_ROOT_PRE_DIV_MASK; 662 val >>= CLK_ROOT_PRE_DIV_SHIFT; 663 664 *pre_div = val; 665 666 return 0; 667 } 668 669 int clock_get_postdiv(enum clk_root_index clock_id, 670 enum root_post_div *post_div) 671 { 672 u32 val, mask; 673 int root_entry; 674 struct clk_root_map *p; 675 void __iomem *clk_root_target; 676 677 if (clock_id >= CLK_ROOT_MAX) 678 return -EINVAL; 679 680 root_entry = select(clock_id); 681 if (root_entry < 0) 682 return -EINVAL; 683 684 p = &root_array[root_entry]; 685 686 if ((p->slice_type == CORE_SEL_CLOCK_SLICE) || 687 (p->slice_type == DRAM_SEL_CLOCK_SLICE)) { 688 *post_div = 0; 689 return 0; 690 } 691 692 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); 693 if (!clk_root_target) 694 return -EINVAL; 695 696 if (p->slice_type == IPG_CLOCK_SLICE) 697 mask = CLK_ROOT_IPG_POST_DIV_MASK; 698 else if (p->slice_type == CORE_CLOCK_SLICE) 699 mask = CLK_ROOT_CORE_POST_DIV_MASK; 700 else 701 mask = CLK_ROOT_POST_DIV_MASK; 702 703 val = readl(clk_root_target); 704 val &= mask; 705 val >>= CLK_ROOT_POST_DIV_SHIFT; 706 707 *post_div = val; 708 709 return 0; 710 } 711 712 int clock_get_src(enum clk_root_index clock_id, enum clk_root_src *p_clock_src) 713 { 714 u32 val; 715 int root_entry; 716 struct clk_root_map *p; 717 void __iomem *clk_root_target; 718 719 if (clock_id >= CLK_ROOT_MAX) 720 return -EINVAL; 721 722 root_entry = select(clock_id); 723 if (root_entry < 0) 724 return -EINVAL; 725 726 p = &root_array[root_entry]; 727 728 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); 729 if (!clk_root_target) 730 return -EINVAL; 731 732 val = readl(clk_root_target); 733 val &= CLK_ROOT_SRC_MUX_MASK; 734 val >>= CLK_ROOT_SRC_MUX_SHIFT; 735 736 *p_clock_src = p->src_mux[val]; 737 738 return 0; 739 } 740