第四章、TIny4412 U-BOOT移植四 配置时钟频率源码分析

发布者:LogicLeaper最新更新时间:2021-12-09 来源: eefocus关键字:TIny4412  U-BOOT移植  时钟频率 手机看文章 扫描二维码
随时随地手机看文章

上篇讲了配置时钟的原理,今天就结合源码具体分析一下。在U-Boot的源码中,系统时钟的初始化是放在板文件夹下的(board/Samsung/mytiny4412)的clock_init_zthtiny4412.S文件中的system_clock_init函数中。我们的Tiny4412是拷贝的smdk4212来的,所以,大家可以先参看smdk4212的clock_init_smdk4212.S文件中的system_clock_init函数来分析,完了再修改适合自己板子的程序。


对于芯片手册中每一个模块的学习,在了解前面的基本原理后,关键的寄存器的操作,可以先浏览一下这个模块的所有寄存器的简介,对各个寄存器的作用做到心中有数,这样,可以大体知道,需要配置哪些寄存器,不至于被下面一大堆的寄存器给弄懵了,系统时钟的寄存器介绍在第776开始的第7.9节REGISTERDESCRIPTION 。


我这里直接参照了FriendlyARM所提供的U-BOOT源码,基本上是复制了其tiny4412目录下的时钟设置代码,说明一下,我是学习为目录,所以很多代码都是从现有可以运行的程序那里复制来的,换句话说,我现在基本是在注释代码吧,下面顺着函数来分析:


一、输入源和分频比

设置时钟模块的时钟输入源和分频比,包括CPU,DMC,TOP,LEFTBUS,RIGHTBUS等。


1、CPU MUX /DIV的时钟源和分频比

由于要设置的模块寄存器比较多,这里我他仅仅分析一下如何设置 CPU MUX /DIV的时钟源和分频比,其设置过程是怎么样的。

开如之前,修改代码开头:

#ifdef CONFIG_EXYNOS4412

#include"smdk4412_val.h"à#include "zthtiny4412_val.h"

#else

#include"smdk4212_val.h"à#include "zthtiny4212_val.h"

#endif


再来看这个图3-1



图4-1、时钟源选择图

以及其设置寄存器如下表4-1截图所示:


表4-1、CLK_SRC_CPU寄存器设置

 

为了用24M的外部时钟进行分频,需设置MUX_APLL_SEL(MUXAPLL)为0,那么MUX_CORE_SEL也需设置成0,选择MOUTAPLL.其它的两位,按代码以前的设置为0,分别将MUX_MPLL_USER_SEL_C设置选择FINPLL.而MUX_HPM_SEL选择MOUTAPLL。所以此寄存器的设置值为0。设置完成后需要等待一定时间,让其设置成功,代码的实现方式是也可以与寄存器CLK_MUX_STAT_CPU的值相比较。如下表4-2所示为CLK_MUX_STAT_CPU状态值说明。


表4-2、CLK_MUX_STAT_CPU状态值说明


结合上表的设置值,设置完成后,MUX_MPLL_USER_SEL_C设置选择FINPLL那么26:24位的值应为001,而MUX_HPM_SEL选择MOUTAPLL,那么26:24位的值也应为001,同理,可分析出其他位的值,那么,此寄存器的值应为0x0111_0001下面来看看代码具体写法:

system_clock_init:

       push {lr}@将链接寄存器压栈    

       ldr   r0,=ELFIN_CLOCK_BASE @ELFIN_CLOCK_BASE=0x1003_0000 ,时钟寄存器的基地址

 

@CMU_CPU MUX / DIV

       ldr   r1,=0x0

       ldr   r2,=CLK_SRC_CPU_OFFSET@ CLK_SRC_CPU寄存器的偏移地址

       str    r1,[r0, r2]@ CLK_SRC_CPU寄存器的设置为0

 

       ldr r2, =CLK_MUX_STAT_CPU_OFFSET@CLK_MUX_STAT_CPU寄存器的偏移地址

       ldr r3, =0x01110001@需要比较的CLK_MUX_STAT_CPU设置值,即我们上面分析的值。

       bl wait_mux_state  @跳转到wait_mux_state等待寄存器值设置成功

 

