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