From c2240d4dbef98f0bc5f5e99324d1eef8d6e9acdf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 14 Mar 2013 07:20:12 +0000 Subject: Adjust board_r.c for ppc This adds ppc features to the generic post-relocation board init. Signed-off-by: Simon Glass --- common/board_r.c | 480 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 477 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/board_r.c b/common/board_r.c index 06b0df0003..c57ae5cace 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -27,25 +27,81 @@ */ #include +/* TODO: can we just include all these headers whether needed or not? */ +#if defined(CONFIG_CMD_BEDBUG) +#include +#endif #ifdef CONFIG_HAS_DATAFLASH #include #endif #include #include +#if defined(CONFIG_CMD_IDE) +#include +#endif #include +#ifdef CONFIG_PS2KBD +#include +#endif +#if defined(CONFIG_CMD_KGDB) +#include +#endif #include #include +#ifdef CONFIG_BITBANGMII +#include +#endif #include #include #include +#include #include +#include #include +#include +#ifdef CONFIG_ADDR_MAP +#include +#endif #include +#include DECLARE_GLOBAL_DATA_PTR; ulong monitor_flash_len; +int __board_flash_wp_on(void) +{ + /* + * Most flashes can't be detected when write protection is enabled, + * so provide a way to let U-Boot gracefully ignore write protected + * devices. + */ + return 0; +} + +int board_flash_wp_on(void) + __attribute__ ((weak, alias("__board_flash_wp_on"))); + +void __cpu_secondary_init_r(void) +{ +} + +void cpu_secondary_init_r(void) + __attribute__ ((weak, alias("__cpu_secondary_init_r"))); + +static int initr_secondary_cpu(void) +{ + /* + * after non-volatile devices & environment is setup and cpu code have + * another round to deal with any initialization that might require + * full access to the environment or loading of some image (firmware) + * from a non-volatile device + */ + /* TODO: maybe define this for all archs? */ + cpu_secondary_init_r(); + + return 0; +} static int initr_reloc(void) { @@ -68,6 +124,11 @@ static int initr_caches(void) } #endif +__weak int fixup_cpu(void) +{ + return 0; +} + static int initr_reloc_global_data(void) { #ifdef CONFIG_SYS_SYM_OFFSETS @@ -75,6 +136,31 @@ static int initr_reloc_global_data(void) #else monitor_flash_len = (ulong)&__init_end - gd->dest_addr; #endif +#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) + /* + * The gd->cpu pointer is set to an address in flash before relocation. + * We need to update it to point to the same CPU entry in RAM. + * TODO: why not just add gd->reloc_ofs? + */ + gd->arch.cpu += gd->dest_addr - CONFIG_SYS_MONITOR_BASE; + + /* + * If we didn't know the cpu mask & # cores, we can save them of + * now rather than 'computing' them constantly + */ + fixup_cpu(); +#endif +#ifdef CONFIG_SYS_EXTRA_ENV_RELOC + /* + * Some systems need to relocate the env_addr pointer early because the + * location it points to will get invalidated before env_relocate is + * called. One example is on systems that might use a L2 or L3 cache + * in SRAM mode and initialize that cache from SRAM mode back to being + * a cache in cpu_init_r. + */ + gd->env_addr += gd->dest_addr - CONFIG_SYS_MONITOR_BASE; +#endif + return 0; } static int initr_serial(void) @@ -83,6 +169,27 @@ static int initr_serial(void) return 0; } +#ifdef CONFIG_PPC +static int initr_trap(void) +{ + /* + * Setup trap handlers + */ + trap_init(gd->dest_addr); + + return 0; +} +#endif + +#ifdef CONFIG_ADDR_MAP +static int initr_addr_map(void) +{ + init_addr_map(); + + return 0; +} +#endif + #ifdef CONFIG_LOGBUFFER unsigned long logbuffer_base(void) { @@ -104,6 +211,50 @@ static int initr_post_backlog(void) } #endif +#ifdef CONFIG_SYS_DELAYED_ICACHE +static int initr_icache_enable(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) +static int initr_unlock_ram_in_cache(void) +{ + unlock_ram_in_cache(); /* it's time to unlock D-cache in e500 */ + return 0; +} +#endif + +#ifdef CONFIG_PCI +static int initr_pci(void) +{ + pci_init(); + + return 0; +} +#endif + +#ifdef CONFIG_WINBOND_83C553 +static int initr_w83c553f(void) +{ + /* + * Initialise the ISA bridge + */ + initialise_w83c553f(); + return 0; +} +#endif + +static int initr_barrier(void) +{ +#ifdef CONFIG_PPC + /* TODO: Can we not use dmb() macros for this? */ + asm("sync ; isync"); +#endif + return 0; +} + static int initr_malloc(void) { ulong malloc_start; @@ -128,13 +279,26 @@ static int initr_announce(void) #if !defined(CONFIG_SYS_NO_FLASH) static int initr_flash(void) { - ulong flash_size; + ulong flash_size = 0; + bd_t *bd = gd->bd; + int ok; puts("Flash: "); - flash_size = flash_init(); - if (flash_size <= 0) { + if (board_flash_wp_on()) { + printf("Uninitialized - Write Protect On\n"); + /* Since WP is on, we can't find real size. Set to 0 */ + ok = 1; + } else { + flash_size = flash_init(); + ok = flash_size > 0; + } + if (!ok) { puts("*** failed ***\n"); +#ifdef CONFIG_PPC + /* Why does PPC do this? */ + hang(); +#endif return -1; } print_size(flash_size, ""); @@ -152,6 +316,39 @@ static int initr_flash(void) #endif /* CONFIG_SYS_FLASH_CHECKSUM */ putc('\n'); + /* update start of FLASH memory */ +#ifdef CONFIG_SYS_FLASH_BASE + bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; +#endif + /* size of FLASH memory (final value) */ + bd->bi_flashsize = flash_size; + +#if defined(CONFIG_SYS_UPDATE_FLASH_SIZE) + /* Make a update of the Memctrl. */ + update_flash_size(flash_size); +#endif + + +#if defined(CONFIG_OXC) || defined(CONFIG_RMU) + /* flash mapped at end of memory map */ + bd->bi_flashoffset = CONFIG_SYS_TEXT_BASE + flash_size; +#elif CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE + bd->bi_flashoffset = monitor_flash_len; /* reserved area for monitor */ +#endif + return 0; +} +#endif + +#ifdef CONFIG_PPC +static int initr_spi(void) +{ + /* PPC does this here */ +#ifdef CONFIG_SPI +#if !defined(CONFIG_ENV_IS_IN_EEPROM) + spi_init_f(); +#endif + spi_init_r(); +#endif return 0; } #endif @@ -226,8 +423,55 @@ static int initr_env(void) /* Initialize from environment */ load_addr = getenv_ulong("loadaddr", 16, load_addr); +#if defined(CONFIG_SYS_EXTBDINFO) +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) +#if defined(CONFIG_I2CFAST) + /* + * set bi_iic_fast for linux taking environment variable + * "i2cfast" into account + */ + { + char *s = getenv("i2cfast"); + + if (s && ((*s == 'y') || (*s == 'Y'))) { + gd->bd->bi_iic_fast[0] = 1; + gd->bd->bi_iic_fast[1] = 1; + } + } +#endif /* CONFIG_I2CFAST */ +#endif /* CONFIG_405GP, CONFIG_405EP */ +#endif /* CONFIG_SYS_EXTBDINFO */ + return 0; +} + +#ifdef CONFIG_HERMES +static int initr_hermes(void) +{ + if ((gd->board_type >> 16) == 2) + gd->bd->bi_ethspeed = gd->board_type & 0xFFFF; + else + gd->bd->bi_ethspeed = 0xFFFF; + return 0; +} + +static int initr_hermes_start(void) +{ + if (gd->bd->bi_ethspeed != 0xFFFF) + hermes_start_lxt980((int) gd->bd->bi_ethspeed); return 0; } +#endif + +#ifdef CONFIG_SC3 +/* TODO: with new initcalls, move this into the driver */ +extern void sc3_read_eeprom(void); + +static int initr_sc3_read_eeprom(void) +{ + sc3_read_eeprom(); + return 0; +} +#endif static int initr_jumptable(void) { @@ -269,11 +513,68 @@ static int initr_enable_interrupts(void) #ifdef CONFIG_CMD_NET static int initr_ethaddr(void) { + bd_t *bd = gd->bd; + + /* kept around for legacy kernels only ... ignore the next section */ + eth_getenv_enetaddr("ethaddr", bd->bi_enetaddr); +#ifdef CONFIG_HAS_ETH1 + eth_getenv_enetaddr("eth1addr", bd->bi_enet1addr); +#endif +#ifdef CONFIG_HAS_ETH2 + eth_getenv_enetaddr("eth2addr", bd->bi_enet2addr); +#endif +#ifdef CONFIG_HAS_ETH3 + eth_getenv_enetaddr("eth3addr", bd->bi_enet3addr); +#endif +#ifdef CONFIG_HAS_ETH4 + eth_getenv_enetaddr("eth4addr", bd->bi_enet4addr); +#endif +#ifdef CONFIG_HAS_ETH5 + eth_getenv_enetaddr("eth5addr", bd->bi_enet5addr); +#endif + return 0; +} +#endif /* CONFIG_CMD_NET */ + +#ifdef CONFIG_CMD_KGDB +static int initr_kgdb(void) +{ + puts("KGDB: "); + kgdb_init(); + return 0; +} +#endif + +#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) +static int initr_status_led(void) +{ + status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); + + return 0; +} +#endif + +#if defined(CONFIG_CMD_SCSI) +static int initr_scsi(void) +{ + /* Not supported properly on ARM yet */ +#ifndef CONFIG_ARM + puts("SCSI: "); + scsi_init(); +#endif return 0; } #endif /* CONFIG_CMD_NET */ +#if defined(CONFIG_CMD_DOC) +static int initr_doc(void) +{ + puts("DOC: "); + doc_init(); +} +#endif + #ifdef CONFIG_BITBANGMII static int initr_bbmii(void) { @@ -303,6 +604,33 @@ static int initr_post(void) } #endif +#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE) +static int initr_pcmcia(void) +{ + puts("PCMCIA:"); + pcmcia_init(); + return 0; +} +#endif + +#if defined(CONFIG_CMD_IDE) +static int initr_ide(void) +{ +#ifdef CONFIG_IDE_8xx_PCCARD + puts("PCMCIA:"); +#else + puts("IDE: "); +#endif +#if defined(CONFIG_START_IDE) + if (board_start_ide()) + ide_init(); +#else + ide_init(); +#endif + return 0; +} +#endif + #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) /* * Export available size of memory for Linux, taking into account the @@ -322,6 +650,37 @@ int initr_mem(void) # endif sprintf(memsz, "%ldk", (gd->ram_size / 1024) - pram); setenv("mem", memsz); + + return 0; +} +#endif + +#ifdef CONFIG_CMD_BEDBUG +static int initr_bedbug(void) +{ + bedbug_init(); + + return 0; +} +#endif + +#ifdef CONFIG_PS2KBD +static int initr_kbd(void) +{ + puts("PS/2: "); + kbd_init(); + return 0; +} +#endif + +#ifdef CONFIG_MODEM_SUPPORT +static int initr_modem(void) +{ + /* TODO: with new initcalls, move this into the driver */ + extern int do_mdm_init; + + do_mdm_init = gd->do_mdm_init; + return 0; } #endif @@ -339,22 +698,63 @@ static int run_main_loop(void) * * We also hope to remove most of the driver-related init and do it if/when * the driver is later used. + * + * TODO: perhaps reset the watchdog in the initcall function after each call? */ init_fnc_t init_sequence_r[] = { initr_reloc, + /* TODO: could x86/PPC have this also perhaps? */ #ifdef CONFIG_ARM initr_caches, board_init, /* Setup chipselects */ +#endif + /* + * TODO: printing of the clock inforamtion of the board is now + * implemented as part of bdinfo command. Currently only support for + * davinci SOC's is added. Remove this check once all the board + * implement this. + */ +#ifdef CONFIG_CLOCKS + set_cpu_clk_info, /* Setup clock information */ #endif initr_reloc_global_data, initr_serial, initr_announce, + INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_PPC + initr_trap, +#endif +#ifdef CONFIG_ADDR_MAP + initr_addr_map, +#endif +#if defined(CONFIG_BOARD_EARLY_INIT_R) + board_early_init_r, +#endif + INIT_FUNC_WATCHDOG_RESET #ifdef CONFIG_LOGBUFFER initr_logbuffer, #endif #ifdef CONFIG_POST initr_post_backlog, #endif + INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_SYS_DELAYED_ICACHE + initr_icache_enable, +#endif +#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) + initr_unlock_ram_in_cache, +#endif +#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT) + /* + * Do early PCI configuration _before_ the flash gets initialised, + * because PCU ressources are crucial for flash access on some boards. + */ + initr_pci, +#endif +#ifdef CONFIG_WINBOND_83C553 + initr_w83c553f, +#endif + initr_barrier, initr_malloc, #ifdef CONFIG_ARCH_EARLY_INIT_R arch_early_init_r, @@ -362,6 +762,12 @@ init_fnc_t init_sequence_r[] = { power_init_board, #ifndef CONFIG_SYS_NO_FLASH initr_flash, +#endif + INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_PPC + /* initialize higher level parts of CPU like time base and timers */ + cpu_init_r, + initr_spi, #endif #ifdef CONFIG_CMD_NAND initr_nand, @@ -376,6 +782,24 @@ init_fnc_t init_sequence_r[] = { initr_dataflash, #endif initr_env, + INIT_FUNC_WATCHDOG_RESET + initr_secondary_cpu, +#ifdef CONFIG_SC3 + initr_sc3_read_eeprom, +#endif +#ifdef CONFIG_HERMES + initr_hermes, +#endif +#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET) + mac_read_from_eeprom, +#endif + INIT_FUNC_WATCHDOG_RESET +#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT) + /* + * Do pci configuration + */ + initr_pci, +#endif stdio_init, initr_jumptable, #ifdef CONFIG_API @@ -390,23 +814,73 @@ init_fnc_t init_sequence_r[] = { #endif #ifdef CONFIG_MISC_INIT_R misc_init_r, /* miscellaneous platform-dependent init */ +#endif +#ifdef CONFIG_HERMES + initr_hermes_start, +#endif + INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_CMD_KGDB + initr_kgdb, #endif interrupt_init, +#ifdef CONFIG_ARM initr_enable_interrupts, +#endif +#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) + initr_status_led, +#endif + /* PPC has a udelay(20) here dating from 2002. Why? */ #ifdef CONFIG_CMD_NET initr_ethaddr, #endif #ifdef CONFIG_BOARD_LATE_INIT board_late_init, #endif +#ifdef CONFIG_CMD_SCSI + INIT_FUNC_WATCHDOG_RESET + initr_scsi, +#endif +#ifdef CONFIG_CMD_DOC + INIT_FUNC_WATCHDOG_RESET + initr_doc, +#endif #ifdef CONFIG_BITBANGMII initr_bbmii, #endif #ifdef CONFIG_CMD_NET + INIT_FUNC_WATCHDOG_RESET initr_net, #endif #ifdef CONFIG_POST initr_post, +#endif +#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE) + initr_pcmcia, +#endif +#if defined(CONFIG_CMD_IDE) + initr_ide, +#endif +#ifdef CONFIG_LAST_STAGE_INIT + INIT_FUNC_WATCHDOG_RESET + /* + * Some parts can be only initialized if all others (like + * Interrupts) are up and running (i.e. the PC-style ISA + * keyboard). + */ + last_stage_init, +#endif +#ifdef CONFIG_CMD_BEDBUG + INIT_FUNC_WATCHDOG_RESET + initr_bedbug, +#endif +#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) + initr_mem, +#endif +#ifdef CONFIG_PS2KBD + initr_kbd, +#endif +#ifdef CONFIG_MODEM_SUPPORT + initr_modem, #endif run_main_loop, }; -- cgit v1.2.3