blob: 61d25c44424ddf361c632367e363730298408e5c [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;
52 DRM_LOGI("drm_utils::%s found connector %d", __FUNCTION__, conn->connector_id);
53 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;
65 DRM_LOGI("drm_utils::%s found encoder %d", __FUNCTION__, enc->encoder_id);
66 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;
78 DRM_LOGI("drm_utils::%s found crtc %d", __FUNCTION__, c->crtc_id);
79 return true;
80 }
81 }
82 }
83
84 return false;
85}
86
87int DRMResMgr::GetInstance(DRMResMgr **res_mgr) {
88 lock_guard<mutex> obj(s_lock);
89
90 if (!s_instance) {
91 s_instance = new DRMResMgr();
92 if (s_instance->Init() < 0) {
93 delete s_instance;
94 s_instance = nullptr;
95 return -ENODEV;
96 }
97 }
98
99 *res_mgr = s_instance;
100 return 0;
101}
102
103int DRMResMgr::Init() {
104 DRMMaster *master = nullptr;
105 int dev_fd = -1;
106
107 int ret = DRMMaster::GetInstance(&master);
108 if (ret < 0) {
109 return ret;
110 }
111
112 master->GetHandle(&dev_fd);
113 drmModeRes *res = drmModeGetResources(dev_fd);
114 if (res == nullptr) {
115 DRM_LOGE("%s::%s: drmModeGetResources failed", __CLASS__, __FUNCTION__);
116 return -ENODEV;
117 }
118
119 drmModeConnector *conn = nullptr;
120 if (!GetConnector(dev_fd, res, &conn)) {
121 DRM_LOGE("%s::%s: Failed to find a connector", __CLASS__, __FUNCTION__);
122 return -ENODEV;
123 }
124
125 drmModeEncoder *enc = nullptr;
126 if (!GetEncoder(dev_fd, conn, &enc)) {
127 DRM_LOGE("%s::%s: Failed to find an encoder", __CLASS__, __FUNCTION__);
128 drmModeFreeConnector(conn);
129 return -ENODEV;
130 }
131
132 drmModeCrtc *crtc = nullptr;
133 if (!GetCrtc(dev_fd, res, enc, &crtc)) {
134 DRM_LOGE("%s::%s: Failed to find a crtc", __CLASS__, __FUNCTION__);
135 drmModeFreeEncoder(enc);
136 drmModeFreeConnector(conn);
137 drmModeFreeResources(res);
138 return -ENODEV;
139 }
140
141 res_ = res;
142 conn_ = conn;
143 enc_ = enc;
144 crtc_ = crtc;
145
146 return 0;
147}
148
149} // namespace drm_utils