1
2
3
4
5
6
7
8
9
10
11
12
13#include <common.h>
14#include <clock_legacy.h>
15#include <dm.h>
16#include <env.h>
17#include <hang.h>
18#include <image.h>
19#include <init.h>
20#include <log.h>
21#include <mmc.h>
22#include <axp_pmic.h>
23#include <generic-phy.h>
24#include <phy-sun4i-usb.h>
25#include <asm/arch/clock.h>
26#include <asm/arch/cpu.h>
27#include <asm/arch/display.h>
28#include <asm/arch/dram.h>
29#include <asm/arch/mmc.h>
30#include <asm/arch/prcm.h>
31#include <asm/arch/pmic_bus.h>
32#include <asm/arch/spl.h>
33#include <asm/arch/sys_proto.h>
34#include <asm/global_data.h>
35#include <linux/delay.h>
36#include <u-boot/crc.h>
37#ifndef CONFIG_ARM64
38#include <asm/armv7.h>
39#endif
40#include <asm/gpio.h>
41#include <asm/io.h>
42#include <u-boot/crc.h>
43#include <env_internal.h>
44#include <linux/libfdt.h>
45#include <fdt_support.h>
46#include <nand.h>
47#include <net.h>
48#include <spl.h>
49#include <sy8106a.h>
50#include <asm/setup.h>
51#include <status_led.h>
52
53DECLARE_GLOBAL_DATA_PTR;
54
55void i2c_init_board(void)
56{
57#ifdef CONFIG_I2C0_ENABLE
58#if defined(CONFIG_MACH_SUN4I) || \
59 defined(CONFIG_MACH_SUN5I) || \
60 defined(CONFIG_MACH_SUN7I) || \
61 defined(CONFIG_MACH_SUN8I_R40)
62 sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0);
63 sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0);
64 clock_twi_onoff(0, 1);
65#elif defined(CONFIG_MACH_SUN6I)
66 sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0);
67 sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0);
68 clock_twi_onoff(0, 1);
69#elif defined(CONFIG_MACH_SUN8I_V3S)
70 sunxi_gpio_set_cfgpin(SUNXI_GPB(6), SUN8I_V3S_GPB_TWI0);
71 sunxi_gpio_set_cfgpin(SUNXI_GPB(7), SUN8I_V3S_GPB_TWI0);
72 clock_twi_onoff(0, 1);
73#elif defined(CONFIG_MACH_SUN8I)
74 sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
75 sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
76 clock_twi_onoff(0, 1);
77#elif defined(CONFIG_MACH_SUN50I)
78 sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_GPH_TWI0);
79 sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_GPH_TWI0);
80 clock_twi_onoff(0, 1);
81#endif
82#endif
83
84#ifdef CONFIG_I2C1_ENABLE
85#if defined(CONFIG_MACH_SUN4I) || \
86 defined(CONFIG_MACH_SUN7I) || \
87 defined(CONFIG_MACH_SUN8I_R40)
88 sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1);
89 sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1);
90 clock_twi_onoff(1, 1);
91#elif defined(CONFIG_MACH_SUN5I)
92 sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1);
93 sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1);
94 clock_twi_onoff(1, 1);
95#elif defined(CONFIG_MACH_SUN6I)
96 sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1);
97 sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1);
98 clock_twi_onoff(1, 1);
99#elif defined(CONFIG_MACH_SUN8I)
100 sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1);
101 sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1);
102 clock_twi_onoff(1, 1);
103#elif defined(CONFIG_MACH_SUN50I)
104 sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN50I_GPH_TWI1);
105 sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1);
106 clock_twi_onoff(1, 1);
107#endif
108#endif
109
110#ifdef CONFIG_I2C2_ENABLE
111#if defined(CONFIG_MACH_SUN4I) || \
112 defined(CONFIG_MACH_SUN7I) || \
113 defined(CONFIG_MACH_SUN8I_R40)
114 sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2);
115 sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2);
116 clock_twi_onoff(2, 1);
117#elif defined(CONFIG_MACH_SUN5I)
118 sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2);
119 sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2);
120 clock_twi_onoff(2, 1);
121#elif defined(CONFIG_MACH_SUN6I)
122 sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2);
123 sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2);
124 clock_twi_onoff(2, 1);
125#elif defined(CONFIG_MACH_SUN8I)
126 sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2);
127 sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2);
128 clock_twi_onoff(2, 1);
129#elif defined(CONFIG_MACH_SUN50I)
130 sunxi_gpio_set_cfgpin(SUNXI_GPE(14), SUN50I_GPE_TWI2);
131 sunxi_gpio_set_cfgpin(SUNXI_GPE(15), SUN50I_GPE_TWI2);
132 clock_twi_onoff(2, 1);
133#endif
134#endif
135
136#ifdef CONFIG_I2C3_ENABLE
137#if defined(CONFIG_MACH_SUN6I)
138 sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3);
139 sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3);
140 clock_twi_onoff(3, 1);
141#elif defined(CONFIG_MACH_SUN7I) || \
142 defined(CONFIG_MACH_SUN8I_R40)
143 sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3);
144 sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3);
145 clock_twi_onoff(3, 1);
146#endif
147#endif
148
149#ifdef CONFIG_I2C4_ENABLE
150#if defined(CONFIG_MACH_SUN7I) || \
151 defined(CONFIG_MACH_SUN8I_R40)
152 sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4);
153 sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4);
154 clock_twi_onoff(4, 1);
155#endif
156#endif
157
158#ifdef CONFIG_R_I2C_ENABLE
159#ifdef CONFIG_MACH_SUN50I
160 clock_twi_onoff(5, 1);
161 sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI);
162 sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI);
163#elif CONFIG_MACH_SUN50I_H616
164 clock_twi_onoff(5, 1);
165 sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_H616_GPL_R_TWI);
166 sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_H616_GPL_R_TWI);
167#else
168 clock_twi_onoff(5, 1);
169 sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI);
170 sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI);
171#endif
172#endif
173}
174
175
176
177
178
179
180
181enum env_location env_get_location(enum env_operation op, int prio)
182{
183 enum env_location boot_loc = ENVL_FAT;
184
185 gd->env_load_prio = prio;
186
187 switch (sunxi_get_boot_device()) {
188 case BOOT_DEVICE_MMC1:
189 case BOOT_DEVICE_MMC2:
190 boot_loc = ENVL_FAT;
191 break;
192 case BOOT_DEVICE_NAND:
193 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
194 boot_loc = ENVL_NAND;
195 break;
196 case BOOT_DEVICE_SPI:
197 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
198 boot_loc = ENVL_SPI_FLASH;
199 break;
200 case BOOT_DEVICE_BOARD:
201 break;
202 default:
203 break;
204 }
205
206
207 if (prio == 0)
208 return boot_loc;
209
210 if (prio == 1) {
211 switch (boot_loc) {
212 case ENVL_SPI_FLASH:
213 return ENVL_FAT;
214 case ENVL_FAT:
215 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
216 return ENVL_MMC;
217 break;
218 default:
219 break;
220 }
221 }
222
223 return ENVL_UNKNOWN;
224}
225
226#ifdef CONFIG_DM_MMC
227static void mmc_pinmux_setup(int sdc);
228#endif
229
230
231int board_init(void)
232{
233 __maybe_unused int id_pfr1, ret, satapwr_pin, macpwr_pin;
234
235 gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
236
237#if !defined(CONFIG_ARM64) && !defined(CONFIG_MACH_SUNIV)
238 asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1));
239 debug("id_pfr1: 0x%08x\n", id_pfr1);
240
241 if ((id_pfr1 >> CPUID_ARM_GENTIMER_SHIFT) & 0xf) {
242 uint32_t freq;
243
244 debug("Setting CNTFRQ\n");
245
246
247
248
249
250
251
252 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(freq));
253 if (freq != COUNTER_FREQUENCY) {
254 debug("arch timer frequency is %d Hz, should be %d, fixing ...\n",
255 freq, COUNTER_FREQUENCY);
256#ifdef CONFIG_NON_SECURE
257 printf("arch timer frequency is wrong, but cannot adjust it\n");
258#else
259 asm volatile("mcr p15, 0, %0, c14, c0, 0"
260 : : "r"(COUNTER_FREQUENCY));
261#endif
262 }
263 }
264#endif
265
266 ret = axp_gpio_init();
267 if (ret)
268 return ret;
269
270
271 if (CONFIG_SATAPWR[0]) {
272 satapwr_pin = sunxi_name_to_gpio(CONFIG_SATAPWR);
273 if (satapwr_pin >= 0) {
274 gpio_request(satapwr_pin, "satapwr");
275 gpio_direction_output(satapwr_pin, 1);
276
277
278
279
280
281 mdelay(500);
282 }
283 }
284
285 if (CONFIG_MACPWR[0]) {
286 macpwr_pin = sunxi_name_to_gpio(CONFIG_MACPWR);
287 if (macpwr_pin >= 0) {
288 gpio_request(macpwr_pin, "macpwr");
289 gpio_direction_output(macpwr_pin, 1);
290 }
291 }
292
293#if CONFIG_IS_ENABLED(DM_I2C)
294
295
296
297
298 i2c_init_board();
299#endif
300
301#ifdef CONFIG_DM_MMC
302
303
304
305
306 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
307#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
308 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
309#endif
310#endif
311
312 eth_init_board();
313
314 return 0;
315}
316
317
318
319
320
321#define INVALID_SPL_HEADER ((void *)~0UL)
322
323static struct boot_file_head * get_spl_header(uint8_t req_version)
324{
325 struct boot_file_head *spl = (void *)(ulong)SPL_ADDR;
326 uint8_t spl_header_version = spl->spl_signature[3];
327
328
329 if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0)
330 return INVALID_SPL_HEADER;
331
332 if (spl_header_version < req_version) {
333 printf("sunxi SPL version mismatch: expected %u, got %u\n",
334 req_version, spl_header_version);
335 return INVALID_SPL_HEADER;
336 }
337
338 return spl;
339}
340
341static const char *get_spl_dt_name(void)
342{
343 struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
344
345
346 if (spl != INVALID_SPL_HEADER && spl->dt_name_offset)
347 return (char *)spl + spl->dt_name_offset;
348
349 return NULL;
350}
351
352int dram_init(void)
353{
354 struct boot_file_head *spl = get_spl_header(SPL_DRAM_HEADER_VERSION);
355
356 if (spl == INVALID_SPL_HEADER)
357 gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0,
358 PHYS_SDRAM_0_SIZE);
359 else
360 gd->ram_size = (phys_addr_t)spl->dram_size << 20;
361
362 if (gd->ram_size > CONFIG_SUNXI_DRAM_MAX_SIZE)
363 gd->ram_size = CONFIG_SUNXI_DRAM_MAX_SIZE;
364
365 return 0;
366}
367
368#if defined(CONFIG_NAND_SUNXI)
369static void nand_pinmux_setup(void)
370{
371 unsigned int pin;
372
373 for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++)
374 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
375
376#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I
377 for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++)
378 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
379#endif
380
381
382#ifdef CONFIG_MACH_SUN7I
383 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND);
384#endif
385}
386
387static void nand_clock_setup(void)
388{
389 struct sunxi_ccm_reg *const ccm =
390 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
391
392 setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
393#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I || \
394 defined CONFIG_MACH_SUN9I || defined CONFIG_MACH_SUN50I
395 setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_GATE_OFFSET_NAND0));
396#endif
397 setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
398}
399
400void board_nand_init(void)
401{
402 nand_pinmux_setup();
403 nand_clock_setup();
404#ifndef CONFIG_SPL_BUILD
405 sunxi_nand_init();
406#endif
407}
408#endif
409
410#ifdef CONFIG_MMC
411static void mmc_pinmux_setup(int sdc)
412{
413 unsigned int pin;
414
415 switch (sdc) {
416 case 0:
417
418 for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) {
419 sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0);
420 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
421 sunxi_gpio_set_drv(pin, 2);
422 }
423 break;
424
425 case 1:
426#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \
427 defined(CONFIG_MACH_SUN8I_R40)
428 if (IS_ENABLED(CONFIG_MMC1_PINS_PH)) {
429
430 for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) {
431 sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1);
432 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
433 sunxi_gpio_set_drv(pin, 2);
434 }
435 } else {
436
437 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
438 sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1);
439 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
440 sunxi_gpio_set_drv(pin, 2);
441 }
442 }
443#elif defined(CONFIG_MACH_SUN5I)
444
445 for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) {
446 sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1);
447 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
448 sunxi_gpio_set_drv(pin, 2);
449 }
450#elif defined(CONFIG_MACH_SUN6I)
451
452 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
453 sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1);
454 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
455 sunxi_gpio_set_drv(pin, 2);
456 }
457#elif defined(CONFIG_MACH_SUN8I)
458
459 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
460 sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1);
461 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
462 sunxi_gpio_set_drv(pin, 2);
463 }
464#endif
465 break;
466
467 case 2:
468#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
469
470 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) {
471 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
472 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
473 sunxi_gpio_set_drv(pin, 2);
474 }
475#elif defined(CONFIG_MACH_SUN5I)
476
477 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
478 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
479 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
480 sunxi_gpio_set_drv(pin, 2);
481 }
482#elif defined(CONFIG_MACH_SUN6I)
483
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#elif defined(CONFIG_MACH_SUN8I_R40)
494
495 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
496 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
497 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
498 sunxi_gpio_set_drv(pin, 2);
499 }
500
501 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
502 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
503 sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
504#elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I)
505
506 for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) {
507 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
508 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
509 sunxi_gpio_set_drv(pin, 2);
510 }
511
512 for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); pin++) {
513 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
514 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
515 sunxi_gpio_set_drv(pin, 2);
516 }
517#elif defined(CONFIG_MACH_SUN50I_H6)
518
519 for (pin = SUNXI_GPC(4); pin <= SUNXI_GPC(14); pin++) {
520 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
521 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
522 sunxi_gpio_set_drv(pin, 2);
523 }
524#elif defined(CONFIG_MACH_SUN50I_H616)
525
526 for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(16); pin++) {
527 if (pin > SUNXI_GPC(1) && pin < SUNXI_GPC(5))
528 continue;
529 if (pin == SUNXI_GPC(7) || pin == SUNXI_GPC(12))
530 continue;
531 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
532 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
533 sunxi_gpio_set_drv(pin, 3);
534 }
535#elif defined(CONFIG_MACH_SUN9I)
536
537 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(16); pin++) {
538 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
539 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
540 sunxi_gpio_set_drv(pin, 2);
541 }
542#else
543 puts("ERROR: No pinmux setup defined for MMC2!\n");
544#endif
545 break;
546
547 case 3:
548#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \
549 defined(CONFIG_MACH_SUN8I_R40)
550
551 for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) {
552 sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3);
553 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
554 sunxi_gpio_set_drv(pin, 2);
555 }
556#elif defined(CONFIG_MACH_SUN6I)
557
558 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
559 sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3);
560 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
561 sunxi_gpio_set_drv(pin, 2);
562 }
563
564 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3);
565 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
566 sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
567#endif
568 break;
569
570 default:
571 printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc);
572 break;
573 }
574}
575
576int board_mmc_init(struct bd_info *bis)
577{
578 __maybe_unused struct mmc *mmc0, *mmc1;
579
580 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
581 mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
582 if (!mmc0)
583 return -1;
584
585#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
586 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
587 mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
588 if (!mmc1)
589 return -1;
590#endif
591
592 return 0;
593}
594
595#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
596int mmc_get_env_dev(void)
597{
598 switch (sunxi_get_boot_device()) {
599 case BOOT_DEVICE_MMC1:
600 return 0;
601 case BOOT_DEVICE_MMC2:
602 return 1;
603 default:
604 return CONFIG_SYS_MMC_ENV_DEV;
605 }
606}
607#endif
608#endif
609
610#ifdef CONFIG_SPL_BUILD
611
612static void sunxi_spl_store_dram_size(phys_addr_t dram_size)
613{
614 struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
615
616 if (spl == INVALID_SPL_HEADER)
617 return;
618
619
620 if (spl->spl_signature[3] < SPL_DRAM_HEADER_VERSION)
621 spl->spl_signature[3] = SPL_DRAM_HEADER_VERSION;
622
623 spl->dram_size = dram_size >> 20;
624}
625
626void sunxi_board_init(void)
627{
628 int power_failed = 0;
629
630#ifdef CONFIG_LED_STATUS
631 if (IS_ENABLED(CONFIG_SPL_DRIVERS_MISC))
632 status_led_init();
633#endif
634
635#ifdef CONFIG_SY8106A_POWER
636 power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT);
637#endif
638
639#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \
640 defined CONFIG_AXP221_POWER || defined CONFIG_AXP305_POWER || \
641 defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
642 power_failed = axp_init();
643
644 if (IS_ENABLED(CONFIG_AXP_DISABLE_BOOT_ON_POWERON) && !power_failed) {
645 u8 boot_reason;
646
647 pmic_bus_read(AXP_POWER_STATUS, &boot_reason);
648 if (boot_reason & AXP_POWER_STATUS_ALDO_IN) {
649 printf("Power on by plug-in, shutting down.\n");
650 pmic_bus_write(0x32, BIT(7));
651 }
652 }
653
654#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
655 defined CONFIG_AXP818_POWER
656 power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT);
657#endif
658#if !defined(CONFIG_AXP305_POWER)
659 power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT);
660 power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT);
661#endif
662#if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER)
663 power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT);
664#endif
665#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
666 defined CONFIG_AXP818_POWER
667 power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT);
668#endif
669
670#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
671 defined CONFIG_AXP818_POWER
672 power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT);
673#endif
674#if !defined(CONFIG_AXP305_POWER)
675 power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT);
676#endif
677#if !defined(CONFIG_AXP152_POWER) && !defined(CONFIG_AXP305_POWER)
678 power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT);
679#endif
680#ifdef CONFIG_AXP209_POWER
681 power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT);
682#endif
683
684#if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP809_POWER) || \
685 defined(CONFIG_AXP818_POWER)
686 power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT);
687 power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT);
688#if !defined CONFIG_AXP809_POWER
689 power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT);
690 power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT);
691#endif
692 power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT);
693 power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT);
694 power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT);
695#endif
696
697#ifdef CONFIG_AXP818_POWER
698 power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT);
699 power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT);
700 power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT);
701#endif
702
703#if defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
704 power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON));
705#endif
706#endif
707 printf("DRAM:");
708 gd->ram_size = sunxi_dram_init();
709 printf(" %d MiB\n", (int)(gd->ram_size >> 20));
710 if (!gd->ram_size)
711 hang();
712
713 sunxi_spl_store_dram_size(gd->ram_size);
714
715
716
717
718
719 if (!power_failed)
720 clock_set_pll1(get_board_sys_clk());
721 else
722 printf("Failed to set core voltage! Can't set CPU frequency\n");
723}
724#endif
725
726#ifdef CONFIG_USB_GADGET
727int g_dnl_board_usb_cable_connected(void)
728{
729 struct udevice *dev;
730 struct phy phy;
731 int ret;
732
733 ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
734 if (ret) {
735 pr_err("%s: Cannot find USB device\n", __func__);
736 return ret;
737 }
738
739 ret = generic_phy_get_by_name(dev, "usb", &phy);
740 if (ret) {
741 pr_err("failed to get %s USB PHY\n", dev->name);
742 return ret;
743 }
744
745 ret = generic_phy_init(&phy);
746 if (ret) {
747 pr_debug("failed to init %s USB PHY\n", dev->name);
748 return ret;
749 }
750
751 return sun4i_usb_phy_vbus_detect(&phy);
752}
753#endif
754
755#ifdef CONFIG_SERIAL_TAG
756void get_board_serial(struct tag_serialnr *serialnr)
757{
758 char *serial_string;
759 unsigned long long serial;
760
761 serial_string = env_get("serial#");
762
763 if (serial_string) {
764 serial = simple_strtoull(serial_string, NULL, 16);
765
766 serialnr->high = (unsigned int) (serial >> 32);
767 serialnr->low = (unsigned int) (serial & 0xffffffff);
768 } else {
769 serialnr->high = 0;
770 serialnr->low = 0;
771 }
772}
773#endif
774
775
776
777
778
779
780static void parse_spl_header(const uint32_t spl_addr)
781{
782 struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION);
783
784 if (spl == INVALID_SPL_HEADER)
785 return;
786
787 if (!spl->fel_script_address)
788 return;
789
790 if (spl->fel_uEnv_length != 0) {
791
792
793
794
795 himport_r(&env_htab, (char *)(uintptr_t)spl->fel_script_address,
796 spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL);
797 return;
798 }
799
800 env_set_hex("fel_scriptaddr", spl->fel_script_address);
801}
802
803static bool get_unique_sid(unsigned int *sid)
804{
805 if (sunxi_get_sid(sid) != 0)
806 return false;
807
808 if (!sid[0])
809 return false;
810
811
812
813
814
815
816
817
818
819
820
821
822#if !defined(CONFIG_MACH_SUN4I) && !defined(CONFIG_MACH_SUN5I) && \
823 !defined(CONFIG_MACH_SUN6I) && !defined(CONFIG_MACH_SUN7I) && \
824 !defined(CONFIG_MACH_SUN8I_A23) && !defined(CONFIG_MACH_SUN8I_A33)
825 sid[3] = crc32(0, (unsigned char *)&sid[1], 12);
826#endif
827
828
829 if ((sid[3] & 0xffffff) == 0)
830 sid[3] |= 0x800000;
831
832 return true;
833}
834
835
836
837
838
839static void setup_environment(const void *fdt)
840{
841 char serial_string[17] = { 0 };
842 unsigned int sid[4];
843 uint8_t mac_addr[6];
844 char ethaddr[16];
845 int i;
846
847 if (!get_unique_sid(sid))
848 return;
849
850 for (i = 0; i < 4; i++) {
851 sprintf(ethaddr, "ethernet%d", i);
852 if (!fdt_get_alias(fdt, ethaddr))
853 continue;
854
855 if (i == 0)
856 strcpy(ethaddr, "ethaddr");
857 else
858 sprintf(ethaddr, "eth%daddr", i);
859
860 if (env_get(ethaddr))
861 continue;
862
863
864 mac_addr[0] = (i << 4) | 0x02;
865 mac_addr[1] = (sid[0] >> 0) & 0xff;
866 mac_addr[2] = (sid[3] >> 24) & 0xff;
867 mac_addr[3] = (sid[3] >> 16) & 0xff;
868 mac_addr[4] = (sid[3] >> 8) & 0xff;
869 mac_addr[5] = (sid[3] >> 0) & 0xff;
870
871 eth_env_set_enetaddr(ethaddr, mac_addr);
872 }
873
874 if (!env_get("serial#")) {
875 snprintf(serial_string, sizeof(serial_string),
876 "%08x%08x", sid[0], sid[3]);
877
878 env_set("serial#", serial_string);
879 }
880}
881
882int misc_init_r(void)
883{
884 const char *spl_dt_name;
885 uint boot;
886
887 env_set("fel_booted", NULL);
888 env_set("fel_scriptaddr", NULL);
889 env_set("mmc_bootdev", NULL);
890
891 boot = sunxi_get_boot_device();
892
893 if (boot == BOOT_DEVICE_BOARD) {
894 env_set("fel_booted", "1");
895 parse_spl_header(SPL_ADDR);
896
897 } else if (boot == BOOT_DEVICE_MMC1) {
898 env_set("mmc_bootdev", "0");
899 } else if (boot == BOOT_DEVICE_MMC2) {
900 env_set("mmc_bootdev", "1");
901 }
902
903
904 spl_dt_name = get_spl_dt_name();
905 if (spl_dt_name) {
906 char *prefix = IS_ENABLED(CONFIG_ARM64) ? "allwinner/" : "";
907 char str[64];
908
909 snprintf(str, sizeof(str), "%s%s.dtb", prefix, spl_dt_name);
910 env_set("fdtfile", str);
911 }
912
913 setup_environment(gd->fdt_blob);
914
915 return 0;
916}
917
918int board_late_init(void)
919{
920#ifdef CONFIG_USB_ETHER
921 usb_ether_init();
922#endif
923
924 return 0;
925}
926
927static void bluetooth_dt_fixup(void *blob)
928{
929
930
931
932 uchar tmp[ETH_ALEN], bdaddr[ETH_ALEN];
933 unsigned int sid[4];
934 int i;
935
936 if (!CONFIG_BLUETOOTH_DT_DEVICE_FIXUP[0])
937 return;
938
939 if (eth_env_get_enetaddr("bdaddr", tmp)) {
940
941 for (i = 0; i < ETH_ALEN; ++i)
942 bdaddr[i] = tmp[ETH_ALEN - i - 1];
943 } else {
944 if (!get_unique_sid(sid))
945 return;
946
947 bdaddr[0] = ((sid[3] >> 0) & 0xff) ^ 1;
948 bdaddr[1] = (sid[3] >> 8) & 0xff;
949 bdaddr[2] = (sid[3] >> 16) & 0xff;
950 bdaddr[3] = (sid[3] >> 24) & 0xff;
951 bdaddr[4] = (sid[0] >> 0) & 0xff;
952 bdaddr[5] = 0x02;
953 }
954
955 do_fixup_by_compat(blob, CONFIG_BLUETOOTH_DT_DEVICE_FIXUP,
956 "local-bd-address", bdaddr, ETH_ALEN, 1);
957}
958
959int ft_board_setup(void *blob, struct bd_info *bd)
960{
961 int __maybe_unused r;
962
963
964
965
966
967
968 setup_environment(blob);
969 fdt_fixup_ethernet(blob);
970
971 bluetooth_dt_fixup(blob);
972
973#ifdef CONFIG_VIDEO_DT_SIMPLEFB
974 r = sunxi_simplefb_setup(blob);
975 if (r)
976 return r;
977#endif
978 return 0;
979}
980
981#ifdef CONFIG_SPL_LOAD_FIT
982
983static void set_spl_dt_name(const char *name)
984{
985 struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION);
986
987 if (spl == INVALID_SPL_HEADER)
988 return;
989
990
991 if (spl->spl_signature[3] < SPL_DT_HEADER_VERSION)
992 spl->spl_signature[3] = SPL_DT_HEADER_VERSION;
993
994 strcpy((char *)&spl->string_pool, name);
995 spl->dt_name_offset = offsetof(struct boot_file_head, string_pool);
996}
997
998int board_fit_config_name_match(const char *name)
999{
1000 const char *best_dt_name = get_spl_dt_name();
1001 int ret;
1002
1003#ifdef CONFIG_DEFAULT_DEVICE_TREE
1004 if (best_dt_name == NULL)
1005 best_dt_name = CONFIG_DEFAULT_DEVICE_TREE;
1006#endif
1007
1008 if (best_dt_name == NULL) {
1009
1010 return 0;
1011 }
1012#ifdef CONFIG_PINE64_DT_SELECTION
1013 if (strstr(best_dt_name, "-pine64-plus")) {
1014
1015 if ((gd->ram_size == 512 * 1024 * 1024))
1016 best_dt_name = "sun50i-a64-pine64";
1017 }
1018#endif
1019#ifdef CONFIG_PINEPHONE_DT_SELECTION
1020 if (strstr(best_dt_name, "-pinephone")) {
1021
1022 prcm_apb0_enable(PRCM_APB0_GATE_PIO);
1023 sunxi_gpio_set_pull(SUNXI_GPL(6), SUNXI_GPIO_PULL_UP);
1024 sunxi_gpio_set_cfgpin(SUNXI_GPL(6), SUNXI_GPIO_INPUT);
1025 udelay(100);
1026
1027
1028 if (gpio_get_value(SUNXI_GPL(6)) == 0)
1029 best_dt_name = "sun50i-a64-pinephone-1.2";
1030 else
1031 best_dt_name = "sun50i-a64-pinephone-1.1";
1032
1033 sunxi_gpio_set_cfgpin(SUNXI_GPL(6), SUNXI_GPIO_DISABLE);
1034 sunxi_gpio_set_pull(SUNXI_GPL(6), SUNXI_GPIO_PULL_DISABLE);
1035 prcm_apb0_disable(PRCM_APB0_GATE_PIO);
1036 }
1037#endif
1038
1039 ret = strcmp(name, best_dt_name);
1040
1041
1042
1043
1044
1045 if (ret == 0)
1046 set_spl_dt_name(best_dt_name);
1047
1048 return ret;
1049}
1050#endif
1051