sdm: Add support for adaptive variable refresh feature
1. Populate information about AVR feature support from sysfs node. 2. Initialize AVR information based on display mode and dynamic fps mode and set corresponding AVR flags. 3. Define debug property sdm.debug.disable_avr to disable avr feature. Change-Id: I1bfbb9e1f9975468aa9eb6d6b575f317c658480e CRs-Fixed: 1043833
This commit is contained in:
@@ -110,6 +110,11 @@ enum HWPipeFlags {
|
||||
kMultiRectParallelMode = 0x04,
|
||||
};
|
||||
|
||||
enum HWAVRModes {
|
||||
kContinuousMode, // Mode to enable AVR feature for every frame.
|
||||
kOneShotMode, // Mode to enable AVR feature for particular frame.
|
||||
};
|
||||
|
||||
typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap;
|
||||
|
||||
struct HWDynBwLimitInfo {
|
||||
@@ -188,6 +193,7 @@ struct HWResourceInfo {
|
||||
FormatsMap supported_formats_map;
|
||||
HWRotatorInfo hw_rot_info;
|
||||
HWDestScalarInfo hw_dest_scalar_info;
|
||||
bool has_avr = false;
|
||||
|
||||
void Reset() { *this = HWResourceInfo(); }
|
||||
};
|
||||
@@ -226,6 +232,7 @@ struct HWPanelInfo {
|
||||
int min_roi_height = 0; // Min height needed for ROI
|
||||
bool needs_roi_merge = false; // Merge ROI's of both the DSI's
|
||||
bool dynamic_fps = false; // Panel Supports dynamic fps
|
||||
bool dfps_porch_mode = false; // dynamic fps VFP or HFP mode
|
||||
uint32_t min_fps = 0; // Min fps supported by panel
|
||||
uint32_t max_fps = 0; // Max fps supported by panel
|
||||
bool is_primary_panel = false; // Panel is primary display
|
||||
@@ -244,6 +251,7 @@ struct HWPanelInfo {
|
||||
(min_roi_height != panel_info.min_roi_height) ||
|
||||
(needs_roi_merge != panel_info.needs_roi_merge) ||
|
||||
(dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
|
||||
(dfps_porch_mode != panel_info.dfps_porch_mode) ||
|
||||
(max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
|
||||
(split_info != panel_info.split_info) ||
|
||||
(s3d_mode != panel_info.s3d_mode));
|
||||
@@ -386,6 +394,11 @@ struct HWDestScaleInfo {
|
||||
|
||||
typedef std::map<uint32_t, HWDestScaleInfo *> DestScaleInfoMap;
|
||||
|
||||
struct HWAVRInfo {
|
||||
bool enable = false; // Flag to Enable AVR feature
|
||||
HWAVRModes mode = kContinuousMode; // Specifies the AVR mode
|
||||
};
|
||||
|
||||
struct HWPipeInfo {
|
||||
uint32_t pipe_id = 0;
|
||||
HWSubBlockType sub_block_type = kHWSubBlockMax;
|
||||
@@ -436,6 +449,7 @@ struct HWLayers {
|
||||
float output_compression = 1.0f;
|
||||
uint32_t bandwidth = 0;
|
||||
uint32_t clock = 0;
|
||||
HWAVRInfo hw_avr_info = {};
|
||||
};
|
||||
|
||||
struct HWDisplayAttributes : DisplayConfigVariableInfo {
|
||||
|
||||
@@ -74,6 +74,7 @@ class Debug {
|
||||
static bool IsRotatorSplitDisabled();
|
||||
static bool IsScalarDisabled();
|
||||
static bool IsUbwcTiledFrameBuffer();
|
||||
static bool IsAVRDisabled();
|
||||
static bool GetProperty(const char *property_name, char *value);
|
||||
static bool SetProperty(const char *property_name, const char *value);
|
||||
|
||||
|
||||
@@ -219,8 +219,6 @@ DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
|
||||
disable_pu_one_frame_ = false;
|
||||
}
|
||||
|
||||
// Clean hw layers for reuse.
|
||||
hw_layers_ = HWLayers();
|
||||
hw_layers_.info.stack = layer_stack;
|
||||
hw_layers_.output_compression = 1.0f;
|
||||
|
||||
|
||||
@@ -114,6 +114,9 @@ DisplayError DisplayHDMI::Prepare(LayerStack *layer_stack) {
|
||||
|
||||
SetS3DMode(layer_stack);
|
||||
|
||||
// Clean hw layers for reuse.
|
||||
hw_layers_ = HWLayers();
|
||||
|
||||
return DisplayBase::Prepare(layer_stack);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,8 @@ DisplayError DisplayPrimary::Init() {
|
||||
}
|
||||
}
|
||||
|
||||
avr_prop_disabled_ = Debug::IsAVRDisabled();
|
||||
|
||||
error = HWEventsInterface::Create(INT(display_type_), this, &event_list_, &hw_events_intf_);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Failed to create hardware events interface. Error = %d", error);
|
||||
@@ -95,6 +97,10 @@ DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
|
||||
}
|
||||
}
|
||||
|
||||
// Clean hw layers for reuse.
|
||||
hw_layers_ = HWLayers();
|
||||
hw_layers_.hw_avr_info.enable = NeedsAVREnable();
|
||||
|
||||
return DisplayBase::Prepare(layer_stack);
|
||||
}
|
||||
|
||||
@@ -294,5 +300,15 @@ DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
bool DisplayPrimary::NeedsAVREnable() {
|
||||
if (avr_prop_disabled_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (hw_panel_info_.mode == kModeVideo && ((hw_panel_info_.dynamic_fps &&
|
||||
hw_panel_info_.dfps_porch_mode) || (!hw_panel_info_.dynamic_fps &&
|
||||
hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
|
||||
@@ -60,9 +60,12 @@ class DisplayPrimary : public DisplayBase, HWEventHandler {
|
||||
virtual void CECMessage(char *message) { }
|
||||
|
||||
private:
|
||||
bool NeedsAVREnable();
|
||||
|
||||
uint32_t idle_timeout_ms_ = 0;
|
||||
std::vector<const char *> event_list_ = {"vsync_event", "show_blank_event", "idle_notify",
|
||||
"msm_fb_thermal_level", "thread_exit"};
|
||||
bool avr_prop_disabled_ = false;
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
@@ -130,5 +130,15 @@ DisplayError DisplayVirtual::SetActiveConfig(DisplayConfigVariableInfo *variable
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError DisplayVirtual::Prepare(LayerStack *layer_stack) {
|
||||
lock_guard<recursive_mutex> obj(recursive_mutex_);
|
||||
|
||||
// Clean hw layers for reuse.
|
||||
hw_layers_ = HWLayers();
|
||||
|
||||
return DisplayBase::Prepare(layer_stack);
|
||||
}
|
||||
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ class DisplayVirtual : public DisplayBase {
|
||||
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
||||
RotatorInterface *rotator_intf);
|
||||
virtual DisplayError Init();
|
||||
virtual DisplayError Prepare(LayerStack *layer_stack);
|
||||
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
|
||||
virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info);
|
||||
virtual DisplayError GetActiveConfig(uint32_t *index);
|
||||
|
||||
@@ -836,6 +836,8 @@ void HWDevice::GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info) {
|
||||
panel_info->needs_roi_merge = atoi(tokens[1]);
|
||||
} else if (!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
|
||||
panel_info->dynamic_fps = atoi(tokens[1]);
|
||||
} else if (!strncmp(tokens[0], "dfps_porch_mode", strlen("dfps_porch_mode"))) {
|
||||
panel_info->dfps_porch_mode = atoi(tokens[1]);
|
||||
} else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
|
||||
panel_info->min_fps = UINT32(atoi(tokens[1]));
|
||||
} else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
|
||||
|
||||
@@ -249,6 +249,8 @@ DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
|
||||
hw_resource->has_qseed3 = true;
|
||||
} else if (!strncmp(tokens[i], "concurrent_writeback", strlen("concurrent_writeback"))) {
|
||||
hw_resource->has_concurrent_writeback = true;
|
||||
} else if (!strncmp(tokens[i], "avr", strlen("avr"))) {
|
||||
hw_resource->has_avr = true;
|
||||
}
|
||||
}
|
||||
} else if (!strncmp(tokens[0], "pipe_count", strlen("pipe_count"))) {
|
||||
|
||||
@@ -57,6 +57,14 @@
|
||||
#define MDP_COMMIT_CWB_DSPP 0x1000
|
||||
#endif
|
||||
|
||||
#ifndef MDP_COMMIT_AVR_EN
|
||||
#define MDP_COMMIT_AVR_EN 0x08
|
||||
#endif
|
||||
|
||||
#ifndef MDP_COMMIT_AVR_ONE_SHOT_MODE
|
||||
#define MDP_COMMIT_AVR_ONE_SHOT_MODE 0x10
|
||||
#endif
|
||||
|
||||
namespace sdm {
|
||||
|
||||
using std::string;
|
||||
@@ -389,6 +397,10 @@ DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
|
||||
DLOGI_IF(kTagDriverConfig, "****************************************************************");
|
||||
}
|
||||
|
||||
if (hw_resource_.has_avr) {
|
||||
SetAVRFlags(hw_layers->hw_avr_info, &mdp_commit.flags);
|
||||
}
|
||||
|
||||
return HWDevice::Validate(hw_layers);
|
||||
}
|
||||
|
||||
@@ -620,5 +632,15 @@ void HWPrimary::UpdateMixerAttributes() {
|
||||
hw_panel_info_.split_info.left_split : mixer_attributes_.width;
|
||||
}
|
||||
|
||||
void HWPrimary::SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags) {
|
||||
if (hw_avr_info.enable) {
|
||||
*avr_flags |= MDP_COMMIT_AVR_EN;
|
||||
}
|
||||
|
||||
if (hw_avr_info.mode == kOneShotMode) {
|
||||
*avr_flags |= MDP_COMMIT_AVR_ONE_SHOT_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ class HWPrimary : public HWDevice {
|
||||
bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
|
||||
bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
|
||||
void UpdateMixerAttributes();
|
||||
void SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags);
|
||||
|
||||
std::vector<DisplayConfigVariableInfo> display_configs_;
|
||||
std::vector<std::string> display_config_strings_;
|
||||
|
||||
@@ -140,6 +140,13 @@ bool Debug::IsUbwcTiledFrameBuffer() {
|
||||
return (ubwc_framebuffer == 1);
|
||||
}
|
||||
|
||||
bool Debug::IsAVRDisabled() {
|
||||
int value = 0;
|
||||
debug_.debug_handler_->GetProperty("sdm.debug.disable_avr", &value);
|
||||
|
||||
return (value == 1);
|
||||
}
|
||||
|
||||
bool Debug::GetProperty(const char* property_name, char* value) {
|
||||
if (debug_.debug_handler_->GetProperty(property_name, value) != kErrorNone) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user