X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmmc%2Fsh_mmcif.c;h=1ff59f06d576b77dbfe1fc92ba7f44f5a9d0e006;hb=640f4e35deccbea377f543737594753ff5a44d95;hp=567e2cb61d32ba8b63f574a2ee14c4dff72b989c;hpb=afb35666da107ccac076b30aed1ad90e7bbcffae;p=u-boot diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 567e2cb61d..1ff59f06d5 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -3,9 +3,7 @@ * * Copyright (C) 2011 Renesas Solutions Corp. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. + * SPDX-License-Identifier: GPL-2.0 */ #include @@ -14,17 +12,12 @@ #include #include #include -#include +#include #include #include "sh_mmcif.h" #define DRIVER_NAME "sh_mmcif" -static void *mmc_priv(struct mmc *mmc) -{ - return (void *)mmc->priv; -} - static int sh_mmcif_intr(void *dev_id) { struct sh_mmcif_host *host = dev_id; @@ -108,20 +101,18 @@ static int mmcif_wait_interrupt_flag(struct sh_mmcif_host *host) static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) { - int i; - sh_mmcif_bitclr(CLK_ENABLE, &host->regs->ce_clk_ctrl); sh_mmcif_bitclr(CLK_CLEAR, &host->regs->ce_clk_ctrl); if (!clk) return; - if (clk == CLKDEV_EMMC_DATA) { + + if (clk == CLKDEV_EMMC_DATA) sh_mmcif_bitset(CLK_PCLK, &host->regs->ce_clk_ctrl); - } else { - for (i = 1; (unsigned int)host->clk / (1 << i) >= clk; i++) - ; - sh_mmcif_bitset((i - 1) << 16, &host->regs->ce_clk_ctrl); - } + else + sh_mmcif_bitset((fls(DIV_ROUND_UP(host->clk, + clk) - 1) - 1) << 16, + &host->regs->ce_clk_ctrl); sh_mmcif_bitset(CLK_ENABLE, &host->regs->ce_clk_ctrl); } @@ -177,7 +168,7 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) if (state2 & STS2_CRC_ERR) ret = -EILSEQ; else if (state2 & STS2_TIMEOUT_ERR) - ret = TIMEOUT; + ret = -ETIMEDOUT; else ret = -EILSEQ; return ret; @@ -492,7 +483,7 @@ static int sh_mmcif_start_cmd(struct sh_mmcif_host *host, case MMC_CMD_ALL_SEND_CID: case MMC_CMD_SELECT_CARD: case MMC_CMD_APP_CMD: - ret = TIMEOUT; + ret = -ETIMEDOUT; break; default: printf(DRIVER_NAME": Cmd(d'%d) err\n", cmd->cmdidx); @@ -522,21 +513,21 @@ static int sh_mmcif_start_cmd(struct sh_mmcif_host *host, static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { - struct sh_mmcif_host *host = mmc_priv(mmc); + struct sh_mmcif_host *host = mmc->priv; int ret; WATCHDOG_RESET(); switch (cmd->cmdidx) { case MMC_CMD_APP_CMD: - return TIMEOUT; + return -ETIMEDOUT; case MMC_CMD_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */ if (data) /* ext_csd */ break; else /* send_if_cond cmd (not support) */ - return TIMEOUT; + return -ETIMEDOUT; default: break; } @@ -548,9 +539,9 @@ static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd, return ret; } -static void sh_mmcif_set_ios(struct mmc *mmc) +static int sh_mmcif_set_ios(struct mmc *mmc) { - struct sh_mmcif_host *host = mmc_priv(mmc); + struct sh_mmcif_host *host = mmc->priv; if (mmc->clock) sh_mmcif_clock_control(host, mmc->clock); @@ -563,46 +554,55 @@ static void sh_mmcif_set_ios(struct mmc *mmc) host->bus_width = MMC_BUS_WIDTH_1; debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); + + return 0; } static int sh_mmcif_init(struct mmc *mmc) { - struct sh_mmcif_host *host = mmc_priv(mmc); + struct sh_mmcif_host *host = mmc->priv; sh_mmcif_sync_reset(host); sh_mmcif_write(MASK_ALL, &host->regs->ce_int_mask); return 0; } +static const struct mmc_ops sh_mmcif_ops = { + .send_cmd = sh_mmcif_request, + .set_ios = sh_mmcif_set_ios, + .init = sh_mmcif_init, +}; + +static struct mmc_config sh_mmcif_cfg = { + .name = DRIVER_NAME, + .ops = &sh_mmcif_ops, + .host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT | + MMC_MODE_8BIT, + .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, + .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, +}; + int mmcif_mmc_init(void) { - int ret = 0; struct mmc *mmc; struct sh_mmcif_host *host = NULL; - mmc = malloc(sizeof(struct mmc)); - if (!mmc) - ret = -ENOMEM; - memset(mmc, 0, sizeof(*mmc)); host = malloc(sizeof(struct sh_mmcif_host)); if (!host) - ret = -ENOMEM; + return -ENOMEM; memset(host, 0, sizeof(*host)); - mmc->f_min = CLKDEV_MMC_INIT; - mmc->f_max = CLKDEV_EMMC_DATA; - mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT | - MMC_MODE_8BIT; - memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME)); - mmc->send_cmd = sh_mmcif_request; - mmc->set_ios = sh_mmcif_set_ios; - mmc->init = sh_mmcif_init; host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR; host->clk = CONFIG_SH_MMCIF_CLK; - mmc->priv = host; - mmc_register(mmc); + sh_mmcif_cfg.f_min = MMC_CLK_DIV_MIN(host->clk); + sh_mmcif_cfg.f_max = MMC_CLK_DIV_MAX(host->clk); - return ret; + mmc = mmc_create(&sh_mmcif_cfg, host); + if (mmc == NULL) { + free(host); + return -ENOMEM; + } + + return 0; }