blob: f3caca7b68e0ac19f3a699d8a03a28b885961104 [file] [log] [blame]
Gousemoodhin Nadaf2e3eb3f2018-12-12 15:25:22 +05301/*
2* Copyright (c) 2019, The Linux Foundation. All rights reserved.
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above
10* copyright notice, this list of conditions and the following
11* disclaimer in the documentation and/or other materials provided
12* with the distribution.
13* * Neither the name of The Linux Foundation nor the names of its
14* contributors may be used to endorse or promote products derived
15* from this software without specific prior written permission.
16
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <drm_logger.h>
31
32#include "drm_atomic_req.h"
33#include "drm_connector.h"
34#include "drm_crtc.h"
35#include "drm_manager.h"
36#include "drm_plane.h"
37#include "string.h"
38
39#define __CLASS__ "DRMAtomicReq"
40
41namespace sde_drm {
42
43DRMAtomicReq::DRMAtomicReq(int fd, DRMManager *drm_mgr) : drm_mgr_(drm_mgr), fd_(fd) {}
44
45DRMAtomicReq::~DRMAtomicReq() {
46 if (drm_atomic_req_) {
47 drmModeAtomicFree(drm_atomic_req_);
48 drm_atomic_req_ = nullptr;
49 }
50}
51
52int DRMAtomicReq::Init(const DRMDisplayToken &tok) {
53 token_ = tok;
54 drm_atomic_req_ = drmModeAtomicAlloc();
55 if (!drm_atomic_req_) {
56 return -ENOMEM;
57 }
58
59 return 0;
60}
61
62int DRMAtomicReq::Perform(DRMOps opcode, uint32_t obj_id, ...) {
63 va_list args;
64 va_start(args, obj_id);
65 switch (opcode) {
66 case DRMOps::PLANE_SET_SRC_RECT:
67 case DRMOps::PLANE_SET_DST_RECT:
68 case DRMOps::PLANE_SET_ZORDER:
69 case DRMOps::PLANE_SET_ROTATION:
70 case DRMOps::PLANE_SET_ALPHA:
71 case DRMOps::PLANE_SET_BLEND_TYPE:
72 case DRMOps::PLANE_SET_H_DECIMATION:
73 case DRMOps::PLANE_SET_V_DECIMATION:
74 case DRMOps::PLANE_SET_FB_ID:
75 case DRMOps::PLANE_SET_ROT_FB_ID:
76 case DRMOps::PLANE_SET_CRTC:
77 case DRMOps::PLANE_SET_SRC_CONFIG:
78 case DRMOps::PLANE_SET_INPUT_FENCE:
79 case DRMOps::PLANE_SET_SCALER_CONFIG:
80 case DRMOps::PLANE_SET_FB_SECURE_MODE:
81 case DRMOps::PLANE_SET_CSC_CONFIG:
82 case DRMOps::PLANE_SET_MULTIRECT_MODE:
83 case DRMOps::PLANE_SET_EXCL_RECT:
84 case DRMOps::PLANE_SET_INVERSE_PMA:
85 case DRMOps::PLANE_SET_DGM_CSC_CONFIG:
86 case DRMOps::PLANE_SET_POST_PROC: {
87 drm_mgr_->GetPlaneMgr()->Perform(opcode, obj_id, drm_atomic_req_, args);
88 } break;
89 case DRMOps::CRTC_SET_POST_PROC:
90 case DRMOps::CRTC_SET_MODE:
91 case DRMOps::CRTC_SET_ACTIVE:
92 case DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET:
93 case DRMOps::CRTC_SET_CORE_CLK:
94 case DRMOps::CRTC_SET_CORE_AB:
95 case DRMOps::CRTC_SET_CORE_IB:
96 case DRMOps::CRTC_SET_LLCC_AB:
97 case DRMOps::CRTC_SET_LLCC_IB:
98 case DRMOps::CRTC_SET_DRAM_AB:
99 case DRMOps::CRTC_SET_DRAM_IB:
100 case DRMOps::CRTC_SET_ROT_PREFILL_BW:
101 case DRMOps::CRTC_SET_ROT_CLK:
102 case DRMOps::CRTC_GET_RELEASE_FENCE:
103 case DRMOps::CRTC_SET_ROI:
104 case DRMOps::CRTC_SET_SECURITY_LEVEL:
105 case DRMOps::CRTC_SET_SOLIDFILL_STAGES:
106 case DRMOps::CRTC_SET_IDLE_TIMEOUT:
107 case DRMOps::CRTC_SET_DEST_SCALER_CONFIG:
108 case DRMOps::CRTC_SET_CAPTURE_MODE:
109 case DRMOps::CRTC_SET_IDLE_PC_STATE: {
110 drm_mgr_->GetCrtcMgr()->Perform(opcode, obj_id, drm_atomic_req_, args);
111 } break;
112 case DRMOps::CONNECTOR_SET_CRTC:
113 case DRMOps::CONNECTOR_GET_RETIRE_FENCE:
114 case DRMOps::CONNECTOR_SET_OUTPUT_RECT:
115 case DRMOps::CONNECTOR_SET_OUTPUT_FB_ID:
116 case DRMOps::CONNECTOR_SET_POWER_MODE:
117 case DRMOps::CONNECTOR_SET_ROI:
118 case DRMOps::CONNECTOR_SET_AUTOREFRESH:
119 case DRMOps::CONNECTOR_SET_FB_SECURE_MODE:
120 case DRMOps::CONNECTOR_SET_POST_PROC:
121 case DRMOps::CONNECTOR_SET_HDR_METADATA:
122 case DRMOps::CONNECTOR_SET_QSYNC_MODE:
Xu Yang39503f12018-12-24 17:43:36 +0800123 case DRMOps::CONNECTOR_SET_TOPOLOGY_CONTROL:
Gousemoodhin Nadaf47b82be2019-05-09 15:30:11 +0530124 case DRMOps::CONNECTOR_SET_FRAME_TRIGGER:
125 case DRMOps::CONNECTOR_SET_COLORSPACE: {
Gousemoodhin Nadaf2e3eb3f2018-12-12 15:25:22 +0530126 drm_mgr_->GetConnectorMgr()->Perform(opcode, obj_id, drm_atomic_req_, args);
127 } break;
128 case DRMOps::DPPS_CACHE_FEATURE: {
129 drm_mgr_->GetDppsMgrIntf()->CacheDppsFeature(obj_id, args);
130 } break;
131 case DRMOps::DPPS_COMMIT_FEATURE: {
132 drm_mgr_->GetDppsMgrIntf()->CommitDppsFeatures(drm_atomic_req_, token_);
133 } break;
134 default:
135 DRM_LOGE("Invalid opcode %d", opcode);
136 }
137 va_end(args);
138 return 0;
139}
140
141int DRMAtomicReq::Validate() {
142 // Call UnsetUnusedPlanes to find planes that need to be unset. Do not call CommitPlaneState,
143 // because we just want to validate, not actually mark planes as removed
144 drm_mgr_->GetPlaneMgr()->UnsetUnusedPlanes(token_.crtc_id, drm_atomic_req_);
145 int ret = drmModeAtomicCommit(fd_, drm_atomic_req_,
146 DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_TEST_ONLY, nullptr);
147 if (ret) {
148 DRM_LOGE("drmModeAtomicCommit failed with error %d (%s).", errno, strerror(errno));
149 }
150
151 drm_mgr_->GetPlaneMgr()->PostValidate(token_.crtc_id, !ret);
152 drm_mgr_->GetCrtcMgr()->PostValidate(token_.crtc_id, !ret);
153 drmModeAtomicSetCursor(drm_atomic_req_, 0);
154
155 return ret;
156}
157
158int DRMAtomicReq::Commit(bool synchronous, bool retain_planes) {
Gurpreet Singh Dhami156211c2019-04-25 17:14:14 -0400159 DTRACE_SCOPED();
Gousemoodhin Nadaf2e3eb3f2018-12-12 15:25:22 +0530160 if (retain_planes) {
161 // It is not enough to simply avoid calling UnsetUnusedPlanes, since state transitons have to
162 // be correct when CommitPlaneState is called
163 drm_mgr_->GetPlaneMgr()->RetainPlanes(token_.crtc_id);
164 }
165
166 drm_mgr_->GetPlaneMgr()->UnsetUnusedPlanes(token_.crtc_id, drm_atomic_req_);
167 uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
168
169 if (!synchronous) {
170 flags |= DRM_MODE_ATOMIC_NONBLOCK;
171 }
172
173 int ret = drmModeAtomicCommit(fd_, drm_atomic_req_, flags, nullptr);
174 if (ret) {
175 DRM_LOGE("drmModeAtomicCommit failed with error %d (%s).", errno, strerror(errno));
176 }
177
178 drm_mgr_->GetPlaneMgr()->PostCommit(token_.crtc_id, !ret);
179 drm_mgr_->GetCrtcMgr()->PostCommit(token_.crtc_id, !ret);
180 drmModeAtomicSetCursor(drm_atomic_req_, 0);
181
182 return ret;
183}
184
185} // namespace sde_drm