[PATCH v3 0/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-03-05 Thread kuro
New patch description for v3 patch 

update upstream MAINTAINERS mail list

New patch description for v2 patch

Missing declaration for i variable in function 
it6505_irq_video_error_handler
, add it by this patch

Origianl description for v1 patch 

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

ITE 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.


allen (1):
  drm/bridge: it6505: fix hibernate to resume no display issue

 drivers/gpu/drm/bridge/ite-it6505.c | 54 -
 1 file changed, 45 insertions(+), 9 deletions(-)

-- 
2.25.1



[PATCH v3 1/1] UPSTREAM: drm/bridge: it6505: fix hibernate to resume no display issue

2024-03-05 Thread kuro
From: kuro chung 

ITE 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.

Signed-off-by: Allen Chen 
---
 drivers/gpu/drm/bridge/ite-it6505.c | 54 -
 1 file changed, 45 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index b53da9bb65a16..e592e14a48578 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1318,6 +1318,8 @@ static void it6505_video_reset(struct it6505 *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, 0x02);
+   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, 0x00);
@@ -2480,10 +2482,6 @@ static void it6505_irq_video_fifo_error(struct it6505 
*it6505)
struct device *dev = &it6505->client->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);
 }
 
 static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
@@ -2491,10 +2489,6 @@ static void it6505_irq_io_latch_fifo_overflow(struct 
it6505 *it6505)
struct device *dev = &it6505->client->dev;
 
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);
 }
 
 static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
@@ -2502,6 +2496,46 @@ static bool it6505_test_bit(unsigned int bit, const 
unsigned int *addr)
return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
 }
 
+static bool it6505_is_video_error_int(const int *int_status)
+{
+   if ((it6505_test_bit(BIT_INT_VID_FIFO_ERROR, (unsigned int 
*)int_status)) || (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW, (unsigned int 
*)int_status)))
+   return 1;
+   return 0;
+}
+
+static void it6505_irq_video_error_handler(struct it6505 *it6505)
+{
+   struct device *dev = &it6505->client->dev;
+   int int_status[3] = {0};
+   int reg_0d;
+   int i;
+
+   it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+   flush_work(&it6505->link_works);
+   it6505_stop_hdcp(it6505);
+   it6505_video_reset(it6505);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait video...");
+
+   for (i = 0; i < 10; i++) {
+   usleep_range(1, 11000);
+   int_status[2] = it6505_read(it6505, INT_STATUS_03);
+   reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+   it6505_write(it6505, INT_STATUS_03, int_status[2]);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", int_status[2]);
+   DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", reg_0d);
+
+   if ((reg_0d & VIDEO_STB) && (reg_0d >= 0))
+   break;
+
+   if (it6505_is_video_error_int(int_status)) {
+   it6505_video_reset(it6505);
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait video 
(%d)", i);
+   }
+   }
+}
+
 static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
 {
struct it6505 *it6505 = data;
@@ -2522,7 +2556,7 @@ static irqreturn_t it6505_int_threaded_handler(int 
unused, void *data)
{ 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;
+   int int_status[3], i, reg_0d;
 
if (it6505->enable_drv_hold || !it6505->powered)
return IRQ_HANDLED;
@@ -2550,6 +2584,8 @@ 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].h

[PATCH v4 0/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-03-08 Thread kuro
From: Kuro Chung 


New patch description for v4 patch

update by reviewer Pin-yen Lin comment, remove function 
it6505_irq_video_fifo_error/it6505_irq_io_latch_fifo_overflow
update by reviewer Pin-yen Lin comment, update Signed-off-by column

New patch description for v3 patch 

update upstream MAINTAINERS mail list

New patch description for v2 patch

Missing declaration for i variable in function 
it6505_irq_video_error_handler
, add it by this patch

Origianl description for v1 patch 

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

ITE 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.


allen (1):
  UPSTREAM: drm/bridge: it6505: fix hibernate to resume no display issue

 drivers/gpu/drm/bridge/ite-it6505.c | 50 -
 1 file changed, 35 insertions(+), 15 deletions(-)

-- 
2.25.1



[PATCH v4 1/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-03-08 Thread kuro
From: Kuro 

ITE 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.

Signed-off-by: Kuro Chung 

---
 drivers/gpu/drm/bridge/ite-it6505.c | 50 -
 1 file changed, 35 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index b53da9bb65a16..eff888fe7c2e7 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1318,6 +1318,8 @@ static void it6505_video_reset(struct it6505 *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, 0x02);
+   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, 0x00);
@@ -2475,31 +2477,49 @@ 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->client->dev;
+   return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
+}
 
-   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);
+static bool it6505_is_video_error_int(const int *int_status)
+{
+   if ((it6505_test_bit(BIT_INT_VID_FIFO_ERROR, (unsigned int 
*)int_status)) || (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW, (unsigned int 
*)int_status)))
+   return 1;
+   return 0;
 }
 
