From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8D9D2CA0EF5 for ; Tue, 19 Aug 2025 20:43:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=IGu9/qbvgUkVrqWgbqZAk5MIshpSA6npw+c9WVTvhdQ=; b=YoXPOevud5Cpi9JjqyGrz76h4k +9kvOLODpiw8aUAv7XvdQY23R1pqGkPYb2r01F8Hz/kWQ25ZKlFKLk/XJlA7BMxnRIZ4sCb2/ziLt kRIIdGZdGBYCyPJg4/zUKh/vnIO5G/iB+1OMPoJ5p/KMdahgvB/IN46/FxkLYT70stRw8gRFJCXWo IkNnmtCVq62lHUA04riBt5VpViZISdEH2sCwbj2roik8WsV32sA5g8zeN7upMslAm8miy3cB3vfFF cUZ4rRViGKpBpZ296/avIh2bxoxsmolSRxz0AL+OYE1rP1oQGjrG1pkORvoJL+f5LqPubisfZwQon vXnAYSog==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1uoTAp-0000000BZS5-0C0q; Tue, 19 Aug 2025 20:43:15 +0000 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uoRWg-0000000BM1a-1ssZ for linux-arm-kernel@lists.infradead.org; Tue, 19 Aug 2025 18:57:44 +0000 Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 57JH5S9t023374 for ; Tue, 19 Aug 2025 18:57:41 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= IGu9/qbvgUkVrqWgbqZAk5MIshpSA6npw+c9WVTvhdQ=; b=cn+FvHfJzq0XcWLp +UdG0PSyEUHoZgq7vI1bMfK4aeGPTtgn38ZxX1jocQp0iA4bz9GLopBEGCMkZLR5 w8DIa7psZG4L/6Ym71r7BihI34BeUXIQPphY9um+xrs/fnChm9CXf+Qaav5cHXb3 lr/LQR83JpalMPdumC11hR/Ms3whsnm5Ob0nRK9Qo6p7GBHObeXB+/CpAt/AWavR BdkfONeF9++icHD+K4f4nBZliREau5VRTlgxxbUQ0YjrJVL4LwAVbaXQgcgk1aj+ jvOcPWCP/c3QNaIoJUAGg12jIGCF7fbp+uY/OiBuFf+6yc8wznQJWYG2A4GWJXWp 7oACBQ== Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 48m62vmmjp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Tue, 19 Aug 2025 18:57:41 +0000 (GMT) Received: by mail-qv1-f71.google.com with SMTP id 6a1803df08f44-70a92820fd0so55629666d6.1 for ; Tue, 19 Aug 2025 11:57:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755629858; x=1756234658; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IGu9/qbvgUkVrqWgbqZAk5MIshpSA6npw+c9WVTvhdQ=; b=iLHUDVibKanoumedLBA8aX5oxNEeiSOv1OdJ+ZMAPE+ihjnbq3g0sMFt49hUea9Wwl iS099naacpcJDF60liQpIKfUFBDoQ1BGvSUA2P6jxfIhPTHv9LOcPdpDn0GGzRJdL7FF FIvnFwP7ktXRCCzOyqP2VQ86fdAUqSIr07O0bYE18BWI4wUVVAWcMuGDW1aIeD/u/FKJ ll98FKuP9RYzPh9Hbmk/PZoJ4J63k+S2DeMucxVmM/v+Zc80HNA+pR9fWHzGeUN/Cjce eoKmswUU+siVjCOksO0jYySBBh4FRQ5Tm6i7iXCkmNmi6NzH1HPOdXtLn5ZloBfbuQbZ nnKw== X-Forwarded-Encrypted: i=1; AJvYcCWwyl98Csij6tgQGWf5i1yqxgTYzihX+YpMwHlDIURWcLA9fsWdhG3YIpV5Cn/Ac4g25is80BpAAojdSf+q28VE@lists.infradead.org X-Gm-Message-State: AOJu0YyhSB5yW5TRMkew4E72Sb4QSjM2NNurYqRSUYQA8o5fxvlmDSef rN4ZQEPuBv3fute7DrMF1YWQlc+W4eApji3qzsR7x7/imP0sC5E7UmfkJfNu/A6iMPK1CEvjTlF Lpoq5BsoJGiGCu5mH3h8SYcszb3x3P23+s/iuwDTJ3jjWPGZTryD01/Nhj41TBQE2W8M8bNKR6m +NOHa85jjR4A== X-Gm-Gg: ASbGncuqeu2Yt2h9xkzEBGzAUv18cTmTYnGVdJRrwwY9W0OoRvlbZorhDLkTZxIXiCc nYAitvmns8LsDBxVuu71VKJCgm0FSPveWuWUYfm3gTK22Lh15KSjk+mTP5gHI1oYBDz79/5z6JS zGgJdTScl7/jZMrMYnhAVIOtZXqsed3s7zs6uAMwzOsQL9GfqpxRcVxjOt2rHUr1/ELPhPT1AM5 LtIkTV6oSvY7YZ95BKI2WcqBtIYCRHPr/Apq3uPvx0omdtUk3a8JBY4Tgd71inVFGqEXnE/ZlXw xRlGNpYbZStMTiF+1AaCA768HtbENVd+FOVFLO/1LNBExLlBWbGPFI4o2020ReIv0GaxI4iQ1Mg qzC52bJzuFaOY7SmYTkELEvvAi1PKgRvFGaqCmTEC4HXC6oVjs1br X-Received: by 2002:ad4:5767:0:b0:709:cf54:2cb6 with SMTP id 6a1803df08f44-70d76fb6a8dmr1096256d6.16.1755629857510; Tue, 19 Aug 2025 11:57:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGuACaEBY+w5nPqs8GIoEiE6G2hOLmW6uXu4WqZtH687zcKyVJX9GDAHY+x4TyOexV3nyqfJg== X-Received: by 2002:ad4:5767:0:b0:709:cf54:2cb6 with SMTP id 6a1803df08f44-70d76fb6a8dmr1095996d6.16.1755629856813; Tue, 19 Aug 2025 11:57:36 -0700 (PDT) Received: from umbar.lan (2001-14ba-a0c3-3a00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a0c3:3a00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-55cef35f11csm2207314e87.51.2025.08.19.11.57.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Aug 2025 11:57:34 -0700 (PDT) From: Dmitry Baryshkov Date: Tue, 19 Aug 2025 21:57:30 +0300 Subject: [PATCH v2 1/8] drm/connector: let drivers declare infoframes as unsupported MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20250819-drm-limit-infoframes-v2-1-7595dda24fbd@oss.qualcomm.com> References: <20250819-drm-limit-infoframes-v2-0-7595dda24fbd@oss.qualcomm.com> In-Reply-To: <20250819-drm-limit-infoframes-v2-0-7595dda24fbd@oss.qualcomm.com> To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Chen-Yu Tsai , Samuel Holland , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Liu Ying , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=21997; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=PqwiZvRPALrMUjLzxT0/ZfTGIGxDBoMjiq2CRNclS2k=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBopMkbCgULTMje/gLZb4auNy+lCmvuteCrp/TYv 4zppck48w6JATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaKTJGwAKCRCLPIo+Aiko 1bP/B/kBZLCaWojMocVYU2sMGuZgP2CGkb5aWYexkfHWN/WHFJif/4YnvMs5LmFYA8bao0zKz/D 7X6SdgKNC8oeIg1ovcNBRXl9Q/uNAYyLJHPUq6ATzt0L5Yh29lK1cH3VW32bRYllpJMbRTPyyb9 zLbPYhB/aV/YQ6lrqdbIYD8U+MCqM47Eliu0n/ygX+AkpfYL5aPKhs8tohPjGvnYyuQeEDY384Q 1eOEcOXH2NzLsMFE9wkIShhh1VJkEnWX0zFZmsRHHxt1Pjs3Z2DujP76m3xjX1BM2zfgWfhaPLB tHXQt9+JvGvAvnqUXbDNf0gQK1Az3VGK0zD7YTyyNn28da2s X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwODE4MDEzOSBTYWx0ZWRfX9IWP2NH4b1ub Qigws2PI5r/Db3Wu3xlPSqOsRww07p/x95ZKXCjGuA4r4AeDfATgYTttn91VuoryW/NiawY47Af 6iS6v1STeIBapTfJUg/ZynwLTD2dZHOmypnvxwleNMMRpFZ2chcFF5cZvF9mFuyqv3fT6zdSpoA eqeNBmQKBRUG0zEDsbYM4MF1WcF5akI+tNUGqVBl108YdvZ8z7dewtufiu3VmPluRpN3YZX7F/l GLI2Pyrmr9INR7K0dcq3J9M7qfsShYliBIPb1AV5ekBcvup6h/390jJgtDCUyprC/+cXRANvgo5 KhQh4vNkm19Dr+Rpy6cli8vDRx13FZp+OnOhhK7mEhgVF1/3pb/++qKv+nlQLd6h1oVkVJ3Lwat Um36TG/k X-Proofpoint-GUID: _zIGQ-r8XyKWcOPNiUOhBgKHRUvUAFnC X-Authority-Analysis: v=2.4 cv=A4tsP7WG c=1 sm=1 tr=0 ts=68a4c925 cx=c_pps a=UgVkIMxJMSkC9lv97toC5g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=2OwXVqhp2XgA:10 a=EUspDBNiAAAA:8 a=EjBJG3Ffxhrz6juHXs8A:9 a=QEXdDO2ut3YA:10 a=1HOtulTD9v-eNWfpl4qZ:22 X-Proofpoint-ORIG-GUID: _zIGQ-r8XyKWcOPNiUOhBgKHRUvUAFnC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-08-19_02,2025-08-14_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 phishscore=0 adultscore=0 malwarescore=0 bulkscore=0 spamscore=0 impostorscore=0 priorityscore=1501 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2507300000 definitions=main-2508180139 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250819_115742_638747_AAA937AA X-CRM114-Status: GOOD ( 23.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Currently DRM framework expects that the HDMI connector driver supports all infoframe types: it generates the data as required and calls into the driver to program all of them, letting the driver to soft-fail if the infoframe is unsupported. This has a major drawback on userspace API: the framework also registers debugfs files for all Infoframe types, possibly surprising the users when infoframe is visible in the debugfs file, but it is not visible on the wire. Let drivers declare that they support only a subset of infoframes, creating a more consistent interface. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_bridge_connector.c | 6 ++++ drivers/gpu/drm/display/drm_hdmi_state_helper.c | 37 ++++++++++++++++++++-- drivers/gpu/drm/drm_connector.c | 4 +++ drivers/gpu/drm/drm_debugfs.c | 16 +++++++--- drivers/gpu/drm/rockchip/inno_hdmi.c | 1 + drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 1 + drivers/gpu/drm/tests/drm_connector_test.c | 28 ++++++++++++++++ drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 8 +++++ drivers/gpu/drm/vc4/vc4_hdmi.c | 5 +++ include/drm/drm_bridge.h | 7 ++++ include/drm/drm_connector.h | 22 +++++++++++++ 11 files changed, 128 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 8c915427d0538435661d771940efe38b462027a1..b94458d5faa9ae283889fc79496ae323bb4dc88c 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -781,6 +781,12 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, &drm_bridge_connector_hdmi_funcs, connector_type, ddc, supported_formats, + bridge->supported_infoframes ? : + DRM_CONNECTOR_INFOFRAME_AUDIO | + DRM_CONNECTOR_INFOFRAME_AVI | + DRM_CONNECTOR_INFOFRAME_DRM | + DRM_CONNECTOR_INFOFRAME_SPD | + DRM_CONNECTOR_INFOFRAME_VENDOR, max_bpc); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index a561f124be99a0cd4259dbacf5f5f6651ff8a0ea..44100fba5e7465b39bce48a086bc3d012d951690 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -687,6 +687,9 @@ static int hdmi_generate_avi_infoframe(const struct drm_connector *connector, infoframe->set = false; + if (!drm_hdmi_connector_supports_infoframe(connector, HDMI_INFOFRAME_TYPE_AVI)) + return 0; + ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode); if (ret) return ret; @@ -718,6 +721,9 @@ static int hdmi_generate_spd_infoframe(const struct drm_connector *connector, infoframe->set = false; + if (!drm_hdmi_connector_supports_infoframe(connector, HDMI_INFOFRAME_TYPE_SPD)) + return 0; + ret = hdmi_spd_infoframe_init(frame, connector->hdmi.vendor, connector->hdmi.product); @@ -742,6 +748,9 @@ static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector, infoframe->set = false; + if (!drm_hdmi_connector_supports_infoframe(connector, HDMI_INFOFRAME_TYPE_DRM)) + return 0; + if (connector->max_bpc < 10) return 0; @@ -771,6 +780,9 @@ static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *conne infoframe->set = false; + if (!drm_hdmi_connector_supports_infoframe(connector, HDMI_INFOFRAME_TYPE_VENDOR)) + return 0; + if (!info->has_hdmi_infoframe) return 0; @@ -905,6 +917,11 @@ static int clear_device_infoframe(struct drm_connector *connector, return 0; } + if (!drm_hdmi_connector_supports_infoframe(connector, type)) { + drm_dbg_kms(dev, "Infoframe 0x%02x not supported, bailing.\n", type); + return 0; + } + ret = funcs->clear_infoframe(connector, type); if (ret) { drm_dbg_kms(dev, "Call failed: %d\n", ret); @@ -930,23 +947,29 @@ static int write_device_infoframe(struct drm_connector *connector, union hdmi_infoframe *frame) { const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; + enum hdmi_infoframe_type type = frame->any.type; struct drm_device *dev = connector->dev; u8 buffer[HDMI_INFOFRAME_SIZE(MAX)]; int ret; int len; - drm_dbg_kms(dev, "Writing infoframe type %x\n", frame->any.type); + drm_dbg_kms(dev, "Writing infoframe type %x\n", type); if (!funcs || !funcs->write_infoframe) { drm_dbg_kms(dev, "Function not implemented, bailing.\n"); return -EINVAL; } + if (!drm_hdmi_connector_supports_infoframe(connector, type)) { + drm_dbg_kms(dev, "Infoframe %d not supported, bailing.\n", type); + return 0; + } + len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer)); if (len < 0) return len; - ret = funcs->write_infoframe(connector, frame->any.type, buffer, len); + ret = funcs->write_infoframe(connector, type, buffer, len); if (ret) { drm_dbg_kms(dev, "Call failed: %d\n", ret); return ret; @@ -1067,6 +1090,11 @@ drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *co struct drm_display_info *info = &connector->display_info; int ret; + if (!drm_hdmi_connector_supports_infoframe(connector, HDMI_INFOFRAME_TYPE_AUDIO)) { + drm_warn_once(connector->dev, "Audio Infoframe not supported, bailing.\n"); + return -EOPNOTSUPP; + } + if (!info->is_hdmi) return 0; @@ -1102,6 +1130,11 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con struct drm_display_info *info = &connector->display_info; int ret; + if (!drm_hdmi_connector_supports_infoframe(connector, HDMI_INFOFRAME_TYPE_AUDIO)) { + drm_warn_once(connector->dev, "Audio Infoframe not supported, bailing.\n"); + return -EOPNOTSUPP; + } + if (!info->is_hdmi) return 0; diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 272d6254ea4784e97ca894ec4d463beebf9fdbf0..e753de9fc80a26c30b9674c96083328711f32960 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -553,6 +553,7 @@ EXPORT_SYMBOL(drmm_connector_init); * @connector_type: user visible type of the connector * @ddc: optional pointer to the associated ddc adapter * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats + * @supported_infoframes: Bitmask of @DRM_CONNECTOR_INFOFRAME listing supported Infoframes * @max_bpc: Maximum bits per char the HDMI connector supports * * Initialises a preallocated HDMI connector. Connectors can be @@ -576,6 +577,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev, int connector_type, struct i2c_adapter *ddc, unsigned long supported_formats, + unsigned long supported_infoframes, unsigned int max_bpc) { int ret; @@ -623,6 +625,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, connector->hdmi.funcs = hdmi_funcs; + connector->hdmi.supported_infoframes = supported_infoframes; + return 0; } EXPORT_SYMBOL(drmm_connector_hdmi_init); diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 365cf337529fa2a88b69516d57360d212419c126..248cb9ea1d8781674160cd8d454113c9422ec691 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -672,6 +672,9 @@ static int create_hdmi_audio_infoframe_file(struct drm_connector *connector, { struct dentry *file; + if (!drm_hdmi_connector_supports_infoframe(connector, HDMI_INFOFRAME_TYPE_AUDIO)) + return 0; + file = debugfs_create_file("audio", 0400, parent, connector, &audio_infoframe_fops); if (IS_ERR(file)) return PTR_ERR(file); @@ -679,7 +682,7 @@ static int create_hdmi_audio_infoframe_file(struct drm_connector *connector, return 0; } -#define DEFINE_INFOFRAME_FILE(_f) \ +#define DEFINE_INFOFRAME_FILE(_f, _F) \ static ssize_t _f##_read_infoframe(struct file *filp, \ char __user *ubuf, \ size_t count, \ @@ -726,6 +729,9 @@ static int create_hdmi_## _f ## _infoframe_file(struct drm_connector *connector, { \ struct dentry *file; \ \ + if (!drm_hdmi_connector_supports_infoframe(connector, HDMI_INFOFRAME_TYPE_ ## _F)) \ + return 0; \ + \ file = debugfs_create_file(#_f, 0400, parent, connector, &_f ## _infoframe_fops); \ if (IS_ERR(file)) \ return PTR_ERR(file); \ @@ -733,10 +739,10 @@ static int create_hdmi_## _f ## _infoframe_file(struct drm_connector *connector, return 0; \ } -DEFINE_INFOFRAME_FILE(avi); -DEFINE_INFOFRAME_FILE(hdmi); -DEFINE_INFOFRAME_FILE(hdr_drm); -DEFINE_INFOFRAME_FILE(spd); +DEFINE_INFOFRAME_FILE(avi, AVI); +DEFINE_INFOFRAME_FILE(hdmi, VENDOR); +DEFINE_INFOFRAME_FILE(hdr_drm, DRM); +DEFINE_INFOFRAME_FILE(spd, SPD); static int create_hdmi_infoframe_files(struct drm_connector *connector, struct dentry *parent) diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c index 1ab3ad4bde9ea7305021186ea221d2ff9057fdbb..65eed5ae23194200c145cb174acff4f252b3ef1f 100644 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -1065,6 +1065,7 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) DRM_MODE_CONNECTOR_HDMIA, hdmi->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_INFOFRAME_AVI, 8); drm_connector_attach_encoder(&hdmi->connector, encoder); diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index ab0938ba61f7d75dd0bec473807a04a20e1cffbd..0b931da4ea2d4eb58a6224476059b9205e8626b4 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -640,6 +640,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, DRM_MODE_CONNECTOR_HDMIA, hdmi->ddc_i2c, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_INFOFRAME_AVI, 8); if (ret) { dev_err(dev, diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 22e2d959eb31459f9981fef488228904d67cb6f9..fd28ed2bf8bcecabaabc67f2f8f5ccc1f42525d3 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -641,6 +641,13 @@ static struct kunit_suite drm_connector_dynamic_register_test_suite = { .test_cases = drm_connector_dynamic_register_tests, }; +#define DRM_CONNECTOR_ALL_INFOFRAMES \ + (DRM_CONNECTOR_INFOFRAME_AUDIO | \ + DRM_CONNECTOR_INFOFRAME_AVI | \ + DRM_CONNECTOR_INFOFRAME_DRM | \ + DRM_CONNECTOR_INFOFRAME_SPD | \ + DRM_CONNECTOR_INFOFRAME_VENDOR) + /* * Test that the registration of a bog standard connector works as * expected and doesn't report any error. @@ -657,6 +664,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -677,6 +685,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, NULL, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -697,6 +706,7 @@ static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -717,6 +727,7 @@ static void drm_test_connector_hdmi_init_null_product(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -743,6 +754,7 @@ static void drm_test_connector_hdmi_init_product_valid(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_MEMEQ(test, @@ -776,6 +788,7 @@ static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_MEMEQ(test, @@ -803,6 +816,7 @@ static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *t DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -829,6 +843,7 @@ static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_MEMEQ(test, @@ -861,6 +876,7 @@ static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_MEMEQ(test, @@ -888,6 +904,7 @@ static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *te DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -908,6 +925,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 9); KUNIT_EXPECT_LT(test, ret, 0); } @@ -928,6 +946,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 0); KUNIT_EXPECT_LT(test, ret, 0); } @@ -953,6 +972,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); @@ -994,6 +1014,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 10); KUNIT_EXPECT_EQ(test, ret, 0); @@ -1035,6 +1056,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 12); KUNIT_EXPECT_EQ(test, ret, 0); @@ -1071,6 +1093,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, 0, + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -1091,6 +1114,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_YUV422), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -1149,6 +1173,7 @@ static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *te DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, params->supported_formats, + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, params->expected_result); } @@ -1170,6 +1195,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) connector_type, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -1205,6 +1231,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) connector_type, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -1482,6 +1509,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector( DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), + DRM_CONNECTOR_ALL_INFOFRAMES, 8); KUNIT_EXPECT_EQ(test, ret, 0); diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c index 8bd412735000cb18e66aeca21433b2ebbefe2b44..2901fcb6b12ee318a4a9c727a62d5290d7c9aa84 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -138,6 +138,13 @@ static const struct drm_connector_funcs dummy_connector_funcs = { .reset = dummy_hdmi_connector_reset, }; +#define DRM_CONNECTOR_ALL_INFOFRAMES \ + (DRM_CONNECTOR_INFOFRAME_AUDIO | \ + DRM_CONNECTOR_INFOFRAME_AVI | \ + DRM_CONNECTOR_INFOFRAME_DRM | \ + DRM_CONNECTOR_INFOFRAME_SPD | \ + DRM_CONNECTOR_INFOFRAME_VENDOR) + static struct drm_atomic_helper_connector_hdmi_priv * __connector_hdmi_init(struct kunit *test, @@ -192,6 +199,7 @@ __connector_hdmi_init(struct kunit *test, DRM_MODE_CONNECTOR_HDMIA, NULL, formats, + DRM_CONNECTOR_ALL_INFOFRAMES, max_bpc); KUNIT_ASSERT_EQ(test, ret, 0); diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 07c91b450f93ab9e795d040d6f60f485ac71cfe8..2098d04c95e7e733307c90bb9ab5e2631f6f5df0 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -556,6 +556,11 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, BIT(HDMI_COLORSPACE_RGB) | BIT(HDMI_COLORSPACE_YUV422) | BIT(HDMI_COLORSPACE_YUV444), + DRM_CONNECTOR_INFOFRAME_AUDIO | + DRM_CONNECTOR_INFOFRAME_AVI | + DRM_CONNECTOR_INFOFRAME_DRM | + DRM_CONNECTOR_INFOFRAME_SPD | + DRM_CONNECTOR_INFOFRAME_VENDOR, max_bpc); if (ret) return ret; diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 620e119cc24c3491c2be5f08efaf51dfa8f708b3..529dcaca1d7924da12d9587170f96ec6a00ad126 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -1153,6 +1153,13 @@ struct drm_bridge { */ unsigned int max_bpc; + /** + * @supported_infoframes: Bitmask of DRM_CONNECTOR_INFOFRAME values, + * listing supported infoframes. This is only relevant if + * @DRM_BRIDGE_OP_HDMI is set. + */ + unsigned int supported_infoframes; + /** * @hdmi_cec_dev: device to be used as a containing device for CEC * functions. diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 8f34f4b8183d83dccd3e820a444fbf74fb6c16f2..7a92b4d75d25b355898b6c5d7cc45431187dc3b9 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1839,6 +1839,12 @@ struct drm_connector_hdmi { */ unsigned long supported_formats; + /** + * @supported_infoframes: Bitmask of infoframe types supported by the + * controller. See @DRM_CONNECTOR_INFOFRAME. + */ + unsigned long supported_infoframes; + /** * @funcs: HDMI connector Control Functions */ @@ -2336,6 +2342,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev, int connector_type, struct i2c_adapter *ddc, unsigned long supported_formats, + unsigned long supported_infoframes, unsigned int max_bpc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); @@ -2488,6 +2495,21 @@ void drm_connector_attach_privacy_screen_provider( struct drm_connector *connector, struct drm_privacy_screen *priv); void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state); +#define DRM_CONNECTOR_INFOFRAME(type) BIT(type - 0x80) + +#define DRM_CONNECTOR_INFOFRAME_AUDIO DRM_CONNECTOR_INFOFRAME(HDMI_INFOFRAME_TYPE_AUDIO) +#define DRM_CONNECTOR_INFOFRAME_AVI DRM_CONNECTOR_INFOFRAME(HDMI_INFOFRAME_TYPE_AVI) +#define DRM_CONNECTOR_INFOFRAME_DRM DRM_CONNECTOR_INFOFRAME(HDMI_INFOFRAME_TYPE_DRM) +#define DRM_CONNECTOR_INFOFRAME_SPD DRM_CONNECTOR_INFOFRAME(HDMI_INFOFRAME_TYPE_SPD) +#define DRM_CONNECTOR_INFOFRAME_VENDOR DRM_CONNECTOR_INFOFRAME(HDMI_INFOFRAME_TYPE_VENDOR) + +static inline bool +drm_hdmi_connector_supports_infoframe(const struct drm_connector *connector, + enum hdmi_infoframe_type type) +{ + return connector->hdmi.supported_infoframes & DRM_CONNECTOR_INFOFRAME(type); +} + /** * struct drm_tile_group - Tile group metadata * @refcount: reference count -- 2.47.2