1/* 2* Copyright (c) 2017, The Linux Foundation. All rights reserved. 3* 4* Redistribution and use in source and binary forms, with or without 5* modification, are permitted provided that the following conditions are 6* met: 7* * Redistributions of source code must retain the above copyright 8* notice, this list of conditions and the following disclaimer. 9* * Redistributions in binary form must reproduce the above 10* copyright notice, this list of conditions and the following 11* disclaimer in the documentation and/or other materials provided 12* with the distribution. 13* * Neither the name of The Linux Foundation nor the names of its 14* contributors may be used to endorse or promote products derived 15* from this software without specific prior written permission. 16* 17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*/ 29 30#define __STDC_FORMAT_MACROS 31 32#include <ctype.h> 33#include <drm/drm_fourcc.h> 34#include <drm_lib_loader.h> 35#include <drm_master.h> 36#include <drm_res_mgr.h> 37#include <fcntl.h> 38#include <inttypes.h> 39#include <linux/fb.h> 40#include <math.h> 41#include <stdio.h> 42#include <string.h> 43#include <sys/ioctl.h> 44#include <sys/stat.h> 45#include <sys/types.h> 46#include <unistd.h> 47#include <utils/constants.h> 48#include <utils/debug.h> 49#include <utils/formats.h> 50#include <utils/sys.h> 51#include <private/color_params.h> 52 53#include <algorithm> 54#include <string> 55#include <unordered_map> 56#include <utility> 57#include <vector> 58 59#include "hw_device_drm.h" 60#include "hw_info_interface.h" 61#include "hw_color_manager_drm.h" 62 63#define __CLASS__ "HWDeviceDRM" 64 65#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED 66#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1) 67#endif 68#ifndef DRM_FORMAT_MOD_QCOM_DX 69#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2) 70#endif 71#ifndef DRM_FORMAT_MOD_QCOM_TIGHT 72#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4) 73#endif 74 75using std::string; 76using std::to_string; 77using std::fstream; 78using std::unordered_map; 79using drm_utils::DRMMaster; 80using drm_utils::DRMResMgr; 81using drm_utils::DRMLibLoader; 82using drm_utils::DRMBuffer; 83using sde_drm::GetDRMManager; 84using sde_drm::DestroyDRMManager; 85using sde_drm::DRMDisplayType; 86using sde_drm::DRMDisplayToken; 87using sde_drm::DRMConnectorInfo; 88using sde_drm::DRMPPFeatureInfo; 89using sde_drm::DRMRect; 90using sde_drm::DRMRotation; 91using sde_drm::DRMBlendType; 92using sde_drm::DRMSrcConfig; 93using sde_drm::DRMOps; 94using sde_drm::DRMTopology; 95 96namespace sdm { 97 98static void GetDRMFormat(LayerBufferFormat format, uint32_t *drm_format, 99 uint64_t *drm_format_modifier) { 100 switch (format) { 101 case kFormatRGBA8888: 102 *drm_format = DRM_FORMAT_ABGR8888; 103 break; 104 case kFormatRGBA8888Ubwc: 105 *drm_format = DRM_FORMAT_ABGR8888; 106 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; 107 break; 108 case kFormatRGBA5551: 109 *drm_format = DRM_FORMAT_ABGR1555; 110 break; 111 case kFormatRGBA4444: 112 *drm_format = DRM_FORMAT_ABGR4444; 113 break; 114 case kFormatBGRA8888: 115 *drm_format = DRM_FORMAT_ARGB8888; 116 break; 117 case kFormatRGBX8888: 118 *drm_format = DRM_FORMAT_XBGR8888; 119 break; 120 case kFormatRGBX8888Ubwc: 121 *drm_format = DRM_FORMAT_XBGR8888; 122 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; 123 break; 124 case kFormatBGRX8888: 125 *drm_format = DRM_FORMAT_XRGB8888; 126 break; 127 case kFormatRGB888: 128 *drm_format = DRM_FORMAT_BGR888; 129 break; 130 case kFormatRGB565: 131 *drm_format = DRM_FORMAT_BGR565; 132 break; 133 case kFormatBGR565: 134 *drm_format = DRM_FORMAT_RGB565; 135 break; 136 case kFormatBGR565Ubwc: 137 *drm_format = DRM_FORMAT_BGR565; 138 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; 139 break; 140 case kFormatRGBA1010102: 141 *drm_format = DRM_FORMAT_ABGR2101010; 142 break; 143 case kFormatRGBA1010102Ubwc: 144 *drm_format = DRM_FORMAT_ABGR2101010; 145 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; 146 break; 147 case kFormatARGB2101010: 148 *drm_format = DRM_FORMAT_BGRA1010102; 149 break; 150 case kFormatRGBX1010102: 151 *drm_format = DRM_FORMAT_XBGR2101010; 152 break; 153 case kFormatRGBX1010102Ubwc: 154 *drm_format = DRM_FORMAT_XBGR2101010; 155 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; 156 break; 157 case kFormatXRGB2101010: 158 *drm_format = DRM_FORMAT_BGRX1010102; 159 break; 160 case kFormatBGRA1010102: 161 *drm_format = DRM_FORMAT_ARGB2101010; 162 break; 163 case kFormatABGR2101010: 164 *drm_format = DRM_FORMAT_RGBA1010102; 165 break; 166 case kFormatBGRX1010102: 167 *drm_format = DRM_FORMAT_XRGB2101010; 168 break; 169 case kFormatXBGR2101010: 170 *drm_format = DRM_FORMAT_RGBX1010102; 171 break; 172 case kFormatYCbCr420SemiPlanar: 173 *drm_format = DRM_FORMAT_NV12; 174 break; 175 case kFormatYCbCr420SemiPlanarVenus: 176 *drm_format = DRM_FORMAT_NV12; 177 break; 178 case kFormatYCbCr420SPVenusUbwc: 179 *drm_format = DRM_FORMAT_NV12; 180 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; 181 break; 182 case kFormatYCrCb420SemiPlanar: 183 *drm_format = DRM_FORMAT_NV21; 184 break; 185 case kFormatYCrCb420SemiPlanarVenus: 186 *drm_format = DRM_FORMAT_NV21; 187 break; 188 case kFormatYCbCr420P010: 189 *drm_format = DRM_FORMAT_NV12; 190 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX; 191 break; 192 case kFormatYCbCr420P010Ubwc: 193 *drm_format = DRM_FORMAT_NV12; 194 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED | 195 DRM_FORMAT_MOD_QCOM_DX; 196 break; 197 case kFormatYCbCr420TP10Ubwc: 198 *drm_format = DRM_FORMAT_NV12; 199 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED | 200 DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT; 201 break; 202 case kFormatYCbCr422H2V1SemiPlanar: 203 *drm_format = DRM_FORMAT_NV16; 204 break; 205 case kFormatYCrCb422H2V1SemiPlanar: 206 *drm_format = DRM_FORMAT_NV61; 207 break; 208 case kFormatYCrCb420PlanarStride16: 209 *drm_format = DRM_FORMAT_YVU420; 210 break; 211 default: 212 DLOGW("Unsupported format %s", GetFormatString(format)); 213 } 214} 215 216void HWDeviceDRM::Registry::RegisterCurrent(HWLayers *hw_layers) { 217 DRMMaster *master = nullptr; 218 DRMMaster::GetInstance(&master); 219 220 if (!master) { 221 DLOGE("Failed to acquire DRM Master instance"); 222 return; 223 } 224 225 HWLayersInfo &hw_layer_info = hw_layers->info; 226 uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size()); 227 228 for (uint32_t i = 0; i < hw_layer_count; i++) { 229 Layer &layer = hw_layer_info.hw_layers.at(i); 230 LayerBuffer *input_buffer = &layer.input_buffer; 231 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session; 232 HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0]; 233 234 if (hw_rotate_info->valid) { 235 input_buffer = &hw_rotator_session->output_buffer; 236 } 237 238 int fd = input_buffer->planes[0].fd; 239 if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) { 240 AllocatedBufferInfo buf_info {}; 241 DRMBuffer layout {}; 242 buf_info.fd = layout.fd = fd; 243 buf_info.aligned_width = layout.width = input_buffer->width; 244 buf_info.aligned_height = layout.height = input_buffer->height; 245 buf_info.format = input_buffer->format; 246 GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier); 247 buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset, 248 &layout.num_planes); 249 uint32_t fb_id = 0; 250 int ret = master->CreateFbId(layout, &fb_id); 251 if (ret < 0) { 252 DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d", 253 layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0], 254 errno); 255 } else { 256 hashmap_[current_index_][fd] = fb_id; 257 } 258 } 259 } 260} 261 262void HWDeviceDRM::Registry::UnregisterNext() { 263 DRMMaster *master = nullptr; 264 DRMMaster::GetInstance(&master); 265 266 if (!master) { 267 DLOGE("Failed to acquire DRM Master instance"); 268 return; 269 } 270 271 current_index_ = (current_index_ + 1) % kCycleDelay; 272 auto &curr_map = hashmap_[current_index_]; 273 for (auto &pair : curr_map) { 274 uint32_t fb_id = pair.second; 275 int ret = master->RemoveFbId(fb_id); 276 if (ret < 0) { 277 DLOGE("Removing fb_id %d failed with error %d", fb_id, errno); 278 } 279 } 280 281 curr_map.clear(); 282} 283 284void HWDeviceDRM::Registry::Clear() { 285 for (int i = 0; i < kCycleDelay; i++) { 286 UnregisterNext(); 287 } 288 current_index_ = 0; 289} 290 291uint32_t HWDeviceDRM::Registry::GetFbId(int fd) { 292 auto it = hashmap_[current_index_].find(fd); 293 return (it == hashmap_[current_index_].end()) ? 0 : it->second; 294} 295 296HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator, 297 HWInfoInterface *hw_info_intf) 298 : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler), 299 registry_(buffer_allocator) { 300 device_type_ = kDevicePrimary; 301 device_name_ = "Peripheral Display"; 302 hw_info_intf_ = hw_info_intf; 303} 304 305DisplayError HWDeviceDRM::Init() { 306 default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false); 307 308 if (!default_mode_) { 309 DRMMaster *drm_master = {}; 310 int dev_fd = -1; 311 DRMMaster::GetInstance(&drm_master); 312 drm_master->GetHandle(&dev_fd); 313 DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_); 314 if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::PERIPHERAL, &token_)) { 315 DLOGE("RegisterDisplay failed"); 316 return kErrorResources; 317 } 318 319 drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_); 320 drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_); 321 InitializeConfigs(); 322 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, ¤t_mode_); 323 324 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET, token_.crtc_id, 1); 325 326 // TODO(user): Enable this and remove the one in SetupAtomic() onces underruns are fixed 327 // drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); 328 // Commit to setup pipeline with mode, which then tells us the topology etc 329 if (drm_atomic_intf_->Commit(true /* synchronous */)) { 330 DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id, token_.conn_id, 331 device_name_); 332 return kErrorResources; 333 } 334 335 // Reload connector info for updated info after 1st commit 336 drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_); 337 DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_); 338 } 339 340 PopulateDisplayAttributes(); 341 PopulateHWPanelInfo(); 342 UpdateMixerAttributes(); 343 hw_info_intf_->GetHWResourceInfo(&hw_resource_); 344 345 // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor 346 if (hw_resource_.has_qseed3) { 347 hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2); 348 } 349 350 return kErrorNone; 351} 352 353DisplayError HWDeviceDRM::Deinit() { 354 delete hw_scale_; 355 registry_.Clear(); 356 drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_); 357 drm_atomic_intf_ = {}; 358 drm_mgr_intf_->UnregisterDisplay(token_); 359 return kErrorNone; 360} 361 362void HWDeviceDRM::InitializeConfigs() { 363 // TODO(user): Update modes 364 current_mode_ = connector_info_.modes[0]; 365} 366 367DisplayError HWDeviceDRM::PopulateDisplayAttributes() { 368 drmModeModeInfo mode = {}; 369 uint32_t mm_width = 0; 370 uint32_t mm_height = 0; 371 DRMTopology topology = DRMTopology::SINGLE_LM; 372 373 if (default_mode_) { 374 DRMResMgr *res_mgr = nullptr; 375 int ret = DRMResMgr::GetInstance(&res_mgr); 376 if (ret < 0) { 377 DLOGE("Failed to acquire DRMResMgr instance"); 378 return kErrorResources; 379 } 380 381 res_mgr->GetMode(&mode); 382 res_mgr->GetDisplayDimInMM(&mm_width, &mm_height); 383 } else { 384 mode = current_mode_; 385 mm_width = connector_info_.mmWidth; 386 mm_height = connector_info_.mmHeight; 387 topology = connector_info_.topology; 388 } 389 390 display_attributes_.x_pixels = mode.hdisplay; 391 display_attributes_.y_pixels = mode.vdisplay; 392 display_attributes_.fps = mode.vrefresh; 393 display_attributes_.vsync_period_ns = UINT32(1000000000L / display_attributes_.fps); 394 395 /* 396 Active Front Sync Back 397 Region Porch Porch 398 <-----------------------><----------------><-------------><--------------> 399 <----- [hv]display -----> 400 <------------- [hv]sync_start ------------> 401 <--------------------- [hv]sync_end ---------------------> 402 <-------------------------------- [hv]total -----------------------------> 403 */ 404 405 display_attributes_.v_front_porch = mode.vsync_start - mode.vdisplay; 406 display_attributes_.v_pulse_width = mode.vsync_end - mode.vsync_start; 407 display_attributes_.v_back_porch = mode.vtotal - mode.vsync_end; 408 display_attributes_.v_total = mode.vtotal; 409 410 display_attributes_.h_total = mode.htotal; 411 uint32_t h_blanking = mode.htotal - mode.hdisplay; 412 display_attributes_.is_device_split = 413 (topology == DRMTopology::DUAL_LM || topology == DRMTopology::DUAL_LM_MERGE); 414 display_attributes_.h_total += display_attributes_.is_device_split ? h_blanking : 0; 415 416 display_attributes_.x_dpi = (FLOAT(mode.hdisplay) * 25.4f) / FLOAT(mm_width); 417 display_attributes_.y_dpi = (FLOAT(mode.vdisplay) * 25.4f) / FLOAT(mm_height); 418 419 return kErrorNone; 420} 421 422void HWDeviceDRM::PopulateHWPanelInfo() { 423 hw_panel_info_ = {}; 424 425 snprintf(hw_panel_info_.panel_name, sizeof(hw_panel_info_.panel_name), "%s", 426 connector_info_.panel_name.c_str()); 427 hw_panel_info_.split_info.left_split = display_attributes_.x_pixels; 428 if (display_attributes_.is_device_split) { 429 hw_panel_info_.split_info.left_split = hw_panel_info_.split_info.right_split = 430 display_attributes_.x_pixels / 2; 431 } 432 433 hw_panel_info_.partial_update = 0; 434 hw_panel_info_.left_align = 0; 435 hw_panel_info_.width_align = 0; 436 hw_panel_info_.top_align = 0; 437 hw_panel_info_.height_align = 0; 438 hw_panel_info_.min_roi_width = 0; 439 hw_panel_info_.min_roi_height = 0; 440 hw_panel_info_.needs_roi_merge = 0; 441 hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps; 442 hw_panel_info_.min_fps = 60; 443 hw_panel_info_.max_fps = 60; 444 hw_panel_info_.is_primary_panel = connector_info_.is_primary; 445 hw_panel_info_.is_pluggable = 0; 446 447 if (!default_mode_) { 448 hw_panel_info_.needs_roi_merge = (connector_info_.topology == DRMTopology::DUAL_LM_MERGE); 449 } 450 451 GetHWDisplayPortAndMode(); 452 GetHWPanelMaxBrightness(); 453 454 DLOGI("%s, Panel Interface = %s, Panel Mode = %s, Is Primary = %d", device_name_, 455 interface_str_.c_str(), hw_panel_info_.mode == kModeVideo ? "Video" : "Command", 456 hw_panel_info_.is_primary_panel); 457 DLOGI("Partial Update = %d, Dynamic FPS = %d", hw_panel_info_.partial_update, 458 hw_panel_info_.dynamic_fps); 459 DLOGI("Align: left = %d, width = %d, top = %d, height = %d", hw_panel_info_.left_align, 460 hw_panel_info_.width_align, hw_panel_info_.top_align, hw_panel_info_.height_align); 461 DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d", hw_panel_info_.min_roi_width, 462 hw_panel_info_.min_roi_height, hw_panel_info_.needs_roi_merge); 463 DLOGI("FPS: min = %d, max =%d", hw_panel_info_.min_fps, hw_panel_info_.max_fps); 464 DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split, 465 hw_panel_info_.split_info.right_split); 466} 467 468void HWDeviceDRM::GetHWDisplayPortAndMode() { 469 hw_panel_info_.port = kPortDefault; 470 hw_panel_info_.mode = 471 (connector_info_.panel_mode == sde_drm::DRMPanelMode::VIDEO) ? kModeVideo : kModeCommand; 472 473 if (default_mode_) { 474 return; 475 } 476 477 switch (connector_info_.type) { 478 case DRM_MODE_CONNECTOR_DSI: 479 hw_panel_info_.port = kPortDSI; 480 interface_str_ = "DSI"; 481 break; 482 case DRM_MODE_CONNECTOR_LVDS: 483 hw_panel_info_.port = kPortLVDS; 484 interface_str_ = "LVDS"; 485 break; 486 case DRM_MODE_CONNECTOR_eDP: 487 hw_panel_info_.port = kPortEDP; 488 interface_str_ = "EDP"; 489 break; 490 case DRM_MODE_CONNECTOR_TV: 491 case DRM_MODE_CONNECTOR_HDMIA: 492 case DRM_MODE_CONNECTOR_HDMIB: 493 hw_panel_info_.port = kPortDTV; 494 interface_str_ = "HDMI"; 495 break; 496 case DRM_MODE_CONNECTOR_VIRTUAL: 497 hw_panel_info_.port = kPortWriteBack; 498 interface_str_ = "Virtual"; 499 break; 500 case DRM_MODE_CONNECTOR_DisplayPort: 501 // TODO(user): Add when available 502 interface_str_ = "DisplayPort"; 503 break; 504 } 505 506 return; 507} 508 509void HWDeviceDRM::GetHWPanelMaxBrightness() { 510 char brightness[kMaxStringLength] = {0}; 511 string kMaxBrightnessNode = "/sys/class/backlight/panel0-backlight/max_brightness"; 512 513 hw_panel_info_.panel_max_brightness = 255; 514 int fd = Sys::open_(kMaxBrightnessNode.c_str(), O_RDONLY); 515 if (fd < 0) { 516 DLOGW("Failed to open max brightness node = %s, error = %s", kMaxBrightnessNode.c_str(), 517 strerror(errno)); 518 return; 519 } 520 521 if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) { 522 hw_panel_info_.panel_max_brightness = atoi(brightness); 523 DLOGI("Max brightness level = %d", hw_panel_info_.panel_max_brightness); 524 } else { 525 DLOGW("Failed to read max brightness level. error = %s", strerror(errno)); 526 } 527 528 Sys::close_(fd); 529} 530 531DisplayError HWDeviceDRM::GetActiveConfig(uint32_t *active_config) { 532 *active_config = 0; 533 return kErrorNone; 534} 535 536DisplayError HWDeviceDRM::GetNumDisplayAttributes(uint32_t *count) { 537 *count = 1; 538 return kErrorNone; 539} 540 541DisplayError HWDeviceDRM::GetDisplayAttributes(uint32_t index, 542 HWDisplayAttributes *display_attributes) { 543 *display_attributes = display_attributes_; 544 return kErrorNone; 545} 546 547DisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) { 548 *panel_info = hw_panel_info_; 549 return kErrorNone; 550} 551 552DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) { 553 return kErrorNone; 554} 555 556DisplayError HWDeviceDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) { 557 return kErrorNotSupported; 558} 559 560DisplayError HWDeviceDRM::GetConfigIndex(uint32_t mode, uint32_t *index) { 561 return kErrorNone; 562} 563 564DisplayError HWDeviceDRM::PowerOn() { 565 DTRACE_SCOPED(); 566 return kErrorNone; 567} 568 569DisplayError HWDeviceDRM::PowerOff() { 570 return kErrorNone; 571} 572 573DisplayError HWDeviceDRM::Doze() { 574 return kErrorNone; 575} 576 577DisplayError HWDeviceDRM::DozeSuspend() { 578 return kErrorNone; 579} 580 581DisplayError HWDeviceDRM::Standby() { 582 return kErrorNone; 583} 584 585void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { 586 if (default_mode_) { 587 return; 588 } 589 590 HWLayersInfo &hw_layer_info = hw_layers->info; 591 uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size()); 592 593 for (uint32_t i = 0; i < hw_layer_count; i++) { 594 Layer &layer = hw_layer_info.hw_layers.at(i); 595 LayerBuffer *input_buffer = &layer.input_buffer; 596 HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe; 597 HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe; 598 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session; 599 bool needs_rotation = false; 600 601 for (uint32_t count = 0; count < 2; count++) { 602 HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe; 603 HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count]; 604 605 if (hw_rotate_info->valid) { 606 input_buffer = &hw_rotator_session->output_buffer; 607 needs_rotation = true; 608 } 609 610 uint32_t fb_id = registry_.GetFbId(input_buffer->planes[0].fd); 611 if (pipe_info->valid && fb_id) { 612 uint32_t pipe_id = pipe_info->pipe_id; 613 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha); 614 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ZORDER, pipe_id, pipe_info->z_order); 615 DRMBlendType blending = {}; 616 SetBlending(layer.blending, &blending); 617 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_BLEND_TYPE, pipe_id, blending); 618 DRMRect src = {}; 619 SetRect(pipe_info->src_roi, &src); 620 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_RECT, pipe_id, src); 621 DRMRect dst = {}; 622 SetRect(pipe_info->dst_roi, &dst); 623 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst); 624 625 uint32_t rot_bit_mask = 0; 626 // In case of rotation, rotator handles flips 627 if (!needs_rotation) { 628 if (layer.transform.flip_horizontal) { 629 rot_bit_mask |= UINT32(DRMRotation::FLIP_H); 630 } 631 if (layer.transform.flip_vertical) { 632 rot_bit_mask |= UINT32(DRMRotation::FLIP_V); 633 } 634 } 635 636 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask); 637 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_H_DECIMATION, pipe_id, 638 pipe_info->horizontal_decimation); 639 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_V_DECIMATION, pipe_id, 640 pipe_info->vertical_decimation); 641 uint32_t config = 0; 642 SetSrcConfig(layer.input_buffer, &config); 643 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);; 644 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id); 645 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id); 646 if (!validate && input_buffer->acquire_fence_fd >= 0) { 647 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id, 648 input_buffer->acquire_fence_fd); 649 } 650 if (hw_scale_) { 651 SDEScaler scaler_output = {}; 652 hw_scale_->SetPlaneScaler(pipe_info->scale_data, &scaler_output); 653 // TODO(user): Remove qseed3 and add version check, then send appropriate scaler object 654 if (hw_resource_.has_qseed3) { 655 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id, 656 reinterpret_cast<uint64_t>(&scaler_output.scaler_v2)); 657 } 658 } 659 } 660 } 661 662 // TODO(user): Remove this and enable the one in Init() onces underruns are fixed 663 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); 664 } 665} 666 667DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) { 668 DTRACE_SCOPED(); 669 670 registry_.RegisterCurrent(hw_layers); 671 SetupAtomic(hw_layers, true /* validate */); 672 673 int ret = drm_atomic_intf_->Validate(); 674 if (ret) { 675 DLOGE("%s failed with error %d", __FUNCTION__, ret); 676 return kErrorHardware; 677 } 678 679 return kErrorNone; 680} 681 682DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) { 683 DTRACE_SCOPED(); 684 685 DisplayError err = kErrorNone; 686 registry_.RegisterCurrent(hw_layers); 687 688 if (default_mode_) { 689 err = DefaultCommit(hw_layers); 690 } else { 691 err = AtomicCommit(hw_layers); 692 } 693 694 registry_.UnregisterNext(); 695 696 return err; 697} 698 699DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) { 700 DTRACE_SCOPED(); 701 702 HWLayersInfo &hw_layer_info = hw_layers->info; 703 LayerStack *stack = hw_layer_info.stack; 704 705 stack->retire_fence_fd = -1; 706 for (Layer &layer : hw_layer_info.hw_layers) { 707 layer.input_buffer.release_fence_fd = -1; 708 } 709 710 DRMMaster *master = nullptr; 711 int ret = DRMMaster::GetInstance(&master); 712 if (ret < 0) { 713 DLOGE("Failed to acquire DRMMaster instance"); 714 return kErrorResources; 715 } 716 717 DRMResMgr *res_mgr = nullptr; 718 ret = DRMResMgr::GetInstance(&res_mgr); 719 if (ret < 0) { 720 DLOGE("Failed to acquire DRMResMgr instance"); 721 return kErrorResources; 722 } 723 724 int dev_fd = -1; 725 master->GetHandle(&dev_fd); 726 727 uint32_t connector_id = 0; 728 res_mgr->GetConnectorId(&connector_id); 729 730 uint32_t crtc_id = 0; 731 res_mgr->GetCrtcId(&crtc_id); 732 733 drmModeModeInfo mode; 734 res_mgr->GetMode(&mode); 735 736 uint32_t fb_id = registry_.GetFbId(hw_layer_info.hw_layers.at(0).input_buffer.planes[0].fd); 737 ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id, 738 1 /* num_connectors */, &mode); 739 if (ret < 0) { 740 DLOGE("drmModeSetCrtc failed dev fd %d, fb_id %d, crtc id %d, connector id %d, %s", dev_fd, 741 fb_id, crtc_id, connector_id, strerror(errno)); 742 return kErrorHardware; 743 } 744 745 return kErrorNone; 746} 747 748DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) { 749 DTRACE_SCOPED(); 750 SetupAtomic(hw_layers, false /* validate */); 751 752 int ret = drm_atomic_intf_->Commit(false /* synchronous */); 753 if (ret) { 754 DLOGE("%s failed with error %d", __FUNCTION__, ret); 755 return kErrorHardware; 756 } 757 758 int release_fence = -1; 759 int retire_fence = -1; 760 761 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence); 762 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_GET_RETIRE_FENCE, token_.conn_id, &retire_fence); 763 764 HWLayersInfo &hw_layer_info = hw_layers->info; 765 LayerStack *stack = hw_layer_info.stack; 766 stack->retire_fence_fd = retire_fence; 767 768 for (uint32_t i = 0; i < hw_layer_info.hw_layers.size(); i++) { 769 Layer &layer = hw_layer_info.hw_layers.at(i); 770 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session; 771 if (hw_rotator_session->hw_block_count) { 772 hw_rotator_session->output_buffer.release_fence_fd = Sys::dup_(release_fence); 773 } else { 774 layer.input_buffer.release_fence_fd = Sys::dup_(release_fence); 775 } 776 } 777 778 hw_layer_info.sync_handle = release_fence; 779 780 return kErrorNone; 781} 782 783DisplayError HWDeviceDRM::Flush() { 784 return kErrorNone; 785} 786 787void HWDeviceDRM::SetBlending(const LayerBlending &source, DRMBlendType *target) { 788 switch (source) { 789 case kBlendingPremultiplied: 790 *target = DRMBlendType::PREMULTIPLIED; 791 break; 792 case kBlendingOpaque: 793 *target = DRMBlendType::OPAQUE; 794 break; 795 case kBlendingCoverage: 796 *target = DRMBlendType::COVERAGE; 797 break; 798 default: 799 *target = DRMBlendType::UNDEFINED; 800 } 801} 802 803 804void HWDeviceDRM::SetSrcConfig(const LayerBuffer &input_buffer, uint32_t *config) { 805 if (input_buffer.flags.interlace) { 806 *config |= (0x01 << UINT32(DRMSrcConfig::DEINTERLACE)); 807 } 808} 809 810void HWDeviceDRM::SetRect(const LayerRect &source, DRMRect *target) { 811 target->left = UINT32(source.left); 812 target->top = UINT32(source.top); 813 target->right = UINT32(source.right); 814 target->bottom = UINT32(source.bottom); 815} 816 817bool HWDeviceDRM::EnableHotPlugDetection(int enable) { 818 return true; 819} 820 821void HWDeviceDRM::ResetDisplayParams() {} 822 823DisplayError HWDeviceDRM::SetCursorPosition(HWLayers *hw_layers, int x, int y) { 824 DTRACE_SCOPED(); 825 return kErrorNone; 826} 827 828DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) { 829 struct DRMPPFeatureInfo info = {}; 830 831 for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) { 832 memset(&info, 0, sizeof(struct DRMPPFeatureInfo)); 833 info.id = HWColorManagerDrm::ToDrmFeatureId(i); 834 if (info.id >= sde_drm::kPPFeaturesMax) 835 continue; 836 // use crtc_id_ = 0 since PP features are same across all CRTCs 837 drm_mgr_intf_->GetCrtcPPInfo(0, info); 838 vers->version[i] = HWColorManagerDrm::GetFeatureVersion(info); 839 } 840 return kErrorNone; 841} 842 843DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) { 844 int ret = 0; 845 PPFeatureInfo *feature = NULL; 846 DRMPPFeatureInfo kernel_params = {}; 847 848 while (true) { 849 ret = feature_list->RetrieveNextFeature(&feature); 850 if (ret) 851 break; 852 853 if (feature) { 854 DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_); 855 if (!HWColorManagerDrm::GetDrmFeature[feature->feature_id_]) { 856 DLOGE("GetDrmFeature is not valid for feature %d", feature->feature_id_); 857 continue; 858 } 859 ret = HWColorManagerDrm::GetDrmFeature[feature->feature_id_](*feature, &kernel_params); 860 if (!ret) 861 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params); 862 HWColorManagerDrm::FreeDrmFeatureData(&kernel_params); 863 } 864 } 865 866 // Once all features were consumed, then destroy all feature instance from feature_list, 867 feature_list->Reset(); 868 869 return kErrorNone; 870} 871 872DisplayError HWDeviceDRM::SetVSyncState(bool enable) { 873 return kErrorNone; 874} 875 876void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {} 877 878DisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) { 879 return kErrorNotSupported; 880} 881 882DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) { 883 return kErrorNotSupported; 884} 885 886DisplayError HWDeviceDRM::SetPanelBrightness(int level) { 887 DisplayError err = kErrorNone; 888 char buffer[kMaxSysfsCommandLength] = {0}; 889 890 DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level); 891 int fd = Sys::open_(kBrightnessNode, O_RDWR); 892 if (fd < 0) { 893 DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode, 894 strerror(errno)); 895 return kErrorFileDescriptor; 896 } 897 898 int32_t bytes = snprintf(buffer, kMaxSysfsCommandLength, "%d\n", level); 899 ssize_t ret = Sys::pwrite_(fd, buffer, static_cast<size_t>(bytes), 0); 900 if (ret <= 0) { 901 DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode, 902 strerror(errno)); 903 err = kErrorHardware; 904 } 905 906 Sys::close_(fd); 907 908 return err; 909} 910 911DisplayError HWDeviceDRM::GetPanelBrightness(int *level) { 912 DisplayError err = kErrorNone; 913 char brightness[kMaxStringLength] = {0}; 914 915 if (!level) { 916 DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer."); 917 return kErrorParameters; 918 } 919 920 int fd = Sys::open_(kBrightnessNode, O_RDWR); 921 if (fd < 0) { 922 DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode, 923 strerror(errno)); 924 return kErrorFileDescriptor; 925 } 926 927 if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) { 928 *level = atoi(brightness); 929 DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level); 930 } else { 931 DLOGV_IF(kTagDriverConfig, "Failed to read panel brightness"); 932 err = kErrorHardware; 933 } 934 935 Sys::close_(fd); 936 937 return err; 938} 939 940DisplayError HWDeviceDRM::CachePanelBrightness(int level) { 941 return kErrorNotSupported; 942} 943 944DisplayError HWDeviceDRM::GetHWScanInfo(HWScanInfo *scan_info) { 945 return kErrorNotSupported; 946} 947 948DisplayError HWDeviceDRM::GetVideoFormat(uint32_t config_index, uint32_t *video_format) { 949 return kErrorNotSupported; 950} 951 952DisplayError HWDeviceDRM::GetMaxCEAFormat(uint32_t *max_cea_format) { 953 return kErrorNotSupported; 954} 955 956DisplayError HWDeviceDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) { 957 return kErrorNotSupported; 958} 959 960DisplayError HWDeviceDRM::SetS3DMode(HWS3DMode s3d_mode) { 961 return kErrorNotSupported; 962} 963 964DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) { 965 sde_drm::DRMScalerLUTInfo drm_lut_info = {}; 966 drm_lut_info.cir_lut = lut_info->cir_lut; 967 drm_lut_info.dir_lut = lut_info->dir_lut; 968 drm_lut_info.sep_lut = lut_info->sep_lut; 969 drm_lut_info.cir_lut_size = lut_info->cir_lut_size; 970 drm_lut_info.dir_lut_size = lut_info->dir_lut_size; 971 drm_lut_info.sep_lut_size = lut_info->sep_lut_size; 972 drm_mgr_intf_->SetScalerLUT(drm_lut_info); 973 974 return kErrorNone; 975} 976 977DisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) { 978 if (!hw_resource_.hw_dest_scalar_info.count) { 979 return kErrorNotSupported; 980 } 981 982 if (mixer_attributes.width > display_attributes_.x_pixels || 983 mixer_attributes.height > display_attributes_.y_pixels) { 984 DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d", 985 mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels, 986 display_attributes_.y_pixels); 987 return kErrorNotSupported; 988 } 989 990 uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width; 991 if (display_attributes_.is_device_split) { 992 max_input_width *= 2; 993 } 994 995 if (mixer_attributes.width > max_input_width) { 996 DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width, 997 max_input_width); 998 return kErrorNotSupported; 999 } 1000 1001 float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height); 1002 float display_aspect_ratio = 1003 FLOAT(display_attributes_.x_pixels) / FLOAT(display_attributes_.y_pixels); 1004 1005 if (display_aspect_ratio != mixer_aspect_ratio) { 1006 DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width, 1007 mixer_attributes.height, display_attributes_.x_pixels, display_attributes_.y_pixels); 1008 return kErrorNotSupported; 1009 } 1010 1011 float scale_x = FLOAT(display_attributes_.x_pixels) / FLOAT(mixer_attributes.width); 1012 float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height); 1013 float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up; 1014 if (scale_x > max_scale_up || scale_y > max_scale_up) { 1015 DLOGW( 1016 "Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f " 1017 "max_scale_up %f", 1018 scale_x, scale_y, max_scale_up); 1019 return kErrorNotSupported; 1020 } 1021 1022 float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width); 1023 1024 mixer_attributes_ = mixer_attributes; 1025 mixer_attributes_.split_left = mixer_attributes_.width; 1026 if (display_attributes_.is_device_split) { 1027 mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio); 1028 } 1029 1030 return kErrorNone; 1031} 1032 1033DisplayError HWDeviceDRM::GetMixerAttributes(HWMixerAttributes *mixer_attributes) { 1034 if (!mixer_attributes) { 1035 return kErrorParameters; 1036 } 1037 1038 mixer_attributes_.width = display_attributes_.x_pixels; 1039 mixer_attributes_.height = display_attributes_.y_pixels; 1040 mixer_attributes_.split_left = display_attributes_.is_device_split 1041 ? hw_panel_info_.split_info.left_split 1042 : mixer_attributes_.width; 1043 *mixer_attributes = mixer_attributes_; 1044 1045 return kErrorNone; 1046} 1047 1048void HWDeviceDRM::UpdateMixerAttributes() { 1049 mixer_attributes_.width = display_attributes_.x_pixels; 1050 mixer_attributes_.height = display_attributes_.y_pixels; 1051 mixer_attributes_.split_left = display_attributes_.is_device_split 1052 ? hw_panel_info_.split_info.left_split 1053 : mixer_attributes_.width; 1054} 1055 1056} // namespace sdm 1057