[U-Boot] [PATCH 4/6] mips: ath79: Add support for ungating USB and ethernet on qca953x

Add code to ungate USB and ethernet controller on qca953x
Signed-off-by: Wills Wang wills.wang@live.com ---
arch/mips/mach-ath79/reset.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c index 33bf979..a5ee141 100644 --- a/arch/mips/mach-ath79/reset.c +++ b/arch/mips/mach-ath79/reset.c @@ -136,6 +136,23 @@ static int eth_init_ar934x(void) return 0; }
+static int eth_init_qca953x(void) +{ + void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE, + MAP_NOCACHE); + const u32 mask = QCA953X_RESET_GE0_MAC | QCA953X_RESET_GE0_MDIO | + QCA953X_RESET_GE1_MAC | QCA953X_RESET_GE1_MDIO | + QCA953X_RESET_ETH_SWITCH_ANALOG | + QCA953X_RESET_ETH_SWITCH; + + setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + + return 0; +} + int ath79_eth_reset(void) { /* @@ -146,6 +163,8 @@ int ath79_eth_reset(void) return eth_init_ar933x(); if (soc_is_ar934x()) return eth_init_ar934x(); + if (soc_is_qca953x()) + return eth_init_qca953x();
return -EINVAL; } @@ -185,6 +204,35 @@ static int usb_reset_ar934x(void __iomem *reset_regs) return 0; }
+static int usb_reset_qca953x(void __iomem *reset_regs) +{ + void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE, + MAP_NOCACHE); + + clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG, + 0xf00, 0x200); + mdelay(10); + + /* Ungate the USB block */ + setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USBSUS_OVERRIDE); + mdelay(1); + clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USB_PHY); + mdelay(1); + clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USB_PHY_ANALOG); + mdelay(1); + clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USB_HOST); + mdelay(1); + clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USB_PHY_PLL_PWD_EXT); + mdelay(1); + + return 0; +} + int ath79_usb_reset(void) { void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE, @@ -204,6 +252,8 @@ int ath79_usb_reset(void) return usb_reset_ar933x(reset_regs); if (soc_is_ar934x()) return usb_reset_ar934x(reset_regs); + if (soc_is_qca953x()) + return usb_reset_qca953x(reset_regs);
return -EINVAL; }

On 05/30/2016 04:54 PM, Wills Wang wrote:
Add code to ungate USB and ethernet controller on qca953x
Is this code coming from mainline Linux ?
Signed-off-by: Wills Wang wills.wang@live.com
arch/mips/mach-ath79/reset.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c index 33bf979..a5ee141 100644 --- a/arch/mips/mach-ath79/reset.c +++ b/arch/mips/mach-ath79/reset.c @@ -136,6 +136,23 @@ static int eth_init_ar934x(void) return 0; }
+static int eth_init_qca953x(void) +{
- void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
MAP_NOCACHE);
- const u32 mask = QCA953X_RESET_GE0_MAC | QCA953X_RESET_GE0_MDIO |
QCA953X_RESET_GE1_MAC | QCA953X_RESET_GE1_MDIO |
QCA953X_RESET_ETH_SWITCH_ANALOG |
QCA953X_RESET_ETH_SWITCH;
- setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
- mdelay(1);
- clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
- mdelay(1);
- return 0;
+}
int ath79_eth_reset(void) { /* @@ -146,6 +163,8 @@ int ath79_eth_reset(void) return eth_init_ar933x(); if (soc_is_ar934x()) return eth_init_ar934x();
if (soc_is_qca953x())
return eth_init_qca953x();
return -EINVAL;
} @@ -185,6 +204,35 @@ static int usb_reset_ar934x(void __iomem *reset_regs) return 0; }
+static int usb_reset_qca953x(void __iomem *reset_regs) +{
- void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
MAP_NOCACHE);
- clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
0xf00, 0x200);
- mdelay(10);
- /* Ungate the USB block */
- setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USBSUS_OVERRIDE);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_ANALOG);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_HOST);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_PLL_PWD_EXT);
- mdelay(1);
- return 0;
+}
int ath79_usb_reset(void) { void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE, @@ -204,6 +252,8 @@ int ath79_usb_reset(void) return usb_reset_ar933x(reset_regs); if (soc_is_ar934x()) return usb_reset_ar934x(reset_regs);
if (soc_is_qca953x())
return usb_reset_qca953x(reset_regs);
return -EINVAL;
}

