/*
* Copyright (c) 1997 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
static int
dwlpxmatch(device_t parent, cfdata_t cf, void *aux)
{
struct kft_dev_attach_args *ka = aux;
unsigned long ls;
uint32_t ctl;
if (strcmp(ka->ka_name, dwlpx_cd.cd_name) != 0)
return (0);
ls = DWLPX_SYSBASE1(ka->ka_node, ka->ka_hosenum);
/*
* Probe the first HPC to make sure this really is a dwlpx and
* nothing else.
*/
if (badaddr(KV(PCIA_CTL(1) + ls), sizeof (ctl)) != 0) {
/*
* If we are here something went wrong. One reason
* could be that this is a dwlma and not a dwlpx.
*
* We can not clear potential illegal CSR errors here
* since it is unknown hardware.
*/
return (0);
}
void
dwlpx_init(struct dwlpx_softc *sc)
{
uint32_t ctl;
struct dwlpx_config *ccp = &sc->dwlpx_cc;
unsigned long vec, ls = DWLPX_SYSBASE(sc);
int i;
if (ccp->cc_initted == 0) {
/*
* On reads, you get a fault if you read a nonexisted HPC.
* We know the internal KFTIA hose (hose 0) has only 2 HPCs,
* but we can also actually probe for HPCs.
* Assume at least one.
*/
for (sc->dwlpx_nhpc = 1; sc->dwlpx_nhpc < NHPC;
sc->dwlpx_nhpc++) {
if (badaddr(KV(PCIA_CTL(sc->dwlpx_nhpc) + ls),
sizeof (ctl)) != 0) {
break;
}
}
if (sc->dwlpx_nhpc != NHPC) {
/* clear (potential) Illegal CSR Address Error */
REGVAL(PCIA_ERR(0) + DWLPX_SYSBASE(sc)) =
PCIA_ERR_ALLERR;
}
/*
* Establish a precalculated base for convenience's sake.
*/
ccp->cc_sysbase = ls;
/*
* If there are only 2 HPCs, then the 'present' register is not
* implemented, so there will only ever be 32K SG entries. Otherwise
* any revision greater than zero will have 128K entries.
*/
ctl = REGVAL(PCIA_PRESENT + ccp->cc_sysbase);
if (sc->dwlpx_nhpc == 2) {
sc->dwlpx_sgmapsz = DWLPX_SG32K;
#if 0
/*
* As of 2/25/98- When I enable SG128K, and then have to flip
* TBIT below, I get bad SGRAM errors. We'll fix this later
* if this gets important.
*/
} else if ((ctl >> PCIA_PRESENT_REVSHIFT) & PCIA_PRESENT_REVMASK) {
sc->dwlpx_sgmapsz = DWLPX_SG128K;
#endif
} else {
sc->dwlpx_sgmapsz = DWLPX_SG32K;
}
/*
* Set up interrupt stuff for this DWLPX.
*
* Note that all PCI interrupt pins are disabled at this time.
*
* Do this even for all HPCs- even for the nonexistent
* one on hose zero of a KFTIA.
*/
mutex_enter(&cpu_lock);
vec = scb_alloc(dwlpx_errintr, sc);
mutex_exit(&cpu_lock);
if (vec == SCB_ALLOC_FAILED)
panic("%s: unable to allocate error vector",
device_xname(sc->dwlpx_dev));
aprint_normal_dev(sc->dwlpx_dev, "error interrupt at vector 0x%lx\n",
vec);
for (i = 0; i < NHPC; i++) {
REGVAL(PCIA_IMASK(i) + ccp->cc_sysbase) = DWLPX_IMASK_DFLT;
REGVAL(PCIA_ERRVEC(i) + ccp->cc_sysbase) = vec;
}
/*
* Establish HAE values, as well as make sure of sanity elsewhere.
*/
for (i = 0; i < sc->dwlpx_nhpc; i++) {
ctl = REGVAL(PCIA_CTL(i) + ccp->cc_sysbase);
ctl &= 0x0fffffff;
ctl &= ~(PCIA_CTL_MHAE(0x1f) | PCIA_CTL_IHAE(0x1f));
/*
* I originally also had it or'ing in 3, which makes no sense.
*/
ctl |= PCIA_CTL_RMMENA | PCIA_CTL_RMMARB;
/*
* Only valid if we're attached to a KFTIA or a KTHA.
*/
ctl |= PCIA_CTL_3UP;
ctl |= PCIA_CTL_CUTENA;
/*
* Fit in appropriate S/G Map Ram size.
*/
if (sc->dwlpx_sgmapsz == DWLPX_SG32K)
ctl |= PCIA_CTL_SG32K;
else if (sc->dwlpx_sgmapsz == DWLPX_SG128K)
ctl |= PCIA_CTL_SG128K;
else
ctl |= PCIA_CTL_SG32K;