am335x 内核频率 ddr3频率 电压调整
由Makefile可知,SPL的入口在u-boot-2011.09-psp04.06.00.08\arch\arm\cpu\armv7\start.S中
SPL的功能无非是设置MPU的Clock、PLL,Power,DDR,Uart,Pin Mux,完成对U-Boot的引导的工作,所以SPL board port主要针对以上几点。
在start.S中:
cpu_init_crit
board_init_f
board_init_r
cpu_init_crit
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
其中,CONFIG_SKIP_LOWLEVEL_INIT 在am335x_evm.h中定义:
/* Since SPL did all of this for us, we don't need to do it twice. */
#ifndef CONFIG_SPL_BUILD
#define CONFIG_SKIP_LOWLEVEL_INIT
#endif
由此可知,cpu_init_crit 只在SPL中才进行编译,U-Boot中不编译,避免了同样的内容重复设置,比如DDR等。
cpu_init_crit
----> lowlevel_init (u-boot-2011.09-psp04.06.00.08\arch\arm\cpu\armv7\omap-common\lowlevel_init.S)
----> s_init (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Evm.c)
----> 关看门狗
----> pll_init(); //PLL和时钟设置
----> rtc32k_enable(); //使能RTC
----> 串口设置
----> init_timer();
----> preloader_console_init();
----> I2C0初始化,读EEPROM
----> DDR设置(DDR2\DDR3)
pll_init(); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Pll.c)
----> mpu_pll_config(MPUPLL_M_500); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Pll.c)
//设置MPU的频率为500MHz,可以修改
----> core_pll_config(); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Pll.c)
//设置CORE频率为1GHz
----> per_pll_config(); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Pll.c)
//设置外设频率为960MHz
----> interface_clocks_enable(); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Pll.c)
//使能内部连接模块的时钟
----> power_domain_transition_enable(); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Pll.c)
//使能模块电源
----> per_clocks_enable(); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Pll.c)
//使能外设模块的时钟
在u-boot-2011.09-psp04.06.00.08\arch\arm\include\asm\arch-ti81xx\Clocks_am335x.h中,定义了所有时钟频率:
/* Put the pll config values over here */
#define OSC 24 /* 外部晶振为24MHz */
/* MAIN PLL Fdll = 1 GHZ, */
#define MPUPLL_M_500 500 /* 125 * n */
#define MPUPLL_M_550 550 /* 125 * n */
#define MPUPLL_M_600 600 /* 125 * n */
#define MPUPLL_M_720 720 /* 125 * n */
#define MPUPLL_N 23 /* (n -1 ) */
#define MPUPLL_M2 1
/* Core PLL Fdll = 1 GHZ, */
#define COREPLL_M 1000 /* 125 * n */
#define COREPLL_N 23 /* (n -1 ) */
#define COREPLL_M4 10 /* CORE_CLKOUTM4 = 200 MHZ */
#define COREPLL_M5 8 /* CORE_CLKOUTM5 = 250 MHZ */
#define COREPLL_M6 4 /* CORE_CLKOUTM6 = 500 MHZ */
/*
* USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
* frequency needs to be set to 960 MHZ. Hence,
* For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
*/
#define PERPLL_M 960
#define PERPLL_N 23
#define PERPLL_M2 5
/* DDR Freq is 266 MHZ for now*/
/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
#define DDRPLL_M 266
#define DDRPLL_N 23
#define DDRPLL_M2 1
MPU PLL结构:
配置MPU PLL:
代码如下:
void mpu_pll_config(int mpupll_M)
{
u32 clkmode, clksel, div_m2;
clkmode = readl(CM_CLKMODE_DPLL_MPU);
clksel = readl(CM_CLKSEL_DPLL_MPU);
div_m2 = readl(CM_DIV_M2_DPLL_MPU);
/* Set the PLL to bypass Mode */
writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_MPU);
while(readl(CM_IDLEST_DPLL_MPU) != 0x00000100);
clksel = clksel & (~0x7ffff);
clksel = clksel | ((mpupll_M << 0x8) | MPUPLL_N);
writel(clksel, CM_CLKSEL_DPLL_MPU);
div_m2 = div_m2 & ~0x1f;
div_m2 = div_m2 | MPUPLL_M2;
writel(div_m2, CM_DIV_M2_DPLL_MPU);
clkmode = clkmode | 0x7;
writel(clkmode, CM_CLKMODE_DPLL_MPU);
while(readl(CM_IDLEST_DPLL_MPU) != 0x1);
}
Core PLL 结构:
配置Core PLL:
代码如下:
static void core_pll_config(void)
{
u32 clkmode, clksel, div_m4, div_m5, div_m6;
clkmode = readl(CM_CLKMODE_DPLL_CORE);
clksel = readl(CM_CLKSEL_DPLL_CORE);
div_m4 = readl(CM_DIV_M4_DPLL_CORE);
div_m5 = readl(CM_DIV_M5_DPLL_CORE);
div_m6 = readl(CM_DIV_M6_DPLL_CORE);
/* Set the PLL to bypass Mode */
writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_CORE);
while(readl(CM_IDLEST_DPLL_CORE) != 0x00000100);
clksel = clksel & (~0x7ffff);
clksel = clksel | ((COREPLL_M << 0x8) | COREPLL_N);
writel(clksel, CM_CLKSEL_DPLL_CORE);
div_m4 = div_m4 & ~0x1f;
div_m4 = div_m4 | COREPLL_M4;
writel(div_m4, CM_DIV_M4_DPLL_CORE);
div_m5 = div_m5 & ~0x1f;
div_m5 = div_m5 | COREPLL_M5;
writel(div_m5, CM_DIV_M5_DPLL_CORE);
div_m6 = div_m6 & ~0x1f;
div_m6 = div_m6 | COREPLL_M6;
writel(div_m6, CM_DIV_M6_DPLL_CORE);
clkmode = clkmode | 0x7;
writel(clkmode, CM_CLKMODE_DPLL_CORE);
while(readl(CM_IDLEST_DPLL_CORE) != 0x1);
}
Peripheral PLL 结构
配置Peripheral PLL:
代码如下:
static void per_pll_config(void)
{
u32 clkmode, clksel, div_m2;
clkmode = readl(CM_CLKMODE_DPLL_PER);
clksel = readl(CM_CLKSEL_DPLL_PER);
div_m2 = readl(CM_DIV_M2_DPLL_PER);
/* Set the PLL to bypass Mode */
writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_PER);
while(readl(CM_IDLEST_DPLL_PER) != 0x00000100);
clksel = clksel & (~0x7ffff);
clksel = clksel | ((PERPLL_M << 0x8) | PERPLL_N);
writel(clksel, CM_CLKSEL_DPLL_PER);
div_m2 = div_m2 & ~0x7f;
div_m2 = div_m2 | PERPLL_M2;
writel(div_m2, CM_DIV_M2_DPLL_PER);
clkmode = clkmode | 0x7;
writel(clkmode, CM_CLKMODE_DPLL_PER);
while(readl(CM_IDLEST_DPLL_PER) != 0x1);
}
串口设置(u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Evm.c)
设置所使用串口的基地址、复位串口、关闭 smart idle。
u32 uart_base = DEFAULT_UART_BASE; // 默认使用的串口是UART0,基地址为 0x44E0_9000
enable_uart0_pin_mux(); // 配置uart0相关引脚为 UART模式
同样可以设置为其他串口,比如IA Motor Control Board就是使用的UART3,只要修改上面两步就可以了
init_timer(); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Evm.c)
这里初始化的是timer2,在之前 pll_init();----> per_clocks_enable(); 中使能的也是timer2,使用24MHz OSC
preloader_console_init(); (u-boot-2011.09-psp04.06.00.08\arch\arm\cpu\armv7\omap-common\Spl.c)
主要是对串口波特率的设置,以及串口终端打印信息。BeagleBone板上使用的是USB转串口芯片,串口驱动drivers\serial\serial.c 、drivers\serial\ns16550.c
I2C0初始化,读EEPROM (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Evm.c)
i2c0接了一个eeprom ( CAT24C256W 256K *8 ),i2c读取eeprom的数据到 header 结构体,header 结构体原型为
struct am335x_baseboard_id {
unsigned int magic;
char name[8];
char version[4];
char serial[12];
char config[32];
char mac_addr[NO_OF_MAC_ADDR][ETH_ALEN];
};
BeagleBone开发板提供的eeprom信息如下:
enable_i2c0_pin_mux(); // 配置i2c0相关引脚为 I2C模式
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);//i2c初始化,速度为标准速度100000,从设备
if (read_eeprom()) {
printf("read_eeprom() failure. continuing with ddr3\n");
} //读eeprom到 header 结构体,会判断magic是否为上表中提供的0xEE3355AA
DDR设置(DDR2\DDR3) (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Evm.c)
u32 is_ddr3 = 0;
if (!strncmp("A335X_SK", header.name, 8)) {
is_ddr3 = 1;
/*
* EVM SK 1.2A and later use gpio0_7 to enable DDR3.
* This is safe enough to do on older revs.
*/
enable_gpio0_7_pin_mux();
gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en");
gpio_direction_output(GPIO_DDR_VTT_EN, 1);
//通过gpio0_7输出高电平来触发VTT稳压器,从而产生VTT_DDR电压
}
if(is_ddr3 == 1){
ddr_pll_config(303);
config_am335x_ddr3();
}
else {
ddr_pll_config(266);
config_am335x_ddr2();
}
在设置DDR之前,要先判断是DDR2(变量is_ddr3 = 0)还是DDR3(变量is_ddr3 = 1),TI推出的开发板目前只有A335X_StarterKit支持DDR3,其余的均是DDR2,包括BeagleBone
一开始默认为DDR2(设置is_ddr3 = 0),但是通过比对header.name是否为A335X_SK,来确定DDR3(设置is_ddr3 = 1)
根据不同的DDR来进行相应的DDR配置,主要有4个部分需要设置,如下:
DDR PLL 结构:
配置DDR PLL:
代码如下:
ddr_pll_config(); (u-boot-2011.09-psp04.06.00.08\board\ti\am335x\Pll.c);
//配置ddr的时钟频率,DDR2为266MHz,DDR3为303MHz
void ddr_pll_config(unsigned int ddrpll_M)
{
u32 clkmode, clksel, div_m2;
clkmode = readl(CM_CLKMODE_DPLL_DDR);
clksel = readl(CM_CLKSEL_DPLL_DDR);
div_m2 = readl(CM_DIV_M2_DPLL_DDR);
/* Set the PLL to bypass Mode */
clkmode = (clkmode & 0xfffffff8) | 0x00000004;
writel(clkmode, CM_CLKMODE_DPLL_DDR);
while ((readl(CM_IDLEST_DPLL_DDR) & 0x00000100) != 0x00000100);
clksel = clksel & (~0x7ffff);
clksel = clksel | ((ddrpll_M << 0x8) | DDRPLL_N);
writel(clksel, CM_CLKSEL_DPLL_DDR);
div_m2 = div_m2 & 0xFFFFFFE0;
div_m2 = div_m2 | DDRPLL_M2;
writel(div_m2, CM_DIV_M2_DPLL_DDR);
clkmode = (clkmode & 0xfffffff8) | 0x7;
writel(clkmode, CM_CLKMODE_DPLL_DDR);
while ((readl(CM_IDLEST_DPLL_DDR) & 0x00000001) != 0x1);
}
config_am335x_ddr2();
am335x 内核频率 ddr3频率 电压调整的更多相关文章
- linux下查看内存频率,内核函数,cpu频率
查看CPU: cat /proc/cpuinfo # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理 ...
- am335x system upgarde ddr3 capacity configuration base on TI DDR3 Software Leveling Tool (二十)
follow test is use ti DDR Software Leveling op log. AM335x DDR3 Software Leveling -- Version: Beta ...
- am335x内核初始化路径
/arch/arm/mach-omap2/board_am335xevm.c中 1.myd_am335x_dev_cfg[]{ evm_nand_init() ... myir_gpio_init() ...
- Linux(debian7)操作基础(四)之CPU频率调整 Linux系统CPU频率调整工具使用
在Linux中,内核的开发者定义了一套框架模型来完成CPU频率动态调整这一目的,它就是CPU Freq系统.如下为CPU的几种模式(governor参数): ondemand:系统默认的超频模式,按需 ...
- Android FM模块学习之二 FM搜索频率流程
上一篇大概分析了一下FM启动流程,若不了解Fm启动流程的,能够去打开前面的链接先了解FM启动流程,接下来我们简单分析一下FM的搜索频率流程. 在了解源代码之前.我们先看一下流程图: 事实上从图中能够看 ...
- CSS/CSS3长度、时间、频率、角度单位大全
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1494 一.一笔带过的 ...
- AI-DRF权限、频率
权限 权限逻辑 权限逻辑 权限组件可以设置在三个地方:写在每个类下边表示,访问这个类的数据时,没有权限就不能访问:写在全局,表示访问每个字段的数据都需要权限:还有默认已经也写好了. 写在每个类中:写一 ...
- DRF Django REST framework 之 频率,响应器与分页器组件(六)
频率组件 频率组件类似于权限组件,它判断是否给予请求通过.频率指示临时状态,并用于控制客户端可以向API发出的请求的速率. 与权限一样,可以使用多个调节器.API可能会对未经身份验证的请求进行限制,而 ...
- day75_10_22频率认证和jwt
一.频率认证原理. 1.从dispatch中获取配置,找到setting中的配置. 2.从thtoyyling中寻找到各个认证类. 3.所有认证类都继承自basethrottle,basethrott ...
随机推荐
- 【转】打开linux-tcp端口快速回收
原文:http://www.zhaoxiaodan.com/lnmp/%E6%89%93%E5%BC%80linux-tcp%E7%AB%AF%E5%8F%A3%E5%BF%AB%E9%80%9F%E ...
- Sn.exe(强名称工具)
Sn.exe(强名称工具) .NET Framework 4.5 强名称工具 (Sn.exe) 有助于使用强名称对程序集进行签名. Sn.exe 提供了用于密钥管理.签名生成和签名验证的选项. 强 ...
- 魔术布局效果-使用本地JSON数据提供数据服务
在线演示 有社区朋友不知道如何修改外部OpenAPI为本地的JSON服务,这里做一个简单演示. 阅读原文:魔术布局效果-使用本地JSON数据提供数据服务
- keytool命令总结
keytool 命令总结 一.创建数字证书 交互模式 使用默认的密钥库.keystore(目录是c: Documents and Setting用户名)和算法(DSA) keytool -genkey ...
- unity3d 版本控制场景合并。
Editor→ProjectSettings→Editor Version Control Mode 设置为 "Visible Meta Files" Asset Serializ ...
- 算法笔记_045:币值最大化问题(Java)
目录 1 问题描述 2 解决方案 2.1 动态规划法 1 问题描述 给定一排n个硬币,其面值均为正整数c1,c2,...,cn,这些整数并不一定两两不同.请问如何选择硬币,使得在其原始位置互不相邻 ...
- studio快捷键
- 重置 radio 和 checkbox 的样式
代码: <!doctype html> <html> <head> <meta charset="utf-8"> <title ...
- VmProtect v2.12.3 安装注冊
执行vmprotect.exe開始安装: 1.选择语言.默觉得"English": 2.欢迎页,点"Next"到下一步: 3.授权信息,选"I acc ...
- .Net 两大利器Newtonsoft.NET和Dapper
你可以使用ado.net返回的DataTable让Newtonsoft.NET来序列化成Json. 当然你可以使用Dapper返回的List让Newtonsoft.NET来序列化成JSON. 参考资料 ...