sdm: Add histogram event registration
Adds histogram event registration and handling to UEventThread.
This is similar to other events sourcing from /dev/dri/card0.
This registers the event, but it is not requested yet
(follow up patch will add requests for the event to the drm atomic commit)
Change-Id: Idd4ef25f883c1fbee70ca17e7170e5dda9b6e7c8
Signed-off-by: Kevin DuBois <kevindubois@google.com>
Signed-off-by: Lakshmi Narayana Kalavala <lkalaval@codeaurora.org>
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index 8d0e1bd..1aaf80d 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -87,20 +87,17 @@
}
if (hw_panel_info_.mode == kModeCommand) {
- event_list_ = {HWEvent::VSYNC,
- HWEvent::EXIT,
- HWEvent::IDLE_NOTIFY,
- HWEvent::SHOW_BLANK_EVENT,
- HWEvent::THERMAL_LEVEL,
- HWEvent::IDLE_POWER_COLLAPSE,
- HWEvent::PINGPONG_TIMEOUT,
- HWEvent::PANEL_DEAD,
- HWEvent::HW_RECOVERY};
+ event_list_ = {HWEvent::VSYNC, HWEvent::EXIT,
+ /*HWEvent::IDLE_NOTIFY, */
+ HWEvent::SHOW_BLANK_EVENT, HWEvent::THERMAL_LEVEL, HWEvent::IDLE_POWER_COLLAPSE,
+ HWEvent::PINGPONG_TIMEOUT, HWEvent::PANEL_DEAD, HWEvent::HW_RECOVERY,
+ HWEvent::HISTOGRAM};
} else {
event_list_ = {HWEvent::VSYNC, HWEvent::EXIT,
HWEvent::IDLE_NOTIFY, HWEvent::SHOW_BLANK_EVENT,
HWEvent::THERMAL_LEVEL, HWEvent::PINGPONG_TIMEOUT,
- HWEvent::PANEL_DEAD, HWEvent::HW_RECOVERY};
+ HWEvent::PANEL_DEAD, HWEvent::HW_RECOVERY,
+ HWEvent::HISTOGRAM};
}
avr_prop_disabled_ = Debug::IsAVRDisabled();
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
index 01d3747..4c8f3bc 100644
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/sdm/libs/core/drm/hw_events_drm.cpp
@@ -44,6 +44,7 @@
#include <drm/msm_drm.h>
#include <algorithm>
+#include <array>
#include <map>
#include <utility>
#include <vector>
@@ -136,6 +137,15 @@
poll_fds_[i].events = POLLIN | POLLPRI | POLLERR;
hw_recovery_index_ = i;
} break;
+ case HWEvent::HISTOGRAM: {
+ poll_fds_[i].fd = drmOpen("msm_drm", nullptr);
+ if (poll_fds_[i].fd < 0) {
+ DLOGE("drmOpen failed with error %d", poll_fds_[i].fd);
+ return kErrorResources;
+ }
+ poll_fds_[i].events = POLLIN | POLLPRI | POLLERR;
+ histogram_index_ = i;
+ } break;
case HWEvent::CEC_READ_MESSAGE:
case HWEvent::SHOW_BLANK_EVENT:
case HWEvent::THERMAL_LEVEL:
@@ -179,6 +189,9 @@
case HWEvent::HW_RECOVERY:
event_data.event_parser = &HWEventsDRM::HandleHwRecovery;
break;
+ case HWEvent::HISTOGRAM:
+ event_data.event_parser = &HWEventsDRM::HandleHistogram;
+ break;
default:
error = kErrorParameters;
break;
@@ -234,12 +247,14 @@
if (!disable_hw_recovery_) {
RegisterHwRecovery(true);
}
+ RegisterHistogram(true);
return kErrorNone;
}
DisplayError HWEventsDRM::Deinit() {
exit_threads_ = true;
+ RegisterHistogram(false);
RegisterPanelDead(false);
RegisterIdleNotify(false);
RegisterIdlePowerCollapse(false);
@@ -356,6 +371,7 @@
case HWEvent::IDLE_NOTIFY:
case HWEvent::IDLE_POWER_COLLAPSE:
case HWEvent::HW_RECOVERY:
+ case HWEvent::HISTOGRAM:
if (poll_fd.revents & (POLLIN | POLLPRI | POLLERR)) {
(this->*(event_data_list_[i]).event_parser)(nullptr);
}
@@ -429,6 +445,31 @@
return kErrorNone;
}
+DisplayError HWEventsDRM::RegisterHistogram(bool enable) {
+ if (histogram_index_ == UINT32_MAX) {
+ DLOGI("histogram is not supported event");
+ return kErrorNone;
+ }
+ struct drm_msm_event_req req = {};
+ int ret = 0;
+
+ req.object_id = token_.crtc_id;
+ req.object_type = DRM_MODE_OBJECT_CRTC;
+ req.event = DRM_EVENT_HISTOGRAM;
+ if (enable) {
+ ret = drmIoctl(poll_fds_[histogram_index_].fd, DRM_IOCTL_MSM_REGISTER_EVENT, &req);
+ } else {
+ ret = drmIoctl(poll_fds_[histogram_index_].fd, DRM_IOCTL_MSM_DEREGISTER_EVENT, &req);
+ }
+
+ if (ret) {
+ DLOGE("register idle notify enable:%d failed", enable);
+ return kErrorResources;
+ }
+
+ return kErrorNone;
+}
+
DisplayError HWEventsDRM::RegisterIdleNotify(bool enable) {
if (idle_notify_index_ == UINT32_MAX) {
DLOGI("idle notify is not supported event");
@@ -721,6 +762,20 @@
return;
}
+void HWEventsDRM::HandleHistogram(char * /*data*/) {
+ auto constexpr expected_size = sizeof(drm_msm_event_resp) + sizeof(uint32_t);
+ std::array<char, expected_size> event_data{'\0'};
+ auto size = Sys::pread_(poll_fds_[histogram_index_].fd, event_data.data(), event_data.size(), 0);
+ if (size != expected_size) {
+ DLOGE("event size %d is unexpected. skipping this histogram event", size);
+ return;
+ }
+
+ auto msm_event = reinterpret_cast<struct drm_msm_event_resp *>(event_data.data());
+ auto blob_id = reinterpret_cast<uint32_t *>(msm_event->data);
+ DLOGI("Received histogram event %i", *blob_id);
+}
+
int HWEventsDRM::SetHwRecoveryEvent(const uint32_t hw_event_code, HWRecoveryEvent *sdm_event_code) {
switch (hw_event_code) {
case SDE_RECOVERY_SUCCESS:
diff --git a/sdm/libs/core/drm/hw_events_drm.h b/sdm/libs/core/drm/hw_events_drm.h
index 2a98504..5838a4a 100644
--- a/sdm/libs/core/drm/hw_events_drm.h
+++ b/sdm/libs/core/drm/hw_events_drm.h
@@ -78,6 +78,7 @@
void HandleIdlePowerCollapse(char *data);
void HandlePanelDead(char *data);
void HandleHwRecovery(char *data);
+ void HandleHistogram(char *data);
int SetHwRecoveryEvent(const uint32_t hw_event_code, HWRecoveryEvent *sdm_event_code);
void PopulateHWEventData(const vector<HWEvent> &event_list);
void WakeUpEventThread();
@@ -89,6 +90,7 @@
DisplayError RegisterIdleNotify(bool enable);
DisplayError RegisterIdlePowerCollapse(bool enable);
DisplayError RegisterHwRecovery(bool enable);
+ DisplayError RegisterHistogram(bool enable);
HWEventHandler *event_handler_{};
vector<HWEventData> event_data_list_{};
@@ -97,6 +99,7 @@
std::string event_thread_name_ = "SDM_EventThread";
bool exit_threads_ = false;
uint32_t vsync_index_ = UINT32_MAX;
+ uint32_t histogram_index_ = UINT32_MAX;
bool vsync_enabled_ = false;
bool vsync_registered_ = false;
std::mutex vsync_mutex_; // To protect vsync_enabled_ and vsync_registered_
diff --git a/sdm/libs/core/hw_events_interface.h b/sdm/libs/core/hw_events_interface.h
index 81d9b04..d32485f 100644
--- a/sdm/libs/core/hw_events_interface.h
+++ b/sdm/libs/core/hw_events_interface.h
@@ -46,6 +46,7 @@
PINGPONG_TIMEOUT,
PANEL_DEAD,
HW_RECOVERY,
+ HISTOGRAM,
};
class HWEventsInterface {