فهرست منبع

Merge "disp: msm: sde: fix vsync wakeup time"

qctecmdr 5 سال پیش
والد
کامیت
a6128a06ce
1فایلهای تغییر یافته به همراه25 افزوده شده و 60 حذف شده
  1. 25 60
      msm/sde/sde_encoder.c

+ 25 - 60
msm/sde/sde_encoder.c

@@ -3607,61 +3607,14 @@ void sde_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
 	sde_enc->idle_pc_restore = false;
 }
 
-static u32 _sde_encoder_calculate_linetime(struct sde_encoder_virt *sde_enc,
-		struct drm_display_mode *mode)
-{
-	u64 pclk_rate;
-	u32 pclk_period;
-	u32 line_time;
-
-	/*
-	 * For linetime calculation, only operate on master encoder.
-	 */
-	if (!sde_enc->cur_master)
-		return 0;
-
-	if (!sde_enc->cur_master->ops.get_line_count) {
-		SDE_ERROR("get_line_count function not defined\n");
-		return 0;
-	}
-
-	pclk_rate = mode->clock; /* pixel clock in kHz */
-	if (pclk_rate == 0) {
-		SDE_ERROR("pclk is 0, cannot calculate line time\n");
-		return 0;
-	}
-
-	pclk_period = DIV_ROUND_UP_ULL(1000000000ull, pclk_rate);
-	if (pclk_period == 0) {
-		SDE_ERROR("pclk period is 0\n");
-		return 0;
-	}
-
-	/*
-	 * Line time calculation based on Pixel clock and HTOTAL.
-	 * Final unit is in ns.
-	 */
-	line_time = (pclk_period * mode->htotal) / 1000;
-	if (line_time == 0) {
-		SDE_ERROR("line time calculation is 0\n");
-		return 0;
-	}
-
-	SDE_DEBUG_ENC(sde_enc,
-			"clk_rate=%lldkHz, clk_period=%d, linetime=%dns\n",
-			pclk_rate, pclk_period, line_time);
-
-	return line_time;
-}
-
 static int _sde_encoder_wakeup_time(struct drm_encoder *drm_enc,
 		ktime_t *wakeup_time)
 {
 	struct drm_display_mode *mode;
 	struct sde_encoder_virt *sde_enc;
-	u32 cur_line;
-	u32 line_time;
-	u32 vtotal, time_to_vsync;
+	u32 cur_line, lines_left;
+	u32 line_time, mdp_transfer_time_us;
+	u32 vtotal, time_to_vsync_us, threshold_time_us = 0;
 	ktime_t cur_time;
 
 	sde_enc = to_sde_encoder_virt(drm_enc);
@@ -3671,31 +3624,43 @@ static int _sde_encoder_wakeup_time(struct drm_encoder *drm_enc,
 	}
 
 	mode = &sde_enc->cur_master->cached_mode;
+	mdp_transfer_time_us = sde_enc->mode_info.mdp_transfer_time_us;
 
-	line_time = _sde_encoder_calculate_linetime(sde_enc, mode);
-	if (!line_time)
+	vtotal = mode->vtotal;
+	if (!mdp_transfer_time_us) {
+		/* mdp_transfer_time set to 0 for video mode */
+		line_time = (1000000 / sde_enc->mode_info.frame_rate) / vtotal;
+	} else {
+		line_time = mdp_transfer_time_us / vtotal;
+		threshold_time_us = ((1000000 / sde_enc->mode_info.frame_rate)
+						- mdp_transfer_time_us);
+	}
+
+	if (!sde_enc->cur_master->ops.get_line_count) {
+		SDE_DEBUG_ENC(sde_enc, "can't get master line count\n");
 		return -EINVAL;
+	}
 
 	cur_line = sde_enc->cur_master->ops.get_line_count(sde_enc->cur_master);
 
-	vtotal = mode->vtotal;
-	if (cur_line >= vtotal)
-		time_to_vsync = line_time * vtotal;
-	else
-		time_to_vsync = line_time * (vtotal - cur_line);
+	lines_left = (cur_line >= vtotal) ? vtotal : (vtotal - cur_line);
+
+	time_to_vsync_us = line_time * lines_left;
 
-	if (time_to_vsync == 0) {
+	if (!time_to_vsync_us) {
 		SDE_ERROR("time to vsync should not be zero, vtotal=%d\n",
 				vtotal);
 		return -EINVAL;
 	}
 
 	cur_time = ktime_get();
-	*wakeup_time = ktime_add_ns(cur_time, time_to_vsync);
+	*wakeup_time = ktime_add_us(cur_time, time_to_vsync_us);
+	if (threshold_time_us)
+		*wakeup_time = ktime_add_us(*wakeup_time, threshold_time_us);
 
 	SDE_DEBUG_ENC(sde_enc,
 			"cur_line=%u vtotal=%u time_to_vsync=%u, cur_time=%lld, wakeup_time=%lld\n",
-			cur_line, vtotal, time_to_vsync,
+			cur_line, vtotal, time_to_vsync_us,
 			ktime_to_ms(cur_time),
 			ktime_to_ms(*wakeup_time));
 	return 0;