S3C2410的时钟驱动分析
1 起点
我们以QT2410这个机器配置为例来说明 .
在文件 .../arch/arm/mach-s3c2410/mach-qt2410.c中我们定义一个机器配置
MACHINE_START(QT2410, "QT2410")
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params= S3C2410_SDRAM_PA + 0x100,
.map_io = qt2410_map_io,
.init_irq = s3c24xx_init_irq,
.init_machine = qt2410_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
当内核启动时以QT2410的配置启动时,在start_kernel(...)中会调用map_io()即 qt2410_map_io()函数.
// 在start_kernel(...)中被调用 .
static void __init qt2410_map_io(void)
{
// 添加IO地址映射 .
s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
// 初始化各种时钟源.
s3c24xx_init_clocks(12*1000*1000);
// 初始化UART
s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
}
在说s3c24xx_init_clocks(12*1000*1000);之前我们需要先看一下前面那个函数.
其中在 s3c24xx_init_io(...)中
void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
{
unsigned long idcode = 0x0;
/* initialise the io descriptors we need for initialisation */
// 初始化我们需要的IO描述符,
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
// 读CPU的结构代码,当前为0x32410000
if (cpu_architecture() >= CPU_ARCH_ARMv5) {
idcode = s3c24xx_read_idcode_v5();
} else {
idcode = s3c24xx_read_idcode_v4();
}
// 根据当前CPU的chip id查找到当前是的cpu_table结构.
cpu = s3c_lookup_cpu(idcode);
if (cpu == NULL) {
printk(KERN_ERR "Unknown CPU type 0x%08lx/n", idcode);
panic("Unknown S3C24XX CPU");
}
printk("CPU %s (id 0x%08lx)/n", cpu->name, idcode);
if (cpu->map_io == NULL || cpu->init == NULL) {
printk(KERN_ERR "CPU %s support not enabled/n", cpu->name);
panic("Unsupported S3C24XX CPU");
}
// 赋值机器重启调用 函数.
arm_pm_restart = s3c24xx_pm_restart;
// 调用 当前cpu的IO映射函数.
(cpu->map_io)(mach_desc, size);
}
其中对于s3c2410芯片来说读到的ID为0x32410000,则对应的cpu_table结构为:
static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x32410000,
.idmask = 0xffffffff,
.map_io = s3c2410_map_io,
.init_clocks = s3c2410_init_clocks,
.init_uarts = s3c2410_init_uarts,
.init = s3c2410_init,
.name = name_s3c2410
},
终于说到了这个cpu_table结构,这个结构在s3c24xx_init_clocks(12*1000*1000)中会用到
2 初始化
.../arch/arm/plat-s3c24xx/cpu.c
void __init s3c24xx_init_clocks(int xtal)
{
if (xtal == 0)
xtal = 12*1000*1000;<