At present, we have found that there may be a problem of blurred
screen during fast sleep/resume. The direct cause of the blurred
screen is that the IC does not receive 0x28/0x10. Because of the
particularity of the IC, before the panel enters sleep hid must
stop scanning, i2c_hid_core_suspend before ili9882t_disable.
This doesn't look very spec-compliant. So in order to solve this
problem, the IC can handle it through the exception mechanism when
it cannot receive 0X28/0X10 command. Handling exceptions requires a reset
50ms delay. Refer to vendor detailed analysis [1].

Ilitek vendor also suggested switching the page before entering sleep to
avoid panel IC not receiving 0x28/0x10 command.

Note: 0x28 is display off, 0x10 is sleep in.

[1]: https://github.com/ILITEK-LoganLin/Document/tree/main/ILITEK_Power_Sequence

Signed-off-by: Cong Yang <yangco...@huaqin.corp-partner.google.com>
---
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 22 ++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index e095ad91c4bc..20ae370ebe2f 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -465,6 +465,24 @@ static int ili9882t_init_dcs_cmd(struct ili9882t *ili)
        return 0;
 }
 
+static int ili9882t_switch_page(struct mipi_dsi_device *dsi, u8 page)
+{
+       int ret;
+       const struct panel_init_cmd cmd = _INIT_SWITCH_PAGE_CMD(page);
+
+       ret = mipi_dsi_dcs_write(dsi, cmd.data[0],
+                                cmd.len <= 1 ? NULL :
+                                &cmd.data[1],
+                                cmd.len - 1);
+       if (ret) {
+               dev_err(&dsi->dev,
+                       "error switching panel controller page (%d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
 static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
 {
        struct mipi_dsi_device *dsi = ili->dsi;
@@ -486,8 +504,10 @@ static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
 static int ili9882t_disable(struct drm_panel *panel)
 {
        struct ili9882t *ili = to_ili9882t(panel);
+       struct mipi_dsi_device *dsi = ili->dsi;
        int ret;
 
+       ili9882t_switch_page(dsi, 0x00);
        ret = ili9882t_enter_sleep_mode(ili);
        if (ret < 0) {
                dev_err(panel->dev, "failed to set panel off: %d\n", ret);
@@ -548,7 +568,7 @@ static int ili9882t_prepare(struct drm_panel *panel)
        gpiod_set_value(ili->enable_gpio, 1);
        usleep_range(1000, 2000);
        gpiod_set_value(ili->enable_gpio, 0);
-       usleep_range(1000, 2000);
+       usleep_range(40000, 50000);
        gpiod_set_value(ili->enable_gpio, 1);
        usleep_range(6000, 10000);
 
-- 
2.25.1

Reply via email to