1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2018-2019 MediaTek Inc.
4 /* A library for MediaTek SGMII circuit
6 * Author: Sean Wang <sean.wang@mediatek.com>
10 #include <linux/mfd/syscon.h>
12 #include <linux/regmap.h>
14 #include "mtk_eth_soc.h"
16 int mtk_sgmii_init(struct mtk_sgmii
*ss
, struct device_node
*r
, u32 ana_rgc3
)
18 struct device_node
*np
;
21 ss
->ana_rgc3
= ana_rgc3
;
23 for (i
= 0; i
< MTK_MAX_DEVS
; i
++) {
24 np
= of_parse_phandle(r
, "mediatek,sgmiisys", i
);
28 ss
->regmap
[i
] = syscon_node_to_regmap(np
);
29 if (IS_ERR(ss
->regmap
[i
]))
30 return PTR_ERR(ss
->regmap
[i
]);
36 int mtk_sgmii_setup_mode_an(struct mtk_sgmii
*ss
, int id
)
43 /* Setup the link timer and QPHY power up inside SGMIISYS */
44 regmap_write(ss
->regmap
[id
], SGMSYS_PCS_LINK_TIMER
,
45 SGMII_LINK_TIMER_DEFAULT
);
47 regmap_read(ss
->regmap
[id
], SGMSYS_SGMII_MODE
, &val
);
48 val
|= SGMII_REMOTE_FAULT_DIS
;
49 regmap_write(ss
->regmap
[id
], SGMSYS_SGMII_MODE
, val
);
51 regmap_read(ss
->regmap
[id
], SGMSYS_PCS_CONTROL_1
, &val
);
52 val
|= SGMII_AN_RESTART
;
53 regmap_write(ss
->regmap
[id
], SGMSYS_PCS_CONTROL_1
, val
);
55 regmap_read(ss
->regmap
[id
], SGMSYS_QPHY_PWR_STATE_CTRL
, &val
);
56 val
&= ~SGMII_PHYA_PWD
;
57 regmap_write(ss
->regmap
[id
], SGMSYS_QPHY_PWR_STATE_CTRL
, val
);
62 int mtk_sgmii_setup_mode_force(struct mtk_sgmii
*ss
, int id
,
63 const struct phylink_link_state
*state
)
70 regmap_read(ss
->regmap
[id
], ss
->ana_rgc3
, &val
);
71 val
&= ~RG_PHY_SPEED_MASK
;
72 if (state
->interface
== PHY_INTERFACE_MODE_2500BASEX
)
73 val
|= RG_PHY_SPEED_3_125G
;
74 regmap_write(ss
->regmap
[id
], ss
->ana_rgc3
, val
);
76 /* Disable SGMII AN */
77 regmap_read(ss
->regmap
[id
], SGMSYS_PCS_CONTROL_1
, &val
);
78 val
&= ~SGMII_AN_ENABLE
;
79 regmap_write(ss
->regmap
[id
], SGMSYS_PCS_CONTROL_1
, val
);
81 /* SGMII force mode setting */
82 regmap_read(ss
->regmap
[id
], SGMSYS_SGMII_MODE
, &val
);
83 val
&= ~SGMII_IF_MODE_MASK
;
85 switch (state
->speed
) {
87 val
|= SGMII_SPEED_10
;
90 val
|= SGMII_SPEED_100
;
94 val
|= SGMII_SPEED_1000
;
98 if (state
->duplex
== DUPLEX_FULL
)
99 val
|= SGMII_DUPLEX_FULL
;
101 regmap_write(ss
->regmap
[id
], SGMSYS_SGMII_MODE
, val
);
103 /* Release PHYA power down state */
104 regmap_read(ss
->regmap
[id
], SGMSYS_QPHY_PWR_STATE_CTRL
, &val
);
105 val
&= ~SGMII_PHYA_PWD
;
106 regmap_write(ss
->regmap
[id
], SGMSYS_QPHY_PWR_STATE_CTRL
, val
);
111 void mtk_sgmii_restart_an(struct mtk_eth
*eth
, int mac_id
)
113 struct mtk_sgmii
*ss
= eth
->sgmii
;
114 unsigned int val
, sid
;
116 /* Decide how GMAC and SGMIISYS be mapped */
117 sid
= (MTK_HAS_CAPS(eth
->soc
->caps
, MTK_SHARED_SGMII
)) ?
120 if (!ss
->regmap
[sid
])
123 regmap_read(ss
->regmap
[sid
], SGMSYS_PCS_CONTROL_1
, &val
);
124 val
|= SGMII_AN_RESTART
;
125 regmap_write(ss
->regmap
[sid
], SGMSYS_PCS_CONTROL_1
, val
);