RK3588 uboot下的emmc驱动

您所在的位置:网站首页 EMMC读取不了保留屏参 RK3588 uboot下的emmc驱动

RK3588 uboot下的emmc驱动

2024-07-08 00:08| 来源: 网络整理| 查看: 265

############## RK3588 uboot下的emmc驱动 1.简介

    MMC 为 MultiMedia Card,多媒体存储卡,但后续泛指一个接口协定(一种卡式),能符合这接口的内 存器都可称作 mmc 储存体。可以分为三类:

    1.1 mmc type card :1.标准 mmc 卡:闪存卡的一种,使用 mmc 标准;2. emmc:Embedded MultiMediaCard,是 MMC 协会所制定的内嵌式存储器标准规格,带有 mmc 接口,是具备 mmc 协议的芯片。

    1.2 sd type card:SD 卡为 Secure Digital Memory Card, 即安全数码卡。它在 MMC 的基础上发展而来, 增加了两个主要特色:SD 卡强调数据的安全安全,可以设定所储存的使用权限,防止数据被他人复制。兼容 mmc 接口规范。

    1.3 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。

2.DTS配置说明

    2.1 dtsi配置

    sdhci: mmc@fe2e0000 {         compatible = "rockchip,rk3588-dwcmshc", "rockchip,dwcmshc-sdhci";         reg = ;        //控制寄存器base         interrupts = ;    //中断配置         assigned-clocks = , ;         assigned-clock-rates = , ;         clocks = , ,              , ,              ;        //控制器对应时钟编号         clock-names = "core", "bus", "axi", "block", "timer";    //控制器时钟名         max-frequency = ;        //当配置emmc为HS200模式时,最大时钟频率生效         status = "disabled";     };

         2.2  板级配置

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

    MMC初始化主要分为2个部分,控制器、设备初始化

3.1 MMC控制器初始化          uboot/arch/arm/mach-rockchip/board.c调用了函数mmc_initialize(gd->bd)     相关代码位于uboot/drivers/mmc/mmc.c     int mmc_initialize(bd_t *bis)

    拓展:__weak声明: 弱函数声明,如果定义了同名函数则舍弃弱函数,如果未定义则使用弱函数

    mmc_initialize()中调用了mmc_probe(),mmc_probe()主要做了以下几件事         1) MMC 控制器的初始化及获取 MMC 设备配置         2) 时钟初始化         3) GPIO 初始化     公用代码位于 uboot/drivers/mmc/dw_mmc.c ,     平台代码位于uboot/drivers/mmc/rockchip_dw_mmc.c (rockchip_sdhci.c)。     时钟框架代码位于 uboot/drivers/clk/rockchip/clk_xxx.c      每个平台有自己的时钟框架,对应不同文件。     mmc_do_preinit()用于初始化struct mmc mmc_static结构体,注册mmc设备

3.2  详解mmc_probe函数

    static int mmc_probe(bd_t *bis)     {         int ret, i;         struct uclass *uc;             struct udevice *dev;         /*从指定的宏定义中获取uclass信息*/         ret = uclass_get(UCLASS_MMC, &uc);         if (ret)             return ret;         /*按顺序获取设备信息*/         for (i = 0; ; i++) {         ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);         if (ret == -ENODEV)             break;         }         uclass_foreach_dev(dev, uc) {         /*逐一probe设备*/         ret = device_probe(dev);         if (ret)             printf("%s - probe failed: %d\n", dev->name, ret);         }         return 0;     }

    struct uclass     uboot下的驱动类型,包含了私有数据、驱动接口、设备列表头节点等成员     struct udevice    设备(硬件)信息,即设备树节点,类似于kernel中的device_node

3.3  移除DTS中的某些配置项           rk3588_defconfig中的配置项     CONFIG_OF_SPL_REMOVE_PROPS 和 CONFIG_OF_U_BOOT_REMOVE_PROPS     CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"     CONFIG_OF_U_BOOT_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"     配置项中的内容不会被初始化

     4 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:初始化设备,获取设备信息。

5  读写函数API     struct blk_desc *dev_desc;     dev_desc = rockchip_get_bootdev();     unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,lbaint_tblkcnt, const void *buffer);     unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,lbaint_tblkcnt, void *buffer);     unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,lbaint_tblkcnt); 6  常见问题

    1. U-Boot 下如何配置使用 MMC 设备     请先按照 DTS 配置说明进行配置         MMC HS200 模式,注意 CONFIG_OF_SPL_REMOVE_PROPS 的配置,需要 remove clock-names。         高速模式、SDR52,DDR52 无需 remove clock-names。     2. 初始化 MMC 设备失败         先查看 MMC device 端的电压是否正常,控制器的 logic 电压是否在 1.0V 以上         查看寄存器配置是否正确         查看时钟配置是否正确,可以在 clock 模块内打印出相应的时钟配置     3. 初始化成功,但读取固件失败         先查看 MMC device 端的电压是否正常,控制器的 logic 电压是否在 1.0 以上。         查看时钟配置是否正确,可以在 clock 模块内打印出相应的时钟配置         MMC HS200 模式,查看 max-frequency 是否过高。硬件是否虚焊     4. 当 U-Boot 作为 pre-loader 或 usbplug 使用时,emmc 初始化失败,命令停留在 CMD8         Rockchip 平台 SDRAM 的前 1MB 位置为安全区域,加载起来的 pre-loader 或 usbplug 在此区域运         行,而 emmc 为非安全的 IP,是无法访问该区域,需要配置允许 emmc 读数据到该区域,才能初始化成功

参考瑞芯微开发文档:《Rockchip_Developer_Guide_U-Boot MMC Device Driver Analysis 》



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3