Esempio n. 1
0
/*
 * PRCM Interrupt Handler Helper Function
 *
 * The purpose of this function is to clear any wake-up events latched
 * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
 * may occur whilst attempting to clear a PM_WKST_x register and thus
 * set another bit in this register. A while loop is used to ensure
 * that any peripheral wake-up events occurring while attempting to
 * clear the PM_WKST_x are detected and cleared.
 */
static int prcm_clear_mod_irqs(s16 module, u8 regs)
{
	u32 wkst, fclk, iclk, clken;
	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
	u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
	u16 grpsel_off = (regs == 3) ?
		OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
	int c = 0;

	wkst = prm_read_mod_reg(module, wkst_off);
	wkst &= prm_read_mod_reg(module, grpsel_off);
	if (wkst) {
		iclk = cm_read_mod_reg(module, iclk_off);
		fclk = cm_read_mod_reg(module, fclk_off);
		while (wkst) {
			clken = wkst;
			cm_set_mod_reg_bits(clken, module, iclk_off);
			/*
			 * For USBHOST, we don't know whether HOST1 or
			 * HOST2 woke us up, so enable both f-clocks
			 */
			if (module == OMAP3430ES2_USBHOST_MOD)
				clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
			cm_set_mod_reg_bits(clken, module, fclk_off);
			prm_write_mod_reg(wkst, module, wkst_off);
			wkst = prm_read_mod_reg(module, wkst_off);
			c++;
		}
		cm_write_mod_reg(iclk, module, iclk_off);
		cm_write_mod_reg(fclk, module, fclk_off);
	}

	return c;
}
Esempio n. 2
0
/*
 * omap3_noncore_dpll_program - set non-core DPLL M,N values directly
 * @clk: struct clk * of DPLL to set
 * @m: DPLL multiplier to set
 * @n: DPLL divider to set
 * @freqsel: FREQSEL value to set
 *
 * Program the DPLL with the supplied M, N values, and wait for the DPLL to
 * lock..  Returns -EINVAL upon error, or 0 upon success.
 */
static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
{
	struct dpll_data *dd;
	u32 v;

	if (!clk)
		return -EINVAL;

	dd = clk->dpll_data;
	if (!dd)
		return -EINVAL;

	/*
	 * According to the 12-5 CDP code from TI, "Limitation 2.5"
	 * on 3430ES1 prevents us from changing DPLL multipliers or dividers
	 * on DPLL4.
	 */
	if (omap_rev() == OMAP3430_REV_ES1_0 &&
	    !strcmp("dpll4_ck", clk->name)) {
		printk(KERN_ERR "clock: DPLL4 cannot change rate due to "
		       "silicon 'Limitation 2.5' on 3430ES1.\n");
		return -EINVAL;
	}

	/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
	_omap3_noncore_dpll_bypass(clk);

	/* Set jitter correction */
	v = cm_read_mod_reg(clk->prcm_mod, dd->control_reg);
	v &= ~dd->freqsel_mask;
	v |= freqsel << __ffs(dd->freqsel_mask);
	cm_write_mod_reg(v, clk->prcm_mod, dd->control_reg);

	/* Set DPLL multiplier, divider */
	v = cm_read_mod_reg(clk->prcm_mod, dd->mult_div1_reg);
	v &= ~(dd->mult_mask | dd->div1_mask);
	v |= m << __ffs(dd->mult_mask);
	v |= (n - 1) << __ffs(dd->div1_mask);
	if (dd->jtype) {
		u8 dco, sd_div;
		lookup_dco_sddiv(clk, &dco, &sd_div, m, n);
		v &= ~(dd->dco_sel_mask | dd->sd_div_mask);
		v |=  dco << __ffs(dd->dco_sel_mask);
		v |=  sd_div << __ffs(dd->sd_div_mask);
	}
	cm_write_mod_reg(v, clk->prcm_mod, dd->mult_div1_reg);

	/* We let the clock framework set the other output dividers later */

	/* REVISIT: Set ramp-up delay? */

	_omap3_noncore_dpll_lock(clk);

	return 0;
}
Esempio n. 3
0
/* Enable an APLL if off */
static int omap2_clk_fixed_enable(struct clk *clk)
{
    u32 cval, apll_mask;

    apll_mask = EN_APLL_LOCKED << clk->enable_bit;

    cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);

    if ((cval & apll_mask) == apll_mask)
        return 0;   /* apll already enabled */

    cval &= ~apll_mask;
    cval |= apll_mask;
    cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);

    if (clk == &apll96_ck)
        cval = OMAP24XX_ST_96M_APLL;
    else if (clk == &apll54_ck)
        cval = OMAP24XX_ST_54M_APLL;

    omap2_wait_clock_ready(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval,
                clk->name);

    /*
     * REVISIT: Should we return an error code if omap2_wait_clock_ready()
     * fails?
     */
    return 0;
}
Esempio n. 4
0
/* Stop APLL */
static void omap2_clk_fixed_disable(struct clk *clk)
{
    u32 cval;

    cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
    cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
    cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
}
Esempio n. 5
0
/* Read-modify-write a register in a CM module. Caller must lock */
u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
{
	u32 v;

	v = cm_read_mod_reg(module, idx);
	v &= ~mask;
	v |= bits;
	cm_write_mod_reg(v, module, idx);

	return v;
}
Esempio n. 6
0
/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
{
	const struct dpll_data *dd;
	u32 v;

	dd = clk->dpll_data;

	v = cm_read_mod_reg(clk->prcm_mod, dd->control_reg);
	v &= ~dd->enable_mask;
	v |= clken_bits << __ffs(dd->enable_mask);
	cm_write_mod_reg(v, clk->prcm_mod, dd->control_reg);
}
Esempio n. 7
0
/**
 * omap3_dpll_deny_idle - prevent DPLL from automatically idling
 * @clk: struct clk * of the DPLL to operate on
 *
 * Disable DPLL automatic idle control.  No return value.
 */
static void omap3_dpll_deny_idle(struct clk *clk)
{
	const struct dpll_data *dd;
	u32 v;

	if (!clk || !clk->dpll_data)
		return;

	dd = clk->dpll_data;

	v = cm_read_mod_reg(clk->prcm_mod, dd->autoidle_reg);
	v &= ~dd->autoidle_mask;
	v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
	cm_write_mod_reg(v, clk->prcm_mod, dd->autoidle_reg);
}
Esempio n. 8
0
/**
 * omap3_dpll_allow_idle - enable DPLL autoidle bits
 * @clk: struct clk * of the DPLL to operate on
 *
 * Enable DPLL automatic idle control.  This automatic idle mode
 * switching takes effect only when the DPLL is locked, at least on
 * OMAP3430.  The DPLL will enter low-power stop when its downstream
 * clocks are gated.  No return value.
 */
