]> git.sur5r.net Git - u-boot/blobdiff - drivers/mmc/mxcmmc.c
dm: core: Add ofnode function to read a 64-bit int
[u-boot] / drivers / mmc / mxcmmc.c
index d30717661f95f02e44296c7b984812a2ad2a648a..dcf17c5d60e90a1569fd0dea00087375a0f665e4 100644 (file)
 #include <part.h>
 #include <malloc.h>
 #include <mmc.h>
-#include <asm/errno.h>
+#include <linux/errno.h>
 #include <asm/io.h>
-#ifdef CONFIG_MX27
 #include <asm/arch/clock.h>
-#endif
 
 #define DRIVER_NAME "mxc-mmc"
 
@@ -124,6 +122,8 @@ struct mxcmci_host {
 };
 
 static struct mxcmci_host mxcmci_host;
+
+/* maintainer note: do we really want to have a global host pointer? */
 static struct mxcmci_host *host = &mxcmci_host;
 
 static inline int mxcmci_use_dma(struct mxcmci_host *host)
@@ -136,14 +136,14 @@ static void mxcmci_softreset(struct mxcmci_host *host)
        int i;
 
        /* reset sequence */
-       writew(STR_STP_CLK_RESET, &host->base->str_stp_clk);
-       writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
+       writel(STR_STP_CLK_RESET, &host->base->str_stp_clk);
+       writel(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
                        &host->base->str_stp_clk);
 
        for (i = 0; i < 8; i++)
-               writew(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
+               writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
 
-       writew(0xff, &host->base->res_to);
+       writel(0xff, &host->base->res_to);
 }
 
 static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
@@ -154,8 +154,8 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
 
        host->data = data;
 
-       writew(nob, &host->base->nob);
-       writew(blksz, &host->base->blk_len);
+       writel(nob, &host->base->nob);
+       writel(blksz, &host->base->blk_len);
        host->datasize = datasize;
 }
 
@@ -185,9 +185,9 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_cmd *cmd,
                return -EINVAL;
        }
 
-       writew(cmd->cmdidx, &host->base->cmd);
+       writel(cmd->cmdidx, &host->base->cmd);
        writel(cmd->cmdarg, &host->base->arg);
-       writew(cmdat, &host->base->cmd_dat_cont);
+       writel(cmdat, &host->base->cmd_dat_cont);
 
        return 0;
 }
@@ -211,11 +211,11 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
                } else if (stat & STATUS_CRC_WRITE_ERR) {
                        u32 err_code = (stat >> 9) & 0x3;
                        if (err_code == 2) /* No CRC response */
-                               data_error = TIMEOUT;
+                               data_error = -ETIMEDOUT;
                        else
                                data_error = -EILSEQ;
                } else if (stat & STATUS_TIME_OUT_READ) {
-                       data_error = TIMEOUT;
+                       data_error = -ETIMEDOUT;
                } else {
                        data_error = -EIO;
                }
