1 From patchwork Thu Mar 9 10:57:44 2023
2 Content-Type: text/plain; charset="utf-8"
4 Content-Transfer-Encoding: 8bit
5 X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
6 X-Patchwork-Id: 13167235
7 X-Patchwork-Delegate: kuba@kernel.org
8 Return-Path: <netdev-owner@vger.kernel.org>
9 Date: Thu, 9 Mar 2023 10:57:44 +0000
10 From: Daniel Golle <daniel@makrotopia.org>
11 To: netdev@vger.kernel.org, linux-mediatek@lists.infradead.org,
12 linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
13 Russell King <linux@armlinux.org.uk>,
14 Heiner Kallweit <hkallweit1@gmail.com>,
15 Lorenzo Bianconi <lorenzo@kernel.org>,
16 Mark Lee <Mark-MC.Lee@mediatek.com>,
17 John Crispin <john@phrozen.org>, Felix Fietkau <nbd@nbd.name>,
18 AngeloGioacchino Del Regno
19 <angelogioacchino.delregno@collabora.com>,
20 Matthias Brugger <matthias.bgg@gmail.com>,
21 DENG Qingfang <dqfext@gmail.com>,
22 Landen Chao <Landen.Chao@mediatek.com>,
23 Sean Wang <sean.wang@mediatek.com>,
24 Paolo Abeni <pabeni@redhat.com>,
25 Jakub Kicinski <kuba@kernel.org>,
26 Eric Dumazet <edumazet@google.com>,
27 "David S. Miller" <davem@davemloft.net>,
28 Vladimir Oltean <olteanv@gmail.com>,
29 Florian Fainelli <f.fainelli@gmail.com>,
30 Andrew Lunn <andrew@lunn.ch>,
31 Vladimir Oltean <vladimir.oltean@nxp.com>
32 Cc: =?iso-8859-1?q?Bj=F8rn?= Mork <bjorn@mork.no>,
33 Frank Wunderlich <frank-w@public-files.de>,
34 Alexander Couzens <lynxis@fe80.eu>
35 Subject: [PATCH net-next v13 11/16] net: dsa: mt7530: use external PCS driver
37 <2ac2ee40d3b0e705461b50613fda6a7edfdbc4b3.1678357225.git.daniel@makrotopia.org>
38 References: <cover.1678357225.git.daniel@makrotopia.org>
40 Content-Disposition: inline
41 In-Reply-To: <cover.1678357225.git.daniel@makrotopia.org>
43 List-ID: <netdev.vger.kernel.org>
44 X-Mailing-List: netdev@vger.kernel.org
45 X-Patchwork-Delegate: kuba@kernel.org
47 Implement regmap access wrappers, for now only to be used by the
49 Make use of external PCS driver and drop the reduntant implementation
51 As a nice side effect the SGMII registers can now also more easily be
52 inspected for debugging via /sys/kernel/debug/regmap.
54 Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
55 Tested-by: Bjørn Mork <bjorn@mork.no>
56 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
57 Tested-by: Frank Wunderlich <frank-w@public-files.de>
59 drivers/net/dsa/Kconfig | 1 +
60 drivers/net/dsa/mt7530.c | 277 ++++++++++-----------------------------
61 drivers/net/dsa/mt7530.h | 47 +------
62 3 files changed, 71 insertions(+), 254 deletions(-)
64 --- a/drivers/net/dsa/Kconfig
65 +++ b/drivers/net/dsa/Kconfig
66 @@ -37,6 +37,7 @@ config NET_DSA_MT7530
67 tristate "MediaTek MT753x and MT7621 Ethernet switch support"
68 select NET_DSA_TAG_MTK
69 select MEDIATEK_GE_PHY
70 + select PCS_MTK_LYNXI
72 This enables support for the MediaTek MT7530, MT7531, and MT7621
73 Ethernet switch chips.
74 --- a/drivers/net/dsa/mt7530.c
75 +++ b/drivers/net/dsa/mt7530.c
77 #include <linux/of_mdio.h>
78 #include <linux/of_net.h>
79 #include <linux/of_platform.h>
80 +#include <linux/pcs/pcs-mtk-lynxi.h>
81 #include <linux/phylink.h>
82 #include <linux/regmap.h>
83 #include <linux/regulator/consumer.h>
84 @@ -2568,128 +2569,11 @@ static int mt7531_rgmii_setup(struct mt7
88 -static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
89 - phy_interface_t interface, int speed, int duplex)
91 - struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
92 - int port = pcs_to_mt753x_pcs(pcs)->port;
95 - /* For adjusting speed and duplex of SGMII force mode. */
96 - if (interface != PHY_INTERFACE_MODE_SGMII ||
97 - phylink_autoneg_inband(mode))
100 - /* SGMII force mode setting */
101 - val = mt7530_read(priv, MT7531_SGMII_MODE(port));
102 - val &= ~MT7531_SGMII_IF_MODE_MASK;
106 - val |= MT7531_SGMII_FORCE_SPEED_10;
109 - val |= MT7531_SGMII_FORCE_SPEED_100;
112 - val |= MT7531_SGMII_FORCE_SPEED_1000;
116 - /* MT7531 SGMII 1G force mode can only work in full duplex mode,
117 - * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
119 - * The speed check is unnecessary as the MAC capabilities apply
120 - * this restriction. --rmk
122 - if ((speed == SPEED_10 || speed == SPEED_100) &&
123 - duplex != DUPLEX_FULL)
124 - val |= MT7531_SGMII_FORCE_HALF_DUPLEX;
126 - mt7530_write(priv, MT7531_SGMII_MODE(port), val);
129 static bool mt753x_is_mac_port(u32 port)
131 return (port == 5 || port == 6);
134 -static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port,
135 - phy_interface_t interface)
139 - if (!mt753x_is_mac_port(port))
142 - mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
143 - MT7531_SGMII_PHYA_PWD);
145 - val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
146 - val &= ~MT7531_RG_TPHY_SPEED_MASK;
147 - /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B
150 - val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ?
151 - MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G;
152 - mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
154 - mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
156 - /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex
157 - * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
159 - mt7530_rmw(priv, MT7531_SGMII_MODE(port),
160 - MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS,
161 - MT7531_SGMII_FORCE_SPEED_1000);
163 - mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
168 -static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port,
169 - phy_interface_t interface)
171 - if (!mt753x_is_mac_port(port))
174 - mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
175 - MT7531_SGMII_PHYA_PWD);
177 - mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port),
178 - MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G);
180 - mt7530_set(priv, MT7531_SGMII_MODE(port),
181 - MT7531_SGMII_REMOTE_FAULT_DIS |
182 - MT7531_SGMII_SPEED_DUPLEX_AN);
184 - mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port),
185 - MT7531_SGMII_TX_CONFIG_MASK, 1);
187 - mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
189 - mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART);
191 - mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
196 -static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
198 - struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
199 - int port = pcs_to_mt753x_pcs(pcs)->port;
202 - /* Only restart AN when AN is enabled */
203 - val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
204 - if (val & MT7531_SGMII_AN_ENABLE) {
205 - val |= MT7531_SGMII_AN_RESTART;
206 - mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
211 mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
212 phy_interface_t interface)
213 @@ -2712,11 +2596,11 @@ mt7531_mac_config(struct dsa_switch *ds,
214 phydev = dp->slave->phydev;
215 return mt7531_rgmii_setup(priv, port, interface, phydev);
216 case PHY_INTERFACE_MODE_SGMII:
217 - return mt7531_sgmii_setup_mode_an(priv, port, interface);
218 case PHY_INTERFACE_MODE_NA:
219 case PHY_INTERFACE_MODE_1000BASEX:
220 case PHY_INTERFACE_MODE_2500BASEX:
221 - return mt7531_sgmii_setup_mode_force(priv, port, interface);
222 + /* handled in SGMII PCS driver */
227 @@ -2741,11 +2625,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
230 case PHY_INTERFACE_MODE_TRGMII:
231 + return &priv->pcs[port].pcs;
232 case PHY_INTERFACE_MODE_SGMII:
233 case PHY_INTERFACE_MODE_1000BASEX:
234 case PHY_INTERFACE_MODE_2500BASEX:
235 - return &priv->pcs[port].pcs;
237 + return priv->ports[port].sgmii_pcs;
241 @@ -2986,86 +2870,6 @@ static void mt7530_pcs_get_state(struct
242 state->pause |= MLO_PAUSE_TX;
246 -mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
247 - struct phylink_link_state *state)
252 - status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
253 - state->link = !!(status & MT7531_SGMII_LINK_STATUS);
254 - state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
255 - if (state->interface == PHY_INTERFACE_MODE_SGMII &&
256 - (status & MT7531_SGMII_AN_ENABLE)) {
257 - val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
258 - config_reg = val >> 16;
260 - switch (config_reg & LPA_SGMII_SPD_MASK) {
261 - case LPA_SGMII_1000:
262 - state->speed = SPEED_1000;
264 - case LPA_SGMII_100:
265 - state->speed = SPEED_100;
268 - state->speed = SPEED_10;
271 - dev_err(priv->dev, "invalid sgmii PHY speed\n");
272 - state->link = false;
276 - if (config_reg & LPA_SGMII_FULL_DUPLEX)
277 - state->duplex = DUPLEX_FULL;
279 - state->duplex = DUPLEX_HALF;
286 -mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
287 - struct phylink_link_state *state)
291 - val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
292 - state->link = !!(val & MT7531_SGMII_LINK_STATUS);
296 - state->an_complete = state->link;
298 - if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
299 - state->speed = SPEED_2500;
301 - state->speed = SPEED_1000;
303 - state->duplex = DUPLEX_FULL;
304 - state->pause = MLO_PAUSE_NONE;
307 -static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
308 - struct phylink_link_state *state)
310 - struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
311 - int port = pcs_to_mt753x_pcs(pcs)->port;
313 - if (state->interface == PHY_INTERFACE_MODE_SGMII) {
314 - mt7531_sgmii_pcs_get_state_an(priv, port, state);
316 - } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
317 - (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
318 - mt7531_sgmii_pcs_get_state_inband(priv, port, state);
322 - state->link = false;
325 static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
326 phy_interface_t interface,
327 const unsigned long *advertising,
328 @@ -3085,18 +2889,57 @@ static const struct phylink_pcs_ops mt75
329 .pcs_an_restart = mt7530_pcs_an_restart,
332 -static const struct phylink_pcs_ops mt7531_pcs_ops = {
333 - .pcs_validate = mt753x_pcs_validate,
334 - .pcs_get_state = mt7531_pcs_get_state,
335 - .pcs_config = mt753x_pcs_config,
336 - .pcs_an_restart = mt7531_pcs_an_restart,
337 - .pcs_link_up = mt7531_pcs_link_up,
338 +static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
340 + struct mt7530_priv *priv = context;
342 + *val = mt7530_read(priv, reg);
346 +static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
348 + struct mt7530_priv *priv = context;
350 + mt7530_write(priv, reg, val);
354 +static int mt7530_regmap_update_bits(void *context, unsigned int reg,
355 + unsigned int mask, unsigned int val)
357 + struct mt7530_priv *priv = context;
359 + mt7530_rmw(priv, reg, mask, val);
363 +static const struct regmap_bus mt7531_regmap_bus = {
364 + .reg_write = mt7530_regmap_write,
365 + .reg_read = mt7530_regmap_read,
366 + .reg_update_bits = mt7530_regmap_update_bits,
369 +#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
375 + .reg_base = _reg_base, \
376 + .max_register = 0x17c, \
379 +static const struct regmap_config mt7531_pcs_config[] = {
380 + MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
381 + MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
385 mt753x_setup(struct dsa_switch *ds)
387 struct mt7530_priv *priv = ds->priv;
388 + struct regmap *regmap;
391 /* Initialise the PCS devices */
392 @@ -3104,8 +2947,6 @@ mt753x_setup(struct dsa_switch *ds)
393 priv->pcs[i].pcs.ops = priv->info->pcs_ops;
394 priv->pcs[i].priv = priv;
395 priv->pcs[i].port = i;
396 - if (mt753x_is_mac_port(i))
397 - priv->pcs[i].pcs.poll = 1;
400 ret = priv->info->sw_setup(ds);
401 @@ -3120,6 +2961,16 @@ mt753x_setup(struct dsa_switch *ds)
402 if (ret && priv->irq)
403 mt7530_free_irq_common(priv);
405 + if (priv->id == ID_MT7531)
406 + for (i = 0; i < 2; i++) {
407 + regmap = devm_regmap_init(ds->dev,
408 + &mt7531_regmap_bus, priv,
409 + &mt7531_pcs_config[i]);
410 + priv->ports[5 + i].sgmii_pcs =
411 + mtk_pcs_lynxi_create(ds->dev, regmap,
412 + MT7531_PHYA_CTRL_SIGNAL3, 0);
418 @@ -3211,7 +3062,7 @@ static const struct mt753x_info mt753x_t
422 - .pcs_ops = &mt7531_pcs_ops,
423 + .pcs_ops = &mt7530_pcs_ops,
424 .sw_setup = mt7531_setup,
425 .phy_read = mt7531_ind_phy_read,
426 .phy_write = mt7531_ind_phy_write,
427 @@ -3319,7 +3170,7 @@ static void
428 mt7530_remove(struct mdio_device *mdiodev)
430 struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
436 @@ -3338,6 +3189,10 @@ mt7530_remove(struct mdio_device *mdiode
437 mt7530_free_irq(priv);
439 dsa_unregister_switch(priv->ds);
441 + for (i = 0; i < 2; ++i)
442 + mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
444 mutex_destroy(&priv->reg_mutex);
446 dev_set_drvdata(&mdiodev->dev, NULL);
447 --- a/drivers/net/dsa/mt7530.h
448 +++ b/drivers/net/dsa/mt7530.h
449 @@ -364,47 +364,8 @@ enum mt7530_vlan_port_acc_frm {
452 /* MT7531 SGMII register group */
453 -#define MT7531_SGMII_REG_BASE 0x5000
454 -#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
455 - ((p) - 5) * 0x1000 + (r))
457 -/* Register forSGMII PCS_CONTROL_1 */
458 -#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00)
459 -#define MT7531_SGMII_LINK_STATUS BIT(18)
460 -#define MT7531_SGMII_AN_ENABLE BIT(12)
461 -#define MT7531_SGMII_AN_RESTART BIT(9)
462 -#define MT7531_SGMII_AN_COMPLETE BIT(21)
464 -/* Register for SGMII PCS_SPPED_ABILITY */
465 -#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)
466 -#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0)
467 -#define MT7531_SGMII_TX_CONFIG BIT(0)
469 -/* Register for SGMII_MODE */
470 -#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20)
471 -#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8)
472 -#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1)
473 -#define MT7531_SGMII_FORCE_DUPLEX BIT(4)
474 -#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2)
475 -#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3)
476 -#define MT7531_SGMII_FORCE_SPEED_100 BIT(2)
477 -#define MT7531_SGMII_FORCE_SPEED_10 0
478 -#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1)
480 -enum mt7531_sgmii_force_duplex {
481 - MT7531_SGMII_FORCE_FULL_DUPLEX = 0,
482 - MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10,
485 -/* Fields of QPHY_PWR_STATE_CTRL */
486 -#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8)
487 -#define MT7531_SGMII_PHYA_PWD BIT(4)
489 -/* Values of SGMII SPEED */
490 -#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128)
491 -#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3))
492 -#define MT7531_RG_TPHY_SPEED_1_25G 0x0
493 -#define MT7531_RG_TPHY_SPEED_3_125G BIT(2)
494 +#define MT7531_SGMII_REG_BASE(p) (0x5000 + ((p) - 5) * 0x1000)
495 +#define MT7531_PHYA_CTRL_SIGNAL3 0x128
497 /* Register for system reset */
498 #define MT7530_SYS_CTRL 0x7000
499 @@ -703,13 +664,13 @@ struct mt7530_fdb {
500 * @pm: The matrix used to show all connections with the port.
501 * @pvid: The VLAN specified is to be considered a PVID at ingress. Any
502 * untagged frames will be assigned to the related VLAN.
503 - * @vlan_filtering: The flags indicating whether the port that can recognize
504 - * VLAN-tagged frames.
505 + * @sgmii_pcs: Pointer to PCS instance for SerDes ports
511 + struct phylink_pcs *sgmii_pcs;
514 /* Port 5 interface select definitions */