14a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/*
24a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* Copyright (c) 2017, The Linux Foundation. All rights reserved.
34a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*
44a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* Redistribution and use in source and binary forms, with or without
54a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* modification, are permitted provided that the following conditions are
64a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* met:
74a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*     * Redistributions of source code must retain the above copyright
84a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*       notice, this list of conditions and the following disclaimer.
94a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*     * Redistributions in binary form must reproduce the above
104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*       copyright notice, this list of conditions and the following
114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*       disclaimer in the documentation and/or other materials provided
124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*       with the distribution.
134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*     * Neither the name of The Linux Foundation nor the names of its
144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*       contributors may be used to endorse or promote products derived
154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*       from this software without specific prior written permission.
164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*
174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*/
294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define __STDC_FORMAT_MACROS
314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <ctype.h>
334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <drm/drm_fourcc.h>
344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <drm_lib_loader.h>
354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <drm_master.h>
364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <drm_res_mgr.h>
374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <fcntl.h>
384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <inttypes.h>
394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <linux/fb.h>
404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <math.h>
414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <stdio.h>
424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <string.h>
434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sys/ioctl.h>
444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sys/stat.h>
454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sys/types.h>
464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <unistd.h>
474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/constants.h>
484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/debug.h>
494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/formats.h>
504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/sys.h>
514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <private/color_params.h>
524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <algorithm>
544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <string>
554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <unordered_map>
564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utility>
574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <vector>
584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "hw_device_drm.h"
604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "hw_info_interface.h"
614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "hw_color_manager_drm.h"
624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define __CLASS__ "HWDeviceDRM"
644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#endif
684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#ifndef DRM_FORMAT_MOD_QCOM_DX
694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#endif
714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#endif
744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing std::string;
764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing std::to_string;
774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing std::fstream;
784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing std::unordered_map;
794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing drm_utils::DRMMaster;
804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing drm_utils::DRMResMgr;
814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing drm_utils::DRMLibLoader;
824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing drm_utils::DRMBuffer;
834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::GetDRMManager;
844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DestroyDRMManager;
854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMDisplayType;
864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMDisplayToken;
874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMConnectorInfo;
884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMPPFeatureInfo;
894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMRect;
904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMRotation;
914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMBlendType;
924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMSrcConfig;
934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMOps;
944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing sde_drm::DRMTopology;
954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhnamespace sdm {
974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic void GetDRMFormat(LayerBufferFormat format, uint32_t *drm_format,
994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                         uint64_t *drm_format_modifier) {
1004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  switch (format) {
1014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBA8888:
1024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_ABGR8888;
1034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBA8888Ubwc:
1054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_ABGR8888;
1064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBA5551:
1094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_ABGR1555;
1104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBA4444:
1124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_ABGR4444;
1134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatBGRA8888:
1154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_ARGB8888;
1164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBX8888:
1184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_XBGR8888;
1194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBX8888Ubwc:
1214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_XBGR8888;
1224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatBGRX8888:
1254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_XRGB8888;
1264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGB888:
1284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_BGR888;
1294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGB565:
1314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_BGR565;
1324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatBGR565:
1344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_RGB565;
1354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatBGR565Ubwc:
1374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_BGR565;
1384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBA1010102:
1414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_ABGR2101010;
1424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBA1010102Ubwc:
1444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_ABGR2101010;
1454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatARGB2101010:
1484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_BGRA1010102;
1494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBX1010102:
1514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_XBGR2101010;
1524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatRGBX1010102Ubwc:
1544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_XBGR2101010;
1554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatXRGB2101010:
1584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_BGRX1010102;
1594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatBGRA1010102:
1614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_ARGB2101010;
1624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatABGR2101010:
1644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_RGBA1010102;
1654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatBGRX1010102:
1674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_XRGB2101010;
1684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatXBGR2101010:
1704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_RGBX1010102;
1714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCbCr420SemiPlanar:
1734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV12;
1744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCbCr420SemiPlanarVenus:
1764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV12;
1774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCbCr420SPVenusUbwc:
1794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV12;
1804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCrCb420SemiPlanar:
1834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV21;
1844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCrCb420SemiPlanarVenus:
1864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV21;
1874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCbCr420P010:
1894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV12;
1904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
1914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCbCr420P010Ubwc:
1934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV12;
1944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
1954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        DRM_FORMAT_MOD_QCOM_DX;
1964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCbCr420TP10Ubwc:
1984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV12;
1994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
2004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
2014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
2024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCbCr422H2V1SemiPlanar:
2034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV16;
2044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
2054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCrCb422H2V1SemiPlanar:
2064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_NV61;
2074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
2084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kFormatYCrCb420PlanarStride16:
2094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *drm_format = DRM_FORMAT_YVU420;
2104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
2114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    default:
2124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      DLOGW("Unsupported format %s", GetFormatString(format));
2134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::Registry::RegisterCurrent(HWLayers *hw_layers) {
2174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DRMMaster *master = nullptr;
2184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DRMMaster::GetInstance(&master);
2194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!master) {
2214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("Failed to acquire DRM Master instance");
2224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return;
2234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  HWLayersInfo &hw_layer_info = hw_layers->info;
2264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
2274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (uint32_t i = 0; i < hw_layer_count; i++) {
2294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    Layer &layer = hw_layer_info.hw_layers.at(i);
2304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    LayerBuffer *input_buffer = &layer.input_buffer;
2314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
2324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
2334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (hw_rotate_info->valid) {
2354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      input_buffer = &hw_rotator_session->output_buffer;
2364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int fd = input_buffer->planes[0].fd;
2394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
2404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      AllocatedBufferInfo buf_info {};
2414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      DRMBuffer layout {};
2424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      buf_info.fd = layout.fd = fd;
2434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      buf_info.aligned_width = layout.width = input_buffer->width;
2444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      buf_info.aligned_height = layout.height = input_buffer->height;
2454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      buf_info.format = input_buffer->format;
2464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
2474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
2484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                         &layout.num_planes);
2494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      uint32_t fb_id = 0;
2504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      int ret = master->CreateFbId(layout, &fb_id);
2514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      if (ret < 0) {
2524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
2534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh              layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
2544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh              errno);
2554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      } else {
2564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        hashmap_[current_index_][fd] = fb_id;
2574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
2584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::Registry::UnregisterNext() {
2634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DRMMaster *master = nullptr;
2644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DRMMaster::GetInstance(&master);
2654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!master) {
2674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("Failed to acquire DRM Master instance");
2684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return;
2694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  current_index_ = (current_index_ + 1) % kCycleDelay;
2724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  auto &curr_map = hashmap_[current_index_];
2734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (auto &pair : curr_map) {
2744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    uint32_t fb_id = pair.second;
2754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int ret = master->RemoveFbId(fb_id);
2764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ret < 0) {
2774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      DLOGE("Removing fb_id %d failed with error %d", fb_id, errno);
2784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  curr_map.clear();
2824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::Registry::Clear() {
2854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (int i = 0; i < kCycleDelay; i++) {
2864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    UnregisterNext();
2874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  current_index_ = 0;
2894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhuint32_t HWDeviceDRM::Registry::GetFbId(int fd) {
2924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  auto it = hashmap_[current_index_].find(fd);
2934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return (it == hashmap_[current_index_].end()) ? 0 : it->second;
2944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhHWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
2974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                         HWInfoInterface *hw_info_intf)
2984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
2994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      registry_(buffer_allocator) {
3004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  device_type_ = kDevicePrimary;
3014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  device_name_ = "Peripheral Display";
3024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_info_intf_ = hw_info_intf;
3034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::Init() {
3064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
3074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!default_mode_) {
3094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DRMMaster *drm_master = {};
3104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int dev_fd = -1;
3114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DRMMaster::GetInstance(&drm_master);
3124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    drm_master->GetHandle(&dev_fd);
3134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
3144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::PERIPHERAL, &token_)) {
3154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      DLOGE("RegisterDisplay failed");
3164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      return kErrorResources;
3174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
3204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
3214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    InitializeConfigs();
3224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode_);
3234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET, token_.crtc_id, 1);
3254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // TODO(user): Enable this and remove the one in SetupAtomic() onces underruns are fixed
3274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
3284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Commit to setup pipeline with mode, which then tells us the topology etc
3294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (drm_atomic_intf_->Commit(true /* synchronous */)) {
3304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id, token_.conn_id,
3314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            device_name_);
3324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      return kErrorResources;
3334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Reload connector info for updated info after 1st commit
3364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
3374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
3384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  PopulateDisplayAttributes();
3414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  PopulateHWPanelInfo();
3424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  UpdateMixerAttributes();
3434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_info_intf_->GetHWResourceInfo(&hw_resource_);
3444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
3464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (hw_resource_.has_qseed3) {
3474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
3484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
3514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::Deinit() {
3544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  delete hw_scale_;
3554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  registry_.Clear();
3564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
3574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_atomic_intf_ = {};
3584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_mgr_intf_->UnregisterDisplay(token_);
3594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
3604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::InitializeConfigs() {
3634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // TODO(user): Update modes
3644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  current_mode_ = connector_info_.modes[0];
3654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::PopulateDisplayAttributes() {
3684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drmModeModeInfo mode = {};
3694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t mm_width = 0;
3704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t mm_height = 0;
3714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DRMTopology topology = DRMTopology::SINGLE_LM;
3724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (default_mode_) {
3744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DRMResMgr *res_mgr = nullptr;
3754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int ret = DRMResMgr::GetInstance(&res_mgr);
3764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ret < 0) {
3774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      DLOGE("Failed to acquire DRMResMgr instance");
3784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      return kErrorResources;
3794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    res_mgr->GetMode(&mode);
3824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    res_mgr->GetDisplayDimInMM(&mm_width, &mm_height);
3834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  } else {
3844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    mode = current_mode_;
3854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    mm_width = connector_info_.mmWidth;
3864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    mm_height = connector_info_.mmHeight;
3874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    topology = connector_info_.topology;
3884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.x_pixels = mode.hdisplay;
3914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.y_pixels = mode.vdisplay;
3924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.fps = mode.vrefresh;
3934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.vsync_period_ns = UINT32(1000000000L / display_attributes_.fps);
3944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  /*
3964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh              Active                 Front           Sync           Back
3974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh              Region                 Porch                          Porch
3984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh     <-----------------------><----------------><-------------><-------------->
3994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh     <----- [hv]display ----->
4004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh     <------------- [hv]sync_start ------------>
4014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh     <--------------------- [hv]sync_end --------------------->
4024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh     <-------------------------------- [hv]total ----------------------------->
4034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh   */
4044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.v_front_porch = mode.vsync_start - mode.vdisplay;
4064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.v_pulse_width = mode.vsync_end - mode.vsync_start;
4074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.v_back_porch = mode.vtotal - mode.vsync_end;
4084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.v_total = mode.vtotal;
4094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.h_total = mode.htotal;
4114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t h_blanking = mode.htotal - mode.hdisplay;
4124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.is_device_split =
4134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      (topology == DRMTopology::DUAL_LM || topology == DRMTopology::DUAL_LM_MERGE);
4144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.h_total += display_attributes_.is_device_split ? h_blanking : 0;
4154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.x_dpi = (FLOAT(mode.hdisplay) * 25.4f) / FLOAT(mm_width);
4174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  display_attributes_.y_dpi = (FLOAT(mode.vdisplay) * 25.4f) / FLOAT(mm_height);
4184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
4204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
4214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::PopulateHWPanelInfo() {
4234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_ = {};
4244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  snprintf(hw_panel_info_.panel_name, sizeof(hw_panel_info_.panel_name), "%s",
4264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh           connector_info_.panel_name.c_str());
4274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.split_info.left_split = display_attributes_.x_pixels;
4284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (display_attributes_.is_device_split) {
4294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    hw_panel_info_.split_info.left_split = hw_panel_info_.split_info.right_split =
4304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        display_attributes_.x_pixels / 2;
4314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
4324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.partial_update = 0;
4344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.left_align = 0;
4354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.width_align = 0;
4364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.top_align = 0;
4374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.height_align = 0;
4384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.min_roi_width = 0;
4394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.min_roi_height = 0;
4404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.needs_roi_merge = 0;
4414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
4424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.min_fps = 60;
4434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.max_fps = 60;
4444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.is_primary_panel = connector_info_.is_primary;
4454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.is_pluggable = 0;
4464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!default_mode_) {
4484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    hw_panel_info_.needs_roi_merge = (connector_info_.topology == DRMTopology::DUAL_LM_MERGE);
4494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
4504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  GetHWDisplayPortAndMode();
4524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  GetHWPanelMaxBrightness();
4534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DLOGI("%s, Panel Interface = %s, Panel Mode = %s, Is Primary = %d", device_name_,
4554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        interface_str_.c_str(), hw_panel_info_.mode == kModeVideo ? "Video" : "Command",
4564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        hw_panel_info_.is_primary_panel);
4574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DLOGI("Partial Update = %d, Dynamic FPS = %d", hw_panel_info_.partial_update,
4584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        hw_panel_info_.dynamic_fps);
4594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DLOGI("Align: left = %d, width = %d, top = %d, height = %d", hw_panel_info_.left_align,
4604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        hw_panel_info_.width_align, hw_panel_info_.top_align, hw_panel_info_.height_align);
4614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d", hw_panel_info_.min_roi_width,
4624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        hw_panel_info_.min_roi_height, hw_panel_info_.needs_roi_merge);
4634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DLOGI("FPS: min = %d, max =%d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
4644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
4654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        hw_panel_info_.split_info.right_split);
4664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
4674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::GetHWDisplayPortAndMode() {
4694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.port = kPortDefault;
4704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.mode =
4714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      (connector_info_.panel_mode == sde_drm::DRMPanelMode::VIDEO) ? kModeVideo : kModeCommand;
4724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (default_mode_) {
4744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return;
4754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
4764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  switch (connector_info_.type) {
4784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case DRM_MODE_CONNECTOR_DSI:
4794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      hw_panel_info_.port = kPortDSI;
4804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      interface_str_ = "DSI";
4814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
4824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case DRM_MODE_CONNECTOR_LVDS:
4834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      hw_panel_info_.port = kPortLVDS;
4844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      interface_str_ = "LVDS";
4854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
4864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case DRM_MODE_CONNECTOR_eDP:
4874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      hw_panel_info_.port = kPortEDP;
4884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      interface_str_ = "EDP";
4894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
4904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case DRM_MODE_CONNECTOR_TV:
4914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case DRM_MODE_CONNECTOR_HDMIA:
4924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case DRM_MODE_CONNECTOR_HDMIB:
4934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      hw_panel_info_.port = kPortDTV;
4944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      interface_str_ = "HDMI";
4954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
4964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case DRM_MODE_CONNECTOR_VIRTUAL:
4974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      hw_panel_info_.port = kPortWriteBack;
4984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      interface_str_ = "Virtual";
4994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
5004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case DRM_MODE_CONNECTOR_DisplayPort:
5014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      // TODO(user): Add when available
5024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      interface_str_ = "DisplayPort";
5034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
5044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
5054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return;
5074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::GetHWPanelMaxBrightness() {
5104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  char brightness[kMaxStringLength] = {0};
5114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  string kMaxBrightnessNode = "/sys/class/backlight/panel0-backlight/max_brightness";
5124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_panel_info_.panel_max_brightness = 255;
5144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int fd = Sys::open_(kMaxBrightnessNode.c_str(), O_RDONLY);
5154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (fd < 0) {
5164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGW("Failed to open max brightness node = %s, error = %s", kMaxBrightnessNode.c_str(),
5174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          strerror(errno));
5184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return;
5194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
5204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
5224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    hw_panel_info_.panel_max_brightness = atoi(brightness);
5234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGI("Max brightness level = %d", hw_panel_info_.panel_max_brightness);
5244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  } else {
5254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGW("Failed to read max brightness level. error = %s", strerror(errno));
5264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
5274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  Sys::close_(fd);
5294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetActiveConfig(uint32_t *active_config) {
5324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  *active_config = 0;
5334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetNumDisplayAttributes(uint32_t *count) {
5374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  *count = 1;
5384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetDisplayAttributes(uint32_t index,
5424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                            HWDisplayAttributes *display_attributes) {
5434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  *display_attributes = display_attributes_;
5444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) {
5484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  *panel_info = hw_panel_info_;
5494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
5534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
5574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
5584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetConfigIndex(uint32_t mode, uint32_t *index) {
5614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::PowerOn() {
5654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DTRACE_SCOPED();
5664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::PowerOff() {
5704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::Doze() {
5744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::DozeSuspend() {
5784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::Standby() {
5824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
5834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
5844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) {
5864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (default_mode_) {
5874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return;
5884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
5894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  HWLayersInfo &hw_layer_info = hw_layers->info;
5914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
5924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (uint32_t i = 0; i < hw_layer_count; i++) {
5944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    Layer &layer = hw_layer_info.hw_layers.at(i);
5954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    LayerBuffer *input_buffer = &layer.input_buffer;
5964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
5974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
5984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
5994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool needs_rotation = false;
6004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (uint32_t count = 0; count < 2; count++) {
6024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
6034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
6044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      if (hw_rotate_info->valid) {
6064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        input_buffer = &hw_rotator_session->output_buffer;
6074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        needs_rotation = true;
6084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
6094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      uint32_t fb_id = registry_.GetFbId(input_buffer->planes[0].fd);
6114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      if (pipe_info->valid && fb_id) {
6124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        uint32_t pipe_id = pipe_info->pipe_id;
6134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha);
6144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ZORDER, pipe_id, pipe_info->z_order);
6154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        DRMBlendType blending = {};
6164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        SetBlending(layer.blending, &blending);
6174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_BLEND_TYPE, pipe_id, blending);
6184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        DRMRect src = {};
6194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        SetRect(pipe_info->src_roi, &src);
6204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_RECT, pipe_id, src);
6214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        DRMRect dst = {};
6224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        SetRect(pipe_info->dst_roi, &dst);
6234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst);
6244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        uint32_t rot_bit_mask = 0;
6264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // In case of rotation, rotator handles flips
6274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (!needs_rotation) {
6284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          if (layer.transform.flip_horizontal) {
6294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            rot_bit_mask |= UINT32(DRMRotation::FLIP_H);
6304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          }
6314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          if (layer.transform.flip_vertical) {
6324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            rot_bit_mask |= UINT32(DRMRotation::FLIP_V);
6334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          }
6344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
6354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask);
6374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_H_DECIMATION, pipe_id,
6384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                  pipe_info->horizontal_decimation);
6394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_V_DECIMATION, pipe_id,
6404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                  pipe_info->vertical_decimation);
6414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        uint32_t config = 0;
6424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        SetSrcConfig(layer.input_buffer, &config);
6434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);;
6444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id);
6454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id);
6464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (!validate && input_buffer->acquire_fence_fd >= 0) {
6474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id,
6484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                    input_buffer->acquire_fence_fd);
6494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
6504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (hw_scale_) {
6514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          SDEScaler scaler_output = {};
6524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          hw_scale_->SetPlaneScaler(pipe_info->scale_data, &scaler_output);
6534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          // TODO(user): Remove qseed3 and add version check, then send appropriate scaler object
6544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          if (hw_resource_.has_qseed3) {
6554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id,
6564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                      reinterpret_cast<uint64_t>(&scaler_output.scaler_v2));
6574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          }
6584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
6594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
6604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // TODO(user): Remove this and enable the one in Init() onces underruns are fixed
6634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
6644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
6654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
6664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
6684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DTRACE_SCOPED();
6694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  registry_.RegisterCurrent(hw_layers);
6714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  SetupAtomic(hw_layers, true /* validate */);
6724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int ret = drm_atomic_intf_->Validate();
6744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (ret) {
6754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("%s failed with error %d", __FUNCTION__, ret);
6764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorHardware;
6774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
6784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
6804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
6814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {
6834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DTRACE_SCOPED();
6844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DisplayError err = kErrorNone;
6864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  registry_.RegisterCurrent(hw_layers);
6874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (default_mode_) {
6894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    err = DefaultCommit(hw_layers);
6904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  } else {
6914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    err = AtomicCommit(hw_layers);
6924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
6934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  registry_.UnregisterNext();
6954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return err;
6974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
6984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) {
7004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DTRACE_SCOPED();
7014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  HWLayersInfo &hw_layer_info = hw_layers->info;
7034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  LayerStack *stack = hw_layer_info.stack;
7044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  stack->retire_fence_fd = -1;
7064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (Layer &layer : hw_layer_info.hw_layers) {
7074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    layer.input_buffer.release_fence_fd = -1;
7084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
7094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DRMMaster *master = nullptr;
7114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int ret = DRMMaster::GetInstance(&master);
7124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (ret < 0) {
7134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("Failed to acquire DRMMaster instance");
7144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorResources;
7154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
7164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DRMResMgr *res_mgr = nullptr;
7184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  ret = DRMResMgr::GetInstance(&res_mgr);
7194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (ret < 0) {
7204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("Failed to acquire DRMResMgr instance");
7214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorResources;
7224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
7234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int dev_fd = -1;
7254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  master->GetHandle(&dev_fd);
7264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t connector_id = 0;
7284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  res_mgr->GetConnectorId(&connector_id);
7294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t crtc_id = 0;
7314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  res_mgr->GetCrtcId(&crtc_id);
7324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drmModeModeInfo mode;
7344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  res_mgr->GetMode(&mode);
7354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t fb_id = registry_.GetFbId(hw_layer_info.hw_layers.at(0).input_buffer.planes[0].fd);
7374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id,
7384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                       1 /* num_connectors */, &mode);
7394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (ret < 0) {
7404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("drmModeSetCrtc failed dev fd %d, fb_id %d, crtc id %d, connector id %d, %s", dev_fd,
7414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          fb_id, crtc_id, connector_id, strerror(errno));
7424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorHardware;
7434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
7444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
7464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
7474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) {
7494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DTRACE_SCOPED();
7504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  SetupAtomic(hw_layers, false /* validate */);
7514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int ret = drm_atomic_intf_->Commit(false /* synchronous */);
7534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (ret) {
7544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("%s failed with error %d", __FUNCTION__, ret);
7554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorHardware;
7564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
7574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int release_fence = -1;
7594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int retire_fence = -1;
7604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence);
7624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_GET_RETIRE_FENCE, token_.conn_id, &retire_fence);
7634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  HWLayersInfo &hw_layer_info = hw_layers->info;
7654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  LayerStack *stack = hw_layer_info.stack;
7664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  stack->retire_fence_fd = retire_fence;
7674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (uint32_t i = 0; i < hw_layer_info.hw_layers.size(); i++) {
7694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    Layer &layer = hw_layer_info.hw_layers.at(i);
7704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
7714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (hw_rotator_session->hw_block_count) {
7724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      hw_rotator_session->output_buffer.release_fence_fd = Sys::dup_(release_fence);
7734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
7744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      layer.input_buffer.release_fence_fd = Sys::dup_(release_fence);
7754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
7764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
7774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  hw_layer_info.sync_handle = release_fence;
7794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
7814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
7824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::Flush() {
7844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
7854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
7864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::SetBlending(const LayerBlending &source, DRMBlendType *target) {
7884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  switch (source) {
7894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kBlendingPremultiplied:
7904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *target = DRMBlendType::PREMULTIPLIED;
7914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
7924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kBlendingOpaque:
7934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *target = DRMBlendType::OPAQUE;
7944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
7954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case kBlendingCoverage:
7964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *target = DRMBlendType::COVERAGE;
7974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
7984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    default:
7994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *target = DRMBlendType::UNDEFINED;
8004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
8014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::SetSrcConfig(const LayerBuffer &input_buffer, uint32_t *config) {
8054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (input_buffer.flags.interlace) {
8064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *config |= (0x01 << UINT32(DRMSrcConfig::DEINTERLACE));
8074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
8084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::SetRect(const LayerRect &source, DRMRect *target) {
8114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  target->left = UINT32(source.left);
8124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  target->top = UINT32(source.top);
8134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  target->right = UINT32(source.right);
8144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  target->bottom = UINT32(source.bottom);
8154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhbool HWDeviceDRM::EnableHotPlugDetection(int enable) {
8184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return true;
8194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::ResetDisplayParams() {}
8224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
8244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DTRACE_SCOPED();
8254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
8264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
8294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  struct DRMPPFeatureInfo info = {};
8304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
8324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
8334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    info.id = HWColorManagerDrm::ToDrmFeatureId(i);
8344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (info.id >= sde_drm::kPPFeaturesMax)
8354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      continue;
8364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // use crtc_id_ = 0 since PP features are same across all CRTCs
8374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    drm_mgr_intf_->GetCrtcPPInfo(0, info);
8384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    vers->version[i] = HWColorManagerDrm::GetFeatureVersion(info);
8394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
8404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
8414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) {
8444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int ret = 0;
8454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  PPFeatureInfo *feature = NULL;
8464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DRMPPFeatureInfo kernel_params = {};
8474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  while (true) {
8494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ret = feature_list->RetrieveNextFeature(&feature);
8504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ret)
8514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
8524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (feature) {
8544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
8554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      if (!HWColorManagerDrm::GetDrmFeature[feature->feature_id_]) {
8564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        DLOGE("GetDrmFeature is not valid for feature %d", feature->feature_id_);
8574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        continue;
8584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
8594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      ret = HWColorManagerDrm::GetDrmFeature[feature->feature_id_](*feature, &kernel_params);
8604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      if (!ret)
8614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params);
8624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      HWColorManagerDrm::FreeDrmFeatureData(&kernel_params);
8634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
8644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
8654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // Once all features were consumed, then destroy all feature instance from feature_list,
8674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  feature_list->Reset();
8684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
8704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetVSyncState(bool enable) {
8734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
8744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {}
8774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) {
8794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
8804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) {
8834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
8844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetPanelBrightness(int level) {
8874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DisplayError err = kErrorNone;
8884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  char buffer[kMaxSysfsCommandLength] = {0};
8894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level);
8914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int fd = Sys::open_(kBrightnessNode, O_RDWR);
8924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (fd < 0) {
8934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode,
8944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh             strerror(errno));
8954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorFileDescriptor;
8964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
8974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int32_t bytes = snprintf(buffer, kMaxSysfsCommandLength, "%d\n", level);
8994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  ssize_t ret = Sys::pwrite_(fd, buffer, static_cast<size_t>(bytes), 0);
9004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (ret <= 0) {
9014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode,
9024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh             strerror(errno));
9034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    err = kErrorHardware;
9044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
9054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  Sys::close_(fd);
9074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return err;
9094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetPanelBrightness(int *level) {
9124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DisplayError err = kErrorNone;
9134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  char brightness[kMaxStringLength] = {0};
9144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!level) {
9164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer.");
9174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorParameters;
9184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
9194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int fd = Sys::open_(kBrightnessNode, O_RDWR);
9214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (fd < 0) {
9224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode,
9234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh             strerror(errno));
9244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorFileDescriptor;
9254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
9264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
9284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *level = atoi(brightness);
9294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level);
9304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  } else {
9314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGV_IF(kTagDriverConfig, "Failed to read panel brightness");
9324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    err = kErrorHardware;
9334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
9344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  Sys::close_(fd);
9364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return err;
9384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::CachePanelBrightness(int level) {
9414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
9424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetHWScanInfo(HWScanInfo *scan_info) {
9454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
9464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetVideoFormat(uint32_t config_index, uint32_t *video_format) {
9494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
9504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetMaxCEAFormat(uint32_t *max_cea_format) {
9534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
9544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
9574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
9584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetS3DMode(HWS3DMode s3d_mode) {
9614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNotSupported;
9624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
9654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  sde_drm::DRMScalerLUTInfo drm_lut_info = {};
9664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_lut_info.cir_lut = lut_info->cir_lut;
9674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_lut_info.dir_lut = lut_info->dir_lut;
9684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_lut_info.sep_lut = lut_info->sep_lut;
9694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_lut_info.cir_lut_size = lut_info->cir_lut_size;
9704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_lut_info.dir_lut_size = lut_info->dir_lut_size;
9714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_lut_info.sep_lut_size = lut_info->sep_lut_size;
9724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  drm_mgr_intf_->SetScalerLUT(drm_lut_info);
9734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
9754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
9784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!hw_resource_.hw_dest_scalar_info.count) {
9794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorNotSupported;
9804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
9814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (mixer_attributes.width > display_attributes_.x_pixels ||
9834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      mixer_attributes.height > display_attributes_.y_pixels) {
9844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
9854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels,
9864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          display_attributes_.y_pixels);
9874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorNotSupported;
9884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
9894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
9914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (display_attributes_.is_device_split) {
9924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    max_input_width *= 2;
9934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
9944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (mixer_attributes.width > max_input_width) {
9964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
9974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          max_input_width);
9984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorNotSupported;
9994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
10004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
10024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  float display_aspect_ratio =
10034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      FLOAT(display_attributes_.x_pixels) / FLOAT(display_attributes_.y_pixels);
10044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (display_aspect_ratio != mixer_aspect_ratio) {
10064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
10074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          mixer_attributes.height, display_attributes_.x_pixels, display_attributes_.y_pixels);
10084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorNotSupported;
10094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
10104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  float scale_x = FLOAT(display_attributes_.x_pixels) / FLOAT(mixer_attributes.width);
10124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height);
10134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
10144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (scale_x > max_scale_up || scale_y > max_scale_up) {
10154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGW(
10164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        "Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f "
10174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        "max_scale_up %f",
10184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        scale_x, scale_y, max_scale_up);
10194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorNotSupported;
10204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
10214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
10234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  mixer_attributes_ = mixer_attributes;
10254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  mixer_attributes_.split_left = mixer_attributes_.width;
10264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (display_attributes_.is_device_split) {
10274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
10284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
10294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
10314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
10324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWDeviceDRM::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
10344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!mixer_attributes) {
10354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorParameters;
10364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
10374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  mixer_attributes_.width = display_attributes_.x_pixels;
10394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  mixer_attributes_.height = display_attributes_.y_pixels;
10404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  mixer_attributes_.split_left = display_attributes_.is_device_split
10414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     ? hw_panel_info_.split_info.left_split
10424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     : mixer_attributes_.width;
10434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  *mixer_attributes = mixer_attributes_;
10444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
10464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
10474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWDeviceDRM::UpdateMixerAttributes() {
10494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  mixer_attributes_.width = display_attributes_.x_pixels;
10504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  mixer_attributes_.height = display_attributes_.y_pixels;
10514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  mixer_attributes_.split_left = display_attributes_.is_device_split
10524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     ? hw_panel_info_.split_info.left_split
10534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     : mixer_attributes_.width;
10544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
10554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}  // namespace sdm
1057