From patchwork Wed Jan 7 18:14:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 522 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF0D63557F6 for ; Wed, 7 Jan 2026 18:15:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809711; cv=none; b=VwM1aEK4WTklgEuy6O3lesRQYQXahhVWbqVYozJCCeB/L353fR6EO5jVLaIZIVZaFJjLsHbNWacdFvDR+0XFA4ZykiqJPGC6c5Cyt89WlYynzptFJUdNQd+CNkjjDaIJooNvCPPTiADTnCclz6eTh/xzO+4QPAFbKnRhb9bwq9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809711; c=relaxed/simple; bh=XZUiI+P1J2mQYMmzuj2kKLbF6PlyfBdfsh+uTUhKM3o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sqT7ZdRZpxn+lYygEUy3ImjRvptQqA3h7cFAsaOspw41FSNyK8aR9ZdffODJAW/Fg1aK5lk853H2F87F7UIoLjqmu2i3KCGstRmIWMqNJGgOokM5nQXDcn6J7Zr/G6hxtdbXX1uH/ArWX7zh6oqEercjd2Nk7A+ubZ0zb5Cug/I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=XjdPzI+v; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Gs161Vfn; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="XjdPzI+v"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Gs161Vfn" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607H5UFb2453884 for ; Wed, 7 Jan 2026 18:15:08 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= pPEqdfktaAHE/Jjjjm6RwHrVcZ7AZ3stnlHc40P42b8=; b=XjdPzI+vprat0Amv gwL3eg4VCPgxWlfP8SP+gmGcQl0yvekPl5SWJ98dXB9sRWjAFvjVdTlLxe8EsDSa bCbSdg7e/6q1v+hHAmq4FOhGOMqEm8eC0vubYxM8GJOK1yBCU/+errTsYHLWBhIk SFPQ4E2fTMzd2tn97gEbpm63rCCzXLmxJ8fjRb4dljA39rjJzOk3p/bPKBc/vyq8 qMbVmKT2l6RFKdu7HoY5DkvrKKkyxuMxaoYPucTRUJI5xhq1v5KKECgSmo+ZDHto nL4i/tijX5o6Fw3wwCPH4i+Bgdnp1Qo1AS/xhUU6LQ28J/eDkz8qaF+rDPVZz9CJ KR6m0A== Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhmnbhpt5-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:07 +0000 (GMT) Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-8b9fa6f808cso698686885a.1 for ; Wed, 07 Jan 2026 10:15:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809707; x=1768414507; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=pPEqdfktaAHE/Jjjjm6RwHrVcZ7AZ3stnlHc40P42b8=; b=Gs161Vfn8S83bs9lrZWeDG1W6SWGoKdCW//UtC6ej76AiRV7ZBdvrRfuy/Xx/RR/Fr scNTjIMtKpiZDdkBu58z0dwDNwAtyrZoEaSYuTKeANqqMHiimjtyO7GNeTILsWD6g1Ep Gf3Xjv0TouTlkM4duPjfbzrLqCyeNPR0ggnCilaC//pYAdYqybGCaPM02vAMzquftIZK rWvx+ZTE2A9pOLvXj0W8F4cK9gTKHhBnUtGZTWwQNRfHmAIdmAHS8Wj6X8ASCE+4x6e4 1ARDCeBhPNAcDXM3uzJXKDmZrhc+ORiDan8OYR0279CntC6Wf0C9EL7h16HIsgV/6OxA Wn/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809707; x=1768414507; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=pPEqdfktaAHE/Jjjjm6RwHrVcZ7AZ3stnlHc40P42b8=; b=lEu6G/gTRz9E1r4KTnn2QI7315sUNl6AHzQCcnLkP3U2tV29sr2Va23m14PQLmRFxJ AbbG6/zsiGoUr5bOBJS68zSYb+g/7150YUd5fAY67HKK7cwGkzNWOnX79j/7dNVWr13Y MPJED8nLHSIEPiREVh1ed4Z+3Wr0tmbITTwx+kiLMkii3YC3VEAT84KQAenXFHG52DYq BwX3sbM2MdsXDoVWtFivMjCb6J+T97hBC/hLDxkeyOd87gfBvN7+D7VYwfihZNZgZFL4 4wGDDBvLCZj4ehq9oJUvnjWukvDaAwclj2dxjcb8/VaHisV0s1nFyOOX9ltyRGfpxBXu 3bJA== X-Forwarded-Encrypted: i=1; AJvYcCXfdqnjGibNOPXFs8Y6rYtFwAJPC2CB/LTQsT0ADu0npHOLFGYnEmGnWwCIU7nFdXpFMA2KPYfhCvDCrQ==@lists.linux.dev X-Gm-Message-State: AOJu0Yykrhhcjy+530fQ0/4YBO2aJirFjmRBhOHa1YarL1Q4PZ7DUVQd aEq9L9Lq7/zpM+CTW9dAilNRZfhdlIGY377yObZ+9urBfSIpoulF4CkoCN5uz3W8+v/GwcsECVV Nr7r9nAyasc6HnMx+gTcdauabBqjwcbnbBwBcGwmzCAek8hp5ld5vVIh3wwMcl9+leQ== X-Gm-Gg: AY/fxX5GQVmOZ/9Nka0t7VsGPtwoebdRMjS8Mge/x5sNXSOo+ZXUUiXGbs9YdPeH8x7 IoStT90e9REOutu7P9vZ3xDcUZGHwXdvS9YOypOozVfl2w3V+to8EBrkwIAx4ymw/mEqJqYuu9T GxAWNsHtURZY1vMD74snTeciXXE3Qb+ycljGyTpO585UHE3Ai7yfIvA/bjc2GA74I3s1AzJdidi /+udKJs4vcD/gzwanDVMl1SM0wGxAsRnarU1ZgYwoFEVdP/U9GFor4dNAw/eyzvsoekXNVAO4MY vepu2ktHHfKwCySm0HBYv0xj/jO4mj6b2vgfXYFTaYxNruDnhYrpe9b4+AAoy2dM54AiJ16Gmq+ KMzru0VPgcPYU2lAUxAwXdhDkuKHIWQGhQ8hj5FrrJyrbFpU+hzXcbMhpmsZ0GaRHxOQPwwMzLm mbzUI2adM4mE0+OSWQMDpb+OQ= X-Received: by 2002:a05:620a:711c:b0:8c0:cca6:8522 with SMTP id af79cd13be357-8c38939ce29mr472852985a.37.1767809706554; Wed, 07 Jan 2026 10:15:06 -0800 (PST) X-Google-Smtp-Source: AGHT+IE0AzgUocYSZpm2KC5Ln3K9tzKrPT4erDK/yC4UWYZHbUCAGZhC15uqj5QHGP7DsMDQRvR3PA== X-Received: by 2002:a05:620a:711c:b0:8c0:cca6:8522 with SMTP id af79cd13be357-8c38939ce29mr472830885a.37.1767809704473; Wed, 07 Jan 2026 10:15:04 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:03 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:14:58 +0200 Subject: [PATCH v4 01/10] drm/tests: hdmi: check the infoframes behaviour Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-1-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=26900; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=XZUiI+P1J2mQYMmzuj2kKLbF6PlyfBdfsh+uTUhKM3o=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBpXqKk/8Nl7ok1dk6fEgJIBY2eHmOcgrrVbCdGg 4G/w01IwRGJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaV6ipAAKCRCLPIo+Aiko 1WqSB/0VrgfS9rAIG9Uf20YH0OIYY4ndo3LeHhBOi8y+NVnkkrgy2GYB7/rQtaNP7nFjGfA4cmL vbob0bl/yFwoZQmX5PkeiPuoQSoaXRP7AtTHFBeRCi8Rj9oXqeEBUvIHu+aQBv/49k7WQadCRsL mUZovgX/I4GjOMOxM5h0ygkXgQO3MvIU+0mML823mquPoOjHaRJ3jIOUUziNm5KhauTTSv8bEZm nSoWmvCvTd8ktElS/MnI/p7rdGaiBmxxWtJifxx6QQ4NVYcjP/iEq3BtdhrWCen/IWD7BodYU3K Hmu1TnqjIt4tgMI702qK4C1kVfoT8MkuGsTjtWOwHZpujBeq X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfX+ETZVUa4n4iO oXB9h+1jTWWx+1ZdbeJ42JfylDf9DzEnHBRIa8fP8r1oMHkAAwLITdgETLRgq6U6BiA1SU+lpUQ pFbZENyzZKL+tnNx49CIfnW2921IXFTf0wZSrG/BWdkBG4Ki3QsFHMHBNQSTXkY3qWMD2700aGL 63Z2pCqocVhbkRYQL3vAQJQMJPZEi427ObbZTo/Xra7wJCg3OubQe4wx5PGvor0o8FtUPtVgql6 Y2WdXcJxbmiri1g52kMUtSLaCMaugxqsJtcbtlDxr+CzO2/+/Gdz9dKlruNQ5ZK8DOp+aOgn+tQ GjcljKrn9afWrewn9SvHOjvRZnbKHehmds3ChiP58/DI1fpeNTUbM5eyjEYCDJFSVwKx3xU//gP 2H/a7M7cjvHKxCs/eAZ3jip2xNsbavdx0LiMt1y8LOdzAuwHgBs2ISB2d3jwNs/3QVq/H1nc7uh FKea3ONx2eqrNhD3Qcg== X-Proofpoint-GUID: mVbirnh2lFo1ghYwUfN22Fyn6eqW2NhN X-Authority-Analysis: v=2.4 cv=eIkeTXp1 c=1 sm=1 tr=0 ts=695ea2ac cx=c_pps a=50t2pK5VMbmlHzFWWp8p/g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=VwQbUJbxAAAA:8 a=8CpnO3W62F676OTI3Z8A:9 a=QEXdDO2ut3YA:10 a=IoWCM6iH3mJn3m4BftBB:22 X-Proofpoint-ORIG-GUID: mVbirnh2lFo1ghYwUfN22Fyn6eqW2NhN X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 clxscore=1015 malwarescore=0 suspectscore=0 phishscore=0 impostorscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O Verify the InfoFrames behaviour. Check that reporting InfoFrame as unsupported doesn't result in a commit error. Also check that HDR and Audio InfoFrames are not triggered if corresponding features are not enabled. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/tests/drm_client_modeset_test.c | 3 + drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 627 +++++++++++++++++++++ drivers/gpu/drm/tests/drm_kunit_edid.h | 119 ++++ 3 files changed, 749 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_client_modeset_test.c b/drivers/gpu/drm/tests/drm_client_modeset_test.c index 3f44fe5e92e4..ec58fe064d86 100644 --- a/drivers/gpu/drm/tests/drm_client_modeset_test.c +++ b/drivers/gpu/drm/tests/drm_client_modeset_test.c @@ -5,6 +5,7 @@ #include +#include #include #include #include @@ -48,6 +49,8 @@ static const struct drm_connector_helper_funcs drm_client_modeset_connector_help }; static const struct drm_connector_funcs drm_client_modeset_connector_funcs = { + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state }; static int drm_client_modeset_test_init(struct kunit *test) 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 8bd412735000..80f819a9ff5b 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -35,11 +35,16 @@ struct drm_atomic_helper_connector_hdmi_priv { const void *current_edid; size_t current_edid_len; + + int hdmi_update_failures; }; #define connector_to_priv(c) \ container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector) +#define encoder_to_priv(e) \ + container_of_const(e, struct drm_atomic_helper_connector_hdmi_priv, encoder) + static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector) { struct drm_device *drm = connector->dev; @@ -138,6 +143,22 @@ static const struct drm_connector_funcs dummy_connector_funcs = { .reset = dummy_hdmi_connector_reset, }; +static void test_encoder_atomic_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv = + encoder_to_priv(encoder); + int ret; + + ret = drm_atomic_helper_connector_hdmi_update_infoframes(&priv->connector, state); + if (ret) + priv->hdmi_update_failures++; +} + +static const struct drm_encoder_helper_funcs test_encoder_helper_funcs = { + .atomic_enable = test_encoder_atomic_enable, +}; + static struct drm_atomic_helper_connector_hdmi_priv * __connector_hdmi_init(struct kunit *test, @@ -2323,10 +2344,616 @@ static struct kunit_suite drm_atomic_helper_connector_hdmi_mode_valid_test_suite .test_cases = drm_atomic_helper_connector_hdmi_mode_valid_tests, }; +/* + * Test that the default behaviour works without errors. We expect that + * infoframe-related hooks are called and there are no errors raised. + */ +static void drm_test_check_infoframes(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx ctx; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int old_hdmi_update_failures; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 8, + &dummy_connector_hdmi_funcs, + test_edid_hdmi_1080p_rgb_max_200mhz); + KUNIT_ASSERT_NOT_NULL(test, priv); + + drm = &priv->drm; + crtc = priv->crtc; + conn = &priv->connector; + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: + ret = drm_kunit_helper_enable_crtc_connector(test, drm, + crtc, conn, + preferred, + &ctx); + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_enable; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_crtc_state: + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (PTR_ERR(crtc_state) == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + crtc_state->mode_changed = true; + + old_hdmi_update_failures = priv->hdmi_update_failures; + + ret = drm_atomic_check_only(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = drm_atomic_commit(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_EXPECT_GE(test, old_hdmi_update_failures, priv->hdmi_update_failures); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +static int reject_avi_infoframe_write_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) +{ + if (type == HDMI_INFOFRAME_TYPE_AVI) + return -EOPNOTSUPP; + + return 0; +} + +static const struct drm_connector_hdmi_funcs reject_avi_infoframe_hdmi_funcs = { + .write_infoframe = reject_avi_infoframe_write_infoframe, +}; + +/* + * Test that the rejection of AVI InfoFrame results in the failure of + * drm_atomic_helper_connector_hdmi_update_infoframes(). + */ +static void drm_test_check_reject_avi_infoframe(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx ctx; + struct drm_atomic_state *state; + struct drm_crtc_state *crtc_state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int old_hdmi_update_failures; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 8, + &reject_avi_infoframe_hdmi_funcs, + test_edid_hdmi_1080p_rgb_max_200mhz); + KUNIT_ASSERT_NOT_NULL(test, priv); + + drm = &priv->drm; + crtc = priv->crtc; + conn = &priv->connector; + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: + ret = drm_kunit_helper_enable_crtc_connector(test, drm, + crtc, conn, + preferred, + &ctx); + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_enable; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_crtc_state: + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (PTR_ERR(crtc_state) == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + crtc_state->mode_changed = true; + + old_hdmi_update_failures = priv->hdmi_update_failures; + + ret = drm_atomic_check_only(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = drm_atomic_commit(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_EXPECT_NE(test, old_hdmi_update_failures, priv->hdmi_update_failures); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +static int reject_hdr_infoframe_write_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) +{ + if (type == HDMI_INFOFRAME_TYPE_DRM) + return -EOPNOTSUPP; + + return 0; +} + +static const struct drm_connector_hdmi_funcs reject_hdr_infoframe_hdmi_funcs = { + .write_infoframe = reject_hdr_infoframe_write_infoframe, +}; + +/* + * Test that the HDR InfoFrame isn't programmed in + * drm_atomic_helper_connector_hdmi_update_infoframes() if the max_bpc is 8. + */ +static void drm_test_check_reject_hdr_infoframe_bpc_8(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx ctx; + struct drm_atomic_state *state; + struct drm_connector_state *new_conn_state; + struct drm_crtc_state *crtc_state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int old_hdmi_update_failures; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 8, + &reject_hdr_infoframe_hdmi_funcs, + test_edid_hdmi_1080p_rgb_max_200mhz_hdr); + KUNIT_ASSERT_NOT_NULL(test, priv); + + drm = &priv->drm; + crtc = priv->crtc; + conn = &priv->connector; + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: + ret = drm_kunit_helper_enable_crtc_connector(test, drm, + crtc, conn, + preferred, + &ctx); + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_enable; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_conn_state: + new_conn_state = drm_atomic_get_connector_state(state, conn); + if (PTR_ERR(new_conn_state) == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_state; + } + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (PTR_ERR(crtc_state) == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_state; + } + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + /* Verify that there is no HDR property, so "userspace" can't set it. */ + for (int i = 0; i < conn->base.properties->count; i++) + KUNIT_ASSERT_PTR_NE(test, + drm->mode_config.hdr_output_metadata_property, + conn->base.properties->properties[i]); + + crtc_state->mode_changed = true; + + old_hdmi_update_failures = priv->hdmi_update_failures; + + ret = drm_atomic_check_only(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = drm_atomic_commit(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, old_hdmi_update_failures, priv->hdmi_update_failures); + + new_conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, new_conn_state); + + KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.output_bpc, 8); + KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.infoframes.hdr_drm.set, false); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +/* + * Test that the rejection of HDR InfoFrame results in the failure of + * drm_atomic_helper_connector_hdmi_update_infoframes() in the high bpc is + * supported. + */ +static void drm_test_check_reject_hdr_infoframe_bpc_10(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx ctx; + struct drm_atomic_state *state; + struct drm_connector_state *new_conn_state; + struct drm_crtc_state *crtc_state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int old_hdmi_update_failures; + struct hdr_output_metadata hdr_data; + struct drm_property_blob *hdr_blob; + bool replaced; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 10, + &reject_hdr_infoframe_hdmi_funcs, + test_edid_hdmi_1080p_rgb_max_200mhz_hdr); + KUNIT_ASSERT_NOT_NULL(test, priv); + + drm = &priv->drm; + crtc = priv->crtc; + conn = &priv->connector; + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: + ret = drm_kunit_helper_enable_crtc_connector(test, drm, + crtc, conn, + preferred, + &ctx); + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_enable; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_conn_state: + new_conn_state = drm_atomic_get_connector_state(state, conn); + if (PTR_ERR(new_conn_state) == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_state; + } + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (PTR_ERR(crtc_state) == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_state; + } + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + hdr_data.metadata_type = HDMI_STATIC_METADATA_TYPE1; + hdr_data.hdmi_metadata_type1.eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; + hdr_data.hdmi_metadata_type1.metadata_type = HDMI_STATIC_METADATA_TYPE1; + + hdr_blob = drm_property_create_blob(drm, sizeof(hdr_data), &hdr_data); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hdr_blob); + + ret = drm_property_replace_blob_from_id(drm, + &new_conn_state->hdr_output_metadata, + hdr_blob->base.id, + sizeof(struct hdr_output_metadata), -1, + &replaced); + KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_EQ(test, replaced, true); + + crtc_state->mode_changed = true; + + old_hdmi_update_failures = priv->hdmi_update_failures; + + ret = drm_atomic_check_only(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = drm_atomic_commit(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_EXPECT_LE(test, old_hdmi_update_failures, priv->hdmi_update_failures); + + new_conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, new_conn_state); + + KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.output_bpc, 10); + KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.infoframes.hdr_drm.set, true); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +static int reject_audio_infoframe_write_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) +{ + if (type == HDMI_INFOFRAME_TYPE_AUDIO) + return -EOPNOTSUPP; + + return 0; +} + +static const struct drm_connector_hdmi_funcs reject_audio_infoframe_hdmi_funcs = { + .write_infoframe = reject_audio_infoframe_write_infoframe, +}; + +/* + * Test that Audio InfoFrame is only programmed if we call a corresponding API, + * thus the drivers can safely assume that they won't get Audio InfoFrames if + * they don't call it. + */ +static void drm_test_check_reject_audio_infoframe(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx ctx; + struct drm_atomic_state *state; + struct drm_crtc_state *crtc_state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int old_hdmi_update_failures; + struct hdmi_audio_infoframe cea; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 8, + &reject_audio_infoframe_hdmi_funcs, + test_edid_hdmi_1080p_rgb_max_200mhz); + KUNIT_ASSERT_NOT_NULL(test, priv); + + drm = &priv->drm; + crtc = priv->crtc; + conn = &priv->connector; + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: + ret = drm_kunit_helper_enable_crtc_connector(test, drm, + crtc, conn, + preferred, + &ctx); + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_conn_enable; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_crtc_state: + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (PTR_ERR(crtc_state) == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + crtc_state->mode_changed = true; + + old_hdmi_update_failures = priv->hdmi_update_failures; + + ret = drm_atomic_check_only(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = drm_atomic_commit(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, old_hdmi_update_failures, priv->hdmi_update_failures); + + /* + * So, it works without Audio InfoFrame, let's fail with it in place, + * checking that writing the infofraem actually gets triggered. + */ + + hdmi_audio_infoframe_init(&cea); + cea.channels = 2; + cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; + cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; + cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; + + ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(conn, &cea); + KUNIT_ASSERT_EQ(test, ret, -EOPNOTSUPP); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_crtc_state_2: + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (PTR_ERR(crtc_state) == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state_2; + } + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + crtc_state->mode_changed = true; + + old_hdmi_update_failures = priv->hdmi_update_failures; + + ret = drm_atomic_check_only(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state_2; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = drm_atomic_commit(state); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_crtc_state_2; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_EXPECT_LE(test, old_hdmi_update_failures, priv->hdmi_update_failures); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + + +static struct kunit_case drm_atomic_helper_connector_hdmi_infoframes_tests[] = { + KUNIT_CASE(drm_test_check_infoframes), + KUNIT_CASE(drm_test_check_reject_avi_infoframe), + KUNIT_CASE(drm_test_check_reject_hdr_infoframe_bpc_8), + KUNIT_CASE(drm_test_check_reject_hdr_infoframe_bpc_10), + KUNIT_CASE(drm_test_check_reject_audio_infoframe), + { } +}; + +static struct kunit_suite drm_atomic_helper_connector_hdmi_infoframes_test_suite = { + .name = "drm_atomic_helper_connector_hdmi_infoframes", + .test_cases = drm_atomic_helper_connector_hdmi_infoframes_tests, +}; + kunit_test_suites( &drm_atomic_helper_connector_hdmi_check_test_suite, &drm_atomic_helper_connector_hdmi_reset_test_suite, &drm_atomic_helper_connector_hdmi_mode_valid_test_suite, + &drm_atomic_helper_connector_hdmi_infoframes_test_suite, ); MODULE_AUTHOR("Maxime Ripard "); diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h index c59c8528a3f7..f4923157f5bf 100644 --- a/drivers/gpu/drm/tests/drm_kunit_edid.h +++ b/drivers/gpu/drm/tests/drm_kunit_edid.h @@ -293,6 +293,125 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = { 0x00, 0x00, 0x00, 0xfc }; +/* + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 + * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00 + * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c + * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32 + * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92 + * + * 02 03 1c 81 e3 05 c0 20 41 10 e2 00 4a 67 03 0c + * 00 12 34 00 28 e6 06 05 01 52 52 51 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4e + * + * ---------------- + * + * Block 0, Base EDID: + * EDID Structure Version & Revision: 1.3 + * Vendor & Product Identification: + * Manufacturer: LNX + * Model: 42 + * Made in: 2023 + * Basic Display Parameters & Features: + * Digital display + * DFP 1.x compatible TMDS + * Maximum image size: 160 cm x 90 cm + * Gamma: 2.20 + * Monochrome or grayscale display + * First detailed timing is the preferred timing + * Color Characteristics: + * Red : 0.0000, 0.0000 + * Green: 0.0000, 0.0000 + * Blue : 0.0000, 0.0000 + * White: 0.0000, 0.0000 + * Established Timings I & II: + * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz + * Standard Timings: none + * Detailed Timing Descriptors: + * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm) + * Hfront 88 Hsync 44 Hback 148 Hpol P + * Vfront 4 Vsync 5 Vback 36 Vpol P + * Display Product Name: 'Test EDID' + * Display Range Limits: + * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz + * Dummy Descriptor: + * Extension blocks: 1 + * Checksum: 0x92 + * + * ---------------- + * + * Block 1, CTA-861 Extension Block: + * Revision: 3 + * Underscans IT Video Formats by default + * Native detailed modes: 1 + * Colorimetry Data Block: + * BT2020YCC + * BT2020RGB + * sRGB + * Video Data Block: + * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz + * Video Capability Data Block: + * YCbCr quantization: No Data + * RGB quantization: Selectable (via AVI Q) + * PT scan behavior: No Data + * IT scan behavior: Always Underscanned + * CE scan behavior: Always Underscanned + * Vendor-Specific Data Block (HDMI), OUI 00-0C-03: + * Source physical address: 1.2.3.4 + * Maximum TMDS clock: 200 MHz + * HDR Static Metadata Data Block: + * Electro optical transfer functions: + * Traditional gamma - SDR luminance range + * SMPTE ST2084 + * Supported static metadata descriptors: + * Static metadata type 1 + * Desired content max luminance: 82 (295.365 cd/m^2) + * Desired content max frame-average luminance: 82 (295.365 cd/m^2) + * Desired content min luminance: 81 (0.298 cd/m^2) + * Checksum: 0x4e Unused space in Extension Block: 99 bytes + * + * ---------------- + * + * edid-decode 1.31.0-5387 + * edid-decode SHA: 5508bc4301ac 2025-08-25 08:14:22 + * + * EDID conformity: PASS + */ +static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz_hdr[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, + 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, + 0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, 0x02, 0x03, 0x1c, 0x81, + 0xe3, 0x05, 0xc0, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x67, 0x03, 0x0c, + 0x00, 0x12, 0x34, 0x78, 0x28, 0xe6, 0x06, 0x05, 0x01, 0x52, 0x52, 0x51, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd6, +}; + /* * edid-decode (hex): * From patchwork Wed Jan 7 18:14:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 524 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF8133559F8 for ; Wed, 7 Jan 2026 18:15:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809710; cv=none; b=ISyfIRqEfX+D0IhxGC+VP86uZktn1NjmzICNlOlpTX5JlEvUvW9jp5c/KnWWUPGpQuxm+slfb7FWtG5WDy1PJq42EWVE8S/ffVogktuRZX7M7RrQlwNteAP1tHPoFpvabbbrE9YgwUWryP4NbrBul+U+B4KW9D5txZrdNqVbeMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809710; c=relaxed/simple; bh=YjRxdH2GhgCXavyWIwCH6N3bsC345EISvDP2gtesFFg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AdMN0tOOKi49wvlDVV0GYmVddERDIsWyByRbLQ9Th7ovjiIbPDNCyms3zUB3jru1N97B5WKeSUHKVyp9eGy1Ju/hiWzPfeSh8SRvWDie4yX+5It6pxpmWh6LNfoe/m3nrbT2E00DzhSdsecyUtBx9+foBr3R3ymvrg2Ir/fPjFE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=LcvKs90c; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=dGiAYGyt; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="LcvKs90c"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="dGiAYGyt" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607H3qIu2593287 for ; Wed, 7 Jan 2026 18:15:08 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= CvOBqRWntd3xVSUEtMwnv/Rm6Go596skSwj2MkU+rb8=; b=LcvKs90co5qyoc2Z d/DIjr6T4wp6peOapih1HLy3dVAbvLTC7P2Kndnry/iEomJs8OzmIVngr3ixTOg4 tVc0xZ0DdmPlAIFS82JO8PKad+Hq37EPFHDDYa0GXy6zgBOnPD7vJ+6HgBeCQiT+ G8XV72EZ8iahnPwLPnscVkw1z9E1UZMXnq1dgZHv7GYsWAjoLBiC4TN5mTDh6g/J 6uEGqMsEJNdB6obsu3FYwEUHg8rQ/O4SdEcPEIwhJuQIkWpFmUB31BYP1mcGpKNr 8ZksV4agCherUaArKSC/9gV6QqRKNRz+GmwyFyV4PyNrFAU9PP6VNmmcPKTYAFYo Lf4E3A== Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhn291n35-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:08 +0000 (GMT) Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-8b234bae2a7so634334085a.3 for ; Wed, 07 Jan 2026 10:15:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809707; x=1768414507; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=CvOBqRWntd3xVSUEtMwnv/Rm6Go596skSwj2MkU+rb8=; b=dGiAYGytJU2x5e35mTWfDNvkI/ymhNDTYNFkPCynhnU95agOtJsbTMmda8d3Pc22G5 Jf+gULosyftxZm7+MZ6F67sxF6eyj1+ZBKyPFbU/ucM2zU62AqiQd/3fr5p7svRBR/ox OgMYacoNqToBE+46iDWgA09TQxUPrNLFXjmPI5nmVqd/D4AAYzdj2v7LWSgjFD0bKKiI Ayk872ii3Ml8wwCDfy/OYaelkgc+tXJo1AQqUvGQfGFwDINrEPevx0yk/58LIZP1uc+N CPJ7QHIHGYe4e2RUTraZvwYeRicedUt7HpsAPMnqRmHc2cu5AEssZrxn7trA79SF0QDt LoYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809707; x=1768414507; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=CvOBqRWntd3xVSUEtMwnv/Rm6Go596skSwj2MkU+rb8=; b=w+bTkgzUHXvu5VoLXaq1VyoZZKvF1TvB7cpslKSrdFZ0C+L8QeypplY11clR0ve1R/ eqDHn1GbbPO1YGTw+9saxGM5SKrqtqkA4cSzCiZCu7bi/etoro0RfDigjMLYD+z1u4Iw GKlLbx0zFXSLAkIexI92JeB09AioCSUTLYD988Cm7NnHa7ts1Qtd48V+YRFQL4LG8o45 Mu14hapfMks488fTabdnl/0BaDU7gfNv7DqszUlmiP5Z6ilqJMrQ+X57Xc/PRWnzpsV0 JKaJOH6EseQD28slO+Z8UVzC21i/kBMjl9+hhjVqAS0v/3o7a0gxFtKdMpDW3MevWF41 lWQQ== X-Forwarded-Encrypted: i=1; AJvYcCX2IbbeqUN2eWH8025KvCVrOl+NecJDTm64k6QqGzTT+leCMvBbVZNkjimYKPtUfHTar3vAVB+gVU83QQ==@lists.linux.dev X-Gm-Message-State: AOJu0YwXCFzTAVZkacIYAp1CwwGh9LGqqWJJkt3BcDIYQEL0+NbVYTLD 7b0T15gEz3QPf3HYQwesoAytT9guzP/3smv+LnEE0bt51YrUJuERf3zB7DQ3xh8CGfImy/9I+LM i+ir0uKdbhC3FOhlvr2VIX57qmUEIyYSrPiwiBJUqblaPANQPmnTGcAOOEFh/lVE/gA== X-Gm-Gg: AY/fxX6CufBnVec/7Eejm/1X+k/KSKRtnWMnmK6ZCWwDmIt6x1Fwla7cACRnRv07WIG finrQT991Z0Vt2ONuzqatH9WIw4/LW7WLPvYMGo2Nb1BXv2plc8RHoOPu/brWC0U4E0Ja8shZT7 vhnj0TM/O/iWD/0mxRsV+/85qZSW28/2mYx3fH0QleGh9GNrpl9V5T11Eda3I4P5pZantx2Sx+0 nPoNiYn8Ssa2AyM8YKMTWFo2QayzYyDh+QvFPe64E6YH9OnIvSnx4YiYaS8BWz5L1pXjOv1WpCC +HxQoq57ZtpFEkLZp4iAqasZM9EUD/EAo8bkPMy9yVz9zfAS7PErgLCHh1N6pT8lqj+cphvqxYk OPZHyM1Lq39/9c6HrwJ66loZOobtVRcbUN5Gy+5pZzh7vjT/UFgtOgMsV0HAy6FpYPvqQEKa6G3 SR9ifom9gKD+mvkhlS5Pjx77Y= X-Received: by 2002:a05:620a:298c:b0:89f:5541:b5f5 with SMTP id af79cd13be357-8c3893751a1mr451570585a.17.1767809706372; Wed, 07 Jan 2026 10:15:06 -0800 (PST) X-Google-Smtp-Source: AGHT+IErco6iIlONdm8FoPmBoVGT4sMle7p6Daei/gbTGJZ8AsHe90PS3UuyAzSsRgYRNtmFv/UWZQ== X-Received: by 2002:a05:620a:298c:b0:89f:5541:b5f5 with SMTP id af79cd13be357-8c3893751a1mr451564685a.17.1767809705824; Wed, 07 Jan 2026 10:15:05 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:05 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:14:59 +0200 Subject: [PATCH v4 02/10] drm/vc4: hdmi: implement clear_infoframe Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-2-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1749; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=YjRxdH2GhgCXavyWIwCH6N3bsC345EISvDP2gtesFFg=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBpXqKkcDiQpwhgi0U0jf8JGOrxJBwtl/l5GypPK coPxI4tELuJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaV6ipAAKCRCLPIo+Aiko 1fRWB/92FTnBMUcYj37wwL0tkj2+9WhnXCNr6YaqOXhJHzBvMN3Ric79sLxWIk6V2x3r2jYCRTc BkdlD9X0pnL+Hq2degXIglnJH2gA1p7PGCVq8s0gm0v1ELu41JL4luLf8f6sJieWu1QXoaJk5qP 79zPwaA5N2vB9hfx5p+R6t4e8pTVe1kMeFaRCUvqmAe1Kovi1sIZ1KaVq04n6rv6Vhjro5yFiFn LyRakv9HjVWBfthh1kbm1YCWTU0Rh+rmb3pMmr07+I6SSf6xRRJ0Yq6B0EcopvIhZhVA3ayoLhz savBzIEyxFTHux8IDyABCGHnOtOfh5srllF0nQkfQKf8sNtQ X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-ORIG-GUID: aFto_l4lrzJaM2-bO35RtTrpMvd3_F6s X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfX55Sg5B3Emjrl vMsSSV7bvs6wHMfzrRloXohr1jmQSSz9PFggFvoHWBTM9OtjmtLHM/RKNwIlT24H/90raPYHr2W a/BSJlHgK6Ns/1qEFl4EaPw4VlV2JGrplhJ1zzZfAqqTTh6/Nx3FpDZX1iPrJjaRFt0tUVsKuQm zH77vDhUptTtvqAUSkEcwNTKj3T03EpFkkbeBPpVbmzaXOhs0v0xFlb4CyZoyJ7SkazSj8fppVn BP5MiAImrJ4eqHCFFv6liF6HefMEHhDYTM1V8TZh4myDzgz+iCeDVQUfi1Yev1C8/kHj5DBHVaa s0LVjh7W4jaj8dq42m/Ql1X7+BfKxdPdt5vvyLn1gqCBntRjUl9bst6Em4UoxUuONUxQf2FMs8X 0A0Es0/APCMZ/UVJPpu6Qpa2Lwt1LIC8e5WhSrcYpbNGl+5ayPRWdxvZ91BJCsYTGrUepcJ/CDr X3ili6N6Etek60NVldA== X-Authority-Analysis: v=2.4 cv=P7k3RyAu c=1 sm=1 tr=0 ts=695ea2ac cx=c_pps a=hnmNkyzTK/kJ09Xio7VxxA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=gsP-wGJUQ9tQerkYUh8A:9 a=QEXdDO2ut3YA:10 a=PEH46H7Ffwr30OY-TuGO:22 X-Proofpoint-GUID: aFto_l4lrzJaM2-bO35RtTrpMvd3_F6s X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 spamscore=0 phishscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 impostorscore=0 adultscore=0 priorityscore=1501 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O Implement the clear_infoframe callback, disabling corresponding InfoFrame type. Acked-by: Maxime Ripard Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 1798d1156d10..4cfb7ebc0c81 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -624,6 +624,30 @@ static int vc4_hdmi_stop_packet(struct vc4_hdmi *vc4_hdmi, return ret; } +static int vc4_hdmi_clear_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type) +{ + struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); + struct drm_device *drm = connector->dev; + int ret; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return 0; + + WARN_ONCE(!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & + VC4_HDMI_RAM_PACKET_ENABLE), + "Packet RAM has to be on to store the packet."); + + ret = vc4_hdmi_stop_packet(vc4_hdmi, type, true); + if (ret) + drm_err(drm, "Failed to wait for infoframe to go idle: %d\n", ret); + + drm_dev_exit(idx); + + return ret; +} + static int vc4_hdmi_write_infoframe(struct drm_connector *connector, enum hdmi_infoframe_type type, const u8 *infoframe, size_t len) @@ -1660,6 +1684,7 @@ vc4_hdmi_connector_clock_valid(const struct drm_connector *connector, static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs = { .tmds_char_rate_valid = vc4_hdmi_connector_clock_valid, + .clear_infoframe = vc4_hdmi_clear_infoframe, .write_infoframe = vc4_hdmi_write_infoframe, }; From patchwork Wed Jan 7 18:15:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 523 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBA58354AF6 for ; Wed, 7 Jan 2026 18:15:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809711; cv=none; b=d5VoYx7vCjP0UaUk9s22othCcXI0/VlM1+UxcGgKqac0wKwrTXNTAkAERViEkHpHBg+jQ7uyXKTYWFl8jNXDuRcGvdStdzkrgW7TCASFxUnExeOcDKTO7H3p/OwXCT37a9kiMNDEm/v25RSV8a4gW4lvqFq1LvCHliuFy5SPTrw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809711; c=relaxed/simple; bh=i9/GyfQ7oCfW1uA2EJ42B3bpRaDaBcnVtDJI1DBQZYU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=X1R5BvMLJa4Cu4kbwXrEO/XEjDqYgTW1Cp+ddAmtwRTheKYrqGJR8GHlhboeFqmU/QJQkNU3xKzqs1L56gYpN38i2gBHUzYTjWrbPxRVdPlpRgJ37IMs19F/IGxvguKW4iroWIqwBX6ecOdJVQu3qe7e5l1+eUOrY5RjWcK1bYI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=VTI+JdNA; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=jasvV9ll; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="VTI+JdNA"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="jasvV9ll" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607CsRDH2239380 for ; Wed, 7 Jan 2026 18:15:08 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= j2BT4ALqtU5AjsTQozcF6Tmng8niaFOYcGnl/GxzzY8=; b=VTI+JdNAvshkdlek Yfh5hok2VL+Ruv93fw7t3nX3JTZAOcnt9yVVeRWzxIrMrpZlkehYKArntaZh4Dhs py6Lp/1rh389bEb6TO0Y+qlxVSCg2M/0T8nIrcc9kP8/orpoqquwDZOkto1AWxb/ cEICWw743ZtkcFMhW8qvlQ9DH1/Cd1MfDCaYRGvFcInihEn1//0v7/KskZESWGo3 Y69JP2reux4mxVQZ3r0Lqk9ULcvavssUs4wagaNQHwAX5YaN1Dx+U04imhGQi0iP 4UE/I2Koa/YNC1rzxkWL1UO7K1dW95kL0fNUN/pRltO3ShXQHw2WkytmT//QMryO taMxNQ== Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhqwg12jp-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:08 +0000 (GMT) Received: by mail-qk1-f199.google.com with SMTP id af79cd13be357-8b2e2342803so615479085a.3 for ; Wed, 07 Jan 2026 10:15:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809708; x=1768414508; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=j2BT4ALqtU5AjsTQozcF6Tmng8niaFOYcGnl/GxzzY8=; b=jasvV9lll005TRM9cd1rxGtaLCKY2kwEPJ7t0syKpAZ8cB9kWU+dFO0xJSn/dbFUXZ HYa9JzzwmrdR/ljimDHwmLkM/b5dQqfN4KpQYjNKtQmxbVprgRpq3AA8lnX7etgVFxnq EQAEeSgrdfuCKr40eH5f2334wafcOPvclkrDxrYv1zD1Rae2yxdE4CwdNvB2AJ2G/FhT M6EROEW7bIkeP9HE3MLvOamXqTS7HE7ffmhu02lN4Ex5Z/AAO3EknTZBa3XmCiTfy5Iu ArSoDdLHxeVU4SqAK4j56nMWo2dFLynIRnM4fVTmbfxzvTp2JPZseMamNODuMjoLHDcU buZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809708; x=1768414508; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=j2BT4ALqtU5AjsTQozcF6Tmng8niaFOYcGnl/GxzzY8=; b=p/vxyv08klHa8hfRXJTbAc1itbHKY66yspSpQllIPA+/37k3w8X3ZFmRQ6sNmBqxp5 YCgeZ2wHdPvgsayIYuS/KdUmcq53za+C82cUVfCw2BgnSL/qPKxNXc7z2cyX/lQijyjJ BXRF1VuTVg0EmLkFnKvsLes+gOHz/o+lo7LRkx1VmPTfXMk5W3qQvZ6Ombf3LQRyUfN2 ys3RpkbyFcJbn9nYFUkuudKcTuZooGlN8g8bcOA9LMWjywGZej2VK90fYge9GfjaNu3t elXpHFLZUwHm5inQvxz09zBp/nqXwygTxmFshzdAgVFMp7J71Dvv46oBuWoe85Fd6SxJ 052w== X-Forwarded-Encrypted: i=1; AJvYcCXp9uap/C6l0fpSQY5swxL+ufKNtksv349bhOoeM3MSMzaqneW+5COKi7wUlIloUFrxKY+VO3Q4QfhzZg==@lists.linux.dev X-Gm-Message-State: AOJu0Yxy4ARY5GDYA8eJNnK+hnT2O+6P8o36wGz6iZ+35CC5KTuWTaed ch/DgGnLWrfW75kjrspfua9qU/bCJNeO+ZwyRyxq62KBNXMtSmYg3xThzIkDh+NNK+8M0Dvo9GK uKAb0wMTPkHsALjq810qfYpo6jrgwbV+w82XMqsEiAalDxXn1K3ogZqpVFS2NRD+KwQ== X-Gm-Gg: AY/fxX57mb5PY3P25Yc1PxVmxmNGBXBs2EM5B5W8/rBvLA/bW/cIZ8vRpM53lgr48YQ hvdtpU6Ar3L7YOqIJdqfibj0hiU1L8iTL+4rTkV1nXHzoKUnY0Exh8JD203gABdnS2/isVZgWTl pWVHBQbQ/fsEHTWKnyUESPnN8nQh/nxXdTiZCUKcFhsjHORp9s7uVgdVzdaA1845Pb6GOlekTpo q5X4ZkW2qvVANbufqVRwy3X+1sKUxaplLXNutN7QcUHcbtJgjAYbmbXPeqPiJEztBf1A/5NI8dc nwahIFRK8NV6y0VFpMK0OiWgTuUHUepKQXr/W70dpRl88QRu4CEmZRVvgHWaCCBXedrFYW8K263 uR+POrsUM0QC4cX6w1sjzWz81sCI7PcEgSyK6XyqKc62hQoatcx6mMxXg+bktRIvpWTGznOrktF kwSDJiCZJiVEM9KRlxcqRu5sM= X-Received: by 2002:a05:620a:bcd:b0:8a9:be12:75cf with SMTP id af79cd13be357-8c3893f7d8cmr453746785a.61.1767809707644; Wed, 07 Jan 2026 10:15:07 -0800 (PST) X-Google-Smtp-Source: AGHT+IEQiBI0nmEwHGDiwmCMtLl/jayFaEU1m0Axo7cKoiE+2HfeOqOTLbx0TrveKVWGZFW8ipORjw== X-Received: by 2002:a05:620a:bcd:b0:8a9:be12:75cf with SMTP id af79cd13be357-8c3893f7d8cmr453739285a.61.1767809707118; Wed, 07 Jan 2026 10:15:07 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:06 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:15:00 +0200 Subject: [PATCH v4 03/10] drm/sun4i: hdmi_enc: implement clear_infoframe stub Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-3-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1354; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=i9/GyfQ7oCfW1uA2EJ42B3bpRaDaBcnVtDJI1DBQZYU=; b=owGbwMvMwMXYbdNlx6SpcZXxtFoSQ2bcoiW5J9/tWb3J4tHugrKAs3JeyiZt4rWpsWICpksuC jCtyXnbyWjMwsDIxSArpsjiU9AyNWZTctiHHVPrYQaxMoFMYeDiFICJiH5k/1/oclnK/Zz/ja8L v6t7HOL18cg1yeBbaeqq8pOvrnf+XBOj/s8szY+lzvBERUkLGakuejhjjs20u3oewa9eNacmbZf ZErVva/T+iCPe/yKqIoU+z/jzp+2KV28zo9cVjnoraUd13pIVM4oiTrkH6U3OTdOSsJwVt8L5h/ /T3zkX1/bOvsVXv8vj+1+jxyrXD8c0ec7+2mYVenlOTuTBvsSSQqvGuY38Xj3Tv9TeX6BzUVOlc 4rNlrpcI3a1MhGFq3s68l8oMFjf+RBpdHu3yN9MrYxg6YlHexbMklnWv1mXiTVGP2Lax/1P8qs4 j9ptzHJSW9Jgcn/7ST4zM4W/whffsC+fsnRj8rbPKZ+zAA== X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-GUID: fdknZFftc1tkGG75mWIpoG1tw5ohxQ4R X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfX0ib4UUfkM7tJ vRN+aXtieZSl5zDMFJ9GM/XVdNAKi4L6vb4lZ9s4PX9owxPYCdS0+lLCQTizpN1LZz9xlgYzQbr dntEDYQ+0H3FBnizJJfwDjP/smvARNm5AelN/Nic7ZYpZvqKoV2YTCSHNcEuq6htyLDOTtk26I8 wBBYCzpUPKwV61bxeaO1/pmyW3Btuyg2zdjQmJggNhTLEa13Pmt7wJCquR12iR9USN3MlY2X2mz yKjUezfZwcr1qEqJJn3wxtAUEzlYemuopCqGjdI7gad4tWqr89RSWb4seVD8Ld8YFDDxUtKIpQi CpE4LTlNYARXWS6kGAJu7ZQOTAUysHZpqtcvFIQHGncVMYju9BfVQSXnEWyOrc8D3kNMxCio79c CaUBmMOBwaXYn1PFjFVHSWtK6FZympMQeaTNiIblyWhcE5hkSZRx/EAl1RWMojt26FrV7tnYfsF be9x6WUP33ctdHNsQ+g== X-Authority-Analysis: v=2.4 cv=Pa7yRyhd c=1 sm=1 tr=0 ts=695ea2ac cx=c_pps a=HLyN3IcIa5EE8TELMZ618Q==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=J8re_t9gDAGCMx8MSDUA:9 a=QEXdDO2ut3YA:10 a=bTQJ7kPSJx9SKPbeHEYW:22 X-Proofpoint-ORIG-GUID: fdknZFftc1tkGG75mWIpoG1tw5ohxQ4R X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 impostorscore=0 spamscore=0 malwarescore=0 clxscore=1015 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O In preparation to making clear_infoframes callbacks required, add a stub to the sun4i driver. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index ab0938ba61f7..6263ee15880a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -40,6 +40,14 @@ #define drm_connector_to_sun4i_hdmi(c) \ container_of_const(c, struct sun4i_hdmi, connector) +static int sun4i_hdmi_clear_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type) +{ + drm_warn_once(connector->dev, "clearing of AVI infoframe is not implemented\n"); + + return 0; +} + static int sun4i_hdmi_write_infoframe(struct drm_connector *connector, enum hdmi_infoframe_type type, const u8 *buffer, size_t len) @@ -236,6 +244,7 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev) static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = { .tmds_char_rate_valid = sun4i_hdmi_connector_clock_valid, + .clear_infoframe = sun4i_hdmi_clear_infoframe, .write_infoframe = sun4i_hdmi_write_infoframe, }; From patchwork Wed Jan 7 18:15:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 521 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 045063559C3 for ; Wed, 7 Jan 2026 18:15:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809715; cv=none; b=hGUhJXM0vCR3MDhXcakW/KikFJMdsOtL6HznXgBTlosN6J+JeuNxPo/LSwIonCPzD/eTaiaDhKW4uYjY4LIjhrivJG0wpRiHpcsbTR8cjr+0uVbog9eqld12Vg25zTkzn+M34sxG1kgdyH03xyQahCtjIpUsrONNO0QEOrKa6R4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809715; c=relaxed/simple; bh=LT/feZw0CtZODegcFJ+4Vz9a++4eaSKUzh1MRBMJ8BM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KWhPDlsDEIvBXwKk5iNvC0qLyrwmC4k7DFzwhRdBeaPQ1PMkUWsQW7NcqP72rdI+xxJ/a8abJzdB/WhlHCeUyL7tyrf4uUdEWsUGZgBYho2JW1IVw2iCE8McTEYEiEikUlIJs0fF4fhwjUpZ2ANgKk7Mfed2FD0vTF2ODnhN3To= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=Md2Ezqvu; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=TvqloOBk; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="Md2Ezqvu"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="TvqloOBk" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607H6eQB2454263 for ; Wed, 7 Jan 2026 18:15:11 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= iDMa/3+oiy4vVFgOo69jkSU/S1Hmln8yfU7tzvohWvc=; b=Md2EzqvuQa88+NJo eO9CT6W6zNA2/mmL8bAXb6GdF2TgbDZwRiPcGhExvC1k/rcBmLe+40l0vu3MF44S QoUy/eggghWay8HBTYciFmcK5g2Aaf1FDZD9rolR0ZkMC1fbK/4XwkN295/ny6OD 7Hj8ZpUvDJbaSgxgOTfCtEZ/BOyzVnuN1jYl2TiJ7O858oy/50DcJLZtCL/98fOS wCygVIIJJAKqG1PSF668wIDMDoHtjoc5LvKMAp7ude/wxjONNzUeXjIqQCv44rac XA1DZJ9KsfhFk550JzlbWRLh4b1Kazpk8gIsV1iwDBjhCZWAHHgTWxHTv9A6e2dC QiQ2Fw== Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhmnbhpts-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:11 +0000 (GMT) Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-8b51db8ebd9so776588485a.2 for ; Wed, 07 Jan 2026 10:15:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809710; x=1768414510; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=iDMa/3+oiy4vVFgOo69jkSU/S1Hmln8yfU7tzvohWvc=; b=TvqloOBkPJocBVNsv2pO/76kIEwtfULI3pQQVj3/z8mTHpbGQagApnS9lP05qQsQos 8FCyEM7z+5THk9ilanWM4sjxYKrK5lfvrj1hMIG8gPcrFnOAyE84By87OBQEecNXUHHF ER1QYVdVFKWwQq5Ef3rm7S+7xtrGuoIYjVWppudisqhxru15Z6i8pYnqzeHY2JpVVmFX uI3LTur9/mjdW736r5kkZ6dZ+1pGuUf9qz5bCG8y6TZ3UTKY9DLzsNez+HnnOA+L/uPn iR4mcjbMaK0KaZNlbnR5gyiUq/xTp33obp1jGnA9GrbYAOH/E2gQGJz7QXjWJL1s6v/j TfCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809710; x=1768414510; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=iDMa/3+oiy4vVFgOo69jkSU/S1Hmln8yfU7tzvohWvc=; b=uK6t/TFBbEmO0J0zY4Rz7LtQEaFEseY814j6k0OTvraTQkNwJQ/csX/Ku0/AG310Pb EoSHt3qqLOpy3y+DS0SlOz78L1TY729NpPaouw5V+NR7WQyJ4SsrCc0WkvVsJJM7PU/T AibwN6SHDIhlDoowcFi/shpRKJqb36kRqLIcPd9Nhps0EJjoNCFau6GUD3xaIJLdPnYE 0Z+qob+z4qQkzyONnGu0uAZB1oKgOeRKIjkcs1ZgbksTMwt0YPB6G6YqvFMxO9iK+f8M ZBpI/xtHKZLtOzbwEHw0gylEp6DPoS19Obg29zeVfHnyB+85XpevjulLCIgiyMZKH7wu N9Ew== X-Forwarded-Encrypted: i=1; AJvYcCVepCoXfNT7fm6+q+GGEY/uFm4/kc+U4Kc2fImV/9LEcpGISxi9EaOOa4NMK2pi+UWhpcjYNVPJSczdVQ==@lists.linux.dev X-Gm-Message-State: AOJu0Yx7K/7Bp530cvNc4hcvflvrUOv5QO7nCsKS8mBM/FGGvy+snW7N dr+/0/xC+Yjg2Z/LxmhJJyCYJpeV/KAro1/azfYDAwJIDP3RkxRNzEOqWWVmtMgkOn1x3sYUAo1 X2mLN1rj5Ufdl6pl2+s4UDRlXTYVj8jSZg1IE7ySGj5uyTM+qAzCbqjBYxYufDRjQbA== X-Gm-Gg: AY/fxX6qwtQ7nXNyzS/d2u91T8sWJ78UMMKwlzsvBR5hmFnJ2CYAHeMOd9sYrGTzhBP So+ziZ4U4LH4yHBBx7dAbhJ7P/gPjUnynhp3Z2n/xTsbDUvmrcDtcIW6LUFuk25EDlf0/sNR4rM /1OA5hV1JQJdjNA49bO38LXcz1wlKmkR9LeJWDXReG0VVKhxVpvRjAax5EXuJD769kE2+5kvxvJ Ogr/mFFbZx335C6or2csaIJklmiHaDRtoVKy70V+Z/pAm5xNIA6pVoVPP6xAt61j+0KxPrigrOG 0IGS2Cun21cbyXbpiK9h4VqOm10HmtXMf9X1a2C6bLLX1yix+jR9OpEWzrnvTC5HP2JuIoCm+Gd PQq3TpGZ5Zp6YtdO2mNpke5yPBsWj0nts9As3CZhWed8keXsK7LleDpGS0YWYDu3Gu7jT/pPW1b ok99NnXOZw60EWGisM29pATsY= X-Received: by 2002:a05:620a:284d:b0:8b0:f8c4:a5ff with SMTP id af79cd13be357-8c38939548dmr415672285a.23.1767809709953; Wed, 07 Jan 2026 10:15:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IHNnSAiO2TN35uowVz5nUxPTarPKtrJKczFdjq8YtoRDL79CU00FYbWgXjKjI0hV5LSFGnXqg== X-Received: by 2002:a05:620a:284d:b0:8b0:f8c4:a5ff with SMTP id af79cd13be357-8c38939548dmr415665885a.23.1767809709293; Wed, 07 Jan 2026 10:15:09 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:07 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:15:01 +0200 Subject: [PATCH v4 04/10] drm/connector: make clear_infoframe callback mandatory for HDMI connectors Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-4-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5425; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=LT/feZw0CtZODegcFJ+4Vz9a++4eaSKUzh1MRBMJ8BM=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBpXqKkh8Uw4zR96uxdfP3B5zJVi4OZsf/KLRV9b W7ObW3B+sCJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaV6ipAAKCRCLPIo+Aiko 1b8ZCACVHXOVdotvxgogUT3C9rJjVAwz5C7cHtd38CQCrPUocd+kYKlETxwvuPGlVJvCHUeAM8X 5/dbL3WQ4QoPcR1iBb8oDv1v6oB7mJeoOsV/aJpocz5lRWP8NYncKNG1ePRkGEpeU3WHjpZqIFS kYhO2EzWmB1sJ9inh/CWFfZvf4ElzxfTYGmj/kCkM/z5sVjYqKRiqW7x7HsR8MtVNsWKFqCfk3V dVqKuC0OSU4IUdW2h3I1weh+JiTliULMhONr5eVnvaNom/JZ5QKI3oJK+lJB7grw4QWcRHvOVP2 EkMSiWdtnpNVOEWxdQ2Q6yJ+NQAxzjfP/bYkeyAmuPwG08rp X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfX9NFSpbziTesV y+HzcNPGrfLoTHBTRDgYFkZ7QCpuvVzDUD50gicawvVudpwZXY5IVG1JgV2XL0Z1jE3thv8xSxe iqSW/z16ClrYUDgRpWENiZQNqp9jyyBVqh9g6CMkP6o6tn7BWuLQOZl43ooBLSsjmkxGWxdwdS4 +Ig1Dsy9741vf2O0vzmwlzUgekakaIO0HObQdj0wPxjI6wZucz0CNwAh0o8QW7OIEFU8JdXmjq9 49eUtkNZhY1SsWN2w2+hGD3/6O2VFMUZNOSEzQGsIz/qaPwzBhjKPVZN1TGT4gbnBvNFK41yRWk 39Za0oAcFcyNQDVoJoyTtdVEA/G2k8LuIIaIGElo9kYoSVRmhZRQYyG8LN/R5s9AgLSqpa5ImQ5 KYFXNMCzUKt48PthQxxyZmuFtd7LHW0lL7LfKfR0uB5MhSYZUMGv+2rb5zs3Gklae/YJmkry6Hg EhgBabpH6t4NfyVHkOg== X-Proofpoint-GUID: GPP4V_72ybXAcXf4WJwLPUJ424Ey_OQp X-Authority-Analysis: v=2.4 cv=eIkeTXp1 c=1 sm=1 tr=0 ts=695ea2af cx=c_pps a=50t2pK5VMbmlHzFWWp8p/g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=9fyoTQa5ixSHU3Y6h0oA:9 a=QEXdDO2ut3YA:10 a=IoWCM6iH3mJn3m4BftBB:22 X-Proofpoint-ORIG-GUID: GPP4V_72ybXAcXf4WJwLPUJ424Ey_OQp X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 clxscore=1015 malwarescore=0 suspectscore=0 phishscore=0 impostorscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O We already require both hdmi_write_infoframe and hdmi_clear_infoframe for bridges implementing DRM_BRIDGE_OP_HDMI. It makes sense to require the clear_infoframes callback for HDMI connectors utilizing drmm_connector_hdmi_init(). Acked-by: Maxime Ripard Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/drm_connector.c | 4 ++++ drivers/gpu/drm/tests/drm_connector_test.c | 15 +++++++++++++++ drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 22 ++++++++++++++++++++++ include/drm/drm_connector.h | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 4d6dc9ebfdb5..40e025712c9b 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -600,6 +600,10 @@ int drmm_connector_hdmi_init(struct drm_device *dev, if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12)) return -EINVAL; + if (!hdmi_funcs->clear_infoframe || + !hdmi_funcs->write_infoframe) + return -EINVAL; + ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc); if (ret) return ret; diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 22e2d959eb31..f356ea695ae7 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -25,7 +25,22 @@ struct drm_connector_init_priv { struct i2c_adapter ddc; }; +static int accept_infoframe_clear_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type) +{ + return 0; +} + +static int accept_infoframe_write_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) +{ + return 0; +} + static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, }; static const struct drm_connector_funcs dummy_funcs = { 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 80f819a9ff5b..cfa14a6eb97f 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -78,7 +78,22 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto return ret; } +static int accept_infoframe_clear_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type) +{ + return 0; +} + +static int accept_infoframe_write_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) +{ + return 0; +} + static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, }; static enum drm_mode_status @@ -91,6 +106,8 @@ reject_connector_tmds_char_rate_valid(const struct drm_connector *connector, static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = { .tmds_char_rate_valid = reject_connector_tmds_char_rate_valid, + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, }; static enum drm_mode_status @@ -103,6 +120,8 @@ reject_100mhz_connector_tmds_char_rate_valid(const struct drm_connector *connect static const struct drm_connector_hdmi_funcs reject_100mhz_connector_hdmi_funcs = { .tmds_char_rate_valid = reject_100mhz_connector_tmds_char_rate_valid, + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, }; static int dummy_connector_get_modes(struct drm_connector *connector) @@ -2441,6 +2460,7 @@ static int reject_avi_infoframe_write_infoframe(struct drm_connector *connector, } static const struct drm_connector_hdmi_funcs reject_avi_infoframe_hdmi_funcs = { + .clear_infoframe = accept_infoframe_clear_infoframe, .write_infoframe = reject_avi_infoframe_write_infoframe, }; @@ -2543,6 +2563,7 @@ static int reject_hdr_infoframe_write_infoframe(struct drm_connector *connector, } static const struct drm_connector_hdmi_funcs reject_hdr_infoframe_hdmi_funcs = { + .clear_infoframe = accept_infoframe_clear_infoframe, .write_infoframe = reject_hdr_infoframe_write_infoframe, }; @@ -2790,6 +2811,7 @@ static int reject_audio_infoframe_write_infoframe(struct drm_connector *connecto } static const struct drm_connector_hdmi_funcs reject_audio_infoframe_hdmi_funcs = { + .clear_infoframe = accept_infoframe_clear_infoframe, .write_infoframe = reject_audio_infoframe_write_infoframe, }; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 8f34f4b8183d..4543833acdec 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1253,7 +1253,7 @@ struct drm_connector_hdmi_funcs { * called multiple times, once for every disabled infoframe * type. * - * The @clear_infoframe callback is optional. + * The @clear_infoframe callback is mandatory. * * Returns: * 0 on success, a negative error code otherwise From patchwork Wed Jan 7 18:15:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 519 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5CE33557F6 for ; Wed, 7 Jan 2026 18:15:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809721; cv=none; b=F8OOc3S4tNKOmqwHQA1azWI5qw0ljx1REZFsJZu43gFWWnvVLNOVeMGmAXcmdG6kYbcqo9cwFCc6iGrKy/HRwO1gQnBstSWdWghJ0pHoYb7Cua5GScJkBq1ldlwyX5OeHTyhdh2RSKZY1evR0eG3WHcZNztE8ZeiEQmYVjYq7dw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809721; c=relaxed/simple; bh=rrAYuYRkoLgiZDcEXYJBgQ4P9j2sq4poijx+pmGceSA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gI7EVnDSXk+tEvs3fg00GHXw0372x72SqcQsHCK9tk6h+nkIWPRxpdLBqr44UjRL7eKjnK/3HKofinGmJLK0HB7IeG4a2gsZyvJW67bEAi0XJ5o9rHYAcmjzUgM/s/dUIEgQbShDTyCd8AUeat0V5U8ZQLYz7TwEEKGFlJe9m38= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=ZQwobCkp; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=J4bkxjJa; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="ZQwobCkp"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="J4bkxjJa" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607HB6IA2593341 for ; Wed, 7 Jan 2026 18:15:16 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= /G9oYIZxPHvtNlgDHuyoJcBPsfPtNnxLcd1dUJtcS+o=; b=ZQwobCkpTW2MdBiK cBSDmjNESFPC0lk+Ot4ZAVWIN/bSnuzmsbA4F2uN8J/GQsy8hcO9jNjNHs6g6zLG 5gZ3dJBpP9n0UhuZajKT+SEyRoundu9vt/qUnjFcUSnolLqEq2y6K0Is0GA3/NLT tZyppf48BtIr600EFVphrKgfiWKAWG9zJs5MBuskH74x9pnxtHSmERdXjSUYGTLU ILP8qV+uM7amINTT0Pkcuo6r5naipuJnFftjcvKP9VuDv4E0See5HRp9QKTXKGDE 4F+UBimIU7IV/TQZrx+6Wjb5KyBbh/RamvtahhRj/K5rz5HDyJjsnuAMHnBnOgyB QZ6OdA== Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhn291n46-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:15 +0000 (GMT) Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-8b259f0da04so605135985a.0 for ; Wed, 07 Jan 2026 10:15:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809715; x=1768414515; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=/G9oYIZxPHvtNlgDHuyoJcBPsfPtNnxLcd1dUJtcS+o=; b=J4bkxjJadivPqJIovZ2PGn1cEuPV1op19bLG80BIcVaMhs+pvN95auTA+T6SCdjLHD CzuSkf5a8p2k78wRzfhTfnrT8zbd3+iGAIghLtFULnOijwECsAbyFmkoJn4qEn1bDJ4B 2xW80BP+R+0ZiDlHaPUokBUgEJFz7R4BQEGZNZObX0MXePIvr9OFFqXUAWCFctGNh01P vxSoCX6AFnptCJX5XsF9q8AJamR2RkpAVnIb1FSzuI4POa9jK/93KDyEQH87J+7ECkyl I+IEAuovRlxLlZDtboljYAmZ3ZamBQNhoEfqSsInnGB28v5JneiBWxzATEPd38F6Dk2h ESJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809715; x=1768414515; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=/G9oYIZxPHvtNlgDHuyoJcBPsfPtNnxLcd1dUJtcS+o=; b=BAFtQuc3jMny1XQrv47xTah7/B1moVuhyAYIuyas5VeCdvqsnDpjMVY7SqiJLY17Vc E50Vc6C1IgXfEKDOQtBLVP53RIJdOsCWvN4MSuWUnIGtCvABh3GuiDKV7x0cdVjGF+6B oQ0GyaKNlqmv6dGK9Xw1ExM8PggBX7Jci4iI3AruObO+ovvGAMHTVF26F8f5EAdnYafW ZFIDpJxY+76fOBWsxawxTyuNQs4YOtO0yomfIMjfsdDv4Cuwg4SzsiWKsOW62EsHuBrv x3CgdRhH6bA+njOvT1ljA1G1MmYtDwWA2q+3diuewSquKnq6tk1pCr/Wf98GztvVAsYU jXVw== X-Forwarded-Encrypted: i=1; AJvYcCUBVSIkr8j3ZoW9Kjkrzx2p6qfcqtT3Rv94l/4K7fik0oqEVCGizNk7f6GZvcCzKa5yrj7qzaOob/ARRg==@lists.linux.dev X-Gm-Message-State: AOJu0YxXBBL2viO5utM6d2qhKlKN7PSmXoYTDv2dH/DFsX2yNxMVVEVm nd3LytI/E2GlF8hwpDzVtWgpjQZq+sfni9BT1X4PnMiy6YS41gR/tpQnrQk8+0ABbNcyLP+H1Kf n+Eu6k8J+LeVR3ESQYphQfsfUE7FAe4JXuoGZFhBuFOXPXXXqNUAijPtv/ZxAQKnpLA== X-Gm-Gg: AY/fxX4DeiCtEz1pBBZ4qCb+BX3XKoE3vSgBJEUBM5Iy2GRQh5Ws+/gGEQ+SKbJan1d FcjbjAP0+kd6w0MaPq6y4TjuyylC3kIRmXWe5u43MxHp2M01zT6h9OXHPyMIh0E/iOYK3V4RFIK 3HcwSUa6IZyW/tNWgVROG+mzo7kGS5EvwGRN2K0vUewPak96Y/Si7aS7C0sKXm4995LUWsmkyBF qnBoUemxCOHMuVT43FR18IuwEqFIqMBwZlvK/zaRNKSP9GGAapQhP6rA1OguZ4JjKuZIjrK0A0C JxQ1o9GD5J/JFzbRJzc5idlBp4uVVa48fi75IVIaU0dz7bx3Xfsr0yD3KVURwEYGIZaa5QxkM+5 OY7Yo2yf8uSEpZ9Tfw/Nloy/C+IANZYbB2UCMt6Er7SNkah0InewBoB5yt3vKMzN9hyqO0BA/nP n580pathTm1FJlS0phY1WPARQ= X-Received: by 2002:a05:620a:40d4:b0:8c0:f13e:42ee with SMTP id af79cd13be357-8c389420351mr442722385a.88.1767809712358; Wed, 07 Jan 2026 10:15:12 -0800 (PST) X-Google-Smtp-Source: AGHT+IHBRowqaOMG1FOaqGi9pLMNYxVafY2/thMkhgmNvOZZ083Yq6iefukoR+kl3+0wFUVHPYuSVg== X-Received: by 2002:a05:620a:40d4:b0:8c0:f13e:42ee with SMTP id af79cd13be357-8c389420351mr442710385a.88.1767809711036; Wed, 07 Jan 2026 10:15:11 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:10 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:15:02 +0200 Subject: [PATCH v4 05/10] drm/bridge: refactor HDMI InfoFrame callbacks Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-5-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=59639; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=rrAYuYRkoLgiZDcEXYJBgQ4P9j2sq4poijx+pmGceSA=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBpXqKkEZbNZ/Br4hx1XBX2GgPBWTb5SY6twy3gh XbZk6d6I9KJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaV6ipAAKCRCLPIo+Aiko 1VwMB/9sl/uLZB5vpOyqv9+DWDFFLjZoLVZME2yljS7sx0rinb4UEdksU9xR3QKb/D2OcsS9g5e GlH/bvxyFUj9cfGEtSJOW8udZAlgl9QU+pC6ZjeBmzlYrkvpFGYk2lSdt3ILbSY+Y2PPLLL5PTH cCsCKCumyB4sIoDVBdxubiGMo/Qh8n1AYm7RDS/8x4VL4TrYIcd5hhiVSzONg8egGqEWo0r0T/T usq8dVMwmN47s0YAP5yDVi+irL2PMe/PKZDwTNJrDuCl3FELqpNcVuzqvlY3GKTGcGyil1LfIJx 3yW1Gz9Oktxu3vnScRM1iRcppsEpdL5xHbEThO42FyWn+Z3R X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-ORIG-GUID: -YhwZoLAk4TG13HQdgc9qrmXRzBIZRgU X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfXyOQVRhQjj7T5 sPHPrOGeB8SPITKgl5JbaMIrwibtiq4Vyg2uEGTVt8eK5NT8TJ0xsQBNd+zohfntNPJ/YBTUcpq HnHvb6VMQ7Ku1uyvWNdFSdetPH62NPSyuhb+Bfukuo5Rf3ZVelkDuC6+4uvoEP/ur82VF6nI8RQ GbsUdQrUD2HhI1/+UlldtupUSP8WEt2CBeTnl740phFcVl+8bASQUADLGPtmljW4Wme9zWOfrUB SOWqr8i1w73PaIpHer0ZodFZ7k9TceV1OwLUBxXa6gWlezndyEWaO5/l16qK3/B317C4+WLrjpS JWaBKDTqGlB6EdGY/gZmaYvYbpMQrncp6LDIsNY3uvW+pwNVdrl6gH5u8qjyr/L+aJTchgE5t9e RIMStrcI008panRb7dXy74ANufeG7kx8g1Br2JOtCKwh6IXPxQ41UCfkQNj1ae+3Jx9s9qvh9tc L2MjqhYvA73HrC5aA7w== X-Authority-Analysis: v=2.4 cv=P7k3RyAu c=1 sm=1 tr=0 ts=695ea2b3 cx=c_pps a=hnmNkyzTK/kJ09Xio7VxxA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=GAiaypzmODBVVc3kIZ8A:9 a=QEXdDO2ut3YA:10 a=PEH46H7Ffwr30OY-TuGO:22 X-Proofpoint-GUID: -YhwZoLAk4TG13HQdgc9qrmXRzBIZRgU X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 spamscore=0 phishscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 impostorscore=0 adultscore=0 priorityscore=1501 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O Having only a single set of callbacks, hdmi_clear_infoframe and hdmi_write_infoframe, bridge drivers don't have an easy way to signal to the DRM framework, which InfoFrames are actually supported by the hardware and by the driver and which are not. Also, it makes it extremely easy for HDMI bridge drivers to skip implementing the seemingly required InfoFrames (e.g. HDMI VSI). Last, but not least, those callbacks take a single 'type' parameter, which makes it impossible to implement support for multiple VSIs (which will be required once we start working on HDMI Forum VSI). Split the callbacks into a per-InfoFrame-kind pairs, letting the bridge drivers actually signal supported features. The implementation follows the overall drm_bridge design, where the bridge has a single drm_bridge_funcs implementation and signals, which functions are to be called using the drm_bridge->ops flags. The AVI and HDMI VSI are assumed to be required for a normal HDMI operation (with the drivers getting a drm_warn_once() stub implementation if one is missing). The Audio InfoFrame is handled by the existing DRM_BRIDGE_OP_HDMI_AUDIO, while the SPD and HDR DRM InfoFrames got new drm_bridge_ops values. Acked-by: Maxime Ripard Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 180 +++++++++++++---------- drivers/gpu/drm/bridge/inno-hdmi.c | 41 +++--- drivers/gpu/drm/bridge/ite-it6263.c | 95 ++++++------ drivers/gpu/drm/bridge/lontium-lt9611.c | 143 ++++++++++-------- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 110 +++++++++----- drivers/gpu/drm/display/drm_bridge_connector.c | 70 ++++++++- drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 8 +- drivers/gpu/drm/mediatek/mtk_hdmi_v2.c | 110 +++++++------- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 195 +++++++++++++------------ drivers/gpu/drm/rockchip/rk3066_hdmi.c | 47 +++--- include/drm/drm_bridge.h | 127 ++++++++++++++-- 11 files changed, 705 insertions(+), 421 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index b9be86541307..1050bb62280b 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -887,88 +887,111 @@ static const struct drm_edid *adv7511_bridge_edid_read(struct drm_bridge *bridge return adv7511_edid_read(adv, connector); } -static int adv7511_bridge_hdmi_clear_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type) +static int adv7511_bridge_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) { struct adv7511 *adv7511 = bridge_to_adv7511(bridge); - switch (type) { - case HDMI_INFOFRAME_TYPE_AUDIO: - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); - break; - case HDMI_INFOFRAME_TYPE_AVI: - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); - break; - case HDMI_INFOFRAME_TYPE_SPD: - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); - break; - case HDMI_INFOFRAME_TYPE_VENDOR: - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); - break; - default: - drm_dbg_driver(adv7511->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); - break; - } + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); return 0; } -static int adv7511_bridge_hdmi_write_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int adv7511_bridge_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) { struct adv7511 *adv7511 = bridge_to_adv7511(bridge); - switch (type) { - case HDMI_INFOFRAME_TYPE_AUDIO: - /* send current Audio infoframe values while updating */ - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, - BIT(5), BIT(5)); - - /* The Audio infoframe id is not configurable */ - regmap_bulk_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_VERSION, - buffer + 1, len - 1); - - /* use Audio infoframe updated info */ - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, - BIT(5), 0); - - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); - break; - case HDMI_INFOFRAME_TYPE_AVI: - /* send current AVI infoframe values while updating */ - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, - BIT(6), BIT(6)); - - /* The AVI infoframe id is not configurable */ - regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION, - buffer + 1, len - 1); - - regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_LENGTH, 0x2); - regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(1), 0x1); - - /* use AVI infoframe updated info */ - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, - BIT(6), 0); - - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); - break; - case HDMI_INFOFRAME_TYPE_SPD: - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); - regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPD(0), - buffer, len); - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPD); - break; - case HDMI_INFOFRAME_TYPE_VENDOR: - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); - regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPARE1(0), - buffer, len); - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); - break; - default: - drm_dbg_driver(adv7511->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); - break; - } + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); + + return 0; +} + +static int adv7511_bridge_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) +{ + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); + + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); + + return 0; +} + +static int adv7511_bridge_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) +{ + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); + + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); + + return 0; +} + +static int adv7511_bridge_hdmi_write_audio_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); + + /* send current Audio infoframe values while updating */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, + BIT(5), BIT(5)); + + /* The Audio infoframe id is not configurable */ + regmap_bulk_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_VERSION, + buffer + 1, len - 1); + + /* use Audio infoframe updated info */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, + BIT(5), 0); + + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); + + return 0; +} + +static int adv7511_bridge_hdmi_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); + + /* send current AVI infoframe values while updating */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, + BIT(6), BIT(6)); + + /* The AVI infoframe id is not configurable */ + regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION, + buffer + 1, len - 1); + + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_LENGTH, 0x2); + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(1), 0x1); + + /* use AVI infoframe updated info */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, + BIT(6), 0); + + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); + + return 0; +} + +static int adv7511_bridge_hdmi_write_spd_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); + + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); + regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPD(0), + buffer, len); + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPD); + + return 0; +} + +static int adv7511_bridge_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); + + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); + regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPARE1(0), + buffer, len); + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); return 0; } @@ -986,8 +1009,14 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = { .atomic_reset = drm_atomic_helper_bridge_reset, .hdmi_tmds_char_rate_valid = adv7511_bridge_hdmi_tmds_char_rate_valid, - .hdmi_clear_infoframe = adv7511_bridge_hdmi_clear_infoframe, - .hdmi_write_infoframe = adv7511_bridge_hdmi_write_infoframe, + .hdmi_clear_audio_infoframe = adv7511_bridge_hdmi_clear_audio_infoframe, + .hdmi_write_audio_infoframe = adv7511_bridge_hdmi_write_audio_infoframe, + .hdmi_clear_avi_infoframe = adv7511_bridge_hdmi_clear_avi_infoframe, + .hdmi_write_avi_infoframe = adv7511_bridge_hdmi_write_avi_infoframe, + .hdmi_clear_spd_infoframe = adv7511_bridge_hdmi_clear_spd_infoframe, + .hdmi_write_spd_infoframe = adv7511_bridge_hdmi_write_spd_infoframe, + .hdmi_clear_hdmi_infoframe = adv7511_bridge_hdmi_clear_hdmi_infoframe, + .hdmi_write_hdmi_infoframe = adv7511_bridge_hdmi_write_hdmi_infoframe, .hdmi_audio_startup = adv7511_hdmi_audio_startup, .hdmi_audio_prepare = adv7511_hdmi_audio_prepare, @@ -1322,7 +1351,8 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | - DRM_BRIDGE_OP_HDMI; + DRM_BRIDGE_OP_HDMI | + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; if (adv7511->i2c_main->irq) adv7511->bridge.ops |= DRM_BRIDGE_OP_HPD; diff --git a/drivers/gpu/drm/bridge/inno-hdmi.c b/drivers/gpu/drm/bridge/inno-hdmi.c index ab4572eb8395..a26b99b101c4 100644 --- a/drivers/gpu/drm/bridge/inno-hdmi.c +++ b/drivers/gpu/drm/bridge/inno-hdmi.c @@ -584,34 +584,22 @@ static void inno_hdmi_init_hw(struct inno_hdmi *hdmi) hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1)); } -static int inno_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type) +static int inno_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) { struct inno_hdmi *hdmi = bridge_to_inno_hdmi(bridge); - if (type != HDMI_INFOFRAME_TYPE_AVI) { - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); - return 0; - } - hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); return 0; } -static int inno_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int inno_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { struct inno_hdmi *hdmi = bridge_to_inno_hdmi(bridge); ssize_t i; - if (type != HDMI_INFOFRAME_TYPE_AVI) { - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); - return 0; - } - - inno_hdmi_bridge_clear_infoframe(bridge, type); + inno_hdmi_bridge_clear_avi_infoframe(bridge); for (i = 0; i < len; i++) hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, buffer[i]); @@ -619,6 +607,21 @@ static int inno_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, return 0; } +static int inno_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) +{ + drm_warn_once(bridge->encoder->dev, "HDMI VSI not implemented\n"); + + return 0; +} + +static int inno_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + drm_warn_once(bridge->encoder->dev, "HDMI VSI not implemented\n"); + + return 0; +} + static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi, struct drm_connector *connector, struct drm_display_mode *mode) @@ -883,8 +886,10 @@ static const struct drm_bridge_funcs inno_hdmi_bridge_funcs = { .atomic_disable = inno_hdmi_bridge_atomic_disable, .detect = inno_hdmi_bridge_detect, .edid_read = inno_hdmi_bridge_edid_read, - .hdmi_clear_infoframe = inno_hdmi_bridge_clear_infoframe, - .hdmi_write_infoframe = inno_hdmi_bridge_write_infoframe, + .hdmi_clear_avi_infoframe = inno_hdmi_bridge_clear_avi_infoframe, + .hdmi_write_avi_infoframe = inno_hdmi_bridge_write_avi_infoframe, + .hdmi_clear_hdmi_infoframe = inno_hdmi_bridge_clear_hdmi_infoframe, + .hdmi_write_hdmi_infoframe = inno_hdmi_bridge_write_hdmi_infoframe, .mode_valid = inno_hdmi_bridge_mode_valid, }; diff --git a/drivers/gpu/drm/bridge/ite-it6263.c b/drivers/gpu/drm/bridge/ite-it6263.c index 2eb8fba7016c..3991fb76143c 100644 --- a/drivers/gpu/drm/bridge/ite-it6263.c +++ b/drivers/gpu/drm/bridge/ite-it6263.c @@ -759,61 +759,62 @@ it6263_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge, return MODE_OK; } -static int it6263_hdmi_clear_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type) +static int it6263_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) { struct it6263 *it = bridge_to_it6263(bridge); - switch (type) { - case HDMI_INFOFRAME_TYPE_AVI: - regmap_write(it->hdmi_regmap, HDMI_REG_AVI_INFOFRM_CTRL, 0); - break; - case HDMI_INFOFRAME_TYPE_VENDOR: - regmap_write(it->hdmi_regmap, HDMI_REG_PKT_NULL_CTRL, 0); - break; - default: - dev_dbg(it->dev, "unsupported HDMI infoframe 0x%x\n", type); - } + regmap_write(it->hdmi_regmap, HDMI_REG_AVI_INFOFRM_CTRL, 0); + + return 0; +} + +static int it6263_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) +{ + struct it6263 *it = bridge_to_it6263(bridge); + + regmap_write(it->hdmi_regmap, HDMI_REG_PKT_NULL_CTRL, 0); return 0; } -static int it6263_hdmi_write_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int it6263_hdmi_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { struct it6263 *it = bridge_to_it6263(bridge); struct regmap *regmap = it->hdmi_regmap; - switch (type) { - case HDMI_INFOFRAME_TYPE_AVI: - /* write the first AVI infoframe data byte chunk(DB1-DB5) */ - regmap_bulk_write(regmap, HDMI_REG_AVI_DB1, - &buffer[HDMI_INFOFRAME_HEADER_SIZE], - HDMI_AVI_DB_CHUNK1_SIZE); - - /* write the second AVI infoframe data byte chunk(DB6-DB13) */ - regmap_bulk_write(regmap, HDMI_REG_AVI_DB6, - &buffer[HDMI_INFOFRAME_HEADER_SIZE + - HDMI_AVI_DB_CHUNK1_SIZE], - HDMI_AVI_DB_CHUNK2_SIZE); - - /* write checksum */ - regmap_write(regmap, HDMI_REG_AVI_CSUM, buffer[3]); - - regmap_write(regmap, HDMI_REG_AVI_INFOFRM_CTRL, - ENABLE_PKT | REPEAT_PKT); - break; - case HDMI_INFOFRAME_TYPE_VENDOR: - /* write header and payload */ - regmap_bulk_write(regmap, HDMI_REG_PKT_HB(0), buffer, len); - - regmap_write(regmap, HDMI_REG_PKT_NULL_CTRL, - ENABLE_PKT | REPEAT_PKT); - break; - default: - dev_dbg(it->dev, "unsupported HDMI infoframe 0x%x\n", type); - } + /* write the first AVI infoframe data byte chunk(DB1-DB5) */ + regmap_bulk_write(regmap, HDMI_REG_AVI_DB1, + &buffer[HDMI_INFOFRAME_HEADER_SIZE], + HDMI_AVI_DB_CHUNK1_SIZE); + + /* write the second AVI infoframe data byte chunk(DB6-DB13) */ + regmap_bulk_write(regmap, HDMI_REG_AVI_DB6, + &buffer[HDMI_INFOFRAME_HEADER_SIZE + + HDMI_AVI_DB_CHUNK1_SIZE], + HDMI_AVI_DB_CHUNK2_SIZE); + + /* write checksum */ + regmap_write(regmap, HDMI_REG_AVI_CSUM, buffer[3]); + + regmap_write(regmap, HDMI_REG_AVI_INFOFRM_CTRL, + ENABLE_PKT | REPEAT_PKT); + + return 0; +} + +static int it6263_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct it6263 *it = bridge_to_it6263(bridge); + struct regmap *regmap = it->hdmi_regmap; + + /* write header and payload */ + regmap_bulk_write(regmap, HDMI_REG_PKT_HB(0), buffer, len); + + regmap_write(regmap, HDMI_REG_PKT_NULL_CTRL, + ENABLE_PKT | REPEAT_PKT); + return 0; } @@ -830,8 +831,10 @@ static const struct drm_bridge_funcs it6263_bridge_funcs = { .edid_read = it6263_bridge_edid_read, .atomic_get_input_bus_fmts = it6263_bridge_atomic_get_input_bus_fmts, .hdmi_tmds_char_rate_valid = it6263_hdmi_tmds_char_rate_valid, - .hdmi_clear_infoframe = it6263_hdmi_clear_infoframe, - .hdmi_write_infoframe = it6263_hdmi_write_infoframe, + .hdmi_clear_avi_infoframe = it6263_hdmi_clear_avi_infoframe, + .hdmi_write_avi_infoframe = it6263_hdmi_write_avi_infoframe, + .hdmi_clear_hdmi_infoframe = it6263_hdmi_clear_hdmi_infoframe, + .hdmi_write_hdmi_infoframe = it6263_hdmi_write_hdmi_infoframe, }; static int it6263_probe(struct i2c_client *client) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index a2d032ee4744..0628d8e737ab 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -843,84 +843,96 @@ lt9611_atomic_get_input_bus_fmts(struct drm_bridge *bridge, #define LT9611_INFOFRAME_AUDIO 0x02 #define LT9611_INFOFRAME_AVI 0x08 #define LT9611_INFOFRAME_SPD 0x10 -#define LT9611_INFOFRAME_VENDOR 0x20 +#define LT9611_INFOFRAME_HDMI 0x20 -static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type) +static int lt9611_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); - unsigned int mask; - switch (type) { - case HDMI_INFOFRAME_TYPE_AUDIO: - mask = LT9611_INFOFRAME_AUDIO; - break; + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0); - case HDMI_INFOFRAME_TYPE_AVI: - mask = LT9611_INFOFRAME_AVI; - break; + return 0; +} - case HDMI_INFOFRAME_TYPE_SPD: - mask = LT9611_INFOFRAME_SPD; - break; +static int lt9611_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); - case HDMI_INFOFRAME_TYPE_VENDOR: - mask = LT9611_INFOFRAME_VENDOR; - break; + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AVI, 0); - default: - drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); - mask = 0; - break; - } + return 0; +} + +static int lt9611_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); - if (mask) - regmap_update_bits(lt9611->regmap, 0x843d, mask, 0); + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_SPD, 0); return 0; } -static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int lt9611_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_HDMI, 0); + + return 0; +} + +static int lt9611_hdmi_write_audio_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); - unsigned int mask, addr; int i; - switch (type) { - case HDMI_INFOFRAME_TYPE_AUDIO: - mask = LT9611_INFOFRAME_AUDIO; - addr = 0x84b2; - break; - - case HDMI_INFOFRAME_TYPE_AVI: - mask = LT9611_INFOFRAME_AVI; - addr = 0x8440; - break; - - case HDMI_INFOFRAME_TYPE_SPD: - mask = LT9611_INFOFRAME_SPD; - addr = 0x8493; - break; - - case HDMI_INFOFRAME_TYPE_VENDOR: - mask = LT9611_INFOFRAME_VENDOR; - addr = 0x8474; - break; - - default: - drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); - mask = 0; - break; - } + for (i = 0; i < len; i++) + regmap_write(lt9611->regmap, 0x84b2 + i, buffer[i]); - if (mask) { - for (i = 0; i < len; i++) - regmap_write(lt9611->regmap, addr + i, buffer[i]); + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, LT9611_INFOFRAME_AUDIO); - regmap_update_bits(lt9611->regmap, 0x843d, mask, mask); - } + return 0; +} + +static int lt9611_hdmi_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + int i; + + for (i = 0; i < len; i++) + regmap_write(lt9611->regmap, 0x8440 + i, buffer[i]); + + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AVI, LT9611_INFOFRAME_AVI); + + return 0; +} + +static int lt9611_hdmi_write_spd_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + int i; + + for (i = 0; i < len; i++) + regmap_write(lt9611->regmap, 0x8493 + i, buffer[i]); + + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_SPD, LT9611_INFOFRAME_SPD); + + return 0; +} + +static int lt9611_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + int i; + + for (i = 0; i < len; i++) + regmap_write(lt9611->regmap, 0x8474 + i, buffer[i]); + + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_HDMI, LT9611_INFOFRAME_HDMI); return 0; } @@ -1003,8 +1015,14 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = { .atomic_get_input_bus_fmts = lt9611_atomic_get_input_bus_fmts, .hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid, - .hdmi_write_infoframe = lt9611_hdmi_write_infoframe, - .hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe, + .hdmi_write_audio_infoframe = lt9611_hdmi_write_audio_infoframe, + .hdmi_clear_audio_infoframe = lt9611_hdmi_clear_audio_infoframe, + .hdmi_write_avi_infoframe = lt9611_hdmi_write_avi_infoframe, + .hdmi_clear_avi_infoframe = lt9611_hdmi_clear_avi_infoframe, + .hdmi_write_spd_infoframe = lt9611_hdmi_write_spd_infoframe, + .hdmi_clear_spd_infoframe = lt9611_hdmi_clear_spd_infoframe, + .hdmi_write_hdmi_infoframe = lt9611_hdmi_write_hdmi_infoframe, + .hdmi_clear_hdmi_infoframe = lt9611_hdmi_clear_hdmi_infoframe, .hdmi_audio_startup = lt9611_hdmi_audio_startup, .hdmi_audio_prepare = lt9611_hdmi_audio_prepare, @@ -1132,7 +1150,8 @@ static int lt9611_probe(struct i2c_client *client) lt9611->bridge.of_node = client->dev.of_node; lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES | - DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO; + DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO | + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA; lt9611->bridge.vendor = "Lontium"; lt9611->bridge.product = "LT9611"; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index fe4c026280f0..f57307dd61c8 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -933,57 +934,85 @@ dw_hdmi_qp_bridge_tmds_char_rate_valid(const struct drm_bridge *bridge, return MODE_OK; } -static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type) +static int dw_hdmi_qp_bridge_clear_avi_infoframe(struct drm_bridge *bridge) { struct dw_hdmi_qp *hdmi = bridge->driver_private; - switch (type) { - case HDMI_INFOFRAME_TYPE_AVI: - dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, - PKTSCHED_PKT_EN); - break; + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, + PKTSCHED_PKT_EN); - case HDMI_INFOFRAME_TYPE_DRM: - dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); - break; + return 0; +} - case HDMI_INFOFRAME_TYPE_AUDIO: - dw_hdmi_qp_mod(hdmi, 0, - PKTSCHED_ACR_TX_EN | - PKTSCHED_AUDS_TX_EN | - PKTSCHED_AUDI_TX_EN, - PKTSCHED_PKT_EN); - break; - default: - dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); - } +static int dw_hdmi_qp_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) +{ + /* FIXME: add support for this InfoFrame */ + + drm_warn_once(bridge->encoder->dev, "HDMI VSI not supported\n"); return 0; } -static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int dw_hdmi_qp_bridge_clear_hdr_drm_infoframe(struct drm_bridge *bridge) { struct dw_hdmi_qp *hdmi = bridge->driver_private; - dw_hdmi_qp_bridge_clear_infoframe(bridge, type); + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); - switch (type) { - case HDMI_INFOFRAME_TYPE_AVI: - return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); + return 0; +} - case HDMI_INFOFRAME_TYPE_DRM: - return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); +static int dw_hdmi_qp_bridge_clear_audio_infoframe(struct drm_bridge *bridge) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; - case HDMI_INFOFRAME_TYPE_AUDIO: - return dw_hdmi_qp_config_audio_infoframe(hdmi, buffer, len); + dw_hdmi_qp_mod(hdmi, 0, + PKTSCHED_ACR_TX_EN | + PKTSCHED_AUDS_TX_EN | + PKTSCHED_AUDI_TX_EN, + PKTSCHED_PKT_EN); - default: - dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); - return 0; - } + return 0; +} + +static int dw_hdmi_qp_bridge_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + + dw_hdmi_qp_bridge_clear_avi_infoframe(bridge); + + return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); +} + +static int dw_hdmi_qp_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + dw_hdmi_qp_bridge_clear_hdmi_infoframe(bridge); + + /* FIXME: add support for the HDMI VSI */ + + return 0; +} + +static int dw_hdmi_qp_bridge_write_hdr_drm_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + + dw_hdmi_qp_bridge_clear_hdr_drm_infoframe(bridge); + + return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); +} + +static int dw_hdmi_qp_bridge_write_audio_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + + dw_hdmi_qp_bridge_clear_audio_infoframe(bridge); + + return dw_hdmi_qp_config_audio_infoframe(hdmi, buffer, len); } #ifdef CONFIG_DRM_DW_HDMI_QP_CEC @@ -1168,8 +1197,14 @@ static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = { .detect = dw_hdmi_qp_bridge_detect, .edid_read = dw_hdmi_qp_bridge_edid_read, .hdmi_tmds_char_rate_valid = dw_hdmi_qp_bridge_tmds_char_rate_valid, - .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe, - .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe, + .hdmi_clear_avi_infoframe = dw_hdmi_qp_bridge_clear_avi_infoframe, + .hdmi_write_avi_infoframe = dw_hdmi_qp_bridge_write_avi_infoframe, + .hdmi_clear_hdmi_infoframe = dw_hdmi_qp_bridge_clear_hdmi_infoframe, + .hdmi_write_hdmi_infoframe = dw_hdmi_qp_bridge_write_hdmi_infoframe, + .hdmi_clear_hdr_drm_infoframe = dw_hdmi_qp_bridge_clear_hdr_drm_infoframe, + .hdmi_write_hdr_drm_infoframe = dw_hdmi_qp_bridge_write_hdr_drm_infoframe, + .hdmi_clear_audio_infoframe = dw_hdmi_qp_bridge_clear_audio_infoframe, + .hdmi_write_audio_infoframe = dw_hdmi_qp_bridge_write_audio_infoframe, .hdmi_audio_startup = dw_hdmi_qp_audio_enable, .hdmi_audio_shutdown = dw_hdmi_qp_audio_disable, .hdmi_audio_prepare = dw_hdmi_qp_audio_prepare, @@ -1282,6 +1317,7 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO | + DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME | DRM_BRIDGE_OP_HPD; hdmi->bridge.of_node = pdev->dev.of_node; hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 57a0cceabd34..d38519e3923e 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -412,7 +412,30 @@ static int drm_bridge_connector_clear_infoframe(struct drm_connector *connector, if (!bridge) return -EINVAL; - return bridge->funcs->hdmi_clear_infoframe(bridge, type); + switch (type) { + case HDMI_INFOFRAME_TYPE_AVI: + /* required */ + return bridge->funcs->hdmi_clear_avi_infoframe(bridge); + case HDMI_INFOFRAME_TYPE_VENDOR: + /* required */ + return bridge->funcs->hdmi_clear_hdmi_infoframe(bridge); + case HDMI_INFOFRAME_TYPE_AUDIO: + if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) + return bridge->funcs->hdmi_clear_audio_infoframe(bridge); + break; + case HDMI_INFOFRAME_TYPE_DRM: + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) + return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge); + break; + case HDMI_INFOFRAME_TYPE_SPD: + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) + return bridge->funcs->hdmi_clear_spd_infoframe(bridge); + break; + } + + drm_dbg_driver(connector->dev, "Unsupported HDMI InfoFrame %x\n", type); + + return 0; } static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, @@ -427,7 +450,30 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, if (!bridge) return -EINVAL; - return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len); + switch (type) { + case HDMI_INFOFRAME_TYPE_AVI: + /* required */ + return bridge->funcs->hdmi_write_avi_infoframe(bridge, buffer, len); + case HDMI_INFOFRAME_TYPE_VENDOR: + /* required */ + return bridge->funcs->hdmi_write_hdmi_infoframe(bridge, buffer, len); + case HDMI_INFOFRAME_TYPE_AUDIO: + if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) + return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len); + break; + case HDMI_INFOFRAME_TYPE_DRM: + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) + return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len); + break; + case HDMI_INFOFRAME_TYPE_SPD: + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) + return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len); + break; + } + + drm_dbg_driver(connector->dev, "Unsupported HDMI InfoFrame %x\n", type); + + return 0; } static const struct drm_edid * @@ -709,8 +755,20 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, if (bridge->ops & DRM_BRIDGE_OP_HDMI) { if (bridge_connector->bridge_hdmi) return ERR_PTR(-EBUSY); - if (!bridge->funcs->hdmi_write_infoframe || - !bridge->funcs->hdmi_clear_infoframe) + if (!bridge->funcs->hdmi_write_avi_infoframe || + !bridge->funcs->hdmi_clear_avi_infoframe || + !bridge->funcs->hdmi_write_hdmi_infoframe || + !bridge->funcs->hdmi_clear_hdmi_infoframe) + return ERR_PTR(-EINVAL); + + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME && + (!bridge->funcs->hdmi_write_hdr_drm_infoframe || + !bridge->funcs->hdmi_clear_hdr_drm_infoframe)) + return ERR_PTR(-EINVAL); + + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME && + (!bridge->funcs->hdmi_write_spd_infoframe || + !bridge->funcs->hdmi_clear_spd_infoframe)) return ERR_PTR(-EINVAL); bridge_connector->bridge_hdmi = drm_bridge_get(bridge); @@ -732,7 +790,9 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, !bridge->hdmi_audio_spdif_playback) return ERR_PTR(-EINVAL); - if (!bridge->funcs->hdmi_audio_prepare || + if (!bridge->funcs->hdmi_write_audio_infoframe || + !bridge->funcs->hdmi_clear_audio_infoframe || + !bridge->funcs->hdmi_audio_prepare || !bridge->funcs->hdmi_audio_shutdown) return ERR_PTR(-EINVAL); diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c index e78eb0876f16..c599ba767093 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c @@ -433,9 +433,11 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev) hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; - if (ver_conf->bridge_funcs->hdmi_write_infoframe && - ver_conf->bridge_funcs->hdmi_clear_infoframe) - hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI; + /* Only v2 support OP_HDMI now and it we know that it also support SPD */ + if (ver_conf->bridge_funcs->hdmi_write_avi_infoframe && + ver_conf->bridge_funcs->hdmi_clear_avi_infoframe) + hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI | + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; hdmi->bridge.ddc = hdmi->ddc_adpt; diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c index c272e1e74b7d..d0e4440b7491 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c @@ -145,8 +145,11 @@ static inline u32 mtk_hdmi_v2_format_hw_packet(const u8 *buffer, u8 len) return val; } -static void mtk_hdmi_v2_hw_write_audio_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) +static int mtk_hdmi_v2_hdmi_write_audio_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR); regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); @@ -158,10 +161,15 @@ static void mtk_hdmi_v2_hw_write_audio_infoframe(struct mtk_hdmi *hdmi, const u8 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); regmap_set_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR); + + return 0; } -static void mtk_hdmi_v2_hw_write_avi_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) +static int mtk_hdmi_v2_hdmi_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); @@ -175,10 +183,15 @@ static void mtk_hdmi_v2_hw_write_avi_infoframe(struct mtk_hdmi *hdmi, const u8 * regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); regmap_set_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); + + return 0; } -static void mtk_hdmi_v2_hw_write_spd_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) +static int mtk_hdmi_v2_hdmi_write_spd_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); @@ -194,10 +207,15 @@ static void mtk_hdmi_v2_hw_write_spd_infoframe(struct mtk_hdmi *hdmi, const u8 * regmap_set_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); regmap_set_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); + + return 0; } -static void mtk_hdmi_v2_hw_write_vendor_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) +static int mtk_hdmi_v2_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); @@ -213,6 +231,8 @@ static void mtk_hdmi_v2_hw_write_vendor_infoframe(struct mtk_hdmi *hdmi, const u regmap_set_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); regmap_set_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); + + return 0; } static void mtk_hdmi_yuv420_downsampling(struct mtk_hdmi *hdmi, bool enable) @@ -255,7 +275,7 @@ static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi) if (ret < 0) return ret; - mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer); + mtk_hdmi_v2_hdmi_write_audio_infoframe(&hdmi->bridge, buffer, sizeof(buffer)); return 0; } @@ -1132,60 +1152,42 @@ static int mtk_hdmi_v2_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge return MODE_OK; } -static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type) +static int mtk_hdmi_v2_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) { struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); - switch (type) { - case HDMI_INFOFRAME_TYPE_AUDIO: - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN_WR | AUD_EN); - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); - break; - case HDMI_INFOFRAME_TYPE_AVI: - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); - break; - case HDMI_INFOFRAME_TYPE_SPD: - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); - break; - case HDMI_INFOFRAME_TYPE_VENDOR: - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); - break; - case HDMI_INFOFRAME_TYPE_DRM: - default: - break; - }; + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN_WR | AUD_EN); + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); return 0; } -static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int mtk_hdmi_v2_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) { struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); - switch (type) { - case HDMI_INFOFRAME_TYPE_AUDIO: - mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer); - break; - case HDMI_INFOFRAME_TYPE_AVI: - mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer); - break; - case HDMI_INFOFRAME_TYPE_SPD: - mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer); - break; - case HDMI_INFOFRAME_TYPE_VENDOR: - mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer); - break; - case HDMI_INFOFRAME_TYPE_DRM: - default: - dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type); - break; - }; + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); + + return 0; +} + +static int mtk_hdmi_v2_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) +{ + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); + + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); + + return 0; +} + +static int mtk_hdmi_v2_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) +{ + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); + + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); return 0; } @@ -1329,8 +1331,14 @@ static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = { .hpd_enable = mtk_hdmi_v2_hpd_enable, .hpd_disable = mtk_hdmi_v2_hpd_disable, .hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid, - .hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe, - .hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe, + .hdmi_clear_audio_infoframe = mtk_hdmi_v2_hdmi_clear_audio_infoframe, + .hdmi_write_audio_infoframe = mtk_hdmi_v2_hdmi_write_audio_infoframe, + .hdmi_clear_avi_infoframe = mtk_hdmi_v2_hdmi_clear_avi_infoframe, + .hdmi_write_avi_infoframe = mtk_hdmi_v2_hdmi_write_avi_infoframe, + .hdmi_clear_spd_infoframe = mtk_hdmi_v2_hdmi_clear_spd_infoframe, + .hdmi_write_spd_infoframe = mtk_hdmi_v2_hdmi_write_spd_infoframe, + .hdmi_clear_hdmi_infoframe = mtk_hdmi_v2_hdmi_clear_hdmi_infoframe, + .hdmi_write_hdmi_infoframe = mtk_hdmi_v2_hdmi_write_hdmi_infoframe, .debugfs_init = mtk_hdmi_v2_debugfs_init, }; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 46fd58646d32..98cd490e7ab0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -54,9 +54,80 @@ static void power_off(struct drm_bridge *bridge) #define SPD_IFRAME_LINE_NUMBER 1 #define VENSPEC_IFRAME_LINE_NUMBER 3 -static int msm_hdmi_config_avi_infoframe(struct hdmi *hdmi, - const u8 *buffer, size_t len) +static int msm_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) { + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; + u32 val; + + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); + val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND | + HDMI_INFOFRAME_CTRL0_AVI_CONT); + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); + + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); + val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); + + return 0; +} + +static int msm_hdmi_bridge_clear_audio_infoframe(struct drm_bridge *bridge) +{ + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; + u32 val; + + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); + val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND | + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT | + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE | + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE); + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); + + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); + val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK; + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); + + return 0; +} + +static int msm_hdmi_bridge_clear_spd_infoframe(struct drm_bridge *bridge) +{ + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; + u32 val; + + val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); + val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND | + HDMI_GEN_PKT_CTRL_GENERIC1_CONT | + HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK); + hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); + + return 0; +} + +static int msm_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) +{ + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; + u32 val; + + val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); + val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND | + HDMI_GEN_PKT_CTRL_GENERIC0_CONT | + HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE | + HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK); + hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); + + return 0; +} + +static int msm_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; u32 buf[4] = {}; u32 val; int i; @@ -67,6 +138,8 @@ static int msm_hdmi_config_avi_infoframe(struct hdmi *hdmi, return -EINVAL; } + msm_hdmi_bridge_clear_avi_infoframe(bridge); + /* * the AVI_INFOx registers don't map exactly to how the AVI infoframes * are packed according to the spec. The checksum from the header is @@ -93,9 +166,11 @@ static int msm_hdmi_config_avi_infoframe(struct hdmi *hdmi, return 0; } -static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi, - const u8 *buffer, size_t len) +static int msm_hdmi_bridge_write_audio_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; u32 val; if (len != HDMI_INFOFRAME_SIZE(AUDIO)) { @@ -104,6 +179,8 @@ static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi, return -EINVAL; } + msm_hdmi_bridge_clear_audio_infoframe(bridge); + hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0, buffer[3] | buffer[4] << 8 | @@ -126,9 +203,11 @@ static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi, return 0; } -static int msm_hdmi_config_spd_infoframe(struct hdmi *hdmi, - const u8 *buffer, size_t len) +static int msm_hdmi_bridge_write_spd_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; u32 buf[7] = {}; u32 val; int i; @@ -139,6 +218,8 @@ static int msm_hdmi_config_spd_infoframe(struct hdmi *hdmi, return -EINVAL; } + msm_hdmi_bridge_clear_spd_infoframe(bridge); + /* checksum gets written together with the body of the frame */ hdmi_write(hdmi, REG_HDMI_GENERIC1_HDR, buffer[0] | @@ -159,9 +240,11 @@ static int msm_hdmi_config_spd_infoframe(struct hdmi *hdmi, return 0; } -static int msm_hdmi_config_hdmi_infoframe(struct hdmi *hdmi, - const u8 *buffer, size_t len) +static int msm_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; u32 buf[7] = {}; u32 val; int i; @@ -173,6 +256,8 @@ static int msm_hdmi_config_hdmi_infoframe(struct hdmi *hdmi, return -EINVAL; } + msm_hdmi_bridge_clear_hdmi_infoframe(bridge); + /* checksum gets written together with the body of the frame */ hdmi_write(hdmi, REG_HDMI_GENERIC0_HDR, buffer[0] | @@ -194,90 +279,6 @@ static int msm_hdmi_config_hdmi_infoframe(struct hdmi *hdmi, return 0; } -static int msm_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type) -{ - struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); - struct hdmi *hdmi = hdmi_bridge->hdmi; - u32 val; - - switch (type) { - case HDMI_INFOFRAME_TYPE_AVI: - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); - val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND | - HDMI_INFOFRAME_CTRL0_AVI_CONT); - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); - - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); - val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); - - break; - - case HDMI_INFOFRAME_TYPE_AUDIO: - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); - val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND | - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT | - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE | - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE); - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); - - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); - val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK; - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); - - break; - - case HDMI_INFOFRAME_TYPE_SPD: - val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); - val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND | - HDMI_GEN_PKT_CTRL_GENERIC1_CONT | - HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK); - hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); - - break; - - case HDMI_INFOFRAME_TYPE_VENDOR: - val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); - val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND | - HDMI_GEN_PKT_CTRL_GENERIC0_CONT | - HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE | - HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK); - hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); - - break; - - default: - drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type); - } - - return 0; -} - -static int msm_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) -{ - struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); - struct hdmi *hdmi = hdmi_bridge->hdmi; - - msm_hdmi_bridge_clear_infoframe(bridge, type); - - switch (type) { - case HDMI_INFOFRAME_TYPE_AVI: - return msm_hdmi_config_avi_infoframe(hdmi, buffer, len); - case HDMI_INFOFRAME_TYPE_AUDIO: - return msm_hdmi_config_audio_infoframe(hdmi, buffer, len); - case HDMI_INFOFRAME_TYPE_SPD: - return msm_hdmi_config_spd_infoframe(hdmi, buffer, len); - case HDMI_INFOFRAME_TYPE_VENDOR: - return msm_hdmi_config_hdmi_infoframe(hdmi, buffer, len); - default: - drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type); - return 0; - } -} - static void msm_hdmi_set_timings(struct hdmi *hdmi, const struct drm_display_mode *mode); @@ -462,8 +463,14 @@ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = { .hpd_enable = msm_hdmi_hpd_enable, .hpd_disable = msm_hdmi_hpd_disable, .hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid, - .hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe, - .hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe, + .hdmi_clear_audio_infoframe = msm_hdmi_bridge_clear_audio_infoframe, + .hdmi_write_audio_infoframe = msm_hdmi_bridge_write_audio_infoframe, + .hdmi_clear_avi_infoframe = msm_hdmi_bridge_clear_avi_infoframe, + .hdmi_write_avi_infoframe = msm_hdmi_bridge_write_avi_infoframe, + .hdmi_clear_spd_infoframe = msm_hdmi_bridge_clear_spd_infoframe, + .hdmi_write_spd_infoframe = msm_hdmi_bridge_write_spd_infoframe, + .hdmi_clear_hdmi_infoframe = msm_hdmi_bridge_clear_hdmi_infoframe, + .hdmi_write_hdmi_infoframe = msm_hdmi_bridge_write_hdmi_infoframe, .hdmi_audio_prepare = msm_hdmi_bridge_audio_prepare, .hdmi_audio_shutdown = msm_hdmi_bridge_audio_shutdown, }; diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c index 997429115068..9066ee2d1dff 100644 --- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c +++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c @@ -158,35 +158,33 @@ static void rk3066_hdmi_set_power_mode(struct rk3066_hdmi *hdmi, int mode) hdmi->tmdsclk = DEFAULT_PLLA_RATE; } -static int rk3066_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type) +static int rk3066_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) { struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); - if (type != HDMI_INFOFRAME_TYPE_AVI) { - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); - return 0; - } - hdmi_writeb(hdmi, HDMI_CP_BUF_INDEX, HDMI_INFOFRAME_AVI); return 0; } static int -rk3066_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +rk3066_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) +{ + /* FIXME: add support for this InfoFrame */ + + drm_warn_once(bridge->encoder->dev, "HDMI VSI not supported\n"); + + return 0; +} + +static int +rk3066_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) { struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); ssize_t i; - if (type != HDMI_INFOFRAME_TYPE_AVI) { - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); - return 0; - } - - rk3066_hdmi_bridge_clear_infoframe(bridge, type); + rk3066_hdmi_bridge_clear_avi_infoframe(bridge); for (i = 0; i < len; i++) hdmi_writeb(hdmi, HDMI_CP_BUF_ACC_HB0 + i * 4, buffer[i]); @@ -194,6 +192,17 @@ rk3066_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, return 0; } +static int +rk3066_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + rk3066_hdmi_bridge_clear_hdmi_infoframe(bridge); + + /* FIXME: add support for this InfoFrame */ + + return 0; +} + static int rk3066_hdmi_config_video_timing(struct rk3066_hdmi *hdmi, struct drm_display_mode *mode) { @@ -493,8 +502,10 @@ static const struct drm_bridge_funcs rk3066_hdmi_bridge_funcs = { .atomic_disable = rk3066_hdmi_bridge_atomic_disable, .detect = rk3066_hdmi_bridge_detect, .edid_read = rk3066_hdmi_bridge_edid_read, - .hdmi_clear_infoframe = rk3066_hdmi_bridge_clear_infoframe, - .hdmi_write_infoframe = rk3066_hdmi_bridge_write_infoframe, + .hdmi_clear_avi_infoframe = rk3066_hdmi_bridge_clear_avi_infoframe, + .hdmi_write_avi_infoframe = rk3066_hdmi_bridge_write_avi_infoframe, + .hdmi_clear_hdmi_infoframe = rk3066_hdmi_bridge_clear_hdmi_infoframe, + .hdmi_write_hdmi_infoframe = rk3066_hdmi_bridge_write_hdmi_infoframe, .mode_valid = rk3066_hdmi_bridge_mode_valid, }; diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 3e6cbfa9dc44..73c23fece792 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -785,29 +785,113 @@ struct drm_bridge_funcs { unsigned long long tmds_rate); /** - * @hdmi_clear_infoframe: + * @hdmi_clear_avi_infoframe: * * This callback clears the infoframes in the hardware during commit. - * It will be called multiple times, once for every disabled infoframe - * type. * * This callback is optional but it must be implemented by bridges that * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. */ - int (*hdmi_clear_infoframe)(struct drm_bridge *bridge, - enum hdmi_infoframe_type type); + int (*hdmi_clear_avi_infoframe)(struct drm_bridge *bridge); + + /** + * @hdmi_write_avi_infoframe: + * + * Program the infoframe into the hardware. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. + */ + int (*hdmi_write_avi_infoframe)(struct drm_bridge *bridge, + const u8 *buffer, size_t len); + + /** + * @hdmi_clear_hdmi_infoframe: + * + * This callback clears the infoframes in the hardware during commit. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. + */ + int (*hdmi_clear_hdmi_infoframe)(struct drm_bridge *bridge); + /** - * @hdmi_write_infoframe: + * @hdmi_write_hdmi_infoframe: * - * Program the infoframe into the hardware. It will be called multiple - * times, once for every updated infoframe type. + * Program the infoframe into the hardware. * * This callback is optional but it must be implemented by bridges that * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. */ - int (*hdmi_write_infoframe)(struct drm_bridge *bridge, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len); + int (*hdmi_write_hdmi_infoframe)(struct drm_bridge *bridge, + const u8 *buffer, size_t len); + + /** + * @hdmi_clear_hdr_drm_infoframe: + * + * This callback clears the infoframes in the hardware during commit. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME flag in their + * &drm_bridge->ops. + */ + int (*hdmi_clear_hdr_drm_infoframe)(struct drm_bridge *bridge); + + /** + * @hdmi_write_hdr_drm_infoframe: + * + * Program the infoframe into the hardware. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME flag in their + * &drm_bridge->ops. + */ + int (*hdmi_write_hdr_drm_infoframe)(struct drm_bridge *bridge, + const u8 *buffer, size_t len); + + /** + * @hdmi_clear_spd_infoframe: + * + * This callback clears the infoframes in the hardware during commit. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME flag in their + * &drm_bridge->ops. + */ + int (*hdmi_clear_spd_infoframe)(struct drm_bridge *bridge); + + /** + * @hdmi_write_spd_infoframe: + * + * Program the infoframe into the hardware. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME flag in their + * &drm_bridge->ops. + */ + int (*hdmi_write_spd_infoframe)(struct drm_bridge *bridge, + const u8 *buffer, size_t len); + + /** + * @hdmi_clear_audio_infoframe: + * + * This callback clears the infoframes in the hardware during commit. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops. + */ + int (*hdmi_clear_audio_infoframe)(struct drm_bridge *bridge); + + /** + * @hdmi_write_audio_infoframe: + * + * Program the infoframe into the hardware. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops. + */ + int (*hdmi_write_audio_infoframe)(struct drm_bridge *bridge, + const u8 *buffer, size_t len); /** * @hdmi_audio_startup: @@ -1063,7 +1147,11 @@ enum drm_bridge_ops { /** * @DRM_BRIDGE_OP_HDMI: The bridge provides HDMI connector operations, * including infoframes support. Bridges that set this flag must - * implement the &drm_bridge_funcs->write_infoframe callback. + * provide HDMI-related information and implement the + * &drm_bridge_funcs->clear_avi_infoframe, + * &drm_bridge_funcs->write_avi_infoframe, + * &drm_bridge_funcs->clear_hdmi_infoframe and + * &drm_bridge_funcs->write_hdmi_infoframe callbacks. * * Note: currently there can be at most one bridge in a chain that sets * this bit. This is to simplify corresponding glue code in connector @@ -1075,6 +1163,9 @@ enum drm_bridge_ops { * Bridges that set this flag must implement the * &drm_bridge_funcs->hdmi_audio_prepare and * &drm_bridge_funcs->hdmi_audio_shutdown callbacks. + * If the bridge implements @DRM_BRIDGE_OP_HDMI, it also must implement + * &drm_bridge_funcs->hdmi_write_audio_infoframe and + * &drm_bridge_funcs->hdmi_cleaer_audio_infoframe callbacks. * * Note: currently there can be at most one bridge in a chain that sets * this bit. This is to simplify corresponding glue code in connector @@ -1106,6 +1197,18 @@ enum drm_bridge_ops { * to be present. */ DRM_BRIDGE_OP_HDMI_CEC_ADAPTER = BIT(8), + /** + * @DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME: The bridge supports + * &drm_bridge_funcs->hdmi_write_hdr_drm_infoframe and + * &drm_bridge_funcs->hdmi_clear_hdr_drm_infoframe callbacks. + */ + DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME = BIT(9), + /** + * @DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME: The bridge supports + * &drm_bridge_funcs->hdmi_write_spd_infoframe and + * &drm_bridge_funcs->hdmi_clear_spd_infoframe callbacks. + */ + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME = BIT(10), }; /** From patchwork Wed Jan 7 18:15:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 520 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DFF9D35A937 for ; Wed, 7 Jan 2026 18:15:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809719; cv=none; b=IlZrAtKJw3Pk4+O0ftxtl4GjXfsoNsFHHisEOSBA1oNZQfpkGCBcx1hYy2j4nDz25EnedOBFPbjY2cwsQhDUl4Ul7a3DP7AttvKeMMf+uke7VNJSRu0X037fHgQKo45LP3+/y9woz6Z2NGcTmgG1fLtd+VHLB3IeT5m5G/F+C50= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809719; c=relaxed/simple; bh=h+8kSKyyCVYvuPI9clygzcqBDU+O9Zth6ETXqpeby+g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dYkhjv8frsNLGJ6FCm58CbK8aflZUY+GVpdgSbt1TKevy+PTx1yAktMLXJIPRVIHiOd1BPZtDlXxpaZPUTwOm6+VP+snjupLCHvohwJFifNJUFO5gKKIgol8HLXtCTlmkMPeYs0vmN/Igtc7W+QOi6DJBrETSHWEsdRhFZf3wUc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=k5gYSI5I; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=cPdkJ7tc; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="k5gYSI5I"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="cPdkJ7tc" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607H7Ydi3672830 for ; Wed, 7 Jan 2026 18:15:14 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= FuvKMsYdeHCb+qiex5eN4gaDeI4nVkcPpNxIVMGnEFs=; b=k5gYSI5I8dYAg17d fM5dOuknFoyC2v0PhhCcQJy5+WYmkaFXDf6UMm2EZAvqWe4PeRQlmErsiIPsumpW in/oAbaL16QkUWySHp9122buDOe66yeR+FWY2W9pm1pyNMCL9XIVOxw1jiXIy10Z b2rFMNQDtpmySyLiiWrz/ovTSBcd/EoniUTuKfFtxmoPje3jymd0OVP/TOQL21/8 DR0aQJPIw7VvRe87OUkIAwv0cY7mlToaJtoxlnrYab9Vb8/BrU7tiYHoykcYN+Ey 3QZ4a2nrlQ09bXti4056YjQbVoGpM//9sWpUq2cuGSYOu1QovfEpiz4ysWexp6sx RWp74Q== 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 4bhum507y1-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:14 +0000 (GMT) Received: by mail-qv1-f71.google.com with SMTP id 6a1803df08f44-88a32bd53cdso30100796d6.0 for ; Wed, 07 Jan 2026 10:15:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809714; x=1768414514; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=FuvKMsYdeHCb+qiex5eN4gaDeI4nVkcPpNxIVMGnEFs=; b=cPdkJ7tcVfctnwHjX4xS+hZB5vqxY7eAvt6AM6AX7RYNVWI/p14jlAQqBMn2YRxHAr k4Pso7M6Sh1W/HmSFlZ9Z1wKAzABTcJSUBttYl73pKc9lMvR7ldRi0DVcd6d8/7vX5ag Avv3kyStjX3RTojUBkeXOsLx/ZsArxobIPZjNonzS6Rp4lAHxHEP6epvVuFxmk0GCwCs QUgUng/cNy4qlJpV3YsKWnxZPPN2EFA7EEIBgCxVZtp23f/q2PTu1XdJQKt00cjGjphh PhkSLyYOi2TmdmJkUMCKr9wgy/f1MHgWtL7ckhVZ1CYgmY6xqfrT4Lzuj/3atdpTF918 gcXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809714; x=1768414514; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=FuvKMsYdeHCb+qiex5eN4gaDeI4nVkcPpNxIVMGnEFs=; b=tFnNM144mTnyeypIWyttYkX9SLWTtUeqrleJ+kJdo6SOBKKSS/deOrPdNiw2wOR7P3 AxzrJhM+pnfe4hMWDLpiYtZ3Aga0IOb60x8OdqTZuY2nS9Nqw+rDih6LYhlksb7ZmSsr AKIA4ouek10KoHvHmvrUYamOGQ4kpbLAmr4hm+ilS11RNcEwgwocGOBTZxy/RxzBUlL4 VEe/zhPrY/dX3NkOqGrYFEDcn0z09mdpq51+YJu6NjGPms8gc31ROfj61axLEXMfMubC +7jP5wyD5GUvQ5ZJIntkCsP5C8yh4LZON9G96hutmV4diq6T1L7cMwfi+FO+OiC5x6SI BTxQ== X-Forwarded-Encrypted: i=1; AJvYcCXF78ZEy1/wZjiiR3K9xJtbQyxDSYN1wIPXH+JOvSfsCV3pWvO/u0EQelYBROnJAQmuC9FRgFwfpa4r1g==@lists.linux.dev X-Gm-Message-State: AOJu0YwDq4Sa1zVq1p+aDEMOGChJxU3JrlukbN2Sd9y59O5vHEsf/TeE 4pPOmg8OJBbJKhCLfPkSnYFa+Pzv9DXey4waxnAC43PYkj/UpRjCBBw1Qrue9sGhVI9fSLBtwxK cBY1dz/L4FCaGXx4xg3Xo+ldpcQoqYbL9gNB6MVJlTjgOJ2AW2yTKuOeB3aSNIYJDHA== X-Gm-Gg: AY/fxX4FB5Yyj2WmZpyRxH2Ev4roi6j6jjoOEucgho7DP+Mv2+vq4zDi2mCKnNjp4Rw /ZkI2IYnYrvFCNQ4P6T9ZPJ2G5o7rhpTZlpwG0vRKBobdGT4CCZ6DtrxLUGwueUCDqSwoYKWodU jv8uGCWnifw6i7mwWjpzuO9RajDwOghHoKZorquFFDS5AW1m4+EvvaaMAuwSN/vxF2rlf2CWojc Yfjfxm8bxNnnD3MpOFNn3ZX5u6DnBH3LKYooftJei7xWCSTV4ZcGcg6j1koswD0Lt4qK2u+tFSV Ov++qnMI0GRLiOldHHh5Jc3aYTfho2SewSDN6ojTW7u5PM1qp42wBKKIiO+ZuL0kzTsBmM1Xz1G kTGhPLHUAG8jaunOVX46HXrdGpqeXSGvzUBo0IS2nndkuVytwhwy8Zd3zi9ZuNjRoxqGH7DK27g bN2X6q7ZjG8RJegIkg4l2OG5M= X-Received: by 2002:a05:620a:698b:b0:8b8:dd7f:f032 with SMTP id af79cd13be357-8c38941bec9mr417351385a.78.1767809713447; Wed, 07 Jan 2026 10:15:13 -0800 (PST) X-Google-Smtp-Source: AGHT+IHoPBA8+usgh8WzBjQcdgLKsyd4pGWZrSMVrhAynD9c1OqnfO2wCskwOefNw7pH9SByyRIHiA== X-Received: by 2002:a05:620a:698b:b0:8b8:dd7f:f032 with SMTP id af79cd13be357-8c38941bec9mr417342485a.78.1767809712676; Wed, 07 Jan 2026 10:15:12 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:11 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:15:03 +0200 Subject: [PATCH v4 06/10] drm/display: hdmi_state_helper: split InfoFrame functions per type Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-6-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=35452; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=h+8kSKyyCVYvuPI9clygzcqBDU+O9Zth6ETXqpeby+g=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBpXqKkW8YHXV5Ify/ZnGCs1fh2rPNCIYw+Hww1v 6TTYyGVo26JATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaV6ipAAKCRCLPIo+Aiko 1XMACACCiORH8/VxHuARR4jC9zTWC4weknBPdzh2/dczrn7LnTslSIwwzW/YqMKowkAyvx4QZL4 Kb9P3cbOnPag/CQdL1Q3wUxPvZMXfhb8+607lpgm2mUUyYvX/zHZrCfzWqQLk6JGqwz4zBg2NUj ov1WzfAwXe/UUbwjf+QF6GX4MbBhopo7f86SYAMTe3Fizo5s+4a2jSzeyJxdRGN7WHXr0gSypg3 koy7NKvt0CRrmph4Ov0bc33YNOeIIk08bklKxwzRhOdynycd+YLuete7Jnneqhf1CD+skA7GY9L aKpqoR7OgtZJJm7LITmUXvLy6CBc0SFmJdjXZp3oj0cDWXEB X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-GUID: ejH4uAjhfipDbHVD7TNmJCBPnCAmGrRs X-Proofpoint-ORIG-GUID: ejH4uAjhfipDbHVD7TNmJCBPnCAmGrRs X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfXz+gGxZ0rR0X4 GTNMErMrn9cSbRxUPeYOFPkHWqIKdkQqdtsAgOh1OcjCfK51pAjh/NMxxShfqUsAEmb+N0mbhEL tRzavTRDLBxlbPHFh0yKb5jNAVM7+bMBIyBclPgtoCh3XAhcvt7BTLGRMFEn/x+SGs4Qh9uu2nq DPBa9TXUcH/7iUYYTdNlGhaBLaZhtH67+s2OgArZLI0Wdwgwr2zmm3p8FUBrwiS3/YInRNf9tO9 UN/4Lh5akQQ2j8JRKUt6ZofNvu6/kY+aFPfVOXkEFzDn/u2LRdJ1n2VfZVNs4vA50A+aVyevcyj AkZXCEnBUCtVPs2bfg+cV8oAw5XTGKAsTs0ZlnqD67TFQor/6mDoxG/mktHkPG2ECAT45M0EmaT D9Z72TMKrCleJWmLt4qziutq2Bb8FOYlDzygk5PgGSUeKr87aTleI67i2MpTI/eXzKJp4wuzGX0 +LtJC6CWPeEHV7XYsxA== X-Authority-Analysis: v=2.4 cv=KNZXzVFo c=1 sm=1 tr=0 ts=695ea2b2 cx=c_pps a=UgVkIMxJMSkC9lv97toC5g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=bATBssBWj1biXikgvRQA:9 a=QEXdDO2ut3YA:10 a=1HOtulTD9v-eNWfpl4qZ:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 priorityscore=1501 clxscore=1015 impostorscore=0 phishscore=0 adultscore=0 suspectscore=0 bulkscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O Havign a single set of InfoFrame callbacks doesn't provide enough information to the DRM framework about the InfoFrame types that are actually supported. Also it's not really future-proof: it provides a way to program only a single Vendor-Specific frame, however we might need to support multiple VSIs at the same time (e.g. HDMI vs HDMI Forum VSIs). Provide separate sets of callbacks, one per the InfoFrame type. Acked-by: Maxime Ripard Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_bridge_connector.c | 206 ++++++++++++++++----- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 86 ++++----- drivers/gpu/drm/drm_connector.c | 6 +- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 39 ++-- drivers/gpu/drm/tests/drm_connector_test.c | 14 +- drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 102 +++++----- drivers/gpu/drm/vc4/vc4_hdmi.c | 82 +++++++- include/drm/drm_connector.h | 105 ++++++++--- 8 files changed, 455 insertions(+), 185 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index d38519e3923e..ca6a72a4cf80 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -401,8 +401,7 @@ drm_bridge_connector_tmds_char_rate_valid(const struct drm_connector *connector, return MODE_OK; } -static int drm_bridge_connector_clear_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type) +static int drm_bridge_connector_clear_avi_infoframe(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); @@ -412,35 +411,70 @@ static int drm_bridge_connector_clear_infoframe(struct drm_connector *connector, if (!bridge) return -EINVAL; - switch (type) { - case HDMI_INFOFRAME_TYPE_AVI: - /* required */ - return bridge->funcs->hdmi_clear_avi_infoframe(bridge); - case HDMI_INFOFRAME_TYPE_VENDOR: - /* required */ - return bridge->funcs->hdmi_clear_hdmi_infoframe(bridge); - case HDMI_INFOFRAME_TYPE_AUDIO: - if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) - return bridge->funcs->hdmi_clear_audio_infoframe(bridge); - break; - case HDMI_INFOFRAME_TYPE_DRM: - if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) - return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge); - break; - case HDMI_INFOFRAME_TYPE_SPD: - if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) - return bridge->funcs->hdmi_clear_spd_infoframe(bridge); - break; - } + return bridge->funcs->hdmi_clear_avi_infoframe(bridge); +} + +static int drm_bridge_connector_write_avi_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + return bridge->funcs->hdmi_write_avi_infoframe(bridge, buffer, len); +} - drm_dbg_driver(connector->dev, "Unsupported HDMI InfoFrame %x\n", type); +static int drm_bridge_connector_clear_hdmi_infoframe(struct drm_connector *connector) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + return bridge->funcs->hdmi_clear_hdmi_infoframe(bridge); +} + +static int drm_bridge_connector_write_hdmi_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + return bridge->funcs->hdmi_write_hdmi_infoframe(bridge, buffer, len); +} + +static int drm_bridge_connector_clear_audio_infoframe(struct drm_connector *connector) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) + return bridge->funcs->hdmi_clear_audio_infoframe(bridge); + + drm_dbg_driver(connector->dev, "Unsupported HDMI Audio InfoFrame\n"); return 0; } -static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int drm_bridge_connector_write_audio_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); @@ -450,28 +484,84 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, if (!bridge) return -EINVAL; - switch (type) { - case HDMI_INFOFRAME_TYPE_AVI: - /* required */ - return bridge->funcs->hdmi_write_avi_infoframe(bridge, buffer, len); - case HDMI_INFOFRAME_TYPE_VENDOR: - /* required */ - return bridge->funcs->hdmi_write_hdmi_infoframe(bridge, buffer, len); - case HDMI_INFOFRAME_TYPE_AUDIO: - if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) - return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len); - break; - case HDMI_INFOFRAME_TYPE_DRM: - if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) - return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len); - break; - case HDMI_INFOFRAME_TYPE_SPD: - if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) - return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len); - break; - } + if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) + return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len); + + drm_dbg_driver(connector->dev, "Unsupported HDMI Audio InfoFrame\n"); + + return 0; +} + +static int drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connector *connector) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) + return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge); + + drm_dbg_driver(connector->dev, "Unsupported HDMI HDR DRM InfoFrame\n"); + + return 0; +} + +static int drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) + return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len); + + drm_dbg_driver(connector->dev, "Unsupported HDMI HDR DRM InfoFrame\n"); + + return 0; +} + +static int drm_bridge_connector_clear_spd_infoframe(struct drm_connector *connector) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) + return bridge->funcs->hdmi_clear_spd_infoframe(bridge); + + drm_dbg_driver(connector->dev, "Unsupported HDMI SPD InfoFrame\n"); + + return 0; +} + +static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) + return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len); - drm_dbg_driver(connector->dev, "Unsupported HDMI InfoFrame %x\n", type); + drm_dbg_driver(connector->dev, "Unsupported HDMI SPD InfoFrame\n"); return 0; } @@ -492,9 +582,27 @@ drm_bridge_connector_read_edid(struct drm_connector *connector) static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = { .tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid, - .clear_infoframe = drm_bridge_connector_clear_infoframe, - .write_infoframe = drm_bridge_connector_write_infoframe, .read_edid = drm_bridge_connector_read_edid, + .avi = { + .clear_infoframe = drm_bridge_connector_clear_avi_infoframe, + .write_infoframe = drm_bridge_connector_write_avi_infoframe, + }, + .hdmi = { + .clear_infoframe = drm_bridge_connector_clear_hdmi_infoframe, + .write_infoframe = drm_bridge_connector_write_hdmi_infoframe, + }, + .audio = { + .clear_infoframe = drm_bridge_connector_clear_audio_infoframe, + .write_infoframe = drm_bridge_connector_write_audio_infoframe, + }, + .hdr_drm = { + .clear_infoframe = drm_bridge_connector_clear_hdr_drm_infoframe, + .write_infoframe = drm_bridge_connector_write_hdr_drm_infoframe, + }, + .spd = { + .clear_infoframe = drm_bridge_connector_clear_spd_infoframe, + .write_infoframe = drm_bridge_connector_write_spd_infoframe, + }, }; static int drm_bridge_connector_audio_startup(struct drm_connector *connector) diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index a561f124be99..5a3817271d91 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -891,21 +891,21 @@ drm_hdmi_connector_mode_valid(struct drm_connector *connector, } EXPORT_SYMBOL(drm_hdmi_connector_mode_valid); -static int clear_device_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type) +static int clear_infoframe(struct drm_connector *connector, + const struct drm_connector_infoframe_funcs *funcs, + const char *type) { - const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; struct drm_device *dev = connector->dev; int ret; - drm_dbg_kms(dev, "Clearing infoframe type 0x%x\n", type); + drm_dbg_kms(dev, "Clearing %s InfoFrame\n", type); - if (!funcs || !funcs->clear_infoframe) { + if (!funcs->clear_infoframe) { drm_dbg_kms(dev, "Function not implemented, bailing.\n"); return 0; } - ret = funcs->clear_infoframe(connector, type); + ret = funcs->clear_infoframe(connector); if (ret) { drm_dbg_kms(dev, "Call failed: %d\n", ret); return ret; @@ -914,39 +914,28 @@ static int clear_device_infoframe(struct drm_connector *connector, return 0; } -static int clear_infoframe(struct drm_connector *connector, - struct drm_connector_hdmi_infoframe *old_frame) -{ - int ret; - - ret = clear_device_infoframe(connector, old_frame->data.any.type); - if (ret) - return ret; - - return 0; -} - -static int write_device_infoframe(struct drm_connector *connector, - union hdmi_infoframe *frame) +static int write_infoframe(struct drm_connector *connector, + const struct drm_connector_infoframe_funcs *funcs, + const char *type, + struct drm_connector_hdmi_infoframe *new_frame) { - const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; 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 %s InfoFrame\n", type); - if (!funcs || !funcs->write_infoframe) { + if (!funcs->write_infoframe) { drm_dbg_kms(dev, "Function not implemented, bailing.\n"); - return -EINVAL; + return 0; /* XXX: temporal until we stop generating unsupported frames */ } - len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer)); + len = hdmi_infoframe_pack(&new_frame->data, buffer, sizeof(buffer)); if (len < 0) return len; - ret = funcs->write_infoframe(connector, frame->any.type, buffer, len); + ret = funcs->write_infoframe(connector, buffer, len); if (ret) { drm_dbg_kms(dev, "Call failed: %d\n", ret); return ret; @@ -955,27 +944,17 @@ static int write_device_infoframe(struct drm_connector *connector, return 0; } -static int write_infoframe(struct drm_connector *connector, - struct drm_connector_hdmi_infoframe *new_frame) -{ - int ret; - - ret = write_device_infoframe(connector, &new_frame->data); - if (ret) - return ret; - - return 0; -} - static int write_or_clear_infoframe(struct drm_connector *connector, + const struct drm_connector_infoframe_funcs *funcs, + const char *type, struct drm_connector_hdmi_infoframe *old_frame, struct drm_connector_hdmi_infoframe *new_frame) { if (new_frame->set) - return write_infoframe(connector, new_frame); + return write_infoframe(connector, funcs, type, new_frame); if (old_frame->set && !new_frame->set) - return clear_infoframe(connector, old_frame); + return clear_infoframe(connector, funcs, type); return 0; } @@ -995,6 +974,7 @@ static int write_or_clear_infoframe(struct drm_connector *connector, int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, struct drm_atomic_state *state) { + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; struct drm_connector_state *old_conn_state = drm_atomic_get_old_connector_state(state, connector); struct drm_connector_state *new_conn_state = @@ -1005,9 +985,15 @@ int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *con if (!info->is_hdmi) return 0; + if (!funcs) { + drm_dbg_kms(connector->dev, "Function not implemented, bailing.\n"); + return -EINVAL; + } + mutex_lock(&connector->hdmi.infoframes.lock); ret = write_or_clear_infoframe(connector, + &funcs->avi, "AVI", &old_conn_state->hdmi.infoframes.avi, &new_conn_state->hdmi.infoframes.avi); if (ret) @@ -1015,18 +1001,21 @@ int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *con if (connector->hdmi.infoframes.audio.set) { ret = write_infoframe(connector, + &funcs->audio, "Audio", &connector->hdmi.infoframes.audio); if (ret) goto out; } ret = write_or_clear_infoframe(connector, + &funcs->hdr_drm, "HDR DRM", &old_conn_state->hdmi.infoframes.hdr_drm, &new_conn_state->hdmi.infoframes.hdr_drm); if (ret) goto out; ret = write_or_clear_infoframe(connector, + &funcs->spd, "SPD", &old_conn_state->hdmi.infoframes.spd, &new_conn_state->hdmi.infoframes.spd); if (ret) @@ -1034,6 +1023,7 @@ int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *con if (info->has_hdmi_infoframe) { ret = write_or_clear_infoframe(connector, + &funcs->hdmi, "HDMI-VS", &old_conn_state->hdmi.infoframes.hdmi, &new_conn_state->hdmi.infoframes.hdmi); if (ret) @@ -1062,6 +1052,7 @@ int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, struct hdmi_audio_infoframe *frame) { + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; struct drm_connector_hdmi_infoframe *infoframe = &connector->hdmi.infoframes.audio; struct drm_display_info *info = &connector->display_info; @@ -1070,12 +1061,17 @@ drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *co if (!info->is_hdmi) return 0; + if (!funcs) { + drm_dbg_kms(connector->dev, "Function not implemented, bailing.\n"); + return -EINVAL; + } + mutex_lock(&connector->hdmi.infoframes.lock); memcpy(&infoframe->data, frame, sizeof(infoframe->data)); infoframe->set = true; - ret = write_infoframe(connector, infoframe); + ret = write_infoframe(connector, &funcs->audio, "Audio", infoframe); mutex_unlock(&connector->hdmi.infoframes.lock); @@ -1097,6 +1093,7 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe); int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector) { + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; struct drm_connector_hdmi_infoframe *infoframe = &connector->hdmi.infoframes.audio; struct drm_display_info *info = &connector->display_info; @@ -1105,11 +1102,16 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con if (!info->is_hdmi) return 0; + if (!funcs) { + drm_dbg_kms(connector->dev, "Function not implemented, bailing.\n"); + return -EINVAL; + } + mutex_lock(&connector->hdmi.infoframes.lock); infoframe->set = false; - ret = clear_infoframe(connector, infoframe); + ret = clear_infoframe(connector, &funcs->audio, "Audio"); memset(&infoframe->data, 0, sizeof(infoframe->data)); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 40e025712c9b..4f5b27fab475 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -600,8 +600,10 @@ int drmm_connector_hdmi_init(struct drm_device *dev, if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12)) return -EINVAL; - if (!hdmi_funcs->clear_infoframe || - !hdmi_funcs->write_infoframe) + if (!hdmi_funcs->avi.clear_infoframe || + !hdmi_funcs->avi.write_infoframe || + !hdmi_funcs->hdmi.clear_infoframe || + !hdmi_funcs->hdmi.write_infoframe) return -EINVAL; ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc); diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index 6263ee15880a..a50f260c73e4 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -40,27 +40,19 @@ #define drm_connector_to_sun4i_hdmi(c) \ container_of_const(c, struct sun4i_hdmi, connector) -static int sun4i_hdmi_clear_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type) +static int sun4i_hdmi_clear_avi_infoframe(struct drm_connector *connector) { drm_warn_once(connector->dev, "clearing of AVI infoframe is not implemented\n"); return 0; } -static int sun4i_hdmi_write_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int sun4i_hdmi_write_avi_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) { struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); int i; - if (type != HDMI_INFOFRAME_TYPE_AVI) { - drm_err(connector->dev, - "Unsupported infoframe type: %u\n", type); - return 0; - } - for (i = 0; i < len; i++) writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i)); @@ -68,6 +60,21 @@ static int sun4i_hdmi_write_infoframe(struct drm_connector *connector, } +static int sun4i_hdmi_clear_hdmi_infoframe(struct drm_connector *connector) +{ + drm_warn_once(connector->dev, "HDMI VSI not implemented\n"); + + return 0; +} + +static int sun4i_hdmi_write_hdmi_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + drm_warn_once(connector->dev, "HDMI VSI not implemented\n"); + + return 0; +} + static void sun4i_hdmi_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { @@ -244,8 +251,14 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev) static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = { .tmds_char_rate_valid = sun4i_hdmi_connector_clock_valid, - .clear_infoframe = sun4i_hdmi_clear_infoframe, - .write_infoframe = sun4i_hdmi_write_infoframe, + .avi = { + .clear_infoframe = sun4i_hdmi_clear_avi_infoframe, + .write_infoframe = sun4i_hdmi_write_avi_infoframe, + }, + .hdmi = { + .clear_infoframe = sun4i_hdmi_clear_hdmi_infoframe, + .write_infoframe = sun4i_hdmi_write_hdmi_infoframe, + }, }; static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = { diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index f356ea695ae7..86860ad0861c 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -25,22 +25,26 @@ struct drm_connector_init_priv { struct i2c_adapter ddc; }; -static int accept_infoframe_clear_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type) +static int accept_infoframe_clear_infoframe(struct drm_connector *connector) { return 0; } static int accept_infoframe_write_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type, const u8 *buffer, size_t len) { return 0; } static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = { - .clear_infoframe = accept_infoframe_clear_infoframe, - .write_infoframe = accept_infoframe_write_infoframe, + .avi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, + .hdmi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, }; static const struct drm_connector_funcs dummy_funcs = { 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 cfa14a6eb97f..1c60947a13a1 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -78,22 +78,26 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto return ret; } -static int accept_infoframe_clear_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type) +static int accept_infoframe_clear_infoframe(struct drm_connector *connector) { return 0; } static int accept_infoframe_write_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type, const u8 *buffer, size_t len) { return 0; } static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { - .clear_infoframe = accept_infoframe_clear_infoframe, - .write_infoframe = accept_infoframe_write_infoframe, + .avi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, + .hdmi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, }; static enum drm_mode_status @@ -106,8 +110,14 @@ reject_connector_tmds_char_rate_valid(const struct drm_connector *connector, static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = { .tmds_char_rate_valid = reject_connector_tmds_char_rate_valid, - .clear_infoframe = accept_infoframe_clear_infoframe, - .write_infoframe = accept_infoframe_write_infoframe, + .avi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, + .hdmi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, }; static enum drm_mode_status @@ -120,8 +130,14 @@ reject_100mhz_connector_tmds_char_rate_valid(const struct drm_connector *connect static const struct drm_connector_hdmi_funcs reject_100mhz_connector_hdmi_funcs = { .tmds_char_rate_valid = reject_100mhz_connector_tmds_char_rate_valid, - .clear_infoframe = accept_infoframe_clear_infoframe, - .write_infoframe = accept_infoframe_write_infoframe, + .avi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, + .hdmi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, }; static int dummy_connector_get_modes(struct drm_connector *connector) @@ -2449,19 +2465,21 @@ static void drm_test_check_infoframes(struct kunit *test) drm_modeset_acquire_fini(&ctx); } -static int reject_avi_infoframe_write_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) +static int reject_infoframe_write_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) { - if (type == HDMI_INFOFRAME_TYPE_AVI) - return -EOPNOTSUPP; - - return 0; + return -EOPNOTSUPP; } static const struct drm_connector_hdmi_funcs reject_avi_infoframe_hdmi_funcs = { - .clear_infoframe = accept_infoframe_clear_infoframe, - .write_infoframe = reject_avi_infoframe_write_infoframe, + .avi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = reject_infoframe_write_infoframe, + }, + .hdmi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, }; /* @@ -2552,19 +2570,19 @@ static void drm_test_check_reject_avi_infoframe(struct kunit *test) drm_modeset_acquire_fini(&ctx); } -static int reject_hdr_infoframe_write_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) -{ - if (type == HDMI_INFOFRAME_TYPE_DRM) - return -EOPNOTSUPP; - - return 0; -} - static const struct drm_connector_hdmi_funcs reject_hdr_infoframe_hdmi_funcs = { - .clear_infoframe = accept_infoframe_clear_infoframe, - .write_infoframe = reject_hdr_infoframe_write_infoframe, + .avi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, + .hdmi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, + .hdr_drm = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = reject_infoframe_write_infoframe, + }, }; /* @@ -2800,19 +2818,19 @@ static void drm_test_check_reject_hdr_infoframe_bpc_10(struct kunit *test) drm_modeset_acquire_fini(&ctx); } -static int reject_audio_infoframe_write_infoframe(struct drm_connector *connector, - enum hdmi_infoframe_type type, - const u8 *buffer, size_t len) -{ - if (type == HDMI_INFOFRAME_TYPE_AUDIO) - return -EOPNOTSUPP; - - return 0; -} - static const struct drm_connector_hdmi_funcs reject_audio_infoframe_hdmi_funcs = { - .clear_infoframe = accept_infoframe_clear_infoframe, - .write_infoframe = reject_audio_infoframe_write_infoframe, + .avi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, + .hdmi = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = accept_infoframe_write_infoframe, + }, + .audio = { + .clear_infoframe = accept_infoframe_clear_infoframe, + .write_infoframe = reject_infoframe_write_infoframe, + }, }; /* diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 4cfb7ebc0c81..9fe605a42df7 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -727,6 +727,66 @@ static int vc4_hdmi_write_infoframe(struct drm_connector *connector, return ret; } +static int vc4_hdmi_clear_avi_infoframe(struct drm_connector *connector) +{ + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_AVI); +} + +static int vc4_hdmi_clear_hdmi_infoframe(struct drm_connector *connector) +{ + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_VENDOR); +} + +static int vc4_hdmi_clear_audio_infoframe(struct drm_connector *connector) +{ + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_AUDIO); +} + +static int vc4_hdmi_clear_hdr_drm_infoframe(struct drm_connector *connector) +{ + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_DRM); +} + +static int vc4_hdmi_clear_spd_infoframe(struct drm_connector *connector) +{ + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_SPD); +} + +static int vc4_hdmi_write_avi_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_AVI, + buffer, len); +} + +static int vc4_hdmi_write_hdmi_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_VENDOR, + buffer, len); +} + +static int vc4_hdmi_write_audio_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_AUDIO, + buffer, len); +} + +static int vc4_hdmi_write_hdr_drm_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_DRM, + buffer, len); +} + +static int vc4_hdmi_write_spd_infoframe(struct drm_connector *connector, + const u8 *buffer, size_t len) +{ + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_SPD, + buffer, len); +} + #define SCRAMBLING_POLLING_DELAY_MS 1000 static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder) @@ -1684,8 +1744,26 @@ vc4_hdmi_connector_clock_valid(const struct drm_connector *connector, static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs = { .tmds_char_rate_valid = vc4_hdmi_connector_clock_valid, - .clear_infoframe = vc4_hdmi_clear_infoframe, - .write_infoframe = vc4_hdmi_write_infoframe, + .avi = { + .clear_infoframe = vc4_hdmi_clear_avi_infoframe, + .write_infoframe = vc4_hdmi_write_avi_infoframe, + }, + .hdmi = { + .clear_infoframe = vc4_hdmi_clear_hdmi_infoframe, + .write_infoframe = vc4_hdmi_write_hdmi_infoframe, + }, + .audio = { + .clear_infoframe = vc4_hdmi_clear_audio_infoframe, + .write_infoframe = vc4_hdmi_write_audio_infoframe, + }, + .hdr_drm = { + .clear_infoframe = vc4_hdmi_clear_hdr_drm_infoframe, + .write_infoframe = vc4_hdmi_write_hdr_drm_infoframe, + }, + .spd = { + .clear_infoframe = vc4_hdmi_clear_spd_infoframe, + .write_infoframe = vc4_hdmi_write_spd_infoframe, + }, }; #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 4543833acdec..7eaec37ae1c7 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1222,44 +1222,24 @@ struct drm_connector_cec_funcs { }; /** - * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions + * struct drm_connector_infoframe_funcs - InfoFrame-related functions */ -struct drm_connector_hdmi_funcs { - /** - * @tmds_char_rate_valid: - * - * This callback is invoked at atomic_check time to figure out - * whether a particular TMDS character rate is supported by the - * driver. - * - * The @tmds_char_rate_valid callback is optional. - * - * Returns: - * - * Either &drm_mode_status.MODE_OK or one of the failure reasons - * in &enum drm_mode_status. - */ - enum drm_mode_status - (*tmds_char_rate_valid)(const struct drm_connector *connector, - const struct drm_display_mode *mode, - unsigned long long tmds_rate); - +struct drm_connector_infoframe_funcs { /** * @clear_infoframe: * * This callback is invoked through * @drm_atomic_helper_connector_hdmi_update_infoframes during a * commit to clear the infoframes into the hardware. It will be - * called multiple times, once for every disabled infoframe - * type. + * called once for each frame type to be disabled. * - * The @clear_infoframe callback is mandatory. + * The @clear_infoframe callback is mandatory for AVI and HDMI-VS + * InfoFrame types. * * Returns: * 0 on success, a negative error code otherwise */ - int (*clear_infoframe)(struct drm_connector *connector, - enum hdmi_infoframe_type type); + int (*clear_infoframe)(struct drm_connector *connector); /** * @write_infoframe: @@ -1267,18 +1247,42 @@ struct drm_connector_hdmi_funcs { * This callback is invoked through * @drm_atomic_helper_connector_hdmi_update_infoframes during a * commit to program the infoframes into the hardware. It will - * be called multiple times, once for every updated infoframe - * type. + * be called for every updated infoframe type. * - * The @write_infoframe callback is mandatory. + * The @write_infoframe callback is mandatory for AVI and HDMI-VS + * InfoFrame types. * * Returns: * 0 on success, a negative error code otherwise */ int (*write_infoframe)(struct drm_connector *connector, - enum hdmi_infoframe_type type, const u8 *buffer, size_t len); +}; + +/** + * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions + */ +struct drm_connector_hdmi_funcs { + /** + * @tmds_char_rate_valid: + * + * This callback is invoked at atomic_check time to figure out + * whether a particular TMDS character rate is supported by the + * driver. + * + * The @tmds_char_rate_valid callback is optional. + * + * Returns: + * + * Either &drm_mode_status.MODE_OK or one of the failure reasons + * in &enum drm_mode_status. + */ + enum drm_mode_status + (*tmds_char_rate_valid)(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long tmds_rate); + /** * @read_edid: * @@ -1293,6 +1297,47 @@ struct drm_connector_hdmi_funcs { * Valid EDID on success, NULL in case of failure. */ const struct drm_edid *(*read_edid)(struct drm_connector *connector); + + /** + * @avi: + * + * Set of callbacks for handling the AVI InfoFrame. These callbacks are + * mandatory. + */ + struct drm_connector_infoframe_funcs avi; + + /** + * @hdmi: + * + * Set of callbacks for handling the HDMI Vendor-Specific InfoFrame. + * These callbacks are mandatory. + */ + struct drm_connector_infoframe_funcs hdmi; + + /** + * @audio: + * + * Set of callbacks for handling the Audio InfoFrame. These callbacks + * are optional, but they are required for drivers which use + * drm_atomic_helper_connector_hdmi_update_audio_infoframe(). + */ + struct drm_connector_infoframe_funcs audio; + + /** + * @hdr_drm: + * + * Set of callbacks for handling the HDR DRM InfoFrame. These callbacks + * are mandatory if HDR output is to be supported. + */ + struct drm_connector_infoframe_funcs hdr_drm; + + /** + * @spd: + * + * Set of callbacks for handling the SPD InfoFrame. These callbacks are + * optional. + */ + struct drm_connector_infoframe_funcs spd; }; /** From patchwork Wed Jan 7 18:15:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 518 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A45B357A22 for ; Wed, 7 Jan 2026 18:15:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809718; cv=none; b=qIR3XNSq1O16kdB1XALBxQZ1xKyFgnUk+FW3hePKh2IEVeytB7BGJNVztjyNypeiduEPRq5bGgmfloQMC3lapHODI42g2xge0aC1fXqYqGW6ixsJKjiS0CMMSte7tFNo4aWJ/tEoq1iwETUjH9CbnRgeyTbzXh5zKu53adfVgnU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809718; c=relaxed/simple; bh=oV58YVZ6PqGUocr9XjdKTVXla4jnp1WcJhUj/fGMzJo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Xb2O98DG9TjJ9n//aMFndlgGA4cx+VHXYbVmHnWO9QA93aaas12vf/Vn9y08z1h+P3dZddwL785HgNLvaID4zID00bVsv6mx2PH62Yrc2Y1NC7t0mkybFuq+OaqjYeZMDpN+2jWP3O7rXGTptw3zRIjYHPhZsYAYjMZJOJMf1nU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=KyrngcOK; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Nz88VhsJ; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="KyrngcOK"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Nz88VhsJ" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607HVORP3890482 for ; Wed, 7 Jan 2026 18:15:15 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= ecVHGdcKUGcf1BVa43vSmPZjJ3ubI7MYeuQBBNyE8CA=; b=KyrngcOKBiSTWSSY izNCCazNvrE8uikK72XmK+Vv0T/Usx1TJnGEi7FoeFr+BCAWxFn5GM7sB7rkw2+R xnkxDU2giwWfYxFgRXZm77sSilAwW+XQfLEnbHeNL5YkgC2bF8pOS/2zY6D1p8zU ibMfQnY8buGFHBKi37HBa7fzog69JpxFX/4NuXpuhM5+I5jdzJdUKlQP3QuW94x3 bA1Uys7tKjWqj4sgvnKSkAfyCHp53cZhkuDxbTa5PCwLUHtNBOuNyxLNwnzd34Ed j7PZBZxB2W5SxkdUVH/o8ptaf5HAjEgqZZJHE5EDaujMhMdI9SLzwqRb2mU52Aea CfoW6A== Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhuy704s3-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:15 +0000 (GMT) Received: by mail-qk1-f198.google.com with SMTP id af79cd13be357-8bb6a7fea4dso572334685a.0 for ; Wed, 07 Jan 2026 10:15:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809715; x=1768414515; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ecVHGdcKUGcf1BVa43vSmPZjJ3ubI7MYeuQBBNyE8CA=; b=Nz88VhsJMnewEbR104L0iD+VPQ8E6XqutadTfUFKMRV4wfrQaU1zedKzbsPq64SSIm AUuza9UwcIM/it3Var4lVCdkQupKTkH0U2YRpW7aibbVkCTdyzA/xmZxzJ89LRvI1Z34 6fjbEo1FpmZk0GfXaF9QNHO6E67nL2soW3GjDXAvlu6YZjUoDu38nmFYZg6eJcVx86/X RDNY2+TjjwxMuoOlIYnzAMLH1adumUkqK0YzZL+2Jobf3F9z46jKv53yVTvfSDv904ui LJi6BvJRaATM4dp0q7/ol8fBWxrhOGTm9/2tToKjwSkLT5b0Bt9BtkQ6C2f+GCiWmWVb Af/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809715; x=1768414515; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ecVHGdcKUGcf1BVa43vSmPZjJ3ubI7MYeuQBBNyE8CA=; b=RK0Jrd0OKaVLR46igPx6azZCOZBeMVsG9KKpLeM8kVsH5LzfalcngQWPWQ7JJIER05 ViS266j3/6TQ1fcvTg4zdEh1nqswsi5gmEU3sXbi3imu/M5JfW8IK4S0ATZSS/le/5pM h/+zEHT+yvVTCC4NsvceadjUSIcDznVCA9Mji3s5S6Gxq3nJwsE8q0VGo2HjpVZtfIQj H5hBAnhXlbGi5IMCs5NkHo63LILYvOrYmrJXqHG9gY2+Eecb/Zdz91vnDjvqNX69m8rH kZaN7BbRjNSU67BCtVcgCG6SEO7mmtMB55S9CKF4Cf5fyPsDmmMswI84RA5KihWz2FOn 2zyQ== X-Forwarded-Encrypted: i=1; AJvYcCX2sX+4PWlKlJHu8xYdSsYJcdj8pQ+cGNK7GWRzGLu8dj4+VR5+JF3vu5gkGtqtHqNlwmKjnt8C8USsyA==@lists.linux.dev X-Gm-Message-State: AOJu0YzRo5PTf075TZJPjacnzF0PcJNQRqwC2Jw0a/E4LxdCB+yxaIN+ Lk20liY2V6g7qa2WdzKzHvyhqecqM5VK4297t9Snak6omQ9/Arphn0febjND7bSFCnvjWtiA3V9 0oIgoAlFbiUVQjafp39bfJ/0QUPOhh76Dzduw4kll8JpnulTzC+vUd8wezA7HcESH0Q== X-Gm-Gg: AY/fxX6MINNpGyvT66pew4wtlF7HI8eAa7tC+giknZAxdojdcx6GuApqXBj1VYtXRsD 3Q27jNiVa2CTD1vvbe7zWZaUVk/dS/UIO7eICt6Eu0rjxEHd7r1mxp2RuimCYkXAz7crZat2gvu NjHC2jy0bC1rIU5ZJ9jhbqJph0CGmd4Ekm/i9H31R2WaiyaDPkV8RJZLt68/JmpUn64HVOgX1ob mYZ2Chr+rIv5uIgJe1fhvsAaV+es2PT1CYw89+S89fqemTbAPPfVA6EzN1hSwuHRjw5j5IFufKL cJhU/HZGfvYsU03rMXTdLNIh7H21cNhsEnUJwvV6XcgJWSXJXDe9KJq7Ey2P5ZhPfO40GrvBNfL jhMN6hcD7Y5DpdakwZr5omQwoveC7epLEexA4hs94bHEzNeFBaFEmpUFT0JzeFUknQNCmWLShvn dCfN3s0kpDwtshb4c2qsgvDRg= X-Received: by 2002:a05:620a:3941:b0:8b2:ed01:b65b with SMTP id af79cd13be357-8c38940dd0dmr456873185a.83.1767809714600; Wed, 07 Jan 2026 10:15:14 -0800 (PST) X-Google-Smtp-Source: AGHT+IE+D5mrG5EJMb00tLGXnGg/5a3iMwygbvY5+APGv4MWQpPpWnlnvrx9Hf8phdL6F9vP8GwsHw== X-Received: by 2002:a05:620a:3941:b0:8b2:ed01:b65b with SMTP id af79cd13be357-8c38940dd0dmr456865885a.83.1767809713987; Wed, 07 Jan 2026 10:15:13 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:13 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:15:04 +0200 Subject: [PATCH v4 07/10] drm/display: hdmi_state_helper: reject Audio IF updates if it's not supported Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-7-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1357; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=oV58YVZ6PqGUocr9XjdKTVXla4jnp1WcJhUj/fGMzJo=; b=owGbwMvMwMXYbdNlx6SpcZXxtFoSQ2bcoqVOypf3nnz7ysbV1SEu2HFL4awvN5mTrKSPbj51+ +HNQtvQTkZjFgZGLgZZMUUWn4KWqTGbksM+7JhaDzOIlQlkCgMXpwBMZFMHB8MEnRhDz5j7S+s7 33/wuCq3e4f0x0ZX/s8/n15gMap103T9tH1VXsdtoTyjK0HrN38MWXF5zjXm73UHjVK8GY/M2v3 SSqTuxuMI+9iXSq+6WG7sOSCfWmNi1tjVpBC7Sa7Atcb1jx7rMa1jP9dN6+f1uO6p0F7NLHKs7X vYqkff23seqZc1hh1t9rINOs58UiHnRuAviVCTrfz7b1QtiT5vyfh3Et+uU3On8c8PKMyJ6V1Wl Mzvy3zdzdrznXCNGIfM95Jm3xs73nrUaDuLFp77wabg8FSVhyN77+u9LzM4bD6zrSxoyyi2in6V c7dLMv/d453GTG+Kbj738GAInXdKPufnrbyYBYbuh6TUAQ== X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-ORIG-GUID: S7H4qlvYqBiCPGaYFs9wJkSzMSNerZEQ X-Proofpoint-GUID: S7H4qlvYqBiCPGaYFs9wJkSzMSNerZEQ X-Authority-Analysis: v=2.4 cv=DZEaa/tW c=1 sm=1 tr=0 ts=695ea2b3 cx=c_pps a=qKBjSQ1v91RyAK45QCPf5w==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=FWtRXCEnrA9oX9MUO7wA:9 a=QEXdDO2ut3YA:10 a=NFOGd7dJGGMPyQGDc5-O:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfXwy6vnwQuGwSH +NgwPWGfu/Doj6hkr94OElyjJb4aFUbzdyTIqi/n0GtRiZL8Kx3XshsyrVWO4UKMnsNaGsH2s9v EM63UwpsMQKuzngCANDmASlhmyDOXW1W7IvdCbdIEtLRE6cAEUkjosU20hI99W0TuGuoPjx3PeZ 3QdcCqdR69I2PMoWYb8Z3Nry2svGIUJzzV+by/nqrRY75bfym1FFtF2rtSbWj+9zIXvbjyz6BGa zGWSfRbTiEtijvD5LEB5f6dv9OhADgfaF1Qu0l+N5rayb0x4+9gSvmzBtgXDveRFiUfKJd2p61n CFYXtK720WR5ltYwdfwtQLH4BdA7PC+knDK5dpz5ryYPU5aoKpEGPjpxzbXg1yWMvwH78W9sCNx 1gQk9N9wOsKEXxRIDgtvJc9Yf7JkU8LE8noz7McVk1R7njMXkIgXAdNriNdhtaGRiOPQ/rt1B6T l6caWtPRKUZmQUDRs/w== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 impostorscore=0 phishscore=0 bulkscore=0 adultscore=0 spamscore=0 clxscore=1015 suspectscore=0 lowpriorityscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O Updating the InfoFrame if it can not be sent over the wire makes no sense. Change drm_atomic_helper_connector_hdmi_update_audio_infoframe() and drm_atomic_helper_connector_hdmi_clear_audio_infoframe() to return an error if Audio InfoFrame callbacks are not implemented. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 5a3817271d91..e8556bf9e1da 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -1061,7 +1061,7 @@ drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *co if (!info->is_hdmi) return 0; - if (!funcs) { + if (!funcs || !funcs->audio.write_infoframe) { drm_dbg_kms(connector->dev, "Function not implemented, bailing.\n"); return -EINVAL; } @@ -1102,7 +1102,7 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con if (!info->is_hdmi) return 0; - if (!funcs) { + if (!funcs || !funcs->audio.write_infoframe) { drm_dbg_kms(connector->dev, "Function not implemented, bailing.\n"); return -EINVAL; } From patchwork Wed Jan 7 18:15:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 517 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 337D33563CC for ; Wed, 7 Jan 2026 18:15:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809720; cv=none; b=lZgDDHX4yxJlYtRuvOvMULy851IRGb+k8oFbc/lZpx1AFq1AIRRlWU2Z7DOooNQD6EmPWSuFNOHkg6bp9cLmtxyCAmTo4K4+glJdVsEQYV1jSedH2HqOZ/sMxgKs5OUPoKtQx8YqjYCgzuoK9eoicA/+4hiIK8IpYSd1JWzIqZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809720; c=relaxed/simple; bh=/ZrVCxC2ORTh/25tcpqTF3QUmYMkLYWP2fYAuUO25LA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MNWM2eMA4JEQHY+XNYreCHA9FguyY/dJcSdf+anpzk7wh1REQyTtJAEPunYsSI75DczHLF5mnt4t2+1RfVDwRL0UtQuunZEovyzYGqayAnC4tVp1q4nTcj7O0lGftHXHHfvEkQclv2VTf6yXQ0qm8Y58tdmMs783F0MbGcanwoQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=YT98JyW5; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=R4H9nTQp; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="YT98JyW5"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="R4H9nTQp" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607HTTlx3751433 for ; Wed, 7 Jan 2026 18:15:17 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= 6ayeKTjgf6jc54pfgcQupo3DnEV3KmeCjaAg9qNbh2E=; b=YT98JyW5oGIce4yx t62vyUO8gfpzGSWjao8mBdPTYJjg9dpxi69OPT+flXHjY6zvvx9HgiN5VBgBBE3z aP7KS2Ai0vJ/lJpU1dpDd0Wxd3AfpuO+r5VqXRzqZpaUaKyoi0LPozqGRblpfFtK 8FFeJxxsq+wpaKuwqGiSnUZWk/S1M+hmWmUCx+hBTMfSwr6J6aj2V5QFdUUVf0kj CHLH4uqz3dyg/R1Bh8EhaSUJI/DxjitNH/wMuHLMhRLagS+uW1jOa4CUCDBGeaVy RdCTC2bWeHtpXMzHIcJEE6pFwJOYIGnHu5DTmubFL5Kv1LjS0Qoq4BlhHH+zqmpU l0KWkw== Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhuxcr5dq-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:17 +0000 (GMT) Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-8bb9f029f31so632013085a.2 for ; Wed, 07 Jan 2026 10:15:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809716; x=1768414516; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=6ayeKTjgf6jc54pfgcQupo3DnEV3KmeCjaAg9qNbh2E=; b=R4H9nTQpYH/MEIShcJmvEk0+JunevMAEWAxi2Vyj4wBgujDp4SNhKUju9qEw6+257l SPuhQHHG6/efpNOqbGAQ5vBicThFMo449zYFtSBaR8rbTrImkcn0dlNNgqjuxFSIGmFE a/D+GD67kF0wAFnnHPHwgacZyvDSDrAYgKxSeHghGjW2eFfvSgxVI0U4ps+ExX86FiFl L9ZglE3N8JvCCwhf0uVVAa1WgQalgk1ARX6RKWRkPsxNIFdewz1Az+/+vYpb4Mmz3vN6 BvZ7/QCRMbXvgucw/9ZYicG8miPghPdUmRZmdutqYa6xUitM6hIbRdLS8ycWIPJ7/rwf lGvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809716; x=1768414516; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=6ayeKTjgf6jc54pfgcQupo3DnEV3KmeCjaAg9qNbh2E=; b=JbXamz9Czi5J9YESCSm3/sVYIxHjKiqZK1VuImQYEDOcWS7MFs1yMUvjlUYaTCx1tV AOUKBcwnNB6SS2d0c3uksEAaF1NnFpHnMJGzULny2O3rDQFNf6vDZ5NgrzQuld44+EMD ravDzriLe2N5rZzTfbbaAko1eVQAg6+1ttKtJ0h/TuX4zi7S754lyCGGBYm9ju+Wxr96 6wKErAvd0AOzNAcSrbewWxGDB/d9OKtLmZe4YpvwULXBiLadoX8QPfxVM8DVYtzmNsLx bW4g9muFRLDCevq6UOYhOK/7E0UToBspkicsVKqbF+5/gv+V2L4KL+rI3gv6xQ4x2y2X ssCw== X-Forwarded-Encrypted: i=1; AJvYcCWkMFz/V9y4XkOLWttLsAgnIZ5ZqV03ZvSniyLhSBkvob4Ihcm2vZF4eHHCHbtCj64qYjLRZ8dLGA4RMA==@lists.linux.dev X-Gm-Message-State: AOJu0Ywb1vPSd7s8cfFvfMZqjRjW2394xlQmHleoJTCrkeoSlJVHacNd yApv/OjHjOYUXFmiV/9WtJmtb41W+/pp59xNcbybmi3ITuMpms+dkqLlRmcCip9dm/nFrbGEQSW IRCDBDTRAhh8ey+oM4NH9xFkLYiES3naExMahMVpsUPQPGHA7seMa4jGMvlHS+8m7Cw== X-Gm-Gg: AY/fxX5tnyQg1A4DbTA8b8hqYYTg+JVDhMg1orNLy7o9LvYb/OaM5YSAWyJPz/3wwYW 8TfQltUFDAQPjz13ZOMsMwYY7oKCDdtOs1DVwuq6thg90ML0gbj/a1YtnUiWh+MClTxQ6nNj1iv +bupVO3Oof+ouUP/rfeqROltTADZwTXhUENT6hf7SwnyLV+FlZXAY9k/+hJRwuF6jHB5iofcIyk TAIa6leV8ejTIHEhZ6Ut7KL1e5FJJ2ubZYFBsK0k+O3oGTKYjWvKGHs4NQpc/TI0itCsdwv4l7H IO7quP4FjHngznS/btdvA48qHcCufDuJuweHk3Yk0QFGSHnH783h3BDVu6KFFfG4QLKVqdi0rTs 5Nx4rMNGXSIsATrzPGO6tZClTuartzEHjSJdj8bCk/mM095qUHaryjP9DumafLa7TqMmyOPa5JD NqLDc7bVKSwmpW+MQPjc9ddoY= X-Received: by 2002:a05:620a:2952:b0:89f:5a59:bf30 with SMTP id af79cd13be357-8c38940cc79mr440815685a.78.1767809716513; Wed, 07 Jan 2026 10:15:16 -0800 (PST) X-Google-Smtp-Source: AGHT+IFzR6/I/M+rb+0CfWg9B2pwtmy0BCZ0528ZAW/PtSMTyk3JvUKmiud8K1hEOQV156GKBDOZmQ== X-Received: by 2002:a05:620a:2952:b0:89f:5a59:bf30 with SMTP id af79cd13be357-8c38940cc79mr440807085a.78.1767809715974; Wed, 07 Jan 2026 10:15:15 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:14 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:15:05 +0200 Subject: [PATCH v4 08/10] drm/display: hdmi_state_helper: don't generate unsupported InfoFrames Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-8-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2066; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=/ZrVCxC2ORTh/25tcpqTF3QUmYMkLYWP2fYAuUO25LA=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBpXqKlLQRVN1fiNfBhJSnlQQ8yf8TEYh+A8edCs YWTlH3Bcj+JATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaV6ipQAKCRCLPIo+Aiko 1QOVB/oDjydk2pqigYtLHtwvNWcAKXJbbdPGQ26WTURthKMHJhz9rPZZV04J2QY5hTtypEXd//d nw5Vbwc0So6ysL8Tv/jIxpWqiL+ciHmVHitK6qOCEBS+i8W0MtTLVx1YAdnQ2gp8v5gmqGooPIj URRZkW/XopRmGOqd8hftr59SVEpUvh5HH5NGGNoX/Wx2rngOV+KmUfwE0HXApJlGUvk5kZ/fwRb bGSKspZn9xiu+96xWnVTNQqum/Ct/2q61VCFkl/XqCm0lDpae50DBapNsWOPBMIWt03yTjsHslN UvAY1W9Roxw/F/vls4Ff8wqqmvewupBjJYfykiyeu5Y2vHLK X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfX0R2JckAfatah x2D36hOmqfkqW2kgmzMpPLH25tU/ya1gn1px3gUy1inzip6WTd8h5MQR3mckl2VDF97QrryTCMJ TiDoYjMZ5D4sotu31GzwrFiIZfINRJ95/g54+eqcfRe5+TDBEr9uSaieeOUV+6OmGGk8vmqpxcm rGsmVfDyfkYKwe0G3749iTdcOgK/I/+oUXNtxzQojJHHYMVrsn8xuLIugxhGGginB5u1pM6nTa6 oWfl4Dw8BtqbOszzCpy+kms1uo7USYFV3Ae7V22kDNsQ8DHHyOPS9PDdsTUnbVcbAQpzGe3++nM CVrckLKPFpjGoH8MnFD5EkI2DDYARwqBcsoz1+NKvIWWMgW+jFvRB+F6MLsEmWowvCIwcGsKF0d TbbCr/jpMDZIb3qHUmc6UTFLkLowqwXZpvCQrYxFTPgSca6VORHcLbKiIOJo+qfmciUM6gCon8H wUZtuAQri39XwVWb0Ww== X-Proofpoint-ORIG-GUID: fzCPmhGl-tEOUUPUS8aIeUN3qWO-iFVz X-Authority-Analysis: v=2.4 cv=SPdPlevH c=1 sm=1 tr=0 ts=695ea2b5 cx=c_pps a=50t2pK5VMbmlHzFWWp8p/g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=58UsvUJqJn8fpqk6aeUA:9 a=QEXdDO2ut3YA:10 a=IoWCM6iH3mJn3m4BftBB:22 X-Proofpoint-GUID: fzCPmhGl-tEOUUPUS8aIeUN3qWO-iFVz X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 phishscore=0 lowpriorityscore=0 malwarescore=0 adultscore=0 bulkscore=0 spamscore=0 clxscore=1015 suspectscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O There is little point in generating InfoFrames which are not supported by the driver. Skip generating the unsupported InfoFrames, making sure that the kernel never tries to write the unsupported frame. As there are no remaining usecases, change write_infoframe / clear_infoframe helpers return an error if the corresponding callback is NULL. Acked-by: Maxime Ripard Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index e8556bf9e1da..a1d16762ac7a 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -718,6 +718,9 @@ static int hdmi_generate_spd_infoframe(const struct drm_connector *connector, infoframe->set = false; + if (!connector->hdmi.funcs->spd.write_infoframe) + return 0; + ret = hdmi_spd_infoframe_init(frame, connector->hdmi.vendor, connector->hdmi.product); @@ -742,6 +745,9 @@ static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector, infoframe->set = false; + if (!connector->hdmi.funcs->hdr_drm.write_infoframe) + return 0; + if (connector->max_bpc < 10) return 0; @@ -902,7 +908,7 @@ static int clear_infoframe(struct drm_connector *connector, if (!funcs->clear_infoframe) { drm_dbg_kms(dev, "Function not implemented, bailing.\n"); - return 0; + return -EOPNOTSUPP; } ret = funcs->clear_infoframe(connector); @@ -928,7 +934,7 @@ static int write_infoframe(struct drm_connector *connector, if (!funcs->write_infoframe) { drm_dbg_kms(dev, "Function not implemented, bailing.\n"); - return 0; /* XXX: temporal until we stop generating unsupported frames */ + return -EOPNOTSUPP; } len = hdmi_infoframe_pack(&new_frame->data, buffer, sizeof(buffer)); From patchwork Wed Jan 7 18:15:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 516 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4547635E53D for ; Wed, 7 Jan 2026 18:15:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809723; cv=none; b=EXm4r/9JyId4wxywUnh1/1Ut/AKV/7igI2Rx/ZrOwhefdWlqh0yvoOendyZtfB/waLa1rqfD7uM2MhGKX1tSGlMY3VVHZ7ywYMO4GhwzvkcMccsXhGqVquebNtlm0Dzw/vuLW1vim86lp0LwMdKTJBDebLIQq/OiUzqBpvZ3jTI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809723; c=relaxed/simple; bh=j/nplc82Uc8n6ck55GeREmF67vUj6ZFIListkklkuXo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j42xN8yX96c9Yi/T/C26BZnfP6u5hWy9FyUt9vqqKb8iC8a1jxsf8IeF5prjY/FOa3VK9onaLrBNOR5fxYRgw6KL/vo5kbeYag68AoVF/qY1MHfjUh67WmfMPEQqLjbxNaCKP9T1sT4r+yi1FecT5ICdgHDr7KTyZcqC+lr+W/E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=OpUmQbYb; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=VAHcNf++; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="OpUmQbYb"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="VAHcNf++" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607HAama2453891 for ; Wed, 7 Jan 2026 18:15:20 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= JPs6IVrvHQYSHaamgUjrxzM3vyFi8BapYIQ1hzBD3c8=; b=OpUmQbYb1j/NSFYk Xft3zpHcpuFEAv3CwOsCEDm8TTZut6f7fktTiYhP1reTavXR/x0cZtP0e3AsQjk2 Kd4d6fr83beQDg7xLfrwhBhAE1TfPfdQLKTzu0NA99ht3KT3l1jDTgchxxzV/8nA msygtyBCiUhJg4YwVhjC0/Yw4oEbkJVb5gT29FunL44ATkzFsPDvFDPjYgCoR5ls J6Ghe+PxRcaqeJPPU3PMEpgkcVIcCIzeIl2l+M80+JIOz89logld2RC4jfJ53ZQm YKlxv/l+pU+RIUbbZPSXmCUkNA3IpMNQ3klIl0c0i1wuE62sfSsCVDo1NuIrb25t HacGAg== Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhmnbhpvd-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:20 +0000 (GMT) Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-8b2dbd36752so622724285a.0 for ; Wed, 07 Jan 2026 10:15:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809720; x=1768414520; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=JPs6IVrvHQYSHaamgUjrxzM3vyFi8BapYIQ1hzBD3c8=; b=VAHcNf++iXCTNGh/ndN61stjjmRlvUpZJYDjOwUCuNOlupz3iGUaHOgcHWBxYX3d0b xWrj1M+hZ8kQcblnlRtf4svUsF6R/dSwDPFwi1t7oQ8S5KtXENzQ6G9UM3xFwpaS30U/ syfvpMvIVMqGzksTQhzcJUyTtLXRWt3Bx7VTr7SgG9tIzHPgxMi//tyM/jd8UeLkly04 J8FFXEVfCWGSZVFu/tqFLION902ozK7q87vJlDjoLl4ENujYSLTO6EIlt9flQUsX947S RCJ1j+jq4L7nnkBJfP5CG2zax5s6EkLpi9MAuZhia1bL/bQmYS5yGzmB9gESv2RrrgIJ OyTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809720; x=1768414520; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=JPs6IVrvHQYSHaamgUjrxzM3vyFi8BapYIQ1hzBD3c8=; b=Xe0W/EtOlkJ48GofKzQ1/TmIl1q3FH1dV6I/nMPJtmfJYgbpk+eNEIoVyZ6FpJuAil Uyjcxu2oT7FEHmrJ8r9twz3I810WiKIXOsV2EbLnLULpyjSlnzFR5oZLRc1L55UttAxP RBrbk898DgOrQfBrgUK6YOgDIR8dXeNvk/RC3CpqIiVO/kGTEFIYdiEOT61BNvFcYNWp bEY/y75Vo3zkNqIH2w/8fnFywsQ18P3Z/61uNKQmkr5p/TGjD9GZIs8U7/7BQ47G/X5b /LokiRq2uN6bb552myMOMt801Q9escOQl1NbYmjhm2VnQtEeAaj3ddPsOQh8HvVM35xc ylLA== X-Forwarded-Encrypted: i=1; AJvYcCVi++fzCv0PSWjnZSYf6PW7NIKe+jdbFdI2TOcj0luYMM3yfSGz7v4NhFJS0lMjXqtJYeiTlUs4trK0Lw==@lists.linux.dev X-Gm-Message-State: AOJu0Yw9t8zylVhaxEnXlvE+VvvvmcMPfM1hp2CSdFf7xdpqrbHRi7tk 6ODfj0SMZby8TMixCPRpd4XxwDymhK1lrhoU46uKZi7X1CYJAHJf28K81NOUnuKDntogq9R6meb SY+rOG8JTPxOjpEw1f0k7o1naBxHuLX9Ieh0FMrn0uQqMUzG97s2ge8O/j9tACF+/7A== X-Gm-Gg: AY/fxX4xihbckzM99QxQC7wzV+7A3/hMPsx+nTIXqCjXRgRWQdyLWEkATXMs7brU/5b bsXM2oJ1OOoENoelGM9xRQbMllp73zfJ0bRsPgL/u4EdK0zn2xph64G7LQOnmOrhMo6rGQCLpMg klx0HObLuBLvuSIqlu4/mq0wuRhRtCS0zN+V8TbJ3Mws3e90cJlqV7PBa8ux/+I6qxYM+VAzt7Z iEV2Ms06t7yw+pzNqVSrno6ySwuinZ5EMf6N+P787ZL836gD1MeWxkm02BeTJpMTC1wmoMtkKx5 bU90Dtd0QjHweA/A+42uF0LHrVqQLh78Le+lM+ctDC+crLBD6rG+5KZptUq5KqJ2IGN6a2VnKqx hRtS9dHuBq/DJBfcmFU7XtLtPz8DgzENxI2DwcjcCoqIY7ZgQR7/fDFitsJAX0qDf6m0NOay/fz eCzbThjWTs4kiVXttneljbwn4= X-Received: by 2002:a05:620a:2a0e:b0:8b2:f145:7f28 with SMTP id af79cd13be357-8c3893a26a4mr408414285a.33.1767809719408; Wed, 07 Jan 2026 10:15:19 -0800 (PST) X-Google-Smtp-Source: AGHT+IFUjHXe7uuYeZEqUMuBR5K2kia77K+Kj14ZWPxBppIzS2JiKcdZruRDku2629OMG4LVhagWmw== X-Received: by 2002:a05:620a:2a0e:b0:8b2:f145:7f28 with SMTP id af79cd13be357-8c3893a26a4mr408404785a.33.1767809718716; Wed, 07 Jan 2026 10:15:18 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:17 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:15:06 +0200 Subject: [PATCH v4 09/10] drm/display: bridge_connector: dynamically generate HDMI callbacks Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-9-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6894; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=j/nplc82Uc8n6ck55GeREmF67vUj6ZFIListkklkuXo=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBpXqKlQWZc4/P6jahK/bWP1w2B50/o9TLzfzbdf aaZXx2QNIaJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaV6ipQAKCRCLPIo+Aiko 1f1FCACoKLk12kYaWdypMvDCzHmH9N8HbMOWbXMZlbluaF79NkCtoNgDonKnKHxYLa9pjqgX17e Rvd8pmDpdv2MOg3WP/GMXH5pZGxRG01FGl7SBtEPw2/YXYEskTFSEq6fG4I+tv8X5Ly85MqO9Lj 9cHsDJOJq0hBFlwxVPg4mvAka59hwWsW69lgA6euCJbibpFCioBMCghtCslqHcxkjZWM/PUGgNE Zgf3lcR3ZdkGqSnlQlrowNKspjiwnAe/Q7/uXCEP9N6R5jyGzXlQUqTGFKBPnuzMfXGuvLMm4dg RY6CU12eS8wodgZ5W3Ilm0fcBuf2GFwlR9F7fNEmqQh95vO+ X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfX5LnPgdvqHFJz 6HMfi01TD3DvQQJ/T1fBQknI3/6miYKGF8UyIIHGYG6Kq7oMzshzDsAhv9yzrmverQKmwodCQ6L x3hJgqTvzSODcnLQYPtidZuSEkBuh12qXoSQaztMxNiNo2xbdzFvtin6BU93YkkQYj7pusMNaNr fwSnX1DpNjRmBvXBFyzcy6Mhi9ZJqQF+uC43f4NNlGY05HqoEkaU783BGRDnEd/MICxBuj5WntI COV7AXlEN3UUFUQ3ydZEHhcPCTYFgi/IXJ/xFTdB+fxi5smoEaNhQ44kiX3WmBPbal7ID2462xz d5WWXFBls6F/7/JCM8+G90uAUfY0rthxjjwLo4ID79A29tr7Ph7xSUgrjDWRILMVVkZp6PyOBzt I8/78L1DEC9I9Xxm5Jg75AOsskWfFNhZn+d3FsPhLm0Ocg1/PLwNyFZ9HJ8qVqym9JNq58KkOfO F33qtFGtTvg7sUzrJ6Q== X-Proofpoint-GUID: Oxnls662mK3tqcTfjOhfCiX020dLnT8- X-Authority-Analysis: v=2.4 cv=eIkeTXp1 c=1 sm=1 tr=0 ts=695ea2b8 cx=c_pps a=hnmNkyzTK/kJ09Xio7VxxA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=SmQ2dRXw9u10PpR7_9MA:9 a=QEXdDO2ut3YA:10 a=PEH46H7Ffwr30OY-TuGO:22 X-Proofpoint-ORIG-GUID: Oxnls662mK3tqcTfjOhfCiX020dLnT8- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 clxscore=1015 malwarescore=0 suspectscore=0 phishscore=0 impostorscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O The rest of the DRM framework uses presence of the callbacks to check if the particular infoframe is supported. Register HDMI callbacks dynamically, basing on the corresponding drm_bridge ops. Acked-by: Maxime Ripard Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_bridge_connector.c | 94 ++++++++++++-------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index ca6a72a4cf80..ba8ff113cff1 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -123,6 +123,14 @@ struct drm_bridge_connector { * DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER). */ struct drm_bridge *bridge_hdmi_cec; + + /** + * @hdmi_funcs: + * + * The particular &drm_connector_hdmi_funcs implementation for this + * bridge connector. + */ + struct drm_connector_hdmi_funcs hdmi_funcs; }; #define to_drm_bridge_connector(x) \ @@ -465,12 +473,7 @@ static int drm_bridge_connector_clear_audio_infoframe(struct drm_connector *conn if (!bridge) return -EINVAL; - if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) - return bridge->funcs->hdmi_clear_audio_infoframe(bridge); - - drm_dbg_driver(connector->dev, "Unsupported HDMI Audio InfoFrame\n"); - - return 0; + return bridge->funcs->hdmi_clear_audio_infoframe(bridge); } static int drm_bridge_connector_write_audio_infoframe(struct drm_connector *connector, @@ -484,12 +487,7 @@ static int drm_bridge_connector_write_audio_infoframe(struct drm_connector *conn if (!bridge) return -EINVAL; - if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) - return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len); - - drm_dbg_driver(connector->dev, "Unsupported HDMI Audio InfoFrame\n"); - - return 0; + return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len); } static int drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connector *connector) @@ -502,12 +500,7 @@ static int drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connector *co if (!bridge) return -EINVAL; - if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) - return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge); - - drm_dbg_driver(connector->dev, "Unsupported HDMI HDR DRM InfoFrame\n"); - - return 0; + return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge); } static int drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connector *connector, @@ -521,12 +514,7 @@ static int drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connector *co if (!bridge) return -EINVAL; - if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) - return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len); - - drm_dbg_driver(connector->dev, "Unsupported HDMI HDR DRM InfoFrame\n"); - - return 0; + return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len); } static int drm_bridge_connector_clear_spd_infoframe(struct drm_connector *connector) @@ -539,12 +527,7 @@ static int drm_bridge_connector_clear_spd_infoframe(struct drm_connector *connec if (!bridge) return -EINVAL; - if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) - return bridge->funcs->hdmi_clear_spd_infoframe(bridge); - - drm_dbg_driver(connector->dev, "Unsupported HDMI SPD InfoFrame\n"); - - return 0; + return bridge->funcs->hdmi_clear_spd_infoframe(bridge); } static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connector, @@ -558,12 +541,7 @@ static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connec if (!bridge) return -EINVAL; - if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) - return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len); - - drm_dbg_driver(connector->dev, "Unsupported HDMI SPD InfoFrame\n"); - - return 0; + return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len); } static const struct drm_edid * @@ -591,18 +569,22 @@ static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = { .clear_infoframe = drm_bridge_connector_clear_hdmi_infoframe, .write_infoframe = drm_bridge_connector_write_hdmi_infoframe, }, - .audio = { - .clear_infoframe = drm_bridge_connector_clear_audio_infoframe, - .write_infoframe = drm_bridge_connector_write_audio_infoframe, - }, - .hdr_drm = { - .clear_infoframe = drm_bridge_connector_clear_hdr_drm_infoframe, - .write_infoframe = drm_bridge_connector_write_hdr_drm_infoframe, - }, - .spd = { - .clear_infoframe = drm_bridge_connector_clear_spd_infoframe, - .write_infoframe = drm_bridge_connector_write_spd_infoframe, - }, + /* audio, hdr_drm and spd are set dynamically during init */ +}; + +static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_audio_infoframe = { + .clear_infoframe = drm_bridge_connector_clear_audio_infoframe, + .write_infoframe = drm_bridge_connector_write_audio_infoframe, +}; + +static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_hdr_drm_infoframe = { + .clear_infoframe = drm_bridge_connector_clear_hdr_drm_infoframe, + .write_infoframe = drm_bridge_connector_write_hdr_drm_infoframe, +}; + +static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_spd_infoframe = { + .clear_infoframe = drm_bridge_connector_clear_spd_infoframe, + .write_infoframe = drm_bridge_connector_write_spd_infoframe, }; static int drm_bridge_connector_audio_startup(struct drm_connector *connector) @@ -971,11 +953,25 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, if (!connector->ycbcr_420_allowed) supported_formats &= ~BIT(HDMI_COLORSPACE_YUV420); + bridge_connector->hdmi_funcs = drm_bridge_connector_hdmi_funcs; + + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_AUDIO) + bridge_connector->hdmi_funcs.audio = + drm_bridge_connector_hdmi_audio_infoframe; + + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) + bridge_connector->hdmi_funcs.hdr_drm = + drm_bridge_connector_hdmi_hdr_drm_infoframe; + + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) + bridge_connector->hdmi_funcs.spd = + drm_bridge_connector_hdmi_spd_infoframe; + ret = drmm_connector_hdmi_init(drm, connector, bridge_connector->bridge_hdmi->vendor, bridge_connector->bridge_hdmi->product, &drm_bridge_connector_funcs, - &drm_bridge_connector_hdmi_funcs, + &bridge_connector->hdmi_funcs, connector_type, ddc, supported_formats, max_bpc); From patchwork Wed Jan 7 18:15:07 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 515 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65A163612D3 for ; Wed, 7 Jan 2026 18:15:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809727; cv=none; b=PKyUNJ6KcGJg6SrEJW2ZS1oR9XPx//JpCmC+tKyD1NKETbkqJMhqNO82afZLw7g/BTB+DhQgRL8dccruqdWZ1IE3K/ijqJvl0+aKXcbKxrZUajsi4yC8jI+rhqTLGo5DlX2yc/aiuczuDvSsGxpNbHRLUcNSccw+SL9QR/taTE8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767809727; c=relaxed/simple; bh=Fqja7nqMdmSMtGtKfnnZaHovKcc+8jCwgpdYFW7dJBE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nVSsz+10GJAoeHx1cpoMDbGS6CZoZZoZeDrD+RmnfIiT4vKqkF4BYGKSnc5EwYotorsudX0/sp3Sx2OO0PleCJ9wraFWuTnF1uW3pnC4HJ4wEd1rdBp1wgwLoAVTu+8cSwKIaBxPgOcAjtpPiSzP/v7FkhgBPu5D7olWcKNyqi4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=KbCTIULR; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=VrheGqmf; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="KbCTIULR"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="VrheGqmf" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 607H3R662453883 for ; Wed, 7 Jan 2026 18:15:24 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= Rhn7f75cBzRSaSyNIXu2sGOU3jGwzD9Mh33JQAcGM6E=; b=KbCTIULR+UQD/OAh U1rI7/tfl1/ayoTyuMELUcglhFt/QcCGv9YR7isr79DbYNFS++Nm24Mu8T+F/ns5 Nb46watlWR+VJAYBlUKos9mkuWeL6NeBUNVZUj98sMVDYn2GjcOiUdMMpXb5ieYU GiBSz7AdGoLuCVNMugOoQB39e48Zo0tN0w05xOS1T9zXpjBM7thGm9bfybGIuNeB xcjjgL2nWqLLasPKHDHVkvqInzjqR3T9K6aYC3POkBBlzly+8qYDAHlsSxywEQ+O taP/Fnm6reneRix/8aOooj18dqvaHgLUcSXdljAPsXO95mEpzCjvaJPHJ2mTKXoA UVL9rQ== Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bhmnbhpvu-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 07 Jan 2026 18:15:24 +0000 (GMT) Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-8b51db8ebd9so776661185a.2 for ; Wed, 07 Jan 2026 10:15:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767809724; x=1768414524; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Rhn7f75cBzRSaSyNIXu2sGOU3jGwzD9Mh33JQAcGM6E=; b=VrheGqmfkP8zlZqF7gP1/HF3Xtx93fBOMbOsvAbJAwGnzPoHN0Kqc6e0nvozzpArTd ClJBKaeXYUm9DC0JBIndQutJuSD/u7ApkBZodamno0QQ0P2SR7eKJXxAWMz51BrK576n f1pL2/B7WV0T91cwfADYzVrH1OaSnaj3ONxRoZcebmp8UmH0+4kwczGKA2dUbehIWT0J DV5caX3enKc3m33SlbfEmB92ROCukyT8/aXoDxLH93BKcJpFmNIcKHIuqZU8FMwAh3w0 rvNQiKqxjNgwUnpFPt0jogT87vqhnps7urKB56f9D7DjByuYaSjyTapmZENl5Nqh5M0s ZOqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767809724; x=1768414524; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Rhn7f75cBzRSaSyNIXu2sGOU3jGwzD9Mh33JQAcGM6E=; b=tkMSIr9aZJBUp9PeNVV2UuyfGZVt/BQhytqkhiSFaV0WcR0cRY74rvmcZjezmDcb+D +gisM0px7qaL3IjEY7tQJ07Bvh1eefmanr9BUbfydfRdoRKbQrERr34fuVZhdnDDsvw3 tJ2NrqmlFOv207THI3W4Qc37m76ptI1O80/i5wNDWeglF/bMGvYw5CUCXvz5nrlvdgHq nOqCJUrRRkMxMuU00YcvKlHRyv55AO/le/28N6ajXZmjU0UR/4FasTrDugL3TTpdEL+K H7rnQZlTf8NU+hloMYN5slnUNlBgt+M5R2TJ67SX/Kdun29qEDTGo77M59VD67agnlN9 fSsQ== X-Forwarded-Encrypted: i=1; AJvYcCVlT7vhPnxuAIUfGBx6BMtiL1L6wZsKbwadJkRk9Z3nEnzLd6HZTOtEtkWslCM9fEeMrdbhQb9KwKk4+A==@lists.linux.dev X-Gm-Message-State: AOJu0YxdF+15VQHoRUQ5WqTa1SRo0CLYon/SqesV6QyXhdk/7JvbAVj0 v46u2cr1J6pFkcmEUULANUYrXlkhVSpzFTspVQ1HJ7Q52A8qppIAm/8CA4Dw+73rHtvAmvpsSSz 3Ov1HNYLvc5yV+mnote+Mj46sriYEmIae+7fJlb7SZov1qfe++IU+UNIC1yuSOK+gUw== X-Gm-Gg: AY/fxX4uI3txLh5k3Nxu4U4jGVoDyezG+vn1y4msCUmn6j6hyM8rkKqn02sTkjm9znO k73HIAZ7Pbkf8dU7HsSwNsYp9Q22fQrXNmHY+/i/JHpwXZF/tRy6b3YAP+JoUacG+vHR0ykXbNR WsPvBb+12kq3kEcufu8OfLwtiE5Cu7qM7sh3wsKybS+9TXjDGnxGMh8I6FTTYMH8jdtdedK6Ue1 iIALFIHyJsR6NfDLqxD5NxeMqgF4FoFHLl/vBm32LZw8hSVaTMz2qBLE61OFcLx6+TZkWy7n0ZP X0mrCkkgq+ZNOgu09+T+FwPif8OTx6DeOYR9DhRMTY0n9S+MiTrRPQfEG6uanWVeQ99TTJQ+Dud 7/8XMt0sP0gx6SLPBLM8Tnct7filGfXf/pq/2ZTYZCGUdoo6Pl0YCGP0//68Nckyd4EKmsRT8Ao YsVL1hDwX7IY2J/ZNVuScN5I4= X-Received: by 2002:a05:620a:19a5:b0:892:10cb:b427 with SMTP id af79cd13be357-8c38940bc70mr456798785a.67.1767809721977; Wed, 07 Jan 2026 10:15:21 -0800 (PST) X-Google-Smtp-Source: AGHT+IEDhZprVBsv7NrDl4r7/stHLp9ske0/9w25bokRbHgFqXeEm1zUot0CQkb+02Aes2IA+aZv+g== X-Received: by 2002:a05:620a:19a5:b0:892:10cb:b427 with SMTP id af79cd13be357-8c38940bc70mr456790785a.67.1767809721391; Wed, 07 Jan 2026 10:15:21 -0800 (PST) Received: from umbar.lan (2001-14ba-a073-af00-264b-feff-fe8b-be8a.rev.dnainternet.fi. [2001:14ba:a073:af00:264b:feff:fe8b:be8a]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-59b65d6988asm1436884e87.80.2026.01.07.10.15.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 10:15:19 -0800 (PST) From: Dmitry Baryshkov Date: Wed, 07 Jan 2026 20:15:07 +0200 Subject: [PATCH v4 10/10] drm/debug: don't register files for unsupported HDMI InfoFrames Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20260107-limit-infoframes-2-v4-10-213d0d3bd490@oss.qualcomm.com> References: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> In-Reply-To: <20260107-limit-infoframes-2-v4-0-213d0d3bd490@oss.qualcomm.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dave Stevenson , =?utf-8?q?Ma=C3=ADra_Canal?= , Raspberry Pi Kernel Maintenance , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Liu Ying , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-rockchip@lists.infradead.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1290; i=dmitry.baryshkov@oss.qualcomm.com; h=from:subject:message-id; bh=Fqja7nqMdmSMtGtKfnnZaHovKcc+8jCwgpdYFW7dJBE=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBpXqKldBKXXeIUEl9VKknThFajiJ4bv/Z+Y6zlU AwqJpH32O6JATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCaV6ipQAKCRCLPIo+Aiko 1SajB/4k5q4SEw24CrrWC3HEsLlY/uKXgpKUIWzeXnMMyXHDWo7v5tevjX/ai/KZzmbo1NC5fGU jhVIocLd7kwuiCUjpW/yVaQGBTAKyovOJsTbYp+V9wBPDqh8cp3VXyONhN+s/zhRGG9gAF2YEzG cgchTc/+0JVBdAMG16Sxc4mMOkZGU+Lxks7qJlyhN6XsUcj8iRQG+d9hUkNlBAgdTcMJpMEn0kd dkJOKbe+FFOrO2OOH4BNawMbMIU0982lxSIPgb5Q/RKX8LhTdWcg7s3XNn8GfdQLMft8fGlKdXt B1XWOTyoPib7k0/IiAyVFTJ9DpbDTMyzhznF9TrmGgOPszSr X-Developer-Key: i=dmitry.baryshkov@oss.qualcomm.com; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA3MDE0NCBTYWx0ZWRfX4m1ke8tL9uHZ L19aCKzaleRh+emkd5JDXrMb8Yfy+Wxb92/YdjP+rtKzoWsIRLxY+0dXF3FFL+AKuf+2PxabkNO dL+Vbx35TdsFpZHM79lBoMCGZyErTso9GgmAqFvH6zp2u0i137RoulbdR85Jq1RrT0PVttu6YW9 McCrfSQdTiQ/tcBuLLCJOlnMZCVO7RJFOuQgeH6UMtBR5I8DDrfQxpzr6RYmncPwEjufC2OGTpM ktVQQEKU0AXkM+OPlBzd6CMpSQ9W0lnSl1Gj+BVg9fRWAk2yU+GWtv2KgmLr7RpHeo1Kz9LYeWn O1zcf2j+jjRpVHykpBMdwa8ktr0AYM1sL2cGcQmpTbZkk4LotsFofLLYqF4V5CU46zZy28uuKoD 5OVlWKRMwPdS/GAG/cF7Z/OHrg6PG5pOLj/nNGLG2YRb/UTqsNPWrYDaCFV6NA668F7WDsAsbTH x3oTjomq4aq3Fw2eJDA== X-Proofpoint-GUID: WnkHisj2JRXYQ-ohh0RG4WEAET4XcYYJ X-Authority-Analysis: v=2.4 cv=eIkeTXp1 c=1 sm=1 tr=0 ts=695ea2bc cx=c_pps a=hnmNkyzTK/kJ09Xio7VxxA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=tIAOKlZC_mo2NaXw_9IA:9 a=QEXdDO2ut3YA:10 a=PEH46H7Ffwr30OY-TuGO:22 X-Proofpoint-ORIG-GUID: WnkHisj2JRXYQ-ohh0RG4WEAET4XcYYJ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-07_03,2026-01-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 clxscore=1015 malwarescore=0 suspectscore=0 phishscore=0 impostorscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601070144 Status: O Having debugfs files for the InfoFrames that are not supported by the driver is confusing, stop registering those in the debugfs. Acked-by: Maxime Ripard Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/drm_debugfs.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 365cf337529f..ae1c6126c2c5 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -672,6 +672,10 @@ static int create_hdmi_audio_infoframe_file(struct drm_connector *connector, { struct dentry *file; + if (!connector->hdmi.funcs || + !connector->hdmi.funcs->audio.write_infoframe) + return 0; + file = debugfs_create_file("audio", 0400, parent, connector, &audio_infoframe_fops); if (IS_ERR(file)) return PTR_ERR(file); @@ -726,6 +730,9 @@ static int create_hdmi_## _f ## _infoframe_file(struct drm_connector *connector, { \ struct dentry *file; \ \ + if (!connector->hdmi.funcs || \ + !connector->hdmi.funcs->_f.write_infoframe) \ + return 0; \ file = debugfs_create_file(#_f, 0400, parent, connector, &_f ## _infoframe_fops); \ if (IS_ERR(file)) \ return PTR_ERR(file); \