File Index
Files and directories
Sign in
FILE

lantiq_gswip.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/dsa/lantiq/lantiq_gswip.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Lantiq / Intel GSWIP switch driver for VRX200, xRX300 and xRX330 SoCs
  4 *
  5 * Copyright (C) 2025 Daniel Golle <daniel@makrotopia.org>
  6 * Copyright (C) 2017 - 2019 Hauke Mehrtens <hauke@hauke-m.de>
  7 * Copyright (C) 2012 John Crispin <john@phrozen.org>
  8 * Copyright (C) 2010 Lantiq Deutschland
  9 */
 10
 11#include "lantiq_gswip.h"
 12#include "lantiq_pce.h"
 13
 14#include <linux/clk.h>
 15#include <linux/delay.h>
 16#include <linux/firmware.h>
 17#include <linux/mfd/syscon.h>
 18#include <linux/module.h>
 19#include <linux/of_platform.h>
 20#include <linux/platform_device.h>
 21#include <linux/regmap.h>
 22#include <linux/reset.h>
 23#include <dt-bindings/mips/lantiq_rcu_gphy.h>
 24
 25#include <net/dsa.h>
 26
 27struct xway_gphy_match_data {
 28	char *fe_firmware_name;
 29	char *ge_firmware_name;
 30};
 31
 32static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
 33					  struct phylink_config *config)
 34{
 35	switch (port) {
 36	case 0:
 37	case 1:
 38		phy_interface_set_rgmii(config->supported_interfaces);
 39		__set_bit(PHY_INTERFACE_MODE_MII,
 40			  config->supported_interfaces);
 41		__set_bit(PHY_INTERFACE_MODE_REVMII,
 42			  config->supported_interfaces);
 43		__set_bit(PHY_INTERFACE_MODE_RMII,
 44			  config->supported_interfaces);
 45		break;
 46
 47	case 2:
 48	case 3:
 49	case 4:
 50	case 6:
 51		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 52			  config->supported_interfaces);
 53		break;
 54
 55	case 5:
 56		phy_interface_set_rgmii(config->supported_interfaces);
 57		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 58			  config->supported_interfaces);
 59		break;
 60	}
 61
 62	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
 63		MAC_10 | MAC_100 | MAC_1000;
 64}
 65
 66static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
 67					  struct phylink_config *config)
 68{
 69	switch (port) {
 70	case 0:
 71		phy_interface_set_rgmii(config->supported_interfaces);
 72		__set_bit(PHY_INTERFACE_MODE_GMII,
 73			  config->supported_interfaces);
 74		__set_bit(PHY_INTERFACE_MODE_RMII,
 75			  config->supported_interfaces);
 76		break;
 77
 78	case 1:
 79	case 2:
 80	case 3:
 81	case 4:
 82	case 6:
 83		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 84			  config->supported_interfaces);
 85		break;
 86
 87	case 5:
 88		phy_interface_set_rgmii(config->supported_interfaces);
 89		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 90			  config->supported_interfaces);
 91		__set_bit(PHY_INTERFACE_MODE_RMII,
 92			  config->supported_interfaces);
 93		break;
 94	}
 95
 96	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
 97		MAC_10 | MAC_100 | MAC_1000;
 98}
 99
