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 <supp...@precedence.co.uk> @@ -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); }