Project

General

Profile

How to reserve EDMA for DSP

Added by Mary Frantz over 6 years ago

I am having an ARM/DSP conflict. The DSP is primarily reading data from the McBSP and transferring the data to a circular buffer in DDR memory which is shared with the ARM. The ARM accesses it through a pointer allocated with CMEM.

The DSP received data from the McBSP using the SIO_issue/SIO_reclaim mechanism, which uses EDMA30_TC0. The data frame rate is 50K frames/sec with 17 channels of 24 bit data. The SIO_issue() call requests 4 frames worth of data at a time.

Problem: I occasionally (this takes 10-20 minutes to occur) see that the DSP fails to acquire any data from the McBSP for a period 200 to 270 msec. When this happens, there is a corresponding timeout on the SIO_reclaim() call.

Could something on the ARM be using the same EDMA resource and fail to release it?

I am using kernel MDK_2012-08-10

I have set the priorities in MSTPRIOn as follows:

EDMA30_TC0: 0
EDMA30_TC1: 2
DSP_CFG: 1
DSP_MDMA: 1
ARM D: 2
ARM I: 2
SATA: 4
UPP: 4
VPIF DMA 0: 4
VPIF DMA 1: 4
EDMA31 TCO: 4
LCDC: 5
USB1: 4
UHPI: 6
USB0CDMA: 4
USB0CFG: 4
EMAC: 4

After reading the following discussion: https://support.criticallink.com/redmine/boards/10/topics/3340?r=3369#message-3369

I added the following to the board-mityomapl138.c file and recompiled the kernel:

/*
 * The following EDMA channels/slots are not being used by drivers (for
 * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence
 * they are being reserved for codecs on the DSP side.
 */
static const s16 da850_dma0_rsv_chans[][2] = {
    /* (offset, number) */
    { 0,  2},        // added MDF
    { 8,  6},
    {24,  4},
    {30,  2},
    {-1, -1}
};

static const s16 da850_dma0_rsv_slots[][2] = {
    /* (offset, number) */
    { 0,  2},        // added MDF
    { 8,  6},
    {24,  4},
    {30, 50},
    {-1, -1}
};

static const s16 da850_dma1_rsv_chans[][2] = {
    /* (offset, number) */
    { 0, 28},
    {30,  2},
    {-1, -1}
};

static const s16 da850_dma1_rsv_slots[][2] = {
    /* (offset, number) */
    { 0, 28},
    {30, 90},
    {-1, -1}
};

static struct edma_rsv_info da850_edma_cc0_rsv = {
    .rsv_chans    = da850_dma0_rsv_chans,
    .rsv_slots    = da850_dma0_rsv_slots,
};

static struct edma_rsv_info da850_edma_cc1_rsv = {
    .rsv_chans    = da850_dma1_rsv_chans,
    .rsv_slots    = da850_dma1_rsv_slots,
};

static struct edma_rsv_info *da850_edma_rsv[2] = {
    &da850_edma_cc0_rsv,
    &da850_edma_cc1_rsv,
};

//    ret = da850_register_edma(NULL);
    // 02/04/14 MDF Replace above line with the one below
    ret = da850_register_edma(da850_edma_rsv);

And at the beginning of the static void __init mityomapl138_init(void) I added the function call:


ret = da850_register_edma(da850_edma_rsv);

Is there documentation that explains the (offset, number) pairs in da850_dma0_rsv_chans and da850_dma0_rsv_slots?

Is this the correct way to reserve edma-channels?

Is there a way to verify that these channels are blocked for linux?

Thanks,
Mary


Replies (3)

RE: How to reserve EDMA for DSP - Added by Mary Frantz over 6 years ago

In researching this I found what looks like a similar problem:

http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/308987.aspx

This discussion describes how the McBSP freezes when other EMDA accesses occur. I also noted in other posts that the linux SPI driver uses the EDMA.

The advice from TI was in part:

