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.

TMS320DM8148 MMC/SD Interface Initialisation

Other Parts Discussed in Thread: TMS320DM8148, SYSCONFIG, CCSTUDIO

Hello,

I wan't to use the MMC/SD1-Interface of the TMS320DM8148 for a bare metal program.
I have already implemented a solution for AM335x. The MMC/SD-Interface of both cpu
looks very similar.

The first thing I have done is the Pinmuxing for MMC/SD1-Interface according to the datasheet of the TMS320DM8148.

REG(PINCNTL1)  = 0x00060000 | MUXMODE_SD1_CLK;
REG(PINCNTL2)  = 0x000E0000 | MUXMODE_SD1_CMD;

REG(PINCNTL3)  = 0x000E0000 | MUXMODE_SD1_DAT0;
REG(PINCNTL4)  = 0x000E0000 | MUXMODE_SD1_DAT1;
REG(PINCNTL5)  = 0x000E0000 | MUXMODE_SD1_DAT2;
REG(PINCNTL6)  = 0x000E0000 | MUXMODE_SD1_DAT3;    
REG(PINCNTL10) = 0x000E0000 | MUXMODE_SD1_DAT4;
REG(PINCNTL11) = 0x000E0000 | MUXMODE_SD1_DAT5;
REG(PINCNTL12) = 0x000E0000 | MUXMODE_SD1_DAT6;
REG(PINCNTL13) = 0x000E0000 | MUXMODE_SD1_DAT7;

REG(PINCNTL80) = 0x00060000 | MUXMODE_SD1_SDCD;
REG(PINCNTL74) = 0x000E0000 | MUXMODE_SD1_POW;




After that enabled the clock CM_ALWON_MMCHS_1_CLKCTRL. But the registers of the MMC/SD1-Interface were not accesible.
So I enable all clocks in CM_ALWON.
Now the access to the MMC/SD1-Interface was possible.

Now I reuse the code for the AM335x to enable the MMC/SD1-Interface. This initialisation begins with the following steps
1. Set the SOFTRESET-Bit in SD_SYSCONFIG
2. Poll for RESETDONE in SD_SYSSTATUS

here RESETDONE are always zero.

The question is what causes RESETDONE to never goes ready. Is there any other prerequisiste of this interface.

