Browse Source

disp: msm: sde: add pm_qos support for high frame rate display

Add/remove pm_qos request during sde encoder resource
controller enable/disable for high frame rate and command mode display.

Change-Id: I95fab92de8399d8b892751d654e7913166856cf3
Signed-off-by: Narendra Muppalla <[email protected]>
Narendra Muppalla 5 năm trước cách đây
mục cha
commit
690deaec8e
4 tập tin đã thay đổi với 67 bổ sung24 xóa
  1. 53 21
      msm/sde/sde_encoder.c
  2. 4 2
      msm/sde/sde_encoder.h
  3. 7 0
      msm/sde/sde_hw_catalog.c
  4. 3 1
      msm/sde/sde_hw_catalog.h

+ 53 - 21
msm/sde/sde_encoder.c

@@ -149,31 +149,67 @@ void sde_encoder_uidle_enable(struct drm_encoder *drm_enc, bool enable)
 	}
 }
 
-static void _sde_encoder_pm_qos_add_request(struct drm_encoder *drm_enc,
-	struct sde_kms *sde_kms)
+static void _sde_encoder_pm_qos_add_request(struct drm_encoder *drm_enc)
 {
 	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
+	struct msm_drm_private *priv;
+	struct sde_kms *sde_kms;
+	struct device *cpu_dev;
+	struct cpumask *cpu_mask = NULL;
+	int cpu = 0;
 	u32 cpu_dma_latency;
 
-	if (!sde_kms->catalog)
+	priv = drm_enc->dev->dev_private;
+	sde_kms = to_sde_kms(priv->kms);
+
+	if (!sde_kms->catalog || !sde_kms->catalog->perf.cpu_mask)
 		return;
 
 	cpu_dma_latency = sde_kms->catalog->perf.cpu_dma_latency;
-	pm_qos_add_request(&sde_enc->pm_qos_cpu_req,
-			PM_QOS_CPU_DMA_LATENCY, cpu_dma_latency);
+	cpumask_clear(&sde_enc->valid_cpu_mask);
 
-	SDE_EVT32_VERBOSE(DRMID(drm_enc), cpu_dma_latency);
+	if (sde_enc->mode_info.frame_rate > FPS60)
+		cpu_mask = to_cpumask(&sde_kms->catalog->perf.cpu_mask_perf);
+	if (!cpu_mask &&
+			sde_encoder_check_curr_mode(drm_enc,
+				MSM_DISPLAY_CMD_MODE))
+		cpu_mask = to_cpumask(&sde_kms->catalog->perf.cpu_mask);
+
+	if (!cpu_mask)
+		return;
+
+	for_each_cpu(cpu, cpu_mask) {
+		cpu_dev = get_cpu_device(cpu);
+		if (!cpu_dev) {
+			SDE_ERROR("%s: failed to get cpu%d device\n", __func__,
+					cpu);
+			return;
+		}
+		cpumask_set_cpu(cpu, &sde_enc->valid_cpu_mask);
+		dev_pm_qos_add_request(cpu_dev,
+				&sde_enc->pm_qos_cpu_req[cpu],
+				DEV_PM_QOS_RESUME_LATENCY, cpu_dma_latency);
+		SDE_EVT32_VERBOSE(DRMID(drm_enc), cpu_dma_latency, cpu);
+	}
 }
 
-static void _sde_encoder_pm_qos_remove_request(struct drm_encoder *drm_enc,
-	struct sde_kms *sde_kms)
+static void _sde_encoder_pm_qos_remove_request(struct drm_encoder *drm_enc)
 {
 	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
-
-	if (!sde_kms->catalog)
-		return;
-
-	pm_qos_remove_request(&sde_enc->pm_qos_cpu_req);
+	struct device *cpu_dev;
+	int cpu = 0;
+
+	for_each_cpu(cpu, &sde_enc->valid_cpu_mask) {
+		cpu_dev = get_cpu_device(cpu);
+		if (!cpu_dev) {
+			SDE_ERROR("%s: failed to get cpu%d device\n", __func__,
+					cpu);
+			continue;
+		}
+		dev_pm_qos_remove_request(&sde_enc->pm_qos_cpu_req[cpu]);
+		SDE_EVT32_VERBOSE(DRMID(drm_enc), cpu);
+	}
+	cpumask_clear(&sde_enc->valid_cpu_mask);
 }
 
 static bool _sde_encoder_is_autorefresh_enabled(
@@ -1382,16 +1418,12 @@ static int _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
 	struct sde_kms *sde_kms;
 	struct sde_encoder_virt *sde_enc;
 	int rc;
-	bool is_cmd_mode = false;
 
 	sde_enc = to_sde_encoder_virt(drm_enc);
 	sde_kms = sde_encoder_get_kms(drm_enc);
 	if (!sde_kms)
 		return -EINVAL;
 
-	if (sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE))
-		is_cmd_mode = true;
-
 	SDE_DEBUG_ENC(sde_enc, "enable:%d\n", enable);
 	SDE_EVT32(DRMID(drm_enc), enable);
 
@@ -1422,12 +1454,10 @@ static int _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
 		/* enable all the irq */
 		_sde_encoder_irq_control(drm_enc, true);
 
