diff options
author | Álvaro Fernández Rojas <noltari@gmail.com> | 2020-03-16 20:41:03 +0100 |
---|---|---|
committer | Álvaro Fernández Rojas <noltari@gmail.com> | 2020-03-16 21:24:23 +0100 |
commit | 0f6d04457a64f2393b05f662dc8d381ea1963c66 (patch) | |
tree | 2d6a3c82d5e6d02b030b16df66da8bf9209b02ec /target/linux/bcm27xx | |
parent | d890f85e59617228b1e76e8cf45a9309904d9124 (diff) | |
download | upstream-0f6d04457a64f2393b05f662dc8d381ea1963c66.tar.gz upstream-0f6d04457a64f2393b05f662dc8d381ea1963c66.tar.bz2 upstream-0f6d04457a64f2393b05f662dc8d381ea1963c66.zip |
bcm27xx: sync 5.4 patches with RPi Foundation
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx')
-rw-r--r-- | target/linux/bcm27xx/bcm2708/config-5.4 | 4 | ||||
-rw-r--r-- | target/linux/bcm27xx/bcm2709/config-5.4 | 14 | ||||
-rw-r--r-- | target/linux/bcm27xx/bcm2710/config-5.4 | 9 | ||||
-rw-r--r-- | target/linux/bcm27xx/bcm2711/config-5.4 | 10 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0205-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch | 1187 | ||||
-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.patch | 569 | ||||
-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.patch | 543 | ||||
-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.patch | 1428 | ||||
-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.patch | 25 | ||||
-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.patch | 945 | ||||
-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.patch | 27 | ||||
-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-.patch | 713 | ||||
-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.patch | 77 | ||||
-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.patch | 25 | ||||
-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.patch | 148 | ||||
-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.patch | 88 | ||||
-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.patch | 26 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0438-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch | 34 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0439-of-overlay-Correct-symbol-path-fixups.patch | 37 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0440-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch | 25 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0441-bcm2835-dma-Correct-SoC-name.patch | 489 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0441-of-address-Introduce-of_get_next_dma_parent-helper.patch | 39 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0442-of-address-Follow-DMA-parent-for-dma-coherent.patch | 30 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0443-of-Factor-out-addr-size-cells-parsing.patch | 117 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0444-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch | 40 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0444-pcie-brcmstb-Correct-SoC-name.patch | 96 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0445-of-Make-of_dma_get_range-work-on-bus-nodes.patch | 107 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0446-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch | 30 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0447-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch | 117 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0448-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch | 174 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0449-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch | 84 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0450-resource-Add-a-resource_list_first_type-helper.patch | 36 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0451-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch | 195 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0452-x86-PCI-sta2x11-use-default-DMA-address-translation.patch | 259 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0453-PCI-of-Add-inbound-resource-parsing-to-helpers.patch | 427 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0454-dma-direct-unify-the-dma_capable-definitions.patch | 103 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0455-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch | 69 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0456-dma-direct-exclude-dma_direct_map_resource-from-the-.patch | 115 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0457-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch | 366 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0458-ARM-dts-bcm2711-Enable-PCIe-controller.patch | 56 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0459-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch | 810 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0460-PCI-brcmstb-Add-MSI-support.patch | 383 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0461-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch | 38 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0462-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch | 75 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0463-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch | 156 | ||||
-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-.patch | 25 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0466-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch | 26 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0467-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch | 74 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0468-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch | 407 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0469-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch | 277 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0470-media-ov5647-Add-extra-10-bit-sensor-modes.patch | 549 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0471-media-ov5647-change-defaults-to-better-match-raw-cam.patch | 59 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0472-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch | 79 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0473-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch | 55 | ||||
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0474-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch | 71 |
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, ®); ++ 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, ®); ++ 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, |