1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Freescale PowerQUICC Ethernet Driver -- MIIM bus implementation
4 * Provides Bus interface for MIIM regs
5 *
6 * Author: Andy Fleming <afleming@freescale.com>
7 * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
8 *
9 * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc.
10 *
11 * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips)
12 */
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/string.h>
17#include <linux/errno.h>
18#include <linux/slab.h>
19#include <linux/delay.h>
20#include <linux/module.h>
21#include <linux/mii.h>
22#include <linux/of_address.h>
23#include <linux/of_mdio.h>
24#include <linux/of_device.h>
25
26#include <asm/io.h>
27#if IS_ENABLED(CONFIG_UCC_GETH)
28#include <soc/fsl/qe/ucc.h>
29#endif
30
31#include "gianfar.h"
32
33#define MIIMIND_BUSY		0x00000001
34#define MIIMIND_NOTVALID	0x00000004
35#define MIIMCFG_INIT_VALUE	0x00000007
36#define MIIMCFG_RESET		0x80000000
37
38#define MII_READ_COMMAND	0x00000001
39
40struct fsl_pq_mii {
41	u32 miimcfg;	/* MII management configuration reg */
42	u32 miimcom;	/* MII management command reg */
43	u32 miimadd;	/* MII management address reg */
44	u32 miimcon;	/* MII management control reg */
45	u32 miimstat;	/* MII management status reg */
46	u32 miimind;	/* MII management indication reg */
47};
48
49struct fsl_pq_mdio {
50	u8 res1[16];
51	u32 ieventm;	/* MDIO Interrupt event register (for etsec2)*/
52	u32 imaskm;	/* MDIO Interrupt mask register (for etsec2)*/
53	u8 res2[4];
54	u32 emapm;	/* MDIO Event mapping register (for etsec2)*/
55	u8 res3[1280];
56	struct fsl_pq_mii mii;
57	u8 res4[28];
58	u32 utbipar;	/* TBI phy address reg (only on UCC) */
59	u8 res5[2728];
60} __packed;
61
62/* Number of microseconds to wait for an MII register to respond */
63#define MII_TIMEOUT	1000
64
65struct fsl_pq_mdio_priv {
66	void __iomem *map;
67	struct fsl_pq_mii __iomem *regs;
68};
69
70/*
71 * Per-device-type data.  Each type of device tree node that we support gets
72 * one of these.
73 *
74 * @mii_offset: the offset of the MII registers within the memory map of the
75 * node.  Some nodes define only the MII registers, and some define the whole
76 * MAC (which includes the MII registers).
77 *
78 * @get_tbipa: determines the address of the TBIPA register
79 *
80 * @ucc_configure: a special function for extra QE configuration
81 */
82struct fsl_pq_mdio_data {
83	unsigned int mii_offset;	/* offset of the MII registers */
84	uint32_t __iomem * (*get_tbipa)(void __iomem *p);
85	void (*ucc_configure)(phys_addr_t start, phys_addr_t end);
86};
87
88/*
89 * Write value to the PHY at mii_id at register regnum, on the bus attached
90 * to the local interface, which may be different from the generic mdio bus
91 * (tied to a single interface), waiting until the write is done before
92 * returning. This is helpful in programming interfaces like the TBI which
93 * control interfaces like onchip SERDES and are always tied to the local
94 * mdio pins, which may not be the same as system mdio bus, used for
95 * controlling the external PHYs, for example.
96 */
97static int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
98		u16 value)
99{
100	struct fsl_pq_mdio_priv *priv = bus->priv;
101	struct fsl_pq_mii __iomem *regs = priv->regs;
102	unsigned int timeout;
103
104	/* Set the PHY address and the register address we want to write */
105	iowrite32be((mii_id << 8) | regnum, &regs->miimadd);
106
107	/* Write out the value we want */
108	iowrite32be(value, &regs->miimcon);
109
110	/* Wait for the transaction to finish */
111	timeout = MII_TIMEOUT;
112	while ((ioread32be(&regs->miimind) & MIIMIND_BUSY) && timeout) {
113		cpu_relax();
114		timeout--;
115	}
116
117	return timeout ? 0 : -ETIMEDOUT;
118}
119
120/*
121 * Read the bus for PHY at addr mii_id, register regnum, and return the value.
122 * Clears miimcom first.
123 *
124 * All PHY operation done on the bus attached to the local interface, which
125 * may be different from the generic mdio bus.  This is helpful in programming
126 * interfaces like the TBI which, in turn, control interfaces like on-chip
127 * SERDES and are always tied to the local mdio pins, which may not be the
128 * same as system mdio bus, used for controlling the external PHYs, for eg.
129 */
130static int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
131{
132	struct fsl_pq_mdio_priv *priv = bus->priv;
133	struct fsl_pq_mii __iomem *regs = priv->regs;
134	unsigned int timeout;
135	u16 value;
136
137	/* Set the PHY address and the register address we want to read */
138	iowrite32be((mii_id << 8) | regnum, &regs->miimadd);
139
140	/* Clear miimcom, and then initiate a read */
141	iowrite32be(0, &regs->miimcom);
142	iowrite32be(MII_READ_COMMAND, &regs->miimcom);
143
144	/* Wait for the transaction to finish, normally less than 100us */
145	timeout = MII_TIMEOUT;
146	while ((ioread32be(&regs->miimind) &
147	       (MIIMIND_NOTVALID | MIIMIND_BUSY)) && timeout) {
148		cpu_relax();
149		timeout--;
150	}
151
152	if (!timeout)
153		return -ETIMEDOUT;
154
155	/* Grab the value of the register from miimstat */
156	value = ioread32be(&regs->miimstat);
157
158	dev_dbg(&bus->dev, "read %04x from address %x/%x\n", value, mii_id, regnum);
159	return value;
160}
161
162/* Reset the MIIM registers, and wait for the bus to free */
163static int fsl_pq_mdio_reset(struct mii_bus *bus)
164{
165	struct fsl_pq_mdio_priv *priv = bus->priv;
166	struct fsl_pq_mii __iomem *regs = priv->regs;
167	unsigned int timeout;
168
169	mutex_lock(&bus->mdio_lock);
170
171	/* Reset the management interface */
172	iowrite32be(MIIMCFG_RESET, &regs->miimcfg);
173
174	/* Setup the MII Mgmt clock speed */
175	iowrite32be(MIIMCFG_INIT_VALUE, &regs->miimcfg);
176
177	/* Wait until the bus is free */
178	timeout = MII_TIMEOUT;
179	while ((ioread32be(&regs->miimind) & MIIMIND_BUSY) && timeout) {
180		cpu_relax();
181		timeout--;
182	}
183
184	mutex_unlock(&bus->mdio_lock);
185
186	if (!timeout) {
187		dev_err(&bus->dev, "timeout waiting for MII bus\n");
188		return -EBUSY;
189	}
190
191	return 0;
192}
193
194#if IS_ENABLED(CONFIG_GIANFAR)
195/*
196 * Return the TBIPA address, starting from the address
197 * of the mapped GFAR MDIO registers (struct gfar)
198 * This is mildly evil, but so is our hardware for doing this.
199 * Also, we have to cast back to struct gfar because of
200 * definition weirdness done in gianfar.h.
201 */
202static uint32_t __iomem *get_gfar_tbipa_from_mdio(void __iomem *p)
203{
204	struct gfar __iomem *enet_regs = p;
205
206	return &enet_regs->tbipa;
207}
208
209/*
210 * Return the TBIPA address, starting from the address
211 * of the mapped GFAR MII registers (gfar_mii_regs[] within struct gfar)
212 */
213static uint32_t __iomem *get_gfar_tbipa_from_mii(void __iomem *p)
214{
215	return get_gfar_tbipa_from_mdio(container_of(p, struct gfar, gfar_mii_regs));
216}
217
218/*
219 * Return the TBIPAR address for an eTSEC2 node
220 */
221static uint32_t __iomem *get_etsec_tbipa(void __iomem *p)
222{
223	return p;
224}
225#endif
226
227#if IS_ENABLED(CONFIG_UCC_GETH)
228/*
229 * Return the TBIPAR address for a QE MDIO node, starting from the address
230 * of the mapped MII registers (struct fsl_pq_mii)
231 */
232static uint32_t __iomem *get_ucc_tbipa(void __iomem *p)
233{
234	struct fsl_pq_mdio __iomem *mdio = container_of(p, struct fsl_pq_mdio, mii);
235
236	return &mdio->utbipar;
237}
238
239/*
240 * Find the UCC node that controls the given MDIO node
241 *
242 * For some reason, the QE MDIO nodes are not children of the UCC devices
243 * that control them.  Therefore, we need to scan all UCC nodes looking for
244 * the one that encompases the given MDIO node.  We do this by comparing
245 * physical addresses.  The 'start' and 'end' addresses of the MDIO node are
246 * passed, and the correct UCC node will cover the entire address range.
247 *
248 * This assumes that there is only one QE MDIO node in the entire device tree.
249 */
250static void ucc_configure(phys_addr_t start, phys_addr_t end)
251{
252	static bool found_mii_master;
253	struct device_node *np = NULL;
254
255	if (found_mii_master)
256		return;
257
258	for_each_compatible_node(np, NULL, "ucc_geth") {
259		struct resource res;
260		const uint32_t *iprop;
261		uint32_t id;
262		int ret;
263
264		ret = of_address_to_resource(np, 0, &res);
265		if (ret < 0) {
266			pr_debug("fsl-pq-mdio: no address range in node %pOF\n",
267				 np);
268			continue;
269		}
270
271		/* if our mdio regs fall within this UCC regs range */
272		if ((start < res.start) || (end > res.end))
273			continue;
274
275		iprop = of_get_property(np, "cell-index", NULL);
276		if (!iprop) {
277			iprop = of_get_property(np, "device-id", NULL);
278			if (!iprop) {
279				pr_debug("fsl-pq-mdio: no UCC ID in node %pOF\n",
280					 np);
281				continue;
282			}
283		}
284
285		id = be32_to_cpup(iprop);
286
287		/*
288		 * cell-index and device-id for QE nodes are
289		 * numbered from 1, not 0.
290		 */
291		if (ucc_set_qe_mux_mii_mng(id - 1) < 0) {
292			pr_debug("fsl-pq-mdio: invalid UCC ID in node %pOF\n",
293				 np);
294			continue;
295		}
296
297		pr_debug("fsl-pq-mdio: setting node UCC%u to MII master\n", id);
298		found_mii_master = true;
299	}
300}
301
302#endif
303
304static const struct of_device_id fsl_pq_mdio_match[] = {
305#if IS_ENABLED(CONFIG_GIANFAR)
306	{
307		.compatible = "fsl,gianfar-tbi",
308		.data = &(struct fsl_pq_mdio_data) {
309			.mii_offset = 0,
310			.get_tbipa = get_gfar_tbipa_from_mii,
311		},
312	},
313	{
314		.compatible = "fsl,gianfar-mdio",
315		.data = &(struct fsl_pq_mdio_data) {
316			.mii_offset = 0,
317			.get_tbipa = get_gfar_tbipa_from_mii,
318		},
319	},
320	{
321		.type = "mdio",
322		.compatible = "gianfar",
323		.data = &(struct fsl_pq_mdio_data) {
324			.mii_offset = offsetof(struct fsl_pq_mdio, mii),
325			.get_tbipa = get_gfar_tbipa_from_mdio,
326		},
327	},
328	{
329		.compatible = "fsl,etsec2-tbi",
330		.data = &(struct fsl_pq_mdio_data) {
331			.mii_offset = offsetof(struct fsl_pq_mdio, mii),
332			.get_tbipa = get_etsec_tbipa,
333		},
334	},
335	{
336		.compatible = "fsl,etsec2-mdio",
337		.data = &(struct fsl_pq_mdio_data) {
338			.mii_offset = offsetof(struct fsl_pq_mdio, mii),
339			.get_tbipa = get_etsec_tbipa,
340		},
341	},
342#endif
343#if IS_ENABLED(CONFIG_UCC_GETH)
344	{
345		.compatible = "fsl,ucc-mdio",
346		.data = &(struct fsl_pq_mdio_data) {
347			.mii_offset = 0,
348			.get_tbipa = get_ucc_tbipa,
349			.ucc_configure = ucc_configure,
350		},
351	},
352	{
353		/* Legacy UCC MDIO node */
354		.type = "mdio",
355		.compatible = "ucc_geth_phy",
356		.data = &(struct fsl_pq_mdio_data) {
357			.mii_offset = 0,
358			.get_tbipa = get_ucc_tbipa,
359			.ucc_configure = ucc_configure,
360		},
361	},
362#endif
363	/* No Kconfig option for Fman support yet */
364	{
365		.compatible = "fsl,fman-mdio",
366		.data = &(struct fsl_pq_mdio_data) {
367			.mii_offset = 0,
368			/* Fman TBI operations are handled elsewhere */
369		},
370	},
371
372	{},
373};
374MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match);
375
376static void set_tbipa(const u32 tbipa_val, struct platform_device *pdev,
377		      uint32_t __iomem * (*get_tbipa)(void __iomem *),
378		      void __iomem *reg_map, struct resource *reg_res)
379{
380	struct device_node *np = pdev->dev.of_node;
381	uint32_t __iomem *tbipa;
382	bool tbipa_mapped;
383
384	tbipa = of_iomap(np, 1);
385	if (tbipa) {
386		tbipa_mapped = true;
387	} else {
388		tbipa_mapped = false;
389		tbipa = (*get_tbipa)(reg_map);
390
391		/*
392		 * Add consistency check to make sure TBI is contained within
393		 * the mapped range (not because we would get a segfault,
394		 * rather to catch bugs in computing TBI address). Print error
395		 * message but continue anyway.
396		 */
397		if ((void *)tbipa > reg_map + resource_size(reg_res) - 4)
398			dev_err(&pdev->dev, "invalid register map (should be at least 0x%04zx to contain TBI address)\n",
399				((void *)tbipa - reg_map) + 4);
400	}
401
402	iowrite32be(be32_to_cpu(tbipa_val), tbipa);
403
404	if (tbipa_mapped)
405		iounmap(tbipa);
406}
407
408static int fsl_pq_mdio_probe(struct platform_device *pdev)
409{
410	const struct of_device_id *id =
411		of_match_device(fsl_pq_mdio_match, &pdev->dev);
412	const struct fsl_pq_mdio_data *data;
413	struct device_node *np = pdev->dev.of_node;
414	struct resource res;
415	struct device_node *tbi;
416	struct fsl_pq_mdio_priv *priv;
417	struct mii_bus *new_bus;
418	int err;
419
420	if (!id) {
421		dev_err(&pdev->dev, "Failed to match device\n");
422		return -ENODEV;
423	}
424
425	data = id->data;
426
427	dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible);
428
429	new_bus = mdiobus_alloc_size(sizeof(*priv));
430	if (!new_bus)
431		return -ENOMEM;
432
433	priv = new_bus->priv;
434	new_bus->name = "Freescale PowerQUICC MII Bus";
435	new_bus->read = &fsl_pq_mdio_read;
436	new_bus->write = &fsl_pq_mdio_write;
437	new_bus->reset = &fsl_pq_mdio_reset;
438
439	err = of_address_to_resource(np, 0, &res);
440	if (err < 0) {
441		dev_err(&pdev->dev, "could not obtain address information\n");
442		goto error;
443	}
444
445	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%pOFn@%llx", np,
446		 (unsigned long long)res.start);
447
448	priv->map = of_iomap(np, 0);
449	if (!priv->map) {
450		err = -ENOMEM;
451		goto error;
452	}
453
454	/*
455	 * Some device tree nodes represent only the MII registers, and
456	 * others represent the MAC and MII registers.  The 'mii_offset' field
457	 * contains the offset of the MII registers inside the mapped register
458	 * space.
459	 */
460	if (data->mii_offset > resource_size(&res)) {
461		dev_err(&pdev->dev, "invalid register map\n");
462		err = -EINVAL;
463		goto error;
464	}
465	priv->regs = priv->map + data->mii_offset;
466
467	new_bus->parent = &pdev->dev;
468	platform_set_drvdata(pdev, new_bus);
469
470	if (data->get_tbipa) {
471		for_each_child_of_node(np, tbi) {
472			if (of_node_is_type(tbi, "tbi-phy")) {
473				dev_dbg(&pdev->dev, "found TBI PHY node %pOFP\n",
474					tbi);
475				break;
476			}
477		}
478
479		if (tbi) {
480			const u32 *prop = of_get_property(tbi, "reg", NULL);
481			if (!prop) {
482				dev_err(&pdev->dev,
483					"missing 'reg' property in node %pOF\n",
484					tbi);
485				err = -EBUSY;
486				goto error;
487			}
488			set_tbipa(*prop, pdev,
489				  data->get_tbipa, priv->map, &res);
490		}
491	}
492
493	if (data->ucc_configure)
494		data->ucc_configure(res.start, res.end);
495
496	err = of_mdiobus_register(new_bus, np);
497	if (err) {
498		dev_err(&pdev->dev, "cannot register %s as MDIO bus\n",
499			new_bus->name);
500		goto error;
501	}
502
503	return 0;
504
505error:
506	if (priv->map)
507		iounmap(priv->map);
508
509	kfree(new_bus);
510
511	return err;
512}
513
514
515static void fsl_pq_mdio_remove(struct platform_device *pdev)
516{
517	struct device *device = &pdev->dev;
518	struct mii_bus *bus = dev_get_drvdata(device);
519	struct fsl_pq_mdio_priv *priv = bus->priv;
520
521	mdiobus_unregister(bus);
522
523	iounmap(priv->map);
524	mdiobus_free(bus);
525}
526
527static struct platform_driver fsl_pq_mdio_driver = {
528	.driver = {
529		.name = "fsl-pq_mdio",
530		.of_match_table = fsl_pq_mdio_match,
531	},
532	.probe = fsl_pq_mdio_probe,
533	.remove_new = fsl_pq_mdio_remove,
534};
535
536module_platform_driver(fsl_pq_mdio_driver);
537
538MODULE_LICENSE("GPL");
539