File Index
Files and directories
Sign in
FILE

mxl-gsw1xx.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/dsa/lantiq/mxl-gsw1xx.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/* DSA Driver for MaxLinear GSW1xx switch devices
  3 *
  4 * Copyright (C) 2025 Daniel Golle <daniel@makrotopia.org>
  5 * Copyright (C) 2023 - 2024 MaxLinear Inc.
  6 * Copyright (C) 2022 Snap One, LLC.  All rights reserved.
  7 * Copyright (C) 2017 - 2019 Hauke Mehrtens <hauke@hauke-m.de>
  8 * Copyright (C) 2012 John Crispin <john@phrozen.org>
  9 * Copyright (C) 2010 Lantiq Deutschland
 10 */
 11
 12#include <linux/bits.h>
 13#include <linux/delay.h>
 14#include <linux/jiffies.h>
 15#include <linux/module.h>
 16#include <linux/of_device.h>
 17#include <linux/of_mdio.h>
 18#include <linux/regmap.h>
 19#include <linux/workqueue.h>
 20#include <net/dsa.h>
 21
 22#include "lantiq_gswip.h"
 23#include "mxl-gsw1xx.h"
 24#include "mxl-gsw1xx_pce.h"
 25
 26struct gsw1xx_priv {
 27	struct mdio_device	*mdio_dev;
 28	int			smdio_badr;
 29	struct			regmap *sgmii;
 30	struct			regmap *gpio;
 31	struct			regmap *clk;
 32	struct			regmap *shell;
 33	struct			phylink_pcs pcs;
 34	struct delayed_work	clear_raneg;
 35	phy_interface_t		tbi_interface;
 36	struct gswip_priv	gswip;
 37};
 38
 39static int gsw1xx_config_smdio_badr(struct gsw1xx_priv *priv,
 40				    unsigned int reg)
 41{
 42	struct mii_bus *bus = priv->mdio_dev->bus;
 43	int sw_addr = priv->mdio_dev->addr;
 44	int smdio_badr = priv->smdio_badr;
 45	int res;
 46
 47	if (smdio_badr == GSW1XX_SMDIO_BADR_UNKNOWN ||
 48	    reg - smdio_badr >= GSW1XX_SMDIO_BADR ||
 49	    smdio_badr > reg) {
 50		/* Configure the Switch Base Address */
 51		smdio_badr = reg & ~GENMASK(3, 0);
 52		res = __mdiobus_write(bus, sw_addr, GSW1XX_SMDIO_BADR, smdio_badr);
 53		if (res < 0) {
 54			dev_err(&priv->mdio_dev->dev,
 55				"%s: Error %d, configuring switch base\n",
 56				__func__, res);
 57			return res;
 58		}
 59		priv->smdio_badr = smdio_badr;
 60	}
 61
 62	return smdio_badr;
 63}
 64
 65static int gsw1xx_regmap_read(void *context, unsigned int reg,
 66			      unsigned int *val)
 67{
 68	struct gsw1xx_priv *priv = context;
 69	struct mii_bus *bus = priv->mdio_dev->bus;
 70	int sw_addr = priv->mdio_dev->addr;
 71	int smdio_badr;
 72	int res;
 73
 74	smdio_badr = gsw1xx_config_smdio_badr(priv, reg);
 75	if (smdio_badr < 0)
 76		return smdio_badr;
 77
 78	res = __mdiobus_read(bus, sw_addr, reg - smdio_badr);
 79	if (res < 0) {
 80		dev_err(&priv->mdio_dev->dev, "%s: Error %d reading 0x%x\n",
 81			__func__, res, reg);
 82		return res;
 83	}
 84
 85	*val = res;
 86
 87	return 0;
 88}
 89
 90static int gsw1xx_regmap_write(void *context, unsigned int reg,
 91			       unsigned int val)
 92{
 93	struct gsw1xx_priv *priv = context;
 94	struct mii_bus *bus = priv->mdio_dev->bus;
 95	int sw_addr = priv->mdio_dev->addr;
 96	int smdio_badr;
 97	int res;
 98
 99	smdio_badr = gsw1xx_config_smdio_badr(priv, reg);
100	if (smdio_badr < 0)
101		return smdio_badr;
102
103	res = __mdiobus_write(bus, sw_addr, reg - smdio_badr, val);
104	if (res < 0)
105		dev_err(&priv->mdio_dev->dev,
106			"%s: Error %d, writing 0x%x:0x%x\n", __func__, res, reg,
107			val);
108
109	return res;
110}
111
112static const struct regmap_bus gsw1xx_regmap_bus = {
113	.reg_write = gsw1xx_regmap_write,
114	.reg_read = gsw1xx_regmap_read,
115};
116
117static void gsw1xx_mdio_regmap_lock(void *mdio_lock)
118{
119	mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
120}
121
122static void gsw1xx_mdio_regmap_unlock(void *mdio_lock)
123{
124	mutex_unlock(mdio_lock);
125}
126
127static unsigned int gsw1xx_pcs_inband_caps(struct phylink_pcs *pcs,
128					   phy_interface_t interface)
129{
130	return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
131}
132
133static struct gsw1xx_priv *pcs_to_gsw1xx(struct phylink_pcs *pcs)
134{
135	return container_of(pcs, struct gsw1xx_priv, pcs);
136}
137
138static int gsw1xx_pcs_enable(struct phylink_pcs *pcs)
139{
140	struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
141
142	/* Deassert SGMII shell reset */
143	return regmap_clear_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
144				 GSW1XX_RST_REQ_SGMII_SHELL);
145}
146
147static void gsw1xx_pcs_disable(struct phylink_pcs *pcs)
148{
149	struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
150
151	cancel_delayed_work_sync(&priv->clear_raneg);
152
153	/* Assert SGMII shell reset (will also clear RANEG bit) */
154	regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
155			GSW1XX_RST_REQ_SGMII_SHELL);
156
157	priv->tbi_interface = PHY_INTERFACE_MODE_NA;
158}
159
160static void gsw1xx_pcs_get_state(struct phylink_pcs *pcs,
161				 unsigned int neg_mode,
162				 struct phylink_link_state *state)
163{
164	struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
165	int ret;
166	u32 val;
167
168	ret = regmap_read(priv->sgmii, GSW1XX_SGMII_TBI_TBISTAT, &val);
169	if (ret < 0)
170		return;
171
172	state->link = !!(val & GSW1XX_SGMII_TBI_TBISTAT_LINK);
173	state->an_complete = !!(val & GSW1XX_SGMII_TBI_TBISTAT_AN_COMPLETE);
174
175	ret = regmap_read(priv->sgmii, GSW1XX_SGMII_TBI_LPSTAT, &val);
176	if (ret < 0)
177		return;
178
179	state->duplex = (val & GSW1XX_SGMII_TBI_LPSTAT_DUPLEX) ?
180			 DUPLEX_FULL : DUPLEX_HALF;
181	if (val & GSW1XX_SGMII_TBI_LPSTAT_PAUSE_RX)
182		state->pause |= MLO_PAUSE_RX;
183
184	if (val & GSW1XX_SGMII_TBI_LPSTAT_PAUSE_TX)
185		state->pause |= MLO_PAUSE_TX;
186
187	switch (FIELD_GET(GSW1XX_SGMII_TBI_LPSTAT_SPEED, val)) {
188	case GSW1XX_SGMII_TBI_LPSTAT_SPEED_10:
189		state->speed = SPEED_10;
190		break;
191	case GSW1XX_SGMII_TBI_LPSTAT_SPEED_100:
192		state->speed = SPEED_100;
193		break;
194	case GSW1XX_SGMII_TBI_LPSTAT_SPEED_1000:
195		state->speed = SPEED_1000;
196		break;
197	case GSW1XX_SGMII_TBI_LPSTAT_SPEED_NOSGMII:
198		if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
199			state->speed = SPEED_1000;
200		else if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
201			state->speed = SPEED_2500;
202		else
203			state->speed = SPEED_UNKNOWN;
204		break;
205	}
206}
207
208static int gsw1xx_pcs_phy_xaui_write(struct gsw1xx_priv *priv, u16 addr,
209				     u16 data)
210{
211	int ret, val;
212
213	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_D, data);
214	if (ret < 0)
215		return ret;
216
217	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_A, addr);
218	if (ret < 0)
219		return ret;
220
221	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_C,
222			   GSW1XX_SGMII_PHY_WRITE |
223			   GSW1XX_SGMII_PHY_RESET_N);
224	if (ret < 0)
225		return ret;
226
227	return regmap_read_poll_timeout(priv->sgmii, GSW1XX_SGMII_PHY_C,
228					val, val & GSW1XX_SGMII_PHY_STATUS,
229					1000, 100000);
230}
231
232static int gsw1xx_pcs_reset(struct gsw1xx_priv *priv)
233{
234	int ret;
235	u16 val;
236
237	/* Assert and deassert SGMII shell reset */
238	ret = regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
239			      GSW1XX_RST_REQ_SGMII_SHELL);
240	if (ret < 0)
241		return ret;
242
243	ret = regmap_clear_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
244				GSW1XX_RST_REQ_SGMII_SHELL);
245	if (ret < 0)
246		return ret;
247
248	/* Hardware Bringup FSM Enable  */
249	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_HWBU_CTRL,
250			   GSW1XX_SGMII_PHY_HWBU_CTRL_EN_HWBU_FSM |
251			   GSW1XX_SGMII_PHY_HWBU_CTRL_HW_FSM_EN);
252	if (ret < 0)
253		return ret;
254
255	/* Configure SGMII PHY Receiver */
256	val = FIELD_PREP(GSW1XX_SGMII_PHY_RX0_CFG2_EQ,
257			 GSW1XX_SGMII_PHY_RX0_CFG2_EQ_DEF) |
258	      GSW1XX_SGMII_PHY_RX0_CFG2_LOS_EN |
259	      GSW1XX_SGMII_PHY_RX0_CFG2_TERM_EN |
260	      FIELD_PREP(GSW1XX_SGMII_PHY_RX0_CFG2_FILT_CNT,
261			 GSW1XX_SGMII_PHY_RX0_CFG2_FILT_CNT_DEF);
262
263	/* RX lane seems to be inverted internally, so bit
264	 * GSW1XX_SGMII_PHY_RX0_CFG2_INVERT needs to be set for normal
265	 * (ie. non-inverted) operation.
266	 *
267	 * TODO: Take care of inverted RX pair once generic property is
268	 *       available
269	 */
270
271	val |= GSW1XX_SGMII_PHY_RX0_CFG2_INVERT;
272
273	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_RX0_CFG2, val);
274	if (ret < 0)
275		return ret;
276
277	val = FIELD_PREP(GSW1XX_SGMII_PHY_TX0_CFG3_VBOOST_LEVEL,
278			 GSW1XX_SGMII_PHY_TX0_CFG3_VBOOST_LEVEL_DEF);
279
280	/* TODO: Take care of inverted TX pair once generic property is
281	 *       available
282	 */
283
284	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_TX0_CFG3, val);
285	if (ret < 0)
286		return ret;
287
288	/* Reset and Release TBI */
289	val = GSW1XX_SGMII_TBI_TBICTL_INITTBI | GSW1XX_SGMII_TBI_TBICTL_ENTBI |
290	      GSW1XX_SGMII_TBI_TBICTL_CRSTRR | GSW1XX_SGMII_TBI_TBICTL_CRSOFF;
291	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_TBICTL, val);
292	if (ret < 0)
293		return ret;
294	val &= ~GSW1XX_SGMII_TBI_TBICTL_INITTBI;
295	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_TBICTL, val);
296	if (ret < 0)
297		return ret;
298
299	/* Release Tx Data Buffers */
300	ret = regmap_set_bits(priv->sgmii, GSW1XX_SGMII_PCS_TXB_CTL,
301			      GSW1XX_SGMII_PCS_TXB_CTL_INIT_TX_TXB);
302	if (ret < 0)
303		return ret;
304	ret = regmap_clear_bits(priv->sgmii, GSW1XX_SGMII_PCS_TXB_CTL,
305				GSW1XX_SGMII_PCS_TXB_CTL_INIT_TX_TXB);
306	if (ret < 0)
307		return ret;
308
309	/* Release Rx Data Buffers */
310	ret = regmap_set_bits(priv->sgmii, GSW1XX_SGMII_PCS_RXB_CTL,
311			      GSW1XX_SGMII_PCS_RXB_CTL_INIT_RX_RXB);
312	if (ret < 0)
313		return ret;
314	return regmap_clear_bits(priv->sgmii, GSW1XX_SGMII_PCS_RXB_CTL,
315				 GSW1XX_SGMII_PCS_RXB_CTL_INIT_RX_RXB);
316}
317
318static int gsw1xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
319			     phy_interface_t interface,
320			     const unsigned long *advertising,
321			     bool permit_pause_to_mac)
322{
323	struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
324	u16 txaneg, anegctl, nco_ctrl;
325	bool reconf = false;
326	int ret = 0;
327
328	/* do not unnecessarily disrupt link and skip resetting the hardware in
329	 * case the PCS has previously been successfully configured for this
330	 * interface mode
331	 */
332	if (priv->tbi_interface == interface)
333		reconf = true;
334
335	/* mark PCS configuration as incomplete */
336	priv->tbi_interface = PHY_INTERFACE_MODE_NA;
337
338	if (!reconf)
339		ret = gsw1xx_pcs_reset(priv);
340
341	if (ret)
342		return ret;
343
344	/* override bootstrap pin settings
345	 * OVRANEG sets ANEG Mode, Enable ANEG and restart ANEG to be
346	 * taken from bits ANMODE, ANEGEN, RANEG of the ANEGCTL register.
347	 * OVERABL sets ability bits in tx_config_reg to be taken from
348	 * the TXANEGH and TXANEGL registers.
349	 */
350	anegctl = GSW1XX_SGMII_TBI_ANEGCTL_OVRANEG |
351		  GSW1XX_SGMII_TBI_ANEGCTL_OVRABL;
352
353	switch (phylink_get_link_timer_ns(interface)) {
354	case 10000:
355		anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_LT,
356				      GSW1XX_SGMII_TBI_ANEGCTL_LT_10US);
357		break;
358	case 1600000:
359		anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_LT,
360				      GSW1XX_SGMII_TBI_ANEGCTL_LT_1_6MS);
361		break;
362	case 5000000:
363		anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_LT,
364				      GSW1XX_SGMII_TBI_ANEGCTL_LT_5MS);
365		break;
366	case 10000000:
367		anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_LT,
368				      GSW1XX_SGMII_TBI_ANEGCTL_LT_10MS);
369		break;
370	default:
371		return -EINVAL;
372	}
373
374	if (neg_mode & PHYLINK_PCS_NEG_INBAND)
375		anegctl |= GSW1XX_SGMII_TBI_ANEGCTL_ANEGEN;
376
377	txaneg = phylink_mii_c22_pcs_encode_advertisement(interface, advertising);
378
379	if (interface == PHY_INTERFACE_MODE_SGMII) {
380		/* lacking a defined reverse-SGMII interface mode this
381		 * driver only supports SGMII (MAC side) for now
382		 */
383		anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_ANMODE,
384				      GSW1XX_SGMII_TBI_ANEGCTL_ANMODE_SGMII_MAC);
385		txaneg |= ADVERTISE_LPACK;
386	} else if (interface == PHY_INTERFACE_MODE_1000BASEX ||
387		   interface == PHY_INTERFACE_MODE_2500BASEX) {
388		anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_ANMODE,
389				      GSW1XX_SGMII_TBI_ANEGCTL_ANMODE_1000BASEX);
390	} else {
391		dev_err(priv->gswip.dev, "%s: wrong interface mode %s\n",
392			__func__, phy_modes(interface));
393		return -EINVAL;
394	}
395
396	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_TXANEGH,
397			   FIELD_GET(GENMASK(15, 8), txaneg));
398	if (ret < 0)
399		return ret;
400	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_TXANEGL,
401			   FIELD_GET(GENMASK(7, 0), txaneg));
402	if (ret < 0)
403		return ret;
404	ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL, anegctl);
405	if (ret < 0)
406		return ret;
407
408	if (!reconf) {
409		/* setup SerDes clock speed */
410		if (interface == PHY_INTERFACE_MODE_2500BASEX)
411			nco_ctrl = GSW1XX_SGMII_2G5 | GSW1XX_SGMII_2G5_NCO2;
412		else
413			nco_ctrl = GSW1XX_SGMII_1G | GSW1XX_SGMII_1G_NCO1;
414
415		ret = regmap_update_bits(priv->clk, GSW1XX_CLK_NCO_CTRL,
416					 GSW1XX_SGMII_HSP_MASK |
417					 GSW1XX_SGMII_SEL,
418					 nco_ctrl);
419		if (ret)
420			return ret;
421
422		ret = gsw1xx_pcs_phy_xaui_write(priv, 0x30, 0x80);
423		if (ret)
424			return ret;
425	}
426
427	/* PCS configuration has now been completed, store mode to prevent
428	 * disrupting the link in case of future calls of this function for the
429	 * same interface mode.
430	 */
431	priv->tbi_interface = interface;
432
433	return 0;
434}
435
436static void gsw1xx_pcs_clear_raneg(struct work_struct *work)
437{
438	struct gsw1xx_priv *priv =
439		container_of(work, struct gsw1xx_priv, clear_raneg.work);
440
441	regmap_clear_bits(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL,
442			  GSW1XX_SGMII_TBI_ANEGCTL_RANEG);
443}
444
445static void gsw1xx_pcs_an_restart(struct phylink_pcs *pcs)
446{
447	struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
448
449	cancel_delayed_work_sync(&priv->clear_raneg);
450
451	regmap_set_bits(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL,
452			GSW1XX_SGMII_TBI_ANEGCTL_RANEG);
453
454	/* despite being documented as self-clearing, the RANEG bit
455	 * sometimes remains set, preventing auto-negotiation from happening.
456	 * MaxLinear advises to manually clear the bit after 10ms.
457	 */
458	schedule_delayed_work(&priv->clear_raneg, msecs_to_jiffies(10));
459}
460
461static void gsw1xx_pcs_link_up(struct phylink_pcs *pcs,
462			       unsigned int neg_mode,
463			       phy_interface_t interface, int speed,
464			       int duplex)
465{
466	struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
467	u16 lpstat;
468
469	/* When in-band AN is enabled hardware will set lpstat */
470	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
471		return;
472
473	/* Force speed and duplex settings */
474	if (interface == PHY_INTERFACE_MODE_SGMII) {
475		if (speed == SPEED_10)
476			lpstat = FIELD_PREP(GSW1XX_SGMII_TBI_LPSTAT_SPEED,
477					    GSW1XX_SGMII_TBI_LPSTAT_SPEED_10);
478		else if (speed == SPEED_100)
479			lpstat = FIELD_PREP(GSW1XX_SGMII_TBI_LPSTAT_SPEED,
480					    GSW1XX_SGMII_TBI_LPSTAT_SPEED_100);
481		else
482			lpstat = FIELD_PREP(GSW1XX_SGMII_TBI_LPSTAT_SPEED,
483					    GSW1XX_SGMII_TBI_LPSTAT_SPEED_1000);
484	} else {
485		lpstat = FIELD_PREP(GSW1XX_SGMII_TBI_LPSTAT_SPEED,
486				    GSW1XX_SGMII_TBI_LPSTAT_SPEED_NOSGMII);
487	}
488
489	if (duplex == DUPLEX_FULL)
490		lpstat |= GSW1XX_SGMII_TBI_LPSTAT_DUPLEX;
491
492	regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_LPSTAT, lpstat);
493}
494
495static const struct phylink_pcs_ops gsw1xx_pcs_ops = {
496	.pcs_inband_caps = gsw1xx_pcs_inband_caps,
497	.pcs_enable = gsw1xx_pcs_enable,
498	.pcs_disable = gsw1xx_pcs_disable,
499	.pcs_get_state = gsw1xx_pcs_get_state,
500	.pcs_config = gsw1xx_pcs_config,
501	.pcs_an_restart = gsw1xx_pcs_an_restart,
502	.pcs_link_up = gsw1xx_pcs_link_up,
503};
504
505static void gsw1xx_phylink_get_caps(struct dsa_switch *ds, int port,
506				    struct phylink_config *config)
507{
508	struct gswip_priv *priv = ds->priv;
509
510	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
511				   MAC_10 | MAC_100 | MAC_1000;
512
513	switch (port) {
514	case 0:
515	case 1:
516	case 2:
517	case 3:
518		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
519			  config->supported_interfaces);
520		break;
521	case 4: /* port 4: SGMII */
522		__set_bit(PHY_INTERFACE_MODE_SGMII,
523			  config->supported_interfaces);
524		__set_bit(PHY_INTERFACE_MODE_1000BASEX,
525			  config->supported_interfaces);
526		if (priv->hw_info->supports_2500m) {
527			__set_bit(PHY_INTERFACE_MODE_2500BASEX,
528				  config->supported_interfaces);
529			config->mac_capabilities |= MAC_2500FD;
530		}
531		return; /* no support for EEE on SGMII port */
532	case 5: /* port 5: RGMII or RMII */
533		__set_bit(PHY_INTERFACE_MODE_RMII,
534			  config->supported_interfaces);
535		phy_interface_set_rgmii(config->supported_interfaces);
536		break;
537	}
538
539	config->lpi_capabilities = MAC_100FD | MAC_1000FD;
540	config->lpi_timer_default = 20;
541	memcpy(config->lpi_interfaces, config->supported_interfaces,
542	       sizeof(config->lpi_interfaces));
543}
544
545static struct phylink_pcs *gsw1xx_phylink_mac_select_pcs(struct phylink_config *config,
546							 phy_interface_t interface)
547{
548	struct dsa_port *dp = dsa_phylink_to_port(config);
549	struct gswip_priv *gswip_priv = dp->ds->priv;
550	struct gsw1xx_priv *gsw1xx_priv = container_of(gswip_priv,
551						       struct gsw1xx_priv,
552						       gswip);
553
554	switch (dp->index) {
555	case GSW1XX_SGMII_PORT:
556		return &gsw1xx_priv->pcs;
557	default:
558		return NULL;
559	}
560}
561
562static struct regmap *gsw1xx_regmap_init(struct gsw1xx_priv *priv,
563					 const char *name,
564					 unsigned int reg_base,
565					 unsigned int max_register)
566{
567	const struct regmap_config config = {
568		.name = name,
569		.reg_bits = 16,
570		.val_bits = 16,
571		.reg_base = reg_base,
572		.max_register = max_register,
573		.lock = gsw1xx_mdio_regmap_lock,
574		.unlock = gsw1xx_mdio_regmap_unlock,
575		.lock_arg = &priv->mdio_dev->bus->mdio_lock,
576	};
577
578	return devm_regmap_init(&priv->mdio_dev->dev, &gsw1xx_regmap_bus,
579				priv, &config);
580}
581
582static int gsw1xx_probe(struct mdio_device *mdiodev)
583{
584	struct device *dev = &mdiodev->dev;
585	struct gsw1xx_priv *priv;
586	u32 version;
587	int ret;
588
589	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
590	if (!priv)
591		return -ENOMEM;
592
593	priv->mdio_dev = mdiodev;
594	priv->smdio_badr = GSW1XX_SMDIO_BADR_UNKNOWN;
595
596	priv->gswip.dev = dev;
597	priv->gswip.hw_info = of_device_get_match_data(dev);
598	if (!priv->gswip.hw_info)
599		return -EINVAL;
600
601	priv->gswip.gswip = gsw1xx_regmap_init(priv, "switch",
602					       GSW1XX_SWITCH_BASE, 0xfff);
603	if (IS_ERR(priv->gswip.gswip))
604		return PTR_ERR(priv->gswip.gswip);
605
606	priv->gswip.mdio = gsw1xx_regmap_init(priv, "mdio", GSW1XX_MMDIO_BASE,
607					      0xff);
608	if (IS_ERR(priv->gswip.mdio))
609		return PTR_ERR(priv->gswip.mdio);
610
611	priv->gswip.mii = gsw1xx_regmap_init(priv, "mii", GSW1XX_RGMII_BASE,
612					     0xff);
613	if (IS_ERR(priv->gswip.mii))
614		return PTR_ERR(priv->gswip.mii);
615
616	priv->sgmii = gsw1xx_regmap_init(priv, "sgmii", GSW1XX_SGMII_BASE,
617					 0xfff);
618	if (IS_ERR(priv->sgmii))
619		return PTR_ERR(priv->sgmii);
620
621	priv->gpio = gsw1xx_regmap_init(priv, "gpio", GSW1XX_GPIO_BASE, 0xff);
622	if (IS_ERR(priv->gpio))
623		return PTR_ERR(priv->gpio);
624
625	priv->clk = gsw1xx_regmap_init(priv, "clk", GSW1XX_CLK_BASE, 0xff);
626	if (IS_ERR(priv->clk))
627		return PTR_ERR(priv->clk);
628
629	priv->shell = gsw1xx_regmap_init(priv, "shell", GSW1XX_SHELL_BASE,
630					 0xff);
631	if (IS_ERR(priv->shell))
632		return PTR_ERR(priv->shell);
633
634	priv->pcs.ops = &gsw1xx_pcs_ops;
635	priv->pcs.poll = true;
636	__set_bit(PHY_INTERFACE_MODE_SGMII,
637		  priv->pcs.supported_interfaces);
638	__set_bit(PHY_INTERFACE_MODE_1000BASEX,
639		  priv->pcs.supported_interfaces);
640	if (priv->gswip.hw_info->supports_2500m)
641		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
642			  priv->pcs.supported_interfaces);
643	priv->tbi_interface = PHY_INTERFACE_MODE_NA;
644
645	/* assert SGMII reset to power down SGMII unit */
646	ret = regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
647			      GSW1XX_RST_REQ_SGMII_SHELL);
648	if (ret < 0)
649		return ret;
650
651	/* configure GPIO pin-mux for MMDIO in case of external PHY connected to
652	 * SGMII or RGMII as slave interface
653	 */
654	regmap_set_bits(priv->gpio, GPIO_ALTSEL0, 3);
655	regmap_set_bits(priv->gpio, GPIO_ALTSEL1, 3);
656
657	ret = regmap_read(priv->gswip.gswip, GSWIP_VERSION, &version);
658	if (ret)
659		return ret;
660
661	INIT_DELAYED_WORK(&priv->clear_raneg, gsw1xx_pcs_clear_raneg);
662
663	ret = gswip_probe_common(&priv->gswip, version);
664	if (ret)
665		return ret;
666
667	dev_set_drvdata(dev, &priv->gswip);
668
669	return 0;
670}
671
672static void gsw1xx_remove(struct mdio_device *mdiodev)
673{
674	struct gswip_priv *priv = dev_get_drvdata(&mdiodev->dev);
675	struct gsw1xx_priv *gsw1xx_priv;
676
677	if (!priv)
678		return;
679
680	dsa_unregister_switch(priv->ds);
681
682	gsw1xx_priv = container_of(priv, struct gsw1xx_priv, gswip);
683	cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg);
684}
685
686static void gsw1xx_shutdown(struct mdio_device *mdiodev)
687{
688	struct gswip_priv *priv = dev_get_drvdata(&mdiodev->dev);
689	struct gsw1xx_priv *gsw1xx_priv;
690
691	if (!priv)
692		return;
693
694	dsa_switch_shutdown(priv->ds);
695
696	dev_set_drvdata(&mdiodev->dev, NULL);
697
698	gsw1xx_priv = container_of(priv, struct gsw1xx_priv, gswip);
699	cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg);
700}
701
702static const struct gswip_hw_info gsw12x_data = {
703	.max_ports		= GSW1XX_PORTS,
704	.allowed_cpu_ports	= BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
705	.mii_ports		= BIT(GSW1XX_MII_PORT),
706	.mii_port_reg_offset	= -GSW1XX_MII_PORT,
707	.mac_select_pcs		= gsw1xx_phylink_mac_select_pcs,
708	.phylink_get_caps	= &gsw1xx_phylink_get_caps,
709	.supports_2500m		= true,
710	.pce_microcode		= &gsw1xx_pce_microcode,
711	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
712	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
713};
714
715static const struct gswip_hw_info gsw140_data = {
716	.max_ports		= GSW1XX_PORTS,
717	.allowed_cpu_ports	= BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
718	.mii_ports		= BIT(GSW1XX_MII_PORT),
719	.mii_port_reg_offset	= -GSW1XX_MII_PORT,
720	.mac_select_pcs		= gsw1xx_phylink_mac_select_pcs,
721	.phylink_get_caps	= &gsw1xx_phylink_get_caps,
722	.supports_2500m		= true,
723	.pce_microcode		= &gsw1xx_pce_microcode,
724	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
725	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
726};
727
728static const struct gswip_hw_info gsw141_data = {
729	.max_ports		= GSW1XX_PORTS,
730	.allowed_cpu_ports	= BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
731	.mii_ports		= BIT(GSW1XX_MII_PORT),
732	.mii_port_reg_offset	= -GSW1XX_MII_PORT,
733	.mac_select_pcs		= gsw1xx_phylink_mac_select_pcs,
734	.phylink_get_caps	= gsw1xx_phylink_get_caps,
735	.pce_microcode		= &gsw1xx_pce_microcode,
736	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
737	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
738};
739
740/*
741 * GSW125 is the industrial temperature version of GSW120.
742 * GSW145 is the industrial temperature version of GSW140.
743 */
744static const struct of_device_id gsw1xx_of_match[] = {
745	{ .compatible = "maxlinear,gsw120", .data = &gsw12x_data },
746	{ .compatible = "maxlinear,gsw125", .data = &gsw12x_data },
747	{ .compatible = "maxlinear,gsw140", .data = &gsw140_data },
748	{ .compatible = "maxlinear,gsw141", .data = &gsw141_data },
749	{ .compatible = "maxlinear,gsw145", .data = &gsw140_data },
750	{ /* sentinel */ },
751};
752
753MODULE_DEVICE_TABLE(of, gsw1xx_of_match);
754
755static struct mdio_driver gsw1xx_driver = {
756	.probe		= gsw1xx_probe,
757	.remove		= gsw1xx_remove,
758	.shutdown	= gsw1xx_shutdown,
759	.mdiodrv.driver	= {
760		.name = "mxl-gsw1xx",
761		.of_match_table = gsw1xx_of_match,
762	},
763};
764
765mdio_module_driver(gsw1xx_driver);
766
767MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
768MODULE_DESCRIPTION("Driver for MaxLinear GSW1xx ethernet switch");
769MODULE_LICENSE("GPL");
~/ Read-only file preview.