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