1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2023 Sartura Ltd.
4 *
5 * Author: Robert Marko <robert.marko@sartura.hr>
6 * Christian Marangi <ansuelsmth@gmail.com>
7 *
8 * Qualcomm QCA8072 and QCA8075 PHY driver
9 */
10
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/phy.h>
14 #include <linux/bitfield.h>
15 #include <linux/gpio/driver.h>
16 #include <linux/sfp.h>
17
18 #include "qcom.h"
19
20 #define QCA807X_CHIP_CONFIGURATION 0x1f
21 #define QCA807X_BT_BX_REG_SEL BIT(15)
22 #define QCA807X_BT_BX_REG_SEL_FIBER 0
23 #define QCA807X_BT_BX_REG_SEL_COPPER 1
24 #define QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK GENMASK(3, 0)
25 #define QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII 4
26 #define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER 3
27 #define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER 0
28
29 #define QCA807X_MEDIA_SELECT_STATUS 0x1a
30 #define QCA807X_MEDIA_DETECTED_COPPER BIT(5)
31 #define QCA807X_MEDIA_DETECTED_1000_BASE_X BIT(4)
32 #define QCA807X_MEDIA_DETECTED_100_BASE_FX BIT(3)
33
34 #define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION 0x807e
35 #define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN BIT(0)
36
37 #define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a
38 #define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0)
39 /* List of tweaks enabled by this bit:
40 * - With both FULL amplitude and FULL bias current: bias current
41 * is set to half.
42 * - With only DSP amplitude: bias current is set to half and
43 * is set to 1/4 with cable < 10m.
44 * - With DSP bias current (included both DSP amplitude and
45 * DSP bias current): bias current is half the detected current
46 * with cable < 10m.
47 */
48 #define QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK BIT(2)
49 #define QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT BIT(1)
50 #define QCA807X_CONTROL_DAC_DSP_AMPLITUDE BIT(0)
51
52 #define QCA807X_MMD7_LED_100N_1 0x8074
53 #define QCA807X_MMD7_LED_100N_2 0x8075
54 #define QCA807X_MMD7_LED_1000N_1 0x8076
55 #define QCA807X_MMD7_LED_1000N_2 0x8077
56
57 #define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2))
58 #define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2))
59
60 /* LED hw control pattern for fiber port */
61 #define QCA807X_LED_FIBER_PATTERN_MASK GENMASK(11, 1)
62 #define QCA807X_LED_FIBER_TXACT_BLK_EN BIT(10)
63 #define QCA807X_LED_FIBER_RXACT_BLK_EN BIT(9)
64 #define QCA807X_LED_FIBER_FDX_ON_EN BIT(6)
65 #define QCA807X_LED_FIBER_HDX_ON_EN BIT(5)
66 #define QCA807X_LED_FIBER_1000BX_ON_EN BIT(2)
67 #define QCA807X_LED_FIBER_100FX_ON_EN BIT(1)
68
69 /* Some device repurpose the LED as GPIO out */
70 #define QCA807X_GPIO_FORCE_EN QCA808X_LED_FORCE_EN
71 #define QCA807X_GPIO_FORCE_MODE_MASK QCA808X_LED_FORCE_MODE_MASK
72
73 #define QCA807X_FUNCTION_CONTROL 0x10
74 #define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5)
75 #define QCA807X_FC_MDI_CROSSOVER_AUTO 3
76 #define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX 1
77 #define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI 0
78
79 /* PQSGMII Analog PHY specific */
80 #define PQSGMII_CTRL_REG 0x0
81 #define PQSGMII_ANALOG_SW_RESET BIT(6)
82 #define PQSGMII_DRIVE_CONTROL_1 0xb
83 #define PQSGMII_TX_DRIVER_MASK GENMASK(7, 4)
84 #define PQSGMII_TX_DRIVER_140MV 0x0
85 #define PQSGMII_TX_DRIVER_160MV 0x1
86 #define PQSGMII_TX_DRIVER_180MV 0x2
87 #define PQSGMII_TX_DRIVER_200MV 0x3
88 #define PQSGMII_TX_DRIVER_220MV 0x4
89 #define PQSGMII_TX_DRIVER_240MV 0x5
90 #define PQSGMII_TX_DRIVER_260MV 0x6
91 #define PQSGMII_TX_DRIVER_280MV 0x7
92 #define PQSGMII_TX_DRIVER_300MV 0x8
93 #define PQSGMII_TX_DRIVER_320MV 0x9
94 #define PQSGMII_TX_DRIVER_400MV 0xa
95 #define PQSGMII_TX_DRIVER_500MV 0xb
96 #define PQSGMII_TX_DRIVER_600MV 0xc
97 #define PQSGMII_MODE_CTRL 0x6d
98 #define PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK BIT(0)
99 #define PQSGMII_MMD3_SERDES_CONTROL 0x805a
100
101 #define PHY_ID_QCA8072 0x004dd0b2
102 #define PHY_ID_QCA8075 0x004dd0b1
103
104 #define QCA807X_COMBO_ADDR_OFFSET 4
105 #define QCA807X_PQSGMII_ADDR_OFFSET 5
106 #define SERDES_RESET_SLEEP 100
107
108 enum qca807x_global_phy {
109 QCA807X_COMBO_ADDR = 4,
110 QCA807X_PQSGMII_ADDR = 5,
111 };
112
113 struct qca807x_shared_priv {
114 unsigned int package_mode;
115 u32 tx_drive_strength;
116 };
117
118 struct qca807x_gpio_priv {
119 struct phy_device *phy;
120 };
121
122 struct qca807x_priv {
123 bool dac_full_amplitude;
124 bool dac_full_bias_current;
125 bool dac_disable_bias_current_tweak;
126 };
127
qca807x_cable_test_start(struct phy_device * phydev)128 static int qca807x_cable_test_start(struct phy_device *phydev)
129 {
130 /* we do all the (time consuming) work later */
131 return 0;
132 }
133
qca807x_led_parse_netdev(struct phy_device * phydev,unsigned long rules,u16 * offload_trigger)134 static int qca807x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
135 u16 *offload_trigger)
136 {
137 /* Parsing specific to netdev trigger */
138 switch (phydev->port) {
139 case PORT_TP:
140 if (test_bit(TRIGGER_NETDEV_TX, &rules))
141 *offload_trigger |= QCA808X_LED_TX_BLINK;
142 if (test_bit(TRIGGER_NETDEV_RX, &rules))
143 *offload_trigger |= QCA808X_LED_RX_BLINK;
144 if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
145 *offload_trigger |= QCA808X_LED_SPEED10_ON;
146 if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
147 *offload_trigger |= QCA808X_LED_SPEED100_ON;
148 if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
149 *offload_trigger |= QCA808X_LED_SPEED1000_ON;
150 if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
151 *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
152 if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
153 *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
154 break;
155 case PORT_FIBRE:
156 if (test_bit(TRIGGER_NETDEV_TX, &rules))
157 *offload_trigger |= QCA807X_LED_FIBER_TXACT_BLK_EN;
158 if (test_bit(TRIGGER_NETDEV_RX, &rules))
159 *offload_trigger |= QCA807X_LED_FIBER_RXACT_BLK_EN;
160 if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
161 *offload_trigger |= QCA807X_LED_FIBER_100FX_ON_EN;
162 if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
163 *offload_trigger |= QCA807X_LED_FIBER_1000BX_ON_EN;
164 if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
165 *offload_trigger |= QCA807X_LED_FIBER_HDX_ON_EN;
166 if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
167 *offload_trigger |= QCA807X_LED_FIBER_FDX_ON_EN;
168 break;
169 default:
170 return -EOPNOTSUPP;
171 }
172
173 if (rules && !*offload_trigger)
174 return -EOPNOTSUPP;
175
176 return 0;
177 }
178
qca807x_led_hw_control_enable(struct phy_device * phydev,u8 index)179 static int qca807x_led_hw_control_enable(struct phy_device *phydev, u8 index)
180 {
181 u16 reg;
182
183 if (index > 1)
184 return -EINVAL;
185
186 reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
187 return qca808x_led_reg_hw_control_enable(phydev, reg);
188 }
189
qca807x_led_hw_is_supported(struct phy_device * phydev,u8 index,unsigned long rules)190 static int qca807x_led_hw_is_supported(struct phy_device *phydev, u8 index,
191 unsigned long rules)
192 {
193 u16 offload_trigger = 0;
194
195 if (index > 1)
196 return -EINVAL;
197
198 return qca807x_led_parse_netdev(phydev, rules, &offload_trigger);
199 }
200
qca807x_led_hw_control_set(struct phy_device * phydev,u8 index,unsigned long rules)201 static int qca807x_led_hw_control_set(struct phy_device *phydev, u8 index,
202 unsigned long rules)
203 {
204 u16 reg, mask, offload_trigger = 0;
205 int ret;
206
207 if (index > 1)
208 return -EINVAL;
209
210 ret = qca807x_led_parse_netdev(phydev, rules, &offload_trigger);
211 if (ret)
212 return ret;
213
214 ret = qca807x_led_hw_control_enable(phydev, index);
215 if (ret)
216 return ret;
217
218 switch (phydev->port) {
219 case PORT_TP:
220 reg = QCA807X_MMD7_LED_CTRL(index);
221 mask = QCA808X_LED_PATTERN_MASK;
222 break;
223 case PORT_FIBRE:
224 /* HW control pattern bits are in LED FORCE reg */
225 reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
226 mask = QCA807X_LED_FIBER_PATTERN_MASK;
227 break;
228 default:
229 return -EINVAL;
230 }
231
232 return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, mask,
233 offload_trigger);
234 }
235
qca807x_led_hw_control_status(struct phy_device * phydev,u8 index)236 static bool qca807x_led_hw_control_status(struct phy_device *phydev, u8 index)
237 {
238 u16 reg;
239
240 if (index > 1)
241 return false;
242
243 reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
244 return qca808x_led_reg_hw_control_status(phydev, reg);
245 }
246
qca807x_led_hw_control_get(struct phy_device * phydev,u8 index,unsigned long * rules)247 static int qca807x_led_hw_control_get(struct phy_device *phydev, u8 index,
248 unsigned long *rules)
249 {
250 u16 reg;
251 int val;
252
253 if (index > 1)
254 return -EINVAL;
255
256 /* Check if we have hw control enabled */
257 if (qca807x_led_hw_control_status(phydev, index))
258 return -EINVAL;
259
260 /* Parsing specific to netdev trigger */
261 switch (phydev->port) {
262 case PORT_TP:
263 reg = QCA807X_MMD7_LED_CTRL(index);
264 val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
265 if (val & QCA808X_LED_TX_BLINK)
266 set_bit(TRIGGER_NETDEV_TX, rules);
267 if (val & QCA808X_LED_RX_BLINK)
268 set_bit(TRIGGER_NETDEV_RX, rules);
269 if (val & QCA808X_LED_SPEED10_ON)
270 set_bit(TRIGGER_NETDEV_LINK_10, rules);
271 if (val & QCA808X_LED_SPEED100_ON)
272 set_bit(TRIGGER_NETDEV_LINK_100, rules);
273 if (val & QCA808X_LED_SPEED1000_ON)
274 set_bit(TRIGGER_NETDEV_LINK_1000, rules);
275 if (val & QCA808X_LED_HALF_DUPLEX_ON)
276 set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
277 if (val & QCA808X_LED_FULL_DUPLEX_ON)
278 set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
279 break;
280 case PORT_FIBRE:
281 /* HW control pattern bits are in LED FORCE reg */
282 reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
283 val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
284 if (val & QCA807X_LED_FIBER_TXACT_BLK_EN)
285 set_bit(TRIGGER_NETDEV_TX, rules);
286 if (val & QCA807X_LED_FIBER_RXACT_BLK_EN)
287 set_bit(TRIGGER_NETDEV_RX, rules);
288 if (val & QCA807X_LED_FIBER_100FX_ON_EN)
289 set_bit(TRIGGER_NETDEV_LINK_100, rules);
290 if (val & QCA807X_LED_FIBER_1000BX_ON_EN)
291 set_bit(TRIGGER_NETDEV_LINK_1000, rules);
292 if (val & QCA807X_LED_FIBER_HDX_ON_EN)
293 set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
294 if (val & QCA807X_LED_FIBER_FDX_ON_EN)
295 set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
296 break;
297 default:
298 return -EINVAL;
299 }
300
301 return 0;
302 }
303
qca807x_led_hw_control_reset(struct phy_device * phydev,u8 index)304 static int qca807x_led_hw_control_reset(struct phy_device *phydev, u8 index)
305 {
306 u16 reg, mask;
307
308 if (index > 1)
309 return -EINVAL;
310
311 switch (phydev->port) {
312 case PORT_TP:
313 reg = QCA807X_MMD7_LED_CTRL(index);
314 mask = QCA808X_LED_PATTERN_MASK;
315 break;
316 case PORT_FIBRE:
317 /* HW control pattern bits are in LED FORCE reg */
318 reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
319 mask = QCA807X_LED_FIBER_PATTERN_MASK;
320 break;
321 default:
322 return -EINVAL;
323 }
324
325 return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, mask);
326 }
327
qca807x_led_brightness_set(struct phy_device * phydev,u8 index,enum led_brightness value)328 static int qca807x_led_brightness_set(struct phy_device *phydev,
329 u8 index, enum led_brightness value)
330 {
331 u16 reg;
332 int ret;
333
334 if (index > 1)
335 return -EINVAL;
336
337 /* If we are setting off the LED reset any hw control rule */
338 if (!value) {
339 ret = qca807x_led_hw_control_reset(phydev, index);
340 if (ret)
341 return ret;
342 }
343
344 reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
345 return qca808x_led_reg_brightness_set(phydev, reg, value);
346 }
347
qca807x_led_blink_set(struct phy_device * phydev,u8 index,unsigned long * delay_on,unsigned long * delay_off)348 static int qca807x_led_blink_set(struct phy_device *phydev, u8 index,
349 unsigned long *delay_on,
350 unsigned long *delay_off)
351 {
352 u16 reg;
353
354 if (index > 1)
355 return -EINVAL;
356
357 reg = QCA807X_MMD7_LED_FORCE_CTRL(index);
358 return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off);
359 }
360
361 #ifdef CONFIG_GPIOLIB
qca807x_gpio_get_direction(struct gpio_chip * gc,unsigned int offset)362 static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
363 {
364 return GPIO_LINE_DIRECTION_OUT;
365 }
366
qca807x_gpio_get(struct gpio_chip * gc,unsigned int offset)367 static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset)
368 {
369 struct qca807x_gpio_priv *priv = gpiochip_get_data(gc);
370 u16 reg;
371 int val;
372
373 reg = QCA807X_MMD7_LED_FORCE_CTRL(offset);
374 val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg);
375
376 return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val);
377 }
378
qca807x_gpio_set(struct gpio_chip * gc,unsigned int offset,int value)379 static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
380 {
381 struct qca807x_gpio_priv *priv = gpiochip_get_data(gc);
382 u16 reg;
383 int val;
384
385 reg = QCA807X_MMD7_LED_FORCE_CTRL(offset);
386
387 val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg);
388 val &= ~QCA807X_GPIO_FORCE_MODE_MASK;
389 val |= QCA807X_GPIO_FORCE_EN;
390 val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value);
391
392 phy_write_mmd(priv->phy, MDIO_MMD_AN, reg, val);
393 }
394
qca807x_gpio_dir_out(struct gpio_chip * gc,unsigned int offset,int value)395 static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value)
396 {
397 qca807x_gpio_set(gc, offset, value);
398
399 return 0;
400 }
401
qca807x_gpio(struct phy_device * phydev)402 static int qca807x_gpio(struct phy_device *phydev)
403 {
404 struct device *dev = &phydev->mdio.dev;
405 struct qca807x_gpio_priv *priv;
406 struct gpio_chip *gc;
407
408 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
409 if (!priv)
410 return -ENOMEM;
411
412 priv->phy = phydev;
413
414 gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
415 if (!gc)
416 return -ENOMEM;
417
418 gc->label = dev_name(dev);
419 gc->base = -1;
420 gc->ngpio = 2;
421 gc->parent = dev;
422 gc->owner = THIS_MODULE;
423 gc->can_sleep = true;
424 gc->get_direction = qca807x_gpio_get_direction;
425 gc->direction_output = qca807x_gpio_dir_out;
426 gc->get = qca807x_gpio_get;
427 gc->set = qca807x_gpio_set;
428
429 return devm_gpiochip_add_data(dev, gc, priv);
430 }
431 #endif
432
qca807x_read_fiber_status(struct phy_device * phydev)433 static int qca807x_read_fiber_status(struct phy_device *phydev)
434 {
435 bool changed;
436 int ss, err;
437
438 err = genphy_c37_read_status(phydev, &changed);
439 if (err || !changed)
440 return err;
441
442 /* Read the QCA807x PHY-Specific Status register fiber page,
443 * which indicates the speed and duplex that the PHY is actually
444 * using, irrespective of whether we are in autoneg mode or not.
445 */
446 ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
447 if (ss < 0)
448 return ss;
449
450 phydev->speed = SPEED_UNKNOWN;
451 phydev->duplex = DUPLEX_UNKNOWN;
452 if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
453 switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) {
454 case AT803X_SS_SPEED_100:
455 phydev->speed = SPEED_100;
456 break;
457 case AT803X_SS_SPEED_1000:
458 phydev->speed = SPEED_1000;
459 break;
460 }
461
462 if (ss & AT803X_SS_DUPLEX)
463 phydev->duplex = DUPLEX_FULL;
464 else
465 phydev->duplex = DUPLEX_HALF;
466 }
467
468 return 0;
469 }
470
qca807x_read_status(struct phy_device * phydev)471 static int qca807x_read_status(struct phy_device *phydev)
472 {
473 if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) {
474 switch (phydev->port) {
475 case PORT_FIBRE:
476 return qca807x_read_fiber_status(phydev);
477 case PORT_TP:
478 return at803x_read_status(phydev);
479 default:
480 return -EINVAL;
481 }
482 }
483
484 return at803x_read_status(phydev);
485 }
486
qca807x_phy_package_probe_once(struct phy_device * phydev)487 static int qca807x_phy_package_probe_once(struct phy_device *phydev)
488 {
489 struct phy_package_shared *shared = phydev->shared;
490 struct qca807x_shared_priv *priv = shared->priv;
491 unsigned int tx_drive_strength;
492 const char *package_mode_name;
493
494 /* Default to 600mw if not defined */
495 if (of_property_read_u32(shared->np, "qcom,tx-drive-strength-milliwatt",
496 &tx_drive_strength))
497 tx_drive_strength = 600;
498
499 switch (tx_drive_strength) {
500 case 140:
501 priv->tx_drive_strength = PQSGMII_TX_DRIVER_140MV;
502 break;
503 case 160:
504 priv->tx_drive_strength = PQSGMII_TX_DRIVER_160MV;
505 break;
506 case 180:
507 priv->tx_drive_strength = PQSGMII_TX_DRIVER_180MV;
508 break;
509 case 200:
510 priv->tx_drive_strength = PQSGMII_TX_DRIVER_200MV;
511 break;
512 case 220:
513 priv->tx_drive_strength = PQSGMII_TX_DRIVER_220MV;
514 break;
515 case 240:
516 priv->tx_drive_strength = PQSGMII_TX_DRIVER_240MV;
517 break;
518 case 260:
519 priv->tx_drive_strength = PQSGMII_TX_DRIVER_260MV;
520 break;
521 case 280:
522 priv->tx_drive_strength = PQSGMII_TX_DRIVER_280MV;
523 break;
524 case 300:
525 priv->tx_drive_strength = PQSGMII_TX_DRIVER_300MV;
526 break;
527 case 320:
528 priv->tx_drive_strength = PQSGMII_TX_DRIVER_320MV;
529 break;
530 case 400:
531 priv->tx_drive_strength = PQSGMII_TX_DRIVER_400MV;
532 break;
533 case 500:
534 priv->tx_drive_strength = PQSGMII_TX_DRIVER_500MV;
535 break;
536 case 600:
537 priv->tx_drive_strength = PQSGMII_TX_DRIVER_600MV;
538 break;
539 default:
540 return -EINVAL;
541 }
542
543 priv->package_mode = PHY_INTERFACE_MODE_NA;
544 if (!of_property_read_string(shared->np, "qcom,package-mode",
545 &package_mode_name)) {
546 if (!strcasecmp(package_mode_name,
547 phy_modes(PHY_INTERFACE_MODE_PSGMII)))
548 priv->package_mode = PHY_INTERFACE_MODE_PSGMII;
549 else if (!strcasecmp(package_mode_name,
550 phy_modes(PHY_INTERFACE_MODE_QSGMII)))
551 priv->package_mode = PHY_INTERFACE_MODE_QSGMII;
552 else
553 return -EINVAL;
554 }
555
556 return 0;
557 }
558
qca807x_phy_package_config_init_once(struct phy_device * phydev)559 static int qca807x_phy_package_config_init_once(struct phy_device *phydev)
560 {
561 struct phy_package_shared *shared = phydev->shared;
562 struct qca807x_shared_priv *priv = shared->priv;
563 int val, ret;
564
565 /* Make sure PHY follow PHY package mode if enforced */
566 if (priv->package_mode != PHY_INTERFACE_MODE_NA &&
567 phydev->interface != priv->package_mode)
568 return -EINVAL;
569
570 phy_lock_mdio_bus(phydev);
571
572 /* Set correct PHY package mode */
573 val = __phy_package_read(phydev, QCA807X_COMBO_ADDR,
574 QCA807X_CHIP_CONFIGURATION);
575 val &= ~QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK;
576 /* package_mode can be QSGMII or PSGMII and we validate
577 * this in probe_once.
578 * With package_mode to NA, we default to PSGMII.
579 */
580 switch (priv->package_mode) {
581 case PHY_INTERFACE_MODE_QSGMII:
582 val |= QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII;
583 break;
584 case PHY_INTERFACE_MODE_PSGMII:
585 default:
586 val |= QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER;
587 }
588 ret = __phy_package_write(phydev, QCA807X_COMBO_ADDR,
589 QCA807X_CHIP_CONFIGURATION, val);
590 if (ret)
591 goto exit;
592
593 /* After mode change Serdes reset is required */
594 val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR,
595 PQSGMII_CTRL_REG);
596 val &= ~PQSGMII_ANALOG_SW_RESET;
597 ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR,
598 PQSGMII_CTRL_REG, val);
599 if (ret)
600 goto exit;
601
602 msleep(SERDES_RESET_SLEEP);
603
604 val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR,
605 PQSGMII_CTRL_REG);
606 val |= PQSGMII_ANALOG_SW_RESET;
607 ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR,
608 PQSGMII_CTRL_REG, val);
609 if (ret)
610 goto exit;
611
612 /* Workaround to enable AZ transmitting ability */
613 val = __phy_package_read_mmd(phydev, QCA807X_PQSGMII_ADDR,
614 MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL);
615 val &= ~PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK;
616 ret = __phy_package_write_mmd(phydev, QCA807X_PQSGMII_ADDR,
617 MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL, val);
618 if (ret)
619 goto exit;
620
621 /* Set PQSGMII TX AMP strength */
622 val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR,
623 PQSGMII_DRIVE_CONTROL_1);
624 val &= ~PQSGMII_TX_DRIVER_MASK;
625 val |= FIELD_PREP(PQSGMII_TX_DRIVER_MASK, priv->tx_drive_strength);
626 ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR,
627 PQSGMII_DRIVE_CONTROL_1, val);
628 if (ret)
629 goto exit;
630
631 /* Prevent PSGMII going into hibernation via PSGMII self test */
632 val = __phy_package_read_mmd(phydev, QCA807X_COMBO_ADDR,
633 MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL);
634 val &= ~BIT(1);
635 ret = __phy_package_write_mmd(phydev, QCA807X_COMBO_ADDR,
636 MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL, val);
637
638 exit:
639 phy_unlock_mdio_bus(phydev);
640
641 return ret;
642 }
643
qca807x_sfp_insert(void * upstream,const struct sfp_eeprom_id * id)644 static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
645 {
646 struct phy_device *phydev = upstream;
647 __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
648 phy_interface_t iface;
649 int ret;
650 DECLARE_PHY_INTERFACE_MASK(interfaces);
651
652 sfp_parse_support(phydev->sfp_bus, id, support, interfaces);
653 iface = sfp_select_interface(phydev->sfp_bus, support);
654
655 dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface));
656
657 switch (iface) {
658 case PHY_INTERFACE_MODE_1000BASEX:
659 case PHY_INTERFACE_MODE_100BASEX:
660 /* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */
661 ret = phy_modify(phydev,
662 QCA807X_CHIP_CONFIGURATION,
663 QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK,
664 QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER);
665 /* Enable fiber mode autodection (1000Base-X or 100Base-FX) */
666 ret = phy_set_bits_mmd(phydev,
667 MDIO_MMD_AN,
668 QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION,
669 QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN);
670 /* Select fiber page */
671 ret = phy_clear_bits(phydev,
672 QCA807X_CHIP_CONFIGURATION,
673 QCA807X_BT_BX_REG_SEL);
674
675 phydev->port = PORT_FIBRE;
676 break;
677 default:
678 dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n");
679 return -EINVAL;
680 }
681
682 return ret;
683 }
684
qca807x_sfp_remove(void * upstream)685 static void qca807x_sfp_remove(void *upstream)
686 {
687 struct phy_device *phydev = upstream;
688
689 /* Select copper page */
690 phy_set_bits(phydev,
691 QCA807X_CHIP_CONFIGURATION,
692 QCA807X_BT_BX_REG_SEL);
693
694 phydev->port = PORT_TP;
695 }
696
697 static const struct sfp_upstream_ops qca807x_sfp_ops = {
698 .attach = phy_sfp_attach,
699 .detach = phy_sfp_detach,
700 .module_insert = qca807x_sfp_insert,
701 .module_remove = qca807x_sfp_remove,
702 .connect_phy = phy_sfp_connect_phy,
703 .disconnect_phy = phy_sfp_disconnect_phy,
704 };
705
qca807x_probe(struct phy_device * phydev)706 static int qca807x_probe(struct phy_device *phydev)
707 {
708 struct device_node *node = phydev->mdio.dev.of_node;
709 struct qca807x_shared_priv *shared_priv;
710 struct device *dev = &phydev->mdio.dev;
711 struct phy_package_shared *shared;
712 struct qca807x_priv *priv;
713 int ret;
714
715 ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv));
716 if (ret)
717 return ret;
718
719 if (phy_package_probe_once(phydev)) {
720 ret = qca807x_phy_package_probe_once(phydev);
721 if (ret)
722 return ret;
723 }
724
725 shared = phydev->shared;
726 shared_priv = shared->priv;
727
728 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
729 if (!priv)
730 return -ENOMEM;
731
732 priv->dac_full_amplitude = of_property_read_bool(node, "qcom,dac-full-amplitude");
733 priv->dac_full_bias_current = of_property_read_bool(node, "qcom,dac-full-bias-current");
734 priv->dac_disable_bias_current_tweak = of_property_read_bool(node,
735 "qcom,dac-disable-bias-current-tweak");
736
737 #if IS_ENABLED(CONFIG_GPIOLIB)
738 /* Do not register a GPIO controller unless flagged for it */
739 if (of_property_read_bool(node, "gpio-controller")) {
740 ret = qca807x_gpio(phydev);
741 if (ret)
742 return ret;
743 }
744 #endif
745
746 /* Attach SFP bus on combo port*/
747 if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) {
748 ret = phy_sfp_probe(phydev, &qca807x_sfp_ops);
749 if (ret)
750 return ret;
751 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
752 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising);
753 }
754
755 phydev->priv = priv;
756
757 return 0;
758 }
759
qca807x_config_init(struct phy_device * phydev)760 static int qca807x_config_init(struct phy_device *phydev)
761 {
762 struct qca807x_priv *priv = phydev->priv;
763 u16 control_dac;
764 int ret;
765
766 if (phy_package_init_once(phydev)) {
767 ret = qca807x_phy_package_config_init_once(phydev);
768 if (ret)
769 return ret;
770 }
771
772 control_dac = phy_read_mmd(phydev, MDIO_MMD_AN,
773 QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH);
774 control_dac &= ~QCA807X_CONTROL_DAC_MASK;
775 if (!priv->dac_full_amplitude)
776 control_dac |= QCA807X_CONTROL_DAC_DSP_AMPLITUDE;
777 if (!priv->dac_full_amplitude)
778 control_dac |= QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT;
779 if (!priv->dac_disable_bias_current_tweak)
780 control_dac |= QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK;
781 return phy_write_mmd(phydev, MDIO_MMD_AN,
782 QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH,
783 control_dac);
784 }
785
786 static struct phy_driver qca807x_drivers[] = {
787 {
788 PHY_ID_MATCH_EXACT(PHY_ID_QCA8072),
789 .name = "Qualcomm QCA8072",
790 .flags = PHY_POLL_CABLE_TEST,
791 /* PHY_GBIT_FEATURES */
792 .probe = qca807x_probe,
793 .config_init = qca807x_config_init,
794 .read_status = qca807x_read_status,
795 .config_intr = at803x_config_intr,
796 .handle_interrupt = at803x_handle_interrupt,
797 .soft_reset = genphy_soft_reset,
798 .get_tunable = at803x_get_tunable,
799 .set_tunable = at803x_set_tunable,
800 .resume = genphy_resume,
801 .suspend = genphy_suspend,
802 .cable_test_start = qca807x_cable_test_start,
803 .cable_test_get_status = qca808x_cable_test_get_status,
804 },
805 {
806 PHY_ID_MATCH_EXACT(PHY_ID_QCA8075),
807 .name = "Qualcomm QCA8075",
808 .flags = PHY_POLL_CABLE_TEST,
809 /* PHY_GBIT_FEATURES */
810 .probe = qca807x_probe,
811 .config_init = qca807x_config_init,
812 .read_status = qca807x_read_status,
813 .config_intr = at803x_config_intr,
814 .handle_interrupt = at803x_handle_interrupt,
815 .soft_reset = genphy_soft_reset,
816 .get_tunable = at803x_get_tunable,
817 .set_tunable = at803x_set_tunable,
818 .resume = genphy_resume,
819 .suspend = genphy_suspend,
820 .cable_test_start = qca807x_cable_test_start,
821 .cable_test_get_status = qca808x_cable_test_get_status,
822 .led_brightness_set = qca807x_led_brightness_set,
823 .led_blink_set = qca807x_led_blink_set,
824 .led_hw_is_supported = qca807x_led_hw_is_supported,
825 .led_hw_control_set = qca807x_led_hw_control_set,
826 .led_hw_control_get = qca807x_led_hw_control_get,
827 },
828 };
829 module_phy_driver(qca807x_drivers);
830
831 static struct mdio_device_id __maybe_unused qca807x_tbl[] = {
832 { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) },
833 { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) },
834 { }
835 };
836
837 MODULE_AUTHOR("Robert Marko <robert.marko@sartura.hr>");
838 MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
839 MODULE_DESCRIPTION("Qualcomm QCA807x PHY driver");
840 MODULE_DEVICE_TABLE(mdio, qca807x_tbl);
841 MODULE_LICENSE("GPL");
842