예제 #1
0
static void
tegra_gpio_attach_bank(struct tegra_gpio_softc *sc, u_int bankno)
{
	struct tegra_gpio_bank *bank = &sc->sc_banks[bankno];
	struct gpiobus_attach_args gba;
	u_int pin;

	bank->bank_sc = sc;
	bank->bank_pb = &tegra_gpio_pinbanks[bankno];
	bank->bank_gc.gp_cookie = bank;
	bank->bank_gc.gp_pin_read = tegra_gpio_pin_read;
	bank->bank_gc.gp_pin_write = tegra_gpio_pin_write;
	bank->bank_gc.gp_pin_ctl = tegra_gpio_pin_ctl;

	const uint32_t cnf = GPIO_READ(bank, GPIO_CNF_REG);

	for (pin = 0; pin < __arraycount(bank->bank_pins); pin++) {
		bank->bank_pins[pin].pin_num = pin;
		/* skip pins in SFIO mode */
		if ((cnf & __BIT(pin)) == 0)
			continue;
		bank->bank_pins[pin].pin_caps =
		    GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
		    GPIO_PIN_TRISTATE;
		bank->bank_pins[pin].pin_state =
		    tegra_gpio_pin_read(bank, pin);
	}

	memset(&gba, 0, sizeof(gba));
	gba.gba_gc = &bank->bank_gc;
	gba.gba_pins = bank->bank_pins;
	gba.gba_npins = __arraycount(bank->bank_pins);

	bank->bank_dev = config_found_ia(sc->sc_dev, "gpiobus", &gba,
	    tegra_gpio_cfprint);
}
예제 #2
0
파일: emdtv_ir.c 프로젝트: ryo/netbsd-src
void
emdtv_ir_attach(struct emdtv_softc *sc)
{
	struct ir_attach_args ia;
	usb_endpoint_descriptor_t *ed;
	usbd_status status;
	int err;

	ed = usbd_interface2endpoint_descriptor(sc->sc_iface, 0);
	if (ed == NULL)
		return;

	status = usbd_open_pipe_intr(sc->sc_iface, ed->bEndpointAddress,
	    USBD_EXCLUSIVE_USE, &sc->sc_intr_pipe, sc, &sc->sc_intr_buf, 1,
	    emdtv_ir_intr, USBD_DEFAULT_INTERVAL);
	if (status != USBD_NORMAL_COMPLETION) {
		aprint_error_dev(sc->sc_dev, "couldn't open intr pipe: %s\n",
		    usbd_errstr(status));
		return;
	}

	mutex_init(&sc->sc_ir_mutex, MUTEX_DEFAULT, IPL_VM);

	err = workqueue_create(&sc->sc_ir_wq, "emdtvir",
	    emdtv_ir_worker, sc, PRI_NONE, IPL_VM, 0);
	if (err)
		aprint_error_dev(sc->sc_dev, "couldn't create workqueue: %d\n",
		    err);

	ia.ia_type = IR_TYPE_CIR;
	ia.ia_methods = &emdtv_ir_methods;
	ia.ia_handle = sc;

	sc->sc_cirdev =
	    config_found_ia(sc->sc_dev, "irbus", &ia, ir_print);
}
예제 #3
0
static void
eppcic_config_socket(struct eppcic_handle *ph)
{
    struct eppcic_softc *sc = ph->ph_sc;
    eppcic_chipset_tag_t pcic = sc->sc_pcic;
    struct pcmciabus_attach_args paa;
    int wait;

    paa.paa_busname = "pcmcia";
    paa.pct = (pcmcia_chipset_tag_t)&eppcic_functions;
    paa.pch = (pcmcia_chipset_handle_t)ph;
    paa.iobase = ph->ph_space[IO].base;
    paa.iosize = ph->ph_space[IO].size;
    ph->ph_card = config_found_ia((void*)sc, "pcmciabus", &paa,
                                  eppcic_print);

    epgpio_intr_establish(sc->sc_gpio, ph->ph_port, ph->ph_cd[0],
                          EDGE_TRIGGER | FALLING_EDGE | DEBOUNCE,
                          IPL_TTY, eppcic_intr_carddetect, ph);
    epgpio_intr_establish(sc->sc_gpio, ph->ph_port, ph->ph_cd[1],
                          EDGE_TRIGGER | RISING_EDGE | DEBOUNCE,
                          IPL_TTY, eppcic_intr_carddetect, ph);
    wait = (pcic->power_ctl)(sc, ph->ph_socket, POWER_OFF);
    delay(wait);


    ph->ph_status[0] = epgpio_read(sc->sc_gpio, ph->ph_port, ph->ph_cd[0]);
    ph->ph_status[1] = epgpio_read(sc->sc_gpio, ph->ph_port, ph->ph_cd[1]);

    DPRINTFN(1, ("eppcic_config_socket: cd1=%d, cd2=%d\n",ph->ph_status[0],ph->ph_status[1]));

    ph->ph_run = 1;
    kthread_create(PRI_NONE, 0, NULL, eppcic_event_thread, ph,
                   &ph->ph_event_thread, "%s,%d", sc->sc_dev.dv_xname,
                   ph->ph_socket);
}
예제 #4
0
static void
mppb_attach(device_t parent, device_t self, void *aux)
{
	struct mppb_softc *sc;
	struct pcibus_attach_args pba;  
	struct zbus_args *zap;
	pci_chipset_tag_t pc;
#ifdef PCI_NETBSD_CONFIGURE
	struct extent *ioext, *memext;
#endif /* PCI_NETBSD_CONFIGURE */

	zap = aux;
	sc = device_private(self);
	pc = &sc->apc;
	sc->sc_dev = self;
	sc->ba = zap->va;

	aprint_normal(": Matay Prometheus PCI bridge\n"); 

	/* Setup bus space mappings. */
	sc->pci_conf_area.base = (bus_addr_t) sc->ba + MPPB_CONF_BASE;
	sc->pci_conf_area.absm = &amiga_bus_stride_1swap;

	sc->pci_mem_area.base = (bus_addr_t) sc->ba + MPPB_MEM_BASE;
	sc->pci_mem_area.absm = &amiga_bus_stride_1;

	sc->pci_io_area.base = (bus_addr_t) sc->ba + MPPB_IO_BASE;
	sc->pci_io_area.absm = &amiga_bus_stride_1;
	
#ifdef MPPB_DEBUG 
	aprint_normal("mppb mapped conf %x->%x, mem %x->%x\n, io %x->%x\n",
	    kvtop((void*) sc->pci_conf_area.base), sc->pci_conf_area.base,
	    kvtop((void*) sc->pci_mem_area.base), sc->pci_mem_area.base,
	    kvtop((void*) sc->pci_io_area.base), sc->pci_io_area.base); 
#endif 

	sc->apc.pci_conf_datat = &(sc->pci_conf_area);

	if (bus_space_map(sc->apc.pci_conf_datat, 0, MPPB_CONF_SIZE, 0, 
	    &sc->apc.pci_conf_datah)) 
		aprint_error_dev(self,
		    "couldn't map PCI configuration data space\n");
	
	/* Initialize the PCI chipset tag. */
	sc->apc.pc_conf_v = (void*) pc;
	sc->apc.pc_bus_maxdevs = mppb_pci_bus_maxdevs;
	sc->apc.pc_make_tag = amiga_pci_make_tag;
	sc->apc.pc_decompose_tag = amiga_pci_decompose_tag;
	sc->apc.pc_conf_read = mppb_pci_conf_read;
	sc->apc.pc_conf_write = mppb_pci_conf_write;
	sc->apc.pc_attach_hook = mppb_pci_attach_hook;

	sc->apc.pc_intr_map = mppb_pci_intr_map;
	sc->apc.pc_intr_string = amiga_pci_intr_string;
	sc->apc.pc_intr_establish = amiga_pci_intr_establish;
	sc->apc.pc_intr_disestablish = amiga_pci_intr_disestablish;

	sc->apc.pc_conf_hook = amiga_pci_conf_hook;
	sc->apc.pc_conf_interrupt = amiga_pci_conf_interrupt;

#ifdef PCI_NETBSD_CONFIGURE
	ioext = extent_create("mppbio",  MPPB_IO_BASE, 
	    MPPB_IO_BASE + MPPB_IO_SIZE, NULL, 0, EX_NOWAIT);
	memext = extent_create("mppbmem",  MPPB_MEM_BASE, 
	    MPPB_MEM_BASE + MPPB_MEM_SIZE, NULL, 0, EX_NOWAIT);

#ifdef MPPB_DEBUG	
	aprint_normal("mppb: reconfiguring the bus!\n");
#endif /* MPPB_DEBUG */
	pci_configure_bus(pc, ioext, memext, NULL, 0, CACHELINE_SIZE);

	extent_destroy(ioext);
	extent_destroy(memext);
#endif /* PCI_NETBSD_CONFIGURE */

	pba.pba_iot = &(sc->pci_io_area);
	pba.pba_memt = &(sc->pci_mem_area);
	pba.pba_dmat = NULL; 
	pba.pba_dmat64 = NULL;
	pba.pba_pc = pc;
	pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;

	config_found_ia(self, "pcibus", &pba, pcibusprint);
}
예제 #5
0
static void
macepci_attach(device_t parent, device_t self, void *aux)
{
	struct macepci_softc *sc = device_private(self);
	pci_chipset_tag_t pc = &sc->sc_pc;
	struct mace_attach_args *maa = aux;
	struct pcibus_attach_args pba;
	u_int32_t control;
	int rev;

	if (bus_space_subregion(maa->maa_st, maa->maa_sh,
	    maa->maa_offset, 0, &pc->ioh) )
		panic("macepci_attach: couldn't map");

	pc->iot = maa->maa_st;

	rev = bus_space_read_4(pc->iot, pc->ioh, MACEPCI_REVISION);
	printf(": rev %d\n", rev);

	pc->pc_bus_maxdevs = macepci_bus_maxdevs;
	pc->pc_conf_read = macepci_conf_read;
	pc->pc_conf_write = macepci_conf_write;
	pc->pc_intr_map = macepci_intr_map;
	pc->pc_intr_string = macepci_intr_string;
	pc->intr_establish = mace_intr_establish;
	pc->intr_disestablish = mace_intr_disestablish;

	bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_ERROR_ADDR, 0);
	bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_ERROR_FLAGS, 0);

	/* Turn on PCI error interrupts */
	bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_CONTROL,
	    MACE_PCI_CONTROL_SERR_ENA |
	    MACE_PCI_CONTROL_PARITY_ERR |
	    MACE_PCI_CONTROL_PARK_LIU |
	    MACE_PCI_CONTROL_OVERRUN_INT |
	    MACE_PCI_CONTROL_PARITY_INT |
	    MACE_PCI_CONTROL_SERR_INT |
	    MACE_PCI_CONTROL_IT_INT |
	    MACE_PCI_CONTROL_RE_INT |
	    MACE_PCI_CONTROL_DPED_INT |
	    MACE_PCI_CONTROL_TAR_INT |
	    MACE_PCI_CONTROL_MAR_INT);

	/*
	 * Enable all MACE PCI interrupts. They will be masked by
	 * the CRIME code.
	 */
	control = bus_space_read_4(pc->iot, pc->ioh, MACEPCI_CONTROL);
	control |= CONTROL_INT_MASK;
	bus_space_write_4(pc->iot, pc->ioh, MACEPCI_CONTROL, control);

#if NPCI > 0
	pc->pc_ioext = extent_create("macepciio", 0x00001000, 0x01ffffff,
	    NULL, 0, EX_NOWAIT);
	pc->pc_memext = extent_create("macepcimem", 0x80100000, 0x81ffffff,
	    NULL, 0, EX_NOWAIT);
	pci_configure_bus(pc, pc->pc_ioext, pc->pc_memext, NULL, 0,
	    mips_cache_info.mci_dcache_align);
	memset(&pba, 0, sizeof pba);
/*XXX*/	pba.pba_iot = SGIMIPS_BUS_SPACE_IO;
/*XXX*/	pba.pba_memt = SGIMIPS_BUS_SPACE_MEM;
	pba.pba_dmat = &pci_bus_dma_tag;
	pba.pba_dmat64 = NULL;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
	    PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
	pba.pba_pc = pc;

#ifdef MACEPCI_IO_WAS_BUGGY
	if (rev == 0)
		pba.pba_flags &= ~PCI_FLAGS_IO_OKAY;		/* Buggy? */
#endif

	cpu_intr_establish(maa->maa_intr, IPL_NONE, macepci_intr, sc);

	config_found_ia(self, "pcibus", &pba, pcibusprint);
