static int
pxauart_match(device_t parent, cfdata_t cf, void *aux)
{
	struct pxaip_attach_args *pxa = aux;
	bus_space_tag_t bt = &pxa2x0_a4x_bs_tag;	/* XXX: This sucks */
	bus_space_handle_t bh;
	struct pxa2x0_gpioconf *gpioconf;
	u_int gpio;
	int rv, i;

	switch (pxa->pxa_addr) {
	case PXA2X0_FFUART_BASE:
		if (pxa->pxa_intr != PXA2X0_INT_FFUART)
			return (0);
		gpioconf = CPU_IS_PXA250 ? pxa25x_com_ffuart_gpioconf :
			    pxa27x_com_ffuart_gpioconf;
		break;

	case PXA2X0_STUART_BASE:
		if (pxa->pxa_intr != PXA2X0_INT_STUART)
			return (0);
		gpioconf = CPU_IS_PXA250 ? pxa25x_com_stuart_gpioconf :
			    pxa27x_com_stuart_gpioconf;
		break;

	case PXA2X0_BTUART_BASE:	/* XXX: Config file option ... */
		if (pxa->pxa_intr != PXA2X0_INT_BTUART)
			return (0);
		gpioconf = CPU_IS_PXA250 ? pxa25x_com_btuart_gpioconf :
			    pxa27x_com_btuart_gpioconf;
		break;

	case PXA2X0_HWUART_BASE:
		if (pxa->pxa_intr != PXA2X0_INT_HWUART)
			return (0);
		if (CPU_IS_PXA270)
			return (0);
		gpioconf = pxa25x_com_hwuart_gpioconf;
		break;

	default:
		return (0);
	}
	for (i = 0; gpioconf[i].pin != -1; i++) {
		gpio = pxa2x0_gpio_get_function(gpioconf[i].pin);
		if (GPIO_FN(gpio) != GPIO_FN(gpioconf[i].value) ||
		    GPIO_FN_IS_OUT(gpio) != GPIO_FN_IS_OUT(gpioconf[i].value))
			return (0);
	}

	pxa->pxa_size = 0x20;

	if (com_is_console(bt, pxa->pxa_addr, NULL))
		return (1);

	if (bus_space_map(bt, pxa->pxa_addr, pxa->pxa_size, 0, &bh))
		return (0);

	/* Make sure the UART is enabled */
	bus_space_write_1(bt, bh, com_ier, IER_EUART);

	rv = comprobe1(bt, bh);
	bus_space_unmap(bt, bh, pxa->pxa_size);

	return (rv);
}
Ejemplo n.º 2
0
/*
 * ae_attach:
 *
 *	Attach an ae interface to the system.
 */
void
ae_attach(device_t parent, device_t self, void *aux)
{
	const uint8_t *enaddr;
	prop_data_t ea;
	struct ae_softc *sc = device_private(self);
	struct arbus_attach_args *aa = aux;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	int i, error;

	sc->sc_dev = self;

	callout_init(&sc->sc_tick_callout, 0);

	printf(": Atheros AR531X 10/100 Ethernet\n");

	/*
	 * Try to get MAC address.
	 */
	ea = prop_dictionary_get(device_properties(sc->sc_dev), "mac-address");
	if (ea == NULL) {
		printf("%s: unable to get mac-addr property\n",
		    device_xname(sc->sc_dev));
		return;
	}
	KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
	KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
	enaddr = prop_data_data_nocopy(ea);

	/* Announce ourselves. */
	printf("%s: Ethernet address %s\n", device_xname(sc->sc_dev),
	    ether_sprintf(enaddr));

	sc->sc_cirq = aa->aa_cirq;
	sc->sc_mirq = aa->aa_mirq;
	sc->sc_st = aa->aa_bst;
	sc->sc_dmat = aa->aa_dmat;

	SIMPLEQ_INIT(&sc->sc_txfreeq);
	SIMPLEQ_INIT(&sc->sc_txdirtyq);

	/*
	 * Map registers.
	 */
	sc->sc_size = aa->aa_size;
	if ((error = bus_space_map(sc->sc_st, aa->aa_addr, sc->sc_size, 0,
	    &sc->sc_sh)) != 0) {
		printf("%s: unable to map registers, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_0;
	}

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmat,
	    sizeof(struct ae_control_data), PAGE_SIZE, 0, &sc->sc_cdseg,
	    1, &sc->sc_cdnseg, 0)) != 0) {
		printf("%s: unable to allocate control data, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_1;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg,
	    sizeof(struct ae_control_data), (void **)&sc->sc_control_data,
	    BUS_DMA_COHERENT)) != 0) {
		printf("%s: unable to map control data, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_2;
	}

	if ((error = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct ae_control_data), 1,
	    sizeof(struct ae_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		printf("%s: unable to create control data DMA map, "
		    "error = %d\n", device_xname(sc->sc_dev), error);
		goto fail_3;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct ae_control_data), NULL,
	    0)) != 0) {
		printf("%s: unable to load control data DMA map, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_4;
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < AE_TXQUEUELEN; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
		    AE_NTXSEGS, MCLBYTES, 0, 0,
		    &sc->sc_txsoft[i].txs_dmamap)) != 0) {
			printf("%s: unable to create tx DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			goto fail_5;
		}
	}

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < AE_NRXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
		    MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
			printf("%s: unable to create rx DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			goto fail_6;
		}
		sc->sc_rxsoft[i].rxs_mbuf = NULL;
	}

	/*
	 * Reset the chip to a known state.
	 */
	ae_reset(sc);

	/*
	 * From this point forward, the attachment cannot fail.  A failure
	 * before this point releases all resources that may have been
	 * allocated.
	 */
	sc->sc_flags |= AE_ATTACHED;

	/*
	 * Initialize our media structures.  This may probe the MII, if
	 * present.
	 */
	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = ae_mii_readreg;
	sc->sc_mii.mii_writereg = ae_mii_writereg;
	sc->sc_mii.mii_statchg = ae_mii_statchg;
	sc->sc_ethercom.ec_mii = &sc->sc_mii;
	ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
	    ether_mediastatus);
	mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);

	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);

	sc->sc_tick = ae_mii_tick;

	strcpy(ifp->if_xname, device_xname(sc->sc_dev));
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	sc->sc_if_flags = ifp->if_flags;
	ifp->if_ioctl = ae_ioctl;
	ifp->if_start = ae_start;
	ifp->if_watchdog = ae_watchdog;
	ifp->if_init = ae_init;
	ifp->if_stop = ae_stop;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * We can support 802.1Q VLAN-sized frames.
	 */
	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;

	/*
	 * Attach the interface.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, enaddr);
	ether_set_ifflags_cb(&sc->sc_ethercom, ae_ifflags_cb);

	rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
	    RND_TYPE_NET, RND_FLAG_DEFAULT);

	/*
	 * Make sure the interface is shutdown during reboot.
	 */
	sc->sc_sdhook = shutdownhook_establish(ae_shutdown, sc);
	if (sc->sc_sdhook == NULL)
		printf("%s: WARNING: unable to establish shutdown hook\n",
		    device_xname(sc->sc_dev));

	/*
	 * Add a suspend hook to make sure we come back up after a
	 * resume.
	 */
	sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev),
	    ae_power, sc);
	if (sc->sc_powerhook == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
		    device_xname(sc->sc_dev));
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_6:
	for (i = 0; i < AE_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_rxsoft[i].rxs_dmamap);
	}
 fail_5:
	for (i = 0; i < AE_TXQUEUELEN; i++) {
		if (sc->sc_txsoft[i].txs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_txsoft[i].txs_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
 fail_4:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
 fail_3:
	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
	    sizeof(struct ae_control_data));
 fail_2:
	bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
 fail_1:
	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size);
 fail_0:
	return;
}
Ejemplo n.º 3
0
static int
fdc_isa_probe(device_t parent, cfdata_t match, void *aux)
{
	struct isa_attach_args *ia = aux;
	bus_space_tag_t iot;
	bus_space_handle_t ioh, ctl_ioh, base_ioh;
	int rv, iobase;

	iot = ia->ia_iot;
	rv = 0;

	if (ia->ia_nio < 1)
		return (0);
	if (ia->ia_nirq < 1)
		return (0);
	if (ia->ia_ndrq < 1)
		return (0);

	if (ISA_DIRECT_CONFIG(ia))
		return (0);

	/* Disallow wildcarded I/O addresses. */
	if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
		return (0);

	/* Don't allow wildcarded IRQ/DRQ. */
	if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ)
		return (0);

	if (ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ)
		return (0);

	/* Map the I/O space. */
	iobase = ia->ia_io[0].ir_addr;
	if (bus_space_map(iot, iobase, 6 /* FDC_NPORT */, 0, &base_ioh))
		return (0);

	if (bus_space_subregion(iot, base_ioh, 2, 4, &ioh)) {
		bus_space_unmap(iot, base_ioh, 6);
		return (0);
	}

	if (bus_space_map(iot, iobase + fdctl + 2, 1, 0, &ctl_ioh)) {
		bus_space_unmap(iot, base_ioh, 6);
		return (0);
	}

	/* Not needed for the rest of the probe. */
	bus_space_unmap(iot, ctl_ioh, 1);

	/* reset */
	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)
		goto out;
	out_fdc(iot, ioh, 0xdf);
	out_fdc(iot, ioh, 2);

	rv = 1;
	ia->ia_nio = 1;
	ia->ia_io[0].ir_size = FDC_NPORT;

	ia->ia_nirq = 1;
	ia->ia_ndrq = 1;

	ia->ia_niomem = 0;

 out:
	bus_space_unmap(iot, base_ioh, 6 /* FDC_NPORT */);
	return (rv);
}
Ejemplo n.º 4
0
static int
smu_attach(device_t dev)
{
	struct smu_softc *sc;
	phandle_t	node, child;
	uint8_t		data[12];

	sc = device_get_softc(dev);

	mtx_init(&sc->sc_mtx, "smu", NULL, MTX_DEF);
	sc->sc_cur_cmd = NULL;
	sc->sc_doorbellirqid = -1;

	sc->sc_u3 = 0;
	if (OF_finddevice("/u3") != -1)
		sc->sc_u3 = 1;

	/*
	 * Map the mailbox area. This should be determined from firmware,
	 * but I have not found a simple way to do that.
	 */
	bus_dma_tag_create(NULL, 16, 0, BUS_SPACE_MAXADDR_32BIT,
	    BUS_SPACE_MAXADDR, NULL, NULL, PAGE_SIZE, 1, PAGE_SIZE, 0, NULL,
	    NULL, &(sc->sc_dmatag));
	sc->sc_bt = &bs_le_tag;
	bus_space_map(sc->sc_bt, SMU_MAILBOX, 4, 0, &sc->sc_mailbox);

	/*
	 * Allocate the command buffer. This can be anywhere in the low 4 GB
	 * of memory.
	 */
	bus_dmamem_alloc(sc->sc_dmatag, (void **)&sc->sc_cmd, BUS_DMA_WAITOK | 
	    BUS_DMA_ZERO, &sc->sc_cmd_dmamap);
	bus_dmamap_load(sc->sc_dmatag, sc->sc_cmd_dmamap,
	    sc->sc_cmd, PAGE_SIZE, smu_phys_callback, sc, 0);
	STAILQ_INIT(&sc->sc_cmdq);

	/*
	 * Set up handlers to change CPU voltage when CPU frequency is changed.
	 */
	EVENTHANDLER_REGISTER(cpufreq_pre_change, smu_cpufreq_pre_change, dev,
	    EVENTHANDLER_PRI_ANY);
	EVENTHANDLER_REGISTER(cpufreq_post_change, smu_cpufreq_post_change, dev,
	    EVENTHANDLER_PRI_ANY);

	/*
	 * Detect and attach child devices.
	 */
	node = ofw_bus_get_node(dev);
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		char name[32];
		memset(name, 0, sizeof(name));
		OF_getprop(child, "name", name, sizeof(name));

		if (strncmp(name, "rpm-fans", 9) == 0 ||
		    strncmp(name, "fans", 5) == 0)
			smu_attach_fans(dev, child);

		if (strncmp(name, "sensors", 8) == 0)
			smu_attach_sensors(dev, child);

		if (strncmp(name, "smu-i2c-control", 15) == 0)
			smu_attach_i2c(dev, child);
	}

	/* Some SMUs have the I2C children directly under the bus. */
	smu_attach_i2c(dev, node);

	/*
	 * Collect calibration constants.
	 */
	smu_get_datablock(dev, SMU_CPUTEMP_CAL, data, sizeof(data));
	sc->sc_cpu_diode_scale = (data[4] << 8) + data[5];
	sc->sc_cpu_diode_offset = (data[6] << 8) + data[7];

	smu_get_datablock(dev, SMU_CPUVOLT_CAL, data, sizeof(data));
	sc->sc_cpu_volt_scale = (data[4] << 8) + data[5];
	sc->sc_cpu_volt_offset = (data[6] << 8) + data[7];
	sc->sc_cpu_curr_scale = (data[8] << 8) + data[9];
	sc->sc_cpu_curr_offset = (data[10] << 8) + data[11];

	smu_get_datablock(dev, SMU_SLOTPW_CAL, data, sizeof(data));
	sc->sc_slots_pow_scale = (data[4] << 8) + data[5];
	sc->sc_slots_pow_offset = (data[6] << 8) + data[7];

	/*
	 * Set up LED interface
	 */
	sc->sc_leddev = led_create(smu_set_sleepled, dev, "sleepled");

	/*
	 * Reset on power loss behavior
	 */

	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
            SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
	    "server_mode", CTLTYPE_INT | CTLFLAG_RW, dev, 0,
	    smu_server_mode, "I", "Enable reboot after power failure");

	/*
	 * Set up doorbell interrupt.
	 */
	sc->sc_doorbellirqid = 0;
	sc->sc_doorbellirq = bus_alloc_resource_any(smu_doorbell, SYS_RES_IRQ,
	    &sc->sc_doorbellirqid, RF_ACTIVE);
	bus_setup_intr(smu_doorbell, sc->sc_doorbellirq,
	    INTR_TYPE_MISC | INTR_MPSAFE, NULL, smu_doorbell_intr, dev,
	    &sc->sc_doorbellirqcookie);
	powerpc_config_intr(rman_get_start(sc->sc_doorbellirq),
	    INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);

	/*
	 * Connect RTC interface.
	 */
	clock_register(dev, 1000);

	/*
	 * Learn about shutdown events
	 */
	EVENTHANDLER_REGISTER(shutdown_final, smu_shutdown, dev,
	    SHUTDOWN_PRI_LAST);

	return (bus_generic_attach(dev));
}
Ejemplo n.º 5
0
/*
 * This routine is called after all the ISA devices are configured,
 * to avoid conflict.
 */
