From nobody Tue Dec 16 07:34:20 2025 Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8707527466A for ; Sun, 14 Dec 2025 20:48:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.68 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765745312; cv=none; b=aj40QNP08Qp6qlAPCXojF+uzy2C2pVyKaFRv6KZx2xuGeo4rXLhPFwdyru4xcBrm+EsJu5ueG7d3FtO3tdtqePX+xogomXRWebiYa/xlwkG664uWXP3nQy/u88yJJEga8+wG4EMmlmUik+nNDjhGHvpSnaojtyFmV6TN7gOLf44= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765745312; c=relaxed/simple; bh=TcwMHoDEwaiNpVVENgTmjk5JwGFt7zB3QOd1uIX5JT8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=ixpFPGlEN1tyyCaGf6SB6ncZtWMaQTyh01HiCVEEYeL2HTc89Z2rDcMrFNS5SuXgPtA8IdpYz5UccNISuwc68QLyXCcbUsT4nxB5uowIzS5Wc/A7nq+CcZrH1XXHCN85oNi7LcaR0D4B+dXrhAIe8U6ftK/ch/MttaB1xb5sQKI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OXEspm8L; arc=none smtp.client-ip=209.85.128.68 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OXEspm8L" Received: by mail-wm1-f68.google.com with SMTP id 5b1f17b1804b1-477b198f4bcso22103875e9.3 for ; Sun, 14 Dec 2025 12:48:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765745308; x=1766350108; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:from:to:cc:subject:date:message-id:reply-to; bh=vNonSz/psu7LwKVFUVtvRRDRx4rkVmD2CMw/UAxEWwM=; b=OXEspm8LsVZghnxaLNr/tMHObtV7E+Dghloyae6U1I+1jHAw1LdnR3aF6f6osDT9bT DLR3aE+WCvnqQNAYoSKFKYe/zX653X/hDFWdvrZR0YD1/be3rqnW5BbX7ZWUHDwMgnID 3qIz19R8OUJdTI9z8Rv3kQKtoRXZqXnTQkHUHo0ejzZbmlmHuPhNIg2EPyhhZBh3/sAD vW+csGhGvYE7kHOaBydMBeDGyovO4RzS9U3YX4fuofQSy9vpPzMGMy1Ij1n3jDC+ErOa nlfPP88I1CHMd1ltrJ/2e623xmxQ92TR2vXCjfUFBAjdwrkCfYWLIG4EYT93HATRA5dS 4Eyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765745308; x=1766350108; h=cc:to: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=vNonSz/psu7LwKVFUVtvRRDRx4rkVmD2CMw/UAxEWwM=; b=RN2PudGccT3Qo5WtfjdeC4iM6g7fiD4PQ6OEvKQ19wlruXIlpEjJNpIMziRAxdQCbx yQYDbdMcOcdXTTExAO4dZL/UWkNkOqwHXJBb+Mm+U6KfiCz4x/2yxIIEXCyRM8L0TWw3 Vaqao1jQ0V5AReCw2FY0mJ8EexdlYNEtWkm/AHeZPaGn6No2+lhIzqOlPlerUFnd7AWs S38Q4EmXRsJhF5GghNjRoafbIqaVrcqaXpKpGS5aVPn9fYHAOnRKLBtuBg+sm6jR9ndc PHHge/JxcVQdck6BTdofemT2OsQ3U22BOwJ/2cFhRl/6Cv+tHemJNKHEijTr6NFvlKeE 1Tkg== X-Forwarded-Encrypted: i=1; AJvYcCWjRAEqziRarXHQQSTLrBOLpNAOfUSnxmf5dCmhfDukcOKahaZigzk8uwjWu3Vo6QKafbjFMWGxhLQ1cGc=@vger.kernel.org X-Gm-Message-State: AOJu0YwZQb82el/4EnYFcS+VVgDGtmA24bn01sjLC/fGTO5awiN0dVA8 t2vDVw4yhgrQ2vmsm1ldsppADeAomzq4wgaMFWMac6r7PYTOSSFa5ds6 X-Gm-Gg: AY/fxX4cJ5H7e7ru8byfWhU0prNiCvLmdtuUlxYyxhbScHhlyQvHc08GEETNxn3GfUS mme54/0aUdpZTKXqwq1yb6+FcQCW71EAla0I+5jMQNz5JxM0vPGyZcK3k85K5TTWC2wTIvRv4tq TCtpvWt9kbD3vI+8E1QCmS95dZULhRoHQ7i6tPk2mW/8sK74QtAiDJucCtCMbh+JgMaIXjibkqi LZaIgRxvB4oI1EqOesl0KYTnJ7+iZOVnbAUdWZVb7vStYab3pv74vVFcRCXYsCJ4K4HvNAIzPQf ViuBXbzEfnKSer+Ic72J19E2AV94+/hP/P0F/+FP9P/A2L7HIZDpuKLYvuRemTcSylpcHRHDH5o uYdc29sLh/3kQGrqTwqlMFKR6dMsu6Xd6JkO+8Fyzj1+rK8cp7jP0ZGfzNXgqH1QDaYKF62qOr6 p5KMr/V+PDFoSOuAkgUMk69E3Jp/fMZaeBfhZ5ZlqMWEPW/bJX5Sn2ZfFEvKWQ71j1k+4= X-Google-Smtp-Source: AGHT+IFBCVvj6+os8tE0zn7I5CZGv9VZPVSZHJMl/dseBhLP5fj10TprRwFuaFPRpuk7nw+hKEUczA== X-Received: by 2002:a05:600c:3104:b0:477:af07:dd17 with SMTP id 5b1f17b1804b1-47a8f90634fmr86748335e9.24.1765745307477; Sun, 14 Dec 2025 12:48:27 -0800 (PST) Received: from [192.168.1.6] (92.40.201.95.threembb.co.uk. [92.40.201.95]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47a8f768936sm151673595e9.6.2025.12.14.12.48.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 14 Dec 2025 12:48:27 -0800 (PST) From: Dale Whinham Date: Sun, 14 Dec 2025 20:48:12 +0000 Subject: [PATCH] drm/msm/dp: Enable support for eDP v1.4+ link rates table Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251214-drm-msm-edp14-v1-1-45de8c168cec@gmail.com> X-B4-Tracking: v=1; b=H4sIAIsiP2kC/x3MQQqAIBBA0avIrBPSNKKrRAtxxpqFJgoRSHdPW r7F/w0qFaYKq2hQ6ObKV+pQgwB/unSQZOwGPWqrtDISS5SxRkmYu5Zg0M8W/WQc9CYXCvz8v21 /3w+xqy7RXwAAAA== X-Change-ID: 20251214-drm-msm-edp14-8f4dc65dc34a To: Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , David Airlie , Simona Vetter Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org, Dale Whinham , =?utf-8?q?J=C3=A9r=C3=B4me_de_Bretagne?= , Steev Klimaszewski X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1765745306; l=8083; i=daleyo@gmail.com; s=20251214; h=from:subject:message-id; bh=TcwMHoDEwaiNpVVENgTmjk5JwGFt7zB3QOd1uIX5JT8=; b=RnEdCGQ3MrJHIIbU35i5I0o3JLkQeHea3CMb/A3VD3uiOO0lL//YVE9vp0JMeb3O4NuwM4iRT MBAlvTWA7FiDQdWKuDO6ZNWqHK94C6Z0yslSnm+shkx4SWrUzUHxF98 X-Developer-Key: i=daleyo@gmail.com; a=ed25519; pk=M4mvgx1TB2TniKaedTDsO3PbLKgFosJuegXRXPbn2Ds= The MSM DRM driver currently does not support panels which report their supported link rates via the SUPPORTED_LINK_RATES table. For panels which do not offer the optional eDP v1.3 fallback via MAX_LINK_RATE, this will cause a panel probe failure (e.g. Samsung ATNA30DW01-1 as found in Microsoft Surface Pro 11). Detect eDP v1.4 panels and parse the SUPPORTED_LINK_RATES table when present. Additionally, set the rate using LINK_RATE_SET instead of LINK_BW_SET, but only if LINK_BW_SET hasn't already been written to. Signed-off-by: Dale Whinham Tested-by: J=C3=A9r=C3=B4me de Bretagne Tested-by: Steev Klimaszewski --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 57 +++++++++++++++++----------- drivers/gpu/drm/msm/dp/dp_link.h | 3 ++ drivers/gpu/drm/msm/dp/dp_panel.c | 79 +++++++++++++++++++++++++++++++++--= ---- 3 files changed, 107 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_c= trl.c index cbcc7c2f0ffc..f00456902c10 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -175,20 +175,29 @@ static inline void msm_dp_write_link(struct msm_dp_ct= rl_private *ctrl, static int msm_dp_aux_link_configure(struct drm_dp_aux *aux, struct msm_dp_link_info *link) { - u8 values[2]; + u8 lane_count, bw_code; int err; =20 - values[0] =3D drm_dp_link_rate_to_bw_code(link->rate); - values[1] =3D link->num_lanes; + lane_count =3D link->num_lanes; =20 if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING) - values[1] |=3D DP_LANE_COUNT_ENHANCED_FRAME_EN; + lane_count |=3D DP_LANE_COUNT_ENHANCED_FRAME_EN; + + if (link->use_rate_set) { + DRM_DEBUG_DP("using LINK_RATE_SET: 0x%02x", link->rate_set); + err =3D drm_dp_dpcd_writeb(aux, DP_LINK_RATE_SET, link->rate_set); + } else { + bw_code =3D drm_dp_link_rate_to_bw_code(link->rate); + DRM_DEBUG_DP("using LINK_BW_SET: 0x%02x", bw_code); + err =3D drm_dp_dpcd_writeb(aux, DP_LINK_BW_SET, bw_code); + } =20 - err =3D drm_dp_dpcd_write(aux, DP_LINK_BW_SET, values, sizeof(values)); if (err < 0) return err; =20 - return 0; + err =3D drm_dp_dpcd_writeb(aux, DP_LANE_COUNT_SET, lane_count); + + return err; } =20 /* @@ -1474,26 +1483,32 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_c= trl_private *ctrl, static int msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private *ct= rl) { int ret =3D 0; + struct msm_dp_link_info *link_params =3D &ctrl->link->link_params; =20 - switch (ctrl->link->link_params.rate) { - case 810000: - ctrl->link->link_params.rate =3D 540000; - break; - case 540000: - ctrl->link->link_params.rate =3D 270000; - break; - case 270000: - ctrl->link->link_params.rate =3D 162000; - break; - case 162000: - default: - ret =3D -EINVAL; - break; + if (link_params->rate_set) { + --link_params->rate_set; + link_params->rate =3D link_params->supported_rates[link_params->rate_set= ]; + } else { + switch (link_params->rate) { + case 810000: + link_params->rate =3D 540000; + break; + case 540000: + link_params->rate =3D 270000; + break; + case 270000: + link_params->rate =3D 162000; + break; + case 162000: + default: + ret =3D -EINVAL; + break; + } } =20 if (!ret) { drm_dbg_dp(ctrl->drm_dev, "new rate=3D0x%x\n", - ctrl->link->link_params.rate); + link_params->rate); } =20 return ret; diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_l= ink.h index b1eb2de6d2a7..725e08f75574 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.h +++ b/drivers/gpu/drm/msm/dp/dp_link.h @@ -17,6 +17,9 @@ struct msm_dp_link_info { unsigned char revision; unsigned int rate; + unsigned int supported_rates[DP_MAX_SUPPORTED_RATES]; + unsigned int rate_set; + bool use_rate_set; unsigned int num_lanes; unsigned long capabilities; }; diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_= panel.c index ad5d55bf009d..5f9ccc48ee6c 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.c +++ b/drivers/gpu/drm/msm/dp/dp_panel.c @@ -13,6 +13,8 @@ #include =20 #include +#include +#include =20 #define DP_INTF_CONFIG_DATABUS_WIDEN BIT(4) =20 @@ -107,29 +109,84 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel= *msm_dp_panel) drm_dbg_dp(panel->drm_dev, "max_lanes=3D%d max_link_rate=3D%d\n", link->max_dp_lanes, link->max_dp_link_rate); =20 - link_info->rate =3D drm_dp_max_link_rate(dpcd); + max_lttpr_lanes =3D drm_dp_lttpr_max_lane_count(link->lttpr_common_caps); + max_lttpr_rate =3D drm_dp_lttpr_max_link_rate(link->lttpr_common_caps); + + /* For eDP v1.4+, parse the SUPPORTED_LINK_RATES table */ + if (link_info->revision >=3D DP_DPCD_REV_14) { + __le16 rates[DP_MAX_SUPPORTED_RATES]; + u8 bw_set; + int i; + + rc =3D drm_dp_dpcd_read_data(panel->aux, DP_SUPPORTED_LINK_RATES, + rates, sizeof(rates)); + if (rc) + return rc; + + rc =3D drm_dp_dpcd_read_byte(panel->aux, DP_LINK_BW_SET, &bw_set); + if (rc) + return rc; + + /* Find index of maximum supported link rate that does not exceed dtsi l= imits */ + for (i =3D 0; i < ARRAY_SIZE(rates); i++) { + /* + * The value from the DPCD multiplied by 200 gives + * the link rate in kHz. Divide by 10 to convert to + * symbol rate, accounting for 8b/10b encoding. + */ + u32 rate =3D (le16_to_cpu(rates[i]) * 200) / 10; + + if (!rate) + break; + + drm_dbg_dp(panel->drm_dev, + "SUPPORTED_LINK_RATES[%d]: %d\n", i, rate); + + /* Limit link rate from link-frequencies of endpoint property of dtsi */ + if (rate > link->max_dp_link_rate) + break; + + /* Limit link rate from LTTPR capabilities, if any */ + if (max_lttpr_rate && rate > max_lttpr_rate) + break; + + link_info->rate =3D rate; + link_info->supported_rates[i] =3D rate; + link_info->rate_set =3D i; + } + + /* Only use LINK_RATE_SET if LINK_BW_SET hasn't already been written to = */ + if (!bw_set && link_info->rate) + link_info->use_rate_set =3D true; + } + + /* Fall back on MAX_LINK_RATE/LINK_BW_SET (eDP v1.3) */ + if (!link_info->rate) { + link_info->rate =3D drm_dp_max_link_rate(dpcd); + + /* Limit link rate from link-frequencies of endpoint property of dtsi */ + if (link_info->rate > link->max_dp_link_rate) + link_info->rate =3D link->max_dp_link_rate; + + /* Limit link rate from LTTPR capabilities, if any */ + if (max_lttpr_rate && max_lttpr_rate < link_info->rate) + link_info->rate =3D max_lttpr_rate; + } + link_info->num_lanes =3D drm_dp_max_lane_count(dpcd); =20 /* Limit data lanes from data-lanes of endpoint property of dtsi */ if (link_info->num_lanes > link->max_dp_lanes) link_info->num_lanes =3D link->max_dp_lanes; =20 - /* Limit link rate from link-frequencies of endpoint property of dtsi */ - if (link_info->rate > link->max_dp_link_rate) - link_info->rate =3D link->max_dp_link_rate; - /* Limit data lanes from LTTPR capabilities, if any */ - max_lttpr_lanes =3D drm_dp_lttpr_max_lane_count(panel->link->lttpr_common= _caps); if (max_lttpr_lanes && max_lttpr_lanes < link_info->num_lanes) link_info->num_lanes =3D max_lttpr_lanes; =20 - /* Limit link rate from LTTPR capabilities, if any */ - max_lttpr_rate =3D drm_dp_lttpr_max_link_rate(panel->link->lttpr_common_c= aps); - if (max_lttpr_rate && max_lttpr_rate < link_info->rate) - link_info->rate =3D max_lttpr_rate; - drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor); drm_dbg_dp(panel->drm_dev, "link_rate=3D%d\n", link_info->rate); + drm_dbg_dp(panel->drm_dev, "link_rate_set=3D%d\n", link_info->rate_set); + drm_dbg_dp(panel->drm_dev, "use_rate_set=3D%d\n", link_info->use_rate_set= ); drm_dbg_dp(panel->drm_dev, "lane_count=3D%d\n", link_info->num_lanes); =20 if (drm_dp_enhanced_frame_cap(dpcd)) --- base-commit: 7bc29d5fb6faff2f547323c9ee8d3a0790cd2530 change-id: 20251214-drm-msm-edp14-8f4dc65dc34a Best regards, --=20 Dale Whinham