637f9e3c58517dd5203781d6d0e360afad28ca23
[openwrt/staging/neocturne.git] /
1 From patchwork Tue Dec 10 08:14:38 2019
2 Content-Type: text/plain; charset="utf-8"
3 MIME-Version: 1.0
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;
13 helo=vger.kernel.org;
14 envelope-from=netdev-owner@vger.kernel.org;
15 receiver=<UNKNOWN>)
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;
35 d=mediatek.com; s=dk;
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
60 adding a new hardware
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>
66 MIME-Version: 1.0
67 X-MTK: N
68 Sender: netdev-owner@vger.kernel.org
69 Precedence: bulk
70 List-ID: <netdev.vger.kernel.org>
71 X-Mailing-List: netdev@vger.kernel.org
72
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.
77
78 The patch is done for ready adding a new hardware MT7531.
79
80 Signed-off-by: Landen Chao <landen.chao@mediatek.com>
81 Signed-off-by: Sean Wang <sean.wang@mediatek.com>
82 ---
83 drivers/net/dsa/mt7530.c | 231 +++++++++++++++++++++++++++++----------
84 drivers/net/dsa/mt7530.h | 29 ++++-
85 2 files changed, 203 insertions(+), 57 deletions(-)
86
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
92 }
93
94 static int
95 -mt7530_pad_clk_setup(struct dsa_switch *ds, int mode)
96 +mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t mode)
97 {
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)
101 return 0;
102 }
103
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)
107 +{
108 + struct mt7530_priv *priv = ds->priv;
109 +
110 + switch (port) {
111 + case 0: /* Internal phy */
112 + case 1:
113 + case 2:
114 + case 3:
115 + case 4:
116 + if (state->interface != PHY_INTERFACE_MODE_GMII)
117 + goto unsupported;
118 + break;
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)
123 + goto unsupported;
124 + break;
125 + case 6: /* 1st cpu port */
126 + if (state->interface != PHY_INTERFACE_MODE_RGMII &&
127 + state->interface != PHY_INTERFACE_MODE_TRGMII)
128 + goto unsupported;
129 + break;
130 + default:
131 + dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
132 + port);
133 + goto unsupported;
134 + }
135 +
136 + return true;
137 +
138 +unsupported:
139 + return false;
140 +}
141 +
142 +static bool mt753x_phy_supported(struct dsa_switch *ds, int port,
143 + const struct phylink_link_state *state)
144 +{
145 + struct mt7530_priv *priv = ds->priv;
146 +
147 + return priv->info->phy_supported(ds, port, state);
148 +}
149 +
150 +static int
151 +mt7530_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
152 +{
153 + struct mt7530_priv *priv = ds->priv;
154 +
155 + /* Setup TX circuit incluing relevant PAD and driving */
156 + mt7530_pad_clk_setup(ds, state->interface);
157 +
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.
162 + */
163 + mt7623_pad_clk_setup(ds);
164 + }
165 +
166 + return 0;
167 +}
168 +
169 +static int
170 +mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
171 +{
172 + struct mt7530_priv *priv = ds->priv;
173 +
174 + return priv->info->pad_setup(ds, state);
175 +}
176 +
177 +static int
178 +mt7530_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
179 + const struct phylink_link_state *state)
180 +{
181 + struct mt7530_priv *priv = ds->priv;
182 +
183 + /* Only need to setup port5. */
184 + if (port != 5)
185 + return 0;
186 +
187 + mt7530_setup_port5(priv->ds, state->interface);
188 +
189 + return 0;
190 +}
191 +
192 +static int mt753x_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
193 + const struct phylink_link_state *state)
194 +{
195 + struct mt7530_priv *priv = ds->priv;
196 +
197 + return priv->info->mac_setup(ds, port, mode, state);
198 +}
199 +
200 +static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port,
201 unsigned int mode,
202 const struct phylink_link_state *state)
203 {
204 struct mt7530_priv *priv = ds->priv;
205 u32 mcr_cur, mcr_new;
206
207 + if (!mt753x_phy_supported(ds, port, state))
208 + return;
209 +
210 switch (port) {
211 case 0: /* Internal phy */
212 case 1:
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)
216 break;
217 - if (!phy_interface_mode_is_rgmii(state->interface) &&
218 - state->interface != PHY_INTERFACE_MODE_MII &&
219 - state->interface != PHY_INTERFACE_MODE_GMII)
220 - return;
221 -
222 - mt7530_setup_port5(ds, state->interface);
223 + if (mt753x_mac_setup(ds, port, mode, state) < 0)
224 + goto unsupported;
225 break;
226 case 6: /* 1st cpu port */
227 if (priv->p6_interface == state->interface)
228 break;
229 -
230 - if (state->interface != PHY_INTERFACE_MODE_RGMII &&
231 - state->interface != PHY_INTERFACE_MODE_TRGMII)
232 - return;
233 -
234 - /* Setup TX circuit incluing relevant PAD and driving */
235 - mt7530_pad_clk_setup(ds, state->interface);
236 -
237 + mt753x_pad_setup(ds, state);
238 + if (mt753x_mac_setup(ds, port, mode, state) < 0)
239 + goto unsupported;
240 priv->p6_interface = state->interface;
241 break;
242 default:
243 @@ -1459,38 +1548,14 @@ static void mt7530_phylink_mac_link_up(s
244 mt7530_port_set_status(priv, port, 1);
245 }
246
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)
251 {
252 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
253
254 - switch (port) {
255 - case 0: /* Internal phy */
256 - case 1:
257 - case 2:
258 - case 3:
259 - case 4:
260 - if (state->interface != PHY_INTERFACE_MODE_NA &&
261 - state->interface != PHY_INTERFACE_MODE_GMII)
262 - goto unsupported;
263 - break;
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)
269 - goto unsupported;
270 - break;
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)
275 - goto unsupported;
276 - break;
277 - default:
278 - dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
279 -unsupported:
280 + if (state->interface != PHY_INTERFACE_MODE_NA &&
281 + !mt753x_phy_supported(ds, port, state)) {
282 linkmode_zero(supported);
283 return;
284 }
285 @@ -1609,12 +1674,36 @@ static int mt7530_set_mac_eee(struct dsa
286 return 0;
287 }
288
289 +static int
290 +mt753x_setup(struct dsa_switch *ds)
291 +{
292 + struct mt7530_priv *priv = ds->priv;
293 +
294 + return priv->info->setup(ds);
295 +}
296 +
297 +static int
298 +mt753x_phy_read(struct dsa_switch *ds, int port, int regnum)
299 +{
300 + struct mt7530_priv *priv = ds->priv;
301 +
302 + return priv->info->phy_read(ds, port, regnum);
303 +}
304 +
305 +static int
306 +mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
307 +{
308 + struct mt7530_priv *priv = ds->priv;
309 +
310 + return priv->info->phy_write(ds, port, regnum, val);
311 +}
312 +
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,
338 };
339
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[] = {
344 + [ID_MT7621] = {
345 + .id = ID_MT7621,
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,
352 + },
353 + [ID_MT7530] = {
354 + .id = ID_MT7530,
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,
361 + },
362 +};
363 +
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], },
367 { /* sentinel */ },
368 };
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.
373 */
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);
377 + if (!priv->info)
378 + return -EINVAL;
379 +
380 + /* Sanity check if these required device operstaions are filled
381 + * properly.
382 + */
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)
386 + return -EINVAL;
387 +
388 + priv->id = priv->info->id;
389
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
396 @@ -11,7 +11,7 @@
397 #define MT7530_NUM_FDB_RECORDS 2048
398 #define MT7530_ALL_MEMBERS 0xff
399
400 -enum {
401 +enum mt753x_id {
402 ID_MT7530 = 0,
403 ID_MT7621 = 1,
404 };
405 @@ -447,6 +447,32 @@ static const char *p5_intf_modes(unsigne
406 }
407 }
408
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
415 + * port
416 + * @pad_setup: Holding the way setting up the bus pad for a certain MAC
417 + * port
418 + * @mac_setup: Holding the way setting up the PHY attribute for a
419 + * certain MAC port
420 + */
421 +struct mt753x_info {
422 + enum mt753x_id id;
423 +
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);
433 +};
434 +
435 /* struct mt7530_priv - This is the main data structure for holding the state
436 * of the driver
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;
443 unsigned int id;
444 bool mcm;
445 phy_interface_t p6_interface;