Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp4057643pxb; Mon, 1 Feb 2021 11:13:27 -0800 (PST) X-Google-Smtp-Source: ABdhPJymYDw9wKXO71hvdonsBi2UrVwLhC5bzeM6ufSzBVtO6/Pi7fkZGzZmiNYHSCRAFXR/eNgB X-Received: by 2002:a05:6402:10ce:: with SMTP id p14mr20388047edu.261.1612206806813; Mon, 01 Feb 2021 11:13:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612206806; cv=none; d=google.com; s=arc-20160816; b=Xw2yhtjjAQoGOpHzGa98AS+QTchnk85o7WbXrQZUaVliKQnqVKYJvWsnBTJvOt67mU MExJXSuNVRghlbRy0GmLYvLUFjGK80yADlfeQ8X/tAlnorF7JcIsjZkKvaWtYBM7+Bvl Im37i3PZrUZKdORk04Tthm8LDXjz/GqVDDUjl703GRcr2pV517UsGl/qOquLWheT4Sez 6EpadBjG3kLau88JMUPWjueHVI1wJPIwI2gh0Y/Kle+lOYkn4yJUxZGPJgw8Dc1H1SxD 7VhDP/Y5DaNW5u14vnBHYKish86SIiJodsaM5AHw4SIX0vrdP1KVKnoVfDcmTJp5LFzA 9rJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=hfRHwAGKbB2/uMbDGI/pTent5KOqGMuSP+OFOJxoO1s=; b=BIgTRvgOyxKTh8jhU6FoSDrgUesvm5eX8HooOduh+Wq6c1EM5f+ojcaaF8dcECk22b EMVoAUKfvuPHBbsDeQ0+92qC6v8c7gA6tsU1GSOzsCENBvV5H1C21Qxnf9lu3Cgd2cOK qNyzrY7Y3+gycdwjK6ZspFwUuyUikNvRT8nzCE2bX8qNqCSie0RbOYu0I87oN98SAzY0 Hk6TjzpdyxHL6TR17nk1q/VL3hVMUs1IMew9WTs3eCzg94xHkRP1gr8PrJOiMACkmjL1 H/Ja9qRdcReUg+O9SKbn5lNyplFL0QjaNfTK1F8BvF+vgJhUgu3q64KCTP5mRIYqnETj TOAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="bxFD/N7/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g16si11672248edv.364.2021.02.01.11.12.53; Mon, 01 Feb 2021 11:13:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="bxFD/N7/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231360AbhBATJp (ORCPT + 99 others); Mon, 1 Feb 2021 14:09:45 -0500 Received: from mail.kernel.org ([198.145.29.99]:39344 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230298AbhBATJo (ORCPT ); Mon, 1 Feb 2021 14:09:44 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id D383164E24; Mon, 1 Feb 2021 19:09:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1612206544; bh=VG9mPOtHquxNPBKnhHB+LOqEx1qe2BWhHRznBKT4Igc=; h=From:To:Cc:Subject:Date:From; b=bxFD/N7/oWqJ06XkQFYjmyxnf5kLAG/QYwQpe8vMqbKTH1GzCQZEq3eDVxrG/GiJO ZrhGplskzsMM/+KhMHPE3b7do07fEsgAdhGcUMMhid15jvkXcK2Uds9kHdHO5xqbcZ ehUSnrXTUxhamq+QGyUApQsz4VS3PJzUS7XweTfPD2F+enp0UojThlVfZ7OkqLKvZG FjDuyMpKPRy/qDVqrjdjtt8sPdPwyKyBBjYvt8OT04fSORPIRlMfJYlilwgljfbEq+ 8UFIaxwBX/TnbORHe6NwVMy6RPk6WMxn7I4xTywTBKWz7qmAXMIsXT6Xfu34Y/rquV B8FgsEnpjZ2Vg== Received: by mail.kernel.org with local (Exim 4.94) (envelope-from ) id 1l6eZJ-000M4m-9a; Mon, 01 Feb 2021 20:09:01 +0100 From: Mauro Carvalho Chehab To: Linux Media Mailing List , Laurent Pinchart Cc: linuxarm@huawei.com, mauro.chehab@huawei.com, Mauro Carvalho Chehab , Mauro Carvalho Chehab , linux-kernel@vger.kernel.org Subject: [PATCH] media: uvc: limit max bandwidth for HDMI capture Date: Mon, 1 Feb 2021 20:08:59 +0100 Message-Id: X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: Mauro Carvalho Chehab Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This device: 534d:2109 MacroSilicon Announces that it supports several frame intervals for their resolutions for MJPEG compression: VideoStreaming Interface Descriptor: bLength 46 bDescriptorType 36 bDescriptorSubtype 7 (FRAME_MJPEG) bFrameIndex 1 bmCapabilities 0x00 Still image unsupported wWidth 1920 wHeight 1080 dwMinBitRate 768000 dwMaxBitRate 196608000 dwMaxVideoFrameBufferSize 4147200 dwDefaultFrameInterval 166666 bFrameIntervalType 5 dwFrameInterval( 0) 166666 dwFrameInterval( 1) 333333 dwFrameInterval( 2) 400000 dwFrameInterval( 3) 500000 dwFrameInterval( 4) 1000000 However, the highest frame interval (166666), which means 60 fps is not supported. For such resolution, the maximum interval is, instead 333333 (30 fps). The last format that supports such frame interval is 1280x720. Add a quirk to estimate a raw bandwidth, by doing: width * height * framerate E. g.: 1920 * 1080 * 30 = 62208000 if the bandwidth is greater than such threshold, get the next value from the dwFrameInterval. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 15 +++++++++++++++ drivers/media/usb/uvc/uvc_video.c | 26 +++++++++++++++++++++++--- drivers/media/usb/uvc/uvcvideo.h | 2 ++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 1abc122a0977..c83a329f6527 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2339,6 +2339,7 @@ static int uvc_probe(struct usb_interface *intf, dev->info = info ? info : &uvc_quirk_none; dev->quirks = uvc_quirks_param == -1 ? dev->info->quirks : uvc_quirks_param; + dev->max_bandwidth = dev->info->max_bandwidth; if (id->idVendor && id->idProduct) uvc_dbg(dev, PROBE, "Probing known UVC device %s (%04x:%04x)\n", @@ -2615,6 +2616,11 @@ static const struct uvc_device_info uvc_quirk_fix_bandwidth = { .quirks = UVC_QUIRK_FIX_BANDWIDTH, }; +static const struct uvc_device_info uvc_quirk_fix_bw_622 = { + .quirks = UVC_QUIRK_FIX_BANDWIDTH, + .max_bandwidth = 62208000, +}; + static const struct uvc_device_info uvc_quirk_probe_def = { .quirks = UVC_QUIRK_PROBE_DEF, }; @@ -2830,6 +2836,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth }, + /* MacroSilicon HDMI capture */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x534d, + .idProduct = 0x2109, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bw_622 }, /* Genesys Logic USB 2.0 PC Camera */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index f2f565281e63..4afc1fbe0801 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -162,9 +162,29 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, if ((ctrl->dwMaxPayloadTransferSize & 0xffff0000) == 0xffff0000) ctrl->dwMaxPayloadTransferSize &= ~0xffff0000; - if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) && - stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && - stream->intf->num_altsetting > 1) { + + if (!(stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH)) + return; + + /* Handle UVC_QUIRK_FIX_BANDWIDTH */ + + if (format->flags & UVC_FMT_FLAG_COMPRESSED && + stream->dev->max_bandwidth && frame->bFrameIntervalType) { + u32 bandwidth; + + for (i = 0; i < frame->bFrameIntervalType - 1; ++i) { + bandwidth = frame->wWidth * frame->wHeight; + bandwidth *= 10000000 / frame->dwFrameInterval[i]; + + if (bandwidth <= stream->dev->max_bandwidth) + break; + } + + ctrl->dwFrameInterval = frame->dwFrameInterval[i]; + return; + } + + if (stream->intf->num_altsetting > 1) { u32 interval; u32 bandwidth; diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 97df5ecd66c9..b44e0cd4c826 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -658,6 +658,7 @@ static inline u32 uvc_urb_index(const struct uvc_urb *uvc_urb) struct uvc_device_info { u32 quirks; + u32 max_bandwidth; u32 meta_format; u16 uvc_version; }; @@ -667,6 +668,7 @@ struct uvc_device { struct usb_interface *intf; unsigned long warnings; u32 quirks; + u32 max_bandwidth; int intfnum; char name[32]; -- 2.29.2