bcm53xx: add xHCI support
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 46080
This commit is contained in:
		@@ -1557,7 +1557,9 @@ XHCI_AUTOLOAD := $(patsubst $(LINUX_DIR)/drivers/usb/host/%.ko,%,$(XHCI_FILES))
 | 
			
		||||
 | 
			
		||||
define KernelPackage/usb3
 | 
			
		||||
  TITLE:=Support for USB3 controllers
 | 
			
		||||
  DEPENDS:=+TARGET_omap:kmod-usb-phy-omap-usb3
 | 
			
		||||
  DEPENDS:= \
 | 
			
		||||
	+TARGET_bcm53xx:kmod-usb-bcma \
 | 
			
		||||
	+TARGET_omap:kmod-usb-phy-omap-usb3
 | 
			
		||||
  KCONFIG:= \
 | 
			
		||||
	CONFIG_USB_XHCI_HCD \
 | 
			
		||||
	CONFIG_USB_XHCI_PCI \
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
From 5b4fed9fc917cc2bfc5297eeab03aeba5d340618 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | 
			
		||||
Date: Tue, 16 Jun 2015 12:33:46 +0200
 | 
			
		||||
Subject: [PATCH] USB: bcma: make helper creating platform dev more generic
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Having "bool ohci" argument bounded us to two cases only and didn't
 | 
			
		||||
allow re-using this code for XHCI.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/usb/host/bcma-hcd.c | 24 +++++++++++++-----------
 | 
			
		||||
 1 file changed, 13 insertions(+), 11 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
index 5398e3d..d347282 100644
 | 
			
		||||
--- a/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
+++ b/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
@@ -249,7 +249,10 @@ static const struct usb_ehci_pdata ehci_pdata = {
 | 
			
		||||
 static const struct usb_ohci_pdata ohci_pdata = {
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
-static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
 | 
			
		||||
+static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev,
 | 
			
		||||
+						    const char *name, u32 addr,
 | 
			
		||||
+						    const void *data,
 | 
			
		||||
+						    size_t size)
 | 
			
		||||
 {
 | 
			
		||||
 	struct platform_device *hci_dev;
 | 
			
		||||
 	struct resource hci_res[2];
 | 
			
		||||
@@ -264,8 +267,7 @@ static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, boo
 | 
			
		||||
 	hci_res[1].start = dev->irq;
 | 
			
		||||
 	hci_res[1].flags = IORESOURCE_IRQ;
 | 
			
		||||
 
 | 
			
		||||
-	hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
 | 
			
		||||
-					"ehci-platform" , 0);
 | 
			
		||||
+	hci_dev = platform_device_alloc(name, 0);
 | 
			
		||||
 	if (!hci_dev)
 | 
			
		||||
 		return ERR_PTR(-ENOMEM);
 | 
			
		||||
 
 | 
			
		||||
@@ -276,12 +278,8 @@ static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, boo
 | 
			
		||||
 					    ARRAY_SIZE(hci_res));
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		goto err_alloc;
 | 
			
		||||
-	if (ohci)
 | 
			
		||||
-		ret = platform_device_add_data(hci_dev, &ohci_pdata,
 | 
			
		||||
-					       sizeof(ohci_pdata));
 | 
			
		||||
-	else
 | 
			
		||||
-		ret = platform_device_add_data(hci_dev, &ehci_pdata,
 | 
			
		||||
-					       sizeof(ehci_pdata));
 | 
			
		||||
+	if (data)
 | 
			
		||||
+		ret = platform_device_add_data(hci_dev, data, size);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		goto err_alloc;
 | 
			
		||||
 	ret = platform_device_add(hci_dev);
 | 
			
		||||
@@ -334,11 +332,15 @@ static int bcma_hcd_probe(struct bcma_device *dev)
 | 
			
		||||
 	    && chipinfo->rev == 0)
 | 
			
		||||
 		ohci_addr = 0x18009000;
 | 
			
		||||
 
 | 
			
		||||
-	usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
 | 
			
		||||
