diff mbox series

[v13] drm/bridge: it6505: fix hibernate to resume no display issue

Message ID 20240522065528.1053439-1-kuro.chung@ite.com.tw (mailing list archive)
State Accepted
Headers show
Series [v13] drm/bridge: it6505: fix hibernate to resume no display issue | expand

Commit Message

kuro May 22, 2024, 6:55 a.m. UTC
From: Kuro Chung <kuro.chung@ite.com.tw>

When the system power resumes, the TTL input of IT6505 may experience
some noise before the video signal stabilizes, necessitating a video
reset. This patch is implemented to prevent a loop of video error
interrupts, which can occur when a video reset in the video FIFO error
interrupt triggers another such interrupt. The patch processes the SCDT
and FIFO error interrupts simultaneously and ignores any video FIFO
error interrupts caused by a video reset.

Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver")
Signed-off-by: Kuro Chung <kuro.chung@ite.com.tw>
Signed-off-by: Hermes Wu <hermes.wu@ite.com.tw>
---
V1->V3: update MAINTAINERS mail list
V3->V4: remove function it6505_irq_video_fifo_error,it6505_irq_io_latch_fifo_overflow
V4->V5: customer feedback again, update again, kernel build pass
V5->V6: remove unrelated patch change, split into another patch
V6->V7: modify code 0x02 to TX_FIFO_RESET by macro define
V7->V8: fix merge conflict, change mail from 'cc' to 'to'
V8->V9: modify patch description, patch summary
V9->V10: modify patch summary, add Fixes
V10->V11: modify patch description, add Signed-off-by
V11->V12: moidfy patch description.
V12->V13: fix code checkpatch.pl warning

---
 drivers/gpu/drm/bridge/ite-it6505.c | 73 +++++++++++++++++++----------
 1 file changed, 49 insertions(+), 24 deletions(-)

Comments

AngeloGioacchino Del Regno May 22, 2024, 7:13 a.m. UTC | #1
Il 22/05/24 08:55, kuro ha scritto:
> From: Kuro Chung <kuro.chung@ite.com.tw>
> 
> When the system power resumes, the TTL input of IT6505 may experience
> some noise before the video signal stabilizes, necessitating a video
> reset. This patch is implemented to prevent a loop of video error
> interrupts, which can occur when a video reset in the video FIFO error
> interrupt triggers another such interrupt. The patch processes the SCDT
> and FIFO error interrupts simultaneously and ignores any video FIFO
> error interrupts caused by a video reset.
> 
> Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver")
> Signed-off-by: Kuro Chung <kuro.chung@ite.com.tw>
> Signed-off-by: Hermes Wu <hermes.wu@ite.com.tw>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Robert Foss May 22, 2024, 12:13 p.m. UTC | #2
On Wed, 22 May 2024 14:55:28 +0800, kuro wrote:
> From: Kuro Chung <kuro.chung@ite.com.tw>
> 
> When the system power resumes, the TTL input of IT6505 may experience
> some noise before the video signal stabilizes, necessitating a video
> reset. This patch is implemented to prevent a loop of video error
> interrupts, which can occur when a video reset in the video FIFO error
> interrupt triggers another such interrupt. The patch processes the SCDT
> and FIFO error interrupts simultaneously and ignores any video FIFO
> error interrupts caused by a video reset.
> 
> [...]

Applied, thanks!

[1/1] drm/bridge: it6505: fix hibernate to resume no display issue
      https://cgit.freedesktop.org/drm/drm-misc/commit/?id=484436ec5c2b



Rob
kuro May 23, 2024, 2:20 a.m. UTC | #3
-----Original Message-----
From: Robert Foss <rfoss@kernel.org> 
Sent: Wednesday, May 22, 2024 8:13 PM
To: Maxime Ripard <mripard@kernel.org>; Thomas Zimmermann <tzimmermann@suse.de>; Jonas Karlman <jonas@kwiboo.se>; Daniel Vetter <daniel@ffwll.ch>; AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>; Allen Chen <allen.chen@ite.com.tw>; Neil Armstrong <neil.armstrong@linaro.org>; Laurent Pinchart <Laurent.pinchart@ideasonboard.com>; Maarten Lankhorst <maarten.lankhorst@linux.intel.com>; David Airlie <airlied@gmail.com>; Kuro Chung (鐘仕廷) <kuro.chung@ite.com.tw>; Kenneth Hung (洪家倫) <Kenneth.Hung@ite.com.tw>; open list:DRM DRIVERS <dri-devel@lists.freedesktop.org>; Pin-yen Lin <treapking@chromium.org>; Andrzej Hajda <andrzej.hajda@intel.com>; Jernej Skrabec <jernej.skrabec@gmail.com>; open list <linux-kernel@vger.kernel.org>; Hermes Wu (吳佳宏) <Hermes.Wu@ite.com.tw>
Subject: Re: [PATCH v13] drm/bridge: it6505: fix hibernate to resume no display issue

On Wed, 22 May 2024 14:55:28 +0800, kuro wrote:
> From: Kuro Chung <kuro.chung@ite.com.tw>
> 
> When the system power resumes, the TTL input of IT6505 may experience 
> some noise before the video signal stabilizes, necessitating a video 
> reset. This patch is implemented to prevent a loop of video error 
> interrupts, which can occur when a video reset in the video FIFO error 
> interrupt triggers another such interrupt. The patch processes the 
> SCDT and FIFO error interrupts simultaneously and ignores any video 
> FIFO error interrupts caused by a video reset.
> 
> [...]

