4c0c9c31f8a9893dbec4ea5cef7383e0e9c78037
[openwrt/staging/stintel.git] /
1 From 23f3550c387246025ed2971989b747a5936bf080 Mon Sep 17 00:00:00 2001
2 From: Lei Wei <quic_leiwei@quicinc.com>
3 Date: Tue, 9 Apr 2024 01:07:22 +0800
4 Subject: [PATCH 14/50] net:pcs: Add 1000BASEX interface mode support to IPQ
5 UNIPHY PCS driver
6
7 1000BASEX is used when PCS connects with a 1G SFP module.
8
9 Change-Id: Ied7298de3c1ecba74e6457a07fdd6b3ceab79728
10 Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
11 ---
12 drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 23 +++++++++++++++++++++++
13 1 file changed, 23 insertions(+)
14
15 diff --git a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
16 index ed9c55a6c0fa..820d197744e8 100644
17 --- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
18 +++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
19 @@ -27,6 +27,9 @@
20 #define PCS_MODE_PSGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x2)
21 #define PCS_MODE_SGMII_PLUS FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
22 #define PCS_MODE_XPCS FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
23 +#define PCS_MODE_SGMII_CTRL_MASK GENMASK(6, 4)
24 +#define PCS_MODE_SGMII_CTRL_1000BASEX FIELD_PREP(PCS_MODE_SGMII_CTRL_MASK, \
25 + 0x0)
26 #define PCS_MODE_AN_MODE BIT(0)
27
28 #define PCS_CHANNEL_CTRL(x) (0x480 + 0x18 * (x))
29 @@ -392,6 +395,13 @@ static int ipq_unipcs_config_mode(struct ipq_uniphy_pcs *qunipcs,
30 PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE,
31 PCS_MODE_PSGMII);
32 break;
33 + case PHY_INTERFACE_MODE_1000BASEX:
34 + ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
35 + PCS_MODE_SEL_MASK |
36 + PCS_MODE_SGMII_CTRL_MASK,
37 + PCS_MODE_SGMII |
38 + PCS_MODE_SGMII_CTRL_1000BASEX);
39 + break;
40 case PHY_INTERFACE_MODE_2500BASEX:
41 rate = 312500000;
42 ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
43 @@ -620,6 +630,7 @@ ipq_unipcs_link_up_clock_rate_set(struct ipq_uniphy_pcs_ch *qunipcs_ch,
44 case PHY_INTERFACE_MODE_SGMII:
45 case PHY_INTERFACE_MODE_QSGMII:
46 case PHY_INTERFACE_MODE_PSGMII:
47 + case PHY_INTERFACE_MODE_1000BASEX:
48 rate = ipq_unipcs_clock_rate_get_gmii(speed);
49 break;
50 case PHY_INTERFACE_MODE_2500BASEX:
51 @@ -765,6 +776,10 @@ static void ipq_unipcs_get_state(struct phylink_pcs *pcs,
52 case PHY_INTERFACE_MODE_SGMII:
53 case PHY_INTERFACE_MODE_QSGMII:
54 case PHY_INTERFACE_MODE_PSGMII:
55 + case PHY_INTERFACE_MODE_1000BASEX:
56 + /* SGMII and 1000BASEX in-band autoneg word format are decoded
57 + * by PCS hardware and both placed to the same status register.
58 + */
59 ipq_unipcs_get_state_sgmii(qunipcs, channel, state);
60 break;
61 case PHY_INTERFACE_MODE_2500BASEX:
62 @@ -802,6 +817,7 @@ static int ipq_unipcs_config(struct phylink_pcs *pcs,
63 case PHY_INTERFACE_MODE_SGMII:
64 case PHY_INTERFACE_MODE_QSGMII:
65 case PHY_INTERFACE_MODE_PSGMII:
66 + case PHY_INTERFACE_MODE_1000BASEX:
67 return ipq_unipcs_config_sgmii(qunipcs, channel,
68 neg_mode, interface);
69 case PHY_INTERFACE_MODE_2500BASEX:
70 @@ -818,6 +834,11 @@ static int ipq_unipcs_config(struct phylink_pcs *pcs,
71 };
72 }
73
74 +static void qcom_ipq_unipcs_an_restart(struct phylink_pcs *pcs)
75 +{
76 + /* Currently not used */
77 +}
78 +
79 static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
80 unsigned int neg_mode,
81 phy_interface_t interface,
82 @@ -835,6 +856,7 @@ static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
83 case PHY_INTERFACE_MODE_SGMII:
84 case PHY_INTERFACE_MODE_QSGMII:
85 case PHY_INTERFACE_MODE_PSGMII:
86 + case PHY_INTERFACE_MODE_1000BASEX:
87 ipq_unipcs_link_up_config_sgmii(qunipcs, channel,
88 neg_mode, speed);
89 break;
90 @@ -858,6 +880,7 @@ static const struct phylink_pcs_ops ipq_unipcs_phylink_ops = {
91 .pcs_validate = ipq_unipcs_validate,
92 .pcs_get_state = ipq_unipcs_get_state,
93 .pcs_config = ipq_unipcs_config,
94 + .pcs_an_restart = qcom_ipq_unipcs_an_restart,
95 .pcs_link_up = ipq_unipcs_link_up,
96 };
97
98 --
99 2.45.2
100