summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatvii Zorin <matvii.zorin@globallogic.com>2020-07-17 12:08:45 +0300
committerMatvii Zorin <matvii.zorin@globallogic.com>2020-07-24 11:08:18 +0300
commitec75ccd0735213423d6cf89409f8a3bfdaeddcee (patch)
tree080773381c0bfdf23fd6a217e68c280d097e26f3
parent2619aabb8754718ce4469407afd3004bfdea768e (diff)
drm_hwcomposer: Add feature to search for KMS DRI cardHEADmaster
Most modern SOCs have separate IP cores for GPU and Display Unit (KMS). Also, there is no warranty that the KMS card will always have /dev/dri/card0 path and GPU - /dev/dri/card1, but drm_hwcomposer should open only KMS device. The order can depend on many factors. For example: on the rpi4 board, it was observed that enabling the WIFI kernel module swapping the card order. Therefore searching for the KMS card is the only efficient solution. The IsKMSDev function returns true when the file descriptor on the path is successfully opened, the drmlib function is returned resources and the target device has at least one CTRC, connector, and encoder. Also, the patch enables finding KMS devices in the case of the absence of the system property specification. Signed-off-by: Matvii Zorin <matvii.zorin@globallogic.com> Reviewed-by: Roman Stratiienko <r.stratiienko@gmail.com> Change-Id: I8874a50188207833389fadd4815b42a80bf69240
-rw-r--r--drm/resourcemanager.cpp31
-rw-r--r--include/resourcemanager.h1
2 files changed, 30 insertions, 2 deletions
diff --git a/drm/resourcemanager.cpp b/drm/resourcemanager.cpp
index da1a2db..382a85a 100644
--- a/drm/resourcemanager.cpp
+++ b/drm/resourcemanager.cpp
@@ -20,6 +20,7 @@
#include <cutils/properties.h>
#include <log/log.h>
+#include <sys/stat.h>
#include <sstream>
#include <string>
@@ -32,7 +33,7 @@ int ResourceManager::Init() {
char path_pattern[PROPERTY_VALUE_MAX];
// Could be a valid path or it can have at the end of it the wildcard %
// which means that it will try open all devices until an error is met.
- int path_len = property_get("hwc.drm.device", path_pattern, "/dev/dri/card0");
+ int path_len = property_get("hwc.drm.device", path_pattern, "/dev/dri/card%");
int ret = 0;
if (path_pattern[path_len - 1] != '%') {
ret = AddDrmDevice(std::string(path_pattern));
@@ -41,7 +42,13 @@ int ResourceManager::Init() {
for (int idx = 0; !ret; ++idx) {
std::ostringstream path;
path << path_pattern << idx;
- ret = AddDrmDevice(path.str());
+
+ struct stat buf;
+ if (stat(path.str().c_str(), &buf)) {
+ break;
+ } else if (IsKMSDev(path.str().c_str())) {
+ ret = AddDrmDevice(path.str());
+ }
}
}
@@ -94,6 +101,26 @@ DrmConnector *ResourceManager::AvailableWritebackConnector(int display) {
return writeback_conn;
}
+bool ResourceManager::IsKMSDev(const char *path) {
+ int fd = open(path, O_RDWR | O_CLOEXEC);
+ if (fd < 0)
+ return false;
+
+ auto res = drmModeGetResources(fd);
+ if (!res) {
+ close(fd);
+ return false;
+ }
+
+ bool is_kms = res->count_crtcs > 0 && res->count_connectors > 0 &&
+ res->count_encoders > 0;
+
+ drmModeFreeResources(res);
+ close(fd);
+
+ return is_kms;
+}
+
DrmDevice *ResourceManager::GetDrmDevice(int display) {
for (auto &drm : drms_) {
if (drm->HandlesDisplay(display))
diff --git a/include/resourcemanager.h b/include/resourcemanager.h
index 7a86828..9fefb46 100644
--- a/include/resourcemanager.h
+++ b/include/resourcemanager.h
@@ -46,6 +46,7 @@ class ResourceManager {
private:
int AddDrmDevice(std::string path);
+ static bool IsKMSDev(const char *path);
int num_displays_;
std::vector<std::unique_ptr<DrmDevice>> drms_;