#endif
}
예제 #6
0
static void
jmide_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct jmide_softc *sc = device_private(self);
	const struct jmide_product *jp;
	const char *intrstr;
        pci_intr_handle_t intrhandle;
	u_int32_t pcictrl0 = pci_conf_read(pa->pa_pc, pa->pa_tag,
	    PCI_JM_CONTROL0);
	u_int32_t pcictrl1 = pci_conf_read(pa->pa_pc, pa->pa_tag,
	    PCI_JM_CONTROL1);
	struct pciide_product_desc *pp;
	int ahci_used = 0;

	sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev = self;

	jp = jmide_lookup(pa->pa_id);
	if (jp == NULL) {
		printf("jmide_attach: WTF?\n");
		return;
	}
	sc->sc_npata = jp->jm_npata;
	sc->sc_nsata = jp->jm_nsata;

        pci_aprint_devinfo(pa, "JMICRON PATA/SATA disk controller");

	aprint_normal("%s: ", JM_NAME(sc));
	if (sc->sc_npata)
		aprint_normal("%d PATA port%s", sc->sc_npata,
		    (sc->sc_npata > 1) ? "s" : "");
	if (sc->sc_nsata)
		aprint_normal("%s%d SATA port%s", sc->sc_npata ? ", " : "",
		    sc->sc_nsata, (sc->sc_nsata > 1) ? "s" : "");
	aprint_normal("\n");

	if (pci_intr_map(pa, &intrhandle) != 0) {
                aprint_error("%s: couldn't map interrupt\n", JM_NAME(sc));
                return;
        }
        intrstr = pci_intr_string(pa->pa_pc, intrhandle);
        sc->sc_pciide.sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle,
	    IPL_BIO, jmide_intr, sc);
        if (sc->sc_pciide.sc_pci_ih == NULL) {
                aprint_error("%s: couldn't establish interrupt", JM_NAME(sc));
                return;
        }
        aprint_normal("%s: interrupting at %s\n", JM_NAME(sc),
            intrstr ? intrstr : "unknown interrupt");

	if (pcictrl0 & JM_CONTROL0_AHCI_EN) {
		bus_size_t size;
		struct jmahci_attach_args jma;
		u_int32_t saved_pcictrl0;
		/*
		 * ahci controller enabled; disable sata on pciide and
		 * enable on ahci
		 */
		saved_pcictrl0 = pcictrl0;
		pcictrl0 |= JM_CONTROL0_SATA0_AHCI | JM_CONTROL0_SATA1_AHCI;
		pcictrl0 &= ~(JM_CONTROL0_SATA0_IDE | JM_CONTROL0_SATA1_IDE);
		pci_conf_write(pa->pa_pc, pa->pa_tag,
		    PCI_JM_CONTROL0, pcictrl0);
		/* attach ahci controller if on the right function */
		if ((pa->pa_function == 0 &&
		      (pcictrl0 & JM_CONTROL0_AHCI_F1) == 0) ||
	    	    (pa->pa_function == 1 &&
		      (pcictrl0 & JM_CONTROL0_AHCI_F1) != 0)) {
			jma.jma_pa = pa;
			/* map registers */
			if (pci_mapreg_map(pa, AHCI_PCI_ABAR,
			    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
			    &jma.jma_ahcit, &jma.jma_ahcih, NULL, &size) != 0) {
				aprint_error("%s: can't map ahci registers\n",
				    JM_NAME(sc));
			} else {
				sc->sc_ahci = config_found_ia(
				    sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev,
				    "jmide_hl", &jma, jmahci_print);
			}
			/*
			 * if we couldn't attach an ahci, try to fall back
			 * to pciide. Note that this will not work if IDE
			 * is on function 0 and AHCI on function 1.
			 */
			if (sc->sc_ahci == NULL) {
				pcictrl0 = saved_pcictrl0 &
				    ~(JM_CONTROL0_SATA0_AHCI |
				      JM_CONTROL0_SATA1_AHCI |
				      JM_CONTROL0_AHCI_EN);
				pcictrl0 |= JM_CONTROL0_SATA1_IDE |
					JM_CONTROL0_SATA0_IDE;
				pci_conf_write(pa->pa_pc, pa->pa_tag,
				    PCI_JM_CONTROL0, pcictrl0);
			} else
				ahci_used = 1;
		}
	}
	sc->sc_chan_swap = ((pcictrl0 & JM_CONTROL0_PCIIDE_CS) != 0);
	/* compute the type of internal primary channel */
	if (pcictrl1 & JM_CONTROL1_PATA1_PRI) {
		if (sc->sc_npata > 1)
			sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_PATA;
		else
			sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_NONE;
	} else if (ahci_used == 0 && sc->sc_nsata > 0)
		sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_SATA;
	else
		sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_NONE;
	/* compute the type of internal secondary channel */
	if (sc->sc_nsata > 1 && ahci_used == 0 &&
	    (pcictrl0 & JM_CONTROL0_PCIIDE0_MS) == 0) {
		sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_SATA;
	} else {
		/* only a drive if first PATA enabled */
		if (sc->sc_npata > 0 && (pcictrl0 & JM_CONTROL0_PATA0_EN)
		    && (pcictrl0 &
		    (sc->sc_chan_swap ? JM_CONTROL0_PATA0_PRI: JM_CONTROL0_PATA0_SEC)))
			sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_PATA;
		else
			sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_NONE;
	}

	if (sc->sc_chan_type[0] == TYPE_NONE &&
	    sc->sc_chan_type[1] == TYPE_NONE)
		return;
	if (pa->pa_function == 0 && (pcictrl0 & JM_CONTROL0_PCIIDE_F1))
		return;
	if (pa->pa_function == 1 && (pcictrl0 & JM_CONTROL0_PCIIDE_F1) == 0)
		return;
	pp = malloc(sizeof(struct pciide_product_desc), M_DEVBUF, M_NOWAIT);
	if (pp == NULL) {
		aprint_error("%s: can't malloc sc_pp\n", JM_NAME(sc));
		return;
	}
	aprint_normal("%s: PCI IDE interface used", JM_NAME(sc));
	pp->ide_product = 0;
	pp->ide_flags = 0;
	pp->ide_name = NULL;
	pp->chip_map = jmpata_chip_map;
	pciide_common_attach(&sc->sc_pciide, pa, pp);
	
}
예제 #7
0
void
gtpci_attach(struct device *parent, struct device *self, void *aux)
{
	struct pcibus_attach_args pba;
	struct gt_attach_args * const ga = aux;
	struct gt_softc * const gt = device_private(parent);
	struct gtpci_softc * const gtp = device_private(self);
	struct gtpci_chipset * const gtpc = &gtp->gtpci_gtpc;
	struct pci_chipset * const pc = &gtpc->gtpc_pc;
	const int busno = ga->ga_unit;
	uint32_t data;

	GT_PCIFOUND(gt, ga);

	pc->pc_funcs = &gtpci_functions;
	pc->pc_parent = self;

	gtpc->gtpc_busno = busno;
	gtpc->gtpc_cfgaddr = PCI_CONFIG_ADDR(busno);
	gtpc->gtpc_cfgdata = PCI_CONFIG_DATA(busno);
	gtpc->gtpc_syncreg = PCI_SYNC_REG(busno);
	gtpc->gtpc_gt_memt = ga->ga_memt;
	gtpc->gtpc_gt_memh = ga->ga_memh;

	/*
	 * Let's find out where we are located.
	 */
	data = gtpci_read(gtpc, PCI_P2P_CONFIGURATION(gtpc->gtpc_busno));
	gtpc->gtpc_self = gtpci_make_tag(&gtpc->gtpc_pc,
		PCI_P2PCFG_BusNum_GET(data), PCI_P2PCFG_DevNum_GET(data), 0);


	switch (busno) {
	case 0:
		gtpc->gtpc_io_bs = gt->gt_pci0_iot;
		gtpc->gtpc_mem_bs = gt->gt_pci0_memt;
		gtpc->gtpc_host = gt->gt_pci0_host;
		break;
	case 1:
		gtpc->gtpc_io_bs = gt->gt_pci1_iot;
		gtpc->gtpc_mem_bs = gt->gt_pci1_memt;
		gtpc->gtpc_host = gt->gt_pci1_host;
		break;
	default:
		break;
	}

	/*
	 * If no bus_spaces exist, then it's been disabled.
	 */
	if (gtpc->gtpc_io_bs == NULL && gtpc->gtpc_mem_bs == NULL) {
		aprint_normal(": disabled\n");
		return;
	}

	aprint_normal("\n");

	/*
	 * clear any pre-existing error interrupt(s)
	 * clear latched pci error registers
	 * establish ISRs for PCI errors
	 * enable PCI error interrupts
	 */
	gtpci_write(gtpc, PCI_ERROR_MASK(gtpc->gtpc_busno), 0);
	gtpci_write(gtpc, PCI_ERROR_CAUSE(gtpc->gtpc_busno), 0);
	(void)gtpci_read(gtpc, PCI_ERROR_DATA_LOW(gtpc->gtpc_busno));
	(void)gtpci_read(gtpc, PCI_ERROR_DATA_HIGH(gtpc->gtpc_busno));
	(void)gtpci_read(gtpc, PCI_ERROR_COMMAND(gtpc->gtpc_busno));
	(void)gtpci_read(gtpc, PCI_ERROR_ADDRESS_HIGH(gtpc->gtpc_busno));
	(void)gtpci_read(gtpc, PCI_ERROR_ADDRESS_LOW(gtpc->gtpc_busno));
	if (gtpc->gtpc_host) {
		intr_establish(pci_irqs[gtpc->gtpc_busno][0], IST_LEVEL,
		    IPL_VM, gtpci_error_intr, pc);
		intr_establish(pci_irqs[gtpc->gtpc_busno][1], IST_LEVEL,
		    IPL_VM, gtpci_error_intr, pc);
		intr_establish(pci_irqs[gtpc->gtpc_busno][2], IST_LEVEL,
		    IPL_VM, gtpci_error_intr, pc);
		aprint_normal_dev(pc->pc_parent, "%s%d error interrupts at irqs %s, %s, %s\n",
		    "pci", busno,
		    intr_string(pci_irqs[gtpc->gtpc_busno][0]),
		    intr_string(pci_irqs[gtpc->gtpc_busno][1]),
		    intr_string(pci_irqs[gtpc->gtpc_busno][2]));
		gtpci_write(gtpc, PCI_ERROR_MASK(gtpc->gtpc_busno),
		    PCI_SERRMSK_ALL_ERRS);
	}

	/*
	 * Fill in the pci_bus_attach_args
	 */
	pba.pba_pc = pc;
	pba.pba_bus = 0;
	pba.pba_iot = gtpc->gtpc_io_bs;
	pba.pba_memt = gtpc->gtpc_mem_bs;
	pba.pba_dmat = gt->gt_dmat;
	pba.pba_flags = 0;
	if (pba.pba_iot != NULL)
		pba.pba_flags |= PCI_FLAGS_IO_ENABLED;
	if (pba.pba_memt != NULL)
		pba.pba_flags |= PCI_FLAGS_MEM_ENABLED;

	data = gtpci_read(gtpc, PCI_COMMAND(gtpc->gtpc_busno));
	if (data & PCI_CMD_MRdMul)
		pba.pba_flags |= PCI_FLAGS_MRM_OKAY;
	if (data & PCI_CMD_MRdLine)
		pba.pba_flags |= PCI_FLAGS_MRL_OKAY;
	pba.pba_flags |= PCI_FLAGS_MWI_OKAY;

	gt_watchdog_service();
	/*
	 * Configure the pci bus.
	 */
	config_found_ia(self, "pcibus", &pba, gtpci_cfprint);

	gt_watchdog_service();

}
예제 #8
0
파일: mainbus.c 프로젝트: ryo/netbsd-src
/*
 * Attach the mainbus.
 */
void
mainbus_attach(device_t parent, device_t self, void *aux)
{
	struct pcibus_attach_args pba;
#if NPCI > 0
	struct genppc_pci_chipset_businfo *pbi;
#endif
#ifdef PCI_NETBSD_CONFIGURE
	struct extent *ioext, *memext;
#endif

	mainbus_found = 1;

	aprint_normal("\n");

	/* attach cpu */
	config_found_ia(self, "mainbus", NULL, mainbus_print);

	/*
	 * XXX Note also that the presence of a PCI bus should
	 * XXX _always_ be checked, and if present the bus should be
	 * XXX 'found'.  However, because of the structure of the code,
	 * XXX that's not currently possible.
	 */
#if NPCI > 0
	genppc_pct = malloc(sizeof(struct genppc_pci_chipset), M_DEVBUF,
	    M_NOWAIT);
	KASSERT(genppc_pct != NULL);
	mvmeppc_pci_get_chipset_tag(genppc_pct);

	pbi = malloc(sizeof(struct genppc_pci_chipset_businfo),
	    M_DEVBUF, M_NOWAIT);
	KASSERT(pbi != NULL);
	pbi->pbi_properties = prop_dictionary_create();
	KASSERT(pbi->pbi_properties != NULL);

	SIMPLEQ_INIT(&genppc_pct->pc_pbi);
	SIMPLEQ_INSERT_TAIL(&genppc_pct->pc_pbi, pbi, next);

#ifdef PCI_NETBSD_CONFIGURE
	ioext  = extent_create("pciio",  0x00008000, 0x0000ffff,
	    NULL, 0, EX_NOWAIT);
	memext = extent_create("pcimem", 0x00000000, 0x0fffffff,
	    NULL, 0, EX_NOWAIT);

	pci_configure_bus(genppc_pct, ioext, memext, NULL, 0, CACHELINESIZE);

	extent_destroy(ioext);
	extent_destroy(memext);
#endif

	pba.pba_iot = &prep_io_space_tag;
	pba.pba_memt = &prep_mem_space_tag;
	pba.pba_dmat = &pci_bus_dma_tag;
	pba.pba_dmat64 = NULL;
	pba.pba_pc = genppc_pct;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
	config_found_ia(self, "pcibus", &pba, pcibusprint);
#endif
}
예제 #9
0
파일: igma.c 프로젝트: ryoon/netbsd-xhci
static void
igma_i2c_attach(struct igma_softc *sc)
{
	struct igma_i2c *ii;
	int i;
#if 0
	struct i2cbus_attach_args iba;
#endif

	for (i=0; i<sc->sc_chip.num_gmbus; ++i) {
		ii = &sc->sc_ii[i];
		ii->ii_sc = sc;

		/* XXX */
		ii->ii_reg = sc->sc_chip.gpio_offset - PCH_GPIOA;
		switch (i) {
		case 0:
			ii->ii_reg += PCH_GPIOB;
			ii->ii_name = "ssc";
			break;
		case 1:
			ii->ii_reg += PCH_GPIOA;
			ii->ii_name = "vga";
			break;
		case 2:
			ii->ii_reg += PCH_GPIOC;
			ii->ii_name = "panel";
			break;
		case 3:
			ii->ii_reg += PCH_GPIOD;
			ii->ii_name = "dpc";
			break;
		case 4:
			ii->ii_reg += PCH_GPIOE;
			ii->ii_name = "dpb";
			break;
		case 5:
			ii->ii_reg += PCH_GPIOF;
			ii->ii_name = "dpd";
			break;
		default:
			panic("don't know GMBUS %d\n",i);
		}

		mutex_init(&ii->ii_lock, MUTEX_DEFAULT, IPL_NONE);

		ii->ii_i2c.ic_cookie = ii;
		ii->ii_i2c.ic_acquire_bus = igma_i2c_acquire_bus;
		ii->ii_i2c.ic_release_bus = igma_i2c_release_bus;
		ii->ii_i2c.ic_send_start = igma_i2c_send_start;
		ii->ii_i2c.ic_send_stop = igma_i2c_send_stop;
		ii->ii_i2c.ic_initiate_xfer = igma_i2c_initiate_xfer;
		ii->ii_i2c.ic_read_byte = igma_i2c_read_byte;
		ii->ii_i2c.ic_write_byte = igma_i2c_write_byte;
		ii->ii_i2c.ic_exec = NULL;

#if 0
		iba.iba_type = I2C_TYPE_SMBUS;
		iba.iba_tag = &ii->ii_i2c;
		config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
#endif
	}
}
예제 #10
0
static void
pchbattach(device_t parent, device_t self, void *aux)
{
	struct plb_attach_args *paa = aux;
	struct pcibus_attach_args pba;
	char devinfo[256];
#ifdef PCI_NETBSD_CONFIGURE
	struct extent *ioext, *memext;
#ifdef PCI_CONFIGURE_VERBOSE
	extern int pci_conf_debug;

	pci_conf_debug = 1;
#endif
#endif
	pci_chipset_tag_t pc = 0;
	pcitag_t tag; 
	int class, id;

	pci_machdep_init();
	tag = pci_make_tag(pc, 0, 0, 0);

	class = pci_conf_read(pc, tag, PCI_CLASS_REG);
	id = pci_conf_read(pc, tag, PCI_ID_REG);

	aprint_normal("\n");
	pcifound = true;
	/*
	 * All we do is print out a description.  Eventually, we
	 * might want to add code that does something that's
	 * possibly chipset-specific.
	 */

	pci_devinfo(id, class, 0, devinfo, sizeof(devinfo));
	aprprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo,
	    PCI_REVISION(class));

	pci_machdep_init(); /* Redundant... */
	ibm4xx_setup_pci();
