Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2275842
  • 博文数量: 668
  • 博客积分: 10016
  • 博客等级: 上将
  • 技术积分: 8588
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-29 19:22
文章分类

全部博文(668)

文章存档

2011年(1)

2010年(2)

2009年(273)

2008年(392)

分类:

2009-05-04 18:02:05


/*
 * linux/arch/arm/mach-davinci/board-evm.c
 *
 * TI DaVinci EVM board
 *
 * Copyright (C) 2006 Texas Instruments.
 *
 * ----------------------------------------------------------------------------
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 * ----------------------------------------------------------------------------
 *
 */

/**************************************************************************
 * Included Files
 **************************************************************************/

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/root_dev.h>
#include <linux/dma-mapping.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/serial.h>
#include <linux/usb_musb.h>
#include <linux/mtd/nand.h>
#include <linux/serial_8250.h>
#include <linux/davinci_mmc.h>
#include <linux/nand_davinci.h>

#include <asm/setup.h>
#include <asm/io.h>
#include <asm/mach-types.h>

#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <asm/arch/irqs.h>
#include <asm/arch/hardware.h>
#include <asm/arch/edma.h>
#include <linux/kgdb.h>
#include <asm/arch/cpu.h>
#include <asm/arch/mux.h>
#include "clock.h"

/* 
内核在启动的时候会运行start_kernel() , 然后它会调用体系结构相关的setup_arch(&command_line), arm体系结构在arch/arm/kernel/setup.c中, 接着初始化平台相关的设备, 但在此之前, 它必须找到这块目标板的描述结构, 所以它会先通过setup_machine,其调用lookup_machine_type(nr)来查找这个结构, 参数是由u-boot传进来的, 存储在r2中. 假设它传入的是DAVINCI_EVM的nr, lookup_machine_type(nr) 就会找到本文件中到最后定义的结构体machine_desc. 
start_kernel之前的linux内核启动的详细过程,可参考该文章http://blog.csdn.net/gates84/archive/2007/01/15/1483979.aspx
*/


/**************************************************************************
 * Definitions
 **************************************************************************/
#define DAVINCI_UART_CLK        27000000    // 串口时钟,与输入的晶振频率相同

/* 
* dm644x平台采用8250兼容串口,该数据结构定义了串口的硬件资源,将填充在其platform_device结构体中,
* 即下面的serial_device中。在该platform_devic被注册后,如果其相关的驱动被注册,则会自动找到它,
* 并可调用其中的资源。plat_serial8250_port定义在include/linux/serial_8250.h文件中
*/
static struct plat_serial8250_port serial_platform_data[] = {
    {
        .membase    = (char *)IO_ADDRESS(DAVINCI_UART0_BASE),    // 串口0寄存器开始处的虚拟地址是IO_ADDRESS(0x01C20000)
        .mapbase    = (unsigned long)DAVINCI_UART0_BASE,        // 串口0寄存器开始处的实地址是0x01C20000
        .irq        = IRQ_UARTINT0,                                // 串口0的中断号是40
        .flags        = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
        .iotype        = UPIO_MEM32,
        .regshift    = 2,
        .uartclk    = DAVINCI_UART_CLK,                            // 串口时钟频率是27MHz
    },
    {
        .flags    = 0,
    },
};

/* 见上述解释。platform_device定义在include/linux/device.h文件中
* 一般platform_device在系统启动的时候就注册了,而其相应到驱动platform_driver或device_driver可在模块中加载。
* http://hi.baidu.com/zengzhaonong/blog/item/440bb91e57e5251a413417d9.html 有关于platform_device结构体的详细解释
*/
static struct platform_device serial_device    = {
    .name            = "serial8250",        // 这个名字很重要,与对应驱动中的机构体device_driver中的.name相同,其被驱动模块用来查找设备
    .id            = 0,                    // 实例名后缀为0
    .dev            = {
        .platform_data    = serial_platform_data,        // 设备的私有数据或资源
    },
};

