psycho.c (115343) | psycho.c (115417) |
---|---|
1/* 2 * Copyright (c) 1999, 2000 Matthew R. Green 3 * All rights reserved. 4 * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 14 unchanged lines hidden (view full) --- 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp 30 * | 1/* 2 * Copyright (c) 1999, 2000 Matthew R. Green 3 * All rights reserved. 4 * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 14 unchanged lines hidden (view full) --- 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp 30 * |
31 * $FreeBSD: head/sys/sparc64/pci/psycho.c 115343 2003-05-27 04:59:59Z scottl $ | 31 * $FreeBSD: head/sys/sparc64/pci/psycho.c 115417 2003-05-30 20:48:05Z tmm $ |
32 */ 33 34/* 35 * Support for `psycho' and `psycho+' UPA to PCI bridge and 36 * UltraSPARC IIi and IIe `sabre' PCI controllers. 37 */ 38 39#include "opt_psycho.h" --- 96 unchanged lines hidden (view full) --- 136static int psycho_release_resource(device_t, device_t, int, int, 137 struct resource *); 138static int psycho_maxslots(device_t); 139static u_int32_t psycho_read_config(device_t, u_int, u_int, u_int, u_int, int); 140static void psycho_write_config(device_t, u_int, u_int, u_int, u_int, u_int32_t, 141 int); 142static int psycho_route_interrupt(device_t, device_t, int); 143static int psycho_intr_pending(device_t, int); | 32 */ 33 34/* 35 * Support for `psycho' and `psycho+' UPA to PCI bridge and 36 * UltraSPARC IIi and IIe `sabre' PCI controllers. 37 */ 38 39#include "opt_psycho.h" --- 96 unchanged lines hidden (view full) --- 136static int psycho_release_resource(device_t, device_t, int, int, 137 struct resource *); 138static int psycho_maxslots(device_t); 139static u_int32_t psycho_read_config(device_t, u_int, u_int, u_int, u_int, int); 140static void psycho_write_config(device_t, u_int, u_int, u_int, u_int, u_int32_t, 141 int); 142static int psycho_route_interrupt(device_t, device_t, int); 143static int psycho_intr_pending(device_t, int); |
144static u_int32_t psycho_guess_ino(device_t, phandle_t, u_int, u_int); |
|
144static bus_space_handle_t psycho_get_bus_handle(device_t dev, enum sbbt_id id, 145 bus_space_handle_t childhdl, bus_space_tag_t *tag); 146 147static device_method_t psycho_methods[] = { 148 /* Device interface */ 149 DEVMETHOD(device_probe, psycho_probe), 150 DEVMETHOD(device_attach, psycho_attach), 151 --- 10 unchanged lines hidden (view full) --- 162 /* pcib interface */ 163 DEVMETHOD(pcib_maxslots, psycho_maxslots), 164 DEVMETHOD(pcib_read_config, psycho_read_config), 165 DEVMETHOD(pcib_write_config, psycho_write_config), 166 DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt), 167 168 /* sparcbus interface */ 169 DEVMETHOD(sparcbus_intr_pending, psycho_intr_pending), | 145static bus_space_handle_t psycho_get_bus_handle(device_t dev, enum sbbt_id id, 146 bus_space_handle_t childhdl, bus_space_tag_t *tag); 147 148static device_method_t psycho_methods[] = { 149 /* Device interface */ 150 DEVMETHOD(device_probe, psycho_probe), 151 DEVMETHOD(device_attach, psycho_attach), 152 --- 10 unchanged lines hidden (view full) --- 163 /* pcib interface */ 164 DEVMETHOD(pcib_maxslots, psycho_maxslots), 165 DEVMETHOD(pcib_read_config, psycho_read_config), 166 DEVMETHOD(pcib_write_config, psycho_write_config), 167 DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt), 168 169 /* sparcbus interface */ 170 DEVMETHOD(sparcbus_intr_pending, psycho_intr_pending), |
171 DEVMETHOD(sparcbus_guess_ino, psycho_guess_ino), |
|
170 DEVMETHOD(sparcbus_get_bus_handle, psycho_get_bus_handle), 171 172 { 0, 0 } 173}; 174 175static driver_t psycho_driver = { 176 "pcib", 177 psycho_methods, --- 153 unchanged lines hidden (view full) --- 331psycho_attach(device_t dev) 332{ 333 struct psycho_softc *sc; 334 struct psycho_softc *osc = NULL; 335 struct psycho_softc *asc; 336 struct upa_regs *reg; 337 struct ofw_pci_bdesc obd; 338 struct psycho_desc *desc; | 172 DEVMETHOD(sparcbus_get_bus_handle, psycho_get_bus_handle), 173 174 { 0, 0 } 175}; 176 177static driver_t psycho_driver = { 178 "pcib", 179 psycho_methods, --- 153 unchanged lines hidden (view full) --- 333psycho_attach(device_t dev) 334{ 335 struct psycho_softc *sc; 336 struct psycho_softc *osc = NULL; 337 struct psycho_softc *asc; 338 struct upa_regs *reg; 339 struct ofw_pci_bdesc obd; 340 struct psycho_desc *desc; |
339 vm_paddr_t pcictl_offs; | |
340 phandle_t node; 341 u_int64_t csr; 342 u_long mlen; 343 int psycho_br[2]; 344 int n, i, nreg, rid; 345#if defined(PSYCHO_DEBUG) || defined(PSYCHO_STRAY) 346 bus_addr_t map, clr; 347 u_int64_t mr; --- 21 unchanged lines hidden (view full) --- 369 reg = nexus_get_reg(dev); 370 nreg = nexus_get_nreg(dev); 371 /* Register layouts are different. stuupid. */ 372 if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { 373 if (nreg <= 2) 374 panic("psycho_attach: %d not enough registers", nreg); 375 sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[2]); 376 mlen = UPA_REG_SIZE(®[2]); | 341 phandle_t node; 342 u_int64_t csr; 343 u_long mlen; 344 int psycho_br[2]; 345 int n, i, nreg, rid; 346#if defined(PSYCHO_DEBUG) || defined(PSYCHO_STRAY) 347 bus_addr_t map, clr; 348 u_int64_t mr; --- 21 unchanged lines hidden (view full) --- 370 reg = nexus_get_reg(dev); 371 nreg = nexus_get_nreg(dev); 372 /* Register layouts are different. stuupid. */ 373 if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { 374 if (nreg <= 2) 375 panic("psycho_attach: %d not enough registers", nreg); 376 sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[2]); 377 mlen = UPA_REG_SIZE(®[2]); |
377 pcictl_offs = UPA_REG_PHYS(®[0]); | 378 sc->sc_pcictl = UPA_REG_PHYS(®[0]) - sc->sc_basepaddr; 379 switch (sc->sc_pcictl) { 380 case PSR_PCICTL0: 381 sc->sc_half = 0; 382 break; 383 case PSR_PCICTL1: 384 sc->sc_half = 1; 385 break; 386 default: 387 panic("psycho_attach: bogus pci control register " 388 "location"); 389 } |
378 } else { 379 if (nreg <= 0) 380 panic("psycho_attach: %d not enough registers", nreg); 381 sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[0]); 382 mlen = UPA_REG_SIZE(reg); | 390 } else { 391 if (nreg <= 0) 392 panic("psycho_attach: %d not enough registers", nreg); 393 sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[0]); 394 mlen = UPA_REG_SIZE(reg); |
383 pcictl_offs = sc->sc_basepaddr + PSR_PCICTL0; | 395 sc->sc_pcictl = PSR_PCICTL0; 396 sc->sc_half = 0; |
384 } 385 386 /* 387 * Match other psycho's that are already configured against 388 * the base physical address. This will be the same for a 389 * pair of devices that share register space. 390 */ 391 SLIST_FOREACH(asc, &psycho_softcs, sc_link) { --- 18 unchanged lines hidden (view full) --- 410 /* 411 * There's another psycho using the same register space. Copy the 412 * relevant stuff. 413 */ 414 sc->sc_mem_res = NULL; 415 sc->sc_bustag = osc->sc_bustag; 416 sc->sc_bushandle = osc->sc_bushandle; 417 } | 397 } 398 399 /* 400 * Match other psycho's that are already configured against 401 * the base physical address. This will be the same for a 402 * pair of devices that share register space. 403 */ 404 SLIST_FOREACH(asc, &psycho_softcs, sc_link) { --- 18 unchanged lines hidden (view full) --- 423 /* 424 * There's another psycho using the same register space. Copy the 425 * relevant stuff. 426 */ 427 sc->sc_mem_res = NULL; 428 sc->sc_bustag = osc->sc_bustag; 429 sc->sc_bushandle = osc->sc_bushandle; 430 } |
418 if (pcictl_offs < sc->sc_basepaddr) 419 panic("psycho_attach: bogus pci control register location"); 420 sc->sc_pcictl = pcictl_offs - sc->sc_basepaddr; | |
421 csr = PSYCHO_READ8(sc, PSR_CS); 422 sc->sc_ign = 0x7c0; /* APB IGN is always 0x7c */ 423 if (sc->sc_mode == PSYCHO_MODE_PSYCHO) 424 sc->sc_ign = PSYCHO_GCSR_IGN(csr) << 6; 425 | 431 csr = PSYCHO_READ8(sc, PSR_CS); 432 sc->sc_ign = 0x7c0; /* APB IGN is always 0x7c */ 433 if (sc->sc_mode == PSYCHO_MODE_PSYCHO) 434 sc->sc_ign = PSYCHO_GCSR_IGN(csr) << 6; 435 |
426 device_printf(dev, "%s, impl %d, version %d, ign %#x\n", | 436 device_printf(dev, "%s, impl %d, version %d, ign %#x, bus %c\n", |
427 desc->pd_name, (int)PSYCHO_GCSR_IMPL(csr), | 437 desc->pd_name, (int)PSYCHO_GCSR_IMPL(csr), |
428 (int)PSYCHO_GCSR_VERS(csr), sc->sc_ign); | 438 (int)PSYCHO_GCSR_VERS(csr), sc->sc_ign, 'A' + sc->sc_half); |
429 430 /* 431 * Setup the PCI control register 432 */ 433 csr = PCICTL_READ8(sc, PCR_CS); 434 csr |= PCICTL_MRLM | PCICTL_ARB_PARK | PCICTL_ERRINTEN | PCICTL_4ENABLE; 435 csr &= ~(PCICTL_SERR | PCICTL_CPU_PRIO | PCICTL_ARB_PRIO | 436 PCICTL_RTRYWAIT); --- 830 unchanged lines hidden (view full) --- 1267 sc = (struct psycho_softc *)device_get_softc(dev); 1268 if (!psycho_find_intrmap(sc, intr, NULL, NULL, &diag)) { 1269 printf("psycho_intr_pending: mapping not found for %d\n", intr); 1270 return (0); 1271 } 1272 return (diag != 0); 1273} 1274 | 439 440 /* 441 * Setup the PCI control register 442 */ 443 csr = PCICTL_READ8(sc, PCR_CS); 444 csr |= PCICTL_MRLM | PCICTL_ARB_PARK | PCICTL_ERRINTEN | PCICTL_4ENABLE; 445 csr &= ~(PCICTL_SERR | PCICTL_CPU_PRIO | PCICTL_ARB_PRIO | 446 PCICTL_RTRYWAIT); --- 830 unchanged lines hidden (view full) --- 1277 sc = (struct psycho_softc *)device_get_softc(dev); 1278 if (!psycho_find_intrmap(sc, intr, NULL, NULL, &diag)) { 1279 printf("psycho_intr_pending: mapping not found for %d\n", intr); 1280 return (0); 1281 } 1282 return (diag != 0); 1283} 1284 |
1285static u_int32_t 1286psycho_guess_ino(device_t dev, phandle_t node, u_int slot, u_int pin) 1287{ 1288 struct psycho_softc *sc = (struct psycho_softc *)device_get_softc(dev); 1289 bus_addr_t intrmap; 1290 1291 /* 1292 * If this is not for one of our direct children (i.e. we are mapping 1293 * at our node), tell the interrupt mapper to go on - we need the 1294 * slot number of the device or it's topmost parent bridge to guess 1295 * the INO. 1296 */ 1297 if (node != sc->sc_node) 1298 return (255); 1299 /* 1300 * Actually guess the INO. We always assume that this is a non-OBIO 1301 * device, and use from the slot number to determine it. 1302 * We only need to do this on e450s, it seems; here, the slot numbers 1303 * for bus A are one-based, while those for bus B seemingly have an 1304 * offset of 2 (hence the factor of 3 below). 1305 */ 1306 intrmap = PSR_PCIA0_INT_MAP + 8 * (slot - 1 + 3 * sc->sc_half); 1307 return (INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1); 1308} 1309 |
|
1275static bus_space_handle_t 1276psycho_get_bus_handle(device_t dev, enum sbbt_id id, 1277 bus_space_handle_t childhdl, bus_space_tag_t *tag) 1278{ 1279 struct psycho_softc *sc; 1280 1281 sc = (struct psycho_softc *)device_get_softc(dev); 1282 switch(id) { --- 130 unchanged lines hidden --- | 1310static bus_space_handle_t 1311psycho_get_bus_handle(device_t dev, enum sbbt_id id, 1312 bus_space_handle_t childhdl, bus_space_tag_t *tag) 1313{ 1314 struct psycho_softc *sc; 1315 1316 sc = (struct psycho_softc *)device_get_softc(dev); 1317 switch(id) { --- 130 unchanged lines hidden --- |