Is there any StarterWare-like software for the TMS320DM8148 where i can see some examples.

  • If I change the boot configuration so that the MMC is the first boot the RESETDONE works.


    But there is the next issue. No signal output on CMD and CLK for MMC1. In the SD_STAT-Register CTO is set

  • I have moved this thread to the DM814X forum, where platform specific questions might be answered better. Please note that there is no Starterware support for DM814X.
  • Hi Martin,

    Martin Ko said:
    I wan't to use the MMC/SD1-Interface of the TMS320DM8148 for a bare metal program.

    Do you mean that you are not planning to use u-boot and linux kernel?

    Martin Ko said:
    Now I reuse the code for the AM335x to enable the MMC/SD1-Interface. This initialisation begins with the following steps

    The DM814x ROM Code and u-boot is using MMC/SD1 interface (0x481D8000) for booting. You can refer to the DM814x ROM code chapter section 4.7.4 MMC/SD Cards and u-boot source code for example of MMC/SD1 programming.

    You can refer also to the CCStudio (GEL file + c/h files) examples in the DM8148 TI EVM software package.

    Regards,
    Pavel



     


  • Hello Pavel,

    Yes I don't want to use U-Boot or Linux for that.
    For me it seems that the MMC/SD-Registers for both processors are the same.
    So I assume that adapting the AM335x code to the DM8148 should not be a big problem.
    The parts I have adapted are: Pinmux (Pinctl), Clock configuration
    For the clocks I have all clocks in CM_AWLON enabled because enabling only CM_ALWON_MMCHS_1_CLKCTR don't work

    In the chapter section 18.3.2.1 there are two clocks mentioned: OCP-Clock and CLKADPI. Which clocks in the
    CM_...-Registers corresponds to these to clocks?

    Here the current status:
    The SD Soft Reset Flow as described in section 18.3.2.2 works now after I switch the BOOT-Pins to MMC first.
    Also the MMC Host and Bus Configuration also works (section 18.3.2.5).

    The strange thing is sending an CMD. After the SD_CMD is written with the CMD (same code as AM335x) there is no output signal on CLK or CMD pin on the scope. After that the CTO Bit (Command timeout error) is set in the MMCHS_STAT-Register.

    Are there any other missing prerequisite that is missing here?
    I'll also look at the CCstdio files



    thank you
  • Martin,

    Martin Ko said:
    For me it seems that the MMC/SD-Registers for both processors are the same.
    So I assume that adapting the AM335x code to the DM8148 should not be a big problem.

    Yes, should be similar. I can find that MMC/SD/SDIO controller is similar between DM814x/AM387x and AM335x:

    Martin Ko said:
    The parts I have adapted are: Pinmux (Pinctl), Clock configuration

    Can you send me these settings (registers with values)?

    Martin Ko said:
    For the clocks I have all clocks in CM_AWLON enabled because enabling only CM_ALWON_MMCHS_1_CLKCTR don't work

    What do you mean by "don't work"? Do you mean you can not access (read/write) the MMC1/SD1 registers?

    Martin Ko said:
    In the chapter section 18.3.2.1 there are two clocks mentioned: OCP-Clock and CLKADPI. Which clocks in the
    CM_...-Registers corresponds to these to clocks?

    I think CM_ALWON_MMCHS_1_CLKCTRL/0x48181620 register should be enough. What other CM_x registers you have program in order to be able to access MMC1/SD1 registers?

    Regards,
    Pavel

  • I check this with CCStudio (without using u-boot, linux kernel, GEL file, c/h files). When power on the DM814x EVM I have CM_ALWON_MMCHS_1_CLKCTRL/0x48181620 = 0x00030000, and MMC1/SD1 register 0x481D8000 can not be accessed (read/write). Then I manually modify CM_ALWON_MMCHS_1_CLKCTRL/0x48181620 to 0x00000002 and then I am able to access (read) 0x481D8000 register.

    Thus I can sum up we need only CM_ALWON_MMCHS_1_CLKCTRL/0x48181620 = 0x2 in order to be able to access MMC1/SD1 registers.

    Regards,
    Pavel
  • Hello Pavel,

    there was an error in my code which uses MMC2-Interface instead of MMC1. (redefine MMC1-Address with MMC2 Address).

    Now If the MMC-Device is the first in the boot order sending/receiving commands to the SD-Card over MMC1 is possible.

    If I change the boot order to NAND-Flash first I can read/write to the MMC1-Registers but RESETDONE never get ready.


    Here is the log message from my program:

    * "setting 0x48181404=0x00000002"
    * "setting 0x48181408=0x00000002"
    * "setting 0x4818140c=0x00000002"
    * "setting 0x48181410=0x00000002"
    * "setting 0x48181414=0x00000002"
    * "setting 0x48181418=0x00000002"
    * "setting 0x4818141c=0x00000002"
    * "setting 0x48181420=0x00000002"
    * "setting 0x48181424=0x00000002"
    * "setting 0x48181428=0x00000002"
    * "setting 0x4818142c=0x00000002"
    * "setting 0x48181430=0x00000002"
    * "setting 0x48181540=0x00000002"
    * "setting 0x48181544=0x00000002"
    * "setting 0x48181548=0x00000002"
    * "setting 0x4818154c=0x00000002"
    * "setting 0x48181550=0x00000002"
    * "setting 0x48181554=0x00000002"
    * "setting 0x48181558=0x00000002"
    * "setting 0x4818155c=0x00000002"
    * "setting 0x48181560=0x00000002"
    * "setting 0x48181564=0x00000002"
    * "setting 0x48181568=0x00000002"
    * "setting 0x4818156c=0x00000002"
    * "setting 0x48181570=0x00000002"
    * "setting 0x48181574=0x00000002"
    * "setting 0x48181578=0x00000002"
    * "setting 0x48181580=0x00000002"
    * "setting 0x48181584=0x00000002"
    * "setting 0x48181588=0x00000002"
    * "setting 0x4818158c=0x00000002"
    * "setting 0x48181590=0x00000002"
    * "setting 0x48181594=0x00000002"
    * "setting 0x48181598=0x00000002"
    * "setting 0x4818159c=0x00000002"
    * "setting 0x481815a8=0x00000002"
    * "setting 0x481815b4=0x00000002"
    * "setting 0x481815b8=0x00000002"
    * "setting 0x481815c4=0x00000002"
    * "setting 0x481815d0=0x00000002"
    * "setting 0x481815d4=0x00000002"
    * "setting 0x481815dc=0x00000002"
    * "setting 0x481815e4=0x00000002"
    * "setting 0x481815e8=0x00000002"
    * "setting 0x481815ec=0x00000002"
    * "setting 0x481815f0=0x00000002"
    * "setting 0x481815f4=0x00000002"
    * "setting 0x481815f8=0x00000002"
    * "setting 0x481815fc=0x00000002"
    * "setting 0x48181600=0x00000002"
    * "setting 0x48181604=0x00000002"
    * "setting 0x48181618=0x00000002"
    * "setting 0x4818161c=0x00000002"
    * "setting 0x48181620=0x00000002"
    * "setting 0x48181624=0x00000002"
    * "setting 0x48181628=0x00000002"
    * "gpio1_sysconfig=0x00000000"
    * "Content of ALWON_MMCGS_1 0x00000002"
    * "PINCNTL6=0x000e0001"
    * "PINCNTL9=0x000e0000"
    * "USBPLL_PWRCTRL=0x00000030"
    * "USBPLL_CLKCTRL=0x0611080d"
    * "Using MMC/SD-Interface 1"
    * "poll for RESETDONE failed"

    Here the register you have mentioned is also included. It would be interesting whether the RESETDONE-behaviour is the same on your board.

    thank you

    BR

    Martin

  • Martin,

    Are you using MMCHS_SYSCONFIG[1] SOFTRESET bit to generate the software reset? MMCHS_SYSCONFIG is at address 0x481D8110?

    Or you are using MMCHS_HL_SYSCONFIG[0] SOFTRESET bit at address 0x481D8010?

    Regards,
    Pavel
  • Hi Pavel,

    I using the SD_SYSCONFIG (RegOffset 0x110) and write the value 0x2 to them (SOFTRESET). After that I poll for SYSSTATUS (RegOffset 0x114) Bit 0 goes high.
  • Martin,

    Martin Ko said:
    I using the SD_SYSCONFIG (RegOffset 0x110) and write the value 0x2 to them (SOFTRESET). After that I poll for SYSSTATUS (RegOffset 0x114) Bit 0 goes high.

    This looks correct behaviour to me. What are your concerns regarding this?

    We have something similar in u-boot code base:

    u-boot/drivers/mmc/omap_hsmmc.c

    static int mmc_init_setup(struct mmc *mmc)
    {
        hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv;

    ........

    writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET, &mmc_base->sysconfig); ---> write 0x2 in MMCHS_SYSCONFIG[1] SOFTRESET
        start = get_timer(0);
        while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {  --> wait until MMCHS_SYSSTATUS[0] RESETDONE is 1 or timeout
            if (get_timer(0) - start > MAX_RETRY_MS) {
                printf("%s: timedout waiting for cc2!\n", __func__);
                return TIMEOUT;
            }
        }
        writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) {
            if (get_timer(0) - start > MAX_RETRY_MS) {
                printf("%s: timedout waiting for softresetall!\n",
                    __func__);
                return TIMEOUT;
            }
        }

    Note that in u-boot, after MMCHS_SYSCONFIG[1] SOFTRESET, we initiate MMCHS_SYSCTL[24] SRA reset also.

    Regards,
    Pavel

     

  • there is another interesting difference between the two boot modes:

    boot mode=mmc (working variant): CLKACTIVITY_SDIO_CLKADPI_GCLK is Active.
    boot mode=nand (not working variant): CLKACTIVITY_SDIO_CLKADPI_GCLK is Inactive.

    I suppose that CLKADPI is required for MMC/SD-Interface because it mentioned in the overviewe on chapter 18.1.1.
    I write 0x2 to CM_ALWON_L3_SLOW_CLKSTCTRL but it has no effect on the SDIO_CLKADPI.
  • Hi Pavel,

    on my board the polling RESETDONE never success. It only works if the first boot device is MMC.

    there is another interesting difference between the two boot modes:

    boot mode=mmc (working variant): CLKACTIVITY_SDIO_CLKADPI_GCLK is Active.
    boot mode=nand (not working variant): CLKACTIVITY_SDIO_CLKADPI_GCLK is Inactive.

    I suppose that CLKADPI is required for MMC/SD-Interface because it mentioned in the overview on chapter 18.1.1.
    I write 0x2 to CM_ALWON_L3_SLOW_CLKSTCTRL but it has no effect on the CLKACTIVITY_SDIO_CLKADPI_GCLK (remains INACTIVE).
  • Hi Pavel,

    on my board the polling RESETDONE never success. It only works if the first boot device is MMC.

    there is another interesting difference between the two boot modes:

    boot mode=mmc (working variant): CLKACTIVITY_SDIO_CLKADPI_GCLK is Active.
    boot mode=nand (not working variant): CLKACTIVITY_SDIO_CLKADPI_GCLK is Inactive.

    I suppose that CLKADPI is required for MMC/SD-Interface because it mentioned in the overview on chapter 18.1.1.
    I write 0x2 to CM_ALWON_L3_SLOW_CLKSTCTRL but it has no effect on the CLKACTIVITY_SDIO_CLKADPI_GCLK (remains INACTIVE).

    could be there some missing clock dependencies?
  • Martin,

    In the DM814x u-boot, I see CM_ALWON_L3_SLOW_CLKSTCTRL[27] CLKACTIVITY_SDIO_CLKADPI_GCLK is 0x1, and also MMCHS_SYSSTATUS[0] RESETDONE is 1. You can explore the source code to align with it:

    http://arago-project.org/git/projects/u-boot-omap3.git?p=projects/u-boot-omap3.git;a=shortlog;h=refs/heads/ti81xx-master

    You can start with files:
    u-boot/board/ti/ti8148/evm.c
    u-boot/drivers/mmc/omap_hsmmc.c

    Regards,
    Pavel

  • Hi Pavel,

    Thank you for that u-boot link. I have tried some u-boot init code. I used the following functions from evm.c

    s_init() which unlocks the plls and class prcm_init
    prcm_init() which configures the plls

    init_board() muxing pins. The function hangs. I think this is caused by polling for UART_SYSSRS
    while( (__raw_readl(UART_SYSSTS) & 0x1) != 0x1);

     

     

    What I don’t understand is that SDIO_CLKADPI_GCLK never goes high. The Term SDIO_CLKADPI are only mentioned once in the whole Reference Manual. So I cannot find the Registers/Clocks on which SDIO_CLKADPI depends. Mabe is there any other clock that must be explicit enabled for SDIO_CLKADPI?

    Is SDIO_CLKADPI an requirenment of MMC1?

    BR

    Martin

     

  • Martin,

    Martin Ko said:

    What I don’t understand is that SDIO_CLKADPI_GCLK never goes high. The Term SDIO_CLKADPI are only mentioned once in the whole Reference Manual. So I cannot find the Registers/Clocks on which SDIO_CLKADPI depends. Mabe is there any other clock that must be explicit enabled for SDIO_CLKADPI?

    Is SDIO_CLKADPI an requirenment of MMC1?

    I do not think CM_ALWON_L3_SLOW_CLKCTRL[27] CLKACTIVITY_SDIO_CLKADPI_GCLK is a must for the MMC1.

    In u-boot source code (board/ti/ti8148/evm.c) we have write 0x2 in CM_ALWON_L3_SLOW_CLKCTRL[1:0] CLKTRCTRL and then check only for UART and L3_SLOW clocks. Then after we enable MMC1 clock, we do not check bit [27] CLKACTIVITY_SDIO_CLKADPI_GCLK to be 1.


    /*
     * Enable the clks & power for perifs (TIMER1, UART0,...)
     */
    void per_clocks_enable(void)
    {
        u32 temp;

        __raw_writel(0x2, CM_ALWON_L3_SLOW_CLKSTCTRL);

    .....

    /* UARTs */
        __raw_writel(0x2, CM_ALWON_UART_0_CLKCTRL);
        while(__raw_readl(CM_ALWON_UART_0_CLKCTRL) != 0x2);

        __raw_writel(0x2, CM_ALWON_UART_1_CLKCTRL);
        while(__raw_readl(CM_ALWON_UART_1_CLKCTRL) != 0x2);

        __raw_writel(0x2, CM_ALWON_UART_2_CLKCTRL);
        while(__raw_readl(CM_ALWON_UART_2_CLKCTRL) != 0x2);

        while((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & 0x2100) != 0x2100);
    ...

    /* HSMMC */
        __raw_writel(0x2, CM_ALWON_HSMMC_CLKCTRL);
        while(__raw_readl(CM_ALWON_HSMMC_CLKCTRL) != 0x2);

    }

    May be this [27] bit will come one when you enable all the MMC clocks (MMC0/1/2) not just MMC1, and write 0x2 in bits [1:0] CLKTRCTRL. Have you tried this?

    In CCStudio GEL file, we have the same as in u-boot. Bit [27] is not checked after we enable MMC1 functional clock in CM_ALWON_MMCHS_1_CLKCTRL.


    Regards,
    Pavel