arm64: dts: qcom: msm8916: Reserve firmware memory dynamically
authorStephan Gerhold <stephan@gerhold.net>
Mon, 11 Sep 2023 17:41:46 +0000 (19:41 +0200)
committerBjorn Andersson <andersson@kernel.org>
Wed, 20 Sep 2023 16:27:44 +0000 (09:27 -0700)
Most of the reserved firmware memory on MSM8916 can be relocated when
respecting the required alignment. To avoid having to precompute the
reserved memory regions in every board DT, describe the actual
requirements (size, alignment, alloc-ranges) using the dynamic reserved
memory allocation.

This approach has several advantages:

 1. We can define "templates" for the reserved memory regions in
    msm8916.dtsi and keep only device-specific details in the board DT.
    This is useful for the "mpss" region size for example, which varies
    from device to device. It is no longer necessary to redefine all
    firmware regions to shift their addresses.

 2. When some of the functionality (e.g. WCNSS, Modem, Venus) is not
    enabled or needed for a device, the reserved memory can stay
    disabled, freeing up the unused reservation for Linux.

 3. Devices with special requirements for one of the firmware regions
    are handled automatically. For example, msm8916-longcheer-l8150
    has non-relocatable "wcnss" firmware that must be loaded exactly
    at address 0x8b600000. When this is defined as a static region,
    the other dynamic allocations automatically adjust to a different
    place with suitable alignment.

All in all this approach significantly reduces the boilerplate necessary
to define the different firmware regions, and makes it easier to enable
functionality on the different devices.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Link: https://lore.kernel.org/r/20230911-msm8916-rmem-v1-4-b7089ec3e3a1@gerhold.net
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
arch/arm64/boot/dts/qcom/msm8916.dtsi

index a0bb8de54fb66ec4f85078d89eab7e5cd38f42c3..503155aefa55dcd62c5ffcb78d039d194e5cbaac 100644 (file)
                stdout-path = "serial0";
        };
 
+       /*
+        * For some reason, the signed wcnss firmware is not relocatable.
+        * It must be loaded at 0x8b600000. All other firmware is relocatable,
+        * so place wcnss at the fixed address and then all other firmware
+        * regions will be automatically allocated at a fitting place.
+        */
        reserved-memory {
-               /* wcnss.mdt is not relocatable, so it must be loaded at 0x8b600000 */
-               /delete-node/ wcnss@89300000;
+               /delete-node/ wcnss;
 
                wcnss_mem: wcnss@8b600000 {
                        reg = <0x0 0x8b600000 0x0 0x600000>;
index 69f268db4df901ab13988e6457f00318c1ceec17..1d92c2e57216a237c32b3bb72be85718bab931d1 100644 (file)
                stdout-path = "serial0";
        };
 
-       reserved-memory {
-               mpss_mem: mpss@86800000 {
-                       reg = <0x0 0x86800000 0x0 0x5500000>;
-                       no-map;
-               };
-       };
-
        gpio-keys {
                compatible = "gpio-keys";
 
        status = "okay";
 };
 
+&mpss_mem {
+       reg = <0x0 0x86800000 0x0 0x5500000>;
+};
+
 &pm8916_usbin {
        status = "okay";
 };
index 9326ba0ea245c37af7c3243da4fa22a37e8d8570..840ae8a1987725a8e3dc548ae525d22122b3de19 100644 (file)
                };
 
                mpss_mem: mpss@86800000 {
+                       /*
+                        * The memory region for the mpss firmware is generally
+                        * relocatable and could be allocated dynamically.
+                        * However, many firmware versions tend to fail when
+                        * loaded to some special addresses, so it is hard to
+                        * define reliable alloc-ranges.
+                        *
+                        * alignment = <0x0 0x400000>;
+                        * alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
+                        */
                        reg = <0x0 0x86800000 0x0 0x2b00000>;
                        no-map;
                };
 
-               wcnss_mem: wcnss@89300000 {
-                       reg = <0x0 0x89300000 0x0 0x600000>;
+               wcnss_mem: wcnss {
+                       size = <0x0 0x600000>;
+                       alignment = <0x0 0x100000>;
+                       alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
                        no-map;
                };
 
-               venus_mem: venus@89900000 {
-                       reg = <0x0 0x89900000 0x0 0x600000>;
+               venus_mem: venus {
+                       size = <0x0 0x600000>;
+                       alignment = <0x0 0x100000>;
+                       alloc-ranges = <0x0 0x86800000 0x0 0x8000000>;
                        no-map;
                };