emac-sgmii.c (10978B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. 3 */ 4 5/* Qualcomm Technologies, Inc. EMAC SGMII Controller driver. 6 */ 7 8#include <linux/interrupt.h> 9#include <linux/iopoll.h> 10#include <linux/acpi.h> 11#include <linux/of_device.h> 12#include "emac.h" 13#include "emac-mac.h" 14#include "emac-sgmii.h" 15 16/* EMAC_SGMII register offsets */ 17#define EMAC_SGMII_PHY_AUTONEG_CFG2 0x0048 18#define EMAC_SGMII_PHY_SPEED_CFG1 0x0074 19#define EMAC_SGMII_PHY_IRQ_CMD 0x00ac 20#define EMAC_SGMII_PHY_INTERRUPT_CLEAR 0x00b0 21#define EMAC_SGMII_PHY_INTERRUPT_MASK 0x00b4 22#define EMAC_SGMII_PHY_INTERRUPT_STATUS 0x00b8 23#define EMAC_SGMII_PHY_RX_CHK_STATUS 0x00d4 24 25#define FORCE_AN_TX_CFG BIT(5) 26#define FORCE_AN_RX_CFG BIT(4) 27#define AN_ENABLE BIT(0) 28 29#define DUPLEX_MODE BIT(4) 30#define SPDMODE_1000 BIT(1) 31#define SPDMODE_100 BIT(0) 32#define SPDMODE_10 0 33 34#define CDR_ALIGN_DET BIT(6) 35 36#define IRQ_GLOBAL_CLEAR BIT(0) 37 38#define DECODE_CODE_ERR BIT(7) 39#define DECODE_DISP_ERR BIT(6) 40 41#define SGMII_PHY_IRQ_CLR_WAIT_TIME 10 42 43#define SGMII_PHY_INTERRUPT_ERR (DECODE_CODE_ERR | DECODE_DISP_ERR) 44#define SGMII_ISR_MASK (SGMII_PHY_INTERRUPT_ERR) 45 46#define SERDES_START_WAIT_TIMES 100 47 48int emac_sgmii_init(struct emac_adapter *adpt) 49{ 50 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->init)) 51 return 0; 52 53 return adpt->phy.sgmii_ops->init(adpt); 54} 55 56int emac_sgmii_open(struct emac_adapter *adpt) 57{ 58 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->open)) 59 return 0; 60 61 return adpt->phy.sgmii_ops->open(adpt); 62} 63 64void emac_sgmii_close(struct emac_adapter *adpt) 65{ 66 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->close)) 67 return; 68 69 adpt->phy.sgmii_ops->close(adpt); 70} 71 72int emac_sgmii_link_change(struct emac_adapter *adpt, bool link_state) 73{ 74 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->link_change)) 75 return 0; 76 77 return adpt->phy.sgmii_ops->link_change(adpt, link_state); 78} 79 80void emac_sgmii_reset(struct emac_adapter *adpt) 81{ 82 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->reset)) 83 return; 84 85 adpt->phy.sgmii_ops->reset(adpt); 86} 87 88/* Initialize the SGMII link between the internal and external PHYs. */ 89static void emac_sgmii_link_init(struct emac_adapter *adpt) 90{ 91 struct emac_sgmii *phy = &adpt->phy; 92 u32 val; 93 94 /* Always use autonegotiation. It works no matter how the external 95 * PHY is configured. 96 */ 97 val = readl(phy->base + EMAC_SGMII_PHY_AUTONEG_CFG2); 98 val &= ~(FORCE_AN_RX_CFG | FORCE_AN_TX_CFG); 99 val |= AN_ENABLE; 100 writel(val, phy->base + EMAC_SGMII_PHY_AUTONEG_CFG2); 101} 102 103static int emac_sgmii_irq_clear(struct emac_adapter *adpt, u8 irq_bits) 104{ 105 struct emac_sgmii *phy = &adpt->phy; 106 u8 status; 107 108 writel_relaxed(irq_bits, phy->base + EMAC_SGMII_PHY_INTERRUPT_CLEAR); 109 writel_relaxed(IRQ_GLOBAL_CLEAR, phy->base + EMAC_SGMII_PHY_IRQ_CMD); 110 /* Ensure interrupt clear command is written to HW */ 111 wmb(); 112 113 /* After set the IRQ_GLOBAL_CLEAR bit, the status clearing must 114 * be confirmed before clearing the bits in other registers. 115 * It takes a few cycles for hw to clear the interrupt status. 116 */ 117 if (readl_poll_timeout_atomic(phy->base + 118 EMAC_SGMII_PHY_INTERRUPT_STATUS, 119 status, !(status & irq_bits), 1, 120 SGMII_PHY_IRQ_CLR_WAIT_TIME)) { 121 net_err_ratelimited("%s: failed to clear SGMII irq: status:0x%x bits:0x%x\n", 122 adpt->netdev->name, status, irq_bits); 123 return -EIO; 124 } 125 126 /* Finalize clearing procedure */ 127 writel_relaxed(0, phy->base + EMAC_SGMII_PHY_IRQ_CMD); 128 writel_relaxed(0, phy->base + EMAC_SGMII_PHY_INTERRUPT_CLEAR); 129 130 /* Ensure that clearing procedure finalization is written to HW */ 131 wmb(); 132 133 return 0; 134} 135 136/* The number of decode errors that triggers a reset */ 137#define DECODE_ERROR_LIMIT 2 138 139static irqreturn_t emac_sgmii_interrupt(int irq, void *data) 140{ 141 struct emac_adapter *adpt = data; 142 struct emac_sgmii *phy = &adpt->phy; 143 u8 status; 144 145 status = readl(phy->base + EMAC_SGMII_PHY_INTERRUPT_STATUS); 146 status &= SGMII_ISR_MASK; 147 if (!status) 148 return IRQ_HANDLED; 149 150 /* If we get a decoding error and CDR is not locked, then try 151 * resetting the internal PHY. The internal PHY uses an embedded 152 * clock with Clock and Data Recovery (CDR) to recover the 153 * clock and data. 154 */ 155 if (status & SGMII_PHY_INTERRUPT_ERR) { 156 int count; 157 158 /* The SGMII is capable of recovering from some decode 159 * errors automatically. However, if we get multiple 160 * decode errors in a row, then assume that something 161 * is wrong and reset the interface. 162 */ 163 count = atomic_inc_return(&phy->decode_error_count); 164 if (count == DECODE_ERROR_LIMIT) { 165 schedule_work(&adpt->work_thread); 166 atomic_set(&phy->decode_error_count, 0); 167 } 168 } else { 169 /* We only care about consecutive decode errors. */ 170 atomic_set(&phy->decode_error_count, 0); 171 } 172 173 if (emac_sgmii_irq_clear(adpt, status)) 174 schedule_work(&adpt->work_thread); 175 176 return IRQ_HANDLED; 177} 178 179static void emac_sgmii_reset_prepare(struct emac_adapter *adpt) 180{ 181 struct emac_sgmii *phy = &adpt->phy; 182 u32 val; 183 184 /* Reset PHY */ 185 val = readl(phy->base + EMAC_EMAC_WRAPPER_CSR2); 186 writel(((val & ~PHY_RESET) | PHY_RESET), phy->base + 187 EMAC_EMAC_WRAPPER_CSR2); 188 /* Ensure phy-reset command is written to HW before the release cmd */ 189 msleep(50); 190 val = readl(phy->base + EMAC_EMAC_WRAPPER_CSR2); 191 writel((val & ~PHY_RESET), phy->base + EMAC_EMAC_WRAPPER_CSR2); 192 /* Ensure phy-reset release command is written to HW before initializing 193 * SGMII 194 */ 195 msleep(50); 196} 197 198static void emac_sgmii_common_reset(struct emac_adapter *adpt) 199{ 200 int ret; 201 202 emac_sgmii_reset_prepare(adpt); 203 emac_sgmii_link_init(adpt); 204 205 ret = emac_sgmii_init(adpt); 206 if (ret) 207 netdev_err(adpt->netdev, 208 "could not reinitialize internal PHY (error=%i)\n", 209 ret); 210} 211 212static int emac_sgmii_common_open(struct emac_adapter *adpt) 213{ 214 struct emac_sgmii *sgmii = &adpt->phy; 215 int ret; 216 217 if (sgmii->irq) { 218 /* Make sure interrupts are cleared and disabled first */ 219 ret = emac_sgmii_irq_clear(adpt, 0xff); 220 if (ret) 221 return ret; 222 writel(0, sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK); 223 224 ret = request_irq(sgmii->irq, emac_sgmii_interrupt, 0, 225 "emac-sgmii", adpt); 226 if (ret) { 227 netdev_err(adpt->netdev, 228 "could not register handler for internal PHY\n"); 229 return ret; 230 } 231 } 232 233 return 0; 234} 235 236static void emac_sgmii_common_close(struct emac_adapter *adpt) 237{ 238 struct emac_sgmii *sgmii = &adpt->phy; 239 240 /* Make sure interrupts are disabled */ 241 writel(0, sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK); 242 free_irq(sgmii->irq, adpt); 243} 244 245/* The error interrupts are only valid after the link is up */ 246static int emac_sgmii_common_link_change(struct emac_adapter *adpt, bool linkup) 247{ 248 struct emac_sgmii *sgmii = &adpt->phy; 249 int ret; 250 251 if (linkup) { 252 /* Clear and enable interrupts */ 253 ret = emac_sgmii_irq_clear(adpt, 0xff); 254 if (ret) 255 return ret; 256 257 writel(SGMII_ISR_MASK, 258 sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK); 259 } else { 260 /* Disable interrupts */ 261 writel(0, sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK); 262 synchronize_irq(sgmii->irq); 263 } 264 265 return 0; 266} 267 268static struct sgmii_ops fsm9900_ops = { 269 .init = emac_sgmii_init_fsm9900, 270 .open = emac_sgmii_common_open, 271 .close = emac_sgmii_common_close, 272 .link_change = emac_sgmii_common_link_change, 273 .reset = emac_sgmii_common_reset, 274}; 275 276static struct sgmii_ops qdf2432_ops = { 277 .init = emac_sgmii_init_qdf2432, 278 .open = emac_sgmii_common_open, 279 .close = emac_sgmii_common_close, 280 .link_change = emac_sgmii_common_link_change, 281 .reset = emac_sgmii_common_reset, 282}; 283 284#ifdef CONFIG_ACPI 285static struct sgmii_ops qdf2400_ops = { 286 .init = emac_sgmii_init_qdf2400, 287 .open = emac_sgmii_common_open, 288 .close = emac_sgmii_common_close, 289 .link_change = emac_sgmii_common_link_change, 290 .reset = emac_sgmii_common_reset, 291}; 292#endif 293 294static int emac_sgmii_acpi_match(struct device *dev, void *data) 295{ 296#ifdef CONFIG_ACPI 297 static const struct acpi_device_id match_table[] = { 298 { 299 .id = "QCOM8071", 300 }, 301 {} 302 }; 303 const struct acpi_device_id *id = acpi_match_device(match_table, dev); 304 struct sgmii_ops **ops = data; 305 306 if (id) { 307 acpi_handle handle = ACPI_HANDLE(dev); 308 unsigned long long hrv; 309 acpi_status status; 310 311 status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv); 312 if (status) { 313 if (status == AE_NOT_FOUND) 314 /* Older versions of the QDF2432 ACPI tables do 315 * not have an _HRV property. 316 */ 317 hrv = 1; 318 else 319 /* Something is wrong with the tables */ 320 return 0; 321 } 322 323 switch (hrv) { 324 case 1: 325 *ops = &qdf2432_ops; 326 return 1; 327 case 2: 328 *ops = &qdf2400_ops; 329 return 1; 330 } 331 } 332#endif 333 334 return 0; 335} 336 337static const struct of_device_id emac_sgmii_dt_match[] = { 338 { 339 .compatible = "qcom,fsm9900-emac-sgmii", 340 .data = &fsm9900_ops, 341 }, 342 { 343 .compatible = "qcom,qdf2432-emac-sgmii", 344 .data = &qdf2432_ops, 345 }, 346 {} 347}; 348 349int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt) 350{ 351 struct platform_device *sgmii_pdev = NULL; 352 struct emac_sgmii *phy = &adpt->phy; 353 struct resource *res; 354 int ret; 355 356 if (has_acpi_companion(&pdev->dev)) { 357 struct device *dev; 358 359 dev = device_find_child(&pdev->dev, &phy->sgmii_ops, 360 emac_sgmii_acpi_match); 361 362 if (!dev) { 363 dev_warn(&pdev->dev, "cannot find internal phy node\n"); 364 return 0; 365 } 366 367 sgmii_pdev = to_platform_device(dev); 368 } else { 369 const struct of_device_id *match; 370 struct device_node *np; 371 372 np = of_parse_phandle(pdev->dev.of_node, "internal-phy", 0); 373 if (!np) { 374 dev_err(&pdev->dev, "missing internal-phy property\n"); 375 return -ENODEV; 376 } 377 378 sgmii_pdev = of_find_device_by_node(np); 379 of_node_put(np); 380 if (!sgmii_pdev) { 381 dev_err(&pdev->dev, "invalid internal-phy property\n"); 382 return -ENODEV; 383 } 384 385 match = of_match_device(emac_sgmii_dt_match, &sgmii_pdev->dev); 386 if (!match) { 387 dev_err(&pdev->dev, "unrecognized internal phy node\n"); 388 ret = -ENODEV; 389 goto error_put_device; 390 } 391 392 phy->sgmii_ops = (struct sgmii_ops *)match->data; 393 } 394 395 /* Base address is the first address */ 396 res = platform_get_resource(sgmii_pdev, IORESOURCE_MEM, 0); 397 if (!res) { 398 ret = -EINVAL; 399 goto error_put_device; 400 } 401 402 phy->base = ioremap(res->start, resource_size(res)); 403 if (!phy->base) { 404 ret = -ENOMEM; 405 goto error_put_device; 406 } 407 408 /* v2 SGMII has a per-lane digital digital, so parse it if it exists */ 409 res = platform_get_resource(sgmii_pdev, IORESOURCE_MEM, 1); 410 if (res) { 411 phy->digital = ioremap(res->start, resource_size(res)); 412 if (!phy->digital) { 413 ret = -ENOMEM; 414 goto error_unmap_base; 415 } 416 } 417 418 ret = emac_sgmii_init(adpt); 419 if (ret) 420 goto error; 421 422 emac_sgmii_link_init(adpt); 423 424 ret = platform_get_irq(sgmii_pdev, 0); 425 if (ret > 0) 426 phy->irq = ret; 427 428 /* We've remapped the addresses, so we don't need the device any 429 * more. of_find_device_by_node() says we should release it. 430 */ 431 put_device(&sgmii_pdev->dev); 432 433 return 0; 434 435error: 436 if (phy->digital) 437 iounmap(phy->digital); 438error_unmap_base: 439 iounmap(phy->base); 440error_put_device: 441 put_device(&sgmii_pdev->dev); 442 443 return ret; 444}