diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2021-01-24 20:22:05 -0800 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2021-01-24 20:22:05 -0800 |
commit | 7a8e2711c27d0b3dbb9227f64c3fdecb67cadfe3 (patch) | |
tree | d0fdbff5918231ce41f34e2f0cf815559034e3a7 | |
parent | a9b2969cdfba576b80f829f614b9e6776d60c0b8 (diff) | |
parent | 5134cb67ea15cb23d3670d3c8400bfbd161f1677 (diff) | |
download | display-drivers-7a8e2711c27d0b3dbb9227f64c3fdecb67cadfe3.tar.gz |
Merge 5134cb67ea15cb23d3670d3c8400bfbd161f1677 on remote branch
Change-Id: I18b208251324d4bd75329150fee937a9127f6323
-rw-r--r-- | msm/msm_drv.c | 8 | ||||
-rw-r--r-- | msm/sde/sde_crtc.c | 13 | ||||
-rw-r--r-- | msm/sde/sde_crtc.h | 6 | ||||
-rw-r--r-- | msm/sde/sde_encoder.c | 9 | ||||
-rw-r--r-- | msm/sde/sde_kms.c | 105 |
5 files changed, 93 insertions, 48 deletions
diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 3f1554e7..abdf61e6 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -1497,6 +1497,13 @@ static int msm_release(struct inode *inode, struct file *filp) kfree(node); } + /** + * Handle preclose operation here for removing fb's whose + * refcount > 1. This operation is not triggered from upstream + * drm as msm_driver does not support DRIVER_LEGACY feature. + */ + msm_preclose(dev, file_priv); + return drm_release(inode, filp); } @@ -1657,7 +1664,6 @@ static struct drm_driver msm_driver = { DRIVER_ATOMIC | DRIVER_MODESET, .open = msm_open, - .preclose = msm_preclose, .postclose = msm_postclose, .lastclose = msm_lastclose, .irq_handler = msm_irq, diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 696dbff2..5f3aede1 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -2480,17 +2480,16 @@ static void _sde_crtc_set_input_fence_timeout(struct sde_crtc_state *cstate) cstate->input_fence_timeout_ns *= NSEC_PER_MSEC; } -/** - * _sde_crtc_clear_dim_layers_v1 - clear all dim layer settings - * @cstate: Pointer to sde crtc state - */ -static void _sde_crtc_clear_dim_layers_v1(struct sde_crtc_state *cstate) +void _sde_crtc_clear_dim_layers_v1(struct drm_crtc_state *state) { u32 i; + struct sde_crtc_state *cstate; - if (!cstate) + if (!state) return; + cstate = to_sde_crtc_state(state); + for (i = 0; i < cstate->num_dim_layers; i++) memset(&cstate->dim_layer[i], 0, sizeof(cstate->dim_layer[i])); @@ -2519,7 +2518,7 @@ static void _sde_crtc_set_dim_layer_v1(struct drm_crtc *crtc, if (!usr_ptr) { /* usr_ptr is null when setting the default property value */ - _sde_crtc_clear_dim_layers_v1(cstate); + _sde_crtc_clear_dim_layers_v1(&cstate->base); SDE_DEBUG("dim_layer data removed\n"); return; } diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index cb93c90f..e7330f7f 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -861,6 +861,12 @@ void sde_crtc_get_misr_info(struct drm_crtc *crtc, int sde_crtc_get_num_datapath(struct drm_crtc *crtc, struct drm_connector *connector); +/** + * _sde_crtc_clear_dim_layers_v1 - clear all dim layer settings + * @cstate: Pointer to drm crtc state + */ +void _sde_crtc_clear_dim_layers_v1(struct drm_crtc_state *state); + /* * sde_crtc_set_compression_ratio - set compression ratio src_bpp/target_bpp * @msm_mode_info: Mode info diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 4c43e13c..691bbc22 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.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 <robdclark@gmail.com> * @@ -1176,8 +1176,11 @@ static int sde_encoder_virt_atomic_check( CONNECTOR_PROP_QSYNC_MODE); if (has_modeset && qsync_dirty && - !msm_is_mode_seamless_vrr(adj_mode)) { - SDE_ERROR("invalid qsync during modeset\n"); + (msm_is_mode_seamless_poms(adj_mode) || + msm_is_mode_seamless_dms(adj_mode) || + msm_is_mode_seamless_dyn_clk(adj_mode))) { + SDE_ERROR("invalid qsync update during modeset priv flag:%x\n", + adj_mode->private_flags); return -EINVAL; } diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 25a869fb..f2f5f971 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1134,10 +1134,12 @@ static void sde_kms_check_for_ext_vote(struct sde_kms *sde_kms, * cases, allow the target to go through a gdsc toggle after * crtc is disabled. */ - if (!crtc_enabled && phandle->is_ext_vote_en) { + if (!crtc_enabled && (phandle->is_ext_vote_en || + !dev->dev->power.runtime_auto)) { pm_runtime_put_sync(sde_kms->dev->dev); - SDE_EVT32(phandle->is_ext_vote_en); pm_runtime_get_sync(sde_kms->dev->dev); + SDE_EVT32(phandle->is_ext_vote_en, + dev->dev->power.runtime_auto); } mutex_unlock(&phandle->ext_client_lock); @@ -2029,6 +2031,48 @@ static void sde_kms_destroy(struct msm_kms *kms) kfree(sde_kms); } +static int sde_kms_set_crtc_for_conn(struct drm_device *dev, + struct drm_encoder *enc, struct drm_atomic_state *state) +{ + struct drm_connector *conn = NULL; + struct drm_connector *tmp_conn = NULL; + struct drm_connector_list_iter conn_iter; + struct drm_crtc_state *crtc_state = NULL; + struct drm_connector_state *conn_state = NULL; + int ret = 0; + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(tmp_conn, &conn_iter) { + if (enc == tmp_conn->state->best_encoder) { + conn = tmp_conn; + break; + } + } + drm_connector_list_iter_end(&conn_iter); + + if (!conn) { + SDE_ERROR("error in finding conn for enc:%d\n", DRMID(enc)); + return -EINVAL; + } + + crtc_state = drm_atomic_get_crtc_state(state, enc->crtc); + conn_state = drm_atomic_get_connector_state(state, conn); + if (IS_ERR(conn_state)) { + SDE_ERROR("error %d getting connector %d state\n", + ret, DRMID(conn)); + return -EINVAL; + } + + crtc_state->active = true; + ret = drm_atomic_set_crtc_for_connector(conn_state, enc->crtc); + if (ret) + SDE_ERROR("error %d setting the crtc\n", ret); + + _sde_crtc_clear_dim_layers_v1(crtc_state); + + return 0; +} + static void _sde_kms_plane_force_remove(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -2060,8 +2104,9 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file, struct drm_framebuffer *fb, *tfb; struct list_head fbs; struct drm_plane *plane; + struct drm_crtc *crtc = NULL; + unsigned int crtc_mask = 0; int ret = 0; - u32 plane_mask = 0; INIT_LIST_HEAD(&fbs); @@ -2070,9 +2115,11 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file, list_move_tail(&fb->filp_head, &fbs); drm_for_each_plane(plane, dev) { - if (plane->fb == fb) { - plane_mask |= - 1 << drm_plane_index(plane); + if (plane->state && + plane->state->fb == fb) { + if (plane->state->crtc) + crtc_mask |= drm_crtc_mask( + plane->state->crtc); _sde_kms_plane_force_remove( plane, state); } @@ -2085,11 +2132,22 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file, if (list_empty(&fbs)) { SDE_DEBUG("skip commit as no fb(s)\n"); - drm_atomic_state_put(state); return 0; } - SDE_DEBUG("committing after removing all the pipes\n"); + drm_for_each_crtc(crtc, dev) { + if ((crtc_mask & drm_crtc_mask(crtc)) && crtc->state->active) { + struct drm_encoder *drm_enc; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, + crtc->state->encoder_mask) + ret = sde_kms_set_crtc_for_conn( + dev, drm_enc, state); + } + } + + SDE_EVT32(state, crtc_mask); + SDE_DEBUG("null commit after removing all the pipes\n"); ret = drm_atomic_commit(state); if (ret) { @@ -2744,12 +2802,7 @@ static void _sde_kms_null_commit(struct drm_device *dev, struct drm_encoder *enc) { struct drm_modeset_acquire_ctx ctx; - struct drm_connector *conn = NULL; - struct drm_connector *tmp_conn = NULL; - struct drm_connector_list_iter conn_iter; struct drm_atomic_state *state = NULL; - struct drm_crtc_state *crtc_state = NULL; - struct drm_connector_state *conn_state = NULL; int retry_cnt = 0; int ret = 0; @@ -2773,32 +2826,10 @@ retry: } state->acquire_ctx = &ctx; - drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(tmp_conn, &conn_iter) { - if (enc == tmp_conn->state->best_encoder) { - conn = tmp_conn; - break; - } - } - drm_connector_list_iter_end(&conn_iter); - - if (!conn) { - SDE_ERROR("error in finding conn for enc:%d\n", DRMID(enc)); - goto end; - } - crtc_state = drm_atomic_get_crtc_state(state, enc->crtc); - conn_state = drm_atomic_get_connector_state(state, conn); - if (IS_ERR(conn_state)) { - SDE_ERROR("error %d getting connector %d state\n", - ret, DRMID(conn)); - goto end; - } - - crtc_state->active = true; - ret = drm_atomic_set_crtc_for_connector(conn_state, enc->crtc); + ret = sde_kms_set_crtc_for_conn(dev, enc, state); if (ret) - SDE_ERROR("error %d setting the crtc\n", ret); + goto end; ret = drm_atomic_commit(state); if (ret) |