static void
yds_configure_legacy(device_t self)
#define FLEXIBLE	(sc->sc_flags & YDS_CAP_LEGACY_FLEXIBLE)
#define SELECTABLE	(sc->sc_flags & YDS_CAP_LEGACY_SELECTABLE)
{
	static const bus_addr_t opl_addrs[] = {0x388, 0x398, 0x3A0, 0x3A8};
	static const bus_addr_t mpu_addrs[] = {0x330, 0x300, 0x332, 0x334};
	struct yds_softc *sc;
	pcireg_t reg;
	device_t dev;
	int i;

	sc = device_private(self);
	if (!FLEXIBLE && !SELECTABLE)
		return;

	reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY);
	reg &= ~0x8133c03f;	/* these bits are out of interest */
	reg |= ((YDS_PCI_EX_LEGACY_IMOD) |
		(YDS_PCI_LEGACY_FMEN |
		 YDS_PCI_LEGACY_MEN /*| YDS_PCI_LEGACY_MIEN*/));
	reg |= YDS_PCI_EX_LEGACY_SMOD_DISABLE;
	if (FLEXIBLE) {
		pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg);
		delay(100*1000);
	}

	/* Look for OPL */
	dev = 0;
	for (i = 0; i < sizeof(opl_addrs) / sizeof(bus_addr_t); i++) {
		if (SELECTABLE) {
			pci_conf_write(sc->sc_pc, sc->sc_pcitag,
				       YDS_PCI_LEGACY, reg | (i << (0+16)));
			delay(100*1000);	/* wait 100ms */
		} else
			pci_conf_write(sc->sc_pc, sc->sc_pcitag,
				       YDS_PCI_FM_BA, opl_addrs[i]);
		if (bus_space_map(sc->sc_opl_iot,
				  opl_addrs[i], 4, 0, &sc->sc_opl_ioh) == 0) {
			struct audio_attach_args aa;

			aa.type = AUDIODEV_TYPE_OPL;
			aa.hwif = aa.hdl = NULL;
			dev = config_found(self, &aa, audioprint);
			if (dev == 0)
				bus_space_unmap(sc->sc_opl_iot,
						sc->sc_opl_ioh, 4);
			else {
				if (SELECTABLE)
					reg |= (i << (0+16));
				break;
			}
		}
	}
	if (dev == 0) {
		reg &= ~YDS_PCI_LEGACY_FMEN;
		pci_conf_write(sc->sc_pc, sc->sc_pcitag,
			       YDS_PCI_LEGACY, reg);
	} else {
		/* Max. volume */
		YWRITE4(sc, YDS_LEGACY_OUT_VOLUME, 0x3fff3fff);
		YWRITE4(sc, YDS_LEGACY_REC_VOLUME, 0x3fff3fff);
	}

	/* Look for MPU */
	dev = NULL;
	for (i = 0; i < sizeof(mpu_addrs) / sizeof(bus_addr_t); i++) {
		if (SELECTABLE)
			pci_conf_write(sc->sc_pc, sc->sc_pcitag,
				       YDS_PCI_LEGACY, reg | (i << (4+16)));
		else
			pci_conf_write(sc->sc_pc, sc->sc_pcitag,
				       YDS_PCI_MPU_BA, mpu_addrs[i]);
		if (bus_space_map(sc->sc_mpu_iot,
				  mpu_addrs[i], 2, 0, &sc->sc_mpu_ioh) == 0) {
			struct audio_attach_args aa;

			aa.type = AUDIODEV_TYPE_MPU;
			aa.hwif = aa.hdl = NULL;
			dev = config_found(self, &aa, audioprint);
			if (dev == 0)
				bus_space_unmap(sc->sc_mpu_iot,
						sc->sc_mpu_ioh, 2);
			else {
				if (SELECTABLE)
					reg |= (i << (4+16));
				break;
			}
		}
	}
	if (dev == 0) {
		reg &= ~(YDS_PCI_LEGACY_MEN | YDS_PCI_LEGACY_MIEN);
		pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg);
	}
	sc->sc_mpu = dev;
}
Ejemplo n.º 6
0
void
ohci_aubus_attach(struct device *parent, struct device *self, void *aux)
{
	ohci_softc_t *sc = (ohci_softc_t *)self;
	void *ih;
	usbd_status r;
	uint32_t x, tmp;
	struct aubus_attach_args *aa = aux;

	r = 0;

	sc->sc_size = USBH_SIZE;
	sc->iot = aa->aa_st;
	sc->sc_bus.dmatag = (bus_dma_tag_t)aa->aa_dt;

	if (bus_space_map(sc->iot, USBH_BASE, USBH_SIZE, 0, &sc->ioh)) {
		printf("%s: Unable to map USBH registers\n",
			sc->sc_bus.bdev.dv_xname);
		return;
	}
	/*
	 * Enable the USB Host controller here.
	 * As per 7.2 in the Au1500 manual:
	 *
	 *  (1) Set CE bit to enable clocks.
	 *  (2) Set E to enable OHCI
	 *  (3) Clear HCFS in OHCI_CONTROL.
	 *  (4) Wait for RD bit to be set.
	 */
	x = bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE);
	x |= UE_CE;
	bus_space_write_4(sc->iot, sc->ioh, USBH_ENABLE, x);
	delay(10);
	x |= UE_E;
#ifdef __MIPSEB__
	x |= UE_BE;
#endif
	bus_space_write_4(sc->iot, sc->ioh, USBH_ENABLE, x);
	delay(10);
	x = bus_space_read_4(sc->iot, sc->ioh, OHCI_CONTROL);
	x &= ~(OHCI_HCFS_MASK);
	bus_space_write_4(sc->iot, sc->ioh, OHCI_CONTROL, x);
	delay(10);
	/*  Need to read USBH_ENABLE twice in succession according to
         *  au1500 Errata #7.
         */
	for (x = 100; x; x--) {
		bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE);
		tmp = bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE);
		if (tmp&UE_RD)
			break;
		delay(1000);
	}
	printf(": Au1X00 OHCI\n");

	/* Disable OHCI interrupts */
	bus_space_write_4(sc->iot, sc->ioh, OHCI_INTERRUPT_DISABLE,
				OHCI_ALL_INTRS);
	/* hook interrupt */
	ih = au_intr_establish(aa->aa_irq[0], 0, IPL_USB, IST_LEVEL_LOW,
			ohci_intr, sc);
	if (ih == NULL) {
		printf("%s: couldn't establish interrupt\n",
			sc->sc_bus.bdev.dv_xname);
	}

	if (x)
		r = ohci_init(sc);
	if (r != USBD_NORMAL_COMPLETION) {
		printf("%s: init failed, error=%d\n",
			sc->sc_bus.bdev.dv_xname, r);
		au_intr_disestablish(ih);
		return;
	}

	/* Attach USB device */
	sc->sc_child = config_found((void *)sc, &sc->sc_bus, usbctlprint);

}
Ejemplo n.º 7
0
void
macfb_obio_attach(struct device *parent, struct device *self, void *aux)
{
	struct obio_attach_args *oa = (struct obio_attach_args *) aux;
	struct macfb_softc *sc = (struct macfb_softc *)self;
	u_long length;
	u_int32_t vbase1, vbase2;
	struct macfb_devconfig *dc;

	sc->card_id = 0;
	sc->sc_tag = oa->oa_tag;

	dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK);
	bzero(dc, sizeof(*dc));

        switch (current_mac_model->class) {
	case MACH_CLASSQ2:
		if (current_mac_model->machineid != MACH_MACLC575) {
			sc->sc_basepa = VALKYRIE_BASE;
			length = 0x00100000;		/* 1MB */

			if (sc->sc_basepa <= mac68k_vidphys &&
			    mac68k_vidphys < (sc->sc_basepa + length))
				sc->sc_fbofs = mac68k_vidphys - sc->sc_basepa;
			else
				sc->sc_fbofs = 0;

#ifdef DEBUG
			printf(" @ %lx", sc->sc_basepa + sc->sc_fbofs);
#endif

			if (bus_space_map(sc->sc_tag, VALKYRIE_CONTROL_BASE,
			    0x40, 0, &sc->sc_regh) != 0) {
				printf(": can't map Valkyrie registers\n");
				free(dc, M_DEVBUF);
				return;
			}
			/* Disable interrupts */
			bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x18, 0x1);
			bus_space_unmap(sc->sc_tag, sc->sc_regh, 0x40);

			printf(": Valkyrie\n");
			break;
		}
		/*
		 * Note:  the only system in this class that does not have
		 * the Valkyrie chip -- at least, that we know of -- is
		 * the Performa/LC 57x series.  This system has a version
		 * of the DAFB controller, instead.
		 *
		 * If this assumption proves false, we'll have to be more
		 * intelligent here.
		 */
		/*FALLTHROUGH*/
        case MACH_CLASSQ:
		if (bus_space_map(sc->sc_tag, DAFB_CONTROL_BASE, 0x120, 0,
		    &sc->sc_regh)) {
			printf(": can't map DAFB registers\n");
			free(dc, M_DEVBUF);
			return;
		}

		sc->sc_basepa = DAFB_BASE;
		length = 0x00100000;		/* 1MB */

		/* Compute the current frame buffer offset */
		vbase1 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x0) & 0xfff;

		/*
		 * XXX The following exists because the DAFB v7 in these
		 * systems doesn't return reasonable values to use for fbofs.
		 * Ken'ichi Ishizaka gets credit for this hack.  (sar 19990426)
		 * (Does this get us the correct result for _all_ DAFB-
		 * equipped systems and monitor combinations?  It seems
		 * possible, if not likely...)
		 */
		switch (current_mac_model->machineid) {
		case MACH_MACLC475:
		case MACH_MACLC475_33:
		case MACH_MACLC575:
		case MACH_MACQ605:
		case MACH_MACQ605_33:
			vbase1 &= 0x3f;
			break;
		}
		vbase2 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x4) & 0xf;
		sc->sc_fbofs = (vbase1 << 9) | (vbase2 << 5);