-static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
+static void it6505_irq_video_error_handler(struct it6505 *it6505)
 {
struct device *dev = &it6505->client->dev;
+   int int_status[3] = {0};
+   int reg_0d;
+   int i;
 
-   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);
-}
 
-static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
-{
-   return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait video...");
+
+   for (i = 0; i < 10; i++) {
+   usleep_range(1, 11000);
+   int_status[2] = it6505_read(it6505, INT_STATUS_03);
+   reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+   it6505_write(it6505, INT_STATUS_03, int_status[2]);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", int_status[2]);
+   DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", reg_0d);
+
+   if ((reg_0d & VIDEO_STB) && (reg_0d >= 0))
+   break;
+
+   if (it6505_is_video_error_int(int_status)) {
+   it6505_video_reset(it6505);
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait video 
(%d)", i);
+   }
+   }
 }
 
 static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
@@ -2519,8 +2539,6 @@ static irqreturn_t it6505_int_threaded_handler(int 
unused, void *data)
{ 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;
 
@@ -2550,6 +2568,8 @@ 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);
}
+   if (it6505_is_video_error_int(int_status))
+   it6505_irq_video_error_handler(it6505);
}
 
pm_runtime_put_sync(dev);
-- 
2.25.1



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

2024-02-21 Thread kuro
From: kuro chung 

ITE 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.

Signed-off-by: Allen Chen 

BUG=None
TEST=None

---
 drivers/gpu/drm/bridge/ite-it6505.c | 53 -
 1 file changed, 44 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index b53da9bb65a16..86277968fab93 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1318,6 +1318,8 @@ static void it6505_video_reset(struct it6505 *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, 0x02);
+   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, 0x00);
@@ -2480,10 +2482,6 @@ static void it6505_irq_video_fifo_error(struct it6505 
*it6505)
struct device *dev = &it6505->client->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);
 }
 
 static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
@@ -2491,10 +2489,6 @@ static void it6505_irq_io_latch_fifo_overflow(struct 
it6505 *it6505)
struct device *dev = &it6505->client->dev;
 
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);
 }
 
 static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
@@ -2502,6 +2496,45 @@ static bool it6505_test_bit(unsigned int bit, const 
unsigned int *addr)
return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
 }
 
