Home | History | Annotate | Download | only in base
      1 /*
      2 // Copyright(c)2014 IntelCorporation
      3 //
      4 // LicensedundertheApacheLicense,Version2.0(the"License");
      5 // youmaynotusethisfileexceptincompliancewiththeLicense.
      6 // YoumayobtainacopyoftheLicenseat
      7 //
      8 // http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software
     11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS,
     12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
     13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand
     14 // limitationsundertheLicense.
     15 */
     16 #include <fcntl.h>
     17 #include <errno.h>
     18 #include <common/utils/HwcTrace.h>
     19 #include <IDisplayDevice.h>
     20 #include <DrmConfig.h>
     21 #include <common/base/Drm.h>
     22 #include <Hwcomposer.h>
     23 
     24 namespace android {
     25 namespace intel {
     26 
     27 Drm::Drm()
     28     : mDrmFd(0),
     29       mLock(),
     30       mInitialized(false)
     31 {
     32     memset(&mOutputs, 0, sizeof(mOutputs));
     33 }
     34 
     35 Drm::~Drm()
     36 {
     37     WARN_IF_NOT_DEINIT();
     38 }
     39 
     40 bool Drm::initialize()
     41 {
     42     if (mInitialized) {
     43         WLOGTRACE("Drm object has been initialized");
     44         return true;
     45     }
     46 
     47     const char *path = DrmConfig::getDrmPath();
     48     mDrmFd = open(path, O_RDWR, 0);
     49     if (mDrmFd < 0) {
     50         ELOGTRACE("failed to open Drm, error: %s", strerror(errno));
     51         return false;
     52     }
     53     DLOGTRACE("mDrmFd = %d", mDrmFd);
     54 
     55     memset(&mOutputs, 0, sizeof(mOutputs));
     56     mInitialized = true;
     57     return true;
     58 }
     59 
     60 void Drm::deinitialize()
     61 {
     62     for (int i = 0; i < OUTPUT_MAX; i++) {
     63         resetOutput(i);
     64     }
     65 
     66     if (mDrmFd) {
     67         close(mDrmFd);
     68         mDrmFd = 0;
     69     }
     70     mInitialized = false;
     71 }
     72 
     73 bool Drm::detect(int device)
     74 {
     75     RETURN_FALSE_IF_NOT_INIT();
     76 
     77     Mutex::Autolock _l(mLock);
     78     int outputIndex = getOutputIndex(device);
     79     if (outputIndex < 0 ) {
     80         return false;
     81     }
     82 
     83     resetOutput(outputIndex);
     84 
     85     // get drm resources
     86     drmModeResPtr resources = drmModeGetResources(mDrmFd);
     87     if (!resources) {
     88         ELOGTRACE("fail to get drm resources, error: %s", strerror(errno));
     89         return false;
     90     }
     91 
     92     drmModeConnectorPtr connector = NULL;
     93     DrmOutput *output = &mOutputs[outputIndex];
     94     bool ret = false;
     95 
     96     // find connector for the given device
     97     for (int i = 0; i < resources->count_connectors; i++) {
     98         if (!resources->connectors || !resources->connectors[i]) {
     99             ELOGTRACE("fail to get drm resources connectors, error: %s", strerror(errno));
    100             continue;
    101         }
    102 
    103         connector = drmModeGetConnector(mDrmFd, resources->connectors[i]);
    104         if (!connector) {
    105             ELOGTRACE("drmModeGetConnector failed");
    106             continue;
    107         }
    108 
    109         if (connector->connector_type != DrmConfig::getDrmConnector(device)) {
    110             drmModeFreeConnector(connector);
    111             continue;
    112         }
    113 
    114         if (connector->connection != DRM_MODE_CONNECTED) {
    115             ILOGTRACE("device %d is not connected", device);
    116             drmModeFreeConnector(connector);
    117             ret = true;
    118             break;
    119         }
    120 
    121         output->connector = connector;
    122         output->connected = true;
    123 
    124         // get proper encoder for the given connector
    125         if (connector->encoder_id) {
    126             ILOGTRACE("Drm connector has encoder attached on device %d", device);
    127             output->encoder = drmModeGetEncoder(mDrmFd, connector->encoder_id);
    128             if (!output->encoder) {
    129                 ELOGTRACE("failed to get encoder from a known encoder id");
    130                 // fall through to get an encoder
    131             }
    132         }
    133         if (!output->encoder) {
    134             ILOGTRACE("getting encoder for device %d", device);
    135             drmModeEncoderPtr encoder;
    136             for (int j = 0; j < resources->count_encoders; j++) {
    137                 if (!resources->encoders || !resources->encoders[j]) {
    138                     ELOGTRACE("fail to get drm resources encoders, error: %s", strerror(errno));
    139                     continue;
    140                 }
    141 
    142                 encoder = drmModeGetEncoder(mDrmFd, resources->encoders[i]);
    143                 if (!encoder) {
    144                     ELOGTRACE("drmModeGetEncoder failed");
    145                     continue;
    146                 }
    147                 if (encoder->encoder_type == DrmConfig::getDrmEncoder(device)) {
    148                     output->encoder = encoder;
    149                     break;
    150                 }
    151                 drmModeFreeEncoder(encoder);
    152                 encoder = NULL;
    153             }
    154         }
    155         if (!output->encoder) {
    156             ELOGTRACE("failed to get drm encoder");
    157             break;
    158         }
    159 
    160         // get an attached crtc or spare crtc
    161         if (output->encoder->crtc_id) {
    162             ILOGTRACE("Drm encoder has crtc attached on device %d", device);
    163             output->crtc = drmModeGetCrtc(mDrmFd, output->encoder->crtc_id);
    164             if (!output->crtc) {
    165                 ELOGTRACE("failed to get crtc from a known crtc id");
    166                 // fall through to get a spare crtc
    167             }
    168         }
    169         if (!output->crtc) {
    170             ILOGTRACE("getting crtc for device %d", device);
    171             drmModeCrtcPtr crtc;
    172             for (int j = 0; j < resources->count_crtcs; j++) {
    173                 if (!resources->crtcs || !resources->crtcs[j]) {
    174                     ELOGTRACE("fail to get drm resources crtcs, error: %s", strerror(errno));
    175                     continue;
    176                 }
    177 
    178                 crtc = drmModeGetCrtc(mDrmFd, resources->crtcs[j]);
    179                 if (!crtc) {
    180                     ELOGTRACE("drmModeGetCrtc failed");
    181                     continue;
    182                 }
    183                 // check if legal crtc to the encoder
    184                 if (output->encoder->possible_crtcs & (1<<j)) {
    185                     if (crtc->buffer_id == 0) {
    186                         output->crtc = crtc;
    187                         break;
    188                     }
    189                 }
    190                 drmModeFreeCrtc(crtc);
    191             }
    192         }
    193         if (!output->crtc) {
    194             ELOGTRACE("failed to get drm crtc");
    195             break;
    196         }
    197 
    198         // current mode
    199         if (output->crtc->mode_valid) {
    200             ILOGTRACE("mode is valid, kernel mode settings");
    201             memcpy(&output->mode, &output->crtc->mode, sizeof(drmModeModeInfo));
    202             //output->fbId = output->crtc->buffer_id;
    203             ret = true;
    204         } else {
    205             ELOGTRACE("mode is invalid. Kernel mode setting is not completed");
    206             ret = false;
    207         }
    208 
    209         if (outputIndex == OUTPUT_PRIMARY) {
    210             if (!readIoctl(DRM_PSB_PANEL_ORIENTATION, &output->panelOrientation, sizeof(int))) {
    211                 ELOGTRACE("failed to get device %d orientation", device);
    212                 output->panelOrientation = PANEL_ORIENTATION_0;
    213             }
    214         } else {
    215             output->panelOrientation = PANEL_ORIENTATION_0;
    216         }
    217         break;
    218     }
    219 
    220     if (!ret) {
    221         if (output->connector == NULL && outputIndex != OUTPUT_PRIMARY) {
    222             // a fatal failure on primary device
    223             // non fatal on secondary device
    224             WLOGTRACE("device %d is disabled?", device);
    225             ret = true;
    226         }
    227          resetOutput(outputIndex);
    228     } else if (output->connected) {
    229         ILOGTRACE("mode is: %dx%d@%dHz", output->mode.hdisplay, output->mode.vdisplay, output->mode.vrefresh);
    230     }
    231 
    232     drmModeFreeResources(resources);
    233     return ret;
    234 }
    235 
    236 bool Drm::isSameDrmMode(drmModeModeInfoPtr value,
    237         drmModeModeInfoPtr base) const
    238 {
    239     if (base->hdisplay == value->hdisplay &&
    240         base->vdisplay == value->vdisplay &&
    241         base->vrefresh == value->vrefresh &&
    242         (base->flags & value->flags) == value->flags) {
    243         VLOGTRACE("Drm mode is not changed");
    244         return true;
    245     }
    246 
    247     return false;
    248 }
    249 
    250 bool Drm::setDrmMode(int device, drmModeModeInfo& value)
    251 {
    252     RETURN_FALSE_IF_NOT_INIT();
    253     Mutex::Autolock _l(mLock);
    254 
    255     if (device != IDisplayDevice::DEVICE_EXTERNAL) {
    256         WLOGTRACE("Setting mode on invalid device %d", device);
    257         return false;
    258     }
    259 
    260     int outputIndex = getOutputIndex(device);
    261     if (outputIndex < 0 ) {
    262         ELOGTRACE("invalid device");
    263         return false;
    264     }
    265 
    266     DrmOutput *output= &mOutputs[outputIndex];
    267     if (!output->connected) {
    268         ELOGTRACE("device is not connected");
    269         return false;
    270     }
    271 
    272     if (output->connector->count_modes <= 0) {
    273         ELOGTRACE("invalid count of modes");
    274         return false;
    275     }
    276 
    277     drmModeModeInfoPtr mode;
    278     int index = 0;
    279     for (int i = 0; i < output->connector->count_modes; i++) {
    280         mode = &output->connector->modes[i];
    281         if (mode->type & DRM_MODE_TYPE_PREFERRED) {
    282             index = i;
    283         }
    284         if (isSameDrmMode(&value, mode)) {
    285             index = i;
    286             break;
    287         }
    288     }
    289 
    290     mode = &output->connector->modes[index];
    291     return setDrmMode(outputIndex, mode);
    292 }
    293 
    294 bool Drm::setRefreshRate(int device, int hz)
    295 {
    296     RETURN_FALSE_IF_NOT_INIT();
    297     Mutex::Autolock _l(mLock);
    298 
    299     if (device != IDisplayDevice::DEVICE_EXTERNAL) {
    300         WLOGTRACE("Setting mode on invalid device %d", device);
    301         return false;
    302     }
    303 
    304     int outputIndex = getOutputIndex(device);
    305     if (outputIndex < 0 ) {
    306         ELOGTRACE("invalid device");
    307         return false;
    308     }
    309 
    310     DrmOutput *output= &mOutputs[outputIndex];
    311     if (!output->connected) {
    312         ELOGTRACE("device is not connected");
    313         return false;
    314     }
    315 
    316     if (output->connector->count_modes <= 0) {
    317         ELOGTRACE("invalid count of modes");
    318         return false;
    319     }
    320 
    321     drmModeModeInfoPtr mode;
    322     int index = 0;
    323     for (int i = 0; i < output->connector->count_modes; i++) {
    324         mode = &output->connector->modes[i];
    325         if (mode->type & DRM_MODE_TYPE_PREFERRED) {
    326             index = i;
    327         }
    328         if (mode->hdisplay == output->mode.hdisplay &&
    329             mode->vdisplay == output->mode.vdisplay &&
    330             mode->vrefresh == (uint32_t)hz) {
    331             index = i;
    332             break;
    333         }
    334     }
    335 
    336     mode = &output->connector->modes[index];
    337     return setDrmMode(outputIndex, mode);
    338 }
    339 
    340 bool Drm::writeReadIoctl(unsigned long cmd, void *data,
    341                            unsigned long size)
    342 {
    343     int err;
    344 
    345     if (mDrmFd <= 0) {
    346         ELOGTRACE("drm is not initialized");
    347         return false;
    348     }
    349 
    350     if (!data || !size) {
    351         ELOGTRACE("invalid parameters");
    352         return false;
    353     }
    354 
    355     err = drmCommandWriteRead(mDrmFd, cmd, data, size);
    356     if (err) {
    357         WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
    358         return false;
    359     }
    360 
    361     return true;
    362 }
    363 
    364 bool Drm::writeIoctl(unsigned long cmd, void *data,
    365                        unsigned long size)
    366 {
    367     int err;
    368 
    369     if (mDrmFd <= 0) {
    370         ELOGTRACE("drm is not initialized");
    371         return false;
    372     }
    373 
    374     if (!data || !size) {
    375         ELOGTRACE("invalid parameters");
    376         return false;
    377     }
    378 
    379     err = drmCommandWrite(mDrmFd, cmd, data, size);
    380     if (err) {
    381         WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
    382         return false;
    383     }
    384 
    385     return true;
    386 }
    387 
    388 
    389 bool Drm::readIoctl(unsigned long cmd, void *data,
    390                        unsigned long size)
    391 {
    392     int err;
    393 
    394     if (mDrmFd <= 0) {
    395         ELOGTRACE("drm is not initialized");
    396         return false;
    397     }
    398 
    399     if (!data || !size) {
    400         ELOGTRACE("invalid parameters");
    401         return false;
    402     }
    403 
    404     err = drmCommandRead(mDrmFd, cmd, data, size);
    405     if (err) {
    406         WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
    407         return false;
    408     }
    409 
    410     return true;
    411 }
    412 
    413 
    414 int Drm::getDrmFd() const
    415 {
    416     return mDrmFd;
    417 }
    418 
    419 bool Drm::getModeInfo(int device, drmModeModeInfo& mode)
    420 {
    421     Mutex::Autolock _l(mLock);
    422 
    423     int outputIndex = getOutputIndex(device);
    424     if (outputIndex < 0 ) {
    425         return false;
    426     }
    427 
    428     DrmOutput *output= &mOutputs[outputIndex];
    429     if (output->connected == false) {
    430         ELOGTRACE("device is not connected");
    431         return false;
    432     }
    433 
    434     if (output->mode.hdisplay == 0 || output->mode.vdisplay == 0) {
    435         ELOGTRACE("invalid width or height");
    436         return false;
    437     }
    438 
    439     memcpy(&mode, &output->mode, sizeof(drmModeModeInfo));
    440 
    441 #ifdef INTEL_SUPPORT_HDMI_PRIMARY
    442     // FIXME: use default fb size instead of hdmi mode, because to
    443     // support hdmi primary, we cannot report dynamic mode to SF.
    444     mode.hdisplay = DEFAULT_DRM_FB_WIDTH;
    445     mode.vdisplay = DEFAULT_DRM_FB_HEIGHT;
    446 #endif
    447 
    448     return true;
    449 }
    450 
    451 bool Drm::getPhysicalSize(int device, uint32_t& width, uint32_t& height)
    452 {
    453     Mutex::Autolock _l(mLock);
    454 
    455     int outputIndex = getOutputIndex(device);
    456     if (outputIndex < 0 ) {
    457         return false;
    458     }
    459 
    460     DrmOutput *output= &mOutputs[outputIndex];
    461     if (output->connected == false) {
    462         ELOGTRACE("device is not connected");
    463         return false;
    464     }
    465 
    466     width = output->connector->mmWidth;
    467     height = output->connector->mmHeight;
    468     return true;
    469 }
    470 
    471 bool Drm::getDisplayResolution(int device, uint32_t& width, uint32_t& height)
    472 {
    473     Mutex::Autolock _l(mLock);
    474 
    475     int outputIndex = getOutputIndex(device);
    476     if (outputIndex < 0) {
    477         return false;
    478     }
    479 
    480     DrmOutput *output= &mOutputs[outputIndex];
    481     if (output->connected == false) {
    482         ELOGTRACE("device is not connected");
    483         return false;
    484     }
    485 
    486     width = output->mode.hdisplay;
    487     height = output->mode.vdisplay;
    488 
    489     if (!width || !height) {
    490         ELOGTRACE("invalid width or height");
    491         return false;
    492     }
    493     return true;
    494 }
    495 
    496 bool Drm::isConnected(int device)
    497 {
    498     Mutex::Autolock _l(mLock);
    499 
    500     int output = getOutputIndex(device);
    501     if (output < 0 ) {
    502         return false;
    503     }
    504 
    505     return mOutputs[output].connected;
    506 }
    507 
    508 bool Drm::setDpmsMode(int device, int mode)
    509 {
    510     Mutex::Autolock _l(mLock);
    511 
    512 #ifdef INTEL_SUPPORT_HDMI_PRIMARY
    513     device = IDisplayDevice::DEVICE_EXTERNAL;
    514 #endif
    515 
    516     int output = getOutputIndex(device);
    517     if (output < 0 ) {
    518         return false;
    519     }
    520 
    521     if (mode != IDisplayDevice::DEVICE_DISPLAY_OFF &&
    522             mode != IDisplayDevice::DEVICE_DISPLAY_STANDBY &&
    523             mode != IDisplayDevice::DEVICE_DISPLAY_ON) {
    524         ELOGTRACE("invalid mode %d", mode);
    525         return false;
    526     }
    527 
    528     DrmOutput *out = &mOutputs[output];
    529     if (!out->connected) {
    530         ELOGTRACE("device is not connected");
    531         return false;
    532     }
    533 
    534     drmModePropertyPtr props;
    535     for (int i = 0; i < out->connector->count_props; i++) {
    536         props = drmModeGetProperty(mDrmFd, out->connector->props[i]);
    537         if (!props) {
    538             continue;
    539         }
    540 
    541         if (strcmp(props->name, "DPMS") == 0) {
    542             int ret = drmModeConnectorSetProperty(
    543                 mDrmFd,
    544                 out->connector->connector_id,
    545                 props->prop_id,
    546                 (mode == IDisplayDevice::DEVICE_DISPLAY_ON) ? DRM_MODE_DPMS_ON :
    547                         IDisplayDevice::DEVICE_DISPLAY_STANDBY == mode ?
    548                         DRM_MODE_DPMS_STANDBY : DRM_MODE_DPMS_OFF);
    549             drmModeFreeProperty(props);
    550             if (ret != 0) {
    551                 ELOGTRACE("unable to set DPMS %d", mode);
    552                 return false;
    553             } else {
    554                 return true;
    555             }
    556         }
    557         drmModeFreeProperty(props);
    558     }
    559     return false;
    560 }
    561 
    562 void Drm::resetOutput(int index)
    563 {
    564     DrmOutput *output = &mOutputs[index];
    565 
    566     output->connected = false;
    567     memset(&output->mode, 0, sizeof(drmModeModeInfo));
    568 
    569     if (output->connector) {
    570         drmModeFreeConnector(output->connector);
    571         output->connector = 0;
    572     }
    573     if (output->encoder) {
    574         drmModeFreeEncoder(output->encoder);
    575         output->encoder = 0;
    576     }
    577     if (output->crtc) {
    578         drmModeFreeCrtc(output->crtc);
    579         output->crtc = 0;
    580     }
    581     if (output->fbId) {
    582         drmModeRmFB(mDrmFd, output->fbId);
    583         output->fbId = 0;
    584     }
    585     if (output->fbHandle) {
    586         Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer(output->fbHandle);
    587         output->fbHandle = 0;
    588     }
    589 }
    590 
    591 bool Drm::initDrmMode(int outputIndex)
    592 {
    593     DrmOutput *output= &mOutputs[outputIndex];
    594     if (output->connector->count_modes <= 0) {
    595         ELOGTRACE("invalid count of modes");
    596         return false;
    597     }
    598 
    599     drmModeModeInfoPtr mode;
    600     int index = 0;
    601     for (int i = 0; i < output->connector->count_modes; i++) {
    602         mode = &output->connector->modes[i];
    603         if (mode->type & DRM_MODE_TYPE_PREFERRED) {
    604             index = i;
    605             break;
    606         }
    607     }
    608 
    609     return setDrmMode(outputIndex, &output->connector->modes[index]);
    610 }
    611 
    612 bool Drm::setDrmMode(int index, drmModeModeInfoPtr mode)
    613 {
    614     DrmOutput *output = &mOutputs[index];
    615 
    616     int oldFbId = 0;
    617     int oldFbHandle = 0;
    618     // reuse current frame buffer if there is no resolution change
    619     int fbId = -1;
    620 
    621     drmModeModeInfo currentMode;
    622     memcpy(&currentMode, &output->mode, sizeof(drmModeModeInfo));
    623 
    624     if (isSameDrmMode(mode, &currentMode))
    625         return true;
    626 
    627     if (currentMode.hdisplay != mode->hdisplay ||
    628         currentMode.vdisplay != mode->vdisplay) {
    629 
    630         oldFbId = output->fbId;
    631         oldFbHandle = output->fbHandle;
    632 
    633         // allocate frame buffer
    634         int stride = 0;
    635 #ifdef INTEL_SUPPORT_HDMI_PRIMARY
    636         output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer(
    637             DEFAULT_DRM_FB_WIDTH, DEFAULT_DRM_FB_HEIGHT, &stride);
    638 #else
    639         output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer(
    640             mode->hdisplay, mode->vdisplay, &stride);
    641 #endif
    642         if (output->fbHandle == 0) {
    643             ELOGTRACE("failed to allocate frame buffer");
    644             return false;
    645         }
    646 
    647         int ret = 0;
    648         ret = drmModeAddFB(
    649             mDrmFd,
    650 #ifdef INTEL_SUPPORT_HDMI_PRIMARY
    651             DEFAULT_DRM_FB_WIDTH,
    652             DEFAULT_DRM_FB_HEIGHT,
    653 #else
    654             mode->hdisplay,
    655             mode->vdisplay,
    656 #endif
    657             DrmConfig::getFrameBufferDepth(),
    658             DrmConfig::getFrameBufferBpp(),
    659             stride,
    660             output->fbHandle,
    661             &output->fbId);
    662         if (ret != 0) {
    663             ELOGTRACE("drmModeAddFB failed, error: %d", ret);
    664             return false;
    665         }
    666         fbId = output->fbId;
    667     }
    668 
    669     ILOGTRACE("mode set: %dx%d@%dHz", mode->hdisplay, mode->vdisplay, mode->vrefresh);
    670 
    671     int ret = drmModeSetCrtc(mDrmFd, output->crtc->crtc_id, fbId, 0, 0,
    672                    &output->connector->connector_id, 1, mode);
    673 
    674     if (ret == 0) {
    675         //save mode
    676         memcpy(&output->mode, mode, sizeof(drmModeModeInfo));
    677     } else {
    678         ELOGTRACE("drmModeSetCrtc failed. error: %d", ret);
    679     }
    680 
    681     if (oldFbId) {
    682         drmModeRmFB(mDrmFd, oldFbId);
    683     }
    684 
    685     if (oldFbHandle) {
    686         Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer(oldFbHandle);
    687     }
    688 
    689     return ret == 0;
    690 }
    691 
    692 int Drm::getOutputIndex(int device)
    693 {
    694     switch (device) {
    695     case IDisplayDevice::DEVICE_PRIMARY:
    696         return OUTPUT_PRIMARY;
    697     case IDisplayDevice::DEVICE_EXTERNAL:
    698         return OUTPUT_EXTERNAL;
    699     default:
    700         ELOGTRACE("invalid display device");
    701         break;
    702     }
    703 
    704     return -1;
    705 }
    706 
    707 int Drm::getPanelOrientation(int device)
    708 {
    709     int outputIndex = getOutputIndex(device);
    710     if (outputIndex < 0) {
    711         ELOGTRACE("invalid device");
    712         return PANEL_ORIENTATION_0;
    713     }
    714 
    715     DrmOutput *output= &mOutputs[outputIndex];
    716     if (output->connected == false) {
    717         ELOGTRACE("device is not connected");
    718         return PANEL_ORIENTATION_0;
    719     }
    720 
    721     return output->panelOrientation;
    722 }
    723 
    724 // HWC 1.4 requires that we return all of the compatible configs in getDisplayConfigs
    725 // this is needed so getActiveConfig/setActiveConfig work correctly.  It is up to the
    726 // user space to decide what speed to send.
    727 drmModeModeInfoPtr Drm::detectAllConfigs(int device, int *modeCount)
    728 {
    729     RETURN_NULL_IF_NOT_INIT();
    730     Mutex::Autolock _l(mLock);
    731 
    732     if (modeCount != NULL)
    733         *modeCount = 0;
    734     else
    735         return NULL;
    736 
    737     int outputIndex = getOutputIndex(device);
    738     if (outputIndex < 0) {
    739         ELOGTRACE("invalid device");
    740         return NULL;
    741     }
    742 
    743     DrmOutput *output= &mOutputs[outputIndex];
    744     if (!output->connected) {
    745         ELOGTRACE("device is not connected");
    746         return NULL;
    747     }
    748 
    749     if (output->connector->count_modes <= 0) {
    750         ELOGTRACE("invalid count of modes");
    751         return NULL;
    752     }
    753 
    754     *modeCount = output->connector->count_modes;
    755     return output->connector->modes;
    756 }
    757 
    758 } // namespace intel
    759 } // namespace android
    760 
    761