From c56edb2f47142582b616621bb7e2577e023f2131 Mon Sep 17 00:00:00 2001 From: Rajeev Nandan Date: Thu, 7 Oct 2021 23:11:32 +0530 Subject: [PATCH 1/9] disp: msm: dsi: Support uncompressed rgb101010 format Add support for uncompressed rgb101010 format. Change-Id: I60c2f7817eb2ea3e462c4692b1beb7f523836326 Signed-off-by: Rajeev Nandan Signed-off-by: Ritesh Kumar --- msm/dsi/dsi_ctrl.c | 3 +++ msm/dsi/dsi_ctrl_hw_cmn.c | 13 ++++++++----- msm/dsi/dsi_defs.h | 4 ++++ msm/dsi/dsi_panel.c | 3 +++ msm/dsi/dsi_phy_timing_calc.c | 4 ++-- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 89092690a678..1040b4f5fb0c 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -933,6 +933,9 @@ int dsi_ctrl_pixel_format_to_bpp(enum dsi_pixel_format dst_format) case DSI_PIXEL_FORMAT_RGB888: bpp = 24; break; + case DSI_PIXEL_FORMAT_RGB101010: + bpp = 30; + break; default: bpp = 24; break; diff --git a/msm/dsi/dsi_ctrl_hw_cmn.c b/msm/dsi/dsi_ctrl_hw_cmn.c index 59281c045075..dceee163c15e 100644 --- a/msm/dsi/dsi_ctrl_hw_cmn.c +++ b/msm/dsi/dsi_ctrl_hw_cmn.c @@ -41,9 +41,9 @@ static bool dsi_compression_enabled(struct dsi_mode_info *mode) /* Unsupported formats default to RGB888 */ static const u8 cmd_mode_format_map[DSI_PIXEL_FORMAT_MAX] = { - 0x6, 0x7, 0x8, 0x8, 0x0, 0x3, 0x4 }; + 0x6, 0x7, 0x8, 0x8, 0x0, 0x3, 0x4, 0x9 }; static const u8 video_mode_format_map[DSI_PIXEL_FORMAT_MAX] = { - 0x0, 0x1, 0x2, 0x3, 0x3, 0x3, 0x3 }; + 0x0, 0x1, 0x2, 0x3, 0x3, 0x3, 0x3, 0x4 }; /** * dsi_split_link_setup() - setup dsi split link configurations @@ -421,10 +421,13 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl, u32 reg = 0, offset = 0; int pic_width = 0, this_frame_slices = 0, intf_ip_w = 0; u32 pkt_per_line = 0, eol_byte_num = 0, bytes_in_slice = 0; + u32 bpp; if (roi && (!roi->w || !roi->h)) return; + bpp = dsi_pixel_format_to_bpp(cfg->dst_format); + if (dsi_dsc_compression_enabled(mode)) { struct msm_display_dsc_info dsc; @@ -458,11 +461,11 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl, bytes_in_slice = vdc.bytes_in_slice; } else if (roi) { width_final = roi->w; - stride_final = roi->w * 3; + stride_final = DIV_ROUND_UP(roi->w * bpp, 8); height_final = roi->h; } else { width_final = mode->h_active; - stride_final = mode->h_active * 3; + stride_final = DIV_ROUND_UP(mode->h_active * bpp, 8); height_final = mode->v_active; } @@ -579,7 +582,7 @@ void dsi_ctrl_hw_cmn_video_engine_setup(struct dsi_ctrl_hw *ctrl, reg |= (cfg->bllp_lp11_en ? BIT(12) : 0); reg |= (cfg->traffic_mode & 0x3) << 8; reg |= (cfg->vc_id & 0x3); - reg |= (video_mode_format_map[common_cfg->dst_format] & 0x3) << 4; + reg |= (video_mode_format_map[common_cfg->dst_format] & 0x7) << 4; DSI_W32(ctrl, DSI_VIDEO_MODE_CTRL, reg); reg = (common_cfg->swap_mode & 0x7) << 12; diff --git a/msm/dsi/dsi_defs.h b/msm/dsi/dsi_defs.h index 41dee2f61823..892334fc1315 100644 --- a/msm/dsi/dsi_defs.h +++ b/msm/dsi/dsi_defs.h @@ -39,6 +39,7 @@ * @DSI_PIXEL_FORMAT_RGB111: * @DSI_PIXEL_FORMAT_RGB332: * @DSI_PIXEL_FORMAT_RGB444: + * @DSI_PIXEL_FORMAT_RGB101010: * @DSI_PIXEL_FORMAT_MAX: */ enum dsi_pixel_format { @@ -49,6 +50,7 @@ enum dsi_pixel_format { DSI_PIXEL_FORMAT_RGB111, DSI_PIXEL_FORMAT_RGB332, DSI_PIXEL_FORMAT_RGB444, + DSI_PIXEL_FORMAT_RGB101010, DSI_PIXEL_FORMAT_MAX }; @@ -740,6 +742,8 @@ static inline int dsi_pixel_format_to_bpp(enum dsi_pixel_format fmt) return 8; case DSI_PIXEL_FORMAT_RGB444: return 12; + case DSI_PIXEL_FORMAT_RGB101010: + return 30; } return 24; } diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index cdde192e19ac..f71718443dda 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -929,6 +929,9 @@ static int dsi_panel_parse_pixel_format(struct dsi_host_common_cfg *host, case 18: fmt = DSI_PIXEL_FORMAT_RGB666; break; + case 30: + fmt = DSI_PIXEL_FORMAT_RGB101010; + break; case 24: default: fmt = DSI_PIXEL_FORMAT_RGB888; diff --git a/msm/dsi/dsi_phy_timing_calc.c b/msm/dsi/dsi_phy_timing_calc.c index 6e2a625a3572..6efc8d781265 100644 --- a/msm/dsi/dsi_phy_timing_calc.c +++ b/msm/dsi/dsi_phy_timing_calc.c @@ -1,12 +1,12 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include "dsi_phy_timing_calc.h" static const u32 bits_per_pixel[DSI_PIXEL_FORMAT_MAX] = { - 16, 18, 18, 24, 3, 8, 12 }; + 16, 18, 18, 24, 3, 8, 12, 30 }; static int dsi_phy_cmn_validate_and_set(struct timing_entry *t, char const *t_name) From 0dd45aa272dcd4f6247ba29a7b26be929960dc57 Mon Sep 17 00:00:00 2001 From: osaisruj Date: Sun, 17 Oct 2021 15:53:40 +0530 Subject: [PATCH 2/9] 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/9] 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/9] 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/9] 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, From 77edd61d98f0351bc0c81a8a171f666ba6b225d7 Mon Sep 17 00:00:00 2001 From: longzhao Date: Thu, 18 Nov 2021 18:00:26 +0800 Subject: [PATCH 6/9] disp: msm: sde: avoid sde irq enable or disable when sde irq not active During the sde_irq_update, the sde irq may not be active, the enable or disable will be nonsence. set the irq_num init value to negtive, if this value change, means sde irq_num has been initial. Change-Id: I7b23c662ccc9db0b38550897adb939305d941e6a Signed-off-by: longzhao --- msm/sde/sde_irq.c | 4 +++- msm/sde/sde_kms.c | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/sde/sde_irq.c b/msm/sde/sde_irq.c index e8574156512e..974c163a6770 100644 --- a/msm/sde/sde_irq.c +++ b/msm/sde/sde_irq.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, 2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -22,6 +22,8 @@ void sde_irq_update(struct msm_kms *msm_kms, bool enable) SDE_ERROR("invalid kms arguments\n"); return; } + if (sde_kms->irq_num < 0) + return; sde_kms->irq_enabled = enable; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index bb7f41ec65db..4bd92b2c5a52 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -4795,6 +4795,7 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) msm_kms_init(&sde_kms->base, &kms_funcs); sde_kms->dev = dev; + sde_kms->irq_num = -1; return &sde_kms->base; } From 67ef82eb35fb8004217b20ed033fa4688bed7ff5 Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Sat, 20 Nov 2021 12:50:17 +0530 Subject: [PATCH 7/9] disp: msm: sde: avoid CWB in power on commit This change depends on HAL change which sets CONNECTOR_SET_CRTC property to null for cwb conn, if cwb is enabled during power off commit. This causes power off commit crtc_state's active_changed and connectors_changed set to true, which is causing seamless_crtc to true during msm_disable_outputs and this leads to invalid crtc state. This change modifies the seamless_crtc condition and the msm_crtc_set_mode callback is early returned during such cases to power off crtc. Without this change, during power on commit crtc_duplicate_state is causing cwb to turn on and the release fence is being created with +2 offset in such case, leading to late release fence signalling and further GPU fence timeouts. Change-Id: Ibe87a8c0e8083d619ee6f502b2a946e1e8ef5553 Signed-off-by: Jayaprakash Madisetty --- msm/msm_atomic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/msm_atomic.c b/msm/msm_atomic.c index 412d8b3bda05..049623486f38 100644 --- a/msm/msm_atomic.c +++ b/msm/msm_atomic.c @@ -55,7 +55,7 @@ static inline bool _msm_seamless_for_crtc(struct drm_device *dev, if (msm_is_mode_seamless_dms(&crtc_state->adjusted_mode) && !enable) return true; - if (!crtc_state->mode_changed && crtc_state->connectors_changed) { + if (!crtc_state->mode_changed && crtc_state->connectors_changed && crtc_state->active) { for_each_old_connector_in_state(state, connector, conn_state, i) { if ((conn_state->crtc == crtc_state->crtc) || @@ -282,6 +282,9 @@ msm_crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) mode = &new_crtc_state->mode; adjusted_mode = &new_crtc_state->adjusted_mode; + if (!new_crtc_state->active) + continue; + if (!new_crtc_state->mode_changed && new_crtc_state->connectors_changed) { if (_msm_seamless_for_conn(connector, From 81d15ab5bd99c64ca131f0fac485fdc07bd0b339 Mon Sep 17 00:00:00 2001 From: Rajeev Nandan Date: Tue, 23 Nov 2021 19:32:13 +0530 Subject: [PATCH 8/9] disp: msm: dsi: Clear slave dma status only for broadcast command In case of broadcast, for master controller, DMA_DONE bit gets cleared in dsi_ctrl_isr and for slave controller it gets cleared in clear_slave_dma_status. Current implementation checks DSI_CTRL_CMD_BROADCAST_MASTER flag to decide if it's slave or not. But, in the case of unicast, this flag is not set, leading to the unnecessary poll for clear_slave_dma_status for all unicast command transfers. Add a check to call clear_slave_dma_status only when the current command is broadcast on slave controller. Change-Id: I7156f8c12ec779b41dafc8fc67639814957ee51b Signed-off-by: Rajeev Nandan --- msm/dsi/dsi_ctrl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index c298e616ac65..764c605e4b96 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -1550,7 +1550,8 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, if (dsi_ctrl->dma_wait_queued) dsi_ctrl_flush_cmd_dma_queue(dsi_ctrl); - if (!(*flags & DSI_CTRL_CMD_BROADCAST_MASTER)) + if ((*flags & DSI_CTRL_CMD_BROADCAST) && + (!(*flags & DSI_CTRL_CMD_BROADCAST_MASTER))) dsi_ctrl_clear_slave_dma_status(dsi_ctrl, *flags); if (*flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { From ad89bfc0d515f98b71fa688170deae37165968b2 Mon Sep 17 00:00:00 2001 From: osaisruj Date: Fri, 12 Nov 2021 19:51:35 +0530 Subject: [PATCH 9/9] disp: msm: sde: modify format specifier Modify error log with correct format specifier. Change-Id: Ifb9d3f2decdb9dcac92ee810454a1027b5b78636 Signed-off-by: osaisruj --- msm/sde/sde_fence.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/sde/sde_fence.c b/msm/sde/sde_fence.c index dd9cc295f4e9..6b7a30fd733c 100644 --- a/msm/sde/sde_fence.c +++ b/msm/sde/sde_fence.c @@ -43,7 +43,7 @@ signed long sde_sync_wait(void *fnc, long timeout_ms) timeline_str, TIMELINE_VAL_LENGTH); SDE_ERROR( - "fence driver name:%s timeline name:%s seqno:0x%x timeline:%s signaled:0x%x\n", + "fence driver name:%s timeline name:%s seqno:0x%llx timeline:%s signaled:0x%x\n", fence->ops->get_driver_name(fence), fence->ops->get_timeline_name(fence), fence->seqno, timeline_str, @@ -132,7 +132,7 @@ static bool sde_fence_signaled(struct dma_fence *fence) bool status; status = ((int)(fence->seqno - f->ctx->done_count) <= 0); - SDE_DEBUG("status:%d fence seq:%d and timeline:%d\n", + SDE_DEBUG("status:%d fence seq:%llu and timeline:%d\n", status, fence->seqno, f->ctx->done_count); return status; } @@ -153,7 +153,7 @@ static void sde_fence_value_str(struct dma_fence *fence, char *str, int size) if (!fence || !str) return; - snprintf(str, size, "%d", fence->seqno); + snprintf(str, size, "%llu", fence->seqno); } static void sde_fence_timeline_value_str(struct dma_fence *fence, char *str, @@ -435,7 +435,7 @@ void sde_fence_list_dump(struct dma_fence *fence, struct seq_file **s) fence->ops->timeline_value_str(fence, timeline_str, TIMELINE_VAL_LENGTH); - seq_printf(*s, "fence name:%s timeline name:%s seqno:0x%x timeline:%s signaled:0x%x\n", + seq_printf(*s, "fence name:%s timeline name:%s seqno:0x%llx timeline:%s signaled:0x%x\n", fence->ops->get_driver_name(fence), fence->ops->get_timeline_name(fence), fence->seqno, timeline_str,