linux/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c
<<
>>
Prefs
   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}
 445