int __init omap2_clk_init(void) { struct prcm_config *prcm; struct omap_clk *c; u32 clkrate; if (cpu_is_omap242x()) cpu_mask = RATE_IN_242X; else if (cpu_is_omap2430()) cpu_mask = RATE_IN_243X; clk_init(&omap2_clk_functions); for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++) clk_init_one(c->lk.clk); osc_ck.rate = omap2_osc_clk_recalc(&osc_ck); propagate_rate(&osc_ck); sys_ck.rate = omap2_sys_clk_recalc(&sys_ck); propagate_rate(&sys_ck); for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++) if (c->cpu & cpu_mask) { clkdev_add(&c->lk); clk_register(c->lk.clk); } /* Check the MPU rate set by bootloader */ clkrate = omap2xxx_clk_get_core_rate(&dpll_ck); for (prcm = rate_table; prcm->mpu_speed; prcm++) { if (!(prcm->flags & cpu_mask)) continue; if (prcm->xtal_speed != sys_ck.rate) continue; if (prcm->dpll_speed <= clkrate) break; } curr_prcm_set = prcm; recalculate_root_clocks(); printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): " "%ld.%01ld/%ld/%ld MHz\n", (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; /* * Only enable those clocks we will need, let the drivers * enable other clocks as necessary */ clk_enable_init_clocks(); /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */ vclk = clk_get(NULL, "virt_prcm_set"); sclk = clk_get(NULL, "sys_ck"); return 0; }
/* Arch specific init */ static int __init omap3_clk_arch_init(void) { struct vdd_prcm_config *vdd1_prcm; struct vdd_prcm_config *vdd2_prcm; u32 sys_clk_speed, mpu_speed, core_speed, l3_speed = 0; int div; printk("OMAP Clock subsystem initializing.\n"); /* Lock DPLL5 */ if (prcm_configure_dpll(DPLL5_PER2, -1, -1, -1)) panic("FATAL ERROR: Unable to Configure DPLL5\n"); if (prcm_enable_dpll(DPLL5_PER2)) panic("FATAL ERROR: Unable to Lock DPLL5\n"); omap3_get_crystal_rate(&osc_sys_ck); omap3_update_sources(); sys_clk_speed = prcm_get_system_clock_speed() * 1000; prcm_get_processor_speed(DOM_MPU, &mpu_speed); mpu_speed = mpu_speed * 1000; prcm_get_dpll_rate((&core_ck)->prcmid, &core_speed); core_speed = core_speed * 1000; prcm_clksel_get_divider((&l3_ck)->prcmid, &div); if (div != 0) l3_speed = core_speed / div; else printk(KERN_ERR"Error: Divider for L3 returned 0 in omap3_clk" "_arch_init\n"); pr_debug("System clock speed: %u, mpu speed : %u, l3_speed : %u" "\n", sys_clk_speed, mpu_speed, l3_speed); for (vdd1_prcm = vdd1_rate_table+MAX_VDD1_OPP; vdd1_prcm->speed; vdd1_prcm--) { pr_debug("%lu\n", vdd1_prcm->speed); if (vdd1_prcm->speed <= mpu_speed) break; } curr_vdd1_prcm_set = vdd1_prcm; for (vdd2_prcm = vdd2_rate_table+MAX_VDD2_OPP; vdd2_prcm->speed; vdd2_prcm++) { pr_debug("%lu\n", vdd2_prcm->speed); if (vdd2_prcm->speed <= l3_speed) break; } curr_vdd2_prcm_set = vdd2_prcm; propagate_rate(&osc_sys_ck); /* update main root fast */ propagate_rate(&omap_32k_fck); /* update main root slow */ propagate_rate(&sysaltck); /* update alt ck tree */ pr_debug("Rate propagation done for all clocks\n"); return 0; }
/** * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate * @clk: DPLL output struct clk * * Using parent clock DPLL data, look up DPLL state. If locked, set our * rate to the dpll_clk * 2; otherwise, just use dpll_clk. */ static void omap3_clkoutx2_recalc(struct clk *clk) { const struct dpll_data *dd; u32 v; struct clk *pclk; /* Walk up the parents of clk, looking for a DPLL */ pclk = clk->parent; while (pclk && !pclk->dpll_data) pclk = pclk->parent; /* clk does not have a DPLL as a parent? */ WARN_ON(!pclk); dd = pclk->dpll_data; WARN_ON(!dd->control_reg || !dd->enable_mask); v = __raw_readl(dd->control_reg) & dd->enable_mask; v >>= __ffs(dd->enable_mask); if (v != DPLL_LOCKED) clk->rate = clk->parent->rate; else clk->rate = clk->parent->rate * 2; if (clk->flags & RATE_PROPAGATES) propagate_rate(clk); }
/* * _ti814x_adpll_check_and_set_rate - check if given clock's parent is an ADPLL * and check if it is allowed to change the rate of the ADPLL based on id, * Set rate if it is a clock not an ADPLL and propagate rate down tree * @clk - pointer to struct clk * @dpll_setrate - output variable indicating whether rate can be set * @rate - rate to be set */ static int _ti814x_adpll_check_and_set_rate(struct clk *clk, int *dpll_setrate, unsigned long rate) { struct dpll_data *dd; struct clk *dclk = clk->parent; int ret = 0; *dpll_setrate = 0; if (dclk->dpll_data) { dd = dclk->dpll_data; if (((dd->dpll_id == TI814X_ARM_DPLL_ID) || (dd->dpll_id == TI814X_DDR_DPLL_ID))) return -EINVAL; *dpll_setrate = 1; } else if (dclk->set_rate) { if (dclk->usecount > 1) { pr_warn("clock: %s,\'s parent %s is already in use, can't" " change rate\n", clk->name, dclk->name); return -EBUSY; //?EWB } ret = dclk->set_rate(dclk, rate); if (!ret) { /* re-set divider based on parent rate */ ret = omap2_clksel_set_rate(clk, dclk->rate); if (ret) { pr_err("clock: failed to reset the divider\n"); return ret; } propagate_rate(dclk); } } return ret; }
/* Recalculate SYST_CLK */ static void omap2_sys_clk_recalc(struct clk * clk) { u32 div = PRCM_CLKSRC_CTRL; div &= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */ div >>= clk->rate_offset; clk->rate = (clk->parent->rate / div); propagate_rate(clk); }
/* * Used for clocks that have the same value as the parent clock, * divided by some factor */ void omap2_fixed_divisor_recalc(struct clk *clk) { WARN_ON(!clk->fixed_div); clk->rate = clk->parent->rate / clk->fixed_div; if (clk->flags & RATE_PROPAGATES) propagate_rate(clk); }
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) { void __iomem *src_addr; u32 field_val, field_mask, reg_val, parent_div; if (unlikely(clk->flags & CONFIG_PARTICIPANT)) return -EINVAL; if (!clk->clksel) return -EINVAL; field_val = omap2_clksel_get_src_field(&src_addr, new_parent, &field_mask, clk, &parent_div); if (src_addr == 0) return -EINVAL; if (clk->usecount > 0) _omap2_clk_disable(clk); /* Set new source value (previous dividers if any in effect) */ reg_val = __raw_readl(src_addr) & ~field_mask; reg_val |= (field_val << __ffs(field_mask)); __raw_writel(reg_val, src_addr); wmb(); if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL); wmb(); } if (clk->usecount > 0) _omap2_clk_enable(clk); clk->parent = new_parent; /* CLKSEL clocks follow their parents' rates, divided by a divisor */ clk->rate = new_parent->rate; if (parent_div > 0) clk->rate /= parent_div; pr_debug("clock: set parent of %s to %s (new rate %ld)\n", clk->name, clk->parent->name, clk->rate); if (unlikely(clk->flags & RATE_PROPAGATES)) propagate_rate(clk); return 0; }
/* Calls appropriate PRCM API to calculate rate of clock */ static void omap3_clk_recalc(struct clk *clk) { u32 parent_rate, divider, ret, rate; parent_rate = clk->parent->rate; ret = PRCM_PASS; pr_debug("Clock name: %s\n", clk->name); if (clk == &sys_ck) { clk->rate = prcm_get_system_clock_speed() * 1000; ret = PRCM_PASS; } if (clk == &mpu_ck) { ret = prcm_get_processor_speed(clk->prcmid, &rate); clk->rate = rate * 1000; } if (clk == &iva2_ck) { ret = prcm_get_processor_speed(clk->prcmid, &rate); clk->rate = rate * 1000; } if (clk->flags & DPLL_OUTPUT) { ret = prcm_get_dpll_rate(clk->prcmid, &rate); if (ret == PRCM_PASS) clk->rate = rate * 1000; } if (clk->flags & RATE_CKCTL) { ret = prcm_clksel_get_divider(clk->prcmid, ÷r); pr_debug("Divider: %d\n", divider); if (ret == PRCM_PASS) clk->rate = clk->parent->rate / divider; } if (ret != PRCM_PASS) printk(KERN_ERR "Error in clk_recalc: %d,%s\n", ret, clk->name); pr_debug("Rate: %lu\n", clk->rate); if (clk->flags & RATE_PROPAGATES) propagate_rate(clk); }
/* * Used for clocks that are part of CLKSEL_xyz governed clocks. * REVISIT: Maybe change to use clk->enable() functions like on omap1? */ void omap2_clksel_recalc(struct clk *clk) { u32 div = 0; pr_debug("clock: recalc'ing clksel clk %s\n", clk->name); div = omap2_clksel_get_divisor(clk); if (div == 0) return; if (unlikely(clk->rate == clk->parent->rate / div)) return; clk->rate = clk->parent->rate / div; pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div); if (unlikely(clk->flags & RATE_PROPAGATES)) propagate_rate(clk); }
/* Set the clock rate for a clock source */ int omap2_clk_set_rate(struct clk *clk, unsigned long rate) { int ret = -EINVAL; pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate); /* CONFIG_PARTICIPANT clocks are changed only in sets via the rate table mechanism, driven by mpu_speed */ if (clk->flags & CONFIG_PARTICIPANT) return -EINVAL; /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ if (clk->set_rate != 0) ret = clk->set_rate(clk, rate); if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) propagate_rate(clk); return ret; }
static int pll160_set_rate(struct clk *clk, u32 rate) { u32 tmp_reg, tmp_m, tmp_2p, i; u32 parent_rate; int ret = -EINVAL; parent_rate = clk->parent->rate; if (!parent_rate) goto out; /* set direct run for ARM or disable output for others */ clk_reg_disable(clk); /* disable source input as well (ignored for ARM) */ clk_reg_disable1(clk); tmp_reg = __raw_readl(clk->scale_reg); tmp_reg &= ~0x1ffff; /*clear all settings, power down */ __raw_writel(tmp_reg, clk->scale_reg); rate -= rate % parent_rate; /*round down the input */ if (rate > PLL160_MAX_FCCO) rate = PLL160_MAX_FCCO; if (!rate) { clk->rate = 0; ret = 0; goto out; } clk_reg_enable1(clk); tmp_reg = __raw_readl(clk->scale_reg); if (rate == parent_rate) { /*enter direct bypass mode */ tmp_reg |= ((1 << 14) | (1 << 15)); __raw_writel(tmp_reg, clk->scale_reg); clk->rate = parent_rate; clk_reg_enable(clk); ret = 0; goto out; } i = 0; for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) { if (rate * tmp_2p >= PLL160_MIN_FCCO) break; i++; } if (tmp_2p > 1) tmp_reg |= ((i - 1) << 11); else tmp_reg |= (1 << 14); /*direct mode, no divide */ tmp_m = rate * tmp_2p; tmp_m /= parent_rate; tmp_reg |= (tmp_m - 1) << 1; /*calculate M */ tmp_reg |= (1 << 16); /*power up PLL */ __raw_writel(tmp_reg, clk->scale_reg); if (clk_wait_for_pll_lock(clk) < 0) { clk_reg_disable(clk); clk_reg_disable1(clk); tmp_reg = __raw_readl(clk->scale_reg); tmp_reg &= ~0x1ffff; /*clear all settings, power down */ __raw_writel(tmp_reg, clk->scale_reg); clk->rate = 0; ret = -EFAULT; goto out; } clk->rate = (tmp_m * parent_rate) / tmp_2p; if (clk->flags & RATE_PROPAGATES) propagate_rate(clk); clk_reg_enable(clk); ret = 0; out: return ret; }
/** * ti814x_clksel_set_rate() - program clock rate in hardware * @clk: struct clk * to program rate * @rate: target rate to program * * This function is intended to be called by the audio and some * of the coprocessors. Program @clk's rate to @rate in the hardware. * The clock must be enabled, or -EPERM is returned * If multiple drivers are using the clock, returns -EBUSY with error message. * Returns -EINVAL upon error, or 0 upon success. */ int ti814x_clksel_set_rate(struct clk *clk, unsigned long rate) { struct clk *pclk; struct clk *dclk; int ret, dpll_setrate = 0; if (clk->usecount == 0) { pr_err("clock: Enable %s before setting rate\n", clk->name); return -EPERM; } if (clk->usecount > 1) { pr_warn("clock: %s usecount(%d) > 1 - can't change the rate\n", clk->name, clk->usecount); return -EBUSY; //?EWB } pclk = clk->parent; if (pclk->usecount > 1) { pr_warn("clock: %s's parent %s usecount(%d) > 1 -" "can't change the rate\n", clk->name, pclk->name, pclk->usecount); return -EBUSY; //?EWB } dclk = pclk->parent; /* check the dividers in parent clock */ ret = pclk->set_rate(pclk, rate); if (!ret) { propagate_rate(pclk); } else { ret = _ti814x_adpll_check_and_set_rate(pclk, &dpll_setrate, rate); if (ret && dpll_setrate) goto failed_set_divider; else if (ret) { pclk = dclk; dclk = dclk->parent; ret = _ti814x_adpll_check_and_set_rate(pclk, &dpll_setrate, rate); if (ret && dpll_setrate) goto failed_set_divider; } } if (dpll_setrate) { if (dclk->usecount > 1) { pr_warn("clock: %s's parent %s usecount(%d) > 1" " - can't change the rate\n", pclk->name, dclk->name, dclk->usecount); return -EBUSY; //?EWB } /* Changing the DPLL rate */ ret = dclk->set_rate(dclk, rate); if (ret) { pr_err("clock: failed to set dpll rate\n"); return -EINVAL; } /* reset divider */ ret = omap2_clksel_set_rate(pclk, dclk->rate); if (ret) { pr_err("clock: failed to reset the divider\n"); return -EINVAL; } propagate_rate(dclk); } return 0; failed_set_divider: pr_err("clock: failed to set divider\n"); return ret; }
static void omap2_sys_clk_recalc(struct clk *clk) { clk->rate = clk->parent->rate / omap2_get_sysclkdiv(); propagate_rate(clk); }
static void omap2_osc_clk_recalc(struct clk *clk) { clk->rate = omap2_get_apll_clkin() * omap2_get_sysclkdiv(); propagate_rate(clk); }
static void omap2_dpll_recalc(struct clk *clk) { clk->rate = omap2_get_dpll_rate_24xx(clk); propagate_rate(clk); }
/* Make the rate same as that of the parent. If the rate propagates, call propagate_rate*/ static void omap3_followparent_recalc(struct clk *clk) { followparent_recalc(clk); if (clk->flags & RATE_PROPAGATES) propagate_rate(clk); }
static void omap3_propagate_rate(struct clk *clk) { propagate_rate(clk); }
/** * ti816x_clksel_set_rate() - program clock rate in hardware * @clk: struct clk * to program rate * @rate: target rate to program * * This function is intended to be called by the audio and some * of the coprocessors. Program @clk's rate to @rate in the hardware. * The clock should be disabled when this happens, otherwise setrate * will fail, because this is treated as clock being used. If multiple * drivers are using the clock, even though it is trying to change * then this return -EINVAL with error message. Returns -EINVAL upon * error, or 0 upon success. */ int ti816x_clksel_set_rate(struct clk *clk, unsigned long rate) { struct clk *pclk; struct clk *fclk; struct fapll_data *fd; int ret, fapll_sr = 0; if (clk->usecount == 0) { pr_err("clock: Enable the clock '%s' before setting rate\n", clk->name); return -EINVAL; } if (clk->usecount > 1) { pr_err("clock: '%s' clock is in use can't change the rate " "usecount = '%d'", clk->name, clk->usecount); return -EBUSY; } pclk = clk->parent; if (pclk->usecount > 1) { pr_err("clock: '%s' clock's parent '%s' is in use can't" " change the rate usecount = %d", clk->name, pclk->name, pclk->usecount); return -EBUSY; } fclk = pclk->parent; /* check the dividers in parent clock */ ret = pclk->set_rate(pclk, rate); if (!ret) propagate_rate(pclk); else { if (!fclk->fapll_data) goto failed_set_divider; fd = fclk->fapll_data; if (!((fd->fapll_id == 1) || (fd->fapll_id == 4))) goto failed_set_divider; if ((fd->fapll_id == 1) && (fclk->synthesizer_id == 2)) goto failed_set_divider; fapll_sr = 1; } if (fapll_sr) { if (fclk->usecount > 1) { pr_err("clock: %s, parent %s is already in use, change" " parent\n", pclk->name, pclk->parent->name); return -EINVAL; } /* Changing the FAPLL synthesizer rate */ ret = fclk->set_rate(fclk, rate); if (ret) { pr_err("clock: failed to set fapll rate\n"); return -EINVAL; } /* reset divider */ ret = omap2_clksel_set_rate(pclk, fclk->rate); if (ret) { pr_err("clock: failed to reset the divider\n"); return -EINVAL; } propagate_rate(fclk); } return 0; failed_set_divider: pr_err("clock: failed to set divider\n"); return -EINVAL; }
static int set_cpu_freq(int wp) { int arm_podf; int podf; int vinc = 0; int ret = 0; int org_cpu_rate; unsigned long rate = 0; int gp_volt = 0; u32 reg; u32 reg1; unsigned long flags; if (cpu_wp_tbl[wp].pll_rate != cpu_wp_tbl[old_wp].pll_rate) { org_cpu_rate = clk_get_rate(cpu_clk); rate = cpu_wp_tbl[wp].cpu_rate; if (org_cpu_rate == rate) return ret; gp_volt = cpu_wp_tbl[wp].cpu_voltage; if (gp_volt == 0) return ret; /*Set the voltage for the GP domain. */ if (rate > org_cpu_rate) { ret = regulator_set_voltage(core_regulator, gp_volt, gp_volt); if (ret < 0) { printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE\n"); return ret; } udelay(dvfs_data->delay_time); } atomic_spin_lock_irqsave(&mxc_dvfs_core_lock, flags); /* PLL_RELOCK, set ARM_FREQ_SHIFT_DIVIDER */ reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset); reg &= 0xFFFFFFFB; __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset); setup_pll(); /* START the GPC main control FSM */ /* set VINC */ reg = __raw_readl(gpc_base + dvfs_data->gpc_vcr_offset); reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK | MXC_GPCVCR_VCNT_MASK); if (rate > org_cpu_rate) reg |= 1 << MXC_GPCVCR_VINC_OFFSET; reg |= (1 << MXC_GPCVCR_VCNTU_OFFSET) | (1 << MXC_GPCVCR_VCNT_OFFSET); __raw_writel(reg, gpc_base + dvfs_data->gpc_vcr_offset); reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg &= ~(MXC_GPCCNTR_ADU_MASK | MXC_GPCCNTR_FUPD_MASK); reg |= MXC_GPCCNTR_FUPD; reg |= MXC_GPCCNTR_ADU; __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); reg |= MXC_GPCCNTR_STRT; __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); while (__raw_readl(gpc_base + dvfs_data->gpc_cntr_offset) & 0x4000) udelay(10); atomic_spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags); if (rate < org_cpu_rate) { ret = regulator_set_voltage(core_regulator, gp_volt, gp_volt); if (ret < 0) { printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n"); return ret; } udelay(dvfs_data->delay_time); } clk_set_rate(cpu_clk, rate); } else { podf = cpu_wp_tbl[wp].cpu_podf; gp_volt = cpu_wp_tbl[wp].cpu_voltage; /* Change arm_podf only */ /* set ARM_FREQ_SHIFT_DIVIDER */ reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset); reg &= 0xFFFFFFFB; reg |= 1 << 2; __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset); /* Get ARM_PODF */ reg = __raw_readl(ccm_base + dvfs_data->ccm_cacrr_offset); arm_podf = reg & 0x07; if (podf == arm_podf) { printk(KERN_DEBUG "No need to change freq and voltage!!!!\n"); return 0; } /* Check if FSVAI indicate freq up */ if (podf < arm_podf) { ret = regulator_set_voltage(core_regulator, gp_volt, gp_volt); if (ret < 0) { printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n"); return 0; } udelay(dvfs_data->delay_time); vinc = 1; } else { vinc = 0; } arm_podf = podf; /* Set ARM_PODF */ reg &= 0xFFFFFFF8; reg |= arm_podf; reg1 = __raw_readl(ccm_base + dvfs_data->ccm_cdhipr_offset); if ((reg1 & 0x00010000) == 0) __raw_writel(reg, ccm_base + dvfs_data->ccm_cacrr_offset); else { printk(KERN_DEBUG "ARM_PODF still in busy!!!!\n"); return 0; } /* START the GPC main control FSM */ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg |= MXC_GPCCNTR_FUPD; /* ADU=1, select ARM domain */ reg |= MXC_GPCCNTR_ADU; __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); /* set VINC */ reg = __raw_readl(gpc_base + dvfs_data->gpc_vcr_offset); reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK | MXC_GPCVCR_VCNT_MASK); reg |= (1 << MXC_GPCVCR_VCNTU_OFFSET) | (100 << MXC_GPCVCR_VCNT_OFFSET) | (vinc << MXC_GPCVCR_VINC_OFFSET); __raw_writel(reg, gpc_base + dvfs_data->gpc_vcr_offset); reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg &= (~(MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD)); reg |= MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD | MXC_GPCCNTR_STRT; __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); /* Wait for arm podf Enable */ while ((__raw_readl(gpc_base + dvfs_data->gpc_cntr_offset) & MXC_GPCCNTR_STRT) == MXC_GPCCNTR_STRT) { printk(KERN_DEBUG "Waiting arm_podf enabled!\n"); udelay(10); } if (vinc == 0) { ret = regulator_set_voltage(core_regulator, gp_volt, gp_volt); if (ret < 0) { printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n"); return ret; } udelay(dvfs_data->delay_time); } propagate_rate(pll1_sw_clk); /* Clear the ARM_FREQ_SHIFT_DIVIDER */ reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset); reg &= 0xFFFFFFFB; __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset); } #if defined(CONFIG_CPU_FREQ) cpufreq_trig_needed = 1; #endif old_wp = wp; return ret; }