summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-03-24 07:21:57 -0400
committerTom Rini <trini@konsulko.com>2017-03-24 07:21:57 -0400
commitc1daa4077365747d4f85ed8c93ba4d318d96a4af (patch)
tree4ac54134dd1970f7a98bcc3b9e225ea54d448f86 /drivers
parentd0ffda8ed208ff2957cd09ccc37e2d6dff81523e (diff)
parent60083261a1b33b492ddb5335c125f1223087068b (diff)
Merge git://www.denx.de/git/u-boot-marvell
This mainly adds support for some new boards, like the ARMv8 community boards MACCHIATOBin and ESPRESSBin
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/mvneta.c125
-rw-r--r--drivers/pci/pcie_dw_mvebu.c20
-rw-r--r--drivers/usb/host/Kconfig1
-rw-r--r--drivers/usb/host/xhci-mvebu.c13
4 files changed, 130 insertions, 29 deletions
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index 674075f037..8881cc77fe 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -191,11 +191,16 @@ DECLARE_GLOBAL_DATA_PTR;
#define MVNETA_GMAC_AUTONEG_CONFIG 0x2c0c
#define MVNETA_GMAC_FORCE_LINK_DOWN BIT(0)
#define MVNETA_GMAC_FORCE_LINK_PASS BIT(1)
+#define MVNETA_GMAC_FORCE_LINK_UP (BIT(0) | BIT(1))
+#define MVNETA_GMAC_IB_BYPASS_AN_EN BIT(3)
#define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5)
#define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6)
#define MVNETA_GMAC_AN_SPEED_EN BIT(7)
+#define MVNETA_GMAC_SET_FC_EN BIT(8)
+#define MVNETA_GMAC_ADVERT_FC_EN BIT(9)
#define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12)
#define MVNETA_GMAC_AN_DUPLEX_EN BIT(13)
+#define MVNETA_GMAC_SAMPLE_TX_CFG_EN BIT(15)
#define MVNETA_MIB_COUNTERS_BASE 0x3080
#define MVNETA_MIB_LATE_COLLISION 0x7c
#define MVNETA_DA_FILT_SPEC_MCAST 0x3400
@@ -404,6 +409,15 @@ static struct buffer_location buffer_loc;
*/
#define BD_SPACE (1 << 20)
+/*
+ * Dummy implementation that can be overwritten by a board
+ * specific function
+ */
+__weak int board_network_enable(struct mii_dev *bus)
+{
+ return 0;
+}
+
/* Utility/helper methods */
/* Write helper method */
@@ -557,6 +571,13 @@ static void mvneta_rxq_buf_size_set(struct mvneta_port *pp,
mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), val);
}
+static int mvneta_port_is_fixed_link(struct mvneta_port *pp)
+{
+ /* phy_addr is set to invalid value for fixed link */
+ return pp->phyaddr > PHY_MAX_ADDR;
+}
+
+
/* Start the Ethernet port RX and TX activity */
static void mvneta_port_up(struct mvneta_port *pp)
{
@@ -807,10 +828,12 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
/* Assign port SDMA configuration */
mvreg_write(pp, MVNETA_SDMA_CONFIG, val);
- /* Enable PHY polling in hardware for U-Boot */
- val = mvreg_read(pp, MVNETA_UNIT_CONTROL);
- val |= MVNETA_PHY_POLLING_ENABLE;
- mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
+ /* Enable PHY polling in hardware if not in fixed-link mode */
+ if (!mvneta_port_is_fixed_link(pp)) {
+ val = mvreg_read(pp, MVNETA_UNIT_CONTROL);
+ val |= MVNETA_PHY_POLLING_ENABLE;
+ mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
+ }
mvneta_set_ucast_table(pp, -1);
mvneta_set_special_mcast_table(pp, -1);
@@ -1128,6 +1151,11 @@ static void mvneta_adjust_link(struct udevice *dev)
struct phy_device *phydev = pp->phydev;
int status_change = 0;
+ if (mvneta_port_is_fixed_link(pp)) {
+ debug("Using fixed link, skip link adjust\n");
+ return;
+ }
+
if (phydev->link) {
if ((pp->speed != phydev->speed) ||
(pp->duplex != phydev->duplex)) {
@@ -1498,28 +1526,54 @@ static int mvneta_start(struct udevice *dev)
mvneta_port_power_up(pp, pp->phy_interface);
if (!pp->init || pp->link == 0) {
- /* Set phy address of the port */
- mvreg_write(pp, MVNETA_PHY_ADDR, pp->phyaddr);
- phydev = phy_connect(pp->bus, pp->phyaddr, dev,
- pp->phy_interface);
-
- pp->phydev = phydev;
- phy_config(phydev);
- phy_startup(phydev);
- if (!phydev->link) {
- printf("%s: No link.\n", phydev->dev->name);
- return -1;
- }
+ if (mvneta_port_is_fixed_link(pp)) {
+ u32 val;
- /* Full init on first call */
- mvneta_init(dev);
- pp->init = 1;
- } else {
- /* Upon all following calls, this is enough */
- mvneta_port_up(pp);
- mvneta_port_enable(pp);
+ pp->init = 1;
+ pp->link = 1;
+ mvneta_init(dev);
+
+ val = MVNETA_GMAC_FORCE_LINK_UP |
+ MVNETA_GMAC_IB_BYPASS_AN_EN |
+ MVNETA_GMAC_SET_FC_EN |
+ MVNETA_GMAC_ADVERT_FC_EN |
+ MVNETA_GMAC_SAMPLE_TX_CFG_EN;
+
+ if (pp->duplex)
+ val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
+
+ if (pp->speed == SPEED_1000)
+ val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
+ else if (pp->speed == SPEED_100)
+ val |= MVNETA_GMAC_CONFIG_MII_SPEED;
+
+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
+ } else {
+ /* Set phy address of the port */
+ mvreg_write(pp, MVNETA_PHY_ADDR, pp->phyaddr);
+
+ phydev = phy_connect(pp->bus, pp->phyaddr, dev,
+ pp->phy_interface);
+
+ pp->phydev = phydev;
+ phy_config(phydev);
+ phy_startup(phydev);
+ if (!phydev->link) {
+ printf("%s: No link.\n", phydev->dev->name);
+ return -1;
+ }
+
+ /* Full init on first call */
+ mvneta_init(dev);
+ pp->init = 1;
+ return 0;
+ }
}
+ /* Upon all following calls, this is enough */
+ mvneta_port_up(pp);
+ mvneta_port_enable(pp);
+
return 0;
}
@@ -1615,6 +1669,8 @@ static int mvneta_probe(struct udevice *dev)
struct mii_dev *bus;
unsigned long addr;
void *bd_space;
+ int ret;
+ int fl_node;
/*
* Allocate buffer area for descs and rx_buffers. This is only
@@ -1647,10 +1703,19 @@ static int mvneta_probe(struct udevice *dev)
/* PHY interface is already decoded in mvneta_ofdata_to_platdata() */
pp->phy_interface = pdata->phy_interface;
- /* Now read phyaddr from DT */
- addr = fdtdec_get_int(blob, node, "phy", 0);
- addr = fdt_node_offset_by_phandle(blob, addr);
- pp->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
+ /* fetch 'fixed-link' property from 'neta' node */
+ fl_node = fdt_subnode_offset(blob, node, "fixed-link");
+ if (fl_node != -FDT_ERR_NOTFOUND) {
+ /* set phy_addr to invalid value for fixed link */
+ pp->phyaddr = PHY_MAX_ADDR + 1;
+ pp->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
+ pp->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
+ } else {
+ /* Now read phyaddr from DT */
+ addr = fdtdec_get_int(blob, node, "phy", 0);
+ addr = fdt_node_offset_by_phandle(blob, addr);
+ pp->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
+ }
bus = mdio_alloc();
if (!bus) {
@@ -1664,7 +1729,11 @@ static int mvneta_probe(struct udevice *dev)
bus->priv = (void *)pp;
pp->bus = bus;
- return mdio_register(bus);
+ ret = mdio_register(bus);
+ if (ret)
+ return ret;
+
+ return board_network_enable(bus);
}
static void mvneta_stop(struct udevice *dev)
diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c
index 17fa0244d0..d4776a9c81 100644
--- a/drivers/pci/pcie_dw_mvebu.c
+++ b/drivers/pci/pcie_dw_mvebu.c
@@ -15,6 +15,7 @@
#include <dm.h>
#include <pci.h>
#include <asm/io.h>
+#include <asm-generic/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -461,6 +462,25 @@ static int pcie_dw_mvebu_probe(struct udevice *dev)
struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
struct udevice *ctlr = pci_get_controller(dev);
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
+#ifdef CONFIG_DM_GPIO
+ struct gpio_desc reset_gpio;
+
+ gpio_request_by_name(dev, "marvell,reset-gpio", 0, &reset_gpio,
+ GPIOD_IS_OUT);
+ /*
+ * Issue reset to add-in card trough the dedicated GPIO.
+ * Some boards are connecting the card reset pin to common system
+ * reset wire and others are using separate GPIO port.
+ * In the last case we have to release a reset of the addon card
+ * using this GPIO.
+ */
+ if (dm_gpio_is_valid(&reset_gpio)) {
+ dm_gpio_set_value(&reset_gpio, 1);
+ mdelay(200);
+ }
+#else
+ debug("PCIE Reset on GPIO support is missing\n");
+#endif /* CONFIG_DM_GPIO */
pcie->first_busno = dev->seq;
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 5129a57304..0bf8274405 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -25,6 +25,7 @@ config USB_XHCI_MVEBU
bool "MVEBU USB 3.0 support"
default y
depends on ARCH_MVEBU
+ select DM_REGULATOR
help
Choose this option to add support for USB 3.0 driver on mvebu
SoCs, which includes Armada8K, Armada3700 and other Armada
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
index 46eb937838..d880af1113 100644
--- a/drivers/usb/host/xhci-mvebu.c
+++ b/drivers/usb/host/xhci-mvebu.c
@@ -10,6 +10,7 @@
#include <dm.h>
#include <fdtdec.h>
#include <usb.h>
+#include <power/regulator.h>
#include <asm/gpio.h>
#include "xhci.h"
@@ -44,12 +45,22 @@ static int xhci_usb_probe(struct udevice *dev)
struct mvebu_xhci_platdata *plat = dev_get_platdata(dev);
struct mvebu_xhci *ctx = dev_get_priv(dev);
struct xhci_hcor *hcor;
- int len;
+ int len, ret;
+ struct udevice *regulator;
ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
len = HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase));
hcor = (struct xhci_hcor *)((uintptr_t)ctx->hcd + len);
+ ret = device_get_supply_regulator(dev, "vbus-supply", &regulator);
+ if (!ret) {
+ ret = regulator_set_enable(regulator, true);
+ if (ret) {
+ printf("Failed to turn ON the VBUS regulator\n");
+ return ret;
+ }
+ }
+
/* Enable USB xHCI (VBUS, reset etc) in board specific code */
board_xhci_enable();