123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- From d6b76c4ddb124dd22c6e910ca9332e472e7b3273 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:56:46 +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>
- Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
- ---
- 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 */
|