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