+static bool it6505_is_video_error_int(const int *int_status)
+{
+   if ((it6505_test_bit(BIT_INT_VID_FIFO_ERROR, (unsigned int 
*)int_status)) || (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW, (unsigned int 
*)int_status)))
+   return 1;
+   return 0;
+}
+
+static void it6505_irq_video_error_handler(struct it6505 *it6505)
+{
+   struct device *dev = &it6505->client->dev;
+   int int_status[3] = {0};
+   int reg_0d;
+
+   it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+   flush_work(&it6505->link_works);
+   it6505_stop_hdcp(it6505);
+   it6505_video_reset(it6505);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait video...");
+
+   for (i = 0; i < 10; i++) {
+   usleep_range(1, 11000);
+   int_status[2] = it6505_read(it6505, INT_STATUS_03);
+   reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+   it6505_write(it6505, INT_STATUS_03, int_status[2]);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", int_status[2]);
+   DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", reg_0d);
+
+   if ((reg_0d & VIDEO_STB) && (reg_0d >= 0))
+   break;
+
+   if (it6505_is_video_error_int(int_status)) {
+   it6505_video_reset(it6505);
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait video 
(%d)", i);
+   }
+   }
+}
+
 static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
 {
struct it6505 *it6505 = data;
@@ -2522,7 +2555,7 @@ static irqreturn_t it6505_int_threaded_handler(int 
unused, void *data)
{ 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;
+   int int_status[3], i, reg_0d;
 
if (it6505->enable_drv_hold || !it6505->powered)
return IRQ_HANDLED;
@@ -2550,6 +2583,8 @@ 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].h

[PATCH v2 0/1] drm/bridge: it6505: fix hibernate to resume no display issue patch v2

2024-03-03 Thread kuro
From: kuro chung 

New patch description for v2 patch

Missing declaration for i variable in function 
it6505_irq_video_error_handler
, add it by this patch

Origianl description for v1 patch 

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

ITE 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.

Signed-off-by: Allen Chen 
(cherry picked from commit Iaa3cd9da92a625496f579d87d0ab74ca9c4937c4)

allen (1):
  UPSTREAM: drm/bridge: it6505: fix hibernate to resume no display issue

 drivers/gpu/drm/bridge/ite-it6505.c | 54 -
 1 file changed, 45 insertions(+), 9 deletions(-)

-- 
2.25.1



[PATCH v2 1/1] UPSTREAM: drm/bridge: it6505: fix hibernate to resume no display issue

2024-03-03 Thread kuro
From: kuro chung 

ITE 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.

Signed-off-by: Allen Chen 
(cherry picked from commit Iaa3cd9da92a625496f579d87d0ab74ca9c4937c4)

BUG=None
TEST=None

Change-Id: Iaa3cd9da92a625496f579d87d0ab74ca9c4937c4
---
 drivers/gpu/drm/bridge/ite-it6505.c | 54 -
 1 file changed, 45 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index b53da9bb65a16..e592e14a48578 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1318,6 +1318,8 @@ static void it6505_video_reset(struct it6505 *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, 0x02);
+   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, 0x00);
@@ -2480,10 +2482,6 @@ static void it6505_irq_video_fifo_error(struct it6505 
*it6505)
struct device *dev = &it6505->client->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);
 }
 
 static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
@@ -2491,10 +2489,6 @@ static void it6505_irq_io_latch_fifo_overflow(struct 
it6505 *it6505)
struct device *dev = &it6505->client->dev;
 
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);
 }
 
 static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
@@ -2502,6 +2496,46 @@ static bool it6505_test_bit(unsigned int bit, const 
unsigned int *addr)
return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
 }
 
