• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
19 #include "drmconnector.h"
20 #include "drmdevice.h"
21 
22 #include <errno.h>
23 #include <stdint.h>
24 
25 #include <log/log.h>
26 #include <xf86drmMode.h>
27 
28 namespace android {
29 
DrmConnector(DrmDevice * drm,drmModeConnectorPtr c,DrmEncoder * current_encoder,std::vector<DrmEncoder * > & possible_encoders)30 DrmConnector::DrmConnector(DrmDevice *drm, drmModeConnectorPtr c,
31                            DrmEncoder *current_encoder,
32                            std::vector<DrmEncoder *> &possible_encoders)
33     : drm_(drm),
34       id_(c->connector_id),
35       encoder_(current_encoder),
36       display_(-1),
37       type_(c->connector_type),
38       state_(c->connection),
39       mm_width_(c->mmWidth),
40       mm_height_(c->mmHeight),
41       possible_encoders_(possible_encoders) {
42 }
43 
Init()44 int DrmConnector::Init() {
45   int ret = drm_->GetConnectorProperty(*this, "DPMS", &dpms_property_);
46   if (ret) {
47     ALOGE("Could not get DPMS property\n");
48     return ret;
49   }
50   ret = drm_->GetConnectorProperty(*this, "CRTC_ID", &crtc_id_property_);
51   if (ret) {
52     ALOGE("Could not get CRTC_ID property\n");
53     return ret;
54   }
55   if (writeback()) {
56     ret = drm_->GetConnectorProperty(*this, "WRITEBACK_PIXEL_FORMATS",
57                                      &writeback_pixel_formats_);
58     if (ret) {
59       ALOGE("Could not get WRITEBACK_PIXEL_FORMATS connector_id = %d\n", id_);
60       return ret;
61     }
62     ret = drm_->GetConnectorProperty(*this, "WRITEBACK_FB_ID",
63                                      &writeback_fb_id_);
64     if (ret) {
65       ALOGE("Could not get WRITEBACK_FB_ID connector_id = %d\n", id_);
66       return ret;
67     }
68     ret = drm_->GetConnectorProperty(*this, "WRITEBACK_OUT_FENCE_PTR",
69                                      &writeback_out_fence_);
70     if (ret) {
71       ALOGE("Could not get WRITEBACK_OUT_FENCE_PTR connector_id = %d\n", id_);
72       return ret;
73     }
74   }
75   return 0;
76 }
77 
id() const78 uint32_t DrmConnector::id() const {
79   return id_;
80 }
81 
display() const82 int DrmConnector::display() const {
83   return display_;
84 }
85 
set_display(int display)86 void DrmConnector::set_display(int display) {
87   display_ = display;
88 }
89 
internal() const90 bool DrmConnector::internal() const {
91   return type_ == DRM_MODE_CONNECTOR_LVDS || type_ == DRM_MODE_CONNECTOR_eDP ||
92          type_ == DRM_MODE_CONNECTOR_DSI || type_ == DRM_MODE_CONNECTOR_VIRTUAL;
93 }
94 
external() const95 bool DrmConnector::external() const {
96   return type_ == DRM_MODE_CONNECTOR_HDMIA ||
97          type_ == DRM_MODE_CONNECTOR_DisplayPort ||
98          type_ == DRM_MODE_CONNECTOR_DVID || type_ == DRM_MODE_CONNECTOR_DVII ||
99          type_ == DRM_MODE_CONNECTOR_VGA;
100 }
101 
writeback() const102 bool DrmConnector::writeback() const {
103 #ifdef DRM_MODE_CONNECTOR_WRITEBACK
104   return type_ == DRM_MODE_CONNECTOR_WRITEBACK;
105 #else
106   return false;
107 #endif
108 }
109 
valid_type() const110 bool DrmConnector::valid_type() const {
111   return internal() || external() || writeback();
112 }
113 
UpdateModes()114 int DrmConnector::UpdateModes() {
115   int fd = drm_->fd();
116 
117   drmModeConnectorPtr c = drmModeGetConnector(fd, id_);
118   if (!c) {
119     ALOGE("Failed to get connector %d", id_);
120     return -ENODEV;
121   }
122 
123   state_ = c->connection;
124 
125   bool preferred_mode_found = false;
126   std::vector<DrmMode> new_modes;
127   for (int i = 0; i < c->count_modes; ++i) {
128     bool exists = false;
129     for (const DrmMode &mode : modes_) {
130       if (mode == c->modes[i]) {
131         new_modes.push_back(mode);
132         exists = true;
133         break;
134       }
135     }
136     if (!exists) {
137       DrmMode m(&c->modes[i]);
138       m.set_id(drm_->next_mode_id());
139       new_modes.push_back(m);
140     }
141     if (new_modes.back().type() & DRM_MODE_TYPE_PREFERRED) {
142       preferred_mode_id_ = new_modes.back().id();
143       preferred_mode_found = true;
144     }
145   }
146   modes_.swap(new_modes);
147   if ((!preferred_mode_found) && (modes_.size() != 0)) {
148     preferred_mode_id_ = modes_[0].id();
149   }
150   return 0;
151 }
152 
active_mode() const153 const DrmMode &DrmConnector::active_mode() const {
154   return active_mode_;
155 }
156 
set_active_mode(const DrmMode & mode)157 void DrmConnector::set_active_mode(const DrmMode &mode) {
158   active_mode_ = mode;
159 }
160 
dpms_property() const161 const DrmProperty &DrmConnector::dpms_property() const {
162   return dpms_property_;
163 }
164 
crtc_id_property() const165 const DrmProperty &DrmConnector::crtc_id_property() const {
166   return crtc_id_property_;
167 }
168 
writeback_pixel_formats() const169 const DrmProperty &DrmConnector::writeback_pixel_formats() const {
170   return writeback_pixel_formats_;
171 }
172 
writeback_fb_id() const173 const DrmProperty &DrmConnector::writeback_fb_id() const {
174   return writeback_fb_id_;
175 }
176 
writeback_out_fence() const177 const DrmProperty &DrmConnector::writeback_out_fence() const {
178   return writeback_out_fence_;
179 }
180 
encoder() const181 DrmEncoder *DrmConnector::encoder() const {
182   return encoder_;
183 }
184 
set_encoder(DrmEncoder * encoder)185 void DrmConnector::set_encoder(DrmEncoder *encoder) {
186   encoder_ = encoder;
187 }
188 
state() const189 drmModeConnection DrmConnector::state() const {
190   return state_;
191 }
192 
mm_width() const193 uint32_t DrmConnector::mm_width() const {
194   return mm_width_;
195 }
196 
mm_height() const197 uint32_t DrmConnector::mm_height() const {
198   return mm_height_;
199 }
200 }  // namespace android
201