由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频率 电压调整的更多相关文章

  1. linux下查看内存频率,内核函数,cpu频率

    查看CPU: cat /proc/cpuinfo # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理 ...

  2. 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 ...

  3. am335x内核初始化路径

    /arch/arm/mach-omap2/board_am335xevm.c中 1.myd_am335x_dev_cfg[]{ evm_nand_init() ... myir_gpio_init() ...

  4. Linux(debian7)操作基础(四)之CPU频率调整 Linux系统CPU频率调整工具使用

    在Linux中,内核的开发者定义了一套框架模型来完成CPU频率动态调整这一目的,它就是CPU Freq系统.如下为CPU的几种模式(governor参数): ondemand:系统默认的超频模式,按需 ...

  5. Android FM模块学习之二 FM搜索频率流程

    上一篇大概分析了一下FM启动流程,若不了解Fm启动流程的,能够去打开前面的链接先了解FM启动流程,接下来我们简单分析一下FM的搜索频率流程. 在了解源代码之前.我们先看一下流程图: 事实上从图中能够看 ...

  6. CSS/CSS3长度、时间、频率、角度单位大全

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1494 一.一笔带过的 ...

  7. AI-DRF权限、频率

    权限 权限逻辑 权限逻辑 权限组件可以设置在三个地方:写在每个类下边表示,访问这个类的数据时,没有权限就不能访问:写在全局,表示访问每个字段的数据都需要权限:还有默认已经也写好了. 写在每个类中:写一 ...

  8. DRF Django REST framework 之 频率,响应器与分页器组件(六)

    频率组件 频率组件类似于权限组件,它判断是否给予请求通过.频率指示临时状态,并用于控制客户端可以向API发出的请求的速率. 与权限一样,可以使用多个调节器.API可能会对未经身份验证的请求进行限制,而 ...

  9. day75_10_22频率认证和jwt

    一.频率认证原理. 1.从dispatch中获取配置,找到setting中的配置. 2.从thtoyyling中寻找到各个认证类. 3.所有认证类都继承自basethrottle,basethrott ...

随机推荐

  1. 10分钟,利用canvas画一个小的loading界面

    首先利用定义下canvas得样式 <canvas width="1024" height="720" id="canvas" styl ...

  2. 检索COM类工厂的组件失败:80040111

    检索 COM 类工厂中 CLSID 为 {--} 的组件失败,原因是出现以下错误: 80040111.如图: 这种问题可能由多种情况造成,目前我遇到两种: 操作系统版本问题 如果是在Win7 64版本 ...

  3. UNIX网络编程学习笔记:值-结果(value-result)参数

    前言 当把套接口地址结构传递给套接口函数时,总是通过指针来传递的,即传递的是一个指向结构的指针.结构的长度也作为参数来传递,其传递的方式取决于结构的传递方向:从进程到内核,还是从内核到进程. 1.从进 ...

  4. js 函数节流throttle 函数去抖debounce

    1.函数节流throttle 通俗解释: 假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯: 但是,你是个没耐心的人,你最多只会等待电梯停留一分钟: ...

  5. webpack 实用配置总结

    1.webpack.config.js配置文件为: //处理共用.通用的js var webpack = require('webpack'); //处理html模板 var htmlWebpackP ...

  6. [多校2015.02.1004 dp] hdu 5303 Delicious Apples

    题意: 在一个长度为L的环上有N棵苹果树.你的篮子容量是K个苹果. 每棵苹果树上都有a[i]个苹果. 问你从0点出发最少要走多少距离能拿完所有的苹果. 思路: 我们考虑dp,dp[0][i]代表顺时针 ...

  7. vnc/route/ifconfig 配置

    重启网卡的方法: 1 network 利用root帐户 # service network restart ############################################## ...

  8. chrome 此网页正试图从未经验证的来源加载脚本

      chrome 此网页正试图从未经验证的来源加载脚本 CreateTime--2018年5月25日08点02分 Author:Marydon 1.情景还原 以我的网站为例,https://www.c ...

  9. 一次安装win10 ubuntu16.0经过记录

    步骤摘要 三个U盘: 1.制作WIN8 PE启动盘,使用的软件为“U深度装机版”,可自行百度下载 2.制作WIN10系统安装盘,使用UltraISO,这里使用的win10镜像为: 链接: http:/ ...

  10. Windows下Hadoop编程环境配置指南

    刘勇    Email: lyssym@sina.com 本博客记录作者在工作与研究中所经历的点滴,一方面给自己的工作与生活留下印记,另一方面若是能对大家有所帮助,则幸甚至哉矣! 简介 鉴于最近在研究 ...