Date: Mon, 2 Jul 2007 23:11:57 +0900 From: "YAMAMOTO, Taku" <taku@tackymt.homeip.net> To: freebsd-multimedia@freebsd.org Subject: [PATCH] snd_hda resume + MSI Message-ID: <20070702231157.dd465e9f.taku@tackymt.homeip.net>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--Multipart=_Mon__2_Jul_2007_23_11_57_+0900_ZHkOoSDFApI.I+6I
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Greetings,
I've made a couple of patches for snd_hda:
1. It reinitializes the hardware after resume.
Otherwise my ThinkPad X60 won't make a noise after resume.
2. It utilizes MSI for interrupt delivery.
To isolate the interrupt line shared with MP-unsafe devices such as
uhci.
Neither patches are depending on each other; one can apply either one
without another.
Of cource, both of the two can be applied at the same time.
Enjoy!
--
YAMAMOTO, Taku <taku@tackymt.homeip.net>
--Multipart=_Mon__2_Jul_2007_23_11_57_+0900_ZHkOoSDFApI.I+6I
Content-Type: text/x-diff;
name="snd_hda-resume.patch"
Content-Disposition: attachment;
filename="snd_hda-resume.patch"
Content-Transfer-Encoding: 7bit
--- sys/dev/sound/pci/hda/hdac.c.orig Sun Jan 28 12:16:54 2007
+++ sys/dev/sound/pci/hda/hdac.c Sun Feb 4 16:46:32 2007
@@ -5370,11 +5370,95 @@ hdac_detach(device_t dev)
return (0);
}
+#if 0
+/****************************************************************************
+ * int hdac_suspend(device_t)
+ *
+ * Prepare for system suspending.
+ * Stops all DMA engines and interrupts for the safety.
+ ****************************************************************************/
+static int
+hdac_suspend(device_t dev)
+{
+ struct hdac_softc *sc = NULL;
+ struct hdac_devinfo *devinfo = NULL;
+
+ devinfo = (struct hdac_devinfo *)pcm_getdevinfo(dev);
+ if (devinfo != NULL && devinfo->codec != NULL)
+ sc = devinfo->codec->sc;
+ if (sc == NULL)
+ return (0);
+
+ hdac_lock(sc);
+ hdac_reset(sc);
+ /* XXX - TODO: stop playback and record channels if running */
+ hdac_unlock(sc);
+
+ return (0);
+}
+#endif
+
+/****************************************************************************
+ * int hdac_resume(device_t)
+ *
+ * Bring the card back to the operational state.
+ * What we do is basically the same what hdac_attach() and hdac_attach2() do,
+ * sans descriptor parsing and node-graph reconstruction.
+ ****************************************************************************/
+static int
+hdac_resume(device_t dev)
+{
+ struct hdac_softc *sc = NULL;
+ struct hdac_devinfo *devinfo = NULL;
+
+ devinfo = pcm_getdevinfo(dev);
+ if (devinfo != NULL && devinfo->codec != NULL)
+ sc = devinfo->codec->sc;
+ if (sc == NULL)
+ return (0);
+ hdac_lock(sc);
+
+ /* Quiesce everything */
+ hdac_reset(sc);
+
+ /* Disable PCI-Express QOS */
+ pci_write_config(sc->dev, 0x44,
+ pci_read_config(sc->dev, 0x44, 1) & 0xf8, 1);
+
+ /* Initialize the CORB and RIRB */
+ hdac_corb_init(sc);
+ hdac_rirb_init(sc);
+
+ /* Restart the CORB and RIRB engines */
+ hdac_corb_start(sc);
+ hdac_rirb_start(sc);
+ if (sc->polling == 0)
+ HDAC_WRITE_4(&sc->mem, HDAC_INTCTL,
+ HDAC_INTCTL_CIE | HDAC_INTCTL_GIE);
+ HDAC_WRITE_4(&sc->mem, HDAC_GCTL, HDAC_READ_4(&sc->mem, HDAC_GCTL) |
+ HDAC_GCTL_UNSOL);
+
+ DELAY(1000);
+
+ hdac_audio_commit(devinfo, HDA_COMMIT_ALL);
+ hdac_audio_ctl_commit(devinfo);
+
+ /* XXX - TODO: restart playback and/or record channels if necessary */
+
+ hdac_unlock(sc);
+
+ /*mixer_reinit(dev);*/
+
+ return (0);
+}
+
static device_method_t hdac_methods[] = {
/* device interface */
DEVMETHOD(device_probe, hdac_probe),
DEVMETHOD(device_attach, hdac_attach),
DEVMETHOD(device_detach, hdac_detach),
+ /*DEVMETHOD(device_suspend, hdac_suspend),*/
+ DEVMETHOD(device_resume, hdac_resume),
{ 0, 0 }
};
--Multipart=_Mon__2_Jul_2007_23_11_57_+0900_ZHkOoSDFApI.I+6I
Content-Type: text/x-diff;
name="snd_hda-msi.patch"
Content-Disposition: attachment;
filename="snd_hda-msi.patch"
Content-Transfer-Encoding: 7bit
--- sys/dev/sound/pci/hda/hdac.c.orig Sun Jan 28 12:16:54 2007
+++ sys/dev/sound/pci/hda/hdac.c Wed Feb 14 05:07:01 2007
@@ -1297,9 +1297,14 @@ hdac_irq_alloc(struct hdac_softc *sc)
{
struct hdac_irq *irq;
int result;
+ int msicnt;
irq = &sc->irq;
- irq->irq_rid = 0x0;
+ msicnt = pci_msi_count(sc->dev);
+ if (msicnt == 1 && pci_alloc_msi(sc->dev, &msicnt) == 0)
+ irq->irq_rid = 0x1;
+ else
+ irq->irq_rid = 0x0;
irq->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
&irq->irq_rid, RF_SHAREABLE | RF_ACTIVE);
if (irq->irq_res == NULL) {
@@ -1340,6 +1345,8 @@ hdac_irq_free(struct hdac_softc *sc)
if (irq->irq_res != NULL)
bus_release_resource(sc->dev, SYS_RES_IRQ, irq->irq_rid,
irq->irq_res);
+ if (irq->irq_rid == 0x01)
+ pci_release_msi(sc->dev);
irq->irq_handle = NULL;
irq->irq_res = NULL;
}
--Multipart=_Mon__2_Jul_2007_23_11_57_+0900_ZHkOoSDFApI.I+6I--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070702231157.dd465e9f.taku>
