@@ -81,7 +81,7 @@
/* CM_CLKSEL1_PLL_IVA2 */
#define OMAP3430_IVA2_CLK_SRC_SHIFT 19
-#define OMAP3430_IVA2_CLK_SRC_MASK (0x3 << 19)
+#define OMAP3430_IVA2_CLK_SRC_MASK (0x7 << 19)
#define OMAP3430_IVA2_DPLL_MULT_SHIFT 8
#define OMAP3430_IVA2_DPLL_MULT_MASK (0x7ff << 8)
#define OMAP3430_IVA2_DPLL_DIV_SHIFT 0
@@ -126,7 +126,7 @@
/* CM_CLKSEL1_PLL_MPU */
#define OMAP3430_MPU_CLK_SRC_SHIFT 19
-#define OMAP3430_MPU_CLK_SRC_MASK (0x3 << 19)
+#define OMAP3430_MPU_CLK_SRC_MASK (0x7 << 19)
#define OMAP3430_MPU_DPLL_MULT_SHIFT 8
#define OMAP3430_MPU_DPLL_MULT_MASK (0x7ff << 8)
#define OMAP3430_MPU_DPLL_DIV_SHIFT 0
@@ -828,6 +828,29 @@ static void __init omap3_d2d_idle(void)
static void __init prcm_setup_regs(void)
{
+ u32 cm_clksel1_mpu, cm_clksel1_iva2;
+
+ /*set Bypass clock dividers for MPU and IVA */
+ cm_clksel1_mpu = cm_read_mod_reg(MPU_MOD, CM_CLKSEL1);
+ cm_clksel1_iva2 = cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+ if (cpu_is_omap3630()) {
+ cm_clksel1_iva2 = (cm_clksel1_iva2 &
+ ~(OMAP3430_IVA2_CLK_SRC_MASK)) |
+ (0x2 << OMAP3430_IVA2_CLK_SRC_SHIFT);
+ cm_clksel1_mpu = (cm_clksel1_mpu &
+ ~(OMAP3430_MPU_CLK_SRC_MASK)) |
+ (0x1 << OMAP3430_MPU_CLK_SRC_SHIFT);
+ } else if (cpu_is_omap34xx()) {
+ cm_clksel1_iva2 = (cm_clksel1_iva2 &
+ ~(OMAP3430_IVA2_CLK_SRC_MASK)) |
+ (0x4 << OMAP3430_IVA2_CLK_SRC_SHIFT);
+ cm_clksel1_mpu = (cm_clksel1_mpu &
+ ~(OMAP3430_MPU_CLK_SRC_MASK)) |
+ (0x2 << OMAP3430_MPU_CLK_SRC_SHIFT);
+ }
+ cm_write_mod_reg(cm_clksel1_iva2, OMAP3430_IVA2_MOD, CM_CLKSEL1);
+ cm_write_mod_reg(cm_clksel1_mpu, MPU_MOD, CM_CLKSEL1);
+
/* XXX Reset all wkdeps. This should be done when initializing
* powerdomains */
prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
@@ -276,12 +276,13 @@ static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
static int program_opp_freq(int res, int target_level, int current_level)
{
- int ret = 0, l3_div;
+ int ret = 0, l3_div, mpu_div, iva2_div;
int *curr_opp;
unsigned long mpu_freq, dsp_freq, l3_freq;
#ifndef CONFIG_CPU_FREQ
unsigned long mpu_cur_freq;
#endif
+ u32 cm_clksel1_mpu, cm_clksel1_iva2, max_core_clk;
/* Check if I can actually switch or not */
if (res == VDD1_OPP) {
@@ -299,6 +300,31 @@ static int program_opp_freq(int res, int target_level, int current_level)
lock_scratchpad_sem();
if (res == VDD1_OPP) {
+ /* adjust bypass clock diviers */
+ max_core_clk = ULONG_MAX;
+ opp_find_freq_floor(OPP_L3, &max_core_clk);
+ l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+ OMAP3430_CLKSEL_L3_MASK;
+
+ max_core_clk *= l3_div;
+ mpu_div = 1 << (max_core_clk / mpu_freq);
+ iva2_div = 1 << (max_core_clk / dsp_freq);
+
+ cm_clksel1_mpu = cm_read_mod_reg(MPU_MOD, CM_CLKSEL1);
+ cm_clksel1_iva2 =
+ cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+
+ cm_clksel1_iva2 = (cm_clksel1_iva2 &
+ ~(OMAP3430_IVA2_CLK_SRC_MASK)) |
+ (iva2_div << OMAP3430_IVA2_CLK_SRC_SHIFT);
+ cm_clksel1_mpu = (cm_clksel1_mpu &
+ ~(OMAP3430_MPU_CLK_SRC_MASK)) |
+ (mpu_div << OMAP3430_MPU_CLK_SRC_SHIFT);
+
+ cm_write_mod_reg(cm_clksel1_iva2,
+ OMAP3430_IVA2_MOD, CM_CLKSEL1);
+ cm_write_mod_reg(cm_clksel1_mpu, MPU_MOD, CM_CLKSEL1);
+
curr_opp = &curr_vdd1_opp;
clk_set_rate(dpll1_clk, mpu_freq);
clk_set_rate(dpll2_clk, dsp_freq);