diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h index 53a709e1..a69ae1ab 100644 --- a/libdrmutils/drm_interface.h +++ b/libdrmutils/drm_interface.h @@ -209,7 +209,14 @@ enum struct DRMOps { * 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 @@ struct DRMCrtcInfo { 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 @@ class DRMManagerInterface { * 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 518d9077..612be9bd 100644 --- a/sdm/libs/core/display_base.cpp +++ b/sdm/libs/core/display_base.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,9 @@ DisplayError DisplayBase::Init() { } 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 @@ DisplayError DisplayBase::Prepare(LayerStack *layer_stack) { 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 @@ DisplayError DisplayBase::ReconfigureDisplay() { if (error != kErrorNone) { return error; } - if (mixer_attributes != mixer_attributes_) { DisablePartialUpdateOneFrame(); } @@ -1064,6 +1069,9 @@ DisplayError DisplayBase::ReconfigureDisplay() { 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 @@ bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *n *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 @@ DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData 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 @@ DisplayError DisplayBase::ValidateDataspace(const ColorMetaData &color_metadata) 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 fd4f7e0e..9696a3f5 100644 --- a/sdm/libs/core/display_base.h +++ b/sdm/libs/core/display_base.h @@ -146,6 +146,7 @@ class DisplayBase : public DisplayInterface, DumpImpl { 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 @@ class DisplayBase : public DisplayInterface, DumpImpl { 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 color_modes_; typedef std::map ColorModeMap; diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp index da33a258..186954d5 100644 --- a/sdm/libs/core/drm/hw_device_drm.cpp +++ b/sdm/libs/core/drm/hw_device_drm.cpp @@ -375,7 +375,7 @@ DisplayError HWDeviceDRM::Init() { 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 @@ void HWDeviceDRM::GetHWPanelMaxBrightness() { } 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 @@ DisplayError HWDeviceDRM::GetDisplayAttributes(uint32_t index, 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::GetHWPanelInfo(HWPanelInfo *panel_info) { } 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 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { 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 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { } 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 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { 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 @@ DisplayError HWDeviceDRM::Flush() { return kErrorHardware; } + ResetDisplayParams(); return kErrorNone; } @@ -1183,7 +1202,12 @@ bool HWDeviceDRM::EnableHotPlugDetection(int enable) { 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 @@ DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) { 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 @@ DisplayError HWDeviceDRM::GetMixerAttributes(HWMixerAttributes *mixer_attributes 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::SetTopology(sde_drm::DRMTopology drm_topology, HWTopology *hw_ } } +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(&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(&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 5130fc5a..67646df6 100644 --- a/sdm/libs/core/drm/hw_device_drm.h +++ b/sdm/libs/core/drm/hw_device_drm.h @@ -179,12 +179,15 @@ class HWDeviceDRM : public HWInterface { 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 solid_fills_ {}; bool resolution_switch_enabled_ = false; uint32_t vrefresh_ = 0; + sde_drm_dest_scaler_data sde_dest_scalar_data_ = {}; + std::vector 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 1ce77b6c..6f933eb9 100644 --- a/sdm/libs/core/drm/hw_info_drm.cpp +++ b/sdm/libs/core/drm/hw_info_drm.cpp @@ -305,6 +305,11 @@ void HWInfoDRM::GetSystemInfo(HWResourceInfo *hw_resource) { 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 de0ccb28..b2f6d3bd 100644 --- a/sdm/libs/core/drm/hw_scale_drm.cpp +++ b/sdm/libs/core/drm/hw_scale_drm.cpp @@ -66,19 +66,24 @@ static uint32_t GetAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg) { } } -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 @@ void HWScaleDRM::SetPlaneScalerV2(const HWScaleData &scale_data, sde_drm_scaler_ 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 @@ void HWScaleDRM::SetPlaneScalerV2(const HWScaleData &scale_data, sde_drm_scaler_ 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 8a4be70b..6f96ecaf 100644 --- a/sdm/libs/core/drm/hw_scale_drm.h +++ b/sdm/libs/core/drm/hw_scale_drm.h @@ -50,11 +50,10 @@ class HWScaleDRM { 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; };