sdm: Add support for destination scalar in drm.
1) Add DRMOps for destination scalar.
2) Pass destination scalar data to DRM driver.
3) Add Scalar LUTs to CRTC during Init()
4) Disable PU when DS is enabled.
Change-Id: I5450b02c16e6d162fb0069c924dc2c9877834093
Crs-fixed: 2063894
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 53a709e..a69ae1a 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -209,7 +209,14 @@
* Arg: uint32_t - CRTC ID
* uint32_t - rot_clk
*/
- CRTC_SET_ROT_CLK, /*
+ CRTC_SET_ROT_CLK,
+ /*
+ * Op: Sets destination scalar data
+ * Arg: uint32_t - CRTC ID
+ * uint64_t - Pointer to destination scalar data
+ */
+ CRTC_SET_DEST_SCALER_CONFIG,
+ /*
* Op: Returns release fence for this frame. Should be called after Commit() on
* DRMAtomicReqInterface.
* Arg: uint32_t - CRTC ID
@@ -374,6 +381,10 @@
uint64_t min_core_ib;
uint64_t min_llcc_ib;
uint64_t min_dram_ib;
+ uint32_t dest_scaler_count = 0;
+ uint32_t max_dest_scaler_input_width = 0;
+ uint32_t max_dest_scaler_output_width = 0;
+ uint32_t max_dest_scale_up = 1;
};
enum struct DRMPlaneType {
@@ -603,7 +614,7 @@
* Will query post propcessing feature info of a CRTC.
* [output]: DRMPPFeatureInfo: CRTC post processing feature info
*/
- virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0;
+ virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo *info) = 0;
/*
* Register a logical display to receive a token.
* Each display pipeline in DRM is identified by its CRTC and Connector(s).
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 518d907..612be9b 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -27,6 +27,7 @@
#include <utils/debug.h>
#include <utils/formats.h>
#include <utils/rect.h>
+#include <utils/utils.h>
#include <string>
#include <vector>
#include <algorithm>
@@ -108,6 +109,9 @@
}
Debug::Get()->GetProperty("sdm.disable_hdr_lut_gen", &disable_hdr_lut_gen_);
+ // TODO(user): Temporary changes, to be removed when DRM driver supports
+ // Partial update with Destination scaler enabled.
+ SetPUonDestScaler();
return kErrorNone;
@@ -235,8 +239,10 @@
if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
DisablePartialUpdateOneFrame();
}
-
- if (partial_update_control_ == false || disable_pu_one_frame_) {
+ // TODO(user): Temporary changes, to be removed when DRM driver supports
+ // Partial update with Destination scaler enabled.
+ if (partial_update_control_ == false || disable_pu_one_frame_ ||
+ disable_pu_on_dest_scaler_) {
comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
disable_pu_one_frame_ = false;
}
@@ -1056,7 +1062,6 @@
if (error != kErrorNone) {
return error;
}
-
if (mixer_attributes != mixer_attributes_) {
DisablePartialUpdateOneFrame();
}
@@ -1064,6 +1069,9 @@
display_attributes_ = display_attributes;
mixer_attributes_ = mixer_attributes;
hw_panel_info_ = hw_panel_info;
+ // TODO(user): Temporary changes, to be removed when DRM driver supports
+ // Partial update with Destination scaler enabled.
+ SetPUonDestScaler();
return kErrorNone;
}
@@ -1203,7 +1211,10 @@
*new_mixer_width = display_width;
*new_mixer_height = display_height;
}
-
+ if (*new_mixer_width > display_width || *new_mixer_height > display_height) {
+ *new_mixer_width = display_width;
+ *new_mixer_height = display_height;
+ }
return true;
}
@@ -1263,8 +1274,17 @@
if (error != kErrorNone) {
return error;
}
-
- DisablePartialUpdateOneFrame();
+ // TODO(user): Temporary changes, to be removed when DRM driver supports
+ // Partial update with Destination scaler enabled.
+ if (GetDriverType() == DriverType::DRM) {
+ if (de_data.enable) {
+ disable_pu_on_dest_scaler_ = true;
+ } else {
+ SetPUonDestScaler();
+ }
+ } else {
+ DisablePartialUpdateOneFrame();
+ }
return kErrorNone;
}
@@ -1589,4 +1609,19 @@
return kErrorNone;
}
+// TODO(user): Temporary changes, to be removed when DRM driver supports
+// Partial update with Destination scaler enabled.
+void DisplayBase::SetPUonDestScaler() {
+ if (GetDriverType() == DriverType::FB) {
+ return;
+ }
+ uint32_t mixer_width = mixer_attributes_.width;
+ uint32_t mixer_height = mixer_attributes_.height;
+ uint32_t display_width = display_attributes_.x_pixels;
+ uint32_t display_height = display_attributes_.y_pixels;
+
+ disable_pu_on_dest_scaler_ = (mixer_width != display_width ||
+ mixer_height != display_height);
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index fd4f7e0..9696a3f 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -146,6 +146,7 @@
DisplayError GetHdrColorMode(std::string *color_mode, bool *found_hdr);
bool IsSupportColorModeAttribute(const std::string &color_mode);
DisplayState GetLastPowerMode();
+ void SetPUonDestScaler();
recursive_mutex recursive_mutex_;
DisplayType display_type_;
@@ -169,6 +170,9 @@
bool partial_update_control_ = true;
HWEventsInterface *hw_events_intf_ = NULL;
bool disable_pu_one_frame_ = false;
+ // TODO(user): Temporary changes, to be removed when DRM driver supports
+ // Partial update with Destination scaler enabled.
+ bool disable_pu_on_dest_scaler_ = false;
uint32_t num_color_modes_ = 0;
std::vector<SDEDisplayMode> color_modes_;
typedef std::map<std::string, SDEDisplayMode *> ColorModeMap;
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index da33a25..186954d 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -375,7 +375,7 @@
if (hw_resource_.has_qseed3) {
hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
}
-
+ scalar_data_.resize(hw_resource_.hw_dest_scalar_info.count);
return kErrorNone;
}
@@ -634,14 +634,22 @@
}
DisplayError HWDeviceDRM::GetActiveConfig(uint32_t *active_config) {
- *active_config = current_mode_index_;
+ if (IsResolutionSwitchEnabled()) {
+ *active_config = current_mode_index_;
+ } else {
+ *active_config = 0;
+ }
return kErrorNone;
}
DisplayError HWDeviceDRM::GetNumDisplayAttributes(uint32_t *count) {
- *count = UINT32(display_attributes_.size());
- if (*count <= 0) {
- return kErrorHardware;
+ if (IsResolutionSwitchEnabled()) {
+ *count = UINT32(display_attributes_.size());
+ if (*count <= 0) {
+ return kErrorHardware;
+ }
+ } else {
+ *count = 1;
}
return kErrorNone;
}
@@ -651,8 +659,11 @@
if (index >= display_attributes_.size()) {
return kErrorParameters;
}
-
- *display_attributes = display_attributes_[index];
+ if (IsResolutionSwitchEnabled()) {
+ *display_attributes = display_attributes_[index];
+ } else {
+ *display_attributes = display_attributes_[current_mode_index_];
+ }
return kErrorNone;
}
@@ -662,6 +673,10 @@
}
DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) {
+ if (!IsResolutionSwitchEnabled()) {
+ return kErrorNotSupported;
+ }
+
if (index >= display_attributes_.size()) {
DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size()));
return kErrorParameters;
@@ -779,6 +794,8 @@
crtc_rects[i].top = UINT32(roi.top);
crtc_rects[i].bottom = UINT32(roi.bottom);
// TODO(user): In Dest scaler + PU, populate from HWDestScaleInfo->panel_roi
+ // TODO(user): panel_roi need to be made as a vector in HWLayersInfo and
+ // needs to be removed from HWDestScaleInfo.
conn_rects[i].left = UINT32(roi.left);
conn_rects[i].right = UINT32(roi.right);
conn_rects[i].top = UINT32(roi.top);
@@ -860,7 +877,7 @@
}
if (hw_scale_) {
SDEScaler scaler_output = {};
- hw_scale_->SetPlaneScaler(pipe_info->scale_data, &scaler_output);
+ hw_scale_->SetScaler(pipe_info->scale_data, &scaler_output);
// TODO(user): Remove qseed3 and add version check, then send appropriate scaler object
if (hw_resource_.has_qseed3) {
drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id,
@@ -912,6 +929,7 @@
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_IDLE_TIMEOUT, token_.crtc_id,
hw_layer_info.set_idle_time_ms);
}
+ SetDestScalarData(hw_layer_info);
}
void HWDeviceDRM::AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha) {
@@ -1088,6 +1106,7 @@
return kErrorHardware;
}
+ ResetDisplayParams();
return kErrorNone;
}
@@ -1183,7 +1202,12 @@
return true;
}
-void HWDeviceDRM::ResetDisplayParams() {}
+void HWDeviceDRM::ResetDisplayParams() {
+ sde_dest_scalar_data_ = {};
+ for (uint32_t j = 0; j < scalar_data_.size(); j++) {
+ scalar_data_[j] = {};
+ }
+}
DisplayError HWDeviceDRM::SetCursorPosition(HWLayers *hw_layers, int x, int y) {
DTRACE_SCOPED();
@@ -1198,7 +1222,7 @@
if (info.id >= sde_drm::kPPFeaturesMax)
continue;
// use crtc_id_ = 0 since PP features are same across all CRTCs
- drm_mgr_intf_->GetCrtcPPInfo(0, info);
+ drm_mgr_intf_->GetCrtcPPInfo(0, &info);
vers->version[i] = HWColorManagerDrm::GetFeatureVersion(info);
}
return kErrorNone;
@@ -1419,12 +1443,6 @@
return kErrorParameters;
}
- uint32_t index = current_mode_index_;
- mixer_attributes_.width = display_attributes_[index].x_pixels;
- mixer_attributes_.height = display_attributes_[index].y_pixels;
- mixer_attributes_.split_left = display_attributes_[index].is_device_split
- ? hw_panel_info_.split_info.left_split
- : mixer_attributes_.width;
*mixer_attributes = mixer_attributes_;
return kErrorNone;
@@ -1494,4 +1512,45 @@
}
}
+void HWDeviceDRM::SetDestScalarData(HWLayersInfo hw_layer_info) {
+ if (!hw_resource_.hw_dest_scalar_info.count) {
+ return;
+ }
+
+ uint32_t index = 0;
+ for (uint32_t i = 0; i < hw_resource_.hw_dest_scalar_info.count; i++) {
+ DestScaleInfoMap::iterator it = hw_layer_info.dest_scale_info_map.find(i);
+
+ if (it == hw_layer_info.dest_scale_info_map.end()) {
+ continue;
+ }
+
+ HWDestScaleInfo *dest_scale_info = it->second;
+ SDEScaler *scale = &scalar_data_[index];
+ hw_scale_->SetScaler(dest_scale_info->scale_data, scale);
+ sde_drm_dest_scaler_cfg *dest_scalar_data = &sde_dest_scalar_data_.ds_cfg[index];
+ dest_scalar_data->flags = 0;
+ if (scale->scaler_v2.enable) {
+ dest_scalar_data->flags |= SDE_DRM_DESTSCALER_ENABLE;
+ }
+ if (scale->scaler_v2.de.enable) {
+ dest_scalar_data->flags |= SDE_DRM_DESTSCALER_ENHANCER_UPDATE;
+ }
+ if (dest_scale_info->scale_update) {
+ dest_scalar_data->flags |= SDE_DRM_DESTSCALER_SCALE_UPDATE;
+ }
+ dest_scalar_data->index = i;
+ dest_scalar_data->lm_width = dest_scale_info->mixer_width;
+ dest_scalar_data->lm_height = dest_scale_info->mixer_height;
+ dest_scalar_data->scaler_cfg = reinterpret_cast<uint64_t>(&scale->scaler_v2);
+ if (hw_panel_info_.partial_update) {
+ dest_scalar_data->flags |= SDE_DRM_DESTSCALER_PU_ENABLE;
+ }
+ index++;
+ }
+ sde_dest_scalar_data_.num_dest_scaler = UINT32(hw_layer_info.dest_scale_info_map.size());
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DEST_SCALER_CONFIG, token_.crtc_id,
+ reinterpret_cast<uint64_t>(&sde_dest_scalar_data_));
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 5130fc5..67646df 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -179,12 +179,15 @@
sde_drm::DRMConnectorInfo connector_info_ = {};
private:
+ void SetDestScalarData(HWLayersInfo hw_layer_info);
bool synchronous_commit_ = false;
HWMixerAttributes mixer_attributes_ = {};
std::string interface_str_ = "DSI";
std::vector<sde_drm::DRMSolidfillStage> solid_fills_ {};
bool resolution_switch_enabled_ = false;
uint32_t vrefresh_ = 0;
+ sde_drm_dest_scaler_data sde_dest_scalar_data_ = {};
+ std::vector<SDEScaler> scalar_data_ = {};
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 1ce77b6..6f933eb 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -305,6 +305,11 @@
hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
sdm_format.clear();
}
+
+ hw_resource->hw_dest_scalar_info.count = info.dest_scaler_count;
+ hw_resource->hw_dest_scalar_info.max_scale_up = info.max_dest_scale_up;
+ hw_resource->hw_dest_scalar_info.max_input_width = info.max_dest_scaler_input_width;
+ hw_resource->hw_dest_scalar_info.max_output_width = info.max_dest_scaler_output_width;
}
void HWInfoDRM::GetHWPlanesInfo(HWResourceInfo *hw_resource) {
diff --git a/sdm/libs/core/drm/hw_scale_drm.cpp b/sdm/libs/core/drm/hw_scale_drm.cpp
index de0ccb2..b2f6d3b 100644
--- a/sdm/libs/core/drm/hw_scale_drm.cpp
+++ b/sdm/libs/core/drm/hw_scale_drm.cpp
@@ -66,19 +66,24 @@
}
}
-void HWScaleDRM::SetPlaneScaler(const HWScaleData &scale_data, SDEScaler *scaler) {
+void HWScaleDRM::SetScaler(const HWScaleData &scale_data, SDEScaler *scaler) {
if (version_ == Version::V2) {
- SetPlaneScalerV2(scale_data, &scaler->scaler_v2);
+ SetScalerV2(scale_data, &scaler->scaler_v2);
}
}
-void HWScaleDRM::SetPlaneScalerV2(const HWScaleData &scale_data, sde_drm_scaler_v2 *scaler) {
+void HWScaleDRM::SetScalerV2(const HWScaleData &scale_data, sde_drm_scaler_v2 *scaler) {
if (!scale_data.enable.scale && !scale_data.enable.direction_detection &&
!scale_data.enable.detail_enhance) {
+ scaler->enable = 0;
+ scaler->dir_en = 0;
+ scaler->de.enable = 0;
return;
}
- scaler->enable = scale_data.enable.scale;
+ scaler->enable = scale_data.enable.scale | scale_data.enable.direction_detection |
+ scale_data.detail_enhance.enable;
+
scaler->dir_en = scale_data.enable.direction_detection;
scaler->de.enable = scale_data.detail_enhance.enable;
@@ -132,7 +137,6 @@
scaler->y_rgb_sep_lut_idx = scale_data.y_rgb_sep_lut_idx;
scaler->uv_sep_lut_idx = scale_data.uv_sep_lut_idx;
- /* TODO(user): Uncomment when de support is added
if (scaler->de.enable) {
sde_drm_de_v1 *det_enhance = &scaler->de;
det_enhance->sharpen_level1 = scale_data.detail_enhance.sharpen_level1;
@@ -151,7 +155,6 @@
det_enhance->adjust_c[i] = scale_data.detail_enhance.adjust_c[i];
}
}
- */
return;
}
diff --git a/sdm/libs/core/drm/hw_scale_drm.h b/sdm/libs/core/drm/hw_scale_drm.h
index 8a4be70..6f96eca 100644
--- a/sdm/libs/core/drm/hw_scale_drm.h
+++ b/sdm/libs/core/drm/hw_scale_drm.h
@@ -50,11 +50,10 @@
public:
enum class Version { V2 };
explicit HWScaleDRM(Version v) : version_(v) {}
- void SetPlaneScaler(const HWScaleData &scale, SDEScaler *scaler);
+ void SetScaler(const HWScaleData &scale, SDEScaler *scaler);
private:
- void SetPlaneScalerV2(const HWScaleData &scale, sde_drm_scaler_v2 *scaler_v2);
-
+ void SetScalerV2(const HWScaleData &scale, sde_drm_scaler_v2 *scaler_v2);
Version version_ = Version::V2;
};