static int gplugd_u2o_vbus_status(unsigned base)
{
	int status = VBUS_HIGH;
	u32 tmp;
	tmp = u2o_get(base, U2xOTGSC);
	if (tmp & U2xOTGSC_ID) {
		if (tmp & U2xOTGSC_BSV)
			status = VBUS_HIGH;
		else
			status = VBUS_LOW;
	} else {
		mini_a_plugin = 1;
		status = VBUS_HIGH;
	}

	return status;
}
예제 #2
0
static int aspenite_u2o_vbus_status(unsigned int base)
{
	int otg_stat1, otg_stat2, otg_pen, status = VBUS_LOW;
	unsigned long flags;

	local_irq_save(flags);

#if 0 /* remove the workaroud here */
#ifdef CONFIG_USB_OTG
	/* FIXME on aspenite R0 boards otg stat1/stat2 could not
	 * reflect VBUS status yet, check with U2O itself instead
	 */
	if (u2o_get(base, U2xOTGSC) & U2xOTGSC_BSV)
		status = VBUS_HIGH;
	else
		status = VBUS_LOW;

	return status;
#endif
#endif

	if (gpio_request(gpio_usb_otg_pen, "USB OTG Power Enable")) {
		printk(KERN_ERR "%s Max7312 USB_OTG_PEN GPIO Request"
			" Failed\n", __func__);
        	return -1;
	}

	if (gpio_request(gpio_usb_otg_stat1, "USB OTG VBUS stat1")) {
		printk(KERN_ERR "%s Max7312 USB_OTG_STAT1 GPIO Request"
			" Failed\n", __func__);
		return -1;
	}

	if (gpio_request(gpio_usb_otg_stat2, "USB OTG Power Enable")) {
		printk(KERN_ERR "%s Max7312 USB_OTG_STAT2 GPIO Request"
			" Failed\n", __func__);
		return -1;
	} 

	gpio_direction_input(gpio_usb_otg_pen);
	gpio_direction_input(gpio_usb_otg_stat1);
	gpio_direction_input(gpio_usb_otg_stat2);

	otg_pen = __gpio_get_value(gpio_usb_otg_pen);
	otg_stat1 = __gpio_get_value(gpio_usb_otg_stat1);
	otg_stat2 = __gpio_get_value(gpio_usb_otg_stat2);

	if (otg_pen) {
		status = VBUS_CHARGE;
		if (otg_stat1 && otg_stat2) {
			status |= VBUS_HIGH;
		}
	} else {
		/* workaroud for some aspenite rev1 board that stat1=1
		 * though vbus high, conflict with max3355 spec
		 * if (!otg_stat1 && !otg_stat2) */
		if (!otg_stat2) {
			status = VBUS_HIGH;
		}
	}

	printk(KERN_DEBUG "%s otg_pen %d stat1 %d stat2 %d status %d\n\n",
			__func__, otg_pen, otg_stat1, otg_stat2, status);
	gpio_free(gpio_usb_otg_pen);
	gpio_free(gpio_usb_otg_stat1);
	gpio_free(gpio_usb_otg_stat2);

	local_irq_restore(flags);
	return status;
}
/********************************************************************
 * USB 2.0 OTG controller
 */
