|
28 | 28 | #define SGMSYS_PCS_CONTROL_1 0x0 |
29 | 29 | #define SGMII_BMCR GENMASK(15, 0) |
30 | 30 | #define SGMII_BMSR GENMASK(31, 16) |
| 31 | +#define SGMII_REF_CK_SEL BIT(24) |
31 | 32 |
|
32 | 33 | #define SGMSYS_PCS_DEVICE_ID 0x4 |
33 | 34 | #define SGMII_LYNXI_DEV_ID 0x4d544950 |
|
55 | 56 | #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) |
56 | 57 | #define SGMII_DUPLEX_HALF BIT(4) |
57 | 58 | #define SGMII_REMOTE_FAULT_DIS BIT(8) |
| 59 | +#define SGMII_TRXBUF_THR_MASK GENMASK(31, 16) |
| 60 | +#define SGMII_TRXBUF_THR(x) FIELD_PREP(SGMII_TRXBUF_THR_MASK, (x)) |
58 | 61 |
|
59 | 62 | /* Register to reset SGMII design */ |
60 | 63 | #define SGMSYS_RESERVED_0 0x34 |
@@ -163,7 +166,7 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, |
163 | 166 | { |
164 | 167 | struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); |
165 | 168 | bool mode_changed = false, changed; |
166 | | - unsigned int rgc3, sgm_mode, bmcr; |
| 169 | + unsigned int rgc3, sgm_mode, bmcr = 0, trxbuf_thr = 0x3112; |
167 | 170 | unsigned int pnswap_tx, pnswap_rx; |
168 | 171 | int link_timer; |
169 | 172 |
|
@@ -194,6 +197,12 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, |
194 | 197 | bmcr = 0; |
195 | 198 | } |
196 | 199 |
|
| 200 | + /* Configure SGMII PCS clock source */ |
| 201 | + if (mpcs->flags & MTK_SGMII_FLAG_PHYA_TRX_CK) { |
| 202 | + bmcr |= SGMII_REF_CK_SEL; |
| 203 | + trxbuf_thr = 0x2111; |
| 204 | + } |
| 205 | + |
197 | 206 | if (mpcs->interface != interface) { |
198 | 207 | link_timer = phylink_get_link_timer_ns(interface); |
199 | 208 | if (link_timer < 0) |
@@ -243,12 +252,14 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, |
243 | 252 |
|
244 | 253 | /* Update the sgmsys mode register */ |
245 | 254 | regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, |
246 | | - SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | |
247 | | - SGMII_IF_MODE_SGMII, sgm_mode); |
| 255 | + SGMII_TRXBUF_THR_MASK | |
| 256 | + SGMII_REMOTE_FAULT_DIS | SGMII_DUPLEX_HALF | |
| 257 | + SGMII_SPEED_DUPLEX_AN | SGMII_IF_MODE_SGMII, |
| 258 | + SGMII_TRXBUF_THR(trxbuf_thr) | sgm_mode); |
248 | 259 |
|
249 | 260 | /* Update the BMCR */ |
250 | 261 | regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, |
251 | | - BMCR_ANENABLE, bmcr); |
| 262 | + SGMII_REF_CK_SEL | BMCR_ANENABLE, bmcr); |
252 | 263 |
|
253 | 264 | /* Release PHYA power down state |
254 | 265 | * Only removing bit SGMII_PHYA_PWD isn't enough. |
@@ -445,6 +456,9 @@ static int mtk_pcs_lynxi_probe(struct platform_device *pdev) |
445 | 456 | else if (of_property_read_bool(np->parent, "mediatek,pnswap-rx")) |
446 | 457 | flags |= MTK_SGMII_FLAG_PN_SWAP_RX; |
447 | 458 |
|
| 459 | + if (of_property_read_bool(np->parent, "mediatek,phya_trx_ck")) |
| 460 | + flags |= MTK_SGMII_FLAG_PHYA_TRX_CK; |
| 461 | + |
448 | 462 | if (of_parse_phandle(np->parent, "resets", 0)) { |
449 | 463 | mpcs->rstc = of_reset_control_get_shared(np->parent, NULL); |
450 | 464 | if (IS_ERR(mpcs->rstc)) |
|
0 commit comments