static void __init rk3188a_clk_init(struct device_node *np) { struct clk *clk1, *clk2; unsigned long rate; int ret; rk3188_common_clk_init(np); rockchip_clk_register_plls(rk3188_pll_clks, ARRAY_SIZE(rk3188_pll_clks), RK3188_GRF_SOC_STATUS); rockchip_clk_register_branches(rk3188_clk_branches, ARRAY_SIZE(rk3188_clk_branches)); rockchip_clk_register_armclk(ARMCLK, "armclk", mux_armclk_p, ARRAY_SIZE(mux_armclk_p), &rk3188_cpuclk_data, rk3188_cpuclk_rates, ARRAY_SIZE(rk3188_cpuclk_rates)); /* reparent aclk_cpu_pre from apll */ clk1 = __clk_lookup("aclk_cpu_pre"); clk2 = __clk_lookup("gpll"); if (clk1 && clk2) { rate = clk_get_rate(clk1); ret = clk_set_parent(clk1, clk2); if (ret < 0) pr_warn("%s: could not reparent aclk_cpu_pre to gpll\n", __func__); clk_set_rate(clk1, rate); } else { pr_warn("%s: missing clocks to reparent aclk_cpu_pre to gpll\n", __func__); } }
struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock) { struct clk *clk; struct clk *pclk; struct meson_clk_cpu *clk_cpu; struct clk_init_data init; int ret; clk_cpu = kzalloc(sizeof(*clk_cpu), GFP_KERNEL); if (!clk_cpu) return ERR_PTR(-ENOMEM); clk_cpu->base = reg_base; clk_cpu->reg_off = clk_conf->reg_off; clk_cpu->div_table = clk_conf->conf.div_table; clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb; init.name = clk_conf->clk_name; init.ops = &meson_clk_cpu_ops; init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE; init.flags |= CLK_SET_RATE_PARENT; init.parent_names = clk_conf->clks_parent; init.num_parents = 1; clk_cpu->hw.init = &init; pclk = __clk_lookup(clk_conf->clks_parent[0]); if (!pclk) { pr_err("%s: could not lookup parent clock %s\n", __func__, clk_conf->clks_parent[0]); ret = -EINVAL; goto free_clk; } ret = clk_notifier_register(pclk, &clk_cpu->clk_nb); if (ret) { pr_err("%s: failed to register clock notifier for %s\n", __func__, clk_conf->clk_name); goto free_clk; } clk = clk_register(NULL, &clk_cpu->hw); if (IS_ERR(clk)) { ret = PTR_ERR(clk); goto unregister_clk_nb; } return clk; unregister_clk_nb: clk_notifier_unregister(pclk, &clk_cpu->clk_nb); free_clk: kfree(clk_cpu); return ERR_PTR(ret); }
void dsi_clock_on(struct display_driver *dispdrv) { if (!dispdrv->dsi_driver.clk) { dispdrv->dsi_driver.clk = __clk_lookup("clk_dsim1"); if (IS_ERR(dispdrv->dsi_driver.clk)) { pr_err("Failed to clk_get - clk_dsim1\n"); return; } } clk_prepare_enable(dispdrv->dsi_driver.clk); }
/* utility function to get the rate of a specified clock */ unsigned long _get_rate(const char *clk_name) { struct clk *clk; clk = __clk_lookup(clk_name); if (!clk) { pr_err("%s: could not find clock %s\n", __func__, clk_name); return 0; } return clk_get_rate(clk); }
void __init rockchip_clk_protect_critical(const char *clocks[], int nclocks) { int i; /* Protect the clocks that needs to stay on */ for (i = 0; i < nclocks; i++) { struct clk *clk = __clk_lookup(clocks[i]); if (clk) clk_prepare_enable(clk); } }
static void __init rockchip_clk_set_rate(char *clock, unsigned long rate) { struct clk *clk; clk = __clk_lookup(clock); if(clk && !IS_ERR(clk)) { clk_set_rate(clk, rate); return; } pr_err("%s: missing clock %s when setting initial rate to %lu\n", __func__, clock, rate); }
int enable_display_decon_clocks(struct device *dev) { int ret = 0; struct display_driver *dispdrv; struct s3c_fb *sfb; dispdrv = get_display_driver(); sfb = dispdrv->decon_driver.sfb; DISPLAY_CLOCK_INLINE_SET_PARENT(mout_fimd1, mout_mpll_ctrl); #if !defined (CONFIG_SOC_EXYNOS5422_REV_0) DISPLAY_CLOCK_INLINE_SET_PARENT(mout_fimd1_mdnie1, mout_fimd1); #endif #if defined(CONFIG_DECON_LCD_S6E8AA0) DISPLAY_INLINE_SET_RATE(dout_fimd1, 67 * MHZ); #elif defined(CONFIG_DECON_LCD_S6E3FA0) || defined(CONFIG_DECON_LCD_S6E3FA2) DISPLAY_INLINE_SET_RATE(dout_fimd1, 133 * MHZ); #else DISPLAY_INLINE_SET_RATE(dout_fimd1, 266 * MHZ); #endif DISPLAY_CLOCK_INLINE_SET_PARENT(mout_aclk_300_disp1_user, mout_aclk_300_disp1_sw); DISPLAY_CLOCK_INLINE_SET_PARENT(mout_aclk_300_disp1_sw, dout_aclk_300_disp1); DISPLAY_CLOCK_INLINE_SET_PARENT(mout_aclk_300_disp1, mout_dpll_ctrl); DISPLAY_INLINE_SET_RATE(dout_aclk_300_disp1, 300 * MHZ); DISPLAY_CLOCK_INLINE_SET_PARENT(mout_aclk_400_disp1_user, mout_aclk_400_disp1_sw); DISPLAY_CLOCK_INLINE_SET_PARENT(mout_aclk_400_disp1_sw, dout_aclk_400_disp1); DISPLAY_CLOCK_INLINE_SET_PARENT(mout_aclk_400_disp1, mout_dpll_ctrl); #ifdef CONFIG_FB_HIBERNATION_DISPLAY_CLOCK_GATING dispdrv->pm_status.ops->clk_on(dispdrv); #else if (!dispdrv->dsi_driver.clk) { dispdrv->dsi_driver.clk = __clk_lookup("clk_dsim1"); if (IS_ERR(dispdrv->dsi_driver.clk)) { pr_err("Failed to clk_get - clk_dsim1\n"); return ret; } } clk_prepare_enable(dispdrv->dsi_driver.clk); clk_prepare_enable(sfb->bus_clk); clk_prepare_enable(sfb->axi_disp1); if (!sfb->variant.has_clksel) clk_prepare_enable(sfb->lcd_clk); #endif return ret; }
static void __init rockchip_reparent_clk(char *clock, char *new_parent) { struct clk *clk1, *clk2; unsigned long rate; int ret; clk1 = __clk_lookup(clock); clk2 = __clk_lookup(new_parent); if (!IS_ERR(clk1) && !IS_ERR(clk2)) { rate = clk_get_rate(clk1); ret = clk_set_parent(clk1, clk2); if (ret < 0) pr_err("%s: could not reparent %s to %s, ret=%d\n", __func__, clock, new_parent, ret); clk_set_rate(clk1, rate); } else { pr_err("%s: missing clocks to reparent %s to %s\n", __func__, clock, new_parent); } }
unsigned int pn547_enable_clk(const char *conid, bool enable) { struct clk *target; target = __clk_lookup(conid); if (IS_ERR(target)) { pr_err("%s: could not lookup clock : %s\n", __func__, conid); return -EINVAL; } if (enable) { return clk_enable(target); } else { clk_disable(target); return 0; } }
struct clk *rockchip_clk_register_cpuclk(const char *name, const char *const *parent_names, u8 num_parents, const struct rockchip_cpuclk_reg_data *reg_data, const struct rockchip_cpuclk_rate_table *rates, int nrates, void __iomem *reg_base, spinlock_t *lock) { struct rockchip_cpuclk *cpuclk; struct clk_init_data init; struct clk *clk, *cclk; int ret; if (num_parents < 2) { pr_err("%s: needs at least two parent clocks\n", __func__); return ERR_PTR(-EINVAL); } cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); if (!cpuclk) return ERR_PTR(-ENOMEM); init.name = name; init.parent_names = &parent_names[reg_data->mux_core_main]; init.num_parents = 1; init.ops = &rockchip_cpuclk_ops; /* only allow rate changes when we have a rate table */ init.flags = (nrates > 0) ? CLK_SET_RATE_PARENT : 0; /* disallow automatic parent changes by ccf */ init.flags |= CLK_SET_RATE_NO_REPARENT; init.flags |= CLK_GET_RATE_NOCACHE; cpuclk->reg_base = reg_base; cpuclk->lock = lock; cpuclk->reg_data = reg_data; cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb; cpuclk->hw.init = &init; cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]); if (!cpuclk->alt_parent) { pr_err("%s: could not lookup alternate parent: (%d)\n", __func__, reg_data->mux_core_alt); ret = -EINVAL; goto free_cpuclk; } ret = clk_prepare_enable(cpuclk->alt_parent); if (ret) { pr_err("%s: could not enable alternate parent\n", __func__); goto free_cpuclk; } clk = __clk_lookup(parent_names[reg_data->mux_core_main]); if (!clk) { pr_err("%s: could not lookup parent clock: (%d) %s\n", __func__, reg_data->mux_core_main, parent_names[reg_data->mux_core_main]); ret = -EINVAL; goto free_alt_parent; } ret = clk_notifier_register(clk, &cpuclk->clk_nb); if (ret) { pr_err("%s: failed to register clock notifier for %s\n", __func__, name); goto free_alt_parent; } if (nrates > 0) { cpuclk->rate_count = nrates; cpuclk->rate_table = kmemdup(rates, sizeof(*rates) * nrates, GFP_KERNEL); if (!cpuclk->rate_table) { pr_err("%s: could not allocate memory for cpuclk rates\n", __func__); ret = -ENOMEM; goto unregister_notifier; } } cclk = clk_register(NULL, &cpuclk->hw); if (IS_ERR(cclk)) { pr_err("%s: could not register cpuclk %s\n", __func__, name); ret = PTR_ERR(cclk); goto free_rate_table; } return cclk; free_rate_table: kfree(cpuclk->rate_table); unregister_notifier: clk_notifier_unregister(clk, &cpuclk->clk_nb); free_alt_parent: clk_disable_unprepare(cpuclk->alt_parent); free_cpuclk: kfree(cpuclk); return ERR_PTR(ret); }