mvebu: import patch enabling AQR112 and AQR412 PHY
[openwrt/openwrt.git] / target / linux / mvebu / patches-5.4 / 721-net-phy-aquantia-enable-AQR112-and-AQR412.patch
1 From 5f62951fba63a9f9cfff564209426bdea5fcc371 Mon Sep 17 00:00:00 2001
2 From: Alex Marginean <alexandru.marginean@nxp.com>
3 Date: Tue, 27 Aug 2019 15:16:56 +0300
4 Subject: [PATCH] drivers: net: phy: aquantia: enable AQR112 and AQR412
5
6 Adds support for AQR112 and AQR412 which is mostly based on existing code
7 with the addition of code configuring the protocol on system side.
8 This allows changing the system side protocol without having to deploy a
9 different firmware on the PHY.
10
11 Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
12 ---
13 drivers/net/phy/aquantia_main.c | 88 +++++++++++++++++++++++++++++++++++++++++
14 1 file changed, 88 insertions(+)
15
16 --- a/drivers/net/phy/aquantia_main.c
17 +++ b/drivers/net/phy/aquantia_main.c
18 @@ -20,8 +20,11 @@
19 #define PHY_ID_AQR105 0x03a1b4a2
20 #define PHY_ID_AQR106 0x03a1b4d0
21 #define PHY_ID_AQR107 0x03a1b4e0
22 +#define PHY_ID_AQR112 0x03a1b662
23 #define PHY_ID_AQCS109 0x03a1b5c2
24 #define PHY_ID_AQR405 0x03a1b4b0
25 +#define PHY_ID_AQR412 0x03a1b712
26 +
27
28 #define MDIO_PHYXS_VEND_IF_STATUS 0xe812
29 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
30 @@ -121,6 +124,29 @@
31 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
32 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
33
34 +/* registers in MDIO_MMD_VEND1 region */
35 +#define AQUANTIA_VND1_GLOBAL_SC 0x000
36 +#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb)
37 +
38 +/* global start rate, the protocol associated with this speed is used by default
39 + * on SI.
40 + */
41 +#define AQUANTIA_VND1_GSTART_RATE 0x31a
42 +#define AQUANTIA_VND1_GSTART_RATE_OFF 0
43 +#define AQUANTIA_VND1_GSTART_RATE_100M 1
44 +#define AQUANTIA_VND1_GSTART_RATE_1G 2
45 +#define AQUANTIA_VND1_GSTART_RATE_10G 3
46 +#define AQUANTIA_VND1_GSTART_RATE_2_5G 4
47 +#define AQUANTIA_VND1_GSTART_RATE_5G 5
48 +
49 +/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */
50 +#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b
51 +#define AQUANTIA_VND1_GSYSCFG_100M 0
52 +#define AQUANTIA_VND1_GSYSCFG_1G 1
53 +#define AQUANTIA_VND1_GSYSCFG_2_5G 2
54 +#define AQUANTIA_VND1_GSYSCFG_5G 3
55 +#define AQUANTIA_VND1_GSYSCFG_10G 4
56 +
57 struct aqr107_hw_stat {
58 const char *name;
59 int reg;
60 @@ -241,6 +267,51 @@ static int aqr_config_aneg(struct phy_de
61 return genphy_c45_check_and_restart_aneg(phydev, changed);
62 }
63
64 +static struct {
65 + u16 syscfg;
66 + int cnt;
67 + u16 start_rate;
68 +} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = {
69 + [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G,
70 + AQUANTIA_VND1_GSTART_RATE_1G},
71 + [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G,
72 + AQUANTIA_VND1_GSTART_RATE_2_5G},
73 + [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G,
74 + AQUANTIA_VND1_GSTART_RATE_10G},
75 + [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G,
76 + AQUANTIA_VND1_GSTART_RATE_10G},
77 +};
78 +
79 +/* Sets up protocol on system side before calling aqr_config_aneg */
80 +static int aqr_config_aneg_set_prot(struct phy_device *phydev)
81 +{
82 + int if_type = phydev->interface;
83 + int i;
84 +
85 + if (!aquantia_syscfg[if_type].cnt)
86 + return 0;
87 +
88 + /* set PHY in low power mode so we can configure protocols */
89 + phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC,
90 + AQUANTIA_VND1_GLOBAL_SC_LP);
91 + mdelay(10);
92 +
93 + /* set the default rate to enable the SI link */
94 + phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE,
95 + aquantia_syscfg[if_type].start_rate);
96 +
97 + for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++)
98 + phy_write_mmd(phydev, MDIO_MMD_VEND1,
99 + AQUANTIA_VND1_GSYSCFG_BASE + i,
100 + aquantia_syscfg[if_type].syscfg);
101 +
102 + /* wake PHY back up */
103 + phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0);
104 + mdelay(10);
105 +
106 + return aqr_config_aneg(phydev);
107 +}
108 +
109 static int aqr_config_intr(struct phy_device *phydev)
110 {
111 bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
112 @@ -682,6 +753,22 @@ static struct phy_driver aqr_driver[] =
113 .ack_interrupt = aqr_ack_interrupt,
114 .read_status = aqr_read_status,
115 },
116 +{
117 + PHY_ID_MATCH_MODEL(PHY_ID_AQR112),
118 + .name = "Aquantia AQR112",
119 + .config_aneg = aqr_config_aneg_set_prot,
120 + .config_intr = aqr_config_intr,
121 + .ack_interrupt = aqr_ack_interrupt,
122 + .read_status = aqr107_read_status,
123 +},
124 +{
125 + PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
126 + .name = "Aquantia AQR412",
127 + .config_aneg = aqr_config_aneg_set_prot,
128 + .config_intr = aqr_config_intr,
129 + .ack_interrupt = aqr_ack_interrupt,
130 + .read_status = aqr107_read_status,
131 +},
132 };
133
134 module_phy_driver(aqr_driver);
135 @@ -692,7 +779,9 @@ static struct mdio_device_id __maybe_unu
136 { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
137 { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
138 { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
139 + { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
140 { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
141 + { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
142 { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
143 { }
144 };