//[+++]Add for those clocks which block CXO or PXO static int clock_debug_print_clock_Block_XO(struct clk *c) { char *start = ""; struct clk *d = NULL; if (!c || !c->count) return 0; d=clk_get_parent(c); if (d == NULL) return 0; pr_info("\t"); do { if (c->vdd_class) pr_cont("%s%s [%ld, %lu]", start, c->dbg_name, c->rate, c->vdd_class->cur_level); else pr_cont("%s%s [%ld]", start, c->dbg_name, c->rate); start = " -> "; } while ((c = clk_get_parent(c))); pr_cont("\n"); return 1; }
static long tegra_dc_rgb_setup_clk(struct tegra_dc *dc, struct clk *clk) { unsigned long rate; struct clk *parent_clk = clk_get_sys(NULL, dc->out->parent_clk ? : "pll_p"); if (dc->out->parent_clk_backup && (parent_clk == clk_get_sys(NULL, "pll_p"))) { rate = tegra_dc_pclk_predict_rate( dc->out->type, parent_clk, dc->mode.pclk); /* use pll_d as last resort */ if (rate < (dc->mode.pclk / 100 * 99) || rate > (dc->mode.pclk / 100 * 109)) parent_clk = clk_get_sys( NULL, dc->out->parent_clk_backup); } if (clk_get_parent(clk) != parent_clk) clk_set_parent(clk, parent_clk); if (parent_clk != clk_get_sys(NULL, "pll_p")) { struct clk *base_clk = clk_get_parent(parent_clk); /* Assuming either pll_d or pll_d2 is used */ rate = dc->mode.pclk * 2; if (rate != clk_get_rate(base_clk)) clk_set_rate(base_clk, rate); } return tegra_dc_pclk_round_rate(dc, dc->mode.pclk); }
static int gk20a_init_clk_setup_sw(struct gk20a *g) { struct clk_gk20a *clk = &g->clk; static int initialized; struct clk *ref; unsigned long ref_rate; gk20a_dbg_fn(""); if (clk->sw_ready) { gk20a_dbg_fn("skip init"); return 0; } if (!gk20a_clk_get(g)) return -EINVAL; ref = clk_get_parent(clk_get_parent(clk->tegra_clk)); if (IS_ERR(ref)) { gk20a_err(dev_from_gk20a(g), "failed to get GPCPLL reference clock"); return -EINVAL; } ref_rate = clk_get_rate(ref); clk->pll_delay = 300; /* usec */ clk->gpc_pll.id = GK20A_GPC_PLL; clk->gpc_pll.clk_in = ref_rate / KHZ; /* Decide initial frequency */ if (!initialized) { initialized = 1; clk->gpc_pll.M = 1; clk->gpc_pll.N = DIV_ROUND_UP(gpc_pll_params.min_vco, clk->gpc_pll.clk_in); clk->gpc_pll.PL = 1; clk->gpc_pll.freq = clk->gpc_pll.clk_in * clk->gpc_pll.N; clk->gpc_pll.freq /= pl_to_div[clk->gpc_pll.PL]; } mutex_init(&clk->clk_mutex); clk->sw_ready = true; gk20a_dbg_fn("done"); return 0; }
void dss_dump_clocks(struct seq_file *s) { unsigned long dpll4_ck_rate; unsigned long dpll4_m4_ck_rate; dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck); seq_printf(s, "- DSS -\n"); seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); if (cpu_is_omap3630()) seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", dpll4_ck_rate, dpll4_ck_rate / dpll4_m4_ck_rate, dss_clk_get_rate(DSS_CLK_FCK1)); else seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n", dpll4_ck_rate, dpll4_ck_rate / dpll4_m4_ck_rate, dss_clk_get_rate(DSS_CLK_FCK1)); dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); }
void onoff_uart_clock(int onoff) { struct clk *parentClk = NULL; parentClk = clk_get_parent(console_uart->uartClk); if(onoff == 1) { if(onoff_uart == 0) { printk("onoff_uart_clock on\n"); clk_enable(parentClk); wake_unlock(&(console_uart->lock)); onoff_uart = 1; } } else { if(onoff_uart == 1) { printk("onoff_uart_clock off\n"); wake_lock(&(console_uart->lock)); clk_disable(parentClk); onoff_uart--; } } }
void clk_disable(struct clk *clk) { unsigned long flags; if (!clk) return; spin_lock_irqsave(&clk->lock, flags); if (WARN(clk->count == 0, "%s is unbalanced", clk->dbg_name)) goto out; if (clk->count == 1) { struct clk *parent = clk_get_parent(clk); if (clk->ops->disable) clk->ops->disable(clk); unvote_rate_vdd(clk, clk->rate); if (!(clk->flags&CLKFLAG_IGNORE)) { /*added by htc for clock debugging*/ clk_disable(clk->depends); clk_disable(parent); /*added by htc for clock debugging*/ spin_lock(&clk_enable_list_lock); list_del(&clk->enable_list); spin_unlock(&clk_enable_list_lock); } } clk->count--; out: spin_unlock_irqrestore(&clk->lock, flags); }
void exit_lp_audio_mode(void) { struct clk *tclk; struct clk *p_clk; struct clk *rmode_parent_clk; int ret; /* Set the voltage to 1.05v for the GP domain. */ ret = regulator_set_voltage(gp_core, GP_NORMAL_VOLTAGE, GP_NORMAL_VOLTAGE); if (ret < 0) printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!\n"); rmode_parent_clk = clk_get(NULL, "pll2"); clk_enable(rmode_parent_clk); tclk = clk_get(NULL, "main_bus_clk"); p_clk = clk_get_parent(tclk); /* Set the dividers before setting the parent clock. */ clk_set_rate(clk_get(NULL, "axi_a_clk"), 6000000); clk_set_rate(clk_get(NULL, "axi_b_clk"), 4800000); clk_set_rate(clk_get(NULL, "ahb_clk"), 4800000); clk_set_rate(clk_get(NULL, "emi_slow_clk"), 4800000); clk_set_rate(clk_get(NULL, "nfc_clk"), 1200000); /* Set the parent of main_bus_clk to be pll2 */ clk_set_parent(tclk, rmode_parent_clk); #ifdef CHANGE_DDR2_TO_PLL2 tclk = clk_get(NULL, "ddr_clk"); clk_set_parent(tclk, clk_get(NULL, "axi_a_clk")); /* Set CPU clock to be derived from PLL1 instead of PLL2 */ tclk = clk_get(NULL, "pll1_sw_clk"); clk_set_parent(tclk, clk_get(NULL, "pll1_main_clk")); clk_disable(tclk); tclk = clk_get(NULL, "ddr_clk"); clk_set_parent(tclk, clk_get(NULL, "ddr_hf_clk")); #endif tclk = clk_get(NULL, "cpu_clk"); ret = clk_set_rate(tclk, org_cpu_rate); if (ret != 0) printk(KERN_DEBUG "cannot set CPU clock rate\n"); clk_put(tclk); tclk = clk_get(NULL, "cpu_clk"); ret = clk_set_rate(tclk, org_cpu_rate); if (ret != 0) printk(KERN_DEBUG "cannot set CPU clock rate\n"); /*Change the DDR freq to 200MHz*/ tclk = clk_get(NULL, "ddr_hf_clk"); clk_set_rate(tclk, clk_round_rate(tclk, 200000000)); lp_audio_mode = 0; }
static int sys_timer_notifier(struct clk *clk, unsigned int cmd, unsigned long wparam, unsigned long lparam) { int ret = 0; struct clk *p; switch(cmd) { case HISILICON_CLK_REGISTER: case HISILICON_CLK_PARENT_SETRATE: p = clk_get_parent(clk); if(p==NULL) break; hisilicon_timer_reload = BUSCLK_TO_TIMER_RELOAD(clk_get_rate(p)); writel(hisilicon_timer_reload, CFG_TIMER_VABASE + REG_TIMER_RELOAD); clk->rate = clk_get_rate(p)/CFG_TIMER_PRESCALE; break; default: ret = hisilicon_clk_default_notifier(clk, cmd, wparam, lparam); break; } return ret; }
/* * Standard clock functions defined in include/linux/clk.h */ int clk_enable(struct clk *clk) { int ret = 0; unsigned long flags; struct clk *parent; if (!clk) return 0; if (IS_ERR(clk)) return -EINVAL; spin_lock_irqsave(&clk->lock, flags); if (WARN(!clk->warned && !clk->prepare_count, "%s: Don't call enable on unprepared clocks\n", clk->dbg_name)) clk->warned = true; if (clk->count == 0) { parent = clk_get_parent(clk); ret = clk_enable(parent); if (ret) goto err_enable_parent; ret = clk_enable(clk->depends); if (ret) goto err_enable_depends; ret = vote_rate_vdd(clk, clk->rate); if (ret) goto err_vote_vdd; trace_clock_enable(clk->dbg_name, 1, smp_processor_id()); if (clk->ops->enable) ret = clk->ops->enable(clk); if (ret) goto err_enable_clock; } else if (clk->flags & CLKFLAG_HANDOFF_RATE) { /* * The clock was already enabled by handoff code so there is no * need to enable it again here. Clearing the handoff flag will * prevent the lateinit handoff code from disabling the clock if * a client driver still has it enabled. */ clk->flags &= ~CLKFLAG_HANDOFF_RATE; goto out; } clk->count++; out: spin_unlock_irqrestore(&clk->lock, flags); return 0; err_enable_clock: unvote_rate_vdd(clk, clk->rate); err_vote_vdd: clk_disable(clk->depends); err_enable_depends: clk_disable(parent); err_enable_parent: spin_unlock_irqrestore(&clk->lock, flags); return ret; }
void debug_clk_set_parent(unsigned int num, unsigned int parent_num) { const char *clk_name = NULL; const char *parent_name = NULL; struct clk *clk = NULL; struct clk *parent_clk = NULL; unsigned long ret = 0; clk_name = hi6930_clk_lookup[num].con_id; clk = clk_get(NULL, clk_name); parent_name = hi6930_clk_lookup[parent_num].con_id; parent_clk = clk_get(NULL, parent_name); if(IS_ERR(clk)){ clk_printf("clk:%s is NULL, can't find it,please check!!\n", clk_name); return; } if(IS_ERR(parent_clk)){ clk_printf("clk:%s is NULL, can't find it,please check!!\n", parent_name); return; } ret = (unsigned long)clk_set_parent(clk, parent_clk); if (ret){ clk_printf("clk:%s set parent clk :%s, failure!!\n", clk_name, parent_name); return; } parent_clk = clk_get_parent(clk); if(parent_clk == NULL) return; clk_printf("clk:%s ---parent is :%s\n\n", clk_name, parent_clk->name); return; }
__u32 OSAL_CCMU_GetMclkDiv( __hdle hMclk ) { struct clk* hModClk = (struct clk*)hMclk; struct clk* hParentClk; u32 mod_freq; u32 srcRate; if(NULL == hModClk || IS_ERR(hModClk)) { __wrn("NULL hdle\n"); return -1; } __inf("OSAL_CCMU_GetMclkDiv of clk 0x%0x\n",(unsigned int)hModClk); hParentClk = clk_get_parent(hModClk); if(NULL == hParentClk || IS_ERR(hParentClk)) { __wrn("fail to get parent of clk 0x%x \n", (unsigned int)hModClk); return -1; } srcRate = clk_get_rate(hParentClk); mod_freq = clk_get_rate(hModClk); if(mod_freq == 0) { return 0; } return srcRate/mod_freq; }
__s32 OSAL_CCMU_SetMclkDiv( __hdle hMclk, __s32 nDiv ) { struct clk* hModClk = (struct clk*)hMclk; struct clk* hParentClk; u32 srcRate; if(NULL == hModClk || IS_ERR(hModClk)) { __wrn("NULL hdle\n"); return -1; } __inf("OSAL_CCMU_SetMclkDiv<0x%0x,%d>\n",(unsigned int)hModClk, nDiv); if(nDiv == 0) { return -1; } hParentClk = clk_get_parent(hModClk); if(NULL == hParentClk || IS_ERR(hParentClk)) { __inf("fail to get parent of clk 0x%x \n", (unsigned int)hModClk); return -1; } srcRate = clk_get_rate(hParentClk); __inf("clk_set_rate<0x%0x,%d>\n",(unsigned int)hModClk, srcRate/nDiv); return clk_set_rate(hModClk, srcRate/nDiv); }
static void __init s5pv310_clockevent_init(void) { unsigned long pclk; unsigned long clock_rate; struct clk *tscaler; pclk = clk_get_rate(timerclk); /* configure clock tick */ tscaler = clk_get_parent(tdiv2); clk_set_rate(tscaler, pclk / 2); clk_set_rate(tdiv2, pclk / 2); clk_set_parent(tin2, tdiv2); clock_rate = clk_get_rate(tin2); clock_count_per_tick = clock_rate / HZ; pwm_event_device.mult = div_sc(clock_rate, NSEC_PER_SEC, pwm_event_device.shift); pwm_event_device.max_delta_ns = clockevent_delta2ns(-1, &pwm_event_device); pwm_event_device.min_delta_ns = clockevent_delta2ns(1, &pwm_event_device); pwm_event_device.cpumask = cpumask_of(0); clockevents_register_device(&pwm_event_device); setup_irq(IRQ_TIMER2, &s5pv310_clock_event_irq); }
__s32 OSAL_CCMU_SetMclkSrc(__hdle hMclk, __u32 nSclkNo) { struct clk *hSysClk = NULL; struct clk *hModClk = (struct clk *)hMclk; s32 retCode = -1; hSysClk = clk_get(NULL, _sysClkName[nSclkNo]); if (NULL == hSysClk) { __wrn("Fail to get handle for system clock [%d].\n", nSclkNo); return -1; } else __inf("OSAL_CCMU_SetMclkSrc<%s,%s>\n", clk_name(hModClk), clk_name(hSysClk)); if (clk_get_parent(hModClk) == hSysClk) { __inf("Parent is alreay %d, not need to set.\n", nSclkNo); clk_put(hSysClk); return 0; } retCode = clk_set_parent(hModClk, hSysClk); if (-1 == retCode) { __wrn("Fail to set parent for clk.\n"); clk_put(hSysClk); return -1; } clk_put(hSysClk); return retCode; }
/* * As IMX6SX_CLK_M4_PRE_SEL is NOT a glitchless MUX, so when * M4 is trying to change its clk parent, need to ask A9 to * help do it, and M4 must be hold in wfi. To avoid glitch * occur, need to gate M4 clk first before switching its parent. */ void imx6sx_set_m4_highfreq(bool high_freq) { static struct clk *m4_high_freq_sel; imx_gpc_hold_m4_in_sleep(); clk_disable_unprepare(clks[IMX6SX_CLK_M4]); imx_clk_set_parent(clks[IMX6SX_CLK_M4_SEL], clks[IMX6SX_CLK_LDB_DI0]); if (high_freq) { imx_clk_set_parent(clks[IMX6SX_CLK_M4_PRE_SEL], m4_high_freq_sel); } else { m4_high_freq_sel = clk_get_parent(clks[IMX6SX_CLK_M4_PRE_SEL]); imx_clk_set_parent(clks[IMX6SX_CLK_M4_PRE_SEL], clks[IMX6SX_CLK_OSC]); } imx_clk_set_parent(clks[IMX6SX_CLK_M4_SEL], clks[IMX6SX_CLK_M4_PRE_SEL]); clk_prepare_enable(clks[IMX6SX_CLK_M4]); imx_gpc_release_m4_in_sleep(); }
void clk_disable(struct clk *clk) { unsigned long flags; if (IS_ERR_OR_NULL(clk)) return; spin_lock_irqsave(&clk->lock, flags); if (WARN(!clk->warned && !clk->prepare_count, "%s: Never called prepare or calling disable " "after unprepare\n", clk->dbg_name)) clk->warned = true; if (WARN(clk->count == 0, "%s is unbalanced", clk->dbg_name)) goto out; if (clk->count == 1) { struct clk *parent = clk_get_parent(clk); trace_clock_disable(clk->dbg_name, 0, smp_processor_id()); if (clk->ops->disable) clk->ops->disable(clk); unvote_rate_vdd(clk, clk->rate); clk_disable(clk->depends); clk_disable(parent); } clk->count--; out: spin_unlock_irqrestore(&clk->lock, flags); }
static int utmi_phy_open(struct tegra_usb_phy *phy) { unsigned long parent_rate; int i; DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst); phy->utmi_pad_clk = clk_get_sys("utmip-pad", NULL); if (IS_ERR(phy->utmi_pad_clk)) { pr_err("%s: can't get utmip pad clock\n", __func__); return PTR_ERR(phy->utmi_pad_clk); } phy->utmi_xcvr_setup = utmi_phy_xcvr_setup_value(phy); parent_rate = clk_get_rate(clk_get_parent(phy->pllu_clk)); for (i = 0; i < ARRAY_SIZE(utmip_freq_table); i++) { if (utmip_freq_table[i].freq == parent_rate) { phy->freq = &utmip_freq_table[i]; break; } } if (!phy->freq) { pr_err("invalid pll_u parent rate %ld\n", parent_rate); return -EINVAL; } return 0; }
static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq) { struct s3c_pwm_device *s3c_pwm = pwm_get_chip_data(pwm); unsigned long tin_parent_rate; unsigned int div; tin_parent_rate = clk_get_rate(clk_get_parent(s3c_pwm->clk_div)); clk_set_rate(clk_get_parent(s3c_pwm->clk_div),tin_parent_rate); for (div = 2; div <= 16; div *= 2) { if ((tin_parent_rate / (div << 16)) < freq) return tin_parent_rate / div; } return tin_parent_rate / 16; }
/* * Standard clock functions defined in include/linux/clk.h */ int clk_enable(struct clk *clk) { int ret = 0; unsigned long flags; struct clk *parent; if (!clk) return 0; spin_lock_irqsave(&clk->lock, flags); if (clk->count == 0) { parent = clk_get_parent(clk); ret = clk_enable(parent); if (ret) goto out; if (clk->ops->enable) ret = clk->ops->enable(clk); if (ret) { clk_disable(parent); goto out; } } clk->count++; out: spin_unlock_irqrestore(&clk->lock, flags); return ret; }
__s32 OSAL_CCMU_GetMclkSrc( __hdle hMclk ) { int sysClkNo = 0; #if 0 struct clk* hModClk = (struct clk*)hMclk; struct clk* hParentClk = clk_get_parent(hModClk); const int TOTAL_SYS_CLK = sizeof(_sysClkName)/sizeof(char*); for (; sysClkNo < TOTAL_SYS_CLK; sysClkNo++) { struct clk* tmpSysClk = clk_get(NULL, _sysClkName[sysClkNo]); if(tmpSysClk == NULL) continue; if(hParentClk == tmpSysClk) { clk_put(tmpSysClk); break; } clk_put(tmpSysClk); } if(sysClkNo >= TOTAL_SYS_CLK) { __wrn("Failed to get parent clk.\n"); return -1; } #endif return sysClkNo; }
/* * Standard clock functions defined in include/linux/clk.h */ int clk_enable(struct clk *clk) { int ret = 0; unsigned long flags; struct clk *parent; if (!clk) return 0; spin_lock_irqsave(&clk->lock, flags); if (clk->count == 0) { parent = clk_get_parent(clk); if (!(clk->flags&CLKFLAG_IGNORE)) { ret = clk_enable(parent); if (ret) goto err_enable_parent; ret = clk_enable(clk->depends); if (ret) goto err_enable_depends; } ret = vote_rate_vdd(clk, clk->rate); if (ret) goto err_vote_vdd; if (clk->ops->enable) ret = clk->ops->enable(clk); if (ret) goto err_enable_clock; /*added by htc for clock debugging*/ if (!(clk->flags&CLKFLAG_IGNORE)) { spin_lock(&clk_enable_list_lock); list_add(&clk->enable_list, &clk_enable_list); spin_unlock(&clk_enable_list_lock); } } else if (clk->flags & CLKFLAG_HANDOFF_RATE) { /* * The clock was already enabled by handoff code so there is no * need to enable it again here. Clearing the handoff flag will * prevent the lateinit handoff code from disabling the clock if * a client driver still has it enabled. */ clk->flags &= ~CLKFLAG_HANDOFF_RATE; goto out; } clk->count++; out: spin_unlock_irqrestore(&clk->lock, flags); return 0; err_enable_clock: unvote_rate_vdd(clk, clk->rate); err_vote_vdd: clk_disable(clk->depends); err_enable_depends: clk_disable(parent); err_enable_parent: spin_unlock_irqrestore(&clk->lock, flags); return ret; }
static int nvhost_scale_make_freq_table(struct nvhost_device_profile *profile) { unsigned long *freqs; int num_freqs, err; unsigned long max_freq = clk_round_rate(profile->clk, UINT_MAX); unsigned long min_freq = clk_round_rate(profile->clk, 0); err = tegra_dvfs_get_freqs(clk_get_parent(profile->clk), &freqs, &num_freqs); if (err) return -ENOSYS; /* check for duplicate frequencies at higher end */ while ((num_freqs >= 2 && freqs[num_freqs - 2] == freqs[num_freqs - 1]) || (num_freqs && max_freq < freqs[num_freqs - 1])) num_freqs--; /* check low end */ while ((num_freqs >= 2 && freqs[0] == freqs[1]) || (num_freqs && freqs[0] < min_freq)) { freqs++; num_freqs--; } if (!num_freqs) dev_warn(&profile->pdev->dev, "dvfs table had no applicable frequencies!\n"); profile->devfreq_profile.freq_table = (unsigned long *)freqs; profile->devfreq_profile.max_state = num_freqs; return 0; }
void __init msm_clock_init(struct clock_init_data *data) { unsigned n; struct clk_lookup *clock_tbl; size_t num_clocks; clk_init_data = data; if (clk_init_data->init) clk_init_data->init(); clock_tbl = data->table; num_clocks = data->size; for (n = 0; n < num_clocks; n++) { struct clk *clk = clock_tbl[n].clk; struct clk *parent = clk_get_parent(clk); clk_set_parent(clk, parent); if (clk->ops->handoff && !(clk->flags & CLKFLAG_HANDOFF_RATE)) { if (clk->ops->handoff(clk)) { clk->flags |= CLKFLAG_HANDOFF_RATE; clk_enable(clk); } } } clkdev_add_table(clock_tbl, num_clocks); }
void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk) { int pclk; if (dc->out->type == TEGRA_DC_OUT_HDMI) { unsigned long rate; struct clk *pll_d_out0_clk = clk_get_sys(NULL, "pll_d_out0"); struct clk *pll_d_clk = clk_get_sys(NULL, "pll_d"); if (dc->mode.pclk > 70000000) rate = 594000000; else if (dc->mode.pclk >= 27000000) rate = 216000000; else rate = 252000000; if (rate != clk_get_rate(pll_d_clk)) clk_set_rate(pll_d_clk, rate); if (clk_get_parent(clk) != pll_d_out0_clk) clk_set_parent(clk, pll_d_out0_clk); } pclk = tegra_dc_pclk_round_rate(dc, dc->mode.pclk); tegra_dvfs_set_rate(clk, pclk); }
static void __init s5p_clockevent_init(void) { unsigned long pclk; unsigned long clock_rate; unsigned int irq_number; struct clk *tscaler; pclk = clk_get_rate(timerclk); tscaler = clk_get_parent(tdiv_event); clk_set_rate(tscaler, pclk / 2); clk_set_rate(tdiv_event, pclk / 2); clk_set_parent(tin_event, tdiv_event); clock_rate = clk_get_rate(tin_event); clock_count_per_tick = clock_rate / HZ; clockevents_calc_mult_shift(&time_event_device, clock_rate, S5PTIMER_MIN_RANGE); time_event_device.max_delta_ns = clockevent_delta2ns(-1, &time_event_device); time_event_device.min_delta_ns = clockevent_delta2ns(1, &time_event_device); time_event_device.cpumask = cpumask_of(0); clockevents_register_device(&time_event_device); irq_number = timer_source.event_id + IRQ_TIMER0; setup_irq(irq_number, &s5p_clock_event_irq); }
static int clk_lcdif_set_rate(struct clk *clk, unsigned long rate, unsigned long unused) { struct clk_lcdif *lcdif = to_clk_lcdif(clk); unsigned long frac, div, best_div = 1; int delta, best_delta = 0x7fffffff; unsigned long frate, rrate, best_frate; unsigned long parent_rate = clk_get_rate(clk_get_parent(lcdif->frac)); best_frate = parent_rate; for (frac = 18; frac < 35; frac++) { frate = (parent_rate / frac) * 18; div = frate / rate; if (!div) div = 1; rrate = frate / div; delta = rate - rrate; if (abs(delta) < abs(best_delta)) { best_frate = frate; best_div = div; best_delta = delta; } } clk_set_rate(lcdif->frac, best_frate); best_frate = clk_get_rate(lcdif->frac); clk_set_rate(lcdif->div, (best_frate + best_div) / best_div); return 0; }
static int tegra124_cpu_switch_to_dfll(struct tegra124_cpufreq_priv *priv) { struct clk *orig_parent; int ret; ret = clk_set_rate(priv->dfll_clk, clk_get_rate(priv->cpu_clk)); if (ret) return ret; orig_parent = clk_get_parent(priv->cpu_clk); clk_set_parent(priv->cpu_clk, priv->pllp_clk); ret = clk_prepare_enable(priv->dfll_clk); if (ret) goto out; clk_set_parent(priv->cpu_clk, priv->dfll_clk); return 0; out: clk_set_parent(priv->cpu_clk, orig_parent); return ret; }
void clk_disable(struct clk *clk) { unsigned long flags; if (!clk) return; spin_lock_irqsave(&clk->lock, flags); if (WARN(clk->count == 0, "%s is unbalanced", clk->dbg_name)) goto out; if (clk->count == 1) { struct clk *parent = clk_get_parent(clk); if (clk->ops->disable) { clk->ops->disable(clk); clk_log_map_disable(clk); } unvote_rate_vdd(clk, clk->rate); clk_disable(clk->depends); clk_disable(parent); } clk->count--; out: spin_unlock_irqrestore(&clk->lock, flags); }
unsigned long dss_get_dpll4_rate(void) { if (cpu_is_omap34xx()) return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); else return 0; }
/* * In SPEAr1340, we cannot use newfreq directly because we need to actually * access a source clock (clk) which might not be ancestor of cpu at present. * Hence in SPEAr1340 we would operate on source clock directly before switching * cpu clock to it. */ static int spear1340_set_cpu_rate(struct clk *sys_pclk, unsigned long newfreq) { struct clk *sys_clk; int ret = 0; sys_clk = clk_get_parent(spear_cpufreq.clk); if (IS_ERR(sys_clk)) { pr_err("failed to get cpu's parent (sys) clock\n"); return PTR_ERR(sys_clk); } /* Set the rate of the source clock before changing the parent */ ret = clk_set_rate(sys_pclk, newfreq); if (ret) { pr_err("Failed to set sys clk rate to %lu\n", newfreq); return ret; } ret = clk_set_parent(sys_clk, sys_pclk); if (ret) { pr_err("Failed to set sys clk parent\n"); return ret; } return 0; }