/* * 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); }
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; } }
/*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); }
/* * 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); }
/*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); }
/* * 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); }
/* * 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)); }
void t4_os_pci_write_cfg1(struct adapter *sc, int reg, uint8_t val) { pci_config_put8(sc->pci_regh, reg, val); }
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 */ }
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)); }
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); }
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); }
/*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); }
/* * 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); }
/*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); }