static void omap3_dpll_allow_idle(struct clk *clk)
{
	const struct dpll_data *dd;
	u32 v;

	if (!clk || !clk->dpll_data)
		return;

	dd = clk->dpll_data;

	/*
	 * REVISIT: CORE DPLL can optionally enter low-power bypass
	 * by writing 0x5 instead of 0x1.  Add some mechanism to
	 * optionally enter this mode.
	 */
	v = cm_read_mod_reg(clk->prcm_mod, dd->autoidle_reg);
	v &= ~dd->autoidle_mask;
	v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
	cm_write_mod_reg(v, clk->prcm_mod, dd->autoidle_reg);
}
Esempio n. 9
0
/* Enable an APLL if off */
static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
{
	u32 cval, apll_mask;

	apll_mask = EN_APLL_LOCKED << clk->enable_bit;

	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);

	if ((cval & apll_mask) == apll_mask)
		return 0;   /* apll already enabled */

	cval &= ~apll_mask;
	cval |= apll_mask;
	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);

	omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
			     OMAP24XX_CM_IDLEST_VAL, clk->name);

	/*
	 * REVISIT: Should we return an error code if omap2_wait_clock_ready()
	 * fails?
	 */
	return 0;
}
Esempio n. 10
0
static void __init prcm_setup_regs(void)
{
	int i, num_mem_banks;
	struct powerdomain *pwrdm;

	/* Enable autoidle */
	prm_write_mod_reg(OMAP24XX_AUTOIDLE, OCP_MOD,
				OMAP24XX_PRM_SYSCONFIG_OFFSET);

	/* Set all domain wakeup dependencies */
	prm_write_mod_reg(OMAP_EN_WKUP_MASK, MPU_MOD, PM_WKDEP);
	prm_write_mod_reg(0, OMAP24XX_DSP_MOD, PM_WKDEP);
	prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
	prm_write_mod_reg(0, CORE_MOD, PM_WKDEP);
	if (cpu_is_omap2430())
		prm_write_mod_reg(0, OMAP2430_MDM_MOD, PM_WKDEP);

	/*
	 * Set CORE powerdomain memory banks to retain their contents
	 * during RETENTION
	 */
	num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm);
	for (i = 0; i < num_mem_banks; i++)
		pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);

	/* Set CORE powerdomain's next power state to RETENTION */
	pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);

	/*
	 * Set MPU powerdomain's next power state to RETENTION;
	 * preserve logic state during retention
	 */
	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);

	/* Force-power down DSP, GFX powerdomains */

	pwrdm = clkdm_get_pwrdm(dsp_clkdm);
	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
	omap2_clkdm_sleep(dsp_clkdm);

	pwrdm = clkdm_get_pwrdm(gfx_clkdm);
	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
	omap2_clkdm_sleep(gfx_clkdm);

	/* Enable clockdomain hardware-supervised control for all clkdms */
	clkdm_for_each(_pm_clkdm_enable_hwsup, NULL);

	/* Enable clock autoidle for all domains */
	cm_write_mod_reg(OMAP24XX_AUTO_CAM |
			 OMAP24XX_AUTO_MAILBOXES |
			 OMAP24XX_AUTO_WDT4 |
			 OMAP2420_AUTO_WDT3 |
			 OMAP24XX_AUTO_MSPRO |
			 OMAP2420_AUTO_MMC |
			 OMAP24XX_AUTO_FAC |
			 OMAP2420_AUTO_EAC |
			 OMAP24XX_AUTO_HDQ |
			 OMAP24XX_AUTO_UART2 |
			 OMAP24XX_AUTO_UART1 |
			 OMAP24XX_AUTO_I2C2 |
			 OMAP24XX_AUTO_I2C1 |
			 OMAP24XX_AUTO_MCSPI2 |
			 OMAP24XX_AUTO_MCSPI1 |
			 OMAP24XX_AUTO_MCBSP2 |
			 OMAP24XX_AUTO_MCBSP1 |
			 OMAP24XX_AUTO_GPT12 |
			 OMAP24XX_AUTO_GPT11 |
			 OMAP24XX_AUTO_GPT10 |
			 OMAP24XX_AUTO_GPT9 |
			 OMAP24XX_AUTO_GPT8 |
			 OMAP24XX_AUTO_GPT7 |
			 OMAP24XX_AUTO_GPT6 |
			 OMAP24XX_AUTO_GPT5 |
			 OMAP24XX_AUTO_GPT4 |
			 OMAP24XX_AUTO_GPT3 |
			 OMAP24XX_AUTO_GPT2 |
			 OMAP2420_AUTO_VLYNQ |
			 OMAP24XX_AUTO_DSS,
			 CORE_MOD, CM_AUTOIDLE1);
	cm_write_mod_reg(OMAP24XX_AUTO_UART3 |
			 OMAP24XX_AUTO_SSI |
			 OMAP24XX_AUTO_USB,
			 CORE_MOD, CM_AUTOIDLE2);
	cm_write_mod_reg(OMAP24XX_AUTO_SDRC |
			 OMAP24XX_AUTO_GPMC |
			 OMAP24XX_AUTO_SDMA,
			 CORE_MOD, CM_AUTOIDLE3);
	cm_write_mod_reg(OMAP24XX_AUTO_PKA |
			 OMAP24XX_AUTO_AES |
			 OMAP24XX_AUTO_RNG |
			 OMAP24XX_AUTO_SHA |
			 OMAP24XX_AUTO_DES,
			 CORE_MOD, OMAP24XX_CM_AUTOIDLE4);

	cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI, OMAP24XX_DSP_MOD, CM_AUTOIDLE);

	/* Put DPLL and both APLLs into autoidle mode */
	cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) |
			 (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
			 (0x03 << OMAP24XX_AUTO_54M_SHIFT),
			 PLL_MOD, CM_AUTOIDLE);

	cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL |
			 OMAP24XX_AUTO_WDT1 |
			 OMAP24XX_AUTO_MPU_WDT |
			 OMAP24XX_AUTO_GPIOS |
			 OMAP24XX_AUTO_32KSYNC |
			 OMAP24XX_AUTO_GPT1,
			 WKUP_MOD, CM_AUTOIDLE);

	/* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
	 * stabilisation */
	prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
					OMAP24XX_PRCM_CLKSSETUP_OFFSET);

	/* Configure automatic voltage transition */
	prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
					OMAP24XX_PRCM_VOLTSETUP_OFFSET);
	prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT |
		      (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) |
		      OMAP24XX_MEMRETCTRL |
		      (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) |
		      (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT),
		      OMAP24XX_GR_MOD, OMAP24XX_PRCM_VOLTCTRL_OFFSET);

	/* Enable wake-up events */
	prm_write_mod_reg(OMAP24XX_EN_GPIOS | OMAP24XX_EN_GPT1,
			  WKUP_MOD, PM_WKEN);
}
Esempio n. 11
0
void omap3_prcm_restore_context(void)
{
	omap_ctrl_writel(prcm_context.control_padconf_sys_nirq,
					 OMAP343X_CONTROL_PADCONF_SYSNIRQ);
	cm_write_mod_reg(prcm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
					 CM_CLKSEL1);
	cm_write_mod_reg(prcm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
					 CM_CLKSEL2);
	__raw_writel(prcm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
	cm_write_mod_reg(prcm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
					 CM_CLKSEL);
	cm_write_mod_reg(prcm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
					 CM_CLKSEL);
	cm_write_mod_reg(prcm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
					 CM_CLKSEL);
	cm_write_mod_reg(prcm_context.per_cm_clksel, OMAP3430_PER_MOD,
					 CM_CLKSEL);
	cm_write_mod_reg(prcm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
					 CM_CLKSEL1);
	cm_write_mod_reg(prcm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
					 OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.pll_cm_autoidle2, PLL_MOD,
					 CM_AUTOIDLE2);
	cm_write_mod_reg(prcm_context.pll_cm_clksel4, PLL_MOD,
					OMAP3430ES2_CM_CLKSEL4);
	cm_write_mod_reg(prcm_context.pll_cm_clksel5, PLL_MOD,
					 OMAP3430ES2_CM_CLKSEL5);
	cm_write_mod_reg(prcm_context.pll_cm_clken2, PLL_MOD,
					OMAP3430ES2_CM_CLKEN2);
	__raw_writel(prcm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
	cm_write_mod_reg(prcm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
					 CM_FCLKEN);
	cm_write_mod_reg(prcm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
					OMAP3430_CM_CLKEN_PLL);
	cm_write_mod_reg(prcm_context.core_cm_fclken1, CORE_MOD, CM_FCLKEN1);
	cm_write_mod_reg(prcm_context.core_cm_fclken3, CORE_MOD,
					 OMAP3430ES2_CM_FCLKEN3);
	cm_write_mod_reg(prcm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
					 CM_FCLKEN);
	cm_write_mod_reg(prcm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
	cm_write_mod_reg(prcm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
					 CM_FCLKEN);
	cm_write_mod_reg(prcm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
					 CM_FCLKEN);
	cm_write_mod_reg(prcm_context.per_cm_fclken, OMAP3430_PER_MOD,
					 CM_FCLKEN);
	cm_write_mod_reg(prcm_context.usbhost_cm_fclken,
					 OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
	cm_write_mod_reg(prcm_context.core_cm_iclken1, CORE_MOD, CM_ICLKEN1);
	cm_write_mod_reg(prcm_context.core_cm_iclken2, CORE_MOD, CM_ICLKEN2);
	cm_write_mod_reg(prcm_context.core_cm_iclken3, CORE_MOD, CM_ICLKEN3);
	cm_write_mod_reg(prcm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
					CM_ICLKEN);
	cm_write_mod_reg(prcm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
	cm_write_mod_reg(prcm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
					CM_ICLKEN);
	cm_write_mod_reg(prcm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
					CM_ICLKEN);
	cm_write_mod_reg(prcm_context.per_cm_iclken, OMAP3430_PER_MOD,
					CM_ICLKEN);
	cm_write_mod_reg(prcm_context.usbhost_cm_iclken,
					OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
	cm_write_mod_reg(prcm_context.iva2_cm_autiidle2, OMAP3430_IVA2_MOD,
					CM_AUTOIDLE2);
	cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
	cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
					OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD,
					OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.core_cm_clkstctrl, CORE_MOD,
					OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
					OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
					OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
					OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
					OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
					OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.usbhost_cm_clkstctrl,
				OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
	cm_write_mod_reg(prcm_context.core_cm_autoidle1, CORE_MOD,
					CM_AUTOIDLE1);
	cm_write_mod_reg(prcm_context.core_cm_autoidle2, CORE_MOD,
					CM_AUTOIDLE2);
	cm_write_mod_reg(prcm_context.core_cm_autoidle3, CORE_MOD,
					CM_AUTOIDLE3);
	cm_write_mod_reg(prcm_context.wkup_cm_autoidle, WKUP_MOD, CM_AUTOIDLE);
	cm_write_mod_reg(prcm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
					CM_AUTOIDLE);
	cm_write_mod_reg(prcm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
					CM_AUTOIDLE);
	cm_write_mod_reg(prcm_context.per_cm_autoidle, OMAP3430_PER_MOD,
					CM_AUTOIDLE);
	cm_write_mod_reg(prcm_context.usbhost_cm_autoidle,
					OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
	cm_write_mod_reg(prcm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
					OMAP3430_CM_SLEEPDEP);
	cm_write_mod_reg(prcm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
					OMAP3430_CM_SLEEPDEP);
	cm_write_mod_reg(prcm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
					OMAP3430_CM_SLEEPDEP);
	cm_write_mod_reg(prcm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
					OMAP3430_CM_SLEEPDEP);
	cm_write_mod_reg(prcm_context.usbhost_cm_sleepdep,
				OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
	cm_write_mod_reg(prcm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
					OMAP3_CM_CLKOUT_CTRL_OFFSET);
	prm_write_mod_reg(prcm_context.prm_clkout_ctrl, OMAP3430_CCR_MOD,
					OMAP3_PRM_CLKOUT_CTRL_OFFSET);
	prm_write_mod_reg(prcm_context.sgx_pm_wkdep, OMAP3430ES2_SGX_MOD,
					PM_WKDEP);
	prm_write_mod_reg(prcm_context.dss_pm_wkdep, OMAP3430_DSS_MOD,
					PM_WKDEP);
	prm_write_mod_reg(prcm_context.cam_pm_wkdep, OMAP3430_CAM_MOD,
					PM_WKDEP);
	prm_write_mod_reg(prcm_context.per_pm_wkdep, OMAP3430_PER_MOD,
					PM_WKDEP);
	prm_write_mod_reg(prcm_context.neon_pm_wkdep, OMAP3430_NEON_MOD,
					PM_WKDEP);
	prm_write_mod_reg(prcm_context.usbhost_pm_wkdep,
					OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
	prm_write_mod_reg(prcm_context.core_pm_mpugrpsel1, CORE_MOD,
					OMAP3430_PM_MPUGRPSEL1);
	prm_write_mod_reg(prcm_context.iva2_pm_ivagrpsel1, OMAP3430_IVA2_MOD,
					OMAP3430_PM_IVAGRPSEL1);
	prm_write_mod_reg(prcm_context.core_pm_mpugrpsel3, CORE_MOD,
					OMAP3430ES2_PM_MPUGRPSEL3);
	prm_write_mod_reg(prcm_context.core_pm_ivagrpsel3, CORE_MOD,
					OMAP3430ES2_PM_IVAGRPSEL3);
	prm_write_mod_reg(prcm_context.wkup_pm_mpugrpsel, WKUP_MOD,
					OMAP3430_PM_MPUGRPSEL);
	prm_write_mod_reg(prcm_context.wkup_pm_ivagrpsel, WKUP_MOD,
					OMAP3430_PM_IVAGRPSEL);
	prm_write_mod_reg(prcm_context.per_pm_mpugrpsel, OMAP3430_PER_MOD,
					OMAP3430_PM_MPUGRPSEL);
	prm_write_mod_reg(prcm_context.per_pm_ivagrpsel, OMAP3430_PER_MOD,
					 OMAP3430_PM_IVAGRPSEL);
	prm_write_mod_reg(prcm_context.wkup_pm_wken, WKUP_MOD, PM_WKEN);
	return;
}
Esempio n. 12
0
/* Sets basic clocks based on the specified rate */
static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
{
    u32 cur_rate, done_rate, bypass = 0, tmp;
    struct prcm_config *prcm;
    unsigned long flags, found_speed;

    if (clk != &virt_prcm_set)
        return -EINVAL;

    found_speed = omap2xxx_clk_find_oppset_by_mpurate(rate, &prcm);
    if (!found_speed) {
        printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
               rate / 1000000);
        return -EINVAL;
    }

    curr_prcm_set = prcm;
    cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck, dpll_ck.parent->rate);

    if (prcm->dpll_speed == cur_rate / 2) {
        omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
    } else if (prcm->dpll_speed == cur_rate * 2) {
        omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
    } else if (prcm->dpll_speed != cur_rate) {
        local_irq_save(flags);

        if (prcm->dpll_speed == prcm->xtal_speed)
            bypass = 1;

        if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
                CORE_CLK_SRC_DPLL_X2)
            done_rate = CORE_CLK_SRC_DPLL_X2;
        else
            done_rate = CORE_CLK_SRC_DPLL;

        /* MPU divider */
        cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);

        /* dsp + iva1 div(2420), iva2.1(2430) */
        cm_write_mod_reg(prcm->cm_clksel_dsp,
                         OMAP24XX_DSP_MOD, CM_CLKSEL);

        cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);

        /* Major subsystem dividers */
        tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
        cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
                         CM_CLKSEL1);

        if (cpu_is_omap2430())
            cm_write_mod_reg(prcm->cm_clksel_mdm,
                             OMAP2430_MDM_MOD, CM_CLKSEL);

        /* x2 to enter omap2xxx_sdrc_init_params() */
        omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);

        omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
                       bypass);

        omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
        omap2xxx_sdrc_reprogram(done_rate, 0);

        local_irq_restore(flags);
    }

    return 0;
}
int request_gptimer12( struct gptimer12_timer *timer )
{
	int loop_count;
	int empty_slot = -1;
	unsigned int next_time = 0;
	unsigned int current_time = 0;
	//unsigned int temp; 

	unsigned char update_flag = 0;
	// printk("request_gptimer12 called \n");

	if ( gptimer12_count >= MAX_GPTIMER12_INSTANCE ) 
	{
		printk( "Error... max gptimer12 instance" );
		return -1;
	}
	//CM_ICLKEN_WKUP |= 1 << 1;
	cm_val = cm_read_mod_reg( WKUP_MOD, CM_ICLKEN1 );
	cm_val = cm_val | ( 1 << 1 );
	cm_write_mod_reg( cm_val, WKUP_MOD, CM_ICLKEN1 );

	//modify exist entry 
	for ( loop_count = 0; loop_count < MAX_GPTIMER12_INSTANCE; loop_count++ )
	{
		if ( timer_manager[loop_count].timer.name != NULL ) 
		{
			if( strcmp( timer_manager[loop_count].timer.name, timer->name ) == 0 ) 
			{
				//printk("timer update \n");
				memcpy( &( timer_manager[loop_count].timer ), timer, sizeof( struct gptimer12_timer ) );
				timer_manager[loop_count].remain_time = timer->expire_time;
				update_flag = 1;
			}
		}
	}

	next_time = timer->expire_time;
	if ( update_flag == 0 ) 
	{
		//add new entry 
		for ( loop_count = 0; loop_count < MAX_GPTIMER12_INSTANCE; loop_count++ )
		{
			if ( ( timer_manager[loop_count].timer.name ) == NULL )
			{
				empty_slot = loop_count;
				break;
			}
		}
		//printk("empty_slot : %d, loop_count : %d\n",empty_slot,loop_count);

		if ( empty_slot == -1 )
		{
			printk("Error.. No empty slot ");
			return -1;
		}

		gptimer12_count++;

		memcpy(&(timer_manager[empty_slot].timer),timer, sizeof(struct gptimer12_timer));
		timer_manager[empty_slot].remain_time = timer->expire_time;

		// printk("test3 : gptimer12_count : %d\n",gptimer12_count);

		if ( gptimer12_count == 1 )
		{
			omap_dm_timer_enable( battery_timer );
			prcm_wakeup_event_control( PRCM_GPT12, PRCM_ENABLE );
			omap_dm_timer_write_status( battery_timer, OMAP_TIMER_INT_OVERFLOW );
			omap_dm_timer_set_int_enable( battery_timer, OMAP_TIMER_INT_OVERFLOW );

			for ( loop_count = 0 ; loop_count < MAX_GPTIMER12_INSTANCE ; loop_count++ )
			{
				if ( timer_manager[loop_count].timer.name != NULL )
					timer_manager[loop_count].remain_time -= next_time;
			}
			omap_dm_timer_set_load_start( battery_timer, 0, 0xffffffff - GP_TIMER12_SEC_TO_TICK(next_time) );
			//CM_ICLKEN_WKUP &= ~(1 << 1);
#if 0
			cm_val = cm_read_mod_reg(WKUP_MOD,CM_ICLKEN1);
			cm_val = cm_val&~(1<<1);
			cm_write_mod_reg(cm_val,WKUP_MOD,CM_ICLKEN1);
#endif

			timer->active = true;

			return 1;
		}
	}

	omap_dm_timer_stop( battery_timer ); //:commented this

#if 1
	current_time = GP_TIMER12_TICK_TO_SEC( 0xffffffff - omap_dm_timer_read_counter(battery_timer) );
#endif
	for ( loop_count = 0; loop_count < MAX_GPTIMER12_INSTANCE; loop_count++ )
	{
		timer_manager[loop_count].remain_time += current_time;
#if 0 
		if((timer_manager[loop_count].timer.name) != 0)
		{
			if((timer_manager[loop_count].remain_time) == 0)
			timer_manager[loop_count].remain_time = current_time; 
		}
#endif
	}

	for ( loop_count = 0 ; loop_count < MAX_GPTIMER12_INSTANCE ; loop_count++ )
	{
		if ( timer_manager[loop_count].timer.name != NULL )
		{
			next_time = timer_manager[loop_count].remain_time;
			break;
		}
	}

	for ( loop_count = 0 ; loop_count < MAX_GPTIMER12_INSTANCE ; loop_count++ )
	{
		if ( timer_manager[loop_count].timer.name != NULL )
		{
			if ( next_time > timer_manager[loop_count].remain_time )
				next_time = timer_manager[loop_count].remain_time;
		}
	}

	for ( loop_count = 0 ; loop_count < MAX_GPTIMER12_INSTANCE ; loop_count++ )
	{
		if ( timer_manager[loop_count].timer.name != NULL )
			timer_manager[loop_count].remain_time -= next_time;
	}

	// timer
	prcm_wakeup_event_control( PRCM_GPT12, PRCM_ENABLE );
	omap_dm_timer_set_int_enable( battery_timer, OMAP_TIMER_INT_OVERFLOW );
	omap_dm_timer_set_load_start( battery_timer, 0, 0xffffffff - GP_TIMER12_SEC_TO_TICK(next_time) );
	//CM_ICLKEN_WKUP &= ~(1 << 1);
#if 0
	cm_val = cm_read_mod_reg(WKUP_MOD,CM_ICLKEN1);
	cm_val = cm_val&~(1<<1);
	cm_write_mod_reg(cm_val,WKUP_MOD,CM_ICLKEN1);
	// printk("requested gptimer12_count : %d \n",gptimer12_count);
#endif

	timer->active = true;

	return 1;

}
int release_gptimer12(struct gptimer12_timer *timer)
{
	int loop_count;
	int temp_count;
	int slot = -1;
	unsigned int next_time=0;
	int current_time;

	if ( gptimer12_count == 0 )
		return -1;

	//printk ("\ntest 1 timer_instance_count : %d \n",gptimer12_count);

	for ( loop_count = 0; loop_count < MAX_GPTIMER12_INSTANCE ; loop_count++ ) 
	{
		if ( timer_manager[loop_count].timer.name != NULL)
		{
			if( strcmp( timer->name, timer_manager[loop_count].timer.name ) == 0 )
			{
				slot = loop_count;
				break;
			}
		}
	}

	if ( slot == -1 )
		return -1;

	// case : delete current working timer 
	//CM_ICLKEN_WKUP |= 1 << 1;
	cm_val = cm_read_mod_reg( WKUP_MOD, CM_ICLKEN1 );
	cm_val = cm_val | ( 1 << 1 );
	cm_write_mod_reg( cm_val, WKUP_MOD, CM_ICLKEN1 );

	if ( timer_manager[slot].remain_time == 0 )
	{
		//current timer ..
		omap_dm_timer_stop( battery_timer );
		current_time = GP_TIMER12_TICK_TO_SEC( 0xffffffff - omap_dm_timer_read_counter( battery_timer ) );
		//printk("test1 current_time : %d\n",current_time);
		for ( loop_count = 0; loop_count < MAX_GPTIMER12_INSTANCE; loop_count++ )
		{
			timer_manager[loop_count].remain_time += current_time;
#if 0 
			if((timer_manager[loop_count].timer.name) != 0)
			{
				if((timer_manager[loop_count].remain_time) == 0)
					timer_manager[loop_count].remain_time = current_time; 

			}
#endif
		}
	}

	memset ( &( timer_manager[slot] ), 0, sizeof( struct gptimer12_manager ) );
	gptimer12_count--;
	
	if( gptimer12_count < 0 )
		gptimer12_count = 0;

	//printk("released : timer_instance_count : %d\n",gptimer12_count);
	if ( gptimer12_count == 0 )
	{
		//printk("\n\n M        timer empty .. \n"); 
		prcm_wakeup_event_control( PRCM_GPT12, PRCM_DISABLE ); //egkim
		finish_gptimer12(); //egkim
		omap_dm_timer_disable( battery_timer );

		//CM_ICLKEN_WKUP &= ~(1 << 1);
		cm_val = cm_read_mod_reg( WKUP_MOD, CM_ICLKEN1 );
		cm_val = cm_val & ~( 1 << 1 );
		cm_write_mod_reg( cm_val, WKUP_MOD,CM_ICLKEN1 );

		/* change active state. */
		timer->active = false;

		return 0;
	}

	for ( temp_count = 0 ; temp_count < MAX_GPTIMER12_INSTANCE ; temp_count++ )
	{
		if( timer_manager[temp_count].timer.name != NULL )
		{
			next_time = timer_manager[temp_count].remain_time;
			break;
		}
	}

	for ( temp_count = 0 ; temp_count < MAX_GPTIMER12_INSTANCE ; temp_count++ )
	{
		if ( timer_manager[temp_count].timer.name != NULL )
		{
			next_time = timer_manager[temp_count].remain_time;
			break;
		}
	}

	for ( loop_count = 0 ; loop_count < MAX_GPTIMER12_INSTANCE ; loop_count++ )
	{
		if( timer_manager[loop_count].timer.name != NULL )
		{
			if ( next_time > timer_manager[loop_count].remain_time )
				next_time = timer_manager[loop_count].remain_time;
		}
	}

	for ( loop_count = 0 ; loop_count < MAX_GPTIMER12_INSTANCE ; loop_count++ )
	{
		if( timer_manager[loop_count].timer.name != NULL )
			timer_manager[loop_count].remain_time -= next_time;
	}
	printk( "\n\n\n next timeout : %d\n",next_time );
	prcm_wakeup_event_control( PRCM_GPT12, PRCM_ENABLE );
	omap_dm_timer_set_load_start( battery_timer, 0, 0xffffffff - GP_TIMER12_SEC_TO_TICK(next_time) );

	//CM_ICLKEN_WKUP &= ~(1 << 1);
	cm_val = cm_read_mod_reg( WKUP_MOD, CM_ICLKEN1 );
	cm_val = cm_val & ~( 1 << 1 );
	cm_write_mod_reg( cm_val, WKUP_MOD,CM_ICLKEN1 );

	timer->active = false;

	return 0;
}
Esempio n. 15
0
/**
 * usb_hcd_omap_probe - initialize OMAP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int usb_hcd_omap_probe(const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	int i;
	u32 uhh_hostconfig_value;
	u8 ohci_port_enable_mask = 0;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;
	struct ohci_omap_clock_defs *ohci_clocks;

	if (pdev->num_resources != 2) {
		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
		       pdev->num_resources);
		return -ENODEV;
	}

	if (pdev->resource[0].flags != IORESOURCE_MEM
			|| pdev->resource[1].flags != IORESOURCE_IRQ) {
		printk(KERN_ERR "hcd probe: invalid resource type\n");
		return -ENODEV;
	}

	hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
	if (!hcd) {
		retval = -ENOMEM;
		goto err0;
	}

	ohci_clocks = (struct ohci_omap_clock_defs *)
			(((char *)hcd_to_ohci(hcd)) + sizeof(struct ohci_hcd));

	/* Enable Clocks for USBHOST */
	ohci_clocks->usbhost_ick_clk = clk_get(&pdev->dev,
						USBHOST_ICLK);
	if (IS_ERR(ohci_clocks->usbhost_ick_clk))
		return PTR_ERR(ohci_clocks->usbhost_ick_clk);
	clk_enable(ohci_clocks->usbhost_ick_clk);

	ohci_clocks->usbhost2_120m_fck_clk = clk_get(&pdev->dev,
						USBHOST_120M_FCLK);
	if (IS_ERR(ohci_clocks->usbhost2_120m_fck_clk)) {
		clk_disable(ohci_clocks->usbhost_ick_clk);
		clk_put(ohci_clocks->usbhost_ick_clk);
		return PTR_ERR(ohci_clocks->usbhost2_120m_fck_clk);
	}
	clk_enable(ohci_clocks->usbhost2_120m_fck_clk);

	ohci_clocks->usbhost1_48m_fck_clk = clk_get(&pdev->dev,
						USBHOST_48M_FCLK);
	if (IS_ERR(ohci_clocks->usbhost1_48m_fck_clk)) {
		clk_disable(ohci_clocks->usbhost_ick_clk);
		clk_put(ohci_clocks->usbhost_ick_clk);
		clk_disable(ohci_clocks->usbhost2_120m_fck_clk);
		clk_put(ohci_clocks->usbhost2_120m_fck_clk);
		return PTR_ERR(ohci_clocks->usbhost1_48m_fck_clk);
	}
	clk_enable(ohci_clocks->usbhost1_48m_fck_clk);

	/* Configure TLL for 60Mhz clk for ULPI */
	ohci_clocks->usbtll_fck_clk = clk_get(&pdev->dev,
						USBHOST_TLL_FCLK);
	if (IS_ERR(ohci_clocks->usbtll_fck_clk)) {
		clk_disable(ohci_clocks->usbhost_ick_clk);
		clk_put(ohci_clocks->usbhost_ick_clk);
		clk_disable(ohci_clocks->usbhost2_120m_fck_clk);
		clk_put(ohci_clocks->usbhost2_120m_fck_clk);
		clk_disable(ohci_clocks->usbhost1_48m_fck_clk);
		clk_put(ohci_clocks->usbhost1_48m_fck_clk);
		return PTR_ERR(ohci_clocks->usbtll_fck_clk);
	}
	clk_enable(ohci_clocks->usbtll_fck_clk);

	ohci_clocks->usbtll_ick_clk = clk_get(&pdev->dev,
						USBHOST_TLL_ICLK);
	if (IS_ERR(ohci_clocks->usbtll_ick_clk)) {
		clk_disable(ohci_clocks->usbhost_ick_clk);
		clk_put(ohci_clocks->usbhost_ick_clk);
		clk_disable(ohci_clocks->usbhost2_120m_fck_clk);
		clk_put(ohci_clocks->usbhost2_120m_fck_clk);
		clk_disable(ohci_clocks->usbhost1_48m_fck_clk);
		clk_put(ohci_clocks->usbhost1_48m_fck_clk);
		clk_disable(ohci_clocks->usbtll_fck_clk);
		clk_put(ohci_clocks->usbtll_fck_clk);
		return PTR_ERR(ohci_clocks->usbtll_ick_clk);
	}

	clk_enable(ohci_clocks->usbtll_ick_clk);

	ohci_clocks->suspended = 0;

	/* Disable Auto Idle of USBTLL */
	cm_write_mod_reg((0 << OMAP3430ES2_AUTO_USBTLL_SHIFT),
				CORE_MOD, CM_AUTOIDLE3);

	/* Wait for TLL to be Active */
	while ((cm_read_mod_reg(CORE_MOD, OMAP2430_CM_IDLEST3) &
				(1 << OMAP3430ES2_ST_USBTLL_SHIFT)));

	/* perform TLL soft reset, and wait until reset is complete */
	omap_writel(1 << OMAP_USBTLL_SYSCONFIG_SOFTRESET_SHIFT,
				OMAP_USBTLL_SYSCONFIG);
	/* Wait for TLL reset to complete */
	while (!(omap_readl(OMAP_USBTLL_SYSSTATUS) &
			(1 << OMAP_USBTLL_SYSSTATUS_RESETDONE_SHIFT)));

	/* smart idle mode */
	omap_writel((1 << OMAP_USBTLL_SYSCONFIG_ENAWAKEUP_SHIFT) |
			(2 << OMAP_USBTLL_SYSCONFIG_SIDLEMODE_SHIFT) |
			(0 << OMAP_USBTLL_SYSCONFIG_CACTIVITY_SHIFT) |
			(1 << OMAP_USBTLL_SYSCONFIG_AUTOIDLE_SHIFT),
						OMAP_USBTLL_SYSCONFIG);


	/* Put UHH in SmartIdle/SmartStandby mode */
	omap_writel((1 << OMAP_UHH_SYSCONFIG_AUTOIDLE_SHIFT) |
			(1 << OMAP_UHH_SYSCONFIG_ENAWAKEUP_SHIFT) |
			(2 << OMAP_UHH_SYSCONFIG_SIDLEMODE_SHIFT) |
			(0 << OMAP_UHH_SYSCONFIG_CACTIVITY_SHIFT) |
			(2 << OMAP_UHH_SYSCONFIG_MIDLEMODE_SHIFT),
						OMAP_UHH_SYSCONFIG);

#ifdef CONFIG_OMAP_OHCI_PHY_MODE
	/* TLL in FS-PHY mode operation */
	uhh_hostconfig_value = (1 << OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN_SHIFT) |
			(1 << OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN_SHIFT) |
			(1 << OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN_SHIFT) |
			(0 << OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN_SHIFT);

	if (is_sil_rev_greater_than(OMAP3430_REV_ES2_1)) {

/* For ES 3, we have per-port control for the ULPI Bypass
 * The ULPI Bypass needs to be set to 0 only if the EHCI PHY Mode
 * is selected for that port.
 * Hence it is easier to make it conditional on EHCI_PHY_MODE
 *
 * ES 2 does not have per-port control. Hence it is not possible to have
 * EHCI in PHY Mode and OHCI both working at the same time
 *
 * FIXME: This common code should be moved elsewhere
 *
 */

#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT1
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P1_ULPI_BYPASS_SHIFT);
#endif

#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT2
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P2_ULPI_BYPASS_SHIFT);
#endif

