hwc: Add layer mixer count
Count how many layer mixers are being used. When DP is connected,
make sure we have enough mixers to handle DP.
Change-Id: Ie40e24cc252c6f032330ac4827088ff0afa2511a
diff --git a/composer/display_null.h b/composer/display_null.h
index 3a0774e..0bd8e10 100644
--- a/composer/display_null.h
+++ b/composer/display_null.h
@@ -81,6 +81,7 @@
virtual bool IsWriteBackSupportedFormat(const LayerBufferFormat &format) { return false; }
virtual bool HandleCwbTeardown() { return false; }
virtual void Abort() {};
+ virtual uint32_t GetAvailableMixerCount() { return 0; }
MAKE_NO_OP(CommitOrPrepare(LayerStack *))
MAKE_NO_OP(PrePrepare(LayerStack *))
diff --git a/composer/hwc_display.cpp b/composer/hwc_display.cpp
index 68eb399..fdffa4c 100644
--- a/composer/hwc_display.cpp
+++ b/composer/hwc_display.cpp
@@ -2238,6 +2238,10 @@
return display_intf_->GetMixerResolution(x_pixels, y_pixels);
}
+uint32_t HWCDisplay::GetAvailableMixerCount() {
+ return display_intf_->GetAvailableMixerCount();
+}
+
void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
DisplayConfigVariableInfo display_config;
uint32_t active_index = 0;
diff --git a/composer/hwc_display.h b/composer/hwc_display.h
index ca7de82..468ae5e 100644
--- a/composer/hwc_display.h
+++ b/composer/hwc_display.h
@@ -252,6 +252,7 @@
virtual int GetActiveSecureSession(std::bitset<kSecureMax> *secure_sessions) { return 0; };
virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
+ virtual uint32_t GetAvailableMixerCount();
virtual void GetPanelResolution(uint32_t *width, uint32_t *height);
virtual void GetRealPanelResolution(uint32_t *width, uint32_t *height);
virtual void Dump(std::ostringstream *os);
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index e858d86..ae94e25 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -3074,14 +3074,16 @@
DLOGW("Skipped pluggable display handling in null-display mode");
return 0;
}
- hwc2_display_t virtual_display_index =
- (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
+
+ hwc2_display_t virtual_display_index = (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
std::bitset<kSecureMax> secure_sessions = 0;
+
hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
}
+
if (secure_sessions.any() || hwc_display_[virtual_display_index]) {
// Defer hotplug handling.
DLOGI("Marking hotplug pending...");
@@ -3133,6 +3135,19 @@
std::vector<hwc2_display_t> pending_hotplugs = {};
hwc2_display_t client_id = 0;
+ static constexpr uint32_t min_mixer_count = 2;
+ uint32_t available_mixer_count = 0;
+ hwc2_display_t active_builtin = GetActiveBuiltinDisplay();
+
+ if (active_builtin < HWCCallbacks::kNumDisplays) {
+ Locker::ScopeLock lock_a(locker_[active_builtin]);
+ available_mixer_count = hwc_display_[active_builtin]->GetAvailableMixerCount();
+ }
+
+ if (available_mixer_count < min_mixer_count) {
+ return -EAGAIN;
+ }
+
for (auto &iter : *hw_displays_info) {
auto &info = iter.second;
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index ca79d4c..3bfdd32 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -1405,6 +1405,13 @@
* [output]: List of plane ids that were used for Demura
*/
virtual void GetInitialDemuraInfo(std::vector<uint32_t> *initial_demura_planes) = 0;
+
+ /*
+ * Get the total number of crtc supported
+ * [return]: crtc count
+ */
+ virtual uint32_t GetCrtcCount() = 0;
+
};
} // namespace sde_drm
diff --git a/sde-drm/drm_crtc.cpp b/sde-drm/drm_crtc.cpp
index 5cf7f02..ab66b7f 100644
--- a/sde-drm/drm_crtc.cpp
+++ b/sde-drm/drm_crtc.cpp
@@ -1019,4 +1019,8 @@
tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::DRAM_IB));
}
+uint32_t DRMCrtcManager::GetCrtcCount() {
+ return crtc_pool_.size();
+}
+
} // namespace sde_drm
diff --git a/sde-drm/drm_crtc.h b/sde-drm/drm_crtc.h
index 09fb1bd..b59feb4 100644
--- a/sde-drm/drm_crtc.h
+++ b/sde-drm/drm_crtc.h
@@ -123,6 +123,7 @@
void PostValidate(uint32_t crtc_id, bool success);
void PostCommit(uint32_t crtc_id, bool success);
void GetCrtcList(std::vector<uint32_t> *crtc_ids);
+ uint32_t GetCrtcCount();
private:
int fd_ = -1;
diff --git a/sde-drm/drm_manager.cpp b/sde-drm/drm_manager.cpp
index 04a4b15..5907728 100644
--- a/sde-drm/drm_manager.cpp
+++ b/sde-drm/drm_manager.cpp
@@ -499,4 +499,9 @@
plane_mgr_->GetPlaneIdsFromDescriptions(frl, initial_demura_planes);
}
}
+
+uint32_t DRMManager::GetCrtcCount() {
+ return crtc_mgr_->GetCrtcCount();
+}
+
} // namespace sde_drm
diff --git a/sde-drm/drm_manager.h b/sde-drm/drm_manager.h
index 850c594..bc349ba 100644
--- a/sde-drm/drm_manager.h
+++ b/sde-drm/drm_manager.h
@@ -72,6 +72,7 @@
virtual void GetInitialDemuraInfo(std::vector<uint32_t> *initial_demura_planes);
virtual void MarkPanelFeatureForNullCommit(const DRMDisplayToken &token,
const DRMPanelFeatureID &id);
+ virtual uint32_t GetCrtcCount();
DRMPlaneManager *GetPlaneMgr();
DRMConnectorManager *GetConnectorMgr();
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 35ce5c8..d94038b 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -1314,8 +1314,18 @@
*/
virtual DisplayError GetPanelFeatureInfo(PanelFeatureInfo *info) = 0;
+ /*! @brief Method to Abort DP connection
+
+ @return \link void \endlink
+ */
virtual void Abort() = 0;
+ /*! @brief Method to Get the free mixer count
+
+ @return \link free mixer count \endlink
+ */
+ virtual uint32_t GetAvailableMixerCount() = 0;
+
protected:
virtual ~DisplayInterface() { }
};
diff --git a/sdm/include/private/hw_info_interface.h b/sdm/include/private/hw_info_interface.h
index 0a17d6f..905ca04 100644
--- a/sdm/include/private/hw_info_interface.h
+++ b/sdm/include/private/hw_info_interface.h
@@ -50,6 +50,8 @@
std::map<uint32_t, uint8_t> *required_demura_fetch_cnt) = 0;
virtual DisplayError GetDemuraPanelIds(std::vector<uint64_t> *panel_ids) = 0;
virtual DisplayError GetPanelBootParamString(std::string *panel_boot_param_string) = 0;
+ virtual uint32_t GetMaxMixerCount() = 0;
+
protected:
static int32_t ref_count_;
static HWInfoInterface *intf_;
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
index 00f69bf..7bc004f 100644
--- a/sdm/include/private/resource_interface.h
+++ b/sdm/include/private/resource_interface.h
@@ -139,6 +139,7 @@
virtual bool HandleCwbTeardown(Handle display_ctx) = 0;
virtual void HandleSkipValidate(Handle display_ctx) = 0;
virtual std::string Dump() = 0;
+ virtual uint32_t GetMixerCount() = 0;
};
} // namespace sdm
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index b6e3168..8dbda9b 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -1004,4 +1004,10 @@
return resource_intf_->HandleCwbTeardown(display_comp_ctx->display_resource_ctx);
}
+uint32_t CompManager::GetMixerCount() {
+ std::lock_guard<std::recursive_mutex> obj(comp_mgr_mutex_);
+
+ return resource_intf_->GetMixerCount();
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index b040ce0..bcc14aa 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -161,6 +161,7 @@
virtual void NotifyCwbDone(int32_t display_id, int32_t status, const LayerBuffer& buffer);
virtual void TriggerRefresh(int32_t display_id);
std::string Dump();
+ uint32_t GetMixerCount();
private:
static const int kMaxThermalLevel = 3;
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 7d84bf9..ea1cccf 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -4295,4 +4295,17 @@
return comp_manager_->HandleCwbTeardown(display_comp_ctx_);
}
+uint32_t DisplayBase::GetAvailableMixerCount() {
+ uint32_t max_count = hw_info_intf_->GetMaxMixerCount();
+ uint32_t cur_count = comp_manager_->GetMixerCount();
+
+ DLOGV("max mixer count: %d, currently used: %d", max_count, cur_count);
+ if (!max_count || max_count < cur_count) {
+ DLOGW("invalid mixer count, returing max");
+ return 0xff;
+ }
+
+ return max_count - cur_count;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index b1df265..1161076 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -245,6 +245,7 @@
virtual void NotifyCwbDone(int32_t status, const LayerBuffer& buffer);
virtual void Refresh();
virtual bool HandleCwbTeardown();
+ virtual uint32_t GetAvailableMixerCount();
protected:
struct DisplayMutex {
diff --git a/sdm/libs/core/resource_default.cpp b/sdm/libs/core/resource_default.cpp
index 669de13..686820a 100644
--- a/sdm/libs/core/resource_default.cpp
+++ b/sdm/libs/core/resource_default.cpp
@@ -388,6 +388,10 @@
return "";
}
+uint32_t ResourceDefault::GetMixerCount() {
+ return 0;
+}
+
DisplayError ResourceDefault::PostCommit(Handle display_ctx, DispLayerStack *disp_layer_stack) {
DisplayResourceContext *display_resource_ctx =
reinterpret_cast<DisplayResourceContext *>(display_ctx);
diff --git a/sdm/libs/core/resource_default.h b/sdm/libs/core/resource_default.h
index adf7a21..7972f66 100644
--- a/sdm/libs/core/resource_default.h
+++ b/sdm/libs/core/resource_default.h
@@ -137,6 +137,7 @@
}
virtual void HandleSkipValidate(Handle display_ctx);
virtual std::string Dump();
+ virtual uint32_t GetMixerCount();
private:
enum PipeOwner {
diff --git a/sdm/libs/dal/hw_info_drm.cpp b/sdm/libs/dal/hw_info_drm.cpp
index ea1228f..cd982ae 100644
--- a/sdm/libs/dal/hw_info_drm.cpp
+++ b/sdm/libs/dal/hw_info_drm.cpp
@@ -1124,4 +1124,8 @@
return kErrorNone;
}
+uint32_t HWInfoDRM::GetMaxMixerCount() {
+ return drm_mgr_intf_->GetCrtcCount();
+}
+
} // namespace sdm
diff --git a/sdm/libs/dal/hw_info_drm.h b/sdm/libs/dal/hw_info_drm.h
index f1d7c89..aec622e 100644
--- a/sdm/libs/dal/hw_info_drm.h
+++ b/sdm/libs/dal/hw_info_drm.h
@@ -56,6 +56,7 @@
std::map<uint32_t, uint8_t> *required_demura_fetch_cnt);
virtual DisplayError GetDemuraPanelIds(std::vector<uint64_t> *panel_ids);
virtual DisplayError GetPanelBootParamString(std::string *panel_boot_param_string);
+ virtual uint32_t GetMaxMixerCount();
private:
void Deinit();