wait_mux_state:

       ldr r1, [r0, r2]@读取CLK_MUX_STAT_CPU寄存器的值

       cmp r1, r3@ 将CLK_MUX_STAT_CPU寄存器的值和0x01110001进行比较

       bne wait_mux_state@不等就再来一次

       mov pc, lr@等了就返回。

@也可以用以下的方法来等待一定的时间

@/* wait ?us */

@    mov r1, #0x10000

@1: subs r1, r1, #1

@    bne  1b

 

好了,至此我们分析了如何设置 CPUMUX /DIV的时钟源选择的代码,但其分频比且没有进行设置,其实设置分频比的代码在后面设置完成LOCKOUT时间后才进行的,至于为什么这么安排我也不清楚,我们顺着代码分析就行,那这段代码还是在后面进行说明。


下面的代码是接着设置DMC,TOP,LEFTBUS,RIGHTBUS等寄存器,这里不做过多分析,以后我会给出详细源码,寄存器的值,针对我们板子是要进行必要修改的,重要的地方我还是会说明,如何查看手册就不做过多说明,接着说。


2、CMU_DMC MUX / DIV设置

这一段代码仅仅设置了其分频值,而其MUX值且没有设置,利用芯片启动的时的默认设置值,大家可以查看手册细细分析。这里参照tiny4412的Uboot进行了其DIV值设置。为什么取用这个值,我一时也还没有弄清楚,这里先留个问号,稍后再做说明。


@ CMU_DMC MUX / DIV  add by zth

@CLK_DIV_DMC1_VAL --Tiny4412_val.h

@defined(CONFIG_CLK_BUS_DMC_100_200)->CLK_DIV_DMC1_VAL=0X00113113

@CLK_DIV_DMC1_VAL=0X00111113

       ldr   r1,=CLK_DIV_DMC0_VAL 

       ldr   r2,=CLK_DIV_DMC0_OFFSET

       str    r1,[r0, r2]

       ldr   r1,=CLK_DIV_DMC1_VAL @CLK_DIV_DMC1_VAL=0x07071713

       ldr   r2,=CLK_DIV_DMC1_OFFSET

       str    r1,[r0, r2]


3、CMU_TOP MUX / DIV设置

CMU_TOP的MUX寄存器是CLK_SRC_TOP0和CLK_SRC_TOP1,他们的设置值分别由原值0X0变为0X00000110和0x01111000,分别利用比较其相应的状态寄存器CLK_MUX_STAT_TOP和CLK_MUX_STAT_TOP1的方法来确定值是否设置成功,当然也可以用等待一段时间的方法。


最后设置CLK_DIV_TOP寄存器,其值为0x01215474

@CMU_TOP MUX / DIV

@CLK_SRC_TOP0_VAL= 0x00000110

       ldr   r1,=CLK_SRC_TOP0_VAL

       ldr   r2,=CLK_SRC_TOP0_OFFSET

       str    r1,[r0, r2]

 

       ldr r2, =CLK_MUX_STAT_TOP_OFFSET

       @ldr r3, =0x11111111   

       ldr r3, =CLK_MUX_STAT_TOP_VAL @0x11111221

       bl wait_mux_state

 

@CLK_SRC_TOP1_VAL= 0x01111000

       ldr   r1,=CLK_SRC_TOP1_VAL

       ldr   r2,=CLK_SRC_TOP1_OFFSET

       str    r1,[r0, r2]

      

       ldr r2, =CLK_MUX_STAT_TOP1_OFFSET 

       @ldr r3, =0x01111110

       ldr r3, =CLK_MUX_STAT_TOP1_VAL  @0x02222110

       bl wait_mux_state

      

       @/* wait ?us */

@    mov r1, #0x10000

@1: subs r1, r1, #1

@    bne  1b

 

       ldr   r1,=CLK_DIV_TOP_VAL @0x01215474

       ldr   r2, =CLK_DIV_TOP_OFFSET

       str    r1,[r0, r2]


4、CMU_LEFTBUS MUX / DIV设置

