diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/u-boot/drivers/mmc | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/u-boot/drivers/mmc')
31 files changed, 0 insertions, 10443 deletions
diff --git a/qemu/roms/u-boot/drivers/mmc/Makefile b/qemu/roms/u-boot/drivers/mmc/Makefile deleted file mode 100644 index 931922bc4..000000000 --- a/qemu/roms/u-boot/drivers/mmc/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o -obj-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o -obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o -obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o -obj-$(CONFIG_FTSDC021) += ftsdc021_sdhci.o -obj-$(CONFIG_GENERIC_MMC) += mmc.o -obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o -obj-$(CONFIG_MMC_SPI) += mmc_spi.o -obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o -obj-$(CONFIG_MV_SDHCI) += mv_sdhci.o -obj-$(CONFIG_MXC_MMC) += mxcmmc.o -obj-$(CONFIG_MXS_MMC) += mxsmmc.o -obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o -obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o -obj-$(CONFIG_SDHCI) += sdhci.o -obj-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o -obj-$(CONFIG_KONA_SDHCI) += kona_sdhci.o -obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o -obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o -obj-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o -obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o -obj-$(CONFIG_DWMMC) += dw_mmc.o -obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o -obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o -obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o -ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o -else -obj-$(CONFIG_GENERIC_MMC) += mmc_write.o -endif diff --git a/qemu/roms/u-boot/drivers/mmc/arm_pl180_mmci.c b/qemu/roms/u-boot/drivers/mmc/arm_pl180_mmci.c deleted file mode 100644 index 5ef7ff7ff..000000000 --- a/qemu/roms/u-boot/drivers/mmc/arm_pl180_mmci.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * ARM PrimeCell MultiMedia Card Interface - PL180 - * - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Ulf Hansson <ulf.hansson@stericsson.com> - * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com> - * Ported to drivers/mmc/ by: Matt Waddel <matt.waddel@linaro.org> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* #define DEBUG */ - -#include <asm/io.h> -#include "common.h" -#include <errno.h> -#include <mmc.h> -#include "arm_pl180_mmci.h" -#include <malloc.h> - -static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd) -{ - u32 hoststatus, statusmask; - struct pl180_mmc_host *host = dev->priv; - - statusmask = SDI_STA_CTIMEOUT | SDI_STA_CCRCFAIL; - if ((cmd->resp_type & MMC_RSP_PRESENT)) - statusmask |= SDI_STA_CMDREND; - else - statusmask |= SDI_STA_CMDSENT; - - do - hoststatus = readl(&host->base->status) & statusmask; - while (!hoststatus); - - writel(statusmask, &host->base->status_clear); - if (hoststatus & SDI_STA_CTIMEOUT) { - debug("CMD%d time out\n", cmd->cmdidx); - return TIMEOUT; - } else if ((hoststatus & SDI_STA_CCRCFAIL) && - (cmd->resp_type & MMC_RSP_CRC)) { - printf("CMD%d CRC error\n", cmd->cmdidx); - return -EILSEQ; - } - - if (cmd->resp_type & MMC_RSP_PRESENT) { - cmd->response[0] = readl(&host->base->response0); - cmd->response[1] = readl(&host->base->response1); - cmd->response[2] = readl(&host->base->response2); - cmd->response[3] = readl(&host->base->response3); - debug("CMD%d response[0]:0x%08X, response[1]:0x%08X, " - "response[2]:0x%08X, response[3]:0x%08X\n", - cmd->cmdidx, cmd->response[0], cmd->response[1], - cmd->response[2], cmd->response[3]); - } - - return 0; -} - -/* send command to the mmc card and wait for results */ -static int do_command(struct mmc *dev, struct mmc_cmd *cmd) -{ - int result; - u32 sdi_cmd = 0; - struct pl180_mmc_host *host = dev->priv; - - sdi_cmd = ((cmd->cmdidx & SDI_CMD_CMDINDEX_MASK) | SDI_CMD_CPSMEN); - - if (cmd->resp_type) { - sdi_cmd |= SDI_CMD_WAITRESP; - if (cmd->resp_type & MMC_RSP_136) - sdi_cmd |= SDI_CMD_LONGRESP; - } - - writel((u32)cmd->cmdarg, &host->base->argument); - udelay(COMMAND_REG_DELAY); - writel(sdi_cmd, &host->base->command); - result = wait_for_command_end(dev, cmd); - - /* After CMD2 set RCA to a none zero value. */ - if ((result == 0) && (cmd->cmdidx == MMC_CMD_ALL_SEND_CID)) - dev->rca = 10; - - /* After CMD3 open drain is switched off and push pull is used. */ - if ((result == 0) && (cmd->cmdidx == MMC_CMD_SET_RELATIVE_ADDR)) { - u32 sdi_pwr = readl(&host->base->power) & ~SDI_PWR_OPD; - writel(sdi_pwr, &host->base->power); - } - - return result; -} - -static int read_bytes(struct mmc *dev, u32 *dest, u32 blkcount, u32 blksize) -{ - u32 *tempbuff = dest; - u64 xfercount = blkcount * blksize; - struct pl180_mmc_host *host = dev->priv; - u32 status, status_err; - - debug("read_bytes: blkcount=%u blksize=%u\n", blkcount, blksize); - - status = readl(&host->base->status); - status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | - SDI_STA_RXOVERR); - while ((!status_err) && (xfercount >= sizeof(u32))) { - if (status & SDI_STA_RXDAVL) { - *(tempbuff) = readl(&host->base->fifo); - tempbuff++; - xfercount -= sizeof(u32); - } - status = readl(&host->base->status); - status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | - SDI_STA_RXOVERR); - } - - status_err = status & - (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND | - SDI_STA_RXOVERR); - while (!status_err) { - status = readl(&host->base->status); - status_err = status & - (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND | - SDI_STA_RXOVERR); - } - - if (status & SDI_STA_DTIMEOUT) { - printf("Read data timed out, xfercount: %llu, status: 0x%08X\n", - xfercount, status); - return -ETIMEDOUT; - } else if (status & SDI_STA_DCRCFAIL) { - printf("Read data bytes CRC error: 0x%x\n", status); - return -EILSEQ; - } else if (status & SDI_STA_RXOVERR) { - printf("Read data RX overflow error\n"); - return -EIO; - } - - writel(SDI_ICR_MASK, &host->base->status_clear); - - if (xfercount) { - printf("Read data error, xfercount: %llu\n", xfercount); - return -ENOBUFS; - } - - return 0; -} - -static int write_bytes(struct mmc *dev, u32 *src, u32 blkcount, u32 blksize) -{ - u32 *tempbuff = src; - int i; - u64 xfercount = blkcount * blksize; - struct pl180_mmc_host *host = dev->priv; - u32 status, status_err; - - debug("write_bytes: blkcount=%u blksize=%u\n", blkcount, blksize); - - status = readl(&host->base->status); - status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT); - while (!status_err && xfercount) { - if (status & SDI_STA_TXFIFOBW) { - if (xfercount >= SDI_FIFO_BURST_SIZE * sizeof(u32)) { - for (i = 0; i < SDI_FIFO_BURST_SIZE; i++) - writel(*(tempbuff + i), - &host->base->fifo); - tempbuff += SDI_FIFO_BURST_SIZE; - xfercount -= SDI_FIFO_BURST_SIZE * sizeof(u32); - } else { - while (xfercount >= sizeof(u32)) { - writel(*(tempbuff), &host->base->fifo); - tempbuff++; - xfercount -= sizeof(u32); - } - } - } - status = readl(&host->base->status); - status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT); - } - - status_err = status & - (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND); - while (!status_err) { - status = readl(&host->base->status); - status_err = status & - (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND); - } - - if (status & SDI_STA_DTIMEOUT) { - printf("Write data timed out, xfercount:%llu,status:0x%08X\n", - xfercount, status); - return -ETIMEDOUT; - } else if (status & SDI_STA_DCRCFAIL) { - printf("Write data CRC error\n"); - return -EILSEQ; - } - - writel(SDI_ICR_MASK, &host->base->status_clear); - - if (xfercount) { - printf("Write data error, xfercount:%llu", xfercount); - return -ENOBUFS; - } - - return 0; -} - -static int do_data_transfer(struct mmc *dev, - struct mmc_cmd *cmd, - struct mmc_data *data) -{ - int error = -ETIMEDOUT; - struct pl180_mmc_host *host = dev->priv; - u32 blksz = 0; - u32 data_ctrl = 0; - u32 data_len = (u32) (data->blocks * data->blocksize); - - if (!host->version2) { - blksz = (ffs(data->blocksize) - 1); - data_ctrl |= ((blksz << 4) & SDI_DCTRL_DBLKSIZE_MASK); - } else { - blksz = data->blocksize; - data_ctrl |= (blksz << SDI_DCTRL_DBLOCKSIZE_V2_SHIFT); - } - data_ctrl |= SDI_DCTRL_DTEN | SDI_DCTRL_BUSYMODE; - - writel(SDI_DTIMER_DEFAULT, &host->base->datatimer); - writel(data_len, &host->base->datalength); - udelay(DATA_REG_DELAY); - - if (data->flags & MMC_DATA_READ) { - data_ctrl |= SDI_DCTRL_DTDIR_IN; - writel(data_ctrl, &host->base->datactrl); - - error = do_command(dev, cmd); - if (error) - return error; - - error = read_bytes(dev, (u32 *)data->dest, (u32)data->blocks, - (u32)data->blocksize); - } else if (data->flags & MMC_DATA_WRITE) { - error = do_command(dev, cmd); - if (error) - return error; - - writel(data_ctrl, &host->base->datactrl); - error = write_bytes(dev, (u32 *)data->src, (u32)data->blocks, - (u32)data->blocksize); - } - - return error; -} - -static int host_request(struct mmc *dev, - struct mmc_cmd *cmd, - struct mmc_data *data) -{ - int result; - - if (data) - result = do_data_transfer(dev, cmd, data); - else - result = do_command(dev, cmd); - - return result; -} - -/* MMC uses open drain drivers in the enumeration phase */ -static int mmc_host_reset(struct mmc *dev) -{ - struct pl180_mmc_host *host = dev->priv; - - writel(host->pwr_init, &host->base->power); - - return 0; -} - -static void host_set_ios(struct mmc *dev) -{ - struct pl180_mmc_host *host = dev->priv; - u32 sdi_clkcr; - - sdi_clkcr = readl(&host->base->clock); - - /* Ramp up the clock rate */ - if (dev->clock) { - u32 clkdiv = 0; - u32 tmp_clock; - - if (dev->clock >= dev->cfg->f_max) { - clkdiv = 0; - dev->clock = dev->cfg->f_max; - } else { - clkdiv = (host->clock_in / dev->clock) - 2; - } - - tmp_clock = host->clock_in / (clkdiv + 2); - while (tmp_clock > dev->clock) { - clkdiv++; - tmp_clock = host->clock_in / (clkdiv + 2); - } - - if (clkdiv > SDI_CLKCR_CLKDIV_MASK) - clkdiv = SDI_CLKCR_CLKDIV_MASK; - - tmp_clock = host->clock_in / (clkdiv + 2); - dev->clock = tmp_clock; - sdi_clkcr &= ~(SDI_CLKCR_CLKDIV_MASK); - sdi_clkcr |= clkdiv; - } - - /* Set the bus width */ - if (dev->bus_width) { - u32 buswidth = 0; - - switch (dev->bus_width) { - case 1: - buswidth |= SDI_CLKCR_WIDBUS_1; - break; - case 4: - buswidth |= SDI_CLKCR_WIDBUS_4; - break; - case 8: - buswidth |= SDI_CLKCR_WIDBUS_8; - break; - default: - printf("Invalid bus width: %d\n", dev->bus_width); - break; - } - sdi_clkcr &= ~(SDI_CLKCR_WIDBUS_MASK); - sdi_clkcr |= buswidth; - } - - writel(sdi_clkcr, &host->base->clock); - udelay(CLK_CHANGE_DELAY); -} - -static const struct mmc_ops arm_pl180_mmci_ops = { - .send_cmd = host_request, - .set_ios = host_set_ios, - .init = mmc_host_reset, -}; - -/* - * mmc_host_init - initialize the mmc controller. - * Set initial clock and power for mmc slot. - * Initialize mmc struct and register with mmc framework. - */ -int arm_pl180_mmci_init(struct pl180_mmc_host *host) -{ - struct mmc *mmc; - u32 sdi_u32; - - writel(host->pwr_init, &host->base->power); - writel(host->clkdiv_init, &host->base->clock); - udelay(CLK_CHANGE_DELAY); - - /* Disable mmc interrupts */ - sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK; - writel(sdi_u32, &host->base->mask0); - - host->cfg.name = host->name; - host->cfg.ops = &arm_pl180_mmci_ops; - /* TODO remove the duplicates */ - host->cfg.host_caps = host->caps; - host->cfg.voltages = host->voltages; - host->cfg.f_min = host->clock_min; - host->cfg.f_max = host->clock_max; - if (host->b_max != 0) - host->cfg.b_max = host->b_max; - else - host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - mmc = mmc_create(&host->cfg, host); - if (mmc == NULL) - return -1; - - debug("registered mmc interface number is:%d\n", mmc->block_dev.dev); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/arm_pl180_mmci.h b/qemu/roms/u-boot/drivers/mmc/arm_pl180_mmci.h deleted file mode 100644 index f23bd391e..000000000 --- a/qemu/roms/u-boot/drivers/mmc/arm_pl180_mmci.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * ARM PrimeCell MultiMedia Card Interface - PL180 - * - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Ulf Hansson <ulf.hansson@stericsson.com> - * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com> - * Ported to drivers/mmc/ by: Matt Waddel <matt.waddel@linaro.org> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ARM_PL180_MMCI_H__ -#define __ARM_PL180_MMCI_H__ - -/* need definition of struct mmc_config */ -#include <mmc.h> - -#define COMMAND_REG_DELAY 300 -#define DATA_REG_DELAY 1000 -#define CLK_CHANGE_DELAY 2000 - -#define INIT_PWR 0xBF /* Power on, full power, not open drain */ -#define ARM_MCLK (100*1000*1000) - -/* SDI Power Control register bits */ -#define SDI_PWR_PWRCTRL_MASK 0x00000003 -#define SDI_PWR_PWRCTRL_ON 0x00000003 -#define SDI_PWR_PWRCTRL_OFF 0x00000000 -#define SDI_PWR_DAT2DIREN 0x00000004 -#define SDI_PWR_CMDDIREN 0x00000008 -#define SDI_PWR_DAT0DIREN 0x00000010 -#define SDI_PWR_DAT31DIREN 0x00000020 -#define SDI_PWR_OPD 0x00000040 -#define SDI_PWR_FBCLKEN 0x00000080 -#define SDI_PWR_DAT74DIREN 0x00000100 -#define SDI_PWR_RSTEN 0x00000200 - -#define VOLTAGE_WINDOW_MMC 0x00FF8080 -#define VOLTAGE_WINDOW_SD 0x80010000 - -/* SDI clock control register bits */ -#define SDI_CLKCR_CLKDIV_MASK 0x000000FF -#define SDI_CLKCR_CLKEN 0x00000100 -#define SDI_CLKCR_PWRSAV 0x00000200 -#define SDI_CLKCR_BYPASS 0x00000400 -#define SDI_CLKCR_WIDBUS_MASK 0x00001800 -#define SDI_CLKCR_WIDBUS_1 0x00000000 -#define SDI_CLKCR_WIDBUS_4 0x00000800 -/* V2 only */ -#define SDI_CLKCR_WIDBUS_8 0x00001000 -#define SDI_CLKCR_NEDGE 0x00002000 -#define SDI_CLKCR_HWFC_EN 0x00004000 - -#define SDI_CLKCR_CLKDIV_INIT_V1 0x000000C6 /* MCLK/(2*(0xC6+1)) => 505KHz */ -#define SDI_CLKCR_CLKDIV_INIT_V2 0x000000FD - -/* SDI command register bits */ -#define SDI_CMD_CMDINDEX_MASK 0x000000FF -#define SDI_CMD_WAITRESP 0x00000040 -#define SDI_CMD_LONGRESP 0x00000080 -#define SDI_CMD_WAITINT 0x00000100 -#define SDI_CMD_WAITPEND 0x00000200 -#define SDI_CMD_CPSMEN 0x00000400 -#define SDI_CMD_SDIOSUSPEND 0x00000800 -#define SDI_CMD_ENDCMDCOMPL 0x00001000 -#define SDI_CMD_NIEN 0x00002000 -#define SDI_CMD_CE_ATACMD 0x00004000 -#define SDI_CMD_CBOOTMODEEN 0x00008000 - -#define SDI_DTIMER_DEFAULT 0xFFFF0000 - -/* SDI Status register bits */ -#define SDI_STA_CCRCFAIL 0x00000001 -#define SDI_STA_DCRCFAIL 0x00000002 -#define SDI_STA_CTIMEOUT 0x00000004 -#define SDI_STA_DTIMEOUT 0x00000008 -#define SDI_STA_TXUNDERR 0x00000010 -#define SDI_STA_RXOVERR 0x00000020 -#define SDI_STA_CMDREND 0x00000040 -#define SDI_STA_CMDSENT 0x00000080 -#define SDI_STA_DATAEND 0x00000100 -#define SDI_STA_STBITERR 0x00000200 -#define SDI_STA_DBCKEND 0x00000400 -#define SDI_STA_CMDACT 0x00000800 -#define SDI_STA_TXACT 0x00001000 -#define SDI_STA_RXACT 0x00002000 -#define SDI_STA_TXFIFOBW 0x00004000 -#define SDI_STA_RXFIFOBR 0x00008000 -#define SDI_STA_TXFIFOF 0x00010000 -#define SDI_STA_RXFIFOF 0x00020000 -#define SDI_STA_TXFIFOE 0x00040000 -#define SDI_STA_RXFIFOE 0x00080000 -#define SDI_STA_TXDAVL 0x00100000 -#define SDI_STA_RXDAVL 0x00200000 -#define SDI_STA_SDIOIT 0x00400000 -#define SDI_STA_CEATAEND 0x00800000 -#define SDI_STA_CARDBUSY 0x01000000 -#define SDI_STA_BOOTMODE 0x02000000 -#define SDI_STA_BOOTACKERR 0x04000000 -#define SDI_STA_BOOTACKTIMEOUT 0x08000000 -#define SDI_STA_RSTNEND 0x10000000 - -/* SDI Interrupt Clear register bits */ -#define SDI_ICR_MASK 0x1DC007FF -#define SDI_ICR_CCRCFAILC 0x00000001 -#define SDI_ICR_DCRCFAILC 0x00000002 -#define SDI_ICR_CTIMEOUTC 0x00000004 -#define SDI_ICR_DTIMEOUTC 0x00000008 -#define SDI_ICR_TXUNDERRC 0x00000010 -#define SDI_ICR_RXOVERRC 0x00000020 -#define SDI_ICR_CMDRENDC 0x00000040 -#define SDI_ICR_CMDSENTC 0x00000080 -#define SDI_ICR_DATAENDC 0x00000100 -#define SDI_ICR_STBITERRC 0x00000200 -#define SDI_ICR_DBCKENDC 0x00000400 -#define SDI_ICR_SDIOITC 0x00400000 -#define SDI_ICR_CEATAENDC 0x00800000 -#define SDI_ICR_BUSYENDC 0x01000000 -#define SDI_ICR_BOOTACKERRC 0x04000000 -#define SDI_ICR_BOOTACKTIMEOUTC 0x08000000 -#define SDI_ICR_RSTNENDC 0x10000000 - -#define SDI_MASK0_MASK 0x1FFFFFFF - -/* SDI Data control register bits */ -#define SDI_DCTRL_DTEN 0x00000001 -#define SDI_DCTRL_DTDIR_IN 0x00000002 -#define SDI_DCTRL_DTMODE_STREAM 0x00000004 -#define SDI_DCTRL_DMAEN 0x00000008 -#define SDI_DCTRL_DBLKSIZE_MASK 0x000000F0 -#define SDI_DCTRL_RWSTART 0x00000100 -#define SDI_DCTRL_RWSTOP 0x00000200 -#define SDI_DCTRL_RWMOD 0x00000200 -#define SDI_DCTRL_SDIOEN 0x00000800 -#define SDI_DCTRL_DMAREQCTL 0x00001000 -#define SDI_DCTRL_DBOOTMODEEN 0x00002000 -#define SDI_DCTRL_BUSYMODE 0x00004000 -#define SDI_DCTRL_DDR_MODE 0x00008000 -#define SDI_DCTRL_DBLOCKSIZE_V2_MASK 0x7fff0000 -#define SDI_DCTRL_DBLOCKSIZE_V2_SHIFT 16 - -#define SDI_FIFO_BURST_SIZE 8 - -struct sdi_registers { - u32 power; /* 0x00*/ - u32 clock; /* 0x04*/ - u32 argument; /* 0x08*/ - u32 command; /* 0x0c*/ - u32 respcommand; /* 0x10*/ - u32 response0; /* 0x14*/ - u32 response1; /* 0x18*/ - u32 response2; /* 0x1c*/ - u32 response3; /* 0x20*/ - u32 datatimer; /* 0x24*/ - u32 datalength; /* 0x28*/ - u32 datactrl; /* 0x2c*/ - u32 datacount; /* 0x30*/ - u32 status; /* 0x34*/ - u32 status_clear; /* 0x38*/ - u32 mask0; /* 0x3c*/ - u32 mask1; /* 0x40*/ - u32 card_select; /* 0x44*/ - u32 fifo_count; /* 0x48*/ - u32 padding1[(0x80-0x4C)>>2]; - u32 fifo; /* 0x80*/ - u32 padding2[(0xFE0-0x84)>>2]; - u32 periph_id0; /* 0xFE0 mmc Peripheral Identifcation Register*/ - u32 periph_id1; /* 0xFE4*/ - u32 periph_id2; /* 0xFE8*/ - u32 periph_id3; /* 0xFEC*/ - u32 pcell_id0; /* 0xFF0*/ - u32 pcell_id1; /* 0xFF4*/ - u32 pcell_id2; /* 0xFF8*/ - u32 pcell_id3; /* 0xFFC*/ -}; - -struct pl180_mmc_host { - struct sdi_registers *base; - char name[32]; - unsigned int b_max; - unsigned int voltages; - unsigned int caps; - unsigned int clock_in; - unsigned int clock_min; - unsigned int clock_max; - unsigned int clkdiv_init; - unsigned int pwr_init; - int version2; - struct mmc_config cfg; -}; - -int arm_pl180_mmci_init(struct pl180_mmc_host *); - -#endif diff --git a/qemu/roms/u-boot/drivers/mmc/bcm2835_sdhci.c b/qemu/roms/u-boot/drivers/mmc/bcm2835_sdhci.c deleted file mode 100644 index 54cfabfb9..000000000 --- a/qemu/roms/u-boot/drivers/mmc/bcm2835_sdhci.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * This code was extracted from: - * git://github.com/gonzoua/u-boot-pi.git master - * and hence presumably (C) 2012 Oleksandr Tymoshenko - * - * Tweaks for U-Boot upstreaming - * (C) 2012 Stephen Warren - * - * Portions (e.g. read/write macros, concepts for back-to-back register write - * timing workarounds) obviously extracted from the Linux kernel at: - * https://github.com/raspberrypi/linux.git rpi-3.6.y - * - * The Linux kernel code has the following (c) and license, which is hence - * propagated to Oleksandr's tree and here: - * - * Support for SDHCI device on 2835 - * Based on sdhci-bcm2708.c (c) 2010 Broadcom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Supports: - * SDHCI platform device - Arasan SD controller in BCM2708 - * - * Inspired by sdhci-pci.c, by Pierre Ossman - */ - -#include <common.h> -#include <malloc.h> -#include <sdhci.h> -#include <asm/arch/timer.h> - -/* 400KHz is max freq for card ID etc. Use that as min */ -#define MIN_FREQ 400000 - -struct bcm2835_sdhci_host { - struct sdhci_host host; - uint twoticks_delay; - ulong last_write; -}; - -static inline struct bcm2835_sdhci_host *to_bcm(struct sdhci_host *host) -{ - return (struct bcm2835_sdhci_host *)host; -} - -static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val, - int reg) -{ - struct bcm2835_sdhci_host *bcm_host = to_bcm(host); - - /* - * The Arasan has a bugette whereby it may lose the content of - * successive writes to registers that are within two SD-card clock - * cycles of each other (a clock domain crossing problem). - * It seems, however, that the data register does not have this problem. - * (Which is just as well - otherwise we'd have to nobble the DMA engine - * too) - */ - while (get_timer_us(bcm_host->last_write) < bcm_host->twoticks_delay) - ; - - writel(val, host->ioaddr + reg); - bcm_host->last_write = get_timer_us(0); -} - -static inline u32 bcm2835_sdhci_raw_readl(struct sdhci_host *host, int reg) -{ - return readl(host->ioaddr + reg); -} - -static void bcm2835_sdhci_writel(struct sdhci_host *host, u32 val, int reg) -{ - bcm2835_sdhci_raw_writel(host, val, reg); -} - -static void bcm2835_sdhci_writew(struct sdhci_host *host, u16 val, int reg) -{ - static u32 shadow; - u32 oldval = (reg == SDHCI_COMMAND) ? shadow : - bcm2835_sdhci_raw_readl(host, reg & ~3); - u32 word_num = (reg >> 1) & 1; - u32 word_shift = word_num * 16; - u32 mask = 0xffff << word_shift; - u32 newval = (oldval & ~mask) | (val << word_shift); - - if (reg == SDHCI_TRANSFER_MODE) - shadow = newval; - else - bcm2835_sdhci_raw_writel(host, newval, reg & ~3); -} - -static void bcm2835_sdhci_writeb(struct sdhci_host *host, u8 val, int reg) -{ - u32 oldval = bcm2835_sdhci_raw_readl(host, reg & ~3); - u32 byte_num = reg & 3; - u32 byte_shift = byte_num * 8; - u32 mask = 0xff << byte_shift; - u32 newval = (oldval & ~mask) | (val << byte_shift); - - bcm2835_sdhci_raw_writel(host, newval, reg & ~3); -} - -static u32 bcm2835_sdhci_readl(struct sdhci_host *host, int reg) -{ - u32 val = bcm2835_sdhci_raw_readl(host, reg); - - return val; -} - -static u16 bcm2835_sdhci_readw(struct sdhci_host *host, int reg) -{ - u32 val = bcm2835_sdhci_raw_readl(host, (reg & ~3)); - u32 word_num = (reg >> 1) & 1; - u32 word_shift = word_num * 16; - u32 word = (val >> word_shift) & 0xffff; - - return word; -} - -static u8 bcm2835_sdhci_readb(struct sdhci_host *host, int reg) -{ - u32 val = bcm2835_sdhci_raw_readl(host, (reg & ~3)); - u32 byte_num = reg & 3; - u32 byte_shift = byte_num * 8; - u32 byte = (val >> byte_shift) & 0xff; - - return byte; -} - -static const struct sdhci_ops bcm2835_ops = { - .write_l = bcm2835_sdhci_writel, - .write_w = bcm2835_sdhci_writew, - .write_b = bcm2835_sdhci_writeb, - .read_l = bcm2835_sdhci_readl, - .read_w = bcm2835_sdhci_readw, - .read_b = bcm2835_sdhci_readb, -}; - -int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq) -{ - struct bcm2835_sdhci_host *bcm_host; - struct sdhci_host *host; - - bcm_host = malloc(sizeof(*bcm_host)); - if (!bcm_host) { - printf("sdhci_host malloc fail!\n"); - return 1; - } - - /* - * See the comments in bcm2835_sdhci_raw_writel(). - * - * This should probably be dynamically calculated based on the actual - * frequency. However, this is the longest we'll have to wait, and - * doesn't seem to slow access down too much, so the added complexity - * doesn't seem worth it for now. - * - * 1/MIN_FREQ is (max) time per tick of eMMC clock. - * 2/MIN_FREQ is time for two ticks. - * Multiply by 1000000 to get uS per two ticks. - * +1 for hack rounding. - */ - bcm_host->twoticks_delay = ((2 * 1000000) / MIN_FREQ) + 1; - bcm_host->last_write = 0; - - host = &bcm_host->host; - host->name = "bcm2835_sdhci"; - host->ioaddr = (void *)regbase; - host->quirks = SDHCI_QUIRK_BROKEN_VOLTAGE | SDHCI_QUIRK_BROKEN_R1B | - SDHCI_QUIRK_WAIT_SEND_CMD; - host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - host->ops = &bcm2835_ops; - - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - add_sdhci(host, emmc_freq, MIN_FREQ); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/bfin_sdh.c b/qemu/roms/u-boot/drivers/mmc/bfin_sdh.c deleted file mode 100644 index bcd6a3e52..000000000 --- a/qemu/roms/u-boot/drivers/mmc/bfin_sdh.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Driver for Blackfin on-chip SDH controller - * - * Copyright (c) 2008-2009 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include <common.h> -#include <malloc.h> -#include <part.h> -#include <mmc.h> - -#include <asm/io.h> -#include <asm/errno.h> -#include <asm/byteorder.h> -#include <asm/blackfin.h> -#include <asm/clock.h> -#include <asm/portmux.h> -#include <asm/mach-common/bits/sdh.h> -#include <asm/mach-common/bits/dma.h> - -#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) || defined(__ADSPBF60x__) -# define bfin_read_SDH_CLK_CTL bfin_read_RSI_CLK_CONTROL -# define bfin_write_SDH_CLK_CTL bfin_write_RSI_CLK_CONTROL -# define bfin_write_SDH_ARGUMENT bfin_write_RSI_ARGUMENT -# define bfin_write_SDH_COMMAND bfin_write_RSI_COMMAND -# define bfin_read_SDH_RESPONSE0 bfin_read_RSI_RESPONSE0 -# define bfin_read_SDH_RESPONSE1 bfin_read_RSI_RESPONSE1 -# define bfin_read_SDH_RESPONSE2 bfin_read_RSI_RESPONSE2 -# define bfin_read_SDH_RESPONSE3 bfin_read_RSI_RESPONSE3 -# define bfin_write_SDH_DATA_TIMER bfin_write_RSI_DATA_TIMER -# define bfin_write_SDH_DATA_LGTH bfin_write_RSI_DATA_LGTH -# define bfin_read_SDH_DATA_CTL bfin_read_RSI_DATA_CONTROL -# define bfin_write_SDH_DATA_CTL bfin_write_RSI_DATA_CONTROL -# define bfin_read_SDH_STATUS bfin_read_RSI_STATUS -# define bfin_write_SDH_STATUS_CLR bfin_write_RSI_STATUSCL -# define bfin_read_SDH_CFG bfin_read_RSI_CONFIG -# define bfin_write_SDH_CFG bfin_write_RSI_CONFIG -# if defined(__ADSPBF60x__) -# define bfin_read_SDH_BLK_SIZE bfin_read_RSI_BLKSZ -# define bfin_write_SDH_BLK_SIZE bfin_write_RSI_BLKSZ -# define bfin_write_DMA_START_ADDR bfin_write_DMA10_START_ADDR -# define bfin_write_DMA_X_COUNT bfin_write_DMA10_X_COUNT -# define bfin_write_DMA_X_MODIFY bfin_write_DMA10_X_MODIFY -# define bfin_write_DMA_CONFIG bfin_write_DMA10_CONFIG -# else -# define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CONTROL -# define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CONTROL -# define bfin_write_DMA_START_ADDR bfin_write_DMA4_START_ADDR -# define bfin_write_DMA_X_COUNT bfin_write_DMA4_X_COUNT -# define bfin_write_DMA_X_MODIFY bfin_write_DMA4_X_MODIFY -# define bfin_write_DMA_CONFIG bfin_write_DMA4_CONFIG -# endif -# define PORTMUX_PINS \ - { P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0 } -#elif defined(__ADSPBF54x__) -# define bfin_write_DMA_START_ADDR bfin_write_DMA22_START_ADDR -# define bfin_write_DMA_X_COUNT bfin_write_DMA22_X_COUNT -# define bfin_write_DMA_X_MODIFY bfin_write_DMA22_X_MODIFY -# define bfin_write_DMA_CONFIG bfin_write_DMA22_CONFIG -# define PORTMUX_PINS \ - { P_SD_D0, P_SD_D1, P_SD_D2, P_SD_D3, P_SD_CLK, P_SD_CMD, 0 } -#else -# error no support for this proc yet -#endif - -static int -sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) -{ - unsigned int status, timeout; - int cmd = mmc_cmd->cmdidx; - int flags = mmc_cmd->resp_type; - int arg = mmc_cmd->cmdarg; - int ret; - u16 sdh_cmd; - - sdh_cmd = cmd | CMD_E; - if (flags & MMC_RSP_PRESENT) - sdh_cmd |= CMD_RSP; - if (flags & MMC_RSP_136) - sdh_cmd |= CMD_L_RSP; -#ifdef RSI_BLKSZ - sdh_cmd |= CMD_DATA0_BUSY; -#endif - - bfin_write_SDH_ARGUMENT(arg); - bfin_write_SDH_COMMAND(sdh_cmd); - - /* wait for a while */ - timeout = 0; - do { - if (++timeout > 1000000) { - status = CMD_TIME_OUT; - break; - } - udelay(1); - status = bfin_read_SDH_STATUS(); - } while (!(status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | - CMD_CRC_FAIL))); - - if (flags & MMC_RSP_PRESENT) { - mmc_cmd->response[0] = bfin_read_SDH_RESPONSE0(); - if (flags & MMC_RSP_136) { - mmc_cmd->response[1] = bfin_read_SDH_RESPONSE1(); - mmc_cmd->response[2] = bfin_read_SDH_RESPONSE2(); - mmc_cmd->response[3] = bfin_read_SDH_RESPONSE3(); - } - } - - if (status & CMD_TIME_OUT) - ret = TIMEOUT; - else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC) - ret = COMM_ERR; - else - ret = 0; - - bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | - CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); -#ifdef RSI_BLKSZ - /* wait till card ready */ - while (!(bfin_read_RSI_ESTAT() & SD_CARD_READY)) - continue; - bfin_write_RSI_ESTAT(SD_CARD_READY); -#endif - - return ret; -} - -/* set data for single block transfer */ -static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data) -{ - u16 data_ctl = 0; - u16 dma_cfg = 0; - unsigned long data_size = data->blocksize * data->blocks; - - /* Don't support write yet. */ - if (data->flags & MMC_DATA_WRITE) - return UNUSABLE_ERR; -#ifndef RSI_BLKSZ - data_ctl |= ((ffs(data_size) - 1) << 4); -#else - bfin_write_SDH_BLK_SIZE(data_size); -#endif - data_ctl |= DTX_DIR; - bfin_write_SDH_DATA_CTL(data_ctl); - dma_cfg = WDSIZE_32 | PSIZE_32 | RESTART | WNR | DMAEN; - - bfin_write_SDH_DATA_TIMER(-1); - - blackfin_dcache_flush_invalidate_range(data->dest, - data->dest + data_size); - /* configure DMA */ - bfin_write_DMA_START_ADDR(data->dest); - bfin_write_DMA_X_COUNT(data_size / 4); - bfin_write_DMA_X_MODIFY(4); - bfin_write_DMA_CONFIG(dma_cfg); - bfin_write_SDH_DATA_LGTH(data_size); - /* kick off transfer */ - bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E); - - return 0; -} - - -static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - u32 status; - int ret = 0; - - if (data) { - ret = sdh_setup_data(mmc, data); - if (ret) - return ret; - } - - ret = sdh_send_cmd(mmc, cmd); - if (ret) { - bfin_write_SDH_COMMAND(0); - bfin_write_DMA_CONFIG(0); - bfin_write_SDH_DATA_CTL(0); - SSYNC(); - printf("sending CMD%d failed\n", cmd->cmdidx); - return ret; - } - - if (data) { - do { - udelay(1); - status = bfin_read_SDH_STATUS(); - } while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN))); - - if (status & DAT_TIME_OUT) { - bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT); - ret |= TIMEOUT; - } else if (status & (DAT_CRC_FAIL | RX_OVERRUN)) { - bfin_write_SDH_STATUS_CLR(DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT); - ret |= COMM_ERR; - } else - bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT); - - if (ret) { - printf("tranfering data failed\n"); - return ret; - } - } - return 0; -} - -static void sdh_set_clk(unsigned long clk) -{ - unsigned long sys_clk; - unsigned long clk_div; - u16 clk_ctl = 0; - - clk_ctl = bfin_read_SDH_CLK_CTL(); - if (clk) { - /* setting SD_CLK */ - sys_clk = get_sclk(); - bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); - if (sys_clk % (2 * clk) == 0) - clk_div = sys_clk / (2 * clk) - 1; - else - clk_div = sys_clk / (2 * clk); - - if (clk_div > 0xff) - clk_div = 0xff; - clk_ctl |= (clk_div & 0xff); - clk_ctl |= CLK_E; - bfin_write_SDH_CLK_CTL(clk_ctl); - } else - bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); -} - -static void bfin_sdh_set_ios(struct mmc *mmc) -{ - u16 cfg = 0; - u16 clk_ctl = 0; - - if (mmc->bus_width == 4) { - cfg = bfin_read_SDH_CFG(); -#ifndef RSI_BLKSZ - cfg &= ~PD_SDDAT3; -#endif - cfg |= PUP_SDDAT3; - bfin_write_SDH_CFG(cfg); - clk_ctl |= WIDE_BUS_4; - } - bfin_write_SDH_CLK_CTL(clk_ctl); - sdh_set_clk(mmc->clock); -} - -static int bfin_sdh_init(struct mmc *mmc) -{ - const unsigned short pins[] = PORTMUX_PINS; - int ret; - - /* Initialize sdh controller */ - ret = peripheral_request_list(pins, "bfin_sdh"); - if (ret < 0) - return ret; -#if defined(__ADSPBF54x__) - bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1); -#endif - bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN); - /* Disable card detect pin */ - bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60); -#ifndef RSI_BLKSZ - bfin_write_SDH_PWR_CTL(PWR_ON | ROD_CTL); -#else - bfin_write_SDH_CFG(bfin_read_SDH_CFG() | PWR_ON); -#endif - return 0; -} - -static const struct mmc_ops bfin_mmc_ops = { - .send_cmd = bfin_sdh_request, - .set_ios = bfin_sdh_set_ios, - .init = bfin_sdh_init, -}; - -static struct mmc_config bfin_mmc_cfg = { - .name = "Blackfin SDH", - .ops = &bfin_mmc_ops, - .host_caps = MMC_MODE_4BIT, - .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, -}; - -int bfin_mmc_init(bd_t *bis) -{ - struct mmc *mmc; - - bfin_mmc_cfg.f_max = get_sclk(); - bfin_mmc_cfg.f_min = bfin_mmc_cfg.f_max >> 9; - - mmc = mmc_create(&bfin_mmc_cfg, NULL); - if (mmc == NULL) - return -1; - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/davinci_mmc.c b/qemu/roms/u-boot/drivers/mmc/davinci_mmc.c deleted file mode 100644 index aae00e9da..000000000 --- a/qemu/roms/u-boot/drivers/mmc/davinci_mmc.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Davinci MMC Controller Driver - * - * Copyright (C) 2010 Texas Instruments Incorporated - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <command.h> -#include <mmc.h> -#include <part.h> -#include <malloc.h> -#include <asm/io.h> -#include <asm/arch/sdmmc_defs.h> - -#define DAVINCI_MAX_BLOCKS (32) -#define WATCHDOG_COUNT (100000) - -#define get_val(addr) REG(addr) -#define set_val(addr, val) REG(addr) = (val) -#define set_bit(addr, val) set_val((addr), (get_val(addr) | (val))) -#define clear_bit(addr, val) set_val((addr), (get_val(addr) & ~(val))) - -/* Set davinci clock prescalar value based on the required clock in HZ */ -static void dmmc_set_clock(struct mmc *mmc, uint clock) -{ - struct davinci_mmc *host = mmc->priv; - struct davinci_mmc_regs *regs = host->reg_base; - uint clkrt, sysclk2, act_clock; - - if (clock < mmc->cfg->f_min) - clock = mmc->cfg->f_min; - if (clock > mmc->cfg->f_max) - clock = mmc->cfg->f_max; - - set_val(®s->mmcclk, 0); - sysclk2 = host->input_clk; - clkrt = (sysclk2 / (2 * clock)) - 1; - - /* Calculate the actual clock for the divider used */ - act_clock = (sysclk2 / (2 * (clkrt + 1))); - - /* Adjust divider if actual clock exceeds the required clock */ - if (act_clock > clock) - clkrt++; - - /* check clock divider boundary and correct it */ - if (clkrt > 0xFF) - clkrt = 0xFF; - - set_val(®s->mmcclk, (clkrt | MMCCLK_CLKEN)); -} - -/* Status bit wait loop for MMCST1 */ -static int -dmmc_wait_fifo_status(volatile struct davinci_mmc_regs *regs, uint status) -{ - uint wdog = WATCHDOG_COUNT; - - while (--wdog && ((get_val(®s->mmcst1) & status) != status)) - udelay(10); - - if (!(get_val(®s->mmcctl) & MMCCTL_WIDTH_4_BIT)) - udelay(100); - - if (wdog == 0) - return COMM_ERR; - - return 0; -} - -/* Busy bit wait loop for MMCST1 */ -static int dmmc_busy_wait(volatile struct davinci_mmc_regs *regs) -{ - uint wdog = WATCHDOG_COUNT; - - while (--wdog && (get_val(®s->mmcst1) & MMCST1_BUSY)) - udelay(10); - - if (wdog == 0) - return COMM_ERR; - - return 0; -} - -/* Status bit wait loop for MMCST0 - Checks for error bits as well */ -static int dmmc_check_status(volatile struct davinci_mmc_regs *regs, - uint *cur_st, uint st_ready, uint st_error) -{ - uint wdog = WATCHDOG_COUNT; - uint mmcstatus = *cur_st; - - while (wdog--) { - if (mmcstatus & st_ready) { - *cur_st = mmcstatus; - mmcstatus = get_val(®s->mmcst1); - return 0; - } else if (mmcstatus & st_error) { - if (mmcstatus & MMCST0_TOUTRS) - return TIMEOUT; - printf("[ ST0 ERROR %x]\n", mmcstatus); - /* - * Ignore CRC errors as some MMC cards fail to - * initialize on DM365-EVM on the SD1 slot - */ - if (mmcstatus & MMCST0_CRCRS) - return 0; - return COMM_ERR; - } - udelay(10); - - mmcstatus = get_val(®s->mmcst0); - } - - printf("Status %x Timeout ST0:%x ST1:%x\n", st_ready, mmcstatus, - get_val(®s->mmcst1)); - return COMM_ERR; -} - -/* - * Sends a command out on the bus. Takes the mmc pointer, - * a command pointer, and an optional data pointer. - */ -static int -dmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) -{ - struct davinci_mmc *host = mmc->priv; - volatile struct davinci_mmc_regs *regs = host->reg_base; - uint mmcstatus, status_rdy, status_err; - uint i, cmddata, bytes_left = 0; - int fifo_words, fifo_bytes, err; - char *data_buf = NULL; - - /* Clear status registers */ - mmcstatus = get_val(®s->mmcst0); - fifo_words = (host->version == MMC_CTLR_VERSION_2) ? 16 : 8; - fifo_bytes = fifo_words << 2; - - /* Wait for any previous busy signal to be cleared */ - dmmc_busy_wait(regs); - - cmddata = cmd->cmdidx; - cmddata |= MMCCMD_PPLEN; - - /* Send init clock for CMD0 */ - if (cmd->cmdidx == MMC_CMD_GO_IDLE_STATE) - cmddata |= MMCCMD_INITCK; - - switch (cmd->resp_type) { - case MMC_RSP_R1b: - cmddata |= MMCCMD_BSYEXP; - /* Fall-through */ - case MMC_RSP_R1: /* R1, R1b, R5, R6, R7 */ - cmddata |= MMCCMD_RSPFMT_R1567; - break; - case MMC_RSP_R2: - cmddata |= MMCCMD_RSPFMT_R2; - break; - case MMC_RSP_R3: /* R3, R4 */ - cmddata |= MMCCMD_RSPFMT_R3; - break; - } - - set_val(®s->mmcim, 0); - - if (data) { - /* clear previous data transfer if any and set new one */ - bytes_left = (data->blocksize * data->blocks); - - /* Reset FIFO - Always use 32 byte fifo threshold */ - set_val(®s->mmcfifoctl, - (MMCFIFOCTL_FIFOLEV | MMCFIFOCTL_FIFORST)); - - if (host->version == MMC_CTLR_VERSION_2) - cmddata |= MMCCMD_DMATRIG; - - cmddata |= MMCCMD_WDATX; - if (data->flags == MMC_DATA_READ) { - set_val(®s->mmcfifoctl, MMCFIFOCTL_FIFOLEV); - } else if (data->flags == MMC_DATA_WRITE) { - set_val(®s->mmcfifoctl, - (MMCFIFOCTL_FIFOLEV | - MMCFIFOCTL_FIFODIR)); - cmddata |= MMCCMD_DTRW; - } - - set_val(®s->mmctod, 0xFFFF); - set_val(®s->mmcnblk, (data->blocks & MMCNBLK_NBLK_MASK)); - set_val(®s->mmcblen, (data->blocksize & MMCBLEN_BLEN_MASK)); - - if (data->flags == MMC_DATA_WRITE) { - uint val; - data_buf = (char *)data->src; - /* For write, fill FIFO with data before issue of CMD */ - for (i = 0; (i < fifo_words) && bytes_left; i++) { - memcpy((char *)&val, data_buf, 4); - set_val(®s->mmcdxr, val); - data_buf += 4; - bytes_left -= 4; - } - } - } else { - set_val(®s->mmcblen, 0); - set_val(®s->mmcnblk, 0); - } - - set_val(®s->mmctor, 0x1FFF); - - /* Send the command */ - set_val(®s->mmcarghl, cmd->cmdarg); - set_val(®s->mmccmd, cmddata); - - status_rdy = MMCST0_RSPDNE; - status_err = (MMCST0_TOUTRS | MMCST0_TOUTRD | - MMCST0_CRCWR | MMCST0_CRCRD); - if (cmd->resp_type & MMC_RSP_CRC) - status_err |= MMCST0_CRCRS; - - mmcstatus = get_val(®s->mmcst0); - err = dmmc_check_status(regs, &mmcstatus, status_rdy, status_err); - if (err) - return err; - - /* For R1b wait for busy done */ - if (cmd->resp_type == MMC_RSP_R1b) - dmmc_busy_wait(regs); - - /* Collect response from controller for specific commands */ - if (mmcstatus & MMCST0_RSPDNE) { - /* Copy the response to the response buffer */ - if (cmd->resp_type & MMC_RSP_136) { - cmd->response[0] = get_val(®s->mmcrsp67); - cmd->response[1] = get_val(®s->mmcrsp45); - cmd->response[2] = get_val(®s->mmcrsp23); - cmd->response[3] = get_val(®s->mmcrsp01); - } else if (cmd->resp_type & MMC_RSP_PRESENT) { - cmd->response[0] = get_val(®s->mmcrsp67); - } - } - - if (data == NULL) - return 0; - - if (data->flags == MMC_DATA_READ) { - /* check for DATDNE along with DRRDY as the controller might - * set the DATDNE without DRRDY for smaller transfers with - * less than FIFO threshold bytes - */ - status_rdy = MMCST0_DRRDY | MMCST0_DATDNE; - status_err = MMCST0_TOUTRD | MMCST0_CRCRD; - data_buf = data->dest; - } else { - status_rdy = MMCST0_DXRDY | MMCST0_DATDNE; - status_err = MMCST0_CRCWR; - } - - /* Wait until all of the blocks are transferred */ - while (bytes_left) { - err = dmmc_check_status(regs, &mmcstatus, status_rdy, - status_err); - if (err) - return err; - - if (data->flags == MMC_DATA_READ) { - /* - * MMC controller sets the Data receive ready bit - * (DRRDY) in MMCST0 even before the entire FIFO is - * full. This results in erratic behavior if we start - * reading the FIFO soon after DRRDY. Wait for the - * FIFO full bit in MMCST1 for proper FIFO clearing. - */ - if (bytes_left > fifo_bytes) - dmmc_wait_fifo_status(regs, 0x4a); - else if (bytes_left == fifo_bytes) { - dmmc_wait_fifo_status(regs, 0x40); - if (cmd->cmdidx == MMC_CMD_SEND_EXT_CSD) - udelay(600); - } - - for (i = 0; bytes_left && (i < fifo_words); i++) { - cmddata = get_val(®s->mmcdrr); - memcpy(data_buf, (char *)&cmddata, 4); - data_buf += 4; - bytes_left -= 4; - } - } else { - /* - * MMC controller sets the Data transmit ready bit - * (DXRDY) in MMCST0 even before the entire FIFO is - * empty. This results in erratic behavior if we start - * writing the FIFO soon after DXRDY. Wait for the - * FIFO empty bit in MMCST1 for proper FIFO clearing. - */ - dmmc_wait_fifo_status(regs, MMCST1_FIFOEMP); - for (i = 0; bytes_left && (i < fifo_words); i++) { - memcpy((char *)&cmddata, data_buf, 4); - set_val(®s->mmcdxr, cmddata); - data_buf += 4; - bytes_left -= 4; - } - dmmc_busy_wait(regs); - } - } - - err = dmmc_check_status(regs, &mmcstatus, MMCST0_DATDNE, status_err); - if (err) - return err; - - return 0; -} - -/* Initialize Davinci MMC controller */ -static int dmmc_init(struct mmc *mmc) -{ - struct davinci_mmc *host = mmc->priv; - struct davinci_mmc_regs *regs = host->reg_base; - - /* Clear status registers explicitly - soft reset doesn't clear it - * If Uboot is invoked from UBL with SDMMC Support, the status - * registers can have uncleared bits - */ - get_val(®s->mmcst0); - get_val(®s->mmcst1); - - /* Hold software reset */ - set_bit(®s->mmcctl, MMCCTL_DATRST); - set_bit(®s->mmcctl, MMCCTL_CMDRST); - udelay(10); - - set_val(®s->mmcclk, 0x0); - set_val(®s->mmctor, 0x1FFF); - set_val(®s->mmctod, 0xFFFF); - - /* Clear software reset */ - clear_bit(®s->mmcctl, MMCCTL_DATRST); - clear_bit(®s->mmcctl, MMCCTL_CMDRST); - - udelay(10); - - /* Reset FIFO - Always use the maximum fifo threshold */ - set_val(®s->mmcfifoctl, (MMCFIFOCTL_FIFOLEV | MMCFIFOCTL_FIFORST)); - set_val(®s->mmcfifoctl, MMCFIFOCTL_FIFOLEV); - - return 0; -} - -/* Set buswidth or clock as indicated by the GENERIC_MMC framework */ -static void dmmc_set_ios(struct mmc *mmc) -{ - struct davinci_mmc *host = mmc->priv; - struct davinci_mmc_regs *regs = host->reg_base; - - /* Set the bus width */ - if (mmc->bus_width == 4) - set_bit(®s->mmcctl, MMCCTL_WIDTH_4_BIT); - else - clear_bit(®s->mmcctl, MMCCTL_WIDTH_4_BIT); - - /* Set clock speed */ - if (mmc->clock) - dmmc_set_clock(mmc, mmc->clock); -} - -static const struct mmc_ops dmmc_ops = { - .send_cmd = dmmc_send_cmd, - .set_ios = dmmc_set_ios, - .init = dmmc_init, -}; - -/* Called from board_mmc_init during startup. Can be called multiple times - * depending on the number of slots available on board and controller - */ -int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host) -{ - host->cfg.name = "davinci"; - host->cfg.ops = &dmmc_ops; - host->cfg.f_min = 200000; - host->cfg.f_max = 25000000; - host->cfg.voltages = host->voltages; - host->cfg.host_caps = host->host_caps; - - host->cfg.b_max = DAVINCI_MAX_BLOCKS; - - mmc_create(&host->cfg, host); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/dw_mmc.c b/qemu/roms/u-boot/drivers/mmc/dw_mmc.c deleted file mode 100644 index eb4e2be51..000000000 --- a/qemu/roms/u-boot/drivers/mmc/dw_mmc.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * (C) Copyright 2012 SAMSUNG Electronics - * Jaehoon Chung <jh80.chung@samsung.com> - * Rajeshawari Shinde <rajeshwari.s@samsung.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <bouncebuf.h> -#include <common.h> -#include <malloc.h> -#include <mmc.h> -#include <dwmmc.h> -#include <asm-generic/errno.h> - -#define PAGE_SIZE 4096 - -static int dwmci_wait_reset(struct dwmci_host *host, u32 value) -{ - unsigned long timeout = 1000; - u32 ctrl; - - dwmci_writel(host, DWMCI_CTRL, value); - - while (timeout--) { - ctrl = dwmci_readl(host, DWMCI_CTRL); - if (!(ctrl & DWMCI_RESET_ALL)) - return 1; - } - return 0; -} - -static void dwmci_set_idma_desc(struct dwmci_idmac *idmac, - u32 desc0, u32 desc1, u32 desc2) -{ - struct dwmci_idmac *desc = idmac; - - desc->flags = desc0; - desc->cnt = desc1; - desc->addr = desc2; - desc->next_addr = (unsigned int)desc + sizeof(struct dwmci_idmac); -} - -static void dwmci_prepare_data(struct dwmci_host *host, - struct mmc_data *data, - struct dwmci_idmac *cur_idmac, - void *bounce_buffer) -{ - unsigned long ctrl; - unsigned int i = 0, flags, cnt, blk_cnt; - ulong data_start, data_end; - - - blk_cnt = data->blocks; - - dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET); - - data_start = (ulong)cur_idmac; - dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac); - - do { - flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ; - flags |= (i == 0) ? DWMCI_IDMAC_FS : 0; - if (blk_cnt <= 8) { - flags |= DWMCI_IDMAC_LD; - cnt = data->blocksize * blk_cnt; - } else - cnt = data->blocksize * 8; - - dwmci_set_idma_desc(cur_idmac, flags, cnt, - (u32)bounce_buffer + (i * PAGE_SIZE)); - - if (blk_cnt <= 8) - break; - blk_cnt -= 8; - cur_idmac++; - i++; - } while(1); - - data_end = (ulong)cur_idmac; - flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN); - - ctrl = dwmci_readl(host, DWMCI_CTRL); - ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN; - dwmci_writel(host, DWMCI_CTRL, ctrl); - - ctrl = dwmci_readl(host, DWMCI_BMOD); - ctrl |= DWMCI_BMOD_IDMAC_FB | DWMCI_BMOD_IDMAC_EN; - dwmci_writel(host, DWMCI_BMOD, ctrl); - - dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize); - dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks); -} - -static int dwmci_set_transfer_mode(struct dwmci_host *host, - struct mmc_data *data) -{ - unsigned long mode; - - mode = DWMCI_CMD_DATA_EXP; - if (data->flags & MMC_DATA_WRITE) - mode |= DWMCI_CMD_RW; - - return mode; -} - -static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct dwmci_host *host = mmc->priv; - ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, - data ? DIV_ROUND_UP(data->blocks, 8) : 0); - int flags = 0, i; - unsigned int timeout = 100000; - u32 retry = 10000; - u32 mask, ctrl; - ulong start = get_timer(0); - struct bounce_buffer bbstate; - - while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { - if (get_timer(start) > timeout) { - printf("Timeout on data busy\n"); - return TIMEOUT; - } - } - - dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL); - - if (data) { - if (data->flags == MMC_DATA_READ) { - bounce_buffer_start(&bbstate, (void*)data->dest, - data->blocksize * - data->blocks, GEN_BB_WRITE); - } else { - bounce_buffer_start(&bbstate, (void*)data->src, - data->blocksize * - data->blocks, GEN_BB_READ); - } - dwmci_prepare_data(host, data, cur_idmac, - bbstate.bounce_buffer); - } - - dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg); - - if (data) - flags = dwmci_set_transfer_mode(host, data); - - if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) - return -1; - - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) - flags |= DWMCI_CMD_ABORT_STOP; - else - flags |= DWMCI_CMD_PRV_DAT_WAIT; - - if (cmd->resp_type & MMC_RSP_PRESENT) { - flags |= DWMCI_CMD_RESP_EXP; - if (cmd->resp_type & MMC_RSP_136) - flags |= DWMCI_CMD_RESP_LENGTH; - } - - if (cmd->resp_type & MMC_RSP_CRC) - flags |= DWMCI_CMD_CHECK_CRC; - - flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG); - - debug("Sending CMD%d\n",cmd->cmdidx); - - dwmci_writel(host, DWMCI_CMD, flags); - - for (i = 0; i < retry; i++) { - mask = dwmci_readl(host, DWMCI_RINTSTS); - if (mask & DWMCI_INTMSK_CDONE) { - if (!data) - dwmci_writel(host, DWMCI_RINTSTS, mask); - break; - } - } - - if (i == retry) - return TIMEOUT; - - if (mask & DWMCI_INTMSK_RTO) { - debug("Response Timeout..\n"); - return TIMEOUT; - } else if (mask & DWMCI_INTMSK_RE) { - debug("Response Error..\n"); - return -1; - } - - - if (cmd->resp_type & MMC_RSP_PRESENT) { - if (cmd->resp_type & MMC_RSP_136) { - cmd->response[0] = dwmci_readl(host, DWMCI_RESP3); - cmd->response[1] = dwmci_readl(host, DWMCI_RESP2); - cmd->response[2] = dwmci_readl(host, DWMCI_RESP1); - cmd->response[3] = dwmci_readl(host, DWMCI_RESP0); - } else { - cmd->response[0] = dwmci_readl(host, DWMCI_RESP0); - } - } - - if (data) { - do { - mask = dwmci_readl(host, DWMCI_RINTSTS); - if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) { - debug("DATA ERROR!\n"); - return -1; - } - } while (!(mask & DWMCI_INTMSK_DTO)); - - dwmci_writel(host, DWMCI_RINTSTS, mask); - - ctrl = dwmci_readl(host, DWMCI_CTRL); - ctrl &= ~(DWMCI_DMA_EN); - dwmci_writel(host, DWMCI_CTRL, ctrl); - - bounce_buffer_stop(&bbstate); - } - - udelay(100); - - return 0; -} - -static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) -{ - u32 div, status; - int timeout = 10000; - unsigned long sclk; - - if ((freq == host->clock) || (freq == 0)) - return 0; - /* - * If host->get_mmc_clk didn't define, - * then assume that host->bus_hz is source clock value. - * host->bus_hz should be set from user. - */ - if (host->get_mmc_clk) - sclk = host->get_mmc_clk(host); - else if (host->bus_hz) - sclk = host->bus_hz; - else { - printf("Didn't get source clock value..\n"); - return -EINVAL; - } - - div = DIV_ROUND_UP(sclk, 2 * freq); - - dwmci_writel(host, DWMCI_CLKENA, 0); - dwmci_writel(host, DWMCI_CLKSRC, 0); - - dwmci_writel(host, DWMCI_CLKDIV, div); - dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT | - DWMCI_CMD_UPD_CLK | DWMCI_CMD_START); - - do { - status = dwmci_readl(host, DWMCI_CMD); - if (timeout-- < 0) { - printf("TIMEOUT error!!\n"); - return -ETIMEDOUT; - } - } while (status & DWMCI_CMD_START); - - dwmci_writel(host, DWMCI_CLKENA, DWMCI_CLKEN_ENABLE | - DWMCI_CLKEN_LOW_PWR); - - dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT | - DWMCI_CMD_UPD_CLK | DWMCI_CMD_START); - - timeout = 10000; - do { - status = dwmci_readl(host, DWMCI_CMD); - if (timeout-- < 0) { - printf("TIMEOUT error!!\n"); - return -ETIMEDOUT; - } - } while (status & DWMCI_CMD_START); - - host->clock = freq; - - return 0; -} - -static void dwmci_set_ios(struct mmc *mmc) -{ - struct dwmci_host *host = mmc->priv; - u32 ctype; - - debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock); - - dwmci_setup_bus(host, mmc->clock); - switch (mmc->bus_width) { - case 8: - ctype = DWMCI_CTYPE_8BIT; - break; - case 4: - ctype = DWMCI_CTYPE_4BIT; - break; - default: - ctype = DWMCI_CTYPE_1BIT; - break; - } - - dwmci_writel(host, DWMCI_CTYPE, ctype); - - if (host->clksel) - host->clksel(host); -} - -static int dwmci_init(struct mmc *mmc) -{ - struct dwmci_host *host = mmc->priv; - - if (host->board_init) - host->board_init(host); - - dwmci_writel(host, DWMCI_PWREN, 1); - - if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) { - debug("%s[%d] Fail-reset!!\n",__func__,__LINE__); - return -1; - } - - /* Enumerate at 400KHz */ - dwmci_setup_bus(host, mmc->cfg->f_min); - - dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF); - dwmci_writel(host, DWMCI_INTMASK, 0); - - dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF); - - dwmci_writel(host, DWMCI_IDINTEN, 0); - dwmci_writel(host, DWMCI_BMOD, 1); - - if (host->fifoth_val) { - dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val); - } - - dwmci_writel(host, DWMCI_CLKENA, 0); - dwmci_writel(host, DWMCI_CLKSRC, 0); - - return 0; -} - -static const struct mmc_ops dwmci_ops = { - .send_cmd = dwmci_send_cmd, - .set_ios = dwmci_set_ios, - .init = dwmci_init, -}; - -int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk) -{ - host->cfg.name = host->name; - host->cfg.ops = &dwmci_ops; - host->cfg.f_min = min_clk; - host->cfg.f_max = max_clk; - - host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - - host->cfg.host_caps = host->caps; - - if (host->buswidth == 8) { - host->cfg.host_caps |= MMC_MODE_8BIT; - host->cfg.host_caps &= ~MMC_MODE_4BIT; - } else { - host->cfg.host_caps |= MMC_MODE_4BIT; - host->cfg.host_caps &= ~MMC_MODE_8BIT; - } - host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HC; - - host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - host->mmc = mmc_create(&host->cfg, host); - if (host->mmc == NULL) - return -1; - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/exynos_dw_mmc.c b/qemu/roms/u-boot/drivers/mmc/exynos_dw_mmc.c deleted file mode 100644 index de8cdcc42..000000000 --- a/qemu/roms/u-boot/drivers/mmc/exynos_dw_mmc.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * (C) Copyright 2012 SAMSUNG Electronics - * Jaehoon Chung <jh80.chung@samsung.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <dwmmc.h> -#include <fdtdec.h> -#include <libfdt.h> -#include <malloc.h> -#include <asm/arch/dwmmc.h> -#include <asm/arch/clk.h> -#include <asm/arch/pinmux.h> - -#define DWMMC_MAX_CH_NUM 4 -#define DWMMC_MAX_FREQ 52000000 -#define DWMMC_MIN_FREQ 400000 -#define DWMMC_MMC0_CLKSEL_VAL 0x03030001 -#define DWMMC_MMC2_CLKSEL_VAL 0x03020001 - -/* - * Function used as callback function to initialise the - * CLKSEL register for every mmc channel. - */ -static void exynos_dwmci_clksel(struct dwmci_host *host) -{ - dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val); -} - -unsigned int exynos_dwmci_get_clk(struct dwmci_host *host) -{ - unsigned long sclk; - int8_t clk_div; - - /* - * Since SDCLKIN is divided inside controller by the DIVRATIO - * value set in the CLKSEL register, we need to use the same output - * clock value to calculate the CLKDIV value. - * as per user manual:cclk_in = SDCLKIN / (DIVRATIO + 1) - */ - clk_div = ((dwmci_readl(host, DWMCI_CLKSEL) >> DWMCI_DIVRATIO_BIT) - & DWMCI_DIVRATIO_MASK) + 1; - sclk = get_mmc_clk(host->dev_index); - - return sclk / clk_div; -} - -static void exynos_dwmci_board_init(struct dwmci_host *host) -{ - if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) { - dwmci_writel(host, EMMCP_MPSBEGIN0, 0); - dwmci_writel(host, EMMCP_SEND0, 0); - dwmci_writel(host, EMMCP_CTRL0, - MPSCTRL_SECURE_READ_BIT | - MPSCTRL_SECURE_WRITE_BIT | - MPSCTRL_NON_SECURE_READ_BIT | - MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID); - } -} - -/* - * 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'. - * clksel - value to be written into CLKSEL register in case of FDT. - * NULL in case od non-FDT. - */ -int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) -{ - struct dwmci_host *host = NULL; - unsigned int div; - unsigned long freq, sclk; - host = malloc(sizeof(struct dwmci_host)); - if (!host) { - printf("dwmci_host malloc fail!\n"); - return 1; - } - /* request mmc clock vlaue of 52MHz. */ - freq = 52000000; - sclk = get_mmc_clk(index); - div = DIV_ROUND_UP(sclk, freq); - /* set the clock divisor for mmc */ - set_mmc_clk(index, div); - - host->name = "EXYNOS DWMMC"; - host->ioaddr = (void *)regbase; - host->buswidth = bus_width; -#ifdef CONFIG_EXYNOS5420 - host->quirks = DWMCI_QUIRK_DISABLE_SMU; -#endif - host->board_init = exynos_dwmci_board_init; - - if (clksel) { - host->clksel_val = clksel; - } else { - if (0 == index) - host->clksel_val = DWMMC_MMC0_CLKSEL_VAL; - if (2 == index) - host->clksel_val = DWMMC_MMC2_CLKSEL_VAL; - } - - host->clksel = exynos_dwmci_clksel; - host->dev_index = index; - host->get_mmc_clk = exynos_dwmci_get_clk; - /* Add the mmc channel to be registered with mmc core */ - if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) { - debug("dwmmc%d registration failed\n", index); - return -1; - } - return 0; -} - -#ifdef CONFIG_OF_CONTROL -int exynos_dwmmc_init(const void *blob) -{ - int index, bus_width; - int node_list[DWMMC_MAX_CH_NUM]; - int err = 0, dev_id, flag, count, i; - u32 clksel_val, base, timing[3]; - - count = fdtdec_find_aliases_for_id(blob, "mmc", - COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list, - DWMMC_MAX_CH_NUM); - - for (i = 0; i < count; i++) { - int node = node_list[i]; - - if (node <= 0) - continue; - - /* Extract device id for each mmc channel */ - dev_id = pinmux_decode_periph_id(blob, node); - - /* Get the bus width from the device node */ - bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0); - if (bus_width <= 0) { - debug("DWMMC: Can't get bus-width\n"); - return -1; - } - if (8 == bus_width) - flag = PINMUX_FLAG_8BIT_MODE; - else - flag = PINMUX_FLAG_NONE; - - /* config pinmux for each mmc channel */ - err = exynos_pinmux_config(dev_id, flag); - if (err) { - debug("DWMMC not configured\n"); - return err; - } - - index = dev_id - PERIPH_ID_SDMMC0; - - /* Get the base address from the device node */ - base = fdtdec_get_addr(blob, node, "reg"); - if (!base) { - debug("DWMMC: Can't get base address\n"); - return -1; - } - /* Extract the timing info from the node */ - err = fdtdec_get_int_array(blob, node, "samsung,timing", - timing, 3); - if (err) { - debug("Can't get sdr-timings for divider\n"); - return -1; - } - - clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) | - DWMCI_SET_DRV_CLK(timing[1]) | - DWMCI_SET_DIV_RATIO(timing[2])); - /* Initialise each mmc channel */ - err = exynos_dwmci_add_port(index, base, bus_width, clksel_val); - if (err) - debug("dwmmc Channel-%d init failed\n", index); - } - return 0; -} -#endif diff --git a/qemu/roms/u-boot/drivers/mmc/fsl_esdhc.c b/qemu/roms/u-boot/drivers/mmc/fsl_esdhc.c deleted file mode 100644 index 50cba64d9..000000000 --- a/qemu/roms/u-boot/drivers/mmc/fsl_esdhc.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc - * Andy Fleming - * - * Based vaguely on the pxa mmc code: - * (C) Copyright 2003 - * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <command.h> -#include <hwconfig.h> -#include <mmc.h> -#include <part.h> -#include <malloc.h> -#include <mmc.h> -#include <fsl_esdhc.h> -#include <fdt_support.h> -#include <asm/io.h> - -DECLARE_GLOBAL_DATA_PTR; - -struct fsl_esdhc { - uint dsaddr; /* SDMA system address register */ - uint blkattr; /* Block attributes register */ - uint cmdarg; /* Command argument register */ - uint xfertyp; /* Transfer type register */ - uint cmdrsp0; /* Command response 0 register */ - uint cmdrsp1; /* Command response 1 register */ - uint cmdrsp2; /* Command response 2 register */ - uint cmdrsp3; /* Command response 3 register */ - uint datport; /* Buffer data port register */ - uint prsstat; /* Present state register */ - uint proctl; /* Protocol control register */ - uint sysctl; /* System Control Register */ - uint irqstat; /* Interrupt status register */ - uint irqstaten; /* Interrupt status enable register */ - uint irqsigen; /* Interrupt signal enable register */ - uint autoc12err; /* Auto CMD error status register */ - uint hostcapblt; /* Host controller capabilities register */ - uint wml; /* Watermark level register */ - uint mixctrl; /* For USDHC */ - char reserved1[4]; /* reserved */ - uint fevt; /* Force event register */ - uint admaes; /* ADMA error status register */ - uint adsaddr; /* ADMA system address register */ - char reserved2[160]; /* reserved */ - uint hostver; /* Host controller version register */ - char reserved3[4]; /* reserved */ - uint dmaerraddr; /* DMA error address register */ - char reserved4[4]; /* reserved */ - uint dmaerrattr; /* DMA error attribute register */ - char reserved5[4]; /* reserved */ - uint hostcapblt2; /* Host controller capabilities register 2 */ - char reserved6[8]; /* reserved */ - uint tcr; /* Tuning control register */ - char reserved7[28]; /* reserved */ - uint sddirctl; /* SD direction control register */ - char reserved8[712]; /* reserved */ - uint scr; /* eSDHC control register */ -}; - -/* Return the XFERTYP flags for a given command and data packet */ -static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) -{ - uint xfertyp = 0; - - if (data) { - xfertyp |= XFERTYP_DPSEL; -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - xfertyp |= XFERTYP_DMAEN; -#endif - if (data->blocks > 1) { - xfertyp |= XFERTYP_MSBSEL; - xfertyp |= XFERTYP_BCEN; -#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 - xfertyp |= XFERTYP_AC12EN; -#endif - } - - if (data->flags & MMC_DATA_READ) - xfertyp |= XFERTYP_DTDSEL; - } - - if (cmd->resp_type & MMC_RSP_CRC) - xfertyp |= XFERTYP_CCCEN; - if (cmd->resp_type & MMC_RSP_OPCODE) - xfertyp |= XFERTYP_CICEN; - if (cmd->resp_type & MMC_RSP_136) - xfertyp |= XFERTYP_RSPTYP_136; - else if (cmd->resp_type & MMC_RSP_BUSY) - xfertyp |= XFERTYP_RSPTYP_48_BUSY; - else if (cmd->resp_type & MMC_RSP_PRESENT) - xfertyp |= XFERTYP_RSPTYP_48; - -#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) - xfertyp |= XFERTYP_CMDTYP_ABORT; -#endif - return XFERTYP_CMD(cmd->cmdidx) | xfertyp; -} - -#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO -/* - * PIO Read/Write Mode reduce the performace as DMA is not used in this mode. - */ -static void -esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data) -{ - struct fsl_esdhc_cfg *cfg = mmc->priv; - struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; - uint blocks; - char *buffer; - uint databuf; - uint size; - uint irqstat; - uint timeout; - - if (data->flags & MMC_DATA_READ) { - blocks = data->blocks; - buffer = data->dest; - while (blocks) { - timeout = PIO_TIMEOUT; - size = data->blocksize; - irqstat = esdhc_read32(®s->irqstat); - while (!(esdhc_read32(®s->prsstat) & PRSSTAT_BREN) - && --timeout); - if (timeout <= 0) { - printf("\nData Read Failed in PIO Mode."); - return; - } - while (size && (!(irqstat & IRQSTAT_TC))) { - udelay(100); /* Wait before last byte transfer complete */ - irqstat = esdhc_read32(®s->irqstat); - databuf = in_le32(®s->datport); - *((uint *)buffer) = databuf; - buffer += 4; - size -= 4; - } - blocks--; - } - } else { - blocks = data->blocks; - buffer = (char *)data->src; - while (blocks) { - timeout = PIO_TIMEOUT; - size = data->blocksize; - irqstat = esdhc_read32(®s->irqstat); - while (!(esdhc_read32(®s->prsstat) & PRSSTAT_BWEN) - && --timeout); - if (timeout <= 0) { - printf("\nData Write Failed in PIO Mode."); - return; - } - while (size && (!(irqstat & IRQSTAT_TC))) { - udelay(100); /* Wait before last byte transfer complete */ - databuf = *((uint *)buffer); - buffer += 4; - size -= 4; - irqstat = esdhc_read32(®s->irqstat); - out_le32(®s->datport, databuf); - } - blocks--; - } - } -} -#endif - -static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) -{ - int timeout; - struct fsl_esdhc_cfg *cfg = mmc->priv; - struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - uint wml_value; - - wml_value = data->blocksize/4; - - if (data->flags & MMC_DATA_READ) { - if (wml_value > WML_RD_WML_MAX) - wml_value = WML_RD_WML_MAX_VAL; - - esdhc_clrsetbits32(®s->wml, WML_RD_WML_MASK, wml_value); - esdhc_write32(®s->dsaddr, (u32)data->dest); - } else { - flush_dcache_range((ulong)data->src, - (ulong)data->src+data->blocks - *data->blocksize); - - if (wml_value > WML_WR_WML_MAX) - wml_value = WML_WR_WML_MAX_VAL; - if ((esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL) == 0) { - printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); - return TIMEOUT; - } - - esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK, - wml_value << 16); - esdhc_write32(®s->dsaddr, (u32)data->src); - } -#else /* CONFIG_SYS_FSL_ESDHC_USE_PIO */ - if (!(data->flags & MMC_DATA_READ)) { - if ((esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL) == 0) { - printf("\nThe SD card is locked. " - "Can not write to a locked card.\n\n"); - return TIMEOUT; - } - esdhc_write32(®s->dsaddr, (u32)data->src); - } else - esdhc_write32(®s->dsaddr, (u32)data->dest); -#endif /* CONFIG_SYS_FSL_ESDHC_USE_PIO */ - - esdhc_write32(®s->blkattr, data->blocks << 16 | data->blocksize); - - /* Calculate the timeout period for data transactions */ - /* - * 1)Timeout period = (2^(timeout+13)) SD Clock cycles - * 2)Timeout period should be minimum 0.250sec as per SD Card spec - * So, Number of SD Clock cycles for 0.25sec should be minimum - * (SD Clock/sec * 0.25 sec) SD Clock cycles - * = (mmc->clock * 1/4) SD Clock cycles - * As 1) >= 2) - * => (2^(timeout+13)) >= mmc->clock * 1/4 - * Taking log2 both the sides - * => timeout + 13 >= log2(mmc->clock/4) - * Rounding up to next power of 2 - * => timeout + 13 = log2(mmc->clock/4) + 1 - * => timeout + 13 = fls(mmc->clock/4) - */ - timeout = fls(mmc->clock/4); - timeout -= 13; - - if (timeout > 14) - timeout = 14; - - if (timeout < 0) - timeout = 0; - -#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC_A001 - if ((timeout == 4) || (timeout == 8) || (timeout == 12)) - timeout++; -#endif - -#ifdef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE - timeout = 0xE; -#endif - esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16); - - return 0; -} - -static void check_and_invalidate_dcache_range - (struct mmc_cmd *cmd, - struct mmc_data *data) { - unsigned start = (unsigned)data->dest ; - unsigned size = roundup(ARCH_DMA_MINALIGN, - data->blocks*data->blocksize); - unsigned end = start+size ; - invalidate_dcache_range(start, end); -} -/* - * Sends a command out on the bus. Takes the mmc pointer, - * a command pointer, and an optional data pointer. - */ -static int -esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) -{ - int err = 0; - uint xfertyp; - uint irqstat; - struct fsl_esdhc_cfg *cfg = mmc->priv; - volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; - -#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) - return 0; -#endif - - esdhc_write32(®s->irqstat, -1); - - sync(); - - /* Wait for the bus to be idle */ - while ((esdhc_read32(®s->prsstat) & PRSSTAT_CICHB) || - (esdhc_read32(®s->prsstat) & PRSSTAT_CIDHB)) - ; - - while (esdhc_read32(®s->prsstat) & PRSSTAT_DLA) - ; - - /* Wait at least 8 SD clock cycles before the next command */ - /* - * Note: This is way more than 8 cycles, but 1ms seems to - * resolve timing issues with some cards - */ - udelay(1000); - - /* Set up for a data transfer if we have one */ - if (data) { - err = esdhc_setup_data(mmc, data); - if(err) - return err; - } - - /* Figure out the transfer arguments */ - xfertyp = esdhc_xfertyp(cmd, data); - - /* Mask all irqs */ - esdhc_write32(®s->irqsigen, 0); - - /* Send the command */ - esdhc_write32(®s->cmdarg, cmd->cmdarg); -#if defined(CONFIG_FSL_USDHC) - esdhc_write32(®s->mixctrl, - (esdhc_read32(®s->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F)); - esdhc_write32(®s->xfertyp, xfertyp & 0xFFFF0000); -#else - esdhc_write32(®s->xfertyp, xfertyp); -#endif - - /* Wait for the command to complete */ - while (!(esdhc_read32(®s->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE))) - ; - - irqstat = esdhc_read32(®s->irqstat); - - if (irqstat & CMD_ERR) { - err = COMM_ERR; - goto out; - } - - if (irqstat & IRQSTAT_CTOE) { - err = TIMEOUT; - goto out; - } - - /* Workaround for ESDHC errata ENGcm03648 */ - if (!data && (cmd->resp_type & MMC_RSP_BUSY)) { - int timeout = 2500; - - /* Poll on DATA0 line for cmd with busy signal for 250 ms */ - while (timeout > 0 && !(esdhc_read32(®s->prsstat) & - PRSSTAT_DAT0)) { - udelay(100); - timeout--; - } - - if (timeout <= 0) { - printf("Timeout waiting for DAT0 to go high!\n"); - err = TIMEOUT; - goto out; - } - } - - /* Copy the response to the response buffer */ - if (cmd->resp_type & MMC_RSP_136) { - u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0; - - cmdrsp3 = esdhc_read32(®s->cmdrsp3); - cmdrsp2 = esdhc_read32(®s->cmdrsp2); - cmdrsp1 = esdhc_read32(®s->cmdrsp1); - cmdrsp0 = esdhc_read32(®s->cmdrsp0); - cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24); - cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24); - cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24); - cmd->response[3] = (cmdrsp0 << 8); - } else - cmd->response[0] = esdhc_read32(®s->cmdrsp0); - - /* Wait until all of the blocks are transferred */ - if (data) { -#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO - esdhc_pio_read_write(mmc, data); -#else - do { - irqstat = esdhc_read32(®s->irqstat); - - if (irqstat & IRQSTAT_DTOE) { - err = TIMEOUT; - goto out; - } - - if (irqstat & DATA_ERR) { - err = COMM_ERR; - goto out; - } - } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE); -#endif - if (data->flags & MMC_DATA_READ) - check_and_invalidate_dcache_range(cmd, data); - } - -out: - /* Reset CMD and DATA portions on error */ - if (err) { - esdhc_write32(®s->sysctl, esdhc_read32(®s->sysctl) | - SYSCTL_RSTC); - while (esdhc_read32(®s->sysctl) & SYSCTL_RSTC) - ; - - if (data) { - esdhc_write32(®s->sysctl, - esdhc_read32(®s->sysctl) | - SYSCTL_RSTD); - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD)) - ; - } - } - - esdhc_write32(®s->irqstat, -1); - - return err; -} - -static void set_sysctl(struct mmc *mmc, uint clock) -{ - int div, pre_div; - struct fsl_esdhc_cfg *cfg = mmc->priv; - volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; - int sdhc_clk = cfg->sdhc_clk; - uint clk; - - if (clock < mmc->cfg->f_min) - clock = mmc->cfg->f_min; - - if (sdhc_clk / 16 > clock) { - for (pre_div = 2; pre_div < 256; pre_div *= 2) - if ((sdhc_clk / pre_div) <= (clock * 16)) - break; - } else - pre_div = 2; - - for (div = 1; div <= 16; div++) - if ((sdhc_clk / (div * pre_div)) <= clock) - break; - - pre_div >>= 1; - div -= 1; - - clk = (pre_div << 8) | (div << 4); - - esdhc_clrbits32(®s->sysctl, SYSCTL_CKEN); - - esdhc_clrsetbits32(®s->sysctl, SYSCTL_CLOCK_MASK, clk); - - udelay(10000); - - clk = SYSCTL_PEREN | SYSCTL_CKEN; - - esdhc_setbits32(®s->sysctl, clk); -} - -static void esdhc_set_ios(struct mmc *mmc) -{ - struct fsl_esdhc_cfg *cfg = mmc->priv; - struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; - - /* Set the clock speed */ - set_sysctl(mmc, mmc->clock); - - /* Set the bus width */ - esdhc_clrbits32(®s->proctl, PROCTL_DTW_4 | PROCTL_DTW_8); - - if (mmc->bus_width == 4) - esdhc_setbits32(®s->proctl, PROCTL_DTW_4); - else if (mmc->bus_width == 8) - esdhc_setbits32(®s->proctl, PROCTL_DTW_8); - -} - -static int esdhc_init(struct mmc *mmc) -{ - struct fsl_esdhc_cfg *cfg = mmc->priv; - struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; - int timeout = 1000; - - /* Reset the entire host controller */ - esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); - - /* Wait until the controller is available */ - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout) - udelay(1000); - -#ifndef ARCH_MXC - /* Enable cache snooping */ - esdhc_write32(®s->scr, 0x00000040); -#endif - - esdhc_setbits32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN); - - /* Set the initial clock speed */ - mmc_set_clock(mmc, 400000); - - /* Disable the BRR and BWR bits in IRQSTAT */ - esdhc_clrbits32(®s->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR); - - /* Put the PROCTL reg back to the default */ - esdhc_write32(®s->proctl, PROCTL_INIT); - - /* Set timout to the maximum value */ - esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16); - - return 0; -} - -static int esdhc_getcd(struct mmc *mmc) -{ - struct fsl_esdhc_cfg *cfg = mmc->priv; - struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; - int timeout = 1000; - -#ifdef CONFIG_ESDHC_DETECT_QUIRK - if (CONFIG_ESDHC_DETECT_QUIRK) - return 1; -#endif - while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout) - udelay(1000); - - return timeout > 0; -} - -static void esdhc_reset(struct fsl_esdhc *regs) -{ - unsigned long timeout = 100; /* wait max 100 ms */ - - /* reset the controller */ - esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); - - /* hardware clears the bit when it is done */ - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout) - udelay(1000); - if (!timeout) - printf("MMC/SD: Reset never completed.\n"); -} - -static const struct mmc_ops esdhc_ops = { - .send_cmd = esdhc_send_cmd, - .set_ios = esdhc_set_ios, - .init = esdhc_init, - .getcd = esdhc_getcd, -}; - -int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) -{ - struct fsl_esdhc *regs; - struct mmc *mmc; - u32 caps, voltage_caps; - - if (!cfg) - return -1; - - regs = (struct fsl_esdhc *)cfg->esdhc_base; - - /* First reset the eSDHC controller */ - esdhc_reset(regs); - - esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN - | SYSCTL_IPGEN | SYSCTL_CKEN); - - memset(&cfg->cfg, 0, sizeof(cfg->cfg)); - - voltage_caps = 0; - caps = regs->hostcapblt; - -#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135 - caps = caps & ~(ESDHC_HOSTCAPBLT_SRS | - ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30); -#endif - -/* T4240 host controller capabilities register should have VS33 bit */ -#ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33 - caps = caps | ESDHC_HOSTCAPBLT_VS33; -#endif - - if (caps & ESDHC_HOSTCAPBLT_VS18) - voltage_caps |= MMC_VDD_165_195; - if (caps & ESDHC_HOSTCAPBLT_VS30) - voltage_caps |= MMC_VDD_29_30 | MMC_VDD_30_31; - if (caps & ESDHC_HOSTCAPBLT_VS33) - voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34; - - cfg->cfg.name = "FSL_SDHC"; - cfg->cfg.ops = &esdhc_ops; -#ifdef CONFIG_SYS_SD_VOLTAGE - cfg->cfg.voltages = CONFIG_SYS_SD_VOLTAGE; -#else - cfg->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; -#endif - if ((cfg->cfg.voltages & voltage_caps) == 0) { - printf("voltage not supported by controller\n"); - return -1; - } - - cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC; - - if (cfg->max_bus_width > 0) { - if (cfg->max_bus_width < 8) - cfg->cfg.host_caps &= ~MMC_MODE_8BIT; - if (cfg->max_bus_width < 4) - cfg->cfg.host_caps &= ~MMC_MODE_4BIT; - } - - if (caps & ESDHC_HOSTCAPBLT_HSS) - cfg->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; - -#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK - if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK) - cfg->cfg.host_caps &= ~MMC_MODE_8BIT; -#endif - - cfg->cfg.f_min = 400000; - cfg->cfg.f_max = MIN(gd->arch.sdhc_clk, 52000000); - - cfg->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - mmc = mmc_create(&cfg->cfg, cfg); - if (mmc == NULL) - return -1; - - return 0; -} - -int fsl_esdhc_mmc_init(bd_t *bis) -{ - struct fsl_esdhc_cfg *cfg; - - cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1); - cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR; - cfg->sdhc_clk = gd->arch.sdhc_clk; - return fsl_esdhc_initialize(bis, cfg); -} - -#ifdef CONFIG_OF_LIBFDT -void fdt_fixup_esdhc(void *blob, bd_t *bd) -{ - const char *compat = "fsl,esdhc"; - -#ifdef CONFIG_FSL_ESDHC_PIN_MUX - if (!hwconfig("esdhc")) { - do_fixup_by_compat(blob, compat, "status", "disabled", - 8 + 1, 1); - return; - } -#endif - - do_fixup_by_compat_u32(blob, compat, "clock-frequency", - gd->arch.sdhc_clk, 1); - - do_fixup_by_compat(blob, compat, "status", "okay", - 4 + 1, 1); -} -#endif diff --git a/qemu/roms/u-boot/drivers/mmc/fsl_esdhc_spl.c b/qemu/roms/u-boot/drivers/mmc/fsl_esdhc_spl.c deleted file mode 100644 index b1cb4b353..000000000 --- a/qemu/roms/u-boot/drivers/mmc/fsl_esdhc_spl.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2013 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <mmc.h> -#include <malloc.h> - -/* - * The environment variables are written to just after the u-boot image - * on SDCard, so we must read the MBR to get the start address and code - * length of the u-boot image, then calculate the address of the env. - */ -#define ESDHC_BOOT_IMAGE_SIZE 0x48 -#define ESDHC_BOOT_IMAGE_ADDR 0x50 -#define MBRDBR_BOOT_SIG_55 0x1fe -#define MBRDBR_BOOT_SIG_AA 0x1ff -#define CONFIG_CFG_DATA_SECTOR 0 - - -void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst) -{ - uint blk_start, blk_cnt, err; - - struct mmc *mmc = find_mmc_device(0); - if (!mmc) { - puts("spl: mmc device not found!!\n"); - hang(); - } - - if (mmc_init(mmc)) { - puts("MMC init failed\n"); - return; - } - - blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len; - blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len; - - err = mmc->block_dev.block_read(0, blk_start, blk_cnt, vdst); - if (err != blk_cnt) { - puts("spl: mmc read failed!!\n"); - hang(); - } -} - -/* - * The main entry for mmc booting. It's necessary that SDRAM is already - * configured and available since this code loads the main U-Boot image - * from mmc into SDRAM and starts it from there. - */ - -void __noreturn mmc_boot(void) -{ - __attribute__((noreturn)) void (*uboot)(void); - uint blk_start, blk_cnt, err; -#ifndef CONFIG_FSL_CORENET - uchar *tmp_buf; - u32 blklen; - uchar val; - uint i, byte_num; -#endif - u32 offset, code_len; - struct mmc *mmc; - - mmc = find_mmc_device(0); - if (!mmc) { - puts("spl: mmc device not found!!\n"); - hang(); - } - -#ifdef CONFIG_FSL_CORENET - offset = CONFIG_SYS_MMC_U_BOOT_OFFS; - code_len = CONFIG_SYS_MMC_U_BOOT_SIZE; -#else - blklen = mmc->read_bl_len; - tmp_buf = malloc(blklen); - if (!tmp_buf) { - puts("spl: malloc memory failed!!\n"); - hang(); - } - memset(tmp_buf, 0, blklen); - - /* - * Read source addr from sd card - */ - err = mmc->block_dev.block_read(0, CONFIG_CFG_DATA_SECTOR, 1, tmp_buf); - if (err != 1) { - puts("spl: mmc read failed!!\n"); - free(tmp_buf); - hang(); - } - - val = *(tmp_buf + MBRDBR_BOOT_SIG_55); - if (0x55 != val) { - puts("spl: mmc signature is not valid!!\n"); - free(tmp_buf); - hang(); - } - val = *(tmp_buf + MBRDBR_BOOT_SIG_AA); - if (0xAA != val) { - puts("spl: mmc signature is not valid!!\n"); - free(tmp_buf); - hang(); - } - - byte_num = 4; - offset = 0; - for (i = 0; i < byte_num; i++) { - val = *(tmp_buf + ESDHC_BOOT_IMAGE_ADDR + i); - offset = (offset << 8) + val; - } - offset += CONFIG_SYS_MMC_U_BOOT_OFFS; - /* Get the code size from offset 0x48 */ - byte_num = 4; - code_len = 0; - for (i = 0; i < byte_num; i++) { - val = *(tmp_buf + ESDHC_BOOT_IMAGE_SIZE + i); - code_len = (code_len << 8) + val; - } - code_len -= CONFIG_SYS_MMC_U_BOOT_OFFS; - /* - * Load U-Boot image from mmc into RAM - */ -#endif - blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len; - blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len; - err = mmc->block_dev.block_read(0, blk_start, blk_cnt, - (uchar *)CONFIG_SYS_MMC_U_BOOT_DST); - if (err != blk_cnt) { - puts("spl: mmc read failed!!\n"); -#ifndef CONFIG_FSL_CORENET - free(tmp_buf); -#endif - hang(); - } - - /* - * Clean d-cache and invalidate i-cache, to - * make sure that no stale data is executed. - */ - flush_cache(CONFIG_SYS_MMC_U_BOOT_DST, CONFIG_SYS_MMC_U_BOOT_SIZE); - - /* - * Jump to U-Boot image - */ - uboot = (void *)CONFIG_SYS_MMC_U_BOOT_START; - (*uboot)(); -} diff --git a/qemu/roms/u-boot/drivers/mmc/ftsdc010_mci.c b/qemu/roms/u-boot/drivers/mmc/ftsdc010_mci.c deleted file mode 100644 index a620678e5..000000000 --- a/qemu/roms/u-boot/drivers/mmc/ftsdc010_mci.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Faraday MMC/SD Host Controller - * - * (C) Copyright 2010 Faraday Technology - * Dante Su <dantesu@faraday-tech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <part.h> -#include <mmc.h> - -#include <asm/io.h> -#include <asm/errno.h> -#include <asm/byteorder.h> -#include <faraday/ftsdc010.h> - -#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */ -#define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */ - -struct ftsdc010_chip { - void __iomem *regs; - uint32_t wprot; /* write protected (locked) */ - uint32_t rate; /* actual SD clock in Hz */ - uint32_t sclk; /* FTSDC010 source clock in Hz */ - uint32_t fifo; /* fifo depth in bytes */ - uint32_t acmd; - struct mmc_config cfg; /* mmc configuration */ -}; - -static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) -{ - struct ftsdc010_chip *chip = mmc->priv; - struct ftsdc010_mmc __iomem *regs = chip->regs; - int ret = TIMEOUT; - uint32_t ts, st; - uint32_t cmd = FTSDC010_CMD_IDX(mmc_cmd->cmdidx); - uint32_t arg = mmc_cmd->cmdarg; - uint32_t flags = mmc_cmd->resp_type; - - cmd |= FTSDC010_CMD_CMD_EN; - - if (chip->acmd) { - cmd |= FTSDC010_CMD_APP_CMD; - chip->acmd = 0; - } - - if (flags & MMC_RSP_PRESENT) - cmd |= FTSDC010_CMD_NEED_RSP; - - if (flags & MMC_RSP_136) - cmd |= FTSDC010_CMD_LONG_RSP; - - writel(FTSDC010_STATUS_RSP_MASK | FTSDC010_STATUS_CMD_SEND, - ®s->clr); - writel(arg, ®s->argu); - writel(cmd, ®s->cmd); - - if (!(flags & (MMC_RSP_PRESENT | MMC_RSP_136))) { - for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { - if (readl(®s->status) & FTSDC010_STATUS_CMD_SEND) { - writel(FTSDC010_STATUS_CMD_SEND, ®s->clr); - ret = 0; - break; - } - } - } else { - st = 0; - for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { - st = readl(®s->status); - writel(st & FTSDC010_STATUS_RSP_MASK, ®s->clr); - if (st & FTSDC010_STATUS_RSP_MASK) - break; - } - if (st & FTSDC010_STATUS_RSP_CRC_OK) { - if (flags & MMC_RSP_136) { - mmc_cmd->response[0] = readl(®s->rsp3); - mmc_cmd->response[1] = readl(®s->rsp2); - mmc_cmd->response[2] = readl(®s->rsp1); - mmc_cmd->response[3] = readl(®s->rsp0); - } else { - mmc_cmd->response[0] = readl(®s->rsp0); - } - ret = 0; - } else { - debug("ftsdc010: rsp err (cmd=%d, st=0x%x)\n", - mmc_cmd->cmdidx, st); - } - } - - if (ret) { - debug("ftsdc010: cmd timeout (op code=%d)\n", - mmc_cmd->cmdidx); - } else if (mmc_cmd->cmdidx == MMC_CMD_APP_CMD) { - chip->acmd = 1; - } - - return ret; -} - -static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate) -{ - struct ftsdc010_chip *chip = mmc->priv; - struct ftsdc010_mmc __iomem *regs = chip->regs; - uint32_t div; - - for (div = 0; div < 0x7f; ++div) { - if (rate >= chip->sclk / (2 * (div + 1))) - break; - } - chip->rate = chip->sclk / (2 * (div + 1)); - - writel(FTSDC010_CCR_CLK_DIV(div), ®s->ccr); - - if (IS_SD(mmc)) { - setbits_le32(®s->ccr, FTSDC010_CCR_CLK_SD); - - if (chip->rate > 25000000) - setbits_le32(®s->ccr, FTSDC010_CCR_CLK_HISPD); - else - clrbits_le32(®s->ccr, FTSDC010_CCR_CLK_HISPD); - } -} - -static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask) -{ - int ret = TIMEOUT; - uint32_t st, ts; - - for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { - st = readl(®s->status); - if (!(st & mask)) - continue; - writel(st & mask, ®s->clr); - ret = 0; - break; - } - - if (ret) - debug("ftsdc010: wait st(0x%x) timeout\n", mask); - - return ret; -} - -/* - * u-boot mmc api - */ - -static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - int ret = UNUSABLE_ERR; - uint32_t len = 0; - struct ftsdc010_chip *chip = mmc->priv; - struct ftsdc010_mmc __iomem *regs = chip->regs; - - if (data && (data->flags & MMC_DATA_WRITE) && chip->wprot) { - printf("ftsdc010: the card is write protected!\n"); - return ret; - } - - if (data) { - uint32_t dcr; - - len = data->blocksize * data->blocks; - - /* 1. data disable + fifo reset */ - dcr = 0; -#ifdef CONFIG_FTSDC010_SDIO - dcr |= FTSDC010_DCR_FIFO_RST; -#endif - writel(dcr, ®s->dcr); - - /* 2. clear status register */ - writel(FTSDC010_STATUS_DATA_MASK | FTSDC010_STATUS_FIFO_URUN - | FTSDC010_STATUS_FIFO_ORUN, ®s->clr); - - /* 3. data timeout (1 sec) */ - writel(chip->rate, ®s->dtr); - - /* 4. data length (bytes) */ - writel(len, ®s->dlr); - - /* 5. data enable */ - dcr = (ffs(data->blocksize) - 1) | FTSDC010_DCR_DATA_EN; - if (data->flags & MMC_DATA_WRITE) - dcr |= FTSDC010_DCR_DATA_WRITE; - writel(dcr, ®s->dcr); - } - - ret = ftsdc010_send_cmd(mmc, cmd); - if (ret) { - printf("ftsdc010: CMD%d failed\n", cmd->cmdidx); - return ret; - } - - if (!data) - return ret; - - if (data->flags & MMC_DATA_WRITE) { - const uint8_t *buf = (const uint8_t *)data->src; - - while (len > 0) { - int wlen; - - /* wait for tx ready */ - ret = ftsdc010_wait(regs, FTSDC010_STATUS_FIFO_URUN); - if (ret) - break; - - /* write bytes to ftsdc010 */ - for (wlen = 0; wlen < len && wlen < chip->fifo; ) { - writel(*(uint32_t *)buf, ®s->dwr); - buf += 4; - wlen += 4; - } - - len -= wlen; - } - - } else { - uint8_t *buf = (uint8_t *)data->dest; - - while (len > 0) { - int rlen; - - /* wait for rx ready */ - ret = ftsdc010_wait(regs, FTSDC010_STATUS_FIFO_ORUN); - if (ret) - break; - - /* fetch bytes from ftsdc010 */ - for (rlen = 0; rlen < len && rlen < chip->fifo; ) { - *(uint32_t *)buf = readl(®s->dwr); - buf += 4; - rlen += 4; - } - - len -= rlen; - } - - } - - if (!ret) { - ret = ftsdc010_wait(regs, - FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_ERROR); - } - - return ret; -} - -static void ftsdc010_set_ios(struct mmc *mmc) -{ - struct ftsdc010_chip *chip = mmc->priv; - struct ftsdc010_mmc __iomem *regs = chip->regs; - - ftsdc010_clkset(mmc, mmc->clock); - - clrbits_le32(®s->bwr, FTSDC010_BWR_MODE_MASK); - switch (mmc->bus_width) { - case 4: - setbits_le32(®s->bwr, FTSDC010_BWR_MODE_4BIT); - break; - case 8: - setbits_le32(®s->bwr, FTSDC010_BWR_MODE_8BIT); - break; - default: - setbits_le32(®s->bwr, FTSDC010_BWR_MODE_1BIT); - break; - } -} - -static int ftsdc010_init(struct mmc *mmc) -{ - struct ftsdc010_chip *chip = mmc->priv; - struct ftsdc010_mmc __iomem *regs = chip->regs; - uint32_t ts; - - if (readl(®s->status) & FTSDC010_STATUS_CARD_DETECT) - return NO_CARD_ERR; - - if (readl(®s->status) & FTSDC010_STATUS_WRITE_PROT) { - printf("ftsdc010: write protected\n"); - chip->wprot = 1; - } - - chip->fifo = (readl(®s->feature) & 0xff) << 2; - - /* 1. chip reset */ - writel(FTSDC010_CMD_SDC_RST, ®s->cmd); - for (ts = get_timer(0); get_timer(ts) < CFG_RST_TIMEOUT; ) { - if (readl(®s->cmd) & FTSDC010_CMD_SDC_RST) - continue; - break; - } - if (readl(®s->cmd) & FTSDC010_CMD_SDC_RST) { - printf("ftsdc010: reset failed\n"); - return UNUSABLE_ERR; - } - - /* 2. enter low speed mode (400k card detection) */ - ftsdc010_clkset(mmc, 400000); - - /* 3. interrupt disabled */ - writel(0, ®s->int_mask); - - return 0; -} - -static const struct mmc_ops ftsdc010_ops = { - .send_cmd = ftsdc010_request, - .set_ios = ftsdc010_set_ios, - .init = ftsdc010_init, -}; - -int ftsdc010_mmc_init(int devid) -{ - struct mmc *mmc; - struct ftsdc010_chip *chip; - struct ftsdc010_mmc __iomem *regs; -#ifdef CONFIG_FTSDC010_BASE_LIST - uint32_t base_list[] = CONFIG_FTSDC010_BASE_LIST; - - if (devid < 0 || devid >= ARRAY_SIZE(base_list)) - return -1; - regs = (void __iomem *)base_list[devid]; -#else - regs = (void __iomem *)(CONFIG_FTSDC010_BASE + (devid << 20)); -#endif - - chip = malloc(sizeof(struct ftsdc010_chip)); - if (!chip) - return -ENOMEM; - memset(chip, 0, sizeof(struct ftsdc010_chip)); - - chip->regs = regs; -#ifdef CONFIG_SYS_CLK_FREQ - chip->sclk = CONFIG_SYS_CLK_FREQ; -#else - chip->sclk = clk_get_rate("SDC"); -#endif - - chip->cfg.name = "ftsdc010"; - chip->cfg.ops = &ftsdc010_ops; - chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz; - switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) { - case FTSDC010_BWR_CAPS_4BIT: - chip->cfg.host_caps |= MMC_MODE_4BIT; - break; - case FTSDC010_BWR_CAPS_8BIT: - chip->cfg.host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT; - break; - default: - break; - } - - chip->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; - chip->cfg.f_max = chip->sclk / 2; - chip->cfg.f_min = chip->sclk / 0x100; - - chip->cfg.part_type = PART_TYPE_DOS; - chip->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - mmc = mmc_create(&chip->cfg, chip); - if (mmc == NULL) { - free(chip); - return -ENOMEM; - } - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/ftsdc021_sdhci.c b/qemu/roms/u-boot/drivers/mmc/ftsdc021_sdhci.c deleted file mode 100644 index 1f6cdba17..000000000 --- a/qemu/roms/u-boot/drivers/mmc/ftsdc021_sdhci.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * (C) Copyright 2013 Faraday Technology - * Kuo-Jung Su <dantesu@faraday-tech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <sdhci.h> - -#ifndef CONFIG_FTSDC021_CLOCK -#define CONFIG_FTSDC021_CLOCK clk_get_rate("MMC") -#endif - -int ftsdc021_sdhci_init(u32 regbase) -{ - struct sdhci_host *host = NULL; - uint32_t freq = CONFIG_FTSDC021_CLOCK; - - host = calloc(1, sizeof(struct sdhci_host)); - if (!host) { - puts("sdh_host malloc fail!\n"); - return 1; - } - - host->name = "FTSDC021"; - host->ioaddr = (void __iomem *)regbase; - host->quirks = 0; - add_sdhci(host, freq, 0); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/gen_atmel_mci.c b/qemu/roms/u-boot/drivers/mmc/gen_atmel_mci.c deleted file mode 100644 index acca0269e..000000000 --- a/qemu/roms/u-boot/drivers/mmc/gen_atmel_mci.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2010 - * Rob Emanuele <rob@emanuele.us> - * Reinhard Meyer, EMK Elektronik <reinhard.meyer@emk-elektronik.de> - * - * Original Driver: - * Copyright (C) 2004-2006 Atmel Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <mmc.h> -#include <part.h> -#include <malloc.h> -#include <asm/io.h> -#include <asm/errno.h> -#include <asm/byteorder.h> -#include <asm/arch/clk.h> -#include <asm/arch/hardware.h> -#include "atmel_mci.h" - -#ifndef CONFIG_SYS_MMC_CLK_OD -# define CONFIG_SYS_MMC_CLK_OD 150000 -#endif - -#define MMC_DEFAULT_BLKLEN 512 - -#if defined(CONFIG_ATMEL_MCI_PORTB) -# define MCI_BUS 1 -#else -# define MCI_BUS 0 -#endif - -static int initialized = 0; - -/* Read Atmel MCI IP version */ -static unsigned int atmel_mci_get_version(struct atmel_mci *mci) -{ - return readl(&mci->version) & 0x00000fff; -} - -/* - * Print command and status: - * - * - always when DEBUG is defined - * - on command errors - */ -static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg) -{ - printf("gen_atmel_mci: CMDR %08x (%2u) ARGR %08x (SR: %08x) %s\n", - cmdr, cmdr&0x3F, arg, status, msg); -} - -/* Setup for MCI Clock and Block Size */ -static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen) -{ - atmel_mci_t *mci = mmc->priv; - u32 bus_hz = get_mci_clk_rate(); - u32 clkdiv = 255; - - debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n", - bus_hz, hz, blklen); - if (hz > 0) { - /* find lowest clkdiv yielding a rate <= than requested */ - for (clkdiv=0; clkdiv<255; clkdiv++) { - if ((bus_hz / (clkdiv+1) / 2) <= hz) - break; - } - } - printf("mci: setting clock %u Hz, block size %u\n", - (bus_hz / (clkdiv+1)) / 2, blklen); - - blklen &= 0xfffc; - /* On some platforms RDPROOF and WRPROOF are ignored */ - writel((MMCI_BF(CLKDIV, clkdiv) - | MMCI_BF(BLKLEN, blklen) - | MMCI_BIT(RDPROOF) - | MMCI_BIT(WRPROOF)), &mci->mr); - /* - * On some new platforms BLKLEN in mci->mr is ignored. - * Should use the BLKLEN in the block register. - */ - writel(MMCI_BF(BLKLEN, blklen), &mci->blkr); - initialized = 1; -} - -/* Return the CMDR with flags for a given command and data packet */ -static u32 mci_encode_cmd( - struct mmc_cmd *cmd, struct mmc_data *data, u32* error_flags) -{ - u32 cmdr = 0; - - /* Default Flags for Errors */ - *error_flags |= (MMCI_BIT(DTOE) | MMCI_BIT(RDIRE) | MMCI_BIT(RENDE) | - MMCI_BIT(RINDE) | MMCI_BIT(RTOE)); - - /* Default Flags for the Command */ - cmdr |= MMCI_BIT(MAXLAT); - - if (data) { - cmdr |= MMCI_BF(TRCMD, 1); - if (data->blocks > 1) - cmdr |= MMCI_BF(TRTYP, 1); - if (data->flags & MMC_DATA_READ) - cmdr |= MMCI_BIT(TRDIR); - } - - if (cmd->resp_type & MMC_RSP_CRC) - *error_flags |= MMCI_BIT(RCRCE); - if (cmd->resp_type & MMC_RSP_136) - cmdr |= MMCI_BF(RSPTYP, 2); - else if (cmd->resp_type & MMC_RSP_BUSY) - cmdr |= MMCI_BF(RSPTYP, 3); - else if (cmd->resp_type & MMC_RSP_PRESENT) - cmdr |= MMCI_BF(RSPTYP, 1); - - return cmdr | MMCI_BF(CMDNB, cmd->cmdidx); -} - -/* Entered into function pointer in mci_send_cmd */ -static u32 mci_data_read(atmel_mci_t *mci, u32* data, u32 error_flags) -{ - u32 status; - - do { - status = readl(&mci->sr); - if (status & (error_flags | MMCI_BIT(OVRE))) - goto io_fail; - } while (!(status & MMCI_BIT(RXRDY))); - - if (status & MMCI_BIT(RXRDY)) { - *data = readl(&mci->rdr); - status = 0; - } -io_fail: - return status; -} - -/* Entered into function pointer in mci_send_cmd */ -static u32 mci_data_write(atmel_mci_t *mci, u32* data, u32 error_flags) -{ - u32 status; - - do { - status = readl(&mci->sr); - if (status & (error_flags | MMCI_BIT(UNRE))) - goto io_fail; - } while (!(status & MMCI_BIT(TXRDY))); - - if (status & MMCI_BIT(TXRDY)) { - writel(*data, &mci->tdr); - status = 0; - } -io_fail: - return status; -} - -/* - * Entered into mmc structure during driver init - * - * Sends a command out on the bus and deals with the block data. - * Takes the mmc pointer, a command pointer, and an optional data pointer. - */ -static int -mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) -{ - atmel_mci_t *mci = mmc->priv; - u32 cmdr; - u32 error_flags = 0; - u32 status; - - if (!initialized) { - puts ("MCI not initialized!\n"); - return COMM_ERR; - } - - /* Figure out the transfer arguments */ - cmdr = mci_encode_cmd(cmd, data, &error_flags); - - /* For multi blocks read/write, set the block register */ - if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) - || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) - writel(data->blocks | MMCI_BF(BLKLEN, mmc->read_bl_len), - &mci->blkr); - - /* Send the command */ - writel(cmd->cmdarg, &mci->argr); - writel(cmdr, &mci->cmdr); - -#ifdef DEBUG - dump_cmd(cmdr, cmd->cmdarg, 0, "DEBUG"); -#endif - - /* Wait for the command to complete */ - while (!((status = readl(&mci->sr)) & MMCI_BIT(CMDRDY))); - - if ((status & error_flags) & MMCI_BIT(RTOE)) { - dump_cmd(cmdr, cmd->cmdarg, status, "Command Time Out"); - return TIMEOUT; - } else if (status & error_flags) { - dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed"); - return COMM_ERR; - } - - /* Copy the response to the response buffer */ - if (cmd->resp_type & MMC_RSP_136) { - cmd->response[0] = readl(&mci->rspr); - cmd->response[1] = readl(&mci->rspr1); - cmd->response[2] = readl(&mci->rspr2); - cmd->response[3] = readl(&mci->rspr3); - } else - cmd->response[0] = readl(&mci->rspr); - - /* transfer all of the blocks */ - if (data) { - u32 word_count, block_count; - u32* ioptr; - u32 sys_blocksize, dummy, i; - u32 (*mci_data_op) - (atmel_mci_t *mci, u32* data, u32 error_flags); - - if (data->flags & MMC_DATA_READ) { - mci_data_op = mci_data_read; - sys_blocksize = mmc->read_bl_len; - ioptr = (u32*)data->dest; - } else { - mci_data_op = mci_data_write; - sys_blocksize = mmc->write_bl_len; - ioptr = (u32*)data->src; - } - - status = 0; - for (block_count = 0; - block_count < data->blocks && !status; - block_count++) { - word_count = 0; - do { - status = mci_data_op(mci, ioptr, error_flags); - word_count++; - ioptr++; - } while (!status && word_count < (data->blocksize/4)); -#ifdef DEBUG - if (data->flags & MMC_DATA_READ) - { - printf("Read Data:\n"); - print_buffer(0, data->dest, 1, - word_count*4, 0); - } -#endif -#ifdef DEBUG - if (!status && word_count < (sys_blocksize / 4)) - printf("filling rest of block...\n"); -#endif - /* fill the rest of a full block */ - while (!status && word_count < (sys_blocksize / 4)) { - status = mci_data_op(mci, &dummy, - error_flags); - word_count++; - } - if (status) { - dump_cmd(cmdr, cmd->cmdarg, status, - "Data Transfer Failed"); - return COMM_ERR; - } - } - - /* Wait for Transfer End */ - i = 0; - do { - status = readl(&mci->sr); - - if (status & error_flags) { - dump_cmd(cmdr, cmd->cmdarg, status, - "DTIP Wait Failed"); - return COMM_ERR; - } - i++; - } while ((status & MMCI_BIT(DTIP)) && i < 10000); - if (status & MMCI_BIT(DTIP)) { - dump_cmd(cmdr, cmd->cmdarg, status, - "XFER DTIP never unset, ignoring"); - } - } - - return 0; -} - -/* Entered into mmc structure during driver init */ -static void mci_set_ios(struct mmc *mmc) -{ - atmel_mci_t *mci = mmc->priv; - int bus_width = mmc->bus_width; - unsigned int version = atmel_mci_get_version(mci); - int busw; - - /* Set the clock speed */ - mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN); - - /* - * set the bus width and select slot for this interface - * there is no capability for multiple slots on the same interface yet - */ - if ((version & 0xf00) >= 0x300) { - switch (bus_width) { - case 8: - busw = 3; - break; - case 4: - busw = 2; - break; - default: - busw = 0; - break; - } - - writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); - } else { - busw = (bus_width == 4) ? 1 : 0; - - writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); - } -} - -/* Entered into mmc structure during driver init */ -static int mci_init(struct mmc *mmc) -{ - atmel_mci_t *mci = mmc->priv; - - /* Initialize controller */ - writel(MMCI_BIT(SWRST), &mci->cr); /* soft reset */ - writel(MMCI_BIT(PWSDIS), &mci->cr); /* disable power save */ - writel(MMCI_BIT(MCIEN), &mci->cr); /* enable mci */ - writel(MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); /* select port */ - - /* This delay can be optimized, but stick with max value */ - writel(0x7f, &mci->dtor); - /* Disable Interrupts */ - writel(~0UL, &mci->idr); - - /* Set default clocks and blocklen */ - mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); - - return 0; -} - -static const struct mmc_ops atmel_mci_ops = { - .send_cmd = mci_send_cmd, - .set_ios = mci_set_ios, - .init = mci_init, -}; - -/* - * This is the only exported function - * - * Call it with the MCI register base address - */ -int atmel_mci_init(void *regs) -{ - struct mmc *mmc; - struct mmc_config *cfg; - struct atmel_mci *mci; - unsigned int version; - - cfg = malloc(sizeof(*cfg)); - if (cfg == NULL) - return -1; - memset(cfg, 0, sizeof(*cfg)); - - mci = (struct atmel_mci *)regs; - - cfg->name = "mci"; - cfg->ops = &atmel_mci_ops; - - /* need to be able to pass these in on a board by board basis */ - cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; - version = atmel_mci_get_version(mci); - if ((version & 0xf00) >= 0x300) - cfg->host_caps = MMC_MODE_8BIT; - - cfg->host_caps |= MMC_MODE_4BIT; - - /* - * min and max frequencies determined by - * max and min of clock divider - */ - cfg->f_min = get_mci_clk_rate() / (2*256); - cfg->f_max = get_mci_clk_rate() / (2*1); - - cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - mmc = mmc_create(cfg, regs); - - if (mmc == NULL) { - free(cfg); - return -1; - } - /* NOTE: possibly leaking the cfg structure */ - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/kona_sdhci.c b/qemu/roms/u-boot/drivers/mmc/kona_sdhci.c deleted file mode 100644 index 77e42c8af..000000000 --- a/qemu/roms/u-boot/drivers/mmc/kona_sdhci.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2013 Broadcom Corporation. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <sdhci.h> -#include <asm/errno.h> -#include <asm/kona-common/clk.h> - -#define SDHCI_CORECTRL_OFFSET 0x00008000 -#define SDHCI_CORECTRL_EN 0x01 -#define SDHCI_CORECTRL_RESET 0x02 - -#define SDHCI_CORESTAT_OFFSET 0x00008004 -#define SDHCI_CORESTAT_CD_SW 0x01 - -#define SDHCI_COREIMR_OFFSET 0x00008008 -#define SDHCI_COREIMR_IP 0x01 - -static int init_kona_mmc_core(struct sdhci_host *host) -{ - unsigned int mask; - unsigned int timeout; - - if (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL) { - printf("%s: sd host controller reset error\n", __func__); - return 1; - } - - /* For kona a hardware reset before anything else. */ - mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET) | SDHCI_CORECTRL_RESET; - sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET); - - /* Wait max 100 ms */ - timeout = 1000; - do { - if (timeout == 0) { - printf("%s: reset timeout error\n", __func__); - return 1; - } - timeout--; - udelay(100); - } while (0 == - (sdhci_readl(host, SDHCI_CORECTRL_OFFSET) & - SDHCI_CORECTRL_RESET)); - - /* Clear the reset bit. */ - mask = mask & ~SDHCI_CORECTRL_RESET; - sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET); - - /* Enable AHB clock */ - mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET); - sdhci_writel(host, mask | SDHCI_CORECTRL_EN, SDHCI_CORECTRL_OFFSET); - - /* Enable interrupts */ - sdhci_writel(host, SDHCI_COREIMR_IP, SDHCI_COREIMR_OFFSET); - - /* Make sure Card is detected in controller */ - mask = sdhci_readl(host, SDHCI_CORESTAT_OFFSET); - sdhci_writel(host, mask | SDHCI_CORESTAT_CD_SW, SDHCI_CORESTAT_OFFSET); - - /* Wait max 100 ms */ - timeout = 1000; - while (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { - if (timeout == 0) { - printf("%s: CARD DETECT timeout error\n", __func__); - return 1; - } - timeout--; - udelay(100); - } - return 0; -} - -int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks) -{ - int ret = 0; - u32 max_clk; - void *reg_base; - struct sdhci_host *host = NULL; - - host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); - if (!host) { - printf("%s: sdhci host malloc fail!\n", __func__); - return -ENOMEM; - } - switch (dev_index) { - case 0: - reg_base = (void *)CONFIG_SYS_SDIO_BASE0; - ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO0_MAX_CLK, - &max_clk); - break; - case 1: - reg_base = (void *)CONFIG_SYS_SDIO_BASE1; - ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO1_MAX_CLK, - &max_clk); - break; - case 2: - reg_base = (void *)CONFIG_SYS_SDIO_BASE2; - ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO2_MAX_CLK, - &max_clk); - break; - case 3: - reg_base = (void *)CONFIG_SYS_SDIO_BASE3; - ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO3_MAX_CLK, - &max_clk); - break; - default: - printf("%s: sdio dev index %d not supported\n", - __func__, dev_index); - ret = -EINVAL; - } - if (ret) - return ret; - - host->name = "kona-sdhci"; - host->ioaddr = reg_base; - host->quirks = quirks; - host->host_caps = MMC_MODE_HC; - - if (init_kona_mmc_core(host)) - return -EINVAL; - - if (quirks & SDHCI_QUIRK_REG32_RW) - host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16; - else - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - - add_sdhci(host, max_clk, min_clk); - return ret; -} diff --git a/qemu/roms/u-boot/drivers/mmc/mmc.c b/qemu/roms/u-boot/drivers/mmc/mmc.c deleted file mode 100644 index 16051e52f..000000000 --- a/qemu/roms/u-boot/drivers/mmc/mmc.c +++ /dev/null @@ -1,1528 +0,0 @@ -/* - * Copyright 2008, Freescale Semiconductor, Inc - * Andy Fleming - * - * Based vaguely on the Linux code - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <command.h> -#include <mmc.h> -#include <part.h> -#include <malloc.h> -#include <linux/list.h> -#include <div64.h> -#include "mmc_private.h" - -static struct list_head mmc_devices; -static int cur_dev_num = -1; - -int __weak board_mmc_getwp(struct mmc *mmc) -{ - return -1; -} - -int mmc_getwp(struct mmc *mmc) -{ - int wp; - - wp = board_mmc_getwp(mmc); - - if (wp < 0) { - if (mmc->cfg->ops->getwp) - wp = mmc->cfg->ops->getwp(mmc); - else - wp = 0; - } - - return wp; -} - -int __board_mmc_getcd(struct mmc *mmc) { - return -1; -} - -int board_mmc_getcd(struct mmc *mmc)__attribute__((weak, - alias("__board_mmc_getcd"))); - -int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) -{ - int ret; - -#ifdef CONFIG_MMC_TRACE - int i; - u8 *ptr; - - printf("CMD_SEND:%d\n", cmd->cmdidx); - printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); - ret = mmc->cfg->ops->send_cmd(mmc, cmd, data); - switch (cmd->resp_type) { - case MMC_RSP_NONE: - printf("\t\tMMC_RSP_NONE\n"); - break; - case MMC_RSP_R1: - printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n", - cmd->response[0]); - break; - case MMC_RSP_R1b: - printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n", - cmd->response[0]); - break; - case MMC_RSP_R2: - printf("\t\tMMC_RSP_R2\t\t 0x%08X \n", - cmd->response[0]); - printf("\t\t \t\t 0x%08X \n", - cmd->response[1]); - printf("\t\t \t\t 0x%08X \n", - cmd->response[2]); - printf("\t\t \t\t 0x%08X \n", - cmd->response[3]); - printf("\n"); - printf("\t\t\t\t\tDUMPING DATA\n"); - for (i = 0; i < 4; i++) { - int j; - printf("\t\t\t\t\t%03d - ", i*4); - ptr = (u8 *)&cmd->response[i]; - ptr += 3; - for (j = 0; j < 4; j++) - printf("%02X ", *ptr--); - printf("\n"); - } - break; - case MMC_RSP_R3: - printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n", - cmd->response[0]); - break; - default: - printf("\t\tERROR MMC rsp not supported\n"); - break; - } -#else - ret = mmc->cfg->ops->send_cmd(mmc, cmd, data); -#endif - return ret; -} - -int mmc_send_status(struct mmc *mmc, int timeout) -{ - struct mmc_cmd cmd; - int err, retries = 5; -#ifdef CONFIG_MMC_TRACE - int status; -#endif - - cmd.cmdidx = MMC_CMD_SEND_STATUS; - cmd.resp_type = MMC_RSP_R1; - if (!mmc_host_is_spi(mmc)) - cmd.cmdarg = mmc->rca << 16; - - do { - err = mmc_send_cmd(mmc, &cmd, NULL); - if (!err) { - if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) && - (cmd.response[0] & MMC_STATUS_CURR_STATE) != - MMC_STATE_PRG) - break; - else if (cmd.response[0] & MMC_STATUS_MASK) { -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("Status Error: 0x%08X\n", - cmd.response[0]); -#endif - return COMM_ERR; - } - } else if (--retries < 0) - return err; - - udelay(1000); - - } while (timeout--); - -#ifdef CONFIG_MMC_TRACE - status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; - printf("CURR STATE:%d\n", status); -#endif - if (timeout <= 0) { -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("Timeout waiting card ready\n"); -#endif - return TIMEOUT; - } - - return 0; -} - -int mmc_set_blocklen(struct mmc *mmc, int len) -{ - struct mmc_cmd cmd; - - cmd.cmdidx = MMC_CMD_SET_BLOCKLEN; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = len; - - return mmc_send_cmd(mmc, &cmd, NULL); -} - -struct mmc *find_mmc_device(int dev_num) -{ - struct mmc *m; - struct list_head *entry; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - - if (m->block_dev.dev == dev_num) - return m; - } - -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("MMC Device %d not found\n", dev_num); -#endif - - return NULL; -} - -static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, - lbaint_t blkcnt) -{ - struct mmc_cmd cmd; - struct mmc_data data; - - if (blkcnt > 1) - cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; - else - cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK; - - if (mmc->high_capacity) - cmd.cmdarg = start; - else - cmd.cmdarg = start * mmc->read_bl_len; - - cmd.resp_type = MMC_RSP_R1; - - data.dest = dst; - data.blocks = blkcnt; - data.blocksize = mmc->read_bl_len; - data.flags = MMC_DATA_READ; - - if (mmc_send_cmd(mmc, &cmd, &data)) - return 0; - - if (blkcnt > 1) { - cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_R1b; - if (mmc_send_cmd(mmc, &cmd, NULL)) { -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("mmc fail to send stop cmd\n"); -#endif - return 0; - } - } - - return blkcnt; -} - -static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst) -{ - lbaint_t cur, blocks_todo = blkcnt; - - if (blkcnt == 0) - return 0; - - struct mmc *mmc = find_mmc_device(dev_num); - if (!mmc) - return 0; - - if ((start + blkcnt) > mmc->block_dev.lba) { -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n", - start + blkcnt, mmc->block_dev.lba); -#endif - return 0; - } - - if (mmc_set_blocklen(mmc, mmc->read_bl_len)) - return 0; - - do { - cur = (blocks_todo > mmc->cfg->b_max) ? - mmc->cfg->b_max : blocks_todo; - if(mmc_read_blocks(mmc, dst, start, cur) != cur) - return 0; - blocks_todo -= cur; - start += cur; - dst += cur * mmc->read_bl_len; - } while (blocks_todo > 0); - - return blkcnt; -} - -static int mmc_go_idle(struct mmc *mmc) -{ - struct mmc_cmd cmd; - int err; - - udelay(1000); - - cmd.cmdidx = MMC_CMD_GO_IDLE_STATE; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_NONE; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - udelay(2000); - - return 0; -} - -static int sd_send_op_cond(struct mmc *mmc) -{ - int timeout = 1000; - int err; - struct mmc_cmd cmd; - - do { - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SEND_OP_COND; - cmd.resp_type = MMC_RSP_R3; - - /* - * Most cards do not answer if some reserved bits - * in the ocr are set. However, Some controller - * can set bit 7 (reserved for low voltages), but - * how to manage low voltages SD card is not yet - * specified. - */ - cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 : - (mmc->cfg->voltages & 0xff8000); - - if (mmc->version == SD_VERSION_2) - cmd.cmdarg |= OCR_HCS; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - udelay(1000); - } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--); - - if (timeout <= 0) - return UNUSABLE_ERR; - - if (mmc->version != SD_VERSION_2) - mmc->version = SD_VERSION_1_0; - - if (mmc_host_is_spi(mmc)) { /* read OCR for spi */ - cmd.cmdidx = MMC_CMD_SPI_READ_OCR; - cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } - - mmc->ocr = cmd.response[0]; - - mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); - mmc->rca = 0; - - return 0; -} - -/* We pass in the cmd since otherwise the init seems to fail */ -static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd, - int use_arg) -{ - int err; - - cmd->cmdidx = MMC_CMD_SEND_OP_COND; - cmd->resp_type = MMC_RSP_R3; - cmd->cmdarg = 0; - if (use_arg && !mmc_host_is_spi(mmc)) { - cmd->cmdarg = - (mmc->cfg->voltages & - (mmc->op_cond_response & OCR_VOLTAGE_MASK)) | - (mmc->op_cond_response & OCR_ACCESS_MODE); - - if (mmc->cfg->host_caps & MMC_MODE_HC) - cmd->cmdarg |= OCR_HCS; - } - err = mmc_send_cmd(mmc, cmd, NULL); - if (err) - return err; - mmc->op_cond_response = cmd->response[0]; - return 0; -} - -int mmc_send_op_cond(struct mmc *mmc) -{ - struct mmc_cmd cmd; - int err, i; - - /* Some cards seem to need this */ - mmc_go_idle(mmc); - - /* Asking to the card its capabilities */ - mmc->op_cond_pending = 1; - for (i = 0; i < 2; i++) { - err = mmc_send_op_cond_iter(mmc, &cmd, i != 0); - if (err) - return err; - - /* exit if not busy (flag seems to be inverted) */ - if (mmc->op_cond_response & OCR_BUSY) - return 0; - } - return IN_PROGRESS; -} - -int mmc_complete_op_cond(struct mmc *mmc) -{ - struct mmc_cmd cmd; - int timeout = 1000; - uint start; - int err; - - mmc->op_cond_pending = 0; - start = get_timer(0); - do { - err = mmc_send_op_cond_iter(mmc, &cmd, 1); - if (err) - return err; - if (get_timer(start) > timeout) - return UNUSABLE_ERR; - udelay(100); - } while (!(mmc->op_cond_response & OCR_BUSY)); - - if (mmc_host_is_spi(mmc)) { /* read OCR for spi */ - cmd.cmdidx = MMC_CMD_SPI_READ_OCR; - cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } - - mmc->version = MMC_VERSION_UNKNOWN; - mmc->ocr = cmd.response[0]; - - mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); - mmc->rca = 1; - - return 0; -} - - -static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) -{ - struct mmc_cmd cmd; - struct mmc_data data; - int err; - - /* Get the Card Status Register */ - cmd.cmdidx = MMC_CMD_SEND_EXT_CSD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - data.dest = (char *)ext_csd; - data.blocks = 1; - data.blocksize = MMC_MAX_BLOCK_LEN; - data.flags = MMC_DATA_READ; - - err = mmc_send_cmd(mmc, &cmd, &data); - - return err; -} - - -static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) -{ - struct mmc_cmd cmd; - int timeout = 1000; - int ret; - - cmd.cmdidx = MMC_CMD_SWITCH; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | - (index << 16) | - (value << 8); - - ret = mmc_send_cmd(mmc, &cmd, NULL); - - /* Waiting for the ready status */ - if (!ret) - ret = mmc_send_status(mmc, timeout); - - return ret; - -} - -static int mmc_change_freq(struct mmc *mmc) -{ - ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); - char cardtype; - int err; - - mmc->card_caps = 0; - - if (mmc_host_is_spi(mmc)) - return 0; - - /* Only version 4 supports high-speed */ - if (mmc->version < MMC_VERSION_4) - return 0; - - err = mmc_send_ext_csd(mmc, ext_csd); - - if (err) - return err; - - cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); - - if (err) - return err; - - /* Now check to see that it worked */ - err = mmc_send_ext_csd(mmc, ext_csd); - - if (err) - return err; - - /* No high-speed support */ - if (!ext_csd[EXT_CSD_HS_TIMING]) - return 0; - - /* High Speed is set, there are two types: 52MHz and 26MHz */ - if (cardtype & MMC_HS_52MHZ) - mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; - else - mmc->card_caps |= MMC_MODE_HS; - - return 0; -} - -static int mmc_set_capacity(struct mmc *mmc, int part_num) -{ - switch (part_num) { - case 0: - mmc->capacity = mmc->capacity_user; - break; - case 1: - case 2: - mmc->capacity = mmc->capacity_boot; - break; - case 3: - mmc->capacity = mmc->capacity_rpmb; - break; - case 4: - case 5: - case 6: - case 7: - mmc->capacity = mmc->capacity_gp[part_num - 4]; - break; - default: - return -1; - } - - mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); - - return 0; -} - -int mmc_switch_part(int dev_num, unsigned int part_num) -{ - struct mmc *mmc = find_mmc_device(dev_num); - int ret; - - if (!mmc) - return -1; - - ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, - (mmc->part_config & ~PART_ACCESS_MASK) - | (part_num & PART_ACCESS_MASK)); - if (ret) - return ret; - - return mmc_set_capacity(mmc, part_num); -} - -int mmc_getcd(struct mmc *mmc) -{ - int cd; - - cd = board_mmc_getcd(mmc); - - if (cd < 0) { - if (mmc->cfg->ops->getcd) - cd = mmc->cfg->ops->getcd(mmc); - else - cd = 1; - } - - return cd; -} - -static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) -{ - struct mmc_cmd cmd; - struct mmc_data data; - - /* Switch the frequency */ - cmd.cmdidx = SD_CMD_SWITCH_FUNC; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = (mode << 31) | 0xffffff; - cmd.cmdarg &= ~(0xf << (group * 4)); - cmd.cmdarg |= value << (group * 4); - - data.dest = (char *)resp; - data.blocksize = 64; - data.blocks = 1; - data.flags = MMC_DATA_READ; - - return mmc_send_cmd(mmc, &cmd, &data); -} - - -static int sd_change_freq(struct mmc *mmc) -{ - int err; - struct mmc_cmd cmd; - ALLOC_CACHE_ALIGN_BUFFER(uint, scr, 2); - ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16); - struct mmc_data data; - int timeout; - - mmc->card_caps = 0; - - if (mmc_host_is_spi(mmc)) - return 0; - - /* Read the SCR to find out if this card supports higher speeds */ - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SEND_SCR; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - timeout = 3; - -retry_scr: - data.dest = (char *)scr; - data.blocksize = 8; - data.blocks = 1; - data.flags = MMC_DATA_READ; - - err = mmc_send_cmd(mmc, &cmd, &data); - - if (err) { - if (timeout--) - goto retry_scr; - - return err; - } - - mmc->scr[0] = __be32_to_cpu(scr[0]); - mmc->scr[1] = __be32_to_cpu(scr[1]); - - switch ((mmc->scr[0] >> 24) & 0xf) { - case 0: - mmc->version = SD_VERSION_1_0; - break; - case 1: - mmc->version = SD_VERSION_1_10; - break; - case 2: - mmc->version = SD_VERSION_2; - if ((mmc->scr[0] >> 15) & 0x1) - mmc->version = SD_VERSION_3; - break; - default: - mmc->version = SD_VERSION_1_0; - break; - } - - if (mmc->scr[0] & SD_DATA_4BIT) - mmc->card_caps |= MMC_MODE_4BIT; - - /* Version 1.0 doesn't support switching */ - if (mmc->version == SD_VERSION_1_0) - return 0; - - timeout = 4; - while (timeout--) { - err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1, - (u8 *)switch_status); - - if (err) - return err; - - /* The high-speed function is busy. Try again */ - if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY)) - break; - } - - /* If high-speed isn't supported, we return */ - if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)) - return 0; - - /* - * If the host doesn't support SD_HIGHSPEED, do not switch card to - * HIGHSPEED mode even if the card support SD_HIGHSPPED. - * This can avoid furthur problem when the card runs in different - * mode between the host. - */ - if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) && - (mmc->cfg->host_caps & MMC_MODE_HS))) - return 0; - - err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status); - - if (err) - return err; - - if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000) - mmc->card_caps |= MMC_MODE_HS; - - return 0; -} - -/* frequency bases */ -/* divided by 10 to be nice to platforms without floating point */ -static const int fbase[] = { - 10000, - 100000, - 1000000, - 10000000, -}; - -/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice - * to platforms without floating point. - */ -static const int multipliers[] = { - 0, /* reserved */ - 10, - 12, - 13, - 15, - 20, - 25, - 30, - 35, - 40, - 45, - 50, - 55, - 60, - 70, - 80, -}; - -static void mmc_set_ios(struct mmc *mmc) -{ - if (mmc->cfg->ops->set_ios) - mmc->cfg->ops->set_ios(mmc); -} - -void mmc_set_clock(struct mmc *mmc, uint clock) -{ - if (clock > mmc->cfg->f_max) - clock = mmc->cfg->f_max; - - if (clock < mmc->cfg->f_min) - clock = mmc->cfg->f_min; - - mmc->clock = clock; - - mmc_set_ios(mmc); -} - -static void mmc_set_bus_width(struct mmc *mmc, uint width) -{ - mmc->bus_width = width; - - mmc_set_ios(mmc); -} - -static int mmc_startup(struct mmc *mmc) -{ - int err, i; - uint mult, freq; - u64 cmult, csize, capacity; - struct mmc_cmd cmd; - ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); - ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN); - int timeout = 1000; - -#ifdef CONFIG_MMC_SPI_CRC_ON - if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */ - cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 1; - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } -#endif - - /* Put the Card in Identify Mode */ - cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID : - MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */ - cmd.resp_type = MMC_RSP_R2; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - memcpy(mmc->cid, cmd.response, 16); - - /* - * For MMC cards, set the Relative Address. - * For SD cards, get the Relatvie Address. - * This also puts the cards into Standby State - */ - if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */ - cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR; - cmd.cmdarg = mmc->rca << 16; - cmd.resp_type = MMC_RSP_R6; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - if (IS_SD(mmc)) - mmc->rca = (cmd.response[0] >> 16) & 0xffff; - } - - /* Get the Card-Specific Data */ - cmd.cmdidx = MMC_CMD_SEND_CSD; - cmd.resp_type = MMC_RSP_R2; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - /* Waiting for the ready status */ - mmc_send_status(mmc, timeout); - - if (err) - return err; - - mmc->csd[0] = cmd.response[0]; - mmc->csd[1] = cmd.response[1]; - mmc->csd[2] = cmd.response[2]; - mmc->csd[3] = cmd.response[3]; - - if (mmc->version == MMC_VERSION_UNKNOWN) { - int version = (cmd.response[0] >> 26) & 0xf; - - switch (version) { - case 0: - mmc->version = MMC_VERSION_1_2; - break; - case 1: - mmc->version = MMC_VERSION_1_4; - break; - case 2: - mmc->version = MMC_VERSION_2_2; - break; - case 3: - mmc->version = MMC_VERSION_3; - break; - case 4: - mmc->version = MMC_VERSION_4; - break; - default: - mmc->version = MMC_VERSION_1_2; - break; - } - } - - /* divide frequency by 10, since the mults are 10x bigger */ - freq = fbase[(cmd.response[0] & 0x7)]; - mult = multipliers[((cmd.response[0] >> 3) & 0xf)]; - - mmc->tran_speed = freq * mult; - - mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1); - mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf); - - if (IS_SD(mmc)) - mmc->write_bl_len = mmc->read_bl_len; - else - mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf); - - if (mmc->high_capacity) { - csize = (mmc->csd[1] & 0x3f) << 16 - | (mmc->csd[2] & 0xffff0000) >> 16; - cmult = 8; - } else { - csize = (mmc->csd[1] & 0x3ff) << 2 - | (mmc->csd[2] & 0xc0000000) >> 30; - cmult = (mmc->csd[2] & 0x00038000) >> 15; - } - - mmc->capacity_user = (csize + 1) << (cmult + 2); - mmc->capacity_user *= mmc->read_bl_len; - mmc->capacity_boot = 0; - mmc->capacity_rpmb = 0; - for (i = 0; i < 4; i++) - mmc->capacity_gp[i] = 0; - - if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN) - mmc->read_bl_len = MMC_MAX_BLOCK_LEN; - - if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN) - mmc->write_bl_len = MMC_MAX_BLOCK_LEN; - - if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) { - cmd.cmdidx = MMC_CMD_SET_DSR; - cmd.cmdarg = (mmc->dsr & 0xffff) << 16; - cmd.resp_type = MMC_RSP_NONE; - if (mmc_send_cmd(mmc, &cmd, NULL)) - printf("MMC: SET_DSR failed\n"); - } - - /* Select the card, and put it into Transfer Mode */ - if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */ - cmd.cmdidx = MMC_CMD_SELECT_CARD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } - - /* - * For SD, its erase group is always one sector - */ - mmc->erase_grp_size = 1; - mmc->part_config = MMCPART_NOAVAILABLE; - if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { - /* check ext_csd version and capacity */ - err = mmc_send_ext_csd(mmc, ext_csd); - if (!err && (ext_csd[EXT_CSD_REV] >= 2)) { - /* - * According to the JEDEC Standard, the value of - * ext_csd's capacity is valid if the value is more - * than 2GB - */ - capacity = ext_csd[EXT_CSD_SEC_CNT] << 0 - | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 - | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 - | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; - capacity *= MMC_MAX_BLOCK_LEN; - if ((capacity >> 20) > 2 * 1024) - mmc->capacity_user = capacity; - } - - switch (ext_csd[EXT_CSD_REV]) { - case 1: - mmc->version = MMC_VERSION_4_1; - break; - case 2: - mmc->version = MMC_VERSION_4_2; - break; - case 3: - mmc->version = MMC_VERSION_4_3; - break; - case 5: - mmc->version = MMC_VERSION_4_41; - break; - case 6: - mmc->version = MMC_VERSION_4_5; - break; - } - - /* - * Host needs to enable ERASE_GRP_DEF bit if device is - * partitioned. This bit will be lost every time after a reset - * or power off. This will affect erase size. - */ - if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) && - (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) { - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_ERASE_GROUP_DEF, 1); - - if (err) - return err; - - /* Read out group size from ext_csd */ - mmc->erase_grp_size = - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * - MMC_MAX_BLOCK_LEN * 1024; - } else { - /* Calculate the group size from the csd value. */ - int erase_gsz, erase_gmul; - erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10; - erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; - mmc->erase_grp_size = (erase_gsz + 1) - * (erase_gmul + 1); - } - - /* store the partition info of emmc */ - if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || - ext_csd[EXT_CSD_BOOT_MULT]) - mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; - - mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17; - - mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17; - - for (i = 0; i < 4; i++) { - int idx = EXT_CSD_GP_SIZE_MULT + i * 3; - mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) + - (ext_csd[idx + 1] << 8) + ext_csd[idx]; - mmc->capacity_gp[i] *= - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; - mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - } - } - - err = mmc_set_capacity(mmc, mmc->part_num); - if (err) - return err; - - if (IS_SD(mmc)) - err = sd_change_freq(mmc); - else - err = mmc_change_freq(mmc); - - if (err) - return err; - - /* Restrict card's capabilities by what the host can do */ - mmc->card_caps &= mmc->cfg->host_caps; - - if (IS_SD(mmc)) { - if (mmc->card_caps & MMC_MODE_4BIT) { - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 2; - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - - mmc_set_bus_width(mmc, 4); - } - - if (mmc->card_caps & MMC_MODE_HS) - mmc->tran_speed = 50000000; - else - mmc->tran_speed = 25000000; - } else { - int idx; - - /* An array of possible bus widths in order of preference */ - static unsigned ext_csd_bits[] = { - EXT_CSD_BUS_WIDTH_8, - EXT_CSD_BUS_WIDTH_4, - EXT_CSD_BUS_WIDTH_1, - }; - - /* An array to map CSD bus widths to host cap bits */ - static unsigned ext_to_hostcaps[] = { - [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT, - [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT, - }; - - /* An array to map chosen bus width to an integer */ - static unsigned widths[] = { - 8, 4, 1, - }; - - for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) { - unsigned int extw = ext_csd_bits[idx]; - - /* - * Check to make sure the controller supports - * this bus width, if it's more than 1 - */ - if (extw != EXT_CSD_BUS_WIDTH_1 && - !(mmc->cfg->host_caps & ext_to_hostcaps[extw])) - continue; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, extw); - - if (err) - continue; - - mmc_set_bus_width(mmc, widths[idx]); - - err = mmc_send_ext_csd(mmc, test_csd); - if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \ - == test_csd[EXT_CSD_PARTITIONING_SUPPORT] - && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \ - == test_csd[EXT_CSD_ERASE_GROUP_DEF] \ - && ext_csd[EXT_CSD_REV] \ - == test_csd[EXT_CSD_REV] - && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \ - == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] - && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \ - &test_csd[EXT_CSD_SEC_CNT], 4) == 0) { - - mmc->card_caps |= ext_to_hostcaps[extw]; - break; - } - } - - if (mmc->card_caps & MMC_MODE_HS) { - if (mmc->card_caps & MMC_MODE_HS_52MHz) - mmc->tran_speed = 52000000; - else - mmc->tran_speed = 26000000; - } - } - - mmc_set_clock(mmc, mmc->tran_speed); - - /* fill in device description */ - mmc->block_dev.lun = 0; - mmc->block_dev.type = 0; - mmc->block_dev.blksz = mmc->read_bl_len; - mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz); - mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x", - mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff), - (mmc->cid[3] >> 16) & 0xffff); - sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff, - (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff, - (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff, - (mmc->cid[2] >> 24) & 0xff); - sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf, - (mmc->cid[2] >> 16) & 0xf); -#else - mmc->block_dev.vendor[0] = 0; - mmc->block_dev.product[0] = 0; - mmc->block_dev.revision[0] = 0; -#endif -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT) - init_part(&mmc->block_dev); -#endif - - return 0; -} - -static int mmc_send_if_cond(struct mmc *mmc) -{ - struct mmc_cmd cmd; - int err; - - cmd.cmdidx = SD_CMD_SEND_IF_COND; - /* We set the bit if the host supports voltages between 2.7 and 3.6 V */ - cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa; - cmd.resp_type = MMC_RSP_R7; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - if ((cmd.response[0] & 0xff) != 0xaa) - return UNUSABLE_ERR; - else - mmc->version = SD_VERSION_2; - - return 0; -} - -/* not used any more */ -int __deprecated mmc_register(struct mmc *mmc) -{ -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("%s is deprecated! use mmc_create() instead.\n", __func__); -#endif - return -1; -} - -struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) -{ - struct mmc *mmc; - - /* quick validation */ - if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL || - cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0) - return NULL; - - mmc = calloc(1, sizeof(*mmc)); - if (mmc == NULL) - return NULL; - - mmc->cfg = cfg; - mmc->priv = priv; - - /* the following chunk was mmc_register() */ - - /* Setup dsr related values */ - mmc->dsr_imp = 0; - mmc->dsr = 0xffffffff; - /* Setup the universal parts of the block interface just once */ - mmc->block_dev.if_type = IF_TYPE_MMC; - mmc->block_dev.dev = cur_dev_num++; - mmc->block_dev.removable = 1; - mmc->block_dev.block_read = mmc_bread; - mmc->block_dev.block_write = mmc_bwrite; - mmc->block_dev.block_erase = mmc_berase; - - /* setup initial part type */ - mmc->block_dev.part_type = mmc->cfg->part_type; - - INIT_LIST_HEAD(&mmc->link); - - list_add_tail(&mmc->link, &mmc_devices); - - return mmc; -} - -void mmc_destroy(struct mmc *mmc) -{ - /* only freeing memory for now */ - free(mmc); -} - -#ifdef CONFIG_PARTITIONS -block_dev_desc_t *mmc_get_dev(int dev) -{ - struct mmc *mmc = find_mmc_device(dev); - if (!mmc || mmc_init(mmc)) - return NULL; - - return &mmc->block_dev; -} -#endif - -int mmc_start_init(struct mmc *mmc) -{ - int err; - - /* we pretend there's no card when init is NULL */ - if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) { - mmc->has_init = 0; -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("MMC: no card present\n"); -#endif - return NO_CARD_ERR; - } - - if (mmc->has_init) - return 0; - - /* made sure it's not NULL earlier */ - err = mmc->cfg->ops->init(mmc); - - if (err) - return err; - - mmc_set_bus_width(mmc, 1); - mmc_set_clock(mmc, 1); - - /* Reset the Card */ - err = mmc_go_idle(mmc); - - if (err) - return err; - - /* The internal partition reset to user partition(0) at every CMD0*/ - mmc->part_num = 0; - - /* Test for SD version 2 */ - err = mmc_send_if_cond(mmc); - - /* Now try to get the SD card's operating condition */ - err = sd_send_op_cond(mmc); - - /* If the command timed out, we check for an MMC card */ - if (err == TIMEOUT) { - err = mmc_send_op_cond(mmc); - - if (err && err != IN_PROGRESS) { -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("Card did not respond to voltage select!\n"); -#endif - return UNUSABLE_ERR; - } - } - - if (err == IN_PROGRESS) - mmc->init_in_progress = 1; - - return err; -} - -static int mmc_complete_init(struct mmc *mmc) -{ - int err = 0; - - if (mmc->op_cond_pending) - err = mmc_complete_op_cond(mmc); - - if (!err) - err = mmc_startup(mmc); - if (err) - mmc->has_init = 0; - else - mmc->has_init = 1; - mmc->init_in_progress = 0; - return err; -} - -int mmc_init(struct mmc *mmc) -{ - int err = IN_PROGRESS; - unsigned start = get_timer(0); - - if (mmc->has_init) - return 0; - if (!mmc->init_in_progress) - err = mmc_start_init(mmc); - - if (!err || err == IN_PROGRESS) - err = mmc_complete_init(mmc); - debug("%s: %d, time %lu\n", __func__, err, get_timer(start)); - return err; -} - -int mmc_set_dsr(struct mmc *mmc, u16 val) -{ - mmc->dsr = val; - return 0; -} - -/* - * CPU and board-specific MMC initializations. Aliased function - * signals caller to move on - */ -static int __def_mmc_init(bd_t *bis) -{ - return -1; -} - -int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init"))); -int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init"))); - -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - -void print_mmc_devices(char separator) -{ - struct mmc *m; - struct list_head *entry; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - - printf("%s: %d", m->cfg->name, m->block_dev.dev); - - if (entry->next != &mmc_devices) - printf("%c ", separator); - } - - printf("\n"); -} - -#else -void print_mmc_devices(char separator) { } -#endif - -int get_mmc_num(void) -{ - return cur_dev_num; -} - -void mmc_set_preinit(struct mmc *mmc, int preinit) -{ - mmc->preinit = preinit; -} - -static void do_preinit(void) -{ - struct mmc *m; - struct list_head *entry; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - - if (m->preinit) - mmc_start_init(m); - } -} - - -int mmc_initialize(bd_t *bis) -{ - INIT_LIST_HEAD (&mmc_devices); - cur_dev_num = 0; - - if (board_mmc_init(bis) < 0) - cpu_mmc_init(bis); - -#ifndef CONFIG_SPL_BUILD - print_mmc_devices(','); -#endif - - do_preinit(); - return 0; -} - -#ifdef CONFIG_SUPPORT_EMMC_BOOT -/* - * This function changes the size of boot partition and the size of rpmb - * partition present on EMMC devices. - * - * Input Parameters: - * struct *mmc: pointer for the mmc device strcuture - * bootsize: size of boot partition - * rpmbsize: size of rpmb partition - * - * Returns 0 on success. - */ - -int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize, - unsigned long rpmbsize) -{ - int err; - struct mmc_cmd cmd; - - /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */ - cmd.cmdidx = MMC_CMD_RES_MAN; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = MMC_CMD62_ARG1; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) { - debug("mmc_boot_partition_size_change: Error1 = %d\n", err); - return err; - } - - /* Boot partition changing mode */ - cmd.cmdidx = MMC_CMD_RES_MAN; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = MMC_CMD62_ARG2; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) { - debug("mmc_boot_partition_size_change: Error2 = %d\n", err); - return err; - } - /* boot partition size is multiple of 128KB */ - bootsize = (bootsize * 1024) / 128; - - /* Arg: boot partition size */ - cmd.cmdidx = MMC_CMD_RES_MAN; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = bootsize; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) { - debug("mmc_boot_partition_size_change: Error3 = %d\n", err); - return err; - } - /* RPMB partition size is multiple of 128KB */ - rpmbsize = (rpmbsize * 1024) / 128; - /* Arg: RPMB partition size */ - cmd.cmdidx = MMC_CMD_RES_MAN; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = rpmbsize; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) { - debug("mmc_boot_partition_size_change: Error4 = %d\n", err); - return err; - } - return 0; -} - -/* - * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH - * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH - * and BOOT_MODE. - * - * Returns 0 on success. - */ -int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode) -{ - int err; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH, - EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) | - EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) | - EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width)); - - if (err) - return err; - return 0; -} - -/* - * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG) - * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and - * PARTITION_ACCESS. - * - * Returns 0 on success. - */ -int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access) -{ - int err; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, - EXT_CSD_BOOT_ACK(ack) | - EXT_CSD_BOOT_PART_NUM(part_num) | - EXT_CSD_PARTITION_ACCESS(access)); - - if (err) - return err; - return 0; -} - -/* - * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value - * for enable. Note that this is a write-once field for non-zero values. - * - * Returns 0 on success. - */ -int mmc_set_rst_n_function(struct mmc *mmc, u8 enable) -{ - return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION, - enable); -} -#endif diff --git a/qemu/roms/u-boot/drivers/mmc/mmc_private.h b/qemu/roms/u-boot/drivers/mmc/mmc_private.h deleted file mode 100644 index 16dcf9ff6..000000000 --- a/qemu/roms/u-boot/drivers/mmc/mmc_private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2008,2010 Freescale Semiconductor, Inc - * Andy Fleming - * - * Based (loosely) on the Linux code - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _MMC_PRIVATE_H_ -#define _MMC_PRIVATE_H_ - -#include <mmc.h> - -extern int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data); -extern int mmc_send_status(struct mmc *mmc, int timeout); -extern int mmc_set_blocklen(struct mmc *mmc, int len); - -#ifndef CONFIG_SPL_BUILD - -extern unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt); - -extern ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, - const void *src); - -#else /* CONFIG_SPL_BUILD */ - -/* SPL will never write or erase, declare dummies to reduce code size. */ - -static inline unsigned long mmc_berase(int dev_num, lbaint_t start, - lbaint_t blkcnt) -{ - return 0; -} - -static inline ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, - const void *src) -{ - return 0; -} - -#endif /* CONFIG_SPL_BUILD */ - -#endif /* _MMC_PRIVATE_H_ */ diff --git a/qemu/roms/u-boot/drivers/mmc/mmc_spi.c b/qemu/roms/u-boot/drivers/mmc/mmc_spi.c deleted file mode 100644 index 5b5b33a4b..000000000 --- a/qemu/roms/u-boot/drivers/mmc/mmc_spi.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * generic mmc spi driver - * - * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> - * Licensed under the GPL-2 or later. - */ -#include <common.h> -#include <malloc.h> -#include <part.h> -#include <mmc.h> -#include <spi.h> -#include <crc.h> -#include <linux/crc7.h> -#include <linux/byteorder/swab.h> - -/* MMC/SD in SPI mode reports R1 status always */ -#define R1_SPI_IDLE (1 << 0) -#define R1_SPI_ERASE_RESET (1 << 1) -#define R1_SPI_ILLEGAL_COMMAND (1 << 2) -#define R1_SPI_COM_CRC (1 << 3) -#define R1_SPI_ERASE_SEQ (1 << 4) -#define R1_SPI_ADDRESS (1 << 5) -#define R1_SPI_PARAMETER (1 << 6) -/* R1 bit 7 is always zero, reuse this bit for error */ -#define R1_SPI_ERROR (1 << 7) - -/* Response tokens used to ack each block written: */ -#define SPI_MMC_RESPONSE_CODE(x) ((x) & 0x1f) -#define SPI_RESPONSE_ACCEPTED ((2 << 1)|1) -#define SPI_RESPONSE_CRC_ERR ((5 << 1)|1) -#define SPI_RESPONSE_WRITE_ERR ((6 << 1)|1) - -/* Read and write blocks start with these tokens and end with crc; - * on error, read tokens act like a subset of R2_SPI_* values. - */ -#define SPI_TOKEN_SINGLE 0xfe /* single block r/w, multiblock read */ -#define SPI_TOKEN_MULTI_WRITE 0xfc /* multiblock write */ -#define SPI_TOKEN_STOP_TRAN 0xfd /* terminate multiblock write */ - -/* MMC SPI commands start with a start bit "0" and a transmit bit "1" */ -#define MMC_SPI_CMD(x) (0x40 | (x & 0x3f)) - -/* bus capability */ -#define MMC_SPI_VOLTAGE (MMC_VDD_32_33 | MMC_VDD_33_34) -#define MMC_SPI_MIN_CLOCK 400000 /* 400KHz to meet MMC spec */ - -/* timeout value */ -#define CTOUT 8 -#define RTOUT 3000000 /* 1 sec */ -#define WTOUT 3000000 /* 1 sec */ - -static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 cmdarg) -{ - struct spi_slave *spi = mmc->priv; - u8 cmdo[7]; - u8 r1; - int i; - cmdo[0] = 0xff; - cmdo[1] = MMC_SPI_CMD(cmdidx); - cmdo[2] = cmdarg >> 24; - cmdo[3] = cmdarg >> 16; - cmdo[4] = cmdarg >> 8; - cmdo[5] = cmdarg; - cmdo[6] = (crc7(0, &cmdo[1], 5) << 1) | 0x01; - spi_xfer(spi, sizeof(cmdo) * 8, cmdo, NULL, 0); - for (i = 0; i < CTOUT; i++) { - spi_xfer(spi, 1 * 8, NULL, &r1, 0); - if (i && (r1 & 0x80) == 0) /* r1 response */ - break; - } - debug("%s:cmd%d resp%d %x\n", __func__, cmdidx, i, r1); - return r1; -} - -static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf, - u32 bcnt, u32 bsize) -{ - struct spi_slave *spi = mmc->priv; - u8 *buf = xbuf; - u8 r1; - u16 crc; - int i; - while (bcnt--) { - for (i = 0; i < RTOUT; i++) { - spi_xfer(spi, 1 * 8, NULL, &r1, 0); - if (r1 != 0xff) /* data token */ - break; - } - debug("%s:tok%d %x\n", __func__, i, r1); - if (r1 == SPI_TOKEN_SINGLE) { - spi_xfer(spi, bsize * 8, NULL, buf, 0); - spi_xfer(spi, 2 * 8, NULL, &crc, 0); -#ifdef CONFIG_MMC_SPI_CRC_ON - if (swab16(cyg_crc16(buf, bsize)) != crc) { - debug("%s: CRC error\n", mmc->cfg->name); - r1 = R1_SPI_COM_CRC; - break; - } -#endif - r1 = 0; - } else { - r1 = R1_SPI_ERROR; - break; - } - buf += bsize; - } - return r1; -} - -static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf, - u32 bcnt, u32 bsize, int multi) -{ - struct spi_slave *spi = mmc->priv; - const u8 *buf = xbuf; - u8 r1; - u16 crc; - u8 tok[2]; - int i; - tok[0] = 0xff; - tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE; - while (bcnt--) { -#ifdef CONFIG_MMC_SPI_CRC_ON - crc = swab16(cyg_crc16((u8 *)buf, bsize)); -#endif - spi_xfer(spi, 2 * 8, tok, NULL, 0); - spi_xfer(spi, bsize * 8, buf, NULL, 0); - spi_xfer(spi, 2 * 8, &crc, NULL, 0); - for (i = 0; i < CTOUT; i++) { - spi_xfer(spi, 1 * 8, NULL, &r1, 0); - if ((r1 & 0x10) == 0) /* response token */ - break; - } - debug("%s:tok%d %x\n", __func__, i, r1); - if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) { - for (i = 0; i < WTOUT; i++) { /* wait busy */ - spi_xfer(spi, 1 * 8, NULL, &r1, 0); - if (i && r1 == 0xff) { - r1 = 0; - break; - } - } - if (i == WTOUT) { - debug("%s:wtout %x\n", __func__, r1); - r1 = R1_SPI_ERROR; - break; - } - } else { - debug("%s: err %x\n", __func__, r1); - r1 = R1_SPI_COM_CRC; - break; - } - buf += bsize; - } - if (multi && bcnt == -1) { /* stop multi write */ - tok[1] = SPI_TOKEN_STOP_TRAN; - spi_xfer(spi, 2 * 8, tok, NULL, 0); - for (i = 0; i < WTOUT; i++) { /* wait busy */ - spi_xfer(spi, 1 * 8, NULL, &r1, 0); - if (i && r1 == 0xff) { - r1 = 0; - break; - } - } - if (i == WTOUT) { - debug("%s:wstop %x\n", __func__, r1); - r1 = R1_SPI_ERROR; - } - } - return r1; -} - -static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct spi_slave *spi = mmc->priv; - u8 r1; - int i; - int ret = 0; - debug("%s:cmd%d %x %x\n", __func__, - cmd->cmdidx, cmd->resp_type, cmd->cmdarg); - spi_claim_bus(spi); - spi_cs_activate(spi); - r1 = mmc_spi_sendcmd(mmc, cmd->cmdidx, cmd->cmdarg); - if (r1 == 0xff) { /* no response */ - ret = NO_CARD_ERR; - goto done; - } else if (r1 & R1_SPI_COM_CRC) { - ret = COMM_ERR; - goto done; - } else if (r1 & ~R1_SPI_IDLE) { /* other errors */ - ret = TIMEOUT; - goto done; - } else if (cmd->resp_type == MMC_RSP_R2) { - r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16); - for (i = 0; i < 4; i++) - cmd->response[i] = swab32(cmd->response[i]); - debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1], - cmd->response[2], cmd->response[3]); - } else if (!data) { - switch (cmd->cmdidx) { - case SD_CMD_APP_SEND_OP_COND: - case MMC_CMD_SEND_OP_COND: - cmd->response[0] = (r1 & R1_SPI_IDLE) ? 0 : OCR_BUSY; - break; - case SD_CMD_SEND_IF_COND: - case MMC_CMD_SPI_READ_OCR: - spi_xfer(spi, 4 * 8, NULL, cmd->response, 0); - cmd->response[0] = swab32(cmd->response[0]); - debug("r32 %x\n", cmd->response[0]); - break; - case MMC_CMD_SEND_STATUS: - spi_xfer(spi, 1 * 8, NULL, cmd->response, 0); - cmd->response[0] = (cmd->response[0] & 0xff) ? - MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA; - break; - } - } else { - debug("%s:data %x %x %x\n", __func__, - data->flags, data->blocks, data->blocksize); - if (data->flags == MMC_DATA_READ) - r1 = mmc_spi_readdata(mmc, data->dest, - data->blocks, data->blocksize); - else if (data->flags == MMC_DATA_WRITE) - r1 = mmc_spi_writedata(mmc, data->src, - data->blocks, data->blocksize, - (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)); - if (r1 & R1_SPI_COM_CRC) - ret = COMM_ERR; - else if (r1) /* other errors */ - ret = TIMEOUT; - } -done: - spi_cs_deactivate(spi); - spi_release_bus(spi); - return ret; -} - -static void mmc_spi_set_ios(struct mmc *mmc) -{ - struct spi_slave *spi = mmc->priv; - - debug("%s: clock %u\n", __func__, mmc->clock); - if (mmc->clock) - spi_set_speed(spi, mmc->clock); -} - -static int mmc_spi_init_p(struct mmc *mmc) -{ - struct spi_slave *spi = mmc->priv; - spi_set_speed(spi, MMC_SPI_MIN_CLOCK); - spi_claim_bus(spi); - /* cs deactivated for 100+ clock */ - spi_xfer(spi, 18 * 8, NULL, NULL, 0); - spi_release_bus(spi); - return 0; -} - -static const struct mmc_ops mmc_spi_ops = { - .send_cmd = mmc_spi_request, - .set_ios = mmc_spi_set_ios, - .init = mmc_spi_init_p, -}; - -static struct mmc_config mmc_spi_cfg = { - .name = "MMC_SPI", - .ops = &mmc_spi_ops, - .host_caps = MMC_MODE_SPI, - .voltages = MMC_SPI_VOLTAGE, - .f_min = MMC_SPI_MIN_CLOCK, - .part_type = PART_TYPE_DOS, - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, -}; - -struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode) -{ - struct mmc *mmc; - struct spi_slave *spi; - - spi = spi_setup_slave(bus, cs, speed, mode); - if (spi == NULL) - return NULL; - - mmc_spi_cfg.f_max = speed; - - mmc = mmc_create(&mmc_spi_cfg, spi); - if (mmc == NULL) { - spi_free_slave(spi); - return NULL; - } - return mmc; -} diff --git a/qemu/roms/u-boot/drivers/mmc/mmc_write.c b/qemu/roms/u-boot/drivers/mmc/mmc_write.c deleted file mode 100644 index 3db9669c8..000000000 --- a/qemu/roms/u-boot/drivers/mmc/mmc_write.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2008, Freescale Semiconductor, Inc - * Andy Fleming - * - * Based vaguely on the Linux code - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <part.h> -#include "mmc_private.h" - -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) -{ - struct mmc_cmd cmd; - ulong end; - int err, start_cmd, end_cmd; - - if (mmc->high_capacity) { - end = start + blkcnt - 1; - } else { - end = (start + blkcnt - 1) * mmc->write_bl_len; - start *= mmc->write_bl_len; - } - - if (IS_SD(mmc)) { - start_cmd = SD_CMD_ERASE_WR_BLK_START; - end_cmd = SD_CMD_ERASE_WR_BLK_END; - } else { - start_cmd = MMC_CMD_ERASE_GROUP_START; - end_cmd = MMC_CMD_ERASE_GROUP_END; - } - - cmd.cmdidx = start_cmd; - cmd.cmdarg = start; - cmd.resp_type = MMC_RSP_R1; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - cmd.cmdidx = end_cmd; - cmd.cmdarg = end; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - cmd.cmdidx = MMC_CMD_ERASE; - cmd.cmdarg = SECURE_ERASE; - cmd.resp_type = MMC_RSP_R1b; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - return 0; - -err_out: - puts("mmc erase failed\n"); - return err; -} - -unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt) -{ - int err = 0; - struct mmc *mmc = find_mmc_device(dev_num); - lbaint_t blk = 0, blk_r = 0; - int timeout = 1000; - - if (!mmc) - return -1; - - if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size)) - printf("\n\nCaution! Your devices Erase group is 0x%x\n" - "The erase range would be change to " - "0x" LBAF "~0x" LBAF "\n\n", - mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), - ((start + blkcnt + mmc->erase_grp_size) - & ~(mmc->erase_grp_size - 1)) - 1); - - while (blk < blkcnt) { - blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? - mmc->erase_grp_size : (blkcnt - blk); - err = mmc_erase_t(mmc, start + blk, blk_r); - if (err) - break; - - blk += blk_r; - - /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) - return 0; - } - - return blk; -} - -static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start, - lbaint_t blkcnt, const void *src) -{ - struct mmc_cmd cmd; - struct mmc_data data; - int timeout = 1000; - - if ((start + blkcnt) > mmc->block_dev.lba) { - printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n", - start + blkcnt, mmc->block_dev.lba); - return 0; - } - - if (blkcnt == 0) - return 0; - else if (blkcnt == 1) - cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK; - else - cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; - - if (mmc->high_capacity) - cmd.cmdarg = start; - else - cmd.cmdarg = start * mmc->write_bl_len; - - cmd.resp_type = MMC_RSP_R1; - - data.src = src; - data.blocks = blkcnt; - data.blocksize = mmc->write_bl_len; - data.flags = MMC_DATA_WRITE; - - if (mmc_send_cmd(mmc, &cmd, &data)) { - printf("mmc write failed\n"); - return 0; - } - - /* SPI multiblock writes terminate using a special - * token, not a STOP_TRANSMISSION request. - */ - if (!mmc_host_is_spi(mmc) && blkcnt > 1) { - cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_R1b; - if (mmc_send_cmd(mmc, &cmd, NULL)) { - printf("mmc fail to send stop cmd\n"); - return 0; - } - } - - /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) - return 0; - - return blkcnt; -} - -ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void *src) -{ - lbaint_t cur, blocks_todo = blkcnt; - - struct mmc *mmc = find_mmc_device(dev_num); - if (!mmc) - return 0; - - if (mmc_set_blocklen(mmc, mmc->write_bl_len)) - return 0; - - do { - cur = (blocks_todo > mmc->cfg->b_max) ? - mmc->cfg->b_max : blocks_todo; - if (mmc_write_blocks(mmc, start, cur, src) != cur) - return 0; - blocks_todo -= cur; - start += cur; - src += cur * mmc->write_bl_len; - } while (blocks_todo > 0); - - return blkcnt; -} diff --git a/qemu/roms/u-boot/drivers/mmc/mv_sdhci.c b/qemu/roms/u-boot/drivers/mmc/mv_sdhci.c deleted file mode 100644 index 63e1f9062..000000000 --- a/qemu/roms/u-boot/drivers/mmc/mv_sdhci.c +++ /dev/null @@ -1,55 +0,0 @@ -#include <common.h> -#include <malloc.h> -#include <sdhci.h> - -#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS -static struct sdhci_ops mv_ops; - -#if defined(CONFIG_SHEEVA_88SV331xV5) -#define SD_CE_ATA_2 0xEA -#define MMC_CARD 0x1000 -#define MMC_WIDTH 0x0100 -static inline void mv_sdhci_writeb(struct sdhci_host *host, u8 val, int reg) -{ - struct mmc *mmc = host->mmc; - u32 ata = (u32)host->ioaddr + SD_CE_ATA_2; - - if (!IS_SD(mmc) && reg == SDHCI_HOST_CONTROL) { - if (mmc->bus_width == 8) - writew(readw(ata) | (MMC_CARD | MMC_WIDTH), ata); - else - writew(readw(ata) & ~(MMC_CARD | MMC_WIDTH), ata); - } - - writeb(val, host->ioaddr + reg); -} - -#else -#define mv_sdhci_writeb NULL -#endif /* CONFIG_SHEEVA_88SV331xV5 */ -#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */ - -static char *MVSDH_NAME = "mv_sdh"; -int mv_sdh_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) -{ - struct sdhci_host *host = NULL; - host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); - if (!host) { - printf("sdh_host malloc fail!\n"); - return 1; - } - - host->name = MVSDH_NAME; - host->ioaddr = (void *)regbase; - host->quirks = quirks; -#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS - memset(&mv_ops, 0, sizeof(struct sdhci_ops)); - mv_ops.write_b = mv_sdhci_writeb; - host->ops = &mv_ops; -#endif - if (quirks & SDHCI_QUIRK_REG32_RW) - host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16; - else - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - return add_sdhci(host, max_clk, min_clk); -} diff --git a/qemu/roms/u-boot/drivers/mmc/mxcmmc.c b/qemu/roms/u-boot/drivers/mmc/mxcmmc.c deleted file mode 100644 index 561b20459..000000000 --- a/qemu/roms/u-boot/drivers/mmc/mxcmmc.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - * This is a driver for the SDHC controller found in Freescale MX2/MX3 - * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). - * Unlike the hardware found on MX1, this hardware just works and does - * not need all the quirks found in imxmmc.c, hence the seperate driver. - * - * Copyright (C) 2009 Ilya Yanok, <yanok@emcraft.com> - * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> - * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> - * - * derived from pxamci.c by Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include <config.h> -#include <common.h> -#include <command.h> -#include <mmc.h> -#include <part.h> -#include <malloc.h> -#include <mmc.h> -#include <asm/errno.h> -#include <asm/io.h> -#include <asm/arch/clock.h> - -#define DRIVER_NAME "mxc-mmc" - -struct mxcmci_regs { - u32 str_stp_clk; - u32 status; - u32 clk_rate; - u32 cmd_dat_cont; - u32 res_to; - u32 read_to; - u32 blk_len; - u32 nob; - u32 rev_no; - u32 int_cntr; - u32 cmd; - u32 arg; - u32 pad; - u32 res_fifo; - u32 buffer_access; -}; - -#define STR_STP_CLK_RESET (1 << 3) -#define STR_STP_CLK_START_CLK (1 << 1) -#define STR_STP_CLK_STOP_CLK (1 << 0) - -#define STATUS_CARD_INSERTION (1 << 31) -#define STATUS_CARD_REMOVAL (1 << 30) -#define STATUS_YBUF_EMPTY (1 << 29) -#define STATUS_XBUF_EMPTY (1 << 28) -#define STATUS_YBUF_FULL (1 << 27) -#define STATUS_XBUF_FULL (1 << 26) -#define STATUS_BUF_UND_RUN (1 << 25) -#define STATUS_BUF_OVFL (1 << 24) -#define STATUS_SDIO_INT_ACTIVE (1 << 14) -#define STATUS_END_CMD_RESP (1 << 13) -#define STATUS_WRITE_OP_DONE (1 << 12) -#define STATUS_DATA_TRANS_DONE (1 << 11) -#define STATUS_READ_OP_DONE (1 << 11) -#define STATUS_WR_CRC_ERROR_CODE_MASK (3 << 10) -#define STATUS_CARD_BUS_CLK_RUN (1 << 8) -#define STATUS_BUF_READ_RDY (1 << 7) -#define STATUS_BUF_WRITE_RDY (1 << 6) -#define STATUS_RESP_CRC_ERR (1 << 5) -#define STATUS_CRC_READ_ERR (1 << 3) -#define STATUS_CRC_WRITE_ERR (1 << 2) -#define STATUS_TIME_OUT_RESP (1 << 1) -#define STATUS_TIME_OUT_READ (1 << 0) -#define STATUS_ERR_MASK 0x2f - -#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1 << 12) -#define CMD_DAT_CONT_STOP_READWAIT (1 << 11) -#define CMD_DAT_CONT_START_READWAIT (1 << 10) -#define CMD_DAT_CONT_BUS_WIDTH_4 (2 << 8) -#define CMD_DAT_CONT_INIT (1 << 7) -#define CMD_DAT_CONT_WRITE (1 << 4) -#define CMD_DAT_CONT_DATA_ENABLE (1 << 3) -#define CMD_DAT_CONT_RESPONSE_48BIT_CRC (1 << 0) -#define CMD_DAT_CONT_RESPONSE_136BIT (2 << 0) -#define CMD_DAT_CONT_RESPONSE_48BIT (3 << 0) - -#define INT_SDIO_INT_WKP_EN (1 << 18) -#define INT_CARD_INSERTION_WKP_EN (1 << 17) -#define INT_CARD_REMOVAL_WKP_EN (1 << 16) -#define INT_CARD_INSERTION_EN (1 << 15) -#define INT_CARD_REMOVAL_EN (1 << 14) -#define INT_SDIO_IRQ_EN (1 << 13) -#define INT_DAT0_EN (1 << 12) -#define INT_BUF_READ_EN (1 << 4) -#define INT_BUF_WRITE_EN (1 << 3) -#define INT_END_CMD_RES_EN (1 << 2) -#define INT_WRITE_OP_DONE_EN (1 << 1) -#define INT_READ_OP_EN (1 << 0) - -struct mxcmci_host { - struct mmc *mmc; - struct mxcmci_regs *base; - int irq; - int detect_irq; - int dma; - int do_dma; - unsigned int power_mode; - - struct mmc_cmd *cmd; - struct mmc_data *data; - - unsigned int dma_nents; - unsigned int datasize; - unsigned int dma_dir; - - u16 rev_no; - unsigned int cmdat; - - int clock; -}; - -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) -{ - return host->do_dma; -} - -static void mxcmci_softreset(struct mxcmci_host *host) -{ - int i; - - /* reset sequence */ - 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++) - writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk); - - writel(0xff, &host->base->res_to); -} - -static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) -{ - unsigned int nob = data->blocks; - unsigned int blksz = data->blocksize; - unsigned int datasize = nob * blksz; - - host->data = data; - - writel(nob, &host->base->nob); - writel(blksz, &host->base->blk_len); - host->datasize = datasize; -} - -static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_cmd *cmd, - unsigned int cmdat) -{ - if (host->cmd != NULL) - printf("mxcmci: error!\n"); - host->cmd = cmd; - - switch (cmd->resp_type) { - case MMC_RSP_R1: /* short CRC, OPCODE */ - case MMC_RSP_R1b:/* short CRC, OPCODE, BUSY */ - cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC; - break; - case MMC_RSP_R2: /* long 136 bit + CRC */ - cmdat |= CMD_DAT_CONT_RESPONSE_136BIT; - break; - case MMC_RSP_R3: /* short */ - cmdat |= CMD_DAT_CONT_RESPONSE_48BIT; - break; - case MMC_RSP_NONE: - break; - default: - printf("mxcmci: unhandled response type 0x%x\n", - cmd->resp_type); - return -EINVAL; - } - - writel(cmd->cmdidx, &host->base->cmd); - writel(cmd->cmdarg, &host->base->arg); - writel(cmdat, &host->base->cmd_dat_cont); - - return 0; -} - -static void mxcmci_finish_request(struct mxcmci_host *host, - struct mmc_cmd *cmd, struct mmc_data *data) -{ - host->cmd = NULL; - host->data = NULL; -} - -static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) -{ - int data_error = 0; - - if (stat & STATUS_ERR_MASK) { - printf("request failed. status: 0x%08x\n", - stat); - if (stat & STATUS_CRC_READ_ERR) { - data_error = -EILSEQ; - } else if (stat & STATUS_CRC_WRITE_ERR) { - u32 err_code = (stat >> 9) & 0x3; - if (err_code == 2) /* No CRC response */ - data_error = TIMEOUT; - else - data_error = -EILSEQ; - } else if (stat & STATUS_TIME_OUT_READ) { - data_error = TIMEOUT; - } else { - data_error = -EIO; - } - } - - host->data = NULL; - - return data_error; -} - -static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat) -{ - struct mmc_cmd *cmd = host->cmd; - int i; - u32 a, b, c; - u32 *resp = (u32 *)cmd->response; - - if (!cmd) - return 0; - - if (stat & STATUS_TIME_OUT_RESP) { - printf("CMD TIMEOUT\n"); - return TIMEOUT; - } else if (stat & STATUS_RESP_CRC_ERR && cmd->resp_type & MMC_RSP_CRC) { - printf("cmd crc error\n"); - return -EILSEQ; - } - - if (cmd->resp_type & MMC_RSP_PRESENT) { - if (cmd->resp_type & MMC_RSP_136) { - for (i = 0; i < 4; i++) { - a = readl(&host->base->res_fifo) & 0xFFFF; - b = readl(&host->base->res_fifo) & 0xFFFF; - resp[i] = a << 16 | b; - } - } else { - 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; - } - } - return 0; -} - -static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask) -{ - u32 stat; - unsigned long timeout = get_ticks() + CONFIG_SYS_HZ; - - do { - stat = readl(&host->base->status); - if (stat & STATUS_ERR_MASK) - return stat; - if (timeout < get_ticks()) - return STATUS_TIME_OUT_READ; - if (stat & mask) - return 0; - } while (1); -} - -static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes) -{ - unsigned int stat; - u32 *buf = _buf; - - while (bytes > 3) { - stat = mxcmci_poll_status(host, - STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE); - if (stat) - return stat; - *buf++ = readl(&host->base->buffer_access); - bytes -= 4; - } - - if (bytes) { - u8 *b = (u8 *)buf; - u32 tmp; - - stat = mxcmci_poll_status(host, - STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE); - if (stat) - return stat; - tmp = readl(&host->base->buffer_access); - memcpy(b, &tmp, bytes); - } - - return 0; -} - -static int mxcmci_push(struct mxcmci_host *host, const void *_buf, int bytes) -{ - unsigned int stat; - const u32 *buf = _buf; - - while (bytes > 3) { - stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); - if (stat) - return stat; - writel(*buf++, &host->base->buffer_access); - bytes -= 4; - } - - if (bytes) { - const u8 *b = (u8 *)buf; - u32 tmp; - - stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); - if (stat) - return stat; - - memcpy(&tmp, b, bytes); - writel(tmp, &host->base->buffer_access); - } - - stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); - if (stat) - return stat; - - return 0; -} - -static int mxcmci_transfer_data(struct mxcmci_host *host) -{ - struct mmc_data *data = host->data; - int stat; - unsigned long length; - - length = data->blocks * data->blocksize; - host->datasize = 0; - - if (data->flags & MMC_DATA_READ) { - stat = mxcmci_pull(host, data->dest, length); - if (stat) - return stat; - host->datasize += length; - } else { - stat = mxcmci_push(host, (const void *)(data->src), length); - if (stat) - return stat; - host->datasize += length; - stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE); - if (stat) - return stat; - } - return 0; -} - -static int mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) -{ - int datastat; - int ret; - - ret = mxcmci_read_response(host, stat); - - if (ret) { - mxcmci_finish_request(host, host->cmd, host->data); - return ret; - } - - if (!host->data) { - mxcmci_finish_request(host, host->cmd, host->data); - return 0; - } - - datastat = mxcmci_transfer_data(host); - ret = mxcmci_finish_data(host, datastat); - mxcmci_finish_request(host, host->cmd, host->data); - return ret; -} - -static int mxcmci_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct mxcmci_host *host = mmc->priv; - unsigned int cmdat = host->cmdat; - u32 stat; - int ret; - - host->cmdat &= ~CMD_DAT_CONT_INIT; - if (data) { - mxcmci_setup_data(host, data); - - cmdat |= CMD_DAT_CONT_DATA_ENABLE; - - if (data->flags & MMC_DATA_WRITE) - cmdat |= CMD_DAT_CONT_WRITE; - } - - if ((ret = mxcmci_start_cmd(host, cmd, cmdat))) { - mxcmci_finish_request(host, cmd, data); - return ret; - } - - do { - stat = readl(&host->base->status); - writel(stat, &host->base->status); - } while (!(stat & STATUS_END_CMD_RESP)); - - return mxcmci_cmd_done(host, stat); -} - -static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios) -{ - unsigned int divider; - int prescaler = 0; - unsigned long clk_in = mxc_get_clock(MXC_ESDHC_CLK); - - while (prescaler <= 0x800) { - for (divider = 1; divider <= 0xF; divider++) { - int x; - - x = (clk_in / (divider + 1)); - - if (prescaler) - x /= (prescaler * 2); - - if (x <= clk_ios) - break; - } - if (divider < 0x10) - break; - - if (prescaler == 0) - prescaler = 1; - else - prescaler <<= 1; - } - - writel((prescaler << 4) | divider, &host->base->clk_rate); -} - -static void mxcmci_set_ios(struct mmc *mmc) -{ - struct mxcmci_host *host = mmc->priv; - if (mmc->bus_width == 4) - host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; - else - host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4; - - if (mmc->clock) { - mxcmci_set_clk_rate(host, mmc->clock); - writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk); - } else { - writel(STR_STP_CLK_STOP_CLK, &host->base->str_stp_clk); - } - - host->clock = mmc->clock; -} - -static int mxcmci_init(struct mmc *mmc) -{ - struct mxcmci_host *host = mmc->priv; - - mxcmci_softreset(host); - - host->rev_no = readl(&host->base->rev_no); - if (host->rev_no != 0x400) { - printf("wrong rev.no. 0x%08x. aborting.\n", - host->rev_no); - return -ENODEV; - } - - /* recommended in data sheet */ - writel(0x2db4, &host->base->read_to); - - writel(0, &host->base->int_cntr); - - return 0; -} - -static const struct mmc_ops mxcmci_ops = { - .send_cmd = mxcmci_request, - .set_ios = mxcmci_set_ios, - .init = mxcmci_init, -}; - -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; - - mxcmci_cfg.f_min = mxc_get_clock(MXC_ESDHC_CLK) >> 7; - mxcmci_cfg.f_max = mxc_get_clock(MXC_ESDHC_CLK) >> 1; - - host->mmc = mmc_create(&mxcmci_cfg, host); - if (host->mmc == NULL) - return -1; - - return 0; -} - -int mxc_mmc_init(bd_t *bis) -{ - return mxcmci_initialize(bis); -} diff --git a/qemu/roms/u-boot/drivers/mmc/mxsmmc.c b/qemu/roms/u-boot/drivers/mmc/mxsmmc.c deleted file mode 100644 index 2fa4eeef4..000000000 --- a/qemu/roms/u-boot/drivers/mmc/mxsmmc.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Freescale i.MX28 SSP MMC driver - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * Based on code from LTIB: - * (C) Copyright 2008-2010 Freescale Semiconductor, Inc. - * Terry Lv - * - * Copyright 2007, Freescale Semiconductor, Inc - * Andy Fleming - * - * Based vaguely on the pxa mmc code: - * (C) Copyright 2003 - * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <malloc.h> -#include <mmc.h> -#include <asm/errno.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/sys_proto.h> -#include <asm/imx-common/dma.h> -#include <bouncebuf.h> - -struct mxsmmc_priv { - int id; - struct mxs_ssp_regs *regs; - uint32_t buswidth; - int (*mmc_is_wp)(int); - int (*mmc_cd)(int); - struct mxs_dma_desc *desc; - struct mmc_config cfg; /* mmc configuration */ -}; - -#define MXSMMC_MAX_TIMEOUT 10000 -#define MXSMMC_SMALL_TRANSFER 512 - -static int mxsmmc_cd(struct mxsmmc_priv *priv) -{ - struct mxs_ssp_regs *ssp_regs = priv->regs; - - if (priv->mmc_cd) - return priv->mmc_cd(priv->id); - - return !(readl(&ssp_regs->hw_ssp_status) & SSP_STATUS_CARD_DETECT); -} - -static int mxsmmc_send_cmd_pio(struct mxsmmc_priv *priv, struct mmc_data *data) -{ - struct mxs_ssp_regs *ssp_regs = priv->regs; - uint32_t *data_ptr; - int timeout = MXSMMC_MAX_TIMEOUT; - uint32_t reg; - uint32_t data_count = data->blocksize * data->blocks; - - if (data->flags & MMC_DATA_READ) { - data_ptr = (uint32_t *)data->dest; - while (data_count && --timeout) { - reg = readl(&ssp_regs->hw_ssp_status); - if (!(reg & SSP_STATUS_FIFO_EMPTY)) { - *data_ptr++ = readl(&ssp_regs->hw_ssp_data); - data_count -= 4; - timeout = MXSMMC_MAX_TIMEOUT; - } else - udelay(1000); - } - } else { - data_ptr = (uint32_t *)data->src; - timeout *= 100; - while (data_count && --timeout) { - reg = readl(&ssp_regs->hw_ssp_status); - if (!(reg & SSP_STATUS_FIFO_FULL)) { - writel(*data_ptr++, &ssp_regs->hw_ssp_data); - data_count -= 4; - timeout = MXSMMC_MAX_TIMEOUT; - } else - udelay(1000); - } - } - - return timeout ? 0 : COMM_ERR; -} - -static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data) -{ - uint32_t data_count = data->blocksize * data->blocks; - int dmach; - struct mxs_dma_desc *desc = priv->desc; - void *addr; - unsigned int flags; - struct bounce_buffer bbstate; - - memset(desc, 0, sizeof(struct mxs_dma_desc)); - desc->address = (dma_addr_t)desc; - - if (data->flags & MMC_DATA_READ) { - priv->desc->cmd.data = MXS_DMA_DESC_COMMAND_DMA_WRITE; - addr = data->dest; - flags = GEN_BB_WRITE; - } else { - priv->desc->cmd.data = MXS_DMA_DESC_COMMAND_DMA_READ; - addr = (void *)data->src; - flags = GEN_BB_READ; - } - - bounce_buffer_start(&bbstate, addr, data_count, flags); - - priv->desc->cmd.address = (dma_addr_t)bbstate.bounce_buffer; - - priv->desc->cmd.data |= MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM | - (data_count << MXS_DMA_DESC_BYTES_OFFSET); - - dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->id; - mxs_dma_desc_append(dmach, priv->desc); - if (mxs_dma_go(dmach)) { - bounce_buffer_stop(&bbstate); - return COMM_ERR; - } - - bounce_buffer_stop(&bbstate); - - return 0; -} - -/* - * Sends a command out on the bus. Takes the mmc pointer, - * a command pointer, and an optional data pointer. - */ -static int -mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) -{ - struct mxsmmc_priv *priv = mmc->priv; - struct mxs_ssp_regs *ssp_regs = priv->regs; - uint32_t reg; - int timeout; - uint32_t ctrl0; - int ret; - - debug("MMC%d: CMD%d\n", mmc->block_dev.dev, cmd->cmdidx); - - /* Check bus busy */ - timeout = MXSMMC_MAX_TIMEOUT; - while (--timeout) { - udelay(1000); - reg = readl(&ssp_regs->hw_ssp_status); - if (!(reg & - (SSP_STATUS_BUSY | SSP_STATUS_DATA_BUSY | - SSP_STATUS_CMD_BUSY))) { - break; - } - } - - if (!timeout) { - printf("MMC%d: Bus busy timeout!\n", mmc->block_dev.dev); - return TIMEOUT; - } - - /* See if card is present */ - if (!mxsmmc_cd(priv)) { - printf("MMC%d: No card detected!\n", mmc->block_dev.dev); - return NO_CARD_ERR; - } - - /* Start building CTRL0 contents */ - ctrl0 = priv->buswidth; - - /* Set up command */ - if (!(cmd->resp_type & MMC_RSP_CRC)) - ctrl0 |= SSP_CTRL0_IGNORE_CRC; - if (cmd->resp_type & MMC_RSP_PRESENT) /* Need to get response */ - ctrl0 |= SSP_CTRL0_GET_RESP; - if (cmd->resp_type & MMC_RSP_136) /* It's a 136 bits response */ - ctrl0 |= SSP_CTRL0_LONG_RESP; - - if (data && (data->blocksize * data->blocks < MXSMMC_SMALL_TRANSFER)) - writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr); - else - writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set); - - /* Command index */ - reg = readl(&ssp_regs->hw_ssp_cmd0); - reg &= ~(SSP_CMD0_CMD_MASK | SSP_CMD0_APPEND_8CYC); - reg |= cmd->cmdidx << SSP_CMD0_CMD_OFFSET; - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) - reg |= SSP_CMD0_APPEND_8CYC; - writel(reg, &ssp_regs->hw_ssp_cmd0); - - /* Command argument */ - writel(cmd->cmdarg, &ssp_regs->hw_ssp_cmd1); - - /* Set up data */ - if (data) { - /* READ or WRITE */ - if (data->flags & MMC_DATA_READ) { - ctrl0 |= SSP_CTRL0_READ; - } else if (priv->mmc_is_wp && - priv->mmc_is_wp(mmc->block_dev.dev)) { - printf("MMC%d: Can not write a locked card!\n", - mmc->block_dev.dev); - return UNUSABLE_ERR; - } - - ctrl0 |= SSP_CTRL0_DATA_XFER; - - reg = data->blocksize * data->blocks; -#if defined(CONFIG_MX23) - ctrl0 |= reg & SSP_CTRL0_XFER_COUNT_MASK; - - clrsetbits_le32(&ssp_regs->hw_ssp_cmd0, - SSP_CMD0_BLOCK_SIZE_MASK | SSP_CMD0_BLOCK_COUNT_MASK, - ((data->blocks - 1) << SSP_CMD0_BLOCK_COUNT_OFFSET) | - ((ffs(data->blocksize) - 1) << - SSP_CMD0_BLOCK_SIZE_OFFSET)); -#elif defined(CONFIG_MX28) - writel(reg, &ssp_regs->hw_ssp_xfer_size); - - reg = ((data->blocks - 1) << - SSP_BLOCK_SIZE_BLOCK_COUNT_OFFSET) | - ((ffs(data->blocksize) - 1) << - SSP_BLOCK_SIZE_BLOCK_SIZE_OFFSET); - writel(reg, &ssp_regs->hw_ssp_block_size); -#endif - } - - /* Kick off the command */ - ctrl0 |= SSP_CTRL0_WAIT_FOR_IRQ | SSP_CTRL0_ENABLE | SSP_CTRL0_RUN; - writel(ctrl0, &ssp_regs->hw_ssp_ctrl0); - - /* Wait for the command to complete */ - timeout = MXSMMC_MAX_TIMEOUT; - while (--timeout) { - udelay(1000); - reg = readl(&ssp_regs->hw_ssp_status); - if (!(reg & SSP_STATUS_CMD_BUSY)) - break; - } - - if (!timeout) { - printf("MMC%d: Command %d busy\n", - mmc->block_dev.dev, cmd->cmdidx); - return TIMEOUT; - } - - /* Check command timeout */ - if (reg & SSP_STATUS_RESP_TIMEOUT) { - printf("MMC%d: Command %d timeout (status 0x%08x)\n", - mmc->block_dev.dev, cmd->cmdidx, reg); - return TIMEOUT; - } - - /* Check command errors */ - if (reg & (SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR)) { - printf("MMC%d: Command %d error (status 0x%08x)!\n", - mmc->block_dev.dev, cmd->cmdidx, reg); - return COMM_ERR; - } - - /* Copy response to response buffer */ - if (cmd->resp_type & MMC_RSP_136) { - cmd->response[3] = readl(&ssp_regs->hw_ssp_sdresp0); - cmd->response[2] = readl(&ssp_regs->hw_ssp_sdresp1); - cmd->response[1] = readl(&ssp_regs->hw_ssp_sdresp2); - cmd->response[0] = readl(&ssp_regs->hw_ssp_sdresp3); - } else - cmd->response[0] = readl(&ssp_regs->hw_ssp_sdresp0); - - /* Return if no data to process */ - if (!data) - return 0; - - if (data->blocksize * data->blocks < MXSMMC_SMALL_TRANSFER) { - ret = mxsmmc_send_cmd_pio(priv, data); - if (ret) { - printf("MMC%d: Data timeout with command %d " - "(status 0x%08x)!\n", - mmc->block_dev.dev, cmd->cmdidx, reg); - return ret; - } - } else { - ret = mxsmmc_send_cmd_dma(priv, data); - if (ret) { - printf("MMC%d: DMA transfer failed\n", - mmc->block_dev.dev); - return ret; - } - } - - /* Check data errors */ - reg = readl(&ssp_regs->hw_ssp_status); - if (reg & - (SSP_STATUS_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | - SSP_STATUS_FIFO_OVRFLW | SSP_STATUS_FIFO_UNDRFLW)) { - printf("MMC%d: Data error with command %d (status 0x%08x)!\n", - mmc->block_dev.dev, cmd->cmdidx, reg); - return COMM_ERR; - } - - return 0; -} - -static void mxsmmc_set_ios(struct mmc *mmc) -{ - struct mxsmmc_priv *priv = mmc->priv; - struct mxs_ssp_regs *ssp_regs = priv->regs; - - /* Set the clock speed */ - if (mmc->clock) - mxs_set_ssp_busclock(priv->id, mmc->clock / 1000); - - switch (mmc->bus_width) { - case 1: - priv->buswidth = SSP_CTRL0_BUS_WIDTH_ONE_BIT; - break; - case 4: - priv->buswidth = SSP_CTRL0_BUS_WIDTH_FOUR_BIT; - break; - case 8: - priv->buswidth = SSP_CTRL0_BUS_WIDTH_EIGHT_BIT; - break; - } - - /* Set the bus width */ - clrsetbits_le32(&ssp_regs->hw_ssp_ctrl0, - SSP_CTRL0_BUS_WIDTH_MASK, priv->buswidth); - - debug("MMC%d: Set %d bits bus width\n", - mmc->block_dev.dev, mmc->bus_width); -} - -static int mxsmmc_init(struct mmc *mmc) -{ - struct mxsmmc_priv *priv = mmc->priv; - struct mxs_ssp_regs *ssp_regs = priv->regs; - - /* Reset SSP */ - mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg); - - /* Reconfigure the SSP block for MMC operation */ - writel(SSP_CTRL1_SSP_MODE_SD_MMC | - SSP_CTRL1_WORD_LENGTH_EIGHT_BITS | - SSP_CTRL1_DMA_ENABLE | - SSP_CTRL1_POLARITY | - SSP_CTRL1_RECV_TIMEOUT_IRQ_EN | - SSP_CTRL1_DATA_CRC_IRQ_EN | - SSP_CTRL1_DATA_TIMEOUT_IRQ_EN | - SSP_CTRL1_RESP_TIMEOUT_IRQ_EN | - SSP_CTRL1_RESP_ERR_IRQ_EN, - &ssp_regs->hw_ssp_ctrl1_set); - - /* Set initial bit clock 400 KHz */ - mxs_set_ssp_busclock(priv->id, 400); - - /* Send initial 74 clock cycles (185 us @ 400 KHz)*/ - writel(SSP_CMD0_CONT_CLKING_EN, &ssp_regs->hw_ssp_cmd0_set); - udelay(200); - writel(SSP_CMD0_CONT_CLKING_EN, &ssp_regs->hw_ssp_cmd0_clr); - - return 0; -} - -static const struct mmc_ops mxsmmc_ops = { - .send_cmd = mxsmmc_send_cmd, - .set_ios = mxsmmc_set_ios, - .init = mxsmmc_init, -}; - -int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int)) -{ - struct mmc *mmc = NULL; - struct mxsmmc_priv *priv = NULL; - int ret; - const unsigned int mxsmmc_clk_id = mxs_ssp_clock_by_bus(id); - - if (!mxs_ssp_bus_id_valid(id)) - return -ENODEV; - - priv = malloc(sizeof(struct mxsmmc_priv)); - if (!priv) - return -ENOMEM; - - priv->desc = mxs_dma_desc_alloc(); - if (!priv->desc) { - free(priv); - return -ENOMEM; - } - - ret = mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + id); - if (ret) - return ret; - - priv->mmc_is_wp = wp; - priv->mmc_cd = cd; - priv->id = id; - priv->regs = mxs_ssp_regs_by_bus(id); - - priv->cfg.name = "MXS MMC"; - priv->cfg.ops = &mxsmmc_ops; - - priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; - - priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | - MMC_MODE_HS_52MHz | MMC_MODE_HS | - MMC_MODE_HC; - - /* - * SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz - * SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)), - * CLOCK_DIVIDE has to be an even value from 2 to 254, and - * CLOCK_RATE could be any integer from 0 to 255. - */ - priv->cfg.f_min = 400000; - priv->cfg.f_max = mxc_get_clock(MXC_SSP0_CLK + mxsmmc_clk_id) * 1000 / 2; - priv->cfg.b_max = 0x20; - - mmc = mmc_create(&priv->cfg, priv); - if (mmc == NULL) { - mxs_dma_desc_free(priv->desc); - free(priv); - return -ENOMEM; - } - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/omap_hsmmc.c b/qemu/roms/u-boot/drivers/mmc/omap_hsmmc.c deleted file mode 100644 index 17cbb0983..000000000 --- a/qemu/roms/u-boot/drivers/mmc/omap_hsmmc.c +++ /dev/null @@ -1,720 +0,0 @@ -/* - * (C) Copyright 2008 - * Texas Instruments, <www.ti.com> - * Sukumar Ghorai <s-ghorai@ti.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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's version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <config.h> -#include <common.h> -#include <malloc.h> -#include <mmc.h> -#include <part.h> -#include <i2c.h> -#include <twl4030.h> -#include <twl6030.h> -#include <palmas.h> -#include <asm/gpio.h> -#include <asm/io.h> -#include <asm/arch/mmc_host_def.h> -#include <asm/arch/sys_proto.h> - -/* simplify defines to OMAP_HSMMC_USE_GPIO */ -#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \ - (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT)) -#define OMAP_HSMMC_USE_GPIO -#else -#undef OMAP_HSMMC_USE_GPIO -#endif - -/* common definitions for all OMAPs */ -#define SYSCTL_SRC (1 << 25) -#define SYSCTL_SRD (1 << 26) - -struct omap_hsmmc_data { - struct hsmmc *base_addr; - struct mmc_config cfg; -#ifdef OMAP_HSMMC_USE_GPIO - int cd_gpio; - int wp_gpio; -#endif -}; - -/* If we fail after 1 second wait, something is really bad */ -#define MAX_RETRY_MS 1000 - -static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size); -static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, - unsigned int siz); - -#ifdef OMAP_HSMMC_USE_GPIO -static int omap_mmc_setup_gpio_in(int gpio, const char *label) -{ - if (!gpio_is_valid(gpio)) - return -1; - - if (gpio_request(gpio, label) < 0) - return -1; - - if (gpio_direction_input(gpio) < 0) - return -1; - - return gpio; -} -#endif - -#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER) -static void omap4_vmmc_pbias_config(struct mmc *mmc) -{ - u32 value = 0; - - value = readl((*ctrl)->control_pbiaslite); - value &= ~(MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ); - writel(value, (*ctrl)->control_pbiaslite); - /* set VMMC to 3V */ - twl6030_power_mmc_init(); - value = readl((*ctrl)->control_pbiaslite); - value |= MMC1_PBIASLITE_VMODE | MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ; - writel(value, (*ctrl)->control_pbiaslite); -} -#endif - -#if defined(CONFIG_OMAP54XX) && defined(CONFIG_PALMAS_POWER) -static void omap5_pbias_config(struct mmc *mmc) -{ - u32 value = 0; - - value = readl((*ctrl)->control_pbias); - value &= ~SDCARD_PWRDNZ; - writel(value, (*ctrl)->control_pbias); - udelay(10); /* wait 10 us */ - value &= ~SDCARD_BIAS_PWRDNZ; - writel(value, (*ctrl)->control_pbias); - - palmas_mmc1_poweron_ldo(); - - value = readl((*ctrl)->control_pbias); - value |= SDCARD_BIAS_PWRDNZ; - writel(value, (*ctrl)->control_pbias); - udelay(150); /* wait 150 us */ - value |= SDCARD_PWRDNZ; - writel(value, (*ctrl)->control_pbias); - udelay(150); /* wait 150 us */ -} -#endif - -unsigned char mmc_board_init(struct mmc *mmc) -{ -#if defined(CONFIG_OMAP34XX) - t2_t *t2_base = (t2_t *)T2_BASE; - struct prcm *prcm_base = (struct prcm *)PRCM_BASE; - u32 pbias_lite; - - pbias_lite = readl(&t2_base->pbias_lite); - pbias_lite &= ~(PBIASLITEPWRDNZ1 | PBIASLITEPWRDNZ0); - writel(pbias_lite, &t2_base->pbias_lite); -#endif -#if defined(CONFIG_TWL4030_POWER) - twl4030_power_mmc_init(); - mdelay(100); /* ramp-up delay from Linux code */ -#endif -#if defined(CONFIG_OMAP34XX) - writel(pbias_lite | PBIASLITEPWRDNZ1 | - PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0, - &t2_base->pbias_lite); - - writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL, - &t2_base->devconf0); - - writel(readl(&t2_base->devconf1) | MMCSDIO2ADPCLKISEL, - &t2_base->devconf1); - - /* Change from default of 52MHz to 26MHz if necessary */ - if (!(mmc->cfg->host_caps & MMC_MODE_HS_52MHz)) - writel(readl(&t2_base->ctl_prog_io1) & ~CTLPROGIO1SPEEDCTRL, - &t2_base->ctl_prog_io1); - - writel(readl(&prcm_base->fclken1_core) | - EN_MMC1 | EN_MMC2 | EN_MMC3, - &prcm_base->fclken1_core); - - writel(readl(&prcm_base->iclken1_core) | - EN_MMC1 | EN_MMC2 | EN_MMC3, - &prcm_base->iclken1_core); -#endif - -#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER) - /* PBIAS config needed for MMC1 only */ - if (mmc->block_dev.dev == 0) - omap4_vmmc_pbias_config(mmc); -#endif -#if defined(CONFIG_OMAP54XX) && defined(CONFIG_PALMAS_POWER) - if (mmc->block_dev.dev == 0) - omap5_pbias_config(mmc); -#endif - - return 0; -} - -void mmc_init_stream(struct hsmmc *mmc_base) -{ - ulong start; - - writel(readl(&mmc_base->con) | INIT_INITSTREAM, &mmc_base->con); - - writel(MMC_CMD0, &mmc_base->cmd); - start = get_timer(0); - while (!(readl(&mmc_base->stat) & CC_MASK)) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for cc!\n", __func__); - return; - } - } - writel(CC_MASK, &mmc_base->stat) - ; - writel(MMC_CMD0, &mmc_base->cmd) - ; - start = get_timer(0); - while (!(readl(&mmc_base->stat) & CC_MASK)) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for cc2!\n", __func__); - return; - } - } - writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con); -} - - -static int omap_hsmmc_init_setup(struct mmc *mmc) -{ - struct hsmmc *mmc_base; - unsigned int reg_val; - unsigned int dsor; - ulong start; - - mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr; - mmc_board_init(mmc); - - writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET, - &mmc_base->sysconfig); - start = get_timer(0); - while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for cc2!\n", __func__); - return TIMEOUT; - } - } - writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl); - start = get_timer(0); - while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for softresetall!\n", - __func__); - return TIMEOUT; - } - } - writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl); - writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP, - &mmc_base->capa); - - reg_val = readl(&mmc_base->con) & RESERVED_MASK; - - writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH | - MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK | - HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con); - - dsor = 240; - mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), - (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); - mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, - (dsor << CLKD_OFFSET) | ICE_OSCILLATE); - start = get_timer(0); - while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for ics!\n", __func__); - return TIMEOUT; - } - } - writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); - - writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl); - - writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE | - IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC, - &mmc_base->ie); - - mmc_init_stream(mmc_base); - - return 0; -} - -/* - * MMC controller internal finite state machine reset - * - * Used to reset command or data internal state machines, using respectively - * SRC or SRD bit of SYSCTL register - */ -static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) -{ - ulong start; - - mmc_reg_out(&mmc_base->sysctl, bit, bit); - - /* - * CMD(DAT) lines reset procedures are slightly different - * for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx). - * According to OMAP3 TRM: - * Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until it - * returns to 0x0. - * According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset - * procedure steps must be as follows: - * 1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in - * MMCHS_SYSCTL register (SD_SYSCTL for AM335x). - * 2. Poll the SRC(SRD) bit until it is set to 0x1. - * 3. Wait until the SRC (SRD) bit returns to 0x0 - * (reset procedure is completed). - */ -#if defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \ - defined(CONFIG_AM33XX) - if (!(readl(&mmc_base->sysctl) & bit)) { - start = get_timer(0); - while (!(readl(&mmc_base->sysctl) & bit)) { - if (get_timer(0) - start > MAX_RETRY_MS) - return; - } - } -#endif - start = get_timer(0); - while ((readl(&mmc_base->sysctl) & bit) != 0) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for sysctl %x to clear\n", - __func__, bit); - return; - } - } -} - -static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct hsmmc *mmc_base; - unsigned int flags, mmc_stat; - ulong start; - - mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr; - start = get_timer(0); - while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting on cmd inhibit to clear\n", - __func__); - return TIMEOUT; - } - } - writel(0xFFFFFFFF, &mmc_base->stat); - start = get_timer(0); - while (readl(&mmc_base->stat)) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for STAT (%x) to clear\n", - __func__, readl(&mmc_base->stat)); - return TIMEOUT; - } - } - /* - * CMDREG - * CMDIDX[13:8] : Command index - * DATAPRNT[5] : Data Present Select - * ENCMDIDX[4] : Command Index Check Enable - * ENCMDCRC[3] : Command CRC Check Enable - * RSPTYP[1:0] - * 00 = No Response - * 01 = Length 136 - * 10 = Length 48 - * 11 = Length 48 Check busy after response - */ - /* Delay added before checking the status of frq change - * retry not supported by mmc.c(core file) - */ - if (cmd->cmdidx == SD_CMD_APP_SEND_SCR) - udelay(50000); /* wait 50 ms */ - - if (!(cmd->resp_type & MMC_RSP_PRESENT)) - flags = 0; - else if (cmd->resp_type & MMC_RSP_136) - flags = RSP_TYPE_LGHT136 | CICE_NOCHECK; - else if (cmd->resp_type & MMC_RSP_BUSY) - flags = RSP_TYPE_LGHT48B; - else - flags = RSP_TYPE_LGHT48; - - /* enable default flags */ - flags = flags | (CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK | - MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE); - - if (cmd->resp_type & MMC_RSP_CRC) - flags |= CCCE_CHECK; - if (cmd->resp_type & MMC_RSP_OPCODE) - flags |= CICE_CHECK; - - if (data) { - if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) || - (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) { - flags |= (MSBS_MULTIBLK | BCE_ENABLE); - data->blocksize = 512; - writel(data->blocksize | (data->blocks << 16), - &mmc_base->blk); - } else - writel(data->blocksize | NBLK_STPCNT, &mmc_base->blk); - - if (data->flags & MMC_DATA_READ) - flags |= (DP_DATA | DDIR_READ); - else - flags |= (DP_DATA | DDIR_WRITE); - } - - writel(cmd->cmdarg, &mmc_base->arg); - udelay(20); /* To fix "No status update" error on eMMC */ - writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd); - - start = get_timer(0); - do { - mmc_stat = readl(&mmc_base->stat); - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s : timeout: No status update\n", __func__); - return TIMEOUT; - } - } while (!mmc_stat); - - if ((mmc_stat & IE_CTO) != 0) { - mmc_reset_controller_fsm(mmc_base, SYSCTL_SRC); - return TIMEOUT; - } else if ((mmc_stat & ERRI_MASK) != 0) - return -1; - - if (mmc_stat & CC_MASK) { - writel(CC_MASK, &mmc_base->stat); - if (cmd->resp_type & MMC_RSP_PRESENT) { - if (cmd->resp_type & MMC_RSP_136) { - /* response type 2 */ - cmd->response[3] = readl(&mmc_base->rsp10); - cmd->response[2] = readl(&mmc_base->rsp32); - cmd->response[1] = readl(&mmc_base->rsp54); - cmd->response[0] = readl(&mmc_base->rsp76); - } else - /* response types 1, 1b, 3, 4, 5, 6 */ - cmd->response[0] = readl(&mmc_base->rsp10); - } - } - - if (data && (data->flags & MMC_DATA_READ)) { - mmc_read_data(mmc_base, data->dest, - data->blocksize * data->blocks); - } else if (data && (data->flags & MMC_DATA_WRITE)) { - mmc_write_data(mmc_base, data->src, - data->blocksize * data->blocks); - } - return 0; -} - -static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size) -{ - unsigned int *output_buf = (unsigned int *)buf; - unsigned int mmc_stat; - unsigned int count; - - /* - * Start Polled Read - */ - count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size; - count /= 4; - - while (size) { - ulong start = get_timer(0); - do { - mmc_stat = readl(&mmc_base->stat); - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for status!\n", - __func__); - return TIMEOUT; - } - } while (mmc_stat == 0); - - if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0) - mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD); - - if ((mmc_stat & ERRI_MASK) != 0) - return 1; - - if (mmc_stat & BRR_MASK) { - unsigned int k; - - writel(readl(&mmc_base->stat) | BRR_MASK, - &mmc_base->stat); - for (k = 0; k < count; k++) { - *output_buf = readl(&mmc_base->data); - output_buf++; - } - size -= (count*4); - } - - if (mmc_stat & BWR_MASK) - writel(readl(&mmc_base->stat) | BWR_MASK, - &mmc_base->stat); - - if (mmc_stat & TC_MASK) { - writel(readl(&mmc_base->stat) | TC_MASK, - &mmc_base->stat); - break; - } - } - return 0; -} - -static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, - unsigned int size) -{ - unsigned int *input_buf = (unsigned int *)buf; - unsigned int mmc_stat; - unsigned int count; - - /* - * Start Polled Write - */ - count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size; - count /= 4; - - while (size) { - ulong start = get_timer(0); - do { - mmc_stat = readl(&mmc_base->stat); - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for status!\n", - __func__); - return TIMEOUT; - } - } while (mmc_stat == 0); - - if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0) - mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD); - - if ((mmc_stat & ERRI_MASK) != 0) - return 1; - - if (mmc_stat & BWR_MASK) { - unsigned int k; - - writel(readl(&mmc_base->stat) | BWR_MASK, - &mmc_base->stat); - for (k = 0; k < count; k++) { - writel(*input_buf, &mmc_base->data); - input_buf++; - } - size -= (count*4); - } - - if (mmc_stat & BRR_MASK) - writel(readl(&mmc_base->stat) | BRR_MASK, - &mmc_base->stat); - - if (mmc_stat & TC_MASK) { - writel(readl(&mmc_base->stat) | TC_MASK, - &mmc_base->stat); - break; - } - } - return 0; -} - -static void omap_hsmmc_set_ios(struct mmc *mmc) -{ - struct hsmmc *mmc_base; - unsigned int dsor = 0; - ulong start; - - mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr; - /* configue bus width */ - switch (mmc->bus_width) { - case 8: - writel(readl(&mmc_base->con) | DTW_8_BITMODE, - &mmc_base->con); - break; - - case 4: - writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, - &mmc_base->con); - writel(readl(&mmc_base->hctl) | DTW_4_BITMODE, - &mmc_base->hctl); - break; - - case 1: - default: - writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, - &mmc_base->con); - writel(readl(&mmc_base->hctl) & ~DTW_4_BITMODE, - &mmc_base->hctl); - break; - } - - /* configure clock with 96Mhz system clock. - */ - if (mmc->clock != 0) { - dsor = (MMC_CLOCK_REFERENCE * 1000000 / mmc->clock); - if ((MMC_CLOCK_REFERENCE * 1000000) / dsor > mmc->clock) - dsor++; - } - - mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), - (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); - - mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, - (dsor << CLKD_OFFSET) | ICE_OSCILLATE); - - start = get_timer(0); - while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) { - if (get_timer(0) - start > MAX_RETRY_MS) { - printf("%s: timedout waiting for ics!\n", __func__); - return; - } - } - writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); -} - -#ifdef OMAP_HSMMC_USE_GPIO -static int omap_hsmmc_getcd(struct mmc *mmc) -{ - struct omap_hsmmc_data *priv_data = mmc->priv; - int cd_gpio; - - /* if no CD return as 1 */ - cd_gpio = priv_data->cd_gpio; - if (cd_gpio < 0) - return 1; - - return gpio_get_value(cd_gpio); -} - -static int omap_hsmmc_getwp(struct mmc *mmc) -{ - struct omap_hsmmc_data *priv_data = mmc->priv; - int wp_gpio; - - /* if no WP return as 0 */ - wp_gpio = priv_data->wp_gpio; - if (wp_gpio < 0) - return 0; - - return gpio_get_value(wp_gpio); -} -#endif - -static const struct mmc_ops omap_hsmmc_ops = { - .send_cmd = omap_hsmmc_send_cmd, - .set_ios = omap_hsmmc_set_ios, - .init = omap_hsmmc_init_setup, -#ifdef OMAP_HSMMC_USE_GPIO - .getcd = omap_hsmmc_getcd, - .getwp = omap_hsmmc_getwp, -#endif -}; - -int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, - int wp_gpio) -{ - struct mmc *mmc; - struct omap_hsmmc_data *priv_data; - struct mmc_config *cfg; - uint host_caps_val; - - priv_data = malloc(sizeof(*priv_data)); - if (priv_data == NULL) - return -1; - - host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS | - MMC_MODE_HC; - - switch (dev_index) { - case 0: - priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE; - break; -#ifdef OMAP_HSMMC2_BASE - case 1: - priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE; -#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \ - defined(CONFIG_DRA7XX)) && defined(CONFIG_HSMMC2_8BIT) - /* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */ - host_caps_val |= MMC_MODE_8BIT; -#endif - break; -#endif -#ifdef OMAP_HSMMC3_BASE - case 2: - priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE; -#if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT) - /* Enable 8-bit interface for eMMC on DRA7XX */ - host_caps_val |= MMC_MODE_8BIT; -#endif - break; -#endif - default: - priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE; - return 1; - } -#ifdef OMAP_HSMMC_USE_GPIO - /* on error gpio values are set to -1, which is what we want */ - priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd"); - priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp"); -#endif - - cfg = &priv_data->cfg; - - cfg->name = "OMAP SD/MMC"; - cfg->ops = &omap_hsmmc_ops; - - cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - cfg->host_caps = host_caps_val & ~host_caps_mask; - - cfg->f_min = 400000; - - if (f_max != 0) - cfg->f_max = f_max; - else { - if (cfg->host_caps & MMC_MODE_HS) { - if (cfg->host_caps & MMC_MODE_HS_52MHz) - cfg->f_max = 52000000; - else - cfg->f_max = 26000000; - } else - cfg->f_max = 20000000; - } - - cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - -#if defined(CONFIG_OMAP34XX) - /* - * Silicon revs 2.1 and older do not support multiblock transfers. - */ - if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21)) - cfg->b_max = 1; -#endif - mmc = mmc_create(cfg, priv_data); - if (mmc == NULL) - return -1; - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/pxa_mmc_gen.c b/qemu/roms/u-boot/drivers/mmc/pxa_mmc_gen.c deleted file mode 100644 index 1f297571e..000000000 --- a/qemu/roms/u-boot/drivers/mmc/pxa_mmc_gen.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> - * - * Loosely based on the old code and Linux's PXA MMC driver - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <malloc.h> - -#include <mmc.h> -#include <asm/errno.h> -#include <asm/arch/hardware.h> -#include <asm/arch/regs-mmc.h> -#include <asm/io.h> - -/* PXAMMC Generic default config for various CPUs */ -#if defined(CONFIG_CPU_PXA25X) -#define PXAMMC_FIFO_SIZE 1 -#define PXAMMC_MIN_SPEED 312500 -#define PXAMMC_MAX_SPEED 20000000 -#define PXAMMC_HOST_CAPS (0) -#elif defined(CONFIG_CPU_PXA27X) -#define PXAMMC_CRC_SKIP -#define PXAMMC_FIFO_SIZE 32 -#define PXAMMC_MIN_SPEED 304000 -#define PXAMMC_MAX_SPEED 19500000 -#define PXAMMC_HOST_CAPS (MMC_MODE_4BIT) -#elif defined(CONFIG_CPU_MONAHANS) -#define PXAMMC_FIFO_SIZE 32 -#define PXAMMC_MIN_SPEED 304000 -#define PXAMMC_MAX_SPEED 26000000 -#define PXAMMC_HOST_CAPS (MMC_MODE_4BIT | MMC_MODE_HS) -#else -#error "This CPU isn't supported by PXA MMC!" -#endif - -#define MMC_STAT_ERRORS \ - (MMC_STAT_RES_CRC_ERROR | MMC_STAT_SPI_READ_ERROR_TOKEN | \ - MMC_STAT_CRC_READ_ERROR | MMC_STAT_TIME_OUT_RESPONSE | \ - MMC_STAT_READ_TIME_OUT | MMC_STAT_CRC_WRITE_ERROR) - -/* 1 millisecond (in wait cycles below it's 100 x 10uS waits) */ -#define PXA_MMC_TIMEOUT 100 - -struct pxa_mmc_priv { - struct pxa_mmc_regs *regs; -}; - -/* Wait for bit to be set */ -static int pxa_mmc_wait(struct mmc *mmc, uint32_t mask) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - unsigned int timeout = PXA_MMC_TIMEOUT; - - /* Wait for bit to be set */ - while (--timeout) { - if (readl(®s->stat) & mask) - break; - udelay(10); - } - - if (!timeout) - return -ETIMEDOUT; - - return 0; -} - -static int pxa_mmc_stop_clock(struct mmc *mmc) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - unsigned int timeout = PXA_MMC_TIMEOUT; - - /* If the clock aren't running, exit */ - if (!(readl(®s->stat) & MMC_STAT_CLK_EN)) - return 0; - - /* Tell the controller to turn off the clock */ - writel(MMC_STRPCL_STOP_CLK, ®s->strpcl); - - /* Wait until the clock are off */ - while (--timeout) { - if (!(readl(®s->stat) & MMC_STAT_CLK_EN)) - break; - udelay(10); - } - - /* The clock refused to stop, scream and die a painful death */ - if (!timeout) - return -ETIMEDOUT; - - /* The clock stopped correctly */ - return 0; -} - -static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - uint32_t cmdat) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - int ret; - - /* The card can send a "busy" response */ - if (cmd->resp_type & MMC_RSP_BUSY) - cmdat |= MMC_CMDAT_BUSY; - - /* Inform the controller about response type */ - switch (cmd->resp_type) { - case MMC_RSP_R1: - case MMC_RSP_R1b: - cmdat |= MMC_CMDAT_R1; - break; - case MMC_RSP_R2: - cmdat |= MMC_CMDAT_R2; - break; - case MMC_RSP_R3: - cmdat |= MMC_CMDAT_R3; - break; - default: - break; - } - - /* Load command and it's arguments into the controller */ - writel(cmd->cmdidx, ®s->cmd); - writel(cmd->cmdarg >> 16, ®s->argh); - writel(cmd->cmdarg & 0xffff, ®s->argl); - writel(cmdat, ®s->cmdat); - - /* Start the controller clock and wait until they are started */ - writel(MMC_STRPCL_START_CLK, ®s->strpcl); - - ret = pxa_mmc_wait(mmc, MMC_STAT_CLK_EN); - if (ret) - return ret; - - /* Correct and happy end */ - return 0; -} - -static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - uint32_t a, b, c; - int i; - int stat; - - /* Read the controller status */ - stat = readl(®s->stat); - - /* - * Linux says: - * Did I mention this is Sick. We always need to - * discard the upper 8 bits of the first 16-bit word. - */ - a = readl(®s->res) & 0xffff; - for (i = 0; i < 4; i++) { - b = readl(®s->res) & 0xffff; - c = readl(®s->res) & 0xffff; - cmd->response[i] = (a << 24) | (b << 8) | (c >> 8); - a = c; - } - - /* The command response didn't arrive */ - if (stat & MMC_STAT_TIME_OUT_RESPONSE) - return -ETIMEDOUT; - else if (stat & MMC_STAT_RES_CRC_ERROR - && cmd->resp_type & MMC_RSP_CRC) { -#ifdef PXAMMC_CRC_SKIP - if (cmd->resp_type & MMC_RSP_136 - && cmd->response[0] & (1 << 31)) - printf("Ignoring CRC, this may be dangerous!\n"); - else -#endif - return -EILSEQ; - } - - /* The command response was successfully read */ - return 0; -} - -static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - uint32_t len; - uint32_t *buf = (uint32_t *)data->dest; - int size; - int ret; - - len = data->blocks * data->blocksize; - - while (len) { - /* The controller has data ready */ - if (readl(®s->i_reg) & MMC_I_REG_RXFIFO_RD_REQ) { - size = min(len, PXAMMC_FIFO_SIZE); - len -= size; - size /= 4; - - /* Read data into the buffer */ - while (size--) - *buf++ = readl(®s->rxfifo); - - } - - if (readl(®s->stat) & MMC_STAT_ERRORS) - return -EIO; - } - - /* Wait for the transmission-done interrupt */ - ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE); - if (ret) - return ret; - - return 0; -} - -static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - uint32_t len; - uint32_t *buf = (uint32_t *)data->src; - int size; - int ret; - - len = data->blocks * data->blocksize; - - while (len) { - /* The controller is ready to receive data */ - if (readl(®s->i_reg) & MMC_I_REG_TXFIFO_WR_REQ) { - size = min(len, PXAMMC_FIFO_SIZE); - len -= size; - size /= 4; - - while (size--) - writel(*buf++, ®s->txfifo); - - if (min(len, PXAMMC_FIFO_SIZE) < 32) - writel(MMC_PRTBUF_BUF_PART_FULL, ®s->prtbuf); - } - - if (readl(®s->stat) & MMC_STAT_ERRORS) - return -EIO; - } - - /* Wait for the transmission-done interrupt */ - ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE); - if (ret) - return ret; - - /* Wait until the data are really written to the card */ - ret = pxa_mmc_wait(mmc, MMC_STAT_PRG_DONE); - if (ret) - return ret; - - return 0; -} - -static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - uint32_t cmdat = 0; - int ret; - - /* Stop the controller */ - ret = pxa_mmc_stop_clock(mmc); - if (ret) - return ret; - - /* If we're doing data transfer, configure the controller accordingly */ - if (data) { - writel(data->blocks, ®s->nob); - writel(data->blocksize, ®s->blklen); - /* This delay can be optimized, but stick with max value */ - writel(0xffff, ®s->rdto); - cmdat |= MMC_CMDAT_DATA_EN; - if (data->flags & MMC_DATA_WRITE) - cmdat |= MMC_CMDAT_WRITE; - } - - /* Run in 4bit mode if the card can do it */ - if (mmc->bus_width == 4) - cmdat |= MMC_CMDAT_SD_4DAT; - - /* Execute the command */ - ret = pxa_mmc_start_cmd(mmc, cmd, cmdat); - if (ret) - return ret; - - /* Wait until the command completes */ - ret = pxa_mmc_wait(mmc, MMC_STAT_END_CMD_RES); - if (ret) - return ret; - - /* Read back the result */ - ret = pxa_mmc_cmd_done(mmc, cmd); - if (ret) - return ret; - - /* In case there was a data transfer scheduled, do it */ - if (data) { - if (data->flags & MMC_DATA_WRITE) - pxa_mmc_do_write_xfer(mmc, data); - else - pxa_mmc_do_read_xfer(mmc, data); - } - - return 0; -} - -static void pxa_mmc_set_ios(struct mmc *mmc) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - uint32_t tmp; - uint32_t pxa_mmc_clock; - - if (!mmc->clock) { - pxa_mmc_stop_clock(mmc); - return; - } - - /* PXA3xx can do 26MHz with special settings. */ - if (mmc->clock == 26000000) { - writel(0x7, ®s->clkrt); - return; - } - - /* Set clock to the card the usual way. */ - pxa_mmc_clock = 0; - tmp = mmc->cfg->f_max / mmc->clock; - tmp += tmp % 2; - - while (tmp > 1) { - pxa_mmc_clock++; - tmp >>= 1; - } - - writel(pxa_mmc_clock, ®s->clkrt); -} - -static int pxa_mmc_init(struct mmc *mmc) -{ - struct pxa_mmc_priv *priv = mmc->priv; - struct pxa_mmc_regs *regs = priv->regs; - - /* Make sure the clock are stopped */ - pxa_mmc_stop_clock(mmc); - - /* Turn off SPI mode */ - writel(0, ®s->spi); - - /* Set up maximum timeout to wait for command response */ - writel(MMC_RES_TO_MAX_MASK, ®s->resto); - - /* Mask all interrupts */ - writel(~(MMC_I_MASK_TXFIFO_WR_REQ | MMC_I_MASK_RXFIFO_RD_REQ), - ®s->i_mask); - return 0; -} - -static const struct mmc_ops pxa_mmc_ops = { - .send_cmd = pxa_mmc_request, - .set_ios = pxa_mmc_set_ios, - .init = pxa_mmc_init, -}; - -static struct mmc_config pxa_mmc_cfg = { - .name = "PXA MMC", - .ops = &pxa_mmc_ops, - .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - .f_max = PXAMMC_MAX_SPEED, - .f_min = PXAMMC_MIN_SPEED, - .host_caps = PXAMMC_HOST_CAPS, - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, -}; - -int pxa_mmc_register(int card_index) -{ - struct mmc *mmc; - struct pxa_mmc_priv *priv; - uint32_t reg; - int ret = -ENOMEM; - - priv = malloc(sizeof(struct pxa_mmc_priv)); - if (!priv) - goto err0; - - memset(priv, 0, sizeof(*priv)); - - switch (card_index) { - case 0: - priv->regs = (struct pxa_mmc_regs *)MMC0_BASE; - break; - case 1: - priv->regs = (struct pxa_mmc_regs *)MMC1_BASE; - break; - default: - ret = -EINVAL; - printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n", - card_index); - goto err1; - } - -#ifndef CONFIG_CPU_MONAHANS /* PXA2xx */ - reg = readl(CKEN); - reg |= CKEN12_MMC; - writel(reg, CKEN); -#else /* PXA3xx */ - reg = readl(CKENA); - reg |= CKENA_12_MMC0 | CKENA_13_MMC1; - writel(reg, CKENA); -#endif - - mmc = mmc_create(&pxa_mmc_cfg, priv); - if (mmc == NULL) - goto err1; - - return 0; - -err1: - free(priv); -err0: - return ret; -} diff --git a/qemu/roms/u-boot/drivers/mmc/s5p_sdhci.c b/qemu/roms/u-boot/drivers/mmc/s5p_sdhci.c deleted file mode 100644 index ccae4ccae..000000000 --- a/qemu/roms/u-boot/drivers/mmc/s5p_sdhci.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * (C) Copyright 2012 SAMSUNG Electronics - * Jaehoon Chung <jh80.chung@samsung.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <sdhci.h> -#include <fdtdec.h> -#include <libfdt.h> -#include <asm/gpio.h> -#include <asm/arch/mmc.h> -#include <asm/arch/clk.h> -#include <errno.h> -#ifdef CONFIG_OF_CONTROL -#include <asm/arch/pinmux.h> -#endif - -static char *S5P_NAME = "SAMSUNG SDHCI"; -static void s5p_sdhci_set_control_reg(struct sdhci_host *host) -{ - unsigned long val, ctrl; - /* - * SELCLKPADDS[17:16] - * 00 = 2mA - * 01 = 4mA - * 10 = 7mA - * 11 = 9mA - */ - sdhci_writel(host, SDHCI_CTRL4_DRIVE_MASK(0x3), SDHCI_CONTROL4); - - val = sdhci_readl(host, SDHCI_CONTROL2); - val &= SDHCI_CTRL2_SELBASECLK_SHIFT; - - val |= SDHCI_CTRL2_ENSTAASYNCCLR | - SDHCI_CTRL2_ENCMDCNFMSK | - SDHCI_CTRL2_ENFBCLKRX | - SDHCI_CTRL2_ENCLKOUTHOLD; - - sdhci_writel(host, val, SDHCI_CONTROL2); - - /* - * FCSEL3[31] FCSEL2[23] FCSEL1[15] FCSEL0[7] - * FCSel[1:0] : Rx Feedback Clock Delay Control - * Inverter delay means10ns delay if SDCLK 50MHz setting - * 01 = Delay1 (basic delay) - * 11 = Delay2 (basic delay + 2ns) - * 00 = Delay3 (inverter delay) - * 10 = Delay4 (inverter delay + 2ns) - */ - val = SDHCI_CTRL3_FCSEL0 | SDHCI_CTRL3_FCSEL1; - sdhci_writel(host, val, SDHCI_CONTROL3); - - /* - * SELBASECLK[5:4] - * 00/01 = HCLK - * 10 = EPLL - * 11 = XTI or XEXTCLK - */ - ctrl = sdhci_readl(host, SDHCI_CONTROL2); - ctrl &= ~SDHCI_CTRL2_SELBASECLK_MASK(0x3); - ctrl |= SDHCI_CTRL2_SELBASECLK_MASK(0x2); - sdhci_writel(host, ctrl, SDHCI_CONTROL2); -} - -int s5p_sdhci_init(u32 regbase, int index, int bus_width) -{ - struct sdhci_host *host = NULL; - host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); - if (!host) { - printf("sdhci__host malloc fail!\n"); - return 1; - } - - host->name = S5P_NAME; - host->ioaddr = (void *)regbase; - - host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | - SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR | - SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_USE_WIDE8; - host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - - host->set_control_reg = &s5p_sdhci_set_control_reg; - host->set_clock = set_mmc_clk; - host->index = index; - - host->host_caps = MMC_MODE_HC; - if (bus_width == 8) - host->host_caps |= MMC_MODE_8BIT; - - return add_sdhci(host, 52000000, 400000); -} - -#ifdef CONFIG_OF_CONTROL -struct sdhci_host sdhci_host[SDHCI_MAX_HOSTS]; - -static int do_sdhci_init(struct sdhci_host *host) -{ - int dev_id, flag; - int err = 0; - - flag = host->bus_width == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE; - dev_id = host->index + PERIPH_ID_SDMMC0; - - if (fdt_gpio_isvalid(&host->pwr_gpio)) { - gpio_direction_output(host->pwr_gpio.gpio, 1); - err = exynos_pinmux_config(dev_id, flag); - if (err) { - debug("MMC not configured\n"); - return err; - } - } - - if (fdt_gpio_isvalid(&host->cd_gpio)) { - gpio_direction_output(host->cd_gpio.gpio, 0xf); - if (gpio_get_value(host->cd_gpio.gpio)) - return -ENODEV; - - err = exynos_pinmux_config(dev_id, flag); - if (err) { - printf("external SD not configured\n"); - return err; - } - } - - host->name = S5P_NAME; - - host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | - SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR | - SDHCI_QUIRK_WAIT_SEND_CMD; - host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - - host->set_control_reg = &s5p_sdhci_set_control_reg; - host->set_clock = set_mmc_clk; - - host->host_caps = MMC_MODE_HC; - - return add_sdhci(host, 52000000, 400000); -} - -static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host) -{ - int bus_width, dev_id; - unsigned int base; - - /* Get device id */ - dev_id = pinmux_decode_periph_id(blob, node); - if (dev_id < PERIPH_ID_SDMMC0 && dev_id > PERIPH_ID_SDMMC3) { - debug("MMC: Can't get device id\n"); - return -1; - } - host->index = dev_id - PERIPH_ID_SDMMC0; - - /* Get bus width */ - bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0); - if (bus_width <= 0) { - debug("MMC: Can't get bus-width\n"); - return -1; - } - host->bus_width = bus_width; - - /* Get the base address from the device node */ - base = fdtdec_get_addr(blob, node, "reg"); - if (!base) { - debug("MMC: Can't get base address\n"); - return -1; - } - host->ioaddr = (void *)base; - - fdtdec_decode_gpio(blob, node, "pwr-gpios", &host->pwr_gpio); - fdtdec_decode_gpio(blob, node, "cd-gpios", &host->cd_gpio); - - return 0; -} - -static int process_nodes(const void *blob, int node_list[], int count) -{ - struct sdhci_host *host; - int i, node; - - debug("%s: count = %d\n", __func__, count); - - /* build sdhci_host[] for each controller */ - for (i = 0; i < count; i++) { - node = node_list[i]; - if (node <= 0) - continue; - - host = &sdhci_host[i]; - - if (sdhci_get_config(blob, node, host)) { - printf("%s: failed to decode dev %d\n", __func__, i); - return -1; - } - do_sdhci_init(host); - } - return 0; -} - -int exynos_mmc_init(const void *blob) -{ - int count; - int node_list[SDHCI_MAX_HOSTS]; - - count = fdtdec_find_aliases_for_id(blob, "mmc", - COMPAT_SAMSUNG_EXYNOS_MMC, node_list, - SDHCI_MAX_HOSTS); - - process_nodes(blob, node_list, count); - - return 1; -} -#endif diff --git a/qemu/roms/u-boot/drivers/mmc/sdhci.c b/qemu/roms/u-boot/drivers/mmc/sdhci.c deleted file mode 100644 index 3125d13ba..000000000 --- a/qemu/roms/u-boot/drivers/mmc/sdhci.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright 2011, Marvell Semiconductor Inc. - * Lei Wen <leiwen@marvell.com> - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Back ported to the 8xx platform (from the 8260 platform) by - * Murray.Jensen@cmst.csiro.au, 27-Jan-01. - */ - -#include <common.h> -#include <malloc.h> -#include <mmc.h> -#include <sdhci.h> - -void *aligned_buffer; - -static void sdhci_reset(struct sdhci_host *host, u8 mask) -{ - unsigned long timeout; - - /* Wait max 100 ms */ - timeout = 100; - sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); - while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) { - if (timeout == 0) { - printf("%s: Reset 0x%x never completed.\n", - __func__, (int)mask); - return; - } - timeout--; - udelay(1000); - } -} - -static void sdhci_cmd_done(struct sdhci_host *host, struct mmc_cmd *cmd) -{ - int i; - if (cmd->resp_type & MMC_RSP_136) { - /* CRC is stripped so we need to do some shifting. */ - for (i = 0; i < 4; i++) { - cmd->response[i] = sdhci_readl(host, - SDHCI_RESPONSE + (3-i)*4) << 8; - if (i != 3) - cmd->response[i] |= sdhci_readb(host, - SDHCI_RESPONSE + (3-i)*4-1); - } - } else { - cmd->response[0] = sdhci_readl(host, SDHCI_RESPONSE); - } -} - -static void sdhci_transfer_pio(struct sdhci_host *host, struct mmc_data *data) -{ - int i; - char *offs; - for (i = 0; i < data->blocksize; i += 4) { - offs = data->dest + i; - if (data->flags == MMC_DATA_READ) - *(u32 *)offs = sdhci_readl(host, SDHCI_BUFFER); - else - sdhci_writel(host, *(u32 *)offs, SDHCI_BUFFER); - } -} - -static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, - unsigned int start_addr) -{ - unsigned int stat, rdy, mask, timeout, block = 0; -#ifdef CONFIG_MMC_SDMA - unsigned char ctrl; - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - ctrl &= ~SDHCI_CTRL_DMA_MASK; - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -#endif - - timeout = 1000000; - rdy = SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_AVAIL; - mask = SDHCI_DATA_AVAILABLE | SDHCI_SPACE_AVAILABLE; - do { - stat = sdhci_readl(host, SDHCI_INT_STATUS); - if (stat & SDHCI_INT_ERROR) { - printf("%s: Error detected in status(0x%X)!\n", - __func__, stat); - return -1; - } - if (stat & rdy) { - if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & mask)) - continue; - sdhci_writel(host, rdy, SDHCI_INT_STATUS); - sdhci_transfer_pio(host, data); - data->dest += data->blocksize; - if (++block >= data->blocks) - break; - } -#ifdef CONFIG_MMC_SDMA - if (stat & SDHCI_INT_DMA_END) { - sdhci_writel(host, SDHCI_INT_DMA_END, SDHCI_INT_STATUS); - start_addr &= ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1); - start_addr += SDHCI_DEFAULT_BOUNDARY_SIZE; - sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS); - } -#endif - if (timeout-- > 0) - udelay(10); - else { - printf("%s: Transfer data timeout\n", __func__); - return -1; - } - } while (!(stat & SDHCI_INT_DATA_END)); - return 0; -} - -/* - * No command will be sent by driver if card is busy, so driver must wait - * for card ready state. - * Every time when card is busy after timeout then (last) timeout value will be - * increased twice but only if it doesn't exceed global defined maximum. - * Each function call will use last timeout value. Max timeout can be redefined - * in board config file. - */ -#ifndef CONFIG_SDHCI_CMD_MAX_TIMEOUT -#define CONFIG_SDHCI_CMD_MAX_TIMEOUT 3200 -#endif -#define CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT 100 - -int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct sdhci_host *host = mmc->priv; - unsigned int stat = 0; - int ret = 0; - int trans_bytes = 0, is_aligned = 1; - u32 mask, flags, mode; - unsigned int time = 0, start_addr = 0; - unsigned int retry = 10000; - int mmc_dev = mmc->block_dev.dev; - - /* Timeout unit - ms */ - static unsigned int cmd_timeout = CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT; - - sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS); - mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT; - - /* We shouldn't wait for data inihibit for stop commands, even - though they might use busy signaling */ - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) - mask &= ~SDHCI_DATA_INHIBIT; - - while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { - if (time >= cmd_timeout) { - printf("%s: MMC: %d busy ", __func__, mmc_dev); - if (2 * cmd_timeout <= CONFIG_SDHCI_CMD_MAX_TIMEOUT) { - cmd_timeout += cmd_timeout; - printf("timeout increasing to: %u ms.\n", - cmd_timeout); - } else { - puts("timeout.\n"); - return COMM_ERR; - } - } - time++; - udelay(1000); - } - - mask = SDHCI_INT_RESPONSE; - if (!(cmd->resp_type & MMC_RSP_PRESENT)) - flags = SDHCI_CMD_RESP_NONE; - else if (cmd->resp_type & MMC_RSP_136) - flags = SDHCI_CMD_RESP_LONG; - else if (cmd->resp_type & MMC_RSP_BUSY) { - flags = SDHCI_CMD_RESP_SHORT_BUSY; - mask |= SDHCI_INT_DATA_END; - } else - flags = SDHCI_CMD_RESP_SHORT; - - if (cmd->resp_type & MMC_RSP_CRC) - flags |= SDHCI_CMD_CRC; - if (cmd->resp_type & MMC_RSP_OPCODE) - flags |= SDHCI_CMD_INDEX; - if (data) - flags |= SDHCI_CMD_DATA; - - /* Set Transfer mode regarding to data flag */ - if (data != 0) { - sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL); - mode = SDHCI_TRNS_BLK_CNT_EN; - trans_bytes = data->blocks * data->blocksize; - if (data->blocks > 1) - mode |= SDHCI_TRNS_MULTI; - - if (data->flags == MMC_DATA_READ) - mode |= SDHCI_TRNS_READ; - -#ifdef CONFIG_MMC_SDMA - if (data->flags == MMC_DATA_READ) - start_addr = (unsigned int)data->dest; - else - start_addr = (unsigned int)data->src; - if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && - (start_addr & 0x7) != 0x0) { - is_aligned = 0; - start_addr = (unsigned int)aligned_buffer; - if (data->flags != MMC_DATA_READ) - memcpy(aligned_buffer, data->src, trans_bytes); - } - - sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS); - mode |= SDHCI_TRNS_DMA; -#endif - sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, - data->blocksize), - SDHCI_BLOCK_SIZE); - sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT); - sdhci_writew(host, mode, SDHCI_TRANSFER_MODE); - } - - sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT); -#ifdef CONFIG_MMC_SDMA - flush_cache(start_addr, trans_bytes); -#endif - sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND); - do { - stat = sdhci_readl(host, SDHCI_INT_STATUS); - if (stat & SDHCI_INT_ERROR) - break; - if (--retry == 0) - break; - } while ((stat & mask) != mask); - - if (retry == 0) { - if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) - return 0; - else { - printf("%s: Timeout for status update!\n", __func__); - return TIMEOUT; - } - } - - if ((stat & (SDHCI_INT_ERROR | mask)) == mask) { - sdhci_cmd_done(host, cmd); - sdhci_writel(host, mask, SDHCI_INT_STATUS); - } else - ret = -1; - - if (!ret && data) - ret = sdhci_transfer_data(host, data, start_addr); - - if (host->quirks & SDHCI_QUIRK_WAIT_SEND_CMD) - udelay(1000); - - stat = sdhci_readl(host, SDHCI_INT_STATUS); - sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS); - if (!ret) { - if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && - !is_aligned && (data->flags == MMC_DATA_READ)) - memcpy(data->dest, aligned_buffer, trans_bytes); - return 0; - } - - sdhci_reset(host, SDHCI_RESET_CMD); - sdhci_reset(host, SDHCI_RESET_DATA); - if (stat & SDHCI_INT_TIMEOUT) - return TIMEOUT; - else - return COMM_ERR; -} - -static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) -{ - struct sdhci_host *host = mmc->priv; - unsigned int div, clk, timeout; - - sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); - - if (clock == 0) - return 0; - - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { - /* Version 3.00 divisors must be a multiple of 2. */ - if (mmc->cfg->f_max <= clock) - div = 1; - else { - for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { - if ((mmc->cfg->f_max / div) <= clock) - break; - } - } - } else { - /* Version 2.00 divisors must be a power of 2. */ - for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) { - if ((mmc->cfg->f_max / div) <= clock) - break; - } - } - div >>= 1; - - if (host->set_clock) - host->set_clock(host->index, div); - - clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; - clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) - << SDHCI_DIVIDER_HI_SHIFT; - clk |= SDHCI_CLOCK_INT_EN; - sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); - - /* Wait max 20 ms */ - timeout = 20; - while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) - & SDHCI_CLOCK_INT_STABLE)) { - if (timeout == 0) { - printf("%s: Internal clock never stabilised.\n", - __func__); - return -1; - } - timeout--; - udelay(1000); - } - - clk |= SDHCI_CLOCK_CARD_EN; - sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); - return 0; -} - -static void sdhci_set_power(struct sdhci_host *host, unsigned short power) -{ - u8 pwr = 0; - - if (power != (unsigned short)-1) { - switch (1 << power) { - case MMC_VDD_165_195: - pwr = SDHCI_POWER_180; - break; - case MMC_VDD_29_30: - case MMC_VDD_30_31: - pwr = SDHCI_POWER_300; - break; - case MMC_VDD_32_33: - case MMC_VDD_33_34: - pwr = SDHCI_POWER_330; - break; - } - } - - if (pwr == 0) { - sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); - return; - } - - if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); - - pwr |= SDHCI_POWER_ON; - - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); -} - -void sdhci_set_ios(struct mmc *mmc) -{ - u32 ctrl; - struct sdhci_host *host = mmc->priv; - - if (host->set_control_reg) - host->set_control_reg(host); - - if (mmc->clock != host->clock) - sdhci_set_clock(mmc, mmc->clock); - - /* Set bus width */ - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - if (mmc->bus_width == 8) { - ctrl &= ~SDHCI_CTRL_4BITBUS; - if ((SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) || - (host->quirks & SDHCI_QUIRK_USE_WIDE8)) - ctrl |= SDHCI_CTRL_8BITBUS; - } else { - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) - ctrl &= ~SDHCI_CTRL_8BITBUS; - if (mmc->bus_width == 4) - ctrl |= SDHCI_CTRL_4BITBUS; - else - ctrl &= ~SDHCI_CTRL_4BITBUS; - } - - if (mmc->clock > 26000000) - ctrl |= SDHCI_CTRL_HISPD; - else - ctrl &= ~SDHCI_CTRL_HISPD; - - if (host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) - ctrl &= ~SDHCI_CTRL_HISPD; - - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -} - -int sdhci_init(struct mmc *mmc) -{ - struct sdhci_host *host = mmc->priv; - - if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !aligned_buffer) { - aligned_buffer = memalign(8, 512*1024); - if (!aligned_buffer) { - printf("%s: Aligned buffer alloc failed!!!\n", - __func__); - return -1; - } - } - - sdhci_set_power(host, fls(mmc->cfg->voltages) - 1); - - if (host->quirks & SDHCI_QUIRK_NO_CD) { - unsigned int status; - - sdhci_writel(host, SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST, - SDHCI_HOST_CONTROL); - - status = sdhci_readl(host, SDHCI_PRESENT_STATE); - while ((!(status & SDHCI_CARD_PRESENT)) || - (!(status & SDHCI_CARD_STATE_STABLE)) || - (!(status & SDHCI_CARD_DETECT_PIN_LEVEL))) - status = sdhci_readl(host, SDHCI_PRESENT_STATE); - } - - /* Enable only interrupts served by the SD controller */ - sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK, - SDHCI_INT_ENABLE); - /* Mask all sdhci interrupt sources */ - sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE); - - return 0; -} - - -static const struct mmc_ops sdhci_ops = { - .send_cmd = sdhci_send_command, - .set_ios = sdhci_set_ios, - .init = sdhci_init, -}; - -int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) -{ - unsigned int caps; - - host->cfg.name = host->name; - host->cfg.ops = &sdhci_ops; - - caps = sdhci_readl(host, SDHCI_CAPABILITIES); -#ifdef CONFIG_MMC_SDMA - if (!(caps & SDHCI_CAN_DO_SDMA)) { - printf("%s: Your controller doesn't support SDMA!!\n", - __func__); - return -1; - } -#endif - - if (max_clk) - host->cfg.f_max = max_clk; - else { - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) - host->cfg.f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) - >> SDHCI_CLOCK_BASE_SHIFT; - else - host->cfg.f_max = (caps & SDHCI_CLOCK_BASE_MASK) - >> SDHCI_CLOCK_BASE_SHIFT; - host->cfg.f_max *= 1000000; - } - if (host->cfg.f_max == 0) { - printf("%s: Hardware doesn't specify base clock frequency\n", - __func__); - return -1; - } - if (min_clk) - host->cfg.f_min = min_clk; - else { - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) - host->cfg.f_min = host->cfg.f_max / - SDHCI_MAX_DIV_SPEC_300; - else - host->cfg.f_min = host->cfg.f_max / - SDHCI_MAX_DIV_SPEC_200; - } - - host->cfg.voltages = 0; - if (caps & SDHCI_CAN_VDD_330) - host->cfg.voltages |= MMC_VDD_32_33 | MMC_VDD_33_34; - if (caps & SDHCI_CAN_VDD_300) - host->cfg.voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; - if (caps & SDHCI_CAN_VDD_180) - host->cfg.voltages |= MMC_VDD_165_195; - - if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE) - host->cfg.voltages |= host->voltages; - - host->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { - if (caps & SDHCI_CAN_DO_8BIT) - host->cfg.host_caps |= MMC_MODE_8BIT; - } - if (host->host_caps) - host->cfg.host_caps |= host->host_caps; - - host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - sdhci_reset(host, SDHCI_RESET_ALL); - - host->mmc = mmc_create(&host->cfg, host); - if (host->mmc == NULL) { - printf("%s: mmc create fail!\n", __func__); - return -1; - } - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/sh_mmcif.c b/qemu/roms/u-boot/drivers/mmc/sh_mmcif.c deleted file mode 100644 index ed83a14c2..000000000 --- a/qemu/roms/u-boot/drivers/mmc/sh_mmcif.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * MMCIF driver. - * - * 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. - */ - -#include <config.h> -#include <common.h> -#include <watchdog.h> -#include <command.h> -#include <mmc.h> -#include <malloc.h> -#include <asm/errno.h> -#include <asm/io.h> -#include "sh_mmcif.h" - -#define DRIVER_NAME "sh_mmcif" - -static int sh_mmcif_intr(void *dev_id) -{ - struct sh_mmcif_host *host = dev_id; - u32 state = 0; - - state = sh_mmcif_read(&host->regs->ce_int); - state &= sh_mmcif_read(&host->regs->ce_int_mask); - - if (state & INT_RBSYE) { - sh_mmcif_write(~(INT_RBSYE | INT_CRSPE), &host->regs->ce_int); - sh_mmcif_bitclr(MASK_MRBSYE, &host->regs->ce_int_mask); - goto end; - } else if (state & INT_CRSPE) { - sh_mmcif_write(~INT_CRSPE, &host->regs->ce_int); - sh_mmcif_bitclr(MASK_MCRSPE, &host->regs->ce_int_mask); - /* one more interrupt (INT_RBSYE) */ - if (sh_mmcif_read(&host->regs->ce_cmd_set) & CMD_SET_RBSY) - return -EAGAIN; - goto end; - } else if (state & INT_BUFREN) { - sh_mmcif_write(~INT_BUFREN, &host->regs->ce_int); - sh_mmcif_bitclr(MASK_MBUFREN, &host->regs->ce_int_mask); - goto end; - } else if (state & INT_BUFWEN) { - sh_mmcif_write(~INT_BUFWEN, &host->regs->ce_int); - sh_mmcif_bitclr(MASK_MBUFWEN, &host->regs->ce_int_mask); - goto end; - } else if (state & INT_CMD12DRE) { - sh_mmcif_write(~(INT_CMD12DRE | INT_CMD12RBE | INT_CMD12CRE | - INT_BUFRE), &host->regs->ce_int); - sh_mmcif_bitclr(MASK_MCMD12DRE, &host->regs->ce_int_mask); - goto end; - } else if (state & INT_BUFRE) { - sh_mmcif_write(~INT_BUFRE, &host->regs->ce_int); - sh_mmcif_bitclr(MASK_MBUFRE, &host->regs->ce_int_mask); - goto end; - } else if (state & INT_DTRANE) { - sh_mmcif_write(~INT_DTRANE, &host->regs->ce_int); - sh_mmcif_bitclr(MASK_MDTRANE, &host->regs->ce_int_mask); - goto end; - } else if (state & INT_CMD12RBE) { - sh_mmcif_write(~(INT_CMD12RBE | INT_CMD12CRE), - &host->regs->ce_int); - sh_mmcif_bitclr(MASK_MCMD12RBE, &host->regs->ce_int_mask); - goto end; - } else if (state & INT_ERR_STS) { - /* err interrupts */ - sh_mmcif_write(~state, &host->regs->ce_int); - sh_mmcif_bitclr(state, &host->regs->ce_int_mask); - goto err; - } else - return -EAGAIN; - -err: - host->sd_error = 1; - debug("%s: int err state = %08x\n", DRIVER_NAME, state); -end: - host->wait_int = 1; - return 0; -} - -static int mmcif_wait_interrupt_flag(struct sh_mmcif_host *host) -{ - int timeout = 10000000; - - while (1) { - timeout--; - if (timeout < 0) { - printf("timeout\n"); - return 0; - } - - if (!sh_mmcif_intr(host)) - break; - - udelay(1); /* 1 usec */ - } - - return 1; /* Return value: NOT 0 = complete waiting */ -} - -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) { - 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); - } - sh_mmcif_bitset(CLK_ENABLE, &host->regs->ce_clk_ctrl); -} - -static void sh_mmcif_sync_reset(struct sh_mmcif_host *host) -{ - u32 tmp; - - tmp = sh_mmcif_read(&host->regs->ce_clk_ctrl) & (CLK_ENABLE | - CLK_CLEAR); - - sh_mmcif_write(SOFT_RST_ON, &host->regs->ce_version); - sh_mmcif_write(SOFT_RST_OFF, &host->regs->ce_version); - sh_mmcif_bitset(tmp | SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29, - &host->regs->ce_clk_ctrl); - /* byte swap on */ - sh_mmcif_bitset(BUF_ACC_ATYP, &host->regs->ce_buf_acc); -} - -static int sh_mmcif_error_manage(struct sh_mmcif_host *host) -{ - u32 state1, state2; - int ret, timeout = 10000000; - - host->sd_error = 0; - host->wait_int = 0; - - state1 = sh_mmcif_read(&host->regs->ce_host_sts1); - state2 = sh_mmcif_read(&host->regs->ce_host_sts2); - debug("%s: ERR HOST_STS1 = %08x\n", \ - DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts1)); - debug("%s: ERR HOST_STS2 = %08x\n", \ - DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts2)); - - if (state1 & STS1_CMDSEQ) { - debug("%s: Forced end of command sequence\n", DRIVER_NAME); - sh_mmcif_bitset(CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl); - sh_mmcif_bitset(~CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl); - while (1) { - timeout--; - if (timeout < 0) { - printf(DRIVER_NAME": Forceed end of " \ - "command sequence timeout err\n"); - return -EILSEQ; - } - if (!(sh_mmcif_read(&host->regs->ce_host_sts1) - & STS1_CMDSEQ)) - break; - } - sh_mmcif_sync_reset(host); - return -EILSEQ; - } - - if (state2 & STS2_CRC_ERR) - ret = -EILSEQ; - else if (state2 & STS2_TIMEOUT_ERR) - ret = TIMEOUT; - else - ret = -EILSEQ; - return ret; -} - -static int sh_mmcif_single_read(struct sh_mmcif_host *host, - struct mmc_data *data) -{ - long time; - u32 blocksize, i; - unsigned long *p = (unsigned long *)data->dest; - - if ((unsigned long)p & 0x00000001) { - printf("%s: The data pointer is unaligned.", __func__); - return -EIO; - } - - host->wait_int = 0; - - /* buf read enable */ - sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask); - time = mmcif_wait_interrupt_flag(host); - if (time == 0 || host->sd_error != 0) - return sh_mmcif_error_manage(host); - - host->wait_int = 0; - blocksize = (BLOCK_SIZE_MASK & - sh_mmcif_read(&host->regs->ce_block_set)) + 3; - for (i = 0; i < blocksize / 4; i++) - *p++ = sh_mmcif_read(&host->regs->ce_data); - - /* buffer read end */ - sh_mmcif_bitset(MASK_MBUFRE, &host->regs->ce_int_mask); - time = mmcif_wait_interrupt_flag(host); - if (time == 0 || host->sd_error != 0) - return sh_mmcif_error_manage(host); - - host->wait_int = 0; - return 0; -} - -static int sh_mmcif_multi_read(struct sh_mmcif_host *host, - struct mmc_data *data) -{ - long time; - u32 blocksize, i, j; - unsigned long *p = (unsigned long *)data->dest; - - if ((unsigned long)p & 0x00000001) { - printf("%s: The data pointer is unaligned.", __func__); - return -EIO; - } - - host->wait_int = 0; - blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set); - for (j = 0; j < data->blocks; j++) { - sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask); - time = mmcif_wait_interrupt_flag(host); - if (time == 0 || host->sd_error != 0) - return sh_mmcif_error_manage(host); - - host->wait_int = 0; - for (i = 0; i < blocksize / 4; i++) - *p++ = sh_mmcif_read(&host->regs->ce_data); - - WATCHDOG_RESET(); - } - return 0; -} - -static int sh_mmcif_single_write(struct sh_mmcif_host *host, - struct mmc_data *data) -{ - long time; - u32 blocksize, i; - const unsigned long *p = (unsigned long *)data->dest; - - if ((unsigned long)p & 0x00000001) { - printf("%s: The data pointer is unaligned.", __func__); - return -EIO; - } - - host->wait_int = 0; - sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask); - - time = mmcif_wait_interrupt_flag(host); - if (time == 0 || host->sd_error != 0) - return sh_mmcif_error_manage(host); - - host->wait_int = 0; - blocksize = (BLOCK_SIZE_MASK & - sh_mmcif_read(&host->regs->ce_block_set)) + 3; - for (i = 0; i < blocksize / 4; i++) - sh_mmcif_write(*p++, &host->regs->ce_data); - - /* buffer write end */ - sh_mmcif_bitset(MASK_MDTRANE, &host->regs->ce_int_mask); - - time = mmcif_wait_interrupt_flag(host); - if (time == 0 || host->sd_error != 0) - return sh_mmcif_error_manage(host); - - host->wait_int = 0; - return 0; -} - -static int sh_mmcif_multi_write(struct sh_mmcif_host *host, - struct mmc_data *data) -{ - long time; - u32 i, j, blocksize; - const unsigned long *p = (unsigned long *)data->dest; - - if ((unsigned long)p & 0x00000001) { - printf("%s: The data pointer is unaligned.", __func__); - return -EIO; - } - - host->wait_int = 0; - blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set); - for (j = 0; j < data->blocks; j++) { - sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask); - - time = mmcif_wait_interrupt_flag(host); - - if (time == 0 || host->sd_error != 0) - return sh_mmcif_error_manage(host); - - host->wait_int = 0; - for (i = 0; i < blocksize / 4; i++) - sh_mmcif_write(*p++, &host->regs->ce_data); - - WATCHDOG_RESET(); - } - return 0; -} - -static void sh_mmcif_get_response(struct sh_mmcif_host *host, - struct mmc_cmd *cmd) -{ - if (cmd->resp_type & MMC_RSP_136) { - cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp3); - cmd->response[1] = sh_mmcif_read(&host->regs->ce_resp2); - cmd->response[2] = sh_mmcif_read(&host->regs->ce_resp1); - cmd->response[3] = sh_mmcif_read(&host->regs->ce_resp0); - debug(" RESP %08x, %08x, %08x, %08x\n", cmd->response[0], - cmd->response[1], cmd->response[2], cmd->response[3]); - } else { - cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp0); - } -} - -static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host, - struct mmc_cmd *cmd) -{ - cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp_cmd12); -} - -static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, - struct mmc_data *data, struct mmc_cmd *cmd) -{ - u32 tmp = 0; - u32 opc = cmd->cmdidx; - - /* Response Type check */ - switch (cmd->resp_type) { - case MMC_RSP_NONE: - tmp |= CMD_SET_RTYP_NO; - break; - case MMC_RSP_R1: - case MMC_RSP_R1b: - case MMC_RSP_R3: - tmp |= CMD_SET_RTYP_6B; - break; - case MMC_RSP_R2: - tmp |= CMD_SET_RTYP_17B; - break; - default: - printf(DRIVER_NAME": Not support type response.\n"); - break; - } - - /* RBSY */ - if (opc == MMC_CMD_SWITCH) - tmp |= CMD_SET_RBSY; - - /* WDAT / DATW */ - if (host->data) { - tmp |= CMD_SET_WDAT; - switch (host->bus_width) { - case MMC_BUS_WIDTH_1: - tmp |= CMD_SET_DATW_1; - break; - case MMC_BUS_WIDTH_4: - tmp |= CMD_SET_DATW_4; - break; - case MMC_BUS_WIDTH_8: - tmp |= CMD_SET_DATW_8; - break; - default: - printf(DRIVER_NAME": Not support bus width.\n"); - break; - } - } - /* DWEN */ - if (opc == MMC_CMD_WRITE_SINGLE_BLOCK || - opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) - tmp |= CMD_SET_DWEN; - /* CMLTE/CMD12EN */ - if (opc == MMC_CMD_READ_MULTIPLE_BLOCK || - opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) { - tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN; - sh_mmcif_bitset(data->blocks << 16, &host->regs->ce_block_set); - } - /* RIDXC[1:0] check bits */ - if (opc == MMC_CMD_SEND_OP_COND || opc == MMC_CMD_ALL_SEND_CID || - opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID) - tmp |= CMD_SET_RIDXC_BITS; - /* RCRC7C[1:0] check bits */ - if (opc == MMC_CMD_SEND_OP_COND) - tmp |= CMD_SET_CRC7C_BITS; - /* RCRC7C[1:0] internal CRC7 */ - if (opc == MMC_CMD_ALL_SEND_CID || - opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID) - tmp |= CMD_SET_CRC7C_INTERNAL; - - return opc = ((opc << 24) | tmp); -} - -static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host, - struct mmc_data *data, u16 opc) -{ - u32 ret; - - switch (opc) { - case MMC_CMD_READ_MULTIPLE_BLOCK: - ret = sh_mmcif_multi_read(host, data); - break; - case MMC_CMD_WRITE_MULTIPLE_BLOCK: - ret = sh_mmcif_multi_write(host, data); - break; - case MMC_CMD_WRITE_SINGLE_BLOCK: - ret = sh_mmcif_single_write(host, data); - break; - case MMC_CMD_READ_SINGLE_BLOCK: - case MMC_CMD_SEND_EXT_CSD: - ret = sh_mmcif_single_read(host, data); - break; - default: - printf(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc); - ret = -EINVAL; - break; - } - return ret; -} - -static int sh_mmcif_start_cmd(struct sh_mmcif_host *host, - struct mmc_data *data, struct mmc_cmd *cmd) -{ - long time; - int ret = 0, mask = 0; - u32 opc = cmd->cmdidx; - - if (opc == MMC_CMD_STOP_TRANSMISSION) { - /* MMCIF sends the STOP command automatically */ - if (host->last_cmd == MMC_CMD_READ_MULTIPLE_BLOCK) - sh_mmcif_bitset(MASK_MCMD12DRE, - &host->regs->ce_int_mask); - else - sh_mmcif_bitset(MASK_MCMD12RBE, - &host->regs->ce_int_mask); - - time = mmcif_wait_interrupt_flag(host); - if (time == 0 || host->sd_error != 0) - return sh_mmcif_error_manage(host); - - sh_mmcif_get_cmd12response(host, cmd); - return 0; - } - if (opc == MMC_CMD_SWITCH) - mask = MASK_MRBSYE; - else - mask = MASK_MCRSPE; - - mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | - MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | - MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | - MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO; - - if (host->data) { - sh_mmcif_write(0, &host->regs->ce_block_set); - sh_mmcif_write(data->blocksize, &host->regs->ce_block_set); - } - opc = sh_mmcif_set_cmd(host, data, cmd); - - sh_mmcif_write(INT_START_MAGIC, &host->regs->ce_int); - sh_mmcif_write(mask, &host->regs->ce_int_mask); - - debug("CMD%d ARG:%08x\n", cmd->cmdidx, cmd->cmdarg); - /* set arg */ - sh_mmcif_write(cmd->cmdarg, &host->regs->ce_arg); - host->wait_int = 0; - /* set cmd */ - sh_mmcif_write(opc, &host->regs->ce_cmd_set); - - time = mmcif_wait_interrupt_flag(host); - if (time == 0) - return sh_mmcif_error_manage(host); - - if (host->sd_error) { - switch (cmd->cmdidx) { - case MMC_CMD_ALL_SEND_CID: - case MMC_CMD_SELECT_CARD: - case MMC_CMD_APP_CMD: - ret = TIMEOUT; - break; - default: - printf(DRIVER_NAME": Cmd(d'%d) err\n", cmd->cmdidx); - ret = sh_mmcif_error_manage(host); - break; - } - host->sd_error = 0; - host->wait_int = 0; - return ret; - } - - /* if no response */ - if (!(opc & 0x00C00000)) - return 0; - - if (host->wait_int == 1) { - sh_mmcif_get_response(host, cmd); - host->wait_int = 0; - } - if (host->data) - ret = sh_mmcif_data_trans(host, data, cmd->cmdidx); - host->last_cmd = cmd->cmdidx; - - return ret; -} - -static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct sh_mmcif_host *host = mmc->priv; - int ret; - - WATCHDOG_RESET(); - - switch (cmd->cmdidx) { - case MMC_CMD_APP_CMD: - return TIMEOUT; - 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; - default: - break; - } - host->sd_error = 0; - host->data = data; - ret = sh_mmcif_start_cmd(host, data, cmd); - host->data = NULL; - - return ret; -} - -static void sh_mmcif_set_ios(struct mmc *mmc) -{ - struct sh_mmcif_host *host = mmc->priv; - - if (mmc->clock) - sh_mmcif_clock_control(host, mmc->clock); - - if (mmc->bus_width == 8) - host->bus_width = MMC_BUS_WIDTH_8; - else if (mmc->bus_width == 4) - host->bus_width = MMC_BUS_WIDTH_4; - else - host->bus_width = MMC_BUS_WIDTH_1; - - debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); -} - -static int sh_mmcif_init(struct mmc *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 | MMC_MODE_HC, - .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - .f_min = CLKDEV_MMC_INIT, - .f_max = CLKDEV_EMMC_DATA, - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, -}; - -int mmcif_mmc_init(void) -{ - struct mmc *mmc; - struct sh_mmcif_host *host = NULL; - - host = malloc(sizeof(struct sh_mmcif_host)); - if (!host) - return -ENOMEM; - memset(host, 0, sizeof(*host)); - - host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR; - host->clk = CONFIG_SH_MMCIF_CLK; - - mmc = mmc_create(&sh_mmcif_cfg, host); - if (mmc == NULL) { - free(host); - return -ENOMEM; - } - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/sh_mmcif.h b/qemu/roms/u-boot/drivers/mmc/sh_mmcif.h deleted file mode 100644 index bd6fbf7c6..000000000 --- a/qemu/roms/u-boot/drivers/mmc/sh_mmcif.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * MMCIF driver. - * - * 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. - * - */ - -#ifndef _SH_MMCIF_H_ -#define _SH_MMCIF_H_ - -struct sh_mmcif_regs { - unsigned long ce_cmd_set; - unsigned long reserved; - unsigned long ce_arg; - unsigned long ce_arg_cmd12; - unsigned long ce_cmd_ctrl; - unsigned long ce_block_set; - unsigned long ce_clk_ctrl; - unsigned long ce_buf_acc; - unsigned long ce_resp3; - unsigned long ce_resp2; - unsigned long ce_resp1; - unsigned long ce_resp0; - unsigned long ce_resp_cmd12; - unsigned long ce_data; - unsigned long reserved2[2]; - unsigned long ce_int; - unsigned long ce_int_mask; - unsigned long ce_host_sts1; - unsigned long ce_host_sts2; - unsigned long reserved3[11]; - unsigned long ce_version; -}; - -/* CE_CMD_SET */ -#define CMD_MASK 0x3f000000 -#define CMD_SET_RTYP_NO ((0 << 23) | (0 << 22)) -/* R1/R1b/R3/R4/R5 */ -#define CMD_SET_RTYP_6B ((0 << 23) | (1 << 22)) -/* R2 */ -#define CMD_SET_RTYP_17B ((1 << 23) | (0 << 22)) -/* R1b */ -#define CMD_SET_RBSY (1 << 21) -#define CMD_SET_CCSEN (1 << 20) -/* 1: on data, 0: no data */ -#define CMD_SET_WDAT (1 << 19) -/* 1: write to card, 0: read from card */ -#define CMD_SET_DWEN (1 << 18) -/* 1: multi block trans, 0: single */ -#define CMD_SET_CMLTE (1 << 17) -/* 1: CMD12 auto issue */ -#define CMD_SET_CMD12EN (1 << 16) -/* index check */ -#define CMD_SET_RIDXC_INDEX ((0 << 15) | (0 << 14)) -/* check bits check */ -#define CMD_SET_RIDXC_BITS ((0 << 15) | (1 << 14)) -/* no check */ -#define CMD_SET_RIDXC_NO ((1 << 15) | (0 << 14)) -/* 1: CRC7 check*/ -#define CMD_SET_CRC7C ((0 << 13) | (0 << 12)) -/* 1: check bits check*/ -#define CMD_SET_CRC7C_BITS ((0 << 13) | (1 << 12)) -/* 1: internal CRC7 check*/ -#define CMD_SET_CRC7C_INTERNAL ((1 << 13) | (0 << 12)) -/* 1: CRC16 check*/ -#define CMD_SET_CRC16C (1 << 10) -/* 1: not receive CRC status */ -#define CMD_SET_CRCSTE (1 << 8) -/* 1: tran mission bit "Low" */ -#define CMD_SET_TBIT (1 << 7) -/* 1: open/drain */ -#define CMD_SET_OPDM (1 << 6) -#define CMD_SET_CCSH (1 << 5) -/* 1bit */ -#define CMD_SET_DATW_1 ((0 << 1) | (0 << 0)) -/* 4bit */ -#define CMD_SET_DATW_4 ((0 << 1) | (1 << 0)) -/* 8bit */ -#define CMD_SET_DATW_8 ((1 << 1) | (0 << 0)) - -/* CE_CMD_CTRL */ -#define CMD_CTRL_BREAK (1 << 0) - -/* CE_BLOCK_SET */ -#define BLOCK_SIZE_MASK 0x0000ffff - -/* CE_CLK_CTRL */ -#define CLK_ENABLE (1 << 24) -#define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16)) -#define CLK_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16)) -/* respons timeout */ -#define SRSPTO_256 ((1 << 13) | (0 << 12)) -/* respons busy timeout */ -#define SRBSYTO_29 ((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8)) -/* read/write timeout */ -#define SRWDTO_29 ((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4)) -/* ccs timeout */ -#define SCCSTO_29 ((1 << 3) | (1 << 2) | (1 << 1) | (1 << 0)) - -/* CE_BUF_ACC */ -#define BUF_ACC_DMAWEN (1 << 25) -#define BUF_ACC_DMAREN (1 << 24) -#define BUF_ACC_BUSW_32 (0 << 17) -#define BUF_ACC_BUSW_16 (1 << 17) -#define BUF_ACC_ATYP (1 << 16) - -/* CE_INT */ -#define INT_CCSDE (1 << 29) -#define INT_CMD12DRE (1 << 26) -#define INT_CMD12RBE (1 << 25) -#define INT_CMD12CRE (1 << 24) -#define INT_DTRANE (1 << 23) -#define INT_BUFRE (1 << 22) -#define INT_BUFWEN (1 << 21) -#define INT_BUFREN (1 << 20) -#define INT_CCSRCV (1 << 19) -#define INT_RBSYE (1 << 17) -#define INT_CRSPE (1 << 16) -#define INT_CMDVIO (1 << 15) -#define INT_BUFVIO (1 << 14) -#define INT_WDATERR (1 << 11) -#define INT_RDATERR (1 << 10) -#define INT_RIDXERR (1 << 9) -#define INT_RSPERR (1 << 8) -#define INT_CCSTO (1 << 5) -#define INT_CRCSTO (1 << 4) -#define INT_WDATTO (1 << 3) -#define INT_RDATTO (1 << 2) -#define INT_RBSYTO (1 << 1) -#define INT_RSPTO (1 << 0) -#define INT_ERR_STS (INT_CMDVIO | INT_BUFVIO | INT_WDATERR | \ - INT_RDATERR | INT_RIDXERR | INT_RSPERR | \ - INT_CCSTO | INT_CRCSTO | INT_WDATTO | \ - INT_RDATTO | INT_RBSYTO | INT_RSPTO) -#define INT_START_MAGIC 0xD80430C0 - -/* CE_INT_MASK */ -#define MASK_ALL 0x00000000 -#define MASK_MCCSDE (1 << 29) -#define MASK_MCMD12DRE (1 << 26) -#define MASK_MCMD12RBE (1 << 25) -#define MASK_MCMD12CRE (1 << 24) -#define MASK_MDTRANE (1 << 23) -#define MASK_MBUFRE (1 << 22) -#define MASK_MBUFWEN (1 << 21) -#define MASK_MBUFREN (1 << 20) -#define MASK_MCCSRCV (1 << 19) -#define MASK_MRBSYE (1 << 17) -#define MASK_MCRSPE (1 << 16) -#define MASK_MCMDVIO (1 << 15) -#define MASK_MBUFVIO (1 << 14) -#define MASK_MWDATERR (1 << 11) -#define MASK_MRDATERR (1 << 10) -#define MASK_MRIDXERR (1 << 9) -#define MASK_MRSPERR (1 << 8) -#define MASK_MCCSTO (1 << 5) -#define MASK_MCRCSTO (1 << 4) -#define MASK_MWDATTO (1 << 3) -#define MASK_MRDATTO (1 << 2) -#define MASK_MRBSYTO (1 << 1) -#define MASK_MRSPTO (1 << 0) - -/* CE_HOST_STS1 */ -#define STS1_CMDSEQ (1 << 31) - -/* CE_HOST_STS2 */ -#define STS2_CRCSTE (1 << 31) -#define STS2_CRC16E (1 << 30) -#define STS2_AC12CRCE (1 << 29) -#define STS2_RSPCRC7E (1 << 28) -#define STS2_CRCSTEBE (1 << 27) -#define STS2_RDATEBE (1 << 26) -#define STS2_AC12REBE (1 << 25) -#define STS2_RSPEBE (1 << 24) -#define STS2_AC12IDXE (1 << 23) -#define STS2_RSPIDXE (1 << 22) -#define STS2_CCSTO (1 << 15) -#define STS2_RDATTO (1 << 14) -#define STS2_DATBSYTO (1 << 13) -#define STS2_CRCSTTO (1 << 12) -#define STS2_AC12BSYTO (1 << 11) -#define STS2_RSPBSYTO (1 << 10) -#define STS2_AC12RSPTO (1 << 9) -#define STS2_RSPTO (1 << 8) - -#define STS2_CRC_ERR (STS2_CRCSTE | STS2_CRC16E | \ - STS2_AC12CRCE | STS2_RSPCRC7E | STS2_CRCSTEBE) -#define STS2_TIMEOUT_ERR (STS2_CCSTO | STS2_RDATTO | \ - STS2_DATBSYTO | STS2_CRCSTTO | \ - STS2_AC12BSYTO | STS2_RSPBSYTO | \ - STS2_AC12RSPTO | STS2_RSPTO) - -/* CE_VERSION */ -#define SOFT_RST_ON (1 << 31) -#define SOFT_RST_OFF (0 << 31) - -#define CLKDEV_EMMC_DATA 52000000 /* 52MHz */ -#define CLKDEV_MMC_INIT 400000 /* 100 - 400 KHz */ - -#define MMC_BUS_WIDTH_1 0 -#define MMC_BUS_WIDTH_4 2 -#define MMC_BUS_WIDTH_8 3 - -struct sh_mmcif_host { - struct mmc_data *data; - struct sh_mmcif_regs *regs; - unsigned int clk; - int bus_width; - u16 wait_int; - u16 sd_error; - u8 last_cmd; -}; - -static inline u32 sh_mmcif_read(unsigned long *reg) -{ - return readl(reg); -} - -static inline void sh_mmcif_write(u32 val, unsigned long *reg) -{ - writel(val, reg); -} - -static inline void sh_mmcif_bitset(u32 val, unsigned long *reg) -{ - sh_mmcif_write(val | sh_mmcif_read(reg), reg); -} - -static inline void sh_mmcif_bitclr(u32 val, unsigned long *reg) -{ - sh_mmcif_write(~val & sh_mmcif_read(reg), reg); -} - -#endif /* _SH_MMCIF_H_ */ diff --git a/qemu/roms/u-boot/drivers/mmc/socfpga_dw_mmc.c b/qemu/roms/u-boot/drivers/mmc/socfpga_dw_mmc.c deleted file mode 100644 index bc53a5da2..000000000 --- a/qemu/roms/u-boot/drivers/mmc/socfpga_dw_mmc.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) Copyright 2013 Altera Corporation <www.altera.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <dwmmc.h> -#include <asm/arch/dwmmc.h> -#include <asm/arch/clock_manager.h> -#include <asm/arch/system_manager.h> - -static const struct socfpga_clock_manager *clock_manager_base = - (void *)SOCFPGA_CLKMGR_ADDRESS; -static const struct socfpga_system_manager *system_manager_base = - (void *)SOCFPGA_SYSMGR_ADDRESS; - -static char *SOCFPGA_NAME = "SOCFPGA DWMMC"; - -static void socfpga_dwmci_clksel(struct dwmci_host *host) -{ - unsigned int drvsel; - unsigned int smplsel; - - /* Disable SDMMC clock. */ - clrbits_le32(&clock_manager_base->per_pll_en, - CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); - - /* Configures drv_sel and smpl_sel */ - drvsel = CONFIG_SOCFPGA_DWMMC_DRVSEL; - smplsel = CONFIG_SOCFPGA_DWMMC_SMPSEL; - - debug("%s: drvsel %d smplsel %d\n", __func__, drvsel, smplsel); - writel(SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel), - &system_manager_base->sdmmcgrp_ctrl); - - debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__, - readl(&system_manager_base->sdmmcgrp_ctrl)); - - /* Enable SDMMC clock */ - setbits_le32(&clock_manager_base->per_pll_en, - CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); -} - -int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) -{ - struct dwmci_host *host = NULL; - host = calloc(sizeof(struct dwmci_host), 1); - if (!host) { - printf("dwmci_host calloc fail!\n"); - return -1; - } - - host->name = SOCFPGA_NAME; - host->ioaddr = (void *)regbase; - host->buswidth = bus_width; - host->clksel = socfpga_dwmci_clksel; - host->dev_index = index; - /* fixed clock divide by 4 which due to the SDMMC wrapper */ - host->bus_hz = CONFIG_SOCFPGA_DWMMC_BUS_HZ; - host->fifoth_val = MSIZE(0x2) | - RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | - TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2); - - return add_dwmci(host, host->bus_hz, 400000); -} - diff --git a/qemu/roms/u-boot/drivers/mmc/spear_sdhci.c b/qemu/roms/u-boot/drivers/mmc/spear_sdhci.c deleted file mode 100644 index 6ca96a2d0..000000000 --- a/qemu/roms/u-boot/drivers/mmc/spear_sdhci.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * (C) Copyright 2012 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <sdhci.h> - -int spear_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) -{ - struct sdhci_host *host = NULL; - host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); - if (!host) { - printf("sdhci host malloc fail!\n"); - return 1; - } - - host->name = "sdhci"; - host->ioaddr = (void *)regbase; - host->quirks = quirks; - - if (quirks & SDHCI_QUIRK_REG32_RW) - host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16; - else - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - - add_sdhci(host, max_clk, min_clk); - return 0; -} diff --git a/qemu/roms/u-boot/drivers/mmc/tegra_mmc.c b/qemu/roms/u-boot/drivers/mmc/tegra_mmc.c deleted file mode 100644 index ed67eec25..000000000 --- a/qemu/roms/u-boot/drivers/mmc/tegra_mmc.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * (C) Copyright 2009 SAMSUNG Electronics - * Minkyu Kang <mk7.kang@samsung.com> - * Jaehoon Chung <jh80.chung@samsung.com> - * Portions Copyright 2011-2013 NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <bouncebuf.h> -#include <common.h> -#include <asm/gpio.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch-tegra/clk_rst.h> -#include <asm/arch-tegra/tegra_mmc.h> -#include <mmc.h> - -DECLARE_GLOBAL_DATA_PTR; - -struct mmc_host mmc_host[MAX_HOSTS]; - -#ifndef CONFIG_OF_CONTROL -#error "Please enable device tree support to use this driver" -#endif - -static void mmc_set_power(struct mmc_host *host, unsigned short power) -{ - u8 pwr = 0; - debug("%s: power = %x\n", __func__, power); - - if (power != (unsigned short)-1) { - switch (1 << power) { - case MMC_VDD_165_195: - pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8; - break; - case MMC_VDD_29_30: - case MMC_VDD_30_31: - pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0; - break; - case MMC_VDD_32_33: - case MMC_VDD_33_34: - pwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3; - break; - } - } - debug("%s: pwr = %X\n", __func__, pwr); - - /* Set the bus voltage first (if any) */ - writeb(pwr, &host->reg->pwrcon); - if (pwr == 0) - return; - - /* Now enable bus power */ - pwr |= TEGRA_MMC_PWRCTL_SD_BUS_POWER; - writeb(pwr, &host->reg->pwrcon); -} - -static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data, - struct bounce_buffer *bbstate) -{ - unsigned char ctrl; - - - debug("buf: %p (%p), data->blocks: %u, data->blocksize: %u\n", - bbstate->bounce_buffer, bbstate->user_buffer, data->blocks, - data->blocksize); - - writel((u32)bbstate->bounce_buffer, &host->reg->sysad); - /* - * DMASEL[4:3] - * 00 = Selects SDMA - * 01 = Reserved - * 10 = Selects 32-bit Address ADMA2 - * 11 = Selects 64-bit Address ADMA2 - */ - ctrl = readb(&host->reg->hostctl); - ctrl &= ~TEGRA_MMC_HOSTCTL_DMASEL_MASK; - ctrl |= TEGRA_MMC_HOSTCTL_DMASEL_SDMA; - writeb(ctrl, &host->reg->hostctl); - - /* We do not handle DMA boundaries, so set it to max (512 KiB) */ - writew((7 << 12) | (data->blocksize & 0xFFF), &host->reg->blksize); - writew(data->blocks, &host->reg->blkcnt); -} - -static void mmc_set_transfer_mode(struct mmc_host *host, struct mmc_data *data) -{ - unsigned short mode; - debug(" mmc_set_transfer_mode called\n"); - /* - * TRNMOD - * MUL1SIN0[5] : Multi/Single Block Select - * RD1WT0[4] : Data Transfer Direction Select - * 1 = read - * 0 = write - * ENACMD12[2] : Auto CMD12 Enable - * ENBLKCNT[1] : Block Count Enable - * ENDMA[0] : DMA Enable - */ - mode = (TEGRA_MMC_TRNMOD_DMA_ENABLE | - TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE); - - if (data->blocks > 1) - mode |= TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT; - - if (data->flags & MMC_DATA_READ) - mode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ; - - writew(mode, &host->reg->trnmod); -} - -static int mmc_wait_inhibit(struct mmc_host *host, - struct mmc_cmd *cmd, - struct mmc_data *data, - unsigned int timeout) -{ - /* - * PRNSTS - * CMDINHDAT[1] : Command Inhibit (DAT) - * CMDINHCMD[0] : Command Inhibit (CMD) - */ - unsigned int mask = TEGRA_MMC_PRNSTS_CMD_INHIBIT_CMD; - - /* - * We shouldn't wait for data inhibit for stop commands, even - * though they might use busy signaling - */ - if ((data == NULL) && (cmd->resp_type & MMC_RSP_BUSY)) - mask |= TEGRA_MMC_PRNSTS_CMD_INHIBIT_DAT; - - while (readl(&host->reg->prnsts) & mask) { - if (timeout == 0) { - printf("%s: timeout error\n", __func__); - return -1; - } - timeout--; - udelay(1000); - } - - return 0; -} - -static int mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data, struct bounce_buffer *bbstate) -{ - struct mmc_host *host = mmc->priv; - int flags, i; - int result; - unsigned int mask = 0; - unsigned int retry = 0x100000; - debug(" mmc_send_cmd called\n"); - - result = mmc_wait_inhibit(host, cmd, data, 10 /* ms */); - - if (result < 0) - return result; - - if (data) - mmc_prepare_data(host, data, bbstate); - - debug("cmd->arg: %08x\n", cmd->cmdarg); - writel(cmd->cmdarg, &host->reg->argument); - - if (data) - mmc_set_transfer_mode(host, data); - - if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) - return -1; - - /* - * CMDREG - * CMDIDX[13:8] : Command index - * DATAPRNT[5] : Data Present Select - * ENCMDIDX[4] : Command Index Check Enable - * ENCMDCRC[3] : Command CRC Check Enable - * RSPTYP[1:0] - * 00 = No Response - * 01 = Length 136 - * 10 = Length 48 - * 11 = Length 48 Check busy after response - */ - if (!(cmd->resp_type & MMC_RSP_PRESENT)) - flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE; - else if (cmd->resp_type & MMC_RSP_136) - flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136; - else if (cmd->resp_type & MMC_RSP_BUSY) - flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY; - else - flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48; - - if (cmd->resp_type & MMC_RSP_CRC) - flags |= TEGRA_MMC_TRNMOD_CMD_CRC_CHECK; - if (cmd->resp_type & MMC_RSP_OPCODE) - flags |= TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK; - if (data) - flags |= TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER; - - debug("cmd: %d\n", cmd->cmdidx); - - writew((cmd->cmdidx << 8) | flags, &host->reg->cmdreg); - - for (i = 0; i < retry; i++) { - mask = readl(&host->reg->norintsts); - /* Command Complete */ - if (mask & TEGRA_MMC_NORINTSTS_CMD_COMPLETE) { - if (!data) - writel(mask, &host->reg->norintsts); - break; - } - } - - if (i == retry) { - printf("%s: waiting for status update\n", __func__); - writel(mask, &host->reg->norintsts); - return TIMEOUT; - } - - if (mask & TEGRA_MMC_NORINTSTS_CMD_TIMEOUT) { - /* Timeout Error */ - debug("timeout: %08x cmd %d\n", mask, cmd->cmdidx); - writel(mask, &host->reg->norintsts); - return TIMEOUT; - } else if (mask & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) { - /* Error Interrupt */ - debug("error: %08x cmd %d\n", mask, cmd->cmdidx); - writel(mask, &host->reg->norintsts); - return -1; - } - - if (cmd->resp_type & MMC_RSP_PRESENT) { - if (cmd->resp_type & MMC_RSP_136) { - /* CRC is stripped so we need to do some shifting. */ - for (i = 0; i < 4; i++) { - unsigned int offset = - (unsigned int)(&host->reg->rspreg3 - i); - cmd->response[i] = readl(offset) << 8; - - if (i != 3) { - cmd->response[i] |= - readb(offset - 1); - } - debug("cmd->resp[%d]: %08x\n", - i, cmd->response[i]); - } - } else if (cmd->resp_type & MMC_RSP_BUSY) { - for (i = 0; i < retry; i++) { - /* PRNTDATA[23:20] : DAT[3:0] Line Signal */ - if (readl(&host->reg->prnsts) - & (1 << 20)) /* DAT[0] */ - break; - } - - if (i == retry) { - printf("%s: card is still busy\n", __func__); - writel(mask, &host->reg->norintsts); - return TIMEOUT; - } - - cmd->response[0] = readl(&host->reg->rspreg0); - debug("cmd->resp[0]: %08x\n", cmd->response[0]); - } else { - cmd->response[0] = readl(&host->reg->rspreg0); - debug("cmd->resp[0]: %08x\n", cmd->response[0]); - } - } - - if (data) { - unsigned long start = get_timer(0); - - while (1) { - mask = readl(&host->reg->norintsts); - - if (mask & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) { - /* Error Interrupt */ - writel(mask, &host->reg->norintsts); - printf("%s: error during transfer: 0x%08x\n", - __func__, mask); - return -1; - } else if (mask & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT) { - /* - * DMA Interrupt, restart the transfer where - * it was interrupted. - */ - unsigned int address = readl(&host->reg->sysad); - - debug("DMA end\n"); - writel(TEGRA_MMC_NORINTSTS_DMA_INTERRUPT, - &host->reg->norintsts); - writel(address, &host->reg->sysad); - } else if (mask & TEGRA_MMC_NORINTSTS_XFER_COMPLETE) { - /* Transfer Complete */ - debug("r/w is done\n"); - break; - } else if (get_timer(start) > 2000UL) { - writel(mask, &host->reg->norintsts); - printf("%s: MMC Timeout\n" - " Interrupt status 0x%08x\n" - " Interrupt status enable 0x%08x\n" - " Interrupt signal enable 0x%08x\n" - " Present status 0x%08x\n", - __func__, mask, - readl(&host->reg->norintstsen), - readl(&host->reg->norintsigen), - readl(&host->reg->prnsts)); - return -1; - } - } - writel(mask, &host->reg->norintsts); - } - - udelay(1000); - return 0; -} - -static int tegra_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - void *buf; - unsigned int bbflags; - size_t len; - struct bounce_buffer bbstate; - int ret; - - if (data) { - if (data->flags & MMC_DATA_READ) { - buf = data->dest; - bbflags = GEN_BB_WRITE; - } else { - buf = (void *)data->src; - bbflags = GEN_BB_READ; - } - len = data->blocks * data->blocksize; - - bounce_buffer_start(&bbstate, buf, len, bbflags); - } - - ret = mmc_send_cmd_bounced(mmc, cmd, data, &bbstate); - - if (data) - bounce_buffer_stop(&bbstate); - - return ret; -} - -static void mmc_change_clock(struct mmc_host *host, uint clock) -{ - int div; - unsigned short clk; - unsigned long timeout; - - debug(" mmc_change_clock called\n"); - - /* - * Change Tegra SDMMCx clock divisor here. Source is PLLP_OUT0 - */ - if (clock == 0) - goto out; - clock_adjust_periph_pll_div(host->mmc_id, CLOCK_ID_PERIPH, clock, - &div); - debug("div = %d\n", div); - - writew(0, &host->reg->clkcon); - - /* - * CLKCON - * SELFREQ[15:8] : base clock divided by value - * ENSDCLK[2] : SD Clock Enable - * STBLINTCLK[1] : Internal Clock Stable - * ENINTCLK[0] : Internal Clock Enable - */ - div >>= 1; - clk = ((div << TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_SHIFT) | - TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE); - writew(clk, &host->reg->clkcon); - - /* Wait max 10 ms */ - timeout = 10; - while (!(readw(&host->reg->clkcon) & - TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE)) { - if (timeout == 0) { - printf("%s: timeout error\n", __func__); - return; - } - timeout--; - udelay(1000); - } - - clk |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; - writew(clk, &host->reg->clkcon); - - debug("mmc_change_clock: clkcon = %08X\n", clk); - -out: - host->clock = clock; -} - -static void tegra_mmc_set_ios(struct mmc *mmc) -{ - struct mmc_host *host = mmc->priv; - unsigned char ctrl; - debug(" mmc_set_ios called\n"); - - debug("bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock); - - /* Change clock first */ - mmc_change_clock(host, mmc->clock); - - ctrl = readb(&host->reg->hostctl); - - /* - * WIDE8[5] - * 0 = Depend on WIDE4 - * 1 = 8-bit mode - * WIDE4[1] - * 1 = 4-bit mode - * 0 = 1-bit mode - */ - if (mmc->bus_width == 8) - ctrl |= (1 << 5); - else if (mmc->bus_width == 4) - ctrl |= (1 << 1); - else - ctrl &= ~(1 << 1); - - writeb(ctrl, &host->reg->hostctl); - debug("mmc_set_ios: hostctl = %08X\n", ctrl); -} - -static void mmc_reset(struct mmc_host *host, struct mmc *mmc) -{ - unsigned int timeout; - debug(" mmc_reset called\n"); - - /* - * RSTALL[0] : Software reset for all - * 1 = reset - * 0 = work - */ - writeb(TEGRA_MMC_SWRST_SW_RESET_FOR_ALL, &host->reg->swrst); - - host->clock = 0; - - /* Wait max 100 ms */ - timeout = 100; - - /* hw clears the bit when it's done */ - while (readb(&host->reg->swrst) & TEGRA_MMC_SWRST_SW_RESET_FOR_ALL) { - if (timeout == 0) { - printf("%s: timeout error\n", __func__); - return; - } - timeout--; - udelay(1000); - } - - /* Set SD bus voltage & enable bus power */ - mmc_set_power(host, fls(mmc->cfg->voltages) - 1); - debug("%s: power control = %02X, host control = %02X\n", __func__, - readb(&host->reg->pwrcon), readb(&host->reg->hostctl)); - - /* Make sure SDIO pads are set up */ - pad_init_mmc(host); -} - -static int tegra_mmc_core_init(struct mmc *mmc) -{ - struct mmc_host *host = mmc->priv; - unsigned int mask; - debug(" mmc_core_init called\n"); - - mmc_reset(host, mmc); - - host->version = readw(&host->reg->hcver); - debug("host version = %x\n", host->version); - - /* mask all */ - writel(0xffffffff, &host->reg->norintstsen); - writel(0xffffffff, &host->reg->norintsigen); - - writeb(0xe, &host->reg->timeoutcon); /* TMCLK * 2^27 */ - /* - * NORMAL Interrupt Status Enable Register init - * [5] ENSTABUFRDRDY : Buffer Read Ready Status Enable - * [4] ENSTABUFWTRDY : Buffer write Ready Status Enable - * [3] ENSTADMAINT : DMA boundary interrupt - * [1] ENSTASTANSCMPLT : Transfre Complete Status Enable - * [0] ENSTACMDCMPLT : Command Complete Status Enable - */ - mask = readl(&host->reg->norintstsen); - mask &= ~(0xffff); - mask |= (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | - TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | - TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT | - TEGRA_MMC_NORINTSTSEN_BUFFER_WRITE_READY | - TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY); - writel(mask, &host->reg->norintstsen); - - /* - * NORMAL Interrupt Signal Enable Register init - * [1] ENSTACMDCMPLT : Transfer Complete Signal Enable - */ - mask = readl(&host->reg->norintsigen); - mask &= ~(0xffff); - mask |= TEGRA_MMC_NORINTSIGEN_XFER_COMPLETE; - writel(mask, &host->reg->norintsigen); - - return 0; -} - -int tegra_mmc_getcd(struct mmc *mmc) -{ - struct mmc_host *host = mmc->priv; - - debug("tegra_mmc_getcd called\n"); - - if (fdt_gpio_isvalid(&host->cd_gpio)) - return fdtdec_get_gpio(&host->cd_gpio); - - return 1; -} - -static const struct mmc_ops tegra_mmc_ops = { - .send_cmd = tegra_mmc_send_cmd, - .set_ios = tegra_mmc_set_ios, - .init = tegra_mmc_core_init, - .getcd = tegra_mmc_getcd, -}; - -static int do_mmc_init(int dev_index) -{ - struct mmc_host *host; - char gpusage[12]; /* "SD/MMCn PWR" or "SD/MMCn CD" */ - struct mmc *mmc; - - /* DT should have been read & host config filled in */ - host = &mmc_host[dev_index]; - if (!host->enabled) - return -1; - - debug(" do_mmc_init: index %d, bus width %d " - "pwr_gpio %d cd_gpio %d\n", - dev_index, host->width, - host->pwr_gpio.gpio, host->cd_gpio.gpio); - - host->clock = 0; - clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000); - - if (fdt_gpio_isvalid(&host->pwr_gpio)) { - sprintf(gpusage, "SD/MMC%d PWR", dev_index); - gpio_request(host->pwr_gpio.gpio, gpusage); - gpio_direction_output(host->pwr_gpio.gpio, 1); - debug(" Power GPIO name = %s\n", host->pwr_gpio.name); - } - - if (fdt_gpio_isvalid(&host->cd_gpio)) { - sprintf(gpusage, "SD/MMC%d CD", dev_index); - gpio_request(host->cd_gpio.gpio, gpusage); - gpio_direction_input(host->cd_gpio.gpio); - debug(" CD GPIO name = %s\n", host->cd_gpio.name); - } - - memset(&host->cfg, 0, sizeof(host->cfg)); - - host->cfg.name = "Tegra SD/MMC"; - host->cfg.ops = &tegra_mmc_ops; - - host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - host->cfg.host_caps = 0; - if (host->width == 8) - host->cfg.host_caps |= MMC_MODE_8BIT; - if (host->width >= 4) - host->cfg.host_caps |= MMC_MODE_4BIT; - host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC; - - /* - * min freq is for card identification, and is the highest - * low-speed SDIO card frequency (actually 400KHz) - * max freq is highest HS eMMC clock as per the SD/MMC spec - * (actually 52MHz) - */ - host->cfg.f_min = 375000; - host->cfg.f_max = 48000000; - - host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - mmc = mmc_create(&host->cfg, host); - if (mmc == NULL) - return -1; - - return 0; -} - -/** - * Get the host address and peripheral ID for a node. - * - * @param blob fdt blob - * @param node Device index (0-3) - * @param host Structure to fill in (reg, width, mmc_id) - */ -static int mmc_get_config(const void *blob, int node, struct mmc_host *host) -{ - debug("%s: node = %d\n", __func__, node); - - host->enabled = fdtdec_get_is_enabled(blob, node); - - host->reg = (struct tegra_mmc *)fdtdec_get_addr(blob, node, "reg"); - if ((fdt_addr_t)host->reg == FDT_ADDR_T_NONE) { - debug("%s: no sdmmc base reg info found\n", __func__); - return -FDT_ERR_NOTFOUND; - } - - host->mmc_id = clock_decode_periph_id(blob, node); - if (host->mmc_id == PERIPH_ID_NONE) { - debug("%s: could not decode periph id\n", __func__); - return -FDT_ERR_NOTFOUND; - } - - /* - * NOTE: mmc->bus_width is determined by mmc.c dynamically. - * TBD: Override it with this value? - */ - host->width = fdtdec_get_int(blob, node, "bus-width", 0); - if (!host->width) - debug("%s: no sdmmc width found\n", __func__); - - /* These GPIOs are optional */ - fdtdec_decode_gpio(blob, node, "cd-gpios", &host->cd_gpio); - fdtdec_decode_gpio(blob, node, "wp-gpios", &host->wp_gpio); - fdtdec_decode_gpio(blob, node, "power-gpios", &host->pwr_gpio); - - debug("%s: found controller at %p, width = %d, periph_id = %d\n", - __func__, host->reg, host->width, host->mmc_id); - return 0; -} - -/* - * Process a list of nodes, adding them to our list of SDMMC ports. - * - * @param blob fdt blob - * @param node_list list of nodes to process (any <=0 are ignored) - * @param count number of nodes to process - * @return 0 if ok, -1 on error - */ -static int process_nodes(const void *blob, int node_list[], int count) -{ - struct mmc_host *host; - int i, node; - - debug("%s: count = %d\n", __func__, count); - - /* build mmc_host[] for each controller */ - for (i = 0; i < count; i++) { - node = node_list[i]; - if (node <= 0) - continue; - - host = &mmc_host[i]; - host->id = i; - - if (mmc_get_config(blob, node, host)) { - printf("%s: failed to decode dev %d\n", __func__, i); - return -1; - } - do_mmc_init(i); - } - return 0; -} - -void tegra_mmc_init(void) -{ - int node_list[MAX_HOSTS], count; - const void *blob = gd->fdt_blob; - debug("%s entry\n", __func__); - - /* See if any Tegra124 MMC controllers are present */ - count = fdtdec_find_aliases_for_id(blob, "sdhci", - COMPAT_NVIDIA_TEGRA124_SDMMC, node_list, MAX_HOSTS); - debug("%s: count of Tegra124 sdhci nodes is %d\n", __func__, count); - if (process_nodes(blob, node_list, count)) { - printf("%s: Error processing T30 mmc node(s)!\n", __func__); - return; - } - - /* See if any Tegra30 MMC controllers are present */ - count = fdtdec_find_aliases_for_id(blob, "sdhci", - COMPAT_NVIDIA_TEGRA30_SDMMC, node_list, MAX_HOSTS); - debug("%s: count of T30 sdhci nodes is %d\n", __func__, count); - if (process_nodes(blob, node_list, count)) { - printf("%s: Error processing T30 mmc node(s)!\n", __func__); - return; - } - - /* Now look for any Tegra20 MMC controllers */ - count = fdtdec_find_aliases_for_id(blob, "sdhci", - COMPAT_NVIDIA_TEGRA20_SDMMC, node_list, MAX_HOSTS); - debug("%s: count of T20 sdhci nodes is %d\n", __func__, count); - if (process_nodes(blob, node_list, count)) { - printf("%s: Error processing T20 mmc node(s)!\n", __func__); - return; - } -} diff --git a/qemu/roms/u-boot/drivers/mmc/zynq_sdhci.c b/qemu/roms/u-boot/drivers/mmc/zynq_sdhci.c deleted file mode 100644 index fdce2c2c1..000000000 --- a/qemu/roms/u-boot/drivers/mmc/zynq_sdhci.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * (C) Copyright 2013 Inc. - * - * Xilinx Zynq SD Host Controller Interface - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <fdtdec.h> -#include <libfdt.h> -#include <malloc.h> -#include <sdhci.h> -#include <asm/arch/sys_proto.h> - -int zynq_sdhci_init(u32 regbase) -{ - struct sdhci_host *host = NULL; - - host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); - if (!host) { - printf("zynq_sdhci_init: sdhci_host malloc fail\n"); - return 1; - } - - host->name = "zynq_sdhci"; - host->ioaddr = (void *)regbase; - host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD | - SDHCI_QUIRK_BROKEN_R1B; - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - - host->host_caps = MMC_MODE_HC; - - add_sdhci(host, 52000000, 52000000 >> 9); - return 0; -} - -#ifdef CONFIG_OF_CONTROL -int zynq_sdhci_of_init(const void *blob) -{ - int offset = 0; - u32 ret = 0; - u32 reg; - - debug("ZYNQ SDHCI: Initialization\n"); - - do { - offset = fdt_node_offset_by_compatible(blob, offset, - "arasan,sdhci-8.9a"); - if (offset != -1) { - reg = fdtdec_get_addr(blob, offset, "reg"); - if (reg != FDT_ADDR_T_NONE) { - ret |= zynq_sdhci_init(reg); - } else { - debug("ZYNQ SDHCI: Can't get base address\n"); - return -1; - } - } - } while (offset != -1); - - return ret; -} -#endif |