Search code examples
memorykerneldriverdts

Allocating boot time memory using dts configuration


I am working with a particular encoder which uses 512M boot time allocated memory. I am supposed to allocate the memory through dts file configuration. The physical memory is devided into low and high as below in the dts file:

    /* 256MB at 0x0 */
    memory@0 {
            device_type = "memory";
            reg =  <0x0 0x00000000 0x0 0x10000000>;
    };

    /* 2GB at 0x8010000000 */
    memory@8000000000 {
            device_type = "memory";
            reg =  <0x80 0x10000000 0x0 0x80000000>;
    };

Now I want to allocate the boot time carved out memory from the high memory. I can think of creating a dts entry as below

encoder: encoder@0xxxxxxxxx {
    compatible = "xyz, abc";
    reg=    <0x0 0x80000000 0x0 0x20000000>;
}  

Here the encoder@xxxx is the actual device entry and it has already a set of register region as below:

    encoder: encoder@0xxxxxxxxx{
        compatible = "xyz, abc";
        #address-cells = <1>;
        #size-cells = <1>;
        reg = <0x0 0xxxxxxxxxx 0x0 0x1234>;
        status = "disabled";
    };

So after adding the carvedout memory the entry would look like this:

    encoder: encoder@0xxxxxxxxx{
        compatible = "xyz, abc";
        #address-cells = <1>;
        #size-cells = <1>;
        reg = <0x0 0xxxxxxxxxx 0x0 0x1234>;
        reg=  <0x0 0x80000000 0x0 0x20000000>;
        status = "disabled";
    };

Would this work? I am not sure though how the driver code would know where is the start address of the carved out memory and the size of it? Can anyone please help?
Thanks.


Solution

  • I have achieved this by creating curving out memory from the lower part of the high memory for my device. To do this I modified my dtsi file to reflect the mew memory map as below:

    /* 256MB at 0x0 - this is the low memory region*/
            memory@0 {
                    device_type = "memory";
                    reg =  <0x0 0x00000000 0x0 0x10000000>;
            };
    
            /* 1GB at 0x8010000000 - high memory region, this used to be 2GB earlier. I curved out to 1GB and allocated 1GB to my device*/
            memory@8000000000 {
                    device_type = "memory";
                    reg =  <0x80 0x10000000 0x0 0x40000000>;
            };
    
    
    
    /* 1GB carved out for my device.*/
            my_device: mydevice@8050000000 {
                    compatible = "xxx,xxx-yyy";
                    reg = <0x00 0x20810000 0x0 0x010000>,
                          **<0x80 0x50000000 0x0 0x40000000>;**
                    interrupts = <GIC_SHARED xx IRQ_TYPE_LEVEL_HIGH>;
                    status = "disabled";
            };
    

    Allocation of 1GB was a bit too much and I have modified to it to 256MB but that is not important here.

    Then in the driver I retried the memory details as below:

    struct resource *res;
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0); /*this is to get hold of the the registers of my device*/
    
    res = platform_get_resource(pdev, IORESOURCE_MEM, 1); /* this is the device memory for my device which had been set aside in the dtsi file above.*/
    
    For using the memories retrieve as above use the below:
    
    res->start /* start address of the memory region */
    res->end - res->start + 1 /* this is to calculate the size of the memory*/
    devm_ioremap_resource(&pdev->dev, res); /* this will give the mapped kernel virtual address for the memory bank*/