odroid: remove CONFIG_DM_I2C_COMPAT config
[platform/kernel/u-boot.git] / board / freescale / s32v234evb / clock.c
1 /*
2  * (C) Copyright 2015, Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <asm/io.h>
8 #include <asm/arch/imx-regs.h>
9 #include <asm/arch/mc_cgm_regs.h>
10 #include <asm/arch/mc_me_regs.h>
11 #include <asm/arch/clock.h>
12
13 /*
14  * Select the clock reference for required pll.
15  * pll - ARM_PLL, PERIPH_PLL, ENET_PLL, DDR_PLL, VIDEO_PLL.
16  * refclk_freq - input referece clock frequency (FXOSC - 40 MHZ, FIRC - 48 MHZ)
17  */
18 static int select_pll_source_clk(enum pll_type pll, u32 refclk_freq)
19 {
20         u32 clk_src;
21         u32 pll_idx;
22         volatile struct src *src = (struct src *)SRC_SOC_BASE_ADDR;
23
24         /* select the pll clock source */
25         switch (refclk_freq) {
26         case FIRC_CLK_FREQ:
27                 clk_src = SRC_GPR1_FIRC_CLK_SOURCE;
28                 break;
29         case XOSC_CLK_FREQ:
30                 clk_src = SRC_GPR1_XOSC_CLK_SOURCE;
31                 break;
32         default:
33                 /* The clock frequency for the source clock is unknown */
34                 return -1;
35         }
36         /*
37          * The hardware definition is not uniform, it has to calculate again
38          * the recurrence formula.
39          */
40         switch (pll) {
41         case PERIPH_PLL:
42                 pll_idx = 3;
43                 break;
44         case ENET_PLL:
45                 pll_idx = 1;
46                 break;
47         case DDR_PLL:
48                 pll_idx = 2;;
49                 break;
50         default:
51                 pll_idx = pll;
52         }
53
54         writel(readl(&src->gpr1) | SRC_GPR1_PLL_SOURCE(pll_idx, clk_src),
55                &src->gpr1);
56
57         return 0;
58 }
59
60 static void entry_to_target_mode(u32 mode)
61 {
62         writel(mode | MC_ME_MCTL_KEY, MC_ME_MCTL);
63         writel(mode | MC_ME_MCTL_INVERTEDKEY, MC_ME_MCTL);
64         while ((readl(MC_ME_GS) & MC_ME_GS_S_MTRANS) != 0x00000000) ;
65 }
66
67 /*
68  * Program the pll according to the input parameters.
69  * pll - ARM_PLL, PERIPH_PLL, ENET_PLL, DDR_PLL, VIDEO_PLL.
70  * refclk_freq - input reference clock frequency (FXOSC - 40 MHZ, FIRC - 48 MHZ)
71  * freq - expected output frequency for PHY0
72  * freq1 - expected output frequency for PHY1
73  * dfs_nr - number of DFS modules for current PLL
74  * dfs - array with the activation dfs field, mfn and mfi
75  * plldv_prediv - divider of clkfreq_ref
76  * plldv_mfd - loop multiplication factor divider
77  * pllfd_mfn - numerator loop multiplication factor divider
78  * Please consult the PLLDIG chapter of platform manual
79  * before to use this function.
80  *)
81  */
82 static int program_pll(enum pll_type pll, u32 refclk_freq, u32 freq0, u32 freq1,
83                        u32 dfs_nr, u32 dfs[][DFS_PARAMS_Nr], u32 plldv_prediv,
84                        u32 plldv_mfd, u32 pllfd_mfn)
85 {
86         u32 i, rfdphi1, rfdphi, dfs_on = 0, fvco;
87
88         /*
89          * This formula is from platform reference manual (Rev. 1, 6/2015), PLLDIG chapter.
90          */
91         fvco =
92             (refclk_freq / plldv_prediv) * (plldv_mfd +
93                                             pllfd_mfn / (float)20480);
94
95         /*
96          * VCO should have value in [ PLL_MIN_FREQ, PLL_MAX_FREQ ]. Please consult
97          * the platform DataSheet in order to determine the allowed values.
98          */
99
100         if (fvco < PLL_MIN_FREQ || fvco > PLL_MAX_FREQ) {
101                 return -1;
102         }
103
104         if (select_pll_source_clk(pll, refclk_freq) < 0) {
105                 return -1;
106         }
107
108         rfdphi = fvco / freq0;
109
110         rfdphi1 = (freq1 == 0) ? 0 : fvco / freq1;
111
112         writel(PLLDIG_PLLDV_RFDPHI1_SET(rfdphi1) |
113                PLLDIG_PLLDV_RFDPHI_SET(rfdphi) |
114                PLLDIG_PLLDV_PREDIV_SET(plldv_prediv) |
115                PLLDIG_PLLDV_MFD(plldv_mfd), PLLDIG_PLLDV(pll));
116
117         writel(readl(PLLDIG_PLLFD(pll)) | PLLDIG_PLLFD_MFN_SET(pllfd_mfn) |
118                PLLDIG_PLLFD_SMDEN, PLLDIG_PLLFD(pll));
119
120         /* switch on the pll in current mode */
121         writel(readl(MC_ME_RUNn_MC(0)) | MC_ME_RUNMODE_MC_PLL(pll),
122                MC_ME_RUNn_MC(0));
123
124         entry_to_target_mode(MC_ME_MCTL_RUN0);
125
126         /* Only ARM_PLL, ENET_PLL and DDR_PLL */
127         if ((pll == ARM_PLL) || (pll == ENET_PLL) || (pll == DDR_PLL)) {
128                 /* DFS clk enable programming */
129                 writel(DFS_CTRL_DLL_RESET, DFS_CTRL(pll));
130
131                 writel(DFS_DLLPRG1_CPICTRL_SET(0x5) |
132                        DFS_DLLPRG1_VSETTLCTRL_SET(0x1) |
133                        DFS_DLLPRG1_CALBYPEN_SET(0x0) |
134                        DFS_DLLPRG1_DACIN_SET(0x1) | DFS_DLLPRG1_LCKWT_SET(0x0) |
135                        DFS_DLLPRG1_V2IGC_SET(0x5), DFS_DLLPRG1(pll));
136
137                 for (i = 0; i < dfs_nr; i++) {
138                         if (dfs[i][0]) {
139                                 writel(DFS_DVPORTn_MFI_SET(dfs[i][2]) |
140                                        DFS_DVPORTn_MFN_SET(dfs[i][1]),
141                                        DFS_DVPORTn(pll, i));
142                                 dfs_on |= (dfs[i][0] << i);
143                         }
144                 }
145
146                 writel(readl(DFS_CTRL(pll)) & ~DFS_CTRL_DLL_RESET,
147                        DFS_CTRL(pll));
148                 writel(readl(DFS_PORTRESET(pll)) &
149                        ~DFS_PORTRESET_PORTRESET_SET(dfs_on),
150                        DFS_PORTRESET(pll));
151                 while ((readl(DFS_PORTSR(pll)) & dfs_on) != dfs_on) ;
152         }
153
154         entry_to_target_mode(MC_ME_MCTL_RUN0);
155
156         return 0;
157
158 }
159
160 static void aux_source_clk_config(uintptr_t cgm_addr, u8 ac, u32 source)
161 {
162         /* select the clock source */
163         writel(MC_CGM_ACn_SEL_SET(source), CGM_ACn_SC(cgm_addr, ac));
164 }
165
166 static void aux_div_clk_config(uintptr_t cgm_addr, u8 ac, u8 dc, u32 divider)
167 {
168         /* set the divider */
169         writel(MC_CGM_ACn_DCm_DE | MC_CGM_ACn_DCm_PREDIV(divider),
170                CGM_ACn_DCm(cgm_addr, ac, dc));
171 }
172
173 static void setup_sys_clocks(void)
174 {
175
176         /* set ARM PLL DFS 1 as SYSCLK */
177         writel((readl(MC_ME_RUNn_MC(0)) & ~MC_ME_RUNMODE_MC_SYSCLK_MASK) |
178                MC_ME_RUNMODE_MC_SYSCLK(0x2), MC_ME_RUNn_MC(0));
179
180         entry_to_target_mode(MC_ME_MCTL_RUN0);
181
182         /* select sysclks  ARMPLL, ARMPLLDFS2, ARMPLLDFS3 */
183         writel(MC_ME_RUNMODE_SEC_CC_I_SYSCLK
184                (0x2,
185                 MC_ME_RUNMODE_SEC_CC_I_SYSCLK1_OFFSET) |
186                MC_ME_RUNMODE_SEC_CC_I_SYSCLK(0x2,
187                                              MC_ME_RUNMODE_SEC_CC_I_SYSCLK2_OFFSET)
188                | MC_ME_RUNMODE_SEC_CC_I_SYSCLK(0x2,
189                                                MC_ME_RUNMODE_SEC_CC_I_SYSCLK3_OFFSET),
190                MC_ME_RUNn_SEC_CC_I(0));
191
192         /* setup the sys clock divider for CORE_CLK (1000MHz) */
193         writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x0),
194                CGM_SC_DCn(MC_CGM1_BASE_ADDR, 0));
195
196         /* setup the sys clock divider for CORE2_CLK (500MHz) */
197         writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x1),
198                CGM_SC_DCn(MC_CGM1_BASE_ADDR, 1));
199         /* setup the sys clock divider for SYS3_CLK (266 MHz) */
200         writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x0),
201                CGM_SC_DCn(MC_CGM0_BASE_ADDR, 0));
202
203         /* setup the sys clock divider for SYS6_CLK (133 Mhz) */
204         writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x1),
205                CGM_SC_DCn(MC_CGM0_BASE_ADDR, 1));
206
207         entry_to_target_mode(MC_ME_MCTL_RUN0);
208
209 }
210
211 static void setup_aux_clocks(void)
212 {
213         /*
214          * setup the aux clock divider for PERI_CLK
215          * (source: PERIPH_PLL_PHI_0/5, PERI_CLK - 80 MHz)
216          */
217         aux_source_clk_config(MC_CGM0_BASE_ADDR, 5, MC_CGM_ACn_SEL_PERPLLDIVX);
218         aux_div_clk_config(MC_CGM0_BASE_ADDR, 5, 0, 4);
219
220         /* setup the aux clock divider for LIN_CLK (40MHz) */
221         aux_source_clk_config(MC_CGM0_BASE_ADDR, 3, MC_CGM_ACn_SEL_PERPLLDIVX);
222         aux_div_clk_config(MC_CGM0_BASE_ADDR, 3, 0, 1);
223
224         /* setup the aux clock divider for ENET_TIME_CLK (50MHz) */
225         aux_source_clk_config(MC_CGM0_BASE_ADDR, 7, MC_CGM_ACn_SEL_ENETPLL);
226         aux_div_clk_config(MC_CGM0_BASE_ADDR, 7, 1, 9);
227
228         /* setup the aux clock divider for ENET_CLK (50MHz) */
229         aux_source_clk_config(MC_CGM2_BASE_ADDR, 2, MC_CGM_ACn_SEL_ENETPLL);
230         aux_div_clk_config(MC_CGM2_BASE_ADDR, 2, 0, 9);
231
232         /* setup the aux clock divider for SDHC_CLK (50 MHz). */
233         aux_source_clk_config(MC_CGM0_BASE_ADDR, 15, MC_CGM_ACn_SEL_ENETPLL);
234         aux_div_clk_config(MC_CGM0_BASE_ADDR, 15, 0, 9);
235
236         /* setup the aux clock divider for DDR_CLK (533MHz) and APEX_SYS_CLK (266MHz) */
237         aux_source_clk_config(MC_CGM0_BASE_ADDR, 8, MC_CGM_ACn_SEL_DDRPLL);
238         aux_div_clk_config(MC_CGM0_BASE_ADDR, 8, 0, 0);
239         /* setup the aux clock divider for DDR4_CLK (133,25MHz) */
240         aux_div_clk_config(MC_CGM0_BASE_ADDR, 8, 1, 3);
241
242         entry_to_target_mode(MC_ME_MCTL_RUN0);
243
244 }
245
246 static void enable_modules_clock(void)
247 {
248         /* PIT0 */
249         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL58);
250         /* PIT1 */
251         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL170);
252         /* LINFLEX0 */
253         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL83);
254         /* LINFLEX1 */
255         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL188);
256         /* ENET */
257         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL50);
258         /* SDHC */
259         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL93);
260         /* IIC0 */
261         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL81);
262         /* IIC1 */
263         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL184);
264         /* IIC2 */
265         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL186);
266         /* MMDC0 */
267         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL54);
268         /* MMDC1 */
269         writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL162);
270
271         entry_to_target_mode(MC_ME_MCTL_RUN0);
272 }
273
274 void clock_init(void)
275 {
276         unsigned int arm_dfs[ARM_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
277                 {ARM_PLL_PHI1_DFS1_EN, ARM_PLL_PHI1_DFS1_MFN,
278                  ARM_PLL_PHI1_DFS1_MFI},
279                 {ARM_PLL_PHI1_DFS2_EN, ARM_PLL_PHI1_DFS2_MFN,
280                  ARM_PLL_PHI1_DFS2_MFI},
281                 {ARM_PLL_PHI1_DFS3_EN, ARM_PLL_PHI1_DFS3_MFN,
282                  ARM_PLL_PHI1_DFS3_MFI}
283         };
284
285         unsigned int enet_dfs[ENET_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
286                 {ENET_PLL_PHI1_DFS1_EN, ENET_PLL_PHI1_DFS1_MFN,
287                  ENET_PLL_PHI1_DFS1_MFI},
288                 {ENET_PLL_PHI1_DFS2_EN, ENET_PLL_PHI1_DFS2_MFN,
289                  ENET_PLL_PHI1_DFS2_MFI},
290                 {ENET_PLL_PHI1_DFS3_EN, ENET_PLL_PHI1_DFS3_MFN,
291                  ENET_PLL_PHI1_DFS3_MFI},
292                 {ENET_PLL_PHI1_DFS4_EN, ENET_PLL_PHI1_DFS4_MFN,
293                  ENET_PLL_PHI1_DFS4_MFI}
294         };
295
296         unsigned int ddr_dfs[DDR_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
297                 {DDR_PLL_PHI1_DFS1_EN, DDR_PLL_PHI1_DFS1_MFN,
298                  DDR_PLL_PHI1_DFS1_MFI},
299                 {DDR_PLL_PHI1_DFS2_EN, DDR_PLL_PHI1_DFS2_MFN,
300                  DDR_PLL_PHI1_DFS2_MFI},
301                 {DDR_PLL_PHI1_DFS3_EN, DDR_PLL_PHI1_DFS3_MFN,
302                  DDR_PLL_PHI1_DFS3_MFI}
303         };
304
305         writel(MC_ME_RUN_PCn_DRUN | MC_ME_RUN_PCn_RUN0 | MC_ME_RUN_PCn_RUN1 |
306                MC_ME_RUN_PCn_RUN2 | MC_ME_RUN_PCn_RUN3, MC_ME_RUN_PCn(0));
307
308         /* turn on FXOSC */
309         writel(MC_ME_RUNMODE_MC_MVRON | MC_ME_RUNMODE_MC_XOSCON |
310                MC_ME_RUNMODE_MC_FIRCON | MC_ME_RUNMODE_MC_SYSCLK(0x1),
311                MC_ME_RUNn_MC(0));
312
313         entry_to_target_mode(MC_ME_MCTL_RUN0);
314
315         program_pll(ARM_PLL, XOSC_CLK_FREQ, ARM_PLL_PHI0_FREQ,
316                     ARM_PLL_PHI1_FREQ, ARM_PLL_PHI1_DFS_Nr, arm_dfs,
317                     ARM_PLL_PLLDV_PREDIV, ARM_PLL_PLLDV_MFD, ARM_PLL_PLLDV_MFN);
318
319         setup_sys_clocks();
320
321         program_pll(PERIPH_PLL, XOSC_CLK_FREQ, PERIPH_PLL_PHI0_FREQ,
322                     PERIPH_PLL_PHI1_FREQ, PERIPH_PLL_PHI1_DFS_Nr, NULL,
323                     PERIPH_PLL_PLLDV_PREDIV, PERIPH_PLL_PLLDV_MFD,
324                     PERIPH_PLL_PLLDV_MFN);
325
326         program_pll(ENET_PLL, XOSC_CLK_FREQ, ENET_PLL_PHI0_FREQ,
327                     ENET_PLL_PHI1_FREQ, ENET_PLL_PHI1_DFS_Nr, enet_dfs,
328                     ENET_PLL_PLLDV_PREDIV, ENET_PLL_PLLDV_MFD,
329                     ENET_PLL_PLLDV_MFN);
330
331         program_pll(DDR_PLL, XOSC_CLK_FREQ, DDR_PLL_PHI0_FREQ,
332                     DDR_PLL_PHI1_FREQ, DDR_PLL_PHI1_DFS_Nr, ddr_dfs,
333                     DDR_PLL_PLLDV_PREDIV, DDR_PLL_PLLDV_MFD, DDR_PLL_PLLDV_MFN);
334
335         program_pll(VIDEO_PLL, XOSC_CLK_FREQ, VIDEO_PLL_PHI0_FREQ,
336                     VIDEO_PLL_PHI1_FREQ, VIDEO_PLL_PHI1_DFS_Nr, NULL,
337                     VIDEO_PLL_PLLDV_PREDIV, VIDEO_PLL_PLLDV_MFD,
338                     VIDEO_PLL_PLLDV_MFN);
339
340         setup_aux_clocks();
341
342         enable_modules_clock();
343
344 }