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.

DRA712: visonSDK 0304 early boot: how to share edma channel between linux and rtos

Part Number: DRA712

hi all experts,

now i encouter an issue that is edma channel can not be shared on linux and rtos.

my board SOC is DRA711, and we make visionSDK0304 earlyboot on IPU2 successfully. 

in kernel dts has following config:

/* Linux uses first 32 channels, BIOS uses last 32 */
&edma {
       dma-requests = <32>;
};

this means that linux use first 32 channel(0~31), RTOS use last channel(32~63).

if enable the following module in omap_hwmod_7xx_data.c of linux kernel, on IPU2 side edma can not work, block at Utils_dmaCopy2D() function. linux side edma can work.

static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {

。。。

 &dra7xx_l4_cfg__dma_system,
 &dra7xx_l3_main_1__tpcc,
 &dra7xx_l3_main_1__tptc0,
 &dra7xx_l3_main_1__tptc1,

。。。

};

but if i disable the privious module, IPU2 side can use EDMA channel 32 to transfer data, but on linux side edma can not work. kernel log as following:

[    0.211235] edma3-tptc 43400000.tptc: _od_fail_runtime_resume: FIXME: missing hwmod/omap_dev info
[    0.211294] edma3-tptc 43500000.tptc: _od_fail_runtime_resume: FIXME: missing hwmod/omap_dev info
[    0.211492] edma 43300000.edma: _od_fail_runtime_resume: FIXME: missing hwmod/omap_dev info
[    0.211502] edma 43300000.edma: pm_runtime_get_sync() failed

could anyone help me figure out the problem? 

i look up this post: 

but also can not fix this problem.

