mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v9] drm/bridge: it6505: This patch fixes hibernate to resume no display issue
@ 2024-05-17  2:16 kuro
  2024-05-17 10:37 ` AngeloGioacchino Del Regno
  2024-05-17 18:30 ` Markus Elfring
  0 siblings, 2 replies; 3+ messages in thread
From: kuro @ 2024-05-17  2:16 UTC (permalink / raw)
  To: Pin-yen Lin, Kuro Chung, Kenneth Haung, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter,
	AngeloGioacchino Del Regno, Hermes Wu, Allen Chen,
	open list:DRM DRIVERS, open list

From: Kuro Chung <kuro.chung@ite.com.tw>

This patch added a FIFO reset bit for input video. When system power resume,
the TTL input of it6505 may get some noise before video signal stable
and the hardware function reset is required.
But the input FIFO reset will also trigger error interrupts of output 
module rising.Thus, it6505 have to wait a period can clear those 
expected error interrupts caused by manual hardware reset in one 
interrupt handler calling to avoid interrupt looping.

Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver")

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

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index 469157341f3ab..5703fcf4b7b00 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);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v9] drm/bridge: it6505: This patch fixes hibernate to resume no display issue
  2024-05-17  2:16 [PATCH v9] drm/bridge: it6505: This patch fixes hibernate to resume no display issue kuro
@ 2024-05-17 10:37 ` AngeloGioacchino Del Regno
  2024-05-17 18:30 ` Markus Elfring
  1 sibling, 0 replies; 3+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-05-17 10:37 UTC (permalink / raw)
  To: kuro, Pin-yen Lin, Kenneth Haung, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Hermes Wu, Allen Chen,
	open list:DRM DRIVERS, open list

Il 17/05/24 04:16, kuro ha scritto:
> From: Kuro Chung <kuro.chung@ite.com.tw>
> 
> This patch added a FIFO reset bit for input video. When system power resume,
> the TTL input of it6505 may get some noise before video signal stable
> and the hardware function reset is required.
> But the input FIFO reset will also trigger error interrupts of output
> module rising.Thus, it6505 have to wait a period can clear those
> expected error interrupts caused by manual hardware reset in one
> interrupt handler calling to avoid interrupt looping.
> 
> Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver")
> 

Your Signed-off-by tag is missing.

Regards,
Angelo

> ---
>   drivers/gpu/drm/bridge/ite-it6505.c | 73 +++++++++++++++++++----------
>   1 file changed, 49 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
> index 469157341f3ab..5703fcf4b7b00 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);



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v9] drm/bridge: it6505: This patch fixes hibernate to resume no display issue
  2024-05-17  2:16 [PATCH v9] drm/bridge: it6505: This patch fixes hibernate to resume no display issue kuro
  2024-05-17 10:37 ` AngeloGioacchino Del Regno
@ 2024-05-17 18:30 ` Markus Elfring
  1 sibling, 0 replies; 3+ messages in thread
From: Markus Elfring @ 2024-05-17 18:30 UTC (permalink / raw)
  To: Kuro Chung, dri-devel, kernel-janitors
  Cc: LKML, Andrzej Hajda, Angelo Gioacchino Del Regno, Allen Chen,
	Daniel Vetter, David Airlie, Jernej Skrabec, Jonas Karlman,
	Kenneth Haung, Kuro Chung, Laurent Pinchart, Maarten Lankhorst,
	Maxime Ripard, Neil Armstrong, Pin-yen Lin, Robert Foss,
	Thomas Zimmermann

Please omit the word combination “This patch” from the summary phrase.


…
> But the input FIFO reset will also trigger error interrupts of output
> module rising.Thus, it6505 have to wait a period can clear those
> expected error interrupts caused by manual hardware reset in one
> interrupt handler calling to avoid interrupt looping.

Please improve this change description another bit.


…
> ---
>  drivers/gpu/drm/bridge/ite-it6505.c | 73 +++++++++++++++++++----------
…

You may present version descriptions behind the marker line.

Regards,
Markus

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-05-17 18:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-17  2:16 [PATCH v9] drm/bridge: it6505: This patch fixes hibernate to resume no display issue kuro
2024-05-17 10:37 ` AngeloGioacchino Del Regno
2024-05-17 18:30 ` Markus Elfring

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®