18b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol/* 28b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Copyright (c) 2014 Intel Corporation 38b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// 48b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Licensed under the Apache License, Version 2.0 (the "License"); 58b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// you may not use this file except in compliance with the License. 68b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// You may obtain a copy of the License at 78b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// 88b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// http://www.apache.org/licenses/LICENSE-2.0 98b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// 108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Unless required by applicable law or agreed to in writing, software 118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// distributed under the License is distributed on an "AS IS" BASIS, 128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// See the License for the specific language governing permissions and 148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// limitations under the License. 158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol*/ 168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <fcntl.h> 178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <errno.h> 188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <HwcTrace.h> 198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <IDisplayDevice.h> 208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <DrmConfig.h> 218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <Drm.h> 228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <Hwcomposer.h> 238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace android { 258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace intel { 268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolDrm::Drm() 288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol : mDrmFd(0), 298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mLock(), 308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mInitialized(false) 318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol memset(&mOutputs, 0, sizeof(mOutputs)); 338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolDrm::~Drm() 368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WARN_IF_NOT_DEINIT(); 388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::initialize() 418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mInitialized) { 438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("Drm object has been initialized"); 448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol const char *path = DrmConfig::getDrmPath(); 488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mDrmFd = open(path, O_RDWR, 0); 498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mDrmFd < 0) { 508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to open Drm, error: %s", strerror(errno)); 518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DTRACE("mDrmFd = %d", mDrmFd); 548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol memset(&mOutputs, 0, sizeof(mOutputs)); 568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mInitialized = true; 578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid Drm::deinitialize() 618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol for (int i = 0; i < OUTPUT_MAX; i++) { 638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol resetOutput(i); 648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mDrmFd) { 678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol close(mDrmFd); 688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mDrmFd = 0; 698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mInitialized = false; 718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::detect(int device) 748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol RETURN_FALSE_IF_NOT_INIT(); 768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock _l(mLock); 788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int outputIndex = getOutputIndex(device); 798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (outputIndex < 0 ) { 808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol resetOutput(outputIndex); 848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // get drm resources 868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeResPtr resources = drmModeGetResources(mDrmFd); 878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!resources) { 888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("fail to get drm resources, error: %s", strerror(errno)); 898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeConnectorPtr connector = NULL; 938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output = &mOutputs[outputIndex]; 948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol bool ret = false; 958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // find connector for the given device 978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol for (int i = 0; i < resources->count_connectors; i++) { 988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!resources->connectors || !resources->connectors[i]) { 998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("fail to get drm resources connectors, error: %s", strerror(errno)); 1008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol continue; 1018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol connector = drmModeGetConnector(mDrmFd, resources->connectors[i]); 1048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!connector) { 1058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("drmModeGetConnector failed"); 1068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol continue; 1078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (connector->connector_type != DrmConfig::getDrmConnector(device)) { 1108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeConnector(connector); 1118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol continue; 1128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (connector->connection != DRM_MODE_CONNECTED) { 1158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("device %d is not connected", device); 1168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeConnector(connector); 1178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ret = true; 1188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 1198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->connector = connector; 1228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->connected = true; 1238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // get proper encoder for the given connector 1258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (connector->encoder_id) { 1268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("Drm connector has encoder attached on device %d", device); 1278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->encoder = drmModeGetEncoder(mDrmFd, connector->encoder_id); 1288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->encoder) { 1298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to get encoder from a known encoder id"); 1308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // fall through to get an encoder 1318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->encoder) { 1348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("getting encoder for device %d", device); 1358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeEncoderPtr encoder; 1368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol for (int j = 0; j < resources->count_encoders; j++) { 1378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!resources->encoders || !resources->encoders[j]) { 1388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("fail to get drm resources encoders, error: %s", strerror(errno)); 1398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol continue; 1408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol encoder = drmModeGetEncoder(mDrmFd, resources->encoders[i]); 1438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!encoder) { 1448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("drmModeGetEncoder failed"); 1458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol continue; 1468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (encoder->encoder_type == DrmConfig::getDrmEncoder(device)) { 1488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->encoder = encoder; 1498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 1508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeEncoder(encoder); 1528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol encoder = NULL; 1538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->encoder) { 1568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to get drm encoder"); 1578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 1588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // get an attached crtc or spare crtc 1618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->encoder->crtc_id) { 1628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("Drm encoder has crtc attached on device %d", device); 1638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->crtc = drmModeGetCrtc(mDrmFd, output->encoder->crtc_id); 1648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->crtc) { 1658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to get crtc from a known crtc id"); 1668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // fall through to get a spare crtc 1678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->crtc) { 1708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("getting crtc for device %d", device); 1718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeCrtcPtr crtc; 1728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol for (int j = 0; j < resources->count_crtcs; j++) { 1738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!resources->crtcs || !resources->crtcs[j]) { 1748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("fail to get drm resources crtcs, error: %s", strerror(errno)); 1758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol continue; 1768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol crtc = drmModeGetCrtc(mDrmFd, resources->crtcs[j]); 1798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!crtc) { 1808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("drmModeGetCrtc failed"); 1818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol continue; 1828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (crtc->buffer_id == 0) { 1848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->crtc = crtc; 1858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 1868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeCrtc(crtc); 1888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->crtc) { 1918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to get drm crtc"); 1928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 1938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // current mode 1968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->crtc->mode_valid) { 1978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("mode is valid, kernel mode settings"); 1988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol memcpy(&output->mode, &output->crtc->mode, sizeof(drmModeModeInfo)); 1998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ret = true; 2008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } else { 2018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("mode is invalid, setting preferred mode"); 2028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ret = initDrmMode(outputIndex); 2038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (outputIndex == OUTPUT_PRIMARY) { 2068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!readIoctl(DRM_PSB_PANEL_ORIENTATION, &output->panelOrientation, sizeof(int))) { 2078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to get device %d orientation", device); 2088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->panelOrientation = PANEL_ORIENTATION_0; 2098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } else { 2118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->panelOrientation = PANEL_ORIENTATION_0; 2128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 2148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!ret) { 2178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connector == NULL && outputIndex != OUTPUT_PRIMARY) { 2188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // a fatal failure on primary device 2198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // non fatal on secondary device 2208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("device %d is disabled?", device); 2218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ret = true; 2228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol resetOutput(outputIndex); 2248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } else if (output->connected) { 2258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("mode is: %dx%d@%dHz", output->mode.hdisplay, output->mode.vdisplay, output->mode.vrefresh); 2268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeResources(resources); 2298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return ret; 2308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 2318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::isSameDrmMode(drmModeModeInfoPtr value, 2338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeModeInfoPtr base) const 2348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 2358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (base->hdisplay == value->hdisplay && 2368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol base->vdisplay == value->vdisplay && 2378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol base->vrefresh == value->vrefresh && 2388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol (base->flags & value->flags) == value->flags) { 2398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol VTRACE("Drm mode is not changed"); 2408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 2418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 2448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 2458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::setDrmMode(int device, drmModeModeInfo& value) 2478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 2488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol RETURN_FALSE_IF_NOT_INIT(); 2498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock _l(mLock); 2508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (device != IDisplayDevice::DEVICE_EXTERNAL) { 2528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("Setting mode on invalid device %d", device); 2538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 2548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int outputIndex = getOutputIndex(device); 2578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (outputIndex < 0 ) { 2588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid device"); 2598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 2608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output= &mOutputs[outputIndex]; 2638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->connected) { 2648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("device is not connected"); 2658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 2668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connector->count_modes <= 0) { 2698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid count of modes"); 2708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 2718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeModeInfoPtr mode; 2748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int index = 0; 2758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol for (int i = 0; i < output->connector->count_modes; i++) { 2768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode = &output->connector->modes[i]; 2778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mode->type & DRM_MODE_TYPE_PREFERRED) { 2788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol index = i; 2798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (isSameDrmMode(&value, mode)) { 2818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol index = i; 2828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 2838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode = &output->connector->modes[index]; 2878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return setDrmMode(outputIndex, mode); 2888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 2898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::setRefreshRate(int device, int hz) 2918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 2928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol RETURN_FALSE_IF_NOT_INIT(); 2938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock _l(mLock); 2948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (device != IDisplayDevice::DEVICE_EXTERNAL) { 2968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("Setting mode on invalid device %d", device); 2978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 2988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int outputIndex = getOutputIndex(device); 3018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (outputIndex < 0 ) { 3028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid device"); 3038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output= &mOutputs[outputIndex]; 3078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->connected) { 3088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("device is not connected"); 3098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connector->count_modes <= 0) { 3138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid count of modes"); 3148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeModeInfoPtr mode; 3188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int index = 0; 3198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol for (int i = 0; i < output->connector->count_modes; i++) { 3208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode = &output->connector->modes[i]; 3218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mode->type & DRM_MODE_TYPE_PREFERRED) { 3228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol index = i; 3238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mode->hdisplay == output->mode.hdisplay && 3258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode->vdisplay == output->mode.vdisplay && 3268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode->vrefresh == (uint32_t)hz) { 3278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol index = i; 3288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 3298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode = &output->connector->modes[index]; 3338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return setDrmMode(outputIndex, mode); 3348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 3358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::writeReadIoctl(unsigned long cmd, void *data, 3378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol unsigned long size) 3388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 3398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int err; 3408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mDrmFd <= 0) { 3428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("drm is not initialized"); 3438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!data || !size) { 3478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid parameters"); 3488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol err = drmCommandWriteRead(mDrmFd, cmd, data, size); 3528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (err) { 3538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("failed to call %ld ioctl with failure %d", cmd, err); 3548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 3588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 3598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::writeIoctl(unsigned long cmd, void *data, 3618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol unsigned long size) 3628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 3638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int err; 3648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mDrmFd <= 0) { 3668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("drm is not initialized"); 3678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!data || !size) { 3718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid parameters"); 3728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol err = drmCommandWrite(mDrmFd, cmd, data, size); 3768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (err) { 3778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("failed to call %ld ioctl with failure %d", cmd, err); 3788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 3828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 3838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::readIoctl(unsigned long cmd, void *data, 3868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol unsigned long size) 3878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 3888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int err; 3898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mDrmFd <= 0) { 3918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("drm is not initialized"); 3928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!data || !size) { 3968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid parameters"); 3978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol err = drmCommandRead(mDrmFd, cmd, data, size); 4018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (err) { 4028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("failed to call %ld ioctl with failure %d", cmd, err); 4038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 4078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 4088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolint Drm::getDrmFd() const 4118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 4128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return mDrmFd; 4138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 4148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::getModeInfo(int device, drmModeModeInfo& mode) 4168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 4178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock _l(mLock); 4188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int outputIndex = getOutputIndex(device); 4208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (outputIndex < 0 ) { 4218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output= &mOutputs[outputIndex]; 4258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connected == false) { 4268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("device is not connected"); 4278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->mode.hdisplay == 0 || output->mode.vdisplay == 0) { 4318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid width or height"); 4328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol memcpy(&mode, &output->mode, sizeof(drmModeModeInfo)); 4368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 4378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 4388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::getPhysicalSize(int device, uint32_t& width, uint32_t& height) 4408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 4418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock _l(mLock); 4428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int outputIndex = getOutputIndex(device); 4448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (outputIndex < 0 ) { 4458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output= &mOutputs[outputIndex]; 4498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connected == false) { 4508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("device is not connected"); 4518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol width = output->connector->mmWidth; 4558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol height = output->connector->mmHeight; 4568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 4578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 4588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::isConnected(int device) 4608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 4618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock _l(mLock); 4628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int output = getOutputIndex(device); 4648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output < 0 ) { 4658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return mOutputs[output].connected; 4698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 4708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::setDpmsMode(int device, int mode) 4728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 4738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock _l(mLock); 4748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int output = getOutputIndex(device); 4768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output < 0 ) { 4778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mode != IDisplayDevice::DEVICE_DISPLAY_OFF && 4818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode != IDisplayDevice::DEVICE_DISPLAY_STANDBY && 4828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode != IDisplayDevice::DEVICE_DISPLAY_ON) { 4838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid mode %d", mode); 4848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *out = &mOutputs[output]; 4888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!out->connected) { 4898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("device is not connected"); 4908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 4918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 4938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModePropertyPtr props; 4948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol for (int i = 0; i < out->connector->count_props; i++) { 4958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol props = drmModeGetProperty(mDrmFd, out->connector->props[i]); 4968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!props) { 4978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol continue; 4988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 4998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (strcmp(props->name, "DPMS") == 0) { 5018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int ret = drmModeConnectorSetProperty( 5028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mDrmFd, 5038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol out->connector->connector_id, 5048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol props->prop_id, 5058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol (mode == IDisplayDevice::DEVICE_DISPLAY_ON) ? DRM_MODE_DPMS_ON : 5068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol IDisplayDevice::DEVICE_DISPLAY_STANDBY == mode ? 5078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DRM_MODE_DPMS_STANDBY : DRM_MODE_DPMS_OFF); 5088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeProperty(props); 5098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (ret != 0) { 5108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("unable to set DPMS %d", mode); 5118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 5128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } else { 5138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 5148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeProperty(props); 5178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 5198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 5208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid Drm::resetOutput(int index) 5228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 5238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output = &mOutputs[index]; 5248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->connected = false; 5268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol memset(&output->mode, 0, sizeof(drmModeModeInfo)); 5278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connector) { 5298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeConnector(output->connector); 5308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->connector = 0; 5318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->encoder) { 5338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeEncoder(output->encoder); 5348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->encoder = 0; 5358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->crtc) { 5378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeFreeCrtc(output->crtc); 5388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->crtc = 0; 5398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->fbId) { 5418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeRmFB(mDrmFd, output->fbId); 5428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->fbId = 0; 5438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->fbHandle) { 5458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer( 5468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol (buffer_handle_t)output->fbHandle); 5478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->fbHandle = 0; 5488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 5508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::initDrmMode(int outputIndex) 5528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 5538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output= &mOutputs[outputIndex]; 5548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connector->count_modes <= 0) { 5558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid count of modes"); 5568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 5578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeModeInfoPtr mode; 5608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int index = 0; 5618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol for (int i = 0; i < output->connector->count_modes; i++) { 5628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode = &output->connector->modes[i]; 5638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mode->type & DRM_MODE_TYPE_PREFERRED) { 5648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol index = i; 5658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 5668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return setDrmMode(outputIndex, &output->connector->modes[index]); 5708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 5718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool Drm::setDrmMode(int index, drmModeModeInfoPtr mode) 5738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 5748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output = &mOutputs[index]; 5758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int oldFbId =0; 5778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol buffer_handle_t oldFbHandle = 0; 5788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeModeInfo currentMode; 5808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol memcpy(¤tMode, &output->mode, sizeof(drmModeModeInfo)); 5818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (isSameDrmMode(mode, ¤tMode)) 5838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 5848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->fbId) { 5878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol oldFbId = output->fbId; 5888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->fbId = 0; 5898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->fbHandle) { 5928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol oldFbHandle = output->fbHandle; 5938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->fbHandle = 0; 5948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 5958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 5968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // allocate frame buffer 5978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int stride = 0; 5988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer( 5998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode->hdisplay, mode->vdisplay, &stride); 6008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->fbHandle == 0) { 6018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to allocate frame buffer"); 6028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 6038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 6048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol uint32_t bo_handles[4] = {0}; 6068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol uint32_t pitches[4] = {0}; 6078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol uint32_t offsets[4] = {0}; 6088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int ret = 0; 6098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // We use bo_handles[0] and bo_handles[1] to store buffer_handle_t 6118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // to support 32 and 64 platforms. 6128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol bo_handles[0] = ((unsigned long)(output->fbHandle)) & 0xffffffff; 6138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol bo_handles[1] = ((unsigned long)(output->fbHandle) >> 32) & 0xffffffff; 6148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol pitches[0] = stride * DrmConfig::getFrameBufferBpp() / 8; 6158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ret = drmModeAddFB2( 6178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mDrmFd, 6188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode->hdisplay, 6198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mode->vdisplay, 6208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmConfig::convertHalFormatToDrmFormat(DrmConfig::getFrameBufferFormat()), 6218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol bo_handles, 6228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol pitches, 6238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol offsets, 6248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol &output->fbId, 6258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 0); 6268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (ret != 0) { 6278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("drmModeAddFB2 failed, error: %d", ret); 6288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 6298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 6308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("mode set: %dx%d@%dHz", mode->hdisplay, mode->vdisplay, mode->vrefresh); 6328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ret = drmModeSetCrtc(mDrmFd, output->crtc->crtc_id, output->fbId, 0, 0, 6348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol &output->connector->connector_id, 1, mode); 6358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (ret == 0) { 6368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol //save mode 6378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol memcpy(&output->mode, mode, sizeof(drmModeModeInfo)); 6388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } else { 6398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("drmModeSetCrtc failed. error: %d", ret); 6408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 6418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (oldFbId) { 6438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeRmFB(mDrmFd, oldFbId); 6448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 6458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (oldFbHandle) { 6478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer((buffer_handle_t)oldFbHandle); 6488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 6498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return ret == 0; 6518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 6528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolint Drm::getOutputIndex(int device) 6548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 6558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol switch (device) { 6568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol case IDisplayDevice::DEVICE_PRIMARY: 6578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return OUTPUT_PRIMARY; 6588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol case IDisplayDevice::DEVICE_EXTERNAL: 6598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return OUTPUT_EXTERNAL; 6608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol default: 6618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid display device"); 6628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol break; 6638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 6648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return -1; 6668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 6678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolint Drm::getPanelOrientation(int device) 6698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 6708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int outputIndex = getOutputIndex(device); 6718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (outputIndex < 0) { 6728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid device"); 6738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return PANEL_ORIENTATION_0; 6748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 6758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output= &mOutputs[outputIndex]; 6778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connected == false) { 6788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("device is not connected"); 6798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return PANEL_ORIENTATION_0; 6808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 6818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return output->panelOrientation; 6838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 6848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// HWC 1.4 requires that we return all of the compatible configs in getDisplayConfigs 6868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// this is needed so getActiveConfig/setActiveConfig work correctly. It is up to the 6878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// user space to decide what speed to send. 6888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujoldrmModeModeInfoPtr Drm::detectAllConfigs(int device, int *modeCount) 6898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 6908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol RETURN_NULL_IF_NOT_INIT(); 6918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock _l(mLock); 6928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (modeCount != NULL) 6948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol *modeCount = 0; 6958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol else 6968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return NULL; 6978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 6988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol int outputIndex = getOutputIndex(device); 6998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (outputIndex < 0) { 7008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid device"); 7018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return NULL; 7028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 7038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 7048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmOutput *output= &mOutputs[outputIndex]; 7058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!output->connected) { 7068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("device is not connected"); 7078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return NULL; 7088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 7098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 7108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (output->connector->count_modes <= 0) { 7118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("invalid count of modes"); 7128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return NULL; 7138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 7148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 7158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol *modeCount = output->connector->count_modes; 7168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return output->connector->modes; 7178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 7188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 7198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace intel 7208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace android 7218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 722