CMU_LEFTBUSCMU的寄器设置和上述过程一样,这里不做过多说明,这里仅给出代码

       ldr   r1,=CLK_SRC_LEFTBUS_VAL

       ldr   r2,=CLK_SRC_LEFTBUS_OFFSET

       str    r1,[r0, r2]

 

       ldr r2, =CLK_MUX_STAT_LEFTBUS_OFFSET

       @ldr r3, =0x00000021

       ldr r3, =CLK_MUX_STAT_LEFTBUS_VAL@0x00000021

       bl wait_mux_state

 

       ldr   r1,=CLK_DIV_LEFRBUS_VAL

       ldr   r2,=CLK_DIV_LEFTBUS_OFFSET

       str    r1,[r0, r2]


5、CMU_RIGHTBUS MUX / DIV设置

CMU_LEFTBUS CMU的寄器设置和上述过程一样,这里不做过多说明,这里仅给出代码.

@ CMU_RIGHTBUS MUX / DIV

ldr   r1,=CLK_SRC_RIGHTBUS_VAL

       ldr   r2,=CLK_SRC_RIGHTBUS_OFFSET

       str    r1,[r0, r2]

 

       ldr r2, =CLK_MUX_STAT_RIGHTBUS_OFFSET

       @ldr r3, =0x00000021

       ldr r3, =CLK_MUX_STAT_RIGHTBUS_VAL  @0x00000021

       bl wait_mux_state

 

       ldr   r1,=CLK_DIV_RIGHTBUS_VAL

       ldr   r2,=CLK_DIV_RIGHTBUS_OFFSET

       str    r1,[r0, r2]


二、设置APLL/MPLL/EPLL/EPLL锁相环锁频时间

翻看手册,P371页,找到PLLCONTROL REGISTERS。

• (APLL_LOCK, R/W, Address =0x1004_0000)

• (MPLL_LOCK, R/W, Address =0x1004_0000)

• (EPLL_LOCK, R/W, Address =0x1003_0000)

• (VPLL_LOCK, R/W, Address =0xE010_0020)


表4-3、PLL寄存器锁定时间


这里出现了一个问题,APLL/MPLL/EPLL/VPLL的锁相环的时间是不一样的,而像S5PC100,频率为667MHz,他的A/M/E/HPLL的锁相环时间均是300us,这个时间一定要查芯片手册,如下截图的表3-4所示每一个寄存器的设置值,里面有完整的说明:





表4-4、xPLL_LOCK寄存器说明


参看上述说明,用如下宏定义先说明设置值

#if defined(CONFIG_CLK_ARM_800_APLL_800)

#define APLL_PDIV            0x3

#if defined(CONFIG_CLK_BUS_DMC_165_330)

#define MPLL_PDIV     0x5

#elifdefined(CONFIG_CLK_BUS_DMC_200_400)

#define MPLL_PDIV     0x3

#elif defined(CONFIG_CLK_BUS_DMC_220_440)

#define MPLL_PDIV     0x3

#endif

#define EPLL_PDIV     0x2

#define VPLL_PDIV     0x3

/* APLL_LOCK     */

#define APLL_LOCK_VAL   (APLL_PDIV * 270)/*  810*/

/* MPLL_LOCK    */

#define MPLL_LOCK_VAL  (MPLL_PDIV * 270)

/* EPLL_LOCK     */

#define EPLL_LOCK_VAL   (EPLL_PDIV * 3000)

/* VPLL_LOCK     */

#define VPLL_LOCK_VAL   (VPLL_PDIV * 3000)

 

接着进行设置,设置方法代码如下,代码的书写方式很明了,这里就不做过多说明。

@ Set PLL locktime

       ldr   r1,=APLL_LOCK_VAL

       ldr   r2,=APLL_LOCK_OFFSET

       str    r1,[r0, r2]

 

       ldr   r1,=MPLL_LOCK_VAL

       ldr   r2,=MPLL_LOCK_OFFSET

       str    r1,[r0, r2]

 

       ldr   r1,=EPLL_LOCK_VAL

       ldr   r2,=EPLL_LOCK_OFFSET

       str    r1,[r0, r2]

 

       ldr   r1,=VPLL_LOCK_VAL

       ldr   r2,=VPLL_LOCK_OFFSET

       str    r1,[r0, r2]

 

