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

This commit is contained in:
qctecmdr
2020-09-12 19:19:50 -07:00
committed by Gerrit - the friendly Code Review server
2 changed files with 92 additions and 44 deletions

View File

@@ -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);