1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2016 Stefan Roese <sr@denx.de> 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <i2c.h> 9 #include <phy.h> 10 #include <asm/io.h> 11 #include <asm/arch/cpu.h> 12 #include <asm/arch/soc.h> 13 14 DECLARE_GLOBAL_DATA_PTR; 15 16 /* IO expander I2C device */ 17 #define I2C_IO_EXP_ADDR 0x22 18 #define I2C_IO_CFG_REG_0 0x6 19 #define I2C_IO_DATA_OUT_REG_0 0x2 20 #define I2C_IO_REG_0_SATA_OFF 2 21 #define I2C_IO_REG_0_USB_H_OFF 1 22 23 /* The pin control values are the same for DB and Espressobin */ 24 #define PINCTRL_NB_REG_VALUE 0x000173fa 25 #define PINCTRL_SB_REG_VALUE 0x00007a23 26 27 /* Ethernet switch registers */ 28 /* SMI addresses for multi-chip mode */ 29 #define MVEBU_PORT_CTRL_SMI_ADDR(p) (16 + (p)) 30 #define MVEBU_SW_G2_SMI_ADDR (28) 31 32 /* Multi-chip mode */ 33 #define MVEBU_SW_SMI_DATA_REG (1) 34 #define MVEBU_SW_SMI_CMD_REG (0) 35 #define SW_SMI_CMD_REG_ADDR_OFF 0 36 #define SW_SMI_CMD_DEV_ADDR_OFF 5 37 #define SW_SMI_CMD_SMI_OP_OFF 10 38 #define SW_SMI_CMD_SMI_MODE_OFF 12 39 #define SW_SMI_CMD_SMI_BUSY_OFF 15 40 41 /* Single-chip mode */ 42 /* Switch Port Registers */ 43 #define MVEBU_SW_LINK_CTRL_REG (1) 44 #define MVEBU_SW_PORT_CTRL_REG (4) 45 46 /* Global 2 Registers */ 47 #define MVEBU_G2_SMI_PHY_CMD_REG (24) 48 #define MVEBU_G2_SMI_PHY_DATA_REG (25) 49 50 int board_early_init_f(void) 51 { 52 return 0; 53 } 54 55 int board_init(void) 56 { 57 /* adress of boot parameters */ 58 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; 59 60 return 0; 61 } 62 63 /* Board specific AHCI / SATA enable code */ 64 int board_ahci_enable(void) 65 { 66 struct udevice *dev; 67 int ret; 68 u8 buf[8]; 69 70 /* Only DB requres this configuration */ 71 if (!of_machine_is_compatible("marvell,armada-3720-db")) 72 return 0; 73 74 /* Configure IO exander PCA9555: 7bit address 0x22 */ 75 ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); 76 if (ret) { 77 printf("Cannot find PCA9555: %d\n", ret); 78 return 0; 79 } 80 81 ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1); 82 if (ret) { 83 printf("Failed to read IO expander value via I2C\n"); 84 return -EIO; 85 } 86 87 /* 88 * Enable SATA power via IO expander connected via I2C by setting 89 * the corresponding bit to output mode to enable power for SATA 90 */ 91 buf[0] &= ~(1 << I2C_IO_REG_0_SATA_OFF); 92 ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1); 93 if (ret) { 94 printf("Failed to set IO expander via I2C\n"); 95 return -EIO; 96 } 97 98 return 0; 99 } 100 101 /* Board specific xHCI enable code */ 102 int board_xhci_enable(fdt_addr_t base) 103 { 104 struct udevice *dev; 105 int ret; 106 u8 buf[8]; 107 108 /* Only DB requres this configuration */ 109 if (!of_machine_is_compatible("marvell,armada-3720-db")) 110 return 0; 111 112 /* Configure IO exander PCA9555: 7bit address 0x22 */ 113 ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); 114 if (ret) { 115 printf("Cannot find PCA9555: %d\n", ret); 116 return 0; 117 } 118 119 printf("Enable USB VBUS\n"); 120 121 /* 122 * Read configuration (direction) and set VBUS pin as output 123 * (reset pin = output) 124 */ 125 ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1); 126 if (ret) { 127 printf("Failed to read IO expander value via I2C\n"); 128 return -EIO; 129 } 130 buf[0] &= ~(1 << I2C_IO_REG_0_USB_H_OFF); 131 ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1); 132 if (ret) { 133 printf("Failed to set IO expander via I2C\n"); 134 return -EIO; 135 } 136 137 /* Read VBUS output value and disable it */ 138 ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); 139 if (ret) { 140 printf("Failed to read IO expander value via I2C\n"); 141 return -EIO; 142 } 143 buf[0] &= ~(1 << I2C_IO_REG_0_USB_H_OFF); 144 ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); 145 if (ret) { 146 printf("Failed to set IO expander via I2C\n"); 147 return -EIO; 148 } 149 150 /* 151 * Required delay for configuration to settle - must wait for 152 * power on port is disabled in case VBUS signal was high, 153 * required 3 seconds delay to let VBUS signal fully settle down 154 */ 155 mdelay(3000); 156 157 /* Enable VBUS power: Set output value of VBUS pin as enabled */ 158 buf[0] |= (1 << I2C_IO_REG_0_USB_H_OFF); 159 ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); 160 if (ret) { 161 printf("Failed to set IO expander via I2C\n"); 162 return -EIO; 163 } 164 165 mdelay(500); /* required delay to let output value settle */ 166 167 return 0; 168 } 169 170 /* Helper function for accessing switch devices in multi-chip connection mode */ 171 static int mii_multi_chip_mode_write(struct mii_dev *bus, int dev_smi_addr, 172 int smi_addr, int reg, u16 value) 173 { 174 u16 smi_cmd = 0; 175 176 if (bus->write(bus, dev_smi_addr, 0, 177 MVEBU_SW_SMI_DATA_REG, value) != 0) { 178 printf("Error writing to the PHY addr=%02x reg=%02x\n", 179 smi_addr, reg); 180 return -EFAULT; 181 } 182 183 smi_cmd = (1 << SW_SMI_CMD_SMI_BUSY_OFF) | 184 (1 << SW_SMI_CMD_SMI_MODE_OFF) | 185 (1 << SW_SMI_CMD_SMI_OP_OFF) | 186 (smi_addr << SW_SMI_CMD_DEV_ADDR_OFF) | 187 (reg << SW_SMI_CMD_REG_ADDR_OFF); 188 if (bus->write(bus, dev_smi_addr, 0, 189 MVEBU_SW_SMI_CMD_REG, smi_cmd) != 0) { 190 printf("Error writing to the PHY addr=%02x reg=%02x\n", 191 smi_addr, reg); 192 return -EFAULT; 193 } 194 195 return 0; 196 } 197 198 /* Bring-up board-specific network stuff */ 199 int board_network_enable(struct mii_dev *bus) 200 { 201 if (!of_machine_is_compatible("marvell,armada-3720-espressobin")) 202 return 0; 203 204 /* 205 * FIXME: remove this code once Topaz driver gets available 206 * A3720 Community Board Only 207 * Configure Topaz switch (88E6341) 208 * Set port 0,1,2,3 to forwarding Mode (through Switch Port registers) 209 */ 210 mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(0), 211 MVEBU_SW_PORT_CTRL_REG, 0x7f); 212 mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(1), 213 MVEBU_SW_PORT_CTRL_REG, 0x7f); 214 mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(2), 215 MVEBU_SW_PORT_CTRL_REG, 0x7f); 216 mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(3), 217 MVEBU_SW_PORT_CTRL_REG, 0x7f); 218 219 /* RGMII Delay on Port 0 (CPU port), force link to 1000Mbps */ 220 mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(0), 221 MVEBU_SW_LINK_CTRL_REG, 0xe002); 222 223 /* Power up PHY 1, 2, 3 (through Global 2 registers) */ 224 mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR, 225 MVEBU_G2_SMI_PHY_DATA_REG, 0x1140); 226 mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR, 227 MVEBU_G2_SMI_PHY_CMD_REG, 0x9620); 228 mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR, 229 MVEBU_G2_SMI_PHY_CMD_REG, 0x9640); 230 mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR, 231 MVEBU_G2_SMI_PHY_CMD_REG, 0x9660); 232 233 return 0; 234 } 235