Пример #1
0
static inline void __init sdp3430_init_smc91x(void)
{
	int eth_cs;
	unsigned long cs_mem_base;
	int eth_gpio = 0;

	eth_cs = SDP3430_SMC91X_CS;

	if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
		printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
		return;
	}

	sdp3430_smc91x_resources[0].start = cs_mem_base + 0x0;
	sdp3430_smc91x_resources[0].end   = cs_mem_base + 0xf;
	udelay(100);

	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0))
		eth_gpio = OMAP34XX_ETHR_GPIO_IRQ_SDPV2;
	else
		eth_gpio = OMAP34XX_ETHR_GPIO_IRQ_SDPV1;

	sdp3430_smc91x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);

	if (omap_request_gpio(eth_gpio) < 0) {
		printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
			eth_gpio);
		return;
	}
	omap_set_gpio_direction(eth_gpio, 1);
}
Пример #2
0
static void __init omap_3430sdp_init(void)
{
	platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices));
	omap_board_config = sdp3430_config;
	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0))
		ts_gpio = OMAP34XX_TS_GPIO_IRQ_SDPV2;
	else
		ts_gpio = OMAP34XX_TS_GPIO_IRQ_SDPV1;
	sdp3430_spi_board_info[0].irq = OMAP_GPIO_IRQ(ts_gpio);
	spi_register_board_info(sdp3430_spi_board_info,
				ARRAY_SIZE(sdp3430_spi_board_info));
	ads7846_dev_init();
	sdp3430_flash_init();
	omap_serial_init();
	sdp3430_usb_init();
	sdp_mmc_init();
}
Пример #3
0
static int omap3_enter_idle(struct cpuidle_device *dev,
			struct cpuidle_state *state)
{
	struct omap3_processor_cx *cx;
	u8 cur_per_state, cur_neon_state, pre_neon_state, pre_per_state;
	struct timespec ts_preidle, ts_postidle, ts_idle;
	u32 fclken_core, iclken_core, fclken_per, iclken_per;
	u32 sdrcpwr_val, sdrc_power_register = 0x0;
	int wakeup_latency;
	int core_sleep_flg = 0;
	u32 per_ctx_saved = 0;
	int ret = -1;
#ifdef CONFIG_ENABLE_SWLATENCY_MEASURE
	int idle_status = 0;
#endif

	local_irq_disable();
	local_fiq_disable();

	if (need_resched()) {
		local_irq_enable();
		local_fiq_enable();
		return 0;
	}

#ifdef CONFIG_ENABLE_SWLATENCY_MEASURE
	sw_latency_arr[swlat_arr_wrptr].sleep_start =
				 omap_32k_sync_timer_read();
#endif
	PM_PREPWSTST_MPU = 0xFF;
	PM_PREPWSTST_CORE = 0xFF;
	PM_PREPWSTST_NEON = 0xFF;
	PM_PREPWSTST_PER = 0xFF;

	cx = cpuidle_get_statedata(state);

	target_state.mpu_state = cx->mpu_state;
	target_state.core_state = cx->core_state;

	/* take a time marker for residency */
	getnstimeofday(&ts_preidle);

	if (cx->type == OMAP3_STATE_C0) {
		omap_sram_idle();
		goto return_sleep_time;
	}

	if (cx->type > OMAP3_STATE_C1)
		sched_clock_idle_sleep_event(); /* about to enter deep idle */

	correct_target_state();
	wakeup_latency = cx->wakeup_latency;
	if (target_state.core_state != cx->core_state) {
		/* Currently, this can happen only for core_off */
		/* Adjust wakeup latency to that of core_cswr state */
		/* Hard coded now and needs to be made more generic */
		/* omap3_power_states[4] is CSWR for core */
		wakeup_latency = omap3_power_states[4].wakeup_latency;
	}

