免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1304 | 回复: 0
打印 上一主题 下一主题

MICRO2440 Fclk:Hclk:Pclk学习 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-20 09:44 |只看该作者 |倒序浏览
时钟和电源管理模块由3部分组成:时钟控制、USB控制、电源控制。
时钟控制部分产生3种时钟信号:CPU用的FCLK,AHB总线用的HCLK,APB总线用的PCLK。
有2个锁相环,一个用于FCLK HCLK PCLK,另一个用于48MHz的USB时钟。
 
s3c2440的clock & power management模块包含三个部分:
clock control
usb control
power control
现在关注点是clock control

s3c2410有两个pll。MPLL<~~>UPLL
MPLL,M即为main,用来产生三种时钟信号:
Fclk(给CPU核供给时钟信号)
Hclk(为AHB bus peripherals供给时钟信号,AHB为advanced high-performance bus)
Pclk(为APB bus peripherals供给时钟信号,APB为advanced peripherals bus)

AHB bus上的外设有LCD controller(CONT代表controller,控制器)、USB Host CONT、ExtMaster、Nand CONT和nand flash ,boot loader、bus CONT、interrupt CONT、power management、memory CONT(sram/nor/sdram等)。

APB bus上的外设有UART、USB device、SDI/MMC、Watch Dog Timer、bus CONT、spi、iic、iis、gpio、rtc、adc、timer/pwm。

主时钟源来自外部晶振或者外部时钟。复位后,MPLL虽然默认启动,但是如果不向MPLLCON中写入value,那么外部晶振直接作

为系统时钟。

写入MPLLCON寄存器值,然后等待LOCKTIME时间后,新的Fclk开始工作
1、上电几个ms后,晶振输出稳定。Fclk=晶振频率。

2、设置P M S divider control,也就是设置MPLLCON寄存器。
公式Mpll(Fclk)=(m×Fin)/(p×(2^s))【m=MDIV+8, p=PDIV+2,s=SDIV】

3、设置CLKDIVN---分频系数
即Fclk为cpu主频,Hclk由Fclk分频得到,Pclk由Hclk分频得到。
Fclk:Hclk:Pclk=1:4:8,如果主频FLCK是400MHz,那么HLCK是100MHz,PLCK是50MHz

4、CLKDIVN的补充设置
@ FCLK:HCLK=1:2
.macro MMU_SetAsyncBusMode
         mrc p15, 0, r0, c1, c0, 0
         orr r0, r0, #(R1_iA | R1_nF)
         mcr p15, 0, r0, c1, c0, 0
.endm
         @ step3: set asynchronous bus mode
         MMU_SetAsyncBusMode

5、第四步软件工作:等待locktime时间,让新的Fclk生效

6、对外设的影响
    在这个实验中,主要是有两个需要改变,一个外设是UART,一个外设是SDRAM。
    (1)UART,它是接在APB总线上,所以对应的时钟信号为Pclk,现在为50MHz。如果想要设置波特率为115200bps,那么根

据公式UBRDIV0=(int)(PCLK/(bps*16))-1计算,应该为26。如果放到程序中,那么应该注意形式。具体如下:
UBRDIV0 = ((int)(PCLK/16./UART_BAUD_RATE) -1);
    (2)SDRAM,主要的影响因素为刷新频率。前面在SDRAM中没有具体分析,现在可以详细说明。使用了两片

HY57V561620CT-H,查看手册其刷新频率为8192 refresh cycles/64ms,所以刷新周期64ms/8192=7.8125us。看寄存器

REFRESH的各个位的设置情况:
    ·REFEN[23]:开启自动模式,设为1
    ·TREFMD[22]:设为Auto refresh模式,设为0
    ·Trp[21:20]:看看RAS precharge Time,查看SDRAM手册,发现-H系列此参数至少为20ns,现在Hclk对应的时钟周期为

10ns,所以至少应该为2个clock。可以设为00
    ·Tsrc: Semi Row Cycle Time,也就是RAS Cycle Time,至少65ms,所以至少得6.5clock,按照可选值,应该设置为11
    ·Refresh[10:0]:
    公式refresh period = (2^11 - refresh_count +1)/Hclk,由此推导出refresh_count=2^11+1-refresh period*Hclk。

带入数值,计算得出1268=0x04f4,这个数值要用四舍五入,减少误差。
    ·其余的保留值,均设置为0
    由此得出该寄存器的值应该为0x008c04f4。

UPLL是提供给USB时钟(48MHz)的,与MPLL一样,UPLL的产生也是通过UPLLCON寄存器设置分频因子得到,计算公式稍有不同:

UPLL=(m*FIN)/(p*2^s) where m=(MDIV+8), p=(PDIV+2), s="SDIV",同样,可以通过查表得到一个合适的值。

最后值得一提的是,在CLKDIVN的第三位DIVN_UPLL用来设置USB时钟UCLK和UPLL的关系,如果UPLL已经是48Mhz了,那么这一位

应该设置为0,表示1:1的关系,否则是1:2的关系

详见2440datasheet_第七章clock & power management


注意:UPLLCON的值只能是:0x38022,因为UCLK=48MHZ

