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 #include <asm/gpio.h> 25 #include <asm/io.h> 26 #include <nand.h> 27 #include <net.h> 28 29 #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) 30 /* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */ 31 int soft_i2c_gpio_sda; 32 int soft_i2c_gpio_scl; 33 34 static int soft_i2c_board_init(void) 35 { 36 int ret; 37 38 soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA); 39 if (soft_i2c_gpio_sda < 0) { 40 printf("Error invalid soft i2c sda pin: '%s', err %d\n", 41 CONFIG_VIDEO_LCD_PANEL_I2C_SDA, soft_i2c_gpio_sda); 42 return soft_i2c_gpio_sda; 43 } 44 ret = gpio_request(soft_i2c_gpio_sda, "soft-i2c-sda"); 45 if (ret) { 46 printf("Error requesting soft i2c sda pin: '%s', err %d\n", 47 CONFIG_VIDEO_LCD_PANEL_I2C_SDA, ret); 48 return ret; 49 } 50 51 soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL); 52 if (soft_i2c_gpio_scl < 0) { 53 printf("Error invalid soft i2c scl pin: '%s', err %d\n", 54 CONFIG_VIDEO_LCD_PANEL_I2C_SCL, soft_i2c_gpio_scl); 55 return soft_i2c_gpio_scl; 56 } 57 ret = gpio_request(soft_i2c_gpio_scl, "soft-i2c-scl"); 58 if (ret) { 59 printf("Error requesting soft i2c scl pin: '%s', err %d\n", 60 CONFIG_VIDEO_LCD_PANEL_I2C_SCL, ret); 61 return ret; 62 } 63 64 return 0; 65 } 66 #else 67 static int soft_i2c_board_init(void) { return 0; } 68 #endif 69 70 DECLARE_GLOBAL_DATA_PTR; 71 72 /* add board specific code here */ 73 int board_init(void) 74 { 75 int id_pfr1, ret; 76 77 gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100); 78 79 asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1)); 80 debug("id_pfr1: 0x%08x\n", id_pfr1); 81 /* Generic Timer Extension available? */ 82 if ((id_pfr1 >> 16) & 0xf) { 83 debug("Setting CNTFRQ\n"); 84 /* CNTFRQ == 24 MHz */ 85 asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000)); 86 } 87 88 ret = axp_gpio_init(); 89 if (ret) 90 return ret; 91 92 /* Uses dm gpio code so do this here and not in i2c_init_board() */ 93 return soft_i2c_board_init(); 94 } 95 96 int dram_init(void) 97 { 98 gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); 99 100 return 0; 101 } 102 103 #if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) 104 static void nand_pinmux_setup(void) 105 { 106 unsigned int pin; 107 108 for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++) 109 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND); 110 111 #if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I 112 for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++) 113 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND); 114 #endif 115 /* sun4i / sun7i do have a PC23, but it is not used for nand, 116 * only sun7i has a PC24 */ 117 #ifdef CONFIG_MACH_SUN7I 118 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND); 119 #endif 120 } 121 122 static void nand_clock_setup(void) 123 { 124 struct sunxi_ccm_reg *const ccm = 125 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 126 127 setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0)); 128 #ifdef CONFIG_MACH_SUN9I 129 setbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA)); 130 #else 131 setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA)); 132 #endif 133 setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1); 134 } 135 136 void board_nand_init(void) 137 { 138 nand_pinmux_setup(); 139 nand_clock_setup(); 140 } 141 #endif 142 143 #ifdef CONFIG_GENERIC_MMC 144 static void mmc_pinmux_setup(int sdc) 145 { 146 unsigned int pin; 147 __maybe_unused int pins; 148 149 switch (sdc) { 150 case 0: 151 /* SDC0: PF0-PF5 */ 152 for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) { 153 sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0); 154 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 155 sunxi_gpio_set_drv(pin, 2); 156 } 157 break; 158 159 case 1: 160 pins = sunxi_name_to_gpio_bank(CONFIG_MMC1_PINS); 161 162 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 163 if (pins == SUNXI_GPIO_H) { 164 /* SDC1: PH22-PH-27 */ 165 for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) { 166 sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1); 167 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 168 sunxi_gpio_set_drv(pin, 2); 169 } 170 } else { 171 /* SDC1: PG0-PG5 */ 172 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 173 sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1); 174 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 175 sunxi_gpio_set_drv(pin, 2); 176 } 177 } 178 #elif defined(CONFIG_MACH_SUN5I) 179 /* SDC1: PG3-PG8 */ 180 for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) { 181 sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1); 182 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 183 sunxi_gpio_set_drv(pin, 2); 184 } 185 #elif defined(CONFIG_MACH_SUN6I) 186 /* SDC1: PG0-PG5 */ 187 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 188 sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1); 189 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 190 sunxi_gpio_set_drv(pin, 2); 191 } 192 #elif defined(CONFIG_MACH_SUN8I) 193 if (pins == SUNXI_GPIO_D) { 194 /* SDC1: PD2-PD7 */ 195 for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) { 196 sunxi_gpio_set_cfgpin(pin, SUN8I_GPD_SDC1); 197 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 198 sunxi_gpio_set_drv(pin, 2); 199 } 200 } else { 201 /* SDC1: PG0-PG5 */ 202 for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { 203 sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1); 204 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 205 sunxi_gpio_set_drv(pin, 2); 206 } 207 } 208 #endif 209 break; 210 211 case 2: 212 pins = sunxi_name_to_gpio_bank(CONFIG_MMC2_PINS); 213 214 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 215 /* SDC2: PC6-PC11 */ 216 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) { 217 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 218 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 219 sunxi_gpio_set_drv(pin, 2); 220 } 221 #elif defined(CONFIG_MACH_SUN5I) 222 if (pins == SUNXI_GPIO_E) { 223 /* SDC2: PE4-PE9 */ 224 for (pin = SUNXI_GPE(4); pin <= SUNXI_GPD(9); pin++) { 225 sunxi_gpio_set_cfgpin(pin, SUN5I_GPE_SDC2); 226 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 227 sunxi_gpio_set_drv(pin, 2); 228 } 229 } else { 230 /* SDC2: PC6-PC15 */ 231 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 232 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 233 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 234 sunxi_gpio_set_drv(pin, 2); 235 } 236 } 237 #elif defined(CONFIG_MACH_SUN6I) 238 if (pins == SUNXI_GPIO_A) { 239 /* SDC2: PA9-PA14 */ 240 for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) { 241 sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC2); 242 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 243 sunxi_gpio_set_drv(pin, 2); 244 } 245 } else { 246 /* SDC2: PC6-PC15, PC24 */ 247 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 248 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 249 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 250 sunxi_gpio_set_drv(pin, 2); 251 } 252 253 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2); 254 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); 255 sunxi_gpio_set_drv(SUNXI_GPC(24), 2); 256 } 257 #elif defined(CONFIG_MACH_SUN8I) 258 /* SDC2: PC5-PC6, PC8-PC16 */ 259 for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) { 260 sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); 261 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 262 sunxi_gpio_set_drv(pin, 2); 263 } 264 265 for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); 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 #endif 271 break; 272 273 case 3: 274 pins = sunxi_name_to_gpio_bank(CONFIG_MMC3_PINS); 275 276 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 277 /* SDC3: PI4-PI9 */ 278 for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { 279 sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3); 280 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 281 sunxi_gpio_set_drv(pin, 2); 282 } 283 #elif defined(CONFIG_MACH_SUN6I) 284 if (pins == SUNXI_GPIO_A) { 285 /* SDC3: PA9-PA14 */ 286 for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) { 287 sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC3); 288 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 289 sunxi_gpio_set_drv(pin, 2); 290 } 291 } else { 292 /* SDC3: PC6-PC15, PC24 */ 293 for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { 294 sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3); 295 sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); 296 sunxi_gpio_set_drv(pin, 2); 297 } 298 299 sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3); 300 sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); 301 sunxi_gpio_set_drv(SUNXI_GPC(24), 2); 302 } 303 #endif 304 break; 305 306 default: 307 printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc); 308 break; 309 } 310 } 311 312 int board_mmc_init(bd_t *bis) 313 { 314 __maybe_unused struct mmc *mmc0, *mmc1; 315 __maybe_unused char buf[512]; 316 317 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT); 318 mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT); 319 if (!mmc0) 320 return -1; 321 322 #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1 323 mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA); 324 mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA); 325 if (!mmc1) 326 return -1; 327 #endif 328 329 #if !defined(CONFIG_SPL_BUILD) && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2 330 /* 331 * On systems with an emmc (mmc2), figure out if we are booting from 332 * the emmc and if we are make it "mmc dev 0" so that boot.scr, etc. 333 * are searched there first. Note we only do this for u-boot proper, 334 * not for the SPL, see spl_boot_device(). 335 */ 336 if (!sunxi_mmc_has_egon_boot_signature(mmc0) && 337 sunxi_mmc_has_egon_boot_signature(mmc1)) { 338 /* Booting from emmc / mmc2, swap */ 339 mmc0->block_dev.dev = 1; 340 mmc1->block_dev.dev = 0; 341 } 342 #endif 343 344 return 0; 345 } 346 #endif 347 348 void i2c_init_board(void) 349 { 350 #ifdef CONFIG_I2C0_ENABLE 351 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) 352 sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0); 353 sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0); 354 clock_twi_onoff(0, 1); 355 #elif defined(CONFIG_MACH_SUN6I) 356 sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0); 357 sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0); 358 clock_twi_onoff(0, 1); 359 #elif defined(CONFIG_MACH_SUN8I) 360 sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0); 361 sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0); 362 clock_twi_onoff(0, 1); 363 #endif 364 #endif 365 366 #ifdef CONFIG_I2C1_ENABLE 367 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 368 sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1); 369 sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1); 370 clock_twi_onoff(1, 1); 371 #elif defined(CONFIG_MACH_SUN5I) 372 sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1); 373 sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1); 374 clock_twi_onoff(1, 1); 375 #elif defined(CONFIG_MACH_SUN6I) 376 sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1); 377 sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1); 378 clock_twi_onoff(1, 1); 379 #elif defined(CONFIG_MACH_SUN8I) 380 sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1); 381 sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1); 382 clock_twi_onoff(1, 1); 383 #endif 384 #endif 385 386 #ifdef CONFIG_I2C2_ENABLE 387 #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) 388 sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2); 389 sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2); 390 clock_twi_onoff(2, 1); 391 #elif defined(CONFIG_MACH_SUN5I) 392 sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2); 393 sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2); 394 clock_twi_onoff(2, 1); 395 #elif defined(CONFIG_MACH_SUN6I) 396 sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2); 397 sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2); 398 clock_twi_onoff(2, 1); 399 #elif defined(CONFIG_MACH_SUN8I) 400 sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2); 401 sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2); 402 clock_twi_onoff(2, 1); 403 #endif 404 #endif 405 406 #ifdef CONFIG_I2C3_ENABLE 407 #if defined(CONFIG_MACH_SUN6I) 408 sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3); 409 sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3); 410 clock_twi_onoff(3, 1); 411 #elif defined(CONFIG_MACH_SUN7I) 412 sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3); 413 sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3); 414 clock_twi_onoff(3, 1); 415 #endif 416 #endif 417 418 #ifdef CONFIG_I2C4_ENABLE 419 #if defined(CONFIG_MACH_SUN7I) 420 sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4); 421 sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4); 422 clock_twi_onoff(4, 1); 423 #endif 424 #endif 425 426 #ifdef CONFIG_R_I2C_ENABLE 427 clock_twi_onoff(5, 1); 428 sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI); 429 sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI); 430 #endif 431 } 432 433 #ifdef CONFIG_SPL_BUILD 434 void sunxi_board_init(void) 435 { 436 int power_failed = 0; 437 unsigned long ramsize; 438 439 #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ 440 defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER 441 power_failed = axp_init(); 442 443 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER 444 power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT); 445 #endif 446 power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT); 447 power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT); 448 #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER) 449 power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT); 450 #endif 451 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER 452 power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT); 453 #endif 454 455 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER 456 power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); 457 #endif 458 power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); 459 #if !defined(CONFIG_AXP152_POWER) 460 power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT); 461 #endif 462 #ifdef CONFIG_AXP209_POWER 463 power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT); 464 #endif 465 466 #if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP818_POWER) 467 power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT); 468 power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT); 469 power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT); 470 power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT); 471 power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT); 472 power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT); 473 power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT); 474 #endif 475 #endif 476 printf("DRAM:"); 477 ramsize = sunxi_dram_init(); 478 printf(" %lu MiB\n", ramsize >> 20); 479 if (!ramsize) 480 hang(); 481 482 /* 483 * Only clock up the CPU to full speed if we are reasonably 484 * assured it's being powered with suitable core voltage 485 */ 486 if (!power_failed) 487 clock_set_pll1(CONFIG_SYS_CLK_FREQ); 488 else 489 printf("Failed to set core voltage! Can't set CPU frequency\n"); 490 } 491 #endif 492 493 #ifdef CONFIG_USB_GADGET 494 int g_dnl_board_usb_cable_connected(void) 495 { 496 return sunxi_usb_phy_vbus_detect(0); 497 } 498 #endif 499 500 #ifdef CONFIG_SERIAL_TAG 501 void get_board_serial(struct tag_serialnr *serialnr) 502 { 503 char *serial_string; 504 unsigned long long serial; 505 506 serial_string = getenv("serial#"); 507 508 if (serial_string) { 509 serial = simple_strtoull(serial_string, NULL, 16); 510 511 serialnr->high = (unsigned int) (serial >> 32); 512 serialnr->low = (unsigned int) (serial & 0xffffffff); 513 } else { 514 serialnr->high = 0; 515 serialnr->low = 0; 516 } 517 } 518 #endif 519 520 #if !defined(CONFIG_SPL_BUILD) 521 #include <asm/arch/spl.h> 522 523 /* 524 * Check the SPL header for the "sunxi" variant. If found: parse values 525 * that might have been passed by the loader ("fel" utility), and update 526 * the environment accordingly. 527 */ 528 static void parse_spl_header(const uint32_t spl_addr) 529 { 530 struct boot_file_head *spl = (void *)spl_addr; 531 if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) { 532 uint8_t spl_header_version = spl->spl_signature[3]; 533 if (spl_header_version == SPL_HEADER_VERSION) { 534 if (spl->fel_script_address) 535 setenv_hex("fel_scriptaddr", 536 spl->fel_script_address); 537 return; 538 } 539 printf("sunxi SPL version mismatch: expected %u, got %u\n", 540 SPL_HEADER_VERSION, spl_header_version); 541 } 542 } 543 #endif 544 545 #ifdef CONFIG_MISC_INIT_R 546 int misc_init_r(void) 547 { 548 char serial_string[17] = { 0 }; 549 unsigned int sid[4]; 550 uint8_t mac_addr[6]; 551 int ret; 552 553 #if !defined(CONFIG_SPL_BUILD) 554 setenv("fel_booted", NULL); 555 setenv("fel_scriptaddr", NULL); 556 /* determine if we are running in FEL mode */ 557 if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */ 558 setenv("fel_booted", "1"); 559 parse_spl_header(SPL_ADDR); 560 } 561 #endif 562 563 ret = sunxi_get_sid(sid); 564 if (ret == 0 && sid[0] != 0 && sid[3] != 0) { 565 if (!getenv("ethaddr")) { 566 /* Non OUI / registered MAC address */ 567 mac_addr[0] = 0x02; 568 mac_addr[1] = (sid[0] >> 0) & 0xff; 569 mac_addr[2] = (sid[3] >> 24) & 0xff; 570 mac_addr[3] = (sid[3] >> 16) & 0xff; 571 mac_addr[4] = (sid[3] >> 8) & 0xff; 572 mac_addr[5] = (sid[3] >> 0) & 0xff; 573 574 eth_setenv_enetaddr("ethaddr", mac_addr); 575 } 576 577 if (!getenv("serial#")) { 578 snprintf(serial_string, sizeof(serial_string), 579 "%08x%08x", sid[0], sid[3]); 580 581 setenv("serial#", serial_string); 582 } 583 } 584 585 #ifndef CONFIG_MACH_SUN9I 586 ret = sunxi_usb_phy_probe(); 587 if (ret) 588 return ret; 589 #endif 590 sunxi_musb_board_init(); 591 592 return 0; 593 } 594 #endif 595 596 #ifdef CONFIG_OF_BOARD_SETUP 597 int ft_board_setup(void *blob, bd_t *bd) 598 { 599 #ifdef CONFIG_VIDEO_DT_SIMPLEFB 600 return sunxi_simplefb_setup(blob); 601 #endif 602 } 603 #endif /* CONFIG_OF_BOARD_SETUP */ 604