/*-
* Copyright (c) 2007 David Young. 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, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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
* 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.
*/
/*-
* Copyright (c) 2006 Itronix Inc.
* All rights reserved.
*
* Written by Garrett D'Amore for Itronix Inc.
*
* 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, 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 Itronix Inc. may not be used to endorse
* or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``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 ITRONIX INC. 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.
*/
#ifdef ADMPCI_DEBUG
int admpci_debug = 1;
#define ADMPCI_DPRINTF(__fmt, ...) \
do { \
if (admpci_debug) \
printf((__fmt), __VA_ARGS__); \
} while (/*CONSTCOND*/0)
#else /* !ADMPCI_DEBUG */
#define ADMPCI_DPRINTF(__fmt, ...) do { } while (/*CONSTCOND*/0)
#endif /* ADMPCI_DEBUG */
#define ADMPCI_TAG_BUS_MASK __BITS(23, 16)
/* Bit 11 is reserved. It selects the AHB-PCI bridge. Let device 0
* be the bridge. For all other device numbers, let bit[11] == 0.
*/
#define ADMPCI_TAG_DEVICE_MASK __BITS(15, 11)
#define ADMPCI_TAG_DEVICE_SUBMASK __BITS(15, 12)
#define ADMPCI_TAG_DEVICE_BRIDGE __BIT(11)
#define ADMPCI_TAG_FUNCTION_MASK __BITS(10, 8)
#define ADMPCI_TAG_REGISTER_MASK __BITS(7, 0)
/*
* Physical PCI addresses are 36-bits long, so we need to have
* adequate storage space for them.
*/
#if NPCI > 0
#if !defined(_MIPS_PADDR_T_64BIT) && !defined(_LP64)
#error "admpci requires 64 bit paddr_t!"
#endif
#endif
/* There are at most four devices on bus 0. The ADM5120 has
* request/grant lines for 3 PCI devices: 1, 2, and 3. The host
* bridge is device 0.
*/
int
admpci_bus_maxdevs(void *v, int bus)
{
if (bus == 0)
return 4;
pcitag_t
admpci_make_tag(void *v, int bus, int device, int function)
{
if (bus > __SHIFTOUT_MASK(ADMPCI_TAG_BUS_MASK) ||
device > __SHIFTOUT_MASK(ADMPCI_TAG_DEVICE_MASK) ||
function > __SHIFTOUT_MASK(ADMPCI_TAG_FUNCTION_MASK))
panic("%s: bad request", __func__);
void
admpci_decompose_tag(void *v, pcitag_t tag, int *b, int *d, int *f)
{
int bus, device, function;
bus = __SHIFTOUT(tag, ADMPCI_TAG_BUS_MASK);
device = __SHIFTOUT(tag, ADMPCI_TAG_DEVICE_MASK);
function = __SHIFTOUT(tag, ADMPCI_TAG_FUNCTION_MASK);
if (b != NULL)
*b = bus;
if (d != NULL)
*d = device;
if (f != NULL)
*f = function;
}
static int
admpci_tag_to_addr(void *v, pcitag_t tag, int reg, bus_addr_t *addrp)
{
int bus, device, function;
KASSERT(addrp != NULL);
if ((unsigned int)reg >= PCI_CONF_SIZE)
return -1;
/* panics if tag is not well-formed */
admpci_decompose_tag(v, tag, &bus, &device, &function);
if (reg > __SHIFTOUT_MASK(ADMPCI_TAG_REGISTER_MASK))
panic("%s: bad register", __func__);
*addrp = 0x80000000 | tag | __SHIFTIN(reg, ADMPCI_TAG_REGISTER_MASK);
void
admpci_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz, int *iline)
{
/*
* We let the machdep_pci_intr_map take care of IRQ routing.
* On some platforms the BIOS may have handled this properly,
* on others it might not have. For now we avoid clobbering
* the settings establishsed by the BIOS, so that they will be
* there if the platform logic is confident that it can rely
* on them.
*/
}
/*
* Map the bus 0 device numbers 1, 2, and 3 to IRQ 6, 7, and 8,
* respectively.
*
* XXX How to handle bridges?
*/
static int
admpci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
int bus, device, function;