[RAMEN9610-9310][Robusta2] fbdev: dev: DPU recovery when read timeout is occurred
authorhwangjae lee <hj-yo.lee@samsung.com>
Mon, 10 Dec 2018 01:18:49 +0000 (10:18 +0900)
committerxiest1 <xiest1@lenovo.com>
Tue, 5 Nov 2019 09:30:05 +0000 (17:30 +0800)
Change-Id: I2287eb166b7e1713b90208b5758a137a8f39b4d5
Signed-off-by: hwangjae lee <hj-yo.lee@samsung.com>
drivers/video/fbdev/exynos/dpu20/decon.h
drivers/video/fbdev/exynos/dpu20/decon_core.c
drivers/video/fbdev/exynos/dpu20/decon_dsi.c
drivers/video/fbdev/exynos/dpu20/dsim_drv.c
drivers/video/fbdev/exynos/dpu20/panels/hix83112a_mipi_lcd.c
drivers/video/fbdev/exynos/dpu20/panels/nov36672a_mipi_lcd.c
drivers/video/fbdev/exynos/dpu20/panels/s6e3fa0_mipi_lcd.c

index 6e40c07c573215b7a88637dbde085058a4ad94d5..91938c11c13a750cb09b73f6aa4c7794992c6a32 100644 (file)
@@ -966,6 +966,7 @@ struct decon_device {
 
        struct mutex lock;
        struct mutex pm_lock;
+       struct mutex rcv_lock; /* recovery lock */
        spinlock_t slock;
 #if defined(CONFIG_EXYNOS_READ_ESD_SOLUTION)
        struct decon_esd esd;
@@ -1421,6 +1422,7 @@ int dpu_pm_domain_check_status(struct exynos_pm_domain *pm_domain);
 int decon_set_out_sd_state(struct decon_device *decon, enum decon_state state);
 int decon_update_last_regs(struct decon_device *decon,
                struct decon_reg_data *regs);
+int decon_handle_recovery(struct decon_device *decon);
 
 int register_lcd_status_notifier(struct notifier_block *nb);
 int unregister_lcd_status_notifier(struct notifier_block *nb);
index 2463fc33d9d2005267ebd0ac019065acddd51dd5..3d8271455350db9331ddaac0a09529ab6ed31a71 100755 (executable)
@@ -4073,6 +4073,7 @@ static int decon_probe(struct platform_device *pdev)
 #if defined(CONFIG_EXYNOS_READ_ESD_SOLUTION)
        mutex_init(&decon->esd.lock);
 #endif
+       mutex_init(&decon->rcv_lock);
 
        decon_enter_shutdown_reset(decon);
 
index 3afffd9ff8605c80f4563749cd78c6309aa3cce6..62e8e6d087a01a735fab29ba239ce20f91751499 100755 (executable)
@@ -385,7 +385,7 @@ void decon_destroy_vsync_thread(struct decon_device *decon)
 
 #if defined(CONFIG_EXYNOS_READ_ESD_SOLUTION)
 #define ESD_RECOVERY_RETRY_CNT 5
-static int decon_handle_esd(struct decon_device *decon)
+int decon_handle_recovery(struct decon_device *decon)
 {
        struct dsim_device *dsim;
        int ret = 0;
@@ -399,6 +399,8 @@ static int decon_handle_esd(struct decon_device *decon)
                return -EINVAL;
        }
 
+       mutex_lock(&decon->rcv_lock);
+
        decon_bypass_on(decon);
        dsim = container_of(decon->out_sd[0], struct dsim_device, sd);
        dsim->esd_recovering = true;
@@ -460,6 +462,9 @@ static int decon_handle_esd(struct decon_device *decon)
                decon_set_bypass(decon, true);
 
        decon_bypass_off(decon);
+
+       mutex_unlock(&decon->rcv_lock);
+
        decon_info("%s -\n", __func__);
 
        return ret;
@@ -473,7 +478,7 @@ static void decon_esd_process(int esd, struct decon_device *decon)
        case DSIM_ESD_CHECK_ERROR:
                decon_err("%s, It is not ESD, \
                        but DDI is abnormal state(%d)\n", __func__, esd);
-               ret = decon_handle_esd(decon);
+               ret = decon_handle_recovery(decon);
                if (ret)
                        decon_err("%s, failed to recover ESD\n", __func__);
                break;
@@ -482,7 +487,7 @@ static void decon_esd_process(int esd, struct decon_device *decon)
                break;
        case DSIM_ESD_ERROR:
                decon_err("%s, ESD is detected(%d)\n", __func__, esd);
-               ret = decon_handle_esd(decon);
+               ret = decon_handle_recovery(decon);
                if (ret)
                        decon_err("%s, failed to recover ESD\n", __func__);
                break;
index db7fe6c84f43b086e1274fa86e9538d3befae002..8407e9548343b8e556fe5fbf8b5e42932fe4b354 100755 (executable)
@@ -275,6 +275,7 @@ int dsim_read_data(struct dsim_device *dsim, u32 id, u32 addr, u32 cnt, u8 *buf)
        u32 rx_fifo_depth = DSIM_RX_FIFO_MAX_DEPTH;
        struct decon_device *decon = get_decon_drvdata(0);
        struct dsim_regs regs;
+       int ret2 = 0;
 
        decon_hiber_block_exit(decon);
 
@@ -297,6 +298,12 @@ int dsim_read_data(struct dsim_device *dsim, u32 id, u32 addr, u32 cnt, u8 *buf)
        dsim_write_data(dsim, id, addr, 0);
        if (!wait_for_completion_timeout(&dsim->rd_comp, MIPI_RD_TIMEOUT)) {
                dsim_err("MIPI DSIM read Timeout!\n");
+               decon_handle_recovery(decon);
+               if (decon->esd.thread) {
+                       ret2 = wake_up_process(decon->esd.thread);
+                       dsim_info("%s:%d, wakeup esd thread(%d)\n", __func__,
+                                       __LINE__, ret2);
+               }
                return -ETIMEDOUT;
        }
 
@@ -1353,10 +1360,10 @@ static ssize_t dsim_cmd_sysfs_store(struct device *dev,
 
        switch (cmd) {
        case 1:
-               ret = dsim_cmd_sysfs_read(dsim);
 #if defined(CONFIG_EXYNOS_PANEL_INIT_LPDT)
        dsim_reg_set_cmd_transfer_mode(dsim->id, 1);
 #endif
+               ret = dsim_cmd_sysfs_read(dsim);
                call_panel_ops(dsim, dump, dsim);
 #if defined(CONFIG_EXYNOS_PANEL_INIT_LPDT)
        dsim_reg_set_cmd_transfer_mode(dsim->id, 0);
index 2578e9a01894097aec535f3e6f26a58b25089feb..ab7623e81755818d8962a8cff9f8746979b9f92a 100755 (executable)
@@ -547,7 +547,10 @@ static int hix83112a_read_state(struct dsim_device *dsim)
        for (i = 0; i < RETRY; i++) {
                ret = dsim_read_data(dsim, MIPI_DSI_DCS_READ,
                                MIPI_DCS_GET_POWER_MODE, 0x1, buf);
-               if (ret < 0) {
+               if (ret == -ETIMEDOUT) {
+                       dsim_info("recovery is already operated\n");
+                       return DSIM_ESD_OK;
+               } else if ((ret < 0) && (ret != -ETIMEDOUT)) {
                        dsim_err("Failed to read panel REG 0x%02X!: 0x%02x, i(%d)\n",
                                        MIPI_DCS_GET_POWER_MODE,
                                        *(unsigned int *)buf & 0xFF, i);
index 68fc7d2ad56972ae6ab29f7efee4737ee3d0f811..9b52de04c212b41ccdd1f9ae652628cc9aa2ad0d 100755 (executable)
@@ -538,7 +538,10 @@ static int nov36672a_read_state(struct dsim_device *dsim)
        for (i = 0; i < RETRY; i++) {
                ret = dsim_read_data(dsim, MIPI_DSI_DCS_READ,
                                MIPI_DCS_GET_POWER_MODE, 0x1, buf);
-               if (ret < 0) {
+               if (ret == -ETIMEDOUT) {
+                       dsim_info("recovery is already operated\n");
+                       return DSIM_ESD_OK;
+               } else if ((ret < 0) && (ret != -ETIMEDOUT)) {
                        dsim_err("Failed to read panel REG 0x%02X!: 0x%02x, i(%d)\n",
                                        MIPI_DCS_GET_POWER_MODE,
                                        *(unsigned int *)buf & 0xFF, i);
index 52b4a4a1f204ec8ab3a01f96d1bc4033ccbcfcb4..2617f1fdfa7c53299304b7c6416e8a66b7844075 100644 (file)
@@ -686,7 +686,10 @@ static int s6e3fa0_read_state(struct dsim_device *dsim)
        for (i = 0; i < RETRY; i++) {
                ret = dsim_read_data(dsim, MIPI_DSI_DCS_READ,
                                        MIPI_DCS_GET_POWER_MODE, 0x1, buf);
-               if (ret < 0) {
+               if (ret == -ETIMEDOUT) {
+                       dsim_info("recovery is already operated\n");
+                       return DSIM_ESD_OK;
+               } else if ((ret < 0) && (ret != -ETIMEDOUT)) {
                        dsim_err("Failed to read panel REG 0x%02X!: 0x%02x, i(%d)\n",
                                        MIPI_DCS_GET_POWER_MODE,
                                        *(unsigned int *)buf & 0xFF, i);