Skip site navigation (1)Skip section navigation (2)
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>