Module Name: src
Committed By: martin
Date: Mon Nov 27 10:21:26 UTC 2017
Modified Files:
src/sys/dev/hdaudio [netbsd-8]: hdaudio.c
Log Message:
Pull up following revision(s) (requested by jmcneill in ticket #391):
sys/dev/hdaudio/hdaudio.c: revision 1.7
sys/dev/hdaudio/hdaudio.c: revision 1.8
Always access CORBCTL using hda_read1/hda_write1 (it is an 8-bit wide reg).
Reported by Michal Necasek.
Always go through RIRB startup process, initialize RIRB interrupt count
register, and ack RIRBs as we process them in polling mode.
XXX pullup
To generate a diff of this commit:
cvs rdiff -u -r1.4.10.2 -r1.4.10.3 src/sys/dev/hdaudio/hdaudio.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/hdaudio/hdaudio.c
diff -u src/sys/dev/hdaudio/hdaudio.c:1.4.10.2 src/sys/dev/hdaudio/hdaudio.c:1.4.10.3
--- src/sys/dev/hdaudio/hdaudio.c:1.4.10.2 Fri Nov 24 08:35:34 2017
+++ src/sys/dev/hdaudio/hdaudio.c Mon Nov 27 10:21:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudio.c,v 1.4.10.2 2017/11/24 08:35:34 martin Exp $ */
+/* $NetBSD: hdaudio.c,v 1.4.10.3 2017/11/27 10:21:26 martin Exp $ */
/*
* Copyright (c) 2009 Precedence Technologies Ltd <[email protected]>
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.4.10.2 2017/11/24 08:35:34 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.4.10.3 2017/11/27 10:21:26 martin Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -347,6 +347,9 @@ hdaudio_command_unlocked(struct hdaudio_
hdaudio_corb_enqueue(sc, co->co_addr, nid, control, param);
result = hdaudio_rirb_dequeue(sc, false);
+ /* Clear response interrupt status */
+ hda_write1(sc, HDAUDIO_MMIO_RIRBSTS, hda_read1(sc, HDAUDIO_MMIO_RIRBSTS));
+
return result;
}
@@ -428,10 +431,10 @@ hdaudio_corb_stop(struct hdaudio_softc *
corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL);
if (corbctl & HDAUDIO_CORBCTL_RUN) {
corbctl &= ~HDAUDIO_CORBCTL_RUN;
- hda_write4(sc, HDAUDIO_MMIO_CORBCTL, corbctl);
+ hda_write1(sc, HDAUDIO_MMIO_CORBCTL, corbctl);
do {
hda_delay(10);
- corbctl = hda_read4(sc, HDAUDIO_MMIO_CORBCTL);
+ corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL);
} while (--retry > 0 && (corbctl & HDAUDIO_CORBCTL_RUN) != 0);
if (retry == 0) {
hda_error(sc, "timeout stopping CORB\n");
@@ -452,10 +455,10 @@ hdaudio_corb_start(struct hdaudio_softc
corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL);
if ((corbctl & HDAUDIO_CORBCTL_RUN) == 0) {
corbctl |= HDAUDIO_CORBCTL_RUN;
- hda_write4(sc, HDAUDIO_MMIO_CORBCTL, corbctl);
+ hda_write1(sc, HDAUDIO_MMIO_CORBCTL, corbctl);
do {
hda_delay(10);
- corbctl = hda_read4(sc, HDAUDIO_MMIO_CORBCTL);
+ corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL);
} while (--retry > 0 && (corbctl & HDAUDIO_CORBCTL_RUN) == 0);
if (retry == 0) {
hda_error(sc, "timeout starting CORB\n");
@@ -497,20 +500,21 @@ hdaudio_rirb_start(struct hdaudio_softc
uint8_t rirbctl;
int retry = HDAUDIO_RIRB_TIMEOUT;
- /* Start the RIRB if necessary */
+ /* Set the RIRB interrupt count */
+ hda_write2(sc, HDAUDIO_MMIO_RINTCNT, 1);
+
+ /* Start the RIRB */
rirbctl = hda_read1(sc, HDAUDIO_MMIO_RIRBCTL);
- if ((rirbctl & (HDAUDIO_RIRBCTL_RUN|HDAUDIO_RIRBCTL_INT_EN)) == 0) {
- rirbctl |= HDAUDIO_RIRBCTL_RUN;
- rirbctl |= HDAUDIO_RIRBCTL_INT_EN;
- hda_write1(sc, HDAUDIO_MMIO_RIRBCTL, rirbctl);
- do {
- hda_delay(10);
- rirbctl = hda_read1(sc, HDAUDIO_MMIO_RIRBCTL);
- } while (--retry > 0 && (rirbctl & HDAUDIO_RIRBCTL_RUN) == 0);
- if (retry == 0) {
- hda_error(sc, "timeout starting RIRB\n");
- return ETIME;
- }
+ rirbctl |= HDAUDIO_RIRBCTL_RUN;
+ rirbctl |= HDAUDIO_RIRBCTL_INT_EN;
+ hda_write1(sc, HDAUDIO_MMIO_RIRBCTL, rirbctl);
+ do {
+ hda_delay(10);
+ rirbctl = hda_read1(sc, HDAUDIO_MMIO_RIRBCTL);
+ } while (--retry > 0 && (rirbctl & HDAUDIO_RIRBCTL_RUN) == 0);
+ if (retry == 0) {
+ hda_error(sc, "timeout starting RIRB\n");
+ return ETIME;
}
return 0;
@@ -558,8 +562,6 @@ static int
hdaudio_rirb_config(struct hdaudio_softc *sc)
{
uint32_t rirbubase, rirblbase;
- uint32_t rirbwp;
- int retry = HDAUDIO_RIRB_TIMEOUT;
/* Program command buffer base address and size */
rirblbase = (uint32_t)DMA_DMAADDR(&sc->sc_rirb);
@@ -570,15 +572,6 @@ hdaudio_rirb_config(struct hdaudio_softc
/* Clear the write pointer */
hda_write2(sc, HDAUDIO_MMIO_RIRBWP, HDAUDIO_RIRBWP_WP_RESET);
- hda_write2(sc, HDAUDIO_MMIO_RIRBWP, 0);
- do {
- hda_delay(10);
- rirbwp = hda_read2(sc, HDAUDIO_MMIO_RIRBWP);
- } while (--retry > 0 && (rirbwp & HDAUDIO_RIRBWP_WP_RESET) != 0);
- if (retry == 0) {
- hda_error(sc, "timeout resetting RIRB\n");
- return ETIME;
- }
sc->sc_rirbrp = 0;
return 0;