From d7a8169269ce8b4a29d09e4cc3ae22be665efb2d Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Tue, 26 Oct 2021 16:58:24 +0530 Subject: [PATCH 1/5] disp: rotator: remove ubwc format support for rotator This change removes ubwc formats from input and output for the holi and blair target which do not support ubwc for offline roation. Change-Id: I34f8f3e6db5e7f8f63bb3948c69f810342b7c0ea Signed-off-by: Mahadevan --- rotator/sde_rotator_r3.c | 170 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 4 deletions(-) diff --git a/rotator/sde_rotator_r3.c b/rotator/sde_rotator_r3.c index 19100a5bcd49..b1e2f15a4b84 100644 --- a/rotator/sde_rotator_r3.c +++ b/rotator/sde_rotator_r3.c @@ -406,6 +406,168 @@ static const u32 sde_hw_rotator_v4_outpixfmts[] = { SDE_PIX_FMT_XBGR_2101010_TILE, }; +static const u32 sde_hw_rotator_v5_inpixfmts[] = { + SDE_PIX_FMT_XRGB_8888, + SDE_PIX_FMT_ARGB_8888, + SDE_PIX_FMT_ABGR_8888, + SDE_PIX_FMT_RGBA_8888, + SDE_PIX_FMT_BGRA_8888, + SDE_PIX_FMT_RGBX_8888, + SDE_PIX_FMT_BGRX_8888, + SDE_PIX_FMT_XBGR_8888, + SDE_PIX_FMT_RGBA_5551, + SDE_PIX_FMT_ARGB_1555, + SDE_PIX_FMT_ABGR_1555, + SDE_PIX_FMT_BGRA_5551, + SDE_PIX_FMT_BGRX_5551, + SDE_PIX_FMT_RGBX_5551, + SDE_PIX_FMT_XBGR_1555, + SDE_PIX_FMT_XRGB_1555, + SDE_PIX_FMT_ARGB_4444, + SDE_PIX_FMT_RGBA_4444, + SDE_PIX_FMT_BGRA_4444, + SDE_PIX_FMT_ABGR_4444, + SDE_PIX_FMT_RGBX_4444, + SDE_PIX_FMT_XRGB_4444, + SDE_PIX_FMT_BGRX_4444, + SDE_PIX_FMT_XBGR_4444, + SDE_PIX_FMT_RGB_888, + SDE_PIX_FMT_BGR_888, + SDE_PIX_FMT_RGB_565, + SDE_PIX_FMT_BGR_565, + SDE_PIX_FMT_Y_CB_CR_H2V2, + SDE_PIX_FMT_Y_CR_CB_H2V2, + SDE_PIX_FMT_Y_CR_CB_GH2V2, + SDE_PIX_FMT_Y_CBCR_H2V2, + SDE_PIX_FMT_Y_CRCB_H2V2, + SDE_PIX_FMT_Y_CBCR_H1V2, + SDE_PIX_FMT_Y_CRCB_H1V2, + SDE_PIX_FMT_Y_CBCR_H2V1, + SDE_PIX_FMT_Y_CRCB_H2V1, + SDE_PIX_FMT_YCBYCR_H2V1, + SDE_PIX_FMT_Y_CBCR_H2V2_VENUS, + SDE_PIX_FMT_Y_CRCB_H2V2_VENUS, + /* SDE_PIX_FMT_RGBA_8888_UBWC */ + /* SDE_PIX_FMT_RGBX_8888_UBWC */ + /* SDE_PIX_FMT_RGB_565_UBWC */ + /* SDE_PIX_FMT_Y_CBCR_H2V2_UBWC */ + SDE_PIX_FMT_RGBA_1010102, + SDE_PIX_FMT_RGBX_1010102, + SDE_PIX_FMT_ARGB_2101010, + SDE_PIX_FMT_XRGB_2101010, + SDE_PIX_FMT_BGRA_1010102, + SDE_PIX_FMT_BGRX_1010102, + SDE_PIX_FMT_ABGR_2101010, + SDE_PIX_FMT_XBGR_2101010, + /* SDE_PIX_FMT_RGBA_1010102_UBWC */ + /* SDE_PIX_FMT_RGBX_1010102_UBWC */ + SDE_PIX_FMT_Y_CBCR_H2V2_P010, + SDE_PIX_FMT_Y_CBCR_H2V2_P010_VENUS, + SDE_PIX_FMT_Y_CBCR_H2V2_TP10, + /* SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC */ + /* SDE_PIX_FMT_Y_CBCR_H2V2_P010_UBWC */ + SDE_PIX_FMT_Y_CBCR_H2V2_P010_TILE, + SDE_PIX_FMT_Y_CBCR_H2V2_TILE, + SDE_PIX_FMT_Y_CRCB_H2V2_TILE, + SDE_PIX_FMT_XRGB_8888_TILE, + SDE_PIX_FMT_ARGB_8888_TILE, + SDE_PIX_FMT_ABGR_8888_TILE, + SDE_PIX_FMT_XBGR_8888_TILE, + SDE_PIX_FMT_RGBA_8888_TILE, + SDE_PIX_FMT_BGRA_8888_TILE, + SDE_PIX_FMT_RGBX_8888_TILE, + SDE_PIX_FMT_BGRX_8888_TILE, + SDE_PIX_FMT_RGBA_1010102_TILE, + SDE_PIX_FMT_RGBX_1010102_TILE, + SDE_PIX_FMT_ARGB_2101010_TILE, + SDE_PIX_FMT_XRGB_2101010_TILE, + SDE_PIX_FMT_BGRA_1010102_TILE, + SDE_PIX_FMT_BGRX_1010102_TILE, + SDE_PIX_FMT_ABGR_2101010_TILE, + SDE_PIX_FMT_XBGR_2101010_TILE, +}; + +static const u32 sde_hw_rotator_v5_outpixfmts[] = { + SDE_PIX_FMT_XRGB_8888, + SDE_PIX_FMT_ARGB_8888, + SDE_PIX_FMT_ABGR_8888, + SDE_PIX_FMT_RGBA_8888, + SDE_PIX_FMT_BGRA_8888, + SDE_PIX_FMT_RGBX_8888, + SDE_PIX_FMT_BGRX_8888, + SDE_PIX_FMT_XBGR_8888, + SDE_PIX_FMT_RGBA_5551, + SDE_PIX_FMT_ARGB_1555, + SDE_PIX_FMT_ABGR_1555, + SDE_PIX_FMT_BGRA_5551, + SDE_PIX_FMT_BGRX_5551, + SDE_PIX_FMT_RGBX_5551, + SDE_PIX_FMT_XBGR_1555, + SDE_PIX_FMT_XRGB_1555, + SDE_PIX_FMT_ARGB_4444, + SDE_PIX_FMT_RGBA_4444, + SDE_PIX_FMT_BGRA_4444, + SDE_PIX_FMT_ABGR_4444, + SDE_PIX_FMT_RGBX_4444, + SDE_PIX_FMT_XRGB_4444, + SDE_PIX_FMT_BGRX_4444, + SDE_PIX_FMT_XBGR_4444, + SDE_PIX_FMT_RGB_888, + SDE_PIX_FMT_BGR_888, + SDE_PIX_FMT_RGB_565, + SDE_PIX_FMT_BGR_565, + /* SDE_PIX_FMT_Y_CB_CR_H2V2 */ + /* SDE_PIX_FMT_Y_CR_CB_H2V2 */ + /* SDE_PIX_FMT_Y_CR_CB_GH2V2 */ + SDE_PIX_FMT_Y_CBCR_H2V2, + SDE_PIX_FMT_Y_CRCB_H2V2, + SDE_PIX_FMT_Y_CBCR_H1V2, + SDE_PIX_FMT_Y_CRCB_H1V2, + SDE_PIX_FMT_Y_CBCR_H2V1, + SDE_PIX_FMT_Y_CRCB_H2V1, + /* SDE_PIX_FMT_YCBYCR_H2V1 */ + SDE_PIX_FMT_Y_CBCR_H2V2_VENUS, + SDE_PIX_FMT_Y_CRCB_H2V2_VENUS, + /* SDE_PIX_FMT_RGBA_8888_UBWC */ + /* SDE_PIX_FMT_RGBX_8888_UBWC */ + /* SDE_PIX_FMT_RGB_565_UBWC */ + /* SDE_PIX_FMT_Y_CBCR_H2V2_UBWC */ + SDE_PIX_FMT_RGBA_1010102, + SDE_PIX_FMT_RGBX_1010102, + SDE_PIX_FMT_ARGB_2101010, + SDE_PIX_FMT_XRGB_2101010, + SDE_PIX_FMT_BGRA_1010102, + SDE_PIX_FMT_BGRX_1010102, + SDE_PIX_FMT_ABGR_2101010, + SDE_PIX_FMT_XBGR_2101010, + /* SDE_PIX_FMT_RGBA_1010102_UBWC */ + /* SDE_PIX_FMT_RGBX_1010102_UBWC */ + SDE_PIX_FMT_Y_CBCR_H2V2_P010, + SDE_PIX_FMT_Y_CBCR_H2V2_P010_VENUS, + SDE_PIX_FMT_Y_CBCR_H2V2_TP10, + /* SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC */ + /* SDE_PIX_FMT_Y_CBCR_H2V2_P010_UBWC */ + SDE_PIX_FMT_Y_CBCR_H2V2_P010_TILE, + SDE_PIX_FMT_Y_CBCR_H2V2_TILE, + SDE_PIX_FMT_Y_CRCB_H2V2_TILE, + SDE_PIX_FMT_XRGB_8888_TILE, + SDE_PIX_FMT_ARGB_8888_TILE, + SDE_PIX_FMT_ABGR_8888_TILE, + SDE_PIX_FMT_XBGR_8888_TILE, + SDE_PIX_FMT_RGBA_8888_TILE, + SDE_PIX_FMT_BGRA_8888_TILE, + SDE_PIX_FMT_RGBX_8888_TILE, + SDE_PIX_FMT_BGRX_8888_TILE, + SDE_PIX_FMT_RGBA_1010102_TILE, + SDE_PIX_FMT_RGBX_1010102_TILE, + SDE_PIX_FMT_ARGB_2101010_TILE, + SDE_PIX_FMT_XRGB_2101010_TILE, + SDE_PIX_FMT_BGRA_1010102_TILE, + SDE_PIX_FMT_BGRX_1010102_TILE, + SDE_PIX_FMT_ABGR_2101010_TILE, + SDE_PIX_FMT_XBGR_2101010_TILE, +}; + static const u32 sde_hw_rotator_v4_inpixfmts_sbuf[] = { SDE_PIX_FMT_Y_CBCR_H2V2_P010, SDE_PIX_FMT_Y_CBCR_H2V2, @@ -3507,13 +3669,13 @@ static int sde_rotator_hw_rev_init(struct sde_hw_rotator *rot) set_bit(SDE_CAPS_PARTIALWR, mdata->sde_caps_map); set_bit(SDE_CAPS_HW_TIMESTAMP, mdata->sde_caps_map); rot->inpixfmts[SDE_ROTATOR_MODE_OFFLINE] = - sde_hw_rotator_v4_inpixfmts; + sde_hw_rotator_v5_inpixfmts; rot->num_inpixfmt[SDE_ROTATOR_MODE_OFFLINE] = - ARRAY_SIZE(sde_hw_rotator_v4_inpixfmts); + ARRAY_SIZE(sde_hw_rotator_v5_inpixfmts); rot->outpixfmts[SDE_ROTATOR_MODE_OFFLINE] = - sde_hw_rotator_v4_outpixfmts; + sde_hw_rotator_v5_outpixfmts; rot->num_outpixfmt[SDE_ROTATOR_MODE_OFFLINE] = - ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts); + ARRAY_SIZE(sde_hw_rotator_v5_outpixfmts); rot->downscale_caps = "LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2"; } else { From 0dd45aa272dcd4f6247ba29a7b26be929960dc57 Mon Sep 17 00:00:00 2001 From: osaisruj Date: Sun, 17 Oct 2021 15:53:40 +0530 Subject: [PATCH 2/5] disp: msm: sde: add sysfs node to give panel power state Add sysfs node on connecter to get the panel power state. This node is used by the HAL to read display power state. Change-Id: I717e4b87513a845c867871f93876fc7c88ff7b2f Signed-off-by: osaisruj --- msm/sde/sde_connector.c | 62 +++++++++++++++++++++++++++++++++++++++++ msm/sde/sde_connector.h | 10 +++++++ msm/sde/sde_kms.c | 6 ++++ 3 files changed, 78 insertions(+) diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 013ebf81887f..6c6a5a6e3585 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -1026,6 +1026,9 @@ void sde_connector_destroy(struct drm_connector *connector) c_conn = to_sde_connector(connector); + if (c_conn->sysfs_dev) + device_unregister(c_conn->sysfs_dev); + /* cancel if any pending esd work */ sde_connector_schedule_status_work(connector, false); @@ -2845,6 +2848,65 @@ static int _sde_connector_install_properties(struct drm_device *dev, return 0; } +static ssize_t panel_power_state_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct drm_connector *conn; + struct sde_connector *sde_conn; + + conn = dev_get_drvdata(device); + sde_conn = to_sde_connector(conn); + + return scnprintf(buf, PAGE_SIZE, "%d\n", sde_conn->last_panel_power_mode); +} + +static DEVICE_ATTR_RO(panel_power_state); + +static struct attribute *sde_connector_dev_attrs[] = { + &dev_attr_panel_power_state.attr, + NULL +}; + +static const struct attribute_group sde_connector_attr_group = { + .attrs = sde_connector_dev_attrs, +}; +static const struct attribute_group *sde_connector_attr_groups[] = { + &sde_connector_attr_group, + NULL, +}; + +int sde_connector_post_init(struct drm_device *dev, struct drm_connector *conn) +{ + struct sde_connector *c_conn; + int rc = 0; + + if (!dev || !dev->primary || !dev->primary->kdev || !conn) { + SDE_ERROR("invalid input param(s)\n"); + rc = -EINVAL; + return rc; + } + + c_conn = to_sde_connector(conn); + + if (conn->connector_type != DRM_MODE_CONNECTOR_DSI) + return rc; + + c_conn->sysfs_dev = + device_create_with_groups(dev->primary->kdev->class, dev->primary->kdev, 0, + conn, sde_connector_attr_groups, "sde-conn-%d-%s", conn->index, + conn->name); + if (IS_ERR_OR_NULL(c_conn->sysfs_dev)) { + SDE_ERROR("connector:%d sysfs create failed rc:%ld\n", &c_conn->base.index, + PTR_ERR(c_conn->sysfs_dev)); + if (!c_conn->sysfs_dev) + rc = -EINVAL; + else + rc = PTR_ERR(c_conn->sysfs_dev); + } + + return rc; +} + struct drm_connector *sde_connector_init(struct drm_device *dev, struct drm_encoder *encoder, struct drm_panel *panel, diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index 2407b7efed42..3caa1fa60666 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -511,6 +511,7 @@ struct sde_connector { int dpms_mode; int lp_mode; int last_panel_power_mode; + struct device *sysfs_dev; struct msm_property_info property_info; struct msm_property_data property_data[CONNECTOR_PROP_COUNT]; @@ -753,6 +754,15 @@ int sde_connector_set_property_for_commit(struct drm_connector *connector, struct drm_atomic_state *atomic_state, uint32_t property_idx, uint64_t value); +/** + * sde_connector_post_init - update connector object with post initialization. + * It can update the debugfs, sysfs, entries + * @dev: Pointer to drm device struct + * @conn: Pointer to drm connector + * Returns: Zero on success + */ +int sde_connector_post_init(struct drm_device *dev, struct drm_connector *conn); + /** * sde_connector_init - create drm connector object for a given display * @dev: Pointer to drm device struct diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index bb7f41ec65db..862fd2e18659 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2176,6 +2176,8 @@ static int sde_kms_postinit(struct msm_kms *kms) struct sde_kms *sde_kms = to_sde_kms(kms); struct drm_device *dev; struct drm_crtc *crtc; + struct drm_connector *conn; + struct drm_connector_list_iter conn_iter; int rc; if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev) { @@ -2192,6 +2194,10 @@ static int sde_kms_postinit(struct msm_kms *kms) drm_for_each_crtc(crtc, dev) sde_crtc_post_init(dev, crtc); + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(conn, &conn_iter) + sde_connector_post_init(dev, conn); + drm_connector_list_iter_end(&conn_iter); return rc; } From 05ccf7d2787ab77e18a20d032e826b41b61880ad Mon Sep 17 00:00:00 2001 From: osaisruj Date: Fri, 29 Oct 2021 01:33:47 +0530 Subject: [PATCH 3/5] disp: msm: sde: add twm mode sysfs mode Add sysfs node on connector to get twm enable state. This node is used by the HAL to notify TWM entry and exit. Change-Id: I56a844076014c2e12075756f6b1bc42b91b48ad1 Signed-off-by: osaisruj --- msm/sde/sde_connector.c | 37 +++++++++++++++++++++++++++++++++++++ msm/sde/sde_connector.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 6c6a5a6e3585..fdd72a459363 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2860,10 +2860,46 @@ static ssize_t panel_power_state_show(struct device *device, return scnprintf(buf, PAGE_SIZE, "%d\n", sde_conn->last_panel_power_mode); } +static ssize_t twm_enable_store(struct device *device, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct drm_connector *conn; + struct sde_connector *sde_conn; + int rc; + int data; + + conn = dev_get_drvdata(device); + sde_conn = to_sde_connector(conn); + + rc = kstrtoint(buf, 10, &data); + if (rc) { + SDE_ERROR("kstrtoint failed, rc =%d\n", rc); + return -EINVAL; + } + sde_conn->twm_en = data ? true : false; + SDE_DEBUG("TWM: %s\n", sde_conn->twm_en ? "ENABLED" : "DISABLED"); + return count; +} + +static ssize_t twm_enable_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct drm_connector *conn; + struct sde_connector *sde_conn; + + conn = dev_get_drvdata(device); + sde_conn = to_sde_connector(conn); + + SDE_DEBUG("TWM: %s\n", sde_conn->twm_en ? "ENABLED" : "DISABLED"); + return scnprintf(buf, PAGE_SIZE, "%d\n", sde_conn->twm_en); +} + static DEVICE_ATTR_RO(panel_power_state); +static DEVICE_ATTR_RW(twm_enable); static struct attribute *sde_connector_dev_attrs[] = { &dev_attr_panel_power_state.attr, + &dev_attr_twm_enable.attr, NULL }; @@ -2958,6 +2994,7 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, c_conn->dpms_mode = DRM_MODE_DPMS_ON; c_conn->lp_mode = 0; c_conn->last_panel_power_mode = SDE_MODE_DPMS_ON; + c_conn->twm_en = false; sde_kms = to_sde_kms(priv->kms); if (sde_kms->vbif[VBIF_NRT]) { diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index 3caa1fa60666..ecbbefbf8b60 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -470,6 +470,7 @@ struct sde_connector_dyn_hdr_metadata { * @esd_status_interval: variable to change ESD check interval in millisec * @panel_dead: Flag to indicate if panel has gone bad * @esd_status_check: Flag to indicate if ESD thread is scheduled or not + * @twm_en: Flag to indicate if TWM mode is enabled or not * @bl_scale_dirty: Flag to indicate PP BL scale value(s) is changed * @bl_scale: BL scale value for ABA feature * @bl_scale_sv: BL scale value for sunlight visibility feature @@ -533,6 +534,7 @@ struct sde_connector { u32 esd_status_interval; bool panel_dead; bool esd_status_check; + bool twm_en; bool bl_scale_dirty; u32 bl_scale; From 1e20848d49ade9817606c79b1735d7d3a0cb6078 Mon Sep 17 00:00:00 2001 From: osaisruj Date: Mon, 1 Nov 2021 01:15:18 +0530 Subject: [PATCH 4/5] disp: msm: add support for twm entry Skip backlight updates and panel off commands during twm entry. Change-Id: I7656fa0d513a8a3e82d9bbbf5c3f85c1b84ee9da Signed-off-by: osaisruj --- msm/dsi/dsi_panel.c | 12 ++++++++++++ msm/dsi/dsi_panel.h | 3 ++- msm/sde/sde_connector.c | 7 +++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index cdde192e19ac..456fcf52574c 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -378,6 +378,10 @@ static int dsi_panel_power_off(struct dsi_panel *panel) { int rc = 0; + if (panel->is_twm_en) { + DSI_DEBUG("TWM Enabled, skip panel power off\n"); + return rc; + } if (gpio_is_valid(panel->reset_config.disp_en_gpio)) gpio_set_value(panel->reset_config.disp_en_gpio, 0); @@ -4305,6 +4309,10 @@ int dsi_panel_set_nolp(struct dsi_panel *panel) return -EINVAL; } + if (panel->is_twm_en) { + DSI_DEBUG("TWM Enabled, skip idle off\n"); + return rc; + } mutex_lock(&panel->panel_lock); if (!panel->panel_initialized) goto exit; @@ -4717,6 +4725,10 @@ int dsi_panel_disable(struct dsi_panel *panel) return -EINVAL; } + if (panel->is_twm_en) { + DSI_DEBUG("TWM Enabled, skip panel disable\n"); + return rc; + } mutex_lock(&panel->panel_lock); /* Avoid sending panel off commands when ESD recovery is underway */ diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index b0c259dacce1..f3902274930b 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, 2021 The Linux Foundation. All rights reserved. */ #ifndef _DSI_PANEL_H_ @@ -244,6 +244,7 @@ struct dsi_panel { bool reset_gpio_always_on; atomic_t esd_recovery_pending; + bool is_twm_en; bool panel_initialized; bool te_using_watchdog_timer; struct dsi_qsync_capabilities qsync_caps; diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index fdd72a459363..8725798c3fe4 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2865,18 +2865,21 @@ static ssize_t twm_enable_store(struct device *device, { struct drm_connector *conn; struct sde_connector *sde_conn; + struct dsi_display *dsi_display; int rc; int data; conn = dev_get_drvdata(device); sde_conn = to_sde_connector(conn); - + dsi_display = (struct dsi_display *) sde_conn->display; rc = kstrtoint(buf, 10, &data); if (rc) { - SDE_ERROR("kstrtoint failed, rc =%d\n", rc); + SDE_ERROR("kstrtoint failed, rc = %d\n", rc); return -EINVAL; } sde_conn->twm_en = data ? true : false; + dsi_display->panel->is_twm_en = sde_conn->twm_en; + sde_conn->allow_bl_update = data ? false : true; SDE_DEBUG("TWM: %s\n", sde_conn->twm_en ? "ENABLED" : "DISABLED"); return count; } From 20c46f6fa6ecde692a7ae316709d534d69730ca3 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Mon, 25 Oct 2021 22:05:03 +0530 Subject: [PATCH 5/5] disp: msm: dsi: remove early return from dma_cmd_wait_for_done In ASYNC wait mode, next command kickoff can happen before previous command ISR execution is completed in below sequence: ASYNC command A -> triggered dsi_ctrl_isr for command A -> fired and executed atomic_set(&dsi_ctrl->dma_irq_trig, 1); wait_for_done for command A -> returns early as dsi_ctrl->dma_irq_trig is 1 ASYNC Command B -> triggered wait_for_done for command B -> waiting for cmd_dma_done dsi_ctrl_isr for command A -> executes complete_all(&dsi_ctrl->irq_info.cmd_dma_done); wait_for_done for command B -> returns success incorrectly based on complete_all of previous command isr and disable_status_interrupt() is not called. This leads to refcount of dma_done going wrong and dsi_ctrl_isr is not enabled on suspend resume. To fix this issue, mark command transfer successful only based on complete_all(cmd_dma_done). This way disable_status_interrupt() will be always called either from dsi_ctrl_isr or wait_for_done(). Change-Id: I0379ea7ff82a1e077b95f6996d11d1722de00936 Signed-off-by: Ritesh Kumar --- msm/dsi/dsi_ctrl.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 89092690a678..c298e616ac65 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -390,13 +390,6 @@ static void dsi_ctrl_dma_cmd_wait_for_done(struct work_struct *work) dsi_hw_ops = dsi_ctrl->hw.ops; SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY); - /* - * This atomic state will be set if ISR has been triggered, - * so the wait is not needed. - */ - if (atomic_read(&dsi_ctrl->dma_irq_trig)) - goto done; - ret = wait_for_completion_timeout( &dsi_ctrl->irq_info.cmd_dma_done, msecs_to_jiffies(DSI_CTRL_TX_TO_MS)); @@ -416,8 +409,8 @@ static void dsi_ctrl_dma_cmd_wait_for_done(struct work_struct *work) DSI_SINT_CMD_MODE_DMA_DONE); } -done: dsi_ctrl->dma_wait_queued = false; + SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_EXIT); } static int dsi_ctrl_check_state(struct dsi_ctrl *dsi_ctrl,