Komeda driver treats KMS-CRTC/PLANE as user which will acquire pipeline resources, but we still need to release the unclaimed resources. crtc_atomic_check is the final check stage, so beside build a display data pipeline according the crtc_state, but still needs to release/disable the unclaimed pipeline resources. Signed-off-by: James (Qian) Wang <james.qian.wang@xxxxxxx> --- .../gpu/drm/arm/display/komeda/komeda_crtc.c | 27 +++++++++ .../drm/arm/display/komeda/komeda_pipeline.h | 3 + .../display/komeda/komeda_pipeline_state.c | 58 +++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index c896e46203ed..f84024aae155 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -14,6 +14,32 @@ #include "komeda_dev.h" #include "komeda_kms.h" +/* crtc_atomic_check is the final check stage, so beside build a display data + * pipeline according the crtc_state, but still needs to release/disable the + * unclaimed pipeline resources. + */ +static int +komeda_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct komeda_crtc *kcrtc = to_kcrtc(crtc); + struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state); + int err; + + if (state->active) { + err = komeda_build_display_data_flow(kcrtc, kcrtc_st); + if (err) + return err; + } + + /* release unclaimed pipeline resources */ + err = komeda_release_unclaimed_resources(kcrtc->master, kcrtc_st); + if (err) + return err; + + return 0; +} + void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, struct komeda_events *evts) { @@ -33,6 +59,7 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, } struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { + .atomic_check = komeda_crtc_atomic_check, }; static const struct drm_crtc_funcs komeda_crtc_funcs = { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index bc4ed1513348..9a17d0152021 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -418,4 +418,7 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer, int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, struct komeda_crtc_state *kcrtc_st); +int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, + struct komeda_crtc_state *kcrtc_st); + #endif /* _KOMEDA_PIPELINE_H_*/ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 05386e9d1749..920d2b40e9cc 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -42,6 +42,18 @@ komeda_pipeline_get_state(struct komeda_pipeline *pipe, return priv_to_pipe_st(priv_st); } +struct komeda_pipeline_state * +komeda_pipeline_get_new_state(struct komeda_pipeline *pipe, + struct drm_atomic_state *state) +{ + struct drm_private_state *priv_st; + + priv_st = drm_atomic_get_new_private_obj_state(state, &pipe->obj); + if (priv_st) + return priv_to_pipe_st(priv_st); + return NULL; +} + /* Assign a pipeline crtc */ struct komeda_pipeline_state * komeda_pipeline_get_state_and_set_crtc(struct komeda_pipeline *pipe, @@ -478,3 +490,49 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, return 0; } + +void komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, + struct komeda_pipeline_state *new) +{ + struct drm_atomic_state *drm_st = new->obj.state; + struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state); + struct komeda_component_state *c_st; + struct komeda_component *c; + u32 disabling_comps, id; + + WARN_ON(!old); + + disabling_comps = (~new->active_comps) & old->active_comps; + + /* unbound all disabling component */ + dp_for_each_set_bit(id, disabling_comps) { + c = komeda_pipeline_get_component(pipe, id); + c_st = komeda_component_get_state_and_set_user(c, + drm_st, NULL, new->crtc); + WARN_ON(IS_ERR(c_st)); + } +} + +/* release unclaimed pipeline resource */ +int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, + struct komeda_crtc_state *kcrtc_st) +{ + struct drm_atomic_state *drm_st = kcrtc_st->base.state; + struct komeda_pipeline_state *st; + + /* ignore the pipeline which is not affected */ + if (!pipe || !has_bit(pipe->id, kcrtc_st->affected_pipes)) + return 0; + + if (has_bit(pipe->id, kcrtc_st->active_pipes)) + st = komeda_pipeline_get_new_state(pipe, drm_st); + else + st = komeda_pipeline_get_state_and_set_crtc(pipe, drm_st, NULL); + + if (WARN_ON(IS_ERR_OR_NULL(st))) + return -EINVAL; + + komeda_pipeline_unbound_components(pipe, st); + + return 0; +} -- 2.17.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel