Loading msm/sde/sde_crtc.c +32 −0 Original line number Diff line number Diff line Loading @@ -380,14 +380,33 @@ static ssize_t vsync_event_show(struct device *device, ktime_to_ns(sde_crtc->vblank_last_cb_time)); } static ssize_t retire_frame_event_show(struct device *device, struct device_attribute *attr, char *buf) { struct drm_crtc *crtc; struct sde_crtc *sde_crtc; if (!device || !buf) { SDE_ERROR("invalid input param(s)\n"); return -EAGAIN; } crtc = dev_get_drvdata(device); sde_crtc = to_sde_crtc(crtc); return scnprintf(buf, PAGE_SIZE, "RETIRE_FRAME_TIME=%llu\n", ktime_to_ns(sde_crtc->retire_frame_event_time)); } 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 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, NULL }; Loading @@ -411,6 +430,8 @@ static void sde_crtc_destroy(struct drm_crtc *crtc) if (sde_crtc->vsync_event_sf) sysfs_put(sde_crtc->vsync_event_sf); if (sde_crtc->retire_frame_event_sf) sysfs_put(sde_crtc->retire_frame_event_sf); if (sde_crtc->sysfs_dev) device_unregister(sde_crtc->sysfs_dev); Loading Loading @@ -2242,6 +2263,12 @@ static void sde_crtc_frame_event_cb(void *data, u32 event) } } if ((event & SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE) && (sde_crtc && sde_crtc->retire_frame_event_sf)) { sde_crtc->retire_frame_event_time = ktime_get(); sysfs_notify_dirent(sde_crtc->retire_frame_event_sf); } fevent->event = event; fevent->crtc = crtc; fevent->connector = cb_data->connector; Loading Loading @@ -6657,6 +6684,11 @@ int sde_crtc_post_init(struct drm_device *dev, struct drm_crtc *crtc) SDE_ERROR("crtc:%d vsync_event sysfs create failed\n", crtc->base.id); sde_crtc->retire_frame_event_sf = sysfs_get_dirent( sde_crtc->sysfs_dev->kobj.sd, "retire_frame_event"); if (!sde_crtc->retire_frame_event_sf) SDE_ERROR("crtc:%d retire frame event sysfs create failed\n", crtc->base.id); end: return rc; } Loading msm/sde/sde_crtc.h +4 −0 Original line number Diff line number Diff line Loading @@ -243,8 +243,10 @@ struct sde_crtc_misr_info { * @play_count : frame count between crtc enable and disable * @vblank_cb_time : ktime at vblank count reset * @vblank_last_cb_time : ktime at last vblank notification * @retire_frame_event_time : ktime at last retire frame event * @sysfs_dev : sysfs device node for crtc * @vsync_event_sf : vsync event notifier sysfs device * @retire_frame_event_sf :retire frame event notifier sysfs device * @enabled : whether the SDE CRTC is currently enabled. updated in the * commit-thread, not state-swap time which is earlier, so * safe to make decisions on during VBLANK on/off work Loading Loading @@ -317,9 +319,11 @@ struct sde_crtc { u64 play_count; ktime_t vblank_cb_time; ktime_t vblank_last_cb_time; ktime_t retire_frame_event_time; struct sde_crtc_fps_info fps_info; struct device *sysfs_dev; struct kernfs_node *vsync_event_sf; struct kernfs_node *retire_frame_event_sf; bool enabled; struct list_head feature_list; Loading Loading
msm/sde/sde_crtc.c +32 −0 Original line number Diff line number Diff line Loading @@ -380,14 +380,33 @@ static ssize_t vsync_event_show(struct device *device, ktime_to_ns(sde_crtc->vblank_last_cb_time)); } static ssize_t retire_frame_event_show(struct device *device, struct device_attribute *attr, char *buf) { struct drm_crtc *crtc; struct sde_crtc *sde_crtc; if (!device || !buf) { SDE_ERROR("invalid input param(s)\n"); return -EAGAIN; } crtc = dev_get_drvdata(device); sde_crtc = to_sde_crtc(crtc); return scnprintf(buf, PAGE_SIZE, "RETIRE_FRAME_TIME=%llu\n", ktime_to_ns(sde_crtc->retire_frame_event_time)); } 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 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, NULL }; Loading @@ -411,6 +430,8 @@ static void sde_crtc_destroy(struct drm_crtc *crtc) if (sde_crtc->vsync_event_sf) sysfs_put(sde_crtc->vsync_event_sf); if (sde_crtc->retire_frame_event_sf) sysfs_put(sde_crtc->retire_frame_event_sf); if (sde_crtc->sysfs_dev) device_unregister(sde_crtc->sysfs_dev); Loading Loading @@ -2242,6 +2263,12 @@ static void sde_crtc_frame_event_cb(void *data, u32 event) } } if ((event & SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE) && (sde_crtc && sde_crtc->retire_frame_event_sf)) { sde_crtc->retire_frame_event_time = ktime_get(); sysfs_notify_dirent(sde_crtc->retire_frame_event_sf); } fevent->event = event; fevent->crtc = crtc; fevent->connector = cb_data->connector; Loading Loading @@ -6657,6 +6684,11 @@ int sde_crtc_post_init(struct drm_device *dev, struct drm_crtc *crtc) SDE_ERROR("crtc:%d vsync_event sysfs create failed\n", crtc->base.id); sde_crtc->retire_frame_event_sf = sysfs_get_dirent( sde_crtc->sysfs_dev->kobj.sd, "retire_frame_event"); if (!sde_crtc->retire_frame_event_sf) SDE_ERROR("crtc:%d retire frame event sysfs create failed\n", crtc->base.id); end: return rc; } Loading
msm/sde/sde_crtc.h +4 −0 Original line number Diff line number Diff line Loading @@ -243,8 +243,10 @@ struct sde_crtc_misr_info { * @play_count : frame count between crtc enable and disable * @vblank_cb_time : ktime at vblank count reset * @vblank_last_cb_time : ktime at last vblank notification * @retire_frame_event_time : ktime at last retire frame event * @sysfs_dev : sysfs device node for crtc * @vsync_event_sf : vsync event notifier sysfs device * @retire_frame_event_sf :retire frame event notifier sysfs device * @enabled : whether the SDE CRTC is currently enabled. updated in the * commit-thread, not state-swap time which is earlier, so * safe to make decisions on during VBLANK on/off work Loading Loading @@ -317,9 +319,11 @@ struct sde_crtc { u64 play_count; ktime_t vblank_cb_time; ktime_t vblank_last_cb_time; ktime_t retire_frame_event_time; struct sde_crtc_fps_info fps_info; struct device *sysfs_dev; struct kernfs_node *vsync_event_sf; struct kernfs_node *retire_frame_event_sf; bool enabled; struct list_head feature_list; Loading