libhwc2.1: set refresh rate throttle when turn on LHBM

Refresh rate is expected stay on peak when LHBM is on. Set refresh rate
throttle to avoid switch to low refresh rate after turn on LHBM.

Bug: 237511061
Test: LHBM test
Change-Id: I9342e03372fc23c1d898f21517fe1c86cdd508fe
diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h
index 0bddd99..0c90883 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.h
+++ b/libhwc2.1/libdevice/ExynosDisplay.h
@@ -150,6 +150,7 @@
     SF = 0,
     PIXEL_DISP,
     TEST,
+    LHBM,
     MAX,
 };
 
diff --git a/libhwc2.1/libhwcService/ExynosHWCService.cpp b/libhwc2.1/libhwcService/ExynosHWCService.cpp
index 7974fee..60dfc8e 100644
--- a/libhwc2.1/libhwcService/ExynosHWCService.cpp
+++ b/libhwc2.1/libhwcService/ExynosHWCService.cpp
@@ -437,7 +437,7 @@
     auto display = mHWCCtx->device->getDisplay(display_id);
 
     if (display != nullptr) {
-        display->requestLhbm(!!on);
+        display->setLhbmState(!!on);
         return NO_ERROR;
     }
 
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
index 2108e96..6cc9d62 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
@@ -514,6 +514,10 @@
         }
     }
 
+    if (enabled) {
+        setLHBMRefreshRateThrottle(kLhbmRefreshRateThrottleMs);
+    }
+
     requestLhbm(enabled);
     constexpr uint32_t kSysfsCheckTimeoutMs = 500;
     ALOGI("setLhbmState =%d", enabled);
@@ -523,9 +527,16 @@
                                     ms2ns(kSysfsCheckTimeoutMs));
     if (!succeed) {
         ALOGE("failed to update lhbm mode");
+        if (enabled) {
+            setLHBMRefreshRateThrottle(0);
+        }
         return -ENODEV;
     }
 
+    if (!enabled) {
+        setLHBMRefreshRateThrottle(0);
+    }
+
     {
         // lhbm takes effect at next vblank
         ATRACE_NAME("lhbm_wait_apply");
@@ -559,6 +570,20 @@
     return mLhbmOn;
 }
 
+void ExynosPrimaryDisplay::setLHBMRefreshRateThrottle(const uint32_t delayMs) {
+    ATRACE_CALL();
+
+    if (delayMs) {
+        // make new throttle take effect
+        mLastRefreshRateAppliedNanos = systemTime(SYSTEM_TIME_MONOTONIC);
+    }
+
+    setRefreshRateThrottleNanos(std::chrono::duration_cast<std::chrono::nanoseconds>(
+                                        std::chrono::milliseconds(delayMs))
+                                        .count(),
+                                DispIdleTimerRequester::LHBM);
+}
+
 void ExynosPrimaryDisplay::setEarlyWakeupDisplay() {
     if (mEarlyWakeupDispFd) {
         writeFileNode(mEarlyWakeupDispFd, 1);
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
index 12d77ce..08b515c 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
@@ -83,6 +83,7 @@
         enum PanelGammaSource currentPanelGammaSource = PanelGammaSource::GAMMA_DEFAULT;
 
         bool checkLhbmMode(bool status, nsecs_t timoutNs);
+        void setLHBMRefreshRateThrottle(const uint32_t delayMs);
 
         hwc2_config_t mPendActiveConfig = UINT_MAX;
         bool mFirstPowerOn = true;
@@ -103,6 +104,7 @@
         int32_t mFramesToReachLhbmPeakBrightness;
         // wait num of vsync periods for peak refresh rate
         static constexpr uint32_t kLhbmWaitForPeakRefreshRate = 10;
+        static constexpr uint32_t kLhbmRefreshRateThrottleMs = 1000;
 
         FILE* mEarlyWakeupDispFd;
         static constexpr const char* kWakeupDispFilePath =