#ifdef PCI_CONFIGURE_VERBOSE
	ibm4xx_show_pci_map();
#endif

	if (bus_space_init(&pchb_io_tag, "pchbio", NULL, 0))
		panic("pchbattach: can't init IO tag");
	if (bus_space_init(&pchb_mem_tag, "pchbmem", NULL, 0))
		panic("pchbattach: can't init MEM tag");

#ifdef PCI_NETBSD_CONFIGURE
	memext = extent_create("pcimem", MIN_PCI_MEMADDR_NOPREFETCH,
	    MIN_PCI_MEMADDR_NOPREFETCH + 0x1fffffff, M_DEVBUF, NULL, 0,
	    EX_NOWAIT);
	ioext = extent_create("pciio", MIN_PCI_PCI_IOADDR,
	    MIN_PCI_PCI_IOADDR + 0xffff, M_DEVBUF, NULL, 0, EX_NOWAIT);
	pci_configure_bus(0, ioext, memext, NULL, 0, 32);
	extent_destroy(memext);
	extent_destroy(ioext);
#endif /* PCI_NETBSD_CONFIGURE */

#ifdef PCI_CONFIGURE_VERBOSE
	printf("running config_found PCI\n");
#endif
	/* IO window located @ e8000000 and maps to 0-0xffff */
	pba.pba_iot = &pchb_io_tag;
	/* PCI memory window is directly mapped */
	pba.pba_memt = &pchb_mem_tag;
	pba.pba_dmat = paa->plb_dmat;
	pba.pba_dmat64 = NULL;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;
	pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY;
	config_found_ia(self, "pcibus", &pba, pchbprint);
}
예제 #11
0
static void
ofbattach(device_t parent, device_t self, void *aux)
{
	struct ofb_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct wsemuldisplaydev_attach_args a;
	struct rasops_info *ri = &rascons_console_screen.scr_ri;
	long defattr;
	int console, node, sub;
	char devinfo[256];

	sc->sc_dev = self;

	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	printf(": %s\n", devinfo);

	if (console_node == 0)
		return;

	node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
	console = (node == console_node);
	if (!console) {
		/* check if any of the childs matches */
		sub = OF_child(node);
		while ((sub != 0) && (sub != console_node)) {
			sub = OF_peer(sub);
		}
		if (sub == console_node) {
			console = true;
		}
	}
	
	sc->sc_memt = pa->pa_memt;
	sc->sc_iot = pa->pa_iot;	
	sc->sc_pc = pa->pa_pc;
	sc->sc_pcitag = pa->pa_tag;
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;

	if (!console)
		return;
	
	vcons_init(&sc->vd, sc, &rascons_stdscreen, &ofb_accessops);
	sc->vd.init_screen = ofb_init_screen;

	sc->sc_node = console_node;

	sc->sc_ih = console_instance;
	vcons_init_screen(&sc->vd, &rascons_console_screen, 1, &defattr);
	rascons_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
	
	printf("%s: %d x %d, %dbpp\n", device_xname(self),
	       ri->ri_width, ri->ri_height, ri->ri_depth);
	
	sc->sc_fbaddr = 0;
	if (OF_getprop(sc->sc_node, "address", &sc->sc_fbaddr, 4) != 4)
		OF_interpret("frame-buffer-adr", 0, 1, &sc->sc_fbaddr);
	if (sc->sc_fbaddr == 0) {
		printf("%s: Unable to find the framebuffer address.\n",
		    device_xname(sc->sc_dev));
		return;
	}
	sc->sc_fbsize = round_page(ri->ri_stride * ri->ri_height);

	/* XXX */
	if (OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs,
	    sizeof(sc->sc_addrs)) == -1) {
		sc->sc_node = OF_parent(sc->sc_node);
		OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs,
		    sizeof(sc->sc_addrs));
	}

	ofb_init_cmap(sc);

	a.console = console;
	a.scrdata = &ofb_screenlist;
	a.accessops = &ofb_accessops;
	a.accesscookie = &sc->vd;

	config_found(self, &a, wsemuldisplaydevprint);

	config_found_ia(self, "drm", aux, ofb_drm_print);
}
static void
obio_attach(device_t parent, device_t self, void *aux)
{
	struct obio_softc *sc = device_private(self);
	struct mainbus_attach_args *mb = (struct mainbus_attach_args *)aux;
#if NPCI > 0
	struct pcibus_attach_args pba;
#endif

	sc->sc_dev = self;

	sc->sc_iot = &gemini_bs_tag;

	aprint_normal(": On-Board IO\n");

#if (GEMINI_BUSBASE != 0)
	sc->sc_dmarange.dr_sysbase = 0;
	sc->sc_dmarange.dr_busbase = (GEMINI_BUSBASE * 1024 * 1024);
	sc->sc_dmarange.dr_len = MEMSIZE * 1024 * 1024;
	gemini_bus_dma_tag._ranges = &sc->sc_dmarange;
	gemini_bus_dma_tag._nranges = 1;
#endif

	sc->sc_ioh = 0;
	sc->sc_dmat = &gemini_bus_dma_tag;
	sc->sc_base = mb->mb_iobase;
	sc->sc_size = mb->mb_iosize;

	/*
	 * Attach critical devices first.
	 */
	obio_attach_critical(sc);

#if NPCI > 0
	/*
	 * map PCI controller registers
	 */
	if (bus_space_map(sc->sc_iot, GEMINI_PCICFG_BASE,
		GEMINI_PCI_CFG_DATA+4, 0, &sc->sc_pcicfg_ioh)) {
			aprint_error("cannot map PCI controller at %#x\n",
				GEMINI_PCICFG_BASE);
			return;
	}
	/*
	 * initialize the PCI chipset tag
	 */
	gemini_pci_init(&sc->sc_pci_chipset, sc);
#endif	/* NPCI */

	/*
	 * attach the rest of our devices
	 */
	config_search_ia(obio_search, self, "obio", NULL);

#if NPCI > 0
	/*
	 * attach the PCI bus
	 */
	pba.pba_memt = sc->sc_iot;
	pba.pba_iot =  sc->sc_iot;
	pba.pba_dmat = sc->sc_dmat;
	pba.pba_dmat64 = NULL;
	pba.pba_pc = &sc->sc_pci_chipset;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;
	pba.pba_intrswiz = 0;
	pba.pba_intrtag = 0;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
	    PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;

	(void) config_found_ia(sc->sc_dev, "pcibus", &pba, pcibusprint);
#endif	/* NPCI */
	
}
예제 #13
0
static void
coram_attach(device_t parent, device_t self, void *aux)
{
	struct coram_softc *sc = device_private(self);
	const struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	pcireg_t reg;
	const char *intrstr;
	struct coram_iic_softc *cic;
	uint32_t value;
	int i;
#ifdef CORAM_ATTACH_I2C
	struct i2cbus_attach_args iba;
#endif

	sc->sc_dev = self;

	pci_aprint_devinfo(pa, NULL);

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	sc->sc_board = coram_board_lookup(PCI_VENDOR(reg), PCI_PRODUCT(reg));
	KASSERT(sc->sc_board != NULL);

	if (pci_mapreg_map(pa, CX23885_MMBASE, PCI_MAPREG_TYPE_MEM, 0,
			   &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) {
		aprint_error_dev(self, "couldn't map memory space\n");
		return;
	}

	sc->sc_dmat = pa->pa_dmat;
	sc->sc_pc = pa->pa_pc;

	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_VM, coram_intr, self);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	/* set master */
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	reg |= PCI_COMMAND_MASTER_ENABLE;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg);

	/* I2C */
	for(i = 0; i < I2C_NUM; i++) {
		cic = &sc->sc_iic[i];

		cic->cic_sc = sc;
		if (bus_space_subregion(sc->sc_memt, sc->sc_memh,
		    I2C_BASE + (I2C_SIZE * i), I2C_SIZE, &cic->cic_regh))
			panic("failed to subregion i2c");

		mutex_init(&cic->cic_busmutex, MUTEX_DRIVER, IPL_NONE);
		cic->cic_i2c.ic_cookie = cic;
		cic->cic_i2c.ic_acquire_bus = coram_iic_acquire_bus;
		cic->cic_i2c.ic_release_bus = coram_iic_release_bus;
		cic->cic_i2c.ic_exec = coram_iic_exec;

#ifdef CORAM_ATTACH_I2C
		/* attach iic(4) */
		memset(&iba, 0, sizeof(iba));
		iba.iba_tag = &cic->cic_i2c;
		iba.iba_type = I2C_TYPE_SMBUS;
		cic->cic_i2cdev = config_found_ia(self, "i2cbus", &iba,
		    iicbus_print);
#endif
	}

	/* HVR1250 GPIO */
	value = bus_space_read_4(sc->sc_memt, sc->sc_memh, 0x110010);
#if 1
	value &= ~0x00010001;
	bus_space_write_4(sc->sc_memt, sc->sc_memh, 0x110010, value);
	delay(5000);
#endif
	value |= 0x00010001;
	bus_space_write_4(sc->sc_memt, sc->sc_memh, 0x110010, value);

#if 0
	int i;
	uint8_t foo[256];
	uint8_t bar;
	bar = 0;
//	seeprom_bootstrap_read(&sc->sc_i2c, 0x50, 0, 256, foo, 256);

	iic_acquire_bus(&sc->sc_i2c, I2C_F_POLL);
	iic_exec(&sc->sc_i2c, I2C_OP_READ_WITH_STOP, 0x50, &bar, 1, foo, 256,
	    I2C_F_POLL);
	iic_release_bus(&sc->sc_i2c, I2C_F_POLL);

	printf("\n");
	for ( i = 0; i < 256; i++) {
		if ( (i % 8) == 0 )
			printf("%02x: ", i);

		printf("%02x", foo[i]);

		if ( (i % 8) == 7 )
			printf("\n");
		else
			printf(" ");
	}
	printf("\n");
