From 0dd45aa272dcd4f6247ba29a7b26be929960dc57 Mon Sep 17 00:00:00 2001 From: osaisruj Date: Sun, 17 Oct 2021 15:53:40 +0530 Subject: [PATCH 1/3] 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 2/3] 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 3/3] 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; }