1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "drm_connector.h" 17094332d3Sopenharmony_ci#include <xf86drm.h> 18094332d3Sopenharmony_ci#include <xf86drmMode.h> 19094332d3Sopenharmony_ci#include <cinttypes> 20094332d3Sopenharmony_ci#include <securec.h> 21094332d3Sopenharmony_ci#include "display_log.h" 22094332d3Sopenharmony_ci#include "drm_device.h" 23094332d3Sopenharmony_ci#include "drm_vsync_worker.h" 24094332d3Sopenharmony_ci 25094332d3Sopenharmony_cinamespace OHOS { 26094332d3Sopenharmony_cinamespace HDI { 27094332d3Sopenharmony_cinamespace DISPLAY { 28094332d3Sopenharmony_civoid DrmMode::ConvertToHdiMode(DisplayModeInfo &hdiMode) 29094332d3Sopenharmony_ci{ 30094332d3Sopenharmony_ci hdiMode.height = mModeInfo.vdisplay; 31094332d3Sopenharmony_ci hdiMode.width = mModeInfo.hdisplay; 32094332d3Sopenharmony_ci hdiMode.freshRate = mModeInfo.vrefresh; 33094332d3Sopenharmony_ci hdiMode.id = mId; 34094332d3Sopenharmony_ci} 35094332d3Sopenharmony_ci 36094332d3Sopenharmony_ciDrmConnector::DrmConnector(drmModeConnector c, FdPtr &fd) 37094332d3Sopenharmony_ci : mId(c.connector_id), 38094332d3Sopenharmony_ci mPhyWidth(c.mmWidth), 39094332d3Sopenharmony_ci mPhyHeight(c.mmHeight), 40094332d3Sopenharmony_ci mEncoderId(c.encoder_id), 41094332d3Sopenharmony_ci mConnectState(c.connection), 42094332d3Sopenharmony_ci mDrmFdPtr(fd) 43094332d3Sopenharmony_ci{ 44094332d3Sopenharmony_ci DISPLAY_LOGD("encoder_id %{public}d", mEncoderId); 45094332d3Sopenharmony_ci DISPLAY_LOGD("the connect state is %{public}d", mConnectState); 46094332d3Sopenharmony_ci 47094332d3Sopenharmony_ci for (int i = 0; i < c.count_encoders; i++) { 48094332d3Sopenharmony_ci mPossibleEncoders.push_back(c.encoders[i]); 49094332d3Sopenharmony_ci DISPLAY_LOGD("add possible encoder id %{public}d", c.encoders[i]); 50094332d3Sopenharmony_ci } 51094332d3Sopenharmony_ci 52094332d3Sopenharmony_ci ConvertToHdiType(c.connector_type, mType); 53094332d3Sopenharmony_ci ConvertTypeToName(mType, mName); 54094332d3Sopenharmony_ci InitModes(c); 55094332d3Sopenharmony_ci DISPLAY_LOGD("name %{public}s", mName.c_str()); 56094332d3Sopenharmony_ci} 57094332d3Sopenharmony_ci 58094332d3Sopenharmony_civoid DrmConnector::InitModes(drmModeConnector c) 59094332d3Sopenharmony_ci{ 60094332d3Sopenharmony_ci DISPLAY_LOGD("id %{public}d mode size %{public}d", mId, c.count_modes); 61094332d3Sopenharmony_ci mModes.clear(); 62094332d3Sopenharmony_ci mPreferenceId = INVALID_MODE_ID; 63094332d3Sopenharmony_ci for (int i = 0; i < c.count_modes; i++) { 64094332d3Sopenharmony_ci drmModeModeInfoPtr mode = c.modes + i; 65094332d3Sopenharmony_ci DISPLAY_LOGD("mode: hdisplay %{public}d, vdisplay %{public}d vrefresh %{public}d type %{public}d", 66094332d3Sopenharmony_ci mode->hdisplay, mode->vdisplay, mode->vrefresh, mode->type); 67094332d3Sopenharmony_ci if ((mPreferenceId == INVALID_MODE_ID) && (mode->type & DRM_MODE_TYPE_PREFERRED)) { 68094332d3Sopenharmony_ci DISPLAY_LOGD("set it to prefernce id %{public}d", i); 69094332d3Sopenharmony_ci mPreferenceId = i; 70094332d3Sopenharmony_ci } 71094332d3Sopenharmony_ci mModes.emplace(i, DrmMode { *mode, i }); 72094332d3Sopenharmony_ci } 73094332d3Sopenharmony_ci DISPLAY_LOGD("mode count %{public}zd", mModes.size()); 74094332d3Sopenharmony_ci} 75094332d3Sopenharmony_ci 76094332d3Sopenharmony_ciint32_t DrmConnector::Init(DrmDevice &drmDevice) 77094332d3Sopenharmony_ci{ 78094332d3Sopenharmony_ci int32_t ret; 79094332d3Sopenharmony_ci DrmProperty prop; 80094332d3Sopenharmony_ci DISPLAY_LOGD(); 81094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((mDrmFdPtr == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the mDrmFdPtr is nullptr")); 82094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((mDrmFdPtr->GetFd() == -1), DISPLAY_FAILURE, DISPLAY_LOGE("the drm fd is -1")); 83094332d3Sopenharmony_ci // find dpms prop 84094332d3Sopenharmony_ci ret = drmDevice.GetConnectorProperty(*this, PROP_DPMS, prop); 85094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not get mode prop id")); 86094332d3Sopenharmony_ci mPropDpmsId = prop.propId; 87094332d3Sopenharmony_ci mDpmsState = prop.value; 88094332d3Sopenharmony_ci DISPLAY_LOGD("dpms state : %{public}" PRIu64 "", mDpmsState); 89094332d3Sopenharmony_ci // find the crtcid 90094332d3Sopenharmony_ci ret = drmDevice.GetConnectorProperty(*this, PROP_CRTCID, prop); 91094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get out fence prop id")); 92094332d3Sopenharmony_ci mPropCrtcId = prop.propId; 93094332d3Sopenharmony_ci DISPLAY_LOGD("encoder_id %{public}d", mEncoderId); 94094332d3Sopenharmony_ci DISPLAY_LOGD("mPropCrtcId %{public}d", mPropCrtcId); 95094332d3Sopenharmony_ci // find the brightness 96094332d3Sopenharmony_ci ret = drmDevice.GetConnectorProperty(*this, PROP_BRIGHTNESS, prop); 97094332d3Sopenharmony_ci if (ret == DISPLAY_SUCCESS) { 98094332d3Sopenharmony_ci mPropBrightnessId = prop.propId; 99094332d3Sopenharmony_ci mBrightnessLevel = static_cast<uint32_t>(prop.value); 100094332d3Sopenharmony_ci DISPLAY_LOGD("prop brightness is %{public}d, level is %{public}d", mPropBrightnessId, mBrightnessLevel); 101094332d3Sopenharmony_ci } else { 102094332d3Sopenharmony_ci DISPLAY_LOGW("can not get the brightness prop, can not set the brightness"); 103094332d3Sopenharmony_ci } 104094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 105094332d3Sopenharmony_ci} 106094332d3Sopenharmony_ci 107094332d3Sopenharmony_ciint32_t DrmConnector::GetBrightness(uint32_t& level) 108094332d3Sopenharmony_ci{ 109094332d3Sopenharmony_ci if (mPropBrightnessId == DRM_INVALID_ID) { 110094332d3Sopenharmony_ci DISPLAY_LOGE("the prop id of brightness is invalid"); 111094332d3Sopenharmony_ci return DISPLAY_NOT_SUPPORT; 112094332d3Sopenharmony_ci } 113094332d3Sopenharmony_ci level = mBrightnessLevel; 114094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 115094332d3Sopenharmony_ci} 116094332d3Sopenharmony_ci 117094332d3Sopenharmony_ciint32_t DrmConnector::SetBrightness(uint32_t level) 118094332d3Sopenharmony_ci{ 119094332d3Sopenharmony_ci static int32_t brFd = 0; 120094332d3Sopenharmony_ci const int32_t buffer_size = 10; /* buffer size */ 121094332d3Sopenharmony_ci char buffer[buffer_size]; 122094332d3Sopenharmony_ci 123094332d3Sopenharmony_ci DISPLAY_LOGD("set %{public}d", level); 124094332d3Sopenharmony_ci if (mPropBrightnessId == DRM_INVALID_ID) { 125094332d3Sopenharmony_ci DISPLAY_LOGE("the prop id of brightness is invalid"); 126094332d3Sopenharmony_ci return DISPLAY_NOT_SUPPORT; 127094332d3Sopenharmony_ci } 128094332d3Sopenharmony_ci if (brFd <= 0) { 129094332d3Sopenharmony_ci brFd = open("/sys/class/backlight/backlight/brightness", O_RDWR); 130094332d3Sopenharmony_ci if (brFd < 0) { 131094332d3Sopenharmony_ci DISPLAY_LOGE("open brightness file failed\n"); 132094332d3Sopenharmony_ci return DISPLAY_NOT_SUPPORT; 133094332d3Sopenharmony_ci } 134094332d3Sopenharmony_ci } 135094332d3Sopenharmony_ci errno_t ret = memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); 136094332d3Sopenharmony_ci if (ret != EOK) { 137094332d3Sopenharmony_ci DISPLAY_LOGE("memset_s failed\n"); 138094332d3Sopenharmony_ci return DISPLAY_FAILURE; 139094332d3Sopenharmony_ci } 140094332d3Sopenharmony_ci int bytes = sprintf_s(buffer, sizeof(buffer), "%d\n", level); 141094332d3Sopenharmony_ci if (bytes < 0) { 142094332d3Sopenharmony_ci DISPLAY_LOGE("change failed\n"); 143094332d3Sopenharmony_ci return DISPLAY_FAILURE; 144094332d3Sopenharmony_ci } 145094332d3Sopenharmony_ci write(brFd, buffer, bytes); 146094332d3Sopenharmony_ci mBrightnessLevel = level; 147094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 148094332d3Sopenharmony_ci} 149094332d3Sopenharmony_ci 150094332d3Sopenharmony_civoid DrmConnector::GetDisplayCap(DisplayCapability &cap) 151094332d3Sopenharmony_ci{ 152094332d3Sopenharmony_ci cap.phyHeight = mPhyHeight; 153094332d3Sopenharmony_ci cap.phyWidth = mPhyWidth; 154094332d3Sopenharmony_ci cap.type = mType; 155094332d3Sopenharmony_ci memcpy_s(const_cast<char*>(cap.name.c_str()), cap.name.size(), mName.c_str(), mName.size()); 156094332d3Sopenharmony_ci if (mName.size() >= sizeof(cap.name)) { 157094332d3Sopenharmony_ci cap.name[sizeof(cap.name) - 1] = 0; 158094332d3Sopenharmony_ci } else { 159094332d3Sopenharmony_ci cap.name[mName.size()] = 0; 160094332d3Sopenharmony_ci } 161094332d3Sopenharmony_ci cap.supportLayers = mSupportLayers; 162094332d3Sopenharmony_ci cap.virtualDispCount = mVirtualDispCount; 163094332d3Sopenharmony_ci cap.supportWriteBack = mSupportWriteBack; 164094332d3Sopenharmony_ci cap.propertyCount = mPropertyCount; 165094332d3Sopenharmony_ci} 166094332d3Sopenharmony_ci 167094332d3Sopenharmony_civoid DrmConnector::ConvertTypeToName(uint32_t type, std::string &name) 168094332d3Sopenharmony_ci{ 169094332d3Sopenharmony_ci DISPLAY_LOGD("type %{public}d", type); 170094332d3Sopenharmony_ci switch (type) { 171094332d3Sopenharmony_ci case DISP_INTF_VGA: 172094332d3Sopenharmony_ci name = "VGA"; 173094332d3Sopenharmony_ci break; 174094332d3Sopenharmony_ci case DISP_INTF_HDMI: 175094332d3Sopenharmony_ci name = "HDMI"; 176094332d3Sopenharmony_ci break; 177094332d3Sopenharmony_ci case DISP_INTF_MIPI: 178094332d3Sopenharmony_ci name = "MIPI"; 179094332d3Sopenharmony_ci break; 180094332d3Sopenharmony_ci default: 181094332d3Sopenharmony_ci name = "Unknown"; 182094332d3Sopenharmony_ci break; 183094332d3Sopenharmony_ci } 184094332d3Sopenharmony_ci} 185094332d3Sopenharmony_ci 186094332d3Sopenharmony_civoid DrmConnector::ConvertToHdiType(uint32_t type, InterfaceType &hdiType) 187094332d3Sopenharmony_ci{ 188094332d3Sopenharmony_ci switch (type) { 189094332d3Sopenharmony_ci case DRM_MODE_CONNECTOR_VGA: 190094332d3Sopenharmony_ci hdiType = DISP_INTF_VGA; 191094332d3Sopenharmony_ci break; 192094332d3Sopenharmony_ci case DRM_MODE_CONNECTOR_DSI: 193094332d3Sopenharmony_ci hdiType = DISP_INTF_MIPI; 194094332d3Sopenharmony_ci break; 195094332d3Sopenharmony_ci case DRM_MODE_CONNECTOR_HDMIA: 196094332d3Sopenharmony_ci case DRM_MODE_CONNECTOR_HDMIB: 197094332d3Sopenharmony_ci hdiType = DISP_INTF_HDMI; 198094332d3Sopenharmony_ci break; 199094332d3Sopenharmony_ci default: 200094332d3Sopenharmony_ci hdiType = DISP_INTF_BUTT; 201094332d3Sopenharmony_ci break; 202094332d3Sopenharmony_ci } 203094332d3Sopenharmony_ci} 204094332d3Sopenharmony_ciint32_t DrmConnector::TryPickEncoder(IdMapPtr<DrmEncoder> &encoders, uint32_t encoderId, IdMapPtr<DrmCrtc> &crtcs, 205094332d3Sopenharmony_ci uint32_t &crtcId) 206094332d3Sopenharmony_ci{ 207094332d3Sopenharmony_ci int ret; 208094332d3Sopenharmony_ci auto encoderIter = encoders.find(encoderId); 209094332d3Sopenharmony_ci if (encoderIter == encoders.end()) { 210094332d3Sopenharmony_ci DISPLAY_LOGW("can not find encoder for id : %{public}d", encoderId); 211094332d3Sopenharmony_ci return DISPLAY_FAILURE; 212094332d3Sopenharmony_ci } 213094332d3Sopenharmony_ci 214094332d3Sopenharmony_ci auto &encoder = encoderIter->second; 215094332d3Sopenharmony_ci DISPLAY_LOGD("connector : %{public}d encoder : %{public}d", mId, encoder->GetId()); 216094332d3Sopenharmony_ci ret = encoder->PickIdleCrtcId(crtcs, crtcId); 217094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret == DISPLAY_SUCCESS), DISPLAY_SUCCESS, 218094332d3Sopenharmony_ci DISPLAY_LOGD("connector : %{public}d pick encoder : %{public}d", mId, encoder->GetId())); 219094332d3Sopenharmony_ci return DISPLAY_FAILURE; 220094332d3Sopenharmony_ci} 221094332d3Sopenharmony_ci 222094332d3Sopenharmony_ciint32_t DrmConnector::PickIdleCrtcId(IdMapPtr<DrmEncoder> &encoders, IdMapPtr<DrmCrtc> &crtcs, uint32_t &crtcId) 223094332d3Sopenharmony_ci{ 224094332d3Sopenharmony_ci DISPLAY_LOGD(); 225094332d3Sopenharmony_ci DISPLAY_LOGD("encoder_id %{public}d", mEncoderId); 226094332d3Sopenharmony_ci int ret = TryPickEncoder(encoders, mEncoderId, crtcs, crtcId); 227094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret == DISPLAY_SUCCESS), DISPLAY_SUCCESS, 228094332d3Sopenharmony_ci DISPLAY_LOGD("connector : %{public}d pick endcoder : %{public}d crtcId : %{public}d", 229094332d3Sopenharmony_ci mId, mEncoderId, crtcId)); 230094332d3Sopenharmony_ci 231094332d3Sopenharmony_ci for (auto encoder : mPossibleEncoders) { 232094332d3Sopenharmony_ci ret = TryPickEncoder(encoders, encoder, crtcs, crtcId); 233094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret == DISPLAY_SUCCESS), DISPLAY_SUCCESS, 234094332d3Sopenharmony_ci DISPLAY_LOGD("connector : %{public}d pick endcoder : %{public}d crtcId : %{public}d", mId, mEncoderId, 235094332d3Sopenharmony_ci crtcId)); 236094332d3Sopenharmony_ci } 237094332d3Sopenharmony_ci 238094332d3Sopenharmony_ci DISPLAY_LOGW("can not pick a crtc for connector"); 239094332d3Sopenharmony_ci return DISPLAY_FAILURE; 240094332d3Sopenharmony_ci} 241094332d3Sopenharmony_ci 242094332d3Sopenharmony_ciint32_t DrmConnector::UpdateModes() 243094332d3Sopenharmony_ci{ 244094332d3Sopenharmony_ci int drmFd = mDrmFdPtr->GetFd(); 245094332d3Sopenharmony_ci drmModeConnectorPtr c = drmModeGetConnector(drmFd, mId); 246094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((c == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get connector")); 247094332d3Sopenharmony_ci mConnectState = c->connection; 248094332d3Sopenharmony_ci // init the modes 249094332d3Sopenharmony_ci InitModes(*c); 250094332d3Sopenharmony_ci drmModeFreeConnector(c); 251094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 252094332d3Sopenharmony_ci} 253094332d3Sopenharmony_ci 254094332d3Sopenharmony_cistd::shared_ptr<DrmCrtc> DrmConnector::UpdateCrtcId(IdMapPtr<DrmEncoder> &encoders, 255094332d3Sopenharmony_ci IdMapPtr<DrmCrtc> &crtcs, bool plugIn, drmModeConnectorPtr c, int *crtc_id) 256094332d3Sopenharmony_ci{ 257094332d3Sopenharmony_ci std::shared_ptr<DrmCrtc> crtc = nullptr; 258094332d3Sopenharmony_ci int encoderid = c->encoders[0]; 259094332d3Sopenharmony_ci auto encoderIter = encoders.find(encoderid); 260094332d3Sopenharmony_ci if (encoderIter == encoders.end()) { 261094332d3Sopenharmony_ci DISPLAY_LOGW("can not find encoder for id : %{public}d", encoderid); 262094332d3Sopenharmony_ci return crtc; 263094332d3Sopenharmony_ci } 264094332d3Sopenharmony_ci 265094332d3Sopenharmony_ci auto &encoder = encoderIter->second; 266094332d3Sopenharmony_ci int possibleCrtcs = encoder->GetPossibleCrtcs(); 267094332d3Sopenharmony_ci 268094332d3Sopenharmony_ci for (auto crtcIter = crtcs.begin(); crtcIter != crtcs.end(); ++crtcIter) { 269094332d3Sopenharmony_ci auto &posCrts = crtcIter->second; 270094332d3Sopenharmony_ci if (possibleCrtcs == (1<<posCrts->GetPipe())) { 271094332d3Sopenharmony_ci DISPLAY_LOGD("find crtc id %{public}d, pipe %{public}d", posCrts->GetId(), posCrts->GetPipe()); 272094332d3Sopenharmony_ci crtc = posCrts; 273094332d3Sopenharmony_ci *crtc_id = posCrts->GetId(); 274094332d3Sopenharmony_ci } 275094332d3Sopenharmony_ci } 276094332d3Sopenharmony_ci if (plugIn) { 277094332d3Sopenharmony_ci encoder->SetCrtcId(*crtc_id); 278094332d3Sopenharmony_ci mEncoderId = c->encoders[0]; 279094332d3Sopenharmony_ci } else if (!plugIn) { 280094332d3Sopenharmony_ci *crtc_id = 0; 281094332d3Sopenharmony_ci mEncoderId = 0; 282094332d3Sopenharmony_ci encoder->SetCrtcId(0); 283094332d3Sopenharmony_ci } 284094332d3Sopenharmony_ci return crtc; 285094332d3Sopenharmony_ci} 286094332d3Sopenharmony_ci 287094332d3Sopenharmony_cibool DrmConnector::HandleHotplug(IdMapPtr<DrmEncoder> &encoders, 288094332d3Sopenharmony_ci IdMapPtr<DrmCrtc> &crtcs, bool plugIn) 289094332d3Sopenharmony_ci{ 290094332d3Sopenharmony_ci DISPLAY_LOGD("plug %{public}d", plugIn); 291094332d3Sopenharmony_ci int drmFd = mDrmFdPtr->GetFd(); 292094332d3Sopenharmony_ci int ret; 293094332d3Sopenharmony_ci int crtc_id = 0; 294094332d3Sopenharmony_ci std::shared_ptr<DrmCrtc> crtc; 295094332d3Sopenharmony_ci uint32_t blob_id; 296094332d3Sopenharmony_ci drmModeAtomicReq *pset = drmModeAtomicAlloc(); 297094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((pset == nullptr), DISPLAY_NULL_PTR, 298094332d3Sopenharmony_ci DISPLAY_LOGE("drm atomic alloc failed errno %{public}d", errno)); 299094332d3Sopenharmony_ci 300094332d3Sopenharmony_ci drmModeConnectorPtr c = drmModeGetConnector(drmFd, mId); 301094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((c == nullptr), false, DISPLAY_LOGE("can not get connector")); 302094332d3Sopenharmony_ci if (mConnectState == c->connection) { 303094332d3Sopenharmony_ci drmModeFreeConnector(c); 304094332d3Sopenharmony_ci return false; 305094332d3Sopenharmony_ci } else { 306094332d3Sopenharmony_ci crtc = UpdateCrtcId(encoders, crtcs, plugIn, c, &crtc_id); 307094332d3Sopenharmony_ci if (crtc == nullptr) { 308094332d3Sopenharmony_ci return DISPLAY_FAILURE; 309094332d3Sopenharmony_ci } 310094332d3Sopenharmony_ci DISPLAY_LOGD("get crtc id %{public}d ", crtc_id); 311094332d3Sopenharmony_ci 312094332d3Sopenharmony_ci DrmVsyncWorker::GetInstance().EnableVsync(plugIn); 313094332d3Sopenharmony_ci drmModeCreatePropertyBlob(drmFd, &c->modes[0], 314094332d3Sopenharmony_ci sizeof(c->modes[0]), &blob_id); 315094332d3Sopenharmony_ci ret = drmModeAtomicAddProperty(pset, crtc->GetId(), crtc->GetActivePropId(), (int)plugIn); 316094332d3Sopenharmony_ci ret |= drmModeAtomicAddProperty(pset, crtc->GetId(), crtc->GetModePropId(), blob_id); 317094332d3Sopenharmony_ci ret |= drmModeAtomicAddProperty(pset, GetId(), GetPropCrtcId(), crtc_id); 318094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, 319094332d3Sopenharmony_ci DISPLAY_LOGE("can not add the crtc id prop %{public}d", errno)); 320094332d3Sopenharmony_ci 321094332d3Sopenharmony_ci ret = drmModeAtomicCommit(drmFd, pset, DRM_MODE_ATOMIC_ALLOW_MODESET, nullptr); 322094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, 323094332d3Sopenharmony_ci DISPLAY_LOGE("can not add the crtc id prop %{public}d", errno)); 324094332d3Sopenharmony_ci drmModeAtomicFree(pset); 325094332d3Sopenharmony_ci 326094332d3Sopenharmony_ci mConnectState = c->connection; 327094332d3Sopenharmony_ci InitModes(*c); 328094332d3Sopenharmony_ci drmModeFreeConnector(c); 329094332d3Sopenharmony_ci return true; 330094332d3Sopenharmony_ci } 331094332d3Sopenharmony_ci} 332094332d3Sopenharmony_ci 333094332d3Sopenharmony_ciint32_t DrmConnector::GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes) 334094332d3Sopenharmony_ci{ 335094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr")); 336094332d3Sopenharmony_ci *num = static_cast<int32_t>(mModes.size()); 337094332d3Sopenharmony_ci if (modes != nullptr) { 338094332d3Sopenharmony_ci int i = 0; 339094332d3Sopenharmony_ci for (const auto &modeMap : mModes) { 340094332d3Sopenharmony_ci DrmMode mode = modeMap.second; 341094332d3Sopenharmony_ci mode.ConvertToHdiMode(*(modes + i)); 342094332d3Sopenharmony_ci i++; 343094332d3Sopenharmony_ci } 344094332d3Sopenharmony_ci } 345094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 346094332d3Sopenharmony_ci} 347094332d3Sopenharmony_ci 348094332d3Sopenharmony_ciint32_t DrmConnector::SetDpmsState(uint64_t dmps) 349094332d3Sopenharmony_ci{ 350094332d3Sopenharmony_ci DISPLAY_LOGD("dmps %{public}" PRIu64 "", dmps); 351094332d3Sopenharmony_ci int ret = drmModeConnectorSetProperty(mDrmFdPtr->GetFd(), mId, mPropDpmsId, dmps); 352094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("can not set dpms")); 353094332d3Sopenharmony_ci mDpmsState = dmps; 354094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 355094332d3Sopenharmony_ci} 356094332d3Sopenharmony_ci 357094332d3Sopenharmony_cibool DrmConnector::IsConnected() 358094332d3Sopenharmony_ci{ 359094332d3Sopenharmony_ci return (mConnectState == DRM_MODE_CONNECTED); 360094332d3Sopenharmony_ci} 361094332d3Sopenharmony_ci 362094332d3Sopenharmony_ciint32_t DrmConnector::GetModeFromId(int32_t id, DrmMode &mode) 363094332d3Sopenharmony_ci{ 364094332d3Sopenharmony_ci DISPLAY_LOGD(); 365094332d3Sopenharmony_ci auto iter = mModes.find(id); 366094332d3Sopenharmony_ci if (iter == mModes.end()) { 367094332d3Sopenharmony_ci return DISPLAY_FAILURE; 368094332d3Sopenharmony_ci } 369094332d3Sopenharmony_ci mode = mModes[id]; 370094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 371094332d3Sopenharmony_ci} 372094332d3Sopenharmony_ci 373094332d3Sopenharmony_cistd::unique_ptr<DrmModeBlock> DrmConnector::GetModeBlockFromId(int32_t id) 374094332d3Sopenharmony_ci{ 375094332d3Sopenharmony_ci DISPLAY_LOGD("id %{public}d", id); 376094332d3Sopenharmony_ci auto iter = mModes.find(id); 377094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((iter == mModes.end()), nullptr, DISPLAY_LOGE("can not the mode %{public}d", id)); 378094332d3Sopenharmony_ci return std::make_unique<DrmModeBlock>(mModes[id]); 379094332d3Sopenharmony_ci} 380094332d3Sopenharmony_ci 381094332d3Sopenharmony_ciDrmModeBlock::DrmModeBlock(DrmMode &mode) 382094332d3Sopenharmony_ci{ 383094332d3Sopenharmony_ci DISPLAY_LOGD(); 384094332d3Sopenharmony_ci Init(mode); 385094332d3Sopenharmony_ci} 386094332d3Sopenharmony_ci 387094332d3Sopenharmony_ciint32_t DrmModeBlock::Init(DrmMode &mode) 388094332d3Sopenharmony_ci{ 389094332d3Sopenharmony_ci int ret; 390094332d3Sopenharmony_ci int drmFd = DrmDevice::GetDrmFd(); 391094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((drmFd < 0), DISPLAY_FAILURE, DISPLAY_LOGE("the drm fd is invalid")); 392094332d3Sopenharmony_ci drmModeModeInfo modeInfo = *(mode.GetModeInfoPtr()); 393094332d3Sopenharmony_ci ret = drmModeCreatePropertyBlob(drmFd, static_cast<void *>(&modeInfo), sizeof(modeInfo), &mBlockId); 394094332d3Sopenharmony_ci DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("create property blob failed")); 395094332d3Sopenharmony_ci DISPLAY_LOGD("mBlockId %{public}d", mBlockId); 396094332d3Sopenharmony_ci return DISPLAY_SUCCESS; 397094332d3Sopenharmony_ci} 398094332d3Sopenharmony_ci 399094332d3Sopenharmony_ciDrmModeBlock::~DrmModeBlock() 400094332d3Sopenharmony_ci{ 401094332d3Sopenharmony_ci DISPLAY_LOGD("mBlockId %{public}d", mBlockId); 402094332d3Sopenharmony_ci int drmFd = DrmDevice::GetDrmFd(); 403094332d3Sopenharmony_ci if ((mBlockId != DRM_INVALID_ID) && (drmFd >= 0)) { 404094332d3Sopenharmony_ci int ret = drmModeDestroyPropertyBlob(drmFd, mBlockId); 405094332d3Sopenharmony_ci if (ret != 0) { 406094332d3Sopenharmony_ci DISPLAY_LOGE("destroy property blob failed errno %{public}d", errno); 407094332d3Sopenharmony_ci } 408094332d3Sopenharmony_ci } else { 409094332d3Sopenharmony_ci DISPLAY_LOGE("can not destruct the block id %{public}d drmFd %{public}d", mBlockId, drmFd); 410094332d3Sopenharmony_ci } 411094332d3Sopenharmony_ci} 412094332d3Sopenharmony_ci} // namespace OHOS 413094332d3Sopenharmony_ci} // namespace HDI 414094332d3Sopenharmony_ci} // namespace DISPLAY 415