drm/komeda: Add komeda_crtc_atomic_flush
authorjames qian wang (Arm Technology China) <james.qian.wang@arm.com>
Tue, 22 Jan 2019 11:10:48 +0000 (11:10 +0000)
committerLiviu Dudau <Liviu.Dudau@arm.com>
Mon, 29 Apr 2019 11:35:57 +0000 (12:35 +0100)
A komeda flush is comprised two steps:
1. update pipeline/component state to HW.
2. call dev_func->flush to notify HW to kickoff the update.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
drivers/gpu/drm/arm/display/komeda/komeda_dev.h
drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c

index 72631d673f85926f88b15dcf79437922eb6cd2f8..12eda3b99e4cf26a9c5cf225d5f96a5d8d26953e 100644 (file)
@@ -243,6 +243,16 @@ static int d71_disable_irq(struct komeda_dev *mdev)
        return 0;
 }
 
+static void d71_flush(struct komeda_dev *mdev,
+                     int master_pipe, u32 active_pipes)
+{
+       struct d71_dev *d71 = mdev->chip_data;
+       u32 reg_offset = (master_pipe == 0) ?
+                        GCU_CONFIG_VALID0 : GCU_CONFIG_VALID1;
+
+       malidp_write32(d71->gcu_addr, reg_offset, GCU_CONFIG_CVAL);
+}
+
 static int d71_reset(struct d71_dev *d71)
 {
        u32 __iomem *gcu = d71->gcu_addr;
@@ -459,6 +469,7 @@ static struct komeda_dev_funcs d71_chip_funcs = {
        .irq_handler    = d71_irq_handler,
        .enable_irq     = d71_enable_irq,
        .disable_irq    = d71_disable_irq,
+       .flush          = d71_flush,
 };
 
 struct komeda_dev_funcs *
index 18209cae287c8a7e6ab95c4a44c01f85f4fbe573..40ee45d36ad6d29b423144c589dda2d8707659b2 100644 (file)
@@ -62,8 +62,41 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
                DRM_DEBUG("FLIP Done.\n");
 }
 
+static void
+komeda_crtc_do_flush(struct drm_crtc *crtc,
+                    struct drm_crtc_state *old)
+{
+       struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+       struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc->state);
+       struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
+       struct komeda_pipeline *master = kcrtc->master;
+
+       DRM_DEBUG_ATOMIC("CRTC%d_FLUSH: active_pipes: 0x%x, affected: 0x%x.\n",
+                        drm_crtc_index(crtc),
+                        kcrtc_st->active_pipes, kcrtc_st->affected_pipes);
+
+       /* step 1: update the pipeline/component state to HW */
+       if (has_bit(master->id, kcrtc_st->affected_pipes))
+               komeda_pipeline_update(master, old->state);
+
+       /* step 2: notify the HW to kickoff the update */
+       mdev->funcs->flush(mdev, master->id, kcrtc_st->active_pipes);
+}
+
+static void
+komeda_crtc_atomic_flush(struct drm_crtc *crtc,
+                        struct drm_crtc_state *old)
+{
+       /* commit with modeset will be handled in enable/disable */
+       if (drm_atomic_crtc_needs_modeset(crtc->state))
+               return;
+
+       komeda_crtc_do_flush(crtc, old);
+}
+
 struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = {
        .atomic_check   = komeda_crtc_atomic_check,
+       .atomic_flush   = komeda_crtc_atomic_flush,
 };
 
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
index 8eae2620ce77160095e5da8536fbb154660400d4..0bd38bdf0518ddbd9605e95f6ced01042fb52335 100644 (file)
@@ -106,6 +106,9 @@ struct komeda_dev_funcs {
 
        /** @dump_register: Optional, dump registers to seq_file */
        void (*dump_register)(struct komeda_dev *mdev, struct seq_file *seq);
+       /** @flush: Notify the HW to flush or kickoff the update */
+       void (*flush)(struct komeda_dev *mdev,
+                     int master_pipe, u32 active_pipes);
 };
 
 /**
index 54b646128760d2c183379ee4d22c6ebb898d5bb9..3d7a9ee550b2724728eedd91d83b9c80bf96a482 100644 (file)
@@ -412,4 +412,9 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
                                       struct komeda_crtc_state *kcrtc_st);
 
+void komeda_pipeline_disable(struct komeda_pipeline *pipe,
+                            struct drm_atomic_state *old_state);
+void komeda_pipeline_update(struct komeda_pipeline *pipe,
+                           struct drm_atomic_state *old_state);
+
 #endif /* _KOMEDA_PIPELINE_H_*/
index 10137297b0046614ef5a327455f348aadebf4728..a05165128ca2b3fb670e8efcd68db1246a455ab9 100644 (file)
@@ -33,6 +33,18 @@ komeda_pipeline_get_state(struct komeda_pipeline *pipe,
        return priv_to_pipe_st(priv_st);
 }
 
+struct komeda_pipeline_state *
+komeda_pipeline_get_old_state(struct komeda_pipeline *pipe,
+                             struct drm_atomic_state *state)
+{
+       struct drm_private_state *priv_st;
+
+       priv_st = drm_atomic_get_old_private_obj_state(state, &pipe->obj);
+       if (priv_st)
+               return priv_to_pipe_st(priv_st);
+       return NULL;
+}
+
 struct komeda_pipeline_state *
 komeda_pipeline_get_new_state(struct komeda_pipeline *pipe,
                              struct drm_atomic_state *state)
@@ -538,3 +550,28 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
 
        return 0;
 }
+
+void komeda_pipeline_update(struct komeda_pipeline *pipe,
+                           struct drm_atomic_state *old_state)
+{
+       struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state);
+       struct komeda_pipeline_state *old;
+       struct komeda_component *c;
+       u32 id, changed_comps = 0;
+
+       old = komeda_pipeline_get_old_state(pipe, old_state);
+
+       changed_comps = new->active_comps | old->active_comps;
+
+       DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n",
+                        pipe->id, new->active_comps, changed_comps);
+
+       dp_for_each_set_bit(id, changed_comps) {
+               c = komeda_pipeline_get_component(pipe, id);
+
+               if (new->active_comps & BIT(c->id))
+                       c->funcs->update(c, priv_to_comp_st(c->obj.state));
+               else
+                       c->funcs->disable(c);
+       }
+}