Пример #1
0
/*
 * Restore memory controller's original configuration.
 */
static void
fipe_mc_restore(void)
{
	pci_config_put8(fipe_mc_ctrl.mc_pci_hdl, FIPE_MC_THRTCTRL,
	    fipe_mc_ctrl.mc_thrtctrl & ~FIPE_MC_THRTCTRL_HUNT);
	pci_config_put8(fipe_mc_ctrl.mc_pci_hdl, FIPE_MC_GBLACT,
	    fipe_mc_ctrl.mc_gblact);
	pci_config_put8(fipe_mc_ctrl.mc_pci_hdl, FIPE_MC_THRTLOW,
	    fipe_mc_ctrl.mc_thrtlow);
	pci_config_put8(fipe_mc_ctrl.mc_pci_hdl, FIPE_MC_THRTCTRL,
	    fipe_mc_ctrl.mc_thrtctrl);
}
Пример #2
0
static void
rge_chip_poke_cfg(rge_t *rgep, rge_peekpoke_t *ppd)
{
	uint64_t regval;
	uint64_t regno;

	RGE_TRACE(("rge_chip_poke_cfg($%p, $%p)",
	    (void *)rgep, (void *)ppd));

	regno = ppd->pp_acc_offset;
	regval = ppd->pp_acc_data;

	switch (ppd->pp_acc_size) {
	case 1:
		pci_config_put8(rgep->cfg_handle, regno, regval);
		break;

	case 2:
		pci_config_put16(rgep->cfg_handle, regno, regval);
		break;

	case 4:
		pci_config_put32(rgep->cfg_handle, regno, regval);
		break;

	case 8:
		pci_config_put64(rgep->cfg_handle, regno, regval);
		break;
	}
}
Пример #3
0
/*ARGSUSED*/
int
plat_ide_chipreset(dev_info_t *dip, int chno)
{
	uint8_t	val;
	int	ret = DDI_SUCCESS;

	if (isa_handle == NULL) {
		return (DDI_FAILURE);
	}

	val = pci_config_get8(isa_handle, 0x58);
	/*
	 * The dip passed as the argument is not used here.
	 * This will be needed for platforms which have multiple on-board SB,
	 * The dip passed will be used to match the corresponding ISA node.
	 */
	switch (chno) {
		case 0:
			/*
			 * First disable the primary channel then re-enable it.
			 * As per ALI no wait should be required in between have
			 * given 1ms delay in between to be on safer side.
			 * bit 2 of register 0x58 when 0 disable the channel 0.
			 * bit 2 of register 0x58 when 1 enables the channel 0.
			 */
			pci_config_put8(isa_handle, 0x58, val & 0xFB);
			drv_usecwait(1000);
			pci_config_put8(isa_handle, 0x58, val);
			break;
		case 1:
			/*
			 * bit 3 of register 0x58 when 0 disable the channel 1.
			 * bit 3 of register 0x58 when 1 enables the channel 1.
			 */
			pci_config_put8(isa_handle, 0x58, val & 0xF7);
			drv_usecwait(1000);
			pci_config_put8(isa_handle, 0x58, val);
			break;
		default:
			/*
			 * Unknown channel number passed. Return failure.
			 */
			ret = DDI_FAILURE;
	}

	return (ret);
}
Пример #4
0
/*
 * pcmu_init_child
 *
 * This function is called from our control ops routine on a
 * DDI_CTLOPS_INITCHILD request.  It builds and sets the device's
 * parent private data area.
 *
 * used by: pcmu_ctlops()
 *
 * return value: none
 */
