Home | History | Annotate | Download | only in libdrmutils
      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 
     38 using std::mutex;
     39 using std::lock_guard;
     40 
     41 namespace drm_utils {
     42 
     43 DRMResMgr *DRMResMgr::s_instance = nullptr;
     44 mutex DRMResMgr::s_lock;
     45 
     46 static 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 
     60 static 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 
     72 static 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 
     89 int 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 
    105 int 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