eMMC总线:入门和驱动调试

eMMC总线概述

下图是eMMC总线接口的基本框架:
eMMC总线:入门和驱动调试_第1张图片
每个信号线的作用如下:

信号线 作用
CLK CLK 信号用于从 Host 端输出时钟信号,进行数据和命令传输的同步。在一个时钟周期内,CMDDAT0-7 信号上都可以支持传输 1 个比特,即 SDR 模式。此外,DAT0-7 信号还支持配置为 DDR 模式,在一个时钟周期内,传输 2 个比特。
CMD CMD 信号主要用于 HostDevice 发送 CommandDeviceHost 发送对于的 Response
DAT0-7 DAT0-7 信号主要用于 HosteMMC 之间的数据传输,数据总线可以工作在 4 bits 或者 8 bits 模式。
Data Strobe Data Strobe 时钟信号由 Device 发送给 Host,用于 Host 端进行数据接收的同步,它只能在 HS400 模式下配置启用。

eMMC总线速度模式

从《emmc 5.1》协议上看,有如下几种总线速度模式

模式 数据速率 总线位宽 总线频率 最大数据速率
legacy mode 单边采样(SDR 1、4、8bit 0-26 MHz 26 MB/s
HS mode 单边采样(SDR 1、4、8bit 0-52 MHz 52 MB/s
HSDDR mode 双边采样(DDR 4、8bit 0-52 MHz 104 MB/s
HS200 mode 单边采样(SDR 4、8bit 0-200 MHz 200 MB/s
HS400 mode 双边采样(DDR 8bit 0-200 MHz 400 MB/s
注意:
Extended CSD byte[185] HS_TIMING 寄存器可以配置总线速率模式
Extended CSD byte[183] BUS_WIDTH 寄存器用于配置总线宽度和 Data Strobe

MMC驱动总线调试

时钟频率的设置
总线速度模式下的最大时钟频率定义如下

#define MMC_HIGH_26_MAX_DTR 26000000                                                                                                                                      
#define MMC_HIGH_52_MAX_DTR 52000000                                                                                                                                             
#define MMC_HIGH_DDR_MAX_DTR    52000000                                                                                                                                         
#define MMC_HS200_MAX_DTR   200000000

mmc.c里面有函数会选择合适的频率: mmc_select_timing ()->mmc_set_bus_speed()
该函数最后调用的是:

mmc_set_clock(card->host, max_dtr);

总线宽度的设置
设备(eMMC)卡支持的总线宽度定义如下

#define EXT_CSD_BUS_WIDTH_1 0   /* Card is in 1 bit mode */                                                                                                                      
#define EXT_CSD_BUS_WIDTH_4 1   /* Card is in 4 bit mode */                                                                                                                      
#define EXT_CSD_BUS_WIDTH_8 2   /* Card is in 8 bit mode */                                                                                                                      
#define EXT_CSD_DDR_BUS_WIDTH_4 5   /* Card is in 4 bit DDR mode */                                                                                                              
#define EXT_CSD_DDR_BUS_WIDTH_8 6   /* Card is in 8 bit DDR mode */

MMC总线宽度定义
#define MMC_BUS_WIDTH_1 0
#define MMC_BUS_WIDTH_4 2
#define MMC_BUS_WIDTH_8 3

mmc.c里面有函数会选择合适的总线宽度: mmc_select_bus_width()->mmc_switch()
该函数最后调用的是:

mmc_set_bus_width(host, bus_width);

选择数据速率模式(SDR/DDR
总线支持的数据速率定义如下:

#define EXT_CSD_BUS_WIDTH_1 0   /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1   /* Card is in 4 bit mode */                                                                                                                   
#define EXT_CSD_BUS_WIDTH_8 2   /* Card is in 8 bit mode */
#define EXT_CSD_DDR_BUS_WIDTH_4 5   /* Card is in 4 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8 6   /* Card is in 8 bit DDR mode */

mmc.c里面有函数会选择合适的数据速率模式:mmc_select_powerclass()
该函数具体实现如下:

static int mmc_select_powerclass(struct mmc_card *card)
{
    struct mmc_host *host = card->host;
    u32 bus_width, ext_csd_bits;
    int err, ddr;

    /* Power class selection is supported for versions >= 4.0 */
    if (!mmc_can_ext_csd(card))
        return 0;

    bus_width = host->ios.bus_width;
    /* Power class values are defined only for 4/8 bit bus */
    if (bus_width == MMC_BUS_WIDTH_1)
        return 0;

    ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52;
    // 这里开始会根据检测到eMMC卡的属性来选择DDR或者SDR以及位宽模式。
    if (ddr)
        ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
            EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;
    else
        ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
            EXT_CSD_BUS_WIDTH_8 :  EXT_CSD_BUS_WIDTH_4;

    err = __mmc_select_powerclass(card, ext_csd_bits);
    if (err)
        pr_warn("%s: power class selection to bus width %d ddr %d failed\n",
            mmc_hostname(host), 1 << bus_width, ddr);

    return err;
}

你可能感兴趣的:(eMMC总线:入门和驱动调试)