#endif

	sc->sc_demod = cx24227_open(sc->sc_dev, &sc->sc_iic[0].cic_i2c, 0x19);
	if (sc->sc_demod == NULL)
		aprint_error_dev(self, "couldn't open cx24227\n");
	sc->sc_tuner = mt2131_open(sc->sc_dev, &sc->sc_iic[0].cic_i2c, 0x61);
	if (sc->sc_tuner == NULL)
		aprint_error_dev(self, "couldn't open mt2131\n");

	coram_mpeg_attach(sc);

	if (!pmf_device_register(self, NULL, coram_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");

	return;
}
예제 #14
0
/*
 * Attach the mainbus.
 */
void
mainbus_attach(device_t parent, device_t self, void *aux)
{
	union mainbus_attach_args mba;
#if defined(DOM0OPS) && defined(XEN3)
	int numcpus = 0;
#ifdef MPBIOS
	int mpbios_present = 0;
#endif
#if NACPI > 0 || defined(MPBIOS)
	int numioapics = 0;     
#endif
#endif /* defined(DOM0OPS) && defined(XEN3) */

	aprint_naive("\n");
	aprint_normal("\n");

#ifndef XEN3
	memset(&mba.mba_caa, 0, sizeof(mba.mba_caa));
	mba.mba_caa.cpu_number = 0;
	mba.mba_caa.cpu_role = CPU_ROLE_SP;
	mba.mba_caa.cpu_func = 0;
	config_found_ia(self, "cpubus", &mba.mba_caa, mainbus_print);
#else /* XEN3 */
#ifdef DOM0OPS
	if (xendomain_is_dom0()) {
#ifdef MPBIOS
		mpbios_present = mpbios_probe(self);
#endif
#if NPCI > 0
		/* ACPI needs to be able to access PCI configuration space. */
		pci_mode = pci_mode_detect();
#ifdef PCI_BUS_FIXUP
		pci_maxbus = pci_bus_fixup(NULL, 0);
		aprint_debug_dev(self, "PCI bus max, after pci_bus_fixup: %i\n",
		    pci_maxbus);
#ifdef PCI_ADDR_FIXUP
		pciaddr.extent_port = NULL;
		pciaddr.extent_mem = NULL;
		pci_addr_fixup(NULL, pci_maxbus);
#endif /* PCI_ADDR_FIXUP */
#endif /* PCI_BUS_FIXUP */
#if NACPI > 0
		acpi_present = acpi_probe();
		if (acpi_present)
			mpacpi_active = mpacpi_scan_apics(self,
			    &numcpus, &numioapics);
		if (!mpacpi_active)
#endif
		{
#ifdef MPBIOS
			if (mpbios_present)
				mpbios_scan(self, &numcpus, &numioapics);       
			else
#endif
			if (numcpus == 0) {
				memset(&mba.mba_caa, 0, sizeof(mba.mba_caa));
				mba.mba_caa.cpu_number = 0;
				mba.mba_caa.cpu_role = CPU_ROLE_SP;
				mba.mba_caa.cpu_func = 0;
				config_found_ia(self, "cpubus",
				    &mba.mba_caa, mainbus_print);
			}
		}
#if NIOAPIC > 0
	ioapic_enable();
#endif
#endif /* NPCI */
	}
#endif /* DOM0OPS */
#endif /* XEN3 */

#if NIPMI > 0
	memset(&mba.mba_ipmi, 0, sizeof(mba.mba_ipmi));
	mba.mba_ipmi.iaa_iot = X86_BUS_SPACE_IO;
	mba.mba_ipmi.iaa_memt = X86_BUS_SPACE_MEM;
	if (ipmi_probe(&mba.mba_ipmi))
		config_found_ia(self, "ipmibus", &mba.mba_ipmi, 0);
#endif

#if NHYPERVISOR > 0
	mba.mba_haa.haa_busname = "hypervisor";
	config_found_ia(self, "hypervisorbus", &mba.mba_haa, mainbus_print);
#endif
}
예제 #15
0
static void
bcmgpio_attach(device_t parent, device_t self, void *aux)
{
	struct bcmgpio_softc * const sc = device_private(self);
#if NGPIO > 0
	struct amba_attach_args *aaa = aux;
	struct gpiobus_attach_args gba;
	int pin, minpin, maxpin;
	u_int func;
	int error;
#endif
	
	sc->sc_dev = self;
	
#if NGPIO > 0
	if (device_unit(sc->sc_dev) > 1) {
		aprint_naive(" NO GPIO\n");	
		aprint_normal(": NO GPIO\n");
		return;
	} else if (device_unit(sc->sc_dev) == 1) {
		maxpin = 53;
		minpin = 32;
	} else {
		maxpin = 31;
		minpin = 0;
	}
	
	aprint_naive("\n");	
	aprint_normal(": GPIO [%d...%d]\n", minpin, maxpin);

	sc->sc_iot = aaa->aaa_iot;
	error = bus_space_map(sc->sc_iot, aaa->aaa_addr, aaa->aaa_size, 0,
	    &sc->sc_ioh);
	if (error) {
		aprint_error_dev(self,
		    "can't map registers for %s: %d\n", aaa->aaa_name, error);
		return;
	}

	for (pin = minpin; pin <= maxpin; pin++) {
	        int epin = pin - minpin;
	
	        sc->sc_gpio_pins[epin].pin_num = epin;
		/*
		 * find out pins still available for GPIO
		 */
		func = bcm2835gpio_function_read(pin);
		
		if (func == BCM2835_GPIO_IN ||
		    func == BCM2835_GPIO_OUT) {
	                sc->sc_gpio_pins[epin].pin_caps = GPIO_PIN_INPUT |
				GPIO_PIN_OUTPUT |
				GPIO_PIN_PUSHPULL | GPIO_PIN_TRISTATE |
				GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
			/* read initial state */
			sc->sc_gpio_pins[epin].pin_state =
				bcm2835gpio_gpio_pin_read(sc, epin);
			DPRINTF(1, ("%s: attach pin %d\n", device_xname(sc->sc_dev), pin));
                } else {
	                sc->sc_gpio_pins[epin].pin_caps = 0;
			sc->sc_gpio_pins[epin].pin_state = 0;
  			DPRINTF(1, ("%s: skip pin %d - func = 0x%x\n", device_xname(sc->sc_dev), pin, func));
                }
        }
	
	/* create controller tag */
	sc->sc_gpio_gc.gp_cookie = sc;
	sc->sc_gpio_gc.gp_pin_read = bcm2835gpio_gpio_pin_read;
	sc->sc_gpio_gc.gp_pin_write = bcm2835gpio_gpio_pin_write;
	sc->sc_gpio_gc.gp_pin_ctl = bcm2835gpio_gpio_pin_ctl;
	
	gba.gba_gc = &sc->sc_gpio_gc;
	gba.gba_pins = sc->sc_gpio_pins;
	gba.gba_npins = maxpin - minpin + 1;

	config_found_ia(self, "gpiobus", &gba, gpiobus_print);
#else
	aprint_normal_dev(sc->sc_dev, "no GPIO configured in kernel");
#endif
}
예제 #16
0
/*
 * Attach the mainbus.
 */
void
mainbus_attach(device_t parent, device_t self, void *aux)
{
	union mainbus_attach_args mba;
	struct confargs ca;

#if NPCI > 0 
	struct genppc_pci_chipset_businfo *pbi;
#ifdef PCI_NETBSD_CONFIGURE
	struct extent *ioext, *memext;
#endif
#endif
	
	mainbus_found = 1;
  
	aprint_normal("\n");


#if defined(RESIDUAL_DATA_DUMP)
	print_residual_device_info();
#endif

	/*
	 * Always find the CPU
	 */
	ca.ca_name = "cpu";
	ca.ca_node = 0;
	config_found_ia(self, "mainbus", &ca, mainbus_print);
	ca.ca_name = "cpu";
	ca.ca_node = 1;
	config_found_ia(self, "mainbus", &ca, mainbus_print);

	/*
	 * XXX Note also that the presence of a PCI bus should
	 * XXX _always_ be checked, and if present the bus should be
	 * XXX 'found'.  However, because of the structure of the code,
	 * XXX that's not currently possible.
	 */

#if NPCI > 0
	genppc_pct = malloc(sizeof(struct genppc_pci_chipset), M_DEVBUF,
	    M_NOWAIT);
	KASSERT(genppc_pct != NULL);
	bebox_pci_get_chipset_tag(genppc_pct);

	pbi = malloc(sizeof(struct genppc_pci_chipset_businfo),
	    M_DEVBUF, M_NOWAIT);
	KASSERT(pbi != NULL);
	pbi->pbi_properties = prop_dictionary_create();
        KASSERT(pbi->pbi_properties != NULL);

	SIMPLEQ_INIT(&genppc_pct->pc_pbi);
	SIMPLEQ_INSERT_TAIL(&genppc_pct->pc_pbi, pbi, next);

#ifdef PCI_NETBSD_CONFIGURE
	ioext  = extent_create("pciio",  0x00008000, 0x0000ffff,
	    NULL, 0, EX_NOWAIT);
	memext = extent_create("pcimem", 0x00000000, 0x0fffffff,
	    NULL, 0, EX_NOWAIT);

	pci_configure_bus(genppc_pct, ioext, memext, NULL, 0, CACHELINESIZE);

	extent_destroy(ioext);
	extent_destroy(memext);
#endif /* PCI_NETBSD_CONFIGURE */
#endif /* NPCI */

#if NPCI > 0
	memset(&mba, 0, sizeof(mba));
	mba.mba_pba.pba_iot = &prep_io_space_tag;
	mba.mba_pba.pba_memt = &prep_mem_space_tag;
	mba.mba_pba.pba_dmat = &pci_bus_dma_tag;
	mba.mba_pba.pba_dmat64 = NULL;
	mba.mba_pba.pba_pc = genppc_pct;
	mba.mba_pba.pba_bus = 0;
	mba.mba_pba.pba_bridgetag = NULL;
	mba.mba_pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
	config_found_ia(self, "pcibus", &mba.mba_pba, pcibusprint);
#endif /* NPCI */

#ifdef RESIDUAL_DATA_DUMP
	SIMPLEQ_FOREACH(pbi, &genppc_pct->pc_pbi, next)
	    printf("%s\n", prop_dictionary_externalize(pbi->pbi_properties));
#endif

}
예제 #17
0
파일: uninorth.c 프로젝트: ryo/netbsd-src
static void
uninorth_attach(device_t parent, device_t self, void *aux)
{
	struct uninorth_softc *sc = device_private(self);
	pci_chipset_tag_t pc = &sc->sc_pc;
	struct confargs *ca = aux;
	struct pcibus_attach_args pba;
	int len, child, node = ca->ca_node;
	uint32_t reg[2], busrange[2];
	char compat[32];
	int ver;
	struct ranges {
		uint32_t pci_hi, pci_mid, pci_lo;
		uint32_t host;
		uint32_t size_hi, size_lo;
	} ranges[6], *rp = ranges;

	printf("\n");
	sc->sc_dev = self;

	memset(compat, 0, sizeof(compat));
	OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat));
	if (strcmp(compat, "u3-agp") == 0)
		ver = 3;
	else if (strcmp(compat, "u4-pcie") == 0)
		ver = 4;
	else
		ver = 0;

	/* UniNorth address */
	if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8)
		return;

	/* PCI bus number */
	if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8)
		return;

	memset(&sc->sc_iot, 0, sizeof(sc->sc_iot));

	/* find i/o tag */
	len = OF_getprop(node, "ranges", ranges, sizeof(ranges));
	if (len == -1)
		return;
	while (len >= sizeof(ranges[0])) {
		if ((rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) ==
		     OFW_PCI_PHYS_HI_SPACE_IO) {
			sc->sc_iot.pbs_base = rp->host;
			sc->sc_iot.pbs_limit = rp->host + rp->size_lo;
			break;
		}
		len -= sizeof(ranges[0]);
		rp++;
	}

	/* XXX enable gmac ethernet */
	for (child = OF_child(node); child; child = OF_peer(child)) {
		volatile int *gmac_gbclock_en = (void *)0xf8000020;

		memset(compat, 0, sizeof(compat));
		OF_getprop(child, "compatible", compat, sizeof(compat));
		if (strcmp(compat, "gmac") == 0)
			*gmac_gbclock_en |= 0x02;
	}

	sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE;
	sc->sc_iot.pbs_offset = 0;
	if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot,
	    "uninorth io-space") != 0)
		panic("Can't init uninorth io tag");

	memset(&sc->sc_memt, 0, sizeof(sc->sc_memt));
	sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE;
	sc->sc_memt.pbs_base = 0x00000000;
	if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt,
	    "uninorth mem-space") != 0)
		panic("Can't init uninorth mem tag");

	macppc_pci_get_chipset_tag(pc);
	pc->pc_node = node;
	pc->pc_bus = busrange[0];
	pc->pc_iot = &sc->sc_iot;
	pc->pc_memt = &sc->sc_memt;

	if (ver < 3) {
		pc->pc_addr = mapiodev(reg[0] + 0x800000, 4, false);
		pc->pc_data = mapiodev(reg[0] + 0xc00000, 8, false);
		pc->pc_conf_read = uninorth_conf_read;
		pc->pc_conf_write = uninorth_conf_write;
	} else {
		pc->pc_addr = mapiodev(reg[1] + 0x800000, 4, false);
		pc->pc_data = mapiodev(reg[1] + 0xc00000, 8, false);
		pc->pc_conf_read = uninorth_conf_read_v3;
		pc->pc_conf_write = uninorth_conf_write_v3;
	}

	memset(&pba, 0, sizeof(pba));
	pba.pba_memt = pc->pc_memt;
	pba.pba_iot = pc->pc_iot;
	pba.pba_dmat = &pci_bus_dma_tag;
	pba.pba_dmat64 = NULL;
	pba.pba_bus = pc->pc_bus;
	pba.pba_bridgetag = NULL;
	pba.pba_pc = pc;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;

	config_found_ia(self, "pcibus", &pba, pcibusprint);
}
예제 #18
0
파일: ata.c 프로젝트: goroutines/rumprun
/*
 * atabus_configthread: finish attach of atabus's childrens, in a separate
 * kernel thread.
 */
static void
atabusconfig_thread(void *arg)
{
	struct atabus_softc *atabus_sc = arg;
	struct ata_channel *chp = atabus_sc->sc_chan;
	struct atac_softc *atac = chp->ch_atac;
	struct atabus_initq *atabus_initq = NULL;
	int i, s;

	/* XXX seems wrong */
	mutex_enter(&atabus_qlock);
	atabus_initq = TAILQ_FIRST(&atabus_initq_head);
	KASSERT(atabus_initq->atabus_sc == atabus_sc);
	mutex_exit(&atabus_qlock);

	/*
	 * First look for a port multiplier
	 */
	if (chp->ch_ndrives == PMP_MAX_DRIVES &&
	    chp->ch_drive[PMP_PORT_CTL].drive_type == ATA_DRIVET_PM) {
#if NSATA_PMP > 0
		satapmp_attach(chp);
#else
		aprint_error_dev(atabus_sc->sc_dev,
		    "SATA port multiplier not supported\n");
		/* no problems going on, all drives are ATA_DRIVET_NONE */
#endif
	}

	/*
	 * Attach an ATAPI bus, if needed.
	 */
	KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL);
	for (i = 0; i < chp->ch_ndrives && chp->atapibus == NULL; i++) {
		if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI) {
#if NATAPIBUS > 0
			(*atac->atac_atapibus_attach)(atabus_sc);
#else
			/*
			 * Fake the autoconfig "not configured" message
			 */
			aprint_normal("atapibus at %s not configured\n",
			    device_xname(atac->atac_dev));
			chp->atapibus = NULL;
			s = splbio();
			for (i = 0; i < chp->ch_ndrives; i++) {
				if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI)
					chp->ch_drive[i].drive_type = ATA_DRIVET_NONE;
			}
			splx(s);
