Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
0003  */
0004 
0005 /* Qualcomm Technologies, Inc. QDF2400 EMAC SGMII Controller driver.
0006  */
0007 
0008 #include <linux/iopoll.h>
0009 #include "emac.h"
0010 
0011 /* EMAC_SGMII register offsets */
0012 #define EMAC_SGMII_PHY_TX_PWR_CTRL      0x000C
0013 #define EMAC_SGMII_PHY_LANE_CTRL1       0x0018
0014 #define EMAC_SGMII_PHY_CDR_CTRL0        0x0058
0015 #define EMAC_SGMII_PHY_POW_DWN_CTRL0        0x0080
0016 #define EMAC_SGMII_PHY_RESET_CTRL       0x00a8
0017 #define EMAC_SGMII_PHY_INTERRUPT_MASK       0x00b4
0018 
0019 /* SGMII digital lane registers */
0020 #define EMAC_SGMII_LN_DRVR_CTRL0        0x000C
0021 #define EMAC_SGMII_LN_DRVR_CTRL1        0x0010
0022 #define EMAC_SGMII_LN_DRVR_TAP_EN       0x0018
0023 #define EMAC_SGMII_LN_TX_MARGINING      0x001C
0024 #define EMAC_SGMII_LN_TX_PRE            0x0020
0025 #define EMAC_SGMII_LN_TX_POST           0x0024
0026 #define EMAC_SGMII_LN_TX_BAND_MODE      0x0060
0027 #define EMAC_SGMII_LN_LANE_MODE         0x0064
0028 #define EMAC_SGMII_LN_PARALLEL_RATE     0x007C
0029 #define EMAC_SGMII_LN_CML_CTRL_MODE0        0x00C0
0030 #define EMAC_SGMII_LN_MIXER_CTRL_MODE0      0x00D8
0031 #define EMAC_SGMII_LN_VGA_INITVAL       0x013C
0032 #define EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0    0x0184
0033 #define EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0    0x0190
0034 #define EMAC_SGMII_LN_UCDR_SO_CONFIG        0x019C
0035 #define EMAC_SGMII_LN_RX_BAND           0x01A4
0036 #define EMAC_SGMII_LN_RX_RCVR_PATH1_MODE0   0x01C0
0037 #define EMAC_SGMII_LN_RSM_CONFIG        0x01F8
0038 #define EMAC_SGMII_LN_SIGDET_ENABLES        0x0230
0039 #define EMAC_SGMII_LN_SIGDET_CNTRL      0x0234
0040 #define EMAC_SGMII_LN_SIGDET_DEGLITCH_CNTRL 0x0238
0041 #define EMAC_SGMII_LN_RX_EN_SIGNAL      0x02AC
0042 #define EMAC_SGMII_LN_RX_MISC_CNTRL0        0x02B8
0043 #define EMAC_SGMII_LN_DRVR_LOGIC_CLKDIV     0x02C8
0044 #define EMAC_SGMII_LN_RX_RESECODE_OFFSET    0x02CC
0045 
0046 /* SGMII digital lane register values */
0047 #define UCDR_STEP_BY_TWO_MODE0          BIT(7)
0048 #define UCDR_xO_GAIN_MODE(x)            ((x) & 0x7f)
0049 #define UCDR_ENABLE             BIT(6)
0050 #define UCDR_SO_SATURATION(x)           ((x) & 0x3f)
0051 
0052 #define SIGDET_LP_BYP_PS4           BIT(7)
0053 #define SIGDET_EN_PS0_TO_PS2            BIT(6)
0054 
0055 #define TXVAL_VALID_INIT            BIT(4)
0056 #define KR_PCIGEN3_MODE             BIT(0)
0057 
0058 #define MAIN_EN                 BIT(0)
0059 
0060 #define TX_MARGINING_MUX            BIT(6)
0061 #define TX_MARGINING(x)             ((x) & 0x3f)
0062 
0063 #define TX_PRE_MUX              BIT(6)
0064 
0065 #define TX_POST_MUX             BIT(6)
0066 
0067 #define CML_GEAR_MODE(x)            (((x) & 7) << 3)
0068 #define CML2CMOS_IBOOST_MODE(x)         ((x) & 7)
0069 
0070 #define RESCODE_OFFSET(x)           ((x) & 0x1f)
0071 
0072 #define MIXER_LOADB_MODE(x)         (((x) & 0xf) << 2)
0073 #define MIXER_DATARATE_MODE(x)          ((x) & 3)
0074 
0075 #define VGA_THRESH_DFE(x)           ((x) & 0x3f)
0076 
0077 #define SIGDET_LP_BYP_PS0_TO_PS2        BIT(5)
0078 #define SIGDET_FLT_BYP              BIT(0)
0079 
0080 #define SIGDET_LVL(x)               (((x) & 0xf) << 4)
0081 
0082 #define SIGDET_DEGLITCH_CTRL(x)         (((x) & 0xf) << 1)
0083 
0084 #define INVERT_PCS_RX_CLK           BIT(7)
0085 
0086 #define DRVR_LOGIC_CLK_EN           BIT(4)
0087 #define DRVR_LOGIC_CLK_DIV(x)           ((x) & 0xf)
0088 
0089 #define PARALLEL_RATE_MODE0(x)          ((x) & 0x3)
0090 
0091 #define BAND_MODE0(x)               ((x) & 0x3)
0092 
0093 #define LANE_MODE(x)                ((x) & 0x1f)
0094 
0095 #define CDR_PD_SEL_MODE0(x)         (((x) & 0x3) << 5)
0096 #define EN_DLL_MODE0                BIT(4)
0097 #define EN_IQ_DCC_MODE0             BIT(3)
0098 #define EN_IQCAL_MODE0              BIT(2)
0099 
0100 #define BYPASS_RSM_SAMP_CAL         BIT(1)
0101 #define BYPASS_RSM_DLL_CAL          BIT(0)
0102 
0103 #define L0_RX_EQUALIZE_ENABLE           BIT(6)
0104 
0105 #define PWRDN_B                 BIT(0)
0106 
0107 #define CDR_MAX_CNT(x)              ((x) & 0xff)
0108 
0109 #define SERDES_START_WAIT_TIMES         100
0110 
0111 struct emac_reg_write {
0112     unsigned int offset;
0113     u32 val;
0114 };
0115 
0116 static void emac_reg_write_all(void __iomem *base,
0117                    const struct emac_reg_write *itr, size_t size)
0118 {
0119     size_t i;
0120 
0121     for (i = 0; i < size; ++itr, ++i)
0122         writel(itr->val, base + itr->offset);
0123 }
0124 
0125 static const struct emac_reg_write sgmii_laned[] = {
0126     /* CDR Settings */
0127     {EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0,
0128         UCDR_STEP_BY_TWO_MODE0 | UCDR_xO_GAIN_MODE(10)},
0129     {EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0, UCDR_xO_GAIN_MODE(0)},
0130     {EMAC_SGMII_LN_UCDR_SO_CONFIG, UCDR_ENABLE | UCDR_SO_SATURATION(12)},
0131 
0132     /* TX/RX Settings */
0133     {EMAC_SGMII_LN_RX_EN_SIGNAL, SIGDET_LP_BYP_PS4 | SIGDET_EN_PS0_TO_PS2},
0134 
0135     {EMAC_SGMII_LN_DRVR_CTRL0, TXVAL_VALID_INIT | KR_PCIGEN3_MODE},
0136     {EMAC_SGMII_LN_DRVR_TAP_EN, MAIN_EN},
0137     {EMAC_SGMII_LN_TX_MARGINING, TX_MARGINING_MUX | TX_MARGINING(25)},
0138     {EMAC_SGMII_LN_TX_PRE, TX_PRE_MUX},
0139     {EMAC_SGMII_LN_TX_POST, TX_POST_MUX},
0140 
0141     {EMAC_SGMII_LN_CML_CTRL_MODE0,
0142         CML_GEAR_MODE(1) | CML2CMOS_IBOOST_MODE(1)},
0143     {EMAC_SGMII_LN_MIXER_CTRL_MODE0,
0144         MIXER_LOADB_MODE(12) | MIXER_DATARATE_MODE(1)},
0145     {EMAC_SGMII_LN_VGA_INITVAL, VGA_THRESH_DFE(31)},
0146     {EMAC_SGMII_LN_SIGDET_ENABLES,
0147         SIGDET_LP_BYP_PS0_TO_PS2 | SIGDET_FLT_BYP},
0148     {EMAC_SGMII_LN_SIGDET_CNTRL, SIGDET_LVL(8)},
0149 
0150     {EMAC_SGMII_LN_SIGDET_DEGLITCH_CNTRL, SIGDET_DEGLITCH_CTRL(4)},
0151     {EMAC_SGMII_LN_RX_MISC_CNTRL0, INVERT_PCS_RX_CLK},
0152     {EMAC_SGMII_LN_DRVR_LOGIC_CLKDIV,
0153         DRVR_LOGIC_CLK_EN | DRVR_LOGIC_CLK_DIV(4)},
0154 
0155     {EMAC_SGMII_LN_PARALLEL_RATE, PARALLEL_RATE_MODE0(1)},
0156     {EMAC_SGMII_LN_TX_BAND_MODE, BAND_MODE0(1)},
0157     {EMAC_SGMII_LN_RX_BAND, BAND_MODE0(2)},
0158     {EMAC_SGMII_LN_DRVR_CTRL1, RESCODE_OFFSET(7)},
0159     {EMAC_SGMII_LN_RX_RESECODE_OFFSET, RESCODE_OFFSET(9)},
0160     {EMAC_SGMII_LN_LANE_MODE, LANE_MODE(26)},
0161     {EMAC_SGMII_LN_RX_RCVR_PATH1_MODE0, CDR_PD_SEL_MODE0(2) |
0162         EN_DLL_MODE0 | EN_IQ_DCC_MODE0 | EN_IQCAL_MODE0},
0163     {EMAC_SGMII_LN_RSM_CONFIG, BYPASS_RSM_SAMP_CAL | BYPASS_RSM_DLL_CAL},
0164 };
0165 
0166 static const struct emac_reg_write physical_coding_sublayer_programming[] = {
0167     {EMAC_SGMII_PHY_POW_DWN_CTRL0, PWRDN_B},
0168     {EMAC_SGMII_PHY_CDR_CTRL0, CDR_MAX_CNT(15)},
0169     {EMAC_SGMII_PHY_TX_PWR_CTRL, 0},
0170     {EMAC_SGMII_PHY_LANE_CTRL1, L0_RX_EQUALIZE_ENABLE},
0171 };
0172 
0173 int emac_sgmii_init_qdf2400(struct emac_adapter *adpt)
0174 {
0175     struct emac_sgmii *phy = &adpt->phy;
0176     void __iomem *phy_regs = phy->base;
0177     void __iomem *laned = phy->digital;
0178     unsigned int i;
0179     u32 lnstatus;
0180 
0181     /* PCS lane-x init */
0182     emac_reg_write_all(phy->base, physical_coding_sublayer_programming,
0183                ARRAY_SIZE(physical_coding_sublayer_programming));
0184 
0185     /* SGMII lane-x init */
0186     emac_reg_write_all(phy->digital, sgmii_laned, ARRAY_SIZE(sgmii_laned));
0187 
0188     /* Power up PCS and start reset lane state machine */
0189 
0190     writel(0, phy_regs + EMAC_SGMII_PHY_RESET_CTRL);
0191     writel(1, laned + SGMII_LN_RSM_START);
0192 
0193     /* Wait for c_ready assertion */
0194     for (i = 0; i < SERDES_START_WAIT_TIMES; i++) {
0195         lnstatus = readl(phy_regs + SGMII_PHY_LN_LANE_STATUS);
0196         if (lnstatus & BIT(1))
0197             break;
0198         usleep_range(100, 200);
0199     }
0200 
0201     if (i == SERDES_START_WAIT_TIMES) {
0202         netdev_err(adpt->netdev, "SGMII failed to start\n");
0203         return -EIO;
0204     }
0205 
0206     /* Disable digital and SERDES loopback */
0207     writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN0);
0208     writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN2);
0209     writel(0, phy_regs + SGMII_PHY_LN_CDR_CTRL1);
0210 
0211     /* Mask out all the SGMII Interrupt */
0212     writel(0, phy_regs + EMAC_SGMII_PHY_INTERRUPT_MASK);
0213 
0214     return 0;
0215 }