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(¤tMode, &output->mode, sizeof(drmModeModeInfo)); 6162fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang 61712eefae3196eaadfcef7a543878fe816c4329a49Lin Xie if (isSameDrmMode(mode, ¤tMode)) 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