mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	bcm53xx: support USB 2.0 controller on BCM53573
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
		
							parent
							
								
									62c5f68095
								
							
						
					
					
						commit
						5b1c00e4fa
					
				@ -0,0 +1,162 @@
 | 
			
		||||
From ef54f033c53bf4518f6e16e7ed815acd855e03c5 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | 
			
		||||
Date: Wed, 10 Aug 2016 11:51:16 +0200
 | 
			
		||||
Subject: [PATCH] USB: bcma: support old USB 2.0 controller on Northstar
 | 
			
		||||
 devices
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Currently bcma-hcd driver handles 3 different bcma cores:
 | 
			
		||||
1) BCMA_CORE_USB20_HOST (0x819)
 | 
			
		||||
2) BCMA_CORE_NS_USB20 (0x504)
 | 
			
		||||
3) BCMA_CORE_NS_USB30 (0x505)
 | 
			
		||||
 | 
			
		||||
The first one was introduced years ago and so far was used on MIPS
 | 
			
		||||
devices only. All Northstar (ARM) devices were using other two cores
 | 
			
		||||
which allowed easy implementation of separated initialization paths.
 | 
			
		||||
 | 
			
		||||
It seems however Broadcom decided to reuse this old USB 2.0 controller
 | 
			
		||||
on some recently introduced cheaper Northstar BCM53573 SoCs. I noticed
 | 
			
		||||
this on Tenda AC9 (based on BCM47189B0 belonging to BCM53573 family).
 | 
			
		||||
 | 
			
		||||
There is no difference in this old controller core identification
 | 
			
		||||
between MIPS and ARM devices: they share the same id and revision. We
 | 
			
		||||
need different controller initialization procedure however.
 | 
			
		||||
To handle this add a check for architecture and implement required
 | 
			
		||||
initialization for ARM case.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
---
 | 
			
		||||
 drivers/usb/host/bcma-hcd.c    | 86 ++++++++++++++++++++++++++++++++++++++++--
 | 
			
		||||
 include/linux/bcma/bcma_regs.h |  1 +
 | 
			
		||||
 2 files changed, 83 insertions(+), 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
+++ b/drivers/usb/host/bcma-hcd.c
 | 
			
		||||
@@ -35,6 +35,9 @@ MODULE_AUTHOR("Hauke Mehrtens");
 | 
			
		||||
 MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
 | 
			
		||||
 MODULE_LICENSE("GPL");
 | 
			
		||||
 
 | 
			
		||||
+/* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */
 | 
			
		||||
+#define USB_BCMA_CLKCTLST_USB_CLK_REQ			0x00000100
 | 
			
		||||
