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 行删除

查看文件

@@ -77,6 +77,9 @@
/* Maximum number of VSYNC wait attempts for RSC state transition */
#define MAX_RSC_WAIT 5
#define IS_ROI_UPDATED(a, b) (a.x1 != b.x1 || a.x2 != b.x2 || \
a.y1 != b.y1 || a.y2 != b.y2)
/**
* enum sde_enc_rc_events - events for resource control state machine
* @SDE_ENC_RC_EVENT_KICKOFF:
@@ -2193,6 +2196,7 @@ static int _sde_encoder_rc_idle(struct drm_encoder *drm_enc,
struct drm_crtc *crtc = drm_enc->crtc;
struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
struct sde_connector *sde_conn;
int crtc_id = 0;
priv = drm_enc->dev->dev_private;
sde_kms = to_sde_kms(priv->kms);
@@ -2218,10 +2222,14 @@ static int _sde_encoder_rc_idle(struct drm_encoder *drm_enc,
goto end;
}
crtc_id = drm_crtc_index(crtc);
if (is_vid_mode) {
sde_encoder_irq_control(drm_enc, false);
_sde_encoder_pm_qos_remove_request(drm_enc);
} else {
if (priv->event_thread[crtc_id].thread)
kthread_flush_worker(&priv->event_thread[crtc_id].worker);
/* disable all the clks and resources */
_sde_encoder_update_rsc_client(drm_enc, false);
_sde_encoder_resource_control_helper(drm_enc, false);
@@ -2985,6 +2993,13 @@ void sde_encoder_virt_restore(struct drm_encoder *drm_enc)
_sde_encoder_virt_enable_helper(drm_enc);
sde_encoder_control_te(drm_enc, true);
/*
* During IPC misr ctl register is reset.
* Need to reconfigure misr after every IPC.
*/
if (atomic_read(&sde_enc->misr_enable))
sde_enc->misr_reconfigure = true;
}
static void sde_encoder_populate_encoder_phys(struct drm_encoder *drm_enc,
@@ -3032,7 +3047,7 @@ static void sde_encoder_populate_encoder_phys(struct drm_encoder *drm_enc,
phys->ops.enable(phys);
}
if (sde_enc->misr_enable && phys->ops.setup_misr &&
if (atomic_read(&sde_enc->misr_enable) && phys->ops.setup_misr &&
(sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_VIDEO_MODE)))
phys->ops.setup_misr(phys, true,
sde_enc->misr_frame_count);
@@ -3977,7 +3992,7 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc,
}
}
if (sde_enc->misr_enable)
if (atomic_read(&sde_enc->misr_enable))
sde_encoder_misr_configure(&sde_enc->base, true,
sde_enc->misr_frame_count);
@@ -4888,7 +4903,7 @@ static ssize_t _sde_encoder_misr_setup(struct file *file,
if (sscanf(buf, "%u %u", &enable, &frame_count) != 2)
return -EINVAL;
sde_enc->misr_enable = enable;
atomic_set(&sde_enc->misr_enable, enable);
sde_enc->misr_reconfigure = true;
sde_enc->misr_frame_count = frame_count;
return count;
@@ -4935,7 +4950,7 @@ static ssize_t _sde_encoder_misr_read(struct file *file,
goto end;
}
if (!sde_enc->misr_enable) {
if (!atomic_read(&sde_enc->misr_enable)) {
len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
"disabled\n");
goto buff_check;
@@ -5914,3 +5929,80 @@ void sde_encoder_add_data_to_minidump_va(struct drm_encoder *drm_enc)
phys_enc->ops.add_to_minidump(phys_enc);
}
}
void sde_encoder_misr_sign_event_notify(struct drm_encoder *drm_enc)
{
struct drm_event event;
struct drm_connector *connector;
struct sde_connector *c_conn = NULL;
struct sde_connector_state *c_state = NULL;
struct sde_encoder_virt *sde_enc = NULL;
struct sde_encoder_phys *phys = NULL;
u32 current_misr_value[MAX_DSI_DISPLAYS] = {0};
int rc = 0, i = 0;
bool misr_updated = false, roi_updated = false;
struct msm_roi_list *prev_roi, *c_state_roi;
if (!drm_enc)
return;
sde_enc = to_sde_encoder_virt(drm_enc);
if (!atomic_read(&sde_enc->misr_enable)) {
SDE_DEBUG("MISR is disabled\n");
return;
}
connector = sde_enc->cur_master->connector;
if (!connector)
return;
c_conn = to_sde_connector(connector);
c_state = to_sde_connector_state(connector->state);
atomic64_set(&c_conn->previous_misr_sign.num_valid_misr, 0);
for (i = 0; i < sde_enc->num_phys_encs; i++) {
phys = sde_enc->phys_encs[i];
if (!phys || !phys->ops.collect_misr) {
SDE_DEBUG("invalid misr ops\n", i);
continue;
}
rc = phys->ops.collect_misr(phys, true, &current_misr_value[i]);
if (rc) {
SDE_ERROR("failed to collect misr %d\n", rc);
return;
}
atomic64_inc(&c_conn->previous_misr_sign.num_valid_misr);
}
for (i = 0; i < sde_enc->num_phys_encs; i++) {
if (current_misr_value[i] != c_conn->previous_misr_sign.misr_sign_value[i]) {
c_conn->previous_misr_sign.misr_sign_value[i] = current_misr_value[i];
misr_updated = true;
}
}
prev_roi = &c_conn->previous_misr_sign.roi_list;
c_state_roi = &c_state->rois;
if (prev_roi->num_rects != c_state_roi->num_rects) {
roi_updated = true;
} else {
for (i = 0; i < prev_roi->num_rects; i++) {
if (IS_ROI_UPDATED(prev_roi->roi[i], c_state_roi->roi[i]))
roi_updated = true;
}
}
if (roi_updated)
memcpy(&c_conn->previous_misr_sign.roi_list, &c_state->rois, sizeof(c_state->rois));
if (misr_updated || roi_updated) {
event.type = DRM_EVENT_MISR_SIGN;
event.length = sizeof(c_conn->previous_misr_sign);
msm_mode_object_event_notify(&connector->base, connector->dev, &event,
(u8 *)&c_conn->previous_misr_sign);
}
}