S5P4418:eMMC 调试笔记

分类: 365bet客服 时间: 2025-10-07 09:56:01 作者: admin

目录1. 前言2. 背景3. eMMC参数调试3.1 eMMC数据位宽调整3.2 eMMC容量调整3.3 eMMC时钟/时序调整3.3.1 内核调整3.3.2 u-boot调整3.3.3 低版本内核不支持 eMMC 5.1 及以后版本调整4. 关于 eMMC 常见问题小结5. 后记

1. 前言

限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。

2. 背景

在 S5P4418 的 Android 5.1.1 下调试 eMMC 时的笔记。

3. eMMC参数调试

3.1 eMMC数据位宽调整

/* @lollipop_2nd_release/u-boot/include/configs/s5p6818_drone.h */

#define CONFIG_MMC0_CLOCK 50000000

#define CONFIG_MMC0_CLK_DELAY DW_MMC_DRIVE_DELAY(0) | DW_MMC_SAMPLE_DELAY(0) | DW_MMC_DRIVE_PHASE(2)| DW_MMC_SAMPLE_PHASE(1)

#define CONFIG_MMC2_CLOCK 50000000

#define CONFIG_MMC2_CLK_DELAY DW_MMC_DRIVE_DELAY(0) | DW_MMC_SAMPLE_DELAY(0) | DW_MMC_DRIVE_PHASE(3)| DW_MMC_SAMPLE_PHASE(2)

#define CONFIG_MMC2_BUS_WIDTH 8 /* 数据位宽调整为 8-bit */

#define CONFIG_MMC2_TRANS_MODE 0 //1 : DDR_MODE, 0: SDR_MODE

3.2 eMMC容量调整

/* @ lollipop-5.1.1_r6/device/nexell/s5p4418_drone/BoardConfig.mk */

# packaging for emmc, sd

TARGET_USERIMAGES_USE_EXT4 := true

BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4

BOARD_BOOTIMAGE_PARTITION_SIZE := 67108864

BOARD_SYSTEMIMAGE_PARTITION_SIZE := 790626304

BOARD_CACHEIMAGE_PARTITION_SIZE := 448790528

BOARD_USERDATAIMAGE_PARTITION_SIZE := 6000000000 /6000000000-8G /14000000000 -16G

BOARD_FLASH_BLOCK_SIZE := 4096

3.3 eMMC时钟/时序调整

3.3.1 内核调整

/* @lollipop-5.1.1_r6/kernel/arch/arm/plat-s5p4418/drone/device.c */

#ifdef CONFIG_MMC_NXP_CH0

static struct dw_mci_board _dwmci0_data = {

.quirks = DW_MCI_QUIRK_HIGHSPEED,

.bus_hz = 100 * 1000 * 1000,

.caps = MMC_CAP_CMD23,

.detect_delay_ms= 200,

.cd_type = DW_MCI_CD_EXTERNAL,

.clk_dly = DW_MMC_DRIVE_DELAY(0) | DW_MMC_SAMPLE_DELAY(0) | DW_MMC_DRIVE_PHASE(2) | DW_MMC_SAMPLE_PHASE(1),

.init = _dwmci0_init,

.get_ro = _dwmci_get_ro,

.get_cd = _dwmci0_get_cd,

.ext_cd_init = _dwmci_ext_cd_init,

.ext_cd_cleanup = _dwmci_ext_cd_cleanup,

#if defined (CONFIG_MMC_DW_IDMAC) && defined (CONFIG_MMC_NXP_CH0_USE_DMA)

.mode = DMA_MODE,

#else

.mode = PIO_MODE,

#endif

};

#endif

#ifdef CONFIG_MMC_NXP_CH1

