2 * Copyright (C) 2015 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #define LOG_TAG "hwc-drm-connector"
19 #include "DrmConnector.h"
21 #include <xf86drmMode.h>
28 #include "DrmDevice.h"
29 #include "utils/log.h"
31 #ifndef DRM_MODE_CONNECTOR_SPI
32 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
33 #define DRM_MODE_CONNECTOR_SPI 19
36 #ifndef DRM_MODE_CONNECTOR_USB
37 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
38 #define DRM_MODE_CONNECTOR_USB 20
43 constexpr size_t kTypesCount = 21;
45 static bool GetOptionalConnectorProperty(const DrmDevice &dev,
46 const DrmConnector &connector,
47 const char *prop_name,
48 DrmProperty *property) {
49 return dev.GetProperty(connector.GetId(), DRM_MODE_OBJECT_CONNECTOR,
50 prop_name, property) == 0;
53 static bool GetConnectorProperty(const DrmDevice &dev,
54 const DrmConnector &connector,
55 const char *prop_name, DrmProperty *property) {
56 if (!GetOptionalConnectorProperty(dev, connector, prop_name, property)) {
57 ALOGE("Could not get %s property\n", prop_name);
63 auto DrmConnector::CreateInstance(DrmDevice &dev, uint32_t connector_id,
65 -> std::unique_ptr<DrmConnector> {
66 auto conn = MakeDrmModeConnectorUnique(dev.GetFd(), connector_id);
68 ALOGE("Failed to get connector %d", connector_id);
72 auto c = std::unique_ptr<DrmConnector>(
73 new DrmConnector(std::move(conn), &dev, index));
75 if (!GetConnectorProperty(dev, *c, "DPMS", &c->dpms_property_) ||
76 !GetConnectorProperty(dev, *c, "CRTC_ID", &c->crtc_id_property_)) {
80 c->UpdateEdidProperty();
82 if (c->IsWriteback() &&
83 (!GetConnectorProperty(dev, *c, "WRITEBACK_PIXEL_FORMATS",
84 &c->writeback_pixel_formats_) ||
85 !GetConnectorProperty(dev, *c, "WRITEBACK_FB_ID",
86 &c->writeback_fb_id_) ||
87 !GetConnectorProperty(dev, *c, "WRITEBACK_OUT_FENCE_PTR",
88 &c->writeback_out_fence_))) {
95 int DrmConnector::UpdateEdidProperty() {
96 return GetOptionalConnectorProperty(*drm_, *this, "EDID", &edid_property_)
101 auto DrmConnector::GetEdidBlob() -> DrmModePropertyBlobUnique {
102 uint64_t blob_id = 0;
103 int ret = UpdateEdidProperty();
108 std::tie(ret, blob_id) = GetEdidProperty().value();
113 return MakeDrmModePropertyBlobUnique(drm_->GetFd(), blob_id);
116 bool DrmConnector::IsInternal() const {
117 auto type = connector_->connector_type;
118 return type == DRM_MODE_CONNECTOR_LVDS || type == DRM_MODE_CONNECTOR_eDP ||
119 type == DRM_MODE_CONNECTOR_DSI || type == DRM_MODE_CONNECTOR_VIRTUAL ||
120 type == DRM_MODE_CONNECTOR_DPI || type == DRM_MODE_CONNECTOR_SPI;
123 bool DrmConnector::IsExternal() const {
124 auto type = connector_->connector_type;
125 return type == DRM_MODE_CONNECTOR_HDMIA ||
126 type == DRM_MODE_CONNECTOR_DisplayPort ||
127 type == DRM_MODE_CONNECTOR_DVID || type == DRM_MODE_CONNECTOR_DVII ||
128 type == DRM_MODE_CONNECTOR_VGA || type == DRM_MODE_CONNECTOR_USB;
131 bool DrmConnector::IsWriteback() const {
132 #ifdef DRM_MODE_CONNECTOR_WRITEBACK
133 return connector_->connector_type == DRM_MODE_CONNECTOR_WRITEBACK;
139 bool DrmConnector::IsValid() const {
140 return IsInternal() || IsExternal() || IsWriteback();
143 std::string DrmConnector::GetName() const {
144 constexpr std::array<const char *, kTypesCount> kNames =
145 {"None", "VGA", "DVI-I", "DVI-D", "DVI-A", "Composite",
146 "SVIDEO", "LVDS", "Component", "DIN", "DP", "HDMI-A",
147 "HDMI-B", "TV", "eDP", "Virtual", "DSI", "DPI",
148 "Writeback", "SPI", "USB"};
150 if (connector_->connector_type < kTypesCount) {
151 std::ostringstream name_buf;
152 name_buf << kNames[connector_->connector_type] << "-"
153 << connector_->connector_type_id;
154 return name_buf.str();
157 ALOGE("Unknown type in connector %d, could not make his name", GetId());
161 int DrmConnector::UpdateModes() {
162 auto conn = MakeDrmModeConnectorUnique(drm_->GetFd(), GetId());
164 ALOGE("Failed to get connector %d", GetId());
167 connector_ = std::move(conn);
170 for (int i = 0; i < connector_->count_modes; ++i) {
172 for (const DrmMode &mode : modes_) {
173 if (mode == connector_->modes[i]) {
180 modes_.emplace_back(DrmMode(&connector_->modes[i]));
187 void DrmConnector::SetActiveMode(DrmMode &mode) {
191 } // namespace android