/* 该数据结构定义了USB的私有数据,主要是usb的类型和功能,musb_hdrc_platform_data定义在include/linux/device.h文件中 */
static struct musb_hdrc_platform_data usb_data[] = {
    {
#if defined(CONFIG_USB_MUSB_OTG)
        /* OTG requires a Mini-AB connector */
        .mode        = MUSB_OTG,                    // OTG类型的usb模块,既可以作usb设备也可以作主机usb使用
#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
        .mode        = MUSB_PERIPHERAL,
#elif defined(CONFIG_USB_MUSB_HOST)                // usb设备
        .mode        = MUSB_HOST,                // 主机usb,类似于电脑的usb功能
#endif
        .set_vbus    = NULL,
        /* irlml6401 switches 5V */
        .power        = 255, /* sustains 3.0+ Amps (!) */
        .potpgt        = 4, /* ~8 msec */
        .multipoint    = 1,                        // 1个收发端口
    },        /* Need Multipoint support */
};

/* 该数据结构定义了USB的硬件资源, resource定义在include/linux/ioport.h文件中 */
static struct resource usb_resources[] = {
    {
        /* physical address */
        .start        = DAVINCI_USB_OTG_BASE,            // USB_OTG寄存器起始处的实地址是0x01C20000
        .end        = DAVINCI_USB_OTG_BASE + 0x5ff,    // USB_OTG寄存器末尾处的实地址是0x01C20000
        .flags        = IORESOURCE_MEM,                // 标识为IO地址资源
    },
    {
        .start        = IRQ_USBINT,                    // USB_OTG中断号是12
        .flags        = IORESOURCE_IRQ,                // 标识为中断资源
    },
};

static u64 usb_dmamask = DMA_32BIT_MASK;

/* usb的platform_device结构体,用于注册usb设备*/
static struct platform_device usb_dev = {
    .name        = "musb_hdrc",                    // 与对应驱动中的名字相同,用于绑定驱动    
    .id        = -1,                                // -1表示只有一个实例,无数字后缀
    .dev        = {
        .platform_data = usb_data,                // USB的私有数据
        .dma_mask = &usb_dmamask,                // 32位的dma
        .coherent_dma_mask = DMA_32BIT_MASK,
    },
    .resource    = usb_resources,                // USB的硬件资源
    .num_resources    = ARRAY_SIZE(usb_resources),
};

/* 返回cpu的类型:DaVinci EVM*/
/**************************************************************************
 * Public Functions
 **************************************************************************/
int cpu_type(void)
{
    return MACH_TYPE_DAVINCI_EVM;
}

/* 串口初始化,主要的工作是打开串口时钟,定义在arch/arm/mach-davinci/serial.c文件中*/
extern void davinci_serial_init(struct platform_device *pdev);

/*如果在menuconfig中配置了使用nand启动系统,则下面的的代码将会被编译。
* mtd_partition定义在include/linux/mtd/partitions.h文件中
*/
#if defined (CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
static struct mtd_partition nand_partitions[] = {
    /* bootloader (U-Boot, etc) in first sector */
    {
        .name        = "bootloader",            // bootloader,一般使用u-boot
        .offset        = 0,                    // 从mtd分区开始地址的偏移量是0
        .size        = SZ_256K,                // 分区大小是256K
        .mask_flags    = 0,    /* force read-only */    // 只读
    },
    /* bootloader params in the next sector */
    {    
        .name        = "params",                // 存放bootloader的参数
        .offset        = MTDPART_OFS_APPEND,    // 从上一分区(bootloader分区)开始
        .size        = SZ_128K,                
        .mask_flags    = MTD_WRITEABLE,    /* force read-only */    // 可写
    },
    /* kernel */
    {
        .name        = "kernel",                // 存放内核
        .offset        = MTDPART_OFS_APPEND,
        .size        = SZ_4M,
        .mask_flags    = 0,
    },
    /* file system */
    {
        .name        = "filesystem",            // 存放文件系统
        .offset        = MTDPART_OFS_APPEND,
        .size        = MTDPART_SIZ_FULL,        // 整个分区的剩余存储空间
        .mask_flags    = 0,
    }
};

