blob: 1d29495da155b08855811b078d2d8b3fa91ca4db [file] [log] [blame]
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001/*
2* Copyright (c) 2017, The Linux Foundation. All rights reserved.
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above
10* copyright notice, this list of conditions and the following
11* disclaimer in the documentation and/or other materials provided
12* with the distribution.
13* * Neither the name of The Linux Foundation nor the names of its
14* contributors may be used to endorse or promote products derived
15* from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <errno.h>
31
32#include "drm_master.h"
33#include "drm_res_mgr.h"
34
35#define DEBUG 0
36#define __CLASS__ "DRMResMgr"
37
38using std::mutex;
39using std::lock_guard;
40
41namespace drm_utils {
42
43DRMResMgr *DRMResMgr::s_instance = nullptr;
44mutex DRMResMgr::s_lock;
45
46static bool GetConnector(int dev_fd, drmModeRes *res, drmModeConnector **connector) {
47 for (auto i = 0; i < res->count_connectors; i++) {
48 drmModeConnector *conn = drmModeGetConnector(dev_fd, res->connectors[i]);
49 if (conn && conn->connector_type == DRM_MODE_CONNECTOR_DSI && conn->count_modes &&
50 conn->connection == DRM_MODE_CONNECTED) {
51 *connector = conn;
Saurabh Shah66c941b2016-07-06 17:34:05 -070052 DRM_LOGI("Found connector %d", conn->connector_id);
Saurabh Shah7d476ed2016-06-27 16:40:58 -070053 return true;
54 }
55 }
56
57 return false;
58}
59
60static bool GetEncoder(int dev_fd, drmModeConnector *conn, drmModeEncoder **encoder) {
61 for (auto i = 0; i < conn->count_encoders; i++) {
62 drmModeEncoder *enc = drmModeGetEncoder(dev_fd, conn->encoders[i]);
63 if (enc && enc->encoder_type == DRM_MODE_ENCODER_DSI) {
64 *encoder = enc;
Saurabh Shah66c941b2016-07-06 17:34:05 -070065 DRM_LOGI("Found encoder %d", enc->encoder_id);
Saurabh Shah7d476ed2016-06-27 16:40:58 -070066 return true;
67 }
68 }
69 return false;
70}
71
72static bool GetCrtc(int dev_fd, drmModeRes *res, drmModeEncoder *enc, drmModeCrtc **crtc) {
73 for (auto i = 0; i < res->count_crtcs; i++) {
74 if (enc->possible_crtcs & (1 << i)) {
75 drmModeCrtc *c = drmModeGetCrtc(dev_fd, res->crtcs[i]);
76 if (c) {
77 *crtc = c;
Saurabh Shah66c941b2016-07-06 17:34:05 -070078 DRM_LOGI("Found crtc %d", c->crtc_id);
Saurabh Shah7d476ed2016-06-27 16:40:58 -070079 return true;
80 }
81 }
82 }
83
84 return false;
85}
86
Saurabh Shah66c941b2016-07-06 17:34:05 -070087#define __CLASS__ "DRMResMgr"
88
Saurabh Shah7d476ed2016-06-27 16:40:58 -070089int DRMResMgr::GetInstance(DRMResMgr **res_mgr) {
90 lock_guard<mutex> obj(s_lock);
91
92 if (!s_instance) {
93 s_instance = new DRMResMgr();
94 if (s_instance->Init() < 0) {
95 delete s_instance;
96 s_instance = nullptr;
97 return -ENODEV;
98 }
99 }
100
101 *res_mgr = s_instance;
102 return 0;
103}
104
105int DRMResMgr::Init() {
106 DRMMaster *master = nullptr;
107 int dev_fd = -1;
108
109 int ret = DRMMaster::GetInstance(&master);
110 if (ret < 0) {
111 return ret;
112 }
113
114 master->GetHandle(&dev_fd);
115 drmModeRes *res = drmModeGetResources(dev_fd);
116 if (res == nullptr) {
Saurabh Shah66c941b2016-07-06 17:34:05 -0700117 DRM_LOGE("drmModeGetResources failed");
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700118 return -ENODEV;
119 }
120
121 drmModeConnector *conn = nullptr;
122 if (!GetConnector(dev_fd, res, &conn)) {
Saurabh Shah66c941b2016-07-06 17:34:05 -0700123 DRM_LOGE("Failed to find a connector");
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700124 return -ENODEV;
125 }
126
127 drmModeEncoder *enc = nullptr;
128 if (!GetEncoder(dev_fd, conn, &enc)) {
Saurabh Shah66c941b2016-07-06 17:34:05 -0700129 DRM_LOGE("Failed to find an encoder");
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700130 drmModeFreeConnector(conn);
131 return -ENODEV;
132 }
133
134 drmModeCrtc *crtc = nullptr;
135 if (!GetCrtc(dev_fd, res, enc, &crtc)) {
Saurabh Shah66c941b2016-07-06 17:34:05 -0700136 DRM_LOGE("Failed to find a crtc");
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700137 drmModeFreeEncoder(enc);
138 drmModeFreeConnector(conn);
139 drmModeFreeResources(res);
140 return -ENODEV;
141 }
142
143 res_ = res;
144 conn_ = conn;
145 enc_ = enc;
146 crtc_ = crtc;
147
148 return 0;
149}
150
151} // namespace drm_utils