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.

AM3359: GPMC Read transaction issue with AD mode configuration

Part Number: AM3359

Dear Experts,

The custom board design housed with an AM3359 processor connected with an FPGA over GPMC interface, which is operating at 100MHz, Synchronous & Multiplexed mode, in AD (Address & Data: 16 bit) configurations.

The AM3359 processor is running with Linux SDK v6.1.

There is an issue with read transactions with address field increment is improper. Whereas, for write transactions the data & address field are proper.

  • Read transaction: Address (ex. 0x10000008) + LSB Data + Address (ex. 0x10000008 - Expected address is 0x1000000A) + MSB Data + Address (ex. 0x1000000A - Expected address is 0x1000000C) + LSB Data + Address (ex. 0x1000000A - Expected address is 0x1000000E) + MSB

Write transaction: Address (ex. 0x10000008) + LSB Data + Address (ex. 0x1000000A) + MSB Data + Address (ex. 0x1000000C) + LSB Data + Address (ex. 0x1000000E) + MSB

The GPMC interface configurations followed are,

0x50000010 0x00000008 

0x5000001C 0x00000200

0x50000040 0x00001FF0

0x50000050 0x00000010

0x50000054 0x00000000

0x500000F0 0x2A651200

0x500000F4 0x00081D00

0x500000F8 0x00010100

0x500000FC 0x08021D03

0x50000100 0x01081F1F

0x50000104 0x820302C0

0x50000108 0x00000001

0x50000108 0x00000f50

Attached the screenshots of the Write and Read transactions.