-		if (is_cmd_mode)
-			_sde_encoder_pm_qos_add_request(drm_enc, sde_kms);
+		_sde_encoder_pm_qos_add_request(drm_enc);
 
 	} else {
-		if (is_cmd_mode)
-			_sde_encoder_pm_qos_remove_request(drm_enc, sde_kms);
+		_sde_encoder_pm_qos_remove_request(drm_enc);
 
 		/* disable all the irq */
 		_sde_encoder_irq_control(drm_enc, false);
@@ -1760,6 +1790,7 @@ static int _sde_encoder_rc_pre_modeset(struct drm_encoder *drm_enc,
 		SDE_ENC_RC_STATE_MODESET, SDE_EVTLOG_FUNC_CASE5);
 
 	sde_enc->rc_state = SDE_ENC_RC_STATE_MODESET;
+	_sde_encoder_pm_qos_remove_request(drm_enc);
 
 end:
 	mutex_unlock(&sde_enc->rc_lock);
@@ -1798,6 +1829,7 @@ static int _sde_encoder_rc_post_modeset(struct drm_encoder *drm_enc,
 			SDE_ENC_RC_STATE_ON, SDE_EVTLOG_FUNC_CASE6);
 
 	sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
+	_sde_encoder_pm_qos_add_request(drm_enc);
 
 end:
 	mutex_unlock(&sde_enc->rc_lock);

+ 4 - 2
msm/sde/sde_encoder.h

@@ -185,7 +185,8 @@ struct sde_encoder_ops {
  * @recovery_events_enabled:	status of hw recovery feature enable by client
  * @elevated_ahb_vote:		increase AHB bus speed for the first frame
  *				after power collapse
- * @pm_qos_cpu_req:		pm_qos request for cpu frequency
+ * @pm_qos_cpu_req:		qos request for all cpu core frequency
+ * @valid_cpu_mask:		actual voted cpu core mask
  * @mode_info:                  stores the current mode and should be used
  *				only in commit phase
  */
@@ -252,7 +253,8 @@ struct sde_encoder_virt {
 
 	bool recovery_events_enabled;
 	bool elevated_ahb_vote;
-	struct pm_qos_request pm_qos_cpu_req;
+	struct dev_pm_qos_request pm_qos_cpu_req[NR_CPUS];
+	struct cpumask valid_cpu_mask;
 	struct msm_mode_info mode_info;
 };
 

+ 7 - 0
msm/sde/sde_hw_catalog.c

@@ -220,6 +220,7 @@ enum {
 	PERF_AXI_BUS_WIDTH,
 	PERF_CDP_SETTING,
 	PERF_CPU_MASK,
+	CPU_MASK_PERF,
 	PERF_CPU_DMA_LATENCY,
 	PERF_PROP_MAX,
 };
@@ -593,6 +594,8 @@ static struct sde_prop_type sde_perf_prop[] = {
 	{PERF_CDP_SETTING, "qcom,sde-cdp-setting", false,
 			PROP_TYPE_U32_ARRAY},
 	{PERF_CPU_MASK, "qcom,sde-qos-cpu-mask", false, PROP_TYPE_U32},
+	{CPU_MASK_PERF, "qcom,sde-qos-cpu-mask-performance", false,
+			PROP_TYPE_U32},
 	{PERF_CPU_DMA_LATENCY, "qcom,sde-qos-cpu-dma-latency", false,
 			PROP_TYPE_U32},
 };
@@ -4246,6 +4249,10 @@ static int _sde_perf_parse_dt_cfg(struct device_node *np,
 			prop_exists[PERF_CPU_MASK] ?
 			PROP_VALUE_ACCESS(prop_value, PERF_CPU_MASK, 0) :
 			DEFAULT_CPU_MASK;
+	cfg->perf.cpu_mask_perf =
+			prop_exists[CPU_MASK_PERF] ?
+			PROP_VALUE_ACCESS(prop_value, CPU_MASK_PERF, 0) :
+			DEFAULT_CPU_MASK;
 	cfg->perf.cpu_dma_latency =
 			prop_exists[PERF_CPU_DMA_LATENCY] ?
 			PROP_VALUE_ACCESS(prop_value, PERF_CPU_DMA_LATENCY, 0) :

+ 3 - 1
msm/sde/sde_hw_catalog.h

@@ -1297,6 +1297,7 @@ struct sde_sc_cfg {
  * @qos_refresh_rate: different refresh rates for luts
  * @cdp_cfg            cdp use case configurations
  * @cpu_mask:          pm_qos cpu mask value
+ * @cpu_mask_perf:     pm_qos cpu silver core mask value
  * @cpu_dma_latency:   pm_qos cpu dma latency value
  * @axi_bus_width:     axi bus width value in bytes
  * @num_mnoc_ports:    number of mnoc ports
@@ -1326,7 +1327,8 @@ struct sde_perf_cfg {
 	u32 qos_refresh_count;
 	u32 *qos_refresh_rate;
 	struct sde_perf_cdp_cfg cdp_cfg[SDE_PERF_CDP_USAGE_MAX];
-	u32 cpu_mask;
+	unsigned long cpu_mask;
+	unsigned long cpu_mask_perf;
 	u32 cpu_dma_latency;
 	u32 axi_bus_width;
 	u32 num_mnoc_ports;