#include "opt_dec_2100_a500.h"
#include "opt_dec_2100a_a500.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ttwoga.c,v 1.21 2023/12/04 00:32:10 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/rpb.h>
#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
#include <dev/eisa/eisavar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <alpha/pci/ttwogareg.h>
#include <alpha/pci/ttwogavar.h>
#if defined(DEC_2100_A500) || defined(DEC_2100A_A500)
#include <alpha/pci/pci_2100_a500.h>
#endif
#include "locators.h"
static int ttwogamatch(device_t, cfdata_t, void *);
static void ttwogaattach(device_t, device_t, void *);
CFATTACH_DECL_NEW(ttwoga, 0,
ttwogamatch, ttwogaattach, NULL, NULL);
static int ttwogaprint(void *, const char *);
static int ttwopcimatch(device_t, cfdata_t, void *);
static void ttwopciattach(device_t, device_t, void *);
CFATTACH_DECL_NEW(ttwopci, 0,
ttwopcimatch, ttwopciattach, NULL, NULL);
static int ttwosableioprint(void *, const char *);
static int ttwogafound;
static struct ttwoga_config ttwoga_configuration[2];
bus_addr_t ttwoga_gamma_cbus_bias;
#define GIGABYTE (1024UL * 1024UL * 1024UL)
#define MEGABYTE (1024UL * 1024UL)
static const struct ttwoga_sysmap ttwoga_sysmap[2] = {
{ T2_PCI0_SIO_BASE, 256UL * MEGABYTE, 8UL * MEGABYTE,
T2_PCI0_SMEM_BASE, 4UL * GIGABYTE, 128UL * MEGABYTE,
T2_PCI0_DMEM_BASE, 1UL * GIGABYTE, 1UL * GIGABYTE,
T2_PCI0_CONF_BASE,
},
{ T2_PCI1_SIO_BASE, 256UL * MEGABYTE, 8UL * MEGABYTE,
T2_PCI1_SMEM_BASE, 2UL * GIGABYTE, 64UL * MEGABYTE,
T2_PCI1_DMEM_BASE, 2UL * GIGABYTE, 2UL * GIGABYTE,
T2_PCI1_CONF_BASE,
},
};
#undef GIGABYTE
#undef MEGABYTE
static int
ttwogamatch(device_t parent, cfdata_t match, void *aux)
{
struct mainbus_attach_args *ma = aux;
if (strcmp(ma->ma_name, match->cf_name) != 0)
return (0);
if (ttwogafound)
return (0);
return (1);
}
static void
ttwogaattach(device_t parent, device_t self, void *aux)
{
struct pcibus_attach_args pba;
int hose;
printf("\n");
ttwogafound = 1;
for (hose = 0; hose < 1 ; hose++) {
#if 0
if (badaddr(_T2GA(hose, T2_IOCSR), sizeof(uint64_t)))
continue;
#endif
memset(&pba, 0, sizeof(pba));
pba.pba_bus = hose;
config_found(self, &pba, ttwogaprint, CFARGS_NONE);
}
}
static int
ttwogaprint(void *aux, const char *pnp)
{
struct pcibus_attach_args *pba = aux;
if (pnp)
aprint_normal("ttwopci at %s", pnp);
aprint_normal(" hose %d", pba->pba_bus);
return (UNCONF);
}
struct ttwoga_config *
ttwoga_init(int hose)
{
struct ttwoga_config *tcp;
if (hose < 0 || hose > 1)
panic("ttwoga_init: bad hose # %d", hose);
tcp = &ttwoga_configuration[hose];
tcp->tc_hose = hose;
tcp->tc_sysmap = &ttwoga_sysmap[hose];
ttwoga_gamma_cbus_bias = (alpha_implver() == ALPHA_IMPLVER_EV5) ?
T2_GAMMA_CBUS_BIAS : 0;
alpha_mb();
tcp->tc_io_bus_start = (T2GA(tcp, T2_HAE0_2) & HAE0_2_PUA2) << 23;
tcp->tc_d_mem_bus_start = (T2GA(tcp, T2_HAE0_4) & HAE0_4_PUA1) << 30;
tcp->tc_s_mem_bus_start = (T2GA(tcp, T2_HAE0_1) & HAE0_1_PUA1) << 27;
tcp->tc_rev = (T2GA(tcp, T2_IOCSR) & IOCSR_TRN) >> IOCSR_TRN_SHIFT;
if (tcp->tc_initted == 0) {
ttwoga_bus_io_init(&tcp->tc_iot, tcp);
ttwoga_bus_mem_init(&tcp->tc_memt, tcp);
}
ttwoga_pci_init(&tcp->tc_pc, tcp);
tcp->tc_initted = 1;
return (tcp);
}
static int
ttwopcimatch(device_t parent, cfdata_t match, void *aux)
{
struct pcibus_attach_args *pba = aux;
if (match->cf_loc[PCIBUSCF_BUS] != PCIBUSCF_BUS_DEFAULT &&
match->cf_loc[PCIBUSCF_BUS] != pba->pba_bus)
return (0);
return (1);
}
static void
ttwopciattach(device_t parent, device_t self, void *aux)
{
struct pcibus_attach_args *pba = aux, npba;
struct ttwoga_config *tcp;
tcp = ttwoga_init(pba->pba_bus);
ttwoga_dma_init(tcp);
aprint_normal(": %s Gate Array rev. %d\n",
(tcp->tc_rev < TRN_T3) ? "T2" : "T3 or T4",
tcp->tc_rev);
if (tcp->tc_rev < 1)
aprint_normal_dev(self,
"WARNING: T2 NOT PASS2... NO BETS...\n");
alpha_pci_intr_init(tcp, &tcp->tc_iot, &tcp->tc_memt, &tcp->tc_pc);
npba.pba_iot = &tcp->tc_iot;
npba.pba_memt = &tcp->tc_memt;
npba.pba_dmat =
alphabus_dma_get_tag(&tcp->tc_dmat_direct, ALPHA_BUS_PCI);
npba.pba_dmat64 = NULL;
npba.pba_pc = &tcp->tc_pc;
npba.pba_bus = 0;
npba.pba_bridgetag = NULL;
npba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
if (pba->pba_bus == 0) {
config_found(self, &npba, ttwosableioprint,
CFARGS(.iattr = "sableiobus"));
}
config_found(self, &npba, pcibusprint,
CFARGS(.iattr = "pcibus"));
}
static int
ttwosableioprint(void *aux, const char *pnp)
{
struct pcibus_attach_args *pba = aux;
if (pnp)
aprint_normal("sableio at %s", pnp);
aprint_normal(" bus %d", pba->pba_bus);
return (UNCONF);
}