Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea264fd5 authored by Adrian Salido's avatar Adrian Salido Committed by Gerrit - the friendly Code Review server
Browse files

disp: msm: add low power mode notifier



Introduce low power mode so that listeners are aware when display is
going into low power mode. This requires moving notifier inside sde code
to be able to retrieve the low power state.

Change-Id: I8671e86af29c959d97e1b8ad758a07719ffa4bec
(cherry picked from commit c4b15f56dd63d24d6f4482deab2423809c700d7a)
Signed-off-by: default avatarAdrian Salido <salidoa@google.com>
[samtran@codeaurora.org: change include header file to
 point to different file where corresponding changes have
 been made]
Signed-off-by: default avatarSamantha Tran <samtran@codeaurora.org>
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 700f3cc7
Loading
Loading
Loading
Loading
+2 −44
Original line number Diff line number Diff line
@@ -144,8 +144,7 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
	struct drm_connector_state *old_conn_state;
	struct drm_crtc *crtc;
	struct drm_crtc_state *old_crtc_state;
	struct drm_panel_notifier notifier_data;
	int i, blank;
	int i;

	SDE_ATRACE_BEGIN("msm_disable");
	for_each_old_connector_in_state(old_state, connector,
@@ -184,15 +183,6 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
		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 = &blank;
			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.
@@ -208,14 +198,6 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
			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);
		}
	}

	for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
@@ -359,12 +341,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,
@@ -424,19 +404,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 = &blank;
			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.
@@ -485,15 +452,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");
}
+71 −0
Original line number Diff line number Diff line
@@ -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>
@@ -844,6 +845,72 @@ 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;
	int i, old_mode, new_mode;

	for_each_old_connector_in_state(old_state, connector,
			old_conn_state, i) {
		if (!connector->state->crtc)
			continue;

		new_mode = _sde_kms_get_blank(connector->state->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_mode = _sde_kms_get_blank(old_crtc_state,
							old_conn_state);
		} else {
			old_mode = DRM_PANEL_BLANK_POWERDOWN;
		}

		if (old_mode != new_mode) {
			struct drm_panel_notifier notifier_data;

			pr_debug("power mode change detected %d->%d\n",
				old_mode, new_mode);

			notifier_data.data = &new_mode;

			drm_panel_notifier_call_chain(connector->panel,
							event, &notifier_data);
		}
	}
}

static void sde_kms_prepare_commit(struct msm_kms *kms,
		struct drm_atomic_state *state)
{
@@ -893,6 +960,8 @@ static void sde_kms_prepare_commit(struct msm_kms *kms,
	 * transitions prepare below if any transtions is required.
	 */
	sde_kms_prepare_secure_transition(kms, state);

	_sde_kms_drm_check_dpms(state, DRM_PANEL_EARLY_EVENT_BLANK);
end:
	SDE_ATRACE_END("prepare_commit");
}
@@ -1038,6 +1107,8 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
		}
	}

	_sde_kms_drm_check_dpms(old_state, DRM_PANEL_EVENT_BLANK);

	pm_runtime_put_sync(sde_kms->dev->dev);

	for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i)