1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * CPSW MDIO generic driver for TI AMxx/K2x/EMAC devices.
4  *
5  * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
6  */
7 
8 #include <common.h>
9 #include <log.h>
10 #include <malloc.h>
11 #include <asm/io.h>
12 #include <miiphy.h>
13 #include <wait_bit.h>
14 #include <linux/bitops.h>
15 #include <linux/delay.h>
16 
17 struct cpsw_mdio_regs {
18 	u32	version;
19 	u32	control;
20 #define CONTROL_IDLE		BIT(31)
21 #define CONTROL_ENABLE		BIT(30)
22 #define CONTROL_FAULT		BIT(19)
23 #define CONTROL_FAULT_ENABLE	BIT(18)
24 #define CONTROL_DIV_MASK	GENMASK(15, 0)
25 
26 	u32	alive;
27 	u32	link;
28 	u32	linkintraw;
29 	u32	linkintmasked;
30 	u32	__reserved_0[2];
31 	u32	userintraw;
32 	u32	userintmasked;
33 	u32	userintmaskset;
34 	u32	userintmaskclr;
35 	u32	__reserved_1[20];
36 
37 	struct {
38 		u32		access;
39 		u32		physel;
40 #define USERACCESS_GO		BIT(31)
41 #define USERACCESS_WRITE	BIT(30)
42 #define USERACCESS_ACK		BIT(29)
43 #define USERACCESS_READ		(0)
44 #define USERACCESS_PHY_REG_SHIFT	(21)
45 #define USERACCESS_PHY_ADDR_SHIFT	(16)
46 #define USERACCESS_DATA		GENMASK(15, 0)
47 	} user[0];
48 };
49 
50 #define CPSW_MDIO_DIV_DEF	0xff
51 #define PHY_REG_MASK		0x1f
52 #define PHY_ID_MASK		0x1f
53 
54 /*
55  * This timeout definition is a worst-case ultra defensive measure against
56  * unexpected controller lock ups.  Ideally, we should never ever hit this
57  * scenario in practice.
58  */
59 #define CPSW_MDIO_TIMEOUT            100 /* msecs */
60 
61 struct cpsw_mdio {
62 	struct cpsw_mdio_regs *regs;
63 	struct mii_dev *bus;
64 	int div;
65 };
66 
67 /* wait until hardware is ready for another user access */
cpsw_mdio_wait_for_user_access(struct cpsw_mdio * mdio)68 static int cpsw_mdio_wait_for_user_access(struct cpsw_mdio *mdio)
69 {
70 	return wait_for_bit_le32(&mdio->regs->user[0].access,
71 				 USERACCESS_GO, false,
72 				 CPSW_MDIO_TIMEOUT, false);
73 }
74 
cpsw_mdio_read(struct mii_dev * bus,int phy_id,int dev_addr,int phy_reg)75 static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
76 			  int dev_addr, int phy_reg)
77 {
78 	struct cpsw_mdio *mdio = bus->priv;
79 	int data, ret;
80 	u32 reg;
81 
82 	if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
83 		return -EINVAL;
84 
85 	ret = cpsw_mdio_wait_for_user_access(mdio);
86 	if (ret)
87 		return ret;
88 	reg = (USERACCESS_GO | USERACCESS_READ |
89 	       (phy_reg << USERACCESS_PHY_REG_SHIFT) |
90 	       (phy_id << USERACCESS_PHY_ADDR_SHIFT));
91 	writel(reg, &mdio->regs->user[0].access);
92 	ret = cpsw_mdio_wait_for_user_access(mdio);
93 	if (ret)
94 		return ret;
95 
96 	reg = readl(&mdio->regs->user[0].access);
97 	data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
98 	return data;
99 }
100 
cpsw_mdio_write(struct mii_dev * bus,int phy_id,int dev_addr,int phy_reg,u16 data)101 static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
102 			   int phy_reg, u16 data)
103 {
104 	struct cpsw_mdio *mdio = bus->priv;
105 	u32 reg;
106 	int ret;
107 
108 	if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
109 		return -EINVAL;
110 
111 	ret = cpsw_mdio_wait_for_user_access(mdio);
112 	if (ret)
113 		return ret;
114 	reg = (USERACCESS_GO | USERACCESS_WRITE |
115 	       (phy_reg << USERACCESS_PHY_REG_SHIFT) |
116 	       (phy_id << USERACCESS_PHY_ADDR_SHIFT) |
117 	       (data & USERACCESS_DATA));
118 	writel(reg, &mdio->regs->user[0].access);
119 
120 	return cpsw_mdio_wait_for_user_access(mdio);
121 }
122 
cpsw_mdio_get_alive(struct mii_dev * bus)123 u32 cpsw_mdio_get_alive(struct mii_dev *bus)
124 {
125 	struct cpsw_mdio *mdio = bus->priv;
126 	u32 val;
127 
128 	val = readl(&mdio->regs->control);
129 	return val & GENMASK(15, 0);
130 }
131 
cpsw_mdio_init(const char * name,phys_addr_t mdio_base,u32 bus_freq,int fck_freq)132 struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
133 			       u32 bus_freq, int fck_freq)
134 {
135 	struct cpsw_mdio *cpsw_mdio;
136 	int ret;
137 
138 	cpsw_mdio = calloc(1, sizeof(*cpsw_mdio));
139 	if (!cpsw_mdio) {
140 		debug("failed to alloc cpsw_mdio\n");
141 		return NULL;
142 	}
143 
144 	cpsw_mdio->bus = mdio_alloc();
145 	if (!cpsw_mdio->bus) {
146 		debug("failed to alloc mii bus\n");
147 		free(cpsw_mdio);
148 		return NULL;
149 	}
150 
151 	cpsw_mdio->regs = (struct cpsw_mdio_regs *)(uintptr_t)mdio_base;
152 
153 	if (!bus_freq || !fck_freq)
154 		cpsw_mdio->div = CPSW_MDIO_DIV_DEF;
155 	else
156 		cpsw_mdio->div = (fck_freq / bus_freq) - 1;
157 	cpsw_mdio->div &= CONTROL_DIV_MASK;
158 
159 	/* set enable and clock divider */
160 	writel(cpsw_mdio->div | CONTROL_ENABLE | CONTROL_FAULT |
161 	       CONTROL_FAULT_ENABLE, &cpsw_mdio->regs->control);
162 	wait_for_bit_le32(&cpsw_mdio->regs->control,
163 			  CONTROL_IDLE, false, CPSW_MDIO_TIMEOUT, true);
164 
165 	/*
166 	 * wait for scan logic to settle:
167 	 * the scan time consists of (a) a large fixed component, and (b) a
168 	 * small component that varies with the mii bus frequency.  These
169 	 * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
170 	 * silicon.  Since the effect of (b) was found to be largely
171 	 * negligible, we keep things simple here.
172 	 */
173 	mdelay(1);
174 
175 	cpsw_mdio->bus->read = cpsw_mdio_read;
176 	cpsw_mdio->bus->write = cpsw_mdio_write;
177 	cpsw_mdio->bus->priv = cpsw_mdio;
178 	snprintf(cpsw_mdio->bus->name, sizeof(cpsw_mdio->bus->name), name);
179 
180 	ret = mdio_register(cpsw_mdio->bus);
181 	if (ret < 0) {
182 		debug("failed to register mii bus\n");
183 		goto free_bus;
184 	}
185 
186 	return cpsw_mdio->bus;
187 
188 free_bus:
189 	mdio_free(cpsw_mdio->bus);
190 	free(cpsw_mdio);
191 	return NULL;
192 }
193 
cpsw_mdio_free(struct mii_dev * bus)194 void cpsw_mdio_free(struct mii_dev *bus)
195 {
196 	struct cpsw_mdio *mdio = bus->priv;
197 	u32 reg;
198 
199 	/* disable mdio */
200 	reg = readl(&mdio->regs->control);
201 	reg &= ~CONTROL_ENABLE;
202 	writel(reg, &mdio->regs->control);
203 
204 	mdio_unregister(bus);
205 	mdio_free(bus);
206 	free(mdio);
207 }
208