]>
Commit | Line | Data |
---|---|---|
18936ee2 JL |
1 | /* |
2 | * (C) Copyright 2007 | |
3 | * Sascha Hauer, Pengutronix | |
4 | * | |
5 | * (C) Copyright 2009 Freescale Semiconductor, Inc. | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
18936ee2 JL |
8 | */ |
9 | ||
5624c6bd | 10 | #include <bootm.h> |
18936ee2 | 11 | #include <common.h> |
5624c6bd | 12 | #include <netdev.h> |
18936ee2 JL |
13 | #include <asm/errno.h> |
14 | #include <asm/io.h> | |
15 | #include <asm/arch/imx-regs.h> | |
16 | #include <asm/arch/clock.h> | |
17 | #include <asm/arch/sys_proto.h> | |
6a376046 | 18 | #include <asm/arch/crm_regs.h> |
e1eb75b5 | 19 | #include <ipu_pixfmt.h> |
18936ee2 JL |
20 | |
21 | #ifdef CONFIG_FSL_ESDHC | |
22 | #include <fsl_esdhc.h> | |
23 | #endif | |
24 | ||
1fc56f1c | 25 | char *get_reset_cause(void) |
18936ee2 JL |
26 | { |
27 | u32 cause; | |
28 | struct src *src_regs = (struct src *)SRC_BASE_ADDR; | |
29 | ||
30 | cause = readl(&src_regs->srsr); | |
31 | writel(cause, &src_regs->srsr); | |
32 | ||
33 | switch (cause) { | |
34 | case 0x00001: | |
cece2622 | 35 | case 0x00011: |
18936ee2 JL |
36 | return "POR"; |
37 | case 0x00004: | |
38 | return "CSU"; | |
39 | case 0x00008: | |
40 | return "IPP USER"; | |
41 | case 0x00010: | |
42 | return "WDOG"; | |
43 | case 0x00020: | |
44 | return "JTAG HIGH-Z"; | |
45 | case 0x00040: | |
46 | return "JTAG SW"; | |
47 | case 0x10000: | |
48 | return "WARM BOOT"; | |
49 | default: | |
50 | return "unknown reset"; | |
51 | } | |
52 | } | |
53 | ||
eb0344d9 TK |
54 | #if defined(CONFIG_MX53) || defined(CONFIG_MX6) |
55 | #if defined(CONFIG_MX53) | |
3e9cbbbb | 56 | #define MEMCTL_BASE ESDCTL_BASE_ADDR |
eb0344d9 | 57 | #else |
3e9cbbbb | 58 | #define MEMCTL_BASE MMDC_P0_BASE_ADDR |
eb0344d9 TK |
59 | #endif |
60 | static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9}; | |
61 | static const unsigned char bank_lookup[] = {3, 2}; | |
62 | ||
b07161c3 | 63 | /* these MMDC registers are common to the IMX53 and IMX6 */ |
eb0344d9 TK |
64 | struct esd_mmdc_regs { |
65 | uint32_t ctl; | |
66 | uint32_t pdc; | |
67 | uint32_t otc; | |
68 | uint32_t cfg0; | |
69 | uint32_t cfg1; | |
70 | uint32_t cfg2; | |
71 | uint32_t misc; | |
eb0344d9 TK |
72 | }; |
73 | ||
74 | #define ESD_MMDC_CTL_GET_ROW(mdctl) ((ctl >> 24) & 7) | |
75 | #define ESD_MMDC_CTL_GET_COLUMN(mdctl) ((ctl >> 20) & 7) | |
76 | #define ESD_MMDC_CTL_GET_WIDTH(mdctl) ((ctl >> 16) & 3) | |
77 | #define ESD_MMDC_CTL_GET_CS1(mdctl) ((ctl >> 30) & 1) | |
78 | #define ESD_MMDC_MISC_GET_BANK(mdmisc) ((misc >> 5) & 1) | |
79 | ||
b07161c3 TH |
80 | /* |
81 | * imx_ddr_size - return size in bytes of DRAM according MMDC config | |
82 | * The MMDC MDCTL register holds the number of bits for row, col, and data | |
83 | * width and the MMDC MDMISC register holds the number of banks. Combine | |
84 | * all these bits to determine the meme size the MMDC has been configured for | |
85 | */ | |
eb0344d9 TK |
86 | unsigned imx_ddr_size(void) |
87 | { | |
88 | struct esd_mmdc_regs *mem = (struct esd_mmdc_regs *)MEMCTL_BASE; | |
89 | unsigned ctl = readl(&mem->ctl); | |
90 | unsigned misc = readl(&mem->misc); | |
91 | int bits = 11 + 0 + 0 + 1; /* row + col + bank + width */ | |
92 | ||
93 | bits += ESD_MMDC_CTL_GET_ROW(ctl); | |
94 | bits += col_lookup[ESD_MMDC_CTL_GET_COLUMN(ctl)]; | |
95 | bits += bank_lookup[ESD_MMDC_MISC_GET_BANK(misc)]; | |
96 | bits += ESD_MMDC_CTL_GET_WIDTH(ctl); | |
97 | bits += ESD_MMDC_CTL_GET_CS1(ctl); | |
fcfdfdd5 MV |
98 | |
99 | /* The MX6 can do only 3840 MiB of DRAM */ | |
100 | if (bits == 32) | |
101 | return 0xf0000000; | |
102 | ||
eb0344d9 TK |
103 | return 1 << bits; |
104 | } | |
105 | #endif | |
106 | ||
18936ee2 | 107 | #if defined(CONFIG_DISPLAY_CPUINFO) |
a7683867 | 108 | |
20332a06 | 109 | const char *get_imx_type(u32 imxtype) |
a7683867 FE |
110 | { |
111 | switch (imxtype) { | |
20332a06 | 112 | case MXC_CPU_MX6Q: |
a7683867 | 113 | return "6Q"; /* Quad-core version of the mx6 */ |
94db6655 FE |
114 | case MXC_CPU_MX6D: |
115 | return "6D"; /* Dual-core version of the mx6 */ | |
20332a06 TK |
116 | case MXC_CPU_MX6DL: |
117 | return "6DL"; /* Dual Lite version of the mx6 */ | |
118 | case MXC_CPU_MX6SOLO: | |
119 | return "6SOLO"; /* Solo version of the mx6 */ | |
120 | case MXC_CPU_MX6SL: | |
a7683867 | 121 | return "6SL"; /* Solo-Lite version of the mx6 */ |
05d54b82 FE |
122 | case MXC_CPU_MX6SX: |
123 | return "6SX"; /* SoloX version of the mx6 */ | |
20332a06 | 124 | case MXC_CPU_MX51: |
a7683867 | 125 | return "51"; |
20332a06 | 126 | case MXC_CPU_MX53: |
a7683867 FE |
127 | return "53"; |
128 | default: | |
e972d72b | 129 | return "??"; |
a7683867 FE |
130 | } |
131 | } | |
132 | ||
18936ee2 JL |
133 | int print_cpuinfo(void) |
134 | { | |
135 | u32 cpurev; | |
136 | ||
137 | cpurev = get_cpu_rev(); | |
a7683867 FE |
138 | |
139 | printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", | |
140 | get_imx_type((cpurev & 0xFF000) >> 12), | |
18936ee2 JL |
141 | (cpurev & 0x000F0) >> 4, |
142 | (cpurev & 0x0000F) >> 0, | |
143 | mxc_get_clock(MXC_ARM_CLK) / 1000000); | |
144 | printf("Reset cause: %s\n", get_reset_cause()); | |
145 | return 0; | |
146 | } | |
147 | #endif | |
148 | ||
149 | int cpu_eth_init(bd_t *bis) | |
150 | { | |
151 | int rc = -ENODEV; | |
152 | ||
153 | #if defined(CONFIG_FEC_MXC) | |
154 | rc = fecmxc_initialize(bis); | |
155 | #endif | |
156 | ||
157 | return rc; | |
158 | } | |
159 | ||
ecb0f317 | 160 | #ifdef CONFIG_FSL_ESDHC |
18936ee2 JL |
161 | /* |
162 | * Initializes on-chip MMC controllers. | |
163 | * to override, implement board_mmc_init() | |
164 | */ | |
165 | int cpu_mmc_init(bd_t *bis) | |
166 | { | |
18936ee2 | 167 | return fsl_esdhc_mmc_init(bis); |
18936ee2 | 168 | } |
ecb0f317 | 169 | #endif |
18936ee2 | 170 | |
6a376046 FE |
171 | u32 get_ahb_clk(void) |
172 | { | |
173 | struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; | |
174 | u32 reg, ahb_podf; | |
175 | ||
176 | reg = __raw_readl(&imx_ccm->cbcdr); | |
177 | reg &= MXC_CCM_CBCDR_AHB_PODF_MASK; | |
178 | ahb_podf = reg >> MXC_CCM_CBCDR_AHB_PODF_OFFSET; | |
179 | ||
180 | return get_periph_clk() / (ahb_podf + 1); | |
181 | } | |
e1eb75b5 EN |
182 | |
183 | #if defined(CONFIG_VIDEO_IPUV3) | |
184 | void arch_preboot_os(void) | |
185 | { | |
186 | /* disable video before launching O/S */ | |
187 | ipuv3_fb_shutdown(); | |
188 | } | |
189 | #endif | |
32c81ea6 FE |
190 | |
191 | void set_chipselect_size(int const cs_size) | |
192 | { | |
193 | unsigned int reg; | |
194 | struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; | |
195 | reg = readl(&iomuxc_regs->gpr[1]); | |
196 | ||
197 | switch (cs_size) { | |
198 | case CS0_128: | |
199 | reg &= ~0x7; /* CS0=128MB, CS1=0, CS2=0, CS3=0 */ | |
200 | reg |= 0x5; | |
201 | break; | |
202 | case CS0_64M_CS1_64M: | |
203 | reg &= ~0x3F; /* CS0=64MB, CS1=64MB, CS2=0, CS3=0 */ | |
204 | reg |= 0x1B; | |
205 | break; | |
206 | case CS0_64M_CS1_32M_CS2_32M: | |
207 | reg &= ~0x1FF; /* CS0=64MB, CS1=32MB, CS2=32MB, CS3=0 */ | |
208 | reg |= 0x4B; | |
209 | break; | |
210 | case CS0_32M_CS1_32M_CS2_32M_CS3_32M: | |
211 | reg &= ~0xFFF; /* CS0=32MB, CS1=32MB, CS2=32MB, CS3=32MB */ | |
212 | reg |= 0x249; | |
213 | break; | |
214 | default: | |
215 | printf("Unknown chip select size: %d\n", cs_size); | |
216 | break; | |
217 | } | |
218 | ||
219 | writel(reg, &iomuxc_regs->gpr[1]); | |
220 | } |