	/* Reprogram next wake up tick to adjust for wake latency */
	if (wakeup_latency > 1000) {
		struct tick_device *d = tick_get_device(smp_processor_id());
		ktime_t adjust, next, now = ktime_get();
		if (ktime_to_ns(ktime_sub(d->evtdev->next_event, now)) >
			(wakeup_latency * 1000 + NSEC_PER_MSEC)) {
			adjust = ktime_set(0, (wakeup_latency * 1000));
			next = ktime_sub(d->evtdev->next_event, adjust);
			clockevents_program_event(d->evtdev, next, now);
		}
	}

	/* Check for pending interrupts. If there is an interrupt, return */
	if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2)
		goto return_sleep_time;

	prcm_get_power_domain_state(DOM_PER, &cur_per_state);
	prcm_get_power_domain_state(DOM_NEON, &cur_neon_state);

	fclken_core = CM_FCLKEN1_CORE;
	iclken_core = CM_ICLKEN1_CORE;
	fclken_per = CM_FCLKEN_PER;
	iclken_per = CM_ICLKEN_PER;

	/* If target state if core_off, save registers
	 * before changing anything
	 */
	if (target_state.core_state >= PRCM_CORE_OSWR_MEMRET) {
		prcm_save_registers(&target_state);
		omap_uart_save_ctx(0);
		omap_uart_save_ctx(1);
	}

	/* Check for pending interrupts. If there is an interrupt, return */
	if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2)
		goto return_sleep_time;

	/* Program MPU and NEON to target state */
	if (target_state.mpu_state > PRCM_MPU_ACTIVE) {
		if ((cur_neon_state == PRCM_ON) &&
			(target_state.neon_state != PRCM_ON)) {

		if (target_state.neon_state == PRCM_OFF)
			omap3_save_neon_context();

#ifdef CONFIG_HW_SUP_TRANS
		/* Facilitating SWSUP RET, from HWSUP mode */
			prcm_set_clock_domain_state(DOM_NEON,
					PRCM_NO_AUTO, PRCM_FALSE);
			prcm_set_power_domain_state(DOM_NEON, PRCM_ON,
						PRCM_FORCE);
#endif
			prcm_force_power_domain_state(DOM_NEON,
				target_state.neon_state);
		}
#ifdef CONFIG_MPU_OFF
		/* Populate scrathpad restore address */
		*(scratchpad_restore_addr) = restore_pointer_address;
#endif
		if (target_state.core_state > PRCM_CORE_CSWR_MEMRET) {
			ret = omap3_save_secure_ram_context(
						target_state.core_state);
			if (ret)
				printk(KERN_ERR "omap3_save_secure_ram_context"
						"failed in idle %x\n", ret);
			if (core_off_notification != NULL)
				core_off_notification(PRCM_TRUE);
		}
		prcm_set_mpu_domain_state(target_state.mpu_state);
	}

	/* Check for pending interrupts. If there is an interrupt, return */
	if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2)
		goto restore;

	/* Program CORE and PER to target state */
	if (target_state.core_state > PRCM_CORE_ACTIVE) {
		/* Log core sleep attmept */
		core_sleep_flg = 1;


#ifdef CONFIG_OMAP_SMARTREFLEX
		disable_smartreflex(SR1_ID);
		disable_smartreflex(SR2_ID);
#endif
		/* Workaround for Silicon Errata 1.64 */
		if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) {
			if (CM_CLKOUT_CTRL & 0x80)
				CM_CLKOUT_CTRL &= ~(0x80);
		}

		prcm_set_core_domain_state(target_state.core_state);
		/* Enable Autoidle for GPT1 explicitly - Errata 1.4 */
		CM_AUTOIDLE_WKUP |= 0x1;
		/* Disable UART-1,2 */
		CM_FCLKEN1_CORE &= ~0x6000;
		/* Disable HSUSB OTG ICLK explicitly*/
		CM_ICLKEN1_CORE &= ~0x10;
		/* Enabling IO_PAD capabilities */
		PM_WKEN_WKUP |= 0x100;
		if (cur_per_state == PRCM_ON && cx->type >= OMAP3_STATE_C3 &&
					!(CM_FCLKEN_PER & PER_FCLK_MASK)) {
			/* In ES3.1, Enable IO Daisy chain */
			if (is_sil_rev_greater_than(OMAP3430_REV_ES3_0)) {
				PM_WKEN_WKUP |= 0x10000;
				/* Wait for daisy chain to be ready */
				while ((PM_WKST_WKUP & 0x10000) == 0x0)
					;
				/* clear the status */
				PM_WKST_WKUP &= ~0x10000;
			}
			omap3_save_per_context();
			prcm_set_power_domain_state(DOM_PER, PRCM_OFF,
							 PRCM_AUTO);
			per_ctx_saved = 1;
			CM_FCLKEN_PER = 0;
			CM_ICLKEN_PER = 0;
		}
	}

	/* Check for pending interrupts. If there is an interrupt, return */
	if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2)
		goto restore;

	if (target_state.core_state == PRCM_CORE_OFF) {
		if (!is_device_type_gp() &&
				is_sil_rev_greater_than(OMAP3430_REV_ES2_1)) {

			/* es3 series bug */
			sdrc_power_register = sdrc_read_reg(SDRC_POWER);
			sdrcpwr_val = sdrc_power_register &
						~(SDRC_PWR_AUTOCOUNT_MASK |
						SDRC_PWR_CLKCTRL_MASK);
			lock_scratchpad_sem();
			sdrcpwr_val |= 0x120;
			save_to_scratchpad(SCRATHPAD_SDRCPWR_OFFSET,
							sdrcpwr_val);
			unlock_scratchpad_sem();
		}
	}

#ifdef CONFIG_ENABLE_SWLATENCY_MEASURE
	sw_latency_arr[swlat_arr_wrptr].sleep_end = omap_32k_sync_timer_read();
	idle_status++;
#endif
	omap_sram_idle();

	if (target_state.core_state == PRCM_CORE_OFF) {
		if (!is_device_type_gp() &&
				is_sil_rev_greater_than(OMAP3430_REV_ES2_1))
		sdrc_write_reg(sdrc_power_register, SDRC_POWER);
	}

restore:
	/* In case of ES3.1, disable IO daisy chain */
	if (is_sil_rev_greater_than(OMAP3430_REV_ES3_0) && per_ctx_saved)
		PM_WKEN_WKUP &= ~(0x10000);

	/* Disabling IO_PAD capabilities */
	if (core_sleep_flg)
		PM_WKEN_WKUP &= ~(0x100);

	/* Disabling IO_PAD capabilities */
	PM_WKEN_WKUP &= ~(0x100);
#ifdef OMAP3_START_RNG
	/*Capture the PM_PREPWSTST_CORE to be used later
	* for starting the RNG (Random Number Generator)*/
	prepwst_core_rng = PM_PREPWSTST_CORE;
#endif

	CM_FCLKEN1_CORE = fclken_core;
	CM_ICLKEN1_CORE = iclken_core;

	if (target_state.mpu_state > PRCM_MPU_ACTIVE) {
#ifdef CONFIG_MPU_OFF
		/* On ES 2.0, if scrathpad is populated with valid
		* pointer, warm reset does not work
		* So populate scrathpad restore address only in
		* cpuidle and suspend calls
		*/
		*(scratchpad_restore_addr) = 0x0;
#endif
		prcm_set_mpu_domain_state(PRCM_MPU_ACTIVE);
		if ((cur_neon_state == PRCM_ON) &&
			(target_state.mpu_state > PRCM_MPU_INACTIVE)) {
			prcm_force_power_domain_state(DOM_NEON, cur_neon_state);
			prcm_get_pre_power_domain_state(DOM_NEON,
				&pre_neon_state);

		if (pre_neon_state == PRCM_OFF)
			omap3_restore_neon_context();

#ifdef CONFIG_HW_SUP_TRANS
			prcm_set_power_domain_state(DOM_NEON, PRCM_ON,
							PRCM_AUTO);
#endif
		}
	}

	/* Continue core restoration part, only if Core-Sleep is attempted */
	if ((target_state.core_state > PRCM_CORE_ACTIVE) && core_sleep_flg) {
		prcm_set_core_domain_state(PRCM_CORE_ACTIVE);

#ifdef CONFIG_OMAP_SMARTREFLEX
		enable_smartreflex(SR1_ID);
		enable_smartreflex(SR2_ID);
#endif

		if (target_state.core_state >= PRCM_CORE_OSWR_MEMRET) {
#ifdef CONFIG_OMAP34XX_OFFMODE
			context_restore_update(DOM_CORE1);
#endif
			prcm_restore_registers(&target_state);
			prcm_restore_core_context(target_state.core_state);
			omap3_restore_core_settings();
			}
		/* Errata 1.4
		* if the timer device gets idled which is when we
		* are cutting the timer ICLK which is when we try
		* to put Core to RET.
		* Wait Period = 2 timer interface clock cycles +
		* 1 timer functional clock cycle
		* Interface clock = L4 clock. For the computation L4
		* clock is assumed at 50MHz (worst case).
		* Functional clock = 32KHz
		* Wait Period = 2*10^-6/50 + 1/32768 = 0.000030557 = 30.557uSec
		* Roundingoff the delay value to a safer 50uSec
		*/
		omap_udelay(GPTIMER_WAIT_DELAY);
		CM_AUTOIDLE_WKUP &= ~(0x1);
		if (core_off_notification != NULL)
			core_off_notification(PRCM_FALSE);
	}

	if (cur_per_state == PRCM_ON) {
		CM_FCLKEN_PER = fclken_per;
		CM_ICLKEN_PER = iclken_per;
		prcm_get_pre_power_domain_state(DOM_PER, &pre_per_state);
		if (pre_per_state == PRCM_OFF && per_ctx_saved) {
			if (enable_debug)
				per_off++;
			omap3_restore_per_context();
			post_uart_inactivity();
#ifdef CONFIG_OMAP34XX_OFFMODE
			context_restore_update(DOM_PER);
#endif
		}
	}

	pr_debug("MPU state:%x,CORE state:%x\n", PM_PREPWSTST_MPU,
							PM_PREPWSTST_CORE);
	store_prepwst();