On 05/30/2016 11:18 PM, Marek Vasut wrote:
On 05/30/2016 04:54 PM, Wills Wang wrote:
Add code to ungate USB and ethernet controller on qca953x
Is this code coming from mainline Linux ?
No, i refer to u-boot code from QSDK.
Signed-off-by: Wills Wang wills.wang@live.com
arch/mips/mach-ath79/reset.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c index 33bf979..a5ee141 100644 --- a/arch/mips/mach-ath79/reset.c +++ b/arch/mips/mach-ath79/reset.c @@ -136,6 +136,23 @@ static int eth_init_ar934x(void) return 0; }
+static int eth_init_qca953x(void) +{
- void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
MAP_NOCACHE);
- const u32 mask = QCA953X_RESET_GE0_MAC | QCA953X_RESET_GE0_MDIO |
QCA953X_RESET_GE1_MAC | QCA953X_RESET_GE1_MDIO |
QCA953X_RESET_ETH_SWITCH_ANALOG |
QCA953X_RESET_ETH_SWITCH;
- setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
- mdelay(1);
- clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
- mdelay(1);
- return 0;
+}
- int ath79_eth_reset(void) { /*
@@ -146,6 +163,8 @@ int ath79_eth_reset(void) return eth_init_ar933x(); if (soc_is_ar934x()) return eth_init_ar934x();
if (soc_is_qca953x())
return eth_init_qca953x();
return -EINVAL; }
@@ -185,6 +204,35 @@ static int usb_reset_ar934x(void __iomem *reset_regs) return 0; }
+static int usb_reset_qca953x(void __iomem *reset_regs) +{
- void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
MAP_NOCACHE);
- clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
0xf00, 0x200);
- mdelay(10);
- /* Ungate the USB block */
- setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USBSUS_OVERRIDE);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_ANALOG);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_HOST);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_PLL_PWD_EXT);
- mdelay(1);
- return 0;
+}
- int ath79_usb_reset(void) { void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
@@ -204,6 +252,8 @@ int ath79_usb_reset(void) return usb_reset_ar933x(reset_regs); if (soc_is_ar934x()) return usb_reset_ar934x(reset_regs);
if (soc_is_qca953x())
return usb_reset_qca953x(reset_regs);
return -EINVAL; }

On 05/31/2016 02:35 AM, Wills Wang wrote:
On 05/30/2016 11:18 PM, Marek Vasut wrote:
On 05/30/2016 04:54 PM, Wills Wang wrote:
Add code to ungate USB and ethernet controller on qca953x
Is this code coming from mainline Linux ?
No, i refer to u-boot code from QSDK.
Oh ok. I'd suggest to pick the code from mainline Linux when possible, it's far more maintained than the ancient LSDK/QSDK.
Signed-off-by: Wills Wang wills.wang@live.com
arch/mips/mach-ath79/reset.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c index 33bf979..a5ee141 100644 --- a/arch/mips/mach-ath79/reset.c +++ b/arch/mips/mach-ath79/reset.c @@ -136,6 +136,23 @@ static int eth_init_ar934x(void) return 0; } +static int eth_init_qca953x(void) +{
- void __iomem *rregs = map_physmem(AR71XX_RESET_BASE,
AR71XX_RESET_SIZE,
MAP_NOCACHE);
- const u32 mask = QCA953X_RESET_GE0_MAC | QCA953X_RESET_GE0_MDIO |
QCA953X_RESET_GE1_MAC | QCA953X_RESET_GE1_MDIO |
QCA953X_RESET_ETH_SWITCH_ANALOG |
QCA953X_RESET_ETH_SWITCH;
- setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
- mdelay(1);
- clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
- mdelay(1);
- return 0;
+}
- int ath79_eth_reset(void) { /*
@@ -146,6 +163,8 @@ int ath79_eth_reset(void) return eth_init_ar933x(); if (soc_is_ar934x()) return eth_init_ar934x();
- if (soc_is_qca953x())
}return eth_init_qca953x(); return -EINVAL;
@@ -185,6 +204,35 @@ static int usb_reset_ar934x(void __iomem *reset_regs) return 0; } +static int usb_reset_qca953x(void __iomem *reset_regs) +{
- void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
MAP_NOCACHE);
- clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
0xf00, 0x200);
Do you know what these magic numbers mean ?
- mdelay(10);
- /* Ungate the USB block */
- setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USBSUS_OVERRIDE);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_ANALOG);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_HOST);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_PLL_PWD_EXT);
- mdelay(1);
- return 0;
+}
- int ath79_usb_reset(void) { void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
@@ -204,6 +252,8 @@ int ath79_usb_reset(void) return usb_reset_ar933x(reset_regs); if (soc_is_ar934x()) return usb_reset_ar934x(reset_regs);
- if (soc_is_qca953x())
}return usb_reset_qca953x(reset_regs); return -EINVAL;

Hello,
2016-05-31 2:51 GMT+02:00 Marek Vasut marex@denx.de:
On 05/31/2016 02:35 AM, Wills Wang wrote:
[snip]
+static int usb_reset_qca953x(void __iomem *reset_regs) +{
- void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
MAP_NOCACHE);
- clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
0xf00, 0x200);
Do you know what these magic numbers mean ?
I can help here.
This register is common for (almost) all modern QC/A WiSOCs, with similar structure, at least for AR934x, QCA953x, QCA955x and QCA956x (please take a look at [1]). I have seen it (SDK, datasheets) under two different names: SWITCH_CLOCK_SPARE and SWITCH_CLOCK_CONTROL, on different addresses (offset +/- 1), depending on the SOC.
The bit field [8:11] is "USB_REFCLK_FREQ_SEL" and it's the same for all above SOCs. Value (dec) 2 is for 25 MHz, value 5 for 40 MHz.
I'm going to provide some patches for ath79 in future, which will make code more universal for all QC/A WiSOCs.
-- Regards, Piotr Dymacz
[1] http://postimg.org/image/tyrkhkw57/full/
- mdelay(10);
- /* Ungate the USB block */
- setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USBSUS_OVERRIDE);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_ANALOG);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_HOST);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_PLL_PWD_EXT);
- mdelay(1);
- return 0;
+}
- int ath79_usb_reset(void) { void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
@@ -204,6 +252,8 @@ int ath79_usb_reset(void) return usb_reset_ar933x(reset_regs); if (soc_is_ar934x()) return usb_reset_ar934x(reset_regs);
- if (soc_is_qca953x())
}return usb_reset_qca953x(reset_regs); return -EINVAL;
-- Best regards, Marek Vasut _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 05/31/2016 10:50 AM, Piotr Dymacz wrote:
Hello,
2016-05-31 2:51 GMT+02:00 Marek Vasut marex@denx.de:
On 05/31/2016 02:35 AM, Wills Wang wrote:
[snip]
+static int usb_reset_qca953x(void __iomem *reset_regs) +{
- void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
MAP_NOCACHE);
- clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
0xf00, 0x200);
Do you know what these magic numbers mean ?
I can help here.
This register is common for (almost) all modern QC/A WiSOCs, with similar structure, at least for AR934x, QCA953x, QCA955x and QCA956x (please take a look at [1]). I have seen it (SDK, datasheets) under two different names: SWITCH_CLOCK_SPARE and SWITCH_CLOCK_CONTROL, on different addresses (offset +/- 1), depending on the SOC.
The bit field [8:11] is "USB_REFCLK_FREQ_SEL" and it's the same for all above SOCs. Value (dec) 2 is for 25 MHz, value 5 for 40 MHz.
I'm going to provide some patches for ath79 in future, which will make code more universal for all QC/A WiSOCs.
Oh, very cool, thanks!

On 05/31/2016 04:50 PM, Piotr Dymacz wrote:
Hello,
2016-05-31 2:51 GMT+02:00 Marek Vasut marex@denx.de:
On 05/31/2016 02:35 AM, Wills Wang wrote:
[snip]
+static int usb_reset_qca953x(void __iomem *reset_regs) +{
- void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
MAP_NOCACHE);
- clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
0xf00, 0x200);
Do you know what these magic numbers mean ?
I can help here.
This register is common for (almost) all modern QC/A WiSOCs, with similar structure, at least for AR934x, QCA953x, QCA955x and QCA956x (please take a look at [1]). I have seen it (SDK, datasheets) under two different names: SWITCH_CLOCK_SPARE and SWITCH_CLOCK_CONTROL, on different addresses (offset +/- 1), depending on the SOC.
The bit field [8:11] is "USB_REFCLK_FREQ_SEL" and it's the same for all above SOCs. Value (dec) 2 is for 25 MHz, value 5 for 40 MHz.
You are right, i found the same description in ar9341 data sheet.
I'm going to provide some patches for ath79 in future, which will make code more universal for all QC/A WiSOCs.
You are always welcome.
-- Regards, Piotr Dymacz
[1] http://postimg.org/image/tyrkhkw57/full/
- mdelay(10);
- /* Ungate the USB block */
- setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USBSUS_OVERRIDE);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_ANALOG);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_HOST);
- mdelay(1);
- clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
QCA953X_RESET_USB_PHY_PLL_PWD_EXT);
- mdelay(1);
- return 0;
+}
- int ath79_usb_reset(void) { void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
@@ -204,6 +252,8 @@ int ath79_usb_reset(void) return usb_reset_ar933x(reset_regs); if (soc_is_ar934x()) return usb_reset_ar934x(reset_regs);
- if (soc_is_qca953x())
}return usb_reset_qca953x(reset_regs); return -EINVAL;
-- Best regards, Marek Vasut _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Am 30.05.2016 um 16:54 schrieb Wills Wang:
Add code to ungate USB and ethernet controller on qca953x
Signed-off-by: Wills Wang wills.wang@live.com
arch/mips/mach-ath79/reset.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
applied to u-boot-mips, thanks!
participants (4)
-
Daniel Schwierzeck
-
Marek Vasut
-
Piotr Dymacz
-
Wills Wang