[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250808-hpd-refactor-v2-11-7f4e1e741aa3@oss.qualcomm.com>
Date: Fri, 08 Aug 2025 17:35:23 -0700
From: Jessica Zhang <jessica.zhang@....qualcomm.com>
To: Rob Clark <robin.clark@....qualcomm.com>,
Abhinav Kumar <abhinav.kumar@...ux.dev>,
Dmitry Baryshkov <lumag@...nel.org>, Sean Paul <sean@...rly.run>,
Marijn Suijten <marijn.suijten@...ainline.org>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>,
Jessica Zhang <jessica.zhang@....qualcomm.com>,
Kuogee Hsieh <quic_khsieh@...cinc.com>
Cc: linux-arm-msm@...r.kernel.org, dri-devel@...ts.freedesktop.org,
freedreno@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
Yongxing Mou <quic_yongmou@...cinc.com>
Subject: [PATCH v2 11/12] drm/msm/dp: drop the entire HPD state machine
Since internal HPD IRQ event handling has been moved to being handled by
the DRM framework detect() and hpd_notify() callbacks, there is no need
for the MSM driver to track the HPD state separately.
Drop all references to the HPD state machine and replace existing checks
with checks for link_ready or sink_count.
Signed-off-by: Jessica Zhang <jessica.zhang@....qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_ctrl.c | 22 ------
drivers/gpu/drm/msm/dp/dp_ctrl.h | 1 -
drivers/gpu/drm/msm/dp/dp_display.c | 148 +++++++++---------------------------
3 files changed, 34 insertions(+), 137 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index c42fd2c17a32..4cf269b98029 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -2567,28 +2567,6 @@ void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl)
phy, phy->init_count, phy->power_count);
}
-void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl)
-{
- struct msm_dp_ctrl_private *ctrl;
- struct phy *phy;
-
- ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
- phy = ctrl->phy;
-
- msm_dp_ctrl_mainlink_disable(ctrl);
-
- dev_pm_opp_set_rate(ctrl->dev, 0);
- msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
-
- DRM_DEBUG_DP("Before, phy=%p init_count=%d power_on=%d\n",
- phy, phy->init_count, phy->power_count);
-
- phy_power_off(phy);
-
- DRM_DEBUG_DP("After, phy=%p init_count=%d power_on=%d\n",
- phy, phy->init_count, phy->power_count);
-}
-
void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
{
struct msm_dp_ctrl_private *ctrl;
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h
index 124b9b21bb7f..f68bee62713f 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.h
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h
@@ -19,7 +19,6 @@ struct phy;
int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl);
int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train);
void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl);
-void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl);
irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 82f0b6bdbf39..dd529942f7db 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -43,15 +43,6 @@ enum {
ISR_HPD_REPLUG_COUNT,
};
-/* event thread connection state */
-enum {
- ST_DISCONNECTED,
- ST_MAINLINK_READY,
- ST_CONNECTED,
- ST_DISCONNECT_PENDING,
- ST_DISPLAY_OFF,
-};
-
struct msm_dp_display_private {
int irq;
@@ -79,7 +70,6 @@ struct msm_dp_display_private {
spinlock_t irq_thread_lock;
u32 hpd_isr_status;
- u32 hpd_state;
bool wide_bus_supported;
struct msm_dp_audio *audio;
@@ -392,24 +382,6 @@ static int msm_dp_display_usbpd_configure_cb(struct device *dev)
return msm_dp_display_process_hpd_high(dp);
}
-static int msm_dp_display_notify_disconnect(struct device *dev)
-{
- struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
-
- if (!dp->msm_dp_display.is_edp)
- drm_dp_set_subconnector_property(dp->msm_dp_display.connector,
- connector_status_disconnected,
- dp->panel->dpcd,
- dp->panel->downstream_ports);
-
- dp->msm_dp_display.link_ready = false;
-
- if (!dp->msm_dp_display.internal_hpd)
- msm_dp_display_send_hpd_notification(dp, false);
-
- return 0;
-}
-
static void msm_dp_display_handle_video_request(struct msm_dp_display_private *dp)
{
if (dp->link->sink_request & DP_TEST_LINK_VIDEO_PATTERN) {
@@ -424,17 +396,11 @@ static int msm_dp_display_handle_port_status_changed(struct msm_dp_display_priva
if (drm_dp_is_branch(dp->panel->dpcd) && dp->link->sink_count == 0) {
drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");
- if (dp->hpd_state != ST_DISCONNECTED) {
- dp->hpd_state = ST_DISCONNECT_PENDING;
+ if (dp->msm_dp_display.link_ready)
msm_dp_display_send_hpd_notification(dp, false);
- }
} else {
- if (dp->hpd_state == ST_DISCONNECTED) {
- dp->hpd_state = ST_MAINLINK_READY;
+ if (!dp->msm_dp_display.link_ready)
rc = msm_dp_display_process_hpd_high(dp);
- if (rc)
- dp->hpd_state = ST_DISCONNECTED;
- }
}
return rc;
@@ -445,7 +411,7 @@ static int msm_dp_display_handle_irq_hpd(struct msm_dp_display_private *dp)
u32 sink_request = dp->link->sink_request;
drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);
- if (dp->hpd_state == ST_DISCONNECTED) {
+ if (!dp->msm_dp_display.link_ready) {
if (sink_request & DP_LINK_STATUS_UPDATED) {
drm_dbg_dp(dp->drm_dev, "Disconnected sink_request: %d\n",
sink_request);
@@ -472,8 +438,7 @@ static int msm_dp_display_usbpd_attention_cb(struct device *dev)
rc = msm_dp_link_process_request(dp->link);
if (!rc) {
sink_request = dp->link->sink_request;
- drm_dbg_dp(dp->drm_dev, "hpd_state=%d sink_request=%d\n",
- dp->hpd_state, sink_request);
+ drm_dbg_dp(dp->drm_dev, "sink_request=%d\n", sink_request);
if (sink_request & DS_PORT_STATUS_CHANGED)
rc = msm_dp_display_handle_port_status_changed(dp);
else
@@ -485,20 +450,15 @@ static int msm_dp_display_usbpd_attention_cb(struct device *dev)
static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp, u32 data)
{
- u32 state;
int ret;
struct platform_device *pdev = dp->msm_dp_display.pdev;
msm_dp_aux_enable_xfers(dp->aux, true);
- state = dp->hpd_state;
- drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
-
- if (state == ST_MAINLINK_READY || state == ST_CONNECTED)
- return 0;
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
+ dp->msm_dp_display.connector_type);
- if (state == ST_DISCONNECT_PENDING)
+ if (dp->msm_dp_display.link_ready)
return 0;
ret = pm_runtime_resume_and_get(&pdev->dev);
@@ -509,14 +469,12 @@ static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp, u32 data)
ret = msm_dp_display_usbpd_configure_cb(&pdev->dev);
if (ret) { /* link train failed */
- dp->hpd_state = ST_DISCONNECTED;
+ dp->msm_dp_display.link_ready = false;
pm_runtime_put_sync(&pdev->dev);
- } else {
- dp->hpd_state = ST_MAINLINK_READY;
}
- drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
+ dp->msm_dp_display.connector_type);
/* uevent will complete connection part */
return 0;
@@ -538,51 +496,40 @@ static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,
static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data)
{
- u32 state;
struct platform_device *pdev = dp->msm_dp_display.pdev;
msm_dp_aux_enable_xfers(dp->aux, false);
- state = dp->hpd_state;
-
- drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
+ dp->msm_dp_display.connector_type);
- if (state == ST_DISCONNECTED) {
- /* triggered by irq_hdp with sink_count = 0 */
- if (dp->link->sink_count == 0) {
- msm_dp_display_host_phy_exit(dp);
- }
- msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
+ if (!dp->msm_dp_display.link_ready)
return 0;
- } else if (state == ST_DISCONNECT_PENDING) {
- return 0;
- } else if (state == ST_MAINLINK_READY) {
- msm_dp_ctrl_off_link(dp->ctrl);
+
+ /* triggered by irq_hdp with sink_count = 0 */
+ if (dp->link->sink_count == 0)
msm_dp_display_host_phy_exit(dp);
- dp->hpd_state = ST_DISCONNECTED;
- msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
- pm_runtime_put_sync(&pdev->dev);
- return 0;
- }
/*
* We don't need separate work for disconnect as
* connect/attention interrupts are disabled
*/
- msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
+ if (!dp->msm_dp_display.is_edp)
+ drm_dp_set_subconnector_property(dp->msm_dp_display.connector,
+ connector_status_disconnected,
+ dp->panel->dpcd,
+ dp->panel->downstream_ports);
- if (state == ST_DISPLAY_OFF) {
- dp->hpd_state = ST_DISCONNECTED;
- } else {
- dp->hpd_state = ST_DISCONNECT_PENDING;
- }
+ dp->msm_dp_display.link_ready = false;
+
+ if (!dp->msm_dp_display.internal_hpd)
+ msm_dp_display_send_hpd_notification(dp, false);
/* signal the disconnect event early to ensure proper teardown */
msm_dp_display_handle_plugged_change(&dp->msm_dp_display, false);
- drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
+ dp->msm_dp_display.connector_type);
/* uevent will complete disconnection part */
pm_runtime_put_sync(&pdev->dev);
@@ -591,23 +538,14 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data)
static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp, u32 data)
{
- u32 state;
-
/* irq_hpd can happen at either connected or disconnected state */
- state = dp->hpd_state;
- drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
-
- if (state == ST_DISPLAY_OFF)
- return 0;
-
- if (state == ST_MAINLINK_READY || state == ST_DISCONNECT_PENDING)
- return 0;
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
+ dp->msm_dp_display.connector_type);
msm_dp_display_usbpd_attention_cb(&dp->msm_dp_display.pdev->dev);
- drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
+ dp->msm_dp_display.connector_type);
return 0;
}
@@ -1426,7 +1364,6 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
int rc = 0;
struct msm_dp_display_private *msm_dp_display;
- u32 hpd_state;
bool force_link_train = false;
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
@@ -1443,7 +1380,6 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
return;
}
- hpd_state = msm_dp_display->hpd_state;
if (msm_dp_display->link->sink_count == 0)
return;
@@ -1453,9 +1389,7 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
return;
}
- hpd_state = msm_dp_display->hpd_state;
-
- if (hpd_state == ST_DISPLAY_OFF) {
+ if (dp->link_ready && !dp->power_on) {
msm_dp_display_host_phy_init(msm_dp_display);
force_link_train = true;
}
@@ -1474,9 +1408,6 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
msm_dp_display_disable(msm_dp_display);
}
- /* completed connection */
- msm_dp_display->hpd_state = ST_CONNECTED;
-
drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
}
@@ -1497,7 +1428,6 @@ void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
{
struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
- u32 hpd_state;
struct msm_dp_display_private *msm_dp_display;
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
@@ -1505,21 +1435,11 @@ void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
if (dp->is_edp)
msm_dp_hpd_unplug_handle(msm_dp_display, 0);
- hpd_state = msm_dp_display->hpd_state;
- if (hpd_state != ST_DISCONNECT_PENDING && hpd_state != ST_CONNECTED)
- drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n",
- dp->connector_type, hpd_state);
+ if (!dp->link_ready)
+ drm_dbg_dp(dp->drm_dev, "type=%d is disconnected\n", dp->connector_type);
msm_dp_display_disable(msm_dp_display);
- hpd_state = msm_dp_display->hpd_state;
- if (hpd_state == ST_DISCONNECT_PENDING) {
- /* completed disconnection */
- msm_dp_display->hpd_state = ST_DISCONNECTED;
- } else {
- msm_dp_display->hpd_state = ST_DISPLAY_OFF;
- }
-
drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
pm_runtime_put_sync(&dp->pdev->dev);
--
2.50.1
Powered by blists - more mailing lists