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.

DRA746: MMC_EDMA

Part Number: DRA746

For MMC DMA to work correctly, is it required to configure IRQ cross bar (or) DMA cross bar is sufficient?

  • Hi Jeba,

    DMA crossbar is needed to make connection between EDMA event source and EDMA channel. IRQ crossbar is needed for interrupt configuration to connect interrupt source with interrupt line. Depending upon your use case you might need both, e.g. if you are using interrupts for EDMA completion.

    Regards,
    Rishabh
  • Hi Rishabh,
    Thank you very much .
    Is there any reference / sample codes available for MMC EDMA configuration, If so can you please provide the link
  • Hi Jeba,

    What is the software package that you are using and which version.

    Regards,
    Rishabh
  • Hi Rishabh,

    The version is "ti-glsdk_dra7xx-evm_7_04_00_03"
  • Hi Jeba,

    I work on Vision SDK package.
    I have pinged a GLSDK expert who will help you on this.

    Regards,
    Rishabh

  • Hi Jeba,
    Can you let me know the background of the question?

    Is this for eMMC or SD? Is this for performance reasons or some other system reasons?

    MMC driver uses ADMA when enabled in the hardware:
    if (val & MADMA_EN)
    host->use_adma = true;

    ADMA being a master DMA and internal to the IP has better performance than SDMA and EDMA as well.

    Even to switch to EDMA you don't need to explicitly configure any thing except for modifying device tree node to inform MMC to use EDMA.


    Regards,
    RK
  • Hi RK,
    Thank you very much for your support.

    Please find the below details to get the background,
    We want to use MMC1 port. we are connecting a external device to this port. we have disabled the default MMC1 in the device tree.
    We have configured the MMC driver and we are able to communicate with the external device. without EDMA we are able to read the stored data from that device in polling mode.

    Now, we want to make the reading via EDMA. can you clarify the below,
    1. What should be the Source address for our Transfer configuration (P set)
    2. Which event number we should use for the MMC1_DREQ_RX
    3. we are using DMA cross bar 62 is this correct?
  • Hi Sangeetha,
    You haven't clarified what's the external device.
    Is it a storage device such as SD or MMC?
    Is it an SDIO based card?

    Regards,
    RK
  • Hi Sangeetha,
    In addition to above details, please share your board dts file so that I can check your ocnfiguration.

    Regards,
    RK
  • devicetree.rarHi RK,

    we are using SDIO Card.

    Please find the attached dts, dtsi file. also attached the configuration file that we are using.

    Kindly check are we missing anything?

    Please provide details for the below also

    1. What should be the Source address for our Transfer configuration (P set)

    2. Which event number we should use for the MMC1_DREQ_RX

    3. we are using DMA cross bar 62 is this correct?

    Thanks and Regards,

    Sangeetha

  • Hi RK,

    Kindly provide the details.

    Please provide details for the below also

    1. What should be the Source address for our Transfer configuration (P set)

    2. Which event number we should use for the MMC1_DREQ_RX

    3. we are using DMA cross bar 62 is this correct?

    Do you have the chance to see the attachment as you requested. kindly provide your feedback.

    Thanks and Regards,

    Sangeetha

  • Hi RK,

    Do you have the chance to go through the attached files. Kindly provide your feedback.
  • Hi Sangeeta,

    Yes, I have been through the files and I have a few questions.

    I'm not quite clear on what are you trying to do here.

    1. What's the SDIO device connected?
    2. Are you trying to port an existing sdio driver/code to Linux? 
    3. Why did you disable the default device in dts? You can use the existing MMC/SDIO controller driver. All you should need is to have a device driver for the end device to talk to the SDIO controller. Using the existing framework will simplify the whole thing and make it easy for you to implement as well to maintain.
    4. If this is the first time you are interfacing with an SDIO device with DRA7x under Linux then you may refer to an existing example such as TI WiliK (WLAN) driver to understand how it communicates with the underlying SDIO controller. Look into drivers/net/wireless/ti/wlcore/sdio.c

    Regards,
    RK

  • Hi RK,
    Please find the details.

    We are using a FPGA memory device connected to the SDSlot.
    with the driver attached in the previous post we are able to read the data in polling mode. we want to read it via EDMA.
    For this, we need to configure EDMA and IRQ but we are not able to get the proper details.
    Kindly guide us to configure EDMA in linking mode for the SDIO (MMC1 DRA746).

    With the default drivers, it is inserted and activated during boot itself. currently we want to read the SDIO data from the application via EDMA.

    Regards,
  • sdio_irq_issue_1.xlsxHi RK,

    Please find the below  details and the attachment  for better understanding,

    We are trying to connect an external FPGA to the SD slot via SDIO interface.

    For this we have written a driver code in polling mode to read the data, this is working fine and we are able to read the data properly.

    We want to update this code to use EDMA, but this is not working for us. Please find the attached sheet “sdio_irq_issue_1.xlsx” for more details.

    1. Without edma_start(i.e.Manual trigger) EDMA call back is not occurring. ( We expect the call back to be event triggered by EDMA_DREQ_61)  Please educate us to configure Event triggering instead of current manual triggering.          

    2  We cannot set the MPU_IRQ_83 (MMC1_RX) line. Is our configuration procedure correct?        

    Kindly inform us are we missing anything in the configuration.

  • Hi RK,

    Currently we have enabled the default MMC in the device tree, we have set the host -> use_dma.
    We are receiving the irq call back and transfer complete flag is set.

    Can you please inform us what can be the destination address of the DMA, from where we can get this details.

    Thanks and Regards,
    Sangeetha
  • Hi Sangeetha,
    As I mentioned earlier you don't need to change any controller side parameters including host->use_dma.
    This is automatically set by the driver.

    Also, the destination DMA address depends on whether the transfer is from DEV_TO_MEM or MEM_TO_DEV.

    In case of MEM_TO_DEV, it's the MMCHS_DATA register address and for DEV_TO_MEM it's the target buffer address provided by the block layer.

    This is automatically handled inside the block layer and the MMC driver.

    Once you enable default MMC device in the device tree, are you able to see the probe() complete?
    Do you see the device enumerated as expected?
    If you are able to read from the device or write to the device then it's already working as expected because every transfer is a DMA transfer.

    Regards,
    RK
  • Hi RK,

    We were not able to use the TI Frame work as such. since we are using customer specific FPGA which has a different command flow than the default kernel.
    please find the below steps we have checked

    1. With TI framework, 'omap_hsmmc_probe' is success and can able to register IRQ properly. (Filename: drivers/mmc/host/omap_hsmmc.c)

     

    2. While trying 'mmc_rescan_try_freq()' in drivers/mmc/core/core.c, sdio_reset() call is failing. It is because of the stuck at mmc_io_rw_direct_host() call inside sdio_reset(). As we are using customer specific FPGA board, we cannot use the CMD52 given in the mmc_io_rw_direct_host() andso stuck occurs.

     

    3. If we ignore sdio_reset() call, it is again failing in mmc_send_io_op_cond() API while calling mmc_attach_sdio(). mmc_send_io_op_cond() is trying to send CMD5 which is not supported by our FPGA. So we have excluded TI's flow and hardcoded MMC1 with our own commands to setup FPGA board (ie) PAD mux, clock configuration, init procedure, bus power configuration, sequence of commands (Reset, SDR mode set & READ MULTIPLE BLOCK commands) to FPGA.

     

    4. After this procedure, we are able to see interrupts for data read. If I put OMAP_HSMMC_READ(host->base, DATA) inside interrupt handler I can get the correct read value(We aware of data read procedure should not be inside interrupt handler. But for the initial check we tried like this). So here we can confirm that data is read by polling method. Next we are trying to read the data by DMA.

     

    5. We understood that DMA is already configured in omap_hsmmc_probe() and can get tx_chan and rx_chan.

     

    6. Now the question is, what API we need to use to get data from DMA. What is the source and destination address? In omap_hsmmc_request() API, we can see the omap_hsmmc_start_dma_transfer() call. But we cannot figure out when this omap_hsmmc_request() getting called. If we call it manually, this call is not succeeded.

    We are not receiving any DMA callback function also.

    Kindly provide your inputs, how we can proceed further.

    Thanks and Regards,
    Sangeetha

  • Sangeeta,
    You can follow the exact steps done in omap_hsmmc.c file to configure DMA and read data using DMA.
    Just add a new driver (with your existing code) and use the compatibility flag in device tree.
    This way your driver's probe will be called as part of device driver initialisation. Use omap-dma engine apis for rest of the configuration.

    Regards,
    RK
  • Hi RK,

    We have checked as per your suggestion with the compatibility flag.

    Now we are able to transmit commands in finite transfer type and read data through this driver.

    Default all the commands are transmitted as finite transfer type, if we change that to infinite transfer type there is no command complete.

    after this there is no response.

    Kindly suggest.

  • Hi Sangeeta,
    Great, glad you could make progress.
    Can you please describe the command sequence between two cases?
    1. FInite
    2. Infinite

    Are you saying when you do not set block count there's no CC?

    Regards,
    RK
  • CC: Sangeetha

    Dear RK,

    Thanks for the help.

    We are sending CMD0 and CMD18 for our FPGA board.

    For Finite transfer,

    1) we have initialized sg buffer with dma size(current size is 20480 bytes).

    2) Set block length as 512

    3) Set block count as dma_size/block length (ie) 20480/512 = 40 blocks

    4) Set stop opcode too in mmc_request structure

    Result:

    i) Got one dma callback after CMD18 CC completes.

    ii) Got one TC interrupt after 20480 bytes transferred.

    iii) Read values are ok.

    For InFinite transfer,

    We have disabled BCE in sdio_hsmmc_start_command() and the remaining flow is same as finite transfer steps (1) to (4). [We understand that setting block count will not affect if we disable BCE bit]

    Result:

    i) Got one dma callback after CMD18 CC completes.

    ii) Not getting TC interrupt. Because of this driver code got stuck after this line.

    As this is infinite transfer, 'req_in_progress' value will be 1 in dma callback API. So mmc_request_done() will not be called. But why we are not getting TC interrupt?

    For finite transfer also, we are expecting TC interrupt after every block length (512)bytes transferred. But we are getting it only after full size is transferred. Response is same for EDMA as well as SDMA. ITCINTEN is not set in edma code (drivers/dma/edma.c). It hangs the system when I'm trying to enable it. Is this is the root cause for the infinite transfer issue? If so, Kindly let us know how to fix it.

     

    Regards,

    Rajeswari S

  • Dear RK,

    In addition to previous message, we have tried stream oriented transfer instead of block transfer. STR bit is set in CON register. For this also, we got the same response as like infinite block transfer. (ie) Got one dma callback after CMD18 CC completes, NOT getting TC interrupt and got stuck.

    Anything have we missed out seriously while going for continuous data?

    Thanks,

    Rajeswari S

  • Hi Rajeswari,
    The behaviour is expected. You get TC only at the end of the transfer not after every block.

    To get an interrupt at every block end you can set MMCHS_HCTL[16]SBGR bit to enable BGE interrupt (MMCHS_STAT[2]BGE).
    Once you enable SBGR the controller will stop after transferring data size equal to teh block length. The host driver needs to explicitly issue a resume request -MMCHS_HCTL[CR] - to continue the transfer.

    Also, when doing infinite transfer you will not get a TC until you send a command 12 (STOP).

    Regards,
    RK
  • Dear RK,

    Thanks for the reply.

    We are not preferring 'Stop at Block Gap' feature as it will cause real time data miss out. Anyway we will give a try.

    Regarding infinite transfer, we already sent CMD12(STOP). Still we are not getting TC, so stuck occurs. Please find the used code below:

            /* Send CMD 18 (READ_MULTIPLE_BLOCK) */
            memset(ptr->buffer, 0, size);
            sg_init_one(&sg, ptr->buffer, size);

            mrq.cmd = &cmd;
            mrq.data = &data;
            mrq.stop = &stop;

            mrq.cmd->opcode = MMC_READ_MULTIPLE_BLOCK;
            mrq.cmd->arg = 0x4809C220;
            mrq.cmd->flags =  MMC_RSP_R1 | MMC_CMD_ADTC;

            mrq.data->blksz = blocklen;                           /* blocklen = 512 */
            mrq.data->blocks = (size / blocklen);           /* size = 20480, it does not matter as we set infinite transfer */
            mrq.data->flags = MMC_DATA_READ;
            mrq.data->sg = &sg;
            mrq.data->sg_len = sg_len;

            mrq.stop->opcode = MMC_STOP_TRANSMISSION;
            mrq.stop->arg = 0;
            mrq.stop->flags = MMC_RSP_R1B | MMC_CMD_AC;

            mmc_wait_for_req(host->mmc, &mrq);

    Any suggestion on this RK?

    Regards,

    Rajeswari S

  • Hi Rajeswari,

       The following assignment is wrong 

    mrq.cmd->arg = 0x4809C220;

    This should be the argument for the CMD18 which is the address of the first data block that needs to be read form the card not MMCHS_DATA.

    It should be a valid block address between 0x0 and the max number of sectors (blocks) -1.

    Regards,

    RK

  • Dear RK,

    We have tried with arg value as 0. Still it is not working for infinite transfer.

    Regards,
    Rajeswari S
  • Hi,
    Can you enable CONFIG_MMC_DEBUG as described below and share the log?
    processors.wiki.ti.com/.../Processor_SDK_Linux_Automotive_FAQ

    Regards,
    RK
  • Hi,
    Also, Try with different offsets in "arg" - 0x0, 0x100, 0x400 etc.

    Regards,
    RK
  • HI,
    Can you share the data sheet of the card that's being used?

    Regards,
    RK
  • Hi,
    I hope you were able to resolve the issue as I didn't receive any feedback in last two weeks.

    Please reply back if you have any follow up questions.

    Regards,
    RK
  • Hi RK,

    Thank you very much for your support.

    Still we are facing some issues in configuring the SDIO with our FPGA. Currently we have put this task on hold.

    We will ask for any clarifications if needed in future.

    Thanks and Regards,

    Sangeetha

  • Hi Sangeetha,

    thanks for the update. I will close the thread for now, but when you start working on it again you can post questions here to reopen it (or start new thread if this one has locked due to inactivity time-out).

    Regards,
    Yordan
  • Hi Yordan,
    Okay. Thank you.