#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT3
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P3_ULPI_BYPASS_SHIFT);
#endif
	} else {
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P1_ULPI_BYPASS_SHIFT);
	}

	omap_writel(uhh_hostconfig_value, OMAP_UHH_HOSTCONFIG);

#if 0
	/* Ensure BYPASS bit is not set */
	while (!(omap_readl(OMAP_UHH_HOSTCONFIG) &
		(1 << OMAP_UHH_HOSTCONFIG_P3_ULPI_BYPASS_SHIFT)));
#endif

	pr_debug("Entered UTMI PHY MODE: success");

	/* Program Common TLL register */
	omap_writel((1 << OMAP_TLL_SHARED_CONF_FCLK_IS_ON_SHIFT) |
			(1 << OMAP_TLL_SHARED_CONF_USB_DIVRATION_SHIFT) |
			(0 << OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN_SHIFT) |
			(0 << OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN_SHFT),
				OMAP_TLL_SHARED_CONF);
#if defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT1) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT1)
		ohci_port_enable_mask |= (1 << 0);
#endif

#if defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT2) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT2)
		ohci_port_enable_mask |= (1 << 1);
#endif

#if defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT3) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT3)
		ohci_port_enable_mask |= (1 << 2);
#endif


#ifdef CONFIG_OMAP_OHCI_PHY_MODE_3PIN
	/* Program the 3 TLL channels upfront */

	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {

		/* Enable only required ports */
		if (!(ohci_port_enable_mask & (1 << i)))
			continue;

		/* Disable AutoIdle */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) &
			    ~(1 << OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

		/* Disable BitStuffing */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			(1 << OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF_SHIFT),
			OMAP_TLL_CHANNEL_CONF(i));

		/* SDR Mode */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) &
			    ~(1 << OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

		/* CHANMODE: UTMI-to-serial FS/LS mode */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			(1 << OMAP_TLL_CHANNEL_CONF_CHANMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

#if 0
		/* Enable port 3 only. Not enabling ports 1 & 2 */
		if (i != 2)
			continue;
#endif

#if defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT1) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT2) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT3)
		/* FSLSMODE: 4-pin bidirectional PHY */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			(3 << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));
#endif

#if defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT1) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT2) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT3)

		/* FSLSMODE: 3-pin bidirectional PHY */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			(2 << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));
