uboot/arch/arm/mach-imx/mx7/clock_slice.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2015 Freescale Semiconductor, Inc.
   4 *
   5 * Author:
   6 *      Peng Fan <Peng.Fan@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
  18struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  19
  20static 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 */
 375static 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
 390static 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. */
 409int 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. */
 434int 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
 457int 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
 489int 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
 520int 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
 548int 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
 572int 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
 610int 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
 650int 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
 660int 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. */
 671int 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
 724int 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 */
 743int 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