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 "drmresources.h"
21 
22 #include <errno.h>
23 #include <stdint.h>
24 
25 #include <cutils/log.h>
26 #include <xf86drmMode.h>
27 
28 namespace android {
29 
DrmConnector(DrmResources * drm,drmModeConnectorPtr c,DrmEncoder * current_encoder,std::vector<DrmEncoder * > & possible_encoders)30 DrmConnector::DrmConnector(DrmResources *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 
~DrmConnector()44 DrmConnector::~DrmConnector() {
45 }
46 
Init()47 int DrmConnector::Init() {
48   int ret = drm_->GetConnectorProperty(*this, "DPMS", &dpms_property_);
49   if (ret) {
50     ALOGE("Could not get DPMS property\n");
51     return ret;
52   }
53   ret = drm_->GetConnectorProperty(*this, "CRTC_ID", &crtc_id_property_);
54   if (ret) {
55     ALOGE("Could not get CRTC_ID property\n");
56     return ret;
57   }
58   return 0;
59 }
60 
id() const61 uint32_t DrmConnector::id() const {
62   return id_;
63 }
64 
display() const65 int DrmConnector::display() const {
66   return display_;
67 }
68 
set_display(int display)69 void DrmConnector::set_display(int display) {
70   display_ = display;
71 }
72 
built_in() const73 bool DrmConnector::built_in() const {
74   return type_ == DRM_MODE_CONNECTOR_LVDS || type_ == DRM_MODE_CONNECTOR_eDP ||
75          type_ == DRM_MODE_CONNECTOR_DSI;
76 }
77 
UpdateModes()78 int DrmConnector::UpdateModes() {
79   int fd = drm_->fd();
80 
81   drmModeConnectorPtr c = drmModeGetConnector(fd, id_);
82   if (!c) {
83     ALOGE("Failed to get connector %d", id_);
84     return -ENODEV;
85   }
86 
87   std::vector<DrmMode> new_modes;
88   for (int i = 0; i < c->count_modes; ++i) {
89     bool exists = false;
90     for (std::vector<DrmMode>::iterator iter = modes_.begin();
91          iter != modes_.end(); ++iter) {
92       if (*iter == c->modes[i]) {
93         new_modes.push_back(*iter);
94         exists = true;
95         break;
96       }
97     }
98     if (exists)
99       continue;
100 
101     DrmMode m(&c->modes[i]);
102     m.set_id(drm_->next_mode_id());
103     new_modes.push_back(m);
104   }
105   modes_.swap(new_modes);
106   return 0;
107 }
108 
active_mode() const109 const DrmMode &DrmConnector::active_mode() const {
110   return active_mode_;
111 }
112 
set_active_mode(const DrmMode & mode)113 void DrmConnector::set_active_mode(const DrmMode &mode) {
114   active_mode_ = mode;
115 }
116 
dpms_property() const117 const DrmProperty &DrmConnector::dpms_property() const {
118   return dpms_property_;
119 }
120 
crtc_id_property() const121 const DrmProperty &DrmConnector::crtc_id_property() const {
122   return crtc_id_property_;
123 }
124 
begin_modes() const125 DrmConnector::ModeIter DrmConnector::begin_modes() const {
126   return modes_.begin();
127 }
128 
end_modes() const129 DrmConnector::ModeIter DrmConnector::end_modes() const {
130   return modes_.end();
131 }
132 
encoder() const133 DrmEncoder *DrmConnector::encoder() const {
134   return encoder_;
135 }
136 
set_encoder(DrmEncoder * encoder)137 void DrmConnector::set_encoder(DrmEncoder *encoder) {
138   encoder_ = encoder;
139 }
140 
begin_possible_encoders() const141 DrmConnector::EncoderIter DrmConnector::begin_possible_encoders() const {
142   return possible_encoders_.begin();
143 }
144 
end_possible_encoders() const145 DrmConnector::EncoderIter DrmConnector::end_possible_encoders() const {
146   return possible_encoders_.end();
147 }
148 
mm_width() const149 uint32_t DrmConnector::mm_width() const {
150   return mm_width_;
151 }
152 
mm_height() const153 uint32_t DrmConnector::mm_height() const {
154   return mm_height_;
155 }
156 }
157