pipa: vendorsetup.sh switch to local patch
Signed-off-by: Abdulwahab Isam <abdoi94.iq@gmail.com>
This commit is contained in:
824
atomic-recovery.diff
Normal file
824
atomic-recovery.diff
Normal file
@@ -0,0 +1,824 @@
|
||||
From 5a1a49949707acbba9dbe264aaeeef9077aabcf8 Mon Sep 17 00:00:00 2001
|
||||
From: Yuan Si <do4suki@gmail.com>
|
||||
Date: Wed, 06 Dec 2023 07:55:51 +0800
|
||||
Subject: [PATCH] minui: Import graphics_drm fix from QSSI 13
|
||||
|
||||
This is a squash of the following commits.
|
||||
|
||||
Author: Samantha Tran <samtran@codeaurora.org>
|
||||
Date: Wed Apr 4 22:24:34 2018 -0700
|
||||
|
||||
minui: implement atomic commit for recovery charger
|
||||
|
||||
Change setCrtc calls to atomic commits. Establish pipeline
|
||||
and split plane to display charger image.
|
||||
|
||||
CRs-Fixed: 2221005
|
||||
Change-Id: I0ca9be1a65b6889afa7e16016b7094ad90930d57
|
||||
Signed-off-by: Samantha Tran <samtran@codeaurora.org>
|
||||
|
||||
Author: Samantha Tran <samtran@codeaurora.org>
|
||||
Date: Tue Jun 12 15:34:01 2018 -0700
|
||||
|
||||
minui: correct licensing and notice for atomic recovery charger
|
||||
|
||||
This change corrects the licensing and notice for the atomic
|
||||
recovery charger commit previously made.
|
||||
|
||||
Change-Id: I105030bcc95e1af4911932347edc76c7f5bbbefd
|
||||
CRs-Fixed: 2221005
|
||||
Signed-off-by: Samantha Tran <samtran@codeaurora.org>
|
||||
|
||||
Author: Samantha Tran <samtran@codeaurora.org>
|
||||
Date: Tue Jun 19 12:28:54 2018 -0700
|
||||
|
||||
minui: Licensing for graphics_drm fix
|
||||
|
||||
Editing licensing for recovery mode to allow mode test overlap.
|
||||
|
||||
Change-Id: I8fdb0a5e2cf6920b0cbd85fc6d891c23487a5461
|
||||
CRs-Fixed: 2221005
|
||||
Signed-off-by: Samantha Tran <samtran@codeaurora.org>
|
||||
|
||||
Author: David Ng <dave@codeaurora.org>
|
||||
Date: Thu Sep 13 18:45:52 2018 -0700
|
||||
|
||||
minui: Handle NULL return conditions and potential beyond bound access
|
||||
|
||||
Fix NULL return handling in minui for DRM scenario.
|
||||
|
||||
CRs-Fixed: 2315166
|
||||
Change-Id: Ifa9f5d055a0cbcfadd505edc1a5f13b97605c92d
|
||||
|
||||
Author: Uday Kiran Pichika <pichika@codeaurora.org>
|
||||
Date: Mon Nov 5 14:19:09 2018 +0530
|
||||
|
||||
minui: Add support for low resolution display topologies
|
||||
|
||||
- Add a single layer mixer topology to cover low resolution
|
||||
display framebuffer e.g. FHD, FHD+. Display is cropped
|
||||
in absence of this topology.
|
||||
|
||||
CRs-Fixed: 2324756
|
||||
Change-Id: I119186b8eace8b03ca044a780e1b98d2a7bb08cc
|
||||
|
||||
Author: Anjaneya Prasad Musunuri <aprasad@codeaurora.org>
|
||||
Date: Fri Nov 30 10:33:45 2018 +0530
|
||||
|
||||
minui: Set client cap properties for planes before accessing them
|
||||
|
||||
Set the client cap properties for planes before
|
||||
getting plane_resources.
|
||||
|
||||
Change-Id: I08371b44bc34c95d7a97a4808cc8abcb6e063f0e
|
||||
CRs-Fixed: 2354871
|
||||
|
||||
Author: Amine Najahi <anajahi@codeaurora.org>
|
||||
Date: Tue Jul 7 18:06:59 2020 -0400
|
||||
|
||||
Add support for 4 layer mixer staging logic
|
||||
|
||||
Currently plane staging logic assumes that only
|
||||
2 planes (L/R) are required to drive the display.
|
||||
When a 4LM topology is used, 4 adjacent planes are
|
||||
needed to cover wider display resolutions.
|
||||
|
||||
This changes offsets plane src_x and dest_x coordinates
|
||||
based on plane index and removes L/R assumption. It also
|
||||
adds 4LM and VDC based topologies.
|
||||
|
||||
CRs-Fixed: 2672665
|
||||
Test: boot-up test on 2LM and 4LM topologies
|
||||
|
||||
Change-Id: If33e9b22b5545e2187ab614eed390dfe09af56a9
|
||||
|
||||
Author: Prashant Beniwal <pbeniw@codeaurora.org>
|
||||
Date: Thu Oct 29 08:24:41 2020 +0530
|
||||
|
||||
Program required properties for 4 layer mixer
|
||||
|
||||
Legacy KMS driver expects planes to have different z-order
|
||||
when staging them across two layer mixer pairs.
|
||||
|
||||
This change increments the plane z-order and programs
|
||||
"zpos" optional property.
|
||||
|
||||
This change also adds missing connector-crtc association
|
||||
property for the atomic commit required for driver to
|
||||
recognize whether its a quadpipe topology or not.
|
||||
|
||||
CRs-Fixed: 2753034
|
||||
Test: boot-up test on 2LM and 4LM topologies
|
||||
|
||||
Change-Id: Icb941ca689b770c529694862925aaedc64cb8afc
|
||||
|
||||
Change-Id: I5d8b45580d0717d255ac9938bb8ad98e30c630d5
|
||||
---
|
||||
|
||||
diff --git a/NOTICE b/NOTICE
|
||||
index c5b1efa..8874ff1 100644
|
||||
--- a/NOTICE
|
||||
+++ b/NOTICE
|
||||
@@ -9,7 +9,32 @@
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+________________________________________________________________________________
|
||||
|
||||
+ DRM based mode setting test program
|
||||
+ Copyright 2008 Tungsten Graphics
|
||||
+ Jakob Bornecrantz <jakob@tungstengraphics.com>
|
||||
+ Copyright 2008 Intel Corporation
|
||||
+ Jesse Barnes <jesse.barnes@intel.com>
|
||||
+
|
||||
+ Permission is hereby granted, free of charge, to any person obtaining a
|
||||
+ copy of this software and associated documentation files (the "Software"),
|
||||
+ to deal in the Software without restriction, including without limitation
|
||||
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
+ and/or sell copies of the Software, and to permit persons to whom the
|
||||
+ Software is furnished to do so, subject to the following conditions:
|
||||
+
|
||||
+ The above copyright notice and this permission notice shall be included in
|
||||
+ all copies or substantial portions of the Software.
|
||||
+
|
||||
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
+ IN THE SOFTWARE.
|
||||
+________________________________________________________________________________
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
diff --git a/minui/graphics_drm.cpp b/minui/graphics_drm.cpp
|
||||
index 6c3a5bd..c17cef9 100644
|
||||
--- a/minui/graphics_drm.cpp
|
||||
+++ b/minui/graphics_drm.cpp
|
||||
@@ -14,8 +14,35 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
+/*
|
||||
+ * DRM based mode setting test program
|
||||
+ * Copyright 2008 Tungsten Graphics
|
||||
+ * Jakob Bornecrantz <jakob@tungstengraphics.com>
|
||||
+ * Copyright 2008 Intel Corporation
|
||||
+ * Jesse Barnes <jesse.barnes@intel.com>
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a
|
||||
+ * copy of this software and associated documentation files (the "Software"),
|
||||
+ * to deal in the Software without restriction, including without limitation
|
||||
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
+ * and/or sell copies of the Software, and to permit persons to whom the
|
||||
+ * Software is furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be included in
|
||||
+ * all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
+ * IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
#include "graphics_drm.h"
|
||||
|
||||
+#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
@@ -29,12 +56,256 @@
|
||||
#include <android-base/macros.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
+#include <string>
|
||||
#include <drm_fourcc.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
+#include <sstream>
|
||||
|
||||
#include "minui/minui.h"
|
||||
|
||||
+#define find_prop_id(_res, type, Type, obj_id, prop_name, prop_id, index) \
|
||||
+ do { \
|
||||
+ int j = 0; \
|
||||
+ int prop_count = 0; \
|
||||
+ struct Type *obj = NULL; \
|
||||
+ obj = (_res); \
|
||||
+ if (!obj || drm[index].monitor_##type->type##_id != (obj_id)){ \
|
||||
+ prop_id = 0; \
|
||||
+ break; \
|
||||
+ } \
|
||||
+ prop_count = (int)obj->props->count_props; \
|
||||
+ for (j = 0; j < prop_count; ++j) \
|
||||
+ if (!strcmp(obj->props_info[j]->name, (prop_name))) \
|
||||
+ break; \
|
||||
+ (prop_id) = (j == prop_count)? \
|
||||
+ 0 : obj->props_info[j]->prop_id; \
|
||||
+ } while (0)
|
||||
+
|
||||
+#define add_prop(res, type, Type, id, id_name, id_val, index) \
|
||||
+ find_prop_id(res, type, Type, id, id_name, prop_id, index); \
|
||||
+ if (prop_id) \
|
||||
+ drmModeAtomicAddProperty(atomic_req, id, prop_id, id_val);
|
||||
+
|
||||
+/**
|
||||
+ * enum sde_rm_topology_name - HW resource use case in use by connector
|
||||
+ * @SDE_RM_TOPOLOGY_NONE: No topology in use currently
|
||||
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE: 1 LM, 1 PP, 1 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE_DSC: 1 LM, 1 DSC, 1 PP, 1 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE_VDC: 1 LM, 1 VDC, 1 PP, 1 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_DUALPIPE: 2 LM, 2 PP, 2 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_DUALPIPE_DSC: 2 LM, 2 DSC, 2 PP, 2 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE: 2 LM, 2 PP, 3DMux, 1 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC: 2 LM, 2 PP, 3DMux, 1 DSC, 1 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC: 2 LM, 2 PP, 3DMux, 1 VDC, 1 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE: 2 LM, 2 PP, 2 DSC Merge, 1 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_PPSPLIT: 1 LM, 2 PPs, 2 INTF/WB
|
||||
+ * @SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE 4 LM, 4 PP, 3DMux, 2 INTF
|
||||
+ * @SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE_DSC 4 LM, 4 PP, 3DMux, 3 DSC, 2 INTF
|
||||
+ * @SDE_RM_TOPOLOGY_QUADPIPE_DSCMERE 4 LM, 4 PP, 4 DSC Merge, 2 INTF
|
||||
+ * @SDE_RM_TOPOLOGY_QUADPIPE_DSC4HSMERGE 4 LM, 4 PP, 4 DSC Merge, 1 INTF
|
||||
+ */
|
||||
+
|
||||
+static uint32_t get_lm_number(const std::string &topology) {
|
||||
+ if (topology == "sde_singlepipe") return 1;
|
||||
+ if (topology == "sde_singlepipe_dsc") return 1;
|
||||
+ if (topology == "sde_singlepipe_vdc") return 1;
|
||||
+ if (topology == "sde_dualpipe") return 2;
|
||||
+ if (topology == "sde_dualpipe_dsc") return 2;
|
||||
+ if (topology == "sde_dualpipe_vdc") return 2;
|
||||
+ if (topology == "sde_dualpipemerge") return 2;
|
||||
+ if (topology == "sde_dualpipemerge_dsc") return 2;
|
||||
+ if (topology == "sde_dualpipemerge_vdc") return 2;
|
||||
+ if (topology == "sde_dualpipe_dscmerge") return 2;
|
||||
+ if (topology == "sde_ppsplit") return 1;
|
||||
+ if (topology == "sde_quadpipemerge") return 4;
|
||||
+ if (topology == "sde_quadpipe_3dmerge_dsc") return 4;
|
||||
+ if (topology == "sde_quadpipe_dscmerge") return 4;
|
||||
+ if (topology == "sde_quadpipe_dsc4hsmerge") return 4;
|
||||
+ return DEFAULT_NUM_LMS;
|
||||
+}
|
||||
+
|
||||
+static uint32_t get_topology_lm_number(int fd, uint32_t blob_id) {
|
||||
+ uint32_t num_lm = DEFAULT_NUM_LMS;
|
||||
+
|
||||
+ drmModePropertyBlobRes *blob = drmModeGetPropertyBlob(fd, blob_id);
|
||||
+ if (!blob) {
|
||||
+ return num_lm;
|
||||
+ }
|
||||
+
|
||||
+ const char *fmt_str = (const char *)(blob->data);
|
||||
+ std::stringstream stream(fmt_str);
|
||||
+ std::string line = {};
|
||||
+ const std::string topology = "topology=";
|
||||
+
|
||||
+ while (std::getline(stream, line)) {
|
||||
+ if (line.find(topology) != std::string::npos) {
|
||||
+ num_lm = get_lm_number(std::string(line, topology.length()));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ drmModeFreePropertyBlob(blob);
|
||||
+ return num_lm;
|
||||
+}
|
||||
+
|
||||
+static int find_plane_prop_id(uint32_t obj_id, const char *prop_name,
|
||||
+ Plane *plane_res) {
|
||||
+ int i, j = 0;
|
||||
+ int prop_count = 0;
|
||||
+ struct Plane *obj = NULL;
|
||||
+
|
||||
+ for (i = 0; i < NUM_PLANES; ++i) {
|
||||
+ obj = &plane_res[i];
|
||||
+ if (!obj || obj->plane->plane_id != obj_id)
|
||||
+ continue;
|
||||
+ prop_count = (int)obj->props->count_props;
|
||||
+ for (j = 0; j < prop_count; ++j)
|
||||
+ if (!strcmp(obj->props_info[j]->name, prop_name))
|
||||
+ return obj->props_info[j]->prop_id;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int atomic_add_prop_to_plane(Plane *plane_res, drmModeAtomicReq *req,
|
||||
+ uint32_t obj_id, const char *prop_name,
|
||||
+ uint64_t value) {
|
||||
+ uint32_t prop_id;
|
||||
+
|
||||
+ prop_id = find_plane_prop_id(obj_id, prop_name, plane_res);
|
||||
+ if (prop_id == 0) {
|
||||
+ printf("Could not find obj_id = %d\n", obj_id);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (drmModeAtomicAddProperty(req, obj_id, prop_id, value) < 0) {
|
||||
+ printf("Could not add prop_id = %d for obj_id %d\n",
|
||||
+ prop_id, obj_id);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int MinuiBackendDrm::AtomicPopulatePlane(int plane, drmModeAtomicReqPtr atomic_req, DrmConnector index) {
|
||||
+ uint32_t src_x, src_y, src_w, src_h;
|
||||
+ uint32_t crtc_x, crtc_y, crtc_w, crtc_h;
|
||||
+ int width = drm[index].monitor_crtc->mode.hdisplay;
|
||||
+ int height = drm[index].monitor_crtc->mode.vdisplay;
|
||||
+ int zpos = 0;
|
||||
+
|
||||
+ src_y = 0;
|
||||
+ src_w = width/number_of_lms;
|
||||
+ src_h = height;
|
||||
+ crtc_y = 0;
|
||||
+ crtc_w = width/number_of_lms;
|
||||
+ crtc_h = height;
|
||||
+ src_x = (width/number_of_lms) * plane;
|
||||
+ crtc_x = (width/number_of_lms) * plane;
|
||||
+
|
||||
+ /* populate z-order property required for 4 layer mixer */
|
||||
+ if (number_of_lms == 4)
|
||||
+ zpos = plane >> 1;
|
||||
+
|
||||
+ atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "zpos", zpos);
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "FB_ID",
|
||||
+ drm[index].GRSurfaceDrms[drm[index].current_buffer]->fb_id))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "SRC_X", src_x << 16))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "SRC_Y", src_y << 16))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "SRC_W", src_w << 16))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "SRC_H", src_h << 16))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "CRTC_X", crtc_x))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "CRTC_Y", crtc_y))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "CRTC_W", crtc_w))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "CRTC_H", crtc_h))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[plane].plane->plane_id, "CRTC_ID",
|
||||
+ drm[index].monitor_crtc->crtc_id))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int MinuiBackendDrm::TeardownPipeline(drmModeAtomicReqPtr atomic_req, DrmConnector index) {
|
||||
+ uint32_t i, prop_id;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* During suspend, tear down pipeline */
|
||||
+ add_prop(&conn_res, connector, Connector, drm[index].monitor_connector->connector_id, "CRTC_ID", 0, index);
|
||||
+ add_prop(&crtc_res, crtc, Crtc, drm[index].monitor_crtc->crtc_id, "MODE_ID", 0, index);
|
||||
+ add_prop(&crtc_res, crtc, Crtc, drm[index].monitor_crtc->crtc_id, "ACTIVE", 0, index);
|
||||
+
|
||||
+ for(i = 0; i < number_of_lms; i++) {
|
||||
+ ret = atomic_add_prop_to_plane(plane_res, atomic_req,
|
||||
+ plane_res[i].plane->plane_id, "CRTC_ID", 0);
|
||||
+ if (ret < 0) {
|
||||
+ printf("Failed to tear down plane %d\n", i);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (drmModeAtomicAddProperty(atomic_req, plane_res[i].plane->plane_id, fb_prop_id, 0) < 0) {
|
||||
+ printf("Failed to add property for plane_id=%d\n", plane_res[i].plane->plane_id);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int MinuiBackendDrm::SetupPipeline(drmModeAtomicReqPtr atomic_req, DrmConnector index) {
|
||||
+ uint32_t i, prop_id;
|
||||
+ int ret;
|
||||
+
|
||||
+ for(i = 0; i < number_of_lms; i++) {
|
||||
+ add_prop(&conn_res, connector, Connector, drm[index].monitor_connector->connector_id,
|
||||
+ "CRTC_ID", drm[index].monitor_crtc->crtc_id, index);
|
||||
+ add_prop(&crtc_res, crtc, Crtc, drm[index].monitor_crtc->crtc_id, "MODE_ID", crtc_res.mode_blob_id, index);
|
||||
+ add_prop(&crtc_res, crtc, Crtc, drm[index].monitor_crtc->crtc_id, "ACTIVE", 1, index);
|
||||
+ }
|
||||
+
|
||||
+ /* Setup planes */
|
||||
+ for(i = 0; i < number_of_lms; i++) {
|
||||
+ ret = AtomicPopulatePlane(i, atomic_req, index);
|
||||
+ if (ret < 0) {
|
||||
+ printf("Error populating plane_id = %d\n", plane_res[i].plane->plane_id);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
GRSurfaceDrm::~GRSurfaceDrm() {
|
||||
if (mmapped_buffer_) {
|
||||
munmap(mmapped_buffer_, row_bytes * height);
|
||||
@@ -141,28 +412,12 @@
|
||||
return surface;
|
||||
}
|
||||
|
||||
-void MinuiBackendDrm::DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc) {
|
||||
- if (crtc) {
|
||||
- drmModeSetCrtc(drm_fd, crtc->crtc_id,
|
||||
- 0, // fb_id
|
||||
- 0, 0, // x,y
|
||||
- nullptr, // connectors
|
||||
- 0, // connector_count
|
||||
- nullptr); // mode
|
||||
- }
|
||||
+int MinuiBackendDrm::DrmDisableCrtc(drmModeAtomicReqPtr atomic_req, DrmConnector index) {
|
||||
+ return TeardownPipeline(atomic_req, index);
|
||||
}
|
||||
|
||||
-bool MinuiBackendDrm::DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc,
|
||||
- const std::unique_ptr<GRSurfaceDrm>& surface,
|
||||
- uint32_t* connector_id) {
|
||||
- if (drmModeSetCrtc(drm_fd, crtc->crtc_id, surface->fb_id, 0, 0, // x,y
|
||||
- connector_id, 1, // connector_count
|
||||
- &crtc->mode) != 0) {
|
||||
- fprintf(stderr, "Failed to drmModeSetCrtc(%d)\n", *connector_id);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- return true;
|
||||
+int MinuiBackendDrm::DrmEnableCrtc(drmModeAtomicReqPtr atomic_req, DrmConnector index){
|
||||
+ return SetupPipeline(atomic_req, index);
|
||||
}
|
||||
|
||||
void MinuiBackendDrm::Blank(bool blank) {
|
||||
@@ -189,15 +444,31 @@
|
||||
return;
|
||||
}
|
||||
|
||||
- if (blank) {
|
||||
- DrmDisableCrtc(drm_fd, drmInterface->monitor_crtc);
|
||||
- } else {
|
||||
- DrmEnableCrtc(drm_fd, drmInterface->monitor_crtc,
|
||||
- drmInterface->GRSurfaceDrms[drmInterface->current_buffer],
|
||||
- &drmInterface->monitor_connector->connector_id);
|
||||
+ int ret = 0;
|
||||
|
||||
- active_display = index;
|
||||
+ if (blank == current_blank_state)
|
||||
+ return;
|
||||
+
|
||||
+ drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
|
||||
+ if (!atomic_req) {
|
||||
+ printf("Atomic Alloc failed\n");
|
||||
+ return;
|
||||
}
|
||||
+
|
||||
+ if (blank)
|
||||
+ ret = DrmDisableCrtc(atomic_req, index);
|
||||
+ else
|
||||
+ ret = DrmEnableCrtc(atomic_req, index);
|
||||
+
|
||||
+ if (!ret)
|
||||
+ ret = drmModeAtomicCommit(drm_fd, atomic_req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
|
||||
+
|
||||
+ if (!ret) {
|
||||
+ printf("Atomic Commit failed, rc = %d\n", ret);
|
||||
+ current_blank_state = blank;
|
||||
+ }
|
||||
+
|
||||
+ drmModeAtomicFree(atomic_req);
|
||||
}
|
||||
|
||||
bool MinuiBackendDrm::HasMultipleConnectors() {
|
||||
@@ -320,20 +591,68 @@
|
||||
}
|
||||
|
||||
void MinuiBackendDrm::DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc) {
|
||||
+ uint32_t prop_id;
|
||||
+ drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
|
||||
+
|
||||
for (int i = 0; i < resources->count_connectors; i++) {
|
||||
drmModeConnector* connector = drmModeGetConnector(fd, resources->connectors[i]);
|
||||
drmModeCrtc* crtc = find_crtc_for_connector(fd, resources, connector);
|
||||
if (crtc->crtc_id != main_crtc->crtc_id) {
|
||||
- DrmDisableCrtc(fd, crtc);
|
||||
+ // Switching to atomic commit. Given only crtc, we can only set ACTIVE = 0
|
||||
+ // to disable any Nonmain CRTCs
|
||||
+ find_prop_id(&crtc_res, crtc, Crtc, crtc->crtc_id, "ACTIVE", prop_id, i);
|
||||
+ if (prop_id == 0)
|
||||
+ return;
|
||||
+
|
||||
+ if (drmModeAtomicAddProperty(atomic_req, drm[i].monitor_crtc->crtc_id, prop_id, 0) < 0)
|
||||
+ return;
|
||||
}
|
||||
drmModeFreeCrtc(crtc);
|
||||
}
|
||||
+
|
||||
+ if (!drmModeAtomicCommit(drm_fd, atomic_req,DRM_MODE_ATOMIC_ALLOW_MODESET, NULL))
|
||||
+ printf("Atomic Commit failed in DisableNonMainCrtcs\n");
|
||||
+
|
||||
+ drmModeAtomicFree(atomic_req);
|
||||
+}
|
||||
+
|
||||
+void MinuiBackendDrm::UpdatePlaneFB(DrmConnector index) {
|
||||
+ uint32_t i, prop_id;
|
||||
+
|
||||
+ /* Set atomic req */
|
||||
+ drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
|
||||
+ if (!atomic_req) {
|
||||
+ printf("Atomic Alloc failed. Could not update fb_id\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Add conn-crtc association property required
|
||||
+ * for driver to recognize quadpipe topology.
|
||||
+ */
|
||||
+ add_prop(&conn_res, connector, Connector, drm[index].monitor_connector->connector_id,
|
||||
+ "CRTC_ID", drm[index].monitor_crtc->crtc_id, index);
|
||||
+
|
||||
+ /* Add property */
|
||||
+ for(i = 0; i < number_of_lms; i++)
|
||||
+ drmModeAtomicAddProperty(atomic_req, plane_res[i].plane->plane_id,
|
||||
+ fb_prop_id, drm[index].GRSurfaceDrms[drm[index].current_buffer]->fb_id);
|
||||
+
|
||||
+ /* Commit changes */
|
||||
+ int32_t ret;
|
||||
+ ret = drmModeAtomicCommit(drm_fd, atomic_req,
|
||||
+ DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
|
||||
+
|
||||
+ drmModeAtomicFree(atomic_req);
|
||||
+
|
||||
+ if (ret)
|
||||
+ printf("Atomic commit failed ret=%d\n", ret);
|
||||
}
|
||||
|
||||
GRSurface* MinuiBackendDrm::Init() {
|
||||
drmModeRes* res = nullptr;
|
||||
drm_fd = -1;
|
||||
|
||||
+ number_of_lms = DEFAULT_NUM_LMS;
|
||||
/* Consider DRM devices in order. */
|
||||
for (int i = 0; i < DRM_MAX_MINOR; i++) {
|
||||
auto dev_name = android::base::StringPrintf(DRM_DEV_NAME, DRM_DIR_NAME, i);
|
||||
@@ -403,75 +722,117 @@
|
||||
|
||||
drmModeFreeResources(res);
|
||||
|
||||
- // We will likely encounter errors in the backend functions (i.e. Flip) if EnableCrtc fails.
|
||||
- if (!DrmEnableCrtc(drm_fd, drm[DRM_MAIN].monitor_crtc, drm[DRM_MAIN].GRSurfaceDrms[1],
|
||||
- &drm[DRM_MAIN].monitor_connector->connector_id)) {
|
||||
- return nullptr;
|
||||
+ drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
+ drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
+
|
||||
+ /* Get possible plane_ids */
|
||||
+ drmModePlaneRes *plane_options = drmModeGetPlaneResources(drm_fd);
|
||||
+ if (!plane_options || !plane_options->planes || (plane_options->count_planes < number_of_lms))
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* Set crtc resources */
|
||||
+ crtc_res.props = drmModeObjectGetProperties(drm_fd,
|
||||
+ drm[DRM_MAIN].monitor_crtc->crtc_id,
|
||||
+ DRM_MODE_OBJECT_CRTC);
|
||||
+ if (!crtc_res.props)
|
||||
+ return NULL;
|
||||
+
|
||||
+ crtc_res.props_info = static_cast<drmModePropertyRes **>
|
||||
+ (calloc(crtc_res.props->count_props,
|
||||
+ sizeof(crtc_res.props_info)));
|
||||
+ if (!crtc_res.props_info)
|
||||
+ return NULL;
|
||||
+ else
|
||||
+ for (int j = 0; j < (int)crtc_res.props->count_props; ++j)
|
||||
+ crtc_res.props_info[j] = drmModeGetProperty(drm_fd,
|
||||
+ crtc_res.props->props[j]);
|
||||
+
|
||||
+ /* Set connector resources */
|
||||
+ conn_res.props = drmModeObjectGetProperties(drm_fd,
|
||||
+ drm[DRM_MAIN].monitor_connector->connector_id,
|
||||
+ DRM_MODE_OBJECT_CONNECTOR);
|
||||
+ if (!conn_res.props)
|
||||
+ return NULL;
|
||||
+
|
||||
+ conn_res.props_info = static_cast<drmModePropertyRes **>
|
||||
+ (calloc(conn_res.props->count_props,
|
||||
+ sizeof(conn_res.props_info)));
|
||||
+ if (!conn_res.props_info)
|
||||
+ return NULL;
|
||||
+ else {
|
||||
+ for (int j = 0; j < (int)conn_res.props->count_props; ++j) {
|
||||
+
|
||||
+ conn_res.props_info[j] = drmModeGetProperty(drm_fd,
|
||||
+ conn_res.props->props[j]);
|
||||
+
|
||||
+ /* Get preferred mode information and extract the
|
||||
+ * number of layer mixers needed from the topology name.
|
||||
+ */
|
||||
+ if (!strcmp(conn_res.props_info[j]->name, "mode_properties")) {
|
||||
+ number_of_lms = get_topology_lm_number(drm_fd, conn_res.props->prop_values[j]);
|
||||
+ printf("number of lms in topology %d\n", number_of_lms);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
+ /* Set plane resources */
|
||||
+ for(uint32_t i = 0; i < number_of_lms; ++i) {
|
||||
+ plane_res[i].plane = drmModeGetPlane(drm_fd, plane_options->planes[i]);
|
||||
+ if (!plane_res[i].plane)
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ for (uint32_t i = 0; i < number_of_lms; ++i) {
|
||||
+ struct Plane *obj = &plane_res[i];
|
||||
+ unsigned int j;
|
||||
+ obj->props = drmModeObjectGetProperties(drm_fd, obj->plane->plane_id,
|
||||
+ DRM_MODE_OBJECT_PLANE);
|
||||
+ if (!obj->props)
|
||||
+ continue;
|
||||
+ obj->props_info = static_cast<drmModePropertyRes **>
|
||||
+ (calloc(obj->props->count_props, sizeof(*obj->props_info)));
|
||||
+ if (!obj->props_info)
|
||||
+ continue;
|
||||
+ for (j = 0; j < obj->props->count_props; ++j)
|
||||
+ obj->props_info[j] = drmModeGetProperty(drm_fd, obj->props->props[j]);
|
||||
+ }
|
||||
+
|
||||
+ drmModeFreePlaneResources(plane_options);
|
||||
+ plane_options = NULL;
|
||||
+
|
||||
+ /* Setup pipe and blob_id */
|
||||
+ if (drmModeCreatePropertyBlob(drm_fd, &drm[DRM_MAIN].monitor_crtc->mode, sizeof(drmModeModeInfo),
|
||||
+ &crtc_res.mode_blob_id)) {
|
||||
+ printf("failed to create mode blob\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Save fb_prop_id*/
|
||||
+ uint32_t prop_id;
|
||||
+ prop_id = find_plane_prop_id(plane_res[0].plane->plane_id, "FB_ID", plane_res);
|
||||
+ fb_prop_id = prop_id;
|
||||
+
|
||||
+ Blank(false);
|
||||
+
|
||||
return drm[DRM_MAIN].GRSurfaceDrms[0].get();
|
||||
}
|
||||
|
||||
-static void page_flip_complete(__unused int fd,
|
||||
- __unused unsigned int sequence,
|
||||
- __unused unsigned int tv_sec,
|
||||
- __unused unsigned int tv_usec,
|
||||
- void *user_data) {
|
||||
- *static_cast<bool*>(user_data) = false;
|
||||
-}
|
||||
-
|
||||
GRSurface* MinuiBackendDrm::Flip() {
|
||||
- GRSurface* surface = NULL;
|
||||
- DrmInterface* current_drm = &drm[active_display];
|
||||
- bool ongoing_flip = true;
|
||||
+ UpdatePlaneFB(active_display);
|
||||
|
||||
- if (!current_drm->monitor_connector) {
|
||||
- fprintf(stderr, "Unsupported. active_display = %d\n", active_display);
|
||||
- return nullptr;
|
||||
- }
|
||||
-
|
||||
- if (drmModePageFlip(drm_fd, current_drm->monitor_crtc->crtc_id,
|
||||
- current_drm->GRSurfaceDrms[current_drm->current_buffer]->fb_id,
|
||||
- DRM_MODE_PAGE_FLIP_EVENT, &ongoing_flip) != 0) {
|
||||
- fprintf(stderr, "Failed to drmModePageFlip, active_display=%d", active_display);
|
||||
- return nullptr;
|
||||
- }
|
||||
-
|
||||
- while (ongoing_flip) {
|
||||
- struct pollfd fds = {
|
||||
- .fd = drm_fd,
|
||||
- .events = POLLIN
|
||||
- };
|
||||
-
|
||||
- if (poll(&fds, 1, -1) == -1 || !(fds.revents & POLLIN)) {
|
||||
- perror("Failed to poll() on drm fd");
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- drmEventContext evctx = {
|
||||
- .version = DRM_EVENT_CONTEXT_VERSION,
|
||||
- .page_flip_handler = page_flip_complete
|
||||
- };
|
||||
-
|
||||
- if (drmHandleEvent(drm_fd, &evctx) != 0) {
|
||||
- perror("Failed to drmHandleEvent");
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- current_drm->current_buffer = 1 - current_drm->current_buffer;
|
||||
- surface = current_drm->GRSurfaceDrms[current_drm->current_buffer].get();
|
||||
- return surface;
|
||||
+ drm[active_display].current_buffer = 1 - drm[active_display].current_buffer;
|
||||
+ return drm[active_display].GRSurfaceDrms[drm[active_display].current_buffer].get();
|
||||
}
|
||||
|
||||
MinuiBackendDrm::~MinuiBackendDrm() {
|
||||
for (int i = 0; i < DRM_MAX; i++) {
|
||||
if (drm[i].monitor_connector) {
|
||||
- DrmDisableCrtc(drm_fd, drm[i].monitor_crtc);
|
||||
drmModeFreeCrtc(drm[i].monitor_crtc);
|
||||
drmModeFreeConnector(drm[i].monitor_connector);
|
||||
}
|
||||
}
|
||||
+ Blank(true);
|
||||
+ drmModeDestroyPropertyBlob(drm_fd, crtc_res.mode_blob_id);
|
||||
close(drm_fd);
|
||||
drm_fd = -1;
|
||||
}
|
||||
diff --git a/minui/graphics_drm.h b/minui/graphics_drm.h
|
||||
index a8c9886..5124dbe 100644
|
||||
--- a/minui/graphics_drm.h
|
||||
+++ b/minui/graphics_drm.h
|
||||
@@ -26,6 +26,27 @@
|
||||
#include "graphics.h"
|
||||
#include "minui/minui.h"
|
||||
|
||||
+#define NUM_MAIN 1
|
||||
+#define NUM_PLANES 4
|
||||
+#define DEFAULT_NUM_LMS 2
|
||||
+
|
||||
+struct Crtc {
|
||||
+ drmModeObjectProperties *props;
|
||||
+ drmModePropertyRes **props_info;
|
||||
+ uint32_t mode_blob_id;
|
||||
+};
|
||||
+
|
||||
+struct Connector {
|
||||
+ drmModeObjectProperties *props;
|
||||
+ drmModePropertyRes **props_info;
|
||||
+};
|
||||
+
|
||||
+struct Plane {
|
||||
+ drmModePlane *plane;
|
||||
+ drmModeObjectProperties *props;
|
||||
+ drmModePropertyRes ** props_info;
|
||||
+};
|
||||
+
|
||||
class GRSurfaceDrm : public GRSurface {
|
||||
public:
|
||||
~GRSurfaceDrm() override;
|
||||
@@ -63,10 +84,15 @@
|
||||
bool HasMultipleConnectors() override;
|
||||
|
||||
private:
|
||||
- void DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc);
|
||||
+ int DrmDisableCrtc(drmModeAtomicReqPtr atomic_req, DrmConnector index);
|
||||
+ int DrmEnableCrtc(drmModeAtomicReqPtr atomic_req, DrmConnector index);
|
||||
bool DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface,
|
||||
uint32_t* conntcors);
|
||||
void DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc);
|
||||
+ int SetupPipeline(drmModeAtomicReqPtr atomic_req, DrmConnector index);
|
||||
+ int TeardownPipeline(drmModeAtomicReqPtr atomic_req, DrmConnector index);
|
||||
+ void UpdatePlaneFB(DrmConnector index);
|
||||
+ int AtomicPopulatePlane(int plane, drmModeAtomicReqPtr atomic_req, DrmConnector index);
|
||||
bool FindAndSetMonitor(int fd, drmModeRes* resources);
|
||||
|
||||
struct DrmInterface {
|
||||
@@ -79,4 +105,10 @@
|
||||
|
||||
int drm_fd{ -1 };
|
||||
DrmConnector active_display = DRM_MAIN;
|
||||
+ bool current_blank_state = true;
|
||||
+ int fb_prop_id;
|
||||
+ struct Crtc crtc_res;
|
||||
+ struct Connector conn_res;
|
||||
+ struct Plane plane_res[NUM_PLANES];
|
||||
+ uint32_t number_of_lms;
|
||||
};
|
||||
@@ -21,40 +21,34 @@ clone_if_missing "https://github.com/ai94iq/proprietary_vendor_xiaomi_sm8250-com
|
||||
clone_if_missing "https://github.com/ai94iq/proprietary_vendor_xiaomi_pipa" "vic" "vendor/xiaomi/pipa"
|
||||
clone_if_missing "https://github.com/ai94iq/android_hardware_xiaomi" "vic" "hardware/xiaomi"
|
||||
|
||||
# Git cherry-pick with enhanced error handling
|
||||
# Apply atomic-recovery patch
|
||||
(
|
||||
# Store the root directory and device paths
|
||||
ROOT_DIR="$(pwd)"
|
||||
DEVICE_PATH="${ROOT_DIR}/device/xiaomi/pipa"
|
||||
PATCH_PATH="${DEVICE_PATH}/atomic-recovery.diff"
|
||||
|
||||
# Check if patch file exists
|
||||
if [ ! -f "$PATCH_PATH" ]; then
|
||||
echo "Error: Patch file not found at ${PATCH_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Enter recovery directory
|
||||
cd bootable/recovery || {
|
||||
echo "Error: Could not change to bootable/recovery directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Fetch the commit
|
||||
echo "Fetching commit from LibreMobileOS..."
|
||||
git fetch https://gerrit.libremobileos.com/LMODroid/platform_bootable_recovery refs/changes/35/11735/1 || {
|
||||
echo "Error: Failed to fetch commit"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if commit is already present
|
||||
COMMIT_ID=$(git rev-parse FETCH_HEAD)
|
||||
if git merge-base --is-ancestor $COMMIT_ID HEAD; then
|
||||
echo "Commit already present, skipping cherry-pick"
|
||||
echo "Applying atomic-recovery patch from ${PATCH_PATH}..."
|
||||
if git am "${PATCH_PATH}"; then
|
||||
echo "Patch applied successfully"
|
||||
else
|
||||
echo "Cherry-picking commit..."
|
||||
if git cherry-pick FETCH_HEAD; then
|
||||
echo "Cherry-pick successful"
|
||||
else
|
||||
if git diff --check; then
|
||||
echo "Empty cherry-pick detected, committing..."
|
||||
git commit --allow-empty -C FETCH_HEAD
|
||||
else
|
||||
echo "Cherry-pick failed with conflicts, cleaning up..."
|
||||
git cherry-pick --abort
|
||||
fi
|
||||
fi
|
||||
echo "Patch failed to apply, cleaning up..."
|
||||
git am --abort
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Return to original directory
|
||||
cd ../.. || echo "Warning: Failed to return to original directory"
|
||||
cd "${ROOT_DIR}" || echo "Warning: Failed to return to original directory"
|
||||
)
|
||||
Reference in New Issue
Block a user