@@ -238,7 +238,7 @@ static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
 
        if (stat & STATUS_TIME_OUT_RESP) {
                printf("CMD TIMEOUT\n");
-               return TIMEOUT;
+               return -ETIMEDOUT;
        } else if (stat & STATUS_RESP_CRC_ERR && cmd->resp_type & MMC_RSP_CRC) {
                printf("cmd crc error\n");
                return -EILSEQ;
@@ -247,14 +247,14 @@ static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
        if (cmd->resp_type & MMC_RSP_PRESENT) {
                if (cmd->resp_type & MMC_RSP_136) {
                        for (i = 0; i < 4; i++) {
-                               a = readw(&host->base->res_fifo);
-                               b = readw(&host->base->res_fifo);
+                               a = readl(&host->base->res_fifo) & 0xFFFF;
+                               b = readl(&host->base->res_fifo) & 0xFFFF;
                                resp[i] = a << 16 | b;
                        }
                } else {
-                       a = readw(&host->base->res_fifo);
-                       b = readw(&host->base->res_fifo);
-                       c = readw(&host->base->res_fifo);
+                       a = readl(&host->base->res_fifo) & 0xFFFF;
+                       b = readl(&host->base->res_fifo) & 0xFFFF;
+                       c = readl(&host->base->res_fifo) & 0xFFFF;
                        resp[0] = a << 24 | b << 8 | c >> 8;
                }
        }
@@ -422,7 +422,7 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
 {
        unsigned int divider;
        int prescaler = 0;
-       unsigned long clk_in = imx_get_perclk2();
+       unsigned long clk_in = mxc_get_clock(MXC_ESDHC_CLK);
 
        while (prescaler <= 0x800) {
                for (divider = 1; divider <= 0xF; divider++) {
@@ -445,10 +445,10 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
                        prescaler <<= 1;
        }
 
-       writew((prescaler << 4) | divider, &host->base->clk_rate);
+       writel((prescaler << 4) | divider, &host->base->clk_rate);
 }
 
-static void mxcmci_set_ios(struct mmc *mmc)
+static int mxcmci_set_ios(struct mmc *mmc)
 {
        struct mxcmci_host *host = mmc->priv;
        if (mmc->bus_width == 4)
@@ -458,12 +458,14 @@ static void mxcmci_set_ios(struct mmc *mmc)
 
        if (mmc->clock) {
                mxcmci_set_clk_rate(host, mmc->clock);
-               writew(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
+               writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
        } else {
-               writew(STR_STP_CLK_STOP_CLK, &host->base->str_stp_clk);
+               writel(STR_STP_CLK_STOP_CLK, &host->base->str_stp_clk);
        }
 
        host->clock = mmc->clock;
+
+       return 0;
 }
 
 static int mxcmci_init(struct mmc *mmc)
@@ -472,7 +474,7 @@ static int mxcmci_init(struct mmc *mmc)
 
        mxcmci_softreset(host);
 
-       host->rev_no = readw(&host->base->rev_no);
+       host->rev_no = readl(&host->base->rev_no);
        if (host->rev_no != 0x400) {
                printf("wrong rev.no. 0x%08x. aborting.\n",
                        host->rev_no);
@@ -480,38 +482,37 @@ static int mxcmci_init(struct mmc *mmc)
        }
 
        /* recommended in data sheet */
-       writew(0x2db4, &host->base->read_to);
+       writel(0x2db4, &host->base->read_to);
 
        writel(0, &host->base->int_cntr);
 
        return 0;
 }
 
-static int mxcmci_initialize(bd_t *bis)
-{
-       struct mmc *mmc = NULL;
-
-       mmc = malloc(sizeof(struct mmc));
-
-       if (!mmc)
-               return -ENOMEM;
+static const struct mmc_ops mxcmci_ops = {
+       .send_cmd       = mxcmci_request,
+       .set_ios        = mxcmci_set_ios,
+       .init           = mxcmci_init,
+};
 
-       sprintf(mmc->name, "MXC MCI");
-       mmc->send_cmd = mxcmci_request;
-       mmc->set_ios = mxcmci_set_ios;
-       mmc->init = mxcmci_init;
-       mmc->host_caps = MMC_MODE_4BIT;
+static struct mmc_config mxcmci_cfg = {
+       .name           = "MXC MCI",
+       .ops            = &mxcmci_ops,
+       .host_caps      = MMC_MODE_4BIT,
+       .voltages       = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+};
 
+static int mxcmci_initialize(bd_t *bis)
+{
        host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
-       mmc->priv = host;
-       host->mmc = mmc;
-
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
-       mmc->f_min = imx_get_perclk2() >> 7;
-       mmc->f_max = imx_get_perclk2() >> 1;
+       mxcmci_cfg.f_min = mxc_get_clock(MXC_ESDHC_CLK) >> 7;
+       mxcmci_cfg.f_max = mxc_get_clock(MXC_ESDHC_CLK) >> 1;
 
-       mmc_register(mmc);
+       host->mmc = mmc_create(&mxcmci_cfg, host);
+       if (host->mmc == NULL)
+               return -1;
 
        return 0;
 }