uboot移植之uboot stage2

来源:互联网 发布:天天向上网络作家专场 编辑:程序博客网 时间:2024/05/01 23:11
从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"#endifDECLARE_GLOBAL_DATA_PTR;ulong monitor_flash_len;#ifdef CONFIG_HAS_DATAFLASHextern int  AT91F_DataflashInit(void);extern void dataflash_print_info(void);#endif#ifndef CONFIG_IDENT_STRING#define CONFIG_IDENT_STRING ""#endifconst char version_string[] =U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING;#ifdef CONFIG_DRIVER_RTL8019extern 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#endifstatic 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#endifprintf ("\n\n%s\n\n", version_string);printf ("Love Linux forever!!\n\n");debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",       _armboot_start, _bss_start, _bss_end);#ifdef CONFIG_MODEM_SUPPORTdebug ("Modem Support enabled\n");#endif#ifdef CONFIG_USE_IRQdebug ("IRQ Stack: %08lx\n", IRQ_STACK_START);debug ("FIQ Stack: %08lx\n", FIQ_STACK_START);#endifreturn (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 DEBUGputs ("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");}#elseulong size = 0;for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {size += gd->bd->bi_dram[i].size;}puts("DRAM:  ");print_size(size, "\n");#endifreturn (0);}#ifndef CONFIG_SYS_NO_FLASHstatic 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 ("ready\n");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 */#endifboard_init,/* basic board dependent setup */#if defined(CONFIG_USE_IRQ)interrupt_init,/* set up exceptions */#endiftimer_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,#endifdram_init,/* configure available RAM banks */#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)arm_pci_init,#endifdisplay_dram_config,NULL,};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, 0, sizeof (gd_t));gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));memset (gd->bd, 0, 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_DATAFLASHAT91F_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_MULTIserial_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 ();#endifconsole_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, NULL, 16);}#if defined(CONFIG_CMD_NET)if ((s = getenv ("bootfile")) != NULL) {copy_filename (BootFile, s, sizeof (BootFile));}#endif#ifdef BOARD_LATE_INITboard_late_init ();#endif#ifdef CONFIG_GENERIC_MMCputs ("MMC:   ");mmc_initialize (gd->bd);#endif#ifdef CONFIG_BITBANGMIIbb_miiphy_init();#endif#if defined(CONFIG_CMD_NET)#if defined(CONFIG_NET_MULTI)puts ("Net:   ");#endifeth_initialize(gd->bd);#if defined(CONFIG_RESET_PHY_R)debug ("Reset Ethernet PHY\n");reset_phy();#endif#endif/****************************lighted led************************************************/#if defined(CONFIG_MINI2440_LED) gpio->GPBDAT = 0x0; //tekkamanninja#endif #if defined(CONFIG_CFB_CONSOLE)        printf ("%s\n", version_string);printf ("modified by tekkamanninja\n(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_PARSERstatic 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_PREBOOTchar *p;#endif#ifdef CONFIG_BOOTCOUNT_LIMITunsigned 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_SUPPORTif (do_mdm_init)bmp = 1;/* alternate bitmap */#endiftrab_vfd (bmp);#endif/* CONFIG_VFD && VFD_TEST_LOGO */#if defined(CONFIG_UPDATE_TFTP)update_tftp ();#endif /* CONFIG_UPDATE_TFTP */#ifdef CONFIG_BOOTCOUNT_LIMITbootcount = bootcount_load();bootcount++;bootcount_store (bootcount);sprintf (bcs_set, "%lu", bootcount);setenv ("bootcount", bcs_set);bcs = getenv ("bootlimit");bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0;#endif /* CONFIG_BOOTCOUNT_LIMIT */#ifdef CONFIG_MODEM_SUPPORTdebug ("DEBUG: main_loop:   do_mdm_init=%d\n", 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_PARSERu_boot_hush_start ();#endif#if defined(CONFIG_HUSH_INIT_VAR)hush_init_var ();#endif#ifdef CONFIG_AUTO_COMPLETEinstall_auto_complete();#endif#ifdef CONFIG_PREBOOTif ((p = getenv ("preboot")) != NULL) {# ifdef CONFIG_AUTOBOOT_KEYEDint prev = disable_ctrlc(1);/* disable Control C checking */# endif# ifndef CONFIG_SYS_HUSH_PARSERrun_command (p, 0);# elseparse_string_outer(p, FLAG_PARSE_SEMICOLON |    FLAG_EXIT_FROM_LOOP);# endif# ifdef CONFIG_AUTOBOOT_KEYEDdisable_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, NULL, 10) : CONFIG_BOOTDELAY;debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);# ifdef CONFIG_BOOT_RETRY_TIMEinit_cmd_timeout ();# endif/* CONFIG_BOOT_RETRY_TIME */#ifdef CONFIG_POSTif (gd->flags & GD_FLG_POSTFAIL) {s = getenv("failbootcmd");}else#endif /* CONFIG_POST */#ifdef CONFIG_BOOTCOUNT_LIMITif (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_KEYEDint prev = disable_ctrlc(1);/* disable Control C checking */# endif# ifndef CONFIG_SYS_HUSH_PARSERrun_command (s, 0);# elseparse_string_outer(s, FLAG_PARSE_SEMICOLON |    FLAG_EXIT_FROM_LOOP);# endif# ifdef CONFIG_AUTOBOOT_KEYEDdisable_ctrlc(prev);/* restore Control C checking */# endif}# ifdef CONFIG_MENUKEYif (menukey == CONFIG_MENUKEY) {    s = getenv("menucmd");    if (s) {# ifndef CONFIG_SYS_HUSH_PARSERrun_command (s, 0);# elseparse_string_outer(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_PARSERparse_file_outer();/* This point is never reached */for (;;);#elsefor (;;) {#ifdef CONFIG_BOOT_RETRY_TIMEif (rc >= 0) {/* Saw enough of a valid command to * restart the timeout. */reset_cmd_timeout();}#endiflen = 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_TIMEelse if (len == -2) {/* -2 means timed out, retry autoboot */puts ("\nTimed out waiting for command\n");# ifdef CONFIG_RESET_TO_RETRY/* Reinit board to run initialization code again */do_reset (NULL, 0, 0, NULL);# elsereturn;/* retry autoboot */# endif}#endifif (len == -1)puts ("<INTERRUPT>\n");elserc = 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 memory\n""\tpassing arguments 'arg ...'; when booting a Linux kernel,\n""\t'arg' can be the address of an initrd image\n"#if defined(CONFIG_OF_LIBFDT)"\tWhen booting a Linux kernel which requires a flat device-tree\n""\ta third argument is required which is the address of the\n""\tdevice-tree blob. To boot that kernel without an initrd image,\n""\tuse a '-' for the second argument. If you do not pass a third\n""\ta bd_info struct will be passed instead\n"#endif#if defined(CONFIG_FIT)"\t\nFor the new multi component uImage format (FIT) addresses\n""\tmust be extened to include component or configuration unit name:\n""\taddr:<subimg_uname> - direct component image specification\n""\taddr#<conf_uname>   - configuration specification\n""\tUse iminfo command to get the list of existing component\n""\timages and configurations.\n"#endif"\nSub-commands to do part of the bootm sequence.  The sub-commands ""must be\n""issued in the order below (it's ok to not issue all sub-commands):\n""\tstart [addr [arg ...]]\n""\tloados  - load OS image\n"#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)"\tramdisk - relocate initrd, set env initrd_start/initrd_end\n"#endif#if defined(CONFIG_OF_LIBFDT)"\tfdt     - relocate flat device tree\n"#endif"\tcmdline - OS specific command line processing/setup\n""\tbdt     - OS specific bd_t processing\n""\tprep    - OS specific prep before relocation or go\n""\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);最终载入内核

