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
原创粉丝点击