+	usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, "ohci-platform",
 | 
			
		||||
+						 ohci_addr, &ohci_pdata,
 | 
			
		||||
+						 sizeof(ohci_pdata));
 | 
			
		||||
 	if (IS_ERR(usb_dev->ohci_dev))
 | 
			
		||||
 		return PTR_ERR(usb_dev->ohci_dev);
 | 
			
		||||
 
 | 
			
		||||
-	usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
 | 
			
		||||
+	usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, "ehci-platform",
 | 
			
		||||
+						 dev->addr, &ehci_pdata,
 | 
			
		||||
+						 sizeof(ehci_pdata));
 | 
			
		||||
 	if (IS_ERR(usb_dev->ehci_dev)) {
 | 
			
		||||
 		err = PTR_ERR(usb_dev->ehci_dev);
 | 
			
		||||
 		goto err_unregister_ohci_dev;
 | 
			
		||||
-- 
 | 
			
		||||
1.8.4.5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,107 @@
 | 
			
		||||
From 4aed231f49954114d5ae23e97789e9aa540a0b70 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | 
			
		||||
Date: Tue, 16 Jun 2015 12:52:07 +0200
 | 
			
		||||
Subject: [PATCH] USB: bcma: use separated function for USB 2.0 initialization
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
This will allow adding USB 3.0 (XHCI) support cleanly.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/usb/host/bcma-hcd.c | 51 +++++++++++++++++++++++++++++++--------------
 | 
			
		||||
 1 file changed, 35 insertions(+), 16 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
index d347282..0b4d0e8 100644
 | 
			
		||||
--- a/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
+++ b/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
@@ -34,6 +34,7 @@ MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
 | 
			
		||||
 MODULE_LICENSE("GPL");
 | 
			
		||||
 
 | 
			
		||||
 struct bcma_hcd_device {
 | 
			
		||||
+	struct bcma_device *core;
 | 
			
		||||
 	struct platform_device *ehci_dev;
 | 
			
		||||
 	struct platform_device *ohci_dev;
 | 
			
		||||
 };
 | 
			
		||||
@@ -293,27 +294,16 @@ err_alloc:
 | 
			
		||||
 	return ERR_PTR(ret);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int bcma_hcd_probe(struct bcma_device *dev)
 | 
			
		||||
+static int bcma_hcd_usb20_init(struct bcma_hcd_device *usb_dev)
 | 
			
		||||
 {
 | 
			
		||||
-	int err;
 | 
			
		||||
+	struct bcma_device *dev = usb_dev->core;
 | 
			
		||||
+	struct bcma_chipinfo *chipinfo = &dev->bus->chipinfo;
 | 
			
		||||
 	u32 ohci_addr;
 | 
			
		||||
-	struct bcma_hcd_device *usb_dev;
 | 
			
		||||
-	struct bcma_chipinfo *chipinfo;
 | 
			
		||||
-
 | 
			
		||||
-	chipinfo = &dev->bus->chipinfo;
 | 
			
		||||
-
 | 
			
		||||
-	/* TODO: Probably need checks here; is the core connected? */
 | 
			
		||||
+	int err;
 | 
			
		||||
 
 | 
			
		||||
 	if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32)))
 | 
			
		||||
 		return -EOPNOTSUPP;
 | 
			
		||||
 
 | 
			
		||||
-	usb_dev = devm_kzalloc(&dev->dev, sizeof(struct bcma_hcd_device),
 | 
			
		||||
-			       GFP_KERNEL);
 | 
			
		||||
-	if (!usb_dev)
 | 
			
		||||
-		return -ENOMEM;
 | 
			
		||||
-
 | 
			
		||||
-	bcma_hci_platform_power_gpio(dev, true);
 | 
			
		||||
