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>