diff options
-rw-r--r-- | arch/arm/include/asm/arch-exynos/dwmmc.h | 36 | ||||
-rw-r--r-- | arch/mips/cpu/mips32/time.c | 1 | ||||
-rw-r--r-- | arch/mips/cpu/mips64/time.c | 1 | ||||
-rw-r--r-- | boards.cfg | 1 | ||||
-rw-r--r-- | common/bouncebuf.c | 75 | ||||
-rw-r--r-- | common/cmd_mmc.c | 9 | ||||
-rw-r--r-- | drivers/mmc/Makefile | 1 | ||||
-rw-r--r-- | drivers/mmc/exynos_dw_mmc.c | 57 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 63 | ||||
-rw-r--r-- | drivers/mmc/mxsmmc.c | 30 | ||||
-rw-r--r-- | drivers/mmc/sdhci.c | 3 | ||||
-rw-r--r-- | drivers/mmc/tegra_mmc.c | 64 | ||||
-rw-r--r-- | include/bouncebuf.h | 47 | ||||
-rw-r--r-- | include/configs/at91sam9x5ek.h | 19 | ||||
-rw-r--r-- | include/configs/mx6qarm2.h | 2 | ||||
-rw-r--r-- | include/configs/mx6qsabre_common.h | 2 | ||||
-rw-r--r-- | include/configs/mx6qsabrelite.h | 2 | ||||
-rw-r--r-- | include/configs/sc_sps_1.h | 2 | ||||
-rw-r--r-- | include/configs/tegra20-common.h | 3 | ||||
-rw-r--r-- | include/sdhci.h | 1 |
20 files changed, 283 insertions, 136 deletions
diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h new file mode 100644 index 0000000..8acdf9b --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h @@ -0,0 +1,36 @@ +/* + * (C) Copyright 2012 SAMSUNG Electronics + * Jaehoon Chung <jh80.chung@samsung.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define DWMCI_CLKSEL 0x09C +#define DWMCI_SHIFT_0 0x0 +#define DWMCI_SHIFT_1 0x1 +#define DWMCI_SHIFT_2 0x2 +#define DWMCI_SHIFT_3 0x3 +#define DWMCI_SET_SAMPLE_CLK(x) (x) +#define DWMCI_SET_DRV_CLK(x) ((x) << 16) +#define DWMCI_SET_DIV_RATIO(x) ((x) << 24) + +int exynos_dwmci_init(u32 regbase, int bus_width, int index); + +static inline unsigned int exynos_dwmmc_init(int index, int bus_width) +{ + unsigned int base = samsung_get_base_mmc() + (0x10000 * index); + return exynos_dwmci_init(base, bus_width, index); +} diff --git a/arch/mips/cpu/mips32/time.c b/arch/mips/cpu/mips32/time.c index 350896a..09fc842 100644 --- a/arch/mips/cpu/mips32/time.c +++ b/arch/mips/cpu/mips32/time.c @@ -36,7 +36,6 @@ static unsigned long timestamp; int timer_init(void) { /* Set up the timer for the first expiration. */ - timestamp = 0; write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY); return 0; diff --git a/arch/mips/cpu/mips64/time.c b/arch/mips/cpu/mips64/time.c index 5154280..720f7b7 100644 --- a/arch/mips/cpu/mips64/time.c +++ b/arch/mips/cpu/mips64/time.c @@ -37,7 +37,6 @@ static unsigned long timestamp; int timer_init(void) { /* Set up the timer for the first expiration. */ - timestamp = 0; write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY); return 0; @@ -98,6 +98,7 @@ at91sam9rlek_dataflash arm arm926ejs at91sam9rlek atmel at91sam9rlek_nandflash arm arm926ejs at91sam9rlek atmel at91 at91sam9rlek:AT91SAM9RL,SYS_USE_NANDFLASH at91sam9x5ek_nandflash arm arm926ejs at91sam9x5ek atmel at91 at91sam9x5ek:AT91SAM9X5,SYS_USE_NANDFLASH at91sam9x5ek_spiflash arm arm926ejs at91sam9x5ek atmel at91 at91sam9x5ek:AT91SAM9X5,SYS_USE_SPIFLASH +at91sam9x5ek_mmc arm arm926ejs at91sam9x5ek atmel at91 at91sam9x5ek:AT91SAM9X5,SYS_USE_MMC at91sam9xeek_dataflash_cs0 arm arm926ejs at91sam9260ek atmel at91 at91sam9260ek:AT91SAM9XE,SYS_USE_DATAFLASH_CS0 at91sam9xeek_dataflash_cs1 arm arm926ejs at91sam9260ek atmel at91 at91sam9260ek:AT91SAM9XE,SYS_USE_DATAFLASH_CS1 at91sam9xeek_nandflash arm arm926ejs at91sam9260ek atmel at91 at91sam9260ek:AT91SAM9XE,SYS_USE_NANDFLASH diff --git a/common/bouncebuf.c b/common/bouncebuf.c index 4f827f8..1df12cd 100644 --- a/common/bouncebuf.c +++ b/common/bouncebuf.c @@ -27,21 +27,19 @@ #include <errno.h> #include <bouncebuf.h> -static int addr_aligned(void *data, size_t len) +static int addr_aligned(struct bounce_buffer *state) { const ulong align_mask = ARCH_DMA_MINALIGN - 1; /* Check if start is aligned */ - if ((ulong)data & align_mask) { - debug("Unaligned start address %p\n", data); + if ((ulong)state->user_buffer & align_mask) { + debug("Unaligned buffer address %p\n", state->user_buffer); return 0; } - data += len; - - /* Check if end is aligned */ - if ((ulong)data & align_mask) { - debug("Unaligned end address %p\n", data); + /* Check if length is aligned */ + if (state->len != state->len_aligned) { + debug("Unaligned buffer length %d\n", state->len); return 0; } @@ -49,44 +47,53 @@ static int addr_aligned(void *data, size_t len) return 1; } -int bounce_buffer_start(void **data, size_t len, void **backup, uint8_t flags) +int bounce_buffer_start(struct bounce_buffer *state, void *data, + size_t len, unsigned int flags) { - void *tmp; - size_t alen; - - if (addr_aligned(*data, len)) { - *backup = NULL; - return 0; + state->user_buffer = data; + state->bounce_buffer = data; + state->len = len; + state->len_aligned = roundup(len, ARCH_DMA_MINALIGN); + state->flags = flags; + + if (!addr_aligned(state)) { + state->bounce_buffer = memalign(ARCH_DMA_MINALIGN, + state->len_aligned); + if (!state->bounce_buffer) + return -ENOMEM; + + if (state->flags & GEN_BB_READ) + memcpy(state->bounce_buffer, state->user_buffer, + state->len); } - alen = roundup(len, ARCH_DMA_MINALIGN); - tmp = memalign(ARCH_DMA_MINALIGN, alen); - - if (!tmp) - return -ENOMEM; - - if (flags & GEN_BB_READ) - memcpy(tmp, *data, len); - - *backup = *data; - *data = tmp; + /* + * Flush data to RAM so DMA reads can pick it up, + * and any CPU writebacks don't race with DMA writes + */ + flush_dcache_range((unsigned long)state->bounce_buffer, + (unsigned long)(state->bounce_buffer) + + state->len_aligned); return 0; } -int bounce_buffer_stop(void **data, size_t len, void **backup, uint8_t flags) +int bounce_buffer_stop(struct bounce_buffer *state) { - void *tmp = *data; + if (state->flags & GEN_BB_WRITE) { + /* Invalidate cache so that CPU can see any newly DMA'd data */ + invalidate_dcache_range((unsigned long)state->bounce_buffer, + (unsigned long)(state->bounce_buffer) + + state->len_aligned); + } - /* The buffer was already aligned, since "backup" is NULL. */ - if (!*backup) + if (state->bounce_buffer == state->user_buffer) return 0; - if (flags & GEN_BB_WRITE) - memcpy(*backup, *data, len); + if (state->flags & GEN_BB_WRITE) + memcpy(state->user_buffer, state->bounce_buffer, state->len); - *data = *backup; - free(tmp); + free(state->bounce_buffer); return 0; } diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 4c19df7..7dacd51 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -250,14 +250,13 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } - if (strcmp(argv[1], "read") == 0) + state = MMC_INVALID; + if (argc == 5 && strcmp(argv[1], "read") == 0) state = MMC_READ; - else if (strcmp(argv[1], "write") == 0) + else if (argc == 5 && strcmp(argv[1], "write") == 0) state = MMC_WRITE; - else if (strcmp(argv[1], "erase") == 0) + else if (argc == 4 && strcmp(argv[1], "erase") == 0) state = MMC_ERASE; - else - state = MMC_INVALID; if (state != MMC_INVALID) { struct mmc *mmc = find_mmc_device(curr_device); diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index a1dd730..65791aa 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -47,6 +47,7 @@ COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o COBJS-$(CONFIG_DWMMC) += dw_mmc.o +COBJS-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c new file mode 100644 index 0000000..72a31b7 --- /dev/null +++ b/drivers/mmc/exynos_dw_mmc.c @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2012 SAMSUNG Electronics + * Jaehoon Chung <jh80.chung@samsung.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <common.h> +#include <malloc.h> +#include <dwmmc.h> +#include <asm/arch/dwmmc.h> +#include <asm/arch/clk.h> + +static char *EXYNOS_NAME = "EXYNOS DWMMC"; + +static void exynos_dwmci_clksel(struct dwmci_host *host) +{ + u32 val; + val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) | + DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(0); + + dwmci_writel(host, DWMCI_CLKSEL, val); +} + +int exynos_dwmci_init(u32 regbase, int bus_width, int index) +{ + struct dwmci_host *host = NULL; + host = malloc(sizeof(struct dwmci_host)); + if (!host) { + printf("dwmci_host malloc fail!\n"); + return 1; + } + + host->name = EXYNOS_NAME; + host->ioaddr = (void *)regbase; + host->buswidth = bus_width; + host->clksel = exynos_dwmci_clksel; + host->dev_index = index; + + add_dwmci(host, 52000000, 400000); + + return 0; +} + diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 5ffd8c5..72e8ce6 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -868,7 +868,7 @@ static void mmc_set_bus_width(struct mmc *mmc, uint width) static int mmc_startup(struct mmc *mmc) { - int err, width; + int err; uint mult, freq; u64 cmult, csize, capacity; struct mmc_cmd cmd; @@ -1087,21 +1087,44 @@ static int mmc_startup(struct mmc *mmc) else mmc->tran_speed = 25000000; } else { - width = ((mmc->host_caps & MMC_MODE_MASK_WIDTH_BITS) >> - MMC_MODE_WIDTH_BITS_SHIFT); - for (; width >= 0; width--) { - /* Set the card to use 4 bit*/ + 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->host_caps & ext_to_hostcaps[extw])) + continue; + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, width); + EXT_CSD_BUS_WIDTH, extw); if (err) continue; - if (!width) { - mmc_set_bus_width(mmc, 1); - break; - } else - mmc_set_bus_width(mmc, 4 * width); + mmc_set_bus_width(mmc, widths[idx]); err = mmc_send_ext_csd(mmc, test_csd); if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \ @@ -1115,7 +1138,7 @@ static int mmc_startup(struct mmc *mmc) && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \ &test_csd[EXT_CSD_SEC_CNT], 4) == 0) { - mmc->card_caps |= width; + mmc->card_caps |= ext_to_hostcaps[extw]; break; } } @@ -1135,13 +1158,15 @@ static int mmc_startup(struct mmc *mmc) mmc->block_dev.type = 0; mmc->block_dev.blksz = mmc->read_bl_len; mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); - sprintf(mmc->block_dev.vendor, "Man %06x Snr %08x", mmc->cid[0] >> 8, - (mmc->cid[2] << 8) | (mmc->cid[3] >> 24)); - sprintf(mmc->block_dev.product, "%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); - sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28, - (mmc->cid[2] >> 24) & 0xf); + 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); #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT) init_part(&mmc->block_dev); #endif diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 109acbf..024df59 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -96,11 +96,11 @@ static int mxsmmc_send_cmd_pio(struct mxsmmc_priv *priv, struct mmc_data *data) static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data) { uint32_t data_count = data->blocksize * data->blocks; - uint32_t cache_data_count = roundup(data_count, ARCH_DMA_MINALIGN); int dmach; struct mxs_dma_desc *desc = priv->desc; - void *addr, *backup; - uint8_t flags; + void *addr; + unsigned int flags; + struct bounce_buffer bbstate; memset(desc, 0, sizeof(struct mxs_dma_desc)); desc->address = (dma_addr_t)desc; @@ -115,19 +115,9 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data) flags = GEN_BB_READ; } - bounce_buffer_start(&addr, data_count, &backup, flags); + bounce_buffer_start(&bbstate, addr, data_count, flags); - priv->desc->cmd.address = (dma_addr_t)addr; - - if (data->flags & MMC_DATA_WRITE) { - /* Flush data to DRAM so DMA can pick them up */ - flush_dcache_range((uint32_t)addr, - (uint32_t)(addr) + cache_data_count); - } - - /* Invalidate the area, so no writeback into the RAM races with DMA */ - invalidate_dcache_range((uint32_t)priv->desc->cmd.address, - (uint32_t)(priv->desc->cmd.address + cache_data_count)); + 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); @@ -135,17 +125,11 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data) dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->id; mxs_dma_desc_append(dmach, priv->desc); if (mxs_dma_go(dmach)) { - bounce_buffer_stop(&addr, data_count, &backup, flags); + bounce_buffer_stop(&bbstate); return COMM_ERR; } - /* The data arrived into DRAM, invalidate cache over them */ - if (data->flags & MMC_DATA_READ) { - invalidate_dcache_range((uint32_t)addr, - (uint32_t)(addr) + cache_data_count); - } - - bounce_buffer_stop(&addr, data_count, &backup, flags); + bounce_buffer_stop(&bbstate); return 0; } diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 7845f87..b9cbe34 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -340,6 +340,9 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) 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); diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 8fea6a6..b141eaf 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <bouncebuf.h> #include <common.h> #include <asm/gpio.h> #include <asm/io.h> @@ -66,14 +67,17 @@ static void tegra_get_setup(struct mmc_host *host, int dev_index) host->reg = (struct tegra_mmc *)host->base; } -static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data) +static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data, + struct bounce_buffer *bbstate) { unsigned char ctrl; - debug("data->dest: %08X, data->blocks: %u, data->blocksize: %u\n", - (u32)data->dest, data->blocks, data->blocksize); - writel((u32)data->dest, &host->reg->sysad); + 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 @@ -114,14 +118,6 @@ static void mmc_set_transfer_mode(struct mmc_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) mode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ; - if (data->flags & MMC_DATA_WRITE) { - if ((uintptr_t)data->src & (ARCH_DMA_MINALIGN - 1)) - printf("Warning: unaligned write to %p may fail\n", - data->src); - flush_dcache_range((ulong)data->src, (ulong)data->src + - data->blocks * data->blocksize); - } - writew(mode, &host->reg->trnmod); } @@ -156,8 +152,8 @@ static int mmc_wait_inhibit(struct mmc_host *host, return 0; } -static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) +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 = (struct mmc_host *)mmc->priv; int flags, i; @@ -172,7 +168,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, return result; if (data) - mmc_prepare_data(host, data); + mmc_prepare_data(host, data, bbstate); debug("cmd->arg: %08x\n", cmd->cmdarg); writel(cmd->cmdarg, &host->reg->argument); @@ -322,20 +318,42 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } } writel(mask, &host->reg->norintsts); - if (data->flags & MMC_DATA_READ) { - if ((uintptr_t)data->dest & (ARCH_DMA_MINALIGN - 1)) - printf("Warning: unaligned read from %p " - "may fail\n", data->dest); - invalidate_dcache_range((ulong)data->dest, - (ulong)data->dest + - data->blocks * data->blocksize); - } } udelay(1000); return 0; } +static int 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; diff --git a/include/bouncebuf.h b/include/bouncebuf.h index 31021c5..707b588 100644 --- a/include/bouncebuf.h +++ b/include/bouncebuf.h @@ -25,6 +25,8 @@ #ifndef __INCLUDE_BOUNCEBUF_H__ #define __INCLUDE_BOUNCEBUF_H__ +#include <linux/types.h> + /* * GEN_BB_READ -- Data are read from the buffer eg. by DMA hardware. * The source buffer is copied into the bounce buffer (if unaligned, otherwise @@ -51,37 +53,36 @@ */ #define GEN_BB_RW (GEN_BB_READ | GEN_BB_WRITE) -#ifdef CONFIG_BOUNCE_BUFFER +struct bounce_buffer { + /* Copy of data parameter passed to start() */ + void *user_buffer; + /* + * DMA-aligned buffer. This field is always set to the value that + * should be used for DMA; either equal to .user_buffer, or to a + * freshly allocated aligned buffer. + */ + void *bounce_buffer; + /* Copy of len parameter passed to start() */ + size_t len; + /* DMA-aligned buffer length */ + size_t len_aligned; + /* Copy of flags parameter passed to start() */ + unsigned int flags; +}; + /** * bounce_buffer_start() -- Start the bounce buffer session + * state: stores state passed between bounce_buffer_{start,stop} * data: pointer to buffer to be aligned * len: length of the buffer - * backup: pointer to backup buffer (the original value is stored here if - * needed * flags: flags describing the transaction, see above. */ -int bounce_buffer_start(void **data, size_t len, void **backup, uint8_t flags); +int bounce_buffer_start(struct bounce_buffer *state, void *data, + size_t len, unsigned int flags); /** * bounce_buffer_stop() -- Finish the bounce buffer session - * data: pointer to buffer that was aligned - * len: length of the buffer - * backup: pointer to backup buffer (the original value is stored here if - * needed - * flags: flags describing the transaction, see above. + * state: stores state passed between bounce_buffer_{start,stop} */ -int bounce_buffer_stop(void **data, size_t len, void **backup, uint8_t flags); -#else -static inline int bounce_buffer_start(void **data, size_t len, void **backup, - uint8_t flags) -{ - return 0; -} - -static inline int bounce_buffer_stop(void **data, size_t len, void **backup, - uint8_t flags) -{ - return 0; -} -#endif +int bounce_buffer_stop(struct bounce_buffer *state); #endif diff --git a/include/configs/at91sam9x5ek.h b/include/configs/at91sam9x5ek.h index 71f765b..1317582 100644 --- a/include/configs/at91sam9x5ek.h +++ b/include/configs/at91sam9x5ek.h @@ -168,8 +168,7 @@ #define CONFIG_BOOTCOMMAND "nand read " \ "0x22000000 0x200000 0x300000; " \ "bootm 0x22000000" -#else -#ifdef CONFIG_SYS_USE_SPIFLASH +#elif defined(CONFIG_SYS_USE_SPIFLASH) /* bootstrap + u-boot + env + linux in spi flash */ #define CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_OFFSET 0x5000 @@ -179,14 +178,28 @@ #define CONFIG_BOOTCOMMAND "sf probe 0; " \ "sf read 0x22000000 0x100000 0x300000; " \ "bootm 0x22000000" -#endif +#else /* CONFIG_SYS_USE_MMC */ +/* bootstrap + u-boot + env + linux in mmc */ +#define CONFIG_ENV_IS_IN_MMC +/* For FAT system, most cases it should be in the reserved sector */ +#define CONFIG_ENV_OFFSET 0x2000 +#define CONFIG_ENV_SIZE 0x1000 +#define CONFIG_SYS_MMC_ENV_DEV 0 #endif +#ifdef CONFIG_SYS_USE_MMC +#define CONFIG_BOOTARGS "mem=128M console=ttyS0,115200 " \ + "mtdparts=atmel_nand:" \ + "8M(bootstrap/uboot/kernel)ro,-(rootfs) " \ + "root=/dev/mmcblk0p2 " \ + "rw rootfstype=ext4 rootwait" +#else #define CONFIG_BOOTARGS "mem=128M console=ttyS0,115200 " \ "mtdparts=atmel_nand:" \ "8M(bootstrap/uboot/kernel)ro,-(rootfs) " \ "root=/dev/mtdblock1 rw " \ "rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs" +#endif #define CONFIG_BAUDRATE 115200 diff --git a/include/configs/mx6qarm2.h b/include/configs/mx6qarm2.h index 23562a8..28a3deb 100644 --- a/include/configs/mx6qarm2.h +++ b/include/configs/mx6qarm2.h @@ -50,7 +50,7 @@ #define CONFIG_MMC #define CONFIG_CMD_MMC #define CONFIG_GENERIC_MMC -#define CONFIG_MMC_BOUNCE_BUFFER +#define CONFIG_BOUNCE_BUFFER #define CONFIG_CMD_FAT #define CONFIG_DOS_PARTITION diff --git a/include/configs/mx6qsabre_common.h b/include/configs/mx6qsabre_common.h index bfb9cd4..a5c93d0 100644 --- a/include/configs/mx6qsabre_common.h +++ b/include/configs/mx6qsabre_common.h @@ -45,7 +45,7 @@ #define CONFIG_MMC #define CONFIG_CMD_MMC #define CONFIG_GENERIC_MMC -#define CONFIG_MMC_BOUNCE_BUFFER +#define CONFIG_BOUNCE_BUFFER #define CONFIG_CMD_EXT2 #define CONFIG_CMD_FAT #define CONFIG_DOS_PARTITION diff --git a/include/configs/mx6qsabrelite.h b/include/configs/mx6qsabrelite.h index b56d7ca..a28d5a5 100644 --- a/include/configs/mx6qsabrelite.h +++ b/include/configs/mx6qsabrelite.h @@ -72,7 +72,7 @@ #define CONFIG_MMC #define CONFIG_CMD_MMC #define CONFIG_GENERIC_MMC -#define CONFIG_MMC_BOUNCE_BUFFER +#define CONFIG_BOUNCE_BUFFER #define CONFIG_CMD_EXT2 #define CONFIG_CMD_FAT #define CONFIG_DOS_PARTITION diff --git a/include/configs/sc_sps_1.h b/include/configs/sc_sps_1.h index f5dc393..cb99d58 100644 --- a/include/configs/sc_sps_1.h +++ b/include/configs/sc_sps_1.h @@ -140,7 +140,7 @@ #ifdef CONFIG_CMD_MMC #define CONFIG_APBH_DMA #define CONFIG_MMC -#define CONFIG_MMC_BOUNCE_BUFFER +#define CONFIG_BOUNCE_BUFFER #define CONFIG_GENERIC_MMC #define CONFIG_MXS_MMC #endif diff --git a/include/configs/tegra20-common.h b/include/configs/tegra20-common.h index 31b68be..5c0833a 100644 --- a/include/configs/tegra20-common.h +++ b/include/configs/tegra20-common.h @@ -202,4 +202,7 @@ #define CONFIG_SYS_NAND_SELF_INIT #define CONFIG_SYS_NAND_ONFI_DETECTION +/* Misc utility code */ +#define CONFIG_BOUNCE_BUFFER + #endif /* __TEGRA20_COMMON_H */ diff --git a/include/sdhci.h b/include/sdhci.h index c44793d..cffbe53 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -225,6 +225,7 @@ #define SDHCI_QUIRK_BROKEN_VOLTAGE (1 << 4) #define SDHCI_QUIRK_NO_CD (1 << 5) #define SDHCI_QUIRK_WAIT_SEND_CMD (1 << 6) +#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1 << 7) /* to make gcc happy */ struct sdhci_host; |