diff options
| author | Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | 2018-12-27 19:04:04 +0530 | 
|---|---|---|
| committer | Tom Rini <trini@konsulko.com> | 2019-01-15 15:28:10 -0500 | 
| commit | 6240e64f92085f6e8950d938a0103281ad4f5ab2 (patch) | |
| tree | ab82ae097c51bfe023199a4c0c224c6302f18869 /drivers | |
| parent | 5bb409c1ba4aea00b5dbd834f0e217a759c1041c (diff) | |
mmc: Convert HI6220 MMC driver to driver model
Convert HiSilicon HI6220 MMC driver based on DWMMC IP to driver
model.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
[trini: Enable this on poplar]
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/mmc/hi6220_dw_mmc.c | 100 | 
1 files changed, 69 insertions, 31 deletions
| diff --git a/drivers/mmc/hi6220_dw_mmc.c b/drivers/mmc/hi6220_dw_mmc.c index ce395d53c94..cc58aff38cc 100644 --- a/drivers/mmc/hi6220_dw_mmc.c +++ b/drivers/mmc/hi6220_dw_mmc.c @@ -5,51 +5,89 @@   */  #include <common.h> +#include <dm.h>  #include <dwmmc.h> +#include <errno.h> +#include <fdtdec.h>  #include <malloc.h> -#include <linux/errno.h> -#define	DWMMC_MAX_CH_NUM		4 +DECLARE_GLOBAL_DATA_PTR; -#define	DWMMC_MAX_FREQ			50000000 -#define	DWMMC_MIN_FREQ			400000 +struct hi6220_dwmmc_plat { +	struct mmc_config cfg; +	struct mmc mmc; +}; -/* Source clock is configured to 100MHz by ATF bl1*/ -#define MMC0_DEFAULT_FREQ		100000000 +struct hi6220_dwmmc_priv_data { +	struct dwmci_host host; +}; -static int hi6220_dwmci_core_init(struct dwmci_host *host, int index) +static int hi6220_dwmmc_ofdata_to_platdata(struct udevice *dev)  { -	host->name = "Hisilicon DWMMC"; +	struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev); +	struct dwmci_host *host = &priv->host; -	host->dev_index = index; +	host->name = dev->name; +	host->ioaddr = (void *)devfdt_get_addr(dev); +	host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), +					"bus-width", 4); + +	/* use non-removable property for differentiating SD card and eMMC */ +	if (dev_read_bool(dev, "non-removable")) +		host->dev_index = 0; +	else +		host->dev_index = 1; + +	host->priv = priv; -	/* Add the mmc channel to be registered with mmc core */ -	if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) { -		printf("DWMMC%d registration failed\n", index); -		return -1; -	}  	return 0;  } -/* - * This function adds the mmc channel to be registered with mmc core. - * index -	mmc channel number. - * regbase -	register base address of mmc channel specified in 'index'. - * bus_width -	operating bus width of mmc channel specified in 'index'. - */ -int hi6220_dwmci_add_port(int index, u32 regbase, int bus_width) +static int hi6220_dwmmc_probe(struct udevice *dev)  { -	struct dwmci_host *host = NULL; +	struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev); +	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); +	struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev); +	struct dwmci_host *host = &priv->host; -	host = calloc(1, sizeof(struct dwmci_host)); -	if (!host) { -		pr_err("dwmci_host calloc failed!\n"); -		return -ENOMEM; -	} +	/* Use default bus speed due to absence of clk driver */ +	host->bus_hz = 50000000; -	host->ioaddr = (void *)(ulong)regbase; -	host->buswidth = bus_width; -	host->bus_hz = MMC0_DEFAULT_FREQ; +	dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000); +	host->mmc = &plat->mmc; -	return hi6220_dwmci_core_init(host, index); +	host->mmc->priv = &priv->host; +	upriv->mmc = host->mmc; +	host->mmc->dev = dev; + +	return dwmci_probe(dev);  } + +static int hi6220_dwmmc_bind(struct udevice *dev) +{ +	struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev); +	int ret; + +	ret = dwmci_bind(dev, &plat->mmc, &plat->cfg); +	if (ret) +		return ret; + +	return 0; +} + +static const struct udevice_id hi6220_dwmmc_ids[] = { +	{ .compatible = "hisilicon,hi6220-dw-mshc" }, +	{ } +}; + +U_BOOT_DRIVER(hi6220_dwmmc_drv) = { +	.name = "hi6220_dwmmc", +	.id = UCLASS_MMC, +	.of_match = hi6220_dwmmc_ids, +	.ofdata_to_platdata = hi6220_dwmmc_ofdata_to_platdata, +	.ops = &dm_dwmci_ops, +	.bind = hi6220_dwmmc_bind, +	.probe = hi6220_dwmmc_probe, +	.priv_auto_alloc_size = sizeof(struct hi6220_dwmmc_priv_data), +	.platdata_auto_alloc_size = sizeof(struct hi6220_dwmmc_plat), +}; | 
