浏览代码

Merge "disp: msm: sde: update crtc check in drm_check_dpms"

qctecmdr 4 年之前
父节点
当前提交
683bf52ce0
共有 2 个文件被更改,包括 92 次插入44 次删除
  1. 2 44
      msm/msm_atomic.c
  2. 90 0
      msm/sde/sde_kms.c

+ 2 - 44
msm/msm_atomic.c

@@ -184,8 +184,7 @@ msm_disable_connector_outputs(struct drm_device *dev,
 {
 	struct drm_connector *connector;
 	struct drm_connector_state *old_conn_state;
-	struct drm_panel_notifier notifier_data;
-	int i, blank;
+	int i;
 
 	for_each_old_connector_in_state(old_state, connector,
 			old_conn_state, i) {
@@ -223,15 +222,6 @@ msm_disable_connector_outputs(struct drm_device *dev,
 		DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n",
 				 encoder->base.id, encoder->name);
 
-		if (connector->state->crtc &&
-			connector->state->crtc->state->active_changed) {
-			blank = DRM_PANEL_BLANK_POWERDOWN;
-			notifier_data.data = ␣
-			if (connector->panel)
-				drm_panel_notifier_call_chain(connector->panel,
-					DRM_PANEL_EARLY_EVENT_BLANK,
-					&notifier_data);
-		}
 		/*
 		 * Each encoder has at most one connector (since we always steal
 		 * it away), so we won't call disable hooks twice.
@@ -247,14 +237,6 @@ msm_disable_connector_outputs(struct drm_device *dev,
 			funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
 
 		drm_bridge_post_disable(encoder->bridge);
-		if (connector->state->crtc &&
-			connector->state->crtc->state->active_changed) {
-			DRM_DEBUG_ATOMIC("Notify blank\n");
-			if (connector->panel)
-				drm_panel_notifier_call_chain(connector->panel,
-					DRM_PANEL_EVENT_BLANK,
-					&notifier_data);
-		}
 	}
 }
 
@@ -410,12 +392,10 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
 	struct drm_crtc_state *new_crtc_state;
 	struct drm_connector *connector;
 	struct drm_connector_state *new_conn_state;
-	struct drm_panel_notifier notifier_data;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct msm_kms *kms = priv->kms;
 	int bridge_enable_count = 0;
-	int i, blank;
-	bool splash = false;
+	int i;
 
 	SDE_ATRACE_BEGIN("msm_enable");
 	for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state,
@@ -475,19 +455,6 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
 		DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
 				 encoder->base.id, encoder->name);
 
-		if (kms && kms->funcs && kms->funcs->check_for_splash)
-			splash = kms->funcs->check_for_splash(kms);
-
-		if (splash || (connector->state->crtc &&
-			connector->state->crtc->state->active_changed)) {
-			blank = DRM_PANEL_BLANK_UNBLANK;
-			notifier_data.data = ␣
-			DRM_DEBUG_ATOMIC("Notify early unblank\n");
-			if (connector->panel)
-				drm_panel_notifier_call_chain(connector->panel,
-					DRM_PANEL_EARLY_EVENT_BLANK,
-					&notifier_data);
-		}
 		/*
 		 * Each encoder has at most one connector (since we always steal
 		 * it away), so we won't call enable hooks twice.
@@ -536,15 +503,6 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
 				 encoder->base.id, encoder->name);
 
 		drm_bridge_enable(encoder->bridge);
-
-		if (splash || (connector->state->crtc &&
-			connector->state->crtc->state->active_changed)) {
-			DRM_DEBUG_ATOMIC("Notify unblank\n");
-			if (connector->panel)
-				drm_panel_notifier_call_chain(connector->panel,
-					DRM_PANEL_EVENT_BLANK,
-					&notifier_data);
-		}
 	}
 	SDE_ATRACE_END("msm_enable");
 }

+ 90 - 0
msm/sde/sde_kms.c

@@ -20,6 +20,7 @@
 
 #include <drm/drm_crtc.h>
 #include <drm/drm_fixed.h>
+#include <drm/drm_panel.h>
 #include <linux/debugfs.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
@@ -941,6 +942,93 @@ static int _sde_kms_unmap_all_splash_regions(struct sde_kms *sde_kms)
 	return ret;
 }
 
+static int _sde_kms_get_blank(struct drm_crtc_state *crtc_state,
+		struct drm_connector_state *conn_state)
+{
+	int lp_mode, blank;
+
+	if (crtc_state->active)
+		lp_mode = sde_connector_get_property(conn_state,
+							CONNECTOR_PROP_LP);
+	else
+		lp_mode = SDE_MODE_DPMS_OFF;
+
+	switch (lp_mode) {
+	case SDE_MODE_DPMS_ON:
+		blank = DRM_PANEL_BLANK_UNBLANK;
+		break;
+	case SDE_MODE_DPMS_LP1:
+	case SDE_MODE_DPMS_LP2:
+		blank = DRM_PANEL_BLANK_LP;
+		break;
+	case SDE_MODE_DPMS_OFF:
+	default:
+		blank = DRM_PANEL_BLANK_POWERDOWN;
+		break;
+	}
+
+	return blank;
+}
+
+static void _sde_kms_drm_check_dpms(struct drm_atomic_state *old_state,
+			unsigned long event)
+{
+	struct drm_connector *connector;
+	struct drm_connector_state *old_conn_state;
+	struct drm_crtc_state *old_crtc_state;
+	struct drm_crtc *crtc;
+	int i, old_mode, new_mode, old_fps, new_fps;
+
+	for_each_old_connector_in_state(old_state, connector,
+			old_conn_state, i) {
+		crtc = connector->state->crtc ? connector->state->crtc :
+			old_conn_state->crtc;
+		if (!crtc)
+			continue;
+
+		new_fps = crtc->state->mode.vrefresh;
+		new_mode = _sde_kms_get_blank(crtc->state, connector->state);
+		if (old_conn_state->crtc) {
+			old_crtc_state = drm_atomic_get_existing_crtc_state(
+					old_state, old_conn_state->crtc);
+
+			old_fps = old_crtc_state->mode.vrefresh;
+			old_mode = _sde_kms_get_blank(old_crtc_state,
+							old_conn_state);
+		} else {
+			old_fps = 0;
+			old_mode = DRM_PANEL_BLANK_POWERDOWN;
+		}
+
+		if ((old_mode != new_mode) || (old_fps != new_fps)) {
+			struct drm_panel_notifier notifier_data;
+
+			SDE_EVT32(old_mode, new_mode, old_fps, new_fps,
+				connector->panel, crtc->state->active,
+				old_conn_state->crtc, event);
+			pr_debug("change detected (power mode %d->%d, fps %d->%d)\n",
+				old_mode, new_mode, old_fps, new_fps);
+
+			/* If suspend resume and fps change are happening
+			 * at the same time, give preference to power mode
+			 * changes rather than fps change.
+			 */
+
+			if ((old_mode == new_mode) && (old_fps != new_fps))
+				new_mode = DRM_PANEL_BLANK_FPS_CHANGE;
+
+			notifier_data.data = &new_mode;
+			notifier_data.refresh_rate = new_fps;
+			notifier_data.id = connector->base.id;
+
+			if (connector->panel)
+				drm_panel_notifier_call_chain(connector->panel,
+							event, &notifier_data);
+		}
+	}
+
+}
+
 int sde_kms_vm_primary_prepare_commit(struct sde_kms *sde_kms,
 				      struct drm_atomic_state *state)
 {
@@ -1081,6 +1169,7 @@ static void sde_kms_prepare_commit(struct msm_kms *kms,
 
 	if (vm_ops->vm_prepare_commit)
 		vm_ops->vm_prepare_commit(sde_kms, state);
+	_sde_kms_drm_check_dpms(state, DRM_PANEL_EARLY_EVENT_BLANK);
 end:
 	SDE_ATRACE_END("prepare_commit");
 }
@@ -1419,6 +1508,7 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
 			SDE_ERROR("vm post commit failed, rc = %d\n",
 				  rc);
 	}
+	_sde_kms_drm_check_dpms(old_state, DRM_PANEL_EVENT_BLANK);
 
 	pm_runtime_put_sync(sde_kms->dev->dev);