#endif

		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			    (1<<OMAP_TLL_CHANNEL_CONF_CHANEN_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

	}
#else
	pr_debug("\nOnly 3-pin PHY mode is implemented");
#endif /* CONFIG_OMAP_OHCI_PHY_MODE_3PIN */
#else
#error "FS-TLL Not implemented"
#endif /* CONFIG_OMAP_OHCI_PHY_MODE */

	hcd->rsrc_start = pdev->resource[0].start;
	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;

	/*
	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err1;
	}
	 */

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "can't ioremap OHCI HCD\n");
		retval = -ENOMEM;
		goto err2;
	}

	/*
	pr_debug("\n\n-->VIRT-OHCI-BASE [0x%x], [0x%x] irq[%d]\n\n",
			hcd->regs, (unsigned int)io_p2v( 0x48064400 ),
			pdev->resource[1].start);
	 */

	ohci = hcd_to_ohci(hcd);
	ohci_hcd_init(ohci);

	ohci_clocks->host_enabled = 1;

	//irq = platform_get_irq(pdev, 0);
	//if (irq < 0) {
	//	retval = -ENXIO;
	//	goto err3;
	//}
	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED);
	if (retval)
		goto err3;

	return 0;
err3:
	iounmap(hcd->regs);
err2:
//	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
//err1:
	usb_put_hcd(hcd);
	clk_disable(ohci_clocks->usbhost_ick_clk);
	clk_put(ohci_clocks->usbhost_ick_clk);
	clk_disable(ohci_clocks->usbhost2_120m_fck_clk);
	clk_put(ohci_clocks->usbhost2_120m_fck_clk);
	clk_disable(ohci_clocks->usbhost1_48m_fck_clk);
	clk_put(ohci_clocks->usbhost1_48m_fck_clk);
	clk_disable(ohci_clocks->usbtll_fck_clk);
	clk_put(ohci_clocks->usbtll_fck_clk);
	clk_disable(ohci_clocks->usbtll_ick_clk);
	clk_put(ohci_clocks->usbtll_ick_clk);
