sdm: drm: Add support to set power mode

Add support to set various power modes like ON, OFF, Doze and Doze
Suspend on Connector.

CRs-Fixed: 2042514
Change-Id: I824fc26c8048c887f236182111462abcf17f62f7
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 4c37e8c..d41181f 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -172,6 +172,12 @@
    *      uint32_t - Framebuffer ID
    */
   CONNECTOR_SET_OUTPUT_FB_ID,
+  /*
+   * Op: Sets power mode for connector.
+   * Arg: uint32_t - Connector ID
+   *      uint32_t - Power Mode
+   */
+  CONNECTOR_SET_POWER_MODE,
 };
 
 enum struct DRMRotation {
@@ -180,6 +186,13 @@
   ROT_90 = 0x4,
 };
 
+enum struct DRMPowerMode {
+  ON,
+  DOZE,
+  DOZE_SUSPEND,
+  OFF,
+};
+
 enum struct DRMBlendType {
   UNDEFINED = 0,
   OPAQUE = 1,
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index bd5861e..8052613 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -48,6 +48,7 @@
 #include <utils/debug.h>
 #include <utils/formats.h>
 #include <utils/sys.h>
+#include <drm/sde_drm.h>
 #include <private/color_params.h>
 
 #include <algorithm>
@@ -92,6 +93,7 @@
 using sde_drm::DRMSrcConfig;
 using sde_drm::DRMOps;
 using sde_drm::DRMTopology;
+using sde_drm::DRMPowerMode;
 
 namespace sdm {
 
@@ -321,8 +323,7 @@
     InitializeConfigs();
     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode_);
 
-    // TODO(user): Enable this and remove the one in SetupAtomic() onces underruns are fixed
-    // drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
     // Commit to setup pipeline with mode, which then tells us the topology etc
     if (drm_atomic_intf_->Commit(true /* synchronous */)) {
       DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id, token_.conn_id,
@@ -561,18 +562,30 @@
 
 DisplayError HWDeviceDRM::PowerOn() {
   DTRACE_SCOPED();
+  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);
   return kErrorNone;
 }
 
 DisplayError HWDeviceDRM::PowerOff() {
+  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
+  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
+  int ret = drm_atomic_intf_->Commit(false /* synchronous */);
+  if (ret) {
+    DLOGE("%s failed with error %d", __FUNCTION__, ret);
+    return kErrorHardware;
+  }
   return kErrorNone;
 }
 
 DisplayError HWDeviceDRM::Doze() {
+  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
   return kErrorNone;
 }
 
 DisplayError HWDeviceDRM::DozeSuspend() {
+  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
+                            DRMPowerMode::DOZE_SUSPEND);
   return kErrorNone;
 }
 
@@ -656,9 +669,6 @@
         }
       }
     }
-
-    // TODO(user): Remove this and enable the one in Init() onces underruns are fixed
-    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
   }
 }