aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/linux/bcm27xx/bcm2708/config-5.44
-rw-r--r--target/linux/bcm27xx/bcm2709/config-5.414
-rw-r--r--target/linux/bcm27xx/bcm2710/config-5.49
-rw-r--r--target/linux/bcm27xx/bcm2711/config-5.410
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0205-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch1187
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0205-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0208-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0206-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch569
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0206-arm-bcm2835-DMA-can-only-address-1GB.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0210-arm-bcm2835-DMA-can-only-address-1GB.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0207-PCI-brcmstb-Add-MSI-capability.patch543
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0207-hwrng-iproc-rng200-Add-BCM2838-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0211-hwrng-iproc-rng200-Add-BCM2838-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0208-thermal-brcmstb_thermal-Add-BCM2838-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0212-thermal-brcmstb_thermal-Add-BCM2838-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0209-pcie-brcmstb-Changes-for-BCM2711.patch1428
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0209-vchiq-Add-36-bit-address-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0213-vchiq-Add-36-bit-address-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0210-bcm2835-pcm.c-Support-multichannel-audio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0214-bcm2835-pcm.c-Support-multichannel-audio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0211-bcmgenet-constrain-max-DMA-burst-length.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0215-bcmgenet-constrain-max-DMA-burst-length.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0212-bcmgenet-Better-coalescing-parameter-defaults.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0216-bcmgenet-Better-coalescing-parameter-defaults.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0213-net-genet-enable-link-energy-detect-powerdown-for-ex.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0217-net-genet-enable-link-energy-detect-powerdown-for-ex.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0214-usb-xhci-Disable-the-XHCI-5-second-timeout.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0218-usb-xhci-Disable-the-XHCI-5-second-timeout.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0215-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0219-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0216-spi-bcm2835-enable-shared-interrupt-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0220-spi-bcm2835-enable-shared-interrupt-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0217-clk-bcm2835-Don-t-wait-for-pllh-lock.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0221-clk-bcm2835-Don-t-wait-for-pllh-lock.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0218-soc-bcm-bcm2835-pm-Add-support-for-2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0222-soc-bcm-bcm2835-pm-Add-support-for-2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0219-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0223-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch)14
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0220-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0224-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0221-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0225-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0222-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0226-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0223-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0227-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0224-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0228-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0225-arm-bcm2835-Add-bcm2838-compatible-string.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0229-arm-bcm2835-Add-bcm2838-compatible-string.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0226-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0227-drm-v3d-Add-support-for-2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0231-drm-v3d-Add-support-for-2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0228-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0232-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0229-drm-v3d-Hook-up-the-runtime-PM-ops.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0233-drm-v3d-Hook-up-the-runtime-PM-ops.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0232-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0233-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0237-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Increase-max-screen-size-to-4096x4096.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Increase-max-screen-size-to-4096x4096.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Fix-build-warning.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Fix-build-warning.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Select-display-to-blank-during-initialisatio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Select-display-to-blank-during-initialisatio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Remove-now-unused-structure.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Remove-now-unused-structure.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Set-the-display-number-when-querying-the-dis.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Set-the-display-number-when-querying-the-dis.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-Increase-max_width-height-to-7680.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Increase-max_width-height-to-7680.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Log-flags-in-fkms-mode-set.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Log-flags-in-fkms-mode-set.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-firmware-kms-Fix-DSI-display-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-firmware-kms-Fix-DSI-display-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-handle-the-case-where-there-are-no-available.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-handle-the-case-where-there-are-no-available.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Support-the-VEC-in-FKMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Support-the-VEC-in-FKMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Correct-SAND-support-for-FKMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Correct-SAND-support-for-FKMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-Add-status-of-which-display-is-updated-throu.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4-Add-status-of-which-display-is-updated-throu.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0266-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Limit-fkms-to-modes-85Hz.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0267-drm-vc4-Limit-fkms-to-modes-85Hz.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4-Ignore-HVS-unless-initialised.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0268-drm-vc4-Ignore-HVS-unless-initialised.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0269-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0266-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0270-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0267-tty-amba-pl011-Make-TX-optimisation-conditional.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0271-tty-amba-pl011-Make-TX-optimisation-conditional.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0268-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0272-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0269-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0273-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0270-staging-vc04_services-fix-compiling-in-separate-dire.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0275-staging-vc04_services-fix-compiling-in-separate-dire.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0271-clk-bcm2835-Avoid-null-pointer-exception.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0277-clk-bcm2835-Avoid-null-pointer-exception.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0272-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0279-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0273-drm-v3d-HACK-gut-runtime-pm-for-now.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0280-drm-v3d-HACK-gut-runtime-pm-for-now.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0274-arm64-mm-Limit-the-DMA-zone-for-arm64.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0274-drm-v3d-Clock-V3D-down-when-not-in-use.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0281-drm-v3d-Clock-V3D-down-when-not-in-use.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0275-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0282-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0276-bcm2835-dma-Add-proper-40-bit-DMA-support.patch945
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0276-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0284-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0278-drm-vc4-Add-support-for-margins-to-fkms.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0278-pcie-brcmstb-Don-t-set-DMA-ops-for-root-complex.patch27
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0279-drm-vc4-Ensure-zpos-is-always-initialised.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0287-drm-vc4-Ensure-zpos-is-always-initialised.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0280-adds-the-Hifiberry-DAC-ADC-PRO-version.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0288-adds-the-Hifiberry-DAC-ADC-PRO-version.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0281-drm-vc4-A-present-but-empty-dmas-disables-audio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0289-drm-vc4-A-present-but-empty-dmas-disables-audio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0282-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0290-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0283-Ported-pcie-brcmstb-bounce-buffer-implementation-to-.patch713
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0283-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0291-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0284-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0292-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-Add-Broadcast-RGB-connector-property.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0293-drm-vc4-Add-Broadcast-RGB-connector-property.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-fkms-Set-default-state-margin-at-reset.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0294-drm-vc4-fkms-Set-default-state-margin-at-reset.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0287-staging-bcm2835-codec-switch-to-multi-planar-API.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0295-staging-bcm2835-codec-switch-to-multi-planar-API.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0288-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0296-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0289-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0297-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0290-Add-HDMI1-facility-to-the-driver.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0298-Add-HDMI1-facility-to-the-driver.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0299-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0292-drm-vc4-Remove-unused-mode-variable.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0300-drm-vc4-Remove-unused-mode-variable.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0293-staging-bcm2835-codec-Expand-logging-on-format-setti.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0301-staging-bcm2835-codec-Expand-logging-on-format-setti.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0294-staging-bcm2835-codec-Correct-bytesperline-on-format.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Correct-bytesperline-on-format.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0295-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0303-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0296-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0304-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0297-xhci-Use-more-event-ring-segment-table-entries.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0305-xhci-Use-more-event-ring-segment-table-entries.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0298-configs-arm64-bcm2711-Enable-V3D.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0306-configs-arm64-bcm2711-Enable-V3D.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0307-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0300-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0301-arch-arm-Add-model-string-to-cpuinfo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0309-arch-arm-Add-model-string-to-cpuinfo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0302-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0310-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-Fix-non-documentation-comment-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0313-staging-bcm2835-codec-Fix-non-documentation-comment-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0304-staging-bcm2835-codec-Fix-declaration-of-roles.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0314-staging-bcm2835-codec-Fix-declaration-of-roles.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-codec-Add-role-to-device-name.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0315-staging-bcm2835-codec-Add-role-to-device-name.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0306-staging-bcm2835-codec-Pass-driver-context-to-create-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0316-staging-bcm2835-codec-Pass-driver-context-to-create-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0307-staging-bcm2835-codec-add-media-controller-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0317-staging-bcm2835-codec-add-media-controller-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0308-v4l2-Add-a-Greyworld-AWB-mode.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0318-v4l2-Add-a-Greyworld-AWB-mode.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0309-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0319-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0310-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0320-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0311-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0321-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0311-media-dt-bindings-Add-binding-for-the-Sony-IMX219-se.patch77
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0312-staging-bcm2835-codec-Allow-height-of-1920.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0322-staging-bcm2835-codec-Allow-height-of-1920.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0313-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0323-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0314-drm-v3d-Delete-pm_runtime-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0324-drm-v3d-Delete-pm_runtime-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0315-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0325-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0316-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0326-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0317-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0327-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0318-dma-direct-Temporary-DMA-fix-on-arm64.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0328-dma-direct-Temporary-DMA-fix-on-arm64.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0319-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0329-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0320-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0330-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0321-vchiq_2835_arm-suppress-warning.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0331-vchiq_2835_arm-suppress-warning.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0322-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0332-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0323-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0334-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0324-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0335-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0325-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0336-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0326-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0337-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch)2
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0327-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0338-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0328-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0339-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0329-staging-bcm2835-codec-Set-default-and-error-check-ti.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0340-staging-bcm2835-codec-Set-default-and-error-check-ti.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0330-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0341-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0331-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0342-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0332-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0343-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0333-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0344-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0333-pcie-brcmstb-bounce64.c-dev_err-dev_info-for-info-me.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0334-drm-v3d-Suppress-all-but-the-first-MMU-error.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0345-drm-v3d-Suppress-all-but-the-first-MMU-error.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0335-drm-v3d-Plug-dma_fence-leak.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0346-drm-v3d-Plug-dma_fence-leak.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0336-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0347-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0337-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0348-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0338-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0349-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0339-staging-vchiq_arm-Unify-the-unload-handling-of-platf.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0350-staging-vchiq_arm-Unify-the-unload-handling-of-platf.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0340-net-bcmgenet-The-second-IRQ-is-optional.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0351-net-bcmgenet-The-second-IRQ-is-optional.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0341-drm-v3d-The-third-IRQ-is-optional.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0352-drm-v3d-The-third-IRQ-is-optional.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0342-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0353-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0343-rpi-poe-fan-fix-def_pwm1-writes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0354-rpi-poe-fan-fix-def_pwm1-writes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0344-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0355-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0345-overlays-smi-fix-typo-in-comment-3320.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0356-overlays-smi-fix-typo-in-comment-3320.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0346-net-phy-2711-Change-the-default-ethernet-LED-actions.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0357-net-phy-2711-Change-the-default-ethernet-LED-actions.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0347-overlays-Add-apds9960-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0358-overlays-Add-apds9960-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0348-overlays-Remove-hack-from-uart0-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0359-overlays-Remove-hack-from-uart0-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0349-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0360-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0350-v3d_drv-Handle-missing-clock-more-gracefully.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0361-v3d_drv-Handle-missing-clock-more-gracefully.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0351-v3d_drv-Allow-clock-retrieval-by-name.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0362-v3d_drv-Allow-clock-retrieval-by-name.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0352-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0363-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0353-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0364-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0354-clk-raspberrypi-Also-support-v3d-clock.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0365-clk-raspberrypi-Also-support-v3d-clock.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0355-clk-bcm2835-Disable-v3d-clock.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0366-clk-bcm2835-Disable-v3d-clock.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0356-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0367-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0357-arm-dts-Correct-Pi-4B-LED-values.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0368-arm-dts-Correct-Pi-4B-LED-values.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0358-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0369-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0359-arm-dts-2711-Add-pcie0-alias.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0370-arm-dts-2711-Add-pcie0-alias.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0360-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0371-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0361-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0372-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0362-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0373-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0363-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0374-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0364-overlays-Make-mcp342x-run-time-compatible.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0375-overlays-Make-mcp342x-run-time-compatible.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0365-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0376-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0366-sound-soc-only-first-codec-is-master-in-multicodec-s.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0377-sound-soc-only-first-codec-is-master-in-multicodec-s.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0367-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0378-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0368-overlays-dht11-Allow-multiple-instantiation.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0379-overlays-dht11-Allow-multiple-instantiation.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0369-overlays-i2c-rtc-Add-pcf85363-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0380-overlays-i2c-rtc-Add-pcf85363-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0370-pinctrl-bcm2835-Remove-gpiochip-on-error.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0381-pinctrl-bcm2835-Remove-gpiochip-on-error.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0371-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0382-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0372-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0383-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0385-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0374-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0386-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0375-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0387-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0388-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0377-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0389-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0378-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0390-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0379-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0391-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0380-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0392-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0381-net-bcmgenet-Add-RGMII_RXID-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0393-net-bcmgenet-Add-RGMII_RXID-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0382-ARM-dts-bcm2838-Backport-genet-from-upstream.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0394-ARM-dts-bcm2838-Backport-genet-from-upstream.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0383-ARM-bcm-Backport-BCM2711-support-from-upstream.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0395-ARM-bcm-Backport-BCM2711-support-from-upstream.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0384-hwrng-iproc-rng200-Add-support-for-BCM2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0396-hwrng-iproc-rng200-Add-support-for-BCM2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0384-pcie-brcmstb-Eliminate-arch_dma_ops-error-message.patch148
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0385-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0397-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0386-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0398-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0387-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0399-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0388-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0400-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0389-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0401-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0390-driver-char-rpimem-Add-SPDX-licence-header.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0402-driver-char-rpimem-Add-SPDX-licence-header.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0391-driver-char-rpivid-Fix-access-to-freed-memory.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0403-driver-char-rpivid-Fix-access-to-freed-memory.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0392-add-BME680-to-i2c-sensor-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0404-add-BME680-to-i2c-sensor-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0393-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0405-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0394-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0406-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0395-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0407-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0396-Add-universal-device-tree-overlay-for-SPI-devices.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0408-Add-universal-device-tree-overlay-for-SPI-devices.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0397-sound-Add-the-HiFiBerry-DAC-HD-version.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0409-sound-Add-the-HiFiBerry-DAC-HD-version.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0398-Initialise-rpi-firmware-before-clk-bcm2835.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0410-Initialise-rpi-firmware-before-clk-bcm2835.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0399-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0411-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0400-overlays-Use-preferred-compatible-strings.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0412-overlays-Use-preferred-compatible-strings.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0401-tty-amba-pl011-Add-un-throttle-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0413-tty-amba-pl011-Add-un-throttle-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0402-Fix-i2c-pwm-pca9685a-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0414-Fix-i2c-pwm-pca9685a-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0403-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0415-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0404-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0416-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0405-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0417-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0406-pisound-Added-reading-Pisound-board-hardware-revisio.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0418-pisound-Added-reading-Pisound-board-hardware-revisio.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0407-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0419-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0408-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0409-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0422-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0410-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0411-tty-amba-pl011-Avoid-rare-write-when-full-error.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0424-tty-amba-pl011-Avoid-rare-write-when-full-error.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0412-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0425-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0413-overlays-Correct-the-eth_led-colour-assignments.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0426-overlays-Correct-the-eth_led-colour-assignments.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0414-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0427-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0415-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0428-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0416-overlays-dwc2-Increase-RX-FIFO-size.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0429-overlays-dwc2-Increase-RX-FIFO-size.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0417-overlays-Fix-mcp23017-s-addr-parameter.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0430-overlays-Fix-mcp23017-s-addr-parameter.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0418-SQUASH-Fix-spi-driver-compiler-warnings.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0431-SQUASH-Fix-spi-driver-compiler-warnings.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0419-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0432-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0433-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0434-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0421-pcie-brcmstb-Bounce-buffer-support-is-for-BCM2711B0.patch88
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0422-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0435-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0436-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0424-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0437-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0425-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0438-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0426-ARM-dts-Rebuild-downstream-DTS-files.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0439-ARM-dts-Rebuild-downstream-DTS-files.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0427-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0440-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0428-thermal-brcmstb_thermal-Correct-SoC-name.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0442-thermal-brcmstb_thermal-Correct-SoC-name.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0429-hwrng-iproc-rng200-Correct-SoC-name.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0443-hwrng-iproc-rng200-Correct-SoC-name.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0430-ARM-dts-Correct-SoC-name.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0445-ARM-dts-Correct-SoC-name.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0431-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0446-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0432-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0447-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0433-staging-vchiq_arm-Add-a-matching-unregister-call.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0448-staging-vchiq_arm-Add-a-matching-unregister-call.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0434-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0449-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0435-ASoC-pcm512x-Fix-unbalanced-regulator-enable-call-in.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0450-ASoC-pcm512x-Fix-unbalanced-regulator-enable-call-in.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0436-ARM-dts-overlays-Create-custom-clocks-in.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0451-ARM-dts-overlays-Create-custom-clocks-in.patch)0
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0437-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch26
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0438-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch34
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0439-of-overlay-Correct-symbol-path-fixups.patch37
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0440-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0441-bcm2835-dma-Correct-SoC-name.patch489
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0441-of-address-Introduce-of_get_next_dma_parent-helper.patch39
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0442-of-address-Follow-DMA-parent-for-dma-coherent.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0443-of-Factor-out-addr-size-cells-parsing.patch117
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0444-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch40
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0444-pcie-brcmstb-Correct-SoC-name.patch96
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0445-of-Make-of_dma_get_range-work-on-bus-nodes.patch107
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0446-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch30
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0447-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch117
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0448-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch174
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0449-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch84
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0450-resource-Add-a-resource_list_first_type-helper.patch36
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0451-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch195
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0452-x86-PCI-sta2x11-use-default-DMA-address-translation.patch259
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0453-PCI-of-Add-inbound-resource-parsing-to-helpers.patch427
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0454-dma-direct-unify-the-dma_capable-definitions.patch103
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0455-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch69
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0456-dma-direct-exclude-dma_direct_map_resource-from-the-.patch115
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0457-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch366
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0458-ARM-dts-bcm2711-Enable-PCIe-controller.patch56
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0459-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch810
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0460-PCI-brcmstb-Add-MSI-support.patch383
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0461-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch38
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0462-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch75
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0463-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch156
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0464-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch (renamed from target/linux/bcm27xx/patches-5.4/950-0312-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch)612
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0465-overlays-imx219-Correct-link-frequency-to-match-the-.patch25
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0466-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch26
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0467-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch74
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0468-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch407
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0469-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch277
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0470-media-ov5647-Add-extra-10-bit-sensor-modes.patch549
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0471-media-ov5647-change-defaults-to-better-match-raw-cam.patch59
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0472-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch79
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0473-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch55
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0474-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch71
288 files changed, 5992 insertions, 6603 deletions
diff --git a/target/linux/bcm27xx/bcm2708/config-5.4 b/target/linux/bcm27xx/bcm2708/config-5.4
index 57c176d168..ca86cb39f6 100644
--- a/target/linux/bcm27xx/bcm2708/config-5.4
+++ b/target/linux/bcm27xx/bcm2708/config-5.4
@@ -184,7 +184,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FREEZER=y
-# CONFIG_FSL_QDMA is not set
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FS_POSIX_ACL=y
@@ -286,10 +285,7 @@ CONFIG_MAX_RAW_DEVS=256
CONFIG_MEMFD_CREATE=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_MFD_CORE=y
-# CONFIG_MFD_LOCHNAGAR is not set
-# CONFIG_MFD_ROHM_BD70528 is not set
# CONFIG_MFD_RPISENSE_CORE is not set
-# CONFIG_MFD_STPMIC1 is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
CONFIG_MIGRATION=y
diff --git a/target/linux/bcm27xx/bcm2709/config-5.4 b/target/linux/bcm27xx/bcm2709/config-5.4
index 6713aef789..53734900b6 100644
--- a/target/linux/bcm27xx/bcm2709/config-5.4
+++ b/target/linux/bcm27xx/bcm2709/config-5.4
@@ -30,14 +30,12 @@ CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-# CONFIG_ARCH_MILBEAUT is not set
CONFIG_ARCH_MULTIPLATFORM=y
CONFIG_ARCH_MULTI_V6_V7=y
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_NR_GPIO=0
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-# CONFIG_ARCH_RDA is not set
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
@@ -52,9 +50,6 @@ CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
# CONFIG_ARM_BCM2835_CPUFREQ is not set
CONFIG_ARM_CPU_SUSPEND=y
-# CONFIG_ARM_ERRATA_814220 is not set
-# CONFIG_ARM_ERRATA_857271 is not set
-# CONFIG_ARM_ERRATA_857272 is not set
CONFIG_ARM_GIC=y
CONFIG_ARM_HAS_SG_CHAIN=y
CONFIG_ARM_L1_CACHE_SHIFT=6
@@ -212,7 +207,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_ENERGY_MODEL is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
@@ -242,7 +236,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FREEZER=y
-# CONFIG_FSL_QDMA is not set
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
@@ -277,7 +270,6 @@ CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_BCM_VIRT=y
CONFIG_GPIO_RASPBERRYPI_EXP=y
CONFIG_GPIO_SYSFS=y
-# CONFIG_GVE is not set
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HARDIRQS_SW_RESEND=y
@@ -370,10 +362,7 @@ CONFIG_MDIO_DEVICE=y
CONFIG_MEMFD_CREATE=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_MFD_CORE=y
-# CONFIG_MFD_LOCHNAGAR is not set
-# CONFIG_MFD_ROHM_BD70528 is not set
# CONFIG_MFD_RPISENSE_CORE is not set
-# CONFIG_MFD_STPMIC1 is not set
CONFIG_MFD_SYSCON=y
CONFIG_MICROCHIP_PHY=y
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
@@ -427,11 +416,9 @@ CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_BRCMSTB=y
-# CONFIG_PCIE_BW is not set
CONFIG_PCIE_PME=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
-# CONFIG_PCI_MESON is not set
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PERF_USE_VMALLOC=y
@@ -512,7 +499,6 @@ CONFIG_TIMER_PROBE=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
-# CONFIG_TRUSTED_FOUNDATIONS is not set
CONFIG_UEVENT_HELPER_PATH=""
# CONFIG_UID16 is not set
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
diff --git a/target/linux/bcm27xx/bcm2710/config-5.4 b/target/linux/bcm27xx/bcm2710/config-5.4
index 7527c3fdd9..587c64b757 100644
--- a/target/linux/bcm27xx/bcm2710/config-5.4
+++ b/target/linux/bcm27xx/bcm2710/config-5.4
@@ -157,6 +157,7 @@ CONFIG_BLK_DEV_SD=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_BOUNCE=y
CONFIG_BRCMSTB_THERMAL=y
CONFIG_BRCM_CHAR_DRIVERS=y
CONFIG_CAVIUM_ERRATUM_22375=y
@@ -253,7 +254,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EFI_EARLYCON=y
CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_ENERGY_MODEL is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
@@ -283,7 +283,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FRAME_POINTER=y
CONFIG_FREEZER=y
CONFIG_FSL_ERRATUM_A008585=y
-# CONFIG_FSL_QDMA is not set
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
@@ -323,7 +322,6 @@ CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_BCM_VIRT=y
CONFIG_GPIO_RASPBERRYPI_EXP=y
CONFIG_GPIO_SYSFS=y
-# CONFIG_GVE is not set
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HARDIRQS_SW_RESEND=y
@@ -446,10 +444,7 @@ CONFIG_MEMFD_CREATE=y
# CONFIG_MEMORY_HOTPLUG is not set
CONFIG_MEMORY_ISOLATION=y
CONFIG_MFD_CORE=y
-# CONFIG_MFD_LOCHNAGAR is not set
-# CONFIG_MFD_ROHM_BD70528 is not set
# CONFIG_MFD_RPISENSE_CORE is not set
-# CONFIG_MFD_STPMIC1 is not set
CONFIG_MFD_SYSCON=y
CONFIG_MICROCHIP_PHY=y
CONFIG_MIGRATION=y
@@ -481,7 +476,6 @@ CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
# CONFIG_NUMA is not set
CONFIG_NVMEM=y
-# CONFIG_NVMEM_REBOOT_MODE is not set
# CONFIG_OCTEONTX2_AF is not set
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
@@ -503,7 +497,6 @@ CONFIG_PCI=y
# CONFIG_PCIE_BRCMSTB is not set
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
-# CONFIG_PCI_MESON is not set
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PGTABLE_LEVELS=3
diff --git a/target/linux/bcm27xx/bcm2711/config-5.4 b/target/linux/bcm27xx/bcm2711/config-5.4
index a813eb586c..a4ab0656cb 100644
--- a/target/linux/bcm27xx/bcm2711/config-5.4
+++ b/target/linux/bcm27xx/bcm2711/config-5.4
@@ -160,6 +160,7 @@ CONFIG_BLK_DEV_SD=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_BOUNCE=y
CONFIG_BRCMSTB_THERMAL=y
CONFIG_BRCM_CHAR_DRIVERS=y
CONFIG_BROADCOM_PHY=y
@@ -258,7 +259,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EFI_EARLYCON=y
CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_ENERGY_MODEL is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
@@ -288,7 +288,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FRAME_POINTER=y
CONFIG_FREEZER=y
CONFIG_FSL_ERRATUM_A008585=y
-# CONFIG_FSL_QDMA is not set
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
@@ -329,7 +328,6 @@ CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_BCM_VIRT=y
CONFIG_GPIO_RASPBERRYPI_EXP=y
CONFIG_GPIO_SYSFS=y
-# CONFIG_GVE is not set
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HARDIRQS_SW_RESEND=y
@@ -453,10 +451,7 @@ CONFIG_MEMFD_CREATE=y
# CONFIG_MEMORY_HOTPLUG is not set
CONFIG_MEMORY_ISOLATION=y
CONFIG_MFD_CORE=y
-# CONFIG_MFD_LOCHNAGAR is not set
-# CONFIG_MFD_ROHM_BD70528 is not set
# CONFIG_MFD_RPISENSE_CORE is not set
-# CONFIG_MFD_STPMIC1 is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
@@ -487,7 +482,6 @@ CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
# CONFIG_NUMA is not set
CONFIG_NVMEM=y
-# CONFIG_NVMEM_REBOOT_MODE is not set
# CONFIG_OCTEONTX2_AF is not set
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
@@ -509,11 +503,9 @@ CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y
# CONFIG_PCIE_AL is not set
CONFIG_PCIE_BRCMSTB=y
-# CONFIG_PCIE_BW is not set
CONFIG_PCIE_PME=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
-# CONFIG_PCI_MESON is not set
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PGTABLE_LEVELS=3
diff --git a/target/linux/bcm27xx/patches-5.4/950-0205-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch b/target/linux/bcm27xx/patches-5.4/950-0205-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch
deleted file mode 100644
index 8fd54b1aa3..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0205-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch
+++ /dev/null
@@ -1,1187 +0,0 @@
-From 79624ca23c53064fefee774a89952a587b72cc01 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 19 Feb 2019 22:06:59 +0000
-Subject: [PATCH] PCI: brcmstb: Add Broadcom STB PCIe host controller
- driver
-
-This commit adds the basic Broadcom STB PCIe controller. Missing is
-the ability to process MSI and also handle dma-ranges for inbound
-memory accesses. These two functionalities are added in subsequent
-commits.
-
-The PCIe block contains an MDIO interface. This is a local interface
-only accessible by the PCIe controller. It cannot be used or shared
-by any other HW. As such, the small amount of code for this
-controller is included in this driver as there is little upside to put
-it elsewhere.
-
-Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
----
- drivers/pci/controller/Kconfig | 9 +
- drivers/pci/controller/Makefile | 2 +-
- drivers/pci/controller/pcie-brcmstb.c | 1097 +++++++++++++++++++++++++
- include/soc/brcmstb/memory_api.h | 25 +
- 4 files changed, 1132 insertions(+), 1 deletion(-)
- create mode 100644 drivers/pci/controller/pcie-brcmstb.c
- create mode 100644 include/soc/brcmstb/memory_api.h
-
---- a/drivers/pci/controller/Kconfig
-+++ b/drivers/pci/controller/Kconfig
-@@ -288,5 +288,14 @@ config PCI_HYPERV_INTERFACE
- The Hyper-V PCI Interface is a helper driver allows other drivers to
- have a common interface with the Hyper-V PCI frontend driver.
-
-+config PCIE_BRCMSTB
-+ tristate "Broadcom Brcmstb PCIe platform host driver"
-+ depends on ARCH_BRCMSTB || BMIPS_GENERIC
-+ depends on OF
-+ depends on SOC_BRCMSTB
-+ default ARCH_BRCMSTB || BMIPS_GENERIC
-+ help
-+ Adds support for Broadcom Settop Box PCIe host controller.
-+
- source "drivers/pci/controller/dwc/Kconfig"
- endmenu
---- a/drivers/pci/controller/Makefile
-+++ b/drivers/pci/controller/Makefile
-@@ -29,11 +29,11 @@ obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie
- obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
- obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
- obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
-+obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
- obj-$(CONFIG_VMD) += vmd.o
- # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
- obj-y += dwc/
-
--
- # The following drivers are for devices that use the generic ACPI
- # pci_root.c driver but don't support standard ECAM config access.
- # They contain MCFG quirks to replace the generic ECAM accessors with
---- /dev/null
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -0,0 +1,1097 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/* Copyright (C) 2009 - 2017 Broadcom */
-+
-+#include <linux/clk.h>
-+#include <linux/compiler.h>
-+#include <linux/delay.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/ioport.h>
-+#include <linux/irqdomain.h>
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/log2.h>
-+#include <linux/module.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_pci.h>
-+#include <linux/of_platform.h>
-+#include <linux/pci.h>
-+#include <linux/printk.h>
-+#include <linux/sizes.h>
-+#include <linux/slab.h>
-+#include <soc/brcmstb/memory_api.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include "../pci.h"
-+
-+/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
-+#define BRCM_PCIE_CAP_REGS 0x00ac
-+
-+/*
-+ * Broadcom Settop Box PCIe Register Offsets. The names are from
-+ * the chip's RDB and we use them here so that a script can correlate
-+ * this code and the RDB to prevent discrepancies.
-+ */
-+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 0x0188
-+#define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c
-+#define PCIE_RC_DL_MDIO_ADDR 0x1100
-+#define PCIE_RC_DL_MDIO_WR_DATA 0x1104
-+#define PCIE_RC_DL_MDIO_RD_DATA 0x1108
-+#define PCIE_MISC_MISC_CTRL 0x4008
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010
-+#define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c
-+#define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034
-+#define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038
-+#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c
-+#define PCIE_MISC_PCIE_CTRL 0x4064
-+#define PCIE_MISC_PCIE_STATUS 0x4068
-+#define PCIE_MISC_REVISION 0x406c
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084
-+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
-+#define PCIE_INTR2_CPU_BASE 0x4300
-+
-+/*
-+ * Broadcom Settop Box PCIe Register Field shift and mask info. The
-+ * names are from the chip's RDB and we use them here so that a script
-+ * can correlate this code and the RDB to prevent discrepancies.
-+ */
-+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc
-+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_SHIFT 0x2
-+#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff
-+#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_SHIFT 0x0
-+#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000
-+#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_SHIFT 0xc
-+#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000
-+#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_SHIFT 0xd
-+#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000
-+#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_SHIFT 0x14
-+#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000
-+#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_SHIFT 0x1b
-+#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK 0x7c00000
-+#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_SHIFT 0x16
-+#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK 0x1f
-+#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_SHIFT 0x0
-+#define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f
-+#define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_SHIFT 0x0
-+#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f
-+#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_SHIFT 0x0
-+#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f
-+#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_SHIFT 0x0
-+#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK 0x4
-+#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_SHIFT 0x2
-+#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1
-+#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_SHIFT 0x0
-+#define PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK 0x80
-+#define PCIE_MISC_PCIE_STATUS_PCIE_PORT_SHIFT 0x7
-+#define PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK 0x20
-+#define PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_SHIFT 0x5
-+#define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK 0x10
-+#define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_SHIFT 0x4
-+#define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK 0x40
-+#define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_SHIFT 0x6
-+#define PCIE_MISC_REVISION_MAJMIN_MASK 0xffff
-+#define PCIE_MISC_REVISION_MAJMIN_SHIFT 0
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_SHIFT 0x14
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_SHIFT 0x4
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS 0xc
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK 0xff
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_SHIFT 0x0
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff
-+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_SHIFT 0x0
-+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
-+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_SHIFT 0x1
-+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
-+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_SHIFT 0x1b
-+#define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1
-+#define PCIE_RGR1_SW_INIT_1_PERST_SHIFT 0x0
-+
-+#define BRCM_NUM_PCIE_OUT_WINS 0x4
-+#define BRCM_MAX_SCB 0x4
-+
-+#define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL
-+#define BRCM_MSI_TARGET_ADDR_GT_4GB 0xffffffffcULL
-+
-+#define BURST_SIZE_128 0
-+#define BURST_SIZE_256 1
-+#define BURST_SIZE_512 2
-+
-+/* Offsets from PCIE_INTR2_CPU_BASE */
-+#define STATUS 0x0
-+#define SET 0x4
-+#define CLR 0x8
-+#define MASK_STATUS 0xc
-+#define MASK_SET 0x10
-+#define MASK_CLR 0x14
-+
-+#define PCIE_BUSNUM_SHIFT 20
-+#define PCIE_SLOT_SHIFT 15
-+#define PCIE_FUNC_SHIFT 12
-+
-+#if defined(__BIG_ENDIAN)
-+#define DATA_ENDIAN 2 /* PCIe->DDR inbound traffic */
-+#define MMIO_ENDIAN 2 /* CPU->PCIe outbound traffic */
-+#else
-+#define DATA_ENDIAN 0
-+#define MMIO_ENDIAN 0
-+#endif
-+
-+#define MDIO_PORT0 0x0
-+#define MDIO_DATA_MASK 0x7fffffff
-+#define MDIO_DATA_SHIFT 0x0
-+#define MDIO_PORT_MASK 0xf0000
-+#define MDIO_PORT_SHIFT 0x16
-+#define MDIO_REGAD_MASK 0xffff
-+#define MDIO_REGAD_SHIFT 0x0
-+#define MDIO_CMD_MASK 0xfff00000
-+#define MDIO_CMD_SHIFT 0x14
-+#define MDIO_CMD_READ 0x1
-+#define MDIO_CMD_WRITE 0x0
-+#define MDIO_DATA_DONE_MASK 0x80000000
-+#define MDIO_RD_DONE(x) (((x) & MDIO_DATA_DONE_MASK) ? 1 : 0)
-+#define MDIO_WT_DONE(x) (((x) & MDIO_DATA_DONE_MASK) ? 0 : 1)
-+#define SSC_REGS_ADDR 0x1100
-+#define SET_ADDR_OFFSET 0x1f
-+#define SSC_CNTL_OFFSET 0x2
-+#define SSC_CNTL_OVRD_EN_MASK 0x8000
-+#define SSC_CNTL_OVRD_EN_SHIFT 0xf
-+#define SSC_CNTL_OVRD_VAL_MASK 0x4000
-+#define SSC_CNTL_OVRD_VAL_SHIFT 0xe
-+#define SSC_STATUS_OFFSET 0x1
-+#define SSC_STATUS_SSC_MASK 0x400
-+#define SSC_STATUS_SSC_SHIFT 0xa
-+#define SSC_STATUS_PLL_LOCK_MASK 0x800
-+#define SSC_STATUS_PLL_LOCK_SHIFT 0xb
-+
-+#define IDX_ADDR(pcie) \
-+ ((pcie)->reg_offsets[EXT_CFG_INDEX])
-+#define DATA_ADDR(pcie) \
-+ ((pcie)->reg_offsets[EXT_CFG_DATA])
-+#define PCIE_RGR1_SW_INIT_1(pcie) \
-+ ((pcie)->reg_offsets[RGR1_SW_INIT_1])
-+
-+enum {
-+ RGR1_SW_INIT_1,
-+ EXT_CFG_INDEX,
-+ EXT_CFG_DATA,
-+};
-+
-+enum {
-+ RGR1_SW_INIT_1_INIT_MASK,
-+ RGR1_SW_INIT_1_INIT_SHIFT,
-+ RGR1_SW_INIT_1_PERST_MASK,
-+ RGR1_SW_INIT_1_PERST_SHIFT,
-+};
-+
-+enum pcie_type {
-+ BCM7425,
-+ BCM7435,
-+ GENERIC,
-+ BCM7278,
-+};
-+
-+struct brcm_window {
-+ dma_addr_t pcie_addr;
-+ phys_addr_t cpu_addr;
-+ dma_addr_t size;
-+};
-+
-+/* Internal PCIe Host Controller Information.*/
-+struct brcm_pcie {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct list_head resources;
-+ int irq;
-+ struct clk *clk;
-+ struct pci_bus *root_bus;
-+ struct device_node *dn;
-+ int id;
-+ bool suspended;
-+ int num_out_wins;
-+ bool ssc;
-+ int gen;
-+ struct brcm_window out_wins[BRCM_NUM_PCIE_OUT_WINS];
-+ unsigned int rev;
-+ const int *reg_offsets;
-+ const int *reg_field_info;
-+ enum pcie_type type;
-+};
-+
-+struct pcie_cfg_data {
-+ const int *reg_field_info;
-+ const int *offsets;
-+ const enum pcie_type type;
-+};
-+
-+static const int pcie_reg_field_info[] = {
-+ [RGR1_SW_INIT_1_INIT_MASK] = 0x2,
-+ [RGR1_SW_INIT_1_INIT_SHIFT] = 0x1,
-+};
-+
-+static const int pcie_reg_field_info_bcm7278[] = {
-+ [RGR1_SW_INIT_1_INIT_MASK] = 0x1,
-+ [RGR1_SW_INIT_1_INIT_SHIFT] = 0x0,
-+};
-+
-+static const int pcie_offset_bcm7425[] = {
-+ [RGR1_SW_INIT_1] = 0x8010,
-+ [EXT_CFG_INDEX] = 0x8300,
-+ [EXT_CFG_DATA] = 0x8304,
-+};
-+
-+static const struct pcie_cfg_data bcm7425_cfg = {
-+ .reg_field_info = pcie_reg_field_info,
-+ .offsets = pcie_offset_bcm7425,
-+ .type = BCM7425,
-+};
-+
-+static const int pcie_offsets[] = {
-+ [RGR1_SW_INIT_1] = 0x9210,
-+ [EXT_CFG_INDEX] = 0x9000,
-+ [EXT_CFG_DATA] = 0x9004,
-+};
-+
-+static const struct pcie_cfg_data bcm7435_cfg = {
-+ .reg_field_info = pcie_reg_field_info,
-+ .offsets = pcie_offsets,
-+ .type = BCM7435,
-+};
-+
-+static const struct pcie_cfg_data generic_cfg = {
-+ .reg_field_info = pcie_reg_field_info,
-+ .offsets = pcie_offsets,
-+ .type = GENERIC,
-+};
-+
-+static const int pcie_offset_bcm7278[] = {
-+ [RGR1_SW_INIT_1] = 0xc010,
-+ [EXT_CFG_INDEX] = 0x9000,
-+ [EXT_CFG_DATA] = 0x9004,
-+};
-+
-+static const struct pcie_cfg_data bcm7278_cfg = {
-+ .reg_field_info = pcie_reg_field_info_bcm7278,
-+ .offsets = pcie_offset_bcm7278,
-+ .type = BCM7278,
-+};
-+
-+static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
-+ int where);
-+
-+static struct pci_ops brcm_pcie_ops = {
-+ .map_bus = brcm_pcie_map_conf,
-+ .read = pci_generic_config_read,
-+ .write = pci_generic_config_write,
-+};
-+
-+#if defined(CONFIG_MIPS)
-+/* Broadcom MIPs HW implicitly does the swapping if necessary */
-+#define bcm_readl(a) __raw_readl(a)
-+#define bcm_writel(d, a) __raw_writel(d, a)
-+#define bcm_readw(a) __raw_readw(a)
-+#define bcm_writew(d, a) __raw_writew(d, a)
-+#else
-+#define bcm_readl(a) readl(a)
-+#define bcm_writel(d, a) writel(d, a)
-+#define bcm_readw(a) readw(a)
-+#define bcm_writew(d, a) writew(d, a)
-+#endif
-+
-+/* These macros extract/insert fields to host controller's register set. */
-+#define RD_FLD(base, reg, field) \
-+ rd_fld(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT)
-+#define WR_FLD(base, reg, field, val) \
-+ wr_fld(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT, val)
-+#define WR_FLD_RB(base, reg, field, val) \
-+ wr_fld_rb(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT, val)
-+#define WR_FLD_WITH_OFFSET(base, off, reg, field, val) \
-+ wr_fld(base + reg + off, reg##_##field##_MASK, \
-+ reg##_##field##_SHIFT, val)
-+#define EXTRACT_FIELD(val, reg, field) \
-+ ((val & reg##_##field##_MASK) >> reg##_##field##_SHIFT)
-+#define INSERT_FIELD(val, reg, field, field_val) \
-+ ((val & ~reg##_##field##_MASK) | \
-+ (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT)))
-+
-+static phys_addr_t scb_size[BRCM_MAX_SCB];
-+static int num_memc;
-+static int num_pcie;
-+static DEFINE_MUTEX(brcm_pcie_lock);
-+
-+static u32 rd_fld(void __iomem *p, u32 mask, int shift)
-+{
-+ return (bcm_readl(p) & mask) >> shift;
-+}
-+
-+static void wr_fld(void __iomem *p, u32 mask, int shift, u32 val)
-+{
-+ u32 reg = bcm_readl(p);
-+
-+ reg = (reg & ~mask) | ((val << shift) & mask);
-+ bcm_writel(reg, p);
-+}
-+
-+static void wr_fld_rb(void __iomem *p, u32 mask, int shift, u32 val)
-+{
-+ wr_fld(p, mask, shift, val);
-+ (void)bcm_readl(p);
-+}
-+
-+static const char *link_speed_to_str(int s)
-+{
-+ switch (s) {
-+ case 1:
-+ return "2.5";
-+ case 2:
-+ return "5.0";
-+ case 3:
-+ return "8.0";
-+ default:
-+ break;
-+ }
-+ return "???";
-+}
-+
-+/*
-+ * The roundup_pow_of_two() from log2.h invokes
-+ * __roundup_pow_of_two(unsigned long), but we really need a
-+ * such a function to take a native u64 since unsigned long
-+ * is 32 bits on some configurations. So we provide this helper
-+ * function below.
-+ */
-+static u64 roundup_pow_of_two_64(u64 n)
-+{
-+ return 1ULL << fls64(n - 1);
-+}
-+
-+/*
-+ * This is to convert the size of the inbound "BAR" region to the
-+ * non-linear values of PCIE_X_MISC_RC_BAR[123]_CONFIG_LO.SIZE
-+ */
-+int encode_ibar_size(u64 size)
-+{
-+ int log2_in = ilog2(size);
-+
-+ if (log2_in >= 12 && log2_in <= 15)
-+ /* Covers 4KB to 32KB (inclusive) */
-+ return (log2_in - 12) + 0x1c;
-+ else if (log2_in >= 16 && log2_in <= 37)
-+ /* Covers 64KB to 32GB, (inclusive) */
-+ return log2_in - 15;
-+ /* Something is awry so disable */
-+ return 0;
-+}
-+
-+static u32 mdio_form_pkt(int port, int regad, int cmd)
-+{
-+ u32 pkt = 0;
-+
-+ pkt |= (port << MDIO_PORT_SHIFT) & MDIO_PORT_MASK;
-+ pkt |= (regad << MDIO_REGAD_SHIFT) & MDIO_REGAD_MASK;
-+ pkt |= (cmd << MDIO_CMD_SHIFT) & MDIO_CMD_MASK;
-+
-+ return pkt;
-+}
-+
-+/* negative return value indicates error */
-+static int mdio_read(void __iomem *base, u8 port, u8 regad)
-+{
-+ int tries;
-+ u32 data;
-+
-+ bcm_writel(mdio_form_pkt(port, regad, MDIO_CMD_READ),
-+ base + PCIE_RC_DL_MDIO_ADDR);
-+ bcm_readl(base + PCIE_RC_DL_MDIO_ADDR);
-+
-+ data = bcm_readl(base + PCIE_RC_DL_MDIO_RD_DATA);
-+ for (tries = 0; !MDIO_RD_DONE(data) && tries < 10; tries++) {
-+ udelay(10);
-+ data = bcm_readl(base + PCIE_RC_DL_MDIO_RD_DATA);
-+ }
-+
-+ return MDIO_RD_DONE(data)
-+ ? (data & MDIO_DATA_MASK) >> MDIO_DATA_SHIFT
-+ : -EIO;
-+}
-+
-+/* negative return value indicates error */
-+static int mdio_write(void __iomem *base, u8 port, u8 regad, u16 wrdata)
-+{
-+ int tries;
-+ u32 data;
-+
-+ bcm_writel(mdio_form_pkt(port, regad, MDIO_CMD_WRITE),
-+ base + PCIE_RC_DL_MDIO_ADDR);
-+ bcm_readl(base + PCIE_RC_DL_MDIO_ADDR);
-+ bcm_writel(MDIO_DATA_DONE_MASK | wrdata,
-+ base + PCIE_RC_DL_MDIO_WR_DATA);
-+
-+ data = bcm_readl(base + PCIE_RC_DL_MDIO_WR_DATA);
-+ for (tries = 0; !MDIO_WT_DONE(data) && tries < 10; tries++) {
-+ udelay(10);
-+ data = bcm_readl(base + PCIE_RC_DL_MDIO_WR_DATA);
-+ }
-+
-+ return MDIO_WT_DONE(data) ? 0 : -EIO;
-+}
-+
-+/*
-+ * Configures device for Spread Spectrum Clocking (SSC) mode; a negative
-+ * return value indicates error.
-+ */
-+static int set_ssc(void __iomem *base)
-+{
-+ int tmp;
-+ u16 wrdata;
-+ int pll, ssc;
-+
-+ tmp = mdio_write(base, MDIO_PORT0, SET_ADDR_OFFSET, SSC_REGS_ADDR);
-+ if (tmp < 0)
-+ return tmp;
-+
-+ tmp = mdio_read(base, MDIO_PORT0, SSC_CNTL_OFFSET);
-+ if (tmp < 0)
-+ return tmp;
-+
-+ wrdata = INSERT_FIELD(tmp, SSC_CNTL_OVRD, EN, 1);
-+ wrdata = INSERT_FIELD(wrdata, SSC_CNTL_OVRD, VAL, 1);
-+ tmp = mdio_write(base, MDIO_PORT0, SSC_CNTL_OFFSET, wrdata);
-+ if (tmp < 0)
-+ return tmp;
-+
-+ usleep_range(1000, 2000);
-+ tmp = mdio_read(base, MDIO_PORT0, SSC_STATUS_OFFSET);
-+ if (tmp < 0)
-+ return tmp;
-+
-+ ssc = EXTRACT_FIELD(tmp, SSC_STATUS, SSC);
-+ pll = EXTRACT_FIELD(tmp, SSC_STATUS, PLL_LOCK);
-+
-+ return (ssc && pll) ? 0 : -EIO;
-+}
-+
-+/* Limits operation to a specific generation (1, 2, or 3) */
-+static void set_gen(void __iomem *base, int gen)
-+{
-+ u32 lnkcap = bcm_readl(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP);
-+ u16 lnkctl2 = bcm_readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2);
-+
-+ lnkcap = (lnkcap & ~PCI_EXP_LNKCAP_SLS) | gen;
-+ bcm_writel(lnkcap, base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP);
-+
-+ lnkctl2 = (lnkctl2 & ~0xf) | gen;
-+ bcm_writew(lnkctl2, base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2);
-+}
-+
-+static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
-+ unsigned int win, phys_addr_t cpu_addr,
-+ dma_addr_t pcie_addr, dma_addr_t size)
-+{
-+ void __iomem *base = pcie->base;
-+ phys_addr_t cpu_addr_mb, limit_addr_mb;
-+ u32 tmp;
-+
-+ /* Set the base of the pcie_addr window */
-+ bcm_writel(lower_32_bits(pcie_addr) + MMIO_ENDIAN,
-+ base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + (win * 8));
-+ bcm_writel(upper_32_bits(pcie_addr),
-+ base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + (win * 8));
-+
-+ cpu_addr_mb = cpu_addr >> 20;
-+ limit_addr_mb = (cpu_addr + size - 1) >> 20;
-+
-+ /* Write the addr base low register */
-+ WR_FLD_WITH_OFFSET(base, (win * 4),
-+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT,
-+ BASE, cpu_addr_mb);
-+ /* Write the addr limit low register */
-+ WR_FLD_WITH_OFFSET(base, (win * 4),
-+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT,
-+ LIMIT, limit_addr_mb);
-+
-+ if (pcie->type != BCM7435 && pcie->type != BCM7425) {
-+ /* Write the cpu addr high register */
-+ tmp = (u32)(cpu_addr_mb >>
-+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS);
-+ WR_FLD_WITH_OFFSET(base, (win * 8),
-+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI,
-+ BASE, tmp);
-+ /* Write the cpu limit high register */
-+ tmp = (u32)(limit_addr_mb >>
-+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS);
-+ WR_FLD_WITH_OFFSET(base, (win * 8),
-+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI,
-+ LIMIT, tmp);
-+ }
-+}
-+
-+/* Configuration space read/write support */
-+static int cfg_index(int busnr, int devfn, int reg)
-+{
-+ return ((PCI_SLOT(devfn) & 0x1f) << PCIE_SLOT_SHIFT)
-+ | ((PCI_FUNC(devfn) & 0x07) << PCIE_FUNC_SHIFT)
-+ | (busnr << PCIE_BUSNUM_SHIFT)
-+ | (reg & ~3);
-+}
-+
-+/* The controller is capable of serving in both RC and EP roles */
-+static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie)
-+{
-+ void __iomem *base = pcie->base;
-+ u32 val = bcm_readl(base + PCIE_MISC_PCIE_STATUS);
-+
-+ return !!EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_PORT);
-+}
-+
-+static bool brcm_pcie_link_up(struct brcm_pcie *pcie)
-+{
-+ void __iomem *base = pcie->base;
-+ u32 val = bcm_readl(base + PCIE_MISC_PCIE_STATUS);
-+ u32 dla = EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_DL_ACTIVE);
-+ u32 plu = EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_PHYLINKUP);
-+
-+ return (dla && plu) ? true : false;
-+}
-+
-+static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
-+ int where)
-+{
-+ struct brcm_pcie *pcie = bus->sysdata;
-+ void __iomem *base = pcie->base;
-+ int idx;
-+
-+ /* Accesses to the RC go right to the RC registers if slot==0 */
-+ if (pci_is_root_bus(bus))
-+ return PCI_SLOT(devfn) ? NULL : base + where;
-+
-+ /* For devices, write to the config space index register */
-+ idx = cfg_index(bus->number, devfn, where);
-+ bcm_writel(idx, pcie->base + IDX_ADDR(pcie));
-+ return base + DATA_ADDR(pcie) + (where & 0x3);
-+}
-+
-+static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie,
-+ unsigned int val)
-+{
-+ unsigned int shift = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_SHIFT];
-+ u32 mask = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_MASK];
-+
-+ wr_fld_rb(pcie->base + PCIE_RGR1_SW_INIT_1(pcie), mask, shift, val);
-+}
-+
-+static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie,
-+ unsigned int val)
-+{
-+ if (pcie->type != BCM7278)
-+ wr_fld_rb(pcie->base + PCIE_RGR1_SW_INIT_1(pcie),
-+ PCIE_RGR1_SW_INIT_1_PERST_MASK,
-+ PCIE_RGR1_SW_INIT_1_PERST_SHIFT, val);
-+ else
-+ /* Assert = 0, de-assert = 1 on 7278 */
-+ WR_FLD_RB(pcie->base, PCIE_MISC_PCIE_CTRL, PCIE_PERSTB, !val);
-+}
-+
-+static int brcm_pcie_add_controller(struct brcm_pcie *pcie)
-+{
-+ int i, ret = 0;
-+
-+ mutex_lock(&brcm_pcie_lock);
-+ if (num_pcie > 0) {
-+ num_pcie++;
-+ goto done;
-+ }
-+
-+ /* Determine num_memc and their sizes */
-+ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) {
-+ u64 size = brcmstb_memory_memc_size(i);
-+
-+ if (size == (u64)-1) {
-+ dev_err(pcie->dev, "cannot get memc%d size\n", i);
-+ ret = -EINVAL;
-+ goto done;
-+ } else if (size) {
-+ scb_size[i] = roundup_pow_of_two_64(size);
-+ num_memc++;
-+ } else {
-+ break;
-+ }
-+ }
-+ if (!ret && num_memc == 0) {
-+ ret = -EINVAL;
-+ goto done;
-+ }
-+
-+ num_pcie++;
-+done:
-+ mutex_unlock(&brcm_pcie_lock);
-+ return ret;
-+}
-+
-+static void brcm_pcie_remove_controller(struct brcm_pcie *pcie)
-+{
-+ mutex_lock(&brcm_pcie_lock);
-+ if (--num_pcie == 0)
-+ num_memc = 0;
-+ mutex_unlock(&brcm_pcie_lock);
-+}
-+
-+static int brcm_pcie_parse_request_of_pci_ranges(struct brcm_pcie *pcie)
-+{
-+ struct resource_entry *win;
-+ int ret;
-+
-+ ret = devm_of_pci_get_host_bridge_resources(pcie->dev, 0, 0xff,
-+ &pcie->resources, NULL);
-+ if (ret) {
-+ dev_err(pcie->dev, "failed to get host resources\n");
-+ return ret;
-+ }
-+
-+ resource_list_for_each_entry(win, &pcie->resources) {
-+ struct resource *parent, *res = win->res;
-+ dma_addr_t offset = (dma_addr_t)win->offset;
-+
-+ if (resource_type(res) == IORESOURCE_IO) {
-+ parent = &ioport_resource;
-+ } else if (resource_type(res) == IORESOURCE_MEM) {
-+ if (pcie->num_out_wins >= BRCM_NUM_PCIE_OUT_WINS) {
-+ dev_err(pcie->dev, "too many outbound wins\n");
-+ return -EINVAL;
-+ }
-+ pcie->out_wins[pcie->num_out_wins].cpu_addr
-+ = (phys_addr_t)res->start;
-+ pcie->out_wins[pcie->num_out_wins].pcie_addr
-+ = (dma_addr_t)(res->start
-+ - (phys_addr_t)offset);
-+ pcie->out_wins[pcie->num_out_wins].size
-+ = (dma_addr_t)(res->end - res->start + 1);
-+ pcie->num_out_wins++;
-+ parent = &iomem_resource;
-+ } else {
-+ continue;
-+ }
-+
-+ ret = devm_request_resource(pcie->dev, parent, res);
-+ if (ret) {
-+ dev_err(pcie->dev, "failed to get res %pR\n", res);
-+ return ret;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int brcm_pcie_setup(struct brcm_pcie *pcie)
-+{
-+ void __iomem *base = pcie->base;
-+ unsigned int scb_size_val;
-+ u64 rc_bar2_offset, rc_bar2_size, total_mem_size = 0;
-+ u32 tmp, burst;
-+ int i, j, ret, limit;
-+ u16 nlw, cls, lnksta;
-+ bool ssc_good = false;
-+ struct device *dev = pcie->dev;
-+
-+ /* Reset the bridge */
-+ brcm_pcie_bridge_sw_init_set(pcie, 1);
-+
-+ /*
-+ * Ensure that the fundamental reset is asserted, except for 7278,
-+ * which fails if we do this.
-+ */
-+ if (pcie->type != BCM7278)
-+ brcm_pcie_perst_set(pcie, 1);
-+
-+ usleep_range(100, 200);
-+
-+ /* Take the bridge out of reset */
-+ brcm_pcie_bridge_sw_init_set(pcie, 0);
-+
-+ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 0);
-+ /* Wait for SerDes to be stable */
-+ usleep_range(100, 200);
-+
-+ /* Grab the PCIe hw revision number */
-+ tmp = bcm_readl(base + PCIE_MISC_REVISION);
-+ pcie->rev = EXTRACT_FIELD(tmp, PCIE_MISC_REVISION, MAJMIN);
-+
-+ /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
-+ tmp = INSERT_FIELD(0, PCIE_MISC_MISC_CTRL, SCB_ACCESS_EN, 1);
-+ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, CFG_READ_UR_MODE, 1);
-+ burst = (pcie->type == GENERIC || pcie->type == BCM7278)
-+ ? BURST_SIZE_512 : BURST_SIZE_256;
-+ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE, burst);
-+ bcm_writel(tmp, base + PCIE_MISC_MISC_CTRL);
-+
-+ /*
-+ * Set up inbound memory view for the EP (called RC_BAR2,
-+ * not to be confused with the BARs that are advertised by
-+ * the EP).
-+ */
-+ for (i = 0; i < num_memc; i++)
-+ total_mem_size += scb_size[i];
-+
-+ /*
-+ * The PCIe host controller by design must set the inbound
-+ * viewport to be a contiguous arrangement of all of the
-+ * system's memory. In addition, its size mut be a power of
-+ * two. To further complicate matters, the viewport must
-+ * start on a pcie-address that is aligned on a multiple of its
-+ * size. If a portion of the viewport does not represent
-+ * system memory -- e.g. 3GB of memory requires a 4GB viewport
-+ * -- we can map the outbound memory in or after 3GB and even
-+ * though the viewport will overlap the outbound memory the
-+ * controller will know to send outbound memory downstream and
-+ * everything else upstream.
-+ */
-+ rc_bar2_size = roundup_pow_of_two_64(total_mem_size);
-+
-+ /*
-+ * Set simple configuration based on memory sizes
-+ * only. We always start the viewport at address 0.
-+ */
-+ rc_bar2_offset = 0;
-+
-+ tmp = lower_32_bits(rc_bar2_offset);
-+ tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE,
-+ encode_ibar_size(rc_bar2_size));
-+ bcm_writel(tmp, base + PCIE_MISC_RC_BAR2_CONFIG_LO);
-+ bcm_writel(upper_32_bits(rc_bar2_offset),
-+ base + PCIE_MISC_RC_BAR2_CONFIG_HI);
-+
-+ scb_size_val = scb_size[0]
-+ ? ilog2(scb_size[0]) - 15 : 0xf; /* 0xf is 1GB */
-+ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB0_SIZE, scb_size_val);
-+
-+ if (num_memc > 1) {
-+ scb_size_val = scb_size[1]
-+ ? ilog2(scb_size[1]) - 15 : 0xf; /* 0xf is 1GB */
-+ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB1_SIZE, scb_size_val);
-+ }
-+
-+ if (num_memc > 2) {
-+ scb_size_val = scb_size[2]
-+ ? ilog2(scb_size[2]) - 15 : 0xf; /* 0xf is 1GB */
-+ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB2_SIZE, scb_size_val);
-+ }
-+
-+ /* disable the PCIe->GISB memory window (RC_BAR1) */
-+ WR_FLD(base, PCIE_MISC_RC_BAR1_CONFIG_LO, SIZE, 0);
-+
-+ /* disable the PCIe->SCB memory window (RC_BAR3) */
-+ WR_FLD(base, PCIE_MISC_RC_BAR3_CONFIG_LO, SIZE, 0);
-+
-+ if (!pcie->suspended) {
-+ /* clear any interrupts we find on boot */
-+ bcm_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + CLR);
-+ (void)bcm_readl(base + PCIE_INTR2_CPU_BASE + CLR);
-+ }
-+
-+ /* Mask all interrupts since we are not handling any yet */
-+ bcm_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + MASK_SET);
-+ (void)bcm_readl(base + PCIE_INTR2_CPU_BASE + MASK_SET);
-+
-+ if (pcie->gen)
-+ set_gen(base, pcie->gen);
-+
-+ /* Unassert the fundamental reset */
-+ brcm_pcie_perst_set(pcie, 0);
-+
-+ /*
-+ * Give the RC/EP time to wake up, before trying to configure RC.
-+ * Intermittently check status for link-up, up to a total of 100ms
-+ * when we don't know if the device is there, and up to 1000ms if
-+ * we do know the device is there.
-+ */
-+ limit = pcie->suspended ? 1000 : 100;
-+ for (i = 1, j = 0; j < limit && !brcm_pcie_link_up(pcie);
-+ j += i, i = i * 2)
-+ msleep(i + j > limit ? limit - j : i);
-+
-+ if (!brcm_pcie_link_up(pcie)) {
-+ dev_info(dev, "link down\n");
-+ return -ENODEV;
-+ }
-+
-+ if (!brcm_pcie_rc_mode(pcie)) {
-+ dev_err(dev, "PCIe misconfigured; is in EP mode\n");
-+ return -EINVAL;
-+ }
-+
-+ for (i = 0; i < pcie->num_out_wins; i++)
-+ brcm_pcie_set_outbound_win(pcie, i, pcie->out_wins[i].cpu_addr,
-+ pcie->out_wins[i].pcie_addr,
-+ pcie->out_wins[i].size);
-+
-+ /*
-+ * For config space accesses on the RC, show the right class for
-+ * a PCIe-PCIe bridge (the default setting is to be EP mode).
-+ */
-+ WR_FLD_RB(base, PCIE_RC_CFG_PRIV1_ID_VAL3, CLASS_CODE, 0x060400);
-+
-+ if (pcie->ssc) {
-+ ret = set_ssc(base);
-+ if (ret == 0)
-+ ssc_good = true;
-+ else
-+ dev_err(dev, "failed attempt to enter ssc mode\n");
-+ }
-+
-+ lnksta = bcm_readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKSTA);
-+ cls = lnksta & PCI_EXP_LNKSTA_CLS;
-+ nlw = (lnksta & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT;
-+ dev_info(dev, "link up, %s Gbps x%u %s\n", link_speed_to_str(cls),
-+ nlw, ssc_good ? "(SSC)" : "(!SSC)");
-+
-+ /* PCIe->SCB endian mode for BAR */
-+ /* field ENDIAN_MODE_BAR2 = DATA_ENDIAN */
-+ WR_FLD_RB(base, PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1,
-+ ENDIAN_MODE_BAR2, DATA_ENDIAN);
-+
-+ /*
-+ * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
-+ * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1.
-+ */
-+ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, CLKREQ_DEBUG_ENABLE, 1);
-+
-+ return 0;
-+}
-+
-+/* L23 is a low-power PCIe link state */
-+static void enter_l23(struct brcm_pcie *pcie)
-+{
-+ void __iomem *base = pcie->base;
-+ int tries, l23;
-+
-+ /* assert request for L23 */
-+ WR_FLD_RB(base, PCIE_MISC_PCIE_CTRL, PCIE_L23_REQUEST, 1);
-+ /* poll L23 status */
-+ for (tries = 0, l23 = 0; tries < 1000 && !l23; tries++)
-+ l23 = RD_FLD(base, PCIE_MISC_PCIE_STATUS, PCIE_LINK_IN_L23);
-+ if (!l23)
-+ dev_err(pcie->dev, "failed to enter L23\n");
-+}
-+
-+static void turn_off(struct brcm_pcie *pcie)
-+{
-+ void __iomem *base = pcie->base;
-+
-+ if (brcm_pcie_link_up(pcie))
-+ enter_l23(pcie);
-+ /* Assert fundamental reset */
-+ brcm_pcie_perst_set(pcie, 1);
-+ /* Deassert request for L23 in case it was asserted */
-+ WR_FLD_RB(base, PCIE_MISC_PCIE_CTRL, PCIE_L23_REQUEST, 0);
-+ /* Turn off SerDes */
-+ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 1);
-+ /* Shutdown PCIe bridge */
-+ brcm_pcie_bridge_sw_init_set(pcie, 1);
-+}
-+
-+static int brcm_pcie_suspend(struct device *dev)
-+{
-+ struct brcm_pcie *pcie = dev_get_drvdata(dev);
-+
-+ turn_off(pcie);
-+ clk_disable_unprepare(pcie->clk);
-+ pcie->suspended = true;
-+
-+ return 0;
-+}
-+
-+static int brcm_pcie_resume(struct device *dev)
-+{
-+ struct brcm_pcie *pcie = dev_get_drvdata(dev);
-+ void __iomem *base;
-+ int ret;
-+
-+ base = pcie->base;
-+ clk_prepare_enable(pcie->clk);
-+
-+ /* Take bridge out of reset so we can access the SerDes reg */
-+ brcm_pcie_bridge_sw_init_set(pcie, 0);
-+
-+ /* Turn on SerDes */
-+ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 0);
-+ /* Wait for SerDes to be stable */
-+ usleep_range(100, 200);
-+
-+ ret = brcm_pcie_setup(pcie);
-+ if (ret)
-+ return ret;
-+
-+ pcie->suspended = false;
-+
-+ return 0;
-+}
-+
-+static void _brcm_pcie_remove(struct brcm_pcie *pcie)
-+{
-+ turn_off(pcie);
-+ clk_disable_unprepare(pcie->clk);
-+ clk_put(pcie->clk);
-+ brcm_pcie_remove_controller(pcie);
-+}
-+
-+static int brcm_pcie_remove(struct platform_device *pdev)
-+{
-+ struct brcm_pcie *pcie = platform_get_drvdata(pdev);
-+
-+ pci_stop_root_bus(pcie->root_bus);
-+ pci_remove_root_bus(pcie->root_bus);
-+ _brcm_pcie_remove(pcie);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id brcm_pcie_match[] = {
-+ { .compatible = "brcm,bcm7425-pcie", .data = &bcm7425_cfg },
-+ { .compatible = "brcm,bcm7435-pcie", .data = &bcm7435_cfg },
-+ { .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg },
-+ { .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, brcm_pcie_match);
-+
-+static int brcm_pcie_probe(struct platform_device *pdev)
-+{
-+ struct device_node *dn = pdev->dev.of_node;
-+ const struct of_device_id *of_id;
-+ const struct pcie_cfg_data *data;
-+ int ret;
-+ struct brcm_pcie *pcie;
-+ struct resource *res;
-+ void __iomem *base;
-+ u32 tmp;
-+ struct pci_host_bridge *bridge;
-+ struct pci_bus *child;
-+
-+ bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie));
-+ if (!bridge)
-+ return -ENOMEM;
-+
-+ pcie = pci_host_bridge_priv(bridge);
-+ INIT_LIST_HEAD(&pcie->resources);
-+
-+ of_id = of_match_node(brcm_pcie_match, dn);
-+ if (!of_id) {
-+ dev_err(&pdev->dev, "failed to look up compatible string\n");
-+ return -EINVAL;
-+ }
-+
-+ if (of_property_read_u32(dn, "dma-ranges", &tmp) == 0) {
-+ dev_err(&pdev->dev, "cannot yet handle dma-ranges\n");
-+ return -EINVAL;
-+ }
-+
-+ data = of_id->data;
-+ pcie->reg_offsets = data->offsets;
-+ pcie->reg_field_info = data->reg_field_info;
-+ pcie->type = data->type;
-+ pcie->dn = dn;
-+ pcie->dev = &pdev->dev;
-+
-+ /* We use the domain number as our controller number */
-+ pcie->id = of_get_pci_domain_nr(dn);
-+ if (pcie->id < 0)
-+ return pcie->id;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res)
-+ return -EINVAL;
-+
-+ base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ pcie->clk = of_clk_get_by_name(dn, "sw_pcie");
-+ if (IS_ERR(pcie->clk)) {
-+ dev_err(&pdev->dev, "could not get clock\n");
-+ pcie->clk = NULL;
-+ }
-+ pcie->base = base;
-+
-+ ret = of_pci_get_max_link_speed(dn);
-+ pcie->gen = (ret < 0) ? 0 : ret;
-+
-+ pcie->ssc = of_property_read_bool(dn, "brcm,enable-ssc");
-+
-+ ret = irq_of_parse_and_map(pdev->dev.of_node, 0);
-+ if (ret == 0)
-+ /* keep going, as we don't use this intr yet */
-+ dev_warn(pcie->dev, "cannot get PCIe interrupt\n");
-+ else
-+ pcie->irq = ret;
-+
-+ ret = brcm_pcie_parse_request_of_pci_ranges(pcie);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_prepare_enable(pcie->clk);
-+ if (ret) {
-+ dev_err(&pdev->dev, "could not enable clock\n");
-+ return ret;
-+ }
-+
-+ ret = brcm_pcie_add_controller(pcie);
-+ if (ret)
-+ return ret;
-+
-+ ret = brcm_pcie_setup(pcie);
-+ if (ret)
-+ goto fail;
-+
-+ list_splice_init(&pcie->resources, &bridge->windows);
-+ bridge->dev.parent = &pdev->dev;
-+ bridge->busnr = 0;
-+ bridge->ops = &brcm_pcie_ops;
-+ bridge->sysdata = pcie;
-+ bridge->map_irq = of_irq_parse_and_map_pci;
-+ bridge->swizzle_irq = pci_common_swizzle;
-+
-+ ret = pci_scan_root_bus_bridge(bridge);
-+ if (ret < 0) {
-+ dev_err(pcie->dev, "Scanning root bridge failed\n");
-+ goto fail;
-+ }
-+
-+ pci_assign_unassigned_bus_resources(bridge->bus);
-+ list_for_each_entry(child, &bridge->bus->children, node)
-+ pcie_bus_configure_settings(child);
-+ pci_bus_add_devices(bridge->bus);
-+ platform_set_drvdata(pdev, pcie);
-+ pcie->root_bus = bridge->bus;
-+
-+ return 0;
-+
-+fail:
-+ _brcm_pcie_remove(pcie);
-+ return ret;
-+}
-+
-+static const struct dev_pm_ops brcm_pcie_pm_ops = {
-+ .suspend_noirq = brcm_pcie_suspend,
-+ .resume_noirq = brcm_pcie_resume,
-+};
-+
-+static struct platform_driver brcm_pcie_driver = {
-+ .probe = brcm_pcie_probe,
-+ .remove = brcm_pcie_remove,
-+ .driver = {
-+ .name = "brcm-pcie",
-+ .owner = THIS_MODULE,
-+ .of_match_table = brcm_pcie_match,
-+ .pm = &brcm_pcie_pm_ops,
-+ },
-+};
-+
-+module_platform_driver(brcm_pcie_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("Broadcom STB PCIe RC driver");
-+MODULE_AUTHOR("Broadcom");
---- /dev/null
-+++ b/include/soc/brcmstb/memory_api.h
-@@ -0,0 +1,25 @@
-+#ifndef __MEMORY_API_H
-+#define __MEMORY_API_H
-+
-+/*
-+ * Bus Interface Unit control register setup, must happen early during boot,
-+ * before SMP is brought up, called by machine entry point.
-+ */
-+void brcmstb_biuctrl_init(void);
-+
-+#ifdef CONFIG_SOC_BRCMSTB
-+int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa);
-+u64 brcmstb_memory_memc_size(int memc);
-+#else
-+static inline int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa)
-+{
-+ return -EINVAL;
-+}
-+
-+static inline u64 brcmstb_memory_memc_size(int memc)
-+{
-+ return -1;
-+}
-+#endif
-+
-+#endif /* __MEMORY_API_H */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0208-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch b/target/linux/bcm27xx/patches-5.4/950-0205-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch
index d4ff3165b3..d4ff3165b3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0208-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0205-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0206-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch b/target/linux/bcm27xx/patches-5.4/950-0206-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch
deleted file mode 100644
index 329b6e268c..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0206-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch
+++ /dev/null
@@ -1,569 +0,0 @@
-From d45590eb858ac7a2578d477791881ba7ffb1e615 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 19 Feb 2019 22:06:59 +0000
-Subject: [PATCH] PCI: brcmstb: Add dma-range mapping for inbound
- traffic
-
-The Broadcom STB PCIe host controller is intimately related to the
-memory subsystem. This close relationship adds complexity to how cpu
-system memory is mapped to PCIe memory. Ideally, this mapping is an
-identity mapping, or an identity mapping off by a constant. Not so in
-this case.
-
-Consider the Broadcom reference board BCM97445LCC_4X8 which has 6 GB
-of system memory. Here is how the PCIe controller maps the
-system memory to PCIe memory:
-
- memc0-a@[ 0....3fffffff] <=> pci@[ 0....3fffffff]
- memc0-b@[100000000...13fffffff] <=> pci@[ 40000000....7fffffff]
- memc1-a@[ 40000000....7fffffff] <=> pci@[ 80000000....bfffffff]
- memc1-b@[300000000...33fffffff] <=> pci@[ c0000000....ffffffff]
- memc2-a@[ 80000000....bfffffff] <=> pci@[100000000...13fffffff]
- memc2-b@[c00000000...c3fffffff] <=> pci@[140000000...17fffffff]
-
-Although there are some "gaps" that can be added between the
-individual mappings by software, the permutation of memory regions for
-the most part is fixed by HW. The solution of having something close
-to an identity mapping is not possible.
-
-The idea behind this HW design is that the same PCIe module can
-act as an RC or EP, and if it acts as an EP it concatenates all
-of system memory into a BAR so anything can be accessed. Unfortunately,
-when the PCIe block is in the role of an RC it also presents this
-"BAR" to downstream PCIe devices, rather than offering an identity map
-between its system memory and PCIe space.
-
-Suppose that an endpoint driver allocs some DMA memory. Suppose this
-memory is located at 0x6000_0000, which is in the middle of memc1-a.
-The driver wants a dma_addr_t value that it can pass on to the EP to
-use. Without doing any custom mapping, the EP will use this value for
-DMA: the driver will get a dma_addr_t equal to 0x6000_0000. But this
-won't work; the device needs a dma_addr_t that reflects the PCIe space
-address, namely 0xa000_0000.
-
-So, essentially the solution to this problem must modify the
-dma_addr_t returned by the DMA routines routines. There are two
-ways (I know of) of doing this:
-
-(a) overriding/redefining the dma_to_phys() and phys_to_dma() calls
-that are used by the dma_ops routines. This is the approach of
-
- arch/mips/cavium-octeon/dma-octeon.c
-
-In ARM and ARM64 these two routines are defiend in asm/dma-mapping.h
-as static inline functions.
-
-(b) Subscribe to a notifier that notifies when a device is added to a
-bus. When this happens, set_dma_ops() can be called for the device.
-This method is mentioned in:
-
- http://lxr.free-electrons.com/source/drivers/of/platform.c?v=3.16#L152
-
-where it says as a comment
-
- "In case if platform code need to use own special DMA
- configuration, it can use Platform bus notifier and
- handle BUS_NOTIFY_ADD_DEVICE event to fix up DMA
- configuration."
-
-Solution (b) is what this commit does. It uses its own set of
-dma_ops which are wrappers around the arch_dma_ops. The
-wrappers translate the dma addresses before/after invoking
-the arch_dma_ops, as appropriate.
-
-Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
----
- drivers/pci/controller/pcie-brcmstb.c | 420 +++++++++++++++++++++++++-
- 1 file changed, 411 insertions(+), 9 deletions(-)
-
---- a/drivers/pci/controller/pcie-brcmstb.c
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -4,6 +4,7 @@
- #include <linux/clk.h>
- #include <linux/compiler.h>
- #include <linux/delay.h>
-+#include <linux/dma-mapping.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/io.h>
-@@ -319,11 +320,307 @@ static struct pci_ops brcm_pcie_ops = {
- ((val & ~reg##_##field##_MASK) | \
- (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT)))
-
-+static const struct dma_map_ops *arch_dma_ops;
-+static const struct dma_map_ops *brcm_dma_ops_ptr;
-+static struct of_pci_range *dma_ranges;
-+static int num_dma_ranges;
-+
- static phys_addr_t scb_size[BRCM_MAX_SCB];
- static int num_memc;
- static int num_pcie;
- static DEFINE_MUTEX(brcm_pcie_lock);
-
-+static dma_addr_t brcm_to_pci(dma_addr_t addr)
-+{
-+ struct of_pci_range *p;
-+
-+ if (!num_dma_ranges)
-+ return addr;
-+
-+ for (p = dma_ranges; p < &dma_ranges[num_dma_ranges]; p++)
-+ if (addr >= p->cpu_addr && addr < (p->cpu_addr + p->size))
-+ return addr - p->cpu_addr + p->pci_addr;
-+
-+ return addr;
-+}
-+
-+static dma_addr_t brcm_to_cpu(dma_addr_t addr)
-+{
-+ struct of_pci_range *p;
-+
-+ if (!num_dma_ranges)
-+ return addr;
-+
-+ for (p = dma_ranges; p < &dma_ranges[num_dma_ranges]; p++)
-+ if (addr >= p->pci_addr && addr < (p->pci_addr + p->size))
-+ return addr - p->pci_addr + p->cpu_addr;
-+
-+ return addr;
-+}
-+
-+static void *brcm_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-+ gfp_t gfp, unsigned long attrs)
-+{
-+ void *ret;
-+
-+ ret = arch_dma_ops->alloc(dev, size, handle, gfp, attrs);
-+ if (ret)
-+ *handle = brcm_to_pci(*handle);
-+ return ret;
-+}
-+
-+static void brcm_free(struct device *dev, size_t size, void *cpu_addr,
-+ dma_addr_t handle, unsigned long attrs)
-+{
-+ handle = brcm_to_cpu(handle);
-+ arch_dma_ops->free(dev, size, cpu_addr, handle, attrs);
-+}
-+
-+static int brcm_mmap(struct device *dev, struct vm_area_struct *vma,
-+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
-+ unsigned long attrs)
-+{
-+ dma_addr = brcm_to_cpu(dma_addr);
-+ return arch_dma_ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
-+}
-+
-+static int brcm_get_sgtable(struct device *dev, struct sg_table *sgt,
-+ void *cpu_addr, dma_addr_t handle, size_t size,
-+ unsigned long attrs)
-+{
-+ handle = brcm_to_cpu(handle);
-+ return arch_dma_ops->get_sgtable(dev, sgt, cpu_addr, handle, size,
-+ attrs);
-+}
-+
-+static dma_addr_t brcm_map_page(struct device *dev, struct page *page,
-+ unsigned long offset, size_t size,
-+ enum dma_data_direction dir,
-+ unsigned long attrs)
-+{
-+ return brcm_to_pci(arch_dma_ops->map_page(dev, page, offset, size,
-+ dir, attrs));
-+}
-+
-+static void brcm_unmap_page(struct device *dev, dma_addr_t handle,
-+ size_t size, enum dma_data_direction dir,
-+ unsigned long attrs)
-+{
-+ handle = brcm_to_cpu(handle);
-+ arch_dma_ops->unmap_page(dev, handle, size, dir, attrs);
-+}
-+
-+static int brcm_map_sg(struct device *dev, struct scatterlist *sgl,
-+ int nents, enum dma_data_direction dir,
-+ unsigned long attrs)
-+{
-+ int i, j;
-+ struct scatterlist *sg;
-+
-+ for_each_sg(sgl, sg, nents, i) {
-+#ifdef CONFIG_NEED_SG_DMA_LENGTH
-+ sg->dma_length = sg->length;
-+#endif
-+ sg->dma_address =
-+ brcm_dma_ops_ptr->map_page(dev, sg_page(sg), sg->offset,
-+ sg->length, dir, attrs);
-+ if (dma_mapping_error(dev, sg->dma_address))
-+ goto bad_mapping;
-+ }
-+ return nents;
-+
-+bad_mapping:
-+ for_each_sg(sgl, sg, i, j)
-+ brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg),
-+ sg_dma_len(sg), dir, attrs);
-+ return 0;
-+}
-+
-+static void brcm_unmap_sg(struct device *dev,
-+ struct scatterlist *sgl, int nents,
-+ enum dma_data_direction dir,
-+ unsigned long attrs)
-+{
-+ int i;
-+ struct scatterlist *sg;
-+
-+ for_each_sg(sgl, sg, nents, i)
-+ brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg),
-+ sg_dma_len(sg), dir, attrs);
-+}
-+
-+static void brcm_sync_single_for_cpu(struct device *dev,
-+ dma_addr_t handle, size_t size,
-+ enum dma_data_direction dir)
-+{
-+ handle = brcm_to_cpu(handle);
-+ arch_dma_ops->sync_single_for_cpu(dev, handle, size, dir);
-+}
-+
-+static void brcm_sync_single_for_device(struct device *dev,
-+ dma_addr_t handle, size_t size,
-+ enum dma_data_direction dir)
-+{
-+ handle = brcm_to_cpu(handle);
-+ arch_dma_ops->sync_single_for_device(dev, handle, size, dir);
-+}
-+
-+static dma_addr_t brcm_map_resource(struct device *dev, phys_addr_t phys,
-+ size_t size,
-+ enum dma_data_direction dir,
-+ unsigned long attrs)
-+{
-+ if (arch_dma_ops->map_resource)
-+ return brcm_to_pci(arch_dma_ops->map_resource
-+ (dev, phys, size, dir, attrs));
-+ return brcm_to_pci((dma_addr_t)phys);
-+}
-+
-+static void brcm_unmap_resource(struct device *dev, dma_addr_t handle,
-+ size_t size, enum dma_data_direction dir,
-+ unsigned long attrs)
-+{
-+ if (arch_dma_ops->unmap_resource)
-+ arch_dma_ops->unmap_resource(dev, brcm_to_cpu(handle), size,
-+ dir, attrs);
-+}
-+
-+void brcm_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
-+ int nents, enum dma_data_direction dir)
-+{
-+ struct scatterlist *sg;
-+ int i;
-+
-+ for_each_sg(sgl, sg, nents, i)
-+ brcm_dma_ops_ptr->sync_single_for_cpu(dev, sg_dma_address(sg),
-+ sg->length, dir);
-+}
-+
-+void brcm_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
-+ int nents, enum dma_data_direction dir)
-+{
-+ struct scatterlist *sg;
-+ int i;
-+
-+ for_each_sg(sgl, sg, nents, i)
-+ brcm_dma_ops_ptr->sync_single_for_device(dev,
-+ sg_dma_address(sg),
-+ sg->length, dir);
-+}
-+
-+static int brcm_mapping_error(struct device *dev, dma_addr_t dma_addr)
-+{
-+ return arch_dma_ops->mapping_error(dev, dma_addr);
-+}
-+
-+static int brcm_dma_supported(struct device *dev, u64 mask)
-+{
-+ if (num_dma_ranges) {
-+ /*
-+ * It is our translated addresses that the EP will "see", so
-+ * we check all of the ranges for the largest possible value.
-+ */
-+ int i;
-+
-+ for (i = 0; i < num_dma_ranges; i++)
-+ if (dma_ranges[i].pci_addr + dma_ranges[i].size - 1
-+ > mask)
-+ return 0;
-+ return 1;
-+ }
-+
-+ return arch_dma_ops->dma_supported(dev, mask);
-+}
-+
-+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
-+u64 brcm_get_required_mask)(struct device *dev)
-+{
-+ return arch_dma_ops->get_required_mask(dev);
-+}
-+#endif
-+
-+static const struct dma_map_ops brcm_dma_ops = {
-+ .alloc = brcm_alloc,
-+ .free = brcm_free,
-+ .mmap = brcm_mmap,
-+ .get_sgtable = brcm_get_sgtable,
-+ .map_page = brcm_map_page,
-+ .unmap_page = brcm_unmap_page,
-+ .map_sg = brcm_map_sg,
-+ .unmap_sg = brcm_unmap_sg,
-+ .map_resource = brcm_map_resource,
-+ .unmap_resource = brcm_unmap_resource,
-+ .sync_single_for_cpu = brcm_sync_single_for_cpu,
-+ .sync_single_for_device = brcm_sync_single_for_device,
-+ .sync_sg_for_cpu = brcm_sync_sg_for_cpu,
-+ .sync_sg_for_device = brcm_sync_sg_for_device,
-+ .mapping_error = brcm_mapping_error,
-+ .dma_supported = brcm_dma_supported,
-+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
-+ .get_required_mask = brcm_get_required_mask,
-+#endif
-+};
-+
-+static void brcm_set_dma_ops(struct device *dev)
-+{
-+ int ret;
-+
-+ if (IS_ENABLED(CONFIG_ARM64)) {
-+ /*
-+ * We are going to invoke get_dma_ops(). That
-+ * function, at this point in time, invokes
-+ * get_arch_dma_ops(), and for ARM64 that function
-+ * returns a pointer to dummy_dma_ops. So then we'd
-+ * like to call arch_setup_dma_ops(), but that isn't
-+ * exported. Instead, we call of_dma_configure(),
-+ * which is exported, and this calls
-+ * arch_setup_dma_ops(). Once we do this the call to
-+ * get_dma_ops() will work properly because
-+ * dev->dma_ops will be set.
-+ */
-+ ret = of_dma_configure(dev, dev->of_node, true);
-+ if (ret) {
-+ dev_err(dev, "of_dma_configure() failed: %d\n", ret);
-+ return;
-+ }
-+ }
-+
-+ arch_dma_ops = get_dma_ops(dev);
-+ if (!arch_dma_ops) {
-+ dev_err(dev, "failed to get arch_dma_ops\n");
-+ return;
-+ }
-+
-+ set_dma_ops(dev, &brcm_dma_ops);
-+}
-+
-+static int brcmstb_platform_notifier(struct notifier_block *nb,
-+ unsigned long event, void *__dev)
-+{
-+ struct device *dev = __dev;
-+
-+ brcm_dma_ops_ptr = &brcm_dma_ops;
-+ if (event != BUS_NOTIFY_ADD_DEVICE)
-+ return NOTIFY_DONE;
-+
-+ brcm_set_dma_ops(dev);
-+ return NOTIFY_OK;
-+}
-+
-+static struct notifier_block brcmstb_platform_nb = {
-+ .notifier_call = brcmstb_platform_notifier,
-+};
-+
-+static int brcm_register_notifier(void)
-+{
-+ return bus_register_notifier(&pci_bus_type, &brcmstb_platform_nb);
-+}
-+
-+static int brcm_unregister_notifier(void)
-+{
-+ return bus_unregister_notifier(&pci_bus_type, &brcmstb_platform_nb);
-+}
-+
- static u32 rd_fld(void __iomem *p, u32 mask, int shift)
- {
- return (bcm_readl(p) & mask) >> shift;
-@@ -597,9 +894,71 @@ static inline void brcm_pcie_perst_set(s
- WR_FLD_RB(pcie->base, PCIE_MISC_PCIE_CTRL, PCIE_PERSTB, !val);
- }
-
-+static int pci_dma_range_parser_init(struct of_pci_range_parser *parser,
-+ struct device_node *node)
-+{
-+ const int na = 3, ns = 2;
-+ int rlen;
-+
-+ parser->node = node;
-+ parser->pna = of_n_addr_cells(node);
-+ parser->np = parser->pna + na + ns;
-+
-+ parser->range = of_get_property(node, "dma-ranges", &rlen);
-+ if (!parser->range)
-+ return -ENOENT;
-+
-+ parser->end = parser->range + rlen / sizeof(__be32);
-+
-+ return 0;
-+}
-+
-+static int brcm_pcie_parse_map_dma_ranges(struct brcm_pcie *pcie)
-+{
-+ int i;
-+ struct of_pci_range_parser parser;
-+ struct device_node *dn = pcie->dn;
-+
-+ /*
-+ * Parse dma-ranges property if present. If there are multiple
-+ * PCIe controllers, we only have to parse from one of them since
-+ * the others will have an identical mapping.
-+ */
-+ if (!pci_dma_range_parser_init(&parser, dn)) {
-+ unsigned int max_ranges
-+ = (parser.end - parser.range) / parser.np;
-+
-+ dma_ranges = kcalloc(max_ranges, sizeof(struct of_pci_range),
-+ GFP_KERNEL);
-+ if (!dma_ranges)
-+ return -ENOMEM;
-+
-+ for (i = 0; of_pci_range_parser_one(&parser, dma_ranges + i);
-+ i++)
-+ num_dma_ranges++;
-+ }
-+
-+ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) {
-+ u64 size = brcmstb_memory_memc_size(i);
-+
-+ if (size == (u64)-1) {
-+ dev_err(pcie->dev, "cannot get memc%d size", i);
-+ return -EINVAL;
-+ } else if (size) {
-+ scb_size[i] = roundup_pow_of_two_64(size);
-+ num_memc++;
-+ } else {
-+ break;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
- static int brcm_pcie_add_controller(struct brcm_pcie *pcie)
- {
- int i, ret = 0;
-+ struct device *dev = pcie->dev;
-
- mutex_lock(&brcm_pcie_lock);
- if (num_pcie > 0) {
-@@ -607,12 +966,21 @@ static int brcm_pcie_add_controller(stru
- goto done;
- }
-
-+ ret = brcm_register_notifier();
-+ if (ret) {
-+ dev_err(dev, "failed to register pci bus notifier\n");
-+ goto done;
-+ }
-+ ret = brcm_pcie_parse_map_dma_ranges(pcie);
-+ if (ret)
-+ goto done;
-+
- /* Determine num_memc and their sizes */
- for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) {
- u64 size = brcmstb_memory_memc_size(i);
-
- if (size == (u64)-1) {
-- dev_err(pcie->dev, "cannot get memc%d size\n", i);
-+ dev_err(dev, "cannot get memc%d size\n", i);
- ret = -EINVAL;
- goto done;
- } else if (size) {
-@@ -636,8 +1004,16 @@ done:
- static void brcm_pcie_remove_controller(struct brcm_pcie *pcie)
- {
- mutex_lock(&brcm_pcie_lock);
-- if (--num_pcie == 0)
-- num_memc = 0;
-+ if (--num_pcie > 0)
-+ goto out;
-+
-+ if (brcm_unregister_notifier())
-+ dev_err(pcie->dev, "failed to unregister pci bus notifier\n");
-+ kfree(dma_ranges);
-+ dma_ranges = NULL;
-+ num_dma_ranges = 0;
-+ num_memc = 0;
-+out:
- mutex_unlock(&brcm_pcie_lock);
- }
-
-@@ -757,6 +1133,38 @@ static int brcm_pcie_setup(struct brcm_p
- */
- rc_bar2_offset = 0;
-
-+ if (dma_ranges) {
-+ /*
-+ * The best-case scenario is to place the inbound
-+ * region in the first 4GB of pci-space, as some
-+ * legacy devices can only address 32bits.
-+ * We would also like to put the MSI under 4GB
-+ * as well, since some devices require a 32bit
-+ * MSI target address.
-+ */
-+ if (total_mem_size <= 0xc0000000ULL &&
-+ rc_bar2_size <= 0x100000000ULL) {
-+ rc_bar2_offset = 0;
-+ } else {
-+ /*
-+ * The system memory is 4GB or larger so we
-+ * cannot start the inbound region at location
-+ * 0 (since we have to allow some space for
-+ * outbound memory @ 3GB). So instead we
-+ * start it at the 1x multiple of its size
-+ */
-+ rc_bar2_offset = rc_bar2_size;
-+ }
-+
-+ } else {
-+ /*
-+ * Set simple configuration based on memory sizes
-+ * only. We always start the viewport at address 0,
-+ * and set the MSI target address accordingly.
-+ */
-+ rc_bar2_offset = 0;
-+ }
-+
- tmp = lower_32_bits(rc_bar2_offset);
- tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE,
- encode_ibar_size(rc_bar2_size));
-@@ -967,7 +1375,6 @@ static int brcm_pcie_probe(struct platfo
- struct brcm_pcie *pcie;
- struct resource *res;
- void __iomem *base;
-- u32 tmp;
- struct pci_host_bridge *bridge;
- struct pci_bus *child;
-
-@@ -984,11 +1391,6 @@ static int brcm_pcie_probe(struct platfo
- return -EINVAL;
- }
-
-- if (of_property_read_u32(dn, "dma-ranges", &tmp) == 0) {
-- dev_err(&pdev->dev, "cannot yet handle dma-ranges\n");
-- return -EINVAL;
-- }
--
- data = of_id->data;
- pcie->reg_offsets = data->offsets;
- pcie->reg_field_info = data->reg_field_info;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0210-arm-bcm2835-DMA-can-only-address-1GB.patch b/target/linux/bcm27xx/patches-5.4/950-0206-arm-bcm2835-DMA-can-only-address-1GB.patch
index 86ad707b95..86ad707b95 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0210-arm-bcm2835-DMA-can-only-address-1GB.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0206-arm-bcm2835-DMA-can-only-address-1GB.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0207-PCI-brcmstb-Add-MSI-capability.patch b/target/linux/bcm27xx/patches-5.4/950-0207-PCI-brcmstb-Add-MSI-capability.patch
deleted file mode 100644
index d2cf8e22d4..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0207-PCI-brcmstb-Add-MSI-capability.patch
+++ /dev/null
@@ -1,543 +0,0 @@
-From b1619c83208e7b804e2c3547dbf24bb02b3be239 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 19 Feb 2019 22:06:59 +0000
-Subject: [PATCH] PCI: brcmstb: Add MSI capability
-
-This commit adds MSI to the Broadcom STB PCIe host controller. It does
-not add MSIX since that functionality is not in the HW. The MSI
-controller is physically located within the PCIe block, however, there
-is no reason why the MSI controller could not be moved elsewhere in
-the future.
-
-Since the internal Brcmstb MSI controller is intertwined with the PCIe
-controller, it is not its own platform device but rather part of the
-PCIe platform device.
-
-Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
----
- drivers/pci/controller/pcie-brcmstb.c | 374 ++++++++++++++++++++++++--
- 1 file changed, 353 insertions(+), 21 deletions(-)
-
---- a/drivers/pci/controller/pcie-brcmstb.c
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -1,6 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0
- /* Copyright (C) 2009 - 2017 Broadcom */
-
-+#include <linux/bitops.h>
- #include <linux/clk.h>
- #include <linux/compiler.h>
- #include <linux/delay.h>
-@@ -9,11 +10,13 @@
- #include <linux/interrupt.h>
- #include <linux/io.h>
- #include <linux/ioport.h>
-+#include <linux/irqchip/chained_irq.h>
- #include <linux/irqdomain.h>
- #include <linux/kernel.h>
- #include <linux/list.h>
- #include <linux/log2.h>
- #include <linux/module.h>
-+#include <linux/msi.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
- #include <linux/of_pci.h>
-@@ -47,6 +50,9 @@
- #define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034
- #define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038
- #define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c
-+#define PCIE_MISC_MSI_BAR_CONFIG_LO 0x4044
-+#define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048
-+#define PCIE_MISC_MSI_DATA_CONFIG 0x404c
- #define PCIE_MISC_PCIE_CTRL 0x4064
- #define PCIE_MISC_PCIE_STATUS 0x4068
- #define PCIE_MISC_REVISION 0x406c
-@@ -55,6 +61,7 @@
- #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084
- #define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
- #define PCIE_INTR2_CPU_BASE 0x4300
-+#define PCIE_MSI_INTR2_BASE 0x4500
-
- /*
- * Broadcom Settop Box PCIe Register Field shift and mask info. The
-@@ -115,6 +122,8 @@
-
- #define BRCM_NUM_PCIE_OUT_WINS 0x4
- #define BRCM_MAX_SCB 0x4
-+#define BRCM_INT_PCI_MSI_NR 32
-+#define BRCM_PCIE_HW_REV_33 0x0303
-
- #define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL
- #define BRCM_MSI_TARGET_ADDR_GT_4GB 0xffffffffcULL
-@@ -203,6 +212,33 @@ struct brcm_window {
- dma_addr_t size;
- };
-
-+struct brcm_msi {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct device_node *dn;
-+ struct irq_domain *msi_domain;
-+ struct irq_domain *inner_domain;
-+ struct mutex lock; /* guards the alloc/free operations */
-+ u64 target_addr;
-+ int irq;
-+
-+ /* intr_base is the base pointer for interrupt status/set/clr regs */
-+ void __iomem *intr_base;
-+
-+ /* intr_legacy_mask indicates how many bits are MSI interrupts */
-+ u32 intr_legacy_mask;
-+
-+ /*
-+ * intr_legacy_offset indicates bit position of MSI_01. It is
-+ * to map the register bit position to a hwirq that starts at 0.
-+ */
-+ u32 intr_legacy_offset;
-+
-+ /* used indicates which MSI interrupts have been alloc'd */
-+ unsigned long used;
-+ unsigned int rev;
-+};
-+
- /* Internal PCIe Host Controller Information.*/
- struct brcm_pcie {
- struct device *dev;
-@@ -217,7 +253,10 @@ struct brcm_pcie {
- int num_out_wins;
- bool ssc;
- int gen;
-+ u64 msi_target_addr;
- struct brcm_window out_wins[BRCM_NUM_PCIE_OUT_WINS];
-+ struct brcm_msi *msi;
-+ bool msi_internal;
- unsigned int rev;
- const int *reg_offsets;
- const int *reg_field_info;
-@@ -225,9 +264,9 @@ struct brcm_pcie {
- };
-
- struct pcie_cfg_data {
-- const int *reg_field_info;
-- const int *offsets;
-- const enum pcie_type type;
-+ const int *reg_field_info;
-+ const int *offsets;
-+ const enum pcie_type type;
- };
-
- static const int pcie_reg_field_info[] = {
-@@ -828,6 +867,267 @@ static void brcm_pcie_set_outbound_win(s
- }
- }
-
-+static struct irq_chip brcm_msi_irq_chip = {
-+ .name = "Brcm_MSI",
-+ .irq_mask = pci_msi_mask_irq,
-+ .irq_unmask = pci_msi_unmask_irq,
-+};
-+
-+static struct msi_domain_info brcm_msi_domain_info = {
-+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-+ MSI_FLAG_PCI_MSIX),
-+ .chip = &brcm_msi_irq_chip,
-+};
-+
-+static void brcm_pcie_msi_isr(struct irq_desc *desc)
-+{
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ struct brcm_msi *msi;
-+ unsigned long status, virq;
-+ u32 mask, bit, hwirq;
-+ struct device *dev;
-+
-+ chained_irq_enter(chip, desc);
-+ msi = irq_desc_get_handler_data(desc);
-+ mask = msi->intr_legacy_mask;
-+ dev = msi->dev;
-+
-+ while ((status = bcm_readl(msi->intr_base + STATUS) & mask)) {
-+ for_each_set_bit(bit, &status, BRCM_INT_PCI_MSI_NR) {
-+ /* clear the interrupt */
-+ bcm_writel(1 << bit, msi->intr_base + CLR);
-+
-+ /* Account for legacy interrupt offset */
-+ hwirq = bit - msi->intr_legacy_offset;
-+
-+ virq = irq_find_mapping(msi->inner_domain, hwirq);
-+ if (virq) {
-+ if (msi->used & (1 << hwirq))
-+ generic_handle_irq(virq);
-+ else
-+ dev_info(dev, "unhandled MSI %d\n",
-+ hwirq);
-+ } else {
-+ /* Unknown MSI, just clear it */
-+ dev_dbg(dev, "unexpected MSI\n");
-+ }
-+ }
-+ }
-+ chained_irq_exit(chip, desc);
-+}
-+
-+static void brcm_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
-+{
-+ struct brcm_msi *msi = irq_data_get_irq_chip_data(data);
-+ u32 temp;
-+
-+ msg->address_lo = lower_32_bits(msi->target_addr);
-+ msg->address_hi = upper_32_bits(msi->target_addr);
-+ temp = bcm_readl(msi->base + PCIE_MISC_MSI_DATA_CONFIG);
-+ msg->data = ((temp >> 16) & (temp & 0xffff)) | data->hwirq;
-+}
-+
-+static int brcm_msi_set_affinity(struct irq_data *irq_data,
-+ const struct cpumask *mask, bool force)
-+{
-+ return -EINVAL;
-+}
-+
-+static struct irq_chip brcm_msi_bottom_irq_chip = {
-+ .name = "Brcm_MSI",
-+ .irq_compose_msi_msg = brcm_compose_msi_msg,
-+ .irq_set_affinity = brcm_msi_set_affinity,
-+};
-+
-+static int brcm_msi_alloc(struct brcm_msi *msi)
-+{
-+ int bit, hwirq;
-+
-+ mutex_lock(&msi->lock);
-+ bit = ~msi->used ? ffz(msi->used) : -1;
-+
-+ if (bit >= 0 && bit < BRCM_INT_PCI_MSI_NR) {
-+ msi->used |= (1 << bit);
-+ hwirq = bit - msi->intr_legacy_offset;
-+ } else {
-+ hwirq = -ENOSPC;
-+ }
-+
-+ mutex_unlock(&msi->lock);
-+ return hwirq;
-+}
-+
-+static void brcm_msi_free(struct brcm_msi *msi, unsigned long hwirq)
-+{
-+ mutex_lock(&msi->lock);
-+ msi->used &= ~(1 << (hwirq + msi->intr_legacy_offset));
-+ mutex_unlock(&msi->lock);
-+}
-+
-+static int brcm_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
-+ unsigned int nr_irqs, void *args)
-+{
-+ struct brcm_msi *msi = domain->host_data;
-+ int hwirq;
-+
-+ hwirq = brcm_msi_alloc(msi);
-+
-+ if (hwirq < 0)
-+ return hwirq;
-+
-+ irq_domain_set_info(domain, virq, (irq_hw_number_t)hwirq,
-+ &brcm_msi_bottom_irq_chip, domain->host_data,
-+ handle_simple_irq, NULL, NULL);
-+ return 0;
-+}
-+
-+static void brcm_irq_domain_free(struct irq_domain *domain,
-+ unsigned int virq, unsigned int nr_irqs)
-+{
-+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
-+ struct brcm_msi *msi = irq_data_get_irq_chip_data(d);
-+
-+ brcm_msi_free(msi, d->hwirq);
-+}
-+
-+static void brcm_msi_set_regs(struct brcm_msi *msi)
-+{
-+ u32 data_val, msi_lo, msi_hi;
-+
-+ if (msi->rev >= BRCM_PCIE_HW_REV_33) {
-+ /*
-+ * ffe0 -- least sig 5 bits are 0 indicating 32 msgs
-+ * 6540 -- this is our arbitrary unique data value
-+ */
-+ data_val = 0xffe06540;
-+ } else {
-+ /*
-+ * fff8 -- least sig 3 bits are 0 indicating 8 msgs
-+ * 6540 -- this is our arbitrary unique data value
-+ */
-+ data_val = 0xfff86540;
-+ }
-+
-+ /*
-+ * Make sure we are not masking MSIs. Note that MSIs can be masked,
-+ * but that occurs on the PCIe EP device
-+ */
-+ bcm_writel(0xffffffff & msi->intr_legacy_mask,
-+ msi->intr_base + MASK_CLR);
-+
-+ msi_lo = lower_32_bits(msi->target_addr);
-+ msi_hi = upper_32_bits(msi->target_addr);
-+ /*
-+ * The 0 bit of PCIE_MISC_MSI_BAR_CONFIG_LO is repurposed to MSI
-+ * enable, which we set to 1.
-+ */
-+ bcm_writel(msi_lo | 1, msi->base + PCIE_MISC_MSI_BAR_CONFIG_LO);
-+ bcm_writel(msi_hi, msi->base + PCIE_MISC_MSI_BAR_CONFIG_HI);
-+ bcm_writel(data_val, msi->base + PCIE_MISC_MSI_DATA_CONFIG);
-+}
-+
-+static const struct irq_domain_ops msi_domain_ops = {
-+ .alloc = brcm_irq_domain_alloc,
-+ .free = brcm_irq_domain_free,
-+};
-+
-+static int brcm_allocate_domains(struct brcm_msi *msi)
-+{
-+ struct fwnode_handle *fwnode = of_node_to_fwnode(msi->dn);
-+ struct device *dev = msi->dev;
-+
-+ msi->inner_domain = irq_domain_add_linear(NULL, BRCM_INT_PCI_MSI_NR,
-+ &msi_domain_ops, msi);
-+ if (!msi->inner_domain) {
-+ dev_err(dev, "failed to create IRQ domain\n");
-+ return -ENOMEM;
-+ }
-+
-+ msi->msi_domain = pci_msi_create_irq_domain(fwnode,
-+ &brcm_msi_domain_info,
-+ msi->inner_domain);
-+ if (!msi->msi_domain) {
-+ dev_err(dev, "failed to create MSI domain\n");
-+ irq_domain_remove(msi->inner_domain);
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+
-+static void brcm_free_domains(struct brcm_msi *msi)
-+{
-+ irq_domain_remove(msi->msi_domain);
-+ irq_domain_remove(msi->inner_domain);
-+}
-+
-+static void brcm_msi_remove(struct brcm_pcie *pcie)
-+{
-+ struct brcm_msi *msi = pcie->msi;
-+
-+ if (!msi)
-+ return;
-+ irq_set_chained_handler(msi->irq, NULL);
-+ irq_set_handler_data(msi->irq, NULL);
-+ brcm_free_domains(msi);
-+}
-+
-+static int brcm_pcie_enable_msi(struct brcm_pcie *pcie)
-+{
-+ struct brcm_msi *msi;
-+ int irq, ret;
-+ struct device *dev = pcie->dev;
-+
-+ irq = irq_of_parse_and_map(dev->of_node, 1);
-+ if (irq <= 0) {
-+ dev_err(dev, "cannot map msi intr\n");
-+ return -ENODEV;
-+ }
-+
-+ msi = devm_kzalloc(dev, sizeof(struct brcm_msi), GFP_KERNEL);
-+ if (!msi)
-+ return -ENOMEM;
-+
-+ msi->dev = dev;
-+ msi->base = pcie->base;
-+ msi->rev = pcie->rev;
-+ msi->dn = pcie->dn;
-+ msi->target_addr = pcie->msi_target_addr;
-+ msi->irq = irq;
-+
-+ ret = brcm_allocate_domains(msi);
-+ if (ret)
-+ return ret;
-+
-+ irq_set_chained_handler_and_data(msi->irq, brcm_pcie_msi_isr, msi);
-+
-+ if (msi->rev >= BRCM_PCIE_HW_REV_33) {
-+ msi->intr_base = msi->base + PCIE_MSI_INTR2_BASE;
-+ /*
-+ * This version of PCIe hw has only 32 intr bits
-+ * starting at bit position 0.
-+ */
-+ msi->intr_legacy_mask = 0xffffffff;
-+ msi->intr_legacy_offset = 0x0;
-+ msi->used = 0x0;
-+
-+ } else {
-+ msi->intr_base = msi->base + PCIE_INTR2_CPU_BASE;
-+ /*
-+ * This version of PCIe hw has only 8 intr bits starting
-+ * at bit position 24.
-+ */
-+ msi->intr_legacy_mask = 0xff000000;
-+ msi->intr_legacy_offset = 24;
-+ msi->used = 0x00ffffff;
-+ }
-+
-+ brcm_msi_set_regs(msi);
-+ pcie->msi = msi;
-+
-+ return 0;
-+}
-+
- /* Configuration space read/write support */
- static int cfg_index(int busnr, int devfn, int reg)
- {
-@@ -1072,6 +1372,7 @@ static int brcm_pcie_setup(struct brcm_p
- u16 nlw, cls, lnksta;
- bool ssc_good = false;
- struct device *dev = pcie->dev;
-+ u64 msi_target_addr;
-
- /* Reset the bridge */
- brcm_pcie_bridge_sw_init_set(pcie, 1);
-@@ -1116,27 +1417,24 @@ static int brcm_pcie_setup(struct brcm_p
- * The PCIe host controller by design must set the inbound
- * viewport to be a contiguous arrangement of all of the
- * system's memory. In addition, its size mut be a power of
-- * two. To further complicate matters, the viewport must
-- * start on a pcie-address that is aligned on a multiple of its
-- * size. If a portion of the viewport does not represent
-- * system memory -- e.g. 3GB of memory requires a 4GB viewport
-- * -- we can map the outbound memory in or after 3GB and even
-- * though the viewport will overlap the outbound memory the
-- * controller will know to send outbound memory downstream and
-- * everything else upstream.
-+ * two. Further, the MSI target address must NOT be placed
-+ * inside this region, as the decoding logic will consider its
-+ * address to be inbound memory traffic. To further
-+ * complicate matters, the viewport must start on a
-+ * pcie-address that is aligned on a multiple of its size.
-+ * If a portion of the viewport does not represent system
-+ * memory -- e.g. 3GB of memory requires a 4GB viewport --
-+ * we can map the outbound memory in or after 3GB and even
-+ * though the viewport will overlap the outbound memory
-+ * the controller will know to send outbound memory downstream
-+ * and everything else upstream.
- */
- rc_bar2_size = roundup_pow_of_two_64(total_mem_size);
-
-- /*
-- * Set simple configuration based on memory sizes
-- * only. We always start the viewport at address 0.
-- */
-- rc_bar2_offset = 0;
--
- if (dma_ranges) {
- /*
- * The best-case scenario is to place the inbound
-- * region in the first 4GB of pci-space, as some
-+ * region in the first 4GB of pcie-space, as some
- * legacy devices can only address 32bits.
- * We would also like to put the MSI under 4GB
- * as well, since some devices require a 32bit
-@@ -1145,6 +1443,14 @@ static int brcm_pcie_setup(struct brcm_p
- if (total_mem_size <= 0xc0000000ULL &&
- rc_bar2_size <= 0x100000000ULL) {
- rc_bar2_offset = 0;
-+ /* If the viewport is less then 4GB we can fit
-+ * the MSI target address under 4GB. Otherwise
-+ * put it right below 64GB.
-+ */
-+ msi_target_addr =
-+ (rc_bar2_size == 0x100000000ULL)
-+ ? BRCM_MSI_TARGET_ADDR_GT_4GB
-+ : BRCM_MSI_TARGET_ADDR_LT_4GB;
- } else {
- /*
- * The system memory is 4GB or larger so we
-@@ -1154,8 +1460,12 @@ static int brcm_pcie_setup(struct brcm_p
- * start it at the 1x multiple of its size
- */
- rc_bar2_offset = rc_bar2_size;
-- }
-
-+ /* Since we are starting the viewport at 4GB or
-+ * higher, put the MSI target address below 4GB
-+ */
-+ msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB;
-+ }
- } else {
- /*
- * Set simple configuration based on memory sizes
-@@ -1163,7 +1473,12 @@ static int brcm_pcie_setup(struct brcm_p
- * and set the MSI target address accordingly.
- */
- rc_bar2_offset = 0;
-+
-+ msi_target_addr = (rc_bar2_size >= 0x100000000ULL)
-+ ? BRCM_MSI_TARGET_ADDR_GT_4GB
-+ : BRCM_MSI_TARGET_ADDR_LT_4GB;
- }
-+ pcie->msi_target_addr = msi_target_addr;
-
- tmp = lower_32_bits(rc_bar2_offset);
- tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE,
-@@ -1333,6 +1648,9 @@ static int brcm_pcie_resume(struct devic
- if (ret)
- return ret;
-
-+ if (pcie->msi && pcie->msi_internal)
-+ brcm_msi_set_regs(pcie->msi);
-+
- pcie->suspended = false;
-
- return 0;
-@@ -1340,6 +1658,7 @@ static int brcm_pcie_resume(struct devic
-
- static void _brcm_pcie_remove(struct brcm_pcie *pcie)
- {
-+ brcm_msi_remove(pcie);
- turn_off(pcie);
- clk_disable_unprepare(pcie->clk);
- clk_put(pcie->clk);
-@@ -1368,7 +1687,7 @@ MODULE_DEVICE_TABLE(of, brcm_pcie_match)
-
- static int brcm_pcie_probe(struct platform_device *pdev)
- {
-- struct device_node *dn = pdev->dev.of_node;
-+ struct device_node *dn = pdev->dev.of_node, *msi_dn;
- const struct of_device_id *of_id;
- const struct pcie_cfg_data *data;
- int ret;
-@@ -1448,6 +1767,20 @@ static int brcm_pcie_probe(struct platfo
- if (ret)
- goto fail;
-
-+ msi_dn = of_parse_phandle(pcie->dn, "msi-parent", 0);
-+ /* Use the internal MSI if no msi-parent property */
-+ if (!msi_dn)
-+ msi_dn = pcie->dn;
-+
-+ if (pci_msi_enabled() && msi_dn == pcie->dn) {
-+ ret = brcm_pcie_enable_msi(pcie);
-+ if (ret)
-+ dev_err(pcie->dev,
-+ "probe of internal MSI failed: %d)", ret);
-+ else
-+ pcie->msi_internal = true;
-+ }
-+
- list_splice_init(&pcie->resources, &bridge->windows);
- bridge->dev.parent = &pdev->dev;
- bridge->busnr = 0;
-@@ -1470,7 +1803,6 @@ static int brcm_pcie_probe(struct platfo
- pcie->root_bus = bridge->bus;
-
- return 0;
--
- fail:
- _brcm_pcie_remove(pcie);
- return ret;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0211-hwrng-iproc-rng200-Add-BCM2838-support.patch b/target/linux/bcm27xx/patches-5.4/950-0207-hwrng-iproc-rng200-Add-BCM2838-support.patch
index c9eac88066..c9eac88066 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0211-hwrng-iproc-rng200-Add-BCM2838-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0207-hwrng-iproc-rng200-Add-BCM2838-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0212-thermal-brcmstb_thermal-Add-BCM2838-support.patch b/target/linux/bcm27xx/patches-5.4/950-0208-thermal-brcmstb_thermal-Add-BCM2838-support.patch
index 6fed7ec4eb..6fed7ec4eb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0212-thermal-brcmstb_thermal-Add-BCM2838-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0208-thermal-brcmstb_thermal-Add-BCM2838-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0209-pcie-brcmstb-Changes-for-BCM2711.patch b/target/linux/bcm27xx/patches-5.4/950-0209-pcie-brcmstb-Changes-for-BCM2711.patch
deleted file mode 100644
index edeab9558a..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0209-pcie-brcmstb-Changes-for-BCM2711.patch
+++ /dev/null
@@ -1,1428 +0,0 @@
-From 1dab5ded41ed07adc12f26e529aa64209a7c44b6 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 19 Feb 2019 22:06:59 +0000
-Subject: [PATCH] pcie-brcmstb: Changes for BCM2711
-
-The initial brcmstb PCIe driver - originally taken from the V3(?)
-patch set - has been modified significantly for the BCM2711.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/dma/bcm2835-dma.c | 107 ++++
- drivers/pci/controller/Makefile | 4 +
- drivers/pci/controller/pcie-brcmstb-bounce.c | 558 +++++++++++++++++++
- drivers/pci/controller/pcie-brcmstb-bounce.h | 32 ++
- drivers/pci/controller/pcie-brcmstb.c | 245 ++++----
- drivers/soc/bcm/brcmstb/Makefile | 2 +-
- drivers/soc/bcm/brcmstb/memory.c | 158 ++++++
- 7 files changed, 991 insertions(+), 115 deletions(-)
- create mode 100644 drivers/pci/controller/pcie-brcmstb-bounce.c
- create mode 100644 drivers/pci/controller/pcie-brcmstb-bounce.h
- create mode 100644 drivers/soc/bcm/brcmstb/memory.c
-
---- a/drivers/dma/bcm2835-dma.c
-+++ b/drivers/dma/bcm2835-dma.c
-@@ -64,6 +64,17 @@ struct bcm2835_dma_cb {
- uint32_t pad[2];
- };
-
-+struct bcm2838_dma40_scb {
-+ uint32_t ti;
-+ uint32_t src;
-+ uint32_t srci;
-+ uint32_t dst;
-+ uint32_t dsti;
-+ uint32_t len;
-+ uint32_t next_cb;
-+ uint32_t rsvd;
-+};
-+
- struct bcm2835_cb_entry {
- struct bcm2835_dma_cb *cb;
- dma_addr_t paddr;
-@@ -180,6 +191,45 @@ struct bcm2835_desc {
- #define MAX_DMA_LEN SZ_1G
- #define MAX_LITE_DMA_LEN (SZ_64K - 4)
-
-+/* 40-bit DMA support */
-+#define BCM2838_DMA40_CS 0x00
-+#define BCM2838_DMA40_CB 0x04
-+#define BCM2838_DMA40_DEBUG 0x0c
-+#define BCM2858_DMA40_TI 0x10
-+#define BCM2838_DMA40_SRC 0x14
-+#define BCM2838_DMA40_SRCI 0x18
-+#define BCM2838_DMA40_DEST 0x1c
-+#define BCM2838_DMA40_DESTI 0x20
-+#define BCM2838_DMA40_LEN 0x24
-+#define BCM2838_DMA40_NEXT_CB 0x28
-+#define BCM2838_DMA40_DEBUG2 0x2c
-+
-+#define BCM2838_DMA40_CS_ACTIVE BIT(0)
-+#define BCM2838_DMA40_CS_END BIT(1)
-+
-+#define BCM2838_DMA40_CS_QOS(x) (((x) & 0x1f) << 16)
-+#define BCM2838_DMA40_CS_PANIC_QOS(x) (((x) & 0x1f) << 20)
-+#define BCM2838_DMA40_CS_WRITE_WAIT BIT(28)
-+
-+#define BCM2838_DMA40_BURST_LEN(x) ((((x) - 1) & 0xf) << 8)
-+#define BCM2838_DMA40_INC BIT(12)
-+#define BCM2838_DMA40_SIZE_128 (2 << 13)
-+
-+#define BCM2838_DMA40_MEMCPY_QOS \
-+ (BCM2838_DMA40_CS_QOS(0x0) | \
-+ BCM2838_DMA40_CS_PANIC_QOS(0x0) | \
-+ BCM2838_DMA40_CS_WRITE_WAIT)
-+
-+#define BCM2838_DMA40_MEMCPY_XFER_INFO \
-+ (BCM2838_DMA40_SIZE_128 | \
-+ BCM2838_DMA40_INC | \
-+ BCM2838_DMA40_BURST_LEN(16))
-+
-+static void __iomem *memcpy_chan;
-+static struct bcm2838_dma40_scb *memcpy_scb;
-+static dma_addr_t memcpy_scb_dma;
-+DEFINE_SPINLOCK(memcpy_lock);
-+
- static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
- {
- /* lite and normal channels have different max frame length */
-@@ -866,6 +916,56 @@ static void bcm2835_dma_free(struct bcm2
- DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
- }
-
-+int bcm2838_dma40_memcpy_init(struct device *dev)
-+{
-+ if (memcpy_scb)
-+ return 0;
-+
-+ memcpy_scb = dma_alloc_coherent(dev, sizeof(*memcpy_scb),
-+ &memcpy_scb_dma, GFP_KERNEL);
-+
-+ if (!memcpy_scb) {
-+ pr_err("bcm2838_dma40_memcpy_init failed!\n");
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(bcm2838_dma40_memcpy_init);
-+
-+void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size)
-+{
-+ struct bcm2838_dma40_scb *scb = memcpy_scb;
-+ unsigned long flags;
-+
-+ if (!scb) {
-+ pr_err("bcm2838_dma40_memcpy not initialised!\n");
-+ return;
-+ }
-+
-+ spin_lock_irqsave(&memcpy_lock, flags);
-+
-+ scb->ti = 0;
-+ scb->src = lower_32_bits(src);
-+ scb->srci = upper_32_bits(src) | BCM2838_DMA40_MEMCPY_XFER_INFO;
-+ scb->dst = lower_32_bits(dst);
-+ scb->dsti = upper_32_bits(dst) | BCM2838_DMA40_MEMCPY_XFER_INFO;
-+ scb->len = size;
-+ scb->next_cb = 0;
-+
-+ writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2838_DMA40_CB);
-+ writel(BCM2838_DMA40_MEMCPY_QOS + BCM2838_DMA40_CS_ACTIVE,
-+ memcpy_chan + BCM2838_DMA40_CS);
-+ /* Poll for completion */
-+ while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_CS_END))
-+ cpu_relax();
-+
-+ writel(BCM2838_DMA40_CS_END, memcpy_chan + BCM2838_DMA40_CS);
-+
-+ spin_unlock_irqrestore(&memcpy_lock, flags);
-+}
-+EXPORT_SYMBOL(bcm2838_dma40_memcpy);
-+
- static const struct of_device_id bcm2835_dma_of_match[] = {
- { .compatible = "brcm,bcm2835-dma", },
- {},
-@@ -971,6 +1071,13 @@ static int bcm2835_dma_probe(struct plat
- /* Channel 0 is used by the legacy API */
- chans_available &= ~BCM2835_DMA_BULK_MASK;
-
-+ /* We can't use channels 11-13 yet */
-+ chans_available &= ~(BIT(11) | BIT(12) | BIT(13));
-+
-+ /* Grab channel 14 for the 40-bit DMA memcpy */
-+ chans_available &= ~BIT(14);
-+ memcpy_chan = BCM2835_DMA_CHANIO(base, 14);
-+
- /* get irqs for each channel that we support */
- for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) {
- /* skip masked out channels */
---- a/drivers/pci/controller/Makefile
-+++ b/drivers/pci/controller/Makefile
-@@ -30,6 +30,10 @@ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-medi
- obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
- obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
- obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
-+ifdef CONFIG_ARM
-+obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb-bounce.o
-+endif
-+
- obj-$(CONFIG_VMD) += vmd.o
- # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
- obj-y += dwc/
---- /dev/null
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce.c
-@@ -0,0 +1,558 @@
-+/*
-+ * This code started out as a version of arch/arm/common/dmabounce.c,
-+ * modified to cope with highmem pages. Now it has been changed heavily -
-+ * it now preallocates a large block (currently 4MB) and carves it up
-+ * sequentially in ring fashion, and DMA is used to copy the data - to the
-+ * point where very little of the original remains.
-+ *
-+ * Copyright (C) 2019 Raspberry Pi (Trading) Ltd.
-+ *
-+ * Original version by Brad Parker (brad@heeltoe.com)
-+ * Re-written by Christopher Hoover <ch@murgatroid.com>
-+ * Made generic by Deepak Saxena <dsaxena@plexity.net>
-+ *
-+ * Copyright (C) 2002 Hewlett Packard Company.
-+ * Copyright (C) 2004 MontaVista Software, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/page-flags.h>
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/list.h>
-+#include <linux/scatterlist.h>
-+#include <linux/bitmap.h>
-+
-+#include <asm/cacheflush.h>
-+#include <asm/dma-iommu.h>
-+
-+#define STATS
-+
-+#ifdef STATS
-+#define DO_STATS(X) do { X ; } while (0)
-+#else
-+#define DO_STATS(X) do { } while (0)
-+#endif
-+
-+/* ************************************************** */
-+
-+struct safe_buffer {
-+ struct list_head node;
-+
-+ /* original request */
-+ size_t size;
-+ int direction;
-+
-+ struct dmabounce_pool *pool;
-+ void *safe;
-+ dma_addr_t unsafe_dma_addr;
-+ dma_addr_t safe_dma_addr;
-+};
-+
-+struct dmabounce_pool {
-+ unsigned long pages;
-+ void *virt_addr;
-+ dma_addr_t dma_addr;
-+ unsigned long *alloc_map;
-+ unsigned long alloc_pos;
-+ spinlock_t lock;
-+ struct device *dev;
-+ unsigned long num_pages;
-+#ifdef STATS
-+ size_t max_size;
-+ unsigned long num_bufs;
-+ unsigned long max_bufs;
-+ unsigned long max_pages;
-+#endif
-+};
-+
-+struct dmabounce_device_info {
-+ struct device *dev;
-+ dma_addr_t threshold;
-+ struct list_head safe_buffers;
-+ struct dmabounce_pool pool;
-+ rwlock_t lock;
-+#ifdef STATS
-+ unsigned long map_count;
-+ unsigned long unmap_count;
-+ unsigned long sync_dev_count;
-+ unsigned long sync_cpu_count;
-+ unsigned long fail_count;
-+ int attr_res;
-+#endif
-+};
-+
-+static struct dmabounce_device_info *g_dmabounce_device_info;
-+
-+extern int bcm2838_dma40_memcpy_init(struct device *dev);
-+extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size);
-+
-+#ifdef STATS
-+static ssize_t
-+bounce_show(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+ struct dmabounce_device_info *device_info = g_dmabounce_device_info;
-+ return sprintf(buf, "m:%lu/%lu s:%lu/%lu f:%lu s:%zu b:%lu/%lu a:%lu/%lu\n",
-+ device_info->map_count,
-+ device_info->unmap_count,
-+ device_info->sync_dev_count,
-+ device_info->sync_cpu_count,
-+ device_info->fail_count,
-+ device_info->pool.max_size,
-+ device_info->pool.num_bufs,
-+ device_info->pool.max_bufs,
-+ device_info->pool.num_pages * PAGE_SIZE,
-+ device_info->pool.max_pages * PAGE_SIZE);
-+}
-+
-+static DEVICE_ATTR(dmabounce_stats, 0444, bounce_show, NULL);
-+#endif
-+
-+static int bounce_create(struct dmabounce_pool *pool, struct device *dev,
-+ unsigned long buffer_size)
-+{
-+ int ret = -ENOMEM;
-+ pool->pages = (buffer_size + PAGE_SIZE - 1)/PAGE_SIZE;
-+ pool->alloc_map = bitmap_zalloc(pool->pages, GFP_KERNEL);
-+ if (!pool->alloc_map)
-+ goto err_bitmap;
-+ pool->virt_addr = dma_alloc_coherent(dev, pool->pages * PAGE_SIZE,
-+ &pool->dma_addr, GFP_KERNEL);
-+ if (!pool->virt_addr)
-+ goto err_dmabuf;
-+
-+ pool->alloc_pos = 0;
-+ spin_lock_init(&pool->lock);
-+ pool->dev = dev;
-+ pool->num_pages = 0;
-+
-+ DO_STATS(pool->max_size = 0);
-+ DO_STATS(pool->num_bufs = 0);
-+ DO_STATS(pool->max_bufs = 0);
-+ DO_STATS(pool->max_pages = 0);
-+
-+ return 0;
-+
-+err_dmabuf:
-+ bitmap_free(pool->alloc_map);
-+err_bitmap:
-+ return ret;
-+}
-+
-+static void bounce_destroy(struct dmabounce_pool *pool)
-+{
-+ dma_free_coherent(pool->dev, pool->pages * PAGE_SIZE, pool->virt_addr,
-+ pool->dma_addr);
-+
-+ bitmap_free(pool->alloc_map);
-+}
-+
-+static void *bounce_alloc(struct dmabounce_pool *pool, size_t size,
-+ dma_addr_t *dmaaddrp)
-+{
-+ unsigned long pages;
-+ unsigned long flags;
-+ unsigned long pos;
-+
-+ pages = (size + PAGE_SIZE - 1)/PAGE_SIZE;
-+
-+ DO_STATS(pool->max_size = max(size, pool->max_size));
-+
-+ spin_lock_irqsave(&pool->lock, flags);
-+ pos = bitmap_find_next_zero_area(pool->alloc_map, pool->pages,
-+ pool->alloc_pos, pages, 0);
-+ /* If not found, try from the start */
-+ if (pos >= pool->pages && pool->alloc_pos)
-+ pos = bitmap_find_next_zero_area(pool->alloc_map, pool->pages,
-+ 0, pages, 0);
-+
-+ if (pos >= pool->pages) {
-+ spin_unlock_irqrestore(&pool->lock, flags);
-+ return NULL;
-+ }
-+
-+ bitmap_set(pool->alloc_map, pos, pages);
-+ pool->alloc_pos = (pos + pages) % pool->pages;
-+ pool->num_pages += pages;
-+
-+ DO_STATS(pool->num_bufs++);
-+ DO_STATS(pool->max_bufs = max(pool->num_bufs, pool->max_bufs));
-+ DO_STATS(pool->max_pages = max(pool->num_pages, pool->max_pages));
-+
-+ spin_unlock_irqrestore(&pool->lock, flags);
-+
-+ *dmaaddrp = pool->dma_addr + pos * PAGE_SIZE;
-+
-+ return pool->virt_addr + pos * PAGE_SIZE;
-+}
-+
-+static void
-+bounce_free(struct dmabounce_pool *pool, void *buf, size_t size)
-+{
-+ unsigned long pages;
-+ unsigned long flags;
-+ unsigned long pos;
-+
-+ pages = (size + PAGE_SIZE - 1)/PAGE_SIZE;
-+ pos = (buf - pool->virt_addr)/PAGE_SIZE;
-+
-+ BUG_ON((buf - pool->virt_addr) & (PAGE_SIZE - 1));
-+
-+ spin_lock_irqsave(&pool->lock, flags);
-+ bitmap_clear(pool->alloc_map, pos, pages);
-+ pool->num_pages -= pages;
-+ if (pool->num_pages == 0)
-+ pool->alloc_pos = 0;
-+ DO_STATS(pool->num_bufs--);
-+ spin_unlock_irqrestore(&pool->lock, flags);
-+}
-+
-+/* allocate a 'safe' buffer and keep track of it */
-+static struct safe_buffer *
-+alloc_safe_buffer(struct dmabounce_device_info *device_info,
-+ dma_addr_t dma_addr, size_t size, enum dma_data_direction dir)
-+{
-+ struct safe_buffer *buf;
-+ struct dmabounce_pool *pool = &device_info->pool;
-+ struct device *dev = device_info->dev;
-+ unsigned long flags;
-+
-+ /*
-+ * Although one might expect this to be called in thread context,
-+ * using GFP_KERNEL here leads to hard-to-debug lockups. in_atomic()
-+ * was previously used to select the appropriate allocation mode,
-+ * but this is unsafe.
-+ */
-+ buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
-+ if (!buf) {
-+ dev_warn(dev, "%s: kmalloc failed\n", __func__);
-+ return NULL;
-+ }
-+
-+ buf->unsafe_dma_addr = dma_addr;
-+ buf->size = size;
-+ buf->direction = dir;
-+ buf->pool = pool;
-+
-+ buf->safe = bounce_alloc(pool, size, &buf->safe_dma_addr);
-+
-+ if (!buf->safe) {
-+ dev_warn(dev,
-+ "%s: could not alloc dma memory (size=%d)\n",
-+ __func__, size);
-+ kfree(buf);
-+ return NULL;
-+ }
-+
-+ write_lock_irqsave(&device_info->lock, flags);
-+ list_add(&buf->node, &device_info->safe_buffers);
-+ write_unlock_irqrestore(&device_info->lock, flags);
-+
-+ return buf;
-+}
-+
-+/* determine if a buffer is from our "safe" pool */
-+static struct safe_buffer *
-+find_safe_buffer(struct dmabounce_device_info *device_info,
-+ dma_addr_t safe_dma_addr)
-+{
-+ struct safe_buffer *b, *rb = NULL;
-+ unsigned long flags;
-+
-+ read_lock_irqsave(&device_info->lock, flags);
-+
-+ list_for_each_entry(b, &device_info->safe_buffers, node)
-+ if (b->safe_dma_addr <= safe_dma_addr &&
-+ b->safe_dma_addr + b->size > safe_dma_addr) {
-+ rb = b;
-+ break;
-+ }
-+
-+ read_unlock_irqrestore(&device_info->lock, flags);
-+ return rb;
-+}
-+
-+static void
-+free_safe_buffer(struct dmabounce_device_info *device_info,
-+ struct safe_buffer *buf)
-+{
-+ unsigned long flags;
-+
-+ write_lock_irqsave(&device_info->lock, flags);
-+ list_del(&buf->node);
-+ write_unlock_irqrestore(&device_info->lock, flags);
-+
-+ bounce_free(buf->pool, buf->safe, buf->size);
-+
-+ kfree(buf);
-+}
-+
-+/* ************************************************** */
-+
-+static struct safe_buffer *
-+find_safe_buffer_dev(struct device *dev, dma_addr_t dma_addr, const char *where)
-+{
-+ if (!dev || !g_dmabounce_device_info)
-+ return NULL;
-+ if (dma_mapping_error(dev, dma_addr)) {
-+ dev_err(dev, "Trying to %s invalid mapping\n", where);
-+ return NULL;
-+ }
-+ return find_safe_buffer(g_dmabounce_device_info, dma_addr);
-+}
-+
-+static dma_addr_t
-+map_single(struct device *dev, struct safe_buffer *buf, size_t size,
-+ enum dma_data_direction dir, unsigned long attrs)
-+{
-+ BUG_ON(buf->size != size);
-+ BUG_ON(buf->direction != dir);
-+
-+ dev_dbg(dev, "map: %llx->%llx\n", (u64)buf->unsafe_dma_addr,
-+ (u64)buf->safe_dma_addr);
-+
-+ if ((dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) &&
-+ !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-+ bcm2838_dma40_memcpy(buf->safe_dma_addr, buf->unsafe_dma_addr,
-+ size);
-+
-+ return buf->safe_dma_addr;
-+}
-+
-+static dma_addr_t
-+unmap_single(struct device *dev, struct safe_buffer *buf, size_t size,
-+ enum dma_data_direction dir, unsigned long attrs)
-+{
-+ BUG_ON(buf->size != size);
-+ BUG_ON(buf->direction != dir);
-+
-+ if ((dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) &&
-+ !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) {
-+ dev_dbg(dev, "unmap: %llx->%llx\n", (u64)buf->safe_dma_addr,
-+ (u64)buf->unsafe_dma_addr);
-+
-+ bcm2838_dma40_memcpy(buf->unsafe_dma_addr, buf->safe_dma_addr,
-+ size);
-+ }
-+ return buf->unsafe_dma_addr;
-+}
-+
-+/* ************************************************** */
-+
-+/*
-+ * see if a buffer address is in an 'unsafe' range. if it is
-+ * allocate a 'safe' buffer and copy the unsafe buffer into it.
-+ * substitute the safe buffer for the unsafe one.
-+ * (basically move the buffer from an unsafe area to a safe one)
-+ */
-+static dma_addr_t
-+dmabounce_map_page(struct device *dev, struct page *page, unsigned long offset,
-+ size_t size, enum dma_data_direction dir,
-+ unsigned long attrs)
-+{
-+ struct dmabounce_device_info *device_info = g_dmabounce_device_info;
-+ dma_addr_t dma_addr;
-+
-+ dma_addr = pfn_to_dma(dev, page_to_pfn(page)) + offset;
-+
-+ arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir);
-+
-+ if (device_info && (dma_addr + size) > device_info->threshold) {
-+ struct safe_buffer *buf;
-+
-+ buf = alloc_safe_buffer(device_info, dma_addr, size, dir);
-+ if (!buf) {
-+ DO_STATS(device_info->fail_count++);
-+ return DMA_MAPPING_ERROR;
-+ }
-+
-+ DO_STATS(device_info->map_count++);
-+
-+ dma_addr = map_single(dev, buf, size, dir, attrs);
-+ }
-+
-+ return dma_addr;
-+}
-+
-+/*
-+ * see if a mapped address was really a "safe" buffer and if so, copy
-+ * the data from the safe buffer back to the unsafe buffer and free up
-+ * the safe buffer. (basically return things back to the way they
-+ * should be)
-+ */
-+static void
-+dmabounce_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
-+ enum dma_data_direction dir, unsigned long attrs)
-+{
-+ struct safe_buffer *buf;
-+
-+ buf = find_safe_buffer_dev(dev, dma_addr, __func__);
-+ if (buf) {
-+ DO_STATS(g_dmabounce_device_info->unmap_count++);
-+ dma_addr = unmap_single(dev, buf, size, dir, attrs);
-+ free_safe_buffer(g_dmabounce_device_info, buf);
-+ }
-+
-+ arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir);
-+}
-+
-+/*
-+ * A version of dmabounce_map_page that assumes the mapping has already
-+ * been created - intended for streaming operation.
-+ */
-+static void
-+dmabounce_sync_for_device(struct device *dev, dma_addr_t dma_addr, size_t size,
-+ enum dma_data_direction dir)
-+{
-+ struct safe_buffer *buf;
-+
-+ arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir);
-+
-+ buf = find_safe_buffer_dev(dev, dma_addr, __func__);
-+ if (buf) {
-+ DO_STATS(g_dmabounce_device_info->sync_dev_count++);
-+ map_single(dev, buf, size, dir, 0);
-+ }
-+}
-+
-+/*
-+ * A version of dmabounce_unmap_page that doesn't destroy the mapping -
-+ * intended for streaming operation.
-+ */
-+static void
-+dmabounce_sync_for_cpu(struct device *dev, dma_addr_t dma_addr,
-+ size_t size, enum dma_data_direction dir)
-+{
-+ struct safe_buffer *buf;
-+
-+ buf = find_safe_buffer_dev(dev, dma_addr, __func__);
-+ if (buf) {
-+ DO_STATS(g_dmabounce_device_info->sync_cpu_count++);
-+ dma_addr = unmap_single(dev, buf, size, dir, 0);
-+ }
-+
-+ arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir);
-+}
-+
-+static int dmabounce_dma_supported(struct device *dev, u64 dma_mask)
-+{
-+ if (g_dmabounce_device_info)
-+ return 0;
-+
-+ return arm_dma_ops.dma_supported(dev, dma_mask);
-+}
-+
-+static const struct dma_map_ops dmabounce_ops = {
-+ .alloc = arm_dma_alloc,
-+ .free = arm_dma_free,
-+ .mmap = arm_dma_mmap,
-+ .get_sgtable = arm_dma_get_sgtable,
-+ .map_page = dmabounce_map_page,
-+ .unmap_page = dmabounce_unmap_page,
-+ .sync_single_for_cpu = dmabounce_sync_for_cpu,
-+ .sync_single_for_device = dmabounce_sync_for_device,
-+ .map_sg = arm_dma_map_sg,
-+ .unmap_sg = arm_dma_unmap_sg,
-+ .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
-+ .sync_sg_for_device = arm_dma_sync_sg_for_device,
-+ .dma_supported = dmabounce_dma_supported,
-+};
-+
-+int brcm_pcie_bounce_register_dev(struct device *dev,
-+ unsigned long buffer_size,
-+ dma_addr_t threshold)
-+{
-+ struct dmabounce_device_info *device_info;
-+ int ret;
-+
-+ /* Only support a single client */
-+ if (g_dmabounce_device_info)
-+ return -EBUSY;
-+
-+ ret = bcm2838_dma40_memcpy_init(dev);
-+ if (ret)
-+ return ret;
-+
-+ device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
-+ if (!device_info) {
-+ dev_err(dev,
-+ "Could not allocated dmabounce_device_info\n");
-+ return -ENOMEM;
-+ }
-+
-+ ret = bounce_create(&device_info->pool, dev, buffer_size);
-+ if (ret) {
-+ dev_err(dev,
-+ "dmabounce: could not allocate %ld byte DMA pool\n",
-+ buffer_size);
-+ goto err_bounce;
-+ }
-+
-+ device_info->dev = dev;
-+ device_info->threshold = threshold;
-+ INIT_LIST_HEAD(&device_info->safe_buffers);
-+ rwlock_init(&device_info->lock);
-+
-+ DO_STATS(device_info->map_count = 0);
-+ DO_STATS(device_info->unmap_count = 0);
-+ DO_STATS(device_info->sync_dev_count = 0);
-+ DO_STATS(device_info->sync_cpu_count = 0);
-+ DO_STATS(device_info->fail_count = 0);
-+ DO_STATS(device_info->attr_res =
-+ device_create_file(dev, &dev_attr_dmabounce_stats));
-+
-+ g_dmabounce_device_info = device_info;
-+ set_dma_ops(dev, &dmabounce_ops);
-+
-+ dev_info(dev, "dmabounce: registered device - %ld kB, threshold %pad\n",
-+ buffer_size / 1024, &threshold);
-+
-+ return 0;
-+
-+ err_bounce:
-+ kfree(device_info);
-+ return ret;
-+}
-+EXPORT_SYMBOL(brcm_pcie_bounce_register_dev);
-+
-+void brcm_pcie_bounce_unregister_dev(struct device *dev)
-+{
-+ struct dmabounce_device_info *device_info = g_dmabounce_device_info;
-+
-+ g_dmabounce_device_info = NULL;
-+ set_dma_ops(dev, NULL);
-+
-+ if (!device_info) {
-+ dev_warn(dev,
-+ "Never registered with dmabounce but attempting"
-+ "to unregister!\n");
-+ return;
-+ }
-+
-+ if (!list_empty(&device_info->safe_buffers)) {
-+ dev_err(dev,
-+ "Removing from dmabounce with pending buffers!\n");
-+ BUG();
-+ }
-+
-+ bounce_destroy(&device_info->pool);
-+
-+ DO_STATS(if (device_info->attr_res == 0)
-+ device_remove_file(dev, &dev_attr_dmabounce_stats));
-+
-+ kfree(device_info);
-+
-+ dev_info(dev, "dmabounce: device unregistered\n");
-+}
-+EXPORT_SYMBOL(brcm_pcie_bounce_unregister_dev);
-+
-+MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.org>");
-+MODULE_DESCRIPTION("Dedicate DMA bounce support for pcie-brcmstb");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce.h
-@@ -0,0 +1,32 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2019 Raspberry Pi (Trading) Ltd.
-+ */
-+
-+#ifndef _PCIE_BRCMSTB_BOUNCE_H
-+#define _PCIE_BRCMSTB_BOUNCE_H
-+
-+#ifdef CONFIG_ARM
-+
-+int brcm_pcie_bounce_register_dev(struct device *dev, unsigned long buffer_size,
-+ dma_addr_t threshold);
-+
-+int brcm_pcie_bounce_unregister_dev(struct device *dev);
-+
-+#else
-+
-+static inline int brcm_pcie_bounce_register_dev(struct device *dev,
-+ unsigned long buffer_size,
-+ dma_addr_t threshold)
-+{
-+ return 0;
-+}
-+
-+static inline int brcm_pcie_bounce_unregister_dev(struct device *dev)
-+{
-+ return 0;
-+}
-+
-+#endif
-+
-+#endif /* _PCIE_BRCMSTB_BOUNCE_H */
---- a/drivers/pci/controller/pcie-brcmstb.c
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -29,6 +29,7 @@
- #include <linux/string.h>
- #include <linux/types.h>
- #include "../pci.h"
-+#include "pcie-brcmstb-bounce.h"
-
- /* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
- #define BRCM_PCIE_CAP_REGS 0x00ac
-@@ -53,6 +54,7 @@
- #define PCIE_MISC_MSI_BAR_CONFIG_LO 0x4044
- #define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048
- #define PCIE_MISC_MSI_DATA_CONFIG 0x404c
-+#define PCIE_MISC_EOI_CTRL 0x4060
- #define PCIE_MISC_PCIE_CTRL 0x4064
- #define PCIE_MISC_PCIE_STATUS 0x4068
- #define PCIE_MISC_REVISION 0x406c
-@@ -260,12 +262,14 @@ struct brcm_pcie {
- unsigned int rev;
- const int *reg_offsets;
- const int *reg_field_info;
-+ u32 max_burst_size;
- enum pcie_type type;
- };
-
- struct pcie_cfg_data {
- const int *reg_field_info;
- const int *offsets;
-+ const u32 max_burst_size;
- const enum pcie_type type;
- };
-
-@@ -288,24 +292,27 @@ static const int pcie_offset_bcm7425[] =
- static const struct pcie_cfg_data bcm7425_cfg = {
- .reg_field_info = pcie_reg_field_info,
- .offsets = pcie_offset_bcm7425,
-+ .max_burst_size = BURST_SIZE_256,
- .type = BCM7425,
- };
-
- static const int pcie_offsets[] = {
- [RGR1_SW_INIT_1] = 0x9210,
- [EXT_CFG_INDEX] = 0x9000,
-- [EXT_CFG_DATA] = 0x9004,
-+ [EXT_CFG_DATA] = 0x8000,
- };
-
- static const struct pcie_cfg_data bcm7435_cfg = {
- .reg_field_info = pcie_reg_field_info,
- .offsets = pcie_offsets,
-+ .max_burst_size = BURST_SIZE_256,
- .type = BCM7435,
- };
-
- static const struct pcie_cfg_data generic_cfg = {
- .reg_field_info = pcie_reg_field_info,
- .offsets = pcie_offsets,
-+ .max_burst_size = BURST_SIZE_128, // before BURST_SIZE_512
- .type = GENERIC,
- };
-
-@@ -318,6 +325,7 @@ static const int pcie_offset_bcm7278[] =
- static const struct pcie_cfg_data bcm7278_cfg = {
- .reg_field_info = pcie_reg_field_info_bcm7278,
- .offsets = pcie_offset_bcm7278,
-+ .max_burst_size = BURST_SIZE_512,
- .type = BCM7278,
- };
-
-@@ -360,7 +368,6 @@ static struct pci_ops brcm_pcie_ops = {
- (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT)))
-
- static const struct dma_map_ops *arch_dma_ops;
--static const struct dma_map_ops *brcm_dma_ops_ptr;
- static struct of_pci_range *dma_ranges;
- static int num_dma_ranges;
-
-@@ -369,6 +376,16 @@ static int num_memc;
- static int num_pcie;
- static DEFINE_MUTEX(brcm_pcie_lock);
-
-+static unsigned int bounce_buffer = 32*1024*1024;
-+module_param(bounce_buffer, uint, 0644);
-+MODULE_PARM_DESC(bounce_buffer, "Size of bounce buffer");
-+
-+static unsigned int bounce_threshold = 0xc0000000;
-+module_param(bounce_threshold, uint, 0644);
-+MODULE_PARM_DESC(bounce_threshold, "Bounce threshold");
-+
-+static struct brcm_pcie *g_pcie;
-+
- static dma_addr_t brcm_to_pci(dma_addr_t addr)
- {
- struct of_pci_range *p;
-@@ -457,12 +474,10 @@ static int brcm_map_sg(struct device *de
- struct scatterlist *sg;
-
- for_each_sg(sgl, sg, nents, i) {
--#ifdef CONFIG_NEED_SG_DMA_LENGTH
-- sg->dma_length = sg->length;
--#endif
-+ sg_dma_len(sg) = sg->length;
- sg->dma_address =
-- brcm_dma_ops_ptr->map_page(dev, sg_page(sg), sg->offset,
-- sg->length, dir, attrs);
-+ brcm_map_page(dev, sg_page(sg), sg->offset,
-+ sg->length, dir, attrs);
- if (dma_mapping_error(dev, sg->dma_address))
- goto bad_mapping;
- }
-@@ -470,8 +485,8 @@ static int brcm_map_sg(struct device *de
-
- bad_mapping:
- for_each_sg(sgl, sg, i, j)
-- brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg),
-- sg_dma_len(sg), dir, attrs);
-+ brcm_unmap_page(dev, sg_dma_address(sg),
-+ sg_dma_len(sg), dir, attrs);
- return 0;
- }
-
-@@ -484,8 +499,8 @@ static void brcm_unmap_sg(struct device
- struct scatterlist *sg;
-
- for_each_sg(sgl, sg, nents, i)
-- brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg),
-- sg_dma_len(sg), dir, attrs);
-+ brcm_unmap_page(dev, sg_dma_address(sg),
-+ sg_dma_len(sg), dir, attrs);
- }
-
- static void brcm_sync_single_for_cpu(struct device *dev,
-@@ -531,8 +546,8 @@ void brcm_sync_sg_for_cpu(struct device
- int i;
-
- for_each_sg(sgl, sg, nents, i)
-- brcm_dma_ops_ptr->sync_single_for_cpu(dev, sg_dma_address(sg),
-- sg->length, dir);
-+ brcm_sync_single_for_cpu(dev, sg_dma_address(sg),
-+ sg->length, dir);
- }
-
- void brcm_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
-@@ -542,14 +557,9 @@ void brcm_sync_sg_for_device(struct devi
- int i;
-
- for_each_sg(sgl, sg, nents, i)
-- brcm_dma_ops_ptr->sync_single_for_device(dev,
-- sg_dma_address(sg),
-- sg->length, dir);
--}
--
--static int brcm_mapping_error(struct device *dev, dma_addr_t dma_addr)
--{
-- return arch_dma_ops->mapping_error(dev, dma_addr);
-+ brcm_sync_single_for_device(dev,
-+ sg_dma_address(sg),
-+ sg->length, dir);
- }
-
- static int brcm_dma_supported(struct device *dev, u64 mask)
-@@ -572,7 +582,7 @@ static int brcm_dma_supported(struct dev
- }
-
- #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
--u64 brcm_get_required_mask)(struct device *dev)
-+u64 brcm_get_required_mask(struct device *dev)
- {
- return arch_dma_ops->get_required_mask(dev);
- }
-@@ -593,7 +603,6 @@ static const struct dma_map_ops brcm_dma
- .sync_single_for_device = brcm_sync_single_for_device,
- .sync_sg_for_cpu = brcm_sync_sg_for_cpu,
- .sync_sg_for_device = brcm_sync_sg_for_device,
-- .mapping_error = brcm_mapping_error,
- .dma_supported = brcm_dma_supported,
- #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
- .get_required_mask = brcm_get_required_mask,
-@@ -633,17 +642,47 @@ static void brcm_set_dma_ops(struct devi
- set_dma_ops(dev, &brcm_dma_ops);
- }
-
-+static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie,
-+ unsigned int val);
- static int brcmstb_platform_notifier(struct notifier_block *nb,
- unsigned long event, void *__dev)
- {
-+ extern unsigned long max_pfn;
- struct device *dev = __dev;
-+ const char *rc_name = "0000:00:00.0";
-
-- brcm_dma_ops_ptr = &brcm_dma_ops;
-- if (event != BUS_NOTIFY_ADD_DEVICE)
-- return NOTIFY_DONE;
-+ switch (event) {
-+ case BUS_NOTIFY_ADD_DEVICE:
-+ if (max_pfn > (bounce_threshold/PAGE_SIZE) &&
-+ strcmp(dev->kobj.name, rc_name)) {
-+ int ret;
-+
-+ ret = brcm_pcie_bounce_register_dev(dev, bounce_buffer,
-+ (dma_addr_t)bounce_threshold);
-+ if (ret) {
-+ dev_err(dev,
-+ "brcm_pcie_bounce_register_dev() failed: %d\n",
-+ ret);
-+ return ret;
-+ }
-+ }
-+ brcm_set_dma_ops(dev);
-+ return NOTIFY_OK;
-
-- brcm_set_dma_ops(dev);
-- return NOTIFY_OK;
-+ case BUS_NOTIFY_DEL_DEVICE:
-+ if (!strcmp(dev->kobj.name, rc_name) && g_pcie) {
-+ /* Force a bus reset */
-+ brcm_pcie_perst_set(g_pcie, 1);
-+ msleep(100);
-+ brcm_pcie_perst_set(g_pcie, 0);
-+ } else if (max_pfn > (bounce_threshold/PAGE_SIZE)) {
-+ brcm_pcie_bounce_unregister_dev(dev);
-+ }
-+ return NOTIFY_OK;
-+
-+ default:
-+ return NOTIFY_DONE;
-+ }
- }
-
- static struct notifier_block brcmstb_platform_nb = {
-@@ -914,6 +953,7 @@ static void brcm_pcie_msi_isr(struct irq
- }
- }
- chained_irq_exit(chip, desc);
-+ bcm_writel(1, msi->base + PCIE_MISC_EOI_CTRL);
- }
-
- static void brcm_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
-@@ -930,7 +970,8 @@ static void brcm_compose_msi_msg(struct
- static int brcm_msi_set_affinity(struct irq_data *irq_data,
- const struct cpumask *mask, bool force)
- {
-- return -EINVAL;
-+ struct brcm_msi *msi = irq_data_get_irq_chip_data(irq_data);
-+ return __irq_set_affinity(msi->irq, mask, force);
- }
-
- static struct irq_chip brcm_msi_bottom_irq_chip = {
-@@ -1168,9 +1209,9 @@ static void __iomem *brcm_pcie_map_conf(
- return PCI_SLOT(devfn) ? NULL : base + where;
-
- /* For devices, write to the config space index register */
-- idx = cfg_index(bus->number, devfn, where);
-+ idx = cfg_index(bus->number, devfn, 0);
- bcm_writel(idx, pcie->base + IDX_ADDR(pcie));
-- return base + DATA_ADDR(pcie) + (where & 0x3);
-+ return base + DATA_ADDR(pcie) + where;
- }
-
- static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie,
-@@ -1238,20 +1279,6 @@ static int brcm_pcie_parse_map_dma_range
- num_dma_ranges++;
- }
-
-- for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) {
-- u64 size = brcmstb_memory_memc_size(i);
--
-- if (size == (u64)-1) {
-- dev_err(pcie->dev, "cannot get memc%d size", i);
-- return -EINVAL;
-- } else if (size) {
-- scb_size[i] = roundup_pow_of_two_64(size);
-- num_memc++;
-- } else {
-- break;
-- }
-- }
--
- return 0;
- }
-
-@@ -1275,26 +1302,25 @@ static int brcm_pcie_add_controller(stru
- if (ret)
- goto done;
-
-- /* Determine num_memc and their sizes */
-- for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) {
-- u64 size = brcmstb_memory_memc_size(i);
--
-- if (size == (u64)-1) {
-- dev_err(dev, "cannot get memc%d size\n", i);
-- ret = -EINVAL;
-- goto done;
-- } else if (size) {
-- scb_size[i] = roundup_pow_of_two_64(size);
-- num_memc++;
-- } else {
-- break;
-+ if (!num_dma_ranges) {
-+ /* Determine num_memc and their sizes by other means */
-+ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) {
-+ u64 size = brcmstb_memory_memc_size(i);
-+
-+ if (size == (u64)-1) {
-+ dev_err(dev, "cannot get memc%d size\n", i);
-+ ret = -EINVAL;
-+ goto done;
-+ } else if (size) {
-+ scb_size[i] = roundup_pow_of_two_64(size);
-+ } else {
-+ break;
-+ }
- }
-- }
-- if (!ret && num_memc == 0) {
-- ret = -EINVAL;
-- goto done;
-+ num_memc = i;
- }
-
-+ g_pcie = pcie;
- num_pcie++;
- done:
- mutex_unlock(&brcm_pcie_lock);
-@@ -1307,6 +1333,7 @@ static void brcm_pcie_remove_controller(
- if (--num_pcie > 0)
- goto out;
-
-+ g_pcie = NULL;
- if (brcm_unregister_notifier())
- dev_err(pcie->dev, "failed to unregister pci bus notifier\n");
- kfree(dma_ranges);
-@@ -1367,7 +1394,7 @@ static int brcm_pcie_setup(struct brcm_p
- void __iomem *base = pcie->base;
- unsigned int scb_size_val;
- u64 rc_bar2_offset, rc_bar2_size, total_mem_size = 0;
-- u32 tmp, burst;
-+ u32 tmp;
- int i, j, ret, limit;
- u16 nlw, cls, lnksta;
- bool ssc_good = false;
-@@ -1400,20 +1427,15 @@ static int brcm_pcie_setup(struct brcm_p
- /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
- tmp = INSERT_FIELD(0, PCIE_MISC_MISC_CTRL, SCB_ACCESS_EN, 1);
- tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, CFG_READ_UR_MODE, 1);
-- burst = (pcie->type == GENERIC || pcie->type == BCM7278)
-- ? BURST_SIZE_512 : BURST_SIZE_256;
-- tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE, burst);
-+ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE,
-+ pcie->max_burst_size);
- bcm_writel(tmp, base + PCIE_MISC_MISC_CTRL);
-
- /*
- * Set up inbound memory view for the EP (called RC_BAR2,
- * not to be confused with the BARs that are advertised by
- * the EP).
-- */
-- for (i = 0; i < num_memc; i++)
-- total_mem_size += scb_size[i];
--
-- /*
-+ *
- * The PCIe host controller by design must set the inbound
- * viewport to be a contiguous arrangement of all of the
- * system's memory. In addition, its size mut be a power of
-@@ -1429,55 +1451,49 @@ static int brcm_pcie_setup(struct brcm_p
- * the controller will know to send outbound memory downstream
- * and everything else upstream.
- */
-- rc_bar2_size = roundup_pow_of_two_64(total_mem_size);
-
-- if (dma_ranges) {
-+ if (num_dma_ranges) {
- /*
-- * The best-case scenario is to place the inbound
-- * region in the first 4GB of pcie-space, as some
-- * legacy devices can only address 32bits.
-- * We would also like to put the MSI under 4GB
-- * as well, since some devices require a 32bit
-- * MSI target address.
-+ * Use the base address and size(s) provided in the dma-ranges
-+ * property.
- */
-- if (total_mem_size <= 0xc0000000ULL &&
-- rc_bar2_size <= 0x100000000ULL) {
-- rc_bar2_offset = 0;
-- /* If the viewport is less then 4GB we can fit
-- * the MSI target address under 4GB. Otherwise
-- * put it right below 64GB.
-- */
-- msi_target_addr =
-- (rc_bar2_size == 0x100000000ULL)
-- ? BRCM_MSI_TARGET_ADDR_GT_4GB
-- : BRCM_MSI_TARGET_ADDR_LT_4GB;
-- } else {
-- /*
-- * The system memory is 4GB or larger so we
-- * cannot start the inbound region at location
-- * 0 (since we have to allow some space for
-- * outbound memory @ 3GB). So instead we
-- * start it at the 1x multiple of its size
-- */
-- rc_bar2_offset = rc_bar2_size;
--
-- /* Since we are starting the viewport at 4GB or
-- * higher, put the MSI target address below 4GB
-- */
-- msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB;
-- }
-- } else {
-+ for (i = 0; i < num_dma_ranges; i++)
-+ scb_size[i] = roundup_pow_of_two_64(dma_ranges[i].size);
-+
-+ num_memc = num_dma_ranges;
-+ rc_bar2_offset = dma_ranges[0].pci_addr;
-+ } else if (num_memc) {
- /*
- * Set simple configuration based on memory sizes
-- * only. We always start the viewport at address 0,
-- * and set the MSI target address accordingly.
-+ * only. We always start the viewport at address 0.
- */
- rc_bar2_offset = 0;
-+ } else {
-+ return -EINVAL;
-+ }
-+
-+ for (i = 0; i < num_memc; i++)
-+ total_mem_size += scb_size[i];
-+
-+ rc_bar2_size = roundup_pow_of_two_64(total_mem_size);
-
-- msi_target_addr = (rc_bar2_size >= 0x100000000ULL)
-- ? BRCM_MSI_TARGET_ADDR_GT_4GB
-- : BRCM_MSI_TARGET_ADDR_LT_4GB;
-+ /* Verify the alignment is correct */
-+ if (rc_bar2_offset & (rc_bar2_size - 1)) {
-+ dev_err(dev, "inbound window is misaligned\n");
-+ return -EINVAL;
- }
-+
-+ /*
-+ * Position the MSI target low if possible.
-+ *
-+ * TO DO: Consider outbound window when choosing MSI target and
-+ * verifying configuration.
-+ */
-+ msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB;
-+ if (rc_bar2_offset <= msi_target_addr &&
-+ rc_bar2_offset + rc_bar2_size > msi_target_addr)
-+ msi_target_addr = BRCM_MSI_TARGET_ADDR_GT_4GB;
-+
- pcie->msi_target_addr = msi_target_addr;
-
- tmp = lower_32_bits(rc_bar2_offset);
-@@ -1713,6 +1729,7 @@ static int brcm_pcie_probe(struct platfo
- data = of_id->data;
- pcie->reg_offsets = data->offsets;
- pcie->reg_field_info = data->reg_field_info;
-+ pcie->max_burst_size = data->max_burst_size;
- pcie->type = data->type;
- pcie->dn = dn;
- pcie->dev = &pdev->dev;
-@@ -1732,7 +1749,7 @@ static int brcm_pcie_probe(struct platfo
-
- pcie->clk = of_clk_get_by_name(dn, "sw_pcie");
- if (IS_ERR(pcie->clk)) {
-- dev_err(&pdev->dev, "could not get clock\n");
-+ dev_warn(&pdev->dev, "could not get clock\n");
- pcie->clk = NULL;
- }
- pcie->base = base;
-@@ -1755,7 +1772,8 @@ static int brcm_pcie_probe(struct platfo
-
- ret = clk_prepare_enable(pcie->clk);
- if (ret) {
-- dev_err(&pdev->dev, "could not enable clock\n");
-+ if (ret != -EPROBE_DEFER)
-+ dev_err(&pdev->dev, "could not enable clock\n");
- return ret;
- }
-
-@@ -1818,7 +1836,6 @@ static struct platform_driver brcm_pcie_
- .remove = brcm_pcie_remove,
- .driver = {
- .name = "brcm-pcie",
-- .owner = THIS_MODULE,
- .of_match_table = brcm_pcie_match,
- .pm = &brcm_pcie_pm_ops,
- },
---- a/drivers/soc/bcm/brcmstb/Makefile
-+++ b/drivers/soc/bcm/brcmstb/Makefile
-@@ -1,3 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-y += common.o biuctrl.o
-+obj-y += common.o biuctrl.o memory.o
- obj-$(CONFIG_BRCMSTB_PM) += pm/
---- /dev/null
-+++ b/drivers/soc/bcm/brcmstb/memory.c
-@@ -0,0 +1,158 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/* Copyright © 2015-2017 Broadcom */
-+
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/libfdt.h>
-+#include <linux/of_address.h>
-+#include <linux/of_fdt.h>
-+#include <linux/sizes.h>
-+#include <soc/brcmstb/memory_api.h>
-+
-+/* Macro to help extract property data */
-+#define DT_PROP_DATA_TO_U32(b, offs) (fdt32_to_cpu(*(u32 *)(b + offs)))
-+
-+/* Constants used when retrieving memc info */
-+#define NUM_BUS_RANGES 10
-+#define BUS_RANGE_ULIMIT_SHIFT 4
-+#define BUS_RANGE_LLIMIT_SHIFT 4
-+#define BUS_RANGE_PA_SHIFT 12
-+
-+enum {
-+ BUSNUM_MCP0 = 0x4,
-+ BUSNUM_MCP1 = 0x5,
-+ BUSNUM_MCP2 = 0x6,
-+};
-+
-+/*
-+ * If the DT nodes are handy, determine which MEMC holds the specified
-+ * physical address.
-+ */
-+#ifdef CONFIG_ARCH_BRCMSTB
-+int __brcmstb_memory_phys_addr_to_memc(phys_addr_t pa, void __iomem *base)
-+{
-+ int memc = -1;
-+ int i;
-+
-+ for (i = 0; i < NUM_BUS_RANGES; i++, base += 8) {
-+ const u64 ulimit_raw = readl(base);
-+ const u64 llimit_raw = readl(base + 4);
-+ const u64 ulimit =
-+ ((ulimit_raw >> BUS_RANGE_ULIMIT_SHIFT)
-+ << BUS_RANGE_PA_SHIFT) | 0xfff;
-+ const u64 llimit = (llimit_raw >> BUS_RANGE_LLIMIT_SHIFT)
-+ << BUS_RANGE_PA_SHIFT;
-+ const u32 busnum = (u32)(ulimit_raw & 0xf);
-+
-+ if (pa >= llimit && pa <= ulimit) {
-+ if (busnum >= BUSNUM_MCP0 && busnum <= BUSNUM_MCP2) {
-+ memc = busnum - BUSNUM_MCP0;
-+ break;
-+ }
-+ }
-+ }
-+
-+ return memc;
-+}
-+
-+int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa)
-+{
-+ int memc = -1;
-+ struct device_node *np;
-+ void __iomem *cpubiuctrl;
-+
-+ np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
-+ if (!np)
-+ return memc;
-+
-+ cpubiuctrl = of_iomap(np, 0);
-+ if (!cpubiuctrl)
-+ goto cleanup;
-+
-+ memc = __brcmstb_memory_phys_addr_to_memc(pa, cpubiuctrl);
-+ iounmap(cpubiuctrl);
-+
-+cleanup:
-+ of_node_put(np);
-+
-+ return memc;
-+}
-+
-+#elif defined(CONFIG_MIPS)
-+int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa)
-+{
-+ /* The logic here is fairly simple and hardcoded: if pa <= 0x5000_0000,
-+ * then this is MEMC0, else MEMC1.
-+ *
-+ * For systems with 2GB on MEMC0, MEMC1 starts at 9000_0000, with 1GB
-+ * on MEMC0, MEMC1 starts at 6000_0000.
-+ */
-+ if (pa >= 0x50000000ULL)
-+ return 1;
-+ else
-+ return 0;
-+}
-+#endif
-+
-+u64 brcmstb_memory_memc_size(int memc)
-+{
-+ const void *fdt = initial_boot_params;
-+ const int mem_offset = fdt_path_offset(fdt, "/memory");
-+ int addr_cells = 1, size_cells = 1;
-+ const struct fdt_property *prop;
-+ int proplen, cellslen;
-+ u64 memc_size = 0;
-+ int i;
-+
-+ /* Get root size and address cells if specified */
-+ prop = fdt_get_property(fdt, 0, "#size-cells", &proplen);
-+ if (prop)
-+ size_cells = DT_PROP_DATA_TO_U32(prop->data, 0);
-+
-+ prop = fdt_get_property(fdt, 0, "#address-cells", &proplen);
-+ if (prop)
-+ addr_cells = DT_PROP_DATA_TO_U32(prop->data, 0);
-+
-+ if (mem_offset < 0)
-+ return -1;
-+
-+ prop = fdt_get_property(fdt, mem_offset, "reg", &proplen);
-+ cellslen = (int)sizeof(u32) * (addr_cells + size_cells);
-+ if ((proplen % cellslen) != 0)
-+ return -1;
-+
-+ for (i = 0; i < proplen / cellslen; ++i) {
-+ u64 addr = 0;
-+ u64 size = 0;
-+ int memc_idx;
-+ int j;
-+
-+ for (j = 0; j < addr_cells; ++j) {
-+ int offset = (cellslen * i) + (sizeof(u32) * j);
-+
-+ addr |= (u64)DT_PROP_DATA_TO_U32(prop->data, offset) <<
-+ ((addr_cells - j - 1) * 32);
-+ }
-+ for (j = 0; j < size_cells; ++j) {
-+ int offset = (cellslen * i) +
-+ (sizeof(u32) * (j + addr_cells));
-+
-+ size |= (u64)DT_PROP_DATA_TO_U32(prop->data, offset) <<
-+ ((size_cells - j - 1) * 32);
-+ }
-+
-+ if ((phys_addr_t)addr != addr) {
-+ pr_err("phys_addr_t is smaller than provided address 0x%llx!\n",
-+ addr);
-+ return -1;
-+ }
-+
-+ memc_idx = brcmstb_memory_phys_addr_to_memc((phys_addr_t)addr);
-+ if (memc_idx == memc)
-+ memc_size += size;
-+ }
-+
-+ return memc_size;
-+}
-+EXPORT_SYMBOL_GPL(brcmstb_memory_memc_size);
-+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0213-vchiq-Add-36-bit-address-support.patch b/target/linux/bcm27xx/patches-5.4/950-0209-vchiq-Add-36-bit-address-support.patch
index ca2a40488a..ca2a40488a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0213-vchiq-Add-36-bit-address-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0209-vchiq-Add-36-bit-address-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0214-bcm2835-pcm.c-Support-multichannel-audio.patch b/target/linux/bcm27xx/patches-5.4/950-0210-bcm2835-pcm.c-Support-multichannel-audio.patch
index 133d346afb..133d346afb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0214-bcm2835-pcm.c-Support-multichannel-audio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0210-bcm2835-pcm.c-Support-multichannel-audio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0215-bcmgenet-constrain-max-DMA-burst-length.patch b/target/linux/bcm27xx/patches-5.4/950-0211-bcmgenet-constrain-max-DMA-burst-length.patch
index 7f065eb630..7f065eb630 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0215-bcmgenet-constrain-max-DMA-burst-length.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0211-bcmgenet-constrain-max-DMA-burst-length.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0216-bcmgenet-Better-coalescing-parameter-defaults.patch b/target/linux/bcm27xx/patches-5.4/950-0212-bcmgenet-Better-coalescing-parameter-defaults.patch
index f2e829aec3..f2e829aec3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0216-bcmgenet-Better-coalescing-parameter-defaults.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0212-bcmgenet-Better-coalescing-parameter-defaults.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0217-net-genet-enable-link-energy-detect-powerdown-for-ex.patch b/target/linux/bcm27xx/patches-5.4/950-0213-net-genet-enable-link-energy-detect-powerdown-for-ex.patch
index ab43dfdfe5..ab43dfdfe5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0217-net-genet-enable-link-energy-detect-powerdown-for-ex.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0213-net-genet-enable-link-energy-detect-powerdown-for-ex.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0218-usb-xhci-Disable-the-XHCI-5-second-timeout.patch b/target/linux/bcm27xx/patches-5.4/950-0214-usb-xhci-Disable-the-XHCI-5-second-timeout.patch
index 2f5e08b7a2..2f5e08b7a2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0218-usb-xhci-Disable-the-XHCI-5-second-timeout.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0214-usb-xhci-Disable-the-XHCI-5-second-timeout.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0219-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch b/target/linux/bcm27xx/patches-5.4/950-0215-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch
index 1728ed70d3..1728ed70d3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0219-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0215-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0220-spi-bcm2835-enable-shared-interrupt-support.patch b/target/linux/bcm27xx/patches-5.4/950-0216-spi-bcm2835-enable-shared-interrupt-support.patch
index 5e2a367750..5e2a367750 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0220-spi-bcm2835-enable-shared-interrupt-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0216-spi-bcm2835-enable-shared-interrupt-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0221-clk-bcm2835-Don-t-wait-for-pllh-lock.patch b/target/linux/bcm27xx/patches-5.4/950-0217-clk-bcm2835-Don-t-wait-for-pllh-lock.patch
index d60b6f3d85..d60b6f3d85 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0221-clk-bcm2835-Don-t-wait-for-pllh-lock.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0217-clk-bcm2835-Don-t-wait-for-pllh-lock.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0222-soc-bcm-bcm2835-pm-Add-support-for-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0218-soc-bcm-bcm2835-pm-Add-support-for-2711.patch
index 61bf911f28..61bf911f28 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0222-soc-bcm-bcm2835-pm-Add-support-for-2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0218-soc-bcm-bcm2835-pm-Add-support-for-2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0223-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch b/target/linux/bcm27xx/patches-5.4/950-0219-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch
index b5e5c039c3..4e3805d9a7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0223-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0219-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch
@@ -28,17 +28,3 @@ Subject: [PATCH] config: Permit LPAE and PCIE_BRCMSTB on BCM2835
help
This enables support for the Broadcom BCM2835 and BCM2836 SoCs.
This SoC is used in the Raspberry Pi and Roku 2 devices.
---- a/drivers/pci/controller/Kconfig
-+++ b/drivers/pci/controller/Kconfig
-@@ -290,9 +290,9 @@ config PCI_HYPERV_INTERFACE
-
- config PCIE_BRCMSTB
- tristate "Broadcom Brcmstb PCIe platform host driver"
-- depends on ARCH_BRCMSTB || BMIPS_GENERIC
-+ depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM2835
- depends on OF
-- depends on SOC_BRCMSTB
-+ depends on SOC_BRCMSTB || ARCH_BCM2835
- default ARCH_BRCMSTB || BMIPS_GENERIC
- help
- Adds support for Broadcom Settop Box PCIe host controller.
diff --git a/target/linux/bcm27xx/patches-5.4/950-0224-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch b/target/linux/bcm27xx/patches-5.4/950-0220-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch
index 056dc69ae7..056dc69ae7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0224-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0220-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0225-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch b/target/linux/bcm27xx/patches-5.4/950-0221-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch
index 59d030c1eb..59d030c1eb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0225-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0221-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0226-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch b/target/linux/bcm27xx/patches-5.4/950-0222-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch
index fe1d069c20..fe1d069c20 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0226-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0222-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0227-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/bcm27xx/patches-5.4/950-0223-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
index cabf592121..cabf592121 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0227-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0223-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0228-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch b/target/linux/bcm27xx/patches-5.4/950-0224-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch
index 5d12037150..5d12037150 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0228-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0224-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0229-arm-bcm2835-Add-bcm2838-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0225-arm-bcm2835-Add-bcm2838-compatible-string.patch
index f11ccb44e9..f11ccb44e9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0229-arm-bcm2835-Add-bcm2838-compatible-string.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0225-arm-bcm2835-Add-bcm2838-compatible-string.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch b/target/linux/bcm27xx/patches-5.4/950-0226-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch
index f95c8778a6..f95c8778a6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0226-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0231-drm-v3d-Add-support-for-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0227-drm-v3d-Add-support-for-2711.patch
index 328c303083..328c303083 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0231-drm-v3d-Add-support-for-2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0227-drm-v3d-Add-support-for-2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0232-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch b/target/linux/bcm27xx/patches-5.4/950-0228-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch
index 1581cc0070..1581cc0070 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0232-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0228-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0233-drm-v3d-Hook-up-the-runtime-PM-ops.patch b/target/linux/bcm27xx/patches-5.4/950-0229-drm-v3d-Hook-up-the-runtime-PM-ops.patch
index 438922177d..438922177d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0233-drm-v3d-Hook-up-the-runtime-PM-ops.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0229-drm-v3d-Hook-up-the-runtime-PM-ops.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch b/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch
index ccd6de065c..ccd6de065c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch
index cb5b6d5aa7..cb5b6d5aa7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch b/target/linux/bcm27xx/patches-5.4/950-0232-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch
index 3b03c98088..3b03c98088 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0232-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0237-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch b/target/linux/bcm27xx/patches-5.4/950-0233-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch
index fc84f535de..fc84f535de 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0237-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0233-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch
index 6878a0c26a..6878a0c26a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Increase-max-screen-size-to-4096x4096.patch b/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Increase-max-screen-size-to-4096x4096.patch
index 92d3d35ead..92d3d35ead 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Increase-max-screen-size-to-4096x4096.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Increase-max-screen-size-to-4096x4096.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch
index cbba43bf2e..cbba43bf2e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Fix-build-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Fix-build-warning.patch
index 63246286a2..63246286a2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Fix-build-warning.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Fix-build-warning.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Select-display-to-blank-during-initialisatio.patch b/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Select-display-to-blank-during-initialisatio.patch
index 693292d04f..693292d04f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Select-display-to-blank-during-initialisatio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Select-display-to-blank-during-initialisatio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Remove-now-unused-structure.patch b/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Remove-now-unused-structure.patch
index e6e4950e9a..e6e4950e9a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Remove-now-unused-structure.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Remove-now-unused-structure.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch b/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch
index 6e463e70eb..6e463e70eb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Set-the-display-number-when-querying-the-dis.patch b/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Set-the-display-number-when-querying-the-dis.patch
index 7b8efc7e73..7b8efc7e73 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Set-the-display-number-when-querying-the-dis.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Set-the-display-number-when-querying-the-dis.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch b/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch
index 635340c082..635340c082 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch b/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch
index 43a2ffab16..43a2ffab16 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch b/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch
index 6740f7fc6e..6740f7fc6e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch b/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch
index 05f50cd913..05f50cd913 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch b/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch
index 10a655ade1..10a655ade1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Increase-max_width-height-to-7680.patch b/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-Increase-max_width-height-to-7680.patch
index 69d1470663..69d1470663 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Increase-max_width-height-to-7680.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-Increase-max_width-height-to-7680.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch
index 92400560ac..92400560ac 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch b/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch
index 2a365798f5..2a365798f5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Log-flags-in-fkms-mode-set.patch b/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Log-flags-in-fkms-mode-set.patch
index caca1c9f82..caca1c9f82 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Log-flags-in-fkms-mode-set.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Log-flags-in-fkms-mode-set.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-firmware-kms-Fix-DSI-display-support.patch b/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-firmware-kms-Fix-DSI-display-support.patch
index 450c156602..450c156602 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-firmware-kms-Fix-DSI-display-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-firmware-kms-Fix-DSI-display-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch b/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch
index a917540869..a917540869 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-handle-the-case-where-there-are-no-available.patch b/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-handle-the-case-where-there-are-no-available.patch
index 72b205c2e4..72b205c2e4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-handle-the-case-where-there-are-no-available.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-handle-the-case-where-there-are-no-available.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Support-the-VEC-in-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Support-the-VEC-in-FKMS.patch
index 87aeacd616..87aeacd616 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Support-the-VEC-in-FKMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Support-the-VEC-in-FKMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch b/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch
index 8008619639..8008619639 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Correct-SAND-support-for-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Correct-SAND-support-for-FKMS.patch
index dcf57e07e7..dcf57e07e7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Correct-SAND-support-for-FKMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Correct-SAND-support-for-FKMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch b/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch
index 186a7c891f..186a7c891f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch b/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch
index 63931bf611..63931bf611 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch
index 5d6171ce40..5d6171ce40 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch b/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch
index 06e073b2ea..06e073b2ea 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4-Add-status-of-which-display-is-updated-throu.patch b/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
index 8dd4caad1c..8dd4caad1c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0266-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch b/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch
index 38b12e049f..38b12e049f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0266-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0267-drm-vc4-Limit-fkms-to-modes-85Hz.patch b/target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Limit-fkms-to-modes-85Hz.patch
index 128ac5d54b..128ac5d54b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0267-drm-vc4-Limit-fkms-to-modes-85Hz.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Limit-fkms-to-modes-85Hz.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0268-drm-vc4-Ignore-HVS-unless-initialised.patch b/target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4-Ignore-HVS-unless-initialised.patch
index f17f4be37d..f17f4be37d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0268-drm-vc4-Ignore-HVS-unless-initialised.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4-Ignore-HVS-unless-initialised.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0269-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch b/target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch
index 9fd796850f..9fd796850f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0269-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0270-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch b/target/linux/bcm27xx/patches-5.4/950-0266-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch
index 619eb811cd..619eb811cd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0270-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0266-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0271-tty-amba-pl011-Make-TX-optimisation-conditional.patch b/target/linux/bcm27xx/patches-5.4/950-0267-tty-amba-pl011-Make-TX-optimisation-conditional.patch
index 9214bda206..9214bda206 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0271-tty-amba-pl011-Make-TX-optimisation-conditional.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0267-tty-amba-pl011-Make-TX-optimisation-conditional.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0272-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch b/target/linux/bcm27xx/patches-5.4/950-0268-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch
index 50b9a9b4b4..50b9a9b4b4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0272-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0268-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0273-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch b/target/linux/bcm27xx/patches-5.4/950-0269-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
index a3bc6c91b6..a3bc6c91b6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0273-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0269-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0275-staging-vc04_services-fix-compiling-in-separate-dire.patch b/target/linux/bcm27xx/patches-5.4/950-0270-staging-vc04_services-fix-compiling-in-separate-dire.patch
index b3d57dc2b3..b3d57dc2b3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0275-staging-vc04_services-fix-compiling-in-separate-dire.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0270-staging-vc04_services-fix-compiling-in-separate-dire.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0277-clk-bcm2835-Avoid-null-pointer-exception.patch b/target/linux/bcm27xx/patches-5.4/950-0271-clk-bcm2835-Avoid-null-pointer-exception.patch
index d669d4066b..d669d4066b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0277-clk-bcm2835-Avoid-null-pointer-exception.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0271-clk-bcm2835-Avoid-null-pointer-exception.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0279-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0272-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch
index e4f178d0a2..e4f178d0a2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0279-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0272-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0280-drm-v3d-HACK-gut-runtime-pm-for-now.patch b/target/linux/bcm27xx/patches-5.4/950-0273-drm-v3d-HACK-gut-runtime-pm-for-now.patch
index ed69f2d157..ed69f2d157 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0280-drm-v3d-HACK-gut-runtime-pm-for-now.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0273-drm-v3d-HACK-gut-runtime-pm-for-now.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0274-arm64-mm-Limit-the-DMA-zone-for-arm64.patch b/target/linux/bcm27xx/patches-5.4/950-0274-arm64-mm-Limit-the-DMA-zone-for-arm64.patch
deleted file mode 100644
index e2c47c4459..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0274-arm64-mm-Limit-the-DMA-zone-for-arm64.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 235f775351e8f7e47cff1baa1284e0df95e3234e Mon Sep 17 00:00:00 2001
-From: Andrei Gherzan <andrei@balena.io>
-Date: Tue, 16 Jul 2019 13:28:22 +0100
-Subject: [PATCH] arm64/mm: Limit the DMA zone for arm64
-
-On RaspberryPi, only the first 1Gb can be used for DMA[1].
-
-[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2019-July/665986.html
-
-Signed-off-by: Andrei Gherzan <andrei@balena.io>
----
- arch/arm64/mm/init.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm64/mm/init.c
-+++ b/arch/arm64/mm/init.c
-@@ -177,7 +177,7 @@ static void __init reserve_elfcorehdr(vo
- static phys_addr_t __init max_zone_dma_phys(void)
- {
- phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
-- return min(offset + (1ULL << 32), memblock_end_of_DRAM());
-+ return min(offset + (1ULL << 30), memblock_end_of_DRAM());
- }
-
- #ifdef CONFIG_NUMA
diff --git a/target/linux/bcm27xx/patches-5.4/950-0281-drm-v3d-Clock-V3D-down-when-not-in-use.patch b/target/linux/bcm27xx/patches-5.4/950-0274-drm-v3d-Clock-V3D-down-when-not-in-use.patch
index 782cc197d5..782cc197d5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0281-drm-v3d-Clock-V3D-down-when-not-in-use.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0274-drm-v3d-Clock-V3D-down-when-not-in-use.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0282-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch b/target/linux/bcm27xx/patches-5.4/950-0275-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch
index 267725d3ef..267725d3ef 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0282-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0275-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0276-bcm2835-dma-Add-proper-40-bit-DMA-support.patch b/target/linux/bcm27xx/patches-5.4/950-0276-bcm2835-dma-Add-proper-40-bit-DMA-support.patch
deleted file mode 100644
index 60610d5edd..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0276-bcm2835-dma-Add-proper-40-bit-DMA-support.patch
+++ /dev/null
@@ -1,945 +0,0 @@
-From 773a2db89ad2785d72b215673d87c0a51d769f61 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 4 Apr 2019 13:33:47 +0100
-Subject: [PATCH] bcm2835-dma: Add proper 40-bit DMA support
-
-The 40-bit additions are not fully tested, but it should be
-capable of supporting both 40-bit memcpy on BCM2711 and regular
-Lite channels on BCM2835.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/dma/bcm2835-dma.c | 421 ++++++++++++++-----
- drivers/pci/controller/pcie-brcmstb-bounce.c | 30 +-
- drivers/pci/controller/pcie-brcmstb-bounce.h | 21 +-
- drivers/pci/controller/pcie-brcmstb.c | 23 +-
- 4 files changed, 369 insertions(+), 126 deletions(-)
-
---- a/drivers/dma/bcm2835-dma.c
-+++ b/drivers/dma/bcm2835-dma.c
-@@ -38,6 +38,11 @@
- #define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14
- #define BCM2835_DMA_CHAN_NAME_SIZE 8
- #define BCM2835_DMA_BULK_MASK BIT(0)
-+#define BCM2838_DMA_MEMCPY_CHAN 14
-+
-+struct bcm2835_dma_cfg_data {
-+ u32 chan_40bit_mask;
-+};
-
- /**
- * struct bcm2835_dmadev - BCM2835 DMA controller
-@@ -52,6 +57,7 @@ struct bcm2835_dmadev {
- void __iomem *base;
- struct device_dma_parameters dma_parms;
- dma_addr_t zero_page;
-+ const struct bcm2835_dma_cfg_data *cfg_data;
- };
-
- struct bcm2835_dma_cb {
-@@ -95,6 +101,7 @@ struct bcm2835_chan {
- unsigned int irq_flags;
-
- bool is_lite_channel;
-+ bool is_40bit_channel;
- };
-
- struct bcm2835_desc {
-@@ -184,7 +191,8 @@ struct bcm2835_desc {
- #define BCM2835_DMA_DATA_TYPE_S128 16
-
- /* Valid only for channels 0 - 14, 15 has its own base address */
--#define BCM2835_DMA_CHAN(n) ((n) << 8) /* Base address */
-+#define BCM2835_DMA_CHAN_SIZE 0x100
-+#define BCM2835_DMA_CHAN(n) ((n) * BCM2835_DMA_CHAN_SIZE) /* Base address */
- #define BCM2835_DMA_CHANIO(base, n) ((base) + BCM2835_DMA_CHAN(n))
-
- /* the max dma length for different channels */
-@@ -195,7 +203,7 @@ struct bcm2835_desc {
- #define BCM2838_DMA40_CS 0x00
- #define BCM2838_DMA40_CB 0x04
- #define BCM2838_DMA40_DEBUG 0x0c
--#define BCM2858_DMA40_TI 0x10
-+#define BCM2838_DMA40_TI 0x10
- #define BCM2838_DMA40_SRC 0x14
- #define BCM2838_DMA40_SRCI 0x18
- #define BCM2838_DMA40_DEST 0x1c
-@@ -204,32 +212,97 @@ struct bcm2835_desc {
- #define BCM2838_DMA40_NEXT_CB 0x28
- #define BCM2838_DMA40_DEBUG2 0x2c
-
--#define BCM2838_DMA40_CS_ACTIVE BIT(0)
--#define BCM2838_DMA40_CS_END BIT(1)
-+#define BCM2838_DMA40_ACTIVE BIT(0)
-+#define BCM2838_DMA40_END BIT(1)
-+#define BCM2838_DMA40_INT BIT(2)
-+#define BCM2838_DMA40_DREQ BIT(3) /* DREQ state */
-+#define BCM2838_DMA40_RD_PAUSED BIT(4) /* Reading is paused */
-+#define BCM2838_DMA40_WR_PAUSED BIT(5) /* Writing is paused */
-+#define BCM2838_DMA40_DREQ_PAUSED BIT(6) /* Is paused by DREQ flow control */
-+#define BCM2838_DMA40_WAITING_FOR_WRITES BIT(7) /* Waiting for last write */
-+#define BCM2838_DMA40_ERR BIT(10)
-+#define BCM2838_DMA40_QOS(x) (((x) & 0x1f) << 16)
-+#define BCM2838_DMA40_PANIC_QOS(x) (((x) & 0x1f) << 20)
-+#define BCM2838_DMA40_WAIT_FOR_WRITES BIT(28)
-+#define BCM2838_DMA40_DISDEBUG BIT(29)
-+#define BCM2838_DMA40_ABORT BIT(30)
-+#define BCM2838_DMA40_HALT BIT(31)
-+#define BCM2838_DMA40_CS_FLAGS(x) (x & (BCM2838_DMA40_QOS(15) | \
-+ BCM2838_DMA40_PANIC_QOS(15) | \
-+ BCM2838_DMA40_WAIT_FOR_WRITES | \
-+ BCM2838_DMA40_DISDEBUG))
-+
-+/* Transfer information bits */
-+#define BCM2838_DMA40_INTEN BIT(0)
-+#define BCM2838_DMA40_TDMODE BIT(1) /* 2D-Mode */
-+#define BCM2838_DMA40_WAIT_RESP BIT(2) /* wait for AXI write to be acked */
-+#define BCM2838_DMA40_WAIT_RD_RESP BIT(3) /* wait for AXI read to complete */
-+#define BCM2838_DMA40_PER_MAP(x) ((x & 31) << 9) /* REQ source */
-+#define BCM2838_DMA40_S_DREQ BIT(14) /* enable SREQ for source */
-+#define BCM2838_DMA40_D_DREQ BIT(15) /* enable DREQ for destination */
-+#define BCM2838_DMA40_S_WAIT(x) ((x & 0xff) << 16) /* add DMA read-wait cycles */
-+#define BCM2838_DMA40_D_WAIT(x) ((x & 0xff) << 24) /* add DMA write-wait cycles */
-
--#define BCM2838_DMA40_CS_QOS(x) (((x) & 0x1f) << 16)
--#define BCM2838_DMA40_CS_PANIC_QOS(x) (((x) & 0x1f) << 20)
--#define BCM2838_DMA40_CS_WRITE_WAIT BIT(28)
-+/* debug register bits */
-+#define BCM2838_DMA40_DEBUG_WRITE_ERR BIT(0)
-+#define BCM2838_DMA40_DEBUG_FIFO_ERR BIT(1)
-+#define BCM2838_DMA40_DEBUG_READ_ERR BIT(2)
-+#define BCM2838_DMA40_DEBUG_READ_CB_ERR BIT(3)
-+#define BCM2838_DMA40_DEBUG_IN_ON_ERR BIT(8)
-+#define BCM2838_DMA40_DEBUG_ABORT_ON_ERR BIT(9)
-+#define BCM2838_DMA40_DEBUG_HALT_ON_ERR BIT(10)
-+#define BCM2838_DMA40_DEBUG_DISABLE_CLK_GATE BIT(11)
-+#define BCM2838_DMA40_DEBUG_RSTATE_SHIFT 14
-+#define BCM2838_DMA40_DEBUG_RSTATE_BITS 4
-+#define BCM2838_DMA40_DEBUG_WSTATE_SHIFT 18
-+#define BCM2838_DMA40_DEBUG_WSTATE_BITS 4
-+#define BCM2838_DMA40_DEBUG_RESET BIT(23)
-+#define BCM2838_DMA40_DEBUG_ID_SHIFT 24
-+#define BCM2838_DMA40_DEBUG_ID_BITS 4
-+#define BCM2838_DMA40_DEBUG_VERSION_SHIFT 28
-+#define BCM2838_DMA40_DEBUG_VERSION_BITS 4
-+
-+/* Valid only for channels 0 - 3 (11 - 14) */
-+#define BCM2838_DMA40_CHAN(n) (((n) + 11) << 8) /* Base address */
-+#define BCM2838_DMA40_CHANIO(base, n) ((base) + BCM2838_DMA_CHAN(n))
-
--#define BCM2838_DMA40_BURST_LEN(x) ((((x) - 1) & 0xf) << 8)
--#define BCM2838_DMA40_INC BIT(12)
--#define BCM2838_DMA40_SIZE_128 (2 << 13)
-+/* the max dma length for different channels */
-+#define MAX_DMA40_LEN SZ_1G
-
--#define BCM2838_DMA40_MEMCPY_QOS \
-- (BCM2838_DMA40_CS_QOS(0x0) | \
-- BCM2838_DMA40_CS_PANIC_QOS(0x0) | \
-- BCM2838_DMA40_CS_WRITE_WAIT)
-+#define BCM2838_DMA40_BURST_LEN(x) ((min(x,16) - 1) << 8)
-+#define BCM2838_DMA40_INC BIT(12)
-+#define BCM2838_DMA40_SIZE_32 (0 << 13)
-+#define BCM2838_DMA40_SIZE_64 (1 << 13)
-+#define BCM2838_DMA40_SIZE_128 (2 << 13)
-+#define BCM2838_DMA40_SIZE_256 (3 << 13)
-+#define BCM2838_DMA40_IGNORE BIT(15)
-+#define BCM2838_DMA40_STRIDE(x) ((x) << 16) /* For 2D mode */
-+
-+#define BCM2838_DMA40_MEMCPY_FLAGS \
-+ (BCM2838_DMA40_QOS(0) | \
-+ BCM2838_DMA40_PANIC_QOS(0) | \
-+ BCM2838_DMA40_WAIT_FOR_WRITES | \
-+ BCM2838_DMA40_DISDEBUG)
-
- #define BCM2838_DMA40_MEMCPY_XFER_INFO \
- (BCM2838_DMA40_SIZE_128 | \
- BCM2838_DMA40_INC | \
- BCM2838_DMA40_BURST_LEN(16))
-
-+struct bcm2835_dmadev *memcpy_parent;
- static void __iomem *memcpy_chan;
- static struct bcm2838_dma40_scb *memcpy_scb;
- static dma_addr_t memcpy_scb_dma;
- DEFINE_SPINLOCK(memcpy_lock);
-
-+static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = {
-+ .chan_40bit_mask = 0,
-+};
-+
-+static const struct bcm2835_dma_cfg_data bcm2838_dma_cfg = {
-+ .chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
-+};
-+
- static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
- {
- /* lite and normal channels have different max frame length */
-@@ -259,6 +332,32 @@ static inline struct bcm2835_desc *to_bc
- return container_of(t, struct bcm2835_desc, vd.tx);
- }
-
-+static inline uint32_t to_bcm2838_ti(uint32_t info)
-+{
-+ return ((info & BCM2835_DMA_INT_EN) ? BCM2838_DMA40_INTEN : 0) |
-+ ((info & BCM2835_DMA_WAIT_RESP) ? BCM2838_DMA40_WAIT_RESP : 0) |
-+ ((info & BCM2835_DMA_S_DREQ) ?
-+ (BCM2838_DMA40_S_DREQ | BCM2838_DMA40_WAIT_RD_RESP) : 0) |
-+ ((info & BCM2835_DMA_D_DREQ) ? BCM2838_DMA40_D_DREQ : 0) |
-+ BCM2838_DMA40_PER_MAP((info >> 16) & 0x1f);
-+}
-+
-+static inline uint32_t to_bcm2838_srci(uint32_t info)
-+{
-+ return ((info & BCM2835_DMA_S_INC) ? BCM2838_DMA40_INC : 0);
-+}
-+
-+static inline uint32_t to_bcm2838_dsti(uint32_t info)
-+{
-+ return ((info & BCM2835_DMA_D_INC) ? BCM2838_DMA40_INC : 0);
-+}
-+
-+static inline uint32_t to_bcm2838_cbaddr(dma_addr_t addr)
-+{
-+ BUG_ON(addr & 0x1f);
-+ return (addr >> 5);
-+}
-+
- static void bcm2835_dma_free_cb_chain(struct bcm2835_desc *desc)
- {
- size_t i;
-@@ -277,45 +376,53 @@ static void bcm2835_dma_desc_free(struct
- }
-
- static void bcm2835_dma_create_cb_set_length(
-- struct bcm2835_chan *chan,
-+ struct bcm2835_chan *c,
- struct bcm2835_dma_cb *control_block,
- size_t len,
- size_t period_len,
- size_t *total_len,
- u32 finalextrainfo)
- {
-- size_t max_len = bcm2835_dma_max_frame_length(chan);
-+ size_t max_len = bcm2835_dma_max_frame_length(c);
-+ uint32_t cb_len;
-
- /* set the length taking lite-channel limitations into account */
-- control_block->length = min_t(u32, len, max_len);
-+ cb_len = min_t(u32, len, max_len);
-
-- /* finished if we have no period_length */
-- if (!period_len)
-- return;
-+ if (period_len) {
-+ /*
-+ * period_len means: that we need to generate
-+ * transfers that are terminating at every
-+ * multiple of period_len - this is typically
-+ * used to set the interrupt flag in info
-+ * which is required during cyclic transfers
-+ */
-
-- /*
-- * period_len means: that we need to generate
-- * transfers that are terminating at every
-- * multiple of period_len - this is typically
-- * used to set the interrupt flag in info
-- * which is required during cyclic transfers
-- */
-+ /* have we filled in period_length yet? */
-+ if (*total_len + cb_len < period_len) {
-+ /* update number of bytes in this period so far */
-+ *total_len += cb_len;
-+ } else {
-+ /* calculate the length that remains to reach period_len */
-+ cb_len = period_len - *total_len;
-
-- /* have we filled in period_length yet? */
-- if (*total_len + control_block->length < period_len) {
-- /* update number of bytes in this period so far */
-- *total_len += control_block->length;
-- return;
-+ /* reset total_length for next period */
-+ *total_len = 0;
-+ }
- }
-
-- /* calculate the length that remains to reach period_length */
-- control_block->length = period_len - *total_len;
--
-- /* reset total_length for next period */
-- *total_len = 0;
--
-- /* add extrainfo bits in info */
-- control_block->info |= finalextrainfo;
-+ if (c->is_40bit_channel) {
-+ struct bcm2838_dma40_scb *scb =
-+ (struct bcm2838_dma40_scb *)control_block;
-+
-+ scb->len = cb_len;
-+ /* add extrainfo bits to ti */
-+ scb->ti |= to_bcm2838_ti(finalextrainfo);
-+ } else {
-+ control_block->length = cb_len;
-+ /* add extrainfo bits to info */
-+ control_block->info |= finalextrainfo;
-+ }
- }
-
- static inline size_t bcm2835_dma_count_frames_for_sg(
-@@ -338,7 +445,7 @@ static inline size_t bcm2835_dma_count_f
- /**
- * bcm2835_dma_create_cb_chain - create a control block and fills data in
- *
-- * @chan: the @dma_chan for which we run this
-+ * @c: the @bcm2835_chan for which we run this
- * @direction: the direction in which we transfer
- * @cyclic: it is a cyclic transfer
- * @info: the default info bits to apply per controlblock
-@@ -356,12 +463,11 @@ static inline size_t bcm2835_dma_count_f
- * @gfp: the GFP flag to use for allocation
- */
- static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
-- struct dma_chan *chan, enum dma_transfer_direction direction,
-+ struct bcm2835_chan *c, enum dma_transfer_direction direction,
- bool cyclic, u32 info, u32 finalextrainfo, size_t frames,
- dma_addr_t src, dma_addr_t dst, size_t buf_len,
- size_t period_len, gfp_t gfp)
- {
-- struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
- size_t len = buf_len, total_len;
- size_t frame;
- struct bcm2835_desc *d;
-@@ -393,11 +499,23 @@ static struct bcm2835_desc *bcm2835_dma_
-
- /* fill in the control block */
- control_block = cb_entry->cb;
-- control_block->info = info;
-- control_block->src = src;
-- control_block->dst = dst;
-- control_block->stride = 0;
-- control_block->next = 0;
-+ if (c->is_40bit_channel) {
-+ struct bcm2838_dma40_scb *scb =
-+ (struct bcm2838_dma40_scb *)control_block;
-+ scb->ti = to_bcm2838_ti(info);
-+ scb->src = lower_32_bits(src);
-+ scb->srci= upper_32_bits(src) | to_bcm2838_srci(info);
-+ scb->dst = lower_32_bits(dst);
-+ scb->dsti = upper_32_bits(dst) | to_bcm2838_dsti(info);
-+ scb->next_cb = 0;
-+ } else {
-+ control_block->info = info;
-+ control_block->src = src;
-+ control_block->dst = dst;
-+ control_block->stride = 0;
-+ control_block->next = 0;
-+ }
-+
- /* set up length in control_block if requested */
- if (buf_len) {
- /* calculate length honoring period_length */
-@@ -411,7 +529,10 @@ static struct bcm2835_desc *bcm2835_dma_
- }
-
- /* link this the last controlblock */
-- if (frame)
-+ if (frame && c->is_40bit_channel)
-+ d->cb_list[frame - 1].cb->next =
-+ to_bcm2838_cbaddr(cb_entry->paddr);
-+ if (frame && !c->is_40bit_channel)
- d->cb_list[frame - 1].cb->next = cb_entry->paddr;
-
- /* update src and dst and length */
-@@ -425,7 +546,14 @@ static struct bcm2835_desc *bcm2835_dma_
- }
-
- /* the last frame requires extra flags */
-- d->cb_list[d->frames - 1].cb->info |= finalextrainfo;
-+ if (c->is_40bit_channel) {
-+ struct bcm2838_dma40_scb *scb =
-+ (struct bcm2838_dma40_scb *)d->cb_list[d->frames-1].cb;
-+
-+ scb->ti |= to_bcm2838_ti(finalextrainfo);
-+ } else {
-+ d->cb_list[d->frames - 1].cb->info |= finalextrainfo;
-+ }
-
- /* detect a size missmatch */
- if (buf_len && (d->size != buf_len))
-@@ -439,13 +567,12 @@ error_cb:
- }
-
- static void bcm2835_dma_fill_cb_chain_with_sg(
-- struct dma_chan *chan,
-+ struct bcm2835_chan *c,
- enum dma_transfer_direction direction,
- struct bcm2835_cb_entry *cb,
- struct scatterlist *sgl,
- unsigned int sg_len)
- {
-- struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
- size_t len, max_len;
- unsigned int i;
- dma_addr_t addr;
-@@ -453,14 +580,34 @@ static void bcm2835_dma_fill_cb_chain_wi
-
- max_len = bcm2835_dma_max_frame_length(c);
- for_each_sg(sgl, sgent, sg_len, i) {
-- for (addr = sg_dma_address(sgent), len = sg_dma_len(sgent);
-- len > 0;
-- addr += cb->cb->length, len -= cb->cb->length, cb++) {
-- if (direction == DMA_DEV_TO_MEM)
-- cb->cb->dst = addr;
-- else
-- cb->cb->src = addr;
-- cb->cb->length = min(len, max_len);
-+ if (c->is_40bit_channel) {
-+ struct bcm2838_dma40_scb *scb =
-+ (struct bcm2838_dma40_scb *)cb->cb;
-+ for (addr = sg_dma_address(sgent),
-+ len = sg_dma_len(sgent);
-+ len > 0;
-+ addr += scb->len, len -= scb->len, scb++) {
-+ if (direction == DMA_DEV_TO_MEM) {
-+ scb->dst = lower_32_bits(addr);
-+ scb->dsti = upper_32_bits(addr) | BCM2838_DMA40_INC;
-+ } else {
-+ scb->src = lower_32_bits(addr);
-+ scb->srci = upper_32_bits(addr) | BCM2838_DMA40_INC;
-+ }
-+ scb->len = min(len, max_len);
-+ }
-+ } else {
-+ for (addr = sg_dma_address(sgent),
-+ len = sg_dma_len(sgent);
-+ len > 0;
-+ addr += cb->cb->length, len -= cb->cb->length,
-+ cb++) {
-+ if (direction == DMA_DEV_TO_MEM)
-+ cb->cb->dst = addr;
-+ else
-+ cb->cb->src = addr;
-+ cb->cb->length = min(len, max_len);
-+ }
- }
- }
- }
-@@ -469,6 +616,10 @@ static void bcm2835_dma_abort(struct bcm
- {
- void __iomem *chan_base = c->chan_base;
- long int timeout = 10000;
-+ u32 wait_mask = BCM2835_DMA_WAITING_FOR_WRITES;
-+
-+ if (c->is_40bit_channel)
-+ wait_mask = BCM2838_DMA40_WAITING_FOR_WRITES;
-
- /*
- * A zero control block address means the channel is idle.
-@@ -481,8 +632,7 @@ static void bcm2835_dma_abort(struct bcm
- writel(0, chan_base + BCM2835_DMA_CS);
-
- /* Wait for any current AXI transfer to complete */
-- while ((readl(chan_base + BCM2835_DMA_CS) &
-- BCM2835_DMA_WAITING_FOR_WRITES) && --timeout)
-+ while ((readl(chan_base + BCM2835_DMA_CS) & wait_mask) && --timeout)
- cpu_relax();
-
- /* Peripheral might be stuck and fail to signal AXI write responses */
-@@ -507,9 +657,16 @@ static void bcm2835_dma_start_desc(struc
-
- c->desc = d = to_bcm2835_dma_desc(&vd->tx);
-
-- writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
-- writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
-- c->chan_base + BCM2835_DMA_CS);
-+ if (c->is_40bit_channel) {
-+ writel(to_bcm2838_cbaddr(d->cb_list[0].paddr),
-+ c->chan_base + BCM2838_DMA40_CB);
-+ writel(BCM2838_DMA40_ACTIVE | BCM2838_DMA40_CS_FLAGS(c->dreq),
-+ c->chan_base + BCM2838_DMA40_CS);
-+ } else {
-+ writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
-+ writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
-+ c->chan_base + BCM2835_DMA_CS);
-+ }
- }
-
- static irqreturn_t bcm2835_dma_callback(int irq, void *data)
-@@ -537,7 +694,8 @@ static irqreturn_t bcm2835_dma_callback(
- * will remain idle despite the ACTIVE flag being set.
- */
- writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE |
-- BCM2835_DMA_CS_FLAGS(c->dreq),
-+ (c->is_40bit_channel ? BCM2838_DMA40_CS_FLAGS(c->dreq) :
-+ BCM2835_DMA_CS_FLAGS(c->dreq)),
- c->chan_base + BCM2835_DMA_CS);
-
- d = c->desc;
-@@ -640,9 +798,17 @@ static enum dma_status bcm2835_dma_tx_st
- struct bcm2835_desc *d = c->desc;
- dma_addr_t pos;
-
-- if (d->dir == DMA_MEM_TO_DEV)
-+ if (d->dir == DMA_MEM_TO_DEV && c->is_40bit_channel)
-+ pos = readl(c->chan_base + BCM2838_DMA40_SRC) +
-+ ((readl(c->chan_base + BCM2838_DMA40_SRCI) &
-+ 0xff) << 8);
-+ else if (d->dir == DMA_MEM_TO_DEV && !c->is_40bit_channel)
- pos = readl(c->chan_base + BCM2835_DMA_SOURCE_AD);
-- else if (d->dir == DMA_DEV_TO_MEM)
-+ else if (d->dir == DMA_DEV_TO_MEM && c->is_40bit_channel)
-+ pos = readl(c->chan_base + BCM2838_DMA40_DEST) +
-+ ((readl(c->chan_base + BCM2838_DMA40_DESTI) &
-+ 0xff) << 8);
-+ else if (d->dir == DMA_DEV_TO_MEM && !c->is_40bit_channel)
- pos = readl(c->chan_base + BCM2835_DMA_DEST_AD);
- else
- pos = 0;
-@@ -688,7 +854,7 @@ static struct dma_async_tx_descriptor *b
- frames = bcm2835_dma_frames_for_length(len, max_len);
-
- /* allocate the CB chain - this also fills in the pointers */
-- d = bcm2835_dma_create_cb_chain(chan, DMA_MEM_TO_MEM, false,
-+ d = bcm2835_dma_create_cb_chain(c, DMA_MEM_TO_MEM, false,
- info, extra, frames,
- src, dst, len, 0, GFP_KERNEL);
- if (!d)
-@@ -723,11 +889,21 @@ static struct dma_async_tx_descriptor *b
- if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
- return NULL;
- src = c->cfg.src_addr;
-+ /*
-+ * One would think it ought to be possible to get the physical
-+ * to dma address mapping information from the dma-ranges DT
-+ * property, but I've not found a way yet that doesn't involve
-+ * open-coding the whole thing.
-+ */
-+ if (c->is_40bit_channel)
-+ src |= 0x400000000ull;
- info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
- } else {
- if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
- return NULL;
- dst = c->cfg.dst_addr;
-+ if (c->is_40bit_channel)
-+ dst |= 0x400000000ull;
- info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
- }
-
-@@ -735,7 +911,7 @@ static struct dma_async_tx_descriptor *b
- frames = bcm2835_dma_count_frames_for_sg(c, sgl, sg_len);
-
- /* allocate the CB chain */
-- d = bcm2835_dma_create_cb_chain(chan, direction, false,
-+ d = bcm2835_dma_create_cb_chain(c, direction, false,
- info, extra,
- frames, src, dst, 0, 0,
- GFP_NOWAIT);
-@@ -743,7 +919,7 @@ static struct dma_async_tx_descriptor *b
- return NULL;
-
- /* fill in frames with scatterlist pointers */
-- bcm2835_dma_fill_cb_chain_with_sg(chan, direction, d->cb_list,
-+ bcm2835_dma_fill_cb_chain_with_sg(c, direction, d->cb_list,
- sgl, sg_len);
-
- return vchan_tx_prep(&c->vc, &d->vd, flags);
-@@ -822,7 +998,7 @@ static struct dma_async_tx_descriptor *b
- * note that we need to use GFP_NOWAIT, as the ALSA i2s dmaengine
- * implementation calls prep_dma_cyclic with interrupts disabled.
- */
-- d = bcm2835_dma_create_cb_chain(chan, direction, true,
-+ d = bcm2835_dma_create_cb_chain(c, direction, true,
- info, extra,
- frames, src, dst, buf_len,
- period_len, GFP_NOWAIT);
-@@ -830,7 +1006,8 @@ static struct dma_async_tx_descriptor *b
- return NULL;
-
- /* wrap around into a loop */
-- d->cb_list[d->frames - 1].cb->next = d->cb_list[0].paddr;
-+ d->cb_list[d->frames - 1].cb->next = c->is_40bit_channel ?
-+ to_bcm2838_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr;
-
- return vchan_tx_prep(&c->vc, &d->vd, flags);
- }
-@@ -894,9 +1071,11 @@ static int bcm2835_dma_chan_init(struct
- c->irq_number = irq;
- c->irq_flags = irq_flags;
-
-- /* check in DEBUG register if this is a LITE channel */
-- if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
-- BCM2835_DMA_DEBUG_LITE)
-+ /* check for 40bit and lite channels */
-+ if (d->cfg_data->chan_40bit_mask & BIT(chan_id))
-+ c->is_40bit_channel = true;
-+ else if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
-+ BCM2835_DMA_DEBUG_LITE)
- c->is_lite_channel = true;
-
- return 0;
-@@ -916,18 +1095,16 @@ static void bcm2835_dma_free(struct bcm2
- DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
- }
-
--int bcm2838_dma40_memcpy_init(struct device *dev)
-+int bcm2838_dma40_memcpy_init(void)
- {
-- if (memcpy_scb)
-- return 0;
-+ if (!memcpy_parent)
-+ return -EPROBE_DEFER;
-
-- memcpy_scb = dma_alloc_coherent(dev, sizeof(*memcpy_scb),
-- &memcpy_scb_dma, GFP_KERNEL);
-+ if (!memcpy_chan)
-+ return -EINVAL;
-
-- if (!memcpy_scb) {
-- pr_err("bcm2838_dma40_memcpy_init failed!\n");
-+ if (!memcpy_scb)
- return -ENOMEM;
-- }
-
- return 0;
- }
-@@ -954,20 +1131,22 @@ void bcm2838_dma40_memcpy(dma_addr_t dst
- scb->next_cb = 0;
-
- writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2838_DMA40_CB);
-- writel(BCM2838_DMA40_MEMCPY_QOS + BCM2838_DMA40_CS_ACTIVE,
-+ writel(BCM2838_DMA40_MEMCPY_FLAGS + BCM2838_DMA40_ACTIVE,
- memcpy_chan + BCM2838_DMA40_CS);
-+
- /* Poll for completion */
-- while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_CS_END))
-+ while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_END))
- cpu_relax();
-
-- writel(BCM2838_DMA40_CS_END, memcpy_chan + BCM2838_DMA40_CS);
-+ writel(BCM2838_DMA40_END, memcpy_chan + BCM2838_DMA40_CS);
-
- spin_unlock_irqrestore(&memcpy_lock, flags);
- }
- EXPORT_SYMBOL(bcm2838_dma40_memcpy);
-
- static const struct of_device_id bcm2835_dma_of_match[] = {
-- { .compatible = "brcm,bcm2835-dma", },
-+ { .compatible = "brcm,bcm2835-dma", .data = &bcm2835_dma_cfg },
-+ { .compatible = "brcm,bcm2838-dma", .data = &bcm2838_dma_cfg },
- {},
- };
- MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match);
-@@ -999,6 +1178,8 @@ static int bcm2835_dma_probe(struct plat
- int irq_flags;
- uint32_t chans_available;
- char chan_name[BCM2835_DMA_CHAN_NAME_SIZE];
-+ const struct of_device_id *of_id;
-+ int chan_count, chan_start, chan_end;
-
- if (!pdev->dev.dma_mask)
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-@@ -1020,9 +1201,13 @@ static int bcm2835_dma_probe(struct plat
- base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(base))
- return PTR_ERR(base);
-- rc = bcm_dmaman_probe(pdev, base, BCM2835_DMA_BULK_MASK);
-- if (rc)
-- dev_err(&pdev->dev, "Failed to initialize the legacy API\n");
-+
-+ /* The set of channels can be split across multiple instances. */
-+ chan_start = ((u32)(uintptr_t)base / BCM2835_DMA_CHAN_SIZE) & 0xf;
-+ base -= BCM2835_DMA_CHAN(chan_start);
-+ chan_count = resource_size(res) / BCM2835_DMA_CHAN_SIZE;
-+ chan_end = min(chan_start + chan_count,
-+ BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED + 1);
-
- od->base = base;
-
-@@ -1059,6 +1244,14 @@ static int bcm2835_dma_probe(struct plat
- return -ENOMEM;
- }
-
-+ of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node);
-+ if (!of_id) {
-+ dev_err(&pdev->dev, "Failed to match compatible string\n");
-+ return -EINVAL;
-+ }
-+
-+ od->cfg_data = of_id->data;
-+
- /* Request DMA channel mask from device tree */
- if (of_property_read_u32(pdev->dev.of_node,
- "brcm,dma-channel-mask",
-@@ -1068,18 +1261,34 @@ static int bcm2835_dma_probe(struct plat
- goto err_no_dma;
- }
-
-- /* Channel 0 is used by the legacy API */
-- chans_available &= ~BCM2835_DMA_BULK_MASK;
-+ /* One channel is reserved for the legacy API */
-+ if (chans_available & BCM2835_DMA_BULK_MASK) {
-+ rc = bcm_dmaman_probe(pdev, base,
-+ chans_available & BCM2835_DMA_BULK_MASK);
-+ if (rc)
-+ dev_err(&pdev->dev,
-+ "Failed to initialize the legacy API\n");
-+
-+ chans_available &= ~BCM2835_DMA_BULK_MASK;
-+ }
-
-- /* We can't use channels 11-13 yet */
-- chans_available &= ~(BIT(11) | BIT(12) | BIT(13));
-+ /* And possibly one for the 40-bit DMA memcpy API */
-+ if (chans_available & od->cfg_data->chan_40bit_mask &
-+ BIT(BCM2838_DMA_MEMCPY_CHAN)) {
-+ memcpy_parent = od;
-+ memcpy_chan = BCM2835_DMA_CHANIO(base, BCM2838_DMA_MEMCPY_CHAN);
-+ memcpy_scb = dma_alloc_coherent(memcpy_parent->ddev.dev,
-+ sizeof(*memcpy_scb),
-+ &memcpy_scb_dma, GFP_KERNEL);
-+ if (!memcpy_scb)
-+ dev_warn(&pdev->dev,
-+ "Failed to allocated memcpy scb\n");
-
-- /* Grab channel 14 for the 40-bit DMA memcpy */
-- chans_available &= ~BIT(14);
-- memcpy_chan = BCM2835_DMA_CHANIO(base, 14);
-+ chans_available &= ~BIT(BCM2838_DMA_MEMCPY_CHAN);
-+ }
-
- /* get irqs for each channel that we support */
-- for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) {
-+ for (i = chan_start; i < chan_end; i++) {
- /* skip masked out channels */
- if (!(chans_available & (1 << i))) {
- irq[i] = -1;
-@@ -1102,13 +1311,17 @@ static int bcm2835_dma_probe(struct plat
- irq[i] = platform_get_irq(pdev, i < 11 ? i : 11);
- }
-
-+ chan_count = 0;
-+
- /* get irqs for each channel */
-- for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) {
-+ for (i = chan_start; i < chan_end; i++) {
- /* skip channels without irq */
- if (irq[i] < 0)
- continue;
-
- /* check if there are other channels that also use this irq */
-+ /* FIXME: This will fail if interrupts are shared across
-+ instances */
- irq_flags = 0;
- for (j = 0; j <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; j++)
- if ((i != j) && (irq[j] == irq[i])) {
-@@ -1120,9 +1333,10 @@ static int bcm2835_dma_probe(struct plat
- rc = bcm2835_dma_chan_init(od, i, irq[i], irq_flags);
- if (rc)
- goto err_no_dma;
-+ chan_count++;
- }
-
-- dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", i);
-+ dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", chan_count);
-
- /* Device-tree DMA controller registration */
- rc = of_dma_controller_register(pdev->dev.of_node,
-@@ -1154,6 +1368,13 @@ static int bcm2835_dma_remove(struct pla
-
- bcm_dmaman_remove(pdev);
- dma_async_device_unregister(&od->ddev);
-+ if (memcpy_parent == od) {
-+ dma_free_coherent(&pdev->dev, sizeof(*memcpy_scb), memcpy_scb,
-+ memcpy_scb_dma);
-+ memcpy_parent = NULL;
-+ memcpy_scb = NULL;
-+ memcpy_chan = NULL;
-+ }
- bcm2835_dma_free(od);
-
- return 0;
---- a/drivers/pci/controller/pcie-brcmstb-bounce.c
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce.c
-@@ -91,7 +91,7 @@ struct dmabounce_device_info {
-
- static struct dmabounce_device_info *g_dmabounce_device_info;
-
--extern int bcm2838_dma40_memcpy_init(struct device *dev);
-+extern int bcm2838_dma40_memcpy_init(void);
- extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size);
-
- #ifdef STATS
-@@ -465,9 +465,9 @@ static const struct dma_map_ops dmabounc
- .dma_supported = dmabounce_dma_supported,
- };
-
--int brcm_pcie_bounce_register_dev(struct device *dev,
-- unsigned long buffer_size,
-- dma_addr_t threshold)
-+int brcm_pcie_bounce_init(struct device *dev,
-+ unsigned long buffer_size,
-+ dma_addr_t threshold)
- {
- struct dmabounce_device_info *device_info;
- int ret;
-@@ -476,9 +476,9 @@ int brcm_pcie_bounce_register_dev(struct
- if (g_dmabounce_device_info)
- return -EBUSY;
-
-- ret = bcm2838_dma40_memcpy_init(dev);
-+ ret = bcm2838_dma40_memcpy_init();
- if (ret)
-- return ret;
-+ return ret;
-
- device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
- if (!device_info) {
-@@ -509,9 +509,8 @@ int brcm_pcie_bounce_register_dev(struct
- device_create_file(dev, &dev_attr_dmabounce_stats));
-
- g_dmabounce_device_info = device_info;
-- set_dma_ops(dev, &dmabounce_ops);
-
-- dev_info(dev, "dmabounce: registered device - %ld kB, threshold %pad\n",
-+ dev_info(dev, "dmabounce: initialised - %ld kB, threshold %pad\n",
- buffer_size / 1024, &threshold);
-
- return 0;
-@@ -520,14 +519,13 @@ int brcm_pcie_bounce_register_dev(struct
- kfree(device_info);
- return ret;
- }
--EXPORT_SYMBOL(brcm_pcie_bounce_register_dev);
-+EXPORT_SYMBOL(brcm_pcie_bounce_init);
-
--void brcm_pcie_bounce_unregister_dev(struct device *dev)
-+void brcm_pcie_bounce_uninit(struct device *dev)
- {
- struct dmabounce_device_info *device_info = g_dmabounce_device_info;
-
- g_dmabounce_device_info = NULL;
-- set_dma_ops(dev, NULL);
-
- if (!device_info) {
- dev_warn(dev,
-@@ -548,10 +546,16 @@ void brcm_pcie_bounce_unregister_dev(str
- device_remove_file(dev, &dev_attr_dmabounce_stats));
-
- kfree(device_info);
-+}
-+EXPORT_SYMBOL(brcm_pcie_bounce_uninit);
-+
-+int brcm_pcie_bounce_register_dev(struct device *dev)
-+{
-+ set_dma_ops(dev, &dmabounce_ops);
-
-- dev_info(dev, "dmabounce: device unregistered\n");
-+ return 0;
- }
--EXPORT_SYMBOL(brcm_pcie_bounce_unregister_dev);
-+EXPORT_SYMBOL(brcm_pcie_bounce_register_dev);
-
- MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.org>");
- MODULE_DESCRIPTION("Dedicate DMA bounce support for pcie-brcmstb");
---- a/drivers/pci/controller/pcie-brcmstb-bounce.h
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce.h
-@@ -8,21 +8,26 @@
-
- #ifdef CONFIG_ARM
-
--int brcm_pcie_bounce_register_dev(struct device *dev, unsigned long buffer_size,
-- dma_addr_t threshold);
--
--int brcm_pcie_bounce_unregister_dev(struct device *dev);
-+int brcm_pcie_bounce_init(struct device *dev, unsigned long buffer_size,
-+ dma_addr_t threshold);
-+int brcm_pcie_bounce_uninit(struct device *dev);
-+int brcm_pcie_bounce_register_dev(struct device *dev);
-
- #else
-
--static inline int brcm_pcie_bounce_register_dev(struct device *dev,
-- unsigned long buffer_size,
-- dma_addr_t threshold)
-+static inline int brcm_pcie_bounce_init(struct device *dev,
-+ unsigned long buffer_size,
-+ dma_addr_t threshold)
-+{
-+ return 0;
-+}
-+
-+static inline int brcm_pcie_bounce_uninit(struct device *dev)
- {
- return 0;
- }
-
--static inline int brcm_pcie_bounce_unregister_dev(struct device *dev)
-+static inline int brcm_pcie_bounce_register_dev(struct device *dev)
- {
- return 0;
- }
---- a/drivers/pci/controller/pcie-brcmstb.c
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -644,6 +644,7 @@ static void brcm_set_dma_ops(struct devi
-
- static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie,
- unsigned int val);
-+
- static int brcmstb_platform_notifier(struct notifier_block *nb,
- unsigned long event, void *__dev)
- {
-@@ -657,12 +658,11 @@ static int brcmstb_platform_notifier(str
- strcmp(dev->kobj.name, rc_name)) {
- int ret;
-
-- ret = brcm_pcie_bounce_register_dev(dev, bounce_buffer,
-- (dma_addr_t)bounce_threshold);
-+ ret = brcm_pcie_bounce_register_dev(dev);
- if (ret) {
- dev_err(dev,
- "brcm_pcie_bounce_register_dev() failed: %d\n",
-- ret);
-+ ret);
- return ret;
- }
- }
-@@ -675,8 +675,6 @@ static int brcmstb_platform_notifier(str
- brcm_pcie_perst_set(g_pcie, 1);
- msleep(100);
- brcm_pcie_perst_set(g_pcie, 0);
-- } else if (max_pfn > (bounce_threshold/PAGE_SIZE)) {
-- brcm_pcie_bounce_unregister_dev(dev);
- }
- return NOTIFY_OK;
-
-@@ -1712,6 +1710,7 @@ static int brcm_pcie_probe(struct platfo
- void __iomem *base;
- struct pci_host_bridge *bridge;
- struct pci_bus *child;
-+ extern unsigned long max_pfn;
-
- bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie));
- if (!bridge)
-@@ -1747,6 +1746,20 @@ static int brcm_pcie_probe(struct platfo
- if (IS_ERR(base))
- return PTR_ERR(base);
-
-+ /* To Do: Add hardware check if this ever gets fixed */
-+ if (max_pfn > (bounce_threshold/PAGE_SIZE)) {
-+ int ret;
-+ ret = brcm_pcie_bounce_init(&pdev->dev, bounce_buffer,
-+ (dma_addr_t)bounce_threshold);
-+ if (ret) {
-+ if (ret != -EPROBE_DEFER)
-+ dev_err(&pdev->dev,
-+ "could not init bounce buffers: %d\n",
-+ ret);
-+ return ret;
-+ }
-+ }
-+
- pcie->clk = of_clk_get_by_name(dn, "sw_pcie");
- if (IS_ERR(pcie->clk)) {
- dev_warn(&pdev->dev, "could not get clock\n");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0284-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0276-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch
index b5358cef29..b5358cef29 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0284-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0276-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch
index ce73e34541..ce73e34541 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0278-drm-vc4-Add-support-for-margins-to-fkms.patch
index 968eb3ff55..968eb3ff55 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0278-drm-vc4-Add-support-for-margins-to-fkms.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0278-pcie-brcmstb-Don-t-set-DMA-ops-for-root-complex.patch b/target/linux/bcm27xx/patches-5.4/950-0278-pcie-brcmstb-Don-t-set-DMA-ops-for-root-complex.patch
deleted file mode 100644
index 91ca6406b3..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0278-pcie-brcmstb-Don-t-set-DMA-ops-for-root-complex.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 510a127017a0aada2734dbf57d25aaa0189198ff Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 7 Aug 2019 17:19:33 +0100
-Subject: [PATCH] pcie-brcmstb: Don't set DMA ops for root complex
-
-A change to arm_get_dma_map_ops has stopped get_dma_ops from working
-on the root complex, causing an error to be logged. However, there is
-no need to override the DMA ops in that case, so skip it and
-eliminate the error message.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/pci/controller/pcie-brcmstb.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pci/controller/pcie-brcmstb.c
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -665,8 +665,8 @@ static int brcmstb_platform_notifier(str
- ret);
- return ret;
- }
-+ brcm_set_dma_ops(dev);
- }
-- brcm_set_dma_ops(dev);
- return NOTIFY_OK;
-
- case BUS_NOTIFY_DEL_DEVICE:
diff --git a/target/linux/bcm27xx/patches-5.4/950-0287-drm-vc4-Ensure-zpos-is-always-initialised.patch b/target/linux/bcm27xx/patches-5.4/950-0279-drm-vc4-Ensure-zpos-is-always-initialised.patch
index 32a13d9c86..32a13d9c86 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0287-drm-vc4-Ensure-zpos-is-always-initialised.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0279-drm-vc4-Ensure-zpos-is-always-initialised.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0288-adds-the-Hifiberry-DAC-ADC-PRO-version.patch b/target/linux/bcm27xx/patches-5.4/950-0280-adds-the-Hifiberry-DAC-ADC-PRO-version.patch
index ed6d6db813..ed6d6db813 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0288-adds-the-Hifiberry-DAC-ADC-PRO-version.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0280-adds-the-Hifiberry-DAC-ADC-PRO-version.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0289-drm-vc4-A-present-but-empty-dmas-disables-audio.patch b/target/linux/bcm27xx/patches-5.4/950-0281-drm-vc4-A-present-but-empty-dmas-disables-audio.patch
index 84b044eb63..84b044eb63 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0289-drm-vc4-A-present-but-empty-dmas-disables-audio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0281-drm-vc4-A-present-but-empty-dmas-disables-audio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0290-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch b/target/linux/bcm27xx/patches-5.4/950-0282-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch
index 60c9c9b03f..60c9c9b03f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0290-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0282-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0283-Ported-pcie-brcmstb-bounce-buffer-implementation-to-.patch b/target/linux/bcm27xx/patches-5.4/950-0283-Ported-pcie-brcmstb-bounce-buffer-implementation-to-.patch
deleted file mode 100644
index aa8d0526ba..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0283-Ported-pcie-brcmstb-bounce-buffer-implementation-to-.patch
+++ /dev/null
@@ -1,713 +0,0 @@
-From 60f3db31d4cb785befed715b80c430f60f647701 Mon Sep 17 00:00:00 2001
-From: yaroslavros <yaroslavros@gmail.com>
-Date: Wed, 14 Aug 2019 15:22:55 +0100
-Subject: [PATCH] Ported pcie-brcmstb bounce buffer implementation to
- ARM64. (#3144)
-
-Ported pcie-brcmstb bounce buffer implementation to ARM64.
-This enables full 4G RAM usage on Raspberry Pi in 64-bit mode.
-
-Signed-off-by: Yaroslav Rosomakho <yaroslavros@gmail.com>
----
- arch/arm64/mm/dma-mapping.c | 29 +
- drivers/pci/controller/Makefile | 3 +
- drivers/pci/controller/pcie-brcmstb-bounce.h | 2 +-
- .../pci/controller/pcie-brcmstb-bounce64.c | 569 ++++++++++++++++++
- drivers/pci/controller/pcie-brcmstb.c | 32 +-
- 5 files changed, 610 insertions(+), 25 deletions(-)
- create mode 100644 drivers/pci/controller/pcie-brcmstb-bounce64.c
-
---- a/arch/arm64/mm/dma-mapping.c
-+++ b/arch/arm64/mm/dma-mapping.c
-@@ -31,6 +31,35 @@ void arch_dma_prep_coherent(struct page
- }
-
- #ifdef CONFIG_IOMMU_DMA
-+static int __swiotlb_get_sgtable_page(struct sg_table *sgt,
-+ struct page *page, size_t size)
-+{
-+ int ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
-+
-+ if (!ret)
-+ sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
-+
-+ return ret;
-+}
-+
-+static int __swiotlb_mmap_pfn(struct vm_area_struct *vma,
-+ unsigned long pfn, size_t size)
-+{
-+ int ret = -ENXIO;
-+ unsigned long nr_vma_pages = vma_pages(vma);
-+ unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
-+ unsigned long off = vma->vm_pgoff;
-+
-+ if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
-+ ret = remap_pfn_range(vma, vma->vm_start,
-+ pfn + off,
-+ vma->vm_end - vma->vm_start,
-+ vma->vm_page_prot);
-+ }
-+
-+ return ret;
-+}
-+
- void arch_teardown_dma_ops(struct device *dev)
- {
- dev->dma_ops = NULL;
---- a/drivers/pci/controller/Makefile
-+++ b/drivers/pci/controller/Makefile
-@@ -33,6 +33,9 @@ obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcms
- ifdef CONFIG_ARM
- obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb-bounce.o
- endif
-+ifdef CONFIG_ARM64
-+obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb-bounce64.o
-+endif
-
- obj-$(CONFIG_VMD) += vmd.o
- # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
---- a/drivers/pci/controller/pcie-brcmstb-bounce.h
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce.h
-@@ -6,7 +6,7 @@
- #ifndef _PCIE_BRCMSTB_BOUNCE_H
- #define _PCIE_BRCMSTB_BOUNCE_H
-
--#ifdef CONFIG_ARM
-+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
-
- int brcm_pcie_bounce_init(struct device *dev, unsigned long buffer_size,
- dma_addr_t threshold);
---- /dev/null
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce64.c
-@@ -0,0 +1,569 @@
-+/*
-+ * This code started out as a version of arch/arm/common/dmabounce.c,
-+ * modified to cope with highmem pages. Now it has been changed heavily -
-+ * it now preallocates a large block (currently 4MB) and carves it up
-+ * sequentially in ring fashion, and DMA is used to copy the data - to the
-+ * point where very little of the original remains.
-+ *
-+ * Copyright (C) 2019 Raspberry Pi (Trading) Ltd.
-+ *
-+ * Original version by Brad Parker (brad@heeltoe.com)
-+ * Re-written by Christopher Hoover <ch@murgatroid.com>
-+ * Made generic by Deepak Saxena <dsaxena@plexity.net>
-+ *
-+ * Copyright (C) 2002 Hewlett Packard Company.
-+ * Copyright (C) 2004 MontaVista Software, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/page-flags.h>
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dma-direct.h>
-+#include <linux/dma-noncoherent.h>
-+#include <linux/dmapool.h>
-+#include <linux/list.h>
-+#include <linux/scatterlist.h>
-+#include <linux/bitmap.h>
-+#include <linux/swiotlb.h>
-+
-+#include <asm/cacheflush.h>
-+
-+#define STATS
-+
-+#ifdef STATS
-+#define DO_STATS(X) do { X ; } while (0)
-+#else
-+#define DO_STATS(X) do { } while (0)
-+#endif
-+
-+/* ************************************************** */
-+
-+struct safe_buffer {
-+ struct list_head node;
-+
-+ /* original request */
-+ size_t size;
-+ int direction;
-+
-+ struct dmabounce_pool *pool;
-+ void *safe;
-+ dma_addr_t unsafe_dma_addr;
-+ dma_addr_t safe_dma_addr;
-+};
-+
-+struct dmabounce_pool {
-+ unsigned long pages;
-+ void *virt_addr;
-+ dma_addr_t dma_addr;
-+ unsigned long *alloc_map;
-+ unsigned long alloc_pos;
-+ spinlock_t lock;
-+ struct device *dev;
-+ unsigned long num_pages;
-+#ifdef STATS
-+ size_t max_size;
-+ unsigned long num_bufs;
-+ unsigned long max_bufs;
-+ unsigned long max_pages;
-+#endif
-+};
-+
-+struct dmabounce_device_info {
-+ struct device *dev;
-+ dma_addr_t threshold;
-+ struct list_head safe_buffers;
-+ struct dmabounce_pool pool;
-+ rwlock_t lock;
-+#ifdef STATS
-+ unsigned long map_count;
-+ unsigned long unmap_count;
-+ unsigned long sync_dev_count;
-+ unsigned long sync_cpu_count;
-+ unsigned long fail_count;
-+ int attr_res;
-+#endif
-+};
-+
-+static struct dmabounce_device_info *g_dmabounce_device_info;
-+
-+extern int bcm2838_dma40_memcpy_init(void);
-+extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size);
-+
-+#ifdef STATS
-+static ssize_t
-+bounce_show(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+ struct dmabounce_device_info *device_info = g_dmabounce_device_info;
-+ return sprintf(buf, "m:%lu/%lu s:%lu/%lu f:%lu s:%zu b:%lu/%lu a:%lu/%lu\n",
-+ device_info->map_count,
-+ device_info->unmap_count,
-+ device_info->sync_dev_count,
-+ device_info->sync_cpu_count,
-+ device_info->fail_count,
-+ device_info->pool.max_size,
-+ device_info->pool.num_bufs,
-+ device_info->pool.max_bufs,
-+ device_info->pool.num_pages * PAGE_SIZE,
-+ device_info->pool.max_pages * PAGE_SIZE);
-+}
-+
-+static DEVICE_ATTR(dmabounce_stats, 0444, bounce_show, NULL);
-+#endif
-+
-+static int bounce_create(struct dmabounce_pool *pool, struct device *dev,
-+ unsigned long buffer_size)
-+{
-+ int ret = -ENOMEM;
-+ pool->pages = (buffer_size + PAGE_SIZE - 1)/PAGE_SIZE;
-+ pool->alloc_map = bitmap_zalloc(pool->pages, GFP_KERNEL);
-+ if (!pool->alloc_map)
-+ goto err_bitmap;
-+ pool->virt_addr = dma_alloc_coherent(dev, pool->pages * PAGE_SIZE,
-+ &pool->dma_addr, GFP_KERNEL);
-+ if (!pool->virt_addr)
-+ goto err_dmabuf;
-+
-+ pool->alloc_pos = 0;
-+ spin_lock_init(&pool->lock);
-+ pool->dev = dev;
-+ pool->num_pages = 0;
-+
-+ DO_STATS(pool->max_size = 0);
-+ DO_STATS(pool->num_bufs = 0);
-+ DO_STATS(pool->max_bufs = 0);
-+ DO_STATS(pool->max_pages = 0);
-+
-+ return 0;
-+
-+err_dmabuf:
-+ bitmap_free(pool->alloc_map);
-+err_bitmap:
-+ return ret;
-+}
-+
-+static void bounce_destroy(struct dmabounce_pool *pool)
-+{
-+ dma_free_coherent(pool->dev, pool->pages * PAGE_SIZE, pool->virt_addr,
-+ pool->dma_addr);
-+
-+ bitmap_free(pool->alloc_map);
-+}
-+
-+static void *bounce_alloc(struct dmabounce_pool *pool, size_t size,
-+ dma_addr_t *dmaaddrp)
-+{
-+ unsigned long pages;
-+ unsigned long flags;
-+ unsigned long pos;
-+
-+ pages = (size + PAGE_SIZE - 1)/PAGE_SIZE;
-+
-+ DO_STATS(pool->max_size = max(size, pool->max_size));
-+
-+ spin_lock_irqsave(&pool->lock, flags);
-+ pos = bitmap_find_next_zero_area(pool->alloc_map, pool->pages,
-+ pool->alloc_pos, pages, 0);
-+ /* If not found, try from the start */
-+ if (pos >= pool->pages && pool->alloc_pos)
-+ pos = bitmap_find_next_zero_area(pool->alloc_map, pool->pages,
-+ 0, pages, 0);
-+
-+ if (pos >= pool->pages) {
-+ spin_unlock_irqrestore(&pool->lock, flags);
-+ return NULL;
-+ }
-+
-+ bitmap_set(pool->alloc_map, pos, pages);
-+ pool->alloc_pos = (pos + pages) % pool->pages;
-+ pool->num_pages += pages;
-+
-+ DO_STATS(pool->num_bufs++);
-+ DO_STATS(pool->max_bufs = max(pool->num_bufs, pool->max_bufs));
-+ DO_STATS(pool->max_pages = max(pool->num_pages, pool->max_pages));
-+
-+ spin_unlock_irqrestore(&pool->lock, flags);
-+
-+ *dmaaddrp = pool->dma_addr + pos * PAGE_SIZE;
-+
-+ return pool->virt_addr + pos * PAGE_SIZE;
-+}
-+
-+static void
-+bounce_free(struct dmabounce_pool *pool, void *buf, size_t size)
-+{
-+ unsigned long pages;
-+ unsigned long flags;
-+ unsigned long pos;
-+
-+ pages = (size + PAGE_SIZE - 1)/PAGE_SIZE;
-+ pos = (buf - pool->virt_addr)/PAGE_SIZE;
-+
-+ BUG_ON((buf - pool->virt_addr) & (PAGE_SIZE - 1));
-+
-+ spin_lock_irqsave(&pool->lock, flags);
-+ bitmap_clear(pool->alloc_map, pos, pages);
-+ pool->num_pages -= pages;
-+ if (pool->num_pages == 0)
-+ pool->alloc_pos = 0;
-+ DO_STATS(pool->num_bufs--);
-+ spin_unlock_irqrestore(&pool->lock, flags);
-+}
-+
-+/* allocate a 'safe' buffer and keep track of it */
-+static struct safe_buffer *
-+alloc_safe_buffer(struct dmabounce_device_info *device_info,
-+ dma_addr_t dma_addr, size_t size, enum dma_data_direction dir)
-+{
-+ struct safe_buffer *buf;
-+ struct dmabounce_pool *pool = &device_info->pool;
-+ struct device *dev = device_info->dev;
-+ unsigned long flags;
-+
-+ /*
-+ * Although one might expect this to be called in thread context,
-+ * using GFP_KERNEL here leads to hard-to-debug lockups. in_atomic()
-+ * was previously used to select the appropriate allocation mode,
-+ * but this is unsafe.
-+ */
-+ buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
-+ if (!buf) {
-+ dev_warn(dev, "%s: kmalloc failed\n", __func__);
-+ return NULL;
-+ }
-+
-+ buf->unsafe_dma_addr = dma_addr;
-+ buf->size = size;
-+ buf->direction = dir;
-+ buf->pool = pool;
-+
-+ buf->safe = bounce_alloc(pool, size, &buf->safe_dma_addr);
-+
-+ if (!buf->safe) {
-+ dev_warn(dev,
-+ "%s: could not alloc dma memory (size=%zu)\n",
-+ __func__, size);
-+ kfree(buf);
-+ return NULL;
-+ }
-+
-+ write_lock_irqsave(&device_info->lock, flags);
-+ list_add(&buf->node, &device_info->safe_buffers);
-+ write_unlock_irqrestore(&device_info->lock, flags);
-+
-+ return buf;
-+}
-+
-+/* determine if a buffer is from our "safe" pool */
-+static struct safe_buffer *
-+find_safe_buffer(struct dmabounce_device_info *device_info,
-+ dma_addr_t safe_dma_addr)
-+{
-+ struct safe_buffer *b, *rb = NULL;
-+ unsigned long flags;
-+
-+ read_lock_irqsave(&device_info->lock, flags);
-+
-+ list_for_each_entry(b, &device_info->safe_buffers, node)
-+ if (b->safe_dma_addr <= safe_dma_addr &&
-+ b->safe_dma_addr + b->size > safe_dma_addr) {
-+ rb = b;
-+ break;
-+ }
-+
-+ read_unlock_irqrestore(&device_info->lock, flags);
-+ return rb;
-+}
-+
-+static void
-+free_safe_buffer(struct dmabounce_device_info *device_info,
-+ struct safe_buffer *buf)
-+{
-+ unsigned long flags;
-+
-+ write_lock_irqsave(&device_info->lock, flags);
-+ list_del(&buf->node);
-+ write_unlock_irqrestore(&device_info->lock, flags);
-+
-+ bounce_free(buf->pool, buf->safe, buf->size);
-+
-+ kfree(buf);
-+}
-+
-+/* ************************************************** */
-+
-+static struct safe_buffer *
-+find_safe_buffer_dev(struct device *dev, dma_addr_t dma_addr, const char *where)
-+{
-+ if (!dev || !g_dmabounce_device_info)
-+ return NULL;
-+ if (dma_mapping_error(dev, dma_addr)) {
-+ dev_err(dev, "Trying to %s invalid mapping\n", where);
-+ return NULL;
-+ }
-+ return find_safe_buffer(g_dmabounce_device_info, dma_addr);
-+}
-+
-+static dma_addr_t
-+map_single(struct device *dev, struct safe_buffer *buf, size_t size,
-+ enum dma_data_direction dir, unsigned long attrs)
-+{
-+ BUG_ON(buf->size != size);
-+ BUG_ON(buf->direction != dir);
-+
-+ dev_dbg(dev, "map: %llx->%llx\n", (u64)buf->unsafe_dma_addr,
-+ (u64)buf->safe_dma_addr);
-+
-+ if ((dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) &&
-+ !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-+ bcm2838_dma40_memcpy(buf->safe_dma_addr, buf->unsafe_dma_addr,
-+ size);
-+
-+ return buf->safe_dma_addr;
-+}
-+
-+static dma_addr_t
-+unmap_single(struct device *dev, struct safe_buffer *buf, size_t size,
-+ enum dma_data_direction dir, unsigned long attrs)
-+{
-+ BUG_ON(buf->size != size);
-+ BUG_ON(buf->direction != dir);
-+
-+ if ((dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) &&
-+ !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) {
-+ dev_dbg(dev, "unmap: %llx->%llx\n", (u64)buf->safe_dma_addr,
-+ (u64)buf->unsafe_dma_addr);
-+
-+ bcm2838_dma40_memcpy(buf->unsafe_dma_addr, buf->safe_dma_addr,
-+ size);
-+ }
-+ return buf->unsafe_dma_addr;
-+}
-+
-+/* ************************************************** */
-+
-+/*
-+ * see if a buffer address is in an 'unsafe' range. if it is
-+ * allocate a 'safe' buffer and copy the unsafe buffer into it.
-+ * substitute the safe buffer for the unsafe one.
-+ * (basically move the buffer from an unsafe area to a safe one)
-+ */
-+static dma_addr_t
-+dmabounce_map_page(struct device *dev, struct page *page, unsigned long offset,
-+ size_t size, enum dma_data_direction dir,
-+ unsigned long attrs)
-+{
-+ struct dmabounce_device_info *device_info = g_dmabounce_device_info;
-+ dma_addr_t dma_addr;
-+
-+ dma_addr = phys_to_dma(dev, page_to_phys(page)) + offset;
-+
-+ dma_direct_sync_single_for_device(dev, dma_addr, size, dir);
-+ if (!dev_is_dma_coherent(dev))
-+ __dma_map_area(phys_to_virt(dma_to_phys(dev, dma_addr)), size, dir);
-+
-+ if (device_info && (dma_addr + size) > device_info->threshold) {
-+ struct safe_buffer *buf;
-+
-+ buf = alloc_safe_buffer(device_info, dma_addr, size, dir);
-+ if (!buf) {
-+ DO_STATS(device_info->fail_count++);
-+ return (~(dma_addr_t)0x0);
-+ }
-+
-+ DO_STATS(device_info->map_count++);
-+
-+ dma_addr = map_single(dev, buf, size, dir, attrs);
-+ }
-+ return dma_addr;
-+}
-+
-+/*
-+ * see if a mapped address was really a "safe" buffer and if so, copy
-+ * the data from the safe buffer back to the unsafe buffer and free up
-+ * the safe buffer. (basically return things back to the way they
-+ * should be)
-+ */
-+static void
-+dmabounce_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
-+ enum dma_data_direction dir, unsigned long attrs)
-+{
-+ struct safe_buffer *buf;
-+
-+ buf = find_safe_buffer_dev(dev, dma_addr, __func__);
-+ if (buf) {
-+ DO_STATS(g_dmabounce_device_info->unmap_count++);
-+ dma_addr = unmap_single(dev, buf, size, dir, attrs);
-+ free_safe_buffer(g_dmabounce_device_info, buf);
-+ }
-+
-+ if (!dev_is_dma_coherent(dev))
-+ __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dma_addr)), size, dir);
-+ dma_direct_sync_single_for_cpu(dev, dma_addr, size, dir);
-+}
-+
-+/*
-+ * A version of dmabounce_map_page that assumes the mapping has already
-+ * been created - intended for streaming operation.
-+ */
-+static void
-+dmabounce_sync_for_device(struct device *dev, dma_addr_t dma_addr, size_t size,
-+ enum dma_data_direction dir)
-+{
-+ struct safe_buffer *buf;
-+
-+ dma_direct_sync_single_for_device(dev, dma_addr, size, dir);
-+ if (!dev_is_dma_coherent(dev))
-+ __dma_map_area(phys_to_virt(dma_to_phys(dev, dma_addr)), size, dir);
-+
-+ buf = find_safe_buffer_dev(dev, dma_addr, __func__);
-+ if (buf) {
-+ DO_STATS(g_dmabounce_device_info->sync_dev_count++);
-+ map_single(dev, buf, size, dir, 0);
-+ }
-+}
-+
-+/*
-+ * A version of dmabounce_unmap_page that doesn't destroy the mapping -
-+ * intended for streaming operation.
-+ */
-+static void
-+dmabounce_sync_for_cpu(struct device *dev, dma_addr_t dma_addr,
-+ size_t size, enum dma_data_direction dir)
-+{
-+ struct safe_buffer *buf;
-+
-+ buf = find_safe_buffer_dev(dev, dma_addr, __func__);
-+ if (buf) {
-+ DO_STATS(g_dmabounce_device_info->sync_cpu_count++);
-+ dma_addr = unmap_single(dev, buf, size, dir, 0);
-+ }
-+
-+ if (!dev_is_dma_coherent(dev))
-+ __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dma_addr)), size, dir);
-+ dma_direct_sync_single_for_cpu(dev, dma_addr, size, dir);
-+}
-+
-+static int dmabounce_dma_supported(struct device *dev, u64 dma_mask)
-+{
-+ if (g_dmabounce_device_info)
-+ return 0;
-+
-+ return dma_direct_supported(dev, dma_mask);
-+}
-+
-+static const struct dma_map_ops dmabounce_ops = {
-+ .alloc = dma_direct_alloc,
-+ .free = dma_direct_free,
-+ .map_page = dmabounce_map_page,
-+ .unmap_page = dmabounce_unmap_page,
-+ .sync_single_for_cpu = dmabounce_sync_for_cpu,
-+ .sync_single_for_device = dmabounce_sync_for_device,
-+ .map_sg = dma_direct_map_sg,
-+ .unmap_sg = dma_direct_unmap_sg,
-+ .sync_sg_for_cpu = dma_direct_sync_sg_for_cpu,
-+ .sync_sg_for_device = dma_direct_sync_sg_for_device,
-+ .dma_supported = dmabounce_dma_supported,
-+};
-+
-+int brcm_pcie_bounce_init(struct device *dev,
-+ unsigned long buffer_size,
-+ dma_addr_t threshold)
-+{
-+ struct dmabounce_device_info *device_info;
-+ int ret;
-+
-+ /* Only support a single client */
-+ if (g_dmabounce_device_info)
-+ return -EBUSY;
-+
-+ ret = bcm2838_dma40_memcpy_init();
-+ if (ret)
-+ return ret;
-+
-+ device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
-+ if (!device_info) {
-+ dev_err(dev,
-+ "Could not allocated dmabounce_device_info\n");
-+ return -ENOMEM;
-+ }
-+
-+ ret = bounce_create(&device_info->pool, dev, buffer_size);
-+ if (ret) {
-+ dev_err(dev,
-+ "dmabounce: could not allocate %ld byte DMA pool\n",
-+ buffer_size);
-+ goto err_bounce;
-+ }
-+
-+ device_info->dev = dev;
-+ device_info->threshold = threshold;
-+ INIT_LIST_HEAD(&device_info->safe_buffers);
-+ rwlock_init(&device_info->lock);
-+
-+ DO_STATS(device_info->map_count = 0);
-+ DO_STATS(device_info->unmap_count = 0);
-+ DO_STATS(device_info->sync_dev_count = 0);
-+ DO_STATS(device_info->sync_cpu_count = 0);
-+ DO_STATS(device_info->fail_count = 0);
-+ DO_STATS(device_info->attr_res =
-+ device_create_file(dev, &dev_attr_dmabounce_stats));
-+
-+ g_dmabounce_device_info = device_info;
-+
-+ dev_err(dev, "dmabounce: initialised - %ld kB, threshold %pad\n",
-+ buffer_size / 1024, &threshold);
-+
-+ return 0;
-+
-+ err_bounce:
-+ kfree(device_info);
-+ return ret;
-+}
-+EXPORT_SYMBOL(brcm_pcie_bounce_init);
-+
-+void brcm_pcie_bounce_uninit(struct device *dev)
-+{
-+ struct dmabounce_device_info *device_info = g_dmabounce_device_info;
-+
-+ g_dmabounce_device_info = NULL;
-+
-+ if (!device_info) {
-+ dev_warn(dev,
-+ "Never registered with dmabounce but attempting"
-+ "to unregister!\n");
-+ return;
-+ }
-+
-+ if (!list_empty(&device_info->safe_buffers)) {
-+ dev_err(dev,
-+ "Removing from dmabounce with pending buffers!\n");
-+ BUG();
-+ }
-+
-+ bounce_destroy(&device_info->pool);
-+
-+ DO_STATS(if (device_info->attr_res == 0)
-+ device_remove_file(dev, &dev_attr_dmabounce_stats));
-+
-+ kfree(device_info);
-+}
-+EXPORT_SYMBOL(brcm_pcie_bounce_uninit);
-+
-+int brcm_pcie_bounce_register_dev(struct device *dev)
-+{
-+ set_dma_ops(dev, &dmabounce_ops);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(brcm_pcie_bounce_register_dev);
-+
-+MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.org>");
-+MODULE_DESCRIPTION("Dedicate DMA bounce support for pcie-brcmstb");
-+MODULE_LICENSE("GPL");
---- a/drivers/pci/controller/pcie-brcmstb.c
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -611,28 +611,6 @@ static const struct dma_map_ops brcm_dma
-
- static void brcm_set_dma_ops(struct device *dev)
- {
-- int ret;
--
-- if (IS_ENABLED(CONFIG_ARM64)) {
-- /*
-- * We are going to invoke get_dma_ops(). That
-- * function, at this point in time, invokes
-- * get_arch_dma_ops(), and for ARM64 that function
-- * returns a pointer to dummy_dma_ops. So then we'd
-- * like to call arch_setup_dma_ops(), but that isn't
-- * exported. Instead, we call of_dma_configure(),
-- * which is exported, and this calls
-- * arch_setup_dma_ops(). Once we do this the call to
-- * get_dma_ops() will work properly because
-- * dev->dma_ops will be set.
-- */
-- ret = of_dma_configure(dev, dev->of_node, true);
-- if (ret) {
-- dev_err(dev, "of_dma_configure() failed: %d\n", ret);
-- return;
-- }
-- }
--
- arch_dma_ops = get_dma_ops(dev);
- if (!arch_dma_ops) {
- dev_err(dev, "failed to get arch_dma_ops\n");
-@@ -651,12 +629,12 @@ static int brcmstb_platform_notifier(str
- extern unsigned long max_pfn;
- struct device *dev = __dev;
- const char *rc_name = "0000:00:00.0";
-+ int ret;
-
- switch (event) {
- case BUS_NOTIFY_ADD_DEVICE:
- if (max_pfn > (bounce_threshold/PAGE_SIZE) &&
- strcmp(dev->kobj.name, rc_name)) {
-- int ret;
-
- ret = brcm_pcie_bounce_register_dev(dev);
- if (ret) {
-@@ -665,8 +643,14 @@ static int brcmstb_platform_notifier(str
- ret);
- return ret;
- }
-- brcm_set_dma_ops(dev);
-+ } else if (IS_ENABLED(CONFIG_ARM64)) {
-+ ret = of_dma_configure(dev, dev->of_node, true);
-+ if (ret) {
-+ dev_err(dev, "of_dma_configure() failed: %d\n", ret);
-+ return ret;
-+ }
- }
-+ brcm_set_dma_ops(dev);
- return NOTIFY_OK;
-
- case BUS_NOTIFY_DEL_DEVICE:
diff --git a/target/linux/bcm27xx/patches-5.4/950-0291-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch b/target/linux/bcm27xx/patches-5.4/950-0283-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch
index 3f3c5ea148..3f3c5ea148 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0291-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0283-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0292-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/bcm27xx/patches-5.4/950-0284-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
index 1843ebdce0..1843ebdce0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0292-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0284-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0293-drm-vc4-Add-Broadcast-RGB-connector-property.patch b/target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-Add-Broadcast-RGB-connector-property.patch
index e221e41189..e221e41189 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0293-drm-vc4-Add-Broadcast-RGB-connector-property.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-Add-Broadcast-RGB-connector-property.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0294-drm-vc4-fkms-Set-default-state-margin-at-reset.patch b/target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-fkms-Set-default-state-margin-at-reset.patch
index 51664f3f98..51664f3f98 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0294-drm-vc4-fkms-Set-default-state-margin-at-reset.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-fkms-Set-default-state-margin-at-reset.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0295-staging-bcm2835-codec-switch-to-multi-planar-API.patch b/target/linux/bcm27xx/patches-5.4/950-0287-staging-bcm2835-codec-switch-to-multi-planar-API.patch
index c4eab3a02a..c4eab3a02a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0295-staging-bcm2835-codec-switch-to-multi-planar-API.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0287-staging-bcm2835-codec-switch-to-multi-planar-API.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0296-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch b/target/linux/bcm27xx/patches-5.4/950-0288-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch
index 6e4af3e38d..6e4af3e38d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0296-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0288-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0297-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch b/target/linux/bcm27xx/patches-5.4/950-0289-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch
index a194eaba14..a194eaba14 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0297-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0289-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0298-Add-HDMI1-facility-to-the-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0290-Add-HDMI1-facility-to-the-driver.patch
index b18d1458fd..b18d1458fd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0298-Add-HDMI1-facility-to-the-driver.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0290-Add-HDMI1-facility-to-the-driver.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0299-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch b/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch
index e50bdee8ae..e50bdee8ae 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0299-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0300-drm-vc4-Remove-unused-mode-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0292-drm-vc4-Remove-unused-mode-variable.patch
index e82fc421d2..e82fc421d2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0300-drm-vc4-Remove-unused-mode-variable.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0292-drm-vc4-Remove-unused-mode-variable.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0301-staging-bcm2835-codec-Expand-logging-on-format-setti.patch b/target/linux/bcm27xx/patches-5.4/950-0293-staging-bcm2835-codec-Expand-logging-on-format-setti.patch
index d2ebeea7f7..d2ebeea7f7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0301-staging-bcm2835-codec-Expand-logging-on-format-setti.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0293-staging-bcm2835-codec-Expand-logging-on-format-setti.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Correct-bytesperline-on-format.patch b/target/linux/bcm27xx/patches-5.4/950-0294-staging-bcm2835-codec-Correct-bytesperline-on-format.patch
index eaba48466a..eaba48466a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Correct-bytesperline-on-format.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0294-staging-bcm2835-codec-Correct-bytesperline-on-format.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0303-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch b/target/linux/bcm27xx/patches-5.4/950-0295-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch
index f29ba4dc5d..f29ba4dc5d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0303-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0295-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0304-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch b/target/linux/bcm27xx/patches-5.4/950-0296-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch
index 73f92187f2..73f92187f2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0304-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0296-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0305-xhci-Use-more-event-ring-segment-table-entries.patch b/target/linux/bcm27xx/patches-5.4/950-0297-xhci-Use-more-event-ring-segment-table-entries.patch
index 4b4766f739..4b4766f739 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0305-xhci-Use-more-event-ring-segment-table-entries.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0297-xhci-Use-more-event-ring-segment-table-entries.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0306-configs-arm64-bcm2711-Enable-V3D.patch b/target/linux/bcm27xx/patches-5.4/950-0298-configs-arm64-bcm2711-Enable-V3D.patch
index f079fcf9ac..f079fcf9ac 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0306-configs-arm64-bcm2711-Enable-V3D.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0298-configs-arm64-bcm2711-Enable-V3D.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0307-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch b/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch
index 42baf4c7d4..42baf4c7d4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0307-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch b/target/linux/bcm27xx/patches-5.4/950-0300-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch
index d2a50860d2..d2a50860d2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0300-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0309-arch-arm-Add-model-string-to-cpuinfo.patch b/target/linux/bcm27xx/patches-5.4/950-0301-arch-arm-Add-model-string-to-cpuinfo.patch
index 83c1592df9..83c1592df9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0309-arch-arm-Add-model-string-to-cpuinfo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0301-arch-arm-Add-model-string-to-cpuinfo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0310-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch b/target/linux/bcm27xx/patches-5.4/950-0302-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch
index af76b81f31..af76b81f31 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0310-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0302-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0313-staging-bcm2835-codec-Fix-non-documentation-comment-.patch b/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-Fix-non-documentation-comment-.patch
index e1ec7d9e69..e1ec7d9e69 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0313-staging-bcm2835-codec-Fix-non-documentation-comment-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-Fix-non-documentation-comment-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0314-staging-bcm2835-codec-Fix-declaration-of-roles.patch b/target/linux/bcm27xx/patches-5.4/950-0304-staging-bcm2835-codec-Fix-declaration-of-roles.patch
index 6e544199ba..6e544199ba 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0314-staging-bcm2835-codec-Fix-declaration-of-roles.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0304-staging-bcm2835-codec-Fix-declaration-of-roles.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0315-staging-bcm2835-codec-Add-role-to-device-name.patch b/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-codec-Add-role-to-device-name.patch
index e1539f4a71..e1539f4a71 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0315-staging-bcm2835-codec-Add-role-to-device-name.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-codec-Add-role-to-device-name.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0316-staging-bcm2835-codec-Pass-driver-context-to-create-.patch b/target/linux/bcm27xx/patches-5.4/950-0306-staging-bcm2835-codec-Pass-driver-context-to-create-.patch
index a0b86db2d6..a0b86db2d6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0316-staging-bcm2835-codec-Pass-driver-context-to-create-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0306-staging-bcm2835-codec-Pass-driver-context-to-create-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0317-staging-bcm2835-codec-add-media-controller-support.patch b/target/linux/bcm27xx/patches-5.4/950-0307-staging-bcm2835-codec-add-media-controller-support.patch
index f0ac32340c..f0ac32340c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0317-staging-bcm2835-codec-add-media-controller-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0307-staging-bcm2835-codec-add-media-controller-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0318-v4l2-Add-a-Greyworld-AWB-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0308-v4l2-Add-a-Greyworld-AWB-mode.patch
index 459646e7e7..459646e7e7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0318-v4l2-Add-a-Greyworld-AWB-mode.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0308-v4l2-Add-a-Greyworld-AWB-mode.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0319-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0309-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch
index e29c3800c4..e29c3800c4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0319-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0309-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0320-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch b/target/linux/bcm27xx/patches-5.4/950-0310-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch
index f6391e0b96..f6391e0b96 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0320-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0310-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0321-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch b/target/linux/bcm27xx/patches-5.4/950-0311-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch
index 5855d0057b..5855d0057b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0321-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0311-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0311-media-dt-bindings-Add-binding-for-the-Sony-IMX219-se.patch b/target/linux/bcm27xx/patches-5.4/950-0311-media-dt-bindings-Add-binding-for-the-Sony-IMX219-se.patch
deleted file mode 100644
index 4fb64f57e7..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0311-media-dt-bindings-Add-binding-for-the-Sony-IMX219-se.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 7bd5937663a13ad17a04d8ca8ba1503d492cf42b Mon Sep 17 00:00:00 2001
-From: Dave Stevenson <dave.stevenson@raspberrypi.org>
-Date: Wed, 28 Aug 2019 13:34:30 +0100
-Subject: [PATCH] media: dt-bindings: Add binding for the Sony IMX219
- sensor
-
-The IMX219 is an 8MPix CSI2 sensor, supporting 2 or 4 data lanes.
-Document the binding for this device.
-
-Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
----
- .../devicetree/bindings/media/i2c/imx219.txt | 59 +++++++++++++++++++
- 1 file changed, 59 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/media/i2c/imx219.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/media/i2c/imx219.txt
-@@ -0,0 +1,59 @@
-+* Sony 1/4.0-Inch 8Mpixel CMOS Digital Image Sensor
-+
-+The Sony imx219 is a 1/4.0-inch CMOS active pixel digital image sensor with
-+an active array size of 3280H x 2464V. It is programmable through I2C
-+interface. The I2C address is fixed to 0x10 as per sensor data sheet.
-+Image data is sent through MIPI CSI-2, which is configured as either 2 or 4
-+data lanes.
-+
-+Required Properties:
-+- compatible: value should be "sony,imx219" for imx219 sensor
-+- reg: I2C bus address of the device
-+- clocks: reference to the xclk input clock.
-+- clock-names: should be "xclk".
-+- DOVDD-supply: Digital I/O voltage supply, 1.8 volts
-+- AVDD-supply: Analog voltage supply, 2.8 volts
-+- DVDD-supply: Digital core voltage supply, 1.2 volts
-+
-+Optional Properties:
-+- xclr-gpios: reference to the GPIO connected to the xclr pin, if any. Must be
-+ released after all supplies are applied.
-+ This is an active high signal to the imx219.
-+
-+The imx219 device node should contain one 'port' child node with
-+an 'endpoint' subnode. For further reading on port node refer to
-+Documentation/devicetree/bindings/media/video-interfaces.txt.
-+
-+Endpoint node required properties for CSI-2 connection are:
-+- remote-endpoint: a phandle to the bus receiver's endpoint node.
-+- clock-lanes: should be set to <0> (clock lane on hardware lane 0)
-+- data-lanes: should be set to <1 2>, or <1 2 3 4> (two or four lane CSI-2
-+ supported)
-+
-+Example:
-+ sensor@10 {
-+ compatible = "sony,imx219";
-+ reg = <0x10>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ clocks = <&imx219_clk>;
-+ clock-names = "xclk";
-+ xclr-gpios = <&gpio_sensor 0 0>;
-+ DOVDD-supply = <&vgen4_reg>; /* 1.8v */
-+ AVDD-supply = <&vgen3_reg>; /* 2.8v */
-+ DVDD-supply = <&vgen2_reg>; /* 1.2v */
-+
-+ imx219_clk: camera-clk {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <24000000>;
-+ };
-+
-+ port {
-+ sensor_out: endpoint {
-+ remote-endpoint = <&csiss_in>;
-+ clock-lanes = <0>;
-+ data-lanes = <1 2>;
-+ };
-+ };
-+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0322-staging-bcm2835-codec-Allow-height-of-1920.patch b/target/linux/bcm27xx/patches-5.4/950-0312-staging-bcm2835-codec-Allow-height-of-1920.patch
index 862737f383..862737f383 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0322-staging-bcm2835-codec-Allow-height-of-1920.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0312-staging-bcm2835-codec-Allow-height-of-1920.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0323-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch b/target/linux/bcm27xx/patches-5.4/950-0313-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch
index a91bcc3111..a91bcc3111 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0323-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0313-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0324-drm-v3d-Delete-pm_runtime-support.patch b/target/linux/bcm27xx/patches-5.4/950-0314-drm-v3d-Delete-pm_runtime-support.patch
index 642be233ad..642be233ad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0324-drm-v3d-Delete-pm_runtime-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0314-drm-v3d-Delete-pm_runtime-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0325-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch b/target/linux/bcm27xx/patches-5.4/950-0315-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch
index c7eccdeed4..c7eccdeed4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0325-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0315-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0326-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch b/target/linux/bcm27xx/patches-5.4/950-0316-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch
index 961c0cc92b..961c0cc92b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0326-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0316-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0327-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch b/target/linux/bcm27xx/patches-5.4/950-0317-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch
index d02902a9b3..d02902a9b3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0327-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0317-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0328-dma-direct-Temporary-DMA-fix-on-arm64.patch b/target/linux/bcm27xx/patches-5.4/950-0318-dma-direct-Temporary-DMA-fix-on-arm64.patch
index e368ae6cd9..e368ae6cd9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0328-dma-direct-Temporary-DMA-fix-on-arm64.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0318-dma-direct-Temporary-DMA-fix-on-arm64.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0329-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch b/target/linux/bcm27xx/patches-5.4/950-0319-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch
index 254a621c83..254a621c83 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0329-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0319-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0330-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch b/target/linux/bcm27xx/patches-5.4/950-0320-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch
index 2ad17cb17c..2ad17cb17c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0330-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0320-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0331-vchiq_2835_arm-suppress-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0321-vchiq_2835_arm-suppress-warning.patch
index 1be935caf4..1be935caf4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0331-vchiq_2835_arm-suppress-warning.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0321-vchiq_2835_arm-suppress-warning.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0332-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch b/target/linux/bcm27xx/patches-5.4/950-0322-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch
index 8ec836621d..8ec836621d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0332-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0322-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0334-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch b/target/linux/bcm27xx/patches-5.4/950-0323-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch
index ff55c5677c..ff55c5677c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0334-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0323-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0335-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch b/target/linux/bcm27xx/patches-5.4/950-0324-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch
index f98002e99c..f98002e99c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0335-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0324-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0336-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch b/target/linux/bcm27xx/patches-5.4/950-0325-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch
index 6f487bf7c6..6f487bf7c6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0336-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0325-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0337-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch b/target/linux/bcm27xx/patches-5.4/950-0326-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch
index 5ea4797bcd..71e218d9ec 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0337-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0326-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch
@@ -21,7 +21,7 @@ Signed-off-by: Markus Proeller <markus.proeller@pieye.org>
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
-@@ -850,6 +850,18 @@ config VIDEO_OV13858
+@@ -839,6 +839,18 @@ config VIDEO_OV13858
This is a Video4Linux2 sensor driver for the OmniVision
OV13858 camera.
diff --git a/target/linux/bcm27xx/patches-5.4/950-0338-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch b/target/linux/bcm27xx/patches-5.4/950-0327-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch
index ab3a971608..ab3a971608 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0338-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0327-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0339-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch b/target/linux/bcm27xx/patches-5.4/950-0328-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch
index fb60b16e56..fb60b16e56 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0339-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0328-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0340-staging-bcm2835-codec-Set-default-and-error-check-ti.patch b/target/linux/bcm27xx/patches-5.4/950-0329-staging-bcm2835-codec-Set-default-and-error-check-ti.patch
index 124b7ae742..124b7ae742 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0340-staging-bcm2835-codec-Set-default-and-error-check-ti.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0329-staging-bcm2835-codec-Set-default-and-error-check-ti.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0341-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch b/target/linux/bcm27xx/patches-5.4/950-0330-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch
index f0fdfd29c8..f0fdfd29c8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0341-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0330-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0342-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch b/target/linux/bcm27xx/patches-5.4/950-0331-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch
index 812f69643f..812f69643f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0342-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0331-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0343-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch b/target/linux/bcm27xx/patches-5.4/950-0332-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch
index f2cf28433a..f2cf28433a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0343-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0332-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0344-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch b/target/linux/bcm27xx/patches-5.4/950-0333-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch
index a4a9dc817b..a4a9dc817b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0344-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0333-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0333-pcie-brcmstb-bounce64.c-dev_err-dev_info-for-info-me.patch b/target/linux/bcm27xx/patches-5.4/950-0333-pcie-brcmstb-bounce64.c-dev_err-dev_info-for-info-me.patch
deleted file mode 100644
index 170c2f3ad0..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0333-pcie-brcmstb-bounce64.c-dev_err-dev_info-for-info-me.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 2340a88a493d750dc3fcfa48de880fc4b8e479d2 Mon Sep 17 00:00:00 2001
-From: Floris Bos <bos@je-eigen-domein.nl>
-Date: Fri, 4 Oct 2019 16:41:30 +0200
-Subject: [PATCH] pcie-brcmstb-bounce64.c: dev_err() -> dev_info() for
- info messages
-
-"dmabounce: initialised" is not an error, so do not log it as such.
-Prevents screen polution on OS with "quiet" as kernel parameter.
-
-Closes #3266
----
- drivers/pci/controller/pcie-brcmstb-bounce64.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pci/controller/pcie-brcmstb-bounce64.c
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce64.c
-@@ -517,7 +517,7 @@ int brcm_pcie_bounce_init(struct device
-
- g_dmabounce_device_info = device_info;
-
-- dev_err(dev, "dmabounce: initialised - %ld kB, threshold %pad\n",
-+ dev_info(dev, "dmabounce: initialised - %ld kB, threshold %pad\n",
- buffer_size / 1024, &threshold);
-
- return 0;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0345-drm-v3d-Suppress-all-but-the-first-MMU-error.patch b/target/linux/bcm27xx/patches-5.4/950-0334-drm-v3d-Suppress-all-but-the-first-MMU-error.patch
index 58f3a44aff..58f3a44aff 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0345-drm-v3d-Suppress-all-but-the-first-MMU-error.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0334-drm-v3d-Suppress-all-but-the-first-MMU-error.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0346-drm-v3d-Plug-dma_fence-leak.patch b/target/linux/bcm27xx/patches-5.4/950-0335-drm-v3d-Plug-dma_fence-leak.patch
index a79912df1e..a79912df1e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0346-drm-v3d-Plug-dma_fence-leak.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0335-drm-v3d-Plug-dma_fence-leak.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0347-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch b/target/linux/bcm27xx/patches-5.4/950-0336-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch
index 28641fd327..28641fd327 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0347-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0336-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0348-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch b/target/linux/bcm27xx/patches-5.4/950-0337-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch
index 016e6c0aa5..016e6c0aa5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0348-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0337-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0349-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch b/target/linux/bcm27xx/patches-5.4/950-0338-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch
index 915ca1a29f..915ca1a29f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0349-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0338-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0350-staging-vchiq_arm-Unify-the-unload-handling-of-platf.patch b/target/linux/bcm27xx/patches-5.4/950-0339-staging-vchiq_arm-Unify-the-unload-handling-of-platf.patch
index 9bcd967b8a..9bcd967b8a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0350-staging-vchiq_arm-Unify-the-unload-handling-of-platf.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0339-staging-vchiq_arm-Unify-the-unload-handling-of-platf.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0351-net-bcmgenet-The-second-IRQ-is-optional.patch b/target/linux/bcm27xx/patches-5.4/950-0340-net-bcmgenet-The-second-IRQ-is-optional.patch
index d48e6948d3..d48e6948d3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0351-net-bcmgenet-The-second-IRQ-is-optional.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0340-net-bcmgenet-The-second-IRQ-is-optional.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0352-drm-v3d-The-third-IRQ-is-optional.patch b/target/linux/bcm27xx/patches-5.4/950-0341-drm-v3d-The-third-IRQ-is-optional.patch
index ea583b105a..ea583b105a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0352-drm-v3d-The-third-IRQ-is-optional.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0341-drm-v3d-The-third-IRQ-is-optional.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0353-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0342-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch
index 3307eacccf..3307eacccf 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0353-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0342-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0354-rpi-poe-fan-fix-def_pwm1-writes.patch b/target/linux/bcm27xx/patches-5.4/950-0343-rpi-poe-fan-fix-def_pwm1-writes.patch
index 8792d5954c..8792d5954c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0354-rpi-poe-fan-fix-def_pwm1-writes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0343-rpi-poe-fan-fix-def_pwm1-writes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0355-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch b/target/linux/bcm27xx/patches-5.4/950-0344-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch
index b3e237fdf5..b3e237fdf5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0355-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0344-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0356-overlays-smi-fix-typo-in-comment-3320.patch b/target/linux/bcm27xx/patches-5.4/950-0345-overlays-smi-fix-typo-in-comment-3320.patch
index 0a4f630a4c..0a4f630a4c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0356-overlays-smi-fix-typo-in-comment-3320.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0345-overlays-smi-fix-typo-in-comment-3320.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0357-net-phy-2711-Change-the-default-ethernet-LED-actions.patch b/target/linux/bcm27xx/patches-5.4/950-0346-net-phy-2711-Change-the-default-ethernet-LED-actions.patch
index d76fd0ec0d..d76fd0ec0d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0357-net-phy-2711-Change-the-default-ethernet-LED-actions.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0346-net-phy-2711-Change-the-default-ethernet-LED-actions.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0358-overlays-Add-apds9960-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0347-overlays-Add-apds9960-overlay.patch
index f0f5368076..f0f5368076 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0358-overlays-Add-apds9960-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0347-overlays-Add-apds9960-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0359-overlays-Remove-hack-from-uart0-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0348-overlays-Remove-hack-from-uart0-overlay.patch
index ac70b35413..ac70b35413 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0359-overlays-Remove-hack-from-uart0-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0348-overlays-Remove-hack-from-uart0-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0360-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch b/target/linux/bcm27xx/patches-5.4/950-0349-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch
index ba19abb895..ba19abb895 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0360-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0349-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0361-v3d_drv-Handle-missing-clock-more-gracefully.patch b/target/linux/bcm27xx/patches-5.4/950-0350-v3d_drv-Handle-missing-clock-more-gracefully.patch
index 812d6f1311..812d6f1311 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0361-v3d_drv-Handle-missing-clock-more-gracefully.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0350-v3d_drv-Handle-missing-clock-more-gracefully.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0362-v3d_drv-Allow-clock-retrieval-by-name.patch b/target/linux/bcm27xx/patches-5.4/950-0351-v3d_drv-Allow-clock-retrieval-by-name.patch
index 4529471b6c..4529471b6c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0362-v3d_drv-Allow-clock-retrieval-by-name.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0351-v3d_drv-Allow-clock-retrieval-by-name.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0363-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch b/target/linux/bcm27xx/patches-5.4/950-0352-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch
index 1892a145fa..1892a145fa 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0363-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0352-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0364-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch b/target/linux/bcm27xx/patches-5.4/950-0353-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch
index 31978c761a..31978c761a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0364-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0353-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0365-clk-raspberrypi-Also-support-v3d-clock.patch b/target/linux/bcm27xx/patches-5.4/950-0354-clk-raspberrypi-Also-support-v3d-clock.patch
index b2a9363ad4..b2a9363ad4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0365-clk-raspberrypi-Also-support-v3d-clock.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0354-clk-raspberrypi-Also-support-v3d-clock.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0366-clk-bcm2835-Disable-v3d-clock.patch b/target/linux/bcm27xx/patches-5.4/950-0355-clk-bcm2835-Disable-v3d-clock.patch
index 160b39b9cd..160b39b9cd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0366-clk-bcm2835-Disable-v3d-clock.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0355-clk-bcm2835-Disable-v3d-clock.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0367-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch b/target/linux/bcm27xx/patches-5.4/950-0356-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch
index 192b13b69a..192b13b69a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0367-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0356-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0368-arm-dts-Correct-Pi-4B-LED-values.patch b/target/linux/bcm27xx/patches-5.4/950-0357-arm-dts-Correct-Pi-4B-LED-values.patch
index a3bae521e7..a3bae521e7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0368-arm-dts-Correct-Pi-4B-LED-values.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0357-arm-dts-Correct-Pi-4B-LED-values.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0369-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch b/target/linux/bcm27xx/patches-5.4/950-0358-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch
index 67cdd44f29..67cdd44f29 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0369-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0358-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0370-arm-dts-2711-Add-pcie0-alias.patch b/target/linux/bcm27xx/patches-5.4/950-0359-arm-dts-2711-Add-pcie0-alias.patch
index fa00fb1974..fa00fb1974 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0370-arm-dts-2711-Add-pcie0-alias.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0359-arm-dts-2711-Add-pcie0-alias.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0371-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0360-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch
index 61f49d5ae4..61f49d5ae4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0371-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0360-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0372-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch b/target/linux/bcm27xx/patches-5.4/950-0361-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch
index 0a6660b893..0a6660b893 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0372-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0361-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0373-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch b/target/linux/bcm27xx/patches-5.4/950-0362-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch
index eb35a81023..eb35a81023 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0373-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0362-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0374-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch b/target/linux/bcm27xx/patches-5.4/950-0363-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch
index ee12a0f5db..ee12a0f5db 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0374-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0363-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0375-overlays-Make-mcp342x-run-time-compatible.patch b/target/linux/bcm27xx/patches-5.4/950-0364-overlays-Make-mcp342x-run-time-compatible.patch
index 1b4809db0d..1b4809db0d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0375-overlays-Make-mcp342x-run-time-compatible.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0364-overlays-Make-mcp342x-run-time-compatible.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0376-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch b/target/linux/bcm27xx/patches-5.4/950-0365-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch
index e1ffd3b0b7..e1ffd3b0b7 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0376-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0365-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0377-sound-soc-only-first-codec-is-master-in-multicodec-s.patch b/target/linux/bcm27xx/patches-5.4/950-0366-sound-soc-only-first-codec-is-master-in-multicodec-s.patch
index c4f70ea11f..c4f70ea11f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0377-sound-soc-only-first-codec-is-master-in-multicodec-s.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0366-sound-soc-only-first-codec-is-master-in-multicodec-s.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0378-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch b/target/linux/bcm27xx/patches-5.4/950-0367-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch
index d0d1e28757..d0d1e28757 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0378-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0367-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0379-overlays-dht11-Allow-multiple-instantiation.patch b/target/linux/bcm27xx/patches-5.4/950-0368-overlays-dht11-Allow-multiple-instantiation.patch
index b75f1d4988..b75f1d4988 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0379-overlays-dht11-Allow-multiple-instantiation.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0368-overlays-dht11-Allow-multiple-instantiation.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0380-overlays-i2c-rtc-Add-pcf85363-support.patch b/target/linux/bcm27xx/patches-5.4/950-0369-overlays-i2c-rtc-Add-pcf85363-support.patch
index 93a699a66a..93a699a66a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0380-overlays-i2c-rtc-Add-pcf85363-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0369-overlays-i2c-rtc-Add-pcf85363-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0381-pinctrl-bcm2835-Remove-gpiochip-on-error.patch b/target/linux/bcm27xx/patches-5.4/950-0370-pinctrl-bcm2835-Remove-gpiochip-on-error.patch
index 31a1a24caf..31a1a24caf 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0381-pinctrl-bcm2835-Remove-gpiochip-on-error.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0370-pinctrl-bcm2835-Remove-gpiochip-on-error.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0382-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch b/target/linux/bcm27xx/patches-5.4/950-0371-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch
index 3865ae11fb..3865ae11fb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0382-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0371-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0383-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch b/target/linux/bcm27xx/patches-5.4/950-0372-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch
index 0221803993..0221803993 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0383-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0372-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0385-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch
index 04b85fd6c5..04b85fd6c5 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0385-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0386-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0374-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch
index 3ececc8f92..3ececc8f92 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0386-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0374-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0387-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0375-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch
index 5303e937bd..5303e937bd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0387-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0375-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0388-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch b/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch
index 1acf84b7ce..1acf84b7ce 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0388-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0389-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch b/target/linux/bcm27xx/patches-5.4/950-0377-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch
index ce0b8811d0..ce0b8811d0 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0389-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0377-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0390-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0378-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch
index fb3a6a3806..fb3a6a3806 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0390-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0378-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0391-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0379-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch
index ef26293498..ef26293498 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0391-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0379-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0392-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch b/target/linux/bcm27xx/patches-5.4/950-0380-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch
index 0e2a78649f..0e2a78649f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0392-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0380-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0393-net-bcmgenet-Add-RGMII_RXID-support.patch b/target/linux/bcm27xx/patches-5.4/950-0381-net-bcmgenet-Add-RGMII_RXID-support.patch
index 0e13394c7f..0e13394c7f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0393-net-bcmgenet-Add-RGMII_RXID-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0381-net-bcmgenet-Add-RGMII_RXID-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0394-ARM-dts-bcm2838-Backport-genet-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0382-ARM-dts-bcm2838-Backport-genet-from-upstream.patch
index ffd7d8e540..ffd7d8e540 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0394-ARM-dts-bcm2838-Backport-genet-from-upstream.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0382-ARM-dts-bcm2838-Backport-genet-from-upstream.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0395-ARM-bcm-Backport-BCM2711-support-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0383-ARM-bcm-Backport-BCM2711-support-from-upstream.patch
index 8d16152154..8d16152154 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0395-ARM-bcm-Backport-BCM2711-support-from-upstream.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0383-ARM-bcm-Backport-BCM2711-support-from-upstream.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0396-hwrng-iproc-rng200-Add-support-for-BCM2711.patch b/target/linux/bcm27xx/patches-5.4/950-0384-hwrng-iproc-rng200-Add-support-for-BCM2711.patch
index 7a47128837..7a47128837 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0396-hwrng-iproc-rng200-Add-support-for-BCM2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0384-hwrng-iproc-rng200-Add-support-for-BCM2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0384-pcie-brcmstb-Eliminate-arch_dma_ops-error-message.patch b/target/linux/bcm27xx/patches-5.4/950-0384-pcie-brcmstb-Eliminate-arch_dma_ops-error-message.patch
deleted file mode 100644
index ee7cf0e52b..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0384-pcie-brcmstb-Eliminate-arch_dma_ops-error-message.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 27cf0ad95cdf30f52a5fc6c69014a0d7bf5a1222 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 8 Jan 2020 17:21:09 +0000
-Subject: [PATCH] pcie-brcmstb: Eliminate arch_dma_ops error message
-
-The driver attempts to set the dma_ops for the root complex, but doing
-so causes an error message and only the end points need it. Fix the
-error by making the code specific to the end point case.
-
-Also copy some cosmetic tidy-ups from 5.5.y.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/pci/controller/pcie-brcmstb.c | 43 ++++++++++++++-------------
- 1 file changed, 22 insertions(+), 21 deletions(-)
-
---- a/drivers/pci/controller/pcie-brcmstb.c
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -633,16 +633,17 @@ static int brcmstb_platform_notifier(str
-
- switch (event) {
- case BUS_NOTIFY_ADD_DEVICE:
-- if (max_pfn > (bounce_threshold/PAGE_SIZE) &&
-- strcmp(dev->kobj.name, rc_name)) {
--
-- ret = brcm_pcie_bounce_register_dev(dev);
-- if (ret) {
-- dev_err(dev,
-- "brcm_pcie_bounce_register_dev() failed: %d\n",
-- ret);
-- return ret;
-+ if (strcmp(dev->kobj.name, rc_name)) {
-+ if (max_pfn > (bounce_threshold/PAGE_SIZE)) {
-+ ret = brcm_pcie_bounce_register_dev(dev);
-+ if (ret) {
-+ dev_err(dev,
-+ "brcm_pcie_bounce_register_dev() failed: %d\n",
-+ ret);
-+ return ret;
-+ }
- }
-+ brcm_set_dma_ops(dev);
- } else if (IS_ENABLED(CONFIG_ARM64)) {
- ret = of_dma_configure(dev, dev->of_node, true);
- if (ret) {
-@@ -650,7 +651,6 @@ static int brcmstb_platform_notifier(str
- return ret;
- }
- }
-- brcm_set_dma_ops(dev);
- return NOTIFY_OK;
-
- case BUS_NOTIFY_DEL_DEVICE:
-@@ -1685,7 +1685,8 @@ MODULE_DEVICE_TABLE(of, brcm_pcie_match)
-
- static int brcm_pcie_probe(struct platform_device *pdev)
- {
-- struct device_node *dn = pdev->dev.of_node, *msi_dn;
-+ struct device *dev = &pdev->dev;
-+ struct device_node *dn = dev->of_node, *msi_dn;
- const struct of_device_id *of_id;
- const struct pcie_cfg_data *data;
- int ret;
-@@ -1696,7 +1697,7 @@ static int brcm_pcie_probe(struct platfo
- struct pci_bus *child;
- extern unsigned long max_pfn;
-
-- bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie));
-+ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
- if (!bridge)
- return -ENOMEM;
-
-@@ -1705,7 +1706,7 @@ static int brcm_pcie_probe(struct platfo
-
- of_id = of_match_node(brcm_pcie_match, dn);
- if (!of_id) {
-- dev_err(&pdev->dev, "failed to look up compatible string\n");
-+ dev_err(dev, "failed to look up compatible string\n");
- return -EINVAL;
- }
-
-@@ -1715,7 +1716,7 @@ static int brcm_pcie_probe(struct platfo
- pcie->max_burst_size = data->max_burst_size;
- pcie->type = data->type;
- pcie->dn = dn;
-- pcie->dev = &pdev->dev;
-+ pcie->dev = dev;
-
- /* We use the domain number as our controller number */
- pcie->id = of_get_pci_domain_nr(dn);
-@@ -1726,18 +1727,18 @@ static int brcm_pcie_probe(struct platfo
- if (!res)
- return -EINVAL;
-
-- base = devm_ioremap_resource(&pdev->dev, res);
-+ base = devm_ioremap_resource(dev, res);
- if (IS_ERR(base))
- return PTR_ERR(base);
-
- /* To Do: Add hardware check if this ever gets fixed */
- if (max_pfn > (bounce_threshold/PAGE_SIZE)) {
- int ret;
-- ret = brcm_pcie_bounce_init(&pdev->dev, bounce_buffer,
-+ ret = brcm_pcie_bounce_init(dev, bounce_buffer,
- (dma_addr_t)bounce_threshold);
- if (ret) {
- if (ret != -EPROBE_DEFER)
-- dev_err(&pdev->dev,
-+ dev_err(dev,
- "could not init bounce buffers: %d\n",
- ret);
- return ret;
-@@ -1746,7 +1747,7 @@ static int brcm_pcie_probe(struct platfo
-
- pcie->clk = of_clk_get_by_name(dn, "sw_pcie");
- if (IS_ERR(pcie->clk)) {
-- dev_warn(&pdev->dev, "could not get clock\n");
-+ dev_warn(dev, "could not get clock\n");
- pcie->clk = NULL;
- }
- pcie->base = base;
-@@ -1756,7 +1757,7 @@ static int brcm_pcie_probe(struct platfo
-
- pcie->ssc = of_property_read_bool(dn, "brcm,enable-ssc");
-
-- ret = irq_of_parse_and_map(pdev->dev.of_node, 0);
-+ ret = irq_of_parse_and_map(dev->of_node, 0);
- if (ret == 0)
- /* keep going, as we don't use this intr yet */
- dev_warn(pcie->dev, "cannot get PCIe interrupt\n");
-@@ -1770,7 +1771,7 @@ static int brcm_pcie_probe(struct platfo
- ret = clk_prepare_enable(pcie->clk);
- if (ret) {
- if (ret != -EPROBE_DEFER)
-- dev_err(&pdev->dev, "could not enable clock\n");
-+ dev_err(dev, "could not enable clock\n");
- return ret;
- }
-
-@@ -1797,7 +1798,7 @@ static int brcm_pcie_probe(struct platfo
- }
-
- list_splice_init(&pcie->resources, &bridge->windows);
-- bridge->dev.parent = &pdev->dev;
-+ bridge->dev.parent = dev;
- bridge->busnr = 0;
- bridge->ops = &brcm_pcie_ops;
- bridge->sysdata = pcie;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0397-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch b/target/linux/bcm27xx/patches-5.4/950-0385-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch
index 2feda7389e..2feda7389e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0397-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0385-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0398-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch b/target/linux/bcm27xx/patches-5.4/950-0386-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch
index 49d885cd73..49d885cd73 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0398-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0386-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0399-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch b/target/linux/bcm27xx/patches-5.4/950-0387-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch
index b61e2c5cfe..b61e2c5cfe 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0399-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0387-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0400-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch b/target/linux/bcm27xx/patches-5.4/950-0388-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch
index 52aa87ed04..52aa87ed04 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0400-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0388-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0401-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch b/target/linux/bcm27xx/patches-5.4/950-0389-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch
index 26d0c9894b..26d0c9894b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0401-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0389-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0402-driver-char-rpimem-Add-SPDX-licence-header.patch b/target/linux/bcm27xx/patches-5.4/950-0390-driver-char-rpimem-Add-SPDX-licence-header.patch
index 86b9400ac6..86b9400ac6 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0402-driver-char-rpimem-Add-SPDX-licence-header.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0390-driver-char-rpimem-Add-SPDX-licence-header.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0403-driver-char-rpivid-Fix-access-to-freed-memory.patch b/target/linux/bcm27xx/patches-5.4/950-0391-driver-char-rpivid-Fix-access-to-freed-memory.patch
index 67147fa58d..67147fa58d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0403-driver-char-rpivid-Fix-access-to-freed-memory.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0391-driver-char-rpivid-Fix-access-to-freed-memory.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0404-add-BME680-to-i2c-sensor-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0392-add-BME680-to-i2c-sensor-overlay.patch
index 0c2fe6aa8a..0c2fe6aa8a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0404-add-BME680-to-i2c-sensor-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0392-add-BME680-to-i2c-sensor-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0405-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch b/target/linux/bcm27xx/patches-5.4/950-0393-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch
index 7e4a3f8b38..7e4a3f8b38 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0405-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0393-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0406-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch b/target/linux/bcm27xx/patches-5.4/950-0394-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch
index 0a7356ffa2..0a7356ffa2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0406-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0394-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0407-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch b/target/linux/bcm27xx/patches-5.4/950-0395-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch
index e986f425ff..e986f425ff 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0407-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0395-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0408-Add-universal-device-tree-overlay-for-SPI-devices.patch b/target/linux/bcm27xx/patches-5.4/950-0396-Add-universal-device-tree-overlay-for-SPI-devices.patch
index cb8fa91bef..cb8fa91bef 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0408-Add-universal-device-tree-overlay-for-SPI-devices.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0396-Add-universal-device-tree-overlay-for-SPI-devices.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0409-sound-Add-the-HiFiBerry-DAC-HD-version.patch b/target/linux/bcm27xx/patches-5.4/950-0397-sound-Add-the-HiFiBerry-DAC-HD-version.patch
index 6b9a6bd29c..6b9a6bd29c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0409-sound-Add-the-HiFiBerry-DAC-HD-version.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0397-sound-Add-the-HiFiBerry-DAC-HD-version.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0410-Initialise-rpi-firmware-before-clk-bcm2835.patch b/target/linux/bcm27xx/patches-5.4/950-0398-Initialise-rpi-firmware-before-clk-bcm2835.patch
index 0e0173085d..0e0173085d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0410-Initialise-rpi-firmware-before-clk-bcm2835.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0398-Initialise-rpi-firmware-before-clk-bcm2835.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0411-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch b/target/linux/bcm27xx/patches-5.4/950-0399-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch
index 54b366f65a..54b366f65a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0411-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0399-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0412-overlays-Use-preferred-compatible-strings.patch b/target/linux/bcm27xx/patches-5.4/950-0400-overlays-Use-preferred-compatible-strings.patch
index 6a246050cf..6a246050cf 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0412-overlays-Use-preferred-compatible-strings.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0400-overlays-Use-preferred-compatible-strings.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0413-tty-amba-pl011-Add-un-throttle-support.patch b/target/linux/bcm27xx/patches-5.4/950-0401-tty-amba-pl011-Add-un-throttle-support.patch
index 7777e2df96..7777e2df96 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0413-tty-amba-pl011-Add-un-throttle-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0401-tty-amba-pl011-Add-un-throttle-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0414-Fix-i2c-pwm-pca9685a-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0402-Fix-i2c-pwm-pca9685a-overlay.patch
index 17bdf3984e..17bdf3984e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0414-Fix-i2c-pwm-pca9685a-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0402-Fix-i2c-pwm-pca9685a-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0415-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch b/target/linux/bcm27xx/patches-5.4/950-0403-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch
index 397a2c3331..397a2c3331 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0415-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0403-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0416-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch b/target/linux/bcm27xx/patches-5.4/950-0404-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch
index bd8f405ef8..bd8f405ef8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0416-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0404-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0417-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch b/target/linux/bcm27xx/patches-5.4/950-0405-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch
index a5c3d40512..a5c3d40512 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0417-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0405-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0418-pisound-Added-reading-Pisound-board-hardware-revisio.patch b/target/linux/bcm27xx/patches-5.4/950-0406-pisound-Added-reading-Pisound-board-hardware-revisio.patch
index df6f526e2e..df6f526e2e 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0418-pisound-Added-reading-Pisound-board-hardware-revisio.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0406-pisound-Added-reading-Pisound-board-hardware-revisio.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0419-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch b/target/linux/bcm27xx/patches-5.4/950-0407-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch
index 4713dde247..4713dde247 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0419-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0407-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch b/target/linux/bcm27xx/patches-5.4/950-0408-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch
index a69feb50b4..a69feb50b4 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0408-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0422-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0409-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch
index 2f5d87b004..2f5d87b004 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0422-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0409-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0410-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch
index 10c5d23b46..10c5d23b46 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0410-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0424-tty-amba-pl011-Avoid-rare-write-when-full-error.patch b/target/linux/bcm27xx/patches-5.4/950-0411-tty-amba-pl011-Avoid-rare-write-when-full-error.patch
index b2b27f258f..b2b27f258f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0424-tty-amba-pl011-Avoid-rare-write-when-full-error.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0411-tty-amba-pl011-Avoid-rare-write-when-full-error.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0425-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch b/target/linux/bcm27xx/patches-5.4/950-0412-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch
index 06e979a462..06e979a462 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0425-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0412-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0426-overlays-Correct-the-eth_led-colour-assignments.patch b/target/linux/bcm27xx/patches-5.4/950-0413-overlays-Correct-the-eth_led-colour-assignments.patch
index f1f3290bad..f1f3290bad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0426-overlays-Correct-the-eth_led-colour-assignments.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0413-overlays-Correct-the-eth_led-colour-assignments.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0427-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0414-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch
index fef644e1c9..fef644e1c9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0427-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0414-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0428-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch b/target/linux/bcm27xx/patches-5.4/950-0415-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch
index 77bf63e2e2..77bf63e2e2 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0428-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0415-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0429-overlays-dwc2-Increase-RX-FIFO-size.patch b/target/linux/bcm27xx/patches-5.4/950-0416-overlays-dwc2-Increase-RX-FIFO-size.patch
index 23bc39b3d8..23bc39b3d8 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0429-overlays-dwc2-Increase-RX-FIFO-size.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0416-overlays-dwc2-Increase-RX-FIFO-size.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0430-overlays-Fix-mcp23017-s-addr-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0417-overlays-Fix-mcp23017-s-addr-parameter.patch
index 29ad87227d..29ad87227d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0430-overlays-Fix-mcp23017-s-addr-parameter.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0417-overlays-Fix-mcp23017-s-addr-parameter.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0431-SQUASH-Fix-spi-driver-compiler-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0418-SQUASH-Fix-spi-driver-compiler-warnings.patch
index bccf74b410..bccf74b410 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0431-SQUASH-Fix-spi-driver-compiler-warnings.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0418-SQUASH-Fix-spi-driver-compiler-warnings.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0432-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0419-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch
index e94f15196b..e94f15196b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0432-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0419-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0433-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch b/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch
index df922eaf4b..df922eaf4b 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0433-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0434-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch b/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch
index a66202a2c9..a66202a2c9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0434-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0421-pcie-brcmstb-Bounce-buffer-support-is-for-BCM2711B0.patch b/target/linux/bcm27xx/patches-5.4/950-0421-pcie-brcmstb-Bounce-buffer-support-is-for-BCM2711B0.patch
deleted file mode 100644
index 73da382074..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0421-pcie-brcmstb-Bounce-buffer-support-is-for-BCM2711B0.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 58ac2d4474e531300f9f83773aa4d09e95ee2626 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 12 Jul 2019 11:41:25 +0100
-Subject: [PATCH] pcie-brcmstb: Bounce buffer support is for BCM2711B0
-
-Add a new compatible string to identify BCM2711B0, as later revisions
-don't require the bounce buffer support.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/pci/controller/pcie-brcmstb.c | 31 +++++++++++++++++++++++----
- 1 file changed, 27 insertions(+), 4 deletions(-)
-
---- a/drivers/pci/controller/pcie-brcmstb.c
-+++ b/drivers/pci/controller/pcie-brcmstb.c
-@@ -206,6 +206,8 @@ enum pcie_type {
- BCM7435,
- GENERIC,
- BCM7278,
-+ BCM2711B0,
-+ BCM2711,
- };
-
- struct brcm_window {
-@@ -302,6 +304,20 @@ static const int pcie_offsets[] = {
- [EXT_CFG_DATA] = 0x8000,
- };
-
-+static const struct pcie_cfg_data bcm2711b0_cfg = {
-+ .reg_field_info = pcie_reg_field_info,
-+ .offsets = pcie_offsets,
-+ .max_burst_size = BURST_SIZE_128,
-+ .type = BCM2711B0,
-+};
-+
-+static const struct pcie_cfg_data bcm2711_cfg = {
-+ .reg_field_info = pcie_reg_field_info,
-+ .offsets = pcie_offsets,
-+ .max_burst_size = BURST_SIZE_128,
-+ .type = BCM2711,
-+};
-+
- static const struct pcie_cfg_data bcm7435_cfg = {
- .reg_field_info = pcie_reg_field_info,
- .offsets = pcie_offsets,
-@@ -312,7 +328,7 @@ static const struct pcie_cfg_data bcm743
- static const struct pcie_cfg_data generic_cfg = {
- .reg_field_info = pcie_reg_field_info,
- .offsets = pcie_offsets,
-- .max_burst_size = BURST_SIZE_128, // before BURST_SIZE_512
-+ .max_burst_size = BURST_SIZE_512,
- .type = GENERIC,
- };
-
-@@ -380,7 +396,7 @@ static unsigned int bounce_buffer = 32*1
- module_param(bounce_buffer, uint, 0644);
- MODULE_PARM_DESC(bounce_buffer, "Size of bounce buffer");
-
--static unsigned int bounce_threshold = 0xc0000000;
-+static unsigned int bounce_threshold;
- module_param(bounce_threshold, uint, 0644);
- MODULE_PARM_DESC(bounce_threshold, "Bounce threshold");
-
-@@ -1675,6 +1691,8 @@ static int brcm_pcie_remove(struct platf
- }
-
- static const struct of_device_id brcm_pcie_match[] = {
-+ { .compatible = "brcm,bcm2711b0-pcie", .data = &bcm2711b0_cfg },
-+ { .compatible = "brcm,bcm2711-pcie", .data = &bcm2711_cfg },
- { .compatible = "brcm,bcm7425-pcie", .data = &bcm7425_cfg },
- { .compatible = "brcm,bcm7435-pcie", .data = &bcm7435_cfg },
- { .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg },
-@@ -1731,8 +1749,13 @@ static int brcm_pcie_probe(struct platfo
- if (IS_ERR(base))
- return PTR_ERR(base);
-
-- /* To Do: Add hardware check if this ever gets fixed */
-- if (max_pfn > (bounce_threshold/PAGE_SIZE)) {
-+ if (!bounce_threshold) {
-+ /* PCIe on BCM2711B0 can only address 3GB */
-+ if (pcie->type == BCM2711B0 || pcie->type == GENERIC)
-+ bounce_threshold = 0xc0000000;
-+ }
-+
-+ if (bounce_threshold && (max_pfn > (bounce_threshold/PAGE_SIZE))) {
- int ret;
- ret = brcm_pcie_bounce_init(dev, bounce_buffer,
- (dma_addr_t)bounce_threshold);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0435-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch b/target/linux/bcm27xx/patches-5.4/950-0422-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch
index 15e4f53a0a..15e4f53a0a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0435-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0422-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0436-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch b/target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch
index 44f60d610f..44f60d610f 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0436-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0437-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch b/target/linux/bcm27xx/patches-5.4/950-0424-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch
index e204859fbd..e204859fbd 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0437-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0424-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0438-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch b/target/linux/bcm27xx/patches-5.4/950-0425-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch
index ed0be9b9a3..ed0be9b9a3 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0438-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0425-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0439-ARM-dts-Rebuild-downstream-DTS-files.patch b/target/linux/bcm27xx/patches-5.4/950-0426-ARM-dts-Rebuild-downstream-DTS-files.patch
index 8d230d0edb..8d230d0edb 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0439-ARM-dts-Rebuild-downstream-DTS-files.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0426-ARM-dts-Rebuild-downstream-DTS-files.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0440-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0427-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch
index 4436c0a39d..4436c0a39d 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0440-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0427-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0442-thermal-brcmstb_thermal-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0428-thermal-brcmstb_thermal-Correct-SoC-name.patch
index 5ba80afd98..5ba80afd98 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0442-thermal-brcmstb_thermal-Correct-SoC-name.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0428-thermal-brcmstb_thermal-Correct-SoC-name.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0443-hwrng-iproc-rng200-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0429-hwrng-iproc-rng200-Correct-SoC-name.patch
index f4e93308b1..f4e93308b1 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0443-hwrng-iproc-rng200-Correct-SoC-name.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0429-hwrng-iproc-rng200-Correct-SoC-name.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0445-ARM-dts-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0430-ARM-dts-Correct-SoC-name.patch
index c18eb8af3c..c18eb8af3c 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0445-ARM-dts-Correct-SoC-name.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0430-ARM-dts-Correct-SoC-name.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0446-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch b/target/linux/bcm27xx/patches-5.4/950-0431-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch
index 2c093459da..2c093459da 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0446-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0431-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0447-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch b/target/linux/bcm27xx/patches-5.4/950-0432-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch
index 7fb3443fa9..7fb3443fa9 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0447-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0432-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0448-staging-vchiq_arm-Add-a-matching-unregister-call.patch b/target/linux/bcm27xx/patches-5.4/950-0433-staging-vchiq_arm-Add-a-matching-unregister-call.patch
index 8271b2505a..8271b2505a 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0448-staging-vchiq_arm-Add-a-matching-unregister-call.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0433-staging-vchiq_arm-Add-a-matching-unregister-call.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0449-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch b/target/linux/bcm27xx/patches-5.4/950-0434-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch
index b5e59e6464..b5e59e6464 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0449-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0434-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0450-ASoC-pcm512x-Fix-unbalanced-regulator-enable-call-in.patch b/target/linux/bcm27xx/patches-5.4/950-0435-ASoC-pcm512x-Fix-unbalanced-regulator-enable-call-in.patch
index ae9b9f44fa..ae9b9f44fa 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0450-ASoC-pcm512x-Fix-unbalanced-regulator-enable-call-in.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0435-ASoC-pcm512x-Fix-unbalanced-regulator-enable-call-in.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0451-ARM-dts-overlays-Create-custom-clocks-in.patch b/target/linux/bcm27xx/patches-5.4/950-0436-ARM-dts-overlays-Create-custom-clocks-in.patch
index ac50884bce..ac50884bce 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0451-ARM-dts-overlays-Create-custom-clocks-in.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0436-ARM-dts-overlays-Create-custom-clocks-in.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0437-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch b/target/linux/bcm27xx/patches-5.4/950-0437-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch
new file mode 100644
index 0000000000..4774fd2326
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0437-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch
@@ -0,0 +1,26 @@
+From 38e906c77467bf83ec130bea6859b46ea1e0d4b8 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Thu, 30 Jan 2020 12:35:44 +0000
+Subject: [PATCH] staging: vc04_services: Fix vcsm overflow bug when
+ counting transactions
+
+The response block and local state were using u16 and u32 respectively
+to represent transaction id. When the former would wrap, there is a
+mismatch and subsequent transactions will be marked as failures.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c
++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c
+@@ -34,7 +34,7 @@ struct sm_cmd_rsp_blk {
+ /* To be signaled when the response is there */
+ struct completion cmplt;
+
+- u16 id;
++ u32 id;
+ u16 length;
+
+ u8 msg[VC_SM_MAX_MSG_LEN];
diff --git a/target/linux/bcm27xx/patches-5.4/950-0438-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch b/target/linux/bcm27xx/patches-5.4/950-0438-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch
new file mode 100644
index 0000000000..213e8b8d9d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0438-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch
@@ -0,0 +1,34 @@
+From 04f569021b0d24ec9f5c3671447b77157c859d16 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 7 Feb 2020 09:51:31 +0000
+Subject: [PATCH] overlays: Add timeout_ms parameter to gpio-poweroff
+
+The timeout_ms parameter specifies in milliseconds how long the kernel
+waits for power-down before issuing a WARN. The default value is 3000 ms.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 2 ++
+ arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts | 1 +
+ 2 files changed, 3 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -821,6 +821,8 @@ Params: gpiopin GPIO for
+ input Set if the gpio pin should be configured as
+ an input.
+ export Set to export the configured pin to sysfs
++ timeout_ms Specify (in ms) how long the kernel waits for
++ power-down before issuing a WARN (default 3000).
+
+
+ Name: gpio-shutdown
+--- a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts
++++ b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts
+@@ -32,5 +32,6 @@
+ active_low = <&power_ctrl>,"gpios:8";
+ input = <&power_ctrl>,"input?";
+ export = <&power_ctrl>,"export?";
++ timeout_ms = <&power_ctrl>,"timeout-ms:0";
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0439-of-overlay-Correct-symbol-path-fixups.patch b/target/linux/bcm27xx/patches-5.4/950-0439-of-overlay-Correct-symbol-path-fixups.patch
new file mode 100644
index 0000000000..4b005876de
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0439-of-overlay-Correct-symbol-path-fixups.patch
@@ -0,0 +1,37 @@
+From 8f22c4228bbb91697ab3510f5a6176e530c0d639 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 6 Feb 2020 12:23:15 +0000
+Subject: [PATCH] of: overlay: Correct symbol path fixups
+
+When symbols from overlays are added to the live tree their paths must
+be rebased. The translated symbol is normally the result of joining
+the fragment-relative path (with a leading "/") to the target path
+(either copied directly from the "target-path" property or resolved
+from the phandle). This translation fails when the target is the root
+node (a common case for Raspberry Pi overlays) because the resulting
+path starts with a double slash. For example, if target-path is "/" and
+the fragment adds a node called "newnode", the label associated with
+that node will be assigned the path "//newnode", which can't be found
+in the tree.
+
+Fix the failure case by explicitly replacing a target path of "/" with
+an empty string.
+
+Fixes: d1651b03c2df ("of: overlay: add overlay symbols to live device tree")
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/of/overlay.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -245,6 +245,8 @@ static struct property *dup_and_fixup_sy
+ if (!target_path)
+ return NULL;
+ target_path_len = strlen(target_path);
++ if (!strcmp(target_path, "/"))
++ target_path_len = 0;
+
+ new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
+ if (!new_prop)
diff --git a/target/linux/bcm27xx/patches-5.4/950-0440-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0440-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch
new file mode 100644
index 0000000000..636ad26a91
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0440-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch
@@ -0,0 +1,25 @@
+From 65318cd76f4523acf8ffe8fe7448fb7d913f8c66 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Tue, 3 Mar 2020 09:43:41 +0000
+Subject: [PATCH] overlays: sc16ic750-i2c: Fix xtal parameter
+
+The xtal parameter is targetting the wrong node - fix it.
+
+See: https://github.com/raspberrypi/linux/issues/3156
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts
++++ b/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts
+@@ -32,7 +32,7 @@
+ __overrides__ {
+ int_pin = <&sc16is750>,"interrupts:0";
+ addr = <&sc16is750>,"reg:0",<&sc16is750_clk>,"name";
+- xtal = <&sc16is750>,"clock-frequency:0";
++ xtal = <&sc16is750_clk>,"clock-frequency:0";
+ };
+
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0441-bcm2835-dma-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0441-bcm2835-dma-Correct-SoC-name.patch
deleted file mode 100644
index fe33168a4d..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0441-bcm2835-dma-Correct-SoC-name.patch
+++ /dev/null
@@ -1,489 +0,0 @@
-From f498861a16d0b9a189a329080da1aa64d6e9bda7 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.com>
-Date: Fri, 31 Jan 2020 09:28:57 +0000
-Subject: [PATCH] bcm2835-dma: Correct SoC name
-
-The Pi 4 SoC is called BCM2711, not BCM2838.
-
-Fixes: "bcm2835-dma: Add proper 40-bit DMA support"
----
- drivers/dma/bcm2835-dma.c | 274 +++++++++++++++++++-------------------
- 1 file changed, 137 insertions(+), 137 deletions(-)
-
---- a/drivers/dma/bcm2835-dma.c
-+++ b/drivers/dma/bcm2835-dma.c
-@@ -38,7 +38,7 @@
- #define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14
- #define BCM2835_DMA_CHAN_NAME_SIZE 8
- #define BCM2835_DMA_BULK_MASK BIT(0)
--#define BCM2838_DMA_MEMCPY_CHAN 14
-+#define BCM2711_DMA_MEMCPY_CHAN 14
-
- struct bcm2835_dma_cfg_data {
- u32 chan_40bit_mask;
-@@ -70,7 +70,7 @@ struct bcm2835_dma_cb {
- uint32_t pad[2];
- };
-
--struct bcm2838_dma40_scb {
-+struct bcm2711_dma40_scb {
- uint32_t ti;
- uint32_t src;
- uint32_t srci;
-@@ -200,98 +200,98 @@ struct bcm2835_desc {
- #define MAX_LITE_DMA_LEN (SZ_64K - 4)
-
- /* 40-bit DMA support */
--#define BCM2838_DMA40_CS 0x00
--#define BCM2838_DMA40_CB 0x04
--#define BCM2838_DMA40_DEBUG 0x0c
--#define BCM2838_DMA40_TI 0x10
--#define BCM2838_DMA40_SRC 0x14
--#define BCM2838_DMA40_SRCI 0x18
--#define BCM2838_DMA40_DEST 0x1c
--#define BCM2838_DMA40_DESTI 0x20
--#define BCM2838_DMA40_LEN 0x24
--#define BCM2838_DMA40_NEXT_CB 0x28
--#define BCM2838_DMA40_DEBUG2 0x2c
--
--#define BCM2838_DMA40_ACTIVE BIT(0)
--#define BCM2838_DMA40_END BIT(1)
--#define BCM2838_DMA40_INT BIT(2)
--#define BCM2838_DMA40_DREQ BIT(3) /* DREQ state */
--#define BCM2838_DMA40_RD_PAUSED BIT(4) /* Reading is paused */
--#define BCM2838_DMA40_WR_PAUSED BIT(5) /* Writing is paused */
--#define BCM2838_DMA40_DREQ_PAUSED BIT(6) /* Is paused by DREQ flow control */
--#define BCM2838_DMA40_WAITING_FOR_WRITES BIT(7) /* Waiting for last write */
--#define BCM2838_DMA40_ERR BIT(10)
--#define BCM2838_DMA40_QOS(x) (((x) & 0x1f) << 16)
--#define BCM2838_DMA40_PANIC_QOS(x) (((x) & 0x1f) << 20)
--#define BCM2838_DMA40_WAIT_FOR_WRITES BIT(28)
--#define BCM2838_DMA40_DISDEBUG BIT(29)
--#define BCM2838_DMA40_ABORT BIT(30)
--#define BCM2838_DMA40_HALT BIT(31)
--#define BCM2838_DMA40_CS_FLAGS(x) (x & (BCM2838_DMA40_QOS(15) | \
-- BCM2838_DMA40_PANIC_QOS(15) | \
-- BCM2838_DMA40_WAIT_FOR_WRITES | \
-- BCM2838_DMA40_DISDEBUG))
-+#define BCM2711_DMA40_CS 0x00
-+#define BCM2711_DMA40_CB 0x04
-+#define BCM2711_DMA40_DEBUG 0x0c
-+#define BCM2711_DMA40_TI 0x10
-+#define BCM2711_DMA40_SRC 0x14
-+#define BCM2711_DMA40_SRCI 0x18
-+#define BCM2711_DMA40_DEST 0x1c
-+#define BCM2711_DMA40_DESTI 0x20
-+#define BCM2711_DMA40_LEN 0x24
-+#define BCM2711_DMA40_NEXT_CB 0x28
-+#define BCM2711_DMA40_DEBUG2 0x2c
-+
-+#define BCM2711_DMA40_ACTIVE BIT(0)
-+#define BCM2711_DMA40_END BIT(1)
-+#define BCM2711_DMA40_INT BIT(2)
-+#define BCM2711_DMA40_DREQ BIT(3) /* DREQ state */
-+#define BCM2711_DMA40_RD_PAUSED BIT(4) /* Reading is paused */
-+#define BCM2711_DMA40_WR_PAUSED BIT(5) /* Writing is paused */
-+#define BCM2711_DMA40_DREQ_PAUSED BIT(6) /* Is paused by DREQ flow control */
-+#define BCM2711_DMA40_WAITING_FOR_WRITES BIT(7) /* Waiting for last write */
-+#define BCM2711_DMA40_ERR BIT(10)
-+#define BCM2711_DMA40_QOS(x) (((x) & 0x1f) << 16)
-+#define BCM2711_DMA40_PANIC_QOS(x) (((x) & 0x1f) << 20)
-+#define BCM2711_DMA40_WAIT_FOR_WRITES BIT(28)
-+#define BCM2711_DMA40_DISDEBUG BIT(29)
-+#define BCM2711_DMA40_ABORT BIT(30)
-+#define BCM2711_DMA40_HALT BIT(31)
-+#define BCM2711_DMA40_CS_FLAGS(x) (x & (BCM2711_DMA40_QOS(15) | \
-+ BCM2711_DMA40_PANIC_QOS(15) | \
-+ BCM2711_DMA40_WAIT_FOR_WRITES | \
-+ BCM2711_DMA40_DISDEBUG))
-
- /* Transfer information bits */
--#define BCM2838_DMA40_INTEN BIT(0)
--#define BCM2838_DMA40_TDMODE BIT(1) /* 2D-Mode */
--#define BCM2838_DMA40_WAIT_RESP BIT(2) /* wait for AXI write to be acked */
--#define BCM2838_DMA40_WAIT_RD_RESP BIT(3) /* wait for AXI read to complete */
--#define BCM2838_DMA40_PER_MAP(x) ((x & 31) << 9) /* REQ source */
--#define BCM2838_DMA40_S_DREQ BIT(14) /* enable SREQ for source */
--#define BCM2838_DMA40_D_DREQ BIT(15) /* enable DREQ for destination */
--#define BCM2838_DMA40_S_WAIT(x) ((x & 0xff) << 16) /* add DMA read-wait cycles */
--#define BCM2838_DMA40_D_WAIT(x) ((x & 0xff) << 24) /* add DMA write-wait cycles */
-+#define BCM2711_DMA40_INTEN BIT(0)
-+#define BCM2711_DMA40_TDMODE BIT(1) /* 2D-Mode */
-+#define BCM2711_DMA40_WAIT_RESP BIT(2) /* wait for AXI write to be acked */
-+#define BCM2711_DMA40_WAIT_RD_RESP BIT(3) /* wait for AXI read to complete */
-+#define BCM2711_DMA40_PER_MAP(x) ((x & 31) << 9) /* REQ source */
-+#define BCM2711_DMA40_S_DREQ BIT(14) /* enable SREQ for source */
-+#define BCM2711_DMA40_D_DREQ BIT(15) /* enable DREQ for destination */
-+#define BCM2711_DMA40_S_WAIT(x) ((x & 0xff) << 16) /* add DMA read-wait cycles */
-+#define BCM2711_DMA40_D_WAIT(x) ((x & 0xff) << 24) /* add DMA write-wait cycles */
-
- /* debug register bits */
--#define BCM2838_DMA40_DEBUG_WRITE_ERR BIT(0)
--#define BCM2838_DMA40_DEBUG_FIFO_ERR BIT(1)
--#define BCM2838_DMA40_DEBUG_READ_ERR BIT(2)
--#define BCM2838_DMA40_DEBUG_READ_CB_ERR BIT(3)
--#define BCM2838_DMA40_DEBUG_IN_ON_ERR BIT(8)
--#define BCM2838_DMA40_DEBUG_ABORT_ON_ERR BIT(9)
--#define BCM2838_DMA40_DEBUG_HALT_ON_ERR BIT(10)
--#define BCM2838_DMA40_DEBUG_DISABLE_CLK_GATE BIT(11)
--#define BCM2838_DMA40_DEBUG_RSTATE_SHIFT 14
--#define BCM2838_DMA40_DEBUG_RSTATE_BITS 4
--#define BCM2838_DMA40_DEBUG_WSTATE_SHIFT 18
--#define BCM2838_DMA40_DEBUG_WSTATE_BITS 4
--#define BCM2838_DMA40_DEBUG_RESET BIT(23)
--#define BCM2838_DMA40_DEBUG_ID_SHIFT 24
--#define BCM2838_DMA40_DEBUG_ID_BITS 4
--#define BCM2838_DMA40_DEBUG_VERSION_SHIFT 28
--#define BCM2838_DMA40_DEBUG_VERSION_BITS 4
-+#define BCM2711_DMA40_DEBUG_WRITE_ERR BIT(0)
-+#define BCM2711_DMA40_DEBUG_FIFO_ERR BIT(1)
-+#define BCM2711_DMA40_DEBUG_READ_ERR BIT(2)
-+#define BCM2711_DMA40_DEBUG_READ_CB_ERR BIT(3)
-+#define BCM2711_DMA40_DEBUG_IN_ON_ERR BIT(8)
-+#define BCM2711_DMA40_DEBUG_ABORT_ON_ERR BIT(9)
-+#define BCM2711_DMA40_DEBUG_HALT_ON_ERR BIT(10)
-+#define BCM2711_DMA40_DEBUG_DISABLE_CLK_GATE BIT(11)
-+#define BCM2711_DMA40_DEBUG_RSTATE_SHIFT 14
-+#define BCM2711_DMA40_DEBUG_RSTATE_BITS 4
-+#define BCM2711_DMA40_DEBUG_WSTATE_SHIFT 18
-+#define BCM2711_DMA40_DEBUG_WSTATE_BITS 4
-+#define BCM2711_DMA40_DEBUG_RESET BIT(23)
-+#define BCM2711_DMA40_DEBUG_ID_SHIFT 24
-+#define BCM2711_DMA40_DEBUG_ID_BITS 4
-+#define BCM2711_DMA40_DEBUG_VERSION_SHIFT 28
-+#define BCM2711_DMA40_DEBUG_VERSION_BITS 4
-
- /* Valid only for channels 0 - 3 (11 - 14) */
--#define BCM2838_DMA40_CHAN(n) (((n) + 11) << 8) /* Base address */
--#define BCM2838_DMA40_CHANIO(base, n) ((base) + BCM2838_DMA_CHAN(n))
-+#define BCM2711_DMA40_CHAN(n) (((n) + 11) << 8) /* Base address */
-+#define BCM2711_DMA40_CHANIO(base, n) ((base) + BCM2711_DMA_CHAN(n))
-
- /* the max dma length for different channels */
- #define MAX_DMA40_LEN SZ_1G
-
--#define BCM2838_DMA40_BURST_LEN(x) ((min(x,16) - 1) << 8)
--#define BCM2838_DMA40_INC BIT(12)
--#define BCM2838_DMA40_SIZE_32 (0 << 13)
--#define BCM2838_DMA40_SIZE_64 (1 << 13)
--#define BCM2838_DMA40_SIZE_128 (2 << 13)
--#define BCM2838_DMA40_SIZE_256 (3 << 13)
--#define BCM2838_DMA40_IGNORE BIT(15)
--#define BCM2838_DMA40_STRIDE(x) ((x) << 16) /* For 2D mode */
--
--#define BCM2838_DMA40_MEMCPY_FLAGS \
-- (BCM2838_DMA40_QOS(0) | \
-- BCM2838_DMA40_PANIC_QOS(0) | \
-- BCM2838_DMA40_WAIT_FOR_WRITES | \
-- BCM2838_DMA40_DISDEBUG)
--
--#define BCM2838_DMA40_MEMCPY_XFER_INFO \
-- (BCM2838_DMA40_SIZE_128 | \
-- BCM2838_DMA40_INC | \
-- BCM2838_DMA40_BURST_LEN(16))
-+#define BCM2711_DMA40_BURST_LEN(x) ((min(x,16) - 1) << 8)
-+#define BCM2711_DMA40_INC BIT(12)
-+#define BCM2711_DMA40_SIZE_32 (0 << 13)
-+#define BCM2711_DMA40_SIZE_64 (1 << 13)
-+#define BCM2711_DMA40_SIZE_128 (2 << 13)
-+#define BCM2711_DMA40_SIZE_256 (3 << 13)
-+#define BCM2711_DMA40_IGNORE BIT(15)
-+#define BCM2711_DMA40_STRIDE(x) ((x) << 16) /* For 2D mode */
-+
-+#define BCM2711_DMA40_MEMCPY_FLAGS \
-+ (BCM2711_DMA40_QOS(0) | \
-+ BCM2711_DMA40_PANIC_QOS(0) | \
-+ BCM2711_DMA40_WAIT_FOR_WRITES | \
-+ BCM2711_DMA40_DISDEBUG)
-+
-+#define BCM2711_DMA40_MEMCPY_XFER_INFO \
-+ (BCM2711_DMA40_SIZE_128 | \
-+ BCM2711_DMA40_INC | \
-+ BCM2711_DMA40_BURST_LEN(16))
-
- struct bcm2835_dmadev *memcpy_parent;
- static void __iomem *memcpy_chan;
--static struct bcm2838_dma40_scb *memcpy_scb;
-+static struct bcm2711_dma40_scb *memcpy_scb;
- static dma_addr_t memcpy_scb_dma;
- DEFINE_SPINLOCK(memcpy_lock);
-
-@@ -299,7 +299,7 @@ static const struct bcm2835_dma_cfg_data
- .chan_40bit_mask = 0,
- };
-
--static const struct bcm2835_dma_cfg_data bcm2838_dma_cfg = {
-+static const struct bcm2835_dma_cfg_data bcm2711_dma_cfg = {
- .chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
- };
-
-@@ -332,27 +332,27 @@ static inline struct bcm2835_desc *to_bc
- return container_of(t, struct bcm2835_desc, vd.tx);
- }
-
--static inline uint32_t to_bcm2838_ti(uint32_t info)
-+static inline uint32_t to_bcm2711_ti(uint32_t info)
- {
-- return ((info & BCM2835_DMA_INT_EN) ? BCM2838_DMA40_INTEN : 0) |
-- ((info & BCM2835_DMA_WAIT_RESP) ? BCM2838_DMA40_WAIT_RESP : 0) |
-+ return ((info & BCM2835_DMA_INT_EN) ? BCM2711_DMA40_INTEN : 0) |
-+ ((info & BCM2835_DMA_WAIT_RESP) ? BCM2711_DMA40_WAIT_RESP : 0) |
- ((info & BCM2835_DMA_S_DREQ) ?
-- (BCM2838_DMA40_S_DREQ | BCM2838_DMA40_WAIT_RD_RESP) : 0) |
-- ((info & BCM2835_DMA_D_DREQ) ? BCM2838_DMA40_D_DREQ : 0) |
-- BCM2838_DMA40_PER_MAP((info >> 16) & 0x1f);
-+ (BCM2711_DMA40_S_DREQ | BCM2711_DMA40_WAIT_RD_RESP) : 0) |
-+ ((info & BCM2835_DMA_D_DREQ) ? BCM2711_DMA40_D_DREQ : 0) |
-+ BCM2711_DMA40_PER_MAP((info >> 16) & 0x1f);
- }
-
--static inline uint32_t to_bcm2838_srci(uint32_t info)
-+static inline uint32_t to_bcm2711_srci(uint32_t info)
- {
-- return ((info & BCM2835_DMA_S_INC) ? BCM2838_DMA40_INC : 0);
-+ return ((info & BCM2835_DMA_S_INC) ? BCM2711_DMA40_INC : 0);
- }
-
--static inline uint32_t to_bcm2838_dsti(uint32_t info)
-+static inline uint32_t to_bcm2711_dsti(uint32_t info)
- {
-- return ((info & BCM2835_DMA_D_INC) ? BCM2838_DMA40_INC : 0);
-+ return ((info & BCM2835_DMA_D_INC) ? BCM2711_DMA40_INC : 0);
- }
-
--static inline uint32_t to_bcm2838_cbaddr(dma_addr_t addr)
-+static inline uint32_t to_bcm2711_cbaddr(dma_addr_t addr)
- {
- BUG_ON(addr & 0x1f);
- return (addr >> 5);
-@@ -412,12 +412,12 @@ static void bcm2835_dma_create_cb_set_le
- }
-
- if (c->is_40bit_channel) {
-- struct bcm2838_dma40_scb *scb =
-- (struct bcm2838_dma40_scb *)control_block;
-+ struct bcm2711_dma40_scb *scb =
-+ (struct bcm2711_dma40_scb *)control_block;
-
- scb->len = cb_len;
- /* add extrainfo bits to ti */
-- scb->ti |= to_bcm2838_ti(finalextrainfo);
-+ scb->ti |= to_bcm2711_ti(finalextrainfo);
- } else {
- control_block->length = cb_len;
- /* add extrainfo bits to info */
-@@ -500,13 +500,13 @@ static struct bcm2835_desc *bcm2835_dma_
- /* fill in the control block */
- control_block = cb_entry->cb;
- if (c->is_40bit_channel) {
-- struct bcm2838_dma40_scb *scb =
-- (struct bcm2838_dma40_scb *)control_block;
-- scb->ti = to_bcm2838_ti(info);
-+ struct bcm2711_dma40_scb *scb =
-+ (struct bcm2711_dma40_scb *)control_block;
-+ scb->ti = to_bcm2711_ti(info);
- scb->src = lower_32_bits(src);
-- scb->srci= upper_32_bits(src) | to_bcm2838_srci(info);
-+ scb->srci= upper_32_bits(src) | to_bcm2711_srci(info);
- scb->dst = lower_32_bits(dst);
-- scb->dsti = upper_32_bits(dst) | to_bcm2838_dsti(info);
-+ scb->dsti = upper_32_bits(dst) | to_bcm2711_dsti(info);
- scb->next_cb = 0;
- } else {
- control_block->info = info;
-@@ -531,7 +531,7 @@ static struct bcm2835_desc *bcm2835_dma_
- /* link this the last controlblock */
- if (frame && c->is_40bit_channel)
- d->cb_list[frame - 1].cb->next =
-- to_bcm2838_cbaddr(cb_entry->paddr);
-+ to_bcm2711_cbaddr(cb_entry->paddr);
- if (frame && !c->is_40bit_channel)
- d->cb_list[frame - 1].cb->next = cb_entry->paddr;
-
-@@ -547,10 +547,10 @@ static struct bcm2835_desc *bcm2835_dma_
-
- /* the last frame requires extra flags */
- if (c->is_40bit_channel) {
-- struct bcm2838_dma40_scb *scb =
-- (struct bcm2838_dma40_scb *)d->cb_list[d->frames-1].cb;
-+ struct bcm2711_dma40_scb *scb =
-+ (struct bcm2711_dma40_scb *)d->cb_list[d->frames-1].cb;
-
-- scb->ti |= to_bcm2838_ti(finalextrainfo);
-+ scb->ti |= to_bcm2711_ti(finalextrainfo);
- } else {
- d->cb_list[d->frames - 1].cb->info |= finalextrainfo;
- }
-@@ -581,18 +581,18 @@ static void bcm2835_dma_fill_cb_chain_wi
- max_len = bcm2835_dma_max_frame_length(c);
- for_each_sg(sgl, sgent, sg_len, i) {
- if (c->is_40bit_channel) {
-- struct bcm2838_dma40_scb *scb =
-- (struct bcm2838_dma40_scb *)cb->cb;
-+ struct bcm2711_dma40_scb *scb =
-+ (struct bcm2711_dma40_scb *)cb->cb;
- for (addr = sg_dma_address(sgent),
- len = sg_dma_len(sgent);
- len > 0;
- addr += scb->len, len -= scb->len, scb++) {
- if (direction == DMA_DEV_TO_MEM) {
- scb->dst = lower_32_bits(addr);
-- scb->dsti = upper_32_bits(addr) | BCM2838_DMA40_INC;
-+ scb->dsti = upper_32_bits(addr) | BCM2711_DMA40_INC;
- } else {
- scb->src = lower_32_bits(addr);
-- scb->srci = upper_32_bits(addr) | BCM2838_DMA40_INC;
-+ scb->srci = upper_32_bits(addr) | BCM2711_DMA40_INC;
- }
- scb->len = min(len, max_len);
- }
-@@ -619,7 +619,7 @@ static void bcm2835_dma_abort(struct bcm
- u32 wait_mask = BCM2835_DMA_WAITING_FOR_WRITES;
-
- if (c->is_40bit_channel)
-- wait_mask = BCM2838_DMA40_WAITING_FOR_WRITES;
-+ wait_mask = BCM2711_DMA40_WAITING_FOR_WRITES;
-
- /*
- * A zero control block address means the channel is idle.
-@@ -658,10 +658,10 @@ static void bcm2835_dma_start_desc(struc
- c->desc = d = to_bcm2835_dma_desc(&vd->tx);
-
- if (c->is_40bit_channel) {
-- writel(to_bcm2838_cbaddr(d->cb_list[0].paddr),
-- c->chan_base + BCM2838_DMA40_CB);
-- writel(BCM2838_DMA40_ACTIVE | BCM2838_DMA40_CS_FLAGS(c->dreq),
-- c->chan_base + BCM2838_DMA40_CS);
-+ writel(to_bcm2711_cbaddr(d->cb_list[0].paddr),
-+ c->chan_base + BCM2711_DMA40_CB);
-+ writel(BCM2711_DMA40_ACTIVE | BCM2711_DMA40_CS_FLAGS(c->dreq),
-+ c->chan_base + BCM2711_DMA40_CS);
- } else {
- writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
- writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
-@@ -694,7 +694,7 @@ static irqreturn_t bcm2835_dma_callback(
- * will remain idle despite the ACTIVE flag being set.
- */
- writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE |
-- (c->is_40bit_channel ? BCM2838_DMA40_CS_FLAGS(c->dreq) :
-+ (c->is_40bit_channel ? BCM2711_DMA40_CS_FLAGS(c->dreq) :
- BCM2835_DMA_CS_FLAGS(c->dreq)),
- c->chan_base + BCM2835_DMA_CS);
-
-@@ -799,14 +799,14 @@ static enum dma_status bcm2835_dma_tx_st
- dma_addr_t pos;
-
- if (d->dir == DMA_MEM_TO_DEV && c->is_40bit_channel)
-- pos = readl(c->chan_base + BCM2838_DMA40_SRC) +
-- ((readl(c->chan_base + BCM2838_DMA40_SRCI) &
-+ pos = readl(c->chan_base + BCM2711_DMA40_SRC) +
-+ ((readl(c->chan_base + BCM2711_DMA40_SRCI) &
- 0xff) << 8);
- else if (d->dir == DMA_MEM_TO_DEV && !c->is_40bit_channel)
- pos = readl(c->chan_base + BCM2835_DMA_SOURCE_AD);
- else if (d->dir == DMA_DEV_TO_MEM && c->is_40bit_channel)
-- pos = readl(c->chan_base + BCM2838_DMA40_DEST) +
-- ((readl(c->chan_base + BCM2838_DMA40_DESTI) &
-+ pos = readl(c->chan_base + BCM2711_DMA40_DEST) +
-+ ((readl(c->chan_base + BCM2711_DMA40_DESTI) &
- 0xff) << 8);
- else if (d->dir == DMA_DEV_TO_MEM && !c->is_40bit_channel)
- pos = readl(c->chan_base + BCM2835_DMA_DEST_AD);
-@@ -1007,7 +1007,7 @@ static struct dma_async_tx_descriptor *b
-
- /* wrap around into a loop */
- d->cb_list[d->frames - 1].cb->next = c->is_40bit_channel ?
-- to_bcm2838_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr;
-+ to_bcm2711_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr;
-
- return vchan_tx_prep(&c->vc, &d->vd, flags);
- }
-@@ -1095,7 +1095,7 @@ static void bcm2835_dma_free(struct bcm2
- DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
- }
-
--int bcm2838_dma40_memcpy_init(void)
-+int bcm2711_dma40_memcpy_init(void)
- {
- if (!memcpy_parent)
- return -EPROBE_DEFER;
-@@ -1108,15 +1108,15 @@ int bcm2838_dma40_memcpy_init(void)
-
- return 0;
- }
--EXPORT_SYMBOL(bcm2838_dma40_memcpy_init);
-+EXPORT_SYMBOL(bcm2711_dma40_memcpy_init);
-
--void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size)
-+void bcm2711_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size)
- {
-- struct bcm2838_dma40_scb *scb = memcpy_scb;
-+ struct bcm2711_dma40_scb *scb = memcpy_scb;
- unsigned long flags;
-
- if (!scb) {
-- pr_err("bcm2838_dma40_memcpy not initialised!\n");
-+ pr_err("bcm2711_dma40_memcpy not initialised!\n");
- return;
- }
-
-@@ -1124,29 +1124,29 @@ void bcm2838_dma40_memcpy(dma_addr_t dst
-
- scb->ti = 0;
- scb->src = lower_32_bits(src);
-- scb->srci = upper_32_bits(src) | BCM2838_DMA40_MEMCPY_XFER_INFO;
-+ scb->srci = upper_32_bits(src) | BCM2711_DMA40_MEMCPY_XFER_INFO;
- scb->dst = lower_32_bits(dst);
-- scb->dsti = upper_32_bits(dst) | BCM2838_DMA40_MEMCPY_XFER_INFO;
-+ scb->dsti = upper_32_bits(dst) | BCM2711_DMA40_MEMCPY_XFER_INFO;
- scb->len = size;
- scb->next_cb = 0;
-
-- writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2838_DMA40_CB);
-- writel(BCM2838_DMA40_MEMCPY_FLAGS + BCM2838_DMA40_ACTIVE,
-- memcpy_chan + BCM2838_DMA40_CS);
-+ writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2711_DMA40_CB);
-+ writel(BCM2711_DMA40_MEMCPY_FLAGS + BCM2711_DMA40_ACTIVE,
-+ memcpy_chan + BCM2711_DMA40_CS);
-
- /* Poll for completion */
-- while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_END))
-+ while (!(readl(memcpy_chan + BCM2711_DMA40_CS) & BCM2711_DMA40_END))
- cpu_relax();
-
-- writel(BCM2838_DMA40_END, memcpy_chan + BCM2838_DMA40_CS);
-+ writel(BCM2711_DMA40_END, memcpy_chan + BCM2711_DMA40_CS);
-
- spin_unlock_irqrestore(&memcpy_lock, flags);
- }
--EXPORT_SYMBOL(bcm2838_dma40_memcpy);
-+EXPORT_SYMBOL(bcm2711_dma40_memcpy);
-
- static const struct of_device_id bcm2835_dma_of_match[] = {
- { .compatible = "brcm,bcm2835-dma", .data = &bcm2835_dma_cfg },
-- { .compatible = "brcm,bcm2838-dma", .data = &bcm2838_dma_cfg },
-+ { .compatible = "brcm,bcm2711-dma", .data = &bcm2711_dma_cfg },
- {},
- };
- MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match);
-@@ -1274,9 +1274,9 @@ static int bcm2835_dma_probe(struct plat
-
- /* And possibly one for the 40-bit DMA memcpy API */
- if (chans_available & od->cfg_data->chan_40bit_mask &
-- BIT(BCM2838_DMA_MEMCPY_CHAN)) {
-+ BIT(BCM2711_DMA_MEMCPY_CHAN)) {
- memcpy_parent = od;
-- memcpy_chan = BCM2835_DMA_CHANIO(base, BCM2838_DMA_MEMCPY_CHAN);
-+ memcpy_chan = BCM2835_DMA_CHANIO(base, BCM2711_DMA_MEMCPY_CHAN);
- memcpy_scb = dma_alloc_coherent(memcpy_parent->ddev.dev,
- sizeof(*memcpy_scb),
- &memcpy_scb_dma, GFP_KERNEL);
-@@ -1284,7 +1284,7 @@ static int bcm2835_dma_probe(struct plat
- dev_warn(&pdev->dev,
- "Failed to allocated memcpy scb\n");
-
-- chans_available &= ~BIT(BCM2838_DMA_MEMCPY_CHAN);
-+ chans_available &= ~BIT(BCM2711_DMA_MEMCPY_CHAN);
- }
-
- /* get irqs for each channel that we support */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0441-of-address-Introduce-of_get_next_dma_parent-helper.patch b/target/linux/bcm27xx/patches-5.4/950-0441-of-address-Introduce-of_get_next_dma_parent-helper.patch
new file mode 100644
index 0000000000..1056cfc60d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0441-of-address-Introduce-of_get_next_dma_parent-helper.patch
@@ -0,0 +1,39 @@
+From 25ab98ceb9844642c994b5766de1033552d1aef2 Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Wed, 3 Jul 2019 18:23:01 +0100
+Subject: [PATCH] of/address: Introduce of_get_next_dma_parent() helper
+
+commit 862ab5578f754117742c8b8c8e5ddf98bdb190ba upstream.
+
+Add of_get_next_dma_parent() helper which is similar to
+__of_get_dma_parent(), but can be used in iterators and decrements the
+ref count on the prior parent.
+
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ drivers/of/address.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -695,6 +695,16 @@ static struct device_node *__of_get_dma_
+ return of_node_get(args.np);
+ }
+
++static struct device_node *of_get_next_dma_parent(struct device_node *np)
++{
++ struct device_node *parent;
++
++ parent = __of_get_dma_parent(np);
++ of_node_put(np);
++
++ return parent;
++}
++
+ u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
+ {
+ struct device_node *host;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0442-of-address-Follow-DMA-parent-for-dma-coherent.patch b/target/linux/bcm27xx/patches-5.4/950-0442-of-address-Follow-DMA-parent-for-dma-coherent.patch
new file mode 100644
index 0000000000..dbfb1025cd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0442-of-address-Follow-DMA-parent-for-dma-coherent.patch
@@ -0,0 +1,30 @@
+From e4a649779ff6857240fe691cdf147a3b4896e71b Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Wed, 3 Jul 2019 14:47:31 +0100
+Subject: [PATCH] of: address: Follow DMA parent for "dma-coherent"
+
+commit c60bf3eb888a362100aa1bdbea351dab681e262a upstream.
+
+Much like for address translation, when checking for DMA coherence we
+should be sure to walk up the DMA hierarchy, rather than the MMIO one,
+now that we can accommodate them being different.
+
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ drivers/of/address.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -1023,7 +1023,7 @@ bool of_dma_is_coherent(struct device_no
+ of_node_put(node);
+ return true;
+ }
+- node = of_get_next_parent(node);
++ node = of_get_next_dma_parent(node);
+ }
+ of_node_put(node);
+ return false;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0443-of-Factor-out-addr-size-cells-parsing.patch b/target/linux/bcm27xx/patches-5.4/950-0443-of-Factor-out-addr-size-cells-parsing.patch
new file mode 100644
index 0000000000..045ee9827f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0443-of-Factor-out-addr-size-cells-parsing.patch
@@ -0,0 +1,117 @@
+From 839aeedc908eb729b9014e7d1d38e109778a52d2 Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Tue, 2 Jul 2019 18:42:39 +0100
+Subject: [PATCH] of: Factor out #{addr,size}-cells parsing
+
+In some cases such as PCI host controllers, we may have a "parent bus"
+which is an OF leaf node, but still need to correctly parse ranges from
+the point of view of that bus. For that, factor out variants of the
+"#addr-cells" and "#size-cells" parsers which do not assume they have a
+device node and thus immediately traverse upwards before reading the
+relevant property.
+
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+[robh: don't make of_bus_n_{addr,size}_cells() public]
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Rob Herring <robh@kernel.org>
+
+(cherry picked from commit b68ac8dc22ebbf003e26e44bf4dd3030c076df5a)
+---
+ drivers/of/address.c | 2 ++
+ drivers/of/base.c | 32 ++++++++++++++++++++++----------
+ drivers/of/of_private.h | 14 ++++++++++++++
+ 3 files changed, 38 insertions(+), 10 deletions(-)
+
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -14,6 +14,8 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+
++#include "of_private.h"
++
+ /* Max address size we deal with */
+ #define OF_MAX_ADDR_CELLS 4
+ #define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -86,34 +86,46 @@ static bool __of_node_is_type(const stru
+ return np && match && type && !strcmp(match, type);
+ }
+
+-int of_n_addr_cells(struct device_node *np)
++int of_bus_n_addr_cells(struct device_node *np)
+ {
+ u32 cells;
+
+- do {
+- if (np->parent)
+- np = np->parent;
++ for (; np; np = np->parent)
+ if (!of_property_read_u32(np, "#address-cells", &cells))
+ return cells;
+- } while (np->parent);
++
+ /* No #address-cells property for the root node */
+ return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+ }
++
++int of_n_addr_cells(struct device_node *np)
++{
++ if (np->parent)
++ np = np->parent;
++
++ return of_bus_n_addr_cells(np);
++}
+ EXPORT_SYMBOL(of_n_addr_cells);
+
+-int of_n_size_cells(struct device_node *np)
++int of_bus_n_size_cells(struct device_node *np)
+ {
+ u32 cells;
+
+- do {
+- if (np->parent)
+- np = np->parent;
++ for (; np; np = np->parent)
+ if (!of_property_read_u32(np, "#size-cells", &cells))
+ return cells;
+- } while (np->parent);
++
+ /* No #size-cells property for the root node */
+ return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+ }
++
++int of_n_size_cells(struct device_node *np)
++{
++ if (np->parent)
++ np = np->parent;
++
++ return of_bus_n_size_cells(np);
++}
+ EXPORT_SYMBOL(of_n_size_cells);
+
+ #ifdef CONFIG_NUMA
+--- a/drivers/of/of_private.h
++++ b/drivers/of/of_private.h
+@@ -158,4 +158,18 @@ extern void __of_sysfs_remove_bin_file(s
+ #define for_each_transaction_entry_reverse(_oft, _te) \
+ list_for_each_entry_reverse(_te, &(_oft)->te_list, node)
+
++extern int of_bus_n_addr_cells(struct device_node *np);
++extern int of_bus_n_size_cells(struct device_node *np);
++
++#ifdef CONFIG_OF_ADDRESS
++extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
++ u64 *paddr, u64 *size);
++#else
++static inline int of_dma_get_range(struct device_node *np, u64 *dma_addr,
++ u64 *paddr, u64 *size)
++{
++ return -ENODEV;
++}
++#endif
++
+ #endif /* _LINUX_OF_PRIVATE_H */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0444-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch b/target/linux/bcm27xx/patches-5.4/950-0444-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch
new file mode 100644
index 0000000000..28d1987a9c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0444-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch
@@ -0,0 +1,40 @@
+From 39f5d9e883393e32938eac45b564f74afde8a942 Mon Sep 17 00:00:00 2001
+From: Rob Herring <robh@kernel.org>
+Date: Wed, 4 Sep 2019 11:43:30 +0100
+Subject: [PATCH] of/address: Translate 'dma-ranges' for parent nodes
+ missing 'dma-ranges'
+
+commit 81db12ee15cb83926e290a8a3654a2dfebc80935 upstream.
+
+'dma-ranges' frequently exists without parent nodes having 'dma-ranges'.
+While this is an error for 'ranges', this is fine because DMA capable
+devices always have a translatable DMA address. Also, with no
+'dma-ranges' at all, the assumption is that DMA addresses are 1:1 with
+no restrictions unless perhaps the device itself has implicit
+restrictions.
+
+Cc: Robin Murphy <robin.murphy@arm.com>
+Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ drivers/of/address.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -519,9 +519,13 @@ static int of_translate_one(struct devic
+ *
+ * As far as we know, this damage only exists on Apple machines, so
+ * This code is only enabled on powerpc. --gcl
++ *
++ * This quirk also applies for 'dma-ranges' which frequently exist in
++ * child nodes without 'dma-ranges' in the parent nodes. --RobH
+ */
+ ranges = of_get_property(parent, rprop, &rlen);
+- if (ranges == NULL && !of_empty_ranges_quirk(parent)) {
++ if (ranges == NULL && !of_empty_ranges_quirk(parent) &&
++ strcmp(rprop, "dma-ranges")) {
+ pr_debug("no ranges; cannot translate\n");
+ return 1;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0444-pcie-brcmstb-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0444-pcie-brcmstb-Correct-SoC-name.patch
deleted file mode 100644
index 3bbcdd5829..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0444-pcie-brcmstb-Correct-SoC-name.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 900b4ad0814df7dbacb01318bf49af5bab605fa0 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.com>
-Date: Fri, 31 Jan 2020 09:39:40 +0000
-Subject: [PATCH] pcie-brcmstb: Correct SoC name
-
-The Pi 4 SoC is called BCM2711, not BCM2838.
-
-Fixes: "bcm2835-dma: Add proper 40-bit DMA support"
-Fixes: "Ported pcie-brcmstb bounce buffer implementation to ARM64."
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.com>
----
- drivers/pci/controller/pcie-brcmstb-bounce.c | 10 +++++-----
- drivers/pci/controller/pcie-brcmstb-bounce64.c | 10 +++++-----
- 2 files changed, 10 insertions(+), 10 deletions(-)
-
---- a/drivers/pci/controller/pcie-brcmstb-bounce.c
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce.c
-@@ -91,8 +91,8 @@ struct dmabounce_device_info {
-
- static struct dmabounce_device_info *g_dmabounce_device_info;
-
--extern int bcm2838_dma40_memcpy_init(void);
--extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size);
-+extern int bcm2711_dma40_memcpy_init(void);
-+extern void bcm2711_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size);
-
- #ifdef STATS
- static ssize_t
-@@ -320,7 +320,7 @@ map_single(struct device *dev, struct sa
-
- if ((dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) &&
- !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-- bcm2838_dma40_memcpy(buf->safe_dma_addr, buf->unsafe_dma_addr,
-+ bcm2711_dma40_memcpy(buf->safe_dma_addr, buf->unsafe_dma_addr,
- size);
-
- return buf->safe_dma_addr;
-@@ -338,7 +338,7 @@ unmap_single(struct device *dev, struct
- dev_dbg(dev, "unmap: %llx->%llx\n", (u64)buf->safe_dma_addr,
- (u64)buf->unsafe_dma_addr);
-
-- bcm2838_dma40_memcpy(buf->unsafe_dma_addr, buf->safe_dma_addr,
-+ bcm2711_dma40_memcpy(buf->unsafe_dma_addr, buf->safe_dma_addr,
- size);
- }
- return buf->unsafe_dma_addr;
-@@ -476,7 +476,7 @@ int brcm_pcie_bounce_init(struct device
- if (g_dmabounce_device_info)
- return -EBUSY;
-
-- ret = bcm2838_dma40_memcpy_init();
-+ ret = bcm2711_dma40_memcpy_init();
- if (ret)
- return ret;
-
---- a/drivers/pci/controller/pcie-brcmstb-bounce64.c
-+++ b/drivers/pci/controller/pcie-brcmstb-bounce64.c
-@@ -93,8 +93,8 @@ struct dmabounce_device_info {
-
- static struct dmabounce_device_info *g_dmabounce_device_info;
-
--extern int bcm2838_dma40_memcpy_init(void);
--extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size);
-+extern int bcm2711_dma40_memcpy_init(void);
-+extern void bcm2711_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size);
-
- #ifdef STATS
- static ssize_t
-@@ -322,7 +322,7 @@ map_single(struct device *dev, struct sa
-
- if ((dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) &&
- !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-- bcm2838_dma40_memcpy(buf->safe_dma_addr, buf->unsafe_dma_addr,
-+ bcm2711_dma40_memcpy(buf->safe_dma_addr, buf->unsafe_dma_addr,
- size);
-
- return buf->safe_dma_addr;
-@@ -340,7 +340,7 @@ unmap_single(struct device *dev, struct
- dev_dbg(dev, "unmap: %llx->%llx\n", (u64)buf->safe_dma_addr,
- (u64)buf->unsafe_dma_addr);
-
-- bcm2838_dma40_memcpy(buf->unsafe_dma_addr, buf->safe_dma_addr,
-+ bcm2711_dma40_memcpy(buf->unsafe_dma_addr, buf->safe_dma_addr,
- size);
- }
- return buf->unsafe_dma_addr;
-@@ -483,7 +483,7 @@ int brcm_pcie_bounce_init(struct device
- if (g_dmabounce_device_info)
- return -EBUSY;
-
-- ret = bcm2838_dma40_memcpy_init();
-+ ret = bcm2711_dma40_memcpy_init();
- if (ret)
- return ret;
-
diff --git a/target/linux/bcm27xx/patches-5.4/950-0445-of-Make-of_dma_get_range-work-on-bus-nodes.patch b/target/linux/bcm27xx/patches-5.4/950-0445-of-Make-of_dma_get_range-work-on-bus-nodes.patch
new file mode 100644
index 0000000000..1cac2dfcd8
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0445-of-Make-of_dma_get_range-work-on-bus-nodes.patch
@@ -0,0 +1,107 @@
+From 7631cb95056f03136c9e0a35484e8bebe7b52650 Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Wed, 3 Jul 2019 18:42:20 +0100
+Subject: [PATCH] of: Make of_dma_get_range() work on bus nodes
+
+commit 951d48855d86e72e0d6de73440fe09d363168064 upstream.
+
+Since the "dma-ranges" property is only valid for a node representing a
+bus, of_dma_get_range() currently assumes the node passed in is a leaf
+representing a device, and starts the walk from its parent. In cases
+like PCI host controllers on typical FDT systems, however, where the PCI
+endpoints are probed dynamically the initial leaf node represents the
+'bus' itself, and this logic means we fail to consider any "dma-ranges"
+describing the host bridge itself. Rework the logic such that
+of_dma_get_range() also works correctly starting from a bus node
+containing "dma-ranges".
+
+While this does mean "dma-ranges" could incorrectly be in a device leaf
+node, there isn't really any way in this function to ensure that a leaf
+node is or isn't a bus node.
+
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+[robh: Allow for the bus child node to still be passed in]
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+---
+ drivers/of/address.c | 44 ++++++++++++++++++--------------------------
+ 1 file changed, 18 insertions(+), 26 deletions(-)
+
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -940,47 +940,39 @@ int of_dma_get_range(struct device_node
+ const __be32 *ranges = NULL;
+ int len, naddr, nsize, pna;
+ int ret = 0;
++ bool found_dma_ranges = false;
+ u64 dmaaddr;
+
+- if (!node)
+- return -EINVAL;
+-
+- while (1) {
+- struct device_node *parent;
+-
+- naddr = of_n_addr_cells(node);
+- nsize = of_n_size_cells(node);
+-
+- parent = __of_get_dma_parent(node);
+- of_node_put(node);
+-
+- node = parent;
+- if (!node)
+- break;
+-
++ while (node) {
+ ranges = of_get_property(node, "dma-ranges", &len);
+
+ /* Ignore empty ranges, they imply no translation required */
+ if (ranges && len > 0)
+ break;
+
+- /*
+- * At least empty ranges has to be defined for parent node if
+- * DMA is supported
+- */
+- if (!ranges)
+- break;
++ /* Once we find 'dma-ranges', then a missing one is an error */
++ if (found_dma_ranges && !ranges) {
++ ret = -ENODEV;
++ goto out;
++ }
++ found_dma_ranges = true;
++
++ node = of_get_next_dma_parent(node);
+ }
+
+- if (!ranges) {
++ if (!node || !ranges) {
+ pr_debug("no dma-ranges found for node(%pOF)\n", np);
+ ret = -ENODEV;
+ goto out;
+ }
+
+- len /= sizeof(u32);
+-
++ naddr = of_bus_n_addr_cells(node);
++ nsize = of_bus_n_size_cells(node);
+ pna = of_n_addr_cells(node);
++ if ((len / sizeof(__be32)) % (pna + naddr + nsize)) {
++ ret = -EINVAL;
++ goto out;
++ }
+
+ /* dma-ranges format:
+ * DMA addr : naddr cells
+@@ -988,7 +980,7 @@ int of_dma_get_range(struct device_node
+ * size : nsize cells
+ */
+ dmaaddr = of_read_number(ranges, naddr);
+- *paddr = of_translate_dma_address(np, ranges);
++ *paddr = of_translate_dma_address(node, ranges + naddr);
+ if (*paddr == OF_BAD_ADDR) {
+ pr_err("translation of DMA address(%pad) to CPU address failed node(%pOF)\n",
+ dma_addr, np);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0446-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch b/target/linux/bcm27xx/patches-5.4/950-0446-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch
new file mode 100644
index 0000000000..a90e7f8587
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0446-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch
@@ -0,0 +1,30 @@
+From c17f622cbb33332a305ef383506740d3d01aa831 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 11 Sep 2019 20:25:43 +0200
+Subject: [PATCH] arm64: mm: use arm64_dma_phys_limit instead of
+ calling max_zone_dma_phys()
+
+commit ae970dc096b2d39f65f2e18d142e3978dc9ee1c7 upstream.
+
+By the time we call zones_sizes_init() arm64_dma_phys_limit already
+contains the result of max_zone_dma_phys(). We use the variable instead
+of calling the function directly to save some precious cpu time.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+---
+ arch/arm64/mm/init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/mm/init.c
++++ b/arch/arm64/mm/init.c
+@@ -187,7 +187,7 @@ static void __init zone_sizes_init(unsig
+ unsigned long max_zone_pfns[MAX_NR_ZONES] = {0};
+
+ #ifdef CONFIG_ZONE_DMA32
+- max_zone_pfns[ZONE_DMA32] = PFN_DOWN(max_zone_dma_phys());
++ max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma_phys_limit);
+ #endif
+ max_zone_pfns[ZONE_NORMAL] = max;
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0447-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch b/target/linux/bcm27xx/patches-5.4/950-0447-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch
new file mode 100644
index 0000000000..3039bfe822
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0447-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch
@@ -0,0 +1,117 @@
+From 4d2bd7f66bac81b042afc2a6e742bd776a5a3938 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 11 Sep 2019 20:25:44 +0200
+Subject: [PATCH] arm64: rename variables used to calculate
+ ZONE_DMA32's size
+
+commit a573cdd7973dedd87e62196c400332896bb236c8 upstream.
+
+Let the name indicate that they are used to calculate ZONE_DMA32's size
+as opposed to ZONE_DMA.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+---
+ arch/arm64/mm/init.c | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+--- a/arch/arm64/mm/init.c
++++ b/arch/arm64/mm/init.c
+@@ -56,7 +56,7 @@ EXPORT_SYMBOL(physvirt_offset);
+ struct page *vmemmap __ro_after_init;
+ EXPORT_SYMBOL(vmemmap);
+
+-phys_addr_t arm64_dma_phys_limit __ro_after_init;
++phys_addr_t arm64_dma32_phys_limit __ro_after_init;
+
+ #ifdef CONFIG_KEXEC_CORE
+ /*
+@@ -174,7 +174,7 @@ static void __init reserve_elfcorehdr(vo
+ * currently assumes that for memory starting above 4G, 32-bit devices will
+ * use a DMA offset.
+ */
+-static phys_addr_t __init max_zone_dma_phys(void)
++static phys_addr_t __init max_zone_dma32_phys(void)
+ {
+ phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
+ return min(offset + (1ULL << 32), memblock_end_of_DRAM());
+@@ -187,7 +187,7 @@ static void __init zone_sizes_init(unsig
+ unsigned long max_zone_pfns[MAX_NR_ZONES] = {0};
+
+ #ifdef CONFIG_ZONE_DMA32
+- max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma_phys_limit);
++ max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma32_phys_limit);
+ #endif
+ max_zone_pfns[ZONE_NORMAL] = max;
+
+@@ -200,16 +200,16 @@ static void __init zone_sizes_init(unsig
+ {
+ struct memblock_region *reg;
+ unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
+- unsigned long max_dma = min;
++ unsigned long max_dma32 = min;
+
+ memset(zone_size, 0, sizeof(zone_size));
+
+ /* 4GB maximum for 32-bit only capable devices */
+ #ifdef CONFIG_ZONE_DMA32
+- max_dma = PFN_DOWN(arm64_dma_phys_limit);
+- zone_size[ZONE_DMA32] = max_dma - min;
++ max_dma32 = PFN_DOWN(arm64_dma32_phys_limit);
++ zone_size[ZONE_DMA32] = max_dma32 - min;
+ #endif
+- zone_size[ZONE_NORMAL] = max - max_dma;
++ zone_size[ZONE_NORMAL] = max - max_dma32;
+
+ memcpy(zhole_size, zone_size, sizeof(zhole_size));
+
+@@ -221,14 +221,14 @@ static void __init zone_sizes_init(unsig
+ continue;
+
+ #ifdef CONFIG_ZONE_DMA32
+- if (start < max_dma) {
+- unsigned long dma_end = min(end, max_dma);
++ if (start < max_dma32) {
++ unsigned long dma_end = min(end, max_dma32);
+ zhole_size[ZONE_DMA32] -= dma_end - start;
+ }
+ #endif
+- if (end > max_dma) {
++ if (end > max_dma32) {
+ unsigned long normal_end = min(end, max);
+- unsigned long normal_start = max(start, max_dma);
++ unsigned long normal_start = max(start, max_dma32);
+ zhole_size[ZONE_NORMAL] -= normal_end - normal_start;
+ }
+ }
+@@ -420,9 +420,9 @@ void __init arm64_memblock_init(void)
+
+ /* 4GB maximum for 32-bit only capable devices */
+ if (IS_ENABLED(CONFIG_ZONE_DMA32))
+- arm64_dma_phys_limit = max_zone_dma_phys();
++ arm64_dma32_phys_limit = max_zone_dma32_phys();
+ else
+- arm64_dma_phys_limit = PHYS_MASK + 1;
++ arm64_dma32_phys_limit = PHYS_MASK + 1;
+
+ reserve_crashkernel();
+
+@@ -430,7 +430,7 @@ void __init arm64_memblock_init(void)
+
+ high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
+
+- dma_contiguous_reserve(arm64_dma_phys_limit);
++ dma_contiguous_reserve(arm64_dma32_phys_limit);
+ }
+
+ void __init bootmem_init(void)
+@@ -534,7 +534,7 @@ static void __init free_unused_memmap(vo
+ void __init mem_init(void)
+ {
+ if (swiotlb_force == SWIOTLB_FORCE ||
+- max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT))
++ max_pfn > (arm64_dma32_phys_limit >> PAGE_SHIFT))
+ swiotlb_init(1);
+ else
+ swiotlb_force = SWIOTLB_NO_FORCE;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0448-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch b/target/linux/bcm27xx/patches-5.4/950-0448-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch
new file mode 100644
index 0000000000..2397c71af7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0448-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch
@@ -0,0 +1,174 @@
+From 1fb65f4bc30fbadd0c89521985ff8142693c9631 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 11 Sep 2019 20:25:45 +0200
+Subject: [PATCH] arm64: use both ZONE_DMA and ZONE_DMA32
+
+commit 1a8e1cef7603e218339ac63cb3178b25554524e5 upstream.
+
+So far all arm64 devices have supported 32 bit DMA masks for their
+peripherals. This is not true anymore for the Raspberry Pi 4 as most of
+it's peripherals can only address the first GB of memory on a total of
+up to 4 GB.
+
+This goes against ZONE_DMA32's intent, as it's expected for ZONE_DMA32
+to be addressable with a 32 bit mask. So it was decided to re-introduce
+ZONE_DMA in arm64.
+
+ZONE_DMA will contain the lower 1G of memory, which is currently the
+memory area addressable by any peripheral on an arm64 device.
+ZONE_DMA32 will contain the rest of the 32 bit addressable memory.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+---
+ arch/arm64/Kconfig | 4 +++
+ arch/arm64/include/asm/page.h | 2 ++
+ arch/arm64/mm/init.c | 54 +++++++++++++++++++++++++----------
+ 3 files changed, 45 insertions(+), 15 deletions(-)
+
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -267,6 +267,10 @@ config GENERIC_CSUM
+ config GENERIC_CALIBRATE_DELAY
+ def_bool y
+
++config ZONE_DMA
++ bool "Support DMA zone" if EXPERT
++ default y
++
+ config ZONE_DMA32
+ bool "Support DMA32 zone" if EXPERT
+ default y
+--- a/arch/arm64/include/asm/page.h
++++ b/arch/arm64/include/asm/page.h
+@@ -38,4 +38,6 @@ extern int pfn_valid(unsigned long);
+
+ #include <asm-generic/getorder.h>
+
++#define ARCH_ZONE_DMA_BITS 30
++
+ #endif
+--- a/arch/arm64/mm/init.c
++++ b/arch/arm64/mm/init.c
+@@ -56,6 +56,13 @@ EXPORT_SYMBOL(physvirt_offset);
+ struct page *vmemmap __ro_after_init;
+ EXPORT_SYMBOL(vmemmap);
+
++/*
++ * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of
++ * memory as some devices, namely the Raspberry Pi 4, have peripherals with
++ * this limited view of the memory. ZONE_DMA32 will cover the rest of the 32
++ * bit addressable memory area.
++ */
++phys_addr_t arm64_dma_phys_limit __ro_after_init;
+ phys_addr_t arm64_dma32_phys_limit __ro_after_init;
+
+ #ifdef CONFIG_KEXEC_CORE
+@@ -169,15 +176,16 @@ static void __init reserve_elfcorehdr(vo
+ {
+ }
+ #endif /* CONFIG_CRASH_DUMP */
++
+ /*
+- * Return the maximum physical address for ZONE_DMA32 (DMA_BIT_MASK(32)). It
+- * currently assumes that for memory starting above 4G, 32-bit devices will
+- * use a DMA offset.
++ * Return the maximum physical address for a zone with a given address size
++ * limit. It currently assumes that for memory starting above 4G, 32-bit
++ * devices will use a DMA offset.
+ */
+-static phys_addr_t __init max_zone_dma32_phys(void)
++static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
+ {
+- phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
+- return min(offset + (1ULL << 32), memblock_end_of_DRAM());
++ phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
++ return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
+ }
+
+ #ifdef CONFIG_NUMA
+@@ -186,6 +194,9 @@ static void __init zone_sizes_init(unsig
+ {
+ unsigned long max_zone_pfns[MAX_NR_ZONES] = {0};
+
++#ifdef CONFIG_ZONE_DMA
++ max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
++#endif
+ #ifdef CONFIG_ZONE_DMA32
+ max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma32_phys_limit);
+ #endif
+@@ -201,13 +212,18 @@ static void __init zone_sizes_init(unsig
+ struct memblock_region *reg;
+ unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
+ unsigned long max_dma32 = min;
++ unsigned long max_dma = min;
+
+ memset(zone_size, 0, sizeof(zone_size));
+
+- /* 4GB maximum for 32-bit only capable devices */
++#ifdef CONFIG_ZONE_DMA
++ max_dma = PFN_DOWN(arm64_dma_phys_limit);
++ zone_size[ZONE_DMA] = max_dma - min;
++ max_dma32 = max_dma;
++#endif
+ #ifdef CONFIG_ZONE_DMA32
+ max_dma32 = PFN_DOWN(arm64_dma32_phys_limit);
+- zone_size[ZONE_DMA32] = max_dma32 - min;
++ zone_size[ZONE_DMA32] = max_dma32 - max_dma;
+ #endif
+ zone_size[ZONE_NORMAL] = max - max_dma32;
+
+@@ -219,11 +235,17 @@ static void __init zone_sizes_init(unsig
+
+ if (start >= max)
+ continue;
+-
++#ifdef CONFIG_ZONE_DMA
++ if (start < max_dma) {
++ unsigned long dma_end = min_not_zero(end, max_dma);
++ zhole_size[ZONE_DMA] -= dma_end - start;
++ }
++#endif
+ #ifdef CONFIG_ZONE_DMA32
+ if (start < max_dma32) {
+- unsigned long dma_end = min(end, max_dma32);
+- zhole_size[ZONE_DMA32] -= dma_end - start;
++ unsigned long dma32_end = min(end, max_dma32);
++ unsigned long dma32_start = max(start, max_dma);
++ zhole_size[ZONE_DMA32] -= dma32_end - dma32_start;
+ }
+ #endif
+ if (end > max_dma32) {
+@@ -418,9 +440,11 @@ void __init arm64_memblock_init(void)
+
+ early_init_fdt_scan_reserved_mem();
+
+- /* 4GB maximum for 32-bit only capable devices */
++ if (IS_ENABLED(CONFIG_ZONE_DMA))
++ arm64_dma_phys_limit = max_zone_phys(ARCH_ZONE_DMA_BITS);
++
+ if (IS_ENABLED(CONFIG_ZONE_DMA32))
+- arm64_dma32_phys_limit = max_zone_dma32_phys();
++ arm64_dma32_phys_limit = max_zone_phys(32);
+ else
+ arm64_dma32_phys_limit = PHYS_MASK + 1;
+
+@@ -430,7 +454,7 @@ void __init arm64_memblock_init(void)
+
+ high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
+
+- dma_contiguous_reserve(arm64_dma32_phys_limit);
++ dma_contiguous_reserve(arm64_dma_phys_limit ? : arm64_dma32_phys_limit);
+ }
+
+ void __init bootmem_init(void)
+@@ -534,7 +558,7 @@ static void __init free_unused_memmap(vo
+ void __init mem_init(void)
+ {
+ if (swiotlb_force == SWIOTLB_FORCE ||
+- max_pfn > (arm64_dma32_phys_limit >> PAGE_SHIFT))
++ max_pfn > PFN_DOWN(arm64_dma_phys_limit ? : arm64_dma32_phys_limit))
+ swiotlb_init(1);
+ else
+ swiotlb_force = SWIOTLB_NO_FORCE;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0449-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch b/target/linux/bcm27xx/patches-5.4/950-0449-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch
new file mode 100644
index 0000000000..23811e0b6e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0449-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch
@@ -0,0 +1,84 @@
+From 1c108eaeae73a504ac1b2d882bc1fefb91eecf17 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Wed, 11 Sep 2019 20:25:46 +0200
+Subject: [PATCH] mm: refresh ZONE_DMA and ZONE_DMA32 comments in 'enum
+ zone_type'
+
+commit 734f9246e791d8da278957b2c326d7709b2a97c0 upstream.
+
+These zones usage has evolved with time and the comments were outdated.
+This joins both ZONE_DMA and ZONE_DMA32 explanation and gives up to date
+examples on how they are used on different architectures.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+---
+ include/linux/mmzone.h | 45 ++++++++++++++++++++++++------------------
+ 1 file changed, 26 insertions(+), 19 deletions(-)
+
+--- a/include/linux/mmzone.h
++++ b/include/linux/mmzone.h
+@@ -358,33 +358,40 @@ struct per_cpu_nodestat {
+ #endif /* !__GENERATING_BOUNDS.H */
+
+ enum zone_type {
+-#ifdef CONFIG_ZONE_DMA
+ /*
+- * ZONE_DMA is used when there are devices that are not able
+- * to do DMA to all of addressable memory (ZONE_NORMAL). Then we
+- * carve out the portion of memory that is needed for these devices.
+- * The range is arch specific.
+- *
+- * Some examples
+- *
+- * Architecture Limit
+- * ---------------------------
+- * parisc, ia64, sparc <4G
+- * s390, powerpc <2G
+- * arm Various
+- * alpha Unlimited or 0-16MB.
++ * ZONE_DMA and ZONE_DMA32 are used when there are peripherals not able
++ * to DMA to all of the addressable memory (ZONE_NORMAL).
++ * On architectures where this area covers the whole 32 bit address
++ * space ZONE_DMA32 is used. ZONE_DMA is left for the ones with smaller
++ * DMA addressing constraints. This distinction is important as a 32bit
++ * DMA mask is assumed when ZONE_DMA32 is defined. Some 64-bit
++ * platforms may need both zones as they support peripherals with
++ * different DMA addressing limitations.
++ *
++ * Some examples:
++ *
++ * - i386 and x86_64 have a fixed 16M ZONE_DMA and ZONE_DMA32 for the
++ * rest of the lower 4G.
++ *
++ * - arm only uses ZONE_DMA, the size, up to 4G, may vary depending on
++ * the specific device.
++ *
++ * - arm64 has a fixed 1G ZONE_DMA and ZONE_DMA32 for the rest of the
++ * lower 4G.
++ *
++ * - powerpc only uses ZONE_DMA, the size, up to 2G, may vary
++ * depending on the specific device.
+ *
+- * i386, x86_64 and multiple other arches
+- * <16M.
++ * - s390 uses ZONE_DMA fixed to the lower 2G.
++ *
++ * - ia64 and riscv only use ZONE_DMA32.
++ *
++ * - parisc uses neither.
+ */
++#ifdef CONFIG_ZONE_DMA
+ ZONE_DMA,
+ #endif
+ #ifdef CONFIG_ZONE_DMA32
+- /*
+- * x86_64 needs two ZONE_DMAs because it supports devices that are
+- * only able to do DMA to the lower 16M but also 32 bit devices that
+- * can only do DMA areas below 4G.
+- */
+ ZONE_DMA32,
+ #endif
+ /*
diff --git a/target/linux/bcm27xx/patches-5.4/950-0450-resource-Add-a-resource_list_first_type-helper.patch b/target/linux/bcm27xx/patches-5.4/950-0450-resource-Add-a-resource_list_first_type-helper.patch
new file mode 100644
index 0000000000..c2c959a3c1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0450-resource-Add-a-resource_list_first_type-helper.patch
@@ -0,0 +1,36 @@
+From dacb1a46835914b8c3862db15726bcc0a68af8f5 Mon Sep 17 00:00:00 2001
+From: Rob Herring <robh@kernel.org>
+Date: Mon, 28 Oct 2019 11:32:32 -0500
+Subject: [PATCH] resource: Add a resource_list_first_type helper
+
+commit 494f8b10d832456a96be4ee7317425f6936cabc8 upstream.
+
+A common pattern is looping over a resource_list just to get a matching
+entry with a specific type. Add resource_list_first_type() helper which
+implements this.
+
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+---
+ include/linux/resource_ext.h | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/include/linux/resource_ext.h
++++ b/include/linux/resource_ext.h
+@@ -66,4 +66,16 @@ resource_list_destroy_entry(struct resou
+ #define resource_list_for_each_entry_safe(entry, tmp, list) \
+ list_for_each_entry_safe((entry), (tmp), (list), node)
+
++static inline struct resource_entry *
++resource_list_first_type(struct list_head *list, unsigned long type)
++{
++ struct resource_entry *entry;
++
++ resource_list_for_each_entry(entry, list) {
++ if (resource_type(entry->res) == type)
++ return entry;
++ }
++ return NULL;
++}
++
+ #endif /* _LINUX_RESOURCE_EXT_H */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0451-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0451-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch
new file mode 100644
index 0000000000..5de73d37f7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0451-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch
@@ -0,0 +1,195 @@
+From 78b03f0aef9f67c4db700ba5dc56e2c8f562d181 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Mon, 14 Oct 2019 20:31:03 +0200
+Subject: [PATCH] dma/direct: turn ARCH_ZONE_DMA_BITS into a variable
+
+commit 8b5369ea580964dbc982781bfb9fb93459fc5e8d upstream.
+
+Some architectures, notably ARM, are interested in tweaking this
+depending on their runtime DMA addressing limitations.
+
+Acked-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+---
+ arch/arm64/include/asm/page.h | 2 --
+ arch/arm64/mm/init.c | 9 +++++++--
+ arch/powerpc/include/asm/page.h | 9 ---------
+ arch/powerpc/mm/mem.c | 20 +++++++++++++++-----
+ arch/s390/include/asm/page.h | 2 --
+ arch/s390/mm/init.c | 1 +
+ include/linux/dma-direct.h | 2 ++
+ kernel/dma/direct.c | 13 ++++++-------
+ 8 files changed, 31 insertions(+), 27 deletions(-)
+
+--- a/arch/arm64/include/asm/page.h
++++ b/arch/arm64/include/asm/page.h
+@@ -38,6 +38,4 @@ extern int pfn_valid(unsigned long);
+
+ #include <asm-generic/getorder.h>
+
+-#define ARCH_ZONE_DMA_BITS 30
+-
+ #endif
+--- a/arch/arm64/mm/init.c
++++ b/arch/arm64/mm/init.c
+@@ -20,6 +20,7 @@
+ #include <linux/sort.h>
+ #include <linux/of.h>
+ #include <linux/of_fdt.h>
++#include <linux/dma-direct.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/dma-contiguous.h>
+ #include <linux/efi.h>
+@@ -41,6 +42,8 @@
+ #include <asm/tlb.h>
+ #include <asm/alternative.h>
+
++#define ARM64_ZONE_DMA_BITS 30
++
+ /*
+ * We need to be able to catch inadvertent references to memstart_addr
+ * that occur (potentially in generic code) before arm64_memblock_init()
+@@ -440,8 +443,10 @@ void __init arm64_memblock_init(void)
+
+ early_init_fdt_scan_reserved_mem();
+
+- if (IS_ENABLED(CONFIG_ZONE_DMA))
+- arm64_dma_phys_limit = max_zone_phys(ARCH_ZONE_DMA_BITS);
++ if (IS_ENABLED(CONFIG_ZONE_DMA)) {
++ zone_dma_bits = ARM64_ZONE_DMA_BITS;
++ arm64_dma_phys_limit = max_zone_phys(ARM64_ZONE_DMA_BITS);
++ }
+
+ if (IS_ENABLED(CONFIG_ZONE_DMA32))
+ arm64_dma32_phys_limit = max_zone_phys(32);
+--- a/arch/powerpc/include/asm/page.h
++++ b/arch/powerpc/include/asm/page.h
+@@ -334,13 +334,4 @@ struct vm_area_struct;
+ #endif /* __ASSEMBLY__ */
+ #include <asm/slice.h>
+
+-/*
+- * Allow 30-bit DMA for very limited Broadcom wifi chips on many powerbooks.
+- */
+-#ifdef CONFIG_PPC32
+-#define ARCH_ZONE_DMA_BITS 30
+-#else
+-#define ARCH_ZONE_DMA_BITS 31
+-#endif
+-
+ #endif /* _ASM_POWERPC_PAGE_H */
+--- a/arch/powerpc/mm/mem.c
++++ b/arch/powerpc/mm/mem.c
+@@ -31,6 +31,7 @@
+ #include <linux/slab.h>
+ #include <linux/vmalloc.h>
+ #include <linux/memremap.h>
++#include <linux/dma-direct.h>
+
+ #include <asm/pgalloc.h>
+ #include <asm/prom.h>
+@@ -223,10 +224,10 @@ static int __init mark_nonram_nosave(voi
+ * everything else. GFP_DMA32 page allocations automatically fall back to
+ * ZONE_DMA.
+ *
+- * By using 31-bit unconditionally, we can exploit ARCH_ZONE_DMA_BITS to
+- * inform the generic DMA mapping code. 32-bit only devices (if not handled
+- * by an IOMMU anyway) will take a first dip into ZONE_NORMAL and get
+- * otherwise served by ZONE_DMA.
++ * By using 31-bit unconditionally, we can exploit zone_dma_bits to inform the
++ * generic DMA mapping code. 32-bit only devices (if not handled by an IOMMU
++ * anyway) will take a first dip into ZONE_NORMAL and get otherwise served by
++ * ZONE_DMA.
+ */
+ static unsigned long max_zone_pfns[MAX_NR_ZONES];
+
+@@ -259,9 +260,18 @@ void __init paging_init(void)
+ printk(KERN_DEBUG "Memory hole size: %ldMB\n",
+ (long int)((top_of_ram - total_ram) >> 20));
+
++ /*
++ * Allow 30-bit DMA for very limited Broadcom wifi chips on many
++ * powerbooks.
++ */
++ if (IS_ENABLED(CONFIG_PPC32))
++ zone_dma_bits = 30;
++ else
++ zone_dma_bits = 31;
++
+ #ifdef CONFIG_ZONE_DMA
+ max_zone_pfns[ZONE_DMA] = min(max_low_pfn,
+- 1UL << (ARCH_ZONE_DMA_BITS - PAGE_SHIFT));
++ 1UL << (zone_dma_bits - PAGE_SHIFT));
+ #endif
+ max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+ #ifdef CONFIG_HIGHMEM
+--- a/arch/s390/include/asm/page.h
++++ b/arch/s390/include/asm/page.h
+@@ -179,8 +179,6 @@ static inline int devmem_is_allowed(unsi
+ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+-#define ARCH_ZONE_DMA_BITS 31
+-
+ #include <asm-generic/memory_model.h>
+ #include <asm-generic/getorder.h>
+
+--- a/arch/s390/mm/init.c
++++ b/arch/s390/mm/init.c
+@@ -118,6 +118,7 @@ void __init paging_init(void)
+
+ sparse_memory_present_with_active_regions(MAX_NUMNODES);
+ sparse_init();
++ zone_dma_bits = 31;
+ memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+ max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS);
+ max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+--- a/include/linux/dma-direct.h
++++ b/include/linux/dma-direct.h
+@@ -8,6 +8,8 @@
+
+ static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+
++extern unsigned int zone_dma_bits;
++
+ #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
+ #include <asm/dma-direct.h>
+ #else
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -16,12 +16,11 @@
+ #include <linux/swiotlb.h>
+
+ /*
+- * Most architectures use ZONE_DMA for the first 16 Megabytes, but
+- * some use it for entirely different regions:
++ * Most architectures use ZONE_DMA for the first 16 Megabytes, but some use it
++ * it for entirely different regions. In that case the arch code needs to
++ * override the variable below for dma-direct to work properly.
+ */
+-#ifndef ARCH_ZONE_DMA_BITS
+-#define ARCH_ZONE_DMA_BITS 24
+-#endif
++unsigned int zone_dma_bits __ro_after_init = 24;
+
+ static void report_addr(struct device *dev, dma_addr_t dma_addr, size_t size)
+ {
+@@ -69,7 +68,7 @@ static gfp_t __dma_direct_optimal_gfp_ma
+ * Note that GFP_DMA32 and GFP_DMA are no ops without the corresponding
+ * zones.
+ */
+- if (*phys_mask <= DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
++ if (*phys_mask <= DMA_BIT_MASK(zone_dma_bits))
+ return GFP_DMA;
+ if (*phys_mask <= DMA_BIT_MASK(32))
+ return GFP_DMA32;
+@@ -395,7 +394,7 @@ int dma_direct_supported(struct device *
+ u64 min_mask;
+
+ if (IS_ENABLED(CONFIG_ZONE_DMA))
+- min_mask = DMA_BIT_MASK(ARCH_ZONE_DMA_BITS);
++ min_mask = DMA_BIT_MASK(zone_dma_bits);
+ else
+ min_mask = DMA_BIT_MASK(30);
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0452-x86-PCI-sta2x11-use-default-DMA-address-translation.patch b/target/linux/bcm27xx/patches-5.4/950-0452-x86-PCI-sta2x11-use-default-DMA-address-translation.patch
new file mode 100644
index 0000000000..51fd4be35e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0452-x86-PCI-sta2x11-use-default-DMA-address-translation.patch
@@ -0,0 +1,259 @@
+From 97a48106d1698038720495fdd49c491b283bf110 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Thu, 7 Nov 2019 16:06:45 +0100
+Subject: [PATCH] x86/PCI: sta2x11: use default DMA address translation
+
+commit e380a0394c36a3a878c858418d5dd7f5f195b6fc upstream.
+
+The devices found behind this PCIe chip have unusual DMA mapping
+constraints as there is an AMBA interconnect placed in between them and
+the different PCI endpoints. The offset between physical memory
+addresses and AMBA's view is provided by reading a PCI config register,
+which is saved and used whenever DMA mapping is needed.
+
+It turns out that this DMA setup can be represented by properly setting
+'dma_pfn_offset', 'dma_bus_mask' and 'dma_mask' during the PCI device
+enable fixup. And ultimately allows us to get rid of this device's
+custom DMA functions.
+
+Aside from the code deletion and DMA setup, sta2x11_pdev_to_mapping() is
+moved to avoid warnings whenever CONFIG_PM is not enabled.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ arch/x86/Kconfig | 1 -
+ arch/x86/include/asm/device.h | 3 -
+ arch/x86/include/asm/dma-direct.h | 9 --
+ arch/x86/pci/sta2x11-fixup.c | 135 ++++++------------------------
+ 4 files changed, 26 insertions(+), 122 deletions(-)
+ delete mode 100644 arch/x86/include/asm/dma-direct.h
+
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -708,7 +708,6 @@ config X86_SUPPORTS_MEMORY_FAILURE
+ config STA2X11
+ bool "STA2X11 Companion Chip Support"
+ depends on X86_32_NON_STANDARD && PCI
+- select ARCH_HAS_PHYS_TO_DMA
+ select SWIOTLB
+ select MFD_STA2X11
+ select GPIOLIB
+--- a/arch/x86/include/asm/device.h
++++ b/arch/x86/include/asm/device.h
+@@ -6,9 +6,6 @@ struct dev_archdata {
+ #if defined(CONFIG_INTEL_IOMMU) || defined(CONFIG_AMD_IOMMU)
+ void *iommu; /* hook for IOMMU specific extension */
+ #endif
+-#ifdef CONFIG_STA2X11
+- bool is_sta2x11;
+-#endif
+ };
+
+ #if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
+--- a/arch/x86/include/asm/dma-direct.h
++++ /dev/null
+@@ -1,9 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0 */
+-#ifndef ASM_X86_DMA_DIRECT_H
+-#define ASM_X86_DMA_DIRECT_H 1
+-
+-bool dma_capable(struct device *dev, dma_addr_t addr, size_t size);
+-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
+-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr);
+-
+-#endif /* ASM_X86_DMA_DIRECT_H */
+--- a/arch/x86/pci/sta2x11-fixup.c
++++ b/arch/x86/pci/sta2x11-fixup.c
+@@ -30,7 +30,6 @@ struct sta2x11_ahb_regs { /* saved durin
+ };
+
+ struct sta2x11_mapping {
+- u32 amba_base;
+ int is_suspended;
+ struct sta2x11_ahb_regs regs[STA2X11_NR_FUNCS];
+ };
+@@ -92,18 +91,6 @@ static int sta2x11_pdev_to_ep(struct pci
+ return pdev->bus->number - instance->bus0;
+ }
+
+-static struct sta2x11_mapping *sta2x11_pdev_to_mapping(struct pci_dev *pdev)
+-{
+- struct sta2x11_instance *instance;
+- int ep;
+-
+- instance = sta2x11_pdev_to_instance(pdev);
+- if (!instance)
+- return NULL;
+- ep = sta2x11_pdev_to_ep(pdev);
+- return instance->map + ep;
+-}
+-
+ /* This is exported, as some devices need to access the MFD registers */
+ struct sta2x11_instance *sta2x11_get_instance(struct pci_dev *pdev)
+ {
+@@ -111,39 +98,6 @@ struct sta2x11_instance *sta2x11_get_ins
+ }
+ EXPORT_SYMBOL(sta2x11_get_instance);
+
+-
+-/**
+- * p2a - Translate physical address to STA2x11 AMBA address,
+- * used for DMA transfers to STA2x11
+- * @p: Physical address
+- * @pdev: PCI device (must be hosted within the connext)
+- */
+-static dma_addr_t p2a(dma_addr_t p, struct pci_dev *pdev)
+-{
+- struct sta2x11_mapping *map;
+- dma_addr_t a;
+-
+- map = sta2x11_pdev_to_mapping(pdev);
+- a = p + map->amba_base;
+- return a;
+-}
+-
+-/**
+- * a2p - Translate STA2x11 AMBA address to physical address
+- * used for DMA transfers from STA2x11
+- * @a: STA2x11 AMBA address
+- * @pdev: PCI device (must be hosted within the connext)
+- */
+-static dma_addr_t a2p(dma_addr_t a, struct pci_dev *pdev)
+-{
+- struct sta2x11_mapping *map;
+- dma_addr_t p;
+-
+- map = sta2x11_pdev_to_mapping(pdev);
+- p = a - map->amba_base;
+- return p;
+-}
+-
+ /* At setup time, we use our own ops if the device is a ConneXt one */
+ static void sta2x11_setup_pdev(struct pci_dev *pdev)
+ {
+@@ -151,9 +105,6 @@ static void sta2x11_setup_pdev(struct pc
+
+ if (!instance) /* either a sta2x11 bridge or another ST device */
+ return;
+- pci_set_consistent_dma_mask(pdev, STA2X11_AMBA_SIZE - 1);
+- pci_set_dma_mask(pdev, STA2X11_AMBA_SIZE - 1);
+- pdev->dev.archdata.is_sta2x11 = true;
+
+ /* We must enable all devices as master, for audio DMA to work */
+ pci_set_master(pdev);
+@@ -161,61 +112,6 @@ static void sta2x11_setup_pdev(struct pc
+ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_setup_pdev);
+
+ /*
+- * The following three functions are exported (used in swiotlb: FIXME)
+- */
+-/**
+- * dma_capable - Check if device can manage DMA transfers (FIXME: kill it)
+- * @dev: device for a PCI device
+- * @addr: DMA address
+- * @size: DMA size
+- */
+-bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+-{
+- struct sta2x11_mapping *map;
+-
+- if (!dev->archdata.is_sta2x11) {
+- if (!dev->dma_mask)
+- return false;
+- return addr + size - 1 <= *dev->dma_mask;
+- }
+-
+- map = sta2x11_pdev_to_mapping(to_pci_dev(dev));
+-
+- if (!map || (addr < map->amba_base))
+- return false;
+- if (addr + size >= map->amba_base + STA2X11_AMBA_SIZE) {
+- return false;
+- }
+-
+- return true;
+-}
+-
+-/**
+- * __phys_to_dma - Return the DMA AMBA address used for this STA2x11 device
+- * @dev: device for a PCI device
+- * @paddr: Physical address
+- */
+-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+-{
+- if (!dev->archdata.is_sta2x11)
+- return paddr;
+- return p2a(paddr, to_pci_dev(dev));
+-}
+-
+-/**
+- * dma_to_phys - Return the physical address used for this STA2x11 DMA address
+- * @dev: device for a PCI device
+- * @daddr: STA2x11 AMBA DMA address
+- */
+-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
+-{
+- if (!dev->archdata.is_sta2x11)
+- return daddr;
+- return a2p(daddr, to_pci_dev(dev));
+-}
+-
+-
+-/*
+ * At boot we must set up the mappings for the pcie-to-amba bridge.
+ * It involves device access, and the same happens at suspend/resume time
+ */
+@@ -234,12 +130,22 @@ phys_addr_t __dma_to_phys(struct device
+ /* At probe time, enable mapping for each endpoint, using the pdev */
+ static void sta2x11_map_ep(struct pci_dev *pdev)
+ {
+- struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
++ struct sta2x11_instance *instance = sta2x11_pdev_to_instance(pdev);
++ struct device *dev = &pdev->dev;
++ u32 amba_base, max_amba_addr;
+ int i;
+
+- if (!map)
++ if (!instance)
+ return;
+- pci_read_config_dword(pdev, AHB_BASE(0), &map->amba_base);
++
++ pci_read_config_dword(pdev, AHB_BASE(0), &amba_base);
++ max_amba_addr = amba_base + STA2X11_AMBA_SIZE - 1;
++
++ dev->dma_pfn_offset = PFN_DOWN(-amba_base);
++
++ dev->bus_dma_mask = max_amba_addr;
++ pci_set_consistent_dma_mask(pdev, max_amba_addr);
++ pci_set_dma_mask(pdev, max_amba_addr);
+
+ /* Configure AHB mapping */
+ pci_write_config_dword(pdev, AHB_PEXLBASE(0), 0);
+@@ -253,13 +159,24 @@ static void sta2x11_map_ep(struct pci_de
+
+ dev_info(&pdev->dev,
+ "sta2x11: Map EP %i: AMBA address %#8x-%#8x\n",
+- sta2x11_pdev_to_ep(pdev), map->amba_base,
+- map->amba_base + STA2X11_AMBA_SIZE - 1);
++ sta2x11_pdev_to_ep(pdev), amba_base, max_amba_addr);
+ }
+ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_map_ep);
+
+ #ifdef CONFIG_PM /* Some register values must be saved and restored */
+
++static struct sta2x11_mapping *sta2x11_pdev_to_mapping(struct pci_dev *pdev)
++{
++ struct sta2x11_instance *instance;
++ int ep;
++
++ instance = sta2x11_pdev_to_instance(pdev);
++ if (!instance)
++ return NULL;
++ ep = sta2x11_pdev_to_ep(pdev);
++ return instance->map + ep;
++}
++
+ static void suspend_mapping(struct pci_dev *pdev)
+ {
+ struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0453-PCI-of-Add-inbound-resource-parsing-to-helpers.patch b/target/linux/bcm27xx/patches-5.4/950-0453-PCI-of-Add-inbound-resource-parsing-to-helpers.patch
new file mode 100644
index 0000000000..0d74bc57ad
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0453-PCI-of-Add-inbound-resource-parsing-to-helpers.patch
@@ -0,0 +1,427 @@
+From 125a18144253e3a3f4bcad24484ee9b590dc47c6 Mon Sep 17 00:00:00 2001
+From: Rob Herring <robh@kernel.org>
+Date: Wed, 30 Oct 2019 17:30:57 -0500
+Subject: [PATCH] PCI: of: Add inbound resource parsing to helpers
+
+Extend devm_of_pci_get_host_bridge_resources() and
+pci_parse_request_of_pci_ranges() helpers to also parse the inbound
+addresses from DT 'dma-ranges' and populate a resource list with the
+translated addresses. This will help ensure 'dma-ranges' is always
+parsed in a consistent way.
+
+Tested-by: Srinath Mannam <srinath.mannam@broadcom.com>
+Tested-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> # for AArdvark
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Srinath Mannam <srinath.mannam@broadcom.com>
+Reviewed-by: Andrew Murray <andrew.murray@arm.com>
+Acked-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: Jingoo Han <jingoohan1@gmail.com>
+Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Cc: Toan Le <toan@os.amperecomputing.com>
+Cc: Ley Foon Tan <lftan@altera.com>
+Cc: Tom Joseph <tjoseph@cadence.com>
+Cc: Ray Jui <rjui@broadcom.com>
+Cc: Scott Branden <sbranden@broadcom.com>
+Cc: bcm-kernel-feedback-list@broadcom.com
+Cc: Ryder Lee <ryder.lee@mediatek.com>
+Cc: Karthikeyan Mitran <m.karthikeyan@mobiveil.co.in>
+Cc: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
+Cc: Simon Horman <horms@verge.net.au>
+Cc: Shawn Lin <shawn.lin@rock-chips.com>
+Cc: Heiko Stuebner <heiko@sntech.de>
+Cc: Michal Simek <michal.simek@xilinx.com>
+Cc: rfi@lists.rocketboards.org
+Cc: linux-mediatek@lists.infradead.org
+Cc: linux-renesas-soc@vger.kernel.org
+Cc: linux-rockchip@lists.infradead.org
+(cherry picked from commit 331f63457165a30c708280de2c77f1742c6351dc)
+---
+ .../pci/controller/dwc/pcie-designware-host.c | 8 +--
+ drivers/pci/controller/pci-aardvark.c | 3 +-
+ drivers/pci/controller/pci-ftpci100.c | 4 +-
+ drivers/pci/controller/pci-host-common.c | 2 +-
+ drivers/pci/controller/pci-v3-semi.c | 8 +--
+ drivers/pci/controller/pci-versatile.c | 3 +-
+ drivers/pci/controller/pci-xgene.c | 4 +-
+ drivers/pci/controller/pcie-altera.c | 5 +-
+ drivers/pci/controller/pcie-cadence-host.c | 2 +-
+ drivers/pci/controller/pcie-iproc-platform.c | 4 +-
+ drivers/pci/controller/pcie-mediatek.c | 4 +-
+ drivers/pci/controller/pcie-mobiveil.c | 4 +-
+ drivers/pci/controller/pcie-rcar.c | 3 +-
+ drivers/pci/controller/pcie-rockchip-host.c | 4 +-
+ drivers/pci/controller/pcie-xilinx-nwl.c | 4 +-
+ drivers/pci/controller/pcie-xilinx.c | 4 +-
+ drivers/pci/of.c | 61 ++++++++++++++++---
+ drivers/pci/pci.h | 8 ++-
+ include/linux/pci.h | 9 ++-
+ 19 files changed, 96 insertions(+), 48 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -343,12 +343,8 @@ int dw_pcie_host_init(struct pcie_port *
+ if (!bridge)
+ return -ENOMEM;
+
+- ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
+- &bridge->windows, &pp->io_base);
+- if (ret)
+- return ret;
+-
+- ret = devm_request_pci_bus_resources(dev, &bridge->windows);
++ ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, NULL);
+ if (ret)
+ return ret;
+
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -1023,7 +1023,8 @@ static int advk_pcie_probe(struct platfo
+ return ret;
+ }
+
+- ret = advk_pcie_parse_request_of_pci_ranges(pcie);
++ ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, &bus);
+ if (ret) {
+ dev_err(dev, "Failed to parse resources\n");
+ return ret;
+--- a/drivers/pci/controller/pci-ftpci100.c
++++ b/drivers/pci/controller/pci-ftpci100.c
+@@ -480,8 +480,8 @@ static int faraday_pci_probe(struct plat
+ if (IS_ERR(p->base))
+ return PTR_ERR(p->base);
+
+- ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
+- &res, &io_base);
++ ret = pci_parse_request_of_pci_ranges(dev, &host->windows,
++ &host->dma_ranges, NULL);
+ if (ret)
+ return ret;
+
+--- a/drivers/pci/controller/pci-host-common.c
++++ b/drivers/pci/controller/pci-host-common.c
+@@ -27,7 +27,7 @@ static struct pci_config_window *gen_pci
+ struct pci_config_window *cfg;
+
+ /* Parse our PCI ranges and request their resources */
+- err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
++ err = pci_parse_request_of_pci_ranges(dev, resources, NULL, &bus_range);
+ if (err)
+ return ERR_PTR(err);
+
+--- a/drivers/pci/controller/pci-v3-semi.c
++++ b/drivers/pci/controller/pci-v3-semi.c
+@@ -793,12 +793,8 @@ static int v3_pci_probe(struct platform_
+ if (IS_ERR(v3->config_base))
+ return PTR_ERR(v3->config_base);
+
+- ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
+- &io_base);
+- if (ret)
+- return ret;
+-
+- ret = devm_request_pci_bus_resources(dev, &res);
++ ret = pci_parse_request_of_pci_ranges(dev, &host->windows,
++ &host->dma_ranges, NULL);
+ if (ret)
+ return ret;
+
+--- a/drivers/pci/controller/pci-versatile.c
++++ b/drivers/pci/controller/pci-versatile.c
+@@ -141,7 +141,8 @@ static int versatile_pci_probe(struct pl
+ if (IS_ERR(versatile_cfg_base[1]))
+ return PTR_ERR(versatile_cfg_base[1]);
+
+- ret = versatile_pci_parse_request_of_pci_ranges(dev, &pci_res);
++ ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ NULL, NULL);
+ if (ret)
+ return ret;
+
+--- a/drivers/pci/controller/pci-xgene.c
++++ b/drivers/pci/controller/pci-xgene.c
+@@ -634,8 +634,8 @@ static int xgene_pcie_probe(struct platf
+ if (ret)
+ return ret;
+
+- ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
+- &iobase);
++ ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, NULL);
+ if (ret)
+ return ret;
+
+--- a/drivers/pci/controller/pcie-altera.c
++++ b/drivers/pci/controller/pcie-altera.c
+@@ -833,9 +833,8 @@ static int altera_pcie_probe(struct plat
+ return ret;
+ }
+
+- INIT_LIST_HEAD(&pcie->resources);
+-
+- ret = altera_pcie_parse_request_of_pci_ranges(pcie);
++ ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, NULL);
+ if (ret) {
+ dev_err(dev, "Failed add resources\n");
+ return ret;
+--- a/drivers/pci/controller/pcie-cadence-host.c
++++ b/drivers/pci/controller/pcie-cadence-host.c
+@@ -211,7 +211,7 @@ static int cdns_pcie_host_init(struct de
+ int err;
+
+ /* Parse our PCI ranges and request their resources */
+- err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
++ err = pci_parse_request_of_pci_ranges(dev, resources, NULL, &bus_range);
+ if (err)
+ return err;
+
+--- a/drivers/pci/controller/pcie-iproc-platform.c
++++ b/drivers/pci/controller/pcie-iproc-platform.c
+@@ -97,8 +97,8 @@ static int iproc_pcie_pltfm_probe(struct
+ if (IS_ERR(pcie->phy))
+ return PTR_ERR(pcie->phy);
+
+- ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &resources,
+- &iobase);
++ ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, NULL);
+ if (ret) {
+ dev_err(dev, "unable to get PCI host bridge resources\n");
+ return ret;
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -1027,8 +1027,8 @@ static int mtk_pcie_setup(struct mtk_pci
+ resource_size_t io_base;
+ int err;
+
+- err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
+- windows, &io_base);
++ err = pci_parse_request_of_pci_ranges(dev, windows,
++ &host->dma_ranges, &bus);
+ if (err)
+ return err;
+
+--- a/drivers/pci/controller/pcie-mobiveil.c
++++ b/drivers/pci/controller/pcie-mobiveil.c
+@@ -883,8 +883,8 @@ static int mobiveil_pcie_probe(struct pl
+ INIT_LIST_HEAD(&pcie->resources);
+
+ /* parse the host bridge base addresses from the device tree file */
+- ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
+- &pcie->resources, &iobase);
++ ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, NULL);
+ if (ret) {
+ dev_err(dev, "Getting bridge resources failed\n");
+ return ret;
+--- a/drivers/pci/controller/pcie-rcar.c
++++ b/drivers/pci/controller/pcie-rcar.c
+@@ -1143,7 +1143,8 @@ static int rcar_pcie_probe(struct platfo
+ pcie->dev = dev;
+ platform_set_drvdata(pdev, pcie);
+
+- err = pci_parse_request_of_pci_ranges(dev, &pcie->resources, NULL);
++ err = pci_parse_request_of_pci_ranges(dev, &pcie->resources,
++ &bridge->dma_ranges, NULL);
+ if (err)
+ goto err_free_bridge;
+
+--- a/drivers/pci/controller/pcie-rockchip-host.c
++++ b/drivers/pci/controller/pcie-rockchip-host.c
+@@ -995,8 +995,8 @@ static int rockchip_pcie_probe(struct pl
+ if (err < 0)
+ goto err_deinit_port;
+
+- err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
+- &res, &io_base);
++ err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, &bus_res);
+ if (err)
+ goto err_remove_irq_domain;
+
+--- a/drivers/pci/controller/pcie-xilinx-nwl.c
++++ b/drivers/pci/controller/pcie-xilinx-nwl.c
+@@ -845,8 +845,8 @@ static int nwl_pcie_probe(struct platfor
+ return err;
+ }
+
+- err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
+- &iobase);
++ err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, NULL);
+ if (err) {
+ dev_err(dev, "Getting bridge resources failed\n");
+ return err;
+--- a/drivers/pci/controller/pcie-xilinx.c
++++ b/drivers/pci/controller/pcie-xilinx.c
+@@ -647,8 +647,8 @@ static int xilinx_pcie_probe(struct plat
+ return err;
+ }
+
+- err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
+- &iobase);
++ err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
++ &bridge->dma_ranges, NULL);
+ if (err) {
+ dev_err(dev, "Getting bridge resources failed\n");
+ return err;
+--- a/drivers/pci/of.c
++++ b/drivers/pci/of.c
+@@ -257,14 +257,16 @@ EXPORT_SYMBOL_GPL(of_pci_check_probe_onl
+ */
+ int devm_of_pci_get_host_bridge_resources(struct device *dev,
+ unsigned char busno, unsigned char bus_max,
+- struct list_head *resources, resource_size_t *io_base)
++ struct list_head *resources,
++ struct list_head *ib_resources,
++ resource_size_t *io_base)
+ {
+ struct device_node *dev_node = dev->of_node;
+ struct resource *res, tmp_res;
+ struct resource *bus_range;
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+- char range_type[4];
++ const char *range_type;
+ int err;
+
+ if (io_base)
+@@ -298,12 +300,12 @@ int devm_of_pci_get_host_bridge_resource
+ for_each_of_pci_range(&parser, &range) {
+ /* Read next ranges element */
+ if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+- snprintf(range_type, 4, " IO");
++ range_type = "IO";
+ else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+- snprintf(range_type, 4, "MEM");
++ range_type = "MEM";
+ else
+- snprintf(range_type, 4, "err");
+- dev_info(dev, " %s %#010llx..%#010llx -> %#010llx\n",
++ range_type = "err";
++ dev_info(dev, " %6s %#012llx..%#012llx -> %#012llx\n",
+ range_type, range.cpu_addr,
+ range.cpu_addr + range.size - 1, range.pci_addr);
+
+@@ -340,6 +342,48 @@ int devm_of_pci_get_host_bridge_resource
+ pci_add_resource_offset(resources, res, res->start - range.pci_addr);
+ }
+
++ /* Check for dma-ranges property */
++ if (!ib_resources)
++ return 0;
++ err = of_pci_dma_range_parser_init(&parser, dev_node);
++ if (err)
++ return 0;
++
++ dev_dbg(dev, "Parsing dma-ranges property...\n");
++ for_each_of_pci_range(&parser, &range) {
++ struct resource_entry *entry;
++ /*
++ * If we failed translation or got a zero-sized region
++ * then skip this range
++ */
++ if (((range.flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM) ||
++ range.cpu_addr == OF_BAD_ADDR || range.size == 0)
++ continue;
++
++ dev_info(dev, " %6s %#012llx..%#012llx -> %#012llx\n",
++ "IB MEM", range.cpu_addr,
++ range.cpu_addr + range.size - 1, range.pci_addr);
++
++
++ err = of_pci_range_to_resource(&range, dev_node, &tmp_res);
++ if (err)
++ continue;
++
++ res = devm_kmemdup(dev, &tmp_res, sizeof(tmp_res), GFP_KERNEL);
++ if (!res) {
++ err = -ENOMEM;
++ goto failed;
++ }
++
++ /* Keep the resource list sorted */
++ resource_list_for_each_entry(entry, ib_resources)
++ if (entry->res->start > res->start)
++ break;
++
++ pci_add_resource_offset(&entry->node, res,
++ res->start - range.pci_addr);
++ }
++
+ return 0;
+
+ failed:
+@@ -482,6 +526,7 @@ EXPORT_SYMBOL_GPL(of_irq_parse_and_map_p
+
+ int pci_parse_request_of_pci_ranges(struct device *dev,
+ struct list_head *resources,
++ struct list_head *ib_resources,
+ struct resource **bus_range)
+ {
+ int err, res_valid = 0;
+@@ -489,8 +534,10 @@ int pci_parse_request_of_pci_ranges(stru
+ struct resource_entry *win, *tmp;
+
+ INIT_LIST_HEAD(resources);
++ if (ib_resources)
++ INIT_LIST_HEAD(ib_resources);
+ err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, resources,
+- &iobase);
++ ib_resources, &iobase);
+ if (err)
+ return err;
+
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -636,11 +636,15 @@ static inline void pci_release_bus_of_no
+ #if defined(CONFIG_OF_ADDRESS)
+ int devm_of_pci_get_host_bridge_resources(struct device *dev,
+ unsigned char busno, unsigned char bus_max,
+- struct list_head *resources, resource_size_t *io_base);
++ struct list_head *resources,
++ struct list_head *ib_resources,
++ resource_size_t *io_base);
+ #else
+ static inline int devm_of_pci_get_host_bridge_resources(struct device *dev,
+ unsigned char busno, unsigned char bus_max,
+- struct list_head *resources, resource_size_t *io_base)
++ struct list_head *resources,
++ struct list_head *ib_resources,
++ resource_size_t *io_base)
+ {
+ return -EINVAL;
+ }
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -2278,6 +2278,7 @@ struct irq_domain;
+ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus);
+ int pci_parse_request_of_pci_ranges(struct device *dev,
+ struct list_head *resources,
++ struct list_head *ib_resources,
+ struct resource **bus_range);
+
+ /* Arch may override this (weak) */
+@@ -2286,9 +2287,11 @@ struct device_node *pcibios_get_phb_of_n
+ #else /* CONFIG_OF */
+ static inline struct irq_domain *
+ pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
+-static inline int pci_parse_request_of_pci_ranges(struct device *dev,
+- struct list_head *resources,
+- struct resource **bus_range)
++static inline int
++pci_parse_request_of_pci_ranges(struct device *dev,
++ struct list_head *resources,
++ struct list_head *ib_resources,
++ struct resource **bus_range)
+ {
+ return -EINVAL;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0454-dma-direct-unify-the-dma_capable-definitions.patch b/target/linux/bcm27xx/patches-5.4/950-0454-dma-direct-unify-the-dma_capable-definitions.patch
new file mode 100644
index 0000000000..d115f0eb80
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0454-dma-direct-unify-the-dma_capable-definitions.patch
@@ -0,0 +1,103 @@
+From 203e0c39b262fc1da6f976495c32ec38ea93a137 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Tue, 12 Nov 2019 17:06:04 +0100
+Subject: [PATCH] dma-direct: unify the dma_capable definitions
+
+commit 130c1ccbf55330b55e82612a6e54eebb82c9d746 upstream.
+
+Currently each architectures that wants to override dma_to_phys and
+phys_to_dma also has to provide dma_capable. But there isn't really
+any good reason for that. powerpc and mips just have copies of the
+generic one minus the latests fix, and the arm one was the inspiration
+for said fix, but misses the bus_dma_mask handling.
+Make all architectures use the generic version instead.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+---
+ arch/arm/include/asm/dma-direct.h | 19 -------------------
+ arch/mips/include/asm/dma-direct.h | 8 --------
+ arch/powerpc/include/asm/dma-direct.h | 9 ---------
+ include/linux/dma-direct.h | 2 +-
+ 4 files changed, 1 insertion(+), 37 deletions(-)
+
+--- a/arch/arm/include/asm/dma-direct.h
++++ b/arch/arm/include/asm/dma-direct.h
+@@ -14,23 +14,4 @@ static inline phys_addr_t __dma_to_phys(
+ return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
+ }
+
+-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+-{
+- u64 limit, mask;
+-
+- if (!dev->dma_mask)
+- return 0;
+-
+- mask = *dev->dma_mask;
+-
+- limit = (mask + 1) & ~mask;
+- if (limit && size > limit)
+- return 0;
+-
+- if ((addr | (addr + size - 1)) & ~mask)
+- return 0;
+-
+- return 1;
+-}
+-
+ #endif /* ASM_ARM_DMA_DIRECT_H */
+--- a/arch/mips/include/asm/dma-direct.h
++++ b/arch/mips/include/asm/dma-direct.h
+@@ -2,14 +2,6 @@
+ #ifndef _MIPS_DMA_DIRECT_H
+ #define _MIPS_DMA_DIRECT_H 1
+
+-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+-{
+- if (!dev->dma_mask)
+- return false;
+-
+- return addr + size - 1 <= *dev->dma_mask;
+-}
+-
+ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
+ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr);
+
+--- a/arch/powerpc/include/asm/dma-direct.h
++++ b/arch/powerpc/include/asm/dma-direct.h
+@@ -2,15 +2,6 @@
+ #ifndef ASM_POWERPC_DMA_DIRECT_H
+ #define ASM_POWERPC_DMA_DIRECT_H 1
+
+-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+-{
+- if (!dev->dma_mask)
+- return false;
+-
+- return addr + size - 1 <=
+- min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
+-}
+-
+ static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+ {
+ if (!dev)
+--- a/include/linux/dma-direct.h
++++ b/include/linux/dma-direct.h
+@@ -26,6 +26,7 @@ static inline phys_addr_t __dma_to_phys(
+
+ return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
+ }
++#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
+
+ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+ {
+@@ -40,7 +41,6 @@ static inline bool dma_capable(struct de
+
+ return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
+ }
+-#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
+
+ #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
+ bool force_dma_unencrypted(struct device *dev);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0455-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch b/target/linux/bcm27xx/patches-5.4/950-0455-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch
new file mode 100644
index 0000000000..a98f1d3852
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0455-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch
@@ -0,0 +1,69 @@
+From a3794022e928547de664abd03b61280163c7f13a Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Tue, 12 Nov 2019 17:07:43 +0100
+Subject: [PATCH] dma-direct: avoid a forward declaration for
+ phys_to_dma
+
+Move dma_capable down a bit so that we don't need a forward declaration
+for phys_to_dma.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+(cherry picked from commit c7345159f7db6fb69ec1c3b3f8f28cd05c731be2)
+---
+ include/linux/dma-direct.h | 30 ++++++++++++++----------------
+ 1 file changed, 14 insertions(+), 16 deletions(-)
+
+--- a/include/linux/dma-direct.h
++++ b/include/linux/dma-direct.h
+@@ -6,8 +6,6 @@
+ #include <linux/memblock.h> /* for min_low_pfn */
+ #include <linux/mem_encrypt.h>
+
+-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+-
+ extern unsigned int zone_dma_bits;
+
+ #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
+@@ -28,20 +26,6 @@ static inline phys_addr_t __dma_to_phys(
+ }
+ #endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
+
+-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+-{
+- dma_addr_t end = addr + size - 1;
+-
+- if (!dev->dma_mask)
+- return false;
+-
+- if (!IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
+- min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn)))
+- return false;
+-
+- return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
+-}
+-
+ #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
+ bool force_dma_unencrypted(struct device *dev);
+ #else
+@@ -67,6 +51,20 @@ static inline phys_addr_t dma_to_phys(st
+ return __sme_clr(__dma_to_phys(dev, daddr));
+ }
+
++static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
++{
++ dma_addr_t end = addr + size - 1;
++
++ if (!dev->dma_mask)
++ return false;
++
++ if (!IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
++ min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn)))
++ return false;
++
++ return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
++}
++
+ u64 dma_direct_get_required_mask(struct device *dev);
+ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0456-dma-direct-exclude-dma_direct_map_resource-from-the-.patch b/target/linux/bcm27xx/patches-5.4/950-0456-dma-direct-exclude-dma_direct_map_resource-from-the-.patch
new file mode 100644
index 0000000000..94a1329d84
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0456-dma-direct-exclude-dma_direct_map_resource-from-the-.patch
@@ -0,0 +1,115 @@
+From b763f24aed409296eb76d085c279b2c40462f8a1 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Tue, 19 Nov 2019 17:38:58 +0100
+Subject: [PATCH] dma-direct: exclude dma_direct_map_resource from the
+ min_low_pfn check
+
+commit 68a33b1794665ba8a1d1ef1d3bfcc7c587d380a6 upstream.
+
+The valid memory address check in dma_capable only makes sense when mapping
+normal memory, not when using dma_map_resource to map a device resource.
+Add a new boolean argument to dma_capable to exclude that check for the
+dma_map_resource case.
+
+Fixes: b12d66278dd6 ("dma-direct: check for overflows on 32 bit DMA addresses")
+Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+---
+ arch/x86/kernel/amd_gart_64.c | 4 ++--
+ drivers/xen/swiotlb-xen.c | 4 ++--
+ include/linux/dma-direct.h | 5 +++--
+ kernel/dma/direct.c | 4 ++--
+ kernel/dma/swiotlb.c | 2 +-
+ 5 files changed, 10 insertions(+), 9 deletions(-)
+
+--- a/arch/x86/kernel/amd_gart_64.c
++++ b/arch/x86/kernel/amd_gart_64.c
+@@ -185,13 +185,13 @@ static void iommu_full(struct device *de
+ static inline int
+ need_iommu(struct device *dev, unsigned long addr, size_t size)
+ {
+- return force_iommu || !dma_capable(dev, addr, size);
++ return force_iommu || !dma_capable(dev, addr, size, true);
+ }
+
+ static inline int
+ nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
+ {
+- return !dma_capable(dev, addr, size);
++ return !dma_capable(dev, addr, size, true);
+ }
+
+ /* Map a single continuous physical area into the IOMMU.
+--- a/drivers/xen/swiotlb-xen.c
++++ b/drivers/xen/swiotlb-xen.c
+@@ -375,7 +375,7 @@ static dma_addr_t xen_swiotlb_map_page(s
+ * we can safely return the device addr and not worry about bounce
+ * buffering it.
+ */
+- if (dma_capable(dev, dev_addr, size) &&
++ if (dma_capable(dev, dev_addr, size, true) &&
+ !range_straddles_page_boundary(phys, size) &&
+ !xen_arch_need_swiotlb(dev, phys, dev_addr) &&
+ swiotlb_force != SWIOTLB_FORCE)
+@@ -397,7 +397,7 @@ static dma_addr_t xen_swiotlb_map_page(s
+ /*
+ * Ensure that the address returned is DMA'ble
+ */
+- if (unlikely(!dma_capable(dev, dev_addr, size))) {
++ if (unlikely(!dma_capable(dev, dev_addr, size, true))) {
+ swiotlb_tbl_unmap_single(dev, map, size, size, dir,
+ attrs | DMA_ATTR_SKIP_CPU_SYNC);
+ return DMA_MAPPING_ERROR;
+--- a/include/linux/dma-direct.h
++++ b/include/linux/dma-direct.h
+@@ -51,14 +51,15 @@ static inline phys_addr_t dma_to_phys(st
+ return __sme_clr(__dma_to_phys(dev, daddr));
+ }
+
+-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
++static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size,
++ bool is_ram)
+ {
+ dma_addr_t end = addr + size - 1;
+
+ if (!dev->dma_mask)
+ return false;
+
+- if (!IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
++ if (is_ram && !IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
+ min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn)))
+ return false;
+
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -325,7 +325,7 @@ static inline bool dma_direct_possible(s
+ size_t size)
+ {
+ return swiotlb_force != SWIOTLB_FORCE &&
+- dma_capable(dev, dma_addr, size);
++ dma_capable(dev, dma_addr, size, true);
+ }
+
+ dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
+@@ -374,7 +374,7 @@ dma_addr_t dma_direct_map_resource(struc
+ {
+ dma_addr_t dma_addr = paddr;
+
+- if (unlikely(!dma_capable(dev, dma_addr, size))) {
++ if (unlikely(!dma_capable(dev, dma_addr, size, false))) {
+ report_addr(dev, dma_addr, size);
+ return DMA_MAPPING_ERROR;
+ }
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -678,7 +678,7 @@ bool swiotlb_map(struct device *dev, phy
+
+ /* Ensure that the address returned is DMA'ble */
+ *dma_addr = __phys_to_dma(dev, *phys);
+- if (unlikely(!dma_capable(dev, *dma_addr, size))) {
++ if (unlikely(!dma_capable(dev, *dma_addr, size, true))) {
+ swiotlb_tbl_unmap_single(dev, *phys, size, size, dir,
+ attrs | DMA_ATTR_SKIP_CPU_SYNC);
+ return false;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0457-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch b/target/linux/bcm27xx/patches-5.4/950-0457-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch
new file mode 100644
index 0000000000..05dad5ddaf
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0457-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch
@@ -0,0 +1,366 @@
+From d5430c466b3c3b5f631ee37be333a40924575b72 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Thu, 21 Nov 2019 10:26:44 +0100
+Subject: [PATCH] dma-mapping: treat dev->bus_dma_mask as a DMA limit
+
+commit a7ba70f1787f977f970cd116076c6fce4b9e01cc upstream.
+
+Using a mask to represent bus DMA constraints has a set of limitations.
+The biggest one being it can only hold a power of two (minus one). The
+DMA mapping code is already aware of this and treats dev->bus_dma_mask
+as a limit. This quirk is already used by some architectures although
+still rare.
+
+With the introduction of the Raspberry Pi 4 we've found a new contender
+for the use of bus DMA limits, as its PCIe bus can only address the
+lower 3GB of memory (of a total of 4GB). This is impossible to represent
+with a mask. To make things worse the device-tree code rounds non power
+of two bus DMA limits to the next power of two, which is unacceptable in
+this case.
+
+In the light of this, rename dev->bus_dma_mask to dev->bus_dma_limit all
+over the tree and treat it as such. Note that dev->bus_dma_limit should
+contain the higher accessible DMA address.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ arch/mips/pci/fixup-sb1250.c | 16 ++++++++--------
+ arch/powerpc/sysdev/fsl_pci.c | 6 +++---
+ arch/x86/kernel/pci-dma.c | 2 +-
+ arch/x86/mm/mem_encrypt.c | 2 +-
+ arch/x86/pci/sta2x11-fixup.c | 2 +-
+ drivers/acpi/arm64/iort.c | 20 +++++++-------------
+ drivers/ata/ahci.c | 2 +-
+ drivers/iommu/dma-iommu.c | 3 +--
+ drivers/of/device.c | 9 +++++----
+ include/linux/device.h | 6 +++---
+ include/linux/dma-direct.h | 2 +-
+ include/linux/dma-mapping.h | 2 +-
+ kernel/dma/direct.c | 27 +++++++++++++--------------
+ 13 files changed, 46 insertions(+), 53 deletions(-)
+
+--- a/arch/mips/pci/fixup-sb1250.c
++++ b/arch/mips/pci/fixup-sb1250.c
+@@ -21,22 +21,22 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SI
+
+ /*
+ * The BCM1250, etc. PCI host bridge does not support DAC on its 32-bit
+- * bus, so we set the bus's DMA mask accordingly. However the HT link
++ * bus, so we set the bus's DMA limit accordingly. However the HT link
+ * down the artificial PCI-HT bridge supports 40-bit addressing and the
+ * SP1011 HT-PCI bridge downstream supports both DAC and a 64-bit bus
+ * width, so we record the PCI-HT bridge's secondary and subordinate bus
+- * numbers and do not set the mask for devices present in the inclusive
++ * numbers and do not set the limit for devices present in the inclusive
+ * range of those.
+ */
+-struct sb1250_bus_dma_mask_exclude {
++struct sb1250_bus_dma_limit_exclude {
+ bool set;
+ unsigned char start;
+ unsigned char end;
+ };
+
+-static int sb1250_bus_dma_mask(struct pci_dev *dev, void *data)
++static int sb1250_bus_dma_limit(struct pci_dev *dev, void *data)
+ {
+- struct sb1250_bus_dma_mask_exclude *exclude = data;
++ struct sb1250_bus_dma_limit_exclude *exclude = data;
+ bool exclude_this;
+ bool ht_bridge;
+
+@@ -55,7 +55,7 @@ static int sb1250_bus_dma_mask(struct pc
+ exclude->start, exclude->end);
+ } else {
+ dev_dbg(&dev->dev, "disabling DAC for device");
+- dev->dev.bus_dma_mask = DMA_BIT_MASK(32);
++ dev->dev.bus_dma_limit = DMA_BIT_MASK(32);
+ }
+
+ return 0;
+@@ -63,9 +63,9 @@ static int sb1250_bus_dma_mask(struct pc
+
+ static void quirk_sb1250_pci_dac(struct pci_dev *dev)
+ {
+- struct sb1250_bus_dma_mask_exclude exclude = { .set = false };
++ struct sb1250_bus_dma_limit_exclude exclude = { .set = false };
+
+- pci_walk_bus(dev->bus, sb1250_bus_dma_mask, &exclude);
++ pci_walk_bus(dev->bus, sb1250_bus_dma_limit, &exclude);
+ }
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI,
+ quirk_sb1250_pci_dac);
+--- a/arch/powerpc/sysdev/fsl_pci.c
++++ b/arch/powerpc/sysdev/fsl_pci.c
+@@ -115,8 +115,8 @@ static void pci_dma_dev_setup_swiotlb(st
+ {
+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+
+- pdev->dev.bus_dma_mask =
+- hose->dma_window_base_cur + hose->dma_window_size;
++ pdev->dev.bus_dma_limit =
++ hose->dma_window_base_cur + hose->dma_window_size - 1;
+ }
+
+ static void setup_swiotlb_ops(struct pci_controller *hose)
+@@ -135,7 +135,7 @@ static void fsl_pci_dma_set_mask(struct
+ * mapping that allows addressing any RAM address from across PCI.
+ */
+ if (dev_is_pci(dev) && dma_mask >= pci64_dma_offset * 2 - 1) {
+- dev->bus_dma_mask = 0;
++ dev->bus_dma_limit = 0;
+ dev->archdata.dma_offset = pci64_dma_offset;
+ }
+ }
+--- a/arch/x86/kernel/pci-dma.c
++++ b/arch/x86/kernel/pci-dma.c
+@@ -146,7 +146,7 @@ rootfs_initcall(pci_iommu_init);
+
+ static int via_no_dac_cb(struct pci_dev *pdev, void *data)
+ {
+- pdev->dev.bus_dma_mask = DMA_BIT_MASK(32);
++ pdev->dev.bus_dma_limit = DMA_BIT_MASK(32);
+ return 0;
+ }
+
+--- a/arch/x86/mm/mem_encrypt.c
++++ b/arch/x86/mm/mem_encrypt.c
+@@ -367,7 +367,7 @@ bool force_dma_unencrypted(struct device
+ if (sme_active()) {
+ u64 dma_enc_mask = DMA_BIT_MASK(__ffs64(sme_me_mask));
+ u64 dma_dev_mask = min_not_zero(dev->coherent_dma_mask,
+- dev->bus_dma_mask);
++ dev->bus_dma_limit);
+
+ if (dma_dev_mask <= dma_enc_mask)
+ return true;
+--- a/arch/x86/pci/sta2x11-fixup.c
++++ b/arch/x86/pci/sta2x11-fixup.c
+@@ -143,7 +143,7 @@ static void sta2x11_map_ep(struct pci_de
+
+ dev->dma_pfn_offset = PFN_DOWN(-amba_base);
+
+- dev->bus_dma_mask = max_amba_addr;
++ dev->bus_dma_limit = max_amba_addr;
+ pci_set_consistent_dma_mask(pdev, max_amba_addr);
+ pci_set_dma_mask(pdev, max_amba_addr);
+
+--- a/drivers/acpi/arm64/iort.c
++++ b/drivers/acpi/arm64/iort.c
+@@ -1057,8 +1057,8 @@ static int rc_dma_get_range(struct devic
+ */
+ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
+ {
+- u64 mask, dmaaddr = 0, size = 0, offset = 0;
+- int ret, msb;
++ u64 end, mask, dmaaddr = 0, size = 0, offset = 0;
++ int ret;
+
+ /*
+ * If @dev is expected to be DMA-capable then the bus code that created
+@@ -1085,19 +1085,13 @@ void iort_dma_setup(struct device *dev,
+ }
+
+ if (!ret) {
+- msb = fls64(dmaaddr + size - 1);
+ /*
+- * Round-up to the power-of-two mask or set
+- * the mask to the whole 64-bit address space
+- * in case the DMA region covers the full
+- * memory window.
++ * Limit coherent and dma mask based on size retrieved from
++ * firmware.
+ */
+- mask = msb == 64 ? U64_MAX : (1ULL << msb) - 1;
+- /*
+- * Limit coherent and dma mask based on size
+- * retrieved from firmware.
+- */
+- dev->bus_dma_mask = mask;
++ end = dmaaddr + size - 1;
++ mask = DMA_BIT_MASK(ilog2(end) + 1);
++ dev->bus_dma_limit = end;
+ dev->coherent_dma_mask = mask;
+ *dev->dma_mask = mask;
+ }
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -899,7 +899,7 @@ static int ahci_configure_dma_masks(stru
+ * value, don't extend it here. This happens on STA2X11, for example.
+ *
+ * XXX: manipulating the DMA mask from platform code is completely
+- * bogus, platform code should use dev->bus_dma_mask instead..
++ * bogus, platform code should use dev->bus_dma_limit instead..
+ */
+ if (pdev->dma_mask && pdev->dma_mask < DMA_BIT_MASK(32))
+ return 0;
+--- a/drivers/iommu/dma-iommu.c
++++ b/drivers/iommu/dma-iommu.c
+@@ -404,8 +404,7 @@ static dma_addr_t iommu_dma_alloc_iova(s
+ if (iova_len < (1 << (IOVA_RANGE_CACHE_MAX_SIZE - 1)))
+ iova_len = roundup_pow_of_two(iova_len);
+
+- if (dev->bus_dma_mask)
+- dma_limit &= dev->bus_dma_mask;
++ dma_limit = min_not_zero(dma_limit, dev->bus_dma_limit);
+
+ if (domain->geometry.force_aperture)
+ dma_limit = min(dma_limit, domain->geometry.aperture_end);
+--- a/drivers/of/device.c
++++ b/drivers/of/device.c
+@@ -93,7 +93,7 @@ int of_dma_configure(struct device *dev,
+ bool coherent;
+ unsigned long offset;
+ const struct iommu_ops *iommu;
+- u64 mask;
++ u64 mask, end;
+
+ ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
+ if (ret < 0) {
+@@ -148,12 +148,13 @@ int of_dma_configure(struct device *dev,
+ * Limit coherent and dma mask based on size and default mask
+ * set by the driver.
+ */
+- mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
++ end = dma_addr + size - 1;
++ mask = DMA_BIT_MASK(ilog2(end) + 1);
+ dev->coherent_dma_mask &= mask;
+ *dev->dma_mask &= mask;
+- /* ...but only set bus mask if we found valid dma-ranges earlier */
++ /* ...but only set bus limit if we found valid dma-ranges earlier */
+ if (!ret)
+- dev->bus_dma_mask = mask;
++ dev->bus_dma_limit = end;
+
+ coherent = of_dma_is_coherent(np);
+ dev_dbg(dev, "device is%sdma coherent\n",
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -1186,8 +1186,8 @@ struct dev_links_info {
+ * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
+ * hardware supports 64-bit addresses for consistent allocations
+ * such descriptors.
+- * @bus_dma_mask: Mask of an upstream bridge or bus which imposes a smaller DMA
+- * limit than the device itself supports.
++ * @bus_dma_limit: Limit of an upstream bridge or bus which imposes a smaller
++ * DMA limit than the device itself supports.
+ * @dma_pfn_offset: offset of DMA memory range relatively of RAM
+ * @dma_parms: A low level driver may set these to teach IOMMU code about
+ * segment limitations.
+@@ -1270,7 +1270,7 @@ struct device {
+ not all hardware supports
+ 64 bit addresses for consistent
+ allocations such descriptors. */
+- u64 bus_dma_mask; /* upstream dma_mask constraint */
++ u64 bus_dma_limit; /* upstream dma constraint */
+ unsigned long dma_pfn_offset;
+
+ struct device_dma_parameters *dma_parms;
+--- a/include/linux/dma-direct.h
++++ b/include/linux/dma-direct.h
+@@ -63,7 +63,7 @@ static inline bool dma_capable(struct de
+ min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn)))
+ return false;
+
+- return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
++ return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_limit);
+ }
+
+ u64 dma_direct_get_required_mask(struct device *dev);
+--- a/include/linux/dma-mapping.h
++++ b/include/linux/dma-mapping.h
+@@ -697,7 +697,7 @@ static inline int dma_coerce_mask_and_co
+ */
+ static inline bool dma_addressing_limited(struct device *dev)
+ {
+- return min_not_zero(dma_get_mask(dev), dev->bus_dma_mask) <
++ return min_not_zero(dma_get_mask(dev), dev->bus_dma_limit) <
+ dma_get_required_mask(dev);
+ }
+
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -26,10 +26,10 @@ static void report_addr(struct device *d
+ {
+ if (!dev->dma_mask) {
+ dev_err_once(dev, "DMA map on device without dma_mask\n");
+- } else if (*dev->dma_mask >= DMA_BIT_MASK(32) || dev->bus_dma_mask) {
++ } else if (*dev->dma_mask >= DMA_BIT_MASK(32) || dev->bus_dma_limit) {
+ dev_err_once(dev,
+- "overflow %pad+%zu of DMA mask %llx bus mask %llx\n",
+- &dma_addr, size, *dev->dma_mask, dev->bus_dma_mask);
++ "overflow %pad+%zu of DMA mask %llx bus limit %llx\n",
++ &dma_addr, size, *dev->dma_mask, dev->bus_dma_limit);
+ }
+ WARN_ON_ONCE(1);
+ }
+@@ -50,15 +50,14 @@ u64 dma_direct_get_required_mask(struct
+ }
+
+ static gfp_t __dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
+- u64 *phys_mask)
++ u64 *phys_limit)
+ {
+- if (dev->bus_dma_mask && dev->bus_dma_mask < dma_mask)
+- dma_mask = dev->bus_dma_mask;
++ u64 dma_limit = min_not_zero(dma_mask, dev->bus_dma_limit);
+
+ if (force_dma_unencrypted(dev))
+- *phys_mask = __dma_to_phys(dev, dma_mask);
++ *phys_limit = __dma_to_phys(dev, dma_limit);
+ else
+- *phys_mask = dma_to_phys(dev, dma_mask);
++ *phys_limit = dma_to_phys(dev, dma_limit);
+
+ /*
+ * Optimistically try the zone that the physical address mask falls
+@@ -68,9 +67,9 @@ static gfp_t __dma_direct_optimal_gfp_ma
+ * Note that GFP_DMA32 and GFP_DMA are no ops without the corresponding
+ * zones.
+ */
+- if (*phys_mask <= DMA_BIT_MASK(zone_dma_bits))
++ if (*phys_limit <= DMA_BIT_MASK(zone_dma_bits))
+ return GFP_DMA;
+- if (*phys_mask <= DMA_BIT_MASK(32))
++ if (*phys_limit <= DMA_BIT_MASK(32))
+ return GFP_DMA32;
+ return 0;
+ }
+@@ -78,7 +77,7 @@ static gfp_t __dma_direct_optimal_gfp_ma
+ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
+ {
+ return phys_to_dma_direct(dev, phys) + size - 1 <=
+- min_not_zero(dev->coherent_dma_mask, dev->bus_dma_mask);
++ min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit);
+ }
+
+ struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
+@@ -87,7 +86,7 @@ struct page *__dma_direct_alloc_pages(st
+ size_t alloc_size = PAGE_ALIGN(size);
+ int node = dev_to_node(dev);
+ struct page *page = NULL;
+- u64 phys_mask;
++ u64 phys_limit;
+
+ if (attrs & DMA_ATTR_NO_WARN)
+ gfp |= __GFP_NOWARN;
+@@ -95,7 +94,7 @@ struct page *__dma_direct_alloc_pages(st
+ /* we always manually zero the memory once we are done: */
+ gfp &= ~__GFP_ZERO;
+ gfp |= __dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
+- &phys_mask);
++ &phys_limit);
+ page = dma_alloc_contiguous(dev, alloc_size, gfp);
+ if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+ dma_free_contiguous(dev, page, alloc_size);
+@@ -109,7 +108,7 @@ again:
+ page = NULL;
+
+ if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
+- phys_mask < DMA_BIT_MASK(64) &&
++ phys_limit < DMA_BIT_MASK(64) &&
+ !(gfp & (GFP_DMA32 | GFP_DMA))) {
+ gfp |= GFP_DMA32;
+ goto again;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0458-ARM-dts-bcm2711-Enable-PCIe-controller.patch b/target/linux/bcm27xx/patches-5.4/950-0458-ARM-dts-bcm2711-Enable-PCIe-controller.patch
new file mode 100644
index 0000000000..9f114c1633
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0458-ARM-dts-bcm2711-Enable-PCIe-controller.patch
@@ -0,0 +1,56 @@
+From 0ec0bc884f6cf1ec9775c750f78ce28be7da4340 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Mon, 16 Dec 2019 12:01:08 +0100
+Subject: [PATCH] ARM: dts: bcm2711: Enable PCIe controller
+
+commit d5c8dc0d4c880fbde5293cc186b1ab23466254c4 upstream.
+
+This enables bcm2711's PCIe bus, which is hardwired to a VIA
+Technologies XHCI USB 3.0 controller.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ arch/arm/boot/dts/bcm2711.dtsi | 31 ++++++++++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/bcm2711.dtsi
++++ b/arch/arm/boot/dts/bcm2711.dtsi
+@@ -331,7 +331,36 @@
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+- ranges = <0x0 0x7c000000 0x0 0xfc000000 0x03800000>;
++ ranges = <0x0 0x7c000000 0x0 0xfc000000 0x03800000>,
++ <0x6 0x00000000 0x6 0x00000000 0x40000000>;
++
++ pcie0: pcie@7d500000 {
++ compatible = "brcm,bcm2711-pcie";
++ reg = <0x0 0x7d500000 0x9310>;
++ device_type = "pci";
++ #address-cells = <3>;
++ #interrupt-cells = <1>;
++ #size-cells = <2>;
++ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "pcie", "msi";
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143
++ IRQ_TYPE_LEVEL_HIGH>;
++ msi-controller;
++ msi-parent = <&pcie0>;
++
++ ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000
++ 0x0 0x04000000>;
++ /*
++ * The wrapper around the PCIe block has a bug
++ * preventing it from accessing beyond the first 3GB of
++ * memory.
++ */
++ dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000
++ 0x0 0xc0000000>;
++ brcm,enable-ssc;
++ };
+
+ genet: ethernet@7d580000 {
+ compatible = "brcm,bcm2711-genet-v5";
diff --git a/target/linux/bcm27xx/patches-5.4/950-0459-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch b/target/linux/bcm27xx/patches-5.4/950-0459-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch
new file mode 100644
index 0000000000..ca97a1966e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0459-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch
@@ -0,0 +1,810 @@
+From 4d9470c29736bf81bdb0d21da24cf350b1e99402 Mon Sep 17 00:00:00 2001
+From: Jim Quinlan <james.quinlan@broadcom.com>
+Date: Mon, 16 Dec 2019 12:01:09 +0100
+Subject: [PATCH] PCI: brcmstb: Add Broadcom STB PCIe host controller
+ driver
+
+commit c0452137034bda8f686dd9a2e167949bfffd6776 upstream.
+
+This adds a basic driver for Broadcom's STB PCIe controller, for now
+aimed at Raspberry Pi 4's SoC, bcm2711.
+
+Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
+Co-developed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+[lorenzo.pieralisi@arm.com: updated brcm_pcie_get_rc_bar2_size_and_offset()according to https://lore.kernel.org/linux-pci/be8ddb33a7360af1815cf686f77f3f0913d02be3.camel@suse.de]
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Andrew Murray <andrew.murray@arm.com>
+Reviewed-by: Jeremy Linton <jeremy.linton@arm.com>
+---
+ drivers/pci/controller/Kconfig | 8 +
+ drivers/pci/controller/Makefile | 1 +
+ drivers/pci/controller/pcie-brcmstb.c | 755 ++++++++++++++++++++++++++
+ 3 files changed, 764 insertions(+)
+ create mode 100644 drivers/pci/controller/pcie-brcmstb.c
+
+--- a/drivers/pci/controller/Kconfig
++++ b/drivers/pci/controller/Kconfig
+@@ -281,6 +281,14 @@ config VMD
+ To compile this driver as a module, choose M here: the
+ module will be called vmd.
+
++config PCIE_BRCMSTB
++ tristate "Broadcom Brcmstb PCIe host controller"
++ depends on ARCH_BCM2835 || COMPILE_TEST
++ depends on OF
++ help
++ Say Y here to enable PCIe host controller support for
++ Broadcom STB based SoCs, like the Raspberry Pi 4.
++
+ config PCI_HYPERV_INTERFACE
+ tristate "Hyper-V PCI Interface"
+ depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64
+--- a/drivers/pci/controller/Makefile
++++ b/drivers/pci/controller/Makefile
+@@ -30,6 +30,7 @@ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-medi
+ obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
+ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
+ obj-$(CONFIG_VMD) += vmd.o
++obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
+ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
+ obj-y += dwc/
+
+--- /dev/null
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -0,0 +1,755 @@
++// SPDX-License-Identifier: GPL-2.0+
++/* Copyright (C) 2009 - 2019 Broadcom */
++
++#include <linux/bitfield.h>
++#include <linux/clk.h>
++#include <linux/compiler.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/irqdomain.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/log2.h>
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++#include <linux/of_pci.h>
++#include <linux/of_platform.h>
++#include <linux/pci.h>
++#include <linux/printk.h>
++#include <linux/sizes.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/types.h>
++
++#include "../pci.h"
++
++/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
++#define BRCM_PCIE_CAP_REGS 0x00ac
++
++/* Broadcom STB PCIe Register Offsets */
++#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 0x0188
++#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc
++#define PCIE_RC_CFG_VENDOR_SPCIFIC_REG1_LITTLE_ENDIAN 0x0
++
++#define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c
++#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff
++
++#define PCIE_RC_DL_MDIO_ADDR 0x1100
++#define PCIE_RC_DL_MDIO_WR_DATA 0x1104
++#define PCIE_RC_DL_MDIO_RD_DATA 0x1108
++
++#define PCIE_MISC_MISC_CTRL 0x4008
++#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000
++#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000
++#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000
++#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_128 0x0
++#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000
++
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c
++#define PCIE_MEM_WIN0_LO(win) \
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 4)
++
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010
++#define PCIE_MEM_WIN0_HI(win) \
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 4)
++
++#define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c
++#define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f
++
++#define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034
++#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f
++#define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038
++
++#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c
++#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f
++
++#define PCIE_MISC_PCIE_CTRL 0x4064
++#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1
++
++#define PCIE_MISC_PCIE_STATUS 0x4068
++#define PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK 0x80
++#define PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK 0x20
++#define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK 0x10
++#define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK 0x40
++
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0
++#define PCIE_MEM_WIN0_BASE_LIMIT(win) \
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
++
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK 0xff
++#define PCIE_MEM_WIN0_BASE_HI(win) \
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
++
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084
++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff
++#define PCIE_MEM_WIN0_LIMIT_HI(win) \
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
++
++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
++
++#define PCIE_MSI_INTR2_STATUS 0x4500
++#define PCIE_MSI_INTR2_CLR 0x4508
++#define PCIE_MSI_INTR2_MASK_SET 0x4510
++#define PCIE_MSI_INTR2_MASK_CLR 0x4514
++
++#define PCIE_EXT_CFG_DATA 0x8000
++
++#define PCIE_EXT_CFG_INDEX 0x9000
++#define PCIE_EXT_BUSNUM_SHIFT 20
++#define PCIE_EXT_SLOT_SHIFT 15
++#define PCIE_EXT_FUNC_SHIFT 12
++
++#define PCIE_RGR1_SW_INIT_1 0x9210
++#define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1
++#define PCIE_RGR1_SW_INIT_1_INIT_MASK 0x2
++
++/* PCIe parameters */
++#define BRCM_NUM_PCIE_OUT_WINS 0x4
++
++/* MDIO registers */
++#define MDIO_PORT0 0x0
++#define MDIO_DATA_MASK 0x7fffffff
++#define MDIO_PORT_MASK 0xf0000
++#define MDIO_REGAD_MASK 0xffff
++#define MDIO_CMD_MASK 0xfff00000
++#define MDIO_CMD_READ 0x1
++#define MDIO_CMD_WRITE 0x0
++#define MDIO_DATA_DONE_MASK 0x80000000
++#define MDIO_RD_DONE(x) (((x) & MDIO_DATA_DONE_MASK) ? 1 : 0)
++#define MDIO_WT_DONE(x) (((x) & MDIO_DATA_DONE_MASK) ? 0 : 1)
++#define SSC_REGS_ADDR 0x1100
++#define SET_ADDR_OFFSET 0x1f
++#define SSC_CNTL_OFFSET 0x2
++#define SSC_CNTL_OVRD_EN_MASK 0x8000
++#define SSC_CNTL_OVRD_VAL_MASK 0x4000
++#define SSC_STATUS_OFFSET 0x1
++#define SSC_STATUS_SSC_MASK 0x400
++#define SSC_STATUS_PLL_LOCK_MASK 0x800
++
++/* Internal PCIe Host Controller Information.*/
++struct brcm_pcie {
++ struct device *dev;
++ void __iomem *base;
++ struct clk *clk;
++ struct pci_bus *root_bus;
++ struct device_node *np;
++ bool ssc;
++ int gen;
++};
++
++/*
++ * This is to convert the size of the inbound "BAR" region to the
++ * non-linear values of PCIE_X_MISC_RC_BAR[123]_CONFIG_LO.SIZE
++ */
++static int brcm_pcie_encode_ibar_size(u64 size)
++{
++ int log2_in = ilog2(size);
++
++ if (log2_in >= 12 && log2_in <= 15)
++ /* Covers 4KB to 32KB (inclusive) */
++ return (log2_in - 12) + 0x1c;
++ else if (log2_in >= 16 && log2_in <= 35)
++ /* Covers 64KB to 32GB, (inclusive) */
++ return log2_in - 15;
++ /* Something is awry so disable */
++ return 0;
++}
++
++static u32 brcm_pcie_mdio_form_pkt(int port, int regad, int cmd)
++{
++ u32 pkt = 0;
++
++ pkt |= FIELD_PREP(MDIO_PORT_MASK, port);
++ pkt |= FIELD_PREP(MDIO_REGAD_MASK, regad);
++ pkt |= FIELD_PREP(MDIO_CMD_MASK, cmd);
++
++ return pkt;
++}
++
++/* negative return value indicates error */
++static int brcm_pcie_mdio_read(void __iomem *base, u8 port, u8 regad, u32 *val)
++{
++ int tries;
++ u32 data;
++
++ writel(brcm_pcie_mdio_form_pkt(port, regad, MDIO_CMD_READ),
++ base + PCIE_RC_DL_MDIO_ADDR);
++ readl(base + PCIE_RC_DL_MDIO_ADDR);
++
++ data = readl(base + PCIE_RC_DL_MDIO_RD_DATA);
++ for (tries = 0; !MDIO_RD_DONE(data) && tries < 10; tries++) {
++ udelay(10);
++ data = readl(base + PCIE_RC_DL_MDIO_RD_DATA);
++ }
++
++ *val = FIELD_GET(MDIO_DATA_MASK, data);
++ return MDIO_RD_DONE(data) ? 0 : -EIO;
++}
++
++/* negative return value indicates error */
++static int brcm_pcie_mdio_write(void __iomem *base, u8 port,
++ u8 regad, u16 wrdata)
++{
++ int tries;
++ u32 data;
++
++ writel(brcm_pcie_mdio_form_pkt(port, regad, MDIO_CMD_WRITE),
++ base + PCIE_RC_DL_MDIO_ADDR);
++ readl(base + PCIE_RC_DL_MDIO_ADDR);
++ writel(MDIO_DATA_DONE_MASK | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA);
++
++ data = readl(base + PCIE_RC_DL_MDIO_WR_DATA);
++ for (tries = 0; !MDIO_WT_DONE(data) && tries < 10; tries++) {
++ udelay(10);
++ data = readl(base + PCIE_RC_DL_MDIO_WR_DATA);
++ }
++
++ return MDIO_WT_DONE(data) ? 0 : -EIO;
++}
++
++/*
++ * Configures device for Spread Spectrum Clocking (SSC) mode; a negative
++ * return value indicates error.
++ */
++static int brcm_pcie_set_ssc(struct brcm_pcie *pcie)
++{
++ int pll, ssc;
++ int ret;
++ u32 tmp;
++
++ ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, SET_ADDR_OFFSET,
++ SSC_REGS_ADDR);
++ if (ret < 0)
++ return ret;
++
++ ret = brcm_pcie_mdio_read(pcie->base, MDIO_PORT0,
++ SSC_CNTL_OFFSET, &tmp);
++ if (ret < 0)
++ return ret;
++
++ u32p_replace_bits(&tmp, 1, SSC_CNTL_OVRD_EN_MASK);
++ u32p_replace_bits(&tmp, 1, SSC_CNTL_OVRD_VAL_MASK);
++ ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0,
++ SSC_CNTL_OFFSET, tmp);
++ if (ret < 0)
++ return ret;
++
++ usleep_range(1000, 2000);
++ ret = brcm_pcie_mdio_read(pcie->base, MDIO_PORT0,
++ SSC_STATUS_OFFSET, &tmp);
++ if (ret < 0)
++ return ret;
++
++ ssc = FIELD_GET(SSC_STATUS_SSC_MASK, tmp);
++ pll = FIELD_GET(SSC_STATUS_PLL_LOCK_MASK, tmp);
++
++ return ssc && pll ? 0 : -EIO;
++}
++
++/* Limits operation to a specific generation (1, 2, or 3) */
++static void brcm_pcie_set_gen(struct brcm_pcie *pcie, int gen)
++{
++ u16 lnkctl2 = readw(pcie->base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2);
++ u32 lnkcap = readl(pcie->base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP);
++
++ lnkcap = (lnkcap & ~PCI_EXP_LNKCAP_SLS) | gen;
++ writel(lnkcap, pcie->base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP);
++
++ lnkctl2 = (lnkctl2 & ~0xf) | gen;
++ writew(lnkctl2, pcie->base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2);
++}
++
++static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
++ unsigned int win, u64 cpu_addr,
++ u64 pcie_addr, u64 size)
++{
++ u32 cpu_addr_mb_high, limit_addr_mb_high;
++ phys_addr_t cpu_addr_mb, limit_addr_mb;
++ int high_addr_shift;
++ u32 tmp;
++
++ /* Set the base of the pcie_addr window */
++ writel(lower_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_LO(win));
++ writel(upper_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_HI(win));
++
++ /* Write the addr base & limit lower bits (in MBs) */
++ cpu_addr_mb = cpu_addr / SZ_1M;
++ limit_addr_mb = (cpu_addr + size - 1) / SZ_1M;
++
++ tmp = readl(pcie->base + PCIE_MEM_WIN0_BASE_LIMIT(win));
++ u32p_replace_bits(&tmp, cpu_addr_mb,
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK);
++ u32p_replace_bits(&tmp, limit_addr_mb,
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK);
++ writel(tmp, pcie->base + PCIE_MEM_WIN0_BASE_LIMIT(win));
++
++ /* Write the cpu & limit addr upper bits */
++ high_addr_shift =
++ HWEIGHT32(PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK);
++
++ cpu_addr_mb_high = cpu_addr_mb >> high_addr_shift;
++ tmp = readl(pcie->base + PCIE_MEM_WIN0_BASE_HI(win));
++ u32p_replace_bits(&tmp, cpu_addr_mb_high,
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK);
++ writel(tmp, pcie->base + PCIE_MEM_WIN0_BASE_HI(win));
++
++ limit_addr_mb_high = limit_addr_mb >> high_addr_shift;
++ tmp = readl(pcie->base + PCIE_MEM_WIN0_LIMIT_HI(win));
++ u32p_replace_bits(&tmp, limit_addr_mb_high,
++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK);
++ writel(tmp, pcie->base + PCIE_MEM_WIN0_LIMIT_HI(win));
++}
++
++/* The controller is capable of serving in both RC and EP roles */
++static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie)
++{
++ void __iomem *base = pcie->base;
++ u32 val = readl(base + PCIE_MISC_PCIE_STATUS);
++
++ return !!FIELD_GET(PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK, val);
++}
++
++static bool brcm_pcie_link_up(struct brcm_pcie *pcie)
++{
++ u32 val = readl(pcie->base + PCIE_MISC_PCIE_STATUS);
++ u32 dla = FIELD_GET(PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK, val);
++ u32 plu = FIELD_GET(PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK, val);
++
++ return dla && plu;
++}
++
++/* Configuration space read/write support */
++static inline int brcm_pcie_cfg_index(int busnr, int devfn, int reg)
++{
++ return ((PCI_SLOT(devfn) & 0x1f) << PCIE_EXT_SLOT_SHIFT)
++ | ((PCI_FUNC(devfn) & 0x07) << PCIE_EXT_FUNC_SHIFT)
++ | (busnr << PCIE_EXT_BUSNUM_SHIFT)
++ | (reg & ~3);
++}
++
++static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
++ int where)
++{
++ struct brcm_pcie *pcie = bus->sysdata;
++ void __iomem *base = pcie->base;
++ int idx;
++
++ /* Accesses to the RC go right to the RC registers if slot==0 */
++ if (pci_is_root_bus(bus))
++ return PCI_SLOT(devfn) ? NULL : base + where;
++
++ /* For devices, write to the config space index register */
++ idx = brcm_pcie_cfg_index(bus->number, devfn, 0);
++ writel(idx, pcie->base + PCIE_EXT_CFG_INDEX);
++ return base + PCIE_EXT_CFG_DATA + where;
++}
++
++static struct pci_ops brcm_pcie_ops = {
++ .map_bus = brcm_pcie_map_conf,
++ .read = pci_generic_config_read,
++ .write = pci_generic_config_write,
++};
++
++static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, u32 val)
++{
++ u32 tmp;
++
++ tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1);
++ u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_INIT_MASK);
++ writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1);
++}
++
++static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, u32 val)
++{
++ u32 tmp;
++
++ tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1);
++ u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_PERST_MASK);
++ writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1);
++}
++
++static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
++ u64 *rc_bar2_size,
++ u64 *rc_bar2_offset)
++{
++ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
++ struct device *dev = pcie->dev;
++ struct resource_entry *entry;
++
++ entry = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM);
++ if (!entry)
++ return -ENODEV;
++
++
++ /*
++ * The controller expects the inbound window offset to be calculated as
++ * the difference between PCIe's address space and CPU's. The offset
++ * provided by the firmware is calculated the opposite way, so we
++ * negate it.
++ */
++ *rc_bar2_offset = -entry->offset;
++ *rc_bar2_size = 1ULL << fls64(entry->res->end - entry->res->start);
++
++ /*
++ * We validate the inbound memory view even though we should trust
++ * whatever the device-tree provides. This is because of an HW issue on
++ * early Raspberry Pi 4's revisions (bcm2711). It turns out its
++ * firmware has to dynamically edit dma-ranges due to a bug on the
++ * PCIe controller integration, which prohibits any access above the
++ * lower 3GB of memory. Given this, we decided to keep the dma-ranges
++ * in check, avoiding hard to debug device-tree related issues in the
++ * future:
++ *
++ * The PCIe host controller by design must set the inbound viewport to
++ * be a contiguous arrangement of all of the system's memory. In
++ * addition, its size mut be a power of two. To further complicate
++ * matters, the viewport must start on a pcie-address that is aligned
++ * on a multiple of its size. If a portion of the viewport does not
++ * represent system memory -- e.g. 3GB of memory requires a 4GB
++ * viewport -- we can map the outbound memory in or after 3GB and even
++ * though the viewport will overlap the outbound memory the controller
++ * will know to send outbound memory downstream and everything else
++ * upstream.
++ *
++ * For example:
++ *
++ * - The best-case scenario, memory up to 3GB, is to place the inbound
++ * region in the first 4GB of pcie-space, as some legacy devices can
++ * only address 32bits. We would also like to put the MSI under 4GB
++ * as well, since some devices require a 32bit MSI target address.
++ *
++ * - If the system memory is 4GB or larger we cannot start the inbound
++ * region at location 0 (since we have to allow some space for
++ * outbound memory @ 3GB). So instead it will start at the 1x
++ * multiple of its size
++ */
++ if (!*rc_bar2_size || *rc_bar2_offset % *rc_bar2_size ||
++ (*rc_bar2_offset < SZ_4G && *rc_bar2_offset > SZ_2G)) {
++ dev_err(dev, "Invalid rc_bar2_offset/size: size 0x%llx, off 0x%llx\n",
++ *rc_bar2_size, *rc_bar2_offset);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int brcm_pcie_setup(struct brcm_pcie *pcie)
++{
++ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
++ u64 rc_bar2_offset, rc_bar2_size;
++ void __iomem *base = pcie->base;
++ struct device *dev = pcie->dev;
++ struct resource_entry *entry;
++ unsigned int scb_size_val;
++ bool ssc_good = false;
++ struct resource *res;
++ int num_out_wins = 0;
++ u16 nlw, cls, lnksta;
++ int i, ret;
++ u32 tmp;
++
++ /* Reset the bridge */
++ brcm_pcie_bridge_sw_init_set(pcie, 1);
++
++ usleep_range(100, 200);
++
++ /* Take the bridge out of reset */
++ brcm_pcie_bridge_sw_init_set(pcie, 0);
++
++ tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
++ tmp &= ~PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK;
++ writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
++ /* Wait for SerDes to be stable */
++ usleep_range(100, 200);
++
++ /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
++ u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK);
++ u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK);
++ u32p_replace_bits(&tmp, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_128,
++ PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK);
++ writel(tmp, base + PCIE_MISC_MISC_CTRL);
++
++ ret = brcm_pcie_get_rc_bar2_size_and_offset(pcie, &rc_bar2_size,
++ &rc_bar2_offset);
++ if (ret)
++ return ret;
++
++ tmp = lower_32_bits(rc_bar2_offset);
++ u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(rc_bar2_size),
++ PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK);
++ writel(tmp, base + PCIE_MISC_RC_BAR2_CONFIG_LO);
++ writel(upper_32_bits(rc_bar2_offset),
++ base + PCIE_MISC_RC_BAR2_CONFIG_HI);
++
++ scb_size_val = rc_bar2_size ?
++ ilog2(rc_bar2_size) - 15 : 0xf; /* 0xf is 1GB */
++ tmp = readl(base + PCIE_MISC_MISC_CTRL);
++ u32p_replace_bits(&tmp, scb_size_val,
++ PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK);
++ writel(tmp, base + PCIE_MISC_MISC_CTRL);
++
++ /* disable the PCIe->GISB memory window (RC_BAR1) */
++ tmp = readl(base + PCIE_MISC_RC_BAR1_CONFIG_LO);
++ tmp &= ~PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK;
++ writel(tmp, base + PCIE_MISC_RC_BAR1_CONFIG_LO);
++
++ /* disable the PCIe->SCB memory window (RC_BAR3) */
++ tmp = readl(base + PCIE_MISC_RC_BAR3_CONFIG_LO);
++ tmp &= ~PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK;
++ writel(tmp, base + PCIE_MISC_RC_BAR3_CONFIG_LO);
++
++ /* Mask all interrupts since we are not handling any yet */
++ writel(0xffffffff, pcie->base + PCIE_MSI_INTR2_MASK_SET);
++
++ /* clear any interrupts we find on boot */
++ writel(0xffffffff, pcie->base + PCIE_MSI_INTR2_CLR);
++
++ if (pcie->gen)
++ brcm_pcie_set_gen(pcie, pcie->gen);
++
++ /* Unassert the fundamental reset */
++ brcm_pcie_perst_set(pcie, 0);
++
++ /*
++ * Give the RC/EP time to wake up, before trying to configure RC.
++ * Intermittently check status for link-up, up to a total of 100ms.
++ */
++ for (i = 0; i < 100 && !brcm_pcie_link_up(pcie); i += 5)
++ msleep(5);
++
++ if (!brcm_pcie_link_up(pcie)) {
++ dev_err(dev, "link down\n");
++ return -ENODEV;
++ }
++
++ if (!brcm_pcie_rc_mode(pcie)) {
++ dev_err(dev, "PCIe misconfigured; is in EP mode\n");
++ return -EINVAL;
++ }
++
++ resource_list_for_each_entry(entry, &bridge->windows) {
++ res = entry->res;
++
++ if (resource_type(res) != IORESOURCE_MEM)
++ continue;
++
++ if (num_out_wins >= BRCM_NUM_PCIE_OUT_WINS) {
++ dev_err(pcie->dev, "too many outbound wins\n");
++ return -EINVAL;
++ }
++
++ brcm_pcie_set_outbound_win(pcie, num_out_wins, res->start,
++ res->start - entry->offset,
++ resource_size(res));
++ num_out_wins++;
++ }
++
++ /*
++ * For config space accesses on the RC, show the right class for
++ * a PCIe-PCIe bridge (the default setting is to be EP mode).
++ */
++ tmp = readl(base + PCIE_RC_CFG_PRIV1_ID_VAL3);
++ u32p_replace_bits(&tmp, 0x060400,
++ PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK);
++ writel(tmp, base + PCIE_RC_CFG_PRIV1_ID_VAL3);
++
++ if (pcie->ssc) {
++ ret = brcm_pcie_set_ssc(pcie);
++ if (ret == 0)
++ ssc_good = true;
++ else
++ dev_err(dev, "failed attempt to enter ssc mode\n");
++ }
++
++ lnksta = readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKSTA);
++ cls = FIELD_GET(PCI_EXP_LNKSTA_CLS, lnksta);
++ nlw = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
++ dev_info(dev, "link up, %s x%u %s\n",
++ PCIE_SPEED2STR(cls + PCI_SPEED_133MHz_PCIX_533),
++ nlw, ssc_good ? "(SSC)" : "(!SSC)");
++
++ /* PCIe->SCB endian mode for BAR */
++ tmp = readl(base + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1);
++ u32p_replace_bits(&tmp, PCIE_RC_CFG_VENDOR_SPCIFIC_REG1_LITTLE_ENDIAN,
++ PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK);
++ writel(tmp, base + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1);
++
++ /*
++ * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
++ * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1.
++ */
++ tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
++ tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK;
++ writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
++
++ return 0;
++}
++
++/* L23 is a low-power PCIe link state */
++static void brcm_pcie_enter_l23(struct brcm_pcie *pcie)
++{
++ void __iomem *base = pcie->base;
++ int l23, i;
++ u32 tmp;
++
++ /* Assert request for L23 */
++ tmp = readl(base + PCIE_MISC_PCIE_CTRL);
++ u32p_replace_bits(&tmp, 1, PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK);
++ writel(tmp, base + PCIE_MISC_PCIE_CTRL);
++
++ /* Wait up to 36 msec for L23 */
++ tmp = readl(base + PCIE_MISC_PCIE_STATUS);
++ l23 = FIELD_GET(PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK, tmp);
++ for (i = 0; i < 15 && !l23; i++) {
++ usleep_range(2000, 2400);
++ tmp = readl(base + PCIE_MISC_PCIE_STATUS);
++ l23 = FIELD_GET(PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK,
++ tmp);
++ }
++
++ if (!l23)
++ dev_err(pcie->dev, "failed to enter low-power link state\n");
++}
++
++static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
++{
++ void __iomem *base = pcie->base;
++ int tmp;
++
++ if (brcm_pcie_link_up(pcie))
++ brcm_pcie_enter_l23(pcie);
++ /* Assert fundamental reset */
++ brcm_pcie_perst_set(pcie, 1);
++
++ /* Deassert request for L23 in case it was asserted */
++ tmp = readl(base + PCIE_MISC_PCIE_CTRL);
++ u32p_replace_bits(&tmp, 0, PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK);
++ writel(tmp, base + PCIE_MISC_PCIE_CTRL);
++
++ /* Turn off SerDes */
++ tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
++ u32p_replace_bits(&tmp, 1, PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
++ writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
++
++ /* Shutdown PCIe bridge */
++ brcm_pcie_bridge_sw_init_set(pcie, 1);
++}
++
++static void __brcm_pcie_remove(struct brcm_pcie *pcie)
++{
++ brcm_pcie_turn_off(pcie);
++ clk_disable_unprepare(pcie->clk);
++ clk_put(pcie->clk);
++}
++
++static int brcm_pcie_remove(struct platform_device *pdev)
++{
++ struct brcm_pcie *pcie = platform_get_drvdata(pdev);
++
++ pci_stop_root_bus(pcie->root_bus);
++ pci_remove_root_bus(pcie->root_bus);
++ __brcm_pcie_remove(pcie);
++
++ return 0;
++}
++
++static int brcm_pcie_probe(struct platform_device *pdev)
++{
++ struct device_node *np = pdev->dev.of_node;
++ struct pci_host_bridge *bridge;
++ struct brcm_pcie *pcie;
++ struct pci_bus *child;
++ struct resource *res;
++ int ret;
++
++ bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie));
++ if (!bridge)
++ return -ENOMEM;
++
++ pcie = pci_host_bridge_priv(bridge);
++ pcie->dev = &pdev->dev;
++ pcie->np = np;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ pcie->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(pcie->base))
++ return PTR_ERR(pcie->base);
++
++ pcie->clk = devm_clk_get_optional(&pdev->dev, "sw_pcie");
++ if (IS_ERR(pcie->clk))
++ return PTR_ERR(pcie->clk);
++
++ ret = of_pci_get_max_link_speed(np);
++ pcie->gen = (ret < 0) ? 0 : ret;
++
++ pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc");
++
++ ret = pci_parse_request_of_pci_ranges(pcie->dev, &bridge->windows,
++ &bridge->dma_ranges, NULL);
++ if (ret)
++ return ret;
++
++ ret = clk_prepare_enable(pcie->clk);
++ if (ret) {
++ dev_err(&pdev->dev, "could not enable clock\n");
++ return ret;
++ }
++
++ ret = brcm_pcie_setup(pcie);
++ if (ret)
++ goto fail;
++
++ bridge->dev.parent = &pdev->dev;
++ bridge->busnr = 0;
++ bridge->ops = &brcm_pcie_ops;
++ bridge->sysdata = pcie;
++ bridge->map_irq = of_irq_parse_and_map_pci;
++ bridge->swizzle_irq = pci_common_swizzle;
++
++ ret = pci_scan_root_bus_bridge(bridge);
++ if (ret < 0) {
++ dev_err(pcie->dev, "Scanning root bridge failed\n");
++ goto fail;
++ }
++
++ pci_assign_unassigned_bus_resources(bridge->bus);
++ list_for_each_entry(child, &bridge->bus->children, node)
++ pcie_bus_configure_settings(child);
++ pci_bus_add_devices(bridge->bus);
++ platform_set_drvdata(pdev, pcie);
++ pcie->root_bus = bridge->bus;
++
++ return 0;
++fail:
++ __brcm_pcie_remove(pcie);
++ return ret;
++}
++
++static const struct of_device_id brcm_pcie_match[] = {
++ { .compatible = "brcm,bcm2711-pcie" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, brcm_pcie_match);
++
++static struct platform_driver brcm_pcie_driver = {
++ .probe = brcm_pcie_probe,
++ .remove = brcm_pcie_remove,
++ .driver = {
++ .name = "brcm-pcie",
++ .of_match_table = brcm_pcie_match,
++ },
++};
++module_platform_driver(brcm_pcie_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Broadcom STB PCIe RC driver");
++MODULE_AUTHOR("Broadcom");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0460-PCI-brcmstb-Add-MSI-support.patch b/target/linux/bcm27xx/patches-5.4/950-0460-PCI-brcmstb-Add-MSI-support.patch
new file mode 100644
index 0000000000..a27259bd19
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0460-PCI-brcmstb-Add-MSI-support.patch
@@ -0,0 +1,383 @@
+From 1a90ecdfae1c0cf1b242276f6f0e3d98b5877f14 Mon Sep 17 00:00:00 2001
+From: Jim Quinlan <james.quinlan@broadcom.com>
+Date: Mon, 16 Dec 2019 12:01:10 +0100
+Subject: [PATCH] PCI: brcmstb: Add MSI support
+
+commit 40ca1bf580ef24df30702032ba5e40dfdcaa200b upstream.
+
+This adds MSI support to the Broadcom STB PCIe host controller. The MSI
+controller is physically located within the PCIe block, however, there
+is no reason why the MSI controller could not be moved elsewhere in the
+future. MSIX is not supported by the HW.
+
+Since the internal Brcmstb MSI controller is intertwined with the PCIe
+controller, it is not its own platform device but rather part of the
+PCIe platform device.
+
+Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
+Co-developed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Andrew Murray <andrew.murray@arm.com>
+---
+ drivers/pci/controller/Kconfig | 1 +
+ drivers/pci/controller/pcie-brcmstb.c | 262 +++++++++++++++++++++++++-
+ 2 files changed, 262 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/Kconfig
++++ b/drivers/pci/controller/Kconfig
+@@ -285,6 +285,7 @@ config PCIE_BRCMSTB
+ tristate "Broadcom Brcmstb PCIe host controller"
+ depends on ARCH_BCM2835 || COMPILE_TEST
+ depends on OF
++ depends on PCI_MSI_IRQ_DOMAIN
+ help
+ Say Y here to enable PCIe host controller support for
+ Broadcom STB based SoCs, like the Raspberry Pi 4.
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -2,6 +2,7 @@
+ /* Copyright (C) 2009 - 2019 Broadcom */
+
+ #include <linux/bitfield.h>
++#include <linux/bitops.h>
+ #include <linux/clk.h>
+ #include <linux/compiler.h>
+ #include <linux/delay.h>
+@@ -9,11 +10,13 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/ioport.h>
++#include <linux/irqchip/chained_irq.h>
+ #include <linux/irqdomain.h>
+ #include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/log2.h>
+ #include <linux/module.h>
++#include <linux/msi.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_pci.h>
+@@ -67,6 +70,12 @@
+ #define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c
+ #define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f
+
++#define PCIE_MISC_MSI_BAR_CONFIG_LO 0x4044
++#define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048
++
++#define PCIE_MISC_MSI_DATA_CONFIG 0x404c
++#define PCIE_MISC_MSI_DATA_CONFIG_VAL 0xffe06540
++
+ #define PCIE_MISC_PCIE_CTRL 0x4064
+ #define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1
+
+@@ -114,6 +123,11 @@
+
+ /* PCIe parameters */
+ #define BRCM_NUM_PCIE_OUT_WINS 0x4
++#define BRCM_INT_PCI_MSI_NR 32
++
++/* MSI target adresses */
++#define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL
++#define BRCM_MSI_TARGET_ADDR_GT_4GB 0xffffffffcULL
+
+ /* MDIO registers */
+ #define MDIO_PORT0 0x0
+@@ -135,6 +149,19 @@
+ #define SSC_STATUS_SSC_MASK 0x400
+ #define SSC_STATUS_PLL_LOCK_MASK 0x800
+
++struct brcm_msi {
++ struct device *dev;
++ void __iomem *base;
++ struct device_node *np;
++ struct irq_domain *msi_domain;
++ struct irq_domain *inner_domain;
++ struct mutex lock; /* guards the alloc/free operations */
++ u64 target_addr;
++ int irq;
++ /* used indicates which MSI interrupts have been alloc'd */
++ unsigned long used;
++};
++
+ /* Internal PCIe Host Controller Information.*/
+ struct brcm_pcie {
+ struct device *dev;
+@@ -144,6 +171,8 @@ struct brcm_pcie {
+ struct device_node *np;
+ bool ssc;
+ int gen;
++ u64 msi_target_addr;
++ struct brcm_msi *msi;
+ };
+
+ /*
+@@ -309,6 +338,215 @@ static void brcm_pcie_set_outbound_win(s
+ writel(tmp, pcie->base + PCIE_MEM_WIN0_LIMIT_HI(win));
+ }
+
++static struct irq_chip brcm_msi_irq_chip = {
++ .name = "BRCM STB PCIe MSI",
++ .irq_ack = irq_chip_ack_parent,
++ .irq_mask = pci_msi_mask_irq,
++ .irq_unmask = pci_msi_unmask_irq,
++};
++
++static struct msi_domain_info brcm_msi_domain_info = {
++ /* Multi MSI is supported by the controller, but not by this driver */
++ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
++ .chip = &brcm_msi_irq_chip,
++};
++
++static void brcm_pcie_msi_isr(struct irq_desc *desc)
++{
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ unsigned long status, virq;
++ struct brcm_msi *msi;
++ struct device *dev;
++ u32 bit;
++
++ chained_irq_enter(chip, desc);
++ msi = irq_desc_get_handler_data(desc);
++ dev = msi->dev;
++
++ status = readl(msi->base + PCIE_MSI_INTR2_STATUS);
++ for_each_set_bit(bit, &status, BRCM_INT_PCI_MSI_NR) {
++ virq = irq_find_mapping(msi->inner_domain, bit);
++ if (virq)
++ generic_handle_irq(virq);
++ else
++ dev_dbg(dev, "unexpected MSI\n");
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void brcm_msi_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
++{
++ struct brcm_msi *msi = irq_data_get_irq_chip_data(data);
++
++ msg->address_lo = lower_32_bits(msi->target_addr);
++ msg->address_hi = upper_32_bits(msi->target_addr);
++ msg->data = (0xffff & PCIE_MISC_MSI_DATA_CONFIG_VAL) | data->hwirq;
++}
++
++static int brcm_msi_set_affinity(struct irq_data *irq_data,
++ const struct cpumask *mask, bool force)
++{
++ return -EINVAL;
++}
++
++static void brcm_msi_ack_irq(struct irq_data *data)
++{
++ struct brcm_msi *msi = irq_data_get_irq_chip_data(data);
++
++ writel(1 << data->hwirq, msi->base + PCIE_MSI_INTR2_CLR);
++}
++
++
++static struct irq_chip brcm_msi_bottom_irq_chip = {
++ .name = "BRCM STB MSI",
++ .irq_compose_msi_msg = brcm_msi_compose_msi_msg,
++ .irq_set_affinity = brcm_msi_set_affinity,
++ .irq_ack = brcm_msi_ack_irq,
++};
++
++static int brcm_msi_alloc(struct brcm_msi *msi)
++{
++ int hwirq;
++
++ mutex_lock(&msi->lock);
++ hwirq = bitmap_find_free_region(&msi->used, BRCM_INT_PCI_MSI_NR, 0);
++ mutex_unlock(&msi->lock);
++
++ return hwirq;
++}
++
++static void brcm_msi_free(struct brcm_msi *msi, unsigned long hwirq)
++{
++ mutex_lock(&msi->lock);
++ bitmap_release_region(&msi->used, hwirq, 0);
++ mutex_unlock(&msi->lock);
++}
++
++static int brcm_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
++ unsigned int nr_irqs, void *args)
++{
++ struct brcm_msi *msi = domain->host_data;
++ int hwirq;
++
++ hwirq = brcm_msi_alloc(msi);
++
++ if (hwirq < 0)
++ return hwirq;
++
++ irq_domain_set_info(domain, virq, (irq_hw_number_t)hwirq,
++ &brcm_msi_bottom_irq_chip, domain->host_data,
++ handle_edge_irq, NULL, NULL);
++ return 0;
++}
++
++static void brcm_irq_domain_free(struct irq_domain *domain,
++ unsigned int virq, unsigned int nr_irqs)
++{
++ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
++ struct brcm_msi *msi = irq_data_get_irq_chip_data(d);
++
++ brcm_msi_free(msi, d->hwirq);
++}
++
++static const struct irq_domain_ops msi_domain_ops = {
++ .alloc = brcm_irq_domain_alloc,
++ .free = brcm_irq_domain_free,
++};
++
++static int brcm_allocate_domains(struct brcm_msi *msi)
++{
++ struct fwnode_handle *fwnode = of_node_to_fwnode(msi->np);
++ struct device *dev = msi->dev;
++
++ msi->inner_domain = irq_domain_add_linear(NULL, BRCM_INT_PCI_MSI_NR,
++ &msi_domain_ops, msi);
++ if (!msi->inner_domain) {
++ dev_err(dev, "failed to create IRQ domain\n");
++ return -ENOMEM;
++ }
++
++ msi->msi_domain = pci_msi_create_irq_domain(fwnode,
++ &brcm_msi_domain_info,
++ msi->inner_domain);
++ if (!msi->msi_domain) {
++ dev_err(dev, "failed to create MSI domain\n");
++ irq_domain_remove(msi->inner_domain);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static void brcm_free_domains(struct brcm_msi *msi)
++{
++ irq_domain_remove(msi->msi_domain);
++ irq_domain_remove(msi->inner_domain);
++}
++
++static void brcm_msi_remove(struct brcm_pcie *pcie)
++{
++ struct brcm_msi *msi = pcie->msi;
++
++ if (!msi)
++ return;
++ irq_set_chained_handler(msi->irq, NULL);
++ irq_set_handler_data(msi->irq, NULL);
++ brcm_free_domains(msi);
++}
++
++static void brcm_msi_set_regs(struct brcm_msi *msi)
++{
++ writel(0xffffffff, msi->base + PCIE_MSI_INTR2_MASK_CLR);
++
++ /*
++ * The 0 bit of PCIE_MISC_MSI_BAR_CONFIG_LO is repurposed to MSI
++ * enable, which we set to 1.
++ */
++ writel(lower_32_bits(msi->target_addr) | 0x1,
++ msi->base + PCIE_MISC_MSI_BAR_CONFIG_LO);
++ writel(upper_32_bits(msi->target_addr),
++ msi->base + PCIE_MISC_MSI_BAR_CONFIG_HI);
++
++ writel(PCIE_MISC_MSI_DATA_CONFIG_VAL,
++ msi->base + PCIE_MISC_MSI_DATA_CONFIG);
++}
++
++static int brcm_pcie_enable_msi(struct brcm_pcie *pcie)
++{
++ struct brcm_msi *msi;
++ int irq, ret;
++ struct device *dev = pcie->dev;
++
++ irq = irq_of_parse_and_map(dev->of_node, 1);
++ if (irq <= 0) {
++ dev_err(dev, "cannot map MSI interrupt\n");
++ return -ENODEV;
++ }
++
++ msi = devm_kzalloc(dev, sizeof(struct brcm_msi), GFP_KERNEL);
++ if (!msi)
++ return -ENOMEM;
++
++ mutex_init(&msi->lock);
++ msi->dev = dev;
++ msi->base = pcie->base;
++ msi->np = pcie->np;
++ msi->target_addr = pcie->msi_target_addr;
++ msi->irq = irq;
++
++ ret = brcm_allocate_domains(msi);
++ if (ret)
++ return ret;
++
++ irq_set_chained_handler_and_data(msi->irq, brcm_pcie_msi_isr, msi);
++
++ brcm_msi_set_regs(msi);
++ pcie->msi = msi;
++
++ return 0;
++}
++
+ /* The controller is capable of serving in both RC and EP roles */
+ static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie)
+ {
+@@ -497,6 +735,18 @@ static int brcm_pcie_setup(struct brcm_p
+ PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK);
+ writel(tmp, base + PCIE_MISC_MISC_CTRL);
+
++ /*
++ * We ideally want the MSI target address to be located in the 32bit
++ * addressable memory area. Some devices might depend on it. This is
++ * possible either when the inbound window is located above the lower
++ * 4GB or when the inbound area is smaller than 4GB (taking into
++ * account the rounding-up we're forced to perform).
++ */
++ if (rc_bar2_offset >= SZ_4G || (rc_bar2_size + rc_bar2_offset) < SZ_4G)
++ pcie->msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB;
++ else
++ pcie->msi_target_addr = BRCM_MSI_TARGET_ADDR_GT_4GB;
++
+ /* disable the PCIe->GISB memory window (RC_BAR1) */
+ tmp = readl(base + PCIE_MISC_RC_BAR1_CONFIG_LO);
+ tmp &= ~PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK;
+@@ -646,6 +896,7 @@ static void brcm_pcie_turn_off(struct br
+
+ static void __brcm_pcie_remove(struct brcm_pcie *pcie)
+ {
++ brcm_msi_remove(pcie);
+ brcm_pcie_turn_off(pcie);
+ clk_disable_unprepare(pcie->clk);
+ clk_put(pcie->clk);
+@@ -664,7 +915,7 @@ static int brcm_pcie_remove(struct platf
+
+ static int brcm_pcie_probe(struct platform_device *pdev)
+ {
+- struct device_node *np = pdev->dev.of_node;
++ struct device_node *np = pdev->dev.of_node, *msi_np;
+ struct pci_host_bridge *bridge;
+ struct brcm_pcie *pcie;
+ struct pci_bus *child;
+@@ -708,6 +959,15 @@ static int brcm_pcie_probe(struct platfo
+ if (ret)
+ goto fail;
+
++ msi_np = of_parse_phandle(pcie->np, "msi-parent", 0);
++ if (pci_msi_enabled() && msi_np == pcie->np) {
++ ret = brcm_pcie_enable_msi(pcie);
++ if (ret) {
++ dev_err(pcie->dev, "probe of internal MSI failed");
++ goto fail;
++ }
++ }
++
+ bridge->dev.parent = &pdev->dev;
+ bridge->busnr = 0;
+ bridge->ops = &brcm_pcie_ops;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0461-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch b/target/linux/bcm27xx/patches-5.4/950-0461-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch
new file mode 100644
index 0000000000..6bb45ccb1f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0461-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch
@@ -0,0 +1,38 @@
+From 39192141aa16809323c24d8910e3a63488f7f55d Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 27 Feb 2020 12:51:46 +0100
+Subject: [PATCH] PCI: brcmstb: Fix build on 32bit ARM platforms with
+ older compilers
+
+commit 73a7a271b3eee7b83f29b13866163776f1cbef89 upstream.
+
+Some older compilers have no implementation for the helper for 64-bit
+unsigned division/modulo, so linking pcie-brcmstb driver causes the
+"undefined reference to `__aeabi_uldivmod'" error.
+
+*rc_bar2_size is always a power of two, because it is calculated as:
+"1ULL << fls64(entry->res->end - entry->res->start)", so the modulo
+operation in the subsequent check can be replaced by a simple logical
+AND with a proper mask.
+
+Link: https://lore.kernel.org/r/20200227115146.24515-1-m.szyprowski@samsung.com
+Fixes: c0452137034b ("PCI: brcmstb: Add Broadcom STB PCIe host controller driver")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+---
+ drivers/pci/controller/pcie-brcmstb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -670,7 +670,7 @@ static inline int brcm_pcie_get_rc_bar2_
+ * outbound memory @ 3GB). So instead it will start at the 1x
+ * multiple of its size
+ */
+- if (!*rc_bar2_size || *rc_bar2_offset % *rc_bar2_size ||
++ if (!*rc_bar2_size || (*rc_bar2_offset & (*rc_bar2_size - 1)) ||
+ (*rc_bar2_offset < SZ_4G && *rc_bar2_offset > SZ_2G)) {
+ dev_err(dev, "Invalid rc_bar2_offset/size: size 0x%llx, off 0x%llx\n",
+ *rc_bar2_size, *rc_bar2_offset);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0462-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch b/target/linux/bcm27xx/patches-5.4/950-0462-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch
new file mode 100644
index 0000000000..729d6e68ba
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0462-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch
@@ -0,0 +1,75 @@
+From 5e9b9f246802f492e7740ab2589aa8c81df5ef20 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 2 Mar 2020 15:05:25 +0000
+Subject: [PATCH] bcm2711-rpi.dtsi: Use upstream pcie node
+
+Now that the upstream bcm2711 DT has a pcie DT node there's no need to
+define one downstream.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 2 +-
+ arch/arm/boot/dts/bcm2711-rpi.dtsi | 41 ---------------------------
+ 2 files changed, 1 insertion(+), 42 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+@@ -163,7 +163,7 @@
+ i2c6 = &i2c6;
+ /delete-property/ ethernet;
+ /delete-property/ intc;
+- pcie0 = &pcie_0;
++ pcie0 = &pcie0;
+ };
+
+ /delete-node/ wifi-pwrseq;
+--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
+@@ -66,47 +66,6 @@
+ <0x0 0x00000000 0x0 0x00000000 0xfc000000>;
+ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0xfc000000>;
+
+- pcie_0: pcie@7d500000 {
+- reg = <0x0 0x7d500000 0x9310>,
+- <0x0 0x7e00f300 0x20>;
+- msi-controller;
+- msi-parent = <&pcie_0>;
+- #address-cells = <3>;
+- #interrupt-cells = <1>;
+- #size-cells = <2>;
+- bus-range = <0x0 0x01>;
+- compatible = "brcm,bcm2711b0-pcie", // Safe value
+- "brcm,bcm2711-pcie",
+- "brcm,pci-plat-dev";
+- max-link-speed = <2>;
+- tot-num-pcie = <1>;
+- linux,pci-domain = <0>;
+- interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "pcie", "msi";
+- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+- interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143
+- IRQ_TYPE_LEVEL_HIGH
+- 0 0 0 2 &gicv2 GIC_SPI 144
+- IRQ_TYPE_LEVEL_HIGH
+- 0 0 0 3 &gicv2 GIC_SPI 145
+- IRQ_TYPE_LEVEL_HIGH
+- 0 0 0 4 &gicv2 GIC_SPI 146
+- IRQ_TYPE_LEVEL_HIGH>;
+-
+- /* Map outbound accesses from scb:0x6_00000000-03ffffff
+- * to pci:0x0_f8000000-fbffffff
+- */
+- ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000
+- 0x0 0x04000000>;
+- /* Map inbound accesses from pci:0x0_00000000..ffffffff
+- * to scb:0x0_00000000-ffffffff
+- */
+- dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000
+- 0x1 0x00000000>;
+- status = "okay";
+- };
+-
+ dma40: dma@7e007b00 {
+ compatible = "brcm,bcm2711-dma";
+ reg = <0x0 0x7e007b00 0x400>;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0463-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch b/target/linux/bcm27xx/patches-5.4/950-0463-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch
new file mode 100644
index 0000000000..16eaeddb29
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0463-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch
@@ -0,0 +1,156 @@
+From a3ceeebaaa66e6786490e850b5019808da3785c0 Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andrey.konovalov@linaro.org>
+Date: Mon, 20 Jan 2020 05:15:57 -0300
+Subject: [PATCH] media: dt-bindings: media: i2c: Add IMX219 CMOS
+ sensor binding
+
+Commit 9d730f2cf4c0391785855dd231577d2de2594df9 upstream.
+(Currently on linux-media/master, queued for 5.7)
+
+Add YAML device tree binding for IMX219 CMOS image sensor, and
+the relevant MAINTAINERS entries.
+
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+---
+ .../devicetree/bindings/media/i2c/imx219.yaml | 114 ++++++++++++++++++
+ MAINTAINERS | 8 ++
+ 2 files changed, 122 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/i2c/imx219.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/i2c/imx219.yaml
+@@ -0,0 +1,114 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/media/i2c/imx219.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Sony 1/4.0-Inch 8Mpixel CMOS Digital Image Sensor
++
++maintainers:
++ - Dave Stevenson <dave.stevenson@raspberrypi.com>
++
++description: |-
++ The Sony imx219 is a 1/4.0-inch CMOS active pixel digital image sensor
++ with an active array size of 3280H x 2464V. It is programmable through
++ I2C interface. The I2C address is fixed to 0x10 as per sensor data sheet.
++ Image data is sent through MIPI CSI-2, which is configured as either 2 or
++ 4 data lanes.
++
++properties:
++ compatible:
++ const: sony,imx219
++
++ reg:
++ description: I2C device address
++ maxItems: 1
++
++ clocks:
++ maxItems: 1
++
++ VDIG-supply:
++ description:
++ Digital I/O voltage supply, 1.8 volts
++
++ VANA-supply:
++ description:
++ Analog voltage supply, 2.8 volts
++
++ VDDL-supply:
++ description:
++ Digital core voltage supply, 1.2 volts
++
++ reset-gpios:
++ description: |-
++ Reference to the GPIO connected to the xclr pin, if any.
++ Must be released (set high) after all supplies are applied.
++
++ # See ../video-interfaces.txt for more details
++ port:
++ type: object
++ properties:
++ endpoint:
++ type: object
++ properties:
++ data-lanes:
++ description: |-
++ The sensor supports either two-lane, or four-lane operation.
++ If this property is omitted four-lane operation is assumed.
++ For two-lane operation the property must be set to <1 2>.
++ items:
++ - const: 1
++ - const: 2
++
++ clock-noncontinuous:
++ type: boolean
++ description: |-
++ MIPI CSI-2 clock is non-continuous if this property is present,
++ otherwise it's continuous.
++
++ link-frequencies:
++ allOf:
++ - $ref: /schemas/types.yaml#/definitions/uint64-array
++ description:
++ Allowed data bus frequencies.
++
++ required:
++ - link-frequencies
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - VANA-supply
++ - VDIG-supply
++ - VDDL-supply
++ - port
++
++additionalProperties: false
++
++examples:
++ - |
++ i2c0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ imx219: sensor@10 {
++ compatible = "sony,imx219";
++ reg = <0x10>;
++ clocks = <&imx219_clk>;
++ VANA-supply = <&imx219_vana>; /* 2.8v */
++ VDIG-supply = <&imx219_vdig>; /* 1.8v */
++ VDDL-supply = <&imx219_vddl>; /* 1.2v */
++
++ port {
++ imx219_0: endpoint {
++ remote-endpoint = <&csi1_ep>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
++ link-frequencies = /bits/ 64 <456000000>;
++ };
++ };
++ };
++ };
++
++...
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -15142,6 +15142,14 @@ S: Maintained
+ F: drivers/media/i2c/imx214.c
+ F: Documentation/devicetree/bindings/media/i2c/sony,imx214.txt
+
++SONY IMX219 SENSOR DRIVER
++M: Dave Stevenson <dave.stevenson@raspberrypi.com>
++L: linux-media@vger.kernel.org
++T: git git://linuxtv.org/media_tree.git
++S: Maintained
++F: drivers/media/i2c/imx219.c
++F: Documentation/devicetree/bindings/media/i2c/imx219.yaml
++
+ SONY IMX258 SENSOR DRIVER
+ M: Sakari Ailus <sakari.ailus@linux.intel.com>
+ L: linux-media@vger.kernel.org
diff --git a/target/linux/bcm27xx/patches-5.4/950-0312-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch b/target/linux/bcm27xx/patches-5.4/950-0464-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch
index 0880d419c7..4ca345f2ad 100644
--- a/target/linux/bcm27xx/patches-5.4/950-0312-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch
+++ b/target/linux/bcm27xx/patches-5.4/950-0464-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch
@@ -1,21 +1,28 @@
-From 8436bbdd722445870c514d889eb082155f88dde1 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson <dave.stevenson@raspberrypi.org>
-Date: Wed, 28 Aug 2019 13:34:49 +0100
+From 5cd8c4efeb46ce1ef370dd3012a7951ba430b58f Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Mon, 20 Jan 2020 05:15:58 -0300
Subject: [PATCH] media: i2c: Add driver for Sony IMX219 sensor
+Commit 1283b3b8f82b9004fbb94398cade5c8e797a2c8d upstream.
+(Currently on linux-media/master, queued for 5.7)
+
Adds a driver for the 8MPix Sony IMX219 CSI2 sensor.
Whilst the sensor supports 2 or 4 CSI2 data lanes, this driver
currently only supports 2 lanes.
8MPix @ 15fps, 1080P @ 30fps (cropped FOV), and 1640x1232 (2x2 binned)
@ 30fps are currently supported.
-Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
-Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+[Sakari Ailus: make imx219_check_hwcfg static]
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
drivers/media/i2c/Kconfig | 11 +
drivers/media/i2c/Makefile | 1 +
- drivers/media/i2c/imx219.c | 1093 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 1105 insertions(+)
+ drivers/media/i2c/imx219.c | 1312 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 1324 insertions(+)
create mode 100644 drivers/media/i2c/imx219.c
--- a/drivers/media/i2c/Kconfig
@@ -27,7 +34,7 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+config VIDEO_IMX219
+ tristate "Sony IMX219 sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
-+ depends on MEDIA_CAMERA_SUPPORT
++ select V4L2_FWNODE
+ help
+ This is a Video4Linux2 sensor driver for the Sony
+ IMX219 camera.
@@ -40,7 +47,7 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
-@@ -110,6 +110,7 @@ obj-$(CONFIG_VIDEO_ML86V7667) += ml86v76
+@@ -111,6 +111,7 @@ obj-$(CONFIG_VIDEO_ML86V7667) += ml86v76
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
obj-$(CONFIG_VIDEO_IMX214) += imx214.o
@@ -50,7 +57,7 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
obj-$(CONFIG_VIDEO_IMX319) += imx319.o
--- /dev/null
+++ b/drivers/media/i2c/imx219.c
-@@ -0,0 +1,1093 @@
+@@ -0,0 +1,1312 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * A V4L2 driver for Sony IMX219 cameras.
@@ -59,9 +66,11 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ * Based on Sony imx258 camera driver
+ * Copyright (C) 2018 Intel Corporation
+ *
-+ * DT / fwnode changes, and regulator / GPIO control taken from ov5640.c
-+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
-+ * Copyright (C) 2014-2017 Mentor Graphics Inc.
++ * DT / fwnode changes, and regulator / GPIO control taken from imx214 driver
++ * Copyright 2018 Qtechnology A/S
++ *
++ * Flip handling taken from the Sony IMX319 driver.
++ * Copyright (C) 2018 Intel Corporation
+ *
+ */
+
@@ -76,6 +85,7 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mediabus.h>
+#include <asm/unaligned.h>
@@ -91,6 +101,14 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+#define IMX219_REG_CHIP_ID 0x0000
+#define IMX219_CHIP_ID 0x0219
+
++/* External clock frequency is 24.0M */
++#define IMX219_XCLK_FREQ 24000000
++
++/* Pixel rate is fixed at 182.4M for all the modes */
++#define IMX219_PIXEL_RATE 182400000
++
++#define IMX219_DEFAULT_LINK_FREQ 456000000
++
+/* V_TIMING internal */
+#define IMX219_REG_VTS 0x0160
+#define IMX219_VTS_15FPS 0x0dc6
@@ -98,6 +116,8 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+#define IMX219_VTS_30FPS_BINNED 0x06e3
+#define IMX219_VTS_MAX 0xffff
+
++#define IMX219_VBLANK_MIN 4
++
+/*Frame Length Line*/
+#define IMX219_FLL_MIN 0x08a6
+#define IMX219_FLL_MAX 0xffff
@@ -105,7 +125,7 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+#define IMX219_FLL_DEFAULT 0x0c98
+
+/* HBLANK control - read only */
-+#define IMX219_PPL_DEFAULT 5352
++#define IMX219_PPL_DEFAULT 3448
+
+/* Exposure control */
+#define IMX219_REG_EXPOSURE 0x015a
@@ -128,6 +148,8 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+#define IMX219_DGTL_GAIN_DEFAULT 0x0100
+#define IMX219_DGTL_GAIN_STEP 1
+
++#define IMX219_REG_ORIENTATION 0x0172
++
+/* Test Pattern Control */
+#define IMX219_REG_TEST_PATTERN 0x0600
+#define IMX219_TEST_PATTERN_DISABLE 0
@@ -136,25 +158,38 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+#define IMX219_TEST_PATTERN_GREY_COLOR 3
+#define IMX219_TEST_PATTERN_PN9 4
+
++/* Test pattern colour components */
++#define IMX219_REG_TESTP_RED 0x0602
++#define IMX219_REG_TESTP_GREENR 0x0604
++#define IMX219_REG_TESTP_BLUE 0x0606
++#define IMX219_REG_TESTP_GREENB 0x0608
++#define IMX219_TESTP_COLOUR_MIN 0
++#define IMX219_TESTP_COLOUR_MAX 0x03ff
++#define IMX219_TESTP_COLOUR_STEP 1
++#define IMX219_TESTP_RED_DEFAULT IMX219_TESTP_COLOUR_MAX
++#define IMX219_TESTP_GREENR_DEFAULT 0
++#define IMX219_TESTP_BLUE_DEFAULT 0
++#define IMX219_TESTP_GREENB_DEFAULT 0
++
+struct imx219_reg {
+ u16 address;
+ u8 val;
+};
+
+struct imx219_reg_list {
-+ u32 num_of_regs;
++ unsigned int num_of_regs;
+ const struct imx219_reg *regs;
+};
+
+/* Mode : resolution and related config&values */
+struct imx219_mode {
+ /* Frame width */
-+ u32 width;
++ unsigned int width;
+ /* Frame height */
-+ u32 height;
++ unsigned int height;
+
+ /* V-timing */
-+ u32 vts_def;
++ unsigned int vts_def;
+
+ /* Default register values */
+ struct imx219_reg_list reg_list;
@@ -221,8 +256,6 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ {0x4793, 0x10},
+ {0x4797, 0x0e},
+ {0x479b, 0x0e},
-+
-+ {0x0172, 0x03},
+ {0x0162, 0x0d},
+ {0x0163, 0x78},
+};
@@ -269,6 +302,10 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ {0x030b, 0x01},
+ {0x030c, 0x00},
+ {0x030d, 0x72},
++ {0x0624, 0x07},
++ {0x0625, 0x80},
++ {0x0626, 0x04},
++ {0x0627, 0x38},
+ {0x455e, 0x00},
+ {0x471e, 0x4b},
+ {0x4767, 0x0f},
@@ -281,13 +318,12 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ {0x4793, 0x10},
+ {0x4797, 0x0e},
+ {0x479b, 0x0e},
-+
-+ {0x0172, 0x03},
+ {0x0162, 0x0d},
+ {0x0163, 0x78},
+};
+
+static const struct imx219_reg mode_1640_1232_regs[] = {
++ {0x0100, 0x00},
+ {0x30eb, 0x0c},
+ {0x30eb, 0x05},
+ {0x300a, 0xff},
@@ -326,6 +362,10 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ {0x030b, 0x01},
+ {0x030c, 0x00},
+ {0x030d, 0x72},
++ {0x0624, 0x06},
++ {0x0625, 0x68},
++ {0x0626, 0x04},
++ {0x0627, 0xd0},
+ {0x455e, 0x00},
+ {0x471e, 0x4b},
+ {0x4767, 0x0f},
@@ -338,8 +378,6 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ {0x4793, 0x10},
+ {0x4797, 0x0e},
+ {0x479b, 0x0e},
-+
-+ {0x0172, 0x03},
+ {0x0162, 0x0d},
+ {0x0163, 0x78},
+};
@@ -370,7 +408,32 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+
+#define IMX219_NUM_SUPPLIES ARRAY_SIZE(imx219_supply_name)
+
-+#define IMX219_XCLR_DELAY_MS 10 /* Initialisation delay after XCLR low->high */
++/*
++ * Initialisation delay between XCLR low->high and the moment when the sensor
++ * can start capture (i.e. can leave software stanby) must be not less than:
++ * t4 + max(t5, t6 + <time to initialize the sensor register over I2C>)
++ * where
++ * t4 is fixed, and is max 200uS,
++ * t5 is fixed, and is 6000uS,
++ * t6 depends on the sensor external clock, and is max 32000 clock periods.
++ * As per sensor datasheet, the external clock must be from 6MHz to 27MHz.
++ * So for any acceptable external clock t6 is always within the range of
++ * 1185 to 5333 uS, and is always less than t5.
++ * For this reason this is always safe to wait (t4 + t5) = 6200 uS, then
++ * initialize the sensor over I2C, and then exit the software standby.
++ *
++ * This start-up time can be optimized a bit more, if we start the writes
++ * over I2C after (t4+t6), but before (t4+t5) expires. But then sensor
++ * initialization over I2C may complete before (t4+t5) expires, and we must
++ * ensure that capture is not started before (t4+t5).
++ *
++ * This delay doesn't account for the power supply startup time. If needed,
++ * this should be taken care of via the regulator framework. E.g. in the
++ * case of DT for regulator-fixed one should define the startup-delay-us
++ * property.
++ */
++#define IMX219_XCLR_MIN_DELAY_US 6200
++#define IMX219_XCLR_DELAY_RANGE_US 1000
+
+/* Mode configs */
+static const struct imx219_mode supported_modes[] = {
@@ -410,17 +473,20 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+
-+ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
+ struct clk *xclk; /* system clock to IMX219 */
+ u32 xclk_freq;
+
-+ struct gpio_desc *xclr_gpio;
++ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[IMX219_NUM_SUPPLIES];
+
+ struct v4l2_ctrl_handler ctrl_handler;
+ /* V4L2 Controls */
+ struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *exposure;
++ struct v4l2_ctrl *vflip;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vblank;
++ struct v4l2_ctrl *hblank;
+
+ /* Current mode */
+ const struct imx219_mode *mode;
@@ -431,7 +497,6 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ */
+ struct mutex mutex;
+
-+ int power_count;
+ /* Streaming on/off */
+ bool streaming;
+};
@@ -513,101 +578,38 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ return 0;
+}
+
-+/* Power/clock management functions */
-+static void imx219_power(struct imx219 *imx219, bool enable)
-+{
-+ gpiod_set_value_cansleep(imx219->xclr_gpio, enable ? 1 : 0);
-+}
-+
-+static int imx219_set_power_on(struct imx219 *imx219)
-+{
-+ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-+ int ret;
-+
-+ ret = clk_prepare_enable(imx219->xclk);
-+ if (ret) {
-+ dev_err(&client->dev, "%s: failed to enable clock\n",
-+ __func__);
-+ return ret;
-+ }
-+
-+ ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
-+ imx219->supplies);
-+ if (ret) {
-+ dev_err(&client->dev, "%s: failed to enable regulators\n",
-+ __func__);
-+ goto xclk_off;
-+ }
-+
-+ imx219_power(imx219, true);
-+ msleep(IMX219_XCLR_DELAY_MS);
-+
-+ return 0;
-+xclk_off:
-+ clk_disable_unprepare(imx219->xclk);
-+ return ret;
-+}
-+
-+static void imx219_set_power_off(struct imx219 *imx219)
-+{
-+ imx219_power(imx219, false);
-+ regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
-+ clk_disable_unprepare(imx219->xclk);
-+}
-+
-+static int imx219_set_power(struct imx219 *imx219, bool on)
-+{
-+ int ret = 0;
-+
-+ if (on) {
-+ ret = imx219_set_power_on(imx219);
-+ if (ret)
-+ return ret;
-+ } else {
-+ imx219_set_power_off(imx219);
-+ }
-+
-+ return 0;
-+}
-+
-+/* Open sub-device */
-+static int imx219_s_power(struct v4l2_subdev *sd, int on)
++/* Get bayer order based on flip setting. */
++static u32 imx219_get_format_code(struct imx219 *imx219)
+{
-+ struct imx219 *imx219 = to_imx219(sd);
-+ int ret = 0;
-+
-+ mutex_lock(&imx219->mutex);
-+
+ /*
-+ * If the power count is modified from 0 to != 0 or from != 0 to 0,
-+ * update the power state.
++ * Only one bayer order is supported.
++ * It depends on the flip settings.
+ */
-+ if (imx219->power_count == !on) {
-+ ret = imx219_set_power(imx219, !!on);
-+ if (ret)
-+ goto out;
-+ }
++ static const u32 codes[2][2] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
++ { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
++ };
+
-+ /* Update the power count. */
-+ imx219->power_count += on ? 1 : -1;
-+ WARN_ON(imx219->power_count < 0);
-+out:
-+ mutex_unlock(&imx219->mutex);
-+
-+ return ret;
++ lockdep_assert_held(&imx219->mutex);
++ return codes[imx219->vflip->val][imx219->hflip->val];
+}
+
+static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
++ struct imx219 *imx219 = to_imx219(sd);
+ struct v4l2_mbus_framefmt *try_fmt =
+ v4l2_subdev_get_try_format(sd, fh->pad, 0);
+
++ mutex_lock(&imx219->mutex);
++
+ /* Initialize try_fmt */
+ try_fmt->width = supported_modes[0].width;
+ try_fmt->height = supported_modes[0].height;
-+ try_fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ try_fmt->code = imx219_get_format_code(imx219);
+ try_fmt->field = V4L2_FIELD_NONE;
+
++ mutex_unlock(&imx219->mutex);
++
+ return 0;
+}
+
@@ -616,7 +618,20 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ struct imx219 *imx219 =
+ container_of(ctrl->handler, struct imx219, ctrl_handler);
+ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-+ int ret = 0;
++ int ret;
++
++ if (ctrl->id == V4L2_CID_VBLANK) {
++ int exposure_max, exposure_def;
++
++ /* Update max exposure while meeting expected vblanking */
++ exposure_max = imx219->mode->height + ctrl->val - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
++ __v4l2_ctrl_modify_range(imx219->exposure,
++ imx219->exposure->minimum,
++ exposure_max, imx219->exposure->step,
++ exposure_def);
++ }
+
+ /*
+ * Applying V4L2 control value only happens
@@ -643,6 +658,33 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ IMX219_REG_VALUE_16BIT,
+ imx219_test_pattern_val[ctrl->val]);
+ break;
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1,
++ imx219->hflip->val |
++ imx219->vflip->val << 1);
++ break;
++ case V4L2_CID_VBLANK:
++ ret = imx219_write_reg(imx219, IMX219_REG_VTS,
++ IMX219_REG_VALUE_16BIT,
++ imx219->mode->height + ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_RED:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENR:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_BLUE:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENB:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
+ default:
+ dev_info(&client->dev,
+ "ctrl(id:0x%x,val:0x%x) is not handled\n",
@@ -664,11 +706,16 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
-+ /* Only one bayer order(GRBG) is supported */
++ struct imx219 *imx219 = to_imx219(sd);
++
++ /*
++ * Only one bayer order is supported (though it depends on the flip
++ * settings)
++ */
+ if (code->index > 0)
+ return -EINVAL;
+
-+ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ code->code = imx219_get_format_code(imx219);
+
+ return 0;
+}
@@ -677,10 +724,12 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
++ struct imx219 *imx219 = to_imx219(sd);
++
+ if (fse->index >= ARRAY_SIZE(supported_modes))
+ return -EINVAL;
+
-+ if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
++ if (fse->code != imx219_get_format_code(imx219))
+ return -EINVAL;
+
+ fse->min_width = supported_modes[fse->index].width;
@@ -691,24 +740,41 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ return 0;
+}
+
-+static void imx219_update_pad_format(const struct imx219_mode *mode,
++static void imx219_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
++{
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace,
++ fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++}
++
++static void imx219_update_pad_format(struct imx219 *imx219,
++ const struct imx219_mode *mode,
+ struct v4l2_subdev_format *fmt)
+{
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
-+ fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ fmt->format.code = imx219_get_format_code(imx219);
+ fmt->format.field = V4L2_FIELD_NONE;
++
++ imx219_reset_colorspace(&fmt->format);
+}
+
+static int __imx219_get_pad_format(struct imx219 *imx219,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
-+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
-+ fmt->format = *v4l2_subdev_get_try_format(&imx219->sd, cfg,
-+ fmt->pad);
-+ else
-+ imx219_update_pad_format(imx219->mode, fmt);
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ struct v4l2_mbus_framefmt *try_fmt =
++ v4l2_subdev_get_try_format(&imx219->sd, cfg, fmt->pad);
++ /* update the code which could change due to vflip or hflip: */
++ try_fmt->code = imx219_get_format_code(imx219);
++ fmt->format = *try_fmt;
++ } else {
++ imx219_update_pad_format(imx219, imx219->mode, fmt);
++ }
+
+ return 0;
+}
@@ -734,22 +800,45 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ struct imx219 *imx219 = to_imx219(sd);
+ const struct imx219_mode *mode;
+ struct v4l2_mbus_framefmt *framefmt;
++ int exposure_max, exposure_def, hblank;
+
+ mutex_lock(&imx219->mutex);
+
-+ /* Only one raw bayer(BGGR) order is supported */
-+ fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ /* Bayer order varies with flips */
++ fmt->format.code = imx219_get_format_code(imx219);
+
+ mode = v4l2_find_nearest_size(supported_modes,
+ ARRAY_SIZE(supported_modes),
+ width, height,
+ fmt->format.width, fmt->format.height);
-+ imx219_update_pad_format(mode, fmt);
++ imx219_update_pad_format(imx219, mode, fmt);
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+ framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+ *framefmt = fmt->format;
-+ } else {
++ } else if (imx219->mode != mode) {
+ imx219->mode = mode;
++ /* Update limits and set FPS to default */
++ __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
++ IMX219_VTS_MAX - mode->height, 1,
++ mode->vts_def - mode->height);
++ __v4l2_ctrl_s_ctrl(imx219->vblank,
++ mode->vts_def - mode->height);
++ /* Update max exposure while meeting expected vblanking */
++ exposure_max = mode->vts_def - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
++ __v4l2_ctrl_modify_range(imx219->exposure,
++ imx219->exposure->minimum,
++ exposure_max, imx219->exposure->step,
++ exposure_def);
++ /*
++ * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
++ * depends on mode->width only, and is not changeble in any
++ * way other than changing the mode.
++ */
++ hblank = IMX219_PPL_DEFAULT - mode->width;
++ __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1,
++ hblank);
+ }
+
+ mutex_unlock(&imx219->mutex);
@@ -757,7 +846,6 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ return 0;
+}
+
-+/* Start streaming */
+static int imx219_start_streaming(struct imx219 *imx219)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
@@ -772,15 +860,6 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ return ret;
+ }
+
-+ /*
-+ * Set VTS appropriately for frame rate control.
-+ * Currently fixed per mode.
-+ */
-+ ret = imx219_write_reg(imx219, IMX219_REG_VTS,
-+ IMX219_REG_VALUE_16BIT, imx219->mode->vts_def);
-+ if (ret)
-+ return ret;
-+
+ /* Apply customized values from user */
+ ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
+ if (ret)
@@ -791,8 +870,7 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
+}
+
-+/* Stop streaming */
-+static int imx219_stop_streaming(struct imx219 *imx219)
++static void imx219_stop_streaming(struct imx219 *imx219)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
+ int ret;
@@ -802,12 +880,6 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
+ if (ret)
+ dev_err(&client->dev, "%s failed to set stream\n", __func__);
-+
-+ /*
-+ * Return success even if it was an error, as there is nothing the
-+ * caller can do about it.
-+ */
-+ return 0;
+}
+
+static int imx219_set_stream(struct v4l2_subdev *sd, int enable)
@@ -834,26 +906,79 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ * and then start streaming.
+ */
+ ret = imx219_start_streaming(imx219);
-+ if (ret) {
-+ pm_runtime_put(&client->dev);
-+ goto err_unlock;
-+ }
++ if (ret)
++ goto err_rpm_put;
+ } else {
+ imx219_stop_streaming(imx219);
+ pm_runtime_put(&client->dev);
+ }
+
+ imx219->streaming = enable;
++
++ /* vflip and hflip cannot change during streaming */
++ __v4l2_ctrl_grab(imx219->vflip, enable);
++ __v4l2_ctrl_grab(imx219->hflip, enable);
++
+ mutex_unlock(&imx219->mutex);
+
+ return ret;
+
++err_rpm_put:
++ pm_runtime_put(&client->dev);
+err_unlock:
+ mutex_unlock(&imx219->mutex);
+
+ return ret;
+}
+
++/* Power/clock management functions */
++static int imx219_power_on(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx219 *imx219 = to_imx219(sd);
++ int ret;
++
++ ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
++ imx219->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(imx219->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ goto reg_off;
++ }
++
++ gpiod_set_value_cansleep(imx219->reset_gpio, 1);
++ usleep_range(IMX219_XCLR_MIN_DELAY_US,
++ IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
++
++ return 0;
++
++reg_off:
++ regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
++
++ return ret;
++}
++
++static int imx219_power_off(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx219 *imx219 = to_imx219(sd);
++
++ gpiod_set_value_cansleep(imx219->reset_gpio, 0);
++ regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
++ clk_disable_unprepare(imx219->xclk);
++
++ return 0;
++}
++
+static int __maybe_unused imx219_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
@@ -884,13 +1009,14 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+error:
+ imx219_stop_streaming(imx219);
+ imx219->streaming = 0;
++
+ return ret;
+}
+
+static int imx219_get_regulators(struct imx219 *imx219)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-+ int i;
++ unsigned int i;
+
+ for (i = 0; i < IMX219_NUM_SUPPLIES; i++)
+ imx219->supplies[i].supply = imx219_supply_name[i];
@@ -907,31 +1033,26 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ int ret;
+ u32 val;
+
-+ ret = imx219_set_power_on(imx219);
-+ if (ret)
-+ return ret;
-+
+ ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID,
+ IMX219_REG_VALUE_16BIT, &val);
+ if (ret) {
+ dev_err(&client->dev, "failed to read chip id %x\n",
+ IMX219_CHIP_ID);
-+ goto power_off;
++ return ret;
+ }
+
+ if (val != IMX219_CHIP_ID) {
+ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ IMX219_CHIP_ID, val);
-+ ret = -EIO;
++ return -EIO;
+ }
+
-+power_off:
-+ imx219_set_power_off(imx219);
-+ return ret;
++ return 0;
+}
+
+static const struct v4l2_subdev_core_ops imx219_core_ops = {
-+ .s_power = imx219_s_power,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_video_ops imx219_video_ops = {
@@ -960,22 +1081,44 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
+ struct v4l2_ctrl_handler *ctrl_hdlr;
-+ int ret;
++ unsigned int height = imx219->mode->height;
++ int exposure_max, exposure_def, hblank;
++ int i, ret;
+
+ ctrl_hdlr = &imx219->ctrl_handler;
-+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9);
+ if (ret)
+ return ret;
+
+ mutex_init(&imx219->mutex);
+ ctrl_hdlr->lock = &imx219->mutex;
+
++ /* By default, PIXEL_RATE is read only */
++ imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_PIXEL_RATE,
++ IMX219_PIXEL_RATE,
++ IMX219_PIXEL_RATE, 1,
++ IMX219_PIXEL_RATE);
++
++ /* Initial vblank/hblank/exposure parameters based on current mode */
++ imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
++ IMX219_VTS_MAX - height, 1,
++ imx219->mode->vts_def - height);
++ hblank = IMX219_PPL_DEFAULT - imx219->mode->width;
++ imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_HBLANK, hblank, hblank,
++ 1, hblank);
++ if (imx219->hblank)
++ imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ exposure_max = imx219->mode->vts_def - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
+ imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
+ V4L2_CID_EXPOSURE,
-+ IMX219_EXPOSURE_MIN,
-+ IMX219_EXPOSURE_MAX,
++ IMX219_EXPOSURE_MIN, exposure_max,
+ IMX219_EXPOSURE_STEP,
-+ IMX219_EXPOSURE_DEFAULT);
++ exposure_def);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+ IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX,
@@ -985,10 +1128,35 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX,
+ IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT);
+
++ imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ if (imx219->hflip)
++ imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++
++ imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ if (imx219->vflip)
++ imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(imx219_test_pattern_menu) - 1,
+ 0, 0, imx219_test_pattern_menu);
++ for (i = 0; i < 4; i++) {
++ /*
++ * The assumption is that
++ * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
++ * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2
++ * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
++ */
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_TEST_PATTERN_RED + i,
++ IMX219_TESTP_COLOUR_MIN,
++ IMX219_TESTP_COLOUR_MAX,
++ IMX219_TESTP_COLOUR_STEP,
++ IMX219_TESTP_COLOUR_MAX);
++ /* The "Solid color" pattern is white by default */
++ }
+
+ if (ctrl_hdlr->error) {
+ ret = ctrl_hdlr->error;
@@ -1014,11 +1182,56 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ mutex_destroy(&imx219->mutex);
+}
+
-+static int imx219_probe(struct i2c_client *client,
-+ const struct i2c_device_id *id)
++static int imx219_check_hwcfg(struct device *dev)
+{
-+ struct device *dev = &client->dev;
+ struct fwnode_handle *endpoint;
++ struct v4l2_fwnode_endpoint ep_cfg = {
++ .bus_type = V4L2_MBUS_CSI2_DPHY
++ };
++ int ret = -EINVAL;
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) {
++ dev_err(dev, "could not parse endpoint\n");
++ goto error_out;
++ }
++
++ /* Check the number of MIPI CSI2 data lanes */
++ if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2) {
++ dev_err(dev, "only 2 data lanes are currently supported\n");
++ goto error_out;
++ }
++
++ /* Check the link frequency set in device tree */
++ if (!ep_cfg.nr_of_link_frequencies) {
++ dev_err(dev, "link-frequency property not found in DT\n");
++ goto error_out;
++ }
++
++ if (ep_cfg.nr_of_link_frequencies != 1 ||
++ ep_cfg.link_frequencies[0] != IMX219_DEFAULT_LINK_FREQ) {
++ dev_err(dev, "Link frequency not supported: %lld\n",
++ ep_cfg.link_frequencies[0]);
++ goto error_out;
++ }
++
++ ret = 0;
++
++error_out:
++ v4l2_fwnode_endpoint_free(&ep_cfg);
++ fwnode_handle_put(endpoint);
++
++ return ret;
++}
++
++static int imx219_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
+ struct imx219 *imx219;
+ int ret;
+
@@ -1026,57 +1239,54 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ if (!imx219)
+ return -ENOMEM;
+
-+ /* Initialize subdev */
+ v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
+
-+ /* Get CSI2 bus config */
-+ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
-+ NULL);
-+ if (!endpoint) {
-+ dev_err(dev, "endpoint node not found\n");
++ /* Check the hardware configuration in device tree */
++ if (imx219_check_hwcfg(dev))
+ return -EINVAL;
-+ }
-+
-+ ret = v4l2_fwnode_endpoint_parse(endpoint, &imx219->ep);
-+ fwnode_handle_put(endpoint);
-+ if (ret) {
-+ dev_err(dev, "Could not parse endpoint\n");
-+ return ret;
-+ }
+
+ /* Get system clock (xclk) */
-+ imx219->xclk = devm_clk_get(dev, "xclk");
++ imx219->xclk = devm_clk_get(dev, NULL);
+ if (IS_ERR(imx219->xclk)) {
+ dev_err(dev, "failed to get xclk\n");
+ return PTR_ERR(imx219->xclk);
+ }
+
+ imx219->xclk_freq = clk_get_rate(imx219->xclk);
-+ if (imx219->xclk_freq != 24000000) {
++ if (imx219->xclk_freq != IMX219_XCLK_FREQ) {
+ dev_err(dev, "xclk frequency not supported: %d Hz\n",
+ imx219->xclk_freq);
+ return -EINVAL;
+ }
+
+ ret = imx219_get_regulators(imx219);
-+ if (ret)
++ if (ret) {
++ dev_err(dev, "failed to get regulators\n");
+ return ret;
++ }
+
-+ /* request optional power down pin */
-+ imx219->xclr_gpio = devm_gpiod_get_optional(dev, "xclr",
-+ GPIOD_OUT_HIGH);
++ /* Request optional enable pin */
++ imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
+
-+ /* Check module identity */
-+ ret = imx219_identify_module(imx219);
++ /*
++ * The sensor must be powered for imx219_identify_module()
++ * to be able to read the CHIP_ID register
++ */
++ ret = imx219_power_on(dev);
+ if (ret)
+ return ret;
+
++ ret = imx219_identify_module(imx219);
++ if (ret)
++ goto error_power_off;
++
+ /* Set default mode to max resolution */
+ imx219->mode = &supported_modes[0];
+
+ ret = imx219_init_controls(imx219);
+ if (ret)
-+ return ret;
++ goto error_power_off;
+
+ /* Initialize subdev */
+ imx219->sd.internal_ops = &imx219_internal_ops;
@@ -1087,16 +1297,21 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ imx219->pad.flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad);
-+ if (ret)
++ if (ret) {
++ dev_err(dev, "failed to init entity pads: %d\n", ret);
+ goto error_handler_free;
++ }
+
+ ret = v4l2_async_register_subdev_sensor_common(&imx219->sd);
-+ if (ret < 0)
++ if (ret < 0) {
++ dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
+ goto error_media_entity;
++ }
+
-+ pm_runtime_set_active(&client->dev);
-+ pm_runtime_enable(&client->dev);
-+ pm_runtime_idle(&client->dev);
++ /* Enable runtime PM and turn off the device */
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_idle(dev);
+
+ return 0;
+
@@ -1106,6 +1321,9 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+error_handler_free:
+ imx219_free_controls(imx219);
+
++error_power_off:
++ imx219_power_off(dev);
++
+ return ret;
+}
+
@@ -1119,6 +1337,8 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+ imx219_free_controls(imx219);
+
+ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ imx219_power_off(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+
+ return 0;
@@ -1130,17 +1350,23 @@ Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+};
+MODULE_DEVICE_TABLE(of, imx219_dt_ids);
+
++static const struct dev_pm_ops imx219_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(imx219_suspend, imx219_resume)
++ SET_RUNTIME_PM_OPS(imx219_power_off, imx219_power_on, NULL)
++};
++
+static struct i2c_driver imx219_i2c_driver = {
+ .driver = {
+ .name = "imx219",
+ .of_match_table = imx219_dt_ids,
++ .pm = &imx219_pm_ops,
+ },
-+ .probe = imx219_probe,
++ .probe_new = imx219_probe,
+ .remove = imx219_remove,
+};
+
+module_i2c_driver(imx219_i2c_driver);
+
-+MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.org");
++MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com");
+MODULE_DESCRIPTION("Sony IMX219 sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/bcm27xx/patches-5.4/950-0465-overlays-imx219-Correct-link-frequency-to-match-the-.patch b/target/linux/bcm27xx/patches-5.4/950-0465-overlays-imx219-Correct-link-frequency-to-match-the-.patch
new file mode 100644
index 0000000000..e9eed21451
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0465-overlays-imx219-Correct-link-frequency-to-match-the-.patch
@@ -0,0 +1,25 @@
+From eae83133532e44adae2f632b2168119a4c7249a2 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 11 Mar 2020 12:07:57 +0000
+Subject: [PATCH] overlays: imx219: Correct link frequency to match the
+ upstream driver
+
+The upstream driver is checking the link frequency parameter, and
+the overlay had the wrong value.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/imx219-overlay.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/imx219-overlay.dts
++++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts
+@@ -40,7 +40,7 @@
+ data-lanes = <1 2>;
+ clock-noncontinuous;
+ link-frequencies =
+- /bits/ 64 <297000000>;
++ /bits/ 64 <456000000>;
+ };
+ };
+ };
diff --git a/target/linux/bcm27xx/patches-5.4/950-0466-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch b/target/linux/bcm27xx/patches-5.4/950-0466-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch
new file mode 100644
index 0000000000..e9b8a76831
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0466-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch
@@ -0,0 +1,26 @@
+From 61113c5463166d734dc6560574f5fb1536bae795 Mon Sep 17 00:00:00 2001
+From: Nataliya Korovkina <malus.brandywine@gmail.com>
+Date: Thu, 12 Mar 2020 17:22:53 -0400
+Subject: [PATCH] Kbuild: Allow .dtbo overlays to be built, adjust.
+
+This is adjustment to commit
+d368ceaacdccd7732dc97d1d7987bdf7149d62e3 "kbuild: Allow .dtbo overlays to be built piecemeal"
+
+prepare3 target has gone from mainline tree in branch 5.4.y
+
+Signed-off-by: Nataliya Korovkina <malus.brandywine@gmail.com>
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -1238,7 +1238,7 @@ ifneq ($(dtstree),)
+ %.dtb: include/config/kernel.release scripts_dtc
+ $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
+
+-%.dtbo: prepare3 scripts_dtc
++%.dtbo: include/config/kernel.release scripts_dtc
+ $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
+
+ PHONY += dtbs dtbs_install dt_binding_check
diff --git a/target/linux/bcm27xx/patches-5.4/950-0467-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch b/target/linux/bcm27xx/patches-5.4/950-0467-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch
new file mode 100644
index 0000000000..c7e10cbdc1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0467-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch
@@ -0,0 +1,74 @@
+From 23f717168dc55f69ad517d3ab5f412d04a5afc0e Mon Sep 17 00:00:00 2001
+From: David Plowman <david.plowman@raspberrypi.org>
+Date: Wed, 15 Jan 2020 13:40:38 +0000
+Subject: [PATCH] media: ov5647: Fix return codes from
+ ov5647_write/ov5647_read functions.
+
+Previously they were returning positive non-zero codes for success,
+which were getting passed up the call stack. Since release 4.19,
+do_dentry_open (fs/open.c) has been catching these and flagging an
+error. (So this driver has been broken since that date.)
+
+Fixes: 3c2472a [media] media: i2c: Add support for OV5647 sensor
+Signed-off-by: David Plowman <david.plowman@raspberrypi.org>
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/i2c/ov5647.c | 30 +++++++++++++++++++++++++++---
+ 1 file changed, 27 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/i2c/ov5647.c
++++ b/drivers/media/i2c/ov5647.c
+@@ -214,9 +214,18 @@ static int ov5647_write(struct v4l2_subd
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ ret = i2c_master_send(client, data, 3);
+- if (ret < 0)
++ /*
++ * Writing the wrong number of bytes also needs to be flagged as an
++ * error. Success needs to produce a 0 return code.
++ */
++ if (ret == 3) {
++ ret = 0;
++ } else {
+ dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
+ __func__, reg);
++ if (ret >= 0)
++ ret = -EINVAL;
++ }
+
+ return ret;
+ }
+@@ -228,16 +237,31 @@ static int ov5647_read(struct v4l2_subde
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ ret = i2c_master_send(client, data_w, 2);
+- if (ret < 0) {
++ /*
++ * A negative return code, or sending the wrong number of bytes, both
++ * count as an error.
++ */
++ if (ret != 2) {
+ dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
+ __func__, reg);
++ if (ret >= 0)
++ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = i2c_master_recv(client, val, 1);
+- if (ret < 0)
++ /*
++ * The only return value indicating success is 1. Anything else, even
++ * a non-negative value, indicates something went wrong.
++ */
++ if (ret == 1) {
++ ret = 0;
++ } else {
+ dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
+ __func__, reg);
++ if (ret >= 0)
++ ret = -EINVAL;
++ }
+
+ return ret;
+ }
diff --git a/target/linux/bcm27xx/patches-5.4/950-0468-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch b/target/linux/bcm27xx/patches-5.4/950-0468-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch
new file mode 100644
index 0000000000..5846e96af8
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0468-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch
@@ -0,0 +1,407 @@
+From 9e584d9de3387588bf455d3c45ec6a092bfa4266 Mon Sep 17 00:00:00 2001
+From: David Plowman <david.plowman@raspberrypi.com>
+Date: Wed, 29 Jan 2020 15:30:53 +0000
+Subject: [PATCH] media: ov5647: Add basic support for multiple sensor
+ modes.
+
+Specifically:
+
+Added a structure ov5647_mode and a list of supported_modes (though no
+actual new modes as yet). The state object points to the "current mode".
+
+ov5647_enum_mbus_code, ov5647_enum_frame_size, ov5647_set_fmt and
+ov5647_get_fmt all needed upgrading to cope with multiple modes.
+
+__sensor_init (which writes all the registers) is now called by
+ov5647_stream_on (once the mode is known) rather than by
+ov5647_sensor_power.
+
+Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/i2c/ov5647.c | 268 ++++++++++++++++++++++++++++---------
+ 1 file changed, 202 insertions(+), 66 deletions(-)
+
+--- a/drivers/media/i2c/ov5647.c
++++ b/drivers/media/i2c/ov5647.c
+@@ -86,13 +86,17 @@ struct regval_list {
+ u8 data;
+ };
+
++struct ov5647_mode {
++ struct v4l2_mbus_framefmt format;
++ struct regval_list *reg_list;
++ unsigned int num_regs;
++};
++
+ struct ov5647 {
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct mutex lock;
+- struct v4l2_mbus_framefmt format;
+- unsigned int width;
+- unsigned int height;
++ const struct ov5647_mode *mode;
+ int power_count;
+ struct clk *xclk;
+ struct gpio_desc *pwdn;
+@@ -207,6 +211,32 @@ static struct regval_list ov5647_640x480
+ {0x0100, 0x01},
+ };
+
++static struct ov5647_mode supported_modes_8bit[] = {
++ /*
++ * Original 8-bit VGA mode
++ * Uncentred crop (top left quarter) from 2x2 binned 1296x972 image.
++ */
++ {
++ {
++ .code = MEDIA_BUS_FMT_SBGGR8_1X8,
++ .colorspace = V4L2_COLORSPACE_SRGB,
++ .field = V4L2_FIELD_NONE,
++ .width = 640,
++ .height = 480
++ },
++ ov5647_640x480,
++ ARRAY_SIZE(ov5647_640x480)
++ },
++ /* more modes below here... */
++};
++
++static struct ov5647_mode supported_modes_10bit[] = {
++ /* no 10-bit modes yet */
++};
++
++/* Use original 8-bit VGA mode as default. */
++#define OV5647_DEFAULT_MODE (&supported_modes_8bit[0])
++
+ static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
+ {
+ int ret;
+@@ -293,12 +323,55 @@ static int ov5647_set_virtual_channel(st
+ return ov5647_write(sd, OV5647_REG_MIPI_CTRL14, channel_id | (channel << 6));
+ }
+
++static int __sensor_init(struct v4l2_subdev *sd)
++{
++ int ret;
++ u8 resetval, rdval;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov5647 *state = to_state(sd);
++
++ ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5647_write_array(sd, state->mode->reg_list,
++ state->mode->num_regs);
++ if (ret < 0) {
++ dev_err(&client->dev, "write sensor default regs error\n");
++ return ret;
++ }
++
++ ret = ov5647_set_virtual_channel(sd, 0);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
++ if (ret < 0)
++ return ret;
++
++ if (!(resetval & 0x01)) {
++ dev_err(&client->dev, "Device was in SW standby");
++ ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
+ static int ov5647_stream_on(struct v4l2_subdev *sd)
+ {
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov5647 *ov5647 = to_state(sd);
+ u8 val = MIPI_CTRL00_BUS_IDLE;
+ int ret;
+
++ ret = __sensor_init(sd);
++ if (ret < 0) {
++ dev_err(&client->dev, "sensor_init failed\n");
++ return ret;
++ }
++
+ if (ov5647->flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)
+ val |= MIPI_CTRL00_CLOCK_LANE_GATE |
+ MIPI_CTRL00_LINE_SYNC_ENABLE;
+@@ -347,44 +420,6 @@ static int set_sw_standby(struct v4l2_su
+ return ov5647_write(sd, OV5647_SW_STANDBY, rdval);
+ }
+
+-static int __sensor_init(struct v4l2_subdev *sd)
+-{
+- int ret;
+- u8 resetval, rdval;
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+-
+- ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
+- if (ret < 0)
+- return ret;
+-
+- ret = ov5647_write_array(sd, ov5647_640x480,
+- ARRAY_SIZE(ov5647_640x480));
+- if (ret < 0) {
+- dev_err(&client->dev, "write sensor default regs error\n");
+- return ret;
+- }
+-
+- ret = ov5647_set_virtual_channel(sd, 0);
+- if (ret < 0)
+- return ret;
+-
+- ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
+- if (ret < 0)
+- return ret;
+-
+- if (!(resetval & 0x01)) {
+- dev_err(&client->dev, "Device was in SW standby");
+- ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
+- if (ret < 0)
+- return ret;
+- }
+-
+- /*
+- * stream off to make the clock lane into LP-11 state.
+- */
+- return ov5647_stream_off(sd);
+-}
+-
+ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
+ {
+ int ret = 0;
+@@ -408,7 +443,7 @@ static int ov5647_sensor_power(struct v4
+ }
+
+ ret = ov5647_write_array(sd, sensor_oe_enable_regs,
+- ARRAY_SIZE(sensor_oe_enable_regs));
++ ARRAY_SIZE(sensor_oe_enable_regs));
+ if (ret < 0) {
+ clk_disable_unprepare(ov5647->xclk);
+ dev_err(&client->dev,
+@@ -416,7 +451,10 @@ static int ov5647_sensor_power(struct v4
+ goto out;
+ }
+
+- ret = __sensor_init(sd);
++ /*
++ * Ensure streaming off to make clock lane go into LP-11 state.
++ */
++ ret = ov5647_stream_off(sd);
+ if (ret < 0) {
+ clk_disable_unprepare(ov5647->xclk);
+ dev_err(&client->dev,
+@@ -427,7 +465,7 @@ static int ov5647_sensor_power(struct v4
+ dev_dbg(&client->dev, "OV5647 power off\n");
+
+ ret = ov5647_write_array(sd, sensor_oe_disable_regs,
+- ARRAY_SIZE(sensor_oe_disable_regs));
++ ARRAY_SIZE(sensor_oe_disable_regs));
+
+ if (ret < 0)
+ dev_dbg(&client->dev, "disable oe failed\n");
+@@ -489,10 +527,19 @@ static const struct v4l2_subdev_core_ops
+
+ static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
+ {
++ struct ov5647 *state = to_state(sd);
++ int ret = 0;
++
++ mutex_lock(&state->lock);
++
+ if (enable)
+- return ov5647_stream_on(sd);
++ ret = ov5647_stream_on(sd);
+ else
+- return ov5647_stream_off(sd);
++ ret = ov5647_stream_off(sd);
++
++ mutex_unlock(&state->lock);
++
++ return ret;
+ }
+
+ static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
+@@ -503,38 +550,127 @@ static int ov5647_enum_mbus_code(struct
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+ {
+- if (code->index > 0)
++ if (code->index == 0 && ARRAY_SIZE(supported_modes_8bit))
++ code->code = MEDIA_BUS_FMT_SBGGR8_1X8;
++ else if (code->index == 0 && ARRAY_SIZE(supported_modes_8bit) == 0 &&
++ ARRAY_SIZE(supported_modes_10bit))
++ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ else if (code->index == 1 && ARRAY_SIZE(supported_modes_8bit) &&
++ ARRAY_SIZE(supported_modes_10bit))
++ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ else
+ return -EINVAL;
+
+- code->code = MEDIA_BUS_FMT_SBGGR8_1X8;
++ return 0;
++}
++
++static int ov5647_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct ov5647_mode *mode = NULL;
++
++ if (fse->code == MEDIA_BUS_FMT_SBGGR8_1X8) {
++ if (fse->index >= ARRAY_SIZE(supported_modes_8bit))
++ return -EINVAL;
++ mode = &supported_modes_8bit[fse->index];
++ } else if (fse->code == MEDIA_BUS_FMT_SBGGR10_1X10) {
++ if (fse->index >= ARRAY_SIZE(supported_modes_10bit))
++ return -EINVAL;
++ mode = &supported_modes_10bit[fse->index];
++ } else {
++ return -EINVAL;
++ }
++
++ fse->min_width = mode->format.width;
++ fse->max_width = fse->min_width;
++ fse->min_height = mode->format.height;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int ov5647_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *fmt = &format->format;
++ struct ov5647 *state = to_state(sd);
++ struct v4l2_mbus_framefmt *framefmt;
++ const struct ov5647_mode *mode_8bit, *mode_10bit, *mode = NULL;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&state->lock);
++
++ /*
++ * Try to respect any given pixel format, otherwise try for a 10-bit
++ * mode.
++ */
++ mode_8bit = v4l2_find_nearest_size(supported_modes_8bit,
++ ARRAY_SIZE(supported_modes_8bit),
++ format.width, format.height,
++ format->format.width,
++ format->format.height);
++ mode_10bit = v4l2_find_nearest_size(supported_modes_10bit,
++ ARRAY_SIZE(supported_modes_10bit),
++ format.width, format.height,
++ format->format.width,
++ format->format.height);
++ if (format->format.code == MEDIA_BUS_FMT_SBGGR8_1X8 && mode_8bit)
++ mode = mode_8bit;
++ else if (format->format.code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
++ mode_10bit)
++ mode = mode_10bit;
++ else if (mode_10bit)
++ mode = mode_10bit;
++ else
++ mode = mode_8bit;
++
++ if (!mode)
++ return -EINVAL;
++
++ *fmt = mode->format;
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
++ framefmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
++ *framefmt = format->format;
++ } else {
++ state->mode = mode;
++ }
++
++ mutex_unlock(&state->lock);
+
+ return 0;
+ }
+
+-static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
+- struct v4l2_subdev_pad_config *cfg,
+- struct v4l2_subdev_format *format)
++static int ov5647_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
+ {
+ struct v4l2_mbus_framefmt *fmt = &format->format;
++ struct ov5647 *state = to_state(sd);
+
+ if (format->pad != 0)
+ return -EINVAL;
+
+- /* Only one format is supported, so return that */
+- memset(fmt, 0, sizeof(*fmt));
+- fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8;
+- fmt->colorspace = V4L2_COLORSPACE_SRGB;
+- fmt->field = V4L2_FIELD_NONE;
+- fmt->width = 640;
+- fmt->height = 480;
++ mutex_lock(&state->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ *fmt = *v4l2_subdev_get_try_format(sd, cfg, format->pad);
++ else
++ *fmt = state->mode->format;
++
++ mutex_unlock(&state->lock);
+
+ return 0;
+ }
+
+ static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
+ .enum_mbus_code = ov5647_enum_mbus_code,
+- .set_fmt = ov5647_set_get_fmt,
+- .get_fmt = ov5647_set_get_fmt,
++ .set_fmt = ov5647_set_fmt,
++ .get_fmt = ov5647_get_fmt,
++ .enum_frame_size = ov5647_enum_frame_size,
+ };
+
+ static const struct v4l2_subdev_ops ov5647_subdev_ops = {
+@@ -580,18 +716,15 @@ static int ov5647_open(struct v4l2_subde
+ v4l2_subdev_get_try_format(sd, fh->pad, 0);
+ struct v4l2_rect *crop =
+ v4l2_subdev_get_try_crop(sd, fh->pad, 0);
++ struct ov5647 *state = to_state(sd);
+
+ crop->left = OV5647_COLUMN_START_DEF;
+ crop->top = OV5647_ROW_START_DEF;
+ crop->width = OV5647_WINDOW_WIDTH_DEF;
+ crop->height = OV5647_WINDOW_HEIGHT_DEF;
+
+- format->code = MEDIA_BUS_FMT_SBGGR8_1X8;
+-
+- format->width = OV5647_WINDOW_WIDTH_DEF;
+- format->height = OV5647_WINDOW_HEIGHT_DEF;
+- format->field = V4L2_FIELD_NONE;
+- format->colorspace = V4L2_COLORSPACE_SRGB;
++ /* Set the default format to the same as the sensor. */
++ *format = state->mode->format;
+
+ return 0;
+ }
+@@ -660,6 +793,9 @@ static int ov5647_probe(struct i2c_clien
+
+ mutex_init(&sensor->lock);
+
++ /* Set the default mode before we init the subdev */
++ sensor->mode = OV5647_DEFAULT_MODE;
++
+ sd = &sensor->sd;
+ v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
+ sensor->sd.internal_ops = &ov5647_subdev_internal_ops;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0469-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch b/target/linux/bcm27xx/patches-5.4/950-0469-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch
new file mode 100644
index 0000000000..907bab5cfd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0469-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch
@@ -0,0 +1,277 @@
+From d9d333b717f220439868edd533994f2709b3a95f Mon Sep 17 00:00:00 2001
+From: David Plowman <david.plowman@raspberrypi.com>
+Date: Wed, 29 Jan 2020 15:31:23 +0000
+Subject: [PATCH] media: ov5647: Add V4L2 controls for analogue gain,
+ exposure and AWB
+
+Added basic v4l2_ctrl_handler infrastructure (there was none
+previously).
+
+Added controls to let AWB/AEC/AGC run in the sensor's auto mode or
+manually. Also controls to set exposure (in lines) and analogue gain
+(as a register code) from user code.
+
+Also delete registers (just the one) from the VGA mode register set
+that are now controlled by the new V4L2 controls.
+
+Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/i2c/ov5647.c | 175 ++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 174 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/i2c/ov5647.c
++++ b/drivers/media/i2c/ov5647.c
+@@ -29,11 +29,13 @@
+ #include <linux/of_graph.h>
+ #include <linux/slab.h>
+ #include <linux/videodev2.h>
++#include <media/v4l2-ctrls.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-fwnode.h>
+ #include <media/v4l2-image-sizes.h>
+ #include <media/v4l2-mediabus.h>
+
++
+ #define SENSOR_NAME "ov5647"
+
+ /*
+@@ -53,9 +55,16 @@
+ #define OV5647_REG_CHIPID_H 0x300A
+ #define OV5647_REG_CHIPID_L 0x300B
+ #define OV5640_REG_PAD_OUT 0x300D
++#define OV5647_REG_EXP_HI 0x3500
++#define OV5647_REG_EXP_MID 0x3501
++#define OV5647_REG_EXP_LO 0x3502
++#define OV5647_REG_AEC_AGC 0x3503
++#define OV5647_REG_GAIN_HI 0x350A
++#define OV5647_REG_GAIN_LO 0x350B
+ #define OV5647_REG_FRAME_OFF_NUMBER 0x4202
+ #define OV5647_REG_MIPI_CTRL00 0x4800
+ #define OV5647_REG_MIPI_CTRL14 0x4814
++#define OV5647_REG_AWB 0x5001
+
+ #define REG_TERM 0xfffe
+ #define VAL_TERM 0xfe
+@@ -101,6 +110,7 @@ struct ov5647 {
+ struct clk *xclk;
+ struct gpio_desc *pwdn;
+ unsigned int flags;
++ struct v4l2_ctrl_handler ctrls;
+ };
+
+ static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
+@@ -135,7 +145,6 @@ static struct regval_list ov5647_640x480
+ {0x3612, 0x59},
+ {0x3618, 0x00},
+ {0x5000, 0x06},
+- {0x5001, 0x01},
+ {0x5002, 0x41},
+ {0x5003, 0x08},
+ {0x5a00, 0x08},
+@@ -372,6 +381,11 @@ static int ov5647_stream_on(struct v4l2_
+ return ret;
+ }
+
++ /* Apply customized values from user when stream starts */
++ ret = __v4l2_ctrl_handler_setup(sd->ctrl_handler);
++ if (ret)
++ return ret;
++
+ if (ov5647->flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)
+ val |= MIPI_CTRL00_CLOCK_LANE_GATE |
+ MIPI_CTRL00_LINE_SYNC_ENABLE;
+@@ -753,6 +767,120 @@ static int ov5647_parse_dt(struct device
+ return ret;
+ }
+
++static int ov5647_s_auto_white_balance(struct v4l2_subdev *sd, u32 val)
++{
++ /* non-zero turns on AWB */
++ return ov5647_write(sd, OV5647_REG_AWB, val ? 1 : 0);
++}
++
++static int ov5647_s_autogain(struct v4l2_subdev *sd, u32 val)
++{
++ int ret;
++ u8 reg;
++
++ /* non-zero turns on AGC by clearing bit 1 */
++ ret = ov5647_read(sd, OV5647_REG_AEC_AGC, &reg);
++ if (ret == 0)
++ ret = ov5647_write(sd, OV5647_REG_AEC_AGC,
++ val ? reg & ~2 : reg | 2);
++
++ return ret;
++}
++
++static int ov5647_s_exposure_auto(struct v4l2_subdev *sd, u32 val)
++{
++ int ret;
++ u8 reg;
++
++ /* Everything except V4L2_EXPOSURE_MANUAL turns on AEC by
++ * clearing bit 0
++ */
++ ret = ov5647_read(sd, OV5647_REG_AEC_AGC, &reg);
++ if (ret == 0)
++ ret = ov5647_write(sd, OV5647_REG_AEC_AGC,
++ val == V4L2_EXPOSURE_MANUAL ?
++ reg | 1 : reg & ~1);
++
++ return ret;
++}
++
++static int ov5647_s_analogue_gain(struct v4l2_subdev *sd, u32 val)
++{
++ int ret;
++
++ /* 10 bits of gain, 2 in the high register */
++ ret = ov5647_write(sd, OV5647_REG_GAIN_HI, (val >> 8) & 3);
++ if (ret == 0)
++ ret = ov5647_write(sd, OV5647_REG_GAIN_LO, val & 0xff);
++
++ return ret;
++}
++
++static int ov5647_s_exposure(struct v4l2_subdev *sd, u32 val)
++{
++ int ret;
++
++ /* Sensor has 20 bits, but the bottom 4 bits are fractions of a line
++ * which we leave as zero (and don't receive in "val").
++ */
++ ret = ov5647_write(sd, OV5647_REG_EXP_HI, (val >> 12) & 0xf);
++ if (ret == 0)
++ ov5647_write(sd, OV5647_REG_EXP_MID, (val >> 4) & 0xff);
++ if (ret == 0)
++ ov5647_write(sd, OV5647_REG_EXP_LO, (val & 0xf) << 4);
++
++ return ret;
++}
++
++static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct ov5647 *state = container_of(ctrl->handler,
++ struct ov5647, ctrls);
++ struct v4l2_subdev *sd = &state->sd;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret = 0;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored right after power-up.
++ */
++ if (state->power_count == 0)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = ov5647_s_auto_white_balance(sd, ctrl->val);
++ break;
++ case V4L2_CID_AUTOGAIN:
++ ret = ov5647_s_autogain(sd, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ ret = ov5647_s_exposure_auto(sd, ctrl->val);
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = ov5647_s_analogue_gain(sd, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = ov5647_s_exposure(sd, ctrl->val);
++ break;
++ default:
++ dev_info(&client->dev,
++ "ctrl(id:0x%x,val:0x%x) is not handled\n",
++ ctrl->id, ctrl->val);
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
++ .s_ctrl = ov5647_s_ctrl,
++};
++
+ static int ov5647_probe(struct i2c_client *client)
+ {
+ struct device *dev = &client->dev;
+@@ -761,6 +889,7 @@ static int ov5647_probe(struct i2c_clien
+ struct v4l2_subdev *sd;
+ struct device_node *np = client->dev.of_node;
+ u32 xclk_freq;
++ struct v4l2_ctrl *ctrl;
+
+ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
+ if (!sensor)
+@@ -793,6 +922,48 @@ static int ov5647_probe(struct i2c_clien
+
+ mutex_init(&sensor->lock);
+
++ /* Initialise controls. */
++ v4l2_ctrl_handler_init(&sensor->ctrls, 3);
++ v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
++ V4L2_CID_AUTOGAIN,
++ 0, /* min */
++ 1, /* max */
++ 1, /* step */
++ 1); /* default */
++ v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, /* min */
++ 1, /* max */
++ 1, /* step */
++ 1); /* default */
++ v4l2_ctrl_new_std_menu(&sensor->ctrls, &ov5647_ctrl_ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, /* max */
++ 0, /* skip_mask */
++ V4L2_EXPOSURE_AUTO); /* default */
++ ctrl = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
++ V4L2_CID_EXPOSURE,
++ 4, /* min lines */
++ 65535, /* max lines (4+8+4 bits)*/
++ 1, /* step */
++ 1000); /* default number of lines */
++ ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
++ ctrl = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN,
++ 16, /* min, 16 = 1.0x */
++ 1023, /* max (10 bits) */
++ 1, /* step */
++ 32); /* default, 32 = 2.0x */
++ ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
++
++ if (sensor->ctrls.error) {
++ ret = sensor->ctrls.error;
++ dev_err(&client->dev, "%s control init failed (%d)\n",
++ __func__, ret);
++ goto error;
++ }
++ sensor->sd.ctrl_handler = &sensor->ctrls;
++
+ /* Set the default mode before we init the subdev */
+ sensor->mode = OV5647_DEFAULT_MODE;
+
+@@ -828,6 +999,7 @@ static int ov5647_probe(struct i2c_clien
+ error:
+ media_entity_cleanup(&sd->entity);
+ mutex_remove:
++ v4l2_ctrl_handler_free(&sensor->ctrls);
+ mutex_destroy(&sensor->lock);
+ return ret;
+ }
+@@ -839,6 +1011,7 @@ static int ov5647_remove(struct i2c_clie
+
+ v4l2_async_unregister_subdev(&ov5647->sd);
+ media_entity_cleanup(&ov5647->sd.entity);
++ v4l2_ctrl_handler_free(&ov5647->ctrls);
+ v4l2_device_unregister_subdev(sd);
+ mutex_destroy(&ov5647->lock);
+
diff --git a/target/linux/bcm27xx/patches-5.4/950-0470-media-ov5647-Add-extra-10-bit-sensor-modes.patch b/target/linux/bcm27xx/patches-5.4/950-0470-media-ov5647-Add-extra-10-bit-sensor-modes.patch
new file mode 100644
index 0000000000..9e40b5164a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0470-media-ov5647-Add-extra-10-bit-sensor-modes.patch
@@ -0,0 +1,549 @@
+From 28c0004a54ce9b2c5862b38408952583b07458f9 Mon Sep 17 00:00:00 2001
+From: David Plowman <david.plowman@raspberrypi.com>
+Date: Wed, 29 Jan 2020 15:31:28 +0000
+Subject: [PATCH] media: ov5647: Add extra 10-bit sensor modes.
+
+The 8-bit VGA mode remains, we add the following 10-bit modes:
+
+Mode 0: 2592x1944 full resolution.
+
+Mode 1: 1920x1080 full resolution, but centre-cropped.
+(This mode achieves 30fps, mode 0 does not.)
+
+Mode 2: 1296x972 full field-of-view 2x2 binned mode.
+
+Mode 3: VGA full field of view mode.
+
+Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/i2c/ov5647.c | 463 ++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 452 insertions(+), 11 deletions(-)
+
+--- a/drivers/media/i2c/ov5647.c
++++ b/drivers/media/i2c/ov5647.c
+@@ -111,6 +111,7 @@ struct ov5647 {
+ struct gpio_desc *pwdn;
+ unsigned int flags;
+ struct v4l2_ctrl_handler ctrls;
++ bool write_mode_regs;
+ };
+
+ static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
+@@ -130,7 +131,7 @@ static struct regval_list sensor_oe_enab
+ {0x3002, 0xe4},
+ };
+
+-static struct regval_list ov5647_640x480[] = {
++static struct regval_list ov5647_640x480_8bit[] = {
+ {0x0100, 0x00},
+ {0x0103, 0x01},
+ {0x3034, 0x08},
+@@ -220,9 +221,378 @@ static struct regval_list ov5647_640x480
+ {0x0100, 0x01},
+ };
+
++static struct regval_list ov5647_2592x1944_10bit[] = {
++ {0x0100, 0x00},
++ {0x0103, 0x01},
++ {0x3034, 0x1a},
++ {0x3035, 0x21},
++ {0x3036, 0x69},
++ {0x303c, 0x11},
++ {0x3106, 0xf5},
++ {0x3821, 0x06},
++ {0x3820, 0x00},
++ {0x3827, 0xec},
++ {0x370c, 0x03},
++ {0x3612, 0x5b},
++ {0x3618, 0x04},
++ {0x5000, 0x06},
++ {0x5002, 0x41},
++ {0x5003, 0x08},
++ {0x5a00, 0x08},
++ {0x3000, 0x00},
++ {0x3001, 0x00},
++ {0x3002, 0x00},
++ {0x3016, 0x08},
++ {0x3017, 0xe0},
++ {0x3018, 0x44},
++ {0x301c, 0xf8},
++ {0x301d, 0xf0},
++ {0x3a18, 0x00},
++ {0x3a19, 0xf8},
++ {0x3c01, 0x80},
++ {0x3b07, 0x0c},
++ {0x380c, 0x0b},
++ {0x380d, 0x1c},
++ {0x380e, 0x07},
++ {0x380f, 0xb0},
++ {0x3814, 0x11},
++ {0x3815, 0x11},
++ {0x3708, 0x64},
++ {0x3709, 0x12},
++ {0x3808, 0x0a},
++ {0x3809, 0x20},
++ {0x380a, 0x07},
++ {0x380b, 0x98},
++ {0x3800, 0x00},
++ {0x3801, 0x00},
++ {0x3802, 0x00},
++ {0x3803, 0x00},
++ {0x3804, 0x0a},
++ {0x3805, 0x3f},
++ {0x3806, 0x07},
++ {0x3807, 0xa3},
++ {0x3811, 0x10},
++ {0x3813, 0x06},
++ {0x3630, 0x2e},
++ {0x3632, 0xe2},
++ {0x3633, 0x23},
++ {0x3634, 0x44},
++ {0x3636, 0x06},
++ {0x3620, 0x64},
++ {0x3621, 0xe0},
++ {0x3600, 0x37},
++ {0x3704, 0xa0},
++ {0x3703, 0x5a},
++ {0x3715, 0x78},
++ {0x3717, 0x01},
++ {0x3731, 0x02},
++ {0x370b, 0x60},
++ {0x3705, 0x1a},
++ {0x3f05, 0x02},
++ {0x3f06, 0x10},
++ {0x3f01, 0x0a},
++ {0x3a08, 0x01},
++ {0x3a09, 0x28},
++ {0x3a0a, 0x00},
++ {0x3a0b, 0xf6},
++ {0x3a0d, 0x08},
++ {0x3a0e, 0x06},
++ {0x3a0f, 0x58},
++ {0x3a10, 0x50},
++ {0x3a1b, 0x58},
++ {0x3a1e, 0x50},
++ {0x3a11, 0x60},
++ {0x3a1f, 0x28},
++ {0x4001, 0x02},
++ {0x4004, 0x04},
++ {0x4000, 0x09},
++ {0x4837, 0x19},
++ {0x4800, 0x24},
++ {0x3503, 0x03},
++ {0x0100, 0x01},
++};
++
++static struct regval_list ov5647_1080p30_10bit[] = {
++ {0x0100, 0x00},
++ {0x0103, 0x01},
++ {0x3034, 0x1a},
++ {0x3035, 0x21},
++ {0x3036, 0x62},
++ {0x303c, 0x11},
++ {0x3106, 0xf5},
++ {0x3821, 0x06},
++ {0x3820, 0x00},
++ {0x3827, 0xec},
++ {0x370c, 0x03},
++ {0x3612, 0x5b},
++ {0x3618, 0x04},
++ {0x5000, 0x06},
++ {0x5002, 0x41},
++ {0x5003, 0x08},
++ {0x5a00, 0x08},
++ {0x3000, 0x00},
++ {0x3001, 0x00},
++ {0x3002, 0x00},
++ {0x3016, 0x08},
++ {0x3017, 0xe0},
++ {0x3018, 0x44},
++ {0x301c, 0xf8},
++ {0x301d, 0xf0},
++ {0x3a18, 0x00},
++ {0x3a19, 0xf8},
++ {0x3c01, 0x80},
++ {0x3b07, 0x0c},
++ {0x380c, 0x09},
++ {0x380d, 0x70},
++ {0x380e, 0x04},
++ {0x380f, 0x50},
++ {0x3814, 0x11},
++ {0x3815, 0x11},
++ {0x3708, 0x64},
++ {0x3709, 0x12},
++ {0x3808, 0x07},
++ {0x3809, 0x80},
++ {0x380a, 0x04},
++ {0x380b, 0x38},
++ {0x3800, 0x01},
++ {0x3801, 0x5c},
++ {0x3802, 0x01},
++ {0x3803, 0xb2},
++ {0x3804, 0x08},
++ {0x3805, 0xe3},
++ {0x3806, 0x05},
++ {0x3807, 0xf1},
++ {0x3811, 0x04},
++ {0x3813, 0x02},
++ {0x3630, 0x2e},
++ {0x3632, 0xe2},
++ {0x3633, 0x23},
++ {0x3634, 0x44},
++ {0x3636, 0x06},
++ {0x3620, 0x64},
++ {0x3621, 0xe0},
++ {0x3600, 0x37},
++ {0x3704, 0xa0},
++ {0x3703, 0x5a},
++ {0x3715, 0x78},
++ {0x3717, 0x01},
++ {0x3731, 0x02},
++ {0x370b, 0x60},
++ {0x3705, 0x1a},
++ {0x3f05, 0x02},
++ {0x3f06, 0x10},
++ {0x3f01, 0x0a},
++ {0x3a08, 0x01},
++ {0x3a09, 0x4b},
++ {0x3a0a, 0x01},
++ {0x3a0b, 0x13},
++ {0x3a0d, 0x04},
++ {0x3a0e, 0x03},
++ {0x3a0f, 0x58},
++ {0x3a10, 0x50},
++ {0x3a1b, 0x58},
++ {0x3a1e, 0x50},
++ {0x3a11, 0x60},
++ {0x3a1f, 0x28},
++ {0x4001, 0x02},
++ {0x4004, 0x04},
++ {0x4000, 0x09},
++ {0x4837, 0x19},
++ {0x4800, 0x34},
++ {0x3503, 0x03},
++ {0x0100, 0x01},
++};
++
++static struct regval_list ov5647_2x2binned_10bit[] = {
++ {0x0100, 0x00},
++ {0x0103, 0x01},
++ {0x3034, 0x1A},
++ {0x3035, 0x21},
++ {0x3036, 0x62},
++ {0x303C, 0x11},
++ {0x3106, 0xF5},
++ {0x3827, 0xEC},
++ {0x370C, 0x03},
++ {0x3612, 0x59},
++ {0x3618, 0x00},
++ {0x5000, 0x06},
++ {0x5002, 0x41},
++ {0x5003, 0x08},
++ {0x5A00, 0x08},
++ {0x3000, 0x00},
++ {0x3001, 0x00},
++ {0x3002, 0x00},
++ {0x3016, 0x08},
++ {0x3017, 0xE0},
++ {0x3018, 0x44},
++ {0x301C, 0xF8},
++ {0x301D, 0xF0},
++ {0x3A18, 0x00},
++ {0x3A19, 0xF8},
++ {0x3C01, 0x80},
++ {0x3B07, 0x0C},
++ {0x3800, 0x00},
++ {0x3801, 0x00},
++ {0x3802, 0x00},
++ {0x3803, 0x00},
++ {0x3804, 0x0A},
++ {0x3805, 0x3F},
++ {0x3806, 0x07},
++ {0x3807, 0xA3},
++ {0x3808, 0x05},
++ {0x3809, 0x10},
++ {0x380A, 0x03},
++ {0x380B, 0xCC},
++ {0x380C, 0x07},
++ {0x380D, 0x68},
++ {0x3811, 0x0c},
++ {0x3813, 0x06},
++ {0x3814, 0x31},
++ {0x3815, 0x31},
++ {0x3630, 0x2E},
++ {0x3632, 0xE2},
++ {0x3633, 0x23},
++ {0x3634, 0x44},
++ {0x3636, 0x06},
++ {0x3620, 0x64},
++ {0x3621, 0xE0},
++ {0x3600, 0x37},
++ {0x3704, 0xA0},
++ {0x3703, 0x5A},
++ {0x3715, 0x78},
++ {0x3717, 0x01},
++ {0x3731, 0x02},
++ {0x370B, 0x60},
++ {0x3705, 0x1A},
++ {0x3F05, 0x02},
++ {0x3F06, 0x10},
++ {0x3F01, 0x0A},
++ {0x3A08, 0x01},
++ {0x3A09, 0x28},
++ {0x3A0A, 0x00},
++ {0x3A0B, 0xF6},
++ {0x3A0D, 0x08},
++ {0x3A0E, 0x06},
++ {0x3A0F, 0x58},
++ {0x3A10, 0x50},
++ {0x3A1B, 0x58},
++ {0x3A1E, 0x50},
++ {0x3A11, 0x60},
++ {0x3A1F, 0x28},
++ {0x4001, 0x02},
++ {0x4004, 0x04},
++ {0x4000, 0x09},
++ {0x4837, 0x16},
++ {0x4800, 0x24},
++ {0x3503, 0x03},
++ {0x3820, 0x41},
++ {0x3821, 0x07},
++ {0x380E, 0x05},
++ {0x380F, 0x9B},
++ {0x350A, 0x00},
++ {0x350B, 0x10},
++ {0x3500, 0x00},
++ {0x3501, 0x1A},
++ {0x3502, 0xF0},
++ {0x3212, 0xA0},
++ {0x0100, 0x01},
++};
++
++static struct regval_list ov5647_640x480_10bit[] = {
++ {0x0100, 0x00},
++ {0x0103, 0x01},
++ {0x3035, 0x11},
++ {0x3036, 0x46},
++ {0x303c, 0x11},
++ {0x3821, 0x07},
++ {0x3820, 0x41},
++ {0x370c, 0x03},
++ {0x3612, 0x59},
++ {0x3618, 0x00},
++ {0x5000, 0x06},
++ {0x5003, 0x08},
++ {0x5a00, 0x08},
++ {0x3000, 0xff},
++ {0x3001, 0xff},
++ {0x3002, 0xff},
++ {0x301d, 0xf0},
++ {0x3a18, 0x00},
++ {0x3a19, 0xf8},
++ {0x3c01, 0x80},
++ {0x3b07, 0x0c},
++ {0x380c, 0x07},
++ {0x380d, 0x3c},
++ {0x380e, 0x01},
++ {0x380f, 0xf8},
++ {0x3814, 0x35},
++ {0x3815, 0x35},
++ {0x3708, 0x64},
++ {0x3709, 0x52},
++ {0x3808, 0x02},
++ {0x3809, 0x80},
++ {0x380a, 0x01},
++ {0x380b, 0xe0},
++ {0x3800, 0x00},
++ {0x3801, 0x10},
++ {0x3802, 0x00},
++ {0x3803, 0x00},
++ {0x3804, 0x0a},
++ {0x3805, 0x2f},
++ {0x3806, 0x07},
++ {0x3807, 0x9f},
++ {0x3630, 0x2e},
++ {0x3632, 0xe2},
++ {0x3633, 0x23},
++ {0x3634, 0x44},
++ {0x3620, 0x64},
++ {0x3621, 0xe0},
++ {0x3600, 0x37},
++ {0x3704, 0xa0},
++ {0x3703, 0x5a},
++ {0x3715, 0x78},
++ {0x3717, 0x01},
++ {0x3731, 0x02},
++ {0x370b, 0x60},
++ {0x3705, 0x1a},
++ {0x3f05, 0x02},
++ {0x3f06, 0x10},
++ {0x3f01, 0x0a},
++ {0x3a08, 0x01},
++ {0x3a09, 0x2e},
++ {0x3a0a, 0x00},
++ {0x3a0b, 0xfb},
++ {0x3a0d, 0x02},
++ {0x3a0e, 0x01},
++ {0x3a0f, 0x58},
++ {0x3a10, 0x50},
++ {0x3a1b, 0x58},
++ {0x3a1e, 0x50},
++ {0x3a11, 0x60},
++ {0x3a1f, 0x28},
++ {0x4001, 0x02},
++ {0x4004, 0x02},
++ {0x4000, 0x09},
++ {0x3000, 0x00},
++ {0x3001, 0x00},
++ {0x3002, 0x00},
++ {0x3017, 0xe0},
++ {0x301c, 0xfc},
++ {0x3636, 0x06},
++ {0x3016, 0x08},
++ {0x3827, 0xec},
++ {0x3018, 0x44},
++ {0x3035, 0x21},
++ {0x3106, 0xf5},
++ {0x3034, 0x1a},
++ {0x301c, 0xf8},
++ {0x4800, 0x34},
++ {0x3503, 0x03},
++ {0x0100, 0x01},
++};
++
+ static struct ov5647_mode supported_modes_8bit[] = {
+ /*
+- * Original 8-bit VGA mode
++ * MODE 0: Original 8-bit VGA mode.
+ * Uncentred crop (top left quarter) from 2x2 binned 1296x972 image.
+ */
+ {
+@@ -233,14 +603,70 @@ static struct ov5647_mode supported_mode
+ .width = 640,
+ .height = 480
+ },
+- ov5647_640x480,
+- ARRAY_SIZE(ov5647_640x480)
++ ov5647_640x480_8bit,
++ ARRAY_SIZE(ov5647_640x480_8bit)
+ },
+- /* more modes below here... */
+ };
+
+ static struct ov5647_mode supported_modes_10bit[] = {
+- /* no 10-bit modes yet */
++ /*
++ * MODE 0: 2592x1944 full resolution full FOV 10-bit mode.
++ */
++ {
++ {
++ .code = MEDIA_BUS_FMT_SBGGR10_1X10,
++ .colorspace = V4L2_COLORSPACE_SRGB,
++ .field = V4L2_FIELD_NONE,
++ .width = 2592,
++ .height = 1944
++ },
++ ov5647_2592x1944_10bit,
++ ARRAY_SIZE(ov5647_2592x1944_10bit)
++ },
++ /*
++ * MODE 1: 1080p30 10-bit mode.
++ * Full resolution centre-cropped down to 1080p.
++ */
++ {
++ {
++ .code = MEDIA_BUS_FMT_SBGGR10_1X10,
++ .colorspace = V4L2_COLORSPACE_SRGB,
++ .field = V4L2_FIELD_NONE,
++ .width = 1920,
++ .height = 1080
++ },
++ ov5647_1080p30_10bit,
++ ARRAY_SIZE(ov5647_1080p30_10bit)
++ },
++ /*
++ * MODE 2: 2x2 binned full FOV 10-bit mode.
++ */
++ {
++ {
++ .code = MEDIA_BUS_FMT_SBGGR10_1X10,
++ .colorspace = V4L2_COLORSPACE_SRGB,
++ .field = V4L2_FIELD_NONE,
++ .width = 1296,
++ .height = 972
++ },
++ ov5647_2x2binned_10bit,
++ ARRAY_SIZE(ov5647_2x2binned_10bit)
++ },
++ /*
++ * MODE 3: 10-bit VGA full FOV mode 60fps.
++ * 2x2 binned and subsampled down to VGA.
++ */
++ {
++ {
++ .code = MEDIA_BUS_FMT_SBGGR10_1X10,
++ .colorspace = V4L2_COLORSPACE_SRGB,
++ .field = V4L2_FIELD_NONE,
++ .width = 640,
++ .height = 480
++ },
++ ov5647_640x480_10bit,
++ ARRAY_SIZE(ov5647_640x480_10bit)
++ },
+ };
+
+ /* Use original 8-bit VGA mode as default. */
+@@ -343,11 +769,14 @@ static int __sensor_init(struct v4l2_sub
+ if (ret < 0)
+ return ret;
+
+- ret = ov5647_write_array(sd, state->mode->reg_list,
+- state->mode->num_regs);
+- if (ret < 0) {
+- dev_err(&client->dev, "write sensor default regs error\n");
+- return ret;
++ if (state->write_mode_regs) {
++ ret = ov5647_write_array(sd, state->mode->reg_list,
++ state->mode->num_regs);
++ if (ret < 0) {
++ dev_err(&client->dev, "write sensor default regs error\n");
++ return ret;
++ }
++ state->write_mode_regs = false;
+ }
+
+ ret = ov5647_set_virtual_channel(sd, 0);
+@@ -475,6 +904,9 @@ static int ov5647_sensor_power(struct v4
+ "Camera not available, check Power\n");
+ goto out;
+ }
++
++ /* Write out the register set over I2C on stream-on. */
++ ov5647->write_mode_regs = true;
+ } else if (!on && ov5647->power_count == 1) {
+ dev_dbg(&client->dev, "OV5647 power off\n");
+
+@@ -650,6 +1082,12 @@ static int ov5647_set_fmt(struct v4l2_su
+ framefmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
+ *framefmt = format->format;
+ } else {
++ /*
++ * If we have changed modes, write the I2C register list on
++ * a stream_on().
++ */
++ if (state->mode != mode)
++ state->write_mode_regs = true;
+ state->mode = mode;
+ }
+
+@@ -967,6 +1405,9 @@ static int ov5647_probe(struct i2c_clien
+ /* Set the default mode before we init the subdev */
+ sensor->mode = OV5647_DEFAULT_MODE;
+
++ /* Write out the register set over I2C on stream-on. */
++ sensor->write_mode_regs = true;
++
+ sd = &sensor->sd;
+ v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
+ sensor->sd.internal_ops = &ov5647_subdev_internal_ops;
diff --git a/target/linux/bcm27xx/patches-5.4/950-0471-media-ov5647-change-defaults-to-better-match-raw-cam.patch b/target/linux/bcm27xx/patches-5.4/950-0471-media-ov5647-change-defaults-to-better-match-raw-cam.patch
new file mode 100644
index 0000000000..58d23b7bcb
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0471-media-ov5647-change-defaults-to-better-match-raw-cam.patch
@@ -0,0 +1,59 @@
+From 8bc19baeeca276374bed2d2ec95029d34fd93d7d Mon Sep 17 00:00:00 2001
+From: David Plowman <david.plowman@raspberrypi.com>
+Date: Wed, 29 Jan 2020 15:31:32 +0000
+Subject: [PATCH] media: ov5647: change defaults to better match raw
+ camera applications.
+
+Specifically:
+
+* AWB is now off by default.
+
+* AEC/AGC is also off by default.
+
+* The default mode is changed to the 10-bit 2x2 binned mode.
+
+AWB and AEC/AGC can be re-enabled using the usual V4L2 controls. The
+original 8-bit mode will be respected if an application requests the
+8-bit format.
+
+Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/i2c/ov5647.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/media/i2c/ov5647.c
++++ b/drivers/media/i2c/ov5647.c
+@@ -669,8 +669,8 @@ static struct ov5647_mode supported_mode
+ },
+ };
+
+-/* Use original 8-bit VGA mode as default. */
+-#define OV5647_DEFAULT_MODE (&supported_modes_8bit[0])
++/* Use 2x2 binned 10-bit mode as default. */
++#define OV5647_DEFAULT_MODE (&supported_modes_10bit[2])
+
+ static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
+ {
+@@ -1367,18 +1367,18 @@ static int ov5647_probe(struct i2c_clien
+ 0, /* min */
+ 1, /* max */
+ 1, /* step */
+- 1); /* default */
++ 0); /* default */
+ v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+ V4L2_CID_AUTO_WHITE_BALANCE,
+ 0, /* min */
+ 1, /* max */
+ 1, /* step */
+- 1); /* default */
++ 0); /* default */
+ v4l2_ctrl_new_std_menu(&sensor->ctrls, &ov5647_ctrl_ops,
+ V4L2_CID_EXPOSURE_AUTO,
+ V4L2_EXPOSURE_MANUAL, /* max */
+ 0, /* skip_mask */
+- V4L2_EXPOSURE_AUTO); /* default */
++ V4L2_EXPOSURE_MANUAL); /* default */
+ ctrl = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ 4, /* min lines */
diff --git a/target/linux/bcm27xx/patches-5.4/950-0472-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch b/target/linux/bcm27xx/patches-5.4/950-0472-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch
new file mode 100644
index 0000000000..0b48018c1e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0472-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch
@@ -0,0 +1,79 @@
+From c0b2ca6abdde60a111fd6d3257be78c7f44e16ff Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Thu, 26 Dec 2019 15:44:31 +0100
+Subject: [PATCH] drm/vc4: fkms: Change crtc_state structure name to
+ avoid conflict
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -260,7 +260,7 @@ static inline struct vc4_crtc *to_vc4_cr
+ return container_of(crtc, struct vc4_crtc, base);
+ }
+
+-struct vc4_crtc_state {
++struct fkms_crtc_state {
+ struct drm_crtc_state base;
+
+ struct {
+@@ -271,10 +271,10 @@ struct vc4_crtc_state {
+ } margins;
+ };
+
+-static inline struct vc4_crtc_state *
+-to_vc4_crtc_state(struct drm_crtc_state *crtc_state)
++static inline struct fkms_crtc_state *
++to_fkms_crtc_state(struct drm_crtc_state *crtc_state)
+ {
+- return (struct vc4_crtc_state *)crtc_state;
++ return (struct fkms_crtc_state *)crtc_state;
+ }
+
+ struct vc4_fkms_encoder {
+@@ -410,7 +410,7 @@ static void vc4_fkms_crtc_get_margins(st
+ unsigned int *left, unsigned int *right,
+ unsigned int *top, unsigned int *bottom)
+ {
+- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
++ struct fkms_crtc_state *vc4_state = to_fkms_crtc_state(state);
+ struct drm_connector_state *conn_state;
+ struct drm_connector *conn;
+ int i;
+@@ -423,7 +423,7 @@ static void vc4_fkms_crtc_get_margins(st
+ /* We have to interate over all new connector states because
+ * vc4_fkms_crtc_get_margins() might be called before
+ * vc4_fkms_crtc_atomic_check() which means margins info in
+- * vc4_crtc_state might be outdated.
++ * fkms_crtc_state might be outdated.
+ */
+ for_each_new_connector_in_state(state->state, conn, conn_state, i) {
+ if (conn_state->crtc != state->crtc)
+@@ -1068,7 +1068,7 @@ vc4_crtc_mode_valid(struct drm_crtc *crt
+ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+ {
+- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
++ struct fkms_crtc_state *vc4_state = to_fkms_crtc_state(state);
+ struct drm_connector *conn;
+ struct drm_connector_state *conn_state;
+ int i;
+@@ -1178,13 +1178,13 @@ static int vc4_page_flip(struct drm_crtc
+ static struct drm_crtc_state *
+ vc4_crtc_duplicate_state(struct drm_crtc *crtc)
+ {
+- struct vc4_crtc_state *vc4_state, *old_vc4_state;
++ struct fkms_crtc_state *vc4_state, *old_vc4_state;
+
+ vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
+ if (!vc4_state)
+ return NULL;
+
+- old_vc4_state = to_vc4_crtc_state(crtc->state);
++ old_vc4_state = to_fkms_crtc_state(crtc->state);
+ vc4_state->margins = old_vc4_state->margins;
+
+ __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base);
diff --git a/target/linux/bcm27xx/patches-5.4/950-0473-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch b/target/linux/bcm27xx/patches-5.4/950-0473-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch
new file mode 100644
index 0000000000..ac4fe1698b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0473-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch
@@ -0,0 +1,55 @@
+From 0d392a430d7dc84d8654972e9dbfa4d13009d3e8 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 24 Jan 2020 14:22:06 +0000
+Subject: [PATCH] drm/fourcc: Add packed 10bit YUV 4:2:0 format
+
+Adds a format that is 3 10bit YUV 4:2:0 samples packed into
+a 32bit work (with 2 spare bits).
+
+Supported on Broadcom BCM2711 chips.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/drm_fourcc.c | 3 +++
+ include/uapi/drm/drm_fourcc.h | 11 +++++++++++
+ 2 files changed, 14 insertions(+)
+
+--- a/drivers/gpu/drm/drm_fourcc.c
++++ b/drivers/gpu/drm/drm_fourcc.c
+@@ -274,6 +274,9 @@ const struct drm_format_info *__drm_form
+ { .format = DRM_FORMAT_YUV420_10BIT, .depth = 0,
+ .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2,
+ .is_yuv = true },
++ { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2,
++ .char_per_block = { 4, 4, 0 }, .block_w = { 3, 0, 0 }, .block_h = { 1, 0, 0 },
++ .hsub = 2, .vsub = 2, .is_yuv = true},
+ };
+
+ unsigned int i;
+--- a/include/uapi/drm/drm_fourcc.h
++++ b/include/uapi/drm/drm_fourcc.h
+@@ -266,6 +266,13 @@ extern "C" {
+ #define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane 16 bits per channel */
+
+ /*
++ * 2 plane YCbCr MSB aligned, 3 pixels packed into 4 bytes.
++ * index 0 = Y plane, [31:0] x:Y2:Y1:Y0 2:10:10:10 little endian
++ * index 1 = Cr:Cb plane, [63:0] x:Cr2:Cb2:Cr1:x:Cb1:Cr0:Cb0 [2:10:10:10:2:10:10:10] little endian
++ */
++#define DRM_FORMAT_P030 fourcc_code('P', '0', '3', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel packed */
++
++/*
+ * 3 plane YCbCr
+ * index 0: Y plane, [7:0] Y
+ * index 1: Cb plane, [7:0] Cb
+@@ -593,6 +600,10 @@ extern "C" {
+ * and UV. Some SAND-using hardware stores UV in a separate tiled
+ * image from Y to reduce the column height, which is not supported
+ * with these modifiers.
++ *
++ * The DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT modifier is also
++ * supported for DRM_FORMAT_P030 where the columns remain as 128 bytes
++ * wide, but as this is a 10 bpp format that translates to 96 pixels.
+ */
+
+ #define DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(v) \
diff --git a/target/linux/bcm27xx/patches-5.4/950-0474-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0474-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch
new file mode 100644
index 0000000000..f6264ff04a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0474-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch
@@ -0,0 +1,71 @@
+From 531d3d5c89825bade52f4257d264bbb06775a6fa Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 24 Jan 2020 14:24:33 +0000
+Subject: [PATCH] drm/vc4: Add DRM_FORMAT_P030 support to firmware-kms
+
+Adds support for this format which is 3 10bit samples packed into
+4 bytes, as used by the HEVC codec block.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 21 ++++++++++++++++++++-
+ drivers/gpu/drm/vc4/vc_image_types.h | 4 ++++
+ 2 files changed, 24 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -216,6 +216,10 @@ static const struct vc_image_format {
+ .vc_image = VC_IMAGE_YUV420SP,
+ .is_vu = 1,
+ },
++ {
++ .drm = DRM_FORMAT_P030,
++ .vc_image = VC_IMAGE_YUV10COL,
++ },
+ };
+
+ static const struct vc_image_format *vc4_get_vc_image_fmt(u32 drm_format)
+@@ -622,7 +626,15 @@ static int vc4_plane_to_mb(struct drm_pl
+ }
+ break;
+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
+- mb->plane.vc_image_type = VC_IMAGE_YUV_UV;
++ switch (mb->plane.vc_image_type) {
++ case VC_IMAGE_YUV420SP:
++ mb->plane.vc_image_type = VC_IMAGE_YUV_UV;
++ break;
++ /* VC_IMAGE_YUV10COL could be included in here, but it is only
++ * valid as a SAND128 format, so the table at the top will have
++ * already set the correct format.
++ */
++ }
+ /* Note that the column pitch is passed across in lines, not
+ * bytes.
+ */
+@@ -707,6 +719,13 @@ static bool vc4_fkms_format_mod_supporte
+ case DRM_FORMAT_MOD_BROADCOM_SAND128:
+ return true;
+ default:
++ return false;
++ }
++ case DRM_FORMAT_P030:
++ switch (fourcc_mod_broadcom_mod(modifier)) {
++ case DRM_FORMAT_MOD_BROADCOM_SAND128:
++ return true;
++ default:
+ return false;
+ }
+ case DRM_FORMAT_NV21:
+--- a/drivers/gpu/drm/vc4/vc_image_types.h
++++ b/drivers/gpu/drm/vc4/vc_image_types.h
+@@ -139,6 +139,10 @@ enum {
+ VC_IMAGE_YUV_UV_16,
+ /* YUV4:2:0 with U,V in side-by-side format */
+ VC_IMAGE_YUV420_S,
++ /* 10-bit YUV 420 column image format */
++ VC_IMAGE_YUV10COL,
++ /* 32-bpp, 10-bit R/G/B, 2-bit Alpha */
++ VC_IMAGE_RGBA1010102,
+
+ VC_IMAGE_MAX, /* bounds for error checking */
+ VC_IMAGE_FORCE_ENUM_16BIT = 0xffff,