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.

Linux/AM5728: GPMC: accessing an external Memory/FGPA

Part Number: AM5728
Other Parts Discussed in Thread: AM5708

Tool/software: Linux

Hi,

we are planning to connect a FPGA to the AM5728 using the GPMC interface and memory mapped access. At Linux I only found a gmpc NAND driver. Can we use this driver to configure a generic memory mapped device via GPMC?

Is there an example doing this?

best regards,

Joerg

  • Hello Joerg,

    Please refer to the following thread as a reference.

    Regards,

    Krunal

  • Thank you for the link. I was able to make the GPMC interface alive with linux. Next step is tuning the timing and prepare correct memory mapping to have access from the DSPs memory space.

    Little bug at the driver omap_gpmc.c which costs some time:
    At the device tree I wrote the property "gpmc,bank-width" but the correct name for NOR device is only "bank-width". but the driver has no error message for that and simply quitts (at Kernel 4.9.41).
    Newer kernel versions have an error message here, but it is wrong ("has no 'gpmc,device-width'" instead of "has no 'bank-width'")
  • Hello Joerg,

    Thank you for the update and I believe the issue is fixed in kernel 4.14.79. In the driver, it reads no 'bank-width'.

    Regards,
    Krunal

  • Hello Joerg,

    I am also in same line like you and planning to interface FPGA/NVSRAM to custom AM5708 via GPMC as NOR flash like devices.

    Can you please help me by sharing your inputs on any driver changes required for the above and how to achieve communication b/w fpga/nvsram and cpu.

    Thanks,
    Narayanan
  • Hi Narayanan,

    Sure, there was no driver modification neccessary. The bug mentioned above was only a missing debug message. I only have to set up the device tree for my GPMC configuration.
    My device tree modifications are:

    For the pin configuration

    &dra7_pmx_core {
    gpmc_fpga_pins_default: gpmc_fpga_pins_default {
    pinctrl-single,pins = <
    0x00 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad0 */
    0x04 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad1 */
    0x08 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad2 */
    0x0C (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad3 */
    0x10 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad4 */
    0x14 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad5 */
    0x18 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad6 */
    0x1C (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad7 */
    0x20 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad8 */
    0x24 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad9 */
    0x28 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad10 */
    0x2C (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad11 */
    0x30 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad12 */
    0x34 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad13 */
    0x38 (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad14 */
    0x3C (PIN_INPUT_SLEW | MUX_MODE0) /* gpmc_ad15 */
    0xB4 (PIN_OUTPUT_PULLUP | SLEWCONTROL | MUX_MODE0) /* gpmc_cs0 */
    0xC4 (PIN_OUTPUT | SLEWCONTROL | MUX_MODE0) /* gpmc_advn_ale */
    0xC8 (PIN_OUTPUT | SLEWCONTROL | MUX_MODE0) /* gpmc_oen_ren */
    0xCC (PIN_OUTPUT | SLEWCONTROL | MUX_MODE0) /* gpmc_wen */
    0xD0 (PIN_OUTPUT | SLEWCONTROL | MUX_MODE0) /* gpmc_ben0 */
    0xD8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0 */
    >;
    };
    -------------------------------

    and for the GPMC configuration:
    (the "nand" is defined elsewhere at the device tree of the board manufacturer, so I have to disable it here,
    the basic configuration of the GPMC unit can be found at the linux sources in the file arch/arm/boot/dts/dra7.dtsi)
    ----------------------------
    &gpmc {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&gpmc_fpga_pins_default>;

    ranges = <0 0 0x08000000 0x01000000>; /* CS0: 16MBytes */

    nand@0,0 {
    status = "disabled";
    };
    nor {
    bank-width = <2>; /* 1 = 8Bit, 2 = 16Bit */

    reg = <0 0 0x01000000>; /*CSn0, start addr 0, length 16M */
    #address-cells = <1>;
    #size-cells = <1>;

    gpmc,mux-add-data = <2>; /* 1 = Addr-Addr-Data multiplex, 2 = Addr-Data multiplex */
    gpmc,async-read; /* GPMC_CONFIG1_READTYPE_ASYNC */
    gpmc,async-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */
    /* gpmc,clk-activation-ns = <20>;*/ /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */

    /* CONFIG2 Timings */
    gpmc,sync-clk-ps = <0>; /* Minimum clock period for synchronous mode, in picoseconds */
    gpmc,cs-on-ns = <0>; /* Assertion time */
    gpmc,cs-rd-off-ns = <40>; /* Read deassertion time */
    gpmc,cs-wr-off-ns = <90>; /* Write deassertion time */

    /* CONFIG3 ADV signal timings (in nanoseconds) */
    gpmc,adv-on-ns = <0>; /* Assertion time */
    gpmc,adv-rd-off-ns = <10>; /* Read deassertion time */
    gpmc,adv-wr-off-ns = <10>; /* Write deassertion time */

    /* GPMC_CONFIG4 WE and OE signals timings (in nanoseconds) */
    gpmc,we-on-ns = <30>;
    gpmc,we-off-ns = <60>;
    gpmc,oe-on-ns = <20>; /* Read Access: after this time OE will go low (active) */
    gpmc,oe-off-ns = <40>; /* Read Access: after this time OE will be deasserted (high) */

    /* CONFIG 5 */
    /*gpmc,page-burst-access-ns = <20>;*/
    gpmc,access-ns = <30>; /* Start-cycle to first data valid delay (RDACCESSTIME) */
    gpmc,rd-cycle-ns = <40>; /* Total read cycle time */
    gpmc,wr-cycle-ns = <90>; /* Total write cycle time */

    /* CONFIG 6*/
    gpmc,wr-access-ns = <40>;
    gpmc,wr-data-mux-bus-ns = <0>;
    gpmc,bus-turnaround-ns = <0>;
    gpmc,cycle2cycle-delay-ns = <0>;
    gpmc,clk-activation-ns = <0>;
    };
    };

    Check for success after boot:

    dmesg | grep gpmc

    should deliver an output like this:

    [ 0.294787] omap-gpmc 50000000.gpmc: could not find pctldev for node /ocp/l4@4a000000/scm@2000/pinmux@1400/gpmc_fpga_pins_default, deferring probe
    [ 2.141790] omap-gpmc 50000000.gpmc: gpmc_probe2
    [ 2.146542] omap-gpmc 50000000.gpmc: GPMC revision 6.0
    [ 2.151706] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000

    (first message with "could not find...." cann be ignored)

    To test the access you can use the tool devmem2 for reading and writing to/from physical addresses.
    e.g.
    devmem2 0x08000000 h
    to read a 16-Bit half word from the first memory cell (with my GPMC setup)

    you should see some togglings at the GPCM hardware signals during read/write access.

    hope that helps a little bit.

    regards,
    Joerg
  • Hi Joerg,

    Thank you so much for your help.

    Can you please let know, how to calculate timing parameters? Are they provided by device vendor(fpga)? or you calculated by your own?

    Best Regards,
    Narayanan
  • Hi Narayanan,

    you can have a look into the Technical Reference Manual of the Chip (should be a chapter about external Signals of the GPMC) or just take an oscilloscope or logic analyser and try it.
    I have not adjusted the timings to our needs because I am waiting for my collegues to get the timing requirements of the FPGA design.
    regards,
    Joerg
  • Hello Joe,

    Still we don't have any luck to read/write fpga memory region from linux console.

    root@am57xx-evm:~# devmem2 0x12000000
    /dev/mem opened.
    Memory mapped at address 0xb6f0f000.
    Read at address 0x12000000 (0xb6f0f000): 0x00000000
    root@am57xx-evm:~# devmem2 0x12000784
    /dev/mem opened.
    Memory mapped at address 0xb6f61000.
    Read at address 0x12000784 (0xb6f61784): 0x00000000
    root@am57xx-evm:~#
    root@am57xx-evm:~# devmem2 0x12000784 w 0xaaaaaaaa
    /dev/mem opened.
    Memory mapped at address 0xb6fe7000.
    Read at address 0x12000784 (0xb6fe7784): 0x00000000
    Write at address 0x12000784 (0xb6fe7784): 0xAAAAAAAA, readback 0xAAAAAAAA
    root@am57xx-evm:~#

    During read i can able to toggle at CS2(using for fpga) and OE signal. I can able to write to fpga registers and all remaining register locations also filled with same data but after reboot of setup, registers are filled with zeros.

    I verified that all control signals(CS,WE and OE) are proper at fpga from CPU but able to succeed and in parallel trying to tune timing parameters to get access with fpga address region but i am thinking that there should to standard procedure to get suitable timing parameters to achieve fpga access from CPU.

    Best Regards,
    Narayanan
  • Hello Narayanan,

    meanwhile I got quite the same results like you (We could write correctly but read access always returns 0).
    I read a bit through the forum here and found the solution at the thread  e2e.ti.com/.../778001

    You have to delclare the GPMC_CLK pin as INPUT not OUTPUT (like I did). Then synchronous read cycles work like expected.

    hope that solves your problem also.

    regards,
    Joerg

  • Hello Joerg,

    We are operating GPMC in asynchronous mode so no need of GPMC_CLK and we are using it for i2c3_scl.

    Best Regards,
    Narayanan