summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/freescale/imx51/config.mk2
-rw-r--r--common/cmd_nvedit.c8
-rw-r--r--cpu/arm_cortexa8/config.mk17
-rw-r--r--cpu/arm_cortexa8/cpu.c1
-rw-r--r--cpu/arm_cortexa8/mx51/Makefile2
-rw-r--r--cpu/arm_cortexa8/mx51/interrupts.c78
-rw-r--r--cpu/arm_cortexa8/mx51/timer.c123
-rw-r--r--drivers/mmc/fsl_esdhc.c648
-rw-r--r--drivers/net/mxc_fec.c4
-rw-r--r--include/configs/imx51.h34
10 files changed, 202 insertions, 715 deletions
diff --git a/board/freescale/imx51/config.mk b/board/freescale/imx51/config.mk
index ce7369d..705aa34 100644
--- a/board/freescale/imx51/config.mk
+++ b/board/freescale/imx51/config.mk
@@ -1 +1,3 @@
+LDSCRIPT := $(SRCTREE)/board/$(VENDOR)/$(BOARD)/u-boot.lds
+
TEXT_BASE = 0x97800000
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index cda14e8..e0ccd56 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -613,14 +613,6 @@ U_BOOT_CMD(
" - delete environment variable 'name'"
);
-#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
-U_BOOT_CMD(
- saveenv, 1, 0, do_saveenv,
- "saveenv - save environment variables to persistent storage\n",
- NULL
-);
-#endif
-
#if defined(CONFIG_CMD_ASKENV)
U_BOOT_CMD(
diff --git a/cpu/arm_cortexa8/config.mk b/cpu/arm_cortexa8/config.mk
index 954ad98..079bd5f 100644
--- a/cpu/arm_cortexa8/config.mk
+++ b/cpu/arm_cortexa8/config.mk
@@ -30,11 +30,14 @@ PLATFORM_CPPFLAGS += -march=armv5
# Supply options according to compiler version
#
# =========================================================================
-ifdef CONFIG_SYS_APCS_GNU
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-else
-PLATFORM_CPPFLAGS +=$(call cc-option)
-endif
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
-PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
+#ifdef CONFIG_SYS_APCS_GNU
+#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+#else
+#PLATFORM_CPPFLAGS +=$(call cc-option)
+#endif
+#PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,\
+# $(call cc-option,-mshort-load-bytes,\
+# $(call cc-option,-malignment-traps,)))
+
+PLATFORM_CPPFLAGS +=$(call cc-option,-mshort-load-bytes,\
$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm_cortexa8/cpu.c b/cpu/arm_cortexa8/cpu.c
index 79f04ea..df96804 100644
--- a/cpu/arm_cortexa8/cpu.c
+++ b/cpu/arm_cortexa8/cpu.c
@@ -35,7 +35,6 @@
#include <command.h>
#include <asm/system.h>
#include <asm/cache.h>
-#include <asm/arch/sys_proto.h>
#ifndef CONFIG_L2_OFF
#ifndef CONFIG_MXC
diff --git a/cpu/arm_cortexa8/mx51/Makefile b/cpu/arm_cortexa8/mx51/Makefile
index 6f10e3e..940b05c 100644
--- a/cpu/arm_cortexa8/mx51/Makefile
+++ b/cpu/arm_cortexa8/mx51/Makefile
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
-COBJS = interrupts.o serial.o generic.o iomux.o
+COBJS = interrupts.o serial.o generic.o iomux.o timer.o
SOBJS = mxc_nand_load.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/arm_cortexa8/mx51/interrupts.c b/cpu/arm_cortexa8/mx51/interrupts.c
index 484b961..1b5a4d1 100644
--- a/cpu/arm_cortexa8/mx51/interrupts.c
+++ b/cpu/arm_cortexa8/mx51/interrupts.c
@@ -38,90 +38,12 @@
#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */
#define GPTCR_TEN (1) /* Timer enable */
-static inline void setup_gpt()
-{
- int i;
- static int init_done;
-
- if (init_done)
- return;
-
- init_done = 1;
-
- /* setup GP Timer 1 */
- GPTCR = GPTCR_SWR;
- for (i = 0; i < 100; i++)
- GPTCR = 0; /* We have no udelay by now */
- GPTPR = 0; /* 32Khz */
- /* Freerun Mode, PERCLK1 input */
- GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
-}
-
/* nothing really to do with interrupts, just starts up a counter. */
int interrupt_init(void)
{
- setup_gpt();
-
return 0;
}
-void reset_timer(void)
-{
- reset_timer_masked();
-}
-
-void reset_timer_masked(void)
-{
- GPTCR = 0;
- /* Freerun Mode, PERCLK1 input */
- GPTCR = GPTCR_CLKSOURCE_32 | GPTCR_TEN;
-}
-
-ulong get_timer_masked(void)
-{
- ulong val = GPTCNT;
- return val;
-}
-
-ulong get_timer(ulong base)
-{
- return get_timer_masked() - base;
-}
-
-void set_timer(ulong t)
-{
-}
-
-/* delay x useconds AND perserve advance timstamp value */
-void udelay(unsigned long usec)
-{
- ulong tmo, tmp;
-
- setup_gpt();
-
- /* if "big" number, spread normalization to seconds */
- if (usec >= 1000) {
- /* start to normalize for usec to ticks per sec */
- tmo = usec / 1000;
- /* find number of "ticks" to wait to achieve target */
- tmo *= CONFIG_SYS_HZ;
- tmo /= 1000; /* finish normalize. */
- } else {/* else small number, don't kill it prior to HZ multiply */
- tmo = usec * CONFIG_SYS_HZ;
- tmo /= (1000 * 1000);
- }
-
- tmp = get_timer(0); /* get current timestamp */
- /* if setting this forward will roll time stamp */
- if ((tmo + tmp + 1) < tmp)
- /* reset "advancing" timestamp to 0, set lastinc value */
- reset_timer_masked();
- else /* else, set advancing stamp wake up time */
- tmo += tmp;
- while (get_timer_masked() < tmo) /* loop till event */
- /*NOP*/;
-}
-
void reset_cpu(ulong addr)
{
__REG16(WDOG1_BASE_ADDR) = 4;
diff --git a/cpu/arm_cortexa8/mx51/timer.c b/cpu/arm_cortexa8/mx51/timer.c
new file mode 100644
index 0000000..ff982be
--- /dev/null
+++ b/cpu/arm_cortexa8/mx51/timer.c
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ *
+ * (C) Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * 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 <asm/arch/mx51.h>
+
+/* General purpose timers registers */
+#define GPTCR __REG(GPT1_BASE_ADDR) /* Control register */
+#define GPTPR __REG(GPT1_BASE_ADDR + 0x4) /* Prescaler register */
+#define GPTSR __REG(GPT1_BASE_ADDR + 0x8) /* Status register */
+#define GPTCNT __REG(GPT1_BASE_ADDR + 0x24) /* Counter register */
+
+/* General purpose timers bitfields */
+#define GPTCR_SWR (1<<15) /* Software reset */
+#define GPTCR_FRR (1<<9) /* Freerun / restart */
+#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */
+#define GPTCR_TEN (1) /* Timer enable */
+
+static inline void setup_gpt()
+{
+ int i;
+ static int init_done;
+
+ if (init_done)
+ return;
+
+ init_done = 1;
+
+ /* setup GP Timer 1 */
+ GPTCR = GPTCR_SWR;
+ for (i = 0; i < 100; i++)
+ GPTCR = 0; /* We have no udelay by now */
+ GPTPR = 0; /* 32Khz */
+ /* Freerun Mode, PERCLK1 input */
+ GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
+}
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init(void)
+{
+ setup_gpt();
+
+ return 0;
+}
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+void reset_timer_masked(void)
+{
+ GPTCR = 0;
+ /* Freerun Mode, PERCLK1 input */
+ GPTCR = GPTCR_CLKSOURCE_32 | GPTCR_TEN;
+}
+
+ulong get_timer_masked(void)
+{
+ ulong val = GPTCNT;
+ return val;
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void udelay(unsigned long usec)
+{
+ ulong tmo, tmp;
+
+ setup_gpt();
+
+ /* if "big" number, spread normalization to seconds */
+ if (usec >= 1000) {
+ /* start to normalize for usec to ticks per sec */
+ tmo = usec / 1000;
+ /* find number of "ticks" to wait to achieve target */
+ tmo *= CONFIG_SYS_HZ;
+ tmo /= 1000; /* finish normalize. */
+ } else {/* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CONFIG_SYS_HZ;
+ tmo /= (1000 * 1000);
+ }
+
+ tmp = get_timer(0); /* get current timestamp */
+ /* if setting this forward will roll time stamp */
+ if ((tmo + tmp + 1) < tmp)
+ /* reset "advancing" timestamp to 0, set lastinc value */
+ reset_timer_masked();
+ else /* else, set advancing stamp wake up time */
+ tmo += tmp;
+ while (get_timer_masked() < tmo) /* loop till event */
+ /*NOP*/;
+}
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index fab39eb..c6e9e6e 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -1,5 +1,6 @@
/*
- * Copyright 2008-2009 Freescale Semiconductor, Inc.
+ * Copyright 2007, Freescale Semiconductor, Inc
+ * Andy Fleming
*
* Based vaguely on the pxa mmc code:
* (C) Copyright 2003
@@ -24,18 +25,7 @@
* MA 02111-1307 USA
*/
-/*!
- * @file esdhc.c
- *
- * @brief source code for the mmc card operation
- *
- * @ingroup mmc
- */
-
#include <config.h>
-#include <asm/arch/sdhc.h>
-#include <linux/mmc/sdhci.h>
-#include <asm/errno.h>
#include <common.h>
#include <command.h>
#include <hwconfig.h>
@@ -45,9 +35,9 @@
#include <mmc.h>
#include <fsl_esdhc.h>
#include <fdt_support.h>
-#include <linux/types.h>
#include <asm/io.h>
+
DECLARE_GLOBAL_DATA_PTR;
struct fsl_esdhc {
@@ -77,41 +67,6 @@ struct fsl_esdhc {
uint scr;
};
-#define RETRIES_TIMES 100
-
-#define REG_WRITE_OR(val, reg) { \
- u32 temp = 0; \
- temp = readl(reg); \
- (temp) |= (val); \
- writel((temp), (reg)); \
- }
-
-#define REG_WRITE_AND(val, reg) { \
- u32 temp = 0; \
- temp = readl(reg); \
- (temp) &= (val); \
- writel((temp), (reg)); \
- }
-
-#define SDHC_DELAY_BY_100(x) { \
- u32 i; \
- for (i = 0; i < x; ++i) \
- udelay(100); \
- }
-
-extern volatile u32 esdhc_base_pointer;
-
-static void esdhc_cmd_config(esdhc_cmd_t *);
-static u32 esdhc_check_response(void);
-static u32 esdhc_wait_buf_rdy_intr(u32, u32);
-static void esdhc_wait_op_done_intr(void);
-static u32 esdhc_check_data(void);
-static void esdhc_set_data_transfer_width(u32 data_transfer_width);
-static u32 esdhc_poll_cihb_cdihb(data_present_select data_present);
-static void esdhc_set_endianness(u32 endian_mode);
-static void esdhc_clear_buf_rdy_intr(u32 mask);
-static u32 esdhc_check_data_crc_status(void);
-
/* Return the XFERTYP flags for a given command and data packet */
uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
{
@@ -119,9 +74,12 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
if (data) {
xfertyp |= XFERTYP_DPSEL | XFERTYP_DMAEN;
+
if (data->blocks > 1) {
xfertyp |= XFERTYP_MSBSEL;
xfertyp |= XFERTYP_BCEN;
+ }
+
if (data->flags & MMC_DATA_READ)
xfertyp |= XFERTYP_DTDSEL;
}
@@ -140,30 +98,20 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
}
-/*!
- * Send 80 SD clock to card and wait for INITA bit to get cleared.
- */
-void interface_initialization_active(void)
-{
- /* Send 80 clock ticks for card to power up */
- REG_WRITE_OR(ESDHC_SYSCTL_INITA, \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
-
- /* Start a general purpose timer */
- udelay(ESDHC_CARD_INIT_TIMEOUT);
-}
-
static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
{
uint wml_value;
int timeout;
struct fsl_esdhc *regs = mmc->priv;
+
wml_value = data->blocksize/4;
if (data->flags & MMC_DATA_READ) {
if (wml_value > 0x10)
wml_value = 0x10;
+
wml_value = 0x100000 | wml_value;
+
out_be32(&regs->dsaddr, (u32)data->dest);
} else {
if (wml_value > 0x80)
@@ -177,127 +125,24 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
}
out_be32(&regs->wml, wml_value);
+
out_be32(&regs->blkattr, data->blocks << 16 | data->blocksize);
+
/* Calculate the timeout period for data transactions */
timeout = __ilog2(mmc->tran_speed/10);
timeout -= 13;
+
if (timeout > 14)
timeout = 14;
+
if (timeout < 0)
timeout = 0;
- clrsetbits_be32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16);
- return 0;
-}
-
-/*!
- * Execute a software reset and set data bus width for eSDHC.
- */
-u32 interface_reset(void)
-{
- u32 reset_status = 0;
- u32 u32Retries = 0;
- u32 u32Temp = 0;
-
- debug("Entry: interface_reset");
-
- /* Reset the entire host controller by writing
- 1 to RSTA bit of SYSCTRL Register */
- REG_WRITE_OR(ESDHC_SOFTWARE_RESET, \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
-
- /* Start a general purpose timer (3 millsec delay) */
- /* udelay(ESDHC_OPER_TIMEOUT); */
-
- /* Wait for clearance of CIHB and CDIHB Bits */
- for (u32Retries = RETRIES_TIMES; u32Retries > 0; --u32Retries) {
- if (readl(esdhc_base_pointer + SDHCI_SYSTEM_CONTROL) \
- & ESDHC_SOFTWARE_RESET) {
- reset_status = 1;
- } else {
- reset_status = 0;
- break;
- }
- }
-
- /* Set data bus width of ESDCH */
- esdhc_set_data_transfer_width(0x00000000);
- /* Set Endianness of ESDHC */
- esdhc_set_endianness(0x00000020);
-
- /* set data timeout delay to max */
- u32Temp = (readl(esdhc_base_pointer + SDHCI_SYSTEM_CONTROL) & \
- 0xfff0ffff) | 0x000e0000;
- writel(u32Temp, esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
- return reset_status;
-}
+ clrsetbits_be32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16);
-/*!
- * Clear interrupts at eSDHC level.
- */
-void interface_clear_interrupt(void)
-{
- /* Clear Interrupt status register */
- writel(ESDHC_CLEAR_INTERRUPT, esdhc_base_pointer + SDHCI_INT_STATUS);
+ return 0;
}
-/*!
- * Enable Clock and set operating frequency.
- */
-void interface_configure_clock(sdhc_freq_t frequency)
-{
- u32 ident_freq = 0;
- u32 oper_freq = 0;
-
- /* Clear SDCLKEN bit */
- REG_WRITE_OR((~ESDHC_SYSCTL_SDCLKEN_MASK), \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
-
- /* Clear DTOCV, SDCLKFS, DVFS bits */
- REG_WRITE_OR((~ESDHC_SYSCTL_FREQ_MASK), \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
- ident_freq = ESDHC_SYSCTL_IDENT_FREQ_TO2;
- oper_freq = ESDHC_SYSCTL_OPERT_FREQ_TO2;
-
- /* Disable the PEREN, HCKEN and IPGEN */
- REG_WRITE_OR((~ESDHC_SYSCTL_INPUT_CLOCK_MASK), \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
-
- if (frequency == IDENTIFICATION_FREQ) {
- /* Input frequecy to eSDHC is 36 MHZ */
- /* PLL3 is the source of input frequency*/
- /*Set DTOCV and SDCLKFS bit to get SD_CLK
- of frequency below 400 KHZ (70.31 KHZ) */
- REG_WRITE_OR(ident_freq, \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
- } else if (frequency == OPERATING_FREQ) {
- /*Set DTOCV and SDCLKFS bit to get SD_CLK
- of frequency around 25 MHz.(18 MHz)*/
- REG_WRITE_OR(oper_freq, \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
- }
-
- /* Start a general purpose timer */
- /* Wait for clock to be stable */
- SDHC_DELAY_BY_100(96);
-
- /* Set SDCLKEN bit to enable clock */
- REG_WRITE_OR(ESDHC_SYSCTL_SDCLKEN_MASK, \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
-
- /* Mask Data Timeout Error Status Enable Interrupt (DTOESEN) */
- REG_WRITE_AND((~ESDHC_IRQSTATEN_DTOESEN), \
- esdhc_base_pointer + SDHCI_INT_ENABLE);
-
- /* Set the Data Timeout Counter Value(DTOCV) */
- REG_WRITE_OR(ESDHC_SYSCTL_DTOCV_VAL, \
- esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
-
- /* Enable Data Timeout Error Status
- Enable Interrupt (DTOESEN) */
- REG_WRITE_OR(ESDHC_IRQSTATEN_DTOESEN, \
- esdhc_base_pointer + SDHCI_INT_ENABLE);
-}
/*
* Sends a command out on the bus. Takes the mmc pointer,
@@ -309,18 +154,24 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
uint xfertyp;
uint irqstat;
volatile struct fsl_esdhc *regs = mmc->priv;
+
out_be32(&regs->irqstat, -1);
+
sync();
+
/* Wait for the bus to be idle */
while ((in_be32(&regs->prsstat) & PRSSTAT_CICHB) ||
(in_be32(&regs->prsstat) & PRSSTAT_CIDHB));
+
while (in_be32(&regs->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) {
int err;
@@ -329,23 +180,30 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
if(err)
return err;
}
+
/* Figure out the transfer arguments */
xfertyp = esdhc_xfertyp(cmd, data);
+
/* Send the command */
out_be32(&regs->cmdarg, cmd->cmdarg);
out_be32(&regs->xfertyp, xfertyp);
+
/* Wait for the command to complete */
while (!(in_be32(&regs->irqstat) & IRQSTAT_CC));
irqstat = in_be32(&regs->irqstat);
out_be32(&regs->irqstat, irqstat);
+
if (irqstat & CMD_ERR)
return COMM_ERR;
+
if (irqstat & IRQSTAT_CTOE)
return TIMEOUT;
+
/* Copy the response to the response buffer */
if (cmd->resp_type & MMC_RSP_136) {
u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
+
cmdrsp3 = in_be32(&regs->cmdrsp3);
cmdrsp2 = in_be32(&regs->cmdrsp2);
cmdrsp1 = in_be32(&regs->cmdrsp1);
@@ -356,12 +214,15 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
cmd->response[3] = (cmdrsp0 << 8);
} else
cmd->response[0] = in_be32(&regs->cmdrsp0);
+
/* Wait until all of the blocks are transferred */
if (data) {
do {
irqstat = in_be32(&regs->irqstat);
+
if (irqstat & DATA_ERR)
return COMM_ERR;
+
if (irqstat & IRQSTAT_DTOE)
return TIMEOUT;
} while (!(irqstat & IRQSTAT_TC) &&
@@ -369,128 +230,10 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
}
out_be32(&regs->irqstat, -1);
- return 0;
-}
-
-/*!
- * Set data transfer width for e-SDHC.
- */
-static void esdhc_set_data_transfer_width(u32 data_transfer_width)
-{
- /* Set DWT bit of protocol control register according to bus_width */
- REG_WRITE_AND((~ESDHC_BUS_WIDTH_MASK), \
- esdhc_base_pointer + SDHCI_HOST_CONTROL);
-
- REG_WRITE_OR((data_transfer_width), \
- esdhc_base_pointer + SDHCI_HOST_CONTROL);
-}
-
-/*!
- * Set endianness mode for e-SDHC.
- */
-static void esdhc_set_endianness(u32 endian_mode)
-{
- REG_WRITE_AND((~ESDHC_ENDIAN_MODE_MASK), \
- esdhc_base_pointer + SDHCI_HOST_CONTROL);
- /* Set DWT bit of protocol control register according to bus_width */
- REG_WRITE_OR((endian_mode), \
- esdhc_base_pointer + SDHCI_HOST_CONTROL);
-}
-
-/*!
- * Poll the CIHB & CDIHB bits of the present
- * state register and wait until it goes low.
- */
-static u32 esdhc_poll_cihb_cdihb(data_present_select data_present)
-{
- u32 init_status = 0;
- u32 u32Retries = 0;
-
- /* Start a general purpose timer */
- for (u32Retries = RETRIES_TIMES; u32Retries > 0; u32Retries--) {
- if (!(readl(esdhc_base_pointer + SDHCI_PRESENT_STATE) & \
- ESDHC_PRESENT_STATE_CIHB)) {
- init_status = 0;
- break;
- }
- SDHC_DELAY_BY_100(10);
- }
-
- /*
- * Wait for the data line to be free (poll the CDIHB bit of
- * the present state register).
- */
- if ((0 == init_status) && (data_present == DATA_PRESENT)) {
- /* Start a general purpose timer */
- SDHC_DELAY_BY_100(32);
-
- if (readl(esdhc_base_pointer + SDHCI_PRESENT_STATE) & \
- ESDHC_PRESENT_STATE_CDIHB) {
- init_status = 1;
- }
- }
-
- return init_status;
-}
-
-/*!
- * Wait until the command and data lines are free.
- */
-u32 interface_wait_cmd_data_lines(data_present_select data_present)
-{
- u32 cmd_status = 0;
-
- cmd_status = esdhc_poll_cihb_cdihb(data_present);
-
- return cmd_status;
-}
-
-u32 interface_set_bus_width(u32 bus_width)
-{
- u32 tmp;
-
- tmp = readl(esdhc_base_pointer + SDHCI_HOST_CONTROL);
- tmp &= ~SDHCI_CTRL_8BITBUS;
- tmp |= SDHCI_CTRL_4BITBUS;
-
- writel(tmp, esdhc_base_pointer + SDHCI_HOST_CONTROL);
return 0;
}
-/*!
- * Execute a command and wait for the response.
- */
-u32 interface_send_cmd_wait_resp(esdhc_cmd_t *cmd)
-{
- u32 cmd_status = 0;
-
- /* Clear Interrupt status register */
- writel(ESDHC_CLEAR_INTERRUPT, \
- esdhc_base_pointer + SDHCI_INT_STATUS);
-
- /* Enable Interrupt */
- REG_WRITE_OR(ESDHC_INTERRUPT_ENABLE, \
- esdhc_base_pointer + SDHCI_INT_ENABLE);
-
- cmd_status = interface_wait_cmd_data_lines(cmd->data_present);
-
- if (cmd_status == 1)
- return 1;
-
- /* Configure Command */
- esdhc_cmd_config(cmd);
-
- /* Wait for interrupt CTOE or CC */
- SDHC_DELAY_BY_100(96);
-
- /* Mask all interrupts */
- writel(0, esdhc_base_pointer + SDHCI_SIGNAL_ENABLE);
-
- /* Check if an error occured */
- return esdhc_check_response();
-}
-
void set_sysctl(struct mmc *mmc, uint clock)
{
int sdhc_clk = gd->sdhc_clk;
@@ -504,176 +247,39 @@ void set_sysctl(struct mmc *mmc, uint clock)
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);
- clrsetbits_be32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
- udelay(10000);
- setbits_be32(&regs->sysctl, SYSCTL_PEREN);
-}
-/*!
- * Configure ESDHC registers for sending a command to MMC.
- */
-static void esdhc_cmd_config(esdhc_cmd_t *cmd)
-{
- u32 u32Temp = 0;
-
- /* Write Command Argument in Command Argument Register */
- writel(cmd->arg, esdhc_base_pointer + SDHCI_ARGUMENT);
-
- /*
- *Configure e-SDHC Register value according to Command
- */
- u32Temp = \
- (((cmd->data_transfer)<<ESDHC_DATA_TRANSFER_SHIFT) |
- ((cmd->response_format)<<ESDHC_RESPONSE_FORMAT_SHIFT) |
- ((cmd->data_present)<<ESDHC_DATA_PRESENT_SHIFT) |
- ((cmd->crc_check) << ESDHC_CRC_CHECK_SHIFT) |
- ((cmd->cmdindex_check) << ESDHC_CMD_INDEX_CHECK_SHIFT) |
- ((cmd->command) << ESDHC_CMD_INDEX_SHIFT) |
- ((cmd->block_count_enable_check) << \
- ESDHC_BLOCK_COUNT_ENABLE_SHIFT) |
- ((cmd->multi_single_block) << \
- ESDHC_MULTI_SINGLE_BLOCK_SELECT_SHIFT));
-
- writel(u32Temp, esdhc_base_pointer + SDHCI_TRANSFER_MODE);
-}
-
-/*!
- * Wait a END_CMD_RESP interrupt by interrupt status register.
- * e-SDHC sets this bit after receving command response.
- */
-static u32 esdhc_check_response(void)
-{
- u32 status = 1;
-
- /* Check whether the interrupt is an END_CMD_RESP
- * or a response time out or a CRC error
- */
- if ((readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_END_CMD_RESP_MSK) &&
- !(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_TIME_OUT_RESP_MSK) &&
- !(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_RESP_CRC_ERR_MSK) &&
- !(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_RESP_CMD_INDEX_ERR_MSK))
- status = 0;
-
- return status;
-}
-
-/*!
- * This function will read response from e-SDHC
- * register according to reponse format.
- */
-void interface_read_response(esdhc_resp_t *cmd_resp)
-{
- /* get response values from e-SDHC CMDRSP registers.*/
- cmd_resp->cmd_rsp0 = (u32)readl(esdhc_base_pointer + SDHCI_RESPONSE);
- cmd_resp->cmd_rsp1 = (u32)readl(esdhc_base_pointer + \
- SDHCI_RESPONSE + 4);
- cmd_resp->cmd_rsp2 = (u32)readl(esdhc_base_pointer + \
- SDHCI_RESPONSE + 8);
- cmd_resp->cmd_rsp3 = (u32)readl(esdhc_base_pointer + \
- SDHCI_RESPONSE + 12);
-}
-
-/*!
- * This function will read response from e-SDHC register
- * according to reponse format.
- */
-u32 interface_data_read(u32 *dest_ptr, u32 blk_len)
-{
- u32 i = 0;
- u32 j = 0;
- u32 status = 1;
- u32 *tmp_ptr = dest_ptr;
-
- debug("Entry: interface_data_read()\n");
-
- /* Enable Interrupt */
- REG_WRITE_OR(ESDHC_INTERRUPT_ENABLE, \
- esdhc_base_pointer + SDHCI_INT_ENABLE);
-
- for (i = 0; i < (blk_len) / (ESDHC_FIFO_SIZE * 4); ++i) {
- /* Wait for BRR bit to be set */
- status = esdhc_wait_buf_rdy_intr(ESDHC_STATUS_BUF_READ_RDY_MSK,
- ESDHC_READ_DATA_TIME_OUT);
-
- debug("esdhc_wait_buf_rdy_intr: %d\n", status);
-
- if (!status) {
- for (j = 0; j < ESDHC_FIFO_SIZE; ++j) {
- *tmp_ptr++ = \
- readl(esdhc_base_pointer + SDHCI_BUFFER);
- }
- /* Clear the BRR */
- esdhc_clear_buf_rdy_intr(ESDHC_STATUS_BUF_READ_RDY_MSK);
- } else {
- debug("esdhc_wait_buf_rdy_intr failed\n");
- break;
- }
- }
-
- esdhc_wait_op_done_intr();
-
- status = esdhc_check_data();
+ clk = (pre_div << 8) | (div << 4);
- if (!status)
- status = 0;
+ clrsetbits_be32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
- debug("esdhc_check_data: %d\n", status);
- debug("Exit: interface_data_read()\n");
+ udelay(10000);
- return status;
+ setbits_be32(&regs->sysctl, SYSCTL_PEREN);
}
static void esdhc_set_ios(struct mmc *mmc)
{
struct fsl_esdhc *regs = mmc->priv;
+
/* Set the clock speed */
set_sysctl(mmc, mmc->clock);
+
/* Set the bus width */
clrbits_be32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
+
if (mmc->bus_width == 4)
setbits_be32(&regs->proctl, PROCTL_DTW_4);
else if (mmc->bus_width == 8)
setbits_be32(&regs->proctl, PROCTL_DTW_8);
}
-/*!
- * Wait a BUF_READ_READY interrupt by pooling STATUS register.
- */
-static u32 esdhc_wait_buf_rdy_intr(u32 mask, u32 multi_single_block)
-{
- u32 status = 0;
- u32 u32Retries = 0;
-
- /* Wait interrupt (BUF_READ_RDY)
- */
-
- for (u32Retries = RETRIES_TIMES; u32Retries > 0; --u32Retries) {
- if (!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & mask)) {
- status = 1;
- } else {
- status = 0;
- break;
- }
- SDHC_DELAY_BY_100(10);
- }
-
- if (multi_single_block == MULTIPLE && \
- readl(esdhc_base_pointer + SDHCI_INT_STATUS) & mask)
- REG_WRITE_OR(mask, (esdhc_base_pointer + SDHCI_INT_STATUS));
-
- return status;
-}
-
static int esdhc_init(struct mmc *mmc)
{
struct fsl_esdhc *regs = mmc->priv;
@@ -681,90 +287,25 @@ static int esdhc_init(struct mmc *mmc)
/* Enable cache snooping */
out_be32(&regs->scr, 0x00000040);
+
out_be32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
+
/* Set the initial clock speed */
set_sysctl(mmc, 400000);
+
/* Disable the BRR and BWR bits in IRQSTAT */
clrbits_be32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
+
/* Put the PROCTL reg back to the default */
out_be32(&regs->proctl, PROCTL_INIT);
+
while (!(in_be32(&regs->prsstat) & PRSSTAT_CINS) && --timeout)
udelay(1000);
+
if (timeout <= 0)
return NO_CARD_ERR;
- return 0;
-}
-/*!
- * Clear BUF_READ_READY/BUF_WRITE_READY interrupt
- * by writing 1 to STATUS register.
- */
-static void esdhc_clear_buf_rdy_intr(u32 mask)
-{
- writel(mask, (esdhc_base_pointer + SDHCI_INT_STATUS));
-}
-
-/*!
- * Wait for TC, DEBE, DCE or DTOE by polling Interrupt STATUS register.
- */
-static void esdhc_wait_op_done_intr(void)
-{
- while (!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_TRANSFER_COMPLETE_MSK))
- ;
-}
-
-/*!
- * If READ_OP_DONE occured check ESDHC_STATUS_TIME_OUT_READ
- * and RD_CRC_ERR_CODE and
- * to determine if an error occured
- */
-static u32 esdhc_check_data(void)
-{
- u32 status = 1;
-
- debug("Entry: esdhc_check_data()\n");
-
- /* Check whether the interrupt is an OP_DONE
- * or a data time out or a CRC error
- */
- if ((readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_TRANSFER_COMPLETE_MSK) &&
- !(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_TIME_OUT_READ_MASK) &&
- !(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_READ_CRC_ERR_MSK)) {
- writel(ESDHC_STATUS_TRANSFER_COMPLETE_MSK, \
- (esdhc_base_pointer + SDHCI_INT_STATUS));
- status = 0;
- } else {
- status = 1;
- }
-
- debug("Exit: esdhc_check_data()\n");
- return status;
-}
-/*!
- * Check for Data timeout error, data CRC error and data end bit error
- * to determine if an error occured.
- */
-static u32 esdhc_check_data_crc_status(void)
-{
- u32 status = 1;
-
- /* Check whether the interrupt is DTOE/DCE/DEBE */
- if (!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_TIME_OUT_READ_MASK) &&
- !(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_READ_CRC_ERR_MSK) &&
- !(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
- ESDHC_STATUS_RW_DATA_END_BIT_ERR_MSK)) {
- status = 0;
- } else {
- status = 1;
- }
-
- return status;
+ return 0;
}
static int esdhc_initialize(bd_t *bis)
@@ -772,75 +313,35 @@ static int esdhc_initialize(bd_t *bis)
struct fsl_esdhc *regs = (struct fsl_esdhc *)CONFIG_SYS_FSL_ESDHC_ADDR;
struct mmc *mmc;
u32 caps;
+
mmc = malloc(sizeof(struct mmc));
+
sprintf(mmc->name, "FSL_ESDHC");
mmc->priv = regs;
mmc->send_cmd = esdhc_send_cmd;
mmc->set_ios = esdhc_set_ios;
mmc->init = esdhc_init;
+
caps = regs->hostcapblt;
+
if (caps & ESDHC_HOSTCAPBLT_VS18)
mmc->voltages |= MMC_VDD_165_195;
if (caps & ESDHC_HOSTCAPBLT_VS30)
mmc->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
if (caps & ESDHC_HOSTCAPBLT_VS33)
mmc->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
+
mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
+
if (caps & ESDHC_HOSTCAPBLT_HSS)
mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+
mmc->f_min = 400000;
mmc->f_max = MIN(gd->sdhc_clk, 50000000);
- mmc_register(mmc);
- return 0;
-}
-
-/*!
- * Set Block length.
- */
-void interface_config_block_info(u32 blk_len, u32 nob, u32 wml)
-{
- /* Configre block Attributes register */
- writel(((nob << ESDHC_BLOCK_SHIFT) | blk_len), \
- (esdhc_base_pointer + SDHCI_BLOCK_SIZE));
- /* Set Read Water MArk Level register */
- writel(wml, esdhc_base_pointer + SDHCI_WML_LEV);
-}
-/*!
- * This function will write data to device attached to interface.
- */
-u32 interface_data_write(u32 *dest_ptr, u32 blk_len)
-{
- u32 i = 0;
- u32 j = 0;
- u32 status = 1;
- u32 *tmp_ptr = dest_ptr;
-
- debug("Entry: interface_data_write()\n");
-
- /* Enable Interrupt */
- REG_WRITE_OR(ESDHC_INTERRUPT_ENABLE, \
- (esdhc_base_pointer + SDHCI_INT_ENABLE));
-
- for (i = 0; i < (blk_len) / (ESDHC_FIFO_SIZE * 4); ++i) {
- /* Wait for BWR bit to be set */
- esdhc_wait_buf_rdy_intr(ESDHC_STATUS_BUF_WRITE_RDY_MSK, \
- SINGLE);
- for (j = 0; j < ESDHC_FIFO_SIZE; ++j) {
- writel((*tmp_ptr), esdhc_base_pointer + SDHCI_BUFFER);
- ++tmp_ptr;
- }
- esdhc_clear_buf_rdy_intr(ESDHC_STATUS_BUF_WRITE_RDY_MSK);
- }
-
- /* Wait for transfer complete operation interrupt */
- esdhc_wait_op_done_intr();
-
- /* Check for status errors */
- status = esdhc_check_data();
+ mmc_register(mmc);
- debug("Exit: interface_data_write()\n");
- return status;
+ return 0;
}
int fsl_esdhc_mmc_init(bd_t *bis)
@@ -852,48 +353,15 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd)
{
const char *compat = "fsl,esdhc";
const char *status = "okay";
+
if (!hwconfig("esdhc")) {
status = "disabled";
goto out;
}
+
do_fixup_by_compat_u32(blob, compat, "clock-frequency",
gd->sdhc_clk, 1);
out:
do_fixup_by_compat(blob, compat, "status", status,
strlen(status) + 1, 1);
}
-
-/*!
- * Configure the CMD line PAD configuration for strong or weak pull-up.
- */
-/*
-void esdhc_set_cmd_pullup(esdhc_pullup_t pull_up)
-{
- u32 interface_esdhc = 0;
- u32 pad_val = 0;
-
- interface_esdhc = (readl(0x53ff080c)) & (0x000000C0) >> 6;
-
- if (pull_up == STRONG) {
- pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
- PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_HIGH |
- PAD_CTL_22K_PU | PAD_CTL_SRE_FAST;
- } else {
- pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
- PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
- PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
- }
-
- switch (interface_esdhc) {
- case ESDHC1:
- mxc_iomux_set_pad(MX51_PIN_SD1_CMD, pad_val);
- break;
- case ESDHC2:
- mxc_iomux_set_pad(MX51_PIN_SD2_CMD, pad_val);
- break;
- case ESDHC3:
- default:
- break;
- }
-}
-*/
diff --git a/drivers/net/mxc_fec.c b/drivers/net/mxc_fec.c
index 91d248b..dcfc263 100644
--- a/drivers/net/mxc_fec.c
+++ b/drivers/net/mxc_fec.c
@@ -622,10 +622,10 @@ int fec_init(struct eth_device *dev, bd_t *bd)
if (info->phy_addr < 0 || info->phy_addr > 0x1F)
info->phy_addr = mxc_fec_mii_discover_phy(dev);
#endif
- setFecDuplexSpeed(fecp, (unsigned char)bd, info->dup_spd);
+ setFecDuplexSpeed(fecp, (unsigned char)info->phy_addr, info->dup_spd);
#else
#ifndef CONFIG_DISCOVER_PHY
- setFecDuplexSpeed(fecp, (unsigned char)bd,
+ setFecDuplexSpeed(fecp, (unsigned char)info->phy_addr,
(FECDUPLEX << 16) | FECSPEED);
#endif /* ifndef CONFIG_SYS_DISCOVER_PHY */
#endif /* CONFIG_CMD_MII || CONFIG_MII */
diff --git a/include/configs/imx51.h b/include/configs/imx51.h
index 23347d1..e5ae114 100644
--- a/include/configs/imx51.h
+++ b/include/configs/imx51.h
@@ -28,7 +28,6 @@
/* High Level Configuration Options */
#define CONFIG_ARMV7 1 /* This is armv7 Cortex-A8 CPU core */
-#define CONFIG_SYS_APCS_GNU
#define CONFIG_L2_OFF
#define CONFIG_MXC 1
@@ -85,13 +84,6 @@
/*
* MMC Configs
* */
-#define CONFIG_FSL_MMC 1
-
-#define CONFIG_MMC 1
-#define CONFIG_CMD_MMC
-#define CONFIG_DOS_PARTITION 1
-#define CONFIG_CMD_FAT 1
-#define CONFIG_MMC_BASE 0x0
/*
* Eth Configs
@@ -107,11 +99,6 @@
#define CONFIG_FEC0_PHY_ADDR 0x1F
#define CONFIG_FEC0_MIIBASE -1
-#define CONFIG_CMD_PING
-#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_MII
-#define CONFIG_CMD_NET
-
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_CONS_INDEX 1
@@ -126,9 +113,11 @@
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NET
+
/* Enable below configure when supporting nand */
-/* #define CONFIG_CMD_NAND */
-/* #define CONFIG_CMD_ENV */
+#define CONFIG_CMD_ENV
#undef CONFIG_CMD_IMLS
@@ -144,25 +133,13 @@
"uboot_addr=0xa0000000\0" \
"uboot=u-boot.bin\0" \
"kernel=uImage\0" \
- "nfsroot=/opt/eldk/arm\0" \
"bootargs_base=setenv bootargs console=ttymxc0,115200\0"\
"bootargs_nfs=setenv bootargs ${bootargs} root=/dev/nfs "\
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0"\
"bootcmd=run bootcmd_net\0" \
"bootcmd_net=run bootargs_base bootargs_nfs; " \
"tftpboot ${loadaddr} ${kernel}; bootm\0" \
- "prg_uboot=tftpboot ${loadaddr} ${uboot}; " \
- "protect off ${uboot_addr} 0xa003ffff; " \
- "erase ${uboot_addr} 0xa003ffff; " \
- "cp.b ${loadaddr} ${uboot_addr} ${filesize}; " \
- "setenv filesize; saveenv\0"
-
-/*Support LAN9217*/
-/*
-#define CONFIG_DRIVER_SMC911X 1
-#define CONFIG_DRIVER_SMC911X_16_BIT 1
-#define CONFIG_DRIVER_SMC911X_BASE_VARIABLE mx51_io_base_addr
-*/
+ "load_uboot=tftpboot ${loadaddr} ${uboot}\0" \
/*
* The MX51 3stack board seems to have a hardware "peculiarity" confirmed under
@@ -247,6 +224,7 @@
#define CONFIG_ENV_OFFSET (768 * 1024)
#elif defined(CONFIG_FSL_ENV_IN_SF)
#define CONFIG_ENV_IS_IN_SPI_FLASH 1
+ #define CONFIG_ENV_IS_EMBEDDED 1
#define CONFIG_ENV_SPI_CS 1
#define CONFIG_ENV_OFFSET (768 * 1024)
#else