aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/2677-drm-amd-display-kcl_dm-use-amdgpu_crtc_page_flip-whi.patch
blob: e06860f81446f83bf19b81a2b7080c8fa8589c75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
From cc7bcdd6fd9b39fa080904c1f3b5c783bf2515e4 Mon Sep 17 00:00:00 2001
From: Xiaojie Yuan <Xiaojie.Yuan@amd.com>
Date: Wed, 15 Nov 2017 14:17:32 +0800
Subject: [PATCH 2677/4131] drm/amd/display/kcl_dm: use amdgpu_crtc_page_flip
 which doesn't block ioctl

Change-Id: I58fca156b2b3746b273ff603b7fa524b1e1a4e88
Signed-off-by: Xiaojie Yuan <Xiaojie.Yuan@amd.com>
Reviewed-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 72 ++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 72ca56f..7098bb0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -112,6 +112,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state);
 static int amdgpu_dm_atomic_check(struct drm_device *dev,
 				  struct drm_atomic_state *state);
 
+static void prepare_flip_isr(struct amdgpu_crtc *acrtc);
 
 
 
@@ -272,6 +273,9 @@ static void dm_pflip_high_irq(void *interrupt_params)
 	}
 
 	spin_lock_irqsave(&adev->ddev->event_lock, flags);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) && !defined(OS_NAME_RHEL_7_4)
+	struct amdgpu_flip_work *works = amdgpu_crtc->pflip_works;
+#endif
 
 	if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED){
 		DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d !=AMDGPU_FLIP_SUBMITTED(%d) on crtc:%d[%p] \n",
@@ -299,12 +303,19 @@ static void dm_pflip_high_irq(void *interrupt_params)
 		WARN_ON(1);
 
 	amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) && !defined(OS_NAME_RHEL_7_4)
+	amdgpu_crtc->pflip_works = NULL;
+#endif
+
 	spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
 
 	DRM_DEBUG_DRIVER("%s - crtc :%d[%p], pflip_stat:AMDGPU_FLIP_NONE\n",
 					__func__, amdgpu_crtc->crtc_id, amdgpu_crtc);
 
 	drm_crtc_vblank_put(&amdgpu_crtc->base);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) && !defined(OS_NAME_RHEL_7_4)
+	schedule_work(&works->unpin_work);
+#endif
 }
 
 static void dm_crtc_high_irq(void *interrupt_params)
@@ -1517,6 +1528,53 @@ static u8 dm_get_backlight_level(struct amdgpu_encoder *amdgpu_encoder)
 	return 0;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) && !defined(OS_NAME_RHEL_7_4)
+/**
+ * dm_page_flip - called by amdgpu_flip_work_func(), which is triggered
+ *                via DRM IOTCL, by user mode.
+ *
+ * @adev: amdgpu_device pointer
+ * @crtc_id: crtc to cleanup pageflip on
+ * @crtc_base: new address of the crtc (GPU MC address)
+ *
+ * Does the actual pageflip (surface address update).
+ */
+static void dm_page_flip(struct amdgpu_device *adev,
+			 int crtc_id, u64 crtc_base, bool async)
+{
+	struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc_id];
+	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(acrtc->base.state);
+	struct dc_stream_state *stream = acrtc_state->stream;
+	struct dc_flip_addrs addr = { {0} };
+
+	/*
+	 * Received a page flip call after the display has been reset.
+	 * Just return in this case. Everything should be clean-up on reset.
+	 */
+	if (!stream) {
+		WARN_ON(1);
+		return;
+	}
+
+	addr.address.grph.addr.low_part = lower_32_bits(crtc_base);
+	addr.address.grph.addr.high_part = upper_32_bits(crtc_base);
+	addr.flip_immediate = async;
+
+	if (acrtc->base.state->event)
+		prepare_flip_isr(acrtc);
+
+	dc_flip_plane_addrs(
+			adev->dm.dc,
+			dc_stream_get_status(stream)->plane_states,
+			&addr, 1);
+
+	DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
+			 __func__,
+			 addr.address.grph.addr.high_part,
+			 addr.address.grph.addr.low_part);
+}
+#endif
+
 static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
 				struct drm_file *filp)
 {
@@ -1558,6 +1616,9 @@ static const struct amdgpu_display_funcs dm_display_funcs = {
 	.hpd_sense = NULL,/* called unconditionally */
 	.hpd_set_polarity = NULL, /* called unconditionally */
 	.hpd_get_gpio_reg = NULL, /* VBIOS parsing. DAL does it. */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) && !defined(OS_NAME_RHEL_7_4)
+	.page_flip = dm_page_flip,
+#endif
 	.page_flip_get_scanoutpos =
 		dm_crtc_get_scanoutpos,/* called unconditionally */
 	.add_encoder = NULL, /* VBIOS parsing. DAL does it. */
@@ -3986,8 +4047,9 @@ static void handle_cursor_update(struct drm_plane *plane,
 
 static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
 {
-
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) || defined(OS_NAME_RHEL_7_4)
 	assert_spin_locked(&acrtc->base.dev->event_lock);
+#endif
 	WARN_ON(acrtc->event);
 
 	acrtc->event = acrtc->base.state->event;
@@ -4194,11 +4256,19 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 			if (plane->type == DRM_PLANE_TYPE_PRIMARY)
 				drm_crtc_vblank_get(crtc);
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) || defined(OS_NAME_RHEL_7_4)
 			amdgpu_dm_do_flip(
 				crtc,
 				fb,
 				drm_crtc_vblank_count(crtc) + *wait_for_vblank,
 				dm_state->context);
+#else
+			amdgpu_crtc_page_flip(
+				crtc,
+				fb,
+				crtc->state->event,
+				acrtc_attach->flip_flags);
+#endif
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
 			/*TODO BUG remove ASAP in 4.12 to avoid race between worker and flip IOCTL */
 
-- 
2.7.4