#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rbus_machdep.c,v 1.21 2025/03/17 08:23:13 macallan Exp $");
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <powerpc/oea/bat.h>
#include <sys/bus.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <dev/cardbus/rbus.h>
#include <dev/ofw/openfirm.h>
static void macppc_cardbus_init(pci_chipset_tag_t, pcitag_t);
#ifdef DEBUG_ALLOC
# define DPRINTF printf
#else
# define DPRINTF while (0) printf
#endif
int
md_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
int flags, bus_space_handle_t *bshp)
{
DPRINTF("md_space_map: %p, 0x%x, 0x%x\n", t, bpa, size);
return bus_space_map(t, bpa, size, flags, bshp);
}
void
md_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size,
bus_addr_t *adrp)
{
DPRINTF("md_space_unmap: %p 0x%x\n", t, bsh);
if (adrp)
*adrp = bsh - t->pbs_offset;
bus_space_unmap(t, bsh, size);
}
rbus_tag_t
rbus_pccbb_parent_mem(struct pci_attach_args *pa)
{
bus_addr_t start = 0;
bus_size_t size = 0;
int node, reg[5];
macppc_cardbus_init(pa->pa_pc, pa->pa_tag);
node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
if (OF_getprop(node, "reserved-segment", &start, 4) == 4) {
size = 0x10000000;
printf("found reserved-segment %08x\n", start);
} else {
OF_getprop(node, "assigned-addresses", reg, sizeof(reg));
if (reg[4] < 0x10000) {
start = 0x90000000;
size = 0x10000000;
} else {
start = reg[2];
size = reg[4];
printf("found assigned-addresses %08x\n", start);
}
}
return rbus_new_root_delegate(pa->pa_memt, start, size, 0);
}
rbus_tag_t
rbus_pccbb_parent_io(struct pci_attach_args *pa)
{
bus_addr_t start = 0x2000;
bus_size_t size = 0x0800;
start += pa->pa_function * size;
return rbus_new_root_delegate(pa->pa_iot, start, size, 0);
}
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);
}
}
}