Merge "disp: msm: sde: update crtc check in drm_check_dpms"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
683bf52ce0
@@ -184,8 +184,7 @@ msm_disable_connector_outputs(struct drm_device *dev,
|
|||||||
{
|
{
|
||||||
struct drm_connector *connector;
|
struct drm_connector *connector;
|
||||||
struct drm_connector_state *old_conn_state;
|
struct drm_connector_state *old_conn_state;
|
||||||
struct drm_panel_notifier notifier_data;
|
int i;
|
||||||
int i, blank;
|
|
||||||
|
|
||||||
for_each_old_connector_in_state(old_state, connector,
|
for_each_old_connector_in_state(old_state, connector,
|
||||||
old_conn_state, i) {
|
old_conn_state, i) {
|
||||||
@@ -223,15 +222,6 @@ msm_disable_connector_outputs(struct drm_device *dev,
|
|||||||
DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n",
|
DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n",
|
||||||
encoder->base.id, encoder->name);
|
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,
|
|
||||||
¬ifier_data);
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Each encoder has at most one connector (since we always steal
|
* Each encoder has at most one connector (since we always steal
|
||||||
* it away), so we won't call disable hooks twice.
|
* 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);
|
funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||||
|
|
||||||
drm_bridge_post_disable(encoder->bridge);
|
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,
|
|
||||||
¬ifier_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_crtc_state *new_crtc_state;
|
||||||
struct drm_connector *connector;
|
struct drm_connector *connector;
|
||||||
struct drm_connector_state *new_conn_state;
|
struct drm_connector_state *new_conn_state;
|
||||||
struct drm_panel_notifier notifier_data;
|
|
||||||
struct msm_drm_private *priv = dev->dev_private;
|
struct msm_drm_private *priv = dev->dev_private;
|
||||||
struct msm_kms *kms = priv->kms;
|
struct msm_kms *kms = priv->kms;
|
||||||
int bridge_enable_count = 0;
|
int bridge_enable_count = 0;
|
||||||
int i, blank;
|
int i;
|
||||||
bool splash = false;
|
|
||||||
|
|
||||||
SDE_ATRACE_BEGIN("msm_enable");
|
SDE_ATRACE_BEGIN("msm_enable");
|
||||||
for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state,
|
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",
|
DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
|
||||||
encoder->base.id, encoder->name);
|
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,
|
|
||||||
¬ifier_data);
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Each encoder has at most one connector (since we always steal
|
* Each encoder has at most one connector (since we always steal
|
||||||
* it away), so we won't call enable hooks twice.
|
* 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);
|
encoder->base.id, encoder->name);
|
||||||
|
|
||||||
drm_bridge_enable(encoder->bridge);
|
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,
|
|
||||||
¬ifier_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SDE_ATRACE_END("msm_enable");
|
SDE_ATRACE_END("msm_enable");
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <drm/drm_crtc.h>
|
#include <drm/drm_crtc.h>
|
||||||
#include <drm/drm_fixed.h>
|
#include <drm/drm_fixed.h>
|
||||||
|
#include <drm/drm_panel.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_irq.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;
|
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, ¬ifier_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int sde_kms_vm_primary_prepare_commit(struct sde_kms *sde_kms,
|
int sde_kms_vm_primary_prepare_commit(struct sde_kms *sde_kms,
|
||||||
struct drm_atomic_state *state)
|
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)
|
if (vm_ops->vm_prepare_commit)
|
||||||
vm_ops->vm_prepare_commit(sde_kms, state);
|
vm_ops->vm_prepare_commit(sde_kms, state);
|
||||||
|
_sde_kms_drm_check_dpms(state, DRM_PANEL_EARLY_EVENT_BLANK);
|
||||||
end:
|
end:
|
||||||
SDE_ATRACE_END("prepare_commit");
|
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",
|
SDE_ERROR("vm post commit failed, rc = %d\n",
|
||||||
rc);
|
rc);
|
||||||
}
|
}
|
||||||
|
_sde_kms_drm_check_dpms(old_state, DRM_PANEL_EVENT_BLANK);
|
||||||
|
|
||||||
pm_runtime_put_sync(sde_kms->dev->dev);
|
pm_runtime_put_sync(sde_kms->dev->dev);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user