err0:
//	clk_put(usb_dc_ck);
//	clk_put(usb_host_ck);
	return retval;
}
Esempio n. 16
0
static void __init prcm_setup_regs(void)
{
	int i, num_mem_banks;
	struct powerdomain *pwrdm;

	/* Enable autoidle */
	prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD,
			  OMAP2_PRCM_SYSCONFIG_OFFSET);

	/*
	 * Set CORE powerdomain memory banks to retain their contents
	 * during RETENTION
	 */
	num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm);
	for (i = 0; i < num_mem_banks; i++)
		pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);

	/* Set CORE powerdomain's next power state to RETENTION */
	pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);

	/*
	 * Set MPU powerdomain's next power state to RETENTION;
	 * preserve logic state during retention
	 */
	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);

	/* Force-power down DSP, GFX powerdomains */

	pwrdm = clkdm_get_pwrdm(dsp_clkdm);
	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
	omap2_clkdm_sleep(dsp_clkdm);

	pwrdm = clkdm_get_pwrdm(gfx_clkdm);
	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
	omap2_clkdm_sleep(gfx_clkdm);

	/*
	 * Clear clockdomain wakeup dependencies and enable
	 * hardware-supervised idle for all clkdms
	 */
	clkdm_for_each(clkdms_setup, NULL);
	clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);

	/* Enable clock autoidle for all domains */
	cm_write_mod_reg(OMAP24XX_AUTO_CAM_MASK |
			 OMAP24XX_AUTO_MAILBOXES_MASK |
			 OMAP24XX_AUTO_WDT4_MASK |
			 OMAP2420_AUTO_WDT3_MASK |
			 OMAP24XX_AUTO_MSPRO_MASK |
			 OMAP2420_AUTO_MMC_MASK |
			 OMAP24XX_AUTO_FAC_MASK |
			 OMAP2420_AUTO_EAC_MASK |
			 OMAP24XX_AUTO_HDQ_MASK |
			 OMAP24XX_AUTO_UART2_MASK |
			 OMAP24XX_AUTO_UART1_MASK |
			 OMAP24XX_AUTO_I2C2_MASK |
			 OMAP24XX_AUTO_I2C1_MASK |
			 OMAP24XX_AUTO_MCSPI2_MASK |
			 OMAP24XX_AUTO_MCSPI1_MASK |
			 OMAP24XX_AUTO_MCBSP2_MASK |
			 OMAP24XX_AUTO_MCBSP1_MASK |
			 OMAP24XX_AUTO_GPT12_MASK |
			 OMAP24XX_AUTO_GPT11_MASK |
			 OMAP24XX_AUTO_GPT10_MASK |
			 OMAP24XX_AUTO_GPT9_MASK |
			 OMAP24XX_AUTO_GPT8_MASK |
			 OMAP24XX_AUTO_GPT7_MASK |
			 OMAP24XX_AUTO_GPT6_MASK |
			 OMAP24XX_AUTO_GPT5_MASK |
			 OMAP24XX_AUTO_GPT4_MASK |
			 OMAP24XX_AUTO_GPT3_MASK |
			 OMAP24XX_AUTO_GPT2_MASK |
			 OMAP2420_AUTO_VLYNQ_MASK |
			 OMAP24XX_AUTO_DSS_MASK,
			 CORE_MOD, CM_AUTOIDLE1);
	cm_write_mod_reg(OMAP24XX_AUTO_UART3_MASK |
			 OMAP24XX_AUTO_SSI_MASK |
			 OMAP24XX_AUTO_USB_MASK,
			 CORE_MOD, CM_AUTOIDLE2);
	cm_write_mod_reg(OMAP24XX_AUTO_SDRC_MASK |
			 OMAP24XX_AUTO_GPMC_MASK |
			 OMAP24XX_AUTO_SDMA_MASK,
			 CORE_MOD, CM_AUTOIDLE3);
	cm_write_mod_reg(OMAP24XX_AUTO_PKA_MASK |
			 OMAP24XX_AUTO_AES_MASK |
			 OMAP24XX_AUTO_RNG_MASK |
			 OMAP24XX_AUTO_SHA_MASK |
			 OMAP24XX_AUTO_DES_MASK,
			 CORE_MOD, OMAP24XX_CM_AUTOIDLE4);

	cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD,
			 CM_AUTOIDLE);

	/* Put DPLL and both APLLs into autoidle mode */
	cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) |
			 (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
			 (0x03 << OMAP24XX_AUTO_54M_SHIFT),
			 PLL_MOD, CM_AUTOIDLE);

	cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK |
			 OMAP24XX_AUTO_WDT1_MASK |
			 OMAP24XX_AUTO_MPU_WDT_MASK |
			 OMAP24XX_AUTO_GPIOS_MASK |
			 OMAP24XX_AUTO_32KSYNC_MASK |
			 OMAP24XX_AUTO_GPT1_MASK,
			 WKUP_MOD, CM_AUTOIDLE);

	/* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
	 * stabilisation */
	prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
			  OMAP2_PRCM_CLKSSETUP_OFFSET);

	/* Configure automatic voltage transition */
	prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
			  OMAP2_PRCM_VOLTSETUP_OFFSET);
	prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT_MASK |
			  (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) |
			  OMAP24XX_MEMRETCTRL_MASK |
			  (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) |
			  (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT),
			  OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET);

	/* Enable wake-up events */
	prm_write_mod_reg(OMAP24XX_EN_GPIOS_MASK | OMAP24XX_EN_GPT1_MASK,
			  WKUP_MOD, PM_WKEN);
}
Esempio n. 17
0
/* Sets basic clocks based on the specified rate */
static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
{
    u32 cur_rate, done_rate, bypass = 0, tmp;
    struct prcm_config *prcm;
    unsigned long found_speed = 0;
    unsigned long flags;

    if (clk != &virt_prcm_set)
        return -EINVAL;

    for (prcm = rate_table; prcm->mpu_speed; prcm++) {
        if (!(prcm->flags & cpu_mask))
            continue;

        if (prcm->xtal_speed != sys_ck.rate)
            continue;

        if (prcm->mpu_speed <= rate) {
            found_speed = prcm->mpu_speed;
            break;
        }
    }

    if (!found_speed) {
        printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
               rate / 1000000);
        return -EINVAL;
    }

    curr_prcm_set = prcm;
    cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);

    if (prcm->dpll_speed == cur_rate / 2) {
        omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
    } else if (prcm->dpll_speed == cur_rate * 2) {
        omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
    } else if (prcm->dpll_speed != cur_rate) {
        local_irq_save(flags);

        if (prcm->dpll_speed == prcm->xtal_speed)
            bypass = 1;

        if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
            CORE_CLK_SRC_DPLL_X2)
            done_rate = CORE_CLK_SRC_DPLL_X2;
        else
            done_rate = CORE_CLK_SRC_DPLL;

        /* MPU divider */
        cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);

        /* dsp + iva1 div(2420), iva2.1(2430) */
        cm_write_mod_reg(prcm->cm_clksel_dsp,
                 OMAP24XX_DSP_MOD, CM_CLKSEL);

        cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);

        /* Major subsystem dividers */
        tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
        cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD, CM_CLKSEL1);
        if (cpu_is_omap2430())
            cm_write_mod_reg(prcm->cm_clksel_mdm,
                     OMAP2430_MDM_MOD, CM_CLKSEL);

        /* x2 to enter init_mem */
        omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);

        omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
                   bypass);

        omap2_init_memory_params(omap2_dll_force_needed());
        omap2_reprogram_sdrc(done_rate, 0);

        local_irq_restore(flags);
    }
    omap2_dpll_recalc(&dpll_ck);

    return 0;
}
Esempio n. 18
0
/* omap_start_ehc
 *	- Start the TI USBHOST controller
 */
