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-all mailing list