blob: c4eac122c647b36842488729a4dec598649ed2b7 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * dwmac-stm32.c - DWMAC Specific Glue layer for ASR SOC
4 *
5 * Copyright (C) ASR Microelectronics 2022
6 * Author: Fei Lv <feilv@asrmicro.com>.
7 */
8
9#include <linux/clk.h>
10#include <linux/kernel.h>
11#include <linux/mfd/syscon.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_gpio.h>
15#include <linux/of_device.h>
16#include <linux/of_net.h>
17#include <linux/phy.h>
18#include <linux/platform_device.h>
19#include <linux/pm_wakeirq.h>
20#include <linux/regmap.h>
21#include <linux/slab.h>
22#include <linux/stmmac.h>
23#include <linux/cputype.h>
24#include <soc/asr/regs-addr.h>
25
26#include "stmmac_platform.h"
27
28#define APMU_XGMAC_CLK_RST_CTRL 0x3d4
29#define XGMAC_PHY_INTR_EN (0x1 << 12)
30#define XGMAC_PHY_LPI_INTR_EN (0x1 << 11)
31#define XGMAC_RGMII_TXC_SRC_SEL (0x1 << 8)
32#define XGMAC_INTF_SEL_SHIFT 2
33#define XGMAC_INTF_SEL_MASK GENMASK(3, XGMAC_INTF_SEL_SHIFT)
34#define XGMAC_INTF_SEL_RGMII (0x1 << XGMAC_INTF_SEL_SHIFT)
35#define APMU_XGMAC_RGMII_RX_DLINE 0x3d8
36#define APMU_XGMAC_RGMII_TX_DLINE 0x3dc
37#define APMU_HSIO_RC_SAVE 0x3f8
38#define APB_SPARE24_REG 0x15c
39
40/*
41 * mapping table:
42 *
43 * 0x0c_0000 ~ 0x0c_00ac ==> 0xc010_0000 ~ 0xc010_00ac
44 * 0x0c_1c20 ~ 0x0c_1c40 ==> 0xc010_0120 ~ 0xc010_0140
45 * 0x0e_0000 ~ 0x0e_0044 ==> 0xc010_0200 ~ 0xc010_0244
46 * 0x78_0000 ~ 0x78_003c ==> 0xc010_0300 ~ 0xc010_033c
47 * 0x7c_0000 ~ 0x7c_003c ==> 0xc010_0400 ~ 0xc010_043c
48 * 0x7e_0000 ~ 0x7e_0028 ==> 0xc010_0500 ~ 0xc010_0528
49 * 0x80_0800 ~ 0x80_0b00 ==> 0xc010_0800 ~ 0xc010_0b00
50 * 0xc0_1000 ~ 0xc0_1fff ==> 0xc010_1000 ~ 0xc010_1fff
51*/
52#define VR_XS_PCS_DIG_CTRL1 0x200
53#define VR_XS_PCS_KR_CTRL 0x21c
54#define PMA_BASE 0x800
55#define SR_MII_CTRL 0x400
56#define VR_MII_AN_CTRL 0x504
57#define SR_XS_PCS_CTRL2 0x01c
58#define SR_XS_PCS_CTRL1 0x000
59#define SR_XS_PCS_STS1 0x004
60#define VR_XS_PCS_DIG_STS 0x240
61#define SR_XS_PCS_TP_CTRL 0x0a8
62#define VR_XS_PCS_KR_CTRL 0x21c
63#define SR_XS_PCS_TP_ERRCTR 0x0ac
64#define VR_XS_PCS_EEE_MCTRL 0x218
65
66struct asr_dwmac {
67 struct clk *clk_eth_ck;
68 u32 mode_reg; /* MAC glue-logic mode register */
69 struct regmap *regmap;
70 u32 speed;
71 const struct asr_xgmac_ops *ops;
72 struct device *dev;
73 struct plat_stmmacenet_data *plat;
74
75 int phy_intr_disable;
76 struct pinctrl *pinctrl;
77 struct pinctrl_state *rgmii_pins;
78 int rst_gpio, ldo_gpio, ldo_gpio2;
79
80 /* rgmii clock settings */
81 int rgmii_tx_clk_soc;
82 u32 rgmii_tx_delay_code;
83 u32 rgmii_tx_delay_step;
84 u32 rgmii_rx_delay_code;
85 u32 rgmii_rx_delay_step;
86};
87
88struct asr_xgmac_ops {
89 int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
90 int (*clk_prepare)(struct asr_dwmac *dwmac, bool prepare);
91 int (*suspend)(struct asr_dwmac *dwmac);
92 void (*resume)(struct asr_dwmac *dwmac);
93 int (*parse_data)(struct asr_dwmac *dwmac,
94 struct device *dev);
95};
96
97#if 0
98static void asr_xgmac_phy_reg_dump(struct plat_stmmacenet_data *plat_dat)
99{
100 struct asr_dwmac *dwmac = plat_dat->bsp_priv;
101 int ret, val;
102 int i;
103
104 for (i = 0; i <= 0xac; i = i + 4) {
105 ret = regmap_read(dwmac->regmap, i, &val);
106 dev_info(dwmac->dev,"PCS_MMD:0x%x:0x%x\n", 0xC0100000 + i, val);
107 }
108 for (i = 0x120; i <= 0x140; i = i + 4) {
109 ret = regmap_read(dwmac->regmap, i, &val);
110 dev_info(dwmac->dev,"PCS_MMD:0x%x:0x%x\n", 0xC0100000 + i, val);
111 }
112 for (i = 0x200; i <= 0x244; i = i + 4) {
113 ret = regmap_read(dwmac->regmap, i, &val);
114 dev_info(dwmac->dev,"PCS_MMD:0x%x:0x%x\n", 0xC0100000 + i, val);
115 }
116 for (i = 0x300; i <= 0x33c; i = i + 4) {
117 ret = regmap_read(dwmac->regmap, i, &val);
118 dev_info(dwmac->dev,"VS_MMD1:0x%x:0x%x\n", 0xC0100000 + i, val);
119 }
120 for (i = 0x400; i <= 0x43c; i = i + 4) {
121 ret = regmap_read(dwmac->regmap, i, &val);
122 dev_info(dwmac->dev,"VS_MII_MMD:0x%x:0x%x\n", 0xC0100000 + i, val);
123 }
124 for (i = 0x500; i <= 0x528; i = i + 4) {
125 ret = regmap_read(dwmac->regmap, i, &val);
126 dev_info(dwmac->dev,"VS_MII_MMD:0x%x:0x%x\n", 0xC0100000 + i, val);
127 }
128 for (i = 0x800; i <= 0xb00; i = i + 4) {
129 ret = regmap_read(dwmac->regmap, i, &val);
130 dev_info(dwmac->dev,"PMA:0x%x:0x%x\n", 0xC0100000 + i, val);
131 }
132}
133#endif
134
135static void asr_dwmac_set_clk_rst(struct plat_stmmacenet_data *plat_dat)
136{
137 void __iomem *apmu_base = regs_addr_get_va(REGS_ADDR_APMU);
138 u32 val;
139
140 val = readl(apmu_base + APMU_XGMAC_CLK_RST_CTRL);
141 val |= 0x3;
142 writel(val, apmu_base + APMU_XGMAC_CLK_RST_CTRL);
143}
144
145static int asr_dwmac_get_phy_rc(struct plat_stmmacenet_data *plat_dat)
146{
147 void __iomem *apmu_base = regs_addr_get_va(REGS_ADDR_APMU);
148 u32 val;
149 (void)plat_dat;
150
151 val = readl(apmu_base + APMU_HSIO_RC_SAVE);
152 return val;
153}
154
155static int asr_dwmac_enable_rc_r_cal(struct plat_stmmacenet_data *plat_dat)
156{
157 void __iomem *apb_spare = regs_addr_get_va(REGS_ADDR_APBS);
158 u32 val;
159 (void)plat_dat;
160
161 val = readl(apb_spare + APB_SPARE24_REG);
162 if ((val & (0x3 << 14)) == (0x3 << 14))
163 return 0;
164
165 writel(val | BIT(0), apb_spare + APB_SPARE24_REG);
166 do {
167 val = readl(apb_spare + APB_SPARE24_REG);
168 if ((val & (0x3 << 14)) == (0x3 << 14))
169 break;
170 } while (1);
171
172 return 0;
173}
174
175static void asr_dwmac_set_rgmii_rx_dline(struct plat_stmmacenet_data *plat_dat)
176{
177 struct asr_dwmac *dwmac = plat_dat->bsp_priv;
178 void __iomem *apmu_base = regs_addr_get_va(REGS_ADDR_APMU);
179 u32 val, dline;
180
181 dline = dwmac->rgmii_rx_delay_step;
182 dline |= (dwmac->rgmii_rx_delay_code << 8);
183 val = readl(apmu_base + APMU_XGMAC_RGMII_RX_DLINE);
184 val &= ~(0xff << 8 | 0xff);
185 val |= dline;
186 val |= BIT(31);
187 writel(val, apmu_base + APMU_XGMAC_RGMII_RX_DLINE);
188 pr_info("==> APMU_XGMAC_RGMII_RX_DLINE: 0x%x rgmii_rx_delay_code=%d\n",
189 readl(apmu_base + APMU_XGMAC_RGMII_RX_DLINE),
190 dwmac->rgmii_rx_delay_code);
191}
192
193static void asr_dwmac_set_rgmii_tx_dline(struct plat_stmmacenet_data *plat_dat)
194{
195 struct asr_dwmac *dwmac = plat_dat->bsp_priv;
196 void __iomem *apmu_base = regs_addr_get_va(REGS_ADDR_APMU);
197 u32 val, dline;
198
199 dline = dwmac->rgmii_tx_delay_step;
200 dline |= (dwmac->rgmii_tx_delay_code << 8);
201 val = readl(apmu_base + APMU_XGMAC_RGMII_TX_DLINE);
202 val &= ~(0xff << 8 | 0xff);
203 val |= dline;
204 val |= BIT(31);
205 writel(val, apmu_base + APMU_XGMAC_RGMII_TX_DLINE);
206 pr_info("==> APMU_XGMAC_RGMII_TX_DLINE: 0x%x rgmii_tx_delay_code=%d\n",
207 readl(apmu_base + APMU_XGMAC_RGMII_TX_DLINE),
208 dwmac->rgmii_tx_delay_code);
209}
210
211static void asr_dwmac_select_interface(struct plat_stmmacenet_data *plat_dat)
212{
213 struct asr_dwmac *dwmac = plat_dat->bsp_priv;
214 void __iomem *apmu_base = regs_addr_get_va(REGS_ADDR_APMU);
215 u32 val;
216
217 val = readl(apmu_base + APMU_XGMAC_CLK_RST_CTRL);
218 val &= ~(XGMAC_INTF_SEL_MASK | XGMAC_RGMII_TXC_SRC_SEL);
219 /* RGMII settings */
220 if (plat_dat->interface == PHY_INTERFACE_MODE_RGMII) {
221 pinctrl_select_state(dwmac->pinctrl, dwmac->rgmii_pins);
222 val |= XGMAC_INTF_SEL_RGMII;
223 if (dwmac->rgmii_tx_clk_soc)
224 val |= XGMAC_RGMII_TXC_SRC_SEL;
225 asr_dwmac_set_rgmii_rx_dline(plat_dat);
226 asr_dwmac_set_rgmii_tx_dline(plat_dat);
227 }
228 if (dwmac->phy_intr_disable)
229 val &= ~XGMAC_PHY_INTR_EN;
230 else
231 val |= XGMAC_PHY_INTR_EN;
232 writel(val, apmu_base + APMU_XGMAC_CLK_RST_CTRL);
233
234 pr_info("==> APMU_XGMAC_CLK_RST_CTRL: 0x%x\n",
235 readl(apmu_base + APMU_XGMAC_CLK_RST_CTRL));
236}
237
238static int asr_dwmac_init(struct plat_stmmacenet_data *plat_dat)
239{
240 struct asr_dwmac *dwmac = plat_dat->bsp_priv;
241 int ret;
242
243 dwmac->plat = plat_dat;
244 asr_dwmac_set_clk_rst(plat_dat);
245
246 if (dwmac->ops->set_mode) {
247 ret = dwmac->ops->set_mode(plat_dat);
248 if (ret)
249 return ret;
250 }
251
252 if (dwmac->ops->clk_prepare)
253 ret = dwmac->ops->clk_prepare(dwmac, true);
254
255 return ret;
256}
257
258static int asr_xgmac_clk_prepare(struct asr_dwmac *dwmac, bool prepare)
259{
260 int ret = 0;
261
262 if (!dwmac->clk_eth_ck)
263 return ret;
264
265 if (prepare)
266 ret = clk_prepare_enable(dwmac->clk_eth_ck);
267 else
268 clk_disable_unprepare(dwmac->clk_eth_ck);
269
270 return ret;
271}
272
273static int asr_xgmac_set_sgmii_2500basex(struct plat_stmmacenet_data *plat_dat)
274{
275 struct asr_dwmac *dwmac = plat_dat->bsp_priv;
276 int speed = dwmac->speed;
277 int val, ret;
278
279 /* disable USXGMII mode */
280 ret = regmap_read(dwmac->regmap, VR_XS_PCS_DIG_CTRL1, &val);
281 val &= ~(0x1 << 9);
282 ret = regmap_write(dwmac->regmap, VR_XS_PCS_DIG_CTRL1, val);
283
284 if (plat_dat->interface == PHY_INTERFACE_MODE_2500BASEX) {
285 /* Select 10GBASE-X PCS Type */
286 ret = regmap_read(dwmac->regmap, SR_XS_PCS_CTRL2, &val);
287 val &= ~0xf;
288 val |= 0xe;
289 ret = regmap_write(dwmac->regmap, SR_XS_PCS_CTRL2, val);
290 } else {
291 /* Select 10GBASE-X PCS Type */
292 ret = regmap_read(dwmac->regmap, SR_XS_PCS_CTRL2, &val);
293 val &= ~0xf;
294 val |= 0x1;
295 ret = regmap_write(dwmac->regmap, SR_XS_PCS_CTRL2, val);
296
297 /* select SGMII mode */
298 ret = regmap_read(dwmac->regmap, VR_MII_AN_CTRL, &val);
299 val &= ~(0x3 << 1);
300 val |= 0x2 << 1;
301 ret = regmap_write(dwmac->regmap, VR_MII_AN_CTRL, val);
302
303 /* disable rpcs_clk in sgmii mode */
304 ret = regmap_write(dwmac->regmap, PMA_BASE, 0x15551555);
305
306 /* Enable 2.5G GMII Mode if needed */
307 ret = regmap_read(dwmac->regmap, VR_XS_PCS_DIG_CTRL1, &val);
308 if (speed == SPEED_2500)
309 val |= 0x1 << 2;
310 else
311 val &= ~(0x1 << 2);
312 ret = regmap_write(dwmac->regmap, VR_XS_PCS_DIG_CTRL1, val);
313 }
314
315 switch (speed) {
316 case SPEED_2500:
317 case SPEED_1000:
318 /* set 2.5G/1G speed */
319 ret = regmap_read(dwmac->regmap, SR_MII_CTRL, &val);
320 val &= ~(0x1 << 13 | 0x1 << 6 | 0x1 << 5);
321 val |= 0x1 << 6;
322 ret = regmap_write(dwmac->regmap, SR_MII_CTRL, val);
323 break;
324 case SPEED_100:
325 /* set 100M speed */
326 ret = regmap_read(dwmac->regmap, SR_MII_CTRL, &val);
327 val &= ~(0x1 << 13 | 0x1 << 6 | 0x1 << 5);
328 val |= 0x1 << 13;
329 ret = regmap_write(dwmac->regmap, SR_MII_CTRL, val);
330 break;
331 case SPEED_10:
332 /* set 10M speed */
333 ret = regmap_read(dwmac->regmap, SR_MII_CTRL, &val);
334 val &= ~(0x1 << 13 | 0x1 << 6 | 0x1 << 5);
335 ret = regmap_write(dwmac->regmap, SR_MII_CTRL, val);
336 break;
337 default:
338 dev_err(dwmac->dev, "unsupported sgmii speed %d\n", speed);
339 break;
340 }
341
342 /* PCS POWER down */
343 ret = regmap_read(dwmac->regmap, SR_XS_PCS_CTRL1, &val);
344 val |= 0x1 << 11;
345 ret = regmap_write(dwmac->regmap, SR_XS_PCS_CTRL1, val);
346
347 if (cpu_is_asr1901()) {
348 /* get rc value from HSIO RC save register */
349 val = asr_dwmac_get_phy_rc(plat_dat);
350 val &= 0xffff;
351 ret = regmap_write(dwmac->regmap, PMA_BASE + 0x28, val);
352 } else {
353 asr_dwmac_enable_rc_r_cal(plat_dat);
354 }
355
356 /* turn off ssc */
357 ret = regmap_read(dwmac->regmap, PMA_BASE + 0x1c, &val);
358 val &= ~(0xf << 24);
359 ret = regmap_write(dwmac->regmap, PMA_BASE + 0x1c, val);
360
361 /* wait till PSEQ_STATE are not 3'b100 */
362 do {
363 ret = regmap_read(dwmac->regmap, VR_XS_PCS_DIG_STS, &val);
364 if ((val & (0x7 << 2)) != 0x10)
365 break;
366 } while (1);
367
368 /* PCS POWER UP */
369 ret = regmap_read(dwmac->regmap, SR_XS_PCS_CTRL1, &val);
370 val &= ~(0x1 << 11);
371 ret = regmap_write(dwmac->regmap, SR_XS_PCS_CTRL1, val);
372
373 /* wait PLL lock */
374 do {
375 ret = regmap_read(dwmac->regmap, PMA_BASE + 8, &val);
376 if (val & (0x1 << 24))
377 break;
378 } while (1);
379 dev_info(dwmac->dev,"PLL is locked, phy mode: %s\n",
380 phy_modes(plat_dat->interface));
381
382 /* clear bit15/bit11 to enable pu_tx and rx data */
383 ret = regmap_write(dwmac->regmap, PMA_BASE + 0x44, 0x0);
384 return ret;
385}
386
387static int asr_xgmac_set_usxgmii(struct plat_stmmacenet_data *plat_dat)
388{
389 struct asr_dwmac *dwmac = plat_dat->bsp_priv;
390 int speed = dwmac->speed;
391 int val, ret;
392
393 /* disable xgxs_clk for usxgmii mode */
394 ret = regmap_write(dwmac->regmap, PMA_BASE, 0x55455545);
395
396 /* enable USXGMII mode */
397 ret = regmap_read(dwmac->regmap, VR_XS_PCS_DIG_CTRL1, &val);
398 val |= 0x1 << 9;
399 ret = regmap_write(dwmac->regmap, VR_XS_PCS_DIG_CTRL1, val);
400
401 switch (speed) {
402 case SPEED_2500:
403 /* enable 2.5G-SXGMII */
404 ret = regmap_read(dwmac->regmap, VR_XS_PCS_KR_CTRL, &val);
405 val &= ~(0x7 << 10);
406 val |= 0x2 << 10;
407 ret = regmap_write(dwmac->regmap, VR_XS_PCS_KR_CTRL, val);
408
409 /* set 2.5G speed */
410 ret = regmap_read(dwmac->regmap, SR_MII_CTRL, &val);
411 val &= ~(0x1 << 13 | 0x1 << 6 | 0x1 << 5);
412 val |= 0x1 << 5;
413 ret = regmap_write(dwmac->regmap, SR_MII_CTRL, val);
414 break;
415 case SPEED_5000:
416 /* enable 5G-SXGMII */
417 ret = regmap_read(dwmac->regmap, VR_XS_PCS_KR_CTRL, &val);
418 val &= ~(0x7 << 10);
419 val |= 0x1 << 10;
420 ret = regmap_write(dwmac->regmap, VR_XS_PCS_KR_CTRL, val);
421
422 /* set 5G speed */
423 ret = regmap_read(dwmac->regmap, SR_MII_CTRL, &val);
424 val &= ~(0x1 << 13 | 0x1 << 6 | 0x1 << 5);
425 val |= 0x1 << 5 | 0x1 << 13;
426 ret = regmap_write(dwmac->regmap, SR_MII_CTRL, val);
427 break;
428 default:
429 dev_err(dwmac->dev, "unsupported usxgmii speed %d\n", speed);
430 break;
431 }
432
433 /* force mpu to 0*/
434 ret = regmap_read(dwmac->regmap, PMA_BASE + 0x44, &val);
435 val |= 0x1 << 9;
436 ret = regmap_write(dwmac->regmap, PMA_BASE + 0x44, val);
437
438 if (cpu_is_asr1901()) {
439 /* get rc value from HSIO RC save register */
440 val = asr_dwmac_get_phy_rc(plat_dat);
441 val &= 0xffff;
442 ret = regmap_write(dwmac->regmap, PMA_BASE + 0x28, val);
443 } else {
444 asr_dwmac_enable_rc_r_cal(plat_dat);
445 }
446
447 /* release mpu to 1 */
448 ret = regmap_read(dwmac->regmap, PMA_BASE + 0x44, &val);
449 val &= ~(0x1 << 9);
450 ret = regmap_write(dwmac->regmap, PMA_BASE + 0x44, val);
451
452 /* do xpcs soft reset to change mode */
453 ret = regmap_read(dwmac->regmap, VR_XS_PCS_DIG_CTRL1, &val);
454 val |= 0x1 << 15;
455 ret = regmap_write(dwmac->regmap, VR_XS_PCS_DIG_CTRL1, val);
456
457 /* wait PLL lock */
458 do {
459 ret = regmap_read(dwmac->regmap, PMA_BASE + 8, &val);
460 if (val & (0x1 << 24))
461 break;
462 } while (1);
463 dev_info(dwmac->dev,"USXGMII: pll is locked\n");
464
465 /* Enable TX PMA output */
466 ret = regmap_write(dwmac->regmap, PMA_BASE + 0x44, 0x0);
467 return ret;
468}
469
470static int asr_xgmac_set_mode(struct plat_stmmacenet_data *plat_dat)
471{
472 /* select RGMII or XGMII/GMII */
473 asr_dwmac_select_interface(plat_dat);
474
475 switch (plat_dat->interface) {
476 case PHY_INTERFACE_MODE_RGMII:
477 break;
478 case PHY_INTERFACE_MODE_SGMII:
479 case PHY_INTERFACE_MODE_2500BASEX:
480 asr_xgmac_set_sgmii_2500basex(plat_dat);
481 break;
482 case PHY_INTERFACE_MODE_USXGMII:
483 asr_xgmac_set_usxgmii(plat_dat);
484 break;
485 default:
486 pr_debug("SYSCFG init : Do not manage %d interface\n",
487 plat_dat->interface);
488 /* Do not manage others interfaces */
489 return -EINVAL;
490 }
491
492 return 0;
493}
494
495static void asr_xgmac_fix_mac_speed(void *priv, unsigned int speed)
496{
497 struct asr_dwmac *dwmac = priv;
498 struct plat_stmmacenet_data *plat_dat = dwmac->plat;
499
500 dwmac->speed = speed;
501 asr_xgmac_set_mode(plat_dat);
502}
503
504static void asr_dwmac_clk_disable(struct asr_dwmac *dwmac)
505{
506 if (dwmac->ops->clk_prepare)
507 dwmac->ops->clk_prepare(dwmac, false);
508}
509
510static int asr_dwmac_parse_data(struct asr_dwmac *dwmac,
511 struct device *dev)
512{
513 struct device_node *np = dev->of_node;
514 int err;
515
516 if (dwmac->ops->parse_data) {
517 err = dwmac->ops->parse_data(dwmac, dev);
518 if (err)
519 return err;
520 }
521
522 /* Get mode register */
523 dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "xgmac,phy");
524 if (IS_ERR(dwmac->regmap))
525 return PTR_ERR(dwmac->regmap);
526
527 err = of_property_read_u32_index(np, "xgmac,phy", 1, &dwmac->mode_reg);
528 if (err)
529 dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
530
531 return err;
532}
533
534static int asr_xgmac_parse_data(struct asr_dwmac *dwmac,
535 struct device *dev)
536{
537 struct device_node *np = dev->of_node;
538 u32 tx_delay_code, rx_delay_code;
539 u32 tx_delay_step, rx_delay_step;
540
541 dwmac->pinctrl = devm_pinctrl_get(dev);
542 if (IS_ERR(dwmac->pinctrl))
543 dev_err(dev, "could not get pinctrl handle\n");
544 else {
545 dwmac->rgmii_pins = pinctrl_lookup_state(dwmac->pinctrl, "rgmii");
546 if (IS_ERR(dwmac->rgmii_pins))
547 dev_err(dev, "could not get rgmii pinstate\n");
548 }
549
550 dwmac->clk_eth_ck = devm_clk_get(dev, "xgmac-clk");
551 if (IS_ERR(dwmac->clk_eth_ck)) {
552 dev_warn(dev, "No phy clock provided...\n");
553 dwmac->clk_eth_ck = NULL;
554 }
555
556 dwmac->phy_intr_disable =
557 of_property_read_bool(np, "xgmac,no-phy-intterrupt");
558 dwmac->rgmii_tx_clk_soc =
559 of_property_read_bool(np, "xgmac,rgmii-tx-clk-soc");
560 if (!of_property_read_u32(np, "xgmac,tx-delay", &tx_delay_code)) {
561 if (tx_delay_code < 255) {
562 dwmac->rgmii_tx_delay_code = tx_delay_code;
563 } else {
564 dev_err(dev, "Invalid TX clock delay: %dps\n",
565 tx_delay_code);
566 return -EINVAL;
567 }
568
569 if (!of_property_read_u32(np, "xgmac,tx-delay-step",
570 &tx_delay_step)) {
571 if (tx_delay_step < 4) {
572 dwmac->rgmii_tx_delay_step = tx_delay_step;
573 } else {
574 dev_err(dev, "Invalid TX delay step: %dps\n",
575 tx_delay_step);
576 return -EINVAL;
577 }
578 } else {
579 dwmac->rgmii_tx_delay_step = 0;
580 }
581 } else {
582 dwmac->rgmii_tx_delay_code = 0;
583 }
584
585 if (!of_property_read_u32(np, "xgmac,rx-delay", &rx_delay_code)) {
586 if (rx_delay_code < 255) {
587 dwmac->rgmii_rx_delay_code = rx_delay_code;
588 } else {
589 dev_err(dev, "Invalid RX clock delay: %dps\n", rx_delay_code);
590 return -EINVAL;
591 }
592 if (!of_property_read_u32(np, "xgmac,rx-delay-step",
593 &rx_delay_step)) {
594 if (rx_delay_step < 4) {
595 dwmac->rgmii_rx_delay_step = rx_delay_step;
596 } else {
597 dev_err(dev, "Invalid RX delay step: %dps\n",
598 rx_delay_step);
599 return -EINVAL;
600 }
601 } else {
602 dwmac->rgmii_rx_delay_step = 0;
603 }
604 } else {
605 dwmac->rgmii_rx_delay_code = 0;
606 }
607
608 return 0;
609}
610
611static int asr_dwmac_gpio_ctrl(struct asr_dwmac *dwmac,
612 struct device *dev)
613{
614 struct device_node *np = dev->of_node;
615 int rst_gpio, ldo_gpio, ldo_gpio2;
616 int low_active_rst;
617 u32 delays_rst[3];
618 int ret;
619
620 rst_gpio = of_get_named_gpio(np, "reset-gpio", 0);
621 if (rst_gpio >= 0) {
622 low_active_rst = of_property_read_bool(np, "reset-active-low");
623 of_property_read_u32_array(np, "reset-delays-us", delays_rst, 3);
624
625 ret = gpio_request(rst_gpio, "xgmac-reset");
626 if (ret < 0) {
627 printk("xgmac: reset-gpio=%d request failed ret=%d\n",
628 rst_gpio, ret);
629 return ret;
630 }
631 dwmac->rst_gpio = rst_gpio;
632 }
633
634 ldo_gpio = of_get_named_gpio(np, "3v3-ldo-gpio", 0);
635 if (ldo_gpio >= 0) {
636 ret = gpio_request(ldo_gpio, "xgmac-ldo-3v3");
637 if (ret < 0) {
638 printk("xgmac: xgmac-ldo-3v3=%d request failed ret=%d\n",
639 ldo_gpio, ret);
640 return ret;
641 }
642
643 dwmac->ldo_gpio = ldo_gpio;
644 gpio_direction_output(ldo_gpio, 1);
645 }
646
647 ldo_gpio2 = of_get_named_gpio(np, "0v95-ldo-gpio", 0);
648 if (ldo_gpio2 >= 0) {
649 ret = gpio_request(ldo_gpio2, "xgmac-ldo-0v95");
650 if (ret < 0) {
651 printk("xgmac: xgmac-ldo-0v95=%d request failed ret=%d\n",
652 ldo_gpio, ret);
653 return ret;
654 }
655
656 dwmac->ldo_gpio2 = ldo_gpio2;
657 gpio_direction_output(ldo_gpio2, 1);
658 }
659
660 /* reset */
661 if (delays_rst[0]) {
662 gpio_direction_output(rst_gpio, low_active_rst ? 1 : 0);
663 msleep(DIV_ROUND_UP(delays_rst[0], 1000));
664 }
665 gpio_direction_output(rst_gpio, low_active_rst ? 0 : 1);
666 if (delays_rst[1])
667 msleep(DIV_ROUND_UP(delays_rst[1], 1000));
668 gpio_direction_output(rst_gpio, low_active_rst ? 1 : 0);
669 if (delays_rst[2])
670 msleep(DIV_ROUND_UP(delays_rst[2], 1000));
671
672 dev_info(dev, "===> gpio init finished\n");
673 return 0;
674}
675
676static int asr_dwmac_probe(struct platform_device *pdev)
677{
678 struct plat_stmmacenet_data *plat_dat;
679 struct stmmac_resources stmmac_res;
680 struct asr_dwmac *dwmac;
681 const struct asr_xgmac_ops *data;
682 int ret;
683
684 ret = stmmac_get_platform_resources(pdev, &stmmac_res);
685 if (ret)
686 return ret;
687
688 plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
689 if (IS_ERR(plat_dat))
690 return PTR_ERR(plat_dat);
691
692 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
693 if (!dwmac) {
694 ret = -ENOMEM;
695 goto err_remove_config_dt;
696 }
697
698 data = of_device_get_match_data(&pdev->dev);
699 if (!data) {
700 dev_err(&pdev->dev, "no of match data provided\n");
701 ret = -EINVAL;
702 goto err_remove_config_dt;
703 }
704
705 dwmac->ops = data;
706 dwmac->dev = &pdev->dev;
707 dwmac->speed = SPEED_1000;
708
709 ret = asr_dwmac_parse_data(dwmac, &pdev->dev);
710 if (ret) {
711 dev_err(&pdev->dev, "Unable to parse OF data\n");
712 goto err_remove_config_dt;
713 }
714
715 plat_dat->bsp_priv = dwmac;
716 plat_dat->fix_mac_speed = asr_xgmac_fix_mac_speed;
717
718 ret = asr_dwmac_gpio_ctrl(dwmac, &pdev->dev);
719 if (ret)
720 return ret;
721
722 ret = asr_dwmac_init(plat_dat);
723 if (ret)
724 goto err_remove_config_dt;
725
726#ifdef STMMAC_DIS_SPH
727 plat_dat->sph_disable = 1;
728#endif
729
730 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
731 if (ret)
732 goto err_clk_disable;
733
734 return 0;
735
736err_clk_disable:
737 asr_dwmac_clk_disable(dwmac);
738err_remove_config_dt:
739 stmmac_remove_config_dt(pdev, plat_dat);
740
741 return ret;
742}
743
744static int asr_dwmac_remove(struct platform_device *pdev)
745{
746 struct net_device *ndev = platform_get_drvdata(pdev);
747 struct stmmac_priv *priv = netdev_priv(ndev);
748 int ret = stmmac_dvr_remove(&pdev->dev);
749
750 asr_dwmac_clk_disable(priv->plat->bsp_priv);
751 return ret;
752}
753
754static int asr_xgmac_suspend(struct asr_dwmac *dwmac)
755{
756 int ret = 0;
757
758 if (dwmac->clk_eth_ck)
759 clk_disable_unprepare(dwmac->clk_eth_ck);
760
761 return ret;
762}
763
764static void asr_xgmac_resume(struct asr_dwmac *dwmac)
765{
766 return;
767}
768
769#ifdef CONFIG_PM_SLEEP
770static int asr_dwmac_suspend(struct device *dev)
771{
772 struct net_device *ndev = dev_get_drvdata(dev);
773 struct stmmac_priv *priv = netdev_priv(ndev);
774 struct asr_dwmac *dwmac = priv->plat->bsp_priv;
775
776 int ret;
777
778 ret = stmmac_suspend(dev);
779
780 if (dwmac->ops->suspend)
781 ret = dwmac->ops->suspend(dwmac);
782
783 return ret;
784}
785
786static int asr_dwmac_resume(struct device *dev)
787{
788 struct net_device *ndev = dev_get_drvdata(dev);
789 struct stmmac_priv *priv = netdev_priv(ndev);
790 struct asr_dwmac *dwmac = priv->plat->bsp_priv;
791 int ret;
792
793 if (dwmac->ops->resume)
794 dwmac->ops->resume(dwmac);
795
796 ret = asr_dwmac_init(priv->plat);
797 if (ret)
798 return ret;
799
800 ret = stmmac_resume(dev);
801
802 return ret;
803}
804#endif /* CONFIG_PM_SLEEP */
805
806static SIMPLE_DEV_PM_OPS(asr_dwmac_pm_ops,
807 asr_dwmac_suspend, asr_dwmac_resume);
808
809static struct asr_xgmac_ops asr_xgmac_dwmac_data = {
810 .set_mode = asr_xgmac_set_mode,
811 .clk_prepare = asr_xgmac_clk_prepare,
812 .suspend = asr_xgmac_suspend,
813 .resume = asr_xgmac_resume,
814 .parse_data = asr_xgmac_parse_data,
815};
816
817static const struct of_device_id asr_dwmac_match[] = {
818 { .compatible = "asr,dwc-xgmac", .data = &asr_xgmac_dwmac_data},
819 { }
820};
821MODULE_DEVICE_TABLE(of, asr_dwmac_match);
822
823static struct platform_driver asr_dwmac_driver = {
824 .probe = asr_dwmac_probe,
825 .remove = asr_dwmac_remove,
826 .driver = {
827 .name = "asr-xgmac",
828 .pm = &asr_dwmac_pm_ops,
829 .of_match_table = asr_dwmac_match,
830 },
831};
832module_platform_driver(asr_dwmac_driver);
833
834MODULE_AUTHOR("Fei Lv <feilv@asrmicro.com>");
835MODULE_DESCRIPTION("ASR Microelectronics DWMAC Specific Glue layer");
836MODULE_LICENSE("GPL v2");