[U-Boot] [PATCH v4 27/33] rockchip: Add an MMC driver

Simon Glass
2015-08-30T22:45:17Z

Hi Jaehoon,

On 24 August 2015 at 20:31, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi, Simon.
>
>
> On 08/25/2015 12:12 AM, Simon Glass wrote:
>> Add an MMC driver which supports RK3288, but may also support other SoCs.
>> It uses the Designware MMC device.
>
> It's based on designware controller. then how about using "_dw_mmc" as postfix?

OK done

>
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v4: None
>> Changes in v3: None
>> Changes in v2: None
>>
>> drivers/mmc/Kconfig | 9 +++++
>> drivers/mmc/Makefile | 1 +
>> drivers/mmc/rockchip_mmc.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 108 insertions(+)
>> create mode 100644 drivers/mmc/rockchip_mmc.c
>>
>> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
>> index 3e835f7..cd5f53c 100644
>> --- a/drivers/mmc/Kconfig
>> +++ b/drivers/mmc/Kconfig
>> @@ -10,6 +10,15 @@ config DM_MMC
>> appear as block devices in U-Boot and can support filesystems such
>> as EXT4 and FAT.
>>
>> +config ROCKCHIP_MMC
>> + bool "Rockchip SD/MMC controller support"
>> + depends on DM && OF_CONTROL
>> + help
>> + This enables support for the Rockchip SD/MMM controller, which is
>> + based on Designware IP. The device is compatible with SD 3.0,
>> + SDIO 3.0 and MMC 4.5 and supports common eMMC chips as well as
>> + removeable SD and micro-SD cards.
>
> I think it's not good that described spec version.
> In future, Rockchip can support upper version than SD3.0, SDIO3.0 and MMC4.5.

Do you mean that Rockchip can support MMC 5, for example? I tweaked
the help a little based on your comments.

>
>> +
>> config SH_SDHI
>> bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
>> depends on RMOBILE
>> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
>> index cae207c..7fd63de 100644
>> --- a/drivers/mmc/Makefile
>> +++ b/drivers/mmc/Makefile
>> @@ -29,6 +29,7 @@ obj-$(CONFIG_MXS_MMC) += mxsmmc.o
>> obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
>> obj-$(CONFIG_X86) += pci_mmc.o
>> obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
>> +obj-$(CONFIG_ROCKCHIP_MMC) += rockchip_mmc.o
>> obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
>> obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
>> obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
>> diff --git a/drivers/mmc/rockchip_mmc.c b/drivers/mmc/rockchip_mmc.c
>> new file mode 100644
>> index 0000000..430e7e5
>> --- /dev/null
>> +++ b/drivers/mmc/rockchip_mmc.c
>> @@ -0,0 +1,98 @@
>> +/*
>> + * Copyright (c) 2013 Google, Inc
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <dwmmc.h>
>> +#include <errno.h>
>> +#include <syscon.h>
>> +#include <asm/arch/clock.h>
>> +#include <asm/arch/periph.h>
>> +#include <linux/err.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +struct rockchip_mmc_priv {
>> + struct udevice *clk;
>> + struct rk3288_grf *grf;
>> + struct dwmci_host host;
>> +};
>> +
>> +static uint rockchip_mmc_get_mmc_clk(struct dwmci_host *host, uint freq)
>
> Well, how about using "dwmci" instead of "mmc". it's just my preference. :)
> (Since it has used function name as "dwmci" in other dwmmc file.)

OK done

>
>> +{
>> + struct udevice *dev = host->priv;
>> + struct rockchip_mmc_priv *priv = dev_get_priv(dev);
>> + int ret;
>> +
>> + ret = clk_set_periph_rate(priv->clk, PERIPH_ID_SDMMC0 + host->dev_index,
>> + freq);
>> + if (ret < 0) {
>> + debug("%s: err=%d\n", __func__, ret);
>> + return ret;
>> + }
>> +
>> + return freq;
>> +}
>> +
>> +static int rockchip_mmc_ofdata_to_platdata(struct udevice *dev)
>> +{
>> + struct rockchip_mmc_priv *priv = dev_get_priv(dev);
>> + struct dwmci_host *host = &priv->host;
>> +
>> + host->name = dev->name;
>> + host->ioaddr = (void *)dev_get_addr(dev);
>> + host->buswidth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
>> + "bus-width", 4);
>> + host->get_mmc_clk = rockchip_mmc_get_mmc_clk;
>> + host->priv = dev;
>> +
>> + /* TODO(sjg at chromium.org): Remove the need for this hack */
>> + host->dev_index = (ulong)host->ioaddr == 0xff0f0000 ? 0 : 1;
>> +
>> + return 0;
>> +}
>> +
>> +int rockchip_mmc_probe(struct udevice *dev)
>> +{
>> + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
>> + struct rockchip_mmc_priv *priv = dev_get_priv(dev);
>> + struct dwmci_host *host = &priv->host;
>> + u32 minmax[2];
>> + int ret;
>> +
>> + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
>> + if (IS_ERR(priv->grf))
>> + return PTR_ERR(priv->grf);
>> + ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk);
>> + if (ret)
>> + return ret;
>> +
>> + ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
>> + "clock-freq-min-max", minmax, 2);
>> + if (!ret)
>> + ret = add_dwmci(host, minmax[1], minmax[0]);
>> + if (ret)
>> + return ret;
>> +
>> + upriv->mmc = host->mmc;
>> +
>> + return 0;
>> +}
>> +
>> +static const struct udevice_id rockchip_mmc_ids[] = {
>> + { .compatible = "rockchip,rk3288-dw-mshc" },
>> + { }
>> +};
>> +
>> +U_BOOT_DRIVER(rockchip_mmc_drv) = {
>> + .name = "rockchip_mmc",
>> + .id = UCLASS_MMC,
>> + .of_match = rockchip_mmc_ids,
>> + .ofdata_to_platdata = rockchip_mmc_ofdata_to_platdata,
>> + .probe = rockchip_mmc_probe,
>> + .priv_auto_alloc_size = sizeof(struct dwmci_host),
>> +};
>>
>

Regards,
Simon