as edma clock has already enable on IPU2 side when earlyboot. so how can i disable edma clock setting on kernel side?

  • Did you try reverting the patch on kernel
    0002-arm-mach-omap2-Remove-edma-related-nodes-from-hwmod-.patch ?

    Do you see this issue getting reproduced only with early-boot late-attach usecase?

    Thanks
    RamPrasad

  • hi RamPrasad,

    according to the 0002-arm-mach-omap2-Remove-edma-related-nodes-from-hwmod-.patch, it remove the edma relate hw modules. 

    this making on A15 side EDMA can not work. 

    remove EDMA relate hw modules, i think EDMA can not work on A15 side for and cases.

    best regards!

  • hi, fanok. 

    thanks for quote my thread.

    you'd not disable edma in the kernel but by-pass any thing that would reset/idle/setup edma which is used in ipu. see here.

    here is the patch i was tried, but the test result is still failed:

    this issue has bother me for a long time, im still struggling.

    Index: src/arch/arm/mach-omap2/omap_hwmod.c

    ===================================================================
    --- src/arch/arm/mach-omap2/omap_hwmod.c	(revision 76059)
    +++ src/arch/arm/mach-omap2/omap_hwmod.c	(working copy)
    @@ -1582,6 +1582,14 @@
     {
     	int ret = 0;
     
    +
    +	if((strcmp(oh->name, "tptc0") == 0) || 
    +	        (strcmp(oh->name, "tptc1") == 0))
    +	{
    +	    printk("%s skiping name of %s\n", __func__, oh->name);
    +	    return 0;
    +	}
    +	
     	if (oh->_state != _HWMOD_STATE_REGISTERED)
     		return 0;
     
    @@ -1653,6 +1661,13 @@
     	if (!oh)
     		return -EINVAL;
     
    +    if((strcmp(oh->name, "tptc0") == 0) ||
    +	        (strcmp(oh->name, "tptc1") == 0))
    +	{
    +		printk("%s skiping name of %s\n", __func__, oh->name);
    +	    return 0;
    +	}
    +
     	if (!soc_ops.assert_hardreset)
     		return -ENOSYS;
     
    @@ -1686,6 +1701,14 @@
     	if (!oh)
     		return -EINVAL;
     
    +
    +    if((strcmp(oh->name, "tptc0") == 0) ||
    +	        (strcmp(oh->name, "tptc1") == 0))
    +	{
    +		printk("%s skiping name of %s\n", __func__, oh->name);
    +	    return 0;
    +	}
    +
     	if (!soc_ops.deassert_hardreset)
     		return -ENOSYS;
     
    @@ -2081,6 +2104,13 @@
     {
     	int r;
     
    +    if((strcmp(oh->name, "tptc0") == 0) ||
    +	        (strcmp(oh->name, "tptc1") == 0))
    +	{
    +		printk("%s skiping name of %s\n", __func__, oh->name);
    +	    return 0;
    +	}
    +
     	pr_debug("omap_hwmod: %s: enabling\n", oh->name);
     
     	/*
    @@ -2202,9 +2232,17 @@
     		oh->_int_flags |= _HWMOD_SKIP_ENABLE;
     		return 0;
     	}
    -
    +	
     	pr_debug("omap_hwmod: %s: idling\n", oh->name);
     
    +
    +    if((strcmp(oh->name, "tptc0") == 0) || 
    +            (strcmp(oh->name, "tptc1") == 0))
    +    {
    +		printk("%s skiping name of %s\n", __func__, oh->name);
    +        return 0;
    +    }
    +    
     	if (_are_all_hardreset_lines_asserted(oh))
     		return 0;
     
    @@ -2698,6 +2736,13 @@
      */
     static int __init _setup(struct omap_hwmod *oh, void *data)
     {
    +    if((strcmp(oh->name, "tptc0") == 0) || 
    +            (strcmp(oh->name, "tptc1") == 0))
    +    {
    +		printk("%s skiping name of %s\n", __func__, oh->name);
    +        return 0;
    +    }
    +    
     	if (oh->_state != _HWMOD_STATE_INITIALIZED)
     		return 0;
     
    @@ -3109,6 +3154,14 @@
     	if (!oh->clkdm)
     		return -EINVAL;
     
    +
    +    if((strcmp(oh->name, "tptc0") == 0) ||
    +	        (strcmp(oh->name, "tptc1") == 0))
    +	{
    +		printk("%s skiping name of %s\n", __func__, oh->name);
    +	    return 0;
    +	}
    +
     	return omap_prm_is_hardreset_asserted(ohri->rst_shift,
     					      oh->clkdm->pwrdm.ptr->
     					      prcm_partition,
    @@ -4107,6 +4160,13 @@
     {
     	int i;
     
    +    if((strcmp(oh->name, "tptc0") == 0) ||
    +	        (strcmp(oh->name, "tptc1") == 0))
    +	{
    +		printk("%s skiping name of %s\n", __func__, oh->name);
    +	    return 0;
    +	}
    +
     	for (i = 0; i < oh->rst_lines_cnt; i++)
     		if (oh->rst_lines[i].context)
     			_assert_hardreset(oh, oh->rst_lines[i].name);

    regards, wen

  • hi wen,

    thanks for your reply, you attach the patch of src/arch/arm/mach-omap2/omap_hwmod.c can fix the problem?

    best regards!

  • hi, fanok.

    it's very urgly patch, but sadly no.

    im still struggling.

    regards, wen

  • Hi, Fan, Wen:

    Please try below approach:

    • revert patch 0002-arm-mach-omap2-Remove-edma-related-nodes-from-hwmod-.patch

    • in uboot (if the uboot exists) : arch/arm/cpu/armv7/omap5/hw_data.c (exact file)

    
    

    • in kernel dts (please find the edma setting in your dts)

    The above should be find.

  • hi, Peter

    i have applied the patch and check the device tree in the system:

    /sys/firmware/devicetree/base/ocp/edma@43300000 # ls
    #dma-cells dma-requests interrupts name reg ti,hwmods ti,no-reset-on-init
    compatible interrupt-names linux,phandle phandle reg-names ti,no-idle-on-init ti,tptcs

    /sys/firmware/devicetree/base/ocp/tptc@43400000 # ls
    compatible interrupt-names interrupts linux,phandle name phandle reg ti,hwmods ti,no-idle-on-init ti,no-reset-on-init

    /sys/firmware/devicetree/base/ocp/tptc@43500000 # ls
    compatible interrupt-names interrupts linux,phandle name phandle reg ti,hwmods ti,no-idle-on-init ti,no-reset-on-init

    but sadly, the test result is failed.

     

    regards, wen

  • hi wen,

    i fixed my problem, and EDMA can work well both on A15 and M4 side. i can share the patch with you:

    diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c
    old mode 100644
    new mode 100755
    index 2fa50a4..50031ed
    --- a/drivers/dma/ti/edma.c
    +++ b/drivers/dma/ti/edma.c
    @@ -2198,6 +2198,7 @@ static int edma_probe(struct platform_device *pdev)
            struct edma_cc          *ecc;
            bool                    legacy_mode = true;
            int ret;
    +       u32 num_channels = 0;
            if (node) {
                    const struct of_device_id *match;
    @@ -2258,6 +2259,17 @@ static int edma_probe(struct platform_device *pdev)
            if (ret)
                    return ret;
    +       /* Number Channel of DMA requests */
    +       if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node,
    +                                                     "dma-requests",
    +                                                     &num_channels)) {
    +               dev_err(&pdev->dev, "Missing dma-requests property. using: %u\n", ecc->num_channels);
    +       }
    +       else {
    +               dev_dbg(&pdev->dev, "edma request channels: %d\n", num_channels);
    +               ecc->num_channels = num_channels;
    +       }
    +
            /* Allocate memory based on the information we got from the IP */
            ecc->slave_chans = devm_kcalloc(dev, ecc->num_channels,
                                            sizeof(*ecc->slave_chans), GFP_KERNEL);
    @@ -2364,11 +2376,16 @@ static int edma_probe(struct platform_device *pdev)
                    edma_assign_priority_to_queue(ecc, queue_priority_mapping[i][0],
                                                  queue_priority_mapping[i][1]);
    +       //DMA Region Access enable for Region M, as Early boot IPU2, EDMA had been setting, so discard in here.
    +       // EDMA first 32 channels for A15, last 32 channels for RTOS
    +#if 0
            for (i = 0; i < ecc->num_region; i++) {
                    edma_write_array2(ecc, EDMA_DRAE, i, 0, 0x0);
                    edma_write_array2(ecc, EDMA_DRAE, i, 1, 0x0);
                    edma_write_array(ecc, EDMA_QRAE, i, 0x0);
            }
    +#endif
    +
            ecc->info = info;
            /* Init the dma device and channels */
    best regards!