#include <clk.h>
#include <fdtdec.h>
#include <mmc.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/compat.h>
+#include <linux/dma-direction.h>
#include <linux/io.h>
#include <linux/sizes.h>
+#include <power/regulator.h>
#include <asm/unaligned.h>
-#include <asm/dma-mapping.h>
DECLARE_GLOBAL_DATA_PTR;
/* alignment required by the DMA engine of this controller */
#define UNIPHIER_SD_DMA_MINALIGN 0x10
-struct uniphier_sd_priv {
+struct uniphier_sd_plat {
struct mmc_config cfg;
- struct mmc *mmc;
+ struct mmc mmc;
+};
+
+struct uniphier_sd_priv {
void __iomem *regbase;
unsigned long mclk;
unsigned int version;
#define UNIPHIER_SD_CAP_NONREMOVABLE BIT(0) /* Nonremovable e.g. eMMC */
#define UNIPHIER_SD_CAP_DMA_INTERNAL BIT(1) /* have internal DMA engine */
#define UNIPHIER_SD_CAP_DIV1024 BIT(2) /* divisor 1024 is available */
+#define UNIPHIER_SD_CAP_64BIT BIT(3) /* Controller is 64bit */
};
+static u64 uniphier_sd_readq(struct uniphier_sd_priv *priv, unsigned int reg)
+{
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT)
+ return readq(priv->regbase + (reg << 1));
+ else
+ return readq(priv->regbase + reg);
+}
+
+static void uniphier_sd_writeq(struct uniphier_sd_priv *priv,
+ u64 val, unsigned int reg)
+{
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT)
+ writeq(val, priv->regbase + (reg << 1));
+ else
+ writeq(val, priv->regbase + reg);
+}
+
+static u32 uniphier_sd_readl(struct uniphier_sd_priv *priv, unsigned int reg)
+{
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT)
+ return readl(priv->regbase + (reg << 1));
+ else
+ return readl(priv->regbase + reg);
+}
+
+static void uniphier_sd_writel(struct uniphier_sd_priv *priv,
+ u32 val, unsigned int reg)
+{
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT)
+ writel(val, priv->regbase + (reg << 1));
+ else
+ writel(val, priv->regbase + reg);
+}
+
static dma_addr_t __dma_map_single(void *ptr, size_t size,
enum dma_data_direction dir)
{
static int uniphier_sd_check_error(struct udevice *dev)
{
struct uniphier_sd_priv *priv = dev_get_priv(dev);
- u32 info2 = readl(priv->regbase + UNIPHIER_SD_INFO2);
+ u32 info2 = uniphier_sd_readl(priv, UNIPHIER_SD_INFO2);
if (info2 & UNIPHIER_SD_INFO2_ERR_RTO) {
/*
long wait = 1000000;
int ret;
- while (!(readl(priv->regbase + reg) & flag)) {
+ while (!(uniphier_sd_readl(priv, reg) & flag)) {
if (wait-- < 0) {
dev_err(dev, "timeout\n");
return -ETIMEDOUT;
return 0;
}
-static int uniphier_sd_pio_read_one_block(struct udevice *dev, u32 **pbuf,
+static int uniphier_sd_pio_read_one_block(struct udevice *dev, char *pbuf,
uint blocksize)
{
struct uniphier_sd_priv *priv = dev_get_priv(dev);
* Clear the status flag _before_ read the buffer out because
* UNIPHIER_SD_INFO2_BRE is edge-triggered, not level-triggered.
*/
- writel(0, priv->regbase + UNIPHIER_SD_INFO2);
-
- if (likely(IS_ALIGNED((unsigned long)*pbuf, 4))) {
- for (i = 0; i < blocksize / 4; i++)
- *(*pbuf)++ = readl(priv->regbase + UNIPHIER_SD_BUF);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_INFO2);
+
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT) {
+ u64 *buf = (u64 *)pbuf;
+ if (likely(IS_ALIGNED((uintptr_t)buf, 8))) {
+ for (i = 0; i < blocksize / 8; i++) {
+ *buf++ = uniphier_sd_readq(priv,
+ UNIPHIER_SD_BUF);
+ }
+ } else {
+ for (i = 0; i < blocksize / 8; i++) {
+ u64 data;
+ data = uniphier_sd_readq(priv,
+ UNIPHIER_SD_BUF);
+ put_unaligned(data, buf++);
+ }
+ }
} else {
- for (i = 0; i < blocksize / 4; i++)
- put_unaligned(readl(priv->regbase + UNIPHIER_SD_BUF),
- (*pbuf)++);
+ u32 *buf = (u32 *)pbuf;
+ if (likely(IS_ALIGNED((uintptr_t)buf, 4))) {
+ for (i = 0; i < blocksize / 4; i++) {
+ *buf++ = uniphier_sd_readl(priv,
+ UNIPHIER_SD_BUF);
+ }
+ } else {
+ for (i = 0; i < blocksize / 4; i++) {
+ u32 data;
+ data = uniphier_sd_readl(priv, UNIPHIER_SD_BUF);
+ put_unaligned(data, buf++);
+ }
+ }
}
return 0;
}
static int uniphier_sd_pio_write_one_block(struct udevice *dev,
- const u32 **pbuf, uint blocksize)
+ const char *pbuf, uint blocksize)
{
struct uniphier_sd_priv *priv = dev_get_priv(dev);
int i, ret;
if (ret)
return ret;
- writel(0, priv->regbase + UNIPHIER_SD_INFO2);
-
- if (likely(IS_ALIGNED((unsigned long)*pbuf, 4))) {
- for (i = 0; i < blocksize / 4; i++)
- writel(*(*pbuf)++, priv->regbase + UNIPHIER_SD_BUF);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_INFO2);
+
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT) {
+ const u64 *buf = (const u64 *)pbuf;
+ if (likely(IS_ALIGNED((uintptr_t)buf, 8))) {
+ for (i = 0; i < blocksize / 8; i++) {
+ uniphier_sd_writeq(priv, *buf++,
+ UNIPHIER_SD_BUF);
+ }
+ } else {
+ for (i = 0; i < blocksize / 8; i++) {
+ u64 data = get_unaligned(buf++);
+ uniphier_sd_writeq(priv, data,
+ UNIPHIER_SD_BUF);
+ }
+ }
} else {
- for (i = 0; i < blocksize / 4; i++)
- writel(get_unaligned((*pbuf)++),
- priv->regbase + UNIPHIER_SD_BUF);
+ const u32 *buf = (const u32 *)pbuf;
+ if (likely(IS_ALIGNED((uintptr_t)buf, 4))) {
+ for (i = 0; i < blocksize / 4; i++) {
+ uniphier_sd_writel(priv, *buf++,
+ UNIPHIER_SD_BUF);
+ }
+ } else {
+ for (i = 0; i < blocksize / 4; i++) {
+ u32 data = get_unaligned(buf++);
+ uniphier_sd_writel(priv, data,
+ UNIPHIER_SD_BUF);
+ }
+ }
}
return 0;
static int uniphier_sd_pio_xfer(struct udevice *dev, struct mmc_data *data)
{
- u32 *dest = (u32 *)data->dest;
- const u32 *src = (const u32 *)data->src;
+ const char *src = data->src;
+ char *dest = data->dest;
int i, ret;
for (i = 0; i < data->blocks; i++) {
if (data->flags & MMC_DATA_READ)
- ret = uniphier_sd_pio_read_one_block(dev, &dest,
+ ret = uniphier_sd_pio_read_one_block(dev, dest,
data->blocksize);
else
- ret = uniphier_sd_pio_write_one_block(dev, &src,
+ ret = uniphier_sd_pio_write_one_block(dev, src,
data->blocksize);
if (ret)
return ret;
+
+ if (data->flags & MMC_DATA_READ)
+ dest += data->blocksize;
+ else
+ src += data->blocksize;
}
return 0;
{
u32 tmp;
- writel(0, priv->regbase + UNIPHIER_SD_DMA_INFO1);
- writel(0, priv->regbase + UNIPHIER_SD_DMA_INFO2);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_DMA_INFO1);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_DMA_INFO2);
/* enable DMA */
- tmp = readl(priv->regbase + UNIPHIER_SD_EXTMODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_EXTMODE);
tmp |= UNIPHIER_SD_EXTMODE_DMA_EN;
- writel(tmp, priv->regbase + UNIPHIER_SD_EXTMODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_EXTMODE);
- writel(dma_addr & U32_MAX, priv->regbase + UNIPHIER_SD_DMA_ADDR_L);
+ uniphier_sd_writel(priv, dma_addr & U32_MAX, 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);
+ uniphier_sd_writel(priv, dma_addr & U32_MAX, UNIPHIER_SD_DMA_ADDR_H);
- writel(UNIPHIER_SD_DMA_CTL_START, priv->regbase + UNIPHIER_SD_DMA_CTL);
+ uniphier_sd_writel(priv, UNIPHIER_SD_DMA_CTL_START, UNIPHIER_SD_DMA_CTL);
}
static int uniphier_sd_dma_wait_for_irq(struct udevice *dev, u32 flag,
struct uniphier_sd_priv *priv = dev_get_priv(dev);
long wait = 1000000 + 10 * blocks;
- while (!(readl(priv->regbase + UNIPHIER_SD_DMA_INFO1) & flag)) {
+ while (!(uniphier_sd_readl(priv, UNIPHIER_SD_DMA_INFO1) & flag)) {
if (wait-- < 0) {
dev_err(dev, "timeout during DMA\n");
return -ETIMEDOUT;
udelay(10);
}
- if (readl(priv->regbase + UNIPHIER_SD_DMA_INFO2)) {
+ if (uniphier_sd_readl(priv, UNIPHIER_SD_DMA_INFO2)) {
dev_err(dev, "error during DMA\n");
return -EIO;
}
u32 poll_flag, tmp;
int ret;
- tmp = readl(priv->regbase + UNIPHIER_SD_DMA_MODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_DMA_MODE);
if (data->flags & MMC_DATA_READ) {
buf = data->dest;
tmp &= ~UNIPHIER_SD_DMA_MODE_DIR_RD;
}
- writel(tmp, priv->regbase + UNIPHIER_SD_DMA_MODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_DMA_MODE);
dma_addr = __dma_map_single(buf, len, dir);
int ret;
u32 tmp;
- if (readl(priv->regbase + UNIPHIER_SD_INFO2) & UNIPHIER_SD_INFO2_CBSY) {
+ if (uniphier_sd_readl(priv, UNIPHIER_SD_INFO2) & UNIPHIER_SD_INFO2_CBSY) {
dev_err(dev, "command busy\n");
return -EBUSY;
}
/* clear all status flags */
- writel(0, priv->regbase + UNIPHIER_SD_INFO1);
- writel(0, priv->regbase + UNIPHIER_SD_INFO2);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_INFO1);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_INFO2);
/* disable DMA once */
- tmp = readl(priv->regbase + UNIPHIER_SD_EXTMODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_EXTMODE);
tmp &= ~UNIPHIER_SD_EXTMODE_DMA_EN;
- writel(tmp, priv->regbase + UNIPHIER_SD_EXTMODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_EXTMODE);
- writel(cmd->cmdarg, priv->regbase + UNIPHIER_SD_ARG);
+ uniphier_sd_writel(priv, cmd->cmdarg, UNIPHIER_SD_ARG);
tmp = cmd->cmdidx;
if (data) {
- writel(data->blocksize, priv->regbase + UNIPHIER_SD_SIZE);
- writel(data->blocks, priv->regbase + UNIPHIER_SD_SECCNT);
+ uniphier_sd_writel(priv, data->blocksize, UNIPHIER_SD_SIZE);
+ uniphier_sd_writel(priv, data->blocks, UNIPHIER_SD_SECCNT);
/* Do not send CMD12 automatically */
tmp |= UNIPHIER_SD_CMD_NOSTOP | UNIPHIER_SD_CMD_DATA;
dev_dbg(dev, "sending CMD%d (SD_CMD=%08x, SD_ARG=%08x)\n",
cmd->cmdidx, tmp, cmd->cmdarg);
- writel(tmp, priv->regbase + UNIPHIER_SD_CMD);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_CMD);
ret = uniphier_sd_wait_for_irq(dev, UNIPHIER_SD_INFO1,
UNIPHIER_SD_INFO1_RSP);
return ret;
if (cmd->resp_type & MMC_RSP_136) {
- u32 rsp_127_104 = readl(priv->regbase + UNIPHIER_SD_RSP76);
- u32 rsp_103_72 = readl(priv->regbase + UNIPHIER_SD_RSP54);
- u32 rsp_71_40 = readl(priv->regbase + UNIPHIER_SD_RSP32);
- u32 rsp_39_8 = readl(priv->regbase + UNIPHIER_SD_RSP10);
-
- cmd->response[0] = (rsp_127_104 & 0xffffff) << 8 |
- (rsp_103_72 & 0xff);
- cmd->response[1] = (rsp_103_72 & 0xffffff) << 8 |
- (rsp_71_40 & 0xff);
- cmd->response[2] = (rsp_71_40 & 0xffffff) << 8 |
- (rsp_39_8 & 0xff);
- cmd->response[3] = (rsp_39_8 & 0xffffff) << 8;
+ u32 rsp_127_104 = uniphier_sd_readl(priv, UNIPHIER_SD_RSP76);
+ u32 rsp_103_72 = uniphier_sd_readl(priv, UNIPHIER_SD_RSP54);
+ u32 rsp_71_40 = uniphier_sd_readl(priv, UNIPHIER_SD_RSP32);
+ u32 rsp_39_8 = uniphier_sd_readl(priv, UNIPHIER_SD_RSP10);
+
+ cmd->response[0] = ((rsp_127_104 & 0x00ffffff) << 8) |
+ ((rsp_103_72 & 0xff000000) >> 24);
+ cmd->response[1] = ((rsp_103_72 & 0x00ffffff) << 8) |
+ ((rsp_71_40 & 0xff000000) >> 24);
+ cmd->response[2] = ((rsp_71_40 & 0x00ffffff) << 8) |
+ ((rsp_39_8 & 0xff000000) >> 24);
+ cmd->response[3] = (rsp_39_8 & 0xffffff) << 8;
} else {
/* bit 39-8 */
- cmd->response[0] = readl(priv->regbase + UNIPHIER_SD_RSP10);
+ cmd->response[0] = uniphier_sd_readl(priv, UNIPHIER_SD_RSP10);
}
if (data) {
return -EINVAL;
}
- tmp = readl(priv->regbase + UNIPHIER_SD_OPTION);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_OPTION);
tmp &= ~UNIPHIER_SD_OPTION_WIDTH_MASK;
tmp |= val;
- writel(tmp, priv->regbase + UNIPHIER_SD_OPTION);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_OPTION);
return 0;
}
{
u32 tmp;
- tmp = readl(priv->regbase + UNIPHIER_SD_IF_MODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_IF_MODE);
if (mmc->ddr_mode)
tmp |= UNIPHIER_SD_IF_MODE_DDR;
else
tmp &= ~UNIPHIER_SD_IF_MODE_DDR;
- writel(tmp, priv->regbase + UNIPHIER_SD_IF_MODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_IF_MODE);
}
static void uniphier_sd_set_clk_rate(struct uniphier_sd_priv *priv,
else
val = UNIPHIER_SD_CLKCTL_DIV1024;
- tmp = readl(priv->regbase + UNIPHIER_SD_CLKCTL);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_CLKCTL);
if (tmp & UNIPHIER_SD_CLKCTL_SCLKEN &&
(tmp & UNIPHIER_SD_CLKCTL_DIV_MASK) == val)
return;
/* stop the clock before changing its rate to avoid a glitch signal */
tmp &= ~UNIPHIER_SD_CLKCTL_SCLKEN;
- writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_CLKCTL);
tmp &= ~UNIPHIER_SD_CLKCTL_DIV_MASK;
tmp |= val | UNIPHIER_SD_CLKCTL_OFFEN;
- writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_CLKCTL);
tmp |= UNIPHIER_SD_CLKCTL_SCLKEN;
- writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_CLKCTL);
udelay(1000);
}
if (priv->caps & UNIPHIER_SD_CAP_NONREMOVABLE)
return 1;
- return !!(readl(priv->regbase + UNIPHIER_SD_INFO1) &
+ return !!(uniphier_sd_readl(priv, UNIPHIER_SD_INFO1) &
UNIPHIER_SD_INFO1_CD);
}
u32 tmp;
/* soft reset of the host */
- tmp = readl(priv->regbase + UNIPHIER_SD_SOFT_RST);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_SOFT_RST);
tmp &= ~UNIPHIER_SD_SOFT_RST_RSTX;
- writel(tmp, priv->regbase + UNIPHIER_SD_SOFT_RST);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_SOFT_RST);
tmp |= UNIPHIER_SD_SOFT_RST_RSTX;
- writel(tmp, priv->regbase + UNIPHIER_SD_SOFT_RST);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_SOFT_RST);
/* FIXME: implement eMMC hw_reset */
- writel(UNIPHIER_SD_STOP_SEC, priv->regbase + UNIPHIER_SD_STOP);
+ uniphier_sd_writel(priv, UNIPHIER_SD_STOP_SEC, UNIPHIER_SD_STOP);
/*
* Connected to 32bit AXI.
* This register dropped backward compatibility at version 0x10.
* Write an appropriate value depending on the IP version.
*/
- writel(priv->version >= 0x10 ? 0x00000101 : 0x00000000,
- priv->regbase + UNIPHIER_SD_HOST_MODE);
+ uniphier_sd_writel(priv, priv->version >= 0x10 ? 0x00000101 : 0x00000000,
+ UNIPHIER_SD_HOST_MODE);
if (priv->caps & UNIPHIER_SD_CAP_DMA_INTERNAL) {
- tmp = readl(priv->regbase + UNIPHIER_SD_DMA_MODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_DMA_MODE);
tmp |= UNIPHIER_SD_DMA_MODE_ADDR_INC;
- writel(tmp, priv->regbase + UNIPHIER_SD_DMA_MODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_DMA_MODE);
}
}
+static int uniphier_sd_bind(struct udevice *dev)
+{
+ struct uniphier_sd_plat *plat = dev_get_platdata(dev);
+
+ return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
+
static int uniphier_sd_probe(struct udevice *dev)
{
+ struct uniphier_sd_plat *plat = dev_get_platdata(dev);
struct uniphier_sd_priv *priv = dev_get_priv(dev);
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ const u32 quirks = dev_get_driver_data(dev);
fdt_addr_t base;
struct clk clk;
int ret;
+#ifdef CONFIG_DM_REGULATOR
+ struct udevice *vqmmc_dev;
+#endif
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
if (!priv->regbase)
return -ENOMEM;
+#ifdef CONFIG_DM_REGULATOR
+ ret = device_get_supply_regulator(dev, "vqmmc-supply", &vqmmc_dev);
+ if (!ret) {
+ /* Set the regulator to 3.3V until we support 1.8V modes */
+ regulator_set_value(vqmmc_dev, 3300000);
+ regulator_set_enable(vqmmc_dev, true);
+ }
+#endif
+
ret = clk_get_by_index(dev, 0, &clk);
if (ret < 0) {
dev_err(dev, "failed to get host clock\n");
return ret;
}
- priv->cfg.name = dev->name;
- priv->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
+ plat->cfg.name = dev->name;
+ plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
- switch (fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 1)) {
+ switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
+ 1)) {
case 8:
- priv->cfg.host_caps |= MMC_MODE_8BIT;
+ plat->cfg.host_caps |= MMC_MODE_8BIT;
break;
case 4:
- priv->cfg.host_caps |= MMC_MODE_4BIT;
+ plat->cfg.host_caps |= MMC_MODE_4BIT;
break;
case 1:
break;
return -EINVAL;
}
- if (fdt_get_property(gd->fdt_blob, dev->of_offset, "non-removable",
- NULL))
- priv->caps |= UNIPHIER_SD_CAP_NONREMOVABLE;
-
- priv->version = readl(priv->regbase + UNIPHIER_SD_VERSION) &
+ if (quirks) {
+ priv->caps = quirks;
+ } else {
+ priv->version = uniphier_sd_readl(priv, UNIPHIER_SD_VERSION) &
UNIPHIER_SD_VERSION_IP;
- dev_dbg(dev, "version %x\n", priv->version);
- if (priv->version >= 0x10) {
- priv->caps |= UNIPHIER_SD_CAP_DMA_INTERNAL;
- priv->caps |= UNIPHIER_SD_CAP_DIV1024;
+ dev_dbg(dev, "version %x\n", priv->version);
+ if (priv->version >= 0x10) {
+ priv->caps |= UNIPHIER_SD_CAP_DMA_INTERNAL;
+ priv->caps |= UNIPHIER_SD_CAP_DIV1024;
+ }
}
+ if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev), "non-removable",
+ NULL))
+ priv->caps |= UNIPHIER_SD_CAP_NONREMOVABLE;
+
uniphier_sd_host_init(priv);
- priv->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
- priv->cfg.f_min = priv->mclk /
+ plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
+ plat->cfg.f_min = priv->mclk /
(priv->caps & UNIPHIER_SD_CAP_DIV1024 ? 1024 : 512);
- priv->cfg.f_max = priv->mclk;
- priv->cfg.b_max = U32_MAX; /* max value of UNIPHIER_SD_SECCNT */
-
- priv->mmc = mmc_create(&priv->cfg, priv);
- if (!priv->mmc)
- return -EIO;
-
- upriv->mmc = priv->mmc;
- priv->mmc->dev = dev;
-
- return 0;
-}
-
-static int uniphier_sd_remove(struct udevice *dev)
-{
- struct uniphier_sd_priv *priv = dev_get_priv(dev);
+ plat->cfg.f_max = priv->mclk;
+ plat->cfg.b_max = U32_MAX; /* max value of UNIPHIER_SD_SECCNT */
- mmc_destroy(priv->mmc);
+ upriv->mmc = &plat->mmc;
return 0;
}
static const struct udevice_id uniphier_sd_match[] = {
- { .compatible = "socionext,uniphier-sdhc" },
+ { .compatible = "renesas,sdhi-r8a7795", .data = UNIPHIER_SD_CAP_64BIT },
+ { .compatible = "renesas,sdhi-r8a7796", .data = UNIPHIER_SD_CAP_64BIT },
+ { .compatible = "renesas,sdhi-r8a77970", .data = UNIPHIER_SD_CAP_64BIT },
+ { .compatible = "renesas,sdhi-r8a77995", .data = UNIPHIER_SD_CAP_64BIT },
+ { .compatible = "socionext,uniphier-sdhc", .data = 0 },
{ /* sentinel */ }
};
.name = "uniphier-mmc",
.id = UCLASS_MMC,
.of_match = uniphier_sd_match,
+ .bind = uniphier_sd_bind,
.probe = uniphier_sd_probe,
- .remove = uniphier_sd_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_sd_priv),
+ .platdata_auto_alloc_size = sizeof(struct uniphier_sd_plat),
.ops = &uniphier_sd_ops,
};