From be08b4e4510978766bd14f74eaf38e52058785b6 Mon Sep 17 00:00:00 2001 From: Satya Rama Aditya Pinapala Date: Mon, 21 Oct 2019 13:47:52 -0700 Subject: [PATCH 01/14] disp: msm: add check for buffer length before copy Length of the buffer to be copied is checked against both source and destination buffer lengths before copying. This ensures that there is no buffer overflow while reading as well as writing. Change-Id: I4bd1a5892b47771aef4c23a4d1594fc1c8361577 Signed-off-by: Satya Rama Aditya Pinapala --- msm/dsi/dsi_ctrl.c | 5 +++++ msm/sde/sde_connector.c | 5 ++++- msm/sde_rsc.c | 10 ++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 599e8a9f5e90..b922bb259d2f 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -116,6 +116,9 @@ static ssize_t debugfs_state_info_read(struct file *file, dsi_ctrl->clk_freq.pix_clk_rate, dsi_ctrl->clk_freq.esc_clk_rate); + if (len > count) + len = count; + len = min_t(size_t, len, SZ_4K); if (copy_to_user(buff, buf, len)) { kfree(buf); @@ -171,6 +174,8 @@ static ssize_t debugfs_reg_dump_read(struct file *file, return rc; } + if (len > count) + len = count; len = min_t(size_t, len, SZ_4K); if (copy_to_user(buff, buf, len)) { diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index c45dc8ca521e..7681aa031109 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -1731,7 +1731,10 @@ static ssize_t _sde_debugfs_conn_cmd_tx_sts_read(struct file *file, return 0; } - blen = min_t(size_t, MAX_CMD_PAYLOAD_SIZE, count); + if (blen > count) + blen = count; + + blen = min_t(size_t, blen, MAX_CMD_PAYLOAD_SIZE); if (copy_to_user(buf, buffer, blen)) { SDE_ERROR("copy to user buffer failed\n"); return -EFAULT; diff --git a/msm/sde_rsc.c b/msm/sde_rsc.c index ed380bcbf9b6..10b17372d124 100644 --- a/msm/sde_rsc.c +++ b/msm/sde_rsc.c @@ -1105,7 +1105,10 @@ end: if (blen <= 0) return 0; - blen = min_t(size_t, MAX_BUFFER_SIZE, count); + if (blen > count) + blen = count; + + blen = min_t(size_t, blen, MAX_BUFFER_SIZE); if (copy_to_user(buf, buffer, blen)) return -EFAULT; @@ -1199,7 +1202,10 @@ end: if (blen <= 0) return 0; - blen = min_t(size_t, MAX_BUFFER_SIZE, count); + if (blen > count) + blen = count; + + blen = min_t(size_t, blen, MAX_BUFFER_SIZE); if (copy_to_user(buf, buffer, blen)) return -EFAULT; From 169ec403f1ff3718497bf01c726a7d183de01b3c Mon Sep 17 00:00:00 2001 From: Tatenda Chipeperekwa Date: Thu, 17 Oct 2019 15:42:45 -0700 Subject: [PATCH 02/14] disp: msm: dp: skip wait if audio engine is disabled Skip the wait in the disable path if the audio engine has already been disabled or was not previously enabled. This avoids an unnecessary wait since the audio subsystem will only acknowledge the notification and not request a tear down if no audio playback was started by the user. CRs-Fixed: 2550150 Change-Id: I7b47345430f3d9c63b80b0aa92cdc4dd77152da9 Signed-off-by: Tatenda Chipeperekwa --- msm/dp/dp_audio.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/msm/dp/dp_audio.c b/msm/dp/dp_audio.c index 61d13ca730cc..67f3741f9ddf 100644 --- a/msm/dp/dp_audio.c +++ b/msm/dp/dp_audio.c @@ -414,6 +414,9 @@ static int dp_audio_info_setup(struct platform_device *pdev, dp_audio_enable(audio, true); mutex_unlock(&audio->ops_lock); + + DP_DEBUG("audio stream configured\n"); + return rc; } @@ -671,8 +674,11 @@ static int dp_audio_notify(struct dp_audio_private *audio, u32 state) if (atomic_read(&audio->acked)) goto end; - if (state == EXT_DISPLAY_CABLE_CONNECT) - goto end; + if (state == EXT_DISPLAY_CABLE_DISCONNECT && !audio->engine_on) + goto end; + + if (state == EXT_DISPLAY_CABLE_CONNECT) + goto end; rc = wait_for_completion_timeout(&audio->hpd_comp, HZ * 4); if (!rc) { From e7780e75260fc59d8ba9d88fc268668ab03066ec Mon Sep 17 00:00:00 2001 From: Sankeerth Billakanti Date: Wed, 30 Oct 2019 11:39:12 +0530 Subject: [PATCH 03/14] disp: msm: dp: perform host_init/deinit to reset abort When doing multiple immediate plug-unplug, the DP display driver is waiting for a link training to exhaust the retry count before processing the disconnect request while flushing the connect_work. The driver should stop link training and exit if the link is disconnected. This change will use the ctrl_aborted flag to early return from link training and perform the host init/deinit and host ready/unready in pairs while handling connect/disconnect to reset the abort flags for the next connect. Change-Id: If321136ecf12ab2f67d13ef841f1590142aad406 Signed-off-by: Sankeerth Billakanti --- msm/dp/dp_ctrl.c | 7 +++++-- msm/dp/dp_display.c | 7 ++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/msm/dp/dp_ctrl.c b/msm/dp/dp_ctrl.c index d12ba536810f..e4248297fd92 100644 --- a/msm/dp/dp_ctrl.c +++ b/msm/dp/dp_ctrl.c @@ -1280,11 +1280,14 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode, ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); - atomic_set(&ctrl->aborted, 0); - if (ctrl->power_on) goto end; + if (atomic_read(&ctrl->aborted)) { + rc = -EPERM; + goto end; + } + ctrl->mst_mode = mst_mode; if (fec_mode) { ctrl->fec_mode = fec_mode; diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index 45b1a689ca2e..2e158b396f08 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -859,7 +859,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp->dp_display.max_pclk_khz = min(dp->parser->max_pclk_khz, dp->debug->max_pclk_khz); - + dp_display_host_init(dp); dp_display_host_ready(dp); dp->link->psm_config(dp->link, &dp->panel->link_info, false); @@ -1084,6 +1084,7 @@ static int dp_display_handle_disconnect(struct dp_display_private *dp) dp_display_clean(dp); dp_display_host_unready(dp); + dp_display_host_deinit(dp); mutex_unlock(&dp->session_lock); @@ -1131,10 +1132,6 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev) dp_display_disconnect_sync(dp); - mutex_lock(&dp->session_lock); - dp_display_host_deinit(dp); - mutex_unlock(&dp->session_lock); - if (!dp->debug->sim_mode && !dp->parser->no_aux_switch && !dp->parser->gpio_aux_switch) dp->aux->aux_switch(dp->aux, false, ORIENTATION_NONE); From 4de15bb6efbb91a6512ce214202d9ddbf14a50d5 Mon Sep 17 00:00:00 2001 From: Samantha Tran Date: Fri, 25 Oct 2019 14:27:04 -0700 Subject: [PATCH 04/14] disp: msm: sde: check all dirty properties during plane update Previously when updating a plane's dirty features, if the dirty all flag was set, the optimization was to break early. This optimization left out color property updates for that plane. This fix removes the mutex locks in the msm_prop function so the break optimization is no longer needed. Function callers will now need to acquire the lock and unlock the property lock when done. Now the plane will iterate through all dirty properties. Change-Id: I3114ac44d62ac0f0633897d757b6fd9a5b1f5d2e Signed-off-by: Samantha Tran --- msm/msm_prop.c | 4 ++-- msm/msm_prop.h | 4 +++- msm/sde/sde_connector.c | 2 ++ msm/sde/sde_plane.c | 5 ++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/msm/msm_prop.c b/msm/msm_prop.c index eb17f5f72eb7..d7c9eb0f8475 100644 --- a/msm/msm_prop.c +++ b/msm/msm_prop.c @@ -77,7 +77,8 @@ int msm_property_pop_dirty(struct msm_property_info *info, return -EINVAL; } - mutex_lock(&info->property_lock); + WARN_ON(!mutex_is_locked(&info->property_lock)); + if (list_empty(&property_state->dirty_list)) { rc = -EAGAIN; } else { @@ -87,7 +88,6 @@ int msm_property_pop_dirty(struct msm_property_info *info, - property_state->values; DRM_DEBUG_KMS("property %d dirty\n", rc); } - mutex_unlock(&info->property_lock); return rc; } diff --git a/msm/msm_prop.h b/msm/msm_prop.h index db2ad988d0c0..6069aaaa5003 100644 --- a/msm/msm_prop.h +++ b/msm/msm_prop.h @@ -162,7 +162,9 @@ bool msm_property_get_is_active(struct msm_property_info *info) /** * msm_property_pop_dirty - determine next dirty property and clear - * its dirty flag + * its dirty flag. Caller needs to acquire property + * lock before calling this function and release + * the lock when finished. * @info: Pointer to property info container struct * @property_state: Pointer to property state container struct * Returns: Valid msm property index on success, diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 7da379b92ce8..dd1744db4698 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -701,6 +701,7 @@ static int _sde_connector_update_dirty_properties( c_conn = to_sde_connector(connector); c_state = to_sde_connector_state(connector->state); + mutex_lock(&c_conn->property_info.property_lock); while ((idx = msm_property_pop_dirty(&c_conn->property_info, &c_state->property_state)) >= 0) { switch (idx) { @@ -723,6 +724,7 @@ static int _sde_connector_update_dirty_properties( break; } } + mutex_unlock(&c_conn->property_info.property_lock); /* if colorspace needs to be updated do it first */ if (c_conn->colorspace_updated) { diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index e9c3a0cf8c8b..c07831702623 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -3182,14 +3182,13 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, } /* determine what needs to be refreshed */ + mutex_lock(&psde->property_info.property_lock); while ((idx = msm_property_pop_dirty(&psde->property_info, &pstate->property_state)) >= 0) { dirty_prop_flag = plane_prop_array[idx]; pstate->dirty |= dirty_prop_flag; - - if (dirty_prop_flag == SDE_PLANE_DIRTY_ALL) - break; } + mutex_unlock(&psde->property_info.property_lock); /** * since plane_atomic_check is invoked before crtc_atomic_check From 423fb3468dd46b17db9e719c4b3b8b0b5bb6ede8 Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Tue, 29 Oct 2019 13:46:38 -0400 Subject: [PATCH 05/14] disp: msm: sde: update clk rate for perf mode This updates the mdp clock rate immediately, instead of waiting for the next frame trigger. Change-Id: I5d58a1f1200fff143b363e89e8c49f6e7d8d14c7 Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_core_perf.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/msm/sde/sde_core_perf.c b/msm/sde/sde_core_perf.c index 3efd37746cce..c8d3b0c8f70e 100644 --- a/msm/sde/sde_core_perf.c +++ b/msm/sde/sde_core_perf.c @@ -992,6 +992,7 @@ static ssize_t _sde_core_perf_mode_write(struct file *file, struct sde_perf_cfg *cfg = &perf->catalog->perf; u32 perf_mode = 0; char buf[10]; + int ret = 0; if (!perf) return -ENODEV; @@ -1017,6 +1018,13 @@ static ssize_t _sde_core_perf_mode_write(struct file *file, perf->perf_tune.min_core_clk = perf->max_core_clk_rate; perf->perf_tune.min_bus_vote = (u64) cfg->max_bw_high * 1000; + + ret = sde_power_clk_set_rate(perf->phandle, + perf->clk_name, perf->max_core_clk_rate); + if (ret) + SDE_ERROR("failed to set %s clock rate %llu\n", + perf->clk_name, + perf->max_core_clk_rate); DRM_INFO("minimum performance mode\n"); } else if (perf_mode == SDE_PERF_MODE_NORMAL) { /* reset the perf tune params to 0 */ From 1195a394b1e3dba05468bbe8556302b6b832318f Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Wed, 30 Oct 2019 10:42:52 -0400 Subject: [PATCH 06/14] Revert "disp: msm: sde: update splash resource allocation for dual display" This reverts commit dbb1a3eee9c1537610a5968b2027017dcde16a74. This change causes regression in populating cont splash data for RM. Change-Id: If239eb921e022fcad54033ae3c7e9e4c3dc54736 Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_rm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index 4edb09f62f01..2b9d51bd3470 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -1735,8 +1735,8 @@ int sde_rm_cont_splash_res_init(struct msm_drm_private *priv, splash_display->cont_splash_enabled = true; splash_display->ctl_ids[splash_display->ctl_cnt++] = iter_c.blk->id; - index++; } + index++; } return 0; From c404a2f158e513028bbbdec42bd490338ab1d092 Mon Sep 17 00:00:00 2001 From: Satya Rama Aditya Pinapala Date: Wed, 30 Oct 2019 10:52:15 -0700 Subject: [PATCH 07/14] disp: msm: dsi: check bit clock before bypassing clock set during DMS This change ensures that if the dsi clock rate is not specified in the timing modes, setting clkrate_change_pending is not bypassed. Change-Id: I2475da1e548f29c68a6a4466c5ef540f7f11d553 Signed-off-by: Satya Rama Aditya Pinapala --- 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 8c799f00836c..f2435fee1876 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -4520,7 +4520,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, commit_phy_timing = true; /* No need to set clkrate pending flag if clocks are same */ - if (cur_bitclk != to_bitclk) + if ((!cur_bitclk && !to_bitclk) || (cur_bitclk != to_bitclk)) atomic_set(&display->clkrate_change_pending, 1); dsi_display_validate_dms_fps(display->panel->cur_mode, mode); From b0df721f2d325c36b0f56c9c5e3a88302493b308 Mon Sep 17 00:00:00 2001 From: Ravikanth Tuniki Date: Thu, 31 Oct 2019 15:37:48 +0530 Subject: [PATCH 08/14] disp: msm: sde: Use platform independent API for 64-bit div 64-bit division( operator "/") on 32-bit platforms is not supported. Using platform independent API's here. Change-Id: I1ec71ac120bb29b7f0bceed581b979606f81e2a5 Signed-off-by: Ravikanth Tuniki --- msm/sde/sde_encoder.c | 5 +++-- msm/sde/sde_encoder_phys_cmd.c | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index a1c9182ff8d3..dad979f09b4b 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -5716,8 +5716,9 @@ void sde_encoder_helper_get_jitter_bounds_ns(struct drm_encoder *drm_enc, info = &sde_enc->mode_info; frametime_ns = (1 * 1000000000) / info->frame_rate; - jitter_ns = (info->jitter_numer * frametime_ns) / - (info->jitter_denom * 100); + jitter_ns = info->jitter_numer * frametime_ns; + do_div(jitter_ns, info->jitter_denom * 100); + *l_bound = frametime_ns - jitter_ns; *u_bound = frametime_ns + jitter_ns; } diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index ba1c6ac84492..23232b03830d 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -1398,9 +1398,12 @@ static bool _sde_encoder_phys_cmd_needs_vsync_change( "time_diff:%llu, prev:%llu, cur:%llu, jitter:%llu/%llu\n", time_diff, prev->timestamp, cur->timestamp, l_bound, u_bound); + time_diff = div_s64(time_diff, 1000); + SDE_EVT32(DRMID(phys_enc->parent), - (u32) (l_bound / 1000), (u32) (u_bound / 1000), - (u32) (time_diff / 1000), SDE_EVTLOG_ERROR); + (u32) (do_div(l_bound, 1000)), + (u32) (do_div(u_bound, 1000)), + (u32) (time_diff), SDE_EVTLOG_ERROR); } return ret; From b1c9d65e3d63c44ce14edc72a9a6aa5d75cca333 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Thu, 24 Oct 2019 16:49:42 -0700 Subject: [PATCH 09/14] disp: msm: sde: fix video mode prefill lines for RSCC The RSCC static wakeup and the bandwidth trigger for the downvotes are based on the prefill lines. Reduce the prefill lines based on the panel vertical front porch to avoid issuing bw downvotes during active region of the previous frame. Change-Id: I408209ba308c32e71d9f70c5ed7e60c134877c84 Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_encoder.c | 26 +++++++++++++++++++++----- msm/sde_rsc.c | 3 +-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 6dba660106e0..8f45613653a7 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1928,11 +1928,13 @@ static int _sde_encoder_update_rsc_client( struct drm_crtc *crtc; enum sde_rsc_state rsc_state = SDE_RSC_IDLE_STATE; struct sde_rsc_cmd_config *rsc_config; - int ret, prefill_lines; + int ret; struct msm_display_info *disp_info; struct msm_mode_info *mode_info; int wait_vblank_crtc_id = SDE_RSC_INVALID_CRTC_ID; - u32 qsync_mode = 0; + u32 qsync_mode = 0, v_front_porch; + struct drm_display_mode *mode; + bool is_vid_mode; if (!drm_enc || !drm_enc->dev) { SDE_ERROR("invalid encoder arguments\n"); @@ -1977,17 +1979,31 @@ static int _sde_encoder_update_rsc_client( SDE_EVT32(rsc_state, qsync_mode); - prefill_lines = mode_info->prefill_lines; + is_vid_mode = sde_encoder_check_curr_mode(&sde_enc->base, + MSM_DISPLAY_VIDEO_MODE); + mode = &sde_enc->crtc->state->mode; + v_front_porch = mode->vsync_start - mode->vdisplay; /* compare specific items and reconfigure the rsc */ if ((rsc_config->fps != mode_info->frame_rate) || (rsc_config->vtotal != mode_info->vtotal) || - (rsc_config->prefill_lines != prefill_lines) || + (rsc_config->prefill_lines != mode_info->prefill_lines) || (rsc_config->jitter_numer != mode_info->jitter_numer) || (rsc_config->jitter_denom != mode_info->jitter_denom)) { + rsc_config->fps = mode_info->frame_rate; rsc_config->vtotal = mode_info->vtotal; - rsc_config->prefill_lines = prefill_lines; + /* + * for video mode, prefill lines should not go beyond vertical + * front porch for RSCC configuration. This will ensure bw + * downvotes are not sent within the active region. Additional + * -1 is to give one line time for rscc mode min_threshold. + */ + if (is_vid_mode && (mode_info->prefill_lines >= v_front_porch)) + rsc_config->prefill_lines = v_front_porch - 1; + else + rsc_config->prefill_lines = mode_info->prefill_lines; + rsc_config->jitter_numer = mode_info->jitter_numer; rsc_config->jitter_denom = mode_info->jitter_denom; sde_enc->rsc_state_init = false; diff --git a/msm/sde_rsc.c b/msm/sde_rsc.c index f60b7e4fe4e8..9e8710494492 100644 --- a/msm/sde_rsc.c +++ b/msm/sde_rsc.c @@ -311,8 +311,7 @@ static u32 sde_rsc_timer_calculate(struct sde_rsc_priv *rsc, default_prefill_lines = (rsc->cmd_config.fps * DEFAULT_PANEL_MIN_V_PREFILL) / DEFAULT_PANEL_FPS; - if ((state == SDE_RSC_CMD_STATE) || - (rsc->cmd_config.prefill_lines < default_prefill_lines)) + if ((state == SDE_RSC_CMD_STATE) || !rsc->cmd_config.prefill_lines) rsc->cmd_config.prefill_lines = default_prefill_lines; pr_debug("frame fps:%d jitter_numer:%d jitter_denom:%d vtotal:%d prefill lines:%d\n", From a823531c33f0b3f34afdc326e56c1f38209f2643 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Wed, 30 Oct 2019 17:36:17 -0700 Subject: [PATCH 10/14] disp: msm: sde: handle another case for lost pp-done interrupt Due to interrupt delays, sometimes the pp-done interrupt for an in-between frame is lost, as with posted-start frames are queued to the hardware before the completion of the previous frame. Handle the lost pp-done interrupt in the case where frame-n pp-done interrupt is missed and frame-n+1 pp-done interrupt is processed before frame-n+1 wr-ptr interrupt. Change-Id: I36ec7ac494b2720fc005dab75047d2f4a5a2a699 Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_encoder_phys_cmd.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index 7e9b3fb01d25..92410685f1a2 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -1345,10 +1345,11 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff( } SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); + phys_enc->frame_trigger_mode = params->frame_trigger_mode; SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, atomic_read(&phys_enc->pending_kickoff_cnt), - atomic_read(&cmd_enc->autorefresh.kickoff_cnt)); - phys_enc->frame_trigger_mode = params->frame_trigger_mode; + atomic_read(&cmd_enc->autorefresh.kickoff_cnt), + phys_enc->frame_trigger_mode); if (phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_DEFAULT) { /* @@ -1557,6 +1558,8 @@ static int sde_encoder_phys_cmd_wait_for_commit_done( int rc = 0, i, pending_cnt; struct sde_encoder_phys_cmd *cmd_enc; ktime_t profile_timestamp = ktime_get(); + u32 scheduler_status = INVALID_CTL_STATUS; + struct sde_hw_ctl *ctl; if (!phys_enc) return -EINVAL; @@ -1582,11 +1585,17 @@ static int sde_encoder_phys_cmd_wait_for_commit_done( if (cmd_enc->autorefresh.cfg.enable) rc = _sde_encoder_phys_cmd_wait_for_autorefresh_done( phys_enc); + + ctl = phys_enc->hw_ctl; + if (ctl && ctl->ops.get_scheduler_status) + scheduler_status = ctl->ops.get_scheduler_status(ctl); } /* wait for posted start or serialize trigger */ - if ((atomic_read(&phys_enc->pending_kickoff_cnt) > 1) || - (!rc && phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_SERIALIZE)) + pending_cnt = atomic_read(&phys_enc->pending_kickoff_cnt); + if ((pending_cnt > 1) || + (pending_cnt && (scheduler_status & BIT(0))) || + (!rc && phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_SERIALIZE)) goto wait_for_idle; return rc; @@ -1601,7 +1610,8 @@ wait_for_idle: phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->frame_trigger_mode, atomic_read(&phys_enc->pending_kickoff_cnt), - phys_enc->enable_state, rc); + phys_enc->enable_state, + cmd_enc->wr_ptr_wait_success, scheduler_status, rc); SDE_ERROR("pp:%d failed wait_for_idle: %d\n", phys_enc->hw_pp->idx - PINGPONG_0, rc); if (phys_enc->enable_state == SDE_ENC_ERR_NEEDS_HW_RESET) From 2d40a1b2a1d6d279b6da0855bd7a8841fc19548f Mon Sep 17 00:00:00 2001 From: Dhaval Patel Date: Thu, 31 Oct 2019 11:52:42 -0700 Subject: [PATCH 11/14] disp: msm: sde: fix uidle trace format configuration Uidle FAL1 and FAL10 counters use 32 bits and should be printed with hex format instead of signed integer format. Change-Id: I31e9a06314ef53bd2dab7ebd041f38c096e84120 Signed-off-by: Dhaval Patel --- msm/sde/sde_trace.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/msm/sde/sde_trace.h b/msm/sde/sde_trace.h index 9a8f414aa019..df6bd1507373 100644 --- a/msm/sde/sde_trace.h +++ b/msm/sde/sde_trace.h @@ -35,7 +35,7 @@ TRACE_EVENT(sde_perf_set_qos_luts, __entry->lut = lut; __entry->lut_usage = lut_usage; ), - TP_printk("pnum=%d fmt=%x rt=%d fl=%d lut=0x%llx lut_usage=%d", + TP_printk("pnum=%d fmt=0x%x rt=%d fl=%d lut=0x%llx lut_usage=%d", __entry->pnum, __entry->fmt, __entry->rt, __entry->fl, __entry->lut, __entry->lut_usage) @@ -59,7 +59,7 @@ TRACE_EVENT(sde_perf_set_danger_luts, __entry->danger_lut = danger_lut; __entry->safe_lut = safe_lut; ), - TP_printk("pnum=%d fmt=%x mode=%d luts[0x%x, 0x%x]", + TP_printk("pnum=%d fmt=0x%x mode=%d luts[0x%x, 0x%x]", __entry->pnum, __entry->fmt, __entry->mode, __entry->danger_lut, __entry->safe_lut) @@ -174,7 +174,7 @@ TRACE_EVENT(sde_evtlog, memset(&__entry->data[cnt], 0, (SDE_TRACE_EVTLOG_SIZE - cnt) * sizeof(u32)); ), - TP_printk("%d|%s:%d|%x|%x|%x|%x|%x|%x|%x|%x|%x|%x|%x|%x|%x|%x|%x", + TP_printk("%d|%s:%d|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x|0x%x", __entry->pid, __get_str(evtlog_tag), __entry->tag_id, __entry->data[0], __entry->data[1], @@ -336,7 +336,7 @@ TRACE_EVENT(sde_perf_uidle_cntr, __entry->max_gate_cntr = max_gate_cntr; ), TP_printk( - "crtc:%d gate:fal1=%d fal10=%d wait=%d min=%d max=%d trns:fal1=%d fal10=%d", + "crtc:%d gate:fal1=0x%x fal10=0x%x wait=0x%x min=0x%x max=0x%x trns:fal1=0x%x fal10=0x%x", __entry->crtc, __entry->fal1_gate_cntr, __entry->fal10_gate_cntr, @@ -396,7 +396,7 @@ TRACE_EVENT(sde_perf_uidle_status, __entry->uidle_status = uidle_status; __entry->uidle_en_fal10 = uidle_en_fal10;), TP_printk( - "crtc:%d danger[%d, %d] safe[%d, %d] idle[%d, %d] fal[%d, %d] status:%d en_fal10:%d", + "crtc:%d danger[0x%x, 0x%x] safe[0x%x, 0x%x] idle[0x%x, 0x%x] fal[0x%x, 0x%x] status:0x%x en_fal10:0x%x", __entry->crtc, __entry->uidle_danger_status_0, __entry->uidle_danger_status_1, From dd76462c66a39d7e2353a9a443e9cf82303a32f2 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Fri, 26 Jul 2019 16:22:06 -0700 Subject: [PATCH 12/14] disp: msm: sde: log bw info in event logs Add all the MNOC, LLCC & EBI bandwidth info in the eventlogs to help in debugging. Change-Id: Idca62ceed2d3a1b2e907f14c245e158cc46900c3 Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_core_perf.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/msm/sde/sde_core_perf.c b/msm/sde/sde_core_perf.c index c8d3b0c8f70e..eefe21aab692 100644 --- a/msm/sde/sde_core_perf.c +++ b/msm/sde/sde_core_perf.c @@ -26,6 +26,9 @@ #define SDE_PERF_MODE_STRING_SIZE 128 #define SDE_PERF_THRESHOLD_HIGH_MIN 12800000 +#define GET_H32(val) (val >> 32) +#define GET_L32(val) (val & 0xffffffff) + static DEFINE_MUTEX(sde_core_perf_lock); /** @@ -150,7 +153,20 @@ static void _sde_core_perf_calc_crtc(struct sde_kms *kms, perf->core_clk_rate); } - SDE_EVT32(crtc->base.id, perf->core_clk_rate); + SDE_EVT32(DRMID(crtc), perf->core_clk_rate, + GET_H32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC]), + GET_L32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC]), + GET_H32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC]), + GET_L32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC]), + GET_H32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI]), + GET_L32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI])); + SDE_EVT32(DRMID(crtc), + GET_H32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC]), + GET_L32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC]), + GET_H32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC]), + GET_L32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC]), + GET_H32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI]), + GET_L32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI])); trace_sde_perf_calc_crtc(crtc->base.id, perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC], perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC], From 810738f2322b05efbde585aab3c1f62adef45514 Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Thu, 31 Oct 2019 12:14:53 -0400 Subject: [PATCH 13/14] disp: msm: sde: null check for kms device Check if kms device objects exist before attempting to create memory space. Change-Id: Idc0cbfd0ce116dab8005f72ba231dcb8c82254ca Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_kms.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 21526db01f54..4ef852de478d 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2934,6 +2934,9 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms) int i, ret; int early_map = 0; + if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev) + return -EINVAL; + for (i = 0; i < MSM_SMMU_DOMAIN_MAX; i++) { struct msm_gem_address_space *aspace; From 62c99029357512edbe048ee799b01c3bb457047a Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Fri, 8 Nov 2019 19:03:34 +0530 Subject: [PATCH 14/14] disp: add rev checks for bengal target Add revision checks to support bengal target for dpu and rotation driver. Change-Id: I7eb8bd2943b94ab246889b1f74cd9613aeee2b2f Signed-off-by: Yashwanth --- msm/sde/sde_hw_catalog.c | 13 +++++++++++++ msm/sde/sde_hw_catalog.h | 2 ++ msm/sde/sde_hw_lm.c | 3 ++- msm/sde/sde_hw_vbif.c | 3 ++- rotator/sde_rotator_base.h | 1 + rotator/sde_rotator_r3.c | 15 +++++++++++++++ 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index eccd9efbaa72..6bb3bc0059cf 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -4235,6 +4235,19 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->sui_block_xin_mask = 0xC61; sde_cfg->has_hdr = false; sde_cfg->has_sui_blendstage = true; + } else if (IS_BENGAL_TARGET(hw_rev)) { + sde_cfg->has_cwb_support = false; + sde_cfg->has_qsync = true; + sde_cfg->perf.min_prefill_lines = 24; + sde_cfg->vbif_qos_nlvl = 8; + sde_cfg->ts_prefill_rev = 2; + sde_cfg->ctl_rev = SDE_CTL_CFG_VERSION_1_0_0; + sde_cfg->delay_prg_fetch_start = true; + sde_cfg->sui_ns_allowed = true; + sde_cfg->sui_misr_supported = true; + sde_cfg->sui_block_xin_mask = 0xC01; + sde_cfg->has_hdr = false; + sde_cfg->has_sui_blendstage = true; } else { SDE_ERROR("unsupported chipset id:%X\n", hw_rev); sde_cfg->perf.min_prefill_lines = 0xffff; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index b37fb5ae7647..22d634250e7b 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -53,6 +53,7 @@ #define SDE_HW_VER_540 SDE_HW_VER(5, 4, 0) /* sdmtrinket v1.0 */ #define SDE_HW_VER_600 SDE_HW_VER(6, 0, 0) /* kona */ #define SDE_HW_VER_610 SDE_HW_VER(6, 1, 0) /* sm7250 */ +#define SDE_HW_VER_630 SDE_HW_VER(6, 3, 0) /* bengal */ #define IS_MSM8996_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_170) #define IS_MSM8998_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_300) @@ -65,6 +66,7 @@ #define IS_SDMTRINKET_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_540) #define IS_KONA_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_600) #define IS_SAIPAN_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_610) +#define IS_BENGAL_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_630) #define SDE_HW_BLK_NAME_LEN 16 diff --git a/msm/sde/sde_hw_lm.c b/msm/sde/sde_hw_lm.c index 8c78fe768497..49974820feee 100644 --- a/msm/sde/sde_hw_lm.c +++ b/msm/sde/sde_hw_lm.c @@ -287,7 +287,8 @@ static void _setup_mixer_ops(struct sde_mdss_cfg *m, IS_SDMMAGPIE_TARGET(m->hwversion) || IS_KONA_TARGET(m->hwversion) || IS_SAIPAN_TARGET(m->hwversion) || - IS_SDMTRINKET_TARGET(m->hwversion)) + IS_SDMTRINKET_TARGET(m->hwversion) || + IS_BENGAL_TARGET(m->hwversion)) ops->setup_blend_config = sde_hw_lm_setup_blend_config_sdm845; else ops->setup_blend_config = sde_hw_lm_setup_blend_config; diff --git a/msm/sde/sde_hw_vbif.c b/msm/sde/sde_hw_vbif.c index d8b6462fb68b..f4c7846493c4 100644 --- a/msm/sde/sde_hw_vbif.c +++ b/msm/sde/sde_hw_vbif.c @@ -236,7 +236,8 @@ static void _setup_vbif_ops(const struct sde_mdss_cfg *m, ops->set_qos_remap = sde_hw_set_qos_remap; if (IS_SM8150_TARGET(m->hwversion) || IS_SM6150_TARGET(m->hwversion) || IS_SDMMAGPIE_TARGET(m->hwversion) || - IS_SDMTRINKET_TARGET(m->hwversion)) + IS_SDMTRINKET_TARGET(m->hwversion) || + IS_BENGAL_TARGET(m->hwversion)) ops->set_mem_type = sde_hw_set_mem_type_v1; else ops->set_mem_type = sde_hw_set_mem_type; diff --git a/rotator/sde_rotator_base.h b/rotator/sde_rotator_base.h index df490f318a26..bdb319dc28a9 100644 --- a/rotator/sde_rotator_base.h +++ b/rotator/sde_rotator_base.h @@ -45,6 +45,7 @@ #define SDE_MDP_HW_REV_530 SDE_MDP_REV(5, 3, 0) /* sm6150 v1.0 */ #define SDE_MDP_HW_REV_540 SDE_MDP_REV(5, 4, 0) /* sdmtrinket v1.0 */ #define SDE_MDP_HW_REV_600 SDE_MDP_REV(6, 0, 0) /* msmnile+ v1.0 */ +#define SDE_MDP_HW_REV_630 SDE_MDP_REV(6, 3, 0) /* bengal v1.0 */ #define SDE_MDP_VBIF_4_LEVEL_REMAPPER 4 #define SDE_MDP_VBIF_8_LEVEL_REMAPPER 8 diff --git a/rotator/sde_rotator_r3.c b/rotator/sde_rotator_r3.c index a667b5b5e049..45f151f63284 100644 --- a/rotator/sde_rotator_r3.c +++ b/rotator/sde_rotator_r3.c @@ -3271,6 +3271,21 @@ static int sde_rotator_hw_rev_init(struct sde_hw_rotator *rot) ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts_sbuf); rot->downscale_caps = "LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2"; + } else if (IS_SDE_MAJOR_MINOR_SAME(mdata->mdss_version, + SDE_MDP_HW_REV_630)) { + SDEROT_DBG("Sys cache inline rotation not supported\n"); + 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; + rot->num_inpixfmt[SDE_ROTATOR_MODE_OFFLINE] = + ARRAY_SIZE(sde_hw_rotator_v4_inpixfmts); + rot->outpixfmts[SDE_ROTATOR_MODE_OFFLINE] = + sde_hw_rotator_v4_outpixfmts; + rot->num_outpixfmt[SDE_ROTATOR_MODE_OFFLINE] = + ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts); + rot->downscale_caps = + "LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2"; } else { rot->inpixfmts[SDE_ROTATOR_MODE_OFFLINE] = sde_hw_rotator_v3_inpixfmts;