s3c2440时钟的体系结构


OM控制使用内部时钟和内部时钟,详细情况可以看数据手册
这里使用的源代码版本是2.6.35.14
初始化时钟代码arch\arm\s3c2440\s3c244x.c
void __init s3c244x_init_clocks(int xtal)
{/* initialise the clocks here, to allow other things like the* console to use them, and to add new ones after the initialisation*/s3c24xx_register_baseclocks(xtal);s3c244x_setup_clocks();s3c2410_baseclk_add();
}
首先我们看一下s3c24xx_register_baseclocks(xtal)函数在这里注册时钟

arch\arm\plat-samsung\clock.c
/* initalise all the clocks */int __init s3c24xx_register_baseclocks(unsigned long xtal)
{printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");clk_xtal.rate = xtal;/* register our clocks */if (s3c24xx_register_clock(&clk_xtal) < 0)printk(KERN_ERR "failed to register master xtal\n");if (s3c24xx_register_clock(&clk_mpll) < 0)printk(KERN_ERR "failed to register mpll clock\n");if (s3c24xx_register_clock(&clk_upll) < 0)printk(KERN_ERR "failed to register upll clock\n");if (s3c24xx_register_clock(&clk_f) < 0)printk(KERN_ERR "failed to register cpu fclk\n");if (s3c24xx_register_clock(&clk_h) < 0)printk(KERN_ERR "failed to register cpu hclk\n");if (s3c24xx_register_clock(&clk_p) < 0)printk(KERN_ERR "failed to register cpu pclk\n");return 0;
}

这里面用到了s3c24xx_register_clock()函数看他是如何实现的
arch\arm\plat-samsung\clock.c
/* initialise the clock system *//*** s3c24xx_register_clock() - register a clock* @clk: The clock to register** Add the specified clock to the list of clocks known by the system.*/
int s3c24xx_register_clock(struct clk *clk)
{if (clk->enable == NULL)clk->enable = clk_null_enable;/* add to the list of available clocks *//* Quick check to see if this clock has already been registered. */BUG_ON(clk->list.prev != clk->list.next);spin_lock(&clocks_lock);list_add(&clk->list, &clocks);              //添加到时钟列表中spin_unlock(&clocks_lock);return 0;
}

接下来我们看一下s3c244x_steup_clocks(xtal)函数

所在目录arch\arm\mach-s3c2440\s3c244x.c
void __init_or_cpufreq s3c244x_setup_clocks(void)
{struct clk *xtal_clk;unsigned long clkdiv;unsigned long camdiv;unsigned long xtal;unsigned long hclk, fclk, pclk;int hdiv = 1;xtal_clk = clk_get(NULL, "xtal");xtal = clk_get_rate(xtal_clk);clk_put(xtal_clk);fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;clkdiv = __raw_readl(S3C2410_CLKDIVN);camdiv = __raw_readl(S3C2440_CAMDIVN);/* work out clock scalings */switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {case S3C2440_CLKDIVN_HDIVN_1:hdiv = 1;break;case S3C2440_CLKDIVN_HDIVN_2:hdiv = 2;break;case S3C2440_CLKDIVN_HDIVN_4_8:hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;break;case S3C2440_CLKDIVN_HDIVN_3_6:hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;break;}hclk = fclk / hdiv;pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);/* print brief summary of clocks, etc */printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));s3c24xx_setup_clocks(fclk, hclk, pclk);
}
再看看s3c24xx_setup_clocks函数

arch\arm\plat-s3c24xx\clock.c
/* initalise all the clocks */void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,unsigned long hclk,unsigned long pclk)
{clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON),clk_xtal.rate);clk_mpll.rate = fclk;clk_h.rate = hclk;clk_p.rate = pclk;clk_f.rate = fclk;
}