#endif
			break;
		}
	}

	for (i = 0; i < chp->ch_ndrives; i++) {
		struct ata_device adev;
		if (chp->ch_drive[i].drive_type != ATA_DRIVET_ATA &&
		    chp->ch_drive[i].drive_type != ATA_DRIVET_OLD) {
			continue;
		}
		if (chp->ch_drive[i].drv_softc != NULL)
			continue;
		memset(&adev, 0, sizeof(struct ata_device));
		adev.adev_bustype = atac->atac_bustype_ata;
		adev.adev_channel = chp->ch_channel;
		adev.adev_openings = 1;
		adev.adev_drv_data = &chp->ch_drive[i];
		chp->ch_drive[i].drv_softc = config_found_ia(atabus_sc->sc_dev,
		    "ata_hl", &adev, ataprint);
		if (chp->ch_drive[i].drv_softc != NULL) {
			ata_probe_caps(&chp->ch_drive[i]);
		} else {
			s = splbio();
			chp->ch_drive[i].drive_type = ATA_DRIVET_NONE;
			splx(s);
		}
	}

	/* now that we know the drives, the controller can set its modes */
	if (atac->atac_set_modes) {
		(*atac->atac_set_modes)(chp);
		ata_print_modes(chp);
	}
#if NATARAID > 0
	if (atac->atac_cap & ATAC_CAP_RAID) {
		for (i = 0; i < chp->ch_ndrives; i++) {
			if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATA) {
				ata_raid_check_component(
				    chp->ch_drive[i].drv_softc);
			}
		}
	}
#endif /* NATARAID > 0 */

	/*
	 * reset drive_flags for unattached devices, reset state for attached
	 * ones
	 */
	s = splbio();
	for (i = 0; i < chp->ch_ndrives; i++) {
		if (chp->ch_drive[i].drive_type == ATA_DRIVET_PM)
			continue;
		if (chp->ch_drive[i].drv_softc == NULL) {
			chp->ch_drive[i].drive_flags = 0;
			chp->ch_drive[i].drive_type = ATA_DRIVET_NONE;
		} else
			chp->ch_drive[i].state = 0;
	}
	splx(s);

	mutex_enter(&atabus_qlock);
	TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq);
	cv_broadcast(&atabus_qcv);
	mutex_exit(&atabus_qlock);

	free(atabus_initq, M_DEVBUF);

	ata_delref(chp);

	config_pending_decr(atac->atac_dev);
	kthread_exit(0);
}
예제 #19
0
파일: igma.c 프로젝트: ryoon/netbsd-xhci
static void
igma_attach(device_t parent, device_t self, void *aux)
{
	struct igma_softc *sc = device_private(self);
	const struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	struct igma_attach_args iaa;
	bus_space_tag_t gttmmt, gmt, regt;
	bus_space_handle_t gttmmh, gmh, regh;
	bus_addr_t gttmmb, gmb;

	pci_aprint_devinfo(pa, NULL);

	sc->sc_dev = self;

	/* Initialize according to chip type */
	igma_product_to_chip(pa, &sc->sc_chip);

	if (pci_mapreg_map(pa, PCI_BAR0, PCI_MAPREG_TYPE_MEM,
			BUS_SPACE_MAP_LINEAR,
			&gttmmt, &gttmmh, &gttmmb, NULL)) {
		aprint_error_dev(sc->sc_dev, "unable to map GTTMM\n");
		return;
	}
	sc->sc_chip.mmiot = gttmmt;
	if (bus_space_subregion(gttmmt, gttmmh, 0, 2*1024*1024,
			&sc->sc_chip.mmioh)) {
		aprint_error_dev(sc->sc_dev, "unable to submap MMIO\n");
		return;
	}
	sc->sc_chip.gttt = gttmmt;
	if (bus_space_subregion(gttmmt, gttmmh, 2*1024*1024, 2*1024*1024,
			&sc->sc_chip.gtth)) {
		aprint_error_dev(sc->sc_dev, "unable to submap GTT\n");
		return;
	}

	if (pci_mapreg_map(pa, PCI_BAR2, PCI_MAPREG_TYPE_MEM,
			BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE,
			&gmt, &gmh, &gmb, NULL)) {
		aprint_error_dev(sc->sc_dev, "unable to map aperture\n");
		return;
	}
	sc->sc_chip.gmt = gmt;
	sc->sc_chip.gmh = gmh;
	sc->sc_chip.gmb = gmb;

	if (pci_mapreg_map(pa, PCI_BAR4, PCI_MAPREG_TYPE_IO, 0,
			&regt, &regh, NULL, NULL)) {
		aprint_error_dev(sc->sc_dev, "unable to map IO registers\n");
		return;
	}

#if NVGA > 0
	iaa.iaa_console = vga_cndetach() ? true : false;
#else
	iaa.iaa_console = 0;
#endif
	sc->sc_chip.vgat = regt;
	if (bus_space_map(regt, 0x3c0, 0x10, 0, &sc->sc_chip.vgah)) {
		aprint_error_dev(sc->sc_dev, "unable to map VGA registers\n");
		return;
	}

	/* Check hardware for more information */
	igma_adjust_chip(sc, &sc->sc_chip);

	aprint_normal("%s: VGA_CNTRL: 0x%x\n",device_xname(sc->sc_dev),
		sc->sc_chip.vga_cntrl);
	aprint_normal("%s: GPIO_OFFSET: 0x%x\n",device_xname(sc->sc_dev),
		sc->sc_chip.gpio_offset);
	aprint_normal("%s: BACKLIGHT_CTRL: 0x%x\n",device_xname(sc->sc_dev),
		sc->sc_chip.backlight_cntrl);
	aprint_normal("%s: BACKLIGHT_CTRL2: 0x%x\n",device_xname(sc->sc_dev),
		sc->sc_chip.backlight_cntrl2);

#if NIGMAFB > 0
	strcpy(iaa.iaa_name, "igmafb");
	iaa.iaa_chip = sc->sc_chip;
	config_found_ia(sc->sc_dev, "igmabus", &iaa, igma_print);
#endif

	igma_i2c_attach(sc);
}
예제 #20
0
void
ixp425_attach(device_t self)
{
	struct ixp425_softc *sc = device_private(self);
#if NPCI > 0
	struct pcibus_attach_args pba;
#endif

	sc->sc_dev = self;
	sc->sc_iot = &ixp425_bs_tag;

	ixp425_softc = sc;

	printf("\n");

	/*
	 * Mapping for GPIO Registers
	 */
	if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE,
			  0, &sc->sc_gpio_ioh))
		panic("%s: unable to map GPIO registers", device_xname(self));

	if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
			  0, &sc->sc_exp_ioh))
		panic("%s: unable to map Expansion Bus registers",
		    device_xname(self));

#if NPCI > 0
	/*
	 * Mapping for PCI CSR
	 */
	if (bus_space_map(sc->sc_iot, IXP425_PCI_HWBASE, IXP425_PCI_SIZE,
			  0, &sc->sc_pci_ioh))
		panic("%s: unable to map PCI registers", device_xname(self));

	/*
	 * Invoke the board-specific PCI initialization code
	 */
	ixp425_md_pci_init(sc);

	/*
	 * Generic initialization of the PCI chipset.
	 */
	ixp425_pci_init(sc);

	/*
	 * Initialize the DMA tags.
	 */
	ixp425_pci_dma_init(sc);

	/*
	 * Attach the PCI bus.
	 */
	pba.pba_pc = &sc->ia_pci_chipset;
	pba.pba_iot = &sc->sc_pci_iot;
	pba.pba_memt = &sc->sc_pci_memt;
	pba.pba_dmat = &sc->ia_pci_dmat;
	pba.pba_bus = 0;	/* bus number = 0 */
	pba.pba_bridgetag = NULL;
	pba.pba_intrswiz = 0;	/* XXX */
	pba.pba_intrtag = 0;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
			PCI_FLAGS_MRL_OKAY   | PCI_FLAGS_MRM_OKAY |
			PCI_FLAGS_MWI_OKAY;
	(void) config_found_ia(self, "pcibus", &pba, pcibusprint);
#endif
}
예제 #21
0
파일: cuda.c 프로젝트: lacombar/netbsd-alc
static void
cuda_attach(device_t parent, device_t dev, void *aux)
{
	struct confargs *ca = aux;
	struct cuda_softc *sc = device_private(dev);
	struct i2cbus_attach_args iba;
	static struct cuda_attach_args caa;
	int irq = ca->ca_intr[0];
	int node, i, child;
	char name[32];

	sc->sc_dev = dev;
	node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1");
	if (node)
		OF_getprop(node, "interrupts", &irq, 4);

	printf(" irq %d: ", irq);

	sc->sc_node = ca->ca_node;
	sc->sc_memt = ca->ca_tag;

	sc->sc_sent = 0;
	sc->sc_received = 0;
	sc->sc_waiting = 0;
	sc->sc_polling = 0;
	sc->sc_state = CUDA_NOTREADY;
	sc->sc_error = 0;
	sc->sc_i2c_read_len = 0;

	if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr,
	    ca->ca_reg[1], 0, &sc->sc_memh) != 0) {

		printf("%s: unable to map registers\n", dev->dv_xname);
		return;
	}
	sc->sc_ih = intr_establish(irq, IST_EDGE, IPL_TTY, cuda_intr, sc);
	printf("\n");

	for (i = 0; i < 16; i++) {
		sc->sc_handlers[i].handler = NULL;
		sc->sc_handlers[i].cookie = NULL;
	}

	cuda_init(sc);

	/* now attach children */
	config_interrupts(dev, cuda_final);
	cuda_set_handler(sc, CUDA_ERROR, cuda_error_handler, sc);
	cuda_set_handler(sc, CUDA_PSEUDO, cuda_todr_handler, sc);

	child = OF_child(ca->ca_node);
	while (child != 0) {

		if (OF_getprop(child, "name", name, 32) == 0)
			continue;
		if (strncmp(name, "adb", 4) == 0) {

			cuda_set_handler(sc, CUDA_ADB, cuda_adb_handler, sc);
			sc->sc_adbops.cookie = sc;
			sc->sc_adbops.send = cuda_adb_send;
			sc->sc_adbops.poll = cuda_adb_poll;
			sc->sc_adbops.autopoll = cuda_autopoll;
			sc->sc_adbops.set_handler = cuda_adb_set_handler;
			config_found_ia(dev, "adb_bus", &sc->sc_adbops,
			    nadb_print);
		} else if (strncmp(name, "rtc", 4) == 0) {

			sc->sc_todr.todr_gettime = cuda_todr_get;
			sc->sc_todr.todr_settime = cuda_todr_set;
			sc->sc_todr.cookie = sc;
			todr_attach(&sc->sc_todr);
		} 
		child = OF_peer(child);
	}

	caa.cookie = sc;
	caa.set_handler = cuda_set_handler;
	caa.send = cuda_send;
	caa.poll = cuda_poll;
#if notyet
	config_found(dev, &caa, cuda_print);
#endif
	mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE);
	iba.iba_tag = &sc->sc_i2c;
	sc->sc_i2c.ic_cookie = sc;
	sc->sc_i2c.ic_acquire_bus = cuda_i2c_acquire_bus;
	sc->sc_i2c.ic_release_bus = cuda_i2c_release_bus;
	sc->sc_i2c.ic_send_start = NULL;
	sc->sc_i2c.ic_send_stop = NULL;
	sc->sc_i2c.ic_initiate_xfer = NULL;
	sc->sc_i2c.ic_read_byte = NULL;
	sc->sc_i2c.ic_write_byte = NULL;
	sc->sc_i2c.ic_exec = cuda_i2c_exec;
	config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);

	if (cuda0 == NULL)
		cuda0 = &caa;
}
예제 #22
0
static void
piixpm_attach(device_t parent, device_t self, void *aux)
{
	struct piixpm_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct i2cbus_attach_args iba;
	pcireg_t base, conf;
	pcireg_t pmmisc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	int i, numbusses = 1;

	sc->sc_dev = self;
	sc->sc_iot = pa->pa_iot;
	sc->sc_id = pa->pa_id;
	sc->sc_pc = pa->pa_pc;
	sc->sc_pcitag = pa->pa_tag;

	pci_aprint_devinfo(pa, NULL);

	if (!pmf_device_register(self, piixpm_suspend, piixpm_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");

	/* Read configuration */
	conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC);
	DPRINTF(("%s: conf 0x%x\n", device_xname(self), conf));

	if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) ||
	    (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC))
		goto nopowermanagement;

	/* check whether I/O access to PM regs is enabled */
	pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC);
	if (!(pmmisc & 1))
		goto nopowermanagement;

	/* Map I/O space */
	base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE);
	if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base),
	    PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) {
		aprint_error_dev(self, "can't map power management I/O space\n");
		goto nopowermanagement;
	}

	/*
	 * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M.
	 * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20
	 * in the "Specification update" (document #297738).
	 */
	acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh,
			   PIIX_PM_PMTMR,
		(PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0 );

