84a335b3ce5c439eecf554b345a08150be7b75a0
[openwrt.git] / target / linux / bcm53xx / patches-4.4 / 811-USB-bcma-improve-USB-2.0-PHY-support-for-BCM4709-and.patch
1 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
2 Subject: [PATCH] USB: bcma: improve USB 2.0 PHY support for BCM4709 and
3  BCM47094
4 MIME-Version: 1.0
5 Content-Type: text/plain; charset=UTF-8
6 Content-Transfer-Encoding: 8bit
7
8 Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
9 ---
10 --- a/drivers/usb/host/bcma-hcd.c
11 +++ b/drivers/usb/host/bcma-hcd.c
12 @@ -31,6 +31,17 @@
13  #include <linux/usb/ohci_pdriver.h>
14  #include <linux/usb/xhci_pdriver.h>
15  
16 +/* DMU (Device Management Unit) */
17 +#define BCMA_DMU_CRU_USB2_CONTROL                      0x0164
18 +#define  BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK   0x00000FFC
19 +#define  BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT  2
20 +#define  BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK   0x00007000
21 +#define  BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT  12
22 +#define BCMA_DMU_CRU_CLKSET_KEY                                0x0180
23 +#define BCMA_DMU_CRU_STRAPS_CTRL                       0x02A0
24 +#define  BCMA_DMU_CRU_STRAPS_CTRL_USB3                 0x00000010
25 +#define  BCMA_DMU_CRU_STRAPS_CTRL_4BYTE                        0x00008000
26 +
27  MODULE_AUTHOR("Hauke Mehrtens");
28  MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
29  MODULE_LICENSE("GPL");
30 @@ -167,10 +178,35 @@ static void bcma_hcd_init_chip_mips(struct bcma_device *dev)
31         }
32  }
33  
34 +static u32 bcma_hcd_usb_ref_clk_get_rate(void __iomem *dmu)
35 +{
36 +       u32 val, ndiv, pdiv, ch2_mdiv, ch2_freq;
37 +
38 +       /* get divider integer from the cru_genpll_control5 */
39 +       val = ioread32(dmu + 0x154);
40 +       ndiv = (val >> 20) & 0x3ff;
41 +       if (ndiv == 0)
42 +               ndiv = 1 << 10;
43 +
44 +       /* get pdiv and ch2_mdiv from the cru_genpll_control6 */
45 +       val = ioread32(dmu + 0x158);
46 +       pdiv = (val >> 24) & 0x7;
47 +       pdiv = (pdiv == 0) ? (1 << 3) : pdiv;
48 +
49 +       ch2_mdiv = val & 0xff;
50 +       ch2_mdiv = (ch2_mdiv == 0) ? (1 << 8) : ch2_mdiv;
51 +
52 +       /* calculate ch2_freq based on 25MHz reference clock */
53 +       ch2_freq = (25000000 / (pdiv * ch2_mdiv)) * ndiv;
54 +
55 +       return ch2_freq;
56 +}
57 +
58  static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev)
59  {
60         struct bcma_device *arm_core;
61         void __iomem *dmu;
62 +       u32 ref_clk_rate, usb2ctl, usb_pll_ndiv, usb_pll_pdiv;
63  
64         arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9);
65         if (!arm_core) {
66 @@ -184,14 +220,29 @@ static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev)
67                 return;
68         }
69  
70 +       ref_clk_rate = bcma_hcd_usb_ref_clk_get_rate(dmu);
71 +
72 +       usb2ctl = ioread32(dmu + BCMA_DMU_CRU_USB2_CONTROL);
73 +
74 +       usb_pll_pdiv = usb2ctl;
75 +       usb_pll_pdiv &= BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK;
76 +       usb_pll_pdiv >>= BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT;
77 +       if (!usb_pll_pdiv)
78 +               usb_pll_pdiv = 1 << 3;
79 +
80 +       /* Calculate ndiv based on a solid 1920 MHz that is for USB2 PHY */
81 +       usb_pll_ndiv = (1920000000 * usb_pll_pdiv) / ref_clk_rate;
82 +
83         /* Unlock DMU PLL settings */
84 -       iowrite32(0x0000ea68, dmu + 0x180);
85 +       iowrite32(0x0000ea68, dmu + BCMA_DMU_CRU_CLKSET_KEY);
86  
87         /* Write USB 2.0 PLL control setting */
88 -       iowrite32(0x00dd10c3, dmu + 0x164);
89 +       usb2ctl &= ~BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK;
90 +       usb2ctl |= usb_pll_ndiv << BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT;
91 +       iowrite32(usb2ctl, dmu + BCMA_DMU_CRU_USB2_CONTROL);
92  
93         /* Lock DMU PLL settings */
94 -       iowrite32(0x00000000, dmu + 0x180);
95 +       iowrite32(0x00000000, dmu + BCMA_DMU_CRU_CLKSET_KEY);
96  
97         iounmap(dmu);
98  }
99 @@ -219,15 +270,17 @@ static void bcma_hcd_init_chip_arm_hc(struct bcma_device *dev)
100  
101  static void bcma_hcd_init_chip_arm(struct bcma_device *dev)
102  {
103 +       struct bcma_chipinfo *chipinfo = &dev->bus->chipinfo;
104 +
105         bcma_core_enable(dev, 0);
106  
107 -       if (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4707 ||
108 -           dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM53018) {
109 -               if (dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4707 ||
110 -                   dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4708)
111 -                       bcma_hcd_init_chip_arm_phy(dev);
112 +       if (chipinfo->id == BCMA_CHIP_ID_BCM4707 ||
113 +           chipinfo->id == BCMA_CHIP_ID_BCM47094 ||
114 +           chipinfo->id == BCMA_CHIP_ID_BCM53018) {
115 +               bcma_hcd_init_chip_arm_phy(dev);
116  
117 -               bcma_hcd_init_chip_arm_hc(dev);
118 +               if (1) /* TODO: Exclude BCM53573 */
119 +                       bcma_hcd_init_chip_arm_hc(dev);
120         }
121  }
122