root/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. emac_sgmii_init
  2. emac_sgmii_open
  3. emac_sgmii_close
  4. emac_sgmii_link_change
  5. emac_sgmii_reset
  6. emac_sgmii_link_init
  7. emac_sgmii_irq_clear
  8. emac_sgmii_interrupt
  9. emac_sgmii_reset_prepare
  10. emac_sgmii_common_reset
  11. emac_sgmii_common_open
  12. emac_sgmii_common_close
  13. emac_sgmii_common_link_change
  14. emac_sgmii_acpi_match
  15. emac_sgmii_config

   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 
  48 int 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 
  56 int 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 
  64 void 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 
  72 int 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 
  80 void 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. */
  89 static 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 
 103 static 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 
 139 static 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 
 179 static 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 
 198 static 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 
 212 static 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 
 236 static 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 */
 246 static 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 
 268 static 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 
 276 static 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
 285 static 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 
 294 static 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 
 337 static 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 
 349 int 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 
 435 error:
 436         if (phy->digital)
 437                 iounmap(phy->digital);
 438 error_unmap_base:
 439         iounmap(phy->base);
 440 error_put_device:
 441         put_device(&sgmii_pdev->dev);
 442 
 443         return ret;
 444 }

/* [<][>][^][v][top][bottom][index][help] */