From abab94fffe6ae4e52c29251778832ceb5e404696 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Fri, 14 Aug 2020 15:36:23 +0530 Subject: [PATCH 001/116] [DNM]: Hack for Touch Bring Up Hack for Touch Bring Up. This is to handle the case when touch probe happens before display panel is bind. This will not be needed once splash is up. Change-Id: I95a7e2983e77c0bf82c670ec7502b4198e8e3afa Signed-off-by: Ritesh Kumar --- msm/dsi/dsi_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index d7dd2e1cebac..7435f2ecec18 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -5644,7 +5644,7 @@ int dsi_display_dev_probe(struct platform_device *pdev) if (!panel_node) DSI_WARN("default panel not found\n"); - if (IS_ENABLED(CONFIG_DSI_PARSER) && !display->trusted_vm_env) + if (0) firm_req = !request_firmware_nowait( THIS_MODULE, 1, "dsi_prop", &pdev->dev, GFP_KERNEL, display, From 49745966474b81d940895f00a5ab3927cbc2b1f0 Mon Sep 17 00:00:00 2001 From: Niranjan Reddy Dumbala Date: Thu, 3 Sep 2020 14:33:01 +0530 Subject: [PATCH 002/116] Revert "[DNM]: Hack for Touch Bring Up" This reverts commit abab94fffe6ae4e52c29251778832ceb5e404696. Change-Id: Idd0b2a428e8aae0ca3cb3f575f0d0d237f94c977 --- msm/dsi/dsi_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 7435f2ecec18..d7dd2e1cebac 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -5644,7 +5644,7 @@ int dsi_display_dev_probe(struct platform_device *pdev) if (!panel_node) DSI_WARN("default panel not found\n"); - if (0) + if (IS_ENABLED(CONFIG_DSI_PARSER) && !display->trusted_vm_env) firm_req = !request_firmware_nowait( THIS_MODULE, 1, "dsi_prop", &pdev->dev, GFP_KERNEL, display, From c0c1d57d69eda3c8f0fa3f1d822152d33fd9c0de Mon Sep 17 00:00:00 2001 From: Rajeev Nandan Date: Thu, 17 Sep 2020 13:45:34 +0530 Subject: [PATCH 003/116] disp: msm: sde: fix panel early event blank notifier call If trusted vm is disabled, the DRM_PANEL_EARLY_EVENT_BLANK notifier does not get called because of this touch early suspend does not happen which leads to continuous touch i2c transfer failure during suspend. Change-Id: I6abaacb9f8343eec24d5642f7eda9e7c410fd8b7 Signed-off-by: Rajeev Nandan --- msm/sde/sde_kms.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 537ae164d78c..4c97812d23d5 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1165,10 +1165,12 @@ static void sde_kms_prepare_commit(struct msm_kms *kms, vm_ops = sde_vm_get_ops(sde_kms); if (!vm_ops) - goto end; + goto end_vm; if (vm_ops->vm_prepare_commit) vm_ops->vm_prepare_commit(sde_kms, state); + +end_vm: _sde_kms_drm_check_dpms(state, DRM_PANEL_EARLY_EVENT_BLANK); end: SDE_ATRACE_END("prepare_commit"); From 545d81b94c3dce8adb6d0fe4fb26158f78a19cb3 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Thu, 8 Oct 2020 17:28:45 +0530 Subject: [PATCH 004/116] Revert "disp: msm: dsi: Panic on getting continuous ESD check failures" This reverts commit 93fa9bdf60a311fea9acb4973f034a3a85d31880. Change-Id: Ia29c690202d53207377fad9117199d9c024a33cf Signed-off-by: Ritesh Kumar --- msm/dsi/dsi_display.h | 3 --- msm/sde/sde_connector.c | 30 +----------------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h index 9b4da4063ddd..7406d7829559 100644 --- a/msm/dsi/dsi_display.h +++ b/msm/dsi/dsi_display.h @@ -184,7 +184,6 @@ struct dsi_display_ext_bridge { * @misr_frame_count Number of frames to accumulate the MISR value * @esd_trigger field indicating ESD trigger through debugfs * @poms_te_work POMS delayed work for disabling panel TE - * @esd_fail_count Count of continuous ESD check failures * @te_source vsync source pin information * @clk_gating_config Clocks for which clock gating needs to be enabled * @queue_cmd_waits Indicates if wait for dma commands done has to be queued. @@ -278,8 +277,6 @@ struct dsi_display { struct dsi_display_boot_param *boot_disp; - u32 esd_fail_count; - u32 te_source; u32 clk_gating_config; bool queue_cmd_waits; diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index e0e31655af50..84e2d5b89131 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2380,8 +2380,6 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn, bool skip_pre_kickoff) { struct drm_event event; - struct dsi_display *display; - u32 const max_conseq_esd_fail_count = 5; if (!conn) return; @@ -2405,17 +2403,6 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn, conn->base.dev, &event, (u8 *)&conn->panel_dead); SDE_ERROR("esd check failed report PANEL_DEAD conn_id: %d enc_id: %d\n", conn->base.base.id, conn->encoder->base.id); - - if (conn->connector_type != DRM_MODE_CONNECTOR_DSI) - return; - - display = (struct dsi_display *)conn->display; - display->esd_fail_count++; - if (display->esd_fail_count == max_conseq_esd_fail_count) { - SDE_ERROR("Triggered reset on multiple PANEL_DEAD instances\n"); - SDE_DBG_DUMP("all", "dbg_bus", "dsi_dbg_bus", - "vbif_dbg_bus", "panic"); - } } int sde_connector_esd_status(struct drm_connector *conn) @@ -2453,16 +2440,8 @@ int sde_connector_esd_status(struct drm_connector *conn) SDE_DEBUG("Successfully received TE from panel\n"); ret = 0; } - - if (sde_conn->connector_type == DRM_MODE_CONNECTOR_DSI) { - /* Reset esd_fail_count on recovery */ - if (!ret) - display->esd_fail_count = 0; - SDE_EVT32(ret, display->esd_fail_count); - return ret; - } - SDE_EVT32(ret); + return ret; } @@ -2471,7 +2450,6 @@ static void sde_connector_check_status_work(struct work_struct *work) struct sde_connector *conn; int rc = 0; struct device *dev; - struct dsi_display *display; conn = container_of(to_delayed_work(work), struct sde_connector, status_work); @@ -2504,12 +2482,6 @@ static void sde_connector_check_status_work(struct work_struct *work) conn->esd_status_interval : STATUS_CHECK_INTERVAL_MS; schedule_delayed_work(&conn->status_work, msecs_to_jiffies(interval)); - - /* Successful ESD check */ - if (conn->connector_type == DRM_MODE_CONNECTOR_DSI) { - display = conn->display; - display->esd_fail_count = 0; - } return; } From e428f0adfb459c589b9aac95fa17d29823540119 Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Wed, 11 Nov 2020 14:37:10 -0500 Subject: [PATCH 005/116] disp: msm: sde: cache encoder_mask for vblank_work There is a race between disable commit swap-state on display thread and vblank work on event thread which may skip applying the vblank vote if the encoder_mask has already been cleared. To avoid the race, use a cached encoder_mask that is gauranteed to be valid between the vblank_on and vblank_off calls. Also, vblank queue work is initializing a variable that's never used and msm_disable_outputs has 2 instances of pointers to old CRTC state. Remove this dead code. Change-Id: I5e4a482b8f067e272a2aef5afa08cc0e1ab89434 Signed-off-by: Steve Cohen --- msm/msm_atomic.c | 1 - msm/msm_drv.c | 3 --- msm/sde/sde_crtc.c | 42 +++++++++++++++++++++--------------------- msm/sde/sde_crtc.h | 2 ++ 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/msm/msm_atomic.c b/msm/msm_atomic.c index 56dff6b2893e..6bddb33d9824 100644 --- a/msm/msm_atomic.c +++ b/msm/msm_atomic.c @@ -156,7 +156,6 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) old_conn_state, i) { const struct drm_encoder_helper_funcs *funcs; struct drm_encoder *encoder; - struct drm_crtc_state *old_crtc_state; /* * Shut down everything that's in the changeset and currently diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 2c582ef0f0ff..180b4662635d 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -366,7 +366,6 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, int crtc_id, bool enable) { struct vblank_work *cur_work; - struct drm_crtc *crtc; struct kthread_worker *worker; if (!priv || crtc_id >= priv->num_crtcs) @@ -376,8 +375,6 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, if (!cur_work) return -ENOMEM; - crtc = priv->crtcs[crtc_id]; - kthread_init_work(&cur_work->work, vblank_ctrl_worker); cur_work->crtc_id = crtc_id; cur_work->enable = enable; diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 8eede091eba1..8064b5fee05c 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -3823,13 +3823,13 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc, } /** - * _sde_crtc_vblank_enable_no_lock - update power resource and vblank request + * _sde_crtc_vblank_enable - update power resource and vblank request * @sde_crtc: Pointer to sde crtc structure * @enable: Whether to enable/disable vblanks * * @Return: error code */ -static int _sde_crtc_vblank_enable_no_lock( +static int _sde_crtc_vblank_enable( struct sde_crtc *sde_crtc, bool enable) { struct drm_crtc *crtc; @@ -3841,38 +3841,38 @@ static int _sde_crtc_vblank_enable_no_lock( } crtc = &sde_crtc->base; + SDE_EVT32(DRMID(crtc), enable, sde_crtc->enabled, + crtc->state->encoder_mask, + sde_crtc->cached_encoder_mask); if (enable) { int ret; - /* drop lock since power crtc cb may try to re-acquire lock */ - mutex_unlock(&sde_crtc->crtc_lock); ret = pm_runtime_get_sync(crtc->dev->dev); - mutex_lock(&sde_crtc->crtc_lock); if (ret < 0) return ret; + mutex_lock(&sde_crtc->crtc_lock); drm_for_each_encoder_mask(enc, crtc->dev, - crtc->state->encoder_mask) { - SDE_EVT32(DRMID(&sde_crtc->base), DRMID(enc), enable, - sde_crtc->enabled); + sde_crtc->cached_encoder_mask) { + SDE_EVT32(DRMID(crtc), DRMID(enc)); sde_encoder_register_vblank_callback(enc, sde_crtc_vblank_cb, (void *)crtc); } + + mutex_unlock(&sde_crtc->crtc_lock); } else { + mutex_lock(&sde_crtc->crtc_lock); drm_for_each_encoder_mask(enc, crtc->dev, - crtc->state->encoder_mask) { - SDE_EVT32(DRMID(&sde_crtc->base), DRMID(enc), enable, - sde_crtc->enabled); + sde_crtc->cached_encoder_mask) { + SDE_EVT32(DRMID(crtc), DRMID(enc)); sde_encoder_register_vblank_callback(enc, NULL, NULL); } - /* drop lock since power crtc cb may try to re-acquire lock */ mutex_unlock(&sde_crtc->crtc_lock); pm_runtime_put_sync(crtc->dev->dev); - mutex_lock(&sde_crtc->crtc_lock); } return 0; @@ -4168,9 +4168,10 @@ static void sde_crtc_disable(struct drm_crtc *crtc) kthread_cancel_delayed_work_sync(&sde_crtc->static_cache_read_work); kthread_cancel_delayed_work_sync(&sde_crtc->idle_notify_work); - SDE_EVT32(DRMID(crtc), sde_crtc->enabled, - crtc->state->active, crtc->state->enable); + SDE_EVT32(DRMID(crtc), sde_crtc->enabled, crtc->state->active, + crtc->state->enable, sde_crtc->cached_encoder_mask); sde_crtc->enabled = false; + sde_crtc->cached_encoder_mask = 0; /* Try to disable uidle */ sde_core_perf_crtc_update_uidle(crtc, false); @@ -4279,8 +4280,11 @@ static void sde_crtc_enable(struct drm_crtc *crtc, * Avoid drm_crtc_vblank_on during seamless DMS case * when CRTC is already in enabled state */ - if (!sde_crtc->enabled) + if (!sde_crtc->enabled) { + /* cache the encoder mask now for vblank work */ + sde_crtc->cached_encoder_mask = crtc->state->encoder_mask; drm_crtc_vblank_on(crtc); + } mutex_lock(&sde_crtc->crtc_lock); SDE_EVT32(DRMID(crtc), sde_crtc->enabled); @@ -5119,15 +5123,11 @@ int sde_crtc_vblank(struct drm_crtc *crtc, bool en) } sde_crtc = to_sde_crtc(crtc); - mutex_lock(&sde_crtc->crtc_lock); - SDE_EVT32(DRMID(&sde_crtc->base), en, sde_crtc->enabled); - ret = _sde_crtc_vblank_enable_no_lock(sde_crtc, en); + ret = _sde_crtc_vblank_enable(sde_crtc, en); if (ret) SDE_ERROR("%s vblank enable failed: %d\n", sde_crtc->name, ret); - mutex_unlock(&sde_crtc->crtc_lock); - return 0; } diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 41ca11bb97ea..f4efaac5578d 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -291,6 +291,7 @@ struct sde_crtc_misr_info { * @static_cache_read_work: delayed worker to transition cache state to read * @cache_state : Current static image cache state * @dspp_blob_info : blob containing dspp hw capability information + * @cached_encoder_mask : cached encoder_mask for vblank work */ struct sde_crtc { struct drm_crtc base; @@ -381,6 +382,7 @@ struct sde_crtc { enum sde_crtc_cache_state cache_state; struct drm_property_blob *dspp_blob_info; + u32 cached_encoder_mask; }; enum sde_crtc_dirty_flags { From 7c00a10c4c9cc0e3c12f80751ac3e4f46c4d275b Mon Sep 17 00:00:00 2001 From: Jayaprakash Date: Thu, 26 Nov 2020 14:34:08 +0530 Subject: [PATCH 006/116] disp: msm: sde: always enable prog fetch and fix prefill calculations Enabling and disabling programmable fetch dynamically across different fps can cause dsi underflow/overflow followed by underrun. Add changes to always enable prog fetch to handle such cases. Fix needed_prefill_lines calculation for vfp method of dfps since linetime is constant in this method and hence prefill lines need to be based on max_fps. For panels whose linetime varies with fps, the needed_prefill_lines calculation remains unchanged. Change-Id: Ib7b68b577ff903fc2359a8e8c4573d62d55c3828 Signed-off-by: Jayaprakash --- msm/sde/sde_encoder_phys_vid.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index 7a156c7bd2bc..7e444aa4dc79 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -205,6 +205,7 @@ static u32 programmable_fetch_get_num_lines( const struct intf_timing_params *timing) { struct sde_encoder_phys *phys_enc = &vid_enc->base; + struct sde_mdss_cfg *m; u32 needed_prefill_lines, needed_vfp_lines, actual_vfp_lines; const u32 fixed_prefill_fps = DEFAULT_FPS; @@ -213,18 +214,23 @@ static u32 programmable_fetch_get_num_lines( u32 start_of_frame_lines = timing->v_back_porch + timing->vsync_pulse_width; u32 v_front_porch = timing->v_front_porch; + u32 vrefresh, max_fps; + + m = phys_enc->sde_kms->catalog; + max_fps = sde_encoder_get_dfps_maxfps(phys_enc->parent); + vrefresh = (max_fps > timing->vrefresh) ? max_fps : timing->vrefresh; /* minimum prefill lines are defined based on 60fps */ - needed_prefill_lines = (timing->vrefresh > fixed_prefill_fps) ? - ((default_prefill_lines * timing->vrefresh) / + needed_prefill_lines = (vrefresh > fixed_prefill_fps) ? + ((default_prefill_lines * vrefresh) / fixed_prefill_fps) : default_prefill_lines; needed_vfp_lines = needed_prefill_lines - start_of_frame_lines; /* Fetch must be outside active lines, otherwise undefined. */ if (start_of_frame_lines >= needed_prefill_lines) { SDE_DEBUG_VIDENC(vid_enc, - "prog fetch is not needed, large vbp+vsw\n"); - actual_vfp_lines = 0; + "prog fetch always enabled case\n"); + actual_vfp_lines = (m->delay_prg_fetch_start) ? 2 : 1; } else if (v_front_porch < needed_vfp_lines) { /* Warn fetch needed, but not enough porch in panel config */ pr_warn_once @@ -239,7 +245,7 @@ static u32 programmable_fetch_get_num_lines( SDE_DEBUG_VIDENC(vid_enc, "vrefresh:%u v_front_porch:%u v_back_porch:%u vsync_pulse_width:%u\n", - timing->vrefresh, v_front_porch, timing->v_back_porch, + vrefresh, v_front_porch, timing->v_back_porch, timing->vsync_pulse_width); SDE_DEBUG_VIDENC(vid_enc, "prefill_lines:%u needed_vfp_lines:%u actual_vfp_lines:%u\n", From fcd859f926565161ea116d0a5f46127ef5c3bcbb Mon Sep 17 00:00:00 2001 From: Narendra Muppalla Date: Thu, 10 Dec 2020 13:02:11 -0800 Subject: [PATCH 007/116] disp: msm: sde: use different spin lock for frame events Due to lock sequence inconsistency between sde_crtc->spin_lock and sde_kms->hw_intr->irq_lock can cause deadlock, to avoid this possible deadlock this change uses different spin lock for frame events. Change-Id: I51b1184dfa1069c87653099b95b992b277721daf Signed-off-by: Narendra Muppalla --- msm/sde/sde_crtc.c | 11 ++++++----- msm/sde/sde_crtc.h | 4 +++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 50c64f3ad3a2..d8dbc1569180 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -2232,12 +2232,12 @@ static void sde_crtc_frame_event_cb(void *data, u32 event) SDE_DEBUG("crtc%d\n", crtc->base.id); SDE_EVT32_VERBOSE(DRMID(crtc), event); - spin_lock_irqsave(&sde_crtc->spin_lock, flags); + spin_lock_irqsave(&sde_crtc->fevent_spin_lock, flags); fevent = list_first_entry_or_null(&sde_crtc->frame_event_list, struct sde_crtc_frame_event, list); if (fevent) list_del_init(&fevent->list); - spin_unlock_irqrestore(&sde_crtc->spin_lock, flags); + spin_unlock_irqrestore(&sde_crtc->fevent_spin_lock, flags); if (!fevent) { SDE_ERROR("crtc%d event %d overflow\n", @@ -2536,9 +2536,9 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) SDE_ERROR("crtc%d ts:%lld received panel dead event\n", crtc->base.id, ktime_to_ns(fevent->ts)); - spin_lock_irqsave(&sde_crtc->spin_lock, flags); + spin_lock_irqsave(&sde_crtc->fevent_spin_lock, flags); list_add_tail(&fevent->list, &sde_crtc->frame_event_list); - spin_unlock_irqrestore(&sde_crtc->spin_lock, flags); + spin_unlock_irqrestore(&sde_crtc->fevent_spin_lock, flags); SDE_ATRACE_END("crtc_frame_event"); } @@ -6591,6 +6591,7 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane) mutex_init(&sde_crtc->crtc_lock); spin_lock_init(&sde_crtc->spin_lock); + spin_lock_init(&sde_crtc->fevent_spin_lock); atomic_set(&sde_crtc->frame_pending, 0); sde_crtc->enabled = false; diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 7892d50f9e5f..bb7fa3b82010 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -259,7 +259,8 @@ struct sde_crtc_misr_info { * @frame_pending : Whether or not an update is pending * @frame_events : static allocation of in-flight frame events * @frame_event_list : available frame event list - * @spin_lock : spin lock for frame event, transaction status, etc... + * @spin_lock : spin lock for transaction status, etc... + * @fevent_spin_lock : spin lock for frame event * @event_thread : Pointer to event handler thread * @event_worker : Event worker queue * @event_cache : Local cache of event worker structures @@ -342,6 +343,7 @@ struct sde_crtc { struct sde_crtc_frame_event frame_events[SDE_CRTC_FRAME_EVENT_SIZE]; struct list_head frame_event_list; spinlock_t spin_lock; + spinlock_t fevent_spin_lock; /* for handling internal event thread */ struct sde_crtc_event event_cache[SDE_CRTC_MAX_EVENT_COUNT]; From 72ad7c669ba7f818a2c6fa0baca9876071f577dc Mon Sep 17 00:00:00 2001 From: Bang Nguyen Date: Wed, 24 Jul 2019 08:05:26 -0500 Subject: [PATCH 008/116] disp: msm: dsi: Add support display 2bytes brightness. Normal, there is a brightness level from 0-255 (1 byte), but some panels are support 2 bytes for brightness, (0-1023). Change-Id: I861aaa3d26e4dbe13183df92f408fdefa709fe61 Reviewed-on: https://gerrit.mot.com/1697222 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Shuo Yan Reviewed-by: Guobin Zhang Submit-Approved: Jira Key --- msm/dsi/dsi_panel.c | 15 ++++++++++++++- msm/dsi/dsi_panel.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index b98447056ce3..2b8a53819195 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -543,6 +543,8 @@ static int dsi_panel_update_backlight(struct dsi_panel *panel, int rc = 0; unsigned long mode_flags = 0; struct mipi_dsi_device *dsi = NULL; + struct dsi_backlight_config *bl = &panel->bl_config; + u32 bl_lvl_2bytes; if (!panel || (bl_lvl > 0xffff)) { DSI_ERR("invalid params\n"); @@ -558,7 +560,13 @@ static int dsi_panel_update_backlight(struct dsi_panel *panel, if (panel->bl_config.bl_inverted_dbv) bl_lvl = (((bl_lvl & 0xff) << 8) | (bl_lvl >> 8)); - rc = mipi_dsi_dcs_set_display_brightness(dsi, bl_lvl); + if (bl->bl_2bytes_enable){ + bl_lvl_2bytes = ((bl_lvl & 0xff00) >> 8) | ((bl_lvl & 0xff) << 8); + rc = mipi_dsi_dcs_set_display_brightness(dsi, bl_lvl_2bytes); + } + else + rc = mipi_dsi_dcs_set_display_brightness(dsi, bl_lvl); + if (rc < 0) DSI_ERR("failed to update dcs backlight:%d\n", bl_lvl); @@ -2455,6 +2463,11 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) else DSI_ERR("bl-dsc-cmd-state command state unrecognized-%s\n", state); + panel->bl_config.bl_2bytes_enable = utils->read_bool(utils->data, + "qcom,bklt-dcs-2bytes-enabled"); + + pr_info("[%s] bl_2bytes_enable=%d\n", panel->name, + panel->bl_config.bl_2bytes_enable); if (panel->bl_config.type == DSI_BACKLIGHT_PWM) { rc = dsi_panel_parse_bl_pwm_config(panel); diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index 3fc6baf9fd13..baa82d2f7fbf 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -118,6 +118,7 @@ struct dsi_backlight_config { enum dsi_backlight_type type; enum bl_update_flag bl_update; + bool bl_2bytes_enable; u32 bl_min_level; u32 bl_max_level; u32 brightness_max_level; From b6b7d7770441b7bb26c1255e62a8f197b6bb0f52 Mon Sep 17 00:00:00 2001 From: Bang Nguyen Date: Thu, 25 Jul 2019 10:11:43 -0500 Subject: [PATCH 009/116] disp: msm: dsi: add prints for DSI/panel turning off/on Add some pr_info to indicate the DSI and panel are turning off and on for ESD or black screen investigation. Port from: 8c661f3540990aa1c37f1ef9b5b361114eec86ce Signed-off-by: Bang Nguyen Change-Id: I7c05aa6b0cf8f0128c8421d58d5a22647fd1b164 Reviewed-on: https://gerrit.mot.com/1697229 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Shuo Yan Reviewed-by: Guobin Zhang Submit-Approved: Jira Key --- msm/dsi/dsi_display.c | 2 ++ msm/dsi/dsi_panel.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 229643bf9b88..5d0767ac4936 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -7890,6 +7890,7 @@ int dsi_display_prepare(struct dsi_display *display) return -EINVAL; } + DSI_INFO("%s(%s)+\n", __func__, display->drm_conn->name); SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY); mutex_lock(&display->display_lock); @@ -8560,6 +8561,7 @@ int dsi_display_disable(struct dsi_display *display) return -EINVAL; } + DSI_INFO("%s(%s)+\n", __func__, display->drm_conn->name); SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY); mutex_lock(&display->display_lock); diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 2b8a53819195..0a65a9135086 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -338,6 +338,7 @@ static int dsi_panel_power_on(struct dsi_panel *panel) { int rc = 0; + DSI_INFO("%s(%s)+\n", __func__, panel->name); rc = dsi_pwr_enable_regulator(&panel->power_info, true); if (rc) { DSI_ERR("[%s] failed to enable vregs, rc=%d\n", @@ -383,6 +384,7 @@ static int dsi_panel_power_off(struct dsi_panel *panel) DSI_DEBUG("TWM Enabled, skip panel power off\n"); return rc; } + DSI_INFO("%s(%s)+\n", __func__, panel->name); if (gpio_is_valid(panel->reset_config.disp_en_gpio)) gpio_set_value(panel->reset_config.disp_en_gpio, 0); @@ -2466,7 +2468,7 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) panel->bl_config.bl_2bytes_enable = utils->read_bool(utils->data, "qcom,bklt-dcs-2bytes-enabled"); - pr_info("[%s] bl_2bytes_enable=%d\n", panel->name, + DSI_INFO("[%s] bl_2bytes_enable=%d\n", panel->name, panel->bl_config.bl_2bytes_enable); if (panel->bl_config.type == DSI_BACKLIGHT_PWM) { @@ -4685,6 +4687,7 @@ int dsi_panel_enable(struct dsi_panel *panel) return -EINVAL; } + DSI_INFO("%s(%s)+\n", __func__, panel->name); mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_ON); @@ -4758,6 +4761,7 @@ int dsi_panel_disable(struct dsi_panel *panel) DSI_DEBUG("TWM Enabled, skip panel disable\n"); return rc; } + DSI_INFO("%s(%s)+\n", __func__, panel->name); mutex_lock(&panel->panel_lock); /* Avoid sending panel off commands when ESD recovery is underway */ From 0fc8989fbd0840897e7ceddd6fe2cd21551c0a63 Mon Sep 17 00:00:00 2001 From: Bang Nguyen Date: Wed, 24 Jul 2019 14:31:35 -0500 Subject: [PATCH 010/116] disp: msm: dsi: Add "bl_ctrl_dummy" to panel bl type Add a new display's backlight type "bl_ctrl_dummy". With this backlight type, the panel backlight driver will ignore any backlight requests. This new backlight type will be used with a bare_board or no-display configuration and the display driver doesn't need to have any communication with panel. Port from: (CR). Change-Id: I1b0c2759deaa4b0808fd4f0503943a191842235e Signed-off-by: Bang Nguyen Reviewed-on: https://gerrit.mot.com/1697250 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Shuo Yan Reviewed-by: Guobin Zhang Submit-Approved: Jira Key --- msm/dsi/dsi_panel.c | 9 +++++++++ msm/dsi/dsi_panel.h | 1 + 2 files changed, 10 insertions(+) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 0a65a9135086..3261ea91253f 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -645,6 +645,9 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) case DSI_BACKLIGHT_DCS: rc = dsi_panel_update_backlight(panel, bl_lvl); break; + case DSI_BACKLIGHT_DUMMY: + rc = 0; + break; case DSI_BACKLIGHT_EXTERNAL: break; case DSI_BACKLIGHT_PWM: @@ -732,6 +735,8 @@ static int dsi_panel_bl_register(struct dsi_panel *panel) break; case DSI_BACKLIGHT_DCS: break; + case DSI_BACKLIGHT_DUMMY: + break; case DSI_BACKLIGHT_EXTERNAL: break; case DSI_BACKLIGHT_PWM: @@ -767,6 +772,8 @@ static int dsi_panel_bl_unregister(struct dsi_panel *panel) break; case DSI_BACKLIGHT_DCS: break; + case DSI_BACKLIGHT_DUMMY: + break; case DSI_BACKLIGHT_EXTERNAL: break; case DSI_BACKLIGHT_PWM: @@ -2403,6 +2410,8 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) panel->bl_config.type = DSI_BACKLIGHT_WLED; } else if (!strcmp(bl_type, "bl_ctrl_dcs")) { panel->bl_config.type = DSI_BACKLIGHT_DCS; + } else if (!strcmp(bl_type, "bl_ctrl_dummy")) { + panel->bl_config.type = DSI_BACKLIGHT_DUMMY; } else if (!strcmp(bl_type, "bl_ctrl_external")) { panel->bl_config.type = DSI_BACKLIGHT_EXTERNAL; } else { diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index baa82d2f7fbf..2379206924f4 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -48,6 +48,7 @@ enum dsi_backlight_type { DSI_BACKLIGHT_PWM = 0, DSI_BACKLIGHT_WLED, DSI_BACKLIGHT_DCS, + DSI_BACKLIGHT_DUMMY, DSI_BACKLIGHT_EXTERNAL, DSI_BACKLIGHT_UNKNOWN, DSI_BACKLIGHT_MAX, From 5e7ff8e6bd9fcfdc1e28505ed6b83a8bad25fb72 Mon Sep 17 00:00:00 2001 From: Bang Nguyen Date: Thu, 25 Jul 2019 10:15:12 -0500 Subject: [PATCH 011/116] disp: msm: sde: Change display ESD checking interval to 8s Change the ESD detection and recovery interval to 8 second Port from: 9679d374c0f7229febbd23cd5531694a9faf6c6c Change-Id: Iad8b11db9a5794fa10e32a52035456f32ee0d304 Reviewed-on: https://gerrit.mot.com/1697251 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Shuo Yan Reviewed-by: Guobin Zhang Submit-Approved: Jira Key --- msm/sde/sde_kms.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/sde/sde_kms.h b/msm/sde/sde_kms.h index db50ede366ce..2322880079e9 100644 --- a/msm/sde/sde_kms.h +++ b/msm/sde/sde_kms.h @@ -126,7 +126,7 @@ #define SDE_KMS_OPS_PREPARE_PLANE_FB BIT(3) /* ESD status check interval in miliseconds */ -#define STATUS_CHECK_INTERVAL_MS 5000 +#define STATUS_CHECK_INTERVAL_MS 8000 /** * enum sde_kms_smmu_state: smmu state From 0223f45a59856b4b2b4bab8d0568ac0de92ef7bd Mon Sep 17 00:00:00 2001 From: Bang Nguyen Date: Thu, 25 Jul 2019 12:56:02 -0500 Subject: [PATCH 012/116] disp: msm: dsi: parsing BL setting ESD and panel After the Boot Loader (BL) detects the panel information, or reading the ESD UTAG setting, the BL will write these information to the DTS. The display driver from kernel and parse and save these setting. Port from: 2701eb2 Change-Id: Ibd1c9429854655ea7c80222ce64c3b86c6df2eda Signed-off-by: Bang Nguyen Reviewed-on: https://gerrit.mot.com/1697267 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Shuo Yan Reviewed-by: Guobin Zhang Submit-Approved: Jira Key --- msm/dsi/dsi_panel.c | 47 + msm/dsi/dsi_panel.c.orig | 4743 ++++++++++++++++++++++++++++++++++++++ msm/dsi/dsi_panel.h | 5 + 3 files changed, 4795 insertions(+) create mode 100644 msm/dsi/dsi_panel.c.orig diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 3261ea91253f..96fbb6e1d525 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -36,6 +36,8 @@ #define DEFAULT_PANEL_PREFILL_LINES 25 #define HIGH_REFRESH_RATE_THRESHOLD_TIME_US 500 #define MIN_PREFILL_LINES 40 +#define DSI_PANEL_UNKNOWN_PANEL_NAME "unknown" +#define DSI_PANEL_PANEL_DEFAULT_VER 0xffffffffffffffff static void dsi_dce_prepare_pps_header(char *buf, u32 pps_delay_ms) { @@ -1425,6 +1427,45 @@ static int dsi_panel_parse_dyn_clk_caps(struct dsi_panel *panel) return 0; } +static int dsi_panel_parse_panel_cfg(struct dsi_panel *panel) +{ + struct device_node *np; + const char *pname; + u32 panel_ver, tmp; + + np = of_find_node_by_path("/chosen"); + /* Disable ESD only if the prop "mmi,esd" exists and is equal to 0 */ + if (!of_property_read_u32(np, "mmi,esd", &tmp) && tmp == 0) { + panel->esd_utag_enable = false; + DSI_WARN("ESD detection is disabled by UTAGS\n"); + } else + panel->esd_utag_enable = true; + + panel->panel_ver = DSI_PANEL_PANEL_DEFAULT_VER; + of_property_read_u64(np, "mmi,panel_ver", &panel->panel_ver); + + pname = of_get_property(np, "mmi,panel_name", NULL); + if (!pname || strlen(pname) == 0) { + DSI_WARN("Failed to get mmi,panel_name\n"); + strlcpy(panel->panel_name, DSI_PANEL_UNKNOWN_PANEL_NAME, + sizeof(panel->panel_name)); + } else + strlcpy(panel->panel_name, pname, sizeof(panel->panel_name)); + + DSI_DEBUG("esd_utage_enable=%d\n", panel->esd_utag_enable); + + panel_ver = (u32)panel->panel_ver; + DSI_INFO("BL: panel = %s, manufacture_id(0xDA) = 0x%x controller_ver(0xDB) = 0x%x controller_drv_ver(0XDC) = 0x%x, full = 0x%016llx\n", + panel->panel_name, + panel_ver & 0xff, (panel_ver & 0xff00) >> 8, + (panel_ver & 0xff0000) >> 16, + panel->panel_ver); + + of_node_put(np); + + return 0; +} + static int dsi_panel_parse_dfps_caps(struct dsi_panel *panel) { int rc = 0; @@ -3548,6 +3589,12 @@ struct dsi_panel *dsi_panel_get(struct device *parent, goto error; } + rc = dsi_panel_parse_panel_cfg(panel); + if (rc) { + pr_err("failed to parse panel config from dts. rc=%d\n", rc); + goto error; + } + rc = dsi_panel_parse_dfps_caps(panel); if (rc) DSI_ERR("failed to parse dfps configuration, rc=%d\n", rc); diff --git a/msm/dsi/dsi_panel.c.orig b/msm/dsi/dsi_panel.c.orig new file mode 100644 index 000000000000..0c3c292a35de --- /dev/null +++ b/msm/dsi/dsi_panel.c.orig @@ -0,0 +1,4743 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include