diff options
author | Amit Pundir <amit.pundir@linaro.org> | 2020-04-14 17:38:38 +0530 |
---|---|---|
committer | Amit Pundir <amit.pundir@linaro.org> | 2020-06-10 17:01:22 +0530 |
commit | 1ed170845781a56efbcb58c6e1f4930bed702fa3 (patch) | |
tree | c70daaa392c1a93eb26f675a708dc06638ac6205 | |
parent | f2bcdb43a72681f24866fed40f472d0600000747 (diff) |
Revert "drm/msm/dpu: Track resources in global state"
This reverts commit de3916c70a24e3e1bdbf6b0a77d75b069d8953d9.
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
Change-Id: I31743ee0d3a5d8100d7389f8e67f806a1cd7038d
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 65 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 83 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 121 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 22 |
5 files changed, 111 insertions, 206 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index a1b79ee2bd9d..baf166ae196b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -164,6 +164,7 @@ enum dpu_enc_rc_states { * clks and resources after IDLE_TIMEOUT time. * @vsync_event_work: worker to handle vsync event for autorefresh * @topology: topology of the display + * @mode_set_complete: flag to indicate modeset completion * @idle_timeout: idle timeout duration in milliseconds */ struct dpu_encoder_virt { @@ -201,6 +202,7 @@ struct dpu_encoder_virt { struct delayed_work delayed_off_work; struct kthread_work vsync_event_work; struct msm_display_topology topology; + bool mode_set_complete; u32 idle_timeout; }; @@ -560,7 +562,6 @@ static int dpu_encoder_virt_atomic_check( const struct drm_display_mode *mode; struct drm_display_mode *adj_mode; struct msm_display_topology topology; - struct dpu_global_state *global_state; int i = 0; int ret = 0; @@ -577,7 +578,6 @@ static int dpu_encoder_virt_atomic_check( dpu_kms = to_dpu_kms(priv->kms); mode = &crtc_state->mode; adj_mode = &crtc_state->adjusted_mode; - global_state = dpu_kms_get_existing_global_state(dpu_kms); trace_dpu_enc_atomic_check(DRMID(drm_enc)); /* @@ -609,15 +609,17 @@ static int dpu_encoder_virt_atomic_check( topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); - /* Reserve dynamic resources now. */ + /* Reserve dynamic resources now. Indicating AtomicTest phase */ if (!ret) { /* * Avoid reserving resources when mode set is pending. Topology * info may not be available to complete reservation. */ - if (drm_atomic_crtc_needs_modeset(crtc_state)) { - ret = dpu_rm_reserve(&dpu_kms->rm, global_state, - drm_enc, crtc_state, topology); + if (drm_atomic_crtc_needs_modeset(crtc_state) + && dpu_enc->mode_set_complete) { + ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, crtc_state, + topology, true); + dpu_enc->mode_set_complete = false; } } @@ -954,13 +956,12 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct drm_connector *conn = NULL, *conn_iter; struct drm_crtc *drm_crtc; struct dpu_crtc_state *cstate; - struct dpu_global_state *global_state; struct msm_display_topology topology; struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; int num_lm, num_ctl, num_pp; - int i, j; + int i, j, ret; if (!drm_enc) { DPU_ERROR("invalid encoder\n"); @@ -974,12 +975,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, dpu_kms = to_dpu_kms(priv->kms); connector_list = &dpu_kms->dev->mode_config.connector_list; - global_state = dpu_kms_get_existing_global_state(dpu_kms); - if (IS_ERR_OR_NULL(global_state)) { - DPU_ERROR("Failed to get global state"); - return; - } - trace_dpu_enc_mode_set(DRMID(drm_enc)); list_for_each_entry(conn_iter, connector_list, head) @@ -1000,14 +995,21 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); - /* Query resource that have been reserved in atomic check step. */ - num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp, - ARRAY_SIZE(hw_pp)); - num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); - num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); + /* Reserve dynamic resources now. Indicating non-AtomicTest phase */ + ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, drm_crtc->state, + topology, false); + if (ret) { + DPU_ERROR_ENC(dpu_enc, + "failed to reserve hw resources, %d\n", ret); + return; + } + + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, + DPU_HW_BLK_PINGPONG, hw_pp, ARRAY_SIZE(hw_pp)); + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, + DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, + DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) @@ -1032,21 +1034,21 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, if (!dpu_enc->hw_pp[i]) { DPU_ERROR_ENC(dpu_enc, "no pp block assigned at idx: %d\n", i); - return; + goto error; } if (!hw_ctl[i]) { DPU_ERROR_ENC(dpu_enc, "no ctl block assigned at idx: %d\n", i); - return; + goto error; } phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); num_blk = dpu_rm_get_assigned_resources(&dpu_kms->rm, - global_state, drm_enc->base.id, DPU_HW_BLK_INTF, - hw_blk, ARRAY_SIZE(hw_blk)); + drm_enc->base.id, DPU_HW_BLK_INTF, hw_blk, + ARRAY_SIZE(hw_blk)); for (j = 0; j < num_blk; j++) { struct dpu_hw_intf *hw_intf; @@ -1058,13 +1060,18 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, if (!phys->hw_intf) { DPU_ERROR_ENC(dpu_enc, "no intf block assigned at idx: %d\n", i); - return; + goto error; } phys->connector = conn->state->connector; if (phys->ops.mode_set) phys->ops.mode_set(phys, mode, adj_mode); } + + dpu_enc->mode_set_complete = true; + +error: + dpu_rm_release(&dpu_kms->rm, drm_enc); } static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) @@ -1161,7 +1168,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) struct dpu_encoder_virt *dpu_enc = NULL; struct msm_drm_private *priv; struct dpu_kms *dpu_kms; - struct dpu_global_state *global_state; int i = 0; if (!drm_enc) { @@ -1180,7 +1186,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) priv = drm_enc->dev->dev_private; dpu_kms = to_dpu_kms(priv->kms); - global_state = dpu_kms_get_existing_global_state(dpu_kms); trace_dpu_enc_disable(DRMID(drm_enc)); @@ -1210,7 +1215,7 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n"); - dpu_rm_release(global_state, drm_enc); + dpu_rm_release(&dpu_kms->rm, drm_enc); mutex_unlock(&dpu_enc->enc_lock); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index ce19f1d39367..089d1cde39da 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -224,85 +224,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) } #endif -/* Global/shared object state funcs */ - -/* - * This is a helper that returns the private state currently in operation. - * Note that this would return the "old_state" if called in the atomic check - * path, and the "new_state" after the atomic swap has been done. - */ -struct dpu_global_state * -dpu_kms_get_existing_global_state(struct dpu_kms *dpu_kms) -{ - return to_dpu_global_state(dpu_kms->global_state.state); -} - -/* - * This acquires the modeset lock set aside for global state, creates - * a new duplicated private object state. - */ -struct dpu_global_state *dpu_kms_get_global_state(struct drm_atomic_state *s) -{ - struct msm_drm_private *priv = s->dev->dev_private; - struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); - struct drm_private_state *priv_state; - int ret; - - ret = drm_modeset_lock(&dpu_kms->global_state_lock, s->acquire_ctx); - if (ret) - return ERR_PTR(ret); - - priv_state = drm_atomic_get_private_obj_state(s, - &dpu_kms->global_state); - if (IS_ERR(priv_state)) - return ERR_CAST(priv_state); - - return to_dpu_global_state(priv_state); -} - -static struct drm_private_state * -dpu_kms_global_duplicate_state(struct drm_private_obj *obj) -{ - struct dpu_global_state *state; - - state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); - if (!state) - return NULL; - - __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); - - return &state->base; -} - -static void dpu_kms_global_destroy_state(struct drm_private_obj *obj, - struct drm_private_state *state) -{ - struct dpu_global_state *dpu_state = to_dpu_global_state(state); - - kfree(dpu_state); -} - -static const struct drm_private_state_funcs dpu_kms_global_state_funcs = { - .atomic_duplicate_state = dpu_kms_global_duplicate_state, - .atomic_destroy_state = dpu_kms_global_destroy_state, -}; - -static int dpu_kms_global_obj_init(struct dpu_kms *dpu_kms) -{ - struct dpu_global_state *state; - - drm_modeset_lock_init(&dpu_kms->global_state_lock); - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - drm_atomic_private_obj_init(dpu_kms->dev, &dpu_kms->global_state, - &state->base, - &dpu_kms_global_state_funcs); - return 0; -} - static int dpu_kms_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { return dpu_crtc_vblank(crtc, true); @@ -838,10 +759,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms = to_dpu_kms(kms); dev = dpu_kms->dev; - rc = dpu_kms_global_obj_init(dpu_kms); - if (rc) - return rc; - atomic_set(&dpu_kms->bandwidth_ref, 0); dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp", "mdp"); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 211f5de99a44..c6169e7df19d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -111,13 +111,6 @@ struct dpu_kms { struct dpu_core_perf perf; - /* - * Global private object state, Do not access directly, use - * dpu_kms_global_get_state() - */ - struct drm_modeset_lock global_state_lock; - struct drm_private_obj global_state; - struct dpu_rm rm; bool rm_init; @@ -146,25 +139,6 @@ struct vsync_info { #define to_dpu_kms(x) container_of(x, struct dpu_kms, base) -#define to_dpu_global_state(x) container_of(x, struct dpu_global_state, base) - -/* Global private object state for tracking resources that are shared across - * multiple kms objects (planes/crtcs/etc). - */ -struct dpu_global_state { - struct drm_private_state base; - - uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0]; - uint32_t mixer_to_enc_id[LM_MAX - LM_0]; - uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; - uint32_t intf_to_enc_id[INTF_MAX - INTF_0]; -}; - -struct dpu_global_state - *dpu_kms_get_existing_global_state(struct dpu_kms *dpu_kms); -struct dpu_global_state - *__must_check dpu_kms_get_global_state(struct drm_atomic_state *s); - /** * Debugfs functions - extra helper functions for debugfs support * diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 9b62451b01ee..594e2d10b000 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -66,6 +66,8 @@ int dpu_rm_destroy(struct dpu_rm *rm) } } + mutex_destroy(&rm->rm_lock); + return 0; } @@ -83,6 +85,8 @@ int dpu_rm_init(struct dpu_rm *rm, /* Clear, setup lists */ memset(rm, 0, sizeof(*rm)); + mutex_init(&rm->rm_lock); + /* Interrogate HW catalog and create tracking items for hw blocks */ for (i = 0; i < cat->mixer_count; i++) { struct dpu_hw_mixer *hw; @@ -226,14 +230,13 @@ static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx, * @Return: true if lm matches all requirements, false otherwise */ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, - struct dpu_global_state *global_state, uint32_t enc_id, int lm_idx, int *pp_idx) { const struct dpu_lm_cfg *lm_cfg; int idx; /* Already reserved? */ - if (reserved_by_other(global_state->mixer_to_enc_id, lm_idx, enc_id)) { + if (reserved_by_other(rm->mixer_to_enc_id, lm_idx, enc_id)) { DPU_DEBUG("lm %d already reserved\n", lm_idx + LM_0); return false; } @@ -245,7 +248,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, return false; } - if (reserved_by_other(global_state->pingpong_to_enc_id, idx, enc_id)) { + if (reserved_by_other(rm->pingpong_to_enc_id, idx, enc_id)) { DPU_DEBUG("lm %d pp %d already reserved\n", lm_cfg->id, lm_cfg->pingpong); return false; @@ -254,9 +257,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, return true; } -static int _dpu_rm_reserve_lms(struct dpu_rm *rm, - struct dpu_global_state *global_state, - uint32_t enc_id, +static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, struct dpu_rm_requirements *reqs) { @@ -278,8 +279,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, lm_count = 0; lm_idx[lm_count] = i; - if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state, - enc_id, i, &pp_idx[lm_count])) { + if (!_dpu_rm_check_lm_and_get_connected_blks( + rm, enc_id, i, &pp_idx[lm_count])) { continue; } @@ -297,9 +298,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, continue; } - if (!_dpu_rm_check_lm_and_get_connected_blks(rm, - global_state, enc_id, j, - &pp_idx[lm_count])) { + if (!_dpu_rm_check_lm_and_get_connected_blks( + rm, enc_id, j, &pp_idx[lm_count])) { continue; } @@ -314,8 +314,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, } for (i = 0; i < lm_count; i++) { - global_state->mixer_to_enc_id[lm_idx[i]] = enc_id; - global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id; + rm->mixer_to_enc_id[lm_idx[i]] = enc_id; + rm->pingpong_to_enc_id[pp_idx[i]] = enc_id; trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id, pp_idx[i] + PINGPONG_0); @@ -326,7 +326,6 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, static int _dpu_rm_reserve_ctls( struct dpu_rm *rm, - struct dpu_global_state *global_state, uint32_t enc_id, const struct msm_display_topology *top) { @@ -346,7 +345,7 @@ static int _dpu_rm_reserve_ctls( if (!rm->ctl_blks[j]) continue; - if (reserved_by_other(global_state->ctl_to_enc_id, j, enc_id)) + if (reserved_by_other(rm->ctl_to_enc_id, j, enc_id)) continue; ctl = to_dpu_hw_ctl(rm->ctl_blks[j]); @@ -370,7 +369,7 @@ static int _dpu_rm_reserve_ctls( return -ENAVAIL; for (i = 0; i < ARRAY_SIZE(ctl_idx) && i < num_ctls; i++) { - global_state->ctl_to_enc_id[ctl_idx[i]] = enc_id; + rm->ctl_to_enc_id[ctl_idx[i]] = enc_id; trace_dpu_rm_reserve_ctls(i + CTL_0, enc_id); } @@ -379,34 +378,27 @@ static int _dpu_rm_reserve_ctls( static int _dpu_rm_reserve_intf( struct dpu_rm *rm, - struct dpu_global_state *global_state, uint32_t enc_id, uint32_t id) { int idx = id - INTF_0; - if (idx < 0 || idx >= ARRAY_SIZE(rm->intf_blks)) { - DPU_ERROR("invalid intf id: %d", id); - return -EINVAL; - } - if (!rm->intf_blks[idx]) { DPU_ERROR("couldn't find intf id %d\n", id); return -EINVAL; } - if (reserved_by_other(global_state->intf_to_enc_id, idx, enc_id)) { + if (reserved_by_other(rm->intf_to_enc_id, idx, enc_id)) { DPU_ERROR("intf id %d already reserved\n", id); return -ENAVAIL; } - global_state->intf_to_enc_id[idx] = enc_id; + rm->intf_to_enc_id[idx] = enc_id; return 0; } static int _dpu_rm_reserve_intf_related_hw( struct dpu_rm *rm, - struct dpu_global_state *global_state, uint32_t enc_id, struct dpu_encoder_hw_resources *hw_res) { @@ -417,7 +409,7 @@ static int _dpu_rm_reserve_intf_related_hw( if (hw_res->intfs[i] == INTF_MODE_NONE) continue; id = i + INTF_0; - ret = _dpu_rm_reserve_intf(rm, global_state, enc_id, id); + ret = _dpu_rm_reserve_intf(rm, enc_id, id); if (ret) return ret; } @@ -427,27 +419,24 @@ static int _dpu_rm_reserve_intf_related_hw( static int _dpu_rm_make_reservation( struct dpu_rm *rm, - struct dpu_global_state *global_state, struct drm_encoder *enc, struct dpu_rm_requirements *reqs) { int ret; - ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, reqs); + ret = _dpu_rm_reserve_lms(rm, enc->base.id, reqs); if (ret) { DPU_ERROR("unable to find appropriate mixers\n"); return ret; } - ret = _dpu_rm_reserve_ctls(rm, global_state, enc->base.id, - &reqs->topology); + ret = _dpu_rm_reserve_ctls(rm, enc->base.id, &reqs->topology); if (ret) { DPU_ERROR("unable to find appropriate CTL\n"); return ret; } - ret = _dpu_rm_reserve_intf_related_hw(rm, global_state, enc->base.id, - &reqs->hw_res); + ret = _dpu_rm_reserve_intf_related_hw(rm, enc->base.id, &reqs->hw_res); if (ret) return ret; @@ -481,25 +470,33 @@ static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt, } } -void dpu_rm_release(struct dpu_global_state *global_state, - struct drm_encoder *enc) +static void _dpu_rm_release_reservation(struct dpu_rm *rm, uint32_t enc_id) +{ + _dpu_rm_clear_mapping(rm->pingpong_to_enc_id, + ARRAY_SIZE(rm->pingpong_to_enc_id), enc_id); + _dpu_rm_clear_mapping(rm->mixer_to_enc_id, + ARRAY_SIZE(rm->mixer_to_enc_id), enc_id); + _dpu_rm_clear_mapping(rm->ctl_to_enc_id, + ARRAY_SIZE(rm->ctl_to_enc_id), enc_id); + _dpu_rm_clear_mapping(rm->intf_to_enc_id, + ARRAY_SIZE(rm->intf_to_enc_id), enc_id); +} + +void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc) { - _dpu_rm_clear_mapping(global_state->pingpong_to_enc_id, - ARRAY_SIZE(global_state->pingpong_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(global_state->mixer_to_enc_id, - ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(global_state->ctl_to_enc_id, - ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(global_state->intf_to_enc_id, - ARRAY_SIZE(global_state->intf_to_enc_id), enc->base.id); + mutex_lock(&rm->rm_lock); + + _dpu_rm_release_reservation(rm, enc->base.id); + + mutex_unlock(&rm->rm_lock); } int dpu_rm_reserve( struct dpu_rm *rm, - struct dpu_global_state *global_state, struct drm_encoder *enc, struct drm_crtc_state *crtc_state, - struct msm_display_topology topology) + struct msm_display_topology topology, + bool test_only) { struct dpu_rm_requirements reqs; int ret; @@ -508,31 +505,35 @@ int dpu_rm_reserve( if (!drm_atomic_crtc_needs_modeset(crtc_state)) return 0; - if (IS_ERR(global_state)) { - DPU_ERROR("failed to global state\n"); - return PTR_ERR(global_state); - } + DRM_DEBUG_KMS("reserving hw for enc %d crtc %d test_only %d\n", + enc->base.id, crtc_state->crtc->base.id, test_only); - DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n", - enc->base.id, crtc_state->crtc->base.id); + mutex_lock(&rm->rm_lock); ret = _dpu_rm_populate_requirements(enc, &reqs, topology); if (ret) { DPU_ERROR("failed to populate hw requirements\n"); - return ret; + goto end; } - ret = _dpu_rm_make_reservation(rm, global_state, enc, &reqs); - if (ret) + ret = _dpu_rm_make_reservation(rm, enc, &reqs); + if (ret) { DPU_ERROR("failed to reserve hw resources: %d\n", ret); + _dpu_rm_release_reservation(rm, enc->base.id); + } else if (test_only) { + /* test_only: test the reservation and then undo */ + DPU_DEBUG("test_only: discard test [enc: %d]\n", + enc->base.id); + _dpu_rm_release_reservation(rm, enc->base.id); + } - +end: + mutex_unlock(&rm->rm_lock); return ret; } -int dpu_rm_get_assigned_resources(struct dpu_rm *rm, - struct dpu_global_state *global_state, uint32_t enc_id, +int dpu_rm_get_assigned_resources(struct dpu_rm *rm, uint32_t enc_id, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size) { struct dpu_hw_blk **hw_blks; @@ -542,22 +543,22 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, switch (type) { case DPU_HW_BLK_PINGPONG: hw_blks = rm->pingpong_blks; - hw_to_enc_id = global_state->pingpong_to_enc_id; + hw_to_enc_id = rm->pingpong_to_enc_id; max_blks = ARRAY_SIZE(rm->pingpong_blks); break; case DPU_HW_BLK_LM: hw_blks = rm->mixer_blks; - hw_to_enc_id = global_state->mixer_to_enc_id; + hw_to_enc_id = rm->mixer_to_enc_id; max_blks = ARRAY_SIZE(rm->mixer_blks); break; case DPU_HW_BLK_CTL: hw_blks = rm->ctl_blks; - hw_to_enc_id = global_state->ctl_to_enc_id; + hw_to_enc_id = rm->ctl_to_enc_id; max_blks = ARRAY_SIZE(rm->ctl_blks); break; case DPU_HW_BLK_INTF: hw_blks = rm->intf_blks; - hw_to_enc_id = global_state->intf_to_enc_id; + hw_to_enc_id = rm->intf_to_enc_id; max_blks = ARRAY_SIZE(rm->intf_blks); break; default: diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index 6d2b04f306f0..9c8a436ba6cc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -11,7 +11,6 @@ #include "msm_kms.h" #include "dpu_hw_top.h" -struct dpu_global_state; /** * struct dpu_rm - DPU dynamic hardware resource manager @@ -19,6 +18,10 @@ struct dpu_global_state; * @mixer_blks: array of layer mixer hardware resources * @ctl_blks: array of ctl hardware resources * @intf_blks: array of intf hardware resources + * @pingpong_to_enc_id: mapping of pingpong hardware resources to an encoder ID + * @mixer_to_enc_id: mapping of mixer hardware resources to an encoder ID + * @ctl_to_enc_id: mapping of ctl hardware resources to an encoder ID + * @intf_to_enc_id: mapping of intf hardware resources to an encoder ID * @lm_max_width: cached layer mixer maximum width * @rm_lock: resource manager mutex */ @@ -28,7 +31,13 @@ struct dpu_rm { struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0]; struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0]; + uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0]; + uint32_t mixer_to_enc_id[LM_MAX - LM_0]; + uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; + uint32_t intf_to_enc_id[INTF_MAX - INTF_0]; + uint32_t lm_max_width; + struct mutex rm_lock; }; /** @@ -61,13 +70,14 @@ int dpu_rm_destroy(struct dpu_rm *rm); * @drm_enc: DRM Encoder handle * @crtc_state: Proposed Atomic DRM CRTC State handle * @topology: Pointer to topology info for the display + * @test_only: Atomic-Test phase, discard results (unless property overrides) * @Return: 0 on Success otherwise -ERROR */ int dpu_rm_reserve(struct dpu_rm *rm, - struct dpu_global_state *global_state, struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, - struct msm_display_topology topology); + struct msm_display_topology topology, + bool test_only); /** * dpu_rm_reserve - Given the encoder for the display chain, release any @@ -76,14 +86,12 @@ int dpu_rm_reserve(struct dpu_rm *rm, * @enc: DRM Encoder handle * @Return: 0 on Success otherwise -ERROR */ -void dpu_rm_release(struct dpu_global_state *global_state, - struct drm_encoder *enc); +void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc); /** * Get hw resources of the given type that are assigned to this encoder. */ -int dpu_rm_get_assigned_resources(struct dpu_rm *rm, - struct dpu_global_state *global_state, uint32_t enc_id, +int dpu_rm_get_assigned_resources(struct dpu_rm *rm, uint32_t enc_id, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size); #endif /* __DPU_RM_H__ */ |