return_sleep_time:
	getnstimeofday(&ts_postidle);
	ts_idle = timespec_sub(ts_postidle, ts_preidle);

	if (cx->type > OMAP3_STATE_C1)
		sched_clock_idle_wakeup_event(timespec_to_ns(&ts_idle));

#ifdef CONFIG_ENABLE_SWLATENCY_MEASURE
	if (idle_status) {
		sw_latency_arr[swlat_arr_wrptr].wkup_end =
					omap_32k_sync_timer_read();
		sw_latency_arr[swlat_arr_wrptr].wkup_start =
					wakeup_start_32ksync;

		sw_latency_arr[swlat_arr_wrptr].cstate =
			((PM_PREPWSTST_MPU & 0x3) << 2) |
			 (PM_PREPWSTST_CORE & 0x3) |
			 (omap_readl(0x48306CB0) << 16);

		swlat_arr_wrptr++;

		if (swlat_arr_wrptr == SW_LATENCY_ARR_SIZE)
			swlat_arr_wrptr = 0;
	}
#endif

	local_irq_enable();
	local_fiq_enable();

#ifdef OMAP3_START_RNG
	if (!is_device_type_gp()) {
		/*Start RNG after interrupts are enabled
		 * and only when CORE OFF was successful
		 */
		if (!(prepwst_core_rng & 0x3)) {
			ret = omap3_start_rng();
			if (ret)
				printk(KERN_INFO"Failed to generate new"
						" RN in idle %x\n", ret);
			prepwst_core_rng = 0xFF;
		}
	}
