@@ -174,6 +174,33 @@ struct mtk_dp {
struct device *codec_dev;
u8 connector_eld[MAX_ELD_BYTES];
struct drm_connector *conn;
+ bool need_debounce;
+ struct timer_list debounce_timer;
+};
+
+enum mtk_dp_sdp_type {
+ MTK_DP_SDP_NONE = 0x00,
+ MTK_DP_SDP_ACM = 0x01,
+ MTK_DP_SDP_ISRC = 0x02,
+ MTK_DP_SDP_AVI = 0x03,
+ MTK_DP_SDP_AUI = 0x04,
+ MTK_DP_SDP_SPD = 0x05,
+ MTK_DP_SDP_MPEG = 0x06,
+ MTK_DP_SDP_NTSC = 0x07,
+ MTK_DP_SDP_VSP = 0x08,
+ MTK_DP_SDP_VSC = 0x09,
+ MTK_DP_SDP_EXT = 0x0A,
+ MTK_DP_SDP_PPS0 = 0x0B,
+ MTK_DP_SDP_PPS1 = 0x0C,
+ MTK_DP_SDP_PPS2 = 0x0D,
+ MTK_DP_SDP_PPS3 = 0x0E,
+ MTK_DP_SDP_DRM = 0x10,
+ MTK_DP_SDP_MAX_NUM
+};
+
+struct mtk_dp_sdp_packet {
+ enum mtk_dp_sdp_type type;
+ struct dp_sdp sdp;
};
static bool mtk_dp_is_edp(struct mtk_dp *mtk_dp)
@@ -1812,6 +1839,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);
@@ -1890,6 +1920,11 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
}
train_info->cable_state_change = true;
+ 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;
}
@@ -2337,6 +2372,13 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
.detect = mtk_dp_bdg_detect,
};
+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;
@@ -2394,6 +2436,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
mtk_dp->bridge.of_node = dev->of_node;
mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
+ 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);
@@ -2413,6 +2458,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
struct mtk_dp *mtk_dp = platform_get_drvdata(pdev);
mtk_dp_video_mute(mtk_dp, true);
+ del_timer_sync(&mtk_dp->debounce_timer);
pm_runtime_disable(&pdev->dev);