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.

AM572x GPMC interface to FPGA

Other Parts Discussed in Thread: AM5728

Background:

Processor: AM5728
Goal: Interface to a FPGA from AM5728 via the GPMC interface.
Problem:
On boot up I see the following (dmesg | grep gpmc):
[ 0.379461] omap-gpmc 50000000.gpmc: could not find pctldev for node /ocp/l4@4a000000/scm@2000/pinmux@1400/gpmc_pins_up, deferring probe
[ 1.946078] omap-gpmc 50000000.gpmc: GPMC revision 6.0
[ 1.951244] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
[ 1.957527] gpiochip_add: registered GPIOs 510 to 511 on device: omap-gpmc
[ 1.957619] omap-gpmc 50000000.gpmc: cannot request GPMC CS 2
[ 1.963392] omap-gpmc 50000000.gpmc: failed to probe DT children
[ 1.969601] omap-gpmc: probe of 50000000.gpmc failed with error -16

Device Tree Configuration:
dra7.dtsi:


gpmc: gpmc@50000000 {


compatible = "ti,am3352-gpmc";
ti,hwmods = "gpmc";
reg = <0x50000000 0x37c>; /* device IO registers */
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&edma_xbar 4 0>;
dma-names = "rxtx";
gpmc,num-cs = <8>;
gpmc,num-waitpins = <2>;
#address-cells = <2>;
#size-cells = <1>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
status = "disabled";

};

Our additions (in separate device tree file):


gpmc_pins_up: gpmc_pins_up {


pinctrl-single,pins = <
0x044 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_a1.gpmc_a1 */
0x068 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE12) /* gpmc_a10.gpmc_a10 */
0x06C (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_a11.gpmc_a11 */
0x048 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_a2.gpmc_a2 */
0x04C (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE10) /* gpmc_a3.gpmc_a3 */
0x050 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE10) /* gpmc_a4.gpmc_a4 */
0x054 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_a5.gpmc_a5 */
0x058 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_a6.gpmc_a6 */
0x05C (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_a7.gpmc_a7 */
0x060 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE12) /* gpmc_a8.gpmc_a8 */
0x064 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE12) /* gpmc_a9.gpmc_a9 */
0x000 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad0.gpmc_ad0 */
0x004 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad1.gpmc_ad1 */
0x028 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad10.gpmc_ad10 */
0x02C (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad11.gpmc_ad11 */
0x030 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad12.gpmc_ad12 */
0x034 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad13.gpmc_ad13 */
0x038 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad14.gpmc_ad14 */
0x03C (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad15.gpmc_ad15 */
0x008 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad2.gpmc_ad2 */
0x00C (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad3.gpmc_ad3 */
0x010 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad4.gpmc_ad4 */
0x014 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad5.gpmc_ad5 */
0x018 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad6.gpmc_ad6 */
0x01C (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad7.gpmc_ad7 */
0x020 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad8.gpmc_ad8 */
0x024 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11) /* gpmc_ad9.gpmc_ad9 */
0x0C0 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE12) /* gpmc_clk.gpmc_clk */
0x0B8 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE12) /* gpmc_cs2.gpmc_cs2 */
0x0BC (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE10) /* gpmc_cs3.gpmc_cs3 */
0x0D0 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11 | MUX_MODE1) /* gpmc_ben0.gpmc_cs4 */
0x0D4 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE11 | MUX_MODE1) /* gpmc_ben1.gpmc_cs5 */
0x0C8 (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE14) /* gpmc_oen_ren.gpmc_oen_ren */
0x0D8 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE14) /* gpmc_wait0.gpmc_wait0 */
0x0C4 (INPUT_EN | PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE13 | MUX_MODE3) /* gpmc_advn_ale.gpmc_wait1 */
0x0CC (PULL_DIS | MODE_SELECT | MUX_VIRTUAL_MODE14) /* gpmc_wen.gpmc_wen */
>;

};

