1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _DISPLAY_TE2_MANAGER_H_
18 #define _DISPLAY_TE2_MANAGER_H_
19 
20 #include "ExynosDisplay.h"
21 #include "ExynosHWCHelper.h"
22 
23 enum class ProximitySensorState : uint32_t {
24     NONE = 0,
25     ACTIVE,
26     INACTIVE,
27 };
28 
29 // TODO: Rename this and integrate with refresh rate throttler related features into this class.
30 class DisplayTe2Manager : public RefreshRateChangeListener {
31 public:
32     DisplayTe2Manager(ExynosDisplay* display, int32_t panelIndex, int fixedTe2DefaultRateHz);
33     ~DisplayTe2Manager() = default;
34 
35     // Set the rate while option is fixed TE2. This should be set by the sensor.
36     int32_t setFixedTe2Rate(int targetTe2RateHz);
37     // Set the rate while option is changeable TE2. This should be set by the composer
38     // while the display state is idle or active.
39     int32_t setChangeableTe2Rate(int targetTe2RateHz);
40     // Update TE2 option to either fixed or changeable according to the proximity sensor state.
41     // Ideally we should use changeable TE2 if the proximity sensor is active. Also set the min
42     // refresh rate of fixed TE2. It equals to the refresh rate while display is idle after
43     // switching to changeable TE2, and we can use it for the notification of refresh rate
44     // change.
45     void updateTe2OptionForProximity(bool proximityActive, int minRefreshRate, bool dozeMode);
isOptionFixedTe2()46     bool isOptionFixedTe2() { return mIsOptionFixedTe2; }
47 
48     // By default we will continue the TE2 setting after entering doze mode. The ALSP may not
49     // work properly if it's changeable TE2 with lower refresh rates, e.g. 1Hz. To avoid this
50     // problem, we should update the setting to fixed TE2 no matter the proximity sensor is
51     // active or not.
52     void updateTe2ForDozeMode();
53     // The TE2 might be enforced to different settings after entering doze mode. We should
54     // restore the previous settings to keep the request from ALSP.
55     void restoreTe2FromDozeMode();
56 
57     // Handle the notifications while the proximity sensor state is changed.
58     void handleProximitySensorStateChange(bool active);
59 
60     void dump(String8& result) const;
61 
62 private:
63     static constexpr const char* kTe2RateFileNode =
64             "/sys/devices/platform/exynos-drm/%s-panel/te2_rate_hz";
65     static constexpr const char* kTe2OptionFileNode =
66             "/sys/devices/platform/exynos-drm/%s-panel/te2_option";
67 
getPanelString()68     const char* getPanelString() {
69         return (mPanelIndex == 0 ? "primary" : mPanelIndex == 1 ? "secondary" : "unknown");
70     }
71 
getPanelTe2RatePath()72     const String8 getPanelTe2RatePath() {
73         return String8::format(kTe2RateFileNode, getPanelString());
74     }
75 
getPanelTe2OptionPath()76     const String8 getPanelTe2OptionPath() {
77         return String8::format(kTe2OptionFileNode, getPanelString());
78     }
79 
80     void setTe2Option(bool fixedTe2);
81     int32_t setTe2Rate(int targetTe2RateHz);
82     int32_t setFixedTe2RateInternal(int targetTe2RateHz, bool enforce);
83 
84     virtual void onRefreshRateChange(int refreshRate) override;
85 
86     ExynosDisplay* mDisplay;
87     int32_t mPanelIndex;
88     // The min refresh rate of fixed TE2. For the refresh rates lower than this, the changeable
89     // TE2 should be used.
90     int mMinRefreshRateForFixedTe2;
91     int mFixedTe2RateHz;
92     // True when the current option is fixed TE2, otherwise it's changeable TE2.
93     bool mIsOptionFixedTe2;
94     // True when the refresh rate change listener of VariableRefreshRateController is
95     // registered successfully. Thus we can receive the notification of refresh rate change
96     // for changeable TE2 usage.
97     bool mRefreshRateChangeListenerRegistered;
98 
99     // Indicates that TE2 was changed from changeable to fixed after entering doze mode. We
100     // should restore the setting after exiting doze mode.
101     bool mPendingOptionChangeableTe2;
102     // After entering doze mode, the TE2 rate will be enforced to mFixedTe2RateForDozeMode.
103     // We should save the previous rate as a pending value and restore it after exiting doze
104     // mode.
105     int mPendingFixedTe2Rate;
106     // After entering doze mode, the TE2 will be enforced to fixed 30Hz.
107     const int kFixedTe2RateForDozeMode = 30;
108 
109     Mutex mTe2Mutex;
110 
111     class ProximitySensorStateNotifierWorker : public Worker {
112     public:
113         explicit ProximitySensorStateNotifierWorker(DisplayTe2Manager* te2Manager);
114         ~ProximitySensorStateNotifierWorker();
115 
116         void onStateChanged(bool active);
117 
118     protected:
119         void Routine() override;
120 
121     private:
122         static constexpr uint32_t kDebounceTimeMs = 500U;
123 
124         DisplayTe2Manager* mTe2Manager;
125         bool mIsStateActive;
126         bool mReceivedFirstStateAfterTimeout;
127         enum ProximitySensorState mPendingState;
128     };
129 
130     std::unique_ptr<ProximitySensorStateNotifierWorker> mProximitySensorStateNotifierWorker;
131 };
132 
133 #endif // _DISPLAY_TE2_MANAGER_H_
134