blob: 7a82885efe7b29c6d21f24a3acde311d8f5dea98 [file] [log] [blame]
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001/*
Rohit Kulkarni21649ef2018-02-08 14:39:40 -08002* Copyright (c) 2017-2018, 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:
264 explicit FrameBufferObject(uint32_t fb_id) : fb_id_(fb_id) {
Saurabh Shah23cd08a2017-07-10 15:18:14 -0700265 }
266
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700267 ~FrameBufferObject() {
268 DRMMaster *master;
269 DRMMaster::GetInstance(&master);
270 int ret = master->RemoveFbId(fb_id_);
271 if (ret < 0) {
272 DLOGE("Removing fb_id %d failed with error %d", fb_id_, errno);
273 }
274 }
275 uint32_t GetFbId() { return fb_id_; }
Saurabh Shah23cd08a2017-07-10 15:18:14 -0700276
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700277 private:
278 uint32_t fb_id_;
279};
280
281HWDeviceDRM::Registry::Registry(BufferAllocator *buffer_allocator) :
282 buffer_allocator_(buffer_allocator) {
283 int value = 0;
284 if (Debug::GetProperty(DISABLE_FBID_CACHE, &value) == kErrorNone) {
285 disable_fbid_cache_ = (value == 1);
286 }
Saurabh Shah23cd08a2017-07-10 15:18:14 -0700287}
288
Saurabh Shah4d4f4002017-12-26 12:42:59 -0800289void HWDeviceDRM::Registry::Register(HWLayers *hw_layers) {
Saurabh Shahf84c4122017-04-07 10:34:40 -0700290 HWLayersInfo &hw_layer_info = hw_layers->info;
291 uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
292
293 for (uint32_t i = 0; i < hw_layer_count; i++) {
294 Layer &layer = hw_layer_info.hw_layers.at(i);
295 LayerBuffer *input_buffer = &layer.input_buffer;
296 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
297 HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700298 fbid_cache_limit_ = input_buffer->flags.video ? VIDEO_FBID_LIMIT : UI_FBID_LIMIT;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700299
Rohit Kulkarni8622e362017-01-30 18:14:10 -0800300 if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) {
Saurabh Shahf84c4122017-04-07 10:34:40 -0700301 input_buffer = &hw_rotator_session->output_buffer;
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700302 fbid_cache_limit_ = OFFLINE_ROTATOR_FBID_LIMIT;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700303 }
304
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700305 // layer input buffer map to fb id also applies for inline rot
306 MapBufferToFbId(&layer, input_buffer);
Rohit Kulkarni2d7151c2017-12-14 22:17:49 -0800307
308 if (hw_rotator_session->mode == kRotatorInline && hw_rotate_info->valid &&
309 hw_rotator_session->output_buffer.planes[0].fd >= 0) {
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700310 fbid_cache_limit_ += 1; // account for inline rot scratch buffer
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700311 MapBufferToFbId(&layer, &hw_rotator_session->output_buffer);
Rohit Kulkarni2d7151c2017-12-14 22:17:49 -0800312 }
Mahesh Aia1d2ceda2017-03-24 11:07:31 -0700313 }
314}
315
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700316int HWDeviceDRM::Registry::CreateFbId(LayerBuffer *buffer, uint32_t *fb_id) {
Mahesh Aia1d2ceda2017-03-24 11:07:31 -0700317 DRMMaster *master = nullptr;
318 DRMMaster::GetInstance(&master);
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700319 int ret = -1;
Mahesh Aia1d2ceda2017-03-24 11:07:31 -0700320
321 if (!master) {
322 DLOGE("Failed to acquire DRM Master instance");
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700323 return ret;
324 }
325
326 DRMBuffer layout{};
327 AllocatedBufferInfo buf_info{};
328 buf_info.fd = layout.fd = buffer->planes[0].fd;
329 buf_info.aligned_width = layout.width = buffer->width;
330 buf_info.aligned_height = layout.height = buffer->height;
331 buf_info.format = buffer->format;
332 GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
333 buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset, &layout.num_planes);
334 ret = master->CreateFbId(layout, fb_id);
335 if (ret < 0) {
336 DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
337 layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0], errno);
338 }
339
340 return ret;
341}
342
343void HWDeviceDRM::Registry::MapBufferToFbId(Layer* layer, LayerBuffer* buffer) {
344 if (buffer->planes[0].fd < 0) {
Mahesh Aia1d2ceda2017-03-24 11:07:31 -0700345 return;
346 }
347
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700348 uint64_t handle_id = buffer->handle_id;
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700349 if (!handle_id || disable_fbid_cache_) {
350 // In legacy path, clear fb_id map in each frame.
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700351 layer->buffer_map->buffer_map.clear();
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700352 } else {
353 if (layer->buffer_map->buffer_map.find(handle_id) != layer->buffer_map->buffer_map.end()) {
354 // Found fb_id for given handle_id key
355 return;
356 }
Saurabh Shahf84c4122017-04-07 10:34:40 -0700357
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700358 if (layer->buffer_map->buffer_map.size() >= fbid_cache_limit_) {
359 // Clear fb_id map, if the size reaches cache limit.
360 layer->buffer_map->buffer_map.clear();
361 }
Saurabh Shahf84c4122017-04-07 10:34:40 -0700362 }
363
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700364 uint32_t fb_id = 0;
365 if (CreateFbId(buffer, &fb_id) >= 0) {
366 // Create and cache the fb_id in map
367 layer->buffer_map->buffer_map[handle_id] = std::make_shared<FrameBufferObject>(fb_id);
368 }
369}
370
371void HWDeviceDRM::Registry::MapOutputBufferToFbId(LayerBuffer *output_buffer) {
372 if (output_buffer->planes[0].fd < 0) {
373 return;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700374 }
375
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700376 uint64_t handle_id = output_buffer->handle_id;
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700377 if (!handle_id || disable_fbid_cache_) {
378 // In legacy path, clear output buffer map in each frame.
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700379 output_buffer_map_.clear();
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700380 } else {
381 if (output_buffer_map_.find(handle_id) != output_buffer_map_.end()) {
382 return;
383 }
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700384
Sushil Chauhan1d00aa52018-06-20 16:11:52 -0700385 if (output_buffer_map_.size() >= UI_FBID_LIMIT) {
386 // Clear output buffer map, if the size reaches cache limit.
387 output_buffer_map_.clear();
388 }
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700389 }
390
391 uint32_t fb_id = 0;
392 if (CreateFbId(output_buffer, &fb_id) >= 0) {
393 output_buffer_map_[handle_id] = std::make_shared<FrameBufferObject>(fb_id);
394 }
Saurabh Shahf84c4122017-04-07 10:34:40 -0700395}
396
397void HWDeviceDRM::Registry::Clear() {
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700398 output_buffer_map_.clear();
Saurabh Shahf84c4122017-04-07 10:34:40 -0700399}
400
Sushil Chauhanabc5b272018-06-20 16:18:13 -0700401uint32_t HWDeviceDRM::Registry::GetFbId(Layer *layer, uint64_t handle_id) {
402 auto it = layer->buffer_map->buffer_map.find(handle_id);
403 if (it != layer->buffer_map->buffer_map.end()) {
404 FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
405 return fb_obj->GetFbId();
406 }
407
408 return 0;
409}
410
411uint32_t HWDeviceDRM::Registry::GetOutputFbId(uint64_t handle_id) {
412 auto it = output_buffer_map_.find(handle_id);
413 if (it != output_buffer_map_.end()) {
414 FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
415 return fb_obj->GetFbId();
416 }
417
418 return 0;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700419}
420
421HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
422 HWInfoInterface *hw_info_intf)
423 : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
424 registry_(buffer_allocator) {
Saurabh Shah66c941b2016-07-06 17:34:05 -0700425 hw_info_intf_ = hw_info_intf;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700426}
427
428DisplayError HWDeviceDRM::Init() {
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530429 int ret = 0;
Saurabh Shah7e16c932017-11-03 17:55:36 -0700430 DRMMaster *drm_master = {};
431 DRMMaster::GetInstance(&drm_master);
432 drm_master->GetHandle(&dev_fd_);
433 DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700434
Mathew Joseph Karimpanal731bc932017-11-22 10:04:56 +0530435 if (-1 == display_id_) {
436 if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
437 DLOGE("RegisterDisplay (by type) failed for %s", device_name_);
438 return kErrorResources;
439 }
440 } else if (drm_mgr_intf_->RegisterDisplay(display_id_, &token_)) {
441 DLOGE("RegisterDisplay (by id) failed for %s - %d", device_name_, display_id_);
Saurabh Shah7e16c932017-11-03 17:55:36 -0700442 return kErrorResources;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700443 }
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700444
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530445 if (token_.conn_id > INT32_MAX) {
446 DLOGE("Connector id %u beyond supported range", token_.conn_id);
447 drm_mgr_intf_->UnregisterDisplay(token_);
448 return kErrorNotSupported;
449 }
450
Mathew Joseph Karimpanal731bc932017-11-22 10:04:56 +0530451 display_id_ = static_cast<int32_t>(token_.conn_id);
452
Mathew Joseph Karimpanal43c9d692018-06-14 13:45:27 +0530453 ret = drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
454 if (ret) {
455 DLOGE("Failed creating atomic request for connector id %u. Error: %d.", token_.conn_id, ret);
456 drm_mgr_intf_->UnregisterDisplay(token_);
457 return kErrorResources;
458 }
459
460 ret = drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
461 if (ret) {
462 DLOGE("Failed getting info for connector id %u. Error: %d.", token_.conn_id, ret);
463 drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
464 drm_atomic_intf_ = {};
465 drm_mgr_intf_->UnregisterDisplay(token_);
466 return kErrorHardware;
467 }
468
469 if (connector_info_.modes.empty()) {
470 DLOGE("Critical error: Zero modes on connector id %u.", token_.conn_id);
471 drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
472 drm_atomic_intf_ = {};
473 drm_mgr_intf_->UnregisterDisplay(token_);
474 return kErrorHardware;
475 }
476
Saurabh Shah66c941b2016-07-06 17:34:05 -0700477 hw_info_intf_->GetHWResourceInfo(&hw_resource_);
Saurabh Shah7e16c932017-11-03 17:55:36 -0700478
479 InitializeConfigs();
480 PopulateHWPanelInfo();
481 UpdateMixerAttributes();
482
Saurabh Shah0ffee302016-11-22 10:42:11 -0800483 // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
484 if (hw_resource_.has_qseed3) {
485 hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
486 }
Saurabh Shah7e16c932017-11-03 17:55:36 -0700487
Rajesh Yadavc4f67b82017-11-15 20:37:13 +0530488 std::unique_ptr<HWColorManagerDrm> hw_color_mgr(new HWColorManagerDrm());
489 hw_color_mgr_ = std::move(hw_color_mgr);
490
Saurabh Shah66c941b2016-07-06 17:34:05 -0700491 return kErrorNone;
492}
493
494DisplayError HWDeviceDRM::Deinit() {
Saurabh Shah3cbc1ae2017-09-12 16:07:41 -0700495 DisplayError err = kErrorNone;
496 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, 0);
497 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
498 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, nullptr);
499 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700500 int ret = NullCommit(true /* synchronous */, false /* retain_planes */);
Saurabh Shah3cbc1ae2017-09-12 16:07:41 -0700501 if (ret) {
502 DLOGE("Commit failed with error: %d", ret);
503 err = kErrorHardware;
504 }
505
Saurabh Shah0ffee302016-11-22 10:42:11 -0800506 delete hw_scale_;
Saurabh Shahf84c4122017-04-07 10:34:40 -0700507 registry_.Clear();
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700508 display_attributes_ = {};
Saurabh Shah66c941b2016-07-06 17:34:05 -0700509 drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
510 drm_atomic_intf_ = {};
511 drm_mgr_intf_->UnregisterDisplay(token_);
Saurabh Shah3cbc1ae2017-09-12 16:07:41 -0700512 return err;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700513}
514
Mathew Joseph Karimpanal731bc932017-11-22 10:04:56 +0530515DisplayError HWDeviceDRM::GetDisplayId(int32_t *display_id) {
516 *display_id = display_id_;
517 return kErrorNone;
518}
519
Saurabh Shah66c941b2016-07-06 17:34:05 -0700520void HWDeviceDRM::InitializeConfigs() {
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700521 current_mode_index_ = 0;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530522 // Update current mode with preferred mode
523 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -0700524 if (connector_info_.modes[mode_index].mode.type & DRM_MODE_TYPE_PREFERRED) {
Mathew Joseph Karimpanal351bf872018-08-28 16:08:28 +0530525 DLOGI("Updating current display mode %d to preferred mode %d.", current_mode_index_,
526 mode_index);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530527 current_mode_index_ = mode_index;
528 break;
529 }
530 }
531
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700532 display_attributes_.resize(connector_info_.modes.size());
533
Saurabh Shah7e16c932017-11-03 17:55:36 -0700534 uint32_t width = connector_info_.modes[current_mode_index_].mode.hdisplay;
535 uint32_t height = connector_info_.modes[current_mode_index_].mode.vdisplay;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700536 for (uint32_t i = 0; i < connector_info_.modes.size(); i++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -0700537 auto &mode = connector_info_.modes[i].mode;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700538 if (mode.hdisplay != width || mode.vdisplay != height) {
539 resolution_switch_enabled_ = true;
540 }
541 PopulateDisplayAttributes(i);
542 }
Saurabh Shah66c941b2016-07-06 17:34:05 -0700543}
544
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700545DisplayError HWDeviceDRM::PopulateDisplayAttributes(uint32_t index) {
Saurabh Shah66c941b2016-07-06 17:34:05 -0700546 drmModeModeInfo mode = {};
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700547 uint32_t mm_width = 0;
548 uint32_t mm_height = 0;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700549 DRMTopology topology = DRMTopology::SINGLE_LM;
550
551 if (default_mode_) {
552 DRMResMgr *res_mgr = nullptr;
553 int ret = DRMResMgr::GetInstance(&res_mgr);
554 if (ret < 0) {
555 DLOGE("Failed to acquire DRMResMgr instance");
556 return kErrorResources;
557 }
558
559 res_mgr->GetMode(&mode);
560 res_mgr->GetDisplayDimInMM(&mm_width, &mm_height);
561 } else {
Saurabh Shah7e16c932017-11-03 17:55:36 -0700562 mode = connector_info_.modes[index].mode;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700563 mm_width = connector_info_.mmWidth;
564 mm_height = connector_info_.mmHeight;
Saurabh Shah7e16c932017-11-03 17:55:36 -0700565 topology = connector_info_.modes[index].topology;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700566 }
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700567
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700568 display_attributes_[index].x_pixels = mode.hdisplay;
569 display_attributes_[index].y_pixels = mode.vdisplay;
570 display_attributes_[index].fps = mode.vrefresh;
571 display_attributes_[index].vsync_period_ns =
572 UINT32(1000000000L / display_attributes_[index].fps);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700573
574 /*
575 Active Front Sync Back
576 Region Porch Porch
577 <-----------------------><----------------><-------------><-------------->
578 <----- [hv]display ----->
579 <------------- [hv]sync_start ------------>
580 <--------------------- [hv]sync_end --------------------->
581 <-------------------------------- [hv]total ----------------------------->
582 */
583
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700584 display_attributes_[index].v_front_porch = mode.vsync_start - mode.vdisplay;
585 display_attributes_[index].v_pulse_width = mode.vsync_end - mode.vsync_start;
586 display_attributes_[index].v_back_porch = mode.vtotal - mode.vsync_end;
587 display_attributes_[index].v_total = mode.vtotal;
588 display_attributes_[index].h_total = mode.htotal;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700589 display_attributes_[index].is_device_split =
Rohit Kulkarni2faa91c2017-06-05 15:43:48 -0700590 (topology == DRMTopology::DUAL_LM || topology == DRMTopology::DUAL_LM_MERGE ||
591 topology == DRMTopology::DUAL_LM_MERGE_DSC || topology == DRMTopology::DUAL_LM_DSC ||
592 topology == DRMTopology::DUAL_LM_DSCMERGE);
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -0700593 display_attributes_[index].clock_khz = mode.clock;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700594
Saurabh Shah88331992017-07-17 14:53:00 -0700595 // If driver doesn't return panel width/height information, default to 320 dpi
596 if (INT(mm_width) <= 0 || INT(mm_height) <= 0) {
597 mm_width = UINT32(((FLOAT(mode.hdisplay) * 25.4f) / 320.0f) + 0.5f);
598 mm_height = UINT32(((FLOAT(mode.vdisplay) * 25.4f) / 320.0f) + 0.5f);
599 DLOGW("Driver doesn't report panel physical width and height - defaulting to 320dpi");
600 }
601
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700602 display_attributes_[index].x_dpi = (FLOAT(mode.hdisplay) * 25.4f) / FLOAT(mm_width);
603 display_attributes_[index].y_dpi = (FLOAT(mode.vdisplay) * 25.4f) / FLOAT(mm_height);
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -0700604 SetTopology(topology, &display_attributes_[index].topology);
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700605
Ramkumar Radhakrishnanf5f24c92017-08-11 18:30:57 -0700606 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 -0700607 " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
608 index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700609 display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
Ramkumar Radhakrishnanf5f24c92017-08-11 18:30:57 -0700610 display_attributes_[index].fps, display_attributes_[index].is_device_split,
611 display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
612 display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -0700613 display_attributes_[index].h_total, display_attributes_[index].clock_khz,
614 display_attributes_[index].topology);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700615
616 return kErrorNone;
617}
618
Saurabh Shah66c941b2016-07-06 17:34:05 -0700619void HWDeviceDRM::PopulateHWPanelInfo() {
620 hw_panel_info_ = {};
621
622 snprintf(hw_panel_info_.panel_name, sizeof(hw_panel_info_.panel_name), "%s",
623 connector_info_.panel_name.c_str());
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700624
Ramkumar Radhakrishnanee0aab22017-10-16 16:11:18 -0700625 uint32_t index = current_mode_index_;
626 hw_panel_info_.split_info.left_split = display_attributes_[index].x_pixels;
627 if (display_attributes_[index].is_device_split) {
628 hw_panel_info_.split_info.left_split = hw_panel_info_.split_info.right_split =
629 display_attributes_[index].x_pixels / 2;
630 }
Saurabh Shah66c941b2016-07-06 17:34:05 -0700631
Saurabh Shah7e16c932017-11-03 17:55:36 -0700632 hw_panel_info_.partial_update = connector_info_.modes[index].num_roi;
633 hw_panel_info_.left_roi_count = UINT32(connector_info_.modes[index].num_roi);
634 hw_panel_info_.right_roi_count = UINT32(connector_info_.modes[index].num_roi);
635 hw_panel_info_.left_align = connector_info_.modes[index].xstart;
636 hw_panel_info_.top_align = connector_info_.modes[index].ystart;
637 hw_panel_info_.width_align = connector_info_.modes[index].walign;
638 hw_panel_info_.height_align = connector_info_.modes[index].halign;
639 hw_panel_info_.min_roi_width = connector_info_.modes[index].wmin;
640 hw_panel_info_.min_roi_height = connector_info_.modes[index].hmin;
641 hw_panel_info_.needs_roi_merge = connector_info_.modes[index].roi_merge;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700642 hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
Sushil Chauhan8f514a52018-02-27 17:35:44 -0800643 hw_panel_info_.qsync_support = connector_info_.qsync_support;
Saurabh Shah7e16c932017-11-03 17:55:36 -0700644 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530645 if (hw_panel_info_.dynamic_fps) {
646 uint32_t min_fps = current_mode.vrefresh;
647 uint32_t max_fps = current_mode.vrefresh;
648 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -0700649 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
650 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay)) {
651 if (min_fps > connector_info_.modes[mode_index].mode.vrefresh) {
652 min_fps = connector_info_.modes[mode_index].mode.vrefresh;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530653 }
Saurabh Shah7e16c932017-11-03 17:55:36 -0700654 if (max_fps < connector_info_.modes[mode_index].mode.vrefresh) {
655 max_fps = connector_info_.modes[mode_index].mode.vrefresh;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530656 }
657 }
658 }
659 hw_panel_info_.min_fps = min_fps;
660 hw_panel_info_.max_fps = max_fps;
661 } else {
662 hw_panel_info_.min_fps = current_mode.vrefresh;
663 hw_panel_info_.max_fps = current_mode.vrefresh;
664 }
665
Saurabh Shah66c941b2016-07-06 17:34:05 -0700666 hw_panel_info_.is_primary_panel = connector_info_.is_primary;
667 hw_panel_info_.is_pluggable = 0;
Sushil Chauhan80e58432017-07-06 11:39:17 -0700668 hw_panel_info_.hdr_enabled = connector_info_.panel_hdr_prop.hdr_enabled;
Sushil Chauhanaa8be832018-08-31 13:38:20 -0700669 // Convert the luminance values to cd/m^2 units.
670 hw_panel_info_.peak_luminance = FLOAT(connector_info_.panel_hdr_prop.peak_brightness) / 10000.0f;
671 hw_panel_info_.blackness_level = FLOAT(connector_info_.panel_hdr_prop.blackness_level) / 10000.0f;
Sushil Chauhan80e58432017-07-06 11:39:17 -0700672 hw_panel_info_.primaries.white_point[0] = connector_info_.panel_hdr_prop.display_primaries[0];
673 hw_panel_info_.primaries.white_point[1] = connector_info_.panel_hdr_prop.display_primaries[1];
674 hw_panel_info_.primaries.red[0] = connector_info_.panel_hdr_prop.display_primaries[2];
675 hw_panel_info_.primaries.red[1] = connector_info_.panel_hdr_prop.display_primaries[3];
676 hw_panel_info_.primaries.green[0] = connector_info_.panel_hdr_prop.display_primaries[4];
677 hw_panel_info_.primaries.green[1] = connector_info_.panel_hdr_prop.display_primaries[5];
678 hw_panel_info_.primaries.blue[0] = connector_info_.panel_hdr_prop.display_primaries[6];
679 hw_panel_info_.primaries.blue[1] = connector_info_.panel_hdr_prop.display_primaries[7];
Ramkumar Radhakrishnan5c94f052017-07-06 11:59:14 -0700680 hw_panel_info_.transfer_time_us = connector_info_.transfer_time_us;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700681
Prabhanjan Kandula5bc7f8b2017-05-23 12:24:57 -0700682 // no supprt for 90 rotation only flips or 180 supported
683 hw_panel_info_.panel_orientation.rotation = 0;
684 hw_panel_info_.panel_orientation.flip_horizontal =
685 (connector_info_.panel_orientation == DRMRotation::FLIP_H) ||
686 (connector_info_.panel_orientation == DRMRotation::ROT_180);
687 hw_panel_info_.panel_orientation.flip_vertical =
688 (connector_info_.panel_orientation == DRMRotation::FLIP_V) ||
689 (connector_info_.panel_orientation == DRMRotation::ROT_180);
690
Saurabh Shah66c941b2016-07-06 17:34:05 -0700691 GetHWDisplayPortAndMode();
692 GetHWPanelMaxBrightness();
693
694 DLOGI("%s, Panel Interface = %s, Panel Mode = %s, Is Primary = %d", device_name_,
695 interface_str_.c_str(), hw_panel_info_.mode == kModeVideo ? "Video" : "Command",
696 hw_panel_info_.is_primary_panel);
Sushil Chauhan8f514a52018-02-27 17:35:44 -0800697 DLOGI("Partial Update = %d, Dynamic FPS = %d, HDR Panel = %d QSync = %d",
698 hw_panel_info_.partial_update, hw_panel_info_.dynamic_fps, hw_panel_info_.hdr_enabled,
699 hw_panel_info_.qsync_support);
Saurabh Shah66c941b2016-07-06 17:34:05 -0700700 DLOGI("Align: left = %d, width = %d, top = %d, height = %d", hw_panel_info_.left_align,
701 hw_panel_info_.width_align, hw_panel_info_.top_align, hw_panel_info_.height_align);
702 DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d", hw_panel_info_.min_roi_width,
703 hw_panel_info_.min_roi_height, hw_panel_info_.needs_roi_merge);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +0530704 DLOGI("FPS: min = %d, max = %d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
Saurabh Shah66c941b2016-07-06 17:34:05 -0700705 DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
706 hw_panel_info_.split_info.right_split);
Ramkumar Radhakrishnan5c94f052017-07-06 11:59:14 -0700707 DLOGI("Panel Transfer time = %d us", hw_panel_info_.transfer_time_us);
Saurabh Shah66c941b2016-07-06 17:34:05 -0700708}
709
710void HWDeviceDRM::GetHWDisplayPortAndMode() {
711 hw_panel_info_.port = kPortDefault;
712 hw_panel_info_.mode =
713 (connector_info_.panel_mode == sde_drm::DRMPanelMode::VIDEO) ? kModeVideo : kModeCommand;
714
715 if (default_mode_) {
716 return;
717 }
718
719 switch (connector_info_.type) {
720 case DRM_MODE_CONNECTOR_DSI:
721 hw_panel_info_.port = kPortDSI;
722 interface_str_ = "DSI";
723 break;
724 case DRM_MODE_CONNECTOR_LVDS:
725 hw_panel_info_.port = kPortLVDS;
726 interface_str_ = "LVDS";
727 break;
728 case DRM_MODE_CONNECTOR_eDP:
729 hw_panel_info_.port = kPortEDP;
730 interface_str_ = "EDP";
731 break;
732 case DRM_MODE_CONNECTOR_TV:
733 case DRM_MODE_CONNECTOR_HDMIA:
734 case DRM_MODE_CONNECTOR_HDMIB:
735 hw_panel_info_.port = kPortDTV;
736 interface_str_ = "HDMI";
737 break;
738 case DRM_MODE_CONNECTOR_VIRTUAL:
739 hw_panel_info_.port = kPortWriteBack;
740 interface_str_ = "Virtual";
741 break;
742 case DRM_MODE_CONNECTOR_DisplayPort:
743 // TODO(user): Add when available
744 interface_str_ = "DisplayPort";
745 break;
746 }
747
748 return;
749}
750
751void HWDeviceDRM::GetHWPanelMaxBrightness() {
752 char brightness[kMaxStringLength] = {0};
Saurabh Shah8b021cf2017-03-14 12:16:43 -0700753 string kMaxBrightnessNode = "/sys/class/backlight/panel0-backlight/max_brightness";
Saurabh Shah66c941b2016-07-06 17:34:05 -0700754
755 hw_panel_info_.panel_max_brightness = 255;
Saurabh Shah8b021cf2017-03-14 12:16:43 -0700756 int fd = Sys::open_(kMaxBrightnessNode.c_str(), O_RDONLY);
Saurabh Shah66c941b2016-07-06 17:34:05 -0700757 if (fd < 0) {
Saurabh Shah8b021cf2017-03-14 12:16:43 -0700758 DLOGW("Failed to open max brightness node = %s, error = %s", kMaxBrightnessNode.c_str(),
Saurabh Shah66c941b2016-07-06 17:34:05 -0700759 strerror(errno));
760 return;
761 }
762
763 if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
764 hw_panel_info_.panel_max_brightness = atoi(brightness);
765 DLOGI("Max brightness level = %d", hw_panel_info_.panel_max_brightness);
766 } else {
767 DLOGW("Failed to read max brightness level. error = %s", strerror(errno));
768 }
769
770 Sys::close_(fd);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700771}
772
773DisplayError HWDeviceDRM::GetActiveConfig(uint32_t *active_config) {
Pullakavi Srinivas8b33a282018-11-01 12:45:38 +0530774 *active_config = current_mode_index_;
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700775 return kErrorNone;
776}
777
778DisplayError HWDeviceDRM::GetNumDisplayAttributes(uint32_t *count) {
Pullakavi Srinivas8b33a282018-11-01 12:45:38 +0530779 *count = UINT32(display_attributes_.size());
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700780 return kErrorNone;
781}
782
783DisplayError HWDeviceDRM::GetDisplayAttributes(uint32_t index,
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700784 HWDisplayAttributes *display_attributes) {
785 if (index >= display_attributes_.size()) {
786 return kErrorParameters;
787 }
Pullakavi Srinivas8b33a282018-11-01 12:45:38 +0530788 *display_attributes = display_attributes_[index];
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700789 return kErrorNone;
790}
791
792DisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) {
793 *panel_info = hw_panel_info_;
794 return kErrorNone;
795}
796
797DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700798 if (index >= display_attributes_.size()) {
Ramkumar Radhakrishnan0dc25f32017-09-06 17:05:18 -0700799 DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size()));
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700800 return kErrorParameters;
801 }
Saurabh Shah7e16c932017-11-03 17:55:36 -0700802
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700803 current_mode_index_ = index;
Ramkumar Radhakrishnanee0aab22017-10-16 16:11:18 -0700804 PopulateHWPanelInfo();
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700805 UpdateMixerAttributes();
Saurabh Shah7e16c932017-11-03 17:55:36 -0700806
807 DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \
808 " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d",
809 index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels,
810 display_attributes_[index].x_dpi, display_attributes_[index].y_dpi,
811 display_attributes_[index].fps, display_attributes_[index].is_device_split,
812 display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch,
813 display_attributes_[index].v_pulse_width, display_attributes_[index].v_total,
814 display_attributes_[index].h_total, display_attributes_[index].clock_khz,
815 display_attributes_[index].topology);
816
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700817 return kErrorNone;
818}
819
820DisplayError HWDeviceDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
821 return kErrorNotSupported;
822}
823
srikanth rajagopalan5d320c62017-06-05 21:08:57 -0700824DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) {
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700825 return kErrorNone;
826}
827
Varun Arorabbb062e2018-07-03 22:33:59 -0700828DisplayError HWDeviceDRM::PowerOn(const HWQosData &qos_data, int *release_fence) {
Varun Arorabbb062e2018-07-03 22:33:59 -0700829 SetQOSData(qos_data);
830
Varun Aroraef987292018-04-16 17:16:42 -0700831 int64_t release_fence_t = -1;
Sushil Chauhan93c892c2018-05-11 17:15:37 -0700832 update_mode_ = true;
Sushil Chauhan3396e202017-04-14 18:34:22 -0700833 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
834 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
Varun Aroraef987292018-04-16 17:16:42 -0700835 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700836 int ret = NullCommit(true /* synchronous */, true /* retain_planes */);
Sushil Chauhan56755522017-06-01 13:39:50 -0700837 if (ret) {
Sushil Chauhana4d1fc02017-08-07 17:41:39 -0700838 DLOGE("Failed with error: %d", ret);
Sushil Chauhan56755522017-06-01 13:39:50 -0700839 return kErrorHardware;
840 }
Saurabh Shah82b06f42017-09-06 16:43:49 -0700841
Varun Aroraef987292018-04-16 17:16:42 -0700842 *release_fence = static_cast<int>(release_fence_t);
Varun Arora006e3a12018-04-20 17:09:35 -0700843 DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700844 return kErrorNone;
845}
846
Varun Arora78580b82018-09-10 13:59:57 -0700847DisplayError HWDeviceDRM::PowerOff(bool teardown) {
Saurabh Shaha917aa72017-09-15 13:27:24 -0700848 DTRACE_SCOPED();
Sushil Chauhan23fc6e12017-06-22 11:15:51 -0700849 if (!drm_atomic_intf_) {
850 DLOGE("DRM Atomic Interface is null!");
851 return kErrorUndefined;
852 }
853
Ramkumar Radhakrishnan3dcf8a22017-11-27 14:53:06 -0800854 SetFullROI();
Ramkumar Radhakrishnan98479932018-03-28 15:33:08 -0700855 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
856 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700857 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
858 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700859 int ret = NullCommit(true /* synchronous */, false /* retain_planes */);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700860 if (ret) {
Sushil Chauhana4d1fc02017-08-07 17:41:39 -0700861 DLOGE("Failed with error: %d", ret);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700862 return kErrorHardware;
863 }
Saurabh Shah82b06f42017-09-06 16:43:49 -0700864
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700865 return kErrorNone;
866}
867
Varun Arorabbb062e2018-07-03 22:33:59 -0700868DisplayError HWDeviceDRM::Doze(const HWQosData &qos_data, int *release_fence) {
Saurabh Shaha917aa72017-09-15 13:27:24 -0700869 DTRACE_SCOPED();
Varun Aroraef987292018-04-16 17:16:42 -0700870
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;
Ramakant Singhda5072f2018-07-09 14:20:01 -0700874
875 if (first_cycle_) {
876 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
877 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
878 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
879 }
Sushil Chauhana4d1fc02017-08-07 17:41:39 -0700880 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700881 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
Varun Aroraef987292018-04-16 17:16:42 -0700882 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700883 int ret = NullCommit(true /* synchronous */, true /* retain_planes */);
Sushil Chauhana4d1fc02017-08-07 17:41:39 -0700884 if (ret) {
885 DLOGE("Failed with error: %d", ret);
886 return kErrorHardware;
887 }
888
Varun Aroraef987292018-04-16 17:16:42 -0700889 *release_fence = static_cast<int>(release_fence_t);
Varun Arora006e3a12018-04-20 17:09:35 -0700890 DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700891 return kErrorNone;
892}
893
Varun Arorabbb062e2018-07-03 22:33:59 -0700894DisplayError HWDeviceDRM::DozeSuspend(const HWQosData &qos_data, int *release_fence) {
Saurabh Shaha917aa72017-09-15 13:27:24 -0700895 DTRACE_SCOPED();
Varun Aroraef987292018-04-16 17:16:42 -0700896
Varun Arorabbb062e2018-07-03 22:33:59 -0700897 SetQOSData(qos_data);
898
Varun Aroraef987292018-04-16 17:16:42 -0700899 int64_t release_fence_t = -1;
Ramakant Singhda5072f2018-07-09 14:20:01 -0700900
901 if (first_cycle_) {
902 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
903 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
904 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
905 }
Saurabh Shaha917aa72017-09-15 13:27:24 -0700906 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
Sushil Chauhan3396e202017-04-14 18:34:22 -0700907 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
908 DRMPowerMode::DOZE_SUSPEND);
Varun Aroraef987292018-04-16 17:16:42 -0700909 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -0700910 int ret = NullCommit(true /* synchronous */, true /* retain_planes */);
Saurabh Shaha917aa72017-09-15 13:27:24 -0700911 if (ret) {
912 DLOGE("Failed with error: %d", ret);
913 return kErrorHardware;
914 }
915
Varun Aroraef987292018-04-16 17:16:42 -0700916 *release_fence = static_cast<int>(release_fence_t);
Varun Arora006e3a12018-04-20 17:09:35 -0700917 DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700918 return kErrorNone;
919}
920
Varun Arorabbb062e2018-07-03 22:33:59 -0700921void HWDeviceDRM::SetQOSData(const HWQosData &qos_data) {
922 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, qos_data.clock_hz);
923 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, qos_data.core_ab_bps);
924 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, qos_data.core_ib_bps);
925 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_AB, token_.crtc_id, qos_data.llcc_ab_bps);
926 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_IB, token_.crtc_id, qos_data.llcc_ib_bps);
927 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_AB, token_.crtc_id, qos_data.dram_ab_bps);
928 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_IB, token_.crtc_id, qos_data.dram_ib_bps);
929 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_PREFILL_BW, token_.crtc_id,
930 qos_data.rot_prefill_bw_bps);
931 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_CLK, token_.crtc_id, qos_data.rot_clock_hz);
932}
933
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700934DisplayError HWDeviceDRM::Standby() {
935 return kErrorNone;
936}
937
Saurabh Shah66c941b2016-07-06 17:34:05 -0700938void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) {
939 if (default_mode_) {
940 return;
941 }
942
943 HWLayersInfo &hw_layer_info = hw_layers->info;
944 uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
Ramkumar Radhakrishnan3c4de112017-05-24 22:38:30 -0700945 HWQosData &qos_data = hw_layers->qos_data;
Sushil Chauhan1021cc02017-05-03 15:11:43 -0700946 DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700947 uint32_t index = current_mode_index_;
Saurabh Shah7e16c932017-11-03 17:55:36 -0700948 drmModeModeInfo current_mode = connector_info_.modes[index].mode;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700949
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -0700950 solid_fills_.clear();
951
Saurabh Shahe9f55d72017-03-03 15:14:13 -0800952 // TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
953 if (hw_panel_info_.partial_update) {
954 const int kNumMaxROIs = 4;
955 DRMRect crtc_rects[kNumMaxROIs] = {{0, 0, mixer_attributes_.width, mixer_attributes_.height}};
Saurabh Shah8c9c00c2017-04-17 16:52:49 -0700956 DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_[index].x_pixels,
957 display_attributes_[index].y_pixels}};
Saurabh Shahe9f55d72017-03-03 15:14:13 -0800958
959 for (uint32_t i = 0; i < hw_layer_info.left_frame_roi.size(); i++) {
960 auto &roi = hw_layer_info.left_frame_roi.at(i);
961 // TODO(user): In multi PU, stitch ROIs vertically adjacent and upate plane destination
962 crtc_rects[i].left = UINT32(roi.left);
963 crtc_rects[i].right = UINT32(roi.right);
964 crtc_rects[i].top = UINT32(roi.top);
965 crtc_rects[i].bottom = UINT32(roi.bottom);
966 // TODO(user): In Dest scaler + PU, populate from HWDestScaleInfo->panel_roi
Namit Solanki24921ab2017-05-23 20:16:25 +0530967 // TODO(user): panel_roi need to be made as a vector in HWLayersInfo and
968 // needs to be removed from HWDestScaleInfo.
Saurabh Shahe9f55d72017-03-03 15:14:13 -0800969 conn_rects[i].left = UINT32(roi.left);
970 conn_rects[i].right = UINT32(roi.right);
971 conn_rects[i].top = UINT32(roi.top);
972 conn_rects[i].bottom = UINT32(roi.bottom);
973 }
974
975 uint32_t num_rects = std::max(1u, static_cast<uint32_t>(hw_layer_info.left_frame_roi.size()));
976 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id,
977 num_rects, crtc_rects);
978 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id,
979 num_rects, conn_rects);
980 }
981
Saurabh Shah66c941b2016-07-06 17:34:05 -0700982 for (uint32_t i = 0; i < hw_layer_count; i++) {
983 Layer &layer = hw_layer_info.hw_layers.at(i);
Saurabh Shaha228f122017-01-23 15:55:25 -0800984 LayerBuffer *input_buffer = &layer.input_buffer;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700985 HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
986 HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
Saurabh Shaha228f122017-01-23 15:55:25 -0800987 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
Saurabh Shah66c941b2016-07-06 17:34:05 -0700988
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -0700989 if (hw_layers->config[i].use_solidfill_stage) {
Gopikrishnaiah Anandancc123062017-07-31 17:21:03 -0700990 hw_layers->config[i].hw_solidfill_stage.solid_fill_info = layer.solid_fill_info;
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -0700991 AddSolidfillStage(hw_layers->config[i].hw_solidfill_stage, layer.plane_alpha);
992 continue;
993 }
994
Saurabh Shah66c941b2016-07-06 17:34:05 -0700995 for (uint32_t count = 0; count < 2; count++) {
996 HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
Saurabh Shaha228f122017-01-23 15:55:25 -0800997 HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
998
Rohit Kulkarni8622e362017-01-30 18:14:10 -0800999 if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) {
Saurabh Shaha228f122017-01-23 15:55:25 -08001000 input_buffer = &hw_rotator_session->output_buffer;
Saurabh Shaha228f122017-01-23 15:55:25 -08001001 }
1002
Sushil Chauhanabc5b272018-06-20 16:18:13 -07001003 uint32_t fb_id = registry_.GetFbId(&layer, input_buffer->handle_id);
1004
Saurabh Shahf84c4122017-04-07 10:34:40 -07001005 if (pipe_info->valid && fb_id) {
Saurabh Shah66c941b2016-07-06 17:34:05 -07001006 uint32_t pipe_id = pipe_info->pipe_id;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001007 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha);
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -07001008
Saurabh Shah66c941b2016-07-06 17:34:05 -07001009 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ZORDER, pipe_id, pipe_info->z_order);
1010 DRMBlendType blending = {};
1011 SetBlending(layer.blending, &blending);
1012 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_BLEND_TYPE, pipe_id, blending);
1013 DRMRect src = {};
1014 SetRect(pipe_info->src_roi, &src);
1015 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_RECT, pipe_id, src);
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001016 DRMRect rot_dst = {0, 0, 0, 0};
1017 if (hw_rotator_session->mode == kRotatorInline && hw_rotate_info->valid) {
1018 SetRect(hw_rotate_info->dst_roi, &rot_dst);
1019 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION_DST_RECT, pipe_id, rot_dst);
Rohit Kulkarni2d7151c2017-12-14 22:17:49 -08001020 if (hw_rotator_session->output_buffer.planes[0].fd >= 0) {
Sushil Chauhanabc5b272018-06-20 16:18:13 -07001021 uint32_t rot_fb_id = registry_.GetFbId(&layer,
1022 hw_rotator_session->output_buffer.handle_id);
Rohit Kulkarni2d7151c2017-12-14 22:17:49 -08001023 if (rot_fb_id) {
1024 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROT_FB_ID, pipe_id, rot_fb_id);
1025 }
1026 }
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001027 }
Saurabh Shah66c941b2016-07-06 17:34:05 -07001028 DRMRect dst = {};
1029 SetRect(pipe_info->dst_roi, &dst);
1030 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst);
Namit Solanki6d0d8062017-11-30 17:29:48 +05301031 DRMRect excl = {};
1032 SetRect(pipe_info->excl_rect, &excl);
1033 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_EXCL_RECT, pipe_id, excl);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001034 uint32_t rot_bit_mask = 0;
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001035 SetRotation(layer.transform, hw_rotator_session->mode, &rot_bit_mask);
Saurabh Shaha228f122017-01-23 15:55:25 -08001036 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001037 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_H_DECIMATION, pipe_id,
1038 pipe_info->horizontal_decimation);
1039 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_V_DECIMATION, pipe_id,
1040 pipe_info->vertical_decimation);
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001041
1042 DRMSecureMode fb_secure_mode;
1043 DRMSecurityLevel security_level;
1044 SetSecureConfig(layer.input_buffer, &fb_secure_mode, &security_level);
1045 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_SECURE_MODE, pipe_id, fb_secure_mode);
1046 if (security_level > crtc_security_level) {
1047 crtc_security_level = security_level;
1048 }
1049
Prabhanjan Kandula585aa652017-01-26 18:39:11 -08001050 uint32_t config = 0;
Ramkumar Radhakrishnan0751f872017-11-09 15:56:10 -08001051 SetSrcConfig(layer.input_buffer, hw_rotator_session->mode, &config);
Prabhanjan Kandula585aa652017-01-26 18:39:11 -08001052 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);;
Saurabh Shahf84c4122017-04-07 10:34:40 -07001053 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001054 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id);
Saurabh Shaha228f122017-01-23 15:55:25 -08001055 if (!validate && input_buffer->acquire_fence_fd >= 0) {
Saurabh Shah66c941b2016-07-06 17:34:05 -07001056 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id,
Saurabh Shaha228f122017-01-23 15:55:25 -08001057 input_buffer->acquire_fence_fd);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001058 }
Saurabh Shah0ffee302016-11-22 10:42:11 -08001059 if (hw_scale_) {
1060 SDEScaler scaler_output = {};
Namit Solanki24921ab2017-05-23 20:16:25 +05301061 hw_scale_->SetScaler(pipe_info->scale_data, &scaler_output);
Saurabh Shah0ffee302016-11-22 10:42:11 -08001062 // TODO(user): Remove qseed3 and add version check, then send appropriate scaler object
1063 if (hw_resource_.has_qseed3) {
1064 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id,
1065 reinterpret_cast<uint64_t>(&scaler_output.scaler_v2));
1066 }
1067 }
Ping Li8d6dd622017-07-03 12:05:15 -07001068
1069 DRMCscType csc_type = DRMCscType::kCscTypeMax;
1070 SelectCscType(layer.input_buffer, &csc_type);
1071 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CSC_CONFIG, pipe_id, &csc_type);
Ramkumar Radhakrishnan07254302017-11-13 16:18:22 -08001072
1073 DRMMultiRectMode multirect_mode;
1074 SetMultiRectMode(pipe_info->flags, &multirect_mode);
1075 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_MULTIRECT_MODE, pipe_id, multirect_mode);
Arun Kumar K.Rc033f942018-01-05 12:25:47 +05301076
1077 SetSsppTonemapFeatures(pipe_info);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001078 }
1079 }
Saurabh Shah66c941b2016-07-06 17:34:05 -07001080 }
Prabhanjan Kandulaf890c252017-07-09 18:22:02 -07001081
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001082 SetSolidfillStages();
Varun Arorabbb062e2018-07-03 22:33:59 -07001083 SetQOSData(qos_data);
Sushil Chauhanedfdfbb2017-07-31 15:00:24 -07001084 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level);
Xu Yangda642222018-06-12 10:32:33 +08001085 drm_atomic_intf_->Perform(DRMOps::DPPS_COMMIT_FEATURE, 0 /* argument is not used */);
Prabhanjan Kandulaf890c252017-07-09 18:22:02 -07001086
Varun Aroraef987292018-04-16 17:16:42 -07001087 if (!validate) {
1088 drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_);
1089 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_GET_RETIRE_FENCE, token_.conn_id, &retire_fence_);
1090 }
1091
Ramkumar Radhakrishnanb7910442017-12-11 13:32:47 -08001092 DLOGI_IF(kTagDriverConfig, "%s::%s System Clock=%d Hz, Core: AB=%llu Bps, IB=%llu Bps, " \
1093 "LLCC: AB=%llu Bps, IB=%llu Bps, DRAM AB=%llu Bps, IB=%llu Bps, "\
1094 "Rot: Bw=%llu Bps, Clock=%d Hz", validate ? "Validate" : "Commit", device_name_,
Prabhanjan Kandulaf890c252017-07-09 18:22:02 -07001095 qos_data.clock_hz, qos_data.core_ab_bps, qos_data.core_ib_bps, qos_data.llcc_ab_bps,
1096 qos_data.llcc_ib_bps, qos_data.dram_ab_bps, qos_data.dram_ib_bps,
Ramkumar Radhakrishnanb7910442017-12-11 13:32:47 -08001097 qos_data.rot_prefill_bw_bps, qos_data.rot_clock_hz);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301098
1099 // Set refresh rate
1100 if (vrefresh_) {
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301101 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -07001102 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1103 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1104 (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
1105 current_mode = connector_info_.modes[mode_index].mode;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301106 break;
1107 }
1108 }
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301109 }
Saurabh Shah7e16c932017-11-03 17:55:36 -07001110
1111 if (first_cycle_) {
Mathew Joseph Karimpanalb7f20c62018-10-09 12:17:20 +05301112 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_TOPOLOGY_CONTROL, token_.conn_id,
1113 topology_control_);
Varun Arorabbb062e2018-07-03 22:33:59 -07001114 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
Saurabh Shah7e16c932017-11-03 17:55:36 -07001115 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
1116 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
1117 }
1118
Sushil Chauhan93c892c2018-05-11 17:15:37 -07001119 // Set CRTC mode, only if display config changes
1120 if (vrefresh_ || first_cycle_ || update_mode_) {
1121 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
1122 }
1123
Anjaneya Prasad Musunurie8c67f22017-07-01 16:16:13 +05301124 if (!validate && (hw_layer_info.set_idle_time_ms >= 0)) {
1125 DLOGI_IF(kTagDriverConfig, "Setting idle timeout to = %d ms",
1126 hw_layer_info.set_idle_time_ms);
1127 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_IDLE_TIMEOUT, token_.crtc_id,
1128 hw_layer_info.set_idle_time_ms);
1129 }
Saurabh Shahf3635952017-10-16 17:08:18 -07001130
1131 if (hw_panel_info_.mode == kModeCommand) {
1132 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_AUTOREFRESH, token_.conn_id, autorefresh_);
1133 }
Sushil Chauhan8f514a52018-02-27 17:35:44 -08001134
1135 sde_drm::DRMQsyncMode mode = hw_layers->hw_avr_info.enable ? sde_drm::DRMQsyncMode::CONTINUOUS :
1136 sde_drm::DRMQsyncMode::NONE;
1137 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_QSYNC_MODE, token_.conn_id, mode);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001138}
1139
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001140void HWDeviceDRM::AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha) {
1141 sde_drm::DRMSolidfillStage solidfill;
1142 solidfill.bounding_rect.left = UINT32(sf.roi.left);
1143 solidfill.bounding_rect.top = UINT32(sf.roi.top);
1144 solidfill.bounding_rect.right = UINT32(sf.roi.right);
1145 solidfill.bounding_rect.bottom = UINT32(sf.roi.bottom);
1146 solidfill.is_exclusion_rect = sf.is_exclusion_rect;
1147 solidfill.plane_alpha = plane_alpha;
1148 solidfill.z_order = sf.z_order;
Gopikrishnaiah Anandancc123062017-07-31 17:21:03 -07001149 if (!sf.solid_fill_info.bit_depth) {
1150 solidfill.color_bit_depth = 8;
1151 solidfill.alpha = (0xff000000 & sf.color) >> 24;
1152 solidfill.red = (0xff0000 & sf.color) >> 16;
1153 solidfill.green = (0xff00 & sf.color) >> 8;
1154 solidfill.blue = 0xff & sf.color;
1155 } else {
1156 solidfill.color_bit_depth = sf.solid_fill_info.bit_depth;
1157 solidfill.alpha = sf.solid_fill_info.alpha;
1158 solidfill.red = sf.solid_fill_info.red;
1159 solidfill.green = sf.solid_fill_info.green;
1160 solidfill.blue = sf.solid_fill_info.blue;
1161 }
Prabhanjan Kanduladbc8aed2017-03-24 14:43:16 -07001162 solid_fills_.push_back(solidfill);
1163 DLOGI_IF(kTagDriverConfig, "Add a solidfill stage at z_order:%d argb_color:%x plane_alpha:%x",
1164 solidfill.z_order, solidfill.color, solidfill.plane_alpha);
1165}
1166
1167void HWDeviceDRM::SetSolidfillStages() {
1168 if (hw_resource_.num_solidfill_stages) {
1169 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SOLIDFILL_STAGES, token_.crtc_id,
1170 reinterpret_cast<uint64_t> (&solid_fills_));
1171 }
1172}
1173
Tharaga Balachandran2fd24262018-11-09 16:03:41 -05001174void HWDeviceDRM::ClearSolidfillStages() {
1175 solid_fills_.clear();
1176 SetSolidfillStages();
1177}
1178
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001179DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
1180 DTRACE_SCOPED();
Saurabh Shahf84c4122017-04-07 10:34:40 -07001181
Saurabh Shah4d4f4002017-12-26 12:42:59 -08001182 DisplayError err = kErrorNone;
1183 registry_.Register(hw_layers);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001184 SetupAtomic(hw_layers, true /* validate */);
1185
1186 int ret = drm_atomic_intf_->Validate();
1187 if (ret) {
Ramkumar Radhakrishnan7e971e02017-08-17 14:19:15 +05301188 DLOGE("failed with error %d for %s", ret, device_name_);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301189 vrefresh_ = 0;
Saurabh Shah4d4f4002017-12-26 12:42:59 -08001190 err = kErrorHardware;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001191 }
1192
Saurabh Shah4d4f4002017-12-26 12:42:59 -08001193 return err;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001194}
1195
1196DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {
1197 DTRACE_SCOPED();
Saurabh Shahf84c4122017-04-07 10:34:40 -07001198
1199 DisplayError err = kErrorNone;
Saurabh Shah4d4f4002017-12-26 12:42:59 -08001200 registry_.Register(hw_layers);
Saurabh Shahf84c4122017-04-07 10:34:40 -07001201
Saurabh Shah66c941b2016-07-06 17:34:05 -07001202 if (default_mode_) {
Saurabh Shahf84c4122017-04-07 10:34:40 -07001203 err = DefaultCommit(hw_layers);
1204 } else {
1205 err = AtomicCommit(hw_layers);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001206 }
1207
Saurabh Shahf84c4122017-04-07 10:34:40 -07001208 return err;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001209}
1210
1211DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) {
1212 DTRACE_SCOPED();
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001213
1214 HWLayersInfo &hw_layer_info = hw_layers->info;
1215 LayerStack *stack = hw_layer_info.stack;
1216
1217 stack->retire_fence_fd = -1;
1218 for (Layer &layer : hw_layer_info.hw_layers) {
1219 layer.input_buffer.release_fence_fd = -1;
1220 }
1221
1222 DRMMaster *master = nullptr;
1223 int ret = DRMMaster::GetInstance(&master);
1224 if (ret < 0) {
1225 DLOGE("Failed to acquire DRMMaster instance");
1226 return kErrorResources;
1227 }
1228
1229 DRMResMgr *res_mgr = nullptr;
1230 ret = DRMResMgr::GetInstance(&res_mgr);
1231 if (ret < 0) {
1232 DLOGE("Failed to acquire DRMResMgr instance");
1233 return kErrorResources;
1234 }
1235
1236 int dev_fd = -1;
1237 master->GetHandle(&dev_fd);
1238
1239 uint32_t connector_id = 0;
1240 res_mgr->GetConnectorId(&connector_id);
1241
1242 uint32_t crtc_id = 0;
1243 res_mgr->GetCrtcId(&crtc_id);
1244
1245 drmModeModeInfo mode;
1246 res_mgr->GetMode(&mode);
1247
Sushil Chauhanabc5b272018-06-20 16:18:13 -07001248 uint64_t handle_id = hw_layer_info.hw_layers.at(0).input_buffer.handle_id;
1249 uint32_t fb_id = registry_.GetFbId(&hw_layer_info.hw_layers.at(0), handle_id);
Saurabh Shahf84c4122017-04-07 10:34:40 -07001250 ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id,
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001251 1 /* num_connectors */, &mode);
1252 if (ret < 0) {
1253 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 -07001254 fb_id, crtc_id, connector_id, strerror(errno));
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001255 return kErrorHardware;
1256 }
1257
1258 return kErrorNone;
1259}
1260
Saurabh Shah66c941b2016-07-06 17:34:05 -07001261DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) {
1262 DTRACE_SCOPED();
1263 SetupAtomic(hw_layers, false /* validate */);
1264
Ramkumar Radhakrishnanf985d482018-07-23 18:10:41 -07001265 int ret = drm_atomic_intf_->Commit(synchronous_commit_, false /* retain_planes*/);
Varun Aroraf182bfa2018-08-14 10:49:08 -07001266 int release_fence = INT(release_fence_);
1267 int retire_fence = INT(retire_fence_);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001268 if (ret) {
Mahesh Aia1d2ceda2017-03-24 11:07:31 -07001269 DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301270 vrefresh_ = 0;
Varun Aroraf182bfa2018-08-14 10:49:08 -07001271 CloseFd(&release_fence);
1272 CloseFd(&retire_fence);
1273 release_fence_ = -1;
1274 retire_fence_ = -1;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001275 return kErrorHardware;
1276 }
1277
Varun Arora006e3a12018-04-20 17:09:35 -07001278 DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", release_fence);
1279 DLOGD_IF(kTagDriverConfig, "RETIRE fence created: fd:%d", retire_fence);
Saurabh Shah66c941b2016-07-06 17:34:05 -07001280
1281 HWLayersInfo &hw_layer_info = hw_layers->info;
1282 LayerStack *stack = hw_layer_info.stack;
1283 stack->retire_fence_fd = retire_fence;
1284
Saurabh Shaha228f122017-01-23 15:55:25 -08001285 for (uint32_t i = 0; i < hw_layer_info.hw_layers.size(); i++) {
1286 Layer &layer = hw_layer_info.hw_layers.at(i);
1287 HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001288 if (hw_rotator_session->mode == kRotatorOffline) {
Saurabh Shaha228f122017-01-23 15:55:25 -08001289 hw_rotator_session->output_buffer.release_fence_fd = Sys::dup_(release_fence);
1290 } else {
1291 layer.input_buffer.release_fence_fd = Sys::dup_(release_fence);
1292 }
Saurabh Shah66c941b2016-07-06 17:34:05 -07001293 }
1294
1295 hw_layer_info.sync_handle = release_fence;
1296
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301297 if (vrefresh_) {
1298 // Update current mode index if refresh rate is changed
Saurabh Shah7e16c932017-11-03 17:55:36 -07001299 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301300 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -07001301 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1302 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1303 (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) {
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301304 current_mode_index_ = mode_index;
1305 break;
1306 }
1307 }
1308 vrefresh_ = 0;
1309 }
1310
Saurabh Shah7e16c932017-11-03 17:55:36 -07001311 first_cycle_ = false;
Sushil Chauhan93c892c2018-05-11 17:15:37 -07001312 update_mode_ = false;
Ramkumar Radhakrishnanee0aab22017-10-16 16:11:18 -07001313
Saurabh Shah66c941b2016-07-06 17:34:05 -07001314 return kErrorNone;
1315}
1316
Pullakavi Srinivas0a1dba62018-07-02 15:49:11 +05301317DisplayError HWDeviceDRM::Flush(HWLayers *hw_layers) {
Tharaga Balachandran2fd24262018-11-09 16:03:41 -05001318 ClearSolidfillStages();
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -07001319 int ret = NullCommit(secure_display_active_ /* synchronous */, false /* retain_planes*/);
Saurabh Shahb5953152017-04-12 14:02:50 -07001320 if (ret) {
1321 DLOGE("failed with error %d", ret);
1322 return kErrorHardware;
1323 }
1324
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001325 return kErrorNone;
1326}
1327
Saurabh Shah66c941b2016-07-06 17:34:05 -07001328void HWDeviceDRM::SetBlending(const LayerBlending &source, DRMBlendType *target) {
1329 switch (source) {
1330 case kBlendingPremultiplied:
1331 *target = DRMBlendType::PREMULTIPLIED;
1332 break;
1333 case kBlendingOpaque:
1334 *target = DRMBlendType::OPAQUE;
1335 break;
1336 case kBlendingCoverage:
1337 *target = DRMBlendType::COVERAGE;
1338 break;
1339 default:
1340 *target = DRMBlendType::UNDEFINED;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001341 }
1342}
1343
Ramkumar Radhakrishnan0751f872017-11-09 15:56:10 -08001344void HWDeviceDRM::SetSrcConfig(const LayerBuffer &input_buffer, const HWRotatorMode &mode,
1345 uint32_t *config) {
1346 // In offline rotation case, rotator will handle deinterlacing.
1347 if (mode != kRotatorOffline) {
1348 if (input_buffer.flags.interlace) {
1349 *config |= (0x01 << UINT32(DRMSrcConfig::DEINTERLACE));
1350 }
Prabhanjan Kandula585aa652017-01-26 18:39:11 -08001351 }
1352}
1353
Ping Li8d6dd622017-07-03 12:05:15 -07001354void HWDeviceDRM::SelectCscType(const LayerBuffer &input_buffer, DRMCscType *type) {
1355 if (type == NULL) {
1356 return;
1357 }
1358
1359 *type = DRMCscType::kCscTypeMax;
1360 if (input_buffer.format < kFormatYCbCr420Planar) {
1361 return;
1362 }
1363
1364 switch (input_buffer.color_metadata.colorPrimaries) {
1365 case ColorPrimaries_BT601_6_525:
1366 case ColorPrimaries_BT601_6_625:
1367 *type = ((input_buffer.color_metadata.range == Range_Full) ?
1368 DRMCscType::kCscYuv2Rgb601FR : DRMCscType::kCscYuv2Rgb601L);
1369 break;
1370 case ColorPrimaries_BT709_5:
1371 *type = DRMCscType::kCscYuv2Rgb709L;
1372 break;
1373 case ColorPrimaries_BT2020:
1374 *type = ((input_buffer.color_metadata.range == Range_Full) ?
1375 DRMCscType::kCscYuv2Rgb2020FR : DRMCscType::kCscYuv2Rgb2020L);
1376 break;
1377 default:
1378 break;
1379 }
1380}
1381
Saurabh Shah66c941b2016-07-06 17:34:05 -07001382void HWDeviceDRM::SetRect(const LayerRect &source, DRMRect *target) {
1383 target->left = UINT32(source.left);
1384 target->top = UINT32(source.top);
1385 target->right = UINT32(source.right);
1386 target->bottom = UINT32(source.bottom);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001387}
1388
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001389void HWDeviceDRM::SetRotation(LayerTransform transform, const HWRotatorMode &mode,
1390 uint32_t* rot_bit_mask) {
1391 // In offline rotation case, rotator will handle flips set via offline rotator interface.
1392 if (mode == kRotatorOffline) {
1393 *rot_bit_mask = 0;
1394 return;
1395 }
1396
1397 // In no rotation case or inline rotation case, plane will handle flips
1398 // In DRM framework rotation is applied in counter-clockwise direction.
Rohit Kulkarnia93babb2017-08-09 17:06:06 -07001399 if (mode == kRotatorInline && transform.rotation == 90) {
Rohit Kulkarni8622e362017-01-30 18:14:10 -08001400 // a) rotate 90 clockwise = rotate 270 counter-clockwise in DRM
1401 // rotate 270 is translated as hflip + vflip + rotate90
1402 // b) rotate 270 clockwise = rotate 90 counter-clockwise in DRM
1403 // c) hflip + rotate 90 clockwise = vflip + rotate 90 counter-clockwise in DRM
1404 // d) vflip + rotate 90 clockwise = hflip + rotate 90 counter-clockwise in DRM
1405 *rot_bit_mask = UINT32(DRMRotation::ROT_90);
1406 transform.flip_horizontal = !transform.flip_horizontal;
1407 transform.flip_vertical = !transform.flip_vertical;
1408 }
1409
1410 if (transform.flip_horizontal) {
1411 *rot_bit_mask |= UINT32(DRMRotation::FLIP_H);
1412 }
1413
1414 if (transform.flip_vertical) {
1415 *rot_bit_mask |= UINT32(DRMRotation::FLIP_V);
1416 }
1417}
1418
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001419bool HWDeviceDRM::EnableHotPlugDetection(int enable) {
1420 return true;
1421}
1422
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001423DisplayError HWDeviceDRM::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
1424 DTRACE_SCOPED();
1425 return kErrorNone;
1426}
1427
1428DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
Ping Li281f48d2017-01-16 12:45:40 -08001429 struct DRMPPFeatureInfo info = {};
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301430
1431 if (!hw_color_mgr_)
1432 return kErrorNotSupported;
1433
Ping Li281f48d2017-01-16 12:45:40 -08001434 for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301435 std::vector<DRMPPFeatureID> drm_id = {};
Ping Li281f48d2017-01-16 12:45:40 -08001436 memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301437 hw_color_mgr_->ToDrmFeatureId(kDSPP, i, &drm_id);
1438 if (drm_id.empty())
Ping Li281f48d2017-01-16 12:45:40 -08001439 continue;
Saurabh Shah16329182018-02-23 12:26:20 -08001440
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301441 info.id = drm_id.at(0);
1442
Saurabh Shah16329182018-02-23 12:26:20 -08001443 drm_mgr_intf_->GetCrtcPPInfo(token_.crtc_id, &info);
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301444 vers->version[i] = hw_color_mgr_->GetFeatureVersion(info);
Ping Li281f48d2017-01-16 12:45:40 -08001445 }
1446 return kErrorNone;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001447}
1448
1449DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) {
Ping Li281f48d2017-01-16 12:45:40 -08001450 int ret = 0;
1451 PPFeatureInfo *feature = NULL;
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301452
1453 if (!hw_color_mgr_)
1454 return kErrorNotSupported;
Ping Li281f48d2017-01-16 12:45:40 -08001455
1456 while (true) {
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301457 std::vector<DRMPPFeatureID> drm_id = {};
1458 DRMPPFeatureInfo kernel_params = {};
1459 bool crtc_feature = true;
1460
Ping Li281f48d2017-01-16 12:45:40 -08001461 ret = feature_list->RetrieveNextFeature(&feature);
1462 if (ret)
1463 break;
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301464
1465 hw_color_mgr_->ToDrmFeatureId(kDSPP, feature->feature_id_, &drm_id);
1466 if (drm_id.empty())
1467 continue;
1468
1469 kernel_params.id = drm_id.at(0);
Gopikrishnaiah Anandan739faf92017-07-21 12:32:00 -07001470 drm_mgr_intf_->GetCrtcPPInfo(token_.crtc_id, &kernel_params);
1471 if (kernel_params.version == std::numeric_limits<uint32_t>::max())
Ping Li13c5ea12018-05-14 13:31:17 -07001472 crtc_feature = false;
Ping Li281f48d2017-01-16 12:45:40 -08001473 if (feature) {
1474 DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301475 for (DRMPPFeatureID id : drm_id) {
Ping Li13c5ea12018-05-14 13:31:17 -07001476 if (id >= kPPFeaturesMax) {
1477 DLOGE("Invalid feature id %d", id);
1478 continue;
1479 }
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301480 kernel_params.id = id;
1481 ret = hw_color_mgr_->GetDrmFeature(feature, &kernel_params);
1482 if (!ret && crtc_feature)
1483 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC,
1484 token_.crtc_id, &kernel_params);
1485 else if (!ret && !crtc_feature)
1486 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POST_PROC,
1487 token_.conn_id, &kernel_params);
Rajesh Yadavd30b0cc2017-09-22 00:26:54 +05301488
Rajesh Yadavc4f67b82017-11-15 20:37:13 +05301489 hw_color_mgr_->FreeDrmFeatureData(&kernel_params);
Rajesh Yadavd30b0cc2017-09-22 00:26:54 +05301490 }
Ping Li281f48d2017-01-16 12:45:40 -08001491 }
1492 }
1493
1494 // Once all features were consumed, then destroy all feature instance from feature_list,
1495 feature_list->Reset();
1496
1497 return kErrorNone;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001498}
1499
1500DisplayError HWDeviceDRM::SetVSyncState(bool enable) {
Saurabh Shah7171af52017-05-02 17:03:26 -07001501 return kErrorNotSupported;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001502}
1503
Anjaneya Prasad Musunurie8c67f22017-07-01 16:16:13 +05301504void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {
1505 // TODO(user): This function can be removed after fb is deprecated
1506}
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001507
1508DisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) {
1509 return kErrorNotSupported;
1510}
1511
1512DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) {
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301513 // Check if requested refresh rate is valid
Saurabh Shah7e16c932017-11-03 17:55:36 -07001514 drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301515 for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
Saurabh Shah7e16c932017-11-03 17:55:36 -07001516 if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) &&
1517 (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) &&
1518 (refresh_rate == connector_info_.modes[mode_index].mode.vrefresh)) {
Anjaneya Prasad Musunuricbefdc42017-06-13 16:10:19 +05301519 vrefresh_ = refresh_rate;
1520 DLOGV_IF(kTagDriverConfig, "Set refresh rate to %d", refresh_rate);
1521 return kErrorNone;
1522 }
1523 }
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001524 return kErrorNotSupported;
1525}
1526
1527DisplayError HWDeviceDRM::SetPanelBrightness(int level) {
Saurabh Shah8b021cf2017-03-14 12:16:43 -07001528 DisplayError err = kErrorNone;
1529 char buffer[kMaxSysfsCommandLength] = {0};
1530
1531 DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level);
1532 int fd = Sys::open_(kBrightnessNode, O_RDWR);
1533 if (fd < 0) {
1534 DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode,
1535 strerror(errno));
1536 return kErrorFileDescriptor;
1537 }
1538
1539 int32_t bytes = snprintf(buffer, kMaxSysfsCommandLength, "%d\n", level);
1540 ssize_t ret = Sys::pwrite_(fd, buffer, static_cast<size_t>(bytes), 0);
1541 if (ret <= 0) {
1542 DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode,
1543 strerror(errno));
1544 err = kErrorHardware;
1545 }
1546
1547 Sys::close_(fd);
1548
1549 return err;
1550}
1551
1552DisplayError HWDeviceDRM::GetPanelBrightness(int *level) {
1553 DisplayError err = kErrorNone;
1554 char brightness[kMaxStringLength] = {0};
1555
1556 if (!level) {
1557 DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer.");
1558 return kErrorParameters;
1559 }
1560
1561 int fd = Sys::open_(kBrightnessNode, O_RDWR);
1562 if (fd < 0) {
1563 DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode,
1564 strerror(errno));
1565 return kErrorFileDescriptor;
1566 }
1567
1568 if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) {
1569 *level = atoi(brightness);
1570 DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level);
1571 } else {
1572 DLOGV_IF(kTagDriverConfig, "Failed to read panel brightness");
1573 err = kErrorHardware;
1574 }
1575
1576 Sys::close_(fd);
1577
1578 return err;
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001579}
1580
1581DisplayError HWDeviceDRM::GetHWScanInfo(HWScanInfo *scan_info) {
1582 return kErrorNotSupported;
1583}
1584
1585DisplayError HWDeviceDRM::GetVideoFormat(uint32_t config_index, uint32_t *video_format) {
1586 return kErrorNotSupported;
1587}
1588
1589DisplayError HWDeviceDRM::GetMaxCEAFormat(uint32_t *max_cea_format) {
1590 return kErrorNotSupported;
1591}
1592
1593DisplayError HWDeviceDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1594 return kErrorNotSupported;
1595}
1596
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001597DisplayError HWDeviceDRM::SetS3DMode(HWS3DMode s3d_mode) {
1598 return kErrorNotSupported;
1599}
1600
1601DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
Saurabh Shah0ffee302016-11-22 10:42:11 -08001602 sde_drm::DRMScalerLUTInfo drm_lut_info = {};
1603 drm_lut_info.cir_lut = lut_info->cir_lut;
1604 drm_lut_info.dir_lut = lut_info->dir_lut;
1605 drm_lut_info.sep_lut = lut_info->sep_lut;
1606 drm_lut_info.cir_lut_size = lut_info->cir_lut_size;
1607 drm_lut_info.dir_lut_size = lut_info->dir_lut_size;
1608 drm_lut_info.sep_lut_size = lut_info->sep_lut_size;
1609 drm_mgr_intf_->SetScalerLUT(drm_lut_info);
1610
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001611 return kErrorNone;
1612}
1613
Varun Arorabaa16472018-08-16 16:19:59 -07001614DisplayError HWDeviceDRM::UnsetScaleLutConfig() {
1615 drm_mgr_intf_->UnsetScalerLUT();
1616
1617 return kErrorNone;
1618}
1619
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001620DisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001621 if (IsResolutionSwitchEnabled()) {
1622 return kErrorNotSupported;
1623 }
1624
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001625 if (!hw_resource_.hw_dest_scalar_info.count) {
1626 return kErrorNotSupported;
1627 }
1628
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001629 uint32_t index = current_mode_index_;
1630
1631 if (mixer_attributes.width > display_attributes_[index].x_pixels ||
1632 mixer_attributes.height > display_attributes_[index].y_pixels) {
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001633 DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001634 mixer_attributes.width, mixer_attributes.height, display_attributes_[index].x_pixels,
1635 display_attributes_[index].y_pixels);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001636 return kErrorNotSupported;
1637 }
1638
1639 uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001640 if (display_attributes_[index].is_device_split) {
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001641 max_input_width *= 2;
1642 }
1643
1644 if (mixer_attributes.width > max_input_width) {
1645 DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
1646 max_input_width);
1647 return kErrorNotSupported;
1648 }
1649
1650 float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
1651 float display_aspect_ratio =
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001652 FLOAT(display_attributes_[index].x_pixels) / FLOAT(display_attributes_[index].y_pixels);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001653
1654 if (display_aspect_ratio != mixer_aspect_ratio) {
1655 DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001656 mixer_attributes.height, display_attributes_[index].x_pixels,
1657 display_attributes_[index].y_pixels);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001658 return kErrorNotSupported;
1659 }
1660
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001661 float scale_x = FLOAT(display_attributes_[index].x_pixels) / FLOAT(mixer_attributes.width);
1662 float scale_y = FLOAT(display_attributes_[index].y_pixels) / FLOAT(mixer_attributes.height);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001663 float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
1664 if (scale_x > max_scale_up || scale_y > max_scale_up) {
Saurabh Shah66c941b2016-07-06 17:34:05 -07001665 DLOGW(
1666 "Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f "
1667 "max_scale_up %f",
1668 scale_x, scale_y, max_scale_up);
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001669 return kErrorNotSupported;
1670 }
1671
1672 float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
1673
1674 mixer_attributes_ = mixer_attributes;
1675 mixer_attributes_.split_left = mixer_attributes_.width;
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001676 if (display_attributes_[index].is_device_split) {
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001677 mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
1678 }
1679
1680 return kErrorNone;
1681}
1682
1683DisplayError HWDeviceDRM::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
1684 if (!mixer_attributes) {
1685 return kErrorParameters;
1686 }
1687
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001688 *mixer_attributes = mixer_attributes_;
1689
1690 return kErrorNone;
1691}
1692
Varun Arora7c8ee542018-05-01 20:58:16 -07001693DisplayError HWDeviceDRM::DumpDebugData() {
Varun Aroraeaefa472018-05-21 13:20:20 -07001694 string dir_path = "/data/vendor/display/hw_recovery/";
Varun Arora7c8ee542018-05-01 20:58:16 -07001695 string device_str = device_name_;
Varun Arora7c8ee542018-05-01 20:58:16 -07001696
Varun Aroraeaefa472018-05-21 13:20:20 -07001697 // Attempt to make hw_recovery dir, it may exist
1698 if (mkdir(dir_path.c_str(), 0777) != 0 && errno != EEXIST) {
1699 DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path.c_str(), errno,
1700 strerror(errno));
1701 return kErrorPermission;
1702 }
1703 // If it does exist, ensure permissions are fine
1704 if (errno == EEXIST && chmod(dir_path.c_str(), 0777) != 0) {
1705 DLOGW("Failed to change permissions on %s directory", dir_path.c_str());
1706 return kErrorPermission;
1707 }
1708
1709 string filename = dir_path+device_str+"_HWR_"+to_string(debug_dump_count_);
1710 ofstream dst(filename);
Varun Arora7c8ee542018-05-01 20:58:16 -07001711 ifstream src;
Varun Aroraeaefa472018-05-21 13:20:20 -07001712 debug_dump_count_++;
Varun Arora7c8ee542018-05-01 20:58:16 -07001713
1714 src.open("/sys/kernel/debug/dri/0/debug/dump");
1715 dst << "---- Event Logs ----" << std::endl;
1716 dst << src.rdbuf() << std::endl;
1717 src.close();
1718
1719 src.open("/sys/kernel/debug/dri/0/debug/recovery_reg");
1720 dst << "---- All Registers ----" << std::endl;
1721 dst << src.rdbuf() << std::endl;
1722 src.close();
1723
1724 src.open("/sys/kernel/debug/dri/0/debug/recovery_dbgbus");
1725 dst << "---- Debug Bus ----" << std::endl;
1726 dst << src.rdbuf() << std::endl;
1727 src.close();
1728
1729 src.open("/sys/kernel/debug/dri/0/debug/recovery_vbif_dbgbus");
1730 dst << "---- VBIF Debug Bus ----" << std::endl;
1731 dst << src.rdbuf() << std::endl;
1732 src.close();
1733
1734 dst.close();
Varun Aroraeaefa472018-05-21 13:20:20 -07001735
1736 DLOGI("Wrote hw_recovery file %s", filename.c_str());
Varun Arora7c8ee542018-05-01 20:58:16 -07001737
1738 return kErrorNone;
1739}
1740
Anjaneya Prasad Musunurie250e672017-05-22 14:16:20 +05301741void HWDeviceDRM::GetDRMDisplayToken(sde_drm::DRMDisplayToken *token) const {
Saurabh Shahf8226712018-02-05 15:51:53 -08001742 *token = token_;
Anjaneya Prasad Musunurie250e672017-05-22 14:16:20 +05301743}
1744
Saurabh Shah66c941b2016-07-06 17:34:05 -07001745void HWDeviceDRM::UpdateMixerAttributes() {
Saurabh Shah8c9c00c2017-04-17 16:52:49 -07001746 uint32_t index = current_mode_index_;
1747
1748 mixer_attributes_.width = display_attributes_[index].x_pixels;
1749 mixer_attributes_.height = display_attributes_[index].y_pixels;
1750 mixer_attributes_.split_left = display_attributes_[index].is_device_split
Saurabh Shah66c941b2016-07-06 17:34:05 -07001751 ? hw_panel_info_.split_info.left_split
1752 : mixer_attributes_.width;
Ramkumar Radhakrishnan7e971e02017-08-17 14:19:15 +05301753 DLOGI("Mixer WxH %dx%d for %s", mixer_attributes_.width, mixer_attributes_.height, device_name_);
Varun Aroraebf52a62018-08-24 16:51:34 -07001754 update_mode_ = true;
Saurabh Shah66c941b2016-07-06 17:34:05 -07001755}
1756
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001757void HWDeviceDRM::SetSecureConfig(const LayerBuffer &input_buffer, DRMSecureMode *fb_secure_mode,
1758 DRMSecurityLevel *security_level) {
1759 *fb_secure_mode = DRMSecureMode::NON_SECURE;
1760 *security_level = DRMSecurityLevel::SECURE_NON_SECURE;
1761
1762 if (input_buffer.flags.secure) {
1763 if (input_buffer.flags.secure_camera) {
1764 // IOMMU configuration for this framebuffer mode is secure domain & requires
1765 // only stage II translation, when this buffer is accessed by Display H/W.
1766 // Secure and non-secure planes can be attached to this CRTC.
1767 *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION;
1768 } else if (input_buffer.flags.secure_display) {
Sushil Chauhan1fc8b842017-08-21 18:40:29 -07001769 // IOMMU configuration for this framebuffer mode is secure domain & requires
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001770 // only stage II translation, when this buffer is accessed by Display H/W.
1771 // Only secure planes can be attached to this CRTC.
Sushil Chauhan1fc8b842017-08-21 18:40:29 -07001772 *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION;
Sushil Chauhan1021cc02017-05-03 15:11:43 -07001773 *security_level = DRMSecurityLevel::SECURE_ONLY;
1774 } else {
1775 // IOMMU configuration for this framebuffer mode is secure domain & requires both
1776 // stage I and stage II translations, when this buffer is accessed by Display H/W.
1777 // Secure and non-secure planes can be attached to this CRTC.
1778 *fb_secure_mode = DRMSecureMode::SECURE;
1779 }
1780 }
1781}
1782
Ramkumar Radhakrishnan05633712017-09-01 11:35:29 -07001783void HWDeviceDRM::SetTopology(sde_drm::DRMTopology drm_topology, HWTopology *hw_topology) {
1784 switch (drm_topology) {
1785 case DRMTopology::SINGLE_LM: *hw_topology = kSingleLM; break;
1786 case DRMTopology::SINGLE_LM_DSC: *hw_topology = kSingleLMDSC; break;
1787 case DRMTopology::DUAL_LM: *hw_topology = kDualLM; break;
1788 case DRMTopology::DUAL_LM_DSC: *hw_topology = kDualLMDSC; break;
1789 case DRMTopology::DUAL_LM_MERGE: *hw_topology = kDualLMMerge; break;
1790 case DRMTopology::DUAL_LM_MERGE_DSC: *hw_topology = kDualLMMergeDSC; break;
1791 case DRMTopology::DUAL_LM_DSCMERGE: *hw_topology = kDualLMDSCMerge; break;
1792 case DRMTopology::PPSPLIT: *hw_topology = kPPSplit; break;
1793 default: *hw_topology = kUnknown; break;
1794 }
1795}
1796
Arun Kumar K.Rc033f942018-01-05 12:25:47 +05301797
Ramkumar Radhakrishnan07254302017-11-13 16:18:22 -08001798void HWDeviceDRM::SetMultiRectMode(const uint32_t flags, DRMMultiRectMode *target) {
1799 *target = DRMMultiRectMode::NONE;
1800 if (flags & kMultiRect) {
1801 *target = DRMMultiRectMode::SERIAL;
1802 if (flags & kMultiRectParallelMode) {
1803 *target = DRMMultiRectMode::PARALLEL;
1804 }
1805 }
1806}
1807
Arun Kumar K.Rc033f942018-01-05 12:25:47 +05301808void HWDeviceDRM::SetSsppTonemapFeatures(HWPipeInfo *pipe_info) {
1809 if (pipe_info->dgm_csc_info.op != kNoOp) {
1810 SDECsc csc = {};
1811 SetDGMCsc(pipe_info->dgm_csc_info, &csc);
1812 DLOGV_IF(kTagDriverConfig, "Call Perform DGM CSC Op = %s",
1813 (pipe_info->dgm_csc_info.op == kSet) ? "Set" : "Reset");
1814 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DGM_CSC_CONFIG, pipe_info->pipe_id,
1815 reinterpret_cast<uint64_t>(&csc.csc_v1));
1816 }
1817 if (pipe_info->inverse_pma_info.op != kNoOp) {
1818 DLOGV_IF(kTagDriverConfig, "Call Perform Inverse PMA Op = %s",
1819 (pipe_info->inverse_pma_info.op == kSet) ? "Set" : "Reset");
1820 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INVERSE_PMA, pipe_info->pipe_id,
1821 (pipe_info->inverse_pma_info.inverse_pma) ? 1: 0);
1822 }
1823 SetSsppLutFeatures(pipe_info);
1824}
1825
1826void HWDeviceDRM::SetDGMCsc(const HWPipeCscInfo &dgm_csc_info, SDECsc *csc) {
1827 SetDGMCscV1(dgm_csc_info.csc, &csc->csc_v1);
1828}
1829
1830void HWDeviceDRM::SetDGMCscV1(const HWCsc &dgm_csc, sde_drm_csc_v1 *csc_v1) {
1831 uint32_t i = 0;
1832 for (i = 0; i < MAX_CSC_MATRIX_COEFF_SIZE; i++) {
1833 csc_v1->ctm_coeff[i] = dgm_csc.ctm_coeff[i];
1834 DLOGV_IF(kTagDriverConfig, " DGM csc_v1[%d] = %d", i, csc_v1->ctm_coeff[i]);
1835 }
1836 for (i = 0; i < MAX_CSC_BIAS_SIZE; i++) {
1837 csc_v1->pre_bias[i] = dgm_csc.pre_bias[i];
1838 csc_v1->post_bias[i] = dgm_csc.post_bias[i];
1839 }
1840 for (i = 0; i < MAX_CSC_CLAMP_SIZE; i++) {
1841 csc_v1->pre_clamp[i] = dgm_csc.pre_clamp[i];
1842 csc_v1->post_clamp[i] = dgm_csc.post_clamp[i];
1843 }
1844}
1845
1846void HWDeviceDRM::SetSsppLutFeatures(HWPipeInfo *pipe_info) {
1847 for (HWPipeTonemapLutInfo &lut_info : pipe_info->lut_info) {
1848 if (lut_info.op != kNoOp) {
1849 std::shared_ptr<PPFeatureInfo> feature = lut_info.pay_load;
1850 if (feature == nullptr) {
1851 DLOGE("Null Pointer for Op = %d lut type = %d", lut_info.op, lut_info.type);
1852 continue;
1853 }
1854 DRMPPFeatureInfo kernel_params = {};
1855 std::vector<DRMPPFeatureID> drm_id = {};
1856 PPBlock pp_block = GetPPBlock(lut_info.type);
1857 hw_color_mgr_->ToDrmFeatureId(pp_block, feature->feature_id_, &drm_id);
1858 for (DRMPPFeatureID id : drm_id) {
Ping Li13c5ea12018-05-14 13:31:17 -07001859 if (id >= kPPFeaturesMax) {
1860 DLOGE("Invalid feature id %d", id);
1861 continue;
1862 }
Arun Kumar K.Rc033f942018-01-05 12:25:47 +05301863 kernel_params.id = id;
1864 bool disable = (lut_info.op == kReset);
1865 DLOGV_IF(kTagDriverConfig, "Lut Type = %d PPBlock = %d Op = %s Disable = %d Feature = %p",
1866 lut_info.type, pp_block, (lut_info.op ==kSet) ? "Set" : "Reset", disable,
1867 feature.get());
1868 int ret = hw_color_mgr_->GetDrmFeature(feature.get(), &kernel_params, disable);
1869 if (!ret) {
1870 drm_atomic_intf_->Perform(DRMOps::PLANE_SET_POST_PROC, pipe_info->pipe_id,
1871 &kernel_params);
1872 hw_color_mgr_->FreeDrmFeatureData(&kernel_params);
1873 } else {
1874 DLOGE("GetDrmFeature failed for Lut type = %d", lut_info.type);
1875 }
1876 }
1877 drm_id.clear();
1878 }
1879 }
1880}
1881
Ramkumar Radhakrishnana38b7602018-03-15 14:49:52 -07001882void HWDeviceDRM::AddDimLayerIfNeeded() {
1883 if (secure_display_active_ && hw_resource_.secure_disp_blend_stage >= 0) {
1884 HWSolidfillStage sf = {};
1885 sf.z_order = UINT32(hw_resource_.secure_disp_blend_stage);
1886 sf.roi = { 0.0, 0.0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height) };
1887 solid_fills_.clear();
1888 AddSolidfillStage(sf, 0xFF);
1889 SetSolidfillStages();
1890 }
1891}
1892
1893DisplayError HWDeviceDRM::NullCommit(bool synchronous, bool retain_planes) {
1894 DTRACE_SCOPED();
1895 AddDimLayerIfNeeded();
1896 int ret = drm_atomic_intf_->Commit(synchronous , retain_planes);
1897 if (ret) {
1898 DLOGE("failed with error %d", ret);
1899 return kErrorHardware;
1900 }
1901
1902 return kErrorNone;
1903}
1904
Sushil Chauhan06521582018-03-19 14:00:23 -07001905void HWDeviceDRM::DumpConnectorModeInfo() {
1906 for (uint32_t i = 0; i < (uint32_t)connector_info_.modes.size(); i++) {
1907 DLOGI("Mode[%d] Name:%s vref:%d hdisp:%d hsync_s:%d hsync_e:%d htotal:%d " \
1908 "vdisp:%d vsync_s:%d vsync_e:%d vtotal:%d\n", i, connector_info_.modes[i].mode.name,
1909 connector_info_.modes[i].mode.vrefresh, connector_info_.modes[i].mode.hdisplay,
1910 connector_info_.modes[i].mode.hsync_start, connector_info_.modes[i].mode.hsync_end,
1911 connector_info_.modes[i].mode.htotal, connector_info_.modes[i].mode.vdisplay,
1912 connector_info_.modes[i].mode.vsync_start, connector_info_.modes[i].mode.vsync_end,
1913 connector_info_.modes[i].mode.vtotal);
1914 }
1915}
1916
Ramkumar Radhakrishnan3dcf8a22017-11-27 14:53:06 -08001917void HWDeviceDRM::SetFullROI() {
1918 // Reset the CRTC ROI and connector ROI only for the panel that supports partial update
1919 if (!hw_panel_info_.partial_update) {
1920 return;
1921 }
1922 uint32_t index = current_mode_index_;
1923 DRMRect crtc_rects = {0, 0, mixer_attributes_.width, mixer_attributes_.height};
1924 DRMRect conn_rects = {0, 0, display_attributes_[index].x_pixels,
1925 display_attributes_[index].y_pixels};
1926 drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id, 1, &crtc_rects);
1927 drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id, 1, &conn_rects);
1928}
1929
Saurabh Shah7d476ed2016-06-27 16:40:58 -07001930} // namespace sdm