[PATCH] ARM: dts: integrator: Fix DMA ranges
Arnd Bergmann
arnd at arndb.de
Fri Sep 23 04:58:10 PDT 2022
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 at 1000000 {
> /* 640x480 16bpp @ 25.175MHz is 36827428 bytes/s */
> max-memory-bandwidth = <40000000>;
> memory-region = <&impd1_ram>;
> + dma-ranges;
> + dma-coherent;
>
> port at 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 at c0000000 {
> lm0: bus at 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
More information about the linux-arm-kernel
mailing list