f8d5dba91c8a04ce5875a02bbb58f68148fbe097
[oweals/u-boot.git] / board / sunxi / board.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2012-2013 Henrik Nordstrom <henrik@henriknordstrom.net>
4  * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
5  *
6  * (C) Copyright 2007-2011
7  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
8  * Tom Cubie <tangliang@allwinnertech.com>
9  *
10  * Some board init for the Allwinner A10-evb board.
11  */
12
13 #include <common.h>
14 #include <dm.h>
15 #include <env.h>
16 #include <hang.h>
17 #include <image.h>
18 #include <init.h>
19 #include <log.h>
20 #include <mmc.h>
21 #include <axp_pmic.h>
22 #include <generic-phy.h>
23 #include <phy-sun4i-usb.h>
24 #include <asm/arch/clock.h>
25 #include <asm/arch/cpu.h>
26 #include <asm/arch/display.h>
27 #include <asm/arch/dram.h>
28 #include <asm/arch/gpio.h>
29 #include <asm/arch/mmc.h>
30 #include <asm/arch/spl.h>
31 #include <u-boot/crc.h>
32 #ifndef CONFIG_ARM64
33 #include <asm/armv7.h>
34 #endif
35 #include <asm/gpio.h>
36 #include <asm/io.h>
37 #include <u-boot/crc.h>
38 #include <env_internal.h>
39 #include <linux/libfdt.h>
40 #include <nand.h>
41 #include <net.h>
42 #include <spl.h>
43 #include <sy8106a.h>
44 #include <asm/setup.h>
45
46 #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
47 /* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */
48 int soft_i2c_gpio_sda;
49 int soft_i2c_gpio_scl;
50
51 static int soft_i2c_board_init(void)
52 {
53         int ret;
54
55         soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA);
56         if (soft_i2c_gpio_sda < 0) {
57                 printf("Error invalid soft i2c sda pin: '%s', err %d\n",
58                        CONFIG_VIDEO_LCD_PANEL_I2C_SDA, soft_i2c_gpio_sda);
59                 return soft_i2c_gpio_sda;
60         }
61         ret = gpio_request(soft_i2c_gpio_sda, "soft-i2c-sda");
62         if (ret) {
63                 printf("Error requesting soft i2c sda pin: '%s', err %d\n",
64                        CONFIG_VIDEO_LCD_PANEL_I2C_SDA, ret);
65                 return ret;
66         }
67
68         soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL);
69         if (soft_i2c_gpio_scl < 0) {
70                 printf("Error invalid soft i2c scl pin: '%s', err %d\n",
71                        CONFIG_VIDEO_LCD_PANEL_I2C_SCL, soft_i2c_gpio_scl);
72                 return soft_i2c_gpio_scl;
73         }
74         ret = gpio_request(soft_i2c_gpio_scl, "soft-i2c-scl");
75         if (ret) {
76                 printf("Error requesting soft i2c scl pin: '%s', err %d\n",
77                        CONFIG_VIDEO_LCD_PANEL_I2C_SCL, ret);
78                 return ret;
79         }
80
81         return 0;
82 }
83 #else
84 static int soft_i2c_board_init(void) { return 0; }
85 #endif
86
87 DECLARE_GLOBAL_DATA_PTR;
88
89 void i2c_init_board(void)
90 {
91 #ifdef CONFIG_I2C0_ENABLE
92 #if defined(CONFIG_MACH_SUN4I) || \
93     defined(CONFIG_MACH_SUN5I) || \
94     defined(CONFIG_MACH_SUN7I) || \
95     defined(CONFIG_MACH_SUN8I_R40)
96         sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0);
97         sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0);
98         clock_twi_onoff(0, 1);
99 #elif defined(CONFIG_MACH_SUN6I)
100         sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0);
101         sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0);
102         clock_twi_onoff(0, 1);
103 #elif defined(CONFIG_MACH_SUN8I)
104         sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
105         sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
106         clock_twi_onoff(0, 1);
107 #elif defined(CONFIG_MACH_SUN50I)
108         sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_GPH_TWI0);
109         sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_GPH_TWI0);
110         clock_twi_onoff(0, 1);
111 #endif
112 #endif
113
114 #ifdef CONFIG_I2C1_ENABLE
115 #if defined(CONFIG_MACH_SUN4I) || \
116     defined(CONFIG_MACH_SUN7I) || \
117     defined(CONFIG_MACH_SUN8I_R40)
118         sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1);
119         sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1);
120         clock_twi_onoff(1, 1);
121 #elif defined(CONFIG_MACH_SUN5I)
122         sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1);
123         sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1);
124         clock_twi_onoff(1, 1);
125 #elif defined(CONFIG_MACH_SUN6I)
126         sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1);
127         sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1);
128         clock_twi_onoff(1, 1);
129 #elif defined(CONFIG_MACH_SUN8I)
130         sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1);
131         sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1);
132         clock_twi_onoff(1, 1);
133 #elif defined(CONFIG_MACH_SUN50I)
134         sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN50I_GPH_TWI1);
135         sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1);
136         clock_twi_onoff(1, 1);
137 #endif
138 #endif
139
140 #ifdef CONFIG_I2C2_ENABLE
141 #if defined(CONFIG_MACH_SUN4I) || \
142     defined(CONFIG_MACH_SUN7I) || \
143     defined(CONFIG_MACH_SUN8I_R40)
144         sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2);
145         sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2);
146         clock_twi_onoff(2, 1);
147 #elif defined(CONFIG_MACH_SUN5I)
148         sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2);
149         sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2);
150         clock_twi_onoff(2, 1);
151 #elif defined(CONFIG_MACH_SUN6I)
152         sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2);
153         sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2);
154         clock_twi_onoff(2, 1);
155 #elif defined(CONFIG_MACH_SUN8I)
156         sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2);
157         sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2);
158         clock_twi_onoff(2, 1);
159 #elif defined(CONFIG_MACH_SUN50I)
160         sunxi_gpio_set_cfgpin(SUNXI_GPE(14), SUN50I_GPE_TWI2);
161         sunxi_gpio_set_cfgpin(SUNXI_GPE(15), SUN50I_GPE_TWI2);
162         clock_twi_onoff(2, 1);
163 #endif
164 #endif
165
166 #ifdef CONFIG_I2C3_ENABLE
167 #if defined(CONFIG_MACH_SUN6I)
168         sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3);
169         sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3);
170         clock_twi_onoff(3, 1);
171 #elif defined(CONFIG_MACH_SUN7I) || \
172       defined(CONFIG_MACH_SUN8I_R40)
173         sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3);
174         sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3);
175         clock_twi_onoff(3, 1);
176 #endif
177 #endif
178
179 #ifdef CONFIG_I2C4_ENABLE
180 #if defined(CONFIG_MACH_SUN7I) || \
181     defined(CONFIG_MACH_SUN8I_R40)
182         sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4);
183         sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4);
184         clock_twi_onoff(4, 1);
185 #endif
186 #endif
187
188 #ifdef CONFIG_R_I2C_ENABLE
189 #ifdef CONFIG_MACH_SUN50I
190         clock_twi_onoff(5, 1);
191         sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI);
192         sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI);
193 #else
194         clock_twi_onoff(5, 1);
195         sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI);
196         sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI);
197 #endif
198 #endif
199 }
200
201 #if defined(CONFIG_ENV_IS_IN_MMC) && defined(CONFIG_ENV_IS_IN_FAT)
202 enum env_location env_get_location(enum env_operation op, int prio)
203 {
204         switch (prio) {
205         case 0:
206                 return ENVL_FAT;
207
208         case 1:
209                 return ENVL_MMC;
210
211         default:
212                 return ENVL_UNKNOWN;
213         }
214 }
215 #endif
216
217 #ifdef CONFIG_DM_MMC
218 static void mmc_pinmux_setup(int sdc);
219 #endif
220
221 /* add board specific code here */
222 int board_init(void)
223 {
224         __maybe_unused int id_pfr1, ret, satapwr_pin, macpwr_pin;
225
226         gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
227
228 #ifndef CONFIG_ARM64
229         asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1));
230         debug("id_pfr1: 0x%08x\n", id_pfr1);
231         /* Generic Timer Extension available? */
232         if ((id_pfr1 >> CPUID_ARM_GENTIMER_SHIFT) & 0xf) {
233                 uint32_t freq;
234
235                 debug("Setting CNTFRQ\n");
236
237                 /*
238                  * CNTFRQ is a secure register, so we will crash if we try to
239                  * write this from the non-secure world (read is OK, though).
240                  * In case some bootcode has already set the correct value,
241                  * we avoid the risk of writing to it.
242                  */
243                 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(freq));
244                 if (freq != COUNTER_FREQUENCY) {
245                         debug("arch timer frequency is %d Hz, should be %d, fixing ...\n",
246                               freq, COUNTER_FREQUENCY);
247 #ifdef CONFIG_NON_SECURE
248                         printf("arch timer frequency is wrong, but cannot adjust it\n");
249 #else
250                         asm volatile("mcr p15, 0, %0, c14, c0, 0"
251                                      : : "r"(COUNTER_FREQUENCY));
252 #endif
253                 }
254         }
255 #endif /* !CONFIG_ARM64 */
256
257         ret = axp_gpio_init();
258         if (ret)
259                 return ret;
260
261 #ifdef CONFIG_SATAPWR
262         satapwr_pin = sunxi_name_to_gpio(CONFIG_SATAPWR);
263         gpio_request(satapwr_pin, "satapwr");
264         gpio_direction_output(satapwr_pin, 1);
265         /* Give attached sata device time to power-up to avoid link timeouts */
266         mdelay(500);
267 #endif
268 #ifdef CONFIG_MACPWR
269         macpwr_pin = sunxi_name_to_gpio(CONFIG_MACPWR);
270         gpio_request(macpwr_pin, "macpwr");
271         gpio_direction_output(macpwr_pin, 1);
272 #endif
273
274 #ifdef CONFIG_DM_I2C
275         /*
276          * Temporary workaround for enabling I2C clocks until proper sunxi DM
277          * clk, reset and pinctrl drivers land.
278          */
279         i2c_init_board();
280 #endif
281
282 #ifdef CONFIG_DM_MMC
283         /*
284          * Temporary workaround for enabling MMC clocks until a sunxi DM
285          * pinctrl driver lands.
286          */
287         mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
288 #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
289         mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
290 #endif
291 #endif  /* CONFIG_DM_MMC */
292
293         /* Uses dm gpio code so do this here and not in i2c_init_board() */
294         return soft_i2c_board_init();
295 }
296
297 /*
298  * On older SoCs the SPL is actually at address zero, so using NULL as
299  * an error value does not work.
300  */
301 #define INVALID_SPL_HEADER ((void *)~0UL)
302
303 static struct boot_file_head * get_spl_header(uint8_t req_version)
304 {
305         struct boot_file_head *spl = (void *)(ulong)SPL_ADDR;
306         uint8_t spl_header_version = spl->spl_signature[3];
307
308         /* Is there really the SPL header (still) there? */
309         if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0)
310                 return INVALID_SPL_HEADER;
311
312         if (spl_header_version < req_version) {
313                 printf("sunxi SPL version mismatch: expected %u, got %u\n",
314                        req_version, spl_header_version);
315                 return INVALID_SPL_HEADER;
316         }
317
318         return spl;
319 }
320
321 int dram_init(void)
322 {
323         struct boot_file_head *spl = get_spl_header(SPL_DRAM_HEADER_VERSION);
324
325         if (spl == INVALID_SPL_HEADER)
326                 gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0,
327                                             PHYS_SDRAM_0_SIZE);
328         else
329                 gd->ram_size = (phys_addr_t)spl->dram_size << 20;
330
331         if (gd->ram_size > CONFIG_SUNXI_DRAM_MAX_SIZE)
332                 gd->ram_size = CONFIG_SUNXI_DRAM_MAX_SIZE;
333
334         return 0;
335 }
336
337 #if defined(CONFIG_NAND_SUNXI)
338 static void nand_pinmux_setup(void)
339 {
340         unsigned int pin;
341
342         for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++)
343                 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
344
345 #if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I
346         for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++)
347                 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
348 #endif
349         /* sun4i / sun7i do have a PC23, but it is not used for nand,
350          * only sun7i has a PC24 */
351 #ifdef CONFIG_MACH_SUN7I
352         sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND);
353 #endif
354 }
355
356 static void nand_clock_setup(void)
357 {
358         struct sunxi_ccm_reg *const ccm =
359                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
360
361         setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
362 #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I || \
363     defined CONFIG_MACH_SUN9I || defined CONFIG_MACH_SUN50I
364         setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_GATE_OFFSET_NAND0));
365 #endif
366         setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
367 }
368
369 void board_nand_init(void)
370 {
371         nand_pinmux_setup();
372         nand_clock_setup();
373 #ifndef CONFIG_SPL_BUILD
374         sunxi_nand_init();
375 #endif
376 }
377 #endif
378
379 #ifdef CONFIG_MMC
380 static void mmc_pinmux_setup(int sdc)
381 {
382         unsigned int pin;
383         __maybe_unused int pins;
384
385         switch (sdc) {
386         case 0:
387                 /* SDC0: PF0-PF5 */
388                 for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) {
389                         sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0);
390                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
391                         sunxi_gpio_set_drv(pin, 2);
392                 }
393                 break;
394
395         case 1:
396                 pins = sunxi_name_to_gpio_bank(CONFIG_MMC1_PINS);
397
398 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \
399     defined(CONFIG_MACH_SUN8I_R40)
400                 if (pins == SUNXI_GPIO_H) {
401                         /* SDC1: PH22-PH-27 */
402                         for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) {
403                                 sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1);
404                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
405                                 sunxi_gpio_set_drv(pin, 2);
406                         }
407                 } else {
408                         /* SDC1: PG0-PG5 */
409                         for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
410                                 sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1);
411                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
412                                 sunxi_gpio_set_drv(pin, 2);
413                         }
414                 }
415 #elif defined(CONFIG_MACH_SUN5I)
416                 /* SDC1: PG3-PG8 */
417                 for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) {
418                         sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1);
419                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
420                         sunxi_gpio_set_drv(pin, 2);
421                 }
422 #elif defined(CONFIG_MACH_SUN6I)
423                 /* SDC1: PG0-PG5 */
424                 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
425                         sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1);
426                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
427                         sunxi_gpio_set_drv(pin, 2);
428                 }
429 #elif defined(CONFIG_MACH_SUN8I)
430                 if (pins == SUNXI_GPIO_D) {
431                         /* SDC1: PD2-PD7 */
432                         for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) {
433                                 sunxi_gpio_set_cfgpin(pin, SUN8I_GPD_SDC1);
434                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
435                                 sunxi_gpio_set_drv(pin, 2);
436                         }
437                 } else {
438                         /* SDC1: PG0-PG5 */
439                         for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
440                                 sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1);
441                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
442                                 sunxi_gpio_set_drv(pin, 2);
443                         }
444                 }
445 #endif
446                 break;
447
448         case 2:
449                 pins = sunxi_name_to_gpio_bank(CONFIG_MMC2_PINS);
450
451 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
452                 /* SDC2: PC6-PC11 */
453                 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) {
454                         sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
455                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
456                         sunxi_gpio_set_drv(pin, 2);
457                 }
458 #elif defined(CONFIG_MACH_SUN5I)
459                 if (pins == SUNXI_GPIO_E) {
460                         /* SDC2: PE4-PE9 */
461                         for (pin = SUNXI_GPE(4); pin <= SUNXI_GPD(9); pin++) {
462                                 sunxi_gpio_set_cfgpin(pin, SUN5I_GPE_SDC2);
463                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
464                                 sunxi_gpio_set_drv(pin, 2);
465                         }
466                 } else {
467                         /* SDC2: PC6-PC15 */
468                         for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
469                                 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
470                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
471                                 sunxi_gpio_set_drv(pin, 2);
472                         }
473                 }
474 #elif defined(CONFIG_MACH_SUN6I)
475                 if (pins == SUNXI_GPIO_A) {
476                         /* SDC2: PA9-PA14 */
477                         for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
478                                 sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC2);
479                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
480                                 sunxi_gpio_set_drv(pin, 2);
481                         }
482                 } else {
483                         /* SDC2: PC6-PC15, PC24 */
484                         for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
485                                 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
486                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
487                                 sunxi_gpio_set_drv(pin, 2);
488                         }
489
490                         sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
491                         sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
492                         sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
493                 }
494 #elif defined(CONFIG_MACH_SUN8I_R40)
495                 /* SDC2: PC6-PC15, PC24 */
496                 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
497                         sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
498                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
499                         sunxi_gpio_set_drv(pin, 2);
500                 }
501
502                 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
503                 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
504                 sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
505 #elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I)
506                 /* SDC2: PC5-PC6, PC8-PC16 */
507                 for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) {
508                         sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
509                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
510                         sunxi_gpio_set_drv(pin, 2);
511                 }
512
513                 for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); pin++) {
514                         sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
515                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
516                         sunxi_gpio_set_drv(pin, 2);
517                 }
518 #elif defined(CONFIG_MACH_SUN50I_H6)
519                 /* SDC2: PC4-PC14 */
520                 for (pin = SUNXI_GPC(4); pin <= SUNXI_GPC(14); pin++) {
521                         sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
522                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
523                         sunxi_gpio_set_drv(pin, 2);
524                 }
525 #elif defined(CONFIG_MACH_SUN9I)
526                 /* SDC2: PC6-PC16 */
527                 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(16); pin++) {
528                         sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
529                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
530                         sunxi_gpio_set_drv(pin, 2);
531                 }
532 #endif
533                 break;
534
535         case 3:
536                 pins = sunxi_name_to_gpio_bank(CONFIG_MMC3_PINS);
537
538 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \
539     defined(CONFIG_MACH_SUN8I_R40)
540                 /* SDC3: PI4-PI9 */
541                 for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) {
542                         sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3);
543                         sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
544                         sunxi_gpio_set_drv(pin, 2);
545                 }
546 #elif defined(CONFIG_MACH_SUN6I)
547                 if (pins == SUNXI_GPIO_A) {
548                         /* SDC3: PA9-PA14 */
549                         for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
550                                 sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC3);
551                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
552                                 sunxi_gpio_set_drv(pin, 2);
553                         }
554                 } else {
555                         /* SDC3: PC6-PC15, PC24 */
556                         for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
557                                 sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3);
558                                 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
559                                 sunxi_gpio_set_drv(pin, 2);
560                         }
561
562                         sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3);
563                         sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
564                         sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
565                 }
566 #endif
567                 break;
568
569         default:
570                 printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc);
571                 break;
572         }
573 }
574
575 int board_mmc_init(bd_t *bis)
576 {
577         __maybe_unused struct mmc *mmc0, *mmc1;
578
579         mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
580         mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
581         if (!mmc0)
582                 return -1;
583
584 #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
585         mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
586         mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
587         if (!mmc1)
588                 return -1;
589 #endif
590
591         return 0;
592 }
593 #endif
594
595 #ifdef CONFIG_SPL_BUILD
596
597 static void sunxi_spl_store_dram_size(phys_addr_t dram_size)
598 {
599         struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
600
601         if (spl == INVALID_SPL_HEADER)
602                 return;
603
604         /* Promote the header version for U-Boot proper, if needed. */
605         if (spl->spl_signature[3] < SPL_DRAM_HEADER_VERSION)
606                 spl->spl_signature[3] = SPL_DRAM_HEADER_VERSION;
607
608         spl->dram_size = dram_size >> 20;
609 }
610
611 void sunxi_board_init(void)
612 {
613         int power_failed = 0;
614
615 #ifdef CONFIG_SY8106A_POWER
616         power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT);
617 #endif
618
619 #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \
620         defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
621         defined CONFIG_AXP818_POWER
622         power_failed = axp_init();
623
624 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
625         defined CONFIG_AXP818_POWER
626         power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT);
627 #endif
628         power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT);
629         power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT);
630 #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER)
631         power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT);
632 #endif
633 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
634         defined CONFIG_AXP818_POWER
635         power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT);
636 #endif
637
638 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
639         defined CONFIG_AXP818_POWER
640         power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT);
641 #endif
642         power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT);
643 #if !defined(CONFIG_AXP152_POWER)
644         power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT);
645 #endif
646 #ifdef CONFIG_AXP209_POWER
647         power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT);
648 #endif
649
650 #if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP809_POWER) || \
651         defined(CONFIG_AXP818_POWER)
652         power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT);
653         power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT);
654 #if !defined CONFIG_AXP809_POWER
655         power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT);
656         power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT);
657 #endif
658         power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT);
659         power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT);
660         power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT);
661 #endif
662
663 #ifdef CONFIG_AXP818_POWER
664         power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT);
665         power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT);
666         power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT);
667 #endif
668
669 #if defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
670         power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON));
671 #endif
672 #endif
673         printf("DRAM:");
674         gd->ram_size = sunxi_dram_init();
675         printf(" %d MiB\n", (int)(gd->ram_size >> 20));
676         if (!gd->ram_size)
677                 hang();
678
679         sunxi_spl_store_dram_size(gd->ram_size);
680
681         /*
682          * Only clock up the CPU to full speed if we are reasonably
683          * assured it's being powered with suitable core voltage
684          */
685         if (!power_failed)
686                 clock_set_pll1(CONFIG_SYS_CLK_FREQ);
687         else
688                 printf("Failed to set core voltage! Can't set CPU frequency\n");
689 }
690 #endif
691
692 #ifdef CONFIG_USB_GADGET
693 int g_dnl_board_usb_cable_connected(void)
694 {
695         struct udevice *dev;
696         struct phy phy;
697         int ret;
698
699         ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
700         if (ret) {
701                 pr_err("%s: Cannot find USB device\n", __func__);
702                 return ret;
703         }
704
705         ret = generic_phy_get_by_name(dev, "usb", &phy);
706         if (ret) {
707                 pr_err("failed to get %s USB PHY\n", dev->name);
708                 return ret;
709         }
710
711         ret = generic_phy_init(&phy);
712         if (ret) {
713                 pr_err("failed to init %s USB PHY\n", dev->name);
714                 return ret;
715         }
716
717         ret = sun4i_usb_phy_vbus_detect(&phy);
718         if (ret == 1) {
719                 pr_err("A charger is plugged into the OTG\n");
720                 return -ENODEV;
721         }
722
723         return ret;
724 }
725 #endif
726
727 #ifdef CONFIG_SERIAL_TAG
728 void get_board_serial(struct tag_serialnr *serialnr)
729 {
730         char *serial_string;
731         unsigned long long serial;
732
733         serial_string = env_get("serial#");
734
735         if (serial_string) {
736                 serial = simple_strtoull(serial_string, NULL, 16);
737
738                 serialnr->high = (unsigned int) (serial >> 32);
739                 serialnr->low = (unsigned int) (serial & 0xffffffff);
740         } else {
741                 serialnr->high = 0;
742                 serialnr->low = 0;
743         }
744 }
745 #endif
746
747 /*
748  * Check the SPL header for the "sunxi" variant. If found: parse values
749  * that might have been passed by the loader ("fel" utility), and update
750  * the environment accordingly.
751  */
752 static void parse_spl_header(const uint32_t spl_addr)
753 {
754         struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION);
755
756         if (spl == INVALID_SPL_HEADER)
757                 return;
758
759         if (!spl->fel_script_address)
760                 return;
761
762         if (spl->fel_uEnv_length != 0) {
763                 /*
764                  * data is expected in uEnv.txt compatible format, so "env
765                  * import -t" the string(s) at fel_script_address right away.
766                  */
767                 himport_r(&env_htab, (char *)(uintptr_t)spl->fel_script_address,
768                           spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL);
769                 return;
770         }
771         /* otherwise assume .scr format (mkimage-type script) */
772         env_set_hex("fel_scriptaddr", spl->fel_script_address);
773 }
774
775 /*
776  * Note this function gets called multiple times.
777  * It must not make any changes to env variables which already exist.
778  */
779 static void setup_environment(const void *fdt)
780 {
781         char serial_string[17] = { 0 };
782         unsigned int sid[4];
783         uint8_t mac_addr[6];
784         char ethaddr[16];
785         int i, ret;
786
787         ret = sunxi_get_sid(sid);
788         if (ret == 0 && sid[0] != 0) {
789                 /*
790                  * The single words 1 - 3 of the SID have quite a few bits
791                  * which are the same on many models, so we take a crc32
792                  * of all 3 words, to get a more unique value.
793                  *
794                  * Note we only do this on newer SoCs as we cannot change
795                  * the algorithm on older SoCs since those have been using
796                  * fixed mac-addresses based on only using word 3 for a
797                  * long time and changing a fixed mac-address with an
798                  * u-boot update is not good.
799                  */
800 #if !defined(CONFIG_MACH_SUN4I) && !defined(CONFIG_MACH_SUN5I) && \
801     !defined(CONFIG_MACH_SUN6I) && !defined(CONFIG_MACH_SUN7I) && \
802     !defined(CONFIG_MACH_SUN8I_A23) && !defined(CONFIG_MACH_SUN8I_A33)
803                 sid[3] = crc32(0, (unsigned char *)&sid[1], 12);
804 #endif
805
806                 /* Ensure the NIC specific bytes of the mac are not all 0 */
807                 if ((sid[3] & 0xffffff) == 0)
808                         sid[3] |= 0x800000;
809
810                 for (i = 0; i < 4; i++) {
811                         sprintf(ethaddr, "ethernet%d", i);
812                         if (!fdt_get_alias(fdt, ethaddr))
813                                 continue;
814
815                         if (i == 0)
816                                 strcpy(ethaddr, "ethaddr");
817                         else
818                                 sprintf(ethaddr, "eth%daddr", i);
819
820                         if (env_get(ethaddr))
821                                 continue;
822
823                         /* Non OUI / registered MAC address */
824                         mac_addr[0] = (i << 4) | 0x02;
825                         mac_addr[1] = (sid[0] >>  0) & 0xff;
826                         mac_addr[2] = (sid[3] >> 24) & 0xff;
827                         mac_addr[3] = (sid[3] >> 16) & 0xff;
828                         mac_addr[4] = (sid[3] >>  8) & 0xff;
829                         mac_addr[5] = (sid[3] >>  0) & 0xff;
830
831                         eth_env_set_enetaddr(ethaddr, mac_addr);
832                 }
833
834                 if (!env_get("serial#")) {
835                         snprintf(serial_string, sizeof(serial_string),
836                                 "%08x%08x", sid[0], sid[3]);
837
838                         env_set("serial#", serial_string);
839                 }
840         }
841 }
842
843 int misc_init_r(void)
844 {
845         uint boot;
846
847         env_set("fel_booted", NULL);
848         env_set("fel_scriptaddr", NULL);
849         env_set("mmc_bootdev", NULL);
850
851         boot = sunxi_get_boot_device();
852         /* determine if we are running in FEL mode */
853         if (boot == BOOT_DEVICE_BOARD) {
854                 env_set("fel_booted", "1");
855                 parse_spl_header(SPL_ADDR);
856         /* or if we booted from MMC, and which one */
857         } else if (boot == BOOT_DEVICE_MMC1) {
858                 env_set("mmc_bootdev", "0");
859         } else if (boot == BOOT_DEVICE_MMC2) {
860                 env_set("mmc_bootdev", "1");
861         }
862
863         setup_environment(gd->fdt_blob);
864
865 #ifdef CONFIG_USB_ETHER
866         usb_ether_init();
867 #endif
868
869         return 0;
870 }
871
872 int ft_board_setup(void *blob, bd_t *bd)
873 {
874         int __maybe_unused r;
875
876         /*
877          * Call setup_environment again in case the boot fdt has
878          * ethernet aliases the u-boot copy does not have.
879          */
880         setup_environment(blob);
881
882 #ifdef CONFIG_VIDEO_DT_SIMPLEFB
883         r = sunxi_simplefb_setup(blob);
884         if (r)
885                 return r;
886 #endif
887         return 0;
888 }
889
890 #ifdef CONFIG_SPL_LOAD_FIT
891 int board_fit_config_name_match(const char *name)
892 {
893         struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
894         const char *cmp_str = (const char *)spl;
895
896         /* Check if there is a DT name stored in the SPL header and use that. */
897         if (spl != INVALID_SPL_HEADER && spl->dt_name_offset) {
898                 cmp_str += spl->dt_name_offset;
899         } else {
900 #ifdef CONFIG_DEFAULT_DEVICE_TREE
901                 cmp_str = CONFIG_DEFAULT_DEVICE_TREE;
902 #else
903                 return 0;
904 #endif
905         };
906
907 #ifdef CONFIG_PINE64_DT_SELECTION
908 /* Differentiate the two Pine64 board DTs by their DRAM size. */
909         if (strstr(name, "-pine64") && strstr(cmp_str, "-pine64")) {
910                 if ((gd->ram_size > 512 * 1024 * 1024))
911                         return !strstr(name, "plus");
912                 else
913                         return !!strstr(name, "plus");
914         } else {
915                 return strcmp(name, cmp_str);
916         }
917 #endif
918         return strcmp(name, cmp_str);
919 }
920 #endif