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>
此提交包含在:
Akshay Ashtunkar
2022-02-28 16:18:41 +05:30
父節點 0384633caf
當前提交 9423445a34
共有 14 個檔案被更改,包括 328 行新增7 行删除

查看文件

@@ -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,
&current_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)
{