Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev hdaudio: pci: PCIe config space fixes and Intel PCH ...
details: https://anonhg.NetBSD.org/src/rev/8a01c6d96db8
branches: trunk
changeset: 364403:8a01c6d96db8
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Mon Mar 21 09:12:09 2022 +0000
description:
hdaudio: pci: PCIe config space fixes and Intel PCH snoop support
The HD audio specification does not cover PCI config space, and this
driver was unconditionally writing to a vendor specific register. Reduce
scope of config space accesses based on PCI IDs.
With this cleaned up, add support for Intel PCH devices which require
some additional vendor specific configuration to bypass no snoop mode.
diffstat:
sys/dev/hdaudio/hdaudioreg.h | 10 +-----
sys/dev/pci/hdaudio_pci.c | 76 +++++++++++++++++++++++++++++++------------
sys/dev/pci/hdaudio_pci.h | 20 +++++++++--
3 files changed, 71 insertions(+), 35 deletions(-)
diffs (211 lines):
diff -r c793f03e0c61 -r 8a01c6d96db8 sys/dev/hdaudio/hdaudioreg.h
--- a/sys/dev/hdaudio/hdaudioreg.h Mon Mar 21 00:25:04 2022 +0000
+++ b/sys/dev/hdaudio/hdaudioreg.h Mon Mar 21 09:12:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudioreg.h,v 1.3 2019/01/07 01:03:05 mrg Exp $ */
+/* $NetBSD: hdaudioreg.h,v 1.4 2022/03/21 09:12:10 jmcneill Exp $ */
/*
* Copyright (c) 2009 Precedence Technologies Ltd <support%precedence.co.uk@localhost>
@@ -36,14 +36,6 @@
#include <sys/types.h>
/*
- * High Definition Audio Audio PCI Configuration Space
- */
-#define HDAUDIO_PCI_AZBARL 0x10
-#define HDAUDIO_PCI_AZBARU 0x14
-#define HDAUDIO_PCI_AZCTL 0x40
-#define HDAUDIO_PCI_TCSEL 0x44
-
-/*
* High Definition Audio Memory Mapped Configuration Registers
*/
#define HDAUDIO_MMIO_GCAP 0x000
diff -r c793f03e0c61 -r 8a01c6d96db8 sys/dev/pci/hdaudio_pci.c
--- a/sys/dev/pci/hdaudio_pci.c Mon Mar 21 00:25:04 2022 +0000
+++ b/sys/dev/pci/hdaudio_pci.c Mon Mar 21 09:12:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudio_pci.c,v 1.11 2021/10/28 09:15:35 msaitoh Exp $ */
+/* $NetBSD: hdaudio_pci.c,v 1.12 2022/03/21 09:12:09 jmcneill Exp $ */
/*
* Copyright (c) 2009 Precedence Technologies Ltd <support%precedence.co.uk@localhost>
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hdaudio_pci.c,v 1.11 2021/10/28 09:15:35 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hdaudio_pci.c,v 1.12 2022/03/21 09:12:09 jmcneill Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -61,6 +61,11 @@
pci_intr_handle_t *sc_pihp;
};
+#define HDAUDIO_PCI_IS_INTEL(sc) \
+ (PCI_VENDOR(sc->sc_id) == PCI_VENDOR_INTEL)
+#define HDAUDIO_PCI_IS_NVIDIA(sc) \
+ (PCI_VENDOR(sc->sc_id) == PCI_VENDOR_NVIDIA)
+
static int hdaudio_pci_match(device_t, cfdata_t, void *);
static void hdaudio_pci_attach(device_t, device_t, void *);
static int hdaudio_pci_detach(device_t, int);
@@ -68,7 +73,7 @@
static void hdaudio_pci_childdet(device_t, device_t);
static int hdaudio_pci_intr(void *);
-static void hdaudio_pci_reinit(struct hdaudio_pci_softc *);
+static void hdaudio_pci_init(struct hdaudio_pci_softc *);
/* power management */
static bool hdaudio_pci_resume(device_t, const pmf_qual_t *);
@@ -139,7 +144,7 @@
pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, csr);
/* Map MMIO registers */
- reg = HDAUDIO_PCI_AZBARL;
+ reg = PCI_BAR0;
maptype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, reg);
err = pci_mapreg_map(pa, reg, maptype, 0,
&sc->sc_hdaudio.sc_memt,
@@ -174,7 +179,7 @@
}
aprint_normal_dev(self, "interrupting at %s\n", intrstr);
- hdaudio_pci_reinit(sc);
+ hdaudio_pci_init(sc);
/* Attach bus-independent HD audio layer */
if (hdaudio_attach(self, &sc->sc_hdaudio)) {
@@ -187,15 +192,18 @@
sc->sc_hdaudio.sc_memvalid = false;
csr = pci_conf_read(sc->sc_pc, sc->sc_tag,
PCI_COMMAND_STATUS_REG);
- csr &= ~(PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_BACKTOBACK_ENABLE);
+ csr &= ~(PCI_COMMAND_MASTER_ENABLE |
+ PCI_COMMAND_BACKTOBACK_ENABLE);
pci_conf_write(sc->sc_pc, sc->sc_tag,
PCI_COMMAND_STATUS_REG, csr);
- if (!pmf_device_register(self, NULL, NULL))
- aprint_error_dev(self, "couldn't establish power handler\n");
+ if (!pmf_device_register(self, NULL, NULL)) {
+ aprint_error_dev(self,
+ "couldn't establish power handler\n");
+ }
+ } else if (!pmf_device_register(self, NULL, hdaudio_pci_resume)) {
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
- else if (!pmf_device_register(self, NULL, hdaudio_pci_resume))
- aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
@@ -252,28 +260,51 @@
return hdaudio_intr(&sc->sc_hdaudio);
}
-
static void
-hdaudio_pci_reinit(struct hdaudio_pci_softc *sc)
+hdaudio_pci_init(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);
+ if (HDAUDIO_PCI_IS_INTEL(sc)) {
+ /*
+ * ICH: Set traffic class for input/output/buf descriptors
+ * to TC0. For PCH without a TCSEL register, PGCTL is in
+ * the same location and clearing these bits is harmless.
+ */
+ val = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ HDAUDIO_INTEL_REG_ICH_TCSEL);
+ val &= ~HDAUDIO_INTEL_ICH_TCSEL_MASK;
+ val |= HDAUDIO_INTEL_ICH_TCSEL_TC0;
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ HDAUDIO_INTEL_REG_ICH_TCSEL, val);
- switch (PCI_VENDOR(sc->sc_id)) {
- case PCI_VENDOR_NVIDIA:
- /* enable snooping */
+ /*
+ * PCH: Disable dynamic clock gating logic. Implementations
+ * without a CGCTL register do not appear to have anything
+ * else in its place.
+ */
+ val = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ HDAUDIO_INTEL_REG_PCH_CGCTL);
+ val &= ~HDAUDIO_INTEL_PCH_CGCTL_MISCBDCGE;
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ HDAUDIO_INTEL_REG_PCH_CGCTL, val);
+
+ /* ICH/PCH: Enable snooping. */
+ val = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ HDAUDIO_INTEL_REG_PCH_DEVC);
+ val &= ~HDAUDIO_INTEL_PCH_DEVC_NSNPEN;
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ HDAUDIO_INTEL_REG_PCH_DEVC, val);
+ }
+
+ if (HDAUDIO_PCI_IS_NVIDIA(sc)) {
+ /* 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;
}
}
@@ -282,7 +313,8 @@
{
struct hdaudio_pci_softc *sc = device_private(self);
- hdaudio_pci_reinit(sc);
+ hdaudio_pci_init(sc);
+
return hdaudio_resume(&sc->sc_hdaudio);
}
diff -r c793f03e0c61 -r 8a01c6d96db8 sys/dev/pci/hdaudio_pci.h
--- a/sys/dev/pci/hdaudio_pci.h Mon Mar 21 00:25:04 2022 +0000
+++ b/sys/dev/pci/hdaudio_pci.h Mon Mar 21 09:12:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hdaudio_pci.h,v 1.1 2015/03/28 14:09:59 jmcneill Exp $ */
+/* $NetBSD: hdaudio_pci.h,v 1.2 2022/03/21 09:12:09 jmcneill Exp $ */
/*
* Copyright (c) 2010 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -31,8 +31,20 @@
#ifndef _HDAUDIO_PCI_H
#define _HDAUDIO_PCI_H
-#define HDAUDIO_NV_REG_SNOOP 0x4c
-#define HDAUDIO_NV_SNOOP_MASK 0x00ff0000
-#define HDAUDIO_NV_SNOOP_ENABLE 0x000f0000
+/* NVIDIA specific registers */
+#define HDAUDIO_NV_REG_SNOOP 0x4c
+#define HDAUDIO_NV_SNOOP_MASK 0x00ff0000
+#define HDAUDIO_NV_SNOOP_ENABLE 0x000f0000
+
+/* Intel ICH specific registers */
+#define HDAUDIO_INTEL_REG_ICH_TCSEL 0x44
+#define HDAUDIO_INTEL_ICH_TCSEL_MASK __BITS(2,0)
+#define HDAUDIO_INTEL_ICH_TCSEL_TC0 0
+
+/* Intel 100 Series Chipset Family Platform Controller Hub (PCH) */
+#define HDAUDIO_INTEL_REG_PCH_CGCTL 0x48
+#define HDAUDIO_INTEL_PCH_CGCTL_MISCBDCGE __BIT(6)
+#define HDAUDIO_INTEL_REG_PCH_DEVC 0x78
+#define HDAUDIO_INTEL_PCH_DEVC_NSNPEN __BIT(11)
#endif /* !_HDAUDIO_PCI_H */
Home |
Main Index |
Thread Index |
Old Index