static int omap_start_ehc(struct platform_device *dev, struct usb_hcd *hcd)
{
	u32 uhh_hostconfig_value = 0;
	struct ehci_omap_clock_defs *ehci_clocks;

	dev_dbg(hcd->self.controller, "starting TI EHCI USB Controller\n");

	ehci_clocks = (struct ehci_omap_clock_defs *)(
				((char *)hcd_to_ehci(hcd)) +
					sizeof(struct ehci_hcd));

	/* Start DPLL5 Programming:
	 * Clock Framework is not doing this now:
	 * This will be done in clock framework later
	 */
	/* Enable DPLL 5 : Based on Input of 13Mhz*/
	cm_write_mod_reg((12 << OMAP3430ES2_PERIPH2_DPLL_DIV_SHIFT)|
			(120 << OMAP3430ES2_PERIPH2_DPLL_MULT_SHIFT),
			PLL_MOD, OMAP3430ES2_CM_CLKSEL4);

	cm_write_mod_reg(1 << OMAP3430ES2_DIV_120M_SHIFT,
			PLL_MOD, OMAP3430ES2_CM_CLKSEL5);

	cm_write_mod_reg((7 << OMAP3430ES2_PERIPH2_DPLL_FREQSEL_SHIFT) |
			(7 << OMAP3430ES2_EN_PERIPH2_DPLL_SHIFT),
			PLL_MOD, OMAP3430ES2_CM_CLKEN2);

#if 0 /* initialization stucks here when EHCI built as module */
	while (!(cm_read_mod_reg(PLL_MOD, CM_IDLEST2) &
				OMAP3430ES2_ST_PERIPH2_CLK_MASK))
		dev_dbg(hcd->self.controller,
			"idlest2 = 0x%x\n",
			cm_read_mod_reg(PLL_MOD, CM_IDLEST2));
#endif
	/* End DPLL5 programming */


	/* PRCM settings for USBHOST:
	 * Interface clk un-related to domain transition
	 */
	cm_write_mod_reg(0 << OMAP3430ES2_AUTO_USBHOST_SHIFT,
				OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);

	/* Disable sleep dependency with MPU and IVA */
	cm_write_mod_reg((0 << OMAP3430ES2_EN_MPU_SHIFT) |
				(0 << OMAP3430ES2_EN_IVA2_SHIFT),
				OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);

	/* Disable Automatic transition of clock */
	cm_write_mod_reg(0 << OMAP3430ES2_CLKTRCTRL_USBHOST_SHIFT,
				OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);

	/* Enable Clocks for USBHOST */
	ehci_clocks->usbhost_ick_clk = clk_get(&dev->dev,
						USBHOST_ICKL);
	if (IS_ERR(ehci_clocks->usbhost_ick_clk))
		return PTR_ERR(ehci_clocks->usbhost_ick_clk);
	clk_enable(ehci_clocks->usbhost_ick_clk);


	ehci_clocks->usbhost2_120m_fck_clk = clk_get(&dev->dev,
							USBHOST_120M_FCLK);
	if (IS_ERR(ehci_clocks->usbhost2_120m_fck_clk))
		return PTR_ERR(ehci_clocks->usbhost2_120m_fck_clk);
	clk_enable(ehci_clocks->usbhost2_120m_fck_clk);

	ehci_clocks->usbhost1_48m_fck_clk = clk_get(&dev->dev,
						USBHOST_48M_FCLK);
	if (IS_ERR(ehci_clocks->usbhost1_48m_fck_clk))
		return PTR_ERR(ehci_clocks->usbhost1_48m_fck_clk);
	clk_enable(ehci_clocks->usbhost1_48m_fck_clk);

	/* get phy reset gpio number */
	EXT_PHY_RESET_GPIO_PORT2 = omap3_ehci_phy_reset_gpio;

#ifdef EXTERNAL_PHY_RESET
	/* Refer: ISSUE1 */
#ifdef CONFIG_OMAP3430SDP_750_2083_001
	gpio_request(EXT_PHY_RESET_GPIO_PORT1, "USB1 PHY reset");
	gpio_direction_output(EXT_PHY_RESET_GPIO_PORT1, 0);
	gpio_set_value(EXT_PHY_RESET_GPIO_PORT1, 0);
#endif
	gpio_request(EXT_PHY_RESET_GPIO_PORT2, "USB2 PHY reset");
	gpio_direction_output(EXT_PHY_RESET_GPIO_PORT2, 0);
	gpio_set_value(EXT_PHY_RESET_GPIO_PORT2, 0);
	/* Hold the PHY in RESET for enough time till DIR is high */
	udelay(EXT_PHY_RESET_DELAY);
#endif

	/* Configure TLL for 60Mhz clk for ULPI */
	ehci_clocks->usbtll_fck_clk = clk_get(&dev->dev, USBHOST_TLL_FCLK);
	if (IS_ERR(ehci_clocks->usbtll_fck_clk))
		return PTR_ERR(ehci_clocks->usbtll_fck_clk);
	clk_enable(ehci_clocks->usbtll_fck_clk);

	ehci_clocks->usbtll_ick_clk = clk_get(&dev->dev, USBHOST_TLL_ICKL);
	if (IS_ERR(ehci_clocks->usbtll_ick_clk))
		return PTR_ERR(ehci_clocks->usbtll_ick_clk);
	clk_enable(ehci_clocks->usbtll_ick_clk);

	/* Disable Auto Idle of USBTLL */
	cm_write_mod_reg((0 << OMAP3430ES2_AUTO_USBTLL_SHIFT),
				CORE_MOD, CM_AUTOIDLE3);

	/* Wait for TLL to be Active */
	while ((cm_read_mod_reg(CORE_MOD, OMAP2430_CM_IDLEST3)
			& (1 << OMAP3430ES2_ST_USBTLL_SHIFT)))
		cpu_relax();

	/* perform TLL soft reset, and wait until reset is complete */
	omap_writel(1 << OMAP_USBTLL_SYSCONFIG_SOFTRESET_SHIFT,
			OMAP_USBTLL_SYSCONFIG);
	/* Wait for TLL reset to complete */
	while (!(omap_readl(OMAP_USBTLL_SYSSTATUS)
			& (1 << OMAP_USBTLL_SYSSTATUS_RESETDONE_SHIFT)))
		cpu_relax();

	dev_dbg(hcd->self.controller, "TLL RESET DONE\n");

	/* (1<<3) = no idle mode only for initial debugging */
	omap_writel((1 << OMAP_USBTLL_SYSCONFIG_ENAWAKEUP_SHIFT) |
			(1 << OMAP_USBTLL_SYSCONFIG_SIDLEMODE_SHIFT) |
			(1 << OMAP_USBTLL_SYSCONFIG_CACTIVITY_SHIFT),
			OMAP_USBTLL_SYSCONFIG);


	/* Put UHH in NoIdle/NoStandby mode */
	omap_writel((0 << OMAP_UHH_SYSCONFIG_AUTOIDLE_SHIFT) |
			(1 << OMAP_UHH_SYSCONFIG_ENAWAKEUP_SHIFT) |
			(1 << OMAP_UHH_SYSCONFIG_SIDLEMODE_SHIFT) |
			(1 << OMAP_UHH_SYSCONFIG_CACTIVITY_SHIFT) |
			(1 << OMAP_UHH_SYSCONFIG_MIDLEMODE_SHIFT),
			OMAP_UHH_SYSCONFIG);

	/* Bypass the TLL module for PHY mode operation */
	uhh_hostconfig_value = (1 << OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN_SHIFT) |
			(1 << OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN_SHIFT) |
			(1 << OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN_SHIFT) |
			(0 << OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN_SHIFT);

/* For ES 3, we have per-port control for the ULPI Bypass
 * The ULPI Bypass needs to be set to 0 only if the EHCI PHY Mode
 * is selected for that port.
 * ES 2 does not have per-port control. Hence it is not possible to have
 * EHCI in PHY Mode and OHCI both working at the same time
 */
	if (omap_rev_ge30()) {
#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT1
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P1_ULPI_BYPASS_SHIFT);
#endif
#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT2
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P2_ULPI_BYPASS_SHIFT);
#endif
#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT3
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P3_ULPI_BYPASS_SHIFT);
#endif
	} else {
#if defined(CONFIG_OMAP_EHCI_PHY_MODE_PORT1) || \
	defined(CONFIG_OMAP_EHCI_PHY_MODE_PORT2) || \
	defined(CONFIG_OMAP_EHCI_PHY_MODE_PORT3)
		uhh_hostconfig_value |=
			(0 << OMAP_UHH_HOSTCONFIG_P1_ULPI_BYPASS_SHIFT);
#else
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P1_ULPI_BYPASS_SHIFT);
#endif
	}

	omap_writel(uhh_hostconfig_value, OMAP_UHH_HOSTCONFIG);

	if (omap_rev_le21()) {
		/* Ensure that BYPASS is set */
		while (omap_readl(OMAP_UHH_HOSTCONFIG)
				& (1 << OMAP_UHH_HOSTCONFIG_ULPI_BYPASS_SHIFT))
			cpu_relax();
	}

	dev_dbg(hcd->self.controller, "Entered ULPI PHY MODE: success\n");

