OMAP4: clock-common: Move the usb dppl configuration to new func
[oweals/u-boot.git] / arch / arm / cpu / armv7 / omap-common / clocks-common.c
index c726093fd27de7e164a30c8029efe17a0e27958a..4cfe11991ab84afdcc48125c2c19d8cdc28ff09f 100644 (file)
@@ -115,17 +115,46 @@ static inline void wait_for_lock(u32 *const base)
        }
 }
 
+inline u32 check_for_lock(u32 *const base)
+{
+       struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+       u32 lock = readl(&dpll_regs->cm_idlest_dpll) & ST_DPLL_CLK_MASK;
+
+       return lock;
+}
+
 static void do_setup_dpll(u32 *const base, const struct dpll_params *params,
-                               u8 lock)
+                               u8 lock, char *dpll)
 {
-       u32 temp;
+       u32 temp, M, N;
        struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
 
+       temp = readl(&dpll_regs->cm_clksel_dpll);
+
+       if (check_for_lock(base)) {
+               /*
+                * The Dpll has already been locked by rom code using CH.
+                * Check if M,N are matching with Ideal nominal opp values.
+                * If matches, skip the rest otherwise relock.
+                */
+               M = (temp & CM_CLKSEL_DPLL_M_MASK) >> CM_CLKSEL_DPLL_M_SHIFT;
+               N = (temp & CM_CLKSEL_DPLL_N_MASK) >> CM_CLKSEL_DPLL_N_SHIFT;
+               if ((M != (params->m)) || (N != (params->n))) {
+                       debug("\n %s Dpll locked, but not for ideal M = %d,"
+                               "N = %d values, current values are M = %d,"
+                               "N= %d" , dpll, params->m, params->n,
+                               M, N);
+               } else {
+                       /* Dpll locked with ideal values for nominal opps. */
+                       debug("\n %s Dpll already locked with ideal"
+                                               "nominal opp values", dpll);
+                       goto setup_post_dividers;
+               }
+       }
+
        bypass_dpll(base);
 
        /* Set M & N */
-       temp = readl(&dpll_regs->cm_clksel_dpll);
-
        temp &= ~CM_CLKSEL_DPLL_M_MASK;
        temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK;
 
@@ -138,6 +167,7 @@ static void do_setup_dpll(u32 *const base, const struct dpll_params *params,
        if (lock)
                do_lock_dpll(base);
 
+setup_post_dividers:
        setup_post_dividers(base, params);
 
        /* Wait till the DPLL locks */
@@ -216,17 +246,46 @@ void configure_mpu_dpll(void)
        }
 
        params = get_mpu_dpll_params();
-       do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK);
+
+       do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK, "mpu");
        debug("MPU DPLL locked\n");
 }
 
+#ifdef CONFIG_USB_EHCI_OMAP
+static void setup_usb_dpll(void)
+{
+       const struct dpll_params *params;
+       u32 sys_clk_khz, sd_div, num, den;
+
+       sys_clk_khz = get_sys_clk_freq() / 1000;
+       /*
+        * USB:
+        * USB dpll is J-type. Need to set DPLL_SD_DIV for jitter correction
+        * DPLL_SD_DIV = CEILING ([DPLL_MULT/(DPLL_DIV+1)]* CLKINP / 250)
+        *      - where CLKINP is sys_clk in MHz
+        * Use CLKINP in KHz and adjust the denominator accordingly so
+        * that we have enough accuracy and at the same time no overflow
+        */
+       params = get_usb_dpll_params();
+       num = params->m * sys_clk_khz;
+       den = (params->n + 1) * 250 * 1000;
+       num += den - 1;
+       sd_div = num / den;
+       clrsetbits_le32(&prcm->cm_clksel_dpll_usb,
+                       CM_CLKSEL_DPLL_DPLL_SD_DIV_MASK,
+                       sd_div << CM_CLKSEL_DPLL_DPLL_SD_DIV_SHIFT);
+
+       /* Now setup the dpll with the regular function */
+       do_setup_dpll(&prcm->cm_clkmode_dpll_usb, params, DPLL_LOCK, "usb");
+}
+#endif
+
 static void setup_dplls(void)
 {
-       u32 sysclk_ind, temp;
+       u32 temp;
        const struct dpll_params *params;
-       debug("setup_dplls\n");
 
-       sysclk_ind = get_sys_clk_index();
+       debug("setup_dplls\n");
 
        /* CORE dpll */
        params = get_core_dpll_params();        /* default - safest */
@@ -235,7 +294,8 @@ static void setup_dplls(void)
         * Core DPLL will be locked after setting up EMIF
         * using the FREQ_UPDATE method(freq_update_core())
         */
-       do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, DPLL_NO_LOCK);
+       do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, DPLL_NO_LOCK,
+                                                               "core");
        /* Set the ratios for CORE_CLK, L3_CLK, L4_CLK */
        temp = (CLKSEL_CORE_X2_DIV_1 << CLKSEL_CORE_SHIFT) |
            (CLKSEL_L3_CORE_DIV_2 << CLKSEL_L3_SHIFT) |
