-/* $OpenBSD: azalia.c,v 1.286 2024/03/06 00:11:25 jsg Exp $ */
+/* $OpenBSD: azalia.c,v 1.287 2024/05/17 19:43:45 kettenis Exp $ */
/* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */
/*-
int nistreams, nostreams, nbstreams;
stream_t pstream;
stream_t rstream;
+ uint32_t intctl;
} azalia_t;
#define XNAME(sc) ((sc)->dev.dv_xname)
#define AZ_READ_1(z, r) bus_space_read_1((z)->iot, (z)->ioh, HDA_##r)
azalia_pci_write(sc->pc, sc->tag, ICH_PCI_MMC, reg);
}
- /* disable MSI for AMD Summit Ridge/Raven Ridge HD Audio */
- if (PCI_VENDOR(sc->pciid) == PCI_VENDOR_AMD) {
- switch (PCI_PRODUCT(sc->pciid)) {
- case PCI_PRODUCT_AMD_17_HDA:
- case PCI_PRODUCT_AMD_17_1X_HDA:
- case PCI_PRODUCT_AMD_HUDSON2_HDA:
- pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED;
- }
- }
-
/* interrupt */
if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) {
printf(": can't map interrupt\n");
AZ_WRITE_4(az, INTCTL, 0);
DPRINTF(("%s: clear interrupts\n", __func__));
- AZ_WRITE_4(az, INTSTS, HDA_INTSTS_CIS | HDA_INTSTS_GIS);
AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE);
AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS);
}
int ret = 0;
mtx_enter(&audio_lock);
- intsts = AZ_READ_4(az, INTSTS);
- if (intsts == 0 || intsts == 0xffffffff) {
- mtx_leave(&audio_lock);
- return (ret);
- }
-
- AZ_WRITE_4(az, INTSTS, intsts);
+ for (;;) {
+ intsts = AZ_READ_4(az, INTSTS);
+ if ((intsts & az->intctl) == 0 || intsts == 0xffffffff)
+ break;
- if (intsts & az->pstream.intr_bit) {
- azalia_stream_intr(&az->pstream);
- ret = 1;
- }
+ if (intsts & az->pstream.intr_bit) {
+ azalia_stream_intr(&az->pstream);
+ ret = 1;
+ }
- if (intsts & az->rstream.intr_bit) {
- azalia_stream_intr(&az->rstream);
- ret = 1;
- }
+ if (intsts & az->rstream.intr_bit) {
+ azalia_stream_intr(&az->rstream);
+ ret = 1;
+ }
- if ((intsts & HDA_INTSTS_CIS) &&
- (AZ_READ_1(az, RIRBCTL) & HDA_RIRBCTL_RINTCTL) &&
- (AZ_READ_1(az, RIRBSTS) & HDA_RIRBSTS_RINTFL)) {
- azalia_rirb_intr(az);
- ret = 1;
+ if ((intsts & HDA_INTSTS_CIS) &&
+ (AZ_READ_1(az, RIRBCTL) & HDA_RIRBCTL_RINTCTL) &&
+ (AZ_READ_1(az, RIRBSTS) & HDA_RIRBSTS_RINTFL)) {
+ azalia_rirb_intr(az);
+ ret = 1;
+ }
}
mtx_leave(&audio_lock);
return (ret);
/* clear interrupt status */
AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE);
AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS);
- AZ_WRITE_4(az, INTSTS, HDA_INTSTS_CIS | HDA_INTSTS_GIS);
AZ_WRITE_4(az, DPLBASE, 0);
AZ_WRITE_4(az, DPUBASE, 0);
if (err)
return(err);
- AZ_WRITE_4(az, INTCTL,
- AZ_READ_4(az, INTCTL) | HDA_INTCTL_CIE | HDA_INTCTL_GIE);
+ az->intctl = HDA_INTCTL_CIE | HDA_INTCTL_GIE;
+ AZ_WRITE_4(az, INTCTL, az->intctl);
return(0);
}
/* stop interrupts and clear status registers */
AZ_WRITE_4(az, INTCTL, 0);
- AZ_WRITE_4(az, INTSTS, HDA_INTSTS_CIS | HDA_INTSTS_GIS);
AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE);
AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS);
bdlist_entry_t *bdlist;
bus_addr_t dmaaddr, dmaend;
int err, index;
- uint32_t intctl;
uint8_t ctl2;
err = azalia_stream_reset(this);
if (err)
return EINVAL;
- intctl = AZ_READ_4(this->az, INTCTL);
- intctl |= this->intr_bit;
- AZ_WRITE_4(this->az, INTCTL, intctl);
+ this->az->intctl |= this->intr_bit;
+ AZ_WRITE_4(this->az, INTCTL, this->az->intctl);
STR_WRITE_1(this, CTL, STR_READ_1(this, CTL) |
HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE |
ctl = STR_READ_2(this, CTL);
ctl &= ~(HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE | HDA_SD_CTL_RUN);
STR_WRITE_2(this, CTL, ctl);
- AZ_WRITE_4(this->az, INTCTL,
- AZ_READ_4(this->az, INTCTL) & ~this->intr_bit);
+ this->az->intctl &= ~this->intr_bit;
+ AZ_WRITE_4(this->az, INTCTL, this->az->intctl);
azalia_codec_disconnect_stream(this);
return (0);