6.2.2 OMAP处理器部分的移植
arch/arm/mach-omap2是OMAP机器相关部分的移植的目录,其中Makefile文件的一个片断如下所示:
obj-y := irq.o id.o io.o sdrc.o control.o prcm.o clock.o mux.o \ devices.o serial.o gpmc.o timer-gp.o powerdomain.o \ clockdomain.o omapdev.o obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ mmc-twl4030.o \ board-ldp-flash.o \ board-zoom2-camera.o \ board-zoom2-wifi.o
在这里,不需要条件编译的各种文件,如irq.c,clock.c,serial.c等是通用OMAP中的文件。由于本例使用的是zoom2类型板级配置,因此MACH_OMAP_ZOOM2宏被打开,选择了一些编译的内容。
board-zoom2.c是OMAP机器实现的核心文件,机器类型的定义如下所示:
MACHINE_START(OMAP_ZOOM2, "OMAP ZOOM2 board") .phys_io = 0x10000000, .io_pg_offst = ((0xfb000000) >> 18) & 0xfffc, .boot_params = 0x80000100, .map_io = omap_zoom2_map_io, .init_irq = omap_zoom2_init_irq, .init_machine= omap_zoom2_init, .timer = &omap_timer, MACHINE_END
在MACHINE_START和MACHINE_END之间的内容为机器的信息,实际上是结构struct machine_desc。这里赋值了影射IO、初始化irq、初始化机器等函数指针。omap_zoom2_map_io,omap_zoom2_init_irq,omap_zoom2_init都是在同文件中实现的初始化函数。omap_timer是为当前机器实现的定时器。
其中,omap_zoom2_map_io()函数用于映射IO空间,这个函数的实现如下所示:
static struct map_desc zoom2_io_desc[] __initdata = { { .virtual = ZOOM2_QUART_VIRT, .pfn = __phys_to_pfn(ZOOM2_QUART_PHYS), .length = ZOOM2_QUART_SIZE, .type = MT_DEVICE }, }; static void __init omap_zoom2_map_io(void) { omap2_set_globals_343x(); iotable_init(zoom2_io_desc, ARRAY_SIZE(zoom2_io_desc)); omap2_map_common_io(); }
由于设备比较多,因此初始化的过程比较复杂。这些设备有一些是OMAP处理器SOC内部的,有一些是在板级连接的设备(SOC外部)。
omap_zoom2_init_irq()函数用于初始化板级的中断系统,内容如下所示:
static void __init omap_zoom2_init_irq(void) { omap2_init_common_hw(mt46h32m32lf6_sdrc_params, omap3_mpu_rate_table, omap3_dsp_rate_table, omap3_l3_rate_table); omap_init_irq(); // 处理器级别的中断初始化 omap_gpio_init(); zoom2_init_smc911x(); // 初始化Zoom的板级的以太网控制器SMC911 }
omap_zoom2_init()函数是OMAP ZOOM平台的板级的初始化函数,这个函数实现的主要内容如下所示:
static void __init omap_zoom2_init(void) { omap_i2c_init(); // 初始化处理器的i2c系统 platform_add_devices(zoom2_devices, ARRAY_SIZE(zoom2_devices)); omap_board_config = zoom2_config; omap_board_config_size = ARRAY_SIZE(zoom2_config); spi_register_board_info(zoom2_spi_board_info, ARRAY_SIZE(zoom2_spi_board_info)); synaptics_dev_init(); // synaptics触摸屏相关的初始化 msecure_init(); ldp_flash_init(); // 板级Flash的初始化 zoom2_init_quaduart(); // 调试板Quad UART (TL16CP754C)的初始化 omap_serial_init(); // 串口的初始化 usb_musb_init(); // USB的初始化 config_wlan_gpio(); // 配置无线局域网相关的GPIO zoom2_cam_init(); //板级Camera部分的初始化 zoom2_lcd_tv_panel_init(); //板级显示屏幕的初始化 }
根据配置,这里调用的zoom2_cam_init()是在board-zoom2-camera.c中实现的。board-zoom2-camera.c和board-zoom2-wifi.c这两个文件是Zoom板级使用的文件,前者负责Camera子系统的初始化,后者负责注册Wifi设备的功能。
文件devices.c的功能和其他平台类似 ,主要负责向系统中注册各种平台设备(platform_device)。例如,spi1的平台设备的资源和注册如下所示:
static struct resource omap2_mcspi1_resources[] = { // SPI 1所使用的左缘 { .start = OMAP2_MCSPI1_BASE, .end = OMAP2_MCSPI1_BASE + 0xff, .flags = IORESOURCE_MEM, }, }; static struct platform_device omap2_mcspi1 = { // SPI 1的平台设备 .name = "omap2_mcspi", .id = 1, .num_resources = ARRAY_SIZE(omap2_mcspi1_resources), .resource = omap2_mcspi1_resources, .dev = { .platform_data = &omap2_mcspi1_config, }, };
平台设备(platform_device)需要和平台驱动(platform_driver)根据名称相匹配。在各种驱动程序中定义平台驱动,通过匹配可以获得平台设备中注册的各种资源(内存、中断、DMA)。
devices.c中定义了Camera、McSBSP接口、SPI等平台设备,另外的一些平台设备也在arch/arm/mach-omap2目录中的其他文件中定义。