Merge changes I63392417,I6ca0188d into display-kernel.lnx.5.4
* changes: disp: msm: add trace logs in display early wakeup function disp: msm: add support for display early wakeup
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
87f5eca6e0
@@ -1626,6 +1626,57 @@ int msm_ioctl_power_ctrl(struct drm_device *dev, void *data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* msm_ioctl_display_early_wakeup - early wakeup display.
|
||||
* @dev: drm device for the ioctl
|
||||
* @data: data pointer for the ioctl
|
||||
* @file_priv: drm file for the ioctl call
|
||||
*
|
||||
*/
|
||||
int msm_ioctl_display_hint_ops(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_msm_display_hint *display_hint = data;
|
||||
struct drm_msm_early_wakeup early_wakeup;
|
||||
void __user *early_wakeup_usr;
|
||||
struct msm_drm_private *priv;
|
||||
struct msm_kms *kms;
|
||||
|
||||
priv = dev->dev_private;
|
||||
kms = priv->kms;
|
||||
|
||||
if (unlikely(!display_hint)) {
|
||||
DRM_ERROR("invalid ioctl data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SDE_EVT32(display_hint->hint_flags);
|
||||
|
||||
if (display_hint->hint_flags == DRM_MSM_DISPLAY_EARLY_WAKEUP_HINT) {
|
||||
if (!display_hint->data) {
|
||||
DRM_ERROR("early_wakeup: wrong parameter\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
early_wakeup_usr =
|
||||
(void __user *)((uintptr_t)display_hint->data);
|
||||
|
||||
if (copy_from_user(&early_wakeup, early_wakeup_usr,
|
||||
sizeof(early_wakeup))) {
|
||||
DRM_ERROR("early_wakeup: copy from user failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SDE_EVT32(early_wakeup.wakeup_hint);
|
||||
if (kms && kms->funcs && kms->funcs->display_early_wakeup
|
||||
&& early_wakeup.wakeup_hint)
|
||||
kms->funcs->display_early_wakeup(dev,
|
||||
early_wakeup.connector_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_ioctl_desc msm_ioctls[] = {
|
||||
DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
@@ -1639,6 +1690,8 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
|
||||
DRM_IOCTL_DEF_DRV(MSM_RMFB2, msm_ioctl_rmfb2, DRM_UNLOCKED),
|
||||
DRM_IOCTL_DEF_DRV(MSM_POWER_CTRL, msm_ioctl_power_ctrl,
|
||||
DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(MSM_DISPLAY_HINT, msm_ioctl_display_hint_ops,
|
||||
DRM_UNLOCKED),
|
||||
};
|
||||
|
||||
static const struct vm_operations_struct vm_ops = {
|
||||
|
@@ -100,6 +100,8 @@ struct msm_kms_funcs {
|
||||
void (*set_encoder_mode)(struct msm_kms *kms,
|
||||
struct drm_encoder *encoder,
|
||||
bool cmd_mode);
|
||||
void (*display_early_wakeup)(struct drm_device *dev,
|
||||
const int32_t connector_id);
|
||||
/* pm suspend/resume hooks */
|
||||
int (*pm_suspend)(struct device *dev);
|
||||
int (*pm_resume)(struct device *dev);
|
||||
|
@@ -3690,6 +3690,53 @@ static void sde_encoder_input_event_work_handler(struct kthread_work *work)
|
||||
SDE_ENC_RC_EVENT_EARLY_WAKEUP);
|
||||
}
|
||||
|
||||
static void sde_encoder_early_wakeup_work_handler(struct kthread_work *work)
|
||||
{
|
||||
struct sde_encoder_virt *sde_enc = container_of(work,
|
||||
struct sde_encoder_virt, early_wakeup_work);
|
||||
|
||||
if (!sde_enc) {
|
||||
SDE_ERROR("invalid sde encoder\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SDE_ATRACE_BEGIN("encoder_early_wakeup");
|
||||
sde_encoder_resource_control(&sde_enc->base,
|
||||
SDE_ENC_RC_EVENT_EARLY_WAKEUP);
|
||||
SDE_ATRACE_END("encoder_early_wakeup");
|
||||
}
|
||||
|
||||
void sde_encoder_early_wakeup(struct drm_encoder *drm_enc)
|
||||
{
|
||||
struct sde_encoder_virt *sde_enc = NULL;
|
||||
struct msm_drm_thread *disp_thread = NULL;
|
||||
struct msm_drm_private *priv = NULL;
|
||||
|
||||
priv = drm_enc->dev->dev_private;
|
||||
sde_enc = to_sde_encoder_virt(drm_enc);
|
||||
|
||||
if (!sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE)) {
|
||||
SDE_DEBUG_ENC(sde_enc,
|
||||
"should only early wake up command mode display\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sde_enc->crtc || (sde_enc->crtc->index
|
||||
>= ARRAY_SIZE(priv->event_thread))) {
|
||||
SDE_ERROR("invalid CRTC: %d or crtc index: %d\n",
|
||||
sde_enc->crtc == NULL,
|
||||
sde_enc->crtc ? sde_enc->crtc->index : -EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
disp_thread = &priv->disp_thread[sde_enc->crtc->index];
|
||||
|
||||
SDE_ATRACE_BEGIN("queue_early_wakeup_work");
|
||||
kthread_queue_work(&disp_thread->worker,
|
||||
&sde_enc->early_wakeup_work);
|
||||
SDE_ATRACE_END("queue_early_wakeup_work");
|
||||
}
|
||||
|
||||
int sde_encoder_poll_line_counts(struct drm_encoder *drm_enc)
|
||||
{
|
||||
static const uint64_t timeout_us = 50000;
|
||||
@@ -4812,6 +4859,9 @@ struct drm_encoder *sde_encoder_init_with_ops(
|
||||
kthread_init_work(&sde_enc->input_event_work,
|
||||
sde_encoder_input_event_work_handler);
|
||||
|
||||
kthread_init_work(&sde_enc->early_wakeup_work,
|
||||
sde_encoder_early_wakeup_work_handler);
|
||||
|
||||
kthread_init_work(&sde_enc->esd_trigger_work,
|
||||
sde_encoder_esd_trigger_work_handler);
|
||||
|
||||
|
@@ -168,6 +168,7 @@ struct sde_encoder_ops {
|
||||
* @rc_state: resource controller state
|
||||
* @delayed_off_work: delayed worker to schedule disabling of
|
||||
* clks and resources after IDLE_TIMEOUT time.
|
||||
* @early_wakeup_work: worker to handle early wakeup event
|
||||
* @input_event_work: worker to handle input device touch events
|
||||
* @esd_trigger_work: worker to handle esd trigger events
|
||||
* @input_handler: handler for input device events
|
||||
@@ -234,6 +235,7 @@ struct sde_encoder_virt {
|
||||
struct mutex rc_lock;
|
||||
enum sde_enc_rc_states rc_state;
|
||||
struct kthread_delayed_work delayed_off_work;
|
||||
struct kthread_work early_wakeup_work;
|
||||
struct kthread_work input_event_work;
|
||||
struct kthread_work esd_trigger_work;
|
||||
struct input_handler *input_handler;
|
||||
@@ -267,6 +269,12 @@ void sde_encoder_get_hw_resources(struct drm_encoder *encoder,
|
||||
struct sde_encoder_hw_resources *hw_res,
|
||||
struct drm_connector_state *conn_state);
|
||||
|
||||
/**
|
||||
* sde_encoder_early_wakeup - early wake up display
|
||||
* @encoder: encoder pointer
|
||||
*/
|
||||
void sde_encoder_early_wakeup(struct drm_encoder *drm_enc);
|
||||
|
||||
/**
|
||||
* sde_encoder_register_vblank_callback - provide callback to encoder that
|
||||
* will be called on the next vblank.
|
||||
|
@@ -3134,6 +3134,32 @@ end:
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
}
|
||||
|
||||
|
||||
void sde_kms_display_early_wakeup(struct drm_device *dev,
|
||||
const int32_t connector_id)
|
||||
{
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct drm_connector *conn;
|
||||
struct drm_encoder *drm_enc;
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
|
||||
drm_for_each_connector_iter(conn, &conn_iter) {
|
||||
if (connector_id != DRM_MSM_WAKE_UP_ALL_DISPLAYS &&
|
||||
connector_id != conn->base.id)
|
||||
continue;
|
||||
|
||||
if (conn->state && conn->state->best_encoder)
|
||||
drm_enc = conn->state->best_encoder;
|
||||
else
|
||||
drm_enc = conn->encoder;
|
||||
|
||||
sde_encoder_early_wakeup(drm_enc);
|
||||
}
|
||||
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
}
|
||||
|
||||
static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
|
||||
struct device *dev)
|
||||
{
|
||||
@@ -3408,6 +3434,7 @@ static const struct msm_kms_funcs kms_funcs = {
|
||||
.atomic_check = sde_kms_atomic_check,
|
||||
.get_format = sde_get_msm_format,
|
||||
.round_pixclk = sde_kms_round_pixclk,
|
||||
.display_early_wakeup = sde_kms_display_early_wakeup,
|
||||
.pm_suspend = sde_kms_pm_suspend,
|
||||
.pm_resume = sde_kms_pm_resume,
|
||||
.destroy = sde_kms_destroy,
|
||||
|
Reference in New Issue
Block a user