]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/armv7/mx7/soc.c
Merge remote-tracking branch 'u-boot/master'
[u-boot] / arch / arm / cpu / armv7 / mx7 / soc.c
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
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) {
82                 if (val == TEMP_AUTOMOTIVE) {
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 }