summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dfu/dfu.c2
-rw-r--r--drivers/dfu/dfu_mmc.c109
-rw-r--r--drivers/i2c/Makefile2
-rw-r--r--drivers/i2c/davinci_i2c.c402
-rw-r--r--drivers/i2c/davinci_i2c.h78
-rw-r--r--drivers/i2c/zynq_i2c.c4
-rw-r--r--drivers/mtd/nand/Makefile3
-rw-r--r--drivers/mtd/nand/am335x_spl_bch.c54
-rw-r--r--drivers/mtd/nand/davinci_nand.c3
-rw-r--r--drivers/mtd/spi/spi_spl_load.c46
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/designware.c2
-rw-r--r--drivers/net/dm9000x.c2
-rw-r--r--drivers/net/ftmac110.c2
-rw-r--r--drivers/net/keystone_net.c716
-rw-r--r--drivers/net/phy/atheros.c4
-rw-r--r--drivers/net/phy/phy.c3
-rw-r--r--drivers/net/zynq_gem.c4
-rw-r--r--drivers/power/tps6586x.c4
-rw-r--r--drivers/serial/ns16550.c14
-rw-r--r--drivers/serial/serial.c14
-rw-r--r--drivers/serial/serial_zynq.c18
-rw-r--r--drivers/spi/davinci_spi.c49
-rw-r--r--drivers/spi/davinci_spi.h33
-rw-r--r--drivers/spi/tegra20_sflash.c6
-rw-r--r--drivers/spi/ti_qspi.c3
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/ci_udc.c31
-rw-r--r--drivers/usb/gadget/ci_udc.h65
-rw-r--r--drivers/usb/gadget/f_dfu.c3
-rw-r--r--drivers/usb/gadget/f_mass_storage.c11
-rw-r--r--drivers/usb/gadget/f_thor.c15
-rw-r--r--drivers/usb/gadget/g_dnl.c66
-rw-r--r--drivers/usb/gadget/storage_common.c4
-rw-r--r--drivers/usb/gadget/usbstring.c3
-rw-r--r--drivers/usb/host/Makefile1
-rw-r--r--drivers/usb/host/ehci-exynos.c3
-rw-r--r--drivers/usb/host/ehci-hcd.c56
-rw-r--r--drivers/usb/host/ehci-rmobile.c130
-rw-r--r--drivers/usb/host/ehci-tegra.c28
-rw-r--r--drivers/usb/host/xhci-exynos5.c3
-rw-r--r--drivers/usb/musb-new/musb_uboot.c5
-rw-r--r--drivers/video/tegra.c4
43 files changed, 1633 insertions, 375 deletions
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 8a09aafbf2..51b10263b8 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -219,7 +219,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
ret = tret;
}
- return ret = 0 ? size : ret;
+ return ret;
}
static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size)
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 651cfff5b3..5e10ea7e66 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -184,66 +184,95 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf,
return ret;
}
+/*
+ * @param s Parameter string containing space-separated arguments:
+ * 1st:
+ * raw (raw read/write)
+ * fat (files)
+ * ext4 (^)
+ * part (partition image)
+ * 2nd and 3rd:
+ * lba_start and lba_size, for raw write
+ * mmc_dev and mmc_part, for filesystems and part
+ */
int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
{
- int dev, part;
- struct mmc *mmc;
- block_dev_desc_t *blk_dev;
- disk_partition_t partinfo;
- char *st;
-
- dfu->dev_type = DFU_DEV_MMC;
- st = strsep(&s, " ");
- if (!strcmp(st, "mmc")) {
- dfu->layout = DFU_RAW_ADDR;
- dfu->data.mmc.lba_start = simple_strtoul(s, &s, 16);
- dfu->data.mmc.lba_size = simple_strtoul(++s, &s, 16);
- dfu->data.mmc.lba_blk_size = get_mmc_blk_size(dfu->dev_num);
- } else if (!strcmp(st, "fat")) {
- dfu->layout = DFU_FS_FAT;
- } else if (!strcmp(st, "ext4")) {
- dfu->layout = DFU_FS_EXT4;
- } else if (!strcmp(st, "part")) {
+ const char *entity_type;
+ size_t second_arg;
+ size_t third_arg;
- dfu->layout = DFU_RAW_ADDR;
+ struct mmc *mmc;
- dev = simple_strtoul(s, &s, 10);
- s++;
- part = simple_strtoul(s, &s, 10);
+ const char *argv[3];
+ const char **parg = argv;
- mmc = find_mmc_device(dev);
- if (mmc == NULL || mmc_init(mmc)) {
- printf("%s: could not find mmc device #%d!\n",
- __func__, dev);
+ for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) {
+ *parg = strsep(&s, " ");
+ if (*parg == NULL) {
+ error("Invalid number of arguments.\n");
return -ENODEV;
}
+ }
+
+ entity_type = argv[0];
+ /*
+ * Base 0 means we'll accept (prefixed with 0x or 0) base 16, 8,
+ * with default 10.
+ */
+ second_arg = simple_strtoul(argv[1], NULL, 0);
+ third_arg = simple_strtoul(argv[2], NULL, 0);
- blk_dev = &mmc->block_dev;
- if (get_partition_info(blk_dev, part, &partinfo) != 0) {
- printf("%s: could not find partition #%d on mmc device #%d!\n",
- __func__, part, dev);
+ mmc = find_mmc_device(dfu->dev_num);
+ if (mmc == NULL) {
+ error("Couldn't find MMC device no. %d.\n", dfu->dev_num);
+ return -ENODEV;
+ }
+
+ if (mmc_init(mmc)) {
+ error("Couldn't init MMC device.\n");
+ return -ENODEV;
+ }
+
+ if (!strcmp(entity_type, "raw")) {
+ dfu->layout = DFU_RAW_ADDR;
+ dfu->data.mmc.lba_start = second_arg;
+ dfu->data.mmc.lba_size = third_arg;
+ dfu->data.mmc.lba_blk_size = mmc->read_bl_len;
+ } else if (!strcmp(entity_type, "part")) {
+ disk_partition_t partinfo;
+ block_dev_desc_t *blk_dev = &mmc->block_dev;
+ int mmcdev = second_arg;
+ int mmcpart = third_arg;
+
+ if (get_partition_info(blk_dev, mmcpart, &partinfo) != 0) {
+ error("Couldn't find part #%d on mmc device #%d\n",
+ mmcpart, mmcdev);
return -ENODEV;
}
- dfu->data.mmc.lba_start = partinfo.start;
- dfu->data.mmc.lba_size = partinfo.size;
- dfu->data.mmc.lba_blk_size = partinfo.blksz;
-
+ dfu->layout = DFU_RAW_ADDR;
+ dfu->data.mmc.lba_start = partinfo.start;
+ dfu->data.mmc.lba_size = partinfo.size;
+ dfu->data.mmc.lba_blk_size = partinfo.blksz;
+ } else if (!strcmp(entity_type, "fat")) {
+ dfu->layout = DFU_FS_FAT;
+ } else if (!strcmp(entity_type, "ext4")) {
+ dfu->layout = DFU_FS_EXT4;
} else {
- printf("%s: Memory layout (%s) not supported!\n", __func__, st);
+ error("Memory layout (%s) not supported!\n", entity_type);
return -ENODEV;
}
- if (dfu->layout == DFU_FS_EXT4 || dfu->layout == DFU_FS_FAT) {
- dfu->data.mmc.dev = simple_strtoul(s, &s, 10);
- dfu->data.mmc.part = simple_strtoul(++s, &s, 10);
+ /* if it's NOT a raw write */
+ if (strcmp(entity_type, "raw")) {
+ dfu->data.mmc.dev = second_arg;
+ dfu->data.mmc.part = third_arg;
}
+ dfu->dev_type = DFU_DEV_MMC;
dfu->read_medium = dfu_read_medium_mmc;
dfu->write_medium = dfu_write_medium_mmc;
dfu->flush_medium = dfu_flush_medium_mmc;
-
- /* initial state */
dfu->inited = 0;
return 0;
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 36d5e5f1a2..e33586d8a6 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -6,7 +6,6 @@
#
obj-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
-obj-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
obj-$(CONFIG_DW_I2C) += designware_i2c.o
obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
obj-$(CONFIG_I2C_MV) += mv_i2c.o
@@ -16,6 +15,7 @@ obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
obj-$(CONFIG_U8500_I2C) += u8500_i2c.o
obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
obj-$(CONFIG_SYS_I2C) += i2c_core.o
+obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o
obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index e56fe75b15..9ca99c4abd 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -1,8 +1,9 @@
/*
* TI DaVinci (TMS320DM644x) I2C driver.
*
- * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
- *
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
* --------------------------------------------------------
*
* SPDX-License-Identifier: GPL-2.0+
@@ -12,305 +13,372 @@
#include <i2c.h>
#include <asm/arch/hardware.h>
#include <asm/arch/i2c_defs.h>
+#include <asm/io.h>
+#include "davinci_i2c.h"
#define CHECK_NACK() \
do {\
if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
- REG(I2C_CON) = 0;\
- return(1);\
- }\
+ REG(&(i2c_base->i2c_con)) = 0;\
+ return 1;\
+ } \
} while (0)
+static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap);
-static int wait_for_bus(void)
+static int wait_for_bus(struct i2c_adapter *adap)
{
+ struct i2c_regs *i2c_base = davinci_get_base(adap);
int stat, timeout;
- REG(I2C_STAT) = 0xffff;
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
for (timeout = 0; timeout < 10; timeout++) {
- if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
- REG(I2C_STAT) = 0xffff;
- return(0);
+ stat = REG(&(i2c_base->i2c_stat));
+ if (!((stat) & I2C_STAT_BB)) {
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ return 0;
}
- REG(I2C_STAT) = stat;
+ REG(&(i2c_base->i2c_stat)) = stat;
udelay(50000);
}
- REG(I2C_STAT) = 0xffff;
- return(1);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ return 1;
}
-static int poll_i2c_irq(int mask)
+static int poll_i2c_irq(struct i2c_adapter *adap, int mask)
{
+ struct i2c_regs *i2c_base = davinci_get_base(adap);
int stat, timeout;
for (timeout = 0; timeout < 10; timeout++) {
udelay(1000);
- stat = REG(I2C_STAT);
- if (stat & mask) {
- return(stat);
- }
+ stat = REG(&(i2c_base->i2c_stat));
+ if (stat & mask)
+ return stat;
}
- REG(I2C_STAT) = 0xffff;
- return(stat | I2C_TIMEOUT);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ return stat | I2C_TIMEOUT;
}
-
-void flush_rx(void)
+static void flush_rx(struct i2c_adapter *adap)
{
+ struct i2c_regs *i2c_base = davinci_get_base(adap);
+
while (1) {
- if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
+ if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY))
break;
- REG(I2C_DRR);
- REG(I2C_STAT) = I2C_STAT_RRDY;
+ REG(&(i2c_base->i2c_drr));
+ REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY;
udelay(1000);
}
}
+static uint davinci_i2c_setspeed(struct i2c_adapter *adap, uint speed)
+{
+ struct i2c_regs *i2c_base = davinci_get_base(adap);
+ uint32_t div, psc;
+
+ psc = 2;
+ /* SCLL + SCLH */
+ div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
+ REG(&(i2c_base->i2c_psc)) = psc; /* 27MHz / (2 + 1) = 9MHz */
+ REG(&(i2c_base->i2c_scll)) = (div * 50) / 100; /* 50% Duty */
+ REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
+
+ adap->speed = speed;
+ return 0;
+}
-void i2c_init(int speed, int slaveadd)
+static void davinci_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
{
- u_int32_t div, psc;
+ struct i2c_regs *i2c_base = davinci_get_base(adap);
- if (REG(I2C_CON) & I2C_CON_EN) {
- REG(I2C_CON) = 0;
- udelay (50000);
+ if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) {
+ REG(&(i2c_base->i2c_con)) = 0;
+ udelay(50000);
}
- psc = 2;
- div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10; /* SCLL + SCLH */
- REG(I2C_PSC) = psc; /* 27MHz / (2 + 1) = 9MHz */
- REG(I2C_SCLL) = (div * 50) / 100; /* 50% Duty */
- REG(I2C_SCLH) = div - REG(I2C_SCLL);
+ davinci_i2c_setspeed(adap, speed);
- REG(I2C_OA) = slaveadd;
- REG(I2C_CNT) = 0;
+ REG(&(i2c_base->i2c_oa)) = slaveadd;
+ REG(&(i2c_base->i2c_cnt)) = 0;
/* Interrupts must be enabled or I2C module won't work */
- REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+ REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
/* Now enable I2C controller (get it out of reset) */
- REG(I2C_CON) = I2C_CON_EN;
+ REG(&(i2c_base->i2c_con)) = I2C_CON_EN;
udelay(1000);
}
-int i2c_set_bus_speed(unsigned int speed)
-{
- i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
- return 0;
-}
-
-int i2c_probe(u_int8_t chip)
+static int davinci_i2c_probe(struct i2c_adapter *adap, uint8_t chip)
{
+ struct i2c_regs *i2c_base = davinci_get_base(adap);
int rc = 1;
- if (chip == REG(I2C_OA)) {
- return(rc);
- }
+ if (chip == REG(&(i2c_base->i2c_oa)))
+ return rc;
- REG(I2C_CON) = 0;
- if (wait_for_bus()) {return(1);}
+ REG(&(i2c_base->i2c_con)) = 0;
+ if (wait_for_bus(adap))
+ return 1;
/* try to read one byte from current (or only) address */
- REG(I2C_CNT) = 1;
- REG(I2C_SA) = chip;
- REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP);
- udelay (50000);
+ REG(&(i2c_base->i2c_cnt)) = 1;
+ REG(&(i2c_base->i2c_sa)) = chip;
+ REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+ I2C_CON_STP);
+ udelay(50000);
- if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
+ if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) {
rc = 0;
- flush_rx();
- REG(I2C_STAT) = 0xffff;
+ flush_rx(adap);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
} else {
- REG(I2C_STAT) = 0xffff;
- REG(I2C_CON) |= I2C_CON_STP;
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ REG(&(i2c_base->i2c_con)) |= I2C_CON_STP;
udelay(20000);
- if (wait_for_bus()) {return(1);}
+ if (wait_for_bus(adap))
+ return 1;
}
- flush_rx();
- REG(I2C_STAT) = 0xffff;
- REG(I2C_CNT) = 0;
- return(rc);
+ flush_rx(adap);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ REG(&(i2c_base->i2c_cnt)) = 0;
+ return rc;
}
-
-int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+static int davinci_i2c_read(struct i2c_adapter *adap, uint8_t chip,
+ uint32_t addr, int alen, uint8_t *buf, int len)
{
- u_int32_t tmp;
+ struct i2c_regs *i2c_base = davinci_get_base(adap);
+ uint32_t tmp;
int i;
if ((alen < 0) || (alen > 2)) {
- printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
- return(1);
+ printf("%s(): bogus address length %x\n", __func__, alen);
+ return 1;
}
- if (wait_for_bus()) {return(1);}
+ if (wait_for_bus(adap))
+ return 1;
if (alen != 0) {
/* Start address phase */
tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
- REG(I2C_CNT) = alen;
- REG(I2C_SA) = chip;
- REG(I2C_CON) = tmp;
+ REG(&(i2c_base->i2c_cnt)) = alen;
+ REG(&(i2c_base->i2c_sa)) = chip;
+ REG(&(i2c_base->i2c_con)) = tmp;
- tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+ tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
CHECK_NACK();
switch (alen) {
- case 2:
- /* Send address MSByte */
- if (tmp & I2C_STAT_XRDY) {
- REG(I2C_DXR) = (addr >> 8) & 0xff;
- } else {
- REG(I2C_CON) = 0;
- return(1);
- }
-
- tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
-
- CHECK_NACK();
- /* No break, fall through */
- case 1:
- /* Send address LSByte */
- if (tmp & I2C_STAT_XRDY) {
- REG(I2C_DXR) = addr & 0xff;
- } else {
- REG(I2C_CON) = 0;
- return(1);
- }
-
- tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
-
- CHECK_NACK();
-
- if (!(tmp & I2C_STAT_ARDY)) {
- REG(I2C_CON) = 0;
- return(1);
- }
+ case 2:
+ /* Send address MSByte */
+ if (tmp & I2C_STAT_XRDY) {
+ REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+ } else {
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
+ }
+
+ tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
+
+ CHECK_NACK();
+ /* No break, fall through */
+ case 1:
+ /* Send address LSByte */
+ if (tmp & I2C_STAT_XRDY) {
+ REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+ } else {
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
+ }
+
+ tmp = poll_i2c_irq(adap, I2C_STAT_XRDY |
+ I2C_STAT_NACK | I2C_STAT_ARDY);
+
+ CHECK_NACK();
+
+ if (!(tmp & I2C_STAT_ARDY)) {
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
+ }
}
}
/* Address phase is over, now read 'len' bytes and stop */
tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
- REG(I2C_CNT) = len & 0xffff;
- REG(I2C_SA) = chip;
- REG(I2C_CON) = tmp;
+ REG(&(i2c_base->i2c_cnt)) = len & 0xffff;
+ REG(&(i2c_base->i2c_sa)) = chip;
+ REG(&(i2c_base->i2c_con)) = tmp;
for (i = 0; i < len; i++) {
- tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
+ tmp = poll_i2c_irq(adap, I2C_STAT_RRDY | I2C_STAT_NACK |
+ I2C_STAT_ROVR);
CHECK_NACK();
if (tmp & I2C_STAT_RRDY) {
- buf[i] = REG(I2C_DRR);
+ buf[i] = REG(&(i2c_base->i2c_drr));
} else {
- REG(I2C_CON) = 0;
- return(1);
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
}
}
- tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+ tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK);
CHECK_NACK();
if (!(tmp & I2C_STAT_SCD)) {
- REG(I2C_CON) = 0;
- return(1);
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
}
- flush_rx();
- REG(I2C_STAT) = 0xffff;
- REG(I2C_CNT) = 0;
- REG(I2C_CON) = 0;
+ flush_rx(adap);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ REG(&(i2c_base->i2c_cnt)) = 0;
+ REG(&(i2c_base->i2c_con)) = 0;
- return(0);
+ return 0;
}
-
-int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+static int davinci_i2c_write(struct i2c_adapter *adap, uint8_t chip,
+ uint32_t addr, int alen, uint8_t *buf, int len)
{
- u_int32_t tmp;
+ struct i2c_regs *i2c_base = davinci_get_base(adap);
+ uint32_t tmp;
int i;
if ((alen < 0) || (alen > 2)) {
- printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
- return(1);
+ printf("%s(): bogus address length %x\n", __func__, alen);
+ return 1;
}
if (len < 0) {
- printf("%s(): bogus length %x\n", __FUNCTION__, len);
- return(1);
+ printf("%s(): bogus length %x\n", __func__, len);
+ return 1;
}
- if (wait_for_bus()) {return(1);}
+ if (wait_for_bus(adap))
+ return 1;
/* Start address phase */
- tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
- REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
- REG(I2C_SA) = chip;
- REG(I2C_CON) = tmp;
+ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+ I2C_CON_TRX | I2C_CON_STP;
+ REG(&(i2c_base->i2c_cnt)) = (alen == 0) ?
+ len & 0xffff : (len & 0xffff) + alen;
+ REG(&(i2c_base->i2c_sa)) = chip;
+ REG(&(i2c_base->i2c_con)) = tmp;
switch (alen) {
- case 2:
- /* Send address MSByte */
- tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+ case 2:
+ /* Send address MSByte */
+ tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
- CHECK_NACK();
+ CHECK_NACK();
- if (tmp & I2C_STAT_XRDY) {
- REG(I2C_DXR) = (addr >> 8) & 0xff;
- } else {
- REG(I2C_CON) = 0;
- return(1);
- }
- /* No break, fall through */
- case 1:
- /* Send address LSByte */
- tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+ if (tmp & I2C_STAT_XRDY) {
+ REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+ } else {
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
+ }
+ /* No break, fall through */
+ case 1:
+ /* Send address LSByte */
+ tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
- CHECK_NACK();
+ CHECK_NACK();
- if (tmp & I2C_STAT_XRDY) {
- REG(I2C_DXR) = addr & 0xff;
- } else {
- REG(I2C_CON) = 0;
- return(1);
- }
+ if (tmp & I2C_STAT_XRDY) {
+ REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+ } else {
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
+ }
}
for (i = 0; i < len; i++) {
- tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+ tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
CHECK_NACK();
- if (tmp & I2C_STAT_XRDY) {
- REG(I2C_DXR) = buf[i];
- } else {
- return(1);
- }
+ if (tmp & I2C_STAT_XRDY)
+ REG(&(i2c_base->i2c_dxr)) = buf[i];
+ else
+ return 1;
}
- tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+ tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK);
CHECK_NACK();
if (!(tmp & I2C_STAT_SCD)) {
- REG(I2C_CON) = 0;
- return(1);
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
}
- flush_rx();
- REG(I2C_STAT) = 0xffff;
- REG(I2C_CNT) = 0;
- REG(I2C_CON) = 0;
+ flush_rx(adap);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ REG(&(i2c_base->i2c_cnt)) = 0;
+ REG(&(i2c_base->i2c_con)) = 0;
+
+ return 0;
+}
+
+static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap)
+{
+ switch (adap->hwadapnr) {
+#if I2C_BUS_MAX >= 3
+ case 2:
+ return (struct i2c_regs *)I2C2_BASE;
+#endif
+#if I2C_BUS_MAX >= 2
+ case 1:
+ return (struct i2c_regs *)I2C1_BASE;
+#endif
+ case 0:
+ return (struct i2c_regs *)I2C_BASE;
+
+ default:
+ printf("wrong hwadapnr: %d\n", adap->hwadapnr);
+ }
- return(0);
+ return NULL;
}
+
+U_BOOT_I2C_ADAP_COMPLETE(davinci_0, davinci_i2c_init, davinci_i2c_probe,
+ davinci_i2c_read, davinci_i2c_write,
+ davinci_i2c_setspeed,
+ CONFIG_SYS_DAVINCI_I2C_SPEED,
+ CONFIG_SYS_DAVINCI_I2C_SLAVE,
+ 0)
+
+#if I2C_BUS_MAX >= 2
+U_BOOT_I2C_ADAP_COMPLETE(davinci_1, davinci_i2c_init, davinci_i2c_probe,
+ davinci_i2c_read, davinci_i2c_write,
+ davinci_i2c_setspeed,
+ CONFIG_SYS_DAVINCI_I2C_SPEED1,
+ CONFIG_SYS_DAVINCI_I2C_SLAVE1,
+ 1)
+#endif
+
+#if I2C_BUS_MAX >= 3
+U_BOOT_I2C_ADAP_COMPLETE(davinci_2, davinci_i2c_init, davinci_i2c_probe,
+ davinci_i2c_read, davinci_i2c_write,
+ davinci_i2c_setspeed,
+ CONFIG_SYS_DAVINCI_I2C_SPEED2,
+ CONFIG_SYS_DAVINCI_I2C_SLAVE2,
+ 2)
+#endif
diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h
new file mode 100644
index 0000000000..20d43424b9
--- /dev/null
+++ b/drivers/i2c/davinci_i2c.h
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2004-2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * Some changes copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _DAVINCI_I2C_H_
+#define _DAVINCI_I2C_H_
+
+#define I2C_WRITE 0
+#define I2C_READ 1
+
+struct i2c_regs {
+ u32 i2c_oa;
+ u32 i2c_ie;
+ u32 i2c_stat;
+ u32 i2c_scll;
+ u32 i2c_sclh;
+ u32 i2c_cnt;
+ u32 i2c_drr;
+ u32 i2c_sa;
+ u32 i2c_dxr;
+ u32 i2c_con;
+ u32 i2c_iv;
+ u32 res_2c;
+ u32 i2c_psc;
+};
+
+/* I2C masks */
+
+/* I2C Interrupt Enable Register (I2C_IE): */
+#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */
+#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */
+#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */
+#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */
+#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */
+#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */
+
+/* I2C Status Register (I2C_STAT): */
+
+#define I2C_STAT_BB (1 << 12) /* Bus busy */
+#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */
+#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */
+#define I2C_STAT_AAS (1 << 9) /* Address as slave */
+#define I2C_STAT_SCD (1 << 5) /* Stop condition detect */
+#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */
+#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */
+#define I2C_STAT_ARDY (1 << 2) /* Register access ready */
+#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */
+#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */
+
+/* I2C Interrupt Code Register (I2C_INTCODE): */
+
+#define I2C_INTCODE_MASK 7
+#define I2C_INTCODE_NONE 0
+#define I2C_INTCODE_AL 1 /* Arbitration lost */
+#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */
+#define I2C_INTCODE_ARDY 3 /* Register access ready */
+#define I2C_INTCODE_RRDY 4 /* Rcv data ready */
+#define I2C_INTCODE_XRDY 5 /* Xmit data ready */
+#define I2C_INTCODE_SCD 6 /* Stop condition detect */
+
+/* I2C Configuration Register (I2C_CON): */
+
+#define I2C_CON_EN (1 << 5) /* I2C module enable */
+#define I2C_CON_STB (1 << 4) /* Start byte mode (master mode only) */
+#define I2C_CON_MST (1 << 10) /* Master/slave mode */
+#define I2C_CON_TRX (1 << 9) /* Tx/Rx mode (master mode only) */
+#define I2C_CON_XA (1 << 8) /* Expand address */
+#define I2C_CON_STP (1 << 11) /* Stop condition (master mode only) */
+#define I2C_CON_STT (1 << 13) /* Start condition (master mode only) */
+#define I2C_CON_FREE (1 << 14) /* Free run on emulation */
+
+#define I2C_TIMEOUT 0xffff0000 /* Timeout mask for poll_i2c_irq() */
+
+#endif
diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c
index f1f65131a2..b3264af452 100644
--- a/drivers/i2c/zynq_i2c.c
+++ b/drivers/i2c/zynq_i2c.c
@@ -142,7 +142,7 @@ static u32 zynq_i2c_wait(struct zynq_i2c_registers *zynq_i2c, u32 mask)
break;
}
#ifdef DEBUG
- zynq_i2c_debug_status(zynq_i2c));
+ zynq_i2c_debug_status(zynq_i2c);
#endif
/* Clear interrupt status flags */
writel(int_status & mask, &zynq_i2c->interrupt_status);
@@ -235,7 +235,7 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,
clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
#ifdef DEBUG
- zynq_i2c_debug_status();
+ zynq_i2c_debug_status(zynq_i2c);
#endif
return 0;
}
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 02b149cacc..4eb354da93 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -18,6 +18,9 @@ obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o
obj-$(CONFIG_SPL_NAND_INIT) += nand.o
+ifeq ($(CONFIG_SPL_ENV_SUPPORT),y)
+obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o
+endif
else # not spl
diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c
index c84851bab5..bd89b067d5 100644
--- a/drivers/mtd/nand/am335x_spl_bch.c
+++ b/drivers/mtd/nand/am335x_spl_bch.c
@@ -16,7 +16,7 @@
#include <linux/mtd/nand_ecc.h>
static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
-static nand_info_t mtd;
+nand_info_t nand_info[1];
static struct nand_chip nand_chip;
#define ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
@@ -30,12 +30,12 @@ static struct nand_chip nand_chip;
static int nand_command(int block, int page, uint32_t offs,
u8 cmd)
{
- struct nand_chip *this = mtd.priv;
+ struct nand_chip *this = nand_info[0].priv;
int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
void (*hwctrl)(struct mtd_info *mtd, int cmd,
unsigned int ctrl) = this->cmd_ctrl;
- while (!this->dev_ready(&mtd))
+ while (!this->dev_ready(&nand_info[0]))
;
/* Emulate NAND_CMD_READOOB */
@@ -45,11 +45,11 @@ static int nand_command(int block, int page, uint32_t offs,
}
/* Begin command latch cycle */
- hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
+ hwctrl(&nand_info[0], cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
if (cmd == NAND_CMD_RESET) {
- hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
- while (!this->dev_ready(&mtd))
+ hwctrl(&nand_info[0], NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+ while (!this->dev_ready(&nand_info[0]))
;
return 0;
}
@@ -60,35 +60,35 @@ static int nand_command(int block, int page, uint32_t offs,
/* Set ALE and clear CLE to start address cycle */
/* Column address */
- hwctrl(&mtd, offs & 0xff,
+ hwctrl(&nand_info[0], offs & 0xff,
NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */
- hwctrl(&mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */
+ hwctrl(&nand_info[0], (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */
/* Row address */
- hwctrl(&mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */
- hwctrl(&mtd, ((page_addr >> 8) & 0xff),
+ hwctrl(&nand_info[0], (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */
+ hwctrl(&nand_info[0], ((page_addr >> 8) & 0xff),
NAND_CTRL_ALE); /* A[27:20] */
#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE
/* One more address cycle for devices > 128MiB */
- hwctrl(&mtd, (page_addr >> 16) & 0x0f,
+ hwctrl(&nand_info[0], (page_addr >> 16) & 0x0f,
NAND_CTRL_ALE); /* A[31:28] */
#endif
- hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+ hwctrl(&nand_info[0], NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
if (cmd == NAND_CMD_READ0) {
/* Latch in address */
- hwctrl(&mtd, NAND_CMD_READSTART,
+ hwctrl(&nand_info[0], NAND_CMD_READSTART,
NAND_CTRL_CLE | NAND_CTRL_CHANGE);
- hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+ hwctrl(&nand_info[0], NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
/*
* Wait a while for the data to be ready
*/
- while (!this->dev_ready(&mtd))
+ while (!this->dev_ready(&nand_info[0]))
;
} else if (cmd == NAND_CMD_RNDOUT) {
- hwctrl(&mtd, NAND_CMD_RNDOUTSTART, NAND_CTRL_CLE |
+ hwctrl(&nand_info[0], NAND_CMD_RNDOUTSTART, NAND_CTRL_CLE |
NAND_CTRL_CHANGE);
- hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+ hwctrl(&nand_info[0], NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
}
return 0;
@@ -96,7 +96,7 @@ static int nand_command(int block, int page, uint32_t offs,
static int nand_is_bad_block(int block)
{
- struct nand_chip *this = mtd.priv;
+ struct nand_chip *this = nand_info[0].priv;
nand_command(block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS,
NAND_CMD_READOOB);
@@ -117,7 +117,7 @@ static int nand_is_bad_block(int block)
static int nand_read_page(int block, int page, void *dst)
{
- struct nand_chip *this = mtd.priv;
+ struct nand_chip *this = nand_info[0].priv;
u_char ecc_calc[ECCTOTAL];
u_char ecc_code[ECCTOTAL];
u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
@@ -133,15 +133,15 @@ static int nand_read_page(int block, int page, void *dst)
nand_command(block, page, 0, NAND_CMD_READ0);
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- this->ecc.hwctl(&mtd, NAND_ECC_READ);
+ this->ecc.hwctl(&nand_info[0], NAND_ECC_READ);
nand_command(block, page, data_pos, NAND_CMD_RNDOUT);
- this->read_buf(&mtd, p, eccsize);
+ this->read_buf(&nand_info[0], p, eccsize);
nand_command(block, page, oob_pos, NAND_CMD_RNDOUT);
- this->read_buf(&mtd, oob, eccbytes);
- this->ecc.calculate(&mtd, p, &ecc_calc[i]);
+ this->read_buf(&nand_info[0], oob, eccbytes);
+ this->ecc.calculate(&nand_info[0], p, &ecc_calc[i]);
data_pos += eccsize;
oob_pos += eccbytes;
@@ -160,7 +160,7 @@ static int nand_read_page(int block, int page, void *dst)
* from correct_data(). We just hope that all possible errors
* are corrected by this routine.
*/
- this->ecc.correct(&mtd, p, &ecc_code[i], &ecc_calc[i]);
+ this->ecc.correct(&nand_info[0], p, &ecc_code[i], &ecc_calc[i]);
}
return 0;
@@ -206,13 +206,13 @@ void nand_init(void)
/*
* Init board specific nand support
*/
- mtd.priv = &nand_chip;
+ nand_info[0].priv = &nand_chip;
nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W =
(void __iomem *)CONFIG_SYS_NAND_BASE;
board_nand_init(&nand_chip);
if (nand_chip.select_chip)
- nand_chip.select_chip(&mtd, 0);
+ nand_chip.select_chip(&nand_info[0], 0);
/* NAND chip may require reset after power-on */
nand_command(0, 0, 0, NAND_CMD_RESET);
@@ -222,5 +222,5 @@ void nand_init(void)
void nand_deselect(void)
{
if (nand_chip.select_chip)
- nand_chip.select_chip(&mtd, -1);
+ nand_chip.select_chip(&nand_info[0], -1);
}
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 5b17d7be8b..75b03a74b6 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -609,6 +609,9 @@ void davinci_nand_init(struct nand_chip *nand)
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
nand->bbt_options |= NAND_BBT_USE_FLASH;
#endif
+#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+ nand->options |= NAND_NO_SUBPAGE_WRITE;
+#endif
#ifdef CONFIG_SYS_NAND_HW_ECC
nand->ecc.mode = NAND_ECC_HW;
nand->ecc.size = 512;
diff --git a/drivers/mtd/spi/spi_spl_load.c b/drivers/mtd/spi/spi_spl_load.c
index 29355307f3..1954b7e886 100644
--- a/drivers/mtd/spi/spi_spl_load.c
+++ b/drivers/mtd/spi/spi_spl_load.c
@@ -13,6 +13,35 @@
#include <spi_flash.h>
#include <spl.h>
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * Load the kernel, check for a valid header we can parse, and if found load
+ * the kernel and then device tree.
+ */
+static int spi_load_image_os(struct spi_flash *flash,
+ struct image_header *header)
+{
+ /* Read for a header, parse or error out. */
+ spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40,
+ (void *)header);
+
+ if (image_get_magic(header) != IH_MAGIC)
+ return -1;
+
+ spl_parse_image_header(header);
+
+ spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS,
+ spl_image.size, (void *)spl_image.load_addr);
+
+ /* Read device tree. */
+ spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS,
+ CONFIG_SYS_SPI_ARGS_SIZE,
+ (void *)CONFIG_SYS_SPL_ARGS_ADDR);
+
+ return 0;
+}
+#endif
+
/*
* The main entry for SPI booting. It's necessary that SDRAM is already
* configured and available since this code loads the main U-Boot image
@@ -37,10 +66,15 @@ void spl_spi_load_image(void)
/* use CONFIG_SYS_TEXT_BASE as temporary storage area */
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
- /* Load u-boot, mkimage header is 64 bytes. */
- spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40,
- (void *)header);
- spl_parse_image_header(header);
- spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
- spl_image.size, (void *)spl_image.load_addr);
+#ifdef CONFIG_SPL_OS_BOOT
+ if (spl_start_uboot() || spi_load_image_os(flash, header))
+#endif
+ {
+ /* Load u-boot, mkimage header is 64 bytes. */
+ spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40,
+ (void *)header);
+ spl_parse_image_header(header);
+ spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
+ spl_image.size, (void *)spl_image.load_addr);
+ }
}
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index c25b3c93ce..6005f7e413 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -29,6 +29,8 @@ obj-$(CONFIG_FTGMAC100) += ftgmac100.o
obj-$(CONFIG_FTMAC110) += ftmac110.o
obj-$(CONFIG_FTMAC100) += ftmac100.o
obj-$(CONFIG_GRETH) += greth.o
+obj-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
+obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o
obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
obj-$(CONFIG_LAN91C96) += lan91c96.o
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index c45593bcc0..78751b2600 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -390,6 +390,8 @@ static int dw_phy_init(struct eth_device *dev)
if (!phydev)
return -1;
+ phy_connect_dev(phydev, dev);
+
phydev->supported &= PHY_GBIT_FEATURES;
phydev->advertising = phydev->supported;
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
index b68d808c74..4de9d41642 100644
--- a/drivers/net/dm9000x.c
+++ b/drivers/net/dm9000x.c
@@ -345,7 +345,7 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd)
if (!is_valid_ether_addr(dev->enetaddr)) {
#ifdef CONFIG_RANDOM_MACADDR
printf("Bad MAC address (uninitialized EEPROM?), randomizing\n");
- eth_random_enetaddr(dev->enetaddr);
+ eth_random_addr(dev->enetaddr);
printf("MAC: %pM\n", dev->enetaddr);
#else
printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n");
diff --git a/drivers/net/ftmac110.c b/drivers/net/ftmac110.c
index 8eee272cf1..98c4f09629 100644
--- a/drivers/net/ftmac110.c
+++ b/drivers/net/ftmac110.c
@@ -425,7 +425,7 @@ int ftmac110_initialize(bd_t *bis)
dev->recv = ftmac110_recv;
if (!eth_getenv_enetaddr_by_index("eth", card_nr, dev->enetaddr))
- eth_random_enetaddr(dev->enetaddr);
+ eth_random_addr(dev->enetaddr);
/* allocate tx descriptors (it must be 16 bytes aligned) */
chip->txd = dma_alloc_coherent(
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
new file mode 100644
index 0000000000..f95c928076
--- /dev/null
+++ b/drivers/net/keystone_net.c
@@ -0,0 +1,716 @@
+/*
+ * Ethernet driver for TI K2HK EVM.
+ *
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+
+#include <net.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <asm/arch/emac_defs.h>
+#include <asm/arch/psc_defs.h>
+#include <asm/arch/keystone_nav.h>
+
+unsigned int emac_dbg;
+
+unsigned int emac_open;
+static unsigned int sys_has_mdio = 1;
+
+#ifdef KEYSTONE2_EMAC_GIG_ENABLE
+#define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x)
+#else
+#define emac_gigabit_enable(x) /* no gigabit to enable */
+#endif
+
+#define RX_BUFF_NUMS 24
+#define RX_BUFF_LEN 1520
+#define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN
+
+static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16);
+
+struct rx_buff_desc net_rx_buffs = {
+ .buff_ptr = rx_buffs,
+ .num_buffs = RX_BUFF_NUMS,
+ .buff_len = RX_BUFF_LEN,
+ .rx_flow = 22,
+};
+
+static void keystone2_eth_mdio_enable(void);
+
+static int gen_get_link_speed(int phy_addr);
+
+/* EMAC Addresses */
+static volatile struct emac_regs *adap_emac =
+ (struct emac_regs *)EMAC_EMACSL_BASE_ADDR;
+static volatile struct mdio_regs *adap_mdio =
+ (struct mdio_regs *)EMAC_MDIO_BASE_ADDR;
+
+int keystone2_eth_read_mac_addr(struct eth_device *dev)
+{
+ struct eth_priv_t *eth_priv;
+ u32 maca = 0;
+ u32 macb = 0;
+
+ eth_priv = (struct eth_priv_t *)dev->priv;
+
+ /* Read the e-fuse mac address */
+ if (eth_priv->slave_port == 1) {
+ maca = __raw_readl(MAC_ID_BASE_ADDR);
+ macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
+ }
+
+ dev->enetaddr[0] = (macb >> 8) & 0xff;
+ dev->enetaddr[1] = (macb >> 0) & 0xff;
+ dev->enetaddr[2] = (maca >> 24) & 0xff;
+ dev->enetaddr[3] = (maca >> 16) & 0xff;
+ dev->enetaddr[4] = (maca >> 8) & 0xff;
+ dev->enetaddr[5] = (maca >> 0) & 0xff;
+
+ return 0;
+}
+
+static void keystone2_eth_mdio_enable(void)
+{
+ u_int32_t clkdiv;
+
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+
+ writel((clkdiv & 0xffff) |
+ MDIO_CONTROL_ENABLE |
+ MDIO_CONTROL_FAULT |
+ MDIO_CONTROL_FAULT_ENABLE,
+ &adap_mdio->control);
+
+ while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE)
+ ;
+}
+
+/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
+int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+{
+ int tmp;
+
+ while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
+ ;
+
+ writel(MDIO_USERACCESS0_GO |
+ MDIO_USERACCESS0_WRITE_READ |
+ ((reg_num & 0x1f) << 21) |
+ ((phy_addr & 0x1f) << 16),
+ &adap_mdio->useraccess0);
+
+ /* Wait for command to complete */
+ while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO)
+ ;
+
+ if (tmp & MDIO_USERACCESS0_ACK) {
+ *data = tmp & 0xffff;
+ return 0;
+ }
+
+ *data = -1;
+ return -1;
+}
+
+/*
+ * Write to a PHY register via MDIO inteface.
+ * Blocks until operation is complete.
+ */
+int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+{
+ while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
+ ;
+
+ writel(MDIO_USERACCESS0_GO |
+ MDIO_USERACCESS0_WRITE_WRITE |
+ ((reg_num & 0x1f) << 21) |
+ ((phy_addr & 0x1f) << 16) |
+ (data & 0xffff),
+ &adap_mdio->useraccess0);
+
+ /* Wait for command to complete */
+ while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
+ ;
+
+ return 0;
+}
+
+/* PHY functions for a generic PHY */
+static int gen_get_link_speed(int phy_addr)
+{
+ u_int16_t tmp;
+
+ if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
+ (tmp & 0x04)) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static void __attribute__((unused))
+ keystone2_eth_gigabit_enable(struct eth_device *dev)
+{
+ u_int16_t data;
+ struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+ if (sys_has_mdio) {
+ if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) ||
+ !(data & (1 << 6))) /* speed selection MSB */
+ return;
+ }
+
+ /*
+ * Check if link detected is giga-bit
+ * If Gigabit mode detected, enable gigbit in MAC
+ */
+ writel(readl(&(adap_emac[eth_priv->slave_port - 1].maccontrol)) |
+ EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
+ &(adap_emac[eth_priv->slave_port - 1].maccontrol))
+ ;
+}
+
+int keystone_sgmii_link_status(int port)
+{
+ u32 status = 0;
+
+ status = __raw_readl(SGMII_STATUS_REG(port));
+
+ return status & SGMII_REG_STATUS_LINK;
+}
+
+
+int keystone_get_link_status(struct eth_device *dev)
+{
+ struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+ int sgmii_link;
+ int link_state = 0;
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
+ int j;
+
+ for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
+ j++) {
+#endif
+ sgmii_link =
+ keystone_sgmii_link_status(eth_priv->slave_port - 1);
+
+ if (sgmii_link) {
+ link_state = 1;
+
+ if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)
+ if (gen_get_link_speed(eth_priv->phy_addr))
+ link_state = 0;
+ }
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
+ }
+#endif
+ return link_state;
+}
+
+int keystone_sgmii_config(int port, int interface)
+{
+ unsigned int i, status, mask;
+ unsigned int mr_adv_ability, control;
+
+ switch (interface) {
+ case SGMII_LINK_MAC_MAC_AUTONEG:
+ mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE |
+ SGMII_REG_MR_ADV_LINK |
+ SGMII_REG_MR_ADV_FULL_DUPLEX |
+ SGMII_REG_MR_ADV_GIG_MODE);
+ control = (SGMII_REG_CONTROL_MASTER |
+ SGMII_REG_CONTROL_AUTONEG);
+
+ break;
+ case SGMII_LINK_MAC_PHY:
+ case SGMII_LINK_MAC_PHY_FORCED:
+ mr_adv_ability = SGMII_REG_MR_ADV_ENABLE;
+ control = SGMII_REG_CONTROL_AUTONEG;
+
+ break;
+ case SGMII_LINK_MAC_MAC_FORCED:
+ mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE |
+ SGMII_REG_MR_ADV_LINK |
+ SGMII_REG_MR_ADV_FULL_DUPLEX |
+ SGMII_REG_MR_ADV_GIG_MODE);
+ control = SGMII_REG_CONTROL_MASTER;
+
+ break;
+ case SGMII_LINK_MAC_FIBER:
+ mr_adv_ability = 0x20;
+ control = SGMII_REG_CONTROL_AUTONEG;
+
+ break;
+ default:
+ mr_adv_ability = SGMII_REG_MR_ADV_ENABLE;
+ control = SGMII_REG_CONTROL_AUTONEG;
+ }
+
+ __raw_writel(0, SGMII_CTL_REG(port));
+
+ /*
+ * Wait for the SerDes pll to lock,
+ * but don't trap if lock is never read
+ */
+ for (i = 0; i < 1000; i++) {
+ udelay(2000);
+ status = __raw_readl(SGMII_STATUS_REG(port));
+ if ((status & SGMII_REG_STATUS_LOCK) != 0)
+ break;
+ }
+
+ __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port));
+ __raw_writel(control, SGMII_CTL_REG(port));
+
+
+ mask = SGMII_REG_STATUS_LINK;
+
+ if (control & SGMII_REG_CONTROL_AUTONEG)
+ mask |= SGMII_REG_STATUS_AUTONEG;
+
+ for (i = 0; i < 1000; i++) {
+ status = __raw_readl(SGMII_STATUS_REG(port));
+ if ((status & mask) == mask)
+ break;
+ }
+
+ return 0;
+}
+
+int mac_sl_reset(u32 port)
+{
+ u32 i, v;
+
+ if (port >= DEVICE_N_GMACSL_PORTS)
+ return GMACSL_RET_INVALID_PORT;
+
+ /* Set the soft reset bit */
+ DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) +
+ CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET);
+
+ /* Wait for the bit to clear */
+ for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
+ v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
+ CPGMACSL_REG_RESET);
+ if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
+ CPGMAC_REG_RESET_VAL_RESET)
+ return GMACSL_RET_OK;
+ }
+
+ /* Timeout on the reset */
+ return GMACSL_RET_WARN_RESET_INCOMPLETE;
+}
+
+int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
+{
+ u32 v, i;
+ int ret = GMACSL_RET_OK;
+
+ if (port >= DEVICE_N_GMACSL_PORTS)
+ return GMACSL_RET_INVALID_PORT;
+
+ if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) {
+ cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN;
+ ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG;
+ }
+
+ /* Must wait if the device is undergoing reset */
+ for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
+ v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
+ CPGMACSL_REG_RESET);
+ if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
+ CPGMAC_REG_RESET_VAL_RESET)
+ break;
+ }
+
+ if (i == DEVICE_EMACSL_RESET_POLL_COUNT)
+ return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE;
+
+ DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN,
+ cfg->max_rx_len);
+
+ DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL,
+ cfg->ctl);
+
+ return ret;
+}
+
+int ethss_config(u32 ctl, u32 max_pkt_size)
+{
+ u32 i;
+
+ /* Max length register */
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_MAXLEN, max_pkt_size);
+
+ /* Control register */
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_CTL, ctl);
+
+ /* All statistics enabled by default */
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN,
+ CPSW_REG_VAL_STAT_ENABLE_ALL);
+
+ /* Reset and enable the ALE */
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL,
+ CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE |
+ CPSW_REG_VAL_ALE_CTL_BYPASS);
+
+ /* All ports put into forward mode */
+ for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++)
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i),
+ CPSW_REG_VAL_PORTCTL_FORWARD_MODE);
+
+ return 0;
+}
+
+int ethss_start(void)
+{
+ int i;
+ struct mac_sl_cfg cfg;
+
+ cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER;
+ cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL;
+
+ for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) {
+ mac_sl_reset(i);
+ mac_sl_config(i, &cfg);
+ }
+
+ return 0;
+}
+
+int ethss_stop(void)
+{
+ int i;
+
+ for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++)
+ mac_sl_reset(i);
+
+ return 0;
+}
+
+int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num)
+{
+ if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
+ num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;
+
+ return netcp_send(buffer, num_bytes, (slave_port_num) << 16);
+}
+
+/* Eth device open */
+static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
+{
+ u_int32_t clkdiv;
+ int link;
+ struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+ debug("+ emac_open\n");
+
+ net_rx_buffs.rx_flow = eth_priv->rx_flow;
+
+ sys_has_mdio =
+ (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
+
+ psc_enable_module(KS2_LPSC_PA);
+ psc_enable_module(KS2_LPSC_CPGMAC);
+
+ sgmii_serdes_setup_156p25mhz();
+
+ if (sys_has_mdio)
+ keystone2_eth_mdio_enable();
+
+ keystone_sgmii_config(eth_priv->slave_port - 1,
+ eth_priv->sgmii_link_type);
+
+ udelay(10000);
+
+ /* On chip switch configuration */
+ ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);
+
+ /* TODO: add error handling code */
+ if (qm_init()) {
+ printf("ERROR: qm_init()\n");
+ return -1;
+ }
+ if (netcp_init(&net_rx_buffs)) {
+ qm_close();
+ printf("ERROR: netcp_init()\n");
+ return -1;
+ }
+
+ /*
+ * Streaming switch configuration. If not present this
+ * statement is defined to void in target.h.
+ * If present this is usually defined to a series of register writes
+ */
+ hw_config_streaming_switch();
+
+ if (sys_has_mdio) {
+ /* Init MDIO & get link state */
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+ writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE |
+ MDIO_CONTROL_FAULT, &adap_mdio->control)
+ ;
+
+ /* We need to wait for MDIO to start */
+ udelay(1000);
+
+ link = keystone_get_link_status(dev);
+ if (link == 0) {
+ netcp_close();
+ qm_close();
+ return -1;
+ }
+ }
+
+ emac_gigabit_enable(dev);
+
+ ethss_start();
+
+ debug("- emac_open\n");
+
+ emac_open = 1;
+
+ return 0;
+}
+
+/* Eth device close */
+void keystone2_eth_close(struct eth_device *dev)
+{
+ debug("+ emac_close\n");
+
+ if (!emac_open)
+ return;
+
+ ethss_stop();
+
+ netcp_close();
+ qm_close();
+
+ emac_open = 0;
+
+ debug("- emac_close\n");
+}
+
+static int tx_send_loop;
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int keystone2_eth_send_packet(struct eth_device *dev,
+ void *packet, int length)
+{
+ int ret_status = -1;
+ struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+ tx_send_loop = 0;
+
+ if (keystone_get_link_status(dev) == 0)
+ return -1;
+
+ emac_gigabit_enable(dev);
+
+ if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
+ return ret_status;
+
+ if (keystone_get_link_status(dev) == 0)
+ return -1;
+
+ emac_gigabit_enable(dev);
+
+ return length;
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int keystone2_eth_rcv_packet(struct eth_device *dev)
+{
+ void *hd;
+ int pkt_size;
+ u32 *pkt;
+
+ hd = netcp_recv(&pkt, &pkt_size);
+ if (hd == NULL)
+ return 0;
+
+ NetReceive((uchar *)pkt, pkt_size);
+
+ netcp_release_rxhd(hd);
+
+ return pkt_size;
+}
+
+/*
+ * This function initializes the EMAC hardware.
+ */
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
+{
+ struct eth_device *dev;
+
+ dev = malloc(sizeof(struct eth_device));
+ if (dev == NULL)
+ return -1;
+
+ memset(dev, 0, sizeof(struct eth_device));
+
+ strcpy(dev->name, eth_priv->int_name);
+ dev->priv = eth_priv;
+
+ keystone2_eth_read_mac_addr(dev);
+
+ dev->iobase = 0;
+ dev->init = keystone2_eth_open;
+ dev->halt = keystone2_eth_close;
+ dev->send = keystone2_eth_send_packet;
+ dev->recv = keystone2_eth_rcv_packet;
+
+ eth_register(dev);
+
+ return 0;
+}
+
+void sgmii_serdes_setup_156p25mhz(void)
+{
+ unsigned int cnt;
+
+ /*
+ * configure Serializer/Deserializer (SerDes) hardware. SerDes IP
+ * hardware vendor published only register addresses and their values
+ * to be used for configuring SerDes. So had to use hardcoded values
+ * below.
+ */
+ clrsetbits_le32(0x0232a000, 0xffff0000, 0x00800000);
+ clrsetbits_le32(0x0232a014, 0x0000ffff, 0x00008282);
+ clrsetbits_le32(0x0232a060, 0x00ffffff, 0x00142438);
+ clrsetbits_le32(0x0232a064, 0x00ffff00, 0x00c3c700);
+ clrsetbits_le32(0x0232a078, 0x0000ff00, 0x0000c000);
+
+ clrsetbits_le32(0x0232a204, 0xff0000ff, 0x38000080);
+ clrsetbits_le32(0x0232a208, 0x000000ff, 0x00000000);
+ clrsetbits_le32(0x0232a20c, 0xff000000, 0x02000000);
+ clrsetbits_le32(0x0232a210, 0xff000000, 0x1b000000);
+ clrsetbits_le32(0x0232a214, 0x0000ffff, 0x00006fb8);
+ clrsetbits_le32(0x0232a218, 0xffff00ff, 0x758000e4);
+ clrsetbits_le32(0x0232a2ac, 0x0000ff00, 0x00004400);
+ clrsetbits_le32(0x0232a22c, 0x00ffff00, 0x00200800);
+ clrsetbits_le32(0x0232a280, 0x00ff00ff, 0x00820082);
+ clrsetbits_le32(0x0232a284, 0xffffffff, 0x1d0f0385);
+
+ clrsetbits_le32(0x0232a404, 0xff0000ff, 0x38000080);
+ clrsetbits_le32(0x0232a408, 0x000000ff, 0x00000000);
+ clrsetbits_le32(0x0232a40c, 0xff000000, 0x02000000);
+ clrsetbits_le32(0x0232a410, 0xff000000, 0x1b000000);
+ clrsetbits_le32(0x0232a414, 0x0000ffff, 0x00006fb8);
+ clrsetbits_le32(0x0232a418, 0xffff00ff, 0x758000e4);
+ clrsetbits_le32(0x0232a4ac, 0x0000ff00, 0x00004400);
+ clrsetbits_le32(0x0232a42c, 0x00ffff00, 0x00200800);
+ clrsetbits_le32(0x0232a480, 0x00ff00ff, 0x00820082);
+ clrsetbits_le32(0x0232a484, 0xffffffff, 0x1d0f0385);
+
+ clrsetbits_le32(0x0232a604, 0xff0000ff, 0x38000080);
+ clrsetbits_le32(0x0232a608, 0x000000ff, 0x00000000);
+ clrsetbits_le32(0x0232a60c, 0xff000000, 0x02000000);
+ clrsetbits_le32(0x0232a610, 0xff000000, 0x1b000000);
+ clrsetbits_le32(0x0232a614, 0x0000ffff, 0x00006fb8);
+ clrsetbits_le32(0x0232a618, 0xffff00ff, 0x758000e4);
+ clrsetbits_le32(0x0232a6ac, 0x0000ff00, 0x00004400);
+ clrsetbits_le32(0x0232a62c, 0x00ffff00, 0x00200800);
+ clrsetbits_le32(0x0232a680, 0x00ff00ff, 0x00820082);
+ clrsetbits_le32(0x0232a684, 0xffffffff, 0x1d0f0385);
+
+ clrsetbits_le32(0x0232a804, 0xff0000ff, 0x38000080);
+ clrsetbits_le32(0x0232a808, 0x000000ff, 0x00000000);
+ clrsetbits_le32(0x0232a80c, 0xff000000, 0x02000000);
+ clrsetbits_le32(0x0232a810, 0xff000000, 0x1b000000);
+ clrsetbits_le32(0x0232a814, 0x0000ffff, 0x00006fb8);
+ clrsetbits_le32(0x0232a818, 0xffff00ff, 0x758000e4);
+ clrsetbits_le32(0x0232a8ac, 0x0000ff00, 0x00004400);
+ clrsetbits_le32(0x0232a82c, 0x00ffff00, 0x00200800);
+ clrsetbits_le32(0x0232a880, 0x00ff00ff, 0x00820082);
+ clrsetbits_le32(0x0232a884, 0xffffffff, 0x1d0f0385);
+
+ clrsetbits_le32(0x0232aa00, 0x0000ff00, 0x00000800);
+ clrsetbits_le32(0x0232aa08, 0xffff0000, 0x38a20000);
+ clrsetbits_le32(0x0232aa30, 0x00ffff00, 0x008a8a00);
+ clrsetbits_le32(0x0232aa84, 0x0000ff00, 0x00000600);
+ clrsetbits_le32(0x0232aa94, 0xff000000, 0x10000000);
+ clrsetbits_le32(0x0232aaa0, 0xff000000, 0x81000000);
+ clrsetbits_le32(0x0232aabc, 0xff000000, 0xff000000);
+ clrsetbits_le32(0x0232aac0, 0x000000ff, 0x0000008b);
+ clrsetbits_le32(0x0232ab08, 0xffff0000, 0x583f0000);
+ clrsetbits_le32(0x0232ab0c, 0x000000ff, 0x0000004e);
+ clrsetbits_le32(0x0232a000, 0x000000ff, 0x00000003);
+ clrsetbits_le32(0x0232aa00, 0x000000ff, 0x0000005f);
+
+ clrsetbits_le32(0x0232aa48, 0x00ffff00, 0x00fd8c00);
+ clrsetbits_le32(0x0232aa54, 0x00ffffff, 0x002fec72);
+ clrsetbits_le32(0x0232aa58, 0xffffff00, 0x00f92100);
+ clrsetbits_le32(0x0232aa5c, 0xffffffff, 0x00040060);
+ clrsetbits_le32(0x0232aa60, 0xffffffff, 0x00008000);
+ clrsetbits_le32(0x0232aa64, 0xffffffff, 0x0c581220);
+ clrsetbits_le32(0x0232aa68, 0xffffffff, 0xe13b0602);
+ clrsetbits_le32(0x0232aa6c, 0xffffffff, 0xb8074cc1);
+ clrsetbits_le32(0x0232aa70, 0xffffffff, 0x3f02e989);
+ clrsetbits_le32(0x0232aa74, 0x000000ff, 0x00000001);
+ clrsetbits_le32(0x0232ab20, 0x00ff0000, 0x00370000);
+ clrsetbits_le32(0x0232ab1c, 0xff000000, 0x37000000);
+ clrsetbits_le32(0x0232ab20, 0x000000ff, 0x0000005d);
+
+ /*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/
+ clrbits_le32(0x0232a010, 1 << 28);
+
+ /* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */
+ clrbits_le32(0x0232a228, 1 << 29);
+ writel(0xF800F8C0, 0x0232bfe0);
+ clrbits_le32(0x0232a428, 1 << 29);
+ writel(0xF800F8C0, 0x0232bfe4);
+ clrbits_le32(0x0232a628, 1 << 29);
+ writel(0xF800F8C0, 0x0232bfe8);
+ clrbits_le32(0x0232a828, 1 << 29);
+ writel(0xF800F8C0, 0x0232bfec);
+
+ /*Enable pll via the pll_ctrl 0x0014*/
+ writel(0xe0000000, 0x0232bff4)
+ ;
+
+ /*Waiting for SGMII Serdes PLL lock.*/
+ for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--)
+ ;
+
+ for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--)
+ ;
+
+ for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--)
+ ;
+
+ for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--)
+ ;
+
+ udelay(45000);
+}
+
+void sgmii_serdes_shutdown(void)
+{
+ /*
+ * shutdown SerDes hardware. SerDes hardware vendor published only
+ * register addresses and their values. So had to use hardcoded
+ * values below.
+ */
+ clrbits_le32(0x0232bfe0, 3 << 29 | 3 << 13);
+ setbits_le32(0x02320228, 1 << 29);
+ clrbits_le32(0x0232bfe4, 3 << 29 | 3 << 13);
+ setbits_le32(0x02320428, 1 << 29);
+ clrbits_le32(0x0232bfe8, 3 << 29 | 3 << 13);
+ setbits_le32(0x02320628, 1 << 29);
+ clrbits_le32(0x0232bfec, 3 << 29 | 3 << 13);
+ setbits_le32(0x02320828, 1 << 29);
+
+ clrbits_le32(0x02320034, 3 << 29);
+ setbits_le32(0x02320010, 1 << 28);
+}
diff --git a/drivers/net/phy/atheros.c b/drivers/net/phy/atheros.c
index abd4e5b463..d509e30d35 100644
--- a/drivers/net/phy/atheros.c
+++ b/drivers/net/phy/atheros.c
@@ -31,9 +31,7 @@ static int ar8035_config(struct phy_device *phydev)
regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));
- genphy_config_aneg(phydev);
-
- phy_reset(phydev);
+ phydev->supported = phydev->drv->features;
return 0;
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c691fbbbc6..230ed97dd1 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -18,6 +18,7 @@
#include <phy.h>
#include <errno.h>
#include <linux/err.h>
+#include <linux/compiler.h>
/* Generic PHY support and helper functions */
@@ -577,7 +578,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
* Description: Reads the ID registers of the PHY at @addr on the
* @bus, stores it in @phy_id and returns zero on success.
*/
-static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
+int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
{
int phy_reg;
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 101489c994..3cadd23bb4 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -11,6 +11,7 @@
#include <common.h>
#include <net.h>
+#include <netdev.h>
#include <config.h>
#include <fdtdec.h>
#include <libfdt.h>
@@ -338,7 +339,8 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
phy_detection(dev);
/* interface - look at tsec */
- phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
+ phydev = phy_connect(priv->bus, priv->phyaddr, dev,
+ PHY_INTERFACE_MODE_MII);
phydev->supported = supported | ADVERTISED_Pause |
ADVERTISED_Asym_Pause;
diff --git a/drivers/power/tps6586x.c b/drivers/power/tps6586x.c
index 704c2439b1..d29d969533 100644
--- a/drivers/power/tps6586x.c
+++ b/drivers/power/tps6586x.c
@@ -32,7 +32,7 @@ enum {
};
#define MAX_I2C_RETRY 3
-int tps6586x_read(int reg)
+static int tps6586x_read(int reg)
{
int i;
uchar data;
@@ -61,7 +61,7 @@ exit:
return retval;
}
-int tps6586x_write(int reg, uchar *data, uint len)
+static int tps6586x_write(int reg, uchar *data, uint len)
{
int i;
int retval = -1;
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index fbc37b27e8..f26979dbe1 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -30,6 +30,17 @@
#define serial_in(y) readb(y)
#endif
+#if defined(CONFIG_K2HK_EVM)
+#define UART_REG_VAL_PWREMU_MGMT_UART_DISABLE 0
+#define UART_REG_VAL_PWREMU_MGMT_UART_ENABLE ((1 << 14) | (1 << 13) | (1 << 0))
+#undef UART_MCRVAL
+#ifdef CONFIG_SERIAL_HW_FLOW_CONTROL
+#define UART_MCRVAL (UART_MCR_RTS | UART_MCR_AFE)
+#else
+#define UART_MCRVAL (UART_MCR_RTS)
+#endif
+#endif
+
#ifndef CONFIG_SYS_NS16550_IER
#define CONFIG_SYS_NS16550_IER 0x00
#endif /* CONFIG_SYS_NS16550_IER */
@@ -77,6 +88,9 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
/* /16 is proper to hit 115200 with 48MHz */
serial_out(0, &com_port->mdr1);
#endif /* CONFIG_OMAP */
+#if defined(CONFIG_K2HK_EVM)
+ serial_out(UART_REG_VAL_PWREMU_MGMT_UART_ENABLE, &com_port->regC);
+#endif
}
#ifndef CONFIG_NS16550_MIN_FUNCTIONS
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index df05bde461..fd61a5e545 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -74,9 +74,6 @@ static int on_baudrate(const char *name, const char *value, enum env_op op,
}
gd->baudrate = baudrate;
-#if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2)
- gd->bd->bi_baudrate = baudrate;
-#endif
serial_setbrg();
@@ -117,7 +114,7 @@ serial_initfunc(ns16550_serial_initialize);
serial_initfunc(pxa_serial_initialize);
serial_initfunc(s3c24xx_serial_initialize);
serial_initfunc(s5p_serial_initialize);
-serial_initfunc(zynq_serial_initalize);
+serial_initfunc(zynq_serial_initialize);
serial_initfunc(bfin_serial_initialize);
serial_initfunc(bfin_jtag_initialize);
serial_initfunc(mpc512x_serial_initialize);
@@ -214,7 +211,7 @@ void serial_initialize(void)
bfin_serial_initialize();
bfin_jtag_initialize();
uartlite_serial_initialize();
- zynq_serial_initalize();
+ zynq_serial_initialize();
au1x00_serial_initialize();
asc_serial_initialize();
jz_serial_initialize();
@@ -502,12 +499,11 @@ int uart_post_test(int flags)
unsigned char c;
int ret, saved_baud, b;
struct serial_device *saved_dev, *s;
- bd_t *bd = gd->bd;
/* Save current serial state */
ret = 0;
saved_dev = serial_current;
- saved_baud = bd->bi_baudrate;
+ saved_baud = gd->baudrate;
for (s = serial_devices; s; s = s->next) {
/* If this driver doesn't support loop back, skip it */
@@ -530,7 +526,7 @@ int uart_post_test(int flags)
/* Test every available baud rate */
for (b = 0; b < ARRAY_SIZE(bauds); ++b) {
- bd->bi_baudrate = bauds[b];
+ gd->baudrate = bauds[b];
serial_setbrg();
/*
@@ -572,7 +568,7 @@ int uart_post_test(int flags)
done:
/* Restore previous serial state */
serial_current = saved_dev;
- bd->bi_baudrate = saved_baud;
+ gd->baudrate = saved_baud;
serial_reinit_all();
serial_setbrg();
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 53a8af02d6..1ff27d5f48 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -153,17 +153,17 @@ static int uart_zynq_serial_getc(const int port)
/* Multi serial device functions */
#define DECLARE_PSSERIAL_FUNCTIONS(port) \
- int uart_zynq##port##_init(void) \
+ static int uart_zynq##port##_init(void) \
{ return uart_zynq_serial_init(port); } \
- void uart_zynq##port##_setbrg(void) \
+ static void uart_zynq##port##_setbrg(void) \
{ return uart_zynq_serial_setbrg(port); } \
- int uart_zynq##port##_getc(void) \
+ static int uart_zynq##port##_getc(void) \
{ return uart_zynq_serial_getc(port); } \
- int uart_zynq##port##_tstc(void) \
+ static int uart_zynq##port##_tstc(void) \
{ return uart_zynq_serial_tstc(port); } \
- void uart_zynq##port##_putc(const char c) \
+ static void uart_zynq##port##_putc(const char c) \
{ uart_zynq_serial_putc(c, port); } \
- void uart_zynq##port##_puts(const char *s) \
+ static void uart_zynq##port##_puts(const char *s) \
{ uart_zynq_serial_puts(s, port); }
/* Serial device descriptor */
@@ -179,10 +179,10 @@ static int uart_zynq_serial_getc(const int port)
}
DECLARE_PSSERIAL_FUNCTIONS(0);
-struct serial_device uart_zynq_serial0_device =
+static struct serial_device uart_zynq_serial0_device =
INIT_PSSERIAL_STRUCTURE(0, "ttyPS0");
DECLARE_PSSERIAL_FUNCTIONS(1);
-struct serial_device uart_zynq_serial1_device =
+static struct serial_device uart_zynq_serial1_device =
INIT_PSSERIAL_STRUCTURE(1, "ttyPS1");
#ifdef CONFIG_OF_CONTROL
@@ -223,7 +223,7 @@ __weak struct serial_device *default_serial_console(void)
}
#endif
-void zynq_serial_initalize(void)
+void zynq_serial_initialize(void)
{
serial_register(&uart_zynq_serial0_device);
serial_register(&uart_zynq_serial1_device);
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index e3fb3212aa..28fb3a2e9f 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!ds)
return NULL;
- ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+ ds->slave.bus = bus;
+ ds->slave.cs = cs;
+
+ switch (bus) {
+ case SPI0_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+ break;
+#ifdef CONFIG_SYS_SPI1
+ case SPI1_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+ break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+ case SPI2_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+ break;
+#endif
+ default: /* Invalid bus number */
+ return NULL;
+ }
+
ds->freq = max_hz;
return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
/* CS, CLK, SIMO and SOMI are functional pins */
- writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+ writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
/* setup format */
@@ -264,7 +284,30 @@ out:
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
- return bus == 0 && cs == 0;
+ int ret = 0;
+
+ switch (bus) {
+ case SPI0_BUS:
+ if (cs < SPI0_NUM_CS)
+ ret = 1;
+ break;
+#ifdef CONFIG_SYS_SPI1
+ case SPI1_BUS:
+ if (cs < SPI1_NUM_CS)
+ ret = 1;
+ break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+ case SPI2_BUS:
+ if (cs < SPI2_NUM_CS)
+ ret = 1;
+ break;
+#endif
+ default:
+ /* Invalid bus number. Do nothing */
+ break;
+ }
+ return ret;
}
void spi_cs_activate(struct spi_slave *slave)
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h
index 33f69b5ca9..d4612d3527 100644
--- a/drivers/spi/davinci_spi.h
+++ b/drivers/spi/davinci_spi.h
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
/* SPIDEF */
#define SPIDEF_CSDEF0_MASK BIT(0)
+#define SPI0_BUS 0
+#define SPI0_BASE CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses this
+ * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS 1
+#else
+#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI1
+#define SPI1_BUS 1
+#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI2
+#define SPI2_BUS 2
+#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE CONFIG_SYS_SPI2_BASE
+#endif
+
struct davinci_spi_slave {
struct spi_slave slave;
struct davinci_spi_regs *regs;
diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c
index 603c024bcc..b5d561be34 100644
--- a/drivers/spi/tegra20_sflash.c
+++ b/drivers/spi/tegra20_sflash.c
@@ -208,9 +208,9 @@ int tegra20_spi_claim_bus(struct spi_slave *slave)
* SPI pins on Tegra20 are muxed - change pinmux later due to UART
* issue.
*/
- pinmux_set_func(PINGRP_GMD, PMUX_FUNC_SFLASH);
- pinmux_tristate_disable(PINGRP_LSPI);
- pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH);
+ pinmux_set_func(PMUX_PINGRP_GMD, PMUX_FUNC_SFLASH);
+ pinmux_tristate_disable(PMUX_PINGRP_LSPI);
+ pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_SFLASH);
return 0;
}
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
index dfa5d0ca21..c5d2245e44 100644
--- a/drivers/spi/ti_qspi.c
+++ b/drivers/spi/ti_qspi.c
@@ -314,6 +314,9 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
qslave->cmd |= QSPI_RD_SNGL;
debug("rx cmd %08x dc %08x\n",
qslave->cmd, qslave->dc);
+ #ifdef CONFIG_DRA7XX
+ udelay(500);
+ #endif
writel(qslave->cmd, &qslave->base->cmd);
status = readl(&qslave->base->status);
timeout = QSPI_TIMEOUT;
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 804a2bd412..896c8d407e 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -13,6 +13,7 @@ ifdef CONFIG_USB_GADGET
obj-$(CONFIG_USB_GADGET_ATMEL_USBA) += atmel_usba_udc.o
obj-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
+obj-$(CONFIG_CI_UDC) += ci_udc.o
obj-$(CONFIG_THOR_FUNCTION) += f_thor.o
obj-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
obj-$(CONFIG_DFU_FUNCTION) += f_dfu.o
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index 14b1e9b8bf..02d3fdade8 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -321,7 +321,7 @@ static void ci_debounce(struct ci_ep *ep, int in)
if (addr == ba)
return; /* not a bounce */
- memcpy(ep->req.buf, ep->b_buf, ep->req.length);
+ memcpy(ep->req.buf, ep->b_buf, ep->req.actual);
free:
/* Large payloads use allocated buffer, free it. */
if (ep->b_buf != ep->b_fast)
@@ -350,6 +350,9 @@ static int ci_ep_queue(struct usb_ep *ep,
item->info = INFO_BYTES(len) | INFO_IOC | INFO_ACTIVE;
item->page0 = (uint32_t)ci_ep->b_buf;
item->page1 = ((uint32_t)ci_ep->b_buf & 0xfffff000) + 0x1000;
+ item->page2 = ((uint32_t)ci_ep->b_buf & 0xfffff000) + 0x2000;
+ item->page3 = ((uint32_t)ci_ep->b_buf & 0xfffff000) + 0x3000;
+ item->page4 = ((uint32_t)ci_ep->b_buf & 0xfffff000) + 0x4000;
ci_flush_qtd(num);
head->next = (unsigned) item;
@@ -385,7 +388,7 @@ static void handle_ep_complete(struct ci_ep *ep)
num, in ? "in" : "out", item->info, item->page0);
len = (item->info >> 16) & 0x7fff;
- ep->req.length -= len;
+ ep->req.actual = ep->req.length - len;
ci_debounce(ep, in);
DBG("ept%d %s complete %x\n",
@@ -413,7 +416,11 @@ static void handle_setup(void)
ci_invalidate_qh(0);
memcpy(&r, head->setup_data, sizeof(struct usb_ctrlrequest));
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+ writel(EPT_RX(0), &udc->epsetupstat);
+#else
writel(EPT_RX(0), &udc->epstat);
+#endif
DBG("handle setup %s, %x, %x index %x value %x\n", reqname(r.bRequest),
r.bRequestType, r.bRequest, r.wIndex, r.wValue);
@@ -480,6 +487,9 @@ static void stop_activity(void)
struct ept_queue_head *head;
struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
writel(readl(&udc->epcomp), &udc->epcomp);
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+ writel(readl(&udc->epsetupstat), &udc->epsetupstat);
+#endif
writel(readl(&udc->epstat), &udc->epstat);
writel(0xffffffff, &udc->epflush);
@@ -521,7 +531,11 @@ void udc_irq(void)
int max = 64;
int speed = USB_SPEED_FULL;
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+ bit = (readl(&udc->hostpc1_devlc) >> 25) & 3;
+#else
bit = (readl(&udc->portsc) >> 26) & 3;
+#endif
DBG("-- portchange %x %s\n", bit, (bit == 2) ? "High" : "Full");
if (bit == 2) {
speed = USB_SPEED_HIGH;
@@ -538,7 +552,11 @@ void udc_irq(void)
printf("<UEI %x>\n", readl(&udc->epcomp));
if ((n & STS_UI) || (n & STS_UEI)) {
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+ n = readl(&udc->epsetupstat);
+#else
n = readl(&udc->epstat);
+#endif
if (n & EPT_RX(0))
handle_setup();
@@ -699,7 +717,6 @@ static int ci_udc_probe(void)
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
{
- struct ci_udc *udc;
int ret;
if (!driver)
@@ -714,12 +731,18 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
return ret;
ret = ci_udc_probe();
+#if defined(CONFIG_USB_EHCI_MX6) || defined(CONFIG_USB_EHCI_MXS)
+ /*
+ * FIXME: usb_lowlevel_init()->ehci_hcd_init() should be doing all
+ * HW-specific initialization, e.g. ULPI-vs-UTMI PHY selection
+ */
if (!ret) {
- udc = (struct ci_udc *)controller.ctrl->hcor;
+ struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
/* select ULPI phy */
writel(PTS(PTS_ENABLE) | PFSC, &udc->portsc);
}
+#endif
ret = driver->bind(&controller.gadget);
if (ret) {
diff --git a/drivers/usb/gadget/ci_udc.h b/drivers/usb/gadget/ci_udc.h
index 42f6ef4ab3..4425fd9345 100644
--- a/drivers/usb/gadget/ci_udc.h
+++ b/drivers/usb/gadget/ci_udc.h
@@ -8,45 +8,74 @@
#define NUM_ENDPOINTS 6
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+struct ci_udc {
+ u32 usbcmd; /* 0x130 */
+ u32 usbsts; /* 0x134 */
+ u32 pad1[3];
+ u32 devaddr; /* 0x144 */
+ u32 epinitaddr; /* 0x148 */
+ u32 pad2[10];
+ u32 portsc; /* 0x174 */
+ u32 pad178[(0x1b4 - (0x174 + 4)) / 4];
+ u32 hostpc1_devlc; /* 0x1b4 */
+ u32 pad1b8[(0x1f8 - (0x1b4 + 4)) / 4];
+ u32 usbmode; /* 0x1f8 */
+ u32 pad1fc[(0x208 - (0x1f8 + 4)) / 4];
+ u32 epsetupstat; /* 0x208 */
+ u32 epprime; /* 0x20c */
+ u32 epflush; /* 0x210 */
+ u32 epstat; /* 0x214 */
+ u32 epcomp; /* 0x218 */
+ u32 epctrl[16]; /* 0x21c */
+};
+#else
struct ci_udc {
-#define MICRO_8FRAME 0x8
-#define USBCMD_ITC(x) ((((x) > 0xff) ? 0xff : x) << 16)
-#define USBCMD_FS2 (1 << 15)
-#define USBCMD_RST (1 << 1)
-#define USBCMD_RUN (1)
u32 usbcmd; /* 0x140 */
-#define STS_SLI (1 << 8)
-#define STS_URI (1 << 6)
-#define STS_PCI (1 << 2)
-#define STS_UEI (1 << 1)
-#define STS_UI (1 << 0)
u32 usbsts; /* 0x144 */
u32 pad1[3];
u32 devaddr; /* 0x154 */
u32 epinitaddr; /* 0x158 */
u32 pad2[10];
-#define PTS_ENABLE 2
-#define PTS(x) (((x) & 0x3) << 30)
-#define PFSC (1 << 24)
u32 portsc; /* 0x184 */
u32 pad3[8];
-#define USBMODE_DEVICE 2
u32 usbmode; /* 0x1a8 */
u32 epstat; /* 0x1ac */
-#define EPT_TX(x) (1 << (((x) & 0xffff) + 16))
-#define EPT_RX(x) (1 << ((x) & 0xffff))
u32 epprime; /* 0x1b0 */
u32 epflush; /* 0x1b4 */
u32 pad4;
u32 epcomp; /* 0x1bc */
+ u32 epctrl[16]; /* 0x1c0 */
+};
+
+#define PTS_ENABLE 2
+#define PTS(x) (((x) & 0x3) << 30)
+#define PFSC (1 << 24)
+#endif
+
+#define MICRO_8FRAME 0x8
+#define USBCMD_ITC(x) ((((x) > 0xff) ? 0xff : x) << 16)
+#define USBCMD_FS2 (1 << 15)
+#define USBCMD_RST (1 << 1)
+#define USBCMD_RUN (1)
+
+#define STS_SLI (1 << 8)
+#define STS_URI (1 << 6)
+#define STS_PCI (1 << 2)
+#define STS_UEI (1 << 1)
+#define STS_UI (1 << 0)
+
+#define USBMODE_DEVICE 2
+
+#define EPT_TX(x) (1 << (((x) & 0xffff) + 16))
+#define EPT_RX(x) (1 << ((x) & 0xffff))
+
#define CTRL_TXE (1 << 23)
#define CTRL_TXR (1 << 22)
#define CTRL_RXE (1 << 7)
#define CTRL_RXR (1 << 6)
#define CTRL_TXT_BULK (2 << 18)
#define CTRL_RXT_BULK (2 << 2)
- u32 epctrl[16]; /* 0x1c0 */
-};
struct ci_ep {
struct usb_ep ep;
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index de75ff1339..1b1e1793d9 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -24,6 +24,7 @@
#include <linux/usb/composite.h>
#include <dfu.h>
+#include <g_dnl.h>
#include "f_dfu.h"
struct f_dfu {
@@ -817,3 +818,5 @@ int dfu_add(struct usb_configuration *c)
return dfu_bind_config(c);
}
+
+DECLARE_GADGET_BIND_CALLBACK(usb_dnl_dfu, dfu_add);
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index f896169743..6374bb953a 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -243,7 +243,7 @@
#include <config.h>
#include <malloc.h>
#include <common.h>
-#include <usb.h>
+#include <g_dnl.h>
#include <linux/err.h>
#include <linux/usb/ch9.h>
@@ -255,6 +255,7 @@
#include <linux/usb/gadget.h>
#include <linux/usb/composite.h>
#include <usb/lin_gadget_compat.h>
+#include <g_dnl.h>
/*------------------------------------------------------------------------*/
@@ -680,11 +681,11 @@ static int sleep_thread(struct fsg_common *common)
/* Handle CTRL+C */
if (ctrlc())
return -EPIPE;
-#ifdef CONFIG_USB_CABLE_CHECK
+
/* Check cable connection */
- if (!usb_cable_connected())
+ if (!g_dnl_board_usb_cable_connected())
return -EIO;
-#endif
+
k = 0;
}
@@ -2778,3 +2779,5 @@ int fsg_init(struct ums *ums_dev)
return 0;
}
+
+DECLARE_GADGET_BIND_CALLBACK(usb_dnl_ums, fsg_add);
diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c
index f5c0224f21..feef9e4619 100644
--- a/drivers/usb/gadget/f_thor.c
+++ b/drivers/usb/gadget/f_thor.c
@@ -204,14 +204,14 @@ static long long int download_head(unsigned long long total,
static int download_tail(long long int left, int cnt)
{
+ struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
void *transfer_buffer = dfu_get_buf();
int ret;
debug("%s: left: %llu cnt: %d\n", __func__, left, cnt);
if (left) {
- ret = dfu_write(dfu_get_entity(alt_setting_num),
- transfer_buffer, left, cnt++);
+ ret = dfu_write(dfu_entity, transfer_buffer, left, cnt++);
if (ret) {
error("DFU write failed [%d]: left: %llu", ret, left);
return ret;
@@ -225,11 +225,16 @@ static int download_tail(long long int left, int cnt)
* This also frees memory malloc'ed by dfu_get_buf(), so no explicit
* need fo call dfu_free_buf() is needed.
*/
- ret = dfu_write(dfu_get_entity(alt_setting_num),
- transfer_buffer, 0, cnt);
+ ret = dfu_write(dfu_entity, transfer_buffer, 0, cnt);
if (ret)
error("DFU write failed [%d] cnt: %d", ret, cnt);
+ ret = dfu_flush(dfu_entity, transfer_buffer, 0, cnt);
+ if (ret) {
+ error("DFU flush failed!");
+ return ret;
+ }
+
return ret;
}
@@ -999,3 +1004,5 @@ int thor_add(struct usb_configuration *c)
debug("%s:\n", __func__);
return thor_func_init(c);
}
+
+DECLARE_GADGET_BIND_CALLBACK(usb_dnl_thor, thor_add);
diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c
index dd95afe86a..25611acd60 100644
--- a/drivers/usb/gadget/g_dnl.c
+++ b/drivers/usb/gadget/g_dnl.c
@@ -41,7 +41,6 @@
#define DRIVER_VERSION "usb_dnl 2.0"
-static const char shortname[] = "usb_dnl_";
static const char product[] = "USB download gadget";
static char g_dnl_serial[MAX_STRING_SERIAL];
static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER;
@@ -96,29 +95,36 @@ static int g_dnl_unbind(struct usb_composite_dev *cdev)
free(cdev->config);
cdev->config = NULL;
debug("%s: calling usb_gadget_disconnect for "
- "controller '%s'\n", shortname, gadget->name);
+ "controller '%s'\n", __func__, gadget->name);
usb_gadget_disconnect(gadget);
return 0;
}
+static inline struct g_dnl_bind_callback *g_dnl_bind_callback_first(void)
+{
+ return ll_entry_start(struct g_dnl_bind_callback,
+ g_dnl_bind_callbacks);
+}
+
+static inline struct g_dnl_bind_callback *g_dnl_bind_callback_end(void)
+{
+ return ll_entry_end(struct g_dnl_bind_callback,
+ g_dnl_bind_callbacks);
+}
+
static int g_dnl_do_config(struct usb_configuration *c)
{
const char *s = c->cdev->driver->name;
- int ret = -1;
+ struct g_dnl_bind_callback *callback = g_dnl_bind_callback_first();
debug("%s: configuration: 0x%p composite dev: 0x%p\n",
__func__, c, c->cdev);
- printf("GADGET DRIVER: %s\n", s);
- if (!strcmp(s, "usb_dnl_dfu"))
- ret = dfu_add(c);
- else if (!strcmp(s, "usb_dnl_ums"))
- ret = fsg_add(c);
- else if (!strcmp(s, "usb_dnl_thor"))
- ret = thor_add(c);
-
- return ret;
+ for (; callback != g_dnl_bind_callback_end(); callback++)
+ if (!strcmp(s, callback->usb_function_name))
+ return callback->fptr(c);
+ return -ENODEV;
}
static int g_dnl_config_register(struct usb_composite_dev *cdev)
@@ -152,6 +158,11 @@ __weak int g_dnl_get_board_bcd_device_number(int gcnum)
return gcnum;
}
+__weak int g_dnl_board_usb_cable_connected(void)
+{
+ return -EOPNOTSUPP;
+}
+
static int g_dnl_get_bcd_device_number(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
@@ -203,12 +214,12 @@ static int g_dnl_bind(struct usb_composite_dev *cdev)
device_desc.bcdDevice = cpu_to_le16(gcnum);
else {
debug("%s: controller '%s' not recognized\n",
- shortname, gadget->name);
+ __func__, gadget->name);
device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
}
debug("%s: calling usb_gadget_connect for "
- "controller '%s'\n", shortname, gadget->name);
+ "controller '%s'\n", __func__, gadget->name);
usb_gadget_connect(gadget);
return 0;
@@ -227,36 +238,23 @@ static struct usb_composite_driver g_dnl_driver = {
.unbind = g_dnl_unbind,
};
-int g_dnl_register(const char *type)
+/*
+ * NOTICE:
+ * Registering via USB function name won't be necessary after rewriting
+ * g_dnl to support multiple USB functions.
+ */
+int g_dnl_register(const char *name)
{
- /* The largest function name is 4 */
- static char name[sizeof(shortname) + 4];
int ret;
- if (!strcmp(type, "dfu")) {
- strcpy(name, shortname);
- strcat(name, type);
- } else if (!strcmp(type, "ums")) {
- strcpy(name, shortname);
- strcat(name, type);
- } else if (!strcmp(type, "thor")) {
- strcpy(name, shortname);
- strcat(name, type);
- } else {
- printf("%s: unknown command: %s\n", __func__, type);
- return -EINVAL;
- }
-
+ debug("%s: g_dnl_driver.name = %s\n", __func__, name);
g_dnl_driver.name = name;
- debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name);
ret = usb_composite_register(&g_dnl_driver);
-
if (ret) {
printf("%s: failed!, error: %d\n", __func__, ret);
return ret;
}
-
return 0;
}
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 02803df23c..74300746b9 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -311,7 +311,11 @@ static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */
/* Number of buffers we will use. 2 is enough for double-buffering */
+#ifndef CONFIG_CI_UDC
#define FSG_NUM_BUFFERS 2
+#else
+#define FSG_NUM_BUFFERS 1 /* ci_udc only allows 1 req per ep at present */
+#endif
/* Default size of buffer length. */
#define FSG_BUFLEN ((u32)16384)
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c
index de5fa3f648..8c3ff64fe3 100644
--- a/drivers/usb/gadget/usbstring.c
+++ b/drivers/usb/gadget/usbstring.c
@@ -108,6 +108,9 @@ usb_gadget_get_string(struct usb_gadget_strings *table, int id, u8 *buf)
struct usb_string *s;
int len;
+ if (!table)
+ return -EINVAL;
+
/* descriptor 0 has the language id */
if (id == 0) {
buf[0] = 4;
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 578b097fc9..b301e28252 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o
obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
+obj-$(CONFIG_USB_EHCI_RMOBILE) += ehci-rmobile.o
# xhci
obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 9356878eb2..edd91a84a7 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -197,7 +197,8 @@ int ehci_hcd_init(int index, enum usb_init_type init,
#ifdef CONFIG_OF_CONTROL
/* setup the Vbus gpio here */
- if (!fdtdec_setup_gpio(&ctx->vbus_gpio))
+ if (fdt_gpio_isvalid(&ctx->vbus_gpio) &&
+ !fdtdec_setup_gpio(&ctx->vbus_gpio))
gpio_direction_output(ctx->vbus_gpio.gpio, 1);
#endif
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6017090ebe..eaf59134cb 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -998,8 +998,8 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
if (!ehcic[index].periodic_list)
return -ENOMEM;
for (i = 0; i < 1024; i++) {
- ehcic[index].periodic_list[i] = (uint32_t)periodic
- | QH_LINK_TYPE_QH;
+ ehcic[index].periodic_list[i] = cpu_to_hc32((uint32_t)periodic
+ | QH_LINK_TYPE_QH);
}
flush_dcache_range((uint32_t)ehcic[index].periodic_list,
@@ -1089,7 +1089,7 @@ struct int_queue {
struct qTD *tds;
};
-#define NEXT_QH(qh) (struct QH *)((qh)->qh_link & ~0x1f)
+#define NEXT_QH(qh) (struct QH *)(hc32_to_cpu((qh)->qh_link) & ~0x1f)
static int
enable_periodic(struct ehci_ctrl *ctrl)
@@ -1184,41 +1184,47 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
struct qTD *td = result->tds + i;
void **buf = &qh->buffer;
- qh->qh_link = (uint32_t)(qh+1) | QH_LINK_TYPE_QH;
+ qh->qh_link = cpu_to_hc32((uint32_t)(qh+1) | QH_LINK_TYPE_QH);
if (i == queuesize - 1)
- qh->qh_link = QH_LINK_TERMINATE;
+ qh->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
- qh->qh_overlay.qt_next = (uint32_t)td;
- qh->qh_overlay.qt_altnext = QT_NEXT_TERMINATE;
- qh->qh_endpt1 = (0 << 28) | /* No NAK reload (ehci 4.9) */
+ qh->qh_overlay.qt_next = cpu_to_hc32((uint32_t)td);
+ qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+ qh->qh_endpt1 =
+ cpu_to_hc32((0 << 28) | /* No NAK reload (ehci 4.9) */
(usb_maxpacket(dev, pipe) << 16) | /* MPS */
(1 << 14) |
QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
(usb_pipeendpoint(pipe) << 8) | /* Endpoint Number */
- (usb_pipedevice(pipe) << 0);
- qh->qh_endpt2 = (1 << 30) | /* 1 Tx per mframe */
- (1 << 0); /* S-mask: microframe 0 */
+ (usb_pipedevice(pipe) << 0));
+ qh->qh_endpt2 = cpu_to_hc32((1 << 30) | /* 1 Tx per mframe */
+ (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 |= (dev->portnr << 23) |
+ qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) |
(dev->parent->devnum << 16) |
- (0x1c << 8); /* C-mask: microframes 2-4 */
+ (0x1c << 8)); /* C-mask: microframes 2-4 */
}
- td->qt_next = QT_NEXT_TERMINATE;
- td->qt_altnext = QT_NEXT_TERMINATE;
+ td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+ td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
debug("communication direction is '%s'\n",
usb_pipein(pipe) ? "in" : "out");
- td->qt_token = (elementsize << 16) |
+ td->qt_token = cpu_to_hc32((elementsize << 16) |
((usb_pipein(pipe) ? 1 : 0) << 8) | /* IN/OUT token */
- 0x80; /* active */
- td->qt_buffer[0] = (uint32_t)buffer + i * elementsize;
- td->qt_buffer[1] = (td->qt_buffer[0] + 0x1000) & ~0xfff;
- td->qt_buffer[2] = (td->qt_buffer[0] + 0x2000) & ~0xfff;
- td->qt_buffer[3] = (td->qt_buffer[0] + 0x3000) & ~0xfff;
- td->qt_buffer[4] = (td->qt_buffer[0] + 0x4000) & ~0xfff;
+ 0x80); /* active */
+ td->qt_buffer[0] =
+ cpu_to_hc32((uint32_t)buffer + i * elementsize);
+ td->qt_buffer[1] =
+ cpu_to_hc32((td->qt_buffer[0] + 0x1000) & ~0xfff);
+ td->qt_buffer[2] =
+ cpu_to_hc32((td->qt_buffer[0] + 0x2000) & ~0xfff);
+ td->qt_buffer[3] =
+ cpu_to_hc32((td->qt_buffer[0] + 0x3000) & ~0xfff);
+ td->qt_buffer[4] =
+ cpu_to_hc32((td->qt_buffer[0] + 0x4000) & ~0xfff);
*buf = buffer + i * elementsize;
}
@@ -1241,7 +1247,7 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
/* hook up to periodic list */
struct QH *list = &ctrl->periodic_queue;
result->last->qh_link = list->qh_link;
- list->qh_link = (uint32_t)result->first | QH_LINK_TYPE_QH;
+ list->qh_link = cpu_to_hc32((uint32_t)result->first | QH_LINK_TYPE_QH);
flush_dcache_range((uint32_t)result->last,
ALIGN_END_ADDR(struct QH, result->last, 1));
@@ -1280,7 +1286,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
/* still active */
invalidate_dcache_range((uint32_t)cur,
ALIGN_END_ADDR(struct QH, cur, 1));
- if (cur->qh_overlay.qt_token & 0x80) {
+ 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);
return NULL;
@@ -1311,7 +1317,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
struct QH *cur = &ctrl->periodic_queue;
timeout = get_timer(0) + 500; /* abort after 500ms */
- while (!(cur->qh_link & QH_LINK_TERMINATE)) {
+ while (!(cur->qh_link & cpu_to_hc32(QH_LINK_TERMINATE))) {
debug("considering %p, with qh_link %x\n", cur, cur->qh_link);
if (NEXT_QH(cur) == queue->first) {
debug("found candidate. removing from chain\n");
diff --git a/drivers/usb/host/ehci-rmobile.c b/drivers/usb/host/ehci-rmobile.c
new file mode 100644
index 0000000000..049e4c4e6b
--- /dev/null
+++ b/drivers/usb/host/ehci-rmobile.c
@@ -0,0 +1,130 @@
+/*
+ * EHCI HCD (Host Controller Driver) for USB.
+ *
+ * Copyright (C) 2013,2014 Renesas Electronics Corporation
+ * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/ehci-rmobile.h>
+#include "ehci.h"
+
+#if defined(CONFIG_R8A7740)
+static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
+ 0xC6700000
+};
+#elif defined(CONFIG_R8A7790)
+static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
+ 0xEE080000, /* USB0 (EHCI) */
+ 0xEE0A0000, /* USB1 */
+ 0xEE0C0000, /* USB2 */
+ 0xEE000000 /* USB3 (USB3.0 Host)*/
+};
+#elif defined(CONFIG_R8A7791)
+static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
+ 0xEE080000, /* USB0 (EHCI) */
+ 0xEE0C0000, /* USB1 */
+ 0xEE000000 /* USB3 (USB3.0 Host)*/
+};
+#else
+#error rmobile EHCI USB driver not supported on this platform
+#endif
+
+int ehci_hcd_stop(int index)
+{
+ int i;
+ u32 base;
+ struct ahbcom_pci_bridge *ahbcom_pci;
+
+ base = usb_base_address[index];
+ ahbcom_pci = (struct ahbcom_pci_bridge *)(base + AHBPCI_OFFSET);
+ writel(0, &ahbcom_pci->ahb_bus_ctr);
+
+ /* reset ehci */
+ setbits_le32(base + EHCI_USBCMD, CMD_RESET);
+ for (i = 100; i > 0; i--) {
+ if (!(readl(base + EHCI_USBCMD) & CMD_RESET))
+ break;
+ udelay(100);
+ }
+
+ if (!i)
+ printf("error : ehci(%d) reset failed.\n", index);
+
+ if (index == (CONFIG_USB_MAX_CONTROLLER_COUNT - 1))
+ setbits_le32(SMSTPCR7, SMSTPCR703);
+
+ return 0;
+}
+
+int ehci_hcd_init(int index, enum usb_init_type init,
+ struct ehci_hccr **hccr, struct ehci_hcor **hcor)
+{
+ u32 base;
+ u32 phys_base;
+ struct rmobile_ehci_reg *rehci;
+ struct ahbcom_pci_bridge *ahbcom_pci;
+ struct ahbconf_pci_bridge *ahbconf_pci;
+ struct ahb_pciconf *ahb_pciconf_ohci;
+ struct ahb_pciconf *ahb_pciconf_ehci;
+ uint32_t cap_base;
+
+ base = usb_base_address[index];
+ phys_base = base;
+ if (index == 0)
+ clrbits_le32(SMSTPCR7, SMSTPCR703);
+
+ rehci = (struct rmobile_ehci_reg *)(base + EHCI_OFFSET);
+ ahbcom_pci = (struct ahbcom_pci_bridge *)(base + AHBPCI_OFFSET);
+ ahbconf_pci =
+ (struct ahbconf_pci_bridge *)(base + PCI_CONF_AHBPCI_OFFSET);
+ ahb_pciconf_ohci = (struct ahb_pciconf *)(base + PCI_CONF_OHCI_OFFSET);
+ ahb_pciconf_ehci = (struct ahb_pciconf *)(base + PCI_CONF_EHCI_OFFSET);
+
+ /* Clock & Reset & Direct Power Down */
+ clrsetbits_le32(&ahbcom_pci->usbctr,
+ (DIRPD | PCICLK_MASK | USBH_RST), USBCTR_WIN_SIZE_1GB);
+ clrbits_le32(&ahbcom_pci->usbctr, PLL_RST);
+
+ /* AHB-PCI Bridge Communication Registers */
+ writel(AHB_BUS_CTR_INIT, &ahbcom_pci->ahb_bus_ctr);
+ writel((CONFIG_SYS_SDRAM_BASE & 0xf0000000) | PCIAHB_WIN_PREFETCH,
+ &ahbcom_pci->pciahb_win1_ctr);
+ writel(0xf0000000 | PCIAHB_WIN_PREFETCH,
+ &ahbcom_pci->pciahb_win2_ctr);
+ writel(phys_base | PCIWIN2_PCICMD, &ahbcom_pci->ahbpci_win2_ctr);
+
+ setbits_le32(&ahbcom_pci->pci_arbiter_ctr,
+ PCIBP_MODE | PCIREQ1 | PCIREQ0);
+
+ /* PCI Configuration Registers for AHBPCI */
+ writel(PCIWIN1_PCICMD | AHB_CFG_AHBPCI,
+ &ahbcom_pci->ahbpci_win1_ctr);
+ writel(phys_base + AHBPCI_OFFSET, &ahbconf_pci->basead);
+ writel(CONFIG_SYS_SDRAM_BASE & 0xf0000000, &ahbconf_pci->win1_basead);
+ writel(0xf0000000, &ahbconf_pci->win2_basead);
+ writel(SERREN | PERREN | MASTEREN | MEMEN,
+ &ahbconf_pci->cmnd_sts);
+
+ /* PCI Configuration Registers for EHCI */
+ writel(PCIWIN1_PCICMD | AHB_CFG_HOST, &ahbcom_pci->ahbpci_win1_ctr);
+ writel(phys_base + OHCI_OFFSET, &ahb_pciconf_ohci->basead);
+ writel(phys_base + EHCI_OFFSET, &ahb_pciconf_ehci->basead);
+ writel(SERREN | PERREN | MASTEREN | MEMEN,
+ &ahb_pciconf_ohci->cmnd_sts);
+ writel(SERREN | PERREN | MASTEREN | MEMEN,
+ &ahb_pciconf_ehci->cmnd_sts);
+
+ /* Enable PCI interrupt */
+ setbits_le32(&ahbcom_pci->pci_int_enable,
+ USBH_PMEEN | USBH_INTBEN | USBH_INTAEN);
+
+ *hccr = (struct ehci_hccr *)((uint32_t)&rehci->hciversion);
+ cap_base = ehci_readl(&(*hccr)->cr_capbase);
+ *hcor = (struct ehci_hcor *)((uint32_t)*hccr + HC_LENGTH(cap_base));
+
+ return 0;
+}
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 0b42aa5b38..38db18e2c9 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -13,7 +13,6 @@
#include <asm/arch/clock.h>
#include <asm/arch-tegra/usb.h>
#include <asm/arch-tegra/clk_rst.h>
-#include <asm/arch/usb.h>
#include <usb.h>
#include <usb/ulpi.h>
#include <libfdt.h>
@@ -461,6 +460,9 @@ static int init_utmi_usb_controller(struct fdt_usb *config)
if (config->periph_id == PERIPH_ID_USBD)
clrbits_le32(&clkrst->crc_utmip_pll_cfg2,
UTMIP_FORCE_PD_SAMP_A_POWERDOWN);
+ if (config->periph_id == PERIPH_ID_USB2)
+ clrbits_le32(&clkrst->crc_utmip_pll_cfg2,
+ UTMIP_FORCE_PD_SAMP_B_POWERDOWN);
if (config->periph_id == PERIPH_ID_USB3)
clrbits_le32(&clkrst->crc_utmip_pll_cfg2,
UTMIP_FORCE_PD_SAMP_C_POWERDOWN);
@@ -483,9 +485,21 @@ static int init_utmi_usb_controller(struct fdt_usb *config)
clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
/* Select UTMI parallel interface */
- clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
+#if defined(CONFIG_TEGRA20)
+ if (config->periph_id == PERIPH_ID_USBD) {
+ clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
+ PTS_UTMI << PTS1_SHIFT);
+ clrbits_le32(&usbctlr->port_sc1, STS1);
+ } else {
+ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
+ PTS_UTMI << PTS_SHIFT);
+ clrbits_le32(&usbctlr->port_sc1, STS);
+ }
+#else
+ clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK,
PTS_UTMI << PTS_SHIFT);
- clrbits_le32(&usbctlr->port_sc1, STS);
+ clrbits_le32(&usbctlr->hostpc1_devlc, STS);
+#endif
/* Deassert power down state */
clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN |
@@ -543,7 +557,13 @@ static int init_ulpi_usb_controller(struct fdt_usb *config)
ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP);
/* Select ULPI parallel interface */
- clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_ULPI << PTS_SHIFT);
+#if defined(CONFIG_TEGRA20)
+ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
+ PTS_ULPI << PTS_SHIFT);
+#else
+ clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK,
+ PTS_ULPI << PTS_SHIFT);
+#endif
/* enable ULPI transceiver */
setbits_le32(&usbctlr->susp_ctrl, ULPI_PHY_ENB);
diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
index 1146d101de..b4946a3f1c 100644
--- a/drivers/usb/host/xhci-exynos5.c
+++ b/drivers/usb/host/xhci-exynos5.c
@@ -298,7 +298,8 @@ int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
#ifdef CONFIG_OF_CONTROL
/* setup the Vbus gpio here */
- if (!fdtdec_setup_gpio(&ctx->vbus_gpio))
+ if (fdt_gpio_isvalid(&ctx->vbus_gpio) &&
+ !fdtdec_setup_gpio(&ctx->vbus_gpio))
gpio_direction_output(ctx->vbus_gpio.gpio, 1);
#endif
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 05126803c3..0d7b89fcf6 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -204,7 +204,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
- /* TODO: implement me */
+ if (driver->disconnect)
+ driver->disconnect(&gadget->g);
+ if (driver->unbind)
+ driver->unbind(&gadget->g);
return 0;
}
#endif /* CONFIG_MUSB_GADGET */
diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
index c047e6e785..57cb0074e2 100644
--- a/drivers/video/tegra.c
+++ b/drivers/video/tegra.c
@@ -229,8 +229,8 @@ static int handle_stage(const void *blob)
break;
case STAGE_PWM:
/* Enable PWM at 15/16 high, 32768 Hz with divider 1 */
- pinmux_set_func(PINGRP_GPU, PMUX_FUNC_PWM);
- pinmux_tristate_disable(PINGRP_GPU);
+ pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_PWM);
+ pinmux_tristate_disable(PMUX_PINGRP_GPU);
pwm_enable(config.pwm_channel, 32768, 0xdf, 1);
break;
OpenPOWER on IntegriCloud