linux 时钟源初步分析

初步概念: 看datasheet的关于时钟与定时器的部分,

FCLK供给cpu,

HCLK供给AHB总线设备(存储器控制器,中断控制器、LCD控制器、DMA、USB主机控制器等),

PCLK供给APB总线上的设备(watchdog、IIS、i2c、 pwm、定时器、ADC、uart、gpio、rtc、spi)

上电时 fclk的时钟等于外部时钟fin, 然后等待LOCKTIME后, 依照MPLLCON寄存器的设置,倍频到高频。

UPLLCON专用于USB同于MPLLCON。

 

关于分频: CLKDIVN寄存器设置fclk、hclk、pclk的分频比。

 

时钟控制寄存器CLOCK CONTROL REGISTER (CLKCON)

寄存器的每一位大部分控制一个硬件模块的时钟源,这个功能将被用于内核控制硬件模块的方式,首先内核定义了

static struct clk init_clocks[] = {
{
  .name  = "dma",
  .id  = 0,
  .parent  = &clk_h,
  .enable  = s3c2412_clkcon_enable,
  .ctrlbit = S3C2412_CLKCON_DMA0,
 }, {
  .name  = "dma",
  .id  = 1,
  .parent  = &clk_h,
  .enable  = s3c2412_clkcon_enable,
  .ctrlbit = S3C2412_CLKCON_DMA1,
 },

......

......

{ .name    = "adc",
      .id       = -1,
      .parent  = &clk_p,
      .enable  = s3c24xx_clkcon_enable,
      .ctrlbit = S3C2410_CLKCON_ADC
    },

 

}(其中的每一项为clock结构体)

结构体,其中ctrlbit对应于CLKCON的每一位, 其中每一项的编号是通过 name来识别, 操作函数都为s3c24xx_clkcon_enable, 其中parent项表示该模块的时钟来源。

在内核里面有时候我们需要自己手动的开启硬件模块,方法如下:

 static struct clk *adc_clock;
定义一个clock时钟,这个结构体代表一个时钟的抽象。

adc_clock = clk_get(NULL, "adc");
 if (!adc_clock) {
  printk(KERN_ERR "failed to get adc clock source/n");
  return -ENOENT;
 }

获取相应模块所对应的clock结构体(存于static struct clk init_clocks中), clk_get函数是通过 name去 init_clocks结构体中遍历找到相应的clock,进而获得了硬件模块相应的clock结构体。

 clk_enable(adc_clock);
使能clock,即使能CLKCON中硬件模块相对应的位,从而实现了硬件模块的时钟源使能。clk_enable函数使用递归方式使能相应的CLKCON位,这个意思也就是说这个函数调用同时也会将这个时钟源的上一级时钟源同样使能,一直往上推保证这条时钟线ok,这个是主要的意思,具体涉及到上级时钟源的设置还需要另外的机制控制,可以参照源码分析。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值