/* nand platform device 私有数据,用于描述nand flash banks
* nand_davinci_platform_data定义在include/linux/nand_davinci.h文件中
*/
static struct nand_davinci_platform_data nand_data = {
    .options        = 0,                
    .eccmode        = NAND_ECC_HW3_512,        // 校验模式
    .cle_mask        = 0x10,
    .ale_mask        = 0x08,
    .bbt_td            = NULL,
    .bbt_md            = NULL,
    .parts            = nand_partitions,        // 分区信息
    .nr_parts        = ARRAY_SIZE(nand_partitions),
};

/* 定义了nand设备使用的硬件资源 */
static struct resource nand_resources[]        = {
    [0] = {        /* First memory resource is AEMIF control registers */
        .start        = DM644X_ASYNC_EMIF_CNTRL_BASE,
        .end        = DM644X_ASYNC_EMIF_CNTRL_BASE + SZ_4K - 1,
        .flags        = IORESOURCE_MEM,
    },
    [1] = {        /* Second memory resource is NAND I/O window */
        .start        = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
        .end        = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16K - 1,
        .flags        = IORESOURCE_MEM,
    },
};



/* nand platform_device ,用于注册nand device到platform总线 */
static struct platform_device nand_device = {
    .name            = "nand_davinci",
    .id            = 0,
    .dev            = {
        .platform_data    = &nand_data,
    },

    .num_resources        = ARRAY_SIZE(nand_resources),
    .resource        = nand_resources,
};
#endif

/*如果在menuconfig中配置了使用nor启动系统,则下面的的代码将会被编译。
* mtd_partition定义在include/linux/mtd/partitions.h文件中
*/
#if defined (CONFIG_MTD_DAVINCI_NOR) || defined(CONFIG_MTD_DAVINCI_NOR_MODULE)
static struct mtd_partition davinci_evm_nor_partitions[] = {
    /* bootloader (U-Boot, etc) in first sector */
     {
         .name             = "bootloader",
         .offset             = 0,
         .size             = SZ_128K,
         .mask_flags         = 0
     },
     /* bootloader params in the next sector */
     {
         .name             = "params",
         .offset             = MTDPART_OFS_APPEND,
         .size             = SZ_128K,
         .mask_flags         = MTD_WRITEABLE, /* force read-only */
     },
     /* kernel */
     {
         .name             = "kernel",
         .offset             = MTDPART_OFS_APPEND,
         .size             = SZ_4M,
         .mask_flags         = 0
     },
     /*cramfs file system */
     {
         .name             = "cramfs",
         .offset             = MTDPART_OFS_APPEND,
         .size             = SZ_2M,
         .mask_flags         = 0
     },
     /* jffs2 file system */
     {
         .name             = "jffs2",        // jffs2文件分区
         .offset             = MTDPART_OFS_APPEND,
         .size             = MTDPART_SIZ_FULL,
         .mask_flags         = 0
     }
};

/* nor platform device 私有数据,用于描述nor flash banks
* flash_platform_data定义在include/asm-arm/mach/flash.h文件中
*/
static struct flash_platform_data davinci_evm_flash_data = {
    .map_name        = "cfi_probe",
    .width            = 2,
    .parts            = davinci_evm_nor_partitions,
    .nr_parts        = ARRAY_SIZE(davinci_evm_nor_partitions),
};

/* 定义了nor设备使用的硬件资源 */
/* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
 ;* limits addresses to 16M, so using addresses past 16M will wrap */
static struct resource davinci_evm_flash_resource = {
    .start            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
    .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
    .flags            = IORESOURCE_MEM,
};

/* nor platform_device ,用于注册nor device到platform总线 */
static struct platform_device davinci_evm_flash_device = {
    .name            = "nor_davinci",
    .id            = 0,
    .dev            = {
        .platform_data    = &davinci_evm_flash_data,
    },

    .num_resources        = 1,
    .resource        = &davinci_evm_flash_resource,
};
#endif

/* 定义了mmc设备使用的硬件资源 */
#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
static struct resource mmc0_resources[] = {
    [0] = {            /* registers */            // 寄存器
        .start        = DAVINCI_MMC_SD_BASE,
        .end        = DAVINCI_MMC_SD_BASE + SZ_1K - 1,
        .flags        = IORESOURCE_MEM,
    },
    [1] = {            /* interrupt */            // 中断号
        .start        = IRQ_MMCINT,
        .end        = IRQ_MMCINT,
        .flags        = IORESOURCE_IRQ,
    },
    [2] = {            /* dma rx */            // dma 接收寄存器
        .start        = DAVINCI_DMA_MMCRXEVT,
        .end        = DAVINCI_DMA_MMCRXEVT,
        .flags        = IORESOURCE_DMA,
    },
    [3] = {            /* dma tx */            // dma 发送寄存器
        .start        = DAVINCI_DMA_MMCTXEVT,
        .end        = DAVINCI_DMA_MMCTXEVT,
        .flags        = IORESOURCE_DMA,
    },
};

/* mmc platform device 私有数据,用于描述mmc flash banks
* davinci_mmc_platform_data定义在include/linux/davinci_mmc.h文件中
*/
static struct davinci_mmc_platform_data mmc0_platform_data = {
    .mmc_clk        = "MMCSDCLK0",        //     用于获mmc取时钟
    .rw_threshold        = 32,
    .use_4bit_mode        = 1,
};

/* mmc platform_device ,用于注册mmc0_device到platform总线 */
static struct platform_device mmc0_device = {
    .name            = "mmc",
    .id            = 0,
    .dev            = {
        .platform_data    = &mmc0_platform_data,
    },

    .num_resources        = ARRAY_SIZE(mmc0_resources),
    .resource        = mmc0_resources,
};

/* 开启mmc模块的电源*/
static void setup_mmc(void)
{
    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_MMC_SD0, 1);
}
#else
#define setup_mmc()
#endif

/* platform_device指针数组 */
static struct platform_device *davinci_evm_devices[] __initdata = {
    &serial_device,
    &usb_dev,
#if defined (CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
    &nand_device,
#endif

#if defined (CONFIG_MTD_DAVINCI_NOR) || defined(CONFIG_MTD_DAVINCI_NOR_MODULE)
    &davinci_evm_flash_device,
#endif

#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
    &mmc0_device,
#endif
};

/* 用于设置fiq,irq 的优先级*/
/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
    [IRQ_VDINT0]        = 2,
    [IRQ_VDINT1]        = 6,
    [IRQ_VDINT2]        = 6,
    [IRQ_HISTINT]        = 6,
    [IRQ_H3AINT]        = 6,
    [IRQ_PRVUINT]        = 6,
    [IRQ_RSZINT]        = 6,
    [IRQ_VFOCINT]        = 7,
    [IRQ_VENCINT]        = 6,
    [IRQ_ASQINT]        = 6,
    [IRQ_IMXINT]        = 6,
    [IRQ_VLCDINT]        = 6,
    [IRQ_USBINT]        = 4,
    [IRQ_EMACINT]        = 4,
    [IRQ_IEEE1394INT]    = 7,
    [IRQ_IEEE1394WK]    = 7,
    [IRQ_CCINT0]        = 5,    /* dma */
    [IRQ_CCERRINT]        = 5,    /* dma */
    [IRQ_TCERRINT0]        = 5,    /* dma */
    [IRQ_TCERRINT]        = 5,    /* dma */
    [IRQ_PSCINT]        = 7,
    [21]            = 7,
    [IRQ_IDE]        = 4,
    [IRQ_HPIINT]        = 7,
    [IRQ_MBXINT]        = 7,
    [IRQ_MBRINT]        = 7,
    [IRQ_MMCINT]        = 7,
    [IRQ_SDIOINT]        = 7,
    [IRQ_HPIINT]        = 7,
    [IRQ_DDRINT]        = 7,
    [IRQ_AEMIFINT]        = 7,
    [IRQ_VLQINT]        = 4,
    [IRQ_TINT0_TINT12]    = 2,    /* clockevent */
    [IRQ_TINT0_TINT34]    = 2,    /* clocksource */
    [IRQ_TINT1_TINT12]    = 7,    /* DSP timer */
    [IRQ_TINT1_TINT34]    = 7,    /* system tick */
    [IRQ_PWMINT0]        = 7,
    [IRQ_PWMINT1]        = 7,
    [IRQ_PWMINT2]        = 7,
    [IRQ_I2C]        = 3,
    [IRQ_UARTINT0]        = 3,
    [IRQ_UARTINT1]        = 3,
    [IRQ_UARTINT2]        = 3,
    [IRQ_SPINT0]        = 3,
    [IRQ_SPINT1]        = 3,
    [45]            = 7,
    [IRQ_DSP2ARM0]        = 4,
    [IRQ_DSP2ARM1]        = 4,
    [IRQ_GPIO0]        = 7,
    [IRQ_GPIO1]        = 7,
    [IRQ_GPIO2]        = 7,
    [IRQ_GPIO3]        = 7,
    [IRQ_GPIO4]        = 7,
    [IRQ_GPIO5]        = 7,
    [IRQ_GPIO6]        = 7,
    [IRQ_GPIO7]        = 7,
    [IRQ_GPIOBNK0]        = 7,
    [IRQ_GPIOBNK1]        = 7,
    [IRQ_GPIOBNK2]        = 7,
    [IRQ_GPIOBNK3]        = 7,
    [IRQ_GPIOBNK4]        = 7,
    [IRQ_COMMTX]        = 7,
    [IRQ_COMMRX]        = 7,
    [IRQ_EMUINT]        = 7,
};

