1/* 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("Found connector %d", 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("Found encoder %d", 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("Found crtc %d", c->crtc_id); 79 return true; 80 } 81 } 82 } 83 84 return false; 85} 86 87#define __CLASS__ "DRMResMgr" 88 89int 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) { 117 DRM_LOGE("drmModeGetResources failed"); 118 return -ENODEV; 119 } 120 121 drmModeConnector *conn = nullptr; 122 if (!GetConnector(dev_fd, res, &conn)) { 123 DRM_LOGE("Failed to find a connector"); 124 return -ENODEV; 125 } 126 127 drmModeEncoder *enc = nullptr; 128 if (!GetEncoder(dev_fd, conn, &enc)) { 129 DRM_LOGE("Failed to find an encoder"); 130 drmModeFreeConnector(conn); 131 return -ENODEV; 132 } 133 134 drmModeCrtc *crtc = nullptr; 135 if (!GetCrtc(dev_fd, res, enc, &crtc)) { 136 DRM_LOGE("Failed to find a crtc"); 137 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 152