diff --git a/Documentation/devicetree/bindings/display/apple,dcp.yaml b/Documentation/devicetree/bindings/display/apple,dcp.yaml index 38be82bc7d1bd..dbb2234164d7e 100644 --- a/Documentation/devicetree/bindings/display/apple,dcp.yaml +++ b/Documentation/devicetree/bindings/display/apple,dcp.yaml @@ -72,6 +72,8 @@ properties: power-domains: maxItems: 1 + dma-noncoherent: true + resets: maxItems: 1 @@ -299,6 +301,7 @@ properties: properties: iommus: maxItems: 1 + dma-noncoherent: true memory-region: minItems: 1 maxItems: 64 diff --git a/Documentation/devicetree/bindings/gpu/apple,agx.yaml b/Documentation/devicetree/bindings/gpu/apple,agx.yaml index f5b1afd7d7dd3..2004c43d42b1d 100644 --- a/Documentation/devicetree/bindings/gpu/apple,agx.yaml +++ b/Documentation/devicetree/bindings/gpu/apple,agx.yaml @@ -40,6 +40,8 @@ properties: power-domains: maxItems: 1 + dma-noncoherent: true + mboxes: minItems: 1 maxItems: 2 diff --git a/arch/arm64/boot/dts/apple/t6040.dtsi b/arch/arm64/boot/dts/apple/t6040.dtsi index 961af1b7b5bd4..b909d0c197f77 100644 --- a/arch/arm64/boot/dts/apple/t6040.dtsi +++ b/arch/arm64/boot/dts/apple/t6040.dtsi @@ -522,7 +522,6 @@ display: display-subsystem { compatible = "apple,display-subsystem"; iommus = <&disp0_dart 0>; - dma-noncoherent; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/apple/t8132-j713-display.dtsi b/arch/arm64/boot/dts/apple/t8132-j713-display.dtsi index d35e9fc89a2a3..e3cb6864c54d6 100644 --- a/arch/arm64/boot/dts/apple/t8132-j713-display.dtsi +++ b/arch/arm64/boot/dts/apple/t8132-j713-display.dtsi @@ -16,6 +16,8 @@ * frontend mappings it adds memory-region and apple,j713-inherited-mappings * to piodma and display-subsystem and enables them and disp0_dart. * apple,j713-native-piodma and apple,j713-native-scanout opt in to that. + * The DCP, PIODMA and scanout paths use non-coherent DMA only, so those + * nodes are marked dma-noncoherent. * The DART driver also reads the ADT through the loader's phram "adt" * region. Without that handoff the DCP and frontend are refused. * @@ -81,6 +83,7 @@ mbox-names = "mbox"; iommus = <&dcp_dart 23>; power-domains = <&ps_disp_cpu>; + dma-noncoherent; apple,j713-native-piodma; apple,j713-native-scanout; /* Full 2560x1664 panel including the notch rows, 224 ppi. */ @@ -91,6 +94,7 @@ disp0_piodma: piodma { iommus = <&disp0_dart 16>; + dma-noncoherent; status = "disabled"; /* Enabled by the loader. */ }; }; @@ -98,6 +102,7 @@ display: display-subsystem { compatible = "apple,t8132-display-subsystem", "apple,t8132-display-diagnostics"; iommus = <&disp0_dart 0>; + dma-noncoherent; status = "disabled"; /* Enabled by the loader. */ }; }; diff --git a/arch/arm64/boot/dts/apple/t8132-j713-gpu.dtsi b/arch/arm64/boot/dts/apple/t8132-j713-gpu.dtsi index 7cddbaf1e5b56..7db8d5a4c16b7 100644 --- a/arch/arm64/boot/dts/apple/t8132-j713-gpu.dtsi +++ b/arch/arm64/boot/dts/apple/t8132-j713-gpu.dtsi @@ -69,6 +69,8 @@ reg-names = "asc", "sgx"; mboxes = <&agx_mbox>; power-domains = <&ps_gfx>; + /* G16 is admitted on non-coherent DMA only. */ + dma-noncoherent; apple,pmp = <&pmp>; memory-region = <&gpu_ttbs>, <&gpu_pagetables>, <&gpu_handoff>, <&gpu_shared_l2>, <&gpu_fw_text>, <&gpu_fw_data>; diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index e517dddb37499..a835ed06cba0d 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -42,12 +43,17 @@ void arch_setup_dma_ops(struct device *dev, bool coherent) { int cls = cache_line_size_of_cpu(); - if (!coherent && !CLIDR_LOC(read_sysreg(clidr_el1))) { + /* + * A device explicitly marked "dma-noncoherent" keeps non-coherent DMA: + * its driver may depend on the non-cacheable attributes of that path. + */ + if (!coherent && !CLIDR_LOC(read_sysreg(clidr_el1)) && + !device_property_present(dev, "dma-noncoherent")) { /* - * This holds for every device on the system, so say it once + * This holds for every other device on the system, so say it once * and keep the per-device line for debugging. */ - pr_info_once("CLIDR_EL1.LoC == 0, treating all devices as DMA coherent\n"); + pr_info_once("CLIDR_EL1.LoC == 0, treating devices not marked dma-noncoherent as DMA coherent\n"); dev_dbg(dev, "CLIDR_EL1.LoC == 0, treating as coherent\n"); coherent = true; }