+static bool it6505_is_video_error_int(const int *int_status)
+{
+   if ((it6505_test_bit(BIT_INT_VID_FIFO_ERROR, (unsigned int 
*)int_status)) || (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW, (unsigned int 
*)int_status)))
+   return 1;
+   return 0;
+}
+
+static void it6505_irq_video_error_handler(struct it6505 *it6505)
+{
+   struct device *dev = &it6505->client->dev;
+   int int_status[3] = {0};
+   int reg_0d;
+   int i;
+
+   it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+   flush_work(&it6505->link_works);
+   it6505_stop_hdcp(it6505);
+   it6505_video_reset(it6505);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait video...");
+
+   for (i = 0; i < 10; i++) {
+   usleep_range(1, 11000);
+   int_status[2] = it6505_read(it6505, INT_STATUS_03);
+   reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+   it6505_write(it6505, INT_STATUS_03, int_status[2]);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", int_status[2]);
+   DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", reg_0d);
+
+   if ((reg_0d & VIDEO_STB) && (reg_0d >= 0))
+   break;
+
+   if (it6505_is_video_error_int(int_status)) {
+   it6505_video_reset(it6505);
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait video 
(%d)", i);
+   }
+   }
+}
+
 static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
 {
struct it6505 *it6505 = data;
@@ -2522,7 +2556,7 @@ static irqreturn_t it6505_int_threaded_handler(int 
unused, void *data)
{ 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;
+   int int_status[3], i, reg_0d;
 
if (it6505->enable_drv_hold || !it6505->powered)
return IRQ_HANDLED;
@@ -2550,6 +2584,8 @@ static irqreturn_t it6505_int_threaded_handler(int 
unused, void 

[PATCH v8 0/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-05-15 Thread kuro
From: Kuro 

New patch description for v8 patch 

resolve merge conflict

New patch description for v7 patch

modify code from
it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 0x02); to
it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 
TX_FIFO_RESET); for macro define

New patch description for v6 patch

remove the unrelated patch change (split into anoter patch)
remove extra line

New patch description for v5 patch

after customer feedback and test finished, update again, kernel build 
pass.

New patch description for v4 patch

update by reviewer Pin-yen Lin comment, remove function 
it6505_irq_video_fifo_error/it6505_irq_io_latch_fifo_overflow
update by reviewer Pin-yen Lin comment, update Signed-off-by column

New patch description for v3 patch

update upstream MAINTAINERS mail list

New patch description for v2 patch

Missing declaration for i variable in function 
it6505_irq_video_error_handler
, add it by this patch

Origianl description for v1 patch

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

ITE 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.


Kuro Chung (1):
  drm/bridge: it6505: fix hibernate to resume no display issue

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

-- 
2.25.1



[PATCH v8 1/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-05-15 Thread kuro
From: Kuro 

ITE 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.

Signed-off-by: Kuro Chung 

---
 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(1, 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 it

[PATCH v9] drm/bridge: it6505: This patch fixes hibernate to resume no display issue

2024-05-16 Thread kuro
From: Kuro Chung 

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(1, 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))
+ 

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

2024-05-17 Thread kuro
From: Kuro Chung 

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(1, 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))
+ 

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

2024-05-19 Thread kuro
From: Kuro Chung 

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 
Signed-off-by: Hermes Wu 
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(1, 11000);
+
+   /*
+* Clear FIFO error IRQ to prevent fifo error -> reset loop
+* HW will trigger SCDT change 

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

2024-05-21 Thread kuro
From: Kuro Chung 

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 
Signed-off-by: Hermes Wu 

---
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.

---
 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(1, 11000);
+
+   /*
+* Clear FIFO error IRQ to prevent fifo error -> reset loo

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

2024-05-21 Thread kuro
From: Kuro Chung 

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 
Signed-off-by: Hermes Wu 
---
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(-)

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(1, 11000);
+
+

[PATCH v5 0/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-04-19 Thread kuro
From: Kuro 


New patch description for v5 patch

after customer feedback and test finished, update again, kernel build 
pass.

New patch description for v4 patch

update by reviewer Pin-yen Lin comment, remove function 
it6505_irq_video_fifo_error/it6505_irq_io_latch_fifo_overflow
update by reviewer Pin-yen Lin comment, update Signed-off-by column

New patch description for v3 patch

update upstream MAINTAINERS mail list

New patch description for v2 patch

Missing declaration for i variable in function 
it6505_irq_video_error_handler
, add it by this patch

Origianl description for v1 patch

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

ITE 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.


allen (1):
  UPSTREAM: drm/bridge: it6505: fix hibernate to resume no display issue

 drivers/gpu/drm/bridge/ite-it6505.c | 181 +++-
 1 file changed, 124 insertions(+), 57 deletions(-)

-- 
2.25.1



[PATCH v5 1/1] UPSTREAM: drm/bridge: it6505: fix hibernate to resume no display issue

2024-04-19 Thread kuro
From: Kuro 

ITE 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.

Signed-off-by: Kuro Chung 

---
 drivers/gpu/drm/bridge/ite-it6505.c | 181 +++-
 1 file changed, 124 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index b53da9bb65a16..4fd693b4b68ca 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -802,8 +802,8 @@ static void it6505_int_mask_enable(struct it6505 *it6505)
 BIT(INT_RECEIVE_HPD_IRQ) | BIT(INT_SCDT_CHANGE) |
 BIT(INT_HDCP_FAIL) | BIT(INT_HDCP_DONE));
 
-   it6505_write(it6505, INT_MASK_02, BIT(INT_AUX_CMD_FAIL) |
-BIT(INT_HDCP_KSV_CHECK) | BIT(INT_AUDIO_FIFO_ERROR));
+   it6505_write(it6505, INT_MASK_02, BIT(INT_HDCP_KSV_CHECK) |
+BIT(INT_AUDIO_FIFO_ERROR));
 
it6505_write(it6505, INT_MASK_03, BIT(INT_LINK_TRAIN_FAIL) |
 BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW));
@@ -1317,10 +1317,17 @@ 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, 0x02);
+   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);
+
 }
 
 static void it6505_update_video_parameter(struct it6505 *it6505,
@@ -1861,16 +1868,29 @@ static void it6505_reset_hdcp(struct it6505 *it6505)
/* Disable CP_Desired */
it6505_set_bits(it6505, REG_HDCP_CTRL1, HDCP_CP_ENABLE, 0x00);
it6505_set_bits(it6505, REG_RESET_CTRL, HDCP_RESET, HDCP_RESET);
+   it6505_set_bits(it6505, REG_RESET_CTRL, HDCP_RESET, 0x00);
 }
 
 static void it6505_start_hdcp(struct it6505 *it6505)
 {
struct device *dev = &it6505->client->dev;
 
-   DRM_DEV_DEBUG_DRIVER(dev, "start");
-   it6505_reset_hdcp(it6505);
-   queue_delayed_work(system_wq, &it6505->hdcp_work,
-  msecs_to_jiffies(2400));
+   /*
+* If video not stable, no need turn on HDCP
+* After video stable
+* SCDT IRQ ->Link Training-> HDCP
+*/
+   if (it6505_get_video_status(it6505)) {
+   DRM_DEV_DEBUG_DRIVER(dev, "start");
+   it6505_reset_hdcp(it6505);
+
+   queue_delayed_work(system_wq, &it6505->hdcp_work,
+  msecs_to_jiffies(2400));
+
+   return;
+   }
+
+   DRM_DEV_DEBUG_DRIVER(dev, "Video not ready for HDCP");
 }
 
 static void it6505_stop_hdcp(struct it6505 *it6505)
@@ -2249,12 +2269,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)
@@ -2309,14 +2328,24 @@ static int it6505_process_hpd_irq(struct it6505 *it6505)
DRM_DEV_DEBUG_DRIVER(dev, "dp_irq_vector = 0x%02x", dp_irq_vector);
 
