1 /*
2 * Copyright (c) 2014 - 2016, 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 <stdio.h>
33 #include <ctype.h>
34 #include <math.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37 #include <string.h>
38 #include <inttypes.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/ioctl.h>
42 #include <linux/fb.h>
43 #include <utils/constants.h>
44 #include <utils/debug.h>
45 #include <utils/sys.h>
46 #include <vector>
47 #include <algorithm>
48 
49 #include "hw_device.h"
50 #include "hw_info_interface.h"
51 
52 #define __CLASS__ "HWDevice"
53 
54 namespace sdm {
55 
HWDevice(BufferSyncHandler * buffer_sync_handler)56 HWDevice::HWDevice(BufferSyncHandler *buffer_sync_handler)
57   : fb_node_index_(-1), fb_path_("/sys/devices/virtual/graphics/fb"), hotplug_enabled_(false),
58     buffer_sync_handler_(buffer_sync_handler), synchronous_commit_(false) {
59 }
60 
Init(HWEventHandler * eventhandler)61 DisplayError HWDevice::Init(HWEventHandler *eventhandler) {
62   DisplayError error = kErrorNone;
63   char device_name[64] = {0};
64 
65   event_handler_ = eventhandler;
66 
67   // Read the fb node index
68   fb_node_index_ = GetFBNodeIndex(device_type_);
69   if (fb_node_index_ == -1) {
70     DLOGE("%s should be present", device_name_);
71     return kErrorHardware;
72   }
73 
74   // Populate Panel Info (Used for Partial Update)
75   PopulateHWPanelInfo();
76   // Populate HW Capabilities
77   hw_resource_ = HWResourceInfo();
78   hw_info_intf_->GetHWResourceInfo(&hw_resource_);
79 
80   snprintf(device_name, sizeof(device_name), "%s%d", "/dev/graphics/fb", fb_node_index_);
81   device_fd_ = Sys::open_(device_name, O_RDWR);
82   if (device_fd_ < 0) {
83     DLOGE("open %s failed err = %d errstr = %s", device_name, errno,  strerror(errno));
84     return kErrorResources;
85   }
86 
87   return error;
88 }
89 
Deinit()90 DisplayError HWDevice::Deinit() {
91   if (device_fd_ >= 0) {
92     Sys::close_(device_fd_);
93     device_fd_ = -1;
94   }
95 
96   return kErrorNone;
97 }
98 
GetActiveConfig(uint32_t * active_config)99 DisplayError HWDevice::GetActiveConfig(uint32_t *active_config) {
100   *active_config = 0;
101   return kErrorNone;
102 }
103 
GetNumDisplayAttributes(uint32_t * count)104 DisplayError HWDevice::GetNumDisplayAttributes(uint32_t *count) {
105   *count = 1;
106   return kErrorNone;
107 }
108 
GetDisplayAttributes(uint32_t index,HWDisplayAttributes * display_attributes)109 DisplayError HWDevice::GetDisplayAttributes(uint32_t index,
110                                             HWDisplayAttributes *display_attributes) {
111   return kErrorNone;
112 }
113 
GetHWPanelInfo(HWPanelInfo * panel_info)114 DisplayError HWDevice::GetHWPanelInfo(HWPanelInfo *panel_info) {
115   *panel_info = hw_panel_info_;
116   return kErrorNone;
117 }
118 
SetDisplayAttributes(uint32_t index)119 DisplayError HWDevice::SetDisplayAttributes(uint32_t index) {
120   return kErrorNone;
121 }
122 
GetConfigIndex(uint32_t mode,uint32_t * index)123 DisplayError HWDevice::GetConfigIndex(uint32_t mode, uint32_t *index) {
124   return kErrorNone;
125 }
126 
PowerOn()127 DisplayError HWDevice::PowerOn() {
128   DTRACE_SCOPED();
129 
130   if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
131     if (errno == ESHUTDOWN) {
132       DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
133       return kErrorShutDown;
134     }
135     IOCTL_LOGE(FB_BLANK_UNBLANK, device_type_);
136     return kErrorHardware;
137   }
138 
139   // Need to turn on HPD
140   if (!hotplug_enabled_) {
141     hotplug_enabled_ = EnableHotPlugDetection(1);
142   }
143 
144   return kErrorNone;
145 }
146 
PowerOff()147 DisplayError HWDevice::PowerOff() {
148   return kErrorNone;
149 }
150 
Doze()151 DisplayError HWDevice::Doze() {
152   return kErrorNone;
153 }
154 
DozeSuspend()155 DisplayError HWDevice::DozeSuspend() {
156   return kErrorNone;
157 }
158 
Standby()159 DisplayError HWDevice::Standby() {
160   return kErrorNone;
161 }
162 
Validate(HWLayers * hw_layers)163 DisplayError HWDevice::Validate(HWLayers *hw_layers) {
164   DTRACE_SCOPED();
165 
166   DisplayError error = kErrorNone;
167 
168   HWLayersInfo &hw_layer_info = hw_layers->info;
169   LayerStack *stack = hw_layer_info.stack;
170 
171   DLOGV_IF(kTagDriverConfig, "************************** %s Validate Input ***********************",
172            device_name_);
173   DLOGV_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_info.count);
174 
175   mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
176   uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
177 
178   DLOGI_IF(kTagDriverConfig, "left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x,
179     mdp_commit.left_roi.y, mdp_commit.left_roi.w, mdp_commit.left_roi.h);
180   DLOGI_IF(kTagDriverConfig, "right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
181     mdp_commit.right_roi.y, mdp_commit.right_roi.w, mdp_commit.right_roi.h);
182 
183   for (uint32_t i = 0; i < hw_layer_info.count; i++) {
184     uint32_t layer_index = hw_layer_info.index[i];
185     Layer &layer = stack->layers[layer_index];
186     LayerBuffer *input_buffer = layer.input_buffer;
187     HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
188     HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
189     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
190     bool is_rotator_used = (hw_rotator_session->hw_block_count != 0);
191     bool is_cursor_pipe_used = (hw_layer_info.use_hw_cursor & layer.flags.cursor);
192 
193     for (uint32_t count = 0; count < 2; count++) {
194       HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
195       HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
196 
197       if (hw_rotate_info->valid) {
198         input_buffer = &hw_rotator_session->output_buffer;
199       }
200 
201       if (pipe_info->valid) {
202         mdp_input_layer &mdp_layer = mdp_in_layers_[mdp_layer_count];
203         mdp_layer_buffer &mdp_buffer = mdp_layer.buffer;
204 
205         mdp_buffer.width = input_buffer->width;
206         mdp_buffer.height = input_buffer->height;
207         mdp_buffer.comp_ratio.denom = 1000;
208         mdp_buffer.comp_ratio.numer = UINT32(hw_layers->config[i].compression * 1000);
209 
210         if (layer.flags.solid_fill) {
211           mdp_buffer.format = MDP_ARGB_8888;
212         } else {
213           error = SetFormat(input_buffer->format, &mdp_buffer.format);
214           if (error != kErrorNone) {
215             return error;
216           }
217         }
218         mdp_layer.alpha = layer.plane_alpha;
219         mdp_layer.z_order = UINT16(pipe_info->z_order);
220         mdp_layer.transp_mask = 0xffffffff;
221         SetBlending(layer.blending, &mdp_layer.blend_op);
222         mdp_layer.pipe_ndx = pipe_info->pipe_id;
223         mdp_layer.horz_deci = pipe_info->horizontal_decimation;
224         mdp_layer.vert_deci = pipe_info->vertical_decimation;
225 
226         SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
227         SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
228         SetMDPFlags(layer, is_rotator_used, is_cursor_pipe_used, &mdp_layer.flags);
229         SetCSC(layer.csc, &mdp_layer.color_space);
230         if (pipe_info->set_igc) {
231           SetIGC(layer, mdp_layer_count);
232         }
233         mdp_layer.bg_color = layer.solid_fill_color;
234 
235         if (pipe_info->scale_data.enable_pixel_ext) {
236           SetHWScaleData(pipe_info->scale_data, mdp_layer_count);
237           mdp_layer.flags |= MDP_LAYER_ENABLE_PIXEL_EXT;
238         }
239 
240         // Send scale data to MDP driver
241         mdp_layer.scale = GetScaleDataRef(mdp_layer_count);
242         mdp_layer_count++;
243 
244         DLOGV_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
245                  i, count ? "Right" : "Left");
246         DLOGV_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d", mdp_buffer.width, mdp_buffer.height,
247                  mdp_buffer.format);
248         DLOGV_IF(kTagDriverConfig, "plane_alpha %d, zorder %d, blending %d, horz_deci %d, "
249                  "vert_deci %d, pipe_id = 0x%x, mdp_flags 0x%x", mdp_layer.alpha, mdp_layer.z_order,
250                  mdp_layer.blend_op, mdp_layer.horz_deci, mdp_layer.vert_deci, mdp_layer.pipe_ndx,
251                  mdp_layer.flags);
252         DLOGV_IF(kTagDriverConfig, "src_rect [%d, %d, %d, %d]", mdp_layer.src_rect.x,
253                  mdp_layer.src_rect.y, mdp_layer.src_rect.w, mdp_layer.src_rect.h);
254         DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_layer.dst_rect.x,
255                  mdp_layer.dst_rect.y, mdp_layer.dst_rect.w, mdp_layer.dst_rect.h);
256         for (int j = 0; j < 4; j++) {
257           mdp_scale_data *scale = reinterpret_cast<mdp_scale_data*>(mdp_layer.scale);
258           DLOGV_IF(kTagDriverConfig, "Scale Data[%d]: Phase=[%x %x %x %x] Pixel_Ext=[%d %d %d %d]",
259                  j, scale->init_phase_x[j], scale->phase_step_x[j], scale->init_phase_y[j],
260                  scale->phase_step_y[j], scale->num_ext_pxls_left[j], scale->num_ext_pxls_top[j],
261                  scale->num_ext_pxls_right[j], scale->num_ext_pxls_btm[j]);
262           DLOGV_IF(kTagDriverConfig, "Fetch=[%d %d %d %d]  Repeat=[%d %d %d %d]  roi_width = %d",
263                  scale->left_ftch[j], scale->top_ftch[j], scale->right_ftch[j], scale->btm_ftch[j],
264                  scale->left_rpt[j], scale->top_rpt[j], scale->right_rpt[j], scale->btm_rpt[j],
265                  scale->roi_w[j]);
266         }
267         DLOGV_IF(kTagDriverConfig, "*************************************************************");
268       }
269     }
270   }
271 
272   if (device_type_ == kDeviceVirtual) {
273     LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
274     // Fill WB index for virtual based on number of rotator WB blocks present in the HW.
275     // Eg: If 2 WB rotator blocks available, the WB index for virtual will be 2, as the
276     // indexing of WB blocks start from 0.
277     mdp_out_layer_.writeback_ndx = hw_resource_.hw_rot_info.num_rotator;
278     mdp_out_layer_.buffer.width = output_buffer->width;
279     mdp_out_layer_.buffer.height = output_buffer->height;
280     if (output_buffer->flags.secure) {
281       mdp_out_layer_.flags |= MDP_LAYER_SECURE_SESSION;
282     }
283     mdp_out_layer_.buffer.comp_ratio.denom = 1000;
284     mdp_out_layer_.buffer.comp_ratio.numer = UINT32(hw_layers->output_compression * 1000);
285     SetFormat(output_buffer->format, &mdp_out_layer_.buffer.format);
286 
287     DLOGI_IF(kTagDriverConfig, "********************* Output buffer Info ************************");
288     DLOGI_IF(kTagDriverConfig, "out_w %d, out_h %d, out_f %d, wb_id %d",
289              mdp_out_layer_.buffer.width, mdp_out_layer_.buffer.height,
290              mdp_out_layer_.buffer.format, mdp_out_layer_.writeback_ndx);
291     DLOGI_IF(kTagDriverConfig, "*****************************************************************");
292   }
293 
294   mdp_commit.flags |= MDP_VALIDATE_LAYER;
295   if (Sys::ioctl_(device_fd_, INT(MSMFB_ATOMIC_COMMIT), &mdp_disp_commit_) < 0) {
296     if (errno == ESHUTDOWN) {
297       DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
298       return kErrorShutDown;
299     }
300     IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
301     DumpLayerCommit(mdp_disp_commit_);
302     return kErrorHardware;
303   }
304 
305   return kErrorNone;
306 }
307 
DumpLayerCommit(const mdp_layer_commit & layer_commit)308 void HWDevice::DumpLayerCommit(const mdp_layer_commit &layer_commit) {
309   const mdp_layer_commit_v1 &mdp_commit = layer_commit.commit_v1;
310   const mdp_input_layer *mdp_layers = mdp_commit.input_layers;
311   const mdp_rect &l_roi = mdp_commit.left_roi;
312   const mdp_rect &r_roi = mdp_commit.right_roi;
313 
314   DLOGI("mdp_commit: flags = %x, release fence = %x", mdp_commit.flags, mdp_commit.release_fence);
315   DLOGI("left_roi: x = %d, y = %d, w = %d, h = %d", l_roi.x, l_roi.y, l_roi.w, l_roi.h);
316   DLOGI("right_roi: x = %d, y = %d, w = %d, h = %d", r_roi.x, r_roi.y, r_roi.w, r_roi.h);
317   for (uint32_t i = 0; i < mdp_commit.input_layer_cnt; i++) {
318     const mdp_input_layer &layer = mdp_layers[i];
319     const mdp_rect &src_rect = layer.src_rect;
320     const mdp_rect &dst_rect = layer.dst_rect;
321     DLOGI("layer = %d, pipe_ndx = %x, z = %d, flags = %x",
322       i, layer.pipe_ndx, layer.z_order, layer.flags);
323     DLOGI("src_rect: x = %d, y = %d, w = %d, h = %d",
324       src_rect.x, src_rect.y, src_rect.w, src_rect.h);
325     DLOGI("dst_rect: x = %d, y = %d, w = %d, h = %d",
326       dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
327   }
328 }
329 
Commit(HWLayers * hw_layers)330 DisplayError HWDevice::Commit(HWLayers *hw_layers) {
331   DTRACE_SCOPED();
332 
333   HWLayersInfo &hw_layer_info = hw_layers->info;
334   LayerStack *stack = hw_layer_info.stack;
335 
336   DLOGV_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
337            device_name_);
338   DLOGV_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_info.count);
339 
340   mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
341   uint32_t mdp_layer_index = 0;
342 
343   for (uint32_t i = 0; i < hw_layer_info.count; i++) {
344     uint32_t layer_index = hw_layer_info.index[i];
345     LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
346     HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
347     HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
348     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
349 
350     for (uint32_t count = 0; count < 2; count++) {
351       HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
352       HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
353 
354       if (hw_rotate_info->valid) {
355         input_buffer = &hw_rotator_session->output_buffer;
356       }
357 
358       if (pipe_info->valid) {
359         mdp_layer_buffer &mdp_buffer = mdp_in_layers_[mdp_layer_index].buffer;
360         mdp_input_layer &mdp_layer = mdp_in_layers_[mdp_layer_index];
361         if (input_buffer->planes[0].fd >= 0) {
362           mdp_buffer.plane_count = 1;
363           mdp_buffer.planes[0].fd = input_buffer->planes[0].fd;
364           mdp_buffer.planes[0].offset = input_buffer->planes[0].offset;
365           SetStride(device_type_, input_buffer->format, input_buffer->planes[0].stride,
366                     &mdp_buffer.planes[0].stride);
367         } else {
368           mdp_buffer.plane_count = 0;
369         }
370 
371         mdp_buffer.fence = input_buffer->acquire_fence_fd;
372         mdp_layer_index++;
373 
374         DLOGV_IF(kTagDriverConfig, "****************** Layer[%d] %s pipe Input *******************",
375                  i, count ? "Right" : "Left");
376         DLOGI_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d, horz_deci %d, vert_deci %d",
377                  mdp_buffer.width, mdp_buffer.height, mdp_buffer.format, mdp_layer.horz_deci,
378                  mdp_layer.vert_deci);
379         DLOGI_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_buf_stride %d, " \
380                  "in_plane_count %d, in_fence %d, layer count %d", mdp_buffer.planes[0].fd,
381                  mdp_buffer.planes[0].offset, mdp_buffer.planes[0].stride, mdp_buffer.plane_count,
382                  mdp_buffer.fence, mdp_commit.input_layer_cnt);
383         DLOGV_IF(kTagDriverConfig, "*************************************************************");
384       }
385     }
386   }
387 
388   if (device_type_ == kDeviceVirtual) {
389     LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
390 
391     if (output_buffer->planes[0].fd >= 0) {
392       mdp_out_layer_.buffer.planes[0].fd = output_buffer->planes[0].fd;
393       mdp_out_layer_.buffer.planes[0].offset = output_buffer->planes[0].offset;
394       SetStride(device_type_, output_buffer->format, output_buffer->planes[0].stride,
395                 &mdp_out_layer_.buffer.planes[0].stride);
396       mdp_out_layer_.buffer.plane_count = 1;
397     } else {
398       DLOGE("Invalid output buffer fd");
399       return kErrorParameters;
400     }
401 
402     mdp_out_layer_.buffer.fence = output_buffer->acquire_fence_fd;
403 
404     DLOGI_IF(kTagDriverConfig, "********************** Output buffer Info ***********************");
405     DLOGI_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d, acquire_fence %d",
406              mdp_out_layer_.buffer.planes[0].fd, mdp_out_layer_.buffer.planes[0].offset,
407              mdp_out_layer_.buffer.planes[0].stride,  mdp_out_layer_.buffer.fence);
408     DLOGI_IF(kTagDriverConfig, "*****************************************************************");
409   }
410 
411   mdp_commit.release_fence = -1;
412   mdp_commit.flags &= UINT32(~MDP_VALIDATE_LAYER);
413   if (synchronous_commit_) {
414     mdp_commit.flags |= MDP_COMMIT_WAIT_FOR_FINISH;
415   }
416   if (Sys::ioctl_(device_fd_, INT(MSMFB_ATOMIC_COMMIT), &mdp_disp_commit_) < 0) {
417     if (errno == ESHUTDOWN) {
418       DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
419       return kErrorShutDown;
420     }
421     IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
422     DumpLayerCommit(mdp_disp_commit_);
423     synchronous_commit_ = false;
424     return kErrorHardware;
425   }
426 
427   stack->retire_fence_fd = mdp_commit.retire_fence;
428 
429   // MDP returns only one release fence for the entire layer stack. Duplicate this fence into all
430   // layers being composed by MDP.
431 
432   std::vector<uint32_t> fence_dup_flag;
433   fence_dup_flag.clear();
434 
435   for (uint32_t i = 0; i < hw_layer_info.count; i++) {
436     uint32_t layer_index = hw_layer_info.index[i];
437     LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
438     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
439 
440     if (hw_rotator_session->hw_block_count) {
441       input_buffer = &hw_rotator_session->output_buffer;
442     }
443 
444     // Make sure the release fence is duplicated only once for each buffer.
445     if (std::find(fence_dup_flag.begin(), fence_dup_flag.end(), layer_index) ==
446         fence_dup_flag.end()) {
447       input_buffer->release_fence_fd = Sys::dup_(mdp_commit.release_fence);
448       fence_dup_flag.push_back(layer_index);
449     }
450   }
451   fence_dup_flag.clear();
452 
453   hw_layer_info.sync_handle = Sys::dup_(mdp_commit.release_fence);
454 
455   DLOGI_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
456            device_name_);
457   DLOGI_IF(kTagDriverConfig, "retire_fence_fd %d", stack->retire_fence_fd);
458   DLOGI_IF(kTagDriverConfig, "*******************************************************************");
459 
460   if (mdp_commit.release_fence >= 0) {
461     Sys::close_(mdp_commit.release_fence);
462   }
463 
464   if (synchronous_commit_) {
465     // A synchronous commit can be requested when changing the display mode so we need to update
466     // panel info.
467     PopulateHWPanelInfo();
468     synchronous_commit_ = false;
469   }
470 
471   return kErrorNone;
472 }
473 
Flush()474 DisplayError HWDevice::Flush() {
475   ResetDisplayParams();
476   mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
477   mdp_commit.input_layer_cnt = 0;
478   mdp_commit.output_layer = NULL;
479 
480   mdp_commit.flags &= UINT32(~MDP_VALIDATE_LAYER);
481   if (Sys::ioctl_(device_fd_, INT(MSMFB_ATOMIC_COMMIT), &mdp_disp_commit_) < 0) {
482     if (errno == ESHUTDOWN) {
483       DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
484       return kErrorShutDown;
485     }
486     IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
487     DumpLayerCommit(mdp_disp_commit_);
488     return kErrorHardware;
489   }
490   return kErrorNone;
491 }
492 
SetFormat(const LayerBufferFormat & source,uint32_t * target)493 DisplayError HWDevice::SetFormat(const LayerBufferFormat &source, uint32_t *target) {
494   switch (source) {
495   case kFormatARGB8888:                 *target = MDP_ARGB_8888;         break;
496   case kFormatRGBA8888:                 *target = MDP_RGBA_8888;         break;
497   case kFormatBGRA8888:                 *target = MDP_BGRA_8888;         break;
498   case kFormatRGBX8888:                 *target = MDP_RGBX_8888;         break;
499   case kFormatBGRX8888:                 *target = MDP_BGRX_8888;         break;
500   case kFormatRGBA5551:                 *target = MDP_RGBA_5551;         break;
501   case kFormatRGBA4444:                 *target = MDP_RGBA_4444;         break;
502   case kFormatRGB888:                   *target = MDP_RGB_888;           break;
503   case kFormatBGR888:                   *target = MDP_BGR_888;           break;
504   case kFormatRGB565:                   *target = MDP_RGB_565;           break;
505   case kFormatBGR565:                   *target = MDP_BGR_565;           break;
506   case kFormatYCbCr420Planar:           *target = MDP_Y_CB_CR_H2V2;      break;
507   case kFormatYCrCb420Planar:           *target = MDP_Y_CR_CB_H2V2;      break;
508   case kFormatYCrCb420PlanarStride16:   *target = MDP_Y_CR_CB_GH2V2;     break;
509   case kFormatYCbCr420SemiPlanar:       *target = MDP_Y_CBCR_H2V2;       break;
510   case kFormatYCrCb420SemiPlanar:       *target = MDP_Y_CRCB_H2V2;       break;
511   case kFormatYCbCr422H1V2SemiPlanar:   *target = MDP_Y_CBCR_H1V2;       break;
512   case kFormatYCrCb422H1V2SemiPlanar:   *target = MDP_Y_CRCB_H1V2;       break;
513   case kFormatYCbCr422H2V1SemiPlanar:   *target = MDP_Y_CBCR_H2V1;       break;
514   case kFormatYCrCb422H2V1SemiPlanar:   *target = MDP_Y_CRCB_H2V1;       break;
515   case kFormatYCbCr422H2V1Packed:       *target = MDP_YCBYCR_H2V1;       break;
516   case kFormatYCbCr420SemiPlanarVenus:  *target = MDP_Y_CBCR_H2V2_VENUS; break;
517   case kFormatRGBA8888Ubwc:             *target = MDP_RGBA_8888_UBWC;    break;
518   case kFormatRGBX8888Ubwc:             *target = MDP_RGBX_8888_UBWC;    break;
519   case kFormatBGR565Ubwc:               *target = MDP_RGB_565_UBWC;      break;
520   case kFormatYCbCr420SPVenusUbwc:      *target = MDP_Y_CBCR_H2V2_UBWC;  break;
521   case kFormatRGBA1010102:              *target = MDP_RGBA_1010102;      break;
522   case kFormatARGB2101010:              *target = MDP_ARGB_2101010;      break;
523   case kFormatRGBX1010102:              *target = MDP_RGBX_1010102;      break;
524   case kFormatXRGB2101010:              *target = MDP_XRGB_2101010;      break;
525   case kFormatBGRA1010102:              *target = MDP_BGRA_1010102;      break;
526   case kFormatABGR2101010:              *target = MDP_ABGR_2101010;      break;
527   case kFormatBGRX1010102:              *target = MDP_BGRX_1010102;      break;
528   case kFormatXBGR2101010:              *target = MDP_XBGR_2101010;      break;
529   case kFormatRGBA1010102Ubwc:          *target = MDP_RGBA_1010102_UBWC; break;
530   case kFormatRGBX1010102Ubwc:          *target = MDP_RGBX_1010102_UBWC; break;
531   case kFormatYCbCr420P010:             *target = MDP_Y_CBCR_H2V2_P010;  break;
532   case kFormatYCbCr420TP10Ubwc:         *target = MDP_Y_CBCR_H2V2_TP10_UBWC; break;
533   default:
534     DLOGE("Unsupported format type %d", source);
535     return kErrorParameters;
536   }
537 
538   return kErrorNone;
539 }
540 
SetStride(HWDeviceType device_type,LayerBufferFormat format,uint32_t width,uint32_t * target)541 DisplayError HWDevice::SetStride(HWDeviceType device_type, LayerBufferFormat format,
542                                       uint32_t width, uint32_t *target) {
543   // TODO(user): This SetStride function is a workaround to satisfy the driver expectation for
544   // rotator and virtual devices. Eventually this will be taken care in the driver.
545   if (device_type != kDeviceRotator && device_type != kDeviceVirtual) {
546     *target = width;
547     return kErrorNone;
548   }
549 
550   switch (format) {
551   case kFormatARGB8888:
552   case kFormatRGBA8888:
553   case kFormatBGRA8888:
554   case kFormatRGBX8888:
555   case kFormatBGRX8888:
556   case kFormatRGBA8888Ubwc:
557   case kFormatRGBX8888Ubwc:
558   case kFormatRGBA1010102:
559   case kFormatARGB2101010:
560   case kFormatRGBX1010102:
561   case kFormatXRGB2101010:
562   case kFormatBGRA1010102:
563   case kFormatABGR2101010:
564   case kFormatBGRX1010102:
565   case kFormatXBGR2101010:
566   case kFormatRGBA1010102Ubwc:
567   case kFormatRGBX1010102Ubwc:
568     *target = width * 4;
569     break;
570   case kFormatRGB888:
571   case kFormatBGR888:
572     *target = width * 3;
573     break;
574   case kFormatRGB565:
575   case kFormatBGR565:
576   case kFormatBGR565Ubwc:
577     *target = width * 2;
578     break;
579   case kFormatYCbCr420SemiPlanarVenus:
580   case kFormatYCbCr420SPVenusUbwc:
581   case kFormatYCbCr420Planar:
582   case kFormatYCrCb420Planar:
583   case kFormatYCrCb420PlanarStride16:
584   case kFormatYCbCr420SemiPlanar:
585   case kFormatYCrCb420SemiPlanar:
586   case kFormatYCbCr420P010:
587   case kFormatYCbCr420TP10Ubwc:
588     *target = width;
589     break;
590   case kFormatYCbCr422H2V1Packed:
591   case kFormatYCrCb422H2V1SemiPlanar:
592   case kFormatYCrCb422H1V2SemiPlanar:
593   case kFormatYCbCr422H2V1SemiPlanar:
594   case kFormatYCbCr422H1V2SemiPlanar:
595   case kFormatRGBA5551:
596   case kFormatRGBA4444:
597     *target = width * 2;
598     break;
599   default:
600     DLOGE("Unsupported format type %d", format);
601     return kErrorParameters;
602   }
603 
604   return kErrorNone;
605 }
606 
SetBlending(const LayerBlending & source,mdss_mdp_blend_op * target)607 void HWDevice::SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target) {
608   switch (source) {
609   case kBlendingPremultiplied:  *target = BLEND_OP_PREMULTIPLIED;   break;
610   case kBlendingOpaque:         *target = BLEND_OP_OPAQUE;          break;
611   case kBlendingCoverage:       *target = BLEND_OP_COVERAGE;        break;
612   default:                      *target = BLEND_OP_NOT_DEFINED;     break;
613   }
614 }
615 
SetRect(const LayerRect & source,mdp_rect * target)616 void HWDevice::SetRect(const LayerRect &source, mdp_rect *target) {
617   target->x = UINT32(source.left);
618   target->y = UINT32(source.top);
619   target->w = UINT32(source.right) - target->x;
620   target->h = UINT32(source.bottom) - target->y;
621 }
622 
SetMDPFlags(const Layer & layer,const bool & is_rotator_used,bool is_cursor_pipe_used,uint32_t * mdp_flags)623 void HWDevice::SetMDPFlags(const Layer &layer, const bool &is_rotator_used,
624                            bool is_cursor_pipe_used, uint32_t *mdp_flags) {
625   LayerBuffer *input_buffer = layer.input_buffer;
626 
627   // Flips will be taken care by rotator, if layer uses rotator for downscale/rotation. So ignore
628   // flip flags for MDP.
629   if (!is_rotator_used) {
630     if (layer.transform.flip_vertical) {
631       *mdp_flags |= MDP_LAYER_FLIP_UD;
632     }
633 
634     if (layer.transform.flip_horizontal) {
635       *mdp_flags |= MDP_LAYER_FLIP_LR;
636     }
637 
638     if (input_buffer->flags.interlace) {
639       *mdp_flags |= MDP_LAYER_DEINTERLACE;
640     }
641   }
642 
643   if (input_buffer->flags.secure) {
644     *mdp_flags |= MDP_LAYER_SECURE_SESSION;
645   }
646 
647   if (input_buffer->flags.secure_display) {
648     *mdp_flags |= MDP_LAYER_SECURE_DISPLAY_SESSION;
649   }
650 
651   if (layer.flags.solid_fill) {
652     *mdp_flags |= MDP_LAYER_SOLID_FILL;
653   }
654 
655   if (hw_panel_info_.mode != kModeCommand && layer.flags.cursor && is_cursor_pipe_used) {
656     // command mode panels does not support async position update
657     *mdp_flags |= MDP_LAYER_ASYNC;
658   }
659 }
660 
GetFBNodeIndex(HWDeviceType device_type)661 int HWDevice::GetFBNodeIndex(HWDeviceType device_type) {
662   for (int i = 0; i <= kDeviceVirtual; i++) {
663     HWPanelInfo panel_info;
664     GetHWPanelInfoByNode(i, &panel_info);
665     switch (device_type) {
666     case kDevicePrimary:
667       if (panel_info.is_primary_panel) {
668         return i;
669       }
670       break;
671     case kDeviceHDMI:
672       if (panel_info.is_pluggable == true) {
673         return i;
674       }
675       break;
676     case kDeviceVirtual:
677       if (panel_info.port == kPortWriteBack) {
678         return i;
679       }
680       break;
681     default:
682       break;
683     }
684   }
685   return -1;
686 }
687 
PopulateHWPanelInfo()688 void HWDevice::PopulateHWPanelInfo() {
689   hw_panel_info_ = HWPanelInfo();
690   GetHWPanelInfoByNode(fb_node_index_, &hw_panel_info_);
691   DLOGI("Device type = %d, Display Port = %d, Display Mode = %d, Device Node = %d, Is Primary = %d",
692         device_type_, hw_panel_info_.port, hw_panel_info_.mode, fb_node_index_,
693         hw_panel_info_.is_primary_panel);
694   DLOGI("Partial Update = %d, Dynamic FPS = %d",
695         hw_panel_info_.partial_update, hw_panel_info_.dynamic_fps);
696   DLOGI("Align: left = %d, width = %d, top = %d, height = %d",
697         hw_panel_info_.left_align, hw_panel_info_.width_align,
698         hw_panel_info_.top_align, hw_panel_info_.height_align);
699   DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d",
700         hw_panel_info_.min_roi_width, hw_panel_info_.min_roi_height,
701         hw_panel_info_.needs_roi_merge);
702   DLOGI("FPS: min = %d, max =%d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
703   DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
704         hw_panel_info_.split_info.right_split);
705 }
706 
GetHWPanelNameByNode(int device_node,HWPanelInfo * panel_info)707 void HWDevice::GetHWPanelNameByNode(int device_node, HWPanelInfo *panel_info) {
708   if (!panel_info) {
709     DLOGE("PanelInfo pointer in invalid.");
710     return;
711   }
712   char *string_buffer = reinterpret_cast<char*>(malloc(sizeof(char) * kMaxStringLength));
713   if (!string_buffer) {
714     DLOGE("Failed to allocated string_buffer memory");
715     return;
716   }
717   snprintf(string_buffer, kMaxStringLength, "%s%d/msm_fb_panel_info", fb_path_, device_node);
718   FILE *fileptr = Sys::fopen_(string_buffer, "r");
719   if (!fileptr) {
720     DLOGW("Failed to open msm_fb_panel_info node device node %d", device_node);
721   } else {
722     size_t len = kMaxStringLength;
723 
724     while ((Sys::getline_(&string_buffer, &len, fileptr)) != -1) {
725       uint32_t token_count = 0;
726       const uint32_t max_count = 10;
727       char *tokens[max_count] = { NULL };
728       if (!ParseLine(string_buffer, "=\n", tokens, max_count, &token_count)) {
729         if (!strncmp(tokens[0], "panel_name", strlen("panel_name"))) {
730           snprintf(panel_info->panel_name, sizeof(panel_info->panel_name), "%s", tokens[1]);
731           break;
732         }
733       }
734     }
735     Sys::fclose_(fileptr);
736   }
737   free(string_buffer);
738 }
739 
GetHWPanelInfoByNode(int device_node,HWPanelInfo * panel_info)740 void HWDevice::GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info) {
741   if (!panel_info) {
742     DLOGE("PanelInfo pointer in invalid.");
743     return;
744   }
745   char stringbuffer[kMaxStringLength];
746   FILE *fileptr = NULL;
747   snprintf(stringbuffer, sizeof(stringbuffer), "%s%d/msm_fb_panel_info", fb_path_, device_node);
748   fileptr = Sys::fopen_(stringbuffer, "r");
749   if (!fileptr) {
750     DLOGW("Failed to open msm_fb_panel_info node device node %d", device_node);
751     return;
752   }
753 
754   char *line = stringbuffer;
755   size_t len = kMaxStringLength;
756   ssize_t read;
757 
758   while ((read = Sys::getline_(&line, &len, fileptr)) != -1) {
759     uint32_t token_count = 0;
760     const uint32_t max_count = 10;
761     char *tokens[max_count] = { NULL };
762     if (!ParseLine(line, tokens, max_count, &token_count)) {
763       if (!strncmp(tokens[0], "pu_en", strlen("pu_en"))) {
764         panel_info->partial_update = atoi(tokens[1]);
765       } else if (!strncmp(tokens[0], "xstart", strlen("xstart"))) {
766         panel_info->left_align = atoi(tokens[1]);
767       } else if (!strncmp(tokens[0], "walign", strlen("walign"))) {
768         panel_info->width_align = atoi(tokens[1]);
769       } else if (!strncmp(tokens[0], "ystart", strlen("ystart"))) {
770         panel_info->top_align = atoi(tokens[1]);
771       } else if (!strncmp(tokens[0], "halign", strlen("halign"))) {
772         panel_info->height_align = atoi(tokens[1]);
773       } else if (!strncmp(tokens[0], "min_w", strlen("min_w"))) {
774         panel_info->min_roi_width = atoi(tokens[1]);
775       } else if (!strncmp(tokens[0], "min_h", strlen("min_h"))) {
776         panel_info->min_roi_height = atoi(tokens[1]);
777       } else if (!strncmp(tokens[0], "roi_merge", strlen("roi_merge"))) {
778         panel_info->needs_roi_merge = atoi(tokens[1]);
779       } else if (!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
780         panel_info->dynamic_fps = atoi(tokens[1]);
781       } else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
782         panel_info->min_fps = UINT32(atoi(tokens[1]));
783       } else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
784         panel_info->max_fps = UINT32(atoi(tokens[1]));
785       } else if (!strncmp(tokens[0], "primary_panel", strlen("primary_panel"))) {
786         panel_info->is_primary_panel = atoi(tokens[1]);
787       } else if (!strncmp(tokens[0], "is_pluggable", strlen("is_pluggable"))) {
788         panel_info->is_pluggable = atoi(tokens[1]);
789       }
790     }
791   }
792   Sys::fclose_(fileptr);
793   GetHWDisplayPortAndMode(device_node, &panel_info->port, &panel_info->mode);
794   GetSplitInfo(device_node, panel_info);
795   GetHWPanelNameByNode(device_node, panel_info);
796   GetHWPanelMaxBrightnessFromNode(panel_info);
797 }
798 
GetHWDisplayPortAndMode(int device_node,HWDisplayPort * port,HWDisplayMode * mode)799 void HWDevice::GetHWDisplayPortAndMode(int device_node, HWDisplayPort *port, HWDisplayMode *mode) {
800   *port = kPortDefault;
801   *mode = kModeDefault;
802   char *stringbuffer = reinterpret_cast<char*>(malloc(sizeof(char) * kMaxStringLength));
803   if (!stringbuffer) {
804     DLOGE("Failed to allocated string_buffer memory");
805     return;
806   }
807 
808   snprintf(stringbuffer, kMaxStringLength, "%s%d/msm_fb_type", fb_path_, device_node);
809   FILE *fileptr = Sys::fopen_(stringbuffer, "r");
810   if (!fileptr) {
811     DLOGW("File not found %s", stringbuffer);
812     free(stringbuffer);
813     return;
814   }
815 
816   size_t len = kMaxStringLength;
817   ssize_t read = Sys::getline_(&stringbuffer, &len, fileptr);
818   if (read == -1) {
819     Sys::fclose_(fileptr);
820     free(stringbuffer);
821     return;
822   }
823   if ((strncmp(stringbuffer, "mipi dsi cmd panel", strlen("mipi dsi cmd panel")) == 0)) {
824     *port = kPortDSI;
825     *mode = kModeCommand;
826   } else if ((strncmp(stringbuffer, "mipi dsi video panel", strlen("mipi dsi video panel")) == 0)) {
827     *port = kPortDSI;
828     *mode = kModeVideo;
829   } else if ((strncmp(stringbuffer, "lvds panel", strlen("lvds panel")) == 0)) {
830     *port = kPortLVDS;
831     *mode = kModeVideo;
832   } else if ((strncmp(stringbuffer, "edp panel", strlen("edp panel")) == 0)) {
833     *port = kPortEDP;
834     *mode = kModeVideo;
835   } else if ((strncmp(stringbuffer, "dtv panel", strlen("dtv panel")) == 0)) {
836     *port = kPortDTv;
837     *mode = kModeVideo;
838   } else if ((strncmp(stringbuffer, "writeback panel", strlen("writeback panel")) == 0)) {
839     *port = kPortWriteBack;
840     *mode = kModeCommand;
841   }
842   Sys::fclose_(fileptr);
843   free(stringbuffer);
844 
845   return;
846 }
847 
GetSplitInfo(int device_node,HWPanelInfo * panel_info)848 void HWDevice::GetSplitInfo(int device_node, HWPanelInfo *panel_info) {
849   char stringbuffer[kMaxStringLength];
850   FILE *fileptr = NULL;
851   uint32_t token_count = 0;
852   const uint32_t max_count = 10;
853   char *tokens[max_count] = { NULL };
854 
855   // Split info - for MDSS Version 5 - No need to check version here
856   snprintf(stringbuffer , sizeof(stringbuffer), "%s%d/msm_fb_split", fb_path_, device_node);
857   fileptr = Sys::fopen_(stringbuffer, "r");
858   if (!fileptr) {
859     DLOGW("File not found %s", stringbuffer);
860     return;
861   }
862 
863   char *line = stringbuffer;
864   size_t len = kMaxStringLength;
865   ssize_t read;
866 
867   // Format "left right" space as delimiter
868   read = Sys::getline_(&line, &len, fileptr);
869   if (read > 0) {
870     if (!ParseLine(line, tokens, max_count, &token_count)) {
871       panel_info->split_info.left_split = UINT32(atoi(tokens[0]));
872       panel_info->split_info.right_split = UINT32(atoi(tokens[1]));
873     }
874   }
875 
876   Sys::fclose_(fileptr);
877 }
878 
GetHWPanelMaxBrightnessFromNode(HWPanelInfo * panel_info)879 void HWDevice::GetHWPanelMaxBrightnessFromNode(HWPanelInfo *panel_info) {
880   char brightness[kMaxStringLength] = { 0 };
881   char kMaxBrightnessNode[64] = { 0 };
882 
883   snprintf(kMaxBrightnessNode, sizeof(kMaxBrightnessNode), "%s",
884            "/sys/class/leds/lcd-backlight/max_brightness");
885 
886   panel_info->panel_max_brightness = 0;
887   int fd = Sys::open_(kMaxBrightnessNode, O_RDONLY);
888   if (fd < 0) {
889     DLOGW("Failed to open max brightness node = %s, error = %s", kMaxBrightnessNode,
890           strerror(errno));
891     return;
892   }
893 
894   if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
895     panel_info->panel_max_brightness = atoi(brightness);
896     DLOGW("Max brightness level = %d", panel_info->panel_max_brightness);
897   } else {
898     DLOGW("Failed to read max brightness level. error = %s", strerror(errno));
899   }
900   Sys::close_(fd);
901 }
902 
ParseLine(char * input,char * tokens[],const uint32_t max_token,uint32_t * count)903 int HWDevice::ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) {
904   char *tmp_token = NULL;
905   char *temp_ptr;
906   uint32_t index = 0;
907   const char *delim = ", =\n";
908   if (!input) {
909     return -1;
910   }
911   tmp_token = strtok_r(input, delim, &temp_ptr);
912   while (tmp_token && index < max_token) {
913     tokens[index++] = tmp_token;
914     tmp_token = strtok_r(NULL, delim, &temp_ptr);
915   }
916   *count = index;
917 
918   return 0;
919 }
920 
ParseLine(char * input,const char * delim,char * tokens[],const uint32_t max_token,uint32_t * count)921 int HWDevice::ParseLine(char *input, const char *delim, char *tokens[],
922                         const uint32_t max_token, uint32_t *count) {
923   char *tmp_token = NULL;
924   char *temp_ptr;
925   uint32_t index = 0;
926   if (!input) {
927     return -1;
928   }
929   tmp_token = strtok_r(input, delim, &temp_ptr);
930   while (tmp_token && index < max_token) {
931     tokens[index++] = tmp_token;
932     tmp_token = strtok_r(NULL, delim, &temp_ptr);
933   }
934   *count = index;
935 
936   return 0;
937 }
938 
EnableHotPlugDetection(int enable)939 bool HWDevice::EnableHotPlugDetection(int enable) {
940   char hpdpath[kMaxStringLength];
941   int hdmi_node_index = GetFBNodeIndex(kDeviceHDMI);
942   if (hdmi_node_index < 0) {
943     return false;
944   }
945 
946   snprintf(hpdpath , sizeof(hpdpath), "%s%d/hpd", fb_path_, hdmi_node_index);
947 
948   char value = enable ? '1' : '0';
949   ssize_t length = SysFsWrite(hpdpath, &value, sizeof(value));
950   if (length <= 0) {
951     return false;
952   }
953 
954   return true;
955 }
956 
ResetDisplayParams()957 void HWDevice::ResetDisplayParams() {
958   memset(&mdp_disp_commit_, 0, sizeof(mdp_disp_commit_));
959   memset(&mdp_in_layers_, 0, sizeof(mdp_in_layers_));
960   memset(&mdp_out_layer_, 0, sizeof(mdp_out_layer_));
961   memset(&scale_data_, 0, sizeof(scale_data_));
962   memset(&pp_params_, 0, sizeof(pp_params_));
963   memset(&igc_lut_data_, 0, sizeof(igc_lut_data_));
964 
965   for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
966     mdp_in_layers_[i].buffer.fence = -1;
967   }
968 
969   mdp_disp_commit_.version = MDP_COMMIT_VERSION_1_0;
970   mdp_disp_commit_.commit_v1.input_layers = mdp_in_layers_;
971   mdp_disp_commit_.commit_v1.output_layer = &mdp_out_layer_;
972   mdp_disp_commit_.commit_v1.release_fence = -1;
973   mdp_disp_commit_.commit_v1.retire_fence = -1;
974 }
975 
SetHWScaleData(const ScaleData & scale,uint32_t index)976 void HWDevice::SetHWScaleData(const ScaleData &scale, uint32_t index) {
977   mdp_scale_data *mdp_scale = GetScaleDataRef(index);
978   mdp_scale->enable_pxl_ext = scale.enable_pixel_ext;
979 
980   for (int i = 0; i < 4; i++) {
981     const HWPlane &plane = scale.plane[i];
982     mdp_scale->init_phase_x[i] = plane.init_phase_x;
983     mdp_scale->phase_step_x[i] = plane.phase_step_x;
984     mdp_scale->init_phase_y[i] = plane.init_phase_y;
985     mdp_scale->phase_step_y[i] = plane.phase_step_y;
986 
987     mdp_scale->num_ext_pxls_left[i] = plane.left.extension;
988     mdp_scale->left_ftch[i] = plane.left.overfetch;
989     mdp_scale->left_rpt[i] = plane.left.repeat;
990 
991     mdp_scale->num_ext_pxls_top[i] = plane.top.extension;
992     mdp_scale->top_ftch[i] = plane.top.overfetch;
993     mdp_scale->top_rpt[i] = plane.top.repeat;
994 
995     mdp_scale->num_ext_pxls_right[i] = plane.right.extension;
996     mdp_scale->right_ftch[i] = plane.right.overfetch;
997     mdp_scale->right_rpt[i] = plane.right.repeat;
998 
999     mdp_scale->num_ext_pxls_btm[i] = plane.bottom.extension;
1000     mdp_scale->btm_ftch[i] = plane.bottom.overfetch;
1001     mdp_scale->btm_rpt[i] = plane.bottom.repeat;
1002 
1003     mdp_scale->roi_w[i] = plane.roi_width;
1004   }
1005 }
1006 
SetCSC(LayerCSC source,mdp_color_space * color_space)1007 void HWDevice::SetCSC(LayerCSC source, mdp_color_space *color_space) {
1008   switch (source) {
1009   case kCSCLimitedRange601:    *color_space = MDP_CSC_ITU_R_601;      break;
1010   case kCSCFullRange601:       *color_space = MDP_CSC_ITU_R_601_FR;   break;
1011   case kCSCLimitedRange709:    *color_space = MDP_CSC_ITU_R_709;      break;
1012   }
1013 }
1014 
SetIGC(const Layer & layer,uint32_t index)1015 void HWDevice::SetIGC(const Layer &layer, uint32_t index) {
1016   mdp_input_layer &mdp_layer = mdp_in_layers_[index];
1017   mdp_overlay_pp_params &pp_params = pp_params_[index];
1018   mdp_igc_lut_data_v1_7 &igc_lut_data = igc_lut_data_[index];
1019 
1020   switch (layer.igc) {
1021   case kIGCsRGB:
1022     igc_lut_data.table_fmt = mdp_igc_srgb;
1023     pp_params.igc_cfg.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
1024     break;
1025 
1026   default:
1027     pp_params.igc_cfg.ops = MDP_PP_OPS_DISABLE;
1028     break;
1029   }
1030 
1031   pp_params.config_ops = MDP_OVERLAY_PP_IGC_CFG;
1032   pp_params.igc_cfg.version = mdp_igc_v1_7;
1033   pp_params.igc_cfg.cfg_payload = &igc_lut_data;
1034 
1035   mdp_layer.pp_info = &pp_params;
1036   mdp_layer.flags |= MDP_LAYER_PP;
1037 }
1038 
SetCursorPosition(HWLayers * hw_layers,int x,int y)1039 DisplayError HWDevice::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
1040   DTRACE_SCOPED();
1041 
1042   HWLayersInfo &hw_layer_info = hw_layers->info;
1043   uint32_t count = hw_layer_info.count;
1044   uint32_t cursor_index = count - 1;
1045   HWPipeInfo *left_pipe = &hw_layers->config[cursor_index].left_pipe;
1046 
1047   STRUCT_VAR(mdp_async_layer, async_layer);
1048   async_layer.flags = MDP_LAYER_ASYNC;
1049   async_layer.pipe_ndx = left_pipe->pipe_id;
1050   async_layer.src.x = UINT32(left_pipe->src_roi.left);
1051   async_layer.src.y = UINT32(left_pipe->src_roi.top);
1052   async_layer.dst.x = UINT32(x);
1053   async_layer.dst.y = UINT32(y);
1054 
1055   STRUCT_VAR(mdp_position_update, pos_update);
1056   pos_update.input_layer_cnt = 1;
1057   pos_update.input_layers = &async_layer;
1058   if (Sys::ioctl_(device_fd_, INT(MSMFB_ASYNC_POSITION_UPDATE), &pos_update) < 0) {
1059     if (errno == ESHUTDOWN) {
1060       DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
1061       return kErrorShutDown;
1062     }
1063     IOCTL_LOGE(MSMFB_ASYNC_POSITION_UPDATE, device_type_);
1064     return kErrorHardware;
1065   }
1066 
1067   return kErrorNone;
1068 }
1069 
GetPPFeaturesVersion(PPFeatureVersion * vers)1070 DisplayError HWDevice::GetPPFeaturesVersion(PPFeatureVersion *vers) {
1071   return kErrorNotSupported;
1072 }
1073 
SetPPFeatures(PPFeaturesConfig * feature_list)1074 DisplayError HWDevice::SetPPFeatures(PPFeaturesConfig *feature_list) {
1075   return kErrorNotSupported;
1076 }
1077 
SetVSyncState(bool enable)1078 DisplayError HWDevice::SetVSyncState(bool enable) {
1079   return kErrorNotSupported;
1080 }
1081 
SetIdleTimeoutMs(uint32_t timeout_ms)1082 void HWDevice::SetIdleTimeoutMs(uint32_t timeout_ms) {
1083 }
1084 
SetDisplayMode(const HWDisplayMode hw_display_mode)1085 DisplayError HWDevice::SetDisplayMode(const HWDisplayMode hw_display_mode) {
1086   return kErrorNotSupported;
1087 }
1088 
SetRefreshRate(uint32_t refresh_rate)1089 DisplayError HWDevice::SetRefreshRate(uint32_t refresh_rate) {
1090   return kErrorNotSupported;
1091 }
1092 
SetPanelBrightness(int level)1093 DisplayError HWDevice::SetPanelBrightness(int level) {
1094   return kErrorNotSupported;
1095 }
1096 
GetHWScanInfo(HWScanInfo * scan_info)1097 DisplayError HWDevice::GetHWScanInfo(HWScanInfo *scan_info) {
1098   return kErrorNotSupported;
1099 }
1100 
GetVideoFormat(uint32_t config_index,uint32_t * video_format)1101 DisplayError HWDevice::GetVideoFormat(uint32_t config_index, uint32_t *video_format) {
1102   return kErrorNotSupported;
1103 }
1104 
GetMaxCEAFormat(uint32_t * max_cea_format)1105 DisplayError HWDevice::GetMaxCEAFormat(uint32_t *max_cea_format) {
1106   return kErrorNotSupported;
1107 }
1108 
OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level)1109 DisplayError HWDevice::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1110   return kErrorNotSupported;
1111 }
1112 
GetPanelBrightness(int * level)1113 DisplayError HWDevice::GetPanelBrightness(int *level) {
1114   return kErrorNotSupported;
1115 }
1116 
SysFsWrite(const char * file_node,const char * value,ssize_t length)1117 ssize_t HWDevice::SysFsWrite(const char* file_node, const char* value, ssize_t length) {
1118   int fd = Sys::open_(file_node, O_RDWR, 0);
1119   if (fd < 0) {
1120     DLOGW("Open failed = %s", file_node);
1121     return -1;
1122   }
1123   ssize_t len = Sys::pwrite_(fd, value, static_cast<size_t>(length), 0);
1124   if (len <= 0) {
1125     DLOGE("Write failed for path %s with value %s", file_node, value);
1126   }
1127   Sys::close_(fd);
1128 
1129   return len;
1130 }
1131 
SetS3DMode(HWS3DMode s3d_mode)1132 DisplayError HWDevice::SetS3DMode(HWS3DMode s3d_mode) {
1133   return kErrorNotSupported;
1134 }
1135 
1136 }  // namespace sdm
1137 
1138