drm/msm/sde: add prepare_commit callback to sde encoder
Allow the sde encoder to react to prepare_commit at the
beginning of an atomic commit sequence to support features like
autorefresh which need to be disabled before any other register
writes take place.
Change-Id: I2891eeba0cc9cdb6f3c6a5c2cc3542d74fa3ba1e
Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 5ccd385..f6e1db6 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -2228,6 +2228,25 @@
return 0;
}
+void sde_encoder_prepare_commit(struct drm_encoder *drm_enc)
+{
+ struct sde_encoder_virt *sde_enc;
+ struct sde_encoder_phys *phys;
+ int i;
+
+ if (!drm_enc) {
+ SDE_ERROR("invalid encoder\n");
+ return;
+ }
+ sde_enc = to_sde_encoder_virt(drm_enc);
+
+ for (i = 0; i < sde_enc->num_phys_encs; i++) {
+ phys = sde_enc->phys_encs[i];
+ if (phys && phys->ops.prepare_commit)
+ phys->ops.prepare_commit(phys);
+ }
+}
+
#ifdef CONFIG_DEBUG_FS
static int _sde_encoder_status_show(struct seq_file *s, void *data)
{
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h
index d3a9bb4..28b6e1c 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.h
@@ -179,4 +179,11 @@
*/
void sde_encoder_destroy(struct drm_encoder *drm_enc);
+/**
+ * sde_encoder_prepare_commit - prepare encoder at the very beginning of an
+ * atomic commit, before any registers are written
+ * @drm_enc: Pointer to previously created drm encoder structure
+ */
+void sde_encoder_prepare_commit(struct drm_encoder *drm_enc);
+
#endif /* __SDE_ENCODER_H__ */
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
index c2ef28d..4fd82da 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
@@ -94,6 +94,7 @@
* struct sde_encoder_phys_ops - Interface the physical encoders provide to
* the containing virtual encoder.
* @late_register: DRM Call. Add Userspace interfaces, debugfs.
+ * @prepare_commit: MSM Atomic Call, start of atomic commit sequence
* @is_master: Whether this phys_enc is the current master
* encoder. Can be switched at enable time. Based
* on split_role and current mode (CMD/VID).
@@ -127,6 +128,7 @@
struct sde_encoder_phys_ops {
int (*late_register)(struct sde_encoder_phys *encoder,
struct dentry *debugfs_root);
+ void (*prepare_commit)(struct sde_encoder_phys *encoder);
bool (*is_master)(struct sde_encoder_phys *encoder);
bool (*mode_fixup)(struct sde_encoder_phys *encoder,
const struct drm_display_mode *mode,
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
index 7adab09..a954b25 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
@@ -864,9 +864,15 @@
_sde_encoder_phys_cmd_update_flush_mask(phys_enc);
}
+static void sde_encoder_phys_cmd_prepare_commit(
+ struct sde_encoder_phys *phys_enc)
+{
+}
+
static void sde_encoder_phys_cmd_init_ops(
struct sde_encoder_phys_ops *ops)
{
+ ops->prepare_commit = sde_encoder_phys_cmd_prepare_commit;
ops->is_master = sde_encoder_phys_cmd_is_master;
ops->mode_set = sde_encoder_phys_cmd_mode_set;
ops->mode_fixup = sde_encoder_phys_cmd_mode_fixup;
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index c783ab0..d33a5dc 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -353,16 +353,24 @@
{
struct sde_kms *sde_kms;
struct msm_drm_private *priv;
+ struct drm_device *dev;
+ struct drm_encoder *encoder;
if (!kms)
return;
sde_kms = to_sde_kms(kms);
+ dev = sde_kms->dev;
- if (!sde_kms->dev || !sde_kms->dev->dev_private)
+ if (!dev || !dev->dev_private)
return;
- priv = sde_kms->dev->dev_private;
+ priv = dev->dev_private;
sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+ if (encoder->crtc != NULL)
+ sde_encoder_prepare_commit(encoder);
+
}
static void sde_kms_commit(struct msm_kms *kms,