1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2018 Marvell |
4 | * |
5 | * Authors: |
6 | * Evan Wang <xswang@marvell.com> |
7 | * Miquèl Raynal <miquel.raynal@bootlin.com> |
8 | * Pali Rohár <pali@kernel.org> |
9 | * Marek Behún <kabel@kernel.org> |
10 | * |
11 | * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart. |
12 | * Comphy code from ARM Trusted Firmware ported by Pali Rohár <pali@kernel.org> |
13 | * and Marek Behún <kabel@kernel.org>. |
14 | */ |
15 | |
16 | #include <linux/bitfield.h> |
17 | #include <linux/clk.h> |
18 | #include <linux/io.h> |
19 | #include <linux/iopoll.h> |
20 | #include <linux/mfd/syscon.h> |
21 | #include <linux/module.h> |
22 | #include <linux/of.h> |
23 | #include <linux/phy.h> |
24 | #include <linux/phy/phy.h> |
25 | #include <linux/platform_device.h> |
26 | #include <linux/spinlock.h> |
27 | |
28 | #define PLL_SET_DELAY_US 600 |
29 | #define COMPHY_PLL_SLEEP 1000 |
30 | #define COMPHY_PLL_TIMEOUT 150000 |
31 | |
32 | /* Comphy lane2 indirect access register offset */ |
33 | #define COMPHY_LANE2_INDIR_ADDR 0x0 |
34 | #define COMPHY_LANE2_INDIR_DATA 0x4 |
35 | |
36 | /* SATA and USB3 PHY offset compared to SATA PHY */ |
37 | #define COMPHY_LANE2_REGS_BASE 0x200 |
38 | |
39 | /* |
40 | * When accessing common PHY lane registers directly, we need to shift by 1, |
41 | * since the registers are 16-bit. |
42 | */ |
43 | #define COMPHY_LANE_REG_DIRECT(reg) (((reg) & 0x7FF) << 1) |
44 | |
45 | /* COMPHY registers */ |
46 | #define COMPHY_POWER_PLL_CTRL 0x01 |
47 | #define PU_IVREF_BIT BIT(15) |
48 | #define PU_PLL_BIT BIT(14) |
49 | #define PU_RX_BIT BIT(13) |
50 | #define PU_TX_BIT BIT(12) |
51 | #define PU_TX_INTP_BIT BIT(11) |
52 | #define PU_DFE_BIT BIT(10) |
53 | #define RESET_DTL_RX_BIT BIT(9) |
54 | #define PLL_LOCK_BIT BIT(8) |
55 | #define REF_FREF_SEL_MASK GENMASK(4, 0) |
56 | #define REF_FREF_SEL_SERDES_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x1) |
57 | #define REF_FREF_SEL_SERDES_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3) |
58 | #define REF_FREF_SEL_SERDES_50MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x4) |
59 | #define REF_FREF_SEL_PCIE_USB3_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x2) |
60 | #define REF_FREF_SEL_PCIE_USB3_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3) |
61 | #define COMPHY_MODE_MASK GENMASK(7, 5) |
62 | #define COMPHY_MODE_SATA FIELD_PREP(COMPHY_MODE_MASK, 0x0) |
63 | #define COMPHY_MODE_PCIE FIELD_PREP(COMPHY_MODE_MASK, 0x3) |
64 | #define COMPHY_MODE_SERDES FIELD_PREP(COMPHY_MODE_MASK, 0x4) |
65 | #define COMPHY_MODE_USB3 FIELD_PREP(COMPHY_MODE_MASK, 0x5) |
66 | |
67 | #define COMPHY_KVCO_CAL_CTRL 0x02 |
68 | #define USE_MAX_PLL_RATE_BIT BIT(12) |
69 | #define SPEED_PLL_MASK GENMASK(7, 2) |
70 | #define SPEED_PLL_VALUE_16 FIELD_PREP(SPEED_PLL_MASK, 0x10) |
71 | |
72 | #define COMPHY_DIG_LOOPBACK_EN 0x23 |
73 | #define SEL_DATA_WIDTH_MASK GENMASK(11, 10) |
74 | #define DATA_WIDTH_10BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x0) |
75 | #define DATA_WIDTH_20BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x1) |
76 | #define DATA_WIDTH_40BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x2) |
77 | #define PLL_READY_TX_BIT BIT(4) |
78 | |
79 | #define COMPHY_SYNC_PATTERN 0x24 |
80 | #define TXD_INVERT_BIT BIT(10) |
81 | #define RXD_INVERT_BIT BIT(11) |
82 | |
83 | #define COMPHY_SYNC_MASK_GEN 0x25 |
84 | #define PHY_GEN_MAX_MASK GENMASK(11, 10) |
85 | #define PHY_GEN_MAX_USB3_5G FIELD_PREP(PHY_GEN_MAX_MASK, 0x1) |
86 | |
87 | #define COMPHY_ISOLATION_CTRL 0x26 |
88 | #define PHY_ISOLATE_MODE BIT(15) |
89 | |
90 | #define COMPHY_GEN2_SET2 0x3e |
91 | #define GS2_TX_SSC_AMP_MASK GENMASK(15, 9) |
92 | #define GS2_TX_SSC_AMP_4128 FIELD_PREP(GS2_TX_SSC_AMP_MASK, 0x20) |
93 | #define GS2_VREG_RXTX_MAS_ISET_MASK GENMASK(8, 7) |
94 | #define GS2_VREG_RXTX_MAS_ISET_60U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ |
95 | 0x0) |
96 | #define GS2_VREG_RXTX_MAS_ISET_80U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ |
97 | 0x1) |
98 | #define GS2_VREG_RXTX_MAS_ISET_100U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ |
99 | 0x2) |
100 | #define GS2_VREG_RXTX_MAS_ISET_120U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ |
101 | 0x3) |
102 | #define GS2_RSVD_6_0_MASK GENMASK(6, 0) |
103 | |
104 | #define COMPHY_GEN3_SET2 0x3f |
105 | |
106 | #define COMPHY_IDLE_SYNC_EN 0x48 |
107 | #define IDLE_SYNC_EN BIT(12) |
108 | |
109 | #define COMPHY_MISC_CTRL0 0x4F |
110 | #define CLK100M_125M_EN BIT(4) |
111 | #define TXDCLK_2X_SEL BIT(6) |
112 | #define CLK500M_EN BIT(7) |
113 | #define PHY_REF_CLK_SEL BIT(10) |
114 | |
115 | #define COMPHY_SFT_RESET 0x52 |
116 | #define SFT_RST BIT(9) |
117 | #define SFT_RST_NO_REG BIT(10) |
118 | |
119 | #define COMPHY_MISC_CTRL1 0x73 |
120 | #define SEL_BITS_PCIE_FORCE BIT(15) |
121 | |
122 | #define COMPHY_GEN2_SET3 0x112 |
123 | #define GS3_FFE_CAP_SEL_MASK GENMASK(3, 0) |
124 | #define GS3_FFE_CAP_SEL_VALUE FIELD_PREP(GS3_FFE_CAP_SEL_MASK, 0xF) |
125 | |
126 | /* PIPE registers */ |
127 | #define COMPHY_PIPE_LANE_CFG0 0x180 |
128 | #define PRD_TXDEEMPH0_MASK BIT(0) |
129 | #define PRD_TXMARGIN_MASK GENMASK(3, 1) |
130 | #define PRD_TXSWING_MASK BIT(4) |
131 | #define CFG_TX_ALIGN_POS_MASK GENMASK(8, 5) |
132 | |
133 | #define COMPHY_PIPE_LANE_CFG1 0x181 |
134 | #define PRD_TXDEEMPH1_MASK BIT(15) |
135 | #define USE_MAX_PLL_RATE_EN BIT(9) |
136 | #define TX_DET_RX_MODE BIT(6) |
137 | #define GEN2_TX_DATA_DLY_MASK GENMASK(4, 3) |
138 | #define GEN2_TX_DATA_DLY_DEFT FIELD_PREP(GEN2_TX_DATA_DLY_MASK, 2) |
139 | #define TX_ELEC_IDLE_MODE_EN BIT(0) |
140 | |
141 | #define COMPHY_PIPE_LANE_STAT1 0x183 |
142 | #define TXDCLK_PCLK_EN BIT(0) |
143 | |
144 | #define COMPHY_PIPE_LANE_CFG4 0x188 |
145 | #define SPREAD_SPECTRUM_CLK_EN BIT(7) |
146 | |
147 | #define COMPHY_PIPE_RST_CLK_CTRL 0x1C1 |
148 | #define PIPE_SOFT_RESET BIT(0) |
149 | #define PIPE_REG_RESET BIT(1) |
150 | #define MODE_CORE_CLK_FREQ_SEL BIT(9) |
151 | #define MODE_PIPE_WIDTH_32 BIT(3) |
152 | #define MODE_REFDIV_MASK GENMASK(5, 4) |
153 | #define MODE_REFDIV_BY_4 FIELD_PREP(MODE_REFDIV_MASK, 0x2) |
154 | |
155 | #define COMPHY_PIPE_TEST_MODE_CTRL 0x1C2 |
156 | #define MODE_MARGIN_OVERRIDE BIT(2) |
157 | |
158 | #define COMPHY_PIPE_CLK_SRC_LO 0x1C3 |
159 | #define MODE_CLK_SRC BIT(0) |
160 | #define BUNDLE_PERIOD_SEL BIT(1) |
161 | #define BUNDLE_PERIOD_SCALE_MASK GENMASK(3, 2) |
162 | #define BUNDLE_SAMPLE_CTRL BIT(4) |
163 | #define PLL_READY_DLY_MASK GENMASK(7, 5) |
164 | #define CFG_SEL_20B BIT(15) |
165 | |
166 | #define COMPHY_PIPE_PWR_MGM_TIM1 0x1D0 |
167 | #define CFG_PM_OSCCLK_WAIT_MASK GENMASK(15, 12) |
168 | #define CFG_PM_RXDEN_WAIT_MASK GENMASK(11, 8) |
169 | #define CFG_PM_RXDEN_WAIT_1_UNIT FIELD_PREP(CFG_PM_RXDEN_WAIT_MASK, 0x1) |
170 | #define CFG_PM_RXDLOZ_WAIT_MASK GENMASK(7, 0) |
171 | #define CFG_PM_RXDLOZ_WAIT_7_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0x7) |
172 | #define CFG_PM_RXDLOZ_WAIT_12_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0xC) |
173 | |
174 | /* |
175 | * This register is not from PHY lane register space. It only exists in the |
176 | * indirect register space, before the actual PHY lane 2 registers. So the |
177 | * offset is absolute, not relative to COMPHY_LANE2_REGS_BASE. |
178 | * It is used only for SATA PHY initialization. |
179 | */ |
180 | #define COMPHY_RESERVED_REG 0x0E |
181 | #define PHYCTRL_FRM_PIN_BIT BIT(13) |
182 | |
183 | /* South Bridge PHY Configuration Registers */ |
184 | #define COMPHY_PHY_REG(lane, reg) (((1 - (lane)) * 0x28) + ((reg) & 0x3f)) |
185 | |
186 | /* |
187 | * lane0: USB3/GbE1 PHY Configuration 1 |
188 | * lane1: PCIe/GbE0 PHY Configuration 1 |
189 | * (used only by SGMII code) |
190 | */ |
191 | #define COMPHY_PHY_CFG1 0x0 |
192 | #define PIN_PU_IVREF_BIT BIT(1) |
193 | #define PIN_RESET_CORE_BIT BIT(11) |
194 | #define PIN_RESET_COMPHY_BIT BIT(12) |
195 | #define PIN_PU_PLL_BIT BIT(16) |
196 | #define PIN_PU_RX_BIT BIT(17) |
197 | #define PIN_PU_TX_BIT BIT(18) |
198 | #define PIN_TX_IDLE_BIT BIT(19) |
199 | #define GEN_RX_SEL_MASK GENMASK(25, 22) |
200 | #define GEN_RX_SEL_VALUE(val) FIELD_PREP(GEN_RX_SEL_MASK, (val)) |
201 | #define GEN_TX_SEL_MASK GENMASK(29, 26) |
202 | #define GEN_TX_SEL_VALUE(val) FIELD_PREP(GEN_TX_SEL_MASK, (val)) |
203 | #define SERDES_SPEED_1_25_G 0x6 |
204 | #define SERDES_SPEED_3_125_G 0x8 |
205 | #define PHY_RX_INIT_BIT BIT(30) |
206 | |
207 | /* |
208 | * lane0: USB3/GbE1 PHY Status 1 |
209 | * lane1: PCIe/GbE0 PHY Status 1 |
210 | * (used only by SGMII code) |
211 | */ |
212 | #define COMPHY_PHY_STAT1 0x18 |
213 | #define PHY_RX_INIT_DONE_BIT BIT(0) |
214 | #define PHY_PLL_READY_RX_BIT BIT(2) |
215 | #define PHY_PLL_READY_TX_BIT BIT(3) |
216 | |
217 | /* PHY Selector */ |
218 | #define COMPHY_SELECTOR_PHY_REG 0xFC |
219 | /* bit0: 0: Lane1 is GbE0; 1: Lane1 is PCIe */ |
220 | #define COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT BIT(0) |
221 | /* bit4: 0: Lane0 is GbE1; 1: Lane0 is USB3 */ |
222 | #define COMPHY_SELECTOR_USB3_GBE1_SEL_BIT BIT(4) |
223 | /* bit8: 0: Lane0 is USB3 instead of GbE1, Lane2 is SATA; 1: Lane2 is USB3 */ |
224 | #define COMPHY_SELECTOR_USB3_PHY_SEL_BIT BIT(8) |
225 | |
226 | struct mvebu_a3700_comphy_conf { |
227 | unsigned int lane; |
228 | enum phy_mode mode; |
229 | int submode; |
230 | }; |
231 | |
232 | #define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode) \ |
233 | { \ |
234 | .lane = _lane, \ |
235 | .mode = _mode, \ |
236 | .submode = _smode, \ |
237 | } |
238 | |
239 | #define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode) \ |
240 | MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA) |
241 | |
242 | #define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode) \ |
243 | MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode) |
244 | |
245 | static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { |
246 | /* lane 0 */ |
247 | MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS), |
248 | MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII), |
249 | MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_1000BASEX), |
250 | MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX), |
251 | /* lane 1 */ |
252 | MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE), |
253 | MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII), |
254 | MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_1000BASEX), |
255 | MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX), |
256 | /* lane 2 */ |
257 | MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA), |
258 | MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS), |
259 | }; |
260 | |
261 | struct mvebu_a3700_comphy_priv { |
262 | void __iomem *comphy_regs; |
263 | void __iomem *lane0_phy_regs; /* USB3 and GbE1 */ |
264 | void __iomem *lane1_phy_regs; /* PCIe and GbE0 */ |
265 | void __iomem *lane2_phy_indirect; /* SATA and USB3 */ |
266 | spinlock_t lock; /* for PHY selector access */ |
267 | bool xtal_is_40m; |
268 | }; |
269 | |
270 | struct mvebu_a3700_comphy_lane { |
271 | struct mvebu_a3700_comphy_priv *priv; |
272 | struct device *dev; |
273 | unsigned int id; |
274 | enum phy_mode mode; |
275 | int submode; |
276 | bool invert_tx; |
277 | bool invert_rx; |
278 | }; |
279 | |
280 | struct gbe_phy_init_data_fix { |
281 | u16 addr; |
282 | u16 value; |
283 | }; |
284 | |
285 | /* Changes to 40M1G25 mode data required for running 40M3G125 init mode */ |
286 | static struct gbe_phy_init_data_fix gbe_phy_init_fix[] = { |
287 | { 0x005, 0x07CC }, { 0x015, 0x0000 }, { 0x01B, 0x0000 }, |
288 | { 0x01D, 0x0000 }, { 0x01E, 0x0000 }, { 0x01F, 0x0000 }, |
289 | { 0x020, 0x0000 }, { 0x021, 0x0030 }, { 0x026, 0x0888 }, |
290 | { 0x04D, 0x0152 }, { 0x04F, 0xA020 }, { 0x050, 0x07CC }, |
291 | { 0x053, 0xE9CA }, { 0x055, 0xBD97 }, { 0x071, 0x3015 }, |
292 | { 0x076, 0x03AA }, { 0x07C, 0x0FDF }, { 0x0C2, 0x3030 }, |
293 | { 0x0C3, 0x8000 }, { 0x0E2, 0x5550 }, { 0x0E3, 0x12A4 }, |
294 | { 0x0E4, 0x7D00 }, { 0x0E6, 0x0C83 }, { 0x101, 0xFCC0 }, |
295 | { 0x104, 0x0C10 } |
296 | }; |
297 | |
298 | /* 40M1G25 mode init data */ |
299 | static u16 gbe_phy_init[512] = { |
300 | /* 0 1 2 3 4 5 6 7 */ |
301 | /*-----------------------------------------------------------*/ |
302 | /* 8 9 A B C D E F */ |
303 | 0x3110, 0xFD83, 0x6430, 0x412F, 0x82C0, 0x06FA, 0x4500, 0x6D26, /* 00 */ |
304 | 0xAFC0, 0x8000, 0xC000, 0x0000, 0x2000, 0x49CC, 0x0BC9, 0x2A52, /* 08 */ |
305 | 0x0BD2, 0x0CDE, 0x13D2, 0x0CE8, 0x1149, 0x10E0, 0x0000, 0x0000, /* 10 */ |
306 | 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x4134, 0x0D2D, 0xFFFF, /* 18 */ |
307 | 0xFFE0, 0x4030, 0x1016, 0x0030, 0x0000, 0x0800, 0x0866, 0x0000, /* 20 */ |
308 | 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, /* 28 */ |
309 | 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */ |
310 | 0x0000, 0x0000, 0x000F, 0x6A62, 0x1988, 0x3100, 0x3100, 0x3100, /* 38 */ |
311 | 0x3100, 0xA708, 0x2430, 0x0830, 0x1030, 0x4610, 0xFF00, 0xFF00, /* 40 */ |
312 | 0x0060, 0x1000, 0x0400, 0x0040, 0x00F0, 0x0155, 0x1100, 0xA02A, /* 48 */ |
313 | 0x06FA, 0x0080, 0xB008, 0xE3ED, 0x5002, 0xB592, 0x7A80, 0x0001, /* 50 */ |
314 | 0x020A, 0x8820, 0x6014, 0x8054, 0xACAA, 0xFC88, 0x2A02, 0x45CF, /* 58 */ |
315 | 0x000F, 0x1817, 0x2860, 0x064F, 0x0000, 0x0204, 0x1800, 0x6000, /* 60 */ |
316 | 0x810F, 0x4F23, 0x4000, 0x4498, 0x0850, 0x0000, 0x000E, 0x1002, /* 68 */ |
317 | 0x9D3A, 0x3009, 0xD066, 0x0491, 0x0001, 0x6AB0, 0x0399, 0x3780, /* 70 */ |
318 | 0x0040, 0x5AC0, 0x4A80, 0x0000, 0x01DF, 0x0000, 0x0007, 0x0000, /* 78 */ |
319 | 0x2D54, 0x00A1, 0x4000, 0x0100, 0xA20A, 0x0000, 0x0000, 0x0000, /* 80 */ |
320 | 0x0000, 0x0000, 0x0000, 0x7400, 0x0E81, 0x1000, 0x1242, 0x0210, /* 88 */ |
321 | 0x80DF, 0x0F1F, 0x2F3F, 0x4F5F, 0x6F7F, 0x0F1F, 0x2F3F, 0x4F5F, /* 90 */ |
322 | 0x6F7F, 0x4BAD, 0x0000, 0x0000, 0x0800, 0x0000, 0x2400, 0xB651, /* 98 */ |
323 | 0xC9E0, 0x4247, 0x0A24, 0x0000, 0xAF19, 0x1004, 0x0000, 0x0000, /* A0 */ |
324 | 0x0000, 0x0013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* A8 */ |
325 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* B0 */ |
326 | 0x0000, 0x0000, 0x0000, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, /* B8 */ |
327 | 0x0000, 0x0000, 0x3010, 0xFA00, 0x0000, 0x0000, 0x0000, 0x0003, /* C0 */ |
328 | 0x1618, 0x8200, 0x8000, 0x0400, 0x050F, 0x0000, 0x0000, 0x0000, /* C8 */ |
329 | 0x4C93, 0x0000, 0x1000, 0x1120, 0x0010, 0x1242, 0x1242, 0x1E00, /* D0 */ |
330 | 0x0000, 0x0000, 0x0000, 0x00F8, 0x0000, 0x0041, 0x0800, 0x0000, /* D8 */ |
331 | 0x82A0, 0x572E, 0x2490, 0x14A9, 0x4E00, 0x0000, 0x0803, 0x0541, /* E0 */ |
332 | 0x0C15, 0x0000, 0x0000, 0x0400, 0x2626, 0x0000, 0x0000, 0x4200, /* E8 */ |
333 | 0x0000, 0xAA55, 0x1020, 0x0000, 0x0000, 0x5010, 0x0000, 0x0000, /* F0 */ |
334 | 0x0000, 0x0000, 0x5000, 0x0000, 0x0000, 0x0000, 0x02F2, 0x0000, /* F8 */ |
335 | 0x101F, 0xFDC0, 0x4000, 0x8010, 0x0110, 0x0006, 0x0000, 0x0000, /*100 */ |
336 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*108 */ |
337 | 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04C6, 0x0000, /*110 */ |
338 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*118 */ |
339 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*120 */ |
340 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*128 */ |
341 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*130 */ |
342 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*138 */ |
343 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*140 */ |
344 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*148 */ |
345 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*150 */ |
346 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*158 */ |
347 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*160 */ |
348 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*168 */ |
349 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*170 */ |
350 | 0x0000, 0x0000, 0x0000, 0x00F0, 0x08A2, 0x3112, 0x0A14, 0x0000, /*178 */ |
351 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*180 */ |
352 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*188 */ |
353 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*190 */ |
354 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*198 */ |
355 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A0 */ |
356 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A8 */ |
357 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B0 */ |
358 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B8 */ |
359 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C0 */ |
360 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C8 */ |
361 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D0 */ |
362 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D8 */ |
363 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E0 */ |
364 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E8 */ |
365 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1F0 */ |
366 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /*1F8 */ |
367 | }; |
368 | |
369 | static inline void comphy_reg_set(void __iomem *addr, u32 data, u32 mask) |
370 | { |
371 | u32 val; |
372 | |
373 | val = readl(addr); |
374 | val = (val & ~mask) | (data & mask); |
375 | writel(val, addr); |
376 | } |
377 | |
378 | static inline void comphy_reg_set16(void __iomem *addr, u16 data, u16 mask) |
379 | { |
380 | u16 val; |
381 | |
382 | val = readw(addr); |
383 | val = (val & ~mask) | (data & mask); |
384 | writew(val, addr); |
385 | } |
386 | |
387 | /* Used for accessing lane 2 registers (SATA/USB3 PHY) */ |
388 | static void comphy_set_indirect(struct mvebu_a3700_comphy_priv *priv, |
389 | u32 offset, u16 data, u16 mask) |
390 | { |
391 | writel(val: offset, |
392 | addr: priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_ADDR); |
393 | comphy_reg_set(addr: priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_DATA, |
394 | data, mask); |
395 | } |
396 | |
397 | static void comphy_lane_reg_set(struct mvebu_a3700_comphy_lane *lane, |
398 | u16 reg, u16 data, u16 mask) |
399 | { |
400 | if (lane->id == 2) { |
401 | /* lane 2 PHY registers are accessed indirectly */ |
402 | comphy_set_indirect(priv: lane->priv, |
403 | offset: reg + COMPHY_LANE2_REGS_BASE, |
404 | data, mask); |
405 | } else { |
406 | void __iomem *base = lane->id == 1 ? |
407 | lane->priv->lane1_phy_regs : |
408 | lane->priv->lane0_phy_regs; |
409 | |
410 | comphy_reg_set16(addr: base + COMPHY_LANE_REG_DIRECT(reg), |
411 | data, mask); |
412 | } |
413 | } |
414 | |
415 | static int comphy_lane_reg_poll(struct mvebu_a3700_comphy_lane *lane, |
416 | u16 reg, u16 bits, |
417 | ulong sleep_us, ulong timeout_us) |
418 | { |
419 | int ret; |
420 | |
421 | if (lane->id == 2) { |
422 | u32 data; |
423 | |
424 | /* lane 2 PHY registers are accessed indirectly */ |
425 | writel(val: reg + COMPHY_LANE2_REGS_BASE, |
426 | addr: lane->priv->lane2_phy_indirect + |
427 | COMPHY_LANE2_INDIR_ADDR); |
428 | |
429 | ret = readl_poll_timeout(lane->priv->lane2_phy_indirect + |
430 | COMPHY_LANE2_INDIR_DATA, |
431 | data, (data & bits) == bits, |
432 | sleep_us, timeout_us); |
433 | } else { |
434 | void __iomem *base = lane->id == 1 ? |
435 | lane->priv->lane1_phy_regs : |
436 | lane->priv->lane0_phy_regs; |
437 | u16 data; |
438 | |
439 | ret = readw_poll_timeout(base + COMPHY_LANE_REG_DIRECT(reg), |
440 | data, (data & bits) == bits, |
441 | sleep_us, timeout_us); |
442 | } |
443 | |
444 | return ret; |
445 | } |
446 | |
447 | static void comphy_periph_reg_set(struct mvebu_a3700_comphy_lane *lane, |
448 | u8 reg, u32 data, u32 mask) |
449 | { |
450 | comphy_reg_set(addr: lane->priv->comphy_regs + COMPHY_PHY_REG(lane->id, reg), |
451 | data, mask); |
452 | } |
453 | |
454 | static int comphy_periph_reg_poll(struct mvebu_a3700_comphy_lane *lane, |
455 | u8 reg, u32 bits, |
456 | ulong sleep_us, ulong timeout_us) |
457 | { |
458 | u32 data; |
459 | |
460 | return readl_poll_timeout(lane->priv->comphy_regs + |
461 | COMPHY_PHY_REG(lane->id, reg), |
462 | data, (data & bits) == bits, |
463 | sleep_us, timeout_us); |
464 | } |
465 | |
466 | /* PHY selector configures with corresponding modes */ |
467 | static int |
468 | mvebu_a3700_comphy_set_phy_selector(struct mvebu_a3700_comphy_lane *lane) |
469 | { |
470 | u32 old, new, clr = 0, set = 0; |
471 | unsigned long flags; |
472 | |
473 | switch (lane->mode) { |
474 | case PHY_MODE_SATA: |
475 | /* SATA must be in Lane2 */ |
476 | if (lane->id == 2) |
477 | clr = COMPHY_SELECTOR_USB3_PHY_SEL_BIT; |
478 | else |
479 | goto error; |
480 | break; |
481 | |
482 | case PHY_MODE_ETHERNET: |
483 | if (lane->id == 0) |
484 | clr = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT; |
485 | else if (lane->id == 1) |
486 | clr = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT; |
487 | else |
488 | goto error; |
489 | break; |
490 | |
491 | case PHY_MODE_USB_HOST_SS: |
492 | if (lane->id == 2) |
493 | set = COMPHY_SELECTOR_USB3_PHY_SEL_BIT; |
494 | else if (lane->id == 0) |
495 | set = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT; |
496 | else |
497 | goto error; |
498 | break; |
499 | |
500 | case PHY_MODE_PCIE: |
501 | /* PCIE must be in Lane1 */ |
502 | if (lane->id == 1) |
503 | set = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT; |
504 | else |
505 | goto error; |
506 | break; |
507 | |
508 | default: |
509 | goto error; |
510 | } |
511 | |
512 | spin_lock_irqsave(&lane->priv->lock, flags); |
513 | |
514 | old = readl(addr: lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG); |
515 | new = (old & ~clr) | set; |
516 | writel(val: new, addr: lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG); |
517 | |
518 | spin_unlock_irqrestore(lock: &lane->priv->lock, flags); |
519 | |
520 | dev_dbg(lane->dev, |
521 | "COMPHY[%d] mode[%d] changed PHY selector 0x%08x -> 0x%08x\n" , |
522 | lane->id, lane->mode, old, new); |
523 | |
524 | return 0; |
525 | error: |
526 | dev_err(lane->dev, "COMPHY[%d] mode[%d] is invalid\n" , lane->id, |
527 | lane->mode); |
528 | return -EINVAL; |
529 | } |
530 | |
531 | static int |
532 | mvebu_a3700_comphy_sata_power_on(struct mvebu_a3700_comphy_lane *lane) |
533 | { |
534 | u32 mask, data, ref_clk; |
535 | int ret; |
536 | |
537 | /* Configure phy selector for SATA */ |
538 | ret = mvebu_a3700_comphy_set_phy_selector(lane); |
539 | if (ret) |
540 | return ret; |
541 | |
542 | /* Clear phy isolation mode to make it work in normal mode */ |
543 | comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL, |
544 | data: 0x0, PHY_ISOLATE_MODE); |
545 | |
546 | /* 0. Check the Polarity invert bits */ |
547 | data = 0x0; |
548 | if (lane->invert_tx) |
549 | data |= TXD_INVERT_BIT; |
550 | if (lane->invert_rx) |
551 | data |= RXD_INVERT_BIT; |
552 | mask = TXD_INVERT_BIT | RXD_INVERT_BIT; |
553 | comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); |
554 | |
555 | /* 1. Select 40-bit data width */ |
556 | comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, |
557 | DATA_WIDTH_40BIT, SEL_DATA_WIDTH_MASK); |
558 | |
559 | /* 2. Select reference clock(25M) and PHY mode (SATA) */ |
560 | if (lane->priv->xtal_is_40m) |
561 | ref_clk = REF_FREF_SEL_SERDES_40MHZ; |
562 | else |
563 | ref_clk = REF_FREF_SEL_SERDES_25MHZ; |
564 | |
565 | data = ref_clk | COMPHY_MODE_SATA; |
566 | mask = REF_FREF_SEL_MASK | COMPHY_MODE_MASK; |
567 | comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); |
568 | |
569 | /* 3. Use maximum PLL rate (no power save) */ |
570 | comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, |
571 | USE_MAX_PLL_RATE_BIT, USE_MAX_PLL_RATE_BIT); |
572 | |
573 | /* 4. Reset reserved bit */ |
574 | comphy_set_indirect(priv: lane->priv, COMPHY_RESERVED_REG, |
575 | data: 0x0, PHYCTRL_FRM_PIN_BIT); |
576 | |
577 | /* 5. Set vendor-specific configuration (It is done in sata driver) */ |
578 | /* XXX: in U-Boot below sequence was executed in this place, in Linux |
579 | * not. Now it is done only in U-Boot before this comphy |
580 | * initialization - tests shows that it works ok, but in case of any |
581 | * future problem it is left for reference. |
582 | * reg_set(MVEBU_REGS_BASE + 0xe00a0, 0, 0xffffffff); |
583 | * reg_set(MVEBU_REGS_BASE + 0xe00a4, BIT(6), BIT(6)); |
584 | */ |
585 | |
586 | /* Wait for > 55 us to allow PLL be enabled */ |
587 | udelay(PLL_SET_DELAY_US); |
588 | |
589 | /* Polling status */ |
590 | ret = comphy_lane_reg_poll(lane, COMPHY_DIG_LOOPBACK_EN, |
591 | PLL_READY_TX_BIT, COMPHY_PLL_SLEEP, |
592 | COMPHY_PLL_TIMEOUT); |
593 | if (ret) |
594 | dev_err(lane->dev, "Failed to lock SATA PLL\n" ); |
595 | |
596 | return ret; |
597 | } |
598 | |
599 | static void comphy_gbe_phy_init(struct mvebu_a3700_comphy_lane *lane, |
600 | bool is_1gbps) |
601 | { |
602 | int addr, fix_idx; |
603 | u16 val; |
604 | |
605 | fix_idx = 0; |
606 | for (addr = 0; addr < 512; addr++) { |
607 | /* |
608 | * All PHY register values are defined in full for 3.125Gbps |
609 | * SERDES speed. The values required for 1.25 Gbps are almost |
610 | * the same and only few registers should be "fixed" in |
611 | * comparison to 3.125 Gbps values. These register values are |
612 | * stored in "gbe_phy_init_fix" array. |
613 | */ |
614 | if (!is_1gbps && gbe_phy_init_fix[fix_idx].addr == addr) { |
615 | /* Use new value */ |
616 | val = gbe_phy_init_fix[fix_idx].value; |
617 | if (fix_idx < ARRAY_SIZE(gbe_phy_init_fix)) |
618 | fix_idx++; |
619 | } else { |
620 | val = gbe_phy_init[addr]; |
621 | } |
622 | |
623 | comphy_lane_reg_set(lane, reg: addr, data: val, mask: 0xFFFF); |
624 | } |
625 | } |
626 | |
627 | static int |
628 | mvebu_a3700_comphy_ethernet_power_on(struct mvebu_a3700_comphy_lane *lane) |
629 | { |
630 | u32 mask, data, speed_sel; |
631 | int ret; |
632 | |
633 | /* Set selector */ |
634 | ret = mvebu_a3700_comphy_set_phy_selector(lane); |
635 | if (ret) |
636 | return ret; |
637 | |
638 | /* |
639 | * 1. Reset PHY by setting PHY input port PIN_RESET=1. |
640 | * 2. Set PHY input port PIN_TX_IDLE=1, PIN_PU_IVREF=1 to keep |
641 | * PHY TXP/TXN output to idle state during PHY initialization |
642 | * 3. Set PHY input port PIN_PU_PLL=0, PIN_PU_RX=0, PIN_PU_TX=0. |
643 | */ |
644 | data = PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT | PIN_RESET_COMPHY_BIT; |
645 | mask = data | PIN_RESET_CORE_BIT | PIN_PU_PLL_BIT | PIN_PU_RX_BIT | |
646 | PIN_PU_TX_BIT | PHY_RX_INIT_BIT; |
647 | comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); |
648 | |
649 | /* 4. Release reset to the PHY by setting PIN_RESET=0. */ |
650 | data = 0x0; |
651 | mask = PIN_RESET_COMPHY_BIT; |
652 | comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); |
653 | |
654 | /* |
655 | * 5. Set PIN_PHY_GEN_TX[3:0] and PIN_PHY_GEN_RX[3:0] to decide COMPHY |
656 | * bit rate |
657 | */ |
658 | switch (lane->submode) { |
659 | case PHY_INTERFACE_MODE_SGMII: |
660 | case PHY_INTERFACE_MODE_1000BASEX: |
661 | /* SGMII 1G, SerDes speed 1.25G */ |
662 | speed_sel = SERDES_SPEED_1_25_G; |
663 | break; |
664 | case PHY_INTERFACE_MODE_2500BASEX: |
665 | /* 2500Base-X, SerDes speed 3.125G */ |
666 | speed_sel = SERDES_SPEED_3_125_G; |
667 | break; |
668 | default: |
669 | /* Other rates are not supported */ |
670 | dev_err(lane->dev, |
671 | "unsupported phy speed %d on comphy lane%d\n" , |
672 | lane->submode, lane->id); |
673 | return -EINVAL; |
674 | } |
675 | data = GEN_RX_SEL_VALUE(speed_sel) | GEN_TX_SEL_VALUE(speed_sel); |
676 | mask = GEN_RX_SEL_MASK | GEN_TX_SEL_MASK; |
677 | comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); |
678 | |
679 | /* |
680 | * 6. Wait 10mS for bandgap and reference clocks to stabilize; then |
681 | * start SW programming. |
682 | */ |
683 | mdelay(10); |
684 | |
685 | /* 7. Program COMPHY register PHY_MODE */ |
686 | data = COMPHY_MODE_SERDES; |
687 | mask = COMPHY_MODE_MASK; |
688 | comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); |
689 | |
690 | /* |
691 | * 8. Set COMPHY register REFCLK_SEL to select the correct REFCLK |
692 | * source |
693 | */ |
694 | data = 0x0; |
695 | mask = PHY_REF_CLK_SEL; |
696 | comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask); |
697 | |
698 | /* |
699 | * 9. Set correct reference clock frequency in COMPHY register |
700 | * REF_FREF_SEL. |
701 | */ |
702 | if (lane->priv->xtal_is_40m) |
703 | data = REF_FREF_SEL_SERDES_50MHZ; |
704 | else |
705 | data = REF_FREF_SEL_SERDES_25MHZ; |
706 | |
707 | mask = REF_FREF_SEL_MASK; |
708 | comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); |
709 | |
710 | /* |
711 | * 10. Program COMPHY register PHY_GEN_MAX[1:0] |
712 | * This step is mentioned in the flow received from verification team. |
713 | * However the PHY_GEN_MAX value is only meaningful for other interfaces |
714 | * (not SERDES). For instance, it selects SATA speed 1.5/3/6 Gbps or |
715 | * PCIe speed 2.5/5 Gbps |
716 | */ |
717 | |
718 | /* |
719 | * 11. Program COMPHY register SEL_BITS to set correct parallel data |
720 | * bus width |
721 | */ |
722 | data = DATA_WIDTH_10BIT; |
723 | mask = SEL_DATA_WIDTH_MASK; |
724 | comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, data, mask); |
725 | |
726 | /* |
727 | * 12. As long as DFE function needs to be enabled in any mode, |
728 | * COMPHY register DFE_UPDATE_EN[5:0] shall be programmed to 0x3F |
729 | * for real chip during COMPHY power on. |
730 | * The value of the DFE_UPDATE_EN already is 0x3F, because it is the |
731 | * default value after reset of the PHY. |
732 | */ |
733 | |
734 | /* |
735 | * 13. Program COMPHY GEN registers. |
736 | * These registers should be programmed based on the lab testing result |
737 | * to achieve optimal performance. Please contact the CEA group to get |
738 | * the related GEN table during real chip bring-up. We only required to |
739 | * run though the entire registers programming flow defined by |
740 | * "comphy_gbe_phy_init" when the REF clock is 40 MHz. For REF clock |
741 | * 25 MHz the default values stored in PHY registers are OK. |
742 | */ |
743 | dev_dbg(lane->dev, "Running C-DPI phy init %s mode\n" , |
744 | lane->submode == PHY_INTERFACE_MODE_2500BASEX ? "2G5" : "1G" ); |
745 | if (lane->priv->xtal_is_40m) |
746 | comphy_gbe_phy_init(lane, |
747 | is_1gbps: lane->submode != PHY_INTERFACE_MODE_2500BASEX); |
748 | |
749 | /* |
750 | * 14. Check the PHY Polarity invert bit |
751 | */ |
752 | data = 0x0; |
753 | if (lane->invert_tx) |
754 | data |= TXD_INVERT_BIT; |
755 | if (lane->invert_rx) |
756 | data |= RXD_INVERT_BIT; |
757 | mask = TXD_INVERT_BIT | RXD_INVERT_BIT; |
758 | comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); |
759 | |
760 | /* |
761 | * 15. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1 to |
762 | * start PHY power up sequence. All the PHY register programming should |
763 | * be done before PIN_PU_PLL=1. There should be no register programming |
764 | * for normal PHY operation from this point. |
765 | */ |
766 | data = PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT; |
767 | mask = data; |
768 | comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); |
769 | |
770 | /* |
771 | * 16. Wait for PHY power up sequence to finish by checking output ports |
772 | * PIN_PLL_READY_TX=1 and PIN_PLL_READY_RX=1. |
773 | */ |
774 | ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, |
775 | PHY_PLL_READY_TX_BIT | |
776 | PHY_PLL_READY_RX_BIT, |
777 | COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); |
778 | if (ret) { |
779 | dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n" , |
780 | lane->id); |
781 | return ret; |
782 | } |
783 | |
784 | /* |
785 | * 17. Set COMPHY input port PIN_TX_IDLE=0 |
786 | */ |
787 | comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data: 0x0, PIN_TX_IDLE_BIT); |
788 | |
789 | /* |
790 | * 18. After valid data appear on PIN_RXDATA bus, set PIN_RX_INIT=1. To |
791 | * start RX initialization. PIN_RX_INIT_DONE will be cleared to 0 by the |
792 | * PHY After RX initialization is done, PIN_RX_INIT_DONE will be set to |
793 | * 1 by COMPHY Set PIN_RX_INIT=0 after PIN_RX_INIT_DONE= 1. Please |
794 | * refer to RX initialization part for details. |
795 | */ |
796 | comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, |
797 | PHY_RX_INIT_BIT, PHY_RX_INIT_BIT); |
798 | |
799 | ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, |
800 | PHY_PLL_READY_TX_BIT | |
801 | PHY_PLL_READY_RX_BIT, |
802 | COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); |
803 | if (ret) { |
804 | dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n" , |
805 | lane->id); |
806 | return ret; |
807 | } |
808 | |
809 | ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, |
810 | PHY_RX_INIT_DONE_BIT, |
811 | COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); |
812 | if (ret) |
813 | dev_err(lane->dev, "Failed to init RX of SERDES PHY %d\n" , |
814 | lane->id); |
815 | |
816 | return ret; |
817 | } |
818 | |
819 | static int |
820 | mvebu_a3700_comphy_usb3_power_on(struct mvebu_a3700_comphy_lane *lane) |
821 | { |
822 | u32 mask, data, cfg, ref_clk; |
823 | int ret; |
824 | |
825 | /* Set phy seclector */ |
826 | ret = mvebu_a3700_comphy_set_phy_selector(lane); |
827 | if (ret) |
828 | return ret; |
829 | |
830 | /* COMPHY register reset (cleared automatically) */ |
831 | comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST); |
832 | |
833 | /* |
834 | * 0. Set PHY OTG Control(0x5d034), bit 4, Power up OTG module The |
835 | * register belong to UTMI module, so it is set in UTMI phy driver. |
836 | */ |
837 | |
838 | /* |
839 | * 1. Set PRD_TXDEEMPH (3.5db de-emph) |
840 | */ |
841 | data = PRD_TXDEEMPH0_MASK; |
842 | mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK | |
843 | CFG_TX_ALIGN_POS_MASK; |
844 | comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG0, data, mask); |
845 | |
846 | /* |
847 | * 2. Set BIT0: enable transmitter in high impedance mode |
848 | * Set BIT[3:4]: delay 2 clock cycles for HiZ off latency |
849 | * Set BIT6: Tx detect Rx at HiZ mode |
850 | * Unset BIT15: set to 0 to set USB3 De-emphasize level to -3.5db |
851 | * together with bit 0 of COMPHY_PIPE_LANE_CFG0 register |
852 | */ |
853 | data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN; |
854 | mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK | |
855 | TX_ELEC_IDLE_MODE_EN; |
856 | comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, data, mask); |
857 | |
858 | /* |
859 | * 3. Set Spread Spectrum Clock Enabled |
860 | */ |
861 | comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG4, |
862 | SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN); |
863 | |
864 | /* |
865 | * 4. Set Override Margining Controls From the MAC: |
866 | * Use margining signals from lane configuration |
867 | */ |
868 | comphy_lane_reg_set(lane, COMPHY_PIPE_TEST_MODE_CTRL, |
869 | MODE_MARGIN_OVERRIDE, mask: 0xFFFF); |
870 | |
871 | /* |
872 | * 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles |
873 | * set Mode Clock Source = PCLK is generated from REFCLK |
874 | */ |
875 | data = 0x0; |
876 | mask = MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE_MASK | |
877 | BUNDLE_SAMPLE_CTRL | PLL_READY_DLY_MASK; |
878 | comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, data, mask); |
879 | |
880 | /* |
881 | * 6. Set G2 Spread Spectrum Clock Amplitude at 4K |
882 | */ |
883 | comphy_lane_reg_set(lane, COMPHY_GEN2_SET2, |
884 | GS2_TX_SSC_AMP_4128, GS2_TX_SSC_AMP_MASK); |
885 | |
886 | /* |
887 | * 7. Unset G3 Spread Spectrum Clock Amplitude |
888 | * set G3 TX and RX Register Master Current Select |
889 | */ |
890 | data = GS2_VREG_RXTX_MAS_ISET_60U; |
891 | mask = GS2_TX_SSC_AMP_MASK | GS2_VREG_RXTX_MAS_ISET_MASK | |
892 | GS2_RSVD_6_0_MASK; |
893 | comphy_lane_reg_set(lane, COMPHY_GEN3_SET2, data, mask); |
894 | |
895 | /* |
896 | * 8. Check crystal jumper setting and program the Power and PLL Control |
897 | * accordingly Change RX wait |
898 | */ |
899 | if (lane->priv->xtal_is_40m) { |
900 | ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ; |
901 | cfg = CFG_PM_RXDLOZ_WAIT_12_UNIT; |
902 | } else { |
903 | ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ; |
904 | cfg = CFG_PM_RXDLOZ_WAIT_7_UNIT; |
905 | } |
906 | |
907 | data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | |
908 | PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_USB3 | ref_clk; |
909 | mask = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | |
910 | PU_TX_INTP_BIT | PU_DFE_BIT | PLL_LOCK_BIT | COMPHY_MODE_MASK | |
911 | REF_FREF_SEL_MASK; |
912 | comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); |
913 | |
914 | data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg; |
915 | mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK | |
916 | CFG_PM_RXDLOZ_WAIT_MASK; |
917 | comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask); |
918 | |
919 | /* |
920 | * 9. Enable idle sync |
921 | */ |
922 | comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN, |
923 | IDLE_SYNC_EN, IDLE_SYNC_EN); |
924 | |
925 | /* |
926 | * 10. Enable the output of 500M clock |
927 | */ |
928 | comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, CLK500M_EN, CLK500M_EN); |
929 | |
930 | /* |
931 | * 11. Set 20-bit data width |
932 | */ |
933 | comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, |
934 | DATA_WIDTH_20BIT, mask: 0xFFFF); |
935 | |
936 | /* |
937 | * 12. Override Speed_PLL value and use MAC PLL |
938 | */ |
939 | data = SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT; |
940 | mask = 0xFFFF; |
941 | comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, data, mask); |
942 | |
943 | /* |
944 | * 13. Check the Polarity invert bit |
945 | */ |
946 | data = 0x0; |
947 | if (lane->invert_tx) |
948 | data |= TXD_INVERT_BIT; |
949 | if (lane->invert_rx) |
950 | data |= RXD_INVERT_BIT; |
951 | mask = TXD_INVERT_BIT | RXD_INVERT_BIT; |
952 | comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); |
953 | |
954 | /* |
955 | * 14. Set max speed generation to USB3.0 5Gbps |
956 | */ |
957 | comphy_lane_reg_set(lane, COMPHY_SYNC_MASK_GEN, |
958 | PHY_GEN_MAX_USB3_5G, PHY_GEN_MAX_MASK); |
959 | |
960 | /* |
961 | * 15. Set capacitor value for FFE gain peaking to 0xF |
962 | */ |
963 | comphy_lane_reg_set(lane, COMPHY_GEN2_SET3, |
964 | GS3_FFE_CAP_SEL_VALUE, GS3_FFE_CAP_SEL_MASK); |
965 | |
966 | /* |
967 | * 16. Release SW reset |
968 | */ |
969 | data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4; |
970 | mask = 0xFFFF; |
971 | comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask); |
972 | |
973 | /* Wait for > 55 us to allow PCLK be enabled */ |
974 | udelay(PLL_SET_DELAY_US); |
975 | |
976 | ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN, |
977 | COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); |
978 | if (ret) |
979 | dev_err(lane->dev, "Failed to lock USB3 PLL\n" ); |
980 | |
981 | return ret; |
982 | } |
983 | |
984 | static int |
985 | mvebu_a3700_comphy_pcie_power_on(struct mvebu_a3700_comphy_lane *lane) |
986 | { |
987 | u32 mask, data, ref_clk; |
988 | int ret; |
989 | |
990 | /* Configure phy selector for PCIe */ |
991 | ret = mvebu_a3700_comphy_set_phy_selector(lane); |
992 | if (ret) |
993 | return ret; |
994 | |
995 | /* 1. Enable max PLL. */ |
996 | comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, |
997 | USE_MAX_PLL_RATE_EN, USE_MAX_PLL_RATE_EN); |
998 | |
999 | /* 2. Select 20 bit SERDES interface. */ |
1000 | comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, |
1001 | CFG_SEL_20B, CFG_SEL_20B); |
1002 | |
1003 | /* 3. Force to use reg setting for PCIe mode */ |
1004 | comphy_lane_reg_set(lane, COMPHY_MISC_CTRL1, |
1005 | SEL_BITS_PCIE_FORCE, SEL_BITS_PCIE_FORCE); |
1006 | |
1007 | /* 4. Change RX wait */ |
1008 | data = CFG_PM_RXDEN_WAIT_1_UNIT | CFG_PM_RXDLOZ_WAIT_12_UNIT; |
1009 | mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK | |
1010 | CFG_PM_RXDLOZ_WAIT_MASK; |
1011 | comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask); |
1012 | |
1013 | /* 5. Enable idle sync */ |
1014 | comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN, |
1015 | IDLE_SYNC_EN, IDLE_SYNC_EN); |
1016 | |
1017 | /* 6. Enable the output of 100M/125M/500M clock */ |
1018 | data = CLK500M_EN | TXDCLK_2X_SEL | CLK100M_125M_EN; |
1019 | mask = data; |
1020 | comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask); |
1021 | |
1022 | /* |
1023 | * 7. Enable TX, PCIE global register, 0xd0074814, it is done in |
1024 | * PCI-E driver |
1025 | */ |
1026 | |
1027 | /* |
1028 | * 8. Check crystal jumper setting and program the Power and PLL |
1029 | * Control accordingly |
1030 | */ |
1031 | |
1032 | if (lane->priv->xtal_is_40m) |
1033 | ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ; |
1034 | else |
1035 | ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ; |
1036 | |
1037 | data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | |
1038 | PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_PCIE | ref_clk; |
1039 | mask = 0xFFFF; |
1040 | comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); |
1041 | |
1042 | /* 9. Override Speed_PLL value and use MAC PLL */ |
1043 | comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, |
1044 | SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT, |
1045 | mask: 0xFFFF); |
1046 | |
1047 | /* 10. Check the Polarity invert bit */ |
1048 | data = 0x0; |
1049 | if (lane->invert_tx) |
1050 | data |= TXD_INVERT_BIT; |
1051 | if (lane->invert_rx) |
1052 | data |= RXD_INVERT_BIT; |
1053 | mask = TXD_INVERT_BIT | RXD_INVERT_BIT; |
1054 | comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); |
1055 | |
1056 | /* 11. Release SW reset */ |
1057 | data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32; |
1058 | mask = data | PIPE_SOFT_RESET | MODE_REFDIV_MASK; |
1059 | comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask); |
1060 | |
1061 | /* Wait for > 55 us to allow PCLK be enabled */ |
1062 | udelay(PLL_SET_DELAY_US); |
1063 | |
1064 | ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN, |
1065 | COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); |
1066 | if (ret) |
1067 | dev_err(lane->dev, "Failed to lock PCIE PLL\n" ); |
1068 | |
1069 | return ret; |
1070 | } |
1071 | |
1072 | static void |
1073 | mvebu_a3700_comphy_sata_power_off(struct mvebu_a3700_comphy_lane *lane) |
1074 | { |
1075 | /* Set phy isolation mode */ |
1076 | comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL, |
1077 | PHY_ISOLATE_MODE, PHY_ISOLATE_MODE); |
1078 | |
1079 | /* Power off PLL, Tx, Rx */ |
1080 | comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, |
1081 | data: 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT); |
1082 | } |
1083 | |
1084 | static void |
1085 | mvebu_a3700_comphy_ethernet_power_off(struct mvebu_a3700_comphy_lane *lane) |
1086 | { |
1087 | u32 mask, data; |
1088 | |
1089 | data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT | PIN_PU_IVREF_BIT | |
1090 | PHY_RX_INIT_BIT; |
1091 | mask = data; |
1092 | comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); |
1093 | } |
1094 | |
1095 | static void |
1096 | mvebu_a3700_comphy_pcie_power_off(struct mvebu_a3700_comphy_lane *lane) |
1097 | { |
1098 | /* Power off PLL, Tx, Rx */ |
1099 | comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, |
1100 | data: 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT); |
1101 | } |
1102 | |
1103 | static void mvebu_a3700_comphy_usb3_power_off(struct mvebu_a3700_comphy_lane *lane) |
1104 | { |
1105 | /* |
1106 | * The USB3 MAC sets the USB3 PHY to low state, so we do not |
1107 | * need to power off USB3 PHY again. |
1108 | */ |
1109 | } |
1110 | |
1111 | static bool mvebu_a3700_comphy_check_mode(int lane, |
1112 | enum phy_mode mode, |
1113 | int submode) |
1114 | { |
1115 | int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes); |
1116 | |
1117 | /* Unused PHY mux value is 0x0 */ |
1118 | if (mode == PHY_MODE_INVALID) |
1119 | return false; |
1120 | |
1121 | for (i = 0; i < n; i++) { |
1122 | if (mvebu_a3700_comphy_modes[i].lane == lane && |
1123 | mvebu_a3700_comphy_modes[i].mode == mode && |
1124 | mvebu_a3700_comphy_modes[i].submode == submode) |
1125 | break; |
1126 | } |
1127 | |
1128 | if (i == n) |
1129 | return false; |
1130 | |
1131 | return true; |
1132 | } |
1133 | |
1134 | static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, |
1135 | int submode) |
1136 | { |
1137 | struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); |
1138 | |
1139 | if (!mvebu_a3700_comphy_check_mode(lane: lane->id, mode, submode)) { |
1140 | dev_err(lane->dev, "invalid COMPHY mode\n" ); |
1141 | return -EINVAL; |
1142 | } |
1143 | |
1144 | /* Mode cannot be changed while the PHY is powered on */ |
1145 | if (phy->power_count && |
1146 | (lane->mode != mode || lane->submode != submode)) |
1147 | return -EBUSY; |
1148 | |
1149 | /* Just remember the mode, ->power_on() will do the real setup */ |
1150 | lane->mode = mode; |
1151 | lane->submode = submode; |
1152 | |
1153 | return 0; |
1154 | } |
1155 | |
1156 | static int mvebu_a3700_comphy_power_on(struct phy *phy) |
1157 | { |
1158 | struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); |
1159 | |
1160 | if (!mvebu_a3700_comphy_check_mode(lane: lane->id, mode: lane->mode, |
1161 | submode: lane->submode)) { |
1162 | dev_err(lane->dev, "invalid COMPHY mode\n" ); |
1163 | return -EINVAL; |
1164 | } |
1165 | |
1166 | switch (lane->mode) { |
1167 | case PHY_MODE_USB_HOST_SS: |
1168 | dev_dbg(lane->dev, "set lane %d to USB3 host mode\n" , lane->id); |
1169 | return mvebu_a3700_comphy_usb3_power_on(lane); |
1170 | case PHY_MODE_SATA: |
1171 | dev_dbg(lane->dev, "set lane %d to SATA mode\n" , lane->id); |
1172 | return mvebu_a3700_comphy_sata_power_on(lane); |
1173 | case PHY_MODE_ETHERNET: |
1174 | dev_dbg(lane->dev, "set lane %d to Ethernet mode\n" , lane->id); |
1175 | return mvebu_a3700_comphy_ethernet_power_on(lane); |
1176 | case PHY_MODE_PCIE: |
1177 | dev_dbg(lane->dev, "set lane %d to PCIe mode\n" , lane->id); |
1178 | return mvebu_a3700_comphy_pcie_power_on(lane); |
1179 | default: |
1180 | dev_err(lane->dev, "unsupported PHY mode (%d)\n" , lane->mode); |
1181 | return -EOPNOTSUPP; |
1182 | } |
1183 | } |
1184 | |
1185 | static int mvebu_a3700_comphy_power_off(struct phy *phy) |
1186 | { |
1187 | struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); |
1188 | |
1189 | switch (lane->id) { |
1190 | case 0: |
1191 | mvebu_a3700_comphy_usb3_power_off(lane); |
1192 | mvebu_a3700_comphy_ethernet_power_off(lane); |
1193 | return 0; |
1194 | case 1: |
1195 | mvebu_a3700_comphy_pcie_power_off(lane); |
1196 | mvebu_a3700_comphy_ethernet_power_off(lane); |
1197 | return 0; |
1198 | case 2: |
1199 | mvebu_a3700_comphy_usb3_power_off(lane); |
1200 | mvebu_a3700_comphy_sata_power_off(lane); |
1201 | return 0; |
1202 | default: |
1203 | dev_err(lane->dev, "invalid COMPHY mode\n" ); |
1204 | return -EINVAL; |
1205 | } |
1206 | } |
1207 | |
1208 | static const struct phy_ops mvebu_a3700_comphy_ops = { |
1209 | .power_on = mvebu_a3700_comphy_power_on, |
1210 | .power_off = mvebu_a3700_comphy_power_off, |
1211 | .set_mode = mvebu_a3700_comphy_set_mode, |
1212 | .owner = THIS_MODULE, |
1213 | }; |
1214 | |
1215 | static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, |
1216 | const struct of_phandle_args *args) |
1217 | { |
1218 | struct mvebu_a3700_comphy_lane *lane; |
1219 | unsigned int port; |
1220 | struct phy *phy; |
1221 | |
1222 | phy = of_phy_simple_xlate(dev, args); |
1223 | if (IS_ERR(ptr: phy)) |
1224 | return phy; |
1225 | |
1226 | lane = phy_get_drvdata(phy); |
1227 | |
1228 | port = args->args[0]; |
1229 | if (port != 0 && (port != 1 || lane->id != 0)) { |
1230 | dev_err(lane->dev, "invalid port number %u\n" , port); |
1231 | return ERR_PTR(error: -EINVAL); |
1232 | } |
1233 | |
1234 | lane->invert_tx = args->args[1] & BIT(0); |
1235 | lane->invert_rx = args->args[1] & BIT(1); |
1236 | |
1237 | return phy; |
1238 | } |
1239 | |
1240 | static int mvebu_a3700_comphy_probe(struct platform_device *pdev) |
1241 | { |
1242 | struct mvebu_a3700_comphy_priv *priv; |
1243 | struct phy_provider *provider; |
1244 | struct device_node *child; |
1245 | struct resource *res; |
1246 | struct clk *clk; |
1247 | int ret; |
1248 | |
1249 | priv = devm_kzalloc(dev: &pdev->dev, size: sizeof(*priv), GFP_KERNEL); |
1250 | if (!priv) |
1251 | return -ENOMEM; |
1252 | |
1253 | spin_lock_init(&priv->lock); |
1254 | |
1255 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "comphy" ); |
1256 | priv->comphy_regs = devm_ioremap_resource(dev: &pdev->dev, res); |
1257 | if (IS_ERR(ptr: priv->comphy_regs)) |
1258 | return PTR_ERR(ptr: priv->comphy_regs); |
1259 | |
1260 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
1261 | "lane1_pcie_gbe" ); |
1262 | priv->lane1_phy_regs = devm_ioremap_resource(dev: &pdev->dev, res); |
1263 | if (IS_ERR(ptr: priv->lane1_phy_regs)) |
1264 | return PTR_ERR(ptr: priv->lane1_phy_regs); |
1265 | |
1266 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
1267 | "lane0_usb3_gbe" ); |
1268 | priv->lane0_phy_regs = devm_ioremap_resource(dev: &pdev->dev, res); |
1269 | if (IS_ERR(ptr: priv->lane0_phy_regs)) |
1270 | return PTR_ERR(ptr: priv->lane0_phy_regs); |
1271 | |
1272 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
1273 | "lane2_sata_usb3" ); |
1274 | priv->lane2_phy_indirect = devm_ioremap_resource(dev: &pdev->dev, res); |
1275 | if (IS_ERR(ptr: priv->lane2_phy_indirect)) |
1276 | return PTR_ERR(ptr: priv->lane2_phy_indirect); |
1277 | |
1278 | /* |
1279 | * Driver needs to know if reference xtal clock is 40MHz or 25MHz. |
1280 | * Old DT bindings do not have xtal clk present. So do not fail here |
1281 | * and expects that default 25MHz reference clock is used. |
1282 | */ |
1283 | clk = clk_get(dev: &pdev->dev, id: "xtal" ); |
1284 | if (IS_ERR(ptr: clk)) { |
1285 | if (PTR_ERR(ptr: clk) == -EPROBE_DEFER) |
1286 | return -EPROBE_DEFER; |
1287 | dev_warn(&pdev->dev, "missing 'xtal' clk (%ld)\n" , |
1288 | PTR_ERR(clk)); |
1289 | } else { |
1290 | ret = clk_prepare_enable(clk); |
1291 | if (ret) { |
1292 | dev_warn(&pdev->dev, "enabling xtal clk failed (%d)\n" , |
1293 | ret); |
1294 | } else { |
1295 | if (clk_get_rate(clk) == 40000000) |
1296 | priv->xtal_is_40m = true; |
1297 | clk_disable_unprepare(clk); |
1298 | } |
1299 | clk_put(clk); |
1300 | } |
1301 | |
1302 | dev_set_drvdata(dev: &pdev->dev, data: priv); |
1303 | |
1304 | for_each_available_child_of_node(pdev->dev.of_node, child) { |
1305 | struct mvebu_a3700_comphy_lane *lane; |
1306 | struct phy *phy; |
1307 | int ret; |
1308 | u32 lane_id; |
1309 | |
1310 | ret = of_property_read_u32(np: child, propname: "reg" , out_value: &lane_id); |
1311 | if (ret < 0) { |
1312 | dev_err(&pdev->dev, "missing 'reg' property (%d)\n" , |
1313 | ret); |
1314 | continue; |
1315 | } |
1316 | |
1317 | if (lane_id >= 3) { |
1318 | dev_err(&pdev->dev, "invalid 'reg' property\n" ); |
1319 | continue; |
1320 | } |
1321 | |
1322 | lane = devm_kzalloc(dev: &pdev->dev, size: sizeof(*lane), GFP_KERNEL); |
1323 | if (!lane) { |
1324 | of_node_put(node: child); |
1325 | return -ENOMEM; |
1326 | } |
1327 | |
1328 | phy = devm_phy_create(dev: &pdev->dev, node: child, |
1329 | ops: &mvebu_a3700_comphy_ops); |
1330 | if (IS_ERR(ptr: phy)) { |
1331 | of_node_put(node: child); |
1332 | return PTR_ERR(ptr: phy); |
1333 | } |
1334 | |
1335 | lane->priv = priv; |
1336 | lane->dev = &pdev->dev; |
1337 | lane->mode = PHY_MODE_INVALID; |
1338 | lane->submode = PHY_INTERFACE_MODE_NA; |
1339 | lane->id = lane_id; |
1340 | lane->invert_tx = false; |
1341 | lane->invert_rx = false; |
1342 | phy_set_drvdata(phy, data: lane); |
1343 | |
1344 | /* |
1345 | * To avoid relying on the bootloader/firmware configuration, |
1346 | * power off all comphys. |
1347 | */ |
1348 | mvebu_a3700_comphy_power_off(phy); |
1349 | } |
1350 | |
1351 | provider = devm_of_phy_provider_register(&pdev->dev, |
1352 | mvebu_a3700_comphy_xlate); |
1353 | |
1354 | return PTR_ERR_OR_ZERO(ptr: provider); |
1355 | } |
1356 | |
1357 | static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = { |
1358 | { .compatible = "marvell,comphy-a3700" }, |
1359 | { }, |
1360 | }; |
1361 | MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table); |
1362 | |
1363 | static struct platform_driver mvebu_a3700_comphy_driver = { |
1364 | .probe = mvebu_a3700_comphy_probe, |
1365 | .driver = { |
1366 | .name = "mvebu-a3700-comphy" , |
1367 | .of_match_table = mvebu_a3700_comphy_of_match_table, |
1368 | }, |
1369 | }; |
1370 | module_platform_driver(mvebu_a3700_comphy_driver); |
1371 | |
1372 | MODULE_AUTHOR("Miquèl Raynal <miquel.raynal@bootlin.com>" ); |
1373 | MODULE_AUTHOR("Pali Rohár <pali@kernel.org>" ); |
1374 | MODULE_AUTHOR("Marek Behún <kabel@kernel.org>" ); |
1375 | MODULE_DESCRIPTION("Common PHY driver for A3700" ); |
1376 | MODULE_LICENSE("GPL v2" ); |
1377 | |