#include <sys/param.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <dev/cardbus/rbus.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <dev/ofw/openfirm.h>
void macppc_cardbus_init(pci_chipset_tag_t pc, pcitag_t tag);
rbus_tag_t
rbus_pccbb_parent_mem(struct device *self, struct pci_attach_args *pa)
{
macppc_cardbus_init(pa->pa_pc, pa->pa_tag);
return (rbus_new_root_share(pa->pa_memt, pa->pa_memex,
0x00000000, 0xffffffff));
}
rbus_tag_t
rbus_pccbb_parent_io(struct device *self, struct pci_attach_args *pa)
{
return (rbus_new_root_share(pa->pa_iot, pa->pa_ioex,
0x0000, 0xffff));
}
void
macppc_cardbus_init(pci_chipset_tag_t pc, pcitag_t tag)
{
u_int x;
static int initted = 0;
if (initted)
return;
initted = 1;
x = pci_conf_read(pc, tag, PCI_ID_REG);
if (PCI_VENDOR(x) == PCI_VENDOR_TI &&
PCI_PRODUCT(x) == PCI_PRODUCT_TI_PCI1211) {
pci_conf_write(pc, tag, 0x18, 0x10010100);
x = pci_conf_read(pc, tag, 0x8c);
x |= 0x02;
pci_conf_write(pc, tag, 0x8c, x);
tag = pci_make_tag(pc, 0, 0, 0);
x = pci_conf_read(pc, tag, PCI_ID_REG);
if (PCI_VENDOR(x) == PCI_VENDOR_MOT &&
PCI_PRODUCT(x) == PCI_PRODUCT_MOT_MPC106) {
x = pci_conf_read(pc, tag, 0x40);
x |= 1 << 8;
pci_conf_write(pc, tag, 0x40, x);
}
}
if (PCI_VENDOR(x) == PCI_VENDOR_TI &&
(PCI_PRODUCT(x) == PCI_PRODUCT_TI_PCI1410 ||
PCI_PRODUCT(x) == PCI_PRODUCT_TI_PCI1510)) {
x = pci_conf_read(pc, tag, 0x8c);
x |= 0x02;
pci_conf_write(pc, tag, 0x8c, x);
}
}
void
pccbb_attach_hook(struct device *parent, struct device *self,
struct pci_attach_args *pa)
{
pci_chipset_tag_t pc = pa->pa_pc;
int node = PCITAG_NODE(pa->pa_tag);
int bus, busrange[2];
if (OF_getprop(OF_parent(node), "bus-range", &busrange,
sizeof(busrange)) != sizeof(busrange))
return;
bus = busrange[0] + 1;
while (bus < 256 && pc->busnode[bus])
bus++;
if (bus == 256)
return;
pc->busnode[bus] = node;
}