techpack: drm/msm/sde: add sysfs node for trigger wake up early
Add sysfs node on crtc to trigger sde wake up early. The command to trigger wake up early give in shell: echo 1 > /sys/class/drm/sde-crtc-*/early_wakeup Bug: 150196517 Test: trigger wake up and switch display power state Test: testInflatingEmojiListViewFling Test: testBrowseContentScroll Change-Id: I96e6ad73e83e8a9e3e5e65e064c92f8e6a6d63f8 Signed-off-by: Midas Chien <midaschieh@google.com> Signed-off-by: DennySPb <dennyspb@gmail.com> Signed-off-by: Karan Parashar <karan@pixelos.net>
This commit is contained in:
parent
29df08815f
commit
a0e90ad8ce
@ -217,6 +217,47 @@ static int _sde_debugfs_fps_status(struct inode *inode, struct file *file)
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t early_wakeup_store(struct device *device,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct msm_drm_private *priv;
|
||||
u32 crtc_id;
|
||||
bool trigger;
|
||||
|
||||
if (!device || !buf || !count) {
|
||||
SDE_ERROR("invalid input param(s)\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (kstrtobool(buf, &trigger) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!trigger)
|
||||
return count;
|
||||
|
||||
crtc = dev_get_drvdata(device);
|
||||
if (!crtc || !crtc->dev || !crtc->dev->dev_private) {
|
||||
SDE_ERROR("invalid crtc\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
priv = crtc->dev->dev_private;
|
||||
|
||||
crtc_id = drm_crtc_index(crtc);
|
||||
if (crtc_id >= ARRAY_SIZE(priv->disp_thread)) {
|
||||
SDE_ERROR("invalid crtc index[%d]\n", crtc_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kthread_queue_work(&priv->disp_thread[crtc_id].worker,
|
||||
&sde_crtc->early_wakeup_work);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t fps_periodicity_ms_store(struct device *device,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
@ -403,12 +444,14 @@ static DEVICE_ATTR_RO(vsync_event);
|
||||
static DEVICE_ATTR_RO(measured_fps);
|
||||
static DEVICE_ATTR_RW(fps_periodicity_ms);
|
||||
static DEVICE_ATTR_RO(retire_frame_event);
|
||||
static DEVICE_ATTR_WO(early_wakeup);
|
||||
|
||||
static struct attribute *sde_crtc_dev_attrs[] = {
|
||||
&dev_attr_vsync_event.attr,
|
||||
&dev_attr_measured_fps.attr,
|
||||
&dev_attr_fps_periodicity_ms.attr,
|
||||
&dev_attr_retire_frame_event.attr,
|
||||
&dev_attr_early_wakeup.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -6644,6 +6687,40 @@ void sde_crtc_cancel_delayed_work(struct drm_crtc *crtc)
|
||||
SDE_EVT32(DRMID(crtc), idle_status, cache_status);
|
||||
}
|
||||
|
||||
/*
|
||||
* __sde_crtc_early_wakeup_work - trigger early wakeup from user space
|
||||
*/
|
||||
static void __sde_crtc_early_wakeup_work(struct kthread_work *work)
|
||||
{
|
||||
struct sde_crtc *sde_crtc = container_of(work, struct sde_crtc,
|
||||
early_wakeup_work);
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_device *dev;
|
||||
struct msm_drm_private *priv;
|
||||
struct sde_kms *sde_kms;
|
||||
|
||||
if (!sde_crtc) {
|
||||
SDE_ERROR("invalid sde crtc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sde_crtc->enabled) {
|
||||
SDE_INFO("sde crtc is not enabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
crtc = &sde_crtc->base;
|
||||
dev = crtc->dev;
|
||||
if (!dev) {
|
||||
SDE_ERROR("invalid drm device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
priv = dev->dev_private;
|
||||
sde_kms = to_sde_kms(priv->kms);
|
||||
sde_kms_trigger_early_wakeup(sde_kms, crtc);
|
||||
}
|
||||
|
||||
/* initialize crtc */
|
||||
struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane)
|
||||
{
|
||||
@ -6740,6 +6817,8 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane)
|
||||
__sde_crtc_idle_notify_work);
|
||||
kthread_init_delayed_work(&sde_crtc->static_cache_read_work,
|
||||
__sde_crtc_static_cache_read_work);
|
||||
kthread_init_work(&sde_crtc->early_wakeup_work,
|
||||
__sde_crtc_early_wakeup_work);
|
||||
|
||||
SDE_DEBUG("crtc=%d new_llcc=%d, old_llcc=%d\n",
|
||||
crtc->base.id,
|
||||
|
@ -278,6 +278,7 @@ struct sde_crtc_misr_info {
|
||||
* @misr_frame_count : misr frame count provided by client
|
||||
* @misr_data : store misr data before turning off the clocks.
|
||||
* @idle_notify_work: delayed worker to notify idle timeout to user space
|
||||
* @early_wakeup_work: work to trigger early wakeup
|
||||
* @power_event : registered power event handle
|
||||
* @cur_perf : current performance committed to clock/bandwidth driver
|
||||
* @plane_mask_old: keeps track of the planes used in the previous commit
|
||||
@ -361,6 +362,7 @@ struct sde_crtc {
|
||||
bool misr_reconfigure;
|
||||
u32 misr_frame_count;
|
||||
struct kthread_delayed_work idle_notify_work;
|
||||
struct kthread_work early_wakeup_work;
|
||||
|
||||
struct sde_power_event *power_event;
|
||||
|
||||
|
@ -5544,3 +5544,27 @@ void sde_encoder_enable_recovery_event(struct drm_encoder *encoder)
|
||||
sde_enc = to_sde_encoder_virt(encoder);
|
||||
sde_enc->recovery_events_enabled = true;
|
||||
}
|
||||
|
||||
void sde_encoder_trigger_early_wakeup(struct drm_encoder *drm_enc)
|
||||
{
|
||||
struct sde_encoder_virt *sde_enc = NULL;
|
||||
struct msm_drm_private *priv = NULL;
|
||||
|
||||
priv = drm_enc->dev->dev_private;
|
||||
sde_enc = to_sde_encoder_virt(drm_enc);
|
||||
if (!sde_enc->crtc || (sde_enc->crtc->index
|
||||
>= ARRAY_SIZE(priv->disp_thread))) {
|
||||
SDE_DEBUG_ENC(sde_enc,
|
||||
"invalid cached CRTC: %d or crtc index: %d\n",
|
||||
sde_enc->crtc == NULL,
|
||||
sde_enc->crtc ? sde_enc->crtc->index : -EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) {
|
||||
SDE_ATRACE_BEGIN("sde_encoder_resource_control");
|
||||
sde_encoder_resource_control(drm_enc,
|
||||
SDE_ENC_RC_EVENT_EARLY_WAKEUP);
|
||||
SDE_ATRACE_END("sde_encoder_resource_control");
|
||||
}
|
||||
}
|
||||
|
@ -640,4 +640,11 @@ static inline bool sde_encoder_is_widebus_enabled(struct drm_encoder *drm_enc)
|
||||
sde_enc = to_sde_encoder_virt(drm_enc);
|
||||
return sde_enc->mode_info.wide_bus_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* sde_encoder_trigger_early_wakeup - trigger early wake up
|
||||
* @drm_enc: Pointer to drm encoder structure
|
||||
*/
|
||||
void sde_encoder_trigger_early_wakeup(struct drm_encoder *drm_enc);
|
||||
|
||||
#endif /* __SDE_ENCODER_H__ */
|
||||
|
@ -5129,3 +5129,26 @@ int sde_kms_handle_recovery(struct drm_encoder *encoder)
|
||||
SDE_EVT32(DRMID(encoder), MSM_ENC_ACTIVE_REGION);
|
||||
return sde_encoder_wait_for_event(encoder, MSM_ENC_ACTIVE_REGION);
|
||||
}
|
||||
|
||||
void sde_kms_trigger_early_wakeup(struct sde_kms *sde_kms,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct msm_drm_private *priv;
|
||||
struct drm_encoder *drm_enc;
|
||||
|
||||
if (!sde_kms || !crtc) {
|
||||
SDE_ERROR("invalid argument sde_kms %pK crtc %pK\n",
|
||||
sde_kms, crtc);
|
||||
return;
|
||||
}
|
||||
|
||||
priv = sde_kms->dev->dev_private;
|
||||
|
||||
SDE_ATRACE_BEGIN("sde_kms_trigger_early_wakeup");
|
||||
drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask)
|
||||
sde_encoder_trigger_early_wakeup(drm_enc);
|
||||
|
||||
if (sde_kms->first_kickoff)
|
||||
sde_power_scale_reg_bus(&priv->phandle, VOTE_INDEX_HIGH, false);
|
||||
SDE_ATRACE_END("sde_kms_trigger_early_wakeup");
|
||||
}
|
||||
|
@ -754,4 +754,13 @@ int sde_kms_vm_trusted_prepare_commit(struct sde_kms *sde_kms,
|
||||
*/
|
||||
int sde_kms_vm_primary_prepare_commit(struct sde_kms *sde_kms,
|
||||
struct drm_atomic_state *state);
|
||||
|
||||
/**
|
||||
* sde_kms_trigger_early_wakeup - trigger early wake up
|
||||
* @sde_kms: pointer to sde_kms structure
|
||||
* @crtc: pointer to drm_crtc structure
|
||||
*/
|
||||
void sde_kms_trigger_early_wakeup(struct sde_kms *sde_kms,
|
||||
struct drm_crtc *crtc);
|
||||
|
||||
#endif /* __sde_kms_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user