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