summaryrefslogtreecommitdiffstats
path: root/sdm/libs/core
diff options
context:
space:
mode:
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() { }