blob: 5b3c697d48ae612a2d5bacc82e72dd6e71ae024d [file] [log] [blame]
Sean Paul6a55e9f2015-04-30 15:31:06 -04001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#define LOG_TAG "hwc-drm-connector"
18
Roman Stratiienko13cc3662020-08-29 21:35:39 +030019#include "DrmConnector.h"
Sean Paul6a55e9f2015-04-30 15:31:06 -040020
Roman Stratiienko13cc3662020-08-29 21:35:39 +030021#include <xf86drmMode.h>
Sean Paul6a55e9f2015-04-30 15:31:06 -040022
Roman Kovalivskyidf882992019-11-04 17:43:40 +020023#include <array>
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +020024#include <cerrno>
25#include <cstdint>
Roman Kovalivskyidf882992019-11-04 17:43:40 +020026#include <sstream>
27
Roman Stratiienko13cc3662020-08-29 21:35:39 +030028#include "DrmDevice.h"
Roman Stratiienkod518a052021-02-25 19:15:14 +020029#include "utils/log.h"
Sean Paul6a55e9f2015-04-30 15:31:06 -040030
31namespace android {
32
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +020033constexpr size_t kTypesCount = 17;
Roman Kovalivskyie606a622019-11-25 19:13:05 +020034
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +010035DrmConnector::DrmConnector(DrmDevice *drm, drmModeConnectorPtr c,
Sean Paul6a55e9f2015-04-30 15:31:06 -040036 DrmEncoder *current_encoder,
37 std::vector<DrmEncoder *> &possible_encoders)
38 : drm_(drm),
39 id_(c->connector_id),
40 encoder_(current_encoder),
41 display_(-1),
42 type_(c->connector_type),
Roman Kovalivskyidf882992019-11-04 17:43:40 +020043 type_id_(c->connector_type_id),
Sean Paul6a55e9f2015-04-30 15:31:06 -040044 state_(c->connection),
45 mm_width_(c->mmWidth),
46 mm_height_(c->mmHeight),
47 possible_encoders_(possible_encoders) {
48}
49
Sean Paul6a55e9f2015-04-30 15:31:06 -040050int DrmConnector::Init() {
51 int ret = drm_->GetConnectorProperty(*this, "DPMS", &dpms_property_);
52 if (ret) {
53 ALOGE("Could not get DPMS property\n");
54 return ret;
55 }
Sean Paul877be972015-06-03 14:08:27 -040056 ret = drm_->GetConnectorProperty(*this, "CRTC_ID", &crtc_id_property_);
57 if (ret) {
58 ALOGE("Could not get CRTC_ID property\n");
59 return ret;
60 }
Roman Stratiienko6a10c4c2021-02-15 11:25:23 +020061 UpdateEdidProperty();
Alexandru Gheorghe364f9572018-03-21 11:40:01 +000062 if (writeback()) {
63 ret = drm_->GetConnectorProperty(*this, "WRITEBACK_PIXEL_FORMATS",
64 &writeback_pixel_formats_);
65 if (ret) {
66 ALOGE("Could not get WRITEBACK_PIXEL_FORMATS connector_id = %d\n", id_);
67 return ret;
68 }
69 ret = drm_->GetConnectorProperty(*this, "WRITEBACK_FB_ID",
70 &writeback_fb_id_);
71 if (ret) {
72 ALOGE("Could not get WRITEBACK_FB_ID connector_id = %d\n", id_);
73 return ret;
74 }
75 ret = drm_->GetConnectorProperty(*this, "WRITEBACK_OUT_FENCE_PTR",
76 &writeback_out_fence_);
77 if (ret) {
78 ALOGE("Could not get WRITEBACK_OUT_FENCE_PTR connector_id = %d\n", id_);
79 return ret;
80 }
81 }
Sean Paul6a55e9f2015-04-30 15:31:06 -040082 return 0;
83}
84
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +030085int DrmConnector::UpdateEdidProperty() {
86 int ret = drm_->GetConnectorProperty(*this, "EDID", &edid_property_);
87 if (ret) {
88 ALOGW("Could not get EDID property\n");
89 }
90 return ret;
91}
92
Roman Stratiienko3e8ce572021-09-29 12:46:28 +030093auto DrmConnector::GetEdidBlob() -> DrmModePropertyBlobUnique {
Roman Stratiienkob3b5c1e2021-02-15 13:44:19 +020094 uint64_t blob_id = 0;
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +030095 int ret = UpdateEdidProperty();
Roman Stratiienko3e8ce572021-09-29 12:46:28 +030096 if (ret != 0) {
97 return DrmModePropertyBlobUnique();
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +030098 }
99
100 std::tie(ret, blob_id) = edid_property().value();
Roman Stratiienko3e8ce572021-09-29 12:46:28 +0300101 if (ret != 0) {
102 return DrmModePropertyBlobUnique();
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +0300103 }
104
Roman Stratiienko3e8ce572021-09-29 12:46:28 +0300105 return MakeDrmModePropertyBlobUnique(drm_->fd(), blob_id);
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +0300106}
107
Sean Paul6a55e9f2015-04-30 15:31:06 -0400108uint32_t DrmConnector::id() const {
109 return id_;
110}
111
112int DrmConnector::display() const {
113 return display_;
114}
115
116void DrmConnector::set_display(int display) {
117 display_ = display;
118}
119
Robert Foss610d9892017-11-01 12:50:04 -0500120bool DrmConnector::internal() const {
Sean Paul6a55e9f2015-04-30 15:31:06 -0400121 return type_ == DRM_MODE_CONNECTOR_LVDS || type_ == DRM_MODE_CONNECTOR_eDP ||
Mykhailo Sopiha87769e62019-07-11 14:31:09 +0300122 type_ == DRM_MODE_CONNECTOR_DSI ||
123 type_ == DRM_MODE_CONNECTOR_VIRTUAL || type_ == DRM_MODE_CONNECTOR_DPI;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400124}
125
Robert Foss610d9892017-11-01 12:50:04 -0500126bool DrmConnector::external() const {
Sean Paulf72cccd2018-08-27 13:59:08 -0400127 return type_ == DRM_MODE_CONNECTOR_HDMIA ||
128 type_ == DRM_MODE_CONNECTOR_DisplayPort ||
Mauro Rossi556bedf2018-01-06 00:59:59 +0100129 type_ == DRM_MODE_CONNECTOR_DVID || type_ == DRM_MODE_CONNECTOR_DVII ||
130 type_ == DRM_MODE_CONNECTOR_VGA;
Robert Foss610d9892017-11-01 12:50:04 -0500131}
132
Alexandru Gheorghe364f9572018-03-21 11:40:01 +0000133bool DrmConnector::writeback() const {
134#ifdef DRM_MODE_CONNECTOR_WRITEBACK
135 return type_ == DRM_MODE_CONNECTOR_WRITEBACK;
136#else
137 return false;
138#endif
139}
140
Robert Foss610d9892017-11-01 12:50:04 -0500141bool DrmConnector::valid_type() const {
Alexandru Gheorghe364f9572018-03-21 11:40:01 +0000142 return internal() || external() || writeback();
Robert Foss610d9892017-11-01 12:50:04 -0500143}
144
Roman Kovalivskyidf882992019-11-04 17:43:40 +0200145std::string DrmConnector::name() const {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200146 constexpr std::array<const char *, kTypesCount> kNames =
Roman Kovalivskyie606a622019-11-25 19:13:05 +0200147 {"None", "VGA", "DVI-I", "DVI-D", "DVI-A", "Composite",
148 "SVIDEO", "LVDS", "Component", "DIN", "DP", "HDMI-A",
149 "HDMI-B", "TV", "eDP", "Virtual", "DSI"};
Roman Kovalivskyidf882992019-11-04 17:43:40 +0200150
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200151 if (type_ < kTypesCount) {
Roman Kovalivskyid6a6e6e2019-11-25 19:17:53 +0200152 std::ostringstream name_buf;
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200153 name_buf << kNames[type_] << "-" << type_id_;
Roman Kovalivskyid6a6e6e2019-11-25 19:17:53 +0200154 return name_buf.str();
Roman Kovalivskyid6a6e6e2019-11-25 19:17:53 +0200155 }
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200156
157 ALOGE("Unknown type in connector %d, could not make his name", id_);
158 return "None";
Roman Kovalivskyidf882992019-11-04 17:43:40 +0200159}
160
Sean Paul6a55e9f2015-04-30 15:31:06 -0400161int DrmConnector::UpdateModes() {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200162 drmModeConnectorPtr c = drmModeGetConnector(drm_->fd(), id_);
Sean Paul6a55e9f2015-04-30 15:31:06 -0400163 if (!c) {
164 ALOGE("Failed to get connector %d", id_);
165 return -ENODEV;
166 }
167
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200168 modes_.clear();
Sean Paul6a55e9f2015-04-30 15:31:06 -0400169 for (int i = 0; i < c->count_modes; ++i) {
170 bool exists = false;
Zach Reiznerff30b522015-10-28 19:08:45 -0700171 for (const DrmMode &mode : modes_) {
172 if (mode == c->modes[i]) {
Sean Paul6a55e9f2015-04-30 15:31:06 -0400173 exists = true;
174 break;
175 }
176 }
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200177
Andrii Chepurnyi1b1e35e2019-02-19 21:38:13 +0200178 if (!exists) {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200179 modes_.emplace_back(DrmMode(&c->modes[i]));
Andrii Chepurnyi1b1e35e2019-02-19 21:38:13 +0200180 }
Sean Paul6a55e9f2015-04-30 15:31:06 -0400181 }
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200182
Sean Paul6a55e9f2015-04-30 15:31:06 -0400183 return 0;
184}
185
186const DrmMode &DrmConnector::active_mode() const {
187 return active_mode_;
188}
189
Sean Paul877be972015-06-03 14:08:27 -0400190void DrmConnector::set_active_mode(const DrmMode &mode) {
191 active_mode_ = mode;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400192}
193
194const DrmProperty &DrmConnector::dpms_property() const {
195 return dpms_property_;
196}
197
Sean Paul877be972015-06-03 14:08:27 -0400198const DrmProperty &DrmConnector::crtc_id_property() const {
199 return crtc_id_property_;
200}
201
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +0800202const DrmProperty &DrmConnector::edid_property() const {
203 return edid_property_;
204}
205
Alexandru Gheorghe364f9572018-03-21 11:40:01 +0000206const DrmProperty &DrmConnector::writeback_pixel_formats() const {
207 return writeback_pixel_formats_;
208}
209
210const DrmProperty &DrmConnector::writeback_fb_id() const {
211 return writeback_fb_id_;
212}
213
214const DrmProperty &DrmConnector::writeback_out_fence() const {
215 return writeback_out_fence_;
216}
217
Sean Paul6a55e9f2015-04-30 15:31:06 -0400218DrmEncoder *DrmConnector::encoder() const {
219 return encoder_;
220}
221
222void DrmConnector::set_encoder(DrmEncoder *encoder) {
223 encoder_ = encoder;
224}
225
Sean Paul09216492015-10-26 15:36:37 -0400226drmModeConnection DrmConnector::state() const {
227 return state_;
228}
229
Sean Paul6a55e9f2015-04-30 15:31:06 -0400230uint32_t DrmConnector::mm_width() const {
231 return mm_width_;
232}
233
234uint32_t DrmConnector::mm_height() const {
235 return mm_height_;
236}
Sean Paulf72cccd2018-08-27 13:59:08 -0400237} // namespace android