[U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver

Andreas Färber afaerber at suse.de
Sun Feb 12 14:20:30 UTC 2017


Am 01.12.2016 um 02:06 schrieb Marek Vasut:
> diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
> new file mode 100644
> index 0000000..95b3367
> --- /dev/null
> +++ b/drivers/mmc/jz_mmc.c
[...]
> +static void jz_mmc_set_ios(struct mmc *mmc)

This needs to return int by now.

> +{
> +	struct jz_mmc_priv *priv = mmc->priv;
> +	u32 real_rate = jz_mmc_clock_rate();
> +	u8 clk_div = 0;
> +
> +	/* calculate clock divide */
> +	while ((real_rate > mmc->clock) && (clk_div < 7)) {
> +		real_rate >>= 1;
> +		clk_div++;
> +	}
> +	writel(clk_div & MSC_CLKRT_CLK_RATE_MASK, priv->regs + MSC_CLKRT);
> +
> +	/* set the bus width for the next command */
> +	priv->flags &= ~JZ_MMC_BUS_WIDTH_MASK;
> +	if (mmc->bus_width == 8)
> +		priv->flags |= JZ_MMC_BUS_WIDTH_8;
> +	else if (mmc->bus_width == 4)
> +		priv->flags |= JZ_MMC_BUS_WIDTH_4;
> +	else
> +		priv->flags |= JZ_MMC_BUS_WIDTH_1;

return 0;

> +}
[...]
> +#ifdef CONFIG_MMC_TINY

Shouldn't this rather use something like #if defined(CONFIG_SPL_BUILD)
&& defined(CONFIG_SPL_MMC_TINY) so that we can drop the #define from ci20.h?

> +static struct jz_mmc_priv jz_mmc_priv_static = {
> +	.cfg = {
> +		.name = "MSC",
> +		.ops = &jz_msc_ops,
> +
> +		.voltages = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
> +				MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
> +				MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36,
> +		.host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
> +
> +		.f_min = 375000,
> +		.f_max = 48000000,
> +		.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
> +	},
> +};
> +
> +int jz_mmc_init(void __iomem *base)
> +{
> +	struct mmc *mmc;
> +
> +	jz_mmc_priv_static.regs = base;
> +
> +	mmc = mmc_create(&jz_mmc_priv_static.cfg, &jz_mmc_priv_static);
> +
> +	return mmc ? 0 : -ENODEV;
> +}
> +#endif
> +
> +#ifdef CONFIG_DM_MMC

Similarly here !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DM_MMC)?

> +#include <dm.h>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static int jz_mmc_ofdata_to_platdata(struct udevice *dev)
> +{
> +	struct jz_mmc_priv *priv = dev_get_priv(dev);
> +	const void *fdt = gd->fdt_blob;
> +	int node = dev->of_offset;
> +	struct mmc_config *cfg;
> +	int val;
> +
> +	priv->regs = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
> +	cfg = &priv->cfg;
> +
> +	cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
> +	val = fdtdec_get_int(fdt, node, "bus-width", 1);
> +	if (val < 0) {
> +		printf("error: bus-width property missing\n");
> +		return -ENOENT;
> +	}
> +
> +	switch (val) {
> +	case 0x8:
> +		cfg->host_caps |= MMC_MODE_8BIT;
> +	case 0x4:
> +		cfg->host_caps |= MMC_MODE_4BIT;
> +	case 0x1:
> +		break;
> +	default:
> +		printf("error: invalid bus-width property\n");
> +		return -ENOENT;
> +	}
> +
> +	cfg->f_min = 400000;
> +	cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000);
> +	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
> +	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
> +
> +	return 0;
> +}
> +
> +static int jz_mmc_probe(struct udevice *dev)
> +{
> +	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
> +	struct jz_mmc_priv *priv = dev_get_priv(dev);
> +	struct mmc_config *cfg = &priv->cfg;
> +	struct mmc *mmc;
> +
> +	cfg->name = "MSC";
> +	cfg->ops = &jz_msc_ops;
> +
> +	mmc = mmc_create(cfg, priv);
> +	if (!mmc)
> +		return -ENODEV;
> +
> +	mmc->dev = dev;
> +	upriv->mmc = mmc;
> +
> +	return 0;
> +}
> +static const struct udevice_id jz_mmc_ids[] = {
> +	{ .compatible = "ingenic,jz4780-mmc" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(jz_mmc_drv) = {
> +	.name			= "jz_mmc",
> +	.id			= UCLASS_MMC,
> +	.of_match		= jz_mmc_ids,
> +	.ofdata_to_platdata	= jz_mmc_ofdata_to_platdata,
> +	.probe			= jz_mmc_probe,
> +	.priv_auto_alloc_size	= sizeof(struct jz_mmc_priv),
> +};
> +#endif

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)


More information about the U-Boot mailing list