1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Marvell 88Q2XXX automotive 100BASE-T1/1000BASE-T1 PHY driver
4 *
5 * Derived from Marvell Q222x API
6 *
7 * Copyright (C) 2024 Liebherr-Electronics and Drives GmbH
8 */
9#include <linux/ethtool_netlink.h>
10#include <linux/marvell_phy.h>
11#include <linux/phy.h>
12#include <linux/hwmon.h>
13
14#define PHY_ID_88Q2220_REVB0	(MARVELL_PHY_ID_88Q2220 | 0x1)
15
16#define MDIO_MMD_AN_MV_STAT			32769
17#define MDIO_MMD_AN_MV_STAT_ANEG		0x0100
18#define MDIO_MMD_AN_MV_STAT_LOCAL_RX		0x1000
19#define MDIO_MMD_AN_MV_STAT_REMOTE_RX		0x2000
20#define MDIO_MMD_AN_MV_STAT_LOCAL_MASTER	0x4000
21#define MDIO_MMD_AN_MV_STAT_MS_CONF_FAULT	0x8000
22
23#define MDIO_MMD_AN_MV_STAT2			32794
24#define MDIO_MMD_AN_MV_STAT2_AN_RESOLVED	0x0800
25#define MDIO_MMD_AN_MV_STAT2_100BT1		0x2000
26#define MDIO_MMD_AN_MV_STAT2_1000BT1		0x4000
27
28#define MDIO_MMD_PCS_MV_INT_EN			32784
29#define MDIO_MMD_PCS_MV_INT_EN_LINK_UP		0x0040
30#define MDIO_MMD_PCS_MV_INT_EN_LINK_DOWN	0x0080
31#define MDIO_MMD_PCS_MV_INT_EN_100BT1		0x1000
32
33#define MDIO_MMD_PCS_MV_GPIO_INT_STAT			32785
34#define MDIO_MMD_PCS_MV_GPIO_INT_STAT_LINK_UP		0x0040
35#define MDIO_MMD_PCS_MV_GPIO_INT_STAT_LINK_DOWN		0x0080
36#define MDIO_MMD_PCS_MV_GPIO_INT_STAT_100BT1_GEN	0x1000
37
38#define MDIO_MMD_PCS_MV_GPIO_INT_CTRL			32787
39#define MDIO_MMD_PCS_MV_GPIO_INT_CTRL_TRI_DIS		0x0800
40
41#define MDIO_MMD_PCS_MV_TEMP_SENSOR1			32833
42#define MDIO_MMD_PCS_MV_TEMP_SENSOR1_RAW_INT		0x0001
43#define MDIO_MMD_PCS_MV_TEMP_SENSOR1_INT		0x0040
44#define MDIO_MMD_PCS_MV_TEMP_SENSOR1_INT_EN		0x0080
45
46#define MDIO_MMD_PCS_MV_TEMP_SENSOR2			32834
47#define MDIO_MMD_PCS_MV_TEMP_SENSOR2_DIS_MASK		0xc000
48
49#define MDIO_MMD_PCS_MV_TEMP_SENSOR3			32835
50#define MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK	0xff00
51#define MDIO_MMD_PCS_MV_TEMP_SENSOR3_MASK		0x00ff
52
53#define MDIO_MMD_PCS_MV_100BT1_STAT1			33032
54#define MDIO_MMD_PCS_MV_100BT1_STAT1_IDLE_ERROR		0x00ff
55#define MDIO_MMD_PCS_MV_100BT1_STAT1_JABBER		0x0100
56#define MDIO_MMD_PCS_MV_100BT1_STAT1_LINK		0x0200
57#define MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_RX		0x1000
58#define MDIO_MMD_PCS_MV_100BT1_STAT1_REMOTE_RX		0x2000
59#define MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_MASTER	0x4000
60
61#define MDIO_MMD_PCS_MV_100BT1_STAT2		33033
62#define MDIO_MMD_PCS_MV_100BT1_STAT2_JABBER	0x0001
63#define MDIO_MMD_PCS_MV_100BT1_STAT2_POL	0x0002
64#define MDIO_MMD_PCS_MV_100BT1_STAT2_LINK	0x0004
65#define MDIO_MMD_PCS_MV_100BT1_STAT2_ANGE	0x0008
66
67#define MDIO_MMD_PCS_MV_100BT1_INT_EN			33042
68#define MDIO_MMD_PCS_MV_100BT1_INT_EN_LINKEVENT		0x0400
69
70#define MDIO_MMD_PCS_MV_COPPER_INT_STAT			33043
71#define MDIO_MMD_PCS_MV_COPPER_INT_STAT_LINKEVENT	0x0400
72
73#define MDIO_MMD_PCS_MV_RX_STAT			33328
74
75#define MDIO_MMD_PCS_MV_TDR_RESET			65226
76#define MDIO_MMD_PCS_MV_TDR_RESET_TDR_RST		0x1000
77
78#define MDIO_MMD_PCS_MV_TDR_OFF_SHORT_CABLE		65241
79
80#define MDIO_MMD_PCS_MV_TDR_OFF_LONG_CABLE		65242
81
82#define MDIO_MMD_PCS_MV_TDR_STATUS			65245
83#define MDIO_MMD_PCS_MV_TDR_STATUS_MASK			0x0003
84#define MDIO_MMD_PCS_MV_TDR_STATUS_OFF			0x0001
85#define MDIO_MMD_PCS_MV_TDR_STATUS_ON			0x0002
86#define MDIO_MMD_PCS_MV_TDR_STATUS_DIST_MASK		0xff00
87#define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_MASK	0x00f0
88#define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_SHORT	0x0030
89#define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_OPEN	0x00e0
90#define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_OK		0x0070
91#define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_IN_PROGR	0x0080
92#define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_NOISE	0x0050
93
94#define MDIO_MMD_PCS_MV_TDR_OFF_CUTOFF			65246
95
96struct mmd_val {
97	int devad;
98	u32 regnum;
99	u16 val;
100};
101
102static const struct mmd_val mv88q222x_revb0_init_seq0[] = {
103	{ MDIO_MMD_PCS, 0x8033, 0x6801 },
104	{ MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
105	{ MDIO_MMD_PMAPMD, MDIO_CTRL1,
106	  MDIO_CTRL1_LPOWER | MDIO_PMA_CTRL1_SPEED1000 },
107	{ MDIO_MMD_PCS, 0xfe1b, 0x48 },
108	{ MDIO_MMD_PCS, 0xffe4, 0x6b6 },
109	{ MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0 },
110	{ MDIO_MMD_PCS, MDIO_CTRL1, 0x0 },
111};
112
113static const struct mmd_val mv88q222x_revb0_init_seq1[] = {
114	{ MDIO_MMD_PCS, 0xfe79, 0x0 },
115	{ MDIO_MMD_PCS, 0xfe07, 0x125a },
116	{ MDIO_MMD_PCS, 0xfe09, 0x1288 },
117	{ MDIO_MMD_PCS, 0xfe08, 0x2588 },
118	{ MDIO_MMD_PCS, 0xfe11, 0x1105 },
119	{ MDIO_MMD_PCS, 0xfe72, 0x042c },
120	{ MDIO_MMD_PCS, 0xfbba, 0xcb2 },
121	{ MDIO_MMD_PCS, 0xfbbb, 0xc4a },
122	{ MDIO_MMD_AN, 0x8032, 0x2020 },
123	{ MDIO_MMD_AN, 0x8031, 0xa28 },
124	{ MDIO_MMD_AN, 0x8031, 0xc28 },
125	{ MDIO_MMD_PCS, 0xffdb, 0xfc10 },
126	{ MDIO_MMD_PCS, 0xfe1b, 0x58 },
127	{ MDIO_MMD_PCS, 0xfe79, 0x4 },
128	{ MDIO_MMD_PCS, 0xfe5f, 0xe8 },
129	{ MDIO_MMD_PCS, 0xfe05, 0x755c },
130};
131
132static int mv88q2xxx_soft_reset(struct phy_device *phydev)
133{
134	int ret;
135	int val;
136
137	ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
138			    MDIO_PCS_1000BT1_CTRL, MDIO_PCS_1000BT1_CTRL_RESET);
139	if (ret < 0)
140		return ret;
141
142	return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PCS,
143					 MDIO_PCS_1000BT1_CTRL, val,
144					 !(val & MDIO_PCS_1000BT1_CTRL_RESET),
145					 50000, 600000, true);
146}
147
148static int mv88q2xxx_read_link_gbit(struct phy_device *phydev)
149{
150	int ret;
151	bool link = false;
152
153	/* Read vendor specific Auto-Negotiation status register to get local
154	 * and remote receiver status according to software initialization
155	 * guide. However, when not in polling mode the local and remote
156	 * receiver status are not evaluated due to the Marvell 88Q2xxx APIs.
157	 */
158	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_MMD_AN_MV_STAT);
159	if (ret < 0) {
160		return ret;
161	} else if (((ret & MDIO_MMD_AN_MV_STAT_LOCAL_RX) &&
162		   (ret & MDIO_MMD_AN_MV_STAT_REMOTE_RX)) ||
163		   !phy_polling_mode(phydev)) {
164		/* The link state is latched low so that momentary link
165		 * drops can be detected. Do not double-read the status
166		 * in polling mode to detect such short link drops except
167		 * the link was already down.
168		 */
169		if (!phy_polling_mode(phydev) || !phydev->link) {
170			ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
171					   MDIO_PCS_1000BT1_STAT);
172			if (ret < 0)
173				return ret;
174			else if (ret & MDIO_PCS_1000BT1_STAT_LINK)
175				link = true;
176		}
177
178		if (!link) {
179			ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
180					   MDIO_PCS_1000BT1_STAT);
181			if (ret < 0)
182				return ret;
183			else if (ret & MDIO_PCS_1000BT1_STAT_LINK)
184				link = true;
185		}
186	}
187
188	phydev->link = link;
189
190	return 0;
191}
192
193static int mv88q2xxx_read_link_100m(struct phy_device *phydev)
194{
195	int ret;
196
197	/* The link state is latched low so that momentary link
198	 * drops can be detected. Do not double-read the status
199	 * in polling mode to detect such short link drops except
200	 * the link was already down. In case we are not polling,
201	 * we always read the realtime status.
202	 */
203	if (!phy_polling_mode(phydev)) {
204		phydev->link = false;
205		ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
206				   MDIO_MMD_PCS_MV_100BT1_STAT2);
207		if (ret < 0)
208			return ret;
209
210		if (ret & MDIO_MMD_PCS_MV_100BT1_STAT2_LINK)
211			phydev->link = true;
212
213		return 0;
214	} else if (!phydev->link) {
215		ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
216				   MDIO_MMD_PCS_MV_100BT1_STAT1);
217		if (ret < 0)
218			return ret;
219		else if (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LINK)
220			goto out;
221	}
222
223	ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_100BT1_STAT1);
224	if (ret < 0)
225		return ret;
226
227out:
228	/* Check if we have link and if the remote and local receiver are ok */
229	if ((ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LINK) &&
230	    (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_RX) &&
231	    (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_REMOTE_RX))
232		phydev->link = true;
233	else
234		phydev->link = false;
235
236	return 0;
237}
238
239static int mv88q2xxx_read_link(struct phy_device *phydev)
240{
241	/* The 88Q2XXX PHYs do not have the PMA/PMD status register available,
242	 * therefore we need to read the link status from the vendor specific
243	 * registers depending on the speed.
244	 */
245
246	if (phydev->speed == SPEED_1000)
247		return mv88q2xxx_read_link_gbit(phydev);
248	else if (phydev->speed == SPEED_100)
249		return mv88q2xxx_read_link_100m(phydev);
250
251	phydev->link = false;
252	return 0;
253}
254
255static int mv88q2xxx_read_master_slave_state(struct phy_device *phydev)
256{
257	int ret;
258
259	phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
260	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_MMD_AN_MV_STAT);
261	if (ret < 0)
262		return ret;
263
264	if (ret & MDIO_MMD_AN_MV_STAT_LOCAL_MASTER)
265		phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
266	else
267		phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
268
269	return 0;
270}
271
272static int mv88q2xxx_read_aneg_speed(struct phy_device *phydev)
273{
274	int ret;
275
276	phydev->speed = SPEED_UNKNOWN;
277	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_MMD_AN_MV_STAT2);
278	if (ret < 0)
279		return ret;
280
281	if (!(ret & MDIO_MMD_AN_MV_STAT2_AN_RESOLVED))
282		return 0;
283
284	if (ret & MDIO_MMD_AN_MV_STAT2_100BT1)
285		phydev->speed = SPEED_100;
286	else if (ret & MDIO_MMD_AN_MV_STAT2_1000BT1)
287		phydev->speed = SPEED_1000;
288
289	return 0;
290}
291
292static int mv88q2xxx_read_status(struct phy_device *phydev)
293{
294	int ret;
295
296	if (phydev->autoneg == AUTONEG_ENABLE) {
297		/* We have to get the negotiated speed first, otherwise we are
298		 * not able to read the link.
299		 */
300		ret = mv88q2xxx_read_aneg_speed(phydev);
301		if (ret < 0)
302			return ret;
303
304		ret = mv88q2xxx_read_link(phydev);
305		if (ret < 0)
306			return ret;
307
308		ret = genphy_c45_read_lpa(phydev);
309		if (ret < 0)
310			return ret;
311
312		ret = genphy_c45_baset1_read_status(phydev);
313		if (ret < 0)
314			return ret;
315
316		ret = mv88q2xxx_read_master_slave_state(phydev);
317		if (ret < 0)
318			return ret;
319
320		phy_resolve_aneg_linkmode(phydev);
321
322		return 0;
323	}
324
325	ret = mv88q2xxx_read_link(phydev);
326	if (ret < 0)
327		return ret;
328
329	return genphy_c45_read_pma(phydev);
330}
331
332static int mv88q2xxx_get_features(struct phy_device *phydev)
333{
334	int ret;
335
336	ret = genphy_c45_pma_read_abilities(phydev);
337	if (ret)
338		return ret;
339
340	/* We need to read the baset1 extended abilities manually because the
341	 * PHY does not signalize it has the extended abilities register
342	 * available.
343	 */
344	ret = genphy_c45_pma_baset1_read_abilities(phydev);
345	if (ret)
346		return ret;
347
348	/* The PHY signalizes it supports autonegotiation. Unfortunately, so
349	 * far it was not possible to get a link even when following the init
350	 * sequence provided by Marvell. Disable it for now until a proper
351	 * workaround is found or a new PHY revision is released.
352	 */
353	if (phydev->drv->phy_id == MARVELL_PHY_ID_88Q2110)
354		linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
355				   phydev->supported);
356
357	return 0;
358}
359
360static int mv88q2xxx_config_aneg(struct phy_device *phydev)
361{
362	int ret;
363
364	ret = genphy_c45_config_aneg(phydev);
365	if (ret)
366		return ret;
367
368	return phydev->drv->soft_reset(phydev);
369}
370
371static int mv88q2xxx_config_init(struct phy_device *phydev)
372{
373	/* The 88Q2XXX PHYs do have the extended ability register available, but
374	 * register MDIO_PMA_EXTABLE where they should signalize it does not
375	 * work according to specification. Therefore, we force it here.
376	 */
377	phydev->pma_extable = MDIO_PMA_EXTABLE_BT1;
378
379	/* Configure interrupt with default settings, output is driven low for
380	 * active interrupt and high for inactive.
381	 */
382	if (phy_interrupt_is_valid(phydev))
383		return phy_set_bits_mmd(phydev, MDIO_MMD_PCS,
384					MDIO_MMD_PCS_MV_GPIO_INT_CTRL,
385					MDIO_MMD_PCS_MV_GPIO_INT_CTRL_TRI_DIS);
386
387	return 0;
388}
389
390static int mv88q2xxx_get_sqi(struct phy_device *phydev)
391{
392	int ret;
393
394	if (phydev->speed == SPEED_100) {
395		/* Read the SQI from the vendor specific receiver status
396		 * register
397		 */
398		ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
399				   MDIO_MMD_PCS_MV_RX_STAT);
400		if (ret < 0)
401			return ret;
402
403		ret = ret >> 12;
404	} else {
405		/* Read from vendor specific registers, they are not documented
406		 * but can be found in the Software Initialization Guide. Only
407		 * revisions >= A0 are supported.
408		 */
409		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, 0xfc5d, 0xff, 0xac);
410		if (ret < 0)
411			return ret;
412
413		ret = phy_read_mmd(phydev, MDIO_MMD_PCS, 0xfc88);
414		if (ret < 0)
415			return ret;
416	}
417
418	return ret & 0x0f;
419}
420
421static int mv88q2xxx_get_sqi_max(struct phy_device *phydev)
422{
423	return 15;
424}
425
426static int mv88q2xxx_config_intr(struct phy_device *phydev)
427{
428	int ret;
429
430	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
431		/* Enable interrupts for 1000BASE-T1 link up and down events
432		 * and enable general interrupts for 100BASE-T1.
433		 */
434		ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
435				    MDIO_MMD_PCS_MV_INT_EN,
436				    MDIO_MMD_PCS_MV_INT_EN_LINK_UP |
437				    MDIO_MMD_PCS_MV_INT_EN_LINK_DOWN |
438				    MDIO_MMD_PCS_MV_INT_EN_100BT1);
439		if (ret < 0)
440			return ret;
441
442		/* Enable interrupts for 100BASE-T1 link events */
443		return phy_write_mmd(phydev, MDIO_MMD_PCS,
444				     MDIO_MMD_PCS_MV_100BT1_INT_EN,
445				     MDIO_MMD_PCS_MV_100BT1_INT_EN_LINKEVENT);
446	} else {
447		ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
448				    MDIO_MMD_PCS_MV_INT_EN, 0);
449		if (ret < 0)
450			return ret;
451
452		return phy_write_mmd(phydev, MDIO_MMD_PCS,
453				     MDIO_MMD_PCS_MV_100BT1_INT_EN, 0);
454	}
455}
456
457static irqreturn_t mv88q2xxx_handle_interrupt(struct phy_device *phydev)
458{
459	bool trigger_machine = false;
460	int irq;
461
462	/* Before we can acknowledge the 100BT1 general interrupt, that is in
463	 * the 1000BT1 interrupt status register, we have to acknowledge any
464	 * interrupts that are related to it. Therefore we read first the 100BT1
465	 * interrupt status register, followed by reading the 1000BT1 interrupt
466	 * status register.
467	 */
468
469	irq = phy_read_mmd(phydev, MDIO_MMD_PCS,
470			   MDIO_MMD_PCS_MV_COPPER_INT_STAT);
471	if (irq < 0) {
472		phy_error(phydev);
473		return IRQ_NONE;
474	}
475
476	/* Check link status for 100BT1 */
477	if (irq & MDIO_MMD_PCS_MV_COPPER_INT_STAT_LINKEVENT)
478		trigger_machine = true;
479
480	irq = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_GPIO_INT_STAT);
481	if (irq < 0) {
482		phy_error(phydev);
483		return IRQ_NONE;
484	}
485
486	/* Check link status for 1000BT1 */
487	if ((irq & MDIO_MMD_PCS_MV_GPIO_INT_STAT_LINK_UP) ||
488	    (irq & MDIO_MMD_PCS_MV_GPIO_INT_STAT_LINK_DOWN))
489		trigger_machine = true;
490
491	if (!trigger_machine)
492		return IRQ_NONE;
493
494	phy_trigger_machine(phydev);
495
496	return IRQ_HANDLED;
497}
498
499static int mv88q2xxx_suspend(struct phy_device *phydev)
500{
501	int ret;
502
503	/* Disable PHY interrupts */
504	if (phy_interrupt_is_valid(phydev)) {
505		phydev->interrupts = PHY_INTERRUPT_DISABLED;
506		ret = mv88q2xxx_config_intr(phydev);
507		if (ret)
508			return ret;
509	}
510
511	return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1,
512				MDIO_CTRL1_LPOWER);
513}
514
515static int mv88q2xxx_resume(struct phy_device *phydev)
516{
517	int ret;
518
519	/* Enable PHY interrupts */
520	if (phy_interrupt_is_valid(phydev)) {
521		phydev->interrupts = PHY_INTERRUPT_ENABLED;
522		ret = mv88q2xxx_config_intr(phydev);
523		if (ret)
524			return ret;
525	}
526
527	return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1,
528				  MDIO_CTRL1_LPOWER);
529}
530
531#if IS_ENABLED(CONFIG_HWMON)
532static const struct hwmon_channel_info * const mv88q2xxx_hwmon_info[] = {
533	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_ALARM),
534	NULL
535};
536
537static umode_t mv88q2xxx_hwmon_is_visible(const void *data,
538					  enum hwmon_sensor_types type,
539					  u32 attr, int channel)
540{
541	switch (attr) {
542	case hwmon_temp_input:
543		return 0444;
544	case hwmon_temp_max:
545		return 0644;
546	case hwmon_temp_alarm:
547		return 0444;
548	default:
549		return 0;
550	}
551}
552
553static int mv88q2xxx_hwmon_read(struct device *dev,
554				enum hwmon_sensor_types type,
555				u32 attr, int channel, long *val)
556{
557	struct phy_device *phydev = dev_get_drvdata(dev);
558	int ret;
559
560	switch (attr) {
561	case hwmon_temp_input:
562		ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
563				   MDIO_MMD_PCS_MV_TEMP_SENSOR3);
564		if (ret < 0)
565			return ret;
566
567		ret = FIELD_GET(MDIO_MMD_PCS_MV_TEMP_SENSOR3_MASK, ret);
568		*val = (ret - 75) * 1000;
569		return 0;
570	case hwmon_temp_max:
571		ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
572				   MDIO_MMD_PCS_MV_TEMP_SENSOR3);
573		if (ret < 0)
574			return ret;
575
576		ret = FIELD_GET(MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK,
577				ret);
578		*val = (ret - 75) * 1000;
579		return 0;
580	case hwmon_temp_alarm:
581		ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
582				   MDIO_MMD_PCS_MV_TEMP_SENSOR1);
583		if (ret < 0)
584			return ret;
585
586		*val = !!(ret & MDIO_MMD_PCS_MV_TEMP_SENSOR1_RAW_INT);
587		return 0;
588	default:
589		return -EOPNOTSUPP;
590	}
591}
592
593static int mv88q2xxx_hwmon_write(struct device *dev,
594				 enum hwmon_sensor_types type, u32 attr,
595				 int channel, long val)
596{
597	struct phy_device *phydev = dev_get_drvdata(dev);
598
599	switch (attr) {
600	case hwmon_temp_max:
601		clamp_val(val, -75000, 180000);
602		val = (val / 1000) + 75;
603		val = FIELD_PREP(MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK,
604				 val);
605		return phy_modify_mmd(phydev, MDIO_MMD_PCS,
606				      MDIO_MMD_PCS_MV_TEMP_SENSOR3,
607				      MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK,
608				      val);
609	default:
610		return -EOPNOTSUPP;
611	}
612}
613
614static const struct hwmon_ops mv88q2xxx_hwmon_hwmon_ops = {
615	.is_visible = mv88q2xxx_hwmon_is_visible,
616	.read = mv88q2xxx_hwmon_read,
617	.write = mv88q2xxx_hwmon_write,
618};
619
620static const struct hwmon_chip_info mv88q2xxx_hwmon_chip_info = {
621	.ops = &mv88q2xxx_hwmon_hwmon_ops,
622	.info = mv88q2xxx_hwmon_info,
623};
624
625static int mv88q2xxx_hwmon_probe(struct phy_device *phydev)
626{
627	struct device *dev = &phydev->mdio.dev;
628	struct device *hwmon;
629	char *hwmon_name;
630	int ret;
631
632	/* Enable temperature sense */
633	ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TEMP_SENSOR2,
634			     MDIO_MMD_PCS_MV_TEMP_SENSOR2_DIS_MASK, 0);
635	if (ret < 0)
636		return ret;
637
638	hwmon_name = devm_hwmon_sanitize_name(dev, dev_name(dev));
639	if (IS_ERR(hwmon_name))
640		return PTR_ERR(hwmon_name);
641
642	hwmon = devm_hwmon_device_register_with_info(dev,
643						     hwmon_name,
644						     phydev,
645						     &mv88q2xxx_hwmon_chip_info,
646						     NULL);
647
648	return PTR_ERR_OR_ZERO(hwmon);
649}
650
651#else
652static int mv88q2xxx_hwmon_probe(struct phy_device *phydev)
653{
654	return 0;
655}
656#endif
657
658static int mv88q2xxx_probe(struct phy_device *phydev)
659{
660	return mv88q2xxx_hwmon_probe(phydev);
661}
662
663static int mv88q222x_soft_reset(struct phy_device *phydev)
664{
665	int ret;
666
667	/* Enable RESET of DCL */
668	if (phydev->autoneg == AUTONEG_ENABLE || phydev->speed == SPEED_1000) {
669		ret = phy_write_mmd(phydev, MDIO_MMD_PCS, 0xfe1b, 0x48);
670		if (ret < 0)
671			return ret;
672	}
673
674	ret = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_1000BT1_CTRL,
675			    MDIO_PCS_1000BT1_CTRL_RESET);
676	if (ret < 0)
677		return ret;
678
679	ret = phy_write_mmd(phydev, MDIO_MMD_PCS, 0xffe4, 0xc);
680	if (ret < 0)
681		return ret;
682
683	/* Disable RESET of DCL */
684	if (phydev->autoneg == AUTONEG_ENABLE || phydev->speed == SPEED_1000)
685		return phy_write_mmd(phydev, MDIO_MMD_PCS, 0xfe1b, 0x58);
686
687	return 0;
688}
689
690static int mv88q222x_revb0_config_init(struct phy_device *phydev)
691{
692	int ret, i;
693
694	for (i = 0; i < ARRAY_SIZE(mv88q222x_revb0_init_seq0); i++) {
695		ret = phy_write_mmd(phydev, mv88q222x_revb0_init_seq0[i].devad,
696				    mv88q222x_revb0_init_seq0[i].regnum,
697				    mv88q222x_revb0_init_seq0[i].val);
698		if (ret < 0)
699			return ret;
700	}
701
702	usleep_range(5000, 10000);
703
704	for (i = 0; i < ARRAY_SIZE(mv88q222x_revb0_init_seq1); i++) {
705		ret = phy_write_mmd(phydev, mv88q222x_revb0_init_seq1[i].devad,
706				    mv88q222x_revb0_init_seq1[i].regnum,
707				    mv88q222x_revb0_init_seq1[i].val);
708		if (ret < 0)
709			return ret;
710	}
711
712	return mv88q2xxx_config_init(phydev);
713}
714
715static int mv88q222x_cable_test_start(struct phy_device *phydev)
716{
717	int ret;
718
719	ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
720			    MDIO_MMD_PCS_MV_TDR_OFF_CUTOFF, 0x0058);
721	if (ret < 0)
722		return ret;
723
724	ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
725			    MDIO_MMD_PCS_MV_TDR_OFF_LONG_CABLE, 0x00eb);
726	if (ret < 0)
727		return ret;
728
729	ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
730			    MDIO_MMD_PCS_MV_TDR_OFF_SHORT_CABLE, 0x010e);
731	if (ret < 0)
732		return ret;
733
734	ret = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TDR_RESET,
735			    0x0d90);
736	if (ret < 0)
737		return ret;
738
739	ret = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TDR_STATUS,
740			    MDIO_MMD_PCS_MV_TDR_STATUS_ON);
741	if (ret < 0)
742		return ret;
743
744	/* According to the Marvell API the test is finished within 500 ms */
745	msleep(500);
746
747	return 0;
748}
749
750static int mv88q222x_cable_test_get_status(struct phy_device *phydev,
751					   bool *finished)
752{
753	int ret, status;
754	u32 dist;
755
756	status = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TDR_STATUS);
757	if (status < 0)
758		return status;
759
760	ret = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TDR_RESET,
761			    MDIO_MMD_PCS_MV_TDR_RESET_TDR_RST | 0xd90);
762	if (ret < 0)
763		return ret;
764
765	/* Test could not be finished */
766	if (FIELD_GET(MDIO_MMD_PCS_MV_TDR_STATUS_MASK, status) !=
767	    MDIO_MMD_PCS_MV_TDR_STATUS_OFF)
768		return -ETIMEDOUT;
769
770	*finished = true;
771	/* Fault length reported in meters, convert to centimeters */
772	dist = FIELD_GET(MDIO_MMD_PCS_MV_TDR_STATUS_DIST_MASK, status) * 100;
773	switch (status & MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_MASK) {
774	case MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_OPEN:
775		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
776					ETHTOOL_A_CABLE_RESULT_CODE_OPEN);
777		ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A,
778					      dist);
779		break;
780	case MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_SHORT:
781		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
782					ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT);
783		ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A,
784					      dist);
785		break;
786	case MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_OK:
787		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
788					ETHTOOL_A_CABLE_RESULT_CODE_OK);
789		break;
790	default:
791		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
792					ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC);
793	}
794
795	return 0;
796}
797
798static struct phy_driver mv88q2xxx_driver[] = {
799	{
800		.phy_id			= MARVELL_PHY_ID_88Q2110,
801		.phy_id_mask		= MARVELL_PHY_ID_MASK,
802		.name			= "mv88q2110",
803		.get_features		= mv88q2xxx_get_features,
804		.config_aneg		= mv88q2xxx_config_aneg,
805		.config_init		= mv88q2xxx_config_init,
806		.read_status		= mv88q2xxx_read_status,
807		.soft_reset		= mv88q2xxx_soft_reset,
808		.set_loopback		= genphy_c45_loopback,
809		.get_sqi		= mv88q2xxx_get_sqi,
810		.get_sqi_max		= mv88q2xxx_get_sqi_max,
811	},
812	{
813		PHY_ID_MATCH_EXACT(PHY_ID_88Q2220_REVB0),
814		.name			= "mv88q2220",
815		.flags			= PHY_POLL_CABLE_TEST,
816		.probe			= mv88q2xxx_probe,
817		.get_features		= mv88q2xxx_get_features,
818		.config_aneg		= mv88q2xxx_config_aneg,
819		.aneg_done		= genphy_c45_aneg_done,
820		.config_init		= mv88q222x_revb0_config_init,
821		.read_status		= mv88q2xxx_read_status,
822		.soft_reset		= mv88q222x_soft_reset,
823		.config_intr		= mv88q2xxx_config_intr,
824		.handle_interrupt	= mv88q2xxx_handle_interrupt,
825		.set_loopback		= genphy_c45_loopback,
826		.cable_test_start	= mv88q222x_cable_test_start,
827		.cable_test_get_status	= mv88q222x_cable_test_get_status,
828		.get_sqi		= mv88q2xxx_get_sqi,
829		.get_sqi_max		= mv88q2xxx_get_sqi_max,
830		.suspend		= mv88q2xxx_suspend,
831		.resume			= mv88q2xxx_resume,
832	},
833};
834
835module_phy_driver(mv88q2xxx_driver);
836
837static struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = {
838	{ MARVELL_PHY_ID_88Q2110, MARVELL_PHY_ID_MASK },
839	{ PHY_ID_MATCH_EXACT(PHY_ID_88Q2220_REVB0), },
840	{ /*sentinel*/ }
841};
842MODULE_DEVICE_TABLE(mdio, mv88q2xxx_tbl);
843
844MODULE_DESCRIPTION("Marvell 88Q2XXX 100/1000BASE-T1 Automotive Ethernet PHY driver");
845MODULE_LICENSE("GPL");
846