在内核配置界界面,我们可以很容易的配置DDR的频率,300M OR 600M, so easy!
那么它是如何起作用的呢?
回想 RK30SDK开发板驱动分析(一) 末尾提到MACHINE_START是系统开始的地方,位于board-rk30-box.c ,注意里面有个函数rk30_map_io
MACHINE_START(RK30, "RK30board") .boot_params = PLAT_PHYS_OFFSET + 0x800, .fixup = rk30_fixup, .reserve = &rk30_reserve, .map_io = rk30_map_io, .init_irq = rk30_init_irq, .timer = &rk30_timer, .init_machine = machine_rk30_board_init, MACHINE_END
它的作用是静态映射外设的物理地址到内核地址空间,外设的寄存器地址都是实际的物理地址,在内核中必须先映射为内核地址,才能访问。映射的方式有2种:
- 动态映射 ioremap
- 静态映射 map_io, 即本文中提到的方式
3066中的实现rk30_map_io的函数位于common.c
void __init rk30_map_io(void) { rk30_map_common_io(); usb_uart_init(); rk29_setup_early_printk(); rk30_cpu_axi_init(); rk29_sram_init(); board_clock_init(); rk30_l2_cache_init(); ddr_init(DDR_TYPE, DDR_FREQ); clk_disable_unused(); rk30_iomux_init(); rk30_boot_mode_init(); }
其调用了ddr_init函数,这里应该就是初始化DDR,并设置DDR频率的地方了,那么DDR_FREQ的定义是什么?grep一下吧:
plat-rk/include/plat/ddr.h
#define DDR_FREQ (CONFIG_DDR_SDRAM_FREQ)
CONFIG_DDR_SDRAM_FREQ正是我们在内核配置界面配置频率时设定的值,至此,前后呼应起来了!
顺便把DDR_TYPE也扒出来吧:
#define DDR3_2133M (19) // 13-13-13 #define DDR3_2133N (20) // 14-14-14 #define DDR3_DEFAULT (21) #define DDR_DDR2 (22) #define DDR_LPDDR (23) #define DDR_LPDDR2 (24)
找到常数了,这个应该直接参与硬件层次的寄存器处理了!DDR_TYPE也是在内核配置界面设置的: