c4b117dcb748f21388cd5a4066df69e8500b45a4
[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 --- a/drivers/net/dsa/mt7530.c
88 +++ b/drivers/net/dsa/mt7530.c
89 @@ -373,7 +373,7 @@ mt7530_fdb_write(struct mt7530_priv *pri
90 }
91
92 static int
93 -mt7530_pad_clk_setup(struct dsa_switch *ds, int mode)
94 +mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t mode)
95 {
96 struct mt7530_priv *priv = ds->priv;
97 u32 ncpo1, ssc_delta, trgint, i, xtal;
98 @@ -1355,13 +1355,111 @@ mt7530_setup(struct dsa_switch *ds)
99 return 0;
100 }
101
102 -static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
103 +static bool mt7530_phy_supported(struct dsa_switch *ds, int port,
104 + const struct phylink_link_state *state)
105 +{
106 + struct mt7530_priv *priv = ds->priv;
107 +
108 + switch (port) {
109 + case 0: /* Internal phy */
110 + case 1:
111 + case 2:
112 + case 3:
113 + case 4:
114 + if (state->interface != PHY_INTERFACE_MODE_GMII)
115 + goto unsupported;
116 + break;
117 + case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
118 + if (!phy_interface_mode_is_rgmii(state->interface) &&
119 + state->interface != PHY_INTERFACE_MODE_MII &&
120 + state->interface != PHY_INTERFACE_MODE_GMII)
121 + goto unsupported;
122 + break;
123 + case 6: /* 1st cpu port */
124 + if (state->interface != PHY_INTERFACE_MODE_RGMII &&
125 + state->interface != PHY_INTERFACE_MODE_TRGMII)
126 + goto unsupported;
127 + break;
128 + default:
129 + dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
130 + port);
131 + goto unsupported;
132 + }
133 +
134 + return true;
135 +
136 +unsupported:
137 + return false;
138 +}
139 +
140 +static bool mt753x_phy_supported(struct dsa_switch *ds, int port,
141 + const struct phylink_link_state *state)
142 +{
143 + struct mt7530_priv *priv = ds->priv;
144 +
145 + return priv->info->phy_supported(ds, port, state);
146 +}
147 +
148 +static int
149 +mt7530_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
150 +{
151 + struct mt7530_priv *priv = ds->priv;
152 +
153 + /* Setup TX circuit incluing relevant PAD and driving */
154 + mt7530_pad_clk_setup(ds, state->interface);
155 +
156 + if (priv->id == ID_MT7530) {
157 + /* Setup RX circuit, relevant PAD and driving on the
158 + * host which must be placed after the setup on the
159 + * device side is all finished.
160 + */
161 + mt7623_pad_clk_setup(ds);
162 + }
163 +
164 + return 0;
165 +}
166 +
167 +static int
168 +mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
169 +{
170 + struct mt7530_priv *priv = ds->priv;
171 +
172 + return priv->info->pad_setup(ds, state);
173 +}
174 +
175 +static int
176 +mt7530_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
177 + const struct phylink_link_state *state)
178 +{
179 + struct mt7530_priv *priv = ds->priv;
180 +
181 + /* Only need to setup port5. */
182 + if (port != 5)
183 + return 0;
184 +
185 + mt7530_setup_port5(priv->ds, state->interface);
186 +
187 + return 0;
188 +}
189 +
190 +static int mt753x_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
191 + const struct phylink_link_state *state)
192 +{
193 + struct mt7530_priv *priv = ds->priv;
194 +
195 + return priv->info->mac_setup(ds, port, mode, state);
196 +}
197 +
198 +static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port,
199 unsigned int mode,
200 const struct phylink_link_state *state)
201 {
202 struct mt7530_priv *priv = ds->priv;
203 u32 mcr_cur, mcr_new;
204
205 + if (!mt753x_phy_supported(ds, port, state))
206 + return;
207 +
208 switch (port) {
209 case 0: /* Internal phy */
210 case 1:
211 @@ -1374,24 +1472,15 @@ static void mt7530_phylink_mac_config(st
212 case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
213 if (priv->p5_interface == state->interface)
214 break;
215 - if (!phy_interface_mode_is_rgmii(state->interface) &&
216 - state->interface != PHY_INTERFACE_MODE_MII &&
217 - state->interface != PHY_INTERFACE_MODE_GMII)
218 - return;
219 -
220 - mt7530_setup_port5(ds, state->interface);
221 + if (mt753x_mac_setup(ds, port, mode, state) < 0)
222 + goto unsupported;
223 break;
224 case 6: /* 1st cpu port */
225 if (priv->p6_interface == state->interface)
226 break;
227 -
228 - if (state->interface != PHY_INTERFACE_MODE_RGMII &&
229 - state->interface != PHY_INTERFACE_MODE_TRGMII)
230 - return;
231 -
232 - /* Setup TX circuit incluing relevant PAD and driving */
233 - mt7530_pad_clk_setup(ds, state->interface);
234 -
235 + mt753x_pad_setup(ds, state);
236 + if (mt753x_mac_setup(ds, port, mode, state) < 0)
237 + goto unsupported;
238 priv->p6_interface = state->interface;
239 break;
240 default:
241 @@ -1459,38 +1548,14 @@ static void mt7530_phylink_mac_link_up(s
242 mt7530_port_set_status(priv, port, 1);
243 }
244
245 -static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
246 +static void mt753x_phylink_validate(struct dsa_switch *ds, int port,
247 unsigned long *supported,
248 struct phylink_link_state *state)
249 {
250 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
251
252 - switch (port) {
253 - case 0: /* Internal phy */
254 - case 1:
255 - case 2:
256 - case 3:
257 - case 4:
258 - if (state->interface != PHY_INTERFACE_MODE_NA &&
259 - state->interface != PHY_INTERFACE_MODE_GMII)
260 - goto unsupported;
261 - break;
262 - case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
263 - if (state->interface != PHY_INTERFACE_MODE_NA &&
264 - !phy_interface_mode_is_rgmii(state->interface) &&
265 - state->interface != PHY_INTERFACE_MODE_MII &&
266 - state->interface != PHY_INTERFACE_MODE_GMII)
267 - goto unsupported;
268 - break;
269 - case 6: /* 1st cpu port */
270 - if (state->interface != PHY_INTERFACE_MODE_NA &&
271 - state->interface != PHY_INTERFACE_MODE_RGMII &&
272 - state->interface != PHY_INTERFACE_MODE_TRGMII)
273 - goto unsupported;
274 - break;
275 - default:
276 - dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
277 -unsupported:
278 + if (state->interface != PHY_INTERFACE_MODE_NA &&
279 + !mt753x_phy_supported(ds, port, state)) {
280 linkmode_zero(supported);
281 return;
282 }
283 @@ -1609,12 +1674,36 @@ static int mt7530_set_mac_eee(struct dsa
284 return 0;
285 }
286
287 +static int
288 +mt753x_setup(struct dsa_switch *ds)
289 +{
290 + struct mt7530_priv *priv = ds->priv;
291 +
292 + return priv->info->setup(ds);
293 +}
294 +
295 +static int
296 +mt753x_phy_read(struct dsa_switch *ds, int port, int regnum)
297 +{
298 + struct mt7530_priv *priv = ds->priv;
299 +
300 + return priv->info->phy_read(ds, port, regnum);
301 +}
302 +
303 +static int
304 +mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
305 +{
306 + struct mt7530_priv *priv = ds->priv;
307 +
308 + return priv->info->phy_write(ds, port, regnum, val);
309 +}
310 +
311 static const struct dsa_switch_ops mt7530_switch_ops = {
312 .get_tag_protocol = mtk_get_tag_protocol,
313 - .setup = mt7530_setup,
314 + .setup = mt753x_setup,
315 .get_strings = mt7530_get_strings,
316 - .phy_read = mt7530_phy_read,
317 - .phy_write = mt7530_phy_write,
318 + .phy_read = mt753x_phy_read,
319 + .phy_write = mt753x_phy_write,
320 .get_ethtool_stats = mt7530_get_ethtool_stats,
321 .get_sset_count = mt7530_get_sset_count,
322 .port_enable = mt7530_port_enable,
323 @@ -1631,18 +1720,39 @@ static const struct dsa_switch_ops mt753
324 .port_vlan_del = mt7530_port_vlan_del,
325 .port_mirror_add = mt7530_port_mirror_add,
326 .port_mirror_del = mt7530_port_mirror_del,
327 - .phylink_validate = mt7530_phylink_validate,
328 + .phylink_validate = mt753x_phylink_validate,
329 .phylink_mac_link_state = mt7530_phylink_mac_link_state,
330 - .phylink_mac_config = mt7530_phylink_mac_config,
331 + .phylink_mac_config = mt753x_phylink_mac_config,
332 .phylink_mac_link_down = mt7530_phylink_mac_link_down,
333 .phylink_mac_link_up = mt7530_phylink_mac_link_up,
334 .get_mac_eee = mt7530_get_mac_eee,
335 .set_mac_eee = mt7530_set_mac_eee,
336 };
337
338 -static const struct of_device_id mt7530_of_match[] = {
339 - { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },
340 - { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },
341 +static const struct mt753x_info mt753x_table[] = {
342 + [ID_MT7621] = {
343 + .id = ID_MT7621,
344 + .setup = mt7530_setup,
345 + .phy_read = mt7530_phy_read,
346 + .phy_write = mt7530_phy_write,
347 + .phy_supported = mt7530_phy_supported,
348 + .pad_setup = mt7530_pad_setup,
349 + .mac_setup = mt7530_mac_setup,
350 + },
351 + [ID_MT7530] = {
352 + .id = ID_MT7530,
353 + .setup = mt7530_setup,
354 + .phy_read = mt7530_phy_read,
355 + .phy_write = mt7530_phy_write,
356 + .phy_supported = mt7530_phy_supported,
357 + .pad_setup = mt7530_pad_setup,
358 + .mac_setup = mt7530_mac_setup,
359 + },
360 +};
361 +
362 + static const struct of_device_id mt7530_of_match[] = {
363 + { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
364 + { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
365 { /* sentinel */ },
366 };
367 MODULE_DEVICE_TABLE(of, mt7530_of_match);
368 @@ -1680,8 +1790,19 @@ mt7530_probe(struct mdio_device *mdiodev
369 /* Get the hardware identifier from the devicetree node.
370 * We will need it for some of the clock and regulator setup.
371 */
372 - priv->id = (unsigned int)(unsigned long)
373 - of_device_get_match_data(&mdiodev->dev);
374 + priv->info = of_device_get_match_data(&mdiodev->dev);
375 + if (!priv->info)
376 + return -EINVAL;
377 +
378 + /* Sanity check if these required device operstaions are filled
379 + * properly.
380 + */
381 + if (!priv->info->setup || !priv->info->phy_read ||
382 + !priv->info->phy_write || !priv->info->phy_supported ||
383 + !priv->info->pad_setup || !priv->info->mac_setup)
384 + return -EINVAL;
385 +
386 + priv->id = priv->info->id;
387
388 if (priv->id == ID_MT7530) {
389 priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
390 --- a/drivers/net/dsa/mt7530.h
391 +++ b/drivers/net/dsa/mt7530.h
392 @@ -11,7 +11,7 @@
393 #define MT7530_NUM_FDB_RECORDS 2048
394 #define MT7530_ALL_MEMBERS 0xff
395
396 -enum {
397 +enum mt753x_id {
398 ID_MT7530 = 0,
399 ID_MT7621 = 1,
400 };
401 @@ -447,6 +447,32 @@ static const char *p5_intf_modes(unsigne
402 }
403 }
404
405 +/* struct mt753x_info - This is the main data structure for holding the specific
406 + * part for each supported device
407 + * @setup: Holding the handler to a device initialization
408 + * @phy_read: Holding the way reading PHY port
409 + * @phy_write: Holding the way writing PHY port
410 + * @phy_supported: Check if the PHY type is being supported on a certain
411 + * port
412 + * @pad_setup: Holding the way setting up the bus pad for a certain MAC
413 + * port
414 + * @mac_setup: Holding the way setting up the PHY attribute for a
415 + * certain MAC port
416 + */
417 +struct mt753x_info {
418 + enum mt753x_id id;
419 +
420 + int (*setup)(struct dsa_switch *ds);
421 + int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
422 + int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val);
423 + bool (*phy_supported)(struct dsa_switch *ds, int port,
424 + const struct phylink_link_state *state);
425 + int (*pad_setup)(struct dsa_switch *ds,
426 + const struct phylink_link_state *state);
427 + int (*mac_setup)(struct dsa_switch *ds, int port, unsigned int mode,
428 + const struct phylink_link_state *state);
429 +};
430 +
431 /* struct mt7530_priv - This is the main data structure for holding the state
432 * of the driver
433 * @dev: The device pointer
434 @@ -472,6 +498,7 @@ struct mt7530_priv {
435 struct regulator *core_pwr;
436 struct regulator *io_pwr;
437 struct gpio_desc *reset;
438 + const struct mt753x_info *info;
439 unsigned int id;
440 bool mcm;
441 phy_interface_t p6_interface;