summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm
diff options
context:
space:
mode:
authorRob Clark <robdclark@chromium.org>2019-08-29 19:45:14 +0300
committerRob Clark <robdclark@chromium.org>2019-09-04 02:17:01 +0300
commit9f6b65642bd2d7ec1fc2eb675cf10a55f29417e2 (patch)
tree00c7928446631b9e4c0f364d6eb388c0ba0e7b9c /drivers/gpu/drm/msm
parent80b4b4a703d6e4fb966e5c6a7c74a06001bf7d19 (diff)
downloadlinux-9f6b65642bd2d7ec1fc2eb675cf10a55f29417e2.tar.xz
drm/msm: add kms->flush_commit()
Add ->flush_commit(crtc_mask). Currently a no-op, but kms backends should migrate writing flush registers to this hook, so we can decouple pushing updates to hardware, and flushing the updates. Once we add async commit support, the hw updates will be pushed down to the hw synchronously, but flushing the updates will be deferred until as close to vblank as possible, so that multiple updates can be combined in a single frame. Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Sean Paul <sean@poorly.run>
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c6
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c6
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c6
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c9
-rw-r--r--drivers/gpu/drm/msm/msm_kms.h40
5 files changed, 63 insertions, 4 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 23566b1aac87..de6223a0b1d4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -280,6 +280,11 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
}
}
+static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+ /* TODO */
+}
+
/*
* Override the encoder enable since we need to setup the inline rotator and do
* some crtc magic before enabling any bridge that might be present.
@@ -680,6 +685,7 @@ static const struct msm_kms_funcs kms_funcs = {
.irq_uninstall = dpu_irq_uninstall,
.irq = dpu_irq,
.prepare_commit = dpu_kms_prepare_commit,
+ .flush_commit = dpu_kms_flush_commit,
.commit = dpu_kms_commit,
.wait_flush = dpu_kms_wait_flush,
.complete_commit = dpu_kms_complete_commit,
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index 8c6622fb373b..63e7a4a77c67 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -110,6 +110,11 @@ static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
drm_crtc_vblank_get(crtc);
}
+static void mdp4_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+ /* TODO */
+}
+
static void mdp4_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
{
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
@@ -181,6 +186,7 @@ static const struct mdp_kms_funcs kms_funcs = {
.enable_vblank = mdp4_enable_vblank,
.disable_vblank = mdp4_disable_vblank,
.prepare_commit = mdp4_prepare_commit,
+ .flush_commit = mdp4_flush_commit,
.wait_flush = mdp4_wait_flush,
.complete_commit = mdp4_complete_commit,
.get_format = mdp_get_format,
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 7be28f14f93b..b374ccda8018 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -160,6 +160,11 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
mdp5_smp_prepare_commit(mdp5_kms->smp, &global_state->smp);
}
+static void mdp5_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+ /* TODO */
+}
+
static void mdp5_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -278,6 +283,7 @@ static const struct mdp_kms_funcs kms_funcs = {
.irq = mdp5_irq,
.enable_vblank = mdp5_enable_vblank,
.disable_vblank = mdp5_disable_vblank,
+ .flush_commit = mdp5_flush_commit,
.prepare_commit = mdp5_prepare_commit,
.wait_flush = mdp5_wait_flush,
.complete_commit = mdp5_complete_commit,
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 1717f430bfb4..7a1c47cd7350 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -51,16 +51,21 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
kms->funcs->prepare_commit(kms, state);
+ /*
+ * Push atomic updates down to hardware:
+ */
drm_atomic_helper_commit_modeset_disables(dev, state);
-
drm_atomic_helper_commit_planes(dev, state, 0);
-
drm_atomic_helper_commit_modeset_enables(dev, state);
+ /*
+ * Flush hardware updates:
+ */
if (kms->funcs->commit) {
DRM_DEBUG_ATOMIC("triggering commit\n");
kms->funcs->commit(kms, state);
}
+ kms->funcs->flush_commit(kms, crtc_mask);
kms->funcs->wait_flush(kms, crtc_mask);
kms->funcs->complete_commit(kms, crtc_mask);
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 10dd171b43f8..80bccbf4d993 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -30,12 +30,47 @@ struct msm_kms_funcs {
irqreturn_t (*irq)(struct msm_kms *kms);
int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
- /* modeset, bracketing atomic_commit(): */
+
+ /*
+ * Atomic commit handling:
+ */
+
+ /**
+ * Prepare for atomic commit. This is called after any previous
+ * (async or otherwise) commit has completed.
+ */
void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state);
+
+ /**
+ * Flush an atomic commit. This is called after the hardware
+ * updates have already been pushed down to effected planes/
+ * crtcs/encoders/connectors.
+ */
+ void (*flush_commit)(struct msm_kms *kms, unsigned crtc_mask);
+
+ /* TODO remove ->commit(), use ->flush_commit() instead: */
void (*commit)(struct msm_kms *kms, struct drm_atomic_state *state);
- void (*complete_commit)(struct msm_kms *kms, unsigned crtc_mask);
+
+ /**
+ * Wait for any in-progress flush to complete on the specified
+ * crtcs. This should not block if there is no in-progress
+ * commit (ie. don't just wait for a vblank), as it will also
+ * be called before ->prepare_commit() to ensure any potential
+ * "async" commit has completed.
+ */
void (*wait_flush)(struct msm_kms *kms, unsigned crtc_mask);
+ /**
+ * Clean up after commit is completed. This is called after
+ * ->wait_flush(), to give the backend a chance to do any
+ * post-commit cleanup.
+ */
+ void (*complete_commit)(struct msm_kms *kms, unsigned crtc_mask);
+
+ /*
+ * Format handling:
+ */
+
/* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */
const struct msm_format *(*get_format)(struct msm_kms *kms,
const uint32_t format,
@@ -45,6 +80,7 @@ struct msm_kms_funcs {
const struct msm_format *msm_fmt,
const struct drm_mode_fb_cmd2 *cmd,
struct drm_gem_object **bos);
+
/* misc: */
long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
struct drm_encoder *encoder);