aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/st-ericsson/snowball/Makefile12
-rw-r--r--board/st-ericsson/snowball/mmc_fifo.S146
-rw-r--r--board/st-ericsson/snowball/mmc_fifo.h45
-rw-r--r--board/st-ericsson/snowball/mmc_host.c589
-rw-r--r--board/st-ericsson/snowball/mmc_host.h302
-rw-r--r--board/st-ericsson/snowball/mmc_utils.c180
-rw-r--r--board/st-ericsson/snowball/snowball.c124
7 files changed, 124 insertions, 1274 deletions
diff --git a/board/st-ericsson/snowball/Makefile b/board/st-ericsson/snowball/Makefile
index 560ed118c..61382960b 100644
--- a/board/st-ericsson/snowball/Makefile
+++ b/board/st-ericsson/snowball/Makefile
@@ -25,20 +25,18 @@ include $(TOPDIR)/config.mk
CFLAGS += -D__RELEASE -D__STN_8500
LIB = $(obj)lib$(BOARD).o
-COBJS := snowball.o mmc_host.o mmc_utils.o
-SOBJS := mmc_fifo.o
+COBJS := snowball.o
#prcmu.o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
-SOBJS := $(addprefix $(obj),$(SOBJS))
-$(LIB): $(obj).depend $(OBJS) $(SOBJS)
- $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
clean:
- rm -f $(SOBJS) $(OBJS)
+ rm -f $(OBJS)
distclean: clean
rm -f $(LIB) core *.bak $(obj).depend
diff --git a/board/st-ericsson/snowball/mmc_fifo.S b/board/st-ericsson/snowball/mmc_fifo.S
deleted file mode 100644
index 44911a8d5..000000000
--- a/board/st-ericsson/snowball/mmc_fifo.S
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
- *
- * License terms: GNU General Public License (GPL), version 2.
- */
-
-#include "mmc_fifo.h"
-#include "mmc_host.h"
-
-/*
- * Function: mmc_fifo_read()
- *
- * int mmc_fifo_read(u32 *fifo, u32 *buf, unsigned int count, u32 *status_reg)
- *
- * Info: Reads data from an MMC (ARM PL180) FIFO
- *
- * Parameters:
- * fifo - pointer to the first PL180 FIFO register
- * buf - pointer to a read buffer (32-bit aligned)
- * count - number of bytes to be read (32-bit aligned)
- * status_reg - pointer to the PL180 status register
- *
- * Returns '0' if success and PL180 status on failure.
- *
- */
-
- .globl mmc_fifo_read
-mmc_fifo_read:
- push {r4-r10,lr}
-mmc_fifo_read_loop_32_1:
- /* If count is <32B read word-wise */
- cmp r2,#32
- blo mmc_fifo_read_loop_4_1
-mmc_fifo_read_loop_32_2:
- /* Load SDI_STA to r4 */
- ldr r4,[r3]
- /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */
- ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
- bne mmc_fifo_read_fail
- /* Wait until SDI_STA_RXFIFOBR is set */
- tst r4,#SDI_STA_RXFIFOBR
- beq mmc_fifo_read_loop_32_2
- /* Load and store 8 words */
- ldmia r0,{r4-r10,lr}
- stmia r1!,{r4-r10,lr}
- subs r2,r2,#32
- b mmc_fifo_read_loop_32_1
-mmc_fifo_read_loop_4_1:
- /* Read word wise */
- cmp r2,#4
- blo mmc_fifo_read_ok
-mmc_fifo_read_loop_4_2:
- /* Load SDI_STA to r4 */
- ldr r4,[r3]
- /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */
- ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
- bne mmc_fifo_read_fail
- /* Wait until SDI_STA_RXDAVL is set */
- tst r4,#SDI_STA_RXDAVL
- beq mmc_fifo_read_loop_4_2
- /* Load and store 1 word */
- ldmia r0,{r4}
- stmia r1!,{r4}
- subs r2,r2,#4
- b mmc_fifo_read_loop_4_1
-mmc_fifo_read_ok:
- /* Wait until SDI_STA_DBCKEND and SDI_STA_DATAEND are set */
- ldr r4,[r3]
- ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
- bne mmc_fifo_read_fail
- and r5,r4,#(SDI_STA_DBCKEND | SDI_STA_DATAEND)
- cmp r5,#(SDI_STA_DBCKEND | SDI_STA_DATAEND)
- bne mmc_fifo_read_ok
-mmc_fifo_read_fail:
- mov r0,r4
- pop {r4-r10,pc}
-
-/*
- * Function: mmc_fifo_write()
- *
- * int mmc_fifo_write(u32 *buf, u32 *fifo, unsigned int count, u32 *status_reg)
- *
- * Info: Writes data to an MMC (ARM PL180) FIFO
- *
- * Parameters:
- * buf - pointer to a write buffer (32-bit aligned)
- * fifo - pointer to the first PL180 FIFO register
- * count - number of bytes to be written (32-bit aligned)
- * status_reg - pointer to the PL180 status register
- *
- * Returns '0' if success and PL180 status on failure.
- *
- */
-
- .globl mmc_fifo_write
-mmc_fifo_write:
- push {r4-r10,lr}
-mmc_fifo_write_loop_32_1:
- /* If count is <32B read word-wise */
- cmp r2,#32
- blo mmc_fifo_write_loop_4_1
-mmc_fifo_write_loop_32_2:
- /* Load SDI_STA to r4 */
- ldr r4,[r3]
- /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */
- ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
- bne mmc_fifo_write_fail
- /* Wait until SDI_STA_TXFIFOBW is set */
- tst r4,#SDI_STA_TXFIFOBW
- beq mmc_fifo_write_loop_32_2
- /* Load and store 8 words */
- ldmia r0!,{r4-r10,lr}
- stmia r1,{r4-r10,lr}
- subs r2,r2,#32
- b mmc_fifo_write_loop_32_1
-mmc_fifo_write_loop_4_1:
- /* Read word wise */
- cmp r2,#4
- blo mmc_fifo_write_ok
-mmc_fifo_write_loop_4_2:
- /* Load SDI_STA to r4 */
- ldr r4,[r3]
- /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */
- ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
- bne mmc_fifo_write_fail
- /* Wait until SDI_STA_TXFIFOBW is set */
- tst r4,#SDI_STA_TXFIFOBW
- beq mmc_fifo_write_loop_4_2
- /* Load and store 1 word */
- ldmia r0!,{r4}
- stmia r1,{r4}
- subs r2,r2,#4
- b mmc_fifo_write_loop_4_1
-mmc_fifo_write_ok:
- /* Wait until SDI_STA_DBCKEND and SDI_STA_DATAEND are set */
- ldr r4,[r3]
- ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT)
- bne mmc_fifo_write_fail
- and r5,r4,#(SDI_STA_DBCKEND | SDI_STA_DATAEND)
- cmp r5,#(SDI_STA_DBCKEND | SDI_STA_DATAEND)
- bne mmc_fifo_write_ok
-mmc_fifo_write_fail:
- mov r0,r4
- pop {r4-r10,pc}
diff --git a/board/st-ericsson/snowball/mmc_fifo.h b/board/st-ericsson/snowball/mmc_fifo.h
deleted file mode 100644
index e2fb0a53b..000000000
--- a/board/st-ericsson/snowball/mmc_fifo.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
- *
- * License terms: GNU General Public License (GPL), version 2.
- */
-
-#include <common.h>
-
-#ifndef __ASSEMBLY__
-
-/*
- * Function: mmc_fifo_read()
- *
- * Info: Reads data from an MMC (ARM PL180) FIFO
- *
- * Parameters:
- * fifo - pointer to the first PL180 FIFO register
- * buf - pointer to a read buffer (32-bit aligned)
- * count - number of bytes to be read (32-bit aligned)
- * status_reg - pointer to the PL180 status register
- *
- * Returns '0' if success and PL180 status on failure.
- *
- */
-int mmc_fifo_read(u32 *fifo, u32 *buf, unsigned int count, u32 *status_reg);
-
-/*
- * Function: mmc_fifo_write()
- *
- * Info: Writes data to an MMC (ARM PL180) FIFO
- *
- * Parameters:
- * buf - pointer to a write buffer (32-bit aligned)
- * fifo - pointer to the first PL180 FIFO register
- * count - number of bytes to be written (32-bit aligned)
- * status_reg - pointer to the PL180 status register
- *
- * Returns '0' if success and PL180 status on failure.
- *
- */
-int mmc_fifo_write(u32 *buf, u32 *fifo, unsigned int count, u32 *status_reg);
-
-#endif /* __ASSEMBLY__ */
diff --git a/board/st-ericsson/snowball/mmc_host.c b/board/st-ericsson/snowball/mmc_host.c
deleted file mode 100644
index 4e5c0e39a..000000000
--- a/board/st-ericsson/snowball/mmc_host.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Ulf Hansson <ulf.hansson@stericsson.com>
- * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
- *
- * License terms: GNU General Public License (GPL), version 2.
- */
-
-/*
- * There are two levels of debug printouts in this file. The macro DEBUG can be
- * set to either DBG_LVL_INFO (1) or DBG_LVL_VERBOSE (2).
- */
-#define DBG_LVL_INFO (1)
-#define DBG_LVL_VERBOSE (2)
-
-#include <asm/io.h>
-#include <asm/arch/common.h>
-#include <asm/arch/cpu.h>
-#include <mmc.h>
-#include "mmc_host.h"
-#include <malloc.h>
-#include <div64.h>
-#include "mmc_fifo.h"
-
-
-struct mmc_host {
- struct sdi_registers *base;
-};
-
-/*
- * wait_for_command_end() - waiting for the command completion
- * this function will wait until the command completion has happened or
- * any error generated by reading the status register
- */
-static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
-{
- u32 hoststatus, statusmask;
- struct 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);
-
- debugX(DBG_LVL_VERBOSE, "SDI_ICR <= 0x%08X\n", statusmask);
- writel(statusmask, &host->base->status_clear);
-
- if (hoststatus & SDI_STA_CTIMEOUT) {
- debugX(DBG_LVL_VERBOSE, "CMD%d time out\n", cmd->cmdidx);
- return TIMEOUT;
- } else if ((hoststatus & SDI_STA_CCRCFAIL) &&
- (cmd->flags & MMC_RSP_CRC)) {
- debugX(DBG_LVL_VERBOSE, "CMD%d CRC error\n", cmd->cmdidx);
- return MMC_CMD_CRC_FAIL;
- }
-
- 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);
- debugX(DBG_LVL_VERBOSE,
- "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 MMC_OK;
-}
-
-/*
- * do_command - sends command to card, and waits for its result.
- */
-static int do_command(struct mmc *dev, struct mmc_cmd *cmd)
-{
- int result;
- u32 sdi_cmd = 0;
- struct mmc_host *host = dev->priv;
- u32 lap = 0;
-
- debugX(DBG_LVL_VERBOSE, "Request to do CMD%d on %s\n", cmd->cmdidx,
- dev->name);
-
- 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;
- }
-
- debugX(DBG_LVL_VERBOSE, "SDI_ARG <= 0x%08X\n", cmd->cmdarg);
- writel((u32)cmd->cmdarg, &host->base->argument);
- udelay(COMMAND_REG_DELAY); /* DONT REMOVE */
- debugX(DBG_LVL_VERBOSE, "SDI_CMD <= 0x%08X\n", sdi_cmd);
-
- /*
- * It has been noticed that after a write operation some cards does
- * not respond to a new command for a few milliseconds. So here we
- * retry the command a couple of times if we get a timeout.
- */
- do {
- writel(sdi_cmd, &host->base->command);
- result = wait_for_command_end(dev, cmd);
- if ((result != TIMEOUT) || (lap >= 10))
- break;
- udelay(1000);
- lap++;
- } while (1);
-
- /* After CMD2 set RCA to a none zero value. */
- if ((result == MMC_OK) && (cmd->cmdidx == MMC_CMD_ALL_SEND_CID))
- dev->rca = 10;
-
- /* After CMD3 open drain is switched off and push pull is used. */
- if ((result == MMC_OK) && (cmd->cmdidx == MMC_CMD_SET_RELATIVE_ADDR)) {
- u32 sdi_pwr = readl(&host->base->power) & ~SDI_PWR_OPD;
- debugX(DBG_LVL_VERBOSE, "SDI_PWR <= 0x%08X\n", sdi_pwr);
- writel(sdi_pwr, &host->base->power);
- }
-
- return result;
-}
-
-static int convert_from_bytes_to_power_of_two(unsigned int x)
-{
- int y = 0;
- y = (x & 0xAAAA) ? 1 : 0;
- y |= ((x & 0xCCCC) ? 1 : 0)<<1;
- y |= ((x & 0xF0F0) ? 1 : 0)<<2;
- y |= ((x & 0xFF00) ? 1 : 0)<<3;
-
- return y;
-}
-
-/*
- * read_bytes - reads bytes from the card, part of data transfer.
- */
-static int read_bytes(struct mmc *dev, u32 *dest, u32 blkcount, u32 blksize)
-{
- u64 xfercount = blkcount * blksize;
- struct mmc_host *host = dev->priv;
- u32 status;
-
- debugX(DBG_LVL_VERBOSE, "read_bytes: blkcount=%u blksize=%u\n",
- blkcount, blksize);
-
- status = mmc_fifo_read(&host->base->fifo, dest, xfercount,
- &host->base->status);
-
- if (status & (SDI_STA_DTIMEOUT | SDI_STA_DCRCFAIL)) {
- printf("Reading data failed: status:0x%08X\n", status);
- if (status & SDI_STA_DTIMEOUT)
- return MMC_DATA_TIMEOUT;
- else if (status & SDI_STA_DCRCFAIL)
- return MMC_DATA_CRC_FAIL;
- }
-
- debugX(DBG_LVL_VERBOSE, "SDI_ICR <= 0x%08X\n", SDI_ICR_MASK);
- writel(SDI_ICR_MASK, &host->base->status_clear);
- debugX(DBG_LVL_VERBOSE, "Reading data completed status:0x%08X\n",
- status);
-
- return MMC_OK;
-}
-
-/*
- * write_bytes - writes byte to the card, part of data transfer.
- */
-static int write_bytes(struct mmc *dev, u32 *src, u32 blkcount, u32 blksize)
-{
- u64 xfercount = blkcount * blksize;
- struct mmc_host *host = dev->priv;
- u32 status;
- u32 status_busy;
-
- debugX(DBG_LVL_VERBOSE, "write_bytes: blkcount=%u blksize=%u\n",
- blkcount, blksize);
-
- status = mmc_fifo_write(src, &host->base->fifo, xfercount,
- &host->base->status);
-
- if (status & (SDI_STA_DTIMEOUT | SDI_STA_DCRCFAIL)) {
- printf("Writing data failed: status=0x%08X\n", status);
- if (status & SDI_STA_DTIMEOUT)
- return MMC_DATA_TIMEOUT;
- else if (status & SDI_STA_DCRCFAIL)
- return MMC_DATA_CRC_FAIL;
- }
-
- /* Wait if busy */
- status_busy = status & SDI_STA_CARDBUSY;
- while (status_busy)
- status_busy = readl(&host->base->status) & SDI_STA_CARDBUSY;
-
- writel(SDI_ICR_MASK, &host->base->status_clear);
- debugX(DBG_LVL_VERBOSE, "Writing data completed status:0x%08X\n",
- status);
-
- return MMC_OK;
-}
-
-/*
- * do_data_transfer - for doing any data transfer operation.
- *
- * dev: mmc device for doing the operation on.
- * cmd: cmd to do.
- * data: if cmd warrants any data transfer.
- */
-static int do_data_transfer(struct mmc *dev,
- struct mmc_cmd *cmd,
- struct mmc_data *data)
-{
-#if (DEBUG >= DBG_LVL_INFO)
- u32 start_time = 0;
-#endif
- int error = MMC_DATA_TIMEOUT;
- struct mmc_host *host = dev->priv;
- u32 blksz = 0;
- u32 data_ctrl = 0;
- u32 data_len = (u32) (data->blocks * data->blocksize);
-
- debugX(DBG_LVL_VERBOSE, "Request to do data xfer on %s\n", dev->name);
- debugX(DBG_LVL_VERBOSE, "do_data_transfer(%u) start\n", data->blocks);
-
-#if (DEBUG >= DBG_LVL_INFO)
- // if (data->blocks > 1)
- // start_time = (u32) get_timer_us();
-#endif
-
- if (cpu_is_u8500v1() || u8500_is_earlydrop()) {
- blksz = convert_from_bytes_to_power_of_two(data->blocksize);
- data_ctrl |= (blksz << INDEX(SDI_DCTRL_DBLOCKSIZE_MASK));
- } else {
- blksz = data->blocksize;
- data_ctrl |= (blksz << INDEX(SDI_DCTRL_DBLOCKSIZE_V2_MASK));
- }
- data_ctrl |= SDI_DCTRL_DTEN | SDI_DCTRL_BUSYMODE;
- if (dev->ddr_en &&
- ((cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) ||
- (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) ||
- (cmd->cmdidx == MMC_CMD_WRITE_SINGLE_BLOCK) ||
- (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK) ||
- (cmd->cmdidx == MMC_CMD_SEND_EXT_CSD)))
- data_ctrl |= SDI_DCTRL_DDR_MODE;
-
-#if (DEBUG >= DBG_LVL_VERBOSE)
- if (data_ctrl & SDI_DCTRL_DDR_MODE)
- printf("SDI_DCTRL_DDR_MODE\n");
-#endif
-
- debugX(DBG_LVL_VERBOSE, "SDI_DTIMER <= 0x%08X\n", dev->data_timeout);
- writel(dev->data_timeout, &host->base->datatimer);
- debugX(DBG_LVL_VERBOSE, "SDI_DLEN <= 0x%08X\n", data_len);
- writel(data_len, &host->base->datalength);
- udelay(DATA_REG_DELAY); /* DONT REMOVE */
-
- if (data->flags & (MMC_DATA_READ)) {
- debugX(DBG_LVL_VERBOSE, "It is a read operation\n");
-
- data_ctrl |= SDI_DCTRL_DTDIR_IN;
- debugX(DBG_LVL_VERBOSE, "SDI_DCTRL <= 0x%08X\n", data_ctrl);
- 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)) {
- debugX(DBG_LVL_VERBOSE, "It is a write operation\n");
-
- error = do_command(dev, cmd);
- if (error)
- return error;
-
- debugX(DBG_LVL_VERBOSE, "SDI_DCTRL <= 0x%08X\n", data_ctrl);
- writel(data_ctrl, &host->base->datactrl);
-
- error = write_bytes(dev,
- (u32 *)data->src,
- (u32)data->blocks,
- (u32)data->blocksize);
- }
-
-#if (DEBUG >= DBG_LVL_INFO)
-#if 0
- if (data->blocks > 1) {
- u32 transfer_time = (u32) get_timer_us() - start_time;
- u64 throughput = lldiv((u64) 1000 * 1000 * data->blocks *
- data->blocksize, transfer_time);
- printf("MMC %s: %u bytes in %u [us] => %llu [B/s] = "
- "%llu [kB/s] = %llu.%02u [MB/s] = %llu [Mbits/s]\n",
- (data->flags & (MMC_DATA_READ)) ? "read" : "write",
- data->blocks * data->blocksize,
- transfer_time,
- throughput, throughput / 1024,
- throughput / (1024 * 1024),
- (u32)((100 * throughput) / (1024 * 1024) -
- (throughput / (1024 * 1024)) * 100),
- throughput * 8 / (1024 * 1024));
- }
-#endif
-#endif
- debugX(DBG_LVL_VERBOSE, "do_data_transfer() end\n");
-
- return error;
-}
-
-/*
- * host_request - For all operations on cards.
- *
- * dev: mmc device for doing the operation on.
- * cmd: cmd to do.
- * data: if cmd warrants any data transfer.
- */
-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;
-}
-
-/*
- * This is to initialize card specific things just before enumerating
- * them. MMC cards uses open drain drivers in enumeration phase.
- */
-static int mmc_host_reset(struct mmc *dev)
-{
- struct mmc_host *host = dev->priv;
- u32 sdi_u32 = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
-
- debugX(DBG_LVL_VERBOSE, "SDI_PWR <= 0x%08X\n", sdi_u32);
- writel(sdi_u32, &host->base->power);
- return MMC_OK;
-}
-
-/*
- * This is to initialize card specific things just before enumerating
- * them. SD cards does not need to be initialized.
- */
-static int sd_host_reset(struct mmc *dev)
-{
- (void) dev; /* Parameter not used! */
-
- return MMC_OK;
-}
-/*
- * host_set_ios:to configure host parameters.
- *
- * dev: the pointer to the host structure for MMC.
- */
-static void host_set_ios(struct mmc *dev)
-{
- struct mmc_host *host = dev->priv;
- u32 sdi_clkcr;
-
- /* First read out the contents of clock control register. */
- sdi_clkcr = readl(&host->base->clock);
-
- /* Set the clock rate and bus width */
- if (dev->clock) {
- u32 clkdiv = 0;
- u32 tmp_clock;
-
- debugX(DBG_LVL_VERBOSE,
- "setting clock and bus width in the host:");
- if (dev->clock >= dev->f_max) {
- clkdiv = 0;
- dev->clock = dev->f_max;
- } else {
- clkdiv = (MCLK / dev->clock) - 2;
- }
- tmp_clock = MCLK / (clkdiv + 2);
- while (tmp_clock > dev->clock) {
- clkdiv++;
- tmp_clock = MCLK / (clkdiv + 2);
- }
- if (clkdiv > SDI_CLKCR_CLKDIV_MASK)
- clkdiv = SDI_CLKCR_CLKDIV_MASK;
- tmp_clock = MCLK / (clkdiv + 2);
- dev->clock = tmp_clock;
- sdi_clkcr &= ~(SDI_CLKCR_CLKDIV_MASK);
- sdi_clkcr |= clkdiv;
- }
-
- 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("wrong bus width, so ignoring");
- break;
- }
- sdi_clkcr &= ~(SDI_CLKCR_WIDBUS_MASK);
- sdi_clkcr |= buswidth;
- }
-
-
- dev->data_timeout = MMC_DATA_TIMEOUT * dev->clock;
-
- debugX(DBG_LVL_VERBOSE, "SDI_CLKCR <= 0x%08X\n", sdi_clkcr);
- writel(sdi_clkcr, &host->base->clock);
- udelay(CLK_CHANGE_DELAY);
-}
-
-struct mmc *alloc_mmc_struct(void)
-{
- struct mmc_host *host = NULL;
- struct mmc *mmc_device = NULL;
-
- host = malloc(sizeof(struct mmc_host));
- if (!host)
- return NULL;
-
- mmc_device = malloc(sizeof(struct mmc));
- if (!mmc_device)
- goto err;
-
- memset(mmc_device, 0x00, sizeof(struct mmc));
-
- mmc_device->priv = host;
- return mmc_device;
- err:
- free(host);
- return NULL;
-}
-
-/*
- * emmc_host_init - initialize the emmc controller.
- * Configure GPIO settings, set initial clock and power for emmc slot.
- * Initialize mmc struct and register with mmc framework.
- */
-static int emmc_host_init(struct mmc *dev)
-{
- struct mmc_host *host = dev->priv;
- u32 sdi_u32;
-
- /* TODO: Investigate what is actually needed of the below. */
-
- if (u8500_is_earlydrop() || u8500_is_snowball()) {
- debugX(DBG_LVL_VERBOSE, "configuring EMMC for ED\n");
- host->base = (struct sdi_registers *)CFG_EMMC_BASE_ED;
- } else {
- debugX(DBG_LVL_VERBOSE, "configuring EMMC for V1\n");
- host->base = (struct sdi_registers *)CFG_EMMC_BASE_V1;
- }
-
- sdi_u32 = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
- debugX(DBG_LVL_VERBOSE, "SDI_PWR <= 0x%08X\n", sdi_u32);
- writel(sdi_u32, &host->base->power);
- /* setting clk freq less than 400KHz */
- sdi_u32 = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
- debugX(DBG_LVL_VERBOSE, "SDI_CLKCR <= 0x%08X\n", sdi_u32);
- writel(sdi_u32, &host->base->clock);
- udelay(CLK_CHANGE_DELAY);
- sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
- debugX(DBG_LVL_VERBOSE, "SDI_MASK0 <= 0x%08X\n", sdi_u32);
- writel(sdi_u32, &host->base->mask0);
- dev->clock = MCLK / (2 + SDI_CLKCR_CLKDIV_INIT);
- sprintf(dev->name, "EMMC");
- dev->send_cmd = host_request;
- dev->set_ios = host_set_ios;
- dev->init = mmc_host_reset;
- dev->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS |
- MMC_MODE_HS_52MHz /* | MMC_MODE_REL_WR | MMC_MODE_DDR */;
- dev->voltages = VOLTAGE_WINDOW_MMC;
- dev->f_min = dev->clock;
- dev->f_max = MCLK / 2;
- dev->ddr_en = 0;
- return 0;
-}
-
-/*
- * mmc_host_init - initialize the external mmc controller.
- * Configure GPIO settings, set initial clock and power for mmc slot.
- * Initialize mmc struct and register with mmc framework.
- */
-static int mmc_host_init(struct mmc *dev)
-{
- struct mmc_host *host = dev->priv;
- u32 sdi_u32;
-
- host->base = (struct sdi_registers *)CFG_MMC_BASE;
- sdi_u32 = 0xBF;
- debugX(DBG_LVL_VERBOSE, "SDI_PWR <= 0x%08X\n", sdi_u32);
- writel(sdi_u32, &host->base->power);
- /* setting clk freq just less than 400KHz */
- sdi_u32 = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
- debugX(DBG_LVL_VERBOSE, "SDI_CLKCR <= 0x%08X\n", sdi_u32);
- writel(sdi_u32, &host->base->clock);
- udelay(CLK_CHANGE_DELAY);
- sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
- debugX(DBG_LVL_VERBOSE, "SDI_MASK0 <= 0x%08X\n", sdi_u32);
- writel(sdi_u32, &host->base->mask0);
- dev->clock = MCLK / (2 + SDI_CLKCR_CLKDIV_INIT);
- sprintf(dev->name, "MMC");
- dev->send_cmd = host_request;
- dev->set_ios = host_set_ios;
- dev->init = sd_host_reset;
- dev->host_caps = /* MMC_MODE_4BIT */ 0; /* Some SD cards do not work in
- 4 bit mode! */
- dev->voltages = VOLTAGE_WINDOW_SD;
- dev->f_min = dev->clock;
- dev->f_max = MCLK / 2;
- dev->ddr_en = 0;
- return 0;
-}
-
-/*
- * board_mmc_init - initialize all the mmc/sd host controllers.
- * Called by generic mmc framework.
- */
-int board_mmc_init(bd_t *bis)
-{
- int error;
- struct mmc *dev;
-
- debugX(DBG_LVL_VERBOSE, "[%s] mmc_host - board_mmc_init board ed %d, snow %d\n",
- __func__,u8500_is_earlydrop(), u8500_is_snowball());
-
- (void) bis; /* Parameter not used! */
-
- dev = alloc_mmc_struct();
- if (!dev)
- return -1;
-
- error = emmc_host_init(dev);
- if (error) {
- printf("emmc_host_init() %d \n", error);
- return -1;
- }
- mmc_register(dev);
- debugX(DBG_LVL_VERBOSE, "registered emmc interface number is:%d\n",
- dev->block_dev.dev);
-
-
- mmc_init(dev);
-
- /*
- * In a perfect world board_early_access shouldn't be here but we want
- * some functionality to be loaded as quickly as possible and putting it
- * here will get the shortest time to start that functionality. Time
- * saved by putting it here compared to later is somewhere between
- * 0.3-0.7s. That is enough to be able to justify putting it here.
- */
-
- board_early_access(&dev->block_dev);
-
- dev = alloc_mmc_struct();
- if (!dev)
- return -1;
-
- error = mmc_host_init(dev);
- if (error) {
- printf("mmc_host_init() %d \n", error);
- return -1;
- }
- mmc_register(dev);
- debugX(DBG_LVL_VERBOSE, "registered mmc/sd interface number is:%d\n",
- dev->block_dev.dev);
-
- return 0;
-}
diff --git a/board/st-ericsson/snowball/mmc_host.h b/board/st-ericsson/snowball/mmc_host.h
deleted file mode 100644
index 3b5e1c589..000000000
--- a/board/st-ericsson/snowball/mmc_host.h
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Ulf Hansson <ulf.hansson@stericsson.com>
- * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
- *
- * License terms: GNU General Public License (GPL), version 2.
- */
-
-#ifndef __MMC_NOMADIK_H__
-#define __MMC_NOMADIK_H__
-
-/* See SDI (SD card host interface) documentation in U8500 sw specification. */
-
-#define COMMAND_REG_DELAY 300
-#define DATA_REG_DELAY 10000
-#define CLK_CHANGE_DELAY 2000
-
-#define MAX_ERROR_VALUE -65
-#ifndef __ASSEMBLY__
-enum mmc_result {
- /* MMC specific error defines */
- MMC_CMD_CRC_FAIL = (MAX_ERROR_VALUE - 1),/* Command response received
- (but CRC check failed) */
- MMC_DATA_CRC_FAIL = (MAX_ERROR_VALUE - 2),/* Data bock sent/received
- (CRC check Failed) */
- MMC_CMD_RSP_TIMEOUT = (MAX_ERROR_VALUE - 3),/*Command response timeout
- */
- MMC_DATA_TIMEOUT = (MAX_ERROR_VALUE - 4),/* Data time out*/
- MMC_TX_UNDERRUN = (MAX_ERROR_VALUE - 5),/* Transmit FIFO under-run */
- MMC_RX_OVERRUN = (MAX_ERROR_VALUE - 6), /* Receive FIFO over-run */
- MMC_START_BIT_ERR = (MAX_ERROR_VALUE - 7),/* Start bit not detected on
- all data signals in widE bus mode */
- MMC_CMD_OUT_OF_RANGE = (MAX_ERROR_VALUE - 8),/* CMD's argument was out
- of range.*/
- MMC_ADDR_MISALIGNED = (MAX_ERROR_VALUE - 9),/* Misaligned address */
- MMC_BLOCK_LEN_ERR = (MAX_ERROR_VALUE - 10),/* Transferred block length
- is not allowed for the card or the number of
- transferred bytes does not match the block length*/
- MMC_ERASE_SEQ_ERR = (MAX_ERROR_VALUE - 11),/* An error in the sequence
- of erase command occurs.*/
- MMC_BAD_ERASE_PARAM = (MAX_ERROR_VALUE - 12),/* An Invalid selection
- for erase groups */
- MMC_WRITE_PROT_VIOLATION = (MAX_ERROR_VALUE - 13),/* Attempt to program
- a write protect block */
- MMC_LOCK_UNLOCK_FAILED = (MAX_ERROR_VALUE - 14),/* Sequence or password
- error has been detected in unlock command or
- if there was an attempt to access a locked card */
- MMC_COM_CRC_FAILED = (MAX_ERROR_VALUE - 15),/* CRC check of the
- previous command failed*/
- MMC_ILLEGAL_CMD = (MAX_ERROR_VALUE - 16),/* Command is not legal for
- the card state */
- MMC_CARD_ECC_FAILED = (MAX_ERROR_VALUE - 17),/* Card internal ECC was
- applied but failed to correct the data */
- MMC_CC_ERROR = (MAX_ERROR_VALUE - 18),/*Internal card controller error
- */
- MMC_GENERAL_UNKNOWN_ERROR = (MAX_ERROR_VALUE - 19),/* General or
- Unknown error */
- MMC_STREAM_READ_UNDERRUN = (MAX_ERROR_VALUE - 20),/* The card could not
- sustain data transfer in stream read
- operation. */
- MMC_STREAM_WRITE_OVERRUN = (MAX_ERROR_VALUE - 21),/* The card could not
- sustain data programming in stream mode */
- MMC_CID_CSD_OVERWRITE = (MAX_ERROR_VALUE - 22), /* CID/CSD overwrite
- error */
- MMC_WP_ERASE_SKIP = (MAX_ERROR_VALUE - 23),/* only partial address
- space was erased */
- MMC_CARD_ECC_DISABLED = (MAX_ERROR_VALUE - 24),/* Command has been
- executed without using internal ECC */
- MMC_ERASE_RESET = (MAX_ERROR_VALUE - 25),/* Erase sequence was cleared
- before executing because an out of erase sequence
- command was received */
- MMC_AKE_SEQ_ERROR = (MAX_ERROR_VALUE - 26),/* Error in sequence of
- authentication. */
- MMC_INVALID_VOLTRANGE = (MAX_ERROR_VALUE - 27),
- MMC_ADDR_OUT_OF_RANGE = (MAX_ERROR_VALUE - 28),
- MMC_SWITCH_ERROR = (MAX_ERROR_VALUE - 29),
- MMC_SDIO_DISABLED = (MAX_ERROR_VALUE - 30),
- MMC_SDIO_FUNCTION_BUSY = (MAX_ERROR_VALUE - 31),
- MMC_SDIO_FUNCTION_FAILED = (MAX_ERROR_VALUE - 32),
- MMC_SDIO_UNKNOWN_FUNCTION = MAX_ERROR_VALUE,
- /* standard error defines */
- MMC_INTERNAL_ERROR = -8,
- MMC_NOT_CONFIGURED = -7,
- MMC_REQUEST_PENDING = -6,
- MMC_REQUEST_NOT_APPLICABLE = -5,
- MMC_INVALID_PARAMETER = -4,
- MMC_UNSUPPORTED_FEATURE = -3,
- MMC_UNSUPPORTED_HW = -2,
- MMC_ERROR = -1,
- MMC_OK = 0,
- MMC_INTERNAL_EVENT = 1,
- MMC_REMAINING_PENDING_EVENTS = 2,
- MMC_REMAINING_FILTER_PENDING_EVENTS = 3,
- MMC_NO_MORE_PENDING_EVENT = 4,
- MMC_NO_MORE_FILTER_PENDING_EVENT = 5,
- MMC_NO_PENDING_EVENT_ERROR = 7,
-};
-#endif
-
-#define MCLK (100*1000*1000)
-
-#define INDEX(mask) ( \
- ((mask & 0x00000001) ? 0 : \
- ((mask & 0x00000002) ? 1 : \
- ((mask & 0x00000004) ? 2 : \
- ((mask & 0x00000008) ? 3 : \
- ((mask & 0x00000010) ? 4 : \
- ((mask & 0x00000020) ? 5 : \
- ((mask & 0x00000040) ? 6 : \
- ((mask & 0x00000080) ? 7 : \
- ((mask & 0x00000100) ? 8 : \
- ((mask & 0x00000200) ? 9 : \
- ((mask & 0x00000400) ? 10 : \
- ((mask & 0x00000800) ? 11 : \
- ((mask & 0x00001000) ? 12 : \
- ((mask & 0x00002000) ? 13 : \
- ((mask & 0x00004000) ? 14 : \
- ((mask & 0x00008000) ? 15 : \
- ((mask & 0x00010000) ? 16 : \
- ((mask & 0x00020000) ? 17 : \
- ((mask & 0x00040000) ? 18 : \
- ((mask & 0x00080000) ? 19 : \
- ((mask & 0x00100000) ? 20 : \
- ((mask & 0x00200000) ? 21 : \
- ((mask & 0x00400000) ? 22 : \
- ((mask & 0x00800000) ? 23 : \
- ((mask & 0x01000000) ? 24 : \
- ((mask & 0x02000000) ? 25 : \
- ((mask & 0x04000000) ? 26 : \
- ((mask & 0x08000000) ? 27 : \
- ((mask & 0x10000000) ? 28 : \
- ((mask & 0x20000000) ? 29 : \
- ((mask & 0x40000000) ? 30 : \
- ((mask & 0x80000000) ? 31 : 0) \
- ))))))))))))))))))))))))))))))) \
-)
-
-#define MMC_PERIPHERAL_ID0 0x81
-#define MMC_PERIPHERAL_ID1 0x11
-#define MMC_PERIPHERAL_ID2 0x04
-#define MMC_PERIPHERAL_ID3 0x00
-
-/* 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)
-#define SDI_CLKCR_WIDBUS_8 (0x00001000)
-#define SDI_CLKCR_NEGEDGE (0x00002000)
-#define SDI_CLKCR_HWFC_EN (0x00004000)
-
-#define SDI_CLKCR_CLKDIV_INIT (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)
-
-/* MMC_DATA_TIMEOUT sets the data timeout in seconds */
-#define MMC_DATA_TIMEOUT (30)
-
-/* SDI Status register bits */
-
-#define SDI_STA_CCRCFAIL (0x00000001) /* (1 << 0) */
-#define SDI_STA_DCRCFAIL (0x00000002) /* (1 << 1) */
-#define SDI_STA_CTIMEOUT (0x00000004) /* (1 << 2) */
-#define SDI_STA_DTIMEOUT (0x00000008) /* (1 << 3) */
-#define SDI_STA_TXUNDERR (0x00000010) /* (1 << 4) */
-#define SDI_STA_RXOVERR (0x00000020) /* (1 << 5) */
-#define SDI_STA_CMDREND (0x00000040) /* (1 << 6) */
-#define SDI_STA_CMDSENT (0x00000080) /* (1 << 7) */
-#define SDI_STA_DATAEND (0x00000100) /* (1 << 8) */
-#define SDI_STA_STBITERR (0x00000200) /* (1 << 9) */
-#define SDI_STA_DBCKEND (0x00000400) /* (1 << 10) */
-#define SDI_STA_CMDACT (0x00000800) /* (1 << 11) */
-#define SDI_STA_TXACT (0x00001000) /* (1 << 12) */
-#define SDI_STA_RXACT (0x00002000) /* (1 << 13) */
-#define SDI_STA_TXFIFOBW (0x00004000) /* (1 << 14) */
-#define SDI_STA_RXFIFOBR (0x00008000) /* (1 << 15) */
-#define SDI_STA_TXFIFOF (0x00010000) /* (1 << 16) */
-#define SDI_STA_RXFIFOF (0x00020000) /* (1 << 17) */
-#define SDI_STA_TXFIFOE (0x00040000) /* (1 << 18) */
-#define SDI_STA_RXFIFOE (0x00080000) /* (1 << 19) */
-#define SDI_STA_TXDAVL (0x00100000) /* (1 << 20) */
-#define SDI_STA_RXDAVL (0x00200000) /* (1 << 21) */
-#define SDI_STA_SDIOIT (0x00400000) /* (1 << 22) */
-#define SDI_STA_CEATAEND (0x00800000) /* (1 << 23) */
-#define SDI_STA_CARDBUSY (0x01000000) /* (1 << 24) */
-#define SDI_STA_BOOTMODE (0x02000000) /* (1 << 25) */
-#define SDI_STA_BOOTACKERR (0x04000000) /* (1 << 26) */
-#define SDI_STA_BOOTACKTIMEOUT (0x08000000) /* (1 << 27) */
-#define SDI_STA_RSTNEND (0x10000000) /* (1 << 28) */
-
-/* SDI Interrupt Clear register bits */
-
-#define SDI_ICR_MASK (0x1DC007FF)
-#define SDI_ICR_CCRCFAILC (0x00000001) /* (1 << 0) */
-#define SDI_ICR_DCRCFAILC (0x00000002) /* (1 << 1) */
-#define SDI_ICR_CTIMEOUTC (0x00000004) /* (1 << 2) */
-#define SDI_ICR_DTIMEOUTC (0x00000008) /* (1 << 3) */
-#define SDI_ICR_TXUNDERRC (0x00000010) /* (1 << 4) */
-#define SDI_ICR_RXOVERRC (0x00000020) /* (1 << 5) */
-#define SDI_ICR_CMDRENDC (0x00000040) /* (1 << 6) */
-#define SDI_ICR_CMDSENTC (0x00000080) /* (1 << 7) */
-#define SDI_ICR_DATAENDC (0x00000100) /* (1 << 8) */
-#define SDI_ICR_STBITERRC (0x00000200) /* (1 << 9) */
-#define SDI_ICR_DBCKENDC (0x00000400) /* (1 << 10) */
-#define SDI_ICR_SDIOITC (0x00400000) /* (1 << 22) */
-#define SDI_ICR_CEATAENDC (0x00800000) /* (1 << 23) */
-#define SDI_ICR_BUSYENDC (0x01000000) /* (1 << 24) */
-#define SDI_ICR_BOOTACKERRC (0x04000000) /* (1 << 26) */
-#define SDI_ICR_BOOTACKTIMEOUTC (0x08000000) /* (1 << 27) */
-#define SDI_ICR_RSTNENDC (0x10000000) /* (1 << 28) */
-
-#define SDI_MASK0_MASK (0x1FFFFFFF)
-
-/* SDI Data control register bits */
-
-#define SDI_DCTRL_DTEN (0x00000001) /* (1 << 0) */
-#define SDI_DCTRL_DTDIR_IN (0x00000002) /* (1 << 1) */
-#define SDI_DCTRL_DTMODE_STREAM (0x00000004) /* (1 << 2) */
-#define SDI_DCTRL_DMAEN (0x00000008) /* (1 << 3) */
-#define SDI_DCTRL_DBLOCKSIZE_MASK (0x000000F0)
-#define SDI_DCTRL_RWSTART (0x00000100) /* (1 << 8) */
-#define SDI_DCTRL_RWSTOP (0x00000200) /* (1 << 9) */
-#define SDI_DCTRL_RWMOD (0x00000200) /* (1 << 10) */
-#define SDI_DCTRL_SDIOEN (0x00000800) /* (1 << 11) */
-#define SDI_DCTRL_DMAREQCTL (0x00001000) /* (1 << 12) */
-#define SDI_DCTRL_DBOOTMODEEN (0x00002000) /* (1 << 13) */
-#define SDI_DCTRL_BUSYMODE (0x00004000) /* (1 << 14) */
-#define SDI_DCTRL_DDR_MODE (0x00008000) /* (1 << 15) */
-#define SDI_DCTRL_DBLOCKSIZE_V2_MASK (0x7fff0000)
-
-#define SDI_FIFO_BURST_SIZE (8)
-
-#ifndef __ASSEMBLY__
-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 Identi.cation 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*/
-};
-#endif
-
-#endif
diff --git a/board/st-ericsson/snowball/mmc_utils.c b/board/st-ericsson/snowball/mmc_utils.c
deleted file mode 100644
index 6c5a8150d..000000000
--- a/board/st-ericsson/snowball/mmc_utils.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2009
- *
- * 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 <linux/ctype.h>
-
-#include <asm/arch/common.h>
-#include <asm/arch/cpu.h>
-#include <command.h>
-#include <mmc.h>
-#include <fat.h>
-
-#define PIB_EMMC_ADDR 0x00
-
-struct partition {
- unsigned char boot_ind; /* 0x80 - active */
- unsigned char head; /* starting head */
- unsigned char sector; /* starting sector */
- unsigned char cyl; /* starting cylinder */
- unsigned char sys_ind; /* What partition type */
- unsigned char end_head; /* end head */
- unsigned char end_sector; /* end sector */
- unsigned char end_cyl; /* end cylinder */
- u32 start_sect; /* starting sector counting from 0 */
- u32 nr_sects; /* nr of sectors in partition */
-} __attribute__((packed));
-
-#define PART(type, start, num) \
- { \
- .boot_ind = 0x00, \
- .head = 0x03, \
- .sector = 0xD0, \
- .cyl = 0xff, \
- .sys_ind = type, \
- .end_head = 0x03, \
- .end_sector = 0xd0, \
- .end_cyl = 0xff, \
- .start_sect = start, \
- .nr_sects = num, \
- }
-
-static struct partition partitions_ed[] = {
- [0] = PART(0x83, 0x000A0000, 0x00004000), /* Kernel */
- [1] = PART(0x83, 0x000A4000, 0x00080000), /* Root file system */
- [2] = PART(0x83, 0x00124000, 0x0022c000),
- [3] = PART(0x0c, 0x00350000, 0x00b9a000),
-};
-
-static struct partition partitions_v1[] = {
- [0] = PART(0x83, 0x000A0000, 0x00004000), /* Kernel */
- [1] = PART(0x83, 0x000A4000, 0x00080000), /* Root file system */
- [2] = PART(0x83, 0x00000400, 0x00000800), /* Modem parameters */
- [3] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-};
-
-#undef PART
-
-int write_partition_block(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- int err;
- u32 offset = PIB_EMMC_ADDR;
- u8 mbr[512];
- u8 emmc_existing_partition[512];
- struct mmc *boot_dev = NULL;
-
- (void) cmdtp; /* Parameter not used! */
- (void) flag; /* Parameter not used! */
- (void) argc; /* Parameter not used! */
- (void) argv; /* Parameter not used! */
-
- memset(mbr, 0, 0x1be);
- if (u8500_is_earlydrop())
- memcpy(mbr + 0x1be, partitions_ed, sizeof(partitions_ed));
- else
- memcpy(mbr + 0x1be, partitions_v1, sizeof(partitions_v1));
-
- /* magic */
- mbr[0x1fe] = 0x55;
- mbr[0x1ff] = 0xAA;
-
- printf("Writing partition block (if needed)...\n");
-
- boot_dev = find_mmc_device(CONFIG_EMMC_DEV_NUM);
- if (!boot_dev) {
- printf(" Error: eMMC device not found\n");
- return 1;
- }
-
- err = boot_dev->block_dev.block_read(CONFIG_EMMC_DEV_NUM,
- offset,
- 1,
- (void *) emmc_existing_partition);
- if (err != 1) {
- printf(" Error: eMMC read failed\n");
- return 1;
- }
-
- if (memcmp((void *)emmc_existing_partition, (void *)mbr, 512)) {
- err = boot_dev->block_dev.block_write(CONFIG_EMMC_DEV_NUM,
- offset,
- 1,
- (void *) mbr);
- if (err != 1) {
- printf(" Error: eMMC write failed\n");
- return 1;
- }
- }
- printf(" eMMC partition block exists now\n");
- return 0;
-}
-
-U_BOOT_CMD(
- write_partition_block, 1, 0, write_partition_block,
- "- write partition block on emmc device\n",
- NULL
-);
-
-/*
- * command line commands
- */
-#ifdef CONFIG_CMD_FAT
-static int mmc_read_cmd_file(cmd_tbl_t *cmdtp, int flag, int argc,
- char *argv[])
-{
- long sz;
- char mmc_cmdbuffer[1024];
- struct mmc *mmc_dev;
- (void) cmdtp; /* Parameter not used! */
- (void) flag; /* Parameter not used! */
- (void) argc; /* Parameter not used! */
- (void) argv; /* Parameter not used! */
-
- mmc_dev = find_mmc_device(CONFIG_MMC_DEV_NUM);
- if (mmc_dev == NULL) {
- printf("mmc_read_cmd_file: find_mmc_device failed\n");
- return 1;
- }
-
- if (fat_register_device(&mmc_dev->block_dev, 1) != 0) {
- printf("mmc_read_cmd_file: fat_register_device failed\n");
- return 1;
- }
-
- sz = file_fat_read("/command.txt", &mmc_cmdbuffer,
- sizeof(mmc_cmdbuffer) - 1);
- if (sz == -1) {
- printf("No command.txt found in the MMC/SD card\n");
- return 1;
- }
-
- mmc_cmdbuffer[sz] = '\0';
- setenv("bootcmd", mmc_cmdbuffer);
- return 0;
-}
-
-U_BOOT_CMD(
- mmc_read_cmd_file, 1, 0, mmc_read_cmd_file,
- "setup bootcmd env from command.txt on SD",
- NULL
-);
-#endif
-
-/* ------------------------------- End of file ---------------------------- */
diff --git a/board/st-ericsson/snowball/snowball.c b/board/st-ericsson/snowball/snowball.c
index 4379b2cb9..bcd5cdb95 100644
--- a/board/st-ericsson/snowball/snowball.c
+++ b/board/st-ericsson/snowball/snowball.c
@@ -18,7 +18,9 @@
#include <config.h>
#include <common.h>
+#include <malloc.h>
#include <i2c.h>
+#include <mmc.h>
#include <asm/types.h>
#include <asm/io.h>
#include <asm/errno.h>
@@ -31,6 +33,8 @@
#include <asm/arch/prcmu.h>
#include <asm/arch/common.h>
+#include "../../../drivers/mmc/arm_pl180_mmci.h"
+
#include <db8500_pincfg.h>
#include "db8500_pins.h"
@@ -254,7 +258,7 @@ int board_early_access(block_dev_desc_t *block_dev)
return 0;
}
-#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_BOARD_LATE_INIT
#ifdef CONFIG_MMC
#define LDO_VAUX3_ENABLE_MASK 0x3
@@ -424,7 +428,6 @@ out:
return ret;
}
-
/*
* called after all initialisation were done, but before the generic
* mmc_initialize().
@@ -455,8 +458,11 @@ int board_late_init(void)
/* setup FSMC for LAN controler */
writel(0x305b, 0x80000000);
- /* the default is too slow */
- writel(0x01010110, 0x80000004);
+ /*
+ * the default is too slow
+ * NOTE: below this some boards corrupt data in SRAM transfers
+ */
+ writel(0x01010210, 0x80000004);
}
/* enable 3V6 for GBF chip */
@@ -477,5 +483,113 @@ int board_late_init(void)
return (0);
}
-#endif /* BOARD_LATE_INIT */
+/*
+ * emmc_host_init - initialize the emmc controller.
+ * Configure GPIO settings, set initial clock and power for emmc slot.
+ * Initialize mmc struct and register with mmc framework.
+ */
+static int emmc_host_init(void)
+{
+ struct pl180_mmc_host *host;
+ u32 sdi_u32;
+ int rc = 0;
+ struct mmc *dev;
+
+ host = malloc(sizeof(struct pl180_mmc_host));
+ if (!host)
+ return -ENOMEM;
+ memset(host, 0, sizeof(*host));
+
+ host->base = (struct sdi_registers *)CFG_EMMC_BASE;
+ host->pwr_init = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
+ host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
+ strcpy(host->name, "EMMC");
+ host->caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz;
+ host->voltages = VOLTAGE_WINDOW_MMC;
+ host->clock_min = ARM_MCLK / (2 + SDI_CLKCR_CLKDIV_INIT);
+ host->clock_max = ARM_MCLK / 2;
+ host->clock_in = ARM_MCLK;
+ host->version2 = 1;
+
+ rc = arm_pl180_mmci_init(host);
+
+ if (rc < 0)
+ return rc;
+
+ dev = find_mmc_device(0);
+ if (!dev)
+ return -ENODEV;
+
+ rc = mmc_init(dev);
+
+ return rc;
+}
+
+/*
+ * mmc_host_init - initialize the external mmc controller.
+ * Configure GPIO settings, set initial clock and power for mmc slot.
+ * Initialize mmc struct and register with mmc framework.
+ */
+static int mmc_host_init(void)
+{
+ struct pl180_mmc_host *host;
+ u32 sdi_u32;
+ int rc = 0;
+
+ host = malloc(sizeof(struct pl180_mmc_host));
+ if (!host)
+ return -ENOMEM;
+ memset(host, 0, sizeof(*host));
+
+ host->base = (struct sdi_registers *)CFG_MMC_BASE;
+ sdi_u32 = 0xBF;
+ writel(sdi_u32, &host->base->power);
+ host->pwr_init = 0xBF;
+ host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
+ strcpy(host->name, "MMC");
+ host->caps = 0; /* Some SD cards do not work in 4 bit mode! */
+ host->b_max = 0;
+ host->voltages = VOLTAGE_WINDOW_SD;
+ host->clock_min = ARM_MCLK / (2 + SDI_CLKCR_CLKDIV_INIT);
+ host->clock_max = ARM_MCLK / 2;
+ host->clock_in = ARM_MCLK;
+ host->version2 = 1;
+ rc = arm_pl180_mmci_init(host);
+
+ return rc;
+}
+
+/*
+ * board_mmc_init - initialize all the mmc/sd host controllers.
+ * Called by generic mmc framework.
+ */
+int board_mmc_init(bd_t *bis)
+{
+ int error;
+
+ (void) bis;
+
+ error = emmc_host_init();
+ if (error) {
+ printf("emmc_host_init() %d \n", error);
+ return -1;
+ }
+
+ /*
+ * In a perfect world board_early_access shouldn't be here but we want
+ * some functionality to be loaded as quickly as possible and putting it
+ * here will get the shortest time to start that functionality. Time
+ * saved by putting it here compared to later is somewhere between
+ * 0.3-0.7s. That is enough to be able to justify putting it here.
+ */
+
+ error = mmc_host_init();
+ if (error) {
+ printf("mmc_host_init() %d \n", error);
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* CONFIG_BOARD_LATE_INIT */