1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /* Copyright 2019 NXP */
3 
4 #include <linux/mdio.h>
5 #include <linux/of_mdio.h>
6 #include <linux/iopoll.h>
7 #include <linux/of.h>
8 
9 #include "enetc_pf.h"
10 
11 struct enetc_mdio_regs {
12 	u32	mdio_cfg;	/* MDIO configuration and status */
13 	u32	mdio_ctl;	/* MDIO control */
14 	u32	mdio_data;	/* MDIO data */
15 	u32	mdio_addr;	/* MDIO address */
16 };
17 
18 #define bus_to_enetc_regs(bus)	(struct enetc_mdio_regs __iomem *)((bus)->priv)
19 
20 #define ENETC_MDIO_REG_OFFSET	0x1c00
21 #define ENETC_MDC_DIV		258
22 
23 #define MDIO_CFG_CLKDIV(x)	((((x) >> 1) & 0xff) << 8)
24 #define MDIO_CFG_BSY		BIT(0)
25 #define MDIO_CFG_RD_ER		BIT(1)
26 #define MDIO_CFG_ENC45		BIT(6)
27  /* external MDIO only - driven on neg MDC edge */
28 #define MDIO_CFG_NEG		BIT(23)
29 
30 #define MDIO_CTL_DEV_ADDR(x)	((x) & 0x1f)
31 #define MDIO_CTL_PORT_ADDR(x)	(((x) & 0x1f) << 5)
32 #define MDIO_CTL_READ		BIT(15)
33 #define MDIO_DATA(x)		((x) & 0xffff)
34 
35 #define TIMEOUT	1000
36 static int enetc_mdio_wait_complete(struct enetc_mdio_regs __iomem *regs)
37 {
38 	u32 val;
39 
40 	return readx_poll_timeout(enetc_rd_reg, &regs->mdio_cfg, val,
41 				  !(val & MDIO_CFG_BSY), 10, 10 * TIMEOUT);
42 }
43 
44 static int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum,
45 			    u16 value)
46 {
47 	struct enetc_mdio_regs __iomem *regs = bus_to_enetc_regs(bus);
48 	u32 mdio_ctl, mdio_cfg;
49 	u16 dev_addr;
50 	int ret;
51 
52 	mdio_cfg = MDIO_CFG_CLKDIV(ENETC_MDC_DIV) | MDIO_CFG_NEG;
53 	if (regnum & MII_ADDR_C45) {
54 		dev_addr = (regnum >> 16) & 0x1f;
55 		mdio_cfg |= MDIO_CFG_ENC45;
56 	} else {
57 		/* clause 22 (ie 1G) */
58 		dev_addr = regnum & 0x1f;
59 		mdio_cfg &= ~MDIO_CFG_ENC45;
60 	}
61 
62 	enetc_wr_reg(&regs->mdio_cfg, mdio_cfg);
63 
64 	ret = enetc_mdio_wait_complete(regs);
65 	if (ret)
66 		return ret;
67 
68 	/* set port and dev addr */
69 	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
70 	enetc_wr_reg(&regs->mdio_ctl, mdio_ctl);
71 
72 	/* set the register address */
73 	if (regnum & MII_ADDR_C45) {
74 		enetc_wr_reg(&regs->mdio_addr, regnum & 0xffff);
75 
76 		ret = enetc_mdio_wait_complete(regs);
77 		if (ret)
78 			return ret;
79 	}
80 
81 	/* write the value */
82 	enetc_wr_reg(&regs->mdio_data, MDIO_DATA(value));
83 
84 	ret = enetc_mdio_wait_complete(regs);
85 	if (ret)
86 		return ret;
87 
88 	return 0;
89 }
90 
91 static int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
92 {
93 	struct enetc_mdio_regs __iomem *regs = bus_to_enetc_regs(bus);
94 	u32 mdio_ctl, mdio_cfg;
95 	u16 dev_addr, value;
96 	int ret;
97 
98 	mdio_cfg = MDIO_CFG_CLKDIV(ENETC_MDC_DIV) | MDIO_CFG_NEG;
99 	if (regnum & MII_ADDR_C45) {
100 		dev_addr = (regnum >> 16) & 0x1f;
101 		mdio_cfg |= MDIO_CFG_ENC45;
102 	} else {
103 		dev_addr = regnum & 0x1f;
104 		mdio_cfg &= ~MDIO_CFG_ENC45;
105 	}
106 
107 	enetc_wr_reg(&regs->mdio_cfg, mdio_cfg);
108 
109 	ret = enetc_mdio_wait_complete(regs);
110 	if (ret)
111 		return ret;
112 
113 	/* set port and device addr */
114 	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
115 	enetc_wr_reg(&regs->mdio_ctl, mdio_ctl);
116 
117 	/* set the register address */
118 	if (regnum & MII_ADDR_C45) {
119 		enetc_wr_reg(&regs->mdio_addr, regnum & 0xffff);
120 
121 		ret = enetc_mdio_wait_complete(regs);
122 		if (ret)
123 			return ret;
124 	}
125 
126 	/* initiate the read */
127 	enetc_wr_reg(&regs->mdio_ctl, mdio_ctl | MDIO_CTL_READ);
128 
129 	ret = enetc_mdio_wait_complete(regs);
130 	if (ret)
131 		return ret;
132 
133 	/* return all Fs if nothing was there */
134 	if (enetc_rd_reg(&regs->mdio_cfg) & MDIO_CFG_RD_ER) {
135 		dev_dbg(&bus->dev,
136 			"Error while reading PHY%d reg at %d.%hhu\n",
137 			phy_id, dev_addr, regnum);
138 		return 0xffff;
139 	}
140 
141 	value = enetc_rd_reg(&regs->mdio_data) & 0xffff;
142 
143 	return value;
144 }
145 
146 int enetc_mdio_probe(struct enetc_pf *pf)
147 {
148 	struct device *dev = &pf->si->pdev->dev;
149 	struct enetc_mdio_regs __iomem *regs;
150 	struct device_node *np;
151 	struct mii_bus *bus;
152 	int ret;
153 
154 	bus = mdiobus_alloc_size(sizeof(regs));
155 	if (!bus)
156 		return -ENOMEM;
157 
158 	bus->name = "Freescale ENETC MDIO Bus";
159 	bus->read = enetc_mdio_read;
160 	bus->write = enetc_mdio_write;
161 	bus->parent = dev;
162 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
163 
164 	/* store the enetc mdio base address for this bus */
165 	regs = pf->si->hw.port + ENETC_MDIO_REG_OFFSET;
166 	bus->priv = regs;
167 
168 	np = of_get_child_by_name(dev->of_node, "mdio");
169 	if (!np) {
170 		dev_err(dev, "MDIO node missing\n");
171 		ret = -EINVAL;
172 		goto err_registration;
173 	}
174 
175 	ret = of_mdiobus_register(bus, np);
176 	if (ret) {
177 		of_node_put(np);
178 		dev_err(dev, "cannot register MDIO bus\n");
179 		goto err_registration;
180 	}
181 
182 	of_node_put(np);
183 	pf->mdio = bus;
184 
185 	return 0;
186 
187 err_registration:
188 	mdiobus_free(bus);
189 
190 	return ret;
191 }
192 
193 void enetc_mdio_remove(struct enetc_pf *pf)
194 {
195 	if (pf->mdio) {
196 		mdiobus_unregister(pf->mdio);
197 		mdiobus_free(pf->mdio);
198 	}
199 }
200