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