#if defined(CONFIG_OMAP_EHCI_TLL_MODE_PORT1) || \
	defined(CONFIG_OMAP_EHCI_TLL_MODE_PORT2) || \
	defined(CONFIG_OMAP_EHCI_TLL_MODE_PORT3)
	/* Enable UTMI mode for all selected TLL channels */
	omap_usb_utmi_init(hcd, 0
#ifdef CONFIG_OMAP_EHCI_TLL_MODE_PORT1
		| OMAP_TLL_CHANNEL_1_EN_MASK
#endif
#ifdef CONFIG_OMAP_EHCI_TLL_MODE_PORT2
		| OMAP_TLL_CHANNEL_2_EN_MASK
#endif
#ifdef CONFIG_OMAP_EHCI_TLL_MODE_PORT3
		| OMAP_TLL_CHANNEL_3_EN_MASK
#endif
		);
#endif

#ifdef EXTERNAL_PHY_RESET
	/* Refer ISSUE1:
	 * Hold the PHY in RESET for enough time till PHY is settled and ready
	 */
	udelay(EXT_PHY_RESET_DELAY);
#ifdef CONFIG_OMAP3430SDP_750_2083_001
	gpio_set_value(EXT_PHY_RESET_GPIO_PORT1, 1);
#endif
	gpio_set_value(EXT_PHY_RESET_GPIO_PORT2, 1);
#endif

#ifdef VBUS_INTERNAL_CHARGEPUMP_HACK
	/* Refer ISSUE2: LINK assumes external charge pump */

	/* use Port1 VBUS to charge externally Port2:
	 *	So for PHY mode operation use Port2 only
	 */
	omap_writel((0xA << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |/* OTG ctrl reg*/
			(2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |/*   Write */
			(1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |/* Port1 */
			(1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |/* Start */
			(0x26),
			EHCI_INSNREG05_ULPI);

	while (!(omap_readl(EHCI_INSNREG05_ULPI)
			& (1<<EHCI_INSNREG05_ULPI_CONTROL_SHIFT)))
		cpu_relax();

#endif

	return 0;
}