nopowermanagement:

	/* SB800 rev 0x40+ needs special initialization */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_SMB &&
	    PCI_REVISION(pa->pa_class) >= 0x40) {
		if (piixpm_sb800_init(sc) == 0) {
			numbusses = 4;
			goto attach_i2c;
		}
		aprint_normal_dev(self, "SMBus disabled\n");
		return;
	}

	if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) {
		aprint_normal_dev(self, "SMBus disabled\n");
		return;
	}

	/* Map I/O space */
	base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff;
	if (bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base),
	    PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) {
		aprint_error_dev(self, "can't map smbus I/O space\n");
		return;
	}

	sc->sc_poll = 1;
	aprint_normal_dev(self, "");
	if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI) {
		/* No PCI IRQ */
		aprint_normal("interrupting at SMI, ");
	} else if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) {
		/* Install interrupt handler */
		if (pci_intr_map(pa, &ih) == 0) {
			intrstr = pci_intr_string(pa->pa_pc, ih);
			sc->sc_smb_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
			    piixpm_intr, sc);
			if (sc->sc_smb_ih != NULL) {
				aprint_normal("interrupting at %s", intrstr);
				sc->sc_poll = 0;
			}
		}
	}
	if (sc->sc_poll)
		aprint_normal("polling");

	aprint_normal("\n");

attach_i2c:
	/* Attach I2C bus */
	mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE);

	for (i = 0; i < numbusses; i++) {
		sc->sc_busses[i].sda = i;
		sc->sc_busses[i].softc = sc;
		sc->sc_i2c_tags[i].ic_cookie = &sc->sc_busses[i];
		sc->sc_i2c_tags[i].ic_acquire_bus = piixpm_i2c_acquire_bus;
		sc->sc_i2c_tags[i].ic_release_bus = piixpm_i2c_release_bus;
		sc->sc_i2c_tags[i].ic_exec = piixpm_i2c_exec;

		memset(&iba, 0, sizeof(iba));
		iba.iba_type = I2C_TYPE_SMBUS;
		iba.iba_tag = &sc->sc_i2c_tags[i];
		config_found_ia(self, "i2cbus", &iba, iicbus_print);
	}
}
예제 #23
0
static void 
giopci_attach(struct device *parent, struct device *self, void *aux)
{
	struct giopci_softc *sc = (void *)self;
	pci_chipset_tag_t pc = &sc->sc_pc;
	struct gio_attach_args *ga = aux;
	uint32_t pci_off, pci_len, arb;
	struct pcibus_attach_args pba;
	u_long m_start, m_end;
#ifdef PCI_NETBSD_CONFIGURE
	extern int pci_conf_debug;

	pci_conf_debug = giopci_debug;
#endif

	sc->sc_iot	= ga->ga_iot;
	sc->sc_slot	= ga->ga_slot;
	sc->sc_gprid	= GIO_PRODUCT_PRODUCTID(ga->ga_product);

	if (mach_type == MACH_SGI_IP22 &&
	    mach_subtype == MACH_SGI_IP22_FULLHOUSE)
		arb = GIO_ARB_RT | GIO_ARB_MST | GIO_ARB_PIPE;
	else
		arb = GIO_ARB_RT | GIO_ARB_MST;

	if (gio_arb_config(ga->ga_slot, arb)) {
		printf(": failed to configure GIO bus arbiter\n");
		return;
	}

#if (NIMC > 0)
	imc_disable_sysad_parity();
#endif

	switch (sc->sc_gprid) {
	case PHOBOS_G100:
	case PHOBOS_G130:
	case PHOBOS_G160:
		pci_off = PHOBOS_PCI_OFFSET;
		pci_len = PHOBOS_PCI_LENGTH;
		m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_START);
		m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_END);
		break;

	case SETENG_GFE:
		/*
		 * NB: The SetEng board does not allow the ThunderLAN's DMA
		 *     engine to properly transfer segments that span page
		 *     boundaries. See sgimips/autoconf.c where we catch a
		 *     tl(4) device attachment and create an appropriate
		 *     proplib entry to enable the workaround.
		 */
		pci_off = SETENG_PCI_OFFSET;
		pci_len = SETENG_PCI_LENGTH;
		m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_START);
		m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_END);
		bus_space_write_4(ga->ga_iot, ga->ga_ioh,
		    SETENG_MAGIC_OFFSET, SETENG_MAGIC_VALUE);
		break;

	default:
		panic("giopci_attach: unsupported GIO product id 0x%02x",
		    sc->sc_gprid);
	}

	if (bus_space_subregion(ga->ga_iot, ga->ga_ioh, pci_off, pci_len,
	    &sc->sc_ioh)) {
		printf("%s: unable to map PCI registers\n",sc->sc_dev.dv_xname);
		return;
	}
	sc->sc_pci_len = pci_len;

	pc->pc_bus_maxdevs	= giopci_bus_maxdevs;
	pc->pc_conf_read	= giopci_conf_read;
	pc->pc_conf_write	= giopci_conf_write;
	pc->pc_conf_hook	= giopci_conf_hook;
	pc->pc_intr_map		= giopci_intr_map;
	pc->pc_intr_string	= giopci_intr_string;
	pc->intr_establish	= giopci_intr_establish;
	pc->intr_disestablish	= giopci_intr_disestablish;
	pc->iot			= ga->ga_iot;
	pc->ioh			= ga->ga_ioh;
	pc->cookie		= sc;

	printf(": %s\n", gio_product_string(sc->sc_gprid));

#ifdef PCI_NETBSD_CONFIGURE
	pc->pc_memext = extent_create("giopcimem", m_start, m_end,
	    M_DEVBUF, NULL, 0, EX_NOWAIT);
	pci_configure_bus(pc, NULL, pc->pc_memext, NULL, 0, mips_dcache_align);
#endif

	memset(&pba, 0, sizeof(pba));
	pba.pba_memt	= SGIMIPS_BUS_SPACE_MEM;
	pba.pba_dmat	= ga->ga_dmat;
	pba.pba_pc	= pc;
	pba.pba_flags	= PCI_FLAGS_MEM_ENABLED;
	/* NB: do not set PCI_FLAGS_{MRL,MRM,MWI}_OKAY  -- true ?! */

	config_found_ia(self, "pcibus", &pba, pcibusprint);
}
예제 #24
0
void
ciaattach(device_t parent, device_t self, void *aux)
{
	struct cia_softc *sc = device_private(self);
	struct cia_config *ccp;
	struct pcibus_attach_args pba;
	char bits[64];
	const char *name;
	int pass;

	/* note that we've attached the chipset; can't have 2 CIAs. */
	ciafound = 1;
	sc->sc_dev = self;

	/*
	 * set up the chipset's info; done once at console init time
	 * (maybe), but we must do it here as well to take care of things
	 * that need to use memory allocation.
	 */
	ccp = sc->sc_ccp = &cia_configuration;
	cia_init(ccp, 1);

	if (ccp->cc_flags & CCF_ISPYXIS) {
		name = "Pyxis";
		pass = ccp->cc_rev;
	} else {
		name = "ALCOR/ALCOR2";
		pass = ccp->cc_rev + 1;
	}

	aprint_normal(": DECchip 2117x Core Logic Chipset (%s), pass %d\n",
	    name, pass);
	if (ccp->cc_cnfg) {
		snprintb(bits, sizeof(bits), CIA_CSR_CNFG_BITS, ccp->cc_cnfg);
		aprint_normal_dev(self, "extended capabilities: %s\n", bits);
	}

	switch (ccp->cc_flags & (CCF_PCI_USE_BWX|CCF_BUS_USE_BWX)) {
	case CCF_PCI_USE_BWX|CCF_BUS_USE_BWX:
		name = "PCI config and bus";
		break;
	case CCF_PCI_USE_BWX:
		name = "PCI config";
		break;
	case CCF_BUS_USE_BWX:
		name = "bus";
		break;
	default:
		name = NULL;
		break;
	}
	if (name != NULL)
		aprint_normal_dev(self, "using BWX for %s access\n", name);

#ifdef DEC_550
	if (cputype == ST_DEC_550 &&
	    (hwrpb->rpb_variation & SV_ST_MASK) < SV_ST_MIATA_1_5) {
		/*
		 * Miata 1 systems have a bug: DMA cannot cross
		 * an 8k boundary!  Make sure PCI read prefetching
		 * is disabled on these chips.  Note that secondary
		 * PCI busses don't have this problem, because of
		 * the way PPBs handle PCI read requests.
		 *
		 * In the 21174 Technical Reference Manual, this is
		 * actually documented as "Pyxis Pass 1", but apparently
		 * there are chips that report themselves as "Pass 1"
		 * which do not have the bug!  Miatas with the Cypress
		 * PCI-ISA bridge (i.e. Miata 1.5 and Miata 2) do not
		 * have the bug, so we use this check.
		 *
		 * NOTE: This bug is actually worked around in cia_dma.c,
		 * when direct-mapped DMA maps are created.
		 *
		 * XXX WE NEED TO THINK ABOUT HOW TO HANDLE THIS FOR
		 * XXX SGMAP DMA MAPPINGS!
		 */
		uint32_t ctrl;

		/* XXX no bets... */
		aprint_error_dev(self,
		    "WARNING: Pyxis pass 1 DMA bug; no bets...\n");

		ccp->cc_flags |= CCF_PYXISBUG;

		alpha_mb();
		ctrl = REGVAL(CIA_CSR_CTRL);
		ctrl &= ~(CTRL_RD_TYPE|CTRL_RL_TYPE|CTRL_RM_TYPE);
		REGVAL(CIA_CSR_CTRL) = ctrl;
		alpha_mb();
	}
#endif /* DEC_550 */

	cia_dma_init(ccp);

	switch (cputype) {
#ifdef DEC_KN20AA
	case ST_DEC_KN20AA:
		pci_kn20aa_pickintr(ccp);
		break;
#endif

#ifdef DEC_EB164
	case ST_EB164:
		pci_eb164_pickintr(ccp);
		break;
#endif

#ifdef DEC_550
	case ST_DEC_550:
		pci_550_pickintr(ccp);
		break;
#endif

#ifdef DEC_1000A
	case ST_DEC_1000A:
		pci_1000a_pickintr(ccp, &ccp->cc_iot, &ccp->cc_memt,
			&ccp->cc_pc);
		break;
#endif

#ifdef DEC_1000
	case ST_DEC_1000:
		pci_1000_pickintr(ccp, &ccp->cc_iot, &ccp->cc_memt,
			&ccp->cc_pc);
		break;
#endif

	default:
		panic("ciaattach: shouldn't be here, really...");
	}

	pba.pba_iot = &ccp->cc_iot;
	pba.pba_memt = &ccp->cc_memt;
	pba.pba_dmat =
	    alphabus_dma_get_tag(&ccp->cc_dmat_direct, ALPHA_BUS_PCI);
	pba.pba_dmat64 = NULL;
	pba.pba_pc = &ccp->cc_pc;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
	if ((ccp->cc_flags & CCF_PYXISBUG) == 0)
		pba.pba_flags |= PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY |
		    PCI_FLAGS_MWI_OKAY;
	config_found_ia(self, "pcibus", &pba, pcibusprint);
}
예제 #25
0
static void
ofwpci_attach(device_t parent, device_t self, void *aux)
{
	struct ofwpci_softc *sc = device_private(self);
	pci_chipset_tag_t pc = &sc->sc_pc;
	struct confargs *ca = aux;
	struct pcibus_attach_args pba;
	struct genppc_pci_chipset_businfo *pbi;
	int node = ca->ca_node;
	int i, isprim = 0;
	uint32_t busrange[2];
	char buf[64];
#ifdef PCI_NETBSD_CONFIGURE
	struct extent *ioext, *memext;
#endif

	aprint_normal("\n");

	sc->sc_dev = self;

	/* PCI bus number */
	if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8)
		return;

	/* bus space map the io ranges */
	sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE;
	sc->sc_iot.pbs_base = 0x00000000;
	if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot,
	    "ofwpci io-space") != 0)
		panic("Can't init ofwpci io tag");

	sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE;
	sc->sc_memt.pbs_base = 0x00000000;
	if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt,
	    "ofwpci mem-space") != 0)
		panic("Can't init ofwpci mem tag");

	aprint_debug("io base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n",
	    sc->sc_iot.pbs_base, sc->sc_iot.pbs_offset, sc->sc_iot.pbs_limit);
	
	aprint_debug("mem base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n",
	    sc->sc_memt.pbs_base, sc->sc_memt.pbs_offset,
	    sc->sc_memt.pbs_limit);
	
	/* are we the primary pci bus? */
	if (of_find_firstchild_byname(OF_finddevice("/"), "pci") == node) {
		int isa_node;

		isprim++;
		/* yes we are, now do we have an ISA child? */
		isa_node = of_find_firstchild_byname(node, "isa");
		if (isa_node != -1) {
			/* isa == pci */
			genppc_isa_io_space_tag = sc->sc_iot;
			genppc_isa_mem_space_tag = sc->sc_memt;
			map_isa_ioregs();
			init_ofppc_interrupt();
			ofppc_init_comcons(isa_node);
		}
	}

	ofwpci_get_chipset_tag(pc);

	pc->pc_node = node;
	i = OF_package_to_path(node, buf, sizeof(buf)-5);
	if (i <= 0)
		panic("Can't determine path for pci node %d", node);
	buf[i] = '\0';
	pc->pc_ihandle = OF_open(buf);
	if (pc->pc_ihandle < 0)
		panic("Can't open device %s", buf);
	pc->pc_bus = busrange[0];
	pc->pc_iot = &sc->sc_iot;
	pc->pc_memt = &sc->sc_memt;

	pbi = malloc(sizeof(struct genppc_pci_chipset_businfo),
	    M_DEVBUF, M_NOWAIT);
	KASSERT(pbi != NULL);
	pbi->pbi_properties = prop_dictionary_create();
	KASSERT(pbi->pbi_properties != NULL);
	SIMPLEQ_INIT(&pc->pc_pbi);
	SIMPLEQ_INSERT_TAIL(&pc->pc_pbi, pbi, next);

	genofw_setup_pciintr_map((void *)pc, pbi, pc->pc_node);
