Linux 时钟模块分析2
来源:互联网 发布:打淘宝客服要话费吗 编辑:程序博客网 时间:2024/05/01 12:18
1. 数据结构
struct clk {unsigned int rate;};struct nxp_clk_periph {const char*dev_name;int dev_id;char periph_id;void *base_addr;bool enable;/* clock config */char level;unsigned int clk_mask0;unsigned int clk_mask1;short clk_src0;short clk_div0;char clk_inv0;short clk_src1;short clk_div1;char clk_inv1;long clk_ext1;long clk_ext2;spinlock_t lock;};struct nxp_clk_dev {struct clk clk;struct clk *link;const char *name;struct nxp_clk_periph *peri;};struct clk_link_dev {char *name;int id;};struct clk_gen_reg {volatile U32 CLKENB;volatile U32 CLKGEN[4];};
2.执行流程
定义15个clk_core
static struct clk_core {int id;const char *name;struct list_head list;} clk_core[] = {[ 0] = { .id = 0, .name = CORECLK_NAME_PLL0, .list = LIST_INIT( 0), },[ 1] = { .id = 1, .name = CORECLK_NAME_PLL1, .list = LIST_INIT( 1), },[ 2] = { .id = 2, .name = CORECLK_NAME_PLL2, .list = LIST_INIT( 2), },[ 3] = { .id = 3, .name = CORECLK_NAME_PLL3, .list = LIST_INIT( 3), },[ 4] = { .id = 4, .name = CORECLK_NAME_FCLK, .list = LIST_INIT( 4), },[ 5] = { .id = 5, .name = CORECLK_NAME_MCLK, .list = LIST_INIT( 5), },[ 6] = { .id = 6, .name = CORECLK_NAME_BCLK, .list = LIST_INIT( 6), },[ 7] = { .id = 7, .name = CORECLK_NAME_PCLK, .list = LIST_INIT( 7), },[ 8] = { .id = 8, .name = CORECLK_NAME_HCLK, .list = LIST_INIT( 8), },[ 9] = { .id = 9, .name = "memdclk", .list = LIST_INIT( 9), },[10] = { .id = 10, .name = "membclk", .list = LIST_INIT(10), },[11] = { .id = 11, .name = "mempclk", .list = LIST_INIT(11), },[12] = { .id = 12, .name = "g3dbclk", .list = LIST_INIT(12), },[13] = { .id = 13, .name = "mpegbclk", .list = LIST_INIT(13), },[14] = { .id = 14, .name = "mpegpclk", .list = LIST_INIT(14), },};定义若干nxp_clk_periph 和 clk_link_dev
static struct nxp_clk_periph clk_periphs [] = {CLK_PERI_1S(DEV_NAME_TIMER, 0, CLK_ID_TIMER_0, PHY_BASEADDR_CLKGEN14, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_TIMER, 1, CLK_ID_TIMER_1, PHY_BASEADDR_CLKGEN0 , (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_TIMER, 2, CLK_ID_TIMER_2, PHY_BASEADDR_CLKGEN1 , (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_TIMER, 3, CLK_ID_TIMER_3, PHY_BASEADDR_CLKGEN2 , (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_UART, 0, CLK_ID_UART_0 , PHY_BASEADDR_CLKGEN22, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_UART, 1, CLK_ID_UART_1 , PHY_BASEADDR_CLKGEN24, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_UART, 2, CLK_ID_UART_2 , PHY_BASEADDR_CLKGEN23, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_UART, 3, CLK_ID_UART_3 , PHY_BASEADDR_CLKGEN25, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_UART, 4, CLK_ID_UART_4 , PHY_BASEADDR_CLKGEN26, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_UART, 5, CLK_ID_UART_5 , PHY_BASEADDR_CLKGEN27, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_PWM, 0, CLK_ID_PWM_0 , PHY_BASEADDR_CLKGEN13, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_PWM, 1, CLK_ID_PWM_1 , PHY_BASEADDR_CLKGEN3 , (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_PWM, 2, CLK_ID_PWM_2 , PHY_BASEADDR_CLKGEN4 , (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_PWM, 3, CLK_ID_PWM_3 , PHY_BASEADDR_CLKGEN5 , (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_I2C, 0, CLK_ID_I2C_0 , PHY_BASEADDR_CLKGEN6 , (_GATE_PCLK_)),CLK_PERI_1S(DEV_NAME_I2C, 1, CLK_ID_I2C_1 , PHY_BASEADDR_CLKGEN7 , (_GATE_PCLK_)),CLK_PERI_1S(DEV_NAME_I2C, 2, CLK_ID_I2C_2 , PHY_BASEADDR_CLKGEN8 , (_GATE_PCLK_)),CLK_PERI_2S(DEV_NAME_I2S, 0, CLK_ID_I2S_0 , PHY_BASEADDR_CLKGEN15, (_PLL_0_3_|_EXTCLK1_), (_CLKOUTn_)),CLK_PERI_2S(DEV_NAME_I2S, 1, CLK_ID_I2S_1 , PHY_BASEADDR_CLKGEN16, (_PLL_0_3_|_EXTCLK1_), (_CLKOUTn_)),CLK_PERI_2S(DEV_NAME_I2S, 2, CLK_ID_I2S_2 , PHY_BASEADDR_CLKGEN17, (_PLL_0_3_|_EXTCLK1_), (_CLKOUTn_)),CLK_PERI_1S(DEV_NAME_SDHC, 0, CLK_ID_SDHC_0 , PHY_BASEADDR_CLKGEN18, (_PLL_0_2_|_GATE_PCLK_)),CLK_PERI_1S(DEV_NAME_SDHC, 1, CLK_ID_SDHC_1 , PHY_BASEADDR_CLKGEN19, (_PLL_0_2_|_GATE_PCLK_)),CLK_PERI_1S(DEV_NAME_SDHC, 2, CLK_ID_SDHC_2 , PHY_BASEADDR_CLKGEN20, (_PLL_0_2_|_GATE_PCLK_)),CLK_PERI_1S(DEV_NAME_SPI, 0, CLK_ID_SPI_0 , PHY_BASEADDR_CLKGEN37, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_SPI, 1, CLK_ID_SPI_1 , PHY_BASEADDR_CLKGEN38, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_SPI, 2, CLK_ID_SPI_2, PHY_BASEADDR_CLKGEN39, (_PLL_0_2_)),#if 0CLK_PERI_1S(DEV_NAME_VIP, 0, CLK_ID_VIP_0 , PHY_BASEADDR_CLKGEN30, (_PLL_0_3_|_EXTCLK1_|_GATE_BCLK_)),CLK_PERI_1S(DEV_NAME_VIP, 1, CLK_ID_VIP_1 , PHY_BASEADDR_CLKGEN31, (_PLL_0_3_|_EXTCLK1_|_EXTCLK2_|_GATE_BCLK_)),#endifCLK_PERI_1S(DEV_NAME_MIPI, -1, CLK_ID_MIPI, PHY_BASEADDR_CLKGEN9 , (_PLL_0_2_)),CLK_PERI_2S(DEV_NAME_GMAC, -1, CLK_ID_GMAC, PHY_BASEADDR_CLKGEN10, (_PLL_0_3_|_EXTCLK1_), (_CLKOUTn_)),CLK_PERI_1S(DEV_NAME_SPDIF_TX, -1, CLK_ID_SPDIF_TX, PHY_BASEADDR_CLKGEN11, (_PLL_0_2_)),CLK_PERI_1S(DEV_NAME_MPEGTSI, -1, CLK_ID_MPEGTSI, PHY_BASEADDR_CLKGEN12, (_GATE_BCLK_)),#if 0CLK_PERI_1S(DEV_NAME_MALI, -1, CLK_ID_MALI, PHY_BASEADDR_CLKGEN21, (_GATE_BCLK_)),#endifCLK_PERI_1S(DEV_NAME_DIT, -1, CLK_ID_DIT, PHY_BASEADDR_CLKGEN28, (_GATE_BCLK_)),CLK_PERI_1S(DEV_NAME_PPM, -1, CLK_ID_PPM, PHY_BASEADDR_CLKGEN29, (_PLL_0_2_)),#if 0CLK_PERI_2S(DEV_NAME_USB2HOST, -1, CLK_ID_USB2HOST, PHY_BASEADDR_CLKGEN32, (_PLL_0_3_), (_PLL_0_3_|_EXTCLK1_)),CLK_PERI_1S(DEV_NAME_CODA, -1, CLK_ID_CODA, PHY_BASEADDR_CLKGEN33, (_GATE_PCLK_|_GATE_BCLK_)),#endifCLK_PERI_1S(DEV_NAME_CRYPTO, -1, CLK_ID_CRYPTO , PHY_BASEADDR_CLKGEN34, (_GATE_PCLK_)),CLK_PERI_1S(DEV_NAME_SCALER, -1, CLK_ID_SCALER , PHY_BASEADDR_CLKGEN35, (_GATE_BCLK_)),CLK_PERI_1S(DEV_NAME_PDM, -1, CLK_ID_PDM, PHY_BASEADDR_CLKGEN36, (_GATE_PCLK_)),#if 0CLK_PERI_2S(DEV_NAME_USBOTG, -1, CLK_ID_USBOTG, PHY_BASEADDR_CLKGEN32, (_PLL_0_3_), (_PLL_0_3_|_EXTCLK1_)),#endif};static struct clk_link_dev clk_link[] = {{ .name = "uart-pl011.0", .id = CLK_ID_UART_0, },{ .name = "uart-pl011.1", .id = CLK_ID_UART_1, },{ .name = "uart-pl011.2", .id = CLK_ID_UART_2, },{ .name = "uart-pl011.3", .id = CLK_ID_UART_3, },{ .name = "uart-pl011.4", .id = CLK_ID_UART_4, },{ .name = "uart-pl011.5", .id = CLK_ID_UART_5, },{ .name = "ssp-pl022.0" , .id = CLK_ID_SPI_0 , },{ .name = "ssp-pl022.1" , .id = CLK_ID_SPI_1 , },{ .name = "ssp-pl022.2" , .id = CLK_ID_SPI_2 , },};#defineCLK_PERI_NUM((int)ARRAY_SIZE(clk_periphs))#defineCLK_CORE_NUM((int)ARRAY_SIZE(clk_core))#defineCLK_LINK_NUM((int)ARRAY_SIZE(clk_link))#defineCLK_DEVS_NUM(CLK_CORE_NUM + CLK_PERI_NUM + CLK_LINK_NUM)#defineMAX_DIVIDER((1<<8) - 1)// 256, align 2
static void __init cpu_map_io(void){.....................................nxp_cpu_base_init();nxp_board_base_init();nxp_cpu_clock_init();nxp_cpu_clock_print();}在cpu_map_iocpu_map_io最后调用nxp_cpu_clock_init 和 nxp_cpu_clock_print来初始化时钟模块和打印时钟信息
static int __init cpu_pll_sys_init(void){struct kobject *kobj = NULL;int ret = 0;/* create attribute interface */kobj = kobject_create_and_add("pll", &platform_bus.kobj);if (!kobj) {printk(KERN_ERR "Fail, create kobject for cpu\n");return -ret;}ret = sysfs_create_group(kobj, &attr_group);if (ret) {printk(KERN_ERR "Fail, create sysfs group for pll ...\n");kobject_del(kobj);return -ret;}return ret;}module_init(cpu_pll_sys_init);创建目录 /sys/bus/platform/pll 和文件 /sys/bus/platform/pl/pll.0 /sys/bus/platform/pl/pll.1 /sys/bus/platform/pl/pll.2 /sys/bus/platform/pl/pll.3
1 0
- Linux 时钟模块分析2
- Linux 时钟模块分析1
- linux中CPU各个模块的时钟驱动函数分析
- linux内核时钟模块
- s3c2410实时时钟模块要点分析
- s3c2410实时时钟模块要点分析
- linux 模块Makefile 分析2
- linux 时钟源初步分析
- linux内核动态时钟分析
- Linux时钟管理透彻分析
- Linux 内核时钟架构之时钟源模块对外接口
- linux kernel 模块时钟的用法
- linux kernel 模块时钟的用法
- TMS320F28335 时钟分析2
- linux模块参数分析
- linux 模块 Makefile 分析
- linux简单模块分析
- ARM-linux s3c2440 之时钟分析
- log4j配置示例&Spring集成log4j
- Division (斜率dp)
- 面试题:两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
- 2016四川省赛 Floyd-Warshall
- [LeetCode]--67. Add Binary
- Linux 时钟模块分析2
- |洛谷|动态规划|P1156 垃圾陷阱
- framebuffer简介与应用
- Cache-Control no-cache与max-age=0的区别
- 机器学习笔记(十五)——HMM序列问题和维特比算法
- HDU 2031 进制转换
- BZOJ2093[Poi2010] Frog
- 【Maven实战】05 依赖
- Java笔试面试题二(常考问答)