bcm63xx: kernel: power cycle the bcm6358 USB PLL

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>
This commit is contained in:
Daniel González Cabanelas 2022-12-19 15:25:30 +01:00 committed by Álvaro Fernández Rojas
parent e55b4b436e
commit 796815eb53
4 changed files with 53 additions and 6 deletions

View File

@ -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)

View 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

View 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 */

View File

@ -111,7 +111,7 @@
#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)