uboot/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2012 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   7#include <asm/fsl_serdes.h>
   8#include <asm/immap_85xx.h>
   9#include <asm/io.h>
  10#include <asm/processor.h>
  11#include <asm/fsl_law.h>
  12#include <linux/errno.h>
  13#include <fsl_errata.h>
  14#include "fsl_corenet2_serdes.h"
  15
  16#ifdef CONFIG_SYS_FSL_SRDS_1
  17static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
  18#endif
  19#ifdef CONFIG_SYS_FSL_SRDS_2
  20static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
  21#endif
  22#ifdef CONFIG_SYS_FSL_SRDS_3
  23static u8 serdes3_prtcl_map[SERDES_PRCTL_COUNT];
  24#endif
  25#ifdef CONFIG_SYS_FSL_SRDS_4
  26static u8 serdes4_prtcl_map[SERDES_PRCTL_COUNT];
  27#endif
  28
  29#ifdef DEBUG
  30static const char *serdes_prtcl_str[] = {
  31        [NONE] = "NA",
  32        [PCIE1] = "PCIE1",
  33        [PCIE2] = "PCIE2",
  34        [PCIE3] = "PCIE3",
  35        [PCIE4] = "PCIE4",
  36        [SATA1] = "SATA1",
  37        [SATA2] = "SATA2",
  38        [SRIO1] = "SRIO1",
  39        [SRIO2] = "SRIO2",
  40        [SGMII_FM1_DTSEC1] = "SGMII_FM1_DTSEC1",
  41        [SGMII_FM1_DTSEC2] = "SGMII_FM1_DTSEC2",
  42        [SGMII_FM1_DTSEC3] = "SGMII_FM1_DTSEC3",
  43        [SGMII_FM1_DTSEC4] = "SGMII_FM1_DTSEC4",
  44        [SGMII_FM1_DTSEC5] = "SGMII_FM1_DTSEC5",
  45        [SGMII_FM1_DTSEC6] = "SGMII_FM1_DTSEC6",
  46        [SGMII_FM2_DTSEC1] = "SGMII_FM2_DTSEC1",
  47        [SGMII_FM2_DTSEC2] = "SGMII_FM2_DTSEC2",
  48        [SGMII_FM2_DTSEC3] = "SGMII_FM2_DTSEC3",
  49        [SGMII_FM2_DTSEC4] = "SGMII_FM2_DTSEC4",
  50        [XAUI_FM1] = "XAUI_FM1",
  51        [XAUI_FM2] = "XAUI_FM2",
  52        [AURORA] = "DEBUG",
  53        [CPRI1] = "CPRI1",
  54        [CPRI2] = "CPRI2",
  55        [CPRI3] = "CPRI3",
  56        [CPRI4] = "CPRI4",
  57        [CPRI5] = "CPRI5",
  58        [CPRI6] = "CPRI6",
  59        [CPRI7] = "CPRI7",
  60        [CPRI8] = "CPRI8",
  61        [XAUI_FM1_MAC9] = "XAUI_FM1_MAC9",
  62        [XAUI_FM1_MAC10] = "XAUI_FM1_MAC10",
  63        [XAUI_FM2_MAC9] = "XAUI_FM2_MAC9",
  64        [XAUI_FM2_MAC10] = "XAUI_FM2_MAC10",
  65        [HIGIG_FM1_MAC9] = "HiGig_FM1_MAC9",
  66        [HIGIG_FM1_MAC10] = "HiGig_FM1_MAC10",
  67        [HIGIG_FM2_MAC9] = "HiGig_FM2_MAC9",
  68        [HIGIG_FM2_MAC10] = "HiGig_FM2_MAC10",
  69        [QSGMII_FM1_A] = "QSGMII_FM1_A",
  70        [QSGMII_FM1_B] = "QSGMII_FM1_B",
  71        [QSGMII_FM2_A] = "QSGMII_FM2_A",
  72        [QSGMII_FM2_B] = "QSGMII_FM2_B",
  73        [XFI_FM1_MAC9] = "XFI_FM1_MAC9",
  74        [XFI_FM1_MAC10] = "XFI_FM1_MAC10",
  75        [XFI_FM2_MAC9] = "XFI_FM2_MAC9",
  76        [XFI_FM2_MAC10] = "XFI_FM2_MAC10",
  77        [INTERLAKEN] = "INTERLAKEN",
  78        [QSGMII_SW1_A] = "QSGMII_SW1_A",
  79        [QSGMII_SW1_B] = "QSGMII_SW1_B",
  80        [SGMII_SW1_MAC1] = "SGMII_SW1_MAC1",
  81        [SGMII_SW1_MAC2] = "SGMII_SW1_MAC2",
  82        [SGMII_SW1_MAC3] = "SGMII_SW1_MAC3",
  83        [SGMII_SW1_MAC4] = "SGMII_SW1_MAC4",
  84        [SGMII_SW1_MAC5] = "SGMII_SW1_MAC5",
  85        [SGMII_SW1_MAC6] = "SGMII_SW1_MAC6",
  86};
  87#endif
  88
  89int is_serdes_configured(enum srds_prtcl device)
  90{
  91        int ret = 0;
  92
  93#ifdef CONFIG_SYS_FSL_SRDS_1
  94        if (!serdes1_prtcl_map[NONE])
  95                fsl_serdes_init();
  96
  97        ret |= serdes1_prtcl_map[device];
  98#endif
  99#ifdef CONFIG_SYS_FSL_SRDS_2
 100        if (!serdes2_prtcl_map[NONE])
 101                fsl_serdes_init();
 102
 103        ret |= serdes2_prtcl_map[device];
 104#endif
 105#ifdef CONFIG_SYS_FSL_SRDS_3
 106        if (!serdes3_prtcl_map[NONE])
 107                fsl_serdes_init();
 108
 109        ret |= serdes3_prtcl_map[device];
 110#endif
 111#ifdef CONFIG_SYS_FSL_SRDS_4
 112        if (!serdes4_prtcl_map[NONE])
 113                fsl_serdes_init();
 114
 115        ret |= serdes4_prtcl_map[device];
 116#endif
 117
 118        return !!ret;
 119}
 120
 121int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
 122{
 123        const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 124        u32 cfg = in_be32(&gur->rcwsr[4]);
 125        int i;
 126
 127        switch (sd) {
 128#ifdef CONFIG_SYS_FSL_SRDS_1
 129        case FSL_SRDS_1:
 130                cfg &= FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
 131                cfg >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
 132                break;
 133#endif
 134#ifdef CONFIG_SYS_FSL_SRDS_2
 135        case FSL_SRDS_2:
 136                cfg &= FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
 137                cfg >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
 138                break;
 139#endif
 140#ifdef CONFIG_SYS_FSL_SRDS_3
 141        case FSL_SRDS_3:
 142                cfg &= FSL_CORENET2_RCWSR4_SRDS3_PRTCL;
 143                cfg >>= FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT;
 144                break;
 145#endif
 146#ifdef CONFIG_SYS_FSL_SRDS_4
 147        case FSL_SRDS_4:
 148                cfg &= FSL_CORENET2_RCWSR4_SRDS4_PRTCL;
 149                cfg >>= FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT;
 150                break;
 151#endif
 152        default:
 153                printf("invalid SerDes%d\n", sd);
 154                break;
 155        }
 156        /* Is serdes enabled at all? */
 157        if (unlikely(cfg == 0))
 158                return -ENODEV;
 159
 160        for (i = 0; i < SRDS_MAX_LANES; i++) {
 161                if (serdes_get_prtcl(sd, cfg, i) == device)
 162                        return i;
 163        }
 164
 165        return -ENODEV;
 166}
 167
 168#define BC3_SHIFT       9
 169#define DC3_SHIFT       6
 170#define FC3_SHIFT       0
 171#define BC2_SHIFT       19
 172#define DC2_SHIFT       16
 173#define FC2_SHIFT       10
 174#define BC1_SHIFT       29
 175#define DC1_SHIFT       26
 176#define FC1_SHIFT       20
 177#define BC_MASK         0x1
 178#define DC_MASK         0x7
 179#define FC_MASK         0x3F
 180
 181#define FUSE_VAL_MASK           0x00000003
 182#define FUSE_VAL_SHIFT          30
 183#define CR0_DCBIAS_SHIFT        5
 184#define CR1_FCAP_SHIFT          15
 185#define CR1_BCAP_SHIFT          29
 186#define FCAP_MASK               0x001F8000
 187#define BCAP_MASK               0x20000000
 188#define BCAP_OVD_MASK           0x10000000
 189#define BYP_CAL_MASK            0x02000000
 190
 191void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
 192                u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
 193{
 194        ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 195        u32 cfg;
 196        int lane;
 197
 198        if (serdes_prtcl_map[NONE])
 199                return;
 200
 201        memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
 202#ifdef CONFIG_SYS_FSL_ERRATUM_A007186
 203        struct ccsr_sfp_regs  __iomem *sfp_regs =
 204                        (struct ccsr_sfp_regs __iomem *)(CONFIG_SYS_SFP_ADDR);
 205        u32 pll_num, pll_status, bc, dc, fc, pll_cr_upd, pll_cr0, pll_cr1;
 206        u32 bc_status, fc_status, dc_status, pll_sr2;
 207        serdes_corenet_t  __iomem *srds_regs = (void *)sd_addr;
 208        u32 sfp_spfr0, sel;
 209#endif
 210
 211        cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask;
 212
 213/* Erratum A-007186
 214 * Freescale Scratch Pad Fuse Register n (SFP_FSPFR0)
 215 * The workaround requires factory pre-set SerDes calibration values to be
 216 * read from a fuse block(Freescale Scratch Pad Fuse Register SFP_FSPFR0)
 217 * These values have been shown to work across the
 218 * entire temperature range for all SerDes. These values are then written into
 219 * the SerDes registers to calibrate the SerDes PLL.
 220 *
 221 * This workaround for the protocols and rates that only have the Ring VCO.
 222 */
 223#ifdef CONFIG_SYS_FSL_ERRATUM_A007186
 224        sfp_spfr0 = in_be32(&sfp_regs->fsl_spfr0);
 225        debug("A007186: sfp_spfr0= %x\n", sfp_spfr0);
 226
 227        sel = (sfp_spfr0 >> FUSE_VAL_SHIFT) & FUSE_VAL_MASK;
 228
 229        if (has_erratum_a007186() && (sel == 0x01 || sel == 0x02)) {
 230                for (pll_num = 0; pll_num < SRDS_MAX_BANK; pll_num++) {
 231                        pll_status = in_be32(&srds_regs->bank[pll_num].pllcr0);
 232                        debug("A007186: pll_num=%x pllcr0=%x\n",
 233                              pll_num, pll_status);
 234                        /* STEP 1 */
 235                        /* Read factory pre-set SerDes calibration values
 236                         * from fuse block(SFP scratch register-sfp_spfr0)
 237                         */
 238                        switch (pll_status & SRDS_PLLCR0_FRATE_SEL_MASK) {
 239                        case SRDS_PLLCR0_FRATE_SEL_3_0:
 240                        case SRDS_PLLCR0_FRATE_SEL_3_072:
 241                                debug("A007186: 3.0/3.072 protocol rate\n");
 242                                bc = (sfp_spfr0 >> BC1_SHIFT) & BC_MASK;
 243                                dc = (sfp_spfr0 >> DC1_SHIFT) & DC_MASK;
 244                                fc = (sfp_spfr0 >> FC1_SHIFT) & FC_MASK;
 245                                break;
 246                        case SRDS_PLLCR0_FRATE_SEL_3_125:
 247                                debug("A007186: 3.125 protocol rate\n");
 248                                bc = (sfp_spfr0 >> BC2_SHIFT) & BC_MASK;
 249                                dc = (sfp_spfr0 >> DC2_SHIFT) & DC_MASK;
 250                                fc = (sfp_spfr0 >> FC2_SHIFT) & FC_MASK;
 251                                break;
 252                        case SRDS_PLLCR0_FRATE_SEL_3_75:
 253                                debug("A007186: 3.75 protocol rate\n");
 254                                bc = (sfp_spfr0 >> BC1_SHIFT) & BC_MASK;
 255                                dc = (sfp_spfr0 >> DC1_SHIFT) & DC_MASK;
 256                                fc = (sfp_spfr0 >> FC1_SHIFT) & FC_MASK;
 257                                break;
 258                        default:
 259                                continue;
 260                        }
 261
 262                        /* STEP 2 */
 263                        /* Write SRDSxPLLnCR1[11:16] = FC
 264                         * Write SRDSxPLLnCR1[2] = BC
 265                         */
 266                        pll_cr1 = in_be32(&srds_regs->bank[pll_num].pllcr1);
 267                        pll_cr_upd = (((bc << CR1_BCAP_SHIFT) & BCAP_MASK) |
 268                                      ((fc << CR1_FCAP_SHIFT) & FCAP_MASK));
 269                        out_be32(&srds_regs->bank[pll_num].pllcr1,
 270                                 (pll_cr_upd | pll_cr1));
 271                        debug("A007186: pll_num=%x Updated PLLCR1=%x\n",
 272                              pll_num, (pll_cr_upd | pll_cr1));
 273                        /* Write SRDSxPLLnCR0[24:26] = DC
 274                         */
 275                        pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
 276                        out_be32(&srds_regs->bank[pll_num].pllcr0,
 277                                 pll_cr0 | (dc << CR0_DCBIAS_SHIFT));
 278                        debug("A007186: pll_num=%x, Updated PLLCR0=%x\n",
 279                              pll_num, (pll_cr0 | (dc << CR0_DCBIAS_SHIFT)));
 280                        /* Write SRDSxPLLnCR1[3] = 1
 281                         * Write SRDSxPLLnCR1[6] = 1
 282                         */
 283                        pll_cr1 = in_be32(&srds_regs->bank[pll_num].pllcr1);
 284                        pll_cr_upd = (BCAP_OVD_MASK | BYP_CAL_MASK);
 285                        out_be32(&srds_regs->bank[pll_num].pllcr1,
 286                                 (pll_cr_upd | pll_cr1));
 287                        debug("A007186: pll_num=%x Updated PLLCR1=%x\n",
 288                              pll_num, (pll_cr_upd | pll_cr1));
 289
 290                        /* STEP 3 */
 291                        /* Read the status Registers */
 292                        /* Verify SRDSxPLLnSR2[8] = BC */
 293                        pll_sr2 = in_be32(&srds_regs->bank[pll_num].pllsr2);
 294                        debug("A007186: pll_num=%x pllsr2=%x\n",
 295                              pll_num, pll_sr2);
 296                        bc_status = (pll_sr2 >> 23) & BC_MASK;
 297                        if (bc_status != bc)
 298                                debug("BC mismatch\n");
 299                        fc_status = (pll_sr2 >> 16) & FC_MASK;
 300                        if (fc_status != fc)
 301                                debug("FC mismatch\n");
 302                        pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
 303                        out_be32(&srds_regs->bank[pll_num].pllcr0, pll_cr0 |
 304                                                                0x02000000);
 305                        pll_sr2 = in_be32(&srds_regs->bank[pll_num].pllsr2);
 306                        dc_status = (pll_sr2 >> 17) & DC_MASK;
 307                        if (dc_status != dc)
 308                                debug("DC mismatch\n");
 309                        pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
 310                        out_be32(&srds_regs->bank[pll_num].pllcr0, pll_cr0 &
 311                                                                0xfdffffff);
 312
 313                        /* STEP 4 */
 314                        /* Wait 750us to verify the PLL is locked
 315                         * by checking SRDSxPLLnCR0[8] = 1.
 316                         */
 317                        udelay(750);
 318                        pll_status = in_be32(&srds_regs->bank[pll_num].pllcr0);
 319                        debug("A007186: pll_num=%x pllcr0=%x\n",
 320                              pll_num, pll_status);
 321
 322                        if ((pll_status & SRDS_PLLCR0_PLL_LCK) == 0)
 323                                printf("A007186 Serdes PLL not locked\n");
 324                        else
 325                                debug("A007186 Serdes PLL locked\n");
 326                }
 327        }
 328#endif
 329
 330        cfg >>= sd_prctl_shift;
 331        printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
 332        if (!is_serdes_prtcl_valid(sd, cfg))
 333                printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
 334
 335        for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
 336                enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
 337                if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
 338                        debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
 339                else
 340                        serdes_prtcl_map[lane_prtcl] = 1;
 341        }
 342
 343        /* Set the first element to indicate serdes has been initialized */
 344        serdes_prtcl_map[NONE] = 1;
 345}
 346
 347void fsl_serdes_init(void)
 348{
 349
 350#ifdef CONFIG_SYS_FSL_SRDS_1
 351        serdes_init(FSL_SRDS_1,
 352                    CONFIG_SYS_FSL_CORENET_SERDES_ADDR,
 353                    FSL_CORENET2_RCWSR4_SRDS1_PRTCL,
 354                    FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT,
 355                    serdes1_prtcl_map);
 356#endif
 357#ifdef CONFIG_SYS_FSL_SRDS_2
 358        serdes_init(FSL_SRDS_2,
 359                    CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_2 * 0x1000,
 360                    FSL_CORENET2_RCWSR4_SRDS2_PRTCL,
 361                    FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT,
 362                    serdes2_prtcl_map);
 363#endif
 364#ifdef CONFIG_SYS_FSL_SRDS_3
 365        serdes_init(FSL_SRDS_3,
 366                    CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_3 * 0x1000,
 367                    FSL_CORENET2_RCWSR4_SRDS3_PRTCL,
 368                    FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT,
 369                    serdes3_prtcl_map);
 370#endif
 371#ifdef CONFIG_SYS_FSL_SRDS_4
 372        serdes_init(FSL_SRDS_4,
 373                    CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_4 * 0x1000,
 374                    FSL_CORENET2_RCWSR4_SRDS4_PRTCL,
 375                    FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT,
 376                    serdes4_prtcl_map);
 377#endif
 378
 379}
 380
 381const char *serdes_clock_to_string(u32 clock)
 382{
 383        switch (clock) {
 384        case SRDS_PLLCR0_RFCK_SEL_100:
 385                return "100";
 386        case SRDS_PLLCR0_RFCK_SEL_125:
 387                return "125";
 388        case SRDS_PLLCR0_RFCK_SEL_156_25:
 389                return "156.25";
 390        case SRDS_PLLCR0_RFCK_SEL_161_13:
 391                return "161.1328123";
 392        default:
 393#if defined(CONFIG_TARGET_T4240QDS) || defined(CONFIG_TARGET_T4160QDS)
 394                return "???";
 395#else
 396                return "122.88";
 397#endif
 398        }
 399}
 400
 401