xref: /netbsd-src/sys/arch/mips/cavium/octeon_misc.c (revision 183889cba7f5563a43fd45def3b2e1a8611f85dc)
1*183889cbSandvar /*	$NetBSD: octeon_misc.c,v 1.2 2022/02/06 20:20:19 andvar Exp $	*/
27beb3ab7Ssimonb 
37beb3ab7Ssimonb /*-
47beb3ab7Ssimonb  * Copyright (c) 2020 The NetBSD Foundation, Inc.
57beb3ab7Ssimonb  * All rights reserved.
67beb3ab7Ssimonb  *
77beb3ab7Ssimonb  * This code is derived from software contributed to The NetBSD Foundation
87beb3ab7Ssimonb  * by Simon Burge.
97beb3ab7Ssimonb  *
107beb3ab7Ssimonb  * Redistribution and use in source and binary forms, with or without
117beb3ab7Ssimonb  * modification, are permitted provided that the following conditions
127beb3ab7Ssimonb  * are met:
137beb3ab7Ssimonb  * 1. Redistributions of source code must retain the above copyright
147beb3ab7Ssimonb  *    notice, this list of conditions and the following disclaimer.
157beb3ab7Ssimonb  * 2. Redistributions in binary form must reproduce the above copyright
167beb3ab7Ssimonb  *    notice, this list of conditions and the following disclaimer in the
177beb3ab7Ssimonb  *    documentation and/or other materials provided with the distribution.
187beb3ab7Ssimonb  *
197beb3ab7Ssimonb  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
207beb3ab7Ssimonb  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
217beb3ab7Ssimonb  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
227beb3ab7Ssimonb  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
237beb3ab7Ssimonb  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
247beb3ab7Ssimonb  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
257beb3ab7Ssimonb  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
267beb3ab7Ssimonb  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
277beb3ab7Ssimonb  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
287beb3ab7Ssimonb  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
297beb3ab7Ssimonb  * POSSIBILITY OF SUCH DAMAGE.
307beb3ab7Ssimonb  */
317beb3ab7Ssimonb 
327beb3ab7Ssimonb /*
337beb3ab7Ssimonb  * Copyright (c) 2009, 2010 Miodrag Vallat.
347beb3ab7Ssimonb  * Copyright (c) 2019 Visa Hankala.
357beb3ab7Ssimonb  *
367beb3ab7Ssimonb  * Permission to use, copy, modify, and distribute this software for any
377beb3ab7Ssimonb  * purpose with or without fee is hereby granted, provided that the above
387beb3ab7Ssimonb  * copyright notice and this permission notice appear in all copies.
397beb3ab7Ssimonb  *
407beb3ab7Ssimonb  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
417beb3ab7Ssimonb  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
427beb3ab7Ssimonb  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
437beb3ab7Ssimonb  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
447beb3ab7Ssimonb  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
457beb3ab7Ssimonb  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
467beb3ab7Ssimonb  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
477beb3ab7Ssimonb  */
487beb3ab7Ssimonb /*
497beb3ab7Ssimonb  * Copyright (c) 2003-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
507beb3ab7Ssimonb  *
517beb3ab7Ssimonb  * Redistribution and use in source and binary forms, with or without
527beb3ab7Ssimonb  * modification, are permitted provided that the following conditions
537beb3ab7Ssimonb  * are met:
547beb3ab7Ssimonb  * 1. Redistributions of source code must retain the above copyright
557beb3ab7Ssimonb  *    notice, this list of conditions and the following disclaimer.
567beb3ab7Ssimonb  * 2. Redistributions in binary form must reproduce the above copyright
577beb3ab7Ssimonb  *    notice, this list of conditions and the following disclaimer in the
587beb3ab7Ssimonb  *    documentation and/or other materials provided with the distribution.
597beb3ab7Ssimonb  *
607beb3ab7Ssimonb  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
617beb3ab7Ssimonb  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
627beb3ab7Ssimonb  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
637beb3ab7Ssimonb  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
647beb3ab7Ssimonb  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
657beb3ab7Ssimonb  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
667beb3ab7Ssimonb  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
677beb3ab7Ssimonb  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
687beb3ab7Ssimonb  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
697beb3ab7Ssimonb  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
707beb3ab7Ssimonb  * SUCH DAMAGE.
717beb3ab7Ssimonb  *
727beb3ab7Ssimonb  */
737beb3ab7Ssimonb 
747beb3ab7Ssimonb #include <sys/cdefs.h>
75*183889cbSandvar __KERNEL_RCSID(0, "$NetBSD: octeon_misc.c,v 1.2 2022/02/06 20:20:19 andvar Exp $");
767beb3ab7Ssimonb 
777beb3ab7Ssimonb #include <sys/param.h>
787beb3ab7Ssimonb 
797beb3ab7Ssimonb #include <mips/cavium/octeonreg.h>
807beb3ab7Ssimonb #include <mips/cavium/octeonvar.h>
817beb3ab7Ssimonb #include <mips/cavium/dev/octeon_ciureg.h>
827beb3ab7Ssimonb 
837beb3ab7Ssimonb int	octeon_core_ver;
847beb3ab7Ssimonb 
857beb3ab7Ssimonb /*
867beb3ab7Ssimonb  * Return the name of the CPU model we are running on.
877beb3ab7Ssimonb  * Side effect: sets the octeon_core_ver variable.
887beb3ab7Ssimonb  */
897beb3ab7Ssimonb const char *
octeon_cpu_model(mips_prid_t cpu_id)907beb3ab7Ssimonb octeon_cpu_model(mips_prid_t cpu_id)
917beb3ab7Ssimonb {
927beb3ab7Ssimonb 	const uint64_t fuse = octeon_xkphys_read_8(CIU_FUSE);
937beb3ab7Ssimonb 	const int numcores = popcount64(fuse);
947beb3ab7Ssimonb 	const int clock_mhz = curcpu()->ci_cpu_freq / 1000000;
957beb3ab7Ssimonb 	const char *family;
967beb3ab7Ssimonb 	const char *coremodel;
977beb3ab7Ssimonb 	bool tested;
987beb3ab7Ssimonb 	static char buf[sizeof("CNnnXX-NNNN (unverified)")] = {};
997beb3ab7Ssimonb 
1007beb3ab7Ssimonb 	if (buf[0] != 0)
1017beb3ab7Ssimonb 		return buf;		/* we've been here before */
1027beb3ab7Ssimonb 
1037beb3ab7Ssimonb 	/*
1047beb3ab7Ssimonb 	 * Don't print "pass X.Y", but if needed:
1057beb3ab7Ssimonb 	 *	passhi = ((cpu_id >> 3) & 7) + '0';
1067beb3ab7Ssimonb 	 *	passlo = (cpu_id & 7) + '0';
1077beb3ab7Ssimonb 	 * Note some chips use different representation for the pass number.
1087beb3ab7Ssimonb 	 */
1097beb3ab7Ssimonb 
1107beb3ab7Ssimonb #ifdef OCTEON_DEBUG
1117beb3ab7Ssimonb 	printf("cpuid = 0x%x\n", cpu_id);
1127beb3ab7Ssimonb #endif
1137beb3ab7Ssimonb 
1147beb3ab7Ssimonb 	switch (numcores) {
1157beb3ab7Ssimonb 	case  1: coremodel = "10"; break;
1167beb3ab7Ssimonb 	case  2: coremodel = "20"; break;
1177beb3ab7Ssimonb 	case  3: coremodel = "25"; break;
1187beb3ab7Ssimonb 	case  4: coremodel = "30"; break;
1197beb3ab7Ssimonb 	case  5: coremodel = "32"; break;
1207beb3ab7Ssimonb 	case  6: coremodel = "34"; break;
1217beb3ab7Ssimonb 	case  7: coremodel = "38"; break;
1227beb3ab7Ssimonb 	case  8: coremodel = "40"; break;
1237beb3ab7Ssimonb 	case  9: coremodel = "42"; break;
1247beb3ab7Ssimonb 	case 10: coremodel = "45"; break;
1257beb3ab7Ssimonb 	case 11: coremodel = "48"; break;
1267beb3ab7Ssimonb 	case 12: coremodel = "50"; break;
1277beb3ab7Ssimonb 	case 13: coremodel = "52"; break;
1287beb3ab7Ssimonb 	case 14: coremodel = "55"; break;
1297beb3ab7Ssimonb 	case 15: coremodel = "58"; break;
1307beb3ab7Ssimonb 	case 16: coremodel = "60"; break;
1317beb3ab7Ssimonb 	case 24: coremodel = "70"; break;
1327beb3ab7Ssimonb 	case 32: coremodel = "80"; break;
1337beb3ab7Ssimonb 	case 40: coremodel = "85"; break;
1347beb3ab7Ssimonb 	case 44: coremodel = "88"; break;
1357beb3ab7Ssimonb 	case 48: coremodel = "90"; break;
1367beb3ab7Ssimonb 	default:
1377beb3ab7Ssimonb 		coremodel = "XX"; break;
1387beb3ab7Ssimonb 	}
1397beb3ab7Ssimonb 
1407beb3ab7Ssimonb 	/*
1417beb3ab7Ssimonb          * Assume all CPU families haven't been tested unless explicitly
1427beb3ab7Ssimonb          * noted.  Sources of extra information for determining actual
1437beb3ab7Ssimonb          * CPU models include chip documentation and U-Boot source code.
1447beb3ab7Ssimonb 	 */
1457beb3ab7Ssimonb 	tested = false;
1467beb3ab7Ssimonb 
1477beb3ab7Ssimonb 	switch (MIPS_PRID_IMPL(cpu_id)) {
1487beb3ab7Ssimonb 	/* the order of these cases is the numeric value of MIPS_CNnnXX */
1497beb3ab7Ssimonb 	case MIPS_CN38XX:
1507beb3ab7Ssimonb 		family = "38";	/* XXX may also be family "36" or "37" */
1517beb3ab7Ssimonb 		octeon_core_ver = OCTEON_1;
1527beb3ab7Ssimonb 		break;
1537beb3ab7Ssimonb 	case MIPS_CN31XX:
1547beb3ab7Ssimonb 		family = "31";	/* XXX may also be model "3020" */
1557beb3ab7Ssimonb 		octeon_core_ver = OCTEON_1;
1567beb3ab7Ssimonb 		break;
1577beb3ab7Ssimonb 	case MIPS_CN30XX:
1587beb3ab7Ssimonb 		family = "30";	/* XXX half cache model is "3005" */
1597beb3ab7Ssimonb 		octeon_core_ver = OCTEON_1;
1607beb3ab7Ssimonb 		break;
1617beb3ab7Ssimonb 	case MIPS_CN58XX:
1627beb3ab7Ssimonb 		family = "58";
1637beb3ab7Ssimonb 		octeon_core_ver = OCTEON_PLUS;
1647beb3ab7Ssimonb 		break;
1657beb3ab7Ssimonb 	case MIPS_CN56XX:
1667beb3ab7Ssimonb 		family = "56";	/* XXX may also be family "54", "55" or "57" */
1677beb3ab7Ssimonb 		octeon_core_ver = OCTEON_PLUS;
1687beb3ab7Ssimonb 		break;
1697beb3ab7Ssimonb 	case MIPS_CN50XX:
1707beb3ab7Ssimonb 		family = "50";
1717beb3ab7Ssimonb 		octeon_core_ver = OCTEON_PLUS;
1727beb3ab7Ssimonb 		tested = true;
1737beb3ab7Ssimonb 		break;
1747beb3ab7Ssimonb 	case MIPS_CN52XX:
1757beb3ab7Ssimonb 		family = "52";	/* XXX may also be family "51" */
1767beb3ab7Ssimonb 		octeon_core_ver = OCTEON_PLUS;
1777beb3ab7Ssimonb 		break;
1787beb3ab7Ssimonb 	case MIPS_CN63XX:
1797beb3ab7Ssimonb 		family = "63";	/* XXX may also be family "62" */
1807beb3ab7Ssimonb 		octeon_core_ver = OCTEON_2;
1817beb3ab7Ssimonb 		break;
1827beb3ab7Ssimonb 	case MIPS_CN68XX:
1837beb3ab7Ssimonb 		family = "68";
1847beb3ab7Ssimonb 		octeon_core_ver = OCTEON_2;
1857beb3ab7Ssimonb 		break;
1867beb3ab7Ssimonb 	case MIPS_CN66XX:
1877beb3ab7Ssimonb 		family = "66";
1887beb3ab7Ssimonb 		octeon_core_ver = OCTEON_2;
1897beb3ab7Ssimonb 		break;
1907beb3ab7Ssimonb 	case MIPS_CN61XX:
1917beb3ab7Ssimonb 		family = "61";	/* XXX may also be family "60" */
1927beb3ab7Ssimonb 		octeon_core_ver = OCTEON_2;
1937beb3ab7Ssimonb 		break;
1947beb3ab7Ssimonb 	case MIPS_CN78XX:
1957beb3ab7Ssimonb 		family = "78";	/* XXX may also be family "76" or "77" */
1967beb3ab7Ssimonb 		octeon_core_ver = OCTEON_3;
1977beb3ab7Ssimonb 		break;
1987beb3ab7Ssimonb 	case MIPS_CN70XX:
1997beb3ab7Ssimonb 		family = "70";
2007beb3ab7Ssimonb 		if (octeon_xkphys_read_8(MIO_FUS_PDF) & MIO_FUS_PDF_IS_71XX)
2017beb3ab7Ssimonb 			family = "71";
2027beb3ab7Ssimonb 		octeon_core_ver = OCTEON_3;
2037beb3ab7Ssimonb 		tested = true;
2047beb3ab7Ssimonb 		break;
2057beb3ab7Ssimonb 	case MIPS_CN73XX:
2067beb3ab7Ssimonb 		family = "73";	/* XXX may also be family "72" */
2077beb3ab7Ssimonb 		octeon_core_ver = OCTEON_3;
2087beb3ab7Ssimonb 		tested = true;
2097beb3ab7Ssimonb 		break;
2107beb3ab7Ssimonb 	default:
211*183889cbSandvar 		panic("IMPL 0x%02x not implemented", MIPS_PRID_IMPL(cpu_id));
2127beb3ab7Ssimonb 	}
2137beb3ab7Ssimonb 
2147beb3ab7Ssimonb 	snprintf(buf, sizeof(buf), "CN%s%s-%d%s", family, coremodel,
2157beb3ab7Ssimonb 	    clock_mhz, tested ? "" : " (unverified)");
2167beb3ab7Ssimonb 
2177beb3ab7Ssimonb 	if (!tested)
2187beb3ab7Ssimonb 		printf(">>> model %s\n", buf);
2197beb3ab7Ssimonb 
2207beb3ab7Ssimonb 	return buf;
2217beb3ab7Ssimonb }
2227beb3ab7Ssimonb 
2237beb3ab7Ssimonb /*
2247beb3ab7Ssimonb  * Return the coprocessor clock speed (IO clock speed).
2257beb3ab7Ssimonb  *
2267beb3ab7Ssimonb  * Octeon I and Octeon Plus use the CPU core clock speed.
2277beb3ab7Ssimonb  * Octeon II and III use a configurable multiplier against
2287beb3ab7Ssimonb  * the PLL reference clock speed (50MHz).
2297beb3ab7Ssimonb  */
2307beb3ab7Ssimonb int
octeon_ioclock_speed(void)2317beb3ab7Ssimonb octeon_ioclock_speed(void)
2327beb3ab7Ssimonb {
2337beb3ab7Ssimonb 	u_int64_t mio_rst_boot, rst_boot;
2347beb3ab7Ssimonb 
2357beb3ab7Ssimonb 	switch (octeon_core_ver) {
2367beb3ab7Ssimonb 	case OCTEON_1:
2377beb3ab7Ssimonb 	case OCTEON_PLUS:
2387beb3ab7Ssimonb 		return curcpu()->ci_cpu_freq;
2397beb3ab7Ssimonb 	case OCTEON_2:
2407beb3ab7Ssimonb 		mio_rst_boot = octeon_xkphys_read_8(MIO_RST_BOOT);
2417beb3ab7Ssimonb 		return OCTEON_PLL_REF_CLK *
2427beb3ab7Ssimonb 		    __SHIFTOUT(mio_rst_boot, MIO_RST_BOOT_PNR_MUL);
2437beb3ab7Ssimonb 	case OCTEON_3:
2447beb3ab7Ssimonb 		rst_boot = octeon_xkphys_read_8(RST_BOOT);
2457beb3ab7Ssimonb 		return OCTEON_PLL_REF_CLK *
2467beb3ab7Ssimonb 		    __SHIFTOUT(rst_boot, RST_BOOT_PNR_MUL);
2477beb3ab7Ssimonb 	default:
2487beb3ab7Ssimonb 		panic("%s: unknown Octeon core type %d", __func__,
2497beb3ab7Ssimonb 		    octeon_core_ver);
2507beb3ab7Ssimonb 	}
2517beb3ab7Ssimonb }
2527beb3ab7Ssimonb 
2537beb3ab7Ssimonb /*
2547beb3ab7Ssimonb  * Initiate chip soft-reset.
2557beb3ab7Ssimonb  */
2567beb3ab7Ssimonb void
octeon_soft_reset(void)2577beb3ab7Ssimonb octeon_soft_reset(void)
2587beb3ab7Ssimonb {
2597beb3ab7Ssimonb 
2607beb3ab7Ssimonb 	/* XXX should invalidate caches, tlb, watchdog? */
2617beb3ab7Ssimonb 	switch (octeon_core_ver) {
2627beb3ab7Ssimonb 	case OCTEON_1:
2637beb3ab7Ssimonb 	case OCTEON_PLUS:
2647beb3ab7Ssimonb 	case OCTEON_2:
2657beb3ab7Ssimonb 		octeon_xkphys_write_8(CIU_SOFT_BIST, CIU_SOFT_BIST_SOFT_BIST);
2667beb3ab7Ssimonb 		octeon_xkphys_write_8(CIU_SOFT_RST, CIU_SOFT_RST_SOFT_RST);
2677beb3ab7Ssimonb 	case OCTEON_3:
2687beb3ab7Ssimonb 		octeon_xkphys_write_8(RST_SOFT_RST, CIU_SOFT_RST_SOFT_RST);
2697beb3ab7Ssimonb 	default:
2707beb3ab7Ssimonb 		panic("%s: unknown Octeon core type %d", __func__,
2717beb3ab7Ssimonb 		    octeon_core_ver);
2727beb3ab7Ssimonb 	}
2737beb3ab7Ssimonb }
274