/*
* 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();
}
|