@@ -246,20 +306,23 @@ static void setup_dplls(void)
        /* lock PER dpll */
        params = get_per_dpll_params();
        do_setup_dpll(&prcm->cm_clkmode_dpll_per,
-                       params, DPLL_LOCK);
+                       params, DPLL_LOCK, "per");
        debug("PER DPLL locked\n");
 
        /* MPU dpll */
        configure_mpu_dpll();
+
+#ifdef CONFIG_USB_EHCI_OMAP
+       setup_usb_dpll();
+#endif
 }
 
+#ifdef CONFIG_SYS_CLOCKS_ENABLE_ALL
 static void setup_non_essential_dplls(void)
 {
        u32 sys_clk_khz, abe_ref_clk;
-       u32 sysclk_ind, sd_div, num, den;
        const struct dpll_params *params;
 
-       sysclk_ind = get_sys_clk_index();
        sys_clk_khz = get_sys_clk_freq() / 1000;
 
        /* IVA */
@@ -267,27 +330,7 @@ static void setup_non_essential_dplls(void)
                CM_BYPCLK_DPLL_IVA_CLKSEL_MASK, DPLL_IVA_CLKSEL_CORE_X2_DIV_2);
 
        params = get_iva_dpll_params();
-       do_setup_dpll(&prcm->cm_clkmode_dpll_iva, params, DPLL_LOCK);
-
-       /*
-        * USB:
-        * USB dpll is J-type. Need to set DPLL_SD_DIV for jitter correction
-        * DPLL_SD_DIV = CEILING ([DPLL_MULT/(DPLL_DIV+1)]* CLKINP / 250)
-        *      - where CLKINP is sys_clk in MHz
-        * Use CLKINP in KHz and adjust the denominator accordingly so
-        * that we have enough accuracy and at the same time no overflow
-        */
-       params = get_usb_dpll_params();
-       num = params->m * sys_clk_khz;
-       den = (params->n + 1) * 250 * 1000;
-       num += den - 1;
-       sd_div = num / den;
-       clrsetbits_le32(&prcm->cm_clksel_dpll_usb,
-                       CM_CLKSEL_DPLL_DPLL_SD_DIV_MASK,
-                       sd_div << CM_CLKSEL_DPLL_DPLL_SD_DIV_SHIFT);
-
-       /* Now setup the dpll with the regular function */
-       do_setup_dpll(&prcm->cm_clkmode_dpll_usb, params, DPLL_LOCK);
+       do_setup_dpll(&prcm->cm_clkmode_dpll_iva, params, DPLL_LOCK, "iva");
 
        /* Configure ABE dpll */
        params = get_abe_dpll_params();
@@ -315,8 +358,9 @@ static void setup_non_essential_dplls(void)
                        CM_ABE_PLL_REF_CLKSEL_CLKSEL_MASK,
                        abe_ref_clk << CM_ABE_PLL_REF_CLKSEL_CLKSEL_SHIFT);
        /* Lock the dpll */
-       do_setup_dpll(&prcm->cm_clkmode_dpll_abe, params, DPLL_LOCK);
+       do_setup_dpll(&prcm->cm_clkmode_dpll_abe, params, DPLL_LOCK, "abe");
 }
+#endif
 
 void do_scale_tps62361(u32 reg, u32 volt_mv)
 {
@@ -325,14 +369,6 @@ void do_scale_tps62361(u32 reg, u32 volt_mv)
        step = volt_mv - TPS62361_BASE_VOLT_MV;
        step /= 10;
 
-       /*
-        * Select SET1 in TPS62361:
-        * VSEL1 is grounded on board. So the following selects
-        * VSEL1 = 0 and VSEL0 = 1
-        */
-       gpio_direction_output(TPS62361_VSEL0_GPIO, 0);
-       gpio_set_value(TPS62361_VSEL0_GPIO, 1);
-
        temp = TPS62361_I2C_SLAVE_ADDR |
            (reg << PRM_VC_VAL_BYPASS_REGADDR_SHIFT) |
            (step << PRM_VC_VAL_BYPASS_DATA_SHIFT) |
@@ -561,10 +597,15 @@ void prcm_init(void)
                enable_basic_clocks();
                scale_vcores();
                setup_dplls();
+#ifdef CONFIG_SYS_CLOCKS_ENABLE_ALL
                setup_non_essential_dplls();
                enable_non_essential_clocks();
+#endif
                break;
        default:
                break;
        }
+
+       if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context())
+               enable_basic_uboot_clocks();
 }