int
pcmu_init_child(pcmu_t *pcmu_p, dev_info_t *child)
{
	char name[10];
	ddi_acc_handle_t config_handle;
	uint8_t bcr;
	uint8_t header_type;

	if (name_child(child, name, 10) != DDI_SUCCESS)
		return (DDI_FAILURE);
	ddi_set_name_addr(child, name);

	PCMU_DBG2(PCMU_DBG_PWR, ddi_get_parent(child),
	    "INITCHILD: config regs setup for %s@%s\n",
	    ddi_node_name(child), ddi_get_name_addr(child));

	/*
	 * Map the child configuration space to for initialization.
	 * We assume the obp will do the following in the devices
	 * config space:
	 *
	 *	Set the latency-timer register to values appropriate
	 *	for the devices on the bus (based on other devices
	 *	MIN_GNT and MAX_LAT registers.
	 *
	 *	Set the fast back-to-back enable bit in the command
	 *	register if it's supported and all devices on the bus
	 *	have the capability.
	 *
	 */
	if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) {
		ddi_set_name_addr(child, NULL);
		return (DDI_FAILURE);
	}

	/*
	 * Determine the configuration header type.
	 */
	header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
	PCMU_DBG2(PCMU_DBG_INIT_CLD, pcmu_p->pcmu_dip, "%s: header_type=%x\n",
	    ddi_driver_name(child), header_type);

	/*
	 * If the device has a bus control register then program it
	 * based on the settings in the command register.
	 */
	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
		bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL);
		if (pcmu_command_default & PCI_COMM_PARITY_DETECT)
			bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
		if (pcmu_command_default & PCI_COMM_SERR_ENABLE)
			bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
		bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
		pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr);
	}

	pci_config_teardown(&config_handle);
	return (DDI_SUCCESS);
}
Пример #5
0
/*ARGSUSED*/
void
pmubus_put8(ddi_acc_impl_t *hdlp, uint8_t *addr, uint8_t value)
{
	ddi_acc_hdl_t *hp = (ddi_acc_hdl_t *)hdlp;
	pmubus_mapreq_t *pmubus_mapreqp = hp->ah_bus_private;
	pmubus_devstate_t *softsp = pmubus_mapreqp->mapreq_softsp;
	off_t offset;
	uint8_t tmp;

	offset = pmubus_mapreqp->mapreq_addr + (uintptr_t)addr;
	offset &= PMUBUS_REGOFFSET;

	if ((pmubus_mapreqp->mapreq_flags) & MAPREQ_SHARED_BITS) {
		/*
		 * Process "bit lane" register
		 */
		DPRINTF(PMUBUS_RW_DEBUG, ("pmubus_put8: addr=%p offset=%lx "
		    "value=%x mask=%lx\n", (void *)addr, offset, value,
		    pmubus_mapreqp->mapreq_mask));

		if (addr != 0 ||
		    pmubus_mapreqp->mapreq_size != sizeof (value)) {
			cmn_err(CE_WARN, "pmubus_put8: store discarded, "
			    "incorrect access addr/size");
			return;
		}

		mutex_enter(&softsp->pmubus_reg_access_lock);
		tmp = pci_config_get8(softsp->pmubus_reghdl, offset);
		tmp &= ~pmubus_mapreqp->mapreq_mask;
		value &= pmubus_mapreqp->mapreq_mask;
		tmp |= value;
		pci_config_put8(softsp->pmubus_reghdl, offset, tmp);
		mutex_exit(&softsp->pmubus_reg_access_lock);
	} else {
		/*
		 * Process shared register
		 */
		DPRINTF(PMUBUS_RW_DEBUG, ("pmubus_put8: addr=%p offset=%lx "
		    "value=%x\n", (void *)addr, offset, value));
		pci_config_put8(softsp->pmubus_reghdl, offset, value);
	}

	/* Flush store buffers XXX Should let drivers do this. */
	tmp = pci_config_get8(softsp->pmubus_reghdl, offset);
}
Пример #6
0
/*
 * Configure memory controller into power saving mode:
 * 1) OLTT activation limit is set to unlimited
 * 2) MC works in S-CLTT mode
 */
static int
fipe_mc_change(int throttle)
{
	/* Enable OLTT/disable S-CLTT mode */
	pci_config_put8(fipe_mc_ctrl.mc_pci_hdl, FIPE_MC_THRTCTRL,
	    fipe_mc_ctrl.mc_thrtctrl & ~FIPE_MC_THRTCTRL_HUNT);
	/* Set OLTT activation limit to unlimited */
	pci_config_put8(fipe_mc_ctrl.mc_pci_hdl, FIPE_MC_GBLACT, 0);
	/*
	 * Set S-CLTT low throttling to desired value. The lower value,
	 * the more power saving and the less available memory bandwidth.
	 */
	pci_config_put8(fipe_mc_ctrl.mc_pci_hdl, FIPE_MC_THRTLOW, throttle);
	/* Enable S-CLTT/disable OLTT mode */
	pci_config_put8(fipe_mc_ctrl.mc_pci_hdl, FIPE_MC_THRTCTRL,
	    fipe_mc_ctrl.mc_thrtctrl | FIPE_MC_THRTCTRL_HUNT);

	return (0);
}
Пример #7
0
/*
 * audio1575_destroy()
 *
 * Description:
 *	This routine releases all resources held by the device instance,
 *	as part of either detach or a failure in attach.
 *
 * Arguments:
 *	audio1575_state_t	*state	The device soft state.
 */
