eMMC
总线概述信号线 | 作用 |
---|---|
CLK |
CLK 信号用于从 Host 端输出时钟信号,进行数据和命令传输的同步。在一个时钟周期内,CMD 和 DAT0-7 信号上都可以支持传输 1 个比特,即 SDR 模式。此外,DAT0-7 信号还支持配置为 DDR 模式,在一个时钟周期内,传输 2 个比特。 |
CMD |
CMD 信号主要用于 Host 向 Device 发送 Command 和 Device 向 Host 发送对于的 Response 。 |
DAT0-7 |
DAT0-7 信号主要用于 Host 和 eMMC 之间的数据传输,数据总线可以工作在 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;
}