#define MPLLCON   0x4C000004   //系统主频配置寄存器基地址
#define UPLLCON   0x4C000008   //USB时钟频率配置寄存器基地址 
    ldr  r0, =CLKDIVN          //设置分频系数FCLK:HCLK:PCLK = 1:4:8
    mov  r1, #5
    str  r1, [r0]
 
    ldr  r0, =MPLLCON  //设置系统主频为405MHz 
    ldr  r1, =0x7F021  //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分
    str  r1, [r0]
 
    ldr  r0, =UPLLCON  //设置USB时钟频率为48MHz 
    ldr  r1, =0x38022  //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分
    str  r1, [r0]


  1. //*************************[ PLL_]*******************************
  2. //总掉函数
  3. FIN=12MHZ
  4. 2440init.s中已经设置了
  5. FCLK=400MHZ,
  6. FCLK:HCLK:PCLK=1:4:8,
  7. UCLK=48MHZ
  8. 没有特殊需求这里可以不用设置的
  9. //*************************[ PLL_]*******************************
  10. void pll_(void)
  11. {
  12.     U8 key = 14;
  13.     U32 mpll_val = (92<<12)|(1<<4)|(1);
  14.     ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);//FCLK=400MHZ
  15.     ChangeClockDivider(key, 12);//FCLK:HCLK:PCLK=1:4:8
  16.     ChangeUPllValue(56,2,2);    //set UCLK=48MHZ
  17.     cal_cpu_bus_clk();    //给FCLK,HCLK,PCLK,UCLK赋值,方便后面调用,可以省略的
  18. }

    1. //*************************[ PLL_]*******************************
    2. //设置MPLL,默认值为FCLK=MPLL,这里FCLK=400MHZ
    3. //*************************[ PLL_]*******************************
  1. void ChangeMPllValue(int mdiv,int pdiv,int sdiv)
  2. {
  3.     rMPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv;
  4. }

    1. //*************************[ PLL_]*******************************
    2. //改变分频比,这里设为:FCLK:HCLK:PCLK=1:4:8
    3. //*************************[ PLL_]*******************************
  1. void ChangeClockDivider(int hdivn_val,int pdivn_val)
  2. {
  3.     int hdivn=2, pdivn=0;

  4.     switch(hdivn_val) {
  5.         case 11: hdivn=0; break;
  6.         case 12: hdivn=1; break;
  7.         case 13:
  8.         case 16: hdivn=3; break;
  9.         case 14: 
  10.         case 18: hdivn=2; break;
  11.     }
  12.     
  13.     switch(pdivn_val) {
  14.         case 11: pdivn=0; break;
  15.         case 12: pdivn=1; break;
  16.     }
  17.     
  18.     rCLKDIVN = (hdivn<<1) | pdivn;    //101b,FCLK:HCLK:PCLK=1:4:8    CAMDIVN=0为默认

  19.     switch(hdivn_val) {
  20.         case 16:        // when 1, HCLK=FCLK/8.
  21.             rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<8); 
  22.         break; 
  23.         case 18:     // when 1, HCLK=FCLK/6.
  24.             rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<9); 
  25.         break;
  26.     }

  27.     if(hdivn!=0)
  28.         MMU_SetAsyncBusMode();        //2440init.s中有定义
  29.     else 
  30.         MMU_SetFastBusMode();

  31. }

    1. //*************************[ PLL_]*******************************
    2. //设置UPLL=PCLK=48MHZ
    3. //*************************[ PLL_]*******************************
  1. void ChangeUPllValue(int mdiv,int pdiv,int sdiv)
  2. {
  3.     rUPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv;
  4. }

    1. //*************************[ PLL_]*******************************
    2. //为FCLK,HCLK,PCLK,UCLK赋值,方便后面调用
    3. //*************************[ PLL_]*******************************
  1. static void cal_cpu_bus_clk(void)
  2. {
  3.     U32 val;
  4.     U8 m, p, s;
  5.     
  6.     val = rMPLLCON;        //FCLK=400MHZ
  7.     m = (val>>12)&0xff;    //92
  8.     p = (val>>4)&0x3f;    //1
  9.     s = val&3;            //1

  10.     //(m+8)*FIN*2 不要超出32位数!
  11.     FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;    //400MHZ
  12.     
  13.     val = rCLKDIVN;        //FCLK:HCLK:PCLK=1:4:8
  14.     m = (val>>1)&3;        //0x2
  15.     p = val&1;            //0x1
  16.     val = rCAMDIVN;        //0x0
  17.     s = val>>8;            //0x0
  18.     
  19.     switch (m) {
  20.     case 0:
  21.         HCLK = FCLK;
  22.         break;
  23.     case 1:
  24.         HCLK = FCLK>>1;
  25.         break;
  26.     case 2:
  27.         if(s&2)
  28.             HCLK = FCLK>>3;
  29.         else
  30.             HCLK = FCLK>>2;    //100MHZ
  31.         break;
  32.     case 3:
  33.         if(s&1)
  34.             HCLK = FCLK/6;
  35.         else
  36.             HCLK = FCLK/3;
  37.         break;
  38.     }
  39.     
  40.     if(p)
  41.         PCLK = HCLK>>1;    //50MHZ
  42.     else
  43.         PCLK = HCLK;
  44.     
  45.     if(s&0x10)
  46.         cpu_freq = HCLK;
  47.     else
  48.         cpu_freq = FCLK;    //400MHZ
  49.         
  50.     val = rUPLLCON;        
  51.     m = (val>>12)&0xff;
  52.     p = (val>>4)&0x3f;
  53.     s = val&3;
  54.     UPLL = ((m+8)*FIN)/((p+2)*(1<<s));    //48MHZ
  55.     UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;//48MHZ
  56. }



您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP