U-Boot移植——设置系统时钟
2016-05-17 21:53
337 查看
0 开发环境
宿主机:Ubuntu14.04
开发板:Mini2440
U-Boot:u-boot-1.1.6
编译器:arm-linux-gcc
1 设置[b]FCLK、HCLK和PCLK[/b]
根据《U-Boot移植——添加新开发板》的方法添加Mni2440的配置和目录后,打开board/mini2440/mini2440.c,在board_init()中通过修改MPLLCON、UPLLCON和CLKDIVN三个寄存器的值来达到设置FCLK、HCLK和PCLK的目的。
(1)在board_init()函数上方添加如下宏,分别表示将要设定MPLLCON、UPLLCON和CLKDIVN三个寄存器的值:
说明:参考资料[2]p7-24指出,若要支持USB,UCLK必须为48MHz。可配置为UCLK = UPLL或者UCLK = UPLL / 2。因此UPLL只能为48MHz或者96MHz。上述配置采用了前者。
(2)添加clk_power->CLKDIVN设置,并且切换到异步总线模式:
注:上述设置必需添加在下面设置前面的位置。
(3)修改clk_power->MPLLCON的值
(4)修改clk_power->UPLLCON的值
2 修改获取系统时钟的函数
打开cpu/arm920t/s3c24x0/speed.c,分别修改get_PCLK()、get_HCLK和get_PLLCLK()三个函数。
(1)通过给get_PLLCLK()传递不同的函数,可以返回Mpll或者Upll的值,在S3C2440中它们的计算公式是不同的[2]p7-20,因此需要添加一个条件判断和Mpll的返回语句:
注:FCLK取Mpll,get_FCLK()函数直接返回Mpll的值:
(2)修改get_HCLK()。
先在get_HCLK()前面的位置定义以下宏:
#define S3C2440_CLKDIVN_PDIVN (1<<0)
#define S3C2440_CLKDIVN_HDIVN_MASK (3<<1)
#define S3C2440_CLKDIVN_HDIVN_1 (0<<1)
#define S3C2440_CLKDIVN_HDIVN_2 (1<<1)
#define S3C2440_CLKDIVN_HDIVN_4_8 (2<<1)
#define S3C2440_CLKDIVN_HDIVN_3_6 (3<<1)
#define S3C2440_CLKDIVN_UCLK (1<<3)
#define S3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0)
#define S3C2440_CAMDIVN_CAMCLK_SEL (1<<4)
#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8)
#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9)
#define S3C2440_CAMDIVN_DVSEN (1<<12) 然后将get_HCLK()的return语句替换为:
(3)修改get_PCLK(),将return语句替换为:
说明:和get_HCLK()基本一样的,只是最后的返回语句不同而已。
3 为S3C24X0_CLOCK_POWER结构添加CAMDIVN成员
在修改get_HCLK()和get_PCLK()时候都使用clk_power->CAMDIVN,然而在u-boot-1.1.6中所定义的S3C24X0_CLOCK_POWER结构并没有CAMDIVN这个成员,因此编译上述修改后的U-Boot会出错。根据参考资料[3]的提示,我们需要为S3C24X0_CLOCK_POWER结构添加CAMDIVN成员。
经过搜索发现上述结构定义于include/s3c24x0.h,打开该头文件,在S3C24X0_CLOCK_POWER结构的最后添加CAMDIVN成员:
4 相关设置
由于SDRAM受到系统时钟的影响,因此需要根据上述设置的系统时钟对其进行相应的修改,详见《U-Boot移植——设置SDRAM》。
参考资料
[1]韦东山. 嵌入式Linux应用开发完全手册. 人民邮电出版社,2012
[2]S3C2440A USER'S MANUAL
[3]关于uboot移植 CAMDIVN与时钟
宿主机:Ubuntu14.04
开发板:Mini2440
U-Boot:u-boot-1.1.6
编译器:arm-linux-gcc
1 设置[b]FCLK、HCLK和PCLK[/b]
根据《U-Boot移植——添加新开发板》的方法添加Mni2440的配置和目录后,打开board/mini2440/mini2440.c,在board_init()中通过修改MPLLCON、UPLLCON和CLKDIVN三个寄存器的值来达到设置FCLK、HCLK和PCLK的目的。
(1)在board_init()函数上方添加如下宏,分别表示将要设定MPLLCON、UPLLCON和CLKDIVN三个寄存器的值:
#define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) #define S3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02)) #define S3C2440_CLKDIV 0x05 /* FCLK:HCLK:PCLK=1:4:8, UCLK=UPLL */
说明:参考资料[2]p7-24指出,若要支持USB,UCLK必须为48MHz。可配置为UCLK = UPLL或者UCLK = UPLL / 2。因此UPLL只能为48MHz或者96MHz。上述配置采用了前者。
(2)添加clk_power->CLKDIVN设置,并且切换到异步总线模式:
/* FCLK:HCLK:PCLK=1:4:8 */ clk_power->CLKDIVN = S3C2440_CLKDIV; // Added by OneSea /* 修改为异步总线模式 */ // Added by OneSea __asm__( "mrc p15, 0, r1, c1, c0, 0\n" /* Read ctrl regisger */ "orr r1, r1, #0xc0000000\n" /* Asynchronous */ "mcr p15, 0, r1, c1, c0, 0\n" /* Write ctrl regisger */ :::"r1" );
注:上述设置必需添加在下面设置前面的位置。
(3)修改clk_power->MPLLCON的值
clk_power->MPLLCON = S3C2440_MPLL_400MHZ;
(4)修改clk_power->UPLLCON的值
clk_power->UPLLCON = S3C2440_UPLL_48MHZ;
2 修改获取系统时钟的函数
打开cpu/arm920t/s3c24x0/speed.c,分别修改get_PCLK()、get_HCLK和get_PLLCLK()三个函数。
(1)通过给get_PLLCLK()传递不同的函数,可以返回Mpll或者Upll的值,在S3C2440中它们的计算公式是不同的[2]p7-20,因此需要添加一个条件判断和Mpll的返回语句:
if (pllreg == UPLL) return((CONFIG_SYS_CLK_FREQ * m) / (p << s)); else return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s)); // Added
注:FCLK取Mpll,get_FCLK()函数直接返回Mpll的值:
ulong get_FCLK(void) { return(get_PLLCLK(MPLL)); }
(2)修改get_HCLK()。
先在get_HCLK()前面的位置定义以下宏:
#define S3C2440_CLKDIVN_PDIVN (1<<0)
#define S3C2440_CLKDIVN_HDIVN_MASK (3<<1)
#define S3C2440_CLKDIVN_HDIVN_1 (0<<1)
#define S3C2440_CLKDIVN_HDIVN_2 (1<<1)
#define S3C2440_CLKDIVN_HDIVN_4_8 (2<<1)
#define S3C2440_CLKDIVN_HDIVN_3_6 (3<<1)
#define S3C2440_CLKDIVN_UCLK (1<<3)
#define S3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0)
#define S3C2440_CAMDIVN_CAMCLK_SEL (1<<4)
#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8)
#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9)
#define S3C2440_CAMDIVN_DVSEN (1<<12) 然后将get_HCLK()的return语句替换为:
unsigned long clkdiv = clk_power->CLKDIVN; unsigned long camdiv = clk_power->CAMDIVN; int hdiv = 1; switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) { case S3C2440_CLKDIVN_HDIVN_1: hdiv = 1; break; case S3C2440_CLKDIVN_HDIVN_2: hdiv = 2; break; case S3C2440_CLKDIVN_HDIVN_4_8: hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4; break; case S3C2440_CLKDIVN_HDIVN_3_6: hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3; break; } return get_FCLK() / hdiv;
(3)修改get_PCLK(),将return语句替换为:
unsigned long clkdiv = clk_power->CLKDIVN; unsigned long camdiv = clk_power->CAMDIVN; int hdiv = 1; switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) { case S3C2440_CLKDIVN_HDIVN_1: hdiv = 1; break; case S3C2440_CLKDIVN_HDIVN_2: hdiv = 2; break; case S3C2440_CLKDIVN_HDIVN_4_8: hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4; break; case S3C2440_CLKDIVN_HDIVN_3_6: hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3; break; } return get_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
说明:和get_HCLK()基本一样的,只是最后的返回语句不同而已。
3 为S3C24X0_CLOCK_POWER结构添加CAMDIVN成员
在修改get_HCLK()和get_PCLK()时候都使用clk_power->CAMDIVN,然而在u-boot-1.1.6中所定义的S3C24X0_CLOCK_POWER结构并没有CAMDIVN这个成员,因此编译上述修改后的U-Boot会出错。根据参考资料[3]的提示,我们需要为S3C24X0_CLOCK_POWER结构添加CAMDIVN成员。
经过搜索发现上述结构定义于include/s3c24x0.h,打开该头文件,在S3C24X0_CLOCK_POWER结构的最后添加CAMDIVN成员:
typedef struct { S3C24X0_REG32 LOCKTIME; S3C24X0_REG32 MPLLCON; S3C24X0_REG32 UPLLCON; S3C24X0_REG32 CLKCON; S3C24X0_REG32 CLKSLOW; S3C24X0_REG32 CLKDIVN; S3C24X0_REG32 CAMDIVN; // Added } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;
4 相关设置
由于SDRAM受到系统时钟的影响,因此需要根据上述设置的系统时钟对其进行相应的修改,详见《U-Boot移植——设置SDRAM》。
参考资料
[1]韦东山. 嵌入式Linux应用开发完全手册. 人民邮电出版社,2012
[2]S3C2440A USER'S MANUAL
[3]关于uboot移植 CAMDIVN与时钟
相关文章推荐
- 文件File操作总结
- FFT 模板
- (未总结完成)C++中的对象放在哪里?
- Linux-文件查找
- 数据结构学习
- SDK (Manager)及 API JDK下载安装处理——ADT 的添加——AVD 的创建;
- HDU 3790 最短路径问题(迪杰斯特拉/优先队列/最短路)
- java中的字符串
- oracle数据库访问
- 设计模式之外观模式
- matplotlib安装问题
- 总线设备驱动模型
- 初识JUnit
- 杭电3791-二叉搜索树
- Genymotion,高性能的 Android 模拟器
- eclipse build path功能总 结
- 创建本地RPM源之更新系统旧版软件mysql
- oracle11g 开启归档模式。
- config libigl in qt through cmake under ubuntu
- hiho1148 编程之美