On Fri, Sep 23, 2022, at 1:38 PM, Linus Walleij wrote:
A recent change affecting the behaviour of phys_to_dma() to actually require the device tree ranges to work unmasked a bug in the Integrator DMA ranges.
The PL110 uses the CMA allocator to obtain coherent allocations from a dedicated 1MB video memory, leading to the following call chain:
drm_gem_cma_create() dma_alloc_attrs() dma_alloc_from_dev_coherent() __dma_alloc_from_coherent() dma_get_device_base() phys_to_dma() translate_phys_to_dma()
phys_to_dma() by way of translate_phys_to_dma() will nowadays not provide 1:1 mappings unless the ranges are properly defined in the device tree and reflected into the dev->dma_range_map.
I don't understand this yet, what did the kernel previously do to that allowed the correct DMA mapping when a wrong address was set in the DT?
There is a bug in the device trees because the DMA ranges are incorrectly specified, and the patch uncovers this bug.
Solution:
- Fix the LB (logic bus) ranges to be 1-to-1 like they should have always been.
- Provide a 1:1 dma-ranges attribute to the PL110.
- Mark the PL110 display controller as DMA coherent.
Are you sure the actually coherent? I'm not aware of any other ARM9 based SoC with cache-coherent DMA. What is the DMA master that accesses
diff --git a/arch/arm/boot/dts/integratorap-im-pd1.dts b/arch/arm/boot/dts/integratorap-im-pd1.dts index 31724753d3f3..ecccbd1777a3 100644 --- a/arch/arm/boot/dts/integratorap-im-pd1.dts +++ b/arch/arm/boot/dts/integratorap-im-pd1.dts @@ -248,6 +248,8 @@ display@1000000 { /* 640x480 16bpp @ 25.175MHz is 36827428 bytes/s */ max-memory-bandwidth = <40000000>; memory-region = <&impd1_ram>;
dma-ranges;
dma-coherent;
port@0 { #address-cells = <1>;
Which device is the actual DMA master here? The "dma-coherent" property sets the pl110 as coherent, but the dma-ranges property would refer to the port, right?
diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index c983435ed492..9148287fa0a9 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts @@ -262,7 +262,7 @@ bus@c0000000 { lm0: bus@c0000000 { compatible = "simple-bus"; ranges = <0x00000000 0xc0000000 0x10000000>;
dma-ranges = <0x00000000 0x80000000 0x10000000>;
dma-ranges = <0x00000000 0xc0000000 0x10000000>;
In your description, you say that you set a 1:1 map, but this is not what you seem to be setting here. Instead you map DMA address zero to point to the beginning of RAM.
Arnd