1139825Simp/*- 286231Stmm * Copyright (c) 1999, 2000 Matthew R. Green 3117119Stmm * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org> 4167308Smarius * Copyright (c) 2005 - 2006 Marius Strobl <marius@FreeBSD.org> 586231Stmm * All rights reserved. 686231Stmm * 786231Stmm * Redistribution and use in source and binary forms, with or without 886231Stmm * modification, are permitted provided that the following conditions 986231Stmm * are met: 1086231Stmm * 1. Redistributions of source code must retain the above copyright 1186231Stmm * notice, this list of conditions and the following disclaimer. 1286231Stmm * 2. Redistributions in binary form must reproduce the above copyright 1386231Stmm * notice, this list of conditions and the following disclaimer in the 1486231Stmm * documentation and/or other materials provided with the distribution. 1586231Stmm * 3. The name of the author may not be used to endorse or promote products 1686231Stmm * derived from this software without specific prior written permission. 1786231Stmm * 1886231Stmm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1986231Stmm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2086231Stmm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2186231Stmm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2286231Stmm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2386231Stmm * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2486231Stmm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2586231Stmm * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2686231Stmm * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2786231Stmm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2886231Stmm * SUCH DAMAGE. 2986231Stmm * 3090617Stmm * from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp 3186231Stmm */ 3286231Stmm 33152696Smarius#include <sys/cdefs.h> 34152696Smarius__FBSDID("$FreeBSD$"); 35152696Smarius 3686231Stmm/* 37153052Smarius * Support for `Hummingbird' (UltraSPARC IIe), `Psycho' and `Psycho+' 38153052Smarius * (UltraSPARC II) and `Sabre' (UltraSPARC IIi) UPA to PCI bridges. 3986231Stmm */ 4086231Stmm 41117119Stmm#include "opt_ofw_pci.h" 4286231Stmm#include "opt_psycho.h" 4386231Stmm 4486231Stmm#include <sys/param.h> 4586231Stmm#include <sys/systm.h> 4686231Stmm#include <sys/bus.h> 47174117Smarius#include <sys/endian.h> 48131949Smarcel#include <sys/kdb.h> 4986231Stmm#include <sys/kernel.h> 50170851Smarius#include <sys/lock.h> 51167308Smarius#include <sys/malloc.h> 52130068Sphk#include <sys/module.h> 53170851Smarius#include <sys/mutex.h> 54107477Stmm#include <sys/pcpu.h> 55153055Smarius#include <sys/reboot.h> 56171730Smarius#include <sys/rman.h> 57247600Smarius#include <sys/sysctl.h> 5886231Stmm 59133589Smarius#include <dev/ofw/ofw_bus.h> 60133589Smarius#include <dev/ofw/ofw_pci.h> 61119338Simp#include <dev/ofw/openfirm.h> 6286231Stmm 6386231Stmm#include <machine/bus.h> 64167308Smarius#include <machine/bus_common.h> 65116541Stmm#include <machine/bus_private.h> 6686231Stmm#include <machine/iommureg.h> 67167308Smarius#include <machine/iommuvar.h> 6886231Stmm#include <machine/resource.h> 69152698Smarius#include <machine/ver.h> 7086231Stmm 71165886Smarius#include <dev/pci/pcireg.h> 72119291Simp#include <dev/pci/pcivar.h> 7386231Stmm 7486231Stmm#include <sparc64/pci/ofw_pci.h> 7586231Stmm#include <sparc64/pci/psychoreg.h> 7686231Stmm#include <sparc64/pci/psychovar.h> 7786231Stmm 7886231Stmm#include "pcib_if.h" 7986231Stmm 80152696Smariusstatic const struct psycho_desc *psycho_find_desc(const struct psycho_desc *, 81152696Smarius const char *); 82167308Smariusstatic const struct psycho_desc *psycho_get_desc(device_t); 83172066Smariusstatic void psycho_set_intr(struct psycho_softc *, u_int, bus_addr_t, 84247620Smarius driver_filter_t, driver_intr_t); 85172066Smariusstatic int psycho_find_intrmap(struct psycho_softc *, u_int, bus_addr_t *, 8690617Stmm bus_addr_t *, u_long *); 87220039Smariusstatic void sabre_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, 88220039Smarius bus_dmasync_op_t op); 89172066Smariusstatic void psycho_intr_enable(void *); 90172066Smariusstatic void psycho_intr_disable(void *); 91178443Smariusstatic void psycho_intr_assign(void *); 92178443Smariusstatic void psycho_intr_clear(void *); 9386231Stmm 9486231Stmm/* Interrupt handlers */ 95167308Smariusstatic driver_filter_t psycho_ue; 96167308Smariusstatic driver_filter_t psycho_ce; 97167308Smariusstatic driver_filter_t psycho_pci_bus; 98247600Smariusstatic driver_filter_t psycho_powerdebug; 99247620Smariusstatic driver_intr_t psycho_powerdown; 100247620Smariusstatic driver_intr_t psycho_overtemp; 10186231Stmm#ifdef PSYCHO_MAP_WAKEUP 102167308Smariusstatic driver_filter_t psycho_wakeup; 10386231Stmm#endif 10486231Stmm 10586231Stmm/* IOMMU support */ 106152698Smariusstatic void psycho_iommu_init(struct psycho_softc *, int, uint32_t); 10786231Stmm 10886231Stmm/* 109152696Smarius * Methods 11086231Stmm */ 111117119Stmmstatic device_probe_t psycho_probe; 112117119Stmmstatic device_attach_t psycho_attach; 113117119Stmmstatic bus_read_ivar_t psycho_read_ivar; 114117119Stmmstatic bus_setup_intr_t psycho_setup_intr; 115117119Stmmstatic bus_alloc_resource_t psycho_alloc_resource; 116117119Stmmstatic bus_activate_resource_t psycho_activate_resource; 117225931Smariusstatic bus_adjust_resource_t psycho_adjust_resource; 118167308Smariusstatic bus_get_dma_tag_t psycho_get_dma_tag; 119117119Stmmstatic pcib_maxslots_t psycho_maxslots; 120117119Stmmstatic pcib_read_config_t psycho_read_config; 121117119Stmmstatic pcib_write_config_t psycho_write_config; 122117119Stmmstatic pcib_route_interrupt_t psycho_route_interrupt; 123133589Smariusstatic ofw_bus_get_node_t psycho_get_node; 124220039Smariusstatic ofw_pci_setup_device_t psycho_setup_device; 12586231Stmm 12686231Stmmstatic device_method_t psycho_methods[] = { 12786231Stmm /* Device interface */ 12886231Stmm DEVMETHOD(device_probe, psycho_probe), 12986231Stmm DEVMETHOD(device_attach, psycho_attach), 130154870Smarius DEVMETHOD(device_shutdown, bus_generic_shutdown), 131154870Smarius DEVMETHOD(device_suspend, bus_generic_suspend), 132154870Smarius DEVMETHOD(device_resume, bus_generic_resume), 13386231Stmm 13486231Stmm /* Bus interface */ 13586231Stmm DEVMETHOD(bus_read_ivar, psycho_read_ivar), 136152696Smarius DEVMETHOD(bus_setup_intr, psycho_setup_intr), 137220039Smarius DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 13886231Stmm DEVMETHOD(bus_alloc_resource, psycho_alloc_resource), 139225931Smarius DEVMETHOD(bus_activate_resource, psycho_activate_resource), 140225931Smarius DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 141225931Smarius DEVMETHOD(bus_adjust_resource, psycho_adjust_resource), 142225931Smarius DEVMETHOD(bus_release_resource, bus_generic_release_resource), 143167308Smarius DEVMETHOD(bus_get_dma_tag, psycho_get_dma_tag), 14486231Stmm 14586231Stmm /* pcib interface */ 14686231Stmm DEVMETHOD(pcib_maxslots, psycho_maxslots), 14786231Stmm DEVMETHOD(pcib_read_config, psycho_read_config), 14886231Stmm DEVMETHOD(pcib_write_config, psycho_write_config), 14986231Stmm DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt), 15086231Stmm 151133589Smarius /* ofw_bus interface */ 152133589Smarius DEVMETHOD(ofw_bus_get_node, psycho_get_node), 153133589Smarius 154220039Smarius /* ofw_pci interface */ 155220039Smarius DEVMETHOD(ofw_pci_setup_device, psycho_setup_device), 156220039Smarius 157227843Smarius DEVMETHOD_END 15886231Stmm}; 15986231Stmm 16086231Stmmstatic devclass_t psycho_devclass; 16186231Stmm 162174117SmariusDEFINE_CLASS_0(pcib, psycho_driver, psycho_methods, 163174117Smarius sizeof(struct psycho_softc)); 164247600SmariusEARLY_DRIVER_MODULE(psycho, nexus, psycho_driver, psycho_devclass, NULL, NULL, 165215349Smarius BUS_PASS_BUS); 16686231Stmm 167247600Smariusstatic SYSCTL_NODE(_hw, OID_AUTO, psycho, CTLFLAG_RD, 0, "psycho parameters"); 168247600Smarius 169247600Smariusstatic u_int psycho_powerfail = 1; 170247600SmariusTUNABLE_INT("hw.psycho.powerfail", &psycho_powerfail); 171247600SmariusSYSCTL_UINT(_hw_psycho, OID_AUTO, powerfail, CTLFLAG_RDTUN, &psycho_powerfail, 172247600Smarius 0, "powerfail action (0: none, 1: shutdown (default), 2: debugger)"); 173247600Smarius 174170930Smariusstatic SLIST_HEAD(, psycho_softc) psycho_softcs = 175105274Stmm SLIST_HEAD_INITIALIZER(psycho_softcs); 17686231Stmm 177172066Smariusstatic const struct intr_controller psycho_ic = { 178172066Smarius psycho_intr_enable, 179172066Smarius psycho_intr_disable, 180178443Smarius psycho_intr_assign, 181178443Smarius psycho_intr_clear 18286231Stmm}; 18386231Stmm 184172066Smariusstruct psycho_icarg { 185172066Smarius struct psycho_softc *pica_sc; 186172066Smarius bus_addr_t pica_map; 187172066Smarius bus_addr_t pica_clr; 188172066Smarius}; 189172066Smarius 190206018Smarius#define PSYCHO_READ8(sc, off) \ 191170851Smarius bus_read_8((sc)->sc_mem_res, (off)) 192206018Smarius#define PSYCHO_WRITE8(sc, off, v) \ 193170851Smarius bus_write_8((sc)->sc_mem_res, (off), (v)) 194206018Smarius#define PCICTL_READ8(sc, off) \ 19590617Stmm PSYCHO_READ8((sc), (sc)->sc_pcictl + (off)) 196206018Smarius#define PCICTL_WRITE8(sc, off, v) \ 19790617Stmm PSYCHO_WRITE8((sc), (sc)->sc_pcictl + (off), (v)) 19890617Stmm 19986231Stmm/* 200152696Smarius * "Sabre" is the UltraSPARC IIi onboard UPA to PCI bridge. It manages a 20186231Stmm * single PCI bus and does not have a streaming buffer. It often has an APB 20286231Stmm * (advanced PCI bridge) connected to it, which was designed specifically for 203247914Sgavin * the IIi. The APB lets the IIi handle two independent PCI buses, and 204152696Smarius * appears as two "Simba"'s underneath the Sabre. 20586231Stmm * 206153052Smarius * "Hummingbird" is the UltraSPARC IIe onboard UPA to PCI bridge. It's 207153052Smarius * basically the same as Sabre but without an APB underneath it. 208153052Smarius * 209201199Smarius * "Psycho" and "Psycho+" are dual UPA to PCI bridges. They sit on the UPA 210201199Smarius * bus and manage two PCI buses. "Psycho" has two 64-bit 33MHz buses, while 211152696Smarius * "Psycho+" controls both a 64-bit 33Mhz and a 64-bit 66Mhz PCI bus. You 212152696Smarius * will usually find a "Psycho+" since I don't think the original "Psycho" 21388371Stmm * ever shipped, and if it did it would be in the U30. 21486231Stmm * 215152696Smarius * Each "Psycho" PCI bus appears as a separate OFW node, but since they are 21686231Stmm * both part of the same IC, they only have a single register space. As such, 21786231Stmm * they need to be configured together, even though the autoconfiguration will 21886231Stmm * attach them separately. 21986231Stmm * 220152696Smarius * On UltraIIi machines, "Sabre" itself usually takes pci0, with "Simba" often 22186231Stmm * as pci1 and pci2, although they have been implemented with other PCI bus 22286231Stmm * numbers on some machines. 22386231Stmm * 224152696Smarius * On UltraII machines, there can be any number of "Psycho+" ICs, each 22588371Stmm * providing two PCI buses. 22686231Stmm */ 227166901Spiso 228105283Stmmstruct psycho_desc { 229152696Smarius const char *pd_string; 230152696Smarius int pd_mode; 231152696Smarius const char *pd_name; 232105283Stmm}; 233105283Stmm 234242625Sdimstatic const struct psycho_desc psycho_compats[] = { 235105283Stmm { "pci108e,8000", PSYCHO_MODE_PSYCHO, "Psycho compatible" }, 236153052Smarius { "pci108e,a000", PSYCHO_MODE_SABRE, "Sabre compatible" }, 237153052Smarius { "pci108e,a001", PSYCHO_MODE_SABRE, "Hummingbird compatible" }, 238105283Stmm { NULL, 0, NULL } 239105283Stmm}; 240105283Stmm 241242625Sdimstatic const struct psycho_desc psycho_models[] = { 242105283Stmm { "SUNW,psycho", PSYCHO_MODE_PSYCHO, "Psycho" }, 243105283Stmm { "SUNW,sabre", PSYCHO_MODE_SABRE, "Sabre" }, 244105283Stmm { NULL, 0, NULL } 245105283Stmm}; 246105283Stmm 247152696Smariusstatic const struct psycho_desc * 248152696Smariuspsycho_find_desc(const struct psycho_desc *table, const char *string) 249105283Stmm{ 250152696Smarius const struct psycho_desc *desc; 251105283Stmm 252167308Smarius if (string == NULL) 253167308Smarius return (NULL); 254167308Smarius for (desc = table; desc->pd_string != NULL; desc++) 255105283Stmm if (strcmp(desc->pd_string, string) == 0) 256105283Stmm return (desc); 257105283Stmm return (NULL); 258105283Stmm} 259105283Stmm 260152696Smariusstatic const struct psycho_desc * 261167308Smariuspsycho_get_desc(device_t dev) 262105283Stmm{ 263152696Smarius const struct psycho_desc *rv; 264105283Stmm 265167308Smarius rv = psycho_find_desc(psycho_models, ofw_bus_get_model(dev)); 266167308Smarius if (rv == NULL) 267201199Smarius rv = psycho_find_desc(psycho_compats, 268201199Smarius ofw_bus_get_compat(dev)); 269105283Stmm return (rv); 270105283Stmm} 271105283Stmm 27286231Stmmstatic int 27386231Stmmpsycho_probe(device_t dev) 27486231Stmm{ 275152696Smarius const char *dtype; 27686231Stmm 277167308Smarius dtype = ofw_bus_get_type(dev); 278197164Smarius if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCI) == 0 && 279167308Smarius psycho_get_desc(dev) != NULL) { 28086231Stmm device_set_desc(dev, "U2P UPA-PCI bridge"); 28186231Stmm return (0); 28286231Stmm } 28386231Stmm return (ENXIO); 28486231Stmm} 28586231Stmm 28686231Stmmstatic int 28786231Stmmpsycho_attach(device_t dev) 28886231Stmm{ 289172066Smarius struct psycho_icarg *pica; 290165886Smarius struct psycho_softc *asc, *sc, *osc; 291153061Smarius struct ofw_pci_ranges *range; 292152696Smarius const struct psycho_desc *desc; 293172066Smarius bus_addr_t intrclr, intrmap; 294165886Smarius uint64_t csr, dr; 295220039Smarius phandle_t node; 296182110Smarius uint32_t dvmabase, prop, prop_array[2]; 297190109Smarius u_int rerun, ver; 298201199Smarius int i, j; 29986231Stmm 300167308Smarius node = ofw_bus_get_node(dev); 30186231Stmm sc = device_get_softc(dev); 302167308Smarius desc = psycho_get_desc(dev); 30386231Stmm 30486231Stmm sc->sc_node = node; 30586231Stmm sc->sc_dev = dev; 306105283Stmm sc->sc_mode = desc->pd_mode; 30786231Stmm 30886231Stmm /* 309152696Smarius * The Psycho gets three register banks: 31086231Stmm * (0) per-PBM configuration and status registers 31186231Stmm * (1) per-PBM PCI configuration space, containing only the 31286231Stmm * PBM 256-byte PCI header 313152696Smarius * (2) the shared Psycho configuration registers 31486231Stmm */ 31586231Stmm if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { 316190109Smarius i = 2; 317167308Smarius sc->sc_pcictl = 318167308Smarius bus_get_resource_start(dev, SYS_RES_MEMORY, 0) - 319167308Smarius bus_get_resource_start(dev, SYS_RES_MEMORY, 2); 320115417Stmm switch (sc->sc_pcictl) { 321115417Stmm case PSR_PCICTL0: 322115417Stmm sc->sc_half = 0; 323115417Stmm break; 324115417Stmm case PSR_PCICTL1: 325115417Stmm sc->sc_half = 1; 326115417Stmm break; 327115417Stmm default: 328152696Smarius panic("%s: bogus PCI control register location", 329152696Smarius __func__); 330182020Smarius /* NOTREACHED */ 331115417Stmm } 33286231Stmm } else { 333190109Smarius i = 0; 334115417Stmm sc->sc_pcictl = PSR_PCICTL0; 335115417Stmm sc->sc_half = 0; 33686231Stmm } 337190109Smarius sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, 338167308Smarius (sc->sc_mode == PSYCHO_MODE_PSYCHO ? RF_SHAREABLE : 0) | 339167308Smarius RF_ACTIVE); 340167308Smarius if (sc->sc_mem_res == NULL) 341167308Smarius panic("%s: could not allocate registers", __func__); 34286231Stmm 34386231Stmm /* 344190109Smarius * Match other Psychos that are already configured against 345178840Smarius * the base physical address. This will be the same for a 34686231Stmm * pair of devices that share register space. 34786231Stmm */ 348165886Smarius osc = NULL; 349105274Stmm SLIST_FOREACH(asc, &psycho_softcs, sc_link) { 350167308Smarius if (rman_get_start(asc->sc_mem_res) == 351167308Smarius rman_get_start(sc->sc_mem_res)) { 352152696Smarius /* Found partner. */ 353105274Stmm osc = asc; 354105274Stmm break; 355105274Stmm } 35686231Stmm } 357170851Smarius if (osc == NULL) { 358170851Smarius sc->sc_mtx = malloc(sizeof(*sc->sc_mtx), M_DEVBUF, 359170851Smarius M_NOWAIT | M_ZERO); 360170851Smarius if (sc->sc_mtx == NULL) 361170851Smarius panic("%s: could not malloc mutex", __func__); 362170851Smarius mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN); 363170851Smarius } else { 364190109Smarius if (sc->sc_mode != PSYCHO_MODE_PSYCHO) 365190109Smarius panic("%s: no partner expected", __func__); 366170851Smarius if (mtx_initialized(osc->sc_mtx) == 0) 367170851Smarius panic("%s: mutex not initialized", __func__); 368170851Smarius sc->sc_mtx = osc->sc_mtx; 369170851Smarius } 37086231Stmm 37190617Stmm csr = PSYCHO_READ8(sc, PSR_CS); 372165886Smarius ver = PSYCHO_GCSR_VERS(csr); 373172066Smarius sc->sc_ign = 0x1f; /* Hummingbird/Sabre IGN is always 0x1f. */ 37490617Stmm if (sc->sc_mode == PSYCHO_MODE_PSYCHO) 375172066Smarius sc->sc_ign = PSYCHO_GCSR_IGN(csr); 376182110Smarius if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1) 377182110Smarius prop = 33000000; 37890617Stmm 379182110Smarius device_printf(dev, 380182110Smarius "%s, impl %d, version %d, IGN %#x, bus %c, %dMHz\n", 381165886Smarius desc->pd_name, (u_int)PSYCHO_GCSR_IMPL(csr), ver, sc->sc_ign, 382182110Smarius 'A' + sc->sc_half, prop / 1000 / 1000); 38390617Stmm 384165886Smarius /* Set up the PCI control and PCI diagnostic registers. */ 385165886Smarius 38690617Stmm csr = PCICTL_READ8(sc, PCR_CS); 387165886Smarius csr &= ~PCICTL_ARB_PARK; 388220039Smarius if (OF_getproplen(node, "no-bus-parking") < 0) 389165886Smarius csr |= PCICTL_ARB_PARK; 390165886Smarius 391165886Smarius /* Workarounds for version specific bugs. */ 392165886Smarius dr = PCICTL_READ8(sc, PCR_DIAG); 393165886Smarius switch (ver) { 394165886Smarius case 0: 395165886Smarius dr |= DIAG_RTRY_DIS; 396165886Smarius dr &= ~DIAG_DWSYNC_DIS; 397190109Smarius rerun = 0; 398165886Smarius break; 399165886Smarius case 1: 400165886Smarius csr &= ~PCICTL_ARB_PARK; 401165886Smarius dr |= DIAG_RTRY_DIS | DIAG_DWSYNC_DIS; 402190109Smarius rerun = 0; 403165886Smarius break; 404165886Smarius default: 405165886Smarius dr |= DIAG_DWSYNC_DIS; 406165886Smarius dr &= ~DIAG_RTRY_DIS; 407190109Smarius rerun = 1; 408165886Smarius break; 409165886Smarius } 410165886Smarius 411183152Smarius csr |= PCICTL_ERRINTEN | PCICTL_ARB_4; 412165886Smarius csr &= ~(PCICTL_SBHINTEN | PCICTL_WAKEUPEN); 413165886Smarius#ifdef PSYCHO_DEBUG 414165886Smarius device_printf(dev, "PCI CSR 0x%016llx -> 0x%016llx\n", 415165886Smarius (unsigned long long)PCICTL_READ8(sc, PCR_CS), 416165886Smarius (unsigned long long)csr); 417165886Smarius#endif 41890617Stmm PCICTL_WRITE8(sc, PCR_CS, csr); 41986231Stmm 420165886Smarius dr &= ~DIAG_ISYNC_DIS; 421165886Smarius#ifdef PSYCHO_DEBUG 422165886Smarius device_printf(dev, "PCI DR 0x%016llx -> 0x%016llx\n", 423165886Smarius (unsigned long long)PCICTL_READ8(sc, PCR_DIAG), 424165886Smarius (unsigned long long)dr); 425165886Smarius#endif 426165886Smarius PCICTL_WRITE8(sc, PCR_DIAG, dr); 427165886Smarius 428108800Stmm if (sc->sc_mode == PSYCHO_MODE_SABRE) { 429128625Stmm /* Use the PROM preset for now. */ 430108800Stmm csr = PCICTL_READ8(sc, PCR_TAS); 431108800Stmm if (csr == 0) 432153052Smarius panic("%s: Hummingbird/Sabre TAS not initialized.", 433153052Smarius __func__); 434152698Smarius dvmabase = (ffs(csr) - 1) << PCITAS_ADDR_SHIFT; 435108800Stmm } else 436152698Smarius dvmabase = -1; 437108800Stmm 438152696Smarius /* Initialize memory and I/O rmans. */ 439152696Smarius sc->sc_pci_io_rman.rm_type = RMAN_ARRAY; 440152696Smarius sc->sc_pci_io_rman.rm_descr = "Psycho PCI I/O Ports"; 441152696Smarius if (rman_init(&sc->sc_pci_io_rman) != 0 || 442152696Smarius rman_manage_region(&sc->sc_pci_io_rman, 0, PSYCHO_IO_SIZE) != 0) 443152696Smarius panic("%s: failed to set up I/O rman", __func__); 444152696Smarius sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY; 445152696Smarius sc->sc_pci_mem_rman.rm_descr = "Psycho PCI Memory"; 446152696Smarius if (rman_init(&sc->sc_pci_mem_rman) != 0 || 447152696Smarius rman_manage_region(&sc->sc_pci_mem_rman, 0, PSYCHO_MEM_SIZE) != 0) 448152696Smarius panic("%s: failed to set up memory rman", __func__); 449128625Stmm 450201199Smarius i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range); 45186231Stmm /* 452178840Smarius * Make sure that the expected ranges are present. The 453178840Smarius * OFW_PCI_CS_MEM64 one is not currently used though. 454152698Smarius */ 455201199Smarius if (i != PSYCHO_NRANGE) 456152698Smarius panic("%s: unsupported number of ranges", __func__); 457152698Smarius /* 45886231Stmm * Find the addresses of the various bus spaces. 45986231Stmm * There should not be multiple ones of one kind. 46086231Stmm * The physical start addresses of the ranges are the configuration, 461152696Smarius * memory and I/O handles. 46286231Stmm */ 463201199Smarius for (i = 0; i < PSYCHO_NRANGE; i++) { 464201199Smarius j = OFW_PCI_RANGE_CS(&range[i]); 465201199Smarius if (sc->sc_pci_bh[j] != 0) 466201199Smarius panic("%s: duplicate range for space %d", 467201199Smarius __func__, j); 468201199Smarius sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]); 46986231Stmm } 470152698Smarius free(range, M_OFWPROP); 47186231Stmm 472152696Smarius /* Register the softc, this is needed for paired Psychos. */ 473105274Stmm SLIST_INSERT_HEAD(&psycho_softcs, sc, sc_link); 474105274Stmm 47586231Stmm /* 476172066Smarius * If we're a Hummingbird/Sabre or the first of a pair of Psychos 477172066Smarius * to arrive here, do the interrupt setup and start up the IOMMU. 478153055Smarius */ 47986231Stmm if (osc == NULL) { 48086231Stmm /* 481172066Smarius * Hunt through all the interrupt mapping regs and register 482172066Smarius * our interrupt controller for the corresponding interrupt 483190109Smarius * vectors. We do this early in order to be able to catch 484190109Smarius * stray interrupts. 485172066Smarius */ 486201199Smarius for (i = 0; i <= PSYCHO_MAX_INO; i++) { 487201199Smarius if (psycho_find_intrmap(sc, i, &intrmap, &intrclr, 488172066Smarius NULL) == 0) 489172066Smarius continue; 490172066Smarius pica = malloc(sizeof(*pica), M_DEVBUF, M_NOWAIT); 491172066Smarius if (pica == NULL) 492172066Smarius panic("%s: could not allocate interrupt " 493172066Smarius "controller argument", __func__); 494172066Smarius pica->pica_sc = sc; 495172066Smarius pica->pica_map = intrmap; 496172066Smarius pica->pica_clr = intrclr; 497172066Smarius#ifdef PSYCHO_DEBUG 498172066Smarius /* 499172066Smarius * Enable all interrupts and clear all interrupt 500178840Smarius * states. This aids the debugging of interrupt 501172066Smarius * routing problems. 502172066Smarius */ 503172066Smarius device_printf(dev, 504172066Smarius "intr map (INO %d, %s) %#lx: %#lx, clr: %#lx\n", 505201199Smarius i, intrmap <= PSR_PCIB3_INT_MAP ? "PCI" : "OBIO", 506201199Smarius (u_long)intrmap, (u_long)PSYCHO_READ8(sc, 507201199Smarius intrmap), (u_long)intrclr); 508201199Smarius PSYCHO_WRITE8(sc, intrmap, INTMAP_VEC(sc->sc_ign, i)); 509206018Smarius PSYCHO_WRITE8(sc, intrclr, INTCLR_IDLE); 510172066Smarius PSYCHO_WRITE8(sc, intrmap, 511201199Smarius INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, i), 512172066Smarius PCPU_GET(mid))); 513172066Smarius#endif 514201199Smarius j = intr_controller_register(INTMAP_VEC(sc->sc_ign, 515201199Smarius i), &psycho_ic, pica); 516201199Smarius if (j != 0) 517190109Smarius device_printf(dev, "could not register " 518190109Smarius "interrupt controller for INO %d (%d)\n", 519201199Smarius i, j); 520172066Smarius } 521172066Smarius 522190109Smarius if (sc->sc_mode == PSYCHO_MODE_PSYCHO) 523178840Smarius sparc64_counter_init(device_get_nameunit(dev), 524178840Smarius rman_get_bustag(sc->sc_mem_res), 525170851Smarius rman_get_bushandle(sc->sc_mem_res), PSR_TC0); 52690617Stmm 52786231Stmm /* 528165886Smarius * Set up IOMMU and PCI configuration if we're the first 529190109Smarius * of a pair of Psychos to arrive here or a Hummingbird 530190109Smarius * or Sabre. 53186231Stmm * 53286231Stmm * We should calculate a TSB size based on amount of RAM 533108470Sschweikh * and number of bus controllers and number and type of 53486231Stmm * child devices. 53586231Stmm * 53686231Stmm * For the moment, 32KB should be more than enough. 53786231Stmm */ 538220147Smarius sc->sc_is = malloc(sizeof(*sc->sc_is), M_DEVBUF, M_NOWAIT | 539220147Smarius M_ZERO); 54090617Stmm if (sc->sc_is == NULL) 541220147Smarius panic("%s: could not malloc IOMMU state", __func__); 542201395Smarius sc->sc_is->is_flags = IOMMU_PRESERVE_PROM; 543220039Smarius if (sc->sc_mode == PSYCHO_MODE_SABRE) { 544220147Smarius sc->sc_dma_methods = 545220147Smarius malloc(sizeof(*sc->sc_dma_methods), M_DEVBUF, 546220147Smarius M_NOWAIT); 547220147Smarius if (sc->sc_dma_methods == NULL) 548220147Smarius panic("%s: could not malloc DMA methods", 549220147Smarius __func__); 550220147Smarius memcpy(sc->sc_dma_methods, &iommu_dma_methods, 551220147Smarius sizeof(*sc->sc_dma_methods)); 552220147Smarius sc->sc_dma_methods->dm_dmamap_sync = 553220039Smarius sabre_dmamap_sync; 554171730Smarius sc->sc_is->is_pmaxaddr = 555171730Smarius IOMMU_MAXADDR(SABRE_IOMMU_BITS); 556220147Smarius } else { 557220147Smarius sc->sc_dma_methods = &iommu_dma_methods; 558171730Smarius sc->sc_is->is_pmaxaddr = 559171730Smarius IOMMU_MAXADDR(PSYCHO_IOMMU_BITS); 560220147Smarius } 561190109Smarius sc->sc_is->is_sb[0] = sc->sc_is->is_sb[1] = 0; 562152696Smarius if (OF_getproplen(node, "no-streaming-cache") < 0) 56390617Stmm sc->sc_is->is_sb[0] = sc->sc_pcictl + PCR_STRBUF; 564190109Smarius sc->sc_is->is_flags |= (rerun != 1) ? IOMMU_RERUN_DISABLE : 0; 565152698Smarius psycho_iommu_init(sc, 3, dvmabase); 56686231Stmm } else { 567153052Smarius /* Just copy IOMMU state, config tag and address. */ 568220147Smarius sc->sc_dma_methods = &iommu_dma_methods; 56986231Stmm sc->sc_is = osc->sc_is; 570152696Smarius if (OF_getproplen(node, "no-streaming-cache") < 0) 57190617Stmm sc->sc_is->is_sb[1] = sc->sc_pcictl + PCR_STRBUF; 57290617Stmm iommu_reset(sc->sc_is); 57386231Stmm } 57486231Stmm 575116213Stmm /* Allocate our tags. */ 576225931Smarius sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag( 577225931Smarius sc->sc_mem_res), PCI_IO_BUS_SPACE, NULL); 578225931Smarius if (sc->sc_pci_iot == NULL) 579225931Smarius panic("%s: could not allocate PCI I/O tag", __func__); 580225931Smarius sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag( 581225931Smarius sc->sc_mem_res), PCI_CONFIG_BUS_SPACE, NULL); 582225931Smarius if (sc->sc_pci_cfgt == NULL) 583225931Smarius panic("%s: could not allocate PCI configuration space tag", 584225931Smarius __func__); 585171730Smarius if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0, 586171730Smarius sc->sc_is->is_pmaxaddr, ~0, NULL, NULL, sc->sc_is->is_pmaxaddr, 587171730Smarius 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0) 588225931Smarius panic("%s: could not create PCI DMA tag", __func__); 589116213Stmm /* Customize the tag. */ 590152696Smarius sc->sc_pci_dmat->dt_cookie = sc->sc_is; 591220147Smarius sc->sc_pci_dmat->dt_mt = sc->sc_dma_methods; 592116213Stmm 593201199Smarius i = OF_getprop(node, "bus-range", (void *)prop_array, 594178279Smarius sizeof(prop_array)); 595201199Smarius if (i == -1) 596165886Smarius panic("%s: could not get bus-range", __func__); 597201199Smarius if (i != sizeof(prop_array)) 598201199Smarius panic("%s: broken bus-range (%d)", __func__, i); 599201395Smarius sc->sc_pci_secbus = prop_array[0]; 600201395Smarius sc->sc_pci_subbus = prop_array[1]; 601178279Smarius if (bootverbose) 602178279Smarius device_printf(dev, "bus range %u to %u; PCI bus %d\n", 603201395Smarius sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus); 60498148Stmm 605183152Smarius /* Clear any pending PCI error bits. */ 606178279Smarius PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, 607183152Smarius PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_pci_secbus, 608183152Smarius PCS_DEVICE, PCS_FUNC, PCIR_STATUS, 2), 2); 609183152Smarius PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS)); 610183152Smarius PCICTL_WRITE8(sc, PCR_AFS, PCICTL_READ8(sc, PCR_AFS)); 611165886Smarius 612183152Smarius if (osc == NULL) { 613183152Smarius /* 614183152Smarius * Establish handlers for interesting interrupts... 615183152Smarius * 616183152Smarius * XXX We need to remember these and remove this to support 617183152Smarius * hotplug on the UPA/FHC bus. 618183152Smarius * 619183152Smarius * XXX Not all controllers have these, but installing them 620183152Smarius * is better than trying to sort through this mess. 621183152Smarius */ 622247620Smarius psycho_set_intr(sc, 1, PSR_UE_INT_MAP, psycho_ue, NULL); 623247620Smarius psycho_set_intr(sc, 2, PSR_CE_INT_MAP, psycho_ce, NULL); 624247600Smarius switch (psycho_powerfail) { 625247600Smarius case 0: 626247600Smarius break; 627247600Smarius case 2: 628247600Smarius psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, 629247620Smarius psycho_powerdebug, NULL); 630247600Smarius break; 631247600Smarius default: 632247620Smarius psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, NULL, 633247600Smarius psycho_powerdown); 634247600Smarius break; 635247600Smarius } 636183152Smarius if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { 637183152Smarius /* 638183152Smarius * Hummingbirds/Sabres do not have the following two 639183152Smarius * interrupts. 640183152Smarius */ 641183152Smarius 642183152Smarius /* 643183152Smarius * The spare hardware interrupt is used for the 644183152Smarius * over-temperature interrupt. 645183152Smarius */ 646247620Smarius psycho_set_intr(sc, 4, PSR_SPARE_INT_MAP, NULL, 647247600Smarius psycho_overtemp); 648183152Smarius#ifdef PSYCHO_MAP_WAKEUP 649183152Smarius /* 650183152Smarius * psycho_wakeup() doesn't do anything useful right 651183152Smarius * now. 652183152Smarius */ 653183152Smarius psycho_set_intr(sc, 5, PSR_PWRMGT_INT_MAP, 654247620Smarius psycho_wakeup, NULL); 655183152Smarius#endif /* PSYCHO_MAP_WAKEUP */ 656183152Smarius } 657183152Smarius } 658165886Smarius /* 659183152Smarius * Register a PCI bus error interrupt handler according to which 660183152Smarius * half this is. Hummingbird/Sabre don't have a PCI bus B error 661183152Smarius * interrupt but they are also only used for PCI bus A. 662183152Smarius */ 663183152Smarius psycho_set_intr(sc, 0, sc->sc_half == 0 ? PSR_PCIAERR_INT_MAP : 664247620Smarius PSR_PCIBERR_INT_MAP, psycho_pci_bus, NULL); 665183152Smarius 666183152Smarius /* 667165886Smarius * Set the latency timer register as this isn't always done by the 668165886Smarius * firmware. 669165886Smarius */ 670178279Smarius PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, 671182020Smarius PCIR_LATTIMER, OFW_PCI_LATENCY, 1); 672165886Smarius 673201199Smarius for (i = PCIR_VENDOR; i < PCIR_STATUS; i += sizeof(uint16_t)) 674201199Smarius le16enc(&sc->sc_pci_hpbcfg[i], bus_space_read_2( 675174117Smarius sc->sc_pci_cfgt, sc->sc_pci_bh[OFW_PCI_CS_CONFIG], 676174117Smarius PSYCHO_CONF_OFF(sc->sc_pci_secbus, PCS_DEVICE, 677201199Smarius PCS_FUNC, i))); 678201199Smarius for (i = PCIR_REVID; i <= PCIR_BIST; i += sizeof(uint8_t)) 679201199Smarius sc->sc_pci_hpbcfg[i] = bus_space_read_1(sc->sc_pci_cfgt, 680174117Smarius sc->sc_pci_bh[OFW_PCI_CS_CONFIG], PSYCHO_CONF_OFF( 681201199Smarius sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, i)); 682174117Smarius 683152696Smarius ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t)); 684152698Smarius /* 685153052Smarius * On E250 the interrupt map entry for the EBus bridge is wrong, 686153052Smarius * causing incorrect interrupts to be assigned to some devices on 687178840Smarius * the EBus. Work around it by changing our copy of the interrupt 688178840Smarius * map mask to perform a full comparison of the INO. That way 689153052Smarius * the interrupt map entry for the EBus bridge won't match at all 690153052Smarius * and the INOs specified in the "interrupts" properties of the 691153052Smarius * EBus devices will be used directly instead. 692152698Smarius */ 693152698Smarius if (strcmp(sparc64_model, "SUNW,Ultra-250") == 0 && 694152698Smarius sc->sc_pci_iinfo.opi_imapmsk != NULL) 695152698Smarius *(ofw_pci_intr_t *)(&sc->sc_pci_iinfo.opi_imapmsk[ 696152698Smarius sc->sc_pci_iinfo.opi_addrc]) = INTMAP_INO_MASK; 697117119Stmm 698178279Smarius device_add_child(dev, "pci", -1); 69986231Stmm return (bus_generic_attach(dev)); 70086231Stmm} 70186231Stmm 70286231Stmmstatic void 703172066Smariuspsycho_set_intr(struct psycho_softc *sc, u_int index, bus_addr_t intrmap, 704247620Smarius driver_filter_t filt, driver_intr_t intr) 70586231Stmm{ 706172066Smarius u_long vec; 707170851Smarius int rid; 70886231Stmm 709153055Smarius rid = index; 710201199Smarius sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, 711201199Smarius SYS_RES_IRQ, &rid, RF_ACTIVE); 712190109Smarius if (sc->sc_irq_res[index] == NULL && intrmap >= PSR_POWER_INT_MAP) { 713190109Smarius /* 714190109Smarius * These interrupts aren't mandatory and not available 715190109Smarius * with all controllers (not even Psychos). 716190109Smarius */ 717190109Smarius return; 718190109Smarius } 719170851Smarius if (sc->sc_irq_res[index] == NULL || 720201199Smarius INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) != 721201199Smarius sc->sc_ign || 722172066Smarius INTVEC(PSYCHO_READ8(sc, intrmap)) != vec || 723172066Smarius intr_vectors[vec].iv_ic != &psycho_ic || 724190109Smarius bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], 725247620Smarius INTR_TYPE_MISC | INTR_BRIDGE, filt, intr, sc, 726190109Smarius &sc->sc_ihand[index]) != 0) 727170851Smarius panic("%s: failed to set up interrupt %d", __func__, index); 72886231Stmm} 72986231Stmm 73086231Stmmstatic int 731201199Smariuspsycho_find_intrmap(struct psycho_softc *sc, u_int ino, 732201199Smarius bus_addr_t *intrmapptr, bus_addr_t *intrclrptr, bus_addr_t *intrdiagptr) 73386231Stmm{ 734172066Smarius bus_addr_t intrclr, intrmap; 735172066Smarius uint64_t diag; 73686231Stmm int found; 73786231Stmm 738172066Smarius /* 739172066Smarius * XXX we only compare INOs rather than INRs since the firmware may 740172066Smarius * not provide the IGN and the IGN is constant for all devices on 741172066Smarius * that PCI controller. 742172066Smarius * This could cause problems for the FFB/external interrupt which 743172066Smarius * has a full vector that can be set arbitrarily. 744172066Smarius */ 745172066Smarius 746172066Smarius if (ino > PSYCHO_MAX_INO) { 747172066Smarius device_printf(sc->sc_dev, "out of range INO %d requested\n", 748172066Smarius ino); 749172066Smarius return (0); 750172066Smarius } 751172066Smarius 75286231Stmm found = 0; 753172066Smarius /* Hunt through OBIO first. */ 75490617Stmm diag = PSYCHO_READ8(sc, PSR_OBIO_INT_DIAG); 75590617Stmm for (intrmap = PSR_SCSI_INT_MAP, intrclr = PSR_SCSI_INT_CLR; 756172066Smarius intrmap <= PSR_PWRMGT_INT_MAP; intrmap += 8, intrclr += 8, 757167308Smarius diag >>= 2) { 758172066Smarius if (sc->sc_mode == PSYCHO_MODE_SABRE && 759172066Smarius (intrmap == PSR_TIMER0_INT_MAP || 760172066Smarius intrmap == PSR_TIMER1_INT_MAP || 761172066Smarius intrmap == PSR_PCIBERR_INT_MAP || 762172066Smarius intrmap == PSR_PWRMGT_INT_MAP)) 763172066Smarius continue; 764172066Smarius if (INTINO(PSYCHO_READ8(sc, intrmap)) == ino) { 76586231Stmm diag &= 2; 76686231Stmm found = 1; 76786231Stmm break; 76886231Stmm } 76986231Stmm } 77086231Stmm 77186231Stmm if (!found) { 77290617Stmm diag = PSYCHO_READ8(sc, PSR_PCI_INT_DIAG); 773153052Smarius /* Now do PCI interrupts. */ 77490617Stmm for (intrmap = PSR_PCIA0_INT_MAP, intrclr = PSR_PCIA0_INT_CLR; 775167308Smarius intrmap <= PSR_PCIB3_INT_MAP; intrmap += 8, intrclr += 32, 776167308Smarius diag >>= 8) { 777107476Stmm if (sc->sc_mode == PSYCHO_MODE_PSYCHO && 778107476Stmm (intrmap == PSR_PCIA2_INT_MAP || 779172066Smarius intrmap == PSR_PCIA3_INT_MAP)) 780107476Stmm continue; 781172066Smarius if (((PSYCHO_READ8(sc, intrmap) ^ ino) & 0x3c) == 0) { 78290617Stmm intrclr += 8 * (ino & 3); 78386231Stmm diag = (diag >> ((ino & 3) * 2)) & 2; 78486231Stmm found = 1; 78586231Stmm break; 78686231Stmm } 78786231Stmm } 78886231Stmm } 78986231Stmm if (intrmapptr != NULL) 79086231Stmm *intrmapptr = intrmap; 79186231Stmm if (intrclrptr != NULL) 79286231Stmm *intrclrptr = intrclr; 79386231Stmm if (intrdiagptr != NULL) 79486231Stmm *intrdiagptr = diag; 79586231Stmm return (found); 79686231Stmm} 79786231Stmm 79886231Stmm/* 799152696Smarius * Interrupt handlers 80086231Stmm */ 801166901Spisostatic int 80286231Stmmpsycho_ue(void *arg) 80386231Stmm{ 804152696Smarius struct psycho_softc *sc = arg; 805152696Smarius uint64_t afar, afsr; 80686231Stmm 80790617Stmm afar = PSYCHO_READ8(sc, PSR_UE_AFA); 80890617Stmm afsr = PSYCHO_READ8(sc, PSR_UE_AFS); 80993053Stmm /* 81093053Stmm * On the UltraSPARC-IIi/IIe, IOMMU misses/protection faults cause 81193053Stmm * the AFAR to be set to the physical address of the TTE entry that 812178840Smarius * was invalid/write protected. Call into the IOMMU code to have 813165886Smarius * them decoded to virtual I/O addresses. 81493053Stmm */ 81593053Stmm if ((afsr & UEAFSR_P_DTE) != 0) 81693053Stmm iommu_decode_fault(sc->sc_is, afar); 817108800Stmm panic("%s: uncorrectable DMA error AFAR %#lx AFSR %#lx", 818206020Smarius device_get_nameunit(sc->sc_dev), (u_long)afar, (u_long)afsr); 819166901Spiso return (FILTER_HANDLED); 82086231Stmm} 82186231Stmm 822166901Spisostatic int 82386231Stmmpsycho_ce(void *arg) 82486231Stmm{ 825152696Smarius struct psycho_softc *sc = arg; 826152696Smarius uint64_t afar, afsr; 82786231Stmm 828170851Smarius mtx_lock_spin(sc->sc_mtx); 82990617Stmm afar = PSYCHO_READ8(sc, PSR_CE_AFA); 83090617Stmm afsr = PSYCHO_READ8(sc, PSR_CE_AFS); 831117119Stmm device_printf(sc->sc_dev, "correctable DMA error AFAR %#lx " 832117119Stmm "AFSR %#lx\n", (u_long)afar, (u_long)afsr); 833119737Stmm /* Clear the error bits that we caught. */ 834183152Smarius PSYCHO_WRITE8(sc, PSR_CE_AFS, afsr); 835170851Smarius mtx_unlock_spin(sc->sc_mtx); 836166901Spiso return (FILTER_HANDLED); 83786231Stmm} 83886231Stmm 839166901Spisostatic int 840153055Smariuspsycho_pci_bus(void *arg) 84186231Stmm{ 842152696Smarius struct psycho_softc *sc = arg; 843152696Smarius uint64_t afar, afsr; 84486231Stmm 845153055Smarius afar = PCICTL_READ8(sc, PCR_AFA); 846153055Smarius afsr = PCICTL_READ8(sc, PCR_AFS); 847153055Smarius panic("%s: PCI bus %c error AFAR %#lx AFSR %#lx", 848206020Smarius device_get_nameunit(sc->sc_dev), 'A' + sc->sc_half, (u_long)afar, 849153055Smarius (u_long)afsr); 850166901Spiso return (FILTER_HANDLED); 85186231Stmm} 85286231Stmm 853166901Spisostatic int 854247600Smariuspsycho_powerdebug(void *arg __unused) 85586231Stmm{ 85692212Sjake 857174898Srwatson kdb_enter(KDB_WHY_POWERFAIL, "powerfail"); 858247600Smarius return (FILTER_HANDLED); 859247600Smarius} 860247600Smarius 861247620Smariusstatic void 862247600Smariuspsycho_powerdown(void *arg __unused) 863247600Smarius{ 864172066Smarius static int shutdown; 865172066Smarius 866172066Smarius /* As the interrupt is cleared we may be called multiple times. */ 867172066Smarius if (shutdown != 0) 868247620Smarius return; 869172066Smarius shutdown++; 87086231Stmm printf("Power Failure Detected: Shutting down NOW.\n"); 871247600Smarius shutdown_nice(RB_POWEROFF); 87286231Stmm} 87386231Stmm 874247620Smariusstatic void 875247600Smariuspsycho_overtemp(void *arg __unused) 876153055Smarius{ 877172066Smarius static int shutdown; 878153055Smarius 879172066Smarius /* As the interrupt is cleared we may be called multiple times. */ 880172066Smarius if (shutdown != 0) 881247620Smarius return; 882172066Smarius shutdown++; 883153055Smarius printf("DANGER: OVER TEMPERATURE detected.\nShutting down NOW.\n"); 884153055Smarius shutdown_nice(RB_POWEROFF); 885153055Smarius} 886153055Smarius 88786231Stmm#ifdef PSYCHO_MAP_WAKEUP 888166901Spisostatic int 88986231Stmmpsycho_wakeup(void *arg) 89086231Stmm{ 891152696Smarius struct psycho_softc *sc = arg; 89286231Stmm 893201199Smarius /* We don't really have a framework to deal with this properly. */ 894117119Stmm device_printf(sc->sc_dev, "power management wakeup\n"); 895166901Spiso return (FILTER_HANDLED); 89686231Stmm} 89786231Stmm#endif /* PSYCHO_MAP_WAKEUP */ 89886231Stmm 899152696Smariusstatic void 900152698Smariuspsycho_iommu_init(struct psycho_softc *sc, int tsbsize, uint32_t dvmabase) 90186231Stmm{ 90290617Stmm struct iommu_state *is = sc->sc_is; 90386231Stmm 904152696Smarius /* Punch in our copies. */ 905170851Smarius is->is_bustag = rman_get_bustag(sc->sc_mem_res); 906170851Smarius is->is_bushandle = rman_get_bushandle(sc->sc_mem_res); 90790617Stmm is->is_iommu = PSR_IOMMU; 90890617Stmm is->is_dtag = PSR_IOMMU_TLB_TAG_DIAG; 90990617Stmm is->is_ddram = PSR_IOMMU_TLB_DATA_DIAG; 91090617Stmm is->is_dqueue = PSR_IOMMU_QUEUE_DIAG; 91190617Stmm is->is_dva = PSR_IOMMU_SVADIAG; 91290617Stmm is->is_dtcmp = PSR_IOMMU_TLB_CMP_DIAG; 91386231Stmm 914178840Smarius iommu_init(device_get_nameunit(sc->sc_dev), is, tsbsize, dvmabase, 0); 91586231Stmm} 91686231Stmm 91786231Stmmstatic int 91886231Stmmpsycho_maxslots(device_t dev) 91986231Stmm{ 92086231Stmm 921117119Stmm /* XXX: is this correct? */ 922117119Stmm return (PCI_SLOTMAX); 92386231Stmm} 92486231Stmm 925152696Smariusstatic uint32_t 92686231Stmmpsycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, 927152696Smarius int width) 92886231Stmm{ 92986231Stmm struct psycho_softc *sc; 93086231Stmm bus_space_handle_t bh; 93186231Stmm u_long offset = 0; 932152696Smarius uint8_t byte; 933152696Smarius uint16_t shrt; 934174117Smarius uint32_t r, wrd; 93588371Stmm int i; 93686231Stmm 937152696Smarius sc = device_get_softc(dev); 938201395Smarius if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus || 939201395Smarius slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX) 940201395Smarius return (-1); 941201395Smarius 942174117Smarius bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; 943174117Smarius 944174117Smarius /* 945174117Smarius * The Hummingbird and Sabre bridges are picky in that they 946174117Smarius * only allow their config space to be accessed using the 947174117Smarius * "native" width of the respective register being accessed 948174117Smarius * and return semi-random other content of their config space 949178840Smarius * otherwise. Given that the PCI specs don't say anything 950174117Smarius * about such a (unusual) limitation and lots of stuff expects 951174117Smarius * to be able to access the contents of the config space at 952178840Smarius * any width we allow just that. We do this by using a copy 953174117Smarius * of the header of the bridge (the rest is all zero anyway) 954174117Smarius * read during attach (expect for PCIR_STATUS) in order to 955174117Smarius * simplify things. 956174117Smarius * The Psycho bridges contain a dupe of their header at 0x80 957174117Smarius * which we nullify that way also. 958174117Smarius */ 959174117Smarius if (bus == sc->sc_pci_secbus && slot == PCS_DEVICE && 960174117Smarius func == PCS_FUNC) { 961174117Smarius if (offset % width != 0) 962174117Smarius return (-1); 963174117Smarius 964174134Smarius if (reg >= sizeof(sc->sc_pci_hpbcfg)) 965174117Smarius return (0); 966174117Smarius 967174117Smarius if ((reg < PCIR_STATUS && reg + width > PCIR_STATUS) || 968174117Smarius reg == PCIR_STATUS || reg == PCIR_STATUS + 1) 969174117Smarius le16enc(&sc->sc_pci_hpbcfg[PCIR_STATUS], 970174117Smarius bus_space_read_2(sc->sc_pci_cfgt, bh, 971174117Smarius PSYCHO_CONF_OFF(sc->sc_pci_secbus, 972174117Smarius PCS_DEVICE, PCS_FUNC, PCIR_STATUS))); 973174117Smarius 974174117Smarius switch (width) { 975174117Smarius case 1: 976174117Smarius return (sc->sc_pci_hpbcfg[reg]); 977174117Smarius case 2: 978174117Smarius return (le16dec(&sc->sc_pci_hpbcfg[reg])); 979174117Smarius case 4: 980174117Smarius return (le32dec(&sc->sc_pci_hpbcfg[reg])); 981174117Smarius } 982174117Smarius } 983174117Smarius 98486231Stmm offset = PSYCHO_CONF_OFF(bus, slot, func, reg); 98586231Stmm switch (width) { 98686231Stmm case 1: 987152696Smarius i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte); 988116659Sjmg r = byte; 98986231Stmm break; 99086231Stmm case 2: 991152696Smarius i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt); 992116659Sjmg r = shrt; 99386231Stmm break; 99486231Stmm case 4: 995152696Smarius i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd); 996116659Sjmg r = wrd; 99786231Stmm break; 99886231Stmm default: 999152696Smarius panic("%s: bad width", __func__); 1000182020Smarius /* NOTREACHED */ 100186231Stmm } 1002116659Sjmg 1003116659Sjmg if (i) { 1004116659Sjmg#ifdef PSYCHO_DEBUG 1005165886Smarius printf("%s: read data error reading: %d.%d.%d: 0x%x\n", 1006165886Smarius __func__, bus, slot, func, reg); 1007116659Sjmg#endif 1008116659Sjmg r = -1; 1009116659Sjmg } 101086231Stmm return (r); 101186231Stmm} 101286231Stmm 101386231Stmmstatic void 1014201199Smariuspsycho_write_config(device_t dev, u_int bus, u_int slot, u_int func, 1015201199Smarius u_int reg, uint32_t val, int width) 101686231Stmm{ 101786231Stmm struct psycho_softc *sc; 101886231Stmm bus_space_handle_t bh; 101986231Stmm u_long offset = 0; 102086231Stmm 1021152696Smarius sc = device_get_softc(dev); 1022201395Smarius if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus || 1023201395Smarius slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX) 1024201395Smarius return; 1025201395Smarius 102686231Stmm offset = PSYCHO_CONF_OFF(bus, slot, func, reg); 1027153061Smarius bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; 102886231Stmm switch (width) { 102986231Stmm case 1: 1030152696Smarius bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val); 103186231Stmm break; 103286231Stmm case 2: 1033152696Smarius bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val); 103486231Stmm break; 103586231Stmm case 4: 1036152696Smarius bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val); 103786231Stmm break; 103886231Stmm default: 1039152696Smarius panic("%s: bad width", __func__); 1040182020Smarius /* NOTREACHED */ 104186231Stmm } 104286231Stmm} 104386231Stmm 104486231Stmmstatic int 1045117119Stmmpsycho_route_interrupt(device_t bridge, device_t dev, int pin) 104686231Stmm{ 1047152696Smarius struct psycho_softc *sc; 1048117119Stmm struct ofw_pci_register reg; 1049117119Stmm bus_addr_t intrmap; 1050117119Stmm ofw_pci_intr_t pintr, mintr; 105186231Stmm 1052152696Smarius sc = device_get_softc(bridge); 1053117119Stmm pintr = pin; 1054201199Smarius if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, 1055201199Smarius ®, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), 1056266020Sian NULL)) 1057117119Stmm return (mintr); 105886231Stmm /* 1059117119Stmm * If this is outside of the range for an intpin, it's likely a full 1060152696Smarius * INO, and no mapping is required at all; this happens on the U30, 1061178840Smarius * where there's no interrupt map at the Psycho node. Fortunately, 1062117119Stmm * there seem to be no INOs in the intpin range on this boxen, so 1063117119Stmm * this easy heuristics will do. 1064117119Stmm */ 1065117119Stmm if (pin > 4) 1066117119Stmm return (pin); 1067117119Stmm /* 1068117119Stmm * Guess the INO; we always assume that this is a non-OBIO 1069178840Smarius * device, and that pin is a "real" intpin number. Determine 1070117119Stmm * the mapping register to be used by the slot number. 1071152696Smarius * We only need to do this on E450s, it seems; here, the slot numbers 1072117119Stmm * for bus A are one-based, while those for bus B seemingly have an 1073117119Stmm * offset of 2 (hence the factor of 3 below). 1074117119Stmm */ 1075117119Stmm intrmap = PSR_PCIA0_INT_MAP + 1076117119Stmm 8 * (pci_get_slot(dev) - 1 + 3 * sc->sc_half); 1077117119Stmm mintr = INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1; 1078201199Smarius device_printf(bridge, 1079201199Smarius "guessing interrupt %d for device %d.%d pin %d\n", 1080117119Stmm (int)mintr, pci_get_slot(dev), pci_get_function(dev), pin); 1081117119Stmm return (mintr); 108286231Stmm} 108386231Stmm 108486231Stmmstatic int 108590617Stmmpsycho_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 108686231Stmm{ 108786231Stmm struct psycho_softc *sc; 108886231Stmm 1089152696Smarius sc = device_get_softc(dev); 109086231Stmm switch (which) { 1091172394Smarius case PCIB_IVAR_DOMAIN: 1092178279Smarius *result = device_get_unit(dev); 1093172394Smarius return (0); 109486231Stmm case PCIB_IVAR_BUS: 1095152696Smarius *result = sc->sc_pci_secbus; 109686231Stmm return (0); 109786231Stmm } 109886231Stmm return (ENOENT); 109986231Stmm} 110086231Stmm 1101220039Smariusstatic void 1102220039Smariussabre_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op) 1103170387Spiso{ 1104220039Smarius struct iommu_state *is = dt->dt_cookie; 1105170387Spiso 1106220039Smarius if ((map->dm_flags & DMF_LOADED) == 0) 1107220039Smarius return; 1108220039Smarius 1109220039Smarius if ((op & BUS_DMASYNC_POSTREAD) != 0) 1110220039Smarius (void)bus_space_read_8(is->is_bustag, is->is_bushandle, 1111220039Smarius PSR_DMA_WRITE_SYNC); 1112220039Smarius 1113220039Smarius if ((op & BUS_DMASYNC_PREWRITE) != 0) 1114220039Smarius membar(Sync); 1115170387Spiso} 1116170387Spiso 1117170387Spisostatic void 1118172066Smariuspsycho_intr_enable(void *arg) 111986231Stmm{ 1120172066Smarius struct intr_vector *iv = arg; 1121172066Smarius struct psycho_icarg *pica = iv->iv_icarg; 112286231Stmm 1123172066Smarius PSYCHO_WRITE8(pica->pica_sc, pica->pica_map, 1124172066Smarius INTMAP_ENABLE(iv->iv_vec, iv->iv_mid)); 112586231Stmm} 112686231Stmm 1127172066Smariusstatic void 1128172066Smariuspsycho_intr_disable(void *arg) 1129172066Smarius{ 1130172066Smarius struct intr_vector *iv = arg; 1131172066Smarius struct psycho_icarg *pica = iv->iv_icarg; 1132172066Smarius 1133172066Smarius PSYCHO_WRITE8(pica->pica_sc, pica->pica_map, iv->iv_vec); 1134172066Smarius} 1135172066Smarius 1136172066Smariusstatic void 1137178443Smariuspsycho_intr_assign(void *arg) 1138172066Smarius{ 1139172066Smarius struct intr_vector *iv = arg; 1140172066Smarius struct psycho_icarg *pica = iv->iv_icarg; 1141172066Smarius 1142178443Smarius PSYCHO_WRITE8(pica->pica_sc, pica->pica_map, INTMAP_TID( 1143178443Smarius PSYCHO_READ8(pica->pica_sc, pica->pica_map), iv->iv_mid)); 1144178443Smarius} 1145178443Smarius 1146178443Smariusstatic void 1147178443Smariuspsycho_intr_clear(void *arg) 1148178443Smarius{ 1149178443Smarius struct intr_vector *iv = arg; 1150178443Smarius struct psycho_icarg *pica = iv->iv_icarg; 1151178443Smarius 1152206018Smarius PSYCHO_WRITE8(pica->pica_sc, pica->pica_clr, INTCLR_IDLE); 1153172066Smarius} 1154172066Smarius 115586231Stmmstatic int 1156152696Smariuspsycho_setup_intr(device_t dev, device_t child, struct resource *ires, 1157167308Smarius int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, 1158166901Spiso void **cookiep) 115986231Stmm{ 116086231Stmm struct psycho_softc *sc; 1161172066Smarius u_long vec; 116286231Stmm 1163152696Smarius sc = device_get_softc(dev); 116486231Stmm /* 1165172066Smarius * Make sure the vector is fully specified and we registered 1166172066Smarius * our interrupt controller for it. 116786231Stmm */ 1168165886Smarius vec = rman_get_start(ires); 1169172066Smarius if (INTIGN(vec) != sc->sc_ign || 1170172066Smarius intr_vectors[vec].iv_ic != &psycho_ic) { 1171172066Smarius device_printf(dev, "invalid interrupt vector 0x%lx\n", vec); 1172165886Smarius return (EINVAL); 117386231Stmm } 1174172066Smarius return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr, 1175172066Smarius arg, cookiep)); 117686231Stmm} 117786231Stmm 117886231Stmmstatic struct resource * 117986231Stmmpsycho_alloc_resource(device_t bus, device_t child, int type, int *rid, 118086231Stmm u_long start, u_long end, u_long count, u_int flags) 118186231Stmm{ 118286231Stmm struct psycho_softc *sc; 118386231Stmm struct resource *rv; 118486231Stmm struct rman *rm; 118586231Stmm 1186152696Smarius sc = device_get_softc(bus); 1187225931Smarius switch (type) { 1188225931Smarius case SYS_RES_IRQ: 118986231Stmm /* 119086231Stmm * XXX: Don't accept blank ranges for now, only single 1191178840Smarius * interrupts. The other case should not happen with 1192178840Smarius * the MI PCI code... 1193152696Smarius * XXX: This may return a resource that is out of the 1194178840Smarius * range that was specified. Is this correct...? 119586231Stmm */ 119686231Stmm if (start != end) 1197152696Smarius panic("%s: XXX: interrupt range", __func__); 1198172066Smarius start = end = INTMAP_VEC(sc->sc_ign, end); 1199225931Smarius return (bus_generic_alloc_resource(bus, child, type, rid, 1200225931Smarius start, end, count, flags)); 120186231Stmm case SYS_RES_MEMORY: 1202152696Smarius rm = &sc->sc_pci_mem_rman; 120386231Stmm break; 120486231Stmm case SYS_RES_IOPORT: 1205152696Smarius rm = &sc->sc_pci_io_rman; 120686231Stmm break; 120786231Stmm default: 120886231Stmm return (NULL); 120986231Stmm } 121086231Stmm 1211225931Smarius rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, 1212225931Smarius child); 121386231Stmm if (rv == NULL) 121486231Stmm return (NULL); 1215157896Simp rman_set_rid(rv, *rid); 121686231Stmm 1217225931Smarius if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, 1218225931Smarius *rid, rv) != 0) { 1219225931Smarius rman_release_resource(rv); 1220225931Smarius return (NULL); 122186231Stmm } 122286231Stmm return (rv); 122386231Stmm} 122486231Stmm 122586231Stmmstatic int 122686231Stmmpsycho_activate_resource(device_t bus, device_t child, int type, int rid, 122786231Stmm struct resource *r) 122886231Stmm{ 1229225931Smarius struct psycho_softc *sc; 1230225931Smarius struct bus_space_tag *tag; 123186231Stmm 1232225931Smarius sc = device_get_softc(bus); 1233225931Smarius switch (type) { 1234225931Smarius case SYS_RES_IRQ: 1235225931Smarius return (bus_generic_activate_resource(bus, child, type, rid, 1236225931Smarius r)); 1237225931Smarius case SYS_RES_MEMORY: 1238225931Smarius tag = sparc64_alloc_bus_tag(r, rman_get_bustag( 1239225931Smarius sc->sc_mem_res), PCI_MEMORY_BUS_SPACE, NULL); 1240225931Smarius if (tag == NULL) 1241225931Smarius return (ENOMEM); 1242225931Smarius rman_set_bustag(r, tag); 1243225931Smarius rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] + 1244225931Smarius rman_get_start(r)); 1245225931Smarius break; 1246225931Smarius case SYS_RES_IOPORT: 1247225931Smarius rman_set_bustag(r, sc->sc_pci_iot); 1248225931Smarius rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] + 1249225931Smarius rman_get_start(r)); 1250225931Smarius break; 125193066Stmm } 125286231Stmm return (rman_activate_resource(r)); 125386231Stmm} 125486231Stmm 125586231Stmmstatic int 1256225931Smariuspsycho_adjust_resource(device_t bus, device_t child, int type, 1257225931Smarius struct resource *r, u_long start, u_long end) 125886231Stmm{ 1259225931Smarius struct psycho_softc *sc; 1260225931Smarius struct rman *rm; 126188371Stmm 1262225931Smarius sc = device_get_softc(bus); 1263225931Smarius switch (type) { 1264225931Smarius case SYS_RES_IRQ: 1265225931Smarius return (bus_generic_adjust_resource(bus, child, type, r, 1266225931Smarius start, end)); 1267225931Smarius case SYS_RES_MEMORY: 1268225931Smarius rm = &sc->sc_pci_mem_rman; 1269225931Smarius break; 1270225931Smarius case SYS_RES_IOPORT: 1271225931Smarius rm = &sc->sc_pci_io_rman; 1272225931Smarius break; 1273225931Smarius default: 1274225931Smarius return (EINVAL); 127593066Stmm } 1276225931Smarius if (rman_is_region_manager(r, rm) == 0) 1277225931Smarius return (EINVAL); 1278225931Smarius return (rman_adjust_resource(r, start, end)); 127986231Stmm} 128086231Stmm 1281167308Smariusstatic bus_dma_tag_t 1282220039Smariuspsycho_get_dma_tag(device_t bus, device_t child __unused) 1283167308Smarius{ 1284167308Smarius struct psycho_softc *sc; 1285167308Smarius 1286167308Smarius sc = device_get_softc(bus); 1287167308Smarius return (sc->sc_pci_dmat); 1288167308Smarius} 1289167308Smarius 1290117119Stmmstatic phandle_t 1291220039Smariuspsycho_get_node(device_t bus, device_t child __unused) 1292117119Stmm{ 1293152696Smarius struct psycho_softc *sc; 1294117119Stmm 1295152696Smarius sc = device_get_softc(bus); 1296117119Stmm /* We only have one child, the PCI bus, which needs our own node. */ 1297117119Stmm return (sc->sc_node); 1298117119Stmm} 1299117119Stmm 1300220039Smariusstatic void 1301220039Smariuspsycho_setup_device(device_t bus, device_t child) 1302220039Smarius{ 1303220039Smarius struct psycho_softc *sc; 1304220039Smarius uint32_t rev; 1305220039Smarius 1306220039Smarius sc = device_get_softc(bus); 1307220039Smarius /* 1308220039Smarius * Revision 0 EBus bridges have a bug which prevents them from 1309220039Smarius * working when bus parking is enabled. 1310220039Smarius */ 1311220039Smarius if ((strcmp(ofw_bus_get_name(child), "ebus") == 0 || 1312220039Smarius strcmp(ofw_bus_get_name(child), "pci108e,1000") == 0) && 1313220039Smarius OF_getprop(ofw_bus_get_node(child), "revision-id", &rev, 1314220039Smarius sizeof(rev)) > 0 && rev == 0) 1315220039Smarius PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS) & 1316220039Smarius ~PCICTL_ARB_PARK); 1317220039Smarius} 1318