int pxa168_usb_phy_init(unsigned base)
{	
	static int init_done;
	int count;

	if (init_done) {
		printk(KERN_DEBUG "re-init phy\n\n");
		/* return; */
	}

	/* enable the pull up */
	if (cpu_is_pxa910_z0()) {
		if (cpu_is_pxa910()) {
			u32 U2H_UTMI_CTRL = 
				(u32)ioremap_nocache(0xc0000004, 4);
			writel(1<<20, U2H_UTMI_CTRL);
		}
	}

	/* Initialize the USB PHY power */
	if (cpu_is_pxa910()) {
		u2o_set(base, UTMI_CTRL, (1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
			| (1<<UTMI_CTRL_PU_REF_SHIFT));
	}

	u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
	u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
	
	/* UTMI_PLL settings */
	u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
		| UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
		| UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
		| UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);

	u2o_set(base, UTMI_PLL, 0xee<<UTMI_PLL_FBDIV_SHIFT
		| 0xb<<UTMI_PLL_REFDIV_SHIFT | 3<<UTMI_PLL_PLLVDD18_SHIFT
		| 3<<UTMI_PLL_PLLVDD12_SHIFT | 3<<UTMI_PLL_PLLCALI12_SHIFT
		| 2<<UTMI_PLL_ICP_SHIFT | 3<<UTMI_PLL_KVCO_SHIFT);

	/* UTMI_TX */
	u2o_clear(base, UTMI_TX, UTMI_TX_TXVDD12_MASK
		| UTMI_TX_CK60_PHSEL_MASK | UTMI_TX_IMPCAL_VTH_MASK);
	u2o_set(base, UTMI_TX, 3<<UTMI_TX_TXVDD12_SHIFT
		| 4<<UTMI_TX_CK60_PHSEL_SHIFT | 5<<UTMI_TX_IMPCAL_VTH_SHIFT);

	/* UTMI_RX */
	u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
		| UTMI_REG_SQ_LENGTH_MASK);
	if (cpu_is_pxa168())
		u2o_set(base, UTMI_RX, 7<<UTMI_RX_SQ_THRESH_SHIFT
			| 2<<UTMI_REG_SQ_LENGTH_SHIFT);
	else
		u2o_set(base, UTMI_RX, 0xa<<UTMI_RX_SQ_THRESH_SHIFT
			| 2<<UTMI_REG_SQ_LENGTH_SHIFT);

	/* UTMI_IVREF */
	if (cpu_is_pxa168())
		/* fixing Microsoft Altair board interface with NEC hub issue -
		 * Set UTMI_IVREF from 0x4a3 to 0x4bf */
		u2o_write(base, UTMI_IVREF, 0x4bf);

	/* calibrate */
	count = 10000;
	while(((u2o_get(base, UTMI_PLL) & PLL_READY)==0) && count--);
	if (count <= 0) printk("%s %d: calibrate timeout, UTMI_PLL %x\n", 
		__func__, __LINE__, u2o_get(base, UTMI_PLL));

	/* toggle VCOCAL_START bit of UTMI_PLL */
	udelay(200);
	u2o_set(base, UTMI_PLL, VCOCAL_START);
	udelay(40);
	u2o_clear(base, UTMI_PLL, VCOCAL_START);

	/* toggle REG_RCAL_START bit of UTMI_TX */
	udelay(200);
	u2o_set(base, UTMI_TX, REG_RCAL_START);
	udelay(40);
	u2o_clear(base, UTMI_TX, REG_RCAL_START);
	udelay(200);

	/* make sure phy is ready */
	count = 1000;
	while(((u2o_get(base, UTMI_PLL) & PLL_READY)==0) && count--);
	if (count <= 0) printk("%s %d: calibrate timeout, UTMI_PLL %x\n", 
		__func__, __LINE__, u2o_get(base, UTMI_PLL));

	if (cpu_is_pxa168()) {
		u2o_set(base, UTMI_RESERVE, 1<<5);
		u2o_write(base, UTMI_OTG_ADDON, 1);  /* Turn on UTMI PHY OTG extension */
	}

	init_done = 1;
	return 0;
}
예제 #4
0
static int usb_phy_init_internal(void __iomem *base)
{
	int loops;

	pr_info("Init usb phy!!!\n");

	/* Initialize the USB PHY power */
	if (cpu_is_pxa910()) {
		u2o_set(base, UTMI_CTRL, (1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
			| (1<<UTMI_CTRL_PU_REF_SHIFT));
	}

	u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
	u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);

	/* UTMI_PLL settings */
	u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
		| UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
		| UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
		| UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);

	u2o_set(base, UTMI_PLL, 0xee<<UTMI_PLL_FBDIV_SHIFT
		| 0xb<<UTMI_PLL_REFDIV_SHIFT | 3<<UTMI_PLL_PLLVDD18_SHIFT
		| 3<<UTMI_PLL_PLLVDD12_SHIFT | 3<<UTMI_PLL_PLLCALI12_SHIFT
		| 1<<UTMI_PLL_ICP_SHIFT | 3<<UTMI_PLL_KVCO_SHIFT);

	/* UTMI_TX */
	u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
		| UTMI_TX_TXVDD12_MASK | UTMI_TX_CK60_PHSEL_MASK
		| UTMI_TX_IMPCAL_VTH_MASK | UTMI_TX_REG_EXT_FS_RCAL_MASK
		| UTMI_TX_AMP_MASK);
	u2o_set(base, UTMI_TX, 3<<UTMI_TX_TXVDD12_SHIFT
		| 4<<UTMI_TX_CK60_PHSEL_SHIFT | 4<<UTMI_TX_IMPCAL_VTH_SHIFT
		| 8<<UTMI_TX_REG_EXT_FS_RCAL_SHIFT | 3<<UTMI_TX_AMP_SHIFT);

	/* UTMI_RX */
	u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
		| UTMI_REG_SQ_LENGTH_MASK);
	u2o_set(base, UTMI_RX, 7<<UTMI_RX_SQ_THRESH_SHIFT
		| 2<<UTMI_REG_SQ_LENGTH_SHIFT);

	/* UTMI_IVREF */
	if (cpu_is_pxa168())
		/* fixing Microsoft Altair board interface with NEC hub issue -
		 * Set UTMI_IVREF from 0x4a3 to 0x4bf */
		u2o_write(base, UTMI_IVREF, 0x4bf);

	/* toggle VCOCAL_START bit of UTMI_PLL */
	udelay(200);
	u2o_set(base, UTMI_PLL, VCOCAL_START);
	udelay(40);
	u2o_clear(base, UTMI_PLL, VCOCAL_START);

	/* toggle REG_RCAL_START bit of UTMI_TX */
	udelay(400);
	u2o_set(base, UTMI_TX, REG_RCAL_START);
	udelay(40);
	u2o_clear(base, UTMI_TX, REG_RCAL_START);
	udelay(400);

	/* Make sure PHY PLL is ready */
	loops = 0;
	while ((u2o_get(base, UTMI_PLL) & PLL_READY) == 0) {
		mdelay(1);
		loops++;
		if (loops > 100) {
			printk(KERN_WARNING "calibrate timeout, UTMI_PLL %x\n",
				u2o_get(base, UTMI_PLL));
			break;
		}
	}

	if (cpu_is_pxa168()) {
		u2o_set(base, UTMI_RESERVE, 1 << 5);
		/* Turn on UTMI PHY OTG extension */
		u2o_write(base, UTMI_OTG_ADDON, 1);
	}

	return 0;
}
예제 #5
0
static int usb_phy_init_internal(void __iomem *base)
{
	int loops = 0;
	u32 temp;

	pr_info("Init usb phy!!!\n");

	temp = __raw_readl(APMU_REG(0x100));
	temp &= ~0xF00;
	temp |= 0xd00;
	__raw_writel(temp, APMU_REG(0x100));

	udelay(100);

	u2o_clear(base, USB2_PLL_REG0,
		USB2_PLL_REFDIV_MASK_MMP3_B0
		| USB2_PLL_FBDIV_MASK_MMP3_B0);

	u2o_set(base, USB2_PLL_REG0,
		0xd << USB2_PLL_REFDIV_SHIFT_MMP3_B0
		| 0xf0 << USB2_PLL_FBDIV_SHIFT_MMP3_B0);


	/* USB2_PLL_REG1 = 0x3333 */
	u2o_clear(base, USB2_PLL_REG1, USB2_PLL_PU_PLL_MASK
		| USB2_PLL_ICP_MASK_MMP3
		| USB2_PLL_KVCO_MASK_MMP3
		| USB2_PLL_CALI12_MASK_MMP3);
	u2o_set(base, USB2_PLL_REG1, 1 << USB2_PLL_PU_PLL_SHIFT_MMP3
		| 1 << USB2_PLL_LOCK_BYPASS_SHIFT_MMP3
		| 3 << USB2_PLL_ICP_SHIFT_MMP3
		| 3 << USB2_PLL_KVCO_SHIFT_MMP3
		| 3 << USB2_PLL_CAL12_SHIFT_MMP3);

	/* USB2_TX_REG0 = 0x288 */
	u2o_clear(base, USB2_TX_REG0, USB2_TX_IMPCAL_VTH_MASK_MMP3);
	u2o_set(base, USB2_TX_REG0, 2 << USB2_TX_IMPCAL_VTH_SHIFT_MMP3);

	/* USB2_TX_REG1 = 0x7c4 */
	u2o_clear(base, USB2_TX_REG1, USB2_TX_VDD12_MASK_MMP3
		| USB2_TX_AMP_MASK_MMP3
		| USB2_TX_CK60_PHSEL_MASK_MMP3);
	u2o_set(base, USB2_TX_REG1, 3 << USB2_TX_VDD12_SHIFT_MMP3
		| 4 << USB2_TX_AMP_SHIFT_MMP3
		| 4 << USB2_TX_CK60_PHSEL_SHIFT_MMP3);

	/* USB2_TX_REG2 = 0xaff */
	u2o_clear(base, USB2_TX_REG2, 3 << USB2_TX_DRV_SLEWRATE_SHIFT);
	u2o_set(base, USB2_TX_REG2, 2 << USB2_TX_DRV_SLEWRATE_SHIFT);

	/* USB2_RX_REG0 =  0xaaa1 */
	u2o_clear(base, USB2_RX_REG0, USB2_RX_SQ_THRESH_MASK_MMP3);
	u2o_set(base, USB2_RX_REG0, 0xa << USB2_RX_SQ_THRESH_SHIFT_MMP3);

	/* USB2_ANA_REG1 =  0x5680 */
	u2o_set(base, USB2_ANA_REG1, 0x1 << USB2_ANA_PU_ANA_SHIFT_MMP3);

	/* USB2_OTG_REG0 =  0x8 */
	u2o_set(base, USB2_OTG_REG0, 0x1 << USB2_OTG_PU_OTG_SHIFT_MMP3);

	/* PLL Power up has been done in usb2CIEnableAppSubSysClocks routine
	*  PLL VCO and TX Impedance Calibration Timing for Eshel & MMP3
	*		   _____________________________________
	*  PU   __________|
	*			   ____________________________
	*  VCOCAL START	__________|
	*				  ___
	*  REG_RCAL_START________________|   |________|_________
	*		  | 200us |400us |40 | 400us  | USB PHY READY
	* ------------------------------------------------------------------
	*/
	/* Calibrate PHY */
	udelay(200);
	u2o_set(base, USB2_PLL_REG1, 1 << USB2_PLL_VCOCAL_START_SHIFT_MMP3);
	udelay(400);
	u2o_set(base, USB2_TX_REG0, 1 << USB2_TX_RCAL_START_SHIFT_MMP3);
	udelay(40);
	u2o_clear(base, USB2_TX_REG0, 1 << USB2_TX_RCAL_START_SHIFT_MMP3);
	udelay(400);

	/* Make sure PHY PLL is ready */
	loops = 0;
	while ((u2o_get(base, USB2_PLL_REG1) & USB2_PLL_READY_MASK_MMP3) == 0) {
		mdelay(1);
		loops++;
		if (loops > 100) {
			pr_warn("PLL_READY not set after 100mS.");
			break;
		}
	}

	return 0;
}