瑞芯微平台uboot mmc 驱动

1. MMC 设备简介

MMC 为 MultiMedia Card,多媒体存储卡,但后续泛指一个接口协定(一种卡式),能符合这接口的内存器都可称作 mmc 储存体。可以分为三类:
mmc type card :1.标准 mmc 卡:闪存卡的一种,使用 mmc 标准;2. emmc:Embedded
MultiMediaCard,是 MMC 协会所制定的内嵌式存储器标准规格,带有 mmc 接口,是具备 mmc 协议的芯片。sd type card:SD 卡为 Secure Digital Memory Card, 即安全数码卡。它在 MMC 的基础上发展而来,增加了两个主要特色:SD 卡强调数据的安全安全,可以设定所储存的使用权限,防止数据被他人复制。兼容 mmc 接口规范。
sdio type card:SDIO 是在 SD 标准上定义了一种外设接口,它和 SD 卡规范间的一个重要区别是增加了低速标准。在 SDIO 卡只需要 SPI 和 1 位 SD 传输模式。低速卡的目标应用是以最小的硬件开销支持低速 IO 能力。常见的 sdio 设备有 Wi-Fi card、Bluetooth card 等等。
目前 MMC 设备的可运行的电压有三种:3V、1.8V、1.2V。工作时钟频率范围为 0~200 MHz。
本文主要介绍 U-Boot 下的 MMC 设备驱动。

2. DTS 配置说明

U-Boot 下的 MMC 设备驱动支持设备树,驱动的硬件配置需要在对应的 dtsi & dts 内配置。

dtsi 的配置及说明:

emmc: dwmmc@ff390000 {
compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xff390000 0x0 0x4000>; //控制器寄存器base
address及长度
max-frequency = <150000000>; //eMMC普通模式时钟为
50MHz,当配置为eMMC
HS200模式,该max-
frequency生效
clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
<&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; //控制器对应时钟编号
clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; //控制器时钟名
fifo-depth = <0x100>; //fifo深度,默认配置
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; //中断配置
status = "disabled";
};

板级 dts 配置及说明:

&emmc {
u-boot,dm-pre-reloc; //表示这个设备在relocate之前就需要使用
bus-width = <8>; //设备总线位宽
cap-mmc-highspeed; //标识此卡槽支持highspeed mmc
mmc-hs200-1_8v; //支持HS200
supports-emmc; //标识此插槽为eMMC功能,必须添加,否则无法
初始化外设。
disable-wp; //对于无物理WP管脚,需要配置
non-removable; //此项表示该插槽为不可移动设备。 此项为必须
添加项。
num-slots = <1>; //标识为第几插槽
pinctrl-names = "default";
pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
status = "okay";
};

3. MMC 初始化

MMC 初始化主要分为两个部分:1,MMC 控制器初始化;2,MMC 设备初始化。

3.1 MMC 控制器初始化

mmc_initialize(gd->bd),为硬件驱动 probe 过程,函数位于 uboot/drivers/mmc/mmc.c 。代码如下

int mmc_initialize(bd_t *bis)
{
static int initialized = 0;
int ret;
if (initialized) /* Avoid initializing mmc multiple times */
return 0;
initialized = 1;
#if !CONFIG_IS_ENABLED(BLK)
#if !CONFIG_IS_ENABLED(MMC_TINY)
mmc_list_init();
#endif
#endif
ret = mmc_probe(bis);
if (ret)
return ret;
#ifndef CONFIG_SPL_BUILD
print_mmc_devices(',');
#endif
mmc_do_preinit();
return 0;
}

mmc_probe(bis)主要做了:

MMC 控制器的初始化及获取 MMC 设备配置
时钟初始化
GPIO 初始化

MMC 控制器公用代码位于 uboot/drivers/mmc/dw_mmc.c ,平台代码位于
uboot/drivers/mmc/rockchip_dw_mmc.c 。

时钟框架代码位于 uboot/drivers/clk/rockchip/clk_xxx.c ,每个平台有自己的时钟框架,对应不
同文件。

目前 Rockchip 平台只做了 MMC 控制器的初始化及时钟初始化,GPIO 使用 pre-loader 的配置。

defconfig 内会有 CONFIG_OF_SPL_REMOVE_PROPS 的配置,为移除 DTS 内的某些配置。当驱动 probe时,移除的配置就不会初始化。示例如下:

CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-
clocks assigned-clock-rates assigned-clock-parents"

mmc_do_preinit()主要做了 static struct mmc mmc_static 初始化,注册 MMC 设备。

3.2 MMC 设备初始化

MMC 控制器初始化,调用 mmc_init 对 MMC 卡做初始化,运行到相应的模式。函数位于
uboot/drivers/mmc/mmc.c

int mmc_init(struct mmc *mmc)
{
int err = 0;
__maybe_unused unsigned start;
#if CONFIG_IS_ENABLED(DM_MMC)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
upriv->mmc = mmc;
#endif
if (mmc->has_init)
return 0;
start = get_timer(0);
if (!mmc->init_in_progress)
err = mmc_start_init(mmc);
if (!err)
err = mmc_complete_init(mmc);
if (err)
printf("%s: %d, time %lu\n", __func__, err, get_timer(start));
return err;
}

mmc_start_init:MMC 有多种类型,该函数为查询是哪个类型的 MMC 设备。
mmc_complete_init:初始化设备,获取设备信息。

4. MMC 设备读写调用

mmc 挂载在 block 下,框架如下:

U-Boot 下读写擦除调用:

struct blk_desc *dev_desc;
dev_desc = rockchip_get_bootdev();
unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,lbaint_t
blkcnt, const void *buffer);
unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,lbaint_t
blkcnt, void *buffer);
unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,lbaint_t
blkcnt);

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶知秋yyds

分享是一种美德,感谢金主打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值