void
audio1575_destroy(audio1575_state_t *statep)
{
	ddi_acc_handle_t	pcih;

	/* stop DMA engines */
	audio1575_dma_stop(statep, B_FALSE);

	if (statep->regsh != NULL) {
		/* reset the codec */
		PUT32(M1575_SCR_REG, M1575_SCR_COLDRST);
	}

	if ((pcih = statep->pcih) != NULL) {
		/* turn off the AC_LINK clock */
		pci_config_put8(pcih, M1575_PCIACD_REG, 0);
		pci_config_put8(pcih, M1575_PCIACD_REG, 4);
		pci_config_put8(pcih, M1575_PCIACD_REG, 0);
	}

	/* Disable PCI I/O and Memory Spaces */
	audio1575_pci_disable(statep);

	audio1575_free_port(statep->ports[M1575_PLAY]);
	audio1575_free_port(statep->ports[M1575_REC]);

	audio1575_unmap_regs(statep);

	if (statep->ac97 != NULL) {
		ac97_free(statep->ac97);
	}

	if (statep->adev != NULL) {
		audio_dev_free(statep->adev);
	}

	kmem_free(statep, sizeof (*statep));
}
Пример #8
0
void
t4_os_pci_write_cfg1(struct adapter *sc, int reg, uint8_t val)
{
    pci_config_put8(sc->pci_regh, reg, val);
}
Пример #9
0
static int
acebus_config(ebus_devstate_t *ebus_p)
{
	ddi_acc_handle_t conf_handle;
	uint16_t comm;
#ifdef	ACEBUS_HOTPLUG
	int tcr_reg;
	caddr_t csr_io;
	ddi_device_acc_attr_t csr_attr = {   /* CSR map attributes */
		DDI_DEVICE_ATTR_V0,
		DDI_STRUCTURE_LE_ACC,
		DDI_STRICTORDER_ACC
	};
	ddi_acc_handle_t csr_handle;
#endif

	/*
	 * Make sure the master enable and memory access enable
	 * bits are set in the config command register.
	 */
	if (pci_config_setup(ebus_p->dip, &conf_handle) != DDI_SUCCESS)
		return (0);

	comm = pci_config_get16(conf_handle, PCI_CONF_COMM),
#ifdef DEBUG
	    DBG1(D_ATTACH, ebus_p, "command register was 0x%x\n", comm);
#endif
	comm |= (PCI_COMM_ME|PCI_COMM_MAE|PCI_COMM_SERR_ENABLE|
	    PCI_COMM_PARITY_DETECT);
	pci_config_put16(conf_handle, PCI_CONF_COMM, comm),
#ifdef DEBUG
	    DBG1(D_MAP, ebus_p, "command register is now 0x%x\n",
	    pci_config_get16(conf_handle, PCI_CONF_COMM));
#endif
	pci_config_put8(conf_handle, PCI_CONF_CACHE_LINESZ,
	    (uchar_t)acebus_cache_line_size);
	pci_config_put8(conf_handle, PCI_CONF_LATENCY_TIMER,
	    (uchar_t)acebus_latency_timer);
	pci_config_teardown(&conf_handle);

#ifdef	ACEBUS_HOTPLUG
	if (acebus_update_props(ebus_p) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not update special properties.",
		    ddi_driver_name(ebus_p->dip),
		    ddi_get_instance(ebus_p->dip));
		return (0);
	}

	if (ddi_regs_map_setup(ebus_p->dip, CSR_IO_RINDEX,
	    (caddr_t *)&csr_io, 0, CSR_SIZE, &csr_attr,
	    &csr_handle) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not map Ebus CSR.",
		    ddi_driver_name(ebus_p->dip),
		    ddi_get_instance(ebus_p->dip));
	}
#ifdef	DEBUG
	if (acebus_debug_flags) {
		DBG3(D_ATTACH, ebus_p, "tcr[123] = %x,%x,%x\n",
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR1_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR2_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR3_OFF)));
		DBG2(D_ATTACH, ebus_p, "pmd-aux=%x, freq-aux=%x\n",
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    PMD_AUX_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    FREQ_AUX_OFF)));
#ifdef ACEBUS_DEBUG
		for (comm = 0; comm < 4; comm++)
			prom_printf("dcsr%d=%x, dacr%d=%x, dbcr%d=%x\n", comm,
			    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
			    0x700000+(0x2000*comm))), comm,
			    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
			    0x700000+(0x2000*comm)+4)), comm,
			    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
			    0x700000+(0x2000*comm)+8)));
#endif
	} /* acebus_debug_flags */
#endif
	/* If TCR registers are not initialized, initialize them here */
	tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
	    TCR1_OFF));
	if ((tcr_reg == 0) || (tcr_reg == -1))
		ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR1_OFF),
		    TCR1_REGVAL);
	tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
	    TCR2_OFF));
	if ((tcr_reg == 0) || (tcr_reg == -1))
		ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR2_OFF),
		    TCR2_REGVAL);
	tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
	    TCR3_OFF));
	if ((tcr_reg == 0) || (tcr_reg == -1))
		ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR3_OFF),
		    TCR3_REGVAL);
#ifdef	DEBUG
	if (acebus_debug_flags) {
		DBG3(D_ATTACH, ebus_p, "wrote tcr[123] = %x,%x,%x\n",
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR1_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR2_OFF)),
		    ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io +
		    TCR3_OFF)));
	}
#endif

	ddi_regs_map_free(&csr_handle);