其中,
machid即设定的板子id,MRCH_TYPE_MINI2440

bd->bi_boot_params即传递给内的参数列表在sdram上存放的位置,为30000100
流程如下

发现在console_init_f初始化串口之前执行printk会使uboot死掉

在调用thekernel之前会打印一行(也是在do_bootm_linux()函数里):
/* we assume that the kernel is in place */
printf ("\nStarting kernel ...\n\n");

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, 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 */#include <common.h>#include <netdev.h>#include <s3c2410.h>#include <video_fb.h>#if defined(CONFIG_CMD_NAND)#include <linux/mtd/nand.h>#endifDECLARE_GLOBAL_DATA_PTR;#define FCLK_SPEED 1#if FCLK_SPEED==0/* Fout = 203MHz, Fin = 12MHz for Audio */#define M_MDIV0xC3#define M_PDIV0x4#define M_SDIV0x1#elif FCLK_SPEED==1/* Fout = 202.8MHz */#if defined(CONFIG_S3C2410)/* Fout = 202.8MHz */#define M_MDIV0xA1#define M_PDIV0x3#define M_SDIV0x1#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_MDIV0xA1#define U_M_PDIV0x3#define U_M_SDIV0x1#elif USB_CLOCK==1#if defined(CONFIG_S3C2410)#define U_M_MDIV0x48#define U_M_PDIV0x3#endif#if defined(CONFIG_S3C2440)#define U_M_MDIV 0x38#define U_M_PDIV 0x2#endif#define U_M_SDIV0x2#endifstatic inline void delay (unsigned long loops){__asm__ volatile ("1:\n"  "subs %0, %1, #1\n"  "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;#elsegpio->GPBCON = 0x00044556;#endifgpio->GPBUP = 0x000007FF;#if defined(CONFIG_MINI2440) gpio->GPCCON = 0xAAAAA6AA;gpio->GPCDAT &= ~(1<<5);#elsegpio->GPCCON = 0xAAAAAAAA;#endifgpio->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();#ifdefined(CONFIG_MINI2440_LED)gpio->GPBDAT = 0x00000181;#endifreturn 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.33MHzvoid 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#endifNF_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 DEBUGprintf("NAND flash probing at 0x%.8lX\n", (ulong)nand);#endifprintf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);}#endif#endif#ifdef CONFIG_CMD_NETint board_eth_init(bd_t *bis){int rc = 0;#ifdef CONFIG_CS8900rc = cs8900_initialize(0, CONFIG_CS8900_BASE);#endif#ifdef CONFIG_DRIVER_DM9000rc = dm9000_initialize(bis);#endifreturn rc;}#endif