1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT) 2 /* 3 * Copyright (c) 2019 Microsemi Corporation 4 */ 5 6 #include <common.h> 7 #include <config.h> 8 #include <dm.h> 9 #include <dm/of_access.h> 10 #include <dm/of_addr.h> 11 #include <fdt_support.h> 12 #include <linux/io.h> 13 #include <linux/ioport.h> 14 #include <miiphy.h> 15 #include <net.h> 16 #include <wait_bit.h> 17 18 #include "mscc_miim.h" 19 #include "mscc_xfer.h" 20 #include "mscc_mac_table.h" 21 22 #define ANA_PORT_VLAN_CFG(x) (0x00 + 0x80 * (x)) 23 #define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20) 24 #define ANA_PORT_VLAN_CFG_POP_CNT(x) ((x) << 18) 25 #define ANA_PORT_CPU_FWD_CFG(x) (0x50 + 0x80 * (x)) 26 #define ANA_PORT_CPU_FWD_CFG_SRC_COPY_ENA BIT(1) 27 #define ANA_PORT_PORT_CFG(x) (0x60 + 0x80 * (x)) 28 #define ANA_PORT_PORT_CFG_RECV_ENA BIT(5) 29 #define ANA_PGID(x) (0x1000 + 4 * (x)) 30 31 #define SYS_FRM_AGING 0x8300 32 33 #define SYS_SYSTEM_RST_CFG 0x81b0 34 #define SYS_SYSTEM_RST_MEM_INIT BIT(0) 35 #define SYS_SYSTEM_RST_MEM_ENA BIT(1) 36 #define SYS_SYSTEM_RST_CORE_ENA BIT(2) 37 #define SYS_PORT_MODE(x) (0x81bc + 0x4 * (x)) 38 #define SYS_PORT_MODE_INCL_INJ_HDR BIT(0) 39 #define SYS_SWITCH_PORT_MODE(x) (0x8294 + 0x4 * (x)) 40 #define SYS_SWITCH_PORT_MODE_PORT_ENA BIT(3) 41 #define SYS_EGR_NO_SHARING 0x8378 42 #define SYS_SCH_CPU 0x85a0 43 44 #define REW_PORT_CFG(x) (0x8 + 0x80 * (x)) 45 #define REW_PORT_CFG_IFH_INSERT_ENA BIT(7) 46 47 #define GCB_DEVCPU_RST_SOFT_CHIP_RST 0x90 48 #define GCB_DEVCPU_RST_SOFT_CHIP_RST_SOFT_PHY BIT(1) 49 #define GCB_MISC_STAT 0x11c 50 #define GCB_MISC_STAT_PHY_READY BIT(3) 51 52 #define QS_XTR_MAP(x) (0x10 + 4 * (x)) 53 #define QS_XTR_MAP_GRP BIT(4) 54 #define QS_XTR_MAP_ENA BIT(0) 55 56 #define HSIO_PLL5G_CFG_PLL5G_CFG2 0x8 57 58 #define HSIO_RCOMP_CFG_CFG0 0x20 59 #define HSIO_RCOMP_CFG_CFG0_MODE_SEL(x) ((x) << 8) 60 #define HSIO_RCOMP_CFG_CFG0_RUN_CAL BIT(12) 61 #define HSIO_RCOMP_STATUS 0x24 62 #define HSIO_RCOMP_STATUS_BUSY BIT(12) 63 #define HSIO_RCOMP_STATUS_RCOMP_M GENMASK(3, 0) 64 #define HSIO_SERDES6G_ANA_CFG_DES_CFG 0x64 65 #define HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_ANA(x) ((x) << 1) 66 #define HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_HYST(x) ((x) << 5) 67 #define HSIO_SERDES6G_ANA_CFG_DES_CFG_MBTR_CTRL(x) ((x) << 10) 68 #define HSIO_SERDES6G_ANA_CFG_DES_CFG_PHS_CTRL(x) ((x) << 13) 69 #define HSIO_SERDES6G_ANA_CFG_IB_CFG 0x68 70 #define HSIO_SERDES6G_ANA_CFG_IB_CFG_RESISTOR_CTRL(x) (x) 71 #define HSIO_SERDES6G_ANA_CFG_IB_CFG_VBCOM(x) ((x) << 4) 72 #define HSIO_SERDES6G_ANA_CFG_IB_CFG_VBAC(x) ((x) << 7) 73 #define HSIO_SERDES6G_ANA_CFG_IB_CFG_RT(x) ((x) << 9) 74 #define HSIO_SERDES6G_ANA_CFG_IB_CFG_RF(x) ((x) << 14) 75 #define HSIO_SERDES6G_ANA_CFG_IB_CFG1 0x6c 76 #define HSIO_SERDES6G_ANA_CFG_IB_CFG1_RST BIT(0) 77 #define HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSDC BIT(2) 78 #define HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSAC BIT(3) 79 #define HSIO_SERDES6G_ANA_CFG_IB_CFG1_ANEG_MODE BIT(6) 80 #define HSIO_SERDES6G_ANA_CFG_IB_CFG1_CHF BIT(7) 81 #define HSIO_SERDES6G_ANA_CFG_IB_CFG1_C(x) ((x) << 8) 82 #define HSIO_SERDES6G_ANA_CFG_OB_CFG 0x70 83 #define HSIO_SERDES6G_ANA_CFG_OB_CFG_SR(x) ((x) << 4) 84 #define HSIO_SERDES6G_ANA_CFG_OB_CFG_SR_H BIT(8) 85 #define HSIO_SERDES6G_ANA_CFG_OB_CFG_POST0(x) ((x) << 23) 86 #define HSIO_SERDES6G_ANA_CFG_OB_CFG_POL BIT(29) 87 #define HSIO_SERDES6G_ANA_CFG_OB_CFG_ENA1V_MODE BIT(30) 88 #define HSIO_SERDES6G_ANA_CFG_OB_CFG1 0x74 89 #define HSIO_SERDES6G_ANA_CFG_OB_CFG1_LEV(x) (x) 90 #define HSIO_SERDES6G_ANA_CFG_OB_CFG1_ENA_CAS(x) ((x) << 6) 91 #define HSIO_SERDES6G_ANA_CFG_COMMON_CFG 0x7c 92 #define HSIO_SERDES6G_ANA_CFG_COMMON_CFG_IF_MODE(x) (x) 93 #define HSIO_SERDES6G_ANA_CFG_COMMON_CFG_ENA_LANE BIT(18) 94 #define HSIO_SERDES6G_ANA_CFG_COMMON_CFG_SYS_RST BIT(31) 95 #define HSIO_SERDES6G_ANA_CFG_PLL_CFG 0x80 96 #define HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_ENA BIT(7) 97 #define HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 8) 98 #define HSIO_SERDES6G_ANA_CFG_SER_CFG 0x84 99 #define HSIO_SERDES6G_DIG_CFG_MISC_CFG 0x88 100 #define HSIO_SERDES6G_DIG_CFG_MISC_CFG_LANE_RST BIT(0) 101 #define HSIO_MCB_SERDES6G_CFG 0xac 102 #define HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT BIT(31) 103 #define HSIO_MCB_SERDES6G_CFG_ADDR(x) (x) 104 105 #define DEV_GMII_PORT_MODE_CLK 0x0 106 #define DEV_GMII_PORT_MODE_CLK_PHY_RST BIT(0) 107 #define DEV_GMII_MAC_CFG_MAC_ENA 0xc 108 #define DEV_GMII_MAC_CFG_MAC_ENA_RX_ENA BIT(4) 109 #define DEV_GMII_MAC_CFG_MAC_ENA_TX_ENA BIT(0) 110 111 #define DEV_PORT_MODE_CLK 0x4 112 #define DEV_PORT_MODE_CLK_PHY_RST BIT(2) 113 #define DEV_PORT_MODE_CLK_LINK_SPEED_1000 1 114 #define DEV_MAC_CFG_MAC_ENA 0x10 115 #define DEV_MAC_CFG_MAC_ENA_RX_ENA BIT(4) 116 #define DEV_MAC_CFG_MAC_ENA_TX_ENA BIT(0) 117 #define DEV_MAC_CFG_MAC_IFG 0x24 118 #define DEV_MAC_CFG_MAC_IFG_TX_IFG(x) ((x) << 8) 119 #define DEV_MAC_CFG_MAC_IFG_RX_IFG2(x) ((x) << 4) 120 #define DEV_MAC_CFG_MAC_IFG_RX_IFG1(x) (x) 121 #define DEV_PCS1G_CFG_PCS1G_CFG 0x40 122 #define DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA BIT(0) 123 #define DEV_PCS1G_CFG_PCS1G_MODE 0x44 124 #define DEV_PCS1G_CFG_PCS1G_SD 0x48 125 #define DEV_PCS1G_CFG_PCS1G_ANEG 0x4c 126 #define DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x) ((x) << 16) 127 128 #define IFH_INJ_BYPASS BIT(31) 129 #define IFH_TAG_TYPE_C 0 130 #define MAC_VID 1 131 #define CPU_PORT 26 132 #define INTERNAL_PORT_MSK 0xFFFFFF 133 #define IFH_LEN 2 134 #define ETH_ALEN 6 135 #define PGID_BROADCAST 28 136 #define PGID_UNICAST 29 137 #define PGID_SRC 80 138 139 enum luton_target { 140 PORT0, 141 PORT1, 142 PORT2, 143 PORT3, 144 PORT4, 145 PORT5, 146 PORT6, 147 PORT7, 148 PORT8, 149 PORT9, 150 PORT10, 151 PORT11, 152 PORT12, 153 PORT13, 154 PORT14, 155 PORT15, 156 PORT16, 157 PORT17, 158 PORT18, 159 PORT19, 160 PORT20, 161 PORT21, 162 PORT22, 163 PORT23, 164 SYS, 165 ANA, 166 REW, 167 GCB, 168 QS, 169 HSIO, 170 TARGET_MAX, 171 }; 172 173 #define MAX_PORT (PORT23 - PORT0 + 1) 174 175 #define MIN_INT_PORT PORT0 176 #define MAX_INT_PORT (PORT11 - PORT0 + 1) 177 #define MIN_EXT_PORT PORT12 178 #define MAX_EXT_PORT MAX_PORT 179 180 enum luton_mdio_target { 181 MIIM, 182 TARGET_MDIO_MAX, 183 }; 184 185 enum luton_phy_id { 186 INTERNAL, 187 EXTERNAL, 188 NUM_PHY, 189 }; 190 191 struct luton_private { 192 void __iomem *regs[TARGET_MAX]; 193 struct mii_dev *bus[NUM_PHY]; 194 }; 195 196 static const unsigned long luton_regs_qs[] = { 197 [MSCC_QS_XTR_RD] = 0x18, 198 [MSCC_QS_XTR_FLUSH] = 0x28, 199 [MSCC_QS_XTR_DATA_PRESENT] = 0x2c, 200 [MSCC_QS_INJ_WR] = 0x3c, 201 [MSCC_QS_INJ_CTRL] = 0x44, 202 }; 203 204 static const unsigned long luton_regs_ana_table[] = { 205 [MSCC_ANA_TABLES_MACHDATA] = 0x11b0, 206 [MSCC_ANA_TABLES_MACLDATA] = 0x11b4, 207 [MSCC_ANA_TABLES_MACACCESS] = 0x11b8, 208 }; 209 210 static struct mscc_miim_dev miim[NUM_PHY]; 211 212 static struct mii_dev *luton_mdiobus_init(struct udevice *dev, 213 int mdiobus_id) 214 { 215 unsigned long phy_size[NUM_PHY]; 216 phys_addr_t phy_base[NUM_PHY]; 217 struct ofnode_phandle_args phandle; 218 ofnode eth_node, node, mdio_node; 219 struct resource res; 220 struct mii_dev *bus; 221 fdt32_t faddr; 222 int i; 223 224 bus = mdio_alloc(); 225 if (!bus) 226 return NULL; 227 228 /* gather only the first mdio bus */ 229 eth_node = dev_read_first_subnode(dev); 230 node = ofnode_first_subnode(eth_node); 231 ofnode_parse_phandle_with_args(node, "phy-handle", NULL, 0, 0, 232 &phandle); 233 mdio_node = ofnode_get_parent(phandle.node); 234 235 for (i = 0; i < TARGET_MDIO_MAX; i++) { 236 if (ofnode_read_resource(mdio_node, i, &res)) { 237 pr_err("%s: get OF resource failed\n", __func__); 238 return NULL; 239 } 240 241 faddr = cpu_to_fdt32(res.start); 242 phy_base[i] = ofnode_translate_address(mdio_node, &faddr); 243 phy_size[i] = res.end - res.start; 244 } 245 246 strcpy(bus->name, "miim-internal"); 247 miim[mdiobus_id].regs = ioremap(phy_base[mdiobus_id], 248 phy_size[mdiobus_id]); 249 bus->priv = &miim[mdiobus_id]; 250 bus->read = mscc_miim_read; 251 bus->write = mscc_miim_write; 252 253 if (mdio_register(bus)) 254 return NULL; 255 else 256 return bus; 257 } 258 259 static void luton_stop(struct udevice *dev) 260 { 261 struct luton_private *priv = dev_get_priv(dev); 262 263 /* 264 * Switch core only reset affects VCORE-III bus and MIPS frequency 265 * and thereby also the DDR SDRAM controller. The workaround is to 266 * not to redirect any trafic to the CPU after the data transfer. 267 */ 268 writel(GENMASK(9, 2), priv->regs[SYS] + SYS_SCH_CPU); 269 } 270 271 static void luton_cpu_capture_setup(struct luton_private *priv) 272 { 273 int i; 274 275 /* map the 8 CPU extraction queues to CPU port 26 */ 276 writel(0x0, priv->regs[SYS] + SYS_SCH_CPU); 277 278 for (i = 0; i <= 1; i++) { 279 /* 280 * One to one mapping from CPU Queue number to Group extraction 281 * number 282 */ 283 writel(QS_XTR_MAP_ENA | (QS_XTR_MAP_GRP * i), 284 priv->regs[QS] + QS_XTR_MAP(i)); 285 286 /* Enable IFH insertion/parsing on CPU ports */ 287 setbits_le32(priv->regs[REW] + REW_PORT_CFG(CPU_PORT + i), 288 REW_PORT_CFG_IFH_INSERT_ENA); 289 290 /* Enable IFH parsing on CPU port 0 and 1 */ 291 setbits_le32(priv->regs[SYS] + SYS_PORT_MODE(CPU_PORT + i), 292 SYS_PORT_MODE_INCL_INJ_HDR); 293 } 294 295 /* Make VLAN aware for CPU traffic */ 296 writel(ANA_PORT_VLAN_CFG_AWARE_ENA | 297 ANA_PORT_VLAN_CFG_POP_CNT(1) | 298 MAC_VID, 299 priv->regs[ANA] + ANA_PORT_VLAN_CFG(CPU_PORT)); 300 301 /* Disable learning (only RECV_ENA must be set) */ 302 writel(ANA_PORT_PORT_CFG_RECV_ENA, 303 priv->regs[ANA] + ANA_PORT_PORT_CFG(CPU_PORT)); 304 305 /* Enable switching to/from cpu port */ 306 setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(CPU_PORT), 307 SYS_SWITCH_PORT_MODE_PORT_ENA); 308 309 setbits_le32(priv->regs[SYS] + SYS_EGR_NO_SHARING, BIT(CPU_PORT)); 310 } 311 312 static void luton_gmii_port_init(struct luton_private *priv, int port) 313 { 314 void __iomem *regs = priv->regs[port]; 315 316 writel(0, regs + DEV_GMII_PORT_MODE_CLK); 317 318 /* Enable MAC RX and TX */ 319 writel(DEV_GMII_MAC_CFG_MAC_ENA_RX_ENA | 320 DEV_GMII_MAC_CFG_MAC_ENA_TX_ENA, 321 regs + DEV_GMII_MAC_CFG_MAC_ENA); 322 323 /* Make VLAN aware for CPU traffic */ 324 writel(ANA_PORT_VLAN_CFG_AWARE_ENA | 325 ANA_PORT_VLAN_CFG_POP_CNT(1) | 326 MAC_VID, 327 priv->regs[ANA] + ANA_PORT_VLAN_CFG(port - PORT0)); 328 329 /* Enable switching to/from port */ 330 setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port - PORT0), 331 SYS_SWITCH_PORT_MODE_PORT_ENA); 332 } 333 334 static void luton_port_init(struct luton_private *priv, int port) 335 { 336 void __iomem *regs = priv->regs[port]; 337 338 writel(0, regs + DEV_PORT_MODE_CLK); 339 340 /* Enable MAC RX and TX */ 341 writel(DEV_MAC_CFG_MAC_ENA_RX_ENA | 342 DEV_MAC_CFG_MAC_ENA_TX_ENA, 343 regs + DEV_MAC_CFG_MAC_ENA); 344 345 /* Make VLAN aware for CPU traffic */ 346 writel(ANA_PORT_VLAN_CFG_AWARE_ENA | 347 ANA_PORT_VLAN_CFG_POP_CNT(1) | 348 MAC_VID, 349 priv->regs[ANA] + ANA_PORT_VLAN_CFG(port - PORT0)); 350 351 /* Enable switching to/from port */ 352 setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port - PORT0), 353 SYS_SWITCH_PORT_MODE_PORT_ENA); 354 } 355 356 static void luton_ext_port_init(struct luton_private *priv, int port) 357 { 358 void __iomem *regs = priv->regs[port]; 359 360 /* Enable PCS */ 361 writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA, 362 regs + DEV_PCS1G_CFG_PCS1G_CFG); 363 364 /* Disable Signal Detect */ 365 writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD); 366 367 /* Enable MAC RX and TX */ 368 writel(DEV_MAC_CFG_MAC_ENA_RX_ENA | 369 DEV_MAC_CFG_MAC_ENA_TX_ENA, 370 regs + DEV_MAC_CFG_MAC_ENA); 371 372 /* Clear sgmii_mode_ena */ 373 writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE); 374 375 /* 376 * Clear sw_resolve_ena(bit 0) and set adv_ability to 377 * something meaningful just in case 378 */ 379 writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20), 380 regs + DEV_PCS1G_CFG_PCS1G_ANEG); 381 382 /* Set MAC IFG Gaps */ 383 writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(7) | 384 DEV_MAC_CFG_MAC_IFG_RX_IFG1(1) | 385 DEV_MAC_CFG_MAC_IFG_RX_IFG2(5), 386 regs + DEV_MAC_CFG_MAC_IFG); 387 388 /* Set link speed and release all resets */ 389 writel(DEV_PORT_MODE_CLK_LINK_SPEED_1000, 390 regs + DEV_PORT_MODE_CLK); 391 392 /* Make VLAN aware for CPU traffic */ 393 writel(ANA_PORT_VLAN_CFG_AWARE_ENA | 394 ANA_PORT_VLAN_CFG_POP_CNT(1) | 395 MAC_VID, 396 priv->regs[ANA] + ANA_PORT_VLAN_CFG(port - PORT0)); 397 398 /* Enable switching to/from port */ 399 setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port - PORT0), 400 SYS_SWITCH_PORT_MODE_PORT_ENA); 401 } 402 403 static void serdes6g_write(struct luton_private *priv, u32 addr) 404 { 405 u32 data; 406 407 writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT | 408 HSIO_MCB_SERDES6G_CFG_ADDR(addr), 409 priv->regs[HSIO] + HSIO_MCB_SERDES6G_CFG); 410 411 do { 412 data = readl(priv->regs[HSIO] + HSIO_MCB_SERDES6G_CFG); 413 } while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT); 414 415 mdelay(100); 416 } 417 418 static void serdes6g_cfg(struct luton_private *priv) 419 { 420 writel(HSIO_RCOMP_CFG_CFG0_MODE_SEL(0x3) | 421 HSIO_RCOMP_CFG_CFG0_RUN_CAL, 422 priv->regs[HSIO] + HSIO_RCOMP_CFG_CFG0); 423 424 while (readl(priv->regs[HSIO] + HSIO_RCOMP_STATUS) & 425 HSIO_RCOMP_STATUS_BUSY) 426 ; 427 428 writel(HSIO_SERDES6G_ANA_CFG_OB_CFG_SR(0xb) | 429 HSIO_SERDES6G_ANA_CFG_OB_CFG_SR_H | 430 HSIO_SERDES6G_ANA_CFG_OB_CFG_POST0(0x10) | 431 HSIO_SERDES6G_ANA_CFG_OB_CFG_POL | 432 HSIO_SERDES6G_ANA_CFG_OB_CFG_ENA1V_MODE, 433 priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_OB_CFG); 434 writel(HSIO_SERDES6G_ANA_CFG_OB_CFG1_LEV(0x18) | 435 HSIO_SERDES6G_ANA_CFG_OB_CFG1_ENA_CAS(0x1), 436 priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_OB_CFG1); 437 writel(HSIO_SERDES6G_ANA_CFG_IB_CFG_RESISTOR_CTRL(0xc) | 438 HSIO_SERDES6G_ANA_CFG_IB_CFG_VBCOM(0x4) | 439 HSIO_SERDES6G_ANA_CFG_IB_CFG_VBAC(0x5) | 440 HSIO_SERDES6G_ANA_CFG_IB_CFG_RT(0xf) | 441 HSIO_SERDES6G_ANA_CFG_IB_CFG_RF(0x4), 442 priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_IB_CFG); 443 writel(HSIO_SERDES6G_ANA_CFG_IB_CFG1_RST | 444 HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSDC | 445 HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSAC | 446 HSIO_SERDES6G_ANA_CFG_IB_CFG1_ANEG_MODE | 447 HSIO_SERDES6G_ANA_CFG_IB_CFG1_CHF | 448 HSIO_SERDES6G_ANA_CFG_IB_CFG1_C(0x4), 449 priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_IB_CFG1); 450 writel(HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_ANA(0x5) | 451 HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_HYST(0x5) | 452 HSIO_SERDES6G_ANA_CFG_DES_CFG_MBTR_CTRL(0x2) | 453 HSIO_SERDES6G_ANA_CFG_DES_CFG_PHS_CTRL(0x6), 454 priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_DES_CFG); 455 writel(HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_ENA | 456 HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_CTRL_DATA(0x78), 457 priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_PLL_CFG); 458 writel(HSIO_SERDES6G_ANA_CFG_COMMON_CFG_IF_MODE(0x30) | 459 HSIO_SERDES6G_ANA_CFG_COMMON_CFG_ENA_LANE, 460 priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_COMMON_CFG); 461 /* 462 * There are 4 serdes6g, configure all except serdes6g0, therefore 463 * the address is b1110 464 */ 465 serdes6g_write(priv, 0xe); 466 467 writel(readl(priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_COMMON_CFG) | 468 HSIO_SERDES6G_ANA_CFG_COMMON_CFG_SYS_RST, 469 priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_COMMON_CFG); 470 serdes6g_write(priv, 0xe); 471 472 clrbits_le32(priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_IB_CFG1, 473 HSIO_SERDES6G_ANA_CFG_IB_CFG1_RST); 474 writel(HSIO_SERDES6G_DIG_CFG_MISC_CFG_LANE_RST, 475 priv->regs[HSIO] + HSIO_SERDES6G_DIG_CFG_MISC_CFG); 476 serdes6g_write(priv, 0xe); 477 } 478 479 static int luton_switch_init(struct luton_private *priv) 480 { 481 setbits_le32(priv->regs[HSIO] + HSIO_PLL5G_CFG_PLL5G_CFG2, BIT(1)); 482 clrbits_le32(priv->regs[HSIO] + HSIO_PLL5G_CFG_PLL5G_CFG2, BIT(1)); 483 484 /* Reset switch & memories */ 485 writel(SYS_SYSTEM_RST_MEM_ENA | SYS_SYSTEM_RST_MEM_INIT, 486 priv->regs[SYS] + SYS_SYSTEM_RST_CFG); 487 488 /* Wait to complete */ 489 if (wait_for_bit_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG, 490 SYS_SYSTEM_RST_MEM_INIT, false, 2000, false)) { 491 printf("Timeout in memory reset\n"); 492 } 493 494 /* Enable switch core */ 495 setbits_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG, 496 SYS_SYSTEM_RST_CORE_ENA); 497 498 /* Setup the Serdes6g macros */ 499 serdes6g_cfg(priv); 500 501 return 0; 502 } 503 504 static int luton_initialize(struct luton_private *priv) 505 { 506 int ret, i; 507 508 /* Initialize switch memories, enable core */ 509 ret = luton_switch_init(priv); 510 if (ret) 511 return ret; 512 513 /* 514 * Disable port-to-port by switching 515 * Put front ports in "port isolation modes" - i.e. they can't send 516 * to other ports - via the PGID sorce masks. 517 */ 518 for (i = 0; i < MAX_PORT; i++) 519 writel(0, priv->regs[ANA] + ANA_PGID(PGID_SRC + i)); 520 521 /* Flush queues */ 522 mscc_flush(priv->regs[QS], luton_regs_qs); 523 524 /* Setup frame ageing - "2 sec" - The unit is 4ns on Luton*/ 525 writel(2000000000 / 4, 526 priv->regs[SYS] + SYS_FRM_AGING); 527 528 for (i = PORT0; i < MAX_PORT; i++) { 529 if (i < PORT10) 530 luton_gmii_port_init(priv, i); 531 else 532 if (i == PORT10 || i == PORT11) 533 luton_port_init(priv, i); 534 else 535 luton_ext_port_init(priv, i); 536 } 537 538 luton_cpu_capture_setup(priv); 539 540 return 0; 541 } 542 543 static int luton_write_hwaddr(struct udevice *dev) 544 { 545 struct luton_private *priv = dev_get_priv(dev); 546 struct eth_pdata *pdata = dev_get_platdata(dev); 547 548 mscc_mac_table_add(priv->regs[ANA], luton_regs_ana_table, 549 pdata->enetaddr, PGID_UNICAST); 550 551 writel(BIT(CPU_PORT), priv->regs[ANA] + ANA_PGID(PGID_UNICAST)); 552 553 return 0; 554 } 555 556 static int luton_start(struct udevice *dev) 557 { 558 struct luton_private *priv = dev_get_priv(dev); 559 struct eth_pdata *pdata = dev_get_platdata(dev); 560 const unsigned char mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 561 0xff }; 562 int ret; 563 564 ret = luton_initialize(priv); 565 if (ret) 566 return ret; 567 568 /* Set MAC address tables entries for CPU redirection */ 569 mscc_mac_table_add(priv->regs[ANA], luton_regs_ana_table, 570 mac, PGID_BROADCAST); 571 572 writel(BIT(CPU_PORT) | INTERNAL_PORT_MSK, 573 priv->regs[ANA] + ANA_PGID(PGID_BROADCAST)); 574 575 mscc_mac_table_add(priv->regs[ANA], luton_regs_ana_table, 576 pdata->enetaddr, PGID_UNICAST); 577 578 writel(BIT(CPU_PORT), priv->regs[ANA] + ANA_PGID(PGID_UNICAST)); 579 580 return 0; 581 } 582 583 static int luton_send(struct udevice *dev, void *packet, int length) 584 { 585 struct luton_private *priv = dev_get_priv(dev); 586 u32 ifh[IFH_LEN]; 587 int port = BIT(0); /* use port 0 */ 588 u32 *buf = packet; 589 590 ifh[0] = IFH_INJ_BYPASS | port; 591 ifh[1] = (IFH_TAG_TYPE_C << 16); 592 593 return mscc_send(priv->regs[QS], luton_regs_qs, 594 ifh, IFH_LEN, buf, length); 595 } 596 597 static int luton_recv(struct udevice *dev, int flags, uchar **packetp) 598 { 599 struct luton_private *priv = dev_get_priv(dev); 600 u32 *rxbuf = (u32 *)net_rx_packets[0]; 601 int byte_cnt = 0; 602 603 byte_cnt = mscc_recv(priv->regs[QS], luton_regs_qs, rxbuf, IFH_LEN, 604 true); 605 606 *packetp = net_rx_packets[0]; 607 608 return byte_cnt; 609 } 610 611 static int luton_probe(struct udevice *dev) 612 { 613 struct luton_private *priv = dev_get_priv(dev); 614 int i; 615 616 struct { 617 enum luton_target id; 618 char *name; 619 } reg[] = { 620 { PORT0, "port0" }, 621 { PORT1, "port1" }, 622 { PORT2, "port2" }, 623 { PORT3, "port3" }, 624 { PORT4, "port4" }, 625 { PORT5, "port5" }, 626 { PORT6, "port6" }, 627 { PORT7, "port7" }, 628 { PORT8, "port8" }, 629 { PORT9, "port9" }, 630 { PORT10, "port10" }, 631 { PORT11, "port11" }, 632 { PORT12, "port12" }, 633 { PORT13, "port13" }, 634 { PORT14, "port14" }, 635 { PORT15, "port15" }, 636 { PORT16, "port16" }, 637 { PORT17, "port17" }, 638 { PORT18, "port18" }, 639 { PORT19, "port19" }, 640 { PORT20, "port20" }, 641 { PORT21, "port21" }, 642 { PORT22, "port22" }, 643 { PORT23, "port23" }, 644 { SYS, "sys" }, 645 { ANA, "ana" }, 646 { REW, "rew" }, 647 { GCB, "gcb" }, 648 { QS, "qs" }, 649 { HSIO, "hsio" }, 650 }; 651 652 if (!priv) 653 return -EINVAL; 654 655 for (i = 0; i < ARRAY_SIZE(reg); i++) { 656 priv->regs[reg[i].id] = dev_remap_addr_name(dev, reg[i].name); 657 if (!priv->regs[reg[i].id]) { 658 debug 659 ("Error can't get regs base addresses for %s\n", 660 reg[i].name); 661 return -ENOMEM; 662 } 663 } 664 665 /* Release reset in the CU-PHY */ 666 writel(0, priv->regs[GCB] + GCB_DEVCPU_RST_SOFT_CHIP_RST); 667 668 /* Ports with ext phy don't need to reset clk */ 669 for (i = PORT0; i < MAX_INT_PORT; i++) { 670 if (i < PORT10) 671 clrbits_le32(priv->regs[i] + DEV_GMII_PORT_MODE_CLK, 672 DEV_GMII_PORT_MODE_CLK_PHY_RST); 673 else 674 clrbits_le32(priv->regs[i] + DEV_PORT_MODE_CLK, 675 DEV_PORT_MODE_CLK_PHY_RST); 676 } 677 678 /* Wait for internal PHY to be ready */ 679 if (wait_for_bit_le32(priv->regs[GCB] + GCB_MISC_STAT, 680 GCB_MISC_STAT_PHY_READY, true, 500, false)) 681 return -EACCES; 682 683 priv->bus[INTERNAL] = luton_mdiobus_init(dev, INTERNAL); 684 685 for (i = 0; i < MAX_INT_PORT; i++) { 686 phy_connect(priv->bus[INTERNAL], i, dev, 687 PHY_INTERFACE_MODE_NONE); 688 } 689 690 /* 691 * coma_mode is need on only one phy, because all the other phys 692 * will be affected. 693 */ 694 mscc_miim_write(priv->bus[INTERNAL], 0, 0, 31, 0x10); 695 mscc_miim_write(priv->bus[INTERNAL], 0, 0, 14, 0x800); 696 mscc_miim_write(priv->bus[INTERNAL], 0, 0, 31, 0); 697 698 return 0; 699 } 700 701 static int luton_remove(struct udevice *dev) 702 { 703 struct luton_private *priv = dev_get_priv(dev); 704 int i; 705 706 for (i = 0; i < NUM_PHY; i++) { 707 mdio_unregister(priv->bus[i]); 708 mdio_free(priv->bus[i]); 709 } 710 711 return 0; 712 } 713 714 static const struct eth_ops luton_ops = { 715 .start = luton_start, 716 .stop = luton_stop, 717 .send = luton_send, 718 .recv = luton_recv, 719 .write_hwaddr = luton_write_hwaddr, 720 }; 721 722 static const struct udevice_id mscc_luton_ids[] = { 723 {.compatible = "mscc,vsc7527-switch", }, 724 { /* Sentinel */ } 725 }; 726 727 U_BOOT_DRIVER(luton) = { 728 .name = "luton-switch", 729 .id = UCLASS_ETH, 730 .of_match = mscc_luton_ids, 731 .probe = luton_probe, 732 .remove = luton_remove, 733 .ops = &luton_ops, 734 .priv_auto_alloc_size = sizeof(struct luton_private), 735 .platdata_auto_alloc_size = sizeof(struct eth_pdata), 736 }; 737