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 427 #ifdef CONFIG_SPL_BUILD 428 void sunxi_board_init(void) 429 { 430 int power_failed = 0; 431 unsigned long ramsize; 432 433 #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || defined CONFIG_AXP221_POWER 434 power_failed = axp_init(); 435 436 #ifdef CONFIG_AXP221_POWER 437 power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT); 438 #endif 439 power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT); 440 power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT); 441 #ifndef CONFIG_AXP209_POWER 442 power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT); 443 #endif 444 #ifdef CONFIG_AXP221_POWER 445 power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT); 446 #endif 447 448 #ifdef CONFIG_AXP221_POWER 449 power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); 450 #endif 451 power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); 452 #ifndef CONFIG_AXP152_POWER 453 power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT); 454 #endif 455 #ifdef CONFIG_AXP209_POWER 456 power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT); 457 #endif 458 459 #ifdef CONFIG_AXP221_POWER 460 power_failed |= axp_set_dldo1(CONFIG_AXP_DLDO1_VOLT); 461 power_failed |= axp_set_dldo2(CONFIG_AXP_DLDO2_VOLT); 462 power_failed |= axp_set_dldo3(CONFIG_AXP_DLDO3_VOLT); 463 power_failed |= axp_set_dldo4(CONFIG_AXP_DLDO4_VOLT); 464 power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT); 465 power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT); 466 power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT); 467 #endif 468 #endif 469 printf("DRAM:"); 470 ramsize = sunxi_dram_init(); 471 printf(" %lu MiB\n", ramsize >> 20); 472 if (!ramsize) 473 hang(); 474 475 /* 476 * Only clock up the CPU to full speed if we are reasonably 477 * assured it's being powered with suitable core voltage 478 */ 479 if (!power_failed) 480 clock_set_pll1(CONFIG_SYS_CLK_FREQ); 481 else 482 printf("Failed to set core voltage! Can't set CPU frequency\n"); 483 } 484 #endif 485 486 #ifdef CONFIG_USB_GADGET 487 int g_dnl_board_usb_cable_connected(void) 488 { 489 return sunxi_usb_phy_vbus_detect(0); 490 } 491 #endif 492 493 #ifdef CONFIG_SERIAL_TAG 494 void get_board_serial(struct tag_serialnr *serialnr) 495 { 496 char *serial_string; 497 unsigned long long serial; 498 499 serial_string = getenv("serial#"); 500 501 if (serial_string) { 502 serial = simple_strtoull(serial_string, NULL, 16); 503 504 serialnr->high = (unsigned int) (serial >> 32); 505 serialnr->low = (unsigned int) (serial & 0xffffffff); 506 } else { 507 serialnr->high = 0; 508 serialnr->low = 0; 509 } 510 } 511 #endif 512 513 #if !defined(CONFIG_SPL_BUILD) 514 #include <asm/arch/spl.h> 515 516 /* 517 * Check the SPL header for the "sunxi" variant. If found: parse values 518 * that might have been passed by the loader ("fel" utility), and update 519 * the environment accordingly. 520 */ 521 static void parse_spl_header(const uint32_t spl_addr) 522 { 523 struct boot_file_head *spl = (void *)spl_addr; 524 if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) { 525 uint8_t spl_header_version = spl->spl_signature[3]; 526 if (spl_header_version == SPL_HEADER_VERSION) { 527 if (spl->fel_script_address) 528 setenv_hex("fel_scriptaddr", 529 spl->fel_script_address); 530 return; 531 } 532 printf("sunxi SPL version mismatch: expected %u, got %u\n", 533 SPL_HEADER_VERSION, spl_header_version); 534 } 535 } 536 #endif 537 538 #ifdef CONFIG_MISC_INIT_R 539 int misc_init_r(void) 540 { 541 char serial_string[17] = { 0 }; 542 unsigned int sid[4]; 543 uint8_t mac_addr[6]; 544 int ret; 545 546 #if !defined(CONFIG_SPL_BUILD) 547 setenv("fel_booted", NULL); 548 setenv("fel_scriptaddr", NULL); 549 /* determine if we are running in FEL mode */ 550 if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */ 551 setenv("fel_booted", "1"); 552 parse_spl_header(SPL_ADDR); 553 } 554 #endif 555 556 ret = sunxi_get_sid(sid); 557 if (ret == 0 && sid[0] != 0 && sid[3] != 0) { 558 if (!getenv("ethaddr")) { 559 /* Non OUI / registered MAC address */ 560 mac_addr[0] = 0x02; 561 mac_addr[1] = (sid[0] >> 0) & 0xff; 562 mac_addr[2] = (sid[3] >> 24) & 0xff; 563 mac_addr[3] = (sid[3] >> 16) & 0xff; 564 mac_addr[4] = (sid[3] >> 8) & 0xff; 565 mac_addr[5] = (sid[3] >> 0) & 0xff; 566 567 eth_setenv_enetaddr("ethaddr", mac_addr); 568 } 569 570 if (!getenv("serial#")) { 571 snprintf(serial_string, sizeof(serial_string), 572 "%08x%08x", sid[0], sid[3]); 573 574 setenv("serial#", serial_string); 575 } 576 } 577 578 #ifndef CONFIG_MACH_SUN9I 579 ret = sunxi_usb_phy_probe(); 580 if (ret) 581 return ret; 582 #endif 583 sunxi_musb_board_init(); 584 585 return 0; 586 } 587 #endif 588 589 #ifdef CONFIG_OF_BOARD_SETUP 590 int ft_board_setup(void *blob, bd_t *bd) 591 { 592 #ifdef CONFIG_VIDEO_DT_SIMPLEFB 593 return sunxi_simplefb_setup(blob); 594 #endif 595 } 596 #endif /* CONFIG_OF_BOARD_SETUP */ 597