blob: 7cbec95740e615e79bd95acf1f1319007b3422d3 [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
Yongqin Liucdee4f22021-11-28 08:46:30 +080031#ifndef DRM_MODE_CONNECTOR_SPI
32#define DRM_MODE_CONNECTOR_SPI 19
33#endif
34
35#ifndef DRM_MODE_CONNECTOR_USB
36#define DRM_MODE_CONNECTOR_USB 20
37#endif
38
Sean Paul6a55e9f2015-04-30 15:31:06 -040039namespace android {
40
Yongqin Liucdee4f22021-11-28 08:46:30 +080041constexpr size_t kTypesCount = 21;
Roman Kovalivskyie606a622019-11-25 19:13:05 +020042
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +010043DrmConnector::DrmConnector(DrmDevice *drm, drmModeConnectorPtr c,
Sean Paul6a55e9f2015-04-30 15:31:06 -040044 DrmEncoder *current_encoder,
45 std::vector<DrmEncoder *> &possible_encoders)
46 : drm_(drm),
47 id_(c->connector_id),
48 encoder_(current_encoder),
49 display_(-1),
50 type_(c->connector_type),
Roman Kovalivskyidf882992019-11-04 17:43:40 +020051 type_id_(c->connector_type_id),
Sean Paul6a55e9f2015-04-30 15:31:06 -040052 state_(c->connection),
53 mm_width_(c->mmWidth),
54 mm_height_(c->mmHeight),
55 possible_encoders_(possible_encoders) {
56}
57
Sean Paul6a55e9f2015-04-30 15:31:06 -040058int DrmConnector::Init() {
59 int ret = drm_->GetConnectorProperty(*this, "DPMS", &dpms_property_);
60 if (ret) {
61 ALOGE("Could not get DPMS property\n");
62 return ret;
63 }
Sean Paul877be972015-06-03 14:08:27 -040064 ret = drm_->GetConnectorProperty(*this, "CRTC_ID", &crtc_id_property_);
65 if (ret) {
66 ALOGE("Could not get CRTC_ID property\n");
67 return ret;
68 }
Roman Stratiienko6a10c4c2021-02-15 11:25:23 +020069 UpdateEdidProperty();
Alexandru Gheorghe364f9572018-03-21 11:40:01 +000070 if (writeback()) {
71 ret = drm_->GetConnectorProperty(*this, "WRITEBACK_PIXEL_FORMATS",
72 &writeback_pixel_formats_);
73 if (ret) {
74 ALOGE("Could not get WRITEBACK_PIXEL_FORMATS connector_id = %d\n", id_);
75 return ret;
76 }
77 ret = drm_->GetConnectorProperty(*this, "WRITEBACK_FB_ID",
78 &writeback_fb_id_);
79 if (ret) {
80 ALOGE("Could not get WRITEBACK_FB_ID connector_id = %d\n", id_);
81 return ret;
82 }
83 ret = drm_->GetConnectorProperty(*this, "WRITEBACK_OUT_FENCE_PTR",
84 &writeback_out_fence_);
85 if (ret) {
86 ALOGE("Could not get WRITEBACK_OUT_FENCE_PTR connector_id = %d\n", id_);
87 return ret;
88 }
89 }
Sean Paul6a55e9f2015-04-30 15:31:06 -040090 return 0;
91}
92
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +030093int DrmConnector::UpdateEdidProperty() {
94 int ret = drm_->GetConnectorProperty(*this, "EDID", &edid_property_);
95 if (ret) {
96 ALOGW("Could not get EDID property\n");
97 }
98 return ret;
99}
100
Roman Stratiienko3e8ce572021-09-29 12:46:28 +0300101auto DrmConnector::GetEdidBlob() -> DrmModePropertyBlobUnique {
Roman Stratiienkob3b5c1e2021-02-15 13:44:19 +0200102 uint64_t blob_id = 0;
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +0300103 int ret = UpdateEdidProperty();
Roman Stratiienko3e8ce572021-09-29 12:46:28 +0300104 if (ret != 0) {
Roman Stratiienko780f7da2022-01-10 16:04:15 +0200105 return {};
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +0300106 }
107
108 std::tie(ret, blob_id) = edid_property().value();
Roman Stratiienko3e8ce572021-09-29 12:46:28 +0300109 if (ret != 0) {
Roman Stratiienko780f7da2022-01-10 16:04:15 +0200110 return {};
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +0300111 }
112
Roman Stratiienko3e8ce572021-09-29 12:46:28 +0300113 return MakeDrmModePropertyBlobUnique(drm_->fd(), blob_id);
Andrii Chepurnyiadc5d822020-07-10 16:07:03 +0300114}
115
Sean Paul6a55e9f2015-04-30 15:31:06 -0400116uint32_t DrmConnector::id() const {
117 return id_;
118}
119
120int DrmConnector::display() const {
121 return display_;
122}
123
124void DrmConnector::set_display(int display) {
125 display_ = display;
126}
127
Robert Foss610d9892017-11-01 12:50:04 -0500128bool DrmConnector::internal() const {
Sean Paul6a55e9f2015-04-30 15:31:06 -0400129 return type_ == DRM_MODE_CONNECTOR_LVDS || type_ == DRM_MODE_CONNECTOR_eDP ||
Mykhailo Sopiha87769e62019-07-11 14:31:09 +0300130 type_ == DRM_MODE_CONNECTOR_DSI ||
Yongqin Liucdee4f22021-11-28 08:46:30 +0800131 type_ == DRM_MODE_CONNECTOR_VIRTUAL ||
132 type_ == DRM_MODE_CONNECTOR_DPI || type_ == DRM_MODE_CONNECTOR_SPI;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400133}
134
Robert Foss610d9892017-11-01 12:50:04 -0500135bool DrmConnector::external() const {
Sean Paulf72cccd2018-08-27 13:59:08 -0400136 return type_ == DRM_MODE_CONNECTOR_HDMIA ||
137 type_ == DRM_MODE_CONNECTOR_DisplayPort ||
Mauro Rossi556bedf2018-01-06 00:59:59 +0100138 type_ == DRM_MODE_CONNECTOR_DVID || type_ == DRM_MODE_CONNECTOR_DVII ||
Yongqin Liucdee4f22021-11-28 08:46:30 +0800139 type_ == DRM_MODE_CONNECTOR_VGA || type_ == DRM_MODE_CONNECTOR_USB;
Robert Foss610d9892017-11-01 12:50:04 -0500140}
141
Alexandru Gheorghe364f9572018-03-21 11:40:01 +0000142bool DrmConnector::writeback() const {
143#ifdef DRM_MODE_CONNECTOR_WRITEBACK
144 return type_ == DRM_MODE_CONNECTOR_WRITEBACK;
145#else
146 return false;
147#endif
148}
149
Robert Foss610d9892017-11-01 12:50:04 -0500150bool DrmConnector::valid_type() const {
Alexandru Gheorghe364f9572018-03-21 11:40:01 +0000151 return internal() || external() || writeback();
Robert Foss610d9892017-11-01 12:50:04 -0500152}
153
Roman Kovalivskyidf882992019-11-04 17:43:40 +0200154std::string DrmConnector::name() const {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200155 constexpr std::array<const char *, kTypesCount> kNames =
Yongqin Liucdee4f22021-11-28 08:46:30 +0800156 {"None", "VGA", "DVI-I", "DVI-D", "DVI-A", "Composite",
157 "SVIDEO", "LVDS", "Component", "DIN", "DP", "HDMI-A",
158 "HDMI-B", "TV", "eDP", "Virtual", "DSI", "DPI",
159 "Writeback", "SPI", "USB"};
Roman Kovalivskyidf882992019-11-04 17:43:40 +0200160
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200161 if (type_ < kTypesCount) {
Roman Kovalivskyid6a6e6e2019-11-25 19:17:53 +0200162 std::ostringstream name_buf;
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200163 name_buf << kNames[type_] << "-" << type_id_;
Roman Kovalivskyid6a6e6e2019-11-25 19:17:53 +0200164 return name_buf.str();
Roman Kovalivskyid6a6e6e2019-11-25 19:17:53 +0200165 }
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200166
167 ALOGE("Unknown type in connector %d, could not make his name", id_);
168 return "None";
Roman Kovalivskyidf882992019-11-04 17:43:40 +0200169}
170
Sean Paul6a55e9f2015-04-30 15:31:06 -0400171int DrmConnector::UpdateModes() {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200172 drmModeConnectorPtr c = drmModeGetConnector(drm_->fd(), id_);
Sean Paul6a55e9f2015-04-30 15:31:06 -0400173 if (!c) {
174 ALOGE("Failed to get connector %d", id_);
175 return -ENODEV;
176 }
177
Roman Stratiienkoad29ee92022-01-17 18:44:22 +0200178 state_ = c->connection;
179
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200180 modes_.clear();
Sean Paul6a55e9f2015-04-30 15:31:06 -0400181 for (int i = 0; i < c->count_modes; ++i) {
182 bool exists = false;
Zach Reiznerff30b522015-10-28 19:08:45 -0700183 for (const DrmMode &mode : modes_) {
184 if (mode == c->modes[i]) {
Sean Paul6a55e9f2015-04-30 15:31:06 -0400185 exists = true;
186 break;
187 }
188 }
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200189
Andrii Chepurnyi1b1e35e2019-02-19 21:38:13 +0200190 if (!exists) {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200191 modes_.emplace_back(DrmMode(&c->modes[i]));
Andrii Chepurnyi1b1e35e2019-02-19 21:38:13 +0200192 }
Sean Paul6a55e9f2015-04-30 15:31:06 -0400193 }
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200194
Sean Paul6a55e9f2015-04-30 15:31:06 -0400195 return 0;
196}
197
198const DrmMode &DrmConnector::active_mode() const {
199 return active_mode_;
200}
201
Sean Paul877be972015-06-03 14:08:27 -0400202void DrmConnector::set_active_mode(const DrmMode &mode) {
203 active_mode_ = mode;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400204}
205
206const DrmProperty &DrmConnector::dpms_property() const {
207 return dpms_property_;
208}
209
Sean Paul877be972015-06-03 14:08:27 -0400210const DrmProperty &DrmConnector::crtc_id_property() const {
211 return crtc_id_property_;
212}
213
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +0800214const DrmProperty &DrmConnector::edid_property() const {
215 return edid_property_;
216}
217
Alexandru Gheorghe364f9572018-03-21 11:40:01 +0000218const DrmProperty &DrmConnector::writeback_pixel_formats() const {
219 return writeback_pixel_formats_;
220}
221
222const DrmProperty &DrmConnector::writeback_fb_id() const {
223 return writeback_fb_id_;
224}
225
226const DrmProperty &DrmConnector::writeback_out_fence() const {
227 return writeback_out_fence_;
228}
229
Sean Paul6a55e9f2015-04-30 15:31:06 -0400230DrmEncoder *DrmConnector::encoder() const {
231 return encoder_;
232}
233
234void DrmConnector::set_encoder(DrmEncoder *encoder) {
235 encoder_ = encoder;
236}
237
Sean Paul09216492015-10-26 15:36:37 -0400238drmModeConnection DrmConnector::state() const {
239 return state_;
240}
241
Sean Paul6a55e9f2015-04-30 15:31:06 -0400242uint32_t DrmConnector::mm_width() const {
243 return mm_width_;
244}
245
246uint32_t DrmConnector::mm_height() const {
247 return mm_height_;
248}
Sean Paulf72cccd2018-08-27 13:59:08 -0400249} // namespace android