summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ahci.c7
-rw-r--r--drivers/block/sata_sil3114.c4
-rw-r--r--drivers/i2c/mxc_i2c.c6
-rw-r--r--drivers/misc/fsl_law.c3
-rw-r--r--drivers/mmc/Makefile2
-rw-r--r--drivers/mmc/atmel_mci.c17
-rw-r--r--drivers/mmc/fsl_esdhc.c348
-rw-r--r--drivers/mmc/mmc.c930
-rw-r--r--drivers/mtd/cfi_flash.c57
-rw-r--r--drivers/mtd/jedec_flash.c16
-rw-r--r--drivers/mtd/nand/nand.c4
-rw-r--r--drivers/mtd/nand/nand_base.c21
-rw-r--r--drivers/net/mcfmii.c27
-rw-r--r--drivers/net/mpc5xxx_fec.c28
-rw-r--r--drivers/net/sh_eth.h2
-rw-r--r--drivers/net/tsec.c1
-rw-r--r--drivers/pci/fsl_pci_init.c10
-rw-r--r--drivers/pci/pci.c121
-rw-r--r--drivers/pci/pci_ixp.c2
-rw-r--r--drivers/pci/tsi108_pci.c2
-rw-r--r--drivers/pcmcia/Makefile2
-rw-r--r--drivers/pcmcia/mpc8xx_pcmcia.c6
-rw-r--r--drivers/serial/mcfuart.c5
-rw-r--r--drivers/serial/ns16550.c4
-rw-r--r--drivers/serial/usbtty.c18
-rw-r--r--drivers/usb/davinci_usb.h1
-rw-r--r--drivers/usb/musb_core.h1
-rw-r--r--drivers/usb/usb_ehci_core.c6
-rw-r--r--drivers/usb/usb_ohci.c2
-rw-r--r--drivers/video/mb862xx.c2
-rw-r--r--drivers/video/smiLynxEM.c2
31 files changed, 1504 insertions, 153 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index 2445e8c..e1b66fd 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -251,7 +251,6 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
static int ahci_init_one(pci_dev_t pdev)
{
- u32 iobase;
u16 vendor;
int rc;
@@ -261,9 +260,6 @@ static int ahci_init_one(pci_dev_t pdev)
memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
probe_ent->dev = pdev;
- pci_read_config_dword(pdev, AHCI_PCI_BAR, &iobase);
- iobase &= ~0xf;
-
probe_ent->host_flags = ATA_FLAG_SATA
| ATA_FLAG_NO_LEGACY
| ATA_FLAG_MMIO
@@ -272,7 +268,8 @@ static int ahci_init_one(pci_dev_t pdev)
probe_ent->pio_mask = 0x1f;
probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
- probe_ent->mmio_base = iobase;
+ probe_ent->mmio_base = (u32)pci_map_bar(pdev, AHCI_PCI_BAR,
+ PCI_REGION_MEM);
/* Take from kernel:
* JMicron-specific fixup:
diff --git a/drivers/block/sata_sil3114.c b/drivers/block/sata_sil3114.c
index 351cf99..62cc99d 100644
--- a/drivers/block/sata_sil3114.c
+++ b/drivers/block/sata_sil3114.c
@@ -96,7 +96,7 @@ static int sata_bus_softreset (int num)
}
if (status & ATA_BUSY) {
- printf ("ata%u is slow to respond,plz be patient\n", port);
+ printf ("ata%u is slow to respond,plz be patient\n", num);
}
while ((status & ATA_BUSY)) {
@@ -105,7 +105,7 @@ static int sata_bus_softreset (int num)
}
if (status & ATA_BUSY) {
- printf ("ata%u failed to respond : ", port);
+ printf ("ata%u failed to respond : ", num);
printf ("bus reset failed\n");
port[num].dev_mask = 0;
return 1;
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index eedad06..8e10fbb 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -49,10 +49,13 @@
#ifdef CONFIG_SYS_I2C_MX31_PORT1
#define I2C_BASE 0x43f80000
+#define I2C_CLK_OFFSET 26
#elif defined (CONFIG_SYS_I2C_MX31_PORT2)
#define I2C_BASE 0x43f98000
+#define I2C_CLK_OFFSET 28
#elif defined (CONFIG_SYS_I2C_MX31_PORT3)
#define I2C_BASE 0x43f84000
+#define I2C_CLK_OFFSET 30
#else
#error "define CONFIG_SYS_I2C_MX31_PORTx to use the mx31 I2C driver"
#endif
@@ -72,6 +75,9 @@ void i2c_init(int speed, int unused)
int freq = mx31_get_ipg_clk();
int i;
+ /* start the required I2C clock */
+ __REG(CCM_CGR0) = __REG(CCM_CGR0) | (3 << I2C_CLK_OFFSET);
+
for (i = 0; i < 0x1f; i++)
if (freq / div[i] <= speed)
break;
diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c
index 44c9e91..58340c1 100644
--- a/drivers/misc/fsl_law.c
+++ b/drivers/misc/fsl_law.c
@@ -38,7 +38,8 @@ DECLARE_GLOBAL_DATA_PTR;
defined(CONFIG_MPC8568) || \
defined(CONFIG_MPC8641) || defined(CONFIG_MPC8610)
#define FSL_HW_NUM_LAWS 10
-#elif defined(CONFIG_MPC8536) || defined(CONFIG_MPC8572)
+#elif defined(CONFIG_MPC8536) || defined(CONFIG_MPC8572) || \
+ defined(CONFIG_P2020)
#define FSL_HW_NUM_LAWS 12
#else
#error FSL_HW_NUM_LAWS not defined for this platform
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index d496364..6aa24f5 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -25,9 +25,11 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libmmc.a
+COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
+COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mmc/atmel_mci.c b/drivers/mmc/atmel_mci.c
index 3aa92f2..3946ffe 100644
--- a/drivers/mmc/atmel_mci.c
+++ b/drivers/mmc/atmel_mci.c
@@ -463,7 +463,7 @@ static void mci_set_data_timeout(struct mmc_csd *csd)
dtocyc << shift, dtor);
}
-int mmc_init(int verbose)
+int mmc_legacy_init(int verbose)
{
struct mmc_cid cid;
struct mmc_csd csd;
@@ -531,18 +531,3 @@ int mmc_init(int verbose)
return 0;
}
-
-int mmc_read(ulong src, uchar *dst, int size)
-{
- return -ENOSYS;
-}
-
-int mmc_write(uchar *src, ulong dst, int size)
-{
- return -ENOSYS;
-}
-
-int mmc2info(ulong addr)
-{
- return 0;
-}
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
new file mode 100644
index 0000000..0ba45cd
--- /dev/null
+++ b/drivers/mmc/fsl_esdhc.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2007, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the pxa mmc code:
+ * (C) Copyright 2003
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * 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 <config.h>
+#include <common.h>
+#include <command.h>
+#include <mmc.h>
+#include <part.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <fsl_esdhc.h>
+#include <asm/io.h>
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct fsl_esdhc {
+ uint dsaddr;
+ uint blkattr;
+ uint cmdarg;
+ uint xfertyp;
+ uint cmdrsp0;
+ uint cmdrsp1;
+ uint cmdrsp2;
+ uint cmdrsp3;
+ uint datport;
+ uint prsstat;
+ uint proctl;
+ uint sysctl;
+ uint irqstat;
+ uint irqstaten;
+ uint irqsigen;
+ uint autoc12err;
+ uint hostcapblt;
+ uint wml;
+ char reserved1[8];
+ uint fevt;
+ char reserved2[168];
+ uint hostver;
+ char reserved3[780];
+ uint scr;
+};
+
+/* Return the XFERTYP flags for a given command and data packet */
+uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
+{
+ uint xfertyp = 0;
+
+ 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;
+ }
+
+ if (cmd->resp_type & MMC_RSP_CRC)
+ xfertyp |= XFERTYP_CCCEN;
+ if (cmd->resp_type & MMC_RSP_OPCODE)
+ xfertyp |= XFERTYP_CICEN;
+ if (cmd->resp_type & MMC_RSP_136)
+ xfertyp |= XFERTYP_RSPTYP_136;
+ else if (cmd->resp_type & MMC_RSP_BUSY)
+ xfertyp |= XFERTYP_RSPTYP_48_BUSY;
+ else if (cmd->resp_type & MMC_RSP_PRESENT)
+ xfertyp |= XFERTYP_RSPTYP_48;
+
+ return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
+}
+
+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)
+ wml_value = 0x80;
+ if ((in_be32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
+ printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
+ return TIMEOUT;
+ }
+ wml_value = wml_value << 16 | 0x10;
+ out_be32(&regs->dsaddr, (u32)data->src);
+ }
+
+ 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;
+}
+
+
+/*
+ * Sends a command out on the bus. Takes the mmc pointer,
+ * a command pointer, and an optional data pointer.
+ */
+static int
+esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+{
+ 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;
+
+ err = esdhc_setup_data(mmc, 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);
+ cmdrsp0 = in_be32(&regs->cmdrsp0);
+ ((uint *)(cmd->response))[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
+ ((uint *)(cmd->response))[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
+ ((uint *)(cmd->response))[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
+ ((uint *)(cmd->response))[3] = (cmdrsp0 << 8);
+ } else
+ ((uint *)(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) &&
+ (in_be32(&regs->prsstat) & PRSSTAT_DLA));
+ }
+
+ out_be32(&regs->irqstat, -1);
+
+ return 0;
+}
+
+void set_sysctl(struct mmc *mmc, uint clock)
+{
+ int sdhc_clk = gd->sdhc_clk;
+ int div, pre_div;
+ volatile struct fsl_esdhc *regs = mmc->priv;
+ uint clk;
+
+ if (sdhc_clk / 16 > clock) {
+ for (pre_div = 2; pre_div < 256; pre_div *= 2)
+ if ((sdhc_clk / pre_div) <= (clock * 16))
+ break;
+ } else
+ pre_div = 2;
+
+ for (div = 1; div <= 16; div++)
+ if ((sdhc_clk / (div * pre_div)) <= clock)
+ break;
+
+ pre_div >>= 1;
+ div -= 1;
+
+ clk = (pre_div << 8) | (div << 4);
+
+ clrsetbits_be32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
+
+ udelay(10000);
+
+ 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);
+}
+
+static int esdhc_init(struct mmc *mmc)
+{
+ struct fsl_esdhc *regs = mmc->priv;
+ int timeout = 1000;
+
+ /* 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;
+}
+
+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;
+}
+
+int fsl_esdhc_mmc_init(bd_t *bis)
+{
+ return esdhc_initialize(bis);
+}
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
new file mode 100644
index 0000000..96186d9
--- /dev/null
+++ b/drivers/mmc/mmc.c
@@ -0,0 +1,930 @@
+/*
+ * Copyright 2008, Freescale Semiconductor, Inc
+ * Andy Fleming
+ *
+ * Based vaguely on the Linux code
+ *
+ * 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 <config.h>
+#include <common.h>
+#include <command.h>
+#include <mmc.h>
+#include <part.h>
+#include <malloc.h>
+#include <linux/list.h>
+#include <mmc.h>
+
+static struct list_head mmc_devices;
+static int cur_dev_num = -1;
+
+int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+{
+ return mmc->send_cmd(mmc, cmd, data);
+}
+
+int mmc_set_blocklen(struct mmc *mmc, int len)
+{
+ struct mmc_cmd cmd;
+
+ cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = len;
+ cmd.flags = 0;
+
+ return mmc_send_cmd(mmc, &cmd, NULL);
+}
+
+struct mmc *find_mmc_device(int dev_num)
+{
+ struct mmc *m;
+ struct list_head *entry;
+
+ list_for_each(entry, &mmc_devices) {
+ m = list_entry(entry, struct mmc, link);
+
+ if (m->block_dev.dev == dev_num)
+ return m;
+ }
+
+ printf("MMC Device %d not found\n", dev_num);
+
+ return NULL;
+}
+
+static ulong
+mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
+{
+ struct mmc_cmd cmd;
+ struct mmc_data data;
+ int err;
+ int stoperr = 0;
+ struct mmc *mmc = find_mmc_device(dev_num);
+ int blklen;
+
+ if (!mmc)
+ return -1;
+
+ blklen = mmc->write_bl_len;
+
+ err = mmc_set_blocklen(mmc, mmc->write_bl_len);
+
+ if (err) {
+ printf("set write bl len failed\n\r");
+ return err;
+ }
+
+ if (blkcnt > 1)
+ cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
+ else
+ cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
+
+ if (mmc->high_capacity)
+ cmd.cmdarg = start;
+ else
+ cmd.cmdarg = start * blklen;
+
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.flags = 0;
+
+ data.src = src;
+ data.blocks = blkcnt;
+ data.blocksize = blklen;
+ data.flags = MMC_DATA_WRITE;
+
+ err = mmc_send_cmd(mmc, &cmd, &data);
+
+ if (err) {
+ printf("mmc write failed\n\r");
+ return err;
+ }
+
+ if (blkcnt > 1) {
+ cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+ cmd.cmdarg = 0;
+ cmd.resp_type = MMC_RSP_R1b;
+ cmd.flags = 0;
+ stoperr = mmc_send_cmd(mmc, &cmd, NULL);
+ }
+
+ return blkcnt;
+}
+
+int mmc_read_block(struct mmc *mmc, void *dst, uint blocknum)
+{
+ struct mmc_cmd cmd;
+ struct mmc_data data;
+
+ cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
+
+ if (mmc->high_capacity)
+ cmd.cmdarg = blocknum;
+ else
+ cmd.cmdarg = blocknum * mmc->read_bl_len;
+
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.flags = 0;
+
+ data.dest = dst;
+ data.blocks = 1;
+ data.blocksize = mmc->read_bl_len;
+ data.flags = MMC_DATA_READ;
+
+ return mmc_send_cmd(mmc, &cmd, &data);
+}
+
+int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size)
+{
+ char *buffer;
+ int i;
+ int blklen = mmc->read_bl_len;
+ int startblock = src / blklen;
+ int endblock = (src + size - 1) / blklen;
+ int err = 0;
+
+ /* Make a buffer big enough to hold all the blocks we might read */
+ buffer = malloc(blklen);
+
+ if (!buffer) {
+ printf("Could not allocate buffer for MMC read!\n");
+ return -1;
+ }
+
+ /* We always do full block reads from the card */
+ err = mmc_set_blocklen(mmc, mmc->read_bl_len);
+
+ if (err)
+ return err;
+
+ for (i = startblock; i <= endblock; i++) {
+ int segment_size;
+ int offset;
+
+ err = mmc_read_block(mmc, buffer, i);
+
+ if (err)
+ goto free_buffer;
+
+ /*
+ * The first block may not be aligned, so we
+ * copy from the desired point in the block
+ */
+ offset = (src & (blklen - 1));
+ segment_size = MIN(blklen - offset, size);
+
+ memcpy(dst, buffer + offset, segment_size);
+
+ dst += segment_size;
+ src += segment_size;
+ size -= segment_size;
+ }
+
+free_buffer:
+ free(buffer);
+
+ return err;
+}
+
+static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
+{
+ int err;
+ int i;
+ struct mmc *mmc = find_mmc_device(dev_num);
+
+ if (!mmc)
+ return 0;
+
+ /* We always do full block reads from the card */
+ err = mmc_set_blocklen(mmc, mmc->read_bl_len);
+
+ if (err) {
+ return 0;
+ }
+
+ for (i = start; i < start + blkcnt; i++, dst += mmc->read_bl_len) {
+ err = mmc_read_block(mmc, dst, i);
+
+ if (err) {
+ printf("block read failed: %d\n", err);
+ return i - start;
+ }
+ }
+
+ return blkcnt;
+}
+
+int mmc_go_idle(struct mmc* mmc)
+{
+ struct mmc_cmd cmd;
+ int err;
+
+ udelay(1000);
+
+ cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
+ cmd.cmdarg = 0;
+ cmd.resp_type = MMC_RSP_NONE;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ udelay(2000);
+
+ return 0;
+}
+
+int
+sd_send_op_cond(struct mmc *mmc)
+{
+ int timeout = 1000;
+ int err;
+ struct mmc_cmd cmd;
+
+ do {
+ cmd.cmdidx = MMC_CMD_APP_CMD;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = 0;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ cmd.cmdidx = SD_CMD_APP_SEND_OP_COND;
+ cmd.resp_type = MMC_RSP_R3;
+ cmd.cmdarg = mmc->voltages;
+
+ if (mmc->version == SD_VERSION_2)
+ cmd.cmdarg |= OCR_HCS;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ udelay(1000);
+ } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
+
+ if (timeout <= 0)
+ return UNUSABLE_ERR;
+
+ if (mmc->version != SD_VERSION_2)
+ mmc->version = SD_VERSION_1_0;
+
+ mmc->ocr = ((uint *)(cmd.response))[0];
+
+ mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
+ mmc->rca = 0;
+
+ return 0;
+}
+
+int mmc_send_op_cond(struct mmc *mmc)
+{
+ int timeout = 1000;
+ struct mmc_cmd cmd;
+ int err;
+
+ /* Some cards seem to need this */
+ mmc_go_idle(mmc);
+
+ do {
+ cmd.cmdidx = MMC_CMD_SEND_OP_COND;
+ cmd.resp_type = MMC_RSP_R3;
+ cmd.cmdarg = OCR_HCS | mmc->voltages;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ udelay(1000);
+ } while (!(cmd.response[0] & OCR_BUSY) && timeout--);
+
+ if (timeout <= 0)
+ return UNUSABLE_ERR;
+
+ mmc->version = MMC_VERSION_UNKNOWN;
+ mmc->ocr = ((uint *)(cmd.response))[0];
+
+ mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
+ mmc->rca = 0;
+
+ return 0;
+}
+
+
+int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
+{
+ struct mmc_cmd cmd;
+ struct mmc_data data;
+ int err;
+
+ /* Get the Card Status Register */
+ cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = 0;
+ cmd.flags = 0;
+
+ data.dest = ext_csd;
+ data.blocks = 1;
+ data.blocksize = 512;
+ data.flags = MMC_DATA_READ;
+
+ err = mmc_send_cmd(mmc, &cmd, &data);
+
+ return err;
+}
+
+
+int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
+{
+ struct mmc_cmd cmd;
+
+ cmd.cmdidx = MMC_CMD_SWITCH;
+ cmd.resp_type = MMC_RSP_R1b;
+ cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (index << 16) |
+ (value << 8);
+ cmd.flags = 0;
+
+ return mmc_send_cmd(mmc, &cmd, NULL);
+}
+
+int mmc_change_freq(struct mmc *mmc)
+{
+ char ext_csd[512];
+ char cardtype;
+ int err;
+
+ mmc->card_caps = 0;
+
+ /* Only version 4 supports high-speed */
+ if (mmc->version < MMC_VERSION_4)
+ return 0;
+
+ mmc->card_caps |= MMC_MODE_4BIT;
+
+ err = mmc_send_ext_csd(mmc, ext_csd);
+
+ if (err)
+ return err;
+
+ if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
+ mmc->high_capacity = 1;
+
+ cardtype = ext_csd[196] & 0xf;
+
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
+
+ if (err)
+ return err;
+
+ /* Now check to see that it worked */
+ err = mmc_send_ext_csd(mmc, ext_csd);
+
+ if (err)
+ return err;
+
+ /* No high-speed support */
+ if (!ext_csd[185])
+ return 0;
+
+ /* High Speed is set, there are two types: 52MHz and 26MHz */
+ if (cardtype & MMC_HS_52MHZ)
+ mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+ else
+ mmc->card_caps |= MMC_MODE_HS;
+
+ return 0;
+}
+
+int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
+{
+ struct mmc_cmd cmd;
+ struct mmc_data data;
+
+ /* Switch the frequency */
+ cmd.cmdidx = SD_CMD_SWITCH_FUNC;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = (mode << 31) | 0xffffff;
+ cmd.cmdarg &= ~(0xf << (group * 4));
+ cmd.cmdarg |= value << (group * 4);
+ cmd.flags = 0;
+
+ data.dest = (char *)resp;
+ data.blocksize = 64;
+ data.blocks = 1;
+ data.flags = MMC_DATA_READ;
+
+ return mmc_send_cmd(mmc, &cmd, &data);
+}
+
+
+int sd_change_freq(struct mmc *mmc)
+{
+ int err;
+ struct mmc_cmd cmd;
+ uint scr[2];
+ uint switch_status[16];
+ struct mmc_data data;
+ int timeout;
+
+ mmc->card_caps = 0;
+
+ /* Read the SCR to find out if this card supports higher speeds */
+ cmd.cmdidx = MMC_CMD_APP_CMD;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = mmc->rca << 16;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ cmd.cmdidx = SD_CMD_APP_SEND_SCR;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = 0;
+ cmd.flags = 0;
+
+ timeout = 3;
+
+retry_scr:
+ data.dest = (char *)&scr;
+ data.blocksize = 8;
+ data.blocks = 1;
+ data.flags = MMC_DATA_READ;
+
+ err = mmc_send_cmd(mmc, &cmd, &data);
+
+ if (err) {
+ if (timeout--)
+ goto retry_scr;
+
+ return err;
+ }
+
+ mmc->scr[0] = scr[0];
+ mmc->scr[1] = scr[1];
+
+ switch ((mmc->scr[0] >> 24) & 0xf) {
+ case 0:
+ mmc->version = SD_VERSION_1_0;
+ break;
+ case 1:
+ mmc->version = SD_VERSION_1_10;
+ break;
+ case 2:
+ mmc->version = SD_VERSION_2;
+ break;
+ default:
+ mmc->version = SD_VERSION_1_0;
+ break;
+ }
+
+ /* Version 1.0 doesn't support switching */
+ if (mmc->version == SD_VERSION_1_0)
+ return 0;
+
+ timeout = 4;
+ while (timeout--) {
+ err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1,
+ (u8 *)&switch_status);
+
+ if (err)
+ return err;
+
+ /* The high-speed function is busy. Try again */
+ if (!switch_status[7] & SD_HIGHSPEED_BUSY)
+ break;
+ }
+
+ if (mmc->scr[0] & SD_DATA_4BIT)
+ mmc->card_caps |= MMC_MODE_4BIT;
+
+ /* If high-speed isn't supported, we return */
+ if (!(switch_status[3] & SD_HIGHSPEED_SUPPORTED))
+ return 0;
+
+ err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status);
+
+ if (err)
+ return err;
+
+ if ((switch_status[4] & 0x0f000000) == 0x01000000)
+ mmc->card_caps |= MMC_MODE_HS;
+
+ return 0;
+}
+
+/* frequency bases */
+/* divided by 10 to be nice to platforms without floating point */
+int fbase[] = {
+ 10000,
+ 100000,
+ 1000000,
+ 10000000,
+};
+
+/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
+ * to platforms without floating point.
+ */
+int multipliers[] = {
+ 0, /* reserved */
+ 10,
+ 12,
+ 13,
+ 15,
+ 20,
+ 25,
+ 30,
+ 35,
+ 40,
+ 45,
+ 50,
+ 55,
+ 60,
+ 70,
+ 80,
+};
+
+void mmc_set_ios(struct mmc *mmc)
+{
+ mmc->set_ios(mmc);
+}
+
+void mmc_set_clock(struct mmc *mmc, uint clock)
+{
+ if (clock > mmc->f_max)
+ clock = mmc->f_max;
+
+ if (clock < mmc->f_min)
+ clock = mmc->f_min;
+
+ mmc->clock = clock;
+
+ mmc_set_ios(mmc);
+}
+
+void mmc_set_bus_width(struct mmc *mmc, uint width)
+{
+ mmc->bus_width = width;
+
+ mmc_set_ios(mmc);
+}
+
+int mmc_startup(struct mmc *mmc)
+{
+ int err;
+ uint mult, freq;
+ u64 cmult, csize;
+ struct mmc_cmd cmd;
+
+ /* Put the Card in Identify Mode */
+ cmd.cmdidx = MMC_CMD_ALL_SEND_CID;
+ cmd.resp_type = MMC_RSP_R2;
+ cmd.cmdarg = 0;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ memcpy(mmc->cid, cmd.response, 16);
+
+ /*
+ * For MMC cards, set the Relative Address.
+ * For SD cards, get the Relatvie Address.
+ * This also puts the cards into Standby State
+ */
+ cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
+ cmd.cmdarg = mmc->rca << 16;
+ cmd.resp_type = MMC_RSP_R6;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ if (IS_SD(mmc))
+ mmc->rca = (((uint *)(cmd.response))[0] >> 16) & 0xffff;
+
+ /* Get the Card-Specific Data */
+ cmd.cmdidx = MMC_CMD_SEND_CSD;
+ cmd.resp_type = MMC_RSP_R2;
+ cmd.cmdarg = mmc->rca << 16;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ mmc->csd[0] = ((uint *)(cmd.response))[0];
+ mmc->csd[1] = ((uint *)(cmd.response))[1];
+ mmc->csd[2] = ((uint *)(cmd.response))[2];
+ mmc->csd[3] = ((uint *)(cmd.response))[3];
+
+ if (mmc->version == MMC_VERSION_UNKNOWN) {
+ int version = (cmd.response[0] >> 2) & 0xf;
+
+ switch (version) {
+ case 0:
+ mmc->version = MMC_VERSION_1_2;
+ break;
+ case 1:
+ mmc->version = MMC_VERSION_1_4;
+ break;
+ case 2:
+ mmc->version = MMC_VERSION_2_2;
+ break;
+ case 3:
+ mmc->version = MMC_VERSION_3;
+ break;
+ case 4:
+ mmc->version = MMC_VERSION_4;
+ break;
+ default:
+ mmc->version = MMC_VERSION_1_2;
+ break;
+ }
+ }
+
+ /* divide frequency by 10, since the mults are 10x bigger */
+ freq = fbase[(cmd.response[3] & 0x7)];
+ mult = multipliers[((cmd.response[3] >> 3) & 0xf)];
+
+ mmc->tran_speed = freq * mult;
+
+ mmc->read_bl_len = 1 << ((((uint *)(cmd.response))[1] >> 16) & 0xf);
+
+ if (IS_SD(mmc))
+ mmc->write_bl_len = mmc->read_bl_len;
+ else
+ mmc->write_bl_len = 1 << ((((uint *)(cmd.response))[3] >> 22) & 0xf);
+
+ if (mmc->high_capacity) {
+ csize = (mmc->csd[1] & 0x3f) << 16
+ | (mmc->csd[2] & 0xffff0000) >> 16;
+ cmult = 8;
+ } else {
+ csize = (mmc->csd[1] & 0x3ff) << 2
+ | (mmc->csd[2] & 0xc0000000) >> 30;
+ cmult = (mmc->csd[2] & 0x00038000) >> 15;
+ }
+
+ mmc->capacity = (csize + 1) << (cmult + 2);
+ mmc->capacity *= mmc->read_bl_len;
+
+ if (mmc->read_bl_len > 512)
+ mmc->read_bl_len = 512;
+
+ if (mmc->write_bl_len > 512)
+ mmc->write_bl_len = 512;
+
+ /* Select the card, and put it into Transfer Mode */
+ cmd.cmdidx = MMC_CMD_SELECT_CARD;
+ cmd.resp_type = MMC_RSP_R1b;
+ cmd.cmdarg = mmc->rca << 16;
+ cmd.flags = 0;
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ if (IS_SD(mmc))
+ err = sd_change_freq(mmc);
+ else
+ err = mmc_change_freq(mmc);
+
+ if (err)
+ return err;
+
+ /* Restrict card's capabilities by what the host can do */
+ mmc->card_caps &= mmc->host_caps;
+
+ if (IS_SD(mmc)) {
+ if (mmc->card_caps & MMC_MODE_4BIT) {
+ cmd.cmdidx = MMC_CMD_APP_CMD;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = mmc->rca << 16;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err)
+ return err;
+
+ cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = 2;
+ cmd.flags = 0;
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err)
+ return err;
+
+ mmc_set_bus_width(mmc, 4);
+ }
+
+ if (mmc->card_caps & MMC_MODE_HS)
+ mmc_set_clock(mmc, 50000000);
+ else
+ mmc_set_clock(mmc, 25000000);
+ } else {
+ if (mmc->card_caps & MMC_MODE_4BIT) {
+ /* Set the card to use 4 bit*/
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BUS_WIDTH,
+ EXT_CSD_BUS_WIDTH_4);
+
+ if (err)
+ return err;
+
+ mmc_set_bus_width(mmc, 4);
+ } else if (mmc->card_caps & MMC_MODE_8BIT) {
+ /* Set the card to use 8 bit*/
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BUS_WIDTH,
+ EXT_CSD_BUS_WIDTH_8);
+
+ if (err)
+ return err;
+
+ mmc_set_bus_width(mmc, 8);
+ }
+
+ if (mmc->card_caps & MMC_MODE_HS) {
+ if (mmc->card_caps & MMC_MODE_HS_52MHz)
+ mmc_set_clock(mmc, 52000000);
+ else
+ mmc_set_clock(mmc, 26000000);
+ } else
+ mmc_set_clock(mmc, 20000000);
+ }
+
+ /* fill in device description */
+ mmc->block_dev.lun = 0;
+ mmc->block_dev.type = 0;
+ mmc->block_dev.blksz = mmc->read_bl_len;
+ mmc->block_dev.lba = mmc->capacity/mmc->read_bl_len;
+ sprintf(mmc->block_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x%02x",
+ mmc->cid[0], mmc->cid[1], mmc->cid[2],
+ mmc->cid[9], mmc->cid[10], mmc->cid[11], mmc->cid[12]);
+ sprintf(mmc->block_dev.product,"%c%c%c%c%c", mmc->cid[3],
+ mmc->cid[4], mmc->cid[5], mmc->cid[6], mmc->cid[7]);
+ sprintf(mmc->block_dev.revision,"%d.%d", mmc->cid[8] >> 4,
+ mmc->cid[8] & 0xf);
+ init_part(&mmc->block_dev);
+
+ return 0;
+}
+
+int mmc_send_if_cond(struct mmc *mmc)
+{
+ struct mmc_cmd cmd;
+ int err;
+
+ cmd.cmdidx = SD_CMD_SEND_IF_COND;
+ /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
+ cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
+ cmd.resp_type = MMC_RSP_R7;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+
+ if (err)
+ return err;
+
+ if ((((uint *)(cmd.response))[0] & 0xff) != 0xaa)
+ return UNUSABLE_ERR;
+ else
+ mmc->version = SD_VERSION_2;
+
+ return 0;
+}
+
+int mmc_register(struct mmc *mmc)
+{
+ /* Setup the universal parts of the block interface just once */
+ mmc->block_dev.if_type = IF_TYPE_MMC;
+ mmc->block_dev.dev = cur_dev_num++;
+ mmc->block_dev.removable = 1;
+ mmc->block_dev.block_read = mmc_bread;
+ mmc->block_dev.block_write = mmc_bwrite;
+
+ INIT_LIST_HEAD (&mmc->link);
+
+ list_add_tail (&mmc->link, &mmc_devices);
+
+ return 0;
+}
+
+block_dev_desc_t *mmc_get_dev(int dev)
+{
+ struct mmc *mmc = find_mmc_device(dev);
+
+ return &mmc->block_dev;
+}
+
+int mmc_init(struct mmc *mmc)
+{
+ int err;
+
+ err = mmc->init(mmc);
+
+ if (err)
+ return err;
+
+ /* Reset the Card */
+ err = mmc_go_idle(mmc);
+
+ if (err)
+ return err;
+
+ /* Test for SD version 2 */
+ err = mmc_send_if_cond(mmc);
+
+ /* If we got an error other than timeout, we bail */
+ if (err && err != TIMEOUT)
+ return err;
+
+ /* Now try to get the SD card's operating condition */
+ err = sd_send_op_cond(mmc);
+
+ /* If the command timed out, we check for an MMC card */
+ if (err == TIMEOUT) {
+ err = mmc_send_op_cond(mmc);
+
+ if (err) {
+ printf("Card did not respond to voltage select!\n");
+ return UNUSABLE_ERR;
+ }
+ }
+
+ return mmc_startup(mmc);
+}
+
+/*
+ * CPU and board-specific MMC initializations. Aliased function
+ * signals caller to move on
+ */
+static int __def_mmc_init(bd_t *bis)
+{
+ return -1;
+}
+
+int cpu_mmc_init(bd_t *bis) __attribute((weak, alias("__def_mmc_init")));
+int board_mmc_init(bd_t *bis) __attribute((weak, alias("__def_mmc_init")));
+
+void print_mmc_devices(char separator)
+{
+ struct mmc *m;
+ struct list_head *entry;
+
+ list_for_each(entry, &mmc_devices) {
+ m = list_entry(entry, struct mmc, link);
+
+ printf("%s: %d", m->name, m->block_dev.dev);
+
+ if (entry->next != &mmc_devices)
+ printf("%c ", separator);
+ }
+
+ printf("\n");
+}
+
+int mmc_initialize(bd_t *bis)
+{
+ INIT_LIST_HEAD (&mmc_devices);
+ cur_dev_num = 0;
+
+ if (board_mmc_init(bis) < 0)
+ cpu_mmc_init(bis);
+
+ print_mmc_devices(',');
+
+ return 0;
+}
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 84ff7e8..a66feac 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -273,7 +273,7 @@ u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
/*-----------------------------------------------------------------------
*/
#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
-static flash_info_t *flash_get_info(ulong base)
+flash_info_t *flash_get_info(ulong base)
{
int i;
flash_info_t * info = 0;
@@ -305,17 +305,12 @@ flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
{
unsigned int byte_offset = offset * info->portwidth;
- return map_physmem(info->start[sect] + byte_offset,
- flash_sector_size(info, sect) - byte_offset,
- MAP_NOCACHE);
+ return (void *)(info->start[sect] + byte_offset);
}
static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
unsigned int offset, void *addr)
{
- unsigned int byte_offset = offset * info->portwidth;
-
- unmap_physmem(addr, flash_sector_size(info, sect) - byte_offset);
}
/*-----------------------------------------------------------------------
@@ -354,7 +349,7 @@ static void print_longlong (char *str, unsigned long long data)
int i;
char *cp;
- cp = (unsigned char *) &data;
+ cp = (char *) &data;
for (i = 0; i < 8; i++)
sprintf (&str[i * 2], "%2.2x", *cp++);
}
@@ -802,13 +797,11 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)
static int flash_write_cfiword (flash_info_t * info, ulong dest,
cfiword_t cword)
{
- void *dstaddr;
+ void *dstaddr = (void *)dest;
int flag;
flash_sect_t sect = 0;
char sect_found = 0;
- dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE);
-
/* Check if Flash is (sufficiently) erased */
switch (info->portwidth) {
case FLASH_CFI_8BIT:
@@ -827,10 +820,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
flag = 0;
break;
}
- if (!flag) {
- unmap_physmem(dstaddr, info->portwidth);
+ if (!flag)
return ERR_NOT_ERASED;
- }
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
@@ -873,8 +864,6 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
if (flag)
enable_interrupts ();
- unmap_physmem(dstaddr, info->portwidth);
-
if (!sect_found)
sect = find_sector (info, dest);
@@ -890,7 +879,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
int cnt;
int retcode;
void *src = cp;
- void *dst = map_physmem(dest, len, MAP_NOCACHE);
+ void *dst = (void *)dest;
void *dst2 = dst;
int flag = 0;
uint offset = 0;
@@ -1052,7 +1041,6 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
}
out_unmap:
- unmap_physmem(dst, len);
return retcode;
}
#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
@@ -1301,7 +1289,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
/* handle unaligned start */
if ((aln = addr - wp) != 0) {
cword.l = 0;
- p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
+ p = (uchar *)wp;
for (i = 0; i < aln; ++i)
flash_add_byte (info, &cword, flash_read8(p + i));
@@ -1313,7 +1301,6 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
flash_add_byte (info, &cword, flash_read8(p + i));
rc = flash_write_cfiword (info, wp, cword);
- unmap_physmem(p, info->portwidth);
if (rc != 0)
return rc;
@@ -1372,14 +1359,13 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
* handle unaligned tail bytes
*/
cword.l = 0;
- p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
+ p = (uchar *)wp;
for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
flash_add_byte (info, &cword, *src++);
--cnt;
}
for (; i < info->portwidth; ++i)
flash_add_byte (info, &cword, flash_read8(p + i));
- unmap_physmem(p, info->portwidth);
return flash_write_cfiword (info, wp, cword);
}
@@ -1618,7 +1604,7 @@ static void flash_read_jedec_ids (flash_info_t * info)
* board_flash_get_legacy needs to fill in at least:
* info->portwidth, info->chipwidth and info->interface for Jedec probing.
*/
-static int flash_detect_legacy(ulong base, int banknum)
+static int flash_detect_legacy(phys_addr_t base, int banknum)
{
flash_info_t *info = &flash_info[banknum];
@@ -1634,7 +1620,10 @@ static int flash_detect_legacy(ulong base, int banknum)
for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) {
info->vendor = modes[i];
- info->start[0] = base;
+ info->start[0] =
+ (ulong)map_physmem(base,
+ info->portwidth,
+ MAP_NOCACHE);
if (info->portwidth == FLASH_CFI_8BIT
&& info->interface == FLASH_CFI_X8X16) {
info->addr_unlock1 = 0x2AAA;
@@ -1648,8 +1637,11 @@ static int flash_detect_legacy(ulong base, int banknum)
info->manufacturer_id,
info->device_id,
info->device_id2);
- if (jedec_flash_match(info, base))
+ if (jedec_flash_match(info, info->start[0]))
break;
+ else
+ unmap_physmem((void *)info->start[0],
+ MAP_NOCACHE);
}
}
@@ -1671,7 +1663,7 @@ static int flash_detect_legacy(ulong base, int banknum)
return 0; /* use CFI */
}
#else
-static inline int flash_detect_legacy(ulong base, int banknum)
+static inline int flash_detect_legacy(phys_addr_t base, int banknum)
{
return 0; /* use CFI */
}
@@ -1826,12 +1818,12 @@ static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry)
* The following code cannot be run from FLASH!
*
*/
-ulong flash_get_size (ulong base, int banknum)
+ulong flash_get_size (phys_addr_t base, int banknum)
{
flash_info_t *info = &flash_info[banknum];
int i, j;
flash_sect_t sect_cnt;
- unsigned long sector;
+ phys_addr_t sector;
unsigned long tmp;
int size_ratio;
uchar num_erase_regions;
@@ -1847,7 +1839,7 @@ ulong flash_get_size (ulong base, int banknum)
info->legacy_unlock = 0;
#endif
- info->start[0] = base;
+ info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);
if (flash_detect_cfi (info, &qry)) {
info->vendor = le16_to_cpu(qry.p_id);
@@ -1939,7 +1931,10 @@ ulong flash_get_size (ulong base, int banknum)
printf("ERROR: too many flash sectors\n");
break;
}
- info->start[sect_cnt] = sector;
+ info->start[sect_cnt] =
+ (ulong)map_physmem(sector,
+ info->portwidth,
+ MAP_NOCACHE);
sector += (erase_region_size * size_ratio);
/*
@@ -2016,7 +2011,7 @@ unsigned long flash_init (void)
char *s = getenv("unlock");
#endif
-#define BANK_BASE(i) (((unsigned long [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])
+#define BANK_BASE(i) (((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])
/* Init: no FLASHes known */
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
diff --git a/drivers/mtd/jedec_flash.c b/drivers/mtd/jedec_flash.c
index 2d99d4d..e48acec 100644
--- a/drivers/mtd/jedec_flash.c
+++ b/drivers/mtd/jedec_flash.c
@@ -37,10 +37,6 @@
#define P_ID_AMD_STD CFI_CMDSET_AMD_LEGACY
-/* Manufacturers */
-#define MANUFACTURER_AMD 0x0001
-#define MANUFACTURER_SST 0x00BF
-
/* AMD */
#define AM29DL800BB 0x22CB
#define AM29DL800BT 0x224A
@@ -172,7 +168,7 @@ struct amd_flash_info {
static const struct amd_flash_info jedec_table[] = {
#ifdef CONFIG_SYS_FLASH_LEGACY_256Kx8
{
- .mfr_id = MANUFACTURER_SST,
+ .mfr_id = (u16)SST_MANUFACT,
.dev_id = SST39LF020,
.name = "SST 39LF020",
.uaddr = {
@@ -188,7 +184,7 @@ static const struct amd_flash_info jedec_table[] = {
#endif
#ifdef CONFIG_SYS_FLASH_LEGACY_512Kx8
{
- .mfr_id = MANUFACTURER_AMD,
+ .mfr_id = (u16)AMD_MANUFACT,
.dev_id = AM29LV040B,
.name = "AMD AM29LV040B",
.uaddr = {
@@ -202,7 +198,7 @@ static const struct amd_flash_info jedec_table[] = {
}
},
{
- .mfr_id = MANUFACTURER_SST,
+ .mfr_id = (u16)SST_MANUFACT,
.dev_id = SST39LF040,
.name = "SST 39LF040",
.uaddr = {
@@ -216,7 +212,7 @@ static const struct amd_flash_info jedec_table[] = {
}
},
{
- .mfr_id = STM_MANUFACT,
+ .mfr_id = (u16)STM_MANUFACT,
.dev_id = STM_ID_M29W040B,
.name = "ST Micro M29W040B",
.uaddr = {
@@ -232,7 +228,7 @@ static const struct amd_flash_info jedec_table[] = {
#endif
#ifdef CONFIG_SYS_FLASH_LEGACY_512Kx16
{
- .mfr_id = MANUFACTURER_AMD,
+ .mfr_id = (u16)AMD_MANUFACT,
.dev_id = AM29LV400BB,
.name = "AMD AM29LV400BB",
.uaddr = {
@@ -249,7 +245,7 @@ static const struct amd_flash_info jedec_table[] = {
}
},
{
- .mfr_id = MANUFACTURER_AMD,
+ .mfr_id = (u16)AMD_MANUFACT,
.dev_id = AM29LV800BB,
.name = "AMD AM29LV800BB",
.uaddr = {
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index cf92617..70b605f 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -28,6 +28,8 @@
#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
int nand_curr_device = -1;
nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
@@ -46,6 +48,8 @@ static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
if (nand_scan(mtd, 1) == 0) {
if (!mtd->name)
mtd->name = (char *)default_nand_name;
+ else
+ mtd->name += gd->reloc_off;
} else
mtd->name = NULL;
} else {
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ef37f97..d33fee2 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -75,6 +75,17 @@
#include <jffs2/jffs2.h>
#endif
+/*
+ * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting
+ * a flash. NAND flash is initialized prior to interrupts so standard timers
+ * can't be used. CONFIG_SYS_NAND_RESET_CNT should be set to a value
+ * which is greater than (max NAND reset time / NAND status read time).
+ * A conservative default of 200000 (500 us / 25 ns) is used as a default.
+ */
+#ifndef CONFIG_SYS_NAND_RESET_CNT
+#define CONFIG_SYS_NAND_RESET_CNT 200000
+#endif
+
/* Define default oob placement schemes for large and small page devices */
static struct nand_ecclayout nand_oob_8 = {
.eccbytes = 3,
@@ -524,6 +535,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
{
register struct nand_chip *chip = mtd->priv;
int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
+ uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT;
/*
* Write out the command to the device.
@@ -590,7 +602,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
NAND_CTRL_CLE | NAND_CTRL_CHANGE);
chip->cmd_ctrl(mtd,
NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
- while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ;
+ while (!(chip->read_byte(mtd) & NAND_STATUS_READY) &&
+ (rst_sts_cnt--));
return;
/* This applies to read commands */
@@ -626,6 +639,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
int column, int page_addr)
{
register struct nand_chip *chip = mtd->priv;
+ uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT;
/* Emulate NAND_CMD_READOOB */
if (command == NAND_CMD_READOOB) {
@@ -696,7 +710,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
chip->cmd_ctrl(mtd, NAND_CMD_NONE,
NAND_NCE | NAND_CTRL_CHANGE);
- while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ;
+ while (!(chip->read_byte(mtd) & NAND_STATUS_READY) &&
+ (rst_sts_cnt--));
return;
case NAND_CMD_RNDOUT:
@@ -2618,7 +2633,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips)
type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
if (IS_ERR(type)) {
+#ifndef CONFIG_SYS_NAND_QUIET_TEST
printk(KERN_WARNING "No NAND device found!!!\n");
+#endif
chip->select_chip(mtd, -1);
return PTR_ERR(type);
}
diff --git a/drivers/net/mcfmii.c b/drivers/net/mcfmii.c
index 2b733c6..4f1c0a0 100644
--- a/drivers/net/mcfmii.c
+++ b/drivers/net/mcfmii.c
@@ -226,7 +226,8 @@ void __mii_init(void)
volatile FEC_T *fecp;
struct eth_device *dev;
int miispd = 0, i = 0;
- u16 autoneg = 0;
+ u16 status = 0;
+ u16 linkgood = 0;
/* retrieve from register structure */
dev = eth_get_dev();
@@ -250,22 +251,32 @@ void __mii_init(void)
info->phy_addr = mii_discover_phy(dev);
-#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)
while (i < MCFFEC_TOUT_LOOP) {
- autoneg = 0;
- miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg);
+ status = 0;
i++;
-
- if ((autoneg & AUTONEGLINK) == AUTONEGLINK)
+ /* Read PHY control register */
+ miiphy_read(dev->name, info->phy_addr, PHY_BMCR, &status);
+
+ /* If phy set to autonegotiate, wait for autonegotiation done,
+ * if phy is not autonegotiating, just wait for link up.
+ */
+ if ((status & PHY_BMCR_AUTON) == PHY_BMCR_AUTON) {
+ linkgood = (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS);
+ } else {
+ linkgood = PHY_BMSR_LS;
+ }
+ /* Read PHY status register */
+ miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &status);
+ if ((status & linkgood) == linkgood)
break;
udelay(500);
}
if (i >= MCFFEC_TOUT_LOOP) {
- printf("Auto Negotiation not complete\n");
+ printf("Link UP timeout\n");
}
- /* adapt to the half/full speed settings */
+ /* adapt to the duplex and speed settings of the phy */
info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16;
info->dup_spd |= miiphy_speed(dev->name, info->phy_addr);
}
diff --git a/drivers/net/mpc5xxx_fec.c b/drivers/net/mpc5xxx_fec.c
index f8618b1..2bf901e 100644
--- a/drivers/net/mpc5xxx_fec.c
+++ b/drivers/net/mpc5xxx_fec.c
@@ -19,9 +19,6 @@ DECLARE_GLOBAL_DATA_PTR;
/* #define DEBUG 0x28 */
-#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
- defined(CONFIG_MPC5xxx_FEC)
-
#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
#error "CONFIG_MII has to be defined!"
#endif
@@ -891,28 +888,11 @@ int mpc5xxx_fec_initialize(bd_t * bis)
fec->eth = (ethernet_regs *)MPC5XXX_FEC;
fec->tbdBase = (FEC_TBD *)FEC_BD_BASE;
fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD));
-#if defined(CONFIG_CANMB) || \
- defined(CONFIG_CM5200) || \
- defined(CONFIG_HMI1001) || \
- defined(CONFIG_ICECUBE) || \
- defined(CONFIG_INKA4X0) || \
- defined(CONFIG_JUPITER) || \
- defined(CONFIG_MCC200) || \
- defined(CONFIG_MOTIONPRO) || \
- defined(CONFIG_MUCMC52) || \
- defined(CONFIG_O2DNT) || \
- defined(CONFIG_PM520) || \
- defined(CONFIG_TOP5200) || \
- defined(CONFIG_TQM5200) || \
- defined(CONFIG_UC101) || \
- defined(CONFIG_V38B) || \
- defined(CONFIG_MUNICES)
-# ifndef CONFIG_FEC_10MBIT
+#if defined(CONFIG_MPC5xxx_FEC_MII100)
fec->xcv_type = MII100;
-# else
+#elif defined(CONFIG_MPC5xxx_FEC_MII10)
fec->xcv_type = MII10;
-# endif
-#elif defined(CONFIG_TOTAL5200)
+#elif defined(CONFIG_MPC5xxx_FEC_SEVENWIRE)
fec->xcv_type = SEVENWIRE;
#else
#error fec->xcv_type not initialized.
@@ -1064,5 +1044,3 @@ static uint32 local_crc32(char *string, unsigned int crc_value, int len)
/**/ return crc;
}
#endif /* DEBUG */
-
-#endif /* CONFIG_MPC5xxx_FEC */
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index a13fff0..e153849 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -168,7 +168,7 @@ enum DMAC_T_BIT {
/* GECMR */
enum GECMR_BIT {
- GECMR_1000B = 0x01, GECMR_100B = 0x40, GECMR_10B = 0x00,
+ GECMR_1000B = 0x01, GECMR_100B = 0x04, GECMR_10B = 0x00,
};
/* EDRRR*/
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index dc90f23..9edba6a 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -158,6 +158,7 @@ int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info)
/* Reset the MAC */
priv->regs->maccfg1 |= MACCFG1_SOFT_RESET;
+ udelay(2); /* Soft Reset must be asserted for 3 TX clocks */
priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
index db68f26..20b2dcc 100644
--- a/drivers/pci/fsl_pci_init.c
+++ b/drivers/pci/fsl_pci_init.c
@@ -72,7 +72,7 @@ int fsl_pci_setup_inbound_windows(struct pci_region *r)
debug ("R0 bus_start: %llx phys_start: %llx size: %llx\n",
(u64)bus_start, (u64)phys_start, (u64)pci_sz);
pci_set_region(r++, bus_start, phys_start, pci_sz,
- PCI_REGION_MEM | PCI_REGION_MEMORY |
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
PCI_REGION_PREFETCH);
sz -= pci_sz;
@@ -84,7 +84,7 @@ int fsl_pci_setup_inbound_windows(struct pci_region *r)
debug ("R1 bus_start: %llx phys_start: %llx size: %llx\n",
(u64)bus_start, (u64)phys_start, (u64)pci_sz);
pci_set_region(r++, bus_start, phys_start, pci_sz,
- PCI_REGION_MEM | PCI_REGION_MEMORY |
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
PCI_REGION_PREFETCH);
sz -= pci_sz;
bus_start += pci_sz;
@@ -108,7 +108,7 @@ int fsl_pci_setup_inbound_windows(struct pci_region *r)
CONFIG_SYS_PCI64_MEMORY_BUS,
CONFIG_SYS_PCI_MEMORY_PHYS,
pci_sz,
- PCI_REGION_MEM | PCI_REGION_MEMORY |
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
PCI_REGION_PREFETCH);
#else
pci_sz = 1ull << __ilog2_u64(sz);
@@ -116,7 +116,7 @@ int fsl_pci_setup_inbound_windows(struct pci_region *r)
debug ("R2 bus_start: %llx phys_start: %llx size: %llx\n",
(u64)bus_start, (u64)phys_start, (u64)pci_sz);
pci_set_region(r++, bus_start, phys_start, pci_sz,
- PCI_REGION_MEM | PCI_REGION_MEMORY |
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
PCI_REGION_PREFETCH);
sz -= pci_sz;
bus_start += pci_sz;
@@ -157,7 +157,7 @@ void fsl_pci_init(struct pci_controller *hose)
for (r=0; r<hose->region_count; r++) {
u32 sz = (__ilog2_u64((u64)hose->regions[r].size) - 1);
- if (hose->regions[r].flags & PCI_REGION_MEMORY) { /* inbound */
+ if (hose->regions[r].flags & PCI_REGION_SYS_MEMORY) { /* inbound */
u32 flag = PIWAR_EN | PIWAR_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
pi->pitar = (hose->regions[r].phys_start >> 12);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e2b05d8..fffca49 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -116,6 +116,25 @@ PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
+/* Get a virtual address associated with a BAR region */
+void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
+{
+ pci_addr_t pci_bus_addr;
+ u32 bar_response;
+
+ /* read BAR address */
+ pci_read_config_dword(pdev, bar, &bar_response);
+ pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
+
+ /*
+ * Pass "0" as the length argument to pci_bus_to_virt. The arg
+ * isn't actualy used on any platform because u-boot assumes a static
+ * linear mapping. In the future, this could read the BAR size
+ * and pass that as the size if needed.
+ */
+ return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
+}
+
/*
*
*/
@@ -218,67 +237,121 @@ pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
*
*/
-pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
- phys_addr_t phys_addr,
- unsigned long flags)
+int __pci_hose_phys_to_bus (struct pci_controller *hose,
+ phys_addr_t phys_addr,
+ unsigned long flags,
+ unsigned long skip_mask,
+ pci_addr_t *ba)
{
struct pci_region *res;
pci_addr_t bus_addr;
int i;
- if (!hose) {
- printf ("pci_hose_phys_to_bus: %s\n", "invalid hose");
- goto Done;
- }
-
for (i = 0; i < hose->region_count; i++) {
res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
continue;
+ if (res->flags & skip_mask)
+ continue;
+
bus_addr = phys_addr - res->phys_start + res->bus_start;
if (bus_addr >= res->bus_start &&
bus_addr < res->bus_start + res->size) {
- return bus_addr;
+ *ba = bus_addr;
+ return 0;
}
}
- printf ("pci_hose_phys_to_bus: %s\n", "invalid physical address");
-
-Done:
- return 0;
+ return 1;
}
-phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
- pci_addr_t bus_addr,
- unsigned long flags)
+pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
+ phys_addr_t phys_addr,
+ unsigned long flags)
{
- struct pci_region *res;
- int i;
+ pci_addr_t bus_addr = 0;
+ int ret;
if (!hose) {
- printf ("pci_hose_bus_to_phys: %s\n", "invalid hose");
- goto Done;
+ puts ("pci_hose_phys_to_bus: invalid hose\n");
+ return bus_addr;
}
+ /* if PCI_REGION_MEM is set we do a two pass search with preference
+ * on matches that don't have PCI_REGION_SYS_MEMORY set */
+ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+ ret = __pci_hose_phys_to_bus(hose, phys_addr,
+ flags, PCI_REGION_SYS_MEMORY, &bus_addr);
+ if (!ret)
+ return bus_addr;
+ }
+
+ ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
+
+ if (ret)
+ puts ("pci_hose_phys_to_bus: invalid physical address\n");
+
+ return bus_addr;
+}
+
+int __pci_hose_bus_to_phys (struct pci_controller *hose,
+ pci_addr_t bus_addr,
+ unsigned long flags,
+ unsigned long skip_mask,
+ phys_addr_t *pa)
+{
+ struct pci_region *res;
+ int i;
+
for (i = 0; i < hose->region_count; i++) {
res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
continue;
+ if (res->flags & skip_mask)
+ continue;
+
if (bus_addr >= res->bus_start &&
bus_addr < res->bus_start + res->size) {
- return bus_addr - res->bus_start + res->phys_start;
+ *pa = (bus_addr - res->bus_start + res->phys_start);
+ return 0;
}
}
- printf ("pci_hose_bus_to_phys: %s\n", "invalid physical address");
+ return 1;
+}
-Done:
- return 0;
+phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
+ pci_addr_t bus_addr,
+ unsigned long flags)
+{
+ phys_addr_t phys_addr = 0;
+ int ret;
+
+ if (!hose) {
+ puts ("pci_hose_bus_to_phys: invalid hose\n");
+ return phys_addr;
+ }
+
+ /* if PCI_REGION_MEM is set we do a two pass search with preference
+ * on matches that don't have PCI_REGION_SYS_MEMORY set */
+ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+ ret = __pci_hose_bus_to_phys(hose, bus_addr,
+ flags, PCI_REGION_SYS_MEMORY, &phys_addr);
+ if (!ret)
+ return phys_addr;
+ }
+
+ ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
+
+ if (ret)
+ puts ("pci_hose_bus_to_phys: invalid physical address\n");
+
+ return phys_addr;
}
/*
diff --git a/drivers/pci/pci_ixp.c b/drivers/pci/pci_ixp.c
index aae3d3d..3b303b4 100644
--- a/drivers/pci/pci_ixp.c
+++ b/drivers/pci/pci_ixp.c
@@ -240,7 +240,7 @@ void pci_ixp_init (struct pci_controller *hose)
/* System memory space */
pci_set_region (hose->regions + 0,
PCI_MEMORY_BUS,
- PCI_MEMORY_PHY, PCI_MEMORY_SIZE, PCI_REGION_MEMORY);
+ PCI_MEMORY_PHY, PCI_MEMORY_SIZE, PCI_REGION_SYS_MEMORY);
/* PCI memory space */
pci_set_region (hose->regions + 1,
diff --git a/drivers/pci/tsi108_pci.c b/drivers/pci/tsi108_pci.c
index d153fc6..627e8a0 100644
--- a/drivers/pci/tsi108_pci.c
+++ b/drivers/pci/tsi108_pci.c
@@ -131,7 +131,7 @@ void pci_init_board (void)
pci_set_region (hose->regions + 0,
CONFIG_SYS_PCI_MEMORY_BUS,
CONFIG_SYS_PCI_MEMORY_PHYS,
- CONFIG_SYS_PCI_MEMORY_SIZE, PCI_REGION_MEM | PCI_REGION_MEMORY);
+ CONFIG_SYS_PCI_MEMORY_SIZE, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
/* PCI memory space */
pci_set_region (hose->regions + 1,
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index ba251d0..babe3ec 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libpcmcia.a
COBJS-$(CONFIG_I82365) += i82365.o
-COBJS-y += mpc8xx_pcmcia.o
+COBJS-$(CONFIG_8xx) += mpc8xx_pcmcia.o
COBJS-$(CONFIG_PXA_PCMCIA) += pxa_pcmcia.o
COBJS-y += rpx_pcmcia.o
COBJS-$(CONFIG_IDE_TI_CARDBUS) += ti_pci1410a.o
diff --git a/drivers/pcmcia/mpc8xx_pcmcia.c b/drivers/pcmcia/mpc8xx_pcmcia.c
index 95ea5e9..7030574 100644
--- a/drivers/pcmcia/mpc8xx_pcmcia.c
+++ b/drivers/pcmcia/mpc8xx_pcmcia.c
@@ -1,7 +1,5 @@
#include <common.h>
-#if defined(CONFIG_8xx)
#include <mpc8xx.h>
-#endif
#include <pcmcia.h>
#undef CONFIG_PCMCIA
@@ -14,7 +12,7 @@
#define CONFIG_PCMCIA
#endif
-#if defined(CONFIG_8xx) && defined(CONFIG_PCMCIA)
+#if defined(CONFIG_PCMCIA)
#if defined(CONFIG_IDE_8xx_PCCARD)
extern int check_ide_device (int slot);
@@ -301,4 +299,4 @@ static u_int m8xx_get_speed(u_int ns, u_int is_io)
}
#endif /* 0 */
-#endif /* CONFIG_8xx && CONFIG_PCMCIA */
+#endif /* CONFIG_PCMCIA */
diff --git a/drivers/serial/mcfuart.c b/drivers/serial/mcfuart.c
index e04fc29..0b53140 100644
--- a/drivers/serial/mcfuart.c
+++ b/drivers/serial/mcfuart.c
@@ -115,8 +115,9 @@ void serial_setbrg(void)
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
u32 counter;
- counter = ((gd->bus_clk / gd->baudrate)) >> 5;
- counter++;
+ /* Setting up BaudRate */
+ counter = (u32) ((gd->bus_clk / 32) + (gd->baudrate / 2));
+ counter = counter / gd->baudrate;
/* write to CTUR: divide counter upper byte */
uart->ubg1 = ((counter & 0xff00) >> 8);
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 93c2243..1b347e9 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -39,6 +39,7 @@ void NS16550_init (NS16550_t com_port, int baud_divisor)
#endif
}
+#ifndef CONFIG_NS16550_MIN_FUNCTIONS
void NS16550_reinit (NS16550_t com_port, int baud_divisor)
{
com_port->ier = 0x00;
@@ -53,6 +54,7 @@ void NS16550_reinit (NS16550_t com_port, int baud_divisor)
com_port->dlm = (baud_divisor >> 8) & 0xff;
com_port->lcr = LCRVAL;
}
+#endif /* CONFIG_NS16550_MIN_FUNCTIONS */
void NS16550_putc (NS16550_t com_port, char c)
{
@@ -60,6 +62,7 @@ void NS16550_putc (NS16550_t com_port, char c)
com_port->thr = c;
}
+#ifndef CONFIG_NS16550_MIN_FUNCTIONS
char NS16550_getc (NS16550_t com_port)
{
while ((com_port->lsr & LSR_DR) == 0) {
@@ -76,4 +79,5 @@ int NS16550_tstc (NS16550_t com_port)
return ((com_port->lsr & LSR_DR) != 0);
}
+#endif /* CONFIG_NS16550_MIN_FUNCTIONS */
#endif
diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c
index 7eba470..2624e6f 100644
--- a/drivers/serial/usbtty.c
+++ b/drivers/serial/usbtty.c
@@ -150,8 +150,7 @@ struct acm_config_desc {
/* Slave Interface */
struct usb_interface_descriptor data_class_interface;
- struct usb_endpoint_descriptor
- data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));
+ struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS-1];
} __attribute__((packed));
static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
@@ -280,10 +279,8 @@ static struct rs232_emu rs232_desc={
struct gserial_config_desc {
struct usb_configuration_descriptor configuration_desc;
- struct usb_interface_descriptor
- interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed));
- struct usb_endpoint_descriptor
- data_endpoints[NUM_ENDPOINTS] __attribute__((packed));
+ struct usb_interface_descriptor interface_desc[NUM_GSERIAL_INTERFACES];
+ struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS];
} __attribute__((packed));
@@ -433,6 +430,9 @@ int usbtty_getc (void)
*/
void usbtty_putc (const char c)
{
+ if (!usbtty_configured ())
+ return;
+
buf_push (&usbtty_output, &c, 1);
/* If \n, also do \r */
if (c == '\n')
@@ -486,8 +486,12 @@ static void __usbtty_puts (const char *str, int len)
void usbtty_puts (const char *str)
{
int n;
- int len = strlen (str);
+ int len;
+
+ if (!usbtty_configured ())
+ return;
+ len = strlen (str);
/* add '\r' for each '\n' */
while (len > 0) {
n = next_nl_pos (str);
diff --git a/drivers/usb/davinci_usb.h b/drivers/usb/davinci_usb.h
index d270861..f6751bf 100644
--- a/drivers/usb/davinci_usb.h
+++ b/drivers/usb/davinci_usb.h
@@ -84,4 +84,3 @@ extern int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len);
extern int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len);
extern void enable_vbus(void);
#endif /* __DAVINCI_USB_H__ */
-
diff --git a/drivers/usb/musb_core.h b/drivers/usb/musb_core.h
index 9f5ebe7..2597c5f 100644
--- a/drivers/usb/musb_core.h
+++ b/drivers/usb/musb_core.h
@@ -314,4 +314,3 @@ extern inline u16 musb_readw(u32 offset);
extern inline u8 musb_readb(u32 offset);
#endif /* __MUSB_HDRC_DEFS_H__ */
-
diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c
index 813f64a..4dbfb66 100644
--- a/drivers/usb/usb_ehci_core.c
+++ b/drivers/usb/usb_ehci_core.c
@@ -818,8 +818,10 @@ int usb_lowlevel_init(void)
/* Start the host controller. */
cmd = ehci_readl(&hcor->or_usbcmd);
- /* Philips, Intel, and maybe others need CMD_RUN before the
- * root hub will detect new devices (why?); NEC doesn't */
+ /*
+ * Philips, Intel, and maybe others need CMD_RUN before the
+ * root hub will detect new devices (why?); NEC doesn't
+ */
cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
cmd |= CMD_RUN;
ehci_writel(&hcor->or_usbcmd, cmd);
diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c
index d68fdcf..0bbee0f 100644
--- a/drivers/usb/usb_ohci.c
+++ b/drivers/usb/usb_ohci.c
@@ -27,7 +27,7 @@
*
* 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
+ * 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
diff --git a/drivers/video/mb862xx.c b/drivers/video/mb862xx.c
index 22a85d1..01eda55 100644
--- a/drivers/video/mb862xx.c
+++ b/drivers/video/mb862xx.c
@@ -12,7 +12,7 @@
*
* 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
+ * 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
diff --git a/drivers/video/smiLynxEM.c b/drivers/video/smiLynxEM.c
index 59b43ef..2001e9c 100644
--- a/drivers/video/smiLynxEM.c
+++ b/drivers/video/smiLynxEM.c
@@ -12,7 +12,7 @@
*
* 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
+ * 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