if (dp_irq_vector & DP_CP_IRQ) {
-   it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ,
-   HDCP_TRIGGER_CPIRQ);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "DP_CP_IRQ :hdcp_status = 0x%02x", 
it6505->hdcp_status);
+
+   /*
+* Some TYPE-C devces trigger CP_IRQ when system resume
+* And IT6505 HDCP is in idle state
+* No Need trigger 6505 HDCP control.
+*/
+   if (it6505->hdcp_status == HDCP_AUTH_GOING)
+   it6505_set_bits(it6505, REG_HDCP_TRIGGER, 
HDCP_TRIGGER_CPIRQ,
+   HDCP_TRIGGER_CPIRQ);
 

[PATCH v6 0/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-04-23 Thread kuro
From: Kuro 

New patch description for v6 patch

remove the unrelated patch change (split into anoter patch)
remove extra line

New patch description for v5 patch

after customer feedback and test finished, update again, kernel build 
pass.

New patch description for v4 patch

update by reviewer Pin-yen Lin comment, remove function 
it6505_irq_video_fifo_error/it6505_irq_io_latch_fifo_overflow
update by reviewer Pin-yen Lin comment, update Signed-off-by column

New patch description for v3 patch

update upstream MAINTAINERS mail list

New patch description for v2 patch

Missing declaration for i variable in function 
it6505_irq_video_error_handler
, add it by this patch

Origianl description for v1 patch

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

ITE 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.

allen (1):
  UPSTREAM: drm/bridge: it6505: fix hibernate to resume no display issue

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

-- 
2.25.1



[PATCH v6 1/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-04-23 Thread kuro
From: Kuro 

ITE 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.

Signed-off-by: Kuro Chung 

---
 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 b53da9bb65a16..ae7f4c7ec6dd0 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1317,9 +1317,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, 0x02);
+   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);
 }
 
@@ -2249,12 +2255,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)
@@ -2475,31 +2480,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->client->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->client->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(1, 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

[PATCH v7 0/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-05-06 Thread kuro
From: Kuro 

New patch description for v7 patch 

modify code from
it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 0x02); to 
it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 
TX_FIFO_RESET); for macro define

New patch description for v6 patch

remove the unrelated patch change (split into anoter patch)
remove extra line

New patch description for v5 patch

after customer feedback and test finished, update again, kernel build 
pass.

New patch description for v4 patch