&gpmc {

status = "okay"; 
pinctrl-names="default";
pinctrl-0 = <&gpmc_pins_up>;

ranges = <2 0 0x00000000 0x01000000>; /* fpga */

fpga {

reg = <2 0 0>;
#address-cells = <1>;
#size-cells = <0>;

gpmc,sync-clk-ps = <20000>; /* Minimum clock period for synchronous mode, in picoseconds */

gpmc,cs-on-ns = <0>; /* Assertion time */
gpmc,cs-rd-off-ns = <100> ; /* Read deassertion time */
gpmc,cs-wr-off-ns = <40>; /* Write deassertion time */

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

/* WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: */
gpmc,we-on-ns = <20>; /* Assertion time */
gpmc,we-off-ns = <20>; /* Deassertion time */

/* OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: */
gpmc,oe-on-ns = <20>; /* Assertion time */
gpmc,oe-off-ns = <100>; /* Deassertion time */

/* Access time and cycle time timings (in nanoseconds) corresponding to GPMC_CONFIG5: */
gpmc,page-burst-access-ns = <20>; /* Multiple access word delay */
gpmc,access-ns = <80>; /* Start-cycle to first data valid delay */
gpmc,rd-cycle-ns = <120>; /* Total read cycle time */
gpmc,wr-cycle-ns = <60>; /* Total write cycle time */

gpmc,device-width = <2>; /* Total width of device(s) connected to a GPMC
chip-select in bytes. The GPMC supports 8-bit
and 16-bit devices and so this property must be
1 or 2. */

gpmc,sync-read; /* Enables synchronous read. Defaults to asynchronous is this is not set. */
gpmc,sync-write; /* Enables synchronous writes. Defaults to asynchronous is this is not set. */


};

};

  • The software team have been notified. They will respond here.
  • Hi Gerard,

    based on your log and looking at drivers/memory/omap-gpmc.c I came up with the following theory what might happen:
    The first message:
    [ 0.379461] omap-gpmc 50000000.gpmc: could not find pctldev for node /ocp/l4@4a000000/scm@2000/pinmux@1400/gpmc_pins_up, deferring probe
    is from pinctrl subsystem and indicates that it cannot find the requested pinctrl handles, for example if the pinctrl driver has not yet registered.
    It isn't critical and indicates that probe should be repeated later. You can check those links for more info about deferral mechanism:
    lwn.net/.../
    www.kernel.org/.../pinctrl.txt
    But when the next probe is called, it eventually fails with EBUSY (error -16 from the log), returned by gpmc_cs_request()
    when it calls gpmc_cs_reserved(cs), which checks for GPMC_CS_RESERVED flag. When looking at the code I found that the function
    that should clear the flag actually do not clear it when called with 0 argument.

    Can you try in the file drivers/memory/omap-gpmc.c to replace the function:

    static void gpmc_cs_set_reserved(int cs, int reserved)
    {
    struct gpmc_cs_data *gpmc = &gpmc_cs[cs];

    gpmc->flags |= GPMC_CS_RESERVED;
    }

    with:

    static void gpmc_cs_set_reserved(int cs, int reserved)
    {
    struct gpmc_cs_data *gpmc = &gpmc_cs[cs];

    if (reserved)
    gpmc->flags |= GPMC_CS_RESERVED;
    else
    gpmc->flags &= ~GPMC_CS_RESERVED;
    }

    and see if it fixes the issue.

    Regards,
    Yordan
  • Thanks for the input.

    I made the change to gpmc_cs_set_reserved() you proposed but I am still getting a similar error:

    -bash-4.3# dmesg | grep gpmc
    [ 0.379447] omap-gpmc 50000000.gpmc: could not find pctldev for node /ocp/l4@4a000000/scm@2000/pinmux@1400/gpmc_pins_up, deferring probe
    [ 1.966098] omap-gpmc 50000000.gpmc: GPMC revision 6.0
    [ 1.971264] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
    [ 1.977549] gpiochip_add: registered GPIOs 510 to 511 on device: omap-gpmc
    [ 1.977641] omap-gpmc 50000000.gpmc: cannot request GPMC CS 2
    [ 1.983414] omap-gpmc 50000000.gpmc: failed to probe DT children
    [ 1.989628] omap-gpmc: probe of 50000000.gpmc failed with error -16

    Gerard
  • Following with your train of thought - is the gpmc_cs array even being initialized?

    (I should add that I'm currently using Processor SDK 02.00.02.11, so I'm using the 4.1.18 kernel included with that release.)
  • Hi Gerard,

    I am not sure about this. If it is the reason for the EBUSY error it mus be initialized at some point, but this needs to be checked.

    Can you add some debug prints to gpmc_probe() function, this might help to narrow down the possible reasons for the problem.

    Regards,
    Yordan
  • My GPMC configuration issues turned out being related to various errors in the device tree definition. I include the final "working" version at the bottom of this post. By working I just mean that it successfully configures during boot - time will tell what timing adjustments/other configuration changes will be necessary.

    Device tree issues (from my original post) included:
    * CS2 range previously started at 0x00000000 - the OMAP GPMC driver requires you start at or above 0x01000000
    * fpga reg definition had 0 for size - corrected to be 0x01000000
    * The "bank-width" property was required (even though "gpmc,device-width" property is essentially the same thing)
    * "gpmc,access-ns", "gpmc,rd-cycle-ns", and "gpmc,wr-cycle-ns" values were too large

    The problem now is when we actually try to communicate from the AM5728 to the FPGA connected via GPMC. In our system the ARM/Linux side does the initial GPMC configuration but all communication with the connected FPGA happens from the DSP.

    I see the following errors on the ARM/Linux when the DSP SW attempts to do a read from the GPMC address space:

    [ 463.491855] omap_l3_noc 44000000.ocp: L3 application error: target 5 mod:1 (unclearable)
    [ 463.491877] omap_l3_noc 44000000.ocp: L3 debug error: target 5 mod:1 (unclearable)

    On the DSP side, the emulator connection to the DSP drops and we essentially have to power-cycle everything to get the AM5728 into a known state.

    What steps are suggested to debug this problem? The error messages don't give you much to go on.

    Thanks



    --------------------------------------------------------------------------
    &gpmc {
    status = "okay";
    pinctrl-names="default";
    pinctrl-0 = <&gpmc_pins_up>;

    ranges = <2 0 0x01000000 0x01000000>; /* fpga */

    fpga {
    reg = <2 0 0x01000000>;

    #address-cells = <1>;
    #size-cells = <1>;

    bank-width = <2>;

    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 = <100> ; /* Read deassertion time */
    gpmc,cs-wr-off-ns = <40>; /* Write deassertion time */

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

    /* WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: */
    gpmc,we-on-ns = <20>; /* Assertion time */
    gpmc,we-off-ns = <20>; /* Deassertion time */

    /* OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: */
    gpmc,oe-on-ns = <20>; /* Assertion time */
    gpmc,oe-off-ns = <100>; /* Deassertion time */

    /* Access time and cycle time timings (in nanoseconds) corresponding to GPMC_CONFIG5: */
    gpmc,page-burst-access-ns = <20>; /* Multiple access word delay */
    gpmc,access-ns = <10>; /* Start-cycle to first data valid delay */
    gpmc,rd-cycle-ns = <20>; /* Total read cycle time */
    gpmc,wr-cycle-ns = <10>; /* Total write cycle time */

    gpmc,device-width = <2>; /* Total width of device(s) connected to a GPMC
    chip-select in bytes. The GPMC supports 8-bit
    and 16-bit devices and so this property must be
    1 or 2. */

    gpmc,sync-read; /* Enables synchronous read. Defaults to asynchronous
    is this is not set. */
    gpmc,sync-write; /* Enables synchronous writes. Defaults to asynchronous
    is this is not set. */
    };
    };
  • Hi Gerard,

    it's great that you have progress on the issue. About L3 errors you can check in those threads for some directions on debugging:

    e2e.ti.com/.../437761
    e2e.ti.com/.../475372

    Regards,
    Yordan
  • Thank you.

    Is there a way to know what the target value of '5' and module value of '1' refers to? I understand the internals of the L3 interconnect registers are not publicly available but it would be helpful to at least know what those ID values refer to.

    Thanks

    [ 463.491855] omap_l3_noc 44000000.ocp: L3 application error: target 5 mod:1 (unclearable)

    [ 463.491877] omap_l3_noc 44000000.ocp: L3 debug error: target 5 mod:1 (unclearable)

  • Hi Gerard,

    the error is printed in l3_interrupt_handler() in <kernel>/drivers/bus/omap_l3_noc.c, but it's not very clear on first sight what happens there. You may look further in the AM572x TRM for the usage of L3_FLAGMUX_REGERR0 register and the chapter "14.2.4.2.1 L3_MAIN Interconnect Error Analysis Mode":
    www.ti.com/.../spruhz6g.pdf

    Regards,
    Yordan
  • Those are the two places I've been looking - omap_l3_noc.c and the AM572x TRM. Sounds like that is the best route then.

    Thank you