uboot移植之uboot stage2
发布时间:2020-12-15 06:45:37 所属栏目:百科 来源:网络整理
导读:从stage1的start.S中跳转到uboot/lib_arm/board.c的start_armboot函数,此时处于stage2,已经在sdram的33f80000地址空间内运行,进行cpu及外设的全面初始化 board.c的源码如下 /* * (C) Copyright 2002-2006 * Wolfgang Denk,DENX Software Engineering,wd@d
从stage1的start.S中跳转到uboot/lib_arm/board.c的start_armboot函数,此时处于stage2,已经在sdram的33f80000地址空间内运行,进行cpu及外设的全面初始化
board.c的源码如下 /* * (C) Copyright 2002-2006 * Wolfgang Denk,DENX Software Engineering,wd@denx.de. * * (C) Copyright 2002 * Sysgo Real-Time Solutions,GmbH <www.elinos.com> * Marius Groeger <mgroeger@sysgo.de> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License,or (at your option) any later version. * * This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not,write to the Free Software * Foundation,Inc.,59 Temple Place,Suite 330,Boston,* MA 02111-1307 USA */ /* * To match the U-Boot user interface on ARM platforms to the U-Boot * standard (as on PPC platforms),some messages with debug character * are removed from the default U-Boot build. * * Define DEBUG here if you want additional info as shown below * printed upon startup: * * U-Boot code: 00F00000 -> 00F3C774 BSS: -> 00FC3274 * IRQ Stack: 00ebff7c * FIQ Stack: 00ebef7c */ #include <common.h> #include <command.h> #include <malloc.h> #include <stdio_dev.h> #include <timestamp.h> #include <version.h> #include <net.h> #include <serial.h> #include <nand.h> #include <onenand_uboot.h> #include <mmc.h> #include <s3c2410.h> //tekkamanninja #ifdef CONFIG_BITBANGMII #include <miiphy.h> #endif #ifdef CONFIG_DRIVER_SMC91111 #include "../drivers/net/smc91111.h" #endif #ifdef CONFIG_DRIVER_LAN91C96 #include "../drivers/net/lan91c96.h" #endif DECLARE_GLOBAL_DATA_PTR; ulong monitor_flash_len; #ifdef CONFIG_HAS_DATAFLASH extern int AT91F_DataflashInit(void); extern void dataflash_print_info(void); #endif #ifndef CONFIG_IDENT_STRING #define CONFIG_IDENT_STRING "" #endif const char version_string[] = U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING; #ifdef CONFIG_DRIVER_RTL8019 extern void rtl8019_get_enetaddr (uchar * addr); #endif #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) #include <i2c.h> #endif #if 0 /************************************************************************ * Coloured LED functionality ************************************************************************ * May be supplied by boards if desired */ void inline __coloured_LED_init (void) {} void coloured_LED_init (void) __attribute__((weak,alias("__coloured_LED_init"))); void inline __red_LED_on (void) {} void red_LED_on (void) __attribute__((weak,alias("__red_LED_on"))); void inline __red_LED_off(void) {} void red_LED_off(void) __attribute__((weak,alias("__red_LED_off"))); void inline __green_LED_on(void) {} void green_LED_on(void) __attribute__((weak,alias("__green_LED_on"))); void inline __green_LED_off(void) {} void green_LED_off(void) __attribute__((weak,alias("__green_LED_off"))); void inline __yellow_LED_on(void) {} void yellow_LED_on(void) __attribute__((weak,alias("__yellow_LED_on"))); void inline __yellow_LED_off(void) {} void yellow_LED_off(void) __attribute__((weak,alias("__yellow_LED_off"))); void inline __blue_LED_on(void) {} void blue_LED_on(void) __attribute__((weak,alias("__blue_LED_on"))); void inline __blue_LED_off(void) {} void blue_LED_off(void) __attribute__((weak,alias("__blue_LED_off"))); #endif /************************************************************************ * Init Utilities * ************************************************************************ * Some of this code should be moved into the core functions,* or dropped completely,* but let's get it working (again) first... */ #if defined(CONFIG_ARM_DCC) && !defined(CONFIG_BAUDRATE) #define CONFIG_BAUDRATE 115200 #endif static int init_baudrate (void) { char tmp[64]; /* long enough for environment variables */ int i = getenv_r ("baudrate",tmp,sizeof (tmp)); gd->bd->bi_baudrate = gd->baudrate = (i > 0) ? (int) simple_strtoul (tmp,NULL,10) : CONFIG_BAUDRATE; return (0); } static int display_banner (void) { #if defined(CONFIG_MINI2440_LED) struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); gpio->GPBDAT = 0x101; //tekkamanninja #endif printf ("nn%snn",version_string); printf ("Love Linux forever!!nn"); debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lXn",_armboot_start,_bss_start,_bss_end); #ifdef CONFIG_MODEM_SUPPORT debug ("Modem Support enabledn"); #endif #ifdef CONFIG_USE_IRQ debug ("IRQ Stack: %08lxn",IRQ_STACK_START); debug ("FIQ Stack: %08lxn",FIQ_STACK_START); #endif return (0); } /* * WARNING: this code looks "cleaner" than the PowerPC version,but * has the disadvantage that you either get nothing,or everything. * On PowerPC,you might see "DRAM: " before the system hangs - which * gives a simple yet clear indication which part of the * initialization if failing. */ static int display_dram_config (void) { int i; #ifdef DEBUG puts ("RAM Configuration:n"); for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) { printf ("Bank #%d: %08lx ",i,gd->bd->bi_dram[i].start); print_size (gd->bd->bi_dram[i].size,"n"); } #else ulong size = 0; for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) { size += gd->bd->bi_dram[i].size; } puts("DRAM: "); print_size(size,"n"); #endif return (0); } #ifndef CONFIG_SYS_NO_FLASH static void display_flash_config (ulong size) { puts ("Flash: "); print_size (size,"n"); } #endif /* CONFIG_SYS_NO_FLASH */ #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) static int init_func_i2c (void) { puts ("I2C: "); i2c_init (CONFIG_SYS_I2C_SPEED,CONFIG_SYS_I2C_SLAVE); puts ("readyn"); return (0); } #endif #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) #include <pci.h> static int arm_pci_init(void) { pci_init(); return 0; } #endif /* CONFIG_CMD_PCI || CONFIG_PCI */ /* * Breathe some life into the board... * * Initialize a serial port as console,and carry out some hardware * tests. * * The first part of initialization is running from Flash memory; * its main purpose is to initialize the RAM so that we * can relocate the monitor code to RAM. */ /* * All attempts to come up with a "common" initialization sequence * that works for all boards and architectures failed: some of the * requirements are just _too_ different. To get rid of the resulting * mess of board dependent #ifdef'ed code we now make the whole * initialization sequence configurable to the user. * * The requirements for any new initalization function is simple: it * receives a pointer to the "global data" structure as it's only * argument,and returns an integer return code,where 0 means * "continue" and != 0 means "fatal error,hang the system". */ typedef int (init_fnc_t) (void); int print_cpuinfo (void); init_fnc_t *init_sequence[] = { #if defined(CONFIG_ARCH_CPU_INIT) arch_cpu_init,/* basic arch cpu dependent setup */ #endif board_init,/* basic board dependent setup */ #if defined(CONFIG_USE_IRQ) interrupt_init,/* set up exceptions */ #endif timer_init,/* initialize timer */ env_init,/* initialize environment */ init_baudrate,/* initialze baudrate settings */ serial_init,/* serial communications setup */ console_init_f,/* stage 1 init of console */ display_banner,/* say that we are here */ #if defined(CONFIG_DISPLAY_CPUINFO) print_cpuinfo,/* display cpu info (and speed) */ #endif #if defined(CONFIG_DISPLAY_BOARDINFO) checkboard,/* display board info */ #endif #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) init_func_i2c,#endif dram_init,/* configure available RAM banks */ #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) arm_pci_init,#endif display_dram_config,}; void start_armboot (void) { init_fnc_t **init_fnc_ptr; char *s; #if defined(CONFIG_VFD) || defined(CONFIG_LCD) unsigned long addr; #endif #if defined(CONFIG_MINI2440_LED) struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); #endif /* Pointer is writable since we allocated a register for it */ gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)); /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); memset ((void*)gd,sizeof (gd_t)); gd->bd = (bd_t*)((char*)gd - sizeof(bd_t)); memset (gd->bd,sizeof (bd_t)); gd->flags |= GD_FLG_RELOC; monitor_flash_len = _bss_start - _armboot_start; for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } } /* armboot_start is defined in the board-specific linker script */ mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,CONFIG_SYS_MALLOC_LEN); #ifndef CONFIG_SYS_NO_FLASH /* configure available FLASH banks */ display_flash_config (flash_init ()); #endif /* CONFIG_SYS_NO_FLASH */ #ifdef CONFIG_VFD # ifndef PAGE_SIZE # define PAGE_SIZE 4096 # endif /* * reserve memory for VFD display (always full pages) */ /* bss_end is defined in the board-specific linker script */ addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); vfd_setmem (addr); gd->fb_base = addr; #endif /* CONFIG_VFD */ #ifdef CONFIG_LCD /* board init may have inited fb_base */ if (!gd->fb_base) { # ifndef PAGE_SIZE # define PAGE_SIZE 4096 # endif /* * reserve memory for LCD display (always full pages) */ /* bss_end is defined in the board-specific linker script */ addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); lcd_setmem (addr); gd->fb_base = addr; } #endif /* CONFIG_LCD */ #if defined(CONFIG_CMD_NAND) puts ("NAND: "); nand_init(); /* go init the NAND */ #endif #if defined(CONFIG_CMD_ONENAND) onenand_init(); #endif #ifdef CONFIG_HAS_DATAFLASH AT91F_DataflashInit(); dataflash_print_info(); #endif /* initialize environment */ env_relocate (); #ifdef CONFIG_VFD /* must do this after the framebuffer is allocated */ drv_vfd_init(); #endif /* CONFIG_VFD */ #ifdef CONFIG_SERIAL_MULTI serial_initialize(); #endif /* IP Address */ gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); stdio_init (); /* get the devices list going. */ jumptable_init (); #if defined(CONFIG_API) /* Initialize API */ api_init (); #endif console_init_r (); /* fully init console as a device */ #if defined(CONFIG_ARCH_MISC_INIT) /* miscellaneous arch dependent initialisations */ arch_misc_init (); #endif #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ misc_init_r (); #endif /* enable exceptions */ enable_interrupts (); /* Perform network card initialisation if necessary */ #ifdef CONFIG_DRIVER_TI_EMAC /* XXX: this needs to be moved to board init */ extern void davinci_eth_set_mac_addr (const u_int8_t *addr); if (getenv ("ethaddr")) { uchar enetaddr[6]; eth_getenv_enetaddr("ethaddr",enetaddr); davinci_eth_set_mac_addr(enetaddr); } #endif #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96) /* XXX: this needs to be moved to board init */ if (getenv ("ethaddr")) { uchar enetaddr[6]; eth_getenv_enetaddr("ethaddr",enetaddr); smc_set_mac_addr(enetaddr); } #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ /* Initialize from environment */ if ((s = getenv ("loadaddr")) != NULL) { load_addr = simple_strtoul (s,16); } #if defined(CONFIG_CMD_NET) if ((s = getenv ("bootfile")) != NULL) { copy_filename (BootFile,s,sizeof (BootFile)); } #endif #ifdef BOARD_LATE_INIT board_late_init (); #endif #ifdef CONFIG_GENERIC_MMC puts ("MMC: "); mmc_initialize (gd->bd); #endif #ifdef CONFIG_BITBANGMII bb_miiphy_init(); #endif #if defined(CONFIG_CMD_NET) #if defined(CONFIG_NET_MULTI) puts ("Net: "); #endif eth_initialize(gd->bd); #if defined(CONFIG_RESET_PHY_R) debug ("Reset Ethernet PHYn"); reset_phy(); #endif #endif /****************************lighted led************************************************/ #if defined(CONFIG_MINI2440_LED) gpio->GPBDAT = 0x0; //tekkamanninja #endif #if defined(CONFIG_CFB_CONSOLE) printf ("%sn",version_string); printf ("modified by tekkamanninjan(tekkamanninja@163.com)n"); printf ("Love Linux forever!!n"); #endif /*****************************************************************************/ /* main_loop() can return to retry autoboot,if so just run it again. */ for (;;) { main_loop (); } /* NOTREACHED - no way out of command loop except booting */ } void hang (void) { puts ("### ERROR ### Please RESET the board ###n"); for (;;); }line246,数组init_sequence[]中记录了需遍历执行的许多初始化函数,这些函数分布在不同的文件中 其中有位于uboot/board/tekkamanninja/mini2440/mini2440.c中的board_init函数进行初始化mini2440板子 其中有串口和控制台的初始化函数,串口和控制台初始化之前无法打印信息,可以点亮led帮助调试 一下摘自mini2440之U-boot移植详细手册-20100419.pdf? ch6.4.1 在U-boot 启动的第一阶段,初始化了Nand Flash 控制器。但到第二阶段start_armboot 函数还是会再次初始化Nand Flash 控制器。因为第二阶段和第一阶段的代码基本是独立 的,第一阶段的代码基本只起到代码重定位的作用,到了第二阶段才是真正U-boot 的开始, 以前的初始化过程还会重做一遍,比如始化Nand Flash 控制器、CPU 频率等。 在line 463 初始化完成后进入main_loop (); main_loop函数在uboot/common/main.c中,源码如下 /****************************************************************************/ void main_loop (void) { #ifndef CONFIG_SYS_HUSH_PARSER static char lastcommand[CONFIG_SYS_CBSIZE] = { 0,}; int len; int rc = 1; int flag; #endif #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) char *s; int bootdelay; #endif #ifdef CONFIG_PREBOOT char *p; #endif #ifdef CONFIG_BOOTCOUNT_LIMIT unsigned long bootcount = 0; unsigned long bootlimit = 0; char *bcs; char bcs_set[16]; #endif /* CONFIG_BOOTCOUNT_LIMIT */ #if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO) ulong bmp = 0; /* default bitmap */ extern int trab_vfd (ulong bitmap); #ifdef CONFIG_MODEM_SUPPORT if (do_mdm_init) bmp = 1; /* alternate bitmap */ #endif trab_vfd (bmp); #endif /* CONFIG_VFD && VFD_TEST_LOGO */ #if defined(CONFIG_UPDATE_TFTP) update_tftp (); #endif /* CONFIG_UPDATE_TFTP */ #ifdef CONFIG_BOOTCOUNT_LIMIT bootcount = bootcount_load(); bootcount++; bootcount_store (bootcount); sprintf (bcs_set,"%lu",bootcount); setenv ("bootcount",bcs_set); bcs = getenv ("bootlimit"); bootlimit = bcs ? simple_strtoul (bcs,10) : 0; #endif /* CONFIG_BOOTCOUNT_LIMIT */ #ifdef CONFIG_MODEM_SUPPORT debug ("DEBUG: main_loop: do_mdm_init=%dn",do_mdm_init); if (do_mdm_init) { char *str = strdup(getenv("mdm_cmd")); setenv ("preboot",str); /* set or delete definition */ if (str != NULL) free (str); mdm_init(); /* wait for modem connection */ } #endif /* CONFIG_MODEM_SUPPORT */ #ifdef CONFIG_VERSION_VARIABLE { extern char version_string[]; setenv ("ver",version_string); /* set version variable */ } #endif /* CONFIG_VERSION_VARIABLE */ #ifdef CONFIG_SYS_HUSH_PARSER u_boot_hush_start (); #endif #if defined(CONFIG_HUSH_INIT_VAR) hush_init_var (); #endif #ifdef CONFIG_AUTO_COMPLETE install_auto_complete(); #endif #ifdef CONFIG_PREBOOT if ((p = getenv ("preboot")) != NULL) { # ifdef CONFIG_AUTOBOOT_KEYED int prev = disable_ctrlc(1); /* disable Control C checking */ # endif # ifndef CONFIG_SYS_HUSH_PARSER run_command (p,0); # else parse_string_outer(p,FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); # endif # ifdef CONFIG_AUTOBOOT_KEYED disable_ctrlc(prev); /* restore Control C checking */ # endif } #endif /* CONFIG_PREBOOT */ #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) s = getenv ("bootdelay"); bootdelay = s ? (int)simple_strtol(s,10) : CONFIG_BOOTDELAY; debug ("### main_loop entered: bootdelay=%dnn",bootdelay); # ifdef CONFIG_BOOT_RETRY_TIME init_cmd_timeout (); # endif /* CONFIG_BOOT_RETRY_TIME */ #ifdef CONFIG_POST if (gd->flags & GD_FLG_POSTFAIL) { s = getenv("failbootcmd"); } else #endif /* CONFIG_POST */ #ifdef CONFIG_BOOTCOUNT_LIMIT if (bootlimit && (bootcount > bootlimit)) { printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.n",(unsigned)bootlimit); s = getenv ("altbootcmd"); } else #endif /* CONFIG_BOOTCOUNT_LIMIT */ s = getenv ("bootcmd"); debug ("### main_loop: bootcmd="%s"n",s ? s : "<UNDEFINED>"); if (bootdelay >= 0 && s && !abortboot (bootdelay)) { # ifdef CONFIG_AUTOBOOT_KEYED int prev = disable_ctrlc(1); /* disable Control C checking */ # endif # ifndef CONFIG_SYS_HUSH_PARSER run_command (s,0); # else parse_string_outer(s,FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); # endif # ifdef CONFIG_AUTOBOOT_KEYED disable_ctrlc(prev); /* restore Control C checking */ # endif } # ifdef CONFIG_MENUKEY if (menukey == CONFIG_MENUKEY) { s = getenv("menucmd"); if (s) { # ifndef CONFIG_SYS_HUSH_PARSER run_command (s,FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); # endif } } #endif /* CONFIG_MENUKEY */ #endif /* CONFIG_BOOTDELAY */ #ifdef CONFIG_AMIGAONEG3SE { extern void video_banner(void); video_banner(); } #endif /* * Main Loop for Monitor Command Processing */ #ifdef CONFIG_SYS_HUSH_PARSER parse_file_outer(); /* This point is never reached */ for (;;); #else for (;;) { #ifdef CONFIG_BOOT_RETRY_TIME if (rc >= 0) { /* Saw enough of a valid command to * restart the timeout. */ reset_cmd_timeout(); } #endif len = readline (CONFIG_SYS_PROMPT); flag = 0; /* assume no special flags for now */ if (len > 0) strcpy (lastcommand,console_buffer); else if (len == 0) flag |= CMD_FLAG_REPEAT; #ifdef CONFIG_BOOT_RETRY_TIME else if (len == -2) { /* -2 means timed out,retry autoboot */ puts ("nTimed out waiting for commandn"); # ifdef CONFIG_RESET_TO_RETRY /* Reinit board to run initialization code again */ do_reset (NULL,NULL); # else return; /* retry autoboot */ # endif } #endif if (len == -1) puts ("<INTERRUPT>n"); else rc = run_command (lastcommand,flag); if (rc <= 0) { /* invalid command or not repeatable,forget it */ lastcommand[0] = 0; } } #endif /*CONFIG_SYS_HUSH_PARSER*/ } #ifdef CONFIG_BOOT_RETRY_TIME /***************************************************************************进入类似shell的命令提示符后, 可以输入bootm命令来加载内核, bootm命令实现在common/cmd_boot.c中,具体是: U_BOOT_CMD( bootm,CONFIG_SYS_MAXARGS,1,do_bootm,"boot application image from memory","[addr [arg ...]]n - boot application image stored in memoryn" "tpassing arguments 'arg ...'; when booting a Linux kernel,n" "t'arg' can be the address of an initrd imagen" #if defined(CONFIG_OF_LIBFDT) "tWhen booting a Linux kernel which requires a flat device-treen" "ta third argument is required which is the address of then" "tdevice-tree blob. To boot that kernel without an initrd image,n" "tuse a '-' for the second argument. If you do not pass a thirdn" "ta bd_info struct will be passed insteadn" #endif #if defined(CONFIG_FIT) "tnFor the new multi component uImage format (FIT) addressesn" "tmust be extened to include component or configuration unit name:n" "taddr:<subimg_uname> - direct component image specificationn" "taddr#<conf_uname> - configuration specificationn" "tUse iminfo command to get the list of existing componentn" "timages and configurations.n" #endif "nSub-commands to do part of the bootm sequence. The sub-commands " "must ben" "issued in the order below (it's ok to not issue all sub-commands):n" "tstart [addr [arg ...]]n" "tloados - load OS imagen" #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) "tramdisk - relocate initrd,set env initrd_start/initrd_endn" #endif #if defined(CONFIG_OF_LIBFDT) "tfdt - relocate flat device treen" #endif "tcmdline - OS specific command line processing/setupn" "tbdt - OS specific bd_t processingn" "tprep - OS specific prep before relocation or gon" "tgo - start OS" ); /*******************************************************************/ /* bootd - boot default image */ /*******************************************************************/ #if defined(CONFIG_CMD_BOOTD)bootm会调用do_bootm()函数---->调用lib_arm/bootm.c中的do_bootm_linux()函数---->调用theKernel (0,machid,bd->bi_boot_params);最终载入内核 其中, 流程如下 发现在console_init_f初始化串口之前执行printk会使uboot死掉 在调用thekernel之前会打印一行(也是在do_bootm_linux()函数里): /* we assume that the kernel is in place */ printf ("nStarting kernel ...nn"); uboot/board/board/tekkamanninja/mini2440/mini2440.c是在第二阶段执行的文件,用于初始化mini2440板子 /* * (C) Copyright 2002 * Sysgo Real-Time Solutions,GmbH <www.elinos.com> * Marius Groeger <mgroeger@sysgo.de> * * (C) Copyright 2002 * David Mueller,ELSOFT AG,<d.mueller@elsoft.ch> * * (C) Copyright 2005 * JinHua Luo,GuangDong Linux Center,<luo.jinhua@gd-linux.com> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License,* MA 02111-1307 USA */ #include <common.h> #include <netdev.h> #include <s3c2410.h> #include <video_fb.h> #if defined(CONFIG_CMD_NAND) #include <linux/mtd/nand.h> #endif DECLARE_GLOBAL_DATA_PTR; #define FCLK_SPEED 1 #if FCLK_SPEED==0 /* Fout = 203MHz,Fin = 12MHz for Audio */ #define M_MDIV 0xC3 #define M_PDIV 0x4 #define M_SDIV 0x1 #elif FCLK_SPEED==1 /* Fout = 202.8MHz */ #if defined(CONFIG_S3C2410) /* Fout = 202.8MHz */ #define M_MDIV 0xA1 #define M_PDIV 0x3 #define M_SDIV 0x1 #endif #if defined(CONFIG_S3C2440) /* Fout = 405MHz */ #define M_MDIV 0x7f #define M_PDIV 0x2 #define M_SDIV 0x1 #endif #endif #define USB_CLOCK 1 #if USB_CLOCK==0 #define U_M_MDIV 0xA1 #define U_M_PDIV 0x3 #define U_M_SDIV 0x1 #elif USB_CLOCK==1 #if defined(CONFIG_S3C2410) #define U_M_MDIV 0x48 #define U_M_PDIV 0x3 #endif #if defined(CONFIG_S3C2440) #define U_M_MDIV 0x38 #define U_M_PDIV 0x2 #endif #define U_M_SDIV 0x2 #endif static inline void delay (unsigned long loops) { __asm__ volatile ("1:n" "subs %0,%1,#1n" "bne 1b":"=r" (loops):"0" (loops)); } /* * Miscellaneous platform dependent initialisations */ int board_init (void) { struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power(); struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); /* to reduce PLL lock time,adjust the LOCKTIME register */ clk_power->LOCKTIME = 0xFFFFFF; /* configure MPLL */ clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV); /* some delay between MPLL and UPLL */ delay (4000); /* configure UPLL */ clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV); /* some delay between MPLL and UPLL */ delay (8000); /* set up the I/O ports */ /* set up the I/O ports */ gpio->GPACON = 0x007FFFFF; #if defined(CONFIG_MINI2440) gpio->GPBCON = 0x00295551; #else gpio->GPBCON = 0x00044556; #endif gpio->GPBUP = 0x000007FF; #if defined(CONFIG_MINI2440) gpio->GPCCON = 0xAAAAA6AA; gpio->GPCDAT &= ~(1<<5); #else gpio->GPCCON = 0xAAAAAAAA; #endif gpio->GPCUP = 0x0000FFFF; gpio->GPDCON = 0xAAAAAAAA; gpio->GPDUP = 0xFFFFFFFF; gpio->GPECON = 0xAAAAAAAA; gpio->GPEUP = 0x0000FFFF; gpio->GPFCON = 0x000055AA; gpio->GPFUP = 0x000000FF; gpio->GPGCON = 0xFF95FF3A; gpio->GPGUP = 0x0000FFFF; gpio->GPHCON = 0x0016FAAA; gpio->GPHUP = 0x000007FF; gpio->EXTINT0=0x22222222; gpio->EXTINT1=0x22222222; gpio->EXTINT2=0x22222222; /* arch number of SMDK2410-Board */ #if defined(CONFIG_S3C2410) /* arch number of SMDK2410-Board */ gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; #endif #if defined(CONFIG_S3C2440) /* arch number of S3C2440-Board */ gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;//defined in include/asm/mach-types.h,is 1999 #endif /* adress of boot parameters */ gd->bd->bi_boot_params = 0x30000100; icache_enable(); dcache_enable(); #if defined(CONFIG_MINI2440_LED) gpio->GPBDAT = 0x00000181; #endif return 0; } /************************************video add by song*****************************************************/ #define MVAL (0) #define MVAL_USED (0) //0=each frame 1=rate by MVAL #define INVVDEN (1) //0=normal 1=inverted #define BSWP (0) //Byte swap control #define HWSWP (1) //Half word swap control //TFT 240320 #define LCD_XSIZE_TFT_240320 (240) #define LCD_YSIZE_TFT_240320 (320) //TFT240320 #define HOZVAL_TFT_240320 (LCD_XSIZE_TFT_240320-1) #define LINEVAL_TFT_240320 (LCD_YSIZE_TFT_240320-1) //Timing parameter for NEC3.5" #define VBPD_240320 (3) #define VFPD_240320 (10) #define VSPW_240320 (1) #define HBPD_240320 (5) #define HFPD_240320 (2) #define HSPW_240320_NEC (36) //Adjust the horizontal displacement of the screen :tekkamanninja@163.com #define HSPW_240320_TD (23) //64MB nand mini2440 is 36,128MB is 23 //+ : --> - : <-- #define CLKVAL_TFT_240320 (3) //FCLK=101.25MHz,HCLK=50.625MHz,VCLK=6.33MHz void board_video_init(GraphicDevice *pGD) { struct s3c24x0_lcd * const lcd = s3c24x0_get_base_lcd(); struct s3c2410_nand * const nand = s3c2410_get_base_nand(); /* FIXME: select LCM type by env variable */ /* Configuration for GTA01 LCM on QT2410 */ lcd->LCDCON1 = 0x00000378; /* CLKVAL=4,BPPMODE=16bpp,TFT,ENVID=0 */ lcd->LCDCON2 = (VBPD_240320<<24)|(LINEVAL_TFT_240320<<14)|(VFPD_240320<<6)|(VSPW_240320); lcd->LCDCON3 = (HBPD_240320<<19)|(HOZVAL_TFT_240320<<8)|(HFPD_240320); if ( (nand->NFCONF) & 0x08 ) { lcd->LCDCON4 = (MVAL<<8)|(HSPW_240320_TD); } else { lcd->LCDCON4 = (MVAL<<8)|(HSPW_240320_NEC); } lcd->LCDCON5 = 0x00000f09; lcd->LPCSEL = 0x00000000; } /************************************video add by song*****************************************************/ int dram_init (void) { gd->bd->bi_dram[0].start = PHYS_SDRAM_1; gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; return 0; } #if 0 #if defined(CONFIG_CMD_NAND) extern ulong nand_probe(ulong physadr); static inline void NF_Reset(void) { int i; NF_SetCE(NFCE_LOW); NF_Cmd(0xFF); /* reset command */ for(i = 0; i < 10; i++); /* tWB = 100ns. */ NF_WaitRB(); /* wait 200~500us; */ NF_SetCE(NFCE_HIGH); } static inline void NF_Init(void) { #if 1 #define TACLS 0 #define TWRPH0 3 #define TWRPH1 0 #else #define TACLS 0 #define TWRPH0 4 #define TWRPH1 2 #endif NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0)); /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */ /* 1 1 1 1,1 xxx,r xxx,r xxx */ /* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */ NF_Reset(); } void nand_init(void) { struct s3c2410_nand * const nand = s3c2410_get_base_nand(); NF_Init(); #ifdef DEBUG printf("NAND flash probing at 0x%.8lXn",(ulong)nand); #endif printf ("%4lu MBn",nand_probe((ulong)nand) >> 20); } #endif #endif #ifdef CONFIG_CMD_NET int board_eth_init(bd_t *bis) { int rc = 0; #ifdef CONFIG_CS8900 rc = cs8900_initialize(0,CONFIG_CS8900_BASE); #endif #ifdef CONFIG_DRIVER_DM9000 rc = dm9000_initialize(bis); #endif return rc; } #endif (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |