xref: /linux/drivers/net/dsa/netc/netc_platform.c (revision a5ccb7f5e067eae23707a61e4fc5d6214b0e4777)
1187fbae0SWei Fang // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2187fbae0SWei Fang /*
3187fbae0SWei Fang  * NXP NETC switch driver
4187fbae0SWei Fang  * Copyright 2025-2026 NXP
5187fbae0SWei Fang  */
6187fbae0SWei Fang 
7187fbae0SWei Fang #include "netc_switch.h"
8187fbae0SWei Fang 
9187fbae0SWei Fang struct netc_switch_platform {
10187fbae0SWei Fang 	u16 revision;
11187fbae0SWei Fang 	const struct netc_switch_info *info;
12187fbae0SWei Fang };
13187fbae0SWei Fang 
14bbe97e34SWei Fang static void imx94_switch_phylink_get_caps(int port,
15bbe97e34SWei Fang 					  struct phylink_config *config)
16bbe97e34SWei Fang {
17*a5ccb7f5SWei Fang 	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_1000FD;
18bbe97e34SWei Fang 
19bbe97e34SWei Fang 	switch (port) {
20bbe97e34SWei Fang 	case 0 ... 1:
21bbe97e34SWei Fang 		__set_bit(PHY_INTERFACE_MODE_SGMII,
22bbe97e34SWei Fang 			  config->supported_interfaces);
23bbe97e34SWei Fang 		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
24bbe97e34SWei Fang 			  config->supported_interfaces);
25bbe97e34SWei Fang 		config->mac_capabilities |= MAC_2500FD;
26bbe97e34SWei Fang 		fallthrough;
27bbe97e34SWei Fang 	case 2:
28bbe97e34SWei Fang 		config->mac_capabilities |= MAC_10 | MAC_100;
29bbe97e34SWei Fang 		__set_bit(PHY_INTERFACE_MODE_MII,
30bbe97e34SWei Fang 			  config->supported_interfaces);
31bbe97e34SWei Fang 		__set_bit(PHY_INTERFACE_MODE_RMII,
32bbe97e34SWei Fang 			  config->supported_interfaces);
33bbe97e34SWei Fang 		/* Port 0 and 1 do not support REVMII */
34bbe97e34SWei Fang 		if (port == 2)
35bbe97e34SWei Fang 			__set_bit(PHY_INTERFACE_MODE_REVMII,
36bbe97e34SWei Fang 				  config->supported_interfaces);
37bbe97e34SWei Fang 
38bbe97e34SWei Fang 		phy_interface_set_rgmii(config->supported_interfaces);
39bbe97e34SWei Fang 		break;
40bbe97e34SWei Fang 	case 3: /* CPU port */
41bbe97e34SWei Fang 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
42bbe97e34SWei Fang 			  config->supported_interfaces);
43bbe97e34SWei Fang 		config->mac_capabilities |= MAC_10FD | MAC_100FD |
44bbe97e34SWei Fang 					    MAC_2500FD;
45bbe97e34SWei Fang 		break;
46bbe97e34SWei Fang 	default:
47bbe97e34SWei Fang 		break;
48bbe97e34SWei Fang 	}
49bbe97e34SWei Fang }
50bbe97e34SWei Fang 
51187fbae0SWei Fang static const struct netc_switch_info imx94_info = {
52187fbae0SWei Fang 	.num_ports = 4,
53bbe97e34SWei Fang 	.phylink_get_caps = imx94_switch_phylink_get_caps,
54187fbae0SWei Fang };
55187fbae0SWei Fang 
56187fbae0SWei Fang static const struct netc_switch_platform netc_platforms[] = {
57187fbae0SWei Fang 	{ .revision = NETC_SWITCH_REV_4_3, .info = &imx94_info, },
58187fbae0SWei Fang 	{ }
59187fbae0SWei Fang };
60187fbae0SWei Fang 
61187fbae0SWei Fang static const struct netc_switch_info *
62187fbae0SWei Fang netc_switch_get_info(struct netc_switch *priv)
63187fbae0SWei Fang {
64187fbae0SWei Fang 	int i;
65187fbae0SWei Fang 
66187fbae0SWei Fang 	/* Matching based on IP revision */
67187fbae0SWei Fang 	for (i = 0; i < ARRAY_SIZE(netc_platforms); i++) {
68187fbae0SWei Fang 		if (priv->revision == netc_platforms[i].revision)
69187fbae0SWei Fang 			return netc_platforms[i].info;
70187fbae0SWei Fang 	}
71187fbae0SWei Fang 
72187fbae0SWei Fang 	return NULL;
73187fbae0SWei Fang }
74187fbae0SWei Fang 
75187fbae0SWei Fang int netc_switch_platform_probe(struct netc_switch *priv)
76187fbae0SWei Fang {
77187fbae0SWei Fang 	const struct netc_switch_info *info = netc_switch_get_info(priv);
78187fbae0SWei Fang 
79187fbae0SWei Fang 	if (!info) {
80187fbae0SWei Fang 		dev_err(priv->dev, "Cannot find switch platform info\n");
81187fbae0SWei Fang 		return -EINVAL;
82187fbae0SWei Fang 	}
83187fbae0SWei Fang 
84187fbae0SWei Fang 	priv->info = info;
85187fbae0SWei Fang 
86187fbae0SWei Fang 	return 0;
87187fbae0SWei Fang }
88