#ifdef PCI_NETBSD_CONFIGURE
	ioext  = extent_create("pciio",
	    modeldata.pciiodata[device_unit(self)].start,
	    modeldata.pciiodata[device_unit(self)].limit,
	    NULL, 0, EX_NOWAIT);
	memext = extent_create("pcimem", sc->sc_memt.pbs_base,
	    sc->sc_memt.pbs_limit-1, NULL, 0, EX_NOWAIT);

	if (pci_configure_bus(pc, ioext, memext, NULL, 0, CACHELINESIZE))
		aprint_error("pci_configure_bus() failed\n");

	extent_destroy(ioext);
	extent_destroy(memext);
#endif /* PCI_NETBSD_CONFIGURE */
	memset(&pba, 0, sizeof(pba));
	pba.pba_memt = pc->pc_memt;
	pba.pba_iot = pc->pc_iot;
	pba.pba_dmat = &pci_bus_dma_tag;
	pba.pba_dmat64 = NULL;
	pba.pba_bus = pc->pc_bus;
	pba.pba_bridgetag = NULL;
	pba.pba_pc = pc;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
	config_found_ia(self, "pcibus", &pba, pcibusprint);
}
예제 #26
0
파일: fd.c 프로젝트: lacombar/netbsd-alc
void
fdcfinishattach(device_t self)
{
	struct fdc_softc *fdc = device_private(self);
	bus_space_tag_t iot = fdc->sc_iot;
	bus_space_handle_t ioh = fdc->sc_ioh;
	struct fdc_attach_args fa;

	/*
	 * Reset the controller to get it into a known state. Not all
	 * probes necessarily need do this to discover the controller up
	 * front, so don't assume anything.
	 */

	bus_space_write_1(iot, ioh, fdout, 0);
	delay(100);
	bus_space_write_1(iot, ioh, fdout, FDO_FRST);

	/* see if it can handle a command */
	if (out_fdc(iot, ioh, NE7CMD_SPECIFY) < 0) {
		aprint_normal_dev(fdc->sc_dev, "can't reset controller\n");
		return;
	}
	out_fdc(iot, ioh, 0xdf);
	out_fdc(iot, ioh, 2);

#if defined(i386) || defined(x86_64)
	/*
	 * The NVRAM info only tells us about the first two disks on the
	 * `primary' floppy controller.
	 */
	/* XXX device_unit() abuse */
	if (device_unit(fdc->sc_dev) == 0) {
		int type = mc146818_read(NULL, NVRAM_DISKETTE); /* XXX softc */
		fdc->sc_known = 1;
		fdc->sc_knownfds[0] = fd_nvtotype(device_xname(fdc->sc_dev),
		    type, 0);
		if (fdc->sc_knownfds[0] != NULL)
			fdc->sc_present |= 1;
		fdc->sc_knownfds[1] = fd_nvtotype(device_xname(fdc->sc_dev),
		    type, 1);
		if (fdc->sc_knownfds[1] != NULL)
			fdc->sc_present |= 2;
	}
#endif /* i386 || x86_64 */

	/* physical limit: four drives per controller. */
	fdc->sc_state = PROBING;
	for (fa.fa_drive = 0; fa.fa_drive < 4; fa.fa_drive++) {
		if (fdc->sc_known) {
			if (fdc->sc_present & (1 << fa.fa_drive)) {
				fa.fa_deftype = fdc->sc_knownfds[fa.fa_drive];
				config_found(fdc->sc_dev, (void *)&fa,
				    fdprint);
			}
		} else {
#if defined(atari)
			/*
			 * Atari has a different ordening, defaults to 1.44
			 */
			fa.fa_deftype = &fd_types[2];
#else
			/*
			 * Default to 1.44MB on Alpha and BeBox.  How do we tell
			 * on these platforms?
			 */
			fa.fa_deftype = &fd_types[0];
#endif
			(void)config_found_ia(fdc->sc_dev, "fdc", (void *)&fa, fdprint);
		}
	}
	fdc->sc_state = DEVIDLE;
}
static void 
rmixl_pcix_attach(device_t parent, device_t self, void *aux)
{
	rmixl_pcix_softc_t *sc = device_private(self);
	struct obio_attach_args *obio = aux;
	struct rmixl_config *rcp = &rmixl_configuration;
        struct pcibus_attach_args pba;
	uint32_t bar;

	rmixl_pcix_found = 1;
	sc->sc_dev = self;
	sc->sc_29bit_dmat = obio->obio_29bit_dmat;
	sc->sc_32bit_dmat = obio->obio_32bit_dmat;
	sc->sc_64bit_dmat = obio->obio_64bit_dmat;
	sc->sc_tmsk = obio->obio_tmsk;

	aprint_normal(": RMI XLR PCI-X Interface\n");

	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_HIGH);

	rmixl_pcix_intcfg(sc);

	rmixl_pcix_errata(sc);

	/*
	 * check XLR Control Register
	 */
	DPRINTF(("%s: XLR_CONTROL=%#x\n", __func__, 
		RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_XLR_CONTROL)));

	/*
	 * HBAR[0]   if a 32 bit BAR, or
	 * HBAR[0,1] if a 64 bit BAR pair 
	 * must cover all RAM
	 */
	extern u_quad_t mem_cluster_maxaddr;
	uint64_t hbar_addr;
	uint64_t hbar_size;
	uint32_t hbar_size_lo, hbar_size_hi;
	uint32_t hbar_addr_lo, hbar_addr_hi;

	hbar_addr_lo = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_HOST_BAR0_ADDR);
	hbar_addr_hi = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_HOST_BAR1_ADDR);
	hbar_size_lo = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_HOST_BAR0_SIZE);
	hbar_size_hi = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_HOST_BAR1_SIZE);

	hbar_addr = (u_quad_t)(hbar_addr_lo & PCI_MAPREG_MEM_ADDR_MASK);
	hbar_size = hbar_size_lo;
	if ((hbar_size_lo & PCI_MAPREG_MEM_TYPE_64BIT) != 0) {
		hbar_addr |= (uint64_t)hbar_addr_hi << 32;
		hbar_size |= (uint64_t)hbar_size_hi << 32;
	}
	if ((hbar_addr != 0) || (hbar_size < mem_cluster_maxaddr)) {
		int error;

		aprint_error_dev(self, "HostBAR0 addr %#x, size %#x\n",
			hbar_addr_lo, hbar_size_lo);
		if ((hbar_size_lo & PCI_MAPREG_MEM_TYPE_64BIT) != 0)
			aprint_error_dev(self, "HostBAR1 addr %#x, size %#x\n",
				hbar_addr_hi, hbar_size_hi);
		aprint_error_dev(self, "WARNING: firmware PCI-X setup error: "
			"RAM %#"PRIx64"..%#"PRIx64" not accessible by Host BAR, "
			"enabling DMA bounce buffers\n",
			hbar_size, mem_cluster_maxaddr-1);

		/*
		 * force use of bouce buffers for inaccessible RAM addrs
		 */
		if (hbar_size < ((uint64_t)1 << 32)) {
			error = bus_dmatag_subregion(sc->sc_32bit_dmat,
				0, (bus_addr_t)hbar_size, &sc->sc_32bit_dmat,
				BUS_DMA_NOWAIT);
			if (error)
				panic("%s: failed to subregion 32-bit dma tag:"
					 " error %d", __func__, error);
			sc->sc_64bit_dmat = NULL;
		} else {
			error = bus_dmatag_subregion(sc->sc_64bit_dmat,
				0, (bus_addr_t)hbar_size, &sc->sc_64bit_dmat,
				BUS_DMA_NOWAIT);
			if (error)
				panic("%s: failed to subregion 64-bit dma tag:"
					" error %d", __func__, error);
		}
	}

	/*
	 * check PCI-X interface byteswap setup
	 * ensure 'Match Byte Lane' is disabled
	 */
	uint32_t mble;
	mble = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_XLR_MBLE);
#ifdef PCI_DEBUG
	uint32_t mba, mbs;
	mba  = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_MATCH_BIT_ADDR);
	mbs  = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_MATCH_BIT_SIZE);
	DPRINTF(("%s: MBLE=%#x, MBA=%#x, MBS=%#x\n", __func__, mble, mba, mbs));
#endif
	if ((mble & __BIT(40)) != 0)
		RMIXL_PCIXREG_WRITE(RMIXL_PCIX_ECFG_XLR_MBLE, 0);

	/*
	 * get PCI config space base addr from SBC PCIe CFG BAR
	 * initialize it if necessary
 	 */
	bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLR_SBC_PCIX_CFG_BAR);
	DPRINTF(("%s: PCIX_CFG_BAR %#x\n", __func__, bar));
	if ((bar & RMIXL_PCIX_CFG_BAR_ENB) == 0) {
		u_long n = RMIXL_PCIX_CFG_SIZE / (1024 * 1024);
		RMIXL_PCIX_BAR_INIT(CFG, bar, n, n);
	}
	rcp->rc_pci_cfg_pbase = (bus_addr_t)RMIXL_PCIX_CFG_BAR_TO_BA(bar);
	rcp->rc_pci_cfg_size  = (bus_size_t)RMIXL_PCIX_CFG_SIZE;

	/*
	 * get PCI MEM space base [addr, size] from SBC PCIe MEM BAR
	 * initialize it if necessary
 	 */
	bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLR_SBC_PCIX_MEM_BAR);
	DPRINTF(("%s: PCIX_MEM_BAR %#x\n", __func__, bar));
	if ((bar & RMIXL_PCIX_MEM_BAR_ENB) == 0) {
		u_long n = 256;				/* 256 MB */
		RMIXL_PCIX_BAR_INIT(MEM, bar, n, n);
	}
	rcp->rc_pci_mem_pbase = (bus_addr_t)RMIXL_PCIX_MEM_BAR_TO_BA(bar);
	rcp->rc_pci_mem_size  = (bus_size_t)RMIXL_PCIX_MEM_BAR_TO_SIZE(bar);

	/*
	 * get PCI IO space base [addr, size] from SBC PCIe IO BAR
	 * initialize it if necessary
 	 */
	bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLR_SBC_PCIX_IO_BAR);
	DPRINTF(("%s: PCIX_IO_BAR %#x\n", __func__, bar));
	if ((bar & RMIXL_PCIX_IO_BAR_ENB) == 0) {
		u_long n = 32;				/* 32 MB */
		RMIXL_PCIX_BAR_INIT(IO, bar, n, n);
	}
	rcp->rc_pci_io_pbase = (bus_addr_t)RMIXL_PCIX_IO_BAR_TO_BA(bar);
	rcp->rc_pci_io_size  = (bus_size_t)RMIXL_PCIX_IO_BAR_TO_SIZE(bar);

	/*
	 * initialize the PCI CFG bus space tag
	 */
	rmixl_pci_cfg_bus_mem_init(&rcp->rc_pci_cfg_memt, rcp);
	sc->sc_pci_cfg_memt = &rcp->rc_pci_cfg_memt;

	/*
	 * initialize the PCI MEM and IO bus space tags
	 */
	rmixl_pci_bus_mem_init(&rcp->rc_pci_memt, rcp);
	rmixl_pci_bus_io_init(&rcp->rc_pci_iot, rcp);

	/*
	 * initialize the extended configuration regs
	 */
	rmixl_pcix_init_errors(sc);

	/*
	 * initialize the PCI chipset tag
	 */
	rmixl_pcix_init(sc);

	/*
	 * attach the PCI bus
	 */
	memset(&pba, 0, sizeof(pba));
	pba.pba_memt = &rcp->rc_pci_memt;
	pba.pba_iot =  &rcp->rc_pci_iot;
	pba.pba_dmat = sc->sc_32bit_dmat;
	pba.pba_dmat64 = sc->sc_64bit_dmat;
	pba.pba_pc = &sc->sc_pci_chipset;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;
	pba.pba_intrswiz = 0;
	pba.pba_intrtag = 0;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
		PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;

	(void) config_found_ia(self, "pcibus", &pba, pcibusprint);
}
예제 #28
0
파일: aupci.c 프로젝트: ryo/netbsd-src
void
aupciattach(device_t parent, device_t self, void *aux)
{
    struct aupci_softc		*sc = device_private(self);
    struct aubus_attach_args	*aa = (struct aubus_attach_args *)aux;
    uint32_t			cfg;
#if NPCI > 0
    uint32_t			mbar, mask;
    bus_addr_t			mstart;
    struct pcibus_attach_args	pba;
#endif

    aupci_found = 1;

    sc->sc_dev = self;
    sc->sc_bust = aa->aa_st;
    if (bus_space_map(sc->sc_bust, aa->aa_addrs[0], 512, 0,
                      &sc->sc_bush) != 0) {
        aprint_error(": unable to map PCI registers\n");
        return;
    }

#if NPCI > 0
    /*
     * These physical addresses are locked in on the CPUs we have
     * seen.  Perhaps these should be passed in via locators, thru
     * the configuration file.
     */
    sc->sc_cfgbase = PCI_CONFIG_BASE;
    sc->sc_membase = PCI_MEM_BASE;
    sc->sc_iobase = PCI_IO_BASE;
#endif

    /*
     * Configure byte swapping, as YAMON doesn't do it.  YAMON does take
     * care of most of the rest of the details (clocking, etc.), however.
     */
#if _BYTE_ORDER == _BIG_ENDIAN
    /*
     * N.B.: This still doesn't do the DMA thing properly.  I have
     * not yet figured out how to get DMA access to work properly
     * without having bytes swapped while the processor is in
     * big-endian mode.  I'm not even sure that the Alchemy part
     * can do it without swapping the bytes (which would be a
     * bummer, since then only parts which had hardware detection
     * and swapping support would work without special hacks in
     * their drivers.)
     */
    cfg = AUPCI_CONFIG_CH | AUPCI_CONFIG_R1H |
          AUPCI_CONFIG_R2H | AUPCI_CONFIG_AEN |
          AUPCI_CONFIG_SM | AUPCI_CONFIG_ST | AUPCI_CONFIG_SIC_DATA;
#else
    cfg = AUPCI_CONFIG_CH | AUPCI_CONFIG_R1H |
          AUPCI_CONFIG_R2H | AUPCI_CONFIG_AEN;
#endif
    bus_space_write_4(sc->sc_bust, sc->sc_bush, AUPCI_CONFIG, cfg);

    cfg = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_COMMAND_STATUS);

    aprint_normal(": Alchemy Host-PCI Bridge, %sMHz\n",
                  (cfg & PCI_STATUS_66MHZ_SUPPORT) ? "66" : "33");
    aprint_naive("\n");