#ifdef DEBUG
		printf(" @ %lx", sc->sc_basepa + sc->sc_fbofs);
#endif

		/* Disable interrupts */
		bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x104, 0);

		/* Clear any pending interrupts */
		bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x10C, 0);
		bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x110, 0);
		bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x114, 0);

		printf(": DAFB, monitor sense %x\n",
		    (bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x1c) & 0x7));

		bus_space_unmap(sc->sc_tag, sc->sc_regh, 0x120);

		if (bus_space_map(sc->sc_tag, DAFB_CMAP_BASE, 0x20, 0,
		    &sc->sc_regh) == 0) {
			dc->dc_cmapregs = (vaddr_t)bus_space_vaddr(sc->sc_tag,
			    sc->sc_regh);
			dc->dc_setcolor = dafb_setcolor;
		}

		break;
	case MACH_CLASSAV:
		sc->sc_basepa = CIVIC_BASE;
		length = 0x00200000;		/* 2MB */

		if (sc->sc_basepa <= mac68k_vidphys &&
		    mac68k_vidphys < (sc->sc_basepa + length))
			sc->sc_fbofs = mac68k_vidphys - sc->sc_basepa;
		else
			sc->sc_fbofs = 0;

#ifdef DEBUG
		printf(" @ %lx", sc->sc_basepa + sc->sc_fbofs);
#endif

		if (bus_space_map(sc->sc_tag, CIVIC_CONTROL_BASE, PAGE_SIZE,
		    0, &sc->sc_regh) != 0) {
			printf(": can't map Civic registers\n");
			free(dc, M_DEVBUF);
			return;
		}

		/* Disable interrupts */
		bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x120, 0);
		bus_space_unmap(sc->sc_tag, sc->sc_regh, PAGE_SIZE);

		printf(": Civic\n");
		break;
	case MACH_CLASSIIci:
	case MACH_CLASSIIsi:
		sc->sc_basepa = trunc_page(mac68k_vidphys);
		sc->sc_fbofs = m68k_page_offset(mac68k_vidphys);
		length = mac68k_vidlen + sc->sc_fbofs;

#ifdef DEBUG
		printf(" @ %lx: RBV", sc->sc_basepa + sc->sc_fbofs);
		switch (via2_reg(rMonitor) & RBVMonitorMask) {
		case RBVMonIDBWP:
			printf(", 15\" monochrome portrait");
			break;
		case RBVMonIDRGB12:
			printf(", 12\" color");
			break;
		case RBVMonIDRGB15:
			printf(", 15\" color");
			break;
		case RBVMonIDStd:
			printf(", Macintosh II");
			break;
		default:
			printf(", unrecognized");
			break;
		}
		printf(" display\n");
#else
		printf(": RBV\n");
#endif

		break;
	default:
		sc->sc_basepa = trunc_page(mac68k_vidphys);
		sc->sc_fbofs = m68k_page_offset(mac68k_vidphys);
		length = mac68k_vidlen + sc->sc_fbofs;

#ifdef DEBUG
		printf(" @ %lx:", sc->sc_basepa + sc->sc_fbofs);
#endif
		printf(": On-board video\n");
		break;
	}

	if (bus_space_map(sc->sc_tag, sc->sc_basepa, length, 0,
	    &sc->sc_handle)) {
		printf("%s: failed to map video RAM\n", sc->sc_dev.dv_xname);
		free(dc, M_DEVBUF);
		return;
	}

	if (sc->sc_basepa <= mac68k_vidphys &&
	    mac68k_vidphys < (sc->sc_basepa + length))
		videoaddr =
		    (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_handle) +
		    sc->sc_fbofs;

	dc->dc_vaddr = (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_handle);
	dc->dc_paddr = sc->sc_basepa;
	dc->dc_offset = sc->sc_fbofs;
	dc->dc_wid = videosize & 0xffff;
	dc->dc_ht = (videosize >> 16) & 0xffff;
	dc->dc_depth = videobitdepth;
	dc->dc_rowbytes = videorowbytes;
	dc->dc_size = dc->dc_ht * dc->dc_rowbytes;

	/* Perform common video attachment. */
	macfb_attach_common(sc, dc);
}
Ejemplo n.º 8
0
/*
 * Attach this instance, and then all the sub-devices
 */
static void
asc_vsbus_attach(struct device *parent, struct device *self, void *aux)
{
	struct vsbus_attach_args *va = aux;
	struct asc_vsbus_softc *asc = (void *)self;
	struct ncr53c9x_softc *sc = &asc->sc_ncr53c9x;
	int error;

	asc_attached = 1;
	/*
	 * Set up glue for MI code early; we use some of it here.
	 */
	sc->sc_glue = &asc_vsbus_glue;

	asc->sc_bst = va->va_iot;
	asc->sc_dmat = va->va_dmat;

	error = bus_space_map(asc->sc_bst, va->va_paddr - ASC_REG_NCR,
	    ASC_REG_END, 0, &asc->sc_bsh);
	if (error) {
		printf(": failed to map registers: error=%d\n", error);
		return;
	}
	error = bus_space_subregion(asc->sc_bst, asc->sc_bsh, ASC_REG_NCR,
	    ASC_REG_END - ASC_REG_NCR, &asc->sc_ncrh);
	if (error) {
		printf(": failed to map ncr registers: error=%d\n", error);
		return;
	}
	if (vax_boardtype == VAX_BTYP_46 || vax_boardtype == VAX_BTYP_48) {
		error = bus_space_subregion(asc->sc_bst, asc->sc_bsh,
		    ASC_REG_KA46_ADR, sizeof(u_int32_t), &asc->sc_adrh);
		if (error) {
			printf(": failed to map adr register: error=%d\n",
			     error);
			return;
		}
		error = bus_space_subregion(asc->sc_bst, asc->sc_bsh,
		    ASC_REG_KA46_DIR, sizeof(u_int32_t), &asc->sc_dirh);
		if (error) {
			printf(": failed to map dir register: error=%d\n",
			     error);
			return;
		}
	} else {
		/* This is a gross and disgusting kludge but it'll
		 * save a bunch of ugly code.  Unlike the VS4000/60,
		 * the SCSI Address and direction registers are not
		 * near the SCSI NCR registers and are inside the 
		 * block of general VAXstation registers.  So we grab
		 * them from there and knowing the internals of the 
		 * bus_space implementation, we cast to bus_space_handles.
		 */
		struct vsbus_softc *vsc = (struct vsbus_softc *) parent;
		asc->sc_adrh = (bus_space_handle_t) (vsc->sc_vsregs + ASC_REG_KA49_ADR);
		asc->sc_dirh = (bus_space_handle_t) (vsc->sc_vsregs + ASC_REG_KA49_DIR);
#if 0
		printf("\n%s: adrh=0x%08lx dirh=0x%08lx", self->dv_xname,
		       asc->sc_adrh, asc->sc_dirh);
		ncr53c9x_debug = NCR_SHOWDMA|NCR_SHOWINTS|NCR_SHOWCMDS|NCR_SHOWPHASE|NCR_SHOWSTART|NCR_SHOWMSGS;
#endif
	}
	error = bus_dmamap_create(asc->sc_dmat, ASC_MAXXFERSIZE, 1, 
	    ASC_MAXXFERSIZE, 0, BUS_DMA_NOWAIT, &asc->sc_dmamap);

	switch (vax_boardtype) {
#if defined(VAX46)
	case VAX_BTYP_46:
		sc->sc_id = (clk_page[0xbc/2] >> clk_tweak) & 7;
		break;
#endif
	default:
		sc->sc_id = 6;	/* XXX need to get this from VMB */
		break;
	}

	sc->sc_freq = ASC_FREQUENCY;

	/* gimme MHz */
	sc->sc_freq /= 1000000;

	scb_vecalloc(va->va_cvec, (void (*)(void *)) ncr53c9x_intr,
	    &asc->sc_ncr53c9x, SCB_ISTACK, &asc->sc_intrcnt);
	asc->sc_cvec = va->va_cvec;
	evcount_attach(&asc->sc_intrcnt, self->dv_xname,
	    (void *)&asc->sc_cvec, &evcount_intr);

	/*
	 * XXX More of this should be in ncr53c9x_attach(), but
	 * XXX should we really poke around the chip that much in
	 * XXX the MI code?  Think about this more...
	 */

	/*
	 * Set up static configuration info.
	 */
	sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
	sc->sc_cfg2 = NCRCFG2_SCSI2;
	sc->sc_cfg3 = 0;
	sc->sc_rev = NCR_VARIANT_NCR53C94;

	/*
	 * XXX minsync and maxxfer _should_ be set up in MI code,
	 * XXX but it appears to have some dependency on what sort
	 * XXX of DMA we're hooked up to, etc.
	 */

	/*
	 * This is the value used to start sync negotiations
	 * Note that the NCR register "SYNCTP" is programmed
	 * in "clocks per byte", and has a minimum value of 4.
	 * The SCSI period used in negotiation is one-fourth
	 * of the time (in nanoseconds) needed to transfer one byte.
	 * Since the chip's clock is given in MHz, we have the following
	 * formula: 4 * period = (1000 / freq) * 4
	 */
	sc->sc_minsync = (1000 / sc->sc_freq);
	sc->sc_maxxfer = 64 * 1024;

	/* Do the common parts of attachment. */
	ncr53c9x_attach(sc, &asc_vsbus_ops, &asc_vsbus_dev);
}
Ejemplo n.º 9
0
int
acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
{
	struct aml_value	res;
	bus_size_t		ec_sc, ec_data;
	int			dtype, ctype;
	char			*buf;
	int			size, ret;
	int64_t			gpe;
	struct acpi_ecdt	*ecdt = aa->aaa_table;
	extern struct aml_node	aml_root;

	/* Check if this is ECDT initialization */
	if (ecdt) {
		/* Get GPE, Data and Control segments */
		sc->sc_gpe = ecdt->gpe_bit;

		ctype = ecdt->ec_control.address_space_id;
		ec_sc = ecdt->ec_control.address;

		dtype = ecdt->ec_data.address_space_id;
		ec_data = ecdt->ec_data.address;

		/* Get devnode from header */
		sc->sc_devnode = aml_searchname(&aml_root, ecdt->ec_id);

		goto ecdtdone;
	}

	if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_GPE", 0, NULL, &gpe)) {
		dnprintf(10, "%s: no _GPE\n", DEVNAME(sc));
		return (1);
	}

	sc->sc_gpe = gpe;

	if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) {
		dnprintf(10, "%s: no _CRS\n", DEVNAME(sc));
		return (1);
	}

	/* Parse CRS to get control and data registers */

	if (res.type != AML_OBJTYPE_BUFFER) {
		dnprintf(10, "%s: unknown _CRS type %d\n",
		    DEVNAME(sc), res.type);
		aml_freevalue(&res);
		return (1);
	}

	size = res.length;
	buf = res.v_buffer;

	ret = acpiec_getregister(buf, size, &dtype, &ec_data);
	if (ret <= 0) {
		dnprintf(10, "%s: failed to read DATA from _CRS\n",
		    DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}

	buf += ret;
	size -= ret;

	ret = acpiec_getregister(buf, size, &ctype, &ec_sc);
	if (ret <= 0) {
		dnprintf(10, "%s: failed to read S/C from _CRS\n",
		    DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}

	buf += ret;
	size -= ret;

	if (size != 2 || *buf != RES_TYPE_ENDTAG) {
		dnprintf(10, "%s: no _CRS end tag\n", DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}
	aml_freevalue(&res);

	/* XXX: todo - validate _CRS checksum? */
ecdtdone:

	dnprintf(10, "%s: Data: 0x%x, S/C: 0x%x\n",
	    DEVNAME(sc), ec_data, ec_sc);

	if (ctype == GAS_SYSTEM_IOSPACE)
		sc->sc_cmd_bt = aa->aaa_iot;
	else
		sc->sc_cmd_bt = aa->aaa_memt;

	if (bus_space_map(sc->sc_cmd_bt, ec_sc, 1, 0, &sc->sc_cmd_bh)) {
		dnprintf(10, "%s: failed to map S/C reg.\n", DEVNAME(sc));
		return (1);
	}

	if (dtype == GAS_SYSTEM_IOSPACE)
		sc->sc_data_bt = aa->aaa_iot;
	else
		sc->sc_data_bt = aa->aaa_memt;

	if (bus_space_map(sc->sc_data_bt, ec_data, 1, 0, &sc->sc_data_bh)) {
		dnprintf(10, "%s: failed to map DATA reg.\n", DEVNAME(sc));
		bus_space_unmap(sc->sc_cmd_bt, sc->sc_cmd_bh, 1);
		return (1);
	}

	return (0);
}
Ejemplo n.º 10
0
void
cpi_nubus_attach(device_t parent, device_t self, void *aux)
{
	struct cpi_softc *sc;
	struct nubus_attach_args *na;
	int err, ii;

	sc = device_private(self);
	sc->sc_options = (device_cfdata(self)->cf_flags & CPI_OPTIONS_MASK);

	na = aux;
	sc->sc_bst = na->na_tag;
	memcpy(&sc->sc_slot, na->fmt, sizeof(nubus_slot));
	sc->sc_basepa = (bus_addr_t)NUBUS_SLOT2PA(na->slot);

	/*
	 * The CIO sits eight bit wide on the top byte lane of
	 * Nubus, so map 16 byte.
	 */
	if (TRACE_CONFIG) {
		printf("\n");
		printf("\tcpi_nubus_attach() mapping 8536 CIO at 0x%lx.\n",
		    sc->sc_basepa + CIO_BASE_OFFSET);
	}

	err = bus_space_map(sc->sc_bst, sc->sc_basepa + CIO_BASE_OFFSET,
	    (Z8536_IOSIZE << 4), 0, &sc->sc_bsh);
	if (err) {
		aprint_normal(": failed to map memory space.\n");
		return;
	}
	
	sc->sc_lpstate = LP_INITIAL;
	sc->sc_intcount = 0;
	sc->sc_bytestoport = 0;

	if (TRACE_CONFIG)
		printf("\tcpi_nubus_attach() about to set up 8536 CIO.\n");

	for (ii = 0; ii < sizeof(cio_reset); ii += 2)
		z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_reset[ii],
		    cio_reset[ii + 1]);
	
	delay(1000);		/* Give the CIO time to set itself up */
	for (ii = 0; ii < sizeof(cio_init); ii += 2) {
		z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_init[ii],
		    cio_init[ii + 1]);
	}
	
	if (TRACE_CONFIG)
		printf("\tcpi_nubus_attach() done with 8536 CIO setup.\n");
		
	/* XXX Get information strings from the card ROM */
	aprint_normal(": CSI Hurdler II Centronics\n");

	/* Attach CIO timers 1+2 as timecounter */
	if (sc->sc_options & CPI_CTC12_IS_TIMECOUNTER) {
		cpi_tc_initclock(sc);
	}

	callout_init(&sc->sc_wakeupchan, 0);	/* XXX */
	
	/* make sure interrupts are vectored to us */
	add_nubus_intr(na->slot, cpi_nubus_intr, sc);
}
Ejemplo n.º 11
0
/*
 * gtmpsc_hackinit - hacks required to supprt GTMPSC console
 */
