- 1.首先分析 sd/mmc 初始化:
-
- puts ("SD/MMC: ");
- mmc_exist = mmc_initialize(gd->bd);
-
- int mmc_initialize(bd_t *bis)
- {
- struct mmc *mmc;
- int err;
-
- INIT_LIST_HEAD(&mmc_devices);
-
- cur_dev_num = 0;
-
- if (board_mmc_init(bis) < 0)
- cpu_mmc_init(bis);
-
-
-
-
-
-
-
-
-
-
-
-
-
- ---------
- void setup_hsmmc_clock(void)
- {
- u32 tmp;
- u32 clock;
- u32 i;
-
-
- tmp = CLK_SRC4_REG & ~(0x0000000f);
- CLK_SRC4_REG = tmp | 0x00000006;
-
- tmp = CLK_DIV4_REG & ~(0x0000000f);
-
- clock = get_MPLL_CLK()/1000000;
- for(i=0; i<0xf; i++)
- {
- if((clock / (i+1)) <= 50) {
- CLK_DIV4_REG = tmp | i<<0;
- break;
- }
- }
-
- #ifdef USE_MMC2
-
- tmp = CLK_SRC4_REG & ~(0x00000f00);
- CLK_SRC4_REG = tmp | 0x00000600;
-
-
- tmp = CLK_DIV4_REG & ~(0x00000f00);
- CLK_DIV4_REG = tmp | i<<8;
- #endif
-
- */
- ------------------------------
-
- void setup_hsmmc_cfg_gpio(void)
- {
- ulong reg;
-
-
-
- reg = readl(GPG0CON) & 0xf0000000;
-
- writel(reg | 0x02222222, GPG0CON);
- reg = readl(GPG0PUD) & 0xffffc000;
-
- writel(reg | 0x00002aaa, GPG0PUD);
- writel(0x00003fff, GPG0DRV);
-
- #ifdef USE_MMC2
-
-
- reg = readl(GPG2CON) & 0xf0000000;
- writel(reg | 0x02222222, GPG2CON);
- reg = readl(GPG2PUD) & 0xffffc000;
- writel(reg | 0x00002aaa, GPG2PUD);
- writel(0x00003fff, GPG2DRV);
-
- */
- -----------------------------
- int smdk_s3c_hsmmc_init(void)
- {
- #ifdef USE_MMC0 //emmc
- err = s3c_hsmmc_initialize(0);
-
- #endif
- #ifdef USE_MMC2 //sd
- err = s3c_hsmmc_initialize(2);
- #endif
- static int s3c_hsmmc_initialize(int channel)
- {
- struct mmc *mmc;
-
- mmc = &mmc_channel[channel];
-
- sprintf(mmc->name, "S3C_HSMMC%d", channel);
-
- mmc->priv = &mmc_host[channel];
-
- mmc->send_cmd = s3c_hsmmc_send_command;
-
- mmc->set_ios = s3c_hsmmc_set_ios;
-
- mmc->init = s3c_hsmmc_init;
-
-
- mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
-
- mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
- #if defined(USE_MMC0_8BIT) || defined(USE_MMC2_8BIT)
- mmc->host_caps |= MMC_MODE_8BIT;
- #endif
- 最小工作平率
- mmc->f_min = 400000;
- mmc->f_max = 52000000;
-
- mmc_host[channel].clock = 0;
-
- switch(channel) {
- case 0:
- mmc_host[channel].ioaddr = (void *)ELFIN_HSMMC_0_BASE;
- break;
-
- case 2:
- mmc_host[channel].ioaddr = (void *)ELFIN_HSMMC_2_BASE;
- break;
-
- default:
- printk("mmc err: not supported channel %d\n", channel);
- }
-
- return mmc_register(mmc);
- }
-
-
- int mmc_register(struct mmc *mmc)
- {
-
- mmc->block_dev.if_type = IF_TYPE_MMC;
-
- mmc->block_dev.dev = cur_dev_num++;
- mmc->block_dev.removable = 1;
-
-
-
-
-
- INIT_LIST_HEAD(&mmc->link);
-
- list_add_tail(&mmc->link, &mmc_devices);
-
- return 0;
- }
- static int s3c_hsmmc_init(struct mmc *mmc)
- {
- struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
-
- sdhci_reset(host, SDHCI_RESET_ALL);
-
- host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
- sdhci_init(host);
-
- sdhci_change_clock(host, 400000);
-
- return 0;
- }
- 时钟全部初始化完成,返回
- ===============================================
-
- 这里为什么是只定义0,是因为,当宏定义打开通道2时
-
-
-
-
- mmc = find_mmc_device(0);
- -------------------------------------------
- <pre class="cpp" name="code">struct mmc *find_mmc_device(int dev_num)
- {
- struct mmc *m;
- struct list_head *entry;
-
- list_for_each(entry, &mmc_devices) {
- m = list_entry(entry, struct mmc, link);
-
- if (m->block_dev.dev == dev_num)
- return m;
- }
-
- printf("MMC Device %d not found\n", dev_num);
-
- return NULL;
- }
- ====================================
-
-
- if (mmc) {
- err = mmc_init(mmc);
- 至此对sd/mmc初始化部分分析完成。
- ====================================================
- </pre><br>
- <pre></pre>
- <pre class="cpp" name="code">修改:
- 以前是从NAND flash启动,现在是从emmc启动,修改启动模式:
- /include/configs/smdkv210signle.h
-
- #define CFG_FASTBOOT_SDMMCBSP //打开 sd/mmc启动模式
-
- #define USE_MMC0 //支持 emmc (占用了通道0)
- #define USE_MMC2 //支持sd (占用了通道2)
-
- 修改 /drivers/mmc/mmc.c 使它支持 emmc 和sd
-
- int mmc_initialize(bd_t *bis)
- {
- struct mmc *mmc;
- int err;
-
- INIT_LIST_HEAD(&mmc_devices);
- cur_dev_num = 0;
-
- if (board_mmc_init(bis) < 0)
- cpu_mmc_init(bis);
-
- #if defined(DEBUG_S3C_HSMMC)
- print_mmc_devices(',');
- #endif
-
- #if ( defined(USE_MMC0 ) && defined(USE_MMC2 ) )
-
- mmc = find_mmc_device(0);
- if (mmc) {
- err = mmc_init(mmc);
- if (err)
- err = mmc_init(mmc);
- if (err) {
- printf("Card init fail!\n");
- return err;
- }
- }
- printf("emmc %ldMB\n", (mmc->capacity/(1024*1024/(mmc->read_bl_len))));
-
- mmc = find_mmc_device(1);
- if (mmc) {
- err = mmc_init(mmc);
- if (err)
- err = mmc_init(mmc);
- if (err) {
- printf("Card init fail!\n");
- return err;
- }
- }
- printf(" sd %ldMB\n", (mmc->capacity/(1024*1024/((mmc->read_bl_len)))));
-
- return 0;
- }
- #else
- mmc = find_mmc_device(0);
- if (mmc) {
- err = mmc_init(mmc);
- if (err)
- err = mmc_init(mmc);
- if (err) {
- printf("Card init fail!\n");
- return err;
- }
- }
- printf("%ldMB\n", (mmc->capacity/(1024*1024/(mmc->read_bl_len))));
- return 0;
- #endif
-
- mmc->read_bl_len :这里要说下此变量,这是emmc 里CSD[80]所定义的,指明了此emmc的块大小,对于SD卡分区格式来说,只支持512 bety 块大小。如果 mmc->read_bl_len =1024
- 的话,对于整个分区体系来说是不支持的,会造成分区不完全。所以后续代码需要修改。
posted on
2013-08-16 14:04
Nickleback
阅读(
323)
评论()
收藏
举报