developer | fd40db2 | 2021-04-29 10:08:25 +0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * Copyright (c) 2018 MediaTek Inc. |
| 4 | * Author: Weijie Gao <weijie.gao@mediatek.com> |
| 5 | */ |
| 6 | |
| 7 | #include <linux/kernel.h> |
| 8 | #include <linux/delay.h> |
| 9 | |
| 10 | #include "mt753x.h" |
| 11 | #include "mt753x_regs.h" |
| 12 | |
| 13 | /* MT7530 registers */ |
| 14 | |
| 15 | /* Unique fields of PMCR for MT7530 */ |
| 16 | #define FORCE_MODE BIT(15) |
| 17 | |
| 18 | /* Unique fields of GMACCR for MT7530 */ |
| 19 | #define VLAN_SUPT_NO_S 14 |
| 20 | #define VLAN_SUPT_NO_M 0x1c000 |
| 21 | #define LATE_COL_DROP BIT(13) |
| 22 | |
| 23 | /* Unique fields of (M)HWSTRAP for MT7530 */ |
| 24 | #define BOND_OPTION BIT(24) |
| 25 | #define P5_PHY0_SEL BIT(20) |
| 26 | #define CHG_TRAP BIT(16) |
| 27 | #define LOOPDET_DIS BIT(14) |
| 28 | #define P5_INTF_SEL_GMAC5 BIT(13) |
| 29 | #define SMI_ADDR_S 11 |
| 30 | #define SMI_ADDR_M 0x1800 |
| 31 | #define XTAL_FSEL_S 9 |
| 32 | #define XTAL_FSEL_M 0x600 |
| 33 | #define P6_INTF_DIS BIT(8) |
| 34 | #define P5_INTF_MODE_RGMII BIT(7) |
| 35 | #define P5_INTF_DIS_S BIT(6) |
| 36 | #define C_MDIO_BPS_S BIT(5) |
| 37 | #define EEPROM_EN_S BIT(4) |
| 38 | |
| 39 | /* PHY EEE Register bitmap of define */ |
| 40 | #define PHY_DEV07 0x07 |
| 41 | #define PHY_DEV07_REG_03C 0x3c |
| 42 | |
| 43 | /* PHY Extend Register 0x14 bitmap of define */ |
| 44 | #define PHY_EXT_REG_14 0x14 |
| 45 | |
| 46 | /* Fields of PHY_EXT_REG_14 */ |
| 47 | #define PHY_EN_DOWN_SHFIT BIT(4) |
| 48 | |
| 49 | /* PHY Token Ring Register 0x10 bitmap of define */ |
| 50 | #define PHY_TR_REG_10 0x10 |
| 51 | |
| 52 | /* PHY Token Ring Register 0x12 bitmap of define */ |
| 53 | #define PHY_TR_REG_12 0x12 |
| 54 | |
| 55 | /* PHY LPI PCS/DSP Control Register bitmap of define */ |
| 56 | #define PHY_LPI_REG_11 0x11 |
| 57 | |
| 58 | /* PHY DEV 0x1e Register bitmap of define */ |
| 59 | #define PHY_DEV1E 0x1e |
| 60 | #define PHY_DEV1E_REG_123 0x123 |
| 61 | #define PHY_DEV1E_REG_A6 0xa6 |
| 62 | |
| 63 | /* Values of XTAL_FSEL */ |
| 64 | #define XTAL_20MHZ 1 |
| 65 | #define XTAL_40MHZ 2 |
| 66 | #define XTAL_25MHZ 3 |
| 67 | |
| 68 | /* Top single control CR define */ |
| 69 | #define TOP_SIG_CTRL 0x7808 |
| 70 | |
| 71 | /* TOP_SIG_CTRL Register bitmap of define */ |
| 72 | #define OUTPUT_INTR_S 16 |
| 73 | #define OUTPUT_INTR_M 0x30000 |
| 74 | |
| 75 | #define P6ECR 0x7830 |
| 76 | #define P6_INTF_MODE_TRGMII BIT(0) |
| 77 | |
| 78 | #define TRGMII_TXCTRL 0x7a40 |
| 79 | #define TRAIN_TXEN BIT(31) |
| 80 | #define TXC_INV BIT(30) |
| 81 | #define TX_DOEO BIT(29) |
| 82 | #define TX_RST BIT(28) |
| 83 | |
| 84 | #define TRGMII_TD0_CTRL 0x7a50 |
| 85 | #define TRGMII_TD1_CTRL 0x7a58 |
| 86 | #define TRGMII_TD2_CTRL 0x7a60 |
| 87 | #define TRGMII_TD3_CTRL 0x7a68 |
| 88 | #define TRGMII_TXCTL_CTRL 0x7a70 |
| 89 | #define TRGMII_TCK_CTRL 0x7a78 |
| 90 | #define TRGMII_TD_CTRL(n) (0x7a50 + (n) * 8) |
| 91 | #define NUM_TRGMII_CTRL 6 |
| 92 | #define TX_DMPEDRV BIT(31) |
| 93 | #define TX_DM_SR BIT(15) |
| 94 | #define TX_DMERODT BIT(14) |
| 95 | #define TX_DMOECTL BIT(13) |
| 96 | #define TX_TAP_S 8 |
| 97 | #define TX_TAP_M 0xf00 |
| 98 | #define TX_TRAIN_WD_S 0 |
| 99 | #define TX_TRAIN_WD_M 0xff |
| 100 | |
| 101 | #define TRGMII_TD0_ODT 0x7a54 |
| 102 | #define TRGMII_TD1_ODT 0x7a5c |
| 103 | #define TRGMII_TD2_ODT 0x7a64 |
| 104 | #define TRGMII_TD3_ODT 0x7a6c |
| 105 | #define TRGMII_TXCTL_ODT 0x7574 |
| 106 | #define TRGMII_TCK_ODT 0x757c |
| 107 | #define TRGMII_TD_ODT(n) (0x7a54 + (n) * 8) |
| 108 | #define NUM_TRGMII_ODT 6 |
| 109 | #define TX_DM_DRVN_PRE_S 30 |
| 110 | #define TX_DM_DRVN_PRE_M 0xc0000000 |
| 111 | #define TX_DM_DRVP_PRE_S 28 |
| 112 | #define TX_DM_DRVP_PRE_M 0x30000000 |
| 113 | #define TX_DM_TDSEL_S 24 |
| 114 | #define TX_DM_TDSEL_M 0xf000000 |
| 115 | #define TX_ODTEN BIT(23) |
| 116 | #define TX_DME_PRE BIT(20) |
| 117 | #define TX_DM_DRVNT0 BIT(19) |
| 118 | #define TX_DM_DRVPT0 BIT(18) |
| 119 | #define TX_DM_DRVNTE BIT(17) |
| 120 | #define TX_DM_DRVPTE BIT(16) |
| 121 | #define TX_DM_ODTN_S 12 |
| 122 | #define TX_DM_ODTN_M 0x7000 |
| 123 | #define TX_DM_ODTP_S 8 |
| 124 | #define TX_DM_ODTP_M 0x700 |
| 125 | #define TX_DM_DRVN_S 4 |
| 126 | #define TX_DM_DRVN_M 0xf0 |
| 127 | #define TX_DM_DRVP_S 0 |
| 128 | #define TX_DM_DRVP_M 0x0f |
| 129 | |
| 130 | #define P5RGMIIRXCR 0x7b00 |
| 131 | #define CSR_RGMII_RCTL_CFG_S 24 |
| 132 | #define CSR_RGMII_RCTL_CFG_M 0x7000000 |
| 133 | #define CSR_RGMII_RXD_CFG_S 16 |
| 134 | #define CSR_RGMII_RXD_CFG_M 0x70000 |
| 135 | #define CSR_RGMII_EDGE_ALIGN BIT(8) |
| 136 | #define CSR_RGMII_RXC_90DEG_CFG_S 4 |
| 137 | #define CSR_RGMII_RXC_90DEG_CFG_M 0xf0 |
| 138 | #define CSR_RGMII_RXC_0DEG_CFG_S 0 |
| 139 | #define CSR_RGMII_RXC_0DEG_CFG_M 0x0f |
| 140 | |
| 141 | #define P5RGMIITXCR 0x7b04 |
| 142 | #define CSR_RGMII_TXEN_CFG_S 16 |
| 143 | #define CSR_RGMII_TXEN_CFG_M 0x70000 |
| 144 | #define CSR_RGMII_TXD_CFG_S 8 |
| 145 | #define CSR_RGMII_TXD_CFG_M 0x700 |
| 146 | #define CSR_RGMII_TXC_CFG_S 0 |
| 147 | #define CSR_RGMII_TXC_CFG_M 0x1f |
| 148 | |
| 149 | #define CHIP_REV 0x7ffc |
| 150 | #define CHIP_NAME_S 16 |
| 151 | #define CHIP_NAME_M 0xffff0000 |
| 152 | #define CHIP_REV_S 0 |
| 153 | #define CHIP_REV_M 0x0f |
| 154 | |
| 155 | /* MMD registers */ |
| 156 | #define CORE_PLL_GROUP2 0x401 |
| 157 | #define RG_SYSPLL_EN_NORMAL BIT(15) |
| 158 | #define RG_SYSPLL_VODEN BIT(14) |
| 159 | #define RG_SYSPLL_POSDIV_S 5 |
| 160 | #define RG_SYSPLL_POSDIV_M 0x60 |
| 161 | |
| 162 | #define CORE_PLL_GROUP4 0x403 |
| 163 | #define RG_SYSPLL_DDSFBK_EN BIT(12) |
| 164 | #define RG_SYSPLL_BIAS_EN BIT(11) |
| 165 | #define RG_SYSPLL_BIAS_LPF_EN BIT(10) |
| 166 | |
| 167 | #define CORE_PLL_GROUP5 0x404 |
| 168 | #define RG_LCDDS_PCW_NCPO1_S 0 |
| 169 | #define RG_LCDDS_PCW_NCPO1_M 0xffff |
| 170 | |
| 171 | #define CORE_PLL_GROUP6 0x405 |
| 172 | #define RG_LCDDS_PCW_NCPO0_S 0 |
| 173 | #define RG_LCDDS_PCW_NCPO0_M 0xffff |
| 174 | |
| 175 | #define CORE_PLL_GROUP7 0x406 |
| 176 | #define RG_LCDDS_PWDB BIT(15) |
| 177 | #define RG_LCDDS_ISO_EN BIT(13) |
| 178 | #define RG_LCCDS_C_S 4 |
| 179 | #define RG_LCCDS_C_M 0x70 |
| 180 | #define RG_LCDDS_PCW_NCPO_CHG BIT(3) |
| 181 | |
| 182 | #define CORE_PLL_GROUP10 0x409 |
| 183 | #define RG_LCDDS_SSC_DELTA_S 0 |
| 184 | #define RG_LCDDS_SSC_DELTA_M 0xfff |
| 185 | |
| 186 | #define CORE_PLL_GROUP11 0x40a |
| 187 | #define RG_LCDDS_SSC_DELTA1_S 0 |
| 188 | #define RG_LCDDS_SSC_DELTA1_M 0xfff |
| 189 | |
| 190 | #define CORE_GSWPLL_GCR_1 0x040d |
| 191 | #define GSWPLL_PREDIV_S 14 |
| 192 | #define GSWPLL_PREDIV_M 0xc000 |
| 193 | #define GSWPLL_POSTDIV_200M_S 12 |
| 194 | #define GSWPLL_POSTDIV_200M_M 0x3000 |
| 195 | #define GSWPLL_EN_PRE BIT(11) |
| 196 | #define GSWPLL_FBKSEL BIT(10) |
| 197 | #define GSWPLL_BP BIT(9) |
| 198 | #define GSWPLL_BR BIT(8) |
| 199 | #define GSWPLL_FBKDIV_200M_S 0 |
| 200 | #define GSWPLL_FBKDIV_200M_M 0xff |
| 201 | |
| 202 | #define CORE_GSWPLL_GCR_2 0x040e |
| 203 | #define GSWPLL_POSTDIV_500M_S 8 |
| 204 | #define GSWPLL_POSTDIV_500M_M 0x300 |
| 205 | #define GSWPLL_FBKDIV_500M_S 0 |
| 206 | #define GSWPLL_FBKDIV_500M_M 0xff |
| 207 | |
| 208 | #define TRGMII_GSW_CLK_CG 0x0410 |
| 209 | #define TRGMIICK_EN BIT(1) |
| 210 | #define GSWCK_EN BIT(0) |
| 211 | |
| 212 | static int mt7530_mii_read(struct gsw_mt753x *gsw, int phy, int reg) |
| 213 | { |
| 214 | if (phy < MT753X_NUM_PHYS) |
| 215 | phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; |
| 216 | |
| 217 | return mdiobus_read(gsw->host_bus, phy, reg); |
| 218 | } |
| 219 | |
| 220 | static void mt7530_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val) |
| 221 | { |
| 222 | if (phy < MT753X_NUM_PHYS) |
| 223 | phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; |
| 224 | |
| 225 | mdiobus_write(gsw->host_bus, phy, reg, val); |
| 226 | } |
| 227 | |
| 228 | static int mt7530_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg) |
| 229 | { |
| 230 | u16 val; |
| 231 | |
| 232 | if (addr < MT753X_NUM_PHYS) |
| 233 | addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; |
| 234 | |
| 235 | mutex_lock(&gsw->host_bus->mdio_lock); |
| 236 | |
| 237 | gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, |
| 238 | (MMD_ADDR << MMD_CMD_S) | |
| 239 | ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); |
| 240 | |
| 241 | gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg); |
| 242 | |
| 243 | gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, |
| 244 | (MMD_DATA << MMD_CMD_S) | |
| 245 | ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); |
| 246 | |
| 247 | val = gsw->host_bus->read(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG); |
| 248 | |
| 249 | mutex_unlock(&gsw->host_bus->mdio_lock); |
| 250 | |
| 251 | return val; |
| 252 | } |
| 253 | |
| 254 | static void mt7530_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, |
| 255 | u16 reg, u16 val) |
| 256 | { |
| 257 | if (addr < MT753X_NUM_PHYS) |
| 258 | addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; |
| 259 | |
| 260 | mutex_lock(&gsw->host_bus->mdio_lock); |
| 261 | |
| 262 | gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, |
| 263 | (MMD_ADDR << MMD_CMD_S) | |
| 264 | ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); |
| 265 | |
| 266 | gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg); |
| 267 | |
| 268 | gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, |
| 269 | (MMD_DATA << MMD_CMD_S) | |
| 270 | ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); |
| 271 | |
| 272 | gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, val); |
| 273 | |
| 274 | mutex_unlock(&gsw->host_bus->mdio_lock); |
| 275 | } |
| 276 | |
| 277 | static void mt7530_core_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val) |
| 278 | { |
| 279 | gsw->mmd_write(gsw, 0, 0x1f, reg, val); |
| 280 | } |
| 281 | |
| 282 | static void mt7530_trgmii_setting(struct gsw_mt753x *gsw) |
| 283 | { |
| 284 | u16 i; |
| 285 | |
| 286 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0780); |
| 287 | mdelay(1); |
| 288 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); |
| 289 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87); |
| 290 | mdelay(1); |
| 291 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87); |
| 292 | |
| 293 | /* PLL BIAS enable */ |
| 294 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, |
| 295 | RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN); |
| 296 | mdelay(1); |
| 297 | |
| 298 | /* PLL LPF enable */ |
| 299 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, |
| 300 | RG_SYSPLL_DDSFBK_EN | |
| 301 | RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN); |
| 302 | |
| 303 | /* sys PLL enable */ |
| 304 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP2, |
| 305 | RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN | |
| 306 | (1 << RG_SYSPLL_POSDIV_S)); |
| 307 | |
| 308 | /* LCDDDS PWDS */ |
| 309 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP7, |
| 310 | (3 << RG_LCCDS_C_S) | |
| 311 | RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); |
| 312 | mdelay(1); |
| 313 | |
| 314 | /* Enable MT7530 TRGMII clock */ |
| 315 | mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN | TRGMIICK_EN); |
| 316 | |
| 317 | /* lower Tx Driving */ |
| 318 | for (i = 0 ; i < NUM_TRGMII_ODT; i++) |
| 319 | mt753x_reg_write(gsw, TRGMII_TD_ODT(i), |
| 320 | (4 << TX_DM_DRVP_S) | (4 << TX_DM_DRVN_S)); |
| 321 | } |
| 322 | |
| 323 | static void mt7530_rgmii_setting(struct gsw_mt753x *gsw) |
| 324 | { |
| 325 | u32 val; |
| 326 | |
| 327 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0c80); |
| 328 | mdelay(1); |
| 329 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); |
| 330 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87); |
| 331 | mdelay(1); |
| 332 | mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87); |
| 333 | |
| 334 | val = mt753x_reg_read(gsw, TRGMII_TXCTRL); |
| 335 | val &= ~TXC_INV; |
| 336 | mt753x_reg_write(gsw, TRGMII_TXCTRL, val); |
| 337 | |
| 338 | mt753x_reg_write(gsw, TRGMII_TCK_CTRL, |
| 339 | (8 << TX_TAP_S) | (0x55 << TX_TRAIN_WD_S)); |
| 340 | } |
| 341 | |
| 342 | static int mt7530_mac_port_setup(struct gsw_mt753x *gsw) |
| 343 | { |
| 344 | u32 hwstrap, p6ecr = 0, p5mcr, p6mcr, phyad; |
| 345 | |
| 346 | hwstrap = mt753x_reg_read(gsw, MHWSTRAP); |
| 347 | hwstrap &= ~(P6_INTF_DIS | P5_INTF_MODE_RGMII | P5_INTF_DIS_S); |
| 348 | hwstrap |= P5_INTF_SEL_GMAC5; |
| 349 | if (!gsw->port5_cfg.enabled) { |
| 350 | p5mcr = FORCE_MODE; |
| 351 | hwstrap |= P5_INTF_DIS_S; |
| 352 | } else { |
| 353 | p5mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | |
| 354 | MAC_MODE | MAC_TX_EN | MAC_RX_EN | |
| 355 | BKOFF_EN | BACKPR_EN; |
| 356 | |
| 357 | if (gsw->port5_cfg.force_link) { |
| 358 | p5mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC | |
| 359 | FORCE_TX_FC; |
| 360 | p5mcr |= gsw->port5_cfg.speed << FORCE_SPD_S; |
| 361 | |
| 362 | if (gsw->port5_cfg.duplex) |
| 363 | p5mcr |= FORCE_DPX; |
| 364 | } |
| 365 | |
| 366 | switch (gsw->port5_cfg.phy_mode) { |
| 367 | case PHY_INTERFACE_MODE_MII: |
| 368 | case PHY_INTERFACE_MODE_GMII: |
| 369 | break; |
| 370 | case PHY_INTERFACE_MODE_RGMII: |
| 371 | hwstrap |= P5_INTF_MODE_RGMII; |
| 372 | break; |
| 373 | default: |
| 374 | dev_info(gsw->dev, "%s is not supported by port5\n", |
| 375 | phy_modes(gsw->port5_cfg.phy_mode)); |
| 376 | p5mcr = FORCE_MODE; |
| 377 | hwstrap |= P5_INTF_DIS_S; |
| 378 | } |
| 379 | |
| 380 | /* Port5 to PHY direct mode */ |
| 381 | if (of_property_read_u32(gsw->port5_cfg.np, "phy-address", |
| 382 | &phyad)) |
| 383 | goto parse_p6; |
| 384 | |
| 385 | if (phyad != 0 && phyad != 4) { |
| 386 | dev_info(gsw->dev, |
| 387 | "Only PHY 0/4 can be connected to Port 5\n"); |
| 388 | goto parse_p6; |
| 389 | } |
| 390 | |
| 391 | hwstrap &= ~P5_INTF_SEL_GMAC5; |
| 392 | if (phyad == 0) |
| 393 | hwstrap |= P5_PHY0_SEL; |
| 394 | else |
| 395 | hwstrap &= ~P5_PHY0_SEL; |
| 396 | } |
| 397 | |
| 398 | parse_p6: |
| 399 | if (!gsw->port6_cfg.enabled) { |
| 400 | p6mcr = FORCE_MODE; |
| 401 | hwstrap |= P6_INTF_DIS; |
| 402 | } else { |
| 403 | p6mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | |
| 404 | MAC_MODE | MAC_TX_EN | MAC_RX_EN | |
| 405 | BKOFF_EN | BACKPR_EN; |
| 406 | |
| 407 | if (gsw->port6_cfg.force_link) { |
| 408 | p6mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC | |
| 409 | FORCE_TX_FC; |
| 410 | p6mcr |= gsw->port6_cfg.speed << FORCE_SPD_S; |
| 411 | |
| 412 | if (gsw->port6_cfg.duplex) |
| 413 | p6mcr |= FORCE_DPX; |
| 414 | } |
| 415 | |
| 416 | switch (gsw->port6_cfg.phy_mode) { |
| 417 | case PHY_INTERFACE_MODE_RGMII: |
| 418 | p6ecr = BIT(1); |
| 419 | break; |
| 420 | case PHY_INTERFACE_MODE_TRGMII: |
| 421 | /* set MT7530 central align */ |
| 422 | p6ecr = BIT(0); |
| 423 | break; |
| 424 | default: |
| 425 | dev_info(gsw->dev, "%s is not supported by port6\n", |
| 426 | phy_modes(gsw->port6_cfg.phy_mode)); |
| 427 | p6mcr = FORCE_MODE; |
| 428 | hwstrap |= P6_INTF_DIS; |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | mt753x_reg_write(gsw, MHWSTRAP, hwstrap); |
| 433 | mt753x_reg_write(gsw, P6ECR, p6ecr); |
| 434 | |
| 435 | mt753x_reg_write(gsw, PMCR(5), p5mcr); |
| 436 | mt753x_reg_write(gsw, PMCR(6), p6mcr); |
| 437 | |
| 438 | return 0; |
| 439 | } |
| 440 | |
| 441 | static void mt7530_core_pll_setup(struct gsw_mt753x *gsw) |
| 442 | { |
| 443 | u32 hwstrap; |
| 444 | |
| 445 | hwstrap = mt753x_reg_read(gsw, HWSTRAP); |
| 446 | |
| 447 | switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) { |
| 448 | case XTAL_40MHZ: |
| 449 | /* Disable MT7530 core clock */ |
| 450 | mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, 0); |
| 451 | |
| 452 | /* disable MT7530 PLL */ |
| 453 | mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1, |
| 454 | (2 << GSWPLL_POSTDIV_200M_S) | |
| 455 | (32 << GSWPLL_FBKDIV_200M_S)); |
| 456 | |
| 457 | /* For MT7530 core clock = 500Mhz */ |
| 458 | mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_2, |
| 459 | (1 << GSWPLL_POSTDIV_500M_S) | |
| 460 | (25 << GSWPLL_FBKDIV_500M_S)); |
| 461 | |
| 462 | /* Enable MT7530 PLL */ |
| 463 | mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1, |
| 464 | (2 << GSWPLL_POSTDIV_200M_S) | |
| 465 | (32 << GSWPLL_FBKDIV_200M_S) | |
| 466 | GSWPLL_EN_PRE); |
| 467 | |
| 468 | usleep_range(20, 40); |
| 469 | |
| 470 | /* Enable MT7530 core clock */ |
| 471 | mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN); |
| 472 | break; |
| 473 | default: |
| 474 | /* TODO: PLL settings for 20/25MHz */ |
| 475 | break; |
| 476 | } |
| 477 | |
| 478 | hwstrap = mt753x_reg_read(gsw, HWSTRAP); |
| 479 | hwstrap |= CHG_TRAP; |
| 480 | if (gsw->direct_phy_access) |
| 481 | hwstrap &= ~C_MDIO_BPS_S; |
| 482 | else |
| 483 | hwstrap |= C_MDIO_BPS_S; |
| 484 | |
| 485 | mt753x_reg_write(gsw, MHWSTRAP, hwstrap); |
| 486 | |
| 487 | if (gsw->port6_cfg.enabled && |
| 488 | gsw->port6_cfg.phy_mode == PHY_INTERFACE_MODE_TRGMII) { |
| 489 | mt7530_trgmii_setting(gsw); |
| 490 | } else { |
| 491 | /* RGMII */ |
| 492 | mt7530_rgmii_setting(gsw); |
| 493 | } |
| 494 | |
| 495 | /* delay setting for 10/1000M */ |
| 496 | mt753x_reg_write(gsw, P5RGMIIRXCR, |
| 497 | CSR_RGMII_EDGE_ALIGN | |
| 498 | (2 << CSR_RGMII_RXC_0DEG_CFG_S)); |
| 499 | mt753x_reg_write(gsw, P5RGMIITXCR, 0x14 << CSR_RGMII_TXC_CFG_S); |
| 500 | } |
| 501 | |
| 502 | static int mt7530_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev) |
| 503 | { |
| 504 | u32 rev; |
| 505 | |
| 506 | rev = mt753x_reg_read(gsw, CHIP_REV); |
| 507 | |
| 508 | if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7530) { |
| 509 | if (crev) { |
| 510 | crev->rev = rev & CHIP_REV_M; |
| 511 | crev->name = "MT7530"; |
| 512 | } |
| 513 | |
| 514 | return 0; |
| 515 | } |
| 516 | |
| 517 | return -ENODEV; |
| 518 | } |
| 519 | |
| 520 | static void mt7530_phy_setting(struct gsw_mt753x *gsw) |
| 521 | { |
| 522 | int i; |
| 523 | u32 val; |
| 524 | |
| 525 | for (i = 0; i < MT753X_NUM_PHYS; i++) { |
| 526 | /* Disable EEE */ |
| 527 | gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0); |
| 528 | |
| 529 | /* Enable HW auto downshift */ |
| 530 | gsw->mii_write(gsw, i, 0x1f, 0x1); |
| 531 | val = gsw->mii_read(gsw, i, PHY_EXT_REG_14); |
| 532 | val |= PHY_EN_DOWN_SHFIT; |
| 533 | gsw->mii_write(gsw, i, PHY_EXT_REG_14, val); |
| 534 | |
| 535 | /* Increase SlvDPSready time */ |
| 536 | gsw->mii_write(gsw, i, 0x1f, 0x52b5); |
| 537 | gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae); |
| 538 | gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f); |
| 539 | gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae); |
| 540 | |
| 541 | /* Increase post_update_timer */ |
| 542 | gsw->mii_write(gsw, i, 0x1f, 0x3); |
| 543 | gsw->mii_write(gsw, i, PHY_LPI_REG_11, 0x4b); |
| 544 | gsw->mii_write(gsw, i, 0x1f, 0); |
| 545 | |
| 546 | /* Adjust 100_mse_threshold */ |
| 547 | gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff); |
| 548 | |
| 549 | /* Disable mcc */ |
| 550 | gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300); |
| 551 | } |
| 552 | } |
| 553 | |
| 554 | static inline bool get_phy_access_mode(const struct device_node *np) |
| 555 | { |
| 556 | return of_property_read_bool(np, "mt7530,direct-phy-access"); |
| 557 | } |
| 558 | |
| 559 | static int mt7530_sw_init(struct gsw_mt753x *gsw) |
| 560 | { |
| 561 | int i; |
| 562 | u32 val; |
| 563 | |
| 564 | gsw->direct_phy_access = get_phy_access_mode(gsw->dev->of_node); |
| 565 | |
| 566 | /* Force MT7530 to use (in)direct PHY access */ |
| 567 | val = mt753x_reg_read(gsw, HWSTRAP); |
| 568 | val |= CHG_TRAP; |
| 569 | if (gsw->direct_phy_access) |
| 570 | val &= ~C_MDIO_BPS_S; |
| 571 | else |
| 572 | val |= C_MDIO_BPS_S; |
| 573 | mt753x_reg_write(gsw, MHWSTRAP, val); |
| 574 | |
| 575 | /* Read PHY address base from HWSTRAP */ |
| 576 | gsw->phy_base = (((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3) + 8; |
| 577 | gsw->phy_base &= MT753X_SMI_ADDR_MASK; |
| 578 | |
| 579 | if (gsw->direct_phy_access) { |
| 580 | gsw->mii_read = mt7530_mii_read; |
| 581 | gsw->mii_write = mt7530_mii_write; |
| 582 | gsw->mmd_read = mt7530_mmd_read; |
| 583 | gsw->mmd_write = mt7530_mmd_write; |
| 584 | } else { |
| 585 | gsw->mii_read = mt753x_mii_read; |
| 586 | gsw->mii_write = mt753x_mii_write; |
| 587 | gsw->mmd_read = mt753x_mmd_ind_read; |
| 588 | gsw->mmd_write = mt753x_mmd_ind_write; |
| 589 | } |
| 590 | |
| 591 | for (i = 0; i < MT753X_NUM_PHYS; i++) { |
| 592 | val = gsw->mii_read(gsw, i, MII_BMCR); |
| 593 | val |= BMCR_PDOWN; |
| 594 | gsw->mii_write(gsw, i, MII_BMCR, val); |
| 595 | } |
| 596 | |
| 597 | /* Force MAC link down before reset */ |
| 598 | mt753x_reg_write(gsw, PMCR(5), FORCE_MODE); |
| 599 | mt753x_reg_write(gsw, PMCR(6), FORCE_MODE); |
| 600 | |
| 601 | /* Switch soft reset */ |
| 602 | /* BUG: sw reset causes gsw int flooding */ |
| 603 | mt753x_reg_write(gsw, SYS_CTRL, SW_PHY_RST | SW_SYS_RST | SW_REG_RST); |
| 604 | usleep_range(10, 20); |
| 605 | |
| 606 | /* global mac control settings configuration */ |
| 607 | mt753x_reg_write(gsw, GMACCR, |
| 608 | LATE_COL_DROP | (15 << MTCC_LMT_S) | |
| 609 | (2 << MAX_RX_JUMBO_S) | RX_PKT_LEN_MAX_JUMBO); |
| 610 | |
| 611 | /* Output INTR selected */ |
| 612 | val = mt753x_reg_read(gsw, TOP_SIG_CTRL); |
| 613 | val &= ~OUTPUT_INTR_M; |
| 614 | val |= (3 << OUTPUT_INTR_S); |
| 615 | mt753x_reg_write(gsw, TOP_SIG_CTRL, val); |
| 616 | |
| 617 | mt7530_core_pll_setup(gsw); |
| 618 | mt7530_mac_port_setup(gsw); |
| 619 | |
| 620 | return 0; |
| 621 | } |
| 622 | |
| 623 | static int mt7530_sw_post_init(struct gsw_mt753x *gsw) |
| 624 | { |
| 625 | int i; |
| 626 | u32 val; |
| 627 | |
| 628 | mt7530_phy_setting(gsw); |
| 629 | |
| 630 | for (i = 0; i < MT753X_NUM_PHYS; i++) { |
| 631 | val = gsw->mii_read(gsw, i, MII_BMCR); |
| 632 | val &= ~BMCR_PDOWN; |
| 633 | gsw->mii_write(gsw, i, MII_BMCR, val); |
| 634 | } |
| 635 | |
| 636 | return 0; |
| 637 | } |
| 638 | |
| 639 | struct mt753x_sw_id mt7530_id = { |
| 640 | .model = MT7530, |
| 641 | .detect = mt7530_sw_detect, |
| 642 | .init = mt7530_sw_init, |
| 643 | .post_init = mt7530_sw_post_init |
| 644 | }; |