[U-Boot] [PATCH v2 1/3] mmc: uniphier: add driver for UniPhier SD/MMC host controller

Marek Vasut marex at denx.de
Wed Feb 10 14:45:48 CET 2016


On 02/10/2016 02:28 PM, Masahiro Yamada wrote:
> Add a driver for the on-chip SD/eMMC host controller used by
> UniPhier SoC family.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>

前略 山田さん,

[...]

> +#include <common.h>
> +#include <clk.h>
> +#include <fdtdec.h>
> +#include <mapmem.h>
> +#include <mmc.h>
> +#include <dm/device.h>
> +#include <linux/compat.h>
> +#include <linux/io.h>
> +#include <asm/unaligned.h>
> +#include <asm/dma-mapping.h>
> +
> +#define pr_err   printf
> +#define pr_warn  printf
> +#ifdef DEBUG
> +#define pr_debug printf
> +#else
> +#define pr_debug(...)
> +#endif

This should go into include/ somewhere, your driver shouldn't be a
platform abstraction library.

> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define UNIPHIER_SD_CMD			0x000	/* command */

[...]

> +static int uniphier_sd_wait_irq(struct uniphier_sd_priv *priv,
> +				unsigned int reg, u32 flag)
> +{
> +	long wait = 1000000;
> +	int ret;

Replace this with wait_for_bit() please .

> +	while (!(readl(priv->regbase + reg) & flag)) {
> +		if (wait-- < 0) {
> +			pr_err("timeout\n");
> +			return -ETIMEDOUT;
> +		}
> +
> +		ret = uniphier_sd_check_error(priv);
> +		if (ret)
> +			return ret;
> +
> +		udelay(1);
> +	}
> +
> +	return 0;
> +}

[...]

> +static void uniphier_sd_dma_start(struct uniphier_sd_priv *priv,
> +				  dma_addr_t dma_addr)
> +{
> +	u32 tmp;
> +
> +	writel(0, priv->regbase + UNIPHIER_SD_DMA_INFO1);
> +	writel(0, priv->regbase + UNIPHIER_SD_DMA_INFO2);
> +
> +	/* enable DMA */
> +	tmp = readl(priv->regbase + UNIPHIER_SD_EXTMODE);
> +	tmp |= UNIPHIER_SD_EXTMODE_DMA_EN;
> +	writel(tmp, priv->regbase + UNIPHIER_SD_EXTMODE);

I'd say, use setbits_le32(), but could it be that this driver is kept in
sync with Linux ?

> +	writel(dma_addr & U32_MAX, priv->regbase + UNIPHIER_SD_DMA_ADDR_L);
> +
> +	/* suppress the warning "right shift count >= width of type" */
> +	dma_addr >>= min_t(int, 32, 8 * sizeof(dma_addr));
> +
> +	writel(dma_addr & U32_MAX, priv->regbase + UNIPHIER_SD_DMA_ADDR_H);
> +
> +	writel(UNIPHIER_SD_DMA_CTL_START, priv->regbase + UNIPHIER_SD_DMA_CTL);
> +}
> +
> +static int uniphier_sd_dma_wait_irq(struct uniphier_sd_priv *priv, u32 flag,
> +				    unsigned int blocks)
> +{
> +	long wait = 1000000 + 10 * blocks;

wait_for_bit() again.

> +	while (!(readl(priv->regbase + UNIPHIER_SD_DMA_INFO1) & flag)) {
> +		if (wait-- < 0) {
> +			pr_err("timeout during DMA\n");
> +			return -ETIMEDOUT;
> +		}
> +
> +		udelay(10);
> +	}
> +
> +	if (readl(priv->regbase + UNIPHIER_SD_DMA_INFO2)) {
> +		pr_err("error during DMA\n");
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}

草々



More information about the U-Boot mailing list