diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/Makefile | 4 | ||||
-rw-r--r-- | drivers/mmc/arm_pl180_mmci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 45 | ||||
-rw-r--r-- | drivers/mmc/pxa_mmc_gen.c | 8 | ||||
-rw-r--r-- | drivers/mmc/s5p_sdhci.c | 18 | ||||
-rw-r--r-- | drivers/mmc/sdhci.c | 30 | ||||
-rw-r--r-- | drivers/mmc/sh_mmcif.c | 2 | ||||
-rw-r--r-- | drivers/mmc/spl_mmc.c | 136 | ||||
-rw-r--r-- | drivers/mmc/spl_mmc_load.c | 62 |
9 files changed, 186 insertions, 121 deletions
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2b96cdc..565ba6a 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -25,8 +25,8 @@ include $(TOPDIR)/config.mk LIB := $(obj)libmmc.o -ifdef CONFIG_SPL_MMC_LOAD -COBJS-$(CONFIG_SPL_MMC_LOAD) += spl_mmc_load.o +ifdef CONFIG_SPL_BUILD +COBJS-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o endif COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index db2c7ab..af1380a 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -52,7 +52,7 @@ static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd) debug("CMD%d time out\n", cmd->cmdidx); return TIMEOUT; } else if ((hoststatus & SDI_STA_CCRCFAIL) && - (cmd->flags & MMC_RSP_CRC)) { + (cmd->resp_type & MMC_RSP_CRC)) { printf("CMD%d CRC error\n", cmd->cmdidx); return -EILSEQ; } diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 551d6a9..a60cfe1 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -151,7 +151,6 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) printf("CMD_SEND:%d\n", cmd->cmdidx); printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); - printf("\t\tFLAG\t\t\t %d\n", cmd->flags); ret = mmc->send_cmd(mmc, cmd, data); switch (cmd->resp_type) { case MMC_RSP_NONE: @@ -213,7 +212,6 @@ int mmc_send_status(struct mmc *mmc, int timeout) cmd.resp_type = MMC_RSP_R1; if (!mmc_host_is_spi(mmc)) cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; do { err = mmc_send_cmd(mmc, &cmd, NULL); @@ -238,7 +236,7 @@ int mmc_send_status(struct mmc *mmc, int timeout) status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; printf("CURR STATE:%d\n", status); #endif - if (!timeout) { + if (timeout <= 0) { printf("Timeout waiting card ready\n"); return TIMEOUT; } @@ -253,7 +251,6 @@ int mmc_set_blocklen(struct mmc *mmc, int len) cmd.cmdidx = MMC_CMD_SET_BLOCKLEN; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = len; - cmd.flags = 0; return mmc_send_cmd(mmc, &cmd, NULL); } @@ -299,7 +296,6 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) cmd.cmdidx = start_cmd; cmd.cmdarg = start; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -386,7 +382,6 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) cmd.cmdarg = start * mmc->write_bl_len; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; data.src = src; data.blocks = blkcnt; @@ -405,7 +400,6 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1b; - cmd.flags = 0; if (mmc_send_cmd(mmc, &cmd, NULL)) { printf("mmc fail to send stop cmd\n"); return 0; @@ -459,7 +453,6 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) cmd.cmdarg = start * mmc->read_bl_len; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; data.dest = dst; data.blocks = blkcnt; @@ -473,7 +466,6 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1b; - cmd.flags = 0; if (mmc_send_cmd(mmc, &cmd, NULL)) { printf("mmc fail to send stop cmd\n"); return 0; @@ -525,7 +517,6 @@ int mmc_go_idle(struct mmc* mmc) cmd.cmdidx = MMC_CMD_GO_IDLE_STATE; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_NONE; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -548,7 +539,6 @@ sd_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -589,7 +579,6 @@ sd_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_READ_OCR; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -618,7 +607,6 @@ int mmc_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SEND_OP_COND; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -638,8 +626,6 @@ int mmc_send_op_cond(struct mmc *mmc) if (mmc->host_caps & MMC_MODE_HC) cmd.cmdarg |= OCR_HCS; - cmd.flags = 0; - err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -655,7 +641,6 @@ int mmc_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_READ_OCR; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -673,7 +658,7 @@ int mmc_send_op_cond(struct mmc *mmc) } -int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd) +int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) { struct mmc_cmd cmd; struct mmc_data data; @@ -683,9 +668,8 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd) cmd.cmdidx = MMC_CMD_SEND_EXT_CSD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; - data.dest = ext_csd; + data.dest = (char *)ext_csd; data.blocks = 1; data.blocksize = 512; data.flags = MMC_DATA_READ; @@ -707,7 +691,6 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | (index << 16) | (value << 8); - cmd.flags = 0; ret = mmc_send_cmd(mmc, &cmd, NULL); @@ -721,7 +704,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) int mmc_change_freq(struct mmc *mmc) { - ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); char cardtype; int err; @@ -800,7 +783,6 @@ int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) cmd.cmdarg = (mode << 31) | 0xffffff; cmd.cmdarg &= ~(0xf << (group * 4)); cmd.cmdarg |= value << (group * 4); - cmd.flags = 0; data.dest = (char *)resp; data.blocksize = 64; @@ -829,7 +811,6 @@ int sd_change_freq(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -839,7 +820,6 @@ int sd_change_freq(struct mmc *mmc) cmd.cmdidx = SD_CMD_APP_SEND_SCR; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; timeout = 3; @@ -983,8 +963,8 @@ int mmc_startup(struct mmc *mmc) uint mult, freq; u64 cmult, csize, capacity; struct mmc_cmd cmd; - ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512); - ALLOC_CACHE_ALIGN_BUFFER(char, test_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512); int timeout = 1000; #ifdef CONFIG_MMC_SPI_CRC_ON @@ -992,7 +972,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 1; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1005,7 +984,6 @@ int mmc_startup(struct mmc *mmc) MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */ cmd.resp_type = MMC_RSP_R2; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1023,7 +1001,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR; cmd.cmdarg = mmc->rca << 16; cmd.resp_type = MMC_RSP_R6; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1038,7 +1015,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SEND_CSD; cmd.resp_type = MMC_RSP_R2; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1115,7 +1091,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SELECT_CARD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1183,7 +1158,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1192,7 +1166,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 2; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) return err; @@ -1260,7 +1233,9 @@ int mmc_startup(struct mmc *mmc) (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff); sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28, (mmc->cid[2] >> 24) & 0xf); +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT) init_part(&mmc->block_dev); +#endif return 0; } @@ -1274,7 +1249,6 @@ int mmc_send_if_cond(struct mmc *mmc) /* We set the bit if the host supports voltages between 2.7 and 3.6 V */ cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa; cmd.resp_type = MMC_RSP_R7; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1312,10 +1286,9 @@ int mmc_register(struct mmc *mmc) block_dev_desc_t *mmc_get_dev(int dev) { struct mmc *mmc = find_mmc_device(dev); - if (!mmc) + if (!mmc || mmc_init(mmc)) return NULL; - mmc_init(mmc); return &mmc->block_dev; } #endif diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index 2c5bf17..b3ec441 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -118,7 +118,7 @@ static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, int ret; /* The card can send a "busy" response */ - if (cmd->flags & MMC_RSP_BUSY) + if (cmd->resp_type & MMC_RSP_BUSY) cmdat |= MMC_CMDAT_BUSY; /* Inform the controller about response type */ @@ -181,9 +181,11 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) /* The command response didn't arrive */ if (stat & MMC_STAT_TIME_OUT_RESPONSE) return -ETIMEDOUT; - else if (stat & MMC_STAT_RES_CRC_ERROR && cmd->flags & MMC_RSP_CRC) { + else if (stat & MMC_STAT_RES_CRC_ERROR + && cmd->resp_type & MMC_RSP_CRC) { #ifdef PXAMMC_CRC_SKIP - if (cmd->flags & MMC_RSP_136 && cmd->response[0] & (1 << 31)) + if (cmd->resp_type & MMC_RSP_136 + && cmd->response[0] & (1 << 31)) printf("Ignoring CRC, this may be dangerous!\n"); else #endif diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 1d4481b..b978236 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -21,6 +21,7 @@ #include <malloc.h> #include <sdhci.h> #include <asm/arch/mmc.h> +#include <asm/arch/clk.h> static char *S5P_NAME = "SAMSUNG SDHCI"; static void s5p_sdhci_set_control_reg(struct sdhci_host *host) @@ -54,7 +55,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) * 00 = Delay3 (inverter delay) * 10 = Delay4 (inverter delay + 2ns) */ - val = SDHCI_CTRL3_FCSEL3 | SDHCI_CTRL3_FCSEL1; + val = SDHCI_CTRL3_FCSEL0 | SDHCI_CTRL3_FCSEL1; sdhci_writel(host, val, SDHCI_CONTROL3); /* @@ -69,7 +70,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) sdhci_writel(host, ctrl, SDHCI_CONTROL2); } -int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) +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)); @@ -80,19 +81,18 @@ int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) host->name = S5P_NAME; host->ioaddr = (void *)regbase; - host->quirks = quirks; - host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE; + host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | + SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR; host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - 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); + 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; - add_sdhci(host, max_clk, min_clk); + add_sdhci(host, 52000000, 400000); return 0; } diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 1709643..2e3c408 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -260,7 +260,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) if (clock == 0) return 0; - if (host->version >= SDHCI_SPEC_300) { + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) { /* Version 3.00 divisors must be a multiple of 2. */ if (mmc->f_max <= clock) div = 1; @@ -279,6 +279,9 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) } 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; @@ -347,10 +350,10 @@ void sdhci_set_ios(struct mmc *mmc) ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if (mmc->bus_width == 8) { ctrl &= ~SDHCI_CTRL_4BITBUS; - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) ctrl |= SDHCI_CTRL_8BITBUS; } else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) ctrl &= ~SDHCI_CTRL_8BITBUS; if (mmc->bus_width == 4) ctrl |= SDHCI_CTRL_4BITBUS; @@ -381,12 +384,25 @@ int sdhci_init(struct mmc *mmc) } } + sdhci_set_power(host, fls(mmc->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); + } + /* Eable all state */ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE); sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE); - sdhci_set_power(host, fls(mmc->voltages) - 1); - return 0; } @@ -421,7 +437,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) if (max_clk) mmc->f_max = max_clk; else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) mmc->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; else @@ -436,7 +452,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) if (min_clk) mmc->f_min = min_clk; else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_300; else mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_200; diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 2835e24..4588568 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -593,7 +593,7 @@ int mmcif_mmc_init(void) mmc->f_max = CLKDEV_EMMC_DATA; mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT | - MMC_MODE_8BIT; + MMC_MODE_8BIT | MMC_MODE_HC; memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME)); mmc->send_cmd = sh_mmcif_request; mmc->set_ios = sh_mmcif_set_ios; diff --git a/drivers/mmc/spl_mmc.c b/drivers/mmc/spl_mmc.c new file mode 100644 index 0000000..753c6a0 --- /dev/null +++ b/drivers/mmc/spl_mmc.c @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@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; either version 2 of + * the License, or (at your option) any later version. + * + * 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 <common.h> +#include <spl.h> +#include <asm/u-boot.h> +#include <asm/utils.h> +#include <mmc.h> +#include <fat.h> +#include <version.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void mmc_load_image_raw(struct mmc *mmc) +{ + u32 image_size_sectors, err; + const struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + /* read image header to find the image size & load address */ + err = mmc->block_dev.block_read(0, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, + (void *)header); + + if (err <= 0) + goto end; + + spl_parse_image_header(header); + + /* convert size to sectors - round up */ + image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / + mmc->read_bl_len; + + /* Read the header too to avoid extra memcpy */ + err = mmc->block_dev.block_read(0, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, + image_size_sectors, (void *)spl_image.load_addr); + +end: + if (err <= 0) { + printf("spl: mmc blk read err - %d\n", err); + hang(); + } +} + +#ifdef CONFIG_SPL_FAT_SUPPORT +static void mmc_load_image_fat(struct mmc *mmc) +{ + s32 err; + struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + err = fat_register_device(&mmc->block_dev, + CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); + if (err) { + printf("spl: fat register err - %d\n", err); + hang(); + } + + err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, + (u8 *)header, sizeof(struct image_header)); + if (err <= 0) + goto end; + + spl_parse_image_header(header); + + err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, + (u8 *)spl_image.load_addr, 0); + +end: + if (err <= 0) { + printf("spl: error reading image %s, err - %d\n", + CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err); + hang(); + } +} +#endif + +void spl_mmc_load_image(void) +{ + struct mmc *mmc; + int err; + u32 boot_mode; + + mmc_initialize(gd->bd); + /* We register only one device. So, the dev id is always 0 */ + mmc = find_mmc_device(0); + if (!mmc) { + puts("spl: mmc device not found!!\n"); + hang(); + } + + err = mmc_init(mmc); + if (err) { + printf("spl: mmc init failed: err - %d\n", err); + hang(); + } + boot_mode = spl_boot_mode(); + if (boot_mode == MMCSD_MODE_RAW) { + debug("boot mode - RAW\n"); + mmc_load_image_raw(mmc); +#ifdef CONFIG_SPL_FAT_SUPPORT + } else if (boot_mode == MMCSD_MODE_FAT) { + debug("boot mode - FAT\n"); + mmc_load_image_fat(mmc); +#endif + } else { + puts("spl: wrong MMC boot mode\n"); + hang(); + } +} diff --git a/drivers/mmc/spl_mmc_load.c b/drivers/mmc/spl_mmc_load.c deleted file mode 100644 index 79a68fb..0000000 --- a/drivers/mmc/spl_mmc_load.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ - * - * 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, or - * (at your option) any later version. - * - * 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. - */ - -#include <common.h> -#include <mmc.h> - -DECLARE_GLOBAL_DATA_PTR; - -static void mmc_load_image(struct mmc *mmc) -{ - s32 err; - void (*uboot)(void) __noreturn; - - err = mmc->block_dev.block_read(0, CONFIG_SYS_MMC_U_BOOT_OFFS, - CONFIG_SYS_MMC_U_BOOT_SIZE/512, - (u32 *)CONFIG_SYS_TEXT_BASE); - - if (err <= 0) { - printf("spl: error reading image %s, err - %d\n", - "u-boot.img", err); - hang(); - } - uboot = (void *) CONFIG_SYS_TEXT_BASE; - (*uboot)(); -} - -void spl_mmc_load(void) -{ - struct mmc *mmc; - int err; - void (mmc_load_image)(struct mmc *mmc) __noreturn; - - mmc_initialize(gd->bd); - mmc = find_mmc_device(0); - if (!mmc) { - puts("spl: mmc device not found!!\n"); - hang(); - } else { - puts("spl: mmc device found\n"); - } - err = mmc_init(mmc); - if (err) { - printf("spl: mmc init failed: err - %d\n", err); - hang(); - } - mmc_load_image(mmc); -} |