Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1 | /* |
Rohit Kulkarni | 21649ef | 2018-02-08 14:39:40 -0800 | [diff] [blame] | 2 | * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions are |
| 6 | * met: |
| 7 | * * Redistributions of source code must retain the above copyright |
| 8 | * notice, this list of conditions and the following disclaimer. |
| 9 | * * Redistributions in binary form must reproduce the above |
| 10 | * copyright notice, this list of conditions and the following |
| 11 | * disclaimer in the documentation and/or other materials provided |
| 12 | * with the distribution. |
| 13 | * * Neither the name of The Linux Foundation nor the names of its |
| 14 | * contributors may be used to endorse or promote products derived |
| 15 | * from this software without specific prior written permission. |
| 16 | * |
| 17 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| 24 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| 26 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | */ |
| 29 | |
| 30 | #define __STDC_FORMAT_MACROS |
| 31 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 32 | #include <ctype.h> |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 33 | #include <drm/drm_fourcc.h> |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 34 | #include <drm_lib_loader.h> |
| 35 | #include <drm_master.h> |
| 36 | #include <drm_res_mgr.h> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 37 | #include <fcntl.h> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 38 | #include <inttypes.h> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 39 | #include <linux/fb.h> |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 40 | #include <math.h> |
| 41 | #include <stdio.h> |
| 42 | #include <string.h> |
| 43 | #include <sys/ioctl.h> |
| 44 | #include <sys/stat.h> |
| 45 | #include <sys/types.h> |
| 46 | #include <unistd.h> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 47 | #include <utils/constants.h> |
| 48 | #include <utils/debug.h> |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 49 | #include <utils/formats.h> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 50 | #include <utils/sys.h> |
Sushil Chauhan | 3396e20 | 2017-04-14 18:34:22 -0700 | [diff] [blame] | 51 | #include <drm/sde_drm.h> |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 52 | #include <private/color_params.h> |
Rohit Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 53 | #include <utils/rect.h> |
Varun Arora | f182bfa | 2018-08-14 10:49:08 -0700 | [diff] [blame] | 54 | #include <utils/utils.h> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 55 | |
Varun Arora | 7c8ee54 | 2018-05-01 20:58:16 -0700 | [diff] [blame] | 56 | #include <sstream> |
| 57 | #include <ctime> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 58 | #include <algorithm> |
| 59 | #include <string> |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 60 | #include <unordered_map> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 61 | #include <utility> |
| 62 | #include <vector> |
Gopikrishnaiah Anandan | 739faf9 | 2017-07-21 12:32:00 -0700 | [diff] [blame] | 63 | #include <limits> |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 64 | |
| 65 | #include "hw_device_drm.h" |
| 66 | #include "hw_info_interface.h" |
| 67 | |
| 68 | #define __CLASS__ "HWDeviceDRM" |
| 69 | |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 70 | #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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 80 | using std::string; |
| 81 | using std::to_string; |
| 82 | using std::fstream; |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 83 | using std::unordered_map; |
Varun Arora | 7c8ee54 | 2018-05-01 20:58:16 -0700 | [diff] [blame] | 84 | using std::stringstream; |
| 85 | using std::ifstream; |
| 86 | using std::ofstream; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 87 | using drm_utils::DRMMaster; |
| 88 | using drm_utils::DRMResMgr; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 89 | using drm_utils::DRMLibLoader; |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 90 | using drm_utils::DRMBuffer; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 91 | using sde_drm::GetDRMManager; |
| 92 | using sde_drm::DestroyDRMManager; |
| 93 | using sde_drm::DRMDisplayType; |
| 94 | using sde_drm::DRMDisplayToken; |
| 95 | using sde_drm::DRMConnectorInfo; |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 96 | using sde_drm::DRMPPFeatureInfo; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 97 | using sde_drm::DRMRect; |
Saurabh Shah | f9266ee | 2017-04-19 15:25:46 -0700 | [diff] [blame] | 98 | using sde_drm::DRMRotation; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 99 | using sde_drm::DRMBlendType; |
Prabhanjan Kandula | 585aa65 | 2017-01-26 18:39:11 -0800 | [diff] [blame] | 100 | using sde_drm::DRMSrcConfig; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 101 | using sde_drm::DRMOps; |
| 102 | using sde_drm::DRMTopology; |
Sushil Chauhan | 3396e20 | 2017-04-14 18:34:22 -0700 | [diff] [blame] | 103 | using sde_drm::DRMPowerMode; |
Sushil Chauhan | 1021cc0 | 2017-05-03 15:11:43 -0700 | [diff] [blame] | 104 | using sde_drm::DRMSecureMode; |
| 105 | using sde_drm::DRMSecurityLevel; |
Ping Li | 8d6dd62 | 2017-07-03 12:05:15 -0700 | [diff] [blame] | 106 | using sde_drm::DRMCscType; |
Ramkumar Radhakrishnan | 0725430 | 2017-11-13 16:18:22 -0800 | [diff] [blame] | 107 | using sde_drm::DRMMultiRectMode; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 108 | |
| 109 | namespace sdm { |
| 110 | |
Arun Kumar K.R | c033f94 | 2018-01-05 12:25:47 +0530 | [diff] [blame] | 111 | static 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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 129 | static 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 Kulkarni | 2d7151c | 2017-12-14 22:17:49 -0800 | [diff] [blame] | 213 | case kFormatYCbCr420SPVenusTile: |
| 214 | *drm_format = DRM_FORMAT_NV12; |
| 215 | *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE; |
| 216 | break; |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 217 | 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 Karimpanal | a73082e | 2017-10-16 18:01:21 +0530 | [diff] [blame] | 224 | case kFormatYCbCr420P010Venus: |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 225 | *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 Kulkarni | 2d7151c | 2017-12-14 22:17:49 -0800 | [diff] [blame] | 233 | 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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 238 | 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 Kulkarni | 2d7151c | 2017-12-14 22:17:49 -0800 | [diff] [blame] | 243 | 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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 248 | 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 Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 262 | class FrameBufferObject : public LayerBufferObject { |
| 263 | public: |
| 264 | explicit FrameBufferObject(uint32_t fb_id) : fb_id_(fb_id) { |
Saurabh Shah | 23cd08a | 2017-07-10 15:18:14 -0700 | [diff] [blame] | 265 | } |
| 266 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 267 | ~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 Shah | 23cd08a | 2017-07-10 15:18:14 -0700 | [diff] [blame] | 276 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 277 | private: |
| 278 | uint32_t fb_id_; |
| 279 | }; |
| 280 | |
| 281 | HWDeviceDRM::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 Shah | 23cd08a | 2017-07-10 15:18:14 -0700 | [diff] [blame] | 287 | } |
| 288 | |
Saurabh Shah | 4d4f400 | 2017-12-26 12:42:59 -0800 | [diff] [blame] | 289 | void HWDeviceDRM::Registry::Register(HWLayers *hw_layers) { |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 290 | 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 Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 298 | fbid_cache_limit_ = input_buffer->flags.video ? VIDEO_FBID_LIMIT : UI_FBID_LIMIT; |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 299 | |
Rohit Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 300 | if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) { |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 301 | input_buffer = &hw_rotator_session->output_buffer; |
Sushil Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 302 | fbid_cache_limit_ = OFFLINE_ROTATOR_FBID_LIMIT; |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 303 | } |
| 304 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 305 | // layer input buffer map to fb id also applies for inline rot |
| 306 | MapBufferToFbId(&layer, input_buffer); |
Rohit Kulkarni | 2d7151c | 2017-12-14 22:17:49 -0800 | [diff] [blame] | 307 | |
| 308 | if (hw_rotator_session->mode == kRotatorInline && hw_rotate_info->valid && |
| 309 | hw_rotator_session->output_buffer.planes[0].fd >= 0) { |
Sushil Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 310 | fbid_cache_limit_ += 1; // account for inline rot scratch buffer |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 311 | MapBufferToFbId(&layer, &hw_rotator_session->output_buffer); |
Rohit Kulkarni | 2d7151c | 2017-12-14 22:17:49 -0800 | [diff] [blame] | 312 | } |
Mahesh Aia | 1d2ceda | 2017-03-24 11:07:31 -0700 | [diff] [blame] | 313 | } |
| 314 | } |
| 315 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 316 | int HWDeviceDRM::Registry::CreateFbId(LayerBuffer *buffer, uint32_t *fb_id) { |
Mahesh Aia | 1d2ceda | 2017-03-24 11:07:31 -0700 | [diff] [blame] | 317 | DRMMaster *master = nullptr; |
| 318 | DRMMaster::GetInstance(&master); |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 319 | int ret = -1; |
Mahesh Aia | 1d2ceda | 2017-03-24 11:07:31 -0700 | [diff] [blame] | 320 | |
| 321 | if (!master) { |
| 322 | DLOGE("Failed to acquire DRM Master instance"); |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 323 | 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 | |
| 343 | void HWDeviceDRM::Registry::MapBufferToFbId(Layer* layer, LayerBuffer* buffer) { |
| 344 | if (buffer->planes[0].fd < 0) { |
Mahesh Aia | 1d2ceda | 2017-03-24 11:07:31 -0700 | [diff] [blame] | 345 | return; |
| 346 | } |
| 347 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 348 | uint64_t handle_id = buffer->handle_id; |
Sushil Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 349 | if (!handle_id || disable_fbid_cache_) { |
| 350 | // In legacy path, clear fb_id map in each frame. |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 351 | layer->buffer_map->buffer_map.clear(); |
Sushil Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 352 | } 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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 357 | |
Sushil Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 358 | 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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 362 | } |
| 363 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 364 | 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 | |
| 371 | void HWDeviceDRM::Registry::MapOutputBufferToFbId(LayerBuffer *output_buffer) { |
| 372 | if (output_buffer->planes[0].fd < 0) { |
| 373 | return; |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 374 | } |
| 375 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 376 | uint64_t handle_id = output_buffer->handle_id; |
Sushil Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 377 | if (!handle_id || disable_fbid_cache_) { |
| 378 | // In legacy path, clear output buffer map in each frame. |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 379 | output_buffer_map_.clear(); |
Sushil Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 380 | } else { |
| 381 | if (output_buffer_map_.find(handle_id) != output_buffer_map_.end()) { |
| 382 | return; |
| 383 | } |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 384 | |
Sushil Chauhan | 1d00aa5 | 2018-06-20 16:11:52 -0700 | [diff] [blame] | 385 | 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 Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 389 | } |
| 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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 395 | } |
| 396 | |
| 397 | void HWDeviceDRM::Registry::Clear() { |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 398 | output_buffer_map_.clear(); |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 399 | } |
| 400 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 401 | uint32_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 | |
| 411 | uint32_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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 419 | } |
| 420 | |
| 421 | HWDeviceDRM::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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 425 | hw_info_intf_ = hw_info_intf; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 426 | } |
| 427 | |
| 428 | DisplayError HWDeviceDRM::Init() { |
Mathew Joseph Karimpanal | 43c9d69 | 2018-06-14 13:45:27 +0530 | [diff] [blame] | 429 | int ret = 0; |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 430 | DRMMaster *drm_master = {}; |
| 431 | DRMMaster::GetInstance(&drm_master); |
| 432 | drm_master->GetHandle(&dev_fd_); |
| 433 | DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 434 | |
Mathew Joseph Karimpanal | 731bc93 | 2017-11-22 10:04:56 +0530 | [diff] [blame] | 435 | 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 Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 442 | return kErrorResources; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 443 | } |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 444 | |
Mathew Joseph Karimpanal | 43c9d69 | 2018-06-14 13:45:27 +0530 | [diff] [blame] | 445 | 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 Karimpanal | 731bc93 | 2017-11-22 10:04:56 +0530 | [diff] [blame] | 451 | display_id_ = static_cast<int32_t>(token_.conn_id); |
| 452 | |
Mathew Joseph Karimpanal | 43c9d69 | 2018-06-14 13:45:27 +0530 | [diff] [blame] | 453 | 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 477 | hw_info_intf_->GetHWResourceInfo(&hw_resource_); |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 478 | |
| 479 | InitializeConfigs(); |
| 480 | PopulateHWPanelInfo(); |
| 481 | UpdateMixerAttributes(); |
| 482 | |
Saurabh Shah | 0ffee30 | 2016-11-22 10:42:11 -0800 | [diff] [blame] | 483 | // 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 Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 487 | |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 488 | std::unique_ptr<HWColorManagerDrm> hw_color_mgr(new HWColorManagerDrm()); |
| 489 | hw_color_mgr_ = std::move(hw_color_mgr); |
| 490 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 491 | return kErrorNone; |
| 492 | } |
| 493 | |
| 494 | DisplayError HWDeviceDRM::Deinit() { |
Saurabh Shah | 3cbc1ae | 2017-09-12 16:07:41 -0700 | [diff] [blame] | 495 | 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 Radhakrishnan | a38b760 | 2018-03-15 14:49:52 -0700 | [diff] [blame] | 500 | int ret = NullCommit(true /* synchronous */, false /* retain_planes */); |
Saurabh Shah | 3cbc1ae | 2017-09-12 16:07:41 -0700 | [diff] [blame] | 501 | if (ret) { |
| 502 | DLOGE("Commit failed with error: %d", ret); |
| 503 | err = kErrorHardware; |
| 504 | } |
| 505 | |
Saurabh Shah | 0ffee30 | 2016-11-22 10:42:11 -0800 | [diff] [blame] | 506 | delete hw_scale_; |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 507 | registry_.Clear(); |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 508 | display_attributes_ = {}; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 509 | drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_); |
| 510 | drm_atomic_intf_ = {}; |
| 511 | drm_mgr_intf_->UnregisterDisplay(token_); |
Saurabh Shah | 3cbc1ae | 2017-09-12 16:07:41 -0700 | [diff] [blame] | 512 | return err; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 513 | } |
| 514 | |
Mathew Joseph Karimpanal | 731bc93 | 2017-11-22 10:04:56 +0530 | [diff] [blame] | 515 | DisplayError HWDeviceDRM::GetDisplayId(int32_t *display_id) { |
| 516 | *display_id = display_id_; |
| 517 | return kErrorNone; |
| 518 | } |
| 519 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 520 | void HWDeviceDRM::InitializeConfigs() { |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 521 | current_mode_index_ = 0; |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 522 | // Update current mode with preferred mode |
| 523 | for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) { |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 524 | if (connector_info_.modes[mode_index].mode.type & DRM_MODE_TYPE_PREFERRED) { |
Mathew Joseph Karimpanal | 351bf87 | 2018-08-28 16:08:28 +0530 | [diff] [blame] | 525 | DLOGI("Updating current display mode %d to preferred mode %d.", current_mode_index_, |
| 526 | mode_index); |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 527 | current_mode_index_ = mode_index; |
| 528 | break; |
| 529 | } |
| 530 | } |
| 531 | |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 532 | display_attributes_.resize(connector_info_.modes.size()); |
| 533 | |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 534 | uint32_t width = connector_info_.modes[current_mode_index_].mode.hdisplay; |
| 535 | uint32_t height = connector_info_.modes[current_mode_index_].mode.vdisplay; |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 536 | for (uint32_t i = 0; i < connector_info_.modes.size(); i++) { |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 537 | auto &mode = connector_info_.modes[i].mode; |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 538 | if (mode.hdisplay != width || mode.vdisplay != height) { |
| 539 | resolution_switch_enabled_ = true; |
| 540 | } |
| 541 | PopulateDisplayAttributes(i); |
| 542 | } |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 543 | } |
| 544 | |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 545 | DisplayError HWDeviceDRM::PopulateDisplayAttributes(uint32_t index) { |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 546 | drmModeModeInfo mode = {}; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 547 | uint32_t mm_width = 0; |
| 548 | uint32_t mm_height = 0; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 549 | 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 Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 562 | mode = connector_info_.modes[index].mode; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 563 | mm_width = connector_info_.mmWidth; |
| 564 | mm_height = connector_info_.mmHeight; |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 565 | topology = connector_info_.modes[index].topology; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 566 | } |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 567 | |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 568 | 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 573 | |
| 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 584 | 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 589 | display_attributes_[index].is_device_split = |
Rohit Kulkarni | 2faa91c | 2017-06-05 15:43:48 -0700 | [diff] [blame] | 590 | (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 Radhakrishnan | 0563371 | 2017-09-01 11:35:29 -0700 | [diff] [blame] | 593 | display_attributes_[index].clock_khz = mode.clock; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 594 | |
Saurabh Shah | 8833199 | 2017-07-17 14:53:00 -0700 | [diff] [blame] | 595 | // 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 602 | 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 Radhakrishnan | 0563371 | 2017-09-01 11:35:29 -0700 | [diff] [blame] | 604 | SetTopology(topology, &display_attributes_[index].topology); |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 605 | |
Ramkumar Radhakrishnan | f5f24c9 | 2017-08-11 18:30:57 -0700 | [diff] [blame] | 606 | DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \ |
Ramkumar Radhakrishnan | 0563371 | 2017-09-01 11:35:29 -0700 | [diff] [blame] | 607 | " 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 609 | display_attributes_[index].x_dpi, display_attributes_[index].y_dpi, |
Ramkumar Radhakrishnan | f5f24c9 | 2017-08-11 18:30:57 -0700 | [diff] [blame] | 610 | 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 Radhakrishnan | 0563371 | 2017-09-01 11:35:29 -0700 | [diff] [blame] | 613 | display_attributes_[index].h_total, display_attributes_[index].clock_khz, |
| 614 | display_attributes_[index].topology); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 615 | |
| 616 | return kErrorNone; |
| 617 | } |
| 618 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 619 | void 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 624 | |
Ramkumar Radhakrishnan | ee0aab2 | 2017-10-16 16:11:18 -0700 | [diff] [blame] | 625 | 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 631 | |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 632 | 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 642 | hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps; |
Sushil Chauhan | 8f514a5 | 2018-02-27 17:35:44 -0800 | [diff] [blame] | 643 | hw_panel_info_.qsync_support = connector_info_.qsync_support; |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 644 | drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode; |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 645 | 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 Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 649 | 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 Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 653 | } |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 654 | if (max_fps < connector_info_.modes[mode_index].mode.vrefresh) { |
| 655 | max_fps = connector_info_.modes[mode_index].mode.vrefresh; |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 656 | } |
| 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 666 | hw_panel_info_.is_primary_panel = connector_info_.is_primary; |
| 667 | hw_panel_info_.is_pluggable = 0; |
Sushil Chauhan | 80e5843 | 2017-07-06 11:39:17 -0700 | [diff] [blame] | 668 | hw_panel_info_.hdr_enabled = connector_info_.panel_hdr_prop.hdr_enabled; |
Sushil Chauhan | aa8be83 | 2018-08-31 13:38:20 -0700 | [diff] [blame] | 669 | // 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 Chauhan | 80e5843 | 2017-07-06 11:39:17 -0700 | [diff] [blame] | 672 | 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 Radhakrishnan | 5c94f05 | 2017-07-06 11:59:14 -0700 | [diff] [blame] | 680 | hw_panel_info_.transfer_time_us = connector_info_.transfer_time_us; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 681 | |
Prabhanjan Kandula | 5bc7f8b | 2017-05-23 12:24:57 -0700 | [diff] [blame] | 682 | // 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 691 | 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 Chauhan | 8f514a5 | 2018-02-27 17:35:44 -0800 | [diff] [blame] | 697 | 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 700 | 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 Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 704 | DLOGI("FPS: min = %d, max = %d", hw_panel_info_.min_fps, hw_panel_info_.max_fps); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 705 | DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split, |
| 706 | hw_panel_info_.split_info.right_split); |
Ramkumar Radhakrishnan | 5c94f05 | 2017-07-06 11:59:14 -0700 | [diff] [blame] | 707 | DLOGI("Panel Transfer time = %d us", hw_panel_info_.transfer_time_us); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 708 | } |
| 709 | |
| 710 | void 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 | |
| 751 | void HWDeviceDRM::GetHWPanelMaxBrightness() { |
| 752 | char brightness[kMaxStringLength] = {0}; |
Saurabh Shah | 8b021cf | 2017-03-14 12:16:43 -0700 | [diff] [blame] | 753 | string kMaxBrightnessNode = "/sys/class/backlight/panel0-backlight/max_brightness"; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 754 | |
| 755 | hw_panel_info_.panel_max_brightness = 255; |
Saurabh Shah | 8b021cf | 2017-03-14 12:16:43 -0700 | [diff] [blame] | 756 | int fd = Sys::open_(kMaxBrightnessNode.c_str(), O_RDONLY); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 757 | if (fd < 0) { |
Saurabh Shah | 8b021cf | 2017-03-14 12:16:43 -0700 | [diff] [blame] | 758 | DLOGW("Failed to open max brightness node = %s, error = %s", kMaxBrightnessNode.c_str(), |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 759 | 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 771 | } |
| 772 | |
| 773 | DisplayError HWDeviceDRM::GetActiveConfig(uint32_t *active_config) { |
Pullakavi Srinivas | 8b33a28 | 2018-11-01 12:45:38 +0530 | [diff] [blame] | 774 | *active_config = current_mode_index_; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 775 | return kErrorNone; |
| 776 | } |
| 777 | |
| 778 | DisplayError HWDeviceDRM::GetNumDisplayAttributes(uint32_t *count) { |
Pullakavi Srinivas | 8b33a28 | 2018-11-01 12:45:38 +0530 | [diff] [blame] | 779 | *count = UINT32(display_attributes_.size()); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 780 | return kErrorNone; |
| 781 | } |
| 782 | |
| 783 | DisplayError HWDeviceDRM::GetDisplayAttributes(uint32_t index, |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 784 | HWDisplayAttributes *display_attributes) { |
| 785 | if (index >= display_attributes_.size()) { |
| 786 | return kErrorParameters; |
| 787 | } |
Pullakavi Srinivas | 8b33a28 | 2018-11-01 12:45:38 +0530 | [diff] [blame] | 788 | *display_attributes = display_attributes_[index]; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 789 | return kErrorNone; |
| 790 | } |
| 791 | |
| 792 | DisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) { |
| 793 | *panel_info = hw_panel_info_; |
| 794 | return kErrorNone; |
| 795 | } |
| 796 | |
| 797 | DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) { |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 798 | if (index >= display_attributes_.size()) { |
Ramkumar Radhakrishnan | 0dc25f3 | 2017-09-06 17:05:18 -0700 | [diff] [blame] | 799 | DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size())); |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 800 | return kErrorParameters; |
| 801 | } |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 802 | |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 803 | current_mode_index_ = index; |
Ramkumar Radhakrishnan | ee0aab2 | 2017-10-16 16:11:18 -0700 | [diff] [blame] | 804 | PopulateHWPanelInfo(); |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 805 | UpdateMixerAttributes(); |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 806 | |
| 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 817 | return kErrorNone; |
| 818 | } |
| 819 | |
| 820 | DisplayError HWDeviceDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) { |
| 821 | return kErrorNotSupported; |
| 822 | } |
| 823 | |
srikanth rajagopalan | 5d320c6 | 2017-06-05 21:08:57 -0700 | [diff] [blame] | 824 | DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) { |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 825 | return kErrorNone; |
| 826 | } |
| 827 | |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 828 | DisplayError HWDeviceDRM::PowerOn(const HWQosData &qos_data, int *release_fence) { |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 829 | SetQOSData(qos_data); |
| 830 | |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 831 | int64_t release_fence_t = -1; |
Sushil Chauhan | 93c892c | 2018-05-11 17:15:37 -0700 | [diff] [blame] | 832 | update_mode_ = true; |
Sushil Chauhan | 3396e20 | 2017-04-14 18:34:22 -0700 | [diff] [blame] | 833 | 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 Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 835 | drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t); |
Ramkumar Radhakrishnan | a38b760 | 2018-03-15 14:49:52 -0700 | [diff] [blame] | 836 | int ret = NullCommit(true /* synchronous */, true /* retain_planes */); |
Sushil Chauhan | 5675552 | 2017-06-01 13:39:50 -0700 | [diff] [blame] | 837 | if (ret) { |
Sushil Chauhan | a4d1fc0 | 2017-08-07 17:41:39 -0700 | [diff] [blame] | 838 | DLOGE("Failed with error: %d", ret); |
Sushil Chauhan | 5675552 | 2017-06-01 13:39:50 -0700 | [diff] [blame] | 839 | return kErrorHardware; |
| 840 | } |
Saurabh Shah | 82b06f4 | 2017-09-06 16:43:49 -0700 | [diff] [blame] | 841 | |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 842 | *release_fence = static_cast<int>(release_fence_t); |
Varun Arora | 006e3a1 | 2018-04-20 17:09:35 -0700 | [diff] [blame] | 843 | DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 844 | return kErrorNone; |
| 845 | } |
| 846 | |
Varun Arora | 78580b8 | 2018-09-10 13:59:57 -0700 | [diff] [blame] | 847 | DisplayError HWDeviceDRM::PowerOff(bool teardown) { |
Saurabh Shah | a917aa7 | 2017-09-15 13:27:24 -0700 | [diff] [blame] | 848 | DTRACE_SCOPED(); |
Sushil Chauhan | 23fc6e1 | 2017-06-22 11:15:51 -0700 | [diff] [blame] | 849 | if (!drm_atomic_intf_) { |
| 850 | DLOGE("DRM Atomic Interface is null!"); |
| 851 | return kErrorUndefined; |
| 852 | } |
| 853 | |
Ramkumar Radhakrishnan | 3dcf8a2 | 2017-11-27 14:53:06 -0800 | [diff] [blame] | 854 | SetFullROI(); |
Ramkumar Radhakrishnan | 9847993 | 2018-03-28 15:33:08 -0700 | [diff] [blame] | 855 | drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode; |
| 856 | drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, ¤t_mode); |
Sushil Chauhan | 3396e20 | 2017-04-14 18:34:22 -0700 | [diff] [blame] | 857 | 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 Radhakrishnan | a38b760 | 2018-03-15 14:49:52 -0700 | [diff] [blame] | 859 | int ret = NullCommit(true /* synchronous */, false /* retain_planes */); |
Sushil Chauhan | 3396e20 | 2017-04-14 18:34:22 -0700 | [diff] [blame] | 860 | if (ret) { |
Sushil Chauhan | a4d1fc0 | 2017-08-07 17:41:39 -0700 | [diff] [blame] | 861 | DLOGE("Failed with error: %d", ret); |
Sushil Chauhan | 3396e20 | 2017-04-14 18:34:22 -0700 | [diff] [blame] | 862 | return kErrorHardware; |
| 863 | } |
Saurabh Shah | 82b06f4 | 2017-09-06 16:43:49 -0700 | [diff] [blame] | 864 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 865 | return kErrorNone; |
| 866 | } |
| 867 | |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 868 | DisplayError HWDeviceDRM::Doze(const HWQosData &qos_data, int *release_fence) { |
Saurabh Shah | a917aa7 | 2017-09-15 13:27:24 -0700 | [diff] [blame] | 869 | DTRACE_SCOPED(); |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 870 | |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 871 | SetQOSData(qos_data); |
| 872 | |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 873 | int64_t release_fence_t = -1; |
Ramakant Singh | da5072f | 2018-07-09 14:20:01 -0700 | [diff] [blame] | 874 | |
| 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, ¤t_mode); |
| 879 | } |
Sushil Chauhan | a4d1fc0 | 2017-08-07 17:41:39 -0700 | [diff] [blame] | 880 | drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); |
Sushil Chauhan | 3396e20 | 2017-04-14 18:34:22 -0700 | [diff] [blame] | 881 | drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE); |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 882 | drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t); |
Ramkumar Radhakrishnan | a38b760 | 2018-03-15 14:49:52 -0700 | [diff] [blame] | 883 | int ret = NullCommit(true /* synchronous */, true /* retain_planes */); |
Sushil Chauhan | a4d1fc0 | 2017-08-07 17:41:39 -0700 | [diff] [blame] | 884 | if (ret) { |
| 885 | DLOGE("Failed with error: %d", ret); |
| 886 | return kErrorHardware; |
| 887 | } |
| 888 | |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 889 | *release_fence = static_cast<int>(release_fence_t); |
Varun Arora | 006e3a1 | 2018-04-20 17:09:35 -0700 | [diff] [blame] | 890 | DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 891 | return kErrorNone; |
| 892 | } |
| 893 | |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 894 | DisplayError HWDeviceDRM::DozeSuspend(const HWQosData &qos_data, int *release_fence) { |
Saurabh Shah | a917aa7 | 2017-09-15 13:27:24 -0700 | [diff] [blame] | 895 | DTRACE_SCOPED(); |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 896 | |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 897 | SetQOSData(qos_data); |
| 898 | |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 899 | int64_t release_fence_t = -1; |
Ramakant Singh | da5072f | 2018-07-09 14:20:01 -0700 | [diff] [blame] | 900 | |
| 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, ¤t_mode); |
| 905 | } |
Saurabh Shah | a917aa7 | 2017-09-15 13:27:24 -0700 | [diff] [blame] | 906 | drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); |
Sushil Chauhan | 3396e20 | 2017-04-14 18:34:22 -0700 | [diff] [blame] | 907 | drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, |
| 908 | DRMPowerMode::DOZE_SUSPEND); |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 909 | drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence_t); |
Ramkumar Radhakrishnan | a38b760 | 2018-03-15 14:49:52 -0700 | [diff] [blame] | 910 | int ret = NullCommit(true /* synchronous */, true /* retain_planes */); |
Saurabh Shah | a917aa7 | 2017-09-15 13:27:24 -0700 | [diff] [blame] | 911 | if (ret) { |
| 912 | DLOGE("Failed with error: %d", ret); |
| 913 | return kErrorHardware; |
| 914 | } |
| 915 | |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 916 | *release_fence = static_cast<int>(release_fence_t); |
Varun Arora | 006e3a1 | 2018-04-20 17:09:35 -0700 | [diff] [blame] | 917 | DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", *release_fence); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 918 | return kErrorNone; |
| 919 | } |
| 920 | |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 921 | void 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 934 | DisplayError HWDeviceDRM::Standby() { |
| 935 | return kErrorNone; |
| 936 | } |
| 937 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 938 | void 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 Radhakrishnan | 3c4de11 | 2017-05-24 22:38:30 -0700 | [diff] [blame] | 945 | HWQosData &qos_data = hw_layers->qos_data; |
Sushil Chauhan | 1021cc0 | 2017-05-03 15:11:43 -0700 | [diff] [blame] | 946 | DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE; |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 947 | uint32_t index = current_mode_index_; |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 948 | drmModeModeInfo current_mode = connector_info_.modes[index].mode; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 949 | |
Prabhanjan Kandula | dbc8aed | 2017-03-24 14:43:16 -0700 | [diff] [blame] | 950 | solid_fills_.clear(); |
| 951 | |
Saurabh Shah | e9f55d7 | 2017-03-03 15:14:13 -0800 | [diff] [blame] | 952 | // 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 956 | DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_[index].x_pixels, |
| 957 | display_attributes_[index].y_pixels}}; |
Saurabh Shah | e9f55d7 | 2017-03-03 15:14:13 -0800 | [diff] [blame] | 958 | |
| 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 Solanki | 24921ab | 2017-05-23 20:16:25 +0530 | [diff] [blame] | 967 | // TODO(user): panel_roi need to be made as a vector in HWLayersInfo and |
| 968 | // needs to be removed from HWDestScaleInfo. |
Saurabh Shah | e9f55d7 | 2017-03-03 15:14:13 -0800 | [diff] [blame] | 969 | 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 982 | for (uint32_t i = 0; i < hw_layer_count; i++) { |
| 983 | Layer &layer = hw_layer_info.hw_layers.at(i); |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 984 | LayerBuffer *input_buffer = &layer.input_buffer; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 985 | HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe; |
| 986 | HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe; |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 987 | HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 988 | |
Prabhanjan Kandula | dbc8aed | 2017-03-24 14:43:16 -0700 | [diff] [blame] | 989 | if (hw_layers->config[i].use_solidfill_stage) { |
Gopikrishnaiah Anandan | cc12306 | 2017-07-31 17:21:03 -0700 | [diff] [blame] | 990 | hw_layers->config[i].hw_solidfill_stage.solid_fill_info = layer.solid_fill_info; |
Prabhanjan Kandula | dbc8aed | 2017-03-24 14:43:16 -0700 | [diff] [blame] | 991 | AddSolidfillStage(hw_layers->config[i].hw_solidfill_stage, layer.plane_alpha); |
| 992 | continue; |
| 993 | } |
| 994 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 995 | for (uint32_t count = 0; count < 2; count++) { |
| 996 | HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe; |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 997 | HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count]; |
| 998 | |
Rohit Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 999 | if (hw_rotator_session->mode == kRotatorOffline && hw_rotate_info->valid) { |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 1000 | input_buffer = &hw_rotator_session->output_buffer; |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 1001 | } |
| 1002 | |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 1003 | uint32_t fb_id = registry_.GetFbId(&layer, input_buffer->handle_id); |
| 1004 | |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1005 | if (pipe_info->valid && fb_id) { |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1006 | uint32_t pipe_id = pipe_info->pipe_id; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1007 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha); |
Ramkumar Radhakrishnan | a38b760 | 2018-03-15 14:49:52 -0700 | [diff] [blame] | 1008 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1009 | 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 Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 1016 | 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 Kulkarni | 2d7151c | 2017-12-14 22:17:49 -0800 | [diff] [blame] | 1020 | if (hw_rotator_session->output_buffer.planes[0].fd >= 0) { |
Sushil Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 1021 | uint32_t rot_fb_id = registry_.GetFbId(&layer, |
| 1022 | hw_rotator_session->output_buffer.handle_id); |
Rohit Kulkarni | 2d7151c | 2017-12-14 22:17:49 -0800 | [diff] [blame] | 1023 | if (rot_fb_id) { |
| 1024 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROT_FB_ID, pipe_id, rot_fb_id); |
| 1025 | } |
| 1026 | } |
Rohit Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 1027 | } |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1028 | DRMRect dst = {}; |
| 1029 | SetRect(pipe_info->dst_roi, &dst); |
| 1030 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst); |
Namit Solanki | 6d0d806 | 2017-11-30 17:29:48 +0530 | [diff] [blame] | 1031 | DRMRect excl = {}; |
| 1032 | SetRect(pipe_info->excl_rect, &excl); |
| 1033 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_EXCL_RECT, pipe_id, excl); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1034 | uint32_t rot_bit_mask = 0; |
Rohit Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 1035 | SetRotation(layer.transform, hw_rotator_session->mode, &rot_bit_mask); |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 1036 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1037 | 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 Chauhan | 1021cc0 | 2017-05-03 15:11:43 -0700 | [diff] [blame] | 1041 | |
| 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 Kandula | 585aa65 | 2017-01-26 18:39:11 -0800 | [diff] [blame] | 1050 | uint32_t config = 0; |
Ramkumar Radhakrishnan | 0751f87 | 2017-11-09 15:56:10 -0800 | [diff] [blame] | 1051 | SetSrcConfig(layer.input_buffer, hw_rotator_session->mode, &config); |
Prabhanjan Kandula | 585aa65 | 2017-01-26 18:39:11 -0800 | [diff] [blame] | 1052 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);; |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1053 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1054 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id); |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 1055 | if (!validate && input_buffer->acquire_fence_fd >= 0) { |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1056 | drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id, |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 1057 | input_buffer->acquire_fence_fd); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1058 | } |
Saurabh Shah | 0ffee30 | 2016-11-22 10:42:11 -0800 | [diff] [blame] | 1059 | if (hw_scale_) { |
| 1060 | SDEScaler scaler_output = {}; |
Namit Solanki | 24921ab | 2017-05-23 20:16:25 +0530 | [diff] [blame] | 1061 | hw_scale_->SetScaler(pipe_info->scale_data, &scaler_output); |
Saurabh Shah | 0ffee30 | 2016-11-22 10:42:11 -0800 | [diff] [blame] | 1062 | // 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 Li | 8d6dd62 | 2017-07-03 12:05:15 -0700 | [diff] [blame] | 1068 | |
| 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 Radhakrishnan | 0725430 | 2017-11-13 16:18:22 -0800 | [diff] [blame] | 1072 | |
| 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.R | c033f94 | 2018-01-05 12:25:47 +0530 | [diff] [blame] | 1076 | |
| 1077 | SetSsppTonemapFeatures(pipe_info); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1078 | } |
| 1079 | } |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1080 | } |
Prabhanjan Kandula | f890c25 | 2017-07-09 18:22:02 -0700 | [diff] [blame] | 1081 | |
Prabhanjan Kandula | dbc8aed | 2017-03-24 14:43:16 -0700 | [diff] [blame] | 1082 | SetSolidfillStages(); |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 1083 | SetQOSData(qos_data); |
Sushil Chauhan | edfdfbb | 2017-07-31 15:00:24 -0700 | [diff] [blame] | 1084 | drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level); |
Xu Yang | da64222 | 2018-06-12 10:32:33 +0800 | [diff] [blame] | 1085 | drm_atomic_intf_->Perform(DRMOps::DPPS_COMMIT_FEATURE, 0 /* argument is not used */); |
Prabhanjan Kandula | f890c25 | 2017-07-09 18:22:02 -0700 | [diff] [blame] | 1086 | |
Varun Arora | ef98729 | 2018-04-16 17:16:42 -0700 | [diff] [blame] | 1087 | 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 Radhakrishnan | b791044 | 2017-12-11 13:32:47 -0800 | [diff] [blame] | 1092 | 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 Kandula | f890c25 | 2017-07-09 18:22:02 -0700 | [diff] [blame] | 1095 | 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 Radhakrishnan | b791044 | 2017-12-11 13:32:47 -0800 | [diff] [blame] | 1097 | qos_data.rot_prefill_bw_bps, qos_data.rot_clock_hz); |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1098 | |
| 1099 | // Set refresh rate |
| 1100 | if (vrefresh_) { |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1101 | for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) { |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 1102 | 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 Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1106 | break; |
| 1107 | } |
| 1108 | } |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1109 | } |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 1110 | |
| 1111 | if (first_cycle_) { |
Mathew Joseph Karimpanal | b7f20c6 | 2018-10-09 12:17:20 +0530 | [diff] [blame] | 1112 | drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_TOPOLOGY_CONTROL, token_.conn_id, |
| 1113 | topology_control_); |
Varun Arora | bbb062e | 2018-07-03 22:33:59 -0700 | [diff] [blame] | 1114 | drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 1115 | 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 Chauhan | 93c892c | 2018-05-11 17:15:37 -0700 | [diff] [blame] | 1119 | // 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, ¤t_mode); |
| 1122 | } |
| 1123 | |
Anjaneya Prasad Musunuri | e8c67f2 | 2017-07-01 16:16:13 +0530 | [diff] [blame] | 1124 | 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 Shah | f363595 | 2017-10-16 17:08:18 -0700 | [diff] [blame] | 1130 | |
| 1131 | if (hw_panel_info_.mode == kModeCommand) { |
| 1132 | drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_AUTOREFRESH, token_.conn_id, autorefresh_); |
| 1133 | } |
Sushil Chauhan | 8f514a5 | 2018-02-27 17:35:44 -0800 | [diff] [blame] | 1134 | |
| 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1138 | } |
| 1139 | |
Prabhanjan Kandula | dbc8aed | 2017-03-24 14:43:16 -0700 | [diff] [blame] | 1140 | void 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 Anandan | cc12306 | 2017-07-31 17:21:03 -0700 | [diff] [blame] | 1149 | 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 Kandula | dbc8aed | 2017-03-24 14:43:16 -0700 | [diff] [blame] | 1162 | 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 | |
| 1167 | void 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 Balachandran | 2fd2426 | 2018-11-09 16:03:41 -0500 | [diff] [blame^] | 1174 | void HWDeviceDRM::ClearSolidfillStages() { |
| 1175 | solid_fills_.clear(); |
| 1176 | SetSolidfillStages(); |
| 1177 | } |
| 1178 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1179 | DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) { |
| 1180 | DTRACE_SCOPED(); |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1181 | |
Saurabh Shah | 4d4f400 | 2017-12-26 12:42:59 -0800 | [diff] [blame] | 1182 | DisplayError err = kErrorNone; |
| 1183 | registry_.Register(hw_layers); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1184 | SetupAtomic(hw_layers, true /* validate */); |
| 1185 | |
| 1186 | int ret = drm_atomic_intf_->Validate(); |
| 1187 | if (ret) { |
Ramkumar Radhakrishnan | 7e971e0 | 2017-08-17 14:19:15 +0530 | [diff] [blame] | 1188 | DLOGE("failed with error %d for %s", ret, device_name_); |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1189 | vrefresh_ = 0; |
Saurabh Shah | 4d4f400 | 2017-12-26 12:42:59 -0800 | [diff] [blame] | 1190 | err = kErrorHardware; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1191 | } |
| 1192 | |
Saurabh Shah | 4d4f400 | 2017-12-26 12:42:59 -0800 | [diff] [blame] | 1193 | return err; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1194 | } |
| 1195 | |
| 1196 | DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) { |
| 1197 | DTRACE_SCOPED(); |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1198 | |
| 1199 | DisplayError err = kErrorNone; |
Saurabh Shah | 4d4f400 | 2017-12-26 12:42:59 -0800 | [diff] [blame] | 1200 | registry_.Register(hw_layers); |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1201 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1202 | if (default_mode_) { |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1203 | err = DefaultCommit(hw_layers); |
| 1204 | } else { |
| 1205 | err = AtomicCommit(hw_layers); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1206 | } |
| 1207 | |
Saurabh Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1208 | return err; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1209 | } |
| 1210 | |
| 1211 | DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) { |
| 1212 | DTRACE_SCOPED(); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1213 | |
| 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 Chauhan | abc5b27 | 2018-06-20 16:18:13 -0700 | [diff] [blame] | 1248 | 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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1250 | ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id, |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1251 | 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 Shah | f84c412 | 2017-04-07 10:34:40 -0700 | [diff] [blame] | 1254 | fb_id, crtc_id, connector_id, strerror(errno)); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1255 | return kErrorHardware; |
| 1256 | } |
| 1257 | |
| 1258 | return kErrorNone; |
| 1259 | } |
| 1260 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1261 | DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) { |
| 1262 | DTRACE_SCOPED(); |
| 1263 | SetupAtomic(hw_layers, false /* validate */); |
| 1264 | |
Ramkumar Radhakrishnan | f985d48 | 2018-07-23 18:10:41 -0700 | [diff] [blame] | 1265 | int ret = drm_atomic_intf_->Commit(synchronous_commit_, false /* retain_planes*/); |
Varun Arora | f182bfa | 2018-08-14 10:49:08 -0700 | [diff] [blame] | 1266 | int release_fence = INT(release_fence_); |
| 1267 | int retire_fence = INT(retire_fence_); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1268 | if (ret) { |
Mahesh Aia | 1d2ceda | 2017-03-24 11:07:31 -0700 | [diff] [blame] | 1269 | DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id); |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1270 | vrefresh_ = 0; |
Varun Arora | f182bfa | 2018-08-14 10:49:08 -0700 | [diff] [blame] | 1271 | CloseFd(&release_fence); |
| 1272 | CloseFd(&retire_fence); |
| 1273 | release_fence_ = -1; |
| 1274 | retire_fence_ = -1; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1275 | return kErrorHardware; |
| 1276 | } |
| 1277 | |
Varun Arora | 006e3a1 | 2018-04-20 17:09:35 -0700 | [diff] [blame] | 1278 | DLOGD_IF(kTagDriverConfig, "RELEASE fence created: fd:%d", release_fence); |
| 1279 | DLOGD_IF(kTagDriverConfig, "RETIRE fence created: fd:%d", retire_fence); |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1280 | |
| 1281 | HWLayersInfo &hw_layer_info = hw_layers->info; |
| 1282 | LayerStack *stack = hw_layer_info.stack; |
| 1283 | stack->retire_fence_fd = retire_fence; |
| 1284 | |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 1285 | 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 Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 1288 | if (hw_rotator_session->mode == kRotatorOffline) { |
Saurabh Shah | a228f12 | 2017-01-23 15:55:25 -0800 | [diff] [blame] | 1289 | 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1293 | } |
| 1294 | |
| 1295 | hw_layer_info.sync_handle = release_fence; |
| 1296 | |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1297 | if (vrefresh_) { |
| 1298 | // Update current mode index if refresh rate is changed |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 1299 | drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode; |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1300 | for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) { |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 1301 | 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 Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1304 | current_mode_index_ = mode_index; |
| 1305 | break; |
| 1306 | } |
| 1307 | } |
| 1308 | vrefresh_ = 0; |
| 1309 | } |
| 1310 | |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 1311 | first_cycle_ = false; |
Sushil Chauhan | 93c892c | 2018-05-11 17:15:37 -0700 | [diff] [blame] | 1312 | update_mode_ = false; |
Ramkumar Radhakrishnan | ee0aab2 | 2017-10-16 16:11:18 -0700 | [diff] [blame] | 1313 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1314 | return kErrorNone; |
| 1315 | } |
| 1316 | |
Pullakavi Srinivas | 0a1dba6 | 2018-07-02 15:49:11 +0530 | [diff] [blame] | 1317 | DisplayError HWDeviceDRM::Flush(HWLayers *hw_layers) { |
Tharaga Balachandran | 2fd2426 | 2018-11-09 16:03:41 -0500 | [diff] [blame^] | 1318 | ClearSolidfillStages(); |
Ramkumar Radhakrishnan | a38b760 | 2018-03-15 14:49:52 -0700 | [diff] [blame] | 1319 | int ret = NullCommit(secure_display_active_ /* synchronous */, false /* retain_planes*/); |
Saurabh Shah | b595315 | 2017-04-12 14:02:50 -0700 | [diff] [blame] | 1320 | if (ret) { |
| 1321 | DLOGE("failed with error %d", ret); |
| 1322 | return kErrorHardware; |
| 1323 | } |
| 1324 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1325 | return kErrorNone; |
| 1326 | } |
| 1327 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1328 | void 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1341 | } |
| 1342 | } |
| 1343 | |
Ramkumar Radhakrishnan | 0751f87 | 2017-11-09 15:56:10 -0800 | [diff] [blame] | 1344 | void 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 Kandula | 585aa65 | 2017-01-26 18:39:11 -0800 | [diff] [blame] | 1351 | } |
| 1352 | } |
| 1353 | |
Ping Li | 8d6dd62 | 2017-07-03 12:05:15 -0700 | [diff] [blame] | 1354 | void 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1382 | void 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1387 | } |
| 1388 | |
Rohit Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 1389 | void 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 Kulkarni | a93babb | 2017-08-09 17:06:06 -0700 | [diff] [blame] | 1399 | if (mode == kRotatorInline && transform.rotation == 90) { |
Rohit Kulkarni | 8622e36 | 2017-01-30 18:14:10 -0800 | [diff] [blame] | 1400 | // 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1419 | bool HWDeviceDRM::EnableHotPlugDetection(int enable) { |
| 1420 | return true; |
| 1421 | } |
| 1422 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1423 | DisplayError HWDeviceDRM::SetCursorPosition(HWLayers *hw_layers, int x, int y) { |
| 1424 | DTRACE_SCOPED(); |
| 1425 | return kErrorNone; |
| 1426 | } |
| 1427 | |
| 1428 | DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) { |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1429 | struct DRMPPFeatureInfo info = {}; |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1430 | |
| 1431 | if (!hw_color_mgr_) |
| 1432 | return kErrorNotSupported; |
| 1433 | |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1434 | for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) { |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1435 | std::vector<DRMPPFeatureID> drm_id = {}; |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1436 | memset(&info, 0, sizeof(struct DRMPPFeatureInfo)); |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1437 | hw_color_mgr_->ToDrmFeatureId(kDSPP, i, &drm_id); |
| 1438 | if (drm_id.empty()) |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1439 | continue; |
Saurabh Shah | 1632918 | 2018-02-23 12:26:20 -0800 | [diff] [blame] | 1440 | |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1441 | info.id = drm_id.at(0); |
| 1442 | |
Saurabh Shah | 1632918 | 2018-02-23 12:26:20 -0800 | [diff] [blame] | 1443 | drm_mgr_intf_->GetCrtcPPInfo(token_.crtc_id, &info); |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1444 | vers->version[i] = hw_color_mgr_->GetFeatureVersion(info); |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1445 | } |
| 1446 | return kErrorNone; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1447 | } |
| 1448 | |
| 1449 | DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) { |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1450 | int ret = 0; |
| 1451 | PPFeatureInfo *feature = NULL; |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1452 | |
| 1453 | if (!hw_color_mgr_) |
| 1454 | return kErrorNotSupported; |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1455 | |
| 1456 | while (true) { |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1457 | std::vector<DRMPPFeatureID> drm_id = {}; |
| 1458 | DRMPPFeatureInfo kernel_params = {}; |
| 1459 | bool crtc_feature = true; |
| 1460 | |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1461 | ret = feature_list->RetrieveNextFeature(&feature); |
| 1462 | if (ret) |
| 1463 | break; |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1464 | |
| 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 Anandan | 739faf9 | 2017-07-21 12:32:00 -0700 | [diff] [blame] | 1470 | drm_mgr_intf_->GetCrtcPPInfo(token_.crtc_id, &kernel_params); |
| 1471 | if (kernel_params.version == std::numeric_limits<uint32_t>::max()) |
Ping Li | 13c5ea1 | 2018-05-14 13:31:17 -0700 | [diff] [blame] | 1472 | crtc_feature = false; |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1473 | if (feature) { |
| 1474 | DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_); |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1475 | for (DRMPPFeatureID id : drm_id) { |
Ping Li | 13c5ea1 | 2018-05-14 13:31:17 -0700 | [diff] [blame] | 1476 | if (id >= kPPFeaturesMax) { |
| 1477 | DLOGE("Invalid feature id %d", id); |
| 1478 | continue; |
| 1479 | } |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1480 | 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 Yadav | d30b0cc | 2017-09-22 00:26:54 +0530 | [diff] [blame] | 1488 | |
Rajesh Yadav | c4f67b8 | 2017-11-15 20:37:13 +0530 | [diff] [blame] | 1489 | hw_color_mgr_->FreeDrmFeatureData(&kernel_params); |
Rajesh Yadav | d30b0cc | 2017-09-22 00:26:54 +0530 | [diff] [blame] | 1490 | } |
Ping Li | 281f48d | 2017-01-16 12:45:40 -0800 | [diff] [blame] | 1491 | } |
| 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1498 | } |
| 1499 | |
| 1500 | DisplayError HWDeviceDRM::SetVSyncState(bool enable) { |
Saurabh Shah | 7171af5 | 2017-05-02 17:03:26 -0700 | [diff] [blame] | 1501 | return kErrorNotSupported; |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1502 | } |
| 1503 | |
Anjaneya Prasad Musunuri | e8c67f2 | 2017-07-01 16:16:13 +0530 | [diff] [blame] | 1504 | void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) { |
| 1505 | // TODO(user): This function can be removed after fb is deprecated |
| 1506 | } |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1507 | |
| 1508 | DisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) { |
| 1509 | return kErrorNotSupported; |
| 1510 | } |
| 1511 | |
| 1512 | DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) { |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1513 | // Check if requested refresh rate is valid |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 1514 | drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode; |
Anjaneya Prasad Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1515 | for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) { |
Saurabh Shah | 7e16c93 | 2017-11-03 17:55:36 -0700 | [diff] [blame] | 1516 | 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 Musunuri | cbefdc4 | 2017-06-13 16:10:19 +0530 | [diff] [blame] | 1519 | vrefresh_ = refresh_rate; |
| 1520 | DLOGV_IF(kTagDriverConfig, "Set refresh rate to %d", refresh_rate); |
| 1521 | return kErrorNone; |
| 1522 | } |
| 1523 | } |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1524 | return kErrorNotSupported; |
| 1525 | } |
| 1526 | |
| 1527 | DisplayError HWDeviceDRM::SetPanelBrightness(int level) { |
Saurabh Shah | 8b021cf | 2017-03-14 12:16:43 -0700 | [diff] [blame] | 1528 | 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 | |
| 1552 | DisplayError 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1579 | } |
| 1580 | |
| 1581 | DisplayError HWDeviceDRM::GetHWScanInfo(HWScanInfo *scan_info) { |
| 1582 | return kErrorNotSupported; |
| 1583 | } |
| 1584 | |
| 1585 | DisplayError HWDeviceDRM::GetVideoFormat(uint32_t config_index, uint32_t *video_format) { |
| 1586 | return kErrorNotSupported; |
| 1587 | } |
| 1588 | |
| 1589 | DisplayError HWDeviceDRM::GetMaxCEAFormat(uint32_t *max_cea_format) { |
| 1590 | return kErrorNotSupported; |
| 1591 | } |
| 1592 | |
| 1593 | DisplayError HWDeviceDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) { |
| 1594 | return kErrorNotSupported; |
| 1595 | } |
| 1596 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1597 | DisplayError HWDeviceDRM::SetS3DMode(HWS3DMode s3d_mode) { |
| 1598 | return kErrorNotSupported; |
| 1599 | } |
| 1600 | |
| 1601 | DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) { |
Saurabh Shah | 0ffee30 | 2016-11-22 10:42:11 -0800 | [diff] [blame] | 1602 | 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1611 | return kErrorNone; |
| 1612 | } |
| 1613 | |
Varun Arora | baa1647 | 2018-08-16 16:19:59 -0700 | [diff] [blame] | 1614 | DisplayError HWDeviceDRM::UnsetScaleLutConfig() { |
| 1615 | drm_mgr_intf_->UnsetScalerLUT(); |
| 1616 | |
| 1617 | return kErrorNone; |
| 1618 | } |
| 1619 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1620 | DisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) { |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1621 | if (IsResolutionSwitchEnabled()) { |
| 1622 | return kErrorNotSupported; |
| 1623 | } |
| 1624 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1625 | if (!hw_resource_.hw_dest_scalar_info.count) { |
| 1626 | return kErrorNotSupported; |
| 1627 | } |
| 1628 | |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1629 | 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1633 | DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d", |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1634 | mixer_attributes.width, mixer_attributes.height, display_attributes_[index].x_pixels, |
| 1635 | display_attributes_[index].y_pixels); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1636 | return kErrorNotSupported; |
| 1637 | } |
| 1638 | |
| 1639 | uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width; |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1640 | if (display_attributes_[index].is_device_split) { |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1641 | 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1652 | FLOAT(display_attributes_[index].x_pixels) / FLOAT(display_attributes_[index].y_pixels); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1653 | |
| 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1656 | mixer_attributes.height, display_attributes_[index].x_pixels, |
| 1657 | display_attributes_[index].y_pixels); |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1658 | return kErrorNotSupported; |
| 1659 | } |
| 1660 | |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1661 | 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1663 | 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1665 | 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1669 | 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 Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1676 | if (display_attributes_[index].is_device_split) { |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1677 | mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio); |
| 1678 | } |
| 1679 | |
| 1680 | return kErrorNone; |
| 1681 | } |
| 1682 | |
| 1683 | DisplayError HWDeviceDRM::GetMixerAttributes(HWMixerAttributes *mixer_attributes) { |
| 1684 | if (!mixer_attributes) { |
| 1685 | return kErrorParameters; |
| 1686 | } |
| 1687 | |
Saurabh Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1688 | *mixer_attributes = mixer_attributes_; |
| 1689 | |
| 1690 | return kErrorNone; |
| 1691 | } |
| 1692 | |
Varun Arora | 7c8ee54 | 2018-05-01 20:58:16 -0700 | [diff] [blame] | 1693 | DisplayError HWDeviceDRM::DumpDebugData() { |
Varun Arora | eaefa47 | 2018-05-21 13:20:20 -0700 | [diff] [blame] | 1694 | string dir_path = "/data/vendor/display/hw_recovery/"; |
Varun Arora | 7c8ee54 | 2018-05-01 20:58:16 -0700 | [diff] [blame] | 1695 | string device_str = device_name_; |
Varun Arora | 7c8ee54 | 2018-05-01 20:58:16 -0700 | [diff] [blame] | 1696 | |
Varun Arora | eaefa47 | 2018-05-21 13:20:20 -0700 | [diff] [blame] | 1697 | // 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 Arora | 7c8ee54 | 2018-05-01 20:58:16 -0700 | [diff] [blame] | 1711 | ifstream src; |
Varun Arora | eaefa47 | 2018-05-21 13:20:20 -0700 | [diff] [blame] | 1712 | debug_dump_count_++; |
Varun Arora | 7c8ee54 | 2018-05-01 20:58:16 -0700 | [diff] [blame] | 1713 | |
| 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 Arora | eaefa47 | 2018-05-21 13:20:20 -0700 | [diff] [blame] | 1735 | |
| 1736 | DLOGI("Wrote hw_recovery file %s", filename.c_str()); |
Varun Arora | 7c8ee54 | 2018-05-01 20:58:16 -0700 | [diff] [blame] | 1737 | |
| 1738 | return kErrorNone; |
| 1739 | } |
| 1740 | |
Anjaneya Prasad Musunuri | e250e67 | 2017-05-22 14:16:20 +0530 | [diff] [blame] | 1741 | void HWDeviceDRM::GetDRMDisplayToken(sde_drm::DRMDisplayToken *token) const { |
Saurabh Shah | f822671 | 2018-02-05 15:51:53 -0800 | [diff] [blame] | 1742 | *token = token_; |
Anjaneya Prasad Musunuri | e250e67 | 2017-05-22 14:16:20 +0530 | [diff] [blame] | 1743 | } |
| 1744 | |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1745 | void HWDeviceDRM::UpdateMixerAttributes() { |
Saurabh Shah | 8c9c00c | 2017-04-17 16:52:49 -0700 | [diff] [blame] | 1746 | 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 Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1751 | ? hw_panel_info_.split_info.left_split |
| 1752 | : mixer_attributes_.width; |
Ramkumar Radhakrishnan | 7e971e0 | 2017-08-17 14:19:15 +0530 | [diff] [blame] | 1753 | DLOGI("Mixer WxH %dx%d for %s", mixer_attributes_.width, mixer_attributes_.height, device_name_); |
Varun Arora | ebf52a6 | 2018-08-24 16:51:34 -0700 | [diff] [blame] | 1754 | update_mode_ = true; |
Saurabh Shah | 66c941b | 2016-07-06 17:34:05 -0700 | [diff] [blame] | 1755 | } |
| 1756 | |
Sushil Chauhan | 1021cc0 | 2017-05-03 15:11:43 -0700 | [diff] [blame] | 1757 | void 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 Chauhan | 1fc8b84 | 2017-08-21 18:40:29 -0700 | [diff] [blame] | 1769 | // IOMMU configuration for this framebuffer mode is secure domain & requires |
Sushil Chauhan | 1021cc0 | 2017-05-03 15:11:43 -0700 | [diff] [blame] | 1770 | // only stage II translation, when this buffer is accessed by Display H/W. |
| 1771 | // Only secure planes can be attached to this CRTC. |
Sushil Chauhan | 1fc8b84 | 2017-08-21 18:40:29 -0700 | [diff] [blame] | 1772 | *fb_secure_mode = DRMSecureMode::SECURE_DIR_TRANSLATION; |
Sushil Chauhan | 1021cc0 | 2017-05-03 15:11:43 -0700 | [diff] [blame] | 1773 | *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 Radhakrishnan | 0563371 | 2017-09-01 11:35:29 -0700 | [diff] [blame] | 1783 | void 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.R | c033f94 | 2018-01-05 12:25:47 +0530 | [diff] [blame] | 1797 | |
Ramkumar Radhakrishnan | 0725430 | 2017-11-13 16:18:22 -0800 | [diff] [blame] | 1798 | void 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.R | c033f94 | 2018-01-05 12:25:47 +0530 | [diff] [blame] | 1808 | void 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 | |
| 1826 | void HWDeviceDRM::SetDGMCsc(const HWPipeCscInfo &dgm_csc_info, SDECsc *csc) { |
| 1827 | SetDGMCscV1(dgm_csc_info.csc, &csc->csc_v1); |
| 1828 | } |
| 1829 | |
| 1830 | void 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 | |
| 1846 | void 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 Li | 13c5ea1 | 2018-05-14 13:31:17 -0700 | [diff] [blame] | 1859 | if (id >= kPPFeaturesMax) { |
| 1860 | DLOGE("Invalid feature id %d", id); |
| 1861 | continue; |
| 1862 | } |
Arun Kumar K.R | c033f94 | 2018-01-05 12:25:47 +0530 | [diff] [blame] | 1863 | 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 Radhakrishnan | a38b760 | 2018-03-15 14:49:52 -0700 | [diff] [blame] | 1882 | void 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 | |
| 1893 | DisplayError 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 Chauhan | 0652158 | 2018-03-19 14:00:23 -0700 | [diff] [blame] | 1905 | void 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 Radhakrishnan | 3dcf8a2 | 2017-11-27 14:53:06 -0800 | [diff] [blame] | 1917 | void 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 Shah | 7d476ed | 2016-06-27 16:40:58 -0700 | [diff] [blame] | 1930 | } // namespace sdm |