Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: USB audio on rasberry pi 2



netbsd-lists%protonmail.com@localhost (satch) writes:

>On Sunday, 15 December 2024 at 14:51, mlelstv%serpens.de@localhost <mlelstv@serpens.d=
>e> wrote:
>> I had some deeper look into the problem.


Our dwc2 driver is derived from the Linux driver which got some
significant rework in that area (isochronous transfers) in the
past. That might fix the issue.

In the meantime, here is a small patch to dwc2 that tries to handle
the split transfer and seems to work for me.

Index: sys/external/bsd/dwc2/dist/dwc2_core.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/dwc2/dist/dwc2_core.c,v
retrieving revision 1.13
diff -p -u -r1.13 dwc2_core.c
--- sys/external/bsd/dwc2/dist/dwc2_core.c	24 Feb 2016 22:17:54 -0000	1.13
+++ sys/external/bsd/dwc2/dist/dwc2_core.c	16 Dec 2024 07:16:17 -0000
@@ -2283,10 +2283,10 @@ u32 dwc2_calc_frame_interval(struct dwc2
 
 	if ((hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT == HPRT0_SPD_HIGH_SPEED)
 		/* High speed case */
-		return 125 * clock;
+		return 125 * clock - 1;
 	else
 		/* FS/LS case */
-		return 1000 * clock;
+		return 1000 * clock - 1;
 }
 
 /**
Index: sys/external/bsd/dwc2/dist/dwc2_hcdddma.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/dwc2/dist/dwc2_hcdddma.c,v
retrieving revision 1.11
diff -p -u -r1.11 dwc2_hcdddma.c
--- sys/external/bsd/dwc2/dist/dwc2_hcdddma.c	9 Apr 2023 12:31:10 -0000	1.11
+++ sys/external/bsd/dwc2/dist/dwc2_hcdddma.c	16 Dec 2024 07:16:17 -0000
@@ -1029,10 +1029,8 @@ static void dwc2_complete_isoc_xfer_ddma
 			if (!rc)
 				continue;
 
-			if (rc == DWC2_CMPL_DONE)
-				break;
-
-			/* rc == DWC2_CMPL_STOP */
+			if (rc == DWC2_CMPL_DONE || rc == DWC2_CMPL_STOP)
+				goto stop_scan;
 
 			if (qh->interval >= 32)
 				goto stop_scan;
Index: sys/external/bsd/dwc2/dist/dwc2_hcdintr.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/dwc2/dist/dwc2_hcdintr.c,v
retrieving revision 1.15
diff -p -u -r1.15 dwc2_hcdintr.c
--- sys/external/bsd/dwc2/dist/dwc2_hcdintr.c	12 Aug 2018 09:59:30 -0000	1.15
+++ sys/external/bsd/dwc2/dist/dwc2_hcdintr.c	16 Dec 2024 07:16:17 -0000
@@ -575,6 +575,7 @@ static enum dwc2_halt_status dwc2_update
 {
 	struct dwc2_hcd_iso_packet_desc *frame_desc;
 	struct dwc2_hcd_urb *urb = qtd->urb;
+	u32 len;
 
 	if (!urb)
 		return DWC2_HC_XFER_NO_HALT_STATUS;
@@ -584,11 +585,11 @@ static enum dwc2_halt_status dwc2_update
 	switch (halt_status) {
 	case DWC2_HC_XFER_COMPLETE:
 		frame_desc->status = 0;
-		frame_desc->actual_length = dwc2_get_actual_xfer_length(hsotg,
-					chan, chnum, qtd, halt_status, NULL);
+		len = dwc2_get_actual_xfer_length(hsotg,
+			chan, chnum, qtd, halt_status, NULL);
 
 		/* Non DWORD-aligned buffer case handling */
-		if (chan->align_buf && frame_desc->actual_length) {
+		if (chan->align_buf && len) {
 			dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n",
 				 __func__);
 			usb_dma_t *ud = &chan->qh->dw_align_buf_usbdma;
@@ -600,11 +601,17 @@ static enum dwc2_halt_status dwc2_update
 				memcpy(urb->buf + frame_desc->offset +
 					qtd->isoc_split_offset,
 					chan->qh->dw_align_buf,
-					frame_desc->actual_length);
+					len);
 			usb_syncmem(ud, 0, chan->qh->dw_align_buf_size,
 			    chan->ep_is_in ?
 			    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
 		}
+
+		frame_desc->actual_length += len;
+
+		if (qtd->isoc_split_pos != DWC2_HCSPLT_XACTPOS_ALL)
+			return DWC2_HC_XFER_COMPLETE;
+
 		break;
 	case DWC2_HC_XFER_FRAME_OVERRUN:
 		urb->error_count++;
@@ -1126,11 +1133,10 @@ static void dwc2_hc_xfercomp_intr(struct
 	case USB_ENDPOINT_XFER_ISOC:
 		if (dbg_perio())
 			dev_vdbg(hsotg->dev, "  Isochronous transfer complete\n");
-		if (qtd->isoc_split_pos == DWC2_HCSPLT_XACTPOS_ALL)
-			halt_status = dwc2_update_isoc_urb_state(hsotg, chan,
-					chnum, qtd, DWC2_HC_XFER_COMPLETE);
+		halt_status = dwc2_update_isoc_urb_state(hsotg, chan,
+		    chnum, qtd, DWC2_HC_XFER_COMPLETE);
 		dwc2_complete_periodic_xfer(hsotg, chan, chnum, qtd,
-					    halt_status);
+		    halt_status);
 		break;
 	}
 


Home | Main Index | Thread Index | Old Index