svn commit: r197502 - in stable/8/sys: . amd64/include/xen
cddl/contrib/opensolaris contrib/dev/acpica contrib/pf
dev/sound/pci dev/xen/xenpci
Marius Strobl
marius at FreeBSD.org
Fri Sep 25 19:59:19 UTC 2009
Author: marius
Date: Fri Sep 25 19:59:18 2009
New Revision: 197502
URL: http://svn.freebsd.org/changeset/base/197502
Log:
MFC: r197401
- According to Linux, the ALi M5451 can do 31-bit DMA instead of just
30-bit like the reset of the controllers supported by this driver.
Actually ALi M5451 can be setup up to generate 32-bit addresses by
setting the 31st bit via the accompanying ISA bridge, which allows
it to work in sparc64 machines whose IOMMU require at least 32-bit
DMA. Even though other architectures would also benefit from 32-bit
DMA, enabling this bit is limited to sparc64 as bus_dma(9) doesn't
generally guarantee that a low address of BUS_SPACE_MAXADDR_32BIT
results in a buffer in the 32-bit range.
- According to Tatsuo YOKOGAWA's ali(4), the the DMA transfer size of
ALi M5451 is fixed to 64k and in fact using the default size of 4k
causes the chip to overrun the mapping, triggering uncorrectable
DMA errors on sparc64.
- The 4DWAVE DX and NX require the recording buffer to be 8-byte
aligned so adjust the bus_dma_tag_create(9) accordingly.
- Unlike the rest of the controllers supported by this driver, the
ALi M5451 only has 32 hardware channels instead of 64 so limit the
loop in tr_intr() accordingly. [1]
Submitted by: yongari [1]
Reviewed by: yongari (superset of what is committed)
Approved by: re (kib)
Modified:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/sound/pci/t4dwave.c
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/dev/sound/pci/t4dwave.c
==============================================================================
--- stable/8/sys/dev/sound/pci/t4dwave.c Fri Sep 25 19:49:07 2009 (r197501)
+++ stable/8/sys/dev/sound/pci/t4dwave.c Fri Sep 25 19:59:18 2009 (r197502)
@@ -45,18 +45,22 @@ SND_DECLARE_FILE("$FreeBSD$");
#define SPA_PCI_ID 0x70181039
#define TR_DEFAULT_BUFSZ 0x1000
+/* For ALi M5451 the DMA transfer size appears to be fixed to 64k. */
+#define ALI_BUFSZ 0x10000
+#define TR_BUFALGN 0x8
#define TR_TIMEOUT_CDC 0xffff
+#define TR_MAXHWCH 64
+#define ALI_MAXHWCH 32
#define TR_MAXPLAYCH 4
+#define ALI_MAXPLAYCH 1
/*
- * Though, it's not clearly documented in trident datasheet, trident
- * audio cards can't handle DMA addresses located above 1GB. The LBA
- * (loop begin address) register which holds DMA base address is 32bits
- * register.
- * But the MSB 2bits are used for other purposes(I guess it is really
- * bad idea). This effectivly limits the DMA address space up to 1GB.
+ * Though, it's not clearly documented in the 4DWAVE datasheet, the
+ * DX and NX chips can't handle DMA addresses located above 1GB as the
+ * LBA (loop begin address) register which holds the DMA base address
+ * is 32-bit, but the two MSBs are used for other purposes.
*/
-#define TR_MAXADDR ((1 << 30) - 1)
-
+#define TR_MAXADDR ((1U << 30) - 1)
+#define ALI_MAXADDR ((1U << 31) - 1)
struct tr_info;
@@ -97,6 +101,7 @@ struct tr_info {
struct mtx *lock;
+ u_int32_t hwchns;
u_int32_t playchns;
unsigned int bufsz;
@@ -398,7 +403,10 @@ tr_wrch(struct tr_chinfo *ch)
ch->ec &= 0x00000fff;
ch->alpha &= 0x00000fff;
ch->delta &= 0x0000ffff;
- ch->lba &= 0x3fffffff;
+ if (tr->type == ALI_PCI_ID)
+ ch->lba &= ALI_MAXADDR;
+ else
+ ch->lba &= TR_MAXADDR;
cr[1]=ch->lba;
cr[3]=(ch->fmc<<14) | (ch->rvol<<7) | (ch->cvol);
@@ -441,7 +449,10 @@ tr_rdch(struct tr_chinfo *ch)
snd_mtxunlock(tr->lock);
- ch->lba= (cr[1] & 0x3fffffff);
+ if (tr->type == ALI_PCI_ID)
+ ch->lba=(cr[1] & ALI_MAXADDR);
+ else
+ ch->lba=(cr[1] & TR_MAXADDR);
ch->fmc= (cr[3] & 0x0000c000) >> 14;
ch->rvol= (cr[3] & 0x00003f80) >> 7;
ch->cvol= (cr[3] & 0x0000007f);
@@ -628,7 +639,6 @@ trrchan_setformat(kobj_t obj, void *data
tr_wr(tr, TR_REG_SBCTRL, i, 1);
return 0;
-
}
static u_int32_t
@@ -729,7 +739,7 @@ tr_intr(void *p)
intsrc = tr_rd(tr, TR_REG_MISCINT, 4);
if (intsrc & TR_INT_ADDR) {
chnum = 0;
- while (chnum < 64) {
+ while (chnum < tr->hwchns) {
mask = 0x00000001;
active = tr_rd(tr, (chnum < 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, 4);
bufhalf = tr_rd(tr, (chnum < 32)? TR_REG_CSPF_A : TR_REG_CSPF_B, 4);
@@ -815,8 +825,13 @@ tr_pci_attach(device_t dev)
u_int32_t data;
struct tr_info *tr;
struct ac97_info *codec = 0;
+ bus_addr_t lowaddr;
int i, dacn;
char status[SND_STATUSLEN];
+#ifdef __sparc64__
+ device_t *children;
+ int nchildren;
+#endif
tr = malloc(sizeof(*tr), M_DEVBUF, M_WAITOK | M_ZERO);
tr->type = pci_get_devid(dev);
@@ -834,7 +849,7 @@ tr_pci_attach(device_t dev)
} else {
switch (tr->type) {
case ALI_PCI_ID:
- dacn = 1;
+ dacn = ALI_MAXPLAYCH;
break;
default:
dacn = TR_MAXPLAYCH;
@@ -859,8 +874,6 @@ tr_pci_attach(device_t dev)
goto bad;
}
- tr->bufsz = pcm_getbuffersize(dev, 4096, TR_DEFAULT_BUFSZ, 65536);
-
if (tr_init(tr) == -1) {
device_printf(dev, "unable to initialize the card\n");
goto bad;
@@ -879,12 +892,59 @@ tr_pci_attach(device_t dev)
goto bad;
}
- if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
+ if (tr->type == ALI_PCI_ID) {
+ /*
+ * The M5451 generates 31 bit of DMA and in order to do
+ * 32-bit DMA, the 31st bit can be set via its accompanying
+ * ISA bridge. Note that we can't predict whether bus_dma(9)
+ * will actually supply us with a 32-bit buffer and even when
+ * using a low address of BUS_SPACE_MAXADDR_32BIT for both
+ * we might end up with the play buffer being in the 32-bit
+ * range while the record buffer isn't or vice versa. So we
+ * limit enabling the 31st bit to sparc64, where the IOMMU
+ * guarantees that we're using a 32-bit address (and in turn
+ * requires it).
+ */
+ lowaddr = ALI_MAXADDR;
+#ifdef __sparc64__
+ if (device_get_children(device_get_parent(dev), &children,
+ &nchildren) == 0) {
+ for (i = 0; i < nchildren; i++) {
+ if (pci_get_devid(children[i]) == 0x153310b9) {
+ lowaddr = BUS_SPACE_MAXADDR_32BIT;
+ data = pci_read_config(children[i],
+ 0x7e, 1);
+ if (bootverbose)
+ device_printf(dev,
+ "M1533 0x7e: 0x%x -> ",
+ data);
+ data |= 0x1;
+ if (bootverbose)
+ printf("0x%x\n", data);
+ pci_write_config(children[i], 0x7e,
+ data, 1);
+ break;
+ }
+ }
+ }
+ free(children, M_TEMP);
+#endif
+ tr->hwchns = ALI_MAXHWCH;
+ tr->bufsz = ALI_BUFSZ;
+ } else {
+ lowaddr = TR_MAXADDR;
+ tr->hwchns = TR_MAXHWCH;
+ tr->bufsz = pcm_getbuffersize(dev, 4096, TR_DEFAULT_BUFSZ,
+ 65536);
+ }
+
+ if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev),
+ /*alignment*/TR_BUFALGN,
/*boundary*/0,
- /*lowaddr*/TR_MAXADDR,
+ /*lowaddr*/lowaddr,
/*highaddr*/BUS_SPACE_MAXADDR,
/*filter*/NULL, /*filterarg*/NULL,
- /*maxsize*/tr->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
+ /*maxsize*/tr->bufsz, /*nsegments*/1, /*maxsegz*/tr->bufsz,
/*flags*/0, /*lockfunc*/busdma_lock_mutex,
/*lockarg*/&Giant, &tr->parent_dmat) != 0) {
device_printf(dev, "unable to create dma tag\n");
More information about the svn-src-stable-8
mailing list