summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorariff <ariff@FreeBSD.org>2007-07-09 20:42:11 +0000
committerariff <ariff@FreeBSD.org>2007-07-09 20:42:11 +0000
commit0e85be48ad07f5f5fd02e483f0c2e935c4338941 (patch)
treeb71c20ee1023a84efc3116e580e5d54315d1290e
parentb4aac62135e0cf64cd595db2f860f0a9c7b6e960 (diff)
downloadFreeBSD-src-0e85be48ad07f5f5fd02e483f0c2e935c4338941.zip
FreeBSD-src-0e85be48ad07f5f5fd02e483f0c2e935c4338941.tar.gz
- Add codec id for Realtek ALC268.
- Add controller id for Intel 82801I (ICH9). PR: kern/114399 Submitted by: Michael Fuckner <michael@fuckner.net> - MSI support. Disable by default due to various issues with too many broken hardwares. MSI can be enabled through device.hints(5) or kenv(8) by setting "hint.pcm.%d.msi=1". Partially submitted by: kevlo YAMAMOTO Taku <taku@tackymt.homeip.net> Tested by: joel, kevlo, YAMAMOTO Taku Approved by: re (hrs) MFC after: 3 days
-rw-r--r--sys/dev/sound/pci/hda/hdac.c64
-rw-r--r--sys/dev/sound/pci/hda/hdac_private.h11
2 files changed, 57 insertions, 18 deletions
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index f4b1761..6441304 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -81,7 +81,7 @@
#include "mixer_if.h"
-#define HDA_DRV_TEST_REV "20070702_0046"
+#define HDA_DRV_TEST_REV "20070710_0047"
#define HDA_WIDGET_PARSER_REV 1
SND_DECLARE_FILE("$FreeBSD$");
@@ -131,9 +131,10 @@ SND_DECLARE_FILE("$FreeBSD$");
/* Intel */
#define INTEL_VENDORID 0x8086
#define HDA_INTEL_82801F HDA_MODEL_CONSTRUCT(INTEL, 0x2668)
+#define HDA_INTEL_63XXESB HDA_MODEL_CONSTRUCT(INTEL, 0x269a)
#define HDA_INTEL_82801G HDA_MODEL_CONSTRUCT(INTEL, 0x27d8)
#define HDA_INTEL_82801H HDA_MODEL_CONSTRUCT(INTEL, 0x284b)
-#define HDA_INTEL_63XXESB HDA_MODEL_CONSTRUCT(INTEL, 0x269a)
+#define HDA_INTEL_82801I HDA_MODEL_CONSTRUCT(INTEL, 0x293e)
#define HDA_INTEL_ALL HDA_MODEL_CONSTRUCT(INTEL, 0xffff)
/* Nvidia */
@@ -398,9 +399,10 @@ static const struct {
char *desc;
} hdac_devices[] = {
{ HDA_INTEL_82801F, "Intel 82801F" },
+ { HDA_INTEL_63XXESB, "Intel 631x/632xESB" },
{ HDA_INTEL_82801G, "Intel 82801G" },
{ HDA_INTEL_82801H, "Intel 82801H" },
- { HDA_INTEL_63XXESB, "Intel 631x/632xESB" },
+ { HDA_INTEL_82801I, "Intel 82801I" },
{ HDA_NVIDIA_MCP51, "NVidia MCP51" },
{ HDA_NVIDIA_MCP55, "NVidia MCP55" },
{ HDA_NVIDIA_MCP61A, "NVidia MCP61A" },
@@ -486,6 +488,7 @@ static const struct {
#define REALTEK_VENDORID 0x10ec
#define HDA_CODEC_ALC260 HDA_CODEC_CONSTRUCT(REALTEK, 0x0260)
#define HDA_CODEC_ALC262 HDA_CODEC_CONSTRUCT(REALTEK, 0x0262)
+#define HDA_CODEC_ALC268 HDA_CODEC_CONSTRUCT(REALTEK, 0x0268)
#define HDA_CODEC_ALC660 HDA_CODEC_CONSTRUCT(REALTEK, 0x0660)
#define HDA_CODEC_ALC861 HDA_CODEC_CONSTRUCT(REALTEK, 0x0861)
#define HDA_CODEC_ALC861VD HDA_CODEC_CONSTRUCT(REALTEK, 0x0862)
@@ -558,6 +561,7 @@ static const struct {
} hdac_codecs[] = {
{ HDA_CODEC_ALC260, "Realtek ALC260" },
{ HDA_CODEC_ALC262, "Realtek ALC262" },
+ { HDA_CODEC_ALC268, "Realtek ALC268" },
{ HDA_CODEC_ALC660, "Realtek ALC660" },
{ HDA_CODEC_ALC861, "Realtek ALC861" },
{ HDA_CODEC_ALC861VD, "Realtek ALC861-VD" },
@@ -1077,7 +1081,7 @@ hdac_stream_intr(struct hdac_softc *sc, struct hdac_chan *ch)
uint32_t res;
#endif
- if (ch->blkcnt == 0)
+ if (!(ch->flags & HDAC_CHN_RUNNING))
return (0);
/* XXX to be removed */
@@ -1387,7 +1391,8 @@ hdac_dma_alloc(struct hdac_softc *sc, struct hdac_dma *dma, bus_size_t size)
*/
result = bus_dmamem_alloc(dma->dma_tag, (void **)&dma->dma_vaddr,
BUS_DMA_NOWAIT | BUS_DMA_ZERO |
- ((sc->nocache != 0) ? BUS_DMA_NOCACHE : 0), &dma->dma_map);
+ ((sc->flags & HDAC_F_DMA_NOCACHE) ? BUS_DMA_NOCACHE : 0),
+ &dma->dma_map);
if (result != 0) {
device_printf(sc->dev, "%s: bus_dmamem_alloc failed (%x)\n",
__func__, result);
@@ -1508,6 +1513,16 @@ hdac_irq_alloc(struct hdac_softc *sc)
irq = &sc->irq;
irq->irq_rid = 0x0;
+
+#if __FreeBSD_version >= 602106
+ if ((sc->flags & HDAC_F_MSI) &&
+ (result = pci_msi_count(sc->dev)) == 1 &&
+ pci_alloc_msi(sc->dev, &result) == 0)
+ irq->irq_rid = 0x1;
+ else
+#endif
+ sc->flags &= ~HDAC_F_MSI;
+
irq->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
&irq->irq_rid, RF_SHAREABLE | RF_ACTIVE);
if (irq->irq_res == NULL) {
@@ -1548,8 +1563,13 @@ 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 __FreeBSD_version >= 602106
+ if ((sc->flags & HDAC_F_MSI) && irq->irq_rid == 0x1)
+ pci_release_msi(sc->dev);
+#endif
irq->irq_handle = NULL;
irq->irq_res = NULL;
+ irq->irq_rid = 0x0;
}
/****************************************************************************
@@ -2373,7 +2393,7 @@ hda_poll_channel(struct hdac_chan *ch)
uint32_t sz, delta;
volatile uint32_t ptr;
- if (ch->active == 0)
+ if (!(ch->flags & HDAC_CHN_RUNNING))
return (0);
sz = ch->blksz * ch->blkcnt;
@@ -2395,7 +2415,8 @@ hda_poll_channel(struct hdac_chan *ch)
return (1);
}
-#define hda_chan_active(sc) ((sc)->play.active + (sc)->rec.active)
+#define hda_chan_active(sc) (((sc)->play.flags | (sc)->rec.flags) & \
+ HDAC_CHN_RUNNING)
static void
hda_poll_callback(void *arg)
@@ -2524,7 +2545,7 @@ hdac_stream_stop(struct hdac_chan *ch)
HDAC_SDCTL_RUN);
HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl);
- ch->active = 0;
+ ch->flags &= ~HDAC_CHN_RUNNING;
if (sc->polling != 0) {
int pollticks;
@@ -2533,7 +2554,7 @@ hdac_stream_stop(struct hdac_chan *ch)
callout_stop(&sc->poll_hda);
sc->poll_ticks = 1;
} else {
- if (sc->play.active != 0)
+ if (sc->play.flags & HDAC_CHN_RUNNING)
ch = &sc->play;
else
ch = &sc->rec;
@@ -2621,7 +2642,7 @@ hdac_stream_start(struct hdac_chan *ch)
}
HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl);
- ch->active = 1;
+ ch->flags |= HDAC_CHN_RUNNING;
}
static void
@@ -2992,7 +3013,8 @@ hdac_channel_init(kobj_t obj, void *data, struct snd_dbuf *b,
}
if (sndbuf_alloc(ch->b, sc->chan_dmat,
- (sc->nocache != 0) ? BUS_DMA_NOCACHE : 0, sc->chan_size) != 0)
+ (sc->flags & HDAC_F_DMA_NOCACHE) ? BUS_DMA_NOCACHE : 0,
+ sc->chan_size) != 0)
return (NULL);
return (ch);
@@ -3708,13 +3730,22 @@ hdac_attach(device_t dev)
);
}
+#if __FreeBSD_version >= 602106
+ if (resource_int_value(device_get_name(dev),
+ device_get_unit(dev), "msi", &i) == 0 && i != 0 &&
+ pci_msi_count(dev) == 1)
+ sc->flags |= HDAC_F_MSI;
+ else
+#endif
+ sc->flags &= ~HDAC_F_MSI;
+
#if defined(__i386__) || defined(__amd64__)
- sc->nocache = 1;
+ sc->flags |= HDAC_F_DMA_NOCACHE;
if (resource_int_value(device_get_name(dev),
device_get_unit(dev), "snoop", &i) == 0 && i != 0) {
#else
- sc->nocache = 0;
+ sc->flags &= ~HDAC_F_DMA_NOCACHE;
#endif
/*
* Try to enable PCIe snoop to avoid messing around with
@@ -3729,7 +3760,7 @@ hdac_attach(device_t dev)
for (i = 0; i < HDAC_PCIESNOOP_LEN; i++) {
if (hdac_pcie_snoop[i].vendor != vendor)
continue;
- sc->nocache = 0;
+ sc->flags &= ~HDAC_F_DMA_NOCACHE;
if (hdac_pcie_snoop[i].reg == 0x00)
break;
v = pci_read_config(dev, hdac_pcie_snoop[i].reg, 1);
@@ -3748,7 +3779,7 @@ hdac_attach(device_t dev)
"snoop!\n");
);
#if defined(__i386__) || defined(__amd64__)
- sc->nocache = 1;
+ sc->flags |= HDAC_F_DMA_NOCACHE;
#endif
}
break;
@@ -3759,7 +3790,8 @@ hdac_attach(device_t dev)
HDA_BOOTVERBOSE(
device_printf(dev, "DMA Coherency: %s / vendor=0x%04x\n",
- (sc->nocache == 0) ? "PCIe snoop" : "Uncacheable", vendor);
+ (sc->flags & HDAC_F_DMA_NOCACHE) ?
+ "Uncacheable" : "PCIe snoop", vendor);
);
/* Allocate resources */
diff --git a/sys/dev/sound/pci/hda/hdac_private.h b/sys/dev/sound/pci/hda/hdac_private.h
index d003d21..dd8d3c4 100644
--- a/sys/dev/sound/pci/hda/hdac_private.h
+++ b/sys/dev/sound/pci/hda/hdac_private.h
@@ -260,6 +260,9 @@ struct hdac_devinfo {
} function;
};
+#define HDAC_CHN_RUNNING 0x00000001
+#define HDAC_CHN_SUSPEND 0x00000002
+
struct hdac_chan {
struct snd_dbuf *b;
struct pcm_channel *c;
@@ -270,7 +273,7 @@ struct hdac_chan {
uint32_t supp_stream_formats, supp_pcm_size_rate;
uint32_t ptr, prevptr, blkcnt, blksz;
uint32_t *dmapos;
- int active;
+ uint32_t flags;
int dir;
int off;
int sid;
@@ -283,6 +286,10 @@ struct hdac_chan {
*
* This structure holds the current state of the hdac driver.
****************************************************************************/
+
+#define HDAC_F_DMA_NOCACHE 0x00000001
+#define HDAC_F_MSI 0x00000002
+
struct hdac_softc {
device_t dev;
device_t hdabus;
@@ -294,7 +301,7 @@ struct hdac_softc {
struct hdac_irq irq;
uint32_t pci_subvendor;
- int nocache;
+ uint32_t flags;
int num_iss;
int num_oss;
OpenPOWER on IntegriCloud