天天看點

Davinci DM6446 Linux 核心分析——board-evm.c

源位址:http://bbs.ivsok.com/blog-2-16.html

/*

 * 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)

繼續閱讀