This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM6442: What is the correct way to make multiple ChipSelect assignments for the GPMC using the Linux Device Tree configuration?

Part Number: AM6442


Tool/software:

Hello,

I'm trying to make use of the default GPMC driver (omap-gpmc.c) in order to interface some hardware to the GPMC. As far as I understood, the omap-gpmc driver is somewhat dedicated to interfacing things like NAND- or NOR-Flashes, which is not what I intend to do. However, the omap-gpmc driver seems as a very good starting point and I'd try to exploit most of the default function here.

Right now I'm struggling to assign address windows to individual ChipSelects. 

My entry within the device tree file is looking like that right now:

&gpmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&gpmc0_pins_default>;
        assigned-clocks = <&k3_clks 80 0>;
        assigned-clock-parents = <&k3_clks 80 1>;
        assigned-clock-rates = <66666667>;
        //assigned-clock-rates = <100000000>;
        gpmc,num-cs = <4>;
        ranges = <0 0 0x00 0x50000000 0x01000000>, /* CS0 space. Min partition = 16MB */
                 <1 0 0x00 0x51000000 0x01000000>, /* CS1 space. Min partition = 16MB */
                 <2 0 0x00 0x52000000 0x01000000>, /* CS2 space. Min partition = 16MB */
                 <3 0 0x00 0x53000000 0x01000000>; /* CS3 space. Min partition = 16MB */
        status = "okay";
};

So there are 4 windows, each 16MiB in size, assigned to ChipSelects 0, 1, 2, and 3 starting at the given adresses (which are within the GPMC data window, of course).

I'm not sure whether this is needed, but I did also add that line gpmc,num-cs = <4>; in order to signal that there are four ChipSelects available.

When I'm building the device tree (make linux-dtbs) and boot with it, dmesg | grep gpmc is showing me the following:

[    1.154690] omap-gpmc 3b000000.memory-controller: GPMC revision 6.0
[    1.161173] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000

The first line is ok and is indicating that the omap-gpmc is running, while the second line is highly questionable to me.

Firstly, why it is writing disabling cs 0? Secondly, what does that 0x0-0x1000000 mean - it should report 0x51000000-0x51000000? And thirdly what about the remaining three ChipSelects?

There is also some question about what that third entry within each range-entry does mean, actually. I checked the Linux documentation regarding the device tree settings for omap-gpmc, which is also available here:

www.kernel.org/.../omap-gpmc.txt

According to that documentation, a range tuple has to have the form:

<cs-number> 0 <physical address of mapping> <size>

When I try that format, I receive a warning during device tree compilation.  

The format I did use above with that additional 0x00 parameter I did actually copy from the default device tree file where there is a single ChipSelect assignment present that is looking like:

ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */

Btw., this default setting is also showing me disabling cs 0...

I did not yet dig deeper into omap-gpmc.c in order to possibly find out what is going on there. Perhaps there are some simple solutions here. In general, it seems rather difficult to find some exemplary documentations about the GPMC module.

Thanks for any insights,

Mario

  • Hi Mario,

    [    1.161173] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000

    This message is misleading. You can ignore it. We have an internal ticket to remove this message.

    I will look into your other questions soon.

  • Hi Bin,

    aha, good to know. Thanks for that.

    In the mean time I spent several hours collecting various fragments of information and I believe I'm also generally making something wrong here. What seems certainly needed as well is to provide "child"-sections to the gpmc-section of the device tree. I.e. there should also be four child sections where each is describing the timing characteristics and other settings associated with that according channel/ChipSelect.

    The final goal is to set up these four address windows and then drive transactions onto an attached FPGA. I think that it is rather simple to set these things up through the device tree settings - if one knows what to do.... At the moment it seems that I'm probably faster off when I drop this and hardcode various GPMC register settings by manipulating the omap-gpmc driver. But of course this is not a very good way.

    Greetings,

    Mario

  • As an update:

    I just made this setup in board-support/ti-linux-kernel-6.12.17+git-ti/arch/arm64/boot/dts/ti/k3-am642-evm.dtb:

    &gpmc0 {
            pinctrl-names = "default";
            pinctrl-0 = <&gpmc0_pins_default>;
            assigned-clocks = <&k3_clks 80 0>;
            assigned-clock-parents = <&k3_clks 80 1>;
            assigned-clock-rates = <66666667>;

            gpmc,num-cs = <4>;

            ranges = <0 0 0x00 0x50000000 0x01000000   /* CS0 space. Min partition = 16MB */
                      1 0 0x00 0x51000000 0x01000000   /* CS1 space. Min partition = 16MB */
                      2 0 0x00 0x52000000 0x01000000   /* CS2 space. Min partition = 16MB */
                      3 0 0x00 0x53000000 0x01000000>; /* CS3 space. Min partition = 16MB */
            status = "okay";

            fpga@0,0{
                    reg = <0 0 0x001000000>;
            };
            fpga@1,0{
                    reg = <1 0 0x001000000>;
            };
            fpga@2,0{
                    reg = <2 0 0x001000000>;
            };
            fpga@3,0{
                    reg = <3 0 0x001000000>;
            };
    };

    Right now I can't tell whether the mappings are ok. But I'm receiving lots of configuration information through dmesg about all four channels - probably with default values. (I did enable CONFIG_OMAP_GPMC_DEBUG=y in defconfig for building the Linux kernel.) I think I can build on that, fill in individual timing parameters and then see how things are progressing. A good summary about all these parameters can be found in the Linux kernel in Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml.

    Nonetheless, there remains some uncertainity about this fifth parameter of each tuple in ranges which is usually filled in with 0x00 although all documentation that can be found is going with four parameters per tuple. The way the tuples are listed is also kind of strange. In my recent version I put all four tuples into a single set of <> braces without any separator. In my example in my initial post I put each tuple into an individual set of <> braces and separated them by comma.  Maybe both notations are valid ones.

  • I just want to confirm that the framework for the device tree settings I did show above is working (as per SDK 11.00.09.04). Although I did slightly change the ranges notation for the sake of a better readability. I.e.:

            ranges = <0 0 0x00 0x50000000 0x01000000>, /* CS0 space. Min partition = 16MB */
                     <1 0 0x00 0x51000000 0x01000000>, /* CS1 space. Min partition = 16MB */
                     <2 0 0x00 0x52000000 0x01000000>, /* CS2 space. Min partition = 16MB */
                     <3 0 0x00 0x53000000 0x01000000>; /* CS3 space. Min partition = 16MB */ 

    Of course, various parameters  still need to be filled in before the  GPMC can be used.

    Following that, individual address windows might be mapped via mmap() from /dev/mem by a user space process and then accessed.

    Nonetheless, I'd like to encourage Texas Instruments to add a GPMC documentation section here: https://software-dl.ti.com/processor-sdk-linux/esd/AM64X/latest/exports/docs/linux/Foundational_Components_Kernel_Drivers.html containing a few words about how to set up and make use of the GPMC module. Actually, this is really simple - if you know what to do....