disp: msm: sde: add custom event to notify OPR, MISR value change
This change collects the OPR, MISR values. If the values are different than the previous then notify to client with custom event. Change-Id: I2546439be1f665d90e6505d65283d28096bf7cdd Signed-off-by: Akshay Ashtunkar <quic_akshayaa@quicinc.com>
此提交包含在:
@@ -78,7 +78,8 @@ static int _sde_crtc_set_noise_layer(struct sde_crtc *sde_crtc,
|
||||
void __user *usr_ptr);
|
||||
static int sde_crtc_vm_release_handler(struct drm_crtc *crtc_drm,
|
||||
bool en, struct sde_irq_callback *irq);
|
||||
|
||||
static int sde_crtc_opr_event_handler(struct drm_crtc *crtc_drm,
|
||||
bool en, struct sde_irq_callback *irq);
|
||||
|
||||
static struct sde_crtc_custom_events custom_events[] = {
|
||||
{DRM_EVENT_AD_BACKLIGHT, sde_cp_ad_interrupt},
|
||||
@@ -92,6 +93,7 @@ static struct sde_crtc_custom_events custom_events[] = {
|
||||
{DRM_EVENT_MMRM_CB, sde_crtc_mmrm_interrupt_handler},
|
||||
{DRM_EVENT_VM_RELEASE, sde_crtc_vm_release_handler},
|
||||
{DRM_EVENT_FRAME_DATA, sde_crtc_frame_data_interrupt_handler},
|
||||
{DRM_EVENT_OPR_VALUE, sde_crtc_opr_event_handler},
|
||||
};
|
||||
|
||||
/* default input fence timeout, in ms */
|
||||
@@ -2989,6 +2991,56 @@ static void _sde_crtc_retire_event(struct drm_connector *connector,
|
||||
SDE_ATRACE_END("signal_retire_fence");
|
||||
}
|
||||
|
||||
void sde_crtc_opr_event_notify(struct drm_crtc *crtc)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
uint32_t current_opr_value[MAX_DSI_DISPLAYS] = {0};
|
||||
int i, rc;
|
||||
bool updated = false;
|
||||
struct drm_event event;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
|
||||
atomic_set(&sde_crtc->previous_opr_value.num_valid_opr, 0);
|
||||
for (i = 0; i < sde_crtc->num_mixers; i++) {
|
||||
rc = sde_dspp_spr_read_opr_value(sde_crtc->mixers[i].hw_dspp,
|
||||
¤t_opr_value[i]);
|
||||
if (rc) {
|
||||
SDE_ERROR("failed to collect OPR %d", i, rc);
|
||||
continue;
|
||||
}
|
||||
|
||||
atomic_inc(&sde_crtc->previous_opr_value.num_valid_opr);
|
||||
if (current_opr_value[i] == sde_crtc->previous_opr_value.opr_value[i])
|
||||
continue;
|
||||
|
||||
sde_crtc->previous_opr_value.opr_value[i] = current_opr_value[i];
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
event.type = DRM_EVENT_OPR_VALUE;
|
||||
event.length = sizeof(sde_crtc->previous_opr_value);
|
||||
msm_mode_object_event_notify(&crtc->base, crtc->dev, &event,
|
||||
(u8 *)&sde_crtc->previous_opr_value);
|
||||
}
|
||||
}
|
||||
|
||||
static void _sde_crtc_frame_done_notify(struct drm_crtc *crtc,
|
||||
struct sde_crtc_frame_event *fevent)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_connector *sde_conn;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
if (sde_crtc->opr_event_notify_enabled)
|
||||
sde_crtc_opr_event_notify(crtc);
|
||||
|
||||
sde_conn = to_sde_connector(fevent->connector);
|
||||
if (sde_conn && sde_conn->misr_event_notify_enabled)
|
||||
sde_encoder_misr_sign_event_notify(fevent->connector->encoder);
|
||||
}
|
||||
|
||||
static void sde_crtc_frame_event_work(struct kthread_work *work)
|
||||
{
|
||||
struct msm_drm_private *priv;
|
||||
@@ -3059,6 +3111,7 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)
|
||||
sde_fence_signal(sde_crtc->output_fence, fevent->ts,
|
||||
(fevent->event & SDE_ENCODER_FRAME_EVENT_ERROR)
|
||||
? SDE_FENCE_SIGNAL_ERROR : SDE_FENCE_SIGNAL);
|
||||
_sde_crtc_frame_done_notify(crtc, fevent);
|
||||
SDE_ATRACE_END("signal_release_fence");
|
||||
}
|
||||
|
||||
@@ -4913,6 +4966,10 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
|
||||
power_on = 0;
|
||||
sde_crtc_event_notify(crtc, DRM_EVENT_CRTC_POWER, &power_on, sizeof(u32));
|
||||
|
||||
/* suspend case: clear stale OPR value */
|
||||
if (sde_crtc->opr_event_notify_enabled)
|
||||
memset(&sde_crtc->previous_opr_value, 0, sizeof(struct sde_opr_value));
|
||||
|
||||
mutex_unlock(&sde_crtc->crtc_lock);
|
||||
}
|
||||
|
||||
@@ -7850,6 +7907,19 @@ static int sde_crtc_mmrm_interrupt_handler(struct drm_crtc *crtc_drm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sde_crtc_opr_event_handler(struct drm_crtc *crtc_drm,
|
||||
bool en, struct sde_irq_callback *irq)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc_drm);
|
||||
if (!sde_crtc)
|
||||
return -EINVAL;
|
||||
|
||||
sde_crtc->opr_event_notify_enabled = en;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sde_crtc_vm_release_handler(struct drm_crtc *crtc_drm,
|
||||
bool en, struct sde_irq_callback *irq)
|
||||
{
|
||||
|
新增問題並參考
封鎖使用者