#if NPCI > 0
    /*
     * PCI configuration space.  Address in this bus are
     * orthogonal to other spaces.  We need to make the entire
     * 32-bit address space available.
     */
    sc->sc_cfgt = &sc->sc_cfg_space;
    au_himem_space_init(sc->sc_cfgt, "pcicfg", sc->sc_cfgbase,
                        0x00000000, 0xffffffff, AU_HIMEM_SPACE_IO);

    /*
     * Virtual PCI memory.  Configured so that we don't overlap
     * with PCI memory space.
     */
    mask = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_MWMASK);
    mask >>= AUPCI_MWMASK_SHIFT;
    mask <<= AUPCI_MWMASK_SHIFT;

    mbar = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_MBAR);
    mstart = (mbar & mask) + (~mask + 1);

    sc->sc_memt = &sc->sc_mem_space;
    au_himem_space_init(sc->sc_memt, "pcimem", sc->sc_membase,
                        mstart, 0xffffffff, AU_HIMEM_SPACE_LITTLE_ENDIAN);

    /*
     * IO space.  Address in this bus are orthogonal to other spaces.
     * 16 MB should be plenty.  We don't start from zero to avoid
     * potential device bugs.
     */
    sc->sc_iot = &sc->sc_io_space;
    au_himem_space_init(sc->sc_iot, "pciio",
                        sc->sc_iobase, AUPCI_IO_START, AUPCI_IO_END,
                        AU_HIMEM_SPACE_LITTLE_ENDIAN | AU_HIMEM_SPACE_IO);

    sc->sc_pc.pc_conf_v = sc;
    sc->sc_pc.pc_attach_hook = aupci_attach_hook;
    sc->sc_pc.pc_bus_maxdevs = aupci_bus_maxdevs;
    sc->sc_pc.pc_make_tag = aupci_make_tag;
    sc->sc_pc.pc_decompose_tag = aupci_decompose_tag;
    sc->sc_pc.pc_conf_read = aupci_conf_read;
    sc->sc_pc.pc_conf_write = aupci_conf_write;

    sc->sc_pc.pc_intr_v = sc;
    sc->sc_pc.pc_intr_map = aupci_intr_map;
    sc->sc_pc.pc_intr_string = aupci_intr_string;
    sc->sc_pc.pc_intr_establish = aupci_intr_establish;
    sc->sc_pc.pc_intr_disestablish = aupci_intr_disestablish;
    sc->sc_pc.pc_conf_interrupt = aupci_conf_interrupt;

#ifdef PCI_NETBSD_CONFIGURE
    mem_ex = extent_create("pcimem", mstart, 0xffffffff,
                           NULL, 0, EX_WAITOK);

    io_ex = extent_create("pciio", AUPCI_IO_START, AUPCI_IO_END,
                          NULL, 0, EX_WAITOK);

    pci_configure_bus(&sc->sc_pc,
                      io_ex, mem_ex, NULL, 0, mips_cache_info.mci_dcache_align);
    extent_destroy(mem_ex);
    extent_destroy(io_ex);
#endif

    pba.pba_iot = sc->sc_iot;
    pba.pba_memt = sc->sc_memt;
    /* XXX: review dma tag logic */
    pba.pba_dmat = aa->aa_dt;
    pba.pba_dmat64 = NULL;
    pba.pba_pc = &sc->sc_pc;
    pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
    pba.pba_bus = 0;
    pba.pba_bridgetag = NULL;

    config_found_ia(self, "pcibus", &pba, pcibusprint);
#endif	/* NPCI > 0 */
}
예제 #29
0
파일: pmu.c 프로젝트: ycui1984/netbsd-src
static void
pmu_attach(device_t parent, device_t self, void *aux)
{
	struct confargs *ca = aux;
	struct pmu_softc *sc = device_private(self);
#if notyet
	struct i2cbus_attach_args iba;
#endif
	uint32_t regs[16];
	int irq = ca->ca_intr[0];
	int node, extint_node, root_node;
	int nbat = 1, i, pmnode;
	int type = IST_EDGE;
	uint8_t cmd[2] = {2, 0};
	uint8_t resp[16];
	char name[256];

	extint_node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1");
	if (extint_node) {

		OF_getprop(extint_node, "interrupts", &irq, 4);
		type = IST_LEVEL;
	}

	aprint_normal(" irq %d: ", irq);

	sc->sc_dev = self;
	sc->sc_node = ca->ca_node;
	sc->sc_memt = ca->ca_tag;

	root_node = OF_finddevice("/");

	sc->sc_error = 0;
	sc->sc_autopoll = 0;
	sc->sc_pending_eject = 0;
	sc->sc_brightness = sc->sc_brightness_wanted = 0x80;
	sc->sc_volume = sc->sc_volume_wanted = 0x80;
	sc->sc_flags = 0;
	sc->sc_callback = NULL;
	sc->sc_lid_closed = 0;

	if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr,
	    ca->ca_reg[1], 0, &sc->sc_memh) != 0) {
		aprint_error_dev(self, "unable to map registers\n");
		return;
	}
	sc->sc_ih = intr_establish(irq, type, IPL_TTY, pmu_intr, sc);

	pmu_init(sc);

	sc->sc_pmu_ops.cookie = sc;
	sc->sc_pmu_ops.do_command = pmu_send;
	sc->sc_pmu_ops.register_callback = pmu_register_callback;

	if (pmu0 == NULL)
		pmu0 = sc;

	pmu_send(sc, PMU_SYSTEM_READY, 1, cmd, 16, resp);

	/* check what kind of PMU we're talking to */
	if (pmu_send(sc, PMU_GET_VERSION, 0, cmd, 16, resp) > 1)
		aprint_normal(" rev. %d", resp[1]);
	aprint_normal("\n");

	node = OF_child(sc->sc_node);

	while (node != 0) {

		if (OF_getprop(node, "name", name, 256) == 0)
			goto next;

		if (strncmp(name, "pmu-i2c", 8) == 0) {
			aprint_normal_dev(self, "initializing IIC bus\n");
			goto next;
		}
		if (strncmp(name, "adb", 4) == 0) {
			aprint_normal_dev(self, "initializing ADB\n");
			sc->sc_adbops.cookie = sc;
			sc->sc_adbops.send = pmu_adb_send;
			sc->sc_adbops.poll = pmu_adb_poll;
			sc->sc_adbops.autopoll = pmu_autopoll;
			sc->sc_adbops.set_handler = pmu_adb_set_handler;
#if NNADB > 0
			config_found_ia(self, "adb_bus", &sc->sc_adbops,
			    nadb_print);
#endif
			goto next;
		}
		if (strncmp(name, "rtc", 4) == 0) {

			aprint_normal_dev(self, "initializing RTC\n");
			sc->sc_todr.todr_gettime = pmu_todr_get;
			sc->sc_todr.todr_settime = pmu_todr_set;
			sc->sc_todr.cookie = sc;
			todr_attach(&sc->sc_todr);
			goto next;
		}
		if (strncmp(name, "battery", 8) == 0)
			goto next;

		aprint_normal_dev(self, "%s not configured\n", name);
next:
		node = OF_peer(node);
	}

	if (OF_finddevice("/bandit/ohare") != -1) {
		aprint_normal_dev(self, "enabling ohare backlight control\n");
		sc->sc_flags |= PMU_HAS_BACKLIGHT_CONTROL;
		cmd[0] = 0;
		cmd[1] = 0;
		memset(resp, 0, 6);
		if (pmu_send(sc, PMU_READ_BRIGHTNESS, 1, cmd, 16, resp) > 1) {
			sc->sc_brightness_wanted = resp[1];
			pmu_update_brightness(sc);
		}
	}

	/* attach batteries */
	if (of_compatible(root_node, has_legacy_battery) != -1) {

		pmu_attach_legacy_battery(sc);
	} else if (of_compatible(root_node, has_two_smart_batteries) != -1) {

		pmu_attach_smart_battery(sc, 0);
		pmu_attach_smart_battery(sc, 1);
	} else {

		/* check how many batteries we have */
		pmnode = of_getnode_byname(ca->ca_node, "power-mgt");
		if (pmnode == -1)
			goto bat_done;
		if (OF_getprop(pmnode, "prim-info", regs, sizeof(regs)) < 24)
			goto bat_done;
		nbat = regs[6] >> 16;
		for (i = 0; i < nbat; i++)
			pmu_attach_smart_battery(sc, i);
	}
bat_done:

#if notyet
	memset(&iba, 0, sizeof(iba));
	iba.iba_tag = &sc->sc_i2c;
	sc->sc_i2c.ic_cookie = sc;
	sc->sc_i2c.ic_acquire_bus = pmu_i2c_acquire_bus;
	sc->sc_i2c.ic_release_bus = pmu_i2c_release_bus;
	sc->sc_i2c.ic_send_start = NULL;
	sc->sc_i2c.ic_send_stop = NULL;
	sc->sc_i2c.ic_initiate_xfer = NULL;
	sc->sc_i2c.ic_read_byte = NULL;
	sc->sc_i2c.ic_write_byte = NULL;
	sc->sc_i2c.ic_exec = pmu_i2c_exec;
	config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
#endif
	
	if (kthread_create(PRI_NONE, 0, NULL, pmu_thread, sc, &sc->sc_thread,
	    "%s", "pmu") != 0) {
		aprint_error_dev(self, "unable to create event kthread\n");
	}

	sc->sc_lidswitch.smpsw_name = "Lid switch";
	sc->sc_lidswitch.smpsw_type = PSWITCH_TYPE_LID;
	if (sysmon_pswitch_register(&sc->sc_lidswitch) != 0)
		aprint_error_dev(self,
		    "unable to register lid switch with sysmon\n");
}
예제 #30
0
static void
piixpm_attach(device_t parent, device_t self, void *aux)
{
	struct piixpm_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct i2cbus_attach_args iba;
	pcireg_t base, conf;
	pcireg_t pmmisc;
	pci_intr_handle_t ih;
	char devinfo[256];
	const char *intrstr = NULL;

	sc->sc_dev = self;
	sc->sc_pc = pa->pa_pc;
	sc->sc_pcitag = pa->pa_tag;

	aprint_naive("\n");
	aprint_normal("\n");

	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	aprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo,
	    PCI_REVISION(pa->pa_class));

	if (!pmf_device_register(self, piixpm_suspend, piixpm_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");

	/* Read configuration */
	conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC);
	DPRINTF(("%s: conf 0x%x\n", device_xname(self), conf));

	if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) ||
	    (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC))
		goto nopowermanagement;

	/* check whether I/O access to PM regs is enabled */
	pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC);
	if (!(pmmisc & 1))
		goto nopowermanagement;

	sc->sc_pm_iot = pa->pa_iot;
	/* Map I/O space */
	base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE);
	if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base),
	    PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) {
		aprint_error_dev(self, "can't map power management I/O space\n");
		goto nopowermanagement;
	}

	/*
	 * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M.
	 * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20
	 * in the "Specification update" (document #297738).
	 */
	acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh,
			   PIIX_PM_PMTMR,
		(PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0 );

nopowermanagement:
	if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) {
		aprint_normal_dev(self, "SMBus disabled\n");
		return;
	}

	/* Map I/O space */
	sc->sc_smb_iot = pa->pa_iot;
	base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff;
	if (bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base),
	    PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) {
		aprint_error_dev(self, "can't map smbus I/O space\n");
		return;
	}

	sc->sc_poll = 1;
	if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI) {
		/* No PCI IRQ */
		aprint_normal_dev(self, "interrupting at SMI");
	} else if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) {
		/* Install interrupt handler */
		if (pci_intr_map(pa, &ih) == 0) {
			intrstr = pci_intr_string(pa->pa_pc, ih);
			sc->sc_smb_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
			    piixpm_intr, sc);
			if (sc->sc_smb_ih != NULL) {
				aprint_normal_dev(self, "interrupting at %s",
				    intrstr);
				sc->sc_poll = 0;
			}
		}
	}
	if (sc->sc_poll)
		aprint_normal_dev(self, "polling");

	aprint_normal("\n");

	/* Attach I2C bus */
	rw_init(&sc->sc_i2c_rwlock);
	sc->sc_i2c_tag.ic_cookie = sc;
	sc->sc_i2c_tag.ic_acquire_bus = piixpm_i2c_acquire_bus;
	sc->sc_i2c_tag.ic_release_bus = piixpm_i2c_release_bus;
	sc->sc_i2c_tag.ic_exec = piixpm_i2c_exec;

	bzero(&iba, sizeof(iba));
	iba.iba_tag = &sc->sc_i2c_tag;
	config_found_ia(self, "i2cbus", &iba, iicbus_print);

	return;
}