Please help to correct the configurations and make read transactions proper.

  • Hi,

    Can you please attach your board device tree file showing how the GPMC is configured?

  • Hi Bin Liu,

    Unfortunately the GPMC is not configured through dts, that's a separate challenge we have. Currently the GPMC INTERFACE is initialised through the register configurations shared above.

    Thanks

  • Hi Bin Liu,

    Any inputs on this?

    Thanks

  • Hi Mark,

    Thanks for the inputs.

    It's observed that by tweaking the above linked test parameters, the processor getting halt inbetween and AD mode is not working properly.

    Please help.

  • Hi,

    What are the GPMC_CONFIGx_y register values now?

    Regards,
    Mark

  • Hi Mark,

    The configurations used were same as mentioned above except,

    0x50000104 0x82030240

    Thanks

  • Looking into it now.


  • I see the only difference is CYCLE2CYCLESAMECSEN went from 1 to 0.
    Would not have expected this to halt the proessor.
    Is there some unhandled interrupt occuring?
    Can you read the registers any other way
    Anything in GPMC_ERR_ADDRESS or GPMC_ERR_TYPE?

    Does the halt occur if you disable WAIT monitoring in the GPMC registers?

    Regards,
    Mark

  • Hi Mark, 

    The processor hang happens in some iterations and it hangs before reading the error registers.

    When it's not hanged the observations of both registers are zero.

    With wait monitoring disabled no halt observed and register values are zero.

    I have one observation to share related to read transaction, the above shared read transaction picture is performed by using the memcpy api to read multiple bytes. In this case the address is getting repeated twice and then incrementing.

    Please share your thoughts and inputs on this.

    Thanks

  • Hi Mark,

    I have one observation to share is that read addresses are proper when memcpy is replaced with 8byte pointer. 

    My doubt was how memcpy effecting the GPMC address generation?

    Any other alternates which can be used in place of memcpy for this gpmc scenario?

    Thanks 

  • Hi Mark,

    I have one observation to share is that read addresses are proper when memcpy is replaced with 8byte pointer. However, the transaction times are varying. I have attached the screenshots of the read 20 * 16-bit locations.

    One more observation from screenshots:

    First 8 * 16-bits clock ticks - 100 to 468 

    Second 8 * 16-bits clock ticks - 18013 to 18379

    Third 4 * 16-bits clock ticks - 25126 to 25276

    There is a lot of gap among every 8 * 16 bits (Please note each tick corresponds to 10ns).

    In the case of write transactions, memcpy address increment is proper.

    My doubt was how memcpy affecting the GPMC address generation for read transaction?

    Any other alternates which can be used in place of memcpy for this gpmc read scenario?

    Thanks 

    PS: not able to edit previous reply

  • Hi,

    Can you try using the DMA to write/read from GPMC - this will decrease the delay between GPMC accesses.

    With CPU accesses like memcpy or 8-, 16-,32-bit pointers, MMU attributes might be impacting the delays between GPMC accesses
    What are the mmu attributes (cacheable, bufferable, shareable,  memory marked as normal, device, or strongly ordered)?

    Refer to these E2E posts:

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/409933/am335x-gpmc-speed-up-using-edma-and-or-burst-access

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/316742/am335x-gpmc-phantom-chip-select-generation

    Hope this helps,
    Mark

  • Hi Mark,

    Thank you for the references.

    We have tried the possible options with asm and still the results were same.

    Regarding DMA, my current environment is in Linux and referred links are with baremetal. I'm looking out for these now.

    Couldn't MMU attributes with Linux or in spruh73q processor data sheet.

    Thanks

  • Hi,

    Sorry for the delay. For MMU attributes that apply to the ARM Cortex A8 on AM335x, refer to 7.3 Memory attributes in the Cortex-A8 Technical Reference Manual.

    Refer to the ARM website: https://developer.arm.com/documentation/ddi0344/latest

    Did you manage to get a DMA transfer from on-chip memory to/from GPMC memory region? The DMA should greatly increase the rate of GPMC transfers (by reducing delay between transfers).

    Regards,
    Mark

  • Hi Mark, 

    Thanks for the info on ARM Cortex A8.

    Yes, I'm checking for GPMC DMA and couldn't get/find proper instructions on this.

    I found this one, I feel this is providing GPMC access from the driver layer, how DMA is coming into the picture for this ?e2e.ti.com/.../am335x-gpmc-using-dma

    Any helpful links to get started with Linux GPMC + DMA ?

    Thanks

  • You are looking for DMA examples in Linux? Have you seen the dmatest source code and documentation?

    Refer to this E2E: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/689540/linux-am3352-edma-example

    Linux src:
    https://software-dl.ti.com/processor-sdk-linux/esd/AM335X/latest/exports/am335x-evm-linux-sdk-src-07.03.00.005.tar.xz

    * Documentation:  under board-support\linux-5.4.106+gitAUTOINC+023faefa70-g023faefa70\Documentation\driver-api\dmaengine\dmatest.rst

    * Source: under board-support\linux-5.4.106+gitAUTOINC+023faefa70-g023faefa70\drivers\dma\dmatest.c

    Regards,
    Mark

  • Hi Mark,

    Thank you for the shared post and sources.

    By following the instructions from the dmatest.rst, we were able to load/run the dmatest.ko. Observed that wait is always 'Y' and run is always 'N'

    # modprobe dmatest run=1 iterations=42

    #cat /sys/module/dmatest/parameters/wait

    Y

    #cat /sys/module/dmatest/parameters/run

    N

    But the output expected is different: wait - N, run - Y

    Any insights on this?

    Thanks

  • Hi,

    Mark is currently out of office and will follow up with you in 2 weeks upon his return.  

    Regards,

    Melissa

  • Part Number: AM3359

    Hi Mark,

    The dmatest code resulted positively by using dma channel: dma1chan0.

    Post to this tried updating the source address using GPMC slave address by doing ioremap.

    With this change observed the kernel panic. Is this update is correct or please share your inputs on how to pass the gpmc address to driver.

    Thanks

  • I don't know much about ioremap.

    Did the DMA try to access a source address outside of the GPMC memory map region?

    Or perhaps it accessed part of the GPMC memory map region that is not mapped to any CS. Check  GPMC_CONFIG7_i MASKADDRESS and BASEADDRESS fields for the chip select you are accessing. What are these values, and what address range are you accessing?

    Its also possible the dest address accessed outside its allocated memory.

    Are there any details in the kernel panic? I'll try to loop in the software team.

    Regards,
    Mark

  • Hi Mark,

    ioremap() function is used to map the physical addres of an I/O device to the kernel virtual address.

    The allocated address of the GPMC: 0x0300_0000

    In the default dmatest driver I have modified the default buffer address with 0x0300_0000 (I have used ioremap to the physical to virtual address and result updated in dmatest driver), following error received,

    [   62.707516] Unable to handle kernel paging request at virtual address 202c4970
    [   62.714503] pgd = 8474ec3c
    [   62.717112] [202c4970] *pgd=00000000
    [   62.720568] Internal error: Oops: 5 [#1] PREEMPT ARM
    [   62.725354] Modules linked in: dmatest
    [   62.728986] CPU: 0 PID: 310 Comm: dma1chan0-copy0 Tainted: G        W         4.19.59-g5f8c1c6121 #149
    [   62.737957] Hardware name: Generic AM33XX (Flattened Device Tree)
    [   62.743850] PC is at __queue_work+0xe0/0x398
    [   62.747980] LR is at cpu_worker_pools+0x0/0x310
    [   62.752346] pc : [<c014105c>]    lr : [<c180deb8>]    psr: 600f0193
    [   62.758387] sp : cbda5b98  ip : 00010001  fp : cbda5bdc
    [   62.763423] r10: 00000000  r9 : c1848d70  r8 : cb803000
    [   62.768460] r7 : ffffe000  r6 : 00000001  r5 : cfd7f100  r4 : cbb7adb0
    [   62.774752] r3 : 41516170  r2 : cbb7adb4  r1 : 202c495c  r0 : 00010001
    [   62.781046] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
    [   62.788008] Control: 10c5387d  Table: 8bc7c019  DAC: 00000051
    [   62.793548] Process dma1chan0-copy0 (pid: 310, stack limit = 0xb1eba87b)
    [   62.800008] Stack: (0xcbda5b98 to 0xcbda6000)
    [   62.804210] 5b80:                                                       3b9aca00 00000000
    [   62.812099] 5ba0: c180f2d0 c0a98f1c c180deb4 00000000 cbda5bdc 400f0193 00000001 00000002
    [   62.819988] 5bc0: fffffffc 00000000 c0193cbc 200f0193 cbda5bf4 cbda5be0 c0141358 c0140f88
    [   62.827877] 5be0: cbb7ada4 00000003 cbda5c04 cbda5bf8 c06b3e34 c0141320 cbda5c24 cbda5c08
    [   62.835766] 5c00: c01b266c c06b3e1c cbda4000 cba1f000 00000000 0000000e cbda5c34 cbda5c28
    [   62.843654] 5c20: c01b2858 c01b2604 cbda5c54 cbda5c38 c0184250 c01b2834 c1816340 cbda5e40
    [   62.851543] 5c40: 99362570 0000000e cbda5c64 cbda5c58 c0193a94 c01841f8 cbda5c8c cbda5c68
    [   62.859431] 5c60: c0193d0c c0193a44 c018469c c0869788 c1815ac0 c1816340 c1815a80 ffffe000
    [   62.867321] 5c80: cbda5ce4 cbda5c90 c0184e10 c0193cc8 c018949c c0a9d7a8 c18468c1 0000000e
    [   62.875209] 5ca0: 99362048 c1815a80 c1815ad4 00000000 99362048 0000000e cbda5cf4 c1815a80
    [   62.883097] 5cc0: ffffe000 200f0193 00000003 7fffffff ffffffff c184687e cbda5d3c cbda5ce8
    [   62.890985] 5ce0: c01855d0 c0184c8c cbda5d0c 0000000e c0727f98 c021c8a0 c18146cc c1814240
    [   62.898872] 5d00: 99362048 7fffffff ffffffff a00f0113 cbda5d8c c1807e00 00000000 00000000
    [   62.906762] 5d20: cbda5d98 00000010 cb807100 c184687e cbda5d4c cbda5d40 c0119218 c01854bc
    [   62.914650] 5d40: cbda5d94 cbda5d50 c016e168 c01191f4 cbda5d94 cbda5d60 c01542ec c0a9bcc4
    [   62.922538] 5d60: c0a9bcb0 c0a9bc88 cbda5d9c c1803048 00000000 cb807100 00000000 cb808000
    [   62.930428] 5d80: cbda4000 cbda0d40 cbda5dbc cbda5d98 c016e280 c016e10c 00000000 aaabebd2
    [   62.938316] 5da0: c0173a34 cb807100 00000000 00000001 cbda5dd4 cbda5dc0 c016e338 c016e258
    [   62.946205] 5dc0: cb807100 00000000 cbda5dec cbda5dd8 c01718d0 c016e2e0 c1845ac4 00000000
    [   62.954093] 5de0: cbda5dfc cbda5df0 c016d2e8 c017181c cbda5e24 cbda5e00 c016dab4 c016d2c8
    [   62.961982] 5e00: c18790cc 600f0013 ffffffff cbda5e74 0000000e cbda4000 cbda5e3c cbda5e28
    [   62.969871] 5e20: c04365cc c016da64 bf000d14 600f0013 cbda5f74 cbda5e40 c0101a0c c043659c
    [   62.977759] 5e40: 00000000 00004000 04151727 d083d840 d083d000 00000840 00000002 00000001
    [   62.985648] 5e60: 0000000e bf004000 cbda0d40 cbda5f74 cbda0e40 cbda5e90 cbdac000 bf000d14
    [   62.993536] 5e80: 600f0013 ffffffff 00000051 00000000 cba1f030 c180ee78 cbda5ecc cbda5ea8
    [   63.001425] 5ea0: c0154f8c c180ee78 c180ee78 c180ee40 640133e0 cbda0e40 cba1f3ac cbd55c40
    [   63.009314] 5ec0: 00004000 0000000e 63cde6c0 c186e704 00000018 cbda5e90 00000000 00000000
    [   63.017202] 5ee0: 00000000 00000000 00000000 cbda4000 00000000 cbda0f00 00000001 fffffff4
    [   63.025091] 5f00: cbda0ec0 00000ff9 00000000 00000000 c1803048 cb979580 cb93b340 00000001
    [   63.032978] 5f20: 00000840 00000000 00000001 cbda4000 13185466 00000000 cbda0dc0 cbda0d80
    [   63.040867] 5f40: 00000000 aaabebd2 cbda0d40 cbda0dc0 cbda0d80 00000000 cbda4000 cbda0d40
    [   63.048755] 5f60: bf0000c8 cbd55c40 cbda5fac cbda5f78 c0147b14 bf0000d4 cbda0dd8 cbda0dd8
    [   63.056644] 5f80: 00000000 cbda0d80 c01479bc 00000000 00000000 00000000 00000000 00000000
    [   63.064531] 5fa0: 00000000 cbda5fb0 c01010e8 c01479c8 00000000 00000000 00000000 00000000
    [   63.072419] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    [   63.080306] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
    [   63.088187] Backtrace:
    [   63.090555] [<c0140f7c>] (__queue_work) from [<c0141358>] (queue_work_on+0x44/0x50)
    [   63.097943]  r10:200f0193 r9:c0193cbc r8:00000000 r7:fffffffc r6:00000002 r5:00000001
    [   63.105491]  r4:400f0193
    [   63.107941] [<c0141314>] (queue_work_on) from [<c06b3e34>] (dbs_irq_work+0x24/0x28)
    [   63.115323]  r5:00000003 r4:cbb7ada4
    [   63.118779] [<c06b3e10>] (dbs_irq_work) from [<c01b266c>] (irq_work_run_list+0x74/0xa8)
    [   63.126501] [<c01b25f8>] (irq_work_run_list) from [<c01b2858>] (irq_work_tick+0x30/0x38)
    [   63.134302]  r7:0000000e r6:00000000 r5:cba1f000 r4:cbda4000
    [   63.139764] [<c01b2828>] (irq_work_tick) from [<c0184250>] (update_process_times+0x64/0x6c)
    [   63.147824] [<c01841ec>] (update_process_times) from [<c0193a94>] (tick_sched_handle+0x5c/0x60)
    [   63.156212]  r7:0000000e r6:99362570 r5:cbda5e40 r4:c1816340
    [   63.161671] [<c0193a38>] (tick_sched_handle) from [<c0193d0c>] (tick_sched_timer+0x50/0xac)
    [   63.169728] [<c0193cbc>] (tick_sched_timer) from [<c0184e10>] (__hrtimer_run_queues.constprop.3+0x190/0x228)
    [   63.179204]  r7:ffffe000 r6:c1815a80 r5:c1816340 r4:c1815ac0
    [   63.184663] [<c0184c80>] (__hrtimer_run_queues.constprop.3) from [<c01855d0>] (hrtimer_interrupt+0x120/0x30c)
    [   63.194227]  r10:c184687e r9:ffffffff r8:7fffffff r7:00000003 r6:200f0193 r5:ffffe000
    [   63.201774]  r4:c1815a80
    [   63.204229] [<c01854b0>] (hrtimer_interrupt) from [<c0119218>] (omap2_gp_timer_interrupt+0x30/0x38)
    [   63.212955]  r10:c184687e r9:cb807100 r8:00000010 r7:cbda5d98 r6:00000000 r5:00000000
    [   63.220501]  r4:c1807e00
    [   63.222951] [<c01191e8>] (omap2_gp_timer_interrupt) from [<c016e168>] (__handle_irq_event_percpu+0x68/0x14c)
    [   63.232429] [<c016e100>] (__handle_irq_event_percpu) from [<c016e280>] (handle_irq_event_percpu+0x34/0x88)
    [   63.241741]  r10:cbda0d40 r9:cbda4000 r8:cb808000 r7:00000000 r6:cb807100 r5:00000000
    [   63.249287]  r4:c1803048
    [   63.251731] [<c016e24c>] (handle_irq_event_percpu) from [<c016e338>] (handle_irq_event+0x64/0x90)
    [   63.260286]  r6:00000001 r5:00000000 r4:cb807100
    [   63.264744] [<c016e2d4>] (handle_irq_event) from [<c01718d0>] (handle_level_irq+0xc0/0x160)
    [   63.272794]  r5:00000000 r4:cb807100
    [   63.276244] [<c0171810>] (handle_level_irq) from [<c016d2e8>] (generic_handle_irq+0x2c/0x3c)
    [   63.284378]  r5:00000000 r4:c1845ac4
    [   63.287828] [<c016d2bc>] (generic_handle_irq) from [<c016dab4>] (__handle_domain_irq+0x5c/0xb0)
    [   63.296224] [<c016da58>] (__handle_domain_irq) from [<c04365cc>] (omap_intc_handle_irq+0x3c/0x94)
    [   63.304782]  r9:cbda4000 r8:0000000e r7:cbda5e74 r6:ffffffff r5:600f0013 r4:c18790cc
    [   63.312254] [<c0436590>] (omap_intc_handle_irq) from [<c0101a0c>] (__irq_svc+0x6c/0xa8)
    [   63.319970] Exception stack(0xcbda5e40 to 0xcbda5e88)
    [   63.324844] 5e40: 00000000 00004000 04151727 d083d840 d083d000 00000840 00000002 00000001
    [   63.332733] 5e60: 0000000e bf004000 cbda0d40 cbda5f74 cbda0e40 cbda5e90 cbdac000 bf000d14
    [   63.340616] 5e80: 600f0013 ffffffff
    [   63.343978]  r5:600f0013 r4:bf000d14
    [   63.347462] [<bf0000c8>] (dmatest_func [dmatest]) from [<c0147b14>] (kthread+0x158/0x160)
    [   63.355351]  r10:cbd55c40 r9:bf0000c8 r8:cbda0d40 r7:cbda4000 r6:00000000 r5:cbda0d80
    [   63.362897]  r4:cbda0dc0
    [   63.365343] [<c01479bc>] (kthread) from [<c01010e8>] (ret_from_fork+0x14/0x2c)
    [   63.372304] Exception stack(0xcbda5fb0 to 0xcbda5ff8)
    [   63.377175] 5fa0:                                     00000000 00000000 00000000 00000000
    [   63.385062] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    [   63.392947] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
    [   63.399328]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c01479bc
    [   63.406875]  r4:cbda0d80
    [   63.409322] Code: 1a000088 e5953008 e0851103 e1a03203 (e5912014)
    [   63.415208] ---[ end trace 495bc8384c08471f ]---
    [   63.419660] Kernel panic - not syncing: Fatal exception in interrupt
    [   63.425789] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---

    How can I update the GPMC address 0x0300_0000 to dmatest (if not the above method)?

    Thanks

  • Hi,

    Can you please post the patch of your dmatest modification?

  • Hi Bin Liu,

    Here is the modified code,

    dmatest_init():

        remap_addr_g = ioremap(RCU_FPGA_WR_ADDR, 0x1000);
        if(remap_addr_g == NULL)
        {
            printk("IO remap failed");
        }


    dmatest_func():

    dst_off = remap_addr_g; //dmatest_random() % (params->buf_size - len + 1);

    Thanks

  • HI,

    I don't know much about the dmatest.c code, but just by reading it, it seems your modification is not correct. In the original code, It seems dst_off is not the destination buffer address, rather an random number for the offset in the destination buffer. thread->dsts should be the array of destination buffer addresses.