Skip to content
Snippets Groups Projects
Commit 0247a7bc authored by Fabio Estevam's avatar Fabio Estevam Committed by Greg Kroah-Hartman
Browse files

USB: ehci-mxc: Setup portsc register prior to accessing OTG viewport


In order to read/write to the i.MX OTG viewport register it is necessary to setup
the PORTSCx register first.

By default i.MX OTG port is configured for USB serial PHY. In order to use a ULPI PHY
the PORTSCx register needs to be configured properly.

commit 724c8525 (USB: ehci/mxc: compile fix) placed the PORTSC setup after the OTG
viewport is accessed and this causes ULPI read/write to fail.

Revert the PORTSC setup order.

Tested on a MX31PDK board with a ISP1504 transceiver:

ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
mxc-ehci mxc-ehci.0: initializing i.MX USB Controller
ULPI transceiver vendor/product ID 0x04cc/0x1504
Found NXP ISP1504 ULPI transceiver.
ULPI integrity check: passed.

Signed-off-by: default avatarFabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 2c8245c4
No related branches found
No related tags found
No related merge requests found
...@@ -36,14 +36,8 @@ struct ehci_mxc_priv { ...@@ -36,14 +36,8 @@ struct ehci_mxc_priv {
static int ehci_mxc_setup(struct usb_hcd *hcd) static int ehci_mxc_setup(struct usb_hcd *hcd)
{ {
struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct device *dev = hcd->self.controller;
struct mxc_usbh_platform_data *pdata = dev_get_platdata(dev);
int retval; int retval;
/* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100;
ehci->regs = hcd->regs + 0x100 +
HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
dbg_hcs_params(ehci, "reset"); dbg_hcs_params(ehci, "reset");
dbg_hcc_params(ehci, "reset"); dbg_hcc_params(ehci, "reset");
...@@ -65,12 +59,6 @@ static int ehci_mxc_setup(struct usb_hcd *hcd) ...@@ -65,12 +59,6 @@ static int ehci_mxc_setup(struct usb_hcd *hcd)
ehci_reset(ehci); ehci_reset(ehci);
/* set up the PORTSCx register */
ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
/* is this really needed? */
msleep(10);
ehci_port_power(ehci, 0); ehci_port_power(ehci, 0);
return 0; return 0;
} }
...@@ -128,6 +116,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -128,6 +116,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
int irq, ret; int irq, ret;
struct ehci_mxc_priv *priv; struct ehci_mxc_priv *priv;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct ehci_hcd *ehci;
dev_info(&pdev->dev, "initializing i.MX USB Controller\n"); dev_info(&pdev->dev, "initializing i.MX USB Controller\n");
...@@ -204,6 +193,19 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -204,6 +193,19 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err_init; goto err_init;
ehci = hcd_to_ehci(hcd);
/* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100;
ehci->regs = hcd->regs + 0x100 +
HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
/* set up the PORTSCx register */
ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
/* is this really needed? */
msleep(10);
/* Initialize the transceiver */ /* Initialize the transceiver */
if (pdata->otg) { if (pdata->otg) {
pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment