1 // SPDX-License-Identifier: GPL-2.0
2 /* Renesas Ethernet SERDES device driver
3  *
4  * Copyright (C) 2022 Renesas Electronics Corporation
5  */
6 
7 #include <linux/delay.h>
8 #include <linux/err.h>
9 #include <linux/iopoll.h>
10 #include <linux/kernel.h>
11 #include <linux/phy.h>
12 #include <linux/phy/phy.h>
13 #include <linux/platform_device.h>
14 #include <linux/reset.h>
15 
16 #define R8A779F0_ETH_SERDES_NUM			3
17 #define R8A779F0_ETH_SERDES_OFFSET		0x0400
18 #define R8A779F0_ETH_SERDES_BANK_SELECT		0x03fc
19 #define R8A779F0_ETH_SERDES_TIMEOUT_US		100000
20 #define R8A779F0_ETH_SERDES_NUM_RETRY_LINKUP	3
21 
22 struct r8a779f0_eth_serdes_drv_data;
23 struct r8a779f0_eth_serdes_channel {
24 	struct r8a779f0_eth_serdes_drv_data *dd;
25 	struct phy *phy;
26 	void __iomem *addr;
27 	phy_interface_t phy_interface;
28 	int speed;
29 	int index;
30 };
31 
32 struct r8a779f0_eth_serdes_drv_data {
33 	void __iomem *addr;
34 	struct platform_device *pdev;
35 	struct reset_control *reset;
36 	struct r8a779f0_eth_serdes_channel channel[R8A779F0_ETH_SERDES_NUM];
37 	bool initialized;
38 };
39 
40 /*
41  * The datasheet describes initialization procedure without any information
42  * about registers' name/bits. So, this is all black magic to initialize
43  * the hardware.
44  */
45 static void r8a779f0_eth_serdes_write32(void __iomem *addr, u32 offs, u32 bank, u32 data)
46 {
47 	iowrite32(bank, addr + R8A779F0_ETH_SERDES_BANK_SELECT);
48 	iowrite32(data, addr + offs);
49 }
50 
51 static int
52 r8a779f0_eth_serdes_reg_wait(struct r8a779f0_eth_serdes_channel *channel,
53 			     u32 offs, u32 bank, u32 mask, u32 expected)
54 {
55 	int ret;
56 	u32 val;
57 
58 	iowrite32(bank, channel->addr + R8A779F0_ETH_SERDES_BANK_SELECT);
59 
60 	ret = readl_poll_timeout_atomic(channel->addr + offs, val,
61 					(val & mask) == expected,
62 					1, R8A779F0_ETH_SERDES_TIMEOUT_US);
63 	if (ret)
64 		dev_dbg(&channel->phy->dev,
65 			"%s: index %d, offs %x, bank %x, mask %x, expected %x\n",
66 			 __func__, channel->index, offs, bank, mask, expected);
67 
68 	return ret;
69 }
70 
71 static int
72 r8a779f0_eth_serdes_common_init_ram(struct r8a779f0_eth_serdes_drv_data *dd)
73 {
74 	struct r8a779f0_eth_serdes_channel *channel;
75 	int i, ret;
76 
77 	for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) {
78 		channel = &dd->channel[i];
79 		ret = r8a779f0_eth_serdes_reg_wait(channel, 0x026c, 0x180, BIT(0), 0x01);
80 		if (ret)
81 			return ret;
82 	}
83 
84 	r8a779f0_eth_serdes_write32(dd->addr, 0x026c, 0x180, 0x03);
85 
86 	return ret;
87 }
88 
89 static int
90 r8a779f0_eth_serdes_common_setting(struct r8a779f0_eth_serdes_channel *channel)
91 {
92 	struct r8a779f0_eth_serdes_drv_data *dd = channel->dd;
93 
94 	switch (channel->phy_interface) {
95 	case PHY_INTERFACE_MODE_SGMII:
96 		r8a779f0_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x0097);
97 		r8a779f0_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060);
98 		r8a779f0_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200);
99 		r8a779f0_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000);
100 		r8a779f0_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d);
101 		return 0;
102 	default:
103 		return -EOPNOTSUPP;
104 	}
105 }
106 
107 static int
108 r8a779f0_eth_serdes_chan_setting(struct r8a779f0_eth_serdes_channel *channel)
109 {
110 	int ret;
111 
112 	switch (channel->phy_interface) {
113 	case PHY_INTERFACE_MODE_SGMII:
114 		r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2000);
115 		r8a779f0_eth_serdes_write32(channel->addr, 0x01c0, 0x180, 0x0011);
116 		r8a779f0_eth_serdes_write32(channel->addr, 0x0248, 0x180, 0x0540);
117 		r8a779f0_eth_serdes_write32(channel->addr, 0x0258, 0x180, 0x0015);
118 		r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x0100);
119 		r8a779f0_eth_serdes_write32(channel->addr, 0x01a0, 0x180, 0x0000);
120 		r8a779f0_eth_serdes_write32(channel->addr, 0x00d0, 0x180, 0x0002);
121 		r8a779f0_eth_serdes_write32(channel->addr, 0x0150, 0x180, 0x0003);
122 		r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0100);
123 		r8a779f0_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x0100);
124 		r8a779f0_eth_serdes_write32(channel->addr, 0x0174, 0x180, 0x0000);
125 		r8a779f0_eth_serdes_write32(channel->addr, 0x0160, 0x180, 0x0007);
126 		r8a779f0_eth_serdes_write32(channel->addr, 0x01ac, 0x180, 0x0000);
127 		r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x0310);
128 		r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0101);
129 		ret = r8a779f0_eth_serdes_reg_wait(channel, 0x00c8, 0x0180, BIT(0), 0);
130 		if (ret)
131 			return ret;
132 
133 		r8a779f0_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x0101);
134 		ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0148, 0x0180, BIT(0), 0);
135 		if (ret)
136 			return ret;
137 
138 		r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x1310);
139 		r8a779f0_eth_serdes_write32(channel->addr, 0x00d8, 0x180, 0x1800);
140 		r8a779f0_eth_serdes_write32(channel->addr, 0x00dc, 0x180, 0x0000);
141 		r8a779f0_eth_serdes_write32(channel->addr, 0x001c, 0x300, 0x0001);
142 		r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2100);
143 		ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0000, 0x0380, BIT(8), 0);
144 		if (ret)
145 			return ret;
146 
147 		if (channel->speed == 1000)
148 			r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x0140);
149 		else if (channel->speed == 100)
150 			r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x2100);
151 
152 		/* For AN_ON */
153 		r8a779f0_eth_serdes_write32(channel->addr, 0x0004, 0x1f80, 0x0005);
154 		r8a779f0_eth_serdes_write32(channel->addr, 0x0028, 0x1f80, 0x07a1);
155 		r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f80, 0x0208);
156 		break;
157 	default:
158 		return -EOPNOTSUPP;
159 	}
160 
161 	return 0;
162 }
163 
164 static int
165 r8a779f0_eth_serdes_chan_speed(struct r8a779f0_eth_serdes_channel *channel)
166 {
167 	int ret;
168 
169 	switch (channel->phy_interface) {
170 	case PHY_INTERFACE_MODE_SGMII:
171 		/* For AN_ON */
172 		if (channel->speed == 1000)
173 			r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x1140);
174 		else if (channel->speed == 100)
175 			r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x3100);
176 		ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0008, 0x1f80, BIT(0), 1);
177 		if (ret)
178 			return ret;
179 		r8a779f0_eth_serdes_write32(channel->addr, 0x0008, 0x1f80, 0x0000);
180 		break;
181 	default:
182 		return -EOPNOTSUPP;
183 	}
184 
185 	return 0;
186 }
187 
188 
189 static int r8a779f0_eth_serdes_monitor_linkup(struct r8a779f0_eth_serdes_channel *channel)
190 {
191 	int i, ret;
192 
193 	for (i = 0; i < R8A779F0_ETH_SERDES_NUM_RETRY_LINKUP; i++) {
194 		ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0004, 0x300,
195 						   BIT(2), BIT(2));
196 		if (!ret)
197 			break;
198 
199 		/* restart */
200 		r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x0100);
201 		udelay(1);
202 		r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x0000);
203 	}
204 
205 	return ret;
206 }
207 
208 static int r8a779f0_eth_serdes_hw_init(struct r8a779f0_eth_serdes_channel *channel)
209 {
210 	struct r8a779f0_eth_serdes_drv_data *dd = channel->dd;
211 	int i, ret;
212 
213 	if (dd->initialized)
214 		return 0;
215 
216 	ret = r8a779f0_eth_serdes_common_init_ram(dd);
217 	if (ret)
218 		return ret;
219 
220 	for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) {
221 		ret = r8a779f0_eth_serdes_reg_wait(&dd->channel[i], 0x0000,
222 						   0x300, BIT(15), 0);
223 		if (ret)
224 			return ret;
225 	}
226 
227 	for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++)
228 		r8a779f0_eth_serdes_write32(dd->channel[i].addr, 0x03d4, 0x380, 0x0443);
229 
230 	ret = r8a779f0_eth_serdes_common_setting(channel);
231 	if (ret)
232 		return ret;
233 
234 	for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++)
235 		r8a779f0_eth_serdes_write32(dd->channel[i].addr, 0x03d0, 0x380, 0x0001);
236 
237 
238 	r8a779f0_eth_serdes_write32(dd->addr, 0x0000, 0x380, 0x8000);
239 
240 	ret = r8a779f0_eth_serdes_common_init_ram(dd);
241 	if (ret)
242 		return ret;
243 
244 	return r8a779f0_eth_serdes_reg_wait(&dd->channel[0], 0x0000, 0x380, BIT(15), 0);
245 }
246 
247 static int r8a779f0_eth_serdes_init(struct phy *p)
248 {
249 	struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p);
250 	int ret;
251 
252 	ret = r8a779f0_eth_serdes_hw_init(channel);
253 	if (!ret)
254 		channel->dd->initialized = true;
255 
256 	return ret;
257 }
258 
259 static int r8a779f0_eth_serdes_hw_init_late(struct r8a779f0_eth_serdes_channel
260 *channel)
261 {
262 	int ret;
263 
264 	ret = r8a779f0_eth_serdes_chan_setting(channel);
265 	if (ret)
266 		return ret;
267 
268 	ret = r8a779f0_eth_serdes_chan_speed(channel);
269 	if (ret)
270 		return ret;
271 
272 	r8a779f0_eth_serdes_write32(channel->addr, 0x03c0, 0x380, 0x0000);
273 
274 	r8a779f0_eth_serdes_write32(channel->addr, 0x03d0, 0x380, 0x0000);
275 
276 	return r8a779f0_eth_serdes_monitor_linkup(channel);
277 }
278 
279 static int r8a779f0_eth_serdes_power_on(struct phy *p)
280 {
281 	struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p);
282 
283 	return r8a779f0_eth_serdes_hw_init_late(channel);
284 }
285 
286 static int r8a779f0_eth_serdes_set_mode(struct phy *p, enum phy_mode mode,
287 					int submode)
288 {
289 	struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p);
290 
291 	if (mode != PHY_MODE_ETHERNET)
292 		return -EOPNOTSUPP;
293 
294 	switch (submode) {
295 	case PHY_INTERFACE_MODE_GMII:
296 	case PHY_INTERFACE_MODE_SGMII:
297 	case PHY_INTERFACE_MODE_USXGMII:
298 		channel->phy_interface = submode;
299 		return 0;
300 	default:
301 		return -EOPNOTSUPP;
302 	}
303 }
304 
305 static int r8a779f0_eth_serdes_set_speed(struct phy *p, int speed)
306 {
307 	struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p);
308 
309 	channel->speed = speed;
310 
311 	return 0;
312 }
313 
314 static const struct phy_ops r8a779f0_eth_serdes_ops = {
315 	.init		= r8a779f0_eth_serdes_init,
316 	.power_on	= r8a779f0_eth_serdes_power_on,
317 	.set_mode	= r8a779f0_eth_serdes_set_mode,
318 	.set_speed	= r8a779f0_eth_serdes_set_speed,
319 };
320 
321 static struct phy *r8a779f0_eth_serdes_xlate(struct device *dev,
322 					     struct of_phandle_args *args)
323 {
324 	struct r8a779f0_eth_serdes_drv_data *dd = dev_get_drvdata(dev);
325 
326 	if (args->args[0] >= R8A779F0_ETH_SERDES_NUM)
327 		return ERR_PTR(-ENODEV);
328 
329 	return dd->channel[args->args[0]].phy;
330 }
331 
332 static const struct of_device_id r8a779f0_eth_serdes_of_table[] = {
333 	{ .compatible = "renesas,r8a779f0-ether-serdes", },
334 	{ }
335 };
336 MODULE_DEVICE_TABLE(of, r8a779f0_eth_serdes_of_table);
337 
338 static int r8a779f0_eth_serdes_probe(struct platform_device *pdev)
339 {
340 	struct r8a779f0_eth_serdes_drv_data *dd;
341 	struct phy_provider *provider;
342 	struct resource *res;
343 	int i;
344 
345 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
346 	if (!res) {
347 		dev_err(&pdev->dev, "invalid resource\n");
348 		return -EINVAL;
349 	}
350 
351 	dd = devm_kzalloc(&pdev->dev, sizeof(*dd), GFP_KERNEL);
352 	if (!dd)
353 		return -ENOMEM;
354 
355 	platform_set_drvdata(pdev, dd);
356 	dd->pdev = pdev;
357 	dd->addr = devm_ioremap_resource(&pdev->dev, res);
358 	if (IS_ERR(dd->addr))
359 		return PTR_ERR(dd->addr);
360 
361 	dd->reset = devm_reset_control_get(&pdev->dev, NULL);
362 	if (IS_ERR(dd->reset))
363 		return PTR_ERR(dd->reset);
364 
365 	reset_control_reset(dd->reset);
366 
367 	for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) {
368 		struct r8a779f0_eth_serdes_channel *channel = &dd->channel[i];
369 
370 		channel->phy = devm_phy_create(&pdev->dev, NULL,
371 					       &r8a779f0_eth_serdes_ops);
372 		if (IS_ERR(channel->phy))
373 			return PTR_ERR(channel->phy);
374 		channel->addr = dd->addr + R8A779F0_ETH_SERDES_OFFSET * i;
375 		channel->dd = dd;
376 		channel->index = i;
377 		phy_set_drvdata(channel->phy, channel);
378 	}
379 
380 	provider = devm_of_phy_provider_register(&pdev->dev,
381 						 r8a779f0_eth_serdes_xlate);
382 	if (IS_ERR(provider))
383 		return PTR_ERR(provider);
384 
385 	pm_runtime_enable(&pdev->dev);
386 	pm_runtime_get_sync(&pdev->dev);
387 
388 	return 0;
389 }
390 
391 static int r8a779f0_eth_serdes_remove(struct platform_device *pdev)
392 {
393 	pm_runtime_put(&pdev->dev);
394 	pm_runtime_disable(&pdev->dev);
395 
396 	platform_set_drvdata(pdev, NULL);
397 
398 	return 0;
399 }
400 
401 static struct platform_driver r8a779f0_eth_serdes_driver_platform = {
402 	.probe = r8a779f0_eth_serdes_probe,
403 	.remove = r8a779f0_eth_serdes_remove,
404 	.driver = {
405 		.name = "r8a779f0_eth_serdes",
406 		.of_match_table = r8a779f0_eth_serdes_of_table,
407 	}
408 };
409 module_platform_driver(r8a779f0_eth_serdes_driver_platform);
410 MODULE_AUTHOR("Yoshihiro Shimoda");
411 MODULE_DESCRIPTION("Renesas Ethernet SERDES device driver");
412 MODULE_LICENSE("GPL");
413