基于RK3399的Linux驱动开发 -- EMMC驱动框架

一、概述

本文章主要通过源代码分析EMMC的驱动框架,解释如何注册一个host驱动、并通过card层的块设备驱动接口和core层相关接口访问host驱动接口,进而访问emmc器件。

二、host层

1、dw_mci框架

dw_mci_drv_data

这个是dw_mci框架的私有数据,主要包含一些回调接口,通过接口访问具体芯片mmc控制器的一些参数。

struct dw_mci_drv_data {
   
	unsigned long	*caps;
	int		(*init)(struct dw_mci *host);
	int		(*setup_clock)(struct dw_mci *host);
	void		(*prepare_command)(struct dw_mci *host, u32 *cmdr);
	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
	int		(*parse_dt)(struct dw_mci *host);
	int		(*execute_tuning)(struct dw_mci_slot *slot, u32 opcode);
	int		(*prepare_hs400_tuning)(struct dw_mci *host,
						struct mmc_ios *ios);
	int		(*switch_voltage)(struct mmc_host *mmc,
					  struct mmc_ios *ios);
};

dw_mci_dma_ops

struct dw_mci_dma_ops {
   
	int (*init)(struct dw_mci *host);
	int (*start)(struct dw_mci *host, unsigned int sg_len);
	void (*complete)(void *host);
	void (*stop)(struct dw_mci *host);
	void (*cleanup)(struct dw_mci *host);
	void (*exit)(struct dw_mci *host);
};

dw_mci

struct dw_mci {
   
	int			use_dma;
	const struct dw_mci_dma_ops	*dma_ops;
	struct device		*dev;
	const struct dw_mci_drv_data	*drv_data;
	struct dw_mci_slot	*slot[MAX_MCI_SLOTS];
};

dw_mci_pltfm_register

该接口由具体mmc控制器驱动调用,注册为一个dw_mci兼容框架的驱动,这一类驱动访问的寄存器,时钟参数都一样的,彼此兼容。

int dw_mci_pltfm_register(struct platform_device *pdev,
			  const struct dw_mci_drv_data *drv_data)
{
   
	struct dw_mci *host;

	host = devm_kzalloc(&pdev->dev, sizeof(struct dw_mci), GFP_KERNEL);
	/* 填充host实例 */
	return dw_mci_probe(host);
}

dw_mci_probe

int dw_mci_probe(struct dw_mci *host)
{
   
	if (!host->pdata) {
   
		/* 从具体平台dts解析出mmc接口的节点参数 */
		host->pdata = dw_mci_parse_dt(host); 
	}
	
	/* 获取时钟 */
	host->biu_clk = devm_clk_get(host->dev, "biu");
	host->ciu_clk = devm_clk_get(host->dev, "ciu");
	
	/* 调用具体mmc控制器的驱动回调 */
	if (drv_data && drv_data->init) {
   
	}
	if (drv_data && drv_data->setup_clock) {
   
	}

	host->dma_ops = host->pdata->dma_ops;
	dw_mci_init_dma(host);
	
	for (i = 0; i < host->num_slots; i++) {
   
		/* 一个mmc控制器就是一个slot,例如rk3399有两个mmc控制器,一个是sdio0,一个是sdmmc */
		ret = dw_mci_init_slot(host, i);
	}
}

dw_mci_init_slot

/* 这个就是mmc控制器的回调接口 */
static const struct mmc_host_ops dw_mci_ops = {
   
	.request		= dw_mci_request,
	.pre_req		= dw_mci_pre_req,
	.post_req		= dw_mci_post_req,
	.set_ios		= dw_mci_set_ios,
	.set_sdio_status	= dw_mci_set_sdio_status,
	.get_ro			= dw_mci_get_ro,
	.get_cd			= dw_mci_get_cd,
	.enable_sdio_irq	= dw_mci_enable_sdio_irq,
	.execute_tuning		= dw_mci_execute_tuning,
	.card_busy		= dw_mci_card_busy,
	.start_signal_voltage_switch = dw_mci_switch_voltage,
	.init_card		= dw_mci_init_card,
	.prepare_hs400_tuning	= dw_mci_prepare_hs400_tuning,
};

static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
{
   
	struct mmc_host *mmc;
	
	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev); 
	/* 绑定回调,以便core层调用,例如request、card_busy等 */
	mmc->ops = &dw_mci_ops;
	ret = mmc_add_host(mmc);
}

dw_mci_init_dma

static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
   
	.init = dw_mci_idmac_init,
	.start = dw_mci_idmac_start_dma,
	.stop = dw_mci_idmac_stop_dma,
	.complete = dw_mci_dmac_complete_dma,
	.cleanup = dw_mci_dma_cleanup,
};

static const struct dw_mci_dma_ops dw_mci_edmac_ops = {
   
	.init = dw_mci_edmac_init,
	.exit = dw_mci_edmac_exit,
	.start = dw_mci_edmac_start_dma,
	.stop = dw_mci_edmac_stop_dma,
	.complete = dw_mci_dmac_complete_dma,
	.cleanup = dw_mci_dma_cleanup,
};

static void dw_mci_init_dma(struct dw_mci *host)
{
   
	if (host->use_dma == TRANS_MODE_IDMAC) {
   
		host->dma_ops = &dw_mci_idmac_ops;
	} else {
   
		host->dma_ops = &dw_mci_edmac_ops;
	}
}

2、dw_mci-rockchip驱动

dw_mci_rockchip_probe

/* 这里实现了dm_mci框架的回调接口 */
static const struct dw_mci_drv_data rk3288_drv_data = {
   
	.caps			= dw_mci_rk3288_dwmmc_caps,
	.prepare_command        = dw_mci_rockchip_prepare_command,
	.set_ios		= dw_mci_rk3288_set_ios,
	.execute_tuning		= dw_mci_rk3288_execute_tuning,
	.parse_dt		= dw_mci_rk3288_
  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
砖头是指移动设备在刷机或者系统升级过程中出现问题导致无法开机或运行不正常所面对的情况。而cm201-2则是一种处理砖头问题的方法之一。那么砖头烧录emmc即指通过cm201-2方法来重写移动设备的emmc存储器,以修复砖头问题。 在砖头烧录emmc的过程中,首先需要准备好相应的工具和设备。一般需要一台电脑、连接设备的数据线、cm201-2工具和对应的固件文件等。然后按照以下步骤进行操作: 1. 首先,将移动设备连接到电脑上,确保设备与电脑正常通信。可以使用数据线将设备与电脑连接。 2. 然后,打开cm201-2工具,并选择正确的设备型号和固件版本。确保选择的固件文件与设备相匹配。 3. 接下来,选择烧录模式。一般有线刷模式和升级模式两种选择。根据设备情况选择合适的烧录模式。 4. 确认选择后,点击开始烧录按钮。此时,烧录工具会开始进行烧录操作,并显示烧录进度。 5. 等待烧录完成后,烧录工具会提示烧录成功,并对设备进行自动重启。此时,移动设备的emmc存储器已经被成功重写。 通过以上步骤,我们成功使用cm201-2砖头烧录emmc修复了移动设备的砖头问题。需要注意的是,在操作过程中要谨慎选择固件版本,确保设备与固件相匹配,以免造成进一步的问题。此外,操作过程中要保持设备与电脑的稳定连接,避免出现断开等问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值