* [PATCH v11] drm/bridge: it6505: fix hibernate to resume no display issue
@ 2024-05-20 7:04 kuro
2024-05-20 13:12 ` Markus Elfring
0 siblings, 1 reply; 2+ messages in thread
From: kuro @ 2024-05-20 7:04 UTC (permalink / raw)
To: 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, AngeloGioacchino Del Regno,
Allen Chen, Hermes Wu, open list:DRM DRIVERS, open list
Cc: Kuro Chung
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 has been 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.
Signed-off-by: Kuro Chung <kuro.chung@ite.com.tw>
Signed-off-by: Hermes Wu <hermes.wu@ite.com.tw>
Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver")
---
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
---
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] 2+ messages in thread
* Re: [PATCH v11] drm/bridge: it6505: fix hibernate to resume no display issue
2024-05-20 7:04 [PATCH v11] drm/bridge: it6505: fix hibernate to resume no display issue kuro
@ 2024-05-20 13:12 ` Markus Elfring
0 siblings, 0 replies; 2+ messages in thread
From: Markus Elfring @ 2024-05-20 13:12 UTC (permalink / raw)
To: Kuro Chung, Hermes Wu, dri-devel, kernel-janitors
Cc: LKML, Andrzej Hajda, Angelo Gioacchino Del Regno, Allen Chen,
Daniel Vetter, David Airlie, Jernej Skrabec, Jonas Karlman,
Kenneth Haung, Laurent Pinchart, Maarten Lankhorst,
Maxime Ripard, Neil Armstrong, Pin-yen Lin, Robert Foss,
Thomas Zimmermann
> … This patch has been implemented to prevent …
Under which circumstances will imperative wordings be applied for
another improved change description?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.9#n94
Regards,
Markus
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-05-20 13:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-20 7:04 [PATCH v11] drm/bridge: it6505: fix hibernate to resume no display issue kuro
2024-05-20 13:12 ` 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®