#endif

	return (u32)timespec_to_ns(&ts_idle)/1000;
}
Пример #4
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;
}
Пример #5
0
static int hsmmc_set_power(struct device *dev, int slot, int power_on,
				int vdd)
{
	u32 vdd_sel = 0, devconf = 0, reg = 0;
	int ret = 0;

	/* REVISIT: Using address directly till the control.h defines
	 * are settled.
	 */
#if defined(CONFIG_ARCH_OMAP2430)
	#define OMAP2_CONTROL_PBIAS 0x490024A0
#else
	#define OMAP2_CONTROL_PBIAS 0x48002520
#endif

	if (power_on) {
		if (cpu_is_omap24xx())
			devconf = omap_readl(OMAP2_CONTROL_DEVCONF1);
		else
			devconf = omap_readl(OMAP3_CONTROL_DEVCONF0);

		switch (1 << vdd) {
		case MMC_VDD_33_34:
		case MMC_VDD_32_33:
			vdd_sel = VSEL_3V;
			if (cpu_is_omap24xx())
				devconf |= OMAP2_CONTROL_DEVCONF1_ACTOV;
			break;
		case MMC_VDD_165_195:
			vdd_sel = VSEL_18V;
			if (cpu_is_omap24xx())
				devconf &= ~OMAP2_CONTROL_DEVCONF1_ACTOV;
		}

		if (cpu_is_omap24xx())
			omap_writel(devconf, OMAP2_CONTROL_DEVCONF1);
		else
			omap_writel(devconf | OMAP2_CONTROL_DEVCONF0_LBCLK,
				    OMAP3_CONTROL_DEVCONF0);

		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg |= OMAP2_CONTROL_PBIAS_SCTRL;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg |= OMAP2_CONTROL_PBIAS_SCTRL1;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ1;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		ret = resource_request(rhandlemmc1, (vdd_sel == VSEL_3V ?
			T2_VMMC1_3V00 : T2_VMMC1_1V85));
		if (ret != 0)
			goto err;

		/* Enable VSIM to support MMC 8-bit on ES2 */
		if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
			ret = resource_request(rhandlevsim,
				(vdd_sel == VSEL_3V ?
				T2_VSIM_3V00 : T2_VSIM_1V80));
			if (ret != 0)
				return ret;
		}
		msleep(100);
		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg = (vdd_sel == VSEL_18V) ?
			(((reg | 0x0606) & ~0x1) & ~(1<<8))
			: (reg | 0x0707);
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		return ret;

	} else {
		/* Power OFF */

		/* For MMC1, Toggle PBIAS before every power up sequence */
		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		if (rhandlemmc1 != NULL) {
			ret = resource_release(rhandlemmc1);
			if (ret != 0)
				goto err;
		}

		if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)
					 && (rhandlevsim != NULL)) {
			ret = resource_release(rhandlevsim);
			if (ret != 0)
				goto err;
		}

		if (is_sil_rev_equal_to(OMAP3430_REV_ES3_0)) {
			ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
				LDO_CLR, VSIM_DEV_GRP);
			if (ret)
				goto err;
			ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
				LDO_CLR, VSIM_DEDICATED);
			if (ret)
				goto err;
		}

		/* 100ms delay required for PBIAS configuration */
		msleep(100);
		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg |= (OMAP2_CONTROL_PBIAS_VMODE |
			OMAP2_CONTROL_PBIAS_VMODE1 |
			OMAP2_CONTROL_PBIAS_PWRDNZ |
			OMAP2_CONTROL_PBIAS_PWRDNZ1 |
			OMAP2_CONTROL_PBIAS_SCTRL |
			OMAP2_CONTROL_PBIAS_SCTRL1);
		omap_writel(reg, OMAP2_CONTROL_PBIAS);
	}

	return 0;

err:
	return 1;
}