#endif	/* ACEBUS_HOTPLUG */
	return (1);	/* return success */
}
Пример #10
0
void
rge_chip_ident(rge_t *rgep)
{
	chip_id_t *chip = &rgep->chipid;
	uint32_t val32;
	uint16_t val16;

	/*
	 * Read and record MAC version
	 */
	val32 = rge_reg_get32(rgep, TX_CONFIG_REG);
	val32 &= HW_VERSION_ID_0 | HW_VERSION_ID_1;
	chip->mac_ver = val32;
	switch (chip->mac_ver) {
	case MAC_VER_8168:
	case MAC_VER_8168B_B:
	case MAC_VER_8168B_C:
	case MAC_VER_8168C:
	case MAC_VER_8101E:
	case MAC_VER_8101E_B:
		chip->is_pcie = B_TRUE;
		break;

	default:
		chip->is_pcie = B_FALSE;
		break;
	}

	/*
	 * Read and record PHY version
	 */
	val16 = rge_mii_get16(rgep, PHY_ID_REG_2);
	val16 &= PHY_VER_MASK;
	chip->phy_ver = val16;

	/* set pci latency timer */
	if (chip->mac_ver == MAC_VER_8169 ||
	    chip->mac_ver == MAC_VER_8169S_D ||
	    chip->mac_ver == MAC_VER_8169SC)
		pci_config_put8(rgep->cfg_handle, PCI_CONF_LATENCY_TIMER, 0x40);

	if (chip->mac_ver == MAC_VER_8169SC) {
		val16 = rge_reg_get16(rgep, RT_CONFIG_1_REG);
		val16 &= 0x0300;
		if (val16 == 0x1)	/* 66Mhz PCI */
			pci_config_put32(rgep->cfg_handle, 0x7c, 0x00ff00ff);
		else if (val16 == 0x0) /* 33Mhz PCI */
			pci_config_put32(rgep->cfg_handle, 0x7c, 0x00ffff00);
	}

	/*
	 * PCIE chipset require the Rx buffer start address must be
	 * 8-byte alignment and the Rx buffer size must be multiple of 8.
	 * We'll just use bcopy in receive procedure for the PCIE chipset.
	 */
	if (chip->is_pcie) {
		rgep->chip_flags |= CHIP_FLAG_FORCE_BCOPY;
		if (rgep->default_mtu > ETHERMTU) {
			rge_notice(rgep, "Jumbo packets not supported "
			    "for this PCIE chipset");
			rgep->default_mtu = ETHERMTU;
		}
	}
	if (rgep->chip_flags & CHIP_FLAG_FORCE_BCOPY)
		rgep->head_room = 0;
	else
		rgep->head_room = RGE_HEADROOM;

	/*
	 * Initialize other variables.
	 */
	if (rgep->default_mtu < ETHERMTU || rgep->default_mtu > RGE_JUMBO_MTU)
		rgep->default_mtu = ETHERMTU;
	if (rgep->default_mtu > ETHERMTU) {
		rgep->rxbuf_size = RGE_BUFF_SIZE_JUMBO;
		rgep->txbuf_size = RGE_BUFF_SIZE_JUMBO;
		rgep->ethmax_size = RGE_JUMBO_SIZE;
	} else {
		rgep->rxbuf_size = RGE_BUFF_SIZE_STD;
		rgep->txbuf_size = RGE_BUFF_SIZE_STD;
		rgep->ethmax_size = ETHERMAX;
	}
	chip->rxconfig = RX_CONFIG_DEFAULT;
	chip->txconfig = TX_CONFIG_DEFAULT;

	RGE_TRACE(("%s: MAC version = %x, PHY version = %x",
	    rgep->ifname, chip->mac_ver, chip->phy_ver));
}
Пример #11
0
static int
ppb_initchild(dev_info_t *child)
{
	char name[MAXNAMELEN];
	ddi_acc_handle_t config_handle;
	ushort_t command_preserve, command;
	uint_t n;
	ushort_t bcr;
	uchar_t header_type;
	uchar_t min_gnt, latency_timer;
	ppb_devstate_t *ppb;

	/*
	 * Name the child
	 */
	if (ppb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
		return (DDI_FAILURE);

	ddi_set_name_addr(child, name);
	ddi_set_parent_data(child, NULL);

	/*
	 * Pseudo nodes indicate a prototype node with per-instance
	 * properties to be merged into the real h/w device node.
	 * The interpretation of the unit-address is DD[,F]
	 * where DD is the device id and F is the function.
	 */
	if (ndi_dev_is_persistent_node(child) == 0) {
		extern int pci_allow_pseudo_children;

		/*
		 * Try to merge the properties from this prototype
		 * node into real h/w nodes.
		 */
		if (ndi_merge_node(child, ppb_name_child) == DDI_SUCCESS) {
			/*
			 * Merged ok - return failure to remove the node.
			 */
			ppb_removechild(child);
			return (DDI_FAILURE);
		}

		/* workaround for ddivs to run under PCI */
		if (pci_allow_pseudo_children)
			return (DDI_SUCCESS);

		/*
		 * The child was not merged into a h/w node,
		 * but there's not much we can do with it other
		 * than return failure to cause the node to be removed.
		 */
		cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
		    ddi_driver_name(child), ddi_get_name_addr(child),
		    ddi_driver_name(child));
		ppb_removechild(child);
		return (DDI_NOT_WELL_FORMED);
	}

	ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
	    ddi_get_instance(ddi_get_parent(child)));

	ddi_set_parent_data(child, NULL);

	/*
	 * If hardware is PM capable, set up the power info structure.
	 * This also ensures the the bus will not be off (0MHz) otherwise
	 * system panics during a bus access.
	 */
	if (PM_CAPABLE(ppb->ppb_pwr_p)) {
		/*
		 * Create a pwr_info struct for child.  Bus will be
		 * at full speed after creating info.
		 */
		pci_pwr_create_info(ppb->ppb_pwr_p, child);
#ifdef DEBUG
		ASSERT(ppb->ppb_pwr_p->current_lvl == PM_LEVEL_B0);
#endif
	}

	/*
	 * If configuration registers were previously saved by
	 * child (before it entered D3), then let the child do the
	 * restore to set up the config regs as it'll first need to
	 * power the device out of D3.
	 */
	if (ddi_prop_exists(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
	    "config-regs-saved-by-child") == 1) {
		DEBUG2(DBG_PWR, ddi_get_parent(child),
		    "INITCHILD: config regs to be restored by child"
		    " for %s@%s\n", ddi_node_name(child),
		    ddi_get_name_addr(child));

		return (DDI_SUCCESS);
	}

	DEBUG2(DBG_PWR, ddi_get_parent(child),
	    "INITCHILD: config regs setup for %s@%s\n",
	    ddi_node_name(child), ddi_get_name_addr(child));

	if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) {
		if (PM_CAPABLE(ppb->ppb_pwr_p)) {
			pci_pwr_rm_info(ppb->ppb_pwr_p, child);
		}

		return (DDI_FAILURE);
	}

	/*
	 * Determine the configuration header type.
	 */
	header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);

	/*
	 * Support for the "command-preserve" property.
	 */
	command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
	    DDI_PROP_DONTPASS, "command-preserve", 0);
	command = pci_config_get16(config_handle, PCI_CONF_COMM);
	command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
	command |= (ppb_command_default & ~command_preserve);
	pci_config_put16(config_handle, PCI_CONF_COMM, command);

	/*
	 * If the device has a bus control register then program it
	 * based on the settings in the command register.
	 */
	if ((header_type  & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
		bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL);
		if (ppb_command_default & PCI_COMM_PARITY_DETECT)
			bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
		if (ppb_command_default & PCI_COMM_SERR_ENABLE)
			bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
		bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
		pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr);
	}

	/*
	 * Initialize cache-line-size configuration register if needed.
	 */
	if (ppb_set_cache_line_size_register &&
	    ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
	    "cache-line-size", 0) == 0) {
		pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
		    ppb->ppb_cache_line_size);
		n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
		if (n != 0) {
			(void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
			    "cache-line-size", n);
		}
	}

	/*
	 * Initialize latency timer configuration registers if needed.
	 */
	if (ppb_set_latency_timer_register &&
	    ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
	    "latency-timer", 0) == 0) {

		if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
			latency_timer = ppb->ppb_latency_timer;
			pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
			    ppb->ppb_latency_timer);
		} else {
			min_gnt = pci_config_get8(config_handle,
			    PCI_CONF_MIN_G);
			latency_timer = min_gnt * 8;
		}
		pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
		    latency_timer);
		n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
		if (n != 0) {
			(void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
			    "latency-timer", n);
		}
	}

	/*
	 * SPARC PCIe FMA specific
	 *
	 * Note: parent_data for parent is created only if this is sparc PCI-E
	 * platform, for which, SG take a different route to handle device
	 * errors.
	 */
	if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
		if (pcie_init_cfghdl(child) != DDI_SUCCESS) {
			pci_config_teardown(&config_handle);
			return (DDI_FAILURE);
		}
		pcie_init_dom(child);
	}

	/*
	 * Check to see if the XMITS/PCI-X workaround applies.
	 */
	n = ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_NOTPROM,
	    "pcix-update-cmd-reg", -1);

	if (n != -1) {
		extern void pcix_set_cmd_reg(dev_info_t *child, uint16_t value);
		DEBUG1(DBG_INIT_CLD, child, "Turning on XMITS NCPQ "
		    "Workaround: value = %x\n", n);
		pcix_set_cmd_reg(child, n);
	}
	pci_config_teardown(&config_handle);
	return (DDI_SUCCESS);
}
Пример #12
0
int
UM_PCI_Services(Adapter_Struc *pAd, union REGS *pregs)
{
	int func = (int)pregs->h.al;
	unsigned long regnum; /* register number */
	unsigned short vendid;
	unsigned short devid;
	unsigned long compval;

	switch (func) {
		case PCI_BIOS_PRESENT:
			/* return PCI present with rev 2.1 */
			pregs->h.ah = 0;
			pregs->h.al = 0;
			pregs->h.bh = 2;
			pregs->h.bl = 1;
			pregs->h.cl = 1;
			pregs->e.edx = 0x20494350;
			pregs->x.cflag = 0;
			break;
		case FIND_PCI_DEVICE:
			vendid = pregs->x.dx;
			devid = pregs->x.cx;
			compval = (((ulong_t)devid) << 16) | ((ulong_t)vendid);
			if (vendid == 0xffff) { /* bad vendor id */
				pregs->x.cflag = 1;
				pregs->h.ah = PCI_BAD_VENDOR_ID;
			} else {
				if (pci_config_get32(
				    (ddi_acc_handle_t)pAd->pcihandle, 0) ==
				    compval) {
					pregs->h.bh = 0; /* put 0 to fake it */
					pregs->h.bl = 0; /* put 0 to fake it */
					pregs->h.ah = PCI_SUCCESSFUL;
					pregs->x.cflag = 0;
				} else {
					pregs->h.ah = PCI_DEVICE_NOT_FOUND;
					pregs->x.cflag = 1;
				}
			}
			break;
		case PCI_READ_CONFIG_BYTE:
			regnum = (unsigned long) pregs->h.di;
			pregs->h.cl = pci_config_get8(
			    (ddi_acc_handle_t)pAd->pcihandle, regnum);
			pregs->x.cflag = 0;
			pregs->h.ah = PCI_SUCCESSFUL;
			break;
		case PCI_READ_CONFIG_WORD:
			regnum = (unsigned long)pregs->h.di;
			if (regnum & 0x1) {
				pregs->x.cflag = 1;
				pregs->h.ah = PCI_BAD_REGISTER_NUMBER;
			} else {
				pregs->x.cx = pci_config_get16(
				    (ddi_acc_handle_t)pAd->pcihandle, regnum);
				pregs->x.cflag = 0;
				pregs->h.ah = PCI_SUCCESSFUL;
			}
			break;
		case PCI_READ_CONFIG_DWORD:
			regnum = (unsigned long)pregs->h.di;
			if (regnum & 0x3) {
				pregs->x.cflag = 1;
				pregs->h.ah = PCI_BAD_REGISTER_NUMBER;
			} else {
				pregs->e.ecx = pci_config_get32(
				    (ddi_acc_handle_t)pAd->pcihandle, regnum);
				pregs->x.cflag = 0;
				pregs->h.ah = PCI_SUCCESSFUL;
			}
			break;
		case PCI_WRITE_CONFIG_BYTE:
			regnum = (unsigned long) pregs->h.di;
			pci_config_put8((ddi_acc_handle_t)pAd->pcihandle,
			    regnum, pregs->h.cl);
			pregs->x.cflag = 0;
			pregs->h.ah = PCI_SUCCESSFUL;
			break;
		case PCI_WRITE_CONFIG_WORD:
			regnum = (unsigned long)pregs->h.di;
			if (regnum & 0x1) {
				pregs->x.cflag = 1;
				pregs->h.ah = PCI_BAD_REGISTER_NUMBER;
			} else {
				pci_config_put16(
				    (ddi_acc_handle_t)pAd->pcihandle,
				    regnum, pregs->x.cx);
				pregs->x.cflag = 0;
				pregs->h.ah = PCI_SUCCESSFUL;
			}
			break;
		case PCI_WRITE_CONFIG_DWORD:
			regnum = (unsigned long)pregs->h.di;
			if (regnum & 0x1) {
				pregs->x.cflag = 1;
				pregs->h.ah = PCI_BAD_REGISTER_NUMBER;
			} else {
				pci_config_put32(
				    (ddi_acc_handle_t)pAd->pcihandle,
				    regnum, pregs->e.ecx);
				pregs->x.cflag = 0;
				pregs->h.ah = PCI_SUCCESSFUL;
			}
			break;
		default:
			pregs->x.cflag = 1;	/* set error */
			pregs->h.ah = PCI_FUNC_NOT_SUPPORTED;
			break;
	}
	return (0);
}
Пример #13
0
/*ARGSUSED*/
static int
xen_uppc_translate_irq(dev_info_t *dip, int irqno)
{
	char dev_type[16];
	int dev_len, pci_irq, devid, busid;
	ddi_acc_handle_t cfg_handle;
	uchar_t ipin, iline;
	iflag_t intr_flag;

	if (dip == NULL) {
		XEN_UPPC_VERBOSE_IRQ((CE_CONT, "!xVM_uppc: irqno = %d"
		    " dip = NULL\n", irqno));
		return (irqno);
	}

	if (!xen_uppc_enable_acpi) {
		return (irqno);
	}

	dev_len = sizeof (dev_type);
	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ddi_get_parent(dip),
	    DDI_PROP_DONTPASS, "device_type", (caddr_t)dev_type,
	    &dev_len) != DDI_PROP_SUCCESS) {
		XEN_UPPC_VERBOSE_IRQ((CE_CONT, "!xVM_uppc: irqno %d"
		    " device %s instance %d no device_type\n", irqno,
		    ddi_get_name(dip), ddi_get_instance(dip)));
		return (irqno);
	}

	if ((strcmp(dev_type, "pci") == 0) ||
	    (strcmp(dev_type, "pciex") == 0)) {

		/* pci device */
		if (acpica_get_bdf(dip, &busid, &devid, NULL) != 0)
			return (irqno);

		if (pci_config_setup(dip, &cfg_handle) != DDI_SUCCESS)
			return (irqno);

		ipin = pci_config_get8(cfg_handle, PCI_CONF_IPIN) - PCI_INTA;
		iline = pci_config_get8(cfg_handle, PCI_CONF_ILINE);
		if (xen_uppc_acpi_translate_pci_irq(dip, busid, devid,
		    ipin, &pci_irq, &intr_flag) == ACPI_PSM_SUCCESS) {

			XEN_UPPC_VERBOSE_IRQ((CE_CONT, "!xVM_uppc: [ACPI] "
			    "new irq %d old irq %d device %s, instance %d\n",
			    pci_irq, irqno, ddi_get_name(dip),
			    ddi_get_instance(dip)));

			/*
			 * Make sure pci_irq is within range.
			 * Otherwise, fall through and return irqno.
			 */
			if (pci_irq <= MAX_ISA_IRQ) {
				if (iline != pci_irq) {
					/*
					 * Update the device's ILINE byte,
					 * in case uppc_acpi_translate_pci_irq
					 * has choosen a different pci_irq
					 * than the BIOS has configured.
					 * Some chipsets use the value in
					 * ILINE to control interrupt routing,
					 * in conflict with the PCI spec.
					 */
					pci_config_put8(cfg_handle,
					    PCI_CONF_ILINE, pci_irq);
				}
				pci_config_teardown(&cfg_handle);
				return (pci_irq);
			}
		}
		pci_config_teardown(&cfg_handle);

		/* FALLTHRU to common case - returning irqno */
	} else {
		/* non-PCI; assumes ISA-style edge-triggered */
		psm_set_elcr(irqno, 0); 	/* set IRQ to ISA mode */

		XEN_UPPC_VERBOSE_IRQ((CE_CONT, "!xVM_uppc: non-pci,"
		    "irqno %d device %s instance %d\n", irqno,
		    ddi_get_name(dip), ddi_get_instance(dip)));
	}

	return (irqno);
}
Пример #14
0
/*
 * audio1575_chip_init()
 *
 * Description:
 *	This routine initializes the M1575 AC97 audio controller and the AC97
 *	codec.	The AC97 codec registers are programmed from codec_shadow[].
 *	If we are not doing a restore, we initialize codec_shadow[], otherwise
 *	we use the current values of shadow.	This routine expects that the
 *	PCI IO and Memory spaces have been mapped and enabled already.
 * Arguments:
 *	audio1575_state_t	*state		The device's state structure
 *						restore	from codec_shadow[]
 * Returns:
 *	DDI_SUCCESS	The hardware was initialized properly
 *	DDI_FAILURE	The hardware couldn't be initialized properly
 */