STATIC int
gtmpsc_hackinit(struct gtmpsc_softc *sc, bus_space_tag_t iot,
		bus_dma_tag_t dmat, bus_addr_t base, int unit, int brg,
		int baudrate, tcflag_t tcflag)
{
	gtmpsc_poll_sdma_t *cn_dmapage =
	    (gtmpsc_poll_sdma_t *)gtmpsc_cn_dmapage;
	int error;

	DPRINTF(("hackinit\n"));

	memset(sc, 0, sizeof(struct gtmpsc_softc));
	error = bus_space_map(iot, base + GTMPSC_BASE(unit), GTMPSC_SIZE, 0,
	    &sc->sc_mpsch);
	if (error != 0)
		goto fail0;

	error = bus_space_map(iot, base + GTSDMA_BASE(unit), GTSDMA_SIZE, 0,
	    &sc->sc_sdmah);
	if (error != 0)
		goto fail1;
	error = bus_dmamap_create(dmat, sizeof(gtmpsc_polltx_t), 1,
	   sizeof(gtmpsc_polltx_t), 0, BUS_DMA_NOWAIT, &sc->sc_txdma_map);
	if (error != 0)
		goto fail2;
	error = bus_dmamap_load(dmat, sc->sc_txdma_map, cn_dmapage->tx,
	    sizeof(gtmpsc_polltx_t), NULL,
	    BUS_DMA_NOWAIT | BUS_DMA_READ | BUS_DMA_WRITE);
	if (error != 0)
		goto fail3;
	error = bus_dmamap_create(dmat, sizeof(gtmpsc_pollrx_t), 1,
	   sizeof(gtmpsc_pollrx_t), 0, BUS_DMA_NOWAIT,
	   &sc->sc_rxdma_map);
	if (error != 0)
		goto fail4;
	error = bus_dmamap_load(dmat, sc->sc_rxdma_map, cn_dmapage->rx,
	    sizeof(gtmpsc_pollrx_t), NULL,
	    BUS_DMA_NOWAIT | BUS_DMA_READ | BUS_DMA_WRITE);
	if (error != 0)
		goto fail5;

	sc->sc_iot = iot;
	sc->sc_dmat = dmat;
	sc->sc_poll_sdmapage = cn_dmapage;
	sc->sc_brg = brg;
	sc->sc_baudrate = baudrate;
	sc->sc_cflag = tcflag;

	gtmpsc_txdesc_init(sc);
	gtmpsc_rxdesc_init(sc);

	return 0;

fail5:
	bus_dmamap_destroy(dmat, sc->sc_rxdma_map);
fail4:
	bus_dmamap_unload(dmat, sc->sc_txdma_map);
fail3:
	bus_dmamap_destroy(dmat, sc->sc_txdma_map);
fail2:
	bus_space_unmap(iot, sc->sc_sdmah, GTSDMA_SIZE);
fail1:
	bus_space_unmap(iot, sc->sc_mpsch, GTMPSC_SIZE);
fail0:
	return error;
}
Ejemplo n.º 12
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);
	}
}
Ejemplo n.º 13
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
}
Ejemplo n.º 14
0
int
nouveau_fifo_channel_create_(struct nouveau_object *parent,
			     struct nouveau_object *engine,
			     struct nouveau_oclass *oclass,
			     int bar, u32 addr, u32 size, u32 pushbuf,
			     u64 engmask, int len, void **ptr)
{
	struct nouveau_device *device = nv_device(engine);
	struct nouveau_fifo *priv = (void *)engine;
	struct nouveau_fifo_chan *chan;
	struct nouveau_dmaeng *dmaeng;
	unsigned long flags;
	int ret;

	/* create base object class */
	ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
				     engmask, len, ptr);
	chan = *ptr;
	if (ret)
		return ret;

	/* validate dma object representing push buffer */
	chan->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
	if (!chan->pushdma)
		return -ENOENT;

	dmaeng = (void *)chan->pushdma->base.engine;
	switch (chan->pushdma->base.oclass->handle) {
	case NV_DMA_FROM_MEMORY_CLASS:
	case NV_DMA_IN_MEMORY_CLASS:
		break;
	default:
		return -EINVAL;
	}

	ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu);
	if (ret)
		return ret;

	/* find a free fifo channel */
	spin_lock_irqsave(&priv->lock, flags);
	for (chan->chid = priv->min; chan->chid < priv->max; chan->chid++) {
		if (!priv->channel[chan->chid]) {
			priv->channel[chan->chid] = nv_object(chan);
			break;
		}
	}
	spin_unlock_irqrestore(&priv->lock, flags);

	if (chan->chid == priv->max) {
		nv_error(priv, "no free channels\n");
		return -ENOSPC;
	}

	/* map fifo control registers */
#ifdef __NetBSD__
	chan->bst = nv_device_resource_tag(device, bar);
	/* XXX errno NetBSD->Linux */
	ret = -bus_space_map(chan->bst, nv_device_resource_start(device, bar) +
	    addr + (chan->chid * size), size, 0, &chan->bsh);
	if (ret)
		return ret;
	chan->mapped = true;
#else
	chan->user = ioremap(nv_device_resource_start(device, bar) + addr +
			     (chan->chid * size), size);
	if (!chan->user)
		return -EFAULT;
