From 0ed4668a5fafa922f450fca4b3431610a21626c5 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 3 Jun 2015 14:41:29 +0800 Subject: [PATCH 01/44] dt-bindings: add imx7d clock ID definitions It adds the imx7d clock ID definitions which will be used by both imx7d clock driver and device tree. Signed-off-by: Frank Li Signed-off-by: Shawn Guo --- include/dt-bindings/clock/imx7d-clock.h | 450 ++++++++++++++++++++++++ 1 file changed, 450 insertions(+) create mode 100644 include/dt-bindings/clock/imx7d-clock.h diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h new file mode 100644 index 000000000000..728df28b00d5 --- /dev/null +++ b/include/dt-bindings/clock/imx7d-clock.h @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __DT_BINDINGS_CLOCK_IMX7D_H +#define __DT_BINDINGS_CLOCK_IMX7D_H + +#define IMX7D_OSC_24M_CLK 0 +#define IMX7D_PLL_ARM_MAIN 1 +#define IMX7D_PLL_ARM_MAIN_CLK 2 +#define IMX7D_PLL_ARM_MAIN_SRC 3 +#define IMX7D_PLL_ARM_MAIN_BYPASS 4 +#define IMX7D_PLL_SYS_MAIN 5 +#define IMX7D_PLL_SYS_MAIN_CLK 6 +#define IMX7D_PLL_SYS_MAIN_SRC 7 +#define IMX7D_PLL_SYS_MAIN_BYPASS 8 +#define IMX7D_PLL_SYS_MAIN_480M 9 +#define IMX7D_PLL_SYS_MAIN_240M 10 +#define IMX7D_PLL_SYS_MAIN_120M 11 +#define IMX7D_PLL_SYS_MAIN_480M_CLK 12 +#define IMX7D_PLL_SYS_MAIN_240M_CLK 13 +#define IMX7D_PLL_SYS_MAIN_120M_CLK 14 +#define IMX7D_PLL_SYS_PFD0_392M_CLK 15 +#define IMX7D_PLL_SYS_PFD0_196M 16 +#define IMX7D_PLL_SYS_PFD0_196M_CLK 17 +#define IMX7D_PLL_SYS_PFD1_332M_CLK 18 +#define IMX7D_PLL_SYS_PFD1_166M 19 +#define IMX7D_PLL_SYS_PFD1_166M_CLK 20 +#define IMX7D_PLL_SYS_PFD2_270M_CLK 21 +#define IMX7D_PLL_SYS_PFD2_135M 22 +#define IMX7D_PLL_SYS_PFD2_135M_CLK 23 +#define IMX7D_PLL_SYS_PFD3_CLK 24 +#define IMX7D_PLL_SYS_PFD4_CLK 25 +#define IMX7D_PLL_SYS_PFD5_CLK 26 +#define IMX7D_PLL_SYS_PFD6_CLK 27 +#define IMX7D_PLL_SYS_PFD7_CLK 28 +#define IMX7D_PLL_ENET_MAIN 29 +#define IMX7D_PLL_ENET_MAIN_CLK 30 +#define IMX7D_PLL_ENET_MAIN_SRC 31 +#define IMX7D_PLL_ENET_MAIN_BYPASS 32 +#define IMX7D_PLL_ENET_MAIN_500M 33 +#define IMX7D_PLL_ENET_MAIN_250M 34 +#define IMX7D_PLL_ENET_MAIN_125M 35 +#define IMX7D_PLL_ENET_MAIN_100M 36 +#define IMX7D_PLL_ENET_MAIN_50M 37 +#define IMX7D_PLL_ENET_MAIN_40M 38 +#define IMX7D_PLL_ENET_MAIN_25M 39 +#define IMX7D_PLL_ENET_MAIN_500M_CLK 40 +#define IMX7D_PLL_ENET_MAIN_250M_CLK 41 +#define IMX7D_PLL_ENET_MAIN_125M_CLK 42 +#define IMX7D_PLL_ENET_MAIN_100M_CLK 43 +#define IMX7D_PLL_ENET_MAIN_50M_CLK 44 +#define IMX7D_PLL_ENET_MAIN_40M_CLK 45 +#define IMX7D_PLL_ENET_MAIN_25M_CLK 46 +#define IMX7D_PLL_DRAM_MAIN 47 +#define IMX7D_PLL_DRAM_MAIN_CLK 48 +#define IMX7D_PLL_DRAM_MAIN_SRC 49 +#define IMX7D_PLL_DRAM_MAIN_BYPASS 50 +#define IMX7D_PLL_DRAM_MAIN_533M 51 +#define IMX7D_PLL_DRAM_MAIN_533M_CLK 52 +#define IMX7D_PLL_AUDIO_MAIN 53 +#define IMX7D_PLL_AUDIO_MAIN_CLK 54 +#define IMX7D_PLL_AUDIO_MAIN_SRC 55 +#define IMX7D_PLL_AUDIO_MAIN_BYPASS 56 +#define IMX7D_PLL_VIDEO_MAIN_CLK 57 +#define IMX7D_PLL_VIDEO_MAIN 58 +#define IMX7D_PLL_VIDEO_MAIN_SRC 59 +#define IMX7D_PLL_VIDEO_MAIN_BYPASS 60 +#define IMX7D_USB_MAIN_480M_CLK 61 +#define IMX7D_ARM_A7_ROOT_CLK 62 +#define IMX7D_ARM_A7_ROOT_SRC 63 +#define IMX7D_ARM_A7_ROOT_CG 64 +#define IMX7D_ARM_A7_ROOT_DIV 65 +#define IMX7D_ARM_M4_ROOT_CLK 66 +#define IMX7D_ARM_M4_ROOT_SRC 67 +#define IMX7D_ARM_M4_ROOT_CG 68 +#define IMX7D_ARM_M4_ROOT_DIV 69 +#define IMX7D_ARM_M0_ROOT_CLK 70 +#define IMX7D_ARM_M0_ROOT_SRC 71 +#define IMX7D_ARM_M0_ROOT_CG 72 +#define IMX7D_ARM_M0_ROOT_DIV 73 +#define IMX7D_MAIN_AXI_ROOT_CLK 74 +#define IMX7D_MAIN_AXI_ROOT_SRC 75 +#define IMX7D_MAIN_AXI_ROOT_CG 76 +#define IMX7D_MAIN_AXI_ROOT_DIV 77 +#define IMX7D_DISP_AXI_ROOT_CLK 78 +#define IMX7D_DISP_AXI_ROOT_SRC 79 +#define IMX7D_DISP_AXI_ROOT_CG 80 +#define IMX7D_DISP_AXI_ROOT_DIV 81 +#define IMX7D_ENET_AXI_ROOT_CLK 82 +#define IMX7D_ENET_AXI_ROOT_SRC 83 +#define IMX7D_ENET_AXI_ROOT_CG 84 +#define IMX7D_ENET_AXI_ROOT_DIV 85 +#define IMX7D_NAND_USDHC_BUS_ROOT_CLK 86 +#define IMX7D_NAND_USDHC_BUS_ROOT_SRC 87 +#define IMX7D_NAND_USDHC_BUS_ROOT_CG 88 +#define IMX7D_NAND_USDHC_BUS_ROOT_DIV 89 +#define IMX7D_AHB_CHANNEL_ROOT_CLK 90 +#define IMX7D_AHB_CHANNEL_ROOT_SRC 91 +#define IMX7D_AHB_CHANNEL_ROOT_CG 92 +#define IMX7D_AHB_CHANNEL_ROOT_DIV 93 +#define IMX7D_DRAM_PHYM_ROOT_CLK 94 +#define IMX7D_DRAM_PHYM_ROOT_SRC 95 +#define IMX7D_DRAM_PHYM_ROOT_CG 96 +#define IMX7D_DRAM_PHYM_ROOT_DIV 97 +#define IMX7D_DRAM_ROOT_CLK 98 +#define IMX7D_DRAM_ROOT_SRC 99 +#define IMX7D_DRAM_ROOT_CG 100 +#define IMX7D_DRAM_ROOT_DIV 101 +#define IMX7D_DRAM_PHYM_ALT_ROOT_CLK 102 +#define IMX7D_DRAM_PHYM_ALT_ROOT_SRC 103 +#define IMX7D_DRAM_PHYM_ALT_ROOT_CG 104 +#define IMX7D_DRAM_PHYM_ALT_ROOT_DIV 105 +#define IMX7D_DRAM_ALT_ROOT_CLK 106 +#define IMX7D_DRAM_ALT_ROOT_SRC 107 +#define IMX7D_DRAM_ALT_ROOT_CG 108 +#define IMX7D_DRAM_ALT_ROOT_DIV 109 +#define IMX7D_USB_HSIC_ROOT_CLK 110 +#define IMX7D_USB_HSIC_ROOT_SRC 111 +#define IMX7D_USB_HSIC_ROOT_CG 112 +#define IMX7D_USB_HSIC_ROOT_DIV 113 +#define IMX7D_PCIE_CTRL_ROOT_CLK 114 +#define IMX7D_PCIE_CTRL_ROOT_SRC 115 +#define IMX7D_PCIE_CTRL_ROOT_CG 116 +#define IMX7D_PCIE_CTRL_ROOT_DIV 117 +#define IMX7D_PCIE_PHY_ROOT_CLK 118 +#define IMX7D_PCIE_PHY_ROOT_SRC 119 +#define IMX7D_PCIE_PHY_ROOT_CG 120 +#define IMX7D_PCIE_PHY_ROOT_DIV 121 +#define IMX7D_EPDC_PIXEL_ROOT_CLK 122 +#define IMX7D_EPDC_PIXEL_ROOT_SRC 123 +#define IMX7D_EPDC_PIXEL_ROOT_CG 124 +#define IMX7D_EPDC_PIXEL_ROOT_DIV 125 +#define IMX7D_LCDIF_PIXEL_ROOT_CLK 126 +#define IMX7D_LCDIF_PIXEL_ROOT_SRC 127 +#define IMX7D_LCDIF_PIXEL_ROOT_CG 128 +#define IMX7D_LCDIF_PIXEL_ROOT_DIV 129 +#define IMX7D_MIPI_DSI_ROOT_CLK 130 +#define IMX7D_MIPI_DSI_ROOT_SRC 131 +#define IMX7D_MIPI_DSI_ROOT_CG 132 +#define IMX7D_MIPI_DSI_ROOT_DIV 133 +#define IMX7D_MIPI_CSI_ROOT_CLK 134 +#define IMX7D_MIPI_CSI_ROOT_SRC 135 +#define IMX7D_MIPI_CSI_ROOT_CG 136 +#define IMX7D_MIPI_CSI_ROOT_DIV 137 +#define IMX7D_MIPI_DPHY_ROOT_CLK 138 +#define IMX7D_MIPI_DPHY_ROOT_SRC 139 +#define IMX7D_MIPI_DPHY_ROOT_CG 140 +#define IMX7D_MIPI_DPHY_ROOT_DIV 141 +#define IMX7D_SAI1_ROOT_CLK 142 +#define IMX7D_SAI1_ROOT_SRC 143 +#define IMX7D_SAI1_ROOT_CG 144 +#define IMX7D_SAI1_ROOT_DIV 145 +#define IMX7D_SAI2_ROOT_CLK 146 +#define IMX7D_SAI2_ROOT_SRC 147 +#define IMX7D_SAI2_ROOT_CG 148 +#define IMX7D_SAI2_ROOT_DIV 149 +#define IMX7D_SAI3_ROOT_CLK 150 +#define IMX7D_SAI3_ROOT_SRC 151 +#define IMX7D_SAI3_ROOT_CG 152 +#define IMX7D_SAI3_ROOT_DIV 153 +#define IMX7D_SPDIF_ROOT_CLK 154 +#define IMX7D_SPDIF_ROOT_SRC 155 +#define IMX7D_SPDIF_ROOT_CG 156 +#define IMX7D_SPDIF_ROOT_DIV 157 +#define IMX7D_ENET1_REF_ROOT_CLK 158 +#define IMX7D_ENET1_REF_ROOT_SRC 159 +#define IMX7D_ENET1_REF_ROOT_CG 160 +#define IMX7D_ENET1_REF_ROOT_DIV 161 +#define IMX7D_ENET1_TIME_ROOT_CLK 162 +#define IMX7D_ENET1_TIME_ROOT_SRC 163 +#define IMX7D_ENET1_TIME_ROOT_CG 164 +#define IMX7D_ENET1_TIME_ROOT_DIV 165 +#define IMX7D_ENET2_REF_ROOT_CLK 166 +#define IMX7D_ENET2_REF_ROOT_SRC 167 +#define IMX7D_ENET2_REF_ROOT_CG 168 +#define IMX7D_ENET2_REF_ROOT_DIV 169 +#define IMX7D_ENET2_TIME_ROOT_CLK 170 +#define IMX7D_ENET2_TIME_ROOT_SRC 171 +#define IMX7D_ENET2_TIME_ROOT_CG 172 +#define IMX7D_ENET2_TIME_ROOT_DIV 173 +#define IMX7D_ENET_PHY_REF_ROOT_CLK 174 +#define IMX7D_ENET_PHY_REF_ROOT_SRC 175 +#define IMX7D_ENET_PHY_REF_ROOT_CG 176 +#define IMX7D_ENET_PHY_REF_ROOT_DIV 177 +#define IMX7D_EIM_ROOT_CLK 178 +#define IMX7D_EIM_ROOT_SRC 179 +#define IMX7D_EIM_ROOT_CG 180 +#define IMX7D_EIM_ROOT_DIV 181 +#define IMX7D_NAND_ROOT_CLK 182 +#define IMX7D_NAND_ROOT_SRC 183 +#define IMX7D_NAND_ROOT_CG 184 +#define IMX7D_NAND_ROOT_DIV 185 +#define IMX7D_QSPI_ROOT_CLK 186 +#define IMX7D_QSPI_ROOT_SRC 187 +#define IMX7D_QSPI_ROOT_CG 188 +#define IMX7D_QSPI_ROOT_DIV 189 +#define IMX7D_USDHC1_ROOT_CLK 190 +#define IMX7D_USDHC1_ROOT_SRC 191 +#define IMX7D_USDHC1_ROOT_CG 192 +#define IMX7D_USDHC1_ROOT_DIV 193 +#define IMX7D_USDHC2_ROOT_CLK 194 +#define IMX7D_USDHC2_ROOT_SRC 195 +#define IMX7D_USDHC2_ROOT_CG 196 +#define IMX7D_USDHC2_ROOT_DIV 197 +#define IMX7D_USDHC3_ROOT_CLK 198 +#define IMX7D_USDHC3_ROOT_SRC 199 +#define IMX7D_USDHC3_ROOT_CG 200 +#define IMX7D_USDHC3_ROOT_DIV 201 +#define IMX7D_CAN1_ROOT_CLK 202 +#define IMX7D_CAN1_ROOT_SRC 203 +#define IMX7D_CAN1_ROOT_CG 204 +#define IMX7D_CAN1_ROOT_DIV 205 +#define IMX7D_CAN2_ROOT_CLK 206 +#define IMX7D_CAN2_ROOT_SRC 207 +#define IMX7D_CAN2_ROOT_CG 208 +#define IMX7D_CAN2_ROOT_DIV 209 +#define IMX7D_I2C1_ROOT_CLK 210 +#define IMX7D_I2C1_ROOT_SRC 211 +#define IMX7D_I2C1_ROOT_CG 212 +#define IMX7D_I2C1_ROOT_DIV 213 +#define IMX7D_I2C2_ROOT_CLK 214 +#define IMX7D_I2C2_ROOT_SRC 215 +#define IMX7D_I2C2_ROOT_CG 216 +#define IMX7D_I2C2_ROOT_DIV 217 +#define IMX7D_I2C3_ROOT_CLK 218 +#define IMX7D_I2C3_ROOT_SRC 219 +#define IMX7D_I2C3_ROOT_CG 220 +#define IMX7D_I2C3_ROOT_DIV 221 +#define IMX7D_I2C4_ROOT_CLK 222 +#define IMX7D_I2C4_ROOT_SRC 223 +#define IMX7D_I2C4_ROOT_CG 224 +#define IMX7D_I2C4_ROOT_DIV 225 +#define IMX7D_UART1_ROOT_CLK 226 +#define IMX7D_UART1_ROOT_SRC 227 +#define IMX7D_UART1_ROOT_CG 228 +#define IMX7D_UART1_ROOT_DIV 229 +#define IMX7D_UART2_ROOT_CLK 230 +#define IMX7D_UART2_ROOT_SRC 231 +#define IMX7D_UART2_ROOT_CG 232 +#define IMX7D_UART2_ROOT_DIV 233 +#define IMX7D_UART3_ROOT_CLK 234 +#define IMX7D_UART3_ROOT_SRC 235 +#define IMX7D_UART3_ROOT_CG 236 +#define IMX7D_UART3_ROOT_DIV 237 +#define IMX7D_UART4_ROOT_CLK 238 +#define IMX7D_UART4_ROOT_SRC 239 +#define IMX7D_UART4_ROOT_CG 240 +#define IMX7D_UART4_ROOT_DIV 241 +#define IMX7D_UART5_ROOT_CLK 242 +#define IMX7D_UART5_ROOT_SRC 243 +#define IMX7D_UART5_ROOT_CG 244 +#define IMX7D_UART5_ROOT_DIV 245 +#define IMX7D_UART6_ROOT_CLK 246 +#define IMX7D_UART6_ROOT_SRC 247 +#define IMX7D_UART6_ROOT_CG 248 +#define IMX7D_UART6_ROOT_DIV 249 +#define IMX7D_UART7_ROOT_CLK 250 +#define IMX7D_UART7_ROOT_SRC 251 +#define IMX7D_UART7_ROOT_CG 252 +#define IMX7D_UART7_ROOT_DIV 253 +#define IMX7D_ECSPI1_ROOT_CLK 254 +#define IMX7D_ECSPI1_ROOT_SRC 255 +#define IMX7D_ECSPI1_ROOT_CG 256 +#define IMX7D_ECSPI1_ROOT_DIV 257 +#define IMX7D_ECSPI2_ROOT_CLK 258 +#define IMX7D_ECSPI2_ROOT_SRC 259 +#define IMX7D_ECSPI2_ROOT_CG 260 +#define IMX7D_ECSPI2_ROOT_DIV 261 +#define IMX7D_ECSPI3_ROOT_CLK 262 +#define IMX7D_ECSPI3_ROOT_SRC 263 +#define IMX7D_ECSPI3_ROOT_CG 264 +#define IMX7D_ECSPI3_ROOT_DIV 265 +#define IMX7D_ECSPI4_ROOT_CLK 266 +#define IMX7D_ECSPI4_ROOT_SRC 267 +#define IMX7D_ECSPI4_ROOT_CG 268 +#define IMX7D_ECSPI4_ROOT_DIV 269 +#define IMX7D_PWM1_ROOT_CLK 270 +#define IMX7D_PWM1_ROOT_SRC 271 +#define IMX7D_PWM1_ROOT_CG 272 +#define IMX7D_PWM1_ROOT_DIV 273 +#define IMX7D_PWM2_ROOT_CLK 274 +#define IMX7D_PWM2_ROOT_SRC 275 +#define IMX7D_PWM2_ROOT_CG 276 +#define IMX7D_PWM2_ROOT_DIV 277 +#define IMX7D_PWM3_ROOT_CLK 278 +#define IMX7D_PWM3_ROOT_SRC 279 +#define IMX7D_PWM3_ROOT_CG 280 +#define IMX7D_PWM3_ROOT_DIV 281 +#define IMX7D_PWM4_ROOT_CLK 282 +#define IMX7D_PWM4_ROOT_SRC 283 +#define IMX7D_PWM4_ROOT_CG 284 +#define IMX7D_PWM4_ROOT_DIV 285 +#define IMX7D_FLEXTIMER1_ROOT_CLK 286 +#define IMX7D_FLEXTIMER1_ROOT_SRC 287 +#define IMX7D_FLEXTIMER1_ROOT_CG 288 +#define IMX7D_FLEXTIMER1_ROOT_DIV 289 +#define IMX7D_FLEXTIMER2_ROOT_CLK 290 +#define IMX7D_FLEXTIMER2_ROOT_SRC 291 +#define IMX7D_FLEXTIMER2_ROOT_CG 292 +#define IMX7D_FLEXTIMER2_ROOT_DIV 293 +#define IMX7D_SIM1_ROOT_CLK 294 +#define IMX7D_SIM1_ROOT_SRC 295 +#define IMX7D_SIM1_ROOT_CG 296 +#define IMX7D_SIM1_ROOT_DIV 297 +#define IMX7D_SIM2_ROOT_CLK 298 +#define IMX7D_SIM2_ROOT_SRC 299 +#define IMX7D_SIM2_ROOT_CG 300 +#define IMX7D_SIM2_ROOT_DIV 301 +#define IMX7D_GPT1_ROOT_CLK 302 +#define IMX7D_GPT1_ROOT_SRC 303 +#define IMX7D_GPT1_ROOT_CG 304 +#define IMX7D_GPT1_ROOT_DIV 305 +#define IMX7D_GPT2_ROOT_CLK 306 +#define IMX7D_GPT2_ROOT_SRC 307 +#define IMX7D_GPT2_ROOT_CG 308 +#define IMX7D_GPT2_ROOT_DIV 309 +#define IMX7D_GPT3_ROOT_CLK 310 +#define IMX7D_GPT3_ROOT_SRC 311 +#define IMX7D_GPT3_ROOT_CG 312 +#define IMX7D_GPT3_ROOT_DIV 313 +#define IMX7D_GPT4_ROOT_CLK 314 +#define IMX7D_GPT4_ROOT_SRC 315 +#define IMX7D_GPT4_ROOT_CG 316 +#define IMX7D_GPT4_ROOT_DIV 317 +#define IMX7D_TRACE_ROOT_CLK 318 +#define IMX7D_TRACE_ROOT_SRC 319 +#define IMX7D_TRACE_ROOT_CG 320 +#define IMX7D_TRACE_ROOT_DIV 321 +#define IMX7D_WDOG1_ROOT_CLK 322 +#define IMX7D_WDOG_ROOT_SRC 323 +#define IMX7D_WDOG_ROOT_CG 324 +#define IMX7D_WDOG_ROOT_DIV 325 +#define IMX7D_CSI_MCLK_ROOT_CLK 326 +#define IMX7D_CSI_MCLK_ROOT_SRC 327 +#define IMX7D_CSI_MCLK_ROOT_CG 328 +#define IMX7D_CSI_MCLK_ROOT_DIV 329 +#define IMX7D_AUDIO_MCLK_ROOT_CLK 330 +#define IMX7D_AUDIO_MCLK_ROOT_SRC 331 +#define IMX7D_AUDIO_MCLK_ROOT_CG 332 +#define IMX7D_AUDIO_MCLK_ROOT_DIV 333 +#define IMX7D_WRCLK_ROOT_CLK 334 +#define IMX7D_WRCLK_ROOT_SRC 335 +#define IMX7D_WRCLK_ROOT_CG 336 +#define IMX7D_WRCLK_ROOT_DIV 337 +#define IMX7D_CLKO1_ROOT_SRC 338 +#define IMX7D_CLKO1_ROOT_CG 339 +#define IMX7D_CLKO1_ROOT_DIV 340 +#define IMX7D_CLKO2_ROOT_SRC 341 +#define IMX7D_CLKO2_ROOT_CG 342 +#define IMX7D_CLKO2_ROOT_DIV 343 +#define IMX7D_MAIN_AXI_ROOT_PRE_DIV 344 +#define IMX7D_DISP_AXI_ROOT_PRE_DIV 345 +#define IMX7D_ENET_AXI_ROOT_PRE_DIV 346 +#define IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV 347 +#define IMX7D_AHB_CHANNEL_ROOT_PRE_DIV 348 +#define IMX7D_USB_HSIC_ROOT_PRE_DIV 349 +#define IMX7D_PCIE_CTRL_ROOT_PRE_DIV 350 +#define IMX7D_PCIE_PHY_ROOT_PRE_DIV 351 +#define IMX7D_EPDC_PIXEL_ROOT_PRE_DIV 352 +#define IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV 353 +#define IMX7D_MIPI_DSI_ROOT_PRE_DIV 354 +#define IMX7D_MIPI_CSI_ROOT_PRE_DIV 355 +#define IMX7D_MIPI_DPHY_ROOT_PRE_DIV 356 +#define IMX7D_SAI1_ROOT_PRE_DIV 357 +#define IMX7D_SAI2_ROOT_PRE_DIV 358 +#define IMX7D_SAI3_ROOT_PRE_DIV 359 +#define IMX7D_SPDIF_ROOT_PRE_DIV 360 +#define IMX7D_ENET1_REF_ROOT_PRE_DIV 361 +#define IMX7D_ENET1_TIME_ROOT_PRE_DIV 362 +#define IMX7D_ENET2_REF_ROOT_PRE_DIV 363 +#define IMX7D_ENET2_TIME_ROOT_PRE_DIV 364 +#define IMX7D_ENET_PHY_REF_ROOT_PRE_DIV 365 +#define IMX7D_EIM_ROOT_PRE_DIV 366 +#define IMX7D_NAND_ROOT_PRE_DIV 367 +#define IMX7D_QSPI_ROOT_PRE_DIV 368 +#define IMX7D_USDHC1_ROOT_PRE_DIV 369 +#define IMX7D_USDHC2_ROOT_PRE_DIV 370 +#define IMX7D_USDHC3_ROOT_PRE_DIV 371 +#define IMX7D_CAN1_ROOT_PRE_DIV 372 +#define IMX7D_CAN2_ROOT_PRE_DIV 373 +#define IMX7D_I2C1_ROOT_PRE_DIV 374 +#define IMX7D_I2C2_ROOT_PRE_DIV 375 +#define IMX7D_I2C3_ROOT_PRE_DIV 376 +#define IMX7D_I2C4_ROOT_PRE_DIV 377 +#define IMX7D_UART1_ROOT_PRE_DIV 378 +#define IMX7D_UART2_ROOT_PRE_DIV 379 +#define IMX7D_UART3_ROOT_PRE_DIV 380 +#define IMX7D_UART4_ROOT_PRE_DIV 381 +#define IMX7D_UART5_ROOT_PRE_DIV 382 +#define IMX7D_UART6_ROOT_PRE_DIV 383 +#define IMX7D_UART7_ROOT_PRE_DIV 384 +#define IMX7D_ECSPI1_ROOT_PRE_DIV 385 +#define IMX7D_ECSPI2_ROOT_PRE_DIV 386 +#define IMX7D_ECSPI3_ROOT_PRE_DIV 387 +#define IMX7D_ECSPI4_ROOT_PRE_DIV 388 +#define IMX7D_PWM1_ROOT_PRE_DIV 389 +#define IMX7D_PWM2_ROOT_PRE_DIV 390 +#define IMX7D_PWM3_ROOT_PRE_DIV 391 +#define IMX7D_PWM4_ROOT_PRE_DIV 392 +#define IMX7D_FLEXTIMER1_ROOT_PRE_DIV 393 +#define IMX7D_FLEXTIMER2_ROOT_PRE_DIV 394 +#define IMX7D_SIM1_ROOT_PRE_DIV 395 +#define IMX7D_SIM2_ROOT_PRE_DIV 396 +#define IMX7D_GPT1_ROOT_PRE_DIV 397 +#define IMX7D_GPT2_ROOT_PRE_DIV 398 +#define IMX7D_GPT3_ROOT_PRE_DIV 399 +#define IMX7D_GPT4_ROOT_PRE_DIV 400 +#define IMX7D_TRACE_ROOT_PRE_DIV 401 +#define IMX7D_WDOG_ROOT_PRE_DIV 402 +#define IMX7D_CSI_MCLK_ROOT_PRE_DIV 403 +#define IMX7D_AUDIO_MCLK_ROOT_PRE_DIV 404 +#define IMX7D_WRCLK_ROOT_PRE_DIV 405 +#define IMX7D_CLKO1_ROOT_PRE_DIV 406 +#define IMX7D_CLKO2_ROOT_PRE_DIV 407 +#define IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV 408 +#define IMX7D_DRAM_ALT_ROOT_PRE_DIV 409 +#define IMX7D_LVDS1_IN_CLK 410 +#define IMX7D_LVDS1_OUT_SEL 411 +#define IMX7D_LVDS1_OUT_CLK 412 +#define IMX7D_CLK_DUMMY 413 +#define IMX7D_GPT_3M_CLK 414 +#define IMX7D_OCRAM_CLK 415 +#define IMX7D_OCRAM_S_CLK 416 +#define IMX7D_WDOG2_ROOT_CLK 417 +#define IMX7D_WDOG3_ROOT_CLK 418 +#define IMX7D_WDOG4_ROOT_CLK 419 +#define IMX7D_SDMA_CORE_CLK 420 +#define IMX7D_USB1_MAIN_480M_CLK 421 +#define IMX7D_USB_CTRL_CLK 422 +#define IMX7D_USB_PHY1_CLK 423 +#define IMX7D_USB_PHY2_CLK 424 +#define IMX7D_IPG_ROOT_CLK 425 +#define IMX7D_SAI1_IPG_CLK 426 +#define IMX7D_SAI2_IPG_CLK 427 +#define IMX7D_SAI3_IPG_CLK 428 +#define IMX7D_PLL_AUDIO_TEST_DIV 429 +#define IMX7D_PLL_AUDIO_POST_DIV 430 +#define IMX7D_PLL_VIDEO_TEST_DIV 431 +#define IMX7D_PLL_VIDEO_POST_DIV 432 +#define IMX7D_MU_ROOT_CLK 433 +#define IMX7D_SEMA4_HS_ROOT_CLK 434 +#define IMX7D_PLL_DRAM_TEST_DIV 435 +#define IMX7D_CLK_END 436 +#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ From 6c529c499fecfe65da6429917bd9cb319040c69e Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 25 Apr 2015 15:44:10 +0800 Subject: [PATCH 02/44] ARM: imx: use dynamic mapping for timer Pass physical address of timer block to mxc_timer_init() call, which in turn does dynamic mapping within the function. Thus, we can avoid using static mapping in clock drivers. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx1.c | 2 +- arch/arm/mach-imx/clk-imx21.c | 2 +- arch/arm/mach-imx/clk-imx27.c | 2 +- arch/arm/mach-imx/clk-imx31.c | 2 +- arch/arm/mach-imx/clk-imx35.c | 2 +- arch/arm/mach-imx/common.h | 2 +- arch/arm/mach-imx/time.c | 5 +++-- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c index 37c307a8d896..f4a76e841966 100644 --- a/arch/arm/mach-imx/clk-imx1.c +++ b/arch/arm/mach-imx/clk-imx1.c @@ -98,7 +98,7 @@ int __init mx1_clocks_init(unsigned long fref) clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0"); clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0"); - mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); + mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT); return 0; } diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c index 4b4c75339aa6..facdf1ddd7f1 100644 --- a/arch/arm/mach-imx/clk-imx21.c +++ b/arch/arm/mach-imx/clk-imx21.c @@ -153,7 +153,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0"); clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0"); - mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1); + mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1); return 0; } diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index ab6349ec23b9..aeb19982a36e 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -229,7 +229,7 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0"); clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0"); - mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); + mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1); return 0; } diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index 286ef422cebc..8a103a2c8b68 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c @@ -182,7 +182,7 @@ int __init mx31_clocks_init(unsigned long fref) mx31_revision(); clk_disable_unprepare(clk[iim_gate]); - mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT); + mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT); return 0; } diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index a0d2b57fd376..4ef1e8bdac5b 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -279,7 +279,7 @@ int __init mx35_clocks_init(void) #ifdef CONFIG_MXC_USE_EPIT epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); #else - mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); + mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT); #endif return 0; diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 0f04e30b726d..5cddd1534265 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -44,7 +44,7 @@ void imx27_soc_init(void); void imx31_soc_init(void); void imx35_soc_init(void); void epit_timer_init(void __iomem *base, int irq); -void mxc_timer_init(void __iomem *, int); +void mxc_timer_init(unsigned long, int); int mx1_clocks_init(unsigned long fref); int mx21_clocks_init(unsigned long lref, unsigned long fref); int mx27_clocks_init(unsigned long fref); diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 15d18e198303..acb1ff577cda 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -344,12 +344,13 @@ static void __init _mxc_timer_init(int irq, setup_irq(irq, &mxc_timer_irq); } -void __init mxc_timer_init(void __iomem *base, int irq) +void __init mxc_timer_init(unsigned long pbase, int irq) { struct clk *clk_per = clk_get_sys("imx-gpt.0", "per"); struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg"); - timer_base = base; + timer_base = ioremap(pbase, SZ_4K); + BUG_ON(!timer_base); _mxc_timer_init(irq, clk_per, clk_ipg); } From 5ab96a8df094b87673b67e4dce70e31248d663a3 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 25 Apr 2015 16:02:53 +0800 Subject: [PATCH 03/44] ARM: imx: use dynamic mapping for CCM Replace the static mapping of CCM block in clock drivers with dynamic mapping. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx1.c | 3 ++- arch/arm/mach-imx/clk-imx31.c | 5 ++++- arch/arm/mach-imx/clk-imx35.c | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c index f4a76e841966..5301d2ebb234 100644 --- a/arch/arm/mach-imx/clk-imx1.c +++ b/arch/arm/mach-imx/clk-imx1.c @@ -75,7 +75,8 @@ static void __init _mx1_clocks_init(unsigned long fref) int __init mx1_clocks_init(unsigned long fref) { - ccm = MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR); + ccm = ioremap(MX1_CCM_BASE_ADDR, SZ_4K); + BUG_ON(!ccm); _mx1_clocks_init(fref); diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index 8a103a2c8b68..2aaccadb9e13 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c @@ -50,9 +50,12 @@ static struct clk_onecell_data clk_data; int __init mx31_clocks_init(unsigned long fref) { - void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); + void __iomem *base; struct device_node *np; + base = ioremap(MX31_CCM_BASE_ADDR, SZ_4K); + BUG_ON(!base); + clk[dummy] = imx_clk_fixed("dummy", 0); clk[ckih] = imx_clk_fixed("ckih", fref); clk[ckil] = imx_clk_fixed("ckil", 32768); diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index 4ef1e8bdac5b..5818521a8766 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -71,11 +71,14 @@ static struct clk *clk[clk_max]; int __init mx35_clocks_init(void) { - void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); + void __iomem *base; u32 pdr0, consumer_sel, hsp_sel; struct arm_ahb_div *aad; unsigned char *hsp_div; + base = ioremap(MX35_CCM_BASE_ADDR, SZ_4K); + BUG_ON(!base); + pdr0 = __raw_readl(base + MXC_CCM_PDR0); consumer_sel = (pdr0 >> 16) & 0xf; aad = &clk_consumer[consumer_sel]; From 9bbef18750b34fa1d476e46a7833867b49f856c4 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 25 Apr 2015 21:03:15 +0800 Subject: [PATCH 04/44] ARM: imx: move revision definitions and declarations into a header The revision definitions and declarations are widely used by clock drivers. As a step of moving clock drivers out of arch/arm/mach-imx, let's create header include/soc/imx/revision.h to accommodate them. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 4 ---- arch/arm/mach-imx/hardware.h | 1 + arch/arm/mach-imx/mx27.h | 4 ---- arch/arm/mach-imx/mx3x.h | 7 ------- arch/arm/mach-imx/mxc.h | 16 ---------------- include/soc/imx/revision.h | 37 ++++++++++++++++++++++++++++++++++++ 6 files changed, 38 insertions(+), 31 deletions(-) create mode 100644 include/soc/imx/revision.h diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 5cddd1534265..3682d094a259 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -56,13 +56,10 @@ struct platform_device *mxc_register_gpio(char *name, int id, void mxc_set_cpu_type(unsigned int type); void mxc_restart(enum reboot_mode, const char *); void mxc_arch_reset_init(void __iomem *); -int mx51_revision(void); -int mx53_revision(void); void imx_set_aips(void __iomem *); void imx_aips_allow_unprivileged_access(const char *compat); int mxc_device_init(void); void imx_set_soc_revision(unsigned int rev); -unsigned int imx_get_soc_revision(void); void imx_init_revision_from_anatop(void); struct device *imx_soc_device_init(void); void imx6_enable_rbc(bool enable); @@ -87,7 +84,6 @@ enum mx3_cpu_pwr_mode { }; void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); -void imx_print_silicon_rev(const char *cpu, int srev); void imx_enable_cpu(int cpu, bool enable); void imx_set_cpu_jump(int cpu, void *jump_addr); diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h index 76af2c03c241..d737f95ebb07 100644 --- a/arch/arm/mach-imx/hardware.h +++ b/arch/arm/mach-imx/hardware.h @@ -22,6 +22,7 @@ #ifndef __ASSEMBLY__ #include +#include #endif #include diff --git a/arch/arm/mach-imx/mx27.h b/arch/arm/mach-imx/mx27.h index 8a65f192e7f3..f96bb2642677 100644 --- a/arch/arm/mach-imx/mx27.h +++ b/arch/arm/mach-imx/mx27.h @@ -231,8 +231,4 @@ #define MX27_DMA_REQ_SDHC3 36 #define MX27_DMA_REQ_NFC 37 -#ifndef __ASSEMBLY__ -extern int mx27_revision(void); -#endif - #endif /* ifndef __MACH_MX27_H__ */ diff --git a/arch/arm/mach-imx/mx3x.h b/arch/arm/mach-imx/mx3x.h index 96fb4fbc8ad7..6fec6114c2f1 100644 --- a/arch/arm/mach-imx/mx3x.h +++ b/arch/arm/mach-imx/mx3x.h @@ -185,11 +185,4 @@ #define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */ -/* Mandatory defines used globally */ - -#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) -extern int mx35_revision(void); -extern int mx31_revision(void); -#endif - #endif /* ifndef __MACH_MX3x_H__ */ diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 4c1343df2ba4..8726051fcfca 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -39,22 +39,6 @@ #define MXC_CPU_IMX6SX 0x62 #define MXC_CPU_IMX6Q 0x63 -#define IMX_CHIP_REVISION_1_0 0x10 -#define IMX_CHIP_REVISION_1_1 0x11 -#define IMX_CHIP_REVISION_1_2 0x12 -#define IMX_CHIP_REVISION_1_3 0x13 -#define IMX_CHIP_REVISION_1_4 0x14 -#define IMX_CHIP_REVISION_1_5 0x15 -#define IMX_CHIP_REVISION_2_0 0x20 -#define IMX_CHIP_REVISION_2_1 0x21 -#define IMX_CHIP_REVISION_2_2 0x22 -#define IMX_CHIP_REVISION_2_3 0x23 -#define IMX_CHIP_REVISION_3_0 0x30 -#define IMX_CHIP_REVISION_3_1 0x31 -#define IMX_CHIP_REVISION_3_2 0x32 -#define IMX_CHIP_REVISION_3_3 0x33 -#define IMX_CHIP_REVISION_UNKNOWN 0xff - #define IMX_DDR_TYPE_LPDDR2 1 #ifndef __ASSEMBLY__ diff --git a/include/soc/imx/revision.h b/include/soc/imx/revision.h new file mode 100644 index 000000000000..9ea346924c35 --- /dev/null +++ b/include/soc/imx/revision.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __SOC_IMX_REVISION_H__ +#define __SOC_IMX_REVISION_H__ + +#define IMX_CHIP_REVISION_1_0 0x10 +#define IMX_CHIP_REVISION_1_1 0x11 +#define IMX_CHIP_REVISION_1_2 0x12 +#define IMX_CHIP_REVISION_1_3 0x13 +#define IMX_CHIP_REVISION_1_4 0x14 +#define IMX_CHIP_REVISION_1_5 0x15 +#define IMX_CHIP_REVISION_2_0 0x20 +#define IMX_CHIP_REVISION_2_1 0x21 +#define IMX_CHIP_REVISION_2_2 0x22 +#define IMX_CHIP_REVISION_2_3 0x23 +#define IMX_CHIP_REVISION_3_0 0x30 +#define IMX_CHIP_REVISION_3_1 0x31 +#define IMX_CHIP_REVISION_3_2 0x32 +#define IMX_CHIP_REVISION_3_3 0x33 +#define IMX_CHIP_REVISION_UNKNOWN 0xff + +int mx27_revision(void); +int mx31_revision(void); +int mx35_revision(void); +int mx51_revision(void); +int mx53_revision(void); + +unsigned int imx_get_soc_revision(void); +void imx_print_silicon_rev(const char *cpu, int srev); + +#endif /* __SOC_IMX_REVISION_H__ */ From f3a9249d096178d29bba69cece29da99a622ce28 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 25 Apr 2015 22:38:19 +0800 Subject: [PATCH 05/44] ARM: imx5: let pm code map CCM block on its own We are about to move imx5 clock driver into drivers/clk, so let's get imx5 pm code map CCM block on its own rather than relying on clock driver to do the mapping. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 2 -- arch/arm/mach-imx/common.h | 2 -- arch/arm/mach-imx/pm-imx5.c | 9 ++++----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 0f7e536147cb..f341464fe7e9 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -133,8 +133,6 @@ static struct clk_onecell_data clk_data; static void __init mx5_clocks_common_init(void __iomem *ccm_base) { - imx5_pm_set_ccm_base(ccm_base); - clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0); clk[IMX5_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); clk[IMX5_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 3682d094a259..fe510fbd0c8c 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -132,11 +132,9 @@ void imx6q_pm_set_ccm_base(void __iomem *base); #ifdef CONFIG_PM void imx51_pm_init(void); void imx53_pm_init(void); -void imx5_pm_set_ccm_base(void __iomem *base); #else static inline void imx51_pm_init(void) {} static inline void imx53_pm_init(void) {} -static inline void imx5_pm_set_ccm_base(void __iomem *base) {} #endif #ifdef CONFIG_NEON diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index f1f80ab73e69..b04025592d94 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -50,16 +50,19 @@ #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF struct imx5_pm_data { + phys_addr_t ccm_addr; phys_addr_t cortex_addr; phys_addr_t gpc_addr; }; static const struct imx5_pm_data imx51_pm_data __initconst = { + .ccm_addr = 0x73fd4000, .cortex_addr = 0x83fa0000, .gpc_addr = 0x73fd8000, }; static const struct imx5_pm_data imx53_pm_data __initconst = { + .ccm_addr = 0x53fd4000, .cortex_addr = 0x63fa0000, .gpc_addr = 0x53fd8000, }; @@ -68,11 +71,6 @@ static void __iomem *ccm_base; static void __iomem *cortex_base; static void __iomem *gpc_base; -void __init imx5_pm_set_ccm_base(void __iomem *base) -{ - ccm_base = base; -} - /* * set cpu low power mode before WFI instruction. This function is called * mx5 because it can be used for mx51, and mx53. @@ -208,6 +206,7 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) arm_pm_idle = imx5_pm_idle; + ccm_base = ioremap(data->ccm_addr, SZ_16K); cortex_base = ioremap(data->cortex_addr, SZ_16K); gpc_base = ioremap(data->gpc_addr, SZ_16K); WARN_ON(!ccm_base || !cortex_base || !gpc_base); From 8fb76a07e2cb08b9f278a6415af4f784bb635a6e Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 25 Apr 2015 22:59:19 +0800 Subject: [PATCH 06/44] ARM: imx6: set initial power mode in pm function Rather than setting initial low-power mode in every single i.MX6 clock initialization function, we should really do that in pm code. Let's move imx6q_set_lpm(WAIT_CLOCKED) call into imx6_pm_common_init(). While at it, let's rename the function to imx6_set_lpm() since it's actually common for all i.MX6 SoCs. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 3 --- arch/arm/mach-imx/clk-imx6sl.c | 3 --- arch/arm/mach-imx/clk-imx6sx.c | 3 --- arch/arm/mach-imx/common.h | 2 +- arch/arm/mach-imx/cpuidle-imx6q.c | 4 ++-- arch/arm/mach-imx/cpuidle-imx6sl.c | 4 ++-- arch/arm/mach-imx/cpuidle-imx6sx.c | 4 ++-- arch/arm/mach-imx/pm-imx6.c | 14 ++++++++------ 8 files changed, 15 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 469a150bf98f..54ce0b30b9ad 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -527,8 +527,5 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) /* All existing boards with PCIe use LVDS1 */ if (IS_ENABLED(CONFIG_PCI_IMX6)) clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); - - /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); } CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index e982ebe10814..d990f51ded71 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -443,8 +443,5 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], clks[IMX6SL_CLK_PLL2_PFD2]); - - /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); } CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init); diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c index 5a3e5a159e70..2b0a1fd5d7eb 100644 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ b/arch/arm/mach-imx/clk-imx6sx.c @@ -560,8 +560,5 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); - - /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); } CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init); diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index fe510fbd0c8c..d7f3b7b1d911 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -107,7 +107,7 @@ void imx_gpc_hwirq_unmask(unsigned int hwirq); void imx_anatop_init(void); void imx_anatop_pre_suspend(void); void imx_anatop_post_resume(void); -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); +int imx6_set_lpm(enum mxc_cpu_pwr_mode mode); void imx6q_set_int_mem_clk_lpm(bool enable); void imx6sl_set_wait_clk(bool enter); int imx_mmdc_get_ddr_type(void); diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c index 8e21ccc1eda2..353bb8774112 100644 --- a/arch/arm/mach-imx/cpuidle-imx6q.c +++ b/arch/arm/mach-imx/cpuidle-imx6q.c @@ -27,9 +27,9 @@ static int imx6q_enter_wait(struct cpuidle_device *dev, */ if (!spin_trylock(&master_lock)) goto idle; - imx6q_set_lpm(WAIT_UNCLOCKED); + imx6_set_lpm(WAIT_UNCLOCKED); cpu_do_idle(); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); spin_unlock(&master_lock); goto done; } diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c index 5742a9fd1ef2..8d866fb674a8 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sl.c +++ b/arch/arm/mach-imx/cpuidle-imx6sl.c @@ -16,7 +16,7 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - imx6q_set_lpm(WAIT_UNCLOCKED); + imx6_set_lpm(WAIT_UNCLOCKED); /* * Software workaround for ERR005311, see function * description for details. @@ -24,7 +24,7 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev, imx6sl_set_wait_clk(true); cpu_do_idle(); imx6sl_set_wait_clk(false); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); return index; } diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c index 2c9f1a8bf245..3c6672b3796b 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sx.c +++ b/arch/arm/mach-imx/cpuidle-imx6sx.c @@ -25,7 +25,7 @@ static int imx6sx_idle_finish(unsigned long val) static int imx6sx_enter_wait(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - imx6q_set_lpm(WAIT_UNCLOCKED); + imx6_set_lpm(WAIT_UNCLOCKED); switch (index) { case 1: @@ -50,7 +50,7 @@ static int imx6sx_enter_wait(struct cpuidle_device *dev, break; } - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); return index; } diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 6a7c6fc780cc..5858bde5a4e7 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -255,7 +255,7 @@ static void imx6q_enable_wb(bool enable) writel_relaxed(val, ccm_base + CCR); } -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) +int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) { u32 val = readl_relaxed(ccm_base + CLPCR); @@ -340,7 +340,7 @@ static int imx6q_pm_enter(suspend_state_t state) { switch (state) { case PM_SUSPEND_STANDBY: - imx6q_set_lpm(STOP_POWER_ON); + imx6_set_lpm(STOP_POWER_ON); imx6q_set_int_mem_clk_lpm(true); imx_gpc_pre_suspend(false); if (cpu_is_imx6sl()) @@ -350,10 +350,10 @@ static int imx6q_pm_enter(suspend_state_t state) if (cpu_is_imx6sl()) imx6sl_set_wait_clk(false); imx_gpc_post_resume(); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); break; case PM_SUSPEND_MEM: - imx6q_set_lpm(STOP_POWER_OFF); + imx6_set_lpm(STOP_POWER_OFF); imx6q_set_int_mem_clk_lpm(false); imx6q_enable_wb(true); /* @@ -373,7 +373,7 @@ static int imx6q_pm_enter(suspend_state_t state) imx6_enable_rbc(false); imx6q_enable_wb(false); imx6q_set_int_mem_clk_lpm(true); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); break; default: return -EINVAL; @@ -559,6 +559,8 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata WARN_ON(!ccm_base); + imx6_set_lpm(WAIT_CLOCKED); + if (IS_ENABLED(CONFIG_SUSPEND)) { ret = imx6q_suspend_init(socdata); if (ret) @@ -568,7 +570,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata /* * This is for SW workaround step #1 of ERR007265, see comments - * in imx6q_set_lpm for details of this errata. + * in imx6_set_lpm for details of this errata. * Force IOMUXC irq pending, so that the interrupt to GPC can be * used to deassert dsm_request signal when the signal gets * asserted unexpectedly. From f0b478b5d42ee9d925b45c22cbdc1ad4c90c3cf1 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 25 Apr 2015 23:37:12 +0800 Subject: [PATCH 07/44] ARM: imx6: let pm code map CCM block on its own We are about to move imx6 clock driver into drivers/clk, so let's get imx6 pm code map CCM block on its own rather than relying on clock driver to do the mapping. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 2 -- arch/arm/mach-imx/clk-imx6sl.c | 3 --- arch/arm/mach-imx/clk-imx6sx.c | 2 -- arch/arm/mach-imx/common.h | 1 - arch/arm/mach-imx/pm-imx6.c | 16 +++++++++------- 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 54ce0b30b9ad..5e88038ad51c 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -262,8 +262,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) base = of_iomap(np, 0); WARN_ON(!base); - imx6q_pm_set_ccm_base(base); - /* name reg shift width parent_names num_parents */ clk[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); clk[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index d990f51ded71..3aef26464110 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -288,9 +288,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) WARN_ON(!base); ccm_base = base; - /* Reuse imx6q pm code */ - imx6q_pm_set_ccm_base(base); - /* name reg shift width parent_names num_parents */ clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c index 2b0a1fd5d7eb..151460a95130 100644 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ b/arch/arm/mach-imx/clk-imx6sx.c @@ -268,8 +268,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) base = of_iomap(np, 0); WARN_ON(!base); - imx6q_pm_set_ccm_base(base); - /* name reg shift width parent_names num_parents */ clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index d7f3b7b1d911..d1e2873f807e 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -127,7 +127,6 @@ void imx6q_pm_init(void); void imx6dl_pm_init(void); void imx6sl_pm_init(void); void imx6sx_pm_init(void); -void imx6q_pm_set_ccm_base(void __iomem *base); #ifdef CONFIG_PM void imx51_pm_init(void); diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 5858bde5a4e7..27bc80dab2d8 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -89,6 +89,7 @@ struct imx6_pm_base { struct imx6_pm_socdata { u32 ddr_type; + const char *ccm_compat; const char *mmdc_compat; const char *src_compat; const char *iomuxc_compat; @@ -138,6 +139,7 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = { }; static const struct imx6_pm_socdata imx6q_pm_data __initconst = { + .ccm_compat = "fsl,imx6q-ccm", .mmdc_compat = "fsl,imx6q-mmdc", .src_compat = "fsl,imx6q-src", .iomuxc_compat = "fsl,imx6q-iomuxc", @@ -147,6 +149,7 @@ static const struct imx6_pm_socdata imx6q_pm_data __initconst = { }; static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { + .ccm_compat = "fsl,imx6q-ccm", .mmdc_compat = "fsl,imx6q-mmdc", .src_compat = "fsl,imx6q-src", .iomuxc_compat = "fsl,imx6dl-iomuxc", @@ -156,6 +159,7 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { }; static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { + .ccm_compat = "fsl,imx6sl-ccm", .mmdc_compat = "fsl,imx6sl-mmdc", .src_compat = "fsl,imx6sl-src", .iomuxc_compat = "fsl,imx6sl-iomuxc", @@ -165,6 +169,7 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { }; static const struct imx6_pm_socdata imx6sx_pm_data __initconst = { + .ccm_compat = "fsl,imx6sx-ccm", .mmdc_compat = "fsl,imx6sx-mmdc", .src_compat = "fsl,imx6sx-src", .iomuxc_compat = "fsl,imx6sx-iomuxc", @@ -392,11 +397,6 @@ static const struct platform_suspend_ops imx6q_pm_ops = { .valid = imx6q_pm_valid, }; -void __init imx6q_pm_set_ccm_base(void __iomem *base) -{ - ccm_base = base; -} - static int __init imx6_pm_get_base(struct imx6_pm_base *base, const char *compat) { @@ -482,8 +482,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) /* * ccm physical address is not used by asm code currently, - * so get ccm virtual address directly, as we already have - * it from ccm driver. + * so get ccm virtual address directly. */ pm_info->ccm_base.vbase = ccm_base; @@ -554,9 +553,12 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) static void __init imx6_pm_common_init(const struct imx6_pm_socdata *socdata) { + struct device_node *np; struct regmap *gpr; int ret; + np = of_find_compatible_node(NULL, NULL, socdata->ccm_compat); + ccm_base = of_iomap(np, 0); WARN_ON(!ccm_base); imx6_set_lpm(WAIT_CLOCKED); From 961dfd37fa165c8d5019648edcec966f28300959 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 26 Apr 2015 10:43:52 +0800 Subject: [PATCH 08/44] ARM: imx6: do not use cpu_is_xxx() in clock driver As we're about to move clock drivers out of arch/arm/mach-imx, cpu_is_xxx() shouldn't be used any more. Let's avoid the call by looking at the device tree machine compatible string to determine which SoC the clock driver is running on. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 5e88038ad51c..d0135c62d21a 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -121,6 +121,16 @@ static unsigned int share_count_ssi2; static unsigned int share_count_ssi3; static unsigned int share_count_mipi_core_cfg; +static inline int clk_on_imx6q(void) +{ + return of_machine_is_compatible("fsl,imx6q"); +} + +static inline int clk_on_imx6dl(void) +{ + return of_machine_is_compatible("fsl,imx6dl"); +} + static void __init imx6q_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -141,7 +151,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) WARN_ON(!base); /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ - if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) { + if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) { post_div_table[1].div = 1; post_div_table[2].div = 1; video_div_table[1].div = 1; @@ -248,7 +258,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20); - if (cpu_is_imx6dl()) { + if (clk_on_imx6dl()) { clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1); clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1); } @@ -273,7 +283,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); clk[IMX6QDL_CLK_ASRC_SEL] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); clk[IMX6QDL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); - if (cpu_is_imx6q()) { + if (clk_on_imx6q()) { clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); } @@ -380,7 +390,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); clk[IMX6QDL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); - if (cpu_is_imx6dl()) + if (clk_on_imx6dl()) clk[IMX6DL_CLK_I2C4] = imx_clk_gate2("i2c4", "ipg_per", base + 0x6c, 8); else clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); @@ -390,7 +400,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); - if (cpu_is_imx6dl()) + if (clk_on_imx6dl()) /* * The multiplexer and divider of imx6q clock gpu3d_shader get * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl. @@ -418,7 +428,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg); clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg); clk[IMX6QDL_CLK_MIPI_IPG] = imx_clk_gate2_shared("mipi_ipg", "ipg", base + 0x74, 16, &share_count_mipi_core_cfg); - if (cpu_is_imx6dl()) + if (clk_on_imx6dl()) /* * The multiplexer and divider of the imx6q clock gpu2d get * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl. @@ -468,7 +478,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) * The gpt_3m clock is not available on i.MX6Q TO1.0. Let's point it * to clock gpt_ipg_per to ease the gpt driver code. */ - if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) + if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER]; imx_check_clocks(clk, ARRAY_SIZE(clk)); @@ -480,7 +490,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL); if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) || - cpu_is_imx6dl()) { + clk_on_imx6dl()) { clk_set_parent(clk[IMX6QDL_CLK_LDB_DI0_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); clk_set_parent(clk[IMX6QDL_CLK_LDB_DI1_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); } From 3bec5f8184125ad4441905aee1856ef0a57b66b1 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 26 Apr 2015 13:33:39 +0800 Subject: [PATCH 09/44] ARM: imx: add clk-pllv1 type support Instead of calling cpu_is_xxx() in clk-pllv1 driver, let's add clk-pllv1 type support to handle the difference/quirk in particular SoC designs. Doing so will help get clk-pllv1 driver ready for being moved out of arch/arm/mach-imx folder. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx1.c | 4 ++-- arch/arm/mach-imx/clk-imx21.c | 4 ++-- arch/arm/mach-imx/clk-imx25.c | 4 ++-- arch/arm/mach-imx/clk-imx27.c | 4 ++-- arch/arm/mach-imx/clk-imx31.c | 6 +++--- arch/arm/mach-imx/clk-imx35.c | 4 ++-- arch/arm/mach-imx/clk-pllv1.c | 31 ++++++++++++++++++++++++------- arch/arm/mach-imx/clk.h | 13 +++++++++++-- 8 files changed, 48 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c index 5301d2ebb234..9e68351bb72c 100644 --- a/arch/arm/mach-imx/clk-imx1.c +++ b/arch/arm/mach-imx/clk-imx1.c @@ -50,9 +50,9 @@ static void __init _mx1_clocks_init(unsigned long fref) clk[IMX1_CLK_CLK16M] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17); clk[IMX1_CLK_CLK32_PREMULT] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1); clk[IMX1_CLK_PREM] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks)); - clk[IMX1_CLK_MPLL] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0); + clk[IMX1_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX1, "mpll", "clk32_premult", CCM_MPCTL0); clk[IMX1_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0); - clk[IMX1_CLK_SPLL] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0); + clk[IMX1_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX1, "spll", "prem", CCM_SPCTL0); clk[IMX1_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); clk[IMX1_CLK_MCU] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1); clk[IMX1_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1); diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c index facdf1ddd7f1..bc4254dd40a1 100644 --- a/arch/arm/mach-imx/clk-imx21.c +++ b/arch/arm/mach-imx/clk-imx21.c @@ -63,9 +63,9 @@ static void __init _mx21_clocks_init(unsigned long lref, unsigned long href) clk[IMX21_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 26, 3); clk[IMX21_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 29, 3); - clk[IMX21_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); + clk[IMX21_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "mpll", "mpll_sel", CCM_MPCTL0); - clk[IMX21_CLK_SPLL] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0); + clk[IMX21_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "spll", "spll_sel", CCM_SPCTL0); clk[IMX21_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "fclk", CCM_PCDR0, 12, 4); clk[IMX21_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6); diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index 9c2633a9de9f..485d090d2267 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -95,8 +95,8 @@ static int __init __mx25_clocks_init(unsigned long osc_rate, clk[dummy] = imx_clk_fixed("dummy", 0); clk[osc] = imx_clk_fixed("osc", osc_rate); - clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL)); - clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL)); + clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "mpll", "osc", ccm(CCM_MPCTL)); + clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "upll", "osc", ccm(CCM_UPCTL)); clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4); clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2); diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index aeb19982a36e..530af09c6bc7 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -54,8 +54,8 @@ static void __init _mx27_clocks_init(unsigned long fref) clk[IMX27_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3); clk[IMX27_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks)); clk[IMX27_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks)); - clk[IMX27_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); - clk[IMX27_CLK_SPLL] = imx_clk_pllv1("spll", "ckih_gate", CCM_SPCTL0); + clk[IMX27_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX27, "mpll", "mpll_sel", CCM_MPCTL0); + clk[IMX27_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX27, "spll", "ckih_gate", CCM_SPCTL0); clk[IMX27_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); clk[IMX27_CLK_MPLL_MAIN2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3); diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index 2aaccadb9e13..caa26ec32152 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c @@ -59,9 +59,9 @@ int __init mx31_clocks_init(unsigned long fref) clk[dummy] = imx_clk_fixed("dummy", 0); clk[ckih] = imx_clk_fixed("ckih", fref); clk[ckil] = imx_clk_fixed("ckil", 32768); - clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL); - clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL); - clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL); + clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "mpll", "ckih", base + MXC_CCM_MPCTL); + clk[spll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "spll", "ckih", base + MXC_CCM_SRPCTL); + clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "upll", "ckih", base + MXC_CCM_UPCTL); clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel)); clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3); clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3); diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index 5818521a8766..1a5c819d4664 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -92,8 +92,8 @@ int __init mx35_clocks_init(void) } clk[ckih] = imx_clk_fixed("ckih", 24000000); - clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL); - clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL); + clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL); + clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL); clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4); diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c index d21d14ca46c1..4e1cb9f39a29 100644 --- a/arch/arm/mach-imx/clk-pllv1.c +++ b/arch/arm/mach-imx/clk-pllv1.c @@ -26,13 +26,29 @@ struct clk_pllv1 { struct clk_hw hw; void __iomem *base; + enum imx_pllv1_type type; }; #define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk)) -static inline bool mfn_is_negative(unsigned int mfn) +static inline bool is_imx1_pllv1(struct clk_pllv1 *pll) { - return !cpu_is_mx1() && !cpu_is_mx21() && (mfn & MFN_SIGN); + return pll->type == IMX_PLLV1_IMX1; +} + +static inline bool is_imx21_pllv1(struct clk_pllv1 *pll) +{ + return pll->type == IMX_PLLV1_IMX21; +} + +static inline bool is_imx27_pllv1(struct clk_pllv1 *pll) +{ + return pll->type == IMX_PLLV1_IMX27; +} + +static inline bool mfn_is_negative(struct clk_pllv1 *pll, unsigned int mfn) +{ + return !is_imx1_pllv1(pll) && !is_imx21_pllv1(pll) && (mfn & MFN_SIGN); } static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, @@ -71,8 +87,8 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, * 2's complements number. * On i.MX27 the bit 9 is the sign bit. */ - if (mfn_is_negative(mfn)) { - if (cpu_is_mx27()) + if (mfn_is_negative(pll, mfn)) { + if (is_imx27_pllv1(pll)) mfn_abs = mfn & MFN_MASK; else mfn_abs = BIT(MFN_BITS) - mfn; @@ -85,7 +101,7 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, do_div(ll, mfd + 1); - if (mfn_is_negative(mfn)) + if (mfn_is_negative(pll, mfn)) ll = -ll; ll = (rate * mfi) + ll; @@ -97,8 +113,8 @@ static struct clk_ops clk_pllv1_ops = { .recalc_rate = clk_pllv1_recalc_rate, }; -struct clk *imx_clk_pllv1(const char *name, const char *parent, - void __iomem *base) +struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, + const char *parent, void __iomem *base) { struct clk_pllv1 *pll; struct clk *clk; @@ -109,6 +125,7 @@ struct clk *imx_clk_pllv1(const char *name, const char *parent, return ERR_PTR(-ENOMEM); pll->base = base; + pll->type = type; init.name = name; init.ops = &clk_pllv1_ops; diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index 6a07903a28bc..b5297e457a8e 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -10,8 +10,17 @@ void imx_check_clocks(struct clk *clks[], unsigned int count); extern void imx_cscmr1_fixup(u32 *val); -struct clk *imx_clk_pllv1(const char *name, const char *parent, - void __iomem *base); +enum imx_pllv1_type { + IMX_PLLV1_IMX1, + IMX_PLLV1_IMX21, + IMX_PLLV1_IMX25, + IMX_PLLV1_IMX27, + IMX_PLLV1_IMX31, + IMX_PLLV1_IMX35, +}; + +struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, + const char *parent, void __iomem *base); struct clk *imx_clk_pllv2(const char *name, const char *parent, void __iomem *base); From 0c831317e77b55612ffa1b402b262983bc7001d2 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 25 Apr 2015 18:43:45 +0800 Subject: [PATCH 10/44] ARM: imx: remove inclusions of platform headers With the cleanup done before, we now can simply define base address and irq as needed in clock driver, to get those platform header inclusions removed. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx1.c | 7 +++++-- arch/arm/mach-imx/clk-imx21.c | 7 +++++-- arch/arm/mach-imx/clk-imx25.c | 2 -- arch/arm/mach-imx/clk-imx27.c | 8 ++++++-- arch/arm/mach-imx/clk-imx31.c | 21 +++++++++++++++++---- arch/arm/mach-imx/clk-imx35.c | 20 +++++++++++++++++--- arch/arm/mach-imx/clk-imx51-imx53.c | 3 +-- arch/arm/mach-imx/clk-imx6q.c | 3 +-- arch/arm/mach-imx/clk-imx6sl.c | 1 - arch/arm/mach-imx/clk-imx6sx.c | 1 - arch/arm/mach-imx/clk-pllv1.c | 2 -- arch/arm/mach-imx/clk.h | 7 +++++++ 12 files changed, 59 insertions(+), 23 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c index 9e68351bb72c..c9812dbacac2 100644 --- a/arch/arm/mach-imx/clk-imx1.c +++ b/arch/arm/mach-imx/clk-imx1.c @@ -23,10 +23,13 @@ #include #include #include +#include #include "clk.h" -#include "common.h" -#include "hardware.h" + +#define MX1_CCM_BASE_ADDR 0x0021b000 +#define MX1_TIM1_BASE_ADDR 0x00220000 +#define MX1_TIM1_INT (NR_IRQS_LEGACY + 59) static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", }; static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c index bc4254dd40a1..0ca842cf4ca7 100644 --- a/arch/arm/mach-imx/clk-imx21.c +++ b/arch/arm/mach-imx/clk-imx21.c @@ -15,10 +15,13 @@ #include #include #include +#include #include "clk.h" -#include "common.h" -#include "hardware.h" + +#define MX21_CCM_BASE_ADDR 0x10027000 +#define MX21_GPT1_BASE_ADDR 0x10003000 +#define MX21_INT_GPT1 (NR_IRQS_LEGACY + 26) static void __iomem *ccm __initdata; diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index 485d090d2267..ec1a4c1dacf1 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -28,8 +28,6 @@ #include #include "clk.h" -#include "common.h" -#include "hardware.h" #define CCM_MPCTL 0x00 #define CCM_UPCTL 0x04 diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index 530af09c6bc7..df2dfc081c71 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -5,10 +5,14 @@ #include #include #include +#include +#include #include "clk.h" -#include "common.h" -#include "hardware.h" + +#define MX27_CCM_BASE_ADDR 0x10027000 +#define MX27_GPT1_BASE_ADDR 0x10003000 +#define MX27_INT_GPT1 (NR_IRQS_LEGACY + 26) static void __iomem *ccm __initdata; diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index caa26ec32152..a55290c1c264 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c @@ -21,12 +21,25 @@ #include #include #include +#include +#include #include "clk.h" -#include "common.h" -#include "crmregs-imx3.h" -#include "hardware.h" -#include "mx31.h" + +#define MX31_CCM_BASE_ADDR 0x53f80000 +#define MX31_GPT1_BASE_ADDR 0x53f90000 +#define MX31_INT_GPT (NR_IRQS_LEGACY + 29) + +#define MXC_CCM_CCMR 0x00 +#define MXC_CCM_PDR0 0x04 +#define MXC_CCM_PDR1 0x08 +#define MXC_CCM_MPCTL 0x10 +#define MXC_CCM_UPCTL 0x14 +#define MXC_CCM_SRPCTL 0x18 +#define MXC_CCM_CGR0 0x20 +#define MXC_CCM_CGR1 0x24 +#define MXC_CCM_CGR2 0x28 +#define MXC_CCM_PMCR0 0x5c static const char *mcu_main_sel[] = { "spll", "mpll", }; static const char *per_sel[] = { "per_div", "ipg", }; diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index 1a5c819d4664..133fda1dcb25 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -13,11 +13,25 @@ #include #include #include +#include +#include -#include "crmregs-imx3.h" #include "clk.h" -#include "common.h" -#include "hardware.h" + +#define MX35_CCM_BASE_ADDR 0x53f80000 +#define MX35_GPT1_BASE_ADDR 0x53f90000 +#define MX35_INT_GPT (NR_IRQS_LEGACY + 29) + +#define MXC_CCM_PDR0 0x04 +#define MX35_CCM_PDR2 0x0c +#define MX35_CCM_PDR3 0x10 +#define MX35_CCM_PDR4 0x14 +#define MX35_CCM_MPCTL 0x1c +#define MX35_CCM_PPCTL 0x20 +#define MX35_CCM_CGR0 0x2c +#define MX35_CCM_CGR1 0x30 +#define MX35_CCM_CGR2 0x34 +#define MX35_CCM_CGR3 0x38 struct arm_ahb_div { unsigned char arm, ahb, sel; diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index f341464fe7e9..a7e4f394be0d 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -16,11 +16,10 @@ #include #include #include +#include #include #include "clk.h" -#include "common.h" -#include "hardware.h" #define MX51_DPLL1_BASE 0x83f80000 #define MX51_DPLL2_BASE 0x83f84000 diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index d0135c62d21a..128f8871cbd8 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -19,11 +19,10 @@ #include #include #include +#include #include #include "clk.h" -#include "common.h" -#include "hardware.h" static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index 3aef26464110..a0d4cf26cfa9 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -16,7 +16,6 @@ #include #include "clk.h" -#include "common.h" #define CCSR 0xc #define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2) diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c index 151460a95130..bf04ad5056d4 100644 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ b/arch/arm/mach-imx/clk-imx6sx.c @@ -21,7 +21,6 @@ #include #include "clk.h" -#include "common.h" #define CCDR 0x4 #define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16) diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c index 4e1cb9f39a29..c34ad8a611dd 100644 --- a/arch/arm/mach-imx/clk-pllv1.c +++ b/arch/arm/mach-imx/clk-pllv1.c @@ -6,8 +6,6 @@ #include #include "clk.h" -#include "common.h" -#include "hardware.h" /** * pll v1 diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index b5297e457a8e..6bae5374dc83 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -6,6 +6,13 @@ extern spinlock_t imx_ccm_lock; +/* + * This is a stop-gap solution for clock drivers like imx1/imx21 which call + * mxc_timer_init() to initialize timer for non-DT boot. It can be removed + * when these legacy non-DT support is converted or dropped. + */ +void mxc_timer_init(unsigned long pbase, int irq); + void imx_check_clocks(struct clk *clks[], unsigned int count); extern void imx_cscmr1_fixup(u32 *val); From 11f68120095d6040abd2eb37bf21bb9450646304 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 26 Apr 2015 21:54:29 +0800 Subject: [PATCH 11/44] ARM: imx: move clock drivers into drivers/clk After the cleanup on clock drivers, they are now ready to be moved into drivers/clk. Let's move them into drivers/clk/imx folder. Signed-off-by: Shawn Guo Acked-by: Stephen Boyd --- arch/arm/mach-imx/Makefile | 27 ++++++++----------- drivers/clk/Makefile | 1 + drivers/clk/imx/Makefile | 25 +++++++++++++++++ .../mach-imx => drivers/clk/imx}/clk-busy.c | 0 .../mach-imx => drivers/clk/imx}/clk-cpu.c | 0 .../clk/imx}/clk-fixup-div.c | 0 .../clk/imx}/clk-fixup-mux.c | 0 .../clk/imx}/clk-gate-exclusive.c | 0 .../mach-imx => drivers/clk/imx}/clk-gate2.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx1.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx21.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx25.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx27.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx31.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx35.c | 0 .../clk/imx}/clk-imx51-imx53.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx6q.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx6sl.c | 0 .../mach-imx => drivers/clk/imx}/clk-imx6sx.c | 0 .../mach-imx => drivers/clk/imx}/clk-pfd.c | 0 .../mach-imx => drivers/clk/imx}/clk-pllv1.c | 0 .../mach-imx => drivers/clk/imx}/clk-pllv2.c | 0 .../mach-imx => drivers/clk/imx}/clk-pllv3.c | 0 .../mach-imx => drivers/clk/imx}/clk-vf610.c | 0 {arch/arm/mach-imx => drivers/clk/imx}/clk.c | 0 {arch/arm/mach-imx => drivers/clk/imx}/clk.h | 0 26 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 drivers/clk/imx/Makefile rename {arch/arm/mach-imx => drivers/clk/imx}/clk-busy.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-cpu.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-fixup-div.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-fixup-mux.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-gate-exclusive.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-gate2.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx1.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx21.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx25.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx27.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx31.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx35.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx51-imx53.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx6q.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx6sl.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-imx6sx.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-pfd.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-pllv1.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-pllv2.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-pllv3.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk-vf610.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk.c (100%) rename {arch/arm/mach-imx => drivers/clk/imx}/clk.h (100%) diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 3244cf1d2773..0622cede2551 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,23 +1,18 @@ obj-y := time.o cpu.o system.o irq-common.o -obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o -obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o +obj-$(CONFIG_SOC_IMX1) += mm-imx1.o +obj-$(CONFIG_SOC_IMX21) += mm-imx21.o -obj-$(CONFIG_SOC_IMX25) += clk-imx25.o cpu-imx25.o mach-imx25.o +obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o -obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o +obj-$(CONFIG_SOC_IMX27) += mm-imx27.o ehci-imx27.o -obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o -obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o +obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o +obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o ehci-imx35.o pm-imx3.o imx5-pm-$(CONFIG_PM) += pm-imx5.o -obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o clk-cpu.o $(imx5-pm-y) - -obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ - clk-pfd.o clk-busy.o clk.o \ - clk-fixup-div.o clk-fixup-mux.o \ - clk-gate-exclusive.o +obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o $(imx5-pm-y) obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o @@ -87,9 +82,9 @@ AFLAGS_headsmp.o :=-Wa,-march=armv7-a obj-$(CONFIG_SMP) += headsmp.o platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o endif -obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o -obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o -obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o mach-imx6sx.o +obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o +obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o +obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o ifeq ($(CONFIG_SUSPEND),y) AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a @@ -101,7 +96,7 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o obj-$(CONFIG_SOC_IMX51) += mach-imx51.o obj-$(CONFIG_SOC_IMX53) += mach-imx53.o -obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o +obj-$(CONFIG_SOC_VF610) += mach-vf610.o obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 3d00c25382c5..d7a507f0c44c 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ obj-$(CONFIG_ARCH_HIP04) += hisilicon/ obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/ +obj-$(CONFIG_ARCH_MXC) += imx/ obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_ARCH_MMP) += mmp/ diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile new file mode 100644 index 000000000000..8be0a1c49a5e --- /dev/null +++ b/drivers/clk/imx/Makefile @@ -0,0 +1,25 @@ + +obj-y += \ + clk.o \ + clk-busy.o \ + clk-cpu.o \ + clk-fixup-div.o \ + clk-fixup-mux.o \ + clk-gate-exclusive.o \ + clk-gate2.o \ + clk-pllv1.o \ + clk-pllv2.o \ + clk-pllv3.o \ + clk-pfd.o + +obj-$(CONFIG_SOC_IMX1) += clk-imx1.o +obj-$(CONFIG_SOC_IMX21) += clk-imx21.o +obj-$(CONFIG_SOC_IMX25) += clk-imx25.o +obj-$(CONFIG_SOC_IMX27) += clk-imx27.o +obj-$(CONFIG_SOC_IMX31) += clk-imx31.o +obj-$(CONFIG_SOC_IMX35) += clk-imx35.o +obj-$(CONFIG_SOC_IMX5) += clk-imx51-imx53.o +obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o +obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o +obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o +obj-$(CONFIG_SOC_VF610) += clk-vf610.o diff --git a/arch/arm/mach-imx/clk-busy.c b/drivers/clk/imx/clk-busy.c similarity index 100% rename from arch/arm/mach-imx/clk-busy.c rename to drivers/clk/imx/clk-busy.c diff --git a/arch/arm/mach-imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c similarity index 100% rename from arch/arm/mach-imx/clk-cpu.c rename to drivers/clk/imx/clk-cpu.c diff --git a/arch/arm/mach-imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c similarity index 100% rename from arch/arm/mach-imx/clk-fixup-div.c rename to drivers/clk/imx/clk-fixup-div.c diff --git a/arch/arm/mach-imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c similarity index 100% rename from arch/arm/mach-imx/clk-fixup-mux.c rename to drivers/clk/imx/clk-fixup-mux.c diff --git a/arch/arm/mach-imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c similarity index 100% rename from arch/arm/mach-imx/clk-gate-exclusive.c rename to drivers/clk/imx/clk-gate-exclusive.c diff --git a/arch/arm/mach-imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c similarity index 100% rename from arch/arm/mach-imx/clk-gate2.c rename to drivers/clk/imx/clk-gate2.c diff --git a/arch/arm/mach-imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c similarity index 100% rename from arch/arm/mach-imx/clk-imx1.c rename to drivers/clk/imx/clk-imx1.c diff --git a/arch/arm/mach-imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c similarity index 100% rename from arch/arm/mach-imx/clk-imx21.c rename to drivers/clk/imx/clk-imx21.c diff --git a/arch/arm/mach-imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c similarity index 100% rename from arch/arm/mach-imx/clk-imx25.c rename to drivers/clk/imx/clk-imx25.c diff --git a/arch/arm/mach-imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c similarity index 100% rename from arch/arm/mach-imx/clk-imx27.c rename to drivers/clk/imx/clk-imx27.c diff --git a/arch/arm/mach-imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c similarity index 100% rename from arch/arm/mach-imx/clk-imx31.c rename to drivers/clk/imx/clk-imx31.c diff --git a/arch/arm/mach-imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c similarity index 100% rename from arch/arm/mach-imx/clk-imx35.c rename to drivers/clk/imx/clk-imx35.c diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c similarity index 100% rename from arch/arm/mach-imx/clk-imx51-imx53.c rename to drivers/clk/imx/clk-imx51-imx53.c diff --git a/arch/arm/mach-imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c similarity index 100% rename from arch/arm/mach-imx/clk-imx6q.c rename to drivers/clk/imx/clk-imx6q.c diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c similarity index 100% rename from arch/arm/mach-imx/clk-imx6sl.c rename to drivers/clk/imx/clk-imx6sl.c diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c similarity index 100% rename from arch/arm/mach-imx/clk-imx6sx.c rename to drivers/clk/imx/clk-imx6sx.c diff --git a/arch/arm/mach-imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c similarity index 100% rename from arch/arm/mach-imx/clk-pfd.c rename to drivers/clk/imx/clk-pfd.c diff --git a/arch/arm/mach-imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c similarity index 100% rename from arch/arm/mach-imx/clk-pllv1.c rename to drivers/clk/imx/clk-pllv1.c diff --git a/arch/arm/mach-imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c similarity index 100% rename from arch/arm/mach-imx/clk-pllv2.c rename to drivers/clk/imx/clk-pllv2.c diff --git a/arch/arm/mach-imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c similarity index 100% rename from arch/arm/mach-imx/clk-pllv3.c rename to drivers/clk/imx/clk-pllv3.c diff --git a/arch/arm/mach-imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c similarity index 100% rename from arch/arm/mach-imx/clk-vf610.c rename to drivers/clk/imx/clk-vf610.c diff --git a/arch/arm/mach-imx/clk.c b/drivers/clk/imx/clk.c similarity index 100% rename from arch/arm/mach-imx/clk.c rename to drivers/clk/imx/clk.c diff --git a/arch/arm/mach-imx/clk.h b/drivers/clk/imx/clk.h similarity index 100% rename from arch/arm/mach-imx/clk.h rename to drivers/clk/imx/clk.h From cf20968a78c8cc8c1c06f6693a0059d27548656e Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 26 Apr 2015 21:58:12 +0800 Subject: [PATCH 12/44] MAINTAINERS: add new folders into IMX entry Add new created folders drivers/clk/imx/ and include/soc/imx/ into IMX entry. Signed-off-by: Shawn Guo --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 2e5bbc0d68b2..4e8fa0f6baae 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1039,6 +1039,8 @@ F: arch/arm/mach-imx/ F: arch/arm/mach-mxs/ F: arch/arm/boot/dts/imx* F: arch/arm/configs/imx*_defconfig +F: drivers/clk/imx/ +F: include/soc/imx/ ARM/FREESCALE VYBRID ARM ARCHITECTURE M: Shawn Guo From de8e434d09f253369621e994da1833703c5c51d6 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 28 Apr 2015 09:19:02 +0800 Subject: [PATCH 13/44] ARM: imx: drop epit timer initialization from imx35 clock driver EPIT provides another timer implementation besides the default GPT timer. The imx35 clock driver will use EPIT timer when option CONFIG_MXC_USE_EPIT is enabled. However, initializing timers from clock driver is a workaround solution and causes problem when we move clock drivers into driver/clk. Let's simply drop the EPIT initialization from there. If people really want this EPIT option, EPIT timer driver needs to be reworked to do the initialization in a standard way - use CLOCKSOURCE_OF_DECLARE() with device tree support. Reported-by: kbuild test robot Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx35.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c index 133fda1dcb25..f2f3b8164f7b 100644 --- a/drivers/clk/imx/clk-imx35.c +++ b/drivers/clk/imx/clk-imx35.c @@ -293,11 +293,7 @@ int __init mx35_clocks_init(void) imx_print_silicon_rev("i.MX35", mx35_revision()); -#ifdef CONFIG_MXC_USE_EPIT - epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); -#else mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT); -#endif return 0; } From 35e2916f70e3be767c5c8ef6cc80bc5398b8914c Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 29 Apr 2015 13:07:03 +0800 Subject: [PATCH 14/44] ARM: imx6: initialize CCM_CLPCR_LPM into RUN mode earlier Commit 4631960d26da ("ARM: imx6: set initial power mode in pm function") moves imx6_set_lpm() from clock init function into imx6_pm_common_init(). This causes a hang when cpuidle support is enabled. The reason for that is ARM core clock is shut down unexpectedly by WAIT mode. It happens with the following call stack: cpuidle_register_governor() cpuidle_switch_governor() cpuidle_uninstall_idle_handler() synchronize_sched() wait_rcu_gp() wait_for_completion() When wait_for_completion() is called as above, all cores are idle/WFI. Hence, the reset value of CCM_CLPCR_LPM - WAIT mode, will trigger a hardware shutdown of the ARM core clock. To fix the regression, we need to ensure that CCM_CLPCR_LPM is initialized into RUN mode earlier than cpuidle governor registration, which is a postcore_initcall. This patch creates function imx6_pm_ccm_init() to map CCM block and initialize CCM_CLPCR_LPM into RUN mode, and have the function called from machine .init_irq hook, which should be early enough. Reported-by: Kevin Hilman Fixes: 8fb76a07e2cb ("ARM: imx6: set initial power mode in pm function") Tested-by: Kevin Hilman Tested-by: Tyler Baker Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 1 + arch/arm/mach-imx/mach-imx6q.c | 1 + arch/arm/mach-imx/mach-imx6sl.c | 1 + arch/arm/mach-imx/mach-imx6sx.c | 1 + arch/arm/mach-imx/pm-imx6.c | 28 ++++++++++++++++++---------- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index d1e2873f807e..fbd86f1b7f3b 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -123,6 +123,7 @@ static inline void v7_cpu_resume(void) {} static inline void imx6_suspend(void __iomem *ocram_vbase) {} #endif +void imx6_pm_ccm_init(const char *ccm_compat); void imx6q_pm_init(void); void imx6dl_pm_init(void); void imx6sl_pm_init(void); diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 3ab61549ce0f..9602cc12d2f1 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -393,6 +393,7 @@ static void __init imx6q_init_irq(void) imx_init_l2cache(); imx_src_init(); irqchip_init(); + imx6_pm_ccm_init("fsl,imx6q-ccm"); } static const char * const imx6q_dt_compat[] __initconst = { diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index 12a1b098fc6a..300326373166 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c @@ -66,6 +66,7 @@ static void __init imx6sl_init_irq(void) imx_init_l2cache(); imx_src_init(); irqchip_init(); + imx6_pm_ccm_init("fsl,imx6sl-ccm"); } static const char * const imx6sl_dt_compat[] __initconst = { diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c index f17b7004c24b..6a0b0614de29 100644 --- a/arch/arm/mach-imx/mach-imx6sx.c +++ b/arch/arm/mach-imx/mach-imx6sx.c @@ -86,6 +86,7 @@ static void __init imx6sx_init_irq(void) imx_init_l2cache(); imx_src_init(); irqchip_init(); + imx6_pm_ccm_init("fsl,imx6sx-ccm"); } static void __init imx6sx_init_late(void) diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 27bc80dab2d8..b01650d94f91 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -89,7 +89,6 @@ struct imx6_pm_base { struct imx6_pm_socdata { u32 ddr_type; - const char *ccm_compat; const char *mmdc_compat; const char *src_compat; const char *iomuxc_compat; @@ -139,7 +138,6 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = { }; static const struct imx6_pm_socdata imx6q_pm_data __initconst = { - .ccm_compat = "fsl,imx6q-ccm", .mmdc_compat = "fsl,imx6q-mmdc", .src_compat = "fsl,imx6q-src", .iomuxc_compat = "fsl,imx6q-iomuxc", @@ -149,7 +147,6 @@ static const struct imx6_pm_socdata imx6q_pm_data __initconst = { }; static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { - .ccm_compat = "fsl,imx6q-ccm", .mmdc_compat = "fsl,imx6q-mmdc", .src_compat = "fsl,imx6q-src", .iomuxc_compat = "fsl,imx6dl-iomuxc", @@ -159,7 +156,6 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { }; static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { - .ccm_compat = "fsl,imx6sl-ccm", .mmdc_compat = "fsl,imx6sl-mmdc", .src_compat = "fsl,imx6sl-src", .iomuxc_compat = "fsl,imx6sl-iomuxc", @@ -169,7 +165,6 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { }; static const struct imx6_pm_socdata imx6sx_pm_data __initconst = { - .ccm_compat = "fsl,imx6sx-ccm", .mmdc_compat = "fsl,imx6sx-mmdc", .src_compat = "fsl,imx6sx-src", .iomuxc_compat = "fsl,imx6sx-iomuxc", @@ -553,16 +548,11 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) static void __init imx6_pm_common_init(const struct imx6_pm_socdata *socdata) { - struct device_node *np; struct regmap *gpr; int ret; - np = of_find_compatible_node(NULL, NULL, socdata->ccm_compat); - ccm_base = of_iomap(np, 0); WARN_ON(!ccm_base); - imx6_set_lpm(WAIT_CLOCKED); - if (IS_ENABLED(CONFIG_SUSPEND)) { ret = imx6q_suspend_init(socdata); if (ret) @@ -583,6 +573,24 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata IMX6Q_GPR1_GINT); } +void __init imx6_pm_ccm_init(const char *ccm_compat) +{ + struct device_node *np; + u32 val; + + np = of_find_compatible_node(NULL, NULL, ccm_compat); + ccm_base = of_iomap(np, 0); + BUG_ON(!ccm_base); + + /* + * Initialize CCM_CLPCR_LPM into RUN mode to avoid ARM core + * clock being shut down unexpectedly by WAIT mode. + */ + val = readl_relaxed(ccm_base + CLPCR); + val &= ~BM_CLPCR_LPM; + writel_relaxed(val, ccm_base + CLPCR); +} + void __init imx6q_pm_init(void) { imx6_pm_common_init(&imx6q_pm_data); From 7a5568ce08c6f0390c73cc62a6f124e9073ebc97 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Fri, 8 May 2015 00:16:51 +0800 Subject: [PATCH 15/44] ARM: imx: using unsigned variable for do_div MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The definition of do_div uses unsigned long long variable as its first parameter, better to pass a u64 variable as first parameter when calling do_div function. Signed-off-by: Anson Huang Acked-by: Uwe Kleine-König Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-pllv3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index 641ebc508920..260035be11ac 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -215,7 +215,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long max_rate = parent_rate * 54; u32 div; u32 mfn, mfd = 1000000; - s64 temp64; + u64 temp64; if (rate > max_rate) rate = max_rate; @@ -239,7 +239,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long max_rate = parent_rate * 54; u32 val, div; u32 mfn, mfd = 1000000; - s64 temp64; + u64 temp64; if (rate < min_rate || rate > max_rate) return -EINVAL; From 9b589a83cf1b2bb89b6e4af7ffafe5cda33e756c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 27 Apr 2015 21:51:39 +0900 Subject: [PATCH 16/44] ARM: imx: Constify irq_domain_ops The irq_domain_ops are not modified by the driver and the irqdomain core code accepts pointer to a const data. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Shawn Guo --- arch/arm/mach-imx/gpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 4d60005e9277..9051dc02dc79 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -227,7 +227,7 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain, return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args); } -static struct irq_domain_ops imx_gpc_domain_ops = { +static const struct irq_domain_ops imx_gpc_domain_ops = { .xlate = imx_gpc_domain_xlate, .alloc = imx_gpc_domain_alloc, .free = irq_domain_free_irqs_common, From d0185d96c6c61871f090fe51116b6d81b3dd74b9 Mon Sep 17 00:00:00 2001 From: Shenwei Wang Date: Wed, 29 Apr 2015 16:18:37 -0500 Subject: [PATCH 17/44] ARM: imx: Remove the duplicated function declaration Removed the duplicated function declaration of mxc_timer_init which was already declared in drivers/clk/imx/clk.h. Signed-off-by: Shenwei Wang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index fbd86f1b7f3b..1f800b9a63f5 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -44,7 +44,6 @@ void imx27_soc_init(void); void imx31_soc_init(void); void imx35_soc_init(void); void epit_timer_init(void __iomem *base, int irq); -void mxc_timer_init(unsigned long, int); int mx1_clocks_init(unsigned long fref); int mx21_clocks_init(unsigned long lref, unsigned long fref); int mx27_clocks_init(unsigned long fref); From 65d0a16dce3c2564b21c13d8492af48959a3c3c3 Mon Sep 17 00:00:00 2001 From: Shenwei Wang Date: Wed, 29 Apr 2015 16:40:27 -0500 Subject: [PATCH 18/44] ARM: imx: Correct the comments in time.c The comments were corrected as the following to reflect the real situation of Freescale MXC timer IP block. There are totally 4 version of the timer on Freescale i.MX SoCs. Signed-off-by: Shenwei Wang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index acb1ff577cda..ab5ee1c445f3 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -38,9 +38,11 @@ #include "hardware.h" /* - * There are 2 versions of the timer hardware on Freescale MXC hardware. - * Version 1: MX1/MXL, MX21, MX27. - * Version 2: MX25, MX31, MX35, MX37, MX51 + * There are 4 versions of the timer hardware on Freescale MXC hardware. + * - MX1/MXL + * - MX21, MX27. + * - MX25, MX31, MX35, MX37, MX51, MX6Q(rev1.0) + * - MX6DL, MX6SX, MX6Q(rev1.1+) */ /* defines common for all i.MX */ From a39973a4fdad7be1edaf276334b3a1907fe31025 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 29 Apr 2015 18:34:42 -0300 Subject: [PATCH 19/44] clk: imx: clk-cpu: Include "clk.h" header file Include the "clk.h" header file to fix the following sparse warning: drivers/clk/imx/clk-cpu.c:77:12: warning: symbol 'imx_clk_cpu' was not declared. Should it be static? Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c index aa1c345e2a19..9d46eac87f45 100644 --- a/drivers/clk/imx/clk-cpu.c +++ b/drivers/clk/imx/clk-cpu.c @@ -12,6 +12,7 @@ #include #include #include +#include "clk.h" struct clk_cpu { struct clk_hw hw; From 666c884418f7b314b3ddf3214ec0ad0aadf81c84 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 2 Apr 2015 19:23:32 -0300 Subject: [PATCH 20/44] ARM: imx: mmdc: Include "common.h" header file Include the "common.h" header file to fix the following sparse warning: arch/arm/mach-imx/mmdc.c:66:5: warning: symbol 'imx_mmdc_get_ddr_type' was not declared. Should it be static? Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mmdc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index 0411f0664c15..db9621c718ec 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -17,6 +17,8 @@ #include #include +#include "common.h" + #define MMDC_MAPSR 0x404 #define BP_MMDC_MAPSR_PSD 0 #define BP_MMDC_MAPSR_PSS 4 From 52d7aec2b8831deae7c0010ed24664d3544e0098 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 6 May 2015 23:16:07 +0800 Subject: [PATCH 21/44] ARM: imx7d: add low level debug uart support Add low level uart debug support for imx7d Signed-off-by: Frank Li Signed-off-by: Bai Ping Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/Kconfig.debug | 13 +++++++++++-- arch/arm/include/debug/imx-uart.h | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 0c12ffb155a2..fe5e1cbda811 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -410,6 +410,13 @@ choice Say Y here if you want kernel low-level debugging support on i.MX6SX. + config DEBUG_IMX7D_UART + bool "i.MX7D Debug UART" + depends on SOC_IMX7D + help + Say Y here if you want kernel low-level debugging support + on i.MX7D. + config DEBUG_KEYSTONE_UART0 bool "Kernel low-level debugging on KEYSTONE2 using UART0" depends on ARCH_KEYSTONE @@ -1231,7 +1238,8 @@ config DEBUG_IMX_UART_PORT DEBUG_IMX53_UART || \ DEBUG_IMX6Q_UART || \ DEBUG_IMX6SL_UART || \ - DEBUG_IMX6SX_UART + DEBUG_IMX6SX_UART || \ + DEBUG_IMX7D_UART default 1 depends on ARCH_MXC help @@ -1281,7 +1289,8 @@ config DEBUG_LL_INCLUDE DEBUG_IMX53_UART ||\ DEBUG_IMX6Q_UART || \ DEBUG_IMX6SL_UART || \ - DEBUG_IMX6SX_UART + DEBUG_IMX6SX_UART || \ + DEBUG_IMX7D_UART default "debug/ks8695.S" if DEBUG_KS8695_UART default "debug/msm.S" if DEBUG_QCOM_UARTDM default "debug/netx.S" if DEBUG_NETX_UART diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h index 032a316eb802..66f736f74684 100644 --- a/arch/arm/include/debug/imx-uart.h +++ b/arch/arm/include/debug/imx-uart.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Freescale Semiconductor, Inc. + * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -90,6 +90,16 @@ #define IMX6SX_UART_BASE_ADDR(n) IMX6SX_UART##n##_BASE_ADDR #define IMX6SX_UART_BASE(n) IMX6SX_UART_BASE_ADDR(n) +#define IMX7D_UART1_BASE_ADDR 0x30860000 +#define IMX7D_UART2_BASE_ADDR 0x30890000 +#define IMX7D_UART3_BASE_ADDR 0x30880000 +#define IMX7D_UART4_BASE_ADDR 0x30a60000 +#define IMX7D_UART5_BASE_ADDR 0x30a70000 +#define IMX7D_UART6_BASE_ADDR 0x30a80000 +#define IMX7D_UART7_BASE_ADDR 0x30a90000 +#define IMX7D_UART_BASE_ADDR(n) IMX7D_UART##n##_BASE_ADDR +#define IMX7D_UART_BASE(n) IMX7D_UART_BASE_ADDR(n) + #define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT) #ifdef CONFIG_DEBUG_IMX1_UART @@ -114,6 +124,9 @@ #define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SL) #elif defined(CONFIG_DEBUG_IMX6SX_UART) #define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SX) +#elif defined(CONFIG_DEBUG_IMX7D_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX7D) + #endif #endif /* __DEBUG_IMX_UART_H */ From 5739b919cf6c1395f3f58dd7759bf0555fb68769 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Fri, 8 May 2015 01:35:55 +0800 Subject: [PATCH 22/44] ARM: imx: add msl support for imx7d Add i.MX7D MSL support. Signed-off-by: Anson Huang Signed-off-by: Frank Li Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 7 ++++++ arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/anatop.c | 5 +++- arch/arm/mach-imx/cpu.c | 3 +++ arch/arm/mach-imx/mach-imx7d.c | 43 ++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/mxc.h | 8 ++++++- 6 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-imx/mach-imx7d.c diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 3a3d3e9d7bfd..1d8707885c57 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -582,6 +582,13 @@ config SOC_IMX6SX help This enables support for Freescale i.MX6 SoloX processor. +config SOC_IMX7D + bool "i.MX7 Dual support" + select PINCTRL_IMX7D + select ARM_GIC + help + This enables support for Freescale i.MX7 Dual processor. + config SOC_VF610 bool "Vybrid Family VF610 support" select IRQ_DOMAIN_HIERARCHY diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 0622cede2551..40df12af5036 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -85,6 +85,7 @@ endif obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o +obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o ifeq ($(CONFIG_SUSPEND),y) AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 7f262fe4ba77..231bb250c571 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Freescale Semiconductor, Inc. + * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -28,6 +28,7 @@ #define ANADIG_USB2_CHRG_DETECT 0x210 #define ANADIG_DIGPROG 0x260 #define ANADIG_DIGPROG_IMX6SL 0x280 +#define ANADIG_DIGPROG_IMX7D 0x800 #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 #define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8 @@ -121,6 +122,8 @@ void __init imx_init_revision_from_anatop(void) WARN_ON(!anatop_base); if (of_device_is_compatible(np, "fsl,imx6sl-anatop")) offset = ANADIG_DIGPROG_IMX6SL; + if (of_device_is_compatible(np, "fsl,imx7d-anatop")) + offset = ANADIG_DIGPROG_IMX7D; digprog = readl_relaxed(anatop_base + offset); iounmap(anatop_base); diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index df42c14ff749..a7fa92a7b1d7 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -130,6 +130,9 @@ struct device * __init imx_soc_device_init(void) case MXC_CPU_IMX6Q: soc_id = "i.MX6Q"; break; + case MXC_CPU_IMX7D: + soc_id = "i.MX7D"; + break; default: soc_id = "Unknown"; } diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c new file mode 100644 index 000000000000..4d4a19099a43 --- /dev/null +++ b/arch/arm/mach-imx/mach-imx7d.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include + +#include "common.h" + +static void __init imx7d_init_machine(void) +{ + struct device *parent; + + parent = imx_soc_device_init(); + if (parent == NULL) + pr_warn("failed to initialize soc device\n"); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + imx_anatop_init(); +} + +static void __init imx7d_init_irq(void) +{ + imx_init_revision_from_anatop(); + imx_src_init(); + irqchip_init(); +} + +static const char *imx7d_dt_compat[] __initconst = { + "fsl,imx7d", + NULL, +}; + +DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)") + .init_irq = imx7d_init_irq, + .init_machine = imx7d_init_machine, + .dt_compat = imx7d_dt_compat, +MACHINE_END diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 8726051fcfca..c4436d4fd6fd 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2007, 2010-2015 Freescale Semiconductor, Inc. * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) * * This program is free software; you can redistribute it and/or @@ -38,6 +38,7 @@ #define MXC_CPU_IMX6DL 0x61 #define MXC_CPU_IMX6SX 0x62 #define MXC_CPU_IMX6Q 0x63 +#define MXC_CPU_IMX7D 0x72 #define IMX_DDR_TYPE_LPDDR2 1 @@ -169,6 +170,11 @@ static inline bool cpu_is_imx6q(void) return __mxc_cpu_type == MXC_CPU_IMX6Q; } +static inline bool cpu_is_imx7d(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX7D; +} + struct cpu_op { u32 cpu_rate; }; From 1579c7b9fe0105a523440ec13b0c59da53c880e3 Mon Sep 17 00:00:00 2001 From: Martin Fuzzey Date: Tue, 12 May 2015 15:31:03 +0200 Subject: [PATCH 23/44] ARM: imx53: Set DDR pins to high impedance when in suspend to RAM. In order to save power the DDR pins should be put into high impedance when in suspend to RAM. This requires manually requesting self refresh (rather than using the automatic mode implemented by the CCM / ESDCTL), followed by reconfiguring the IOMUXC. Of course the code to do this cannot itself run from DDR so the code is copied to and executed from internal memory. In my tests using a custom i.MX53 board with LPDDR2 RAM this reduced the suspend power consumption from 200mW to 60mW. Signed-off-by: Martin Fuzzey Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/common.h | 4 + arch/arm/mach-imx/pm-imx5.c | 190 +++++++++++++++++++++++++++++- arch/arm/mach-imx/suspend-imx53.S | 139 ++++++++++++++++++++++ 4 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-imx/suspend-imx53.S diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 40df12af5036..799e65a530be 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -90,6 +90,7 @@ obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o ifeq ($(CONFIG_SUSPEND),y) AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o +obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o endif obj-$(CONFIG_SOC_IMX6) += pm-imx6.o diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 1f800b9a63f5..21e4e8697a58 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -116,9 +116,13 @@ int imx_cpu_kill(unsigned int cpu); #ifdef CONFIG_SUSPEND void v7_cpu_resume(void); +void imx53_suspend(void __iomem *ocram_vbase); +extern const u32 imx53_suspend_sz; void imx6_suspend(void __iomem *ocram_vbase); #else static inline void v7_cpu_resume(void) {} +static inline void imx53_suspend(void __iomem *ocram_vbase) {} +static const u32 imx53_suspend_sz; static inline void imx6_suspend(void __iomem *ocram_vbase) {} #endif diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index b04025592d94..a8d00b9c9236 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -13,7 +13,14 @@ #include #include #include + +#include +#include +#include +#include + #include +#include #include #include @@ -49,10 +56,50 @@ */ #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF +struct imx5_suspend_io_state { + u32 offset; + u32 clear; + u32 set; + u32 saved_value; +}; + struct imx5_pm_data { phys_addr_t ccm_addr; phys_addr_t cortex_addr; phys_addr_t gpc_addr; + phys_addr_t m4if_addr; + phys_addr_t iomuxc_addr; + void (*suspend_asm)(void __iomem *ocram_vbase); + const u32 *suspend_asm_sz; + const struct imx5_suspend_io_state *suspend_io_config; + int suspend_io_count; +}; + +static const struct imx5_suspend_io_state imx53_suspend_io_config[] = { +#define MX53_DSE_HIGHZ_MASK (0x7 << 19) + {.offset = 0x584, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM0 */ + {.offset = 0x594, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM1 */ + {.offset = 0x560, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM2 */ + {.offset = 0x554, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM3 */ + {.offset = 0x574, .clear = MX53_DSE_HIGHZ_MASK}, /* CAS */ + {.offset = 0x588, .clear = MX53_DSE_HIGHZ_MASK}, /* RAS */ + {.offset = 0x578, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_0 */ + {.offset = 0x570, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_1 */ + + {.offset = 0x580, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT0 */ + {.offset = 0x564, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT1 */ + {.offset = 0x57c, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS0 */ + {.offset = 0x590, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS1 */ + {.offset = 0x568, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS2 */ + {.offset = 0x558, .clear = MX53_DSE_HIGHZ_MASK}, /* SDSQ3 */ + {.offset = 0x6f0, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_ADDS */ + {.offset = 0x718, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_BODS */ + {.offset = 0x71c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B1DS */ + {.offset = 0x728, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B2DS */ + {.offset = 0x72c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B3DS */ + + /* Controls the CKE signal which is required to leave self refresh */ + {.offset = 0x720, .clear = MX53_DSE_HIGHZ_MASK, .set = 1 << 19}, /* CTLDS */ }; static const struct imx5_pm_data imx51_pm_data __initconst = { @@ -65,11 +112,35 @@ static const struct imx5_pm_data imx53_pm_data __initconst = { .ccm_addr = 0x53fd4000, .cortex_addr = 0x63fa0000, .gpc_addr = 0x53fd8000, + .m4if_addr = 0x63fd8000, + .iomuxc_addr = 0x53fa8000, + .suspend_asm = &imx53_suspend, + .suspend_asm_sz = &imx53_suspend_sz, + .suspend_io_config = imx53_suspend_io_config, + .suspend_io_count = ARRAY_SIZE(imx53_suspend_io_config), }; +#define MX5_MAX_SUSPEND_IOSTATE ARRAY_SIZE(imx53_suspend_io_config) + +/* + * This structure is for passing necessary data for low level ocram + * suspend code(arch/arm/mach-imx/suspend-imx53.S), if this struct + * definition is changed, the offset definition in that file + * must be also changed accordingly otherwise, the suspend to ocram + * function will be broken! + */ +struct imx5_cpu_suspend_info { + void __iomem *m4if_base; + void __iomem *iomuxc_base; + u32 io_count; + struct imx5_suspend_io_state io_state[MX5_MAX_SUSPEND_IOSTATE]; +} __aligned(8); + static void __iomem *ccm_base; static void __iomem *cortex_base; static void __iomem *gpc_base; +static void __iomem *suspend_ocram_base; +static void (*imx5_suspend_in_ocram_fn)(void __iomem *ocram_vbase); /* * set cpu low power mode before WFI instruction. This function is called @@ -159,8 +230,15 @@ static int mx5_suspend_enter(suspend_state_t state) /*clear the EMPGC0/1 bits */ __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + + if (imx5_suspend_in_ocram_fn) + imx5_suspend_in_ocram_fn(suspend_ocram_base); + else + cpu_do_idle(); + + } else { + cpu_do_idle(); } - cpu_do_idle(); /* return registers to default idle state */ mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); @@ -192,6 +270,111 @@ static void imx5_pm_idle(void) imx5_cpu_do_idle(); } +static int __init imx_suspend_alloc_ocram( + size_t size, + void __iomem **virt_out, + phys_addr_t *phys_out) +{ + struct device_node *node; + struct platform_device *pdev; + struct gen_pool *ocram_pool; + unsigned long ocram_base; + void __iomem *virt; + phys_addr_t phys; + int ret = 0; + + /* Copied from imx6: TODO factorize */ + node = of_find_compatible_node(NULL, NULL, "mmio-sram"); + if (!node) { + pr_warn("%s: failed to find ocram node!\n", __func__); + return -ENODEV; + } + + pdev = of_find_device_by_node(node); + if (!pdev) { + pr_warn("%s: failed to find ocram device!\n", __func__); + ret = -ENODEV; + goto put_node; + } + + ocram_pool = dev_get_gen_pool(&pdev->dev); + if (!ocram_pool) { + pr_warn("%s: ocram pool unavailable!\n", __func__); + ret = -ENODEV; + goto put_node; + } + + ocram_base = gen_pool_alloc(ocram_pool, size); + if (!ocram_base) { + pr_warn("%s: unable to alloc ocram!\n", __func__); + ret = -ENOMEM; + goto put_node; + } + + phys = gen_pool_virt_to_phys(ocram_pool, ocram_base); + virt = __arm_ioremap_exec(phys, size, false); + if (phys_out) + *phys_out = phys; + if (virt_out) + *virt_out = virt; + +put_node: + of_node_put(node); + + return ret; +} + +static int __init imx5_suspend_init(const struct imx5_pm_data *soc_data) +{ + struct imx5_cpu_suspend_info *suspend_info; + int ret; + /* Need this to avoid compile error due to const typeof in fncpy.h */ + void (*suspend_asm)(void __iomem *) = soc_data->suspend_asm; + + if (!suspend_asm) + return 0; + + if (!soc_data->suspend_asm_sz || !*soc_data->suspend_asm_sz) + return -EINVAL; + + ret = imx_suspend_alloc_ocram( + *soc_data->suspend_asm_sz + sizeof(*suspend_info), + &suspend_ocram_base, NULL); + if (ret) + return ret; + + suspend_info = suspend_ocram_base; + + suspend_info->io_count = soc_data->suspend_io_count; + memcpy(suspend_info->io_state, soc_data->suspend_io_config, + sizeof(*suspend_info->io_state) * soc_data->suspend_io_count); + + suspend_info->m4if_base = ioremap(soc_data->m4if_addr, SZ_16K); + if (!suspend_info->m4if_base) { + ret = -ENOMEM; + goto failed_map_m4if; + } + + suspend_info->iomuxc_base = ioremap(soc_data->iomuxc_addr, SZ_16K); + if (!suspend_info->iomuxc_base) { + ret = -ENOMEM; + goto failed_map_iomuxc; + } + + imx5_suspend_in_ocram_fn = fncpy( + suspend_ocram_base + sizeof(*suspend_info), + suspend_asm, + *soc_data->suspend_asm_sz); + + return 0; + +failed_map_iomuxc: + iounmap(suspend_info->m4if_base); + +failed_map_m4if: + return ret; +} + static int __init imx5_pm_common_init(const struct imx5_pm_data *data) { int ret; @@ -218,6 +401,11 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) if (ret) pr_warn("%s: cpuidle init failed %d\n", __func__, ret); + ret = imx5_suspend_init(data); + if (ret) + pr_warn("%s: No DDR LPM support with suspend %d!\n", + __func__, ret); + suspend_set_ops(&mx5_suspend_ops); return 0; diff --git a/arch/arm/mach-imx/suspend-imx53.S b/arch/arm/mach-imx/suspend-imx53.S new file mode 100644 index 000000000000..5ed078ad110a --- /dev/null +++ b/arch/arm/mach-imx/suspend-imx53.S @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. + */ +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include + +#define M4IF_MCR0_OFFSET (0x008C) +#define M4IF_MCR0_FDVFS (0x1 << 11) +#define M4IF_MCR0_FDVACK (0x1 << 27) + + .align 3 + +/* + * ==================== low level suspend ==================== + * + * On entry + * r0: pm_info structure address; + * + * suspend ocram space layout: + * ======================== high address ====================== + * . + * . + * . + * ^ + * ^ + * ^ + * imx53_suspend code + * PM_INFO structure(imx53_suspend_info) + * ======================== low address ======================= + */ + +/* Offsets of members of struct imx53_suspend_info */ +#define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 +#define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 +#define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 +#define SUSPEND_INFO_MX53_IO_STATE_OFFSET 0xc + +ENTRY(imx53_suspend) + stmfd sp!, {r4,r5,r6,r7} + + /* Save pad config */ + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] + cmp r1, #0 + beq skip_pad_conf_1 + + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] + +1: + ldr r5, [r2], #12 /* IOMUXC register offset */ + ldr r6, [r3, r5] /* current value */ + str r6, [r2], #4 /* save area */ + subs r1, r1, #1 + bne 1b + +skip_pad_conf_1: + /* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */ + ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] + ldr r2,[r1, #M4IF_MCR0_OFFSET] + orr r2, r2, #M4IF_MCR0_FDVFS + str r2,[r1, #M4IF_MCR0_OFFSET] + + /* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */ +wait_sr_ack: + ldr r2,[r1, #M4IF_MCR0_OFFSET] + ands r2, r2, #M4IF_MCR0_FDVACK + beq wait_sr_ack + + /* Set pad config */ + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] + cmp r1, #0 + beq skip_pad_conf_2 + + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] + +2: + ldr r5, [r2], #4 /* IOMUXC register offset */ + ldr r6, [r2], #4 /* clear */ + ldr r7, [r3, r5] + bic r7, r7, r6 + ldr r6, [r2], #8 /* set */ + orr r7, r7, r6 + str r7, [r3, r5] + subs r1, r1, #1 + bne 2b + +skip_pad_conf_2: + /* Zzz, enter stop mode */ + wfi + nop + nop + nop + nop + + /* Restore pad config */ + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] + cmp r1, #0 + beq skip_pad_conf_3 + + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] + +3: + ldr r5, [r2], #12 /* IOMUXC register offset */ + ldr r6, [r2], #4 /* saved value */ + str r6, [r3, r5] + subs r1, r1, #1 + bne 3b + +skip_pad_conf_3: + /* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */ + ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] + ldr r2,[r1, #M4IF_MCR0_OFFSET] + bic r2, r2, #M4IF_MCR0_FDVFS + str r2,[r1, #M4IF_MCR0_OFFSET] + + /* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */ +wait_ar_ack: + ldr r2,[r1, #M4IF_MCR0_OFFSET] + ands r2, r2, #M4IF_MCR0_FDVACK + bne wait_ar_ack + + /* Restore registers */ + ldmfd sp!, {r4,r5,r6,r7} + mov pc, lr + +ENDPROC(imx53_suspend) + +ENTRY(imx53_suspend_sz) + .word . - imx53_suspend From d930d56825e934dc464cdad3f909333f994a89f3 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Mon, 18 May 2015 00:13:33 +0200 Subject: [PATCH 24/44] ARM: imx: clk-vf610: enable debug access port by default Enabled DAP (debug access port) by default. This enables the hw- breakpoint framework to make use of the breakpoints and watchpoints supported by hardware. [ 0.215805] hw-breakpoint: found 2 (+1 reserved) breakpoint and 1 watchpoint registers. [ 0.224624] hw-breakpoint: maximum watchpoint size is 4 bytes. Without this clock, the hw-breakpoint driver claims an undefined instruction during initialization: [ 0.227380] hw-breakpoint: Debug register access (0xee003e17) caused undefined instruction on CPU 0 [ 0.227519] hw-breakpoint: CPU 0 failed to disable vector catch Signed-off-by: Stefan Agner Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-vf610.c | 2 ++ include/dt-bindings/clock/vf610-clock.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 61876ed6e11e..1c2d3240efe7 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -118,6 +118,7 @@ static struct clk_onecell_data clk_data; static unsigned int const clks_init_on[] __initconst = { VF610_CLK_SYS_BUS, VF610_CLK_DDR_SEL, + VF610_CLK_DAP, }; static struct clk * __init vf610_get_fixed_clock( @@ -383,6 +384,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2)); clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7)); + clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24); imx_check_clocks(clk, ARRAY_SIZE(clk)); diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h index 979d24a6799f..d19763439472 100644 --- a/include/dt-bindings/clock/vf610-clock.h +++ b/include/dt-bindings/clock/vf610-clock.h @@ -193,6 +193,7 @@ #define VF610_PLL6_BYPASS 180 #define VF610_PLL7_BYPASS 181 #define VF610_CLK_SNVS 182 -#define VF610_CLK_END 183 +#define VF610_CLK_DAP 183 +#define VF610_CLK_END 184 #endif /* __DT_BINDINGS_CLOCK_VF610_H */ From f53947456f98085b26d689b63c63c5e60fd1349b Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 19 May 2015 02:45:02 +0800 Subject: [PATCH 25/44] ARM: clk: imx: update pllv3 to support imx7 Add type IMX_PLLV3_ENET_IMX7 Signed-off-by: Frank Li Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-pllv3.c | 9 ++++++++- drivers/clk/imx/clk.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index 260035be11ac..f0d15fb9d783 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -24,12 +24,14 @@ #define BM_PLL_POWER (0x1 << 12) #define BM_PLL_LOCK (0x1 << 31) +#define IMX7_ENET_PLL_POWER (0x1 << 5) /** * struct clk_pllv3 - IMX PLL clock version 3 * @clk_hw: clock source * @base: base address of PLL registers * @powerup_set: set POWER bit to power up the PLL + * @powerdown: pll powerdown offset bit * @div_mask: mask of divider bits * @div_shift: shift of divider bits * @@ -40,6 +42,7 @@ struct clk_pllv3 { struct clk_hw hw; void __iomem *base; bool powerup_set; + u32 powerdown; u32 div_mask; u32 div_shift; }; @@ -49,7 +52,7 @@ struct clk_pllv3 { static int clk_pllv3_wait_lock(struct clk_pllv3 *pll) { unsigned long timeout = jiffies + msecs_to_jiffies(10); - u32 val = readl_relaxed(pll->base) & BM_PLL_POWER; + u32 val = readl_relaxed(pll->base) & pll->powerdown; /* No need to wait for lock when pll is not powered up */ if ((pll->powerup_set && !val) || (!pll->powerup_set && val)) @@ -293,6 +296,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, if (!pll) return ERR_PTR(-ENOMEM); + pll->powerdown = BM_PLL_POWER; + switch (type) { case IMX_PLLV3_SYS: ops = &clk_pllv3_sys_ops; @@ -306,6 +311,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, case IMX_PLLV3_AV: ops = &clk_pllv3_av_ops; break; + case IMX_PLLV3_ENET_IMX7: + pll->powerdown = IMX7_ENET_PLL_POWER; case IMX_PLLV3_ENET: ops = &clk_pllv3_enet_ops; break; diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 6bae5374dc83..8b112182a83b 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -39,6 +39,7 @@ enum imx_pllv3_type { IMX_PLLV3_USB_VF610, IMX_PLLV3_AV, IMX_PLLV3_ENET, + IMX_PLLV3_ENET_IMX7, }; struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, From 8f6d8094b215b5705948262c7076fbe02ae859dc Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 19 May 2015 02:45:03 +0800 Subject: [PATCH 26/44] ARM: imx: add imx7d clk tree support Add i.MX7D clk tree support. Enable all clock to bring up imx7. Clock framework need be modified a little since imx7d change clock design. otherwise system will halt and block the other part upstream. All clock refine need wait for Dong Aisheng's patch clk: support clocks which requires parent clock on during operation Or other solution ready. Signed-off-by: Anson Huang Signed-off-by: Adrian Alonso Signed-off-by: Frank Li Signed-off-by: Shawn Guo --- drivers/clk/imx/Makefile | 1 + drivers/clk/imx/clk-imx7d.c | 860 ++++++++++++++++++++++++++++++++++++ 2 files changed, 861 insertions(+) create mode 100644 drivers/clk/imx/clk-imx7d.c diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 8be0a1c49a5e..75fae169ce8f 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -22,4 +22,5 @@ obj-$(CONFIG_SOC_IMX5) += clk-imx51-imx53.o obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o +obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o obj-$(CONFIG_SOC_VF610) += clk-vf610.o diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c new file mode 100644 index 000000000000..71f3a94b472c --- /dev/null +++ b/drivers/clk/imx/clk-imx7d.c @@ -0,0 +1,860 @@ +/* + * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +static struct clk *clks[IMX7D_CLK_END]; +static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk", + "pll_enet_500m_clk", "pll_dram_main_clk", + "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_main_clk", + "pll_usb_main_clk", }; + +static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_250m_clk", "pll_sys_pfd2_270m_clk", + "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_usb_main_clk", }; + +static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk", + "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk", + "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_usb_main_clk", }; + +static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk", + "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk", + "pll_audio_main_clk", "pll_video_main_clk", "pll_sys_pfd7_clk", }; + +static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk", + "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk", + "pll_sys_pfd7_clk", "pll_audio_main_clk", "pll_video_main_clk", }; + +static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk", + "pll_dram_533m_clk", "pll_enet_250m_clk", + "pll_sys_main_240m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_sys_pfd4_clk", }; + +static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk", + "pll_dram_533m_clk", "pll_sys_main_240m_clk", + "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk", + "pll_audio_main_clk", }; + +static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", + "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk", + "pll_video_main_clk", }; + +static const char *dram_phym_sel[] = { "pll_dram_main_clk", + "dram_phym_alt_clk", }; + +static const char *dram_sel[] = { "pll_dram_main_clk", + "dram_alt_clk", }; + +static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk", + "pll_sys_main_clk", "pll_enet_500m_clk", + "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_main_clk", + "pll_video_main_clk", }; + +static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk", + "pll_sys_main_clk", "pll_enet_500m_clk", + "pll_enet_250m_clk", "pll_sys_pfd0_392m_clk", + "pll_audio_main_clk", "pll_sys_pfd2_270m_clk", }; + +static const char *usb_hsic_sel[] = { "osc", "pll_sys_main_clk", + "pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk", + "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; + +static const char *pcie_ctrl_sel[] = { "osc", "pll_enet_250m_clk", + "pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk", + "pll_dram_533m_clk", "pll_enet_500m_clk", + "pll_sys_pfd1_332m_clk", "pll_sys_pfd6_clk", }; + +static const char *pcie_phy_sel[] = { "osc", "pll_enet_100m_clk", + "pll_enet_500m_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", + "ext_clk_4", "pll_sys_pfd0_392m_clk", }; + +static const char *epdc_pixel_sel[] = { "osc", "pll_sys_pfd1_332m_clk", + "pll_dram_533m_clk", "pll_sys_main_clk", "pll_sys_pfd5_clk", + "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", "pll_video_main_clk", }; + +static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk", + "pll_dram_533m_clk", "ext_clk_3", "pll_sys_pfd4_clk", + "pll_sys_pfd2_270m_clk", "pll_video_main_clk", + "pll_usb_main_clk", }; + +static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk", + "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk", + "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", }; + +static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk", + "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk", + "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", }; + +static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk", + "pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2", + "pll_video_main_clk", "ext_clk_3", }; + +static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", + "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", }; + +static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", + "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", }; + +static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", + "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", }; + +static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", + "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", }; + +static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk", + "pll_enet_50m_clk", "pll_enet_25m_clk", + "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "ext_clk_4", }; + +static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk", + "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", + "ext_clk_4", "pll_video_main_clk", }; + +static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk", + "pll_enet_50m_clk", "pll_enet_25m_clk", + "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "ext_clk_4", }; + +static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk", + "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", + "ext_clk_4", "pll_video_main_clk", }; + +static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk", + "pll_enet_50m_clk", "pll_enet_125m_clk", + "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_sys_pfd3_clk", }; + +static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_sys_main_120m_clk", "pll_dram_533m_clk", + "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_enet_125m_clk", + "pll_usb_main_clk", }; + +static const char *nand_sel[] = { "osc", "pll_sys_main_clk", + "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd3_clk", + "pll_enet_500m_clk", "pll_enet_250m_clk", + "pll_video_main_clk", }; + +static const char *qspi_sel[] = { "osc", "pll_sys_pfd4_clk", + "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd3_clk", + "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; + +static const char *usdhc1_sel[] = { "osc", "pll_sys_pfd0_392m_clk", + "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk", + "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; + +static const char *usdhc2_sel[] = { "osc", "pll_sys_pfd0_392m_clk", + "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk", + "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; + +static const char *usdhc3_sel[] = { "osc", "pll_sys_pfd0_392m_clk", + "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk", + "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; + +static const char *can1_sel[] = { "osc", "pll_sys_main_120m_clk", + "pll_dram_533m_clk", "pll_sys_main_clk", + "pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1", + "ext_clk_4", }; + +static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk", + "pll_dram_533m_clk", "pll_sys_main_clk", + "pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1", + "ext_clk_3", }; + +static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk", + "pll_enet_50m_clk", "pll_dram_533m_clk", + "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", + "pll_sys_pfd2_135m_clk", }; + +static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk", + "pll_enet_50m_clk", "pll_dram_533m_clk", + "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", + "pll_sys_pfd2_135m_clk", }; + +static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk", + "pll_enet_50m_clk", "pll_dram_533m_clk", + "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", + "pll_sys_pfd2_135m_clk", }; + +static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk", + "pll_enet_50m_clk", "pll_dram_533m_clk", + "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", + "pll_sys_pfd2_135m_clk", }; + +static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_enet_100m_clk", + "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", + "pll_usb_main_clk", }; + +static const char *uart2_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_enet_100m_clk", + "pll_sys_main_clk", "ext_clk_2", "ext_clk_3", + "pll_usb_main_clk", }; + +static const char *uart3_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_enet_100m_clk", + "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", + "pll_usb_main_clk", }; + +static const char *uart4_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_enet_100m_clk", + "pll_sys_main_clk", "ext_clk_2", "ext_clk_3", + "pll_usb_main_clk", }; + +static const char *uart5_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_enet_100m_clk", + "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", + "pll_usb_main_clk", }; + +static const char *uart6_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_enet_100m_clk", + "pll_sys_main_clk", "ext_clk_2", "ext_clk_3", + "pll_usb_main_clk", }; + +static const char *uart7_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_enet_100m_clk", + "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", + "pll_usb_main_clk", }; + +static const char *ecspi1_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_sys_main_120m_clk", + "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk", + "pll_usb_main_clk", }; + +static const char *ecspi2_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_sys_main_120m_clk", + "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk", + "pll_usb_main_clk", }; + +static const char *ecspi3_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_sys_main_120m_clk", + "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk", + "pll_usb_main_clk", }; + +static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_enet_40m_clk", "pll_sys_main_120m_clk", + "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk", + "pll_usb_main_clk", }; + +static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", }; + +static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", }; + +static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", }; + +static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", }; + +static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", }; + +static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", }; + +static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_sys_main_120m_clk", "pll_dram_533m_clk", + "pll_usb_main_clk", "pll_audio_main_clk", "pll_enet_125m_clk", + "pll_sys_pfd7_clk", }; + +static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_sys_main_120m_clk", "pll_dram_533m_clk", + "pll_usb_main_clk", "pll_video_main_clk", "pll_enet_125m_clk", + "pll_sys_pfd7_clk", }; + +static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", + "ref_1m_clk", "pll_audio_main_clk", "ext_clk_1", }; + +static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", + "ref_1m_clk", "pll_audio_main_clk", "ext_clk_2", }; + +static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", + "ref_1m_clk", "pll_audio_main_clk", "ext_clk_3", }; + +static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk", + "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", + "ref_1m_clk", "pll_audio_main_clk", "ext_clk_4", }; + +static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_sys_main_120m_clk", "pll_dram_533m_clk", + "pll_enet_125m_clk", "pll_usb_main_clk", "ext_clk_2", + "ext_clk_3", }; + +static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_sys_main_120m_clk", "pll_dram_533m_clk", + "pll_enet_125m_clk", "pll_usb_main_clk", "ref_1m_clk", + "pll_sys_pfd1_166m_clk", }; + +static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_sys_main_120m_clk", "pll_dram_533m_clk", + "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_usb_main_clk", }; + +static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk", + "pll_sys_main_120m_clk", "pll_dram_533m_clk", + "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_usb_main_clk", }; + +static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk", + "pll_dram_533m_clk", "pll_usb_main_clk", + "pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk", + "pll_enet_500m_clk", "pll_sys_pfd7_clk", }; + +static const char *clko1_sel[] = { "osc", "pll_sys_main_clk", + "pll_sys_main_240m_clk", "pll_sys_pfd0_196m_clk", "pll_sys_pfd3_clk", + "pll_enet_500m_clk", "pll_dram_533m_clk", "ref_1m_clk", }; + +static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk", + "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk", + "pll_audio_main_clk", "pll_video_main_clk", "osc_32k_clk", }; + +static const char *lvds1_sel[] = { "pll_arm_main_clk", + "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk", + "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk", + "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", + "pll_audio_main_clk", "pll_video_main_clk", "pll_enet_500m_clk", + "pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk", + "pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk", + "pll_dram_main_clk", }; + +static const char *pll_bypass_src_sel[] = { "osc", "dummy", }; +static const char *pll_arm_bypass_sel[] = { "pll_arm_main", "pll_arm_main_src", }; +static const char *pll_dram_bypass_sel[] = { "pll_dram_main", "pll_dram_main_src", }; +static const char *pll_sys_bypass_sel[] = { "pll_sys_main", "pll_sys_main_src", }; +static const char *pll_enet_bypass_sel[] = { "pll_enet_main", "pll_enet_main_src", }; +static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", }; +static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", }; + +static struct clk_onecell_data clk_data; + +static void __init imx7d_clocks_init(struct device_node *ccm_node) +{ + struct device_node *np; + void __iomem *base; + int i; + + clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0); + clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc"); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); + base = of_iomap(np, 0); + WARN_ON(!base); + + clks[IMX7D_PLL_ARM_MAIN_SRC] = imx_clk_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); + clks[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); + clks[IMX7D_PLL_SYS_MAIN_SRC] = imx_clk_mux("pll_sys_main_src", base + 0xb0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); + clks[IMX7D_PLL_ENET_MAIN_SRC] = imx_clk_mux("pll_enet_main_src", base + 0xe0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); + clks[IMX7D_PLL_AUDIO_MAIN_SRC] = imx_clk_mux("pll_audio_main_src", base + 0xf0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); + clks[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); + + clks[IMX7D_PLL_ARM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "pll_arm_main_src", base + 0x60, 0x7f); + clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_dram_main", "pll_dram_main_src", base + 0x70, 0x7f); + clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "pll_sys_main_src", base + 0xb0, 0x1); + clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "pll_enet_main_src", base + 0xe0, 0x0); + clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "pll_audio_main_src", base + 0xf0, 0x7f); + clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "pll_video_main_src", base + 0x130, 0x7f); + + clks[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT); + clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT); + clks[IMX7D_PLL_SYS_MAIN_BYPASS] = imx_clk_mux_flags("pll_sys_main_bypass", base + 0xb0, 16, 1, pll_sys_bypass_sel, ARRAY_SIZE(pll_sys_bypass_sel), CLK_SET_RATE_PARENT); + clks[IMX7D_PLL_ENET_MAIN_BYPASS] = imx_clk_mux_flags("pll_enet_main_bypass", base + 0xe0, 16, 1, pll_enet_bypass_sel, ARRAY_SIZE(pll_enet_bypass_sel), CLK_SET_RATE_PARENT); + clks[IMX7D_PLL_AUDIO_MAIN_BYPASS] = imx_clk_mux_flags("pll_audio_main_bypass", base + 0xf0, 16, 1, pll_audio_bypass_sel, ARRAY_SIZE(pll_audio_bypass_sel), CLK_SET_RATE_PARENT); + clks[IMX7D_PLL_VIDEO_MAIN_BYPASS] = imx_clk_mux_flags("pll_video_main_bypass", base + 0x130, 16, 1, pll_video_bypass_sel, ARRAY_SIZE(pll_video_bypass_sel), CLK_SET_RATE_PARENT); + + clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]); + clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]); + clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]); + clk_set_parent(clks[IMX7D_PLL_ENET_MAIN_BYPASS], clks[IMX7D_PLL_ENET_MAIN]); + clk_set_parent(clks[IMX7D_PLL_AUDIO_MAIN_BYPASS], clks[IMX7D_PLL_AUDIO_MAIN]); + clk_set_parent(clks[IMX7D_PLL_VIDEO_MAIN_BYPASS], clks[IMX7D_PLL_VIDEO_MAIN]); + + clks[IMX7D_PLL_ARM_MAIN_CLK] = imx_clk_gate("pll_arm_main_clk", "pll_arm_main_bypass", base + 0x60, 13); + clks[IMX7D_PLL_DRAM_MAIN_CLK] = imx_clk_gate("pll_dram_main_clk", "pll_dram_main_bypass", base + 0x70, 13); + clks[IMX7D_PLL_SYS_MAIN_CLK] = imx_clk_gate("pll_sys_main_clk", "pll_sys_main_bypass", base + 0xb0, 13); + clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13); + clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13); + + clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0); + clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1); + clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2); + + clks[IMX7D_PLL_SYS_PFD3_CLK] = imx_clk_pfd("pll_sys_pfd3_clk", "pll_sys_main_clk", base + 0xc0, 3); + clks[IMX7D_PLL_SYS_PFD4_CLK] = imx_clk_pfd("pll_sys_pfd4_clk", "pll_sys_main_clk", base + 0xd0, 0); + clks[IMX7D_PLL_SYS_PFD5_CLK] = imx_clk_pfd("pll_sys_pfd5_clk", "pll_sys_main_clk", base + 0xd0, 1); + clks[IMX7D_PLL_SYS_PFD6_CLK] = imx_clk_pfd("pll_sys_pfd6_clk", "pll_sys_main_clk", base + 0xd0, 2); + clks[IMX7D_PLL_SYS_PFD7_CLK] = imx_clk_pfd("pll_sys_pfd7_clk", "pll_sys_main_clk", base + 0xd0, 3); + + clks[IMX7D_PLL_SYS_MAIN_480M] = imx_clk_fixed_factor("pll_sys_main_480m", "pll_sys_main_clk", 1, 1); + clks[IMX7D_PLL_SYS_MAIN_240M] = imx_clk_fixed_factor("pll_sys_main_240m", "pll_sys_main_clk", 1, 2); + clks[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_fixed_factor("pll_sys_main_120m", "pll_sys_main_clk", 1, 4); + clks[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2); + + clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4); + clks[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5); + clks[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6); + clks[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12); + + clks[IMX7D_PLL_SYS_PFD0_196M] = imx_clk_fixed_factor("pll_sys_pfd0_196m", "pll_sys_pfd0_392m_clk", 1, 2); + clks[IMX7D_PLL_SYS_PFD1_166M] = imx_clk_fixed_factor("pll_sys_pfd1_166m", "pll_sys_pfd1_332m_clk", 1, 2); + clks[IMX7D_PLL_SYS_PFD2_135M] = imx_clk_fixed_factor("pll_sys_pfd2_135m", "pll_sys_pfd2_270m_clk", 1, 2); + + clks[IMX7D_PLL_SYS_PFD0_196M_CLK] = imx_clk_gate_dis("pll_sys_pfd0_196m_clk", "pll_sys_pfd0_196m", base + 0xb0, 26); + clks[IMX7D_PLL_SYS_PFD1_166M_CLK] = imx_clk_gate_dis("pll_sys_pfd1_166m_clk", "pll_sys_pfd1_166m", base + 0xb0, 27); + clks[IMX7D_PLL_SYS_PFD2_135M_CLK] = imx_clk_gate_dis("pll_sys_pfd2_135m_clk", "pll_sys_pfd2_135m", base + 0xb0, 28); + + clks[IMX7D_PLL_ENET_MAIN_CLK] = imx_clk_fixed_factor("pll_enet_main_clk", "pll_enet_main_bypass", 1, 1); + clks[IMX7D_PLL_ENET_MAIN_500M] = imx_clk_fixed_factor("pll_enet_500m", "pll_enet_main_clk", 1, 2); + clks[IMX7D_PLL_ENET_MAIN_250M] = imx_clk_fixed_factor("pll_enet_250m", "pll_enet_main_clk", 1, 4); + clks[IMX7D_PLL_ENET_MAIN_125M] = imx_clk_fixed_factor("pll_enet_125m", "pll_enet_main_clk", 1, 8); + clks[IMX7D_PLL_ENET_MAIN_100M] = imx_clk_fixed_factor("pll_enet_100m", "pll_enet_main_clk", 1, 10); + clks[IMX7D_PLL_ENET_MAIN_50M] = imx_clk_fixed_factor("pll_enet_50m", "pll_enet_main_clk", 1, 20); + clks[IMX7D_PLL_ENET_MAIN_40M] = imx_clk_fixed_factor("pll_enet_40m", "pll_enet_main_clk", 1, 25); + clks[IMX7D_PLL_ENET_MAIN_25M] = imx_clk_fixed_factor("pll_enet_25m", "pll_enet_main_clk", 1, 40); + + clks[IMX7D_PLL_ENET_MAIN_500M_CLK] = imx_clk_gate("pll_enet_500m_clk", "pll_enet_500m", base + 0xe0, 12); + clks[IMX7D_PLL_ENET_MAIN_250M_CLK] = imx_clk_gate("pll_enet_250m_clk", "pll_enet_250m", base + 0xe0, 11); + clks[IMX7D_PLL_ENET_MAIN_125M_CLK] = imx_clk_gate("pll_enet_125m_clk", "pll_enet_125m", base + 0xe0, 10); + clks[IMX7D_PLL_ENET_MAIN_100M_CLK] = imx_clk_gate("pll_enet_100m_clk", "pll_enet_100m", base + 0xe0, 9); + clks[IMX7D_PLL_ENET_MAIN_50M_CLK] = imx_clk_gate("pll_enet_50m_clk", "pll_enet_50m", base + 0xe0, 8); + clks[IMX7D_PLL_ENET_MAIN_40M_CLK] = imx_clk_gate("pll_enet_40m_clk", "pll_enet_40m", base + 0xe0, 7); + clks[IMX7D_PLL_ENET_MAIN_25M_CLK] = imx_clk_gate("pll_enet_25m_clk", "pll_enet_25m", base + 0xe0, 6); + + clks[IMX7D_LVDS1_OUT_SEL] = imx_clk_mux("lvds1_sel", base + 0x170, 0, 5, lvds1_sel, ARRAY_SIZE(lvds1_sel)); + clks[IMX7D_LVDS1_OUT_CLK] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x170, 5, BIT(6)); + + np = ccm_node; + base = of_iomap(np, 0); + WARN_ON(!base); + + clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel)); + clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel)); + clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel)); + clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel)); + clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel)); + clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel)); + clks[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_mux("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel)); + clks[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_mux("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel)); + clks[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_mux("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel)); + clks[IMX7D_DRAM_ROOT_SRC] = imx_clk_mux("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel)); + clks[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_mux("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel)); + clks[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_mux("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel)); + clks[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_mux("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel)); + clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel)); + clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel)); + clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel)); + clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel)); + clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel)); + clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel)); + clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel)); + clks[IMX7D_SAI1_ROOT_SRC] = imx_clk_mux("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel)); + clks[IMX7D_SAI2_ROOT_SRC] = imx_clk_mux("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel)); + clks[IMX7D_SAI3_ROOT_SRC] = imx_clk_mux("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel)); + clks[IMX7D_SPDIF_ROOT_SRC] = imx_clk_mux("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel)); + clks[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_mux("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel)); + clks[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_mux("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel)); + clks[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_mux("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel)); + clks[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_mux("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel)); + clks[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_mux("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel)); + clks[IMX7D_EIM_ROOT_SRC] = imx_clk_mux("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel)); + clks[IMX7D_NAND_ROOT_SRC] = imx_clk_mux("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel)); + clks[IMX7D_QSPI_ROOT_SRC] = imx_clk_mux("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel)); + clks[IMX7D_USDHC1_ROOT_SRC] = imx_clk_mux("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel)); + clks[IMX7D_USDHC2_ROOT_SRC] = imx_clk_mux("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel)); + clks[IMX7D_USDHC3_ROOT_SRC] = imx_clk_mux("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel)); + clks[IMX7D_CAN1_ROOT_SRC] = imx_clk_mux("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel)); + clks[IMX7D_CAN2_ROOT_SRC] = imx_clk_mux("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel)); + clks[IMX7D_I2C1_ROOT_SRC] = imx_clk_mux("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel)); + clks[IMX7D_I2C2_ROOT_SRC] = imx_clk_mux("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel)); + clks[IMX7D_I2C3_ROOT_SRC] = imx_clk_mux("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel)); + clks[IMX7D_I2C4_ROOT_SRC] = imx_clk_mux("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel)); + clks[IMX7D_UART1_ROOT_SRC] = imx_clk_mux("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel)); + clks[IMX7D_UART2_ROOT_SRC] = imx_clk_mux("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel)); + clks[IMX7D_UART3_ROOT_SRC] = imx_clk_mux("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel)); + clks[IMX7D_UART4_ROOT_SRC] = imx_clk_mux("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel)); + clks[IMX7D_UART5_ROOT_SRC] = imx_clk_mux("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel)); + clks[IMX7D_UART6_ROOT_SRC] = imx_clk_mux("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel)); + clks[IMX7D_UART7_ROOT_SRC] = imx_clk_mux("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel)); + clks[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_mux("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel)); + clks[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_mux("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel)); + clks[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_mux("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel)); + clks[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_mux("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel)); + clks[IMX7D_PWM1_ROOT_SRC] = imx_clk_mux("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel)); + clks[IMX7D_PWM2_ROOT_SRC] = imx_clk_mux("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel)); + clks[IMX7D_PWM3_ROOT_SRC] = imx_clk_mux("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel)); + clks[IMX7D_PWM4_ROOT_SRC] = imx_clk_mux("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel)); + clks[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_mux("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel)); + clks[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_mux("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel)); + clks[IMX7D_SIM1_ROOT_SRC] = imx_clk_mux("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel)); + clks[IMX7D_SIM2_ROOT_SRC] = imx_clk_mux("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel)); + clks[IMX7D_GPT1_ROOT_SRC] = imx_clk_mux("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel)); + clks[IMX7D_GPT2_ROOT_SRC] = imx_clk_mux("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel)); + clks[IMX7D_GPT3_ROOT_SRC] = imx_clk_mux("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel)); + clks[IMX7D_GPT4_ROOT_SRC] = imx_clk_mux("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel)); + clks[IMX7D_TRACE_ROOT_SRC] = imx_clk_mux("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel)); + clks[IMX7D_WDOG_ROOT_SRC] = imx_clk_mux("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel)); + clks[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_mux("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel)); + clks[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_mux("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel)); + clks[IMX7D_WRCLK_ROOT_SRC] = imx_clk_mux("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel)); + clks[IMX7D_CLKO1_ROOT_SRC] = imx_clk_mux("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel)); + clks[IMX7D_CLKO2_ROOT_SRC] = imx_clk_mux("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel)); + + clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate("arm_a7_cg", "arm_a7_src", base + 0x8000, 28); + clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); + clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate("arm_m0_cg", "arm_m0_src", base + 0x8100, 28); + clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate("axi_cg", "axi_src", base + 0x8800, 28); + clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate("disp_axi_cg", "disp_axi_src", base + 0x8880, 28); + clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate("enet_axi_cg", "enet_axi_src", base + 0x8900, 28); + clks[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_gate("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28); + clks[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_gate("ahb_cg", "ahb_src", base + 0x9000, 28); + clks[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_gate("dram_phym_cg", "dram_phym_src", base + 0x9800, 28); + clks[IMX7D_DRAM_ROOT_CG] = imx_clk_gate("dram_cg", "dram_src", base + 0x9880, 28); + clks[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_gate("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28); + clks[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_gate("dram_alt_cg", "dram_alt_src", base + 0xa080, 28); + clks[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_gate("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28); + clks[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_gate("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28); + clks[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_gate("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28); + clks[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_gate("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28); + clks[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_gate("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28); + clks[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_gate("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28); + clks[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_gate("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28); + clks[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_gate("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28); + clks[IMX7D_SAI1_ROOT_CG] = imx_clk_gate("sai1_cg", "sai1_src", base + 0xa500, 28); + clks[IMX7D_SAI2_ROOT_CG] = imx_clk_gate("sai2_cg", "sai2_src", base + 0xa580, 28); + clks[IMX7D_SAI3_ROOT_CG] = imx_clk_gate("sai3_cg", "sai3_src", base + 0xa600, 28); + clks[IMX7D_SPDIF_ROOT_CG] = imx_clk_gate("spdif_cg", "spdif_src", base + 0xa680, 28); + clks[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_gate("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28); + clks[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_gate("enet1_time_cg", "enet1_time_src", base + 0xa780, 28); + clks[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_gate("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28); + clks[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_gate("enet2_time_cg", "enet2_time_src", base + 0xa880, 28); + clks[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_gate("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28); + clks[IMX7D_EIM_ROOT_CG] = imx_clk_gate("eim_cg", "eim_src", base + 0xa980, 28); + clks[IMX7D_NAND_ROOT_CG] = imx_clk_gate("nand_cg", "nand_src", base + 0xaa00, 28); + clks[IMX7D_QSPI_ROOT_CG] = imx_clk_gate("qspi_cg", "qspi_src", base + 0xaa80, 28); + clks[IMX7D_USDHC1_ROOT_CG] = imx_clk_gate("usdhc1_cg", "usdhc1_src", base + 0xab00, 28); + clks[IMX7D_USDHC2_ROOT_CG] = imx_clk_gate("usdhc2_cg", "usdhc2_src", base + 0xab80, 28); + clks[IMX7D_USDHC3_ROOT_CG] = imx_clk_gate("usdhc3_cg", "usdhc3_src", base + 0xac00, 28); + clks[IMX7D_CAN1_ROOT_CG] = imx_clk_gate("can1_cg", "can1_src", base + 0xac80, 28); + clks[IMX7D_CAN2_ROOT_CG] = imx_clk_gate("can2_cg", "can2_src", base + 0xad00, 28); + clks[IMX7D_I2C1_ROOT_CG] = imx_clk_gate("i2c1_cg", "i2c1_src", base + 0xad80, 28); + clks[IMX7D_I2C2_ROOT_CG] = imx_clk_gate("i2c2_cg", "i2c2_src", base + 0xae00, 28); + clks[IMX7D_I2C3_ROOT_CG] = imx_clk_gate("i2c3_cg", "i2c3_src", base + 0xae80, 28); + clks[IMX7D_I2C4_ROOT_CG] = imx_clk_gate("i2c4_cg", "i2c4_src", base + 0xaf00, 28); + clks[IMX7D_UART1_ROOT_CG] = imx_clk_gate("uart1_cg", "uart1_src", base + 0xaf80, 28); + clks[IMX7D_UART2_ROOT_CG] = imx_clk_gate("uart2_cg", "uart2_src", base + 0xb000, 28); + clks[IMX7D_UART3_ROOT_CG] = imx_clk_gate("uart3_cg", "uart3_src", base + 0xb080, 28); + clks[IMX7D_UART4_ROOT_CG] = imx_clk_gate("uart4_cg", "uart4_src", base + 0xb100, 28); + clks[IMX7D_UART5_ROOT_CG] = imx_clk_gate("uart5_cg", "uart5_src", base + 0xb180, 28); + clks[IMX7D_UART6_ROOT_CG] = imx_clk_gate("uart6_cg", "uart6_src", base + 0xb200, 28); + clks[IMX7D_UART7_ROOT_CG] = imx_clk_gate("uart7_cg", "uart7_src", base + 0xb280, 28); + clks[IMX7D_ECSPI1_ROOT_CG] = imx_clk_gate("ecspi1_cg", "ecspi1_src", base + 0xb300, 28); + clks[IMX7D_ECSPI2_ROOT_CG] = imx_clk_gate("ecspi2_cg", "ecspi2_src", base + 0xb380, 28); + clks[IMX7D_ECSPI3_ROOT_CG] = imx_clk_gate("ecspi3_cg", "ecspi3_src", base + 0xb400, 28); + clks[IMX7D_ECSPI4_ROOT_CG] = imx_clk_gate("ecspi4_cg", "ecspi4_src", base + 0xb480, 28); + clks[IMX7D_PWM1_ROOT_CG] = imx_clk_gate("pwm1_cg", "pwm1_src", base + 0xb500, 28); + clks[IMX7D_PWM2_ROOT_CG] = imx_clk_gate("pwm2_cg", "pwm2_src", base + 0xb580, 28); + clks[IMX7D_PWM3_ROOT_CG] = imx_clk_gate("pwm3_cg", "pwm3_src", base + 0xb600, 28); + clks[IMX7D_PWM4_ROOT_CG] = imx_clk_gate("pwm4_cg", "pwm4_src", base + 0xb680, 28); + clks[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_gate("flextimer1_cg", "flextimer1_src", base + 0xb700, 28); + clks[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_gate("flextimer2_cg", "flextimer2_src", base + 0xb780, 28); + clks[IMX7D_SIM1_ROOT_CG] = imx_clk_gate("sim1_cg", "sim1_src", base + 0xb800, 28); + clks[IMX7D_SIM2_ROOT_CG] = imx_clk_gate("sim2_cg", "sim2_src", base + 0xb880, 28); + clks[IMX7D_GPT1_ROOT_CG] = imx_clk_gate("gpt1_cg", "gpt1_src", base + 0xb900, 28); + clks[IMX7D_GPT2_ROOT_CG] = imx_clk_gate("gpt2_cg", "gpt2_src", base + 0xb980, 28); + clks[IMX7D_GPT3_ROOT_CG] = imx_clk_gate("gpt3_cg", "gpt3_src", base + 0xbA00, 28); + clks[IMX7D_GPT4_ROOT_CG] = imx_clk_gate("gpt4_cg", "gpt4_src", base + 0xbA80, 28); + clks[IMX7D_TRACE_ROOT_CG] = imx_clk_gate("trace_cg", "trace_src", base + 0xbb00, 28); + clks[IMX7D_WDOG_ROOT_CG] = imx_clk_gate("wdog_cg", "wdog_src", base + 0xbb80, 28); + clks[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_gate("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28); + clks[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_gate("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28); + clks[IMX7D_WRCLK_ROOT_CG] = imx_clk_gate("wrclk_cg", "wrclk_src", base + 0xbd00, 28); + clks[IMX7D_CLKO1_ROOT_CG] = imx_clk_gate("clko1_cg", "clko1_src", base + 0xbd80, 28); + clks[IMX7D_CLKO2_ROOT_CG] = imx_clk_gate("clko2_cg", "clko2_src", base + 0xbe00, 28); + + clks[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_divider("axi_pre_div", "axi_cg", base + 0x8800, 16, 3); + clks[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_divider("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3); + clks[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_divider("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3); + clks[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_divider("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3); + clks[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_divider("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3); + clks[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3); + clks[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3); + clks[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_divider("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3); + clks[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_divider("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3); + clks[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_divider("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3); + clks[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3); + clks[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3); + clks[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3); + clks[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3); + clks[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_divider("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3); + clks[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_divider("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3); + clks[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_divider("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3); + clks[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_divider("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3); + clks[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_divider("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3); + clks[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_divider("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3); + clks[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3); + clks[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_divider("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3); + clks[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3); + clks[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_divider("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3); + clks[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_divider("eim_pre_div", "eim_cg", base + 0xa980, 16, 3); + clks[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_divider("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3); + clks[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_divider("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3); + clks[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_divider("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3); + clks[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_divider("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3); + clks[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_divider("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3); + clks[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_divider("can1_pre_div", "can1_cg", base + 0xac80, 16, 3); + clks[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_divider("can2_pre_div", "can2_cg", base + 0xad00, 16, 3); + clks[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_divider("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3); + clks[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_divider("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3); + clks[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_divider("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3); + clks[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_divider("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3); + clks[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_divider("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3); + clks[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_divider("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3); + clks[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_divider("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3); + clks[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_divider("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3); + clks[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_divider("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3); + clks[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_divider("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3); + clks[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_divider("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3); + clks[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_divider("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3); + clks[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_divider("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3); + clks[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_divider("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3); + clks[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_divider("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3); + clks[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_divider("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3); + clks[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_divider("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3); + clks[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_divider("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3); + clks[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_divider("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3); + clks[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_divider("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3); + clks[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_divider("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3); + clks[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_divider("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3); + clks[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_divider("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3); + clks[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_divider("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3); + clks[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_divider("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3); + clks[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_divider("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3); + clks[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_divider("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3); + clks[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_divider("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3); + clks[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_divider("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3); + clks[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_divider("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3); + clks[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_divider("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3); + clks[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_divider("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3); + clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3); + clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3); + + clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3); + clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); + clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3); + clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6); + clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6); + clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6); + clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6); + clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider("ahb_post_div", "ahb_pre_div", base + 0x9000, 0, 6); + clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider("dram_post_div", "dram_cg", base + 0x9880, 0, 3); + clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3); + clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3); + clks[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_divider("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6); + clks[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_divider("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6); + clks[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_divider("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6); + clks[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_divider("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6); + clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6); + clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6); + clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6); + clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider("mipi_dphy_post_div", "mipi_csi_dphy_div", base + 0xa480, 0, 6); + clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6); + clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6); + clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6); + clks[IMX7D_SPDIF_ROOT_DIV] = imx_clk_divider("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6); + clks[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_divider("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6); + clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6); + clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6); + clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6); + clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6); + clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6); + clks[IMX7D_NAND_ROOT_DIV] = imx_clk_divider("nand_post_div", "nand_pre_div", base + 0xaa00, 0, 6); + clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6); + clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6); + clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6); + clks[IMX7D_USDHC3_ROOT_DIV] = imx_clk_divider("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6); + clks[IMX7D_CAN1_ROOT_DIV] = imx_clk_divider("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6); + clks[IMX7D_CAN2_ROOT_DIV] = imx_clk_divider("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6); + clks[IMX7D_I2C1_ROOT_DIV] = imx_clk_divider("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6); + clks[IMX7D_I2C2_ROOT_DIV] = imx_clk_divider("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6); + clks[IMX7D_I2C3_ROOT_DIV] = imx_clk_divider("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6); + clks[IMX7D_I2C4_ROOT_DIV] = imx_clk_divider("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6); + clks[IMX7D_UART1_ROOT_DIV] = imx_clk_divider("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6); + clks[IMX7D_UART2_ROOT_DIV] = imx_clk_divider("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6); + clks[IMX7D_UART3_ROOT_DIV] = imx_clk_divider("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6); + clks[IMX7D_UART4_ROOT_DIV] = imx_clk_divider("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6); + clks[IMX7D_UART5_ROOT_DIV] = imx_clk_divider("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6); + clks[IMX7D_UART6_ROOT_DIV] = imx_clk_divider("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6); + clks[IMX7D_UART7_ROOT_DIV] = imx_clk_divider("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6); + clks[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_divider("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6); + clks[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_divider("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6); + clks[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_divider("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6); + clks[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_divider("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6); + clks[IMX7D_PWM1_ROOT_DIV] = imx_clk_divider("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6); + clks[IMX7D_PWM2_ROOT_DIV] = imx_clk_divider("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6); + clks[IMX7D_PWM3_ROOT_DIV] = imx_clk_divider("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6); + clks[IMX7D_PWM4_ROOT_DIV] = imx_clk_divider("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6); + clks[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_divider("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6); + clks[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_divider("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6); + clks[IMX7D_SIM1_ROOT_DIV] = imx_clk_divider("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6); + clks[IMX7D_SIM2_ROOT_DIV] = imx_clk_divider("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6); + clks[IMX7D_GPT1_ROOT_DIV] = imx_clk_divider("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6); + clks[IMX7D_GPT2_ROOT_DIV] = imx_clk_divider("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6); + clks[IMX7D_GPT3_ROOT_DIV] = imx_clk_divider("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6); + clks[IMX7D_GPT4_ROOT_DIV] = imx_clk_divider("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6); + clks[IMX7D_TRACE_ROOT_DIV] = imx_clk_divider("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6); + clks[IMX7D_WDOG_ROOT_DIV] = imx_clk_divider("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6); + clks[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_divider("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6); + clks[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_divider("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6); + clks[IMX7D_WRCLK_ROOT_DIV] = imx_clk_divider("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6); + clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6); + clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6); + + clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0); + clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate2("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0); + clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate2("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0); + clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate2("main_axi_root_clk", "axi_post_div", base + 0x4040, 0); + clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate2("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0); + clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate2("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0); + clks[IMX7D_OCRAM_CLK] = imx_clk_gate2("ocram_clk", "axi_post_div", base + 0x4110, 0); + clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate2("ocram_s_clk", "ahb_post_div", base + 0x4120, 0); + clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate2("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0); + clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate2("ahb_root_clk", "ahb_post_div", base + 0x4200, 0); + clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate2("dram_root_clk", "dram_post_div", base + 0x4130, 0); + clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate2("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0); + clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate2("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0); + clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate2("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0); + clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate2("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0); + clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate2("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0); + clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate2("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0); + clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate2("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0); + clks[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_gate2("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0); + clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate2("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0); + clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate2("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0); + clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate2("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0); + clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0); + clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0); + clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0); + clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate2("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0); + clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate2("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0); + clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate2("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0); + clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate2("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0); + clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0); + clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate2("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0); + clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate2("eim_root_clk", "eim_post_div", base + 0x4160, 0); + clks[IMX7D_NAND_ROOT_CLK] = imx_clk_gate2("nand_root_clk", "nand_post_div", base + 0x4140, 0); + clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate2("qspi_root_clk", "qspi_post_div", base + 0x4150, 0); + clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate2("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0); + clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate2("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0); + clks[IMX7D_USDHC3_ROOT_CLK] = imx_clk_gate2("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0); + clks[IMX7D_CAN1_ROOT_CLK] = imx_clk_gate2("can1_root_clk", "can1_post_div", base + 0x4740, 0); + clks[IMX7D_CAN2_ROOT_CLK] = imx_clk_gate2("can2_root_clk", "can2_post_div", base + 0x4750, 0); + clks[IMX7D_I2C1_ROOT_CLK] = imx_clk_gate2("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0); + clks[IMX7D_I2C2_ROOT_CLK] = imx_clk_gate2("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0); + clks[IMX7D_I2C3_ROOT_CLK] = imx_clk_gate2("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0); + clks[IMX7D_I2C4_ROOT_CLK] = imx_clk_gate2("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0); + clks[IMX7D_UART1_ROOT_CLK] = imx_clk_gate2("uart1_root_clk", "uart1_post_div", base + 0x4940, 0); + clks[IMX7D_UART2_ROOT_CLK] = imx_clk_gate2("uart2_root_clk", "uart2_post_div", base + 0x4950, 0); + clks[IMX7D_UART3_ROOT_CLK] = imx_clk_gate2("uart3_root_clk", "uart3_post_div", base + 0x4960, 0); + clks[IMX7D_UART4_ROOT_CLK] = imx_clk_gate2("uart4_root_clk", "uart4_post_div", base + 0x4970, 0); + clks[IMX7D_UART5_ROOT_CLK] = imx_clk_gate2("uart5_root_clk", "uart5_post_div", base + 0x4980, 0); + clks[IMX7D_UART6_ROOT_CLK] = imx_clk_gate2("uart6_root_clk", "uart6_post_div", base + 0x4990, 0); + clks[IMX7D_UART7_ROOT_CLK] = imx_clk_gate2("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0); + clks[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_gate2("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0); + clks[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_gate2("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0); + clks[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_gate2("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0); + clks[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_gate2("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0); + clks[IMX7D_PWM1_ROOT_CLK] = imx_clk_gate2("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0); + clks[IMX7D_PWM2_ROOT_CLK] = imx_clk_gate2("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0); + clks[IMX7D_PWM3_ROOT_CLK] = imx_clk_gate2("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0); + clks[IMX7D_PWM4_ROOT_CLK] = imx_clk_gate2("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0); + clks[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_gate2("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0); + clks[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_gate2("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0); + clks[IMX7D_SIM1_ROOT_CLK] = imx_clk_gate2("sim1_root_clk", "sim1_post_div", base + 0x4900, 0); + clks[IMX7D_SIM2_ROOT_CLK] = imx_clk_gate2("sim2_root_clk", "sim2_post_div", base + 0x4910, 0); + clks[IMX7D_GPT1_ROOT_CLK] = imx_clk_gate2("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0); + clks[IMX7D_GPT2_ROOT_CLK] = imx_clk_gate2("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0); + clks[IMX7D_GPT3_ROOT_CLK] = imx_clk_gate2("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0); + clks[IMX7D_GPT4_ROOT_CLK] = imx_clk_gate2("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0); + clks[IMX7D_TRACE_ROOT_CLK] = imx_clk_gate2("trace_root_clk", "trace_post_div", base + 0x4300, 0); + clks[IMX7D_WDOG1_ROOT_CLK] = imx_clk_gate2("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0); + clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate2("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0); + clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate2("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0); + clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate2("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0); + clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); + clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); + clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); + + clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); + + for (i = 0; i < ARRAY_SIZE(clks); i++) + if (IS_ERR(clks[i])) + pr_err("i.MX7D clk %d: register failed with %ld\n", + i, PTR_ERR(clks[i])); + + clk_data.clks = clks; + clk_data.clk_num = ARRAY_SIZE(clks); + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + + /* TO BE FIXED LATER + * Enable all clock to bring up imx7, otherwise system will be halt and block + * the other part upstream Because imx7d clock design changed, clock framework + * need do a little modify. + * Dong Aisheng is working on this. After that, this part need be changed. + */ + for (i = 0; i < IMX7D_CLK_END; i++) + clk_prepare_enable(clks[i]); + + /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */ + clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); + + /* + * init enet clock source: + * AXI clock source is 250MHz + * Phy refrence clock is 25MHz + * 1588 time clock source is 100MHz + */ + clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]); + clk_set_parent(clks[IMX7D_ENET_PHY_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_25M_CLK]); + clk_set_parent(clks[IMX7D_ENET1_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]); + clk_set_parent(clks[IMX7D_ENET2_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]); + + /* set uart module clock's parent clock source that must be great then 80MHz */ + clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); + +} +CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init); From f6d4750298568778bd4ff86ae83983ac41290188 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 19 May 2015 18:37:49 -0700 Subject: [PATCH 27/44] ARM: mach-imx: iomux-imx31: Use DECLARE_BITMAP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the generic mechanism to declare a bitmap instead of unsigned long. Signed-off-by: Joe Perches Acked-by: Uwe Kleine-König Signed-off-by: Shawn Guo --- arch/arm/mach-imx/iomux-imx31.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c index d6a30753ca7c..6dd22cabf4d3 100644 --- a/arch/arm/mach-imx/iomux-imx31.c +++ b/arch/arm/mach-imx/iomux-imx31.c @@ -40,7 +40,7 @@ static DEFINE_SPINLOCK(gpio_mux_lock); #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) -static unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG]; +static DECLARE_BITMAP(mxc_pin_alloc_map, NB_PORTS * 32); /* * set the mode for a IOMUX pin. */ From fbfd617ea4ff5a1b8a049521eaf69fe554025569 Mon Sep 17 00:00:00 2001 From: Mirza Krak Date: Wed, 20 May 2015 11:38:03 +0200 Subject: [PATCH 28/44] ARM: imx: clk-v610: Add clock for I2C2 and I2C3 Add support for clock gating of I2C2 and I2C3. We use I2C2 in a (not yet mainlined) device tree. Signed-off-by: Mirza Krak Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-vf610.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 1c2d3240efe7..bff45ead7389 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -273,6 +273,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6)); clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7)); + clk[VF610_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(6)); + clk[VF610_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(7)); clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12)); clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13)); From da946aeaeadcd24ff0cda9984c6fb8ed2bfd462a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Szymanski?= Date: Wed, 20 May 2015 16:30:37 +0200 Subject: [PATCH 29/44] ARM: clk-imx6q: refine sata's parent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to IMX6D/Q RM, table 18-3, sata clock's parent is ahb, not ipg. Signed-off-by: Sébastien Szymanski Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx6q.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index 128f8871cbd8..d046f8e43de8 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -450,7 +450,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); clk[IMX6QDL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); - clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); + clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); From e20d7b5208c86111ead338ded8b25a0970eee661 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 21 May 2015 14:06:30 +0200 Subject: [PATCH 30/44] ARM: imx: make imx51/3 suspend optional A recent change to the imx53 power management caused a build regression when CONFIG_SOC_IMX53 is disabled: mach-imx/built-in.o:(.init.rodata+0x60): undefined reference to `imx53_suspend' mach-imx/built-in.o:(.init.rodata+0x64): undefined reference to `imx53_suspend_sz' This avoids the problem by compiling the code in question conditionally on the presence of CONFIG_SOC_IMX53. For consistency, I'm also changing the same thing for CONFIG_SOC_IMX51. An additional benefit of this approach is reduced code size for kernels that only include support for one of the two SoCs. Signed-off-by: Arnd Bergmann Fixes: 1579c7b9fe01 ("ARM: imx53: Set DDR pins to high impedance when in suspend to RAM.") Signed-off-by: Shawn Guo --- arch/arm/mach-imx/pm-imx5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index a8d00b9c9236..0309ccda36a9 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -413,10 +413,12 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) void __init imx51_pm_init(void) { - imx5_pm_common_init(&imx51_pm_data); + if (IS_ENABLED(CONFIG_SOC_IMX51)) + imx5_pm_common_init(&imx51_pm_data); } void __init imx53_pm_init(void) { - imx5_pm_common_init(&imx53_pm_data); + if (IS_ENABLED(CONFIG_SOC_IMX53)) + imx5_pm_common_init(&imx53_pm_data); } From c7770bbae276135ec59370159e60497593cc6b46 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 19 May 2015 18:47:47 +0800 Subject: [PATCH 31/44] ARM: imx: use relaxed IO accessor in timer driver Replace the __raw_readl/__raw_writel with readl_relaxed/writel_relaxed which is endian-safe, as a step of moving the driver code into folder drivers/clocksource. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index ab5ee1c445f3..376d5d8ccfb8 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -91,19 +91,19 @@ static inline void gpt_irq_disable(void) unsigned int tmp; if (timer_is_v2()) - __raw_writel(0, timer_base + V2_IR); + writel_relaxed(0, timer_base + V2_IR); else { - tmp = __raw_readl(timer_base + MXC_TCTL); - __raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL); + tmp = readl_relaxed(timer_base + MXC_TCTL); + writel_relaxed(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL); } } static inline void gpt_irq_enable(void) { if (timer_is_v2()) - __raw_writel(1<<0, timer_base + V2_IR); + writel_relaxed(1<<0, timer_base + V2_IR); else { - __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, + writel_relaxed(readl_relaxed(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL); } } @@ -112,26 +112,26 @@ static void gpt_irq_acknowledge(void) { if (timer_is_v1()) { if (cpu_is_mx1()) - __raw_writel(0, timer_base + MX1_2_TSTAT); + writel_relaxed(0, timer_base + MX1_2_TSTAT); else - __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, + writel_relaxed(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT); } else if (timer_is_v2()) - __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT); + writel_relaxed(V2_TSTAT_OF1, timer_base + V2_TSTAT); } static void __iomem *sched_clock_reg; static u64 notrace mxc_read_sched_clock(void) { - return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; + return sched_clock_reg ? readl_relaxed(sched_clock_reg) : 0; } static struct delay_timer imx_delay_timer; static unsigned long imx_read_current_timer(void) { - return __raw_readl(sched_clock_reg); + return readl_relaxed(sched_clock_reg); } static int __init mxc_clocksource_init(struct clk *timer_clk) @@ -157,11 +157,11 @@ static int mx1_2_set_next_event(unsigned long evt, { unsigned long tcmp; - tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt; + tcmp = readl_relaxed(timer_base + MX1_2_TCN) + evt; - __raw_writel(tcmp, timer_base + MX1_2_TCMP); + writel_relaxed(tcmp, timer_base + MX1_2_TCMP); - return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ? + return (int)(tcmp - readl_relaxed(timer_base + MX1_2_TCN)) < 0 ? -ETIME : 0; } @@ -170,12 +170,12 @@ static int v2_set_next_event(unsigned long evt, { unsigned long tcmp; - tcmp = __raw_readl(timer_base + V2_TCN) + evt; + tcmp = readl_relaxed(timer_base + V2_TCN) + evt; - __raw_writel(tcmp, timer_base + V2_TCMP); + writel_relaxed(tcmp, timer_base + V2_TCMP); return evt < 0x7fffffff && - (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ? + (int)(tcmp - readl_relaxed(timer_base + V2_TCN)) < 0 ? -ETIME : 0; } @@ -206,10 +206,10 @@ static void mxc_set_mode(enum clock_event_mode mode, if (mode != clockevent_mode) { /* Set event time into far-far future */ if (timer_is_v2()) - __raw_writel(__raw_readl(timer_base + V2_TCN) - 3, + writel_relaxed(readl_relaxed(timer_base + V2_TCN) - 3, timer_base + V2_TCMP); else - __raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3, + writel_relaxed(readl_relaxed(timer_base + MX1_2_TCN) - 3, timer_base + MX1_2_TCMP); /* Clear pending interrupt */ @@ -259,9 +259,9 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) uint32_t tstat; if (timer_is_v2()) - tstat = __raw_readl(timer_base + V2_TSTAT); + tstat = readl_relaxed(timer_base + V2_TSTAT); else - tstat = __raw_readl(timer_base + MX1_2_TSTAT); + tstat = readl_relaxed(timer_base + MX1_2_TSTAT); gpt_irq_acknowledge(); @@ -316,8 +316,8 @@ static void __init _mxc_timer_init(int irq, * Initialise to a known state (all timers off, and timing reset) */ - __raw_writel(0, timer_base + MXC_TCTL); - __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ + writel_relaxed(0, timer_base + MXC_TCTL); + writel_relaxed(0, timer_base + MXC_TPRER); /* see datasheet note */ if (timer_is_v2()) { tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; @@ -325,7 +325,7 @@ static void __init _mxc_timer_init(int irq, tctl_val |= V2_TCTL_CLK_OSC_DIV8; if (cpu_is_imx6dl() || cpu_is_imx6sx()) { /* 24 / 8 = 3 MHz */ - __raw_writel(7 << V2_TPRER_PRE24M, + writel_relaxed(7 << V2_TPRER_PRE24M, timer_base + MXC_TPRER); tctl_val |= V2_TCTL_24MEN; } @@ -336,7 +336,7 @@ static void __init _mxc_timer_init(int irq, tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; } - __raw_writel(tctl_val, timer_base + MXC_TCTL); + writel_relaxed(tctl_val, timer_base + MXC_TCTL); /* init and register the timer to the framework */ mxc_clocksource_init(clk_per); From 6dd747825b206e9863c80c8b311fd2ed0964140a Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 22 May 2015 13:53:45 +0800 Subject: [PATCH 32/44] ARM: imx: move timer resources into a structure Instead of passing around as individual argument, let's move timer resources like irq and clocks together with base address into a data structure, and pass pointer of the structure as argument to simplify the function call interface. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 91 ++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 376d5d8ccfb8..7c131e1b2637 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,13 @@ static struct clock_event_device clockevent_mxc; static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; +struct imx_timer { + void __iomem *base; + int irq; + struct clk *clk_per; + struct clk *clk_ipg; +}; + static void __iomem *timer_base; static inline void gpt_irq_disable(void) @@ -134,10 +142,10 @@ static unsigned long imx_read_current_timer(void) return readl_relaxed(sched_clock_reg); } -static int __init mxc_clocksource_init(struct clk *timer_clk) +static int __init mxc_clocksource_init(struct imx_timer *imxtm) { - unsigned int c = clk_get_rate(timer_clk); - void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN); + unsigned int c = clk_get_rate(imxtm->clk_per); + void __iomem *reg = imxtm->base + (timer_is_v2() ? V2_TCN : MX1_2_TCN); imx_delay_timer.read_current_timer = &imx_read_current_timer; imx_delay_timer.freq = c; @@ -284,49 +292,51 @@ static struct clock_event_device clockevent_mxc = { .rating = 200, }; -static int __init mxc_clockevent_init(struct clk *timer_clk) +static int __init mxc_clockevent_init(struct imx_timer *imxtm) { if (timer_is_v2()) clockevent_mxc.set_next_event = v2_set_next_event; clockevent_mxc.cpumask = cpumask_of(0); clockevents_config_and_register(&clockevent_mxc, - clk_get_rate(timer_clk), + clk_get_rate(imxtm->clk_per), 0xff, 0xfffffffe); return 0; } -static void __init _mxc_timer_init(int irq, - struct clk *clk_per, struct clk *clk_ipg) +static void __init _mxc_timer_init(struct imx_timer *imxtm) { uint32_t tctl_val; - if (IS_ERR(clk_per)) { + /* Temporary */ + timer_base = imxtm->base; + + if (IS_ERR(imxtm->clk_per)) { pr_err("i.MX timer: unable to get clk\n"); return; } - if (!IS_ERR(clk_ipg)) - clk_prepare_enable(clk_ipg); + if (!IS_ERR(imxtm->clk_ipg)) + clk_prepare_enable(imxtm->clk_ipg); - clk_prepare_enable(clk_per); + clk_prepare_enable(imxtm->clk_per); /* * Initialise to a known state (all timers off, and timing reset) */ - writel_relaxed(0, timer_base + MXC_TCTL); - writel_relaxed(0, timer_base + MXC_TPRER); /* see datasheet note */ + writel_relaxed(0, imxtm->base + MXC_TCTL); + writel_relaxed(0, imxtm->base + MXC_TPRER); /* see datasheet note */ if (timer_is_v2()) { tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; - if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) { + if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8) { tctl_val |= V2_TCTL_CLK_OSC_DIV8; if (cpu_is_imx6dl() || cpu_is_imx6sx()) { /* 24 / 8 = 3 MHz */ writel_relaxed(7 << V2_TPRER_PRE24M, - timer_base + MXC_TPRER); + imxtm->base + MXC_TPRER); tctl_val |= V2_TCTL_24MEN; } } else { @@ -336,47 +346,58 @@ static void __init _mxc_timer_init(int irq, tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; } - writel_relaxed(tctl_val, timer_base + MXC_TCTL); + writel_relaxed(tctl_val, imxtm->base + MXC_TCTL); /* init and register the timer to the framework */ - mxc_clocksource_init(clk_per); - mxc_clockevent_init(clk_per); + mxc_clocksource_init(imxtm); + mxc_clockevent_init(imxtm); /* Make irqs happen */ - setup_irq(irq, &mxc_timer_irq); + setup_irq(imxtm->irq, &mxc_timer_irq); } void __init mxc_timer_init(unsigned long pbase, int irq) { - struct clk *clk_per = clk_get_sys("imx-gpt.0", "per"); - struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg"); + struct imx_timer *imxtm; - timer_base = ioremap(pbase, SZ_4K); - BUG_ON(!timer_base); + imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL); + BUG_ON(!imxtm); - _mxc_timer_init(irq, clk_per, clk_ipg); + imxtm->clk_per = clk_get_sys("imx-gpt.0", "per"); + imxtm->clk_ipg = clk_get_sys("imx-gpt.0", "ipg"); + + imxtm->base = ioremap(pbase, SZ_4K); + BUG_ON(!imxtm->base); + + _mxc_timer_init(imxtm); } static void __init mxc_timer_init_dt(struct device_node *np) { - struct clk *clk_per, *clk_ipg; - int irq; + struct imx_timer *imxtm; + static int initialized; - if (timer_base) + /* Support one instance only */ + if (initialized) return; - timer_base = of_iomap(np, 0); - WARN_ON(!timer_base); - irq = irq_of_parse_and_map(np, 0); + imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL); + BUG_ON(!imxtm); - clk_ipg = of_clk_get_by_name(np, "ipg"); + imxtm->base = of_iomap(np, 0); + WARN_ON(!imxtm->base); + imxtm->irq = irq_of_parse_and_map(np, 0); + + imxtm->clk_ipg = of_clk_get_by_name(np, "ipg"); /* Try osc_per first, and fall back to per otherwise */ - clk_per = of_clk_get_by_name(np, "osc_per"); - if (IS_ERR(clk_per)) - clk_per = of_clk_get_by_name(np, "per"); + imxtm->clk_per = of_clk_get_by_name(np, "osc_per"); + if (IS_ERR(imxtm->clk_per)) + imxtm->clk_per = of_clk_get_by_name(np, "per"); - _mxc_timer_init(irq, clk_per, clk_ipg); + _mxc_timer_init(imxtm); + + initialized = 1; } CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt); CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt); From 0931aff7226abb7e1dab018488e363294385fa66 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 15 May 2015 11:41:39 +0800 Subject: [PATCH 33/44] ARM: imx: define an enum for gpt timer device type Define an enum for gpt timer device type in include/soc/imx/timer.h to tell the gpt block differences among SoCs. Update non-DT users (clock drivers) to pass the device type. As we now have include/soc/imx/timer.h, the declaration of mxc_timer_init() is moved into there as the best fit. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 6 +++++- drivers/clk/imx/clk-imx1.c | 3 ++- drivers/clk/imx/clk-imx21.c | 3 ++- drivers/clk/imx/clk-imx27.c | 3 ++- drivers/clk/imx/clk-imx31.c | 3 ++- drivers/clk/imx/clk-imx35.c | 3 ++- drivers/clk/imx/clk.h | 7 ------- include/soc/imx/timer.h | 26 ++++++++++++++++++++++++++ 8 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 include/soc/imx/timer.h diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 7c131e1b2637..307cbc7abc8e 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -86,6 +87,7 @@ static struct clock_event_device clockevent_mxc; static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; struct imx_timer { + enum imx_gpt_type type; void __iomem *base; int irq; struct clk *clk_per; @@ -356,7 +358,7 @@ static void __init _mxc_timer_init(struct imx_timer *imxtm) setup_irq(imxtm->irq, &mxc_timer_irq); } -void __init mxc_timer_init(unsigned long pbase, int irq) +void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type) { struct imx_timer *imxtm; @@ -369,6 +371,8 @@ void __init mxc_timer_init(unsigned long pbase, int irq) imxtm->base = ioremap(pbase, SZ_4K); BUG_ON(!imxtm->base); + imxtm->type = type; + _mxc_timer_init(imxtm); } diff --git a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c index c9812dbacac2..c2647fa19f28 100644 --- a/drivers/clk/imx/clk-imx1.c +++ b/drivers/clk/imx/clk-imx1.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "clk.h" @@ -102,7 +103,7 @@ int __init mx1_clocks_init(unsigned long fref) clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0"); clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0"); - mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT); + mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT, GPT_TYPE_IMX1); return 0; } diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c index 0ca842cf4ca7..dba987e3b89f 100644 --- a/drivers/clk/imx/clk-imx21.c +++ b/drivers/clk/imx/clk-imx21.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "clk.h" @@ -156,7 +157,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0"); clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0"); - mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1); + mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, GPT_TYPE_IMX21); return 0; } diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c index df2dfc081c71..d9d50d54ef2a 100644 --- a/drivers/clk/imx/clk-imx27.c +++ b/drivers/clk/imx/clk-imx27.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "clk.h" @@ -233,7 +234,7 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0"); clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0"); - mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1); + mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1, GPT_TYPE_IMX21); return 0; } diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c index a55290c1c264..fe66c40b7be2 100644 --- a/drivers/clk/imx/clk-imx31.c +++ b/drivers/clk/imx/clk-imx31.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "clk.h" @@ -198,7 +199,7 @@ int __init mx31_clocks_init(unsigned long fref) mx31_revision(); clk_disable_unprepare(clk[iim_gate]); - mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT); + mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31); return 0; } diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c index f2f3b8164f7b..69138ba3dec7 100644 --- a/drivers/clk/imx/clk-imx35.c +++ b/drivers/clk/imx/clk-imx35.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "clk.h" @@ -293,7 +294,7 @@ int __init mx35_clocks_init(void) imx_print_silicon_rev("i.MX35", mx35_revision()); - mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT); + mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31); return 0; } diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 8b112182a83b..1049b0c7d818 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -6,13 +6,6 @@ extern spinlock_t imx_ccm_lock; -/* - * This is a stop-gap solution for clock drivers like imx1/imx21 which call - * mxc_timer_init() to initialize timer for non-DT boot. It can be removed - * when these legacy non-DT support is converted or dropped. - */ -void mxc_timer_init(unsigned long pbase, int irq); - void imx_check_clocks(struct clk *clks[], unsigned int count); extern void imx_cscmr1_fixup(u32 *val); diff --git a/include/soc/imx/timer.h b/include/soc/imx/timer.h new file mode 100644 index 000000000000..bbbafd65f464 --- /dev/null +++ b/include/soc/imx/timer.h @@ -0,0 +1,26 @@ +/* + * Copyright 2015 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __SOC_IMX_TIMER_H__ +#define __SOC_IMX_TIMER_H__ + +enum imx_gpt_type { + GPT_TYPE_IMX1, /* i.MX1 */ + GPT_TYPE_IMX21, /* i.MX21/27 */ + GPT_TYPE_IMX31, /* i.MX31/35/25/37/51/6Q */ + GPT_TYPE_IMX6DL, /* i.MX6DL/SX/SL */ +}; + +/* + * This is a stop-gap solution for clock drivers like imx1/imx21 which call + * mxc_timer_init() to initialize timer for non-DT boot. It can be removed + * when these legacy non-DT support is converted or dropped. + */ +void mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type); + +#endif /* __SOC_IMX_TIMER_H__ */ From bef11c881ba52a6481b64f9a84cca75c3bf9d325 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 15 May 2015 13:38:20 +0800 Subject: [PATCH 34/44] ARM: imx: initialize gpt device type for DT boot Use different initialization function in CLOCKSOURCE_OF_DECLARE() to initialize gpt device type for DT boot. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 55 +++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 307cbc7abc8e..594f7f786e9a 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -376,7 +376,7 @@ void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type) _mxc_timer_init(imxtm); } -static void __init mxc_timer_init_dt(struct device_node *np) +static void __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type type) { struct imx_timer *imxtm; static int initialized; @@ -399,15 +399,52 @@ static void __init mxc_timer_init_dt(struct device_node *np) if (IS_ERR(imxtm->clk_per)) imxtm->clk_per = of_clk_get_by_name(np, "per"); + imxtm->type = type; + _mxc_timer_init(imxtm); initialized = 1; } -CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", mxc_timer_init_dt); + +static void __init imx1_timer_init_dt(struct device_node *np) +{ + mxc_timer_init_dt(np, GPT_TYPE_IMX1); +} + +static void __init imx21_timer_init_dt(struct device_node *np) +{ + mxc_timer_init_dt(np, GPT_TYPE_IMX21); +} + +static void __init imx31_timer_init_dt(struct device_node *np) +{ + enum imx_gpt_type type = GPT_TYPE_IMX31; + + /* + * We were using the same compatible string for i.MX6Q/D and i.MX6DL/S + * GPT device, while they actually have different programming model. + * This is a workaround to keep the existing i.MX6DL/S DTBs continue + * working with the new kernel. + */ + if (of_machine_is_compatible("fsl,imx6dl")) + type = GPT_TYPE_IMX6DL; + + mxc_timer_init_dt(np, type); +} + +static void __init imx6dl_timer_init_dt(struct device_node *np) +{ + mxc_timer_init_dt(np, GPT_TYPE_IMX6DL); +} + +CLOCKSOURCE_OF_DECLARE(imx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx21_timer, "fsl,imx21-gpt", imx21_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx31_timer, "fsl,imx31-gpt", imx31_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx25_timer, "fsl,imx25-gpt", imx31_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx50_timer, "fsl,imx50-gpt", imx31_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx51_timer, "fsl,imx51-gpt", imx31_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx53_timer, "fsl,imx53-gpt", imx31_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx6q_timer, "fsl,imx6q-gpt", imx31_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx6dl_timer, "fsl,imx6dl-gpt", imx6dl_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx6sl_timer, "fsl,imx6sl-gpt", imx6dl_timer_init_dt); +CLOCKSOURCE_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt); From 9c8694bd6c1e9e40a532c5c609288d6bc95d05b4 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 15 May 2015 14:24:41 +0800 Subject: [PATCH 35/44] ARM: imx: setup tctl register in device specific function It creates a gpt device speicific data structure and adds function hook gpt_setup_tctl in there to set up gpt TCTL register. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 98 ++++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 594f7f786e9a..6142740e8000 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -92,6 +92,11 @@ struct imx_timer { int irq; struct clk *clk_per; struct clk *clk_ipg; + const struct imx_gpt_data *gpt; +}; + +struct imx_gpt_data { + void (*gpt_setup_tctl)(struct imx_timer *imxtm); }; static void __iomem *timer_base; @@ -307,13 +312,83 @@ static int __init mxc_clockevent_init(struct imx_timer *imxtm) return 0; } +static void imx1_gpt_setup_tctl(struct imx_timer *imxtm) +{ + u32 tctl_val; + + tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; + writel_relaxed(tctl_val, imxtm->base + MXC_TCTL); +} +#define imx21_gpt_setup_tctl imx1_gpt_setup_tctl + +static void imx31_gpt_setup_tctl(struct imx_timer *imxtm) +{ + u32 tctl_val; + + tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; + if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8) + tctl_val |= V2_TCTL_CLK_OSC_DIV8; + else + tctl_val |= V2_TCTL_CLK_PER; + + writel_relaxed(tctl_val, imxtm->base + MXC_TCTL); +} + +static void imx6dl_gpt_setup_tctl(struct imx_timer *imxtm) +{ + u32 tctl_val; + + tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; + if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8) { + tctl_val |= V2_TCTL_CLK_OSC_DIV8; + /* 24 / 8 = 3 MHz */ + writel_relaxed(7 << V2_TPRER_PRE24M, imxtm->base + MXC_TPRER); + tctl_val |= V2_TCTL_24MEN; + } else { + tctl_val |= V2_TCTL_CLK_PER; + } + + writel_relaxed(tctl_val, imxtm->base + MXC_TCTL); +} + +static const struct imx_gpt_data imx1_gpt_data = { + .gpt_setup_tctl = imx1_gpt_setup_tctl, +}; + +static const struct imx_gpt_data imx21_gpt_data = { + .gpt_setup_tctl = imx21_gpt_setup_tctl, +}; + +static const struct imx_gpt_data imx31_gpt_data = { + .gpt_setup_tctl = imx31_gpt_setup_tctl, +}; + +static const struct imx_gpt_data imx6dl_gpt_data = { + .gpt_setup_tctl = imx6dl_gpt_setup_tctl, +}; + static void __init _mxc_timer_init(struct imx_timer *imxtm) { - uint32_t tctl_val; - /* Temporary */ timer_base = imxtm->base; + switch (imxtm->type) { + case GPT_TYPE_IMX1: + imxtm->gpt = &imx1_gpt_data; + break; + case GPT_TYPE_IMX21: + imxtm->gpt = &imx21_gpt_data; + break; + case GPT_TYPE_IMX31: + imxtm->gpt = &imx31_gpt_data; + break; + case GPT_TYPE_IMX6DL: + imxtm->gpt = &imx6dl_gpt_data; + break; + default: + BUG(); + } + if (IS_ERR(imxtm->clk_per)) { pr_err("i.MX timer: unable to get clk\n"); return; @@ -331,24 +406,7 @@ static void __init _mxc_timer_init(struct imx_timer *imxtm) writel_relaxed(0, imxtm->base + MXC_TCTL); writel_relaxed(0, imxtm->base + MXC_TPRER); /* see datasheet note */ - if (timer_is_v2()) { - tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; - if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8) { - tctl_val |= V2_TCTL_CLK_OSC_DIV8; - if (cpu_is_imx6dl() || cpu_is_imx6sx()) { - /* 24 / 8 = 3 MHz */ - writel_relaxed(7 << V2_TPRER_PRE24M, - imxtm->base + MXC_TPRER); - tctl_val |= V2_TCTL_24MEN; - } - } else { - tctl_val |= V2_TCTL_CLK_PER; - } - } else { - tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; - } - - writel_relaxed(tctl_val, imxtm->base + MXC_TCTL); + imxtm->gpt->gpt_setup_tctl(imxtm); /* init and register the timer to the framework */ mxc_clocksource_init(imxtm); From 5ab0475b70ccdb349812d932a84dec86029a84d7 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 22 May 2015 15:51:41 +0800 Subject: [PATCH 36/44] ARM: imx: set up .set_next_event hook via imx_gpt_data Set up .set_next_event hook via imx_gpt_data, so that we can save the use of timer_is_v2(). Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 6142740e8000..b16a4e07d1ec 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -97,6 +97,8 @@ struct imx_timer { struct imx_gpt_data { void (*gpt_setup_tctl)(struct imx_timer *imxtm); + int (*set_next_event)(unsigned long evt, + struct clock_event_device *ced); }; static void __iomem *timer_base; @@ -301,9 +303,7 @@ static struct clock_event_device clockevent_mxc = { static int __init mxc_clockevent_init(struct imx_timer *imxtm) { - if (timer_is_v2()) - clockevent_mxc.set_next_event = v2_set_next_event; - + clockevent_mxc.set_next_event = imxtm->gpt->set_next_event; clockevent_mxc.cpumask = cpumask_of(0); clockevents_config_and_register(&clockevent_mxc, clk_get_rate(imxtm->clk_per), @@ -353,18 +353,22 @@ static void imx6dl_gpt_setup_tctl(struct imx_timer *imxtm) static const struct imx_gpt_data imx1_gpt_data = { .gpt_setup_tctl = imx1_gpt_setup_tctl, + .set_next_event = mx1_2_set_next_event, }; static const struct imx_gpt_data imx21_gpt_data = { .gpt_setup_tctl = imx21_gpt_setup_tctl, + .set_next_event = mx1_2_set_next_event, }; static const struct imx_gpt_data imx31_gpt_data = { .gpt_setup_tctl = imx31_gpt_setup_tctl, + .set_next_event = v2_set_next_event, }; static const struct imx_gpt_data imx6dl_gpt_data = { .gpt_setup_tctl = imx6dl_gpt_setup_tctl, + .set_next_event = v2_set_next_event, }; static void __init _mxc_timer_init(struct imx_timer *imxtm) From e510d2015d38a2bfbaebf9793f28377b6328e409 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 22 May 2015 16:38:49 +0800 Subject: [PATCH 37/44] ARM: imx: move clock event variables into imx_timer Since we now have imx_timer structure, it makes more sense to move those clock event related variables into the structure, so that we can save some global variables. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 64 +++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index b16a4e07d1ec..127602e14efb 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -83,9 +83,6 @@ #define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) #define timer_is_v2() (!timer_is_v1()) -static struct clock_event_device clockevent_mxc; -static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; - struct imx_timer { enum imx_gpt_type type; void __iomem *base; @@ -93,6 +90,9 @@ struct imx_timer { struct clk *clk_per; struct clk *clk_ipg; const struct imx_gpt_data *gpt; + struct clock_event_device ced; + enum clock_event_mode cem; + struct irqaction act; }; struct imx_gpt_data { @@ -103,6 +103,11 @@ struct imx_gpt_data { static void __iomem *timer_base; +static inline struct imx_timer *to_imx_timer(struct clock_event_device *ced) +{ + return container_of(ced, struct imx_timer, ced); +} + static inline void gpt_irq_disable(void) { unsigned int tmp; @@ -207,8 +212,9 @@ static const char *clock_event_mode_label[] = { #endif /* DEBUG */ static void mxc_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) + struct clock_event_device *ced) { + struct imx_timer *imxtm = to_imx_timer(ced); unsigned long flags; /* @@ -220,7 +226,7 @@ static void mxc_set_mode(enum clock_event_mode mode, /* Disable interrupt in GPT module */ gpt_irq_disable(); - if (mode != clockevent_mode) { + if (mode != imxtm->cem) { /* Set event time into far-far future */ if (timer_is_v2()) writel_relaxed(readl_relaxed(timer_base + V2_TCN) - 3, @@ -235,12 +241,12 @@ static void mxc_set_mode(enum clock_event_mode mode, #ifdef DEBUG printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n", - clock_event_mode_label[clockevent_mode], + clock_event_mode_label[imxtm->cem], clock_event_mode_label[mode]); #endif /* DEBUG */ /* Remember timer mode */ - clockevent_mode = mode; + imxtm->cem = mode; local_irq_restore(flags); switch (mode) { @@ -272,7 +278,7 @@ static void mxc_set_mode(enum clock_event_mode mode, */ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) { - struct clock_event_device *evt = &clockevent_mxc; + struct clock_event_device *ced = dev_id; uint32_t tstat; if (timer_is_v2()) @@ -282,34 +288,33 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) gpt_irq_acknowledge(); - evt->event_handler(evt); + ced->event_handler(ced); return IRQ_HANDLED; } -static struct irqaction mxc_timer_irq = { - .name = "i.MX Timer Tick", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = mxc_timer_interrupt, -}; - -static struct clock_event_device clockevent_mxc = { - .name = "mxc_timer1", - .features = CLOCK_EVT_FEAT_ONESHOT, - .set_mode = mxc_set_mode, - .set_next_event = mx1_2_set_next_event, - .rating = 200, -}; - static int __init mxc_clockevent_init(struct imx_timer *imxtm) { - clockevent_mxc.set_next_event = imxtm->gpt->set_next_event; - clockevent_mxc.cpumask = cpumask_of(0); - clockevents_config_and_register(&clockevent_mxc, - clk_get_rate(imxtm->clk_per), + struct clock_event_device *ced = &imxtm->ced; + struct irqaction *act = &imxtm->act; + + imxtm->cem = CLOCK_EVT_MODE_UNUSED; + + ced->name = "mxc_timer1"; + ced->features = CLOCK_EVT_FEAT_ONESHOT; + ced->set_mode = mxc_set_mode; + ced->set_next_event = imxtm->gpt->set_next_event; + ced->rating = 200; + ced->cpumask = cpumask_of(0); + clockevents_config_and_register(ced, clk_get_rate(imxtm->clk_per), 0xff, 0xfffffffe); - return 0; + act->name = "i.MX Timer Tick"; + act->flags = IRQF_TIMER | IRQF_IRQPOLL; + act->handler = mxc_timer_interrupt; + act->dev_id = ced; + + return setup_irq(imxtm->irq, act); } static void imx1_gpt_setup_tctl(struct imx_timer *imxtm) @@ -415,9 +420,6 @@ static void __init _mxc_timer_init(struct imx_timer *imxtm) /* init and register the timer to the framework */ mxc_clocksource_init(imxtm); mxc_clockevent_init(imxtm); - - /* Make irqs happen */ - setup_irq(imxtm->irq, &mxc_timer_irq); } void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type) From 24f74ad1c75e9893db4386ed9c7f8c20cdbc3198 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 22 May 2015 21:39:55 +0800 Subject: [PATCH 38/44] ARM: imx: define gpt register offset per device type It defines offset of gpt registers TSTAT, TCN and TCMP per device type in imx_gpt_data, so that these registers can be accessed in an way without timer_is_v2() checking. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 127602e14efb..61b850e9510d 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -96,6 +96,9 @@ struct imx_timer { }; struct imx_gpt_data { + int reg_tstat; + int reg_tcn; + int reg_tcmp; void (*gpt_setup_tctl)(struct imx_timer *imxtm); int (*set_next_event)(unsigned long evt, struct clock_event_device *ced); @@ -159,7 +162,7 @@ static unsigned long imx_read_current_timer(void) static int __init mxc_clocksource_init(struct imx_timer *imxtm) { unsigned int c = clk_get_rate(imxtm->clk_per); - void __iomem *reg = imxtm->base + (timer_is_v2() ? V2_TCN : MX1_2_TCN); + void __iomem *reg = imxtm->base + imxtm->gpt->reg_tcn; imx_delay_timer.read_current_timer = &imx_read_current_timer; imx_delay_timer.freq = c; @@ -227,13 +230,9 @@ static void mxc_set_mode(enum clock_event_mode mode, gpt_irq_disable(); if (mode != imxtm->cem) { + u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn); /* Set event time into far-far future */ - if (timer_is_v2()) - writel_relaxed(readl_relaxed(timer_base + V2_TCN) - 3, - timer_base + V2_TCMP); - else - writel_relaxed(readl_relaxed(timer_base + MX1_2_TCN) - 3, - timer_base + MX1_2_TCMP); + writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp); /* Clear pending interrupt */ gpt_irq_acknowledge(); @@ -279,12 +278,10 @@ static void mxc_set_mode(enum clock_event_mode mode, static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *ced = dev_id; + struct imx_timer *imxtm = to_imx_timer(ced); uint32_t tstat; - if (timer_is_v2()) - tstat = readl_relaxed(timer_base + V2_TSTAT); - else - tstat = readl_relaxed(timer_base + MX1_2_TSTAT); + tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat); gpt_irq_acknowledge(); @@ -357,21 +354,33 @@ static void imx6dl_gpt_setup_tctl(struct imx_timer *imxtm) } static const struct imx_gpt_data imx1_gpt_data = { + .reg_tstat = MX1_2_TSTAT, + .reg_tcn = MX1_2_TCN, + .reg_tcmp = MX1_2_TCMP, .gpt_setup_tctl = imx1_gpt_setup_tctl, .set_next_event = mx1_2_set_next_event, }; static const struct imx_gpt_data imx21_gpt_data = { + .reg_tstat = MX1_2_TSTAT, + .reg_tcn = MX1_2_TCN, + .reg_tcmp = MX1_2_TCMP, .gpt_setup_tctl = imx21_gpt_setup_tctl, .set_next_event = mx1_2_set_next_event, }; static const struct imx_gpt_data imx31_gpt_data = { + .reg_tstat = V2_TSTAT, + .reg_tcn = V2_TCN, + .reg_tcmp = V2_TCMP, .gpt_setup_tctl = imx31_gpt_setup_tctl, .set_next_event = v2_set_next_event, }; static const struct imx_gpt_data imx6dl_gpt_data = { + .reg_tstat = V2_TSTAT, + .reg_tcn = V2_TCN, + .reg_tcmp = V2_TCMP, .gpt_setup_tctl = imx6dl_gpt_setup_tctl, .set_next_event = v2_set_next_event, }; From 89955520851064ff4bd39714aea947fe7104be73 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 22 May 2015 22:23:28 +0800 Subject: [PATCH 39/44] ARM: imx: get rid of variable timer_base We now have pointer to imx_timer structure available where timer base address is needed, so we can just kill global timer_base by using imxtm->base instead. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 55 +++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 61b850e9510d..c7e2287670cf 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -104,45 +104,43 @@ struct imx_gpt_data { struct clock_event_device *ced); }; -static void __iomem *timer_base; - static inline struct imx_timer *to_imx_timer(struct clock_event_device *ced) { return container_of(ced, struct imx_timer, ced); } -static inline void gpt_irq_disable(void) +static inline void gpt_irq_disable(struct imx_timer *imxtm) { unsigned int tmp; if (timer_is_v2()) - writel_relaxed(0, timer_base + V2_IR); + writel_relaxed(0, imxtm->base + V2_IR); else { - tmp = readl_relaxed(timer_base + MXC_TCTL); - writel_relaxed(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL); + tmp = readl_relaxed(imxtm->base + MXC_TCTL); + writel_relaxed(tmp & ~MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL); } } -static inline void gpt_irq_enable(void) +static inline void gpt_irq_enable(struct imx_timer *imxtm) { if (timer_is_v2()) - writel_relaxed(1<<0, timer_base + V2_IR); + writel_relaxed(1<<0, imxtm->base + V2_IR); else { - writel_relaxed(readl_relaxed(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, - timer_base + MXC_TCTL); + writel_relaxed(readl_relaxed(imxtm->base + MXC_TCTL) | MX1_2_TCTL_IRQEN, + imxtm->base + MXC_TCTL); } } -static void gpt_irq_acknowledge(void) +static void gpt_irq_acknowledge(struct imx_timer *imxtm) { if (timer_is_v1()) { if (cpu_is_mx1()) - writel_relaxed(0, timer_base + MX1_2_TSTAT); + writel_relaxed(0, imxtm->base + MX1_2_TSTAT); else writel_relaxed(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, - timer_base + MX1_2_TSTAT); + imxtm->base + MX1_2_TSTAT); } else if (timer_is_v2()) - writel_relaxed(V2_TSTAT_OF1, timer_base + V2_TSTAT); + writel_relaxed(V2_TSTAT_OF1, imxtm->base + V2_TSTAT); } static void __iomem *sched_clock_reg; @@ -178,29 +176,31 @@ static int __init mxc_clocksource_init(struct imx_timer *imxtm) /* clock event */ static int mx1_2_set_next_event(unsigned long evt, - struct clock_event_device *unused) + struct clock_event_device *ced) { + struct imx_timer *imxtm = to_imx_timer(ced); unsigned long tcmp; - tcmp = readl_relaxed(timer_base + MX1_2_TCN) + evt; + tcmp = readl_relaxed(imxtm->base + MX1_2_TCN) + evt; - writel_relaxed(tcmp, timer_base + MX1_2_TCMP); + writel_relaxed(tcmp, imxtm->base + MX1_2_TCMP); - return (int)(tcmp - readl_relaxed(timer_base + MX1_2_TCN)) < 0 ? + return (int)(tcmp - readl_relaxed(imxtm->base + MX1_2_TCN)) < 0 ? -ETIME : 0; } static int v2_set_next_event(unsigned long evt, - struct clock_event_device *unused) + struct clock_event_device *ced) { + struct imx_timer *imxtm = to_imx_timer(ced); unsigned long tcmp; - tcmp = readl_relaxed(timer_base + V2_TCN) + evt; + tcmp = readl_relaxed(imxtm->base + V2_TCN) + evt; - writel_relaxed(tcmp, timer_base + V2_TCMP); + writel_relaxed(tcmp, imxtm->base + V2_TCMP); return evt < 0x7fffffff && - (int)(tcmp - readl_relaxed(timer_base + V2_TCN)) < 0 ? + (int)(tcmp - readl_relaxed(imxtm->base + V2_TCN)) < 0 ? -ETIME : 0; } @@ -227,7 +227,7 @@ static void mxc_set_mode(enum clock_event_mode mode, local_irq_save(flags); /* Disable interrupt in GPT module */ - gpt_irq_disable(); + gpt_irq_disable(imxtm); if (mode != imxtm->cem) { u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn); @@ -235,7 +235,7 @@ static void mxc_set_mode(enum clock_event_mode mode, writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp); /* Clear pending interrupt */ - gpt_irq_acknowledge(); + gpt_irq_acknowledge(imxtm); } #ifdef DEBUG @@ -261,7 +261,7 @@ static void mxc_set_mode(enum clock_event_mode mode, * mode switching */ local_irq_save(flags); - gpt_irq_enable(); + gpt_irq_enable(imxtm); local_irq_restore(flags); break; case CLOCK_EVT_MODE_SHUTDOWN: @@ -283,7 +283,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat); - gpt_irq_acknowledge(); + gpt_irq_acknowledge(imxtm); ced->event_handler(ced); @@ -387,9 +387,6 @@ static const struct imx_gpt_data imx6dl_gpt_data = { static void __init _mxc_timer_init(struct imx_timer *imxtm) { - /* Temporary */ - timer_base = imxtm->base; - switch (imxtm->type) { case GPT_TYPE_IMX1: imxtm->gpt = &imx1_gpt_data; From db2ae4b4f6b79bd11d6461d41bd0966b0006f20b Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 22 May 2015 22:42:55 +0800 Subject: [PATCH 40/44] ARM: imx: provide gpt device specific irq functions It splits irq enable/disable/acknowledge operations into device specific functions as the hooks in imx_gpt_data, so that we can save the use of timer_is_xxx() and cpu_is_xxx() checking in these irq functions. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 86 ++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 29 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index c7e2287670cf..131f9b870c04 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -100,6 +100,9 @@ struct imx_gpt_data { int reg_tcn; int reg_tcmp; void (*gpt_setup_tctl)(struct imx_timer *imxtm); + void (*gpt_irq_enable)(struct imx_timer *imxtm); + void (*gpt_irq_disable)(struct imx_timer *imxtm); + void (*gpt_irq_acknowledge)(struct imx_timer *imxtm); int (*set_next_event)(unsigned long evt, struct clock_event_device *ced); }; @@ -109,40 +112,53 @@ static inline struct imx_timer *to_imx_timer(struct clock_event_device *ced) return container_of(ced, struct imx_timer, ced); } -static inline void gpt_irq_disable(struct imx_timer *imxtm) +static void imx1_gpt_irq_disable(struct imx_timer *imxtm) { unsigned int tmp; - if (timer_is_v2()) - writel_relaxed(0, imxtm->base + V2_IR); - else { - tmp = readl_relaxed(imxtm->base + MXC_TCTL); - writel_relaxed(tmp & ~MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL); - } + tmp = readl_relaxed(imxtm->base + MXC_TCTL); + writel_relaxed(tmp & ~MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL); +} +#define imx21_gpt_irq_disable imx1_gpt_irq_disable + +static void imx31_gpt_irq_disable(struct imx_timer *imxtm) +{ + writel_relaxed(0, imxtm->base + V2_IR); +} +#define imx6dl_gpt_irq_disable imx31_gpt_irq_disable + +static void imx1_gpt_irq_enable(struct imx_timer *imxtm) +{ + unsigned int tmp; + + tmp = readl_relaxed(imxtm->base + MXC_TCTL); + writel_relaxed(tmp | MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL); +} +#define imx21_gpt_irq_enable imx1_gpt_irq_enable + +static void imx31_gpt_irq_enable(struct imx_timer *imxtm) +{ + writel_relaxed(1<<0, imxtm->base + V2_IR); +} +#define imx6dl_gpt_irq_enable imx31_gpt_irq_enable + +static void imx1_gpt_irq_acknowledge(struct imx_timer *imxtm) +{ + writel_relaxed(0, imxtm->base + MX1_2_TSTAT); } -static inline void gpt_irq_enable(struct imx_timer *imxtm) +static void imx21_gpt_irq_acknowledge(struct imx_timer *imxtm) { - if (timer_is_v2()) - writel_relaxed(1<<0, imxtm->base + V2_IR); - else { - writel_relaxed(readl_relaxed(imxtm->base + MXC_TCTL) | MX1_2_TCTL_IRQEN, - imxtm->base + MXC_TCTL); - } -} - -static void gpt_irq_acknowledge(struct imx_timer *imxtm) -{ - if (timer_is_v1()) { - if (cpu_is_mx1()) - writel_relaxed(0, imxtm->base + MX1_2_TSTAT); - else - writel_relaxed(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, + writel_relaxed(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, imxtm->base + MX1_2_TSTAT); - } else if (timer_is_v2()) - writel_relaxed(V2_TSTAT_OF1, imxtm->base + V2_TSTAT); } +static void imx31_gpt_irq_acknowledge(struct imx_timer *imxtm) +{ + writel_relaxed(V2_TSTAT_OF1, imxtm->base + V2_TSTAT); +} +#define imx6dl_gpt_irq_acknowledge imx31_gpt_irq_acknowledge + static void __iomem *sched_clock_reg; static u64 notrace mxc_read_sched_clock(void) @@ -227,7 +243,7 @@ static void mxc_set_mode(enum clock_event_mode mode, local_irq_save(flags); /* Disable interrupt in GPT module */ - gpt_irq_disable(imxtm); + imxtm->gpt->gpt_irq_disable(imxtm); if (mode != imxtm->cem) { u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn); @@ -235,7 +251,7 @@ static void mxc_set_mode(enum clock_event_mode mode, writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp); /* Clear pending interrupt */ - gpt_irq_acknowledge(imxtm); + imxtm->gpt->gpt_irq_acknowledge(imxtm); } #ifdef DEBUG @@ -261,7 +277,7 @@ static void mxc_set_mode(enum clock_event_mode mode, * mode switching */ local_irq_save(flags); - gpt_irq_enable(imxtm); + imxtm->gpt->gpt_irq_enable(imxtm); local_irq_restore(flags); break; case CLOCK_EVT_MODE_SHUTDOWN: @@ -283,7 +299,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat); - gpt_irq_acknowledge(imxtm); + imxtm->gpt->gpt_irq_acknowledge(imxtm); ced->event_handler(ced); @@ -357,6 +373,9 @@ static const struct imx_gpt_data imx1_gpt_data = { .reg_tstat = MX1_2_TSTAT, .reg_tcn = MX1_2_TCN, .reg_tcmp = MX1_2_TCMP, + .gpt_irq_enable = imx1_gpt_irq_enable, + .gpt_irq_disable = imx1_gpt_irq_disable, + .gpt_irq_acknowledge = imx1_gpt_irq_acknowledge, .gpt_setup_tctl = imx1_gpt_setup_tctl, .set_next_event = mx1_2_set_next_event, }; @@ -365,6 +384,9 @@ static const struct imx_gpt_data imx21_gpt_data = { .reg_tstat = MX1_2_TSTAT, .reg_tcn = MX1_2_TCN, .reg_tcmp = MX1_2_TCMP, + .gpt_irq_enable = imx21_gpt_irq_enable, + .gpt_irq_disable = imx21_gpt_irq_disable, + .gpt_irq_acknowledge = imx21_gpt_irq_acknowledge, .gpt_setup_tctl = imx21_gpt_setup_tctl, .set_next_event = mx1_2_set_next_event, }; @@ -373,6 +395,9 @@ static const struct imx_gpt_data imx31_gpt_data = { .reg_tstat = V2_TSTAT, .reg_tcn = V2_TCN, .reg_tcmp = V2_TCMP, + .gpt_irq_enable = imx31_gpt_irq_enable, + .gpt_irq_disable = imx31_gpt_irq_disable, + .gpt_irq_acknowledge = imx31_gpt_irq_acknowledge, .gpt_setup_tctl = imx31_gpt_setup_tctl, .set_next_event = v2_set_next_event, }; @@ -381,6 +406,9 @@ static const struct imx_gpt_data imx6dl_gpt_data = { .reg_tstat = V2_TSTAT, .reg_tcn = V2_TCN, .reg_tcmp = V2_TCMP, + .gpt_irq_enable = imx6dl_gpt_irq_enable, + .gpt_irq_disable = imx6dl_gpt_irq_disable, + .gpt_irq_acknowledge = imx6dl_gpt_irq_acknowledge, .gpt_setup_tctl = imx6dl_gpt_setup_tctl, .set_next_event = v2_set_next_event, }; From 2321f246e54abf544d3b9f781ade482b5471d37c Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 15 May 2015 15:27:03 +0800 Subject: [PATCH 41/44] ARM: imx: remove platform headers from timer driver With the cleanup done before, the platform specific headers now can be removed. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 131f9b870c04..b4609283085b 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -36,9 +36,6 @@ #include -#include "common.h" -#include "hardware.h" - /* * There are 4 versions of the timer hardware on Freescale MXC hardware. * - MX1/MXL @@ -80,9 +77,6 @@ #define V2_TIMER_RATE_OSC_DIV8 3000000 -#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) -#define timer_is_v2() (!timer_is_v1()) - struct imx_timer { enum imx_gpt_type type; void __iomem *base; From bea5af41dd9b5f127c730c00610756972a616ed4 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 15 May 2015 15:41:00 +0800 Subject: [PATCH 42/44] ARM: imx: move timer driver into drivers/clocksource After the cleanup on imx timer driver, now it's ready to be moved into drivers/clocksource/. Let's do it. Signed-off-by: Shawn Guo Acked-by: Daniel Lezcano --- arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/Makefile | 2 +- drivers/clocksource/Kconfig | 6 ++++++ drivers/clocksource/Makefile | 1 + .../mach-imx/time.c => drivers/clocksource/timer-imx-gpt.c | 0 5 files changed, 9 insertions(+), 2 deletions(-) rename arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx-gpt.c (100%) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 1d8707885c57..f5813f9f31df 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -2,7 +2,7 @@ menuconfig ARCH_MXC bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 select ARCH_REQUIRE_GPIOLIB select ARM_CPU_SUSPEND if PM - select CLKSRC_MMIO + select CLKSRC_IMX_GPT select GENERIC_IRQ_CHIP select PINCTRL select PM_OPP if PM diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 799e65a530be..f70e18470799 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,4 +1,4 @@ -obj-y := time.o cpu.o system.o irq-common.o +obj-y := cpu.o system.o irq-common.o obj-$(CONFIG_SOC_IMX1) += mm-imx1.o obj-$(CONFIG_SOC_IMX21) += mm-imx21.o diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 51d7865fdddb..618102e5aa2a 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -258,4 +258,10 @@ config CLKSRC_PXA help This enables OST0 support available on PXA and SA-11x0 platforms. + +config CLKSRC_IMX_GPT + bool "Clocksource using i.MX GPT" if COMPILE_TEST + depends on ARM && CLKDEV_LOOKUP + select CLKSRC_MMIO + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 5b85f6adb258..fce332cac646 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -51,4 +51,5 @@ obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o +obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o diff --git a/arch/arm/mach-imx/time.c b/drivers/clocksource/timer-imx-gpt.c similarity index 100% rename from arch/arm/mach-imx/time.c rename to drivers/clocksource/timer-imx-gpt.c From cc013fa8dc302c5835465155da4799a1f0b4b06d Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 29 May 2015 21:02:36 +0800 Subject: [PATCH 43/44] clocksource: timer-imx-gpt: remove include of The include of is not needed at all, and causes build error in some cases. Remove it. Reported-by: Stephen Rothwell Signed-off-by: Shawn Guo Acked-by: Daniel Lezcano --- drivers/clocksource/timer-imx-gpt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c index b4609283085b..879c78423546 100644 --- a/drivers/clocksource/timer-imx-gpt.c +++ b/drivers/clocksource/timer-imx-gpt.c @@ -34,8 +34,6 @@ #include #include -#include - /* * There are 4 versions of the timer hardware on Freescale MXC hardware. * - MX1/MXL From 0be5da9dc249391e3310cc2351e7af5ce211ac49 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 May 2015 11:28:05 +0200 Subject: [PATCH 44/44] ARM: imx: imx7d requires anatop Like i.MX6, the i.MX7 code calls into the anatop driver, which fails if that is disabled: arch/arm/mach-imx/built-in.o: In function `imx7d_init_machine': arch/arm/mach-imx/mach-imx7d.c:24: undefined reference to `imx_anatop_init' arch/arm/mach-imx/built-in.o: In function `imx7d_init_irq': arch/arm/mach-imx/mach-imx7d.c:29: undefined reference to `imx_init_revision_from_anatop' This patch ensures that for an imx7-only build, we still get anatop built-in, matching what we do for imx6. We also need to select HAVE_IMX_MMDC, as that is needed by the anatop code. Signed-off-by: Arnd Bergmann Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index f5813f9f31df..8474c38e9b18 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -586,6 +586,8 @@ config SOC_IMX7D bool "i.MX7 Dual support" select PINCTRL_IMX7D select ARM_GIC + select HAVE_IMX_ANATOP + select HAVE_IMX_MMDC help This enables support for Freescale i.MX7 Dual processor.