static int
audio1575_chip_init(audio1575_state_t *statep)
{
	uint32_t		ssr;
	uint32_t		rtsr;
	uint32_t		intrsr;
	int 			i;
	int			j;
#ifdef	__sparc
	uint8_t			clk_detect;
	ddi_acc_handle_t	pcih;
#endif
	clock_t			ticks;

	/*
	 * clear the interrupt control and status register
	 * READ/WRITE/READ workaround required
	 * for buggy hardware
	 */

	PUT32(M1575_INTRCR_REG, 0);
	(void) GET32(M1575_INTRCR_REG);

	intrsr = GET32(M1575_INTRSR_REG);
	PUT32(M1575_INTRSR_REG, (intrsr & M1575_INTR_MASK));
	(void) GET32(M1575_INTRSR_REG);

	ticks = drv_usectohz(M1575_LOOP_CTR);

	/*
	 * SADA only supports stereo, so we set the channel bits
	 * to "00" to select 2 channels.
	 * will also set the following:
	 *
	 * Disable double rate enable
	 * no SPDIF output selected
	 * 16 bit audio record mode
	 * 16 bit pcm out mode
	 * PCM Out 6 chan mode FL FR CEN BL BR LFE
	 * PCM Out 2 channel mode (00)
	 */
	for (i = 0; i < M1575_LOOP_CTR; i++) {
		/* Reset the AC97 Codec	and default to 2 channel 16 bit mode */
		PUT32(M1575_SCR_REG, M1575_SCR_COLDRST);
		delay(ticks<<1);

		/* Read the System Status Reg */
		ssr = GET32(M1575_SSR_REG);

		/* make sure and release the blocked reset bit */
		if (ssr & M1575_SSR_RSTBLK) {
			SET32(M1575_INTFCR_REG, M1575_INTFCR_RSTREL);
			delay(ticks);

			/* Read the System Status Reg */
			ssr = GET32(M1575_SSR_REG);

			/* make sure and release the blocked reset bit */
			if (ssr & M1575_SSR_RSTBLK) {
				return (DDI_FAILURE);
			}

			/* Reset the controller */
			PUT32(M1575_SCR_REG, M1575_SCR_COLDRST);
			delay(ticks);
		}

		/* according AC'97 spec, wait for codec reset */
		for (j = 0; j < M1575_LOOP_CTR; j++) {
			if ((GET32(M1575_SCR_REG) & M1575_SCR_COLDRST) == 0) {
				break;
			}
			delay(ticks);
		}

		/* codec reset failed */
		if (j >= M1575_LOOP_CTR) {
			audio_dev_warn(statep->adev,
			    "failure to reset codec");
			return (DDI_FAILURE);
		}

		/*
		 * Wait for FACRDY First codec ready. The hardware can
		 * provide the state of
		 * codec ready bit on SDATA_IN[0] and as reflected in
		 * the Recv Tag Slot Reg.
		 */
		rtsr = GET32(M1575_RTSR_REG);
		if (rtsr & M1575_RTSR_FACRDY) {
			break;
		} else { /* reset the status and wait for new status to set */
			rtsr |= M1575_RTSR_FACRDY;
			PUT32(M1575_RTSR_REG, rtsr);
			drv_usecwait(10);
		}
	}

	/* if we could not reset the AC97 codec then report failure */
	if (i >= M1575_LOOP_CTR) {
		audio_dev_warn(statep->adev,
		    "no codec ready signal received");
		return (DDI_FAILURE);
	}

#ifdef	__sparc
	/* Magic code from ULi to Turn on the AC_LINK clock */
	pcih = statep->pcih;
	pci_config_put8(pcih, M1575_PCIACD_REG, 0);
	pci_config_put8(pcih, M1575_PCIACD_REG, 4);
	pci_config_put8(pcih, M1575_PCIACD_REG, 0);
	(void) pci_config_get8(pcih, M1575_PCIACD_REG);
	pci_config_put8(pcih, M1575_PCIACD_REG, 2);
	pci_config_put8(pcih, M1575_PCIACD_REG, 0);
	clk_detect = pci_config_get8(pcih, M1575_PCIACD_REG);

	if (clk_detect != 1) {
		audio_dev_warn(statep->adev, "No AC97 Clock Detected");
		return (DDI_FAILURE);
	}
#endif

	/* Magic code from Uli to Init FIFO1 and FIFO2 */
	PUT32(M1575_FIFOCR1_REG, 0x81818181);
	PUT32(M1575_FIFOCR2_REG, 0x81818181);
	PUT32(M1575_FIFOCR3_REG, 0x81818181);

	/* Make sure that PCM in and PCM out are enabled */
	SET32(M1575_INTFCR_REG, (M1575_INTFCR_PCMIENB | M1575_INTFCR_PCMOENB));

	audio1575_dma_stop(statep, B_FALSE);

	return (DDI_SUCCESS);
}
Пример #15
0
/*ARGSUSED*/
static int
agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
    cred_t *cred, int *rval)
{
	int instance = DEV2INST(dev);
	agp_target_softstate_t *st;
	static char kernel_only[] =
	    "amd64_gart_ioctl: is a kernel only ioctl";

	if (!(mode & FKIOCTL)) {
		TARGETDB_PRINT2((CE_CONT, kernel_only));
		return (ENXIO);
	}
	st = GETSOFTC(instance);

	if (st == NULL)
		return (ENXIO);

	mutex_enter(&st->tsoft_lock);

	switch (cmd) {
	case CHIP_DETECT:
	{
		int type;
		switch (st->tsoft_devid & VENDOR_ID_MASK) {
		case INTEL_VENDOR_ID:
			type = CHIP_IS_INTEL;
			break;
		case AMD_VENDOR_ID:
			type = CHIP_IS_AMD;
			break;
		default:
			type = 0;
		}
		if (ddi_copyout(&type, (void *)data, sizeof (int), mode)) {
			mutex_exit(&st->tsoft_lock);
			return (EFAULT);
		}

		break;
	}
	case I8XX_GET_PREALLOC_SIZE:
	{
		size_t prealloc_size;

		if ((st->tsoft_devid & VENDOR_ID_MASK) !=
		    INTEL_VENDOR_ID) {
			mutex_exit(&st->tsoft_lock);
			return (EINVAL);
		}

		prealloc_size = i8xx_biosmem_detect(st);
		if (ddi_copyout(&prealloc_size, (void *)data,
		    sizeof (size_t), mode)) {
			mutex_exit(&st->tsoft_lock);
			return (EFAULT);
		}

		break;
	}
	case AGP_TARGET_GETINFO:
	{
		i_agp_info_t info;
		uint32_t value;
		off_t cap;

		ASSERT(st->tsoft_acaptr);

		cap = st->tsoft_acaptr;
		value = pci_config_get32(st->tsoft_pcihdl, cap);
		info.iagp_ver.agpv_major = (uint16_t)((value >> 20) & 0xf);
		info.iagp_ver.agpv_minor = (uint16_t)((value >> 16) & 0xf);
		info.iagp_devid = st->tsoft_devid;
		info.iagp_mode = pci_config_get32(st->tsoft_pcihdl,
			    cap + AGP_CONF_STATUS);
		info.iagp_aperbase = agp_target_get_apbase(st);
		info.iagp_apersize = agp_target_get_apsize(st);

		if (ddi_copyout(&info, (void *)data,
		    sizeof (i_agp_info_t), mode)) {
			mutex_exit(&st->tsoft_lock);
			return (EFAULT);
		}
		break;

	}
	/*
	 * This ioctl is only for Intel AGP chipsets.
	 * It is not necessary for the AMD8151 AGP bridge, because
	 * this register in the AMD8151 does not control any hardware.
	 * It is only provided for compatibility with an Intel AGP bridge.
	 * Please refer to the <<AMD8151 data sheet>> page 24,
	 * AGP device GART pointer.
	 */
	case AGP_TARGET_SET_GATTADDR:
	{
		uint32_t gartaddr;

		if (ddi_copyin((void *)data, &gartaddr,
		    sizeof (uint32_t), mode)) {
			mutex_exit(&st->tsoft_lock);
			return (EFAULT);
		}

		agp_target_set_gartaddr(st, gartaddr);
		break;
	}
	case AGP_TARGET_SETCMD:
	{
		uint32_t command;

		if (ddi_copyin((void *)data, &command,
		    sizeof (uint32_t), mode)) {
			mutex_exit(&st->tsoft_lock);
			return (EFAULT);
		}

		ASSERT(st->tsoft_acaptr);

		pci_config_put32(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_COMMAND,
		    command);
		break;

	}
	case AGP_TARGET_FLUSH_GTLB:
	{
		uint16_t value;

		ASSERT(st->tsoft_acaptr);

		value = pci_config_get16(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_CONTROL);
		value &= ~AGPCTRL_GTLBEN;
		pci_config_put16(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_CONTROL, value);
		value |= AGPCTRL_GTLBEN;
		pci_config_put16(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_CONTROL, value);

		break;
	}
	case AGP_TARGET_CONFIGURE:
	{
		uint8_t value;

		ASSERT(st->tsoft_acaptr);

		value = pci_config_get8(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_MISC);
		value |= AGP_MISC_APEN;
		pci_config_put8(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_MISC, value);
		break;

	}
	case AGP_TARGET_UNCONFIG:
	{
		uint32_t value1;
		uint8_t value2;

		ASSERT(st->tsoft_acaptr);

		pci_config_put16(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_CONTROL, 0x0);

		value2 = pci_config_get8(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_MISC);
		value2 &= ~AGP_MISC_APEN;
		pci_config_put8(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_MISC, value2);

		value1 = pci_config_get32(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_COMMAND);
		value1 &= ~AGPCMD_AGPEN;
		pci_config_put32(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_COMMAND,
		    value1);

		pci_config_put32(st->tsoft_pcihdl,
		    st->tsoft_acaptr + AGP_CONF_ATTBASE, 0x0);

		break;
	}

	default:
		mutex_exit(&st->tsoft_lock);
		return (ENXIO);
	} /* end switch */

	mutex_exit(&st->tsoft_lock);

	return (0);
}