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,
|
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;
|
typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap;
|
||||||
|
|
||||||
struct HWDynBwLimitInfo {
|
struct HWDynBwLimitInfo {
|
||||||
@@ -188,6 +193,7 @@ struct HWResourceInfo {
|
|||||||
FormatsMap supported_formats_map;
|
FormatsMap supported_formats_map;
|
||||||
HWRotatorInfo hw_rot_info;
|
HWRotatorInfo hw_rot_info;
|
||||||
HWDestScalarInfo hw_dest_scalar_info;
|
HWDestScalarInfo hw_dest_scalar_info;
|
||||||
|
bool has_avr = false;
|
||||||
|
|
||||||
void Reset() { *this = HWResourceInfo(); }
|
void Reset() { *this = HWResourceInfo(); }
|
||||||
};
|
};
|
||||||
@@ -226,6 +232,7 @@ struct HWPanelInfo {
|
|||||||
int min_roi_height = 0; // Min height needed for ROI
|
int min_roi_height = 0; // Min height needed for ROI
|
||||||
bool needs_roi_merge = false; // Merge ROI's of both the DSI's
|
bool needs_roi_merge = false; // Merge ROI's of both the DSI's
|
||||||
bool dynamic_fps = false; // Panel Supports dynamic fps
|
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 min_fps = 0; // Min fps supported by panel
|
||||||
uint32_t max_fps = 0; // Max fps supported by panel
|
uint32_t max_fps = 0; // Max fps supported by panel
|
||||||
bool is_primary_panel = false; // Panel is primary display
|
bool is_primary_panel = false; // Panel is primary display
|
||||||
@@ -244,6 +251,7 @@ struct HWPanelInfo {
|
|||||||
(min_roi_height != panel_info.min_roi_height) ||
|
(min_roi_height != panel_info.min_roi_height) ||
|
||||||
(needs_roi_merge != panel_info.needs_roi_merge) ||
|
(needs_roi_merge != panel_info.needs_roi_merge) ||
|
||||||
(dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
|
(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) ||
|
(max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
|
||||||
(split_info != panel_info.split_info) ||
|
(split_info != panel_info.split_info) ||
|
||||||
(s3d_mode != panel_info.s3d_mode));
|
(s3d_mode != panel_info.s3d_mode));
|
||||||
@@ -386,6 +394,11 @@ struct HWDestScaleInfo {
|
|||||||
|
|
||||||
typedef std::map<uint32_t, HWDestScaleInfo *> DestScaleInfoMap;
|
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 {
|
struct HWPipeInfo {
|
||||||
uint32_t pipe_id = 0;
|
uint32_t pipe_id = 0;
|
||||||
HWSubBlockType sub_block_type = kHWSubBlockMax;
|
HWSubBlockType sub_block_type = kHWSubBlockMax;
|
||||||
@@ -436,6 +449,7 @@ struct HWLayers {
|
|||||||
float output_compression = 1.0f;
|
float output_compression = 1.0f;
|
||||||
uint32_t bandwidth = 0;
|
uint32_t bandwidth = 0;
|
||||||
uint32_t clock = 0;
|
uint32_t clock = 0;
|
||||||
|
HWAVRInfo hw_avr_info = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HWDisplayAttributes : DisplayConfigVariableInfo {
|
struct HWDisplayAttributes : DisplayConfigVariableInfo {
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class Debug {
|
|||||||
static bool IsRotatorSplitDisabled();
|
static bool IsRotatorSplitDisabled();
|
||||||
static bool IsScalarDisabled();
|
static bool IsScalarDisabled();
|
||||||
static bool IsUbwcTiledFrameBuffer();
|
static bool IsUbwcTiledFrameBuffer();
|
||||||
|
static bool IsAVRDisabled();
|
||||||
static bool GetProperty(const char *property_name, char *value);
|
static bool GetProperty(const char *property_name, char *value);
|
||||||
static bool SetProperty(const char *property_name, const 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;
|
disable_pu_one_frame_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean hw layers for reuse.
|
|
||||||
hw_layers_ = HWLayers();
|
|
||||||
hw_layers_.info.stack = layer_stack;
|
hw_layers_.info.stack = layer_stack;
|
||||||
hw_layers_.output_compression = 1.0f;
|
hw_layers_.output_compression = 1.0f;
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,9 @@ DisplayError DisplayHDMI::Prepare(LayerStack *layer_stack) {
|
|||||||
|
|
||||||
SetS3DMode(layer_stack);
|
SetS3DMode(layer_stack);
|
||||||
|
|
||||||
|
// Clean hw layers for reuse.
|
||||||
|
hw_layers_ = HWLayers();
|
||||||
|
|
||||||
return DisplayBase::Prepare(layer_stack);
|
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_);
|
error = HWEventsInterface::Create(INT(display_type_), this, &event_list_, &hw_events_intf_);
|
||||||
if (error != kErrorNone) {
|
if (error != kErrorNone) {
|
||||||
DLOGE("Failed to create hardware events interface. Error = %d", error);
|
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);
|
return DisplayBase::Prepare(layer_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,5 +300,15 @@ DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
|
|||||||
return kErrorNone;
|
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
|
} // namespace sdm
|
||||||
|
|
||||||
|
|||||||
@@ -60,9 +60,12 @@ class DisplayPrimary : public DisplayBase, HWEventHandler {
|
|||||||
virtual void CECMessage(char *message) { }
|
virtual void CECMessage(char *message) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool NeedsAVREnable();
|
||||||
|
|
||||||
uint32_t idle_timeout_ms_ = 0;
|
uint32_t idle_timeout_ms_ = 0;
|
||||||
std::vector<const char *> event_list_ = {"vsync_event", "show_blank_event", "idle_notify",
|
std::vector<const char *> event_list_ = {"vsync_event", "show_blank_event", "idle_notify",
|
||||||
"msm_fb_thermal_level", "thread_exit"};
|
"msm_fb_thermal_level", "thread_exit"};
|
||||||
|
bool avr_prop_disabled_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sdm
|
} // namespace sdm
|
||||||
|
|||||||
@@ -130,5 +130,15 @@ DisplayError DisplayVirtual::SetActiveConfig(DisplayConfigVariableInfo *variable
|
|||||||
return kErrorNone;
|
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
|
} // namespace sdm
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class DisplayVirtual : public DisplayBase {
|
|||||||
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
|
||||||
RotatorInterface *rotator_intf);
|
RotatorInterface *rotator_intf);
|
||||||
virtual DisplayError Init();
|
virtual DisplayError Init();
|
||||||
|
virtual DisplayError Prepare(LayerStack *layer_stack);
|
||||||
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
|
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
|
||||||
virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info);
|
virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info);
|
||||||
virtual DisplayError GetActiveConfig(uint32_t *index);
|
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]);
|
panel_info->needs_roi_merge = atoi(tokens[1]);
|
||||||
} else if (!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
|
} else if (!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
|
||||||
panel_info->dynamic_fps = atoi(tokens[1]);
|
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"))) {
|
} else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
|
||||||
panel_info->min_fps = UINT32(atoi(tokens[1]));
|
panel_info->min_fps = UINT32(atoi(tokens[1]));
|
||||||
} else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
|
} 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;
|
hw_resource->has_qseed3 = true;
|
||||||
} else if (!strncmp(tokens[i], "concurrent_writeback", strlen("concurrent_writeback"))) {
|
} else if (!strncmp(tokens[i], "concurrent_writeback", strlen("concurrent_writeback"))) {
|
||||||
hw_resource->has_concurrent_writeback = true;
|
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"))) {
|
} else if (!strncmp(tokens[0], "pipe_count", strlen("pipe_count"))) {
|
||||||
|
|||||||
@@ -57,6 +57,14 @@
|
|||||||
#define MDP_COMMIT_CWB_DSPP 0x1000
|
#define MDP_COMMIT_CWB_DSPP 0x1000
|
||||||
#endif
|
#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 {
|
namespace sdm {
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
@@ -389,6 +397,10 @@ DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
|
|||||||
DLOGI_IF(kTagDriverConfig, "****************************************************************");
|
DLOGI_IF(kTagDriverConfig, "****************************************************************");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hw_resource_.has_avr) {
|
||||||
|
SetAVRFlags(hw_layers->hw_avr_info, &mdp_commit.flags);
|
||||||
|
}
|
||||||
|
|
||||||
return HWDevice::Validate(hw_layers);
|
return HWDevice::Validate(hw_layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,5 +632,15 @@ void HWPrimary::UpdateMixerAttributes() {
|
|||||||
hw_panel_info_.split_info.left_split : mixer_attributes_.width;
|
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
|
} // namespace sdm
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ class HWPrimary : public HWDevice {
|
|||||||
bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
|
bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
|
||||||
bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
|
bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
|
||||||
void UpdateMixerAttributes();
|
void UpdateMixerAttributes();
|
||||||
|
void SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags);
|
||||||
|
|
||||||
std::vector<DisplayConfigVariableInfo> display_configs_;
|
std::vector<DisplayConfigVariableInfo> display_configs_;
|
||||||
std::vector<std::string> display_config_strings_;
|
std::vector<std::string> display_config_strings_;
|
||||||
|
|||||||
@@ -140,6 +140,13 @@ bool Debug::IsUbwcTiledFrameBuffer() {
|
|||||||
return (ubwc_framebuffer == 1);
|
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) {
|
bool Debug::GetProperty(const char* property_name, char* value) {
|
||||||
if (debug_.debug_handler_->GetProperty(property_name, value) != kErrorNone) {
|
if (debug_.debug_handler_->GetProperty(property_name, value) != kErrorNone) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user