#endif

	nouveau_event_trigger(priv->cevent, 0);

	chan->size = size;
	return 0;
}
Ejemplo n.º 15
0
void
pchbattach(struct device *parent, struct device *self, void *aux)
{
	struct pchb_softc *sc = (struct pchb_softc *)self;
	struct pci_attach_args *pa = aux;
	int has_agp = 0, i, r;

	switch (PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_AMD:
		printf("\n");
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_AMD_AMD64_0F_HT:
		case PCI_PRODUCT_AMD_AMD64_10_HT:
		case PCI_PRODUCT_AMD_AMD64_11_HT:
			for (i = 0; i < AMD64HT_NUM_LDT; i++)
				pchb_amd64ht_attach(self, pa, i);
			break;
		}
		break;
	case PCI_VENDOR_INTEL:
		switch (PCI_PRODUCT(pa->pa_id)) {

		/*
		 * As for Intel AGP, the host bridge is either in GFX mode
		 * (internal graphics) or in AGP mode. In GFX mode, we pretend
		 * to have AGP because the graphics memory access is very
		 * similar and the AGP GATT code will deal with this. In the
		 * latter case, the pci_get_capability(PCI_CAP_AGP) test below
		 * will fire, so we do no harm by already setting the flag.
		 */

		/* AGP only */
		case PCI_PRODUCT_INTEL_82915GM_HB:
		case PCI_PRODUCT_INTEL_82945GM_HB:
		case PCI_PRODUCT_INTEL_82945GME_HB:
		case PCI_PRODUCT_INTEL_82G965_HB:
		case PCI_PRODUCT_INTEL_82Q965_HB:
		case PCI_PRODUCT_INTEL_82GM965_HB:
		case PCI_PRODUCT_INTEL_82G33_HB:
		case PCI_PRODUCT_INTEL_82G35_HB:
			has_agp = 1;
			break;

		/* AGP + RNG */
		case PCI_PRODUCT_INTEL_82915G_HB:
		case PCI_PRODUCT_INTEL_82945G_HB:
			has_agp = 1;
			/* FALLTHROUGH */

		case PCI_PRODUCT_INTEL_82925X_HB:
		case PCI_PRODUCT_INTEL_82955X_HB:
			sc->sc_bt = pa->pa_memt;
			if (bus_space_map(sc->sc_bt, I82802_IOBASE,
			    I82802_IOSIZE, 0, &sc->sc_bh))
				break;

			/* probe and init rng */
			if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh,
			    I82802_RNG_HWST) & I82802_RNG_HWST_PRESENT))
				break;

			/* enable RNG */
			bus_space_write_1(sc->sc_bt, sc->sc_bh,
			    I82802_RNG_HWST,
			    bus_space_read_1(sc->sc_bt, sc->sc_bh,
			    I82802_RNG_HWST) | I82802_RNG_HWST_ENABLE);

			/* see if we can read anything */
			for (i = 1000; i-- &&
			    !(bus_space_read_1(sc->sc_bt, sc->sc_bh,
			    I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV); )
				DELAY(10);

			if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh,
			    I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV))
				break;

			r = bus_space_read_1(sc->sc_bt, sc->sc_bh,
			    I82802_RNG_DATA);

			timeout_set(&sc->sc_rng_to, pchb_rnd, sc);
			sc->sc_rng_i = 4;
			pchb_rnd(sc);
			break;
		}
		printf("\n");
		break;
	default:
		printf("\n");
		break;
	}

#if NAGP > 0
	/*
	 * If we haven't detected AGP yet (via a product ID),
	 * then check for AGP capability on the device.
	 */
	if (has_agp ||
	    pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
	    NULL, NULL) != 0) {
		agp_set_pchb(pa);
	}
#endif
}
Ejemplo n.º 16
0
/*
 * Probe routine.
 *
 * See if the card is there and at the right place.
 * (XXX - cgd -- needs help)
 */
int
elprobe(device_t parent, cfdata_t match, void *aux)
{
	struct isa_attach_args *ia = aux;
	bus_space_tag_t iot = ia->ia_iot;
	bus_space_handle_t ioh;
	int iobase;
	u_int8_t station_addr[ETHER_ADDR_LEN];
	u_int8_t i;
	int rval;

	rval = 0;

	if (ia->ia_nio < 1)
		return (0);
	if (ia->ia_nirq < 1)
		return (0);

	if (ISA_DIRECT_CONFIG(ia))
		return (0);

	iobase = ia->ia_io[0].ir_addr;

	if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
		return (0);
	if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ)
		return (0);

	/* First check the base. */
	if (iobase < 0x200 || iobase > 0x3f0)
		return 0;

	/* Map i/o space. */
	if (bus_space_map(iot, iobase, 16, 0, &ioh))
		return 0;

	/*
	 * Now attempt to grab the station address from the PROM and see if it
	 * contains the 3com vendor code.
	 */
	DPRINTF(("Probing 3c501 at 0x%x...\n", iobase));

	/* Reset the board. */
	DPRINTF(("Resetting board...\n"));
	bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
	delay(5);
	bus_space_write_1(iot, ioh, EL_AC, 0);

	/* Now read the address. */
	DPRINTF(("Reading station address...\n"));
	for (i = 0; i < ETHER_ADDR_LEN; i++) {
		bus_space_write_1(iot, ioh, EL_GPBL, i);
		station_addr[i] = bus_space_read_1(iot, ioh, EL_EAW);
	}
	DPRINTF(("Address is %s\n", ether_sprintf(station_addr)));

	/*
	 * If the vendor code is ok, return a 1.  We'll assume that whoever
	 * configured this system is right about the IRQ.
	 */
	if (station_addr[0] != 0x02 || station_addr[1] != 0x60 ||
	    station_addr[2] != 0x8c) {
		DPRINTF(("Bad vendor code.\n"));
		goto out;
	}
	DPRINTF(("Vendor code ok.\n"));

	ia->ia_nio = 1;
	ia->ia_io[0].ir_size = 16;

	ia->ia_nirq = 1;

	ia->ia_niomem = 0;
	ia->ia_ndrq = 0;

	rval = 1;

 out:
	bus_space_unmap(iot, ioh, 16);
	return rval;
}
Ejemplo n.º 17
0
void    
platform_mp_start_ap(void)
{
	bus_space_handle_t scu;
	bus_space_handle_t src;

	uint32_t val;
	int i;

	if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
		panic("Couldn't map the SCU\n");
	if (bus_space_map(fdtbus_bs_tag, SRC_PHYSBASE, SRC_SIZE, 0, &src) != 0)
		panic("Couldn't map the system reset controller (SRC)\n");

	/*
	 * Invalidate SCU cache tags.  The 0x0000ffff constant invalidates all
	 * ways on all cores 0-3.  Per the ARM docs, it's harmless to write to
	 * the bits for cores that are not present.
	 */
	bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000ffff);

	/*
	 * Erratum ARM/MP: 764369 (problems with cache maintenance).
	 * Setting the "disable-migratory bit" in the undocumented SCU
	 * Diagnostic Control Register helps work around the problem.
	 */
	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL);
	bus_space_write_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL, 
	    val | SCU_DIAG_DISABLE_MIGBIT);

	/*
	 * Enable the SCU, then clean the cache on this core.  After these two
	 * operations the cache tag ram in the SCU is coherent with the contents
	 * of the cache on this core.  The other cores aren't running yet so
	 * their caches can't contain valid data yet, but we've initialized
	 * their SCU tag ram above, so they will be coherent from startup.
	 */
	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG);
	bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG, 
	    val | SCU_CONTROL_ENABLE);
	cpu_idcache_wbinv_all();

	/*
	 * For each AP core, set the entry point address and argument registers,
	 * and set the core-enable and core-reset bits in the control register.
	 */
	val = bus_space_read_4(fdtbus_bs_tag, src, SRC_CONTROL_REG);
	for (i=1; i < mp_ncpus; i++) {
		bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR0_C1FUNC + 8*i,
		    pmap_kextract((vm_offset_t)mpentry));
		bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR1_C1ARG  + 8*i, 0);

		val |= ((1 << (SRC_CONTROL_C1ENA_SHIFT - 1 + i )) |
		    ( 1 << (SRC_CONTROL_C1RST_SHIFT - 1 + i)));

	}
	bus_space_write_4(fdtbus_bs_tag, src, SRC_CONTROL_REG, val);

	armv7_sev();

	bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
	bus_space_unmap(fdtbus_bs_tag, src, SRC_SIZE);
}
Ejemplo n.º 18
0
/*
 * Attach the interface to the kernel data structures.  By the time this is
 * called, we know that the card exists at the given I/O address.  We still
 * assume that the IRQ given is correct.
 */
void
elattach(device_t parent, device_t self, void *aux)
{
	struct el_softc *sc = device_private(self);
	struct isa_attach_args *ia = aux;
	bus_space_tag_t iot = ia->ia_iot;
	bus_space_handle_t ioh;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	u_int8_t myaddr[ETHER_ADDR_LEN];
	u_int8_t i;

	sc->sc_dev = self;

	printf("\n");

	DPRINTF(("Attaching %s...\n", device_xname(sc->sc_dev)));

	/* Map i/o space. */
	if (bus_space_map(iot, ia->ia_io[0].ir_addr, 16, 0, &ioh)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	sc->sc_iot = iot;
	sc->sc_ioh = ioh;

	/* Reset the board. */
	bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
	delay(5);
	bus_space_write_1(iot, ioh, EL_AC, 0);

	/* Now read the address. */
	for (i = 0; i < ETHER_ADDR_LEN; i++) {
		bus_space_write_1(iot, ioh, EL_GPBL, i);
		myaddr[i] = bus_space_read_1(iot, ioh, EL_EAW);
	}

	/* Stop the board. */
	elstop(sc);

	/* Initialize ifnet structure. */
	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_start = elstart;
	ifp->if_ioctl = elioctl;
	ifp->if_watchdog = elwatchdog;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
	IFQ_SET_READY(&ifp->if_snd);

	/* Now we can attach the interface. */
	DPRINTF(("Attaching interface...\n"));
	if_attach(ifp);
	ether_ifattach(ifp, myaddr);

	/* Print out some information for the user. */
	printf("%s: address %s\n", device_xname(self), ether_sprintf(myaddr));

	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
	    IST_EDGE, IPL_NET, elintr, sc);

	DPRINTF(("Attaching to random...\n"));
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_NET, RND_FLAG_DEFAULT);

	DPRINTF(("elattach() finished.\n"));
}
Ejemplo n.º 19
0
void
imxpcibr_attach(struct device *parent, struct device *self, void *args)
{
	struct armv7_attach_args *aa = args;
	struct imxpcibr_softc *sc = (struct imxpcibr_softc *) self;
	struct pcibus_attach_args pba;

	sc->sc_iot = aa->aa_iot;
	sc->sc_dma_tag = aa->aa_dmat;
	if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
	    aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
		panic("imxpcibr_attach: bus_space_map failed!");

	printf("\n");

	return;

	imxiomuxc_enable_pcie();
	imxiomuxc_pcie_test_powerdown(0);
	clk_enable(clk_get("pcie_axi"));
	clk_enable(clk_get("pcie_ref_125m"));
	imxiomuxc_pcie_test_powerdown(1);

	HSET4(sc, PCIE_RC_COMMAND, PCIE_RC_COMMAND_IO_SPACE |
	    PCIE_RC_COMMAND_MEMORY_SPACE | PCIE_RC_COMMAND_BUS_MASTER);

	HSET4(sc, PCIE_RC_REVID, PCI_CLASS_BRIDGE_PCI << 16);

	snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name),
	    "%s pciio", sc->sc_dev.dv_xname);
	sc->sc_ioex = extent_create(sc->sc_ioex_name, 0x00000000, 0xffffffff,
	    M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED);
	snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name),
	    "%s pcimem", sc->sc_dev.dv_xname);
	sc->sc_memex = extent_create(sc->sc_memex_name, 0x00000000, 0xffffffff,
	    M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED);

	sc->sc_pc.pc_conf_v = sc;
	sc->sc_pc.pc_attach_hook = imxpcibr_attach_hook;
	sc->sc_pc.pc_bus_maxdevs = imxpcibr_bus_maxdevs;
	sc->sc_pc.pc_make_tag = imxpcibr_make_tag;
	sc->sc_pc.pc_decompose_tag = imxpcibr_decompose_tag;
	sc->sc_pc.pc_conf_size = imxpcibr_conf_size;
	sc->sc_pc.pc_conf_read = imxpcibr_conf_read;
	sc->sc_pc.pc_conf_write = imxpcibr_conf_write;

	sc->sc_pc.pc_intr_v = sc;
	sc->sc_pc.pc_intr_map = imxpcibr_intr_map;
	sc->sc_pc.pc_intr_string = imxpcibr_intr_string;
	sc->sc_pc.pc_intr_establish = imxpcibr_intr_establish;
	sc->sc_pc.pc_intr_disestablish = imxpcibr_intr_disestablish;

	bzero(&pba, sizeof(pba));
	pba.pba_dmat = sc->sc_dma_tag;

	pba.pba_busname = "pci";
	pba.pba_iot = sc->sc_iot;
	pba.pba_memt = sc->sc_iot;
	pba.pba_ioex = sc->sc_ioex;
	pba.pba_memex = sc->sc_memex;
	pba.pba_pc = &sc->sc_pc;
	pba.pba_domain = pci_ndomains++;
	pba.pba_bus = 0;

	imxpcibr_sc = sc;

	config_found(self, &pba, NULL);
}
Ejemplo n.º 20
0
int
sti_sgc_probe(struct device *parent, struct cfdata *cf, void *aux)
{
	struct confargs *ca = aux;
	bus_space_handle_t romh;
	paddr_t rom;
	u_int32_t id, romend;
	u_char devtype;
	int rv = 0, romunmapped = 0;

	if (ca->ca_type.iodc_type != HPPA_TYPE_FIO)
		return (0);

	/* these need futher checking for the graphics id */
	if (ca->ca_type.iodc_sv_model != HPPA_FIO_GSGC &&
	    ca->ca_type.iodc_sv_model != HPPA_FIO_SGC)
		return 0;

	rom = sti_sgc_getrom(ca);
#ifdef STIDEBUG
	printf ("sti: hpa=%x, rom=%x\n", (uint)ca->ca_hpa, (uint)rom);
#endif

	/* if it does not map, probably part of the lasi space */
	if ((rv = bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &romh))) {
#ifdef STIDEBUG
		printf ("sti: cannot map rom space (%d)\n", rv);
#endif
		if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) {
			romh = rom;
			romunmapped++;
		} else {
			/* in this case nobody has no freaking idea */
			return 0;
		}
	}

	devtype = bus_space_read_1(ca->ca_iot, romh, 3);