在这段代码后才是设置MCU_CPU的分频比的代码。设置值可以查看

P585 页7.9.1.136CLK_DIV_CPU0和7.9.1.137 CLK_DIV_CPU1页的寄存器列表。

由于zthtiny4412_val.h中可以设置其值,这里修改设置的值如下所示,这两个值的设置得以照APLL后的频来决定。不能随便设置,APLL设置好后,即可以知道APLL频率,此后根据CLK_DIV_CPU0和CLK_DIV_CPU1的说明来计算出所需的值进行设置即可,zthtiny4412_val.h中有设置好几类时钟频率的值,如APLL为800MHZ,1000MHZ时的值不一样。


@Set MCU_CPU Ratio

       ldr   r1,=CLK_DIV_CPU0_VAL

       ldr   r2,=CLK_DIV_CPU0_OFFSET

       str    r1,[r0, r2]

       ldr   r1,=CLK_DIV_CPU1_VAL

       ldr   r2,=CLK_DIV_CPU1_OFFSET

       str    r1,[r0, r2]


三、下面的代码就是开始倍频

1、倍频APLL

这个倍频值需根据需求参考手册来时行设置。这里有不同频进行设置,每一个设置值不做过多说明,仅仅说明一下参考位置,设置值P,M,S可以设置寄存器APLL_CON0,如下图所示,其中,其上电初始化后,如果外部的时钟晶振是24MHZ的话,那么其频率为800MHZ。但需要注意的是设置的输出频率范围在21.9MHZ到1400MHZ

[1] [2]
关键字:TIny4412  U-BOOT移植  时钟频率 引用地址:第四章、TIny4412 U-BOOT移植四 配置时钟频率源码分析

上一篇:第三章、Tiny4412 U-BOOT移植三 时钟设置
下一篇:第五章、Tiny4412 U-BOOT移植五 Nand Flash原理

推荐阅读最新更新时间:2024-11-03 08:50

