Module Name: src
Committed By: jakllsch
Date: Wed Feb 1 16:56:34 UTC 2012
Modified Files:
src/sys/dev/pci/hdaudio: hdaudio_pci.c
Log Message:
Set HDAUDIO_PCI_TCSEL to TC0 like Linux does.
Fixes stalled audio on Lenovo X60 with coreboot firmware.
Additionally, move snooping adjustment to be executed on resume too,
as Linux does.
To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/pci/hdaudio/hdaudio_pci.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/pci/hdaudio/hdaudio_pci.c
diff -u src/sys/dev/pci/hdaudio/hdaudio_pci.c:1.10 src/sys/dev/pci/hdaudio/hdaudio_pci.c:1.11
--- src/sys/dev/pci/hdaudio/hdaudio_pci.c:1.10 Thu Nov 24 03:35:59 2011
+++ src/sys/dev/pci/hdaudio/hdaudio_pci.c Wed Feb 1 16:56:34 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudio_pci.c,v 1.10 2011/11/24 03:35:59 mrg Exp $ */
+/* $NetBSD: hdaudio_pci.c,v 1.11 2012/02/01 16:56:34 jakllsch Exp $ */
/*
* Copyright (c) 2009 Precedence Technologies Ltd <[email protected]>
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hdaudio_pci.c,v 1.10 2011/11/24 03:35:59 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hdaudio_pci.c,v 1.11 2012/02/01 16:56:34 jakllsch Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -56,6 +56,7 @@ struct hdaudio_pci_softc {
pcitag_t sc_tag;
pci_chipset_tag_t sc_pc;
void *sc_ih;
+ pcireg_t sc_id;
};
static int hdaudio_pci_match(device_t, cfdata_t, void *);
@@ -65,6 +66,7 @@ static int hdaudio_pci_rescan(device_t,
static void hdaudio_pci_childdet(device_t, device_t);
static int hdaudio_pci_intr(void *);
+static void hdaudio_pci_reinit(struct hdaudio_pci_softc *);
/* power management */
static bool hdaudio_pci_resume(device_t, const pmf_qual_t *);
@@ -112,6 +114,7 @@ hdaudio_pci_attach(device_t parent, devi
sc->sc_pc = pa->pa_pc;
sc->sc_tag = pa->pa_tag;
+ sc->sc_id = pa->pa_id;
sc->sc_hdaudio.sc_subsystem = pci_conf_read(sc->sc_pc, sc->sc_tag,
PCI_SUBSYS_ID_REG);
@@ -155,17 +158,7 @@ hdaudio_pci_attach(device_t parent, devi
if (!pmf_device_register(self, NULL, hdaudio_pci_resume))
aprint_error_dev(self, "couldn't establish power handler\n");
- switch (PCI_VENDOR(pa->pa_id)) {
- case PCI_VENDOR_NVIDIA:
- /* enable snooping */
- csr = pci_conf_read(sc->sc_pc, sc->sc_tag,
- HDAUDIO_NV_REG_SNOOP);
- csr &= ~HDAUDIO_NV_SNOOP_MASK;
- csr |= HDAUDIO_NV_SNOOP_ENABLE;
- pci_conf_write(sc->sc_pc, sc->sc_tag,
- HDAUDIO_NV_REG_SNOOP, csr);
- break;
- }
+ hdaudio_pci_reinit(sc);
/* Attach bus-independent HD audio layer */
hdaudio_attach(self, &sc->sc_hdaudio);
@@ -224,10 +217,36 @@ hdaudio_pci_intr(void *opaque)
return hdaudio_intr(&sc->sc_hdaudio);
}
+
+static void
+hdaudio_pci_reinit(struct hdaudio_pci_softc *sc)
+{
+ pcireg_t val;
+
+ /* stops playback static */
+ val = pci_conf_read(sc->sc_pc, sc->sc_tag, HDAUDIO_PCI_TCSEL);
+ val &= ~7;
+ val |= 0;
+ pci_conf_write(sc->sc_pc, sc->sc_tag, HDAUDIO_PCI_TCSEL, val);
+
+ switch (PCI_VENDOR(sc->sc_id)) {
+ case PCI_VENDOR_NVIDIA:
+ /* enable snooping */
+ val = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ HDAUDIO_NV_REG_SNOOP);
+ val &= ~HDAUDIO_NV_SNOOP_MASK;
+ val |= HDAUDIO_NV_SNOOP_ENABLE;
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ HDAUDIO_NV_REG_SNOOP, val);
+ break;
+ }
+}
+
static bool
hdaudio_pci_resume(device_t self, const pmf_qual_t *qual)
{
struct hdaudio_pci_softc *sc = device_private(self);
+ hdaudio_pci_reinit(sc);
return hdaudio_resume(&sc->sc_hdaudio);
}