summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/cfi_flash.c11
-rw-r--r--drivers/mtd/nand/Makefile3
-rw-r--r--drivers/mtd/nand/davinci_nand.c289
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c4
-rw-r--r--drivers/mtd/nand/nand_plat.c53
-rw-r--r--drivers/mtd/nand/nand_util.c20
-rw-r--r--drivers/usb/host/Makefile1
-rw-r--r--drivers/usb/host/ehci-fsl.c18
-rw-r--r--drivers/usb/host/ehci-hcd.c4
-rw-r--r--drivers/usb/host/ehci-kirkwood.c108
-rw-r--r--drivers/usb/musb/musb_core.h6
-rw-r--r--drivers/usb/musb/musb_hcd.c31
-rw-r--r--drivers/usb/musb/musb_hcd.h4
13 files changed, 269 insertions, 283 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index d0732f5..81ac5d3 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -835,14 +835,19 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
break;
case CFI_CMDSET_AMD_EXTENDED:
case CFI_CMDSET_AMD_STANDARD:
-#ifdef CONFIG_FLASH_CFI_LEGACY
- case CFI_CMDSET_AMD_LEGACY:
-#endif
sect = find_sector(info, dest);
flash_unlock_seq (info, sect);
flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_WRITE);
sect_found = 1;
break;
+#ifdef CONFIG_FLASH_CFI_LEGACY
+ case CFI_CMDSET_AMD_LEGACY:
+ sect = find_sector(info, dest);
+ flash_unlock_seq (info, 0);
+ flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE);
+ sect_found = 1;
+ break;
+#endif
}
switch (info->portwidth) {
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d4d3948..a5680e8 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -43,9 +43,10 @@ COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o
-COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.c
+COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
+COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
endif
COBJS := $(COBJS-y)
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 8ef18b8..ca40c6a 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -47,7 +47,7 @@
#include <asm/arch/nand_defs.h>
#include <asm/arch/emif_defs.h>
-extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE];
+static emif_registers *const emif_regs = (void *) DAVINCI_ASYNC_EMIF_CNTRL_BASE;
static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
@@ -68,81 +68,30 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c
writeb(cmd, this->IO_ADDR_W);
}
-/* Set WP on deselect, write enable on select */
-static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
-{
-#define GPIO_SET_DATA01 0x01c67018
-#define GPIO_CLR_DATA01 0x01c6701c
-#define GPIO_NAND_WP (1 << 4)
-#ifdef SONATA_BOARD_GPIOWP
- if (chip < 0) {
- REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP;
- } else {
- REG(GPIO_SET_DATA01) |= GPIO_NAND_WP;
- }
-#endif
-}
-
#ifdef CONFIG_SYS_NAND_HW_ECC
-#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
-/* Linux-compatible ECC uses MTD defaults. */
-/* These layouts are not compatible with Linux or RBL/UBL. */
-#ifdef CONFIG_SYS_NAND_LARGEPAGE
-static struct nand_ecclayout davinci_nand_ecclayout = {
- .eccbytes = 12,
- .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
- .oobfree = {
- {.offset = 2, .length = 6},
- {.offset = 12, .length = 12},
- {.offset = 28, .length = 12},
- {.offset = 44, .length = 12},
- {.offset = 60, .length = 4}
- }
-};
-#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
-static struct nand_ecclayout davinci_nand_ecclayout = {
- .eccbytes = 3,
- .eccpos = {0, 1, 2},
- .oobfree = {
- {.offset = 6, .length = 2},
- {.offset = 8, .length = 8}
- }
-};
-#else
-#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
-#endif
-#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
{
- emifregs emif_addr;
int dummy;
- emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
+ dummy = emif_regs->NANDF1ECC;
- dummy = emif_addr->NANDF1ECC;
- dummy = emif_addr->NANDF2ECC;
- dummy = emif_addr->NANDF3ECC;
- dummy = emif_addr->NANDF4ECC;
-
- emif_addr->NANDFCR |= (1 << 8);
+ /* FIXME: only chipselect 0 is supported for now */
+ emif_regs->NANDFCR |= 1 << 8;
}
static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
{
u_int32_t ecc = 0;
- emifregs emif_base_addr;
-
- emif_base_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
if (region == 1)
- ecc = emif_base_addr->NANDF1ECC;
+ ecc = emif_regs->NANDF1ECC;
else if (region == 2)
- ecc = emif_base_addr->NANDF2ECC;
+ ecc = emif_regs->NANDF2ECC;
else if (region == 3)
- ecc = emif_base_addr->NANDF3ECC;
+ ecc = emif_regs->NANDF3ECC;
else if (region == 4)
- ecc = emif_base_addr->NANDF4ECC;
+ ecc = emif_regs->NANDF4ECC;
return(ecc);
}
@@ -150,29 +99,6 @@ static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
{
u_int32_t tmp;
-#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
- /*
- * This is not how you should read ECCs on large page Davinci devices.
- * The region parameter gets you ECCs for flash chips on different chip
- * selects, not the 4x512 byte pages in a 2048 byte page.
- *
- * Preserved for backwards compatibility though.
- */
-
- int region, n;
- struct nand_chip *this = mtd->priv;
-
- n = (this->ecc.size/512);
-
- region = 1;
- while (n--) {
- tmp = nand_davinci_readecc(mtd, region);
- *ecc_code++ = tmp;
- *ecc_code++ = tmp >> 16;
- *ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0);
- region++;
- }
-#else
const int region = 1;
tmp = nand_davinci_readecc(mtd, region);
@@ -187,148 +113,26 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
*ecc_code++ = tmp;
*ecc_code++ = tmp >> 8;
*ecc_code++ = tmp >> 16;
-#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
- return(0);
-}
-
-#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
-static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf)
-{
- u_int32_t tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8);
-
- ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) | P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp));
- ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) | P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp));
- ecc_buf[2] = ~( P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) | P1e(tmp) | P2048o(tmp) | P2048e(tmp));
-}
-
-static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_int8_t *page_data)
-{
- u_int32_t i;
- u_int8_t tmp0_bit[8], tmp1_bit[8], tmp2_bit[8];
- u_int8_t comp0_bit[8], comp1_bit[8], comp2_bit[8];
- u_int8_t ecc_bit[24];
- u_int8_t ecc_sum = 0;
- u_int8_t find_bit = 0;
- u_int32_t find_byte = 0;
- int is_ecc_ff;
-
- is_ecc_ff = ((*ecc_nand == 0xff) && (*(ecc_nand + 1) == 0xff) && (*(ecc_nand + 2) == 0xff));
-
- nand_davinci_gen_true_ecc(ecc_nand);
- nand_davinci_gen_true_ecc(ecc_calc);
-
- for (i = 0; i <= 2; i++) {
- *(ecc_nand + i) = ~(*(ecc_nand + i));
- *(ecc_calc + i) = ~(*(ecc_calc + i));
- }
- for (i = 0; i < 8; i++) {
- tmp0_bit[i] = *ecc_nand % 2;
- *ecc_nand = *ecc_nand / 2;
- }
-
- for (i = 0; i < 8; i++) {
- tmp1_bit[i] = *(ecc_nand + 1) % 2;
- *(ecc_nand + 1) = *(ecc_nand + 1) / 2;
- }
-
- for (i = 0; i < 8; i++) {
- tmp2_bit[i] = *(ecc_nand + 2) % 2;
- *(ecc_nand + 2) = *(ecc_nand + 2) / 2;
- }
-
- for (i = 0; i < 8; i++) {
- comp0_bit[i] = *ecc_calc % 2;
- *ecc_calc = *ecc_calc / 2;
- }
-
- for (i = 0; i < 8; i++) {
- comp1_bit[i] = *(ecc_calc + 1) % 2;
- *(ecc_calc + 1) = *(ecc_calc + 1) / 2;
- }
-
- for (i = 0; i < 8; i++) {
- comp2_bit[i] = *(ecc_calc + 2) % 2;
- *(ecc_calc + 2) = *(ecc_calc + 2) / 2;
- }
-
- for (i = 0; i< 6; i++)
- ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
-
- for (i = 0; i < 8; i++)
- ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
-
- for (i = 0; i < 8; i++)
- ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
-
- ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0];
- ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1];
-
- for (i = 0; i < 24; i++)
- ecc_sum += ecc_bit[i];
+ /* NOTE: the above code matches mainline Linux:
+ * .PQR.stu ==> ~PQRstu
+ *
+ * MontaVista/TI kernels encode those bytes differently, use
+ * complicated (and allegedly sometimes-wrong) correction code,
+ * and usually shipped with U-Boot that uses software ECC:
+ * .PQR.stu ==> PsQRtu
+ *
+ * If you need MV/TI compatible NAND I/O in U-Boot, it should
+ * be possible to (a) change the mangling above, (b) reverse
+ * that mangling in nand_davinci_correct_data() below.
+ */
- switch (ecc_sum) {
- case 0:
- /* Not reached because this function is not called if
- ECC values are equal */
- return 0;
- case 1:
- /* Uncorrectable error */
- MTDDEBUG (MTD_DEBUG_LEVEL0,
- "ECC UNCORRECTED_ERROR 1\n");
- return(-1);
- case 12:
- /* Correctable error */
- find_byte = (ecc_bit[23] << 8) +
- (ecc_bit[21] << 7) +
- (ecc_bit[19] << 6) +
- (ecc_bit[17] << 5) +
- (ecc_bit[15] << 4) +
- (ecc_bit[13] << 3) +
- (ecc_bit[11] << 2) +
- (ecc_bit[9] << 1) +
- ecc_bit[7];
-
- find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
-
- MTDDEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC "
- "error at offset: %d, bit: %d\n",
- find_byte, find_bit);
-
- page_data[find_byte] ^= (1 << find_bit);
-
- return(0);
- default:
- if (is_ecc_ff) {
- if (ecc_calc[0] == 0 && ecc_calc[1] == 0 && ecc_calc[2] == 0)
- return(0);
- }
- MTDDEBUG (MTD_DEBUG_LEVEL0,
- "UNCORRECTED_ERROR default\n");
- return(-1);
- }
+ return 0;
}
-#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
{
struct nand_chip *this = mtd->priv;
-#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
- int block_count = 0, i, rc;
-
- block_count = (this->ecc.size/512);
- for (i = 0; i < block_count; i++) {
- if (memcmp(read_ecc, calc_ecc, 3) != 0) {
- rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat);
- if (rc < 0) {
- return(rc);
- }
- }
- read_ecc += 3;
- calc_ecc += 3;
- dat += 512;
- }
-#else
u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
(read_ecc[2] << 16);
u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) |
@@ -362,31 +166,24 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *
return -1;
}
}
-#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
return(0);
}
#endif /* CONFIG_SYS_NAND_HW_ECC */
static int nand_davinci_dev_ready(struct mtd_info *mtd)
{
- emifregs emif_addr;
-
- emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
-
- return(emif_addr->NANDFSR & 0x1);
-}
-
-static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
-{
- while(!nand_davinci_dev_ready(mtd)) {;}
- *NAND_CE0CLE = NAND_STATUS;
- return(*NAND_CE0DATA);
+ return emif_regs->NANDFSR & 0x1;
}
static void nand_flash_init(void)
{
+ /* This is for DM6446 EVM and *very* similar. DO NOT GROW THIS!
+ * Instead, have your board_init() set EMIF timings, based on its
+ * knowledge of the clocks and what devices are hooked up ... and
+ * don't even do that unless no UBL handled it.
+ */
+#ifdef CONFIG_SOC_DM6446
u_int32_t acfg1 = 0x3ffffffc;
- emifregs emif_regs;
/*------------------------------------------------------------------*
* NAND FLASH CHIP TIMEOUT @ 459 MHz *
@@ -408,39 +205,22 @@ static void nand_flash_init(void)
| (0 << 0 ) /* asyncSize 8-bit bus */
;
- emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
-
emif_regs->AB1CR = acfg1; /* CS2 */
emif_regs->NANDFCR = 0x00000101; /* NAND flash on CS2 */
+#endif
}
-int board_nand_init(struct nand_chip *nand)
+void davinci_nand_init(struct nand_chip *nand)
{
- nand->IO_ADDR_R = (void __iomem *)NAND_CE0DATA;
- nand->IO_ADDR_W = (void __iomem *)NAND_CE0DATA;
nand->chip_delay = 0;
- nand->select_chip = nand_davinci_select_chip;
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
nand->options = NAND_USE_FLASH_BBT;
#endif
#ifdef CONFIG_SYS_NAND_HW_ECC
nand->ecc.mode = NAND_ECC_HW;
-#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
- nand->ecc.layout = &davinci_nand_ecclayout;
-#ifdef CONFIG_SYS_NAND_LARGEPAGE
- nand->ecc.size = 2048;
- nand->ecc.bytes = 12;
-#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
nand->ecc.size = 512;
nand->ecc.bytes = 3;
-#else
-#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
-#endif
-#else
- nand->ecc.size = 512;
- nand->ecc.bytes = 3;
-#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */
nand->ecc.calculate = nand_davinci_calculate_ecc;
nand->ecc.correct = nand_davinci_correct_data;
nand->ecc.hwctl = nand_davinci_enable_hwecc;
@@ -452,9 +232,14 @@ int board_nand_init(struct nand_chip *nand)
nand->cmd_ctrl = nand_davinci_hwcontrol;
nand->dev_ready = nand_davinci_dev_ready;
- nand->waitfunc = nand_davinci_waitfunc;
nand_flash_init();
+}
- return(0);
+int board_nand_init(struct nand_chip *chip) __attribute__((weak));
+
+int board_nand_init(struct nand_chip *chip)
+{
+ davinci_nand_init(chip);
+ return 0;
}
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 3f318e0..77a33c0 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -766,6 +766,9 @@ int board_nand_init(struct nand_chip *nand)
nand->waitfunc = fsl_elbc_wait;
/* set up nand options */
+ /* redirect the pointer of bbt pattern to RAM */
+ bbt_main_descr.pattern = bbt_pattern;
+ bbt_mirror_descr.pattern = mirror_pattern;
nand->bbt_td = &bbt_main_descr;
nand->bbt_md = &bbt_mirror_descr;
@@ -812,6 +815,7 @@ int board_nand_init(struct nand_chip *nand)
/* Large-page-specific setup */
if (or & OR_FCM_PGS) {
priv->page_size = 1;
+ largepage_memorybased.pattern = scan_ff_pattern;
nand->badblock_pattern = &largepage_memorybased;
/* adjust ecc setup if needed */
diff --git a/drivers/mtd/nand/nand_plat.c b/drivers/mtd/nand/nand_plat.c
new file mode 100644
index 0000000..b35492b
--- /dev/null
+++ b/drivers/mtd/nand/nand_plat.c
@@ -0,0 +1,53 @@
+/*
+ * Genericish driver for memory mapped NAND devices
+ *
+ * Copyright (c) 2006-2009 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
+ */
+
+/* Your board must implement the following macros:
+ * NAND_PLAT_WRITE_CMD(chip, cmd)
+ * NAND_PLAT_WRITE_ADR(chip, cmd)
+ * NAND_PLAT_INIT()
+ *
+ * It may also implement the following:
+ * NAND_PLAT_DEV_READY(chip)
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include <nand.h>
+
+static void plat_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ NAND_PLAT_WRITE_CMD(this, cmd);
+ else
+ NAND_PLAT_WRITE_ADR(this, cmd);
+}
+
+#ifdef NAND_PLAT_DEV_READY
+static int plat_dev_ready(struct mtd_info *mtd)
+{
+ return NAND_PLAT_DEV_READY((struct nand_chip *)mtd->priv);
+}
+#else
+# define plat_dev_ready NULL
+#endif
+
+int board_nand_init(struct nand_chip *nand)
+{
+ NAND_PLAT_INIT();
+
+ nand->cmd_ctrl = plat_cmd_ctrl;
+ nand->dev_ready = plat_dev_ready;
+ nand->ecc.mode = NAND_ECC_SOFT;
+
+ return 0;
+}
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index 88206d0..fc16282 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -315,7 +315,7 @@ int nand_lock(struct mtd_info *mtd, int tight)
* NAND_LOCK_STATUS_UNLOCK: page unlocked
*
*/
-int nand_get_lock_status(struct mtd_info *mtd, ulong offset)
+int nand_get_lock_status(struct mtd_info *mtd, loff_t offset)
{
int ret = 0;
int chipnr;
@@ -436,7 +436,7 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)
* @param length image length
* @return image length including bad blocks
*/
-static size_t get_len_incl_bad (nand_info_t *nand, size_t offset,
+static size_t get_len_incl_bad (nand_info_t *nand, loff_t offset,
const size_t length)
{
size_t len_incl_bad = 0;
@@ -473,7 +473,7 @@ static size_t get_len_incl_bad (nand_info_t *nand, size_t offset,
* @param buf buffer to read from
* @return 0 in case of success
*/
-int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
+int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
u_char *buffer)
{
int rval;
@@ -498,7 +498,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
if (len_incl_bad == *length) {
rval = nand_write (nand, offset, length, buffer);
if (rval != 0)
- printf ("NAND write to offset %zx failed %d\n",
+ printf ("NAND write to offset %llx failed %d\n",
offset, rval);
return rval;
@@ -509,7 +509,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
size_t write_size;
if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
- printf ("Skip bad block 0x%08zx\n",
+ printf ("Skip bad block 0x%08llx\n",
offset & ~(nand->erasesize - 1));
offset += nand->erasesize - block_offset;
continue;
@@ -522,7 +522,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
rval = nand_write (nand, offset, &write_size, p_buffer);
if (rval != 0) {
- printf ("NAND write to offset %zx failed %d\n",
+ printf ("NAND write to offset %llx failed %d\n",
offset, rval);
*length -= left_to_write;
return rval;
@@ -550,7 +550,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
* @param buffer buffer to write to
* @return 0 in case of success
*/
-int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
+int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
u_char *buffer)
{
int rval;
@@ -568,7 +568,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
if (len_incl_bad == *length) {
rval = nand_read (nand, offset, length, buffer);
if (rval != 0)
- printf ("NAND read from offset %zx failed %d\n",
+ printf ("NAND read from offset %llx failed %d\n",
offset, rval);
return rval;
@@ -579,7 +579,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
size_t read_length;
if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
- printf ("Skipping bad block 0x%08zx\n",
+ printf ("Skipping bad block 0x%08llx\n",
offset & ~(nand->erasesize - 1));
offset += nand->erasesize - block_offset;
continue;
@@ -592,7 +592,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
rval = nand_read (nand, offset, &read_length, p_buffer);
if (rval != 0) {
- printf ("NAND read from offset %zx failed %d\n",
+ printf ("NAND read from offset %llx failed %d\n",
offset, rval);
*length -= left_to_read;
return rval;
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index ec1d689..940d4a8 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -37,6 +37,7 @@ COBJS-$(CONFIG_USB_SL811HS) += sl811-hcd.o
COBJS-$(CONFIG_USB_EHCI) += ehci-hcd.o
COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
COBJS-$(CONFIG_USB_EHCI_IXP4XX) += ehci-ixp.o
+COBJS-$(CONFIG_USB_EHCI_KIRKWOOD) += ehci-kirkwood.o
COBJS-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
COBJS-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index bf148c4..c674929 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -41,15 +41,15 @@ int ehci_hcd_init(void)
struct usb_ehci *ehci;
ehci = (struct usb_ehci *)CONFIG_SYS_MPC8xxx_USB_ADDR;
- hccr = (struct ehci_hccr *)((uint32_t)ehci->caplength);
+ hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
hcor = (struct ehci_hcor *)((uint32_t) hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
/* Set to Host mode */
- setbits_le32((void *)ehci->usbmode, CM_HOST);
+ setbits_le32(&ehci->usbmode, CM_HOST);
- out_be32((void *)ehci->snoop1, SNOOP_SIZE_2GB);
- out_be32((void *)ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB);
+ out_be32(&ehci->snoop1, SNOOP_SIZE_2GB);
+ out_be32(&ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB);
/* Init phy */
if (!strcmp(getenv("usb_phy_type"), "utmi"))
@@ -58,13 +58,13 @@ int ehci_hcd_init(void)
out_le32(&(hcor->or_portsc[0]), PORT_PTS_ULPI);
/* Enable interface. */
- setbits_be32((void *)ehci->control, USB_EN);
+ setbits_be32(&ehci->control, USB_EN);
- out_be32((void *)ehci->prictrl, 0x0000000c);
- out_be32((void *)ehci->age_cnt_limit, 0x00000040);
- out_be32((void *)ehci->sictrl, 0x00000001);
+ out_be32(&ehci->prictrl, 0x0000000c);
+ out_be32(&ehci->age_cnt_limit, 0x00000040);
+ out_be32(&ehci->sictrl, 0x00000001);
- in_le32((void *)ehci->usbmode);
+ in_le32(&ehci->usbmode);
return 0;
}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index bbd547b..423ea5d 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -716,7 +716,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
goto unknown;
}
/* unblock posted writes */
- ehci_readl(&hcor->or_usbcmd);
+ (void) ehci_readl(&hcor->or_usbcmd);
break;
case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
reg = ehci_readl(status_reg);
@@ -745,7 +745,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
}
ehci_writel(status_reg, reg);
/* unblock posted write */
- ehci_readl(&hcor->or_usbcmd);
+ (void) ehci_readl(&hcor->or_usbcmd);
break;
default:
debug("Unknown request\n");
diff --git a/drivers/usb/host/ehci-kirkwood.c b/drivers/usb/host/ehci-kirkwood.c
new file mode 100644
index 0000000..64997b8
--- /dev/null
+++ b/drivers/usb/host/ehci-kirkwood.c
@@ -0,0 +1,108 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <usb.h>
+#include "ehci.h"
+#include "ehci-core.h"
+#include <asm/arch/kirkwood.h>
+
+#define rdl(off) readl(KW_USB20_BASE + (off))
+#define wrl(off, val) writel((val), KW_USB20_BASE + (off))
+
+#define USB_WINDOW_CTRL(i) (0x320 + ((i) << 4))
+#define USB_WINDOW_BASE(i) (0x324 + ((i) << 4))
+#define USB_TARGET_DRAM 0x0
+
+/*
+ * USB 2.0 Bridge Address Decoding registers setup
+ */
+static void usb_brg_adrdec_setup(void)
+{
+ int i;
+ u32 size, attrib;
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+
+ /* Enable DRAM bank */
+ switch (i) {
+ case 0:
+ attrib = KWCPU_ATTR_DRAM_CS0;
+ break;
+ case 1:
+ attrib = KWCPU_ATTR_DRAM_CS1;
+ break;
+ case 2:
+ attrib = KWCPU_ATTR_DRAM_CS2;
+ break;
+ case 3:
+ attrib = KWCPU_ATTR_DRAM_CS3;
+ break;
+ default:
+ /* invalide bank, disable access */
+ attrib = 0;
+ break;
+ }
+
+ size = kw_sdram_bs(i);
+ if ((size) && (attrib))
+ wrl(USB_WINDOW_CTRL(i),
+ KWCPU_WIN_CTRL_DATA(size, USB_TARGET_DRAM,
+ attrib, KWCPU_WIN_ENABLE));
+ else
+ wrl(USB_WINDOW_CTRL(i), KWCPU_WIN_DISABLE);
+
+ wrl(USB_WINDOW_BASE(i), kw_sdram_bar(i));
+ }
+}
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init(void)
+{
+ usb_brg_adrdec_setup();
+
+ hccr = (struct ehci_hccr *)(KW_USB20_BASE + 0x100);
+ hcor = (struct ehci_hcor *)((uint32_t) hccr
+ + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ debug("Kirkwood-ehci: init hccr %x and hcor %x hc_length %d\n",
+ (uint32_t)hccr, (uint32_t)hcor,
+ (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop(void)
+{
+ return 0;
+}
+
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index b81c536..f9da3f0 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -307,10 +307,4 @@ extern void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt);
extern void write_fifo(u8 ep, u32 length, void *fifo_data);
extern void read_fifo(u8 ep, u32 length, void *fifo_data);
-/* extern functions */
-extern inline void musb_writew(u32 offset, u16 value);
-extern inline void musb_writeb(u32 offset, u8 value);
-extern inline u16 musb_readw(u32 offset);
-extern inline u8 musb_readb(u32 offset);
-
#endif /* __MUSB_HDRC_DEFS_H__ */
diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c
index 352a0d4..19d978b 100644
--- a/drivers/usb/musb/musb_hcd.c
+++ b/drivers/usb/musb/musb_hcd.c
@@ -111,6 +111,7 @@ static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask)
{
u16 csr;
int result = 1;
+ int timeout = CONFIG_MUSB_TIMEOUT;
while (result > 0) {
csr = readw(&musbr->txcsr);
@@ -152,7 +153,17 @@ static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask)
}
break;
}
+
+ /* Check the timeout */
+ if (--timeout)
+ udelay(1);
+ else {
+ dev->status = USB_ST_CRC_ERR;
+ result = -1;
+ break;
+ }
}
+
return result;
}
@@ -162,6 +173,7 @@ static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask)
static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep)
{
u16 csr;
+ int timeout = CONFIG_MUSB_TIMEOUT;
do {
if (check_stall(ep, 1)) {
@@ -174,6 +186,15 @@ static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep)
dev->status = USB_ST_CRC_ERR;
return 0;
}
+
+ /* Check the timeout */
+ if (--timeout)
+ udelay(1);
+ else {
+ dev->status = USB_ST_CRC_ERR;
+ return -1;
+ }
+
} while (csr & MUSB_TXCSR_TXPKTRDY);
return 1;
}
@@ -184,6 +205,7 @@ static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep)
static u8 wait_until_rxep_ready(struct usb_device *dev, u8 ep)
{
u16 csr;
+ int timeout = CONFIG_MUSB_TIMEOUT;
do {
if (check_stall(ep, 0)) {
@@ -196,6 +218,15 @@ static u8 wait_until_rxep_ready(struct usb_device *dev, u8 ep)
dev->status = USB_ST_CRC_ERR;
return 0;
}
+
+ /* Check the timeout */
+ if (--timeout)
+ udelay(1);
+ else {
+ dev->status = USB_ST_CRC_ERR;
+ return -1;
+ }
+
} while (!(csr & MUSB_RXCSR_RXPKTRDY));
return 1;
}
diff --git a/drivers/usb/musb/musb_hcd.h b/drivers/usb/musb/musb_hcd.h
index bb83311..b7f571d 100644
--- a/drivers/usb/musb/musb_hcd.h
+++ b/drivers/usb/musb/musb_hcd.h
@@ -30,6 +30,10 @@
extern unsigned char new[];
#endif
+#ifndef CONFIG_MUSB_TIMEOUT
+# define CONFIG_MUSB_TIMEOUT 100000
+#endif
+
/* This defines the endpoint number used for control transfers */
#define MUSB_CONTROL_EP 0