U-boot在S3C2440上的移植详解(五)
一、移植环境 主 机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand,Kernel:2.6.30.4 编译器:arm-linux-gcc-4.3.2.tgz u-boot:u-boot-2009.08.tar.bz2 二、移植步骤 9)实现u-boot对yaffs/yaffs2文件系统下载的支持。 注意:此篇对Nand的操作是基于MTD架构方式,在“u-boot-2009.08在2440上的移植详解(三)”中讲到过。 通常一个Nnad Flash存储设备由若干块组成,1个块由若干页组成。一般128MB以下容量的Nand Flash芯片,一页大小为528B,被依次分为2
[单片机]
<font color='red'>U-boot</font>在S3C2440上的<font color='red'>移植</font>详解(五)
Atmel推出时钟频率达500Msps的12位ADC
Atmel公司日前推出时钟频率达500Msps的商用单芯片12位ADC,这款型号为AT84AS001TP组件是为了帮助系统设计人员以250MHz采样率数字化信号而设计,而之前,12位分辨率还从未达到250MHz的采样率。现有12位商用产品均不能达到250MSps,因而设计人员只能在把模拟信号输入ADC前使用数个下行转换硬件级,并交叉采用数个ADC来达到高资料采样率。 AT84AS001TP能使系统架构更简单,并提供更宽的采样信号。因而将使电信设备、高IF宽频数字接收器、测试和 测量设备、高速资料采集和国防雷达及通讯系统等应用领域从中获益。此款产品采用TBGA192塑料封装,有商业 和产业温度范围两种产品。现已开始提供样品,将
[新品]
51单片机有关晶振的问题总结
前言 学51单片机的时候,总是伴随很多有关于晶振的问题,其实晶振就是如同人的心脏,是血液的脉搏,把单片机的晶振问题搞明白了,51单片机的其他问题迎刃而解……有关51单片机有关晶振的问题一并总结出来,希望对学51的童鞋来说能有帮助。 一、为什么51单片机爱用11.0592MHZ晶振? 其一:因为它能够准确地划分成时钟频率,与UART(通用异步接收器/发送器)量常见的波特率相关。特别是较高的波特率(19600,19200),不管多么古怪的值,这些晶振都是准确,常被使用的。 其二:用11.0592晶振的原因是51单片机的定时器导致的。用51单片机的定时器做波特率发生器时,如果用11.0592Mhz的晶振,根据公式算下来需要定时器设置
[单片机]
第九章、Tiny4412 U-BOOT移植九 DDR工作时序与原理 一
DDR SDRAM 全称为 Double Data Rate SDRAM,中文名为“双倍数据流 SDRAM”。DDR SDRAM 在原有的 SDRAM的基础上改进而来。下图9-1是DDR和SDRAM的数据传输对比图。 图9-1、DDR和SDRAM的数据传输对比图 上图8-1可以清楚的看到,DDR可在一个时钟周期内传送两次数据,上升沿传一次,下降沿传一次。 一、DDR的基本原理 图9-2、DDR读操作时序图 从中可以发现它多了两个信号:CLK#与DQS,CLK#与正常 CLK 时钟相位相反,形成差分时钟信号。而数据的传输在 CLK 与 CLK#的交叉点进行,可见在 CLK 的上升与下降沿(此时正好是 CLK#的上
[单片机]
第九章、<font color='red'>Tiny4412</font> <font color='red'>U-BOOT</font><font color='red'>移植</font>九 DDR工作时序与原理 一
基于S3C2410A的嵌入式系统的U-Boot移植
   0 引 言   ARM嵌入式处理器已被广泛应用于消费电子产品、无线通信、网络通信和工业控制等领域。其中,ARM9的芯片更是以其低价格、低功耗、高性能在手持设备中占据着重要市场。在嵌入式操作系统中,Linux,Vxworks,WinCE三足鼎立,其中Linux由于其开源性、稳定性、安全性、可裁减性更是一支独放。在嵌入式系统中,如何实现在ARM9平台下Linux操作系统的引导工作是嵌入式技术开发的重要环节。    1 嵌入式系统的软件组成   1.1 系统的软件组成   嵌入式的软件系统主要由Bootloader、操作系统、文件系统、应用程序等组成。其中,Bootloader是介于硬件和操作系统之间的一层,其作用
[嵌入式]
u-boot移植(十三)---代码修改---支持文件系统及补丁制作
一、烧写文件系统 1.1 jffs2烧写   1.下载文件系统:tftp 30000000 fs_mini_mdev.jffs2      2.擦除文件的块:nand erase.part rootfs      3.烧入文件系统:nand write.jffs2 30000000 0x00260000 5b89a8      4.设置启动参数:set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2      5.重新启动      这个需要先烧写内核。 1.2 yaffs烧写   1.下载文件系统:tftp 30000000 fs_mini_m
[单片机]
<font color='red'>u-boot</font><font color='red'>移植</font>(十三)---代码修改---支持文件系统及补丁制作
U-boot内核移植步骤
Linux 3.3.5系统移植 将arch/arm/mach-s3c6410/下的,mach-smdk6410.c cp为mach-my6410.c; 打开arch/arm/mach-s3c6410/下的Kconfig,仿照MACH_SMDK6410做一个菜单项: config MACH_MY6410 bool MY6410 select CPU_S3C6410 select SAMSUNG_DEV_ADC select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_I2C1 select SAMSUNG_DEV_IDE select
[单片机]
STM32学习之:时钟频率
******************************** 本学习笔记基于STM32固件库V3.0 使用芯片型号:STM32F103 开发环境:MDK ******************************** 第一课 时钟频率 STM32F103内部8M的内部震荡,经过倍频后最高可以达到72M。目前TI的M3系列芯片最高频率可以达到80M。 在stm32固件库3.0中对时钟频率的选择进行了大大的简化,原先的一大堆操作都在后台进行。系统给出的函数为SystemInit()。但在调用前还需要进行一些宏定义的设置,具体的设置在system_stm32f10x.c文件中。 文件开头就有一个这样的定义: //#defi
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved