diff options
-rw-r--r-- | target/linux/bcm53xx/patches-4.4/811-USB-bcma-improve-USB-2.0-PHY-support-for-BCM4709-and.patch | 122 |
1 files changed, 122 insertions, 0 deletions
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 new file mode 100644 index 0000000000..84a335b3ce --- /dev/null +++ b/target/linux/bcm53xx/patches-4.4/811-USB-bcma-improve-USB-2.0-PHY-support-for-BCM4709-and.patch @@ -0,0 +1,122 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> +Subject: [PATCH] USB: bcma: improve USB 2.0 PHY support for BCM4709 and + BCM47094 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Rafał Miłecki <zajec5@gmail.com> +--- +--- a/drivers/usb/host/bcma-hcd.c ++++ b/drivers/usb/host/bcma-hcd.c +@@ -31,6 +31,17 @@ + #include <linux/usb/ohci_pdriver.h> + #include <linux/usb/xhci_pdriver.h> + ++/* DMU (Device Management Unit) */ ++#define BCMA_DMU_CRU_USB2_CONTROL 0x0164 ++#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK 0x00000FFC ++#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT 2 ++#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK 0x00007000 ++#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT 12 ++#define BCMA_DMU_CRU_CLKSET_KEY 0x0180 ++#define BCMA_DMU_CRU_STRAPS_CTRL 0x02A0 ++#define BCMA_DMU_CRU_STRAPS_CTRL_USB3 0x00000010 ++#define BCMA_DMU_CRU_STRAPS_CTRL_4BYTE 0x00008000 ++ + MODULE_AUTHOR("Hauke Mehrtens"); + MODULE_DESCRIPTION("Common USB driver for BCMA Bus"); + MODULE_LICENSE("GPL"); +@@ -167,10 +178,35 @@ static void bcma_hcd_init_chip_mips(struct bcma_device *dev) + } + } + ++static u32 bcma_hcd_usb_ref_clk_get_rate(void __iomem *dmu) ++{ ++ u32 val, ndiv, pdiv, ch2_mdiv, ch2_freq; ++ ++ /* get divider integer from the cru_genpll_control5 */ ++ val = ioread32(dmu + 0x154); ++ ndiv = (val >> 20) & 0x3ff; ++ if (ndiv == 0) ++ ndiv = 1 << 10; ++ ++ /* get pdiv and ch2_mdiv from the cru_genpll_control6 */ ++ val = ioread32(dmu + 0x158); ++ pdiv = (val >> 24) & 0x7; ++ pdiv = (pdiv == 0) ? (1 << 3) : pdiv; ++ ++ ch2_mdiv = val & 0xff; ++ ch2_mdiv = (ch2_mdiv == 0) ? (1 << 8) : ch2_mdiv; ++ ++ /* calculate ch2_freq based on 25MHz reference clock */ ++ ch2_freq = (25000000 / (pdiv * ch2_mdiv)) * ndiv; ++ ++ return ch2_freq; ++} ++ + static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev) + { + struct bcma_device *arm_core; + void __iomem *dmu; ++ u32 ref_clk_rate, usb2ctl, usb_pll_ndiv, usb_pll_pdiv; + + arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9); + if (!arm_core) { +@@ -184,14 +220,29 @@ static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev) + return; + } + ++ ref_clk_rate = bcma_hcd_usb_ref_clk_get_rate(dmu); ++ ++ usb2ctl = ioread32(dmu + BCMA_DMU_CRU_USB2_CONTROL); ++ ++ usb_pll_pdiv = usb2ctl; ++ usb_pll_pdiv &= BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK; ++ usb_pll_pdiv >>= BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT; ++ if (!usb_pll_pdiv) ++ usb_pll_pdiv = 1 << 3; ++ ++ /* Calculate ndiv based on a solid 1920 MHz that is for USB2 PHY */ ++ usb_pll_ndiv = (1920000000 * usb_pll_pdiv) / ref_clk_rate; ++ + /* Unlock DMU PLL settings */ +- iowrite32(0x0000ea68, dmu + 0x180); ++ iowrite32(0x0000ea68, dmu + BCMA_DMU_CRU_CLKSET_KEY); + + /* Write USB 2.0 PLL control setting */ +- iowrite32(0x00dd10c3, dmu + 0x164); ++ usb2ctl &= ~BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK; ++ usb2ctl |= usb_pll_ndiv << BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT; ++ iowrite32(usb2ctl, dmu + BCMA_DMU_CRU_USB2_CONTROL); + + /* Lock DMU PLL settings */ +- iowrite32(0x00000000, dmu + 0x180); ++ iowrite32(0x00000000, dmu + BCMA_DMU_CRU_CLKSET_KEY); + + iounmap(dmu); + } +@@ -219,15 +270,17 @@ static void bcma_hcd_init_chip_arm_hc(struct bcma_device *dev) + + static void bcma_hcd_init_chip_arm(struct bcma_device *dev) + { ++ struct bcma_chipinfo *chipinfo = &dev->bus->chipinfo; ++ + bcma_core_enable(dev, 0); + +- if (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4707 || +- dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM53018) { +- if (dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4707 || +- dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4708) +- bcma_hcd_init_chip_arm_phy(dev); ++ if (chipinfo->id == BCMA_CHIP_ID_BCM4707 || ++ chipinfo->id == BCMA_CHIP_ID_BCM47094 || ++ chipinfo->id == BCMA_CHIP_ID_BCM53018) { ++ bcma_hcd_init_chip_arm_phy(dev); + +- bcma_hcd_init_chip_arm_hc(dev); ++ if (1) /* TODO: Exclude BCM53573 */ ++ bcma_hcd_init_chip_arm_hc(dev); + } + } + |