From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
To: Rob Clark <robin.clark@oss.qualcomm.com>,
Dmitry Baryshkov <lumag@kernel.org>,
Abhinav Kumar <abhinav.kumar@linux.dev>,
Jessica Zhang <jesszhan0024@gmail.com>,
Sean Paul <sean@poorly.run>,
Marijn Suijten <marijn.suijten@somainline.org>,
David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
Andrzej Hajda <andrzej.hajda@intel.com>,
Neil Armstrong <neil.armstrong@linaro.org>,
Robert Foss <rfoss@kernel.org>,
Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
Jonas Karlman <jonas@kwiboo.se>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Luca Ceresoli <luca.ceresoli@bootlin.com>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>
Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org,
freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: [PATCH 18/24] drm/msm/hdmi: cache is_hdmi instead of storing the connector
Date: Wed, 22 Jul 2026 09:36:33 +0300 [thread overview]
Message-ID: <20260722-drm-msm-display-interface-v1-18-368c10fe62fd@oss.qualcomm.com> (raw)
In-Reply-To: <20260722-drm-msm-display-interface-v1-0-368c10fe62fd@oss.qualcomm.com>
The HDMI driver stored the drm_connector in struct hdmi solely so that a
handful of call sites could consult connector->display_info.is_hdmi, and
so that the hotplug work could hand a connector to drm_bridge_detect().
Several of those call sites run outside of an atomic commit (the HPD
enable/disable paths in msm_hdmi_set_mode(), and the audio update path),
so they have no drm_atomic_state to derive the connector from and thus
relied on the stored pointer.
The only information actually consumed is the is_hdmi boolean. Cache it
in struct hdmi and refresh it from a new .hpd_notify bridge callback:
drm_bridge_connector_detect() updates the connector's EDID (and hence
display_info.is_hdmi) via drm_atomic_helper_connector_hdmi_hotplug()
before invoking .hpd_notify, so the cached value is always up to date.
With that, the stored connector becomes local to msm_hdmi_modeset_init():
the connector object is owned by the DRM core after creation, so there is
no need to keep a driver-side reference. The hotplug work now calls
msm_hdmi_bridge_detect() directly, which ignores its connector argument
anyway.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/hdmi/hdmi.c | 17 ++++++++---------
drivers/gpu/drm/msm/hdmi/hdmi.h | 4 +++-
drivers/gpu/drm/msm/hdmi/hdmi_audio.c | 2 +-
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 16 ++++++++++++++--
4 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 1d5a4b63f3c8..62961dddd8f5 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -27,7 +27,7 @@ void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
spin_lock_irqsave(&hdmi->reg_lock, flags);
if (power_on) {
ctrl |= HDMI_CTRL_ENABLE;
- if (!hdmi->connector->display_info.is_hdmi) {
+ if (!hdmi->is_hdmi) {
ctrl |= HDMI_CTRL_HDMI;
hdmi_write(hdmi, REG_HDMI_CTRL, ctrl);
ctrl &= ~HDMI_CTRL_HDMI;
@@ -164,6 +164,7 @@ static int msm_hdmi_modeset_init(struct msm_display *display,
struct drm_device *dev, struct drm_encoder *encoder)
{
struct hdmi *hdmi = container_of(display, struct hdmi, display);
+ struct drm_connector *connector = NULL;
int ret;
hdmi->dev = dev;
@@ -184,11 +185,11 @@ static int msm_hdmi_modeset_init(struct msm_display *display,
}
}
- hdmi->connector = drm_bridge_connector_init(hdmi->dev, encoder);
- if (IS_ERR(hdmi->connector)) {
- ret = PTR_ERR(hdmi->connector);
+ connector = drm_bridge_connector_init(hdmi->dev, encoder);
+ if (IS_ERR(connector)) {
+ ret = PTR_ERR(connector);
DRM_DEV_ERROR(dev->dev, "failed to create HDMI connector: %d\n", ret);
- hdmi->connector = NULL;
+ connector = NULL;
goto fail;
}
@@ -204,10 +205,8 @@ static int msm_hdmi_modeset_init(struct msm_display *display,
return 0;
fail:
- if (hdmi->connector) {
- hdmi->connector->funcs->destroy(hdmi->connector);
- hdmi->connector = NULL;
- }
+ if (connector)
+ connector->funcs->destroy(connector);
return ret;
}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 869f55d4704a..d4adaa6ccdd5 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -47,6 +47,9 @@ struct hdmi {
struct mutex state_mutex; /* protects two booleans */
unsigned long pixclock;
+ /* cached from the connector's EDID, updated on hotplug */
+ bool is_hdmi;
+
void __iomem *mmio;
phys_addr_t mmio_size;
void __iomem *qfprom_mmio;
@@ -62,7 +65,6 @@ struct hdmi {
struct device *phy_dev;
struct i2c_adapter *i2c;
- struct drm_connector *connector;
struct drm_bridge *bridge;
struct drm_bridge *next_bridge;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c
index 249c167ab04d..ce1864f3f659 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c
@@ -19,7 +19,7 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
bool enabled = audio->enabled;
u32 acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl, audio_config;
- if (!hdmi->connector->display_info.is_hdmi)
+ if (!hdmi->is_hdmi)
return -EINVAL;
DBG("audio: enabled=%d, channels=%d, rate=%d",
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 7abb9243dba5..84a423af73e9 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -345,7 +345,7 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
if (hdmi->power_on) {
power_off(bridge);
hdmi->power_on = false;
- if (hdmi->connector->display_info.is_hdmi)
+ if (hdmi->is_hdmi)
msm_hdmi_audio_update(hdmi);
msm_hdmi_phy_resource_disable(phy);
}
@@ -452,6 +452,17 @@ static enum drm_mode_status msm_hdmi_bridge_tmds_char_rate_valid(const struct dr
return 0;
}
+static void msm_hdmi_bridge_hpd_notify(struct drm_bridge *bridge,
+ struct drm_connector *connector,
+ enum drm_connector_status status)
+{
+ struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+ struct hdmi *hdmi = hdmi_bridge->hdmi;
+
+ /* called after the EDID update, so display_info is up to date */
+ hdmi->is_hdmi = connector->display_info.is_hdmi;
+}
+
static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -460,6 +471,7 @@ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
.atomic_post_disable = msm_hdmi_bridge_atomic_post_disable,
.edid_read = msm_hdmi_bridge_edid_read,
.detect = msm_hdmi_bridge_detect,
+ .hpd_notify = msm_hdmi_bridge_hpd_notify,
.hpd_enable = msm_hdmi_hpd_enable,
.hpd_disable = msm_hdmi_hpd_disable,
.hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid,
@@ -482,7 +494,7 @@ msm_hdmi_hotplug_work(struct work_struct *work)
container_of(work, struct hdmi_bridge, hpd_work);
struct drm_bridge *bridge = &hdmi_bridge->base;
- drm_bridge_hpd_notify(bridge, drm_bridge_detect(bridge, hdmi_bridge->hdmi->connector));
+ drm_bridge_hpd_notify(bridge, msm_hdmi_bridge_detect(bridge, NULL));
}
/* initialize bridge */
--
2.47.3
next prev parent reply other threads:[~2026-07-22 6:37 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-22 6:36 [PATCH 00/24] drm/msm: introduce the struct msm_display interface Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 01/24] drm/msm/dp: reject YUV420-only modes without VSC SDP support Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 02/24] drm/msm/dp: drop the always-true yuv_supported argument Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 03/24] drm/msm: create the display connectors from common code Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 04/24] drm/msm: introduce the struct msm_display interface Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 05/24] drm/msm: route the display snapshot through the " Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 06/24] drm/msm/hdmi: capture the HDMI registers in the display snapshot Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 07/24] drm/msm: add the wide_bus_enabled callback to msm_display Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 08/24] drm/msm: add the needs_periph_flush " Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 09/24] drm/msm: add the is_cmd_mode " Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 10/24] drm/msm: add the get_dsc_config " Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 11/24] drm/msm: add the get_te_source " Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 12/24] drm/msm: add is_bonded and needs_encoder callbacks " Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 13/24] drm/msm/hdmi: use dev_get_drvdata() in msm_hdmi_unbind() Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 14/24] drm/msm: store the display sub-blocks as struct msm_display Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 15/24] drm/msm/dp: do not reject wide-bus modes while a YUV420 mode is active Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 16/24] drm/msm/dp: remove cached drm_edid from panel Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 17/24] drm/msm/dp: drop deprecated .mode_set() and use .atomic_pre_enable Dmitry Baryshkov
2026-07-22 6:36 ` Dmitry Baryshkov [this message]
2026-07-22 6:36 ` [PATCH 19/24] drm/msm/dp: drop redundant panel->connector Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 20/24] drm/msm/dp: use drm_display_info in mode_valid callbacks Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 21/24] drm/msm/dp: guard subconnector setup on the connector type Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 22/24] drm/msm/dp: stop storing the connector in struct msm_dp Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 23/24] drm/msm: create the bridge connectors from common code Dmitry Baryshkov
2026-07-22 6:36 ` [PATCH 24/24] drm/bridge-connector: attach the DP subconnector property Dmitry Baryshkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260722-drm-msm-display-interface-v1-18-368c10fe62fd@oss.qualcomm.com \
--to=dmitry.baryshkov@oss.qualcomm.com \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=abhinav.kumar@linux.dev \
--cc=airlied@gmail.com \
--cc=andrzej.hajda@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=jernej.skrabec@gmail.com \
--cc=jesszhan0024@gmail.com \
--cc=jonas@kwiboo.se \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luca.ceresoli@bootlin.com \
--cc=lumag@kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=marijn.suijten@somainline.org \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=rfoss@kernel.org \
--cc=robin.clark@oss.qualcomm.com \
--cc=sean@poorly.run \
--cc=simona@ffwll.ch \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®