1 /* 2 * (C) Copyright 2012-2013 Henrik Nordstrom <henrik@henriknordstrom.net> 3 * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net> 4 * 5 * (C) Copyright 2007-2011 6 * Allwinner Technology Co., Ltd. <www.allwinnertech.com> 7 * Tom Cubie <tangliang@allwinnertech.com> 8 * 9 * Some board init for the Allwinner A10-evb board. 10 * 11 * SPDX-License-Identifier: GPL-2.0+ 12 */ 13 14 #include <common.h> 15 #include <mmc.h> 16 #include <axp_pmic.h> 17 #include <asm/arch/clock.h> 18 #include <asm/arch/cpu.h> 19 #include <asm/arch/display.h> 20 #include <asm/arch/dram.h> 21 #include <asm/arch/gpio.h> 22 #include <asm/arch/mmc.h> 23 #include <asm/arch/usb_phy.h> 24 #ifndef CONFIG_ARM64 25 #include <asm/armv7.h> 26 #endif 27 #include <asm/gpio.h> 28 #include <asm/io.h> 29 #include <libfdt.h> 30 #include <nand.h> 31 #include <net.h> 32 #include <sy8106a.h> 33 34 #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) 35 /* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */ 36 int soft_i2c_gpio_sda; 37 int soft_i2c_gpio_scl; 38 39 static int soft_i2c_board_init(void) 40 { 41 int ret; 42 43 soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA); 44 if (soft_i2c_gpio_sda < 0) { 45 printf("Error invalid soft i2c sda pin: '%s', err %d\n", 46 CONFIG_VIDEO_LCD_PANEL_I2C_SDA, soft_i2c_gpio_sda); 47 return soft_i2c_gpio_sda; 48 } 49 ret = gpio_request(soft_i2c_gpio_sda, "soft-i2c-sda"); 50 if (ret) { 51 printf("Error requesting soft i2c sda pin: '%s', err %d\n", 52 CONFIG_VIDEO_LCD_PANEL_I2C_SDA, ret); 53 return ret; 54 } 55 56 soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL); 57 if (soft_i2c_gpio_scl < 0) { 58 printf("Error invalid soft i2c scl pin: '%s', err %d\n", 59 CONFIG_VIDEO_LCD_PANEL_I2C_SCL, soft_i2c_gpio_scl); 60 return soft_i2c_gpio_scl; 61 } 62 ret = gpio_request(soft_i2c_gpio_scl, "soft-i2c-scl"); 63 if (ret) { 64 printf("Error requesting soft i2c scl pin: '%s', err %d\n", 65 CONFIG_VIDEO_LCD_PANEL_I2C_SCL, ret); 66 return ret; 67 } 68 69 return 0; 70 } 71 #else 72 static int soft_i2c_board_init(void) { return 0; } 73 #endif 74 75 DECLARE_GLOBAL_DATA_PTR; 76 77 /* add board specific code here */ 78 int board_init(void) 79 { 80 __maybe_unused int id_pfr1, ret; 81 82 gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100); 83 84 #ifndef CONFIG_ARM64 85 asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1)); 86 debug("id_pfr1: 0x%08x\n", id_pfr1); 87 /* Generic Timer Extension available? */ 88 if ((id_pfr1 >> CPUID_ARM_GENTIMER_SHIFT) & 0xf) { 89 uint32_t freq; 90 91 debug("Setting CNTFRQ\n"); 92 93 /* 94 * CNTFRQ is a secure register, so we will crash if we try to 95 * write this from the non-secure world (read is OK, though). 96 * In case some bootcode has already set the correct value, 97 * we avoid the risk of writing to it. 98 */ 99 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(freq)); 100 if (freq != CONFIG_TIMER_CLK_FREQ) { 101 debug("arch timer frequency is %d Hz, should be %d, fixing ...\n", 102 freq, CONFIG_TIMER_CLK_FREQ); 103 #ifdef CONFIG_NON_SECURE 104 printf("arch timer frequency is wrong, but cannot adjust it\n"); 105 #else 106 asm volatile("mcr p15, 0, %0, c14, c0, 0" 107 : : "r"(CONFIG_TIMER_CLK_FREQ)); 108 #endif 109 } 110 } 111 #endif /* !CONFIG_ARM64 */ 112 113 ret = axp_gpio_init(); 114 if (ret) 115 return ret; 116 117 #ifdef CONFIG_SATAPWR 118 gpio_request(CONFIG_SATAPWR, "satapwr"); 119 gpio_direction_output(CONFIG_SATAPWR, 1); 120 #endif 121 #ifdef CONFIG_MACPWR 122 gpio_request(CONFIG_MACPWR, "macpwr"); 123 gpio_direction_output(CONFIG_MACPWR, 1); 124 #endif 125 126 /* Uses dm gpio code so do this here and not in i2c_init_board() */ 127 return soft_i2c_board_init(); 128 } 129 130 int dram_init(void) 131 { 132 gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); 133 134 return 0; 135 } 136 137 #if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) 138 static void nand_pinmux_setup(void) 139 { 140 unsigned int pin; 141 142 for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++) 143 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND); 144 145 #if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I 146 for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++) 147 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND); 148 #endif 149 /* sun4i / sun7i do have a PC23, but it is not used for nand, 150 * only sun7i has a PC24 */ 151 #ifdef CONFIG_MACH_SUN7I 152 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND); 153 #endif 154 } 155 156 static void nand_clock_setup(void) 157 { 158 struct sunxi_ccm_reg *const ccm = 159 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 160 161 setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0)); 162 #ifdef CONFIG_MACH_SUN9I 163 setbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA)); 164 #else 165 setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA)); 166 #endif 167 setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1); 168 } 169 170 void board_nand_init(void) 171 { 172 nand_pinmux_setup(); 173 nand_clock_setup(); 174 } 175 #endif 176 177 #ifdef CONFIG_GENERIC_MMC 178 static void mmc_pinmux_setup(int sdc) 179 { 180 unsigned int pin; 181 __maybe_unused int pins; 182 183 switch (sdc) { 184 case 0: 185 /* SDC0: PF0-PF5 */ 186 for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) { 187 sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0); 188 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 189 sunxi_gpio_set_drv(pin, 2); 190 } 191 break; 192 193 case 1: 194 pins = sunxi_name_to_gpio_bank(CONFIG_MMC1_PINS); 195 196 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 197 if (pins == SUNXI_GPIO_H) { 198 /* SDC1: PH22-PH-27 */ 199 for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) { 200 sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1); 201 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 202 sunxi_gpio_set_drv(pin, 2); 203 } 204 } else { 205 /* SDC1: PG0-PG5 */ 206 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 207 sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1); 208 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 209 sunxi_gpio_set_drv(pin, 2); 210 } 211 } 212 #elif defined(CONFIG_MACH_SUN5I) 213 /* SDC1: PG3-PG8 */ 214 for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) { 215 sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1); 216 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 217 sunxi_gpio_set_drv(pin, 2); 218 } 219 #elif defined(CONFIG_MACH_SUN6I) 220 /* SDC1: PG0-PG5 */ 221 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 222 sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1); 223 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 224 sunxi_gpio_set_drv(pin, 2); 225 } 226 #elif defined(CONFIG_MACH_SUN8I) 227 if (pins == SUNXI_GPIO_D) { 228 /* SDC1: PD2-PD7 */ 229 for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) { 230 sunxi_gpio_set_cfgpin(pin, SUN8I_GPD_SDC1); 231 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 232 sunxi_gpio_set_drv(pin, 2); 233 } 234 } else { 235 /* SDC1: PG0-PG5 */ 236 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 237 sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1); 238 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 239 sunxi_gpio_set_drv(pin, 2); 240 } 241 } 242 #endif 243 break; 244 245 case 2: 246 pins = sunxi_name_to_gpio_bank(CONFIG_MMC2_PINS); 247 248 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 249 /* SDC2: PC6-PC11 */ 250 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) { 251 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 252 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 253 sunxi_gpio_set_drv(pin, 2); 254 } 255 #elif defined(CONFIG_MACH_SUN5I) 256 if (pins == SUNXI_GPIO_E) { 257 /* SDC2: PE4-PE9 */ 258 for (pin = SUNXI_GPE(4); pin <= SUNXI_GPD(9); pin++) { 259 sunxi_gpio_set_cfgpin(pin, SUN5I_GPE_SDC2); 260 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 261 sunxi_gpio_set_drv(pin, 2); 262 } 263 } else { 264 /* SDC2: PC6-PC15 */ 265 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 266 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 267 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 268 sunxi_gpio_set_drv(pin, 2); 269 } 270 } 271 #elif defined(CONFIG_MACH_SUN6I) 272 if (pins == SUNXI_GPIO_A) { 273 /* SDC2: PA9-PA14 */ 274 for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) { 275 sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC2); 276 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 277 sunxi_gpio_set_drv(pin, 2); 278 } 279 } else { 280 /* SDC2: PC6-PC15, PC24 */ 281 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 282 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 283 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 284 sunxi_gpio_set_drv(pin, 2); 285 } 286 287 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2); 288 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); 289 sunxi_gpio_set_drv(SUNXI_GPC(24), 2); 290 } 291 #elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I) 292 /* SDC2: PC5-PC6, PC8-PC16 */ 293 for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) { 294 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 295 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 296 sunxi_gpio_set_drv(pin, 2); 297 } 298 299 for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); pin++) { 300 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 301 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 302 sunxi_gpio_set_drv(pin, 2); 303 } 304 #endif 305 break; 306 307 case 3: 308 pins = sunxi_name_to_gpio_bank(CONFIG_MMC3_PINS); 309 310 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 311 /* SDC3: PI4-PI9 */ 312 for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { 313 sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3); 314 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 315 sunxi_gpio_set_drv(pin, 2); 316 } 317 #elif defined(CONFIG_MACH_SUN6I) 318 if (pins == SUNXI_GPIO_A) { 319 /* SDC3: PA9-PA14 */ 320 for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) { 321 sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC3); 322 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 323 sunxi_gpio_set_drv(pin, 2); 324 } 325 } else { 326 /* SDC3: PC6-PC15, PC24 */ 327 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 328 sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3); 329 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 330 sunxi_gpio_set_drv(pin, 2); 331 } 332 333 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3); 334 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); 335 sunxi_gpio_set_drv(SUNXI_GPC(24), 2); 336 } 337 #endif 338 break; 339 340 default: 341 printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc); 342 break; 343 } 344 } 345 346 int board_mmc_init(bd_t *bis) 347 { 348 __maybe_unused struct mmc *mmc0, *mmc1; 349 __maybe_unused char buf[512]; 350 351 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT); 352 mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT); 353 if (!mmc0) 354 return -1; 355 356 #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1 357 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA); 358 mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA); 359 if (!mmc1) 360 return -1; 361 #endif 362 363 #if !defined(CONFIG_SPL_BUILD) && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2 364 /* 365 * On systems with an emmc (mmc2), figure out if we are booting from 366 * the emmc and if we are make it "mmc dev 0" so that boot.scr, etc. 367 * are searched there first. Note we only do this for u-boot proper, 368 * not for the SPL, see spl_boot_device(). 369 */ 370 if (!sunxi_mmc_has_egon_boot_signature(mmc0) && 371 sunxi_mmc_has_egon_boot_signature(mmc1)) { 372 /* Booting from emmc / mmc2, swap */ 373 mmc0->block_dev.devnum = 1; 374 mmc1->block_dev.devnum = 0; 375 } 376 #endif 377 378 return 0; 379 } 380 #endif 381 382 void i2c_init_board(void) 383 { 384 #ifdef CONFIG_I2C0_ENABLE 385 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) 386 sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0); 387 sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0); 388 clock_twi_onoff(0, 1); 389 #elif defined(CONFIG_MACH_SUN6I) 390 sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0); 391 sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0); 392 clock_twi_onoff(0, 1); 393 #elif defined(CONFIG_MACH_SUN8I) 394 sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0); 395 sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0); 396 clock_twi_onoff(0, 1); 397 #endif 398 #endif 399 400 #ifdef CONFIG_I2C1_ENABLE 401 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 402 sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1); 403 sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1); 404 clock_twi_onoff(1, 1); 405 #elif defined(CONFIG_MACH_SUN5I) 406 sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1); 407 sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1); 408 clock_twi_onoff(1, 1); 409 #elif defined(CONFIG_MACH_SUN6I) 410 sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1); 411 sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1); 412 clock_twi_onoff(1, 1); 413 #elif defined(CONFIG_MACH_SUN8I) 414 sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1); 415 sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1); 416 clock_twi_onoff(1, 1); 417 #endif 418 #endif 419 420 #ifdef CONFIG_I2C2_ENABLE 421 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 422 sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2); 423 sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2); 424 clock_twi_onoff(2, 1); 425 #elif defined(CONFIG_MACH_SUN5I) 426 sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2); 427 sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2); 428 clock_twi_onoff(2, 1); 429 #elif defined(CONFIG_MACH_SUN6I) 430 sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2); 431 sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2); 432 clock_twi_onoff(2, 1); 433 #elif defined(CONFIG_MACH_SUN8I) 434 sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2); 435 sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2); 436 clock_twi_onoff(2, 1); 437 #endif 438 #endif 439 440 #ifdef CONFIG_I2C3_ENABLE 441 #if defined(CONFIG_MACH_SUN6I) 442 sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3); 443 sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3); 444 clock_twi_onoff(3, 1); 445 #elif defined(CONFIG_MACH_SUN7I) 446 sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3); 447 sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3); 448 clock_twi_onoff(3, 1); 449 #endif 450 #endif 451 452 #ifdef CONFIG_I2C4_ENABLE 453 #if defined(CONFIG_MACH_SUN7I) 454 sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4); 455 sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4); 456 clock_twi_onoff(4, 1); 457 #endif 458 #endif 459 460 #ifdef CONFIG_R_I2C_ENABLE 461 clock_twi_onoff(5, 1); 462 sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI); 463 sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI); 464 #endif 465 } 466 467 #ifdef CONFIG_SPL_BUILD 468 void sunxi_board_init(void) 469 { 470 int power_failed = 0; 471 unsigned long ramsize; 472 473 #ifdef CONFIG_SY8106A_POWER 474 power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT); 475 #endif 476 477 #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ 478 defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ 479 defined CONFIG_AXP818_POWER 480 power_failed = axp_init(); 481 482 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ 483 defined CONFIG_AXP818_POWER 484 power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT); 485 #endif 486 power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT); 487 power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT); 488 #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER) 489 power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT); 490 #endif 491 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ 492 defined CONFIG_AXP818_POWER 493 power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT); 494 #endif 495 496 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ 497 defined CONFIG_AXP818_POWER 498 power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); 499 #endif 500 power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); 501 #if !defined(CONFIG_AXP152_POWER) 502 power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT); 503 #endif 504 #ifdef CONFIG_AXP209_POWER 505 power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT); 506 #endif 507 508 #if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP809_POWER) || \ 509 defined(CONFIG_AXP818_POWER) 510 power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT); 511 power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT); 512 #if !defined CONFIG_AXP809_POWER 513 power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT); 514 power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT); 515 #endif 516 power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT); 517 power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT); 518 power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT); 519 #endif 520 521 #ifdef CONFIG_AXP818_POWER 522 power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT); 523 power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT); 524 power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT); 525 #endif 526 527 #if defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER 528 power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON)); 529 #endif 530 #endif 531 printf("DRAM:"); 532 ramsize = sunxi_dram_init(); 533 printf(" %d MiB\n", (int)(ramsize >> 20)); 534 if (!ramsize) 535 hang(); 536 537 /* 538 * Only clock up the CPU to full speed if we are reasonably 539 * assured it's being powered with suitable core voltage 540 */ 541 if (!power_failed) 542 clock_set_pll1(CONFIG_SYS_CLK_FREQ); 543 else 544 printf("Failed to set core voltage! Can't set CPU frequency\n"); 545 } 546 #endif 547 548 #ifdef CONFIG_USB_GADGET 549 int g_dnl_board_usb_cable_connected(void) 550 { 551 return sunxi_usb_phy_vbus_detect(0); 552 } 553 #endif 554 555 #ifdef CONFIG_SERIAL_TAG 556 void get_board_serial(struct tag_serialnr *serialnr) 557 { 558 char *serial_string; 559 unsigned long long serial; 560 561 serial_string = getenv("serial#"); 562 563 if (serial_string) { 564 serial = simple_strtoull(serial_string, NULL, 16); 565 566 serialnr->high = (unsigned int) (serial >> 32); 567 serialnr->low = (unsigned int) (serial & 0xffffffff); 568 } else { 569 serialnr->high = 0; 570 serialnr->low = 0; 571 } 572 } 573 #endif 574 575 #if !defined(CONFIG_SPL_BUILD) 576 #include <asm/arch/spl.h> 577 #include <environment.h> 578 579 /* 580 * Check the SPL header for the "sunxi" variant. If found: parse values 581 * that might have been passed by the loader ("fel" utility), and update 582 * the environment accordingly. 583 */ 584 static void parse_spl_header(const uint32_t spl_addr) 585 { 586 struct boot_file_head *spl = (void *)(ulong)spl_addr; 587 if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0) 588 return; /* signature mismatch, no usable header */ 589 590 uint8_t spl_header_version = spl->spl_signature[3]; 591 if (spl_header_version != SPL_HEADER_VERSION) { 592 printf("sunxi SPL version mismatch: expected %u, got %u\n", 593 SPL_HEADER_VERSION, spl_header_version); 594 return; 595 } 596 if (!spl->fel_script_address) 597 return; 598 599 if (spl->fel_uEnv_length != 0) { 600 /* 601 * data is expected in uEnv.txt compatible format, so "env 602 * import -t" the string(s) at fel_script_address right away. 603 */ 604 himport_r(&env_htab, (char *)spl->fel_script_address, 605 spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL); 606 return; 607 } 608 /* otherwise assume .scr format (mkimage-type script) */ 609 setenv_hex("fel_scriptaddr", spl->fel_script_address); 610 } 611 #endif 612 613 /* 614 * Note this function gets called multiple times. 615 * It must not make any changes to env variables which already exist. 616 */ 617 static void setup_environment(const void *fdt) 618 { 619 char serial_string[17] = { 0 }; 620 unsigned int sid[4]; 621 uint8_t mac_addr[6]; 622 char ethaddr[16]; 623 int i, ret; 624 625 ret = sunxi_get_sid(sid); 626 if (ret == 0 && sid[0] != 0 && sid[3] != 0) { 627 for (i = 0; i < 4; i++) { 628 sprintf(ethaddr, "ethernet%d", i); 629 if (!fdt_get_alias(fdt, ethaddr)) 630 continue; 631 632 if (i == 0) 633 strcpy(ethaddr, "ethaddr"); 634 else 635 sprintf(ethaddr, "eth%daddr", i); 636 637 if (getenv(ethaddr)) 638 continue; 639 640 /* Non OUI / registered MAC address */ 641 mac_addr[0] = (i << 4) | 0x02; 642 mac_addr[1] = (sid[0] >> 0) & 0xff; 643 mac_addr[2] = (sid[3] >> 24) & 0xff; 644 mac_addr[3] = (sid[3] >> 16) & 0xff; 645 mac_addr[4] = (sid[3] >> 8) & 0xff; 646 mac_addr[5] = (sid[3] >> 0) & 0xff; 647 648 eth_setenv_enetaddr(ethaddr, mac_addr); 649 } 650 651 if (!getenv("serial#")) { 652 snprintf(serial_string, sizeof(serial_string), 653 "%08x%08x", sid[0], sid[3]); 654 655 setenv("serial#", serial_string); 656 } 657 } 658 } 659 660 #ifdef CONFIG_MISC_INIT_R 661 int misc_init_r(void) 662 { 663 __maybe_unused int ret; 664 665 #if !defined(CONFIG_SPL_BUILD) 666 setenv("fel_booted", NULL); 667 setenv("fel_scriptaddr", NULL); 668 /* determine if we are running in FEL mode */ 669 if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */ 670 setenv("fel_booted", "1"); 671 parse_spl_header(SPL_ADDR); 672 } 673 #endif 674 675 setup_environment(gd->fdt_blob); 676 677 #ifndef CONFIG_MACH_SUN9I 678 ret = sunxi_usb_phy_probe(); 679 if (ret) 680 return ret; 681 #endif 682 sunxi_musb_board_init(); 683 684 return 0; 685 } 686 #endif 687 688 int ft_board_setup(void *blob, bd_t *bd) 689 { 690 int __maybe_unused r; 691 692 /* 693 * Call setup_environment again in case the boot fdt has 694 * ethernet aliases the u-boot copy does not have. 695 */ 696 setup_environment(blob); 697 698 #ifdef CONFIG_VIDEO_DT_SIMPLEFB 699 r = sunxi_simplefb_setup(blob); 700 if (r) 701 return r; 702 #endif 703 return 0; 704 } 705