]>
Commit | Line | Data |
---|---|---|
c5752f73 AA |
1 | /* |
2 | * Copyright (C) 2015 Freescale Semiconductor, Inc. | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <asm/io.h> | |
9 | #include <asm/arch/imx-regs.h> | |
10 | #include <asm/arch/clock.h> | |
11 | #include <asm/arch/sys_proto.h> | |
12 | #include <asm/imx-common/boot_mode.h> | |
13 | #include <asm/imx-common/dma.h> | |
14 | #include <asm/arch/crm_regs.h> | |
15 | #include <dm.h> | |
16 | #include <imx_thermal.h> | |
17 | ||
c5752f73 AA |
18 | #if defined(CONFIG_IMX_THERMAL) |
19 | static const struct imx_thermal_plat imx7_thermal_plat = { | |
20 | .regs = (void *)ANATOP_BASE_ADDR, | |
21 | .fuse_bank = 3, | |
22 | .fuse_word = 3, | |
23 | }; | |
24 | ||
25 | U_BOOT_DEVICE(imx7_thermal) = { | |
26 | .name = "imx_thermal", | |
27 | .platdata = &imx7_thermal_plat, | |
28 | }; | |
29 | #endif | |
30 | ||
31 | /* | |
32 | * OCOTP_TESTER3[9:8] (see Fusemap Description Table offset 0x440) | |
33 | * defines a 2-bit SPEED_GRADING | |
34 | */ | |
35 | #define OCOTP_TESTER3_SPEED_SHIFT 8 | |
36 | #define OCOTP_TESTER3_SPEED_800MHZ 0 | |
37 | #define OCOTP_TESTER3_SPEED_850MHZ 1 | |
38 | #define OCOTP_TESTER3_SPEED_1GHZ 2 | |
39 | ||
40 | u32 get_cpu_speed_grade_hz(void) | |
41 | { | |
42 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | |
43 | struct fuse_bank *bank = &ocotp->bank[1]; | |
44 | struct fuse_bank1_regs *fuse = | |
45 | (struct fuse_bank1_regs *)bank->fuse_regs; | |
46 | uint32_t val; | |
47 | ||
48 | val = readl(&fuse->tester3); | |
49 | val >>= OCOTP_TESTER3_SPEED_SHIFT; | |
50 | val &= 0x3; | |
51 | ||
52 | switch(val) { | |
53 | case OCOTP_TESTER3_SPEED_800MHZ: | |
54 | return 792000000; | |
55 | case OCOTP_TESTER3_SPEED_850MHZ: | |
56 | return 852000000; | |
57 | case OCOTP_TESTER3_SPEED_1GHZ: | |
58 | return 996000000; | |
59 | } | |
60 | return 0; | |
61 | } | |
62 | ||
63 | /* | |
64 | * OCOTP_TESTER3[7:6] (see Fusemap Description Table offset 0x440) | |
65 | * defines a 2-bit SPEED_GRADING | |
66 | */ | |
67 | #define OCOTP_TESTER3_TEMP_SHIFT 6 | |
68 | ||
69 | u32 get_cpu_temp_grade(int *minc, int *maxc) | |
70 | { | |
71 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | |
72 | struct fuse_bank *bank = &ocotp->bank[1]; | |
73 | struct fuse_bank1_regs *fuse = | |
74 | (struct fuse_bank1_regs *)bank->fuse_regs; | |
75 | uint32_t val; | |
76 | ||
77 | val = readl(&fuse->tester3); | |
78 | val >>= OCOTP_TESTER3_TEMP_SHIFT; | |
79 | val &= 0x3; | |
80 | ||
81 | if (minc && maxc) { | |
f697c2ac | 82 | if (val == TEMP_AUTOMOTIVE) { |
c5752f73 AA |
83 | *minc = -40; |
84 | *maxc = 125; | |
85 | } else if (val == TEMP_INDUSTRIAL) { | |
86 | *minc = -40; | |
87 | *maxc = 105; | |
88 | } else if (val == TEMP_EXTCOMMERCIAL) { | |
89 | *minc = -20; | |
90 | *maxc = 105; | |
91 | } else { | |
92 | *minc = 0; | |
93 | *maxc = 95; | |
94 | } | |
95 | } | |
96 | return val; | |
97 | } | |
98 | ||
99 | u32 get_cpu_rev(void) | |
100 | { | |
101 | struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) | |
102 | ANATOP_BASE_ADDR; | |
103 | u32 reg = readl(&ccm_anatop->digprog); | |
104 | u32 type = (reg >> 16) & 0xff; | |
105 | ||
106 | reg &= 0xff; | |
107 | return (type << 12) | reg; | |
108 | } | |
109 | ||
110 | #ifdef CONFIG_REVISION_TAG | |
111 | u32 __weak get_board_rev(void) | |
112 | { | |
113 | return get_cpu_rev(); | |
114 | } | |
115 | #endif | |
116 | ||
117 | int arch_cpu_init(void) | |
118 | { | |
119 | init_aips(); | |
120 | ||
121 | /* Disable PDE bit of WMCR register */ | |
122 | imx_set_wdog_powerdown(false); | |
123 | ||
124 | #ifdef CONFIG_APBH_DMA | |
125 | /* Start APBH DMA */ | |
126 | mxs_dma_init(); | |
127 | #endif | |
128 | ||
129 | return 0; | |
130 | } | |
131 | ||
132 | #ifdef CONFIG_SERIAL_TAG | |
133 | void get_board_serial(struct tag_serialnr *serialnr) | |
134 | { | |
135 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | |
136 | struct fuse_bank *bank = &ocotp->bank[0]; | |
137 | struct fuse_bank0_regs *fuse = | |
138 | (struct fuse_bank0_regs *)bank->fuse_regs; | |
139 | ||
140 | serialnr->low = fuse->tester0; | |
141 | serialnr->high = fuse->tester1; | |
142 | } | |
143 | #endif | |
144 | ||
145 | #if defined(CONFIG_FEC_MXC) | |
146 | void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) | |
147 | { | |
148 | struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | |
149 | struct fuse_bank *bank = &ocotp->bank[9]; | |
150 | struct fuse_bank9_regs *fuse = | |
151 | (struct fuse_bank9_regs *)bank->fuse_regs; | |
152 | ||
153 | if (0 == dev_id) { | |
154 | u32 value = readl(&fuse->mac_addr1); | |
155 | mac[0] = (value >> 8); | |
156 | mac[1] = value; | |
157 | ||
158 | value = readl(&fuse->mac_addr0); | |
159 | mac[2] = value >> 24; | |
160 | mac[3] = value >> 16; | |
161 | mac[4] = value >> 8; | |
162 | mac[5] = value; | |
163 | } else { | |
164 | u32 value = readl(&fuse->mac_addr2); | |
165 | mac[0] = value >> 24; | |
166 | mac[1] = value >> 16; | |
167 | mac[2] = value >> 8; | |
168 | mac[3] = value; | |
169 | ||
170 | value = readl(&fuse->mac_addr1); | |
171 | mac[4] = value >> 24; | |
172 | mac[5] = value >> 16; | |
173 | } | |
174 | } | |
175 | #endif | |
176 | ||
177 | void set_wdog_reset(struct wdog_regs *wdog) | |
178 | { | |
179 | u32 reg = readw(&wdog->wcr); | |
180 | /* | |
181 | * Output WDOG_B signal to reset external pmic or POR_B decided by | |
182 | * the board desgin. Without external reset, the peripherals/DDR/ | |
183 | * PMIC are not reset, that may cause system working abnormal. | |
184 | */ | |
185 | reg = readw(&wdog->wcr); | |
186 | reg |= 1 << 3; | |
187 | /* | |
188 | * WDZST bit is write-once only bit. Align this bit in kernel, | |
189 | * otherwise kernel code will have no chance to set this bit. | |
190 | */ | |
191 | reg |= 1 << 0; | |
192 | writew(reg, &wdog->wcr); | |
193 | } | |
194 | ||
195 | /* | |
196 | * cfg_val will be used for | |
197 | * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] | |
198 | * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0] | |
199 | * to SBMR1, which will determine the boot device. | |
200 | */ | |
201 | const struct boot_mode soc_boot_modes[] = { | |
202 | {"ecspi1:0", MAKE_CFGVAL(0x00, 0x60, 0x00, 0x00)}, | |
203 | {"ecspi1:1", MAKE_CFGVAL(0x40, 0x62, 0x00, 0x00)}, | |
204 | {"ecspi1:2", MAKE_CFGVAL(0x80, 0x64, 0x00, 0x00)}, | |
205 | {"ecspi1:3", MAKE_CFGVAL(0xc0, 0x66, 0x00, 0x00)}, | |
206 | ||
207 | {"weim", MAKE_CFGVAL(0x00, 0x50, 0x00, 0x00)}, | |
208 | {"qspi1", MAKE_CFGVAL(0x10, 0x40, 0x00, 0x00)}, | |
209 | /* 4 bit bus width */ | |
210 | {"usdhc1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)}, | |
211 | {"usdhc2", MAKE_CFGVAL(0x10, 0x14, 0x00, 0x00)}, | |
212 | {"usdhc3", MAKE_CFGVAL(0x10, 0x18, 0x00, 0x00)}, | |
213 | {"mmc1", MAKE_CFGVAL(0x10, 0x20, 0x00, 0x00)}, | |
214 | {"mmc2", MAKE_CFGVAL(0x10, 0x24, 0x00, 0x00)}, | |
215 | {"mmc3", MAKE_CFGVAL(0x10, 0x28, 0x00, 0x00)}, | |
216 | {NULL, 0}, | |
217 | }; | |
218 | ||
219 | enum boot_device get_boot_device(void) | |
220 | { | |
221 | struct bootrom_sw_info **p = | |
222 | (struct bootrom_sw_info **)ROM_SW_INFO_ADDR; | |
223 | ||
224 | enum boot_device boot_dev = SD1_BOOT; | |
225 | u8 boot_type = (*p)->boot_dev_type; | |
226 | u8 boot_instance = (*p)->boot_dev_instance; | |
227 | ||
228 | switch (boot_type) { | |
229 | case BOOT_TYPE_SD: | |
230 | boot_dev = boot_instance + SD1_BOOT; | |
231 | break; | |
232 | case BOOT_TYPE_MMC: | |
233 | boot_dev = boot_instance + MMC1_BOOT; | |
234 | break; | |
235 | case BOOT_TYPE_NAND: | |
236 | boot_dev = NAND_BOOT; | |
237 | break; | |
238 | case BOOT_TYPE_QSPI: | |
239 | boot_dev = QSPI_BOOT; | |
240 | break; | |
241 | case BOOT_TYPE_WEIM: | |
242 | boot_dev = WEIM_NOR_BOOT; | |
243 | break; | |
244 | case BOOT_TYPE_SPINOR: | |
245 | boot_dev = SPI_NOR_BOOT; | |
246 | break; | |
247 | default: | |
248 | break; | |
249 | } | |
250 | ||
251 | return boot_dev; | |
252 | } | |
253 | ||
254 | void s_init(void) | |
255 | { | |
256 | #if !defined CONFIG_SPL_BUILD | |
257 | /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ | |
258 | asm volatile( | |
259 | "mrc p15, 0, r0, c1, c0, 1\n" | |
260 | "orr r0, r0, #1 << 6\n" | |
261 | "mcr p15, 0, r0, c1, c0, 1\n"); | |
262 | #endif | |
263 | /* clock configuration. */ | |
264 | clock_init(); | |
265 | ||
266 | return; | |
267 | } |