diff options
Diffstat (limited to 'board')
-rw-r--r-- | board/Marvell/mvebu_armada-37xx/board.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c index 3337f3fbe7..b9878bf19d 100644 --- a/board/Marvell/mvebu_armada-37xx/board.c +++ b/board/Marvell/mvebu_armada-37xx/board.c @@ -5,7 +5,9 @@ */ #include <common.h> +#include <dm.h> #include <i2c.h> +#include <phy.h> #include <asm/io.h> #include <asm/arch/cpu.h> #include <asm/arch/soc.h> @@ -22,6 +24,29 @@ DECLARE_GLOBAL_DATA_PTR; #define PINCTRL_NB_REG_VALUE 0x000173fa #define PINCTRL_SB_REG_VALUE 0x00007a23 +/* Ethernet switch registers */ +/* SMI addresses for multi-chip mode */ +#define MVEBU_PORT_CTRL_SMI_ADDR(p) (16 + (p)) +#define MVEBU_SW_G2_SMI_ADDR (28) + +/* Multi-chip mode */ +#define MVEBU_SW_SMI_DATA_REG (1) +#define MVEBU_SW_SMI_CMD_REG (0) + #define SW_SMI_CMD_REG_ADDR_OFF 0 + #define SW_SMI_CMD_DEV_ADDR_OFF 5 + #define SW_SMI_CMD_SMI_OP_OFF 10 + #define SW_SMI_CMD_SMI_MODE_OFF 12 + #define SW_SMI_CMD_SMI_BUSY_OFF 15 + +/* Single-chip mode */ +/* Switch Port Registers */ +#define MVEBU_SW_LINK_CTRL_REG (1) +#define MVEBU_SW_PORT_CTRL_REG (4) + +/* Global 2 Registers */ +#define MVEBU_G2_SMI_PHY_CMD_REG (24) +#define MVEBU_G2_SMI_PHY_DATA_REG (25) + int board_early_init_f(void) { const void *blob = gd->fdt_blob; @@ -156,3 +181,69 @@ int board_xhci_enable(void) return 0; } + +/* Helper function for accessing switch devices in multi-chip connection mode */ +static int mii_multi_chip_mode_write(struct mii_dev *bus, int dev_smi_addr, + int smi_addr, int reg, u16 value) +{ + u16 smi_cmd = 0; + + if (bus->write(bus, dev_smi_addr, 0, + MVEBU_SW_SMI_DATA_REG, value) != 0) { + printf("Error writing to the PHY addr=%02x reg=%02x\n", + smi_addr, reg); + return -EFAULT; + } + + smi_cmd = (1 << SW_SMI_CMD_SMI_BUSY_OFF) | + (1 << SW_SMI_CMD_SMI_MODE_OFF) | + (1 << SW_SMI_CMD_SMI_OP_OFF) | + (smi_addr << SW_SMI_CMD_DEV_ADDR_OFF) | + (reg << SW_SMI_CMD_REG_ADDR_OFF); + if (bus->write(bus, dev_smi_addr, 0, + MVEBU_SW_SMI_CMD_REG, smi_cmd) != 0) { + printf("Error writing to the PHY addr=%02x reg=%02x\n", + smi_addr, reg); + return -EFAULT; + } + + return 0; +} + +/* Bring-up board-specific network stuff */ +int board_network_enable(struct mii_dev *bus) +{ + if (!of_machine_is_compatible("marvell,armada-3720-espressobin")) + return 0; + + /* + * FIXME: remove this code once Topaz driver gets available + * A3720 Community Board Only + * Configure Topaz switch (88E6341) + * Set port 0,1,2,3 to forwarding Mode (through Switch Port registers) + */ + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(0), + MVEBU_SW_PORT_CTRL_REG, 0x7f); + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(1), + MVEBU_SW_PORT_CTRL_REG, 0x7f); + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(2), + MVEBU_SW_PORT_CTRL_REG, 0x7f); + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(3), + MVEBU_SW_PORT_CTRL_REG, 0x7f); + + /* RGMII Delay on Port 0 (CPU port), force link to 1000Mbps */ + mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(0), + MVEBU_SW_LINK_CTRL_REG, 0xe002); + + /* Power up PHY 1, 2, 3 (through Global 2 registers) */ + mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR, + MVEBU_G2_SMI_PHY_DATA_REG, 0x1140); + mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR, + MVEBU_G2_SMI_PHY_CMD_REG, 0x9620); + mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR, + MVEBU_G2_SMI_PHY_CMD_REG, 0x9640); + mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR, + MVEBU_G2_SMI_PHY_CMD_REG, 0x9660); + + return 0; +} |