/* davinci平台初始化,主要是开启各模块到电源。dm644x平台到电源管理是分模块到,不使用到时候关掉,可降低功耗。
* 所以需要使用哪个模块,必须在程序中打开,打开后才能设置相应的寄存器。
*/
static void board_init(void)
{
    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VLYNQ, 1);        

    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSMSTR, 1);    
    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSSLV, 1);
    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPCC, 1);
    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC0, 1);
    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC1, 1);
    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1);

    /* Turn on WatchDog timer LPSC. Needed for RESET to work */
    board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);

    davinci_serial_init(&serial_device);    // 初始化串口
}

/* dm644x平台许多功能模块到引脚是gpio复用到,功能引脚和gpio脚是互斥的 ,
* 该函数用来设置这些引脚.
*/
static void dm644x_setup_pinmux(unsigned int id)
{
    switch (id) {
    case DAVINCI_LPSC_ATA:
        davinci_cfg_reg(DM644X_HDIREN);
        davinci_cfg_reg(DM644X_ATAEN);
        break;
    case DAVINCI_LPSC_MMC_SD0:
        /* VDD power manipulations are done in U-Boot for CPMAC
        * so applies to MMC as well
        */
        /*Set up the pull register for MMC */
        DAVINCI_VDD3P3V_PWDN = 0x0;
        davinci_cfg_reg(DM644X_MSTK);
        break;
    case DAVINCI_LPSC_I2C:
        davinci_cfg_reg(DM644X_I2C);
        break;
    case DAVINCI_LPSC_McBSP0:
        davinci_cfg_reg(DM644X_MCBSP0);
        break;
    case DAVINCI_LPSC_PWM0:
        davinci_cfg_reg(DM644X_PWM0);
        break;
    case DAVINCI_LPSC_PWM1:
        davinci_cfg_reg(DM644X_PWM1);
        break;
    case DAVINCI_LPSC_PWM2:
        davinci_cfg_reg(DM644X_PWM2);
        break;
    case DAVINCI_LPSC_VLYNQ:
        davinci_cfg_reg(DM644X_VLINQEN);
        davinci_cfg_reg(DM644X_VLINQWD);
        break;
    default:
        break;

    }
}

/* 用于设置各中断的优先级,
* 该指针定义在arch/arm/mach-davinci/irq.c中
 */
extern const u8 *davinci_def_priorities;

/* 初始化IO口,开启各模块电源 */
static void __init davinci_map_io(void)
{
    davinci_pinmux_setup = dm644x_setup_pinmux;
    davinci_def_priorities = dm644x_default_priorities;
    davinci_map_common_io();

#ifdef CONFIG_KGDB_8250
    early_serial_setup((struct uart_port *)
             &serial_platform_data[kgdb8250_ttyS]);
    kgdb8250_add_platform_port(kgdb8250_ttyS,
                 &serial_platform_data[kgdb8250_ttyS]);
#endif
    /* Initialize the DaVinci EVM board settigs */
    board_init ();
}

