summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-10-11 01:20:30 +0200
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-10-11 01:20:30 +0200
commit790af815436bc6a93e4c581840be2419897f23b1 (patch)
tree1ba0aaacad86092aea67d3612ae066b33b117619 /drivers
parentd0b3723034aa865b8618428739efe1d98b1a2e2b (diff)
parentdb67801bf92f7fae6131dbc0d387131698fb9490 (diff)
downloadblackbird-obmc-uboot-790af815436bc6a93e4c581840be2419897f23b1.tar.gz
blackbird-obmc-uboot-790af815436bc6a93e4c581840be2419897f23b1.zip
Merge branch 'u-boot/master' into 'u-boot-arm/master'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ahci.c1
-rw-r--r--drivers/fpga/Makefile1
-rw-r--r--drivers/fpga/altera.c308
-rw-r--r--drivers/fpga/socfpga.c301
-rw-r--r--drivers/mmc/bfin_sdh.c7
-rw-r--r--drivers/mmc/dw_mmc.c34
-rw-r--r--drivers/mmc/mmc.c18
-rw-r--r--drivers/mmc/mvebu_mmc.c62
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c15
-rw-r--r--drivers/mtd/cfi_flash.c2
-rw-r--r--drivers/mtd/nand/denali.c12
-rw-r--r--drivers/net/designware.c46
-rw-r--r--drivers/net/phy/micrel.c7
-rw-r--r--drivers/serial/serial-uclass.c2
-rw-r--r--drivers/usb/gadget/ci_udc.c5
-rw-r--r--drivers/usb/gadget/f_dfu.c11
-rw-r--r--drivers/usb/gadget/f_fastboot.c28
-rw-r--r--drivers/usb/gadget/f_mass_storage.c1
-rw-r--r--drivers/usb/gadget/f_thor.c10
-rw-r--r--drivers/usb/host/ehci-hcd.c65
-rw-r--r--drivers/usb/host/ehci-tegra.c4
-rw-r--r--drivers/usb/host/ehci.h1
-rw-r--r--drivers/usb/musb-new/musb_core.c2
23 files changed, 654 insertions, 289 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index dce99adc6b..a93a8e1c04 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -229,7 +229,6 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
* already be on in the command register.
*/
cmd = readl(port_mmio + PORT_CMD);
- cmd |= PORT_CMD_FIS_RX;
cmd |= PORT_CMD_SPIN_UP;
writel_with_flush(cmd, port_mmio + PORT_CMD);
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index dfb2e7fc76..6aa24d4359 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -17,4 +17,5 @@ obj-y += altera.o
obj-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o
obj-$(CONFIG_FPGA_CYCLON2) += cyclon2.o
obj-$(CONFIG_FPGA_STRATIX_II) += stratixII.o
+obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o
endif
diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c
index 6e34a8e56e..a5bfe5dce1 100644
--- a/drivers/fpga/altera.c
+++ b/drivers/fpga/altera.c
@@ -12,216 +12,162 @@
* Altera FPGA support
*/
#include <common.h>
+#include <errno.h>
#include <ACEX1K.h>
#include <stratixII.h>
-/* Define FPGA_DEBUG to get debug printf's */
-/* #define FPGA_DEBUG */
+/* Define FPGA_DEBUG to 1 to get debug printf's */
+#define FPGA_DEBUG 0
-#ifdef FPGA_DEBUG
-#define PRINTF(fmt,args...) printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
-/* Local Static Functions */
-static int altera_validate (Altera_desc * desc, const char *fn);
-
-/* ------------------------------------------------------------------------- */
-int altera_load(Altera_desc *desc, const void *buf, size_t bsize)
-{
- int ret_val = FPGA_FAIL; /* assume a failure */
-
- if (!altera_validate (desc, (char *)__FUNCTION__)) {
- printf ("%s: Invalid device descriptor\n", __FUNCTION__);
- } else {
- switch (desc->family) {
- case Altera_ACEX1K:
- case Altera_CYC2:
+static const struct altera_fpga {
+ enum altera_family family;
+ const char *name;
+ int (*load)(Altera_desc *, const void *, size_t);
+ int (*dump)(Altera_desc *, const void *, size_t);
+ int (*info)(Altera_desc *);
+} altera_fpga[] = {
#if defined(CONFIG_FPGA_ACEX1K)
- PRINTF ("%s: Launching the ACEX1K Loader...\n",
- __FUNCTION__);
- ret_val = ACEX1K_load (desc, buf, bsize);
+ { Altera_ACEX1K, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info },
+ { Altera_CYC2, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info },
#elif defined(CONFIG_FPGA_CYCLON2)
- PRINTF ("%s: Launching the CYCLONE II Loader...\n",
- __FUNCTION__);
- ret_val = CYC2_load (desc, buf, bsize);
-#else
- printf ("%s: No support for ACEX1K devices.\n",
- __FUNCTION__);
+ { Altera_ACEX1K, "CycloneII", CYC2_load, CYC2_dump, CYC2_info },
+ { Altera_CYC2, "CycloneII", CYC2_load, CYC2_dump, CYC2_info },
#endif
- break;
-
#if defined(CONFIG_FPGA_STRATIX_II)
- case Altera_StratixII:
- PRINTF ("%s: Launching the Stratix II Loader...\n",
- __FUNCTION__);
- ret_val = StratixII_load (desc, buf, bsize);
- break;
+ { Altera_StratixII, "StratixII", StratixII_load,
+ StratixII_dump, StratixII_info },
+#endif
+#if defined(CONFIG_FPGA_SOCFPGA)
+ { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL },
#endif
- default:
- printf ("%s: Unsupported family type, %d\n",
- __FUNCTION__, desc->family);
- }
+};
+
+static int altera_validate(Altera_desc *desc, const char *fn)
+{
+ if (!desc) {
+ printf("%s: NULL descriptor!\n", fn);
+ return -EINVAL;
+ }
+
+ if ((desc->family < min_altera_type) ||
+ (desc->family > max_altera_type)) {
+ printf("%s: Invalid family type, %d\n", fn, desc->family);
+ return -EINVAL;
+ }
+
+ if ((desc->iface < min_altera_iface_type) ||
+ (desc->iface > max_altera_iface_type)) {
+ printf("%s: Invalid Interface type, %d\n", fn, desc->iface);
+ return -EINVAL;
}
- return ret_val;
+ if (!desc->size) {
+ printf("%s: NULL part size\n", fn);
+ return -EINVAL;
+ }
+
+ return 0;
}
-int altera_dump(Altera_desc *desc, const void *buf, size_t bsize)
+static const struct altera_fpga *
+altera_desc_to_fpga(Altera_desc *desc, const char *fn)
{
- int ret_val = FPGA_FAIL; /* assume a failure */
+ int i;
- if (!altera_validate (desc, (char *)__FUNCTION__)) {
- printf ("%s: Invalid device descriptor\n", __FUNCTION__);
- } else {
- switch (desc->family) {
- case Altera_ACEX1K:
-#if defined(CONFIG_FPGA_ACEX)
- PRINTF ("%s: Launching the ACEX1K Reader...\n",
- __FUNCTION__);
- ret_val = ACEX1K_dump (desc, buf, bsize);
-#else
- printf ("%s: No support for ACEX1K devices.\n",
- __FUNCTION__);
-#endif
- break;
+ if (altera_validate(desc, fn)) {
+ printf("%s: Invalid device descriptor\n", fn);
+ return NULL;
+ }
-#if defined(CONFIG_FPGA_STRATIX_II)
- case Altera_StratixII:
- PRINTF ("%s: Launching the Stratix II Reader...\n",
- __FUNCTION__);
- ret_val = StratixII_dump (desc, buf, bsize);
+ for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) {
+ if (desc->family == altera_fpga[i].family)
break;
-#endif
- default:
- printf ("%s: Unsupported family type, %d\n",
- __FUNCTION__, desc->family);
- }
}
- return ret_val;
+ if (i == ARRAY_SIZE(altera_fpga)) {
+ printf("%s: Unsupported family type, %d\n", fn, desc->family);
+ return NULL;
+ }
+
+ return &altera_fpga[i];
}
-int altera_info( Altera_desc *desc )
+int altera_load(Altera_desc *desc, const void *buf, size_t bsize)
{
- int ret_val = FPGA_FAIL;
+ const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
- if (altera_validate (desc, (char *)__FUNCTION__)) {
- printf ("Family: \t");
- switch (desc->family) {
- case Altera_ACEX1K:
- printf ("ACEX1K\n");
- break;
- case Altera_CYC2:
- printf ("CYCLON II\n");
- break;
- case Altera_StratixII:
- printf ("Stratix II\n");
- break;
- /* Add new family types here */
- default:
- printf ("Unknown family type, %d\n", desc->family);
- }
-
- printf ("Interface type:\t");
- switch (desc->iface) {
- case passive_serial:
- printf ("Passive Serial (PS)\n");
- break;
- case passive_parallel_synchronous:
- printf ("Passive Parallel Synchronous (PPS)\n");
- break;
- case passive_parallel_asynchronous:
- printf ("Passive Parallel Asynchronous (PPA)\n");
- break;
- case passive_serial_asynchronous:
- printf ("Passive Serial Asynchronous (PSA)\n");
- break;
- case altera_jtag_mode: /* Not used */
- printf ("JTAG Mode\n");
- break;
- case fast_passive_parallel:
- printf ("Fast Passive Parallel (FPP)\n");
- break;
- case fast_passive_parallel_security:
- printf
- ("Fast Passive Parallel with Security (FPPS) \n");
- break;
- /* Add new interface types here */
- default:
- printf ("Unsupported interface type, %d\n", desc->iface);
- }
-
- printf("Device Size: \t%zd bytes\n"
- "Cookie: \t0x%x (%d)\n",
- desc->size, desc->cookie, desc->cookie);
-
- if (desc->iface_fns) {
- printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
- switch (desc->family) {
- case Altera_ACEX1K:
- case Altera_CYC2:
-#if defined(CONFIG_FPGA_ACEX1K)
- ACEX1K_info (desc);
-#elif defined(CONFIG_FPGA_CYCLON2)
- CYC2_info (desc);
-#else
- /* just in case */
- printf ("%s: No support for ACEX1K devices.\n",
- __FUNCTION__);
-#endif
- break;
-#if defined(CONFIG_FPGA_STRATIX_II)
- case Altera_StratixII:
- StratixII_info (desc);
- break;
-#endif
- /* Add new family types here */
- default:
- /* we don't need a message here - we give one up above */
- break;
- }
- } else {
- printf ("No Device Function Table.\n");
- }
-
- ret_val = FPGA_SUCCESS;
- } else {
- printf ("%s: Invalid device descriptor\n", __FUNCTION__);
- }
+ if (!fpga)
+ return FPGA_FAIL;
- return ret_val;
+ debug_cond(FPGA_DEBUG, "%s: Launching the %s Loader...\n",
+ __func__, fpga->name);
+ if (fpga->load)
+ return fpga->load(desc, buf, bsize);
+ return 0;
}
-/* ------------------------------------------------------------------------- */
+int altera_dump(Altera_desc *desc, const void *buf, size_t bsize)
+{
+ const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
+
+ if (!fpga)
+ return FPGA_FAIL;
-static int altera_validate (Altera_desc * desc, const char *fn)
+ debug_cond(FPGA_DEBUG, "%s: Launching the %s Reader...\n",
+ __func__, fpga->name);
+ if (fpga->dump)
+ return fpga->dump(desc, buf, bsize);
+ return 0;
+}
+
+int altera_info(Altera_desc *desc)
{
- int ret_val = false;
-
- if (desc) {
- if ((desc->family > min_altera_type) &&
- (desc->family < max_altera_type)) {
- if ((desc->iface > min_altera_iface_type) &&
- (desc->iface < max_altera_iface_type)) {
- if (desc->size) {
- ret_val = true;
- } else {
- printf ("%s: NULL part size\n", fn);
- }
- } else {
- printf ("%s: Invalid Interface type, %d\n",
- fn, desc->iface);
- }
- } else {
- printf ("%s: Invalid family type, %d\n", fn, desc->family);
- }
+ const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
+
+ if (!fpga)
+ return FPGA_FAIL;
+
+ printf("Family: \t%s\n", fpga->name);
+
+ printf("Interface type:\t");
+ switch (desc->iface) {
+ case passive_serial:
+ printf("Passive Serial (PS)\n");
+ break;
+ case passive_parallel_synchronous:
+ printf("Passive Parallel Synchronous (PPS)\n");
+ break;
+ case passive_parallel_asynchronous:
+ printf("Passive Parallel Asynchronous (PPA)\n");
+ break;
+ case passive_serial_asynchronous:
+ printf("Passive Serial Asynchronous (PSA)\n");
+ break;
+ case altera_jtag_mode: /* Not used */
+ printf("JTAG Mode\n");
+ break;
+ case fast_passive_parallel:
+ printf("Fast Passive Parallel (FPP)\n");
+ break;
+ case fast_passive_parallel_security:
+ printf("Fast Passive Parallel with Security (FPPS)\n");
+ break;
+ /* Add new interface types here */
+ default:
+ printf("Unsupported interface type, %d\n", desc->iface);
+ }
+
+ printf("Device Size: \t%zd bytes\n"
+ "Cookie: \t0x%x (%d)\n",
+ desc->size, desc->cookie, desc->cookie);
+
+ if (desc->iface_fns) {
+ printf("Device Function Table @ 0x%p\n", desc->iface_fns);
+ if (fpga->info)
+ fpga->info(desc);
} else {
- printf ("%s: NULL descriptor!\n", fn);
+ printf("No Device Function Table.\n");
}
- return ret_val;
+ return FPGA_SUCCESS;
}
-
-/* ------------------------------------------------------------------------- */
diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
new file mode 100644
index 0000000000..63b3566e3e
--- /dev/null
+++ b/drivers/fpga/socfpga.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/fpga_manager.h>
+#include <asm/arch/reset_manager.h>
+#include <asm/arch/system_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Timeout count */
+#define FPGA_TIMEOUT_CNT 0x1000000
+
+static struct socfpga_fpga_manager *fpgamgr_regs =
+ (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS;
+static struct socfpga_system_manager *sysmgr_regs =
+ (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
+
+/* Set CD ratio */
+static void fpgamgr_set_cd_ratio(unsigned long ratio)
+{
+ clrsetbits_le32(&fpgamgr_regs->ctrl,
+ 0x3 << FPGAMGRREGS_CTRL_CDRATIO_LSB,
+ (ratio & 0x3) << FPGAMGRREGS_CTRL_CDRATIO_LSB);
+}
+
+static int fpgamgr_dclkcnt_set(unsigned long cnt)
+{
+ unsigned long i;
+
+ /* Clear any existing done status */
+ if (readl(&fpgamgr_regs->dclkstat))
+ writel(0x1, &fpgamgr_regs->dclkstat);
+
+ /* Write the dclkcnt */
+ writel(cnt, &fpgamgr_regs->dclkcnt);
+
+ /* Wait till the dclkcnt done */
+ for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+ if (!readl(&fpgamgr_regs->dclkstat))
+ continue;
+
+ writel(0x1, &fpgamgr_regs->dclkstat);
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+/* Start the FPGA programming by initialize the FPGA Manager */
+static int fpgamgr_program_init(void)
+{
+ unsigned long msel, i;
+
+ /* Get the MSEL value */
+ msel = readl(&fpgamgr_regs->stat);
+ msel &= FPGAMGRREGS_STAT_MSEL_MASK;
+ msel >>= FPGAMGRREGS_STAT_MSEL_LSB;
+
+ /*
+ * Set the cfg width
+ * If MSEL[3] = 1, cfg width = 32 bit
+ */
+ if (msel & 0x8) {
+ setbits_le32(&fpgamgr_regs->ctrl,
+ FPGAMGRREGS_CTRL_CFGWDTH_MASK);
+
+ /* To determine the CD ratio */
+ /* MSEL[1:0] = 0, CD Ratio = 1 */
+ if ((msel & 0x3) == 0x0)
+ fpgamgr_set_cd_ratio(CDRATIO_x1);
+ /* MSEL[1:0] = 1, CD Ratio = 4 */
+ else if ((msel & 0x3) == 0x1)
+ fpgamgr_set_cd_ratio(CDRATIO_x4);
+ /* MSEL[1:0] = 2, CD Ratio = 8 */
+ else if ((msel & 0x3) == 0x2)
+ fpgamgr_set_cd_ratio(CDRATIO_x8);
+
+ } else { /* MSEL[3] = 0 */
+ clrbits_le32(&fpgamgr_regs->ctrl,
+ FPGAMGRREGS_CTRL_CFGWDTH_MASK);
+
+ /* To determine the CD ratio */
+ /* MSEL[1:0] = 0, CD Ratio = 1 */
+ if ((msel & 0x3) == 0x0)
+ fpgamgr_set_cd_ratio(CDRATIO_x1);
+ /* MSEL[1:0] = 1, CD Ratio = 2 */
+ else if ((msel & 0x3) == 0x1)
+ fpgamgr_set_cd_ratio(CDRATIO_x2);
+ /* MSEL[1:0] = 2, CD Ratio = 4 */
+ else if ((msel & 0x3) == 0x2)
+ fpgamgr_set_cd_ratio(CDRATIO_x4);
+ }
+
+ /* To enable FPGA Manager configuration */
+ clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCE_MASK);
+
+ /* To enable FPGA Manager drive over configuration line */
+ setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK);
+
+ /* Put FPGA into reset phase */
+ setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK);
+
+ /* (1) wait until FPGA enter reset phase */
+ for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+ if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_RESETPHASE)
+ break;
+ }
+
+ /* If not in reset state, return error */
+ if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_RESETPHASE) {
+ puts("FPGA: Could not reset\n");
+ return -1;
+ }
+
+ /* Release FPGA from reset phase */
+ clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK);
+
+ /* (2) wait until FPGA enter configuration phase */
+ for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+ if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_CFGPHASE)
+ break;
+ }
+
+ /* If not in configuration state, return error */
+ if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_CFGPHASE) {
+ puts("FPGA: Could not configure\n");
+ return -2;
+ }
+
+ /* Clear all interrupts in CB Monitor */
+ writel(0xFFF, &fpgamgr_regs->gpio_porta_eoi);
+
+ /* Enable AXI configuration */
+ setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK);
+
+ return 0;
+}
+
+/* Write the RBF data to FPGA Manager */
+static void fpgamgr_program_write(const void *rbf_data, unsigned long rbf_size)
+{
+ uint32_t src = (uint32_t)rbf_data;
+ uint32_t dst = SOCFPGA_FPGAMGRDATA_ADDRESS;
+
+ /* Number of loops for 32-byte long copying. */
+ uint32_t loops32 = rbf_size / 32;
+ /* Number of loops for 4-byte long copying + trailing bytes */
+ uint32_t loops4 = DIV_ROUND_UP(rbf_size % 32, 4);
+
+ asm volatile(
+ "1: ldmia %0!, {r0-r7}\n"
+ " stmia %1!, {r0-r7}\n"
+ " sub %1, #32\n"
+ " subs %2, #1\n"
+ " bne 1b\n"
+ "2: ldr %2, [%0], #4\n"
+ " str %2, [%1]\n"
+ " subs %3, #1\n"
+ " bne 2b\n"
+ : "+r"(src), "+r"(dst), "+r"(loops32), "+r"(loops4) :
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "cc");
+}
+
+/* Ensure the FPGA entering config done */
+static int fpgamgr_program_poll_cd(void)
+{
+ const uint32_t mask = FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK |
+ FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK;
+ unsigned long reg, i;
+
+ /* (3) wait until full config done */
+ for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+ reg = readl(&fpgamgr_regs->gpio_ext_porta);
+
+ /* Config error */
+ if (!(reg & mask)) {
+ printf("FPGA: Configuration error.\n");
+ return -3;
+ }
+
+ /* Config done without error */
+ if (reg & mask)
+ break;
+ }
+
+ /* Timeout happened, return error */
+ if (i == FPGA_TIMEOUT_CNT) {
+ printf("FPGA: Timeout waiting for program.\n");
+ return -4;
+ }
+
+ /* Disable AXI configuration */
+ clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK);
+
+ return 0;
+}
+
+/* Ensure the FPGA entering init phase */
+static int fpgamgr_program_poll_initphase(void)
+{
+ unsigned long i;
+
+ /* Additional clocks for the CB to enter initialization phase */
+ if (fpgamgr_dclkcnt_set(0x4))
+ return -5;
+
+ /* (4) wait until FPGA enter init phase or user mode */
+ for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+ if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_INITPHASE)
+ break;
+ if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE)
+ break;
+ }
+
+ /* If not in configuration state, return error */
+ if (i == FPGA_TIMEOUT_CNT)
+ return -6;
+
+ return 0;
+}
+
+/* Ensure the FPGA entering user mode */
+static int fpgamgr_program_poll_usermode(void)
+{
+ unsigned long i;
+
+ /* Additional clocks for the CB to exit initialization phase */
+ if (fpgamgr_dclkcnt_set(0x5000))
+ return -7;
+
+ /* (5) wait until FPGA enter user mode */
+ for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+ if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE)
+ break;
+ }
+ /* If not in configuration state, return error */
+ if (i == FPGA_TIMEOUT_CNT)
+ return -8;
+
+ /* To release FPGA Manager drive over configuration line */
+ clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK);
+
+ return 0;
+}
+
+/*
+ * FPGA Manager to program the FPGA. This is the interface used by FPGA driver.
+ * Return 0 for sucess, non-zero for error.
+ */
+int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
+{
+ unsigned long status;
+
+ if ((uint32_t)rbf_data & 0x3) {
+ puts("FPGA: Unaligned data, realign to 32bit boundary.\n");
+ return -EINVAL;
+ }
+
+ /* Prior programming the FPGA, all bridges need to be shut off */
+
+ /* Disable all signals from hps peripheral controller to fpga */
+ writel(0, &sysmgr_regs->fpgaintfgrp_module);
+
+ /* Disable all signals from FPGA to HPS SDRAM */
+#define SDR_CTRLGRP_FPGAPORTRST_ADDRESS 0x5080
+ writel(0, SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS);
+
+ /* Disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
+ socfpga_bridges_reset(1);
+
+ /* Unmap the bridges from NIC-301 */
+ writel(0x1, SOCFPGA_L3REGS_ADDRESS);
+
+ /* Initialize the FPGA Manager */
+ status = fpgamgr_program_init();
+ if (status)
+ return status;
+
+ /* Write the RBF data to FPGA Manager */
+ fpgamgr_program_write(rbf_data, rbf_size);
+
+ /* Ensure the FPGA entering config done */
+ status = fpgamgr_program_poll_cd();
+ if (status)
+ return status;
+
+ /* Ensure the FPGA entering init phase */
+ status = fpgamgr_program_poll_initphase();
+ if (status)
+ return status;
+
+ /* Ensure the FPGA entering user mode */
+ return fpgamgr_program_poll_usermode();
+}
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c
index bcd6a3e52f..9bdfbbca01 100644
--- a/drivers/mmc/bfin_sdh.c
+++ b/drivers/mmc/bfin_sdh.c
@@ -138,9 +138,9 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)
if (data->flags & MMC_DATA_WRITE)
return UNUSABLE_ERR;
#ifndef RSI_BLKSZ
- data_ctl |= ((ffs(data_size) - 1) << 4);
+ data_ctl |= ((ffs(data->blocksize) - 1) << 4);
#else
- bfin_write_SDH_BLK_SIZE(data_size);
+ bfin_write_SDH_BLK_SIZE(data->blocksize);
#endif
data_ctl |= DTX_DIR;
bfin_write_SDH_DATA_CTL(data_ctl);
@@ -189,7 +189,8 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd,
do {
udelay(1);
status = bfin_read_SDH_STATUS();
- } while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN)));
+ } while (!(status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL |
+ RX_OVERRUN)));
if (status & DAT_TIME_OUT) {
bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT);
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 0df30bc045..785eed567c 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -119,7 +119,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
if (get_timer(start) > timeout) {
- printf("Timeout on data busy\n");
+ printf("%s: Timeout on data busy\n", __func__);
return TIMEOUT;
}
}
@@ -177,14 +177,24 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
}
}
- if (i == retry)
+ if (i == retry) {
+ printf("%s: Timeout.\n", __func__);
return TIMEOUT;
+ }
if (mask & DWMCI_INTMSK_RTO) {
- debug("Response Timeout..\n");
+ /*
+ * Timeout here is not necessarily fatal. (e)MMC cards
+ * will splat here when they receive CMD55 as they do
+ * not support this command and that is exactly the way
+ * to tell them apart from SD cards. Thus, this output
+ * below shall be debug(). eMMC cards also do not favor
+ * CMD8, please keep that in mind.
+ */
+ debug("%s: Response Timeout.\n", __func__);
return TIMEOUT;
} else if (mask & DWMCI_INTMSK_RE) {
- debug("Response Error..\n");
+ printf("%s: Response Error.\n", __func__);
return -1;
}
@@ -204,7 +214,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
do {
mask = dwmci_readl(host, DWMCI_RINTSTS);
if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
- debug("DATA ERROR!\n");
+ printf("%s: DATA ERROR!\n", __func__);
return -1;
}
} while (!(mask & DWMCI_INTMSK_DTO));
@@ -232,16 +242,16 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
if ((freq == host->clock) || (freq == 0))
return 0;
/*
- * If host->get_mmc_clk didn't define,
+ * If host->get_mmc_clk isn't defined,
* then assume that host->bus_hz is source clock value.
- * host->bus_hz should be set from user.
+ * host->bus_hz should be set by user.
*/
if (host->get_mmc_clk)
sclk = host->get_mmc_clk(host);
else if (host->bus_hz)
sclk = host->bus_hz;
else {
- printf("Didn't get source clock value..\n");
+ printf("%s: Didn't get source clock value.\n", __func__);
return -EINVAL;
}
@@ -260,7 +270,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
do {
status = dwmci_readl(host, DWMCI_CMD);
if (timeout-- < 0) {
- printf("TIMEOUT error!!\n");
+ printf("%s: Timeout!\n", __func__);
return -ETIMEDOUT;
}
} while (status & DWMCI_CMD_START);
@@ -275,7 +285,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
do {
status = dwmci_readl(host, DWMCI_CMD);
if (timeout-- < 0) {
- printf("TIMEOUT error!!\n");
+ printf("%s: Timeout!\n", __func__);
return -ETIMEDOUT;
}
} while (status & DWMCI_CMD_START);
@@ -290,7 +300,7 @@ static void dwmci_set_ios(struct mmc *mmc)
struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
u32 ctype, regs;
- debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock);
+ debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock);
dwmci_setup_bus(host, mmc->clock);
switch (mmc->bus_width) {
@@ -329,7 +339,7 @@ static int dwmci_init(struct mmc *mmc)
dwmci_writel(host, DWMCI_PWREN, 1);
if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
- debug("%s[%d] Fail-reset!!\n",__func__,__LINE__);
+ printf("%s[%d] Fail-reset!!\n", __func__, __LINE__);
return -1;
}
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index a26f3cec20..44a4feb96e 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -594,10 +594,15 @@ int mmc_switch_part(int dev_num, unsigned int part_num)
ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
(mmc->part_config & ~PART_ACCESS_MASK)
| (part_num & PART_ACCESS_MASK));
- if (ret)
- return ret;
- return mmc_set_capacity(mmc, part_num);
+ /*
+ * Set the capacity if the switch succeeded or was intended
+ * to return to representing the raw device.
+ */
+ if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
+ ret = mmc_set_capacity(mmc, part_num);
+
+ return ret;
}
int mmc_getcd(struct mmc *mmc)
@@ -1010,6 +1015,8 @@ static int mmc_startup(struct mmc *mmc)
if (err)
return err;
+ else
+ ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
/* Read out group size from ext_csd */
mmc->erase_grp_size =
@@ -1127,10 +1134,11 @@ static int mmc_startup(struct mmc *mmc)
mmc_set_bus_width(mmc, widths[idx]);
err = mmc_send_ext_csd(mmc, test_csd);
+ /* Only compare read only fields */
if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
== test_csd[EXT_CSD_PARTITIONING_SUPPORT]
- && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
- == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
+ && ext_csd[EXT_CSD_HC_WP_GRP_SIZE] \
+ == test_csd[EXT_CSD_HC_WP_GRP_SIZE] \
&& ext_csd[EXT_CSD_REV] \
== test_csd[EXT_CSD_REV]
&& ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 97591983d2..d34e74357f 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -17,8 +17,12 @@
#include <asm/arch/kirkwood.h>
#include <mvebu_mmc.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#define DRIVER_NAME "MVEBU_MMC"
+#define MVEBU_TARGET_DRAM 0
+
static void mvebu_mmc_write(u32 offs, u32 val)
{
writel(val, CONFIG_SYS_MMC_BASE + (offs));
@@ -164,6 +168,9 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
return TIMEOUT;
}
}
+ if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
+ (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
+ return TIMEOUT;
/* Handling response */
if (cmd->resp_type & MMC_RSP_136) {
@@ -271,6 +278,7 @@ static void mvebu_mmc_set_bus(unsigned int bus)
/* default to maximum timeout */
ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
+ ctrl_reg |= SDIO_HOST_CTRL_TMOUT_EN;
ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN;
@@ -296,6 +304,55 @@ static void mvebu_mmc_set_ios(struct mmc *mmc)
mvebu_mmc_set_clk(mmc->clock);
}
+/*
+ * Set window register.
+ */
+static void mvebu_window_setup(void)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ mvebu_mmc_write(WINDOW_CTRL(i), 0);
+ mvebu_mmc_write(WINDOW_BASE(i), 0);
+ }
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ u32 size, base, attrib;
+
+ /* 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 = gd->bd->bi_dram[i].size;
+ base = gd->bd->bi_dram[i].start;
+ if (size && attrib) {
+ mvebu_mmc_write(WINDOW_CTRL(i),
+ MVCPU_WIN_CTRL_DATA(size,
+ MVEBU_TARGET_DRAM,
+ attrib,
+ MVCPU_WIN_ENABLE));
+ } else {
+ mvebu_mmc_write(WINDOW_CTRL(i), MVCPU_WIN_DISABLE);
+ }
+ mvebu_mmc_write(WINDOW_BASE(i), base);
+ }
+}
+
static int mvebu_mmc_initialize(struct mmc *mmc)
{
debug("%s: mvebu_mmc_initialize", DRIVER_NAME);
@@ -322,6 +379,8 @@ static int mvebu_mmc_initialize(struct mmc *mmc)
mvebu_mmc_write(SDIO_NOR_INTR_EN, 0);
mvebu_mmc_write(SDIO_ERR_INTR_EN, 0);
+ mvebu_window_setup();
+
/* SW reset */
mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
@@ -342,7 +401,8 @@ static struct mmc_config mvebu_mmc_cfg = {
.f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
.f_max = MVEBU_MMC_CLOCKRATE_MAX,
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
- .host_caps = MMC_MODE_4BIT | MMC_MODE_HS,
+ .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC |
+ MMC_MODE_HS_52MHz,
.part_type = PART_TYPE_DOS,
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
};
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index 1f96382dea..eb69aed9df 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <malloc.h>
#include <dwmmc.h>
+#include <errno.h>
#include <asm/arch/dwmmc.h>
#include <asm/arch/clock_manager.h>
#include <asm/arch/system_manager.h>
@@ -44,12 +45,18 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host)
int socfpga_dwmmc_init(u32 regbase, int bus_width, int index)
{
struct dwmci_host *host;
+ unsigned long clk = cm_get_mmc_controller_clk_hz();
+
+ if (clk == 0) {
+ printf("%s: MMC clock is zero!", __func__);
+ return -EINVAL;
+ }
/* calloc for zero init */
- host = calloc(sizeof(struct dwmci_host), 1);
+ host = calloc(1, sizeof(struct dwmci_host));
if (!host) {
- printf("dwmci_host calloc fail!\n");
- return -1;
+ printf("%s: calloc() failed!\n", __func__);
+ return -ENOMEM;
}
host->name = "SOCFPGA DWMMC";
@@ -58,7 +65,7 @@ int socfpga_dwmmc_init(u32 regbase, int bus_width, int index)
host->clksel = socfpga_dwmci_clksel;
host->dev_index = index;
/* fixed clock divide by 4 which due to the SDMMC wrapper */
- host->bus_hz = CONFIG_SOCFPGA_DWMMC_BUS_HZ;
+ host->bus_hz = clk;
host->fifoth_val = MSIZE(0x2) |
RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) |
TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2);
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index c4b5bc1de5..9b3175d87f 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -593,7 +593,7 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
case CFI_CMDSET_INTEL_PROG_REGIONS:
case CFI_CMDSET_INTEL_EXTENDED:
case CFI_CMDSET_INTEL_STANDARD:
- if ((retcode != ERR_OK)
+ if ((retcode == ERR_OK)
&& !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
retcode = ERR_INVAL;
printf ("Flash %s error at address %lx\n", prompt,
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index ba3de1a635..308b7845f1 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1059,9 +1059,8 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
addr = MODE_11 | BANK(denali->flash_bank);
index_addr(denali, addr | 0, cmd);
break;
- case NAND_CMD_PARAM:
- clear_interrupts(denali);
case NAND_CMD_READID:
+ case NAND_CMD_PARAM:
reset_buf(denali);
/* sometimes ManufactureId read from register is not right
* e.g. some of Micron MT29F32G08QAA MLC NAND chips
@@ -1070,6 +1069,15 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
addr = MODE_11 | BANK(denali->flash_bank);
index_addr(denali, addr | 0, cmd);
index_addr(denali, addr | 1, col & 0xFF);
+ if (cmd == NAND_CMD_PARAM)
+ udelay(50);
+ break;
+ case NAND_CMD_RNDOUT:
+ addr = MODE_11 | BANK(denali->flash_bank);
+ index_addr(denali, addr | 0, cmd);
+ index_addr(denali, addr | 1, col & 0xFF);
+ index_addr(denali, addr | 1, col >> 8);
+ index_addr(denali, addr | 0, NAND_CMD_RNDOUTSTART);
break;
case NAND_CMD_READ0:
case NAND_CMD_SEQIN:
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 7186e3b491..9ded8950b8 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -279,19 +279,21 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
struct eth_dma_regs *dma_p = priv->dma_regs_p;
u32 desc_num = priv->tx_currdescnum;
struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
-
+ uint32_t desc_start = (uint32_t)desc_p;
+ uint32_t desc_end = desc_start +
+ roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
+ uint32_t data_start = (uint32_t)desc_p->dmamac_addr;
+ uint32_t data_end = data_start +
+ roundup(length, ARCH_DMA_MINALIGN);
/*
* Strictly we only need to invalidate the "txrx_status" field
* for the following check, but on some platforms we cannot
- * invalidate only 4 bytes, so roundup to
- * ARCH_DMA_MINALIGN. This is safe because the individual
- * descriptors in the array are each aligned to
- * ARCH_DMA_MINALIGN.
+ * invalidate only 4 bytes, so we flush the entire descriptor,
+ * which is 16 bytes in total. This is safe because the
+ * individual descriptors in the array are each aligned to
+ * ARCH_DMA_MINALIGN and padded appropriately.
*/
- invalidate_dcache_range(
- (unsigned long)desc_p,
- (unsigned long)desc_p +
- roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN));
+ invalidate_dcache_range(desc_start, desc_end);
/* Check if the descriptor is owned by CPU */
if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
@@ -299,11 +301,10 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
return -1;
}
- memcpy((void *)desc_p->dmamac_addr, packet, length);
+ memcpy(desc_p->dmamac_addr, packet, length);
/* Flush data to be sent */
- flush_dcache_range((unsigned long)desc_p->dmamac_addr,
- (unsigned long)desc_p->dmamac_addr + length);
+ flush_dcache_range(data_start, data_end);
#if defined(CONFIG_DW_ALTDESCRIPTOR)
desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
@@ -321,8 +322,7 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
#endif
/* Flush modified buffer descriptor */
- flush_dcache_range((unsigned long)desc_p,
- (unsigned long)desc_p + sizeof(struct dmamacdescr));
+ flush_dcache_range(desc_start, desc_end);
/* Test the wrap-around condition. */
if (++desc_num >= CONFIG_TX_DESCR_NUM)
@@ -342,11 +342,14 @@ static int dw_eth_recv(struct eth_device *dev)
u32 status, desc_num = priv->rx_currdescnum;
struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
int length = 0;
+ uint32_t desc_start = (uint32_t)desc_p;
+ uint32_t desc_end = desc_start +
+ roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
+ uint32_t data_start = (uint32_t)desc_p->dmamac_addr;
+ uint32_t data_end;
/* Invalidate entire buffer descriptor */
- invalidate_dcache_range((unsigned long)desc_p,
- (unsigned long)desc_p +
- sizeof(struct dmamacdescr));
+ invalidate_dcache_range(desc_start, desc_end);
status = desc_p->txrx_status;
@@ -357,9 +360,8 @@ static int dw_eth_recv(struct eth_device *dev)
DESC_RXSTS_FRMLENSHFT;
/* Invalidate received data */
- invalidate_dcache_range((unsigned long)desc_p->dmamac_addr,
- (unsigned long)desc_p->dmamac_addr +
- roundup(length, ARCH_DMA_MINALIGN));
+ data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
+ invalidate_dcache_range(data_start, data_end);
NetReceive(desc_p->dmamac_addr, length);
@@ -370,9 +372,7 @@ static int dw_eth_recv(struct eth_device *dev)
desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
/* Flush only status field - others weren't changed */
- flush_dcache_range((unsigned long)&desc_p->txrx_status,
- (unsigned long)&desc_p->txrx_status +
- sizeof(desc_p->txrx_status));
+ flush_dcache_range(desc_start, desc_end);
/* Test the wrap-around condition. */
if (++desc_num >= CONFIG_RX_DESCR_NUM)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 5d7e3be52e..507b9a368b 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -25,8 +25,7 @@ static struct phy_driver KSZ804_driver = {
#ifndef CONFIG_PHY_MICREL_KSZ9021
/*
* I can't believe Micrel used the exact same part number
- * for the KSZ9021
- * Shame Micrel, Shame!!!!!
+ * for the KSZ9021. Shame Micrel, Shame!
*/
static struct phy_driver KS8721_driver = {
.name = "Micrel KS8721BL",
@@ -40,7 +39,7 @@ static struct phy_driver KS8721_driver = {
#endif
-/**
+/*
* KSZ9021 - KSZ9031 common
*/
@@ -69,8 +68,8 @@ static int ksz90xx_startup(struct phy_device *phydev)
phydev->speed = SPEED_10;
return 0;
}
-#ifdef CONFIG_PHY_MICREL_KSZ9021
+#ifdef CONFIG_PHY_MICREL_KSZ9021
/*
* KSZ9021
*/
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 1ac943f692..fd010cac42 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -198,7 +198,7 @@ static int serial_pre_remove(struct udevice *dev)
#ifdef CONFIG_SYS_STDIO_DEREGISTER
struct serial_dev_priv *upriv = dev->uclass_priv;
- if (stdio_deregister_dev(upriv->sdev))
+ if (stdio_deregister_dev(upriv->sdev), 0)
return -EPERM;
#endif
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index 2572b346eb..b0ef35e745 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -777,6 +777,11 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on)
/* select DEVICE mode */
writel(USBMODE_DEVICE, &udc->usbmode);
+#if !defined(CONFIG_USB_GADGET_DUALSPEED)
+ /* Port force Full-Speed Connect */
+ setbits_le32(&udc->portsc, PFSC);
+#endif
+
writel(0xffffffff, &udc->epflush);
/* Turn on the USB connection by enabling the pullup resistor */
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index 3e4f02932b..16fc9ddf82 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -81,14 +81,6 @@ static struct usb_descriptor_header *dfu_runtime_descs[] = {
NULL,
};
-static const struct usb_qualifier_descriptor dev_qualifier = {
- .bLength = sizeof dev_qualifier,
- .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
- .bDeviceClass = USB_CLASS_VENDOR_SPEC,
- .bNumConfigurations = 1,
-};
-
static const char dfu_name[] = "Device Firmware Upgrade";
/*
@@ -237,6 +229,7 @@ static inline void to_dfu_mode(struct f_dfu *f_dfu)
{
f_dfu->usb_function.strings = dfu_strings;
f_dfu->usb_function.hs_descriptors = f_dfu->function;
+ f_dfu->usb_function.descriptors = f_dfu->function;
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
}
@@ -244,6 +237,7 @@ static inline void to_runtime_mode(struct f_dfu *f_dfu)
{
f_dfu->usb_function.strings = NULL;
f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
+ f_dfu->usb_function.descriptors = dfu_runtime_descs;
}
static int handle_upload(struct usb_request *req, u16 len)
@@ -808,6 +802,7 @@ static int dfu_bind_config(struct usb_configuration *c)
return -ENOMEM;
f_dfu->usb_function.name = "dfu";
f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
+ f_dfu->usb_function.descriptors = dfu_runtime_descs;
f_dfu->usb_function.bind = dfu_bind;
f_dfu->usb_function.unbind = dfu_unbind;
f_dfu->usb_function.set_alt = dfu_set_alt;
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 38c09658cc..71b62e5005 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -351,10 +351,11 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
strncat(response, FASTBOOT_VERSION, chars_left);
} else if (!strcmp_l1("bootloader-version", cmd)) {
strncat(response, U_BOOT_VERSION, chars_left);
- } else if (!strcmp_l1("downloadsize", cmd)) {
+ } else if (!strcmp_l1("downloadsize", cmd) ||
+ !strcmp_l1("max-download-size", cmd)) {
char str_num[12];
- sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
+ sprintf(str_num, "0x%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
strncat(response, str_num, chars_left);
} else if (!strcmp_l1("serialno", cmd)) {
s = getenv("serial#");
@@ -386,6 +387,7 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
unsigned int transfer_size = download_size - download_bytes;
const unsigned char *buffer = req->buf;
unsigned int buffer_size = req->actual;
+ unsigned int pre_dot_num, now_dot_num;
if (req->status != 0) {
printf("Bad status: %d\n", req->status);
@@ -398,7 +400,15 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes,
buffer, transfer_size);
+ pre_dot_num = download_bytes / BYTES_PER_DOT;
download_bytes += transfer_size;
+ now_dot_num = download_bytes / BYTES_PER_DOT;
+
+ if (pre_dot_num != now_dot_num) {
+ putc('.');
+ if (!(now_dot_num % 74))
+ putc('\n');
+ }
/* Check if transfer is done */
if (download_bytes >= download_size) {
@@ -420,11 +430,6 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
req->length = ep->maxpacket;
}
- if (download_bytes && !(download_bytes % BYTES_PER_DOT)) {
- putc('.');
- if (!(download_bytes % (74 * BYTES_PER_DOT)))
- putc('\n');
- }
req->actual = 0;
usb_ep_queue(ep, req, 0);
}
@@ -541,7 +546,14 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
error("unknown command: %s\n", cmdbuf);
fastboot_tx_write_str("FAILunknown command");
} else {
- func_cb(ep, req);
+ if (req->actual < req->length) {
+ u8 *buf = (u8 *)req->buf;
+ buf[req->actual] = 0;
+ func_cb(ep, req);
+ } else {
+ error("buffer overflow\n");
+ fastboot_tx_write_str("FAILbuffer overflow");
+ }
}
if (req->status == 0) {
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index f274d9679f..e045957d07 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -1110,6 +1110,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh)
memset(buf, 0, 8);
buf[0] = TYPE_DISK;
+ buf[1] = curlun->removable ? 0x80 : 0;
buf[2] = 2; /* ANSI SCSI level 2 */
buf[3] = 2; /* SCSI-2 INQUIRY data format */
buf[4] = 31; /* Additional length */
diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c
index c85b0fbd3c..78519fa41f 100644
--- a/drivers/usb/gadget/f_thor.c
+++ b/drivers/usb/gadget/f_thor.c
@@ -458,16 +458,6 @@ static struct usb_endpoint_descriptor hs_int_desc = {
.bInterval = 0x9,
};
-static struct usb_qualifier_descriptor dev_qualifier = {
- .bLength = sizeof(dev_qualifier),
- .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
-
- .bcdUSB = __constant_cpu_to_le16(0x0200),
- .bDeviceClass = USB_CLASS_VENDOR_SPEC,
-
- .bNumConfigurations = 2,
-};
-
/*
* This attribute vendor descriptor is necessary for correct operation with
* Windows version of THOR download program
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index eaf59134cb..6323c50837 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -273,6 +273,29 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed)
return QH_FULL_SPEED;
}
+static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
+ struct QH *qh)
+{
+ struct usb_device *ttdev;
+
+ if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL)
+ return;
+
+ /*
+ * For full / low speed devices we need to get the devnum and portnr of
+ * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
+ * in the tree before that one!
+ */
+ ttdev = dev;
+ while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
+ ttdev = ttdev->parent;
+ if (!ttdev->parent)
+ return;
+
+ qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
+ QH_ENDPT2_HUBADDR(ttdev->parent->devnum));
+}
+
static int
ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
int length, struct devrequest *req)
@@ -390,10 +413,9 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
qh->qh_endpt1 = cpu_to_hc32(endpt);
- endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) |
- QH_ENDPT2_HUBADDR(dev->parent->devnum) |
- QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
+ endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
qh->qh_endpt2 = cpu_to_hc32(endpt);
+ ehci_update_endpt2_dev_n_port(dev, qh);
qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -974,6 +996,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
* Set up periodic list
* Step 1: Parent QH for all periodic transfers.
*/
+ ehcic[index].periodic_schedules = 0;
periodic = &ehcic[index].periodic_queue;
memset(periodic, 0, sizeof(*periodic));
periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
@@ -1132,8 +1155,6 @@ disable_periodic(struct ehci_ctrl *ctrl)
return 0;
}
-static int periodic_schedules;
-
struct int_queue *
create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
int elementsize, void *buffer)
@@ -1201,12 +1222,10 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
(1 << 0)); /* S-mask: microframe 0 */
if (dev->speed == USB_SPEED_LOW ||
dev->speed == USB_SPEED_FULL) {
- debug("TT: port: %d, hub address: %d\n",
- dev->portnr, dev->parent->devnum);
- qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) |
- (dev->parent->devnum << 16) |
- (0x1c << 8)); /* C-mask: microframes 2-4 */
+ /* C-mask: microframes 2-4 */
+ qh->qh_endpt2 |= cpu_to_hc32((0x1c << 8));
}
+ ehci_update_endpt2_dev_n_port(dev, qh);
td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -1258,7 +1277,7 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
debug("FATAL: periodic should never fail, but did");
goto fail3;
}
- periodic_schedules++;
+ ctrl->periodic_schedules++;
debug("Exit create_int_queue\n");
return result;
@@ -1277,6 +1296,7 @@ fail1:
void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
{
struct QH *cur = queue->current;
+ struct qTD *cur_td;
/* depleted queue */
if (cur == NULL) {
@@ -1284,20 +1304,21 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
return NULL;
}
/* still active */
- invalidate_dcache_range((uint32_t)cur,
- ALIGN_END_ADDR(struct QH, cur, 1));
- if (cur->qh_overlay.qt_token & cpu_to_hc32(0x80)) {
- debug("Exit poll_int_queue with no completed intr transfer. "
- "token is %x\n", cur->qh_overlay.qt_token);
+ cur_td = &queue->tds[queue->current - queue->first];
+ invalidate_dcache_range((uint32_t)cur_td,
+ ALIGN_END_ADDR(struct qTD, cur_td, 1));
+ if (QT_TOKEN_GET_STATUS(hc32_to_cpu(cur_td->qt_token)) &
+ QT_TOKEN_STATUS_ACTIVE) {
+ debug("Exit poll_int_queue with no completed intr transfer. token is %x\n",
+ hc32_to_cpu(cur_td->qt_token));
return NULL;
}
if (!(cur->qh_link & QH_LINK_TERMINATE))
queue->current++;
else
queue->current = NULL;
- debug("Exit poll_int_queue with completed intr transfer. "
- "token is %x at %p (first at %p)\n", cur->qh_overlay.qt_token,
- &cur->qh_overlay.qt_token, queue->first);
+ debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n",
+ hc32_to_cpu(cur_td->qt_token), cur, queue->first);
return cur->buffer;
}
@@ -1313,7 +1334,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
debug("FATAL: periodic should never fail, but did");
goto out;
}
- periodic_schedules--;
+ ctrl->periodic_schedules--;
struct QH *cur = &ctrl->periodic_queue;
timeout = get_timer(0) + 500; /* abort after 500ms */
@@ -1322,6 +1343,8 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
if (NEXT_QH(cur) == queue->first) {
debug("found candidate. removing from chain\n");
cur->qh_link = queue->last->qh_link;
+ flush_dcache_range((uint32_t)cur,
+ ALIGN_END_ADDR(struct QH, cur, 1));
result = 0;
break;
}
@@ -1333,7 +1356,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
}
}
- if (periodic_schedules > 0) {
+ if (ctrl->periodic_schedules > 0) {
result = enable_periodic(ctrl);
if (result < 0)
debug("FATAL: periodic should never fail, but did");
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 33e5ea9ebd..5f0a98e8b8 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -305,11 +305,11 @@ static void init_phy_mux(struct fdt_usb *config, uint pts,
#if defined(CONFIG_TEGRA20)
if (config->periph_id == PERIPH_ID_USBD) {
clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
- PTS_UTMI << PTS1_SHIFT);
+ pts << PTS1_SHIFT);
clrbits_le32(&usbctlr->port_sc1, STS1);
} else {
clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
- PTS_UTMI << PTS_SHIFT);
+ pts << PTS_SHIFT);
clrbits_le32(&usbctlr->port_sc1, STS);
}
#else
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 093eb4b832..433e703da8 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -246,6 +246,7 @@ struct ehci_ctrl {
struct QH qh_list __aligned(USB_DMA_MINALIGN);
struct QH periodic_queue __aligned(USB_DMA_MINALIGN);
uint32_t *periodic_list;
+ int periodic_schedules;
int ntds;
};
diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c
index 4edd6d729d..242cc30b1c 100644
--- a/drivers/usb/musb-new/musb_core.c
+++ b/drivers/usb/musb-new/musb_core.c
@@ -942,9 +942,7 @@ void musb_start(struct musb *musb)
/* put into basic highspeed mode and start session */
musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
-#ifdef CONFIG_USB_GADGET_DUALSPEED
| MUSB_POWER_HSENAB
-#endif
/* ENSUSPEND wedges tusb */
/* | MUSB_POWER_ENSUSPEND */
);
OpenPOWER on IntegriCloud