1/* $NetBSD: octeon_misc.c,v 1.2 2022/02/06 20:20:19 andvar Exp $ */ 2 3/*- 4 * Copyright (c) 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Simon Burge. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * Copyright (c) 2009, 2010 Miodrag Vallat. 34 * Copyright (c) 2019 Visa Hankala. 35 * 36 * Permission to use, copy, modify, and distribute this software for any 37 * purpose with or without fee is hereby granted, provided that the above 38 * copyright notice and this permission notice appear in all copies. 39 * 40 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 41 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 42 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 43 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 44 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 45 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 46 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 47 */ 48/* 49 * Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) 50 * 51 * Redistribution and use in source and binary forms, with or without 52 * modification, are permitted provided that the following conditions 53 * are met: 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 61 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 62 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 64 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 */ 73 74#include <sys/cdefs.h> 75__KERNEL_RCSID(0, "$NetBSD: octeon_misc.c,v 1.2 2022/02/06 20:20:19 andvar Exp $"); 76 77#include <sys/param.h> 78 79#include <mips/cavium/octeonreg.h> 80#include <mips/cavium/octeonvar.h> 81#include <mips/cavium/dev/octeon_ciureg.h> 82 83int octeon_core_ver; 84 85/* 86 * Return the name of the CPU model we are running on. 87 * Side effect: sets the octeon_core_ver variable. 88 */ 89const char * 90octeon_cpu_model(mips_prid_t cpu_id) 91{ 92 const uint64_t fuse = octeon_xkphys_read_8(CIU_FUSE); 93 const int numcores = popcount64(fuse); 94 const int clock_mhz = curcpu()->ci_cpu_freq / 1000000; 95 const char *family; 96 const char *coremodel; 97 bool tested; 98 static char buf[sizeof("CNnnXX-NNNN (unverified)")] = {}; 99 100 if (buf[0] != 0) 101 return buf; /* we've been here before */ 102 103 /* 104 * Don't print "pass X.Y", but if needed: 105 * passhi = ((cpu_id >> 3) & 7) + '0'; 106 * passlo = (cpu_id & 7) + '0'; 107 * Note some chips use different representation for the pass number. 108 */ 109 110#ifdef OCTEON_DEBUG 111 printf("cpuid = 0x%x\n", cpu_id); 112#endif 113 114 switch (numcores) { 115 case 1: coremodel = "10"; break; 116 case 2: coremodel = "20"; break; 117 case 3: coremodel = "25"; break; 118 case 4: coremodel = "30"; break; 119 case 5: coremodel = "32"; break; 120 case 6: coremodel = "34"; break; 121 case 7: coremodel = "38"; break; 122 case 8: coremodel = "40"; break; 123 case 9: coremodel = "42"; break; 124 case 10: coremodel = "45"; break; 125 case 11: coremodel = "48"; break; 126 case 12: coremodel = "50"; break; 127 case 13: coremodel = "52"; break; 128 case 14: coremodel = "55"; break; 129 case 15: coremodel = "58"; break; 130 case 16: coremodel = "60"; break; 131 case 24: coremodel = "70"; break; 132 case 32: coremodel = "80"; break; 133 case 40: coremodel = "85"; break; 134 case 44: coremodel = "88"; break; 135 case 48: coremodel = "90"; break; 136 default: 137 coremodel = "XX"; break; 138 } 139 140 /* 141 * Assume all CPU families haven't been tested unless explicitly 142 * noted. Sources of extra information for determining actual 143 * CPU models include chip documentation and U-Boot source code. 144 */ 145 tested = false; 146 147 switch (MIPS_PRID_IMPL(cpu_id)) { 148 /* the order of these cases is the numeric value of MIPS_CNnnXX */ 149 case MIPS_CN38XX: 150 family = "38"; /* XXX may also be family "36" or "37" */ 151 octeon_core_ver = OCTEON_1; 152 break; 153 case MIPS_CN31XX: 154 family = "31"; /* XXX may also be model "3020" */ 155 octeon_core_ver = OCTEON_1; 156 break; 157 case MIPS_CN30XX: 158 family = "30"; /* XXX half cache model is "3005" */ 159 octeon_core_ver = OCTEON_1; 160 break; 161 case MIPS_CN58XX: 162 family = "58"; 163 octeon_core_ver = OCTEON_PLUS; 164 break; 165 case MIPS_CN56XX: 166 family = "56"; /* XXX may also be family "54", "55" or "57" */ 167 octeon_core_ver = OCTEON_PLUS; 168 break; 169 case MIPS_CN50XX: 170 family = "50"; 171 octeon_core_ver = OCTEON_PLUS; 172 tested = true; 173 break; 174 case MIPS_CN52XX: 175 family = "52"; /* XXX may also be family "51" */ 176 octeon_core_ver = OCTEON_PLUS; 177 break; 178 case MIPS_CN63XX: 179 family = "63"; /* XXX may also be family "62" */ 180 octeon_core_ver = OCTEON_2; 181 break; 182 case MIPS_CN68XX: 183 family = "68"; 184 octeon_core_ver = OCTEON_2; 185 break; 186 case MIPS_CN66XX: 187 family = "66"; 188 octeon_core_ver = OCTEON_2; 189 break; 190 case MIPS_CN61XX: 191 family = "61"; /* XXX may also be family "60" */ 192 octeon_core_ver = OCTEON_2; 193 break; 194 case MIPS_CN78XX: 195 family = "78"; /* XXX may also be family "76" or "77" */ 196 octeon_core_ver = OCTEON_3; 197 break; 198 case MIPS_CN70XX: 199 family = "70"; 200 if (octeon_xkphys_read_8(MIO_FUS_PDF) & MIO_FUS_PDF_IS_71XX) 201 family = "71"; 202 octeon_core_ver = OCTEON_3; 203 tested = true; 204 break; 205 case MIPS_CN73XX: 206 family = "73"; /* XXX may also be family "72" */ 207 octeon_core_ver = OCTEON_3; 208 tested = true; 209 break; 210 default: 211 panic("IMPL 0x%02x not implemented", MIPS_PRID_IMPL(cpu_id)); 212 } 213 214 snprintf(buf, sizeof(buf), "CN%s%s-%d%s", family, coremodel, 215 clock_mhz, tested ? "" : " (unverified)"); 216 217 if (!tested) 218 printf(">>> model %s\n", buf); 219 220 return buf; 221} 222 223/* 224 * Return the coprocessor clock speed (IO clock speed). 225 * 226 * Octeon I and Octeon Plus use the CPU core clock speed. 227 * Octeon II and III use a configurable multiplier against 228 * the PLL reference clock speed (50MHz). 229 */ 230int 231octeon_ioclock_speed(void) 232{ 233 u_int64_t mio_rst_boot, rst_boot; 234 235 switch (octeon_core_ver) { 236 case OCTEON_1: 237 case OCTEON_PLUS: 238 return curcpu()->ci_cpu_freq; 239 case OCTEON_2: 240 mio_rst_boot = octeon_xkphys_read_8(MIO_RST_BOOT); 241 return OCTEON_PLL_REF_CLK * 242 __SHIFTOUT(mio_rst_boot, MIO_RST_BOOT_PNR_MUL); 243 case OCTEON_3: 244 rst_boot = octeon_xkphys_read_8(RST_BOOT); 245 return OCTEON_PLL_REF_CLK * 246 __SHIFTOUT(rst_boot, RST_BOOT_PNR_MUL); 247 default: 248 panic("%s: unknown Octeon core type %d", __func__, 249 octeon_core_ver); 250 } 251} 252 253/* 254 * Initiate chip soft-reset. 255 */ 256void 257octeon_soft_reset(void) 258{ 259 260 /* XXX should invalidate caches, tlb, watchdog? */ 261 switch (octeon_core_ver) { 262 case OCTEON_1: 263 case OCTEON_PLUS: 264 case OCTEON_2: 265 octeon_xkphys_write_8(CIU_SOFT_BIST, CIU_SOFT_BIST_SOFT_BIST); 266 octeon_xkphys_write_8(CIU_SOFT_RST, CIU_SOFT_RST_SOFT_RST); 267 case OCTEON_3: 268 octeon_xkphys_write_8(RST_SOFT_RST, CIU_SOFT_RST_SOFT_RST); 269 default: 270 panic("%s: unknown Octeon core type %d", __func__, 271 octeon_core_ver); 272 } 273} 274