#ifdef STIDEBUG
	printf("sti: devtype=%d\n", devtype);
#endif
	rv = 1;
	switch (devtype) {
	case STI_DEVTYPE4:
		id = bus_space_read_4(ca->ca_iot, romh, STI_DEV4_DD_GRID);
		romend = bus_space_read_4(ca->ca_iot, romh, STI_DEV4_DD_ROMEND);
		break;
	case STI_DEVTYPE1:
		id = (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID
		    +  3) << 24) |
		    (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID
		    +  7) << 16) |
		    (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID
		    + 11) <<  8) |
		    (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID
		    + 15));
		romend = (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND 
		    +  3) << 24) |
		    (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND 
		    +  7) << 16) |
		    (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND 
		    + 11) <<  8) |
		    (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND 
		    + 15));
		break;
	default:
#ifdef STIDEBUG
		printf("sti: unknown type (%x)\n", devtype);
#endif
		rv = 0;
		romend = 0;
	}

	if (rv &&
	    ca->ca_type.iodc_sv_model == HPPA_FIO_SGC && id == STI_ID_FDDI) {
#ifdef STIDEBUG
		printf("sti: not a graphics device\n");
#endif
		rv = 0;
	}

	if (ca->ca_naddrs >= sizeof(ca->ca_addrs) / sizeof(ca->ca_addrs[0])) {
		printf("sti: address list overflow\n");
		return (0);
	}

	ca->ca_addrs[ca->ca_naddrs].addr = rom;
	ca->ca_addrs[ca->ca_naddrs].size = round_page(romend);
	ca->ca_naddrs++;

	if (!romunmapped)
		bus_space_unmap(ca->ca_iot, romh, STI_ROMSIZE);
	return (rv);
}
Ejemplo n.º 21
0
void
aupciattach(struct device *parent, struct device *self, void *aux)
{
	struct aupci_softc		*sc = (struct aupci_softc *)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_bust = aa->aa_st;
	if (bus_space_map(sc->sc_bust, aa->aa_addrs[0], 512, 0,
		&sc->sc_bush) != 0) {
		printf("\n%s: unable to map PCI registers\n",
		    sc->sc_dev.dv_xname);
		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);

	printf(": Alchemy Host-PCI Bridge");
	if (cfg & PCI_STATUS_66MHZ_SUPPORT)
		printf(", 66MHz");
	else
		printf(", 33MHz");

	printf("\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,
	    M_DEVBUF, NULL, 0, EX_WAITOK);

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

	pci_configure_bus(&sc->sc_pc,
	    io_ex, mem_ex, NULL, 0, mips_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_ENABLED | PCI_FLAGS_MEM_ENABLED;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;

	config_found_ia(self, "pcibus", &pba, pcibusprint);
#endif	/* NPCI > 0 */
}
Ejemplo n.º 22
0
static void
atppc_acpi_attach(device_t parent, device_t self, void *aux)
{
	struct atppc_softc *sc = device_private(self);
	struct atppc_acpi_softc *asc = device_private(self);
	struct acpi_attach_args *aa = aux;
	struct acpi_resources res;
	struct acpi_io *io;
	struct acpi_irq *irq;
	struct acpi_drq *drq;
	ACPI_STATUS rv;
	int nirq;

	sc->sc_dev_ok = ATPPC_NOATTACH;

	sc->sc_dev = self;

	/* parse resources */
	rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS",
				 &res, &acpi_resource_parse_ops_default);
	if (ACPI_FAILURE(rv))
		return;

	/* find our i/o registers */
	io = acpi_res_io(&res, 0);
	if (io == NULL) {
		aprint_error_dev(sc->sc_dev, "unable to find i/o register resource\n");
		goto out;
	}

	/* find our IRQ */
	irq = acpi_res_irq(&res, 0);
	if (irq == NULL) {
		aprint_error_dev(sc->sc_dev, "unable to find irq resource\n");
		goto out;
	}
	nirq = irq->ar_irq;

	/* find our DRQ */
	drq = acpi_res_drq(&res, 0);
	if (drq == NULL) {
		aprint_error_dev(sc->sc_dev, "unable to find drq resource\n");
		goto out;
	}
	asc->sc_drq = drq->ar_drq;

	/* Attach */
	sc->sc_iot = aa->aa_iot;
	sc->sc_has = 0;
	asc->sc_ic = aa->aa_ic;

	sc->sc_dev_ok = ATPPC_ATTACHED;

	if (bus_space_map(sc->sc_iot, io->ar_base, io->ar_length, 0,
		&sc->sc_ioh) != 0) {
		aprint_error_dev(self, "attempt to map bus space failed, device not "
			"properly attached.\n");
		goto out;
	}

	sc->sc_ieh = isa_intr_establish(aa->aa_ic, nirq,
	    (irq->ar_type == ACPI_EDGE_SENSITIVE) ? IST_EDGE : IST_LEVEL,
	    IPL_TTY, atppcintr, sc->sc_dev);

	/* setup DMA hooks */
	if (atppc_isadma_setup(sc, asc->sc_ic, asc->sc_drq) == 0) {
		sc->sc_has |= ATPPC_HAS_DMA;
		sc->sc_dma_start = atppc_acpi_dma_start;
		sc->sc_dma_finish = atppc_acpi_dma_finish;
		sc->sc_dma_abort = atppc_acpi_dma_abort;
		sc->sc_dma_malloc = atppc_acpi_dma_malloc;
		sc->sc_dma_free = atppc_acpi_dma_free;
	}

	sc->sc_has |= ATPPC_HAS_INTR;

	/* Run soft configuration attach */
	atppc_sc_attach(sc);
 out:
	acpi_resource_cleanup(&res);
}
Ejemplo n.º 23
0
static void
itesio_isa_attach(device_t parent, device_t self, void *aux)
{
	struct itesio_softc *sc = device_private(self);
	struct isa_attach_args *ia = aux;
	int i;
	uint8_t cr;

	sc->sc_iot = ia->ia_iot;

	if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 2, 0,
			  &sc->sc_ioh)) {
		aprint_error(": can't map i/o space\n");
		return;
	}

	aprint_naive("\n");

	/*
	 * Enter to the Super I/O MB PNP mode.
	 */
	itesio_enter(sc->sc_iot, sc->sc_ioh);
	/*
	 * Get info from the Super I/O Global Configuration Registers:
	 * Chip IDs and Device Revision.
	 */
	sc->sc_chipid = (itesio_readreg(sc->sc_iot, sc->sc_ioh,
	    ITESIO_CHIPID1) << 8);
	sc->sc_chipid |= itesio_readreg(sc->sc_iot, sc->sc_ioh,
	    ITESIO_CHIPID2);
	sc->sc_devrev = (itesio_readreg(sc->sc_iot, sc->sc_ioh,
	    ITESIO_DEVREV) & 0x0f);
	/*
	 * Select the EC LDN to get the Base Address.
	 */
	itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_LDNSEL, ITESIO_EC_LDN);
	sc->sc_hwmon_baseaddr =
	    (itesio_readreg(sc->sc_iot, sc->sc_ioh, ITESIO_EC_MSB) << 8);
	sc->sc_hwmon_baseaddr |= itesio_readreg(sc->sc_iot, sc->sc_ioh,
	    ITESIO_EC_LSB);
	/*
	 * We are done, exit MB PNP mode.
	 */
	itesio_exit(sc->sc_iot, sc->sc_ioh);

	aprint_normal(": iTE IT%4xF Super I/O (rev %d)\n",
	    sc->sc_chipid, sc->sc_devrev);
	aprint_normal_dev(self, "Hardware Monitor registers at 0x%x\n",
	    sc->sc_hwmon_baseaddr);

	if (bus_space_map(sc->sc_ec_iot, sc->sc_hwmon_baseaddr, 8, 0,
	    &sc->sc_ec_ioh)) {
		aprint_error_dev(self, "cannot map hwmon i/o space\n");
		goto out2;
	}

	sc->sc_hwmon_mapped = true;

	/* Activate monitoring */
	cr = itesio_ecreadreg(sc, ITESIO_EC_CONFIG);
	SET(cr, 0x01);
	itesio_ecwritereg(sc, ITESIO_EC_CONFIG, cr);

#ifdef notyet
	/* Enable beep alarms */
	cr = itesio_ecreadreg(sc, ITESIO_EC_BEEPEER);
	SET(cr, 0x02);	/* Voltage exceeds limit */
	SET(cr, 0x04);	/* Temperature exceeds limit */
	itesio_ecwritereg(sc, ITESIO_EC_BEEPEER, cr);
