gt.c revision 1.30
1/* $NetBSD: gt.c,v 1.30 2021/08/07 16:19:13 thorpej Exp $ */ 2 3/* 4 * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed for the NetBSD Project by 18 * Allegro Networks, Inc., and Wasabi Systems, Inc. 19 * 4. The name of Allegro Networks, Inc. may not be used to endorse 20 * or promote products derived from this software without specific prior 21 * written permission. 22 * 5. The name of Wasabi Systems, Inc. may not be used to endorse 23 * or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND 27 * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 28 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC. 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40/* 41 * gt.c -- GT system controller driver 42 */ 43 44#include <sys/cdefs.h> 45__KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.30 2021/08/07 16:19:13 thorpej Exp $"); 46 47#include "opt_marvell.h" 48#include "gtmpsc.h" 49#include "opt_multiprocessor.h" 50#include "locators.h" 51 52#include <sys/param.h> 53#include <sys/bus.h> 54#include <sys/device.h> 55#include <sys/kernel.h> 56#include <sys/types.h> 57 58#include <dev/marvell/gtintrreg.h> 59#include <dev/marvell/gtsdmareg.h> 60#if NGTMPSC > 0 61#include <dev/marvell/gtmpscreg.h> 62#include <dev/marvell/gtmpscvar.h> 63#endif 64#include <dev/marvell/gtpcireg.h> 65#include <dev/marvell/gtreg.h> 66#include <dev/marvell/gtvar.h> 67#include <dev/marvell/marvellreg.h> 68#include <dev/marvell/marvellvar.h> 69 70#include <dev/pci/pcireg.h> 71 72#if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0) 73# error /* unqualified: configuration botch! */ 74#endif 75 76#define gt_read(sc,r) bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (r)) 77#define gt_write(sc,r,v) bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (r), (v)) 78 79 80static int gt_cfprint(void *, const char *); 81static int gt_cfsearch(device_t, cfdata_t, const int *, void *); 82static void gt_attach_peripherals(struct gt_softc *); 83 84#ifdef GT_DEVBUS 85static int gt_devbus_intr(void *); 86static void gt_devbus_intr_enb(struct gt_softc *); 87#endif 88#ifdef GT_ECC 89static int gt_ecc_intr(void *); 90static void gt_ecc_intr_enb(struct gt_softc *); 91#endif 92#if NGTMPSC > 0 93static void gt_sdma_intr_enb(struct gt_softc *); 94#endif 95#ifdef GT_COMM 96static int gt_comm_intr(void *); 97static void gt_comm_intr_enb(struct gt_softc *); 98#endif 99 100 101#ifdef GT_WATCHDOG 102static void gt_watchdog_init(struct gt_softc *); 103static void gt_watchdog_enable(struct gt_softc *); 104#ifndef GT_MPP_WATCHDOG 105static void gt_watchdog_disable(struct gt_softc *); 106#endif 107 108static struct gt_softc *gt_watchdog_sc = NULL; 109static int gt_watchdog_state = 0; 110#endif 111 112 113#define OFFSET_DEFAULT MVA_OFFSET_DEFAULT 114#define IRQ_DEFAULT MVA_IRQ_DEFAULT 115static const struct gt_dev { 116 int model; 117 const char *name; 118 int unit; 119 bus_size_t offset; 120 int irq; 121} gt_devs[] = { 122 { MARVELL_DISCOVERY, "gfec", 0, 0x0000, IRQ_DEFAULT }, 123 { MARVELL_DISCOVERY, "gtidmac", 0, 0x0000, 4 /*...7 */ }, 124 { MARVELL_DISCOVERY, "gtmpsc", 0, 0x8000, 40 }, 125 { MARVELL_DISCOVERY, "gtmpsc", 1, 0x9000, 42 }, 126 { MARVELL_DISCOVERY, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 127 { MARVELL_DISCOVERY, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 128 { MARVELL_DISCOVERY, "gttwsi", 0, 0xc000, 37 }, 129 { MARVELL_DISCOVERY, "obio", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 130 { MARVELL_DISCOVERY, "obio", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 131 { MARVELL_DISCOVERY, "obio", 2, OFFSET_DEFAULT, IRQ_DEFAULT }, 132 { MARVELL_DISCOVERY, "obio", 3, OFFSET_DEFAULT, IRQ_DEFAULT }, 133 { MARVELL_DISCOVERY, "obio", 4, OFFSET_DEFAULT, IRQ_DEFAULT }, 134 135 { MARVELL_DISCOVERY_II, "gtidmac", 0, 0x0000, 4 /*...7 */ }, 136 { MARVELL_DISCOVERY_II, "gtmpsc", 0, 0x8000, 40 }, 137 { MARVELL_DISCOVERY_II, "gtmpsc", 1, 0x9000, 42 }, 138 { MARVELL_DISCOVERY_II, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 139 { MARVELL_DISCOVERY_II, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 140 { MARVELL_DISCOVERY_II, "gttwsi", 0, 0xc000, 37 }, 141 { MARVELL_DISCOVERY_II, "mvgbec", 0, 0x0000, IRQ_DEFAULT }, 142 143 { MARVELL_DISCOVERY_III,"gtidmac", 0, 0x0000, 4 /*...7 */ }, 144 { MARVELL_DISCOVERY_III,"gtmpsc", 0, 0x8000, 40 }, 145 { MARVELL_DISCOVERY_III,"gtmpsc", 1, 0x9000, 42 }, 146 { MARVELL_DISCOVERY_III,"gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 147 { MARVELL_DISCOVERY_III,"gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 148 { MARVELL_DISCOVERY_III,"gttwsi", 0, 0xc000, 37 }, 149 { MARVELL_DISCOVERY_III,"mvgbec", 0, 0x0000, IRQ_DEFAULT }, 150 151#if 0 /* XXXXXX: from www.marvell.com */ 152 /* Discovery LT (Discovery Light) MV644[23]0 */ 153 { MARVELL_DISCOVERY_LT, "gtidmac", 0, 0x?000, ? /*...? */ }, 154 { MARVELL_DISCOVERY_LT, "gtmpsc", 0, 0x?000, ? }, 155 { MARVELL_DISCOVERY_LT, "gtmpsc", 1, 0x?000, ? }, 156 { MARVELL_DISCOVERY_LT, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 157 { MARVELL_DISCOVERY_LT, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 158 { MARVELL_DISCOVERY_LT, "gttwsi", 0, 0x?000, ? }, 159 { MARVELL_DISCOVERY_LT, "mvgbec", 0, 0x?000, IRQ_DEFAULT }, 160 161 /* Discovery V MV64560 */ 162 { MARVELL_DISCOVERY_V, "com", ?, 0x?0000, ? }, 163 { MARVELL_DISCOVERY_V, "ehci", 0, 0x?0000, ? }, 164 { MARVELL_DISCOVERY_V, "ehci", 1, 0x?0000, ? }, 165 { MARVELL_DISCOVERY_V, "gtidmac", 0, 0x?0000, ? /*...? */ }, 166 { MARVELL_DISCOVERY_V, "gtpci", 0, 0x?0000, IRQ_DEFAULT }, 167 { MARVELL_DISCOVERY_V, "gttwsi", 0, 0x?0000, ? }, 168 { MARVELL_DISCOVERY_V, "mvgbec", 0, 0x?0000, IRQ_DEFAULT }, 169 { MARVELL_DISCOVERY_V, "mvpex or gtpci?", 0, 0x?0000, IRQ_DEFAULT }, 170 { MARVELL_DISCOVERY_V, "obio", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 171 172 /* Discovery VI MV64660 */ 173 /* MV64560 + SATA? */ 174 { MARVELL_DISCOVERY_VI, "mvsata", 0, 0x?0000, ? }, 175#endif 176}; 177 178 179static int 180gt_cfprint(void *aux, const char *pnp) 181{ 182 struct marvell_attach_args *mva = aux; 183 184 if (pnp) 185 aprint_normal("%s at %s unit %d", 186 mva->mva_name, pnp, mva->mva_unit); 187 else { 188 if (mva->mva_unit != MVA_UNIT_DEFAULT) 189 aprint_normal(" unit %d", mva->mva_unit); 190 if (mva->mva_offset != MVA_OFFSET_DEFAULT) { 191 aprint_normal(" offset 0x%04x", mva->mva_offset); 192 if (mva->mva_size > 0) 193 aprint_normal("-0x%04x", 194 mva->mva_offset + mva->mva_size - 1); 195 } 196 if (mva->mva_irq != MVA_IRQ_DEFAULT) 197 aprint_normal(" irq %d", mva->mva_irq); 198 } 199 200 return UNCONF; 201} 202 203 204/* ARGSUSED */ 205static int 206gt_cfsearch(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 207{ 208 struct marvell_attach_args *mva = aux; 209 210 if (cf->cf_loc[GTCF_IRQ] != MVA_IRQ_DEFAULT) 211 mva->mva_irq = cf->cf_loc[GTCF_IRQ]; 212 213 return config_match(parent, cf, aux); 214} 215 216static void 217gt_attach_peripherals(struct gt_softc *sc) 218{ 219 struct marvell_attach_args mva; 220 int i; 221 222 for (i = 0; i < __arraycount(gt_devs); i++) { 223 if (gt_devs[i].model != sc->sc_model) 224 continue; 225 226 mva.mva_name = gt_devs[i].name; 227 mva.mva_model = sc->sc_model; 228 mva.mva_revision = sc->sc_rev; 229 mva.mva_iot = sc->sc_iot; 230 mva.mva_ioh = sc->sc_ioh; 231 mva.mva_unit = gt_devs[i].unit; 232 mva.mva_addr = sc->sc_addr; 233 mva.mva_offset = gt_devs[i].offset; 234 mva.mva_size = 0; 235 mva.mva_dmat = sc->sc_dmat; 236 mva.mva_irq = gt_devs[i].irq; 237 238 config_found(sc->sc_dev, &mva, gt_cfprint, 239 CFARGS(.submatch = gt_cfsearch)); 240 } 241} 242 243void 244gt_attach_common(struct gt_softc *gt) 245{ 246 uint32_t cpucfg, cpumode, cpumstr; 247#ifdef GT_DEBUG 248 uint32_t loaddr, hiaddr; 249#endif 250 251 gt_write(gt, GTPCI_CA(0), PCI_ID_REG); 252 gt->sc_model = PCI_PRODUCT(gt_read(gt, GTPCI_CD(0))); 253 gt_write(gt, GTPCI_CA(0), PCI_CLASS_REG); 254 gt->sc_rev = PCI_REVISION(gt_read(gt, GTPCI_CD(0))); 255 256 aprint_naive("\n"); 257 switch (gt->sc_model) { 258 case MARVELL_DISCOVERY: 259 aprint_normal(": GT-6426x%c Discovery\n", 260 (gt->sc_rev == MARVELL_DISCOVERY_REVA) ? 'A' : 'B'); 261 break; 262 case MARVELL_DISCOVERY_II: 263 aprint_normal(": MV6436x Discovery II\n"); 264 break; 265 266 case MARVELL_DISCOVERY_III: 267 aprint_normal(": MV6446x Discovery III\n"); 268 break; 269#if 0 270 case MARVELL_DISCOVERY_LT: 271 case MARVELL_DISCOVERY_V: 272 case MARVELL_DISCOVERY_VI: 273#endif 274 275 default: 276 aprint_normal(": type unknown\n"); break; 277 } 278 279 cpumode = gt_read(gt, GT_CPU_Mode); 280 aprint_normal_dev(gt->sc_dev, 281 "id %d", GT_CPUMode_MultiGTID_GET(cpumode)); 282 if (cpumode & GT_CPUMode_MultiGT) 283 aprint_normal (" (multi)"); 284 switch (GT_CPUMode_CPUType_GET(cpumode)) { 285 case 4: aprint_normal(", 60x bus"); break; 286 case 5: aprint_normal(", MPX bus"); break; 287 288 default: 289 aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode)); 290 break; 291 } 292 293 cpumstr = gt_read(gt, GT_CPU_Master_Ctl); 294 switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) { 295 case 0: break; 296 case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break; 297 case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break; 298 case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock: 299 aprint_normal(", snoop=clean&flush"); break; 300 } 301 aprint_normal(" wdog=%#x,%#x\n", 302 gt_read(gt, GT_WDOG_Config), gt_read(gt, GT_WDOG_Value)); 303 304#ifdef GT_DEBUG 305 loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS0_Low_Decode), gt->sc_model); 306 hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS0_High_Decode), gt->sc_model); 307 aprint_normal_dev(gt->sc_dev, " scs[0]=%#10x-%#10x\n", 308 loaddr, hiaddr); 309 310 loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS1_Low_Decode), gt->sc_model); 311 hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS1_High_Decode), gt->sc_model); 312 aprint_normal_dev(gt->sc_dev, " scs[1]=%#10x-%#10x\n", 313 loaddr, hiaddr); 314 315 loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS2_Low_Decode), gt->sc_model); 316 hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS2_High_Decode), gt->sc_model); 317 aprint_normal_dev(gt->sc_dev, " scs[2]=%#10x-%#10x\n", 318 loaddr, hiaddr); 319 320 loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS3_Low_Decode), gt->sc_model); 321 hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS3_High_Decode), gt->sc_model); 322 aprint_normal_dev(gt->sc_dev, " scs[3]=%#10x-%#10x\n", 323 loaddr, hiaddr); 324 325 loaddr = GT_LADDR_GET(gt_read(gt, GT_CS0_Low_Decode), gt->sc_model); 326 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS0_High_Decode), gt->sc_model); 327 aprint_normal_dev(gt->sc_dev, " cs[0]=%#10x-%#10x\n", 328 loaddr, hiaddr); 329 330 loaddr = GT_LADDR_GET(gt_read(gt, GT_CS1_Low_Decode), gt->sc_model); 331 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS1_High_Decode), gt->sc_model); 332 aprint_normal_dev(gt->sc_dev, " cs[1]=%#10x-%#10x\n", 333 loaddr, hiaddr); 334 335 loaddr = GT_LADDR_GET(gt_read(gt, GT_CS2_Low_Decode), gt->sc_model); 336 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS2_High_Decode), gt->sc_model); 337 aprint_normal_dev(gt->sc_dev, " cs[2]=%#10x-%#10x\n", 338 loaddr, hiaddr); 339 340 loaddr = GT_LADDR_GET(gt_read(gt, GT_CS3_Low_Decode), gt->sc_model); 341 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS3_High_Decode), gt->sc_model); 342 aprint_normal_dev(gt->sc_dev, " cs[3]=%#10x-%#10x\n", 343 loaddr, hiaddr); 344 345 loaddr = GT_LADDR_GET(gt_read(gt, GT_BootCS_Low_Decode), gt->sc_model); 346 hiaddr = GT_HADDR_GET(gt_read(gt, GT_BootCS_High_Decode), gt->sc_model); 347 aprint_normal_dev(gt->sc_dev, " bootcs=%#10x-%#10x\n", 348 loaddr, hiaddr); 349 350 loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI0_IO_Low_Decode), gt->sc_model); 351 hiaddr = 352 GT_HADDR_GET(gt_read(gt, GT_PCI0_IO_High_Decode), gt->sc_model); 353 aprint_normal_dev(gt->sc_dev, " pci0io=%#10x-%#10x ", 354 loaddr, hiaddr); 355 356 loaddr = gt_read(gt, GT_PCI0_IO_Remap); 357 aprint_normal("remap=%#010x\n", loaddr); 358 359 loaddr = 360 GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode), gt->sc_model); 361 hiaddr = 362 GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode), gt->sc_model); 363 aprint_normal_dev(gt->sc_dev, " pci0mem[0]=%#10x-%#10x ", 364 loaddr, hiaddr); 365 366 loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low); 367 hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High); 368 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 369 370 loaddr = 371 GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode), gt->sc_model); 372 hiaddr = 373 GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode), gt->sc_model); 374 aprint_normal_dev(gt->sc_dev, " pci0mem[1]=%#10x-%#10x ", 375 loaddr, hiaddr); 376 377 loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low); 378 hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High); 379 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 380 381 loaddr = 382 GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode), gt->sc_model); 383 hiaddr = 384 GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode), gt->sc_model); 385 aprint_normal_dev(gt->sc_dev, " pci0mem[2]=%#10x-%#10x ", 386 loaddr, hiaddr); 387 388 loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low); 389 hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High); 390 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 391 392 loaddr = 393 GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode), gt->sc_model); 394 hiaddr = 395 GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode), gt->sc_model); 396 aprint_normal_dev(gt->sc_dev, " pci0mem[3]=%#10x-%#10x ", 397 loaddr, hiaddr); 398 399 loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low); 400 hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High); 401 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 402 403 loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI1_IO_Low_Decode), gt->sc_model); 404 hiaddr = 405 GT_HADDR_GET(gt_read(gt, GT_PCI1_IO_High_Decode), gt->sc_model); 406 aprint_normal_dev(gt->sc_dev, " pci1io=%#10x-%#10x ", 407 loaddr, hiaddr); 408 409 loaddr = gt_read(gt, GT_PCI1_IO_Remap); 410 aprint_normal("remap=%#010x\n", loaddr); 411 412 loaddr = 413 GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode), gt->sc_model); 414 hiaddr = 415 GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode), gt->sc_model); 416 aprint_normal_dev(gt->sc_dev, " pci1mem[0]=%#10x-%#10x ", 417 loaddr, hiaddr); 418 419 loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low); 420 hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High); 421 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 422 423 loaddr = 424 GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode), gt->sc_model); 425 hiaddr = 426 GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode), gt->sc_model); 427 aprint_normal_dev(gt->sc_dev, " pci1mem[1]=%#10x-%#10x ", 428 loaddr, hiaddr); 429 430 loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low); 431 hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High); 432 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 433 434 loaddr = 435 GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode), gt->sc_model); 436 hiaddr = 437 GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode), gt->sc_model); 438 aprint_normal_dev(gt->sc_dev, " pci1mem[2]=%#10x-%#10x ", 439 loaddr, hiaddr); 440 441 loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low); 442 hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High); 443 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 444 445 loaddr = 446 GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode), gt->sc_model); 447 hiaddr = 448 GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode), gt->sc_model); 449 aprint_normal_dev(gt->sc_dev, " pci1mem[3]=%#10x-%#10x ", 450 loaddr, hiaddr); 451 452 loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low); 453 hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High); 454 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 455 456 loaddr = GT_LADDR_GET(gt_read(gt, GT_Internal_Decode), gt->sc_model); 457 aprint_normal_dev(gt->sc_dev, " internal=%#10x-%#10x\n", 458 loaddr, loaddr + 256 * 1024); 459 460 loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU0_Low_Decode), gt->sc_model); 461 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU0_High_Decode), gt->sc_model); 462 aprint_normal_dev(gt->sc_dev, " cpu0=%#10x-%#10x\n", 463 loaddr, hiaddr); 464 465#ifdef MULTIPROCESSOR 466 loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU1_Low_Decode), gt->sc_model); 467 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU1_High_Decode), gt->sc_model); 468 aprint_normal_dev(gt->sc_dev, " cpu1=%#10x-%#10x", 469 loaddr, hiaddr); 470#endif 471#endif 472 473 aprint_normal("%s:", device_xname(gt->sc_dev)); 474 475 cpucfg = gt_read(gt, GT_CPU_Cfg); 476 cpucfg |= GT_CPUCfg_ConfSBDis; /* per errata #46 */ 477 cpucfg |= GT_CPUCfg_AACKDelay; /* per restriction #18 */ 478 gt_write(gt, GT_CPU_Cfg, cpucfg); 479 if (cpucfg & GT_CPUCfg_Pipeline) 480 aprint_normal(" pipeline"); 481 if (cpucfg & GT_CPUCfg_AACKDelay) 482 aprint_normal(" aack-delay"); 483 if (cpucfg & GT_CPUCfg_RdOOO) 484 aprint_normal(" read-ooo"); 485 if (cpucfg & GT_CPUCfg_IOSBDis) 486 aprint_normal(" io-sb-dis"); 487 if (cpucfg & GT_CPUCfg_ConfSBDis) 488 aprint_normal(" conf-sb-dis"); 489 if (cpucfg & GT_CPUCfg_ClkSync) 490 aprint_normal(" clk-sync"); 491 aprint_normal("\n"); 492 493#ifdef GT_WATCHDOG 494 gt_watchdog_init(gt); 495#endif 496 497#ifdef GT_DEVBUS 498 gt_devbus_intr_enb(gt); 499#endif 500#ifdef GT_ECC 501 gt_ecc_intr_enb(gt); 502#endif 503#if NGTMPSC > 0 504 gt_sdma_intr_enb(gt); 505#endif 506#ifdef GT_COMM 507 gt_comm_intr_enb(gt); 508#endif 509 510 gt_attach_peripherals(gt); 511 512#ifdef GT_WATCHDOG 513 gt_watchdog_service(); 514 gt_watchdog_enable(gt); 515#endif 516} 517 518 519#ifdef GT_DEVBUS 520static int 521gt_devbus_intr(void *arg) 522{ 523 struct gt_softc *gt = (struct gt_softc *)arg; 524 u_int32_t cause; 525 u_int32_t addr; 526 527 cause = gt_read(gt, GT_DEVBUS_ICAUSE); 528 addr = gt_read(gt, GT_DEVBUS_ERR_ADDR); 529 gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear intr */ 530 531 if (cause & GT_DEVBUS_DBurstErr) { 532 aprint_error_dev(gt->sc_dev, 533 "Device Bus error: burst violation"); 534 if ((cause & GT_DEVBUS_Sel) == 0) 535 aprint_error(", addr %#x", addr); 536 aprint_error("\n"); 537 } 538 if (cause & GT_DEVBUS_DRdyErr) { 539 aprint_error_dev(gt->sc_dev, 540 "Device Bus error: ready timer expired"); 541 if ((cause & GT_DEVBUS_Sel) != 0) 542 aprint_error(", addr %#x\n", addr); 543 aprint_error("\n"); 544 } 545 546 return cause != 0; 547} 548 549/* 550 * gt_devbus_intr_enb - enable GT-64260 Device Bus interrupts 551 */ 552static void 553gt_devbus_intr_enb(struct gt_softc *gt) 554{ 555 gt_write(gt, GT_DEVBUS_IMASK, 556 GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr); 557 (void)gt_read(gt, GT_DEVBUS_ERR_ADDR); /* clear addr */ 558 gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear intr */ 559 560 (void)marvell_intr_establish(IRQ_DEV, IPL_VM, gt_devbus_intr, gt); 561} 562#endif /* GT_DEVBUS */ 563 564#ifdef GT_ECC 565const static char *gt_ecc_intr_str[4] = { 566 "(none)", 567 "single bit", 568 "double bit", 569 "(reserved)" 570}; 571 572static int 573gt_ecc_intr(void *arg) 574{ 575 struct gt_softc *gt = (struct gt_softc *)arg; 576 uint32_t addr, dlo, dhi, rec, calc, count; 577 int err; 578 579 count = gt_read(gt, GT_ECC_Count); 580 dlo = gt_read(gt, GT_ECC_Data_Lo); 581 dhi = gt_read(gt, GT_ECC_Data_Hi); 582 rec = gt_read(gt, GT_ECC_Rec); 583 calc = gt_read(gt, GT_ECC_Calc); 584 addr = gt_read(gt, GT_ECC_Addr); /* read last! */ 585 gt_write(gt, GT_ECC_Addr, 0); /* clear intr */ 586 587 err = addr & 0x3; 588 589 aprint_error_dev(gt->sc_dev, 590 "ECC error: %s: addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n", 591 gt_ecc_intr_str[err], addr, dhi, dlo, rec, calc, count); 592 593 if (err == 2) 594 panic("ecc"); 595 596 return err == 1; 597} 598 599/* 600 * gt_ecc_intr_enb - enable GT-64260 ECC interrupts 601 */ 602static void 603gt_ecc_intr_enb(struct gt_softc *gt) 604{ 605 uint32_t ctl; 606 607 ctl = gt_read(gt, GT_ECC_Ctl); 608 ctl |= 1 << 16; /* XXX 1-bit threshold == 1 */ 609 gt_write(gt, GT_ECC_Ctl, ctl); 610 (void)gt_read(gt, GT_ECC_Data_Lo); 611 (void)gt_read(gt, GT_ECC_Data_Hi); 612 (void)gt_read(gt, GT_ECC_Rec); 613 (void)gt_read(gt, GT_ECC_Calc); 614 (void)gt_read(gt, GT_ECC_Addr); /* read last! */ 615 gt_write(gt, GT_ECC_Addr, 0); /* clear intr */ 616 617 (void)marvell_intr_establish(IRQ_ECC, IPL_VM, gt_ecc_intr, gt); 618} 619#endif /* GT_ECC */ 620 621#if NGTMPSC > 0 622/* 623 * gt_sdma_intr_enb - enable GT-64260 SDMA interrupts 624 */ 625static void 626gt_sdma_intr_enb(struct gt_softc *gt) 627{ 628 629 (void)marvell_intr_establish(IRQ_SDMA, IPL_SERIAL, gtmpsc_intr, gt); 630} 631#endif 632 633#ifdef GT_COMM 634/* 635 * unknown board, enable everything 636 */ 637# define GT_CommUnitIntr_DFLT \ 638 GT_CommUnitIntr_S0 |\ 639 GT_CommUnitIntr_S1 |\ 640 GT_CommUnitIntr_E0 |\ 641 GT_CommUnitIntr_E1 |\ 642 GT_CommUnitIntr_E2 643 644static const char * const gt_comm_subunit_name[8] = { 645 "ethernet 0", 646 "ethernet 1", 647 "ethernet 2", 648 "(reserved)", 649 "MPSC 0", 650 "MPSC 1", 651 "(reserved)", 652 "(sel)", 653}; 654 655static int 656gt_comm_intr(void *arg) 657{ 658 struct gt_softc *gt = (struct gt_softc *)arg; 659 uint32_t cause, addr; 660 unsigned int mask; 661 int i; 662 663 cause = gt_read(gt, GT_CommUnitIntr_Cause); 664 gt_write(gt, GT_CommUnitIntr_Cause, ~cause); 665 addr = gt_read(gt, GT_CommUnitIntr_ErrAddr); 666 667 aprint_error_dev(gt->sc_dev, 668 "Communications Unit Controller interrupt, cause %#x addr %#x\n", 669 cause, addr); 670 671 cause &= GT_CommUnitIntr_DFLT; 672 if (cause == 0) 673 return 0; 674 675 mask = 0x7; 676 for (i=0; i<7; i++) { 677 if (cause & mask) { 678 printf("%s: Comm Unit %s:", device_xname(gt->sc_dev), 679 gt_comm_subunit_name[i]); 680 if (cause & 1) 681 printf(" AddrMiss"); 682 if (cause & 2) 683 printf(" AccProt"); 684 if (cause & 4) 685 printf(" WrProt"); 686 printf("\n"); 687 } 688 cause >>= 4; 689 } 690 return 1; 691} 692 693/* 694 * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts 695 */ 696static void 697gt_comm_intr_enb(struct gt_softc *gt) 698{ 699 uint32_t cause; 700 701 cause = gt_read(gt, GT_CommUnitIntr_Cause); 702 if (cause) 703 gt_write(gt, GT_CommUnitIntr_Cause, ~cause); 704 gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT); 705 (void)gt_read(gt, GT_CommUnitIntr_ErrAddr); 706 707 (void)marvell_intr_establish(IRQ_COMM, IPL_VM, gt_comm_intr, gt); 708} 709#endif /* GT_COMM */ 710 711 712#ifdef GT_WATCHDOG 713#ifndef GT_MPP_WATCHDOG 714static void 715gt_watchdog_init(struct gt_softc *gt) 716{ 717 u_int32_t r; 718 719 aprint_normal_dev(gt->sc_dev, "watchdog"); 720 721 /* 722 * handle case where firmware started watchdog 723 */ 724 r = gt_read(gt, GT_WDOG_Config); 725 aprint_normal(" status %#x,%#x:", r, gt_read(gt, GT_WDOG_Value)); 726 if ((r & 0x80000000) != 0) { 727 gt_watchdog_sc = gt; /* enabled */ 728 gt_watchdog_state = 1; 729 aprint_normal(" firmware-enabled\n"); 730 gt_watchdog_disable(gt); 731 } else 732 aprint_normal(" firmware-disabled\n"); 733} 734 735#elif GT_MPP_WATCHDOG == 0 736 737static void 738gt_watchdog_init(struct gt_softc *gt) 739{ 740 741 aprint_normal_dev(gt->sc_dev, "watchdog not configured\n"); 742 return; 743} 744 745#else /* GT_MPP_WATCHDOG > 0 */ 746 747static void 748gt_watchdog_init(struct gt_softc *gt) 749{ 750 u_int32_t mpp_watchdog = GT_MPP_WATCHDOG; /* from config */ 751 u_int32_t cfgbits, mppbits, mppmask, regoff, r; 752 753 mppmask = 0; 754 755 aprint_normal_dev(gt->sc_dev, "watchdog"); 756 757 /* 758 * if firmware started watchdog, we disable and start 759 * from scratch to get it in a known state. 760 * 761 * on GT-64260A we always see 0xffffffff 762 * in both the GT_WDOG_Config_Enb and GT_WDOG_Value registers. 763 */ 764 r = gt_read(gt, GT_WDOG_Config); 765 if (r != ~0) { 766 if ((r & GT_WDOG_Config_Enb) != 0) { 767 gt_write(gt, GT_WDOG_Config, 768 GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 769 gt_write(gt, GT_WDOG_Config, 770 GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 771 } 772 } 773 774 /* 775 * "the watchdog timer can be activated only after 776 * configuring two MPP pins to act as WDE and WDNMI" 777 */ 778 mppbits = 0; 779 cfgbits = 0x3; 780 for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) { 781 if ((mpp_watchdog & cfgbits) == cfgbits) { 782 mppbits = 0x99; 783 mppmask = 0xff; 784 break; 785 } 786 cfgbits <<= 2; 787 if ((mpp_watchdog & cfgbits) == cfgbits) { 788 mppbits = 0x9900; 789 mppmask = 0xff00; 790 break; 791 } 792 cfgbits <<= 6; /* skip unqualified bits */ 793 } 794 if (mppbits == 0) { 795 aprint_error(" config error\n"); 796 return; 797 } 798 799 r = gt_read(gt, regoff); 800 r &= ~mppmask; 801 r |= mppbits; 802 gt_write(gt, regoff, r); 803 aprint_normal(" mpp %#x %#x", regoff, mppbits); 804 805 gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT); 806 807 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a|GT_WDOG_Preset_DFLT); 808 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b|GT_WDOG_Preset_DFLT); 809 810 r = gt_read(gt, GT_WDOG_Config); 811 aprint_normal(" status %#x,%#x: %s\n", 812 r, gt_read(gt, GT_WDOG_Value), 813 ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch"); 814} 815#endif /* GT_MPP_WATCHDOG */ 816 817static void 818gt_watchdog_enable(struct gt_softc *gt) 819{ 820 821 if (gt_watchdog_state == 0) { 822 gt_watchdog_state = 1; 823 824 gt_write(gt, GT_WDOG_Config, 825 GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 826 gt_write(gt, GT_WDOG_Config, 827 GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 828 } 829} 830 831#ifndef GT_MPP_WATCHDOG 832static void 833gt_watchdog_disable(struct gt_softc *gt) 834{ 835 836 if (gt_watchdog_state != 0) { 837 gt_watchdog_state = 0; 838 839 gt_write(gt, GT_WDOG_Config, 840 GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 841 gt_write(gt, GT_WDOG_Config, 842 GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 843 } 844} 845#endif 846 847/* 848 * XXXX: gt_watchdog_service/reset functions need mutex lock... 849 */ 850 851#ifdef GT_DEBUG 852int inhibit_watchdog_service = 0; 853#endif 854void 855gt_watchdog_service(void) 856{ 857 struct gt_softc *gt = gt_watchdog_sc; 858 859 if ((gt == NULL) || (gt_watchdog_state == 0)) 860 return; /* not enabled */ 861#ifdef GT_DEBUG 862 if (inhibit_watchdog_service) 863 return; 864#endif 865 866 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2a|GT_WDOG_Preset_DFLT); 867 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2b|GT_WDOG_Preset_DFLT); 868} 869 870/* 871 * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0 872 */ 873void 874gt_watchdog_reset(void) 875{ 876 struct gt_softc *gt = gt_watchdog_sc; 877 u_int32_t r; 878 879 r = gt_read(gt, GT_WDOG_Config); 880 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a); 881 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b); 882 if ((r & GT_WDOG_Config_Enb) != 0) { 883 /* 884 * was enabled, we just toggled it off, toggle on again 885 */ 886 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a); 887 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b); 888 } 889 for(;;); 890} 891#endif 892 893 894int 895marvell_winparams_by_tag(device_t dev, int tag, int *target, int *attr, 896 uint64_t *base, uint32_t *size) 897{ 898 static const struct { 899 int tag; 900 uint32_t attribute; 901 uint32_t basereg; 902 uint32_t sizereg; 903 } tagtbl[] = { 904 { MARVELL_TAG_SDRAM_CS0, MARVELL_ATTR_SDRAM_CS0, 905 GT_SCS0_Low_Decode, GT_SCS0_High_Decode }, 906 { MARVELL_TAG_SDRAM_CS1, MARVELL_ATTR_SDRAM_CS1, 907 GT_SCS1_Low_Decode, GT_SCS1_High_Decode }, 908 { MARVELL_TAG_SDRAM_CS2, MARVELL_ATTR_SDRAM_CS2, 909 GT_SCS2_Low_Decode, GT_SCS2_High_Decode }, 910 { MARVELL_TAG_SDRAM_CS3, MARVELL_ATTR_SDRAM_CS3, 911 GT_SCS3_Low_Decode, GT_SCS3_High_Decode }, 912 913 { MARVELL_TAG_UNDEFINED, 0, 0 } 914 }; 915 struct gt_softc *sc = device_private(dev); 916 int i; 917 918 for (i = 0; tagtbl[i].tag != MARVELL_TAG_UNDEFINED; i++) 919 if (tag == tagtbl[i].tag) 920 break; 921 if (tagtbl[i].tag == MARVELL_TAG_UNDEFINED) 922 return -1; 923 924 if (target != NULL) 925 *target = 0; 926 if (attr != NULL) 927 *attr = tagtbl[i].attribute; 928 if (base != NULL) 929 *base = gt_read(sc, tagtbl[i].basereg) << 930 (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16); 931 if (size != NULL) { 932 const uint32_t s = gt_read(sc, tagtbl[i].sizereg); 933 934 if (s != 0) 935 *size = (s + 1) << 936 (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16); 937 else 938 *size = 0; 939 } 940 941 return 0; 942} 943