1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2015 Freescale Semiconductor, Inc. 4 * 5 * Author: 6 * Peng Fan <Peng.Fan (at) freescale.com> 7 */ 8 9 #include <common.h> 10 #include <div64.h> 11 #include <asm/io.h> 12 #include <linux/errno.h> 13 #include <asm/arch/imx-regs.h> 14 #include <asm/arch/crm_regs.h> 15 #include <asm/arch/clock.h> 16 #include <asm/arch/sys_proto.h> 17 18 struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 19 20 static struct clk_root_map root_array[] = { 21 {ARM_A7_CLK_ROOT, CCM_CORE_CHANNEL, 22 {OSC_24M_CLK, PLL_ARM_MAIN_800M_CLK, PLL_ENET_MAIN_500M_CLK, 23 PLL_DRAM_MAIN_1066M_CLK, PLL_SYS_MAIN_480M_CLK, 24 PLL_SYS_PFD0_392M_CLK, PLL_AUDIO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} 25 }, 26 {ARM_M4_CLK_ROOT, CCM_BUS_CHANNEL, 27 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_250M_CLK, 28 PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, 29 PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} 30 }, 31 {ARM_M0_CLK_ROOT, CCM_BUS_CHANNEL, 32 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_125M_CLK, 33 PLL_SYS_PFD2_135M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, 34 PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} 35 }, 36 {MAIN_AXI_CLK_ROOT, CCM_BUS_CHANNEL, 37 {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, 38 PLL_ENET_MAIN_250M_CLK, PLL_SYS_PFD5_CLK, PLL_AUDIO_MAIN_CLK, 39 PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD7_CLK} 40 }, 41 {DISP_AXI_CLK_ROOT, CCM_BUS_CHANNEL, 42 {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, 43 PLL_ENET_MAIN_250M_CLK, PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK, 44 PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} 45 }, 46 {ENET_AXI_CLK_ROOT, CCM_IP_CHANNEL, 47 {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, 48 PLL_ENET_MAIN_250M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_AUDIO_MAIN_CLK, 49 PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK} 50 }, 51 {NAND_USDHC_BUS_CLK_ROOT, CCM_IP_CHANNEL, 52 {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, 53 PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_PFD6_CLK, 54 PLL_ENET_MAIN_250M_CLK, PLL_AUDIO_MAIN_CLK} 55 }, 56 {AHB_CLK_ROOT, CCM_AHB_CHANNEL, 57 {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, 58 PLL_SYS_PFD0_392M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, 59 PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} 60 }, 61 {DRAM_PHYM_CLK_ROOT, CCM_DRAM_PHYM_CHANNEL, 62 {PLL_DRAM_MAIN_1066M_CLK, DRAM_PHYM_ALT_CLK_ROOT} 63 }, 64 {DRAM_CLK_ROOT, CCM_DRAM_CHANNEL, 65 {PLL_DRAM_MAIN_1066M_CLK, DRAM_ALT_CLK_ROOT} 66 }, 67 {DRAM_PHYM_ALT_CLK_ROOT, CCM_IP_CHANNEL, 68 {OSC_24M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_SYS_MAIN_480M_CLK, 69 PLL_ENET_MAIN_500M_CLK, PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD7_CLK, 70 PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} 71 }, 72 {DRAM_ALT_CLK_ROOT, CCM_IP_CHANNEL, 73 {OSC_24M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_SYS_MAIN_480M_CLK, 74 PLL_ENET_MAIN_500M_CLK, PLL_ENET_MAIN_250M_CLK, 75 PLL_SYS_PFD0_392M_CLK, PLL_AUDIO_MAIN_CLK, PLL_SYS_PFD2_270M_CLK} 76 }, 77 {USB_HSIC_CLK_ROOT, CCM_IP_CHANNEL, 78 {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_USB_MAIN_480M_CLK, 79 PLL_SYS_PFD3_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD5_CLK, 80 PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} 81 }, 82 {PCIE_CTRL_CLK_ROOT, CCM_IP_CHANNEL, 83 {OSC_24M_CLK, PLL_ENET_MAIN_250M_CLK, PLL_SYS_MAIN_240M_CLK, 84 PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, 85 PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_SYS_PFD6_CLK} 86 }, 87 {PCIE_PHY_CLK_ROOT, CCM_IP_CHANNEL, 88 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_ENET_MAIN_500M_CLK, 89 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, 90 EXT_CLK_4, PLL_SYS_PFD0_392M_CLK} 91 }, 92 {EPDC_PIXEL_CLK_ROOT, CCM_IP_CHANNEL, 93 {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, 94 PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD5_CLK, PLL_SYS_PFD6_CLK, 95 PLL_SYS_PFD7_CLK, PLL_VIDEO_MAIN_CLK} 96 }, 97 {LCDIF_PIXEL_CLK_ROOT, CCM_IP_CHANNEL, 98 {OSC_24M_CLK, PLL_SYS_PFD5_CLK, PLL_DRAM_MAIN_533M_CLK, 99 EXT_CLK_3, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, 100 PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} 101 }, 102 {MIPI_DSI_EXTSER_CLK_ROOT, CCM_IP_CHANNEL, 103 {OSC_24M_CLK, PLL_SYS_PFD5_CLK, PLL_SYS_PFD3_CLK, 104 PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD0_196M_CLK, PLL_DRAM_MAIN_533M_CLK, 105 PLL_VIDEO_MAIN_CLK, PLL_AUDIO_MAIN_CLK} 106 }, 107 {MIPI_CSI_WARP_CLK_ROOT, CCM_IP_CHANNEL, 108 {OSC_24M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD3_CLK, 109 PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD0_196M_CLK, PLL_DRAM_MAIN_533M_CLK, 110 PLL_VIDEO_MAIN_CLK, PLL_AUDIO_MAIN_CLK} 111 }, 112 {MIPI_DPHY_REF_CLK_ROOT, CCM_IP_CHANNEL, 113 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, 114 PLL_SYS_PFD5_CLK, REF_1M_CLK, EXT_CLK_2, 115 PLL_VIDEO_MAIN_CLK, EXT_CLK_3} 116 }, 117 {SAI1_CLK_ROOT, CCM_IP_CHANNEL, 118 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, 119 PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, 120 PLL_ENET_MAIN_125M_CLK, EXT_CLK_2} 121 }, 122 {SAI2_CLK_ROOT, CCM_IP_CHANNEL, 123 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, 124 PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, 125 PLL_ENET_MAIN_125M_CLK, EXT_CLK_2} 126 }, 127 {SAI3_CLK_ROOT, CCM_IP_CHANNEL, 128 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, 129 PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, 130 PLL_ENET_MAIN_125M_CLK, EXT_CLK_3} 131 }, 132 {SPDIF_CLK_ROOT, CCM_IP_CHANNEL, 133 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, 134 PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, 135 PLL_ENET_MAIN_125M_CLK, EXT_CLK_3} 136 }, 137 {ENET1_REF_CLK_ROOT, CCM_IP_CHANNEL, 138 {OSC_24M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_ENET_MAIN_50M_CLK, 139 PLL_ENET_MAIN_25M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_AUDIO_MAIN_CLK, 140 PLL_VIDEO_MAIN_CLK, EXT_CLK_4} 141 }, 142 {ENET1_TIME_CLK_ROOT, CCM_IP_CHANNEL, 143 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_AUDIO_MAIN_CLK, 144 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, 145 EXT_CLK_4, PLL_VIDEO_MAIN_CLK} 146 }, 147 {ENET2_REF_CLK_ROOT, CCM_IP_CHANNEL, 148 {OSC_24M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_ENET_MAIN_50M_CLK, 149 PLL_ENET_MAIN_25M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_AUDIO_MAIN_CLK, 150 PLL_VIDEO_MAIN_CLK, EXT_CLK_4} 151 }, 152 {ENET2_TIME_CLK_ROOT, CCM_IP_CHANNEL, 153 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_AUDIO_MAIN_CLK, 154 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, 155 EXT_CLK_4, PLL_VIDEO_MAIN_CLK} 156 }, 157 {ENET_PHY_REF_CLK_ROOT, CCM_IP_CHANNEL, 158 {OSC_24M_CLK, PLL_ENET_MAIN_25M_CLK, PLL_ENET_MAIN_50M_CLK, 159 PLL_ENET_MAIN_125M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, 160 PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD3_CLK} 161 }, 162 {EIM_CLK_ROOT, CCM_IP_CHANNEL, 163 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, 164 PLL_DRAM_MAIN_533M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_SYS_PFD3_CLK, 165 PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK} 166 }, 167 {NAND_CLK_ROOT, CCM_IP_CHANNEL, 168 {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_DRAM_MAIN_533M_CLK, 169 PLL_SYS_PFD0_392M_CLK, PLL_SYS_PFD3_CLK, PLL_ENET_MAIN_500M_CLK, 170 PLL_ENET_MAIN_250M_CLK, PLL_VIDEO_MAIN_CLK} 171 }, 172 {QSPI_CLK_ROOT, CCM_IP_CHANNEL, 173 {OSC_24M_CLK, PLL_SYS_PFD4_CLK, PLL_DRAM_MAIN_533M_CLK, 174 PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD3_CLK, PLL_SYS_PFD2_270M_CLK, 175 PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} 176 }, 177 {USDHC1_CLK_ROOT, CCM_IP_CHANNEL, 178 {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, 179 PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, 180 PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} 181 }, 182 {USDHC2_CLK_ROOT, CCM_IP_CHANNEL, 183 {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, 184 PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, 185 PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} 186 }, 187 {USDHC3_CLK_ROOT, CCM_IP_CHANNEL, 188 {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, 189 PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, 190 PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} 191 }, 192 {CAN1_CLK_ROOT, CCM_IP_CHANNEL, 193 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, 194 PLL_SYS_MAIN_480M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_USB_MAIN_480M_CLK, 195 EXT_CLK_1, EXT_CLK_4} 196 }, 197 {CAN2_CLK_ROOT, CCM_IP_CHANNEL, 198 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, 199 PLL_SYS_MAIN_480M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_USB_MAIN_480M_CLK, 200 EXT_CLK_1, EXT_CLK_3} 201 }, 202 {I2C1_CLK_ROOT, CCM_IP_CHANNEL, 203 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, 204 PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, 205 PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} 206 }, 207 {I2C2_CLK_ROOT, CCM_IP_CHANNEL, 208 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, 209 PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, 210 PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} 211 }, 212 {I2C3_CLK_ROOT, CCM_IP_CHANNEL, 213 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, 214 PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, 215 PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} 216 }, 217 {I2C4_CLK_ROOT, CCM_IP_CHANNEL, 218 {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, 219 PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, 220 PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} 221 }, 222 {UART1_CLK_ROOT, CCM_IP_CHANNEL, 223 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 224 PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, 225 EXT_CLK_4, PLL_USB_MAIN_480M_CLK} 226 }, 227 {UART2_CLK_ROOT, CCM_IP_CHANNEL, 228 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 229 PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, 230 EXT_CLK_3, PLL_USB_MAIN_480M_CLK} 231 }, 232 {UART3_CLK_ROOT, CCM_IP_CHANNEL, 233 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 234 PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, 235 EXT_CLK_4, PLL_USB_MAIN_480M_CLK} 236 }, 237 {UART4_CLK_ROOT, CCM_IP_CHANNEL, 238 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 239 PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, 240 EXT_CLK_3, PLL_USB_MAIN_480M_CLK} 241 }, 242 {UART5_CLK_ROOT, CCM_IP_CHANNEL, 243 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 244 PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, 245 EXT_CLK_4, PLL_USB_MAIN_480M_CLK} 246 }, 247 {UART6_CLK_ROOT, CCM_IP_CHANNEL, 248 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 249 PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, 250 EXT_CLK_3, PLL_USB_MAIN_480M_CLK} 251 }, 252 {UART7_CLK_ROOT, CCM_IP_CHANNEL, 253 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 254 PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, 255 EXT_CLK_4, PLL_USB_MAIN_480M_CLK} 256 }, 257 {ECSPI1_CLK_ROOT, CCM_IP_CHANNEL, 258 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 259 PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, 260 PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} 261 }, 262 {ECSPI2_CLK_ROOT, CCM_IP_CHANNEL, 263 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 264 PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, 265 PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} 266 }, 267 {ECSPI3_CLK_ROOT, CCM_IP_CHANNEL, 268 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 269 PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, 270 PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} 271 }, 272 {ECSPI4_CLK_ROOT, CCM_IP_CHANNEL, 273 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, 274 PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, 275 PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} 276 }, 277 {PWM1_CLK_ROOT, CCM_IP_CHANNEL, 278 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, 279 PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_1, 280 REF_1M_CLK, PLL_VIDEO_MAIN_CLK} 281 }, 282 {PWM2_CLK_ROOT, CCM_IP_CHANNEL, 283 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, 284 PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_1, 285 REF_1M_CLK, PLL_VIDEO_MAIN_CLK} 286 }, 287 {PWM3_CLK_ROOT, CCM_IP_CHANNEL, 288 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, 289 PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_2, 290 REF_1M_CLK, PLL_VIDEO_MAIN_CLK} 291 }, 292 {PWM4_CLK_ROOT, CCM_IP_CHANNEL, 293 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, 294 PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_2, 295 REF_1M_CLK, PLL_VIDEO_MAIN_CLK} 296 }, 297 {FLEXTIMER1_CLK_ROOT, CCM_IP_CHANNEL, 298 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, 299 PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_3, 300 REF_1M_CLK, PLL_VIDEO_MAIN_CLK} 301 }, 302 {FLEXTIMER2_CLK_ROOT, CCM_IP_CHANNEL, 303 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, 304 PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_3, 305 REF_1M_CLK, PLL_VIDEO_MAIN_CLK} 306 }, 307 {SIM1_CLK_ROOT, CCM_IP_CHANNEL, 308 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, 309 PLL_DRAM_MAIN_533M_CLK, PLL_USB_MAIN_480M_CLK, PLL_AUDIO_MAIN_CLK, 310 PLL_ENET_MAIN_125M_CLK, PLL_SYS_PFD7_CLK} 311 }, 312 {SIM2_CLK_ROOT, CCM_IP_CHANNEL, 313 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, 314 PLL_DRAM_MAIN_533M_CLK, PLL_USB_MAIN_480M_CLK, PLL_VIDEO_MAIN_CLK, 315 PLL_ENET_MAIN_125M_CLK, PLL_SYS_PFD7_CLK} 316 }, 317 {GPT1_CLK_ROOT, CCM_IP_CHANNEL, 318 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, 319 PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, 320 PLL_AUDIO_MAIN_CLK, EXT_CLK_1} 321 }, 322 {GPT2_CLK_ROOT, CCM_IP_CHANNEL, 323 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, 324 PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, 325 PLL_AUDIO_MAIN_CLK, EXT_CLK_2} 326 }, 327 {GPT3_CLK_ROOT, CCM_IP_CHANNEL, 328 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, 329 PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, 330 PLL_AUDIO_MAIN_CLK, EXT_CLK_3} 331 }, 332 {GPT4_CLK_ROOT, CCM_IP_CHANNEL, 333 {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, 334 PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, 335 PLL_AUDIO_MAIN_CLK, EXT_CLK_4} 336 }, 337 {TRACE_CLK_ROOT, CCM_IP_CHANNEL, 338 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, 339 PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, 340 EXT_CLK_1, EXT_CLK_3} 341 }, 342 {WDOG_CLK_ROOT, CCM_IP_CHANNEL, 343 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, 344 PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, 345 REF_1M_CLK, PLL_SYS_PFD1_166M_CLK} 346 }, 347 {CSI_MCLK_CLK_ROOT, CCM_IP_CHANNEL, 348 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, 349 PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_AUDIO_MAIN_CLK, 350 PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} 351 }, 352 {AUDIO_MCLK_CLK_ROOT, CCM_IP_CHANNEL, 353 {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, 354 PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_AUDIO_MAIN_CLK, 355 PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} 356 }, 357 {WRCLK_CLK_ROOT, CCM_IP_CHANNEL, 358 {OSC_24M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_DRAM_MAIN_533M_CLK, 359 PLL_USB_MAIN_480M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD2_270M_CLK, 360 PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD7_CLK} 361 }, 362 {IPP_DO_CLKO1, CCM_IP_CHANNEL, 363 {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_MAIN_240M_CLK, 364 PLL_SYS_PFD0_196M_CLK, PLL_SYS_PFD3_CLK, PLL_ENET_MAIN_500M_CLK, 365 PLL_DRAM_MAIN_533M_CLK, REF_1M_CLK} 366 }, 367 {IPP_DO_CLKO2, CCM_IP_CHANNEL, 368 {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD0_392M_CLK, 369 PLL_SYS_PFD1_166M_CLK, PLL_SYS_PFD4_CLK, PLL_AUDIO_MAIN_CLK, 370 PLL_VIDEO_MAIN_CLK, OSC_32K_CLK} 371 }, 372 }; 373 374 /* select which entry of root_array */ 375 static int select(enum clk_root_index clock_id) 376 { 377 int i, size; 378 struct clk_root_map *p = root_array; 379 380 size = ARRAY_SIZE(root_array); 381 382 for (i = 0; i < size; i++, p++) { 383 if (clock_id == p->entry) 384 return i; 385 } 386 387 return -EINVAL; 388 } 389 390 static int src_supported(int entry, enum clk_root_src clock_src) 391 { 392 int i, size; 393 struct clk_root_map *p = &root_array[entry]; 394 395 if ((p->type == CCM_DRAM_PHYM_CHANNEL) || (p->type == CCM_DRAM_CHANNEL)) 396 size = 2; 397 else 398 size = 8; 399 400 for (i = 0; i < size; i++) { 401 if (p->src_mux[i] == clock_src) 402 return i; 403 } 404 405 return -EINVAL; 406 } 407 408 /* Set src for clock root slice. */ 409 int clock_set_src(enum clk_root_index clock_id, enum clk_root_src clock_src) 410 { 411 int root_entry, src_entry; 412 u32 reg; 413 414 if (clock_id >= CLK_ROOT_MAX) 415 return -EINVAL; 416 417 root_entry = select(clock_id); 418 if (root_entry < 0) 419 return -EINVAL; 420 421 src_entry = src_supported(root_entry, clock_src); 422 if (src_entry < 0) 423 return -EINVAL; 424 425 reg = __raw_readl(&imx_ccm->root[clock_id].target_root); 426 reg &= ~CLK_ROOT_MUX_MASK; 427 reg |= src_entry << CLK_ROOT_MUX_SHIFT; 428 __raw_writel(reg, &imx_ccm->root[clock_id].target_root); 429 430 return 0; 431 } 432 433 /* Get src of a clock root slice. */ 434 int clock_get_src(enum clk_root_index clock_id, enum clk_root_src *p_clock_src) 435 { 436 u32 val; 437 int root_entry; 438 struct clk_root_map *p; 439 440 if (clock_id >= CLK_ROOT_MAX) 441 return -EINVAL; 442 443 val = __raw_readl(&imx_ccm->root[clock_id].target_root); 444 val &= CLK_ROOT_MUX_MASK; 445 val >>= CLK_ROOT_MUX_SHIFT; 446 447 root_entry = select(clock_id); 448 if (root_entry < 0) 449 return -EINVAL; 450 451 p = &root_array[root_entry]; 452 *p_clock_src = p->src_mux[val]; 453 454 return 0; 455 } 456 457 int clock_set_prediv(enum clk_root_index clock_id, enum root_pre_div pre_div) 458 { 459 int root_entry; 460 struct clk_root_map *p; 461 u32 reg; 462 463 if (clock_id >= CLK_ROOT_MAX) 464 return -EINVAL; 465 466 root_entry = select(clock_id); 467 if (root_entry < 0) 468 return -EINVAL; 469 470 p = &root_array[root_entry]; 471 472 if ((p->type == CCM_CORE_CHANNEL) || 473 (p->type == CCM_DRAM_PHYM_CHANNEL) || 474 (p->type == CCM_DRAM_CHANNEL)) { 475 if (pre_div != CLK_ROOT_PRE_DIV1) { 476 printf("Error pre div!\n"); 477 return -EINVAL; 478 } 479 } 480 481 reg = __raw_readl(&imx_ccm->root[clock_id].target_root); 482 reg &= ~CLK_ROOT_PRE_DIV_MASK; 483 reg |= pre_div << CLK_ROOT_PRE_DIV_SHIFT; 484 __raw_writel(reg, &imx_ccm->root[clock_id].target_root); 485 486 return 0; 487 } 488 489 int clock_get_prediv(enum clk_root_index clock_id, enum root_pre_div *pre_div) 490 { 491 u32 val; 492 int root_entry; 493 struct clk_root_map *p; 494 495 if (clock_id >= CLK_ROOT_MAX) 496 return -EINVAL; 497 498 root_entry = select(clock_id); 499 if (root_entry < 0) 500 return -EINVAL; 501 502 p = &root_array[root_entry]; 503 504 if ((p->type == CCM_CORE_CHANNEL) || 505 (p->type == CCM_DRAM_PHYM_CHANNEL) || 506 (p->type == CCM_DRAM_CHANNEL)) { 507 *pre_div = 0; 508 return 0; 509 } 510 511 val = __raw_readl(&imx_ccm->root[clock_id].target_root); 512 val &= CLK_ROOT_PRE_DIV_MASK; 513 val >>= CLK_ROOT_PRE_DIV_SHIFT; 514 515 *pre_div = val; 516 517 return 0; 518 } 519 520 int clock_set_postdiv(enum clk_root_index clock_id, enum root_post_div div) 521 { 522 u32 reg; 523 524 if (clock_id >= CLK_ROOT_MAX) 525 return -EINVAL; 526 527 if (clock_id == DRAM_PHYM_CLK_ROOT) { 528 if (div != CLK_ROOT_POST_DIV1) { 529 printf("Error post div!\n"); 530 return -EINVAL; 531 } 532 } 533 534 /* Only 3 bit post div. */ 535 if ((clock_id == DRAM_CLK_ROOT) && (div > CLK_ROOT_POST_DIV7)) { 536 printf("Error post div!\n"); 537 return -EINVAL; 538 } 539 540 reg = __raw_readl(&imx_ccm->root[clock_id].target_root); 541 reg &= ~CLK_ROOT_POST_DIV_MASK; 542 reg |= div << CLK_ROOT_POST_DIV_SHIFT; 543 __raw_writel(reg, &imx_ccm->root[clock_id].target_root); 544 545 return 0; 546 } 547 548 int clock_get_postdiv(enum clk_root_index clock_id, enum root_post_div *div) 549 { 550 u32 val; 551 552 if (clock_id >= CLK_ROOT_MAX) 553 return -EINVAL; 554 555 if (clock_id == DRAM_PHYM_CLK_ROOT) { 556 *div = 0; 557 return 0; 558 } 559 560 val = __raw_readl(&imx_ccm->root[clock_id].target_root); 561 if (clock_id == DRAM_CLK_ROOT) 562 val &= DRAM_CLK_ROOT_POST_DIV_MASK; 563 else 564 val &= CLK_ROOT_POST_DIV_MASK; 565 val >>= CLK_ROOT_POST_DIV_SHIFT; 566 567 *div = val; 568 569 return 0; 570 } 571 572 int clock_set_autopostdiv(enum clk_root_index clock_id, enum root_auto_div div, 573 int auto_en) 574 { 575 u32 val; 576 int root_entry; 577 struct clk_root_map *p; 578 579 if (clock_id >= CLK_ROOT_MAX) 580 return -EINVAL; 581 582 root_entry = select(clock_id); 583 if (root_entry < 0) 584 return -EINVAL; 585 586 p = &root_array[root_entry]; 587 588 if ((p->type != CCM_BUS_CHANNEL) && (p->type != CCM_AHB_CHANNEL)) { 589 printf("Auto postdiv not supported.!\n"); 590 return -EINVAL; 591 } 592 593 /* 594 * Each time only one filed can be changed, no use target_root_set. 595 */ 596 val = __raw_readl(&imx_ccm->root[clock_id].target_root); 597 val &= ~CLK_ROOT_AUTO_DIV_MASK; 598 val |= (div << CLK_ROOT_AUTO_DIV_SHIFT); 599 600 if (auto_en) 601 val |= CLK_ROOT_AUTO_EN; 602 else 603 val &= ~CLK_ROOT_AUTO_EN; 604 605 __raw_writel(val, &imx_ccm->root[clock_id].target_root); 606 607 return 0; 608 } 609 610 int clock_get_autopostdiv(enum clk_root_index clock_id, enum root_auto_div *div, 611 int *auto_en) 612 { 613 u32 val; 614 int root_entry; 615 struct clk_root_map *p; 616 617 if (clock_id >= CLK_ROOT_MAX) 618 return -EINVAL; 619 620 root_entry = select(clock_id); 621 if (root_entry < 0) 622 return -EINVAL; 623 624 p = &root_array[root_entry]; 625 626 /* 627 * Only bus/ahb channel supports auto div. 628 * If unsupported, just set auto_en and div with 0. 629 */ 630 if ((p->type != CCM_BUS_CHANNEL) && (p->type != CCM_AHB_CHANNEL)) { 631 *auto_en = 0; 632 *div = 0; 633 return 0; 634 } 635 636 val = __raw_readl(&imx_ccm->root[clock_id].target_root); 637 if ((val & CLK_ROOT_AUTO_EN_MASK) == 0) 638 *auto_en = 0; 639 else 640 *auto_en = 1; 641 642 val &= CLK_ROOT_AUTO_DIV_MASK; 643 val >>= CLK_ROOT_AUTO_DIV_SHIFT; 644 645 *div = val; 646 647 return 0; 648 } 649 650 int clock_get_target_val(enum clk_root_index clock_id, u32 *val) 651 { 652 if (clock_id >= CLK_ROOT_MAX) 653 return -EINVAL; 654 655 *val = __raw_readl(&imx_ccm->root[clock_id].target_root); 656 657 return 0; 658 } 659 660 int clock_set_target_val(enum clk_root_index clock_id, u32 val) 661 { 662 if (clock_id >= CLK_ROOT_MAX) 663 return -EINVAL; 664 665 __raw_writel(val, &imx_ccm->root[clock_id].target_root); 666 667 return 0; 668 } 669 670 /* Auto_div and auto_en is ignored, they are rarely used. */ 671 int clock_root_cfg(enum clk_root_index clock_id, enum root_pre_div pre_div, 672 enum root_post_div post_div, enum clk_root_src clock_src) 673 { 674 u32 val; 675 int root_entry, src_entry; 676 struct clk_root_map *p; 677 678 if (clock_id >= CLK_ROOT_MAX) 679 return -EINVAL; 680 681 root_entry = select(clock_id); 682 if (root_entry < 0) 683 return -EINVAL; 684 685 p = &root_array[root_entry]; 686 687 if ((p->type == CCM_CORE_CHANNEL) || 688 (p->type == CCM_DRAM_PHYM_CHANNEL) || 689 (p->type == CCM_DRAM_CHANNEL)) { 690 if (pre_div != CLK_ROOT_PRE_DIV1) { 691 printf("Error pre div!\n"); 692 return -EINVAL; 693 } 694 } 695 696 /* Only 3 bit post div. */ 697 if (p->type == CCM_DRAM_CHANNEL) { 698 if (post_div > CLK_ROOT_POST_DIV7) { 699 printf("Error post div!\n"); 700 return -EINVAL; 701 } 702 } 703 704 if (p->type == CCM_DRAM_PHYM_CHANNEL) { 705 if (post_div != CLK_ROOT_POST_DIV1) { 706 printf("Error post div!\n"); 707 return -EINVAL; 708 } 709 } 710 711 src_entry = src_supported(root_entry, clock_src); 712 if (src_entry < 0) 713 return -EINVAL; 714 715 val = CLK_ROOT_ON | pre_div << CLK_ROOT_PRE_DIV_SHIFT | 716 post_div << CLK_ROOT_POST_DIV_SHIFT | 717 src_entry << CLK_ROOT_MUX_SHIFT; 718 719 __raw_writel(val, &imx_ccm->root[clock_id].target_root); 720 721 return 0; 722 } 723 724 int clock_root_enabled(enum clk_root_index clock_id) 725 { 726 u32 val; 727 728 if (clock_id >= CLK_ROOT_MAX) 729 return -EINVAL; 730 731 /* 732 * No enable bit for DRAM controller and PHY. Just return enabled. 733 */ 734 if ((clock_id == DRAM_PHYM_CLK_ROOT) || (clock_id == DRAM_CLK_ROOT)) 735 return 1; 736 737 val = __raw_readl(&imx_ccm->root[clock_id].target_root); 738 739 return (val & CLK_ROOT_ENABLE_MASK) ? 1 : 0; 740 } 741 742 /* CCGR gate operation */ 743 int clock_enable(enum clk_ccgr_index index, bool enable) 744 { 745 if (index >= CCGR_MAX) 746 return -EINVAL; 747 748 if (enable) 749 __raw_writel(CCM_CLK_ON_MSK, 750 &imx_ccm->ccgr_array[index].ccgr_set); 751 else 752 __raw_writel(CCM_CLK_ON_MSK, 753 &imx_ccm->ccgr_array[index].ccgr_clr); 754 755 return 0; 756 } 757