8e9939a4166b73bcc538a75052ead4b498eeb60f
[openwrt/openwrt.git] / target / linux / ipq806x / patches-5.10 / 101-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch
1 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
2 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
3 @@ -64,6 +64,17 @@
4 #define NSS_COMMON_CLK_DIV_SGMII_100 4
5 #define NSS_COMMON_CLK_DIV_SGMII_10 49
6
7 +#define QSGMII_PCS_ALL_CH_CTL 0x80
8 +#define QSGMII_PCS_CH_SPEED_FORCE 0x2
9 +#define QSGMII_PCS_CH_SPEED_10 0x0
10 +#define QSGMII_PCS_CH_SPEED_100 0x4
11 +#define QSGMII_PCS_CH_SPEED_1000 0x8
12 +#define QSGMII_PCS_CH_SPEED_MASK (QSGMII_PCS_CH_SPEED_FORCE | \
13 + QSGMII_PCS_CH_SPEED_10 | \
14 + QSGMII_PCS_CH_SPEED_100 | \
15 + QSGMII_PCS_CH_SPEED_1000)
16 +#define QSGMII_PCS_CH_SPEED_SHIFT(x) (x * 4)
17 +
18 #define QSGMII_PCS_CAL_LCKDT_CTL 0x120
19 #define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
20
21 @@ -242,6 +253,36 @@ static void ipq806x_gmac_fix_mac_speed(v
22 ipq806x_gmac_set_speed(gmac, speed);
23 }
24
25 +static int
26 +ipq806x_gmac_get_qsgmii_pcs_speed_val(struct platform_device *pdev) {
27 + struct device_node *fixed_link_node;
28 + int rv;
29 + int fixed_link_speed;
30 +
31 + if (!of_phy_is_fixed_link(pdev->dev.of_node))
32 + return 0;
33 +
34 + fixed_link_node = of_get_child_by_name(pdev->dev.of_node, "fixed-link");
35 + if (!fixed_link_node)
36 + return -1;
37 +
38 + rv = of_property_read_u32(fixed_link_node, "speed", &fixed_link_speed);
39 + of_node_put(fixed_link_node);
40 + if (rv)
41 + return -1;
42 +
43 + switch (fixed_link_speed) {
44 + case SPEED_1000:
45 + return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_1000;
46 + case SPEED_100:
47 + return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_100;
48 + case SPEED_10:
49 + return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_10;
50 + }
51 +
52 + return -1;
53 +}
54 +
55 static int ipq806x_gmac_probe(struct platform_device *pdev)
56 {
57 struct plat_stmmacenet_data *plat_dat;
58 @@ -250,6 +291,7 @@ static int ipq806x_gmac_probe(struct pla
59 struct ipq806x_gmac *gmac;
60 int val;
61 int err;
62 + int qsgmii_pcs_speed;
63
64 val = stmmac_get_platform_resources(pdev, &stmmac_res);
65 if (val)
66 @@ -346,6 +388,17 @@ static int ipq806x_gmac_probe(struct pla
67 0x1ul << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
68 0x2ul << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
69 0xCul << QSGMII_PHY_TX_DRV_AMP_OFFSET);
70 +
71 + qsgmii_pcs_speed = ipq806x_gmac_get_qsgmii_pcs_speed_val(pdev);
72 + if (qsgmii_pcs_speed != -1) {
73 + regmap_update_bits(
74 + gmac->qsgmii_csr,
75 + QSGMII_PCS_ALL_CH_CTL,
76 + QSGMII_PCS_CH_SPEED_MASK <<
77 + QSGMII_PCS_CH_SPEED_SHIFT(gmac->id),
78 + qsgmii_pcs_speed <<
79 + QSGMII_PCS_CH_SPEED_SHIFT(gmac->id));
80 + }
81 }
82
83 plat_dat->has_gmac = true;