+
 | 
			
		||||
 struct bcma_hcd_device {
 | 
			
		||||
 	struct bcma_device *core;
 | 
			
		||||
 	struct platform_device *ehci_dev;
 | 
			
		||||
@@ -166,6 +169,76 @@ static void bcma_hcd_init_chip_mips(stru
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+/**
 | 
			
		||||
+ * bcma_hcd_usb20_old_arm_init - Initialize old USB 2.0 controller on ARM
 | 
			
		||||
+ *
 | 
			
		||||
+ * Old USB 2.0 core is identified as BCMA_CORE_USB20_HOST and was introduced
 | 
			
		||||
+ * long before Northstar devices. It seems some cheaper chipsets like BCM53573
 | 
			
		||||
+ * still use it.
 | 
			
		||||
+ * Initialization of this old core differs between MIPS and ARM.
 | 
			
		||||
+ */
 | 
			
		||||
+static int bcma_hcd_usb20_old_arm_init(struct bcma_hcd_device *usb_dev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcma_device *core = usb_dev->core;
 | 
			
		||||
+	struct device *dev = &core->dev;
 | 
			
		||||
+	struct bcma_device *pmu_core;
 | 
			
		||||
+
 | 
			
		||||
+	usleep_range(10000, 20000);
 | 
			
		||||
+	if (core->id.rev < 5)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	pmu_core = bcma_find_core(core->bus, BCMA_CORE_PMU);
 | 
			
		||||
+	if (!pmu_core) {
 | 
			
		||||
+		dev_err(dev, "Could not find PMU core\n");
 | 
			
		||||
+		return -ENOENT;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/* Take USB core out of reset */
 | 
			
		||||
+	bcma_awrite32(core, BCMA_IOCTL, BCMA_IOCTL_CLK | BCMA_IOCTL_FGC);
 | 
			
		||||
+	usleep_range(100, 200);
 | 
			
		||||
+	bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
 | 
			
		||||
+	usleep_range(100, 200);
 | 
			
		||||
+	bcma_awrite32(core, BCMA_RESET_CTL, 0);
 | 
			
		||||
+	usleep_range(100, 200);
 | 
			
		||||
+	bcma_awrite32(core, BCMA_IOCTL, BCMA_IOCTL_CLK);
 | 
			
		||||
+	usleep_range(100, 200);
 | 
			
		||||
+
 | 
			
		||||
+	/* Enable Misc PLL */
 | 
			
		||||
+	bcma_write32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT |
 | 
			
		||||
+					  BCMA_CLKCTLST_HQCLKREQ |
 | 
			
		||||
+					  USB_BCMA_CLKCTLST_USB_CLK_REQ);
 | 
			
		||||
+	usleep_range(100, 200);
 | 
			
		||||
+
 | 
			
		||||
+	bcma_write32(core, 0x510, 0xc7f85000);
 | 
			
		||||
+	bcma_write32(core, 0x510, 0xc7f85003);
 | 
			
		||||
+	usleep_range(300, 600);
 | 
			
		||||
+
 | 
			
		||||
+	/* Program USB PHY PLL parameters */
 | 
			
		||||
+	bcma_write32(pmu_core, BCMA_CC_PMU_PLLCTL_ADDR, 0x6);
 | 
			
		||||
+	bcma_write32(pmu_core, BCMA_CC_PMU_PLLCTL_DATA, 0x005360c1);
 | 
			
		||||
+	usleep_range(100, 200);
 | 
			
		||||
+	bcma_write32(pmu_core, BCMA_CC_PMU_PLLCTL_ADDR, 0x7);
 | 
			
		||||
+	bcma_write32(pmu_core, BCMA_CC_PMU_PLLCTL_DATA, 0x0);
 | 
			
		||||
+	usleep_range(100, 200);
 | 
			
		||||
+	bcma_set32(pmu_core, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
 | 
			
		||||
+	usleep_range(100, 200);
 | 
			
		||||
+
 | 
			
		||||
+	bcma_write32(core, 0x510, 0x7f8d007);
 | 
			
		||||
+	udelay(1000);
 | 
			
		||||
+
 | 
			
		||||
+	/* Take controller out of reset */
 | 
			
		||||
+	bcma_write32(core, 0x200, 0x4ff);
 | 
			
		||||
+	usleep_range(25, 50);
 | 
			
		||||
+	bcma_write32(core, 0x200, 0x6ff);
 | 
			
		||||
+	usleep_range(25, 50);
 | 
			
		||||
+	bcma_write32(core, 0x200, 0x7ff);
 | 
			
		||||
+	usleep_range(25, 50);
 | 
			
		||||
+
 | 
			
		||||
+	of_platform_default_populate(dev->of_node, NULL, dev);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev)
 | 
			
		||||
 {
 | 
			
		||||
 	struct bcma_device *arm_core;
 | 
			
		||||
@@ -370,19 +443,24 @@ static int bcma_hcd_probe(struct bcma_de
 | 
			
		||||
 
 | 
			
		||||
 	switch (core->id.id) {
 | 
			
		||||
 	case BCMA_CORE_USB20_HOST:
 | 
			
		||||
+		if (IS_ENABLED(CONFIG_ARM))
 | 
			
		||||
+			err = bcma_hcd_usb20_old_arm_init(usb_dev);
 | 
			
		||||
+		else if (IS_ENABLED(CONFIG_MIPS))
 | 
			
		||||
+			err = bcma_hcd_usb20_init(usb_dev);
 | 
			
		||||
+		else
 | 
			
		||||
+			err = -ENOTSUPP;
 | 
			
		||||
+		break;
 | 
			
		||||
 	case BCMA_CORE_NS_USB20:
 | 
			
		||||
 		err = bcma_hcd_usb20_init(usb_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;
 | 
			
		||||
 	}
 | 
			
		||||
+	if (err)
 | 
			
		||||
+		return err;
 | 
			
		||||
 
 | 
			
		||||
 	bcma_set_drvdata(core, usb_dev);
 | 
			
		||||
 	return 0;
 | 
			
		||||
--- a/include/linux/bcma/bcma_regs.h
 | 
			
		||||
+++ b/include/linux/bcma/bcma_regs.h
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
 #define  BCMA_CLKCTLST_HAVEALPREQ	0x00000008 /* ALP available request */
 | 
			
		||||
 #define  BCMA_CLKCTLST_HAVEHTREQ	0x00000010 /* HT available request */
 | 
			
		||||
 #define  BCMA_CLKCTLST_HWCROFF		0x00000020 /* Force HW clock request off */
 | 
			
		||||
+#define  BCMA_CLKCTLST_HQCLKREQ		0x00000040 /* HQ Clock */
 | 
			
		||||
 #define  BCMA_CLKCTLST_EXTRESREQ	0x00000700 /* Mask of external resource requests */
 | 
			
		||||
 #define  BCMA_CLKCTLST_EXTRESREQ_SHIFT	8
 | 
			
		||||
 #define  BCMA_CLKCTLST_HAVEALP		0x00010000 /* ALP available */
 | 
			
		||||
@ -22,7 +22,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 
 | 
			
		||||
 MODULE_AUTHOR("Hauke Mehrtens");
 | 
			
		||||
 MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
 | 
			
		||||
@@ -39,6 +40,7 @@ struct bcma_hcd_device {
 | 
			
		||||
@@ -42,6 +43,7 @@ struct bcma_hcd_device {
 | 
			
		||||
 	struct bcma_device *core;
 | 
			
		||||
 	struct platform_device *ehci_dev;
 | 
			
		||||
 	struct platform_device *ohci_dev;
 | 
			
		||||
@ -30,7 +30,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 	struct gpio_desc *gpio_desc;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -246,6 +248,10 @@ static const struct usb_ehci_pdata ehci_
 | 
			
		||||
@@ -319,6 +321,10 @@ static const struct usb_ehci_pdata ehci_
 | 
			
		||||
 static const struct usb_ohci_pdata ohci_pdata = {
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@ -41,7 +41,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev,
 | 
			
		||||
 						    const char *name, u32 addr,
 | 
			
		||||
 						    const void *data,
 | 
			
		||||
@@ -339,6 +345,150 @@ err_unregister_ohci_dev:
 | 
			
		||||
@@ -412,6 +418,150 @@ err_unregister_ohci_dev:
 | 
			
		||||
 	return err;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@ -192,7 +192,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 static int bcma_hcd_usb30_init(struct bcma_hcd_device *bcma_hcd)
 | 
			
		||||
 {
 | 
			
		||||
 	struct bcma_device *core = bcma_hcd->core;
 | 
			
		||||
@@ -346,6 +496,14 @@ static int bcma_hcd_usb30_init(struct bc
 | 
			
		||||
@@ -419,6 +569,14 @@ static int bcma_hcd_usb30_init(struct bc
 | 
			
		||||
 
 | 
			
		||||
 	bcma_core_enable(core, 0);
 | 
			
		||||
 
 | 
			
		||||
@ -207,7 +207,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 	of_platform_default_populate(dev->of_node, NULL, dev);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
@@ -393,11 +551,14 @@ static void bcma_hcd_remove(struct bcma_
 | 
			
		||||
@@ -471,11 +629,14 @@ static void bcma_hcd_remove(struct bcma_
 | 
			
		||||
 	struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
 | 
			
		||||
 	struct platform_device *ohci_dev = usb_dev->ohci_dev;
 | 
			
		||||
 	struct platform_device *ehci_dev = usb_dev->ehci_dev;
 | 
			
		||||
 | 
			
		||||
@ -27,8 +27,8 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
			
		||||
 MODULE_AUTHOR("Hauke Mehrtens");
 | 
			
		||||
 MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
 | 
			
		||||
 MODULE_LICENSE("GPL");
 | 
			
		||||
@@ -168,10 +179,35 @@ static void bcma_hcd_init_chip_mips(stru
 | 
			
		||||
 	}
 | 
			
		||||
@@ -241,10 +252,35 @@ static int bcma_hcd_usb20_old_arm_init(s
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static u32 bcma_hcd_usb_ref_clk_get_rate(void __iomem *dmu)
 | 
			
		||||
@ -63,7 +63,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
			
		||||
 
 | 
			
		||||
 	arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9);
 | 
			
		||||
 	if (!arm_core) {
 | 
			
		||||
@@ -185,14 +221,29 @@ static void bcma_hcd_init_chip_arm_phy(s
 | 
			
		||||
@@ -258,14 +294,29 @@ static void bcma_hcd_init_chip_arm_phy(s
 | 
			
		||||
 		return;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@ -96,7 +96,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
			
		||||
 
 | 
			
		||||
 	iounmap(dmu);
 | 
			
		||||
 }
 | 
			
		||||
@@ -220,15 +271,17 @@ static void bcma_hcd_init_chip_arm_hc(st
 | 
			
		||||
@@ -293,15 +344,17 @@ static void bcma_hcd_init_chip_arm_hc(st
 | 
			
		||||
 
 | 
			
		||||
 static void bcma_hcd_init_chip_arm(struct bcma_device *dev)
 | 
			
		||||
 {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user