blob: 25a98e0f93577a5b77c4b4b4f216e806595a4794 [file] [log] [blame]
developer7efa6382025-01-10 16:41:24 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2025 MediaTek Inc.
4 *
5 * Author: Neal Yen <neal.yen@mediatek.com>
6 * Author: Weijie Gao <weijie.gao@mediatek.com>
7 */
8
9#include <phy.h>
10#include <miiphy.h>
11#include <linux/bitops.h>
12#include <linux/delay.h>
13#include <linux/mdio.h>
14#include <linux/mii.h>
15#include "mtk_eth.h"
16
17/* AN8855 Register Definitions */
18#define AN8855_SYS_CTRL_REG 0x100050c0
19#define AN8855_SW_SYS_RST BIT(31)
20
21#define AN8855_PMCR_REG(p) (0x10210000 + (p) * 0x200)
22#define AN8855_FORCE_MODE_LNK BIT(31)
23#define AN8855_FORCE_MODE 0xb31593f0
24
developer10c0aae2025-01-24 16:04:28 +080025#define AN8855_PORT_CTRL_BASE 0x10208000
developer7efa6382025-01-10 16:41:24 +080026#define AN8855_PORT_CTRL_REG(p, r) (AN8855_PORT_CTRL_BASE + (p) * 0x200 + (r))
27
28#define AN8855_PORTMATRIX_REG(p) AN8855_PORT_CTRL_REG(p, 0x44)
29
30#define AN8855_PVC(p) AN8855_PORT_CTRL_REG(p, 0x10)
31#define AN8855_STAG_VPID_S 16
32#define AN8855_STAG_VPID_M 0xffff0000
33#define AN8855_VLAN_ATTR_S 6
34#define AN8855_VLAN_ATTR_M 0xc0
35
36#define VLAN_ATTR_USER 0
37
38#define AN8855_INT_MASK 0x100050F0
39#define AN8855_INT_SYS_BIT BIT(15)
40
41#define AN8855_RG_CLK_CPU_ICG 0x10005034
42#define AN8855_MCU_ENABLE BIT(3)
43
44#define AN8855_RG_TIMER_CTL 0x1000a100
45#define AN8855_WDOG_ENABLE BIT(25)
46
47#define AN8855_CKGCR 0x10213e1c
48
developer10c0aae2025-01-24 16:04:28 +080049#define AN8855_SCU_BASE 0x10000000
developer7efa6382025-01-10 16:41:24 +080050#define AN8855_RG_RGMII_TXCK_C (AN8855_SCU_BASE + 0x1d0)
51#define AN8855_RG_GPIO_LED_MODE (AN8855_SCU_BASE + 0x0054)
52#define AN8855_RG_GPIO_LED_SEL(i) (AN8855_SCU_BASE + (0x0058 + ((i) * 4)))
53#define AN8855_RG_INTB_MODE (AN8855_SCU_BASE + 0x0080)
54#define AN8855_RG_GDMP_RAM (AN8855_SCU_BASE + 0x10000)
55#define AN8855_RG_GPIO_L_INV (AN8855_SCU_BASE + 0x0010)
56#define AN8855_RG_GPIO_CTRL (AN8855_SCU_BASE + 0xa300)
57#define AN8855_RG_GPIO_DATA (AN8855_SCU_BASE + 0xa304)
58#define AN8855_RG_GPIO_OE (AN8855_SCU_BASE + 0xa314)
59
60#define AN8855_HSGMII_AN_CSR_BASE 0x10220000
61#define AN8855_SGMII_REG_AN0 (AN8855_HSGMII_AN_CSR_BASE + 0x000)
62#define AN8855_SGMII_REG_AN_13 (AN8855_HSGMII_AN_CSR_BASE + 0x034)
63#define AN8855_SGMII_REG_AN_FORCE_CL37 (AN8855_HSGMII_AN_CSR_BASE + 0x060)
64
65#define AN8855_HSGMII_CSR_PCS_BASE 0x10220000
66#define AN8855_RG_HSGMII_PCS_CTROL_1 (AN8855_HSGMII_CSR_PCS_BASE + 0xa00)
67#define AN8855_RG_AN_SGMII_MODE_FORCE (AN8855_HSGMII_CSR_PCS_BASE + 0xa24)
68
developer10c0aae2025-01-24 16:04:28 +080069#define AN8855_MULTI_SGMII_CSR_BASE 0x10224000
70#define AN8855_SGMII_STS_CTRL_0 (AN8855_MULTI_SGMII_CSR_BASE + 0x018)
developer7efa6382025-01-10 16:41:24 +080071#define AN8855_MSG_RX_CTRL_0 (AN8855_MULTI_SGMII_CSR_BASE + 0x100)
developer10c0aae2025-01-24 16:04:28 +080072#define AN8855_MSG_RX_LIK_STS_0 (AN8855_MULTI_SGMII_CSR_BASE + 0x514)
73#define AN8855_MSG_RX_LIK_STS_2 (AN8855_MULTI_SGMII_CSR_BASE + 0x51c)
developer7efa6382025-01-10 16:41:24 +080074#define AN8855_PHY_RX_FORCE_CTRL_0 (AN8855_MULTI_SGMII_CSR_BASE + 0x520)
75
developer10c0aae2025-01-24 16:04:28 +080076#define AN8855_XFI_CSR_PCS_BASE 0x10225000
developer7efa6382025-01-10 16:41:24 +080077#define AN8855_RG_USXGMII_AN_CONTROL_0 (AN8855_XFI_CSR_PCS_BASE + 0xbf8)
78
79#define AN8855_MULTI_PHY_RA_CSR_BASE 0x10226000
developer10c0aae2025-01-24 16:04:28 +080080#define AN8855_RG_RATE_ADAPT_CTRL_0 (AN8855_MULTI_PHY_RA_CSR_BASE + 0x000)
developer7efa6382025-01-10 16:41:24 +080081#define AN8855_RATE_ADP_P0_CTRL_0 (AN8855_MULTI_PHY_RA_CSR_BASE + 0x100)
developer10c0aae2025-01-24 16:04:28 +080082#define AN8855_MII_RA_AN_ENABLE (AN8855_MULTI_PHY_RA_CSR_BASE + 0x300)
developer7efa6382025-01-10 16:41:24 +080083
84#define AN8855_QP_DIG_CSR_BASE 0x1022a000
developer10c0aae2025-01-24 16:04:28 +080085#define AN8855_QP_CK_RST_CTRL_4 (AN8855_QP_DIG_CSR_BASE + 0x310)
developer7efa6382025-01-10 16:41:24 +080086#define AN8855_QP_DIG_MODE_CTRL_0 (AN8855_QP_DIG_CSR_BASE + 0x324)
87#define AN8855_QP_DIG_MODE_CTRL_1 (AN8855_QP_DIG_CSR_BASE + 0x330)
88
89#define AN8855_QP_PMA_TOP_BASE 0x1022e000
90#define AN8855_PON_RXFEDIG_CTRL_0 (AN8855_QP_PMA_TOP_BASE + 0x100)
91#define AN8855_PON_RXFEDIG_CTRL_9 (AN8855_QP_PMA_TOP_BASE + 0x124)
92
developer10c0aae2025-01-24 16:04:28 +080093#define AN8855_SS_LCPLL_PWCTL_SETTING_2 (AN8855_QP_PMA_TOP_BASE + 0x208)
developer7efa6382025-01-10 16:41:24 +080094#define AN8855_SS_LCPLL_TDC_FLT_2 (AN8855_QP_PMA_TOP_BASE + 0x230)
95#define AN8855_SS_LCPLL_TDC_FLT_5 (AN8855_QP_PMA_TOP_BASE + 0x23c)
96#define AN8855_SS_LCPLL_TDC_PCW_1 (AN8855_QP_PMA_TOP_BASE + 0x248)
97#define AN8855_INTF_CTRL_8 (AN8855_QP_PMA_TOP_BASE + 0x320)
98#define AN8855_INTF_CTRL_9 (AN8855_QP_PMA_TOP_BASE + 0x324)
99#define AN8855_PLL_CTRL_0 (AN8855_QP_PMA_TOP_BASE + 0x400)
100#define AN8855_PLL_CTRL_2 (AN8855_QP_PMA_TOP_BASE + 0x408)
101#define AN8855_PLL_CTRL_3 (AN8855_QP_PMA_TOP_BASE + 0x40c)
102#define AN8855_PLL_CTRL_4 (AN8855_QP_PMA_TOP_BASE + 0x410)
103#define AN8855_PLL_CK_CTRL_0 (AN8855_QP_PMA_TOP_BASE + 0x414)
developer10c0aae2025-01-24 16:04:28 +0800104#define AN8855_RX_DLY_0 (AN8855_QP_PMA_TOP_BASE + 0x614)
developer7efa6382025-01-10 16:41:24 +0800105#define AN8855_RX_CTRL_2 (AN8855_QP_PMA_TOP_BASE + 0x630)
106#define AN8855_RX_CTRL_5 (AN8855_QP_PMA_TOP_BASE + 0x63c)
107#define AN8855_RX_CTRL_6 (AN8855_QP_PMA_TOP_BASE + 0x640)
108#define AN8855_RX_CTRL_7 (AN8855_QP_PMA_TOP_BASE + 0x644)
109#define AN8855_RX_CTRL_8 (AN8855_QP_PMA_TOP_BASE + 0x648)
110#define AN8855_RX_CTRL_26 (AN8855_QP_PMA_TOP_BASE + 0x690)
111#define AN8855_RX_CTRL_42 (AN8855_QP_PMA_TOP_BASE + 0x6d0)
112
113#define AN8855_QP_ANA_CSR_BASE 0x1022f000
114#define AN8855_RG_QP_RX_DAC_EN (AN8855_QP_ANA_CSR_BASE + 0x00)
115#define AN8855_RG_QP_RXAFE_RESERVE (AN8855_QP_ANA_CSR_BASE + 0x04)
116#define AN8855_RG_QP_CDR_LPF_MJV_LIM (AN8855_QP_ANA_CSR_BASE + 0x0c)
117#define AN8855_RG_QP_CDR_LPF_SETVALUE (AN8855_QP_ANA_CSR_BASE + 0x14)
118#define AN8855_RG_QP_CDR_PR_CKREF_DIV1 (AN8855_QP_ANA_CSR_BASE + 0x18)
119#define AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE (AN8855_QP_ANA_CSR_BASE + 0x1c)
120#define AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF (AN8855_QP_ANA_CSR_BASE + 0x20)
developer10c0aae2025-01-24 16:04:28 +0800121#define AN8855_RG_QP_TX_MODE_16B_EN (AN8855_QP_ANA_CSR_BASE + 0x28)
developer7efa6382025-01-10 16:41:24 +0800122#define AN8855_RG_QP_PLL_IPLL_DIG_PWR_SEL (AN8855_QP_ANA_CSR_BASE + 0x3c)
123#define AN8855_RG_QP_PLL_SDM_ORD (AN8855_QP_ANA_CSR_BASE + 0x40)
124
125#define AN8855_ETHER_SYS_BASE 0x1028c800
126#define RG_GPHY_AFE_PWD (AN8855_ETHER_SYS_BASE + 0x40)
127
128#define AN8855_PKG_SEL 0x10000094
129#define PAG_SEL_AN8855H 0x2
130
131/* PHY LED Register bitmap of define */
132#define PHY_LED_CTRL_SELECT 0x3e8
133#define PHY_SINGLE_LED_ON_CTRL(i) (0x3e0 + ((i) * 2))
134#define PHY_SINGLE_LED_BLK_CTRL(i) (0x3e1 + ((i) * 2))
135#define PHY_SINGLE_LED_ON_DUR(i) (0x3e9 + ((i) * 2))
136#define PHY_SINGLE_LED_BLK_DUR(i) (0x3ea + ((i) * 2))
137
developer10c0aae2025-01-24 16:04:28 +0800138#define PHY_PMA_CTRL 0x340
developer7efa6382025-01-10 16:41:24 +0800139
140#define PHY_DEV1F 0x1f
141
142#define PHY_LED_ON_CTRL(i) (0x24 + ((i) * 2))
developer10c0aae2025-01-24 16:04:28 +0800143#define LED_ON_EN BIT(15)
144#define LED_ON_POL BIT(14)
145#define LED_ON_EVT_MASK 0x7f
developer7efa6382025-01-10 16:41:24 +0800146
147/* LED ON Event */
developer10c0aae2025-01-24 16:04:28 +0800148#define LED_ON_EVT_FORCE BIT(6)
149#define LED_ON_EVT_LINK_HD BIT(5)
150#define LED_ON_EVT_LINK_FD BIT(4)
151#define LED_ON_EVT_LINK_DOWN BIT(3)
152#define LED_ON_EVT_LINK_10M BIT(2)
153#define LED_ON_EVT_LINK_100M BIT(1)
154#define LED_ON_EVT_LINK_1000M BIT(0)
developer7efa6382025-01-10 16:41:24 +0800155
156#define PHY_LED_BLK_CTRL(i) (0x25 + ((i) * 2))
developer10c0aae2025-01-24 16:04:28 +0800157#define LED_BLK_EVT_MASK 0x3ff
developer7efa6382025-01-10 16:41:24 +0800158/* LED Blinking Event */
developer10c0aae2025-01-24 16:04:28 +0800159#define LED_BLK_EVT_FORCE BIT(9)
160#define LED_BLK_EVT_10M_RX_ACT BIT(5)
161#define LED_BLK_EVT_10M_TX_ACT BIT(4)
162#define LED_BLK_EVT_100M_RX_ACT BIT(3)
163#define LED_BLK_EVT_100M_TX_ACT BIT(2)
164#define LED_BLK_EVT_1000M_RX_ACT BIT(1)
165#define LED_BLK_EVT_1000M_TX_ACT BIT(0)
developer7efa6382025-01-10 16:41:24 +0800166
167#define PHY_LED_BCR (0x21)
developer10c0aae2025-01-24 16:04:28 +0800168#define LED_BCR_EXT_CTRL BIT(15)
169#define LED_BCR_CLK_EN BIT(3)
170#define LED_BCR_TIME_TEST BIT(2)
171#define LED_BCR_MODE_MASK 3
172#define LED_BCR_MODE_DISABLE 0
developer7efa6382025-01-10 16:41:24 +0800173
developer10c0aae2025-01-24 16:04:28 +0800174#define PHY_LED_ON_DUR 0x22
175#define LED_ON_DUR_MASK 0xffff
developer7efa6382025-01-10 16:41:24 +0800176
developer10c0aae2025-01-24 16:04:28 +0800177#define PHY_LED_BLK_DUR 0x23
178#define LED_BLK_DUR_MASK 0xffff
developer7efa6382025-01-10 16:41:24 +0800179
developer10c0aae2025-01-24 16:04:28 +0800180#define PHY_LED_BLINK_DUR_CTRL 0x720
developer7efa6382025-01-10 16:41:24 +0800181
182/* Definition of LED */
183#define LED_ON_EVENT (LED_ON_EVT_LINK_1000M | \
184 LED_ON_EVT_LINK_100M | LED_ON_EVT_LINK_10M |\
185 LED_ON_EVT_LINK_HD | LED_ON_EVT_LINK_FD)
186
187#define LED_BLK_EVENT (LED_BLK_EVT_1000M_TX_ACT | \
188 LED_BLK_EVT_1000M_RX_ACT | \
189 LED_BLK_EVT_100M_TX_ACT | \
190 LED_BLK_EVT_100M_RX_ACT | \
191 LED_BLK_EVT_10M_TX_ACT | \
192 LED_BLK_EVT_10M_RX_ACT)
193
194#define LED_FREQ AIR_LED_BLK_DUR_64M
195
196#define AN8855_NUM_PHYS 5
197#define AN8855_NUM_PORTS 6
198#define AN8855_PHY_ADDR(base, addr) (((base) + (addr)) & 0x1f)
199
200/* PHY LED Register bitmap of define */
201#define PHY_LED_CTRL_SELECT 0x3e8
202#define PHY_SINGLE_LED_ON_CTRL(i) (0x3e0 + ((i) * 2))
203#define PHY_SINGLE_LED_BLK_CTRL(i) (0x3e1 + ((i) * 2))
204#define PHY_SINGLE_LED_ON_DUR(i) (0x3e9 + ((i) * 2))
205#define PHY_SINGLE_LED_BLK_DUR(i) (0x3ea + ((i) * 2))
206
207/* AN8855 LED */
208enum an8855_led_blk_dur {
209 AIR_LED_BLK_DUR_32M,
210 AIR_LED_BLK_DUR_64M,
211 AIR_LED_BLK_DUR_128M,
212 AIR_LED_BLK_DUR_256M,
213 AIR_LED_BLK_DUR_512M,
214 AIR_LED_BLK_DUR_1024M,
215 AIR_LED_BLK_DUR_LAST
216};
217
218enum an8855_led_polarity {
219 LED_LOW,
220 LED_HIGH,
221};
222
223enum an8855_led_mode {
224 AN8855_LED_MODE_DISABLE,
225 AN8855_LED_MODE_USER_DEFINE,
226 AN8855_LED_MODE_LAST
227};
228
229enum phy_led_idx {
230 P0_LED0,
231 P0_LED1,
232 P0_LED2,
233 P0_LED3,
234 P1_LED0,
235 P1_LED1,
236 P1_LED2,
237 P1_LED3,
238 P2_LED0,
239 P2_LED1,
240 P2_LED2,
241 P2_LED3,
242 P3_LED0,
243 P3_LED1,
244 P3_LED2,
245 P3_LED3,
246 P4_LED0,
247 P4_LED1,
248 P4_LED2,
249 P4_LED3,
250 PHY_LED_MAX
251};
252
253struct an8855_led_cfg {
254 u16 en;
255 u8 phy_led_idx;
256 u16 pol;
257 u16 on_cfg;
258 u16 blk_cfg;
259 u8 led_freq;
260};
261
262struct an8855_switch_priv {
263 struct mtk_eth_switch_priv epriv;
264 struct mii_dev *mdio_bus;
265 u32 phy_base;
266};
267
268/* AN8855 Reference Board */
269static const struct an8855_led_cfg led_cfg[] = {
270/*************************************************************************
271 * Enable, LED idx, LED Polarity, LED ON event, LED Blink event LED Freq
272 *************************************************************************
273 */
274 /* GPIO0 */
275 {1, P4_LED0, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
276 /* GPIO1 */
277 {1, P4_LED1, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
278 /* GPIO2 */
279 {1, P0_LED0, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
280 /* GPIO3 */
281 {1, P0_LED1, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
282 /* GPIO4 */
283 {1, P1_LED0, LED_LOW, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
284 /* GPIO5 */
285 {1, P1_LED1, LED_LOW, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
286 /* GPIO6 */
287 {0, PHY_LED_MAX, LED_LOW, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
288 /* GPIO7 */
289 {0, PHY_LED_MAX, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
290 /* GPIO8 */
291 {0, PHY_LED_MAX, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
292 /* GPIO9 */
293 {1, P2_LED0, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
294 /* GPIO10 */
295 {1, P2_LED1, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
296 /* GPIO11 */
297 {1, P3_LED0, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
298 /* GPIO12 */
299 {1, P3_LED1, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
300 /* GPIO13 */
301 {0, PHY_LED_MAX, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
302 /* GPIO14 */
303 {0, PHY_LED_MAX, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
304 /* GPIO15 */
305 {0, PHY_LED_MAX, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
306 /* GPIO16 */
307 {0, PHY_LED_MAX, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
308 /* GPIO17 */
309 {0, PHY_LED_MAX, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
310 /* GPIO18 */
311 {0, PHY_LED_MAX, LED_HIGH, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
312 /* GPIO19 */
313 {0, PHY_LED_MAX, LED_LOW, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
314 /* GPIO20 */
315 {0, PHY_LED_MAX, LED_LOW, LED_ON_EVENT, LED_BLK_EVENT, LED_FREQ},
316};
317
318static int __an8855_reg_read(struct mtk_eth_priv *priv, u8 phy_base, u32 reg, u32 *data)
319{
320 int ret, low_word, high_word;
321
322 ret = mtk_mii_write(priv, phy_base, 0x1f, 0x4);
323 if (ret)
324 return ret;
325
326 ret = mtk_mii_write(priv, phy_base, 0x10, 0);
327 if (ret)
328 return ret;
329
330 ret = mtk_mii_write(priv, phy_base, 0x15, ((reg >> 16) & 0xFFFF));
331 if (ret)
332 return ret;
333
334 ret = mtk_mii_write(priv, phy_base, 0x16, (reg & 0xFFFF));
335 if (ret)
336 return ret;
337
338 low_word = mtk_mii_read(priv, phy_base, 0x18);
339 if (low_word < 0)
340 return low_word;
341
342 high_word = mtk_mii_read(priv, phy_base, 0x17);
343 if (high_word < 0)
344 return high_word;
345
346 ret = mtk_mii_write(priv, phy_base, 0x1f, 0);
347 if (ret)
348 return ret;
349
350 ret = mtk_mii_write(priv, phy_base, 0x10, 0);
351 if (ret)
352 return ret;
353
354 if (data)
355 *data = ((u32)high_word << 16) | (low_word & 0xffff);
356
357 return 0;
358}
359
360static int an8855_reg_read(struct an8855_switch_priv *priv, u32 reg, u32 *data)
361{
362 return __an8855_reg_read(priv->epriv.eth, priv->phy_base, reg, data);
363}
364
365static int an8855_reg_write(struct an8855_switch_priv *priv, u32 reg, u32 data)
366{
367 int ret;
368
369 ret = mtk_mii_write(priv->epriv.eth, priv->phy_base, 0x1f, 0x4);
370 if (ret)
371 return ret;
372
373 ret = mtk_mii_write(priv->epriv.eth, priv->phy_base, 0x10, 0);
374 if (ret)
375 return ret;
376
377 ret = mtk_mii_write(priv->epriv.eth, priv->phy_base, 0x11,
378 ((reg >> 16) & 0xFFFF));
379 if (ret)
380 return ret;
381
382 ret = mtk_mii_write(priv->epriv.eth, priv->phy_base, 0x12,
383 (reg & 0xFFFF));
384 if (ret)
385 return ret;
386
387 ret = mtk_mii_write(priv->epriv.eth, priv->phy_base, 0x13,
388 ((data >> 16) & 0xFFFF));
389 if (ret)
390 return ret;
391
392 ret = mtk_mii_write(priv->epriv.eth, priv->phy_base, 0x14,
393 (data & 0xFFFF));
394 if (ret)
395 return ret;
396
397 ret = mtk_mii_write(priv->epriv.eth, priv->phy_base, 0x1f, 0);
398 if (ret)
399 return ret;
400
401 ret = mtk_mii_write(priv->epriv.eth, priv->phy_base, 0x10, 0);
402 if (ret)
403 return ret;
404
405 return 0;
406}
407
408static int an8855_phy_cl45_read(struct an8855_switch_priv *priv, int port,
409 int devad, int regnum, u16 *data)
410{
411 u16 phy_addr = AN8855_PHY_ADDR(priv->phy_base, port);
412
413 *data = mtk_mmd_ind_read(priv->epriv.eth, phy_addr, devad, regnum);
414
415 return 0;
416}
417
418static int an8855_phy_cl45_write(struct an8855_switch_priv *priv, int port,
419 int devad, int regnum, u16 data)
420{
421 u16 phy_addr = AN8855_PHY_ADDR(priv->phy_base, port);
422
423 mtk_mmd_ind_write(priv->epriv.eth, phy_addr, devad, regnum, data);
424
425 return 0;
426}
427
428static int an8855_port_sgmii_init(struct an8855_switch_priv *priv, u32 port)
429{
430 u32 val = 0;
431
432 if (port != 5) {
433 printf("an8855: port %d is not a SGMII port\n", port);
434 return -EINVAL;
435 }
436
437 /* PLL */
438 an8855_reg_read(priv, AN8855_QP_DIG_MODE_CTRL_1, &val);
439 val &= ~(0x3 << 2);
440 val |= (0x1 << 2);
441 an8855_reg_write(priv, AN8855_QP_DIG_MODE_CTRL_1, val);
442
443 /* PLL - LPF */
444 an8855_reg_read(priv, AN8855_PLL_CTRL_2, &val);
445 val &= ~(0x3 << 0);
446 val |= (0x1 << 0);
447 val &= ~(0x7 << 2);
448 val |= (0x5 << 2);
449 val &= ~GENMASK(7, 6);
450 val &= ~(0x7 << 8);
451 val |= (0x3 << 8);
452 val |= BIT(29);
453 val &= ~GENMASK(13, 12);
454 an8855_reg_write(priv, AN8855_PLL_CTRL_2, val);
455
456 /* PLL - ICO */
457 an8855_reg_read(priv, AN8855_PLL_CTRL_4, &val);
458 val |= BIT(2);
459 an8855_reg_write(priv, AN8855_PLL_CTRL_4, val);
460
461 an8855_reg_read(priv, AN8855_PLL_CTRL_2, &val);
462 val &= ~BIT(14);
463 an8855_reg_write(priv, AN8855_PLL_CTRL_2, val);
464
465 /* PLL - CHP */
466 an8855_reg_read(priv, AN8855_PLL_CTRL_2, &val);
467 val &= ~(0xf << 16);
468 val |= (0x6 << 16);
469 an8855_reg_write(priv, AN8855_PLL_CTRL_2, val);
470
471 /* PLL - PFD */
472 an8855_reg_read(priv, AN8855_PLL_CTRL_2, &val);
473 val &= ~(0x3 << 20);
474 val |= (0x1 << 20);
475 val &= ~(0x3 << 24);
476 val |= (0x1 << 24);
477 val &= ~BIT(26);
478 an8855_reg_write(priv, AN8855_PLL_CTRL_2, val);
479
480 /* PLL - POSTDIV */
481 an8855_reg_read(priv, AN8855_PLL_CTRL_2, &val);
482 val |= BIT(22);
483 val &= ~BIT(27);
484 val &= ~BIT(28);
485 an8855_reg_write(priv, AN8855_PLL_CTRL_2, val);
486
487 /* PLL - SDM */
488 an8855_reg_read(priv, AN8855_PLL_CTRL_4, &val);
489 val &= ~GENMASK(4, 3);
490 an8855_reg_write(priv, AN8855_PLL_CTRL_4, val);
491
492 an8855_reg_read(priv, AN8855_PLL_CTRL_2, &val);
493 val &= ~BIT(30);
494 an8855_reg_write(priv, AN8855_PLL_CTRL_2, val);
495
496 an8855_reg_read(priv, AN8855_SS_LCPLL_PWCTL_SETTING_2, &val);
497 val &= ~(0x3 << 16);
498 val |= (0x1 << 16);
499 an8855_reg_write(priv, AN8855_SS_LCPLL_PWCTL_SETTING_2, val);
500
501 an8855_reg_write(priv, AN8855_SS_LCPLL_TDC_FLT_2, 0x7a000000);
502 an8855_reg_write(priv, AN8855_SS_LCPLL_TDC_PCW_1, 0x7a000000);
503
504 an8855_reg_read(priv, AN8855_SS_LCPLL_TDC_FLT_5, &val);
505 val &= ~BIT(24);
506 an8855_reg_write(priv, AN8855_SS_LCPLL_TDC_FLT_5, val);
507
508 an8855_reg_read(priv, AN8855_PLL_CK_CTRL_0, &val);
509 val &= ~BIT(8);
510 an8855_reg_write(priv, AN8855_PLL_CK_CTRL_0, val);
511
512 /* PLL - SS */
513 an8855_reg_read(priv, AN8855_PLL_CTRL_3, &val);
514 val &= ~GENMASK(15, 0);
515 an8855_reg_write(priv, AN8855_PLL_CTRL_3, val);
516
517 an8855_reg_read(priv, AN8855_PLL_CTRL_4, &val);
518 val &= ~GENMASK(1, 0);
519 an8855_reg_write(priv, AN8855_PLL_CTRL_4, val);
520
521 an8855_reg_read(priv, AN8855_PLL_CTRL_3, &val);
522 val &= ~GENMASK(31, 16);
523 an8855_reg_write(priv, AN8855_PLL_CTRL_3, val);
524
525 /* PLL - TDC */
526 an8855_reg_read(priv, AN8855_PLL_CK_CTRL_0, &val);
527 val &= ~BIT(9);
528 an8855_reg_write(priv, AN8855_PLL_CK_CTRL_0, val);
529
530 an8855_reg_read(priv, AN8855_RG_QP_PLL_SDM_ORD, &val);
531 val |= BIT(3);
532 val |= BIT(4);
533 an8855_reg_write(priv, AN8855_RG_QP_PLL_SDM_ORD, val);
534
535 an8855_reg_read(priv, AN8855_RG_QP_RX_DAC_EN, &val);
536 val &= ~(0x3 << 16);
537 val |= (0x2 << 16);
538 an8855_reg_write(priv, AN8855_RG_QP_RX_DAC_EN, val);
539
540 /* TCL Disable (only for Co-SIM) */
541 an8855_reg_read(priv, AN8855_PON_RXFEDIG_CTRL_0, &val);
542 val &= ~BIT(12);
543 an8855_reg_write(priv, AN8855_PON_RXFEDIG_CTRL_0, val);
544
545 /* TX Init */
546 an8855_reg_read(priv, AN8855_RG_QP_TX_MODE_16B_EN, &val);
547 val &= ~BIT(0);
548 val &= ~(0xffff << 16);
549 val |= (0x4 << 16);
550 an8855_reg_write(priv, AN8855_RG_QP_TX_MODE_16B_EN, val);
551
552 /* RX Control */
553 an8855_reg_read(priv, AN8855_RG_QP_RXAFE_RESERVE, &val);
554 val |= BIT(11);
555 an8855_reg_write(priv, AN8855_RG_QP_RXAFE_RESERVE, val);
556
557 an8855_reg_read(priv, AN8855_RG_QP_CDR_LPF_MJV_LIM, &val);
558 val &= ~(0x3 << 4);
559 val |= (0x1 << 4);
560 an8855_reg_write(priv, AN8855_RG_QP_CDR_LPF_MJV_LIM, val);
561
562 an8855_reg_read(priv, AN8855_RG_QP_CDR_LPF_SETVALUE, &val);
563 val &= ~(0xf << 25);
564 val |= (0x1 << 25);
565 val &= ~(0x7 << 29);
566 val |= (0x3 << 29);
567 an8855_reg_write(priv, AN8855_RG_QP_CDR_LPF_SETVALUE, val);
568
569 an8855_reg_read(priv, AN8855_RG_QP_CDR_PR_CKREF_DIV1, &val);
570 val &= ~(0x1f << 8);
571 val |= (0xf << 8);
572 an8855_reg_write(priv, AN8855_RG_QP_CDR_PR_CKREF_DIV1, val);
573
574 an8855_reg_read(priv, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE, &val);
575 val &= ~(0x3f << 0);
576 val |= (0x19 << 0);
577 val &= ~BIT(6);
578 an8855_reg_write(priv, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE, val);
579
580 an8855_reg_read(priv, AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF, &val);
581 val &= ~(0x7f << 6);
582 val |= (0x21 << 6);
583 val &= ~(0x3 << 16);
584 val |= (0x2 << 16);
585 val &= ~BIT(13);
586 an8855_reg_write(priv, AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF, val);
587
588 an8855_reg_read(priv, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE, &val);
589 val &= ~BIT(30);
590 an8855_reg_write(priv, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE, val);
591
592 an8855_reg_read(priv, AN8855_RG_QP_CDR_PR_CKREF_DIV1, &val);
593 val &= ~(0x7 << 24);
594 val |= (0x4 << 24);
595 an8855_reg_write(priv, AN8855_RG_QP_CDR_PR_CKREF_DIV1, val);
596
597 an8855_reg_read(priv, AN8855_PLL_CTRL_0, &val);
598 val |= BIT(0);
599 an8855_reg_write(priv, AN8855_PLL_CTRL_0, val);
600
601 an8855_reg_read(priv, AN8855_RX_CTRL_26, &val);
602 val &= ~BIT(23);
603 val |= BIT(26);
604 an8855_reg_write(priv, AN8855_RX_CTRL_26, val);
605
606 an8855_reg_read(priv, AN8855_RX_DLY_0, &val);
607 val &= ~(0xff << 0);
608 val |= (0x6f << 0);
609 val |= GENMASK(13, 8);
610 an8855_reg_write(priv, AN8855_RX_DLY_0, val);
611
612 an8855_reg_read(priv, AN8855_RX_CTRL_42, &val);
613 val &= ~(0x1fff << 0);
614 val |= (0x150 << 0);
615 an8855_reg_write(priv, AN8855_RX_CTRL_42, val);
616
617 an8855_reg_read(priv, AN8855_RX_CTRL_2, &val);
618 val &= ~(0x1fff << 16);
619 val |= (0x150 << 16);
620 an8855_reg_write(priv, AN8855_RX_CTRL_2, val);
621
622 an8855_reg_read(priv, AN8855_PON_RXFEDIG_CTRL_9, &val);
623 val &= ~(0x7 << 0);
624 val |= (0x1 << 0);
625 an8855_reg_write(priv, AN8855_PON_RXFEDIG_CTRL_9, val);
626
627 an8855_reg_read(priv, AN8855_RX_CTRL_8, &val);
628 val &= ~(0xfff << 16);
629 val |= (0x200 << 16);
630 val &= ~(0x7fff << 14);
631 val |= (0xfff << 14);
632 an8855_reg_write(priv, AN8855_RX_CTRL_8, val);
633
634 /* Frequency memter */
635 an8855_reg_read(priv, AN8855_RX_CTRL_5, &val);
636 val &= ~(0xfffff << 10);
637 val |= (0x10 << 10);
638 an8855_reg_write(priv, AN8855_RX_CTRL_5, val);
639
640 an8855_reg_read(priv, AN8855_RX_CTRL_6, &val);
641 val &= ~(0xfffff << 0);
642 val |= (0x64 << 0);
643 an8855_reg_write(priv, AN8855_RX_CTRL_6, val);
644
645 an8855_reg_read(priv, AN8855_RX_CTRL_7, &val);
646 val &= ~(0xfffff << 0);
647 val |= (0x2710 << 0);
648 an8855_reg_write(priv, AN8855_RX_CTRL_7, val);
649
650 /* PCS Init */
651 an8855_reg_read(priv, AN8855_RG_HSGMII_PCS_CTROL_1, &val);
652 val &= ~BIT(30);
653 an8855_reg_write(priv, AN8855_RG_HSGMII_PCS_CTROL_1, val);
654
655 /* Rate Adaption */
656 an8855_reg_read(priv, AN8855_RATE_ADP_P0_CTRL_0, &val);
657 val &= ~BIT(31);
658 an8855_reg_write(priv, AN8855_RATE_ADP_P0_CTRL_0, val);
659
660 an8855_reg_read(priv, AN8855_RG_RATE_ADAPT_CTRL_0, &val);
661 val |= BIT(0);
662 val |= BIT(4);
663 val |= GENMASK(27, 26);
664 an8855_reg_write(priv, AN8855_RG_RATE_ADAPT_CTRL_0, val);
665
666 /* Disable AN */
667 an8855_reg_read(priv, AN8855_SGMII_REG_AN0, &val);
668 val &= ~BIT(12);
669 an8855_reg_write(priv, AN8855_SGMII_REG_AN0, val);
670
671 /* Force Speed */
672 an8855_reg_read(priv, AN8855_SGMII_STS_CTRL_0, &val);
673 val |= BIT(2);
674 val |= GENMASK(5, 4);
675 an8855_reg_write(priv, AN8855_SGMII_STS_CTRL_0, val);
676
677 /* bypass flow control to MAC */
678 an8855_reg_write(priv, AN8855_MSG_RX_LIK_STS_0, 0x01010107);
679 an8855_reg_write(priv, AN8855_MSG_RX_LIK_STS_2, 0x00000EEF);
680
681 return 0;
682}
683
684static void an8855_led_set_usr_def(struct an8855_switch_priv *priv, u8 entity,
685 enum an8855_led_polarity pol, u16 on_evt,
686 u16 blk_evt, u8 led_freq)
687{
688 u32 cl45_data;
689
690 if (pol == LED_HIGH)
691 on_evt |= LED_ON_POL;
692 else
693 on_evt &= ~LED_ON_POL;
694
695 /* LED on event */
696 an8855_phy_cl45_write(priv, (entity / 4), 0x1e,
697 PHY_SINGLE_LED_ON_CTRL(entity % 4),
698 on_evt | LED_ON_EN);
699
700 /* LED blink event */
701 an8855_phy_cl45_write(priv, (entity / 4), 0x1e,
702 PHY_SINGLE_LED_BLK_CTRL(entity % 4),
703 blk_evt);
704
705 /* LED freq */
706 switch (led_freq) {
707 case AIR_LED_BLK_DUR_32M:
708 cl45_data = 0x30e;
709 break;
710
711 case AIR_LED_BLK_DUR_64M:
712 cl45_data = 0x61a;
713 break;
714
715 case AIR_LED_BLK_DUR_128M:
716 cl45_data = 0xc35;
717 break;
718
719 case AIR_LED_BLK_DUR_256M:
720 cl45_data = 0x186a;
721 break;
722
723 case AIR_LED_BLK_DUR_512M:
724 cl45_data = 0x30d4;
725 break;
726
727 case AIR_LED_BLK_DUR_1024M:
728 cl45_data = 0x61a8;
729 break;
730
731 default:
732 cl45_data = 0;
733 break;
734 }
735
736 an8855_phy_cl45_write(priv, (entity / 4), 0x1e,
737 PHY_SINGLE_LED_BLK_DUR(entity % 4),
738 cl45_data);
739
740 an8855_phy_cl45_write(priv, (entity / 4), 0x1e,
741 PHY_SINGLE_LED_ON_DUR(entity % 4),
742 (cl45_data >> 1));
743
744 /* Disable DATA & BAD_SSD for port LED blink behavior */
745 cl45_data = mtk_mmd_ind_read(priv->epriv.eth, (entity / 4), 0x1e, PHY_PMA_CTRL);
746 cl45_data &= ~BIT(0);
747 cl45_data &= ~BIT(15);
748 an8855_phy_cl45_write(priv, (entity / 4), 0x1e, PHY_PMA_CTRL, cl45_data);
749}
750
751static int an8855_led_set_mode(struct an8855_switch_priv *priv, u8 mode)
752{
753 u16 cl45_data;
754
755 an8855_phy_cl45_read(priv, 0, 0x1f, PHY_LED_BCR, &cl45_data);
756
757 switch (mode) {
758 case AN8855_LED_MODE_DISABLE:
759 cl45_data &= ~LED_BCR_EXT_CTRL;
760 cl45_data &= ~LED_BCR_MODE_MASK;
761 cl45_data |= LED_BCR_MODE_DISABLE;
762 break;
763
764 case AN8855_LED_MODE_USER_DEFINE:
765 cl45_data |= LED_BCR_EXT_CTRL;
766 cl45_data |= LED_BCR_CLK_EN;
767 break;
768
769 default:
770 printf("an8855: LED mode%d is not supported!\n", mode);
771 return -EINVAL;
772 }
773
774 an8855_phy_cl45_write(priv, 0, 0x1f, PHY_LED_BCR, cl45_data);
775
776 return 0;
777}
778
779static int an8855_led_set_state(struct an8855_switch_priv *priv, u8 entity,
780 u8 state)
781{
782 u16 cl45_data = 0;
783
784 /* Change to per port contorl */
785 an8855_phy_cl45_read(priv, (entity / 4), 0x1e, PHY_LED_CTRL_SELECT,
786 &cl45_data);
787
788 if (state == 1)
789 cl45_data |= (1 << (entity % 4));
790 else
791 cl45_data &= ~(1 << (entity % 4));
792
793 an8855_phy_cl45_write(priv, (entity / 4), 0x1e, PHY_LED_CTRL_SELECT,
794 cl45_data);
795
796 /* LED enable setting */
797 an8855_phy_cl45_read(priv, (entity / 4), 0x1e,
798 PHY_SINGLE_LED_ON_CTRL(entity % 4), &cl45_data);
799
800 if (state == 1)
801 cl45_data |= LED_ON_EN;
802 else
803 cl45_data &= ~LED_ON_EN;
804
805 an8855_phy_cl45_write(priv, (entity / 4), 0x1e,
806 PHY_SINGLE_LED_ON_CTRL(entity % 4), cl45_data);
807
808 return 0;
809}
810
811static int an8855_led_init(struct an8855_switch_priv *priv)
812{
813 u32 val, id, tmp_id = 0;
814 int ret;
815
816 ret = an8855_led_set_mode(priv, AN8855_LED_MODE_USER_DEFINE);
817 if (ret) {
818 printf("an8855: led_set_mode failed with %d!\n", ret);
819 return ret;
820 }
821
822 for (id = 0; id < ARRAY_SIZE(led_cfg); id++) {
823 ret = an8855_led_set_state(priv, led_cfg[id].phy_led_idx,
824 led_cfg[id].en);
825 if (ret != 0) {
826 printf("an8855: led_set_state failed with %d!\n", ret);
827 return ret;
828 }
829
830 if (led_cfg[id].en == 1) {
831 an8855_led_set_usr_def(priv,
832 led_cfg[id].phy_led_idx,
833 led_cfg[id].pol,
834 led_cfg[id].on_cfg,
835 led_cfg[id].blk_cfg,
836 led_cfg[id].led_freq);
837 }
838 }
839
840 /* Setting for System LED & Loop LED */
841 an8855_reg_write(priv, AN8855_RG_GPIO_OE, 0x0);
842 an8855_reg_write(priv, AN8855_RG_GPIO_CTRL, 0x0);
843 an8855_reg_write(priv, AN8855_RG_GPIO_L_INV, 0);
844
845 an8855_reg_write(priv, AN8855_RG_GPIO_CTRL, 0x1001);
846 an8855_reg_read(priv, AN8855_RG_GPIO_DATA, &val);
847 val |= GENMASK(3, 1);
848 val &= ~(BIT(0));
849 val &= ~(BIT(6));
850 an8855_reg_write(priv, AN8855_RG_GPIO_DATA, val);
851
852 an8855_reg_read(priv, AN8855_RG_GPIO_OE, &val);
853 val |= 0x41;
854 an8855_reg_write(priv, AN8855_RG_GPIO_OE, val);
855
856 /* Mapping between GPIO & LED */
857 val = 0;
858 for (id = 0; id < ARRAY_SIZE(led_cfg); id++) {
859 /* Skip GPIO6, due to GPIO6 does not support PORT LED */
860 if (id == 6)
861 continue;
862
863 if (led_cfg[id].en == 1) {
864 if (id < 7)
865 val |= led_cfg[id].phy_led_idx << ((id % 4) * 8);
866 else
867 val |= led_cfg[id].phy_led_idx << (((id - 1) % 4) * 8);
868 }
869
870 if (id < 7)
871 tmp_id = id;
872 else
873 tmp_id = id - 1;
874
875 if ((tmp_id % 4) == 0x3) {
876 an8855_reg_write(priv,
877 AN8855_RG_GPIO_LED_SEL(tmp_id / 4),
878 val);
879 val = 0;
880 }
881 }
882
883 /* Turn on LAN LED mode */
884 val = 0;
885 for (id = 0; id < ARRAY_SIZE(led_cfg); id++) {
886 if (led_cfg[id].en == 1)
887 val |= 0x1 << id;
888 }
889 an8855_reg_write(priv, AN8855_RG_GPIO_LED_MODE, val);
890
891 /* Force clear blink pulse for per port LED */
892 an8855_phy_cl45_write(priv, 0, 0x1f, PHY_LED_BLINK_DUR_CTRL, 0x1f);
893 udelay(1000);
894 an8855_phy_cl45_write(priv, 0, 0x1f, PHY_LED_BLINK_DUR_CTRL, 0);
895
896 return 0;
897}
898
899static void an8855_port_isolation(struct an8855_switch_priv *priv)
900{
901 u32 i;
902
903 for (i = 0; i < AN8855_NUM_PORTS; i++) {
904 /* Set port matrix mode */
905 if (i != 5)
906 an8855_reg_write(priv, AN8855_PORTMATRIX_REG(i), 0x20);
907 else
908 an8855_reg_write(priv, AN8855_PORTMATRIX_REG(i), 0x1f);
909
910 /* Set port mode to user port */
911 an8855_reg_write(priv, AN8855_PVC(i),
912 (0x8100 << AN8855_STAG_VPID_S) |
913 (VLAN_ATTR_USER << AN8855_VLAN_ATTR_S));
914 }
915}
916
917static void an8855_mac_control(struct mtk_eth_switch_priv *swpriv, bool enable)
918{
919 struct an8855_switch_priv *priv = (struct an8855_switch_priv *)swpriv;
920 u32 pmcr = AN8855_FORCE_MODE_LNK;
921
922 if (enable)
923 pmcr = AN8855_FORCE_MODE;
924
925 an8855_reg_write(priv, AN8855_PMCR_REG(5), pmcr);
926}
927
928static int an8855_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
929{
930 struct an8855_switch_priv *priv = bus->priv;
931
932 if (devad < 0)
933 return mtk_mii_read(priv->epriv.eth, addr, reg);
934
935 return mtk_mmd_ind_read(priv->epriv.eth, addr, devad, reg);
936}
937
938static int an8855_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
939 u16 val)
940{
941 struct an8855_switch_priv *priv = bus->priv;
942
943 if (devad < 0)
944 return mtk_mii_write(priv->epriv.eth, addr, reg, val);
945
946 return mtk_mmd_ind_write(priv->epriv.eth, addr, devad, reg, val);
947}
948
949static int an8855_mdio_register(struct an8855_switch_priv *priv)
950{
951 struct mii_dev *mdio_bus = mdio_alloc();
952 int ret;
953
954 if (!mdio_bus)
955 return -ENOMEM;
956
957 mdio_bus->read = an8855_mdio_read;
958 mdio_bus->write = an8855_mdio_write;
959 snprintf(mdio_bus->name, sizeof(mdio_bus->name), priv->epriv.sw->name);
960
961 mdio_bus->priv = priv;
962
963 ret = mdio_register(mdio_bus);
964 if (ret) {
965 mdio_free(mdio_bus);
966 return ret;
967 }
968
969 priv->mdio_bus = mdio_bus;
970
971 return 0;
972}
973
974static int an8855_setup(struct mtk_eth_switch_priv *swpriv)
975{
976 struct an8855_switch_priv *priv = (struct an8855_switch_priv *)swpriv;
977 u16 phy_addr, phy_val;
978 u32 i, id, val = 0;
979 int ret;
980
981 priv->phy_base = 1;
982
983 /* Turn off PHYs */
984 for (i = 0; i < AN8855_NUM_PHYS; i++) {
985 phy_addr = AN8855_PHY_ADDR(priv->phy_base, i);
986 phy_val = mtk_mii_read(priv->epriv.eth, phy_addr, MII_BMCR);
987 phy_val |= BMCR_PDOWN;
988 mtk_mii_write(priv->epriv.eth, phy_addr, MII_BMCR, phy_val);
989 }
990
991 /* Force MAC link down before reset */
992 an8855_reg_write(priv, AN8855_PMCR_REG(5), AN8855_FORCE_MODE_LNK);
993
994 /* Switch soft reset */
995 an8855_reg_write(priv, AN8855_SYS_CTRL_REG, AN8855_SW_SYS_RST);
developer10c0aae2025-01-24 16:04:28 +0800996 mdelay(100);
developer7efa6382025-01-10 16:41:24 +0800997
998 an8855_reg_read(priv, AN8855_PKG_SEL, &val);
999 if ((val & 0x7) == PAG_SEL_AN8855H) {
1000 /* Release power down */
1001 an8855_reg_write(priv, RG_GPHY_AFE_PWD, 0x0);
1002
1003 /* Invert for LED activity change */
1004 an8855_reg_read(priv, AN8855_RG_GPIO_L_INV, &val);
1005 for (id = 0; id < ARRAY_SIZE(led_cfg); id++) {
developer10c0aae2025-01-24 16:04:28 +08001006 if (led_cfg[id].pol == LED_HIGH && led_cfg[id].en == 1)
developer7efa6382025-01-10 16:41:24 +08001007 val |= 0x1 << id;
1008 }
1009 an8855_reg_write(priv, AN8855_RG_GPIO_L_INV, (val | 0x1));
1010
1011 /* MCU NOP CMD */
1012 an8855_reg_write(priv, AN8855_RG_GDMP_RAM, 0x846);
1013 an8855_reg_write(priv, AN8855_RG_GDMP_RAM + 4, 0x4a);
1014
1015 /* Enable MCU */
1016 an8855_reg_read(priv, AN8855_RG_CLK_CPU_ICG, &val);
1017 an8855_reg_write(priv, AN8855_RG_CLK_CPU_ICG,
1018 val | AN8855_MCU_ENABLE);
1019 udelay(1000);
1020
1021 /* Disable MCU watchdog */
1022 an8855_reg_read(priv, AN8855_RG_TIMER_CTL, &val);
1023 an8855_reg_write(priv, AN8855_RG_TIMER_CTL,
1024 (val & (~AN8855_WDOG_ENABLE)));
1025
1026 /* LED settings for T830 reference board */
1027 ret = an8855_led_init(priv);
1028 if (ret < 0) {
1029 printf("an8855: an8855_led_init failed with %d\n", ret);
1030 return ret;
1031 }
1032 }
1033
1034 switch (priv->epriv.phy_interface) {
1035 case PHY_INTERFACE_MODE_2500BASEX:
1036 an8855_port_sgmii_init(priv, 5);
1037 break;
1038
1039 default:
1040 break;
1041 }
1042
1043 an8855_reg_read(priv, AN8855_CKGCR, &val);
1044 val &= ~(0x3);
1045 an8855_reg_write(priv, AN8855_CKGCR, val);
1046
1047 /* Enable port isolation to block inter-port communication */
1048 an8855_port_isolation(priv);
1049
1050 /* Turn on PHYs */
1051 for (i = 0; i < AN8855_NUM_PHYS; i++) {
1052 phy_addr = AN8855_PHY_ADDR(priv->phy_base, i);
1053 phy_val = mtk_mii_read(priv->epriv.eth, phy_addr, MII_BMCR);
1054 phy_val &= ~BMCR_PDOWN;
1055 mtk_mii_write(priv->epriv.eth, phy_addr, MII_BMCR, phy_val);
1056 }
1057
1058 return an8855_mdio_register(priv);
1059}
1060
1061static int an8855_cleanup(struct mtk_eth_switch_priv *swpriv)
1062{
1063 struct an8855_switch_priv *priv = (struct an8855_switch_priv *)swpriv;
1064
1065 mdio_unregister(priv->mdio_bus);
1066
1067 return 0;
1068}
1069
1070static int an8855_detect(struct mtk_eth_priv *priv)
1071{
1072 int ret;
1073 u32 val;
1074
1075 ret = __an8855_reg_read(priv, 1, 0x10005000, &val);
1076 if (ret)
1077 return ret;
1078
1079 if (val == 0x8855)
1080 return 0;
1081
1082 return -ENODEV;
1083}
1084
1085MTK_ETH_SWITCH(an8855) = {
1086 .name = "an8855",
1087 .desc = "Airoha AN8855",
1088 .priv_size = sizeof(struct an8855_switch_priv),
1089 .reset_wait_time = 100,
1090
1091 .detect = an8855_detect,
1092 .setup = an8855_setup,
1093 .cleanup = an8855_cleanup,
1094 .mac_control = an8855_mac_control,
1095};