xref: /openbmc/linux/arch/mips/cavium-octeon/executive/cvmx-helper-board.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1af866496SDavid Daney /***********************license start***************
2af866496SDavid Daney  * Author: Cavium Networks
3af866496SDavid Daney  *
4af866496SDavid Daney  * Contact: support@caviumnetworks.com
5af866496SDavid Daney  * This file is part of the OCTEON SDK
6af866496SDavid Daney  *
7af866496SDavid Daney  * Copyright (c) 2003-2008 Cavium Networks
8af866496SDavid Daney  *
9af866496SDavid Daney  * This file is free software; you can redistribute it and/or modify
10af866496SDavid Daney  * it under the terms of the GNU General Public License, Version 2, as
11af866496SDavid Daney  * published by the Free Software Foundation.
12af866496SDavid Daney  *
13af866496SDavid Daney  * This file is distributed in the hope that it will be useful, but
14af866496SDavid Daney  * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15af866496SDavid Daney  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16af866496SDavid Daney  * NONINFRINGEMENT.  See the GNU General Public License for more
17af866496SDavid Daney  * details.
18af866496SDavid Daney  *
19af866496SDavid Daney  * You should have received a copy of the GNU General Public License
20af866496SDavid Daney  * along with this file; if not, write to the Free Software
21af866496SDavid Daney  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22af866496SDavid Daney  * or visit http://www.gnu.org/licenses/.
23af866496SDavid Daney  *
24af866496SDavid Daney  * This file may also be available under a different license from Cavium.
25af866496SDavid Daney  * Contact Cavium Networks for more information
26af866496SDavid Daney  ***********************license end**************************************/
27af866496SDavid Daney 
28af866496SDavid Daney /*
29af866496SDavid Daney  *
30af866496SDavid Daney  * Helper functions to abstract board specific data about
31af866496SDavid Daney  * network ports from the rest of the cvmx-helper files.
32af866496SDavid Daney  */
33af866496SDavid Daney 
342c0756d3SAaro Koskinen #include <linux/bug.h>
35af866496SDavid Daney #include <asm/octeon/octeon.h>
36af866496SDavid Daney #include <asm/octeon/cvmx-bootinfo.h>
37af866496SDavid Daney 
38af866496SDavid Daney #include <asm/octeon/cvmx-config.h>
39af866496SDavid Daney 
40af866496SDavid Daney #include <asm/octeon/cvmx-helper.h>
41af866496SDavid Daney #include <asm/octeon/cvmx-helper-util.h>
42af866496SDavid Daney #include <asm/octeon/cvmx-helper-board.h>
43af866496SDavid Daney 
44af866496SDavid Daney #include <asm/octeon/cvmx-gmxx-defs.h>
45af866496SDavid Daney #include <asm/octeon/cvmx-asxx-defs.h>
46af866496SDavid Daney 
4716df55ceSRandy Dunlap /*
48af866496SDavid Daney  * Return the MII PHY address associated with the given IPD
49af866496SDavid Daney  * port. A result of -1 means there isn't a MII capable PHY
50af866496SDavid Daney  * connected to this port. On chips supporting multiple MII
51af866496SDavid Daney  * busses the bus number is encoded in bits <15:8>.
52af866496SDavid Daney  *
53af866496SDavid Daney  * This function must be modified for every new Octeon board.
54af866496SDavid Daney  * Internally it uses switch statements based on the cvmx_sysinfo
55af866496SDavid Daney  * data to determine board types and revisions. It replies on the
56af866496SDavid Daney  * fact that every Octeon board receives a unique board type
57af866496SDavid Daney  * enumeration from the bootloader.
58af866496SDavid Daney  *
59af866496SDavid Daney  * @ipd_port: Octeon IPD port to get the MII address for.
60af866496SDavid Daney  *
61af866496SDavid Daney  * Returns MII PHY address and bus number or -1.
62af866496SDavid Daney  */
cvmx_helper_board_get_mii_address(int ipd_port)63af866496SDavid Daney int cvmx_helper_board_get_mii_address(int ipd_port)
64af866496SDavid Daney {
65af866496SDavid Daney 	switch (cvmx_sysinfo_get()->board_type) {
66af866496SDavid Daney 	case CVMX_BOARD_TYPE_SIM:
67af866496SDavid Daney 		/* Simulator doesn't have MII */
68af866496SDavid Daney 		return -1;
69af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBT3000:
70af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBT5800:
71af866496SDavid Daney 	case CVMX_BOARD_TYPE_THUNDER:
72af866496SDavid Daney 	case CVMX_BOARD_TYPE_NICPRO2:
73af866496SDavid Daney 		/* Interface 0 is SPI4, interface 1 is RGMII */
74af866496SDavid Daney 		if ((ipd_port >= 16) && (ipd_port < 20))
75af866496SDavid Daney 			return ipd_port - 16;
76af866496SDavid Daney 		else
77af866496SDavid Daney 			return -1;
78af866496SDavid Daney 	case CVMX_BOARD_TYPE_KODAMA:
79af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBH3100:
80af866496SDavid Daney 	case CVMX_BOARD_TYPE_HIKARI:
81af866496SDavid Daney 	case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
82af866496SDavid Daney 	case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
83af866496SDavid Daney 	case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
84af866496SDavid Daney 		/*
85af866496SDavid Daney 		 * Port 0 is WAN connected to a PHY, Port 1 is GMII
86af866496SDavid Daney 		 * connected to a switch
87af866496SDavid Daney 		 */
88af866496SDavid Daney 		if (ipd_port == 0)
89af866496SDavid Daney 			return 4;
90af866496SDavid Daney 		else if (ipd_port == 1)
91af866496SDavid Daney 			return 9;
92af866496SDavid Daney 		else
93af866496SDavid Daney 			return -1;
94af866496SDavid Daney 	case CVMX_BOARD_TYPE_NAC38:
95af866496SDavid Daney 		/* Board has 8 RGMII ports PHYs are 0-7 */
96af866496SDavid Daney 		if ((ipd_port >= 0) && (ipd_port < 4))
97af866496SDavid Daney 			return ipd_port;
98af866496SDavid Daney 		else if ((ipd_port >= 16) && (ipd_port < 20))
99af866496SDavid Daney 			return ipd_port - 16 + 4;
100af866496SDavid Daney 		else
101af866496SDavid Daney 			return -1;
102af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBH3000:
103af866496SDavid Daney 		/* Board has dual SPI4 and no PHYs */
104af866496SDavid Daney 		return -1;
105af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBH5200:
106af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBH5201:
107af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBT5200:
108ada11a33SDavid Daney 		/* Board has 2 management ports */
109ada11a33SDavid Daney 		if ((ipd_port >= CVMX_HELPER_BOARD_MGMT_IPD_PORT) &&
110ada11a33SDavid Daney 		    (ipd_port < (CVMX_HELPER_BOARD_MGMT_IPD_PORT + 2)))
111ada11a33SDavid Daney 			return ipd_port - CVMX_HELPER_BOARD_MGMT_IPD_PORT;
112af866496SDavid Daney 		/*
113af866496SDavid Daney 		 * Board has 4 SGMII ports. The PHYs start right after the MII
114af866496SDavid Daney 		 * ports MII0 = 0, MII1 = 1, SGMII = 2-5.
115af866496SDavid Daney 		 */
116af866496SDavid Daney 		if ((ipd_port >= 0) && (ipd_port < 4))
117af866496SDavid Daney 			return ipd_port + 2;
118af866496SDavid Daney 		else
119af866496SDavid Daney 			return -1;
120af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBH5600:
121af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBH5601:
122af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBH5610:
123ada11a33SDavid Daney 		/* Board has 1 management port */
124ada11a33SDavid Daney 		if (ipd_port == CVMX_HELPER_BOARD_MGMT_IPD_PORT)
125ada11a33SDavid Daney 			return 0;
126af866496SDavid Daney 		/*
127af866496SDavid Daney 		 * Board has 8 SGMII ports. 4 connect out, two connect
128af866496SDavid Daney 		 * to a switch, and 2 loop to each other
129af866496SDavid Daney 		 */
130af866496SDavid Daney 		if ((ipd_port >= 0) && (ipd_port < 4))
131af866496SDavid Daney 			return ipd_port + 1;
132af866496SDavid Daney 		else
133af866496SDavid Daney 			return -1;
134af866496SDavid Daney 	case CVMX_BOARD_TYPE_CUST_NB5:
135af866496SDavid Daney 		if (ipd_port == 2)
136af866496SDavid Daney 			return 4;
137af866496SDavid Daney 		else
138af866496SDavid Daney 			return -1;
139af866496SDavid Daney 	case CVMX_BOARD_TYPE_NIC_XLE_4G:
140af866496SDavid Daney 		/* Board has 4 SGMII ports. connected QLM3(interface 1) */
141af866496SDavid Daney 		if ((ipd_port >= 16) && (ipd_port < 20))
142af866496SDavid Daney 			return ipd_port - 16 + 1;
143af866496SDavid Daney 		else
144af866496SDavid Daney 			return -1;
145ada11a33SDavid Daney 	case CVMX_BOARD_TYPE_NIC_XLE_10G:
146ada11a33SDavid Daney 	case CVMX_BOARD_TYPE_NIC10E:
147ada11a33SDavid Daney 		return -1;
148ada11a33SDavid Daney 	case CVMX_BOARD_TYPE_NIC4E:
149ada11a33SDavid Daney 		if (ipd_port >= 0 && ipd_port <= 3)
150ada11a33SDavid Daney 			return (ipd_port + 0x1f) & 0x1f;
151ada11a33SDavid Daney 		else
152ada11a33SDavid Daney 			return -1;
153ada11a33SDavid Daney 	case CVMX_BOARD_TYPE_NIC2E:
154ada11a33SDavid Daney 		if (ipd_port >= 0 && ipd_port <= 1)
155ada11a33SDavid Daney 			return ipd_port + 1;
156ada11a33SDavid Daney 		else
157ada11a33SDavid Daney 			return -1;
158af866496SDavid Daney 	case CVMX_BOARD_TYPE_BBGW_REF:
159af866496SDavid Daney 		/*
160af866496SDavid Daney 		 * No PHYs are connected to Octeon, everything is
161af866496SDavid Daney 		 * through switch.
162af866496SDavid Daney 		 */
163af866496SDavid Daney 		return -1;
164af866496SDavid Daney 
165af866496SDavid Daney 	case CVMX_BOARD_TYPE_CUST_WSX16:
166af866496SDavid Daney 		if (ipd_port >= 0 && ipd_port <= 3)
167af866496SDavid Daney 			return ipd_port;
168af866496SDavid Daney 		else if (ipd_port >= 16 && ipd_port <= 19)
169af866496SDavid Daney 			return ipd_port - 16 + 4;
170af866496SDavid Daney 		else
171af866496SDavid Daney 			return -1;
172a135a9b5SAaro Koskinen 	case CVMX_BOARD_TYPE_UBNT_E100:
173a135a9b5SAaro Koskinen 		if (ipd_port >= 0 && ipd_port <= 2)
174a135a9b5SAaro Koskinen 			return 7 - ipd_port;
175a135a9b5SAaro Koskinen 		else
176a135a9b5SAaro Koskinen 			return -1;
177cef232ecSAaro Koskinen 	case CVMX_BOARD_TYPE_KONTRON_S1901:
178cef232ecSAaro Koskinen 		if (ipd_port == CVMX_HELPER_BOARD_MGMT_IPD_PORT)
179cef232ecSAaro Koskinen 			return 1;
180cef232ecSAaro Koskinen 		else
181cef232ecSAaro Koskinen 			return -1;
182cef232ecSAaro Koskinen 
183af866496SDavid Daney 	}
184af866496SDavid Daney 
185af866496SDavid Daney 	/* Some unknown board. Somebody forgot to update this function... */
186af866496SDavid Daney 	cvmx_dprintf
187af866496SDavid Daney 	    ("cvmx_helper_board_get_mii_address: Unknown board type %d\n",
188af866496SDavid Daney 	     cvmx_sysinfo_get()->board_type);
189af866496SDavid Daney 	return -1;
190af866496SDavid Daney }
191af866496SDavid Daney 
19216df55ceSRandy Dunlap /*
193af866496SDavid Daney  * This function is the board specific method of determining an
194af866496SDavid Daney  * ethernet ports link speed. Most Octeon boards have Marvell PHYs
195af866496SDavid Daney  * and are handled by the fall through case. This function must be
196af866496SDavid Daney  * updated for boards that don't have the normal Marvell PHYs.
197af866496SDavid Daney  *
198af866496SDavid Daney  * This function must be modified for every new Octeon board.
199af866496SDavid Daney  * Internally it uses switch statements based on the cvmx_sysinfo
200af866496SDavid Daney  * data to determine board types and revisions. It relies on the
201af866496SDavid Daney  * fact that every Octeon board receives a unique board type
202af866496SDavid Daney  * enumeration from the bootloader.
203af866496SDavid Daney  *
204af866496SDavid Daney  * @ipd_port: IPD input port associated with the port we want to get link
205af866496SDavid Daney  *		   status for.
206af866496SDavid Daney  *
207af866496SDavid Daney  * Returns The ports link status. If the link isn't fully resolved, this must
208af866496SDavid Daney  *	   return zero.
209af866496SDavid Daney  */
__cvmx_helper_board_link_get(int ipd_port)210f7d2bdcbSChris Packham union cvmx_helper_link_info __cvmx_helper_board_link_get(int ipd_port)
211af866496SDavid Daney {
212f7d2bdcbSChris Packham 	union cvmx_helper_link_info result;
213af866496SDavid Daney 
214*4c587a98SLadislav Michl 	WARN_ONCE(!octeon_is_simulation(),
2152c0756d3SAaro Koskinen 	     "Using deprecated link status - please update your DT");
2162c0756d3SAaro Koskinen 
217af866496SDavid Daney 	/* Unless we fix it later, all links are defaulted to down */
218af866496SDavid Daney 	result.u64 = 0;
219af866496SDavid Daney 
2201836c2b2SAaro Koskinen 	if (octeon_is_simulation()) {
221af866496SDavid Daney 		/* The simulator gives you a simulated 1Gbps full duplex link */
222af866496SDavid Daney 		result.s.link_up = 1;
223af866496SDavid Daney 		result.s.full_duplex = 1;
224af866496SDavid Daney 		result.s.speed = 1000;
225af866496SDavid Daney 		return result;
226af866496SDavid Daney 	}
227af866496SDavid Daney 
2280d19672eSAaro Koskinen 	if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
229af866496SDavid Daney 		   || OCTEON_IS_MODEL(OCTEON_CN58XX)
230af866496SDavid Daney 		   || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
231af866496SDavid Daney 		/*
232af866496SDavid Daney 		 * We don't have a PHY address, so attempt to use
233af866496SDavid Daney 		 * in-band status. It is really important that boards
234af866496SDavid Daney 		 * not supporting in-band status never get
235af866496SDavid Daney 		 * here. Reading broken in-band status tends to do bad
236af866496SDavid Daney 		 * things
237af866496SDavid Daney 		 */
238af866496SDavid Daney 		union cvmx_gmxx_rxx_rx_inbnd inband_status;
239af866496SDavid Daney 		int interface = cvmx_helper_get_interface_num(ipd_port);
240af866496SDavid Daney 		int index = cvmx_helper_get_interface_index_num(ipd_port);
241af866496SDavid Daney 		inband_status.u64 =
242af866496SDavid Daney 		    cvmx_read_csr(CVMX_GMXX_RXX_RX_INBND(index, interface));
243af866496SDavid Daney 
244af866496SDavid Daney 		result.s.link_up = inband_status.s.status;
245af866496SDavid Daney 		result.s.full_duplex = inband_status.s.duplex;
246af866496SDavid Daney 		switch (inband_status.s.speed) {
247af866496SDavid Daney 		case 0: /* 10 Mbps */
248af866496SDavid Daney 			result.s.speed = 10;
249af866496SDavid Daney 			break;
250af866496SDavid Daney 		case 1: /* 100 Mbps */
251af866496SDavid Daney 			result.s.speed = 100;
252af866496SDavid Daney 			break;
253af866496SDavid Daney 		case 2: /* 1 Gbps */
254af866496SDavid Daney 			result.s.speed = 1000;
255af866496SDavid Daney 			break;
256af866496SDavid Daney 		case 3: /* Illegal */
257af866496SDavid Daney 			result.u64 = 0;
258af866496SDavid Daney 			break;
259af866496SDavid Daney 		}
260af866496SDavid Daney 	} else {
261af866496SDavid Daney 		/*
262af866496SDavid Daney 		 * We don't have a PHY address and we don't have
263af866496SDavid Daney 		 * in-band status. There is no way to determine the
264af866496SDavid Daney 		 * link speed. Return down assuming this port isn't
265af866496SDavid Daney 		 * wired
266af866496SDavid Daney 		 */
267af866496SDavid Daney 		result.u64 = 0;
268af866496SDavid Daney 	}
269af866496SDavid Daney 
270af866496SDavid Daney 	/* If link is down, return all fields as zero. */
271af866496SDavid Daney 	if (!result.s.link_up)
272af866496SDavid Daney 		result.u64 = 0;
273af866496SDavid Daney 
274af866496SDavid Daney 	return result;
275af866496SDavid Daney }
276af866496SDavid Daney 
27716df55ceSRandy Dunlap /*
278af866496SDavid Daney  * This function is called by cvmx_helper_interface_probe() after it
279af866496SDavid Daney  * determines the number of ports Octeon can support on a specific
280af866496SDavid Daney  * interface. This function is the per board location to override
281af866496SDavid Daney  * this value. It is called with the number of ports Octeon might
282af866496SDavid Daney  * support and should return the number of actual ports on the
283af866496SDavid Daney  * board.
284af866496SDavid Daney  *
2855e1138c6SZhang Jiaming  * This function must be modified for every new Octeon board.
286af866496SDavid Daney  * Internally it uses switch statements based on the cvmx_sysinfo
2875e1138c6SZhang Jiaming  * data to determine board types and revisions. It relies on the
288af866496SDavid Daney  * fact that every Octeon board receives a unique board type
289af866496SDavid Daney  * enumeration from the bootloader.
290af866496SDavid Daney  *
291af866496SDavid Daney  * @interface: Interface to probe
292af866496SDavid Daney  * @supported_ports:
293af866496SDavid Daney  *		    Number of ports Octeon supports.
294af866496SDavid Daney  *
295af866496SDavid Daney  * Returns Number of ports the actual board supports. Many times this will
296af866496SDavid Daney  *	   simple be "support_ports".
297af866496SDavid Daney  */
__cvmx_helper_board_interface_probe(int interface,int supported_ports)298af866496SDavid Daney int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
299af866496SDavid Daney {
300af866496SDavid Daney 	switch (cvmx_sysinfo_get()->board_type) {
301af866496SDavid Daney 	case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
302af866496SDavid Daney 		if (interface == 0)
303af866496SDavid Daney 			return 2;
304af866496SDavid Daney 		break;
305af866496SDavid Daney 	case CVMX_BOARD_TYPE_BBGW_REF:
306af866496SDavid Daney 		if (interface == 0)
307af866496SDavid Daney 			return 2;
308af866496SDavid Daney 		break;
309af866496SDavid Daney 	case CVMX_BOARD_TYPE_NIC_XLE_4G:
310af866496SDavid Daney 		if (interface == 0)
311af866496SDavid Daney 			return 0;
312af866496SDavid Daney 		break;
313af866496SDavid Daney 		/* The 2nd interface on the EBH5600 is connected to the Marvel switch,
314af866496SDavid Daney 		   which we don't support. Disable ports connected to it */
315af866496SDavid Daney 	case CVMX_BOARD_TYPE_EBH5600:
316af866496SDavid Daney 		if (interface == 1)
317af866496SDavid Daney 			return 0;
318af866496SDavid Daney 		break;
319af866496SDavid Daney 	}
320af866496SDavid Daney 	return supported_ports;
321af866496SDavid Daney }
322af866496SDavid Daney 
32316df55ceSRandy Dunlap /*
324d617f9e9SDavid Daney  * Get the clock type used for the USB block based on board type.
325d617f9e9SDavid Daney  * Used by the USB code for auto configuration of clock type.
326d617f9e9SDavid Daney  *
327d617f9e9SDavid Daney  * Return USB clock type enumeration
328d617f9e9SDavid Daney  */
__cvmx_helper_board_usb_get_clock_type(void)329d617f9e9SDavid Daney enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void)
330d617f9e9SDavid Daney {
331d617f9e9SDavid Daney 	switch (cvmx_sysinfo_get()->board_type) {
332d617f9e9SDavid Daney 	case CVMX_BOARD_TYPE_BBGW_REF:
333d617f9e9SDavid Daney 	case CVMX_BOARD_TYPE_LANAI2_A:
334d617f9e9SDavid Daney 	case CVMX_BOARD_TYPE_LANAI2_U:
335d617f9e9SDavid Daney 	case CVMX_BOARD_TYPE_LANAI2_G:
336d617f9e9SDavid Daney 	case CVMX_BOARD_TYPE_NIC10E_66:
337d617f9e9SDavid Daney 	case CVMX_BOARD_TYPE_UBNT_E100:
338d617f9e9SDavid Daney 		return USB_CLOCK_TYPE_CRYSTAL_12;
339d617f9e9SDavid Daney 	case CVMX_BOARD_TYPE_NIC10E:
340d617f9e9SDavid Daney 		return USB_CLOCK_TYPE_REF_12;
341d617f9e9SDavid Daney 	default:
342d617f9e9SDavid Daney 		break;
343d617f9e9SDavid Daney 	}
344d617f9e9SDavid Daney 	/* Most boards except NIC10e use a 12MHz crystal */
345debe6a62SDavid Daney 	if (OCTEON_IS_OCTEON2())
346d617f9e9SDavid Daney 		return USB_CLOCK_TYPE_CRYSTAL_12;
347d617f9e9SDavid Daney 	return USB_CLOCK_TYPE_REF_48;
348d617f9e9SDavid Daney }
349