-
 | 
			
		||||
 	switch (dev->id.id) {
 | 
			
		||||
 	case BCMA_CORE_NS_USB20:
 | 
			
		||||
 		bcma_hcd_init_chip_arm(dev);
 | 
			
		||||
@@ -346,7 +336,6 @@ static int bcma_hcd_probe(struct bcma_device *dev)
 | 
			
		||||
 		goto err_unregister_ohci_dev;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	bcma_set_drvdata(dev, usb_dev);
 | 
			
		||||
 	return 0;
 | 
			
		||||
 
 | 
			
		||||
 err_unregister_ohci_dev:
 | 
			
		||||
@@ -354,6 +343,36 @@ err_unregister_ohci_dev:
 | 
			
		||||
 	return err;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int bcma_hcd_probe(struct bcma_device *dev)
 | 
			
		||||
+{
 | 
			
		||||
+	int err;
 | 
			
		||||
+	struct bcma_hcd_device *usb_dev;
 | 
			
		||||
+
 | 
			
		||||
+	/* TODO: Probably need checks here; is the core connected? */
 | 
			
		||||
+
 | 
			
		||||
+	usb_dev = devm_kzalloc(&dev->dev, sizeof(struct bcma_hcd_device),
 | 
			
		||||
+			       GFP_KERNEL);
 | 
			
		||||
+	if (!usb_dev)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+	usb_dev->core = dev;
 | 
			
		||||
+
 | 
			
		||||
+	bcma_hci_platform_power_gpio(dev, true);
 | 
			
		||||
+
 | 
			
		||||
+	switch (dev->id.id) {
 | 
			
		||||
+	case BCMA_CORE_USB20_HOST:
 | 
			
		||||
+	case BCMA_CORE_NS_USB20:
 | 
			
		||||
+		err = bcma_hcd_usb20_init(usb_dev);
 | 
			
		||||
+		if (err)
 | 
			
		||||
+			return err;
 | 
			
		||||
+		break;
 | 
			
		||||
+	default:
 | 
			
		||||
+		return -ENODEV;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	bcma_set_drvdata(dev, usb_dev);
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void bcma_hcd_remove(struct bcma_device *dev)
 | 
			
		||||
 {
 | 
			
		||||
 	struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
 | 
			
		||||
-- 
 | 
			
		||||
1.8.4.5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,266 @@
 | 
			
		||||
From 78008c94c253963454a9f6d3d2e0324acef3f20a Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | 
			
		||||
Date: Tue, 16 Jun 2015 17:14:26 +0200
 | 
			
		||||
Subject: [PATCH] USB: bcma: add USB 3.0 support
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/usb/host/bcma-hcd.c | 218 ++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 218 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
index 0b4d0e8..71fa06d 100644
 | 
			
		||||
--- a/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
+++ b/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
@@ -37,6 +37,7 @@ struct bcma_hcd_device {
 | 
			
		||||
 	struct bcma_device *core;
 | 
			
		||||
 	struct platform_device *ehci_dev;
 | 
			
		||||
 	struct platform_device *ohci_dev;
 | 
			
		||||
+	struct platform_device *xhci_dev;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /* Wait for bitmask in a register to get set or cleared.
 | 
			
		||||
@@ -343,6 +344,217 @@ err_unregister_ohci_dev:
 | 
			
		||||
 	return err;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static bool bcma_wait_reg(struct bcma_bus *bus, void __iomem *addr, u32 mask,
 | 
			
		||||
+			  u32 value, int timeout)
 | 
			
		||||
+{
 | 
			
		||||
+	unsigned long deadline = jiffies + timeout;
 | 
			
		||||
+	u32 val;
 | 
			
		||||
+
 | 
			
		||||
+	do {
 | 
			
		||||
+		val = readl(addr);
 | 
			
		||||
+		if ((val & mask) == value)
 | 
			
		||||
+			return true;
 | 
			
		||||
+		cpu_relax();
 | 
			
		||||
+		udelay(10);
 | 
			
		||||
+	} while (!time_after_eq(jiffies, deadline));
 | 
			
		||||
+
 | 
			
		||||
+	pr_err("Timeout waiting for register %p\n", addr);
 | 
			
		||||
+
 | 
			
		||||
+	return false;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void bcma_hcd_usb30_phy_init(struct bcma_hcd_device *bcma_hcd)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcma_device *core = bcma_hcd->core;
 | 
			
		||||
+	struct bcma_bus *bus = core->bus;
 | 
			
		||||
+	struct bcma_chipinfo *chipinfo = &bus->chipinfo;
 | 
			
		||||
+	struct bcma_drv_cc_b *ccb = &bus->drv_cc_b;
 | 
			
		||||
+	struct bcma_device *arm_core;
 | 
			
		||||
+	void __iomem *dmu = NULL;
 | 
			
		||||
+	u32 cru_straps_ctrl;
 | 
			
		||||
+
 | 
			
		||||
+	if (chipinfo->id != BCMA_CHIP_ID_BCM4707 &&
 | 
			
		||||
+	    chipinfo->id != BCMA_CHIP_ID_BCM53018)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	arm_core = bcma_find_core(bus, BCMA_CORE_ARMCA9);
 | 
			
		||||
+	if (!arm_core)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
 | 
			
		||||
+	if (!dmu)
 | 
			
		||||
+		goto out;
 | 
			
		||||
+
 | 
			
		||||
+	/* Check strapping of PCIE/USB3 SEL */
 | 
			
		||||
+	cru_straps_ctrl = ioread32(dmu + 0x2a0);
 | 
			
		||||
+	if ((cru_straps_ctrl & 0x10) == 0)
 | 
			
		||||
+		goto out;
 | 
			
		||||
+
 | 
			
		||||
+	/* Perform USB3 system soft reset */
 | 
			
		||||
+	bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
 | 
			
		||||
+
 | 
			
		||||
+	/* Enable MDIO. Setting MDCDIV as 26  */
 | 
			
		||||
+	iowrite32(0x0000009a, ccb->mii + 0x000);
 | 
			
		||||
+	udelay(2);
 | 
			
		||||
+
 | 
			
		||||
+	switch (chipinfo->id) {
 | 
			
		||||
+	case BCMA_CHIP_ID_BCM4707:
 | 
			
		||||
+		if (chipinfo->rev == 4) {
 | 
			
		||||
+			/* For NS-B0, USB3 PLL Block */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x587e8000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* Clear ana_pllSeqStart */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x58061000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* CMOS Divider ratio to 25 */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x582a6400, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* Asserting PLL Reset */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x582ec000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* Deaaserting PLL Reset */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x582e8000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* Deasserting USB3 system reset */
 | 
			
		||||
+			bcma_awrite32(core, BCMA_RESET_CTL, 0);
 | 
			
		||||
+
 | 
			
		||||
+			/* Set ana_pllSeqStart */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x58069000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* RXPMD block */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x587e8020, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* CDR int loop locking BW to 1 */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x58120049, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* CDR int loop acquisition BW to 1 */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x580e0049, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* CDR prop loop BW to 1 */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x580a005c, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* Waiting MII Mgt interface idle */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		} else {
 | 
			
		||||
+			/* PLL30 block */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x587e8000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x582a6400, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x587e80e0, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x580a009c, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* Enable SSC */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x587e8040, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x580a21d3, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+			iowrite32(0x58061003, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+			/* Waiting MII Mgt interface idle */
 | 
			
		||||
+			bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+
 | 
			
		||||
+			/* Deasserting USB3 system reset */
 | 
			
		||||
+			bcma_awrite32(core, BCMA_RESET_CTL, 0);
 | 
			
		||||
+		}
 | 
			
		||||
+		break;
 | 
			
		||||
+	case BCMA_CHIP_ID_BCM53018:
 | 
			
		||||
+		/* USB3 PLL Block */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x587e8000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* Assert Ana_Pllseq start */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x58061000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* Assert CML Divider ratio to 26 */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x582a6400, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* Asserting PLL Reset */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x582ec000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* Deaaserting PLL Reset */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x582e8000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* Waiting MII Mgt interface idle */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+
 | 
			
		||||
+		/* Deasserting USB3 system reset */
 | 
			
		||||
+		bcma_awrite32(core, BCMA_RESET_CTL, 0);
 | 
			
		||||
+
 | 
			
		||||
+		/* PLL frequency monitor enable */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x58069000, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* PIPE Block */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x587e8060, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* CMPMAX & CMPMINTH setting */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x580af30d, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* DEGLITCH MIN & MAX setting */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x580e6302, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* TXPMD block */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x587e8040, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* Enabling SSC */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+		iowrite32(0x58061003, ccb->mii + 0x004);
 | 
			
		||||
+
 | 
			
		||||
+		/* Waiting MII Mgt interface idle */
 | 
			
		||||
+		bcma_wait_reg(bus, ccb->mii + 0x000, 0x0100, 0x0000, 1000);
 | 
			
		||||
+
 | 
			
		||||
+		break;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	pr_info("[%s:%d] DONE\n", __FUNCTION__, __LINE__);
 | 
			
		||||
+out:
 | 
			
		||||
+	if (dmu)
 | 
			
		||||
+		iounmap(dmu);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int bcma_hcd_usb30_init(struct bcma_hcd_device *bcma_hcd)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcma_device *core = bcma_hcd->core;
 | 
			
		||||
+
 | 
			
		||||
+	bcma_core_enable(core, 0);
 | 
			
		||||
+
 | 
			
		||||
+	bcma_hcd_usb30_phy_init(bcma_hcd);
 | 
			
		||||
+
 | 
			
		||||
+	bcma_hcd->xhci_dev = bcma_hcd_create_pdev(core, "xhci-hcd", core->addr,
 | 
			
		||||
+						  NULL, 0);
 | 
			
		||||
+	if (IS_ERR(bcma_hcd->ohci_dev))
 | 
			
		||||
+		return PTR_ERR(bcma_hcd->ohci_dev);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int bcma_hcd_probe(struct bcma_device *dev)
 | 
			
		||||
 {
 | 
			
		||||
 	int err;
 | 
			
		||||
@@ -365,6 +577,11 @@ static int bcma_hcd_probe(struct bcma_device *dev)
 | 
			
		||||
 		if (err)
 | 
			
		||||
 			return err;
 | 
			
		||||
 		break;
 | 
			
		||||
+	case BCMA_CORE_NS_USB30:
 | 
			
		||||
+		err = bcma_hcd_usb30_init(usb_dev);
 | 
			
		||||
+		if (err)
 | 
			
		||||
+			return err;
 | 
			
		||||
+		break;
 | 
			
		||||
 	default:
 | 
			
		||||
 		return -ENODEV;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -419,6 +636,7 @@ static int bcma_hcd_resume(struct bcma_device *dev)
 | 
			
		||||
 static const struct bcma_device_id bcma_hcd_table[] = {
 | 
			
		||||
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
 | 
			
		||||
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
 | 
			
		||||
+	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB30, BCMA_ANY_REV, BCMA_ANY_CLASS),
 | 
			
		||||
 	BCMA_CORETABLE_END
 | 
			
		||||
 };
 | 
			
		||||
 MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
 | 
			
		||||
-- 
 | 
			
		||||
1.8.4.5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,99 @@
 | 
			
		||||
From 9cc14ca0aae53c16d10ffea49848ac61a5015562 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | 
			
		||||
Date: Sun, 21 Jun 2015 11:10:49 +0200
 | 
			
		||||
Subject: [PATCH] xhci: add Broadcom specific fake doorbell
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
This fixes problem with controller seeing devices only in some small
 | 
			
		||||
percentage of cold boots.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/usb/host/xhci.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 62 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
 | 
			
		||||
index 3bceabe..0737ab2 100644
 | 
			
		||||
--- a/drivers/usb/host/xhci.c
 | 
			
		||||
+++ b/drivers/usb/host/xhci.c
 | 
			
		||||
@@ -122,6 +122,64 @@ int xhci_halt(struct xhci_hcd *xhci)
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+#ifdef CONFIG_ARCH_BCM_5301X
 | 
			
		||||
+int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
 | 
			
		||||
+{
 | 
			
		||||
+	unsigned int temp1, ret;
 | 
			
		||||
+
 | 
			
		||||
+	/* alloc a virt device for slot */
 | 
			
		||||
+	if (!xhci_alloc_virt_device(xhci, slot_id, 0, GFP_NOIO)) {
 | 
			
		||||
+		xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
 | 
			
		||||
+		return 1;
 | 
			
		||||
+        }
 | 
			
		||||
+
 | 
			
		||||
+	/* ring fake doorbell for slot_id ep 0 */
 | 
			
		||||
+	xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
 | 
			
		||||
+	mdelay(1);
 | 
			
		||||
+
 | 
			
		||||
+	/* read the status register to check if HSE is set or not? */
 | 
			
		||||
+	temp1 = readl(&xhci->op_regs->status);
 | 
			
		||||
+	xhci_dbg(xhci, "op reg status = %x\n",temp1);
 | 
			
		||||
+
 | 
			
		||||
+	/* clear HSE if set */
 | 
			
		||||
+	if(temp1 & STS_FATAL) {
 | 
			
		||||
+		xhci_dbg(xhci, "HSE problem detected\n");
 | 
			
		||||
+		temp1 &= ~(0x1fff);
 | 
			
		||||
+		temp1 |= STS_FATAL;
 | 
			
		||||
+		xhci_dbg(xhci, "temp1=%x\n",temp1);
 | 
			
		||||
+		writel(temp1, &xhci->op_regs->status);
 | 
			
		||||
+		mdelay(1);
 | 
			
		||||
+		temp1 = readl(&xhci->op_regs->status);
 | 
			
		||||
+		xhci_dbg(xhci, "After clear op reg status=%x\n", temp1);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/* Free virt device */
 | 
			
		||||
+	xhci_free_virt_device(xhci, slot_id);
 | 
			
		||||
+
 | 
			
		||||
+	/* Run the controller if needed */
 | 
			
		||||
+	temp1 = readl(&xhci->op_regs->command);
 | 
			
		||||
+	if (temp1 & CMD_RUN)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+	temp1 |= (CMD_RUN);
 | 
			
		||||
+
 | 
			
		||||
+	writel(temp1, &xhci->op_regs->command);
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Wait for the HCHalted Status bit to be 0 to indicate the host is running.
 | 
			
		||||
+	 */
 | 
			
		||||
+	ret = xhci_handshake(xhci, &xhci->op_regs->status,
 | 
			
		||||
+			     STS_HALT, 0, XHCI_MAX_HALT_USEC);
 | 
			
		||||
+
 | 
			
		||||
+	if (ret == -ETIMEDOUT) {
 | 
			
		||||
+		xhci_err(xhci, "Host took too long to start, "
 | 
			
		||||
+				"waited %u microseconds.\n",
 | 
			
		||||
+				XHCI_MAX_HALT_USEC);
 | 
			
		||||
+		return 1;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+#endif /* CONFIG_ARCH_BCM_5301X */
 | 
			
		||||
+
 | 
			
		||||
 /*
 | 
			
		||||
  * Set the run bit and wait for the host to be running.
 | 
			
		||||
  */
 | 
			
		||||
@@ -146,6 +204,10 @@ static int xhci_start(struct xhci_hcd *xhci)
 | 
			
		||||
 		xhci_err(xhci, "Host took too long to start, "
 | 
			
		||||
 				"waited %u microseconds.\n",
 | 
			
		||||
 				XHCI_MAX_HALT_USEC);
 | 
			
		||||
+#ifdef CONFIG_ARCH_BCM_5301X
 | 
			
		||||
+	xhci_fake_doorbell(xhci, 1);
 | 
			
		||||
+#endif /* CONFIG_ARCH_BCM_5301X */
 | 
			
		||||
+
 | 
			
		||||
 	if (!ret)
 | 
			
		||||
 		xhci->xhc_state &= ~XHCI_STATE_HALTED;
 | 
			
		||||
 	return ret;
 | 
			
		||||
-- 
 | 
			
		||||
1.8.4.5
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user