文件目录arch\arm\plat-s3c24xx\s3c2410-clock.c
/* s3c2410_baseclk_add()** Add all the clocks used by the s3c2410 or compatible CPUs* such as the S3C2440 and S3C2442.** We cannot use a system device as we are needed before any* of the init-calls that initialise the devices are actually* done.
*/int __init s3c2410_baseclk_add(void)
{unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);            //快慢时钟寄存器unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);             //时钟控制寄存器struct clk *clkp;struct clk *xtal;int ret;int ptr;clk_upll.enable = s3c2410_upll_enable;                           //记录使能函数if (s3c24xx_register_clock(&clk_usb_bus) < 0)                    //注册USB时钟printk(KERN_ERR "failed to register usb bus clock\n");/* register clocks from clock array */clkp = init_clocks;                                              //初始化要注册的clock列表for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { /* ensure that we note the clock state */clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;            //判断clock当前的状态ret = s3c24xx_register_clock(clkp);                      //注册clock列表if (ret < 0) {printk(KERN_ERR "Failed to register clock %s (%d)\n",clkp->name, ret);}}/* We must be careful disabling the clocks we are not intending to* be using at boot time, as subsystems such as the LCD which do* their own DMA requests to the bus can cause the system to lockup* if they where in the middle of requesting bus access.** Disabling the LCD clock if the LCD is active is very dangerous,* and therefore the bootloader should be careful to not enable* the LCD clock if it is not needed.*//* install (and disable) the clocks we do not need immediately */s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); //注册启动不需要使用的clock列表s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));  //禁止clock列表中的各项时钟/* show the clock-slow value */xtal = clk_get(NULL, "xtal");                                   //获得xtal的时钟printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",print_mhz(clk_get_rate(xtal) /( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),(clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",(clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",(clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");s3c_pwmclk_init();                                          //初始化PWM时钟
 return 0;
}
看看init_clocks中都有哪些时钟

目录arch\arm\plat-s3c24xx\s3c2410-clock.c
static struct clk init_clocks[] = {{.name        = "lcd",.id      = -1,.parent       = &clk_h,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_LCDC,}, {.name        = "gpio",.id     = -1,.parent       = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_GPIO,}, {.name        = "usb-host",.id     = -1,.parent       = &clk_h,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_USBH,}, {.name        = "usb-device",.id       = -1,.parent       = &clk_h,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_USBD,}, {.name        = "timers",.id       = -1,.parent       = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_PWMT,}, {.name        = "uart",.id     = 0,.parent        = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_UART0,}, {.name       = "uart",.id     = 1,.parent        = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_UART1,}, {.name       = "uart",.id     = 2,.parent        = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_UART2,}, {.name       = "rtc",.id      = -1,.parent       = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_RTC,}, {.name     = "watchdog",.id     = -1,.parent       = &clk_p,.ctrlbit  = 0,}, {.name      = "usb-bus-host",.id     = -1,.parent       = &clk_usb_bus,}, {.name       = "usb-bus-gadget",.id       = -1,.parent       = &clk_usb_bus,},
};
再看看init_clocks_0ff中都有哪些时钟

目录arch\arm\plat-s3c24xx\s3c2410-clock.c
* standard clock definitions */static struct clk init_clocks_off[] = {{.name     = "nand",.id     = -1,.parent       = &clk_h,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_NAND,}, {.name        = "sdi",.id      = -1,.parent       = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_SDI,}, {.name     = "adc",.id      = -1,.parent       = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_ADC,}, {.name     = "i2c",.id      = -1,.parent       = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_IIC,}, {.name     = "iis",.id      = -1,.parent       = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_IIS,}, {.name     = "spi",.id      = -1,.parent       = &clk_p,.enable       = s3c2410_clkcon_enable,.ctrlbit   = S3C2410_CLKCON_SPI,}
};
到此我们已经知道在系统启动后我们的那些时钟已经启动了,那些没有启动。

S3C2440下clock的源码分析相关推荐

  1. 【学习笔记】Keras库下的resnet源码分析

    Keras库下的resnet源码应用及解读 其实我也不知道这种东西有没有写下来的必要,但是跑代码的时候总摸鱼总归是不好的.虽然很简单,不过我也大概做个学习记录,写给小白看的.源码来自keras文档,大 ...

  2. Unidbg-Linker部分源码分析(下)

    Unidbg-Linker部分源码分析(下) Unidbg-Linker部分源码分析(下) 概要 align resolveLibrary VirtualModule initFunctions ca ...

  3. S3C24XX DMA框架源码分析

    基于S3C2440 的DMA 框架源码分析 基于S3C2440 的DMA 框架源码分析 二寻根溯源 1 设备类的注册 2 s3c2410_dma_init 3 s3c24xx_dma_order_se ...

  4. 【源码分析】Android触摸事件的分发拦截

    Android中View的分发拦截机制是一块重要的内容,网上也有很多大神进行过相关的分析. 在这篇文章里我将以自己的理解尽量全面地分析整个流程,有些分析结果是很多文章没有提及的. 整个分析过程将通过d ...

  5. 视频教程-经典Vue从入门到案例到源码分析教程(含资料)-Vue

    经典Vue从入门到案例到源码分析教程(含资料) 张长志技术全才.擅长领域:区块链.大数据.Java等.10余年软件研发及企业培训经验,曾为多家大型企业提供企业内训如中石化,中国联通,中国移动等知名企业 ...

  6. AndroidVideoCache简单使用及源码分析

    对于视频播放,如果需要用到缓存,AndroidVideoCach是一个不错的选择,该项目地址: https://github.com/danikula/AndroidVideoCache 优缺点: 优 ...

  7. eos源码分析和应用(一)调试环境搭建

    转载自 http://www.limerence2017.com/2018/09/02/eos1/#more eos基于区块链技术实现的开源引擎,开发人员可以基于该引擎开发DAPP(分布式应用).下面 ...

  8. celery源码分析-worker初始化分析(下)

    celery源码分析 本文环境python3.5.2,celery4.0.2,django1.10.x系列 celery的worker启动 在上文中分析到了Hub类的初始化,接下来继续分析Pool类的 ...

  9. Linux下USB suspend/resume源码分析【转】

    转自:http://blog.csdn.net/aaronychen/article/details/3928479 Linux下USB suspend/resume源码分析 Author:aaron ...

最新文章

  1. 3. Swift 数组|字典|集合
  2. 用于python环境下的数据操作_数据分析(一):环境搭建,以及初步操作文件
  3. Jpeglib使用指南, 各种压缩包的压缩和解压方法, 开源社区分裂史
  4. C++实现AOE网中的关键路径算法(邻接表存储)
  5. 理解至上:二叉堆与优先队列详细用法
  6. MAC系统下 win7虚拟机上网应该怎么设置啊
  7. NSSet与NSArray区别
  8. VIM插件——vimplus安装(centos 7)
  9. 一次防火墙无法重启的排查过程和总结
  10. html设置word页脚,Word页码从任意页开始如何设置?
  11. 关于安卓/苹果H5移动端上传视频
  12. 从开发平台到智能供应链,AI技术如何推动企业智能化升级?
  13. 谷歌软件工程师是怎样写设计文档的?
  14. nginx限速_NGINX限速简而言之
  15. 笔记本外接显示屏,FPS下降严重的解决办法
  16. SH7218T拆解手记(4)修改外屏大时钟
  17. 第三方开发者平台地址整理
  18. Vue.js下载与使用
  19. 安卓音乐播放时微信视频微信语音电话进来音乐暂停播放
  20. WebBrowser and Cookies

热门文章

  1. 旭日x3派个人配置总结(ubuntu server + xrdp)
  2. 安卓手机状态栏显示秒_免Root让安卓状态栏时间精确到秒
  3. python 三个点‘...’、Ellipsis符号
  4. c语言链表拆分,P2 拆分链表
  5. java秒转换为年月日_java时间转化为年月日以及将秒转化为天小时分秒字符串显示总结...
  6. 【p4】perforce命令笔记
  7. Python:SM2
  8. 最长的英文单词十大排行榜
  9. Lake Shore PT-100铂电阻温度传感器
  10. 英国AI初创企业OKRA获416万美元A轮融资