diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index c205f37da1e12b11c384670db83e43613e031340..ccbfe084d6ffbcf9b5599a9234347f4a7bb6c3e1 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -99,25 +99,25 @@ sink_supports_format_bpc(const struct drm_connector *connector,
 	 * VIC1), the bpc must be 8.
 	 */
 	if (vic == 1 && bpc != 8) {
-		drm_dbg_kms(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
+		drm_info(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
 		return false;
 	}
 
 	if (!info->is_hdmi &&
 	    (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
-		drm_dbg_kms(dev, "DVI Monitors require an RGB output at 8 bpc\n");
+		drm_info(dev, "DVI Monitors require an RGB output at 8 bpc\n");
 		return false;
 	}
 
 	if (!(connector->hdmi.supported_formats & BIT(format))) {
-		drm_dbg_kms(dev, "%s format unsupported by the connector.\n",
+		drm_info(dev, "%s format unsupported by the connector.\n",
 			    drm_hdmi_connector_get_output_format_name(format));
 		return false;
 	}
 
 	switch (format) {
 	case HDMI_COLORSPACE_RGB:
-		drm_dbg_kms(dev, "RGB Format, checking the constraints.\n");
+		drm_info(dev, "RGB Format, checking the constraints.\n");
 
 		/*
 		 * In some cases, like when the EDID readout fails, or
@@ -127,38 +127,40 @@ sink_supports_format_bpc(const struct drm_connector *connector,
 		 * supported so we can keep things going and light up
 		 * the display.
 		 */
-		if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
+		if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444)) {
 			drm_warn(dev, "HDMI Sink doesn't support RGB, something's wrong.\n");
+			return false;
+		}
 
 		if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
-			drm_dbg_kms(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
+			drm_info(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
 			return false;
 		}
 
 		if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
-			drm_dbg_kms(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
+			drm_info(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
 			return false;
 		}
 
-		drm_dbg_kms(dev, "RGB format supported in that configuration.\n");
+		drm_info(dev, "RGB format supported in that configuration.\n");
 
 		return true;
 
 	case HDMI_COLORSPACE_YUV420:
 		/* TODO: YUV420 is unsupported at the moment. */
-		drm_dbg_kms(dev, "YUV420 format isn't supported yet.\n");
+		drm_info(dev, "YUV420 format isn't supported yet.\n");
 		return false;
 
 	case HDMI_COLORSPACE_YUV422:
-		drm_dbg_kms(dev, "YUV422 format, checking the constraints.\n");
+		drm_info(dev, "YUV422 format, checking the constraints.\n");
 
 		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
-			drm_dbg_kms(dev, "Sink doesn't support YUV422.\n");
+			drm_info(dev, "Sink doesn't support YUV422.\n");
 			return false;
 		}
 
 		if (bpc > 12) {
-			drm_dbg_kms(dev, "YUV422 only supports 12 bpc or lower.\n");
+			drm_info(dev, "YUV422 only supports 12 bpc or lower.\n");
 			return false;
 		}
 
@@ -168,34 +170,34 @@ sink_supports_format_bpc(const struct drm_connector *connector,
 		 * don't need to check the Deep Color bits in the EDIDs here.
 		 */
 
-		drm_dbg_kms(dev, "YUV422 format supported in that configuration.\n");
+		drm_info(dev, "YUV422 format supported in that configuration.\n");
 
 		return true;
 
 	case HDMI_COLORSPACE_YUV444:
-		drm_dbg_kms(dev, "YUV444 format, checking the constraints.\n");
+		drm_info(dev, "YUV444 format, checking the constraints.\n");
 
 		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
-			drm_dbg_kms(dev, "Sink doesn't support YUV444.\n");
+			drm_info(dev, "Sink doesn't support YUV444.\n");
 			return false;
 		}
 
 		if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {
-			drm_dbg_kms(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
+			drm_info(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
 			return false;
 		}
 
 		if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {
-			drm_dbg_kms(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
+			drm_info(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
 			return false;
 		}
 
-		drm_dbg_kms(dev, "YUV444 format supported in that configuration.\n");
+		drm_info(dev, "YUV444 format supported in that configuration.\n");
 
 		return true;
 	}
 
-	drm_dbg_kms(dev, "Unsupported pixel format.\n");
+	drm_info(dev, "Unsupported pixel format.\n");
 	return false;
 }
 
@@ -253,11 +255,11 @@ hdmi_try_format_bpc(const struct drm_connector *connector,
 	struct drm_device *dev = connector->dev;
 	int ret;
 
-	drm_dbg_kms(dev, "Trying %s output format\n",
+	drm_info(dev, "Trying %s output format\n",
 		    drm_hdmi_connector_get_output_format_name(fmt));
 
 	if (!sink_supports_format_bpc(connector, info, mode, fmt, bpc)) {
-		drm_dbg_kms(dev, "%s output format not supported with %u bpc\n",
+		drm_info(dev, "%s output format not supported with %u bpc\n",
 			    drm_hdmi_connector_get_output_format_name(fmt),
 			    bpc);
 		return false;
@@ -265,13 +267,13 @@ hdmi_try_format_bpc(const struct drm_connector *connector,
 
 	ret = hdmi_compute_clock(connector, conn_state, mode, bpc, fmt);
 	if (ret) {
-		drm_dbg_kms(dev, "Couldn't compute clock for %s output format and %u bpc\n",
+		drm_info(dev, "Couldn't compute clock for %s output format and %u bpc\n",
 			    drm_hdmi_connector_get_output_format_name(fmt),
 			    bpc);
 		return false;
 	}
 
-	drm_dbg_kms(dev, "%s output format supported with %u (TMDS char rate: %llu Hz)\n",
+	drm_info(dev, "%s output format supported with %u (TMDS char rate: %llu Hz)\n",
 		    drm_hdmi_connector_get_output_format_name(fmt),
 		    bpc, conn_state->hdmi.tmds_char_rate);
 
@@ -295,7 +297,7 @@ hdmi_compute_format(const struct drm_connector *connector,
 		return 0;
 	}
 
-	drm_dbg_kms(dev, "Failed. No Format Supported for that bpc count.\n");
+	drm_info(dev, "Failed. No Format Supported for that bpc count.\n");
 
 	return -EINVAL;
 }
@@ -313,7 +315,7 @@ hdmi_compute_config(const struct drm_connector *connector,
 	int ret;
 
 	for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
-		drm_dbg_kms(dev, "Trying with a %d bpc output\n", bpc);
+		drm_info(dev, "Trying with a %d bpc output\n", bpc);
 
 		ret = hdmi_compute_format(connector, conn_state, mode, bpc);
 		if (ret)
@@ -321,7 +323,7 @@ hdmi_compute_config(const struct drm_connector *connector,
 
 		conn_state->hdmi.output_bpc = bpc;
 
-		drm_dbg_kms(dev,
+		drm_info(dev,
 			    "Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
 			    mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
 			    conn_state->hdmi.output_bpc,
@@ -561,16 +563,16 @@ static int clear_device_infoframe(struct drm_connector *connector,
 	struct drm_device *dev = connector->dev;
 	int ret;
 
-	drm_dbg_kms(dev, "Clearing infoframe type 0x%x\n", type);
+	drm_info(dev, "Clearing infoframe type 0x%x\n", type);
 
 	if (!funcs || !funcs->clear_infoframe) {
-		drm_dbg_kms(dev, "Function not implemented, bailing.\n");
+		drm_info(dev, "Function not implemented, bailing.\n");
 		return 0;
 	}
 
 	ret = funcs->clear_infoframe(connector, type);
 	if (ret) {
-		drm_dbg_kms(dev, "Call failed: %d\n", ret);
+		drm_info(dev, "Call failed: %d\n", ret);
 		return ret;
 	}
 
@@ -598,10 +600,10 @@ static int write_device_infoframe(struct drm_connector *connector,
 	int ret;
 	int len;
 
-	drm_dbg_kms(dev, "Writing infoframe type %x\n", frame->any.type);
+	drm_info(dev, "Writing infoframe type %x\n", frame->any.type);
 
 	if (!funcs || !funcs->write_infoframe) {
-		drm_dbg_kms(dev, "Function not implemented, bailing.\n");
+		drm_info(dev, "Function not implemented, bailing.\n");
 		return -EINVAL;
 	}
 
@@ -611,7 +613,7 @@ static int write_device_infoframe(struct drm_connector *connector,
 
 	ret = funcs->write_infoframe(connector, frame->any.type, buffer, len);
 	if (ret) {
-		drm_dbg_kms(dev, "Call failed: %d\n", ret);
+		drm_info(dev, "Call failed: %d\n", ret);
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 00a638a3caf4f2e7242ecb07fd399887fbaa99c5..a6f7315e059cf7a0b38211ef5b5530899394df65 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -422,6 +422,8 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
 	hdmi->bridge.product = "On-Chip HDMI";
 	hdmi->bridge.interlace_allowed = ver_conf->interlace_allowed;
 
+	hdmi->bridge.supported_formats = BIT(HDMI_COLORSPACE_RGB) | BIT(HDMI_COLORSPACE_YUV444);
+
 	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
 	if (ret)
 		return dev_err_ptr_probe(dev, ret, "Failed to add bridge\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
index b411282d33e6fb249163e6245251141858ec69b1..1c798ee42597c6e9294e834f79c62ba72a41c642 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
@@ -29,6 +29,7 @@
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
 #include <drm/display/drm_scdc_helper.h>
+#include <drm/drm_drv.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
@@ -259,22 +260,21 @@ static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi)
 	return 0;
 }
 
-static inline void mtk_hdmi_v2_hw_reset_av_mute_regs(struct mtk_hdmi *hdmi)
-{
-	/* GCP packet */
-	regmap_clear_bits(hdmi->regs, TOP_CFG01, CP_CLR_MUTE_EN | CP_SET_MUTE_EN);
-	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, CP_RPT_EN);
-	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, CP_EN | CP_EN_WR);
-}
-
 static inline void mtk_hdmi_v2_hw_gcp_avmute(struct mtk_hdmi *hdmi, bool mute)
 {
-	mtk_hdmi_v2_hw_reset_av_mute_regs(hdmi);
+	u32 val;
 
-	if (mute)
-		regmap_set_bits(hdmi->regs, TOP_CFG01, CP_SET_MUTE_EN);
-	else
-		regmap_set_bits(hdmi->regs, TOP_CFG01, CP_CLR_MUTE_EN);
+	regmap_read(hdmi->regs, TOP_CFG01, &val);
+	val &= ~(CP_CLR_MUTE_EN | CP_SET_MUTE_EN);
+
+	if (mute) {
+		val |= CP_SET_MUTE_EN;
+		val &= ~CP_CLR_MUTE_EN;
+	} else {
+		val |= CP_CLR_MUTE_EN;
+		val &= ~CP_SET_MUTE_EN;
+	}
+	regmap_write(hdmi->regs, TOP_CFG01, val);
 
 	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, CP_RPT_EN);
 	regmap_set_bits(hdmi->regs, TOP_INFO_EN, CP_EN | CP_EN_WR);
@@ -686,7 +686,10 @@ static void mtk_hdmi_v2_change_video_resolution(struct mtk_hdmi *hdmi)
 
 	regmap_write(hdmi->regs, HDCP_TOP_CTRL, 0);
 
-	/* Enable HDCP reauthentication interrupt */
+	/*
+	 * Enable HDCP reauthentication interrupt: the HW uses this internally
+	 * for the HPD state machine even if HDCP encryption is not enabled.
+	 */
 	regmap_set_bits(hdmi->regs, TOP_INT_ENABLE00, HDCP2X_RX_REAUTH_REQ_DDCM_INT);
 
 	/* Enable hotplug and pord interrupts */
@@ -781,14 +784,32 @@ static void mtk_hdmi_v2_clk_disable(struct mtk_hdmi *hdmi)
 	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
 }
 
-static void mtk_hdmi_hpd_event(enum hdmi_hpd_state hpd, struct device *dev)
+static int mtk_hdmi_v2_reset_link(struct drm_bridge *bridge)
 {
-	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	struct drm_encoder *encoder = bridge->encoder;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct drm_device *dev = encoder->dev;
+	struct drm_modeset_acquire_ctx ctx;
+	int ret;
+
+	/* No crtc attached means no outputs to reset, don't do anything! */
+	if (!crtc) {
+		pr_err("NO CRTC NO RESET :-)\n");
+		return 0;
+	}
 
-	if (hdmi && hdmi->bridge.encoder && hdmi->bridge.encoder->dev)
-		drm_helper_hpd_irq_event(hdmi->bridge.encoder->dev);
+pr_err("HDMI RESET LINK\n");
+
+	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
+
+	ret = drm_atomic_helper_reset_crtc(crtc, &ctx);
+
+	DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
+
+	return ret;
 }
 
+
 static enum hdmi_hpd_state mtk_hdmi_v2_hpd_pord_status(struct mtk_hdmi *hdmi)
 {
 	u8 hpd_pin_sta, pord_pin_sta;
@@ -798,6 +819,21 @@ static enum hdmi_hpd_state mtk_hdmi_v2_hpd_pord_status(struct mtk_hdmi *hdmi)
 	hpd_pin_sta = FIELD_GET(HPD_PIN_STA, hpd_status);
 	pord_pin_sta = FIELD_GET(PORD_PIN_STA, hpd_status);
 
+	/*
+	 * Inform that the cable is plugged in (hpd_pin_sta) so that the
+	 * sink can be powered on by switching the 5V VBUS as required by
+	 * the HDMI spec for reading EDID and for HDMI Audio registers to
+	 * be accessible.
+	 *
+	 * PORD detection succeeds only when the cable is plugged in and
+	 * the sink is powered on: reaching that state means that the
+	 * communication with the sink can be started.
+	 *
+	 * Please note that when the cable is plugged out the HPD pin will
+	 * be the first one to fall, while PORD may still be in rise state
+	 * for a few more milliseconds, so we decide HDMI_PLUG_OUT without
+	 * checking PORD at all (we check only HPD falling for that).
+	 */
 	if (hpd_pin_sta && pord_pin_sta)
 		return HDMI_PLUG_IN_AND_SINK_POWER_ON;
 	else if (hpd_pin_sta)
@@ -814,22 +850,19 @@ static irqreturn_t mtk_hdmi_v2_isr(int irq, void *arg)
 
 	regmap_read(hdmi->regs, TOP_INT_STA00, &irq_sta);
 
-	/* Handle Hotplug Detection interrupt */
-	if (irq_sta & (HTPLG_R_INT | HTPLG_F_INT | PORD_F_INT | PORD_R_INT)) {
+	/* Handle Hotplug Detection interrupts */
+	if (irq_sta & HPD_PORD_HWIRQS) {
+		/*
+		 * Disable the HPD/PORD IRQs now and until thread done to
+		 * avoid interrupt storm that could happen with bad cables
+		 */
 		mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, false);
 		ret = IRQ_WAKE_THREAD;
-	}
-
-	/*
-	 * Clear all 32 + 19 interrupts in CLR00 and CLR01: this is important
-	 * to avoid unwanted retriggering of any interrupts
-	 */
-	regmap_write(hdmi->regs, TOP_INT_CLR00, GENMASK(31, 0));
-	regmap_write(hdmi->regs, TOP_INT_CLR01, GENMASK(18, 0));
 
-	/* Restore interrupt clearing registers to zero */
-	regmap_write(hdmi->regs, TOP_INT_CLR00, 0);
-	regmap_write(hdmi->regs, TOP_INT_CLR01, 0);
+		/* Clear HPD/PORD irqs to avoid unwanted retriggering */
+		regmap_write(hdmi->regs, TOP_INT_CLR00, HPD_PORD_HWIRQS);
+		regmap_write(hdmi->regs, TOP_INT_CLR00, 0);;
+	}
 
 	return ret;
 }
@@ -840,8 +873,12 @@ static irqreturn_t __mtk_hdmi_v2_isr_thread(struct mtk_hdmi *hdmi)
 
 	hpd = mtk_hdmi_v2_hpd_pord_status(hdmi);
 	if (hpd != hdmi->hpd) {
+		struct drm_encoder *encoder = hdmi->bridge.encoder;
+
 		hdmi->hpd = hpd;
-		mtk_hdmi_hpd_event(hpd, hdmi->dev);
+
+		if (encoder && encoder->dev)
+			drm_helper_hpd_irq_event(hdmi->bridge.encoder->dev);
 	}
 
 	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
@@ -1049,10 +1086,38 @@ static void mtk_hdmi_v2_bridge_post_disable(struct drm_bridge *bridge,
 	mtk_hdmi_v2_disable(hdmi);
 }
 
+
+static void mtk_hdmi_v2_hpd_notify(struct drm_bridge *bridge,
+				   enum drm_connector_status status)
+{
+	//struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+//	if (status == connector_status_connected)
+//		mtk_hdmi_v2_reset_link(bridge);
+
+	return;
+}
+
 static enum drm_connector_status mtk_hdmi_v2_bridge_detect(struct drm_bridge *bridge)
 {
 	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
 
+	switch (hdmi->hpd) {
+	default:
+	case HDMI_PLUG_IN_ONLY:
+pr_err("UNKNOWN CONNECTOR STATUS\n");
+		//return connector_status_unknown;
+		return connector_status_disconnected;
+	case HDMI_PLUG_OUT:
+pr_err("PLUGOUT CONNECTOR STATUS\n");
+		return connector_status_disconnected;
+	case HDMI_PLUG_IN_AND_SINK_POWER_ON:
+pr_err("PLUGIN SINK POWERON CONNECTOR STATUS\n");
+		return connector_status_connected;
+	}
+
+
+
 	return hdmi->hpd != HDMI_PLUG_OUT ?
 	       connector_status_connected : connector_status_disconnected;
 }
@@ -1293,6 +1358,7 @@ static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = {
 	.edid_read = mtk_hdmi_v2_bridge_edid_read,
 	.hpd_enable = mtk_hdmi_v2_hpd_enable,
 	.hpd_disable = mtk_hdmi_v2_hpd_disable,
+	.hpd_notify = mtk_hdmi_v2_hpd_notify,
 	.hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid,
 	.hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe,
 	.hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe,
@@ -1420,13 +1486,26 @@ static int mtk_hdmi_v2_probe(struct platform_device *pdev)
 
 	hdmi->hpd = HDMI_PLUG_OUT;
 
+	/* Disable all HW interrupts at probe stage */
+	mtk_hdmi_v2_hwirq_disable(hdmi);
+
 	/*
-	 * Disable all HW interrupts at probe stage and install the ISR
-	 * but keep it disabled, as the rest of the interrupts setup is
-	 * done in the .bridge_attach() callback, which will enable both
-	 * the right HW IRQs and the ISR.
+	 * In case bootloader leaves HDMI enabled before booting, make
+	 * sure that any interrupt that was left is cleared by setting
+	 * all bits in the INT_CLR registers for all 32+19 interrupts.
+	 */
+	regmap_write(hdmi->regs, TOP_INT_CLR00, GENMASK(31, 0));
+	regmap_write(hdmi->regs, TOP_INT_CLR01, GENMASK(18, 0));
+
+	/* Restore interrupt clearing registers to zero */
+	regmap_write(hdmi->regs, TOP_INT_CLR00, 0);
+	regmap_write(hdmi->regs, TOP_INT_CLR01, 0);
+
+	/*
+	 * Install the ISR but keep it disabled: as the interrupts are
+	 * being set up in the .bridge_attach() callback which will
+	 * enable both the right HW IRQs and the ISR.
 	 */
-	mtk_hdmi_v2_hwirq_disable(hdmi);
 	irq_set_status_flags(hdmi->irq, IRQ_NOAUTOEN);
 	ret = devm_request_threaded_irq(&pdev->dev, hdmi->irq, mtk_hdmi_v2_isr,
 					mtk_hdmi_v2_isr_thread,