void __init sunxi_init_clocks(void) { int i; struct clk *clk; struct factor_init_data *factor; struct periph_init_data *periph; #ifdef CONFIG_SUNXI_CLK_DUMMY_DEBUG sunxi_clk_base = &dummy_reg[0]; dummy_reg_init(); #else /* get clk register base address */ sunxi_clk_base = IO_ADDRESS(0x01c20000); //no change here sunxi_clk_cpus_base = IO_ADDRESS(0x01F01400); // I get it from "1677 PRCM Spec" #endif sunxi_clk_factor_initlimits(); /* register oscs */ clk = clk_register_fixed_rate(NULL, "losc", NULL, CLK_IS_ROOT, 32768); clk_register_clkdev(clk, "losc", NULL); clk = clk_register_fixed_rate(NULL, "hosc", NULL, CLK_IS_ROOT, 24000000); clk_register_clkdev(clk, "hosc", NULL); sunxi_clk_get_factors_ops(&pll_mipi_ops); pll_mipi_ops.get_parent = get_parent_pll_mipi; pll_mipi_ops.set_parent = set_parent_pll_mipi; pll_mipi_ops.enable = clk_enable_pll_mipi; pll_mipi_ops.disable = clk_disable_pll_mipi; /* register normal factors, based on sunxi factor framework */ for(i=0; i<ARRAY_SIZE(sunxi_factos); i++) { factor = &sunxi_factos[i]; clk = sunxi_clk_register_factors(NULL, sunxi_clk_base, &clk_lock,factor); clk_register_clkdev(clk, factor->name, NULL); } /* register fixed factors, based on clk-fixed-factor framework, such as pllx2 for ex. */ clk = clk_register_fixed_factor(NULL, "pll_audiox4", "pll_audio", 0, 8, 2); clk_register_clkdev(clk, "pll_audiox4", NULL); clk = clk_register_fixed_factor(NULL, "pll_videox2", "pll_video", 0, 2, 1); clk_register_clkdev(clk, "pll_videox2", NULL); clk = clk_register_fixed_factor(NULL, "pll_periph0x2", "pll_periph0", 0, 2, 1); clk_register_clkdev(clk, "pll_periph0x2", NULL); clk = clk_register_fixed_factor(NULL, "hoscd2", "hosc", 0, 1, 2); clk_register_clkdev(clk, "hoscd2", NULL); /* force enable only for sun8iw5 PLLs */ for(i=0;i < ARRAY_SIZE(force_enable_clks);i++) { clk = clk_get(NULL,force_enable_clks[i]); if(!clk || IS_ERR(clk)) { clk = NULL; printk("Error not get clk %s\n",force_enable_clks[i]); continue; } clk_prepare_enable(clk); clk_put(clk); clk=NULL; } /* register periph clock */ for(i=0; i<ARRAY_SIZE(sunxi_periphs_init); i++) { periph = &sunxi_periphs_init[i]; if((unsigned int)periph->periph->gate.bus == (unsigned int)LOSC_OUT_GATE) clk = sunxi_clk_register_periph(periph->name, periph->parent_names, periph->num_parents,periph->flags, IO_ADDRESS(0x00000000), periph->periph); else clk = sunxi_clk_register_periph(periph->name, periph->parent_names, periph->num_parents,periph->flags, sunxi_clk_base, periph->periph); clk_register_clkdev(clk, periph->name, NULL); } for(i=0; i<ARRAY_SIZE(sunxi_periphs_cpus_init); i++) { periph = &sunxi_periphs_cpus_init[i]; clk = sunxi_clk_register_periph(periph->name, periph->parent_names, periph->num_parents,periph->flags, sunxi_clk_cpus_base , periph->periph); clk_register_clkdev(clk, periph->name, NULL); } clk_add_alias("pll1",NULL,"pll_cpu0",NULL); clk_add_alias("pll2",NULL,"pll_audio",NULL); clk_add_alias("pll3",NULL,"pll_video",NULL); clk_add_alias("pll4",NULL,"pll_ve",NULL); clk_add_alias("pll5",NULL,"pll_ddr0",NULL); clk_add_alias("pll6",NULL,"pll_periph0",NULL); clk_add_alias("pll8",NULL,"pll_gpu",NULL); clk_add_alias("pll9",NULL,"pll_hsic",NULL); clk_add_alias("pll10",NULL,"pll_de",NULL); clk_add_alias("pll6ahb1",NULL,"pll_periph0ahb1",NULL); #ifdef CONFIG_COMMON_CLK_ENABLE_SYNCBOOT_EARLY clk_syncboot(); #endif }
static int __init sunxi_init_ac100_clocks(void) { struct clk *clk; struct clk *parent; int i; struct periph_init_data *periph; if (arisc_rsb_set_rtsaddr(RSB_DEVICE_SADDR7, RSB_RTSADDR_AC100)) { pr_err("%s err: config codec failed\n", __func__); return -1; } //reigster source for AC100 32K clk = clk_register_fixed_rate(NULL, "32k_rtc", NULL, CLK_IS_ROOT, 32768); clk_register_clkdev(clk, "32k_rtc", NULL); clk = clk_register_fixed_rate(NULL, "4m_adda", NULL, CLK_IS_ROOT, 4000000); clk_register_clkdev(clk, "4m_adda", NULL); sunxi_clk_get_periph_ops(&ac100_clkops); ac100_clkops.prepare = ac100_clkops.enable; ac100_clkops.unprepare = ac100_clkops.disable; ac100_clkops.enable = NULL; ac100_clkops.disable = NULL; ac100_clkops.recalc_rate = sunxi_ac100_recalc_rate; ac100_clkops.round_rate = sunxi_ac100_round_rate; ac100_clkops.set_rate = __sunxi_clk_periph_set_rate; ac100_regops.reg_writel = ac100_writel; ac100_regops.reg_readl = ac100_readl; /* register AC100 clock */ for(i=0; i<ARRAY_SIZE(sunxi_ac100_init); i++) { periph = &sunxi_ac100_init[i]; periph->periph->priv_clkops = &ac100_clkops; periph->periph->priv_regops = &ac100_regops; clk = sunxi_clk_register_periph(periph->name, periph->parent_names, periph->num_parents,periph->flags, NULL, periph->periph); clk_register_clkdev(clk, periph->name, NULL); } //Sync enable count for Ac100 for(i=0; i<ARRAY_SIZE(sunxi_ac100_init); i++) { periph = &sunxi_ac100_init[i]; clk = clk_get(NULL,periph->name); if(!clk || IS_ERR(clk)) continue; if((!clk->prepare_count) && (!clk->enable_count) && clk->ops->is_enabled(clk->hw)) { clk->prepare_count++; clk->enable_count++; parent = clk->parent; while(parent) { parent->enable_count++; parent->prepare_count++; parent = parent->parent; } } clk_put(clk); } return 0; }
void __init sunxi_init_clocks(void) { int i; struct clk *clk; struct factor_init_data *factor; struct periph_init_data *periph; #ifdef CONFIG_SUNXI_CLK_DUMMY_DEBUG sunxi_clk_base = &dummy_reg[0]; dummy_reg_init(); #else /* get clk register base address */ sunxi_clk_base = IO_ADDRESS(0x01c20000); #endif sunxi_clk_factor_initlimits(); /* register oscs */ clk = clk_register_fixed_rate(NULL, "losc", NULL, CLK_IS_ROOT, 32768); clk_register_clkdev(clk, "losc", NULL); clk = clk_register_fixed_rate(NULL, "hosc", NULL, CLK_IS_ROOT, 24000000); clk_register_clkdev(clk, "hosc", NULL); /* register normal factors, based on sunxi factor framework */ for(i=0; i<ARRAY_SIZE(sunxi_factos); i++) { factor = &sunxi_factos[i]; clk = sunxi_clk_register_factors(NULL, sunxi_clk_base, &clk_lock,factor); clk_register_clkdev(clk, factor->name, NULL); } /* register fixed factors, based on clk-fixed-factor framework, such as pllx2 for ex. */ clk = clk_register_fixed_factor(NULL, "pll_audiox8", "pll_audio", 0, 8, 1); clk_register_clkdev(clk, "pll_audiox8", NULL); clk = clk_register_fixed_factor(NULL, "pll_audiox4", "pll_audio", 0, 8, 2); clk_register_clkdev(clk, "pll_audiox4", NULL); clk = clk_register_fixed_factor(NULL, "pll_audiox2", "pll_audio", 0, 8, 4); clk_register_clkdev(clk, "pll_audiox2", NULL); clk = clk_register_fixed_factor(NULL, "pll_videox2", "pll_video", 0, 2, 1); clk_register_clkdev(clk, "pll_videox2", NULL); clk = clk_register_fixed_factor(NULL, "pll_periph0x2", "pll_periph0", 0, 2, 1); clk_register_clkdev(clk, "pll_periph0x2", NULL); clk = clk_register_fixed_factor(NULL, "pll_periph0d2", "pll_periph0", 0, 1, 2); clk_register_clkdev(clk, "pll_periph0d2", NULL); clk = clk_register_fixed_factor(NULL, "hoscd2", "hosc", 0, 1, 2); clk_register_clkdev(clk, "hoscd2", NULL); /* register periph clock */ for(i=0; i<ARRAY_SIZE(sunxi_periphs_init); i++) { periph = &sunxi_periphs_init[i]; clk = sunxi_clk_register_periph(periph->name, periph->parent_names, periph->num_parents,periph->flags, sunxi_clk_base, periph->periph); clk_register_clkdev(clk, periph->name, NULL); } clk = clk_get(NULL,"ahb1"); if(!clk || IS_ERR(clk)) printk("Error not get clk ahb1\n"); else { struct clk *parent_clk = clk_get(NULL,"pll_periph0d2"); if(!parent_clk || IS_ERR(parent_clk)) { printk("%d Error not get clk pll_periph0d2\n" , __LINE__); } else { printk("%d ahb1 set parent pll_periph0d2\n" , __LINE__); clk_set_parent(clk,parent_clk); clk_put(parent_clk); } clk_put(clk); } clk_add_alias("pll1",NULL,"pll_cpu",NULL); clk_add_alias("pll2",NULL,"pll_audio",NULL); clk_add_alias("pll3",NULL,"pll_video",NULL); clk_add_alias("pll4",NULL,"pll_ve",NULL); clk_add_alias("pll5",NULL,"pll_ddr0",NULL); clk_add_alias("pll6",NULL,"pll_periph0",NULL); clk_add_alias("pll6ahb0",NULL,"pll_periphahb0",NULL); #ifdef CONFIG_COMMON_CLK_ENABLE_SYNCBOOT_EARLY clk_syncboot(); #endif }