drm/msm/sde: add inline prefill to rsc request
Update rsc prefill calculation to include inline rotation prefill.
During inline rotation, there is one additional block row latency
due to internal caching.
CRs-Fixed: 2009714
Change-Id: I76184359521b7d6ce43960d5628210c0252eceb1
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index ec5ec1d..6a22115 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -420,6 +420,19 @@
}
/**
+ * sde_crtc_get_inline_prefill - get current inline rotation prefill
+ * @crtc: Pointer to crtc
+ * return: number of prefill lines
+ */
+static inline u32 sde_crtc_get_inline_prefill(struct drm_crtc *crtc)
+{
+ if (!crtc || !crtc->state)
+ return 0;
+
+ return to_sde_crtc_state(crtc->state)->sbuf_prefill_line;
+}
+
+/**
* sde_crtc_event_queue - request event callback
* @crtc: Pointer to drm crtc structure
* @func: Pointer to callback function
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 39127e0..f11ba51 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -154,6 +154,7 @@
* clks and resources after IDLE_TIMEOUT time.
* @topology: topology of the display
* @mode_set_complete: flag to indicate modeset completion
+ * @rsc_cfg: rsc configuration
*/
struct sde_encoder_virt {
struct drm_encoder base;
@@ -192,6 +193,8 @@
struct delayed_work delayed_off_work;
struct msm_display_topology topology;
bool mode_set_complete;
+
+ struct sde_encoder_rsc_config rsc_cfg;
};
#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)
@@ -760,7 +763,8 @@
}
static int sde_encoder_update_rsc_client(
- struct drm_encoder *drm_enc, bool enable)
+ struct drm_encoder *drm_enc,
+ struct sde_encoder_rsc_config *config, bool enable)
{
struct sde_encoder_virt *sde_enc;
enum sde_rsc_state rsc_state;
@@ -791,14 +795,22 @@
disp_info->is_primary) ? SDE_RSC_CMD_STATE :
SDE_RSC_VID_STATE) : SDE_RSC_IDLE_STATE;
+ if (config && memcmp(&sde_enc->rsc_cfg, config,
+ sizeof(sde_enc->rsc_cfg)))
+ sde_enc->rsc_state_init = false;
+
if (rsc_state != SDE_RSC_IDLE_STATE && !sde_enc->rsc_state_init
&& disp_info->is_primary) {
rsc_config.fps = disp_info->frame_rate;
rsc_config.vtotal = disp_info->vtotal;
rsc_config.prefill_lines = disp_info->prefill_lines;
rsc_config.jitter = disp_info->jitter;
+ rsc_config.prefill_lines += config ?
+ config->inline_rotate_prefill : 0;
/* update it only once */
sde_enc->rsc_state_init = true;
+ if (config)
+ sde_enc->rsc_cfg = *config;
ret = sde_rsc_client_state_update(sde_enc->rsc_client,
rsc_state, &rsc_config,
@@ -835,6 +847,7 @@
struct msm_drm_private *priv;
struct sde_kms *sde_kms;
struct sde_encoder_virt *sde_enc;
+ struct sde_encoder_rsc_config rsc_cfg = { 0 };
int i;
sde_enc = to_sde_encoder_virt(drm_enc);
@@ -865,13 +878,16 @@
phys->ops.irq_control(phys, true);
}
+ rsc_cfg.inline_rotate_prefill =
+ sde_crtc_get_inline_prefill(drm_enc->crtc);
+
/* enable RSC */
- sde_encoder_update_rsc_client(drm_enc, true);
+ sde_encoder_update_rsc_client(drm_enc, &rsc_cfg, true);
} else {
/* disable RSC */
- sde_encoder_update_rsc_client(drm_enc, false);
+ sde_encoder_update_rsc_client(drm_enc, NULL, false);
/* disable all the irq */
for (i = 0; i < sde_enc->num_phys_encs; i++) {
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h
index b756313..7292a12 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.h
@@ -57,6 +57,14 @@
};
/**
+ * sde_encoder_rsc_config - rsc configuration for encoder
+ * @inline_rotate_prefill: number of lines to prefill for inline rotation
+ */
+struct sde_encoder_rsc_config {
+ u32 inline_rotate_prefill;
+};
+
+/**
* sde_encoder_get_hw_resources - Populate table of required hardware resources
* @encoder: encoder pointer
* @hw_res: resource table to populate with encoder required resources
@@ -141,24 +149,6 @@
void sde_encoder_virt_restore(struct drm_encoder *encoder);
/**
- * enum sde_encoder_property - property tags for sde enoder
- * @SDE_ENCODER_PROPERTY_INLINE_ROTATE_REFILL: # of prefill line, 0 to disable
- */
-enum sde_encoder_property {
- SDE_ENCODER_PROPERTY_INLINE_ROTATE_PREFILL,
- SDE_ENCODER_PROPERTY_MAX,
-};
-
-/*
- * sde_encoder_set_property - set the property tag to the given value
- * @encoder: Pointer to drm encoder object
- * @tag: property tag
- * @val: property value
- * return: 0 if success; errror code otherwise
- */
-int sde_encoder_set_property(struct drm_encoder *encoder, u32 tag, u64 val);
-
-/**
* sde_encoder_init - initialize virtual encoder object
* @dev: Pointer to drm device structure
* @disp_info: Pointer to display information structure