linux/drivers/net/dsa/sja1105/sja1105_clocking.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause
   2/* Copyright 2016-2018 NXP
   3 * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
   4 */
   5#include <linux/packing.h>
   6#include "sja1105.h"
   7
   8#define SJA1105_SIZE_CGU_CMD    4
   9#define SJA1110_BASE_MCSS_CLK   SJA1110_CGU_ADDR(0x70)
  10#define SJA1110_BASE_TIMER_CLK  SJA1110_CGU_ADDR(0x74)
  11
  12/* Common structure for CFG_PAD_MIIx_RX and CFG_PAD_MIIx_TX */
  13struct sja1105_cfg_pad_mii {
  14        u64 d32_os;
  15        u64 d32_ih;
  16        u64 d32_ipud;
  17        u64 d10_ih;
  18        u64 d10_os;
  19        u64 d10_ipud;
  20        u64 ctrl_os;
  21        u64 ctrl_ih;
  22        u64 ctrl_ipud;
  23        u64 clk_os;
  24        u64 clk_ih;
  25        u64 clk_ipud;
  26};
  27
  28struct sja1105_cfg_pad_mii_id {
  29        u64 rxc_stable_ovr;
  30        u64 rxc_delay;
  31        u64 rxc_bypass;
  32        u64 rxc_pd;
  33        u64 txc_stable_ovr;
  34        u64 txc_delay;
  35        u64 txc_bypass;
  36        u64 txc_pd;
  37};
  38
  39/* UM10944 Table 82.
  40 * IDIV_0_C to IDIV_4_C control registers
  41 * (addr. 10000Bh to 10000Fh)
  42 */
  43struct sja1105_cgu_idiv {
  44        u64 clksrc;
  45        u64 autoblock;
  46        u64 idiv;
  47        u64 pd;
  48};
  49
  50/* PLL_1_C control register
  51 *
  52 * SJA1105 E/T: UM10944 Table 81 (address 10000Ah)
  53 * SJA1105 P/Q/R/S: UM11040 Table 116 (address 10000Ah)
  54 */
  55struct sja1105_cgu_pll_ctrl {
  56        u64 pllclksrc;
  57        u64 msel;
  58        u64 autoblock;
  59        u64 psel;
  60        u64 direct;
  61        u64 fbsel;
  62        u64 bypass;
  63        u64 pd;
  64};
  65
  66struct sja1110_cgu_outclk {
  67        u64 clksrc;
  68        u64 autoblock;
  69        u64 pd;
  70};
  71
  72enum {
  73        CLKSRC_MII0_TX_CLK      = 0x00,
  74        CLKSRC_MII0_RX_CLK      = 0x01,
  75        CLKSRC_MII1_TX_CLK      = 0x02,
  76        CLKSRC_MII1_RX_CLK      = 0x03,
  77        CLKSRC_MII2_TX_CLK      = 0x04,
  78        CLKSRC_MII2_RX_CLK      = 0x05,
  79        CLKSRC_MII3_TX_CLK      = 0x06,
  80        CLKSRC_MII3_RX_CLK      = 0x07,
  81        CLKSRC_MII4_TX_CLK      = 0x08,
  82        CLKSRC_MII4_RX_CLK      = 0x09,
  83        CLKSRC_PLL0             = 0x0B,
  84        CLKSRC_PLL1             = 0x0E,
  85        CLKSRC_IDIV0            = 0x11,
  86        CLKSRC_IDIV1            = 0x12,
  87        CLKSRC_IDIV2            = 0x13,
  88        CLKSRC_IDIV3            = 0x14,
  89        CLKSRC_IDIV4            = 0x15,
  90};
  91
  92/* UM10944 Table 83.
  93 * MIIx clock control registers 1 to 30
  94 * (addresses 100013h to 100035h)
  95 */
  96struct sja1105_cgu_mii_ctrl {
  97        u64 clksrc;
  98        u64 autoblock;
  99        u64 pd;
 100};
 101
 102static void sja1105_cgu_idiv_packing(void *buf, struct sja1105_cgu_idiv *idiv,
 103                                     enum packing_op op)
 104{
 105        const int size = 4;
 106
 107        sja1105_packing(buf, &idiv->clksrc,    28, 24, size, op);
 108        sja1105_packing(buf, &idiv->autoblock, 11, 11, size, op);
 109        sja1105_packing(buf, &idiv->idiv,       5,  2, size, op);
 110        sja1105_packing(buf, &idiv->pd,         0,  0, size, op);
 111}
 112
 113static int sja1105_cgu_idiv_config(struct sja1105_private *priv, int port,
 114                                   bool enabled, int factor)
 115{
 116        const struct sja1105_regs *regs = priv->info->regs;
 117        struct device *dev = priv->ds->dev;
 118        struct sja1105_cgu_idiv idiv;
 119        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 120
 121        if (regs->cgu_idiv[port] == SJA1105_RSV_ADDR)
 122                return 0;
 123
 124        if (enabled && factor != 1 && factor != 10) {
 125                dev_err(dev, "idiv factor must be 1 or 10\n");
 126                return -ERANGE;
 127        }
 128
 129        /* Payload for packed_buf */
 130        idiv.clksrc    = 0x0A;            /* 25MHz */
 131        idiv.autoblock = 1;               /* Block clk automatically */
 132        idiv.idiv      = factor - 1;      /* Divide by 1 or 10 */
 133        idiv.pd        = enabled ? 0 : 1; /* Power down? */
 134        sja1105_cgu_idiv_packing(packed_buf, &idiv, PACK);
 135
 136        return sja1105_xfer_buf(priv, SPI_WRITE, regs->cgu_idiv[port],
 137                                packed_buf, SJA1105_SIZE_CGU_CMD);
 138}
 139
 140static void
 141sja1105_cgu_mii_control_packing(void *buf, struct sja1105_cgu_mii_ctrl *cmd,
 142                                enum packing_op op)
 143{
 144        const int size = 4;
 145
 146        sja1105_packing(buf, &cmd->clksrc,    28, 24, size, op);
 147        sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
 148        sja1105_packing(buf, &cmd->pd,         0,  0, size, op);
 149}
 150
 151static int sja1105_cgu_mii_tx_clk_config(struct sja1105_private *priv,
 152                                         int port, sja1105_mii_role_t role)
 153{
 154        const struct sja1105_regs *regs = priv->info->regs;
 155        struct sja1105_cgu_mii_ctrl mii_tx_clk;
 156        const int mac_clk_sources[] = {
 157                CLKSRC_MII0_TX_CLK,
 158                CLKSRC_MII1_TX_CLK,
 159                CLKSRC_MII2_TX_CLK,
 160                CLKSRC_MII3_TX_CLK,
 161                CLKSRC_MII4_TX_CLK,
 162        };
 163        const int phy_clk_sources[] = {
 164                CLKSRC_IDIV0,
 165                CLKSRC_IDIV1,
 166                CLKSRC_IDIV2,
 167                CLKSRC_IDIV3,
 168                CLKSRC_IDIV4,
 169        };
 170        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 171        int clksrc;
 172
 173        if (regs->mii_tx_clk[port] == SJA1105_RSV_ADDR)
 174                return 0;
 175
 176        if (role == XMII_MAC)
 177                clksrc = mac_clk_sources[port];
 178        else
 179                clksrc = phy_clk_sources[port];
 180
 181        /* Payload for packed_buf */
 182        mii_tx_clk.clksrc    = clksrc;
 183        mii_tx_clk.autoblock = 1;  /* Autoblock clk while changing clksrc */
 184        mii_tx_clk.pd        = 0;  /* Power Down off => enabled */
 185        sja1105_cgu_mii_control_packing(packed_buf, &mii_tx_clk, PACK);
 186
 187        return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_tx_clk[port],
 188                                packed_buf, SJA1105_SIZE_CGU_CMD);
 189}
 190
 191static int
 192sja1105_cgu_mii_rx_clk_config(struct sja1105_private *priv, int port)
 193{
 194        const struct sja1105_regs *regs = priv->info->regs;
 195        struct sja1105_cgu_mii_ctrl mii_rx_clk;
 196        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 197        const int clk_sources[] = {
 198                CLKSRC_MII0_RX_CLK,
 199                CLKSRC_MII1_RX_CLK,
 200                CLKSRC_MII2_RX_CLK,
 201                CLKSRC_MII3_RX_CLK,
 202                CLKSRC_MII4_RX_CLK,
 203        };
 204
 205        if (regs->mii_rx_clk[port] == SJA1105_RSV_ADDR)
 206                return 0;
 207
 208        /* Payload for packed_buf */
 209        mii_rx_clk.clksrc    = clk_sources[port];
 210        mii_rx_clk.autoblock = 1;  /* Autoblock clk while changing clksrc */
 211        mii_rx_clk.pd        = 0;  /* Power Down off => enabled */
 212        sja1105_cgu_mii_control_packing(packed_buf, &mii_rx_clk, PACK);
 213
 214        return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_rx_clk[port],
 215                                packed_buf, SJA1105_SIZE_CGU_CMD);
 216}
 217
 218static int
 219sja1105_cgu_mii_ext_tx_clk_config(struct sja1105_private *priv, int port)
 220{
 221        const struct sja1105_regs *regs = priv->info->regs;
 222        struct sja1105_cgu_mii_ctrl mii_ext_tx_clk;
 223        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 224        const int clk_sources[] = {
 225                CLKSRC_IDIV0,
 226                CLKSRC_IDIV1,
 227                CLKSRC_IDIV2,
 228                CLKSRC_IDIV3,
 229                CLKSRC_IDIV4,
 230        };
 231
 232        if (regs->mii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
 233                return 0;
 234
 235        /* Payload for packed_buf */
 236        mii_ext_tx_clk.clksrc    = clk_sources[port];
 237        mii_ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
 238        mii_ext_tx_clk.pd        = 0; /* Power Down off => enabled */
 239        sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_tx_clk, PACK);
 240
 241        return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_ext_tx_clk[port],
 242                                packed_buf, SJA1105_SIZE_CGU_CMD);
 243}
 244
 245static int
 246sja1105_cgu_mii_ext_rx_clk_config(struct sja1105_private *priv, int port)
 247{
 248        const struct sja1105_regs *regs = priv->info->regs;
 249        struct sja1105_cgu_mii_ctrl mii_ext_rx_clk;
 250        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 251        const int clk_sources[] = {
 252                CLKSRC_IDIV0,
 253                CLKSRC_IDIV1,
 254                CLKSRC_IDIV2,
 255                CLKSRC_IDIV3,
 256                CLKSRC_IDIV4,
 257        };
 258
 259        if (regs->mii_ext_rx_clk[port] == SJA1105_RSV_ADDR)
 260                return 0;
 261
 262        /* Payload for packed_buf */
 263        mii_ext_rx_clk.clksrc    = clk_sources[port];
 264        mii_ext_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
 265        mii_ext_rx_clk.pd        = 0; /* Power Down off => enabled */
 266        sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_rx_clk, PACK);
 267
 268        return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_ext_rx_clk[port],
 269                                packed_buf, SJA1105_SIZE_CGU_CMD);
 270}
 271
 272static int sja1105_mii_clocking_setup(struct sja1105_private *priv, int port,
 273                                      sja1105_mii_role_t role)
 274{
 275        struct device *dev = priv->ds->dev;
 276        int rc;
 277
 278        dev_dbg(dev, "Configuring MII-%s clocking\n",
 279                (role == XMII_MAC) ? "MAC" : "PHY");
 280        /* If role is MAC, disable IDIV
 281         * If role is PHY, enable IDIV and configure for 1/1 divider
 282         */
 283        rc = sja1105_cgu_idiv_config(priv, port, (role == XMII_PHY), 1);
 284        if (rc < 0)
 285                return rc;
 286
 287        /* Configure CLKSRC of MII_TX_CLK_n
 288         *   * If role is MAC, select TX_CLK_n
 289         *   * If role is PHY, select IDIV_n
 290         */
 291        rc = sja1105_cgu_mii_tx_clk_config(priv, port, role);
 292        if (rc < 0)
 293                return rc;
 294
 295        /* Configure CLKSRC of MII_RX_CLK_n
 296         * Select RX_CLK_n
 297         */
 298        rc = sja1105_cgu_mii_rx_clk_config(priv, port);
 299        if (rc < 0)
 300                return rc;
 301
 302        if (role == XMII_PHY) {
 303                /* Per MII spec, the PHY (which is us) drives the TX_CLK pin */
 304
 305                /* Configure CLKSRC of EXT_TX_CLK_n
 306                 * Select IDIV_n
 307                 */
 308                rc = sja1105_cgu_mii_ext_tx_clk_config(priv, port);
 309                if (rc < 0)
 310                        return rc;
 311
 312                /* Configure CLKSRC of EXT_RX_CLK_n
 313                 * Select IDIV_n
 314                 */
 315                rc = sja1105_cgu_mii_ext_rx_clk_config(priv, port);
 316                if (rc < 0)
 317                        return rc;
 318        }
 319        return 0;
 320}
 321
 322static void
 323sja1105_cgu_pll_control_packing(void *buf, struct sja1105_cgu_pll_ctrl *cmd,
 324                                enum packing_op op)
 325{
 326        const int size = 4;
 327
 328        sja1105_packing(buf, &cmd->pllclksrc, 28, 24, size, op);
 329        sja1105_packing(buf, &cmd->msel,      23, 16, size, op);
 330        sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
 331        sja1105_packing(buf, &cmd->psel,       9,  8, size, op);
 332        sja1105_packing(buf, &cmd->direct,     7,  7, size, op);
 333        sja1105_packing(buf, &cmd->fbsel,      6,  6, size, op);
 334        sja1105_packing(buf, &cmd->bypass,     1,  1, size, op);
 335        sja1105_packing(buf, &cmd->pd,         0,  0, size, op);
 336}
 337
 338static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
 339                                           int port, u64 speed)
 340{
 341        const struct sja1105_regs *regs = priv->info->regs;
 342        struct sja1105_cgu_mii_ctrl txc;
 343        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 344        int clksrc;
 345
 346        if (regs->rgmii_tx_clk[port] == SJA1105_RSV_ADDR)
 347                return 0;
 348
 349        if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
 350                clksrc = CLKSRC_PLL0;
 351        } else {
 352                int clk_sources[] = {CLKSRC_IDIV0, CLKSRC_IDIV1, CLKSRC_IDIV2,
 353                                     CLKSRC_IDIV3, CLKSRC_IDIV4};
 354                clksrc = clk_sources[port];
 355        }
 356
 357        /* RGMII: 125MHz for 1000, 25MHz for 100, 2.5MHz for 10 */
 358        txc.clksrc = clksrc;
 359        /* Autoblock clk while changing clksrc */
 360        txc.autoblock = 1;
 361        /* Power Down off => enabled */
 362        txc.pd = 0;
 363        sja1105_cgu_mii_control_packing(packed_buf, &txc, PACK);
 364
 365        return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgmii_tx_clk[port],
 366                                packed_buf, SJA1105_SIZE_CGU_CMD);
 367}
 368
 369/* AGU */
 370static void
 371sja1105_cfg_pad_mii_packing(void *buf, struct sja1105_cfg_pad_mii *cmd,
 372                            enum packing_op op)
 373{
 374        const int size = 4;
 375
 376        sja1105_packing(buf, &cmd->d32_os,   28, 27, size, op);
 377        sja1105_packing(buf, &cmd->d32_ih,   26, 26, size, op);
 378        sja1105_packing(buf, &cmd->d32_ipud, 25, 24, size, op);
 379        sja1105_packing(buf, &cmd->d10_os,   20, 19, size, op);
 380        sja1105_packing(buf, &cmd->d10_ih,   18, 18, size, op);
 381        sja1105_packing(buf, &cmd->d10_ipud, 17, 16, size, op);
 382        sja1105_packing(buf, &cmd->ctrl_os,  12, 11, size, op);
 383        sja1105_packing(buf, &cmd->ctrl_ih,  10, 10, size, op);
 384        sja1105_packing(buf, &cmd->ctrl_ipud, 9,  8, size, op);
 385        sja1105_packing(buf, &cmd->clk_os,    4,  3, size, op);
 386        sja1105_packing(buf, &cmd->clk_ih,    2,  2, size, op);
 387        sja1105_packing(buf, &cmd->clk_ipud,  1,  0, size, op);
 388}
 389
 390static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
 391                                           int port)
 392{
 393        const struct sja1105_regs *regs = priv->info->regs;
 394        struct sja1105_cfg_pad_mii pad_mii_tx = {0};
 395        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 396
 397        if (regs->pad_mii_tx[port] == SJA1105_RSV_ADDR)
 398                return 0;
 399
 400        /* Payload */
 401        pad_mii_tx.d32_os    = 3; /* TXD[3:2] output stage: */
 402                                  /*          high noise/high speed */
 403        pad_mii_tx.d10_os    = 3; /* TXD[1:0] output stage: */
 404                                  /*          high noise/high speed */
 405        pad_mii_tx.d32_ipud  = 2; /* TXD[3:2] input stage: */
 406                                  /*          plain input (default) */
 407        pad_mii_tx.d10_ipud  = 2; /* TXD[1:0] input stage: */
 408                                  /*          plain input (default) */
 409        pad_mii_tx.ctrl_os   = 3; /* TX_CTL / TX_ER output stage */
 410        pad_mii_tx.ctrl_ipud = 2; /* TX_CTL / TX_ER input stage (default) */
 411        pad_mii_tx.clk_os    = 3; /* TX_CLK output stage */
 412        pad_mii_tx.clk_ih    = 0; /* TX_CLK input hysteresis (default) */
 413        pad_mii_tx.clk_ipud  = 2; /* TX_CLK input stage (default) */
 414        sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_tx, PACK);
 415
 416        return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_tx[port],
 417                                packed_buf, SJA1105_SIZE_CGU_CMD);
 418}
 419
 420static int sja1105_cfg_pad_rx_config(struct sja1105_private *priv, int port)
 421{
 422        const struct sja1105_regs *regs = priv->info->regs;
 423        struct sja1105_cfg_pad_mii pad_mii_rx = {0};
 424        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 425
 426        if (regs->pad_mii_rx[port] == SJA1105_RSV_ADDR)
 427                return 0;
 428
 429        /* Payload */
 430        pad_mii_rx.d32_ih    = 0; /* RXD[3:2] input stage hysteresis: */
 431                                  /*          non-Schmitt (default) */
 432        pad_mii_rx.d32_ipud  = 2; /* RXD[3:2] input weak pull-up/down */
 433                                  /*          plain input (default) */
 434        pad_mii_rx.d10_ih    = 0; /* RXD[1:0] input stage hysteresis: */
 435                                  /*          non-Schmitt (default) */
 436        pad_mii_rx.d10_ipud  = 2; /* RXD[1:0] input weak pull-up/down */
 437                                  /*          plain input (default) */
 438        pad_mii_rx.ctrl_ih   = 0; /* RX_DV/CRS_DV/RX_CTL and RX_ER */
 439                                  /* input stage hysteresis: */
 440                                  /* non-Schmitt (default) */
 441        pad_mii_rx.ctrl_ipud = 3; /* RX_DV/CRS_DV/RX_CTL and RX_ER */
 442                                  /* input stage weak pull-up/down: */
 443                                  /* pull-down */
 444        pad_mii_rx.clk_os    = 2; /* RX_CLK/RXC output stage: */
 445                                  /* medium noise/fast speed (default) */
 446        pad_mii_rx.clk_ih    = 0; /* RX_CLK/RXC input hysteresis: */
 447                                  /* non-Schmitt (default) */
 448        pad_mii_rx.clk_ipud  = 2; /* RX_CLK/RXC input pull-up/down: */
 449                                  /* plain input (default) */
 450        sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_rx, PACK);
 451
 452        return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_rx[port],
 453                                packed_buf, SJA1105_SIZE_CGU_CMD);
 454}
 455
 456static void
 457sja1105_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
 458                               enum packing_op op)
 459{
 460        const int size = SJA1105_SIZE_CGU_CMD;
 461
 462        sja1105_packing(buf, &cmd->rxc_stable_ovr, 15, 15, size, op);
 463        sja1105_packing(buf, &cmd->rxc_delay,      14, 10, size, op);
 464        sja1105_packing(buf, &cmd->rxc_bypass,      9,  9, size, op);
 465        sja1105_packing(buf, &cmd->rxc_pd,          8,  8, size, op);
 466        sja1105_packing(buf, &cmd->txc_stable_ovr,  7,  7, size, op);
 467        sja1105_packing(buf, &cmd->txc_delay,       6,  2, size, op);
 468        sja1105_packing(buf, &cmd->txc_bypass,      1,  1, size, op);
 469        sja1105_packing(buf, &cmd->txc_pd,          0,  0, size, op);
 470}
 471
 472static void
 473sja1110_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
 474                               enum packing_op op)
 475{
 476        const int size = SJA1105_SIZE_CGU_CMD;
 477        u64 range = 4;
 478
 479        /* Fields RXC_RANGE and TXC_RANGE select the input frequency range:
 480         * 0 = 2.5MHz
 481         * 1 = 25MHz
 482         * 2 = 50MHz
 483         * 3 = 125MHz
 484         * 4 = Automatically determined by port speed.
 485         * There's no point in defining a structure different than the one for
 486         * SJA1105, so just hardcode the frequency range to automatic, just as
 487         * before.
 488         */
 489        sja1105_packing(buf, &cmd->rxc_stable_ovr, 26, 26, size, op);
 490        sja1105_packing(buf, &cmd->rxc_delay,      25, 21, size, op);
 491        sja1105_packing(buf, &range,               20, 18, size, op);
 492        sja1105_packing(buf, &cmd->rxc_bypass,     17, 17, size, op);
 493        sja1105_packing(buf, &cmd->rxc_pd,         16, 16, size, op);
 494        sja1105_packing(buf, &cmd->txc_stable_ovr, 10, 10, size, op);
 495        sja1105_packing(buf, &cmd->txc_delay,       9,  5, size, op);
 496        sja1105_packing(buf, &range,                4,  2, size, op);
 497        sja1105_packing(buf, &cmd->txc_bypass,      1,  1, size, op);
 498        sja1105_packing(buf, &cmd->txc_pd,          0,  0, size, op);
 499}
 500
 501/* The RGMII delay setup procedure is 2-step and gets called upon each
 502 * .phylink_mac_config. Both are strategic.
 503 * The reason is that the RX Tunable Delay Line of the SJA1105 MAC has issues
 504 * with recovering from a frequency change of the link partner's RGMII clock.
 505 * The easiest way to recover from this is to temporarily power down the TDL,
 506 * as it will re-lock at the new frequency afterwards.
 507 */
 508int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port)
 509{
 510        const struct sja1105_private *priv = ctx;
 511        const struct sja1105_regs *regs = priv->info->regs;
 512        struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
 513        int rx_delay = priv->rgmii_rx_delay_ps[port];
 514        int tx_delay = priv->rgmii_tx_delay_ps[port];
 515        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 516        int rc;
 517
 518        if (rx_delay)
 519                pad_mii_id.rxc_delay = SJA1105_RGMII_DELAY_PS_TO_HW(rx_delay);
 520        if (tx_delay)
 521                pad_mii_id.txc_delay = SJA1105_RGMII_DELAY_PS_TO_HW(tx_delay);
 522
 523        /* Stage 1: Turn the RGMII delay lines off. */
 524        pad_mii_id.rxc_bypass = 1;
 525        pad_mii_id.rxc_pd = 1;
 526        pad_mii_id.txc_bypass = 1;
 527        pad_mii_id.txc_pd = 1;
 528        sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
 529
 530        rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
 531                              packed_buf, SJA1105_SIZE_CGU_CMD);
 532        if (rc < 0)
 533                return rc;
 534
 535        /* Stage 2: Turn the RGMII delay lines on. */
 536        if (rx_delay) {
 537                pad_mii_id.rxc_bypass = 0;
 538                pad_mii_id.rxc_pd = 0;
 539        }
 540        if (tx_delay) {
 541                pad_mii_id.txc_bypass = 0;
 542                pad_mii_id.txc_pd = 0;
 543        }
 544        sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
 545
 546        return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
 547                                packed_buf, SJA1105_SIZE_CGU_CMD);
 548}
 549
 550int sja1110_setup_rgmii_delay(const void *ctx, int port)
 551{
 552        const struct sja1105_private *priv = ctx;
 553        const struct sja1105_regs *regs = priv->info->regs;
 554        struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
 555        int rx_delay = priv->rgmii_rx_delay_ps[port];
 556        int tx_delay = priv->rgmii_tx_delay_ps[port];
 557        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 558
 559        pad_mii_id.rxc_pd = 1;
 560        pad_mii_id.txc_pd = 1;
 561
 562        if (rx_delay) {
 563                pad_mii_id.rxc_delay = SJA1105_RGMII_DELAY_PS_TO_HW(rx_delay);
 564                /* The "BYPASS" bit in SJA1110 is actually a "don't bypass" */
 565                pad_mii_id.rxc_bypass = 1;
 566                pad_mii_id.rxc_pd = 0;
 567        }
 568
 569        if (tx_delay) {
 570                pad_mii_id.txc_delay = SJA1105_RGMII_DELAY_PS_TO_HW(tx_delay);
 571                pad_mii_id.txc_bypass = 1;
 572                pad_mii_id.txc_pd = 0;
 573        }
 574
 575        sja1110_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
 576
 577        return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
 578                                packed_buf, SJA1105_SIZE_CGU_CMD);
 579}
 580
 581static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port,
 582                                        sja1105_mii_role_t role)
 583{
 584        struct device *dev = priv->ds->dev;
 585        struct sja1105_mac_config_entry *mac;
 586        u64 speed;
 587        int rc;
 588
 589        mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
 590        speed = mac[port].speed;
 591
 592        dev_dbg(dev, "Configuring port %d RGMII at speed %lldMbps\n",
 593                port, speed);
 594
 595        if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
 596                /* 1000Mbps, IDIV disabled (125 MHz) */
 597                rc = sja1105_cgu_idiv_config(priv, port, false, 1);
 598        } else if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) {
 599                /* 100Mbps, IDIV enabled, divide by 1 (25 MHz) */
 600                rc = sja1105_cgu_idiv_config(priv, port, true, 1);
 601        } else if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) {
 602                /* 10Mbps, IDIV enabled, divide by 10 (2.5 MHz) */
 603                rc = sja1105_cgu_idiv_config(priv, port, true, 10);
 604        } else if (speed == priv->info->port_speed[SJA1105_SPEED_AUTO]) {
 605                /* Skip CGU configuration if there is no speed available
 606                 * (e.g. link is not established yet)
 607                 */
 608                dev_dbg(dev, "Speed not available, skipping CGU config\n");
 609                return 0;
 610        } else {
 611                rc = -EINVAL;
 612        }
 613
 614        if (rc < 0) {
 615                dev_err(dev, "Failed to configure idiv\n");
 616                return rc;
 617        }
 618        rc = sja1105_cgu_rgmii_tx_clk_config(priv, port, speed);
 619        if (rc < 0) {
 620                dev_err(dev, "Failed to configure RGMII Tx clock\n");
 621                return rc;
 622        }
 623        rc = sja1105_rgmii_cfg_pad_tx_config(priv, port);
 624        if (rc < 0) {
 625                dev_err(dev, "Failed to configure Tx pad registers\n");
 626                return rc;
 627        }
 628
 629        if (!priv->info->setup_rgmii_delay)
 630                return 0;
 631
 632        return priv->info->setup_rgmii_delay(priv, port);
 633}
 634
 635static int sja1105_cgu_rmii_ref_clk_config(struct sja1105_private *priv,
 636                                           int port)
 637{
 638        const struct sja1105_regs *regs = priv->info->regs;
 639        struct sja1105_cgu_mii_ctrl ref_clk;
 640        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 641        const int clk_sources[] = {
 642                CLKSRC_MII0_TX_CLK,
 643                CLKSRC_MII1_TX_CLK,
 644                CLKSRC_MII2_TX_CLK,
 645                CLKSRC_MII3_TX_CLK,
 646                CLKSRC_MII4_TX_CLK,
 647        };
 648
 649        if (regs->rmii_ref_clk[port] == SJA1105_RSV_ADDR)
 650                return 0;
 651
 652        /* Payload for packed_buf */
 653        ref_clk.clksrc    = clk_sources[port];
 654        ref_clk.autoblock = 1;      /* Autoblock clk while changing clksrc */
 655        ref_clk.pd        = 0;      /* Power Down off => enabled */
 656        sja1105_cgu_mii_control_packing(packed_buf, &ref_clk, PACK);
 657
 658        return sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_ref_clk[port],
 659                                packed_buf, SJA1105_SIZE_CGU_CMD);
 660}
 661
 662static int
 663sja1105_cgu_rmii_ext_tx_clk_config(struct sja1105_private *priv, int port)
 664{
 665        const struct sja1105_regs *regs = priv->info->regs;
 666        struct sja1105_cgu_mii_ctrl ext_tx_clk;
 667        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 668
 669        if (regs->rmii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
 670                return 0;
 671
 672        /* Payload for packed_buf */
 673        ext_tx_clk.clksrc    = CLKSRC_PLL1;
 674        ext_tx_clk.autoblock = 1;   /* Autoblock clk while changing clksrc */
 675        ext_tx_clk.pd        = 0;   /* Power Down off => enabled */
 676        sja1105_cgu_mii_control_packing(packed_buf, &ext_tx_clk, PACK);
 677
 678        return sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_ext_tx_clk[port],
 679                                packed_buf, SJA1105_SIZE_CGU_CMD);
 680}
 681
 682static int sja1105_cgu_rmii_pll_config(struct sja1105_private *priv)
 683{
 684        const struct sja1105_regs *regs = priv->info->regs;
 685        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 686        struct sja1105_cgu_pll_ctrl pll = {0};
 687        struct device *dev = priv->ds->dev;
 688        int rc;
 689
 690        if (regs->rmii_pll1 == SJA1105_RSV_ADDR)
 691                return 0;
 692
 693        /* PLL1 must be enabled and output 50 Mhz.
 694         * This is done by writing first 0x0A010941 to
 695         * the PLL_1_C register and then deasserting
 696         * power down (PD) 0x0A010940.
 697         */
 698
 699        /* Step 1: PLL1 setup for 50Mhz */
 700        pll.pllclksrc = 0xA;
 701        pll.msel      = 0x1;
 702        pll.autoblock = 0x1;
 703        pll.psel      = 0x1;
 704        pll.direct    = 0x0;
 705        pll.fbsel     = 0x1;
 706        pll.bypass    = 0x0;
 707        pll.pd        = 0x1;
 708
 709        sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
 710        rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_pll1, packed_buf,
 711                              SJA1105_SIZE_CGU_CMD);
 712        if (rc < 0) {
 713                dev_err(dev, "failed to configure PLL1 for 50MHz\n");
 714                return rc;
 715        }
 716
 717        /* Step 2: Enable PLL1 */
 718        pll.pd = 0x0;
 719
 720        sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
 721        rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_pll1, packed_buf,
 722                              SJA1105_SIZE_CGU_CMD);
 723        if (rc < 0) {
 724                dev_err(dev, "failed to enable PLL1\n");
 725                return rc;
 726        }
 727        return rc;
 728}
 729
 730static int sja1105_rmii_clocking_setup(struct sja1105_private *priv, int port,
 731                                       sja1105_mii_role_t role)
 732{
 733        struct device *dev = priv->ds->dev;
 734        int rc;
 735
 736        dev_dbg(dev, "Configuring RMII-%s clocking\n",
 737                (role == XMII_MAC) ? "MAC" : "PHY");
 738        /* AH1601.pdf chapter 2.5.1. Sources */
 739        if (role == XMII_MAC) {
 740                /* Configure and enable PLL1 for 50Mhz output */
 741                rc = sja1105_cgu_rmii_pll_config(priv);
 742                if (rc < 0)
 743                        return rc;
 744        }
 745        /* Disable IDIV for this port */
 746        rc = sja1105_cgu_idiv_config(priv, port, false, 1);
 747        if (rc < 0)
 748                return rc;
 749        /* Source to sink mappings */
 750        rc = sja1105_cgu_rmii_ref_clk_config(priv, port);
 751        if (rc < 0)
 752                return rc;
 753        if (role == XMII_MAC) {
 754                rc = sja1105_cgu_rmii_ext_tx_clk_config(priv, port);
 755                if (rc < 0)
 756                        return rc;
 757        }
 758        return 0;
 759}
 760
 761int sja1105_clocking_setup_port(struct sja1105_private *priv, int port)
 762{
 763        struct sja1105_xmii_params_entry *mii;
 764        struct device *dev = priv->ds->dev;
 765        sja1105_phy_interface_t phy_mode;
 766        sja1105_mii_role_t role;
 767        int rc;
 768
 769        mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
 770
 771        /* RGMII etc */
 772        phy_mode = mii->xmii_mode[port];
 773        /* MAC or PHY, for applicable types (not RGMII) */
 774        role = mii->phy_mac[port];
 775
 776        switch (phy_mode) {
 777        case XMII_MODE_MII:
 778                rc = sja1105_mii_clocking_setup(priv, port, role);
 779                break;
 780        case XMII_MODE_RMII:
 781                rc = sja1105_rmii_clocking_setup(priv, port, role);
 782                break;
 783        case XMII_MODE_RGMII:
 784                rc = sja1105_rgmii_clocking_setup(priv, port, role);
 785                break;
 786        case XMII_MODE_SGMII:
 787                /* Nothing to do in the CGU for SGMII */
 788                rc = 0;
 789                break;
 790        default:
 791                dev_err(dev, "Invalid interface mode specified: %d\n",
 792                        phy_mode);
 793                return -EINVAL;
 794        }
 795        if (rc) {
 796                dev_err(dev, "Clocking setup for port %d failed: %d\n",
 797                        port, rc);
 798                return rc;
 799        }
 800
 801        /* Internally pull down the RX_DV/CRS_DV/RX_CTL and RX_ER inputs */
 802        return sja1105_cfg_pad_rx_config(priv, port);
 803}
 804
 805int sja1105_clocking_setup(struct sja1105_private *priv)
 806{
 807        struct dsa_switch *ds = priv->ds;
 808        int port, rc;
 809
 810        for (port = 0; port < ds->num_ports; port++) {
 811                rc = sja1105_clocking_setup_port(priv, port);
 812                if (rc < 0)
 813                        return rc;
 814        }
 815        return 0;
 816}
 817
 818static void
 819sja1110_cgu_outclk_packing(void *buf, struct sja1110_cgu_outclk *outclk,
 820                           enum packing_op op)
 821{
 822        const int size = 4;
 823
 824        sja1105_packing(buf, &outclk->clksrc,    27, 24, size, op);
 825        sja1105_packing(buf, &outclk->autoblock, 11, 11, size, op);
 826        sja1105_packing(buf, &outclk->pd,         0,  0, size, op);
 827}
 828
 829int sja1110_disable_microcontroller(struct sja1105_private *priv)
 830{
 831        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 832        struct sja1110_cgu_outclk outclk_6_c = {
 833                .clksrc = 0x3,
 834                .pd = true,
 835        };
 836        struct sja1110_cgu_outclk outclk_7_c = {
 837                .clksrc = 0x5,
 838                .pd = true,
 839        };
 840        int rc;
 841
 842        /* Power down the BASE_TIMER_CLK to disable the watchdog timer */
 843        sja1110_cgu_outclk_packing(packed_buf, &outclk_7_c, PACK);
 844
 845        rc = sja1105_xfer_buf(priv, SPI_WRITE, SJA1110_BASE_TIMER_CLK,
 846                              packed_buf, SJA1105_SIZE_CGU_CMD);
 847        if (rc)
 848                return rc;
 849
 850        /* Power down the BASE_MCSS_CLOCK to gate the microcontroller off */
 851        sja1110_cgu_outclk_packing(packed_buf, &outclk_6_c, PACK);
 852
 853        return sja1105_xfer_buf(priv, SPI_WRITE, SJA1110_BASE_MCSS_CLK,
 854                                packed_buf, SJA1105_SIZE_CGU_CMD);
 855}
 856