16a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu/*
2cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// Copyright (c) 2014 Intel Corporation 
3cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika//
4cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// Licensed under the Apache License, Version 2.0 (the "License");
5cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// you may not use this file except in compliance with the License.
6cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// You may obtain a copy of the License at
7cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika//
8cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika//      http://www.apache.org/licenses/LICENSE-2.0
9cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika//
10cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// Unless required by applicable law or agreed to in writing, software
11cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// distributed under the License is distributed on an "AS IS" BASIS,
12cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// See the License for the specific language governing permissions and
14cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// limitations under the License.
15cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika*/
166a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu#include <fcntl.h>
176a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu#include <errno.h>
180594c42af26255fd8d3d7d39c0cb0e2da5b8841bThierry Strudel#include <common/utils/HwcTrace.h>
1965efc253a628175c7afa95c431b746ea20052794Andy Qiu#include <IDisplayDevice.h>
20877d4ac27c6fde0b89b68e7c6e352edf879b3dedAndy Qiu#include <DrmConfig.h>
210594c42af26255fd8d3d7d39c0cb0e2da5b8841bThierry Strudel#include <common/base/Drm.h>
2230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu#include <Hwcomposer.h>
236a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
246a6081a46a83da606cf21548879b37695adc7e1fAndy Qiunamespace android {
256a6081a46a83da606cf21548879b37695adc7e1fAndy Qiunamespace intel {
266a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
276a6081a46a83da606cf21548879b37695adc7e1fAndy QiuDrm::Drm()
28e2ad4c047651d4442f6a0e002290016d45e9201afu jin    : mDrmFd(0),
29e2ad4c047651d4442f6a0e002290016d45e9201afu jin      mLock(),
30e2ad4c047651d4442f6a0e002290016d45e9201afu jin      mInitialized(false)
316a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
32e2ad4c047651d4442f6a0e002290016d45e9201afu jin    memset(&mOutputs, 0, sizeof(mOutputs));
33e2ad4c047651d4442f6a0e002290016d45e9201afu jin}
34e2ad4c047651d4442f6a0e002290016d45e9201afu jin
35e2ad4c047651d4442f6a0e002290016d45e9201afu jinDrm::~Drm()
36e2ad4c047651d4442f6a0e002290016d45e9201afu jin{
37e2ad4c047651d4442f6a0e002290016d45e9201afu jin    WARN_IF_NOT_DEINIT();
38e2ad4c047651d4442f6a0e002290016d45e9201afu jin}
39e2ad4c047651d4442f6a0e002290016d45e9201afu jin
40e2ad4c047651d4442f6a0e002290016d45e9201afu jinbool Drm::initialize()
41e2ad4c047651d4442f6a0e002290016d45e9201afu jin{
42e2ad4c047651d4442f6a0e002290016d45e9201afu jin    if (mInitialized) {
434157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("Drm object has been initialized");
44e2ad4c047651d4442f6a0e002290016d45e9201afu jin        return true;
45e2ad4c047651d4442f6a0e002290016d45e9201afu jin    }
46e2ad4c047651d4442f6a0e002290016d45e9201afu jin
47877d4ac27c6fde0b89b68e7c6e352edf879b3dedAndy Qiu    const char *path = DrmConfig::getDrmPath();
48e2ad4c047651d4442f6a0e002290016d45e9201afu jin    mDrmFd = open(path, O_RDWR, 0);
49e2ad4c047651d4442f6a0e002290016d45e9201afu jin    if (mDrmFd < 0) {
504157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("failed to open Drm, error: %s", strerror(errno));
51e2ad4c047651d4442f6a0e002290016d45e9201afu jin        return false;
526a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
534157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev    DLOGTRACE("mDrmFd = %d", mDrmFd);
546a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
556a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    memset(&mOutputs, 0, sizeof(mOutputs));
56e2ad4c047651d4442f6a0e002290016d45e9201afu jin    mInitialized = true;
57e2ad4c047651d4442f6a0e002290016d45e9201afu jin    return true;
58e2ad4c047651d4442f6a0e002290016d45e9201afu jin}
596a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
60e2ad4c047651d4442f6a0e002290016d45e9201afu jinvoid Drm::deinitialize()
61e2ad4c047651d4442f6a0e002290016d45e9201afu jin{
6230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    for (int i = 0; i < OUTPUT_MAX; i++) {
6330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        resetOutput(i);
6430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
6530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
66e2ad4c047651d4442f6a0e002290016d45e9201afu jin    if (mDrmFd) {
67e2ad4c047651d4442f6a0e002290016d45e9201afu jin        close(mDrmFd);
68e2ad4c047651d4442f6a0e002290016d45e9201afu jin        mDrmFd = 0;
69e2ad4c047651d4442f6a0e002290016d45e9201afu jin    }
70e2ad4c047651d4442f6a0e002290016d45e9201afu jin    mInitialized = false;
716a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
726a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
7330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::detect(int device)
746a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
7530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    RETURN_FALSE_IF_NOT_INIT();
766a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
7730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    Mutex::Autolock _l(mLock);
7830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    int outputIndex = getOutputIndex(device);
7930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (outputIndex < 0 ) {
806a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
816a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
826a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
8330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    resetOutput(outputIndex);
8430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
8530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    // get drm resources
866a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    drmModeResPtr resources = drmModeGetResources(mDrmFd);
876a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    if (!resources) {
884157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("fail to get drm resources, error: %s", strerror(errno));
896a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
906a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
916a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
926a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    drmModeConnectorPtr connector = NULL;
9330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    DrmOutput *output = &mOutputs[outputIndex];
9430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    bool ret = false;
956a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
9630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    // find connector for the given device
976a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    for (int i = 0; i < resources->count_connectors; i++) {
98bc1f26891639e31ef419360724e1c0af3954ae51wli        if (!resources->connectors || !resources->connectors[i]) {
994157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ELOGTRACE("fail to get drm resources connectors, error: %s", strerror(errno));
1000f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell            continue;
1010f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell        }
1020f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell
1036a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        connector = drmModeGetConnector(mDrmFd, resources->connectors[i]);
1046a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        if (!connector) {
1054157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ELOGTRACE("drmModeGetConnector failed");
1066a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu            continue;
1076a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
1086a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
10930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (connector->connector_type != DrmConfig::getDrmConnector(device)) {
11030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            drmModeFreeConnector(connector);
11130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            continue;
1126a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
1136a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
11430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (connector->connection != DRM_MODE_CONNECTED) {
1154157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ILOGTRACE("device %d is not connected", device);
116eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            drmModeFreeConnector(connector);
11730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            ret = true;
11830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            break;
11930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        }
1206a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
121eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        output->connector = connector;
12230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        output->connected = true;
1236a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
12430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        // get proper encoder for the given connector
12530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (connector->encoder_id) {
1264157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ILOGTRACE("Drm connector has encoder attached on device %d", device);
12730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            output->encoder = drmModeGetEncoder(mDrmFd, connector->encoder_id);
12830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            if (!output->encoder) {
1294157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                ELOGTRACE("failed to get encoder from a known encoder id");
13030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                // fall through to get an encoder
13130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            }
1326a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
13330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (!output->encoder) {
1344157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ILOGTRACE("getting encoder for device %d", device);
13530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            drmModeEncoderPtr encoder;
13630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            for (int j = 0; j < resources->count_encoders; j++) {
137bc1f26891639e31ef419360724e1c0af3954ae51wli                if (!resources->encoders || !resources->encoders[j]) {
1384157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                    ELOGTRACE("fail to get drm resources encoders, error: %s", strerror(errno));
1390f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell                    continue;
1400f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell                }
1410f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell
14230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                encoder = drmModeGetEncoder(mDrmFd, resources->encoders[i]);
14330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                if (!encoder) {
1444157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                    ELOGTRACE("drmModeGetEncoder failed");
14530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                    continue;
14630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                }
14730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                if (encoder->encoder_type == DrmConfig::getDrmEncoder(device)) {
14830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                    output->encoder = encoder;
14930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                    break;
15030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                }
15130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                drmModeFreeEncoder(encoder);
15230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                encoder = NULL;
15330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            }
1546a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
15530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (!output->encoder) {
1564157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ELOGTRACE("failed to get drm encoder");
15730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            break;
1586a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
1596a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
16030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        // get an attached crtc or spare crtc
16130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (output->encoder->crtc_id) {
1624157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ILOGTRACE("Drm encoder has crtc attached on device %d", device);
16330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            output->crtc = drmModeGetCrtc(mDrmFd, output->encoder->crtc_id);
16430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            if (!output->crtc) {
1654157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                ELOGTRACE("failed to get crtc from a known crtc id");
16630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                // fall through to get a spare crtc
16730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            }
16830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        }
16930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (!output->crtc) {
1704157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ILOGTRACE("getting crtc for device %d", device);
17130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            drmModeCrtcPtr crtc;
17230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            for (int j = 0; j < resources->count_crtcs; j++) {
173bc1f26891639e31ef419360724e1c0af3954ae51wli                if (!resources->crtcs || !resources->crtcs[j]) {
1744157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                    ELOGTRACE("fail to get drm resources crtcs, error: %s", strerror(errno));
1750f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell                    continue;
1760f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell                }
1770f3087a3fcd76560a54aa167d2fb8b67129730baGreg Cantrell
17830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                crtc = drmModeGetCrtc(mDrmFd, resources->crtcs[j]);
17930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                if (!crtc) {
1804157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                    ELOGTRACE("drmModeGetCrtc failed");
18130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                    continue;
18230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                }
183b55fbe96ff6c2b98374d2137c8e91c0ca357fdb2Lei Zhang                // check if legal crtc to the encoder
184b55fbe96ff6c2b98374d2137c8e91c0ca357fdb2Lei Zhang                if (output->encoder->possible_crtcs & (1<<j)) {
185b55fbe96ff6c2b98374d2137c8e91c0ca357fdb2Lei Zhang                    if (crtc->buffer_id == 0) {
186b55fbe96ff6c2b98374d2137c8e91c0ca357fdb2Lei Zhang                        output->crtc = crtc;
187b55fbe96ff6c2b98374d2137c8e91c0ca357fdb2Lei Zhang                        break;
188b55fbe96ff6c2b98374d2137c8e91c0ca357fdb2Lei Zhang                    }
18930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                }
19030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu                drmModeFreeCrtc(crtc);
19130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            }
19230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        }
19330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (!output->crtc) {
1944157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ELOGTRACE("failed to get drm crtc");
19530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            break;
1966a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
1976a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
19830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        // current mode
19930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (output->crtc->mode_valid) {
2004157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            ILOGTRACE("mode is valid, kernel mode settings");
20130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            memcpy(&output->mode, &output->crtc->mode, sizeof(drmModeModeInfo));
20230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            ret = true;
20330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        } else {
2047b871c6aa5fae82dfe062e3de5822d0b7ccb76bbAndy Qiu            ELOGTRACE("mode is invalid. Kernel mode setting is not completed");
2057b871c6aa5fae82dfe062e3de5822d0b7ccb76bbAndy Qiu            ret = false;
2066a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
207ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley
208ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley        if (outputIndex == OUTPUT_PRIMARY) {
209ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley            if (!readIoctl(DRM_PSB_PANEL_ORIENTATION, &output->panelOrientation, sizeof(int))) {
2104157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                ELOGTRACE("failed to get device %d orientation", device);
211ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley                output->panelOrientation = PANEL_ORIENTATION_0;
212ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley            }
213ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley        } else {
214ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley            output->panelOrientation = PANEL_ORIENTATION_0;
215ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley        }
21630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        break;
21730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
2186a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
21930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (!ret) {
220486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu        if (output->connector == NULL && outputIndex != OUTPUT_PRIMARY) {
221486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu            // a fatal failure on primary device
222486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu            // non fatal on secondary device
2234157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            WLOGTRACE("device %d is disabled?", device);
224486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu            ret = true;
225486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu        }
22630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu         resetOutput(outputIndex);
22730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    } else if (output->connected) {
2284157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ILOGTRACE("mode is: %dx%d@%dHz", output->mode.hdisplay, output->mode.vdisplay, output->mode.vrefresh);
22930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
2306a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
23130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    drmModeFreeResources(resources);
23230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    return ret;
23330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu}
2346a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
23512eefae3196eaadfcef7a543878fe816c4329a49Lin Xiebool Drm::isSameDrmMode(drmModeModeInfoPtr value,
23612eefae3196eaadfcef7a543878fe816c4329a49Lin Xie        drmModeModeInfoPtr base) const
23712eefae3196eaadfcef7a543878fe816c4329a49Lin Xie{
23812eefae3196eaadfcef7a543878fe816c4329a49Lin Xie    if (base->hdisplay == value->hdisplay &&
23912eefae3196eaadfcef7a543878fe816c4329a49Lin Xie        base->vdisplay == value->vdisplay &&
24012eefae3196eaadfcef7a543878fe816c4329a49Lin Xie        base->vrefresh == value->vrefresh &&
24112eefae3196eaadfcef7a543878fe816c4329a49Lin Xie        (base->flags & value->flags) == value->flags) {
2424157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        VLOGTRACE("Drm mode is not changed");
24312eefae3196eaadfcef7a543878fe816c4329a49Lin Xie        return true;
24412eefae3196eaadfcef7a543878fe816c4329a49Lin Xie    }
24512eefae3196eaadfcef7a543878fe816c4329a49Lin Xie
24612eefae3196eaadfcef7a543878fe816c4329a49Lin Xie    return false;
24712eefae3196eaadfcef7a543878fe816c4329a49Lin Xie}
24812eefae3196eaadfcef7a543878fe816c4329a49Lin Xie
2493f1974031c88750a14adc8f2f49538837238abf9Lin Xiebool Drm::setDrmMode(int device, drmModeModeInfo& value)
25030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu{
25130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    RETURN_FALSE_IF_NOT_INIT();
25230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    Mutex::Autolock _l(mLock);
2536a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
25430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (device != IDisplayDevice::DEVICE_EXTERNAL) {
2554157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("Setting mode on invalid device %d", device);
25630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
25730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
2586a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
25930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    int outputIndex = getOutputIndex(device);
26030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (outputIndex < 0 ) {
2614157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid device");
26230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
26330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
2646a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
26530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    DrmOutput *output= &mOutputs[outputIndex];
26630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (!output->connected) {
2674157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("device is not connected");
26830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
2696a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
2706a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
27130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->connector->count_modes <= 0) {
2724157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid count of modes");
27330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
27430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
2756a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
27630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    drmModeModeInfoPtr mode;
27730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    int index = 0;
27830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    for (int i = 0; i < output->connector->count_modes; i++) {
27930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        mode = &output->connector->modes[i];
28030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (mode->type & DRM_MODE_TYPE_PREFERRED) {
28130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            index = i;
28230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        }
28312eefae3196eaadfcef7a543878fe816c4329a49Lin Xie        if (isSameDrmMode(&value, mode)) {
28430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            index = i;
28530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            break;
28630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        }
28730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
28830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
28930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    mode = &output->connector->modes[index];
29030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    return setDrmMode(outputIndex, mode);
2916a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
2926a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
293b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xiebool Drm::setRefreshRate(int device, int hz)
294b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie{
295b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    RETURN_FALSE_IF_NOT_INIT();
296b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    Mutex::Autolock _l(mLock);
297b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie
298b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    if (device != IDisplayDevice::DEVICE_EXTERNAL) {
2994157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("Setting mode on invalid device %d", device);
300b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        return false;
301b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    }
302b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie
303b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    int outputIndex = getOutputIndex(device);
304b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    if (outputIndex < 0 ) {
3054157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid device");
306b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        return false;
307b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    }
308b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie
309b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    DrmOutput *output= &mOutputs[outputIndex];
310b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    if (!output->connected) {
3114157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("device is not connected");
312b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        return false;
313b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    }
314b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie
315b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    if (output->connector->count_modes <= 0) {
3164157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid count of modes");
317b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        return false;
318b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    }
319b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie
320b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    drmModeModeInfoPtr mode;
321b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    int index = 0;
322b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    for (int i = 0; i < output->connector->count_modes; i++) {
323b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        mode = &output->connector->modes[i];
324b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        if (mode->type & DRM_MODE_TYPE_PREFERRED) {
325b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie            index = i;
326b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        }
327b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        if (mode->hdisplay == output->mode.hdisplay &&
328b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie            mode->vdisplay == output->mode.vdisplay &&
329b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie            mode->vrefresh == (uint32_t)hz) {
330b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie            index = i;
331b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie            break;
332b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie        }
333b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    }
334b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie
335b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    mode = &output->connector->modes[index];
336b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie    return setDrmMode(outputIndex, mode);
337b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie}
33830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
3396a6081a46a83da606cf21548879b37695adc7e1fAndy Qiubool Drm::writeReadIoctl(unsigned long cmd, void *data,
3406a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu                           unsigned long size)
3416a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
3426a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    int err;
3436a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3446a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    if (mDrmFd <= 0) {
3454157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("drm is not initialized");
3466a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
3476a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
3486a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3496a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    if (!data || !size) {
3504157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid parameters");
3516a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
3526a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
3536a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3546a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    err = drmCommandWriteRead(mDrmFd, cmd, data, size);
3556a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    if (err) {
3564157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
3576a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
3586a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
3596a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3606a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    return true;
3616a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
3626a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3636a6081a46a83da606cf21548879b37695adc7e1fAndy Qiubool Drm::writeIoctl(unsigned long cmd, void *data,
3646a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu                       unsigned long size)
3656a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
3666a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    int err;
3676a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3686a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    if (mDrmFd <= 0) {
3694157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("drm is not initialized");
3706a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
3716a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
3726a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3736a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    if (!data || !size) {
3744157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid parameters");
3756a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
3766a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
3776a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3786a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    err = drmCommandWrite(mDrmFd, cmd, data, size);
3796a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    if (err) {
3804157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
3816a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
3826a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
3836a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
3846a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    return true;
3856a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
3866a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
387466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu
388466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hubool Drm::readIoctl(unsigned long cmd, void *data,
389466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu                       unsigned long size)
390466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu{
391466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    int err;
392466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu
393466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    if (mDrmFd <= 0) {
3944157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("drm is not initialized");
395466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu        return false;
396466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    }
397466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu
398466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    if (!data || !size) {
3994157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid parameters");
400466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu        return false;
401466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    }
402466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu
403466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    err = drmCommandRead(mDrmFd, cmd, data, size);
404466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    if (err) {
4054157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
406466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu        return false;
407466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    }
408466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu
409466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu    return true;
410466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu}
411466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu
412466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu
4136a6081a46a83da606cf21548879b37695adc7e1fAndy Qiuint Drm::getDrmFd() const
4146a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
4156a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    return mDrmFd;
4166a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
4176a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
41830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::getModeInfo(int device, drmModeModeInfo& mode)
4194a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li{
42030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    Mutex::Autolock _l(mLock);
42130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
42230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    int outputIndex = getOutputIndex(device);
42330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (outputIndex < 0 ) {
42430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
4254a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li    }
4264a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li
42730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    DrmOutput *output= &mOutputs[outputIndex];
42830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->connected == false) {
4294157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("device is not connected");
43030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
4314a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li    }
4324a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li
43330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->mode.hdisplay == 0 || output->mode.vdisplay == 0) {
4344157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid width or height");
43530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
4364a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li    }
4374a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li
43830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    memcpy(&mode, &output->mode, sizeof(drmModeModeInfo));
43995dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang
44095dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#ifdef INTEL_SUPPORT_HDMI_PRIMARY
44195dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang    // FIXME: use default fb size instead of hdmi mode, because to
44295dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang    // support hdmi primary, we cannot report dynamic mode to SF.
44395dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang    mode.hdisplay = DEFAULT_DRM_FB_WIDTH;
44495dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang    mode.vdisplay = DEFAULT_DRM_FB_HEIGHT;
44595dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#endif
44695dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang
44730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    return true;
4484a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li}
4494a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li
45030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::getPhysicalSize(int device, uint32_t& width, uint32_t& height)
4516a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
4526a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    Mutex::Autolock _l(mLock);
4536a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
45430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    int outputIndex = getOutputIndex(device);
45530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (outputIndex < 0 ) {
45630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
45730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
45830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
45930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    DrmOutput *output= &mOutputs[outputIndex];
46030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->connected == false) {
4614157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("device is not connected");
46230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
4636a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
4646a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
46530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    width = output->connector->mmWidth;
46630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    height = output->connector->mmHeight;
46730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    return true;
4686a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
4696a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
470af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiubool Drm::getDisplayResolution(int device, uint32_t& width, uint32_t& height)
471af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu{
472af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    Mutex::Autolock _l(mLock);
473af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu
474af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    int outputIndex = getOutputIndex(device);
475af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    if (outputIndex < 0) {
476af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu        return false;
477af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    }
478af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu
479af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    DrmOutput *output= &mOutputs[outputIndex];
480af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    if (output->connected == false) {
481af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu        ELOGTRACE("device is not connected");
482af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu        return false;
483af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    }
484af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu
485af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    width = output->mode.hdisplay;
486af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    height = output->mode.vdisplay;
487af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu
488af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    if (!width || !height) {
489af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu        ELOGTRACE("invalid width or height");
490af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu        return false;
491af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    }
492af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu    return true;
493af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu}
494af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu
49530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::isConnected(int device)
4966a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
4976a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    Mutex::Autolock _l(mLock);
4986a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
49965efc253a628175c7afa95c431b746ea20052794Andy Qiu    int output = getOutputIndex(device);
50065efc253a628175c7afa95c431b746ea20052794Andy Qiu    if (output < 0 ) {
5016a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return false;
5026a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
5036a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
50430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    return mOutputs[output].connected;
5056a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
5066a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
50765efc253a628175c7afa95c431b746ea20052794Andy Qiubool Drm::setDpmsMode(int device, int mode)
50865efc253a628175c7afa95c431b746ea20052794Andy Qiu{
50965efc253a628175c7afa95c431b746ea20052794Andy Qiu    Mutex::Autolock _l(mLock);
51065efc253a628175c7afa95c431b746ea20052794Andy Qiu
51165efc253a628175c7afa95c431b746ea20052794Andy Qiu    int output = getOutputIndex(device);
51265efc253a628175c7afa95c431b746ea20052794Andy Qiu    if (output < 0 ) {
51365efc253a628175c7afa95c431b746ea20052794Andy Qiu        return false;
51465efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
51565efc253a628175c7afa95c431b746ea20052794Andy Qiu
51665efc253a628175c7afa95c431b746ea20052794Andy Qiu    if (mode != IDisplayDevice::DEVICE_DISPLAY_OFF &&
5176c061a816e1bb454afc8d294231bc235a771d646Nie Jun            mode != IDisplayDevice::DEVICE_DISPLAY_STANDBY &&
5186c061a816e1bb454afc8d294231bc235a771d646Nie Jun            mode != IDisplayDevice::DEVICE_DISPLAY_ON) {
5194157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid mode %d", mode);
52065efc253a628175c7afa95c431b746ea20052794Andy Qiu        return false;
52165efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
52265efc253a628175c7afa95c431b746ea20052794Andy Qiu
52330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    DrmOutput *out = &mOutputs[output];
52430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (!out->connected) {
5254157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("device is not connected");
52665efc253a628175c7afa95c431b746ea20052794Andy Qiu        return false;
52765efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
52865efc253a628175c7afa95c431b746ea20052794Andy Qiu
52965efc253a628175c7afa95c431b746ea20052794Andy Qiu    drmModePropertyPtr props;
53065efc253a628175c7afa95c431b746ea20052794Andy Qiu    for (int i = 0; i < out->connector->count_props; i++) {
53165efc253a628175c7afa95c431b746ea20052794Andy Qiu        props = drmModeGetProperty(mDrmFd, out->connector->props[i]);
53265efc253a628175c7afa95c431b746ea20052794Andy Qiu        if (!props) {
53365efc253a628175c7afa95c431b746ea20052794Andy Qiu            continue;
53465efc253a628175c7afa95c431b746ea20052794Andy Qiu        }
53565efc253a628175c7afa95c431b746ea20052794Andy Qiu
53665efc253a628175c7afa95c431b746ea20052794Andy Qiu        if (strcmp(props->name, "DPMS") == 0) {
53765efc253a628175c7afa95c431b746ea20052794Andy Qiu            int ret = drmModeConnectorSetProperty(
53865efc253a628175c7afa95c431b746ea20052794Andy Qiu                mDrmFd,
53965efc253a628175c7afa95c431b746ea20052794Andy Qiu                out->connector->connector_id,
54065efc253a628175c7afa95c431b746ea20052794Andy Qiu                props->prop_id,
5416c061a816e1bb454afc8d294231bc235a771d646Nie Jun                (mode == IDisplayDevice::DEVICE_DISPLAY_ON) ? DRM_MODE_DPMS_ON :
5426c061a816e1bb454afc8d294231bc235a771d646Nie Jun                        IDisplayDevice::DEVICE_DISPLAY_STANDBY == mode ?
5436c061a816e1bb454afc8d294231bc235a771d646Nie Jun                        DRM_MODE_DPMS_STANDBY : DRM_MODE_DPMS_OFF);
54465efc253a628175c7afa95c431b746ea20052794Andy Qiu            drmModeFreeProperty(props);
54565efc253a628175c7afa95c431b746ea20052794Andy Qiu            if (ret != 0) {
5464157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                ELOGTRACE("unable to set DPMS %d", mode);
54765efc253a628175c7afa95c431b746ea20052794Andy Qiu                return false;
54865efc253a628175c7afa95c431b746ea20052794Andy Qiu            } else {
54965efc253a628175c7afa95c431b746ea20052794Andy Qiu                return true;
55065efc253a628175c7afa95c431b746ea20052794Andy Qiu            }
55165efc253a628175c7afa95c431b746ea20052794Andy Qiu        }
55265efc253a628175c7afa95c431b746ea20052794Andy Qiu        drmModeFreeProperty(props);
55365efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
55465efc253a628175c7afa95c431b746ea20052794Andy Qiu    return false;
55565efc253a628175c7afa95c431b746ea20052794Andy Qiu}
55665efc253a628175c7afa95c431b746ea20052794Andy Qiu
55730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiuvoid Drm::resetOutput(int index)
55830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu{
55930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    DrmOutput *output = &mOutputs[index];
56030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
56130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    output->connected = false;
56230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    memset(&output->mode, 0, sizeof(drmModeModeInfo));
56330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
56430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->connector) {
56530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        drmModeFreeConnector(output->connector);
56630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        output->connector = 0;
56730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
56830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->encoder) {
56930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        drmModeFreeEncoder(output->encoder);
57030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        output->encoder = 0;
57130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
57230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->crtc) {
57330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        drmModeFreeCrtc(output->crtc);
57430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        output->crtc = 0;
57530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
57630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->fbId) {
57730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        drmModeRmFB(mDrmFd, output->fbId);
57830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        output->fbId = 0;
57930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
58030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->fbHandle) {
58130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer(output->fbHandle);
58230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        output->fbHandle = 0;
58330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
58430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu}
58530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
58630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::initDrmMode(int outputIndex)
58730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu{
58830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    DrmOutput *output= &mOutputs[outputIndex];
58930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->connector->count_modes <= 0) {
5904157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid count of modes");
59130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
59230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
59330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
59430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    drmModeModeInfoPtr mode;
59530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    int index = 0;
59630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    for (int i = 0; i < output->connector->count_modes; i++) {
59730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        mode = &output->connector->modes[i];
59830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        if (mode->type & DRM_MODE_TYPE_PREFERRED) {
59930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            index = i;
60030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu            break;
60130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        }
60230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
60330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
60430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    return setDrmMode(outputIndex, &output->connector->modes[index]);
60530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu}
60630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
60730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::setDrmMode(int index, drmModeModeInfoPtr mode)
60830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu{
60930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    DrmOutput *output = &mOutputs[index];
61030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
6112fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang    int oldFbId =0;
6122fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang    int oldFbHandle = 0;
6132fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang
61412eefae3196eaadfcef7a543878fe816c4329a49Lin Xie    drmModeModeInfo currentMode;
61512eefae3196eaadfcef7a543878fe816c4329a49Lin Xie    memcpy(&currentMode, &output->mode, sizeof(drmModeModeInfo));
6162fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang
61712eefae3196eaadfcef7a543878fe816c4329a49Lin Xie    if (isSameDrmMode(mode, &currentMode))
61812eefae3196eaadfcef7a543878fe816c4329a49Lin Xie        return true;
61912eefae3196eaadfcef7a543878fe816c4329a49Lin Xie
6202fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang
62130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->fbId) {
6222fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang        oldFbId = output->fbId ;
62330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        output->fbId = 0;
62430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
62530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
62630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->fbHandle) {
6272fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang        oldFbHandle = output->fbHandle;
62830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        output->fbHandle = 0;
62930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
63030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
63130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    // allocate frame buffer
63230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    int stride = 0;
63395dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#ifdef INTEL_SUPPORT_HDMI_PRIMARY
63495dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang    output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer(
63595dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang        DEFAULT_DRM_FB_WIDTH, DEFAULT_DRM_FB_HEIGHT, &stride);
63695dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#else
63730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer(
63830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        mode->hdisplay, mode->vdisplay, &stride);
63995dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#endif
64030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (output->fbHandle == 0) {
6414157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("failed to allocate frame buffer");
64230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu        return false;
64330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
64430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
645eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    int ret = 0;
646eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    ret = drmModeAddFB(
647eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mDrmFd,
64895dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#ifdef INTEL_SUPPORT_HDMI_PRIMARY
64995dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang        DEFAULT_DRM_FB_WIDTH,
65095dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang        DEFAULT_DRM_FB_HEIGHT,
65195dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#else
652eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mode->hdisplay,
653eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mode->vdisplay,
65495dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#endif
655eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        DrmConfig::getFrameBufferDepth(),
656eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        DrmConfig::getFrameBufferBpp(),
657eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        stride,
658eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        output->fbHandle,
659eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        &output->fbId);
660eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (ret != 0) {
6614157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("drmModeAddFB failed, error: %d", ret);
662eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return false;
663eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
664eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
6654157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev    ILOGTRACE("mode set: %dx%d@%dHz", mode->hdisplay, mode->vdisplay, mode->vrefresh);
6663f1974031c88750a14adc8f2f49538837238abf9Lin Xie
667eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    ret = drmModeSetCrtc(mDrmFd, output->crtc->crtc_id, output->fbId, 0, 0,
668eb726af21649d79ed720bdf329e0849270995c45Andy Qiu                   &output->connector->connector_id, 1, mode);
66930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    if (ret == 0) {
670eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        //save mode
671eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        memcpy(&output->mode, mode, sizeof(drmModeModeInfo));
67230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    } else {
6734157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("drmModeSetCrtc failed. error: %d", ret);
67430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    }
67530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
6762fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang    if (oldFbId) {
6772fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang        drmModeRmFB(mDrmFd, oldFbId);
6782fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang    }
6792fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang
6802fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang    if (oldFbHandle) {
6812fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang        Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer(oldFbHandle);
6822fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang    }
6832fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang
68430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu    return ret == 0;
68530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu}
68630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu
68765efc253a628175c7afa95c431b746ea20052794Andy Qiuint Drm::getOutputIndex(int device)
68865efc253a628175c7afa95c431b746ea20052794Andy Qiu{
68965efc253a628175c7afa95c431b746ea20052794Andy Qiu    switch (device) {
69065efc253a628175c7afa95c431b746ea20052794Andy Qiu    case IDisplayDevice::DEVICE_PRIMARY:
69165efc253a628175c7afa95c431b746ea20052794Andy Qiu        return OUTPUT_PRIMARY;
69265efc253a628175c7afa95c431b746ea20052794Andy Qiu    case IDisplayDevice::DEVICE_EXTERNAL:
69365efc253a628175c7afa95c431b746ea20052794Andy Qiu        return OUTPUT_EXTERNAL;
69465efc253a628175c7afa95c431b746ea20052794Andy Qiu    default:
6954157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid display device");
69665efc253a628175c7afa95c431b746ea20052794Andy Qiu        break;
69765efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
69865efc253a628175c7afa95c431b746ea20052794Andy Qiu
69965efc253a628175c7afa95c431b746ea20052794Andy Qiu    return -1;
70065efc253a628175c7afa95c431b746ea20052794Andy Qiu}
70165efc253a628175c7afa95c431b746ea20052794Andy Qiu
702ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanleyint Drm::getPanelOrientation(int device)
703ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley{
704ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley    int outputIndex = getOutputIndex(device);
705ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley    if (outputIndex < 0) {
7064157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid device");
707ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley        return PANEL_ORIENTATION_0;
708ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley    }
709ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley
710ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley    DrmOutput *output= &mOutputs[outputIndex];
711ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley    if (output->connected == false) {
7124157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("device is not connected");
713ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley        return PANEL_ORIENTATION_0;
714ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley    }
715ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley
716ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley    return output->panelOrientation;
717ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley}
718ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley
719452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish// HWC 1.4 requires that we return all of the compatible configs in getDisplayConfigs
720452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish// this is needed so getActiveConfig/setActiveConfig work correctly.  It is up to the
721452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish// user space to decide what speed to send.
722452fbc109a9c585737bcac18f19aff40574c3d79Jim BishdrmModeModeInfoPtr Drm::detectAllConfigs(int device, int *modeCount)
723452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish{
724452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    RETURN_NULL_IF_NOT_INIT();
725452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    Mutex::Autolock _l(mLock);
726452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish
727452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    if (modeCount != NULL)
728452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish        *modeCount = 0;
729452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    else
730452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish        return NULL;
731452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish
732452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    int outputIndex = getOutputIndex(device);
733452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    if (outputIndex < 0) {
7344157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid device");
735452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish        return NULL;
736452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    }
737452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish
738452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    DrmOutput *output= &mOutputs[outputIndex];
739452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    if (!output->connected) {
7404157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("device is not connected");
741452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish        return NULL;
742452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    }
743452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish
744452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    if (output->connector->count_modes <= 0) {
7454157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("invalid count of modes");
746452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish        return NULL;
747452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    }
748452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish
749452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    *modeCount = output->connector->count_modes;
750452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish    return output->connector->modes;
751452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish}
75265efc253a628175c7afa95c431b746ea20052794Andy Qiu
7536a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} // namespace intel
7546a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} // namespace android
7556a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
756