Hi, yfw <[email protected]> writes: >>>>>>>>>>>> Does this mean the issue of isoc high bandwidth transfer was fixed >>>>>>>>>>>> by >>>>>>>>>>>> this patchset per your test? >>>>>>>>>>> >>>>>>>>>>> No, I couldn't get g_webcam to work yet. >>>>>>>>>> >>>>>>>>>> In mainline, g_webcam is broken with DWC3. Also these two patches >>>>>>>>>> don't >>>>>>>>>> fix the issue on v4.4.21. >>>>>>>>> >>>>>>>>> care to send tracepoint output? Best if you could cherry pick my >>>>>>>>> latest >>>>>>>>> tracepoint changes so we have the best output possible. >>>>>>>>> >>>>>>>>> I have also built a branch with v4.4.21 + all dwc3 patches (except for >>>>>>>>> device properties and PCI stuff) which you could use for testing. If >>>>>>>>> you >>>>>>>>> run with that, then I can get proper trace output and I can try to >>>>>>>>> figure out what's missing. >>>>>>>>> >>>>>>>>> Branch is here: >>>>>>>>> >>>>>>>>> git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git >>>>>>>>> usb/v4.4.21+dwc3 >>>>>>>> >>>>>>>> This branch does not generate the isoch traffic (on ep2in). ftrace >>>>>>>> attached (dwc3-g_webcam-v4.4.21+tp.ftrace). >>>>>>>> >>>>>>>> I also attached the ftrace log for v4.4.21 tag >>>>>>>> (dwc3-g_webcam-v4.4.21.ftrace) for comparison, which has ep2in isoch >>>>>>>> traffic, but only one transaction per SOF. >>>>>>> >>>>>>> Sorry, I didn't realize the ftrace file size is huge. Attached the >>>>>>> tarball here. >>>>>> >>>>>> looking at webcam.c, it'll set wMaxPacket correctly (to 0x1400) if you >>>>>> pass streaming_maxpacket=3072. So that's one thing. >>>>>> >>>>>> I'll look at this log with more detail tomorrow, though. >>>>> >>>>> here's a bug in composite.c because of a bug in usb_endpoint_maxp(). >>>>> >>>>> diff --git a/drivers/usb/gadget/composite.c >>>>> b/drivers/usb/gadget/composite.c >>>>> index 32176f779861..f6a7583ab6d1 100644 >>>>> --- a/drivers/usb/gadget/composite.c >>>>> +++ b/drivers/usb/gadget/composite.c >>>>> @@ -197,7 +197,7 @@ int config_ep_by_speed(struct usb_gadget *g, >>>>> >>>>> ep_found: >>>>> /* commit results */ >>>>> - _ep->maxpacket = usb_endpoint_maxp(chosen_desc); >>>>> + _ep->maxpacket = usb_endpoint_maxp(chosen_desc) & 0x7ff; >>>> >>>> uvc_video set the each request size (you could check function >>>> uvc_video_alloc_requests()) for uvc: >>>> req_size = video->ep->maxpacket >>>> * max_t(unsigned int, video->ep->maxburst, 1) >>>> * (video->ep->mult + 1); >>>> >>>> >>>> If we change the ep->maxpacket like this, uvc layer will only set the >>>> req size to 1024 (while it should be 3072 if we want to use high >>>> bindwidth isoc transfer). >>> >>> it'll be 1024 * (mult + 1). Hmm, mult isn't set for highspeed isoc >>> endpoints. So here you go: >> >> Great! all the 4 patches you sent so far fix the issue on v4.4.21 tag! >> Now I see 3 1024-bytes transactions in each SOF. > Great news. But the same changes still can't work in my side. I need to > look at other registers. > > Do you mind dumping the dwc3 registers in your side and share to me? Thanks > in advance.
tracepoints contain all that information. We trace every single register
access.
Frankly, I think you'd be much better off trying to cherry-pick changes
back to your kernel.
Now I need to find a way to get g_webcam working with today's mainline
so I can test this periodically. Bin, what else did you change in
uvc-gadget.c? Here's what I have:
diff --git a/uvc-gadget.c b/uvc-gadget.c
index 9ef315cf0166..26ce9cdf4ea5 100644
--- a/uvc-gadget.c
+++ b/uvc-gadget.c
@@ -319,7 +319,7 @@ struct uvc_format_info
};
static const struct uvc_frame_info uvc_frames_yuyv[] = {
- { 640, 360, { 666666, 10000000, 50000000, 0 }, },
+ { 640, 480, { 333333, 666666, 1000000, 0 }, },
{ 1280, 720, { 50000000, 0 }, },
{ 0, 0, { 0, }, },
};
@@ -397,6 +397,8 @@ uvc_events_process_control(struct uvc_device *dev, uint8_t
req, uint8_t cs,
printf("control request (req %02x cs %02x)\n", req, cs);
(void)dev;
(void)resp;
+
+ resp->length = 0;
}
static void
@@ -732,6 +734,9 @@ int main(int argc, char *argv[])
fd_set wfds = fds;
ret = select(dev->fd + 1, NULL, &wfds, &efds, NULL);
+ if (ret < 0)
+ fprintf(stderr, "Select failed: %s\n", strerror(errno));
+
if (FD_ISSET(dev->fd, &efds))
uvc_events_process(dev);
if (FD_ISSET(dev->fd, &wfds))
I also have this quick hack in webcam gadget:
diff --git a/drivers/usb/gadget/function/f_uvc.c
b/drivers/usb/gadget/function/f_uvc.c
index 29b41b5dee04..935fd76ba83e 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -396,6 +399,9 @@ uvc_function_connect(struct uvc_device *uvc)
struct usb_composite_dev *cdev = uvc->func.config->cdev;
int ret;
+ if (cdev->deactivations == 0)
+ return;
+
if ((ret = usb_function_activate(&uvc->func)) < 0)
INFO(cdev, "UVC connect failed with %d\n", ret);
}
diff --git a/drivers/usb/gadget/function/uvc_v4l2.c
b/drivers/usb/gadget/function/uvc_v4l2.c
index f4ccbd56f4d2..6c0ac0525b80 100644
--- a/drivers/usb/gadget/function/uvc_v4l2.c
+++ b/drivers/usb/gadget/function/uvc_v4l2.c
@@ -298,7 +300,6 @@ uvc_v4l2_open(struct file *file)
handle->device = &uvc->video;
file->private_data = &handle->vfh;
- uvc_function_connect(uvc);
return 0;
}
@@ -340,6 +341,7 @@ uvc_v4l2_poll(struct file *file, poll_table *wait)
struct video_device *vdev = video_devdata(file);
struct uvc_device *uvc = video_get_drvdata(vdev);
+ uvc_function_connect(uvc);
return uvcg_queue_poll(&uvc->video.queue, file, wait);
}
diff --git a/drivers/usb/gadget/legacy/webcam.c
b/drivers/usb/gadget/legacy/webcam.c
index 72c976bf3530..bfbe7f10175a 100644
--- a/drivers/usb/gadget/legacy/webcam.c
+++ b/drivers/usb/gadget/legacy/webcam.c
@@ -191,15 +191,15 @@ static const struct UVC_FRAME_UNCOMPRESSED(3)
uvc_frame_yuv_360p = {
.bFrameIndex = 1,
.bmCapabilities = 0,
.wWidth = cpu_to_le16(640),
- .wHeight = cpu_to_le16(360),
+ .wHeight = cpu_to_le16(480),
.dwMinBitRate = cpu_to_le32(18432000),
.dwMaxBitRate = cpu_to_le32(55296000),
- .dwMaxVideoFrameBufferSize = cpu_to_le32(460800),
- .dwDefaultFrameInterval = cpu_to_le32(666666),
+ .dwMaxVideoFrameBufferSize = cpu_to_le32(614400),
+ .dwDefaultFrameInterval = cpu_to_le32(333333),
.bFrameIntervalType = 3,
- .dwFrameInterval[0] = cpu_to_le32(666666),
- .dwFrameInterval[1] = cpu_to_le32(1000000),
- .dwFrameInterval[2] = cpu_to_le32(5000000),
+ .dwFrameInterval[0] = cpu_to_le32(333333),
+ .dwFrameInterval[1] = cpu_to_le32(666666),
+ .dwFrameInterval[2] = cpu_to_le32(1000000),
};
static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
Still no luck. I'll continue hacking on this tomorrow.
--
balbi
signature.asc
Description: PGP signature