#endif

	/*
	 * Initialize and attach sensors.
	 */
	itesio_setup_sensors(sc);
	sc->sc_sme = sysmon_envsys_create();
	for (i = 0; i < IT_NUM_SENSORS; i++) {
		if (sysmon_envsys_sensor_attach(sc->sc_sme,
						&sc->sc_sensor[i])) {
			sysmon_envsys_destroy(sc->sc_sme);
			goto out;
		}
	}
	/*
	 * Hook into the system monitor.
	 */
	sc->sc_sme->sme_name = device_xname(self);
	sc->sc_sme->sme_cookie = sc;
	sc->sc_sme->sme_refresh = itesio_refresh;
	
	if ((i = sysmon_envsys_register(sc->sc_sme))) {
		aprint_error_dev(self,
		    "unable to register with sysmon (%d)\n", i);
		sysmon_envsys_destroy(sc->sc_sme);
		goto out;
	}
	sc->sc_hwmon_enabled = true;

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

	/* The IT8705 doesn't support the WDT */
	if (sc->sc_chipid == ITESIO_ID8705)
		goto out2;

	/*
	 * Initialize the watchdog timer.
	 */
	sc->sc_smw.smw_name = device_xname(self);
	sc->sc_smw.smw_cookie = sc;
	sc->sc_smw.smw_setmode = itesio_wdt_setmode;
	sc->sc_smw.smw_tickle = itesio_wdt_tickle;
	sc->sc_smw.smw_period = 60;

	if (sysmon_wdog_register(&sc->sc_smw)) {
		aprint_error_dev(self, "unable to register watchdog timer\n");
		goto out2;
	}
	sc->sc_wdt_enabled = true;
	aprint_normal_dev(self, "Watchdog Timer present\n");
	return;

out:
	bus_space_unmap(sc->sc_ec_iot, sc->sc_ec_ioh, 8);
out2:
	bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2);
}
Ejemplo n.º 24
0
static void
obioohci_attach(struct device *parent, struct device *self, void *aux)
{
	struct obioohci_softc *sc = (struct obioohci_softc *)self;
	struct obio_attach_args *obio = aux;
	usbd_status r;

	sc->sc.sc_size = 0;
	sc->sc_ih = NULL;
	sc->sc.sc_bus.dmatag = 0;

	/* Map I/O space */
	if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0,
	    &sc->sc.ioh)) {
		aprint_error(": couldn't map memory space\n");
		return;
	}
	sc->sc.iot = obio->obio_iot;
	sc->sc_addr = obio->obio_addr;
	sc->sc.sc_size = obio->obio_size;
	sc->sc.sc_bus.dmatag = obio->obio_dmac;

	/* XXX copied from ohci_pci.c. needed? */
	bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);

	/* start the usb clock */
#ifdef NOTYET
	pxa2x0_clkman_config(CKEN_USBHC, 1);
#endif
	obioohci_enable(sc);

	/* Disable interrupts, so we don't get any spurious ones. */
	bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
	    OHCI_MIE);

#ifdef NOTYET
	sc->sc_ih = obio_intr_establish(obio->obio_intr, IPL_USB,
		sc->sc.sc_bus.bdev.dv_xname, ohci_intr, &sc->sc);
	if (sc->sc_ih == NULL) {
		aprint_error(": unable to establish interrupt\n");
		goto free_map;
	}
#else
	sc->sc_ih = obioohci_fake_intr_establish(ohci_intr, &sc->sc);
#endif

	strlcpy(sc->sc.sc_vendor, "OMAP2", sizeof(sc->sc.sc_vendor));
	r = ohci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		aprint_error("%s: init failed, error=%d\n",
		    sc->sc.sc_bus.bdev.dv_xname, r);
		goto free_intr;
	}

	sc->sc.sc_powerhook = powerhook_establish(sc->sc.sc_bus.bdev.dv_xname,
	    obioohci_power, sc);
	if (sc->sc.sc_powerhook == NULL) {
		aprint_error("%s: cannot establish powerhook\n",
		    sc->sc.sc_bus.bdev.dv_xname);
	}

	sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus, usbctlprint);

	return;

free_intr:
#ifdef NOTYET
	obio_gpio_intr_disestablish(sc->sc_ih);
#endif
	sc->sc_ih = NULL;
#ifdef NOTYET
free_map:
#endif
	obioohci_disable(sc);
#ifdef NOTYET
	pxa2x0_clkman_config(CKEN_USBHC, 0);
#endif
	bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
	sc->sc.sc_size = 0;
}
Ejemplo n.º 25
0
void
j720sspattach(struct device *parent, struct device *self, void *aux)
{
	struct j720ssp_softc *sc = (void *)self;
	struct sa11x0_softc *psc = (void *)parent;
	struct sa11x0_attach_args *sa = aux;
	struct wskbddev_attach_args a;

	printf("\n");

	sc->sc_iot = psc->sc_iot;
	sc->sc_gpioh = psc->sc_gpioh;
	if (bus_space_map(sc->sc_iot, sa->sa_addr, sa->sa_size, 0,
			  &sc->sc_ssph)) {
		printf("%s: unable to map SSP registers\n",
		       sc->sc_dev.dv_xname);
		return;
	}

	sc->sc_si = softintr_establish(IPL_SOFTCLOCK, j720kbdsoft, sc);

	sc->sc_enabled = 0;

	a.console = 0;

	a.keymap = &j720kbd_keymapdata;

	a.accessops = &j720kbd_accessops;
	a.accesscookie = sc;

	/* Do console initialization */
	if (! (bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) {
		j720kbdcons_sc = *sc;
		a.console = 1;

		wskbd_cnattach(&j720kbd_consops, NULL, &j720kbd_keymapdata);
		j720kbdcons_initstate = 1;
	}

	/*
	 * Attach the wskbd, saving a handle to it.
	 * XXX XXX XXX
	 */
	sc->sc_wskbddev = config_found(self, &a, wskbddevprint);

#ifdef DEBUG
	/* Zero the stat counters */
	j720sspwaitcnt = 0;
	j720sspwaittime = 0;
#endif

	if (j720kbdcons_initstate == 1)
		j720kbd_enable(sc, 1);

	/* LCD control is on the same bus */
	config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS,
		    CONFIG_HOOK_SHARE, j720lcdparam, sc);
	config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS,
		    CONFIG_HOOK_SHARE, j720lcdparam, sc);
	config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS_MAX,
		    CONFIG_HOOK_SHARE, j720lcdparam, sc);

	config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST,
		    CONFIG_HOOK_SHARE, j720lcdparam, sc);
	config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST,
		    CONFIG_HOOK_SHARE, j720lcdparam, sc);
	config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST_MAX,
		    CONFIG_HOOK_SHARE, j720lcdparam, sc);
}
Ejemplo n.º 26
0
static void
sdhc_attach(device_t parent, device_t self, void *aux)
{
	struct sdhc_axi_softc *sc = device_private(self);
	struct axi_attach_args *aa = aux;
	bus_space_tag_t iot = aa->aa_iot;
	bus_space_handle_t ioh;
	u_int perclk = 0, v;

	sc->sc_sdhc.sc_dev = self;

	sc->sc_sdhc.sc_dmat = aa->aa_dmat;

	if (bus_space_map(iot, aa->aa_addr, AIPS2_USDHC_SIZE, 0, &ioh)) {
		aprint_error_dev(self, "can't map\n");
		return;
	}

	aprint_normal(": Ultra Secured Digial Host Controller\n");
	aprint_naive("\n");
	sc->sc_sdhc.sc_host = sc->sc_hosts;

	switch (aa->aa_addr) {
	case IMX6_AIPS2_BASE + AIPS2_USDHC1_BASE:
		v = imx6_ccm_read(CCM_CCGR6);
		imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC1_CLK_ENABLE(3));
		perclk = imx6_get_clock(IMX6CLK_USDHC1_CLK_ROOT);
		break;
	case IMX6_AIPS2_BASE + AIPS2_USDHC2_BASE:
		v = imx6_ccm_read(CCM_CCGR6);
		imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC2_CLK_ENABLE(3));
		perclk = imx6_get_clock(IMX6CLK_USDHC2_CLK_ROOT);
		break;
	case IMX6_AIPS2_BASE + AIPS2_USDHC3_BASE:
		v = imx6_ccm_read(CCM_CCGR6);
		imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC3_CLK_ENABLE(3));
		perclk = imx6_get_clock(IMX6CLK_USDHC3_CLK_ROOT);
		break;
	case IMX6_AIPS2_BASE + AIPS2_USDHC4_BASE:
		v = imx6_ccm_read(CCM_CCGR6);
		imx6_ccm_write(CCM_CCGR6, v | CCM_CCGR6_USDHC4_CLK_ENABLE(3));
		perclk = imx6_get_clock(IMX6CLK_USDHC4_CLK_ROOT);
		break;
	}

	sc->sc_sdhc.sc_clkbase = perclk / 1000;
	sc->sc_sdhc.sc_flags |=
	    SDHC_FLAG_USDHC |
	    SDHC_FLAG_NO_PWR0 |
	    SDHC_FLAG_HAVE_DVS |
	    SDHC_FLAG_32BIT_ACCESS |
	    SDHC_FLAG_ENHANCED;

	sc->sc_ih = intr_establish(aa->aa_irq, IPL_SDMMC, IST_LEVEL,
	    sdhc_intr, &sc->sc_sdhc);

	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "can't establish interrupt\n");
		return;
	}

	if (sdhc_host_found(&sc->sc_sdhc, iot, ioh, AIPS2_USDHC_SIZE)) {
		aprint_error_dev(self, "can't initialize host\n");
		return;
	}

	if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume,
		sdhc_shutdown)) {
		aprint_error_dev(self,
		    "can't establish power hook\n");
	}
}
Ejemplo n.º 27
0
int
nouveau_fifo_channel_create_(struct nouveau_object *parent,
			     struct nouveau_object *engine,
			     struct nouveau_oclass *oclass,
			     int bar, u32 addr, u32 size, u32 pushbuf,
			     u64 engmask, int len, void **ptr)
{
	struct nouveau_device *device = nv_device(engine);
	struct nouveau_fifo *priv = (void *)engine;
	struct nouveau_fifo_chan *chan;
	struct nouveau_dmaeng *dmaeng;
	unsigned long flags;
	int ret;

	/* create base object class */
	ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
				     engmask, len, ptr);
	chan = *ptr;
	if (ret)
		return ret;

	/* validate dma object representing push buffer */
	chan->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
	if (!chan->pushdma)
		return -ENOENT;

	dmaeng = (void *)chan->pushdma->base.engine;
	switch (chan->pushdma->base.oclass->handle) {
	case NV_DMA_FROM_MEMORY_CLASS:
	case NV_DMA_IN_MEMORY_CLASS:
		break;
	default:
		return -EINVAL;
	}

	ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu);
	if (ret)
		return ret;

	/* find a free fifo channel */
	spin_lock_irqsave(&priv->lock, flags);
	for (chan->chid = priv->min; chan->chid < priv->max; chan->chid++) {
		if (!priv->channel[chan->chid]) {
			priv->channel[chan->chid] = nv_object(chan);
			break;
		}
	}
	spin_unlock_irqrestore(&priv->lock, flags);

	if (chan->chid == priv->max) {
		nv_error(priv, "no free channels\n");
		return -ENOSPC;
	}

	/* map fifo control registers */