update by reviewer Pin-yen Lin comment, remove function 
it6505_irq_video_fifo_error/it6505_irq_io_latch_fifo_overflow
update by reviewer Pin-yen Lin comment, update Signed-off-by column

New patch description for v3 patch

update upstream MAINTAINERS mail list

New patch description for v2 patch

Missing declaration for i variable in function 
it6505_irq_video_error_handler
, add it by this patch

Origianl description for v1 patch

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

ITE 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.


allen (1):
  UPSTREAM: drm/bridge: it6505: fix hibernate to resume no display issue

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

-- 
2.25.1



[PATCH v7 1/1] drm/bridge: it6505: fix hibernate to resume no display issue

2024-05-06 Thread kuro
From: Kuro 

ITE 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.

Signed-off-by: Kuro Chung 

---
 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 b53da9bb65a16..64e2706e3d0c3 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1317,9 +1317,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);
 }
 
@@ -2249,12 +2255,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)
@@ -2475,31 +2480,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->client->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->client->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(1, 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

[PATCH v1] drm/bridge: it6505: update usleep_range for RC circuit charge time

2024-06-03 Thread kuro
From: Kuro Chung 

The spec of timing between IVDD/OVDD and SYSRTEN is 10ms, but SYSRSTN RC
circuit need at least 25ms for rising time, update for match spec

Signed-off-by: Kuro Chung 
Signed-off-by: Hermes Wu 
---
 drivers/gpu/drm/bridge/ite-it6505.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index cd1b5057ddfb4..1e1c06fdf2064 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -2615,7 +2615,7 @@ static int it6505_poweron(struct it6505 *it6505)
gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
usleep_range(1000, 2000);
gpiod_set_value_cansleep(pdata->gpiod_reset, 1);
-   usleep_range(1, 2);
+   usleep_range(25000, 35000);
}
 
it6505->powered = true;
-- 
2.25.1



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

2024-02-06 Thread kuro chung
From: allen chen 

Change-Id: Iaa3cd9da92a625496f579d87d0ab74ca9c4937c4
---
 drivers/gpu/drm/bridge/ite-it6505.c | 42 ++---
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index b53da9bb65a1..07883001e6ca 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1318,6 +1318,8 @@ static void it6505_video_reset(struct it6505 *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, 0x02);
+   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, 0x00);
@@ -2480,10 +2482,6 @@ static void it6505_irq_video_fifo_error(struct it6505 
*it6505)
struct device *dev = &it6505->client->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);
 }
 
 static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
@@ -2491,10 +2489,6 @@ static void it6505_irq_io_latch_fifo_overflow(struct 
it6505 *it6505)
struct device *dev = &it6505->client->dev;
 
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);
 }
 
 static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
@@ -2522,7 +2516,7 @@ static irqreturn_t it6505_int_threaded_handler(int 
unused, void *data)
{ 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;
+   int int_status[3], i, reg_0d;
 
if (it6505->enable_drv_hold || !it6505->powered)
return IRQ_HANDLED;
@@ -2550,6 +2544,36 @@ 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);
}
+
+   if ((it6505_test_bit(irq_vec[9].bit, (unsigned int 
*)int_status)) ||
+   (it6505_test_bit(irq_vec[10].bit, (unsigned int 
*)int_status))) {
+   it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+   flush_work(&it6505->link_works);
+   it6505_stop_hdcp(it6505);
+   it6505_video_reset(it6505);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error reset wait 
video...");
+
+   for (i = 0; i < 10; i++) {
+   usleep_range(1, 11000);
+   int_status[2] = it6505_read(it6505, 
INT_STATUS_03);
+   reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+   it6505_write(it6505, INT_STATUS_03, 
int_status[2]);
+
+   DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", 
int_status[2]);
+   DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", 
reg_0d);
+   if ((reg_0d & VIDEO_STB) && (reg_0d >= 0))
+   break;
+
+   if ((it6505_test_bit(irq_vec[9].bit, (unsigned 
int *)int_status)) || (it6505_test_bit(irq_vec[10].bit, (unsigned int 
*)int_status))) {
+   it6505_video_reset(it6505);
+   DRM_DEV_DEBUG_DRIVER(dev, "Video Error 
reset wait video (%d)", i);
+   }
+
+   }
+
+   }
+
}
 
pm_runtime_put_sync(dev);
-- 
2.25.1