Re: [Freedreno] [v1] drm/msm/dpu: update reservations in commit path

From: kalyan_t
Date: Wed Aug 05 2020 - 14:19:45 EST


On 2020-08-05 01:02, Rob Clark wrote:
On Tue, Aug 4, 2020 at 4:32 AM Kalyan Thota <kalyan_t@xxxxxxxxxxxxxx> wrote:

DPU resources reserved in the atomic_check path gets unwinded
during modeset operation before commit happens in a non seamless
transition.

Update the reservations in the commit path to avoid resource
failures. Secondly have dummy reservations in atomic_check path
so that we can gracefully fail the composition if resources are
not available.

Signed-off-by: Kalyan Thota <kalyan_t@xxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 63976dc..c6b8254 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -565,7 +565,7 @@ 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;
+ struct dpu_global_state tmp_resv_state;
int i = 0;
int ret = 0;

@@ -582,7 +582,7 @@ 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);
+ memset(&tmp_resv_state, 0, sizeof(tmp_resv_state));

I think what you want to do is dpu_kms_get_global_state().. that will
clone/duplicate the existing global state (or return the already
duplicated global state if it is called multiple times).

Thanks Rob, realized the same after posting patch. Made changes in the new patch
accordingly.

It is safe to modify this global state in the atomic_check() path.. in
fact that is the intention. For a TEST_ONLY atomic commit, or if any
of the atomic_check()'s fail, this new duplicated global state is
discarded. If all the checks succeed and the atomic update is
committed to hw, this new global state replaces the existing global
state.

Posted a new change kindly review.

BR,
-R

trace_dpu_enc_atomic_check(DRMID(drm_enc));

/*
@@ -621,7 +621,7 @@ static int dpu_encoder_virt_atomic_check(
* 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,
+ ret = dpu_rm_reserve(&dpu_kms->rm, &tmp_resv_state,
drm_enc, crtc_state, topology);
}
}
@@ -966,7 +966,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
int num_lm, num_ctl, num_pp, num_dspp;
- int i, j;
+ int i, j, rc;

if (!drm_enc) {
DPU_ERROR("invalid encoder\n");
@@ -1006,6 +1006,13 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,

topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);

+ rc = dpu_rm_reserve(&dpu_kms->rm, global_state, drm_enc,
+ drm_crtc->state, topology);
+ if (rc) {
+ DPU_ERROR_ENC(dpu_enc, "Failed to reserve resources\n");
+ return;
+ }
+
/* 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,
--
1.9.1

_______________________________________________
Freedreno mailing list
Freedreno@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/freedreno