Specifically, put only the McBSP1 read transfer on EDMA0_TC0. Put all of the other transfers that have to be on EDMA0 on EDMA0_TC1. It was not obvious that you did this, since the SPI operation did not have the TCn specified.

Is there a way to do this?

I reinstalled a kernel that did not include the SPI driver and used instead my own SPI support code which directly configures the SPI registers.

This code ran without any problems.

The SPIDEV drivers seems a bit heavy handed for an embedded system. DMA is useful for reading and writing to memory devices, but probably not required for 2 bytes transfers to configure a register on a peripheral chip like a DAC. I also found that the SPI driver was holding off a high priority task when writing to the console about changes to SPI parameters (see my other post: https://support.criticallink.com/redmine/boards/10/topics/3441?r=3612#message-3612 ) This issue was also resolved by abandoning the linux SPIDEV driver.

Mary

RE: How to reserve EDMA for DSP - Added by Jonathan Cormier over 6 years ago

Mary,

I think you can disable the dma usage of the spi driver. I am using the following resource declaration for a different project. Note that the dm365 is a cousin of the l138.

static struct resource dm365_spi1_resources[] = {
        {
                .start = 0x01c66800,
                .end   = 0x01c66fff,
                .flags = IORESOURCE_MEM,
        },
        {
                .start = IRQ_DM365_SPIINT1_1,
                  .end = IRQ_DM365_SPIINT1_1,
                .flags = IORESOURCE_IRQ,
        },
        /*//disable dma for spi currently
        {
                .start = 17,
                .flags = IORESOURCE_DMA,
        },
        {
                .start = 16,
                .flags = IORESOURCE_DMA,
        },
        {
                .start = EVENTQ_3,
                .flags = IORESOURCE_DMA,
        },
        */
};

So using that as a reference you could try to edit da850_spi0_resources/da850_spi1_resources structs in device-da8xx.c and comment out the DMA resource lines. And see if this solves your DMA problem.

RE: How to reserve EDMA for DSP - Added by Mary Frantz over 6 years ago

I tried modifying device-da8xx.c as describe above, but the boot process hung. Here's the relevant part of the log:

Creating 2 MTD partitions on "davinci_nand.1":
0x000000000000-0x000008000000 : "rootfs" 
0x000008000000-0x000010000000 : "homefs" 
davinci_nand davinci_nand.1: controller rev. 2.5
m25p80 spi1.0: m25p64-nonjedec (8192 Kbytes)
Creating 8 MTD partitions on "m25p80":
0x000000000000-0x000000010000 : "ubl" 
0x000000010000-0x000000090000 : "u-boot" 
0x000000090000-0x0000000a0000 : "u-boot-env" 
0x0000000a0000-0x0000000b0000 : "periph-config" 
INFO: task swapper:1 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
swapper         D c032a4d8     0     1      0 0x00000000
[<c032a4d8>] (__schedule+0x350/0x3b0) from [<c032ad2c>] (schedule_timeout+0x1c/0
x224)
[<c032ad2c>] (schedule_timeout+0x1c/0x224) from [<c032a880>] (wait_for_common+0x
f4/0x1bc)
[<c032a880>] (wait_for_common+0xf4/0x1bc) from [<c01dfcdc>] (__spi_sync+0x80/0x9
c)
[<c01dfcdc>] (__spi_sync+0x80/0x9c) from [<c01dfe00>] (spi_write_then_read+0xf8/
0x158)
[<c01dfe00>] (spi_write_then_read+0xf8/0x158) from [<c01d82ac>] (wait_till_ready
.clone.8+0x3c/0x90)
[<c01d82ac>] (wait_till_ready.clone.8+0x3c/0x90) from [<c01d89f0>] (m25p80_read+
0xd4/0x144)
[<c01d89f0>] (m25p80_read+0xd4/0x144) from [<c01d4094>] (part_read+0x6c/0xc0)
[<c01d4094>] (part_read+0x6c/0xc0) from [<c00141f8>] (mityomapl138_notify_add+0x
4c/0x134)
[<c00141f8>] (mityomapl138_notify_add+0x4c/0x134) from [<c01d1fc0>] (add_mtd_dev
ice+0x1fc/0x264)
[<c01d1fc0>] (add_mtd_device+0x1fc/0x264) from [<c01d4dcc>] (add_mtd_partitions+
0xa4/0xd8)
[<c01d4dcc>] (add_mtd_partitions+0xa4/0xd8) from [<c01d20ac>] (mtd_device_parse_
register+0x84/0xb8)
[<c01d20ac>] (mtd_device_parse_register+0x84/0xb8) from [<c0324dc4>] (m25p_probe
+0x43c/0x498)
[<c0324dc4>] (m25p_probe+0x43c/0x498) from [<c01df74c>] (spi_drv_probe+0x18/0x1c
)
[<c01df74c>] (spi_drv_probe+0x18/0x1c) from [<c0194f8c>] (driver_probe_device+0x
d4/0x198)
[<c0194f8c>] (driver_probe_device+0xd4/0x198) from [<c0193f60>] (bus_for_each_dr
v+0x4c/0x84)
[<c0193f60>] (bus_for_each_drv+0x4c/0x84) from [<c0194dd4>] (device_attach+0x78/
0xa4)
[<c0194dd4>] (device_attach+0x78/0xa4) from [<c0194758>] (bus_probe_device+0x24/
0x44)
[<c0194758>] (bus_probe_device+0x24/0x44) from [<c0192f98>] (device_add+0x3a8/0x
524)
[<c0192f98>] (device_add+0x3a8/0x524) from [<c01e01dc>] (spi_add_device+0xcc/0x1
44)
[<c01e01dc>] (spi_add_device+0xcc/0x144) from [<c01e02d4>] (spi_new_device+0x80/
0xa4)
[<c01e02d4>] (spi_new_device+0x80/0xa4) from [<c01e031c>] (spi_match_master_to_b
oardinfo+0x24/0x44)
[<c01e031c>] (spi_match_master_to_boardinfo+0x24/0x44) from [<c01e0450>] (spi_re
gister_master+0x114/0x158)
[<c01e0450>] (spi_register_master+0x114/0x158) from [<c01e1218>] (spi_bitbang_st
art+0x130/0x16c)
[<c01e1218>] (spi_bitbang_start+0x130/0x16c) from [<c03252e0>] (davinci_spi_prob
e+0x374/0x478)
[<c03252e0>] (davinci_spi_probe+0x374/0x478) from [<c019609c>] (platform_drv_pro
be+0x14/0x18)
[<c019609c>] (platform_drv_probe+0x14/0x18) from [<c0194f8c>] (driver_probe_devi
ce+0xd4/0x198)
[<c0194f8c>] (driver_probe_device+0xd4/0x198) from [<c01950b0>] (__driver_attach
+0x60/0x84)
[<c01950b0>] (__driver_attach+0x60/0x84) from [<c0194220>] (bus_for_each_dev+0x4
c/0x78)
[<c0194220>] (bus_for_each_dev+0x4c/0x78) from [<c0194898>] (bus_add_driver+0x98
/0x214)
[<c0194898>] (bus_add_driver+0x98/0x214) from [<c0195614>] (driver_register+0xa0
/0x120)
[<c0195614>] (driver_register+0xa0/0x120) from [<c000887c>] (do_one_initcall+0x9
0/0x168)
[<c000887c>] (do_one_initcall+0x90/0x168) from [<c05367e8>] (kernel_init+0x78/0x
11c)
[<c05367e8>] (kernel_init+0x78/0x11c) from [<c0009cb8>] (kernel_thread_exit+0x0/
0x8)

Is there a way to disable dma for spi1 at run time? I don't mind having dma enabled for flash transfers, but it interferes with the real time constraints for other transfers, which are all very short anyway.

Mary

    (1-3/3)
    Add picture from clipboard (Maximum size: 500 MB)