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 178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <HwcTrace.h> 188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <Drm.h> 198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <DrmConfig.h> 208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <Hwcomposer.h> 218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <ExternalDevice.h> 228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace android { 248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace intel { 258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolExternalDevice::ExternalDevice(Hwcomposer& hwc, DeviceControlFactory* controlFactory) 278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol : PhysicalDevice(DEVICE_EXTERNAL, hwc, controlFactory), 288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl(NULL), 298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mAbortModeSettingCond(), 308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mPendingDrmMode(), 318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending(false), 328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mExpectedRefreshRate(0) 338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol CTRACE(); 358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolExternalDevice::~ExternalDevice() 388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol CTRACE(); 408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool ExternalDevice::initialize() 438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!PhysicalDevice::initialize()) { 458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DEINIT_AND_RETURN_FALSE("failed to initialize physical device"); 468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl = mControlFactory->createHdcpControl(); 498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!mHdcpControl) { 508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DEINIT_AND_RETURN_FALSE("failed to create HDCP control"); 518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = false; 548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mConnected) { 558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl->startHdcpAsync(HdcpLinkStatusListener, this); 568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol UeventObserver *observer = Hwcomposer::getInstance().getUeventObserver(); 598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (observer) { 608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol observer->registerListener( 618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DrmConfig::getHotplugString(), 628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol hotplugEventListener, 638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol this); 648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } else { 658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("Uevent observer is NULL"); 668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid ExternalDevice::deinitialize() 718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // abort mode settings if it is in the middle 738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mAbortModeSettingCond.signal(); 748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mThread.get()) { 758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mThread->join(); 768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mThread = NULL; 778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mHdcpControl) { 808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl->stopHdcp(); 818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol delete mHdcpControl; 828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl = 0; 838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = false; 868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol PhysicalDevice::deinitialize(); 878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool ExternalDevice::setDrmMode(drmModeModeInfo& value) 908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!mConnected) { 928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("external device is not connected"); 938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mThread.get()) { 978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mThread->join(); 988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mThread = NULL; 998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Drm *drm = Hwcomposer::getInstance().getDrm(); 1028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeModeInfo mode; 1038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drm->getModeInfo(mType, mode); 1048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (drm->isSameDrmMode(&value, &mode)) 1058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 1068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // any issue here by faking connection status? 1088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mConnected = false; 1098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mPendingDrmMode = value; 1108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // setting mode in a working thread 1128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mThread = new ModeSettingThread(this); 1138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!mThread.get()) { 1148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to create mode settings thread"); 1158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 1168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mThread->run("ModeSettingsThread", PRIORITY_URGENT_DISPLAY); 1198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 1208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 1218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool ExternalDevice::threadLoop() 1238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 1248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // one-time execution 1258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol setDrmMode(); 1268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 1278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 1288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid ExternalDevice::setDrmMode() 1308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 1318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("start mode setting..."); 1328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Drm *drm = Hwcomposer::getInstance().getDrm(); 1348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mConnected = false; 1368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.hotplug(mType, false); 1378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol { 1398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Mutex::Autolock lock(mLock); 1408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // TODO: make timeout value flexible, or wait until surface flinger 1418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // acknowledges hot unplug event. 1428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol status_t err = mAbortModeSettingCond.waitRelative(mLock, milliseconds(20)); 1438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (err != -ETIMEDOUT) { 1448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("Mode settings is interrupted"); 1458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.hotplug(mType, true); 1468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 1478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // TODO: potential threading issue with onHotplug callback 1518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl->stopHdcp(); 1528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!drm->setDrmMode(mType, mPendingDrmMode)) { 1538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to set Drm mode"); 1548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.hotplug(mType, true); 1558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 1568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!PhysicalDevice::updateDisplayConfigs()) { 1598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to update display configs"); 1608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.hotplug(mType, true); 1618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 1628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mConnected = true; 1648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = true; 1658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // delay sending hotplug event until HDCP is authenticated 1668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mHdcpControl->startHdcpAsync(HdcpLinkStatusListener, this) == false) { 1678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("startHdcpAsync() failed; HDCP is not enabled"); 1688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = false; 1698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.hotplug(mType, true); 1708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mExpectedRefreshRate = 0; 1728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 1738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid ExternalDevice::HdcpLinkStatusListener(bool success, void *userData) 1768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 1778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (userData == NULL) { 1788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 1798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ExternalDevice *p = (ExternalDevice*)userData; 1828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol p->HdcpLinkStatusListener(success); 1838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 1848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid ExternalDevice::HdcpLinkStatusListener(bool success) 1868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 1878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!success) { 1888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("HDCP is not authenticated, disabling dynamic vsync"); 1898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.getVsyncManager()->enableDynamicVsync(false); 1908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mHotplugEventPending) { 1938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DTRACE("HDCP authentication status %d, sending hotplug event...", success); 1948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.hotplug(mType, mConnected); 1958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = false; 1968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 1978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 1988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (success) { 1998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("HDCP authenticated, enabling dynamic vsync"); 2008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.getVsyncManager()->enableDynamicVsync(true); 2018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 2038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid ExternalDevice::hotplugEventListener(void *data) 2058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 2068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ExternalDevice *pThis = (ExternalDevice*)data; 2078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (pThis) { 2088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol pThis->hotplugListener(); 2098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 2118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid ExternalDevice::hotplugListener() 2138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 2148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol bool ret; 2158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol CTRACE(); 2178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // abort mode settings if it is in the middle 2198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mAbortModeSettingCond.signal(); 2208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // remember the current connection status before detection 2228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol bool connected = mConnected; 2238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // detect display configs 2258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ret = detectDisplayConfigs(); 2268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (ret == false) { 2278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to detect display config"); 2288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 2298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("hotpug event: %d", mConnected); 2328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (connected == mConnected) { 2348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("same connection status detected, hotplug event ignored"); 2358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 2368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mConnected == false) { 2398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = false; 2408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.getVsyncManager()->resetVsyncSource(); 2418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl->stopHdcp(); 2428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.hotplug(mType, mConnected); 2438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } else { 2448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DTRACE("start HDCP asynchronously..."); 2458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // delay sending hotplug event till HDCP is authenticated. 2468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = true; 2478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ret = mHdcpControl->startHdcpAsync(HdcpLinkStatusListener, this); 2488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (ret == false) { 2498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ETRACE("failed to start HDCP"); 2508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = false; 2518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.hotplug(mType, mConnected); 2528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mActiveDisplayConfig = 0; 2558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 2568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolint ExternalDevice::getRefreshRate() 2588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 2598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Drm *drm = Hwcomposer::getInstance().getDrm(); 2608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeModeInfo mode; 2618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!drm->getModeInfo(IDisplayDevice::DEVICE_EXTERNAL, mode)) 2628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return 0; 2638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return mode.vrefresh; 2648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 2658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid ExternalDevice::setRefreshRate(int hz) 2678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 2688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol RETURN_VOID_IF_NOT_INIT(); 2698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("setting refresh rate to %d", hz); 2718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mBlank) { 2738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol WTRACE("external device is blank"); 2748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 2758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol Drm *drm = Hwcomposer::getInstance().getDrm(); 2788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drmModeModeInfo mode; 2798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!drm->getModeInfo(IDisplayDevice::DEVICE_EXTERNAL, mode)) 2808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 2818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (hz == 0 && (mode.type & DRM_MODE_TYPE_PREFERRED)) 2838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 2848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (hz == (int)mode.vrefresh) 2868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 2878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (mExpectedRefreshRate != 0 && 2898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mExpectedRefreshRate == hz && mHotplugEventPending) { 2908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("Ignore a new refresh setting event because there is a same event is handling"); 2918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return; 2928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 2938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mExpectedRefreshRate = hz; 2948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol ITRACE("changing refresh rate from %d to %d", mode.vrefresh, hz); 2968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.getVsyncManager()->enableDynamicVsync(false); 2988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 2998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl->stopHdcp(); 3008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol drm->setRefreshRate(IDisplayDevice::DEVICE_EXTERNAL, hz); 3028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHotplugEventPending = false; 3048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHdcpControl->startHdcpAsync(HdcpLinkStatusListener, this); 3058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mHwc.getVsyncManager()->enableDynamicVsync(true); 3068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 3078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolint ExternalDevice::getActiveConfig() 3098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 3108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!mConnected) { 3118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return 0; 3128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return mActiveDisplayConfig; 3148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 3158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool ExternalDevice::setActiveConfig(int index) 3178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{ 3188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (!mConnected) { 3198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (index == 0) 3208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 3218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol else 3228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // for now we will only permit the frequency change. In the future 3268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol // we may need to set mode as well. 3278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol if (index >= 0 && index < static_cast<int>(mDisplayConfigs.size())) { 3288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol DisplayConfig *config = mDisplayConfigs.itemAt(index); 3298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol setRefreshRate(config->getRefreshRate()); 3308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol mActiveDisplayConfig = index; 3318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 3328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } else { 3338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return false; 3348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol } 3358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol return true; 3368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} 3378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol 3388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace intel 3398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace android 340