#ifdef __NetBSD__
	if (bar == 0) {
		/*
		 * We already map BAR 0 in the engine device base, so
		 * grab a subregion of that.
		 */
		bus_space_tag_t mmiot = nv_subdev(device)->mmiot;
		bus_space_handle_t mmioh = nv_subdev(device)->mmioh;
		bus_size_t mmiosz = nv_subdev(device)->mmiosz;

		/* Check whether it lies inside the region.  */
		if (mmiosz < addr ||
		    mmiosz - addr < chan->chid*size ||
		    mmiosz - addr - chan->chid*size < size) {
			ret = EIO;
			nv_error(priv, "fifo channel out of range:"
			    " addr 0x%"PRIxMAX
			    " chid 0x%"PRIxMAX" size 0x%"PRIxMAX
			    " mmiosz 0x%"PRIxMAX"\n",
			    (uintmax_t)addr,
			    (uintmax_t)chan->chid, (uintmax_t)size,
			    (uintmax_t)mmiosz);
			return ret;
		}

		/* Grab a subregion.  */
		/* XXX errno NetBSD->Linux */
		ret = -bus_space_subregion(mmiot, mmioh,
		    (addr + chan->chid*size), size, &chan->bsh);
		if (ret) {
			nv_error(priv, "bus_space_subregion failed: %d\n",
			    ret);
			return ret;
		}

		/* Success!  No need to unmap a subregion.  */
		chan->mapped = false;
		chan->bst = mmiot;
	} else {
		chan->bst = nv_device_resource_tag(device, bar);
		/* XXX errno NetBSD->Linux */
		ret = -bus_space_map(chan->bst,
		    (nv_device_resource_start(device, bar) +
			addr + (chan->chid * size)),
		    size, 0, &chan->bsh);
		if (ret) {
			nv_error(priv, "failed to map fifo channel:"
			    " bar %d addr %"PRIxMAX" + %"PRIxMAX
			    " + (%"PRIxMAX" * %"PRIxMAX") = %"PRIxMAX
			    " size %"PRIxMAX": %d\n",
			    bar,
			    (uintmax_t)nv_device_resource_start(device, bar),
			    (uintmax_t)addr,
			    (uintmax_t)chan->chid,
			    (uintmax_t)size,
			    (uintmax_t)(nv_device_resource_start(device, bar) +
				addr + (chan->chid * size)),
			    (uintmax_t)size,
			    ret);
			return ret;
		}
		chan->mapped = true;
	}
#else
	chan->user = ioremap(nv_device_resource_start(device, bar) + addr +
			     (chan->chid * size), size);
	if (!chan->user)
		return -EFAULT;
#endif

	nouveau_event_trigger(priv->cevent, 0);

	chan->size = size;
	return 0;
}
Ejemplo n.º 28
0
Archivo: amdpm.c Proyecto: MarginC/kame
void
amdpm_attach(struct device *parent, struct device *self, void *aux)
{
	struct amdpm_softc *sc = (struct amdpm_softc *) self;
	struct pci_attach_args *pa = aux;
	struct timeval tv1, tv2;
	pcireg_t reg;
	int i;

	sc->sc_pc = pa->pa_pc;
	sc->sc_tag = pa->pa_tag;
	sc->sc_iot = pa->pa_iot;

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_CONFREG);
	if ((reg & AMDPM_PMIOEN) == 0) {
		printf(": PMxx space isn't enabled\n");
		return;
	}
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_PMPTR);
	if (bus_space_map(sc->sc_iot, AMDPM_PMBASE(reg), AMDPM_PMSIZE,
	    0, &sc->sc_ioh)) {
		printf(": failed to map PMxx space\n");
		return;
	}

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_CONFREG);
	if (reg & AMDPM_RNGEN) {
		/* Check to see if we can read data from the RNG. */
		(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh,
		    AMDPM_RNGDATA);
		/* benchmark the RNG */
		microtime(&tv1);
		for (i = 2 * 1024; i--; ) {
			while(!(bus_space_read_1(sc->sc_iot, sc->sc_ioh,
			    AMDPM_RNGSTAT) & AMDPM_RNGDONE))
				;
			(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh,
			    AMDPM_RNGDATA);
		}
		microtime(&tv2);

		timersub(&tv2, &tv1, &tv1);
		if (tv1.tv_sec)
			tv1.tv_usec += 1000000 * tv1.tv_sec;
		printf(": rng active, %dKb/sec", 8 * 1000000 / tv1.tv_usec);

#ifdef AMDPM_RND_COUNTERS
			evcnt_attach_dynamic(&sc->sc_rnd_hits, EVCNT_TYPE_MISC,
			    NULL, sc->sc_dev.dv_xname, "rnd hits");
			evcnt_attach_dynamic(&sc->sc_rnd_miss, EVCNT_TYPE_MISC,
			    NULL, sc->sc_dev.dv_xname, "rnd miss");
			for (i = 0; i < 256; i++) {
				evcnt_attach_dynamic(&sc->sc_rnd_data[i],
				    EVCNT_TYPE_MISC, NULL, sc->sc_dev.dv_xname,
				    "rnd data");
			}
#endif
		timeout_set(&sc->sc_rnd_ch, amdpm_rnd_callout, sc);
		amdpm_rnd_callout(sc);
	}
}
static void
omapl1xohci_attach (struct device *parent, struct device *self, void *aux)
{
	struct omapl1xohci_softc *sc = device_private(self);
	struct tipb_attach_args *tipb = aux;
	usbd_status r;

	/* Map OHCI registers */
	if (bus_space_map(tipb->tipb_iot, tipb->tipb_addr, tipb->tipb_size, 0,
			  &sc->sc.ioh)) {
		aprint_error_dev(self, "can't map ohci mem space\n");
		return;
	}

	/* Enable the usb lpsc modules */
	if (omapl1x_lpsc_enable(PSC1_USB20_MODULE) != 0) {
		aprint_error_dev(self, "can't enable usb2.0 module\n");
		return;
	}

	if (omapl1x_lpsc_enable(PSC1_USB11_MODULE) != 0) {
		aprint_error_dev(self, "can't enable usb1.1 module\n");
		return;
	}

	syscfg0.syscfg_iot = tipb->tipb_iot;
	syscfg0.syscfg_addr = OMAPL1X_SYSCFG0_ADDR;
	syscfg0.syscfg_size = OMAPL1X_SYSCFG0_SIZE;

	/* Map syscfg registers. We want to use it for configuring cfgchip2 */
	if (bus_space_map(syscfg0.syscfg_iot, syscfg0.syscfg_addr,
			  syscfg0.syscfg_size, 0, &syscfg0.syscfg_ioh)) {
		aprint_error_dev(self, "can't map syscfg0 mem space\n");
		return;
	}

	sc->sc.sc_dev = self;
	sc->sc.sc_bus.hci_private = sc;
	sc->sc_intr = tipb->tipb_intr;
	sc->sc.iot = tipb->tipb_iot;
	sc->sc.sc_addr = tipb->tipb_addr;
	sc->sc.sc_size = tipb->tipb_size;
	sc->sc.sc_bus.dmatag = tipb->tipb_dmac;

	/* Disable interrupts, so we don't get any spurious ones. */
	bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
			  OHCI_ALL_INTRS);

	/* provide clock to USB block */
	if (!omapl1x_usbclk_enable(&syscfg0)) {
		aprint_error_dev(self, "phy init failed\n");
		return;
	}

	/* establish the interrupt. */
	sc->sc_ih = intr_establish(sc->sc_intr, IPL_USB, IST_LEVEL_HIGH,
				   ohci_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt\n");
		return;
	}

	strlcpy(sc->sc.sc_vendor, "OMAPL1X", sizeof sc->sc.sc_vendor);
	
	r = ohci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		aprint_error_dev(self, "init failed, error=%d\n", r);
		return;
	}

	/* Attach usb device. */
	sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);

	/* Done accessing the syscfg0 registers */
	bus_space_unmap(syscfg0.syscfg_iot, syscfg0.syscfg_ioh,
			syscfg0.syscfg_size);
}
Ejemplo n.º 30
0
void
sbbc_attach(struct device *parent, struct device *self, void *aux)
{
	struct sbbc_softc *sc = (void *)self;
	struct pci_attach_args *pa = aux;
	struct sbbc_sram_toc *toc;
	bus_addr_t base;
	bus_size_t size;
	pci_intr_handle_t ih;
	int chosen, iosram;
	int i;

	/* XXX Don't byteswap. */
	sc->sc_bbt = *pa->pa_memt;
	sc->sc_bbt.sasi = ASI_PRIMARY;
	sc->sc_iot = &sc->sc_bbt;

	if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, SBBC_PCI_BAR,
	    PCI_MAPREG_TYPE_MEM, &base, &size, NULL)) {
		printf(": can't find register space\n");
		return;
	}

	if (bus_space_map(sc->sc_iot, base + SBBC_REGS_OFFSET,
	    SBBC_REGS_SIZE, 0, &sc->sc_regs_ioh)) {
		printf(": can't map register space\n");
		return;
	}

	if (bus_space_map(sc->sc_iot, base + SBBC_EPLD_OFFSET,
	    SBBC_EPLD_SIZE, 0, &sc->sc_epld_ioh)) {
		printf(": can't map EPLD registers\n");
		goto unmap_regs;
	}

	if (bus_space_map(sc->sc_iot, base + SBBC_SRAM_OFFSET,
	    SBBC_SRAM_SIZE, 0, &sc->sc_sram_ioh)) {
		printf(": can't map SRAM\n");
		goto unmap_epld;
	}

	if (pci_intr_map(pa, &ih)) {
		printf(": unable to map interrupt\n");
		goto unmap_sram;
	}
	printf(": %s\n", pci_intr_string(pa->pa_pc, ih));

	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY,
	    sbbc_intr, sc, sc->sc_dv.dv_xname);
	if (sc->sc_ih == NULL) {
		printf("%s: unable to establish interrupt\n", sc->sc_dv.dv_xname);
		goto unmap_sram;
	}

	bus_space_write_4(sc->sc_iot, sc->sc_regs_ioh,
	    SBBC_PCI_INT_ENABLE, SBBC_PCI_ENABLE_INT_A);

	/* Check if we are the chosen one. */
	chosen = OF_finddevice("/chosen");
	if (OF_getprop(chosen, "iosram", &iosram, sizeof(iosram)) <= 0 ||
	    PCITAG_NODE(pa->pa_tag) != iosram)
		return;

	/* SRAM TOC offset defaults to 0. */
	if (OF_getprop(chosen, "iosram-toc", &sc->sc_sram_toc,
	    sizeof(sc->sc_sram_toc)) <= 0)
		sc->sc_sram_toc = 0;

	sc->sc_sram = bus_space_vaddr(sc->sc_iot, sc->sc_sram_ioh);
	toc = (struct sbbc_sram_toc *)(sc->sc_sram + sc->sc_sram_toc);

	for (i = 0; i < toc->toc_ntags; i++) {
		if (strcmp(toc->toc_tag[i].tag_key, "SOLSCIE") == 0)
			sc->sc_sram_solscie = (uint32_t *)
			    (sc->sc_sram + toc->toc_tag[i].tag_offset);
		if (strcmp(toc->toc_tag[i].tag_key, "SOLSCIR") == 0)
			sc->sc_sram_solscir = (uint32_t *)
			    (sc->sc_sram + toc->toc_tag[i].tag_offset);
		if (strcmp(toc->toc_tag[i].tag_key, "SCSOLIE") == 0)
			sc->sc_sram_scsolie = (uint32_t *)
			    (sc->sc_sram + toc->toc_tag[i].tag_offset);
		if (strcmp(toc->toc_tag[i].tag_key, "SCSOLIR") == 0)
			sc->sc_sram_scsolir = (uint32_t *)
			    (sc->sc_sram + toc->toc_tag[i].tag_offset);
	}

	for (i = 0; i < toc->toc_ntags; i++) {
		if (strcmp(toc->toc_tag[i].tag_key, "TODDATA") == 0)
			sbbc_attach_tod(sc, toc->toc_tag[i].tag_offset);
		if (strcmp(toc->toc_tag[i].tag_key, "SOLCONS") == 0)
			sbbc_attach_cons(sc, toc->toc_tag[i].tag_offset);
	}

	return;

 unmap_sram:
	bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_SRAM_SIZE);
 unmap_epld:
	bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_EPLD_SIZE);
 unmap_regs:
	bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_REGS_SIZE);
}