mirror of
https://github.com/genesi/linux-legacy.git
synced 2026-09-20 21:54:23 +00:00
ENGR00125251 usb_gadget: should not read PORT Reset at reset_irq
1. At reset_irq, the status of port reset is unsure, maybe the reset process(hardware does it) is finished, and the status of port reset is also cleared by usb controller. So it only needs to compare to USBSTS at usb irq process. 2. Due to mx35/mx25 phy's bug, it needs to reset phy when re-open usb clock next time(Begin to use usb next time) 3. mdelay 100 seconds is too long for resume process, as this code is only added for mx37, add arch macro for this mdelay. This can minimize the effect for other platforms. 4. Compile is ok for all imx platform, functional tests are finished for mx35 and mx23. Signed-off-by: Peter Chen <peter.chen@freescale.com>
This commit is contained in:
@@ -177,6 +177,25 @@ static inline void dump_ep_queue(struct fsl_ep *ep)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined CONFIG_ARCH_MX35 || defined CONFIG_ARCH_MX25)
|
||||
/*
|
||||
* The Phy at MX35 and MX25 have bugs, it must disable, and re-eable phy
|
||||
* if the phy clock is disabled before
|
||||
*/
|
||||
static void reset_phy(void)
|
||||
{
|
||||
u32 phyctrl;
|
||||
phyctrl = fsl_readl(&dr_regs->phyctrl1);
|
||||
phyctrl &= ~PHY_CTRL0_USBEN;
|
||||
fsl_writel(phyctrl, &dr_regs->phyctrl1);
|
||||
|
||||
phyctrl = fsl_readl(&dr_regs->phyctrl1);
|
||||
phyctrl |= PHY_CTRL0_USBEN;
|
||||
fsl_writel(phyctrl, &dr_regs->phyctrl1);
|
||||
}
|
||||
#else
|
||||
static void reset_phy(void){; }
|
||||
#endif
|
||||
/*-----------------------------------------------------------------
|
||||
* done() - retire a request; caller blocked irqs
|
||||
* @status : request status to be set, only works when
|
||||
@@ -300,6 +319,8 @@ static void dr_phy_low_power_mode(struct fsl_udc *udc, bool enable)
|
||||
if (udc_controller->pdata->usb_clock_for_pm)
|
||||
udc_controller->pdata->usb_clock_for_pm(true);
|
||||
|
||||
/* Due to mx35/mx25's phy's bug */
|
||||
reset_phy();
|
||||
temp = fsl_readl(&dr_regs->portsc1);
|
||||
temp &= ~PORTSCX_PHY_LOW_POWER_SPD;
|
||||
fsl_writel(temp, &dr_regs->portsc1);
|
||||
@@ -445,12 +466,14 @@ static void dr_controller_run(struct fsl_udc *udc)
|
||||
dr_phy_low_power_mode(udc, true);
|
||||
printk(KERN_INFO "udc enter low power mode \n");
|
||||
} else {
|
||||
#ifdef CONFIG_ARCH_MX37
|
||||
/*
|
||||
add some delay for USB timing issue. USB may be
|
||||
recognize as FS device
|
||||
during USB gadget remote wake up function
|
||||
*/
|
||||
mdelay(100);
|
||||
#endif
|
||||
/* Clear stopped bit */
|
||||
udc->stopped = 0;
|
||||
/* Set controller to Run */
|
||||
@@ -2018,29 +2041,12 @@ static void reset_irq(struct fsl_udc *udc)
|
||||
/* Write 1s to the flush register */
|
||||
fsl_writel(0xffffffff, &dr_regs->endptflush);
|
||||
|
||||
if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) {
|
||||
VDBG("Bus reset");
|
||||
/* Bus is reseting */
|
||||
udc->bus_reset = 1;
|
||||
/* Reset all the queues, include XD, dTD, EP queue
|
||||
* head and TR Queue */
|
||||
reset_queues(udc);
|
||||
udc->usb_state = USB_STATE_DEFAULT;
|
||||
} else {
|
||||
VDBG("Controller reset");
|
||||
/* initialize usb hw reg except for regs for EP, not
|
||||
* touch usbintr reg */
|
||||
dr_controller_setup(udc);
|
||||
|
||||
/* Reset all internal used Queues */
|
||||
reset_queues(udc);
|
||||
|
||||
ep0_setup(udc);
|
||||
|
||||
/* Enable DR IRQ reg, Set Run bit, change udc state */
|
||||
dr_controller_run(udc);
|
||||
udc->usb_state = USB_STATE_ATTACHED;
|
||||
}
|
||||
/* Bus is reseting */
|
||||
udc->bus_reset = 1;
|
||||
/* Reset all the queues, include XD, dTD, EP queue
|
||||
* head and TR Queue */
|
||||
reset_queues(udc);
|
||||
udc->usb_state = USB_STATE_DEFAULT;
|
||||
}
|
||||
|
||||
/* if wakup udc, return true; else return false*/
|
||||
@@ -2702,7 +2708,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
||||
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
|
||||
int ret = -ENODEV;
|
||||
unsigned int i;
|
||||
u32 dccparams, portsc;
|
||||
u32 dccparams;
|
||||
|
||||
udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
|
||||
if (udc_controller == NULL) {
|
||||
@@ -2758,6 +2764,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
||||
goto err2a;
|
||||
}
|
||||
|
||||
/* Due to mx35/mx25's phy's bug */
|
||||
reset_phy();
|
||||
|
||||
if (pdata->have_sysif_regs)
|
||||
usb_sys_regs = (struct usb_sys_interface *)
|
||||
((u32)dr_regs + USB_DR_SYS_OFFSET);
|
||||
@@ -2871,10 +2880,14 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
||||
dr_wake_up_enable(udc_controller, false);
|
||||
udc_controller->stopped = 1;
|
||||
|
||||
#if !(defined CONFIG_ARCH_MX35 || defined CONFIG_ARCH_MX25)
|
||||
{
|
||||
u32 portsc;
|
||||
portsc = fsl_readl(&dr_regs->portsc1);
|
||||
portsc |= PORTSCX_PHY_LOW_POWER_SPD;
|
||||
fsl_writel(portsc, &dr_regs->portsc1);
|
||||
|
||||
}
|
||||
#endif
|
||||
if (udc_controller->pdata->usb_clock_for_pm)
|
||||
udc_controller->pdata->usb_clock_for_pm(false);
|
||||
#endif
|
||||
|
||||
@@ -365,6 +365,7 @@ struct usb_sys_interface {
|
||||
|
||||
/* PHY control0 Register Bit Masks */
|
||||
#define PHY_CTRL0_CONF2 (1 << 26)
|
||||
#define PHY_CTRL0_USBEN (1 << 24) /* USB UTMI PHY Enable */
|
||||
|
||||
/* USB UH2 CTRL Register Bits */
|
||||
#define USB_UH2_OVBWK_EN (1 << 6) /* OTG VBUS Wakeup Enable */
|
||||
|
||||
Reference in New Issue
Block a user