/* 初始化平台irq,该函数在arch/arm/mach-davinci/irq.c中定义 */
int __init davinci_gpio_irq_setup(void);


void davinci_msp430_deep_sleep(void)
{
    unsigned int icstr = DAVINCI_I2C_BASE + 0x08;
    unsigned int icsar = DAVINCI_I2C_BASE + 0x1C;
    unsigned int iccnt = DAVINCI_I2C_BASE + 0x14;
    unsigned int icdxr = DAVINCI_I2C_BASE + 0x20;
    unsigned int icmdr = DAVINCI_I2C_BASE + 0x24;
    u32 cnt = 0, buflen = 2;
    char rtcdata[2] = { 2, 8 };
    char *buffer = rtcdata;

    /* check for bus busy */
    while (readl(icstr) & 0x1000) ;

    /* configure the count register */
    writel(2, iccnt);

    /* set the salve address */
    writel(0x23, icsar);

    /* Take I2C out of reset, configure it as master,
     * set the start bit, stop bit and enable the
     * transmitter */
    writel(0x2e20, icmdr);

    while (cnt < buflen) {
        if ((readl(icstr) & 0x0010) != 0) {
            writel(*buffer, icdxr);
            ++buffer;
            ++cnt;
        }
    }
}

/* 该驱动的初始化函数 */
static __init void evm_init(void)
{
#if defined (CONFIG_MTD_DAVINCI_NOR) || defined(CONFIG_MTD_DAVINCI_NOR_MODULE)
#if defined(CONFIG_BLK_DEV_DAVINCI) || defined(CONFIG_BLK_DEV_DAVINCI_MODULE)
#warning IDE and NOR flash are are pin-muxed. Disable IDE or NOR.
    printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, "
         "but are pin-muxed.\n\t Disable IDE or NOR support.\n");
#endif
#if defined (CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
#warning NAND and NOR flash are are pin-muxed. Disable NAND or NOR.
    printk(KERN_WARNING "WARNING: both NAND and NOR flash are enabled, "
         "but are pin-muxed.\n\t Disable NAND or NOR support.\n");
#endif
#endif

#if defined(CONFIG_BLK_DEV_DAVINCI) || defined(CONFIG_BLK_DEV_DAVINCI_MODULE)
#if defined (CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
#warning IDE and NAND flash are are pin-muxed. Disable IDE or NAND.
    printk(KERN_WARNING "WARNING: both IDE and NAND flash are enabled, "
         "but are pin-muxed.\n\t Disable IDE or NAND support.\n");
#endif
#endif
    pm_power_off = davinci_msp430_deep_sleep;
    setup_mmc();
    davinci_gpio_irq_setup();
    platform_add_devices(davinci_evm_devices,        // 注册所有已定义的platform_device
        ARRAY_SIZE(davinci_evm_devices));
}

/* 初始化ARM中断控制寄存器函数 
* 在arch/arm/mach-davinci/irq.c文件中定义
*/
extern void davinci_irq_init(void);

/* 系统定时器结构体,用于初始化平台的定时器 */
extern struct sys_timer davinci_timer;

/* 定义平台属性,MACHINE_START是个宏定义,用于填充平台描述符结构体machine_desc
* 它们都在include/asm-arm/mach-davinci/arch.h中定义
* 
 */
MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
    MAINTAINER("Texas Instruments, PSP Team")
    BOOT_MEM(DAVINCI_DDR_BASE, IO_PHYS, IO_VIRT)    // 定义了DDR2的起始物理地址,IO寄存器的起始物理地址以及IO寄存器的到虚拟地址
    BOOT_PARAMS(0x80000100)            // bootloader存放启动参数到起始物理地址,系统启动会从中读取各种参数
    MAPIO(davinci_map_io)            // IO模块初始化,定义在本文件中
    INITIRQ(davinci_irq_init)        
    .timer = &davinci_timer,
    INIT_MACHINE(evm_init)
    MACHINE_END
EXPORT_SYMBOL(cpu_type)

阅读(1242) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~