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