fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)
[linux-2.6-microblaze.git] / drivers / net / pcs / pcs-xpcs-nxp.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright 2021 NXP Semiconductors
3  */
4 #include <linux/pcs/pcs-xpcs.h>
5 #include "pcs-xpcs.h"
6
7 /* LANE_DRIVER1_0 register */
8 #define SJA1110_LANE_DRIVER1_0          0x8038
9 #define SJA1110_TXDRV(x)                (((x) << 12) & GENMASK(14, 12))
10
11 /* LANE_DRIVER2_0 register */
12 #define SJA1110_LANE_DRIVER2_0          0x803a
13 #define SJA1110_TXDRVTRIM_LSB(x)        ((x) & GENMASK_ULL(15, 0))
14
15 /* LANE_DRIVER2_1 register */
16 #define SJA1110_LANE_DRIVER2_1          0x803b
17 #define SJA1110_LANE_DRIVER2_1_RSV      BIT(9)
18 #define SJA1110_TXDRVTRIM_MSB(x)        (((x) & GENMASK_ULL(23, 16)) >> 16)
19
20 /* LANE_TRIM register */
21 #define SJA1110_LANE_TRIM               0x8040
22 #define SJA1110_TXTEN                   BIT(11)
23 #define SJA1110_TXRTRIM(x)              (((x) << 8) & GENMASK(10, 8))
24 #define SJA1110_TXPLL_BWSEL             BIT(7)
25 #define SJA1110_RXTEN                   BIT(6)
26 #define SJA1110_RXRTRIM(x)              (((x) << 3) & GENMASK(5, 3))
27 #define SJA1110_CDR_GAIN                BIT(2)
28 #define SJA1110_ACCOUPLE_RXVCM_EN       BIT(0)
29
30 /* LANE_DATAPATH_1 register */
31 #define SJA1110_LANE_DATAPATH_1         0x8037
32
33 /* POWERDOWN_ENABLE register */
34 #define SJA1110_POWERDOWN_ENABLE        0x8041
35 #define SJA1110_TXPLL_PD                BIT(12)
36 #define SJA1110_TXPD                    BIT(11)
37 #define SJA1110_RXPKDETEN               BIT(10)
38 #define SJA1110_RXCH_PD                 BIT(9)
39 #define SJA1110_RXBIAS_PD               BIT(8)
40 #define SJA1110_RESET_SER_EN            BIT(7)
41 #define SJA1110_RESET_SER               BIT(6)
42 #define SJA1110_RESET_DES               BIT(5)
43 #define SJA1110_RCVEN                   BIT(4)
44
45 /* RXPLL_CTRL0 register */
46 #define SJA1110_RXPLL_CTRL0             0x8065
47 #define SJA1110_RXPLL_FBDIV(x)          (((x) << 2) & GENMASK(9, 2))
48
49 /* RXPLL_CTRL1 register */
50 #define SJA1110_RXPLL_CTRL1             0x8066
51 #define SJA1110_RXPLL_REFDIV(x)         ((x) & GENMASK(4, 0))
52
53 /* TXPLL_CTRL0 register */
54 #define SJA1110_TXPLL_CTRL0             0x806d
55 #define SJA1110_TXPLL_FBDIV(x)          ((x) & GENMASK(11, 0))
56
57 /* TXPLL_CTRL1 register */
58 #define SJA1110_TXPLL_CTRL1             0x806e
59 #define SJA1110_TXPLL_REFDIV(x)         ((x) & GENMASK(5, 0))
60
61 /* RX_DATA_DETECT register */
62 #define SJA1110_RX_DATA_DETECT          0x8045
63
64 /* RX_CDR_CTLE register */
65 #define SJA1110_RX_CDR_CTLE             0x8042
66
67 /* In NXP SJA1105, the PCS is integrated with a PMA that has the TX lane
68  * polarity inverted by default (PLUS is MINUS, MINUS is PLUS). To obtain
69  * normal non-inverted behavior, the TX lane polarity must be inverted in the
70  * PCS, via the DIGITAL_CONTROL_2 register.
71  */
72 int nxp_sja1105_sgmii_pma_config(struct dw_xpcs *xpcs)
73 {
74         return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL2,
75                           DW_VR_MII_DIG_CTRL2_TX_POL_INV);
76 }
77
78 static int nxp_sja1110_pma_config(struct dw_xpcs *xpcs,
79                                   u16 txpll_fbdiv, u16 txpll_refdiv,
80                                   u16 rxpll_fbdiv, u16 rxpll_refdiv,
81                                   u16 rx_cdr_ctle)
82 {
83         u16 val;
84         int ret;
85
86         /* Program TX PLL feedback divider and reference divider settings for
87          * correct oscillation frequency.
88          */
89         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_TXPLL_CTRL0,
90                          SJA1110_TXPLL_FBDIV(txpll_fbdiv));
91         if (ret < 0)
92                 return ret;
93
94         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_TXPLL_CTRL1,
95                          SJA1110_TXPLL_REFDIV(txpll_refdiv));
96         if (ret < 0)
97                 return ret;
98
99         /* Program transmitter amplitude and disable amplitude trimming */
100         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_DRIVER1_0,
101                          SJA1110_TXDRV(0x5));
102         if (ret < 0)
103                 return ret;
104
105         val = SJA1110_TXDRVTRIM_LSB(0xffffffull);
106
107         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_DRIVER2_0, val);
108         if (ret < 0)
109                 return ret;
110
111         val = SJA1110_TXDRVTRIM_MSB(0xffffffull) | SJA1110_LANE_DRIVER2_1_RSV;
112
113         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_DRIVER2_1, val);
114         if (ret < 0)
115                 return ret;
116
117         /* Enable input and output resistor terminations for low BER. */
118         val = SJA1110_ACCOUPLE_RXVCM_EN | SJA1110_CDR_GAIN |
119               SJA1110_RXRTRIM(4) | SJA1110_RXTEN | SJA1110_TXPLL_BWSEL |
120               SJA1110_TXRTRIM(3) | SJA1110_TXTEN;
121
122         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_TRIM, val);
123         if (ret < 0)
124                 return ret;
125
126         /* Select PCS as transmitter data source. */
127         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_DATAPATH_1, 0);
128         if (ret < 0)
129                 return ret;
130
131         /* Program RX PLL feedback divider and reference divider for correct
132          * oscillation frequency.
133          */
134         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_RXPLL_CTRL0,
135                          SJA1110_RXPLL_FBDIV(rxpll_fbdiv));
136         if (ret < 0)
137                 return ret;
138
139         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_RXPLL_CTRL1,
140                          SJA1110_RXPLL_REFDIV(rxpll_refdiv));
141         if (ret < 0)
142                 return ret;
143
144         /* Program threshold for receiver signal detector.
145          * Enable control of RXPLL by receiver signal detector to disable RXPLL
146          * when an input signal is not present.
147          */
148         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_RX_DATA_DETECT, 0x0005);
149         if (ret < 0)
150                 return ret;
151
152         /* Enable TX and RX PLLs and circuits.
153          * Release reset of PMA to enable data flow to/from PCS.
154          */
155         ret = xpcs_read(xpcs, MDIO_MMD_VEND2, SJA1110_POWERDOWN_ENABLE);
156         if (ret < 0)
157                 return ret;
158
159         val = ret & ~(SJA1110_TXPLL_PD | SJA1110_TXPD | SJA1110_RXCH_PD |
160                       SJA1110_RXBIAS_PD | SJA1110_RESET_SER_EN |
161                       SJA1110_RESET_SER | SJA1110_RESET_DES);
162         val |= SJA1110_RXPKDETEN | SJA1110_RCVEN;
163
164         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_POWERDOWN_ENABLE, val);
165         if (ret < 0)
166                 return ret;
167
168         /* Program continuous-time linear equalizer (CTLE) settings. */
169         ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_RX_CDR_CTLE,
170                          rx_cdr_ctle);
171         if (ret < 0)
172                 return ret;
173
174         return 0;
175 }
176
177 int nxp_sja1110_sgmii_pma_config(struct dw_xpcs *xpcs)
178 {
179         return nxp_sja1110_pma_config(xpcs, 0x19, 0x1, 0x19, 0x1, 0x212a);
180 }
181
182 int nxp_sja1110_2500basex_pma_config(struct dw_xpcs *xpcs)
183 {
184         return nxp_sja1110_pma_config(xpcs, 0x7d, 0x2, 0x7d, 0x2, 0x732a);
185 }