• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2017-2018, 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 <drm/sde_drm.h>
52 #include <private/color_params.h>
53 #include <utils/rect.h>
54 
55 #include <algorithm>
56 #include <string>
57 #include <unordered_map>
58 #include <utility>
59 #include <vector>
60 #include <limits>
61 
62 #include "hw_device_drm.h"
63 #include "hw_info_interface.h"
64 #include "hw_color_manager_drm.h"
65 
66 #define __CLASS__ "HWDeviceDRM"
67 
68 #ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
69 #define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
70 #endif
71 #ifndef DRM_FORMAT_MOD_QCOM_DX
72 #define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
73 #endif
74 #ifndef DRM_FORMAT_MOD_QCOM_TIGHT
75 #define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
76 #endif
77 
78 using std::string;
79 using std::to_string;
80 using std::fstream;
81 using std::unordered_map;
82 using drm_utils::DRMMaster;
83 using drm_utils::DRMResMgr;
84 using drm_utils::DRMLibLoader;
85 using drm_utils::DRMBuffer;
86 using sde_drm::GetDRMManager;
87 using sde_drm::DestroyDRMManager;
88 using sde_drm::DRMDisplayType;
89 using sde_drm::DRMDisplayToken;
90 using sde_drm::DRMConnectorInfo;
91 using sde_drm::DRMPPFeatureInfo;
92 using sde_drm::DRMRect;
93 using sde_drm::DRMRotation;
94 using sde_drm::DRMBlendType;
95 using sde_drm::DRMSrcConfig;
96 using sde_drm::DRMOps;
97 using sde_drm::DRMTopology;
98 using sde_drm::DRMPowerMode;
99 using sde_drm::DRMSecureMode;
100 using sde_drm::DRMSecurityLevel;
101 using sde_drm::DRMCscType;
102 using sde_drm::DRMMultiRectMode;
103 
104 namespace sdm {
105 
GetDRMFormat(LayerBufferFormat format,uint32_t * drm_format,uint64_t * drm_format_modifier)106 static void GetDRMFormat(LayerBufferFormat format, uint32_t *drm_format,
107                          uint64_t *drm_format_modifier) {
108   switch (format) {
109     case kFormatRGBA8888:
110       *drm_format = DRM_FORMAT_ABGR8888;
111       break;
112     case kFormatRGBA8888Ubwc:
113       *drm_format = DRM_FORMAT_ABGR8888;
114       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
115       break;
116     case kFormatRGBA5551:
117       *drm_format = DRM_FORMAT_ABGR1555;
118       break;
119     case kFormatRGBA4444:
120       *drm_format = DRM_FORMAT_ABGR4444;
121       break;
122     case kFormatBGRA8888:
123       *drm_format = DRM_FORMAT_ARGB8888;
124       break;
125     case kFormatRGBX8888:
126       *drm_format = DRM_FORMAT_XBGR8888;
127       break;
128     case kFormatRGBX8888Ubwc:
129       *drm_format = DRM_FORMAT_XBGR8888;
130       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
131       break;
132     case kFormatBGRX8888:
133       *drm_format = DRM_FORMAT_XRGB8888;
134       break;
135     case kFormatRGB888:
136       *drm_format = DRM_FORMAT_BGR888;
137       break;
138     case kFormatRGB565:
139       *drm_format = DRM_FORMAT_BGR565;
140       break;
141     case kFormatBGR565:
142       *drm_format = DRM_FORMAT_RGB565;
143       break;
144     case kFormatBGR565Ubwc:
145       *drm_format = DRM_FORMAT_BGR565;
146       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
147       break;
148     case kFormatRGBA1010102:
149       *drm_format = DRM_FORMAT_ABGR2101010;
150       break;
151     case kFormatRGBA1010102Ubwc:
152       *drm_format = DRM_FORMAT_ABGR2101010;
153       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
154       break;
155     case kFormatARGB2101010:
156       *drm_format = DRM_FORMAT_BGRA1010102;
157       break;
158     case kFormatRGBX1010102:
159       *drm_format = DRM_FORMAT_XBGR2101010;
160       break;
161     case kFormatRGBX1010102Ubwc:
162       *drm_format = DRM_FORMAT_XBGR2101010;
163       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
164       break;
165     case kFormatXRGB2101010:
166       *drm_format = DRM_FORMAT_BGRX1010102;
167       break;
168     case kFormatBGRA1010102:
169       *drm_format = DRM_FORMAT_ARGB2101010;
170       break;
171     case kFormatABGR2101010:
172       *drm_format = DRM_FORMAT_RGBA1010102;
173       break;
174     case kFormatBGRX1010102:
175       *drm_format = DRM_FORMAT_XRGB2101010;
176       break;
177     case kFormatXBGR2101010:
178       *drm_format = DRM_FORMAT_RGBX1010102;
179       break;
180     case kFormatYCbCr420SemiPlanar:
181       *drm_format = DRM_FORMAT_NV12;
182       break;
183     case kFormatYCbCr420SemiPlanarVenus:
184       *drm_format = DRM_FORMAT_NV12;
185       break;
186     case kFormatYCbCr420SPVenusUbwc:
187       *drm_format = DRM_FORMAT_NV12;
188       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
189       break;
190     case kFormatYCrCb420SemiPlanar:
191       *drm_format = DRM_FORMAT_NV21;
192       break;
193     case kFormatYCrCb420SemiPlanarVenus:
194       *drm_format = DRM_FORMAT_NV21;
195       break;
196     case kFormatYCbCr420P010:
197     case kFormatYCbCr420P010Venus:
198       *drm_format = DRM_FORMAT_NV12;
199       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
200       break;
201     case kFormatYCbCr420P010Ubwc:
202       *drm_format = DRM_FORMAT_NV12;
203       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
204         DRM_FORMAT_MOD_QCOM_DX;
205       break;
206     case kFormatYCbCr420TP10Ubwc:
207       *drm_format = DRM_FORMAT_NV12;
208       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
209         DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
210       break;
211     case kFormatYCbCr422H2V1SemiPlanar:
212       *drm_format = DRM_FORMAT_NV16;
213       break;
214     case kFormatYCrCb422H2V1SemiPlanar:
215       *drm_format = DRM_FORMAT_NV61;
216       break;
217     case kFormatYCrCb420PlanarStride16:
218       *drm_format = DRM_FORMAT_YVU420;
219       break;
220     default:
221       DLOGW("Unsupported format %s", GetFormatString(format));
222   }
223 }
224 
225 class FrameBufferObject : public LayerBufferObject {
226  public:
FrameBufferObject(uint32_t fb_id)227   explicit FrameBufferObject(uint32_t fb_id) : fb_id_(fb_id) {
228   }
229 
~FrameBufferObject()230   ~FrameBufferObject() {
231     DRMMaster *master;
232     DRMMaster::GetInstance(&master);
233     int ret = master->RemoveFbId(fb_id_);
234     if (ret < 0) {
235       DLOGE("Removing fb_id %d failed with error %d", fb_id_, errno);
236     }
237   }
GetFbId()238   uint32_t GetFbId() { return fb_id_; }
239 
240  private:
241   uint32_t fb_id_;
242 };
243 
Registry(BufferAllocator * buffer_allocator)244 HWDeviceDRM::Registry::Registry(BufferAllocator *buffer_allocator) :
245   buffer_allocator_(buffer_allocator) {
246   int value = 0;
247   if (Debug::GetProperty(DISABLE_FBID_CACHE, &value) == kErrorNone) {
248     disable_fbid_cache_ = (value == 1);
249   }
250 }
251 
Register(HWLayers * hw_layers)252 void HWDeviceDRM::Registry::Register(HWLayers *hw_layers) {
253   HWLayersInfo &hw_layer_info = hw_layers->info;
254   uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
255 
256   for (uint32_t i = 0; i < hw_layer_count; i++) {
257     Layer &layer = hw_layer_info.hw_layers.at(i);
258     LayerBuffer *input_buffer = &layer.input_buffer;
259     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
260     HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
261     fbid_cache_limit_ = input_buffer->flags.video ? VIDEO_FBID_LIMIT : UI_FBID_LIMIT;
262 
263     if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) {
264       input_buffer = &hw_rotator_session->output_buffer;
265       fbid_cache_limit_ = ROTATOR_FBID_LIMIT;
266     }
267 
268     MapBufferToFbId(&layer, input_buffer);
269   }
270 }
271 
CreateFbId(LayerBuffer * buffer,uint32_t * fb_id)272 int HWDeviceDRM::Registry::CreateFbId(LayerBuffer *buffer, uint32_t *fb_id) {
273   DRMMaster *master = nullptr;
274   DRMMaster::GetInstance(&master);
275   int ret = -1;
276 
277   if (!master) {
278     DLOGE("Failed to acquire DRM Master instance");
279     return ret;
280   }
281 
282   DRMBuffer layout{};
283   AllocatedBufferInfo buf_info{};
284   buf_info.fd = layout.fd = buffer->planes[0].fd;
285   buf_info.aligned_width = layout.width = buffer->width;
286   buf_info.aligned_height = layout.height = buffer->height;
287   buf_info.format = buffer->format;
288   GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
289   buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset, &layout.num_planes);
290   ret = master->CreateFbId(layout, fb_id);
291   if (ret < 0) {
292     DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
293         layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0], errno);
294   }
295 
296   return ret;
297 }
298 
MapBufferToFbId(Layer * layer,LayerBuffer * buffer)299 void HWDeviceDRM::Registry::MapBufferToFbId(Layer* layer, LayerBuffer* buffer) {
300   if (buffer->planes[0].fd < 0) {
301     return;
302   }
303 
304   uint64_t handle_id = buffer->handle_id;
305   if (!handle_id || disable_fbid_cache_) {
306     // In legacy path, clear fb_id map in each frame.
307     layer->buffer_map->buffer_map.clear();
308   } else {
309 
310     if (layer->buffer_map->buffer_map.find(handle_id) != layer->buffer_map->buffer_map.end()) {
311       // Found fb_id for given handle_id key
312       return;
313     }
314 
315     if (layer->buffer_map->buffer_map.size() >= fbid_cache_limit_) {
316       // Clear fb_id map, if the size reaches cache limit.
317       layer->buffer_map->buffer_map.clear();
318     }
319   }
320 
321   uint32_t fb_id = 0;
322   if (CreateFbId(buffer, &fb_id) >= 0) {
323     // Create and cache the fb_id in map
324     layer->buffer_map->buffer_map[handle_id] = std::make_shared<FrameBufferObject>(fb_id);
325   }
326 }
327 
MapOutputBufferToFbId(LayerBuffer * output_buffer)328 void HWDeviceDRM::Registry::MapOutputBufferToFbId(LayerBuffer *output_buffer) {
329   if (output_buffer->planes[0].fd < 0) {
330     return;
331   }
332 
333   uint64_t handle_id = output_buffer->handle_id;
334   if (!handle_id || disable_fbid_cache_) {
335     // In legacy path, clear output buffer map in each frame.
336     output_buffer_map_.clear();
337   } else {
338 
339     if (output_buffer_map_.find(handle_id) != output_buffer_map_.end()) {
340       return;
341     }
342 
343     if (output_buffer_map_.size() >= UI_FBID_LIMIT) {
344       // Clear output buffer map, if the size reaches cache limit.
345       output_buffer_map_.clear();
346     }
347   }
348 
349   uint32_t fb_id = 0;
350   if (CreateFbId(output_buffer, &fb_id) >= 0) {
351     output_buffer_map_[handle_id] = std::make_shared<FrameBufferObject>(fb_id);
352   }
353 }
354 
Clear()355 void HWDeviceDRM::Registry::Clear() {
356   output_buffer_map_.clear();
357 }
358 
GetFbId(Layer * layer,uint64_t handle_id)359 uint32_t HWDeviceDRM::Registry::GetFbId(Layer *layer, uint64_t handle_id) {
360   auto it = layer->buffer_map->buffer_map.find(handle_id);
361   if (it != layer->buffer_map->buffer_map.end()) {
362     FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
363     return fb_obj->GetFbId();
364   }
365 
366   return 0;
367 }
368 
GetOutputFbId(uint64_t handle_id)369 uint32_t HWDeviceDRM::Registry::GetOutputFbId(uint64_t handle_id) {
370   auto it = output_buffer_map_.find(handle_id);
371   if (it != output_buffer_map_.end()) {
372     FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
373     return fb_obj->GetFbId();
374   }
375 
376   return 0;
377 }
378 
HWDeviceDRM(BufferSyncHandler * buffer_sync_handler,BufferAllocator * buffer_allocator,HWInfoInterface * hw_info_intf)379 HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
380                          HWInfoInterface *hw_info_intf)
381     : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
382       registry_(buffer_allocator) {
383   hw_info_intf_ = hw_info_intf;
384 }
385 
Init()386 DisplayError HWDeviceDRM::Init() {
387   DRMMaster *drm_master = {};
388   DRMMaster::GetInstance(&drm_master);
389   drm_master->GetHandle(&dev_fd_);
390   DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_);
391 
392   if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
393     DLOGE("RegisterDisplay failed for %s", device_name_);
394     return kErrorResources;
395   }
396 
397   drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
398   drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
399   hw_info_intf_->GetHWResourceInfo(&hw_resource_);
400 
401   InitializeConfigs();
402   PopulateHWPanelInfo();
403   UpdateMixerAttributes();
404 
405   // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
406   if (hw_resource_.has_qseed3) {
407     hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
408   }
409 
410   return kErrorNone;
411 }
412 
Deinit()413 DisplayError HWDeviceDRM::Deinit() {
414   DisplayError err = kErrorNone;
415   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, 0);
416   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
417   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, nullptr);
418   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
419   int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes */);
420   if (ret) {
421     DLOGE("Commit failed with error: %d", ret);
422     err = kErrorHardware;
423   }
424 
425   delete hw_scale_;
426   registry_.Clear();
427   display_attributes_ = {};
428   drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
429   drm_atomic_intf_ = {};
430   drm_mgr_intf_->UnregisterDisplay(token_);
431   return err;
432 }
433 
InitializeConfigs()434 void HWDeviceDRM::InitializeConfigs() {
435   current_mode_index_ = 0;
436   // Update current mode with preferred mode
437   for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
438       if (connector_info_.modes[mode_index].mode.type & DRM_MODE_TYPE_PREFERRED) {
439         current_mode_index_ = mode_index;
440         break;
441       }
442   }
443 
444   display_attributes_.resize(connector_info_.modes.size());
445 
446   uint32_t width = connector_info_.modes[current_mode_index_].mode.hdisplay;
447   uint32_t height = connector_info_.modes[current_mode_index_].mode.vdisplay;
448   for (uint32_t i = 0; i < connector_info_.modes.size(); i++) {
449     auto &mode = connector_info_.modes[i].mode;
450     if (mode.hdisplay != width || mode.vdisplay != height) {
451       resolution_switch_enabled_ = true;
452     }
453     PopulateDisplayAttributes(i);
454   }
455 }
456 
PopulateDisplayAttributes(uint32_t index)457 DisplayError HWDeviceDRM::PopulateDisplayAttributes(uint32_t index) {
458   drmModeModeInfo mode = {};
459   uint32_t mm_width = 0;
460   uint32_t mm_height = 0;
461   DRMTopology topology = DRMTopology::SINGLE_LM;
462 
463   if (default_mode_) {
464     DRMResMgr *res_mgr = nullptr;
465     int ret = DRMResMgr::GetInstance(&res_mgr);
466     if (ret < 0) {
467       DLOGE("Failed to acquire DRMResMgr instance");
468       return kErrorResources;
469     }
470 
471     res_mgr->GetMode(&mode);
472     res_mgr->GetDisplayDimInMM(&mm_width, &mm_height);
473   } else {
474     mode = connector_info_.modes[index].mode;
475     mm_width = connector_info_.mmWidth;
476     mm_height = connector_info_.mmHeight;
477     topology = connector_info_.modes[index].topology;
478   }
479 
480   display_attributes_[index].x_pixels = mode.hdisplay;
481   display_attributes_[index].y_pixels = mode.vdisplay;
482   display_attributes_[index].fps = mode.vrefresh;
483   display_attributes_[index].vsync_period_ns =
484     UINT32(1000000000L / display_attributes_[index].fps);
485 
486   /*
487               Active                 Front           Sync           Back
488               Region                 Porch                          Porch
489      <-----------------------><----------------><-------------><-------------->
490      <----- [hv]display ----->
491      <------------- [hv]sync_start ------------>
492      <--------------------- [hv]sync_end --------------------->
493      <-------------------------------- [hv]total ----------------------------->
494    */
495 
496   display_attributes_[index].v_front_porch = mode.vsync_start - mode.vdisplay;
497   display_attributes_[index].v_pulse_width = mode.vsync_end - mode.vsync_start;
498   display_attributes_[index].v_back_porch = mode.vtotal - mode.vsync_end;
499   display_attributes_[index].v_total = mode.vtotal;
500   display_attributes_[index].h_total = mode.htotal;
501   display_attributes_[index].is_device_split =
502       (topology == DRMTopology::DUAL_LM || topology == DRMTopology::DUAL_LM_MERGE ||
503        topology == DRMTopology::DUAL_LM_MERGE_DSC || topology == DRMTopology::DUAL_LM_DSC ||
504        topology == DRMTopology::DUAL_LM_DSCMERGE);
505   display_attributes_[index].clock_khz = mode.clock;
506 
507   // If driver doesn't return panel width/height information, default to 320 dpi
508   if (INT(mm_width) <= 0 || INT(mm_height) <= 0) {
509     mm_width  = UINT32(((FLOAT(mode.hdisplay) * 25.4f) / 320.0f) + 0.5f);
510     mm_height = UINT32(((FLOAT(mode.vdisplay) * 25.4f) / 320.0f) + 0.5f);
511     DLOGW("Driver doesn't report panel physical width and height - defaulting to 320dpi");
512   }
513 
514   display_attributes_[index].x_dpi = (FLOAT(mode.hdisplay) * 25.4f) / FLOAT(mm_width);
515   display_attributes_[index].y_dpi = (FLOAT(mode.vdisplay) * 25.4f) / FLOAT(mm_height);
516   SetTopology(topology, &display_attributes_[index].topology);
517 
518   DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
519         " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
520         index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
521         display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
522         display_attributes_[index].fps, display_attributes_[index].is_device_split,
523         display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
524         display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
525         display_attributes_[index].h_total, display_attributes_[index].clock_khz,
526         display_attributes_[index].topology);
527 
528   return kErrorNone;
529 }
530 
PopulateHWPanelInfo()531 void HWDeviceDRM::PopulateHWPanelInfo() {
532   hw_panel_info_ = {};
533 
534   snprintf(hw_panel_info_.panel_name, sizeof(hw_panel_info_.panel_name), "%s",
535            connector_info_.panel_name.c_str());
536 
537   uint32_t index = current_mode_index_;
538   hw_panel_info_.split_info.left_split = display_attributes_[index].x_pixels;
539   if (display_attributes_[index].is_device_split) {
540     hw_panel_info_.split_info.left_split = hw_panel_info_.split_info.right_split =
541         display_attributes_[index].x_pixels / 2;
542   }
543 
544   hw_panel_info_.partial_update = connector_info_.modes[index].num_roi;
545   hw_panel_info_.left_roi_count = UINT32(connector_info_.modes[index].num_roi);
546   hw_panel_info_.right_roi_count = UINT32(connector_info_.modes[index].num_roi);
547   hw_panel_info_.left_align = connector_info_.modes[index].xstart;
548   hw_panel_info_.top_align = connector_info_.modes[index].ystart;
549   hw_panel_info_.width_align = connector_info_.modes[index].walign;
550   hw_panel_info_.height_align = connector_info_.modes[index].halign;
551   hw_panel_info_.min_roi_width = connector_info_.modes[index].wmin;
552   hw_panel_info_.min_roi_height = connector_info_.modes[index].hmin;
553   hw_panel_info_.needs_roi_merge = connector_info_.modes[index].roi_merge;
554   hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
555   drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
556   if (hw_panel_info_.dynamic_fps) {
557     uint32_t min_fps = current_mode.vrefresh;
558     uint32_t max_fps = current_mode.vrefresh;
559     for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
560       if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
561           (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay)) {
562         if (min_fps > connector_info_.modes[mode_index].mode.vrefresh)  {
563           min_fps = connector_info_.modes[mode_index].mode.vrefresh;
564         }
565         if (max_fps < connector_info_.modes[mode_index].mode.vrefresh)  {
566           max_fps = connector_info_.modes[mode_index].mode.vrefresh;
567         }
568       }
569     }
570     hw_panel_info_.min_fps = min_fps;
571     hw_panel_info_.max_fps = max_fps;
572   } else {
573     hw_panel_info_.min_fps = current_mode.vrefresh;
574     hw_panel_info_.max_fps = current_mode.vrefresh;
575   }
576 
577   hw_panel_info_.is_primary_panel = connector_info_.is_primary;
578   hw_panel_info_.is_pluggable = 0;
579   hw_panel_info_.hdr_enabled = connector_info_.panel_hdr_prop.hdr_enabled;
580   hw_panel_info_.peak_luminance = connector_info_.panel_hdr_prop.peak_brightness;
581   hw_panel_info_.blackness_level = connector_info_.panel_hdr_prop.blackness_level;
582   hw_panel_info_.primaries.white_point[0] = connector_info_.panel_hdr_prop.display_primaries[0];
583   hw_panel_info_.primaries.white_point[1] = connector_info_.panel_hdr_prop.display_primaries[1];
584   hw_panel_info_.primaries.red[0] = connector_info_.panel_hdr_prop.display_primaries[2];
585   hw_panel_info_.primaries.red[1] = connector_info_.panel_hdr_prop.display_primaries[3];
586   hw_panel_info_.primaries.green[0] = connector_info_.panel_hdr_prop.display_primaries[4];
587   hw_panel_info_.primaries.green[1] = connector_info_.panel_hdr_prop.display_primaries[5];
588   hw_panel_info_.primaries.blue[0] = connector_info_.panel_hdr_prop.display_primaries[6];
589   hw_panel_info_.primaries.blue[1] = connector_info_.panel_hdr_prop.display_primaries[7];
590   hw_panel_info_.transfer_time_us = connector_info_.transfer_time_us;
591 
592   // no supprt for 90 rotation only flips or 180 supported
593   hw_panel_info_.panel_orientation.rotation = 0;
594   hw_panel_info_.panel_orientation.flip_horizontal =
595     (connector_info_.panel_orientation == DRMRotation::FLIP_H) ||
596     (connector_info_.panel_orientation == DRMRotation::ROT_180);
597   hw_panel_info_.panel_orientation.flip_vertical =
598     (connector_info_.panel_orientation == DRMRotation::FLIP_V) ||
599     (connector_info_.panel_orientation == DRMRotation::ROT_180);
600 
601   GetHWDisplayPortAndMode();
602   GetHWPanelMaxBrightness();
603 
604   DLOGI("%s, Panel Interface = %s, Panel Mode = %s, Is Primary = %d", device_name_,
605         interface_str_.c_str(), hw_panel_info_.mode == kModeVideo ? "Video" : "Command",
606         hw_panel_info_.is_primary_panel);
607   DLOGI("Partial Update = %d, Dynamic FPS = %d, HDR Panel = %d", hw_panel_info_.partial_update,
608         hw_panel_info_.dynamic_fps, hw_panel_info_.hdr_enabled);
609   DLOGI("Align: left = %d, width = %d, top = %d, height = %d", hw_panel_info_.left_align,
610         hw_panel_info_.width_align, hw_panel_info_.top_align, hw_panel_info_.height_align);
611   DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d", hw_panel_info_.min_roi_width,
612         hw_panel_info_.min_roi_height, hw_panel_info_.needs_roi_merge);
613   DLOGI("FPS: min = %d, max = %d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
614   DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
615         hw_panel_info_.split_info.right_split);
616   DLOGI("Panel Transfer time = %d us", hw_panel_info_.transfer_time_us);
617 }
618 
GetHWDisplayPortAndMode()619 void HWDeviceDRM::GetHWDisplayPortAndMode() {
620   hw_panel_info_.port = kPortDefault;
621   hw_panel_info_.mode =
622       (connector_info_.panel_mode == sde_drm::DRMPanelMode::VIDEO) ? kModeVideo : kModeCommand;
623 
624   if (default_mode_) {
625     return;
626   }
627 
628   switch (connector_info_.type) {
629     case DRM_MODE_CONNECTOR_DSI:
630       hw_panel_info_.port = kPortDSI;
631       interface_str_ = "DSI";
632       break;
633     case DRM_MODE_CONNECTOR_LVDS:
634       hw_panel_info_.port = kPortLVDS;
635       interface_str_ = "LVDS";
636       break;
637     case DRM_MODE_CONNECTOR_eDP:
638       hw_panel_info_.port = kPortEDP;
639       interface_str_ = "EDP";
640       break;
641     case DRM_MODE_CONNECTOR_TV:
642     case DRM_MODE_CONNECTOR_HDMIA:
643     case DRM_MODE_CONNECTOR_HDMIB:
644       hw_panel_info_.port = kPortDTV;
645       interface_str_ = "HDMI";
646       break;
647     case DRM_MODE_CONNECTOR_VIRTUAL:
648       hw_panel_info_.port = kPortWriteBack;
649       interface_str_ = "Virtual";
650       break;
651     case DRM_MODE_CONNECTOR_DisplayPort:
652       // TODO(user): Add when available
653       interface_str_ = "DisplayPort";
654       break;
655   }
656 
657   return;
658 }
659 
GetHWPanelMaxBrightness()660 void HWDeviceDRM::GetHWPanelMaxBrightness() {
661   char brightness[kMaxStringLength] = {0};
662   string kMaxBrightnessNode = "/sys/class/backlight/panel0-backlight/max_brightness";
663 
664   hw_panel_info_.panel_max_brightness = 255;
665   int fd = Sys::open_(kMaxBrightnessNode.c_str(), O_RDONLY);
666   if (fd < 0) {
667     DLOGW("Failed to open max brightness node = %s, error = %s", kMaxBrightnessNode.c_str(),
668           strerror(errno));
669     return;
670   }
671 
672   if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
673     hw_panel_info_.panel_max_brightness = atoi(brightness);
674     DLOGI("Max brightness level = %d", hw_panel_info_.panel_max_brightness);
675   } else {
676     DLOGW("Failed to read max brightness level. error = %s", strerror(errno));
677   }
678 
679   Sys::close_(fd);
680 }
681 
GetActiveConfig(uint32_t * active_config)682 DisplayError HWDeviceDRM::GetActiveConfig(uint32_t *active_config) {
683   if (IsResolutionSwitchEnabled()) {
684     *active_config = current_mode_index_;
685   } else {
686     *active_config = 0;
687   }
688   return kErrorNone;
689 }
690 
GetNumDisplayAttributes(uint32_t * count)691 DisplayError HWDeviceDRM::GetNumDisplayAttributes(uint32_t *count) {
692   if (IsResolutionSwitchEnabled()) {
693     *count = UINT32(display_attributes_.size());
694     if (*count <= 0) {
695        return kErrorHardware;
696     }
697   } else {
698     *count = 1;
699   }
700   return kErrorNone;
701 }
702 
GetDisplayAttributes(uint32_t index,HWDisplayAttributes * display_attributes)703 DisplayError HWDeviceDRM::GetDisplayAttributes(uint32_t index,
704                                                HWDisplayAttributes *display_attributes) {
705   if (index >= display_attributes_.size()) {
706     return kErrorParameters;
707   }
708   if (IsResolutionSwitchEnabled()) {
709     *display_attributes = display_attributes_[index];
710   } else {
711     *display_attributes = display_attributes_[current_mode_index_];
712   }
713   return kErrorNone;
714 }
715 
GetHWPanelInfo(HWPanelInfo * panel_info)716 DisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) {
717   *panel_info = hw_panel_info_;
718   return kErrorNone;
719 }
720 
SetDisplayAttributes(uint32_t index)721 DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
722   if (!IsResolutionSwitchEnabled()) {
723     return kErrorNotSupported;
724   }
725 
726   if (index >= display_attributes_.size()) {
727     DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size()));
728     return kErrorParameters;
729   }
730 
731   current_mode_index_ = index;
732   PopulateHWPanelInfo();
733   UpdateMixerAttributes();
734   update_mode_ = true;
735 
736   DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
737         " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
738         index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
739         display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
740         display_attributes_[index].fps, display_attributes_[index].is_device_split,
741         display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
742         display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
743         display_attributes_[index].h_total, display_attributes_[index].clock_khz,
744         display_attributes_[index].topology);
745 
746   return kErrorNone;
747 }
748 
SetDisplayAttributes(const HWDisplayAttributes & display_attributes)749 DisplayError HWDeviceDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
750   return kErrorNotSupported;
751 }
752 
GetConfigIndex(char * mode,uint32_t * index)753 DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) {
754   return kErrorNone;
755 }
756 
PowerOn(int * release_fence)757 DisplayError HWDeviceDRM::PowerOn(int *release_fence) {
758   update_mode_ = true;
759   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
760   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
761   int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
762   if (ret) {
763     DLOGE("Failed with error: %d", ret);
764     return kErrorHardware;
765   }
766   drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
767 
768   return kErrorNone;
769 }
770 
PowerOff()771 DisplayError HWDeviceDRM::PowerOff() {
772   DTRACE_SCOPED();
773   if (!drm_atomic_intf_) {
774     DLOGE("DRM Atomic Interface is null!");
775     return kErrorUndefined;
776   }
777 
778   SetFullROI();
779   drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
780   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
781   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
782   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
783   int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes */);
784   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
785   if (cwb_config_.enabled) {
786     drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, cwb_config_.token.conn_id, 0);
787     drm_mgr_intf_->UnregisterDisplay(cwb_config_.token);
788     cwb_config_.enabled = false;
789     registry_.Clear();
790   }
791   if (ret) {
792     DLOGE("Failed with error: %d", ret);
793     return kErrorHardware;
794   }
795 
796   return kErrorNone;
797 }
798 
Doze(int * release_fence)799 DisplayError HWDeviceDRM::Doze(int *release_fence) {
800   DTRACE_SCOPED();
801   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
802   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
803   int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
804   if (ret) {
805     DLOGE("Failed with error: %d", ret);
806     return kErrorHardware;
807   }
808 
809   drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
810 
811   return kErrorNone;
812 }
813 
DozeSuspend(int * release_fence)814 DisplayError HWDeviceDRM::DozeSuspend(int *release_fence) {
815   DTRACE_SCOPED();
816   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
817   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
818                             DRMPowerMode::DOZE_SUSPEND);
819   int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
820   if (ret) {
821     DLOGE("Failed with error: %d", ret);
822     return kErrorHardware;
823   }
824 
825   drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
826 
827   return kErrorNone;
828 }
829 
Standby()830 DisplayError HWDeviceDRM::Standby() {
831   return kErrorNone;
832 }
833 
SetupAtomic(HWLayers * hw_layers,bool validate)834 void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) {
835   if (default_mode_) {
836     return;
837   }
838 
839   HWLayersInfo &hw_layer_info = hw_layers->info;
840   uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
841   HWQosData &qos_data = hw_layers->qos_data;
842   DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
843   uint32_t index = current_mode_index_;
844   drmModeModeInfo current_mode = connector_info_.modes[index].mode;
845 
846   solid_fills_.clear();
847 
848   // TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
849   if (hw_panel_info_.partial_update) {
850     const int kNumMaxROIs = 4;
851     DRMRect crtc_rects[kNumMaxROIs] = {{0, 0, mixer_attributes_.width, mixer_attributes_.height}};
852     DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_[index].x_pixels,
853                                         display_attributes_[index].y_pixels}};
854 
855     for (uint32_t i = 0; i < hw_layer_info.left_frame_roi.size(); i++) {
856       auto &roi = hw_layer_info.left_frame_roi.at(i);
857       // TODO(user): In multi PU, stitch ROIs vertically adjacent and upate plane destination
858       crtc_rects[i].left = UINT32(roi.left);
859       crtc_rects[i].right = UINT32(roi.right);
860       crtc_rects[i].top = UINT32(roi.top);
861       crtc_rects[i].bottom = UINT32(roi.bottom);
862       // TODO(user): In Dest scaler + PU, populate from HWDestScaleInfo->panel_roi
863       // TODO(user): panel_roi need to be made as a vector in HWLayersInfo and
864       // needs to be removed from  HWDestScaleInfo.
865       conn_rects[i].left = UINT32(roi.left);
866       conn_rects[i].right = UINT32(roi.right);
867       conn_rects[i].top = UINT32(roi.top);
868       conn_rects[i].bottom = UINT32(roi.bottom);
869     }
870 
871     uint32_t num_rects = std::max(1u, static_cast<uint32_t>(hw_layer_info.left_frame_roi.size()));
872     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id,
873                               num_rects, crtc_rects);
874     drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id,
875                               num_rects, conn_rects);
876   }
877 
878   for (uint32_t i = 0; i < hw_layer_count; i++) {
879     Layer &layer = hw_layer_info.hw_layers.at(i);
880     LayerBuffer *input_buffer = &layer.input_buffer;
881     HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
882     HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
883     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
884 
885     if (hw_layers->config[i].use_solidfill_stage) {
886       hw_layers->config[i].hw_solidfill_stage.solid_fill_info = layer.solid_fill_info;
887       AddSolidfillStage(hw_layers->config[i].hw_solidfill_stage, layer.plane_alpha);
888       continue;
889     }
890 
891     for (uint32_t count = 0; count < 2; count++) {
892       HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
893       HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
894 
895       if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) {
896         input_buffer = &hw_rotator_session->output_buffer;
897       }
898 
899       uint32_t fb_id = registry_.GetFbId(&layer, input_buffer->handle_id);
900 
901       if (pipe_info->valid && fb_id) {
902         uint32_t pipe_id = pipe_info->pipe_id;
903         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha);
904         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ZORDER, pipe_id, pipe_info->z_order);
905         DRMBlendType blending = {};
906         SetBlending(layer.blending, &blending);
907         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_BLEND_TYPE, pipe_id, blending);
908         DRMRect src = {};
909         SetRect(pipe_info->src_roi, &src);
910         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_RECT, pipe_id, src);
911         DRMRect rot_dst = {0, 0, 0, 0};
912         if (hw_rotator_session->mode == kRotatorInline && hw_rotate_info->valid) {
913           SetRect(hw_rotate_info->dst_roi, &rot_dst);
914           drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION_DST_RECT, pipe_id, rot_dst);
915         }
916         DRMRect dst = {};
917         SetRect(pipe_info->dst_roi, &dst);
918         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst);
919 
920         uint32_t rot_bit_mask = 0;
921         SetRotation(layer.transform, hw_rotator_session->mode, &rot_bit_mask);
922         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask);
923         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_H_DECIMATION, pipe_id,
924                                   pipe_info->horizontal_decimation);
925         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_V_DECIMATION, pipe_id,
926                                   pipe_info->vertical_decimation);
927 
928         DRMSecureMode fb_secure_mode;
929         DRMSecurityLevel security_level;
930         SetSecureConfig(layer.input_buffer, &fb_secure_mode, &security_level);
931         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_SECURE_MODE, pipe_id, fb_secure_mode);
932         if (security_level > crtc_security_level) {
933           crtc_security_level = security_level;
934         }
935 
936         uint32_t config = 0;
937         SetSrcConfig(layer.input_buffer, hw_rotator_session->mode, &config);
938         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);;
939         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id);
940         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id);
941         if (!validate && input_buffer->acquire_fence_fd >= 0) {
942           drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id,
943                                     input_buffer->acquire_fence_fd);
944         }
945         if (hw_scale_) {
946           SDEScaler scaler_output = {};
947           hw_scale_->SetScaler(pipe_info->scale_data, &scaler_output);
948           // TODO(user): Remove qseed3 and add version check, then send appropriate scaler object
949           if (hw_resource_.has_qseed3) {
950             drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id,
951                                       reinterpret_cast<uint64_t>(&scaler_output.scaler_v2));
952           }
953         }
954 
955         DRMCscType csc_type = DRMCscType::kCscTypeMax;
956         SelectCscType(layer.input_buffer, &csc_type);
957         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CSC_CONFIG, pipe_id, &csc_type);
958 
959         DRMMultiRectMode multirect_mode;
960         SetMultiRectMode(pipe_info->flags, &multirect_mode);
961         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_MULTIRECT_MODE, pipe_id, multirect_mode);
962       }
963     }
964   }
965 
966   SetSolidfillStages();
967   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, qos_data.clock_hz);
968   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, qos_data.core_ab_bps);
969   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, qos_data.core_ib_bps);
970   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_AB, token_.crtc_id, qos_data.llcc_ab_bps);
971   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_IB, token_.crtc_id, qos_data.llcc_ib_bps);
972   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_AB, token_.crtc_id, qos_data.dram_ab_bps);
973   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_IB, token_.crtc_id, qos_data.dram_ib_bps);
974   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_PREFILL_BW, token_.crtc_id,
975                             qos_data.rot_prefill_bw_bps);
976   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_CLK, token_.crtc_id, qos_data.rot_clock_hz);
977   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level);
978 
979   DLOGI_IF(kTagDriverConfig, "%s::%s System Clock=%d Hz, Core: AB=%llu Bps, IB=%llu Bps, " \
980            "LLCC: AB=%llu Bps, IB=%llu Bps, DRAM AB=%llu Bps, IB=%llu Bps, "\
981            "Rot: Bw=%llu Bps, Clock=%d Hz", validate ? "Validate" : "Commit", device_name_,
982            qos_data.clock_hz, qos_data.core_ab_bps, qos_data.core_ib_bps, qos_data.llcc_ab_bps,
983            qos_data.llcc_ib_bps, qos_data.dram_ab_bps, qos_data.dram_ib_bps,
984            qos_data.rot_prefill_bw_bps, qos_data.rot_clock_hz);
985 
986   // Set refresh rate
987   if (vrefresh_) {
988     for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
989       if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
990           (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
991           (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
992         current_mode = connector_info_.modes[mode_index].mode;
993         break;
994       }
995     }
996   }
997 
998   if (first_cycle_) {
999     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURE_UI_ENHANCEMENT, token_.crtc_id, 1);
1000     drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
1001     drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
1002   }
1003 
1004   // Set CRTC mode, only if display config changes
1005   if (vrefresh_ || first_cycle_ || update_mode_) {
1006     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
1007   }
1008 
1009   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
1010 
1011   if (!validate && (hw_layer_info.set_idle_time_ms >= 0)) {
1012     DLOGI_IF(kTagDriverConfig, "Setting idle timeout to = %d ms",
1013              hw_layer_info.set_idle_time_ms);
1014     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_IDLE_TIMEOUT, token_.crtc_id,
1015                               hw_layer_info.set_idle_time_ms);
1016   }
1017 
1018   if (hw_panel_info_.mode == kModeCommand) {
1019     drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_AUTOREFRESH, token_.conn_id, autorefresh_);
1020   }
1021 }
1022 
AddSolidfillStage(const HWSolidfillStage & sf,uint32_t plane_alpha)1023 void HWDeviceDRM::AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha) {
1024   sde_drm::DRMSolidfillStage solidfill;
1025   solidfill.bounding_rect.left = UINT32(sf.roi.left);
1026   solidfill.bounding_rect.top = UINT32(sf.roi.top);
1027   solidfill.bounding_rect.right = UINT32(sf.roi.right);
1028   solidfill.bounding_rect.bottom = UINT32(sf.roi.bottom);
1029   solidfill.is_exclusion_rect  = sf.is_exclusion_rect;
1030   solidfill.plane_alpha = plane_alpha;
1031   solidfill.z_order = sf.z_order;
1032   if (!sf.solid_fill_info.bit_depth) {
1033     solidfill.color_bit_depth = 8;
1034     solidfill.alpha = (0xff000000 & sf.color) >> 24;
1035     solidfill.red = (0xff0000 & sf.color) >> 16;
1036     solidfill.green = (0xff00 & sf.color) >> 8;
1037     solidfill.blue = 0xff & sf.color;
1038   } else {
1039     solidfill.color_bit_depth = sf.solid_fill_info.bit_depth;
1040     solidfill.alpha = sf.solid_fill_info.alpha;
1041     solidfill.red = sf.solid_fill_info.red;
1042     solidfill.green = sf.solid_fill_info.green;
1043     solidfill.blue = sf.solid_fill_info.blue;
1044   }
1045   solid_fills_.push_back(solidfill);
1046   DLOGI_IF(kTagDriverConfig, "Add a solidfill stage at z_order:%d argb_color:%x plane_alpha:%x",
1047            solidfill.z_order, solidfill.color, solidfill.plane_alpha);
1048 }
1049 
SetSolidfillStages()1050 void HWDeviceDRM::SetSolidfillStages() {
1051   if (hw_resource_.num_solidfill_stages) {
1052     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SOLIDFILL_STAGES, token_.crtc_id,
1053                               reinterpret_cast<uint64_t> (&solid_fills_));
1054   }
1055 }
1056 
ClearSolidfillStages()1057 void HWDeviceDRM::ClearSolidfillStages() {
1058   solid_fills_.clear();
1059   SetSolidfillStages();
1060 }
1061 
Validate(HWLayers * hw_layers)1062 DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
1063   DTRACE_SCOPED();
1064 
1065   DisplayError err = kErrorNone;
1066   registry_.Register(hw_layers);
1067   SetupAtomic(hw_layers, true /* validate */);
1068 
1069   int ret = drm_atomic_intf_->Validate();
1070   if (ret) {
1071     DLOGE("failed with error %d for %s", ret, device_name_);
1072     vrefresh_ = 0;
1073     err = kErrorHardware;
1074   }
1075 
1076   return err;
1077 }
1078 
Commit(HWLayers * hw_layers)1079 DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {
1080   DTRACE_SCOPED();
1081 
1082   DisplayError err = kErrorNone;
1083   registry_.Register(hw_layers);
1084 
1085   if (default_mode_) {
1086     err = DefaultCommit(hw_layers);
1087   } else {
1088     err = AtomicCommit(hw_layers);
1089   }
1090 
1091   return err;
1092 }
1093 
DefaultCommit(HWLayers * hw_layers)1094 DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) {
1095   DTRACE_SCOPED();
1096 
1097   HWLayersInfo &hw_layer_info = hw_layers->info;
1098   LayerStack *stack = hw_layer_info.stack;
1099 
1100   stack->retire_fence_fd = -1;
1101   for (Layer &layer : hw_layer_info.hw_layers) {
1102     layer.input_buffer.release_fence_fd = -1;
1103   }
1104 
1105   DRMMaster *master = nullptr;
1106   int ret = DRMMaster::GetInstance(&master);
1107   if (ret < 0) {
1108     DLOGE("Failed to acquire DRMMaster instance");
1109     return kErrorResources;
1110   }
1111 
1112   DRMResMgr *res_mgr = nullptr;
1113   ret = DRMResMgr::GetInstance(&res_mgr);
1114   if (ret < 0) {
1115     DLOGE("Failed to acquire DRMResMgr instance");
1116     return kErrorResources;
1117   }
1118 
1119   int dev_fd = -1;
1120   master->GetHandle(&dev_fd);
1121 
1122   uint32_t connector_id = 0;
1123   res_mgr->GetConnectorId(&connector_id);
1124 
1125   uint32_t crtc_id = 0;
1126   res_mgr->GetCrtcId(&crtc_id);
1127 
1128   drmModeModeInfo mode;
1129   res_mgr->GetMode(&mode);
1130 
1131   uint64_t handle_id = hw_layer_info.hw_layers.at(0).input_buffer.handle_id;
1132   uint32_t fb_id = registry_.GetFbId(&hw_layer_info.hw_layers.at(0), handle_id);
1133   ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id,
1134                        1 /* num_connectors */, &mode);
1135   if (ret < 0) {
1136     DLOGE("drmModeSetCrtc failed dev fd %d, fb_id %d, crtc id %d, connector id %d, %s", dev_fd,
1137           fb_id, crtc_id, connector_id, strerror(errno));
1138     return kErrorHardware;
1139   }
1140 
1141   return kErrorNone;
1142 }
1143 
AtomicCommit(HWLayers * hw_layers)1144 DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) {
1145   DTRACE_SCOPED();
1146   SetupAtomic(hw_layers, false /* validate */);
1147 
1148   int ret = drm_atomic_intf_->Commit(synchronous_commit_, false /* retain_planes*/);
1149   if (ret) {
1150     DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
1151     vrefresh_ = 0;
1152     return kErrorHardware;
1153   }
1154 
1155   int release_fence = -1;
1156   int retire_fence = -1;
1157 
1158   drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence);
1159   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_GET_RETIRE_FENCE, token_.conn_id, &retire_fence);
1160 
1161   HWLayersInfo &hw_layer_info = hw_layers->info;
1162   LayerStack *stack = hw_layer_info.stack;
1163   stack->retire_fence_fd = retire_fence;
1164 
1165   for (uint32_t i = 0; i < hw_layer_info.hw_layers.size(); i++) {
1166     Layer &layer = hw_layer_info.hw_layers.at(i);
1167     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
1168     if (hw_rotator_session->mode == kRotatorOffline) {
1169       hw_rotator_session->output_buffer.release_fence_fd = Sys::dup_(release_fence);
1170     } else {
1171       layer.input_buffer.release_fence_fd = Sys::dup_(release_fence);
1172     }
1173   }
1174 
1175   hw_layer_info.sync_handle = release_fence;
1176 
1177   if (vrefresh_) {
1178     // Update current mode index if refresh rate is changed
1179     drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
1180     for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
1181       if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1182           (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1183           (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
1184         current_mode_index_ = mode_index;
1185         break;
1186       }
1187     }
1188     vrefresh_ = 0;
1189   }
1190 
1191   first_cycle_ = false;
1192   update_mode_ = false;
1193 
1194   return kErrorNone;
1195 }
1196 
Flush()1197 DisplayError HWDeviceDRM::Flush() {
1198   DTRACE_SCOPED();
1199   ClearSolidfillStages();
1200   int ret = drm_atomic_intf_->Commit(false /* synchronous */, false /* retain_planes*/);
1201   if (ret) {
1202     DLOGE("failed with error %d", ret);
1203     return kErrorHardware;
1204   }
1205 
1206   return kErrorNone;
1207 }
1208 
SetBlending(const LayerBlending & source,DRMBlendType * target)1209 void HWDeviceDRM::SetBlending(const LayerBlending &source, DRMBlendType *target) {
1210   switch (source) {
1211     case kBlendingPremultiplied:
1212       *target = DRMBlendType::PREMULTIPLIED;
1213       break;
1214     case kBlendingOpaque:
1215       *target = DRMBlendType::OPAQUE;
1216       break;
1217     case kBlendingCoverage:
1218       *target = DRMBlendType::COVERAGE;
1219       break;
1220     default:
1221       *target = DRMBlendType::UNDEFINED;
1222   }
1223 }
1224 
SetSrcConfig(const LayerBuffer & input_buffer,const HWRotatorMode & mode,uint32_t * config)1225 void HWDeviceDRM::SetSrcConfig(const LayerBuffer &input_buffer, const HWRotatorMode &mode,
1226                                uint32_t *config) {
1227   // In offline rotation case, rotator will handle deinterlacing.
1228   if (mode != kRotatorOffline) {
1229     if (input_buffer.flags.interlace) {
1230       *config |= (0x01 << UINT32(DRMSrcConfig::DEINTERLACE));
1231     }
1232   }
1233 }
1234 
SelectCscType(const LayerBuffer & input_buffer,DRMCscType * type)1235 void HWDeviceDRM::SelectCscType(const LayerBuffer &input_buffer, DRMCscType *type) {
1236   if (type == NULL) {
1237     return;
1238   }
1239 
1240   *type = DRMCscType::kCscTypeMax;
1241   if (input_buffer.format < kFormatYCbCr420Planar) {
1242     return;
1243   }
1244 
1245   switch (input_buffer.color_metadata.colorPrimaries) {
1246     case ColorPrimaries_BT601_6_525:
1247     case ColorPrimaries_BT601_6_625:
1248       *type = ((input_buffer.color_metadata.range == Range_Full) ?
1249                DRMCscType::kCscYuv2Rgb601FR : DRMCscType::kCscYuv2Rgb601L);
1250       break;
1251     case ColorPrimaries_BT709_5:
1252       *type = DRMCscType::kCscYuv2Rgb709L;
1253       break;
1254     case ColorPrimaries_BT2020:
1255       *type = ((input_buffer.color_metadata.range == Range_Full) ?
1256                 DRMCscType::kCscYuv2Rgb2020FR : DRMCscType::kCscYuv2Rgb2020L);
1257       break;
1258     default:
1259       break;
1260   }
1261 }
1262 
SetRect(const LayerRect & source,DRMRect * target)1263 void HWDeviceDRM::SetRect(const LayerRect &source, DRMRect *target) {
1264   target->left = UINT32(source.left);
1265   target->top = UINT32(source.top);
1266   target->right = UINT32(source.right);
1267   target->bottom = UINT32(source.bottom);
1268 }
1269 
SetRotation(LayerTransform transform,const HWRotatorMode & mode,uint32_t * rot_bit_mask)1270 void HWDeviceDRM::SetRotation(LayerTransform transform, const HWRotatorMode &mode,
1271                               uint32_t* rot_bit_mask) {
1272   // In offline rotation case, rotator will handle flips set via offline rotator interface.
1273   if (mode == kRotatorOffline) {
1274     *rot_bit_mask = 0;
1275     return;
1276   }
1277 
1278   // In no rotation case or inline rotation case, plane will handle flips
1279   // In DRM framework rotation is applied in counter-clockwise direction.
1280   if (mode == kRotatorInline && transform.rotation == 90) {
1281     // a) rotate 90 clockwise = rotate 270 counter-clockwise in DRM
1282     // rotate 270 is translated as hflip + vflip + rotate90
1283     // b) rotate 270 clockwise = rotate 90 counter-clockwise in DRM
1284     // c) hflip + rotate 90 clockwise = vflip + rotate 90 counter-clockwise in DRM
1285     // d) vflip + rotate 90 clockwise = hflip + rotate 90 counter-clockwise in DRM
1286     *rot_bit_mask = UINT32(DRMRotation::ROT_90);
1287     transform.flip_horizontal = !transform.flip_horizontal;
1288     transform.flip_vertical = !transform.flip_vertical;
1289   }
1290 
1291   if (transform.flip_horizontal) {
1292     *rot_bit_mask |= UINT32(DRMRotation::FLIP_H);
1293   }
1294 
1295   if (transform.flip_vertical) {
1296     *rot_bit_mask |= UINT32(DRMRotation::FLIP_V);
1297   }
1298 }
1299 
EnableHotPlugDetection(int enable)1300 bool HWDeviceDRM::EnableHotPlugDetection(int enable) {
1301   return true;
1302 }
1303 
SetCursorPosition(HWLayers * hw_layers,int x,int y)1304 DisplayError HWDeviceDRM::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
1305   DTRACE_SCOPED();
1306   return kErrorNone;
1307 }
1308 
GetPPFeaturesVersion(PPFeatureVersion * vers)1309 DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
1310   struct DRMPPFeatureInfo info = {};
1311   for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
1312     memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
1313     info.id = HWColorManagerDrm::ToDrmFeatureId(i);
1314     if (info.id >= sde_drm::kPPFeaturesMax)
1315       continue;
1316     // use crtc_id_ = 0 since PP features are same across all CRTCs
1317     drm_mgr_intf_->GetCrtcPPInfo(0, &info);
1318     vers->version[i] = HWColorManagerDrm::GetFeatureVersion(info);
1319   }
1320   return kErrorNone;
1321 }
1322 
SetPPFeatures(PPFeaturesConfig * feature_list)1323 DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) {
1324   int ret = 0;
1325   PPFeatureInfo *feature = NULL;
1326   DRMPPFeatureInfo kernel_params = {};
1327   bool crtc_feature = true;
1328 
1329   while (true) {
1330     crtc_feature = true;
1331     ret = feature_list->RetrieveNextFeature(&feature);
1332     if (ret)
1333       break;
1334     kernel_params.id = HWColorManagerDrm::ToDrmFeatureId(feature->feature_id_);
1335     drm_mgr_intf_->GetCrtcPPInfo(0, &kernel_params);
1336     if (kernel_params.version == std::numeric_limits<uint32_t>::max())
1337         crtc_feature = false;
1338     if (feature) {
1339       DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
1340       auto drm_features = DrmPPfeatureMap_.find(feature->feature_id_);
1341       if (drm_features == DrmPPfeatureMap_.end()) {
1342         DLOGE("DrmFeatures not valid for feature %d", feature->feature_id_);
1343         continue;
1344       }
1345 
1346       for (uint32_t drm_feature : drm_features->second) {
1347         if (!HWColorManagerDrm::GetDrmFeature[drm_feature]) {
1348           DLOGE("GetDrmFeature is not valid for DRM feature %d", drm_feature);
1349           continue;
1350         }
1351         ret = HWColorManagerDrm::GetDrmFeature[drm_feature](*feature, &kernel_params);
1352       if (!ret && crtc_feature)
1353         drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params);
1354       else if (!ret && !crtc_feature)
1355         drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POST_PROC, token_.conn_id, &kernel_params);
1356       HWColorManagerDrm::FreeDrmFeatureData(&kernel_params);
1357       }
1358     }
1359   }
1360 
1361   // Once all features were consumed, then destroy all feature instance from feature_list,
1362   feature_list->Reset();
1363 
1364   return kErrorNone;
1365 }
1366 
SetVSyncState(bool enable)1367 DisplayError HWDeviceDRM::SetVSyncState(bool enable) {
1368   return kErrorNotSupported;
1369 }
1370 
SetIdleTimeoutMs(uint32_t timeout_ms)1371 void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {
1372   // TODO(user): This function can be removed after fb is deprecated
1373 }
1374 
SetDisplayMode(const HWDisplayMode hw_display_mode)1375 DisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) {
1376   return kErrorNotSupported;
1377 }
1378 
SetRefreshRate(uint32_t refresh_rate)1379 DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) {
1380   // Check if requested refresh rate is valid
1381   drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
1382   for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
1383     if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1384         (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1385         (refresh_rate == connector_info_.modes[mode_index].mode.vrefresh)) {
1386       vrefresh_ = refresh_rate;
1387       DLOGV_IF(kTagDriverConfig, "Set refresh rate to %d", refresh_rate);
1388       return kErrorNone;
1389     }
1390   }
1391   return kErrorNotSupported;
1392 }
1393 
SetPanelBrightness(int level)1394 DisplayError HWDeviceDRM::SetPanelBrightness(int level) {
1395   DisplayError err = kErrorNone;
1396   char buffer[kMaxSysfsCommandLength] = {0};
1397 
1398   DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level);
1399   int fd = Sys::open_(kBrightnessNode, O_RDWR);
1400   if (fd < 0) {
1401     DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode,
1402              strerror(errno));
1403     return kErrorFileDescriptor;
1404   }
1405 
1406   int32_t bytes = snprintf(buffer, kMaxSysfsCommandLength, "%d\n", level);
1407   ssize_t ret = Sys::pwrite_(fd, buffer, static_cast<size_t>(bytes), 0);
1408   if (ret <= 0) {
1409     DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode,
1410              strerror(errno));
1411     err = kErrorHardware;
1412   }
1413 
1414   Sys::close_(fd);
1415 
1416   return err;
1417 }
1418 
GetPanelBrightness(int * level)1419 DisplayError HWDeviceDRM::GetPanelBrightness(int *level) {
1420   DisplayError err = kErrorNone;
1421   char brightness[kMaxStringLength] = {0};
1422 
1423   if (!level) {
1424     DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer.");
1425     return kErrorParameters;
1426   }
1427 
1428   int fd = Sys::open_(kBrightnessNode, O_RDWR);
1429   if (fd < 0) {
1430     DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode,
1431              strerror(errno));
1432     return kErrorFileDescriptor;
1433   }
1434 
1435   if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
1436     *level = atoi(brightness);
1437     DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level);
1438   } else {
1439     DLOGV_IF(kTagDriverConfig, "Failed to read panel brightness");
1440     err = kErrorHardware;
1441   }
1442 
1443   Sys::close_(fd);
1444 
1445   return err;
1446 }
1447 
GetHWScanInfo(HWScanInfo * scan_info)1448 DisplayError HWDeviceDRM::GetHWScanInfo(HWScanInfo *scan_info) {
1449   return kErrorNotSupported;
1450 }
1451 
GetVideoFormat(uint32_t config_index,uint32_t * video_format)1452 DisplayError HWDeviceDRM::GetVideoFormat(uint32_t config_index, uint32_t *video_format) {
1453   return kErrorNotSupported;
1454 }
1455 
GetMaxCEAFormat(uint32_t * max_cea_format)1456 DisplayError HWDeviceDRM::GetMaxCEAFormat(uint32_t *max_cea_format) {
1457   return kErrorNotSupported;
1458 }
1459 
OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level)1460 DisplayError HWDeviceDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1461   return kErrorNotSupported;
1462 }
1463 
SetS3DMode(HWS3DMode s3d_mode)1464 DisplayError HWDeviceDRM::SetS3DMode(HWS3DMode s3d_mode) {
1465   return kErrorNotSupported;
1466 }
1467 
SetScaleLutConfig(HWScaleLutInfo * lut_info)1468 DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
1469   sde_drm::DRMScalerLUTInfo drm_lut_info = {};
1470   drm_lut_info.cir_lut = lut_info->cir_lut;
1471   drm_lut_info.dir_lut = lut_info->dir_lut;
1472   drm_lut_info.sep_lut = lut_info->sep_lut;
1473   drm_lut_info.cir_lut_size = lut_info->cir_lut_size;
1474   drm_lut_info.dir_lut_size = lut_info->dir_lut_size;
1475   drm_lut_info.sep_lut_size = lut_info->sep_lut_size;
1476   drm_mgr_intf_->SetScalerLUT(drm_lut_info);
1477 
1478   return kErrorNone;
1479 }
1480 
SetMixerAttributes(const HWMixerAttributes & mixer_attributes)1481 DisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
1482   if (IsResolutionSwitchEnabled()) {
1483     return kErrorNotSupported;
1484   }
1485 
1486   if (!hw_resource_.hw_dest_scalar_info.count) {
1487     return kErrorNotSupported;
1488   }
1489 
1490   uint32_t index = current_mode_index_;
1491 
1492   if (mixer_attributes.width > display_attributes_[index].x_pixels ||
1493       mixer_attributes.height > display_attributes_[index].y_pixels) {
1494     DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
1495           mixer_attributes.width, mixer_attributes.height, display_attributes_[index].x_pixels,
1496           display_attributes_[index].y_pixels);
1497     return kErrorNotSupported;
1498   }
1499 
1500   uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
1501   if (display_attributes_[index].is_device_split) {
1502     max_input_width *= 2;
1503   }
1504 
1505   if (mixer_attributes.width > max_input_width) {
1506     DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
1507           max_input_width);
1508     return kErrorNotSupported;
1509   }
1510 
1511   float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
1512   float display_aspect_ratio =
1513       FLOAT(display_attributes_[index].x_pixels) / FLOAT(display_attributes_[index].y_pixels);
1514 
1515   if (display_aspect_ratio != mixer_aspect_ratio) {
1516     DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
1517           mixer_attributes.height, display_attributes_[index].x_pixels,
1518           display_attributes_[index].y_pixels);
1519     return kErrorNotSupported;
1520   }
1521 
1522   float scale_x = FLOAT(display_attributes_[index].x_pixels) / FLOAT(mixer_attributes.width);
1523   float scale_y = FLOAT(display_attributes_[index].y_pixels) / FLOAT(mixer_attributes.height);
1524   float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
1525   if (scale_x > max_scale_up || scale_y > max_scale_up) {
1526     DLOGW(
1527         "Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f "
1528         "max_scale_up %f",
1529         scale_x, scale_y, max_scale_up);
1530     return kErrorNotSupported;
1531   }
1532 
1533   float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
1534 
1535   mixer_attributes_ = mixer_attributes;
1536   mixer_attributes_.split_left = mixer_attributes_.width;
1537   if (display_attributes_[index].is_device_split) {
1538     mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
1539   }
1540 
1541   return kErrorNone;
1542 }
1543 
GetMixerAttributes(HWMixerAttributes * mixer_attributes)1544 DisplayError HWDeviceDRM::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
1545   if (!mixer_attributes) {
1546     return kErrorParameters;
1547   }
1548 
1549   *mixer_attributes = mixer_attributes_;
1550 
1551   return kErrorNone;
1552 }
1553 
GetDRMDisplayToken(sde_drm::DRMDisplayToken * token) const1554 void HWDeviceDRM::GetDRMDisplayToken(sde_drm::DRMDisplayToken *token) const {
1555   *token = token_;
1556 }
1557 
UpdateMixerAttributes()1558 void HWDeviceDRM::UpdateMixerAttributes() {
1559   uint32_t index = current_mode_index_;
1560 
1561   mixer_attributes_.width = display_attributes_[index].x_pixels;
1562   mixer_attributes_.height = display_attributes_[index].y_pixels;
1563   mixer_attributes_.split_left = display_attributes_[index].is_device_split
1564                                      ? hw_panel_info_.split_info.left_split
1565                                      : mixer_attributes_.width;
1566   DLOGI("Mixer WxH %dx%d for %s", mixer_attributes_.width, mixer_attributes_.height, device_name_);
1567 }
1568 
SetSecureConfig(const LayerBuffer & input_buffer,DRMSecureMode * fb_secure_mode,DRMSecurityLevel * security_level)1569 void HWDeviceDRM::SetSecureConfig(const LayerBuffer &input_buffer, DRMSecureMode *fb_secure_mode,
1570                                   DRMSecurityLevel *security_level) {
1571   *fb_secure_mode = DRMSecureMode::NON_SECURE;
1572   *security_level = DRMSecurityLevel::SECURE_NON_SECURE;
1573 
1574   if (input_buffer.flags.secure) {
1575     if (input_buffer.flags.secure_camera) {
1576       // IOMMU configuration for this framebuffer mode is secure domain & requires
1577       // only stage II translation, when this buffer is accessed by Display H/W.
1578       // Secure and non-secure planes can be attached to this CRTC.
1579       *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION;
1580     } else if (input_buffer.flags.secure_display) {
1581       // IOMMU configuration for this framebuffer mode is secure domain & requires
1582       // only stage II translation, when this buffer is accessed by Display H/W.
1583       // Only secure planes can be attached to this CRTC.
1584       *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION;
1585       *security_level = DRMSecurityLevel::SECURE_ONLY;
1586     } else {
1587       // IOMMU configuration for this framebuffer mode is secure domain & requires both
1588       // stage I and stage II translations, when this buffer is accessed by Display H/W.
1589       // Secure and non-secure planes can be attached to this CRTC.
1590       *fb_secure_mode = DRMSecureMode::SECURE;
1591     }
1592   }
1593 }
1594 
SetTopology(sde_drm::DRMTopology drm_topology,HWTopology * hw_topology)1595 void HWDeviceDRM::SetTopology(sde_drm::DRMTopology drm_topology, HWTopology *hw_topology) {
1596   switch (drm_topology) {
1597     case DRMTopology::SINGLE_LM:          *hw_topology = kSingleLM;        break;
1598     case DRMTopology::SINGLE_LM_DSC:      *hw_topology = kSingleLMDSC;     break;
1599     case DRMTopology::DUAL_LM:            *hw_topology = kDualLM;          break;
1600     case DRMTopology::DUAL_LM_DSC:        *hw_topology = kDualLMDSC;       break;
1601     case DRMTopology::DUAL_LM_MERGE:      *hw_topology = kDualLMMerge;     break;
1602     case DRMTopology::DUAL_LM_MERGE_DSC:  *hw_topology = kDualLMMergeDSC;  break;
1603     case DRMTopology::DUAL_LM_DSCMERGE:   *hw_topology = kDualLMDSCMerge;  break;
1604     case DRMTopology::PPSPLIT:            *hw_topology = kPPSplit;         break;
1605     default:                              *hw_topology = kUnknown;         break;
1606   }
1607 }
1608 
SetMultiRectMode(const uint32_t flags,DRMMultiRectMode * target)1609 void HWDeviceDRM::SetMultiRectMode(const uint32_t flags, DRMMultiRectMode *target) {
1610   *target = DRMMultiRectMode::NONE;
1611   if (flags & kMultiRect) {
1612     *target = DRMMultiRectMode::SERIAL;
1613     if (flags & kMultiRectParallelMode) {
1614       *target = DRMMultiRectMode::PARALLEL;
1615     }
1616   }
1617 }
1618 
SetFullROI()1619 void HWDeviceDRM::SetFullROI() {
1620   // Reset the CRTC ROI and connector ROI only for the panel that supports partial update
1621   if (!hw_panel_info_.partial_update) {
1622     return;
1623   }
1624   uint32_t index = current_mode_index_;
1625   DRMRect crtc_rects = {0, 0, mixer_attributes_.width, mixer_attributes_.height};
1626   DRMRect conn_rects = {0, 0, display_attributes_[index].x_pixels,
1627                          display_attributes_[index].y_pixels};
1628   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id, 1, &crtc_rects);
1629   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id, 1, &conn_rects);
1630 }
1631 
DumpConnectorModeInfo()1632 void HWDeviceDRM::DumpConnectorModeInfo() {
1633   for (uint32_t i = 0; i < (uint32_t)connector_info_.modes.size(); i++) {
1634     DLOGI("Mode[%d] Name:%s vref:%d hdisp:%d hsync_s:%d hsync_e:%d htotal:%d " \
1635           "vdisp:%d vsync_s:%d vsync_e:%d vtotal:%d\n", i, connector_info_.modes[i].mode.name,
1636           connector_info_.modes[i].mode.vrefresh, connector_info_.modes[i].mode.hdisplay,
1637           connector_info_.modes[i].mode.hsync_start, connector_info_.modes[i].mode.hsync_end,
1638           connector_info_.modes[i].mode.htotal, connector_info_.modes[i].mode.vdisplay,
1639           connector_info_.modes[i].mode.vsync_start, connector_info_.modes[i].mode.vsync_end,
1640           connector_info_.modes[i].mode.vtotal);
1641   }
1642 }
1643 
1644 }  // namespace sdm
1645