From 5b1c00e4fa97d2c424edc16f8521065298eee56c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 14 Aug 2016 13:05:02 +0200 Subject: [PATCH] bcm53xx: support USB 2.0 controller on BCM53573 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- ...-old-USB-2.0-controller-on-Northstar.patch | 162 ++++++++++++++++++ .../197-USB-bcma-add-USB-3.0-support.patch | 10 +- ...-USB-2.0-PHY-support-for-BCM4709-and.patch | 8 +- 3 files changed, 171 insertions(+), 9 deletions(-) create mode 100644 target/linux/bcm53xx/patches-4.4/170-USB-bcma-support-old-USB-2.0-controller-on-Northstar.patch diff --git a/target/linux/bcm53xx/patches-4.4/170-USB-bcma-support-old-USB-2.0-controller-on-Northstar.patch b/target/linux/bcm53xx/patches-4.4/170-USB-bcma-support-old-USB-2.0-controller-on-Northstar.patch new file mode 100644 index 0000000000..9e17115fda --- /dev/null +++ b/target/linux/bcm53xx/patches-4.4/170-USB-bcma-support-old-USB-2.0-controller-on-Northstar.patch @@ -0,0 +1,162 @@ +From ef54f033c53bf4518f6e16e7ed815acd855e03c5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +--- + 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 */ diff --git a/target/linux/bcm53xx/patches-4.4/197-USB-bcma-add-USB-3.0-support.patch b/target/linux/bcm53xx/patches-4.4/197-USB-bcma-add-USB-3.0-support.patch index a86dfc1b95..c7b65867d8 100644 --- a/target/linux/bcm53xx/patches-4.4/197-USB-bcma-add-USB-3.0-support.patch +++ b/target/linux/bcm53xx/patches-4.4/197-USB-bcma-add-USB-3.0-support.patch @@ -22,7 +22,7 @@ Signed-off-by: Hauke Mehrtens 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 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 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 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 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; diff --git a/target/linux/bcm53xx/patches-4.4/811-USB-bcma-improve-USB-2.0-PHY-support-for-BCM4709-and.patch b/target/linux/bcm53xx/patches-4.4/811-USB-bcma-improve-USB-2.0-PHY-support-for-BCM4709-and.patch index 02cac54c3d..1a27b4ecd3 100644 --- a/target/linux/bcm53xx/patches-4.4/811-USB-bcma-improve-USB-2.0-PHY-support-for-BCM4709-and.patch +++ b/target/linux/bcm53xx/patches-4.4/811-USB-bcma-improve-USB-2.0-PHY-support-for-BCM4709-and.patch @@ -27,8 +27,8 @@ Signed-off-by: Rafał Miłecki 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 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 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) { -- 2.30.2