]> Git Repo - u-boot.git/blob - arch/arm/cpu/armv7/vf610/generic.c
common: Drop net.h from common header
[u-boot.git] / arch / arm / cpu / armv7 / vf610 / generic.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2013 Freescale Semiconductor, Inc.
4  */
5
6 #include <common.h>
7 #include <clock_legacy.h>
8 #include <cpu_func.h>
9 #include <net.h>
10 #include <asm/cache.h>
11 #include <asm/io.h>
12 #include <asm/arch/imx-regs.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/crm_regs.h>
15 #include <asm/mach-imx/sys_proto.h>
16 #include <env.h>
17 #include <netdev.h>
18 #ifdef CONFIG_FSL_ESDHC_IMX
19 #include <fsl_esdhc_imx.h>
20 #endif
21
22 #ifdef CONFIG_FSL_ESDHC_IMX
23 DECLARE_GLOBAL_DATA_PTR;
24 #endif
25
26 static char soc_type[] = "xx0";
27
28 #ifdef CONFIG_MXC_OCOTP
29 void enable_ocotp_clk(unsigned char enable)
30 {
31         struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
32         u32 reg;
33
34         reg = readl(&ccm->ccgr6);
35         if (enable)
36                 reg |= CCM_CCGR6_OCOTP_CTRL_MASK;
37         else
38                 reg &= ~CCM_CCGR6_OCOTP_CTRL_MASK;
39         writel(reg, &ccm->ccgr6);
40 }
41 #endif
42
43 static u32 get_mcu_main_clk(void)
44 {
45         struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
46         u32 ccm_ccsr, ccm_cacrr, armclk_div;
47         u32 sysclk_sel, pll_pfd_sel = 0;
48         u32 freq = 0;
49
50         ccm_ccsr = readl(&ccm->ccsr);
51         sysclk_sel = ccm_ccsr & CCM_CCSR_SYS_CLK_SEL_MASK;
52         sysclk_sel >>= CCM_CCSR_SYS_CLK_SEL_OFFSET;
53
54         ccm_cacrr = readl(&ccm->cacrr);
55         armclk_div = ccm_cacrr & CCM_CACRR_ARM_CLK_DIV_MASK;
56         armclk_div >>= CCM_CACRR_ARM_CLK_DIV_OFFSET;
57         armclk_div += 1;
58
59         switch (sysclk_sel) {
60         case 0:
61                 freq = FASE_CLK_FREQ;
62                 break;
63         case 1:
64                 freq = SLOW_CLK_FREQ;
65                 break;
66         case 2:
67                 pll_pfd_sel = ccm_ccsr & CCM_CCSR_PLL2_PFD_CLK_SEL_MASK;
68                 pll_pfd_sel >>= CCM_CCSR_PLL2_PFD_CLK_SEL_OFFSET;
69                 if (pll_pfd_sel == 0)
70                         freq = PLL2_MAIN_FREQ;
71                 else if (pll_pfd_sel == 1)
72                         freq = PLL2_PFD1_FREQ;
73                 else if (pll_pfd_sel == 2)
74                         freq = PLL2_PFD2_FREQ;
75                 else if (pll_pfd_sel == 3)
76                         freq = PLL2_PFD3_FREQ;
77                 else if (pll_pfd_sel == 4)
78                         freq = PLL2_PFD4_FREQ;
79                 break;
80         case 3:
81                 freq = PLL2_MAIN_FREQ;
82                 break;
83         case 4:
84                 pll_pfd_sel = ccm_ccsr & CCM_CCSR_PLL1_PFD_CLK_SEL_MASK;
85                 pll_pfd_sel >>= CCM_CCSR_PLL1_PFD_CLK_SEL_OFFSET;
86                 if (pll_pfd_sel == 0)
87                         freq = PLL1_MAIN_FREQ;
88                 else if (pll_pfd_sel == 1)
89                         freq = PLL1_PFD1_FREQ;
90                 else if (pll_pfd_sel == 2)
91                         freq = PLL1_PFD2_FREQ;
92                 else if (pll_pfd_sel == 3)
93                         freq = PLL1_PFD3_FREQ;
94                 else if (pll_pfd_sel == 4)
95                         freq = PLL1_PFD4_FREQ;
96                 break;
97         case 5:
98                 freq = PLL3_MAIN_FREQ;
99                 break;
100         default:
101                 printf("unsupported system clock select\n");
102         }
103
104         return freq / armclk_div;
105 }
106
107 static u32 get_bus_clk(void)
108 {
109         struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
110         u32 ccm_cacrr, busclk_div;
111
112         ccm_cacrr = readl(&ccm->cacrr);
113
114         busclk_div = ccm_cacrr & CCM_CACRR_BUS_CLK_DIV_MASK;
115         busclk_div >>= CCM_CACRR_BUS_CLK_DIV_OFFSET;
116         busclk_div += 1;
117
118         return get_mcu_main_clk() / busclk_div;
119 }
120
121 static u32 get_ipg_clk(void)
122 {
123         struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
124         u32 ccm_cacrr, ipgclk_div;
125
126         ccm_cacrr = readl(&ccm->cacrr);
127
128         ipgclk_div = ccm_cacrr & CCM_CACRR_IPG_CLK_DIV_MASK;
129         ipgclk_div >>= CCM_CACRR_IPG_CLK_DIV_OFFSET;
130         ipgclk_div += 1;
131
132         return get_bus_clk() / ipgclk_div;
133 }
134
135 static u32 get_uart_clk(void)
136 {
137         return get_ipg_clk();
138 }
139
140 static u32 get_sdhc_clk(void)
141 {
142         struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
143         u32 ccm_cscmr1, ccm_cscdr2, sdhc_clk_sel, sdhc_clk_div;
144         u32 freq = 0;
145
146         ccm_cscmr1 = readl(&ccm->cscmr1);
147         sdhc_clk_sel = ccm_cscmr1 & CCM_CSCMR1_ESDHC1_CLK_SEL_MASK;
148         sdhc_clk_sel >>= CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET;
149
150         ccm_cscdr2 = readl(&ccm->cscdr2);
151         sdhc_clk_div = ccm_cscdr2 & CCM_CSCDR2_ESDHC1_CLK_DIV_MASK;
152         sdhc_clk_div >>= CCM_CSCDR2_ESDHC1_CLK_DIV_OFFSET;
153         sdhc_clk_div += 1;
154
155         switch (sdhc_clk_sel) {
156         case 0:
157                 freq = PLL3_MAIN_FREQ;
158                 break;
159         case 1:
160                 freq = PLL3_PFD3_FREQ;
161                 break;
162         case 2:
163                 freq = PLL1_PFD3_FREQ;
164                 break;
165         case 3:
166                 freq = get_bus_clk();
167                 break;
168         }
169
170         return freq / sdhc_clk_div;
171 }
172
173 u32 get_fec_clk(void)
174 {
175         struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
176         u32 ccm_cscmr2, rmii_clk_sel;
177         u32 freq = 0;
178
179         ccm_cscmr2 = readl(&ccm->cscmr2);
180         rmii_clk_sel = ccm_cscmr2 & CCM_CSCMR2_RMII_CLK_SEL_MASK;
181         rmii_clk_sel >>= CCM_CSCMR2_RMII_CLK_SEL_OFFSET;
182
183         switch (rmii_clk_sel) {
184         case 0:
185                 freq = ENET_EXTERNAL_CLK;
186                 break;
187         case 1:
188                 freq = AUDIO_EXTERNAL_CLK;
189                 break;
190         case 2:
191                 freq = PLL5_MAIN_FREQ;
192                 break;
193         case 3:
194                 freq = PLL5_MAIN_FREQ / 2;
195                 break;
196         }
197
198         return freq;
199 }
200
201 static u32 get_i2c_clk(void)
202 {
203         return get_ipg_clk();
204 }
205
206 static u32 get_dspi_clk(void)
207 {
208         return get_ipg_clk();
209 }
210
211 u32 get_lpuart_clk(void)
212 {
213         return get_uart_clk();
214 }
215
216 unsigned int mxc_get_clock(enum mxc_clock clk)
217 {
218         switch (clk) {
219         case MXC_ARM_CLK:
220                 return get_mcu_main_clk();
221         case MXC_BUS_CLK:
222                 return get_bus_clk();
223         case MXC_IPG_CLK:
224                 return get_ipg_clk();
225         case MXC_UART_CLK:
226                 return get_uart_clk();
227         case MXC_ESDHC_CLK:
228                 return get_sdhc_clk();
229         case MXC_FEC_CLK:
230                 return get_fec_clk();
231         case MXC_I2C_CLK:
232                 return get_i2c_clk();
233         case MXC_DSPI_CLK:
234                 return get_dspi_clk();
235         default:
236                 break;
237         }
238         return -1;
239 }
240
241 /* Dump some core clocks */
242 int do_vf610_showclocks(cmd_tbl_t *cmdtp, int flag, int argc,
243                          char * const argv[])
244 {
245         printf("\n");
246         printf("cpu clock : %8d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
247         printf("bus clock : %8d MHz\n", mxc_get_clock(MXC_BUS_CLK) / 1000000);
248         printf("ipg clock : %8d MHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000000);
249
250         return 0;
251 }
252
253 U_BOOT_CMD(
254         clocks, CONFIG_SYS_MAXARGS, 1, do_vf610_showclocks,
255         "display clocks",
256         ""
257 );
258
259 #ifdef CONFIG_FEC_MXC
260 __weak void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
261 {
262         struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
263         struct fuse_bank *bank = &ocotp->bank[4];
264         struct fuse_bank4_regs *fuse =
265                 (struct fuse_bank4_regs *)bank->fuse_regs;
266
267         u32 value = readl(&fuse->mac_addr0);
268         mac[0] = (value >> 8);
269         mac[1] = value;
270
271         value = readl(&fuse->mac_addr1);
272         mac[2] = value >> 24;
273         mac[3] = value >> 16;
274         mac[4] = value >> 8;
275         mac[5] = value;
276 }
277 #endif
278
279 u32 get_cpu_rev(void)
280 {
281         return MXC_CPU_VF610 << 12;
282 }
283
284 #if defined(CONFIG_DISPLAY_CPUINFO)
285 static char *get_reset_cause(void)
286 {
287         u32 cause;
288         struct src *src_regs = (struct src *)SRC_BASE_ADDR;
289
290         cause = readl(&src_regs->srsr);
291         writel(cause, &src_regs->srsr);
292
293         if (cause & SRC_SRSR_POR_RST)
294                 return "POWER ON RESET";
295         else if (cause & SRC_SRSR_WDOG_A5)
296                 return "WDOG A5";
297         else if (cause & SRC_SRSR_WDOG_M4)
298                 return "WDOG M4";
299         else if (cause & SRC_SRSR_JTAG_RST)
300                 return "JTAG HIGH-Z";
301         else if (cause & SRC_SRSR_SW_RST)
302                 return "SW RESET";
303         else if (cause & SRC_SRSR_RESETB)
304                 return "EXTERNAL RESET";
305         else
306                 return "unknown reset";
307 }
308
309 int print_cpuinfo(void)
310 {
311         printf("CPU: Freescale Vybrid VF%s at %d MHz\n",
312                soc_type, mxc_get_clock(MXC_ARM_CLK) / 1000000);
313         printf("Reset cause: %s\n", get_reset_cause());
314
315         return 0;
316 }
317 #endif
318
319 int arch_cpu_init(void)
320 {
321         struct mscm *mscm = (struct mscm *)MSCM_BASE_ADDR;
322
323         soc_type[0] = mscm->cpxcount ? '6' : '5'; /*Dual Core => VF6x0 */
324         soc_type[1] = mscm->cpxcfg1 ? '1' : '0'; /* L2 Cache => VFx10 */
325
326         return 0;
327 }
328
329 #ifdef CONFIG_ARCH_MISC_INIT
330 int arch_misc_init(void)
331 {
332         char soc[6];
333
334         strcpy(soc, "vf");
335         strcat(soc, soc_type);
336         env_set("soc", soc);
337
338         return 0;
339 }
340 #endif
341
342 int cpu_eth_init(bd_t *bis)
343 {
344         int rc = -ENODEV;
345
346 #if defined(CONFIG_FEC_MXC)
347         rc = fecmxc_initialize(bis);
348 #endif
349
350         return rc;
351 }
352
353 #ifdef CONFIG_FSL_ESDHC_IMX
354 int cpu_mmc_init(bd_t *bis)
355 {
356         return fsl_esdhc_mmc_init(bis);
357 }
358 #endif
359
360 int get_clocks(void)
361 {
362 #ifdef CONFIG_FSL_ESDHC_IMX
363         gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
364 #endif
365         return 0;
366 }
367
368 #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
369 void enable_caches(void)
370 {
371 #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
372         enum dcache_option option = DCACHE_WRITETHROUGH;
373 #else
374         enum dcache_option option = DCACHE_WRITEBACK;
375 #endif
376         dcache_enable();
377         icache_enable();
378
379     /* Enable caching on OCRAM */
380         mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, IRAM_SIZE, option);
381 }
382 #endif
383
384 #ifdef CONFIG_SYS_I2C_MXC
385 /* i2c_num can be from 0 - 3 */
386 int enable_i2c_clk(unsigned char enable, unsigned int i2c_num)
387 {
388         struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
389
390         switch (i2c_num) {
391         case 0:
392                 clrsetbits_le32(&ccm->ccgr4, CCM_CCGR4_I2C0_CTRL_MASK,
393                                 CCM_CCGR4_I2C0_CTRL_MASK);
394         case 2:
395                 clrsetbits_le32(&ccm->ccgr10, CCM_CCGR10_I2C2_CTRL_MASK,
396                                 CCM_CCGR10_I2C2_CTRL_MASK);
397                 break;
398         default:
399                 return -EINVAL;
400         }
401
402         return 0;
403 }
404 #endif
This page took 0.050272 seconds and 4 git commands to generate.