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