100static const struct xway_gphy_match_data xrx200a1x_gphy_data = {
101	.fe_firmware_name = "lantiq/xrx200_phy22f_a14.bin",
102	.ge_firmware_name = "lantiq/xrx200_phy11g_a14.bin",
103};
104
105static const struct xway_gphy_match_data xrx200a2x_gphy_data = {
106	.fe_firmware_name = "lantiq/xrx200_phy22f_a22.bin",
107	.ge_firmware_name = "lantiq/xrx200_phy11g_a22.bin",
108};
109
110static const struct xway_gphy_match_data xrx300_gphy_data = {
111	.fe_firmware_name = "lantiq/xrx300_phy22f_a21.bin",
112	.ge_firmware_name = "lantiq/xrx300_phy11g_a21.bin",
113};
114
115static const struct of_device_id xway_gphy_match[] __maybe_unused = {
116	{ .compatible = "lantiq,xrx200-gphy-fw", .data = NULL },
117	{ .compatible = "lantiq,xrx200a1x-gphy-fw", .data = &xrx200a1x_gphy_data },
118	{ .compatible = "lantiq,xrx200a2x-gphy-fw", .data = &xrx200a2x_gphy_data },
119	{ .compatible = "lantiq,xrx300-gphy-fw", .data = &xrx300_gphy_data },
120	{ .compatible = "lantiq,xrx330-gphy-fw", .data = &xrx300_gphy_data },
121	{},
122};
123
124static int gswip_gphy_fw_load(struct gswip_priv *priv, struct gswip_gphy_fw *gphy_fw)
125{
126	struct device *dev = priv->dev;
127	const struct firmware *fw;
128	void *fw_addr;
129	dma_addr_t dma_addr;
130	dma_addr_t dev_addr;
131	size_t size;
132	int ret;
133
134	ret = clk_prepare_enable(gphy_fw->clk_gate);
135	if (ret)
136		return ret;
137
138	reset_control_assert(gphy_fw->reset);
139
140	/* The vendor BSP uses a 200ms delay after asserting the reset line.
141	 * Without this some users are observing that the PHY is not coming up
142	 * on the MDIO bus.
143	 */
144	msleep(200);
145
146	ret = request_firmware(&fw, gphy_fw->fw_name, dev);
147	if (ret)
148		return dev_err_probe(dev, ret, "failed to load firmware: %s\n",
149				     gphy_fw->fw_name);
150
151	/* GPHY cores need the firmware code in a persistent and contiguous
152	 * memory area with a 16 kB boundary aligned start address.
153	 */
154	size = fw->size + XRX200_GPHY_FW_ALIGN;
155
156	fw_addr = dmam_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL);
157	if (fw_addr) {
158		fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN);
159		dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
160		memcpy(fw_addr, fw->data, fw->size);
161	} else {
162		release_firmware(fw);
163		return -ENOMEM;
164	}
165
166	release_firmware(fw);
167
168	ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, dev_addr);
169	if (ret)
170		return ret;
171
172	reset_control_deassert(gphy_fw->reset);
173
174	return ret;
175}
176
177static int gswip_gphy_fw_probe(struct gswip_priv *priv,
178			       struct gswip_gphy_fw *gphy_fw,
179			       struct device_node *gphy_fw_np, int i)
180{
181	struct device *dev = priv->dev;
182	u32 gphy_mode;
183	int ret;
184	char gphyname[10];
185
186	snprintf(gphyname, sizeof(gphyname), "gphy%d", i);
187
188	gphy_fw->clk_gate = devm_clk_get(dev, gphyname);
189	if (IS_ERR(gphy_fw->clk_gate)) {
190		return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate),
191				     "Failed to lookup gate clock\n");
192	}
193
194	ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset);
195	if (ret)
196		return ret;
197
198	ret = of_property_read_u32(gphy_fw_np, "lantiq,gphy-mode", &gphy_mode);
199	/* Default to GE mode */
200	if (ret)
201		gphy_mode = GPHY_MODE_GE;
202
203	switch (gphy_mode) {
204	case GPHY_MODE_FE:
205		gphy_fw->fw_name = priv->gphy_fw_name_cfg->fe_firmware_name;
206		break;
207	case GPHY_MODE_GE:
208		gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name;
209		break;
210	default:
211		return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n",
212				     gphy_mode);
213	}
214
215	gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np);
216	if (IS_ERR(gphy_fw->reset))
217		return dev_err_probe(dev, PTR_ERR(gphy_fw->reset),
218				     "Failed to lookup gphy reset\n");
219
220	return gswip_gphy_fw_load(priv, gphy_fw);
221}
222
223static void gswip_gphy_fw_remove(struct gswip_priv *priv,
224				 struct gswip_gphy_fw *gphy_fw)
225{
226	int ret;
227
228	/* check if the device was fully probed */
229	if (!gphy_fw->fw_name)
230		return;
231
232	ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, 0);
233	if (ret)
234		dev_err(priv->dev, "can not reset GPHY FW pointer\n");
235
236	clk_disable_unprepare(gphy_fw->clk_gate);
237
238	reset_control_put(gphy_fw->reset);
239}
240
241static int gswip_gphy_fw_list(struct gswip_priv *priv,
242			      struct device_node *gphy_fw_list_np, u32 version)
243{
244	struct device *dev = priv->dev;
245	struct device_node *gphy_fw_np;
246	const struct of_device_id *match;
247	int err;
248	int i = 0;
249
250	/* The VRX200 rev 1.1 uses the GSWIP 2.0 and needs the older
251	 * GPHY firmware. The VRX200 rev 1.2 uses the GSWIP 2.1 and also
252	 * needs a different GPHY firmware.
253	 */
254	if (of_device_is_compatible(gphy_fw_list_np, "lantiq,xrx200-gphy-fw")) {
255		switch (version) {
256		case GSWIP_VERSION_2_0:
257			priv->gphy_fw_name_cfg = &xrx200a1x_gphy_data;
258			break;
259		case GSWIP_VERSION_2_1:
260			priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
261			break;
262		default:
263			return dev_err_probe(dev, -ENOENT,
264					     "unknown GSWIP version: 0x%x\n",
265					     version);
266		}
267	}
268
269	match = of_match_node(xway_gphy_match, gphy_fw_list_np);
270	if (match && match->data)
271		priv->gphy_fw_name_cfg = match->data;
272
273	if (!priv->gphy_fw_name_cfg)
274		return dev_err_probe(dev, -ENOENT,
275				     "GPHY compatible type not supported\n");
276
277	priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np);
278	if (!priv->num_gphy_fw)
279		return -ENOENT;
280
281	priv->rcu_regmap = syscon_regmap_lookup_by_phandle(gphy_fw_list_np,
282							   "lantiq,rcu");
283	if (IS_ERR(priv->rcu_regmap))
284		return PTR_ERR(priv->rcu_regmap);
285
286	priv->gphy_fw = devm_kmalloc_array(dev, priv->num_gphy_fw,
287					   sizeof(*priv->gphy_fw),
288					   GFP_KERNEL | __GFP_ZERO);
289	if (!priv->gphy_fw)
290		return -ENOMEM;
291
292	for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) {
293		err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i],
294					  gphy_fw_np, i);
295		if (err) {
296			of_node_put(gphy_fw_np);
297			goto remove_gphy;
298		}
299		i++;
300	}
301
302	/* The standalone PHY11G requires 300ms to be fully
303	 * initialized and ready for any MDIO communication after being
304	 * taken out of reset. For the SoC-internal GPHY variant there
305	 * is no (known) documentation for the minimum time after a
306	 * reset. Use the same value as for the standalone variant as
307	 * some users have reported internal PHYs not being detected
308	 * without any delay.
309	 */
310	msleep(300);
311
312	return 0;
313
314remove_gphy:
315	for (i = 0; i < priv->num_gphy_fw; i++)
316		gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]);
317	return err;
318}
319
320static const struct regmap_config sw_regmap_config = {
321	.name = "switch",
322	.reg_bits = 32,
323	.val_bits = 32,
324	.reg_shift = REGMAP_UPSHIFT(2),
325	.val_format_endian = REGMAP_ENDIAN_NATIVE,
326	.max_register = GSWIP_SDMA_PCTRLp(6),
327};
328
329static const struct regmap_config mdio_regmap_config = {
330	.name = "mdio",
331	.reg_bits = 32,
332	.val_bits = 32,
333	.reg_shift = REGMAP_UPSHIFT(2),
334	.val_format_endian = REGMAP_ENDIAN_NATIVE,
335	.max_register = GSWIP_MDIO_PHYp(0),
336};
337
338static const struct regmap_config mii_regmap_config = {
339	.name = "mii",
340	.reg_bits = 32,
341	.val_bits = 32,
342	.reg_shift = REGMAP_UPSHIFT(2),
343	.val_format_endian = REGMAP_ENDIAN_NATIVE,
344	.max_register = GSWIP_MII_CFGp(6),
345};
346
347static int gswip_probe(struct platform_device *pdev)
348{
349	struct device_node *np, *gphy_fw_np;
350	__iomem void *gswip, *mdio, *mii;
351	struct device *dev = &pdev->dev;
352	struct gswip_priv *priv;
353	int err;
354	int i;
355	u32 version;
356
357	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
358	if (!priv)
359		return -ENOMEM;
360
361	gswip = devm_platform_ioremap_resource(pdev, 0);
362	if (IS_ERR(gswip))
363		return PTR_ERR(gswip);
364
365	mdio = devm_platform_ioremap_resource(pdev, 1);
366	if (IS_ERR(mdio))
367		return PTR_ERR(mdio);
368
369	mii = devm_platform_ioremap_resource(pdev, 2);
370	if (IS_ERR(mii))
371		return PTR_ERR(mii);
372
373	priv->gswip = devm_regmap_init_mmio(dev, gswip, &sw_regmap_config);
374	if (IS_ERR(priv->gswip))
375		return PTR_ERR(priv->gswip);
376
377	priv->mdio = devm_regmap_init_mmio(dev, mdio, &mdio_regmap_config);
378	if (IS_ERR(priv->mdio))
379		return PTR_ERR(priv->mdio);
380
381	priv->mii = devm_regmap_init_mmio(dev, mii, &mii_regmap_config);
382	if (IS_ERR(priv->mii))
383		return PTR_ERR(priv->mii);
384
385	priv->hw_info = of_device_get_match_data(dev);
386	if (!priv->hw_info)
387		return -EINVAL;
388
389	priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
390	if (!priv->ds)
391		return -ENOMEM;
392
393	priv->dev = dev;
394
395	regmap_read(priv->gswip, GSWIP_VERSION, &version);
396
397	np = dev->of_node;
398	switch (version) {
399	case GSWIP_VERSION_2_0:
400	case GSWIP_VERSION_2_1:
401		if (!of_device_is_compatible(np, "lantiq,xrx200-gswip"))
402			return -EINVAL;
403		break;
404	case GSWIP_VERSION_2_2:
405	case GSWIP_VERSION_2_2_ETC:
406		if (!of_device_is_compatible(np, "lantiq,xrx300-gswip") &&
407		    !of_device_is_compatible(np, "lantiq,xrx330-gswip"))
408			return -EINVAL;
409		break;
410	default:
411		return dev_err_probe(dev, -ENOENT,
412				     "unknown GSWIP version: 0x%x\n", version);
413	}
414
415	/* bring up the mdio bus */
416	gphy_fw_np = of_get_compatible_child(dev->of_node, "lantiq,gphy-fw");
417	if (gphy_fw_np) {
418		err = gswip_gphy_fw_list(priv, gphy_fw_np, version);
419		of_node_put(gphy_fw_np);
420		if (err)
421			return dev_err_probe(dev, err,
422					     "gphy fw probe failed\n");
423	}
424
425	err = gswip_probe_common(priv, version);
426	if (err)
427		goto gphy_fw_remove;
428
429	platform_set_drvdata(pdev, priv);
430
431	return 0;
432
433gphy_fw_remove:
434	for (i = 0; i < priv->num_gphy_fw; i++)
435		gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]);
436	return err;
437}
438
439static void gswip_remove(struct platform_device *pdev)
440{
441	struct gswip_priv *priv = platform_get_drvdata(pdev);
442	int i;
443
444	if (!priv)
445		return;
446
447	dsa_unregister_switch(priv->ds);
448
449	for (i = 0; i < priv->num_gphy_fw; i++)
450		gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]);
451}
452
453static void gswip_shutdown(struct platform_device *pdev)
454{
455	struct gswip_priv *priv = platform_get_drvdata(pdev);
456
457	if (!priv)
458		return;
459
460	dsa_switch_shutdown(priv->ds);
461
462	platform_set_drvdata(pdev, NULL);
463}
464
465static const struct gswip_hw_info gswip_xrx200 = {
466	.max_ports = 7,
467	.allowed_cpu_ports = BIT(6),
468	.mii_ports = BIT(0) | BIT(1) | BIT(5),
469	.mii_port_reg_offset = 0,
470	.phylink_get_caps = gswip_xrx200_phylink_get_caps,
471	.pce_microcode = &gswip_pce_microcode,
472	.pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
473	.tag_protocol = DSA_TAG_PROTO_GSWIP,
474};
475
476static const struct gswip_hw_info gswip_xrx300 = {
477	.max_ports = 7,
478	.allowed_cpu_ports = BIT(6),
479	.mii_ports = BIT(0) | BIT(5),
480	.mii_port_reg_offset = 0,
481	.phylink_get_caps = gswip_xrx300_phylink_get_caps,
482	.pce_microcode = &gswip_pce_microcode,
483	.pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
484	.tag_protocol = DSA_TAG_PROTO_GSWIP,
485};
486
487static const struct of_device_id gswip_of_match[] = {
488	{ .compatible = "lantiq,xrx200-gswip", .data = &gswip_xrx200 },
489	{ .compatible = "lantiq,xrx300-gswip", .data = &gswip_xrx300 },
490	{ .compatible = "lantiq,xrx330-gswip", .data = &gswip_xrx300 },
491	{},
492};
493MODULE_DEVICE_TABLE(of, gswip_of_match);
494
495static struct platform_driver gswip_driver = {
496	.probe = gswip_probe,
497	.remove = gswip_remove,
498	.shutdown = gswip_shutdown,
499	.driver = {
500		.name = "gswip",
501		.of_match_table = gswip_of_match,
502	},
503};
504
505module_platform_driver(gswip_driver);
506
507MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin");
508MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin");
509MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin");
510MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin");
511MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin");
512MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin");
513MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
514MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver");
515MODULE_LICENSE("GPL v2");
~/ Read-only file preview.