summaryrefslogtreecommitdiff
path: root/sdm/libs/core
diff options
context:
space:
mode:
authorRamkumar Radhakrishnan <ramkumar@codeaurora.org>2018-08-08 13:55:08 -0700
committerRamkumar Radhakrishnan <ramkumar@codeaurora.org>2018-08-21 14:37:31 -0700
commit7ef1a992b71b63d34c84a9a3aea6727e7923232d (patch)
tree74735b3ed597e8194992a0bfc4031320be13c5af /sdm/libs/core
parent9ec9547d998cd5f4af4226593930bba53d8c66e1 (diff)
downloaddisplay-7ef1a992b71b63d34c84a9a3aea6727e7923232d.tar.gz
sdm: Define client interface to enable/disable idle pc
1. Define client interface to enable/disable idle power collapse 2. Maintain refcount to handle concurrent enable/disable 3. Trigger the screen refresh and wait for the next frame commit done event before returning the control to the client on disable idle pc 4. Enable idle pc on suspend and reset the refcount 5. Add binder support to enable/disable idle pc CRs-Fixed: 2255316 Change-Id:Ibcaf9d4edca502cc91e9b201be822bd48313a635
Diffstat (limited to 'sdm/libs/core')
-rw-r--r--sdm/libs/core/display_base.h3
-rw-r--r--sdm/libs/core/display_primary.cpp13
-rw-r--r--sdm/libs/core/display_primary.h1
-rw-r--r--sdm/libs/core/drm/hw_device_drm.cpp12
-rw-r--r--sdm/libs/core/drm/hw_device_drm.h5
-rw-r--r--sdm/libs/core/drm/hw_peripheral_drm.cpp42
-rw-r--r--sdm/libs/core/drm/hw_peripheral_drm.h8
-rw-r--r--sdm/libs/core/drm/hw_tv_drm.cpp14
-rw-r--r--sdm/libs/core/drm/hw_tv_drm.h1
-rw-r--r--sdm/libs/core/drm/hw_virtual_drm.cpp19
-rw-r--r--sdm/libs/core/drm/hw_virtual_drm.h1
-rw-r--r--sdm/libs/core/fb/hw_device.h3
-rw-r--r--sdm/libs/core/hw_interface.h1
13 files changed, 111 insertions, 12 deletions
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index fcc076cd..d5c32a96 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -116,6 +116,9 @@ class DisplayBase : public DisplayInterface {
LayerBufferFormat format,
const ColorMetaData &color_metadata);
virtual std::string Dump();
+ virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous) {
+ return kErrorNotSupported;
+ }
protected:
DisplayError BuildLayerStackStats(LayerStack *layer_stack);
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index ba83d05c..4326d8ea 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -416,5 +416,18 @@ void DisplayPrimary::ResetPanel() {
}
}
+DisplayError DisplayPrimary::ControlIdlePowerCollapse(bool enable, bool synchronous) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ if (!active_) {
+ DLOGW("Invalid display state = %d. Panel must be on.", state_);
+ return kErrorPermission;
+ }
+ if (hw_panel_info_.mode == kModeVideo) {
+ DLOGW("Idle power collapse not supported for video mode panel.");
+ return kErrorNotSupported;
+ }
+ return hw_intf_->ControlIdlePowerCollapse(enable, synchronous);
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index a5a3ae0f..60dee5c7 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -51,6 +51,7 @@ class DisplayPrimary : public DisplayBase, HWEventHandler {
virtual DisplayError SetRefreshRate(uint32_t refresh_rate, bool final_rate);
virtual DisplayError SetPanelBrightness(int level);
virtual DisplayError GetPanelBrightness(int *level);
+ virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous);
// Implement the HWEventHandlers
virtual DisplayError VSync(int64_t timestamp);
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index aee7cae3..627e0080 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -755,16 +755,6 @@ DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) {
}
DisplayError HWDeviceDRM::PowerOn(int *release_fence) {
- DTRACE_SCOPED();
- if (!drm_atomic_intf_) {
- DLOGE("DRM Atomic Interface is null!");
- return kErrorUndefined;
- }
-
- if (first_cycle_) {
- return kErrorNone;
- }
-
update_mode_ = true;
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
@@ -1143,7 +1133,7 @@ DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) {
DTRACE_SCOPED();
SetupAtomic(hw_layers, false /* validate */);
- int ret = drm_atomic_intf_->Commit(false /* synchronous */, false /* retain_planes*/);
+ int ret = drm_atomic_intf_->Commit(synchronous_commit_, false /* retain_planes*/);
if (ret) {
DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
vrefresh_ = 0;
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 9caa0955..63853c4a 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -101,6 +101,9 @@ class HWDeviceDRM : public HWInterface {
virtual void InitializeConfigs();
virtual DisplayError DumpDebugData() { return kErrorNone; }
virtual void PopulateHWPanelInfo();
+ virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous) {
+ return kErrorNotSupported;
+ }
enum {
kHWEventVSync,
@@ -182,9 +185,9 @@ class HWDeviceDRM : public HWInterface {
uint32_t current_mode_index_ = 0;
sde_drm::DRMConnectorInfo connector_info_ = {};
bool first_cycle_ = true;
+ bool synchronous_commit_ = false;
private:
- bool synchronous_commit_ = false;
HWMixerAttributes mixer_attributes_ = {};
std::string interface_str_ = "DSI";
std::vector<sde_drm::DRMSolidfillStage> solid_fills_ {};
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index 87c99495..03403e5a 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -66,6 +66,7 @@ DisplayError HWPeripheralDRM::Validate(HWLayers *hw_layers) {
HWLayersInfo &hw_layer_info = hw_layers->info;
SetDestScalarData(hw_layer_info);
SetupConcurrentWriteback(hw_layer_info, true);
+ SetIdlePCState();
return HWDeviceDRM::Validate(hw_layers);
}
@@ -74,13 +75,20 @@ DisplayError HWPeripheralDRM::Commit(HWLayers *hw_layers) {
HWLayersInfo &hw_layer_info = hw_layers->info;
SetDestScalarData(hw_layer_info);
SetupConcurrentWriteback(hw_layer_info, false);
+ SetIdlePCState();
DisplayError error = HWDeviceDRM::Commit(hw_layers);
+ if (error != kErrorNone) {
+ return error;
+ }
if (cwb_config_.enabled && (error == kErrorNone)) {
PostCommitConcurrentWriteback(hw_layer_info.stack->output_buffer);
}
+ // Initialize to default after successful commit
+ synchronous_commit_ = false;
+
return error;
}
@@ -241,4 +249,38 @@ void HWPeripheralDRM::PostCommitConcurrentWriteback(LayerBuffer *output_buffer)
}
}
+DisplayError HWPeripheralDRM::ControlIdlePowerCollapse(bool enable, bool synchronous) {
+ sde_drm::DRMIdlePCState idle_pc_state =
+ enable ? sde_drm::DRMIdlePCState::ENABLE : sde_drm::DRMIdlePCState::DISABLE;
+ if (idle_pc_state == idle_pc_state_) {
+ return kErrorNone;
+ }
+ // As idle PC is disabled after subsequent commit, Make sure to have synchrounous commit and
+ // ensure TA accesses the display_cc registers after idle PC is disabled.
+ idle_pc_state_ = idle_pc_state;
+ synchronous_commit_ = !enable ? synchronous : false;
+ return kErrorNone;
+}
+
+DisplayError HWPeripheralDRM::PowerOn(int *release_fence) {
+ DTRACE_SCOPED();
+ if (!drm_atomic_intf_) {
+ DLOGE("DRM Atomic Interface is null!");
+ return kErrorUndefined;
+ }
+
+ if (first_cycle_) {
+ return kErrorNone;
+ }
+ drm_atomic_intf_->Perform(sde_drm::DRMOps::CRTC_SET_IDLE_PC_STATE, token_.crtc_id,
+ sde_drm::DRMIdlePCState::ENABLE);
+ DisplayError err = HWDeviceDRM::PowerOn(release_fence);
+ if (err != kErrorNone) {
+ return err;
+ }
+ idle_pc_state_ = sde_drm::DRMIdlePCState::ENABLE;
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h
index b3b8306c..365da42c 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.h
+++ b/sdm/libs/core/drm/hw_peripheral_drm.h
@@ -52,6 +52,9 @@ class HWPeripheralDRM : public HWDeviceDRM {
virtual DisplayError Validate(HWLayers *hw_layers);
virtual DisplayError Commit(HWLayers *hw_layers);
virtual DisplayError Flush();
+ virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous);
+ virtual DisplayError PowerOn(int *release_fence);
+
private:
void SetDestScalarData(HWLayersInfo hw_layer_info);
void ResetDisplayParams();
@@ -59,10 +62,15 @@ class HWPeripheralDRM : public HWDeviceDRM {
void SetupConcurrentWriteback(const HWLayersInfo &hw_layer_info, bool validate);
void ConfigureConcurrentWriteback(LayerStack *stack);
void PostCommitConcurrentWriteback(LayerBuffer *output_buffer);
+ void SetIdlePCState() {
+ drm_atomic_intf_->Perform(sde_drm::DRMOps::CRTC_SET_IDLE_PC_STATE, token_.crtc_id,
+ idle_pc_state_);
+ }
sde_drm_dest_scaler_data sde_dest_scalar_data_ = {};
std::vector<SDEScaler> scalar_data_ = {};
CWBConfig cwb_config_ = {};
+ sde_drm::DRMIdlePCState idle_pc_state_ = sde_drm::DRMIdlePCState::NONE;
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index adf1f1ea..8e141e32 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -317,5 +317,19 @@ DisplayError HWTVDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
return error;
}
+DisplayError HWTVDRM::PowerOn(int *release_fence) {
+ DTRACE_SCOPED();
+ if (!drm_atomic_intf_) {
+ DLOGE("DRM Atomic Interface is null!");
+ return kErrorUndefined;
+ }
+
+ if (first_cycle_) {
+ return kErrorNone;
+ }
+
+ return HWDeviceDRM::PowerOn(release_fence);
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h
index 3e592f97..93d4e73f 100644
--- a/sdm/libs/core/drm/hw_tv_drm.h
+++ b/sdm/libs/core/drm/hw_tv_drm.h
@@ -49,6 +49,7 @@ class HWTVDRM : public HWDeviceDRM {
virtual DisplayError Commit(HWLayers *hw_layers);
virtual void PopulateHWPanelInfo();
virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
+ virtual DisplayError PowerOn(int *release_fence);
private:
DisplayError UpdateHDRMetaData(HWLayers *hw_layers);
diff --git a/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm/libs/core/drm/hw_virtual_drm.cpp
index a2e84a29..16afe489 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.cpp
+++ b/sdm/libs/core/drm/hw_virtual_drm.cpp
@@ -207,5 +207,24 @@ void HWVirtualDRM::GetModeIndex(const HWDisplayAttributes &display_attributes, i
}
}
+DisplayError HWVirtualDRM::PowerOn(int *release_fence) {
+ DTRACE_SCOPED();
+ if (!drm_atomic_intf_) {
+ DLOGE("DRM Atomic Interface is null!");
+ return kErrorUndefined;
+ }
+
+ if (first_cycle_) {
+ return kErrorNone;
+ }
+
+ DisplayError err = HWDeviceDRM::PowerOn(release_fence);
+ if (err != kErrorNone) {
+ return err;
+ }
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_virtual_drm.h b/sdm/libs/core/drm/hw_virtual_drm.h
index d89737e3..392b9bf5 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.h
+++ b/sdm/libs/core/drm/hw_virtual_drm.h
@@ -52,6 +52,7 @@ class HWVirtualDRM : public HWDeviceDRM {
virtual DisplayError Validate(HWLayers *hw_layers);
virtual DisplayError Commit(HWLayers *hw_layers);
virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
+ virtual DisplayError PowerOn(int *release_fence);
private:
void ConfigureWbConnectorFbId(uint32_t fb_id);
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index fe954aee..636baa5b 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -97,6 +97,9 @@ class HWDevice : public HWInterface {
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
virtual DisplayError DumpDebugData();
+ virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous) {
+ return kErrorNotSupported;
+ }
enum {
kHWEventVSync,
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index cdb7cbad..143391c2 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -112,6 +112,7 @@ class HWInterface {
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) = 0;
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes) = 0;
virtual DisplayError DumpDebugData() = 0;
+ virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous) = 0;
protected:
virtual ~HWInterface() { }