Applied, thanks!
> thanks everyone for your help!, I really appreciate it.

[1/1] drm/bridge: it6505: fix hibernate to resume no display issue
      https://cgit.freedesktop.org/drm/drm-misc/commit/?id=484436ec5c2b



Rob
diff mbox series

Patch

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index 469157341f3ab..cd1b5057ddfb4 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1307,9 +1307,15 @@  static void it6505_video_reset(struct it6505 *it6505)
 	it6505_link_reset_step_train(it6505);
 	it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, EN_VID_MUTE);
 	it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_VID_CTRL_PKT, 0x00);
-	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET);
+
+	it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, TX_FIFO_RESET);
+	it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 0x00);
+
 	it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, RST_501_FIFO);
 	it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, 0x00);
+
+	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET);
+	usleep_range(1000, 2000);
 	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, 0x00);
 }
 
@@ -2245,12 +2251,11 @@  static void it6505_link_training_work(struct work_struct *work)
 	if (ret) {
 		it6505->auto_train_retry = AUTO_TRAIN_RETRY;
 		it6505_link_train_ok(it6505);
-		return;
 	} else {
 		it6505->auto_train_retry--;
+		it6505_dump(it6505);
 	}
 
-	it6505_dump(it6505);
 }
 
 static void it6505_plugged_status_to_codec(struct it6505 *it6505)
@@ -2471,31 +2476,53 @@  static void it6505_irq_link_train_fail(struct it6505 *it6505)
 	schedule_work(&it6505->link_works);
 }
 
-static void it6505_irq_video_fifo_error(struct it6505 *it6505)
+static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
 {
-	struct device *dev = it6505->dev;
-
-	DRM_DEV_DEBUG_DRIVER(dev, "video fifo overflow interrupt");
-	it6505->auto_train_retry = AUTO_TRAIN_RETRY;
-	flush_work(&it6505->link_works);
-	it6505_stop_hdcp(it6505);
-	it6505_video_reset(it6505);
+	return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
 }
 
-static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
+static void it6505_irq_video_handler(struct it6505 *it6505, const int *int_status)
 {
 	struct device *dev = it6505->dev;
+	int reg_0d, reg_int03;
 
-	DRM_DEV_DEBUG_DRIVER(dev, "IO latch fifo overflow interrupt");
-	it6505->auto_train_retry = AUTO_TRAIN_RETRY;
-	flush_work(&it6505->link_works);
-	it6505_stop_hdcp(it6505);
-	it6505_video_reset(it6505);
-}
+	/*
+	 * When video SCDT change with video not stable,
+	 * Or video FIFO error, need video reset
+	 */
 
-static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
-{
-	return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
+	if ((!it6505_get_video_status(it6505) &&
+	     (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *)int_status))) ||
+	    (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW,
+			     (unsigned int *)int_status)) ||
+	    (it6505_test_bit(BIT_INT_VID_FIFO_ERROR,
+			     (unsigned int *)int_status))) {
+		it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+		flush_work(&it6505->link_works);
+		it6505_stop_hdcp(it6505);
+		it6505_video_reset(it6505);
+
+		usleep_range(10000, 11000);
+
+		/*
+		 * Clear FIFO error IRQ to prevent fifo error -> reset loop
+		 * HW will trigger SCDT change IRQ again when video stable
+		 */
+
+		reg_int03 = it6505_read(it6505, INT_STATUS_03);
+		reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+
+		reg_int03 &= (BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW));
+		it6505_write(it6505, INT_STATUS_03, reg_int03);
+
+		DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", reg_int03);
+		DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", reg_0d);
+
+		return;
+	}
+
+	if (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *)int_status))
+		it6505_irq_scdt(it6505);
 }
 
 static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
@@ -2508,15 +2535,12 @@  static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
 	} irq_vec[] = {
 		{ BIT_INT_HPD, it6505_irq_hpd },
 		{ BIT_INT_HPD_IRQ, it6505_irq_hpd_irq },
-		{ BIT_INT_SCDT, it6505_irq_scdt },
 		{ BIT_INT_HDCP_FAIL, it6505_irq_hdcp_fail },
 		{ BIT_INT_HDCP_DONE, it6505_irq_hdcp_done },
 		{ BIT_INT_AUX_CMD_FAIL, it6505_irq_aux_cmd_fail },
 		{ BIT_INT_HDCP_KSV_CHECK, it6505_irq_hdcp_ksv_check },
 		{ BIT_INT_AUDIO_FIFO_ERROR, it6505_irq_audio_fifo_error },
 		{ BIT_INT_LINK_TRAIN_FAIL, it6505_irq_link_train_fail },
-		{ BIT_INT_VID_FIFO_ERROR, it6505_irq_video_fifo_error },
-		{ BIT_INT_IO_FIFO_OVERFLOW, it6505_irq_io_latch_fifo_overflow },
 	};
 	int int_status[3], i;
 
@@ -2546,6 +2570,7 @@  static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
 			if (it6505_test_bit(irq_vec[i].bit, (unsigned int *)int_status))
 				irq_vec[i].handler(it6505);
 		}
+		it6505_irq_video_handler(it6505, (unsigned int *)int_status);
 	}
 
 	pm_runtime_put_sync(dev);