linux/drivers/net/dsa/sja1105/sja1105_clocking.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause
   2/* Copyright (c) 2016-2018, NXP Semiconductors
   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
  10struct sja1105_cfg_pad_mii_tx {
  11        u64 d32_os;
  12        u64 d32_ipud;
  13        u64 d10_os;
  14        u64 d10_ipud;
  15        u64 ctrl_os;
  16        u64 ctrl_ipud;
  17        u64 clk_os;
  18        u64 clk_ih;
  19        u64 clk_ipud;
  20};
  21
  22struct sja1105_cfg_pad_mii_id {
  23        u64 rxc_stable_ovr;
  24        u64 rxc_delay;
  25        u64 rxc_bypass;
  26        u64 rxc_pd;
  27        u64 txc_stable_ovr;
  28        u64 txc_delay;
  29        u64 txc_bypass;
  30        u64 txc_pd;
  31};
  32
  33/* UM10944 Table 82.
  34 * IDIV_0_C to IDIV_4_C control registers
  35 * (addr. 10000Bh to 10000Fh)
  36 */
  37struct sja1105_cgu_idiv {
  38        u64 clksrc;
  39        u64 autoblock;
  40        u64 idiv;
  41        u64 pd;
  42};
  43
  44/* PLL_1_C control register
  45 *
  46 * SJA1105 E/T: UM10944 Table 81 (address 10000Ah)
  47 * SJA1105 P/Q/R/S: UM11040 Table 116 (address 10000Ah)
  48 */
  49struct sja1105_cgu_pll_ctrl {
  50        u64 pllclksrc;
  51        u64 msel;
  52        u64 autoblock;
  53        u64 psel;
  54        u64 direct;
  55        u64 fbsel;
  56        u64 bypass;
  57        u64 pd;
  58};
  59
  60enum {
  61        CLKSRC_MII0_TX_CLK      = 0x00,
  62        CLKSRC_MII0_RX_CLK      = 0x01,
  63        CLKSRC_MII1_TX_CLK      = 0x02,
  64        CLKSRC_MII1_RX_CLK      = 0x03,
  65        CLKSRC_MII2_TX_CLK      = 0x04,
  66        CLKSRC_MII2_RX_CLK      = 0x05,
  67        CLKSRC_MII3_TX_CLK      = 0x06,
  68        CLKSRC_MII3_RX_CLK      = 0x07,
  69        CLKSRC_MII4_TX_CLK      = 0x08,
  70        CLKSRC_MII4_RX_CLK      = 0x09,
  71        CLKSRC_PLL0             = 0x0B,
  72        CLKSRC_PLL1             = 0x0E,
  73        CLKSRC_IDIV0            = 0x11,
  74        CLKSRC_IDIV1            = 0x12,
  75        CLKSRC_IDIV2            = 0x13,
  76        CLKSRC_IDIV3            = 0x14,
  77        CLKSRC_IDIV4            = 0x15,
  78};
  79
  80/* UM10944 Table 83.
  81 * MIIx clock control registers 1 to 30
  82 * (addresses 100013h to 100035h)
  83 */
  84struct sja1105_cgu_mii_ctrl {
  85        u64 clksrc;
  86        u64 autoblock;
  87        u64 pd;
  88};
  89
  90static void sja1105_cgu_idiv_packing(void *buf, struct sja1105_cgu_idiv *idiv,
  91                                     enum packing_op op)
  92{
  93        const int size = 4;
  94
  95        sja1105_packing(buf, &idiv->clksrc,    28, 24, size, op);
  96        sja1105_packing(buf, &idiv->autoblock, 11, 11, size, op);
  97        sja1105_packing(buf, &idiv->idiv,       5,  2, size, op);
  98        sja1105_packing(buf, &idiv->pd,         0,  0, size, op);
  99}
 100
 101static int sja1105_cgu_idiv_config(struct sja1105_private *priv, int port,
 102                                   bool enabled, int factor)
 103{
 104        const struct sja1105_regs *regs = priv->info->regs;
 105        struct device *dev = priv->ds->dev;
 106        struct sja1105_cgu_idiv idiv;
 107        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 108
 109        if (enabled && factor != 1 && factor != 10) {
 110                dev_err(dev, "idiv factor must be 1 or 10\n");
 111                return -ERANGE;
 112        }
 113
 114        /* Payload for packed_buf */
 115        idiv.clksrc    = 0x0A;            /* 25MHz */
 116        idiv.autoblock = 1;               /* Block clk automatically */
 117        idiv.idiv      = factor - 1;      /* Divide by 1 or 10 */
 118        idiv.pd        = enabled ? 0 : 1; /* Power down? */
 119        sja1105_cgu_idiv_packing(packed_buf, &idiv, PACK);
 120
 121        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 122                                           regs->cgu_idiv[port], packed_buf,
 123                                           SJA1105_SIZE_CGU_CMD);
 124}
 125
 126static void
 127sja1105_cgu_mii_control_packing(void *buf, struct sja1105_cgu_mii_ctrl *cmd,
 128                                enum packing_op op)
 129{
 130        const int size = 4;
 131
 132        sja1105_packing(buf, &cmd->clksrc,    28, 24, size, op);
 133        sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
 134        sja1105_packing(buf, &cmd->pd,         0,  0, size, op);
 135}
 136
 137static int sja1105_cgu_mii_tx_clk_config(struct sja1105_private *priv,
 138                                         int port, sja1105_mii_role_t role)
 139{
 140        const struct sja1105_regs *regs = priv->info->regs;
 141        struct sja1105_cgu_mii_ctrl mii_tx_clk;
 142        const int mac_clk_sources[] = {
 143                CLKSRC_MII0_TX_CLK,
 144                CLKSRC_MII1_TX_CLK,
 145                CLKSRC_MII2_TX_CLK,
 146                CLKSRC_MII3_TX_CLK,
 147                CLKSRC_MII4_TX_CLK,
 148        };
 149        const int phy_clk_sources[] = {
 150                CLKSRC_IDIV0,
 151                CLKSRC_IDIV1,
 152                CLKSRC_IDIV2,
 153                CLKSRC_IDIV3,
 154                CLKSRC_IDIV4,
 155        };
 156        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 157        int clksrc;
 158
 159        if (role == XMII_MAC)
 160                clksrc = mac_clk_sources[port];
 161        else
 162                clksrc = phy_clk_sources[port];
 163
 164        /* Payload for packed_buf */
 165        mii_tx_clk.clksrc    = clksrc;
 166        mii_tx_clk.autoblock = 1;  /* Autoblock clk while changing clksrc */
 167        mii_tx_clk.pd        = 0;  /* Power Down off => enabled */
 168        sja1105_cgu_mii_control_packing(packed_buf, &mii_tx_clk, PACK);
 169
 170        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 171                                           regs->mii_tx_clk[port], packed_buf,
 172                                           SJA1105_SIZE_CGU_CMD);
 173}
 174
 175static int
 176sja1105_cgu_mii_rx_clk_config(struct sja1105_private *priv, int port)
 177{
 178        const struct sja1105_regs *regs = priv->info->regs;
 179        struct sja1105_cgu_mii_ctrl mii_rx_clk;
 180        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 181        const int clk_sources[] = {
 182                CLKSRC_MII0_RX_CLK,
 183                CLKSRC_MII1_RX_CLK,
 184                CLKSRC_MII2_RX_CLK,
 185                CLKSRC_MII3_RX_CLK,
 186                CLKSRC_MII4_RX_CLK,
 187        };
 188
 189        /* Payload for packed_buf */
 190        mii_rx_clk.clksrc    = clk_sources[port];
 191        mii_rx_clk.autoblock = 1;  /* Autoblock clk while changing clksrc */
 192        mii_rx_clk.pd        = 0;  /* Power Down off => enabled */
 193        sja1105_cgu_mii_control_packing(packed_buf, &mii_rx_clk, PACK);
 194
 195        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 196                                           regs->mii_rx_clk[port], packed_buf,
 197                                           SJA1105_SIZE_CGU_CMD);
 198}
 199
 200static int
 201sja1105_cgu_mii_ext_tx_clk_config(struct sja1105_private *priv, int port)
 202{
 203        const struct sja1105_regs *regs = priv->info->regs;
 204        struct sja1105_cgu_mii_ctrl mii_ext_tx_clk;
 205        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 206        const int clk_sources[] = {
 207                CLKSRC_IDIV0,
 208                CLKSRC_IDIV1,
 209                CLKSRC_IDIV2,
 210                CLKSRC_IDIV3,
 211                CLKSRC_IDIV4,
 212        };
 213
 214        /* Payload for packed_buf */
 215        mii_ext_tx_clk.clksrc    = clk_sources[port];
 216        mii_ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
 217        mii_ext_tx_clk.pd        = 0; /* Power Down off => enabled */
 218        sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_tx_clk, PACK);
 219
 220        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 221                                           regs->mii_ext_tx_clk[port],
 222                                           packed_buf, SJA1105_SIZE_CGU_CMD);
 223}
 224
 225static int
 226sja1105_cgu_mii_ext_rx_clk_config(struct sja1105_private *priv, int port)
 227{
 228        const struct sja1105_regs *regs = priv->info->regs;
 229        struct sja1105_cgu_mii_ctrl mii_ext_rx_clk;
 230        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 231        const int clk_sources[] = {
 232                CLKSRC_IDIV0,
 233                CLKSRC_IDIV1,
 234                CLKSRC_IDIV2,
 235                CLKSRC_IDIV3,
 236                CLKSRC_IDIV4,
 237        };
 238
 239        /* Payload for packed_buf */
 240        mii_ext_rx_clk.clksrc    = clk_sources[port];
 241        mii_ext_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
 242        mii_ext_rx_clk.pd        = 0; /* Power Down off => enabled */
 243        sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_rx_clk, PACK);
 244
 245        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 246                                           regs->mii_ext_rx_clk[port],
 247                                           packed_buf, SJA1105_SIZE_CGU_CMD);
 248}
 249
 250static int sja1105_mii_clocking_setup(struct sja1105_private *priv, int port,
 251                                      sja1105_mii_role_t role)
 252{
 253        struct device *dev = priv->ds->dev;
 254        int rc;
 255
 256        dev_dbg(dev, "Configuring MII-%s clocking\n",
 257                (role == XMII_MAC) ? "MAC" : "PHY");
 258        /* If role is MAC, disable IDIV
 259         * If role is PHY, enable IDIV and configure for 1/1 divider
 260         */
 261        rc = sja1105_cgu_idiv_config(priv, port, (role == XMII_PHY), 1);
 262        if (rc < 0)
 263                return rc;
 264
 265        /* Configure CLKSRC of MII_TX_CLK_n
 266         *   * If role is MAC, select TX_CLK_n
 267         *   * If role is PHY, select IDIV_n
 268         */
 269        rc = sja1105_cgu_mii_tx_clk_config(priv, port, role);
 270        if (rc < 0)
 271                return rc;
 272
 273        /* Configure CLKSRC of MII_RX_CLK_n
 274         * Select RX_CLK_n
 275         */
 276        rc = sja1105_cgu_mii_rx_clk_config(priv, port);
 277        if (rc < 0)
 278                return rc;
 279
 280        if (role == XMII_PHY) {
 281                /* Per MII spec, the PHY (which is us) drives the TX_CLK pin */
 282
 283                /* Configure CLKSRC of EXT_TX_CLK_n
 284                 * Select IDIV_n
 285                 */
 286                rc = sja1105_cgu_mii_ext_tx_clk_config(priv, port);
 287                if (rc < 0)
 288                        return rc;
 289
 290                /* Configure CLKSRC of EXT_RX_CLK_n
 291                 * Select IDIV_n
 292                 */
 293                rc = sja1105_cgu_mii_ext_rx_clk_config(priv, port);
 294                if (rc < 0)
 295                        return rc;
 296        }
 297        return 0;
 298}
 299
 300static void
 301sja1105_cgu_pll_control_packing(void *buf, struct sja1105_cgu_pll_ctrl *cmd,
 302                                enum packing_op op)
 303{
 304        const int size = 4;
 305
 306        sja1105_packing(buf, &cmd->pllclksrc, 28, 24, size, op);
 307        sja1105_packing(buf, &cmd->msel,      23, 16, size, op);
 308        sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
 309        sja1105_packing(buf, &cmd->psel,       9,  8, size, op);
 310        sja1105_packing(buf, &cmd->direct,     7,  7, size, op);
 311        sja1105_packing(buf, &cmd->fbsel,      6,  6, size, op);
 312        sja1105_packing(buf, &cmd->bypass,     1,  1, size, op);
 313        sja1105_packing(buf, &cmd->pd,         0,  0, size, op);
 314}
 315
 316static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
 317                                           int port, sja1105_speed_t speed)
 318{
 319        const struct sja1105_regs *regs = priv->info->regs;
 320        struct sja1105_cgu_mii_ctrl txc;
 321        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 322        int clksrc;
 323
 324        if (speed == SJA1105_SPEED_1000MBPS) {
 325                clksrc = CLKSRC_PLL0;
 326        } else {
 327                int clk_sources[] = {CLKSRC_IDIV0, CLKSRC_IDIV1, CLKSRC_IDIV2,
 328                                     CLKSRC_IDIV3, CLKSRC_IDIV4};
 329                clksrc = clk_sources[port];
 330        }
 331
 332        /* RGMII: 125MHz for 1000, 25MHz for 100, 2.5MHz for 10 */
 333        txc.clksrc = clksrc;
 334        /* Autoblock clk while changing clksrc */
 335        txc.autoblock = 1;
 336        /* Power Down off => enabled */
 337        txc.pd = 0;
 338        sja1105_cgu_mii_control_packing(packed_buf, &txc, PACK);
 339
 340        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 341                                           regs->rgmii_tx_clk[port],
 342                                           packed_buf, SJA1105_SIZE_CGU_CMD);
 343}
 344
 345/* AGU */
 346static void
 347sja1105_cfg_pad_mii_tx_packing(void *buf, struct sja1105_cfg_pad_mii_tx *cmd,
 348                               enum packing_op op)
 349{
 350        const int size = 4;
 351
 352        sja1105_packing(buf, &cmd->d32_os,   28, 27, size, op);
 353        sja1105_packing(buf, &cmd->d32_ipud, 25, 24, size, op);
 354        sja1105_packing(buf, &cmd->d10_os,   20, 19, size, op);
 355        sja1105_packing(buf, &cmd->d10_ipud, 17, 16, size, op);
 356        sja1105_packing(buf, &cmd->ctrl_os,  12, 11, size, op);
 357        sja1105_packing(buf, &cmd->ctrl_ipud, 9,  8, size, op);
 358        sja1105_packing(buf, &cmd->clk_os,    4,  3, size, op);
 359        sja1105_packing(buf, &cmd->clk_ih,    2,  2, size, op);
 360        sja1105_packing(buf, &cmd->clk_ipud,  1,  0, size, op);
 361}
 362
 363static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
 364                                           int port)
 365{
 366        const struct sja1105_regs *regs = priv->info->regs;
 367        struct sja1105_cfg_pad_mii_tx pad_mii_tx;
 368        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 369
 370        /* Payload */
 371        pad_mii_tx.d32_os    = 3; /* TXD[3:2] output stage: */
 372                                  /*          high noise/high speed */
 373        pad_mii_tx.d10_os    = 3; /* TXD[1:0] output stage: */
 374                                  /*          high noise/high speed */
 375        pad_mii_tx.d32_ipud  = 2; /* TXD[3:2] input stage: */
 376                                  /*          plain input (default) */
 377        pad_mii_tx.d10_ipud  = 2; /* TXD[1:0] input stage: */
 378                                  /*          plain input (default) */
 379        pad_mii_tx.ctrl_os   = 3; /* TX_CTL / TX_ER output stage */
 380        pad_mii_tx.ctrl_ipud = 2; /* TX_CTL / TX_ER input stage (default) */
 381        pad_mii_tx.clk_os    = 3; /* TX_CLK output stage */
 382        pad_mii_tx.clk_ih    = 0; /* TX_CLK input hysteresis (default) */
 383        pad_mii_tx.clk_ipud  = 2; /* TX_CLK input stage (default) */
 384        sja1105_cfg_pad_mii_tx_packing(packed_buf, &pad_mii_tx, PACK);
 385
 386        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 387                                           regs->pad_mii_tx[port],
 388                                           packed_buf, SJA1105_SIZE_CGU_CMD);
 389}
 390
 391static void
 392sja1105_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
 393                               enum packing_op op)
 394{
 395        const int size = SJA1105_SIZE_CGU_CMD;
 396
 397        sja1105_packing(buf, &cmd->rxc_stable_ovr, 15, 15, size, op);
 398        sja1105_packing(buf, &cmd->rxc_delay,      14, 10, size, op);
 399        sja1105_packing(buf, &cmd->rxc_bypass,      9,  9, size, op);
 400        sja1105_packing(buf, &cmd->rxc_pd,          8,  8, size, op);
 401        sja1105_packing(buf, &cmd->txc_stable_ovr,  7,  7, size, op);
 402        sja1105_packing(buf, &cmd->txc_delay,       6,  2, size, op);
 403        sja1105_packing(buf, &cmd->txc_bypass,      1,  1, size, op);
 404        sja1105_packing(buf, &cmd->txc_pd,          0,  0, size, op);
 405}
 406
 407/* Valid range in degrees is an integer between 73.8 and 101.7 */
 408static inline u64 sja1105_rgmii_delay(u64 phase)
 409{
 410        /* UM11040.pdf: The delay in degree phase is 73.8 + delay_tune * 0.9.
 411         * To avoid floating point operations we'll multiply by 10
 412         * and get 1 decimal point precision.
 413         */
 414        phase *= 10;
 415        return (phase - 738) / 9;
 416}
 417
 418/* The RGMII delay setup procedure is 2-step and gets called upon each
 419 * .phylink_mac_config. Both are strategic.
 420 * The reason is that the RX Tunable Delay Line of the SJA1105 MAC has issues
 421 * with recovering from a frequency change of the link partner's RGMII clock.
 422 * The easiest way to recover from this is to temporarily power down the TDL,
 423 * as it will re-lock at the new frequency afterwards.
 424 */
 425int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port)
 426{
 427        const struct sja1105_private *priv = ctx;
 428        const struct sja1105_regs *regs = priv->info->regs;
 429        struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
 430        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 431        int rc;
 432
 433        if (priv->rgmii_rx_delay[port])
 434                pad_mii_id.rxc_delay = sja1105_rgmii_delay(90);
 435        if (priv->rgmii_tx_delay[port])
 436                pad_mii_id.txc_delay = sja1105_rgmii_delay(90);
 437
 438        /* Stage 1: Turn the RGMII delay lines off. */
 439        pad_mii_id.rxc_bypass = 1;
 440        pad_mii_id.rxc_pd = 1;
 441        pad_mii_id.txc_bypass = 1;
 442        pad_mii_id.txc_pd = 1;
 443        sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
 444
 445        rc = sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 446                                         regs->pad_mii_id[port],
 447                                         packed_buf, SJA1105_SIZE_CGU_CMD);
 448        if (rc < 0)
 449                return rc;
 450
 451        /* Stage 2: Turn the RGMII delay lines on. */
 452        if (priv->rgmii_rx_delay[port]) {
 453                pad_mii_id.rxc_bypass = 0;
 454                pad_mii_id.rxc_pd = 0;
 455        }
 456        if (priv->rgmii_tx_delay[port]) {
 457                pad_mii_id.txc_bypass = 0;
 458                pad_mii_id.txc_pd = 0;
 459        }
 460        sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
 461
 462        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 463                                           regs->pad_mii_id[port],
 464                                           packed_buf, SJA1105_SIZE_CGU_CMD);
 465}
 466
 467static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port,
 468                                        sja1105_mii_role_t role)
 469{
 470        struct device *dev = priv->ds->dev;
 471        struct sja1105_mac_config_entry *mac;
 472        sja1105_speed_t speed;
 473        int rc;
 474
 475        mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
 476        speed = mac[port].speed;
 477
 478        dev_dbg(dev, "Configuring port %d RGMII at speed %dMbps\n",
 479                port, speed);
 480
 481        switch (speed) {
 482        case SJA1105_SPEED_1000MBPS:
 483                /* 1000Mbps, IDIV disabled (125 MHz) */
 484                rc = sja1105_cgu_idiv_config(priv, port, false, 1);
 485                break;
 486        case SJA1105_SPEED_100MBPS:
 487                /* 100Mbps, IDIV enabled, divide by 1 (25 MHz) */
 488                rc = sja1105_cgu_idiv_config(priv, port, true, 1);
 489                break;
 490        case SJA1105_SPEED_10MBPS:
 491                /* 10Mbps, IDIV enabled, divide by 10 (2.5 MHz) */
 492                rc = sja1105_cgu_idiv_config(priv, port, true, 10);
 493                break;
 494        case SJA1105_SPEED_AUTO:
 495                /* Skip CGU configuration if there is no speed available
 496                 * (e.g. link is not established yet)
 497                 */
 498                dev_dbg(dev, "Speed not available, skipping CGU config\n");
 499                return 0;
 500        default:
 501                rc = -EINVAL;
 502        }
 503
 504        if (rc < 0) {
 505                dev_err(dev, "Failed to configure idiv\n");
 506                return rc;
 507        }
 508        rc = sja1105_cgu_rgmii_tx_clk_config(priv, port, speed);
 509        if (rc < 0) {
 510                dev_err(dev, "Failed to configure RGMII Tx clock\n");
 511                return rc;
 512        }
 513        rc = sja1105_rgmii_cfg_pad_tx_config(priv, port);
 514        if (rc < 0) {
 515                dev_err(dev, "Failed to configure Tx pad registers\n");
 516                return rc;
 517        }
 518        if (!priv->info->setup_rgmii_delay)
 519                return 0;
 520        /* The role has no hardware effect for RGMII. However we use it as
 521         * a proxy for this interface being a MAC-to-MAC connection, with
 522         * the RGMII internal delays needing to be applied by us.
 523         */
 524        if (role == XMII_MAC)
 525                return 0;
 526
 527        return priv->info->setup_rgmii_delay(priv, port);
 528}
 529
 530static int sja1105_cgu_rmii_ref_clk_config(struct sja1105_private *priv,
 531                                           int port)
 532{
 533        const struct sja1105_regs *regs = priv->info->regs;
 534        struct sja1105_cgu_mii_ctrl ref_clk;
 535        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 536        const int clk_sources[] = {
 537                CLKSRC_MII0_TX_CLK,
 538                CLKSRC_MII1_TX_CLK,
 539                CLKSRC_MII2_TX_CLK,
 540                CLKSRC_MII3_TX_CLK,
 541                CLKSRC_MII4_TX_CLK,
 542        };
 543
 544        /* Payload for packed_buf */
 545        ref_clk.clksrc    = clk_sources[port];
 546        ref_clk.autoblock = 1;      /* Autoblock clk while changing clksrc */
 547        ref_clk.pd        = 0;      /* Power Down off => enabled */
 548        sja1105_cgu_mii_control_packing(packed_buf, &ref_clk, PACK);
 549
 550        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 551                                           regs->rmii_ref_clk[port],
 552                                           packed_buf, SJA1105_SIZE_CGU_CMD);
 553}
 554
 555static int
 556sja1105_cgu_rmii_ext_tx_clk_config(struct sja1105_private *priv, int port)
 557{
 558        const struct sja1105_regs *regs = priv->info->regs;
 559        struct sja1105_cgu_mii_ctrl ext_tx_clk;
 560        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 561
 562        /* Payload for packed_buf */
 563        ext_tx_clk.clksrc    = CLKSRC_PLL1;
 564        ext_tx_clk.autoblock = 1;   /* Autoblock clk while changing clksrc */
 565        ext_tx_clk.pd        = 0;   /* Power Down off => enabled */
 566        sja1105_cgu_mii_control_packing(packed_buf, &ext_tx_clk, PACK);
 567
 568        return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
 569                                           regs->rmii_ext_tx_clk[port],
 570                                           packed_buf, SJA1105_SIZE_CGU_CMD);
 571}
 572
 573static int sja1105_cgu_rmii_pll_config(struct sja1105_private *priv)
 574{
 575        const struct sja1105_regs *regs = priv->info->regs;
 576        u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
 577        struct sja1105_cgu_pll_ctrl pll = {0};
 578        struct device *dev = priv->ds->dev;
 579        int rc;
 580
 581        /* PLL1 must be enabled and output 50 Mhz.
 582         * This is done by writing first 0x0A010941 to
 583         * the PLL_1_C register and then deasserting
 584         * power down (PD) 0x0A010940.
 585         */
 586
 587        /* Step 1: PLL1 setup for 50Mhz */
 588        pll.pllclksrc = 0xA;
 589        pll.msel      = 0x1;
 590        pll.autoblock = 0x1;
 591        pll.psel      = 0x1;
 592        pll.direct    = 0x0;
 593        pll.fbsel     = 0x1;
 594        pll.bypass    = 0x0;
 595        pll.pd        = 0x1;
 596
 597        sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
 598        rc = sja1105_spi_send_packed_buf(priv, SPI_WRITE, regs->rmii_pll1,
 599                                         packed_buf, SJA1105_SIZE_CGU_CMD);
 600        if (rc < 0) {
 601                dev_err(dev, "failed to configure PLL1 for 50MHz\n");
 602                return rc;
 603        }
 604
 605        /* Step 2: Enable PLL1 */
 606        pll.pd = 0x0;
 607
 608        sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
 609        rc = sja1105_spi_send_packed_buf(priv, SPI_WRITE, regs->rmii_pll1,
 610                                         packed_buf, SJA1105_SIZE_CGU_CMD);
 611        if (rc < 0) {
 612                dev_err(dev, "failed to enable PLL1\n");
 613                return rc;
 614        }
 615        return rc;
 616}
 617
 618static int sja1105_rmii_clocking_setup(struct sja1105_private *priv, int port,
 619                                       sja1105_mii_role_t role)
 620{
 621        struct device *dev = priv->ds->dev;
 622        int rc;
 623
 624        dev_dbg(dev, "Configuring RMII-%s clocking\n",
 625                (role == XMII_MAC) ? "MAC" : "PHY");
 626        /* AH1601.pdf chapter 2.5.1. Sources */
 627        if (role == XMII_MAC) {
 628                /* Configure and enable PLL1 for 50Mhz output */
 629                rc = sja1105_cgu_rmii_pll_config(priv);
 630                if (rc < 0)
 631                        return rc;
 632        }
 633        /* Disable IDIV for this port */
 634        rc = sja1105_cgu_idiv_config(priv, port, false, 1);
 635        if (rc < 0)
 636                return rc;
 637        /* Source to sink mappings */
 638        rc = sja1105_cgu_rmii_ref_clk_config(priv, port);
 639        if (rc < 0)
 640                return rc;
 641        if (role == XMII_MAC) {
 642                rc = sja1105_cgu_rmii_ext_tx_clk_config(priv, port);
 643                if (rc < 0)
 644                        return rc;
 645        }
 646        return 0;
 647}
 648
 649int sja1105_clocking_setup_port(struct sja1105_private *priv, int port)
 650{
 651        struct sja1105_xmii_params_entry *mii;
 652        struct device *dev = priv->ds->dev;
 653        sja1105_phy_interface_t phy_mode;
 654        sja1105_mii_role_t role;
 655        int rc;
 656
 657        mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
 658
 659        /* RGMII etc */
 660        phy_mode = mii->xmii_mode[port];
 661        /* MAC or PHY, for applicable types (not RGMII) */
 662        role = mii->phy_mac[port];
 663
 664        switch (phy_mode) {
 665        case XMII_MODE_MII:
 666                rc = sja1105_mii_clocking_setup(priv, port, role);
 667                break;
 668        case XMII_MODE_RMII:
 669                rc = sja1105_rmii_clocking_setup(priv, port, role);
 670                break;
 671        case XMII_MODE_RGMII:
 672                rc = sja1105_rgmii_clocking_setup(priv, port, role);
 673                break;
 674        default:
 675                dev_err(dev, "Invalid interface mode specified: %d\n",
 676                        phy_mode);
 677                return -EINVAL;
 678        }
 679        if (rc)
 680                dev_err(dev, "Clocking setup for port %d failed: %d\n",
 681                        port, rc);
 682        return rc;
 683}
 684
 685int sja1105_clocking_setup(struct sja1105_private *priv)
 686{
 687        int port, rc;
 688
 689        for (port = 0; port < SJA1105_NUM_PORTS; port++) {
 690                rc = sja1105_clocking_setup_port(priv, port);
 691                if (rc < 0)
 692                        return rc;
 693        }
 694        return 0;
 695}
 696