static struct dw_mci_board _dwmci1_data = {

.quirks = DW_MCI_QUIRK_HIGHSPEED,

.bus_hz = 100 * 1000 * 1000,

.caps = MMC_CAP_CMD23|MMC_CAP_NONREMOVABLE,

.detect_delay_ms= 200,

.cd_type = DW_MCI_CD_NONE,

.pm_caps = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY,

.clk_dly = DW_MMC_DRIVE_DELAY(0) | DW_MMC_SAMPLE_DELAY(0) | DW_MMC_DRIVE_PHASE(0) | DW_MMC_SAMPLE_PHASE(0),

#if defined (CONFIG_MMC_DW_IDMAC) && defined (CONFIG_MMC_NXP_CH1_USE_DMA)

.mode = DMA_MODE,

#else

.mode = PIO_MODE,

#endif

};

#endif

#ifdef CONFIG_MMC_NXP_CH2

static struct dw_mci_board _dwmci2_data = {

.quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION |

DW_MCI_QUIRK_HIGHSPEED |

DW_MMC_QUIRK_HW_RESET_PW |

DW_MCI_QUIRK_NO_DETECT_EBIT,

.bus_hz = 100 * 1000 * 1000,

.caps = MMC_CAP_UHS_DDR50 |

MMC_CAP_NONREMOVABLE |

MMC_CAP_4_BIT_DATA | MMC_CAP_CMD23 |

MMC_CAP_HW_RESET,

.clk_dly = DW_MMC_DRIVE_DELAY(0) | DW_MMC_SAMPLE_DELAY(0) | DW_MMC_DRIVE_PHASE(3) | DW_MMC_SAMPLE_PHASE(2),

.desc_sz = 4,

.detect_delay_ms= 200,

.sdr_timing = 0x01010001,

.ddr_timing = 0x03030002,

#if defined (CONFIG_MMC_DW_IDMAC) && defined (CONFIG_MMC_NXP_CH2_USE_DMA)

.mode = DMA_MODE,

#else

.mode = PIO_MODE,

#endif

};

#endif

#endif /* CONFIG_MMC_DW */

3.3.2 u-boot调整

/* @lollipop-5.1.1_r6/u-boot/include/configs/s5p4418_drone.h */

#if defined(CONFIG_CMD_MMC)

#define CONFIG_MMC

#define CONFIG_GENERIC_MMC

#define HAVE_BLOCK_DEVICE

#define CONFIG_MMC0_ATTACH TRUE /* 0 = MMC0 : External */

#define CONFIG_MMC1_ATTACH FALSE /* 1 = MMC1 : */

#define CONFIG_MMC2_ATTACH TRUE /* 2 = MMC2 : BOOT(eMMC) */

#define CONFIG_MMC0_CLOCK 25000000

#define CONFIG_MMC0_CLK_DELAY DW_MMC_DRIVE_DELAY(0) | DW_MMC_SAMPLE_DELAY(0) | DW_MMC_DRIVE_PHASE(2)| DW_MMC_SAMPLE_PHASE(1)

#define CONFIG_MMC2_CLOCK 50000000

#define CONFIG_MMC2_CLK_DELAY DW_MMC_DRIVE_DELAY(0) | DW_MMC_SAMPLE_DELAY(0) | DW_MMC_DRIVE_PHASE(3)| DW_MMC_SAMPLE_PHASE(2)

#define CONFIG_MMC2_BUS_WIDTH 4

3.3.3 低版本内核不支持 eMMC 5.1 及以后版本调整

/* @kernel/drivers/mmc/core/mmc.c */

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

struct mmc_card *oldcard)

{

...

//if (card->ext_csd.rev > 7) {

if (card->ext_csd.rev > 8) { /* 支持 eMMC 5.1 */

...

}

4. 关于 eMMC 常见问题小结

本小节总结调试 eMMC 时遇到的常见问题,将持续更新。

1. 有时候 eMMC 无法初始化成功,内核会打印对不同频率进行设置的日志。这时候可能需要检查 eMMC 各 PIN

脚信号。供电不正常经常导致这类问题,如本应使用 1.8V 供电,却使用了 3.3V 供电,等等情形。

5. 后记

本文以及相关篇章基于刚接触Linux嵌入式系统开发的小白阶段,或存在错漏。从开始学习编译内核,修改内核配置,移植一个驱动,然后学习自己写驱动,各种工具使用,Git代码管理,...... 嗯,一段值得怀念的岁月啊_。