summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-06-28 17:22:15 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-06-28 17:22:15 -0700
commit81abb87426aefd98594ae8d97357ee93d1f256f8 (patch)
tree57c3b3231fe5d5e4e469e43eda36d35862e313cd
parent52773656de7a11de050c2bf514b7b0811b384d5a (diff)
parent68b10a4b1956757b656b0786ec5b8f5392b4f38e (diff)
downloadandroid_hardware_qcom_display-81abb87426aefd98594ae8d97357ee93d1f256f8.tar.gz
android_hardware_qcom_display-81abb87426aefd98594ae8d97357ee93d1f256f8.tar.bz2
android_hardware_qcom_display-81abb87426aefd98594ae8d97357ee93d1f256f8.zip
Merge "sdm: Add mode chose for dynamic framerate switch" into dev-2.0
-rw-r--r--sdm/libs/core/fb/hw_hdmi.cpp117
-rw-r--r--sdm/libs/core/fb/hw_hdmi.h22
-rw-r--r--sdm/libs/hwc/hwc_display_external.cpp21
3 files changed, 147 insertions, 13 deletions
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp
index 5fe9bc1f1..ec76b4170 100644
--- a/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/sdm/libs/core/fb/hw_hdmi.cpp
@@ -698,13 +698,103 @@ DisplayError HWHDMI::SetS3DMode(HWS3DMode s3d_mode) {
return kErrorNone;
}
+DisplayError HWHDMI::GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t *mode,
+ DynamicFPSData *data, uint32_t *config_index) {
+ msm_hdmi_mode_timing_info *cur = NULL;
+ msm_hdmi_mode_timing_info *dst = NULL;
+ uint32_t i = 0;
+ int pre_refresh_rate_diff = 0;
+ bool pre_unstd_mode = false;
+
+ for (i = 0; i < hdmi_mode_count_; i++) {
+ msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[i];
+ if (timing_mode->video_format == hdmi_modes_[active_config_index_]) {
+ cur = timing_mode;
+ break;
+ }
+ }
+
+ if (cur == NULL) {
+ DLOGE("can't find timing info for active config index(%d)", active_config_index_);
+ return kErrorUndefined;
+ }
+
+ if (cur->refresh_rate != frame_rate_) {
+ pre_unstd_mode = true;
+ }
+
+ if (i >= hdmi_mode_count_) {
+ return kErrorNotSupported;
+ }
+
+ dst = cur;
+ pre_refresh_rate_diff = static_cast<int>(dst->refresh_rate) - static_cast<int>(refresh_rate);
+
+ for (i = 0; i < hdmi_mode_count_; i++) {
+ msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[i];
+ if (cur->active_h == timing_mode->active_h &&
+ cur->active_v == timing_mode->active_v &&
+ cur->pixel_formats == timing_mode->pixel_formats ) {
+ int cur_refresh_rate_diff = static_cast<int>(timing_mode->refresh_rate) -
+ static_cast<int>(refresh_rate);
+ if (abs(pre_refresh_rate_diff) > abs(cur_refresh_rate_diff)) {
+ pre_refresh_rate_diff = cur_refresh_rate_diff;
+ dst = timing_mode;
+ }
+ }
+ }
+
+ if (dst == NULL) {
+ DLOGE("can't find timing mode switch to");
+ return kErrorUndefined;
+ }
+
+ GetConfigIndex(dst->video_format, config_index);
+
+ data->hor_front_porch = dst->front_porch_h;
+ data->hor_back_porch = dst->back_porch_h;
+ data->hor_pulse_width = dst->pulse_width_h;
+ data->clk_rate_hz = dst->pixel_freq;
+ data->fps = refresh_rate;
+
+ if (dst->front_porch_h != cur->front_porch_h) {
+ *mode = kModeHFP;
+ }
+
+ if (dst->refresh_rate != refresh_rate || dst->pixel_freq != cur->pixel_freq) {
+ if (*mode == kModeHFP) {
+ if (dst->refresh_rate != refresh_rate) {
+ *mode = kModeHFPCalcClock;
+ } else {
+ *mode = kModeClockHFP;
+ }
+ } else {
+ *mode = kModeClock;
+ }
+ }
+
+ if (pre_unstd_mode && (*mode == kModeHFP)) {
+ *mode = kModeClockHFP;
+ }
+
+ return kErrorNone;
+}
+
DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) {
char mode_path[kMaxStringLength] = {0};
char node_path[kMaxStringLength] = {0};
- uint32_t mode = kModeHFP;
+ uint32_t mode = kModeClock;
+ uint32_t config_index = 0;
+ DynamicFPSData data;
+ DisplayError error = kErrorNone;
if (refresh_rate == frame_rate_) {
- return kErrorNone;
+ return error;
+ }
+
+ error = GetDynamicFrameRateMode(refresh_rate, &mode, &data, &config_index);
+ if (error != kErrorNone) {
+ return error;
}
snprintf(mode_path, sizeof(mode_path), "%s%d/msm_fb_dfps_mode", fb_path_, fb_node_index_);
@@ -712,7 +802,7 @@ DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) {
int fd_mode = Sys::open_(mode_path, O_WRONLY);
if (fd_mode < 0) {
- DLOGE("Failed to open %s with error %s", node_path, strerror(errno));
+ DLOGE("Failed to open %s with error %s", mode_path, strerror(errno));
return kErrorFileDescriptor;
}
@@ -734,8 +824,14 @@ DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) {
}
char refresh_rate_string[kMaxStringLength];
- snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d", refresh_rate);
- DLOGI_IF(kTagDriverConfig, "Setting refresh rate = %d", refresh_rate);
+ if (mode == kModeHFP || mode == kModeClock) {
+ snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d", refresh_rate);
+ DLOGI_IF(kTagDriverConfig, "Setting refresh rate = %d", refresh_rate);
+ } else {
+ snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d %d %d %d %d",
+ data.hor_front_porch, data.hor_back_porch, data.hor_pulse_width,
+ data.clk_rate_hz, data.fps);
+ }
len = Sys::pwrite_(fd_node, refresh_rate_string, strlen(refresh_rate_string), 0);
if (len < 0) {
DLOGE("Failed to write %d with error %s", refresh_rate, strerror(errno));
@@ -744,12 +840,21 @@ DisplayError HWHDMI::SetRefreshRate(uint32_t refresh_rate) {
}
Sys::close_(fd_node);
- DisplayError error = ReadTimingInfo();
+ error = ReadTimingInfo();
if (error != kErrorNone) {
return error;
}
+// GetDisplayAttributes(config_index, &display_attributes_);
+// UpdateMixerAttributes();
+
frame_rate_ = refresh_rate;
+ active_config_index_ = config_index;
+
+ DLOGI_IF(kTagDriverConfig, "config_index(%d) Mode(%d) frame_rate(%d)",
+ config_index,
+ mode,
+ frame_rate_);
return kErrorNone;
}
diff --git a/sdm/libs/core/fb/hw_hdmi.h b/sdm/libs/core/fb/hw_hdmi.h
index aa5e2a09e..28adc39e6 100644
--- a/sdm/libs/core/fb/hw_hdmi.h
+++ b/sdm/libs/core/fb/hw_hdmi.h
@@ -49,9 +49,29 @@ class HWHDMI : public HWDevice {
kModeVFP,
// Switch framerate by tuning horizontal front porch
kModeHFP,
+ // Switch framerate by tuning horizontal front porch and clock
+ kModeClockHFP,
+ // Switch framerate by tuning horizontal front porch and re-caculate clock
+ kModeHFPCalcClock,
kModeMAX
};
+ /**
+ * struct DynamicFPSData - defines dynamic fps related data
+ * @hor_front_porch: horizontal front porch
+ * @hor_back_porch: horizontal back porch
+ * @hor_pulse_width: horizontal pulse width
+ * @clk_rate_hz: panel clock rate in HZ
+ * @fps: frames per second
+ */
+ struct DynamicFPSData {
+ uint32_t hor_front_porch;
+ uint32_t hor_back_porch;
+ uint32_t hor_pulse_width;
+ uint32_t clk_rate_hz;
+ uint32_t fps;
+ };
+
HWHDMI(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
virtual DisplayError Init();
virtual DisplayError Deinit();
@@ -84,6 +104,8 @@ class HWHDMI : public HWDevice {
HWDisplayAttributes *attrib);
bool IsSupportedS3DMode(HWS3DMode s3d_mode);
+ DisplayError GetDynamicFrameRateMode(uint32_t refresh_rate, uint32_t*mode,
+ DynamicFPSData *data, uint32_t *config_index);
uint32_t hdmi_mode_count_;
uint32_t hdmi_modes_[256];
// Holds the hdmi timing information. Ex: resolution, fps etc.,
diff --git a/sdm/libs/hwc/hwc_display_external.cpp b/sdm/libs/hwc/hwc_display_external.cpp
index 43160c3a6..38be91be7 100644
--- a/sdm/libs/hwc/hwc_display_external.cpp
+++ b/sdm/libs/hwc/hwc_display_external.cpp
@@ -128,14 +128,12 @@ int HWCDisplayExternal::Prepare(hwc_display_contents_1_t *content_list) {
if (current_refresh_rate_ != metadata_refresh_rate_ && one_video_updating_layer && drc_enabled_) {
error = display_intf_->SetRefreshRate(metadata_refresh_rate_);
+ if (error == kErrorNone) {
+ // On success, set current refresh rate to new refresh rate
+ current_refresh_rate_ = metadata_refresh_rate_;
+ }
}
- if (error == kErrorNone) {
- // On success, set current refresh rate to new refresh rate
- current_refresh_rate_ = metadata_refresh_rate_;
- }
-
-
status = PrepareLayerStack(content_list);
if (status) {
return status;
@@ -239,6 +237,11 @@ uint32_t HWCDisplayExternal::RoundToStandardFPS(float fps) {
static const uint32_t mapping_fps[] = {59940, 60000, 60000, 59940, 60000, 50000, 59940, 60000};
uint32_t frame_rate = (uint32_t)(fps * 1000);
+ // process non valid
+ if (frame_rate == 0) {
+ return current_refresh_rate_;
+ }
+
int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0]));
for (int i = 0; i < count; i++) {
// Most likely used for video, the fps for frames should be stable from video side.
@@ -260,7 +263,11 @@ uint32_t HWCDisplayExternal::RoundToStandardFPS(float fps) {
void HWCDisplayExternal::PrepareDynamicRefreshRate(Layer *layer) {
if (layer->input_buffer->flags.video) {
- metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
+ if (layer->frame_rate != 0) {
+ metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
+ } else {
+ metadata_refresh_rate_ = current_refresh_rate_;
+ }
layer->frame_rate = current_refresh_rate_;
}
}