/* * linux/arch/arm/mach-davinci/io.c * * DaVinci I/O mapping code * * Copyright (C) 2005-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 version 2 as * published by the Free Software Foundation. */
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h>
#include <asm/tlb.h> #include <asm/io.h>
#include <asm/mach/map.h> #include <asm/arch/memory.h> #include <asm/arch/cpu.h> #include <asm/arch/mux.h>
/* 该文件实现了DM644x平台的IO寄存器物理地址到虚拟地址的映射和IRAM的物理地址到虚拟地址的映射, 以及模块时钟的注册和复用引脚的初始化。 */
extern int davinci_clk_init(void); extern void davinci_check_revision(void); unsigned int davinci_cpu_index = DM644X_CPU_IDX; // 0
/* * The machine specific code may provide the extra mapping besides the * default mapping provided here. */ static struct map_desc davinci_io_desc[] __initdata = { { .virtual = IO_VIRT, // 0xe1000000
.physical = IO_PHYS, // 0x01c00000
.length = IO_SIZE, // 4M
.type = MT_DEVICE, }, };
// 针对DM644x平台的映射
static struct map_desc dm644x_io_desc[] __initdata = { { .virtual = DAVINCI_IRAM_VIRT, // IO_VIRT+IO_SIZE+4M
.physical = DAVINCI_IRAM_BASE, // 0x00008000
.length = DAVINCI_IRAM_SIZE, // 16K
.type = MT_DEVICE, }, };
// 针对DM646x平台的映射
static struct map_desc dm646x_io_desc[] __initdata = { { .virtual = DM646X_IO_VIRT, .physical = DM646X_IO_PHYS, .length = DM646X_IO_SIZE, .type = MT_DEVICE, }, { .virtual = DAVINCI_IRAM_VIRT, .physical = DM646X_IRAM_BASE, .length = DAVINCI_IRAM_SIZE, .type = MT_DEVICE, }, { .virtual = EMIF_CNTRL_VIRT, .physical = DAVINCI_DM646X_ASYNC_EMIF_CNTRL_BASE, .length = SZ_16K, .type = MT_DEVICE, }, };
/* IO内存初始化。 davinci_map_common_io()例程被davinci_map_io()例程调用,而其又被注册到board_evm.c中的 机器描述符中(struct machine_desc),故具体调用过程是: start_kernel()-->setup_arch()-->paging_init()-->mdesc->map_io() (其就是davinci_map_io())-->davinci_map_common_io()。 */ void __init davinci_map_common_io(void) { // 创建IO寄存器物理地址到虚拟地址的映射,不cache
iotable_init(davinci_io_desc, ARRAY_SIZE(davinci_io_desc));
/* We want to check CPU revision early for cpu_is_davinci_xxxx() macros. * IO space mapping must be initialized before we can do that. */ // 从寄存器中读取达芬奇平台版本号并打印
davinci_check_revision();
// 根据不同的平台映射IRAM的物理地址到虚拟地址,不cache
if (cpu_is_davinci_dm644x()) { iotable_init(dm644x_io_desc, ARRAY_SIZE(dm644x_io_desc)); } else if (cpu_is_davinci_dm6467()) { davinci_cpu_index = DM6467_CPU_IDX; iotable_init(dm646x_io_desc, ARRAY_SIZE(dm646x_io_desc)); } else if (cpu_is_davinci_dm355()) { davinci_cpu_index = DM355_CPU_IDX; }
/* Normally devicemaps_init() would flush caches and tlb after * mdesc->map_io(), but we must also do it here because of the CPU * revision check below. */ flush_tlb_all(); flush_cache_all();
// 初始化各服用功能引脚(与GPIO引脚复用)
davinci_mux_init(); // 注册模块时钟,以便使用模块时申请
davinci_clk_init(); }
|