1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2018-2019 MediaTek Inc. 3 /* A library for MediaTek SGMII circuit 4 * 5 * Author: Sean Wang <sean.wang@mediatek.com> 6 * Author: Alexander Couzens <lynxis@fe80.eu> 7 * Author: Daniel Golle <daniel@makrotopia.org> 8 * 9 */ 10 11 #include <linux/mdio.h> 12 #include <linux/of.h> 13 #include <linux/pcs/pcs-mtk-lynxi.h> 14 #include <linux/phy/phy-common-props.h> 15 #include <linux/phylink.h> 16 #include <linux/regmap.h> 17 18 /* SGMII subsystem config registers */ 19 /* BMCR (low 16) BMSR (high 16) */ 20 #define SGMSYS_PCS_CONTROL_1 0x0 21 #define SGMII_BMCR GENMASK(15, 0) 22 #define SGMII_BMSR GENMASK(31, 16) 23 24 #define SGMSYS_PCS_DEVICE_ID 0x4 25 #define SGMII_LYNXI_DEV_ID 0x4d544950 26 27 #define SGMSYS_PCS_ADVERTISE 0x8 28 #define SGMII_ADVERTISE GENMASK(15, 0) 29 #define SGMII_LPA GENMASK(31, 16) 30 31 #define SGMSYS_PCS_SCRATCH 0x14 32 #define SGMII_DEV_VERSION GENMASK(31, 16) 33 34 /* Register to programmable link timer, the unit in 2 * 8ns */ 35 #define SGMSYS_PCS_LINK_TIMER 0x18 36 #define SGMII_LINK_TIMER_MASK GENMASK(19, 0) 37 #define SGMII_LINK_TIMER_VAL(ns) FIELD_PREP(SGMII_LINK_TIMER_MASK, \ 38 ((ns) / 2 / 8)) 39 40 /* Register to control remote fault */ 41 #define SGMSYS_SGMII_MODE 0x20 42 #define SGMII_IF_MODE_SGMII BIT(0) 43 #define SGMII_SPEED_DUPLEX_AN BIT(1) 44 #define SGMII_SPEED_MASK GENMASK(3, 2) 45 #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) 46 #define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) 47 #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) 48 #define SGMII_DUPLEX_HALF BIT(4) 49 #define SGMII_REMOTE_FAULT_DIS BIT(8) 50 51 /* Register to reset SGMII design */ 52 #define SGMSYS_RESERVED_0 0x34 53 #define SGMII_SW_RESET BIT(0) 54 55 /* Register to set SGMII speed, ANA RG_ Control Signals III */ 56 #define SGMII_PHY_SPEED_MASK GENMASK(3, 2) 57 #define SGMII_PHY_SPEED_1_25G FIELD_PREP(SGMII_PHY_SPEED_MASK, 0) 58 #define SGMII_PHY_SPEED_3_125G FIELD_PREP(SGMII_PHY_SPEED_MASK, 1) 59 60 /* Register to power up QPHY */ 61 #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 62 #define SGMII_PHYA_PWD BIT(4) 63 64 /* Register to QPHY wrapper control */ 65 #define SGMSYS_QPHY_WRAP_CTRL 0xec 66 #define SGMII_PN_SWAP_RX BIT(1) 67 #define SGMII_PN_SWAP_TX BIT(0) 68 69 70 /* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated 71 * data 72 * @regmap: The register map pointing at the range used to setup 73 * SGMII modes 74 * @dev: Pointer to device owning the PCS 75 * @ana_rgc3: The offset of register ANA_RGC3 relative to regmap 76 * @interface: Currently configured interface mode 77 * @pcs: Phylink PCS structure 78 * @flags: Flags indicating hardware properties 79 */ 80 struct mtk_pcs_lynxi { 81 struct regmap *regmap; 82 u32 ana_rgc3; 83 phy_interface_t interface; 84 struct phylink_pcs pcs; 85 u32 flags; 86 struct fwnode_handle *fwnode; 87 }; 88 89 static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs) 90 { 91 return container_of(pcs, struct mtk_pcs_lynxi, pcs); 92 } 93 94 static unsigned int mtk_pcs_lynxi_inband_caps(struct phylink_pcs *pcs, 95 phy_interface_t interface) 96 { 97 switch (interface) { 98 case PHY_INTERFACE_MODE_1000BASEX: 99 case PHY_INTERFACE_MODE_2500BASEX: 100 case PHY_INTERFACE_MODE_SGMII: 101 return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; 102 103 default: 104 return 0; 105 } 106 } 107 108 static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs, 109 unsigned int neg_mode, 110 struct phylink_link_state *state) 111 { 112 struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); 113 unsigned int bm, adv; 114 115 /* Read the BMSR and LPA */ 116 regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); 117 regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); 118 119 phylink_mii_c22_pcs_decode_state(state, neg_mode, 120 FIELD_GET(SGMII_BMSR, bm), 121 FIELD_GET(SGMII_LPA, adv)); 122 } 123 124 static int mtk_pcs_config_polarity(struct mtk_pcs_lynxi *mpcs, 125 phy_interface_t interface) 126 { 127 struct fwnode_handle *fwnode = mpcs->fwnode, *pcs_fwnode; 128 unsigned int pol, default_pol = PHY_POL_NORMAL; 129 unsigned int val = 0; 130 int ret; 131 132 if (fwnode_property_read_bool(fwnode, "mediatek,pnswap")) 133 default_pol = PHY_POL_INVERT; 134 135 pcs_fwnode = fwnode_get_named_child_node(fwnode, "pcs"); 136 137 ret = phy_get_rx_polarity(pcs_fwnode, phy_modes(interface), 138 BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT), 139 default_pol, &pol); 140 if (ret) { 141 fwnode_handle_put(pcs_fwnode); 142 return ret; 143 } 144 if (pol == PHY_POL_INVERT) 145 val |= SGMII_PN_SWAP_RX; 146 147 ret = phy_get_tx_polarity(pcs_fwnode, phy_modes(interface), 148 BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT), 149 default_pol, &pol); 150 fwnode_handle_put(pcs_fwnode); 151 if (ret) 152 return ret; 153 if (pol == PHY_POL_INVERT) 154 val |= SGMII_PN_SWAP_TX; 155 156 return regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, 157 SGMII_PN_SWAP_RX | SGMII_PN_SWAP_TX, val); 158 } 159 160 static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, 161 phy_interface_t interface, 162 const unsigned long *advertising, 163 bool permit_pause_to_mac) 164 { 165 struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); 166 bool mode_changed = false, changed; 167 unsigned int rgc3, sgm_mode, bmcr; 168 int advertise, link_timer; 169 int ret; 170 171 advertise = phylink_mii_c22_pcs_encode_advertisement(interface, 172 advertising); 173 if (advertise < 0) 174 return advertise; 175 176 /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and 177 * we assume that fixes it's speed at bitrate = line rate (in 178 * other words, 1000Mbps or 2500Mbps). 179 */ 180 if (interface == PHY_INTERFACE_MODE_SGMII) 181 sgm_mode = SGMII_IF_MODE_SGMII; 182 else 183 sgm_mode = 0; 184 185 if (neg_mode & PHYLINK_PCS_NEG_INBAND) 186 sgm_mode |= SGMII_REMOTE_FAULT_DIS; 187 188 if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { 189 if (interface == PHY_INTERFACE_MODE_SGMII) 190 sgm_mode |= SGMII_SPEED_DUPLEX_AN; 191 bmcr = BMCR_ANENABLE; 192 } else { 193 bmcr = 0; 194 } 195 196 if (mpcs->interface != interface) { 197 link_timer = phylink_get_link_timer_ns(interface); 198 if (link_timer < 0) 199 return link_timer; 200 201 /* PHYA power down */ 202 regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 203 SGMII_PHYA_PWD); 204 205 /* Reset SGMII PCS state */ 206 regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0, 207 SGMII_SW_RESET); 208 209 ret = mtk_pcs_config_polarity(mpcs, interface); 210 if (ret) 211 return ret; 212 213 if (interface == PHY_INTERFACE_MODE_2500BASEX) 214 rgc3 = SGMII_PHY_SPEED_3_125G; 215 else 216 rgc3 = SGMII_PHY_SPEED_1_25G; 217 218 /* Configure the underlying interface speed */ 219 regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, 220 SGMII_PHY_SPEED_MASK, rgc3); 221 222 /* Setup the link timer */ 223 regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, 224 SGMII_LINK_TIMER_VAL(link_timer)); 225 226 mpcs->interface = interface; 227 mode_changed = true; 228 } 229 230 /* Update the advertisement, noting whether it has changed */ 231 regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, 232 SGMII_ADVERTISE, advertise, &changed); 233 234 /* Update the sgmsys mode register */ 235 regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, 236 SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | 237 SGMII_IF_MODE_SGMII, sgm_mode); 238 239 /* Update the BMCR */ 240 regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, 241 BMCR_ANENABLE, bmcr); 242 243 /* Release PHYA power down state 244 * Only removing bit SGMII_PHYA_PWD isn't enough. 245 * There are cases when the SGMII_PHYA_PWD register contains 0x9 which 246 * prevents SGMII from working. The SGMII still shows link but no traffic 247 * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was 248 * taken from a good working state of the SGMII interface. 249 * Unknown how much the QPHY needs but it is racy without a sleep. 250 * Tested on mt7622 & mt7986. 251 */ 252 usleep_range(50, 100); 253 regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); 254 255 return changed || mode_changed; 256 } 257 258 static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs) 259 { 260 struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); 261 262 regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART); 263 } 264 265 static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, 266 unsigned int neg_mode, 267 phy_interface_t interface, int speed, 268 int duplex) 269 { 270 struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); 271 unsigned int sgm_mode; 272 273 if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) { 274 /* Force the speed and duplex setting */ 275 if (speed == SPEED_10) 276 sgm_mode = SGMII_SPEED_10; 277 else if (speed == SPEED_100) 278 sgm_mode = SGMII_SPEED_100; 279 else 280 sgm_mode = SGMII_SPEED_1000; 281 282 if (duplex != DUPLEX_FULL) 283 sgm_mode |= SGMII_DUPLEX_HALF; 284 285 regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, 286 SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, 287 sgm_mode); 288 } 289 } 290 291 static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) 292 { 293 struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); 294 295 mpcs->interface = PHY_INTERFACE_MODE_NA; 296 } 297 298 static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { 299 .pcs_inband_caps = mtk_pcs_lynxi_inband_caps, 300 .pcs_get_state = mtk_pcs_lynxi_get_state, 301 .pcs_config = mtk_pcs_lynxi_config, 302 .pcs_an_restart = mtk_pcs_lynxi_restart_an, 303 .pcs_link_up = mtk_pcs_lynxi_link_up, 304 .pcs_disable = mtk_pcs_lynxi_disable, 305 }; 306 307 struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, 308 struct fwnode_handle *fwnode, 309 struct regmap *regmap, u32 ana_rgc3) 310 { 311 struct mtk_pcs_lynxi *mpcs; 312 u32 id, ver; 313 int ret; 314 315 ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id); 316 if (ret < 0) 317 return NULL; 318 319 if (id != SGMII_LYNXI_DEV_ID) { 320 dev_err(dev, "unknown PCS device id %08x\n", id); 321 return NULL; 322 } 323 324 ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver); 325 if (ret < 0) 326 return NULL; 327 328 ver = FIELD_GET(SGMII_DEV_VERSION, ver); 329 if (ver != 0x1) { 330 dev_err(dev, "unknown PCS device version %04x\n", ver); 331 return NULL; 332 } 333 334 dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id, 335 ver); 336 337 mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); 338 if (!mpcs) 339 return NULL; 340 341 mpcs->ana_rgc3 = ana_rgc3; 342 mpcs->regmap = regmap; 343 mpcs->pcs.ops = &mtk_pcs_lynxi_ops; 344 mpcs->pcs.poll = true; 345 mpcs->interface = PHY_INTERFACE_MODE_NA; 346 mpcs->fwnode = fwnode_handle_get(fwnode); 347 348 __set_bit(PHY_INTERFACE_MODE_SGMII, mpcs->pcs.supported_interfaces); 349 __set_bit(PHY_INTERFACE_MODE_1000BASEX, mpcs->pcs.supported_interfaces); 350 __set_bit(PHY_INTERFACE_MODE_2500BASEX, mpcs->pcs.supported_interfaces); 351 352 return &mpcs->pcs; 353 } 354 EXPORT_SYMBOL(mtk_pcs_lynxi_create); 355 356 void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs) 357 { 358 struct mtk_pcs_lynxi *mpcs; 359 360 if (!pcs) 361 return; 362 363 mpcs = pcs_to_mtk_pcs_lynxi(pcs); 364 fwnode_handle_put(mpcs->fwnode); 365 kfree(mpcs); 366 } 367 EXPORT_SYMBOL(mtk_pcs_lynxi_destroy); 368 369 MODULE_DESCRIPTION("MediaTek SGMII library for LynxI"); 370 MODULE_LICENSE("GPL"); 371