bcm63xx: kernel: power cycle the bcm6358 USB PLL
authorDaniel González Cabanelas <dgcbueu@gmail.com>
Mon, 19 Dec 2022 14:25:30 +0000 (15:25 +0100)
committerÁlvaro Fernández Rojas <noltari@gmail.com>
Sat, 4 Mar 2023 19:09:49 +0000 (20:09 +0100)
Some BCM6358 based boards may detect USB2.0 high speed devices as USB1.1
full speed. This is an old well known bug, but nobody cared about it. It
is quite random and hard to track.

With the latest versions of Openwrt, one user confirmed that the bug is
still there (tested router: HG556a).

Power cycle the USB PLL to fix it.

Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
target/linux/bcm63xx/patches-5.15/393-bcm6358-power-cycle-usb-pll.patch [new file with mode: 0644]
target/linux/bcm63xx/patches-5.15/411-MIPS-BCM63XX-Register-SPI-flash-if-present.patch
target/linux/bcm63xx/patches-5.15/430-MIPS-BCM63XX-add-nand-clocks.patch
target/linux/bcm63xx/patches-5.15/431-MIPS-BCM63XX-add-nand-rset.patch

diff --git a/target/linux/bcm63xx/patches-5.15/393-bcm6358-power-cycle-usb-pll.patch b/target/linux/bcm63xx/patches-5.15/393-bcm6358-power-cycle-usb-pll.patch
new file mode 100644 (file)
index 0000000..43b82bc
--- /dev/null
@@ -0,0 +1,47 @@
+--- a/arch/mips/bcm63xx/clk.c
++++ b/arch/mips/bcm63xx/clk.c
+@@ -258,6 +258,8 @@ static struct clk clk_pcm = {
+  */
+ static void usbh_set(struct clk *clk, int enable)
+ {
++      u32 reg;
++
+       if (BCMCPU_IS_6318()) {
+               bcm_hwclock_set(CKCTL_6318_USB_EN, enable);
+               bcm_ub_hwclock_set(UB_CKCTL_6318_USB_EN, enable);
+@@ -265,13 +267,19 @@ static void usbh_set(struct clk *clk, in
+               bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
+       } else if (BCMCPU_IS_6348()) {
+               bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
++      } else if (BCMCPU_IS_6358()) {
++              /* power cycle the USB PLL */
++              reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_PLL_CTRL_6358_REG);
++              reg &= ~USBH_PRIV_PLL_CTRL_6358_EN;
++              bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_PLL_CTRL_6358_REG);
++              mdelay(1);
++              reg |= USBH_PRIV_PLL_CTRL_6358_EN;
++              bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_PLL_CTRL_6358_REG);
+       } else if (BCMCPU_IS_6362()) {
+               bcm_hwclock_set(CKCTL_6362_USBH_EN, enable);
+       } else if (BCMCPU_IS_6368()) {
+               bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
+       } else if (BCMCPU_IS_63268()) {
+-              u32 reg;
+-
+               bcm_hwclock_set(CKCTL_63268_USBH_EN, enable);
+               bcm_misc_iddq_set(IDDQ_CTRL_63268_USBH, enable);
+               bcm63xx_core_set_reset(BCM63XX_RESET_USBH, !enable);
+--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+@@ -1043,9 +1043,11 @@
+ #define USBH_PRIV_SETUP_IPP_MASK      (1 << USBH_PRIV_SETUP_IPP_SHIFT)
+ #define USBH_PRIV_SETUP_6318_REG      0x00
++#define USBH_PRIV_PLL_CTRL_6358_REG   0x0c
+ #define USBH_PRIV_PLL_CTRL1_6368_REG  0x18
+ #define USBH_PRIV_PLL_CTRL1_6318_REG  0x04
++#define USBH_PRIV_PLL_CTRL_6358_EN            (1 << 25)
+ #define USBH_PRIV_PLL_CTRL1_6318_SUSP_EN      (1 << 27)
+ #define USBH_PRIV_PLL_CTRL1_6318_IDDQ_PWRDN   (1 << 31)
+ #define USBH_PRIV_PLL_CTRL1_63268_IDDQ_PWRDN  (1 << 9)
index c2738c15e508129ef4bebead49241144aab5596e..364e7005338d2ac98640bc8ce4cef44bb21ffc34 100644 (file)
@@ -146,7 +146,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
  #define STRAPBUS_6368_BOOT_SEL_MASK   0x3
  #define STRAPBUS_6368_BOOT_SEL_NAND   0
  #define STRAPBUS_6368_BOOT_SEL_SERIAL 1
-@@ -1570,6 +1571,7 @@
+@@ -1572,6 +1573,7 @@
  #define IDDQ_CTRL_63268_USBH          (1 << 4)
  
  #define MISC_STRAPBUS_6328_REG                0x240
index 4106aa0ded6b0088c899dc92d9f132db3f89f3c0..432c2251761fe1bd89af4f65bf05d2f2f0e5522b 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/mips/bcm63xx/clk.c
 +++ b/arch/mips/bcm63xx/clk.c
-@@ -444,6 +444,23 @@ static struct clk clk_pcie = {
+@@ -452,6 +452,23 @@ static struct clk clk_pcie = {
  };
  
  /*
@@ -24,7 +24,7 @@
   * Internal peripheral clock
   */
  static struct clk clk_periph = {
-@@ -640,6 +657,7 @@ static struct clk_lookup bcm6362_clks[]
+@@ -648,6 +665,7 @@ static struct clk_lookup bcm6362_clks[]
        CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
        CLKDEV_INIT("10001000.spi", "pll", &clk_hsspi_pll),
        /* gated clocks */
@@ -32,7 +32,7 @@
        CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
        CLKDEV_INIT(NULL, "usbh", &clk_usbh),
        CLKDEV_INIT(NULL, "usbd", &clk_usbd),
-@@ -657,6 +675,7 @@ static struct clk_lookup bcm6368_clks[]
+@@ -665,6 +683,7 @@ static struct clk_lookup bcm6368_clks[]
        CLKDEV_INIT("10000100.serial", "refclk", &clk_periph),
        CLKDEV_INIT("10000120.serial", "refclk", &clk_periph),
        /* gated clocks */
@@ -40,7 +40,7 @@
        CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
        CLKDEV_INIT(NULL, "usbh", &clk_usbh),
        CLKDEV_INIT(NULL, "usbd", &clk_usbd),
-@@ -675,6 +694,7 @@ static struct clk_lookup bcm63268_clks[]
+@@ -683,6 +702,7 @@ static struct clk_lookup bcm63268_clks[]
        CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
        CLKDEV_INIT("10001000.spi", "pll", &clk_hsspi_pll),
        /* gated clocks */
index 3035be35aef39b02625ffe20fc8af4deaaaffaa2..75eea3a66c26e13408e6fa6e9180e94beb628fc3 100644 (file)
  #endif /* ! BCM63XX_IO_H_ */
 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
-@@ -1693,4 +1693,31 @@
+@@ -1695,4 +1695,31 @@
  #define OTP_USER_BITS_6328_REG(i)     (0x20 + (i) * 4)
  #define   OTP_6328_REG3_TP1_DISABLED  BIT(9)