Hi, Jitao: Jitao Shi <jitao.shi@xxxxxxxxxxxx> 於 2022年1月12日 週三 下午11:01寫道: > > DP Spec 1.4a 3.3 requires dp detect the hpd with debounce. > > Upstream implementations should implement HPD signal de-bouncing on > an external connection. A period of 100ms should be used for > detecting an HPD connect event (i.e., the event, “HPD high,” is > confirmed only after HPD has been continuously asserted for 100ms). > Care should be taken to not implement de-bouncing on an IRQ_HPD and > on a downstream device-generated pair of HPD disconnect/reconnect > events (typically HPD shall be de-asserted for more than 2ms, but > less than 100ms in this case). To cover these cases, HPD de-bounce > should be implemented only after HPD low has been detected for 100ms. > Timing requirements in this Standard related to the detection of > HPD high are to be interpreted as applying from the completion of an > implementation-dependent de-bounce period. > > Signed-off-by: Jitao Shi <jitao.shi@xxxxxxxxxxxx> > --- mtk dp driver has not been upstreamed yet. This patch seems depend on another series [1]. Please describe the dependency information here. [1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=597485 Regards, Chun-Kuang. > drivers/gpu/drm/mediatek/mtk_dp.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c > index a256d55346a2..05f401a024a4 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dp.c > +++ b/drivers/gpu/drm/mediatek/mtk_dp.c > @@ -193,6 +193,8 @@ struct mtk_dp { > struct mutex eld_lock; > u8 connector_eld[MAX_ELD_BYTES]; > struct drm_connector *conn; > + bool need_debounce; > + struct timer_list debounce_timer; > }; > > enum mtk_dp_sdp_type { > @@ -2217,6 +2219,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev) > if (event < 0) > return IRQ_HANDLED; > > + if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in) > + msleep(100); > + > if (mtk_dp->drm_dev) { > dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n"); > drm_helper_hpd_irq_event(mtk_dp->bridge.dev); > @@ -2296,6 +2301,14 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp) > mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP; > } > train_info->cable_state_change = true; > + > + if (train_info->cable_state_change) { > + if (!train_info->cable_plugged_in) { > + mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1); > + mtk_dp->need_debounce = false; > + } > + } > + > return IRQ_WAKE_THREAD; > } > > @@ -2903,6 +2916,13 @@ static int mtk_dp_register_audio_driver(struct device *dev) > return 0; > } > > +static void mtk_dp_debounce_timer(struct timer_list *t) > +{ > + struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer); > + > + mtk_dp->need_debounce = true; > +} > + > static int mtk_dp_probe(struct platform_device *pdev) > { > struct mtk_dp *mtk_dp; > @@ -2990,6 +3010,9 @@ static int mtk_dp_probe(struct platform_device *pdev) > else > mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; > > + mtk_dp->need_debounce = true; > + timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0); > + > mtk_dp->bridge.ops = > DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; > drm_bridge_add(&mtk_dp->bridge); > @@ -3008,6 +3031,7 @@ static int mtk_dp_remove(struct platform_device *pdev) > > mtk_dp_video_mute(mtk_dp, true); > mtk_dp_audio_mute(mtk_dp, true); > + del_timer_sync(&mtk_dp->debounce_timer); > > pm_runtime_disable(&pdev->dev); > > -- > 2.12.5 >