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)); 20297ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu //output->fbId = output->crtc->buffer_id; 20330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu ret = true; 20430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } else { 2057b871c6aa5fae82dfe062e3de5822d0b7ccb76bbAndy Qiu ELOGTRACE("mode is invalid. Kernel mode setting is not completed"); 2067b871c6aa5fae82dfe062e3de5822d0b7ccb76bbAndy Qiu ret = false; 2076a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 208ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley 209ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley if (outputIndex == OUTPUT_PRIMARY) { 210ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley if (!readIoctl(DRM_PSB_PANEL_ORIENTATION, &output->panelOrientation, sizeof(int))) { 2114157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("failed to get device %d orientation", device); 212ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley output->panelOrientation = PANEL_ORIENTATION_0; 213ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley } 214ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley } else { 215ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley output->panelOrientation = PANEL_ORIENTATION_0; 216ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley } 21730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu break; 21830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 2196a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 22030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (!ret) { 221486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu if (output->connector == NULL && outputIndex != OUTPUT_PRIMARY) { 222486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu // a fatal failure on primary device 223486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu // non fatal on secondary device 2244157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev WLOGTRACE("device %d is disabled?", device); 225486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu ret = true; 226486ba9a29ca00369f7f160701f3395f10e611d98Andy Qiu } 22730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu resetOutput(outputIndex); 22830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } else if (output->connected) { 2294157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ILOGTRACE("mode is: %dx%d@%dHz", output->mode.hdisplay, output->mode.vdisplay, output->mode.vrefresh); 23030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 2316a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 23230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu drmModeFreeResources(resources); 23330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return ret; 23430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu} 2356a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 23612eefae3196eaadfcef7a543878fe816c4329a49Lin Xiebool Drm::isSameDrmMode(drmModeModeInfoPtr value, 23712eefae3196eaadfcef7a543878fe816c4329a49Lin Xie drmModeModeInfoPtr base) const 23812eefae3196eaadfcef7a543878fe816c4329a49Lin Xie{ 23912eefae3196eaadfcef7a543878fe816c4329a49Lin Xie if (base->hdisplay == value->hdisplay && 24012eefae3196eaadfcef7a543878fe816c4329a49Lin Xie base->vdisplay == value->vdisplay && 24112eefae3196eaadfcef7a543878fe816c4329a49Lin Xie base->vrefresh == value->vrefresh && 24212eefae3196eaadfcef7a543878fe816c4329a49Lin Xie (base->flags & value->flags) == value->flags) { 2434157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev VLOGTRACE("Drm mode is not changed"); 24412eefae3196eaadfcef7a543878fe816c4329a49Lin Xie return true; 24512eefae3196eaadfcef7a543878fe816c4329a49Lin Xie } 24612eefae3196eaadfcef7a543878fe816c4329a49Lin Xie 24712eefae3196eaadfcef7a543878fe816c4329a49Lin Xie return false; 24812eefae3196eaadfcef7a543878fe816c4329a49Lin Xie} 24912eefae3196eaadfcef7a543878fe816c4329a49Lin Xie 2503f1974031c88750a14adc8f2f49538837238abf9Lin Xiebool Drm::setDrmMode(int device, drmModeModeInfo& value) 25130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu{ 25230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu RETURN_FALSE_IF_NOT_INIT(); 25330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu Mutex::Autolock _l(mLock); 2546a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 25530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (device != IDisplayDevice::DEVICE_EXTERNAL) { 2564157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev WLOGTRACE("Setting mode on invalid device %d", device); 25730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 25830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 2596a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 26030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu int outputIndex = getOutputIndex(device); 26130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (outputIndex < 0 ) { 2624157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid device"); 26330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 26430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 2656a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 26630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu DrmOutput *output= &mOutputs[outputIndex]; 26730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (!output->connected) { 2684157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("device is not connected"); 26930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 2706a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 2716a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 27230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->connector->count_modes <= 0) { 2734157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid count of modes"); 27430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 27530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 2766a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 27730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu drmModeModeInfoPtr mode; 27830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu int index = 0; 27930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu for (int i = 0; i < output->connector->count_modes; i++) { 28030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu mode = &output->connector->modes[i]; 28130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (mode->type & DRM_MODE_TYPE_PREFERRED) { 28230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu index = i; 28330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 28412eefae3196eaadfcef7a543878fe816c4329a49Lin Xie if (isSameDrmMode(&value, mode)) { 28530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu index = i; 28630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu break; 28730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 28830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 28930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 29030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu mode = &output->connector->modes[index]; 29130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return setDrmMode(outputIndex, mode); 2926a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} 2936a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 294b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xiebool Drm::setRefreshRate(int device, int hz) 295b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie{ 296b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie RETURN_FALSE_IF_NOT_INIT(); 297b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie Mutex::Autolock _l(mLock); 298b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie 299b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie if (device != IDisplayDevice::DEVICE_EXTERNAL) { 3004157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev WLOGTRACE("Setting mode on invalid device %d", device); 301b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie return false; 302b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie } 303b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie 304b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie int outputIndex = getOutputIndex(device); 305b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie if (outputIndex < 0 ) { 3064157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid device"); 307b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie return false; 308b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie } 309b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie 310b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie DrmOutput *output= &mOutputs[outputIndex]; 311b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie if (!output->connected) { 3124157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("device is not connected"); 313b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie return false; 314b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie } 315b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie 316b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie if (output->connector->count_modes <= 0) { 3174157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid count of modes"); 318b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie return false; 319b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie } 320b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie 321b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie drmModeModeInfoPtr mode; 322b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie int index = 0; 323b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie for (int i = 0; i < output->connector->count_modes; i++) { 324b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie mode = &output->connector->modes[i]; 325b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie if (mode->type & DRM_MODE_TYPE_PREFERRED) { 326b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie index = i; 327b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie } 328b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie if (mode->hdisplay == output->mode.hdisplay && 329b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie mode->vdisplay == output->mode.vdisplay && 330b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie mode->vrefresh == (uint32_t)hz) { 331b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie index = i; 332b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie break; 333b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie } 334b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie } 335b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie 336b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie mode = &output->connector->modes[index]; 337b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie return setDrmMode(outputIndex, mode); 338b58f29390918c0df3bd6d0731bf98daf57511b9fLin Xie} 33930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 3406a6081a46a83da606cf21548879b37695adc7e1fAndy Qiubool Drm::writeReadIoctl(unsigned long cmd, void *data, 3416a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu unsigned long size) 3426a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{ 3436a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu int err; 3446a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3456a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu if (mDrmFd <= 0) { 3464157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("drm is not initialized"); 3476a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return false; 3486a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 3496a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3506a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu if (!data || !size) { 3514157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid parameters"); 3526a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return false; 3536a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 3546a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3556a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu err = drmCommandWriteRead(mDrmFd, cmd, data, size); 3566a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu if (err) { 3574157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err); 3586a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return false; 3596a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 3606a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3616a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return true; 3626a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} 3636a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3646a6081a46a83da606cf21548879b37695adc7e1fAndy Qiubool Drm::writeIoctl(unsigned long cmd, void *data, 3656a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu unsigned long size) 3666a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{ 3676a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu int err; 3686a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3696a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu if (mDrmFd <= 0) { 3704157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("drm is not initialized"); 3716a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return false; 3726a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 3736a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3746a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu if (!data || !size) { 3754157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid parameters"); 3766a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return false; 3776a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 3786a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3796a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu err = drmCommandWrite(mDrmFd, cmd, data, size); 3806a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu if (err) { 3814157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err); 3826a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return false; 3836a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 3846a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 3856a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return true; 3866a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} 3876a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 388466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu 389466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hubool Drm::readIoctl(unsigned long cmd, void *data, 390466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu unsigned long size) 391466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu{ 392466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu int err; 393466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu 394466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu if (mDrmFd <= 0) { 3954157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("drm is not initialized"); 396466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu return false; 397466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu } 398466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu 399466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu if (!data || !size) { 4004157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid parameters"); 401466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu return false; 402466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu } 403466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu 404466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu err = drmCommandRead(mDrmFd, cmd, data, size); 405466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu if (err) { 4064157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err); 407466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu return false; 408466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu } 409466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu 410466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu return true; 411466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu} 412466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu 413466748a6f67ce4d1ad8baa944e68a88cf3c86d26Austin Hu 4146a6081a46a83da606cf21548879b37695adc7e1fAndy Qiuint Drm::getDrmFd() const 4156a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{ 4166a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return mDrmFd; 4176a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} 4186a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 41930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::getModeInfo(int device, drmModeModeInfo& mode) 4204a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li{ 42130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu Mutex::Autolock _l(mLock); 42230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 42330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu int outputIndex = getOutputIndex(device); 42430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (outputIndex < 0 ) { 42530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 4264a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li } 4274a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li 42830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu DrmOutput *output= &mOutputs[outputIndex]; 42930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->connected == false) { 4304157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("device is not connected"); 43130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 4324a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li } 4334a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li 43430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->mode.hdisplay == 0 || output->mode.vdisplay == 0) { 4354157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid width or height"); 43630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 4374a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li } 4384a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li 43930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu memcpy(&mode, &output->mode, sizeof(drmModeModeInfo)); 44095dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang 44195dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#ifdef INTEL_SUPPORT_HDMI_PRIMARY 44295dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang // FIXME: use default fb size instead of hdmi mode, because to 44395dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang // support hdmi primary, we cannot report dynamic mode to SF. 44495dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang mode.hdisplay = DEFAULT_DRM_FB_WIDTH; 44595dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang mode.vdisplay = DEFAULT_DRM_FB_HEIGHT; 44695dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#endif 44795dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang 44830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return true; 4494a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li} 4504a17bd5f8632806430043ab67e10c54a1406a7a2Jackie Li 45130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::getPhysicalSize(int device, uint32_t& width, uint32_t& height) 4526a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{ 4536a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu Mutex::Autolock _l(mLock); 4546a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 45530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu int outputIndex = getOutputIndex(device); 45630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (outputIndex < 0 ) { 45730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 45830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 45930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 46030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu DrmOutput *output= &mOutputs[outputIndex]; 46130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->connected == false) { 4624157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("device is not connected"); 46330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 4646a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 4656a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 46630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu width = output->connector->mmWidth; 46730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu height = output->connector->mmHeight; 46830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return true; 4696a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} 4706a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 471af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiubool Drm::getDisplayResolution(int device, uint32_t& width, uint32_t& height) 472af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu{ 473af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu Mutex::Autolock _l(mLock); 474af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu 475af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu int outputIndex = getOutputIndex(device); 476af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu if (outputIndex < 0) { 477af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu return false; 478af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu } 479af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu 480af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu DrmOutput *output= &mOutputs[outputIndex]; 481af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu if (output->connected == false) { 482af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu ELOGTRACE("device is not connected"); 483af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu return false; 484af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu } 485af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu 486af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu width = output->mode.hdisplay; 487af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu height = output->mode.vdisplay; 488af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu 489af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu if (!width || !height) { 490af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu ELOGTRACE("invalid width or height"); 491af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu return false; 492af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu } 493af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu return true; 494af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu} 495af3bf2227c951a59e2dcc44ab90790d247225375Andy Qiu 49630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::isConnected(int device) 4976a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{ 4986a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu Mutex::Autolock _l(mLock); 4996a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 50065efc253a628175c7afa95c431b746ea20052794Andy Qiu int output = getOutputIndex(device); 50165efc253a628175c7afa95c431b746ea20052794Andy Qiu if (output < 0 ) { 5026a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu return false; 5036a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu } 5046a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 50530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return mOutputs[output].connected; 5066a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} 5076a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 50865efc253a628175c7afa95c431b746ea20052794Andy Qiubool Drm::setDpmsMode(int device, int mode) 50965efc253a628175c7afa95c431b746ea20052794Andy Qiu{ 51065efc253a628175c7afa95c431b746ea20052794Andy Qiu Mutex::Autolock _l(mLock); 51165efc253a628175c7afa95c431b746ea20052794Andy Qiu 512ddb9b7fce03c36a660cd633b19191d9ce23c023bAustin Hu#ifdef INTEL_SUPPORT_HDMI_PRIMARY 513ddb9b7fce03c36a660cd633b19191d9ce23c023bAustin Hu device = IDisplayDevice::DEVICE_EXTERNAL; 514ddb9b7fce03c36a660cd633b19191d9ce23c023bAustin Hu#endif 515ddb9b7fce03c36a660cd633b19191d9ce23c023bAustin Hu 51665efc253a628175c7afa95c431b746ea20052794Andy Qiu int output = getOutputIndex(device); 51765efc253a628175c7afa95c431b746ea20052794Andy Qiu if (output < 0 ) { 51865efc253a628175c7afa95c431b746ea20052794Andy Qiu return false; 51965efc253a628175c7afa95c431b746ea20052794Andy Qiu } 52065efc253a628175c7afa95c431b746ea20052794Andy Qiu 52165efc253a628175c7afa95c431b746ea20052794Andy Qiu if (mode != IDisplayDevice::DEVICE_DISPLAY_OFF && 5226c061a816e1bb454afc8d294231bc235a771d646Nie Jun mode != IDisplayDevice::DEVICE_DISPLAY_STANDBY && 5236c061a816e1bb454afc8d294231bc235a771d646Nie Jun mode != IDisplayDevice::DEVICE_DISPLAY_ON) { 5244157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid mode %d", mode); 52565efc253a628175c7afa95c431b746ea20052794Andy Qiu return false; 52665efc253a628175c7afa95c431b746ea20052794Andy Qiu } 52765efc253a628175c7afa95c431b746ea20052794Andy Qiu 52830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu DrmOutput *out = &mOutputs[output]; 52930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (!out->connected) { 5304157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("device is not connected"); 53165efc253a628175c7afa95c431b746ea20052794Andy Qiu return false; 53265efc253a628175c7afa95c431b746ea20052794Andy Qiu } 53365efc253a628175c7afa95c431b746ea20052794Andy Qiu 53465efc253a628175c7afa95c431b746ea20052794Andy Qiu drmModePropertyPtr props; 53565efc253a628175c7afa95c431b746ea20052794Andy Qiu for (int i = 0; i < out->connector->count_props; i++) { 53665efc253a628175c7afa95c431b746ea20052794Andy Qiu props = drmModeGetProperty(mDrmFd, out->connector->props[i]); 53765efc253a628175c7afa95c431b746ea20052794Andy Qiu if (!props) { 53865efc253a628175c7afa95c431b746ea20052794Andy Qiu continue; 53965efc253a628175c7afa95c431b746ea20052794Andy Qiu } 54065efc253a628175c7afa95c431b746ea20052794Andy Qiu 54165efc253a628175c7afa95c431b746ea20052794Andy Qiu if (strcmp(props->name, "DPMS") == 0) { 54265efc253a628175c7afa95c431b746ea20052794Andy Qiu int ret = drmModeConnectorSetProperty( 54365efc253a628175c7afa95c431b746ea20052794Andy Qiu mDrmFd, 54465efc253a628175c7afa95c431b746ea20052794Andy Qiu out->connector->connector_id, 54565efc253a628175c7afa95c431b746ea20052794Andy Qiu props->prop_id, 5466c061a816e1bb454afc8d294231bc235a771d646Nie Jun (mode == IDisplayDevice::DEVICE_DISPLAY_ON) ? DRM_MODE_DPMS_ON : 5476c061a816e1bb454afc8d294231bc235a771d646Nie Jun IDisplayDevice::DEVICE_DISPLAY_STANDBY == mode ? 5486c061a816e1bb454afc8d294231bc235a771d646Nie Jun DRM_MODE_DPMS_STANDBY : DRM_MODE_DPMS_OFF); 54965efc253a628175c7afa95c431b746ea20052794Andy Qiu drmModeFreeProperty(props); 55065efc253a628175c7afa95c431b746ea20052794Andy Qiu if (ret != 0) { 5514157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("unable to set DPMS %d", mode); 55265efc253a628175c7afa95c431b746ea20052794Andy Qiu return false; 55365efc253a628175c7afa95c431b746ea20052794Andy Qiu } else { 55465efc253a628175c7afa95c431b746ea20052794Andy Qiu return true; 55565efc253a628175c7afa95c431b746ea20052794Andy Qiu } 55665efc253a628175c7afa95c431b746ea20052794Andy Qiu } 55765efc253a628175c7afa95c431b746ea20052794Andy Qiu drmModeFreeProperty(props); 55865efc253a628175c7afa95c431b746ea20052794Andy Qiu } 55965efc253a628175c7afa95c431b746ea20052794Andy Qiu return false; 56065efc253a628175c7afa95c431b746ea20052794Andy Qiu} 56165efc253a628175c7afa95c431b746ea20052794Andy Qiu 56230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiuvoid Drm::resetOutput(int index) 56330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu{ 56430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu DrmOutput *output = &mOutputs[index]; 56530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 56630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu output->connected = false; 56730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu memset(&output->mode, 0, sizeof(drmModeModeInfo)); 56830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 56930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->connector) { 57030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu drmModeFreeConnector(output->connector); 57130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu output->connector = 0; 57230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 57330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->encoder) { 57430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu drmModeFreeEncoder(output->encoder); 57530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu output->encoder = 0; 57630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 57730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->crtc) { 57830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu drmModeFreeCrtc(output->crtc); 57930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu output->crtc = 0; 58030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 58130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->fbId) { 58230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu drmModeRmFB(mDrmFd, output->fbId); 58330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu output->fbId = 0; 58430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 58530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->fbHandle) { 58630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer(output->fbHandle); 58730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu output->fbHandle = 0; 58830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 58930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu} 59030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 59130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::initDrmMode(int outputIndex) 59230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu{ 59330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu DrmOutput *output= &mOutputs[outputIndex]; 59430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (output->connector->count_modes <= 0) { 5954157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid count of modes"); 59630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return false; 59730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 59830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 59930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu drmModeModeInfoPtr mode; 60030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu int index = 0; 60130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu for (int i = 0; i < output->connector->count_modes; i++) { 60230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu mode = &output->connector->modes[i]; 60330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (mode->type & DRM_MODE_TYPE_PREFERRED) { 60430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu index = i; 60530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu break; 60630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 60730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 60830c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 60930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return setDrmMode(outputIndex, &output->connector->modes[index]); 61030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu} 61130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 61230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiubool Drm::setDrmMode(int index, drmModeModeInfoPtr mode) 61330c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu{ 61430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu DrmOutput *output = &mOutputs[index]; 61530c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 61697ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu int oldFbId = 0; 6172fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang int oldFbHandle = 0; 61897ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu // reuse current frame buffer if there is no resolution change 61997ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu int fbId = -1; 6202fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang 62112eefae3196eaadfcef7a543878fe816c4329a49Lin Xie drmModeModeInfo currentMode; 62212eefae3196eaadfcef7a543878fe816c4329a49Lin Xie memcpy(¤tMode, &output->mode, sizeof(drmModeModeInfo)); 6232fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang 62412eefae3196eaadfcef7a543878fe816c4329a49Lin Xie if (isSameDrmMode(mode, ¤tMode)) 62512eefae3196eaadfcef7a543878fe816c4329a49Lin Xie return true; 62612eefae3196eaadfcef7a543878fe816c4329a49Lin Xie 62797ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu if (currentMode.hdisplay != mode->hdisplay || 62897ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu currentMode.vdisplay != mode->vdisplay) { 6292fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang 63097ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu oldFbId = output->fbId; 6312fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang oldFbHandle = output->fbHandle; 63230c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 63397ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu // allocate frame buffer 63497ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu int stride = 0; 63595dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#ifdef INTEL_SUPPORT_HDMI_PRIMARY 63697ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer( 63797ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu DEFAULT_DRM_FB_WIDTH, DEFAULT_DRM_FB_HEIGHT, &stride); 63895dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#else 63997ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer( 64097ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu mode->hdisplay, mode->vdisplay, &stride); 64195dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#endif 64297ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu if (output->fbHandle == 0) { 64397ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu ELOGTRACE("failed to allocate frame buffer"); 64497ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu return false; 64597ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu } 64630c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 64797ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu int ret = 0; 64897ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu ret = drmModeAddFB( 64997ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu mDrmFd, 65095dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#ifdef INTEL_SUPPORT_HDMI_PRIMARY 65197ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu DEFAULT_DRM_FB_WIDTH, 65297ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu DEFAULT_DRM_FB_HEIGHT, 65395dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#else 65497ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu mode->hdisplay, 65597ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu mode->vdisplay, 65695dd47c04c25844c759e84a1473bf9f14c2bcb7bLei Zhang#endif 65797ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu DrmConfig::getFrameBufferDepth(), 65897ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu DrmConfig::getFrameBufferBpp(), 65997ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu stride, 66097ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu output->fbHandle, 66197ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu &output->fbId); 66297ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu if (ret != 0) { 66397ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu ELOGTRACE("drmModeAddFB failed, error: %d", ret); 66497ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu return false; 66597ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu } 66697ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu fbId = output->fbId; 667eb726af21649d79ed720bdf329e0849270995c45Andy Qiu } 668eb726af21649d79ed720bdf329e0849270995c45Andy Qiu 6694157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ILOGTRACE("mode set: %dx%d@%dHz", mode->hdisplay, mode->vdisplay, mode->vrefresh); 6703f1974031c88750a14adc8f2f49538837238abf9Lin Xie 67197ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu int ret = drmModeSetCrtc(mDrmFd, output->crtc->crtc_id, fbId, 0, 0, 672eb726af21649d79ed720bdf329e0849270995c45Andy Qiu &output->connector->connector_id, 1, mode); 67397ca3dba1b7c7fc5f35961ff6e6a14ef3843aa86Andy Qiu 67430c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu if (ret == 0) { 675eb726af21649d79ed720bdf329e0849270995c45Andy Qiu //save mode 676eb726af21649d79ed720bdf329e0849270995c45Andy Qiu memcpy(&output->mode, mode, sizeof(drmModeModeInfo)); 67730c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } else { 6784157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("drmModeSetCrtc failed. error: %d", ret); 67930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu } 68030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 6812fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang if (oldFbId) { 6822fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang drmModeRmFB(mDrmFd, oldFbId); 6832fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang } 6842fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang 6852fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang if (oldFbHandle) { 6862fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer(oldFbHandle); 6872fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang } 6882fb3ffb8c3d9f7ef6bcc11c69339eba9609d406fShi Yang 68930c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu return ret == 0; 69030c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu} 69130c19aca49c615368ae3bce961c431fa901e90b9Andy Qiu 69265efc253a628175c7afa95c431b746ea20052794Andy Qiuint Drm::getOutputIndex(int device) 69365efc253a628175c7afa95c431b746ea20052794Andy Qiu{ 69465efc253a628175c7afa95c431b746ea20052794Andy Qiu switch (device) { 69565efc253a628175c7afa95c431b746ea20052794Andy Qiu case IDisplayDevice::DEVICE_PRIMARY: 69665efc253a628175c7afa95c431b746ea20052794Andy Qiu return OUTPUT_PRIMARY; 69765efc253a628175c7afa95c431b746ea20052794Andy Qiu case IDisplayDevice::DEVICE_EXTERNAL: 69865efc253a628175c7afa95c431b746ea20052794Andy Qiu return OUTPUT_EXTERNAL; 69965efc253a628175c7afa95c431b746ea20052794Andy Qiu default: 7004157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid display device"); 70165efc253a628175c7afa95c431b746ea20052794Andy Qiu break; 70265efc253a628175c7afa95c431b746ea20052794Andy Qiu } 70365efc253a628175c7afa95c431b746ea20052794Andy Qiu 70465efc253a628175c7afa95c431b746ea20052794Andy Qiu return -1; 70565efc253a628175c7afa95c431b746ea20052794Andy Qiu} 70665efc253a628175c7afa95c431b746ea20052794Andy Qiu 707ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanleyint Drm::getPanelOrientation(int device) 708ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley{ 709ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley int outputIndex = getOutputIndex(device); 710ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley if (outputIndex < 0) { 7114157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid device"); 712ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley return PANEL_ORIENTATION_0; 713ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley } 714ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley 715ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley DrmOutput *output= &mOutputs[outputIndex]; 716ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley if (output->connected == false) { 7174157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("device is not connected"); 718ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley return PANEL_ORIENTATION_0; 719ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley } 720ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley 721ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley return output->panelOrientation; 722ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley} 723ab302a7c5992e3668443dc9bdac481c108c20a34Lee, Stanley 724452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish// HWC 1.4 requires that we return all of the compatible configs in getDisplayConfigs 725452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish// this is needed so getActiveConfig/setActiveConfig work correctly. It is up to the 726452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish// user space to decide what speed to send. 727452fbc109a9c585737bcac18f19aff40574c3d79Jim BishdrmModeModeInfoPtr Drm::detectAllConfigs(int device, int *modeCount) 728452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish{ 729452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish RETURN_NULL_IF_NOT_INIT(); 730452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish Mutex::Autolock _l(mLock); 731452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish 732452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish if (modeCount != NULL) 733452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish *modeCount = 0; 734452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish else 735452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish return NULL; 736452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish 737452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish int outputIndex = getOutputIndex(device); 738452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish if (outputIndex < 0) { 7394157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid device"); 740452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish return NULL; 741452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish } 742452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish 743452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish DrmOutput *output= &mOutputs[outputIndex]; 744452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish if (!output->connected) { 7454157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("device is not connected"); 746452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish return NULL; 747452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish } 748452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish 749452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish if (output->connector->count_modes <= 0) { 7504157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev ELOGTRACE("invalid count of modes"); 751452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish return NULL; 752452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish } 753452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish 754452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish *modeCount = output->connector->count_modes; 755452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish return output->connector->modes; 756452fbc109a9c585737bcac18f19aff40574c3d79Jim Bish} 75765efc253a628175c7afa95c431b746ea20052794Andy Qiu 7586a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} // namespace intel 7596a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} // namespace android 7606a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu 761