blob: 5d792ae1b5efa7ef0339d999f2f765da54c9b62a [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018-2019 MediaTek Inc.
3
4/* A library for MediaTek SGMII circuit
5 *
6 * Author: Sean Wang <sean.wang@mediatek.com>
7 *
8 */
9
10#include <linux/mfd/syscon.h>
11#include <linux/of.h>
12#include <linux/regmap.h>
13
14#include "mtk_eth_soc.h"
15
developer089e8852022-09-28 14:43:46 +080016int mtk_sgmii_init(struct mtk_xgmii *ss, struct device_node *r, u32 ana_rgc3)
developerfd40db22021-04-29 10:08:25 +080017{
18 struct device_node *np;
19 int i;
20
21 ss->ana_rgc3 = ana_rgc3;
22
23 for (i = 0; i < MTK_MAX_DEVS; i++) {
24 np = of_parse_phandle(r, "mediatek,sgmiisys", i);
25 if (!np)
26 break;
27
developer089e8852022-09-28 14:43:46 +080028 ss->regmap_sgmii[i] = syscon_node_to_regmap(np);
29 if (IS_ERR(ss->regmap_sgmii[i]))
30 return PTR_ERR(ss->regmap_sgmii[i]);
developerf8ac94a2021-07-29 16:40:01 +080031
32 ss->flags[i] &= ~(MTK_SGMII_PN_SWAP);
33 if (of_property_read_bool(np, "pn_swap"))
34 ss->flags[i] |= MTK_SGMII_PN_SWAP;
developerfd40db22021-04-29 10:08:25 +080035 }
36
37 return 0;
38}
39
developer024387a2022-12-07 22:18:27 +080040void mtk_sgmii_reset(struct mtk_xgmii *ss, int mac_id)
41{
42 struct mtk_eth *eth = ss->eth;
43 u32 id = mtk_mac2xgmii_id(eth, mac_id);
44 u32 val = 0;
45
46 if (id >= MTK_MAX_DEVS || !eth->toprgu)
47 return;
48
49 switch (mac_id) {
50 case MTK_GMAC2_ID:
51 /* Enable software reset */
52 regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
53 val |= SWSYSRST_XFI_PEXPT1_GRST |
54 SWSYSRST_SGMII1_GRST;
55 regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
56
57 /* Assert SGMII reset */
58 regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
59 val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
60 SWSYSRST_XFI_PEXPT1_GRST |
61 SWSYSRST_SGMII1_GRST;
62 regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
63
64 udelay(100);
65
66 /* De-assert SGMII reset */
67 regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
68 val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
69 val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
70 SWSYSRST_SGMII1_GRST);
71 regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
72
73 /* Disable software reset */
74 regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
75 val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
76 SWSYSRST_SGMII1_GRST);
77 regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
78 break;
79 case MTK_GMAC3_ID:
80 /* Enable Software reset */
81 regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
82 val |= SWSYSRST_XFI_PEXPT0_GRST |
83 SWSYSRST_SGMII0_GRST;
84 regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
85
86 /* Assert SGMII reset */
87 regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
88 val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
89 SWSYSRST_XFI_PEXPT0_GRST |
90 SWSYSRST_SGMII0_GRST;
91 regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
92
93 udelay(100);
94
95 /* De-assert SGMII reset */
96 regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
97 val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
98 val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
99 SWSYSRST_SGMII0_GRST);
100 regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
101
102 /* Disable software reset */
103 regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
104 val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
105 SWSYSRST_SGMII0_GRST);
106 regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
107 break;
108 }
109
110 mdelay(1);
111}
112
developer035d33e2023-02-09 22:24:46 +0800113int mtk_sgmii_need_powerdown(struct mtk_xgmii *ss, int id, int speed)
114{
115 u32 val;
116
117 /* need to power down sgmii if link down */
118 regmap_read(ss->regmap_sgmii[id], SGMSYS_PCS_CONTROL_1, &val);
119 if (!(val & SGMII_LINK_STATYS))
120 return true;
121
122 /* need to power down sgmii if link speed changed */
123 regmap_read(ss->regmap_sgmii[id], ss->ana_rgc3, &val);
124 if (speed == SPEED_2500) {
125 if (!(val & RG_PHY_SPEED_3_125G))
126 return true;
127 } else {
128 if (val & RG_PHY_SPEED_3_125G)
129 return true;
130 }
131
132 return false;
133}
134
developer089e8852022-09-28 14:43:46 +0800135void mtk_sgmii_setup_phya_gen1(struct mtk_xgmii *ss, int mac_id)
developerfd40db22021-04-29 10:08:25 +0800136{
developer089e8852022-09-28 14:43:46 +0800137 u32 id = mtk_mac2xgmii_id(ss->eth, mac_id);
138
developer543e7922022-12-01 11:24:47 +0800139 if (id >= MTK_MAX_DEVS ||
developer089e8852022-09-28 14:43:46 +0800140 !ss->regmap_sgmii[id] || !ss->regmap_pextp[id])
141 return;
142
143 regmap_update_bits(ss->regmap_pextp[id], 0x9024, GENMASK(31, 0), 0x00D9071C);
144 regmap_update_bits(ss->regmap_pextp[id], 0x2020, GENMASK(31, 0), 0xAA8585AA);
145 regmap_update_bits(ss->regmap_pextp[id], 0x2030, GENMASK(31, 0), 0x0C020207);
146 regmap_update_bits(ss->regmap_pextp[id], 0x2034, GENMASK(31, 0), 0x0E05050F);
147 regmap_update_bits(ss->regmap_pextp[id], 0x2040, GENMASK(31, 0), 0x00200032);
148 regmap_update_bits(ss->regmap_pextp[id], 0x50F0, GENMASK(31, 0), 0x00C014BA);
149 regmap_update_bits(ss->regmap_pextp[id], 0x50E0, GENMASK(31, 0), 0x3777C12B);
150 regmap_update_bits(ss->regmap_pextp[id], 0x506C, GENMASK(31, 0), 0x005F9CFF);
151 regmap_update_bits(ss->regmap_pextp[id], 0x5070, GENMASK(31, 0), 0x9D9DFAFA);
152 regmap_update_bits(ss->regmap_pextp[id], 0x5074, GENMASK(31, 0), 0x27273F3F);
153 regmap_update_bits(ss->regmap_pextp[id], 0x5078, GENMASK(31, 0), 0xA7883C68);
154 regmap_update_bits(ss->regmap_pextp[id], 0x507C, GENMASK(31, 0), 0x11661166);
155 regmap_update_bits(ss->regmap_pextp[id], 0x5080, GENMASK(31, 0), 0x0E000EAF);
156 regmap_update_bits(ss->regmap_pextp[id], 0x5084, GENMASK(31, 0), 0x08080E0D);
157 regmap_update_bits(ss->regmap_pextp[id], 0x5088, GENMASK(31, 0), 0x02030B09);
158 regmap_update_bits(ss->regmap_pextp[id], 0x50E4, GENMASK(31, 0), 0x0C0C0000);
159 regmap_update_bits(ss->regmap_pextp[id], 0x50E8, GENMASK(31, 0), 0x04040000);
160 regmap_update_bits(ss->regmap_pextp[id], 0x50EC, GENMASK(31, 0), 0x0F0F0606);
161 regmap_update_bits(ss->regmap_pextp[id], 0x50A8, GENMASK(31, 0), 0x506E8C8C);
162 regmap_update_bits(ss->regmap_pextp[id], 0x6004, GENMASK(31, 0), 0x18190000);
163 regmap_update_bits(ss->regmap_pextp[id], 0x00F8, GENMASK(31, 0), 0x00FA32FA);
164 regmap_update_bits(ss->regmap_pextp[id], 0x00F4, GENMASK(31, 0), 0x80201F21);
165 regmap_update_bits(ss->regmap_pextp[id], 0x0030, GENMASK(31, 0), 0x00050C00);
166 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x02002800);
167 ndelay(1020);
168 regmap_update_bits(ss->regmap_pextp[id], 0x30B0, GENMASK(31, 0), 0x00000020);
169 regmap_update_bits(ss->regmap_pextp[id], 0x3028, GENMASK(31, 0), 0x00008A01);
170 regmap_update_bits(ss->regmap_pextp[id], 0x302C, GENMASK(31, 0), 0x0000A884);
171 regmap_update_bits(ss->regmap_pextp[id], 0x3024, GENMASK(31, 0), 0x00083002);
172 regmap_update_bits(ss->regmap_pextp[id], 0x3010, GENMASK(31, 0), 0x00011110);
173 regmap_update_bits(ss->regmap_pextp[id], 0x3048, GENMASK(31, 0), 0x40704000);
174 regmap_update_bits(ss->regmap_pextp[id], 0x3064, GENMASK(31, 0), 0x0000C000);
175 regmap_update_bits(ss->regmap_pextp[id], 0x3050, GENMASK(31, 0), 0xA8000000);
176 regmap_update_bits(ss->regmap_pextp[id], 0x3054, GENMASK(31, 0), 0x000000AA);
177 regmap_update_bits(ss->regmap_pextp[id], 0x306C, GENMASK(31, 0), 0x20200F00);
178 regmap_update_bits(ss->regmap_pextp[id], 0xA060, GENMASK(31, 0), 0x00050000);
179 regmap_update_bits(ss->regmap_pextp[id], 0x90D0, GENMASK(31, 0), 0x00000007);
180 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0200E800);
181 udelay(150);
182 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0200C111);
183 ndelay(1020);
184 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0200C101);
185 udelay(15);
186 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0201C111);
187 ndelay(1020);
188 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0201C101);
189 udelay(100);
190 regmap_update_bits(ss->regmap_pextp[id], 0x30B0, GENMASK(31, 0), 0x00000030);
191 regmap_update_bits(ss->regmap_pextp[id], 0x00F4, GENMASK(31, 0), 0x80201F01);
192 regmap_update_bits(ss->regmap_pextp[id], 0x3040, GENMASK(31, 0), 0x30000000);
193 udelay(400);
194}
195
196void mtk_sgmii_setup_phya_gen2(struct mtk_xgmii *ss, int mac_id)
197{
198 u32 id = mtk_mac2xgmii_id(ss->eth, mac_id);
199
developer8b6f2402022-11-28 13:42:34 +0800200 if (id >= MTK_MAX_DEVS ||
developer089e8852022-09-28 14:43:46 +0800201 !ss->regmap_sgmii[id] || !ss->regmap_pextp[id])
202 return;
203
204 regmap_update_bits(ss->regmap_pextp[id], 0x9024, GENMASK(31, 0), 0x00D9071C);
205 regmap_update_bits(ss->regmap_pextp[id], 0x2020, GENMASK(31, 0), 0xAA8585AA);
206 regmap_update_bits(ss->regmap_pextp[id], 0x2030, GENMASK(31, 0), 0x0C020707);
207 regmap_update_bits(ss->regmap_pextp[id], 0x2034, GENMASK(31, 0), 0x0E050F0F);
208 regmap_update_bits(ss->regmap_pextp[id], 0x2040, GENMASK(31, 0), 0x00140032);
209 regmap_update_bits(ss->regmap_pextp[id], 0x50F0, GENMASK(31, 0), 0x00C014AA);
210 regmap_update_bits(ss->regmap_pextp[id], 0x50E0, GENMASK(31, 0), 0x3777C12B);
211 regmap_update_bits(ss->regmap_pextp[id], 0x506C, GENMASK(31, 0), 0x005F9CFF);
212 regmap_update_bits(ss->regmap_pextp[id], 0x5070, GENMASK(31, 0), 0x9D9DFAFA);
213 regmap_update_bits(ss->regmap_pextp[id], 0x5074, GENMASK(31, 0), 0x27273F3F);
214 regmap_update_bits(ss->regmap_pextp[id], 0x5078, GENMASK(31, 0), 0xA7883C68);
215 regmap_update_bits(ss->regmap_pextp[id], 0x507C, GENMASK(31, 0), 0x11661166);
216 regmap_update_bits(ss->regmap_pextp[id], 0x5080, GENMASK(31, 0), 0x0E000AAF);
217 regmap_update_bits(ss->regmap_pextp[id], 0x5084, GENMASK(31, 0), 0x08080D0D);
218 regmap_update_bits(ss->regmap_pextp[id], 0x5088, GENMASK(31, 0), 0x02030909);
219 regmap_update_bits(ss->regmap_pextp[id], 0x50E4, GENMASK(31, 0), 0x0C0C0000);
220 regmap_update_bits(ss->regmap_pextp[id], 0x50E8, GENMASK(31, 0), 0x04040000);
221 regmap_update_bits(ss->regmap_pextp[id], 0x50EC, GENMASK(31, 0), 0x0F0F0C06);
222 regmap_update_bits(ss->regmap_pextp[id], 0x50A8, GENMASK(31, 0), 0x506E8C8C);
223 regmap_update_bits(ss->regmap_pextp[id], 0x6004, GENMASK(31, 0), 0x18190000);
224 regmap_update_bits(ss->regmap_pextp[id], 0x00F8, GENMASK(31, 0), 0x009C329C);
225 regmap_update_bits(ss->regmap_pextp[id], 0x00F4, GENMASK(31, 0), 0x80201F21);
226 regmap_update_bits(ss->regmap_pextp[id], 0x0030, GENMASK(31, 0), 0x00050C00);
227 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x02002800);
228 ndelay(1020);
229 regmap_update_bits(ss->regmap_pextp[id], 0x30B0, GENMASK(31, 0), 0x00000020);
230 regmap_update_bits(ss->regmap_pextp[id], 0x3028, GENMASK(31, 0), 0x00008A01);
231 regmap_update_bits(ss->regmap_pextp[id], 0x302C, GENMASK(31, 0), 0x0000A884);
232 regmap_update_bits(ss->regmap_pextp[id], 0x3024, GENMASK(31, 0), 0x00083002);
233 regmap_update_bits(ss->regmap_pextp[id], 0x3010, GENMASK(31, 0), 0x00011110);
234 regmap_update_bits(ss->regmap_pextp[id], 0x3048, GENMASK(31, 0), 0x40704000);
235 regmap_update_bits(ss->regmap_pextp[id], 0x3050, GENMASK(31, 0), 0xA8000000);
236 regmap_update_bits(ss->regmap_pextp[id], 0x3054, GENMASK(31, 0), 0x000000AA);
237 regmap_update_bits(ss->regmap_pextp[id], 0x306C, GENMASK(31, 0), 0x22000F00);
238 regmap_update_bits(ss->regmap_pextp[id], 0xA060, GENMASK(31, 0), 0x00050000);
239 regmap_update_bits(ss->regmap_pextp[id], 0x90D0, GENMASK(31, 0), 0x00000005);
240 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0200E800);
241 udelay(150);
242 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0200C111);
243 ndelay(1020);
244 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0200C101);
245 udelay(15);
246 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0201C111);
247 ndelay(1020);
248 regmap_update_bits(ss->regmap_pextp[id], 0x0070, GENMASK(31, 0), 0x0201C101);
249 udelay(100);
250 regmap_update_bits(ss->regmap_pextp[id], 0x30B0, GENMASK(31, 0), 0x00000030);
251 regmap_update_bits(ss->regmap_pextp[id], 0x00F4, GENMASK(31, 0), 0x80201F01);
252 regmap_update_bits(ss->regmap_pextp[id], 0x3040, GENMASK(31, 0), 0x30000000);
253 udelay(400);
254}
255
256int mtk_sgmii_setup_mode_an(struct mtk_xgmii *ss, unsigned int mac_id)
257{
258 struct mtk_eth *eth = ss->eth;
developer543e7922022-12-01 11:24:47 +0800259 unsigned int val = 0;
developer089e8852022-09-28 14:43:46 +0800260 u32 id = mtk_mac2xgmii_id(ss->eth, mac_id);
developerfd40db22021-04-29 10:08:25 +0800261
developer089e8852022-09-28 14:43:46 +0800262 if (!ss->regmap_sgmii[id])
developerfd40db22021-04-29 10:08:25 +0800263 return -EINVAL;
264
developer024387a2022-12-07 22:18:27 +0800265 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
developer089e8852022-09-28 14:43:46 +0800266 mtk_xfi_pll_enable(ss);
developer024387a2022-12-07 22:18:27 +0800267 mtk_sgmii_reset(ss, mac_id);
268 }
developer089e8852022-09-28 14:43:46 +0800269
developer035d33e2023-02-09 22:24:46 +0800270 /* Assert PHYA power down state when needed */
271 if (mtk_sgmii_need_powerdown(ss, id, SPEED_1000))
272 regmap_write(ss->regmap_sgmii[id], SGMSYS_QPHY_PWR_STATE_CTRL,
273 SGMII_PHYA_PWD);
developer2fbee452022-08-12 13:58:20 +0800274
developer2b76a9d2022-09-20 14:59:45 +0800275 /* Reset SGMII PCS state */
developer089e8852022-09-28 14:43:46 +0800276 regmap_write(ss->regmap_sgmii[id], SGMII_RESERVED_0, SGMII_SW_RESET);
developer2b76a9d2022-09-20 14:59:45 +0800277
developer089e8852022-09-28 14:43:46 +0800278 regmap_read(ss->regmap_sgmii[id], ss->ana_rgc3, &val);
developer2fbee452022-08-12 13:58:20 +0800279 val &= ~RG_PHY_SPEED_3_125G;
developer089e8852022-09-28 14:43:46 +0800280 regmap_write(ss->regmap_sgmii[id], ss->ana_rgc3, val);
developer2fbee452022-08-12 13:58:20 +0800281
developerfd40db22021-04-29 10:08:25 +0800282 /* Setup the link timer and QPHY power up inside SGMIISYS */
developer089e8852022-09-28 14:43:46 +0800283 regmap_write(ss->regmap_sgmii[id], SGMSYS_PCS_LINK_TIMER,
developerfd40db22021-04-29 10:08:25 +0800284 SGMII_LINK_TIMER_DEFAULT);
285
developer089e8852022-09-28 14:43:46 +0800286 regmap_read(ss->regmap_sgmii[id], SGMSYS_SGMII_MODE, &val);
developerfd40db22021-04-29 10:08:25 +0800287 val |= SGMII_REMOTE_FAULT_DIS;
developer089e8852022-09-28 14:43:46 +0800288 regmap_write(ss->regmap_sgmii[id], SGMSYS_SGMII_MODE, val);
developerfd40db22021-04-29 10:08:25 +0800289
developer2fbee452022-08-12 13:58:20 +0800290 /* SGMII AN mode setting */
developer089e8852022-09-28 14:43:46 +0800291 regmap_read(ss->regmap_sgmii[id], SGMSYS_SGMII_MODE, &val);
developer2fbee452022-08-12 13:58:20 +0800292 val &= ~SGMII_IF_MODE_MASK;
293 val |= SGMII_SPEED_DUPLEX_AN;
developer089e8852022-09-28 14:43:46 +0800294 regmap_write(ss->regmap_sgmii[id], SGMSYS_SGMII_MODE, val);
developer2fbee452022-08-12 13:58:20 +0800295
developer089e8852022-09-28 14:43:46 +0800296 /* Enable SGMII AN */
297 regmap_read(ss->regmap_sgmii[id], SGMSYS_PCS_CONTROL_1, &val);
developer2fbee452022-08-12 13:58:20 +0800298 val |= SGMII_AN_ENABLE;
developer089e8852022-09-28 14:43:46 +0800299 regmap_write(ss->regmap_sgmii[id], SGMSYS_PCS_CONTROL_1, val);
developerfd40db22021-04-29 10:08:25 +0800300
developerf8ac94a2021-07-29 16:40:01 +0800301 if(MTK_HAS_FLAGS(ss->flags[id],MTK_SGMII_PN_SWAP))
developer089e8852022-09-28 14:43:46 +0800302 regmap_update_bits(ss->regmap_sgmii[id], SGMSYS_QPHY_WRAP_CTRL,
developerf8ac94a2021-07-29 16:40:01 +0800303 SGMII_PN_SWAP_MASK, SGMII_PN_SWAP_TX_RX);
304
developer3d014da2022-05-11 16:29:59 +0800305 /* Release PHYA power down state */
developer089e8852022-09-28 14:43:46 +0800306 regmap_write(ss->regmap_sgmii[id], SGMSYS_QPHY_PWR_STATE_CTRL, 0);
307
308 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
309 mtk_sgmii_setup_phya_gen1(ss, mac_id);
developerfd40db22021-04-29 10:08:25 +0800310
311 return 0;
312}
313
developer089e8852022-09-28 14:43:46 +0800314int mtk_sgmii_setup_mode_force(struct mtk_xgmii *ss, unsigned int mac_id,
developerfd40db22021-04-29 10:08:25 +0800315 const struct phylink_link_state *state)
316{
developer089e8852022-09-28 14:43:46 +0800317 struct mtk_eth *eth = ss->eth;
developer543e7922022-12-01 11:24:47 +0800318 unsigned int val = 0;
developer089e8852022-09-28 14:43:46 +0800319 u32 id = mtk_mac2xgmii_id(eth, mac_id);
developerfd40db22021-04-29 10:08:25 +0800320
developer089e8852022-09-28 14:43:46 +0800321 if (!ss->regmap_sgmii[id])
developerfd40db22021-04-29 10:08:25 +0800322 return -EINVAL;
323
developer024387a2022-12-07 22:18:27 +0800324 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
developer089e8852022-09-28 14:43:46 +0800325 mtk_xfi_pll_enable(ss);
developer024387a2022-12-07 22:18:27 +0800326 mtk_sgmii_reset(ss, mac_id);
327 }
developer089e8852022-09-28 14:43:46 +0800328
developer035d33e2023-02-09 22:24:46 +0800329 /* Assert PHYA power down state when needed */
330 if (mtk_sgmii_need_powerdown(ss, id, state->speed))
331 regmap_write(ss->regmap_sgmii[id], SGMSYS_QPHY_PWR_STATE_CTRL,
332 SGMII_PHYA_PWD);
developer2fbee452022-08-12 13:58:20 +0800333
developer2b76a9d2022-09-20 14:59:45 +0800334 /* Reset SGMII PCS state */
developer089e8852022-09-28 14:43:46 +0800335 regmap_write(ss->regmap_sgmii[id], SGMII_RESERVED_0, SGMII_SW_RESET);
developer2b76a9d2022-09-20 14:59:45 +0800336
developer089e8852022-09-28 14:43:46 +0800337 regmap_read(ss->regmap_sgmii[id], ss->ana_rgc3, &val);
developerfd40db22021-04-29 10:08:25 +0800338 val &= ~RG_PHY_SPEED_MASK;
339 if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
340 val |= RG_PHY_SPEED_3_125G;
developer089e8852022-09-28 14:43:46 +0800341 regmap_write(ss->regmap_sgmii[id], ss->ana_rgc3, val);
developerfd40db22021-04-29 10:08:25 +0800342
343 /* Disable SGMII AN */
developer089e8852022-09-28 14:43:46 +0800344 regmap_read(ss->regmap_sgmii[id], SGMSYS_PCS_CONTROL_1, &val);
developerfd40db22021-04-29 10:08:25 +0800345 val &= ~SGMII_AN_ENABLE;
developer089e8852022-09-28 14:43:46 +0800346 regmap_write(ss->regmap_sgmii[id], SGMSYS_PCS_CONTROL_1, val);
developerfd40db22021-04-29 10:08:25 +0800347
348 /* SGMII force mode setting */
developer089e8852022-09-28 14:43:46 +0800349 regmap_read(ss->regmap_sgmii[id], SGMSYS_SGMII_MODE, &val);
developerfd40db22021-04-29 10:08:25 +0800350 val &= ~SGMII_IF_MODE_MASK;
developer2b76a9d2022-09-20 14:59:45 +0800351 val &= ~SGMII_REMOTE_FAULT_DIS;
developerfd40db22021-04-29 10:08:25 +0800352
353 switch (state->speed) {
354 case SPEED_10:
355 val |= SGMII_SPEED_10;
356 break;
357 case SPEED_100:
358 val |= SGMII_SPEED_100;
359 break;
360 case SPEED_2500:
361 case SPEED_1000:
developer089e8852022-09-28 14:43:46 +0800362 default:
developerfd40db22021-04-29 10:08:25 +0800363 val |= SGMII_SPEED_1000;
364 break;
365 };
366
developer2b76a9d2022-09-20 14:59:45 +0800367 /* SGMII 1G and 2.5G force mode can only work in full duplex
368 * mode, no matter SGMII_FORCE_HALF_DUPLEX is set or not.
369 */
370 if (state->duplex != DUPLEX_FULL)
developerfd40db22021-04-29 10:08:25 +0800371 val |= SGMII_DUPLEX_FULL;
372
developer089e8852022-09-28 14:43:46 +0800373 regmap_write(ss->regmap_sgmii[id], SGMSYS_SGMII_MODE, val);
developerfd40db22021-04-29 10:08:25 +0800374
developerf8ac94a2021-07-29 16:40:01 +0800375 if(MTK_HAS_FLAGS(ss->flags[id],MTK_SGMII_PN_SWAP))
developer089e8852022-09-28 14:43:46 +0800376 regmap_update_bits(ss->regmap_sgmii[id], SGMSYS_QPHY_WRAP_CTRL,
developerf8ac94a2021-07-29 16:40:01 +0800377 SGMII_PN_SWAP_MASK, SGMII_PN_SWAP_TX_RX);
developer3d014da2022-05-11 16:29:59 +0800378
developerfd40db22021-04-29 10:08:25 +0800379 /* Release PHYA power down state */
developer089e8852022-09-28 14:43:46 +0800380 regmap_write(ss->regmap_sgmii[id], SGMSYS_QPHY_PWR_STATE_CTRL, 0);
381
382 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
383 mtk_sgmii_setup_phya_gen2(ss, mac_id);
developerfd40db22021-04-29 10:08:25 +0800384
385 return 0;
386}
387
388void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
389{
developer089e8852022-09-28 14:43:46 +0800390 struct mtk_xgmii *ss = eth->xgmii;
developer543e7922022-12-01 11:24:47 +0800391 unsigned int val = 0, sid = mtk_mac2xgmii_id(eth, mac_id);
developerfd40db22021-04-29 10:08:25 +0800392
393 /* Decide how GMAC and SGMIISYS be mapped */
394 sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
developer089e8852022-09-28 14:43:46 +0800395 0 : sid;
developerfd40db22021-04-29 10:08:25 +0800396
developer089e8852022-09-28 14:43:46 +0800397 if (!ss->regmap_sgmii[sid])
developerfd40db22021-04-29 10:08:25 +0800398 return;
399
developer089e8852022-09-28 14:43:46 +0800400 regmap_read(ss->regmap_sgmii[sid], SGMSYS_PCS_CONTROL_1, &val);
developerfd40db22021-04-29 10:08:25 +0800401 val |= SGMII_AN_RESTART;
developer089e8852022-09-28 14:43:46 +0800402 regmap_write(ss->regmap_sgmii[sid], SGMSYS_PCS_CONTROL_1, val);
developerfd40db22021-04-29 10:08:25 +0800403}