/* * Copyright (C) 2024 Amlogic Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "DrmProperty.h" #include "DispAdptLog.h" DrmProperty::DrmProperty(int drvFd, drmModePropertyPtr p, uint32_t objectId, uint64_t value) : mDrvFd(drvFd), mValue(value), mComponentId(objectId) { memcpy(&mPropRes, p, sizeof(mPropRes)); if (p->count_values > 0) { size_t contentLen = p->count_values * sizeof(uint64_t); mPropRes.values = (uint64_t*)malloc(contentLen); memcpy(mPropRes.values, p->values, contentLen); } else { mPropRes.values = NULL; } if (p->count_enums > 0) { size_t contentLen = p->count_enums * sizeof(struct drm_mode_property_enum); mPropRes.enums = (struct drm_mode_property_enum *)malloc(contentLen); memcpy(mPropRes.enums, p->enums, contentLen); } else { mPropRes.enums = NULL; } if (p->count_blobs > 0) { size_t contentLen = p->count_blobs * sizeof(uint32_t); mPropRes.blob_ids = (uint32_t*)malloc(contentLen); memcpy(mPropRes.blob_ids, p->blob_ids, contentLen); } else { mPropRes.blob_ids = NULL; } mType = 0; if (drm_property_type_is(p, DRM_MODE_PROP_RANGE)) { mType = DRM_MODE_PROP_RANGE; DISPLAY_ASSERT(p->count_values > 0, " NO RANGE SPECIFIED (%s)", mPropRes.name); } else if (drm_property_type_is(p, DRM_MODE_PROP_SIGNED_RANGE)) { mType = DRM_MODE_PROP_SIGNED_RANGE; DISPLAY_ASSERT(p->count_values > 0, " NO RANGE SPECIFIED (%s)", mPropRes.name); } else if (drm_property_type_is(p, DRM_MODE_PROP_ENUM)) { mType = DRM_MODE_PROP_ENUM; DISPLAY_ASSERT(p->count_enums > 0, " NO ENUM SPECIFIED (%s)", mPropRes.name); } else if (drm_property_type_is(p, DRM_MODE_PROP_OBJECT)) { mType = DRM_MODE_PROP_OBJECT; } else if (drm_property_type_is(p, DRM_MODE_PROP_BLOB)) { mType = DRM_MODE_PROP_BLOB; } else if (drm_property_type_is(p, DRM_MODE_PROP_BITMASK)) { mType = DRM_MODE_PROP_BITMASK; } DISPLAY_ASSERT(mType !=0, "UNKNOWN type for prop (%s)", mPropRes.name); DISPLAY_LOGD("DrmProperty: %s (%d), value [%" PRId64 "]", mPropRes.name, mPropRes.prop_id, mValue); } DrmProperty::~DrmProperty() { if (mPropRes.values) free(mPropRes.values); if (mPropRes.enums) free(mPropRes.enums); if (mPropRes.blob_ids) free(mPropRes.blob_ids); } int DrmProperty::setValue(uint64_t val) { if (isImmutable()) return -EIO; if (mType == DRM_MODE_PROP_RANGE) { if (val < mPropRes.values[0] || val > mPropRes.values[1]) { DISPLAY_LOGE("[%s] RANGE ERROR (%" PRId64 ") -> (%" PRId64 ",%" PRId64 ")", mPropRes.name, val, mPropRes.values[0], mPropRes.values[1]); return -EINVAL; } } else if (mType == DRM_MODE_PROP_SIGNED_RANGE) { int64_t signedVal = (int64_t)val; int64_t minVal = (int64_t) mPropRes.values[0]; int64_t maxVal = (int64_t) mPropRes.values[1]; if (signedVal < minVal || signedVal > maxVal) { return -EINVAL; } } if (mValue != val) { mValue = val; } return 0; } uint64_t DrmProperty::getValue() { switch (mType) { case DRM_MODE_PROP_OBJECT: case DRM_MODE_PROP_RANGE: case DRM_MODE_PROP_SIGNED_RANGE: case DRM_MODE_PROP_BLOB: case DRM_MODE_PROP_ENUM: case DRM_MODE_PROP_BITMASK: return mValue; default: DISPLAY_LOGE("unknown property type"); return 0; } } int DrmProperty::getBlobData(std::vector & blob) { if (mType != DRM_MODE_PROP_BLOB) return -EINVAL; return getBlobData(blob, mValue); } int DrmProperty::getBlobData(std::vector & blob, uint32_t blobId) { DISPLAY_ASSERT(mType == DRM_MODE_PROP_BLOB, "Only For blob."); drmModePropertyBlobPtr blobProp = drmModeGetPropertyBlob(mDrvFd, blobId); if (!blobProp) { return -EIO; } uint8_t * blobData = (uint8_t * )blobProp->data; for (uint32_t i = 0; i < blobProp->length; i++) { blob.push_back(blobData[i]); } drmModeFreePropertyBlob(blobProp); return 0; } int DrmProperty::getEnumValueWithName(const char *name, uint64_t & val) { DISPLAY_ASSERT(mType == DRM_MODE_PROP_ENUM, "Only For RANG ENUM."); for (int i = 0; i < mPropRes.count_enums; i++) { if (strcmp(mPropRes.enums[i].name, name) == 0) { val = mPropRes.enums[i].value; return 0; } } return -EINVAL; } int DrmProperty::getRangeValue(uint64_t &min, uint64_t &max) { DISPLAY_ASSERT(mType == DRM_MODE_PROP_RANGE || mType == DRM_MODE_PROP_SIGNED_RANGE, "Only For RANG PROP."); min = mPropRes.values[0]; max = mPropRes.values[1]; return 0; } int DrmProperty::apply(drmModeAtomicReqPtr req) { return drmModeAtomicAddProperty(req, mComponentId, mPropRes.prop_id, getValue()); }