1 From patchwork Tue Dec 10 08:14:38 2019
2 Content-Type: text/plain; charset="utf-8"
4 Content-Transfer-Encoding: 7bit
5 X-Patchwork-Submitter: Landen Chao <landen.chao@mediatek.com>
6 X-Patchwork-Id: 1206963
7 X-Patchwork-Delegate: davem@davemloft.net
8 Return-Path: <netdev-owner@vger.kernel.org>
9 X-Original-To: patchwork-incoming-netdev@ozlabs.org
10 Delivered-To: patchwork-incoming-netdev@ozlabs.org
11 Authentication-Results: ozlabs.org; spf=none (no SPF record)
12 smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67;
14 envelope-from=netdev-owner@vger.kernel.org;
16 Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none)
17 header.from=mediatek.com
18 Authentication-Results: ozlabs.org; dkim=pass (1024-bit key;
19 unprotected) header.d=mediatek.com header.i=@mediatek.com
20 header.b="UJ5NATux"; dkim-atps=neutral
21 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
22 by ozlabs.org (Postfix) with ESMTP id 47XCY92tBkz9sR7
23 for <patchwork-incoming-netdev@ozlabs.org>;
24 Tue, 10 Dec 2019 19:15:25 +1100 (AEDT)
25 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
26 id S1727003AbfLJIO4 (ORCPT
27 <rfc822;patchwork-incoming-netdev@ozlabs.org>);
28 Tue, 10 Dec 2019 03:14:56 -0500
29 Received: from mailgw02.mediatek.com ([210.61.82.184]:45567 "EHLO
30 mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by
31 vger.kernel.org with ESMTP id S1726071AbfLJIOy (ORCPT
32 <rfc822;netdev@vger.kernel.org>); Tue, 10 Dec 2019 03:14:54 -0500
33 X-UUID: a18674d7b33c423e9e67b7440f4771cf-20191210
34 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
36 h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
37 bh=c2C/fEHYw/8uqadmiP2m2xa2hsUpAd52urXVJTPlYck=;
38 b=UJ5NATuxMtqHln5i6BTpWiLnxGKgWvp4DpRsKVO2xdnz2cJaT4XL8F/T5fK3CTF4nAai0EKPAcqp+rr8eCLq7uURJv5e5h+ZIzKLSAB4zgnchXesQLo0uFS8vs5w2yp49j6bez1z3v/uN+1+Lpq0uYid9awCqzvbnovrooEysu4=;
39 X-UUID: a18674d7b33c423e9e67b7440f4771cf-20191210
40 Received: from mtkcas09.mediatek.inc [(172.21.101.178)] by
41 mailgw02.mediatek.com (envelope-from <landen.chao@mediatek.com>)
42 (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS)
43 with ESMTP id 1965641267; Tue, 10 Dec 2019 16:14:46 +0800
44 Received: from mtkcas08.mediatek.inc (172.21.101.126) by
45 mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server
46 (TLS) id 15.0.1395.4; Tue, 10 Dec 2019 16:14:31 +0800
47 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc
48 (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via
49 Frontend Transport; Tue, 10 Dec 2019 16:14:26 +0800
50 From: Landen Chao <landen.chao@mediatek.com>
51 To: <andrew@lunn.ch>, <f.fainelli@gmail.com>,
52 <vivien.didelot@savoirfairelinux.com>, <matthias.bgg@gmail.com>,
53 <robh+dt@kernel.org>, <mark.rutland@arm.com>
54 CC: <devicetree@vger.kernel.org>, <netdev@vger.kernel.org>,
55 <linux-kernel@vger.kernel.org>,
56 <linux-mediatek@lists.infradead.org>, <davem@davemloft.net>,
57 <sean.wang@mediatek.com>, <opensource@vdorst.com>,
58 <frank-w@public-files.de>, Landen Chao <landen.chao@mediatek.com>
59 Subject: [PATCH net-next 2/6] net: dsa: mt7530: Extend device data ready for
61 Date: Tue, 10 Dec 2019 16:14:38 +0800
62 Message-ID: <2d546d6bb15ff8b4b75af2220e20db4e634f4145.1575914275.git.landen.chao@mediatek.com>
63 X-Mailer: git-send-email 2.18.0
64 In-Reply-To: <cover.1575914275.git.landen.chao@mediatek.com>
65 References: <cover.1575914275.git.landen.chao@mediatek.com>
68 Sender: netdev-owner@vger.kernel.org
70 List-ID: <netdev.vger.kernel.org>
71 X-Mailing-List: netdev@vger.kernel.org
73 Add a structure holding required operations for each device such as device
74 initialization, PHY port read or write, a checker whether PHY interface is
75 supported on a certain port, MAC port setup for either bus pad or a
76 specific PHY interface.
78 The patch is done for ready adding a new hardware MT7531.
80 Signed-off-by: Landen Chao <landen.chao@mediatek.com>
81 Signed-off-by: Sean Wang <sean.wang@mediatek.com>
83 drivers/net/dsa/mt7530.c | 231 +++++++++++++++++++++++++++++----------
84 drivers/net/dsa/mt7530.h | 29 ++++-
85 2 files changed, 203 insertions(+), 57 deletions(-)
87 Index: linux-5.4.43/drivers/net/dsa/mt7530.c
88 ===================================================================
89 --- linux-5.4.43.orig/drivers/net/dsa/mt7530.c
90 +++ linux-5.4.43/drivers/net/dsa/mt7530.c
91 @@ -373,7 +373,7 @@ mt7530_fdb_write(struct mt7530_priv *pri
95 -mt7530_pad_clk_setup(struct dsa_switch *ds, int mode)
96 +mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t mode)
98 struct mt7530_priv *priv = ds->priv;
99 u32 ncpo1, ssc_delta, trgint, i, xtal;
100 @@ -1355,13 +1355,111 @@ mt7530_setup(struct dsa_switch *ds)
104 -static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
105 +static bool mt7530_phy_supported(struct dsa_switch *ds, int port,
106 + const struct phylink_link_state *state)
108 + struct mt7530_priv *priv = ds->priv;
111 + case 0: /* Internal phy */
116 + if (state->interface != PHY_INTERFACE_MODE_GMII)
119 + case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
120 + if (!phy_interface_mode_is_rgmii(state->interface) &&
121 + state->interface != PHY_INTERFACE_MODE_MII &&
122 + state->interface != PHY_INTERFACE_MODE_GMII)
125 + case 6: /* 1st cpu port */
126 + if (state->interface != PHY_INTERFACE_MODE_RGMII &&
127 + state->interface != PHY_INTERFACE_MODE_TRGMII)
131 + dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
142 +static bool mt753x_phy_supported(struct dsa_switch *ds, int port,
143 + const struct phylink_link_state *state)
145 + struct mt7530_priv *priv = ds->priv;
147 + return priv->info->phy_supported(ds, port, state);
151 +mt7530_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
153 + struct mt7530_priv *priv = ds->priv;
155 + /* Setup TX circuit incluing relevant PAD and driving */
156 + mt7530_pad_clk_setup(ds, state->interface);
158 + if (priv->id == ID_MT7530) {
159 + /* Setup RX circuit, relevant PAD and driving on the
160 + * host which must be placed after the setup on the
161 + * device side is all finished.
163 + mt7623_pad_clk_setup(ds);
170 +mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
172 + struct mt7530_priv *priv = ds->priv;
174 + return priv->info->pad_setup(ds, state);
178 +mt7530_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
179 + const struct phylink_link_state *state)
181 + struct mt7530_priv *priv = ds->priv;
183 + /* Only need to setup port5. */
187 + mt7530_setup_port5(priv->ds, state->interface);
192 +static int mt753x_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
193 + const struct phylink_link_state *state)
195 + struct mt7530_priv *priv = ds->priv;
197 + return priv->info->mac_setup(ds, port, mode, state);
200 +static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port,
202 const struct phylink_link_state *state)
204 struct mt7530_priv *priv = ds->priv;
205 u32 mcr_cur, mcr_new;
207 + if (!mt753x_phy_supported(ds, port, state))
211 case 0: /* Internal phy */
213 @@ -1374,24 +1472,15 @@ static void mt7530_phylink_mac_config(st
214 case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
215 if (priv->p5_interface == state->interface)
217 - if (!phy_interface_mode_is_rgmii(state->interface) &&
218 - state->interface != PHY_INTERFACE_MODE_MII &&
219 - state->interface != PHY_INTERFACE_MODE_GMII)
222 - mt7530_setup_port5(ds, state->interface);
223 + if (mt753x_mac_setup(ds, port, mode, state) < 0)
226 case 6: /* 1st cpu port */
227 if (priv->p6_interface == state->interface)
230 - if (state->interface != PHY_INTERFACE_MODE_RGMII &&
231 - state->interface != PHY_INTERFACE_MODE_TRGMII)
234 - /* Setup TX circuit incluing relevant PAD and driving */
235 - mt7530_pad_clk_setup(ds, state->interface);
237 + mt753x_pad_setup(ds, state);
238 + if (mt753x_mac_setup(ds, port, mode, state) < 0)
240 priv->p6_interface = state->interface;
243 @@ -1459,38 +1548,14 @@ static void mt7530_phylink_mac_link_up(s
244 mt7530_port_set_status(priv, port, 1);
247 -static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
248 +static void mt753x_phylink_validate(struct dsa_switch *ds, int port,
249 unsigned long *supported,
250 struct phylink_link_state *state)
252 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
255 - case 0: /* Internal phy */
260 - if (state->interface != PHY_INTERFACE_MODE_NA &&
261 - state->interface != PHY_INTERFACE_MODE_GMII)
264 - case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
265 - if (state->interface != PHY_INTERFACE_MODE_NA &&
266 - !phy_interface_mode_is_rgmii(state->interface) &&
267 - state->interface != PHY_INTERFACE_MODE_MII &&
268 - state->interface != PHY_INTERFACE_MODE_GMII)
271 - case 6: /* 1st cpu port */
272 - if (state->interface != PHY_INTERFACE_MODE_NA &&
273 - state->interface != PHY_INTERFACE_MODE_RGMII &&
274 - state->interface != PHY_INTERFACE_MODE_TRGMII)
278 - dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
280 + if (state->interface != PHY_INTERFACE_MODE_NA &&
281 + !mt753x_phy_supported(ds, port, state)) {
282 linkmode_zero(supported);
285 @@ -1609,12 +1674,36 @@ static int mt7530_set_mac_eee(struct dsa
290 +mt753x_setup(struct dsa_switch *ds)
292 + struct mt7530_priv *priv = ds->priv;
294 + return priv->info->setup(ds);
298 +mt753x_phy_read(struct dsa_switch *ds, int port, int regnum)
300 + struct mt7530_priv *priv = ds->priv;
302 + return priv->info->phy_read(ds, port, regnum);
306 +mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
308 + struct mt7530_priv *priv = ds->priv;
310 + return priv->info->phy_write(ds, port, regnum, val);
313 static const struct dsa_switch_ops mt7530_switch_ops = {
314 .get_tag_protocol = mtk_get_tag_protocol,
315 - .setup = mt7530_setup,
316 + .setup = mt753x_setup,
317 .get_strings = mt7530_get_strings,
318 - .phy_read = mt7530_phy_read,
319 - .phy_write = mt7530_phy_write,
320 + .phy_read = mt753x_phy_read,
321 + .phy_write = mt753x_phy_write,
322 .get_ethtool_stats = mt7530_get_ethtool_stats,
323 .get_sset_count = mt7530_get_sset_count,
324 .port_enable = mt7530_port_enable,
325 @@ -1631,18 +1720,39 @@ static const struct dsa_switch_ops mt753
326 .port_vlan_del = mt7530_port_vlan_del,
327 .port_mirror_add = mt7530_port_mirror_add,
328 .port_mirror_del = mt7530_port_mirror_del,
329 - .phylink_validate = mt7530_phylink_validate,
330 + .phylink_validate = mt753x_phylink_validate,
331 .phylink_mac_link_state = mt7530_phylink_mac_link_state,
332 - .phylink_mac_config = mt7530_phylink_mac_config,
333 + .phylink_mac_config = mt753x_phylink_mac_config,
334 .phylink_mac_link_down = mt7530_phylink_mac_link_down,
335 .phylink_mac_link_up = mt7530_phylink_mac_link_up,
336 .get_mac_eee = mt7530_get_mac_eee,
337 .set_mac_eee = mt7530_set_mac_eee,
340 -static const struct of_device_id mt7530_of_match[] = {
341 - { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },
342 - { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },
343 +static const struct mt753x_info mt753x_table[] = {
346 + .setup = mt7530_setup,
347 + .phy_read = mt7530_phy_read,
348 + .phy_write = mt7530_phy_write,
349 + .phy_supported = mt7530_phy_supported,
350 + .pad_setup = mt7530_pad_setup,
351 + .mac_setup = mt7530_mac_setup,
355 + .setup = mt7530_setup,
356 + .phy_read = mt7530_phy_read,
357 + .phy_write = mt7530_phy_write,
358 + .phy_supported = mt7530_phy_supported,
359 + .pad_setup = mt7530_pad_setup,
360 + .mac_setup = mt7530_mac_setup,
364 + static const struct of_device_id mt7530_of_match[] = {
365 + { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
366 + { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
369 MODULE_DEVICE_TABLE(of, mt7530_of_match);
370 @@ -1680,8 +1790,19 @@ mt7530_probe(struct mdio_device *mdiodev
371 /* Get the hardware identifier from the devicetree node.
372 * We will need it for some of the clock and regulator setup.
374 - priv->id = (unsigned int)(unsigned long)
375 - of_device_get_match_data(&mdiodev->dev);
376 + priv->info = of_device_get_match_data(&mdiodev->dev);
380 + /* Sanity check if these required device operstaions are filled
383 + if (!priv->info->setup || !priv->info->phy_read ||
384 + !priv->info->phy_write || !priv->info->phy_supported ||
385 + !priv->info->pad_setup || !priv->info->mac_setup)
388 + priv->id = priv->info->id;
390 if (priv->id == ID_MT7530) {
391 priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
392 Index: linux-5.4.43/drivers/net/dsa/mt7530.h
393 ===================================================================
394 --- linux-5.4.43.orig/drivers/net/dsa/mt7530.h
395 +++ linux-5.4.43/drivers/net/dsa/mt7530.h
397 #define MT7530_NUM_FDB_RECORDS 2048
398 #define MT7530_ALL_MEMBERS 0xff
405 @@ -447,6 +447,32 @@ static const char *p5_intf_modes(unsigne
409 +/* struct mt753x_info - This is the main data structure for holding the specific
410 + * part for each supported device
411 + * @setup: Holding the handler to a device initialization
412 + * @phy_read: Holding the way reading PHY port
413 + * @phy_write: Holding the way writing PHY port
414 + * @phy_supported: Check if the PHY type is being supported on a certain
416 + * @pad_setup: Holding the way setting up the bus pad for a certain MAC
418 + * @mac_setup: Holding the way setting up the PHY attribute for a
421 +struct mt753x_info {
424 + int (*setup)(struct dsa_switch *ds);
425 + int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
426 + int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val);
427 + bool (*phy_supported)(struct dsa_switch *ds, int port,
428 + const struct phylink_link_state *state);
429 + int (*pad_setup)(struct dsa_switch *ds,
430 + const struct phylink_link_state *state);
431 + int (*mac_setup)(struct dsa_switch *ds, int port, unsigned int mode,
432 + const struct phylink_link_state *state);
435 /* struct mt7530_priv - This is the main data structure for holding the state
437 * @dev: The device pointer
438 @@ -472,6 +498,7 @@ struct mt7530_priv {
439 struct regulator *core_pwr;
440 struct regulator *io_pwr;
441 struct gpio_desc *reset;
442 + const struct mt753x_info *info;
445 phy_interface_t p6_interface;