int set_high_bus_freq(int high_bus_freq) { int ret = 0; unsigned long flags; unsigned long lp_lpm_clk; if (!low_bus_freq_mode) return ret; if (dvfs_per_active()) return ret; /* Set the voltage to 1.25V for the LP domain. */ ret = regulator_set_voltage(lp_regulator, 1250000, 1250000); udelay(100); if (ret < 0) { printk(KERN_ERR "COULD NOT SET LP VOLTAGE!!!!!!\n"); return ret; } spin_lock_irqsave(&bus_freq_lock, flags); low_bus_freq_mode = 0; /* Set the LP clocks. */ lp_lpm_clk = clk_get_rate(periph_apm_clk); clk_set_rate(axi_a_clk, clk_round_rate(axi_a_clk, lp_lpm_clk/5)); clk_set_rate(axi_b_clk, clk_round_rate(axi_b_clk, lp_lpm_clk/5)); clk_set_rate(axi_c_clk, clk_round_rate(axi_c_clk, lp_lpm_clk/5)); clk_set_rate(emi_core_clk, clk_round_rate(emi_core_clk, lp_lpm_clk/5)); clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, lp_lpm_clk/5)); /* Set emi_intr clock back to divide by 2. */ clk_set_rate(emi_intr_clk, clk_round_rate(emi_intr_clk, lp_lpm_clk/10)); /* Set the parent of main_bus_clk to be pll2 */ clk_set_parent(main_bus_clk, pll2); high_bus_freq_mode = 1; spin_unlock_irqrestore(&bus_freq_lock, flags); start_dvfs_per(); return ret; }
int set_high_bus_freq(int high_bus_freq) { u32 reg; if (bus_freq_scaling_initialized) { mutex_lock(&bus_freq_mutex); /* * If the CPU freq is 800MHz, set the bus to the high * setpoint (133MHz) and DDR to 200MHz. */ if ((clk_get_rate(cpu_clk) > cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) || lp_high_freq) high_bus_freq = 1; stop_sdram_autogating(); if (low_bus_freq_mode) { /* Relock PLL3 to 133MHz */ if (cpu_is_mx50()) exit_lpapm_mode_mx50(high_bus_freq); else if (cpu_is_mx51()) exit_lpapm_mode_mx51(); else exit_lpapm_mode_mx53(); start_dvfs_per(); } if (bus_freq_scaling_is_active) { if (!high_bus_freq_mode && high_bus_freq) { if (cpu_is_mx50()) { if (med_bus_freq_mode) { /* Increase SYS_CLK */ reg = __raw_readl(MXC_CCM_CLK_SYS); reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK; reg |= 4 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET; __raw_writel(reg, MXC_CCM_CLK_SYS); /* Set the dividers to the default dividers */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET |1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET |2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0xF) udelay(10); } } else { clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, lp_normal_rate)); clk_set_rate(ddr_hf_clk, clk_round_rate(ddr_hf_clk, ddr_normal_rate)); } /* Set to the high setpoint. */ high_bus_freq_mode = 1; low_bus_freq_mode = 0; med_bus_freq_mode = 0; } else if (!med_bus_freq_mode && !high_bus_freq) { if (cpu_is_mx50()) { /* Set the dividers to the medium setpoint dividers */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET |3 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET |5 << MXC_CCM_CBCDR_AHB_PODF_OFFSET |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0xF) udelay(10); /* Reduce SYS_CLK */ reg = __raw_readl(MXC_CCM_CLK_SYS); reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK; reg |= 8 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET; __raw_writel(reg, MXC_CCM_CLK_SYS); } else { if (cpu_is_mx51()) clk_set_rate(ddr_hf_clk, clk_round_rate( ddr_hf_clk, ddr_low_rate)); clk_set_rate(ahb_clk, clk_round_rate( ahb_clk, lp_med_rate)); } /* Set to the medium setpoint. */ high_bus_freq_mode = 0; low_bus_freq_mode = 0; med_bus_freq_mode = 1; } if (cpu_is_mx50()) { if (med_bus_freq_mode && (cur_ddr_rate != ddr_med_rate)) set_ddr_freq(ddr_med_rate); if (high_bus_freq_mode && (cur_ddr_rate != ddr_normal_rate)) set_ddr_freq(ddr_normal_rate); } } start_sdram_autogating(); mutex_unlock(&bus_freq_mutex); } return 0; }
/*! * Enable DVFS Peripheral * */ int dvfs_enable(struct device *dev) { if (dvfs_per_is_active) return 0; return (start_dvfs_per()); }