最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

How to setup the clock for SD/MMC in Linux Driver

工作和技术 crifan 3796浏览 0评论

How to setup the clock for SD/MMC in Linux Driver

1. set up clock

Driversmmccoremmc.c

(for SD, similar is Driversmmccoresd.c)

static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,

       struct mmc_card *oldcard)

{

………..

//1.Setup to high speed if hw support

       /*

       * Activate high speed (if supported)

       */

       if ((card->ext_csd.hs_max_dtr != 0) &&

              (host->caps & MMC_CAP_MMC_HIGHSPEED)) {

              err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,

                     EXT_CSD_HS_TIMING, 1);

              if (err != MMC_ERR_NONE)

                     goto free_card;

              mmc_card_set_highspeed(card);

              mmc_set_timing(card->host, MMC_TIMING_MMC_HS);

       }

//2.set the allowable clock

       /*

       * Compute bus speed.

       */

       max_dtr = (unsigned int)-1;

       if (mmc_card_highspeed(card)) {

              if (max_dtr > card->ext_csd.hs_max_dtr)

                     max_dtr = card->ext_csd.hs_max_dtr;

       } else if (max_dtr > card->csd.max_dtr) {

              max_dtr = card->csd.max_dtr;

       }

       mmc_set_clock(host, max_dtr);

………..

}

2.do set up clock

Driversmmccorecore.c

void mmc_set_clock(struct mmc_host *host, unsigned int hz)

{

………..

       host->ios.clock = hz;

       mmc_set_ios(host);

………..

}

3. set io related info, include clock

static inline void mmc_set_ios(struct mmc_host *host)

{

………..

       host->ops->set_ios(host, ios);

}

4.call driver’s set_ios function

Here , host->ops->set_ios is

DriversmmchostYOUR_ARCH_NAME_mmc.c

static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)

{

       if (ios->clock) {

              if (ios->clock >= host->mclk) {

//for bypass mode, the MCLK(input clock/main clock/mclk)

//directly driven into the MCLCLK(card clock/cclk)

//that is MCLK=MCLCLK, mclk=cclk

                     clk = MCI_CLK_BYPASS;

                     host->cclk = host->mclk;

              } else {

//calculate the clkDiv in follow picture :

//(in SD/MMC datasheet )

                     if ( host->mclk < (2 * ios->clock) )

                     {

                            clk = 2;

                     }

                     else

                     {

                            clk = (host->mclk -(2 * ios->clock)) / (2 * ios->clock) + 1;

                           

                            if (clk > 255)

                                   clk = 255;

                     }

                     if ( clk == 1)

                     clk = 16;

                     //clk = 255;

//according to Mclclk(card clock)= Mclk(input clock/main clock)/(2x (clkDiv + 1)),

//calculate out the real cclk(card clock)

                     host->cclk = host->mclk / (2 * (clk + 1));

              }

              clk |= MCI_CLK_ENABLE;

       }

       if (host->plat->translate_vdd)

              pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);

       switch (ios->power_mode) {

       case MMC_POWER_OFF:

              break;

       case MMC_POWER_UP:

              pwr |= MCI_PWR_UP;

              break;

       case MMC_POWER_ON:

              pwr |= MCI_PWR_ON;

              break;

       }

       if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)

              pwr |= MCI_ROD;

       if (ios->bus_width == MMC_BUS_WIDTH_4 ) {

              DBG(host,"MMC: Setting controller bus width to %dn",4);

              clk |= MCI_CLK_WIDEBUS;      

       }

//write the setting value into the reg

       writel(clk, host->base + MMCICLOCK);

……….

}

5.Note:

In which the host->mclk is get in:

static int mmci_probe(struct amba_device *dev, void *id)

{

       host->mclk = clk_get_rate(host->clk);

}

\archarmmach-YOUR_ARCH_NAMEClock.c

unsigned long clk_get_rate(struct clk *clk)

{

…….

       return clk->rate;

}

【Suffix】

Related articles:

【转】mmci控制器驱动(2.6.22.5) — (1) 驱动注册

http://hi.baidu.com/serial_story/blog/item/24bb1a2dd050fd3c359bf701.html

转载请注明:在路上 » How to setup the clock for SD/MMC in Linux Driver

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
79 queries in 0.219 seconds, using 22.16MB memory