blob: 617145f8c3a8a3de9847294cd0b68d4a5be8c940 [file] [log] [blame]
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001/*
Gousemoodhin Nadafc81fd0b2019-01-16 14:40:39 +05302* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
Saurabh Shah7d476ed2016-06-27 16:40:58 -07003*
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
Saurabh Shah7d476ed2016-06-27 16:40:58 -070032#include <ctype.h>
Saurabh Shahf84c4122017-04-07 10:34:40 -070033#include <drm/drm_fourcc.h>
Saurabh Shah66c941b2016-07-06 17:34:05 -070034#include <drm_lib_loader.h>
35#include <drm_master.h>
36#include <drm_res_mgr.h>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070037#include <fcntl.h>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070038#include <inttypes.h>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070039#include <linux/fb.h>
Saurabh Shah66c941b2016-07-06 17:34:05 -070040#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>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070047#include <utils/constants.h>
48#include <utils/debug.h>
Saurabh Shahf84c4122017-04-07 10:34:40 -070049#include <utils/formats.h>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070050#include <utils/sys.h>
Sushil Chauhan3396e202017-04-14 18:34:22 -070051#include <drm/sde_drm.h>
Ping Li281f48d2017-01-16 12:45:40 -080052#include <private/color_params.h>
Rohit Kulkarni8622e362017-01-30 18:14:10 -080053#include <utils/rect.h>
Varun Aroraf182bfa2018-08-14 10:49:08 -070054#include <utils/utils.h>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070055
Varun Arora7c8ee542018-05-01 20:58:16 -070056#include <sstream>
57#include <ctime>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070058#include <algorithm>
59#include <string>
Saurabh Shahf84c4122017-04-07 10:34:40 -070060#include <unordered_map>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070061#include <utility>
62#include <vector>
Gopikrishnaiah Anandan739faf92017-07-21 12:32:00 -070063#include <limits>
Saurabh Shah7d476ed2016-06-27 16:40:58 -070064
65#include "hw_device_drm.h"
66#include "hw_info_interface.h"
67
68#define __CLASS__ "HWDeviceDRM"
69
Saurabh Shahf84c4122017-04-07 10:34:40 -070070#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
71#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
72#endif
73#ifndef DRM_FORMAT_MOD_QCOM_DX
74#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
75#endif
76#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
77#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
78#endif
79
Saurabh Shah7d476ed2016-06-27 16:40:58 -070080using std::string;
81using std::to_string;
82using std::fstream;
Saurabh Shahf84c4122017-04-07 10:34:40 -070083using std::unordered_map;
Varun Arora7c8ee542018-05-01 20:58:16 -070084using std::stringstream;
85using std::ifstream;
86using std::ofstream;
Saurabh Shah7d476ed2016-06-27 16:40:58 -070087using drm_utils::DRMMaster;
88using drm_utils::DRMResMgr;
Saurabh Shah66c941b2016-07-06 17:34:05 -070089using drm_utils::DRMLibLoader;
Saurabh Shahf84c4122017-04-07 10:34:40 -070090using drm_utils::DRMBuffer;
Saurabh Shah66c941b2016-07-06 17:34:05 -070091using sde_drm::GetDRMManager;
92using sde_drm::DestroyDRMManager;
93using sde_drm::DRMDisplayType;
94using sde_drm::DRMDisplayToken;
95using sde_drm::DRMConnectorInfo;
Ping Li281f48d2017-01-16 12:45:40 -080096using sde_drm::DRMPPFeatureInfo;
Saurabh Shah66c941b2016-07-06 17:34:05 -070097using sde_drm::DRMRect;
Saurabh Shahf9266ee2017-04-19 15:25:46 -070098using sde_drm::DRMRotation;
Saurabh Shah66c941b2016-07-06 17:34:05 -070099using sde_drm::DRMBlendType;
Prabhanjan Kandula585aa652017-01-26 18:39:11 -0800100using sde_drm::DRMSrcConfig;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700101using sde_drm::DRMOps;
102using sde_drm::DRMTopology;
Sushil Chauhan3396e202017-04-14 18:34:22 -0700103using sde_drm::DRMPowerMode;
Sushil Chauhan1021cc02017-05-03 15:11:43 -0700104using sde_drm::DRMSecureMode;
105using sde_drm::DRMSecurityLevel;
Ping Li8d6dd622017-07-03 12:05:15 -0700106using sde_drm::DRMCscType;
Ramkumar Radhakrishnan07254302017-11-13 16:18:22 -0800107using sde_drm::DRMMultiRectMode;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700108
109namespace sdm {
110
Arun Kumar K.Rc033f942018-01-05 12:25:47 +0530111static PPBlock GetPPBlock(const HWToneMapLut &lut_type) {
112 PPBlock pp_block = kPPBlockMax;
113 switch (lut_type) {
114 case kDma1dIgc:
115 case kDma1dGc:
116 pp_block = kDGM;
117 break;
118 case kVig1dIgc:
119 case kVig3dGamut:
120 pp_block = kVIG;
121 break;
122 default:
123 DLOGE("Unknown PP Block");
124 break;
125 }
126 return pp_block;
127}
128
Saurabh Shahf84c4122017-04-07 10:34:40 -0700129static void GetDRMFormat(LayerBufferFormat format, uint32_t *drm_format,
130 uint64_t *drm_format_modifier) {
131 switch (format) {
132 case kFormatRGBA8888:
133 *drm_format = DRM_FORMAT_ABGR8888;
134 break;
135 case kFormatRGBA8888Ubwc:
136 *drm_format = DRM_FORMAT_ABGR8888;
137 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
138 break;
139 case kFormatRGBA5551:
140 *drm_format = DRM_FORMAT_ABGR1555;
141 break;
142 case kFormatRGBA4444:
143 *drm_format = DRM_FORMAT_ABGR4444;
144 break;
145 case kFormatBGRA8888:
146 *drm_format = DRM_FORMAT_ARGB8888;
147 break;
148 case kFormatRGBX8888:
149 *drm_format = DRM_FORMAT_XBGR8888;
150 break;
151 case kFormatRGBX8888Ubwc:
152 *drm_format = DRM_FORMAT_XBGR8888;
153 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
154 break;
155 case kFormatBGRX8888:
156 *drm_format = DRM_FORMAT_XRGB8888;
157 break;
158 case kFormatRGB888:
159 *drm_format = DRM_FORMAT_BGR888;
160 break;
161 case kFormatRGB565:
162 *drm_format = DRM_FORMAT_BGR565;
163 break;
164 case kFormatBGR565:
165 *drm_format = DRM_FORMAT_RGB565;
166 break;
167 case kFormatBGR565Ubwc:
168 *drm_format = DRM_FORMAT_BGR565;
169 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
170 break;
171 case kFormatRGBA1010102:
172 *drm_format = DRM_FORMAT_ABGR2101010;
173 break;
174 case kFormatRGBA1010102Ubwc:
175 *drm_format = DRM_FORMAT_ABGR2101010;
176 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
177 break;
178 case kFormatARGB2101010:
179 *drm_format = DRM_FORMAT_BGRA1010102;
180 break;
181 case kFormatRGBX1010102:
182 *drm_format = DRM_FORMAT_XBGR2101010;
183 break;
184 case kFormatRGBX1010102Ubwc:
185 *drm_format = DRM_FORMAT_XBGR2101010;
186 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
187 break;
188 case kFormatXRGB2101010:
189 *drm_format = DRM_FORMAT_BGRX1010102;
190 break;
191 case kFormatBGRA1010102:
192 *drm_format = DRM_FORMAT_ARGB2101010;
193 break;
194 case kFormatABGR2101010:
195 *drm_format = DRM_FORMAT_RGBA1010102;
196 break;
197 case kFormatBGRX1010102:
198 *drm_format = DRM_FORMAT_XRGB2101010;
199 break;
200 case kFormatXBGR2101010:
201 *drm_format = DRM_FORMAT_RGBX1010102;
202 break;
203 case kFormatYCbCr420SemiPlanar:
204 *drm_format = DRM_FORMAT_NV12;
205 break;
206 case kFormatYCbCr420SemiPlanarVenus:
207 *drm_format = DRM_FORMAT_NV12;
208 break;
209 case kFormatYCbCr420SPVenusUbwc:
210 *drm_format = DRM_FORMAT_NV12;
211 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
212 break;
Rohit Kulkarni2d7151c2017-12-14 22:17:49 -0800213 case kFormatYCbCr420SPVenusTile:
214 *drm_format = DRM_FORMAT_NV12;
215 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE;
216 break;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700217 case kFormatYCrCb420SemiPlanar:
218 *drm_format = DRM_FORMAT_NV21;
219 break;
220 case kFormatYCrCb420SemiPlanarVenus:
221 *drm_format = DRM_FORMAT_NV21;
222 break;
223 case kFormatYCbCr420P010:
Mathew Joseph Karimpanala73082e2017-10-16 18:01:21 +0530224 case kFormatYCbCr420P010Venus:
Saurabh Shahf84c4122017-04-07 10:34:40 -0700225 *drm_format = DRM_FORMAT_NV12;
226 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
227 break;
228 case kFormatYCbCr420P010Ubwc:
229 *drm_format = DRM_FORMAT_NV12;
230 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
231 DRM_FORMAT_MOD_QCOM_DX;
232 break;
Rohit Kulkarni2d7151c2017-12-14 22:17:49 -0800233 case kFormatYCbCr420P010Tile:
234 *drm_format = DRM_FORMAT_NV12;
235 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE |
236 DRM_FORMAT_MOD_QCOM_DX;
237 break;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700238 case kFormatYCbCr420TP10Ubwc:
239 *drm_format = DRM_FORMAT_NV12;
240 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
241 DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
242 break;
Rohit Kulkarni2d7151c2017-12-14 22:17:49 -0800243 case kFormatYCbCr420TP10Tile:
244 *drm_format = DRM_FORMAT_NV12;
245 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE |
246 DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
247 break;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700248 case kFormatYCbCr422H2V1SemiPlanar:
249 *drm_format = DRM_FORMAT_NV16;
250 break;
251 case kFormatYCrCb422H2V1SemiPlanar:
252 *drm_format = DRM_FORMAT_NV61;
253 break;
254 case kFormatYCrCb420PlanarStride16:
255 *drm_format = DRM_FORMAT_YVU420;
256 break;
257 default:
258 DLOGW("Unsupported format %s", GetFormatString(format));
259 }
260}
261
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700262class FrameBufferObject : public LayerBufferObject {
263 public:
Xiaowen Wu35425092019-04-29 17:11:51 -0400264 explicit FrameBufferObject(uint32_t fb_id, LayerBufferFormat format,
265 uint32_t width, uint32_t height)
266 :fb_id_(fb_id), format_(format), width_(width), height_(height) {
Saurabh Shah23cd08a2017-07-10 15:18:14 -0700267 }
268
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700269 ~FrameBufferObject() {
270 DRMMaster *master;
271 DRMMaster::GetInstance(&master);
272 int ret = master->RemoveFbId(fb_id_);
273 if (ret < 0) {
274 DLOGE("Removing fb_id %d failed with error %d", fb_id_, errno);
275 }
276 }
277 uint32_t GetFbId() { return fb_id_; }
Xiaowen Wu35425092019-04-29 17:11:51 -0400278 bool IsEqual(LayerBufferFormat format, uint32_t width, uint32_t height) {
279 return (format == format_ && width == width_ && height == height_);
280 }
Saurabh Shah23cd08a2017-07-10 15:18:14 -0700281
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700282 private:
283 uint32_t fb_id_;
Xiaowen Wu35425092019-04-29 17:11:51 -0400284 LayerBufferFormat format_;
285 uint32_t width_;
286 uint32_t height_;
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700287};
288
289HWDeviceDRM::Registry::Registry(BufferAllocator *buffer_allocator) :
290 buffer_allocator_(buffer_allocator) {
291 int value = 0;
292 if (Debug::GetProperty(DISABLE_FBID_CACHE, &value) == kErrorNone) {
293 disable_fbid_cache_ = (value == 1);
294 }
Saurabh Shah23cd08a2017-07-10 15:18:14 -0700295}
296
Saurabh Shah4d4f4002017-12-26 12:42:59 -0800297void HWDeviceDRM::Registry::Register(HWLayers *hw_layers) {
Saurabh Shahf84c4122017-04-07 10:34:40 -0700298 HWLayersInfo &hw_layer_info = hw_layers->info;
299 uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
300
301 for (uint32_t i = 0; i < hw_layer_count; i++) {
302 Layer &layer = hw_layer_info.hw_layers.at(i);
303 LayerBuffer *input_buffer = &layer.input_buffer;
304 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
305 HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700306 fbid_cache_limit_ = input_buffer->flags.video ? VIDEO_FBID_LIMIT : UI_FBID_LIMIT;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700307
Rohit Kulkarni8622e362017-01-30 18:14:10 -0800308 if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) {
Saurabh Shahf84c4122017-04-07 10:34:40 -0700309 input_buffer = &hw_rotator_session->output_buffer;
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700310 fbid_cache_limit_ = OFFLINE_ROTATOR_FBID_LIMIT;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700311 }
312
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700313 MapBufferToFbId(&layer, input_buffer);
Mahesh Aia1d2ceda2017-03-24 11:07:31 -0700314 }
315}
316
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700317int HWDeviceDRM::Registry::CreateFbId(LayerBuffer *buffer, uint32_t *fb_id) {
Mahesh Aia1d2ceda2017-03-24 11:07:31 -0700318 DRMMaster *master = nullptr;
319 DRMMaster::GetInstance(&master);
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700320 int ret = -1;
Mahesh Aia1d2ceda2017-03-24 11:07:31 -0700321
322 if (!master) {
323 DLOGE("Failed to acquire DRM Master instance");
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700324 return ret;
325 }
326
327 DRMBuffer layout{};
328 AllocatedBufferInfo buf_info{};
329 buf_info.fd = layout.fd = buffer->planes[0].fd;
330 buf_info.aligned_width = layout.width = buffer->width;
331 buf_info.aligned_height = layout.height = buffer->height;
332 buf_info.format = buffer->format;
333 GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
334 buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset, &layout.num_planes);
335 ret = master->CreateFbId(layout, fb_id);
336 if (ret < 0) {
337 DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
338 layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0], errno);
339 }
340
341 return ret;
342}
343
344void HWDeviceDRM::Registry::MapBufferToFbId(Layer* layer, LayerBuffer* buffer) {
345 if (buffer->planes[0].fd < 0) {
Mahesh Aia1d2ceda2017-03-24 11:07:31 -0700346 return;
347 }
348
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700349 uint64_t handle_id = buffer->handle_id;
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700350 if (!handle_id || disable_fbid_cache_) {
351 // In legacy path, clear fb_id map in each frame.
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700352 layer->buffer_map->buffer_map.clear();
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700353 } else {
Xiaowen Wu35425092019-04-29 17:11:51 -0400354 auto it = layer->buffer_map->buffer_map.find(handle_id);
355 if (it != layer->buffer_map->buffer_map.end()) {
356 FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
357 if (fb_obj->IsEqual(buffer->format, buffer->width, buffer->height)) {
358 // Found fb_id for given handle_id key
359 return;
360 } else {
361 // Erase from fb_id map if format or size have been modified
362 layer->buffer_map->buffer_map.erase(it);
363 }
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700364 }
Saurabh Shahf84c4122017-04-07 10:34:40 -0700365
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700366 if (layer->buffer_map->buffer_map.size() >= fbid_cache_limit_) {
367 // Clear fb_id map, if the size reaches cache limit.
368 layer->buffer_map->buffer_map.clear();
369 }
Saurabh Shahf84c4122017-04-07 10:34:40 -0700370 }
371
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700372 uint32_t fb_id = 0;
373 if (CreateFbId(buffer, &fb_id) >= 0) {
374 // Create and cache the fb_id in map
Xiaowen Wu35425092019-04-29 17:11:51 -0400375 layer->buffer_map->buffer_map[handle_id] = std::make_shared<FrameBufferObject>(fb_id,
376 buffer->format, buffer->width, buffer->height);
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700377 }
378}
379
380void HWDeviceDRM::Registry::MapOutputBufferToFbId(LayerBuffer *output_buffer) {
381 if (output_buffer->planes[0].fd < 0) {
382 return;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700383 }
384
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700385 uint64_t handle_id = output_buffer->handle_id;
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700386 if (!handle_id || disable_fbid_cache_) {
387 // In legacy path, clear output buffer map in each frame.
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700388 output_buffer_map_.clear();
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700389 } else {
Xiaowen Wu35425092019-04-29 17:11:51 -0400390 auto it = output_buffer_map_.find(handle_id);
391 if (it != output_buffer_map_.end()) {
392 FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
393 if (fb_obj->IsEqual(output_buffer->format, output_buffer->width, output_buffer->height)) {
394 return;
395 } else {
396 output_buffer_map_.erase(it);
397 }
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700398 }
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700399
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700400 if (output_buffer_map_.size() >= UI_FBID_LIMIT) {
401 // Clear output buffer map, if the size reaches cache limit.
402 output_buffer_map_.clear();
403 }
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700404 }
405
406 uint32_t fb_id = 0;
407 if (CreateFbId(output_buffer, &fb_id) >= 0) {
Xiaowen Wu35425092019-04-29 17:11:51 -0400408 output_buffer_map_[handle_id] = std::make_shared<FrameBufferObject>(fb_id,
409 output_buffer->format, output_buffer->width, output_buffer->height);
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700410 }
Saurabh Shahf84c4122017-04-07 10:34:40 -0700411}
412
413void HWDeviceDRM::Registry::Clear() {
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700414 output_buffer_map_.clear();
Saurabh Shahf84c4122017-04-07 10:34:40 -0700415}
416
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700417uint32_t HWDeviceDRM::Registry::GetFbId(Layer *layer, uint64_t handle_id) {
418 auto it = layer->buffer_map->buffer_map.find(handle_id);
419 if (it != layer->buffer_map->buffer_map.end()) {
420 FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
421 return fb_obj->GetFbId();
422 }
423
424 return 0;
425}
426
427uint32_t HWDeviceDRM::Registry::GetOutputFbId(uint64_t handle_id) {
428 auto it = output_buffer_map_.find(handle_id);
429 if (it != output_buffer_map_.end()) {
430 FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
431 return fb_obj->GetFbId();
432 }
433
434 return 0;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700435}
436
437HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
438 HWInfoInterface *hw_info_intf)
439 : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
440 registry_(buffer_allocator) {
Saurabh Shah66c941b2016-07-06 17:34:05 -0700441 hw_info_intf_ = hw_info_intf;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700442}
443
444DisplayError HWDeviceDRM::Init() {
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530445 int ret = 0;
Saurabh Shah7e16c932017-11-03 17:55:36 -0700446 DRMMaster *drm_master = {};
447 DRMMaster::GetInstance(&drm_master);
448 drm_master->GetHandle(&dev_fd_);
449 DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700450
Mathew Joseph Karimpanal731bc932017-11-22 10:04:56 +0530451 if (-1 == display_id_) {
452 if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
453 DLOGE("RegisterDisplay (by type) failed for %s", device_name_);
454 return kErrorResources;
455 }
456 } else if (drm_mgr_intf_->RegisterDisplay(display_id_, &token_)) {
457 DLOGE("RegisterDisplay (by id) failed for %s - %d", device_name_, display_id_);
Saurabh Shah7e16c932017-11-03 17:55:36 -0700458 return kErrorResources;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700459 }
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700460
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530461 if (token_.conn_id > INT32_MAX) {
462 DLOGE("Connector id %u beyond supported range", token_.conn_id);
Varun Arora6ba9eda2019-02-07 17:59:32 -0800463 drm_mgr_intf_->UnregisterDisplay(&token_);
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530464 return kErrorNotSupported;
465 }
466
Mathew Joseph Karimpanal731bc932017-11-22 10:04:56 +0530467 display_id_ = static_cast<int32_t>(token_.conn_id);
468
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530469 ret = drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
470 if (ret) {
471 DLOGE("Failed creating atomic request for connector id %u. Error: %d.", token_.conn_id, ret);
Varun Arora6ba9eda2019-02-07 17:59:32 -0800472 drm_mgr_intf_->UnregisterDisplay(&token_);
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530473 return kErrorResources;
474 }
475
476 ret = drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
477 if (ret) {
478 DLOGE("Failed getting info for connector id %u. Error: %d.", token_.conn_id, ret);
479 drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
480 drm_atomic_intf_ = {};
Varun Arora6ba9eda2019-02-07 17:59:32 -0800481 drm_mgr_intf_->UnregisterDisplay(&token_);
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530482 return kErrorHardware;
483 }
484
Mathew Joseph Karimpanal23e2da02018-11-13 17:44:43 +0530485 if (!connector_info_.is_connected || connector_info_.modes.empty()) {
486 DLOGW("Device removal detected on connector id %u. Connector status %s and %d modes.",
487 token_.conn_id, connector_info_.is_connected ? "connected":"disconnected",
488 connector_info_.modes.size());
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530489 drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
490 drm_atomic_intf_ = {};
Varun Arora6ba9eda2019-02-07 17:59:32 -0800491 drm_mgr_intf_->UnregisterDisplay(&token_);
Mathew Joseph Karimpanal23e2da02018-11-13 17:44:43 +0530492 return kErrorDeviceRemoved;
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530493 }
494
Saurabh Shah66c941b2016-07-06 17:34:05 -0700495 hw_info_intf_->GetHWResourceInfo(&hw_resource_);
Saurabh Shah7e16c932017-11-03 17:55:36 -0700496
497 InitializeConfigs();
498 PopulateHWPanelInfo();
499 UpdateMixerAttributes();
500
Saurabh Shah0ffee302016-11-22 10:42:11 -0800501 // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
502 if (hw_resource_.has_qseed3) {
503 hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
504 }
Saurabh Shah7e16c932017-11-03 17:55:36 -0700505
Rajesh Yadavc4f67b82017-11-15 20:37:13 +0530506 std::unique_ptr<HWColorManagerDrm> hw_color_mgr(new HWColorManagerDrm());
507 hw_color_mgr_ = std::move(hw_color_mgr);
508
Saurabh Shah66c941b2016-07-06 17:34:05 -0700509 return kErrorNone;
510}
511
512DisplayError HWDeviceDRM::Deinit() {
Saurabh Shah3cbc1ae2017-09-12 16:07:41 -0700513 DisplayError err = kErrorNone;
Mathew Joseph Karimpanal23e2da02018-11-13 17:44:43 +0530514 if (!first_cycle_) {
515 // A null-commit is needed only if the first commit had gone through. e.g., If a pluggable
516 // display is plugged in and plugged out immediately, HWDeviceDRM::Deinit() may be called
517 // before any commit happened on the device. The driver may have removed any not-in-use
518 // connector (i.e., any connector which did not have a display commit on it and a crtc path
519 // setup), so token_.conn_id may have been removed if there was no commit, resulting in
520 // drmModeAtomicCommit() failure with ENOENT, 'No such file or directory'.
521 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, 0);
522 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
523 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, nullptr);
524 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
525 int ret = NullCommit(true /* synchronous */, false /* retain_planes */);
526 if (ret) {
527 DLOGE("Commit failed with error: %d", ret);
528 err = kErrorHardware;
529 }
Saurabh Shah3cbc1ae2017-09-12 16:07:41 -0700530 }
Saurabh Shah0ffee302016-11-22 10:42:11 -0800531 delete hw_scale_;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700532 registry_.Clear();
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700533 display_attributes_ = {};
Saurabh Shah66c941b2016-07-06 17:34:05 -0700534 drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
535 drm_atomic_intf_ = {};
Varun Arora6ba9eda2019-02-07 17:59:32 -0800536 drm_mgr_intf_->UnregisterDisplay(&token_);
Saurabh Shah3cbc1ae2017-09-12 16:07:41 -0700537 return err;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700538}
539
Mathew Joseph Karimpanal731bc932017-11-22 10:04:56 +0530540DisplayError HWDeviceDRM::GetDisplayId(int32_t *display_id) {
541 *display_id = display_id_;
542 return kErrorNone;
543}
544
Saurabh Shah66c941b2016-07-06 17:34:05 -0700545void HWDeviceDRM::InitializeConfigs() {
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700546 current_mode_index_ = 0;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530547 // Update current mode with preferred mode
548 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -0700549 if (connector_info_.modes[mode_index].mode.type & DRM_MODE_TYPE_PREFERRED) {
Mathew Joseph Karimpanal351bf872018-08-28 16:08:28 +0530550 DLOGI("Updating current display mode %d to preferred mode %d.", current_mode_index_,
551 mode_index);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530552 current_mode_index_ = mode_index;
553 break;
554 }
555 }
556
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700557 display_attributes_.resize(connector_info_.modes.size());
558
Saurabh Shah7e16c932017-11-03 17:55:36 -0700559 uint32_t width = connector_info_.modes[current_mode_index_].mode.hdisplay;
560 uint32_t height = connector_info_.modes[current_mode_index_].mode.vdisplay;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700561 for (uint32_t i = 0; i < connector_info_.modes.size(); i++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -0700562 auto &mode = connector_info_.modes[i].mode;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700563 if (mode.hdisplay != width || mode.vdisplay != height) {
564 resolution_switch_enabled_ = true;
565 }
566 PopulateDisplayAttributes(i);
567 }
Saurabh Shah66c941b2016-07-06 17:34:05 -0700568}
569
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700570DisplayError HWDeviceDRM::PopulateDisplayAttributes(uint32_t index) {
Saurabh Shah66c941b2016-07-06 17:34:05 -0700571 drmModeModeInfo mode = {};
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700572 uint32_t mm_width = 0;
573 uint32_t mm_height = 0;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700574 DRMTopology topology = DRMTopology::SINGLE_LM;
575
576 if (default_mode_) {
577 DRMResMgr *res_mgr = nullptr;
578 int ret = DRMResMgr::GetInstance(&res_mgr);
579 if (ret < 0) {
580 DLOGE("Failed to acquire DRMResMgr instance");
581 return kErrorResources;
582 }
583
584 res_mgr->GetMode(&mode);
585 res_mgr->GetDisplayDimInMM(&mm_width, &mm_height);
586 } else {
Saurabh Shah7e16c932017-11-03 17:55:36 -0700587 mode = connector_info_.modes[index].mode;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700588 mm_width = connector_info_.mmWidth;
589 mm_height = connector_info_.mmHeight;
Saurabh Shah7e16c932017-11-03 17:55:36 -0700590 topology = connector_info_.modes[index].topology;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700591 }
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700592
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700593 display_attributes_[index].x_pixels = mode.hdisplay;
594 display_attributes_[index].y_pixels = mode.vdisplay;
595 display_attributes_[index].fps = mode.vrefresh;
596 display_attributes_[index].vsync_period_ns =
597 UINT32(1000000000L / display_attributes_[index].fps);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700598
599 /*
600 Active Front Sync Back
601 Region Porch Porch
602 <-----------------------><----------------><-------------><-------------->
603 <----- [hv]display ----->
604 <------------- [hv]sync_start ------------>
605 <--------------------- [hv]sync_end --------------------->
606 <-------------------------------- [hv]total ----------------------------->
607 */
608
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700609 display_attributes_[index].v_front_porch = mode.vsync_start - mode.vdisplay;
610 display_attributes_[index].v_pulse_width = mode.vsync_end - mode.vsync_start;
611 display_attributes_[index].v_back_porch = mode.vtotal - mode.vsync_end;
612 display_attributes_[index].v_total = mode.vtotal;
613 display_attributes_[index].h_total = mode.htotal;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700614 display_attributes_[index].is_device_split =
Rohit Kulkarni2faa91c2017-06-05 15:43:48 -0700615 (topology == DRMTopology::DUAL_LM || topology == DRMTopology::DUAL_LM_MERGE ||
616 topology == DRMTopology::DUAL_LM_MERGE_DSC || topology == DRMTopology::DUAL_LM_DSC ||
617 topology == DRMTopology::DUAL_LM_DSCMERGE);
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -0700618 display_attributes_[index].clock_khz = mode.clock;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700619
Saurabh Shah88331992017-07-17 14:53:00 -0700620 // If driver doesn't return panel width/height information, default to 320 dpi
621 if (INT(mm_width) <= 0 || INT(mm_height) <= 0) {
622 mm_width = UINT32(((FLOAT(mode.hdisplay) * 25.4f) / 320.0f) + 0.5f);
623 mm_height = UINT32(((FLOAT(mode.vdisplay) * 25.4f) / 320.0f) + 0.5f);
624 DLOGW("Driver doesn't report panel physical width and height - defaulting to 320dpi");
625 }
626
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700627 display_attributes_[index].x_dpi = (FLOAT(mode.hdisplay) * 25.4f) / FLOAT(mm_width);
628 display_attributes_[index].y_dpi = (FLOAT(mode.vdisplay) * 25.4f) / FLOAT(mm_height);
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -0700629 SetTopology(topology, &display_attributes_[index].topology);
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700630
Ramkumar Radhakrishnanf5f24c92017-08-11 18:30:57 -0700631 DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -0700632 " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
633 index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700634 display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
Ramkumar Radhakrishnanf5f24c92017-08-11 18:30:57 -0700635 display_attributes_[index].fps, display_attributes_[index].is_device_split,
636 display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
637 display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -0700638 display_attributes_[index].h_total, display_attributes_[index].clock_khz,
639 display_attributes_[index].topology);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700640
641 return kErrorNone;
642}
643
Saurabh Shah66c941b2016-07-06 17:34:05 -0700644void HWDeviceDRM::PopulateHWPanelInfo() {
645 hw_panel_info_ = {};
646
647 snprintf(hw_panel_info_.panel_name, sizeof(hw_panel_info_.panel_name), "%s",
648 connector_info_.panel_name.c_str());
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700649
Ramkumar Radhakrishnanee0aab22017-10-16 16:11:18 -0700650 uint32_t index = current_mode_index_;
651 hw_panel_info_.split_info.left_split = display_attributes_[index].x_pixels;
652 if (display_attributes_[index].is_device_split) {
653 hw_panel_info_.split_info.left_split = hw_panel_info_.split_info.right_split =
654 display_attributes_[index].x_pixels / 2;
655 }
Saurabh Shah66c941b2016-07-06 17:34:05 -0700656
Saurabh Shah7e16c932017-11-03 17:55:36 -0700657 hw_panel_info_.partial_update = connector_info_.modes[index].num_roi;
658 hw_panel_info_.left_roi_count = UINT32(connector_info_.modes[index].num_roi);
659 hw_panel_info_.right_roi_count = UINT32(connector_info_.modes[index].num_roi);
660 hw_panel_info_.left_align = connector_info_.modes[index].xstart;
661 hw_panel_info_.top_align = connector_info_.modes[index].ystart;
662 hw_panel_info_.width_align = connector_info_.modes[index].walign;
663 hw_panel_info_.height_align = connector_info_.modes[index].halign;
664 hw_panel_info_.min_roi_width = connector_info_.modes[index].wmin;
665 hw_panel_info_.min_roi_height = connector_info_.modes[index].hmin;
666 hw_panel_info_.needs_roi_merge = connector_info_.modes[index].roi_merge;
Mahesh Aia25b22712019-01-04 11:49:46 -0800667 hw_panel_info_.transfer_time_us = connector_info_.modes[index].transfer_time_us;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700668 hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
Sushil Chauhan8f514a52018-02-27 17:35:44 -0800669 hw_panel_info_.qsync_support = connector_info_.qsync_support;
Saurabh Shah7e16c932017-11-03 17:55:36 -0700670 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530671 if (hw_panel_info_.dynamic_fps) {
672 uint32_t min_fps = current_mode.vrefresh;
673 uint32_t max_fps = current_mode.vrefresh;
674 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -0700675 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
676 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay)) {
677 if (min_fps > connector_info_.modes[mode_index].mode.vrefresh) {
678 min_fps = connector_info_.modes[mode_index].mode.vrefresh;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530679 }
Saurabh Shah7e16c932017-11-03 17:55:36 -0700680 if (max_fps < connector_info_.modes[mode_index].mode.vrefresh) {
681 max_fps = connector_info_.modes[mode_index].mode.vrefresh;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530682 }
683 }
684 }
685 hw_panel_info_.min_fps = min_fps;
686 hw_panel_info_.max_fps = max_fps;
687 } else {
688 hw_panel_info_.min_fps = current_mode.vrefresh;
689 hw_panel_info_.max_fps = current_mode.vrefresh;
690 }
691
Saurabh Shah66c941b2016-07-06 17:34:05 -0700692 hw_panel_info_.is_primary_panel = connector_info_.is_primary;
693 hw_panel_info_.is_pluggable = 0;
Sushil Chauhan80e58432017-07-06 11:39:17 -0700694 hw_panel_info_.hdr_enabled = connector_info_.panel_hdr_prop.hdr_enabled;
Sushil Chauhanaa8be832018-08-31 13:38:20 -0700695 // Convert the luminance values to cd/m^2 units.
696 hw_panel_info_.peak_luminance = FLOAT(connector_info_.panel_hdr_prop.peak_brightness) / 10000.0f;
697 hw_panel_info_.blackness_level = FLOAT(connector_info_.panel_hdr_prop.blackness_level) / 10000.0f;
Sushil Chauhan80e58432017-07-06 11:39:17 -0700698 hw_panel_info_.primaries.white_point[0] = connector_info_.panel_hdr_prop.display_primaries[0];
699 hw_panel_info_.primaries.white_point[1] = connector_info_.panel_hdr_prop.display_primaries[1];
700 hw_panel_info_.primaries.red[0] = connector_info_.panel_hdr_prop.display_primaries[2];
701 hw_panel_info_.primaries.red[1] = connector_info_.panel_hdr_prop.display_primaries[3];
702 hw_panel_info_.primaries.green[0] = connector_info_.panel_hdr_prop.display_primaries[4];
703 hw_panel_info_.primaries.green[1] = connector_info_.panel_hdr_prop.display_primaries[5];
704 hw_panel_info_.primaries.blue[0] = connector_info_.panel_hdr_prop.display_primaries[6];
705 hw_panel_info_.primaries.blue[1] = connector_info_.panel_hdr_prop.display_primaries[7];
Pullakavi Srinivas9189e602018-12-19 16:58:07 +0530706 hw_panel_info_.dyn_bitclk_support = connector_info_.dyn_bitclk_support;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700707
Prabhanjan Kandula5bc7f8b2017-05-23 12:24:57 -0700708 // no supprt for 90 rotation only flips or 180 supported
709 hw_panel_info_.panel_orientation.rotation = 0;
710 hw_panel_info_.panel_orientation.flip_horizontal =
711 (connector_info_.panel_orientation == DRMRotation::FLIP_H) ||
712 (connector_info_.panel_orientation == DRMRotation::ROT_180);
713 hw_panel_info_.panel_orientation.flip_vertical =
714 (connector_info_.panel_orientation == DRMRotation::FLIP_V) ||
715 (connector_info_.panel_orientation == DRMRotation::ROT_180);
716
Saurabh Shah66c941b2016-07-06 17:34:05 -0700717 GetHWDisplayPortAndMode();
718 GetHWPanelMaxBrightness();
719
Lei Chen7994a792019-02-18 18:47:49 +0800720 if (current_mode.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) {
721 hw_panel_info_.mode = kModeCommand;
722 }
723 if (current_mode.flags & DRM_MODE_FLAG_VID_MODE_PANEL) {
724 hw_panel_info_.mode = kModeVideo;
725 }
Saurabh Shah66c941b2016-07-06 17:34:05 -0700726 DLOGI("%s, Panel Interface = %s, Panel Mode = %s, Is Primary = %d", device_name_,
727 interface_str_.c_str(), hw_panel_info_.mode == kModeVideo ? "Video" : "Command",
728 hw_panel_info_.is_primary_panel);
Sushil Chauhan8f514a52018-02-27 17:35:44 -0800729 DLOGI("Partial Update = %d, Dynamic FPS = %d, HDR Panel = %d QSync = %d",
730 hw_panel_info_.partial_update, hw_panel_info_.dynamic_fps, hw_panel_info_.hdr_enabled,
731 hw_panel_info_.qsync_support);
Saurabh Shah66c941b2016-07-06 17:34:05 -0700732 DLOGI("Align: left = %d, width = %d, top = %d, height = %d", hw_panel_info_.left_align,
733 hw_panel_info_.width_align, hw_panel_info_.top_align, hw_panel_info_.height_align);
734 DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d", hw_panel_info_.min_roi_width,
735 hw_panel_info_.min_roi_height, hw_panel_info_.needs_roi_merge);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530736 DLOGI("FPS: min = %d, max = %d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
Saurabh Shah66c941b2016-07-06 17:34:05 -0700737 DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
738 hw_panel_info_.split_info.right_split);
Ramkumar Radhakrishnan5c94f052017-07-06 11:59:14 -0700739 DLOGI("Panel Transfer time = %d us", hw_panel_info_.transfer_time_us);
Pullakavi Srinivas9189e602018-12-19 16:58:07 +0530740 DLOGI("Dynamic Bit Clk Support = %d", hw_panel_info_.dyn_bitclk_support);
Saurabh Shah66c941b2016-07-06 17:34:05 -0700741}
742
Varun Arora6ba9eda2019-02-07 17:59:32 -0800743DisplayError HWDeviceDRM::GetDisplayIdentificationData(uint8_t *out_port, uint32_t *out_data_size,
744 uint8_t *out_data) {
745 *out_port = token_.hw_port;
746 std::vector<uint8_t> &edid = connector_info_.edid;
747
748 if (out_data == nullptr) {
749 *out_data_size = (uint32_t)(edid.size());
750 if (*out_data_size == 0) {
751 DLOGE("EDID blob is empty, no data to return");
752 return kErrorDriverData;
753 }
754 } else {
755 *out_data_size = std::min(*out_data_size, (uint32_t)(edid.size()));
756 memcpy(out_data, edid.data(), *out_data_size);
757 }
758
759 return kErrorNone;
760}
761
Saurabh Shah66c941b2016-07-06 17:34:05 -0700762void HWDeviceDRM::GetHWDisplayPortAndMode() {
763 hw_panel_info_.port = kPortDefault;
764 hw_panel_info_.mode =
765 (connector_info_.panel_mode == sde_drm::DRMPanelMode::VIDEO) ? kModeVideo : kModeCommand;
766
767 if (default_mode_) {
768 return;
769 }
770
771 switch (connector_info_.type) {
772 case DRM_MODE_CONNECTOR_DSI:
773 hw_panel_info_.port = kPortDSI;
774 interface_str_ = "DSI";
775 break;
776 case DRM_MODE_CONNECTOR_LVDS:
777 hw_panel_info_.port = kPortLVDS;
778 interface_str_ = "LVDS";
779 break;
780 case DRM_MODE_CONNECTOR_eDP:
781 hw_panel_info_.port = kPortEDP;
782 interface_str_ = "EDP";
783 break;
784 case DRM_MODE_CONNECTOR_TV:
785 case DRM_MODE_CONNECTOR_HDMIA:
786 case DRM_MODE_CONNECTOR_HDMIB:
787 hw_panel_info_.port = kPortDTV;
788 interface_str_ = "HDMI";
789 break;
790 case DRM_MODE_CONNECTOR_VIRTUAL:
791 hw_panel_info_.port = kPortWriteBack;
792 interface_str_ = "Virtual";
793 break;
794 case DRM_MODE_CONNECTOR_DisplayPort:
Gousemoodhin Nadaf47b82be2019-05-09 15:30:11 +0530795 hw_panel_info_.port = kPortDP;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700796 interface_str_ = "DisplayPort";
797 break;
798 }
799
800 return;
801}
802
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700803DisplayError HWDeviceDRM::GetActiveConfig(uint32_t *active_config) {
Pullakavi Srinivas8b33a282018-11-01 12:45:38 +0530804 *active_config = current_mode_index_;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700805 return kErrorNone;
806}
807
808DisplayError HWDeviceDRM::GetNumDisplayAttributes(uint32_t *count) {
Pullakavi Srinivas8b33a282018-11-01 12:45:38 +0530809 *count = UINT32(display_attributes_.size());
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700810 return kErrorNone;
811}
812
813DisplayError HWDeviceDRM::GetDisplayAttributes(uint32_t index,
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700814 HWDisplayAttributes *display_attributes) {
815 if (index >= display_attributes_.size()) {
816 return kErrorParameters;
817 }
Pullakavi Srinivas8b33a282018-11-01 12:45:38 +0530818 *display_attributes = display_attributes_[index];
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700819 return kErrorNone;
820}
821
822DisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) {
823 *panel_info = hw_panel_info_;
824 return kErrorNone;
825}
826
827DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700828 if (index >= display_attributes_.size()) {
Ramkumar Radhakrishnan0dc25f32017-09-06 17:05:18 -0700829 DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size()));
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700830 return kErrorParameters;
831 }
Saurabh Shah7e16c932017-11-03 17:55:36 -0700832
Archit Srivastavaf4488322019-04-24 15:16:10 +0530833 drmModeModeInfo to_set = connector_info_.modes[index].mode;
834 uint64_t current_bit_clk = connector_info_.modes[current_mode_index_].bit_clk_rate;
835 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
836 if ((to_set.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
837 (to_set.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
838 (to_set.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) &&
839 (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate)) {
840 index = mode_index;
841 break;
842 }
843 }
844
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700845 current_mode_index_ = index;
Ramkumar Radhakrishnanee0aab22017-10-16 16:11:18 -0700846 PopulateHWPanelInfo();
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700847 UpdateMixerAttributes();
Saurabh Shah7e16c932017-11-03 17:55:36 -0700848
849 DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
850 " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
851 index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
852 display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
853 display_attributes_[index].fps, display_attributes_[index].is_device_split,
854 display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
855 display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
856 display_attributes_[index].h_total, display_attributes_[index].clock_khz,
857 display_attributes_[index].topology);
858
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700859 return kErrorNone;
860}
861
862DisplayError HWDeviceDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
863 return kErrorNotSupported;
864}
865
srikanth rajagopalan5d320c62017-06-05 21:08:57 -0700866DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) {
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700867 return kErrorNone;
868}
869
Varun Arorabbb062e2018-07-03 22:33:59 -0700870DisplayError HWDeviceDRM::PowerOn(const HWQosData &qos_data, int *release_fence) {
Varun Arorabbb062e2018-07-03 22:33:59 -0700871 SetQOSData(qos_data);
872
Varun Aroraef987292018-04-16 17:16:42 -0700873 int64_t release_fence_t = -1;
Sushil Chauhan93c892c2018-05-11 17:15:37 -0700874 update_mode_ = true;
Ramkumar Radhakrishnan273fc3b2019-03-13 17:47:10 -0700875
876 if (first_cycle_) {
877 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
878 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
879 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
880 }
Sushil Chauhan3396e202017-04-14 18:34:22 -0700881 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
882 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
Ramkumar Radhakrishnan273fc3b2019-03-13 17:47:10 -0700883 if (release_fence) {
884 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t);
885 }
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700886 int ret = NullCommit(true /* synchronous */, true /* retain_planes */);
Sushil Chauhan56755522017-06-01 13:39:50 -0700887 if (ret) {
Sushil Chauhana4d1fc02017-08-07 17:41:39 -0700888 DLOGE("Failed with error: %d", ret);
Sushil Chauhan56755522017-06-01 13:39:50 -0700889 return kErrorHardware;
890 }
Saurabh Shah82b06f42017-09-06 16:43:49 -0700891
Ramkumar Radhakrishnan273fc3b2019-03-13 17:47:10 -0700892 if (release_fence) {
893 *release_fence = static_cast<int>(release_fence_t);
894 DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence);
895 }
Rajavenu Kyatham9d509582019-02-13 15:29:55 +0530896 pending_doze_ = false;
897
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700898 return kErrorNone;
899}
900
Varun Arora78580b82018-09-10 13:59:57 -0700901DisplayError HWDeviceDRM::PowerOff(bool teardown) {
Saurabh Shaha917aa72017-09-15 13:27:24 -0700902 DTRACE_SCOPED();
Sushil Chauhan23fc6e12017-06-22 11:15:51 -0700903 if (!drm_atomic_intf_) {
904 DLOGE("DRM Atomic Interface is null!");
905 return kErrorUndefined;
906 }
907
Rajavenu Kyatham8d259762019-02-11 19:23:48 +0530908 if (first_cycle_) {
909 return kErrorNone;
910 }
911
Ramkumar Radhakrishnanf7f52162019-06-06 19:40:04 -0700912 ResetROI();
Ramkumar Radhakrishnan98479932018-03-28 15:33:08 -0700913 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
914 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700915 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
916 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700917 int ret = NullCommit(true /* synchronous */, false /* retain_planes */);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700918 if (ret) {
Sushil Chauhana4d1fc02017-08-07 17:41:39 -0700919 DLOGE("Failed with error: %d", ret);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700920 return kErrorHardware;
921 }
Rajavenu Kyatham9d509582019-02-13 15:29:55 +0530922 pending_doze_ = false;
Saurabh Shah82b06f42017-09-06 16:43:49 -0700923
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700924 return kErrorNone;
925}
926
Varun Arorabbb062e2018-07-03 22:33:59 -0700927DisplayError HWDeviceDRM::Doze(const HWQosData &qos_data, int *release_fence) {
Saurabh Shaha917aa72017-09-15 13:27:24 -0700928 DTRACE_SCOPED();
Varun Aroraef987292018-04-16 17:16:42 -0700929
Rajavenu Kyatham9d509582019-02-13 15:29:55 +0530930 if (!first_cycle_) {
931 pending_doze_ = true;
932 return kErrorNone;
933 }
934
Varun Arorabbb062e2018-07-03 22:33:59 -0700935 SetQOSData(qos_data);
936
Varun Aroraef987292018-04-16 17:16:42 -0700937 int64_t release_fence_t = -1;
Ramakant Singhda5072f2018-07-09 14:20:01 -0700938
Rajavenu Kyatham9d509582019-02-13 15:29:55 +0530939 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
940 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
941 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
942
Sushil Chauhana4d1fc02017-08-07 17:41:39 -0700943 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700944 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
Ramkumar Radhakrishnan273fc3b2019-03-13 17:47:10 -0700945 if (release_fence) {
946 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t);
947 }
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700948 int ret = NullCommit(true /* synchronous */, true /* retain_planes */);
Sushil Chauhana4d1fc02017-08-07 17:41:39 -0700949 if (ret) {
950 DLOGE("Failed with error: %d", ret);
951 return kErrorHardware;
952 }
953
Ramkumar Radhakrishnan273fc3b2019-03-13 17:47:10 -0700954 if (release_fence) {
955 *release_fence = static_cast<int>(release_fence_t);
956 DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence);
957 }
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700958 return kErrorNone;
959}
960
Varun Arorabbb062e2018-07-03 22:33:59 -0700961DisplayError HWDeviceDRM::DozeSuspend(const HWQosData &qos_data, int *release_fence) {
Saurabh Shaha917aa72017-09-15 13:27:24 -0700962 DTRACE_SCOPED();
Varun Aroraef987292018-04-16 17:16:42 -0700963
Varun Arorabbb062e2018-07-03 22:33:59 -0700964 SetQOSData(qos_data);
965
Varun Aroraef987292018-04-16 17:16:42 -0700966 int64_t release_fence_t = -1;
Ramakant Singhda5072f2018-07-09 14:20:01 -0700967
968 if (first_cycle_) {
969 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
970 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
971 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
972 }
Saurabh Shaha917aa72017-09-15 13:27:24 -0700973 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700974 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
975 DRMPowerMode::DOZE_SUSPEND);
Ramkumar Radhakrishnan273fc3b2019-03-13 17:47:10 -0700976 if (release_fence) {
977 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t);
978 }
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700979 int ret = NullCommit(true /* synchronous */, true /* retain_planes */);
Saurabh Shaha917aa72017-09-15 13:27:24 -0700980 if (ret) {
981 DLOGE("Failed with error: %d", ret);
982 return kErrorHardware;
983 }
984
Ramkumar Radhakrishnan273fc3b2019-03-13 17:47:10 -0700985 if (release_fence) {
986 *release_fence = static_cast<int>(release_fence_t);
987 DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence);
988 }
Rajavenu Kyatham9d509582019-02-13 15:29:55 +0530989 pending_doze_ = false;
990
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700991 return kErrorNone;
992}
993
Varun Arorabbb062e2018-07-03 22:33:59 -0700994void HWDeviceDRM::SetQOSData(const HWQosData &qos_data) {
995 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, qos_data.clock_hz);
996 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, qos_data.core_ab_bps);
997 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, qos_data.core_ib_bps);
998 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_AB, token_.crtc_id, qos_data.llcc_ab_bps);
999 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_IB, token_.crtc_id, qos_data.llcc_ib_bps);
1000 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_AB, token_.crtc_id, qos_data.dram_ab_bps);
1001 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_IB, token_.crtc_id, qos_data.dram_ib_bps);
1002 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_PREFILL_BW, token_.crtc_id,
1003 qos_data.rot_prefill_bw_bps);
1004 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_CLK, token_.crtc_id, qos_data.rot_clock_hz);
1005}
1006
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001007DisplayError HWDeviceDRM::Standby() {
1008 return kErrorNone;
1009}
1010
Saurabh Shah66c941b2016-07-06 17:34:05 -07001011void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) {
1012 if (default_mode_) {
1013 return;
1014 }
1015
Gurpreet Singh Dhamia4276882019-04-12 10:30:58 -07001016 DTRACE_SCOPED();
Saurabh Shah66c941b2016-07-06 17:34:05 -07001017 HWLayersInfo &hw_layer_info = hw_layers->info;
1018 uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
Ramkumar Radhakrishnan3c4de112017-05-24 22:38:30 -07001019 HWQosData &qos_data = hw_layers->qos_data;
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001020 DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001021 uint32_t index = current_mode_index_;
Saurabh Shah7e16c932017-11-03 17:55:36 -07001022 drmModeModeInfo current_mode = connector_info_.modes[index].mode;
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301023 uint64_t current_bit_clk = connector_info_.modes[index].bit_clk_rate;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001024
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001025 solid_fills_.clear();
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001026 bool resource_update = hw_layers->updates_mask.test(kUpdateResources);
1027 bool update_config = resource_update || hw_layer_info.stack->flags.geometry_changed;
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001028
Ramkumar Radhakrishnanf7f52162019-06-06 19:40:04 -07001029 if (hw_panel_info_.partial_update && update_config) {
1030 if (IsFullFrameUpdate(hw_layer_info)) {
1031 ResetROI();
1032 } else {
1033 const int kNumMaxROIs = 4;
1034 DRMRect crtc_rects[kNumMaxROIs] = {{0, 0, mixer_attributes_.width, mixer_attributes_.height}};
1035 DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_[index].x_pixels,
1036 display_attributes_[index].y_pixels}};
Saurabh Shahe9f55d72017-03-03 15:14:13 -08001037
Ramkumar Radhakrishnanf7f52162019-06-06 19:40:04 -07001038 for (uint32_t i = 0; i < hw_layer_info.left_frame_roi.size(); i++) {
1039 auto &roi = hw_layer_info.left_frame_roi.at(i);
1040 // TODO(user): In multi PU, stitch ROIs vertically adjacent and upate plane destination
1041 crtc_rects[i].left = UINT32(roi.left);
1042 crtc_rects[i].right = UINT32(roi.right);
1043 crtc_rects[i].top = UINT32(roi.top);
1044 crtc_rects[i].bottom = UINT32(roi.bottom);
1045 conn_rects[i].left = UINT32(roi.left);
1046 conn_rects[i].right = UINT32(roi.right);
1047 conn_rects[i].top = UINT32(roi.top);
1048 conn_rects[i].bottom = UINT32(roi.bottom);
1049 }
1050
1051 uint32_t num_rects = std::max(1u, static_cast<uint32_t>(hw_layer_info.left_frame_roi.size()));
1052 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id, num_rects, crtc_rects);
1053 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id, num_rects, conn_rects);
Saurabh Shahe9f55d72017-03-03 15:14:13 -08001054 }
Saurabh Shahe9f55d72017-03-03 15:14:13 -08001055 }
1056
Saurabh Shah66c941b2016-07-06 17:34:05 -07001057 for (uint32_t i = 0; i < hw_layer_count; i++) {
1058 Layer &layer = hw_layer_info.hw_layers.at(i);
Saurabh Shaha228f122017-01-23 15:55:25 -08001059 LayerBuffer *input_buffer = &layer.input_buffer;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001060 HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
1061 HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
Alex Sarraf4ec5f612018-10-29 14:02:45 -07001062 HWLayerConfig &layer_config = hw_layers->config[i];
1063 HWRotatorSession *hw_rotator_session = &layer_config.hw_rotator_session;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001064
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001065 if (hw_layers->config[i].use_solidfill_stage) {
Gopikrishnaiah Anandancc123062017-07-31 17:21:03 -07001066 hw_layers->config[i].hw_solidfill_stage.solid_fill_info = layer.solid_fill_info;
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001067 AddSolidfillStage(hw_layers->config[i].hw_solidfill_stage, layer.plane_alpha);
1068 continue;
1069 }
1070
Saurabh Shah66c941b2016-07-06 17:34:05 -07001071 for (uint32_t count = 0; count < 2; count++) {
1072 HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
Saurabh Shaha228f122017-01-23 15:55:25 -08001073 HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
1074
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001075 if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) {
Saurabh Shaha228f122017-01-23 15:55:25 -08001076 input_buffer = &hw_rotator_session->output_buffer;
Saurabh Shaha228f122017-01-23 15:55:25 -08001077 }
1078
Sushil Chauhanabc5b272018-06-20 16:18:13 -07001079 uint32_t fb_id = registry_.GetFbId(&layer, input_buffer->handle_id);
1080
Saurabh Shahf84c4122017-04-07 10:34:40 -07001081 if (pipe_info->valid && fb_id) {
Saurabh Shah66c941b2016-07-06 17:34:05 -07001082 uint32_t pipe_id = pipe_info->pipe_id;
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -07001083
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001084 if (update_config) {
1085 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha);
Alex Sarraf4ec5f612018-10-29 14:02:45 -07001086
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001087 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ZORDER, pipe_id, pipe_info->z_order);
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001088
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001089 DRMBlendType blending = {};
1090 SetBlending(layer.blending, &blending);
1091 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_BLEND_TYPE, pipe_id, blending);
1092
1093 DRMRect src = {};
1094 SetRect(pipe_info->src_roi, &src);
1095 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_RECT, pipe_id, src);
1096
1097 DRMRect dst = {};
1098 SetRect(pipe_info->dst_roi, &dst);
1099 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst);
1100
1101 DRMRect excl = {};
1102 SetRect(pipe_info->excl_rect, &excl);
1103 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_EXCL_RECT, pipe_id, excl);
1104
1105 uint32_t rot_bit_mask = 0;
1106 SetRotation(layer.transform, layer_config, &rot_bit_mask);
1107 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask);
1108
1109 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_H_DECIMATION, pipe_id,
1110 pipe_info->horizontal_decimation);
1111 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_V_DECIMATION, pipe_id,
1112 pipe_info->vertical_decimation);
1113
1114 DRMSecureMode fb_secure_mode;
1115 DRMSecurityLevel security_level;
1116 SetSecureConfig(layer.input_buffer, &fb_secure_mode, &security_level);
1117 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_SECURE_MODE, pipe_id, fb_secure_mode);
1118 if (security_level > crtc_security_level) {
1119 crtc_security_level = security_level;
1120 }
1121
1122 uint32_t config = 0;
1123 SetSrcConfig(layer.input_buffer, hw_rotator_session->mode, &config);
1124 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);;
1125
1126 if (hw_scale_) {
1127 SDEScaler scaler_output = {};
1128 hw_scale_->SetScaler(pipe_info->scale_data, &scaler_output);
1129 // TODO(user): Remove qseed3 and add version check, then send appropriate scaler object
1130 if (hw_resource_.has_qseed3) {
1131 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id,
1132 reinterpret_cast<uint64_t>(&scaler_output.scaler_v2));
1133 }
1134 }
1135
1136 DRMCscType csc_type = DRMCscType::kCscTypeMax;
1137 SelectCscType(layer.input_buffer, &csc_type);
1138 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CSC_CONFIG, pipe_id, &csc_type);
1139
1140 DRMMultiRectMode multirect_mode;
1141 SetMultiRectMode(pipe_info->flags, &multirect_mode);
1142 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_MULTIRECT_MODE, pipe_id, multirect_mode);
1143
1144 SetSsppTonemapFeatures(pipe_info);
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001145 }
1146
Saurabh Shahf84c4122017-04-07 10:34:40 -07001147 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001148 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id);
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001149
Saurabh Shaha228f122017-01-23 15:55:25 -08001150 if (!validate && input_buffer->acquire_fence_fd >= 0) {
Saurabh Shah66c941b2016-07-06 17:34:05 -07001151 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id,
Saurabh Shaha228f122017-01-23 15:55:25 -08001152 input_buffer->acquire_fence_fd);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001153 }
1154 }
1155 }
Saurabh Shah66c941b2016-07-06 17:34:05 -07001156 }
Prabhanjan Kandulaf890c252017-07-09 18:22:02 -07001157
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001158 if (update_config) {
1159 SetSolidfillStages();
1160 SetQOSData(qos_data);
1161 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level);
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001162
1163 sde_drm::DRMQsyncMode mode = hw_layers->hw_avr_info.enable ? sde_drm::DRMQsyncMode::CONTINUOUS :
1164 sde_drm::DRMQsyncMode::NONE;
1165 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_QSYNC_MODE, token_.conn_id, mode);
1166 }
Prabhanjan Kandulaf890c252017-07-09 18:22:02 -07001167
Ping Li04ce92a2019-03-14 12:09:12 -07001168 drm_atomic_intf_->Perform(DRMOps::DPPS_COMMIT_FEATURE, 0 /* argument is not used */);
Lei Chen7994a792019-02-18 18:47:49 +08001169
1170 if (reset_output_fence_offset_ && !validate) {
1171 // Change back the fence_offset
1172 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET, token_.crtc_id, 0);
1173 reset_output_fence_offset_ = false;
1174 }
1175
1176 // Set panel mode
1177 if (panel_mode_changed_) {
1178 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
1179 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1180 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1181 (current_mode.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) &&
1182 (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) &&
1183 (panel_mode_changed_ & connector_info_.modes[mode_index].mode.flags)) {
1184 current_mode = connector_info_.modes[mode_index].mode;
1185 if ((current_mode.flags & DRM_MODE_FLAG_VID_MODE_PANEL) && !validate) {
1186 // Switch to video mode, corresponding change the fence_offset
1187 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET, token_.crtc_id, 1);
1188 }
1189 break;
1190 }
1191 }
1192 }
1193
Varun Aroraef987292018-04-16 17:16:42 -07001194 if (!validate) {
1195 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_);
1196 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_GET_RETIRE_FENCE, token_.conn_id, &retire_fence_);
1197 }
1198
Ramkumar Radhakrishnanb7910442017-12-11 13:32:47 -08001199 DLOGI_IF(kTagDriverConfig, "%s::%s System Clock=%d Hz, Core: AB=%llu Bps, IB=%llu Bps, " \
1200 "LLCC: AB=%llu Bps, IB=%llu Bps, DRAM AB=%llu Bps, IB=%llu Bps, "\
1201 "Rot: Bw=%llu Bps, Clock=%d Hz", validate ? "Validate" : "Commit", device_name_,
Prabhanjan Kandulaf890c252017-07-09 18:22:02 -07001202 qos_data.clock_hz, qos_data.core_ab_bps, qos_data.core_ib_bps, qos_data.llcc_ab_bps,
1203 qos_data.llcc_ib_bps, qos_data.dram_ab_bps, qos_data.dram_ib_bps,
Ramkumar Radhakrishnanb7910442017-12-11 13:32:47 -08001204 qos_data.rot_prefill_bw_bps, qos_data.rot_clock_hz);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301205
1206 // Set refresh rate
1207 if (vrefresh_) {
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301208 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -07001209 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1210 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301211 (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) &&
Lei Chen7994a792019-02-18 18:47:49 +08001212 (current_mode.flags == connector_info_.modes[mode_index].mode.flags) &&
Saurabh Shah7e16c932017-11-03 17:55:36 -07001213 (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
1214 current_mode = connector_info_.modes[mode_index].mode;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301215 break;
1216 }
1217 }
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301218 }
Saurabh Shah7e16c932017-11-03 17:55:36 -07001219
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301220 if (bit_clk_rate_) {
1221 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
1222 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1223 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1224 (current_mode.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) &&
Lei Chen7994a792019-02-18 18:47:49 +08001225 (current_mode.flags == connector_info_.modes[mode_index].mode.flags) &&
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301226 (bit_clk_rate_ == connector_info_.modes[mode_index].bit_clk_rate)) {
1227 current_mode = connector_info_.modes[mode_index].mode;
1228 break;
1229 }
1230 }
1231 }
1232
Saurabh Shah7e16c932017-11-03 17:55:36 -07001233 if (first_cycle_) {
Mathew Joseph Karimpanalb7f20c62018-10-09 12:17:20 +05301234 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_TOPOLOGY_CONTROL, token_.conn_id,
1235 topology_control_);
Rajavenu Kyatham9d509582019-02-13 15:29:55 +05301236 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
1237 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
Padmanabhan Komanduru8b1f1922019-02-25 15:50:34 +05301238 DRMPowerMode power_mode = pending_doze_ ? DRMPowerMode::DOZE : DRMPowerMode::ON;
1239 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, power_mode);
Rajavenu Kyatham9d509582019-02-13 15:29:55 +05301240 } else if (pending_doze_ && !validate) {
1241 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
1242 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
1243 pending_doze_ = false;
Saurabh Shah7e16c932017-11-03 17:55:36 -07001244 }
1245
Sushil Chauhan93c892c2018-05-11 17:15:37 -07001246 // Set CRTC mode, only if display config changes
Lei Chen7994a792019-02-18 18:47:49 +08001247 if (vrefresh_ || update_mode_ || panel_mode_changed_) {
Sushil Chauhan93c892c2018-05-11 17:15:37 -07001248 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
1249 }
1250
Anjaneya Prasad Musunurie8c67f22017-07-01 16:16:13 +05301251 if (!validate && (hw_layer_info.set_idle_time_ms >= 0)) {
1252 DLOGI_IF(kTagDriverConfig, "Setting idle timeout to = %d ms",
1253 hw_layer_info.set_idle_time_ms);
1254 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_IDLE_TIMEOUT, token_.crtc_id,
1255 hw_layer_info.set_idle_time_ms);
1256 }
Saurabh Shahf3635952017-10-16 17:08:18 -07001257
1258 if (hw_panel_info_.mode == kModeCommand) {
1259 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_AUTOREFRESH, token_.conn_id, autorefresh_);
1260 }
Saurabh Shah66c941b2016-07-06 17:34:05 -07001261}
1262
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001263void HWDeviceDRM::AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha) {
1264 sde_drm::DRMSolidfillStage solidfill;
1265 solidfill.bounding_rect.left = UINT32(sf.roi.left);
1266 solidfill.bounding_rect.top = UINT32(sf.roi.top);
1267 solidfill.bounding_rect.right = UINT32(sf.roi.right);
1268 solidfill.bounding_rect.bottom = UINT32(sf.roi.bottom);
1269 solidfill.is_exclusion_rect = sf.is_exclusion_rect;
1270 solidfill.plane_alpha = plane_alpha;
1271 solidfill.z_order = sf.z_order;
Gopikrishnaiah Anandancc123062017-07-31 17:21:03 -07001272 if (!sf.solid_fill_info.bit_depth) {
1273 solidfill.color_bit_depth = 8;
1274 solidfill.alpha = (0xff000000 & sf.color) >> 24;
1275 solidfill.red = (0xff0000 & sf.color) >> 16;
1276 solidfill.green = (0xff00 & sf.color) >> 8;
1277 solidfill.blue = 0xff & sf.color;
1278 } else {
1279 solidfill.color_bit_depth = sf.solid_fill_info.bit_depth;
1280 solidfill.alpha = sf.solid_fill_info.alpha;
1281 solidfill.red = sf.solid_fill_info.red;
1282 solidfill.green = sf.solid_fill_info.green;
1283 solidfill.blue = sf.solid_fill_info.blue;
1284 }
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001285 solid_fills_.push_back(solidfill);
1286 DLOGI_IF(kTagDriverConfig, "Add a solidfill stage at z_order:%d argb_color:%x plane_alpha:%x",
1287 solidfill.z_order, solidfill.color, solidfill.plane_alpha);
1288}
1289
1290void HWDeviceDRM::SetSolidfillStages() {
1291 if (hw_resource_.num_solidfill_stages) {
1292 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SOLIDFILL_STAGES, token_.crtc_id,
1293 reinterpret_cast<uint64_t> (&solid_fills_));
1294 }
1295}
1296
Tharaga Balachandran2fd24262018-11-09 16:03:41 -05001297void HWDeviceDRM::ClearSolidfillStages() {
1298 solid_fills_.clear();
1299 SetSolidfillStages();
1300}
1301
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001302DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
1303 DTRACE_SCOPED();
Saurabh Shahf84c4122017-04-07 10:34:40 -07001304
Saurabh Shah4d4f4002017-12-26 12:42:59 -08001305 DisplayError err = kErrorNone;
1306 registry_.Register(hw_layers);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001307 SetupAtomic(hw_layers, true /* validate */);
1308
1309 int ret = drm_atomic_intf_->Validate();
1310 if (ret) {
Ramkumar Radhakrishnan7e971e02017-08-17 14:19:15 +05301311 DLOGE("failed with error %d for %s", ret, device_name_);
Ashish Kumar43c8d802019-02-05 20:14:28 +05301312 DumpHWLayers(hw_layers);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301313 vrefresh_ = 0;
Lei Chen7994a792019-02-18 18:47:49 +08001314 panel_mode_changed_ = 0;
Saurabh Shah4d4f4002017-12-26 12:42:59 -08001315 err = kErrorHardware;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001316 }
1317
Saurabh Shah4d4f4002017-12-26 12:42:59 -08001318 return err;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001319}
1320
1321DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {
1322 DTRACE_SCOPED();
Saurabh Shahf84c4122017-04-07 10:34:40 -07001323
1324 DisplayError err = kErrorNone;
Saurabh Shah4d4f4002017-12-26 12:42:59 -08001325 registry_.Register(hw_layers);
Saurabh Shahf84c4122017-04-07 10:34:40 -07001326
Saurabh Shah66c941b2016-07-06 17:34:05 -07001327 if (default_mode_) {
Saurabh Shahf84c4122017-04-07 10:34:40 -07001328 err = DefaultCommit(hw_layers);
1329 } else {
1330 err = AtomicCommit(hw_layers);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001331 }
1332
Saurabh Shahf84c4122017-04-07 10:34:40 -07001333 return err;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001334}
1335
1336DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) {
1337 DTRACE_SCOPED();
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001338
1339 HWLayersInfo &hw_layer_info = hw_layers->info;
1340 LayerStack *stack = hw_layer_info.stack;
1341
1342 stack->retire_fence_fd = -1;
1343 for (Layer &layer : hw_layer_info.hw_layers) {
1344 layer.input_buffer.release_fence_fd = -1;
1345 }
1346
1347 DRMMaster *master = nullptr;
1348 int ret = DRMMaster::GetInstance(&master);
1349 if (ret < 0) {
1350 DLOGE("Failed to acquire DRMMaster instance");
1351 return kErrorResources;
1352 }
1353
1354 DRMResMgr *res_mgr = nullptr;
1355 ret = DRMResMgr::GetInstance(&res_mgr);
1356 if (ret < 0) {
1357 DLOGE("Failed to acquire DRMResMgr instance");
1358 return kErrorResources;
1359 }
1360
1361 int dev_fd = -1;
1362 master->GetHandle(&dev_fd);
1363
1364 uint32_t connector_id = 0;
1365 res_mgr->GetConnectorId(&connector_id);
1366
1367 uint32_t crtc_id = 0;
1368 res_mgr->GetCrtcId(&crtc_id);
1369
1370 drmModeModeInfo mode;
1371 res_mgr->GetMode(&mode);
1372
Sushil Chauhanabc5b272018-06-20 16:18:13 -07001373 uint64_t handle_id = hw_layer_info.hw_layers.at(0).input_buffer.handle_id;
1374 uint32_t fb_id = registry_.GetFbId(&hw_layer_info.hw_layers.at(0), handle_id);
Saurabh Shahf84c4122017-04-07 10:34:40 -07001375 ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id,
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001376 1 /* num_connectors */, &mode);
1377 if (ret < 0) {
1378 DLOGE("drmModeSetCrtc failed dev fd %d, fb_id %d, crtc id %d, connector id %d, %s", dev_fd,
Saurabh Shahf84c4122017-04-07 10:34:40 -07001379 fb_id, crtc_id, connector_id, strerror(errno));
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001380 return kErrorHardware;
1381 }
1382
1383 return kErrorNone;
1384}
1385
Saurabh Shah66c941b2016-07-06 17:34:05 -07001386DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) {
1387 DTRACE_SCOPED();
1388 SetupAtomic(hw_layers, false /* validate */);
1389
Ramkumar Radhakrishnanf985d482018-07-23 18:10:41 -07001390 int ret = drm_atomic_intf_->Commit(synchronous_commit_, false /* retain_planes*/);
Varun Aroraf182bfa2018-08-14 10:49:08 -07001391 int release_fence = INT(release_fence_);
1392 int retire_fence = INT(retire_fence_);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001393 if (ret) {
Mahesh Aia1d2ceda2017-03-24 11:07:31 -07001394 DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
Ashish Kumar43c8d802019-02-05 20:14:28 +05301395 DumpHWLayers(hw_layers);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301396 vrefresh_ = 0;
Lei Chen7994a792019-02-18 18:47:49 +08001397 panel_mode_changed_ = 0;
Varun Aroraf182bfa2018-08-14 10:49:08 -07001398 CloseFd(&release_fence);
1399 CloseFd(&retire_fence);
1400 release_fence_ = -1;
1401 retire_fence_ = -1;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001402 return kErrorHardware;
1403 }
1404
Varun Arora006e3a12018-04-20 17:09:35 -07001405 DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", release_fence);
1406 DLOGD_IF(kTagDriverConfig, "RETIRE fence created: fd:%d", retire_fence);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001407
1408 HWLayersInfo &hw_layer_info = hw_layers->info;
1409 LayerStack *stack = hw_layer_info.stack;
1410 stack->retire_fence_fd = retire_fence;
1411
Saurabh Shaha228f122017-01-23 15:55:25 -08001412 for (uint32_t i = 0; i < hw_layer_info.hw_layers.size(); i++) {
1413 Layer &layer = hw_layer_info.hw_layers.at(i);
1414 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001415 if (hw_rotator_session->mode == kRotatorOffline) {
Saurabh Shaha228f122017-01-23 15:55:25 -08001416 hw_rotator_session->output_buffer.release_fence_fd = Sys::dup_(release_fence);
1417 } else {
1418 layer.input_buffer.release_fence_fd = Sys::dup_(release_fence);
1419 }
Saurabh Shah66c941b2016-07-06 17:34:05 -07001420 }
1421
1422 hw_layer_info.sync_handle = release_fence;
1423
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301424 if (vrefresh_) {
1425 // Update current mode index if refresh rate is changed
Saurabh Shah7e16c932017-11-03 17:55:36 -07001426 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301427 uint64_t current_bit_clk = connector_info_.modes[current_mode_index_].bit_clk_rate;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301428 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -07001429 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1430 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301431 (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) &&
Saurabh Shah7e16c932017-11-03 17:55:36 -07001432 (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301433 current_mode_index_ = mode_index;
1434 break;
1435 }
1436 }
1437 vrefresh_ = 0;
1438 }
1439
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301440 if (bit_clk_rate_) {
1441 // Update current mode index if bit clk rate is changed.
1442 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
1443 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
1444 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1445 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1446 (current_mode.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) &&
1447 (bit_clk_rate_ == connector_info_.modes[mode_index].bit_clk_rate)) {
1448 current_mode_index_ = mode_index;
1449 break;
1450 }
1451 }
1452 bit_clk_rate_ = 0;
1453 }
1454
Lei Chen7994a792019-02-18 18:47:49 +08001455 if (panel_mode_changed_) {
1456 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
1457 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
1458 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1459 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1460 (current_mode.vrefresh & connector_info_.modes[mode_index].mode.vrefresh) &&
1461 (panel_mode_changed_ & connector_info_.modes[mode_index].mode.flags)) {
1462 if (connector_info_.modes[mode_index].mode.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) {
1463 hw_panel_info_.mode = kModeCommand;
1464 DLOGV_IF(kTagDriverConfig, "switch to command mode done, mode_index = %d\n",
1465 mode_index);
1466 }
1467 if (connector_info_.modes[mode_index].mode.flags & DRM_MODE_FLAG_VID_MODE_PANEL) {
1468 hw_panel_info_.mode = kModeVideo;
1469 reset_output_fence_offset_ = true;
1470 DLOGV_IF(kTagDriverConfig, "switch to video mode done, mode_index = %d\n", mode_index);
1471 }
1472 current_mode_index_ = mode_index;
1473 break;
1474 }
1475 }
1476 panel_mode_changed_ = 0;
1477 synchronous_commit_ = false;
1478 }
1479
Saurabh Shah7e16c932017-11-03 17:55:36 -07001480 first_cycle_ = false;
Sushil Chauhan93c892c2018-05-11 17:15:37 -07001481 update_mode_ = false;
Sushil Chauhanec4eb572019-02-07 13:29:42 -08001482 hw_layers->updates_mask = 0;
Padmanabhan Komanduru8b1f1922019-02-25 15:50:34 +05301483 pending_doze_ = false;
Ramkumar Radhakrishnanee0aab22017-10-16 16:11:18 -07001484
Saurabh Shah66c941b2016-07-06 17:34:05 -07001485 return kErrorNone;
1486}
1487
Pullakavi Srinivas0a1dba62018-07-02 15:49:11 +05301488DisplayError HWDeviceDRM::Flush(HWLayers *hw_layers) {
Tharaga Balachandran2fd24262018-11-09 16:03:41 -05001489 ClearSolidfillStages();
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -07001490 int ret = NullCommit(secure_display_active_ /* synchronous */, false /* retain_planes*/);
Saurabh Shahb5953152017-04-12 14:02:50 -07001491 if (ret) {
1492 DLOGE("failed with error %d", ret);
1493 return kErrorHardware;
1494 }
1495
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001496 return kErrorNone;
1497}
1498
Saurabh Shah66c941b2016-07-06 17:34:05 -07001499void HWDeviceDRM::SetBlending(const LayerBlending &source, DRMBlendType *target) {
1500 switch (source) {
1501 case kBlendingPremultiplied:
1502 *target = DRMBlendType::PREMULTIPLIED;
1503 break;
1504 case kBlendingOpaque:
1505 *target = DRMBlendType::OPAQUE;
1506 break;
1507 case kBlendingCoverage:
1508 *target = DRMBlendType::COVERAGE;
1509 break;
1510 default:
1511 *target = DRMBlendType::UNDEFINED;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001512 }
1513}
1514
Ramkumar Radhakrishnan0751f872017-11-09 15:56:10 -08001515void HWDeviceDRM::SetSrcConfig(const LayerBuffer &input_buffer, const HWRotatorMode &mode,
1516 uint32_t *config) {
1517 // In offline rotation case, rotator will handle deinterlacing.
1518 if (mode != kRotatorOffline) {
1519 if (input_buffer.flags.interlace) {
1520 *config |= (0x01 << UINT32(DRMSrcConfig::DEINTERLACE));
1521 }
Prabhanjan Kandula585aa652017-01-26 18:39:11 -08001522 }
1523}
1524
Ping Li8d6dd622017-07-03 12:05:15 -07001525void HWDeviceDRM::SelectCscType(const LayerBuffer &input_buffer, DRMCscType *type) {
1526 if (type == NULL) {
1527 return;
1528 }
1529
1530 *type = DRMCscType::kCscTypeMax;
1531 if (input_buffer.format < kFormatYCbCr420Planar) {
1532 return;
1533 }
1534
1535 switch (input_buffer.color_metadata.colorPrimaries) {
1536 case ColorPrimaries_BT601_6_525:
1537 case ColorPrimaries_BT601_6_625:
1538 *type = ((input_buffer.color_metadata.range == Range_Full) ?
1539 DRMCscType::kCscYuv2Rgb601FR : DRMCscType::kCscYuv2Rgb601L);
1540 break;
1541 case ColorPrimaries_BT709_5:
1542 *type = DRMCscType::kCscYuv2Rgb709L;
1543 break;
1544 case ColorPrimaries_BT2020:
1545 *type = ((input_buffer.color_metadata.range == Range_Full) ?
1546 DRMCscType::kCscYuv2Rgb2020FR : DRMCscType::kCscYuv2Rgb2020L);
1547 break;
1548 default:
1549 break;
1550 }
1551}
1552
Saurabh Shah66c941b2016-07-06 17:34:05 -07001553void HWDeviceDRM::SetRect(const LayerRect &source, DRMRect *target) {
1554 target->left = UINT32(source.left);
1555 target->top = UINT32(source.top);
1556 target->right = UINT32(source.right);
1557 target->bottom = UINT32(source.bottom);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001558}
1559
Alex Sarraf4ec5f612018-10-29 14:02:45 -07001560void HWDeviceDRM::SetRotation(LayerTransform transform, const HWLayerConfig &layer_config,
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001561 uint32_t* rot_bit_mask) {
Alex Sarraf4ec5f612018-10-29 14:02:45 -07001562 HWRotatorMode mode = layer_config.hw_rotator_session.mode;
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001563 // In offline rotation case, rotator will handle flips set via offline rotator interface.
1564 if (mode == kRotatorOffline) {
1565 *rot_bit_mask = 0;
1566 return;
1567 }
1568
1569 // In no rotation case or inline rotation case, plane will handle flips
1570 // In DRM framework rotation is applied in counter-clockwise direction.
Alex Sarraf4ec5f612018-10-29 14:02:45 -07001571 if (layer_config.use_inline_rot && transform.rotation == 90) {
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001572 // a) rotate 90 clockwise = rotate 270 counter-clockwise in DRM
1573 // rotate 270 is translated as hflip + vflip + rotate90
1574 // b) rotate 270 clockwise = rotate 90 counter-clockwise in DRM
1575 // c) hflip + rotate 90 clockwise = vflip + rotate 90 counter-clockwise in DRM
1576 // d) vflip + rotate 90 clockwise = hflip + rotate 90 counter-clockwise in DRM
1577 *rot_bit_mask = UINT32(DRMRotation::ROT_90);
1578 transform.flip_horizontal = !transform.flip_horizontal;
1579 transform.flip_vertical = !transform.flip_vertical;
1580 }
1581
1582 if (transform.flip_horizontal) {
1583 *rot_bit_mask |= UINT32(DRMRotation::FLIP_H);
1584 }
1585
1586 if (transform.flip_vertical) {
1587 *rot_bit_mask |= UINT32(DRMRotation::FLIP_V);
1588 }
1589}
1590
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001591bool HWDeviceDRM::EnableHotPlugDetection(int enable) {
1592 return true;
1593}
1594
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001595DisplayError HWDeviceDRM::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
1596 DTRACE_SCOPED();
1597 return kErrorNone;
1598}
1599
1600DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
Ping Li281f48d2017-01-16 12:45:40 -08001601 struct DRMPPFeatureInfo info = {};
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301602
1603 if (!hw_color_mgr_)
1604 return kErrorNotSupported;
1605
Ping Li281f48d2017-01-16 12:45:40 -08001606 for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301607 std::vector<DRMPPFeatureID> drm_id = {};
Ping Li281f48d2017-01-16 12:45:40 -08001608 memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301609 hw_color_mgr_->ToDrmFeatureId(kDSPP, i, &drm_id);
1610 if (drm_id.empty())
Ping Li281f48d2017-01-16 12:45:40 -08001611 continue;
Saurabh Shah16329182018-02-23 12:26:20 -08001612
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301613 info.id = drm_id.at(0);
1614
Saurabh Shah16329182018-02-23 12:26:20 -08001615 drm_mgr_intf_->GetCrtcPPInfo(token_.crtc_id, &info);
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301616 vers->version[i] = hw_color_mgr_->GetFeatureVersion(info);
Ping Li281f48d2017-01-16 12:45:40 -08001617 }
1618 return kErrorNone;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001619}
1620
1621DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) {
Padmanabhan Komanduru1649f222019-03-05 11:25:00 +05301622 if (pending_doze_) {
1623 DLOGI("Doze state pending!! Skip for now");
1624 return kErrorNone;
1625 }
1626
Ping Li281f48d2017-01-16 12:45:40 -08001627 int ret = 0;
1628 PPFeatureInfo *feature = NULL;
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301629
1630 if (!hw_color_mgr_)
1631 return kErrorNotSupported;
Ping Li281f48d2017-01-16 12:45:40 -08001632
1633 while (true) {
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301634 std::vector<DRMPPFeatureID> drm_id = {};
1635 DRMPPFeatureInfo kernel_params = {};
1636 bool crtc_feature = true;
1637
Ping Li281f48d2017-01-16 12:45:40 -08001638 ret = feature_list->RetrieveNextFeature(&feature);
Varun Arora9a395152019-04-01 16:10:51 -07001639 if (ret || !feature)
Ping Li281f48d2017-01-16 12:45:40 -08001640 break;
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301641
1642 hw_color_mgr_->ToDrmFeatureId(kDSPP, feature->feature_id_, &drm_id);
1643 if (drm_id.empty())
1644 continue;
1645
1646 kernel_params.id = drm_id.at(0);
Gopikrishnaiah Anandan739faf92017-07-21 12:32:00 -07001647 drm_mgr_intf_->GetCrtcPPInfo(token_.crtc_id, &kernel_params);
Varun Arora9a395152019-04-01 16:10:51 -07001648 if (kernel_params.version == std::numeric_limits<uint32_t>::max()) {
Ping Li13c5ea12018-05-14 13:31:17 -07001649 crtc_feature = false;
Varun Arora9a395152019-04-01 16:10:51 -07001650 }
1651 DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
1652 for (DRMPPFeatureID id : drm_id) {
1653 if (id >= kPPFeaturesMax) {
1654 DLOGE("Invalid feature id %d", id);
1655 continue;
Rajesh Yadavd30b0cc2017-09-22 00:26:54 +05301656 }
Varun Arora9a395152019-04-01 16:10:51 -07001657 kernel_params.id = id;
1658 ret = hw_color_mgr_->GetDrmFeature(feature, &kernel_params);
1659 if (!ret && crtc_feature)
1660 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC,
1661 token_.crtc_id, &kernel_params);
1662 else if (!ret && !crtc_feature)
1663 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POST_PROC,
1664 token_.conn_id, &kernel_params);
1665
1666 hw_color_mgr_->FreeDrmFeatureData(&kernel_params);
Ping Li281f48d2017-01-16 12:45:40 -08001667 }
1668 }
1669
1670 // Once all features were consumed, then destroy all feature instance from feature_list,
1671 feature_list->Reset();
1672
1673 return kErrorNone;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001674}
1675
1676DisplayError HWDeviceDRM::SetVSyncState(bool enable) {
Saurabh Shah7171af52017-05-02 17:03:26 -07001677 return kErrorNotSupported;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001678}
1679
Anjaneya Prasad Musunurie8c67f22017-07-01 16:16:13 +05301680void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {
1681 // TODO(user): This function can be removed after fb is deprecated
1682}
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001683
1684DisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) {
Lei Chene26f91c2019-05-15 11:14:03 +08001685 uint32_t mode_flag = 0;
Lei Chen7994a792019-02-18 18:47:49 +08001686
1687 if (hw_display_mode == kModeCommand) {
1688 mode_flag = DRM_MODE_FLAG_CMD_MODE_PANEL;
1689 DLOGI_IF(kTagDriverConfig, "switch panel mode to command");
1690 } else if (hw_display_mode == kModeVideo) {
1691 mode_flag = DRM_MODE_FLAG_VID_MODE_PANEL;
1692 DLOGI_IF(kTagDriverConfig, "switch panel mode to video");
1693 }
1694
1695 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
1696 uint64_t current_bit_clk = connector_info_.modes[current_mode_index_].bit_clk_rate;
1697 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
1698 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1699 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1700 (current_mode.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) &&
1701 (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) &&
1702 (mode_flag & connector_info_.modes[mode_index].mode.flags)) {
1703 panel_mode_changed_ = mode_flag;
1704 synchronous_commit_ = true;
1705 return kErrorNone;
1706 }
1707 }
1708
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001709 return kErrorNotSupported;
1710}
1711
1712DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) {
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301713 if (bit_clk_rate_) {
1714 // bit rate update pending.
1715 // Defer any refresh rate setting.
1716 return kErrorNotSupported;
1717 }
1718
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301719 // Check if requested refresh rate is valid
Saurabh Shah7e16c932017-11-03 17:55:36 -07001720 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301721 uint64_t current_bit_clk = connector_info_.modes[current_mode_index_].bit_clk_rate;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301722 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -07001723 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1724 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05301725 (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) &&
Lei Chen7994a792019-02-18 18:47:49 +08001726 (current_mode.flags == connector_info_.modes[mode_index].mode.flags) &&
Saurabh Shah7e16c932017-11-03 17:55:36 -07001727 (refresh_rate == connector_info_.modes[mode_index].mode.vrefresh)) {
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301728 vrefresh_ = refresh_rate;
1729 DLOGV_IF(kTagDriverConfig, "Set refresh rate to %d", refresh_rate);
1730 return kErrorNone;
1731 }
1732 }
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001733 return kErrorNotSupported;
1734}
1735
Saurabh Shah8b021cf2017-03-14 12:16:43 -07001736
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001737
1738DisplayError HWDeviceDRM::GetHWScanInfo(HWScanInfo *scan_info) {
1739 return kErrorNotSupported;
1740}
1741
1742DisplayError HWDeviceDRM::GetVideoFormat(uint32_t config_index, uint32_t *video_format) {
1743 return kErrorNotSupported;
1744}
1745
1746DisplayError HWDeviceDRM::GetMaxCEAFormat(uint32_t *max_cea_format) {
1747 return kErrorNotSupported;
1748}
1749
1750DisplayError HWDeviceDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1751 return kErrorNotSupported;
1752}
1753
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001754DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
Saurabh Shah0ffee302016-11-22 10:42:11 -08001755 sde_drm::DRMScalerLUTInfo drm_lut_info = {};
1756 drm_lut_info.cir_lut = lut_info->cir_lut;
1757 drm_lut_info.dir_lut = lut_info->dir_lut;
1758 drm_lut_info.sep_lut = lut_info->sep_lut;
1759 drm_lut_info.cir_lut_size = lut_info->cir_lut_size;
1760 drm_lut_info.dir_lut_size = lut_info->dir_lut_size;
1761 drm_lut_info.sep_lut_size = lut_info->sep_lut_size;
1762 drm_mgr_intf_->SetScalerLUT(drm_lut_info);
1763
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001764 return kErrorNone;
1765}
1766
Varun Arorabaa16472018-08-16 16:19:59 -07001767DisplayError HWDeviceDRM::UnsetScaleLutConfig() {
1768 drm_mgr_intf_->UnsetScalerLUT();
1769
1770 return kErrorNone;
1771}
1772
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001773DisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
Rajavenu Kyatham836a76d2019-03-28 11:48:24 +05301774 if (IsResolutionSwitchEnabled()) {
1775 return kErrorNotSupported;
1776 }
1777
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001778 if (!hw_resource_.hw_dest_scalar_info.count) {
1779 return kErrorNotSupported;
1780 }
1781
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001782 uint32_t index = current_mode_index_;
1783
1784 if (mixer_attributes.width > display_attributes_[index].x_pixels ||
1785 mixer_attributes.height > display_attributes_[index].y_pixels) {
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001786 DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001787 mixer_attributes.width, mixer_attributes.height, display_attributes_[index].x_pixels,
1788 display_attributes_[index].y_pixels);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001789 return kErrorNotSupported;
1790 }
1791
1792 uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001793 if (display_attributes_[index].is_device_split) {
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001794 max_input_width *= 2;
1795 }
1796
1797 if (mixer_attributes.width > max_input_width) {
1798 DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
1799 max_input_width);
1800 return kErrorNotSupported;
1801 }
1802
1803 float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
1804 float display_aspect_ratio =
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001805 FLOAT(display_attributes_[index].x_pixels) / FLOAT(display_attributes_[index].y_pixels);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001806
1807 if (display_aspect_ratio != mixer_aspect_ratio) {
1808 DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001809 mixer_attributes.height, display_attributes_[index].x_pixels,
1810 display_attributes_[index].y_pixels);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001811 return kErrorNotSupported;
1812 }
1813
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001814 float scale_x = FLOAT(display_attributes_[index].x_pixels) / FLOAT(mixer_attributes.width);
1815 float scale_y = FLOAT(display_attributes_[index].y_pixels) / FLOAT(mixer_attributes.height);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001816 float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
1817 if (scale_x > max_scale_up || scale_y > max_scale_up) {
Saurabh Shah66c941b2016-07-06 17:34:05 -07001818 DLOGW(
1819 "Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f "
1820 "max_scale_up %f",
1821 scale_x, scale_y, max_scale_up);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001822 return kErrorNotSupported;
1823 }
1824
1825 float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
1826
1827 mixer_attributes_ = mixer_attributes;
1828 mixer_attributes_.split_left = mixer_attributes_.width;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001829 if (display_attributes_[index].is_device_split) {
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001830 mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
1831 }
1832
1833 return kErrorNone;
1834}
1835
1836DisplayError HWDeviceDRM::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
1837 if (!mixer_attributes) {
1838 return kErrorParameters;
1839 }
1840
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001841 *mixer_attributes = mixer_attributes_;
1842
1843 return kErrorNone;
1844}
1845
Varun Arora7c8ee542018-05-01 20:58:16 -07001846DisplayError HWDeviceDRM::DumpDebugData() {
Varun Aroraeaefa472018-05-21 13:20:20 -07001847 string dir_path = "/data/vendor/display/hw_recovery/";
Varun Arora7c8ee542018-05-01 20:58:16 -07001848 string device_str = device_name_;
Varun Arora7c8ee542018-05-01 20:58:16 -07001849
Varun Aroraeaefa472018-05-21 13:20:20 -07001850 // Attempt to make hw_recovery dir, it may exist
1851 if (mkdir(dir_path.c_str(), 0777) != 0 && errno != EEXIST) {
1852 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path.c_str(), errno,
1853 strerror(errno));
1854 return kErrorPermission;
1855 }
1856 // If it does exist, ensure permissions are fine
1857 if (errno == EEXIST && chmod(dir_path.c_str(), 0777) != 0) {
1858 DLOGW("Failed to change permissions on %s directory", dir_path.c_str());
1859 return kErrorPermission;
1860 }
1861
1862 string filename = dir_path+device_str+"_HWR_"+to_string(debug_dump_count_);
1863 ofstream dst(filename);
Varun Aroraeaefa472018-05-21 13:20:20 -07001864 debug_dump_count_++;
Varun Arora7c8ee542018-05-01 20:58:16 -07001865
Varun Arora9b9f6e22019-03-29 10:43:00 -07001866 {
1867 ifstream src;
1868 src.open("/sys/kernel/debug/dri/0/debug/dump");
1869 dst << "---- Event Logs ----" << std::endl;
1870 dst << src.rdbuf() << std::endl;
1871 src.close();
1872 }
Varun Arora7c8ee542018-05-01 20:58:16 -07001873
Varun Arora9b9f6e22019-03-29 10:43:00 -07001874 {
1875 ifstream src;
1876 src.open("/sys/kernel/debug/dri/0/debug/recovery_reg");
1877 dst << "---- All Registers ----" << std::endl;
1878 dst << src.rdbuf() << std::endl;
1879 src.close();
1880 }
Varun Arora7c8ee542018-05-01 20:58:16 -07001881
Varun Arora9b9f6e22019-03-29 10:43:00 -07001882 {
1883 ifstream src;
1884 src.open("/sys/kernel/debug/dri/0/debug/recovery_dbgbus");
1885 dst << "---- Debug Bus ----" << std::endl;
1886 dst << src.rdbuf() << std::endl;
1887 src.close();
1888 }
Varun Arora7c8ee542018-05-01 20:58:16 -07001889
Varun Arora9b9f6e22019-03-29 10:43:00 -07001890 {
1891 ifstream src;
1892 src.open("/sys/kernel/debug/dri/0/debug/recovery_vbif_dbgbus");
1893 dst << "---- VBIF Debug Bus ----" << std::endl;
1894 dst << src.rdbuf() << std::endl;
1895 src.close();
1896 }
Varun Arora7c8ee542018-05-01 20:58:16 -07001897
1898 dst.close();
Varun Aroraeaefa472018-05-21 13:20:20 -07001899 DLOGI("Wrote hw_recovery file %s", filename.c_str());
Varun Arora7c8ee542018-05-01 20:58:16 -07001900
1901 return kErrorNone;
1902}
1903
Anjaneya Prasad Musunurie250e672017-05-22 14:16:20 +05301904void HWDeviceDRM::GetDRMDisplayToken(sde_drm::DRMDisplayToken *token) const {
Saurabh Shahf8226712018-02-05 15:51:53 -08001905 *token = token_;
Anjaneya Prasad Musunurie250e672017-05-22 14:16:20 +05301906}
1907
Saurabh Shah66c941b2016-07-06 17:34:05 -07001908void HWDeviceDRM::UpdateMixerAttributes() {
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001909 uint32_t index = current_mode_index_;
1910
1911 mixer_attributes_.width = display_attributes_[index].x_pixels;
1912 mixer_attributes_.height = display_attributes_[index].y_pixels;
1913 mixer_attributes_.split_left = display_attributes_[index].is_device_split
Saurabh Shah66c941b2016-07-06 17:34:05 -07001914 ? hw_panel_info_.split_info.left_split
1915 : mixer_attributes_.width;
Ramkumar Radhakrishnan7e971e02017-08-17 14:19:15 +05301916 DLOGI("Mixer WxH %dx%d for %s", mixer_attributes_.width, mixer_attributes_.height, device_name_);
Varun Aroraebf52a62018-08-24 16:51:34 -07001917 update_mode_ = true;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001918}
1919
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001920void HWDeviceDRM::SetSecureConfig(const LayerBuffer &input_buffer, DRMSecureMode *fb_secure_mode,
1921 DRMSecurityLevel *security_level) {
1922 *fb_secure_mode = DRMSecureMode::NON_SECURE;
1923 *security_level = DRMSecurityLevel::SECURE_NON_SECURE;
1924
1925 if (input_buffer.flags.secure) {
1926 if (input_buffer.flags.secure_camera) {
1927 // IOMMU configuration for this framebuffer mode is secure domain & requires
1928 // only stage II translation, when this buffer is accessed by Display H/W.
1929 // Secure and non-secure planes can be attached to this CRTC.
1930 *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION;
1931 } else if (input_buffer.flags.secure_display) {
Sushil Chauhan1fc8b842017-08-21 18:40:29 -07001932 // IOMMU configuration for this framebuffer mode is secure domain & requires
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001933 // only stage II translation, when this buffer is accessed by Display H/W.
1934 // Only secure planes can be attached to this CRTC.
Sushil Chauhan1fc8b842017-08-21 18:40:29 -07001935 *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION;
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001936 *security_level = DRMSecurityLevel::SECURE_ONLY;
1937 } else {
1938 // IOMMU configuration for this framebuffer mode is secure domain & requires both
1939 // stage I and stage II translations, when this buffer is accessed by Display H/W.
1940 // Secure and non-secure planes can be attached to this CRTC.
1941 *fb_secure_mode = DRMSecureMode::SECURE;
1942 }
1943 }
1944}
1945
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -07001946void HWDeviceDRM::SetTopology(sde_drm::DRMTopology drm_topology, HWTopology *hw_topology) {
1947 switch (drm_topology) {
1948 case DRMTopology::SINGLE_LM: *hw_topology = kSingleLM; break;
1949 case DRMTopology::SINGLE_LM_DSC: *hw_topology = kSingleLMDSC; break;
1950 case DRMTopology::DUAL_LM: *hw_topology = kDualLM; break;
1951 case DRMTopology::DUAL_LM_DSC: *hw_topology = kDualLMDSC; break;
1952 case DRMTopology::DUAL_LM_MERGE: *hw_topology = kDualLMMerge; break;
1953 case DRMTopology::DUAL_LM_MERGE_DSC: *hw_topology = kDualLMMergeDSC; break;
1954 case DRMTopology::DUAL_LM_DSCMERGE: *hw_topology = kDualLMDSCMerge; break;
1955 case DRMTopology::PPSPLIT: *hw_topology = kPPSplit; break;
1956 default: *hw_topology = kUnknown; break;
1957 }
1958}
1959
Arun Kumar K.Rc033f942018-01-05 12:25:47 +05301960
Ramkumar Radhakrishnan07254302017-11-13 16:18:22 -08001961void HWDeviceDRM::SetMultiRectMode(const uint32_t flags, DRMMultiRectMode *target) {
1962 *target = DRMMultiRectMode::NONE;
1963 if (flags & kMultiRect) {
1964 *target = DRMMultiRectMode::SERIAL;
1965 if (flags & kMultiRectParallelMode) {
1966 *target = DRMMultiRectMode::PARALLEL;
1967 }
1968 }
1969}
1970
Arun Kumar K.Rc033f942018-01-05 12:25:47 +05301971void HWDeviceDRM::SetSsppTonemapFeatures(HWPipeInfo *pipe_info) {
1972 if (pipe_info->dgm_csc_info.op != kNoOp) {
1973 SDECsc csc = {};
1974 SetDGMCsc(pipe_info->dgm_csc_info, &csc);
1975 DLOGV_IF(kTagDriverConfig, "Call Perform DGM CSC Op = %s",
1976 (pipe_info->dgm_csc_info.op == kSet) ? "Set" : "Reset");
1977 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DGM_CSC_CONFIG, pipe_info->pipe_id,
1978 reinterpret_cast<uint64_t>(&csc.csc_v1));
1979 }
1980 if (pipe_info->inverse_pma_info.op != kNoOp) {
1981 DLOGV_IF(kTagDriverConfig, "Call Perform Inverse PMA Op = %s",
1982 (pipe_info->inverse_pma_info.op == kSet) ? "Set" : "Reset");
1983 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INVERSE_PMA, pipe_info->pipe_id,
1984 (pipe_info->inverse_pma_info.inverse_pma) ? 1: 0);
1985 }
1986 SetSsppLutFeatures(pipe_info);
1987}
1988
1989void HWDeviceDRM::SetDGMCsc(const HWPipeCscInfo &dgm_csc_info, SDECsc *csc) {
1990 SetDGMCscV1(dgm_csc_info.csc, &csc->csc_v1);
1991}
1992
1993void HWDeviceDRM::SetDGMCscV1(const HWCsc &dgm_csc, sde_drm_csc_v1 *csc_v1) {
1994 uint32_t i = 0;
1995 for (i = 0; i < MAX_CSC_MATRIX_COEFF_SIZE; i++) {
1996 csc_v1->ctm_coeff[i] = dgm_csc.ctm_coeff[i];
1997 DLOGV_IF(kTagDriverConfig, " DGM csc_v1[%d] = %d", i, csc_v1->ctm_coeff[i]);
1998 }
1999 for (i = 0; i < MAX_CSC_BIAS_SIZE; i++) {
2000 csc_v1->pre_bias[i] = dgm_csc.pre_bias[i];
2001 csc_v1->post_bias[i] = dgm_csc.post_bias[i];
2002 }
2003 for (i = 0; i < MAX_CSC_CLAMP_SIZE; i++) {
2004 csc_v1->pre_clamp[i] = dgm_csc.pre_clamp[i];
2005 csc_v1->post_clamp[i] = dgm_csc.post_clamp[i];
2006 }
2007}
2008
2009void HWDeviceDRM::SetSsppLutFeatures(HWPipeInfo *pipe_info) {
2010 for (HWPipeTonemapLutInfo &lut_info : pipe_info->lut_info) {
2011 if (lut_info.op != kNoOp) {
2012 std::shared_ptr<PPFeatureInfo> feature = lut_info.pay_load;
2013 if (feature == nullptr) {
2014 DLOGE("Null Pointer for Op = %d lut type = %d", lut_info.op, lut_info.type);
2015 continue;
2016 }
2017 DRMPPFeatureInfo kernel_params = {};
2018 std::vector<DRMPPFeatureID> drm_id = {};
2019 PPBlock pp_block = GetPPBlock(lut_info.type);
2020 hw_color_mgr_->ToDrmFeatureId(pp_block, feature->feature_id_, &drm_id);
2021 for (DRMPPFeatureID id : drm_id) {
Ping Li13c5ea12018-05-14 13:31:17 -07002022 if (id >= kPPFeaturesMax) {
2023 DLOGE("Invalid feature id %d", id);
2024 continue;
2025 }
Arun Kumar K.Rc033f942018-01-05 12:25:47 +05302026 kernel_params.id = id;
2027 bool disable = (lut_info.op == kReset);
2028 DLOGV_IF(kTagDriverConfig, "Lut Type = %d PPBlock = %d Op = %s Disable = %d Feature = %p",
2029 lut_info.type, pp_block, (lut_info.op ==kSet) ? "Set" : "Reset", disable,
2030 feature.get());
2031 int ret = hw_color_mgr_->GetDrmFeature(feature.get(), &kernel_params, disable);
2032 if (!ret) {
2033 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_POST_PROC, pipe_info->pipe_id,
2034 &kernel_params);
2035 hw_color_mgr_->FreeDrmFeatureData(&kernel_params);
2036 } else {
2037 DLOGE("GetDrmFeature failed for Lut type = %d", lut_info.type);
2038 }
2039 }
2040 drm_id.clear();
2041 }
2042 }
2043}
2044
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -07002045void HWDeviceDRM::AddDimLayerIfNeeded() {
2046 if (secure_display_active_ && hw_resource_.secure_disp_blend_stage >= 0) {
2047 HWSolidfillStage sf = {};
2048 sf.z_order = UINT32(hw_resource_.secure_disp_blend_stage);
2049 sf.roi = { 0.0, 0.0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height) };
2050 solid_fills_.clear();
2051 AddSolidfillStage(sf, 0xFF);
2052 SetSolidfillStages();
2053 }
Ramkumar Radhakrishnanbe13bab2019-01-04 17:41:42 -08002054
2055 if (!secure_display_active_) {
2056 DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
2057 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level);
2058 }
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -07002059}
2060
2061DisplayError HWDeviceDRM::NullCommit(bool synchronous, bool retain_planes) {
2062 DTRACE_SCOPED();
2063 AddDimLayerIfNeeded();
2064 int ret = drm_atomic_intf_->Commit(synchronous , retain_planes);
2065 if (ret) {
2066 DLOGE("failed with error %d", ret);
2067 return kErrorHardware;
2068 }
2069
2070 return kErrorNone;
2071}
2072
Sushil Chauhan06521582018-03-19 14:00:23 -07002073void HWDeviceDRM::DumpConnectorModeInfo() {
2074 for (uint32_t i = 0; i < (uint32_t)connector_info_.modes.size(); i++) {
2075 DLOGI("Mode[%d] Name:%s vref:%d hdisp:%d hsync_s:%d hsync_e:%d htotal:%d " \
2076 "vdisp:%d vsync_s:%d vsync_e:%d vtotal:%d\n", i, connector_info_.modes[i].mode.name,
2077 connector_info_.modes[i].mode.vrefresh, connector_info_.modes[i].mode.hdisplay,
2078 connector_info_.modes[i].mode.hsync_start, connector_info_.modes[i].mode.hsync_end,
2079 connector_info_.modes[i].mode.htotal, connector_info_.modes[i].mode.vdisplay,
2080 connector_info_.modes[i].mode.vsync_start, connector_info_.modes[i].mode.vsync_end,
2081 connector_info_.modes[i].mode.vtotal);
2082 }
2083}
2084
Ramkumar Radhakrishnanf7f52162019-06-06 19:40:04 -07002085void HWDeviceDRM::ResetROI() {
2086 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id, 0, nullptr);
2087 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id, 0, nullptr);
2088}
2089
2090bool HWDeviceDRM::IsFullFrameUpdate(const HWLayersInfo &hw_layer_info) {
2091 LayerRect full_frame = {0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height)};
2092
2093 const LayerRect &frame_roi = hw_layer_info.left_frame_roi.at(0);
2094 // If multiple ROIs are present, then it's not fullscreen update.
2095 if (hw_layer_info.left_frame_roi.size() > 1 ||
2096 (IsValid(frame_roi) && !IsCongruent(full_frame, frame_roi))) {
2097 return false;
Ramkumar Radhakrishnan3dcf8a22017-11-27 14:53:06 -08002098 }
Ramkumar Radhakrishnanf7f52162019-06-06 19:40:04 -07002099
2100 return true;
Ramkumar Radhakrishnan3dcf8a22017-11-27 14:53:06 -08002101}
2102
Pullakavi Srinivas9189e602018-12-19 16:58:07 +05302103DisplayError HWDeviceDRM::SetDynamicDSIClock(uint64_t bit_clk_rate) {
2104 return kErrorNotSupported;
2105}
2106
2107DisplayError HWDeviceDRM::GetDynamicDSIClock(uint64_t *bit_clk_rate) {
2108 return kErrorNotSupported;
2109}
2110
Ashish Kumar43c8d802019-02-05 20:14:28 +05302111void HWDeviceDRM::DumpHWLayers(HWLayers *hw_layers) {
2112 HWLayersInfo &hw_layer_info = hw_layers->info;
2113 DestScaleInfoMap &dest_scale_info_map = hw_layer_info.dest_scale_info_map;
2114 LayerStack *stack = hw_layer_info.stack;
2115 uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
2116 std::vector<LayerRect> &left_frame_roi = hw_layer_info.left_frame_roi;
2117 std::vector<LayerRect> &right_frame_roi = hw_layer_info.right_frame_roi;
2118 DLOGI("HWLayers Stack: layer_count: %d, app_layer_count: %d, gpu_target_index: %d",
2119 hw_layer_count, hw_layer_info.app_layer_count, hw_layer_info.gpu_target_index);
2120 DLOGI("LayerStackFlags = 0x%X, blend_cs = {primaries = %d, transfer = %d}",
2121 stack->flags, stack->blend_cs.primaries, stack->blend_cs.transfer);
2122 for (uint32_t i = 0; i < left_frame_roi.size(); i++) {
2123 DLOGI("left_frame_roi: x = %d, y = %d, w = %d, h = %d", INT(left_frame_roi[i].left),
2124 INT(left_frame_roi[i].top), INT(left_frame_roi[i].right), INT(left_frame_roi[i].bottom));
2125 }
2126 for (uint32_t i = 0; i < right_frame_roi.size(); i++) {
2127 DLOGI("right_frame_roi: x = %d, y = %d, w = %d h = %d", INT(right_frame_roi[i].left),
2128 INT(right_frame_roi[i].top), INT(right_frame_roi[i].right),
2129 INT(right_frame_roi[i].bottom));
2130 }
2131
2132 for (uint32_t i = 0; i < dest_scale_info_map.size(); i++) {
2133 HWDestScaleInfo *dest_scalar_data = dest_scale_info_map[i];
2134 if (dest_scalar_data->scale_data.enable.scale) {
2135 HWScaleData &scale_data = dest_scalar_data->scale_data;
2136 DLOGI("Dest scalar index %d Mixer WxH %dx%d", i,
2137 dest_scalar_data->mixer_width, dest_scalar_data->mixer_height);
2138 DLOGI("Panel ROI [%d, %d, %d, %d]", INT(dest_scalar_data->panel_roi.left),
2139 INT(dest_scalar_data->panel_roi.top), INT(dest_scalar_data->panel_roi.right),
2140 INT(dest_scalar_data->panel_roi.bottom));
2141 DLOGI("Dest scalar Dst WxH %dx%d", scale_data.dst_width, scale_data.dst_height);
2142 }
2143 }
2144
2145 for (uint32_t i = 0; i < hw_layer_count; i++) {
2146 HWLayerConfig &hw_config = hw_layers->config[i];
2147 HWRotatorSession &hw_rotator_session = hw_config.hw_rotator_session;
2148 HWSessionConfig &hw_session_config = hw_rotator_session.hw_session_config;
2149 DLOGI("========================= HW_layer: %d =========================", i);
2150 DLOGI("src_width = %d, src_height = %d, src_format = %d, src_LayerBufferFlags = 0x%X",
2151 hw_layer_info.hw_layers[i].input_buffer.width,
2152 hw_layer_info.hw_layers[i].input_buffer.height,
2153 hw_layer_info.hw_layers[i].input_buffer.format,
2154 hw_layer_info.hw_layers[i].input_buffer.flags);
2155 if (hw_config.use_inline_rot) {
2156 DLOGI("rotator = %s, rotation = %d, flip_horizontal = %s, flip_vertical = %s",
2157 "inline rotator", INT(hw_session_config.transform.rotation),
2158 hw_session_config.transform.flip_horizontal ? "true" : "false",
2159 hw_session_config.transform.flip_vertical ? "true" : "false");
2160 } else if (hw_rotator_session.mode == kRotatorOffline) {
2161 DLOGI("rotator = %s, rotation = %d, flip_horizontal = %s, flip_vertical = %s",
2162 "offline rotator", INT(hw_session_config.transform.rotation),
2163 hw_session_config.transform.flip_horizontal ? "true" : "false",
2164 hw_session_config.transform.flip_vertical ? "true" : "false");
2165 }
2166 if (hw_config.use_solidfill_stage) {
2167 HWSolidfillStage &hw_solidfill_stage = hw_config.hw_solidfill_stage;
2168 LayerSolidFill &solid_fill_info = hw_solidfill_stage.solid_fill_info;
2169 DLOGI("HW Solid fill info: z_order = %d, color = %d", hw_solidfill_stage.z_order,
2170 hw_solidfill_stage.color);
2171 DLOGI("bit_depth = %d, red = %d, green = %d, blue = %d, alpha = %d",
2172 solid_fill_info.bit_depth, solid_fill_info.red, solid_fill_info.green,
2173 solid_fill_info.blue, solid_fill_info.alpha);
2174 }
2175 for (uint32_t count = 0; count < 2; count++) {
2176 HWPipeInfo &left_pipe = hw_config.left_pipe;
2177 HWPipeInfo &right_pipe = hw_config.right_pipe;
2178 HWPipeInfo &pipe_info = (count == 0) ? left_pipe : right_pipe;
2179 HWScaleData &scale_data = pipe_info.scale_data;
2180 if (!pipe_info.valid) {
2181 continue;
2182 }
2183 std::string pipe = (count == 0) ? "left_pipe" : "right_pipe";
2184 DLOGI("pipe = %s, pipe_id = %d, z_order = %d, flags = 0x%X",
2185 pipe.c_str(), pipe_info.pipe_id, pipe_info.z_order, pipe_info.flags);
2186 DLOGI("src_rect: x = %d, y = %d, w = %d, h = %d", INT(pipe_info.src_roi.left),
2187 INT(pipe_info.src_roi.top), INT(pipe_info.src_roi.right - pipe_info.src_roi.left),
2188 INT(pipe_info.src_roi.bottom - pipe_info.src_roi.top));
2189 DLOGI("dst_rect: x = %d, y = %d, w = %d, h = %d", INT(pipe_info.dst_roi.left),
2190 INT(pipe_info.dst_roi.top), INT(pipe_info.dst_roi.right - pipe_info.dst_roi.left),
2191 INT(pipe_info.dst_roi.bottom - pipe_info.dst_roi.top));
2192 DLOGI("excl_rect: left = %d, top = %d, right = %d, bottom = %d",
2193 INT(pipe_info.excl_rect.left), INT(pipe_info.excl_rect.top),
2194 INT(pipe_info.excl_rect.right), INT(pipe_info.excl_rect.bottom));
2195 if (scale_data.enable.scale) {
2196 DLOGI("HWScaleData enable flags: scale = %s, direction_detection = %s, detail_enhance = %s,"
2197 " dyn_exp_disable = %s", scale_data.enable.scale ? "true" : "false",
2198 scale_data.enable.direction_detection ? "true" : "false",
2199 scale_data.enable.detail_enhance ? "true" : "false",
2200 scale_data.enable.dyn_exp_disable ? "true" : "false");
2201 DLOGI("lut_flags: lut_swap = 0x%X, lut_dir_wr = 0x%X, lut_y_cir_wr = 0x%X, "
2202 "lut_uv_cir_wr = 0x%X, lut_y_sep_wr = 0x%X, lut_uv_sep_wr = 0x%X",
2203 scale_data.lut_flag.lut_swap, scale_data.lut_flag.lut_dir_wr,
2204 scale_data.lut_flag.lut_y_cir_wr, scale_data.lut_flag.lut_uv_cir_wr,
2205 scale_data.lut_flag.lut_y_sep_wr, scale_data.lut_flag.lut_uv_sep_wr);
2206 DLOGI("dir_lut_idx = %d, y_rgb_cir_lut_idx = %d, uv_cir_lut_idx = %d, "
2207 "y_rgb_sep_lut_idx = %d, uv_sep_lut_idx = %d", scale_data.dir_lut_idx,
2208 scale_data.y_rgb_cir_lut_idx, scale_data.uv_cir_lut_idx,
2209 scale_data.y_rgb_sep_lut_idx, scale_data.uv_sep_lut_idx);
2210 }
2211 }
2212 }
2213}
2214
Saurabh Shah7d476ed2016-06-27 16:40:58 -07002215} // namespace sdm