Chinaunix首页 | 论坛 | 博客
  • 博客访问: 532776
  • 博文数量: 150
  • 博客积分: 5010
  • 博客等级: 大校
  • 技术积分: 1861
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-17 00:19
文章分类

全部博文(150)

文章存档

2011年(1)

2009年(14)

2008年(135)

我的朋友

分类:

2008-05-04 14:34:25

ARM9硬件接口学习专题


http://blog.chinaunix.net/u2/60011/showart_471534.html










/root/u-boot-1.1.4/board/smdk2410.c


代码:


#define FCLK_SPEED 1

#if FCLK_SPEED==0        /* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV    0xC3
#define M_PDIV    0x4
#define M_SDIV    0x1
#elif FCLK_SPEED==1        /* Fout = 200MHz */
#define M_MDIV    0x5C
#define M_PDIV    0x4
#define M_SDIV    0x0
#endif

#define USB_CLOCK 1

#if USB_CLOCK==0
#define U_M_MDIV    0xA1
#define U_M_PDIV    0x3
#define U_M_SDIV    0x1
#elif USB_CLOCK==1
#define U_M_MDIV    0x48
#define U_M_PDIV    0x3
#define U_M_SDIV    0x2
#endif

static inline void delay (unsigned long loops)
{
    __asm__ volatile ("1:\n"
     "subs %0, %1, #1\n"
     "bne 1b":"=r" (loops):"0" (loops));
}

/*
 * Miscellaneous platform dependent initialisations
 */

int board_init (void)
{
    DECLARE_GLOBAL_DATA_PTR;
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

    /* to reduce PLL lock time, adjust the LOCKTIME register */
    clk_power->LOCKTIME = 0xFFFFFF;

    /* configure MPLL */
    clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

    /* some delay between MPLL and UPLL */
    delay (4000);

    /* configure UPLL */
    clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

    /* some delay between MPLL and UPLL */
    delay (8000)











==========================================================================

S3C2410 CPU默认的工作主频为12MHz,使用PLL电路可以产生更高的主频供CPU及外围器件使用。S3C2410有两个PLLMPLLUPLLUPLL专用与USB设备。MPLL用于CPU及其他外围器件。

通过MPLL会产生三个部分的时钟频率:FCLKHCLKPLCKFCLK用于CPU核,HCLK用于AHB总线的设备(比如SDRAM)PCLK用于APB总线的设备(比如UART)。从时钟结构图中可以查看到使用不同时钟频率的硬件。

Figure 7-1. Clock Generator Block Diagram

 

(注:这里要注意从图中看出,Uart使用的是PCLK,后面Uart实验会用到)

 

下面介绍MPLL的启动流程:

(注:下面内容部分直接摘录自《s3c2410完全开发流程》,Clock部分写了非常好)

S3c2410 datasheet 224Figure 7-4. Power-On Reset Sequence展示了上电后MPLL启动的过程

 

 

请跟随FCLK的图像了解启动过程:

1、上电几毫秒后,晶振输出稳定,FCLK=晶振频率,nRESET信号恢复高电平后,

CPU开始执行指令。

2我们可以在程序开头启动MPLL,在设置MPLL的几个寄存器后,需要等待一段时间(Lock Time)MPLL的输出才稳定。在这段时间(Lock Time)内,FCLK停振,CPU停止工作。Lock Time的长短由寄存器LOCKTIME设定。

3Lock Time之后,MPLL输出正常,CPU工作在新的FCLK下。

 

设置S3c2410的时钟频率就是设置MPLL的几个寄存器:

1LOCKTIME:设为0x00ffffff

前面说过,MPLL启动后需要等待一段时间(Lock Time),使得其输出稳定。位[23:12]用于UPLL,位[11:0]用于MPLL使用确省值0x00ffffff即可。

2CLKDIVN:用来设置FCLK:HCLK:PCLK的比例关系,默认为1:1:1

这里值设为0x03,即FCLK:HCLK:PCLK=1:2:4

CLKDIVN不同的设置及对应的时钟比例关系如下图:

 

3MPLLCON:设为(0x5c << 12)|(0x04 << 4)|(0x00),即0x5c0040

对于MPLLCON寄存器,[19:12]MDIV[9:4]PDIV[1:0]SDIV。有如下计算公式:

MPLL(FCLK) = (m * Fin)/(p * 2^s)

其中: m = MDIV + 8, p = PDIV + 2

Fin 即默认输入的时钟频率12MHzMPLLCON设为0x5c0040,可以计算出FCLK=200MHz,再由CLKDIVN的设置可知:HCLK=100MHzPCLK=50MHz

 

 通常我们将如上时钟初始化的过程写成clock_init函数供其他函数调用,代码如下:

void clock_init(void)

{

        /*init clock*/

rLOCKTIME = 0xFFFFFF;

 

    /*设置FCLK:HCLK:PCLK=1:2:4,这样假设处理器主频为200M,HCLK50M,PCLK25MARM920T内核使用FCLK, 内存控制器,LCD控制器等使用HCLK,看门狗、串口等使用PCLK*/

rCLKDIVN  = 0x3;

 

    /* 设置时钟频率为202.7M*/

    rMPLLCON = 0x5c0040;

   

}

#include <common.h>
#include <s3c2410.h>

/* ------------------------------------------------------------------------- */

#define FCLK_SPEED 1

#if FCLK_SPEED==0        /* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV    0xC3
#define M_PDIV    0x4
#define M_SDIV    0x1
#elif FCLK_SPEED==1        /* Fout = 200MHz */
#define M_MDIV    0x5C
#define M_PDIV    0x4
#define M_SDIV    0x0
#endif

#define USB_CLOCK 1

#if USB_CLOCK==0
#define U_M_MDIV    0xA1
#define U_M_PDIV    0x3
#define U_M_SDIV    0x1
#elif USB_CLOCK==1
#define U_M_MDIV    0x48
#define U_M_PDIV    0x3
#define U_M_SDIV    0x2
#endif

static inline void delay (unsigned long loops)
{
    __asm__ volatile ("1:\n"
     "subs %0, %1, #1\n"
     "bne 1b":"=r" (loops):"0" (loops));
}

/*
 * Miscellaneous platform dependent initialisations
 */

int board_init (void)
{
    DECLARE_GLOBAL_DATA_PTR;
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

    /* to reduce PLL lock time, adjust the LOCKTIME register */
    clk_power->LOCKTIME = 0xFFFFFF;

    /* configure MPLL */
    clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

    /* some delay between MPLL and UPLL */
    delay (4000);

    /* configure UPLL */
    clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

    /* some delay between MPLL and UPLL */
    delay (8000)

阅读(1554) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~