summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/root.c8
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_a38x.h5
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h7
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_init.c72
-rw-r--r--drivers/gpio/altera_pio.c5
-rw-r--r--drivers/misc/altera_sysid.c5
-rw-r--r--drivers/mmc/zynq_sdhci.c2
-rw-r--r--drivers/mtd/altera_qspi.c2
-rw-r--r--drivers/mtd/spi/sf-uclass.c23
-rw-r--r--drivers/mtd/spi/spi_spl_load.c17
-rw-r--r--drivers/net/altera_tse.c2
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/phy.c3
-rw-r--r--drivers/net/phy/ti.c200
-rw-r--r--drivers/net/zynq_gem.c143
-rw-r--r--drivers/serial/altera_jtag_uart.c5
-rw-r--r--drivers/serial/altera_uart.c5
-rw-r--r--drivers/spi/altera_spi.c5
-rw-r--r--drivers/spi/spi-uclass.c20
-rw-r--r--drivers/timer/altera_timer.c5
20 files changed, 400 insertions, 135 deletions
diff --git a/drivers/core/root.c b/drivers/core/root.c
index bdb394a9ae..e7b1f24968 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -59,6 +59,8 @@ void fix_drivers(void)
entry->unbind += gd->reloc_off;
if (entry->ofdata_to_platdata)
entry->ofdata_to_platdata += gd->reloc_off;
+ if (entry->child_post_bind)
+ entry->child_post_bind += gd->reloc_off;
if (entry->child_pre_probe)
entry->child_pre_probe += gd->reloc_off;
if (entry->child_post_remove)
@@ -81,10 +83,16 @@ void fix_uclass(void)
entry->post_bind += gd->reloc_off;
if (entry->pre_unbind)
entry->pre_unbind += gd->reloc_off;
+ if (entry->pre_probe)
+ entry->pre_probe += gd->reloc_off;
if (entry->post_probe)
entry->post_probe += gd->reloc_off;
if (entry->pre_remove)
entry->pre_remove += gd->reloc_off;
+ if (entry->child_post_bind)
+ entry->child_post_bind += gd->reloc_off;
+ if (entry->child_pre_probe)
+ entry->child_pre_probe += gd->reloc_off;
if (entry->init)
entry->init += gd->reloc_off;
if (entry->destroy)
diff --git a/drivers/ddr/marvell/a38x/ddr3_a38x.h b/drivers/ddr/marvell/a38x/ddr3_a38x.h
index 49621bc133..1ed517446f 100644
--- a/drivers/ddr/marvell/a38x/ddr3_a38x.h
+++ b/drivers/ddr/marvell/a38x/ddr3_a38x.h
@@ -12,11 +12,6 @@
#include "ddr3_hws_hw_training_def.h"
-/* Allow topolgy update from board TWSI device*/
-#if !defined(CONFIG_CUSTOMER_BOARD_SUPPORT)
-#define MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI
-#endif
-
#define ECC_SUPPORT
/* right now, we're not supporting this in mainline */
diff --git a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
index 7500a72403..06d0ab10aa 100644
--- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
+++ b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
@@ -23,8 +23,8 @@
#define CPU_CONFIGURATION_REG(id) (0x21800 + (id * 0x100))
#define CPU_MRVL_ID_OFFSET 0x10
-#define SAR1_CPU_CORE_MASK 0x00000018
-#define SAR1_CPU_CORE_OFFSET 3
+#define SAR1_CPU_CORE_MASK 0x38000000
+#define SAR1_CPU_CORE_OFFSET 27
#define NEW_FABRIC_TWSI_ADDR 0x4e
#ifdef DB_784MP_GP
@@ -461,7 +461,4 @@
#define CLK_CPU_2200 13
#define CLK_CPU_2400 14
-#define SAR1_CPU_CORE_MASK 0x00000018
-#define SAR1_CPU_CORE_OFFSET 3
-
#endif /* _DDR3_HWS_HW_TRAINING_DEF_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c
index d6ed8e03e9..556f877039 100644
--- a/drivers/ddr/marvell/a38x/ddr3_init.c
+++ b/drivers/ddr/marvell/a38x/ddr3_init.c
@@ -96,7 +96,6 @@ u8 generic_init_controller = 1;
static u32 ddr3_get_static_ddr_mode(void);
#endif
static int ddr3_hws_tune_training_params(u8 dev_num);
-static int ddr3_update_topology_map(struct hws_topology_map *topology_map);
/* device revision */
#define DEV_VERSION_ID_REG 0x1823c
@@ -383,14 +382,6 @@ int ddr3_init(void)
}
#endif
- /* Load topology for New Training IP */
- status = ddr3_load_topology_map();
- if (MV_OK != status) {
- printf("%s Training Sequence topology load - FAILED\n",
- ddr_type);
- return status;
- }
-
/* Tune training algo paramteres */
status = ddr3_hws_tune_training_params(0);
if (MV_OK != status)
@@ -539,27 +530,6 @@ u32 ddr3_get_cs_num_from_reg(void)
return cs_count;
}
-/*
- * Name: ddr3_load_topology_map
- * Desc:
- * Args:
- * Notes:
- * Returns:
- */
-int ddr3_load_topology_map(void)
-{
- struct hws_topology_map *tm = ddr3_get_topology_map();
-
-#if defined(MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI)
- /* Update topology data */
- if (MV_OK != ddr3_update_topology_map(tm)) {
- DEBUG_INIT_FULL_S("Failed update of DDR3 Topology map\n");
- }
-#endif
-
- return MV_OK;
-}
-
void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps)
{
u32 tmp, hclk = 200;
@@ -781,48 +751,6 @@ int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size)
return MV_OK;
}
-#if defined(MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI)
-/*
- * Name: ddr3_update_topology_map
- * Desc:
- * Args:
- * Notes: Update topology map by Sat_r values
- * Returns:
- */
-static int ddr3_update_topology_map(struct hws_topology_map *tm)
-{
- struct topology_update_info topology_update_info;
-
- topology_update_info.update_width = 0;
- topology_update_info.update_ecc = 0;
- topology_update_info.update_ecc_pup3_mode = 0;
- sys_env_get_topology_update_info(&topology_update_info);
- if (topology_update_info.update_width) {
- tm->bus_act_mask &=
- ~(TOPOLOGY_UPDATE_WIDTH_32BIT_MASK);
- if (topology_update_info.width == TOPOLOGY_UPDATE_WIDTH_16BIT)
- tm->bus_act_mask =
- TOPOLOGY_UPDATE_WIDTH_16BIT_MASK;
- else
- tm->bus_act_mask =
- TOPOLOGY_UPDATE_WIDTH_32BIT_MASK;
- }
-
- if (topology_update_info.update_ecc) {
- if (topology_update_info.ecc == TOPOLOGY_UPDATE_ECC_OFF) {
- tm->bus_act_mask &=
- ~(1 << topology_update_info.ecc_pup_mode_offset);
- } else {
- tm->bus_act_mask |=
- topology_update_info.
- ecc << topology_update_info.ecc_pup_mode_offset;
- }
- }
-
- return MV_OK;
-}
-#endif
-
/*
* Name: ddr3_hws_tune_training_params
* Desc:
diff --git a/drivers/gpio/altera_pio.c b/drivers/gpio/altera_pio.c
index 7ceb80e951..6f42bf8a22 100644
--- a/drivers/gpio/altera_pio.c
+++ b/drivers/gpio/altera_pio.c
@@ -89,8 +89,9 @@ static int altera_pio_ofdata_to_platdata(struct udevice *dev)
{
struct altera_pio_platdata *plat = dev_get_platdata(dev);
- plat->regs = ioremap(dev_get_addr(dev),
- sizeof(struct altera_pio_regs));
+ plat->regs = map_physmem(dev_get_addr(dev),
+ sizeof(struct altera_pio_regs),
+ MAP_NOCACHE);
plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"altr,gpio-bank-width", 32);
plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c
index 737520f247..2d0fa2a7dd 100644
--- a/drivers/misc/altera_sysid.c
+++ b/drivers/misc/altera_sysid.c
@@ -76,8 +76,9 @@ static int altera_sysid_ofdata_to_platdata(struct udevice *dev)
{
struct altera_sysid_platdata *plat = dev_get_platdata(dev);
- plat->regs = ioremap(dev_get_addr(dev),
- sizeof(struct altera_sysid_regs));
+ plat->regs = map_physmem(dev_get_addr(dev),
+ sizeof(struct altera_sysid_regs),
+ MAP_NOCACHE);
return 0;
}
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index c69f5d4e2d..e169b77493 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -29,7 +29,7 @@ int zynq_sdhci_init(phys_addr_t regbase)
SDHCI_QUIRK_BROKEN_R1B;
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
- add_sdhci(host, 52000000, 52000000 >> 9);
+ add_sdhci(host, CONFIG_ZYNQ_SDHCI_MAX_FREQ, 52000000 >> 9);
return 0;
}
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c
index 1826dc8272..50c6e0e587 100644
--- a/drivers/mtd/altera_qspi.c
+++ b/drivers/mtd/altera_qspi.c
@@ -243,7 +243,7 @@ static int altera_qspi_ofdata_to_platdata(struct udevice *dev)
addr = fdt_translate_address((void *)blob,
node, cell + idx);
size = fdt_addr_to_cpu(cell[idx + addrc]);
- base = ioremap(addr, size);
+ base = map_physmem(addr, size, MAP_NOCACHE);
len = strlen(list);
if (strcmp(list, "avl_csr") == 0) {
pdata->regs = base;
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 350e21aa7d..72e0f6b3fb 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -11,6 +11,8 @@
#include <dm/device-internal.h>
#include "sf_internal.h"
+DECLARE_GLOBAL_DATA_PTR;
+
int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf)
{
return sf_get_ops(dev)->read(dev, offset, len, buf);
@@ -72,8 +74,29 @@ int spi_flash_remove(struct udevice *dev)
return device_remove(dev);
}
+static int spi_flash_post_bind(struct udevice *dev)
+{
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+ struct dm_spi_flash_ops *ops = sf_get_ops(dev);
+ static int reloc_done;
+
+ if (!reloc_done) {
+ if (ops->read)
+ ops->read += gd->reloc_off;
+ if (ops->write)
+ ops->write += gd->reloc_off;
+ if (ops->erase)
+ ops->erase += gd->reloc_off;
+
+ reloc_done++;
+ }
+#endif
+ return 0;
+}
+
UCLASS_DRIVER(spi_flash) = {
.id = UCLASS_SPI_FLASH,
.name = "spi_flash",
+ .post_bind = spi_flash_post_bind,
.per_device_auto_alloc_size = sizeof(struct spi_flash),
};
diff --git a/drivers/mtd/spi/spi_spl_load.c b/drivers/mtd/spi/spi_spl_load.c
index 2e0c871219..ca56fe9015 100644
--- a/drivers/mtd/spi/spi_spl_load.c
+++ b/drivers/mtd/spi/spi_spl_load.c
@@ -12,6 +12,7 @@
#include <common.h>
#include <spi.h>
#include <spi_flash.h>
+#include <errno.h>
#include <spl.h>
#ifdef CONFIG_SPL_OS_BOOT
@@ -48,8 +49,9 @@ static int spi_load_image_os(struct spi_flash *flash,
* configured and available since this code loads the main U-Boot image
* from SPI into SDRAM and starts it from there.
*/
-void spl_spi_load_image(void)
+int spl_spi_load_image(void)
{
+ int err = 0;
struct spi_flash *flash;
struct image_header *header;
@@ -63,7 +65,7 @@ void spl_spi_load_image(void)
CONFIG_SF_DEFAULT_MODE);
if (!flash) {
puts("SPI probe failed.\n");
- hang();
+ return -ENODEV;
}
/* use CONFIG_SYS_TEXT_BASE as temporary storage area */
@@ -74,10 +76,15 @@ void spl_spi_load_image(void)
#endif
{
/* Load u-boot, mkimage header is 64 bytes. */
- spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40,
- (void *)header);
+ err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40,
+ (void *)header);
+ if (err)
+ return err;
+
spl_parse_image_header(header);
- spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
+ err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
spl_image.size, (void *)spl_image.load_addr);
}
+
+ return err;
}
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index 5692fe9d4a..3eaa270677 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -608,7 +608,7 @@ static int altera_tse_probe(struct udevice *dev)
addr = fdt_translate_address((void *)blob,
node, cell + idx);
size = fdt_addr_to_cpu(cell[idx + addrc]);
- base = ioremap(addr, size);
+ base = map_physmem(addr, size, MAP_NOCACHE);
len = strlen(list);
if (strcmp(list, "control_port") == 0)
priv->mac_dev = base;
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index d096db87a2..9e4d4927e6 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -24,4 +24,5 @@ obj-$(CONFIG_PHY_NATSEMI) += natsemi.o
obj-$(CONFIG_PHY_REALTEK) += realtek.o
obj-$(CONFIG_PHY_SMSC) += smsc.o
obj-$(CONFIG_PHY_TERANETICS) += teranetics.o
+obj-$(CONFIG_PHY_TI) += ti.o
obj-$(CONFIG_PHY_VITESSE) += vitesse.o
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index d7364ffc34..5633ec2402 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -484,6 +484,9 @@ int phy_init(void)
#ifdef CONFIG_PHY_TERANETICS
phy_teranetics_init();
#endif
+#ifdef CONFIG_PHY_TI
+ phy_ti_init();
+#endif
#ifdef CONFIG_PHY_VITESSE
phy_vitesse_init();
#endif
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
new file mode 100644
index 0000000000..541a57f980
--- /dev/null
+++ b/drivers/net/phy/ti.c
@@ -0,0 +1,200 @@
+/*
+ * TI PHY drivers
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+#include <common.h>
+#include <phy.h>
+
+/* TI DP83867 */
+#define DP83867_DEVADDR 0x1f
+
+#define MII_DP83867_PHYCTRL 0x10
+#define MII_DP83867_MICR 0x12
+#define DP83867_CTRL 0x1f
+
+/* Extended Registers */
+#define DP83867_RGMIICTL 0x0032
+#define DP83867_RGMIIDCTL 0x0086
+
+#define DP83867_SW_RESET BIT(15)
+#define DP83867_SW_RESTART BIT(14)
+
+/* MICR Interrupt bits */
+#define MII_DP83867_MICR_AN_ERR_INT_EN BIT(15)
+#define MII_DP83867_MICR_SPEED_CHNG_INT_EN BIT(14)
+#define MII_DP83867_MICR_DUP_MODE_CHNG_INT_EN BIT(13)
+#define MII_DP83867_MICR_PAGE_RXD_INT_EN BIT(12)
+#define MII_DP83867_MICR_AUTONEG_COMP_INT_EN BIT(11)
+#define MII_DP83867_MICR_LINK_STS_CHNG_INT_EN BIT(10)
+#define MII_DP83867_MICR_FALSE_CARRIER_INT_EN BIT(8)
+#define MII_DP83867_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4)
+#define MII_DP83867_MICR_WOL_INT_EN BIT(3)
+#define MII_DP83867_MICR_XGMII_ERR_INT_EN BIT(2)
+#define MII_DP83867_MICR_POL_CHNG_INT_EN BIT(1)
+#define MII_DP83867_MICR_JABBER_INT_EN BIT(0)
+
+/* RGMIICTL bits */
+#define DP83867_RGMII_TX_CLK_DELAY_EN BIT(1)
+#define DP83867_RGMII_RX_CLK_DELAY_EN BIT(0)
+
+/* PHY CTRL bits */
+#define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14
+
+/* RGMIIDCTL bits */
+#define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4
+
+#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
+#define MII_MMD_DATA 0x0e /* MMD Access Data Register */
+
+/* MMD Access Control register fields */
+#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
+#define MII_MMD_CTRL_ADDR 0x0000 /* Address */
+#define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */
+#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
+#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
+
+/**
+ * phy_read_mmd_indirect - reads data from the MMD registers
+ * @phydev: The PHY device bus
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ * @addr: PHY address on the MII bus
+ *
+ * Description: it reads data from the MMD registers (clause 22 to access to
+ * clause 45) of the specified phy address.
+ * To read these registers we have:
+ * 1) Write reg 13 // DEVAD
+ * 2) Write reg 14 // MMD Address
+ * 3) Write reg 13 // MMD Data Command for MMD DEVAD
+ * 3) Read reg 14 // Read MMD data
+ */
+int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
+ int devad, int addr)
+{
+ int value = -1;
+
+ /* Write the desired MMD Devad */
+ phy_write(phydev, addr, MII_MMD_CTRL, devad);
+
+ /* Write the desired MMD register address */
+ phy_write(phydev, addr, MII_MMD_DATA, prtad);
+
+ /* Select the Function : DATA with no post increment */
+ phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
+
+ /* Read the content of the MMD's selected register */
+ value = phy_read(phydev, addr, MII_MMD_DATA);
+ return value;
+}
+
+/**
+ * phy_write_mmd_indirect - writes data to the MMD registers
+ * @phydev: The PHY device
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ * @addr: PHY address on the MII bus
+ * @data: data to write in the MMD register
+ *
+ * Description: Write data from the MMD registers of the specified
+ * phy address.
+ * To write these registers we have:
+ * 1) Write reg 13 // DEVAD
+ * 2) Write reg 14 // MMD Address
+ * 3) Write reg 13 // MMD Data Command for MMD DEVAD
+ * 3) Write reg 14 // Write MMD data
+ */
+void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
+ int devad, int addr, u32 data)
+{
+ /* Write the desired MMD Devad */
+ phy_write(phydev, addr, MII_MMD_CTRL, devad);
+
+ /* Write the desired MMD register address */
+ phy_write(phydev, addr, MII_MMD_DATA, prtad);
+
+ /* Select the Function : DATA with no post increment */
+ phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
+
+ /* Write the data into MMD's selected register */
+ phy_write(phydev, addr, MII_MMD_DATA, data);
+}
+
+/**
+ * phy_interface_is_rgmii - Convenience function for testing if a PHY interface
+ * is RGMII (all variants)
+ * @phydev: the phy_device struct
+ */
+static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
+{
+ return phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
+ phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID;
+}
+
+/* User setting - can be taken from DTS */
+#define RX_ID_DELAY 8
+#define TX_ID_DELAY 0xa
+#define FIFO_DEPTH 1
+
+static int dp83867_config(struct phy_device *phydev)
+{
+ unsigned int val, delay;
+ int ret;
+
+ /* Restart the PHY. */
+ val = phy_read(phydev, MDIO_DEVAD_NONE, DP83867_CTRL);
+ phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL,
+ val | DP83867_SW_RESTART);
+
+ if (phy_interface_is_rgmii(phydev)) {
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
+ (FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
+ if (ret)
+ return ret;
+ }
+
+ if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) &&
+ (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) {
+ val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL,
+ DP83867_DEVADDR, phydev->addr);
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+ val |= (DP83867_RGMII_TX_CLK_DELAY_EN |
+ DP83867_RGMII_RX_CLK_DELAY_EN);
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ val |= DP83867_RGMII_TX_CLK_DELAY_EN;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ val |= DP83867_RGMII_RX_CLK_DELAY_EN;
+
+ phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
+ DP83867_DEVADDR, phydev->addr, val);
+
+ delay = (RX_ID_DELAY |
+ (TX_ID_DELAY << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
+
+ phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
+ DP83867_DEVADDR, phydev->addr, delay);
+ }
+
+ genphy_config_aneg(phydev);
+ return 0;
+}
+
+static struct phy_driver DP83867_driver = {
+ .name = "TI DP83867",
+ .uid = 0x2000a231,
+ .mask = 0xfffffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &dp83867_config,
+ .startup = &genphy_startup,
+ .shutdown = &genphy_shutdown,
+};
+
+int phy_ti_init(void)
+{
+ phy_register(&DP83867_driver);
+ return 0;
+}
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 5637a0d083..858093f0d7 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -23,6 +23,7 @@
#include <asm/system.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
+#include <asm-generic/errno.h>
#if !defined(CONFIG_PHYLIB)
# error XILINX_GEM_ETHERNET requires PHYLIB
@@ -46,6 +47,7 @@
/* Wrap bit, last descriptor */
#define ZYNQ_GEM_TXBUF_WRAP_MASK 0x40000000
#define ZYNQ_GEM_TXBUF_LAST_MASK 0x00008000 /* Last buffer */
+#define ZYNQ_GEM_TXBUF_USED_MASK 0x80000000 /* Used by Hw */
#define ZYNQ_GEM_NWCTRL_TXEN_MASK 0x00000008 /* Enable transmit */
#define ZYNQ_GEM_NWCTRL_RXEN_MASK 0x00000004 /* Enable receive */
@@ -56,8 +58,7 @@
#define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400 /* 1Gbps operation */
#define ZYNQ_GEM_NWCFG_FDEN 0x000000002 /* Full Duplex mode */
#define ZYNQ_GEM_NWCFG_FSREM 0x000020000 /* FCS removal */
-#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */
-#define ZYNQ_GEM_NWCFG_MDCCLKDIV2 0x0000c0000 /* Div pclk by 48, 120MHz */
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x0000c0000 /* Div pclk by 48, max 120MHz */
#ifdef CONFIG_ARM64
# define ZYNQ_GEM_DBUS_WIDTH (1 << 21) /* 64 bit bus */
@@ -85,6 +86,8 @@
ZYNQ_GEM_DMACR_TXSIZE | \
ZYNQ_GEM_DMACR_RXBUF)
+#define ZYNQ_GEM_TSR_DONE 0x00000020 /* Tx done mask */
+
/* Use MII register 1 (MII status register) to detect PHY */
#define PHY_DETECT_REG 1
@@ -108,28 +111,33 @@
/* Device registers */
struct zynq_gem_regs {
- u32 nwctrl; /* Network Control reg */
- u32 nwcfg; /* Network Config reg */
- u32 nwsr; /* Network Status reg */
+ u32 nwctrl; /* 0x0 - Network Control reg */
+ u32 nwcfg; /* 0x4 - Network Config reg */
+ u32 nwsr; /* 0x8 - Network Status reg */
u32 reserved1;
- u32 dmacr; /* DMA Control reg */
- u32 txsr; /* TX Status reg */
- u32 rxqbase; /* RX Q Base address reg */
- u32 txqbase; /* TX Q Base address reg */
- u32 rxsr; /* RX Status reg */
+ u32 dmacr; /* 0x10 - DMA Control reg */
+ u32 txsr; /* 0x14 - TX Status reg */
+ u32 rxqbase; /* 0x18 - RX Q Base address reg */
+ u32 txqbase; /* 0x1c - TX Q Base address reg */
+ u32 rxsr; /* 0x20 - RX Status reg */
u32 reserved2[2];
- u32 idr; /* Interrupt Disable reg */
+ u32 idr; /* 0x2c - Interrupt Disable reg */
u32 reserved3;
- u32 phymntnc; /* Phy Maintaince reg */
+ u32 phymntnc; /* 0x34 - Phy Maintaince reg */
u32 reserved4[18];
- u32 hashl; /* Hash Low address reg */
- u32 hashh; /* Hash High address reg */
+ u32 hashl; /* 0x80 - Hash Low address reg */
+ u32 hashh; /* 0x84 - Hash High address reg */
#define LADDR_LOW 0
#define LADDR_HIGH 1
- u32 laddr[4][LADDR_HIGH + 1]; /* Specific1 addr low/high reg */
- u32 match[4]; /* Type ID1 Match reg */
+ u32 laddr[4][LADDR_HIGH + 1]; /* 0x8c - Specific1 addr low/high reg */
+ u32 match[4]; /* 0xa8 - Type ID1 Match reg */
u32 reserved6[18];
- u32 stat[44]; /* Octects transmitted Low reg - stat start */
+#define STAT_SIZE 44
+ u32 stat[STAT_SIZE]; /* 0x100 - Octects transmitted Low reg */
+ u32 reserved7[164];
+ u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
+ u32 reserved8[15];
+ u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */
};
/* BD descriptors */
@@ -144,7 +152,10 @@ struct emac_bd {
*/
#define BD_SPACE 0x100000
/* BD separation space */
-#define BD_SEPRN_SPACE 64
+#define BD_SEPRN_SPACE (RX_BUF * sizeof(struct emac_bd))
+
+/* Setup the first free TX descriptor */
+#define TX_FREE_DESC 2
/* Initialized, rxbd_current, rx_first_buf must be 0 after init */
struct zynq_gem_priv {
@@ -156,6 +167,7 @@ struct zynq_gem_priv {
int phyaddr;
u32 emio;
int init;
+ phy_interface_t interface;
struct phy_device *phydev;
struct mii_dev *bus;
};
@@ -208,12 +220,23 @@ static u32 phy_setup_op(struct eth_device *dev, u32 phy_addr, u32 regnum,
static u32 phyread(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 *val)
{
- return phy_setup_op(dev, phy_addr, regnum,
+ u32 ret;
+
+ ret = phy_setup_op(dev, phy_addr, regnum,
ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val);
+
+ if (!ret)
+ debug("%s: phy_addr %d, regnum 0x%x, val 0x%x\n", __func__,
+ phy_addr, regnum, *val);
+
+ return ret;
}
static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data)
{
+ debug("%s: phy_addr %d, regnum 0x%x, data 0x%x\n", __func__, phy_addr,
+ regnum, data);
+
return phy_setup_op(dev, phy_addr, regnum,
ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data);
}
@@ -289,10 +312,10 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
u32 i;
unsigned long clk_rate = 0;
struct phy_device *phydev;
- const u32 stat_size = (sizeof(struct zynq_gem_regs) -
- offsetof(struct zynq_gem_regs, stat)) / 4;
struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
struct zynq_gem_priv *priv = dev->priv;
+ struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC];
+ struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2];
const u32 supported = SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
@@ -318,7 +341,7 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
writel(0x0, &regs->hashh);
/* Clear all counters */
- for (i = 0; i <= stat_size; i++)
+ for (i = 0; i < STAT_SIZE; i++)
readl(&regs->stat[i]);
/* Setup RxBD space */
@@ -341,6 +364,23 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
/* Setup for Network Control register, MDIO, Rx and Tx enable */
setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);
+ /* Disable the second priority queue */
+ dummy_tx_bd->addr = 0;
+ dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
+ ZYNQ_GEM_TXBUF_LAST_MASK|
+ ZYNQ_GEM_TXBUF_USED_MASK;
+
+ dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
+ ZYNQ_GEM_RXBUF_NEW_MASK;
+ dummy_rx_bd->status = 0;
+ flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd +
+ sizeof(dummy_tx_bd));
+ flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd +
+ sizeof(dummy_rx_bd));
+
+ writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
+ writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);
+
priv->init++;
}
@@ -348,7 +388,7 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
/* interface - look at tsec */
phydev = phy_connect(priv->bus, priv->phyaddr, dev,
- PHY_INTERFACE_MODE_MII);
+ priv->interface);
phydev->supported = supported | ADVERTISED_Pause |
ADVERTISED_Asym_Pause;
@@ -369,8 +409,8 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
clk_rate = ZYNQ_GEM_FREQUENCY_1000;
break;
case SPEED_100:
- clrsetbits_le32(&regs->nwcfg, ZYNQ_GEM_NWCFG_SPEED1000,
- ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100);
+ writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100,
+ &regs->nwcfg);
clk_rate = ZYNQ_GEM_FREQUENCY_100;
break;
case SPEED_10:
@@ -389,22 +429,54 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
return 0;
}
+static int wait_for_bit(const char *func, u32 *reg, const u32 mask,
+ bool set, unsigned int timeout)
+{
+ u32 val;
+ unsigned long start = get_timer(0);
+
+ while (1) {
+ val = readl(reg);
+
+ if (!set)
+ val = ~val;
+
+ if ((val & mask) == mask)
+ return 0;
+
+ if (get_timer(start) > timeout)
+ break;
+
+ udelay(1);
+ }
+
+ debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
+ func, reg, mask, set);
+
+ return -ETIMEDOUT;
+}
+
static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
{
u32 addr, size;
struct zynq_gem_priv *priv = dev->priv;
struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
-
- /* setup BD */
- writel((ulong)priv->tx_bd, &regs->txqbase);
+ struct emac_bd *current_bd = &priv->tx_bd[1];
/* Setup Tx BD */
memset(priv->tx_bd, 0, sizeof(struct emac_bd));
priv->tx_bd->addr = (ulong)ptr;
priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
- ZYNQ_GEM_TXBUF_LAST_MASK |
- ZYNQ_GEM_TXBUF_WRAP_MASK;
+ ZYNQ_GEM_TXBUF_LAST_MASK;
+ /* Dummy descriptor to mark it as the last in descriptor chain */
+ current_bd->addr = 0x0;
+ current_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
+ ZYNQ_GEM_TXBUF_LAST_MASK|
+ ZYNQ_GEM_TXBUF_USED_MASK;
+
+ /* setup BD */
+ writel((ulong)priv->tx_bd, &regs->txqbase);
addr = (ulong) ptr;
addr &= ~(ARCH_DMA_MINALIGN - 1);
@@ -421,12 +493,11 @@ static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK);
/* Read TX BD status */
- if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_UNDERRUN)
- printf("TX underrun\n");
if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED)
printf("TX buffers exhausted in mid frame\n");
- return 0;
+ return wait_for_bit(__func__, &regs->txsr, ZYNQ_GEM_TSR_DONE,
+ true, 20000);
}
/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */
@@ -535,6 +606,12 @@ int zynq_gem_initialize(bd_t *bis, phys_addr_t base_addr,
priv->phyaddr = phy_addr;
priv->emio = emio;
+#ifndef CONFIG_ZYNQ_GEM_INTERFACE
+ priv->interface = PHY_INTERFACE_MODE_MII;
+#else
+ priv->interface = CONFIG_ZYNQ_GEM_INTERFACE;
+#endif
+
sprintf(dev->name, "Gem.%lx", base_addr);
dev->iobase = base_addr;
diff --git a/drivers/serial/altera_jtag_uart.c b/drivers/serial/altera_jtag_uart.c
index c77bea3a1e..cb11b31326 100644
--- a/drivers/serial/altera_jtag_uart.c
+++ b/drivers/serial/altera_jtag_uart.c
@@ -97,8 +97,9 @@ static int altera_jtaguart_ofdata_to_platdata(struct udevice *dev)
{
struct altera_jtaguart_platdata *plat = dev_get_platdata(dev);
- plat->regs = ioremap(dev_get_addr(dev),
- sizeof(struct altera_jtaguart_regs));
+ plat->regs = map_physmem(dev_get_addr(dev),
+ sizeof(struct altera_jtaguart_regs),
+ MAP_NOCACHE);
return 0;
}
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c
index 5d76c3359b..eff9c592d6 100644
--- a/drivers/serial/altera_uart.c
+++ b/drivers/serial/altera_uart.c
@@ -89,8 +89,9 @@ static int altera_uart_ofdata_to_platdata(struct udevice *dev)
{
struct altera_uart_platdata *plat = dev_get_platdata(dev);
- plat->regs = ioremap(dev_get_addr(dev),
- sizeof(struct altera_uart_regs));
+ plat->regs = map_physmem(dev_get_addr(dev),
+ sizeof(struct altera_uart_regs),
+ MAP_NOCACHE);
plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"clock-frequency", 0);
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 3e09592ac6..eb1ba27acc 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -174,8 +174,9 @@ static int altera_spi_ofdata_to_platdata(struct udevice *bus)
{
struct altera_spi_platdata *plat = dev_get_platdata(bus);
- plat->regs = ioremap(dev_get_addr(bus),
- sizeof(struct altera_spi_regs));
+ plat->regs = map_physmem(dev_get_addr(bus),
+ sizeof(struct altera_spi_regs),
+ MAP_NOCACHE);
return 0;
}
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 58388efbc3..3c7d64ae63 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -118,6 +118,26 @@ static int spi_post_probe(struct udevice *bus)
spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
"spi-max-frequency", 0);
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+ struct dm_spi_ops *ops = spi_get_ops(bus);
+
+
+ if (ops->claim_bus)
+ ops->claim_bus += gd->reloc_off;
+ if (ops->release_bus)
+ ops->release_bus += gd->reloc_off;
+ if (ops->set_wordlen)
+ ops->set_wordlen += gd->reloc_off;
+ if (ops->xfer)
+ ops->xfer += gd->reloc_off;
+ if (ops->set_speed)
+ ops->set_speed += gd->reloc_off;
+ if (ops->set_mode)
+ ops->set_mode += gd->reloc_off;
+ if (ops->cs_info)
+ ops->cs_info += gd->reloc_off;
+#endif
+
return 0;
}
diff --git a/drivers/timer/altera_timer.c b/drivers/timer/altera_timer.c
index 46a598ae9f..971ed38b6b 100644
--- a/drivers/timer/altera_timer.c
+++ b/drivers/timer/altera_timer.c
@@ -75,8 +75,9 @@ static int altera_timer_ofdata_to_platdata(struct udevice *dev)
{
struct altera_timer_platdata *plat = dev_get_platdata(dev);
- plat->regs = ioremap(dev_get_addr(dev),
- sizeof(struct altera_timer_regs));
+ plat->regs = map_physmem(dev_get_addr(dev),
+ sizeof(struct altera_timer_regs),
+ MAP_NOCACHE);
plat->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"clock-frequency", 0);
OpenPOWER on IntegriCloud