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 <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 <linux/printk.h> 37#include <linux/types.h> 38#ifndef CONFIG_ARM64 39#include <asm/armv7.h> 40#endif 41#include <asm/gpio.h> 42#include <sunxi_gpio.h> 43#include <asm/io.h> 44#include <u-boot/crc.h> 45#include <env_internal.h> 46#include <linux/libfdt.h> 47#include <fdt_support.h> 48#include <nand.h> 49#include <net.h> 50#include <spl.h> 51#include <sy8106a.h> 52#include <asm/setup.h> 53#include <status_led.h> 54 55DECLARE_GLOBAL_DATA_PTR; 56 57void i2c_init_board(void) 58{ 59#ifdef CONFIG_I2C0_ENABLE 60#if defined(CONFIG_MACH_SUN4I) || \ 61 defined(CONFIG_MACH_SUN5I) || \ 62 defined(CONFIG_MACH_SUN7I) || \ 63 defined(CONFIG_MACH_SUN8I_R40) 64 sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0); 65 sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0); 66 clock_twi_onoff(0, 1); 67#elif defined(CONFIG_MACH_SUN6I) 68 sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0); 69 sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0); 70 clock_twi_onoff(0, 1); 71#elif defined(CONFIG_MACH_SUN8I_V3S) 72 sunxi_gpio_set_cfgpin(SUNXI_GPB(6), SUN8I_V3S_GPB_TWI0); 73 sunxi_gpio_set_cfgpin(SUNXI_GPB(7), SUN8I_V3S_GPB_TWI0); 74 clock_twi_onoff(0, 1); 75#elif defined(CONFIG_MACH_SUN8I) 76 sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0); 77 sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0); 78 clock_twi_onoff(0, 1); 79#elif defined(CONFIG_MACH_SUN50I) 80 sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_GPH_TWI0); 81 sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_GPH_TWI0); 82 clock_twi_onoff(0, 1); 83#endif 84#endif 85 86#ifdef CONFIG_I2C1_ENABLE 87#if defined(CONFIG_MACH_SUN4I) || \ 88 defined(CONFIG_MACH_SUN7I) || \ 89 defined(CONFIG_MACH_SUN8I_R40) 90 sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1); 91 sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1); 92 clock_twi_onoff(1, 1); 93#elif defined(CONFIG_MACH_SUN5I) 94 sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1); 95 sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1); 96 clock_twi_onoff(1, 1); 97#elif defined(CONFIG_MACH_SUN6I) 98 sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1); 99 sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1); 100 clock_twi_onoff(1, 1); 101#elif defined(CONFIG_MACH_SUN8I) 102 sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1); 103 sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1); 104 clock_twi_onoff(1, 1); 105#elif defined(CONFIG_MACH_SUN50I) 106 sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN50I_GPH_TWI1); 107 sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1); 108 clock_twi_onoff(1, 1); 109#endif 110#endif 111 112#ifdef CONFIG_R_I2C_ENABLE 113#ifdef CONFIG_MACH_SUN50I 114 clock_twi_onoff(5, 1); 115 sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI); 116 sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI); 117#elif CONFIG_MACH_SUN50I_H616 118 clock_twi_onoff(5, 1); 119 sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_H616_GPL_R_TWI); 120 sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_H616_GPL_R_TWI); 121#else 122 clock_twi_onoff(5, 1); 123 sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI); 124 sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI); 125#endif 126#endif 127} 128 129/* 130 * Try to use the environment from the boot source first. 131 * For MMC, this means a FAT partition on the boot device (SD or eMMC). 132 * If the raw MMC environment is also enabled, this is tried next. 133 * When booting from NAND we try UBI first, then NAND directly. 134 * SPI flash falls back to FAT (on SD card). 135 */ 136enum env_location env_get_location(enum env_operation op, int prio) 137{ 138 if (prio > 1) 139 return ENVL_UNKNOWN; 140 141 /* NOWHERE is exclusive, no other option can be defined. */ 142 if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE)) 143 return ENVL_NOWHERE; 144 145 switch (sunxi_get_boot_device()) { 146 case BOOT_DEVICE_MMC1: 147 case BOOT_DEVICE_MMC2: 148 if (prio == 0 && IS_ENABLED(CONFIG_ENV_IS_IN_FAT)) 149 return ENVL_FAT; 150 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC)) 151 return ENVL_MMC; 152 break; 153 case BOOT_DEVICE_NAND: 154 if (prio == 0 && IS_ENABLED(CONFIG_ENV_IS_IN_UBI)) 155 return ENVL_UBI; 156 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND)) 157 return ENVL_NAND; 158 break; 159 case BOOT_DEVICE_SPI: 160 if (prio == 0 && IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) 161 return ENVL_SPI_FLASH; 162 if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT)) 163 return ENVL_FAT; 164 break; 165 case BOOT_DEVICE_BOARD: 166 break; 167 default: 168 break; 169 } 170 171 /* 172 * If we come here for the first time, we *must* return a valid 173 * environment location other than ENVL_UNKNOWN, or the setup sequence 174 * in board_f() will silently hang. This is arguably a bug in 175 * env_init(), but for now pick one environment for which we know for 176 * sure to have a driver for. For all defconfigs this is either FAT 177 * or UBI, or NOWHERE, which is already handled above. 178 */ 179 if (prio == 0) { 180 if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT)) 181 return ENVL_FAT; 182 if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI)) 183 return ENVL_UBI; 184 } 185 186 return ENVL_UNKNOWN; 187} 188 189/* called only from U-Boot proper */ 190int board_init(void) 191{ 192 __maybe_unused int id_pfr1, ret; 193 194 gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100); 195 196#if !defined(CONFIG_ARM64) && !defined(CONFIG_MACH_SUNIV) 197 asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1)); 198 debug("id_pfr1: 0x%08x\n", id_pfr1); 199 /* Generic Timer Extension available? */ 200 if ((id_pfr1 >> CPUID_ARM_GENTIMER_SHIFT) & 0xf) { 201 uint32_t freq; 202 203 debug("Setting CNTFRQ\n"); 204 205 /* 206 * CNTFRQ is a secure register, so we will crash if we try to 207 * write this from the non-secure world (read is OK, though). 208 * In case some bootcode has already set the correct value, 209 * we avoid the risk of writing to it. 210 */ 211 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(freq)); 212 if (freq != CONFIG_COUNTER_FREQUENCY) { 213 debug("arch timer frequency is %d Hz, should be %d, fixing ...\n", 214 freq, CONFIG_COUNTER_FREQUENCY); 215#ifdef CONFIG_NON_SECURE 216 printf("arch timer frequency is wrong, but cannot adjust it\n"); 217#else 218 asm volatile("mcr p15, 0, %0, c14, c0, 0" 219 : : "r"(CONFIG_COUNTER_FREQUENCY)); 220#endif 221 } 222 } 223#endif /* !CONFIG_ARM64 && !CONFIG_MACH_SUNIV */ 224 225 ret = axp_gpio_init(); 226 if (ret) 227 return ret; 228 229 eth_init_board(); 230 231 return 0; 232} 233 234/* 235 * On older SoCs the SPL is actually at address zero, so using NULL as 236 * an error value does not work. 237 */ 238#define INVALID_SPL_HEADER ((void *)~0UL) 239 240static struct boot_file_head * get_spl_header(uint8_t req_version) 241{ 242 struct boot_file_head *spl = (void *)(ulong)SPL_ADDR; 243 uint8_t spl_header_version = spl->spl_signature[3]; 244 245 /* Is there really the SPL header (still) there? */ 246 if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0) 247 return INVALID_SPL_HEADER; 248 249 if (spl_header_version < req_version) { 250 printf("sunxi SPL version mismatch: expected %u, got %u\n", 251 req_version, spl_header_version); 252 return INVALID_SPL_HEADER; 253 } 254 255 return spl; 256} 257 258static const char *get_spl_dt_name(void) 259{ 260 struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION); 261 262 /* Check if there is a DT name stored in the SPL header. */ 263 if (spl != INVALID_SPL_HEADER && spl->dt_name_offset) 264 return (char *)spl + spl->dt_name_offset; 265 266 return NULL; 267} 268 269int dram_init(void) 270{ 271 struct boot_file_head *spl = get_spl_header(SPL_DRAM_HEADER_VERSION); 272 273 if (spl == INVALID_SPL_HEADER) 274 gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, 275 PHYS_SDRAM_0_SIZE); 276 else 277 gd->ram_size = (phys_addr_t)spl->dram_size << 20; 278 279 if (gd->ram_size > CONFIG_SUNXI_DRAM_MAX_SIZE) 280 gd->ram_size = CONFIG_SUNXI_DRAM_MAX_SIZE; 281 282 return 0; 283} 284 285#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) 286static void nand_pinmux_setup(void) 287{ 288 unsigned int pin; 289 290 for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++) 291 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND); 292 293#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I 294 for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++) 295 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND); 296#endif 297 /* sun4i / sun7i do have a PC23, but it is not used for nand, 298 * only sun7i has a PC24 */ 299#ifdef CONFIG_MACH_SUN7I 300 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND); 301#endif 302} 303 304static void nand_clock_setup(void) 305{ 306 struct sunxi_ccm_reg *const ccm = 307 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 308 309 setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0)); 310#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I || \ 311 defined CONFIG_MACH_SUN9I || defined CONFIG_MACH_SUN50I 312 setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_GATE_OFFSET_NAND0)); 313#endif 314 setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1); 315} 316 317void board_nand_init(void) 318{ 319 nand_pinmux_setup(); 320 nand_clock_setup(); 321} 322#endif /* CONFIG_NAND_SUNXI */ 323 324#ifdef CONFIG_MMC 325static void mmc_pinmux_setup(int sdc) 326{ 327 unsigned int pin; 328 329 switch (sdc) { 330 case 0: 331 /* SDC0: PF0-PF5 */ 332 for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) { 333 sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0); 334 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 335 sunxi_gpio_set_drv(pin, 2); 336 } 337 break; 338 339 case 1: 340#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \ 341 defined(CONFIG_MACH_SUN8I_R40) 342 if (IS_ENABLED(CONFIG_MMC1_PINS_PH)) { 343 /* SDC1: PH22-PH-27 */ 344 for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) { 345 sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1); 346 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 347 sunxi_gpio_set_drv(pin, 2); 348 } 349 } else { 350 /* SDC1: PG0-PG5 */ 351 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 352 sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1); 353 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 354 sunxi_gpio_set_drv(pin, 2); 355 } 356 } 357#elif defined(CONFIG_MACH_SUN5I) 358 /* SDC1: PG3-PG8 */ 359 for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) { 360 sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1); 361 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 362 sunxi_gpio_set_drv(pin, 2); 363 } 364#elif defined(CONFIG_MACH_SUN6I) 365 /* SDC1: PG0-PG5 */ 366 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 367 sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1); 368 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 369 sunxi_gpio_set_drv(pin, 2); 370 } 371#elif defined(CONFIG_MACH_SUN8I) 372 /* SDC1: PG0-PG5 */ 373 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 374 sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1); 375 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 376 sunxi_gpio_set_drv(pin, 2); 377 } 378#endif 379 break; 380 381 case 2: 382#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 383 /* SDC2: PC6-PC11 */ 384 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) { 385 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 386 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 387 sunxi_gpio_set_drv(pin, 2); 388 } 389#elif defined(CONFIG_MACH_SUN5I) 390 /* SDC2: PC6-PC15 */ 391 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 392 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 393 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 394 sunxi_gpio_set_drv(pin, 2); 395 } 396#elif defined(CONFIG_MACH_SUN6I) 397 /* SDC2: PC6-PC15, PC24 */ 398 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 399 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 400 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 401 sunxi_gpio_set_drv(pin, 2); 402 } 403 404 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2); 405 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); 406 sunxi_gpio_set_drv(SUNXI_GPC(24), 2); 407#elif defined(CONFIG_MACH_SUN8I_R40) 408 /* SDC2: PC6-PC15, PC24 */ 409 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 410 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 411 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 412 sunxi_gpio_set_drv(pin, 2); 413 } 414 415 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2); 416 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); 417 sunxi_gpio_set_drv(SUNXI_GPC(24), 2); 418#elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I) 419 /* SDC2: PC5-PC6, PC8-PC16 */ 420 for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) { 421 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 422 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 423 sunxi_gpio_set_drv(pin, 2); 424 } 425 426 for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); pin++) { 427 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 428 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 429 sunxi_gpio_set_drv(pin, 2); 430 } 431#elif defined(CONFIG_MACH_SUN50I_H6) 432 /* SDC2: PC4-PC14 */ 433 for (pin = SUNXI_GPC(4); pin <= SUNXI_GPC(14); pin++) { 434 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 435 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 436 sunxi_gpio_set_drv(pin, 2); 437 } 438#elif defined(CONFIG_MACH_SUN50I_H616) 439 /* SDC2: PC0-PC1, PC5-PC6, PC8-PC11, PC13-PC16 */ 440 for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(16); pin++) { 441 if (pin > SUNXI_GPC(1) && pin < SUNXI_GPC(5)) 442 continue; 443 if (pin == SUNXI_GPC(7) || pin == SUNXI_GPC(12)) 444 continue; 445 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 446 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 447 sunxi_gpio_set_drv(pin, 3); 448 } 449#elif defined(CONFIG_MACH_SUN9I) 450 /* SDC2: PC6-PC16 */ 451 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(16); pin++) { 452 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 453 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 454 sunxi_gpio_set_drv(pin, 2); 455 } 456#elif defined(CONFIG_MACH_SUN8I_R528) 457 /* SDC2: PC2-PC7 */ 458 for (pin = SUNXI_GPC(2); pin <= SUNXI_GPC(7); pin++) { 459 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 460 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 461 sunxi_gpio_set_drv(pin, 2); 462 } 463#else 464 puts("ERROR: No pinmux setup defined for MMC2!\n"); 465#endif 466 break; 467 468 case 3: 469#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \ 470 defined(CONFIG_MACH_SUN8I_R40) 471 /* SDC3: PI4-PI9 */ 472 for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { 473 sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3); 474 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 475 sunxi_gpio_set_drv(pin, 2); 476 } 477#elif defined(CONFIG_MACH_SUN6I) 478 /* SDC3: PC6-PC15, PC24 */ 479 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 480 sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3); 481 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 482 sunxi_gpio_set_drv(pin, 2); 483 } 484 485 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3); 486 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); 487 sunxi_gpio_set_drv(SUNXI_GPC(24), 2); 488#endif 489 break; 490 491 default: 492 printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc); 493 break; 494 } 495} 496 497int board_mmc_init(struct bd_info *bis) 498{ 499 /* 500 * The BROM always accesses MMC port 0 (typically an SD card), and 501 * most boards seem to have such a slot. The others haven't reported 502 * any problem with unconditionally enabling this in the SPL. 503 */ 504 if (!IS_ENABLED(CONFIG_UART0_PORT_F)) { 505 mmc_pinmux_setup(0); 506 if (!sunxi_mmc_init(0)) 507 return -1; 508 } 509 510 if (CONFIG_MMC_SUNXI_SLOT_EXTRA != -1) { 511 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA); 512 if (!sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA)) 513 return -1; 514 } 515 516 return 0; 517} 518 519#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1 520int mmc_get_env_dev(void) 521{ 522 switch (sunxi_get_boot_device()) { 523 case BOOT_DEVICE_MMC1: 524 return 0; 525 case BOOT_DEVICE_MMC2: 526 return 1; 527 default: 528 return CONFIG_SYS_MMC_ENV_DEV; 529 } 530} 531#endif 532#endif /* CONFIG_MMC */ 533 534#ifdef CONFIG_SPL_BUILD 535 536static void sunxi_spl_store_dram_size(phys_addr_t dram_size) 537{ 538 struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION); 539 540 if (spl == INVALID_SPL_HEADER) 541 return; 542 543 /* Promote the header version for U-Boot proper, if needed. */ 544 if (spl->spl_signature[3] < SPL_DRAM_HEADER_VERSION) 545 spl->spl_signature[3] = SPL_DRAM_HEADER_VERSION; 546 547 spl->dram_size = dram_size >> 20; 548} 549 550void sunxi_board_init(void) 551{ 552 int power_failed = 0; 553 554#ifdef CONFIG_LED_STATUS 555 if (IS_ENABLED(CONFIG_SPL_DRIVERS_MISC)) 556 status_led_init(); 557#endif 558 559#ifdef CONFIG_SY8106A_POWER 560 power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT); 561#endif 562 563#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ 564 defined CONFIG_AXP221_POWER || defined CONFIG_AXP305_POWER || \ 565 defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER || \ 566 defined CONFIG_AXP313_POWER 567 power_failed = axp_init(); 568 569 if (IS_ENABLED(CONFIG_AXP_DISABLE_BOOT_ON_POWERON) && !power_failed) { 570 u8 boot_reason; 571 572 pmic_bus_read(AXP_POWER_STATUS, &boot_reason); 573 if (boot_reason & AXP_POWER_STATUS_ALDO_IN) { 574 printf("Power on by plug-in, shutting down.\n"); 575 pmic_bus_write(0x32, BIT(7)); 576 } 577 } 578 579#ifdef CONFIG_AXP_DCDC1_VOLT 580 power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT); 581 power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT); 582#endif 583#ifdef CONFIG_AXP_DCDC2_VOLT 584 power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT); 585 power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT); 586#endif 587#ifdef CONFIG_AXP_DCDC4_VOLT 588 power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT); 589#endif 590 591#ifdef CONFIG_AXP_ALDO1_VOLT 592 power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); 593#endif 594#ifdef CONFIG_AXP_ALDO2_VOLT 595 power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); 596#endif 597#ifdef CONFIG_AXP_ALDO3_VOLT 598 power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT); 599#endif 600#ifdef CONFIG_AXP_ALDO4_VOLT 601 power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT); 602#endif 603 604#ifdef CONFIG_AXP_DLDO1_VOLT 605 power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT); 606 power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT); 607#endif 608#ifdef CONFIG_AXP_DLDO3_VOLT 609 power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT); 610 power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT); 611#endif 612#ifdef CONFIG_AXP_ELDO1_VOLT 613 power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT); 614 power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT); 615 power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT); 616#endif 617 618#ifdef CONFIG_AXP_FLDO1_VOLT 619 power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT); 620 power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT); 621 power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT); 622#endif 623 624#if defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER 625 power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON)); 626#endif 627#endif /* CONFIG_AXPxxx_POWER */ 628 printf("DRAM:"); 629 gd->ram_size = sunxi_dram_init(); 630 printf(" %d MiB\n", (int)(gd->ram_size >> 20)); 631 if (!gd->ram_size) 632 hang(); 633 634 sunxi_spl_store_dram_size(gd->ram_size); 635 636 /* 637 * Only clock up the CPU to full speed if we are reasonably 638 * assured it's being powered with suitable core voltage 639 */ 640 if (!power_failed) 641 clock_set_pll1(get_board_sys_clk()); 642 else 643 printf("Failed to set core voltage! Can't set CPU frequency\n"); 644} 645#endif /* CONFIG_SPL_BUILD */ 646 647#ifdef CONFIG_USB_GADGET 648int g_dnl_board_usb_cable_connected(void) 649{ 650 struct udevice *dev; 651 struct phy phy; 652 int ret; 653 654 ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev); 655 if (ret) { 656 pr_err("%s: Cannot find USB device\n", __func__); 657 return ret; 658 } 659 660 ret = generic_phy_get_by_name(dev, "usb", &phy); 661 if (ret) { 662 pr_err("failed to get %s USB PHY\n", dev->name); 663 return ret; 664 } 665 666 ret = generic_phy_init(&phy); 667 if (ret) { 668 pr_debug("failed to init %s USB PHY\n", dev->name); 669 return ret; 670 } 671 672 return sun4i_usb_phy_vbus_detect(&phy); 673} 674#endif /* CONFIG_USB_GADGET */ 675 676#ifdef CONFIG_SERIAL_TAG 677void get_board_serial(struct tag_serialnr *serialnr) 678{ 679 char *serial_string; 680 unsigned long long serial; 681 682 serial_string = env_get("serial#"); 683 684 if (serial_string) { 685 serial = simple_strtoull(serial_string, NULL, 16); 686 687 serialnr->high = (unsigned int) (serial >> 32); 688 serialnr->low = (unsigned int) (serial & 0xffffffff); 689 } else { 690 serialnr->high = 0; 691 serialnr->low = 0; 692 } 693} 694#endif 695 696/* 697 * Check the SPL header for the "sunxi" variant. If found: parse values 698 * that might have been passed by the loader ("fel" utility), and update 699 * the environment accordingly. 700 */ 701static void parse_spl_header(const uint32_t spl_addr) 702{ 703 struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION); 704 705 if (spl == INVALID_SPL_HEADER) 706 return; 707 708 if (!spl->fel_script_address) 709 return; 710 711 if (spl->fel_uEnv_length != 0) { 712 /* 713 * data is expected in uEnv.txt compatible format, so "env 714 * import -t" the string(s) at fel_script_address right away. 715 */ 716 himport_r(&env_htab, (char *)(uintptr_t)spl->fel_script_address, 717 spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL); 718 return; 719 } 720 /* otherwise assume .scr format (mkimage-type script) */ 721 env_set_hex("fel_scriptaddr", spl->fel_script_address); 722} 723 724static bool get_unique_sid(unsigned int *sid) 725{ 726 if (sunxi_get_sid(sid) != 0) 727 return false; 728 729 if (!sid[0]) 730 return false; 731 732 /* 733 * The single words 1 - 3 of the SID have quite a few bits 734 * which are the same on many models, so we take a crc32 735 * of all 3 words, to get a more unique value. 736 * 737 * Note we only do this on newer SoCs as we cannot change 738 * the algorithm on older SoCs since those have been using 739 * fixed mac-addresses based on only using word 3 for a 740 * long time and changing a fixed mac-address with an 741 * u-boot update is not good. 742 */ 743#if !defined(CONFIG_MACH_SUN4I) && !defined(CONFIG_MACH_SUN5I) && \ 744 !defined(CONFIG_MACH_SUN6I) && !defined(CONFIG_MACH_SUN7I) && \ 745 !defined(CONFIG_MACH_SUN8I_A23) && !defined(CONFIG_MACH_SUN8I_A33) 746 sid[3] = crc32(0, (unsigned char *)&sid[1], 12); 747#endif 748 749 /* Ensure the NIC specific bytes of the mac are not all 0 */ 750 if ((sid[3] & 0xffffff) == 0) 751 sid[3] |= 0x800000; 752 753 return true; 754} 755 756/* 757 * Note this function gets called multiple times. 758 * It must not make any changes to env variables which already exist. 759 */ 760static void setup_environment(const void *fdt) 761{ 762 char serial_string[17] = { 0 }; 763 unsigned int sid[4]; 764 uint8_t mac_addr[6]; 765 char ethaddr[16]; 766 int i; 767 768 if (!get_unique_sid(sid)) 769 return; 770 771 for (i = 0; i < 4; i++) { 772 sprintf(ethaddr, "ethernet%d", i); 773 if (!fdt_get_alias(fdt, ethaddr)) 774 continue; 775 776 if (i == 0) 777 strcpy(ethaddr, "ethaddr"); 778 else 779 sprintf(ethaddr, "eth%daddr", i); 780 781 if (env_get(ethaddr)) 782 continue; 783 784 /* Non OUI / registered MAC address */ 785 mac_addr[0] = (i << 4) | 0x02; 786 mac_addr[1] = (sid[0] >> 0) & 0xff; 787 mac_addr[2] = (sid[3] >> 24) & 0xff; 788 mac_addr[3] = (sid[3] >> 16) & 0xff; 789 mac_addr[4] = (sid[3] >> 8) & 0xff; 790 mac_addr[5] = (sid[3] >> 0) & 0xff; 791 792 eth_env_set_enetaddr(ethaddr, mac_addr); 793 } 794 795 if (!env_get("serial#")) { 796 snprintf(serial_string, sizeof(serial_string), 797 "%08x%08x", sid[0], sid[3]); 798 799 env_set("serial#", serial_string); 800 } 801} 802 803int misc_init_r(void) 804{ 805 const char *spl_dt_name; 806 uint boot; 807 808 env_set("fel_booted", NULL); 809 env_set("fel_scriptaddr", NULL); 810 env_set("mmc_bootdev", NULL); 811 812 boot = sunxi_get_boot_device(); 813 /* determine if we are running in FEL mode */ 814 if (boot == BOOT_DEVICE_BOARD) { 815 env_set("fel_booted", "1"); 816 parse_spl_header(SPL_ADDR); 817 /* or if we booted from MMC, and which one */ 818 } else if (boot == BOOT_DEVICE_MMC1) { 819 env_set("mmc_bootdev", "0"); 820 } else if (boot == BOOT_DEVICE_MMC2) { 821 env_set("mmc_bootdev", "1"); 822 } 823 824 /* Set fdtfile to match the FIT configuration chosen in SPL. */ 825 spl_dt_name = get_spl_dt_name(); 826 if (spl_dt_name) { 827 char *prefix = IS_ENABLED(CONFIG_ARM64) ? "allwinner/" : ""; 828 char str[64]; 829 830 snprintf(str, sizeof(str), "%s%s.dtb", prefix, spl_dt_name); 831 env_set("fdtfile", str); 832 } 833 834 setup_environment(gd->fdt_blob); 835 836 return 0; 837} 838 839int board_late_init(void) 840{ 841#ifdef CONFIG_USB_ETHER 842 usb_ether_init(); 843#endif 844 845 return 0; 846} 847 848static void bluetooth_dt_fixup(void *blob) 849{ 850 /* Some devices ship with a Bluetooth controller default address. 851 * Set a valid address through the device tree. 852 */ 853 uchar tmp[ETH_ALEN], bdaddr[ETH_ALEN]; 854 unsigned int sid[4]; 855 int i; 856 857 if (!CONFIG_BLUETOOTH_DT_DEVICE_FIXUP[0]) 858 return; 859 860 if (eth_env_get_enetaddr("bdaddr", tmp)) { 861 /* Convert between the binary formats of the corresponding stacks */ 862 for (i = 0; i < ETH_ALEN; ++i) 863 bdaddr[i] = tmp[ETH_ALEN - i - 1]; 864 } else { 865 if (!get_unique_sid(sid)) 866 return; 867 868 bdaddr[0] = ((sid[3] >> 0) & 0xff) ^ 1; 869 bdaddr[1] = (sid[3] >> 8) & 0xff; 870 bdaddr[2] = (sid[3] >> 16) & 0xff; 871 bdaddr[3] = (sid[3] >> 24) & 0xff; 872 bdaddr[4] = (sid[0] >> 0) & 0xff; 873 bdaddr[5] = 0x02; 874 } 875 876 do_fixup_by_compat(blob, CONFIG_BLUETOOTH_DT_DEVICE_FIXUP, 877 "local-bd-address", bdaddr, ETH_ALEN, 1); 878} 879 880int ft_board_setup(void *blob, struct bd_info *bd) 881{ 882 int __maybe_unused r; 883 884 /* 885 * Call setup_environment and fdt_fixup_ethernet again 886 * in case the boot fdt has ethernet aliases the u-boot 887 * copy does not have. 888 */ 889 setup_environment(blob); 890 fdt_fixup_ethernet(blob); 891 892 bluetooth_dt_fixup(blob); 893 894#ifdef CONFIG_VIDEO_DT_SIMPLEFB 895 r = sunxi_simplefb_setup(blob); 896 if (r) 897 return r; 898#endif 899 return 0; 900} 901 902#ifdef CONFIG_SPL_LOAD_FIT 903static void set_spl_dt_name(const char *name) 904{ 905 struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION); 906 907 if (spl == INVALID_SPL_HEADER) 908 return; 909 910 /* Promote the header version for U-Boot proper, if needed. */ 911 if (spl->spl_signature[3] < SPL_DT_HEADER_VERSION) 912 spl->spl_signature[3] = SPL_DT_HEADER_VERSION; 913 914 strcpy((char *)&spl->string_pool, name); 915 spl->dt_name_offset = offsetof(struct boot_file_head, string_pool); 916} 917 918int board_fit_config_name_match(const char *name) 919{ 920 const char *best_dt_name = get_spl_dt_name(); 921 int ret; 922 923#ifdef CONFIG_DEFAULT_DEVICE_TREE 924 if (best_dt_name == NULL) 925 best_dt_name = CONFIG_DEFAULT_DEVICE_TREE; 926#endif 927 928 if (best_dt_name == NULL) { 929 /* No DT name was provided, so accept the first config. */ 930 return 0; 931 } 932#ifdef CONFIG_PINE64_DT_SELECTION 933 if (strstr(best_dt_name, "-pine64-plus")) { 934 /* Differentiate the Pine A64 boards by their DRAM size. */ 935 if (gd->ram_size == SZ_512M) 936 best_dt_name = "sun50i-a64-pine64"; 937 } 938#endif 939#ifdef CONFIG_PINEPHONE_DT_SELECTION 940 if (strstr(best_dt_name, "-pinephone")) { 941 /* Differentiate the PinePhone revisions by GPIO inputs. */ 942 prcm_apb0_enable(PRCM_APB0_GATE_PIO); 943 sunxi_gpio_set_pull(SUNXI_GPL(6), SUNXI_GPIO_PULL_UP); 944 sunxi_gpio_set_cfgpin(SUNXI_GPL(6), SUNXI_GPIO_INPUT); 945 udelay(100); 946 947 /* PL6 is pulled low by the modem on v1.2. */ 948 if (gpio_get_value(SUNXI_GPL(6)) == 0) 949 best_dt_name = "sun50i-a64-pinephone-1.2"; 950 else 951 best_dt_name = "sun50i-a64-pinephone-1.1"; 952 953 sunxi_gpio_set_cfgpin(SUNXI_GPL(6), SUNXI_GPIO_DISABLE); 954 sunxi_gpio_set_pull(SUNXI_GPL(6), SUNXI_GPIO_PULL_DISABLE); 955 prcm_apb0_disable(PRCM_APB0_GATE_PIO); 956 } 957#endif 958 959 ret = strcmp(name, best_dt_name); 960 961 /* 962 * If one of the FIT configurations matches the most accurate DT name, 963 * update the SPL header to provide that DT name to U-Boot proper. 964 */ 965 if (ret == 0) 966 set_spl_dt_name(best_dt_name); 967 968 return ret; 969} 970#endif /* CONFIG_SPL_LOAD_FIT */ 971