[PATCH 1/5] USB: add support for phy init for the Dove SoC
Saeed Bishara
saeed at marvell.com
Sun May 2 10:22:38 EDT 2010
This patch adds support for initializing the USB phy of the Marvell's Dove SoC.
Signed-off-by: Saeed Bishara <saeed at marvell.com>
---
arch/arm/plat-orion/include/plat/ehci-orion.h | 1 +
drivers/usb/host/ehci-orion.c | 139 +++++++++++++++++++++----
2 files changed, 120 insertions(+), 20 deletions(-)
diff --git a/arch/arm/plat-orion/include/plat/ehci-orion.h b/arch/arm/plat-orion/include/plat/ehci-orion.h
index 4ec668e..67df73e 100644
--- a/arch/arm/plat-orion/include/plat/ehci-orion.h
+++ b/arch/arm/plat-orion/include/plat/ehci-orion.h
@@ -13,6 +13,7 @@
enum orion_ehci_phy_ver {
EHCI_PHY_ORION,
+ EHCI_PHY_DOVE,
EHCI_PHY_DD,
EHCI_PHY_KW,
EHCI_PHY_NA,
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 0f87dc7..ba659e0 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -25,6 +25,7 @@
#define USB_WINDOW_BASE(i) (0x324 + ((i) << 4))
#define USB_IPG 0x360
#define USB_PHY_PWR_CTRL 0x400
+#define USB_PHY_PLL_CTRL 0x410
#define USB_PHY_TX_CTRL 0x420
#define USB_PHY_RX_CTRL 0x430
#define USB_PHY_IVREF_CTRL 0x440
@@ -100,6 +101,93 @@ static void orion_usb_phy_v1_setup(struct usb_hcd *hcd)
wrl(USB_MODE, 0x13);
}
+static void orion_usb_phy_v2_setup(struct usb_hcd *hcd)
+{
+ u32 reg;
+
+ /* The below GLs are according to the Orion Errata document */
+ /*
+ * Clear interrupt cause and mask
+ */
+ wrl(USB_CAUSE, 0);
+ wrl(USB_MASK, 0);
+
+ /*
+ * Reset controller
+ */
+ wrl(USB_CMD, rdl(USB_CMD) | 0x2);
+ while (rdl(USB_CMD) & 0x2);
+
+ /* Clear bits 30 and 31. */
+ reg = rdl(USB_IPG);
+ reg &= ~(0x3 << 30);
+ /* Change bits[14:8] - IPG for non Start of Frame Packets
+ * from 0x9(default) to 0xD
+ */
+ reg &= ~(0x7f << 8);
+ reg |= 0xd << 8;
+ wrl(USB_IPG, reg);
+
+ /* VCO recalibrate */
+ wrl(USB_PHY_PLL_CTRL, rdl(USB_PHY_PLL_CTRL) | (1 << 21));
+ udelay(100);
+ wrl(USB_PHY_PLL_CTRL, rdl(USB_PHY_PLL_CTRL) & ~(1 << 21));
+
+ reg = rdl(USB_PHY_TX_CTRL);
+ reg |= 1 << 11; /* LOWVDD_EN */
+ reg |= 1 << 12; /* REG_RCAL_START */
+ /* bits[16:14] (IMPCAL_VTH[2:0] = 101) */
+ reg &= ~(0x7 << 14);
+ reg |= (0x5 << 14);
+
+ reg &= ~(1 << 21); /* TX_BLOCK_EN */
+ reg &= ~(1 << 31); /* HS_STRESS_CTRL */
+ wrl(USB_PHY_TX_CTRL, reg);
+ udelay(100);
+ reg = rdl(USB_PHY_TX_CTRL);
+ reg &= ~(1 << 12); /* REG_RCAL_START */
+ wrl(USB_PHY_TX_CTRL, reg);
+
+ reg = rdl(USB_PHY_RX_CTRL);
+ reg &= ~(3 << 2); /* LPL_COEF */
+ reg |= 1 << 2;
+
+ reg &= ~(0xf << 4);
+ reg |= 0xc << 4; /* SQ_THRESH */
+
+ reg &= ~(3 << 15); /* REG_SQ_LENGTH */
+ reg |= 1 << 15;
+ reg &= ~(1 << 21); /* CDR_FASTLOCK_EN */
+ reg &= ~(3 << 26); /* EDGE_DET */
+ wrl(USB_PHY_RX_CTRL, reg);
+
+
+ /*
+ * USB PHY IVREF Control
+ * TXVDD12[9:8]=0x3
+ */
+ wrl(USB_PHY_IVREF_CTRL, rdl(USB_PHY_IVREF_CTRL) | (0x3 << 8));
+
+
+ /*
+ * GL# USB-3 GL# USB-9: USB PHY Test Group Control
+ * REG_FIFO_SQ_RST[15]=0
+ */
+ wrl(USB_PHY_TST_GRP_CTRL, rdl(USB_PHY_TST_GRP_CTRL) & ~0x8000);
+
+ /*
+ * Stop and reset controller
+ */
+ wrl(USB_CMD, rdl(USB_CMD) & ~0x1);
+ wrl(USB_CMD, rdl(USB_CMD) | 0x2);
+ while (rdl(USB_CMD) & 0x2);
+
+ /*
+ * GL# USB-4 Setup USB Host mode
+ */
+ wrl(USB_MODE, 0x3);
+}
+
static int ehci_orion_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -190,6 +278,36 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
}
}
+static void __devinit
+ehci_orion_hw_init(struct usb_hcd *hcd, struct orion_ehci_data *pd)
+{
+ /*
+ * (Re-)program MBUS remapping windows if we are asked to.
+ */
+ if (pd != NULL && pd->dram != NULL)
+ ehci_orion_conf_mbus_windows(hcd, pd->dram);
+
+
+ /*
+ * setup Orion USB controller.
+ */
+ switch (pd->phy_version) {
+ case EHCI_PHY_NA: /* dont change USB phy settings */
+ break;
+ case EHCI_PHY_ORION:
+ orion_usb_phy_v1_setup(hcd);
+ break;
+ case EHCI_PHY_DOVE:
+ orion_usb_phy_v2_setup(hcd);
+ break;
+ case EHCI_PHY_DD:
+ case EHCI_PHY_KW:
+ default:
+ printk(KERN_WARNING "Orion ehci -USB phy version isn't supported.\n");
+ }
+
+}
+
static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
{
struct orion_ehci_data *pd = pdev->dev.platform_data;
@@ -255,26 +373,7 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
hcd->has_tt = 1;
ehci->sbrn = 0x20;
- /*
- * (Re-)program MBUS remapping windows if we are asked to.
- */
- if (pd != NULL && pd->dram != NULL)
- ehci_orion_conf_mbus_windows(hcd, pd->dram);
-
- /*
- * setup Orion USB controller.
- */
- switch (pd->phy_version) {
- case EHCI_PHY_NA: /* dont change USB phy settings */
- break;
- case EHCI_PHY_ORION:
- orion_usb_phy_v1_setup(hcd);
- break;
- case EHCI_PHY_DD:
- case EHCI_PHY_KW:
- default:
- printk(KERN_WARNING "Orion ehci -USB phy version isn't supported.\n");
- }
+ ehci_orion_hw_init(hcd, pd);
err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
if (err)
--
1.6.0.4
More information about the linux-arm-kernel
mailing list