[openwrt/openwrt] bcm4908: backport brcmstb USB PHY driver changes

LEDE Commits lede-commits at lists.infradead.org
Thu Jan 14 06:34:47 EST 2021


rmilecki pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/6c90999e2e0dee6e5e0322b89e8e6fb6f76aecc9

commit 6c90999e2e0dee6e5e0322b89e8e6fb6f76aecc9
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Thu Jan 14 12:13:49 2021 +0100

    bcm4908: backport brcmstb USB PHY driver changes
    
    This includes BCM4908 support
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 target/linux/bcm4908/config-5.4                    |   3 +
 ...phy-brcm-usb-init-fix-__iomem-annotations.patch | 286 +++++++++
 ...cm-usb-init-fix-use-of-integer-as-pointer.patch |  26 +
 ...I-DMA-may-lose-a-burst-of-DMA-data-for-72.patch |  61 ++
 ...-all-drivers-that-use-USB-clks-using-corr.patch | 102 ++++
 ...-USB-phys-into-IDDQ-on-suspend-to-save-po.patch |  51 ++
 ....6-0004-phy-usb-Add-wake-on-functionality.patch | 205 +++++++
 ...tructure-in-preparation-for-adding-7216-U.patch | 611 ++++++++++++++++++
 ...-Add-Broadcom-STB-USB-PHY-binding-documen.patch | 108 ++++
 ...-support-for-new-Synopsys-USB-controller-.patch | 358 +++++++++++
 ...-support-for-new-Synopsys-USB-controller-.patch | 680 +++++++++++++++++++++
 ...-usb-fix-driver-to-defer-on-clk_get-defer.patch |  44 ++
 ...-s-MDIO-registers-not-accessible-without-.patch |  44 ++
 ...c-Fix-occasional-failure-with-BDC-on-7211.patch | 135 ++++
 ...-driver-is-crashing-during-S3-resume-on-7.patch |  26 +
 ...-support-for-wake-and-USB-low-power-mode-.patch | 328 ++++++++++
 ...-phy-phy-brcm-usb-Constify-static-structs.patch |  99 +++
 ...brcm-usb-improve-getting-OF-matching-data.patch |  49 ++
 ...m-usb-specify-init-function-format-at-str.patch |  50 ++
 ...-phy-brcm-brcmstb-usb-phy-convert-to-the-.patch | 315 ++++++++++
 ...-phy-brcm-brcmstb-usb-phy-add-BCM4908-bin.patch |  41 ++
 ...y-phy-brcm-usb-support-PHY-on-the-BCM4908.patch |  48 ++
 ...rcmstb-add-stubs-for-getting-platform-IDs.patch |  50 ++
 ...cm-usb-select-SOC_BRCMSTB-on-brcmstb-only.patch |  26 +
 24 files changed, 3746 insertions(+)

diff --git a/target/linux/bcm4908/config-5.4 b/target/linux/bcm4908/config-5.4
index 6998cdcaf0..9991afda15 100644
--- a/target/linux/bcm4908/config-5.4
+++ b/target/linux/bcm4908/config-5.4
@@ -89,6 +89,7 @@ CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
 CONFIG_GENERIC_MSI_IRQ=y
 CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
 CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
 CONFIG_GENERIC_SCHED_CLOCK=y
 CONFIG_GENERIC_SMP_IDLE_THREAD=y
 CONFIG_GENERIC_STRNCPY_FROM_USER=y
@@ -156,6 +157,7 @@ CONFIG_PGTABLE_LEVELS=3
 CONFIG_PHYLIB=y
 CONFIG_PHYLINK=y
 CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_PHY_BRCM_USB=y
 CONFIG_PM=y
 CONFIG_PM_CLK=y
 CONFIG_PM_GENERIC_DOMAINS=y
@@ -193,6 +195,7 @@ CONFIG_TIMER_PROBE=y
 CONFIG_TREE_RCU=y
 CONFIG_TREE_SRCU=y
 CONFIG_UNMAP_KERNEL_AT_EL0=y
+CONFIG_USB_SUPPORT=y
 CONFIG_VMAP_STACK=y
 CONFIG_XPS=y
 CONFIG_ZONE_DMA32=y
diff --git a/target/linux/bcm4908/patches-5.4/083-v5.5-0001-phy-phy-brcm-usb-init-fix-__iomem-annotations.patch b/target/linux/bcm4908/patches-5.4/083-v5.5-0001-phy-phy-brcm-usb-init-fix-__iomem-annotations.patch
new file mode 100644
index 0000000000..90f6224386
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/083-v5.5-0001-phy-phy-brcm-usb-init-fix-__iomem-annotations.patch
@@ -0,0 +1,286 @@
+From e4b957d3a7c74749e2ccfb3dedb63b81e84b292c Mon Sep 17 00:00:00 2001
+From: Ben Dooks <ben.dooks at codethink.co.uk>
+Date: Tue, 15 Oct 2019 17:03:31 +0100
+Subject: [PATCH] phy: phy-brcm-usb-init: fix __iomem annotations
+
+The register address should have __iomem attributes
+so fix this to remove the following sparse warnings:
+
+drivers/phy/broadcom/phy-brcm-usb-init.c:459:30: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:459:30: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:459:30:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:459:30:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:461:30: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:461:30: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:461:30:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:461:30:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:465:30: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:465:30: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:465:30:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:465:30:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:469:30: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:469:30: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:469:30:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:469:30:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:478:30: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:478:30: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:478:30:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:478:30:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:480:30: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:480:30: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:480:30:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:480:30:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:485:30: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:485:30: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:485:30:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:485:30:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:494:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:494:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:494:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:494:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:495:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:495:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:495:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:495:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:498:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:498:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:498:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:498:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:501:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:501:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:501:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:501:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:613:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:613:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:613:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:613:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:640:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:640:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:640:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:640:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:710:64: warning: Using plain integer as NULL pointer
+drivers/phy/broadcom/phy-brcm-usb-init.c:712:32: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:712:32: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:712:32:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:712:32:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:713:29: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:713:29: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:713:29:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:713:29:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:717:29: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:717:29: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:717:29:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:717:29:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:720:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:720:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:720:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:720:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:721:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:721:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:721:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:721:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:794:29: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:794:29: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:794:29:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:794:29:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:813:29: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:813:29: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:813:29:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:813:29:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:829:37: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:829:37: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:829:37:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:829:37:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:843:37: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:843:37: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:843:37:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:843:37:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:847:37: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:847:37: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:847:37:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:847:37:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:878:9: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:878:9: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:878:9:    expected void [noderef] <asn:2> *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:878:9:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:880:29: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:880:29: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:880:29:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:880:29:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:896:29: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:896:29: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:896:29:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:896:29:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:901:37: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:901:37: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:901:37:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:901:37:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:905:37: warning: cast removes address space '<asn:2>' of expression
+drivers/phy/broadcom/phy-brcm-usb-init.c:905:37: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:905:37:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:905:37:    got void *
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:423:52:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13: warning: incorrect type in assignment (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    expected void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:434:13:    got void [noderef] <asn:2> *
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38: warning: incorrect type in argument 1 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:38:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51: warning: incorrect type in argument 2 (different address spaces)
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    expected void [noderef] <asn:2> *addr
+drivers/phy/broadcom/phy-brcm-usb-init.c:435:51:    got void *reg
+drivers/phy/broadcom/phy-brcm-usb-init.c:422:13: warning: too many warnings
+
+Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb-init.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
+@@ -126,8 +126,8 @@ enum {
+ 	USB_CTRL_SELECTOR_COUNT,
+ };
+ 
+-#define USB_CTRL_REG(base, reg)	((void *)base + USB_CTRL_##reg)
+-#define USB_XHCI_EC_REG(base, reg) ((void *)base + USB_XHCI_EC_##reg)
++#define USB_CTRL_REG(base, reg)	((void __iomem *)base + USB_CTRL_##reg)
++#define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
+ #define USB_CTRL_MASK(reg, field) \
+ 	USB_CTRL_##reg##_##field##_MASK
+ #define USB_CTRL_MASK_FAMILY(params, reg, field)			\
+@@ -416,7 +416,7 @@ void usb_ctrl_unset_family(struct brcm_u
+ 			   u32 reg_offset, u32 field)
+ {
+ 	u32 mask;
+-	void *reg;
++	void __iomem *reg;
+ 
+ 	mask = params->usb_reg_bits_map[field];
+ 	reg = params->ctrl_regs + reg_offset;
+@@ -428,7 +428,7 @@ void usb_ctrl_set_family(struct brcm_usb
+ 			 u32 reg_offset, u32 field)
+ {
+ 	u32 mask;
+-	void *reg;
++	void __iomem *reg;
+ 
+ 	mask = params->usb_reg_bits_map[field];
+ 	reg = params->ctrl_regs + reg_offset;
diff --git a/target/linux/bcm4908/patches-5.4/083-v5.5-0002-phy-phy-brcm-usb-init-fix-use-of-integer-as-pointer.patch b/target/linux/bcm4908/patches-5.4/083-v5.5-0002-phy-phy-brcm-usb-init-fix-use-of-integer-as-pointer.patch
new file mode 100644
index 0000000000..9252c35fb9
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/083-v5.5-0002-phy-phy-brcm-usb-init-fix-use-of-integer-as-pointer.patch
@@ -0,0 +1,26 @@
+From 1025cb924bd517f3c458f36973582d4c2adedd6a Mon Sep 17 00:00:00 2001
+From: Ben Dooks <ben.dooks at codethink.co.uk>
+Date: Tue, 15 Oct 2019 17:03:32 +0100
+Subject: [PATCH] phy: phy-brcm-usb-init: fix use of integer as pointer
+
+The xhci_ec_base variable is a pointer, so don't compare
+it with an integer.
+
+Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
+Reviewed-by: Andrew Murray <andrew.murray at arm.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb-init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
+@@ -707,7 +707,7 @@ static void brcmusb_usb3_otp_fix(struct
+ 	void __iomem *xhci_ec_base = params->xhci_ec_regs;
+ 	u32 val;
+ 
+-	if (params->family_id != 0x74371000 || xhci_ec_base == 0)
++	if (params->family_id != 0x74371000 || !xhci_ec_base)
+ 		return;
+ 	brcmusb_writel(0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR));
+ 	val = brcmusb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0001-phy-usb-EHCI-DMA-may-lose-a-burst-of-DMA-data-for-72.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0001-phy-usb-EHCI-DMA-may-lose-a-burst-of-DMA-data-for-72.patch
new file mode 100644
index 0000000000..ac368d5dd1
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0001-phy-usb-EHCI-DMA-may-lose-a-burst-of-DMA-data-for-72.patch
@@ -0,0 +1,61 @@
+From dc9aa43c43668481089c48135707ec3f8f5b2e19 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:17:59 -0500
+Subject: [PATCH] phy: usb: EHCI DMA may lose a burst of DMA data for 7255xA0
+ family
+
+When the EHCI controller received a 512 byte USB packet that
+had to be broken into 2 256 byte bursts across the SCB bus AND
+there was a following 512 byte USB packet, the second burst of
+data from the first packet was sometimes being lost. If the
+burst size was changed to 128 bytes via the EBR_SCB_SIZE field
+in the USB_CTRL_EBRIDGE register we'd see the 4th 128 byte burst
+of the first packet being lost. This problem became much worse
+if other threads were running that accessed memory, like a memcpy
+test. Setting the EBR_SCB_SIZE to 512, which prevents breaking
+the EHCI USB packet (max size of 512 bytes) into bursts, fixed
+the problem.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb-init.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
+@@ -42,6 +42,7 @@
+ #define   USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK		0x80000000 /* option */
+ #define USB_CTRL_EBRIDGE		0x0c
+ #define   USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK		0x00020000 /* option */
++#define   USB_CTRL_EBRIDGE_EBR_SCB_SIZE_MASK		0x00000f80 /* option */
+ #define USB_CTRL_OBRIDGE		0x10
+ #define   USB_CTRL_OBRIDGE_LS_KEEP_ALIVE_MASK		0x08000000
+ #define USB_CTRL_MDIO			0x14
+@@ -176,6 +177,7 @@ static const struct id_to_type id_to_typ
+ 	{ 0x33900000, BRCM_FAMILY_3390A0 },
+ 	{ 0x72500010, BRCM_FAMILY_7250B0 },
+ 	{ 0x72600000, BRCM_FAMILY_7260A0 },
++	{ 0x72550000, BRCM_FAMILY_7260A0 },
+ 	{ 0x72680000, BRCM_FAMILY_7271A0 },
+ 	{ 0x72710000, BRCM_FAMILY_7271A0 },
+ 	{ 0x73640000, BRCM_FAMILY_7364A0 },
+@@ -948,6 +950,17 @@ void brcm_usb_init_eohci(struct brcm_usb
+ 	if (params->selected_family == BRCM_FAMILY_7271A0)
+ 		/* Enable LS keep alive fix for certain keyboards */
+ 		USB_CTRL_SET(ctrl, OBRIDGE, LS_KEEP_ALIVE);
++
++	if (params->family_id == 0x72550000) {
++		/*
++		 * Make the burst size 512 bytes to fix a hardware bug
++		 * on the 7255a0. See HW7255-24.
++		 */
++		reg = brcmusb_readl(USB_CTRL_REG(ctrl, EBRIDGE));
++		reg &= ~USB_CTRL_MASK(EBRIDGE, EBR_SCB_SIZE);
++		reg |= 0x800;
++		brcmusb_writel(reg, USB_CTRL_REG(ctrl, EBRIDGE));
++	}
+ }
+ 
+ void brcm_usb_init_xhci(struct brcm_usb_init_params *params)
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0002-phy-usb-Get-all-drivers-that-use-USB-clks-using-corr.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0002-phy-usb-Get-all-drivers-that-use-USB-clks-using-corr.patch
new file mode 100644
index 0000000000..e269f80cf4
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0002-phy-usb-Get-all-drivers-that-use-USB-clks-using-corr.patch
@@ -0,0 +1,102 @@
+From ece5ffd9e15e9c8471e58b581a098032a679d34e Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:00 -0500
+Subject: [PATCH] phy: usb: Get all drivers that use USB clks using correct
+ enable/disable
+
+The BRCM USB Phy, ohci, ehci and xhci drivers all use the USB clocks
+but not all drivers use the clk_prepare_enable/clk_disable_unprepare
+versions to enable/disable the clocks. This change gets all drivers
+using the prepare version.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -74,8 +74,8 @@ static int brcm_usb_phy_init(struct phy
+ 	 */
+ 	mutex_lock(&priv->mutex);
+ 	if (priv->init_count++ == 0) {
+-		clk_enable(priv->usb_20_clk);
+-		clk_enable(priv->usb_30_clk);
++		clk_prepare_enable(priv->usb_20_clk);
++		clk_prepare_enable(priv->usb_30_clk);
+ 		brcm_usb_init_common(&priv->ini);
+ 	}
+ 	mutex_unlock(&priv->mutex);
+@@ -106,8 +106,8 @@ static int brcm_usb_phy_exit(struct phy
+ 	mutex_lock(&priv->mutex);
+ 	if (--priv->init_count == 0) {
+ 		brcm_usb_uninit_common(&priv->ini);
+-		clk_disable(priv->usb_20_clk);
+-		clk_disable(priv->usb_30_clk);
++		clk_disable_unprepare(priv->usb_20_clk);
++		clk_disable_unprepare(priv->usb_30_clk);
+ 	}
+ 	mutex_unlock(&priv->mutex);
+ 	phy->inited = false;
+@@ -360,8 +360,8 @@ static int brcm_usb_phy_probe(struct pla
+ 	if (priv->has_eohci)
+ 		brcm_usb_uninit_eohci(&priv->ini);
+ 	brcm_usb_uninit_common(&priv->ini);
+-	clk_disable(priv->usb_20_clk);
+-	clk_disable(priv->usb_30_clk);
++	clk_disable_unprepare(priv->usb_20_clk);
++	clk_disable_unprepare(priv->usb_30_clk);
+ 
+ 	phy_provider = devm_of_phy_provider_register(dev, brcm_usb_phy_xlate);
+ 
+@@ -381,8 +381,8 @@ static int brcm_usb_phy_suspend(struct d
+ 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
+ 
+ 	if (priv->init_count) {
+-		clk_disable(priv->usb_20_clk);
+-		clk_disable(priv->usb_30_clk);
++		clk_disable_unprepare(priv->usb_20_clk);
++		clk_disable_unprepare(priv->usb_30_clk);
+ 	}
+ 	return 0;
+ }
+@@ -391,8 +391,8 @@ static int brcm_usb_phy_resume(struct de
+ {
+ 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
+ 
+-	clk_enable(priv->usb_20_clk);
+-	clk_enable(priv->usb_30_clk);
++	clk_prepare_enable(priv->usb_20_clk);
++	clk_prepare_enable(priv->usb_30_clk);
+ 	brcm_usb_init_ipp(&priv->ini);
+ 
+ 	/*
+@@ -405,13 +405,13 @@ static int brcm_usb_phy_resume(struct de
+ 			brcm_usb_init_eohci(&priv->ini);
+ 		} else if (priv->has_eohci) {
+ 			brcm_usb_uninit_eohci(&priv->ini);
+-			clk_disable(priv->usb_20_clk);
++			clk_disable_unprepare(priv->usb_20_clk);
+ 		}
+ 		if (priv->phys[BRCM_USB_PHY_3_0].inited) {
+ 			brcm_usb_init_xhci(&priv->ini);
+ 		} else if (priv->has_xhci) {
+ 			brcm_usb_uninit_xhci(&priv->ini);
+-			clk_disable(priv->usb_30_clk);
++			clk_disable_unprepare(priv->usb_30_clk);
+ 		}
+ 	} else {
+ 		if (priv->has_xhci)
+@@ -419,8 +419,8 @@ static int brcm_usb_phy_resume(struct de
+ 		if (priv->has_eohci)
+ 			brcm_usb_uninit_eohci(&priv->ini);
+ 		brcm_usb_uninit_common(&priv->ini);
+-		clk_disable(priv->usb_20_clk);
+-		clk_disable(priv->usb_30_clk);
++		clk_disable_unprepare(priv->usb_20_clk);
++		clk_disable_unprepare(priv->usb_30_clk);
+ 	}
+ 
+ 	return 0;
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0003-phy-usb-Put-USB-phys-into-IDDQ-on-suspend-to-save-po.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0003-phy-usb-Put-USB-phys-into-IDDQ-on-suspend-to-save-po.patch
new file mode 100644
index 0000000000..356e305460
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0003-phy-usb-Put-USB-phys-into-IDDQ-on-suspend-to-save-po.patch
@@ -0,0 +1,51 @@
+From 6597af4e4835ec0709638d48f73c11b5c624790f Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:01 -0500
+Subject: [PATCH] phy: usb: Put USB phys into IDDQ on suspend to save power in
+ S2 mode
+
+Currently the Phy driver will put the USB phys into the max
+power saving mode (IDDQ) when there is no corresponding XHCI, EHCI
+or OHCI client (through rmmod, unbind or if the driver is not
+builtin). This change will also put the Phys into IDDQ mode
+on suspend so that S2 will get the additional power savings.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb-init.c |  2 --
+ drivers/phy/broadcom/phy-brcm-usb.c      | 11 +++++++++--
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
+@@ -1002,8 +1002,6 @@ void brcm_usb_uninit_common(struct brcm_
+ 
+ void brcm_usb_uninit_eohci(struct brcm_usb_init_params *params)
+ {
+-	if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB20_HC_RESETB))
+-		USB_CTRL_UNSET_FAMILY(params, USB_PM, USB20_HC_RESETB);
+ }
+ 
+ void brcm_usb_uninit_xhci(struct brcm_usb_init_params *params)
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -381,8 +381,15 @@ static int brcm_usb_phy_suspend(struct d
+ 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
+ 
+ 	if (priv->init_count) {
+-		clk_disable_unprepare(priv->usb_20_clk);
+-		clk_disable_unprepare(priv->usb_30_clk);
++		if (priv->phys[BRCM_USB_PHY_3_0].inited)
++			brcm_usb_uninit_xhci(&priv->ini);
++		if (priv->phys[BRCM_USB_PHY_2_0].inited)
++			brcm_usb_uninit_eohci(&priv->ini);
++		brcm_usb_uninit_common(&priv->ini);
++		if (priv->phys[BRCM_USB_PHY_3_0].inited)
++			clk_disable_unprepare(priv->usb_30_clk);
++		if (priv->phys[BRCM_USB_PHY_2_0].inited)
++			clk_disable_unprepare(priv->usb_20_clk);
+ 	}
+ 	return 0;
+ }
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0004-phy-usb-Add-wake-on-functionality.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0004-phy-usb-Add-wake-on-functionality.patch
new file mode 100644
index 0000000000..d52edfef77
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0004-phy-usb-Add-wake-on-functionality.patch
@@ -0,0 +1,205 @@
+From f1c0db40a3ade1f1a39e5794d728f2953d817322 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:02 -0500
+Subject: [PATCH] phy: usb: Add "wake on" functionality
+
+Add the ability to handle USB wake events from USB devices when
+in S2 mode. Typically there is some additional configuration
+needed to tell the USB device to generate the wake event when
+suspended but this varies with the different USB device classes.
+For example, on USB Ethernet dongles, ethtool should be used to
+enable the magic packet wake functionality in the dongle.
+NOTE:  This requires that the "power/wakeup" sysfs entry for
+the USB device generating the wakeup be set to "enabled".
+
+This functionality requires a special hardware sideband path that
+will trigger the AON_PM_L2 interrupt needed to wake the system from
+S2 even though the USB host controllers are in IDDQ (low power state)
+and most USB related clocks are shut off. For the sideband signaling
+to work we need to leave the usbx_freerun clock running, but this
+clock consumes very little power by design. There's a bug in the
+XHCI wake hardware so only EHCI/OHCI wake is currently supported.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb-init.c | 17 +++++++++
+ drivers/phy/broadcom/phy-brcm-usb-init.h |  1 +
+ drivers/phy/broadcom/phy-brcm-usb.c      | 48 ++++++++++++++++++++++--
+ 3 files changed, 63 insertions(+), 3 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
+@@ -58,6 +58,8 @@
+ #define   USB_CTRL_USB_PM_SOFT_RESET_MASK		0x40000000 /* option */
+ #define   USB_CTRL_USB_PM_USB20_HC_RESETB_MASK		0x30000000 /* option */
+ #define   USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK	0x00300000 /* option */
++#define   USB_CTRL_USB_PM_RMTWKUP_EN_MASK		0x00000001
++#define USB_CTRL_USB_PM_STATUS		0x38
+ #define USB_CTRL_USB30_CTL1		0x60
+ #define   USB_CTRL_USB30_CTL1_PHY3_PLL_SEQ_START_MASK	0x00000010
+ #define   USB_CTRL_USB30_CTL1_PHY3_RESETB_MASK		0x00010000
+@@ -855,6 +857,10 @@ void brcm_usb_init_common(struct brcm_us
+ 	u32 reg;
+ 	void __iomem *ctrl = params->ctrl_regs;
+ 
++	/* Clear any pending wake conditions */
++	reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
++	brcmusb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS));
++
+ 	/* Take USB out of power down */
+ 	if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN)) {
+ 		USB_CTRL_UNSET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);
+@@ -1010,6 +1016,17 @@ void brcm_usb_uninit_xhci(struct brcm_us
+ 	USB_CTRL_SET(params->ctrl_regs, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
+ }
+ 
++void brcm_usb_wake_enable(struct brcm_usb_init_params *params,
++			  int enable)
++{
++	void __iomem *ctrl = params->ctrl_regs;
++
++	if (enable)
++		USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
++	else
++		USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);
++}
++
+ void brcm_usb_set_family_map(struct brcm_usb_init_params *params)
+ {
+ 	int fam;
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.h
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
+@@ -38,5 +38,6 @@ void brcm_usb_init_xhci(struct brcm_usb_
+ void brcm_usb_uninit_common(struct brcm_usb_init_params *ini);
+ void brcm_usb_uninit_eohci(struct brcm_usb_init_params *ini);
+ void brcm_usb_uninit_xhci(struct brcm_usb_init_params *ini);
++void brcm_usb_wake_enable(struct brcm_usb_init_params *params, int enable);
+ 
+ #endif /* _USB_BRCM_COMMON_INIT_H */
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -57,11 +57,22 @@ struct brcm_usb_phy_data {
+ 	bool			has_xhci;
+ 	struct clk		*usb_20_clk;
+ 	struct clk		*usb_30_clk;
++	struct clk		*suspend_clk;
+ 	struct mutex		mutex;	/* serialize phy init */
+ 	int			init_count;
++	int			wake_irq;
+ 	struct brcm_usb_phy	phys[BRCM_USB_PHY_ID_MAX];
+ };
+ 
++static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
++{
++	struct phy *gphy = dev_id;
++
++	pm_wakeup_event(&gphy->dev, 0);
++
++	return IRQ_HANDLED;
++}
++
+ static int brcm_usb_phy_init(struct phy *gphy)
+ {
+ 	struct brcm_usb_phy *phy = phy_get_drvdata(gphy);
+@@ -76,6 +87,7 @@ static int brcm_usb_phy_init(struct phy
+ 	if (priv->init_count++ == 0) {
+ 		clk_prepare_enable(priv->usb_20_clk);
+ 		clk_prepare_enable(priv->usb_30_clk);
++		clk_prepare_enable(priv->suspend_clk);
+ 		brcm_usb_init_common(&priv->ini);
+ 	}
+ 	mutex_unlock(&priv->mutex);
+@@ -108,6 +120,7 @@ static int brcm_usb_phy_exit(struct phy
+ 		brcm_usb_uninit_common(&priv->ini);
+ 		clk_disable_unprepare(priv->usb_20_clk);
+ 		clk_disable_unprepare(priv->usb_30_clk);
++		clk_disable_unprepare(priv->suspend_clk);
+ 	}
+ 	mutex_unlock(&priv->mutex);
+ 	phy->inited = false;
+@@ -228,11 +241,12 @@ static const struct attribute_group brcm
+ 	.attrs = brcm_usb_phy_attrs,
+ };
+ 
+-static int brcm_usb_phy_dvr_init(struct device *dev,
++static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
+ 				 struct brcm_usb_phy_data *priv,
+ 				 struct device_node *dn)
+ {
+-	struct phy *gphy;
++	struct device *dev = &pdev->dev;
++	struct phy *gphy = NULL;
+ 	int err;
+ 
+ 	priv->usb_20_clk = of_clk_get_by_name(dn, "sw_usb");
+@@ -275,6 +289,28 @@ static int brcm_usb_phy_dvr_init(struct
+ 		if (err)
+ 			return err;
+ 	}
++
++	priv->suspend_clk = clk_get(dev, "usb0_freerun");
++	if (IS_ERR(priv->suspend_clk)) {
++		dev_err(dev, "Suspend Clock not found in Device Tree\n");
++		priv->suspend_clk = NULL;
++	}
++
++	priv->wake_irq = platform_get_irq_byname(pdev, "wake");
++	if (priv->wake_irq < 0)
++		priv->wake_irq = platform_get_irq_byname(pdev, "wakeup");
++	if (priv->wake_irq >= 0) {
++		err = devm_request_irq(dev, priv->wake_irq,
++				       brcm_usb_phy_wake_isr, 0,
++				       dev_name(dev), gphy);
++		if (err < 0)
++			return err;
++		device_set_wakeup_capable(dev, 1);
++	} else {
++		dev_info(dev,
++			 "Wake interrupt missing, system wake not supported\n");
++	}
++
+ 	return 0;
+ }
+ 
+@@ -335,7 +371,7 @@ static int brcm_usb_phy_probe(struct pla
+ 	if (of_property_read_bool(dn, "brcm,has-eohci"))
+ 		priv->has_eohci = true;
+ 
+-	err = brcm_usb_phy_dvr_init(dev, priv, dn);
++	err = brcm_usb_phy_dvr_init(pdev, priv, dn);
+ 	if (err)
+ 		return err;
+ 
+@@ -386,10 +422,13 @@ static int brcm_usb_phy_suspend(struct d
+ 		if (priv->phys[BRCM_USB_PHY_2_0].inited)
+ 			brcm_usb_uninit_eohci(&priv->ini);
+ 		brcm_usb_uninit_common(&priv->ini);
++		brcm_usb_wake_enable(&priv->ini, true);
+ 		if (priv->phys[BRCM_USB_PHY_3_0].inited)
+ 			clk_disable_unprepare(priv->usb_30_clk);
+ 		if (priv->phys[BRCM_USB_PHY_2_0].inited)
+ 			clk_disable_unprepare(priv->usb_20_clk);
++		if (priv->wake_irq >= 0)
++			enable_irq_wake(priv->wake_irq);
+ 	}
+ 	return 0;
+ }
+@@ -400,6 +439,7 @@ static int brcm_usb_phy_resume(struct de
+ 
+ 	clk_prepare_enable(priv->usb_20_clk);
+ 	clk_prepare_enable(priv->usb_30_clk);
++	brcm_usb_wake_enable(&priv->ini, false);
+ 	brcm_usb_init_ipp(&priv->ini);
+ 
+ 	/*
+@@ -407,6 +447,8 @@ static int brcm_usb_phy_resume(struct de
+ 	 * Uninitialize anything that wasn't previously initialized.
+ 	 */
+ 	if (priv->init_count) {
++		if (priv->wake_irq >= 0)
++			disable_irq_wake(priv->wake_irq);
+ 		brcm_usb_init_common(&priv->ini);
+ 		if (priv->phys[BRCM_USB_PHY_2_0].inited) {
+ 			brcm_usb_init_eohci(&priv->ini);
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0005-phy-usb-Restructure-in-preparation-for-adding-7216-U.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0005-phy-usb-Restructure-in-preparation-for-adding-7216-U.patch
new file mode 100644
index 0000000000..2a63556122
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0005-phy-usb-Restructure-in-preparation-for-adding-7216-U.patch
@@ -0,0 +1,611 @@
+From 94583a41047eb9489f576344b8ba9370cf4cbfb7 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:03 -0500
+Subject: [PATCH] phy: usb: Restructure in preparation for adding 7216 USB
+ support
+
+The driver is being restructured in preparation for adding support
+for the new Synopsys USB conroller on the 7216. Since all the bugs
+and work-arounds in previous STB chips are supposed to be fixed,
+most of the code in phy-brcm-usb-init.c is not needed. Instead of
+adding more complexity to the already complicated phy-brcm-usb-init.c
+module, the driver will be restructured to use a vector table to
+dispatch into different C modules for the different controllers.
+
+There was also some general cleanup done including some ipp setup
+code that was incorrect.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb-init.c | 191 ++++++++++-------------
+ drivers/phy/broadcom/phy-brcm-usb-init.h | 140 +++++++++++++++--
+ drivers/phy/broadcom/phy-brcm-usb.c      |   6 +-
+ 3 files changed, 214 insertions(+), 123 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
+@@ -129,10 +129,6 @@ enum {
+ 	USB_CTRL_SELECTOR_COUNT,
+ };
+ 
+-#define USB_CTRL_REG(base, reg)	((void __iomem *)base + USB_CTRL_##reg)
+-#define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
+-#define USB_CTRL_MASK(reg, field) \
+-	USB_CTRL_##reg##_##field##_MASK
+ #define USB_CTRL_MASK_FAMILY(params, reg, field)			\
+ 	(params->usb_reg_bits_map[USB_CTRL_##reg##_##field##_SELECTOR])
+ 
+@@ -143,13 +139,6 @@ enum {
+ 	usb_ctrl_unset_family(params, USB_CTRL_##reg,	\
+ 		USB_CTRL_##reg##_##field##_SELECTOR)
+ 
+-#define USB_CTRL_SET(base, reg, field)	\
+-	usb_ctrl_set(USB_CTRL_REG(base, reg),		\
+-		     USB_CTRL_##reg##_##field##_MASK)
+-#define USB_CTRL_UNSET(base, reg, field)	\
+-	usb_ctrl_unset(USB_CTRL_REG(base, reg),		\
+-		       USB_CTRL_##reg##_##field##_MASK)
+-
+ #define MDIO_USB2	0
+ #define MDIO_USB3	BIT(31)
+ 
+@@ -405,26 +394,14 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT
+ 	},
+ };
+ 
+-static inline u32 brcmusb_readl(void __iomem *addr)
+-{
+-	return readl(addr);
+-}
+-
+-static inline void brcmusb_writel(u32 val, void __iomem *addr)
+-{
+-	writel(val, addr);
+-}
+-
+ static inline
+ void usb_ctrl_unset_family(struct brcm_usb_init_params *params,
+ 			   u32 reg_offset, u32 field)
+ {
+ 	u32 mask;
+-	void __iomem *reg;
+ 
+ 	mask = params->usb_reg_bits_map[field];
+-	reg = params->ctrl_regs + reg_offset;
+-	brcmusb_writel(brcmusb_readl(reg) & ~mask, reg);
++	brcm_usb_ctrl_unset(params->ctrl_regs + reg_offset, mask);
+ };
+ 
+ static inline
+@@ -432,45 +409,27 @@ void usb_ctrl_set_family(struct brcm_usb
+ 			 u32 reg_offset, u32 field)
+ {
+ 	u32 mask;
+-	void __iomem *reg;
+ 
+ 	mask = params->usb_reg_bits_map[field];
+-	reg = params->ctrl_regs + reg_offset;
+-	brcmusb_writel(brcmusb_readl(reg) | mask, reg);
++	brcm_usb_ctrl_set(params->ctrl_regs + reg_offset, mask);
+ };
+ 
+-static inline void usb_ctrl_set(void __iomem *reg, u32 field)
+-{
+-	u32 value;
+-
+-	value = brcmusb_readl(reg);
+-	brcmusb_writel(value | field, reg);
+-}
+-
+-static inline void usb_ctrl_unset(void __iomem *reg, u32 field)
+-{
+-	u32 value;
+-
+-	value = brcmusb_readl(reg);
+-	brcmusb_writel(value & ~field, reg);
+-}
+-
+ static u32 brcmusb_usb_mdio_read(void __iomem *ctrl_base, u32 reg, int mode)
+ {
+ 	u32 data;
+ 
+ 	data = (reg << 16) | mode;
+-	brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
++	brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+ 	data |= (1 << 24);
+-	brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
++	brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+ 	data &= ~(1 << 24);
+ 	/* wait for the 60MHz parallel to serial shifter */
+ 	usleep_range(10, 20);
+-	brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
++	brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+ 	/* wait for the 60MHz parallel to serial shifter */
+ 	usleep_range(10, 20);
+ 
+-	return brcmusb_readl(USB_CTRL_REG(ctrl_base, MDIO2)) & 0xffff;
++	return brcm_usb_readl(USB_CTRL_REG(ctrl_base, MDIO2)) & 0xffff;
+ }
+ 
+ static void brcmusb_usb_mdio_write(void __iomem *ctrl_base, u32 reg,
+@@ -479,14 +438,14 @@ static void brcmusb_usb_mdio_write(void
+ 	u32 data;
+ 
+ 	data = (reg << 16) | val | mode;
+-	brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
++	brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+ 	data |= (1 << 25);
+-	brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
++	brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+ 	data &= ~(1 << 25);
+ 
+ 	/* wait for the 60MHz parallel to serial shifter */
+ 	usleep_range(10, 20);
+-	brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
++	brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+ 	/* wait for the 60MHz parallel to serial shifter */
+ 	usleep_range(10, 20);
+ }
+@@ -713,12 +672,12 @@ static void brcmusb_usb3_otp_fix(struct
+ 
+ 	if (params->family_id != 0x74371000 || !xhci_ec_base)
+ 		return;
+-	brcmusb_writel(0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR));
+-	val = brcmusb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
++	brcm_usb_writel(0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR));
++	val = brcm_usb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
+ 
+ 	/* set cfg_pick_ss_lock */
+ 	val |= (1 << 27);
+-	brcmusb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
++	brcm_usb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
+ 
+ 	/* Reset USB 3.0 PHY for workaround to take effect */
+ 	USB_CTRL_UNSET(params->ctrl_regs, USB30_CTL1, PHY3_RESETB);
+@@ -751,7 +710,7 @@ static void brcmusb_xhci_soft_reset(stru
+  *   - default chip/rev.
+  * NOTE: The minor rev is always ignored.
+  */
+-static enum brcm_family_type brcmusb_get_family_type(
++static enum brcm_family_type get_family_type(
+ 	struct brcm_usb_init_params *params)
+ {
+ 	int last_type = -1;
+@@ -779,7 +738,7 @@ static enum brcm_family_type brcmusb_get
+ 	return last_type;
+ }
+ 
+-void brcm_usb_init_ipp(struct brcm_usb_init_params *params)
++static void usb_init_ipp(struct brcm_usb_init_params *params)
+ {
+ 	void __iomem *ctrl = params->ctrl_regs;
+ 	u32 reg;
+@@ -795,7 +754,7 @@ void brcm_usb_init_ipp(struct brcm_usb_i
+ 			USB_CTRL_SET_FAMILY(params, USB30_CTL1, USB3_IPP);
+ 	}
+ 
+-	reg = brcmusb_readl(USB_CTRL_REG(ctrl, SETUP));
++	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
+ 	orig_reg = reg;
+ 	if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_CC_DRD_MODE_ENABLE_SEL))
+ 		/* Never use the strap, it's going away. */
+@@ -803,8 +762,8 @@ void brcm_usb_init_ipp(struct brcm_usb_i
+ 					      SETUP,
+ 					      STRAP_CC_DRD_MODE_ENABLE_SEL));
+ 	if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_IPP_SEL))
++		/* override ipp strap pin (if it exits) */
+ 		if (params->ipp != 2)
+-			/* override ipp strap pin (if it exits) */
+ 			reg &= ~(USB_CTRL_MASK_FAMILY(params, SETUP,
+ 						      STRAP_IPP_SEL));
+ 
+@@ -812,54 +771,26 @@ void brcm_usb_init_ipp(struct brcm_usb_i
+ 	reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
+ 	if (params->ioc)
+ 		reg |= USB_CTRL_MASK(SETUP, IOC);
+-	if (params->ipp == 1 && ((reg & USB_CTRL_MASK(SETUP, IPP)) == 0))
++	if (params->ipp == 1)
+ 		reg |= USB_CTRL_MASK(SETUP, IPP);
+-	brcmusb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
++	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
+ 
+ 	/*
+ 	 * If we're changing IPP, make sure power is off long enough
+ 	 * to turn off any connected devices.
+ 	 */
+-	if (reg != orig_reg)
++	if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
+ 		msleep(50);
+ }
+ 
+-int brcm_usb_init_get_dual_select(struct brcm_usb_init_params *params)
+-{
+-	void __iomem *ctrl = params->ctrl_regs;
+-	u32 reg = 0;
+-
+-	if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
+-		reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+-		reg &= USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
+-					PORT_MODE);
+-	}
+-	return reg;
+-}
+-
+-void brcm_usb_init_set_dual_select(struct brcm_usb_init_params *params,
+-				   int mode)
+-{
+-	void __iomem *ctrl = params->ctrl_regs;
+-	u32 reg;
+-
+-	if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
+-		reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+-		reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
+-					PORT_MODE);
+-		reg |= mode;
+-		brcmusb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+-	}
+-}
+-
+-void brcm_usb_init_common(struct brcm_usb_init_params *params)
++static void usb_init_common(struct brcm_usb_init_params *params)
+ {
+ 	u32 reg;
+ 	void __iomem *ctrl = params->ctrl_regs;
+ 
+ 	/* Clear any pending wake conditions */
+-	reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
+-	brcmusb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS));
++	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
++	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS));
+ 
+ 	/* Take USB out of power down */
+ 	if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN)) {
+@@ -885,7 +816,7 @@ void brcm_usb_init_common(struct brcm_us
+ 	/* Block auto PLL suspend by USB2 PHY (Sasi) */
+ 	USB_CTRL_SET(ctrl, PLL_CTL, PLL_SUSPEND_EN);
+ 
+-	reg = brcmusb_readl(USB_CTRL_REG(ctrl, SETUP));
++	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
+ 	if (params->selected_family == BRCM_FAMILY_7364A0)
+ 		/* Suppress overcurrent indication from USB30 ports for A0 */
+ 		reg |= USB_CTRL_MASK_FAMILY(params, SETUP, OC3_DISABLE);
+@@ -901,16 +832,16 @@ void brcm_usb_init_common(struct brcm_us
+ 		reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB1_EN);
+ 	if (USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN))
+ 		reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN);
+-	brcmusb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
++	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
+ 
+ 	brcmusb_memc_fix(params);
+ 
+ 	if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
+-		reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+ 		reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
+ 					PORT_MODE);
+ 		reg |= params->mode;
+-		brcmusb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++		brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+ 	}
+ 	if (USB_CTRL_MASK_FAMILY(params, USB_PM, BDC_SOFT_RESETB)) {
+ 		switch (params->mode) {
+@@ -932,7 +863,7 @@ void brcm_usb_init_common(struct brcm_us
+ 	}
+ }
+ 
+-void brcm_usb_init_eohci(struct brcm_usb_init_params *params)
++static void usb_init_eohci(struct brcm_usb_init_params *params)
+ {
+ 	u32 reg;
+ 	void __iomem *ctrl = params->ctrl_regs;
+@@ -948,10 +879,10 @@ void brcm_usb_init_eohci(struct brcm_usb
+ 		USB_CTRL_SET(ctrl, EBRIDGE, ESTOP_SCB_REQ);
+ 
+ 	/* Setup the endian bits */
+-	reg = brcmusb_readl(USB_CTRL_REG(ctrl, SETUP));
++	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
+ 	reg &= ~USB_CTRL_SETUP_ENDIAN_BITS;
+ 	reg |= USB_CTRL_MASK_FAMILY(params, SETUP, ENDIAN);
+-	brcmusb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
++	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
+ 
+ 	if (params->selected_family == BRCM_FAMILY_7271A0)
+ 		/* Enable LS keep alive fix for certain keyboards */
+@@ -962,14 +893,14 @@ void brcm_usb_init_eohci(struct brcm_usb
+ 		 * Make the burst size 512 bytes to fix a hardware bug
+ 		 * on the 7255a0. See HW7255-24.
+ 		 */
+-		reg = brcmusb_readl(USB_CTRL_REG(ctrl, EBRIDGE));
++		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, EBRIDGE));
+ 		reg &= ~USB_CTRL_MASK(EBRIDGE, EBR_SCB_SIZE);
+ 		reg |= 0x800;
+-		brcmusb_writel(reg, USB_CTRL_REG(ctrl, EBRIDGE));
++		brcm_usb_writel(reg, USB_CTRL_REG(ctrl, EBRIDGE));
+ 	}
+ }
+ 
+-void brcm_usb_init_xhci(struct brcm_usb_init_params *params)
++static void usb_init_xhci(struct brcm_usb_init_params *params)
+ {
+ 	void __iomem *ctrl = params->ctrl_regs;
+ 
+@@ -997,7 +928,7 @@ void brcm_usb_init_xhci(struct brcm_usb_
+ 	brcmusb_usb3_otp_fix(params);
+ }
+ 
+-void brcm_usb_uninit_common(struct brcm_usb_init_params *params)
++static void usb_uninit_common(struct brcm_usb_init_params *params)
+ {
+ 	if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB_PWRDN))
+ 		USB_CTRL_SET_FAMILY(params, USB_PM, USB_PWRDN);
+@@ -1006,17 +937,47 @@ void brcm_usb_uninit_common(struct brcm_
+ 		USB_CTRL_SET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);
+ }
+ 
+-void brcm_usb_uninit_eohci(struct brcm_usb_init_params *params)
++static void usb_uninit_eohci(struct brcm_usb_init_params *params)
+ {
+ }
+ 
+-void brcm_usb_uninit_xhci(struct brcm_usb_init_params *params)
++static void usb_uninit_xhci(struct brcm_usb_init_params *params)
+ {
+ 	brcmusb_xhci_soft_reset(params, 1);
+ 	USB_CTRL_SET(params->ctrl_regs, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
+ }
+ 
+-void brcm_usb_wake_enable(struct brcm_usb_init_params *params,
++static int usb_get_dual_select(struct brcm_usb_init_params *params)
++{
++	void __iomem *ctrl = params->ctrl_regs;
++	u32 reg = 0;
++
++	pr_debug("%s\n", __func__);
++	if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
++		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++		reg &= USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
++					PORT_MODE);
++	}
++	return reg;
++}
++
++static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
++{
++	void __iomem *ctrl = params->ctrl_regs;
++	u32 reg;
++
++	pr_debug("%s\n", __func__);
++
++	if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
++		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++		reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
++					PORT_MODE);
++		reg |= mode;
++		brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++	}
++}
++
++static void usb_wake_enable(struct brcm_usb_init_params *params,
+ 			  int enable)
+ {
+ 	void __iomem *ctrl = params->ctrl_regs;
+@@ -1027,13 +988,29 @@ void brcm_usb_wake_enable(struct brcm_us
+ 		USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);
+ }
+ 
+-void brcm_usb_set_family_map(struct brcm_usb_init_params *params)
++static const struct brcm_usb_init_ops bcm7445_ops = {
++	.init_ipp = usb_init_ipp,
++	.init_common = usb_init_common,
++	.init_eohci = usb_init_eohci,
++	.init_xhci = usb_init_xhci,
++	.uninit_common = usb_uninit_common,
++	.uninit_eohci = usb_uninit_eohci,
++	.uninit_xhci = usb_uninit_xhci,
++	.get_dual_select = usb_get_dual_select,
++	.set_dual_select = usb_set_dual_select,
++	.wake_enable = usb_wake_enable,
++};
++
++void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params)
+ {
+ 	int fam;
+ 
+-	fam = brcmusb_get_family_type(params);
++	pr_debug("%s\n", __func__);
++
++	fam = get_family_type(params);
+ 	params->selected_family = fam;
+ 	params->usb_reg_bits_map =
+ 		&usb_reg_bits_map_table[fam][0];
+ 	params->family_name = family_names[fam];
++	params->ops = &bcm7445_ops;
+ }
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.h
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
+@@ -13,6 +13,33 @@
+ 
+ struct  brcm_usb_init_params;
+ 
++#define USB_CTRL_REG(base, reg)	((void __iomem *)base + USB_CTRL_##reg)
++#define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
++#define USB_CTRL_MASK(reg, field) \
++	USB_CTRL_##reg##_##field##_MASK
++#define USB_CTRL_SET(base, reg, field)	\
++	brcm_usb_ctrl_set(USB_CTRL_REG(base, reg),	\
++			  USB_CTRL_##reg##_##field##_MASK)
++#define USB_CTRL_UNSET(base, reg, field)	\
++	brcm_usb_ctrl_unset(USB_CTRL_REG(base, reg),		\
++			    USB_CTRL_##reg##_##field##_MASK)
++
++struct  brcm_usb_init_params;
++
++struct brcm_usb_init_ops {
++	void (*init_ipp)(struct brcm_usb_init_params *params);
++	void (*init_common)(struct brcm_usb_init_params *params);
++	void (*init_eohci)(struct brcm_usb_init_params *params);
++	void (*init_xhci)(struct brcm_usb_init_params *params);
++	void (*uninit_common)(struct brcm_usb_init_params *params);
++	void (*uninit_eohci)(struct brcm_usb_init_params *params);
++	void (*uninit_xhci)(struct brcm_usb_init_params *params);
++	int  (*get_dual_select)(struct brcm_usb_init_params *params);
++	void (*set_dual_select)(struct brcm_usb_init_params *params, int mode);
++	void (*wake_enable)(struct brcm_usb_init_params *params,
++			    int enable);
++};
++
+ struct  brcm_usb_init_params {
+ 	void __iomem *ctrl_regs;
+ 	void __iomem *xhci_ec_regs;
+@@ -24,20 +51,107 @@ struct  brcm_usb_init_params {
+ 	int selected_family;
+ 	const char *family_name;
+ 	const u32 *usb_reg_bits_map;
++	const struct brcm_usb_init_ops *ops;
+ };
+ 
+-void brcm_usb_set_family_map(struct brcm_usb_init_params *params);
+-int brcm_usb_init_get_dual_select(struct brcm_usb_init_params *params);
+-void brcm_usb_init_set_dual_select(struct brcm_usb_init_params *params,
+-				   int mode);
+-
+-void brcm_usb_init_ipp(struct brcm_usb_init_params *ini);
+-void brcm_usb_init_common(struct brcm_usb_init_params *ini);
+-void brcm_usb_init_eohci(struct brcm_usb_init_params *ini);
+-void brcm_usb_init_xhci(struct brcm_usb_init_params *ini);
+-void brcm_usb_uninit_common(struct brcm_usb_init_params *ini);
+-void brcm_usb_uninit_eohci(struct brcm_usb_init_params *ini);
+-void brcm_usb_uninit_xhci(struct brcm_usb_init_params *ini);
+-void brcm_usb_wake_enable(struct brcm_usb_init_params *params, int enable);
++void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
++
++static inline u32 brcm_usb_readl(void __iomem *addr)
++{
++	/*
++	 * MIPS endianness is configured by boot strap, which also reverses all
++	 * bus endianness (i.e., big-endian CPU + big endian bus ==> native
++	 * endian I/O).
++	 *
++	 * Other architectures (e.g., ARM) either do not support big endian, or
++	 * else leave I/O in little endian mode.
++	 */
++	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
++		return __raw_readl(addr);
++	else
++		return readl_relaxed(addr);
++}
++
++static inline void brcm_usb_writel(u32 val, void __iomem *addr)
++{
++	/* See brcmnand_readl() comments */
++	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
++		__raw_writel(val, addr);
++	else
++		writel_relaxed(val, addr);
++}
++
++static inline void brcm_usb_ctrl_unset(void __iomem *reg, u32 mask)
++{
++	brcm_usb_writel(brcm_usb_readl(reg) & ~(mask), reg);
++};
++
++static inline void brcm_usb_ctrl_set(void __iomem *reg, u32 mask)
++{
++	brcm_usb_writel(brcm_usb_readl(reg) | (mask), reg);
++};
++
++static inline void brcm_usb_init_ipp(struct brcm_usb_init_params *ini)
++{
++	if (ini->ops->init_ipp)
++		ini->ops->init_ipp(ini);
++}
++
++static inline void brcm_usb_init_common(struct brcm_usb_init_params *ini)
++{
++	if (ini->ops->init_common)
++		ini->ops->init_common(ini);
++}
++
++static inline void brcm_usb_init_eohci(struct brcm_usb_init_params *ini)
++{
++	if (ini->ops->init_eohci)
++		ini->ops->init_eohci(ini);
++}
++
++static inline void brcm_usb_init_xhci(struct brcm_usb_init_params *ini)
++{
++	if (ini->ops->init_xhci)
++		ini->ops->init_xhci(ini);
++}
++
++static inline void brcm_usb_uninit_common(struct brcm_usb_init_params *ini)
++{
++	if (ini->ops->uninit_common)
++		ini->ops->uninit_common(ini);
++}
++
++static inline void brcm_usb_uninit_eohci(struct brcm_usb_init_params *ini)
++{
++	if (ini->ops->uninit_eohci)
++		ini->ops->uninit_eohci(ini);
++}
++
++static inline void brcm_usb_uninit_xhci(struct brcm_usb_init_params *ini)
++{
++	if (ini->ops->uninit_xhci)
++		ini->ops->uninit_xhci(ini);
++}
++
++static inline void brcm_usb_wake_enable(struct brcm_usb_init_params *ini,
++	int enable)
++{
++	if (ini->ops->wake_enable)
++		ini->ops->wake_enable(ini, enable);
++}
++
++static inline int brcm_usb_get_dual_select(struct brcm_usb_init_params *ini)
++{
++	if (ini->ops->get_dual_select)
++		return ini->ops->get_dual_select(ini);
++	return 0;
++}
++
++static inline void brcm_usb_set_dual_select(struct brcm_usb_init_params *ini,
++	int mode)
++{
++	if (ini->ops->set_dual_select)
++		ini->ops->set_dual_select(ini, mode);
++}
+ 
+ #endif /* _USB_BRCM_COMMON_INIT_H */
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -207,7 +207,7 @@ static ssize_t dual_select_store(struct
+ 	res = name_to_value(&brcm_dual_mode_to_name[0],
+ 			    ARRAY_SIZE(brcm_dual_mode_to_name), buf, &value);
+ 	if (!res) {
+-		brcm_usb_init_set_dual_select(&priv->ini, value);
++		brcm_usb_set_dual_select(&priv->ini, value);
+ 		res = len;
+ 	}
+ 	mutex_unlock(&sysfs_lock);
+@@ -222,7 +222,7 @@ static ssize_t dual_select_show(struct d
+ 	int value;
+ 
+ 	mutex_lock(&sysfs_lock);
+-	value = brcm_usb_init_get_dual_select(&priv->ini);
++	value = brcm_usb_get_dual_select(&priv->ini);
+ 	mutex_unlock(&sysfs_lock);
+ 	return sprintf(buf, "%s\n",
+ 		value_to_name(&brcm_dual_mode_to_name[0],
+@@ -331,7 +331,7 @@ static int brcm_usb_phy_probe(struct pla
+ 
+ 	priv->ini.family_id = brcmstb_get_family_id();
+ 	priv->ini.product_id = brcmstb_get_product_id();
+-	brcm_usb_set_family_map(&priv->ini);
++	brcm_usb_dvr_init_7445(&priv->ini);
+ 	dev_dbg(dev, "Best mapping table is for %s\n",
+ 		priv->ini.family_name);
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0006-dt-bindings-Add-Broadcom-STB-USB-PHY-binding-documen.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0006-dt-bindings-Add-Broadcom-STB-USB-PHY-binding-documen.patch
new file mode 100644
index 0000000000..2a57d1dc80
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0006-dt-bindings-Add-Broadcom-STB-USB-PHY-binding-documen.patch
@@ -0,0 +1,108 @@
+From b11df0c9efbbe2b52c5133ca15030f01b43ec6ef Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:04 -0500
+Subject: [PATCH] dt-bindings: Add Broadcom STB USB PHY binding document
+
+Add support for bcm7216 and bcm7211
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Rob Herring <robh at kernel.org>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ .../bindings/phy/brcm,brcmstb-usb-phy.txt     | 69 +++++++++++++++----
+ 1 file changed, 56 insertions(+), 13 deletions(-)
+
+--- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.txt
++++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.txt
+@@ -1,30 +1,49 @@
+ Broadcom STB USB PHY
+ 
+ Required properties:
+- - compatible: brcm,brcmstb-usb-phy
+- - reg: two offset and length pairs.
+-	The first pair specifies a manditory set of memory mapped
+-	registers used for general control of the PHY.
+-	The second pair specifies optional registers used by some of
+-	the SoCs that support USB 3.x
+- - #phy-cells: Shall be 1 as it expects one argument for setting
+-	       the type of the PHY. Possible values are:
+-	       - PHY_TYPE_USB2 for USB1.1/2.0 PHY
+-	       - PHY_TYPE_USB3 for USB3.x PHY
++- compatible: should be one of
++	"brcm,brcmstb-usb-phy"
++	"brcm,bcm7216-usb-phy"
++	"brcm,bcm7211-usb-phy"
++
++- reg and reg-names properties requirements are specific to the
++  compatible string.
++  "brcm,brcmstb-usb-phy":
++    - reg: 1 or 2 offset and length pairs. One for the base CTRL registers
++           and an optional pair for systems with USB 3.x support
++    - reg-names: not specified
++  "brcm,bcm7216-usb-phy":
++    - reg: 3 offset and length pairs for CTRL, XHCI_EC and XHCI_GBL
++           registers
++    - reg-names: "ctrl", "xhci_ec", "xhci_gbl"
++  "brcm,bcm7211-usb-phy":
++    - reg: 5 offset and length pairs for CTRL, XHCI_EC, XHCI_GBL,
++           USB_PHY and USB_MDIO registers and an optional pair
++	   for the BDC registers
++    - reg-names: "ctrl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec"
++
++- #phy-cells: Shall be 1 as it expects one argument for setting
++	      the type of the PHY. Possible values are:
++	      - PHY_TYPE_USB2 for USB1.1/2.0 PHY
++	      - PHY_TYPE_USB3 for USB3.x PHY
+ 
+ Optional Properties:
+ - clocks : clock phandles.
+ - clock-names: String, clock name.
++- interrupts: wakeup interrupt
++- interrupt-names: "wakeup"
+ - brcm,ipp: Boolean, Invert Port Power.
+   Possible values are: 0 (Don't invert), 1 (Invert)
+ - brcm,ioc: Boolean, Invert Over Current detection.
+   Possible values are: 0 (Don't invert), 1 (Invert)
+-NOTE: one or both of the following two properties must be set
+-- brcm,has-xhci: Boolean indicating the phy has an XHCI phy.
+-- brcm,has-eohci: Boolean indicating the phy has an EHCI/OHCI phy.
+ - dr_mode: String, PHY Device mode.
+   Possible values are: "host", "peripheral ", "drd" or "typec-pd"
+   If this property is not defined, the phy will default to "host" mode.
++- brcm,syscon-piarbctl: phandle to syscon for handling config registers
++NOTE: one or both of the following two properties must be set
++- brcm,has-xhci: Boolean indicating the phy has an XHCI phy.
++- brcm,has-eohci: Boolean indicating the phy has an EHCI/OHCI phy.
++
+ 
+ Example:
+ 
+@@ -41,3 +60,27 @@ usbphy_0: usb-phy at f0470200 {
+ 	clocks = <&usb20>, <&usb30>;
+ 	clock-names = "sw_usb", "sw_usb3";
+ };
++
++usb-phy at 29f0200 {
++	reg = <0x29f0200 0x200>,
++		<0x29c0880 0x30>,
++		<0x29cc100 0x534>,
++		<0x2808000 0x24>,
++		<0x2980080 0x8>;
++	reg-names = "ctrl",
++		"xhci_ec",
++		"xhci_gbl",
++		"usb_phy",
++		"usb_mdio";
++	brcm,ioc = <0x0>;
++	brcm,ipp = <0x0>;
++	compatible = "brcm,bcm7211-usb-phy";
++	interrupts = <0x30>;
++	interrupt-parent = <&vpu_intr1_nosec_intc>;
++	interrupt-names = "wake";
++	#phy-cells = <0x1>;
++	brcm,has-xhci;
++	syscon-piarbctl = <&syscon_piarbctl>;
++	clocks = <&scmi_clk 256>;
++	clock-names = "sw_usb";
++};
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0007-phy-usb-Add-support-for-new-Synopsys-USB-controller-.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0007-phy-usb-Add-support-for-new-Synopsys-USB-controller-.patch
new file mode 100644
index 0000000000..11cc080c23
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0007-phy-usb-Add-support-for-new-Synopsys-USB-controller-.patch
@@ -0,0 +1,358 @@
+From 4e5b9c9a73b32d28759225a40d30848393a8f1fd Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:05 -0500
+Subject: [PATCH] phy: usb: Add support for new Synopsys USB controller on the
+ 7216
+
+The 7216 has the new USB XHCI controller from Synopsys. While
+this new controller and the PHY are similar to the STB versions,
+the major differences are:
+
+- Many of the registers and fields in the CTRL block have been
+  removed or changed.
+- A new set of Synopsys control registers, BCHP_USB_XHCI_GBL, were
+  added.
+- MDIO functionality has been replaced with direct access registers
+  in the BCHP_USB_XHCI_GBL block.
+- Power up PHY defaults that had to be changed by MDIO in previous
+  chips will now power up with the correct defaults.
+
+A new init module was created for this new Synopsys USB controller.
+A new compatible string was added and the driver will dispatch
+into one of two init modules based on it. A "reg-names" field was
+added so the driver can more easily get optional registers.
+A DT bindings document was also added for this driver.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/Makefile                 |   2 +-
+ .../phy/broadcom/phy-brcm-usb-init-synopsys.c | 171 ++++++++++++++++++
+ drivers/phy/broadcom/phy-brcm-usb-init.h      |   2 +
+ drivers/phy/broadcom/phy-brcm-usb.c           |  70 +++++--
+ 4 files changed, 227 insertions(+), 18 deletions(-)
+ create mode 100644 drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+
+--- a/drivers/phy/broadcom/Makefile
++++ b/drivers/phy/broadcom/Makefile
+@@ -8,7 +8,7 @@ obj-$(CONFIG_PHY_NS2_USB_DRD)		+= phy-bc
+ obj-$(CONFIG_PHY_BRCM_SATA)		+= phy-brcm-sata.o
+ obj-$(CONFIG_PHY_BRCM_USB)		+= phy-brcm-usb-dvr.o
+ 
+-phy-brcm-usb-dvr-objs := phy-brcm-usb.o phy-brcm-usb-init.o
++phy-brcm-usb-dvr-objs := phy-brcm-usb.o phy-brcm-usb-init.o phy-brcm-usb-init-synopsys.o
+ 
+ obj-$(CONFIG_PHY_BCM_SR_PCIE)		+= phy-bcm-sr-pcie.o
+ obj-$(CONFIG_PHY_BCM_SR_USB)		+= phy-bcm-sr-usb.o
+--- /dev/null
++++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+@@ -0,0 +1,171 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (c) 2018, Broadcom */
++
++/*
++ * This module contains USB PHY initialization for power up and S3 resume
++ * for newer Synopsys based USB hardware first used on the bcm7216.
++ */
++
++#include <linux/delay.h>
++#include <linux/io.h>
++
++#include <linux/soc/brcmstb/brcmstb.h>
++#include "phy-brcm-usb-init.h"
++
++/* Register definitions for the USB CTRL block */
++#define USB_CTRL_SETUP			0x00
++#define   USB_CTRL_SETUP_STRAP_IPP_SEL_MASK		0x02000000
++#define   USB_CTRL_SETUP_SCB2_EN_MASK			0x00008000
++#define   USB_CTRL_SETUP_SCB1_EN_MASK			0x00004000
++#define   USB_CTRL_SETUP_SOFT_SHUTDOWN_MASK		0x00000200
++#define   USB_CTRL_SETUP_IPP_MASK			0x00000020
++#define   USB_CTRL_SETUP_IOC_MASK			0x00000010
++#define USB_CTRL_USB_PM			0x04
++#define   USB_CTRL_USB_PM_USB_PWRDN_MASK		0x80000000
++#define   USB_CTRL_USB_PM_SOFT_RESET_MASK		0x40000000
++#define   USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK		0x00800000
++#define   USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK		0x00400000
++#define USB_CTRL_USB_PM_STATUS		0x08
++#define USB_CTRL_USB_DEVICE_CTL1	0x10
++#define   USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK	0x00000003
++
++
++static void xhci_soft_reset(struct brcm_usb_init_params *params,
++			int on_off)
++{
++	void __iomem *ctrl = params->ctrl_regs;
++
++	/* Assert reset */
++	if (on_off)
++		USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB);
++	/* De-assert reset */
++	else
++		USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB);
++}
++
++static void usb_init_ipp(struct brcm_usb_init_params *params)
++{
++	void __iomem *ctrl = params->ctrl_regs;
++	u32 reg;
++	u32 orig_reg;
++
++	pr_debug("%s\n", __func__);
++
++	orig_reg = reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
++	if (params->ipp != 2)
++		/* override ipp strap pin (if it exits) */
++		reg &= ~(USB_CTRL_MASK(SETUP, STRAP_IPP_SEL));
++
++	/* Override the default OC and PP polarity */
++	reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
++	if (params->ioc)
++		reg |= USB_CTRL_MASK(SETUP, IOC);
++	if (params->ipp == 1)
++		reg |= USB_CTRL_MASK(SETUP, IPP);
++	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
++
++	/*
++	 * If we're changing IPP, make sure power is off long enough
++	 * to turn off any connected devices.
++	 */
++	if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
++		msleep(50);
++}
++
++static void usb_init_common(struct brcm_usb_init_params *params)
++{
++	u32 reg;
++	void __iomem *ctrl = params->ctrl_regs;
++
++	pr_debug("%s\n", __func__);
++
++	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
++	/* 1 millisecond - for USB clocks to settle down */
++	usleep_range(1000, 2000);
++
++	if (USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE)) {
++		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++		reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
++		reg |= params->mode;
++		brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++	}
++	switch (params->mode) {
++	case USB_CTLR_MODE_HOST:
++		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
++		break;
++	default:
++		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
++		USB_CTRL_SET(ctrl, USB_PM, BDC_SOFT_RESETB);
++		break;
++	}
++}
++
++static void usb_init_xhci(struct brcm_usb_init_params *params)
++{
++	pr_debug("%s\n", __func__);
++
++	xhci_soft_reset(params, 0);
++}
++
++static void usb_uninit_common(struct brcm_usb_init_params *params)
++{
++	void __iomem *ctrl = params->ctrl_regs;
++
++	pr_debug("%s\n", __func__);
++
++	USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
++
++}
++
++static void usb_uninit_xhci(struct brcm_usb_init_params *params)
++{
++
++	pr_debug("%s\n", __func__);
++
++	xhci_soft_reset(params, 1);
++}
++
++static int usb_get_dual_select(struct brcm_usb_init_params *params)
++{
++	void __iomem *ctrl = params->ctrl_regs;
++	u32 reg = 0;
++
++	pr_debug("%s\n", __func__);
++
++	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++	reg &= USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
++	return reg;
++}
++
++static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
++{
++	void __iomem *ctrl = params->ctrl_regs;
++	u32 reg;
++
++	pr_debug("%s\n", __func__);
++
++	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++	reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
++	reg |= mode;
++	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
++}
++
++
++static const struct brcm_usb_init_ops bcm7216_ops = {
++	.init_ipp = usb_init_ipp,
++	.init_common = usb_init_common,
++	.init_xhci = usb_init_xhci,
++	.uninit_common = usb_uninit_common,
++	.uninit_xhci = usb_uninit_xhci,
++	.get_dual_select = usb_get_dual_select,
++	.set_dual_select = usb_set_dual_select,
++};
++
++void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
++{
++
++	pr_debug("%s\n", __func__);
++
++	params->family_name = "7216";
++	params->ops = &bcm7216_ops;
++}
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.h
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
+@@ -43,6 +43,7 @@ struct brcm_usb_init_ops {
+ struct  brcm_usb_init_params {
+ 	void __iomem *ctrl_regs;
+ 	void __iomem *xhci_ec_regs;
++	void __iomem *xhci_gbl_regs;
+ 	int ioc;
+ 	int ipp;
+ 	int mode;
+@@ -55,6 +56,7 @@ struct  brcm_usb_init_params {
+ };
+ 
+ void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
++void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params);
+ 
+ static inline u32 brcm_usb_readl(void __iomem *addr)
+ {
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -241,6 +241,15 @@ static const struct attribute_group brcm
+ 	.attrs = brcm_usb_phy_attrs,
+ };
+ 
++static const struct of_device_id brcm_usb_dt_ids[] = {
++	{
++		.compatible = "brcm,bcm7216-usb-phy",
++		.data = &brcm_usb_dvr_init_7216,
++	},
++	{ .compatible = "brcm,brcmstb-usb-phy" },
++	{ /* sentinel */ }
++};
++
+ static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
+ 				 struct brcm_usb_phy_data *priv,
+ 				 struct device_node *dn)
+@@ -316,13 +325,16 @@ static int brcm_usb_phy_dvr_init(struct
+ 
+ static int brcm_usb_phy_probe(struct platform_device *pdev)
+ {
+-	struct resource *res;
++	struct resource *res_ctrl;
++	struct resource *res_xhciec = NULL;
++	struct resource *res_xhcigbl = NULL;
+ 	struct device *dev = &pdev->dev;
+ 	struct brcm_usb_phy_data *priv;
+ 	struct phy_provider *phy_provider;
+ 	struct device_node *dn = pdev->dev.of_node;
+ 	int err;
+ 	const char *mode;
++	const struct of_device_id *match;
+ 
+ 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ 	if (!priv)
+@@ -331,30 +343,59 @@ static int brcm_usb_phy_probe(struct pla
+ 
+ 	priv->ini.family_id = brcmstb_get_family_id();
+ 	priv->ini.product_id = brcmstb_get_product_id();
+-	brcm_usb_dvr_init_7445(&priv->ini);
++
++	match = of_match_node(brcm_usb_dt_ids, dev->of_node);
++	if (match && match->data) {
++		void (*dvr_init)(struct brcm_usb_init_params *params);
++
++		dvr_init = match->data;
++		(*dvr_init)(&priv->ini);
++	} else {
++		brcm_usb_dvr_init_7445(&priv->ini);
++	}
++
+ 	dev_dbg(dev, "Best mapping table is for %s\n",
+ 		priv->ini.family_name);
+-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	if (!res) {
+-		dev_err(dev, "can't get USB_CTRL base address\n");
+-		return -EINVAL;
++
++	/* Newer DT node has reg-names. xhci_ec and xhci_gbl are optional. */
++	res_ctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
++	if (res_ctrl != NULL) {
++		res_xhciec = platform_get_resource_byname(pdev,
++							  IORESOURCE_MEM,
++							  "xhci_ec");
++		res_xhcigbl = platform_get_resource_byname(pdev,
++							   IORESOURCE_MEM,
++							   "xhci_gbl");
++	} else {
++		/* Older DT node without reg-names, use index */
++		res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++		if (res_ctrl == NULL) {
++			dev_err(dev, "can't get CTRL base address\n");
++			return -EINVAL;
++		}
++		res_xhciec = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ 	}
+-	priv->ini.ctrl_regs = devm_ioremap_resource(dev, res);
++	priv->ini.ctrl_regs = devm_ioremap_resource(dev, res_ctrl);
+ 	if (IS_ERR(priv->ini.ctrl_regs)) {
+ 		dev_err(dev, "can't map CTRL register space\n");
+ 		return -EINVAL;
+ 	}
+-
+-	/* The XHCI EC registers are optional */
+-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+-	if (res) {
++	if (res_xhciec) {
+ 		priv->ini.xhci_ec_regs =
+-			devm_ioremap_resource(dev, res);
++			devm_ioremap_resource(dev, res_xhciec);
+ 		if (IS_ERR(priv->ini.xhci_ec_regs)) {
+ 			dev_err(dev, "can't map XHCI EC register space\n");
+ 			return -EINVAL;
+ 		}
+ 	}
++	if (res_xhcigbl) {
++		priv->ini.xhci_gbl_regs =
++			devm_ioremap_resource(dev, res_xhcigbl);
++		if (IS_ERR(priv->ini.xhci_gbl_regs)) {
++			dev_err(dev, "can't map XHCI Global register space\n");
++			return -EINVAL;
++		}
++	}
+ 
+ 	of_property_read_u32(dn, "brcm,ipp", &priv->ini.ipp);
+ 	of_property_read_u32(dn, "brcm,ioc", &priv->ini.ioc);
+@@ -480,11 +521,6 @@ static const struct dev_pm_ops brcm_usb_
+ 	SET_LATE_SYSTEM_SLEEP_PM_OPS(brcm_usb_phy_suspend, brcm_usb_phy_resume)
+ };
+ 
+-static const struct of_device_id brcm_usb_dt_ids[] = {
+-	{ .compatible = "brcm,brcmstb-usb-phy" },
+-	{ /* sentinel */ }
+-};
+-
+ MODULE_DEVICE_TABLE(of, brcm_usb_dt_ids);
+ 
+ static struct platform_driver brcm_usb_driver = {
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0008-phy-usb-Add-support-for-new-Synopsys-USB-controller-.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0008-phy-usb-Add-support-for-new-Synopsys-USB-controller-.patch
new file mode 100644
index 0000000000..008108c589
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0008-phy-usb-Add-support-for-new-Synopsys-USB-controller-.patch
@@ -0,0 +1,680 @@
+From 9d5f51dcdb646c2ed21649d379fbb703994f1ec9 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:06 -0500
+Subject: [PATCH] phy: usb: Add support for new Synopsys USB controller on the
+ 7211b0
+
+The 7211b0 has added the STB XHCI Synopsys controller and it
+will be used instead of the RPi based DWC USB controller. The new
+Synopsys XHCI controller core is the same one that is used on the
+7216, but because of the way the STB USB PHY is used on both the A0
+and B0, some of the PHY control is different.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ .../phy/broadcom/phy-brcm-usb-init-synopsys.c | 163 +++++++++++++++++-
+ drivers/phy/broadcom/phy-brcm-usb-init.c      |  31 ++--
+ drivers/phy/broadcom/phy-brcm-usb-init.h      |  17 +-
+ drivers/phy/broadcom/phy-brcm-usb.c           | 162 +++++++++++------
+ 4 files changed, 295 insertions(+), 78 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+@@ -12,10 +12,33 @@
+ #include <linux/soc/brcmstb/brcmstb.h>
+ #include "phy-brcm-usb-init.h"
+ 
++#define PHY_LOCK_TIMEOUT_MS 200
++
++/* Register definitions for syscon piarbctl registers */
++#define PIARBCTL_CAM			0x00
++#define PIARBCTL_SPLITTER		0x04
++#define PIARBCTL_MISC			0x08
++#define   PIARBCTL_MISC_SECURE_MASK			0x80000000
++#define   PIARBCTL_MISC_USB_SELECT_MASK			0x40000000
++#define   PIARBCTL_MISC_USB_4G_SDRAM_MASK		0x20000000
++#define   PIARBCTL_MISC_USB_PRIORITY_MASK		0x000f0000
++#define   PIARBCTL_MISC_USB_MEM_PAGE_MASK		0x0000f000
++#define   PIARBCTL_MISC_CAM1_MEM_PAGE_MASK		0x00000f00
++#define   PIARBCTL_MISC_CAM0_MEM_PAGE_MASK		0x000000f0
++#define   PIARBCTL_MISC_SATA_PRIORITY_MASK		0x0000000f
++#define PIARBCTL_USB_M_ASB_CTRL		0x10
++
++#define PIARBCTL_MISC_USB_ONLY_MASK		\
++	(PIARBCTL_MISC_USB_SELECT_MASK |	\
++	 PIARBCTL_MISC_USB_4G_SDRAM_MASK |	\
++	 PIARBCTL_MISC_USB_PRIORITY_MASK |	\
++	 PIARBCTL_MISC_USB_MEM_PAGE_MASK)
++
+ /* Register definitions for the USB CTRL block */
+ #define USB_CTRL_SETUP			0x00
+ #define   USB_CTRL_SETUP_STRAP_IPP_SEL_MASK		0x02000000
+ #define   USB_CTRL_SETUP_SCB2_EN_MASK			0x00008000
++#define   USB_CTRL_SETUP_tca_drv_sel_MASK		0x01000000
+ #define   USB_CTRL_SETUP_SCB1_EN_MASK			0x00004000
+ #define   USB_CTRL_SETUP_SOFT_SHUTDOWN_MASK		0x00000200
+ #define   USB_CTRL_SETUP_IPP_MASK			0x00000020
+@@ -29,11 +52,73 @@
+ #define USB_CTRL_USB_DEVICE_CTL1	0x10
+ #define   USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK	0x00000003
+ 
++/* Register definitions for the USB_PHY block in 7211b0 */
++#define USB_PHY_PLL_LDO_CTL		0x08
++#define   USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK		0x00000004
++#define USB_PHY_UTMI_CTL_1		0x04
++#define   USB_PHY_UTMI_CTL_1_PHY_MODE_MASK		0x0000000c
++#define   USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT		2
++#define USB_PHY_STATUS			0x20
++#define   USB_PHY_STATUS_pll_lock_MASK			0x00000001
++
++/* Register definitions for the MDIO registers in the DWC2 block of
++ * the 7211b0.
++ * NOTE: The PHY's MDIO registers are only accessible through the
++ * legacy DesignWare USB controller even though it's not being used.
++ */
++#define USB_GMDIOCSR	0
++#define USB_GMDIOGEN	4
++
++
++static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params,
++				  uint8_t addr, uint16_t data)
++{
++	void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
++
++	addr &= 0x1f; /* 5-bit address */
++	brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
++	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
++		;
++	brcm_usb_writel(0x59020000 | (addr << 18) | data,
++			usb_mdio + USB_GMDIOGEN);
++	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
++		;
++	brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
++	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
++		;
++}
++
++static uint16_t __maybe_unused usb_mdio_read_7211b0(
++	struct brcm_usb_init_params *params, uint8_t addr)
++{
++	void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
++
++	addr &= 0x1f; /* 5-bit address */
++	brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
++	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
++		;
++	brcm_usb_writel(0x69020000 | (addr << 18), usb_mdio + USB_GMDIOGEN);
++	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
++		;
++	brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
++	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
++		;
++	return brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & 0xffff;
++}
++
++static void usb2_eye_fix_7211b0(struct brcm_usb_init_params *params)
++{
++	/* select bank */
++	usb_mdio_write_7211b0(params, 0x1f, 0x80a0);
++
++	/* Set the eye */
++	usb_mdio_write_7211b0(params, 0x0a, 0xc6a0);
++}
+ 
+ static void xhci_soft_reset(struct brcm_usb_init_params *params,
+ 			int on_off)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 
+ 	/* Assert reset */
+ 	if (on_off)
+@@ -45,7 +130,7 @@ static void xhci_soft_reset(struct brcm_
+ 
+ static void usb_init_ipp(struct brcm_usb_init_params *params)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 	u32 reg;
+ 	u32 orig_reg;
+ 
+@@ -72,10 +157,18 @@ static void usb_init_ipp(struct brcm_usb
+ 		msleep(50);
+ }
+ 
++static void syscon_piarbctl_init(struct regmap *rmap)
++{
++	/* Switch from legacy USB OTG controller to new STB USB controller */
++	regmap_update_bits(rmap, PIARBCTL_MISC, PIARBCTL_MISC_USB_ONLY_MASK,
++			   PIARBCTL_MISC_USB_SELECT_MASK |
++			   PIARBCTL_MISC_USB_4G_SDRAM_MASK);
++}
++
+ static void usb_init_common(struct brcm_usb_init_params *params)
+ {
+ 	u32 reg;
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 
+ 	pr_debug("%s\n", __func__);
+ 
+@@ -100,6 +193,45 @@ static void usb_init_common(struct brcm_
+ 	}
+ }
+ 
++static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
++{
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
++	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
++	int timeout_ms = PHY_LOCK_TIMEOUT_MS;
++	u32 reg;
++
++	if (params->syscon_piarbctl)
++		syscon_piarbctl_init(params->syscon_piarbctl);
++
++	/* Init the PHY */
++	reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_LDO_CTL);
++	reg |= USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK;
++	brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
++
++	/* wait for lock */
++	while (timeout_ms-- > 0) {
++		reg = brcm_usb_readl(usb_phy + USB_PHY_STATUS);
++		if (reg & USB_PHY_STATUS_pll_lock_MASK)
++			break;
++		usleep_range(1000, 2000);
++	}
++
++	/* Set the PHY_MODE */
++	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
++	reg &= ~USB_PHY_UTMI_CTL_1_PHY_MODE_MASK;
++	reg |= params->mode << USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT;
++	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
++
++	/* Fix the incorrect default */
++	reg = brcm_usb_readl(ctrl + USB_CTRL_SETUP);
++	reg &= ~USB_CTRL_SETUP_tca_drv_sel_MASK;
++	brcm_usb_writel(reg, ctrl + USB_CTRL_SETUP);
++
++	usb_init_common(params);
++
++	usb2_eye_fix_7211b0(params);
++}
++
+ static void usb_init_xhci(struct brcm_usb_init_params *params)
+ {
+ 	pr_debug("%s\n", __func__);
+@@ -109,7 +241,7 @@ static void usb_init_xhci(struct brcm_us
+ 
+ static void usb_uninit_common(struct brcm_usb_init_params *params)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 
+ 	pr_debug("%s\n", __func__);
+ 
+@@ -127,7 +259,7 @@ static void usb_uninit_xhci(struct brcm_
+ 
+ static int usb_get_dual_select(struct brcm_usb_init_params *params)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 	u32 reg = 0;
+ 
+ 	pr_debug("%s\n", __func__);
+@@ -139,7 +271,7 @@ static int usb_get_dual_select(struct br
+ 
+ static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 	u32 reg;
+ 
+ 	pr_debug("%s\n", __func__);
+@@ -161,6 +293,16 @@ static const struct brcm_usb_init_ops bc
+ 	.set_dual_select = usb_set_dual_select,
+ };
+ 
++static const struct brcm_usb_init_ops bcm7211b0_ops = {
++	.init_ipp = usb_init_ipp,
++	.init_common = usb_init_common_7211b0,
++	.init_xhci = usb_init_xhci,
++	.uninit_common = usb_uninit_common,
++	.uninit_xhci = usb_uninit_xhci,
++	.get_dual_select = usb_get_dual_select,
++	.set_dual_select = usb_set_dual_select,
++};
++
+ void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
+ {
+ 
+@@ -169,3 +311,12 @@ void brcm_usb_dvr_init_7216(struct brcm_
+ 	params->family_name = "7216";
+ 	params->ops = &bcm7216_ops;
+ }
++
++void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
++{
++
++	pr_debug("%s\n", __func__);
++
++	params->family_name = "7211";
++	params->ops = &bcm7211b0_ops;
++}
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
+@@ -401,7 +401,7 @@ void usb_ctrl_unset_family(struct brcm_u
+ 	u32 mask;
+ 
+ 	mask = params->usb_reg_bits_map[field];
+-	brcm_usb_ctrl_unset(params->ctrl_regs + reg_offset, mask);
++	brcm_usb_ctrl_unset(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);
+ };
+ 
+ static inline
+@@ -411,7 +411,7 @@ void usb_ctrl_set_family(struct brcm_usb
+ 	u32 mask;
+ 
+ 	mask = params->usb_reg_bits_map[field];
+-	brcm_usb_ctrl_set(params->ctrl_regs + reg_offset, mask);
++	brcm_usb_ctrl_set(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);
+ };
+ 
+ static u32 brcmusb_usb_mdio_read(void __iomem *ctrl_base, u32 reg, int mode)
+@@ -544,7 +544,7 @@ static void brcmusb_usb3_pll_54mhz(struc
+ {
+ 	u32 ofs;
+ 	int ii;
+-	void __iomem *ctrl_base = params->ctrl_regs;
++	void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];
+ 
+ 	/*
+ 	 * On newer B53 based SoC's, the reference clock for the
+@@ -625,7 +625,7 @@ static void brcmusb_usb3_ssc_enable(void
+ 
+ static void brcmusb_usb3_phy_workarounds(struct brcm_usb_init_params *params)
+ {
+-	void __iomem *ctrl_base = params->ctrl_regs;
++	void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];
+ 
+ 	brcmusb_usb3_pll_fix(ctrl_base);
+ 	brcmusb_usb3_pll_54mhz(params);
+@@ -667,7 +667,7 @@ static void brcmusb_memc_fix(struct brcm
+ 
+ static void brcmusb_usb3_otp_fix(struct brcm_usb_init_params *params)
+ {
+-	void __iomem *xhci_ec_base = params->xhci_ec_regs;
++	void __iomem *xhci_ec_base = params->regs[BRCM_REGS_XHCI_EC];
+ 	u32 val;
+ 
+ 	if (params->family_id != 0x74371000 || !xhci_ec_base)
+@@ -680,8 +680,8 @@ static void brcmusb_usb3_otp_fix(struct
+ 	brcm_usb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
+ 
+ 	/* Reset USB 3.0 PHY for workaround to take effect */
+-	USB_CTRL_UNSET(params->ctrl_regs, USB30_CTL1, PHY3_RESETB);
+-	USB_CTRL_SET(params->ctrl_regs,	USB30_CTL1, PHY3_RESETB);
++	USB_CTRL_UNSET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);
++	USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);
+ }
+ 
+ static void brcmusb_xhci_soft_reset(struct brcm_usb_init_params *params,
+@@ -740,7 +740,7 @@ static enum brcm_family_type get_family_
+ 
+ static void usb_init_ipp(struct brcm_usb_init_params *params)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 	u32 reg;
+ 	u32 orig_reg;
+ 
+@@ -786,7 +786,7 @@ static void usb_init_ipp(struct brcm_usb
+ static void usb_init_common(struct brcm_usb_init_params *params)
+ {
+ 	u32 reg;
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 
+ 	/* Clear any pending wake conditions */
+ 	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
+@@ -866,7 +866,7 @@ static void usb_init_common(struct brcm_
+ static void usb_init_eohci(struct brcm_usb_init_params *params)
+ {
+ 	u32 reg;
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 
+ 	if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB20_HC_RESETB))
+ 		USB_CTRL_SET_FAMILY(params, USB_PM, USB20_HC_RESETB);
+@@ -902,7 +902,7 @@ static void usb_init_eohci(struct brcm_u
+ 
+ static void usb_init_xhci(struct brcm_usb_init_params *params)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 
+ 	USB_CTRL_UNSET(ctrl, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
+ 	/* 1 millisecond - for USB clocks to settle down */
+@@ -944,12 +944,13 @@ static void usb_uninit_eohci(struct brcm
+ static void usb_uninit_xhci(struct brcm_usb_init_params *params)
+ {
+ 	brcmusb_xhci_soft_reset(params, 1);
+-	USB_CTRL_SET(params->ctrl_regs, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
++	USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_PCTL,
++		     PHY3_IDDQ_OVERRIDE);
+ }
+ 
+ static int usb_get_dual_select(struct brcm_usb_init_params *params)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 	u32 reg = 0;
+ 
+ 	pr_debug("%s\n", __func__);
+@@ -963,7 +964,7 @@ static int usb_get_dual_select(struct br
+ 
+ static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 	u32 reg;
+ 
+ 	pr_debug("%s\n", __func__);
+@@ -980,7 +981,7 @@ static void usb_set_dual_select(struct b
+ static void usb_wake_enable(struct brcm_usb_init_params *params,
+ 			  int enable)
+ {
+-	void __iomem *ctrl = params->ctrl_regs;
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 
+ 	if (enable)
+ 		USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.h
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
+@@ -6,12 +6,21 @@
+ #ifndef _USB_BRCM_COMMON_INIT_H
+ #define _USB_BRCM_COMMON_INIT_H
+ 
++#include <linux/regmap.h>
++
+ #define USB_CTLR_MODE_HOST 0
+ #define USB_CTLR_MODE_DEVICE 1
+ #define USB_CTLR_MODE_DRD 2
+ #define USB_CTLR_MODE_TYPEC_PD 3
+ 
+-struct  brcm_usb_init_params;
++enum brcmusb_reg_sel {
++	BRCM_REGS_CTRL = 0,
++	BRCM_REGS_XHCI_EC,
++	BRCM_REGS_XHCI_GBL,
++	BRCM_REGS_USB_PHY,
++	BRCM_REGS_USB_MDIO,
++	BRCM_REGS_MAX
++};
+ 
+ #define USB_CTRL_REG(base, reg)	((void __iomem *)base + USB_CTRL_##reg)
+ #define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
+@@ -41,9 +50,7 @@ struct brcm_usb_init_ops {
+ };
+ 
+ struct  brcm_usb_init_params {
+-	void __iomem *ctrl_regs;
+-	void __iomem *xhci_ec_regs;
+-	void __iomem *xhci_gbl_regs;
++	void __iomem *regs[BRCM_REGS_MAX];
+ 	int ioc;
+ 	int ipp;
+ 	int mode;
+@@ -53,10 +60,12 @@ struct  brcm_usb_init_params {
+ 	const char *family_name;
+ 	const u32 *usb_reg_bits_map;
+ 	const struct brcm_usb_init_ops *ops;
++	struct regmap *syscon_piarbctl;
+ };
+ 
+ void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
+ void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params);
++void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params);
+ 
+ static inline u32 brcm_usb_readl(void __iomem *addr)
+ {
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -16,6 +16,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/soc/brcmstb/brcmstb.h>
+ #include <dt-bindings/phy/phy.h>
++#include <linux/mfd/syscon.h>
+ 
+ #include "phy-brcm-usb-init.h"
+ 
+@@ -32,6 +33,11 @@ struct value_to_name_map {
+ 	const char *name;
+ };
+ 
++struct match_chip_info {
++	void *init_func;
++	u8 required_regs[BRCM_REGS_MAX + 1];
++};
++
+ static struct value_to_name_map brcm_dr_mode_to_name[] = {
+ 	{ USB_CTLR_MODE_HOST, "host" },
+ 	{ USB_CTLR_MODE_DEVICE, "peripheral" },
+@@ -64,6 +70,10 @@ struct brcm_usb_phy_data {
+ 	struct brcm_usb_phy	phys[BRCM_USB_PHY_ID_MAX];
+ };
+ 
++static s8 *node_reg_names[BRCM_REGS_MAX] = {
++	"crtl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio"
++};
++
+ static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
+ {
+ 	struct phy *gphy = dev_id;
+@@ -241,15 +251,86 @@ static const struct attribute_group brcm
+ 	.attrs = brcm_usb_phy_attrs,
+ };
+ 
++static struct match_chip_info chip_info_7216 = {
++	.init_func = &brcm_usb_dvr_init_7216,
++	.required_regs = {
++		BRCM_REGS_CTRL,
++		BRCM_REGS_XHCI_EC,
++		BRCM_REGS_XHCI_GBL,
++		-1,
++	},
++};
++
++static struct match_chip_info chip_info_7211b0 = {
++	.init_func = &brcm_usb_dvr_init_7211b0,
++	.required_regs = {
++		BRCM_REGS_CTRL,
++		BRCM_REGS_XHCI_EC,
++		BRCM_REGS_XHCI_GBL,
++		BRCM_REGS_USB_PHY,
++		BRCM_REGS_USB_MDIO,
++		-1,
++	},
++};
++
++static struct match_chip_info chip_info_7445 = {
++	.init_func = &brcm_usb_dvr_init_7445,
++	.required_regs = {
++		BRCM_REGS_CTRL,
++		BRCM_REGS_XHCI_EC,
++		-1,
++	},
++};
++
+ static const struct of_device_id brcm_usb_dt_ids[] = {
+ 	{
+ 		.compatible = "brcm,bcm7216-usb-phy",
+-		.data = &brcm_usb_dvr_init_7216,
++		.data = &chip_info_7216,
++	},
++	{
++		.compatible = "brcm,bcm7211-usb-phy",
++		.data = &chip_info_7211b0,
++	},
++	{
++		.compatible = "brcm,brcmstb-usb-phy",
++		.data = &chip_info_7445,
+ 	},
+-	{ .compatible = "brcm,brcmstb-usb-phy" },
+ 	{ /* sentinel */ }
+ };
+ 
++static int brcm_usb_get_regs(struct platform_device *pdev,
++			     enum brcmusb_reg_sel regs,
++			     struct  brcm_usb_init_params *ini)
++{
++	struct resource *res;
++
++	/* Older DT nodes have ctrl and optional xhci_ec by index only */
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
++						node_reg_names[regs]);
++	if (res == NULL) {
++		if (regs == BRCM_REGS_CTRL) {
++			res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++		} else if (regs == BRCM_REGS_XHCI_EC) {
++			res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++			/* XHCI_EC registers are optional */
++			if (res == NULL)
++				return 0;
++		}
++		if (res == NULL) {
++			dev_err(&pdev->dev, "can't get %s base address\n",
++				node_reg_names[regs]);
++			return 1;
++		}
++	}
++	ini->regs[regs] = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(ini->regs[regs])) {
++		dev_err(&pdev->dev, "can't map %s register space\n",
++			node_reg_names[regs]);
++		return 1;
++	}
++	return 0;
++}
++
+ static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
+ 				 struct brcm_usb_phy_data *priv,
+ 				 struct device_node *dn)
+@@ -325,9 +406,6 @@ static int brcm_usb_phy_dvr_init(struct
+ 
+ static int brcm_usb_phy_probe(struct platform_device *pdev)
+ {
+-	struct resource *res_ctrl;
+-	struct resource *res_xhciec = NULL;
+-	struct resource *res_xhcigbl = NULL;
+ 	struct device *dev = &pdev->dev;
+ 	struct brcm_usb_phy_data *priv;
+ 	struct phy_provider *phy_provider;
+@@ -335,6 +413,10 @@ static int brcm_usb_phy_probe(struct pla
+ 	int err;
+ 	const char *mode;
+ 	const struct of_device_id *match;
++	void (*dvr_init)(struct brcm_usb_init_params *params);
++	const struct match_chip_info *info;
++	struct regmap *rmap;
++	int x;
+ 
+ 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ 	if (!priv)
+@@ -345,58 +427,13 @@ static int brcm_usb_phy_probe(struct pla
+ 	priv->ini.product_id = brcmstb_get_product_id();
+ 
+ 	match = of_match_node(brcm_usb_dt_ids, dev->of_node);
+-	if (match && match->data) {
+-		void (*dvr_init)(struct brcm_usb_init_params *params);
+-
+-		dvr_init = match->data;
+-		(*dvr_init)(&priv->ini);
+-	} else {
+-		brcm_usb_dvr_init_7445(&priv->ini);
+-	}
++	info = match->data;
++	dvr_init = info->init_func;
++	(*dvr_init)(&priv->ini);
+ 
+ 	dev_dbg(dev, "Best mapping table is for %s\n",
+ 		priv->ini.family_name);
+ 
+-	/* Newer DT node has reg-names. xhci_ec and xhci_gbl are optional. */
+-	res_ctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
+-	if (res_ctrl != NULL) {
+-		res_xhciec = platform_get_resource_byname(pdev,
+-							  IORESOURCE_MEM,
+-							  "xhci_ec");
+-		res_xhcigbl = platform_get_resource_byname(pdev,
+-							   IORESOURCE_MEM,
+-							   "xhci_gbl");
+-	} else {
+-		/* Older DT node without reg-names, use index */
+-		res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-		if (res_ctrl == NULL) {
+-			dev_err(dev, "can't get CTRL base address\n");
+-			return -EINVAL;
+-		}
+-		res_xhciec = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+-	}
+-	priv->ini.ctrl_regs = devm_ioremap_resource(dev, res_ctrl);
+-	if (IS_ERR(priv->ini.ctrl_regs)) {
+-		dev_err(dev, "can't map CTRL register space\n");
+-		return -EINVAL;
+-	}
+-	if (res_xhciec) {
+-		priv->ini.xhci_ec_regs =
+-			devm_ioremap_resource(dev, res_xhciec);
+-		if (IS_ERR(priv->ini.xhci_ec_regs)) {
+-			dev_err(dev, "can't map XHCI EC register space\n");
+-			return -EINVAL;
+-		}
+-	}
+-	if (res_xhcigbl) {
+-		priv->ini.xhci_gbl_regs =
+-			devm_ioremap_resource(dev, res_xhcigbl);
+-		if (IS_ERR(priv->ini.xhci_gbl_regs)) {
+-			dev_err(dev, "can't map XHCI Global register space\n");
+-			return -EINVAL;
+-		}
+-	}
+-
+ 	of_property_read_u32(dn, "brcm,ipp", &priv->ini.ipp);
+ 	of_property_read_u32(dn, "brcm,ioc", &priv->ini.ioc);
+ 
+@@ -412,6 +449,16 @@ static int brcm_usb_phy_probe(struct pla
+ 	if (of_property_read_bool(dn, "brcm,has-eohci"))
+ 		priv->has_eohci = true;
+ 
++	for (x = 0; x < BRCM_REGS_MAX; x++) {
++		if (info->required_regs[x] >= BRCM_REGS_MAX)
++			break;
++
++		err = brcm_usb_get_regs(pdev, info->required_regs[x],
++					&priv->ini);
++		if (err)
++			return -EINVAL;
++	}
++
+ 	err = brcm_usb_phy_dvr_init(pdev, priv, dn);
+ 	if (err)
+ 		return err;
+@@ -431,6 +478,15 @@ static int brcm_usb_phy_probe(struct pla
+ 	if (err)
+ 		dev_warn(dev, "Error creating sysfs attributes\n");
+ 
++	/* Get piarbctl syscon if it exists */
++	rmap = syscon_regmap_lookup_by_phandle(dev->of_node,
++						 "syscon-piarbctl");
++	if (IS_ERR(rmap))
++		rmap = syscon_regmap_lookup_by_phandle(dev->of_node,
++						       "brcm,syscon-piarbctl");
++	if (!IS_ERR(rmap))
++		priv->ini.syscon_piarbctl = rmap;
++
+ 	/* start with everything off */
+ 	if (priv->has_xhci)
+ 		brcm_usb_uninit_xhci(&priv->ini);
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0009-phy-usb-fix-driver-to-defer-on-clk_get-defer.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0009-phy-usb-fix-driver-to-defer-on-clk_get-defer.patch
new file mode 100644
index 0000000000..a9e4b60ea6
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0009-phy-usb-fix-driver-to-defer-on-clk_get-defer.patch
@@ -0,0 +1,44 @@
+From 89927fe0061aaa69b39e95ed793d2c61903b7895 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:07 -0500
+Subject: [PATCH] phy: usb: fix driver to defer on clk_get defer
+
+Handle defer on clk_get because the new SCMI clock driver comes
+up after this driver.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -341,6 +341,8 @@ static int brcm_usb_phy_dvr_init(struct
+ 
+ 	priv->usb_20_clk = of_clk_get_by_name(dn, "sw_usb");
+ 	if (IS_ERR(priv->usb_20_clk)) {
++		if (PTR_ERR(priv->usb_20_clk) == -EPROBE_DEFER)
++			return -EPROBE_DEFER;
+ 		dev_info(dev, "Clock not found in Device Tree\n");
+ 		priv->usb_20_clk = NULL;
+ 	}
+@@ -371,6 +373,8 @@ static int brcm_usb_phy_dvr_init(struct
+ 
+ 		priv->usb_30_clk = of_clk_get_by_name(dn, "sw_usb3");
+ 		if (IS_ERR(priv->usb_30_clk)) {
++			if (PTR_ERR(priv->usb_30_clk) == -EPROBE_DEFER)
++				return -EPROBE_DEFER;
+ 			dev_info(dev,
+ 				 "USB3.0 clock not found in Device Tree\n");
+ 			priv->usb_30_clk = NULL;
+@@ -382,6 +386,8 @@ static int brcm_usb_phy_dvr_init(struct
+ 
+ 	priv->suspend_clk = clk_get(dev, "usb0_freerun");
+ 	if (IS_ERR(priv->suspend_clk)) {
++		if (PTR_ERR(priv->suspend_clk) == -EPROBE_DEFER)
++			return -EPROBE_DEFER;
+ 		dev_err(dev, "Suspend Clock not found in Device Tree\n");
+ 		priv->suspend_clk = NULL;
+ 	}
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0010-phy-usb-PHY-s-MDIO-registers-not-accessible-without-.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0010-phy-usb-PHY-s-MDIO-registers-not-accessible-without-.patch
new file mode 100644
index 0000000000..48f829f799
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0010-phy-usb-PHY-s-MDIO-registers-not-accessible-without-.patch
@@ -0,0 +1,44 @@
+From fc430aea02068150d053ef24bc424db3dd1357d4 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:08 -0500
+Subject: [PATCH] phy: usb: PHY's MDIO registers not accessible without device
+ installed
+
+When there is no device connected and FSM is enabled, the XHCI puts
+the PHY into suspend mode.  When the PHY is put into suspend mode
+the USB LDO powers down the PHY. This causes the MDIO to be
+inaccessible and its registers reset to default. The fix is to
+disable FSM.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+@@ -56,6 +56,7 @@
+ #define USB_PHY_PLL_LDO_CTL		0x08
+ #define   USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK		0x00000004
+ #define USB_PHY_UTMI_CTL_1		0x04
++#define   USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK	0x00000800
+ #define   USB_PHY_UTMI_CTL_1_PHY_MODE_MASK		0x0000000c
+ #define   USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT		2
+ #define USB_PHY_STATUS			0x20
+@@ -229,6 +230,14 @@ static void usb_init_common_7211b0(struc
+ 
+ 	usb_init_common(params);
+ 
++	/*
++	 * Disable FSM, otherwise the PHY will auto suspend when no
++	 * device is connected and will be reset on resume.
++	 */
++	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
++	reg &= ~USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
++	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
++
+ 	usb2_eye_fix_7211b0(params);
+ }
+ 
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0011-phy-usb-bdc-Fix-occasional-failure-with-BDC-on-7211.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0011-phy-usb-bdc-Fix-occasional-failure-with-BDC-on-7211.patch
new file mode 100644
index 0000000000..80ec141685
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0011-phy-usb-bdc-Fix-occasional-failure-with-BDC-on-7211.patch
@@ -0,0 +1,135 @@
+From bed63b636fedf47dbab899a5193ec5ec4539f6fc Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:09 -0500
+Subject: [PATCH] phy: usb: bdc: Fix occasional failure with BDC on 7211
+
+The BDC "Read Transaction Size" needs to be changed from 1024
+bytes to 256 bytes to prevent occasional transaction failures.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ .../phy/broadcom/phy-brcm-usb-init-synopsys.c | 18 +++++++++++++++
+ drivers/phy/broadcom/phy-brcm-usb-init.h      |  1 +
+ drivers/phy/broadcom/phy-brcm-usb.c           | 23 +++++++++++++++----
+ 3 files changed, 38 insertions(+), 4 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+@@ -70,6 +70,11 @@
+ #define USB_GMDIOCSR	0
+ #define USB_GMDIOGEN	4
+ 
++/* Register definitions for the BDC EC block in 7211b0 */
++#define BDC_EC_AXIRDA			0x0c
++#define   BDC_EC_AXIRDA_RTS_MASK			0xf0000000
++#define   BDC_EC_AXIRDA_RTS_SHIFT			28
++
+ 
+ static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params,
+ 				  uint8_t addr, uint16_t data)
+@@ -198,6 +203,7 @@ static void usb_init_common_7211b0(struc
+ {
+ 	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
++	void __iomem *bdc_ec = params->regs[BRCM_REGS_BDC_EC];
+ 	int timeout_ms = PHY_LOCK_TIMEOUT_MS;
+ 	u32 reg;
+ 
+@@ -231,6 +237,18 @@ static void usb_init_common_7211b0(struc
+ 	usb_init_common(params);
+ 
+ 	/*
++	 * The BDC controller will get occasional failures with
++	 * the default "Read Transaction Size" of 6 (1024 bytes).
++	 * Set it to 4 (256 bytes).
++	 */
++	if ((params->mode != USB_CTLR_MODE_HOST) && bdc_ec) {
++		reg = brcm_usb_readl(bdc_ec + BDC_EC_AXIRDA);
++		reg &= ~BDC_EC_AXIRDA_RTS_MASK;
++		reg |= (0x4 << BDC_EC_AXIRDA_RTS_SHIFT);
++		brcm_usb_writel(reg, bdc_ec + BDC_EC_AXIRDA);
++	}
++
++	/*
+ 	 * Disable FSM, otherwise the PHY will auto suspend when no
+ 	 * device is connected and will be reset on resume.
+ 	 */
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.h
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
+@@ -19,6 +19,7 @@ enum brcmusb_reg_sel {
+ 	BRCM_REGS_XHCI_GBL,
+ 	BRCM_REGS_USB_PHY,
+ 	BRCM_REGS_USB_MDIO,
++	BRCM_REGS_BDC_EC,
+ 	BRCM_REGS_MAX
+ };
+ 
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -36,6 +36,7 @@ struct value_to_name_map {
+ struct match_chip_info {
+ 	void *init_func;
+ 	u8 required_regs[BRCM_REGS_MAX + 1];
++	u8 optional_reg;
+ };
+ 
+ static struct value_to_name_map brcm_dr_mode_to_name[] = {
+@@ -71,7 +72,7 @@ struct brcm_usb_phy_data {
+ };
+ 
+ static s8 *node_reg_names[BRCM_REGS_MAX] = {
+-	"crtl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio"
++	"crtl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec"
+ };
+ 
+ static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
+@@ -271,6 +272,7 @@ static struct match_chip_info chip_info_
+ 		BRCM_REGS_USB_MDIO,
+ 		-1,
+ 	},
++	.optional_reg = BRCM_REGS_BDC_EC,
+ };
+ 
+ static struct match_chip_info chip_info_7445 = {
+@@ -300,7 +302,8 @@ static const struct of_device_id brcm_us
+ 
+ static int brcm_usb_get_regs(struct platform_device *pdev,
+ 			     enum brcmusb_reg_sel regs,
+-			     struct  brcm_usb_init_params *ini)
++			     struct  brcm_usb_init_params *ini,
++			     bool optional)
+ {
+ 	struct resource *res;
+ 
+@@ -317,7 +320,13 @@ static int brcm_usb_get_regs(struct plat
+ 				return 0;
+ 		}
+ 		if (res == NULL) {
+-			dev_err(&pdev->dev, "can't get %s base address\n",
++			if (optional) {
++				dev_dbg(&pdev->dev,
++					"Optional reg %s not found\n",
++					node_reg_names[regs]);
++				return 0;
++			}
++			dev_err(&pdev->dev, "can't get %s base addr\n",
+ 				node_reg_names[regs]);
+ 			return 1;
+ 		}
+@@ -460,7 +469,13 @@ static int brcm_usb_phy_probe(struct pla
+ 			break;
+ 
+ 		err = brcm_usb_get_regs(pdev, info->required_regs[x],
+-					&priv->ini);
++					&priv->ini, false);
++		if (err)
++			return -EINVAL;
++	}
++	if (info->optional_reg) {
++		err = brcm_usb_get_regs(pdev, info->optional_reg,
++					&priv->ini, true);
+ 		if (err)
+ 			return -EINVAL;
+ 	}
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0012-phy-usb-USB-driver-is-crashing-during-S3-resume-on-7.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0012-phy-usb-USB-driver-is-crashing-during-S3-resume-on-7.patch
new file mode 100644
index 0000000000..b10f86d0a3
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0012-phy-usb-USB-driver-is-crashing-during-S3-resume-on-7.patch
@@ -0,0 +1,26 @@
+From 5dfe1cec580829faa49842672a25481b104c26ef Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:10 -0500
+Subject: [PATCH] phy: usb: USB driver is crashing during S3 resume on 7216
+
+This is a result of the USB 2.0 clocks not being disabled/enabled
+during suspend/resume on XHCI only systems.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -543,7 +543,7 @@ static int brcm_usb_phy_suspend(struct d
+ 		brcm_usb_wake_enable(&priv->ini, true);
+ 		if (priv->phys[BRCM_USB_PHY_3_0].inited)
+ 			clk_disable_unprepare(priv->usb_30_clk);
+-		if (priv->phys[BRCM_USB_PHY_2_0].inited)
++		if (priv->phys[BRCM_USB_PHY_2_0].inited || !priv->has_eohci)
+ 			clk_disable_unprepare(priv->usb_20_clk);
+ 		if (priv->wake_irq >= 0)
+ 			enable_irq_wake(priv->wake_irq);
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0013-phy-usb-Add-support-for-wake-and-USB-low-power-mode-.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0013-phy-usb-Add-support-for-wake-and-USB-low-power-mode-.patch
new file mode 100644
index 0000000000..5a3a687adb
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/084-v5.6-0013-phy-usb-Add-support-for-wake-and-USB-low-power-mode-.patch
@@ -0,0 +1,328 @@
+From b0c0b66c0b432d3f3a1ae5849298ba9c7f1810c5 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx at gmail.com>
+Date: Fri, 3 Jan 2020 13:18:11 -0500
+Subject: [PATCH] phy: usb: Add support for wake and USB low power mode for
+ 7211 S2/S5
+
+Add support for 7211 USB wake. Disable all possible 7211 USB logic
+for S2/S5 if USB wake is not enabled.
+
+On the 7211, the XHCI wake signal was not connected properly and
+only goes to the USB1_USB1_CTRL_TP_DIAG1 diagonstic register.
+The workaround is to have VPU code running that polls for the
+proper bit in the DIAG register and to wake the system when
+the bit is asserted.
+
+Signed-off-by: Al Cooper <alcooperx at gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ .../phy/broadcom/phy-brcm-usb-init-synopsys.c | 77 +++++++++++++++++--
+ drivers/phy/broadcom/phy-brcm-usb-init.c      | 26 ++++---
+ drivers/phy/broadcom/phy-brcm-usb-init.h      | 11 +--
+ drivers/phy/broadcom/phy-brcm-usb.c           | 25 ++++--
+ 4 files changed, 105 insertions(+), 34 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+@@ -26,7 +26,6 @@
+ #define   PIARBCTL_MISC_CAM1_MEM_PAGE_MASK		0x00000f00
+ #define   PIARBCTL_MISC_CAM0_MEM_PAGE_MASK		0x000000f0
+ #define   PIARBCTL_MISC_SATA_PRIORITY_MASK		0x0000000f
+-#define PIARBCTL_USB_M_ASB_CTRL		0x10
+ 
+ #define PIARBCTL_MISC_USB_ONLY_MASK		\
+ 	(PIARBCTL_MISC_USB_SELECT_MASK |	\
+@@ -51,14 +50,27 @@
+ #define USB_CTRL_USB_PM_STATUS		0x08
+ #define USB_CTRL_USB_DEVICE_CTL1	0x10
+ #define   USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK	0x00000003
++#define USB_CTRL_TEST_PORT_CTL		0x30
++#define   USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_MASK	0x000000ff
++#define   USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_PME_GEN_MASK	0x0000002e
++#define USB_CTRL_TP_DIAG1		0x34
++#define   USB_CTLR_TP_DIAG1_wake_MASK	0x00000002
++#define USB_CTRL_CTLR_CSHCR		0x50
++#define   USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK	0x00040000
+ 
+ /* Register definitions for the USB_PHY block in 7211b0 */
++#define USB_PHY_PLL_CTL			0x00
++#define   USB_PHY_PLL_CTL_PLL_RESETB_MASK		0x40000000
+ #define USB_PHY_PLL_LDO_CTL		0x08
+ #define   USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK		0x00000004
++#define   USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK	0x00000002
++#define   USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK	0x00000001
+ #define USB_PHY_UTMI_CTL_1		0x04
+ #define   USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK	0x00000800
+ #define   USB_PHY_UTMI_CTL_1_PHY_MODE_MASK		0x0000000c
+ #define   USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT		2
++#define USB_PHY_IDDQ			0x1c
++#define   USB_PHY_IDDQ_phy_iddq_MASK			0x00000001
+ #define USB_PHY_STATUS			0x20
+ #define   USB_PHY_STATUS_pll_lock_MASK			0x00000001
+ 
+@@ -199,6 +211,17 @@ static void usb_init_common(struct brcm_
+ 	}
+ }
+ 
++static void usb_wake_enable_7211b0(struct brcm_usb_init_params *params,
++				   bool enable)
++{
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
++
++	if (enable)
++		USB_CTRL_SET(ctrl, CTLR_CSHCR, ctl_pme_en);
++	else
++		USB_CTRL_UNSET(ctrl, CTLR_CSHCR, ctl_pme_en);
++}
++
+ static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
+ {
+ 	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+@@ -210,9 +233,27 @@ static void usb_init_common_7211b0(struc
+ 	if (params->syscon_piarbctl)
+ 		syscon_piarbctl_init(params->syscon_piarbctl);
+ 
++	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
++
++	usb_wake_enable_7211b0(params, false);
++	if (!params->wake_enabled) {
++
++		/* undo possible suspend settings */
++		brcm_usb_writel(0, usb_phy + USB_PHY_IDDQ);
++		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
++		reg |= USB_PHY_PLL_CTL_PLL_RESETB_MASK;
++		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
++
++		/* temporarily enable FSM so PHY comes up properly */
++		reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
++		reg |= USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
++		brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
++	}
++
+ 	/* Init the PHY */
+-	reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_LDO_CTL);
+-	reg |= USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK;
++	reg = USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK |
++		USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK |
++		USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK;
+ 	brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
+ 
+ 	/* wait for lock */
+@@ -276,12 +317,36 @@ static void usb_uninit_common(struct brc
+ 
+ }
+ 
++static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
++{
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
++	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
++	u32 reg;
++
++	pr_debug("%s\n", __func__);
++
++	if (params->wake_enabled) {
++		USB_CTRL_SET(ctrl, TEST_PORT_CTL, TPOUT_SEL_PME_GEN);
++		usb_wake_enable_7211b0(params, true);
++	} else {
++		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
++		brcm_usb_writel(0, usb_phy + USB_PHY_PLL_LDO_CTL);
++		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
++		reg &= ~USB_PHY_PLL_CTL_PLL_RESETB_MASK;
++		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
++		brcm_usb_writel(USB_PHY_IDDQ_phy_iddq_MASK,
++				usb_phy + USB_PHY_IDDQ);
++	}
++
++}
++
+ static void usb_uninit_xhci(struct brcm_usb_init_params *params)
+ {
+ 
+ 	pr_debug("%s\n", __func__);
+ 
+-	xhci_soft_reset(params, 1);
++	if (!params->wake_enabled)
++		xhci_soft_reset(params, 1);
+ }
+ 
+ static int usb_get_dual_select(struct brcm_usb_init_params *params)
+@@ -309,7 +374,6 @@ static void usb_set_dual_select(struct b
+ 	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+ }
+ 
+-
+ static const struct brcm_usb_init_ops bcm7216_ops = {
+ 	.init_ipp = usb_init_ipp,
+ 	.init_common = usb_init_common,
+@@ -324,7 +388,7 @@ static const struct brcm_usb_init_ops bc
+ 	.init_ipp = usb_init_ipp,
+ 	.init_common = usb_init_common_7211b0,
+ 	.init_xhci = usb_init_xhci,
+-	.uninit_common = usb_uninit_common,
++	.uninit_common = usb_uninit_common_7211b0,
+ 	.uninit_xhci = usb_uninit_xhci,
+ 	.get_dual_select = usb_get_dual_select,
+ 	.set_dual_select = usb_set_dual_select,
+@@ -346,4 +410,5 @@ void brcm_usb_dvr_init_7211b0(struct brc
+ 
+ 	params->family_name = "7211";
+ 	params->ops = &bcm7211b0_ops;
++	params->suspend_with_clocks = true;
+ }
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.c
+@@ -783,12 +783,24 @@ static void usb_init_ipp(struct brcm_usb
+ 		msleep(50);
+ }
+ 
++static void usb_wake_enable(struct brcm_usb_init_params *params,
++			  bool enable)
++{
++	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
++
++	if (enable)
++		USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
++	else
++		USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);
++}
++
+ static void usb_init_common(struct brcm_usb_init_params *params)
+ {
+ 	u32 reg;
+ 	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+ 
+ 	/* Clear any pending wake conditions */
++	usb_wake_enable(params, false);
+ 	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
+ 	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS));
+ 
+@@ -935,6 +947,8 @@ static void usb_uninit_common(struct brc
+ 
+ 	if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN))
+ 		USB_CTRL_SET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);
++	if (params->wake_enabled)
++		usb_wake_enable(params, true);
+ }
+ 
+ static void usb_uninit_eohci(struct brcm_usb_init_params *params)
+@@ -978,17 +992,6 @@ static void usb_set_dual_select(struct b
+ 	}
+ }
+ 
+-static void usb_wake_enable(struct brcm_usb_init_params *params,
+-			  int enable)
+-{
+-	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+-
+-	if (enable)
+-		USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
+-	else
+-		USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);
+-}
+-
+ static const struct brcm_usb_init_ops bcm7445_ops = {
+ 	.init_ipp = usb_init_ipp,
+ 	.init_common = usb_init_common,
+@@ -999,7 +1002,6 @@ static const struct brcm_usb_init_ops bc
+ 	.uninit_xhci = usb_uninit_xhci,
+ 	.get_dual_select = usb_get_dual_select,
+ 	.set_dual_select = usb_set_dual_select,
+-	.wake_enable = usb_wake_enable,
+ };
+ 
+ void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params)
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.h
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
+@@ -46,8 +46,6 @@ struct brcm_usb_init_ops {
+ 	void (*uninit_xhci)(struct brcm_usb_init_params *params);
+ 	int  (*get_dual_select)(struct brcm_usb_init_params *params);
+ 	void (*set_dual_select)(struct brcm_usb_init_params *params, int mode);
+-	void (*wake_enable)(struct brcm_usb_init_params *params,
+-			    int enable);
+ };
+ 
+ struct  brcm_usb_init_params {
+@@ -62,6 +60,8 @@ struct  brcm_usb_init_params {
+ 	const u32 *usb_reg_bits_map;
+ 	const struct brcm_usb_init_ops *ops;
+ 	struct regmap *syscon_piarbctl;
++	bool wake_enabled;
++	bool suspend_with_clocks;
+ };
+ 
+ void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
+@@ -145,13 +145,6 @@ static inline void brcm_usb_uninit_xhci(
+ 		ini->ops->uninit_xhci(ini);
+ }
+ 
+-static inline void brcm_usb_wake_enable(struct brcm_usb_init_params *ini,
+-	int enable)
+-{
+-	if (ini->ops->wake_enable)
+-		ini->ops->wake_enable(ini, enable);
+-}
+-
+ static inline int brcm_usb_get_dual_select(struct brcm_usb_init_params *ini)
+ {
+ 	if (ini->ops->get_dual_select)
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -535,16 +535,26 @@ static int brcm_usb_phy_suspend(struct d
+ 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
+ 
+ 	if (priv->init_count) {
++		priv->ini.wake_enabled = device_may_wakeup(dev);
+ 		if (priv->phys[BRCM_USB_PHY_3_0].inited)
+ 			brcm_usb_uninit_xhci(&priv->ini);
+ 		if (priv->phys[BRCM_USB_PHY_2_0].inited)
+ 			brcm_usb_uninit_eohci(&priv->ini);
+ 		brcm_usb_uninit_common(&priv->ini);
+-		brcm_usb_wake_enable(&priv->ini, true);
+-		if (priv->phys[BRCM_USB_PHY_3_0].inited)
+-			clk_disable_unprepare(priv->usb_30_clk);
+-		if (priv->phys[BRCM_USB_PHY_2_0].inited || !priv->has_eohci)
+-			clk_disable_unprepare(priv->usb_20_clk);
++
++		/*
++		 * Handle the clocks unless needed for wake. This has
++		 * to work for both older XHCI->3.0-clks, EOHCI->2.0-clks
++		 * and newer XHCI->2.0-clks/3.0-clks.
++		 */
++
++		if (!priv->ini.suspend_with_clocks) {
++			if (priv->phys[BRCM_USB_PHY_3_0].inited)
++				clk_disable_unprepare(priv->usb_30_clk);
++			if (priv->phys[BRCM_USB_PHY_2_0].inited ||
++			    !priv->has_eohci)
++				clk_disable_unprepare(priv->usb_20_clk);
++		}
+ 		if (priv->wake_irq >= 0)
+ 			enable_irq_wake(priv->wake_irq);
+ 	}
+@@ -557,7 +567,6 @@ static int brcm_usb_phy_resume(struct de
+ 
+ 	clk_prepare_enable(priv->usb_20_clk);
+ 	clk_prepare_enable(priv->usb_30_clk);
+-	brcm_usb_wake_enable(&priv->ini, false);
+ 	brcm_usb_init_ipp(&priv->ini);
+ 
+ 	/*
+@@ -579,6 +588,8 @@ static int brcm_usb_phy_resume(struct de
+ 		} else if (priv->has_xhci) {
+ 			brcm_usb_uninit_xhci(&priv->ini);
+ 			clk_disable_unprepare(priv->usb_30_clk);
++			if (!priv->has_eohci)
++				clk_disable_unprepare(priv->usb_20_clk);
+ 		}
+ 	} else {
+ 		if (priv->has_xhci)
+@@ -589,7 +600,7 @@ static int brcm_usb_phy_resume(struct de
+ 		clk_disable_unprepare(priv->usb_20_clk);
+ 		clk_disable_unprepare(priv->usb_30_clk);
+ 	}
+-
++	priv->ini.wake_enabled = false;
+ 	return 0;
+ }
+ #endif /* CONFIG_PM_SLEEP */
diff --git a/target/linux/bcm4908/patches-5.4/085-v5.8-0001-phy-phy-brcm-usb-Constify-static-structs.patch b/target/linux/bcm4908/patches-5.4/085-v5.8-0001-phy-phy-brcm-usb-Constify-static-structs.patch
new file mode 100644
index 0000000000..36683fc437
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/085-v5.8-0001-phy-phy-brcm-usb-Constify-static-structs.patch
@@ -0,0 +1,99 @@
+From c79cc3d55c4bf94e9028d6818d449fbdc488eac5 Mon Sep 17 00:00:00 2001
+From: Rikard Falkeborn <rikard.falkeborn at gmail.com>
+Date: Sat, 16 May 2020 14:04:41 +0200
+Subject: [PATCH] phy: phy-brcm-usb: Constify static structs
+
+A number of structs were not modified and can therefore be made const
+to allow the compiler to put them in read-only memory.
+
+In order to do so, update a few functions that don't modify there input
+to take pointers to const.
+
+Before:
+   text    data     bss     dec     hex filename
+  15511    6448      64   22023    5607 drivers/phy/broadcom/phy-brcm-usb.o
+
+After:
+   text    data     bss     dec     hex filename
+  16058    5936      64   22058    562a drivers/phy/broadcom/phy-brcm-usb.o
+
+Signed-off-by: Rikard Falkeborn <rikard.falkeborn at gmail.com>
+Link: https://lore.kernel.org/r/20200516120441.7627-4-rikard.falkeborn@gmail.com
+Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
+---
+ drivers/phy/broadcom/phy-brcm-usb.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -39,14 +39,14 @@ struct match_chip_info {
+ 	u8 optional_reg;
+ };
+ 
+-static struct value_to_name_map brcm_dr_mode_to_name[] = {
++static const struct value_to_name_map brcm_dr_mode_to_name[] = {
+ 	{ USB_CTLR_MODE_HOST, "host" },
+ 	{ USB_CTLR_MODE_DEVICE, "peripheral" },
+ 	{ USB_CTLR_MODE_DRD, "drd" },
+ 	{ USB_CTLR_MODE_TYPEC_PD, "typec-pd" }
+ };
+ 
+-static struct value_to_name_map brcm_dual_mode_to_name[] = {
++static const struct value_to_name_map brcm_dual_mode_to_name[] = {
+ 	{ 0, "host" },
+ 	{ 1, "device" },
+ 	{ 2, "auto" },
+@@ -138,7 +138,7 @@ static int brcm_usb_phy_exit(struct phy
+ 	return 0;
+ }
+ 
+-static struct phy_ops brcm_usb_phy_ops = {
++static const struct phy_ops brcm_usb_phy_ops = {
+ 	.init		= brcm_usb_phy_init,
+ 	.exit		= brcm_usb_phy_exit,
+ 	.owner		= THIS_MODULE,
+@@ -170,7 +170,7 @@ static struct phy *brcm_usb_phy_xlate(st
+ 	return ERR_PTR(-ENODEV);
+ }
+ 
+-static int name_to_value(struct value_to_name_map *table, int count,
++static int name_to_value(const struct value_to_name_map *table, int count,
+ 			 const char *name, int *value)
+ {
+ 	int x;
+@@ -185,7 +185,7 @@ static int name_to_value(struct value_to
+ 	return -EINVAL;
+ }
+ 
+-static const char *value_to_name(struct value_to_name_map *table, int count,
++static const char *value_to_name(const struct value_to_name_map *table, int count,
+ 				 int value)
+ {
+ 	if (value >= count)
+@@ -252,7 +252,7 @@ static const struct attribute_group brcm
+ 	.attrs = brcm_usb_phy_attrs,
+ };
+ 
+-static struct match_chip_info chip_info_7216 = {
++static const struct match_chip_info chip_info_7216 = {
+ 	.init_func = &brcm_usb_dvr_init_7216,
+ 	.required_regs = {
+ 		BRCM_REGS_CTRL,
+@@ -262,7 +262,7 @@ static struct match_chip_info chip_info_
+ 	},
+ };
+ 
+-static struct match_chip_info chip_info_7211b0 = {
++static const struct match_chip_info chip_info_7211b0 = {
+ 	.init_func = &brcm_usb_dvr_init_7211b0,
+ 	.required_regs = {
+ 		BRCM_REGS_CTRL,
+@@ -275,7 +275,7 @@ static struct match_chip_info chip_info_
+ 	.optional_reg = BRCM_REGS_BDC_EC,
+ };
+ 
+-static struct match_chip_info chip_info_7445 = {
++static const struct match_chip_info chip_info_7445 = {
+ 	.init_func = &brcm_usb_dvr_init_7445,
+ 	.required_regs = {
+ 		BRCM_REGS_CTRL,
diff --git a/target/linux/bcm4908/patches-5.4/086-v5.12-0001-phy-phy-brcm-usb-improve-getting-OF-matching-data.patch b/target/linux/bcm4908/patches-5.4/086-v5.12-0001-phy-phy-brcm-usb-improve-getting-OF-matching-data.patch
new file mode 100644
index 0000000000..cc71373165
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/086-v5.12-0001-phy-phy-brcm-usb-improve-getting-OF-matching-data.patch
@@ -0,0 +1,49 @@
+From d14f4cce9340a6586512a0eb6bc680dedeaaef14 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Wed, 16 Dec 2020 15:33:04 +0100
+Subject: [PATCH] phy: phy-brcm-usb: improve getting OF matching data
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+1. Use of_device_get_match_data() helper to simplify the code
+2. Check for NULL as a good practice
+
+Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli at gmail.com>
+Link: https://lore.kernel.org/r/20201216143305.12179-1-zajec5@gmail.com
+Signed-off-by: Vinod Koul <vkoul at kernel.org>
+---
+ drivers/phy/broadcom/phy-brcm-usb.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -11,6 +11,7 @@
+ #include <linux/io.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+@@ -427,7 +428,6 @@ static int brcm_usb_phy_probe(struct pla
+ 	struct device_node *dn = pdev->dev.of_node;
+ 	int err;
+ 	const char *mode;
+-	const struct of_device_id *match;
+ 	void (*dvr_init)(struct brcm_usb_init_params *params);
+ 	const struct match_chip_info *info;
+ 	struct regmap *rmap;
+@@ -441,8 +441,9 @@ static int brcm_usb_phy_probe(struct pla
+ 	priv->ini.family_id = brcmstb_get_family_id();
+ 	priv->ini.product_id = brcmstb_get_product_id();
+ 
+-	match = of_match_node(brcm_usb_dt_ids, dev->of_node);
+-	info = match->data;
++	info = of_device_get_match_data(&pdev->dev);
++	if (!info)
++		return -ENOENT;
+ 	dvr_init = info->init_func;
+ 	(*dvr_init)(&priv->ini);
+ 
diff --git a/target/linux/bcm4908/patches-5.4/086-v5.12-0002-phy-phy-brcm-usb-specify-init-function-format-at-str.patch b/target/linux/bcm4908/patches-5.4/086-v5.12-0002-phy-phy-brcm-usb-specify-init-function-format-at-str.patch
new file mode 100644
index 0000000000..bdc932732c
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/086-v5.12-0002-phy-phy-brcm-usb-specify-init-function-format-at-str.patch
@@ -0,0 +1,50 @@
+From 915f1d230e5292bc2156a9997bcb19d9e632f10b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Wed, 16 Dec 2020 15:33:05 +0100
+Subject: [PATCH] phy: phy-brcm-usb: specify init function format at struct
+ level
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is slightly cleaner solution that assures noone assings a wrong
+function to the pointer.
+
+Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli at gmail.com>
+Link: https://lore.kernel.org/r/20201216143305.12179-2-zajec5@gmail.com
+Signed-off-by: Vinod Koul <vkoul at kernel.org>
+---
+ drivers/phy/broadcom/phy-brcm-usb.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -35,7 +35,7 @@ struct value_to_name_map {
+ };
+ 
+ struct match_chip_info {
+-	void *init_func;
++	void (*init_func)(struct brcm_usb_init_params *params);
+ 	u8 required_regs[BRCM_REGS_MAX + 1];
+ 	u8 optional_reg;
+ };
+@@ -428,7 +428,6 @@ static int brcm_usb_phy_probe(struct pla
+ 	struct device_node *dn = pdev->dev.of_node;
+ 	int err;
+ 	const char *mode;
+-	void (*dvr_init)(struct brcm_usb_init_params *params);
+ 	const struct match_chip_info *info;
+ 	struct regmap *rmap;
+ 	int x;
+@@ -444,8 +443,8 @@ static int brcm_usb_phy_probe(struct pla
+ 	info = of_device_get_match_data(&pdev->dev);
+ 	if (!info)
+ 		return -ENOENT;
+-	dvr_init = info->init_func;
+-	(*dvr_init)(&priv->ini);
++
++	info->init_func(&priv->ini);
+ 
+ 	dev_dbg(dev, "Best mapping table is for %s\n",
+ 		priv->ini.family_name);
diff --git a/target/linux/bcm4908/patches-5.4/086-v5.12-0003-dt-bindings-phy-brcm-brcmstb-usb-phy-convert-to-the-.patch b/target/linux/bcm4908/patches-5.4/086-v5.12-0003-dt-bindings-phy-brcm-brcmstb-usb-phy-convert-to-the-.patch
new file mode 100644
index 0000000000..1edd63ea5d
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/086-v5.12-0003-dt-bindings-phy-brcm-brcmstb-usb-phy-convert-to-the-.patch
@@ -0,0 +1,315 @@
+From b39069a482ade0c5e18c407c3218ba1aeed371b6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Wed, 6 Jan 2021 21:58:36 +0100
+Subject: [PATCH] dt-bindings: phy: brcm, brcmstb-usb-phy: convert to the
+ json-schema
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Changes that require mentioning:
+1. interrupt-names
+   Name "wakeup" was changed to the "wake". It matches example and what
+   Linux driver looks for in the first place
+2. brcm,ipp and brcm,ioc
+   Both were described as booleans with 0 / 1 values. In examples they
+   were integers and Linux checks for int as well. Both got uint32.
+3. Added minimal description
+
+Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Reviewed-by: Rob Herring <robh at kernel.org>
+Link: https://lore.kernel.org/r/20210106205838.10964-1-zajec5@gmail.com
+Signed-off-by: Vinod Koul <vkoul at kernel.org>
+---
+ .../bindings/phy/brcm,brcmstb-usb-phy.txt     |  86 --------
+ .../bindings/phy/brcm,brcmstb-usb-phy.yaml    | 193 ++++++++++++++++++
+ 2 files changed, 193 insertions(+), 86 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.txt
+ create mode 100644 Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml
+
+--- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.txt
++++ /dev/null
+@@ -1,86 +0,0 @@
+-Broadcom STB USB PHY
+-
+-Required properties:
+-- compatible: should be one of
+-	"brcm,brcmstb-usb-phy"
+-	"brcm,bcm7216-usb-phy"
+-	"brcm,bcm7211-usb-phy"
+-
+-- reg and reg-names properties requirements are specific to the
+-  compatible string.
+-  "brcm,brcmstb-usb-phy":
+-    - reg: 1 or 2 offset and length pairs. One for the base CTRL registers
+-           and an optional pair for systems with USB 3.x support
+-    - reg-names: not specified
+-  "brcm,bcm7216-usb-phy":
+-    - reg: 3 offset and length pairs for CTRL, XHCI_EC and XHCI_GBL
+-           registers
+-    - reg-names: "ctrl", "xhci_ec", "xhci_gbl"
+-  "brcm,bcm7211-usb-phy":
+-    - reg: 5 offset and length pairs for CTRL, XHCI_EC, XHCI_GBL,
+-           USB_PHY and USB_MDIO registers and an optional pair
+-	   for the BDC registers
+-    - reg-names: "ctrl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec"
+-
+-- #phy-cells: Shall be 1 as it expects one argument for setting
+-	      the type of the PHY. Possible values are:
+-	      - PHY_TYPE_USB2 for USB1.1/2.0 PHY
+-	      - PHY_TYPE_USB3 for USB3.x PHY
+-
+-Optional Properties:
+-- clocks : clock phandles.
+-- clock-names: String, clock name.
+-- interrupts: wakeup interrupt
+-- interrupt-names: "wakeup"
+-- brcm,ipp: Boolean, Invert Port Power.
+-  Possible values are: 0 (Don't invert), 1 (Invert)
+-- brcm,ioc: Boolean, Invert Over Current detection.
+-  Possible values are: 0 (Don't invert), 1 (Invert)
+-- dr_mode: String, PHY Device mode.
+-  Possible values are: "host", "peripheral ", "drd" or "typec-pd"
+-  If this property is not defined, the phy will default to "host" mode.
+-- brcm,syscon-piarbctl: phandle to syscon for handling config registers
+-NOTE: one or both of the following two properties must be set
+-- brcm,has-xhci: Boolean indicating the phy has an XHCI phy.
+-- brcm,has-eohci: Boolean indicating the phy has an EHCI/OHCI phy.
+-
+-
+-Example:
+-
+-usbphy_0: usb-phy at f0470200 {
+-	reg = <0xf0470200 0xb8>,
+-		<0xf0471940 0x6c0>;
+-	compatible = "brcm,brcmstb-usb-phy";
+-	#phy-cells = <1>;
+-	dr_mode = "host"
+-	brcm,ioc = <1>;
+-	brcm,ipp = <1>;
+-	brcm,has-xhci;
+-	brcm,has-eohci;
+-	clocks = <&usb20>, <&usb30>;
+-	clock-names = "sw_usb", "sw_usb3";
+-};
+-
+-usb-phy at 29f0200 {
+-	reg = <0x29f0200 0x200>,
+-		<0x29c0880 0x30>,
+-		<0x29cc100 0x534>,
+-		<0x2808000 0x24>,
+-		<0x2980080 0x8>;
+-	reg-names = "ctrl",
+-		"xhci_ec",
+-		"xhci_gbl",
+-		"usb_phy",
+-		"usb_mdio";
+-	brcm,ioc = <0x0>;
+-	brcm,ipp = <0x0>;
+-	compatible = "brcm,bcm7211-usb-phy";
+-	interrupts = <0x30>;
+-	interrupt-parent = <&vpu_intr1_nosec_intc>;
+-	interrupt-names = "wake";
+-	#phy-cells = <0x1>;
+-	brcm,has-xhci;
+-	syscon-piarbctl = <&syscon_piarbctl>;
+-	clocks = <&scmi_clk 256>;
+-	clock-names = "sw_usb";
+-};
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml
+@@ -0,0 +1,193 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/phy/brcm,brcmstb-usb-phy.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom STB USB PHY
++
++description: Broadcom's PHY that handles EHCI/OHCI and/or XHCI
++
++maintainers:
++  - Al Cooper <alcooperx at gmail.com>
++  - Rafał Miłecki <rafal at milecki.pl>
++
++properties:
++  compatible:
++    enum:
++      - brcm,bcm7211-usb-phy
++      - brcm,bcm7216-usb-phy
++      - brcm,brcmstb-usb-phy
++
++  reg:
++    minItems: 1
++    maxItems: 6
++    items:
++      - description: the base CTRL register
++      - description: XHCI EC register
++      - description: XHCI GBL register
++      - description: USB PHY register
++      - description: USB MDIO register
++      - description: BDC register
++
++  reg-names:
++    minItems: 1
++    maxItems: 6
++    items:
++      - const: ctrl
++      - const: xhci_ec
++      - const: xhci_gbl
++      - const: usb_phy
++      - const: usb_mdio
++      - const: bdc_ec
++
++  clocks:
++    minItems: 1
++    maxItems: 2
++
++  clock-names:
++    minItems: 1
++    maxItems: 2
++    items:
++      - const: sw_usb
++      - const: sw_usb3
++
++  interrupts:
++    description: wakeup interrupt
++
++  interrupt-names:
++    const: wake
++
++  brcm,ipp:
++    $ref: /schemas/types.yaml#/definitions/uint32
++    description: Invert Port Power
++    minimum: 0
++    maximum: 1
++
++  brcm,ioc:
++    $ref: /schemas/types.yaml#/definitions/uint32
++    description: Invert Over Current detection
++    minimum: 0
++    maximum: 1
++
++  dr_mode:
++    description: PHY Device mode. If this property is not defined, the PHY will
++      default to "host" mode.
++    enum:
++      - host
++      - peripheral
++      - drd
++      - typec-pd
++
++  brcm,syscon-piarbctl:
++    description: phandle to syscon for handling config registers
++    $ref: /schemas/types.yaml#/definitions/phandle
++
++  brcm,has-xhci:
++    description: Indicates the PHY has an XHCI PHY.
++    type: boolean
++
++  brcm,has-eohci:
++    description: Indicates the PHY has an EHCI/OHCI PHY.
++    type: boolean
++
++  "#phy-cells":
++    description: |
++      Cell allows setting the type of the PHY. Possible values are:
++      - PHY_TYPE_USB2 for USB1.1/2.0 PHY
++      - PHY_TYPE_USB3 for USB3.x PHY
++    const: 1
++
++required:
++  - reg
++  - "#phy-cells"
++
++anyOf:
++  - required:
++      - brcm,has-xhci
++  - required:
++      - brcm,has-eohci
++
++allOf:
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: brcm,brcmstb-usb-phy
++    then:
++      properties:
++        reg:
++          minItems: 1
++          maxItems: 2
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: brcm,bcm7211-usb-phy
++    then:
++      properties:
++        reg:
++          minItems: 5
++          maxItems: 6
++        reg-names:
++          minItems: 5
++          maxItems: 6
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: brcm,bcm7216-usb-phy
++    then:
++      properties:
++        reg:
++          minItems: 3
++          maxItems: 3
++        reg-names:
++          minItems: 3
++          maxItems: 3
++
++additionalProperties: false
++
++examples:
++  - |
++    #include <dt-bindings/phy/phy.h>
++
++    usb-phy at f0470200 {
++        compatible = "brcm,brcmstb-usb-phy";
++        reg = <0xf0470200 0xb8>,
++              <0xf0471940 0x6c0>;
++        #phy-cells = <1>;
++        dr_mode = "host";
++        brcm,ioc = <1>;
++        brcm,ipp = <1>;
++        brcm,has-xhci;
++        brcm,has-eohci;
++        clocks = <&usb20>, <&usb30>;
++        clock-names = "sw_usb", "sw_usb3";
++    };
++  - |
++    #include <dt-bindings/phy/phy.h>
++
++    usb-phy at 29f0200 {
++        compatible = "brcm,bcm7211-usb-phy";
++        reg = <0x29f0200 0x200>,
++              <0x29c0880 0x30>,
++              <0x29cc100 0x534>,
++              <0x2808000 0x24>,
++              <0x2980080 0x8>;
++        reg-names = "ctrl",
++            "xhci_ec",
++            "xhci_gbl",
++            "usb_phy",
++            "usb_mdio";
++        brcm,ioc = <0x0>;
++        brcm,ipp = <0x0>;
++        interrupts = <0x30>;
++        interrupt-parent = <&vpu_intr1_nosec_intc>;
++        interrupt-names = "wake";
++        #phy-cells = <0x1>;
++        brcm,has-xhci;
++        brcm,syscon-piarbctl = <&syscon_piarbctl>;
++        clocks = <&scmi_clk 256>;
++        clock-names = "sw_usb";
++    };
diff --git a/target/linux/bcm4908/patches-5.4/086-v5.12-0004-dt-bindings-phy-brcm-brcmstb-usb-phy-add-BCM4908-bin.patch b/target/linux/bcm4908/patches-5.4/086-v5.12-0004-dt-bindings-phy-brcm-brcmstb-usb-phy-add-BCM4908-bin.patch
new file mode 100644
index 0000000000..6127800a43
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/086-v5.12-0004-dt-bindings-phy-brcm-brcmstb-usb-phy-add-BCM4908-bin.patch
@@ -0,0 +1,41 @@
+From 46b616c1574def7a1629bdeded3d44e76382f950 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Wed, 6 Jan 2021 21:58:37 +0100
+Subject: [PATCH] dt-bindings: phy: brcm, brcmstb-usb-phy: add BCM4908 binding
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM4908 uses the same PHY and may require just a slightly different
+programming.
+
+Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli at gmail.com>
+Acked-by: Rob Herring <robh at kernel.org>
+Link: https://lore.kernel.org/r/20210106205838.10964-2-zajec5@gmail.com
+Signed-off-by: Vinod Koul <vkoul at kernel.org>
+---
+ .../devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml        | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml
++++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml
+@@ -15,6 +15,7 @@ maintainers:
+ properties:
+   compatible:
+     enum:
++      - brcm,bcm4908-usb-phy
+       - brcm,bcm7211-usb-phy
+       - brcm,bcm7216-usb-phy
+       - brcm,brcmstb-usb-phy
+@@ -113,7 +114,9 @@ allOf:
+       properties:
+         compatible:
+           contains:
+-            const: brcm,brcmstb-usb-phy
++            enum:
++              - const: brcm,bcm4908-usb-phy
++              - const: brcm,brcmstb-usb-phy
+     then:
+       properties:
+         reg:
diff --git a/target/linux/bcm4908/patches-5.4/086-v5.12-0005-phy-phy-brcm-usb-support-PHY-on-the-BCM4908.patch b/target/linux/bcm4908/patches-5.4/086-v5.12-0005-phy-phy-brcm-usb-support-PHY-on-the-BCM4908.patch
new file mode 100644
index 0000000000..c021201f6b
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/086-v5.12-0005-phy-phy-brcm-usb-support-PHY-on-the-BCM4908.patch
@@ -0,0 +1,48 @@
+From 4b402fa8e0b7817f3e3738d7828038f114e6899e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Wed, 6 Jan 2021 21:58:38 +0100
+Subject: [PATCH] phy: phy-brcm-usb: support PHY on the BCM4908
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM4908 seems to have slightly different registers but works when
+programmed just like the STB one.
+
+Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli at gmail.com>
+Link: https://lore.kernel.org/r/20210106205838.10964-3-zajec5@gmail.com
+Signed-off-by: Vinod Koul <vkoul at kernel.org>
+---
+ drivers/phy/broadcom/Kconfig        | 3 ++-
+ drivers/phy/broadcom/phy-brcm-usb.c | 4 ++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/phy/broadcom/Kconfig
++++ b/drivers/phy/broadcom/Kconfig
+@@ -83,10 +83,11 @@ config PHY_BRCM_SATA
+ 
+ config PHY_BRCM_USB
+ 	tristate "Broadcom STB USB PHY driver"
+-	depends on ARCH_BRCMSTB
++	depends on ARCH_BCM4908 || ARCH_BRCMSTB
+ 	depends on OF
+ 	select GENERIC_PHY
+ 	select SOC_BRCMSTB
++	default ARCH_BCM4908
+ 	default ARCH_BRCMSTB
+ 	help
+ 	  Enable this to support the Broadcom STB USB PHY.
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -287,6 +287,10 @@ static const struct match_chip_info chip
+ 
+ static const struct of_device_id brcm_usb_dt_ids[] = {
+ 	{
++		.compatible = "brcm,bcm4908-usb-phy",
++		.data = &chip_info_7445,
++	},
++	{
+ 		.compatible = "brcm,bcm7216-usb-phy",
+ 		.data = &chip_info_7216,
+ 	},
diff --git a/target/linux/bcm4908/patches-5.4/180-soc-brcmstb-add-stubs-for-getting-platform-IDs.patch b/target/linux/bcm4908/patches-5.4/180-soc-brcmstb-add-stubs-for-getting-platform-IDs.patch
new file mode 100644
index 0000000000..366e6089c4
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/180-soc-brcmstb-add-stubs-for-getting-platform-IDs.patch
@@ -0,0 +1,50 @@
+From c149974b2ae2e2296c66262a4ee797c06c39982b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Thu, 14 Jan 2021 11:33:01 +0100
+Subject: [PATCH] soc: brcmstb: add stubs for getting platform IDs
+
+Some brcmstb drivers may be shared with other SoC families. E.g. the
+same USB PHY block is shared by brcmstb and BCM4908.
+
+To avoid building brcmstb common code on non-brcmstb platforms we need
+stubs for:
+1. brcmstb_get_family_id()
+2. brcmstb_get_product_id()
+(to avoid "undefined reference to" errors).
+
+With this change PHY_BRCM_USB will not have to unconditionally select
+SOC_BRCMSTB anymore.
+---
+ include/linux/soc/brcmstb/brcmstb.h | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/include/linux/soc/brcmstb/brcmstb.h
++++ b/include/linux/soc/brcmstb/brcmstb.h
+@@ -12,6 +12,8 @@ static inline u32 BRCM_REV(u32 reg)
+ 	return reg & 0xff;
+ }
+ 
++#ifdef CONFIG_SOC_BRCMSTB
++
+ /*
+  * Helper functions for getting family or product id from the
+  * SoC driver.
+@@ -19,4 +21,18 @@ static inline u32 BRCM_REV(u32 reg)
+ u32 brcmstb_get_family_id(void);
+ u32 brcmstb_get_product_id(void);
+ 
++#else
++
++static inline u32 brcmstb_get_family_id(void)
++{
++	return 0;
++}
++
++static inline u32 brcmstb_get_product_id(void)
++{
++	return 0;
++}
++
++#endif
++
+ #endif /* __BRCMSTB_SOC_H */
diff --git a/target/linux/bcm4908/patches-5.4/800-phy-phy-brcm-usb-select-SOC_BRCMSTB-on-brcmstb-only.patch b/target/linux/bcm4908/patches-5.4/800-phy-phy-brcm-usb-select-SOC_BRCMSTB-on-brcmstb-only.patch
new file mode 100644
index 0000000000..965d60c18e
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/800-phy-phy-brcm-usb-select-SOC_BRCMSTB-on-brcmstb-only.patch
@@ -0,0 +1,26 @@
+From 73f63c66bf80bebd46d38a2660078dbe3fe11170 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Thu, 14 Jan 2021 12:02:28 +0100
+Subject: [PATCH] phy: phy-brcm-usb: select SOC_BRCMSTB on brcmstb only
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM4908 doesn't need brcmstb SoC stuff compiled.
+
+Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
+---
+ drivers/phy/broadcom/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/broadcom/Kconfig
++++ b/drivers/phy/broadcom/Kconfig
+@@ -86,7 +86,7 @@ config PHY_BRCM_USB
+ 	depends on ARCH_BCM4908 || ARCH_BRCMSTB
+ 	depends on OF
+ 	select GENERIC_PHY
+-	select SOC_BRCMSTB
++	select SOC_BRCMSTB if ARCH_BRCMSTB
+ 	default ARCH_BCM4908
+ 	default ARCH_BRCMSTB
+ 	help



More information about the lede-commits mailing list