Explorar o código

disp: msm: sde: add wait on spec fences for hwfencing

This change adds a wait for input spec fence to bind
before registering for hw fencing wait on it.

Change-Id: I5453547c29672e39a95b91197983075e3b61d1eb
Signed-off-by: Christina Oliveira <[email protected]>
Christina Oliveira %!s(int64=3) %!d(string=hai) anos
pai
achega
15e352d634
Modificáronse 4 ficheiros con 36 adicións e 1 borrados
  1. 1 0
      config/gki_kalamadisp.conf
  2. 1 0
      config/gki_kalamadispconf.h
  3. 3 0
      msm/Android.mk
  4. 31 1
      msm/sde/sde_crtc.c

+ 1 - 0
config/gki_kalamadisp.conf

@@ -14,3 +14,4 @@ export CONFIG_DISPLAY_BUILD=m
 export CONFIG_HDCP_QSEECOM=y
 export CONFIG_DRM_SDE_VM=y
 export CONFIG_QTI_HW_FENCE=y
+export CONFIG_QCOM_SPEC_SYNC=y

+ 1 - 0
config/gki_kalamadispconf.h

@@ -22,3 +22,4 @@
 #define CONFIG_HDCP_QSEECOM 1
 #define CONFIG_DRM_SDE_VM 1
 #define CONFIG_QTI_HW_FENCE 1
+#define CONFIG_QCOM_SPEC_SYNC 1

+ 3 - 0
msm/Android.mk

@@ -28,6 +28,7 @@ ifneq ($(TARGET_BOARD_PLATFORM), taro)
 	KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS+=$(PWD)/$(call intermediates-dir-for,DLKM,msm-ext-disp-module-symvers)/Module.symvers
 	KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS+=$(PWD)/$(call intermediates-dir-for,DLKM,sec-module-symvers)/Module.symvers
 	KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS+=$(PWD)/$(call intermediates-dir-for,DLKM,hw-fence-module-symvers)/Module.symvers
+	KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS+=$(PWD)/$(call intermediates-dir-for,DLKM,sync-fence-module-symvers)/Module.symvers
 endif
 endif
 
@@ -47,9 +48,11 @@ ifneq ($(TARGET_BOARD_PLATFORM), taro)
 	LOCAL_REQUIRED_MODULES    += msm-ext-disp-module-symvers
 	LOCAL_REQUIRED_MODULES    += sec-module-symvers
 	LOCAL_REQUIRED_MODULES    += hw-fence-module-symvers
+	LOCAL_REQUIRED_MODULES    += sync-fence-module-symvers
 	LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,msm-ext-disp-module-symvers)/Module.symvers
 	LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,sec-module-symvers)/Module.symvers
 	LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,hw-fence-module-symvers)/Module.symvers
+	LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,sync-fence-module-symvers)/Module.symvers
 endif
 endif
 

+ 31 - 1
msm/sde/sde_crtc.c

@@ -28,6 +28,7 @@
 #include <drm/drm_flip_work.h>
 #include <soc/qcom/of_common.h>
 #include <linux/version.h>
+#include <linux/soc/qcom/qcom_sync_file.h>
 
 #include "sde_kms.h"
 #include "sde_hw_lm.h"
@@ -53,6 +54,9 @@
 /* Max number of planes with hw fences within one commit */
 #define MAX_HW_FENCES SDE_MULTIRECT_PLANE_MAX
 
+/* Wait for at most 2 vsync for spec fence bind */
+#define SPEC_FENCE_TIMEOUT_MS 84
+
 struct sde_crtc_custom_events {
 	u32 event;
 	int (*func)(struct drm_crtc *crtc, bool en,
@@ -3682,6 +3686,10 @@ static struct dma_fence *_sde_plane_get_input_hw_fence(struct drm_plane *plane)
 	struct sde_plane_state *pstate;
 	void *input_fence;
 	struct dma_fence *input_hw_fence = NULL;
+	struct dma_fence_array *array = NULL;
+	struct dma_fence *spec_fence = NULL;
+	bool spec_hw_fence = true;
+	int i;
 
 	if (!plane || !plane->state) {
 		SDE_ERROR("invalid input %d\n", !plane);
@@ -3694,7 +3702,28 @@ static struct dma_fence *_sde_plane_get_input_hw_fence(struct drm_plane *plane)
 
 	if (input_fence) {
 		fence = (struct dma_fence *)pstate->input_fence;
-		if (fence->flags & BIT(MSM_HW_FENCE_FLAG_ENABLED_BIT)) {
+
+		if (test_bit(SPEC_FENCE_FLAG_FENCE_ARRAY, &fence->flags)) {
+			array = container_of(fence, struct dma_fence_array, base);
+			if (IS_ERR_OR_NULL(array))
+				goto exit;
+
+			if (!test_bit(SPEC_FENCE_FLAG_FENCE_ARRAY_BOUND, &fence->flags))
+				if (spec_sync_wait_bind_array(array, SPEC_FENCE_TIMEOUT_MS) < 0)
+					goto exit;
+
+			for (i = 0; i < array->num_fences; i++) {
+				spec_fence = array->fences[i];
+				if (IS_ERR_OR_NULL(spec_fence) ||
+					!(test_bit(MSM_HW_FENCE_FLAG_ENABLED_BIT,
+						&spec_fence->flags))) {
+					spec_hw_fence = false;
+					break;
+				}
+			}
+			if (spec_hw_fence)
+				input_hw_fence = fence;
+		} else if (test_bit(MSM_HW_FENCE_FLAG_ENABLED_BIT, &fence->flags)) {
 			input_hw_fence = fence;
 
 			SDE_DEBUG("input hwfence ctx:%llu seqno:%llu f:0x%lx timeline:%s\n",
@@ -3705,6 +3734,7 @@ static struct dma_fence *_sde_plane_get_input_hw_fence(struct drm_plane *plane)
 		SDE_EVT32_VERBOSE(DRMID(plane), fence->flags);
 	}
 
+exit:
 	return input_hw_fence;
 }