16a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul/*
26a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * Copyright (C) 2015 The Android Open Source Project
36a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul *
46a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * Licensed under the Apache License, Version 2.0 (the "License");
56a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * you may not use this file except in compliance with the License.
66a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * You may obtain a copy of the License at
76a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul *
86a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul *      http://www.apache.org/licenses/LICENSE-2.0
96a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul *
106a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * Unless required by applicable law or agreed to in writing, software
116a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * distributed under the License is distributed on an "AS IS" BASIS,
126a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * See the License for the specific language governing permissions and
146a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul * limitations under the License.
156a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul */
166a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
176a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul#define LOG_TAG "hwc-drm-connector"
186a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
196a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul#include "drmconnector.h"
206a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul#include "drmresources.h"
216a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
226a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul#include <errno.h>
236a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul#include <stdint.h>
246a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
256a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul#include <cutils/log.h>
266a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul#include <xf86drmMode.h>
276a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
286a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulnamespace android {
296a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
306a55e9fb8e16c63c2e42bde31814f963205f722dSean PaulDrmConnector::DrmConnector(DrmResources *drm, drmModeConnectorPtr c,
316a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul                           DrmEncoder *current_encoder,
326a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul                           std::vector<DrmEncoder *> &possible_encoders)
336a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    : drm_(drm),
346a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      id_(c->connector_id),
356a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      encoder_(current_encoder),
366a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      display_(-1),
376a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      type_(c->connector_type),
386a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      state_(c->connection),
396a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      mm_width_(c->mmWidth),
406a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      mm_height_(c->mmHeight),
416a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      possible_encoders_(possible_encoders) {
426a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
436a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
446a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulint DrmConnector::Init() {
456a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  int ret = drm_->GetConnectorProperty(*this, "DPMS", &dpms_property_);
466a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  if (ret) {
476a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    ALOGE("Could not get DPMS property\n");
486a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    return ret;
496a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  }
50877be974a2d4fc518700be8ffe803a50cb716eadSean Paul  ret = drm_->GetConnectorProperty(*this, "CRTC_ID", &crtc_id_property_);
51877be974a2d4fc518700be8ffe803a50cb716eadSean Paul  if (ret) {
52877be974a2d4fc518700be8ffe803a50cb716eadSean Paul    ALOGE("Could not get CRTC_ID property\n");
53877be974a2d4fc518700be8ffe803a50cb716eadSean Paul    return ret;
54877be974a2d4fc518700be8ffe803a50cb716eadSean Paul  }
556a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return 0;
566a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
576a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
586a55e9fb8e16c63c2e42bde31814f963205f722dSean Pauluint32_t DrmConnector::id() const {
596a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return id_;
606a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
616a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
626a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulint DrmConnector::display() const {
636a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return display_;
646a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
656a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
666a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulvoid DrmConnector::set_display(int display) {
676a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  display_ = display;
686a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
696a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
706a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulbool DrmConnector::built_in() const {
716a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return type_ == DRM_MODE_CONNECTOR_LVDS || type_ == DRM_MODE_CONNECTOR_eDP ||
726a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul         type_ == DRM_MODE_CONNECTOR_DSI;
736a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
746a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
756a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulint DrmConnector::UpdateModes() {
766a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  int fd = drm_->fd();
776a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
786a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  drmModeConnectorPtr c = drmModeGetConnector(fd, id_);
796a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  if (!c) {
806a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    ALOGE("Failed to get connector %d", id_);
816a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    return -ENODEV;
826a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  }
836a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
840a1bb6f0d006eabdb8c8a3ee61100a63af0396efSean Paul  state_ = c->connection;
850a1bb6f0d006eabdb8c8a3ee61100a63af0396efSean Paul
866a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  std::vector<DrmMode> new_modes;
876a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  for (int i = 0; i < c->count_modes; ++i) {
886a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    bool exists = false;
89ff30b52303cdbeb9cbfb054e2a12da1135ea49c9Zach Reizner    for (const DrmMode &mode : modes_) {
90ff30b52303cdbeb9cbfb054e2a12da1135ea49c9Zach Reizner      if (mode == c->modes[i]) {
91ff30b52303cdbeb9cbfb054e2a12da1135ea49c9Zach Reizner        new_modes.push_back(mode);
926a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul        exists = true;
936a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul        break;
946a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      }
956a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    }
966a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    if (exists)
976a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul      continue;
986a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
996a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    DrmMode m(&c->modes[i]);
1006a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    m.set_id(drm_->next_mode_id());
1016a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul    new_modes.push_back(m);
1026a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  }
1036a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  modes_.swap(new_modes);
1046a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return 0;
1056a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
1066a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
1076a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulconst DrmMode &DrmConnector::active_mode() const {
1086a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return active_mode_;
1096a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
1106a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
111877be974a2d4fc518700be8ffe803a50cb716eadSean Paulvoid DrmConnector::set_active_mode(const DrmMode &mode) {
112877be974a2d4fc518700be8ffe803a50cb716eadSean Paul  active_mode_ = mode;
1136a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
1146a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
1156a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulconst DrmProperty &DrmConnector::dpms_property() const {
1166a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return dpms_property_;
1176a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
1186a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
119877be974a2d4fc518700be8ffe803a50cb716eadSean Paulconst DrmProperty &DrmConnector::crtc_id_property() const {
120877be974a2d4fc518700be8ffe803a50cb716eadSean Paul  return crtc_id_property_;
121877be974a2d4fc518700be8ffe803a50cb716eadSean Paul}
122877be974a2d4fc518700be8ffe803a50cb716eadSean Paul
1236a55e9fb8e16c63c2e42bde31814f963205f722dSean PaulDrmEncoder *DrmConnector::encoder() const {
1246a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return encoder_;
1256a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
1266a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
1276a55e9fb8e16c63c2e42bde31814f963205f722dSean Paulvoid DrmConnector::set_encoder(DrmEncoder *encoder) {
1286a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  encoder_ = encoder;
1296a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
1306a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
1310a1bb6f0d006eabdb8c8a3ee61100a63af0396efSean PauldrmModeConnection DrmConnector::state() const {
1320a1bb6f0d006eabdb8c8a3ee61100a63af0396efSean Paul  return state_;
1330a1bb6f0d006eabdb8c8a3ee61100a63af0396efSean Paul}
1340a1bb6f0d006eabdb8c8a3ee61100a63af0396efSean Paul
1356a55e9fb8e16c63c2e42bde31814f963205f722dSean Pauluint32_t DrmConnector::mm_width() const {
1366a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return mm_width_;
1376a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
1386a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul
1396a55e9fb8e16c63c2e42bde31814f963205f722dSean Pauluint32_t DrmConnector::mm_height() const {
1406a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul  return mm_height_;
1416a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
1426a55e9fb8e16c63c2e42bde31814f963205f722dSean Paul}
143