aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0313-drm-amd-display-update-plane-functionalities.patch
blob: dceba875d17be686a7c022c04a44464388b1539c (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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
From 82545407ddfcc2b06e508fe16d061fb11498a7bb Mon Sep 17 00:00:00 2001
From: Shirish S <shirish.s@amd.com>
Date: Thu, 23 Mar 2017 14:54:40 +0530
Subject: [PATCH 0313/4131] drm/amd/display: update plane functionalities

This patch introduces amdgpu_drm_plane_state
structure, which subclasses drm_plane_state and
holds data suitable for configuring hardware.

It switches reset(), atomic_duplicate_state()
& atomic_destroy_state() functions to new internal
implementation, earlier they were pointing to
drm core functions.

TESTS(On Chromium OS on Stoney Only)
* Builds without compilation errors.
* 'plane_test' passes for XR24 format
  based Overlay plane.
* Chromium OS ui comes up.

Signed-off-by: Shirish S <shirish.s@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Kalyan Alle <kalyan.alle@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h           | 13 +++++
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c    | 55 ++++++++++++++++++++--
 drivers/gpu/drm/drm_atomic.c                       |  3 +-
 drivers/gpu/drm/drm_atomic_helper.c                | 55 ++++++++++++++++++++++
 include/drm/drm_atomic.h                           |  3 ++
 include/drm/drm_atomic_helper.h                    |  3 ++
 6 files changed, 126 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 1b89a18..3bfebab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -57,6 +57,7 @@ struct amdgpu_hpd;
 #define to_amdgpu_connector(x) container_of(x, struct amdgpu_connector, base)
 #define to_amdgpu_encoder(x) container_of(x, struct amdgpu_encoder, base)
 #define to_amdgpu_framebuffer(x) container_of(x, struct amdgpu_framebuffer, base)
+#define to_amdgpu_plane(x)	container_of(x, struct amdgpu_plane, base)
 
 #define AMDGPU_MAX_HPD_PINS 6
 #define AMDGPU_MAX_CRTCS 6
@@ -443,6 +444,18 @@ struct amdgpu_crtc {
 	struct drm_pending_vblank_event *event;
 };
 
+struct amdgpu_drm_plane_state {
+	struct drm_plane_state base;
+	unsigned int h_ratio;
+	unsigned int v_ratio;
+};
+
+static inline struct amdgpu_drm_plane_state *
+to_amdgpu_plane_state(struct drm_plane_state *state)
+{
+	return container_of(state, struct amdgpu_drm_plane_state, base);
+}
+
 struct amdgpu_plane {
 	struct drm_plane base;
 	enum drm_plane_type plane_type;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
index e8de976..1b23081 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
@@ -1608,12 +1608,57 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = {
 	.atomic_check = dm_encoder_helper_atomic_check
 };
 
+static void dm_drm_plane_reset(struct drm_plane *plane)
+{
+	struct amdgpu_drm_plane_state *amdgpu_state;
+
+	if (plane->state) {
+		amdgpu_state = to_amdgpu_plane_state(plane->state);
+		if (amdgpu_state->base.fb)
+			drm_framebuffer_unreference(amdgpu_state->base.fb);
+		kfree(amdgpu_state);
+		plane->state = NULL;
+	}
+
+	amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
+	if (amdgpu_state) {
+		plane->state = &amdgpu_state->base;
+		plane->state->plane = plane;
+	}
+}
+
+static struct drm_plane_state *
+dm_drm_plane_duplicate_state(struct drm_plane *plane)
+{
+	struct amdgpu_drm_plane_state *amdgpu_state;
+	struct amdgpu_drm_plane_state *copy;
+
+	amdgpu_state = to_amdgpu_plane_state(plane->state);
+	copy = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
+	if (!copy)
+		return NULL;
+
+	__drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
+	return &copy->base;
+}
+
+static void dm_drm_plane_destroy_state(struct drm_plane *plane,
+					   struct drm_plane_state *old_state)
+{
+	struct amdgpu_drm_plane_state *old_amdgpu_state =
+					to_amdgpu_plane_state(old_state);
+	__drm_atomic_helper_plane_destroy_state(old_state);
+	kfree(old_amdgpu_state);
+}
+
 static const struct drm_plane_funcs dm_plane_funcs = {
-	.update_plane   = drm_atomic_helper_update_plane,
-	.disable_plane  = drm_atomic_helper_disable_plane,
-	.reset = drm_atomic_helper_plane_reset,
-	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state
+	.update_plane	= drm_atomic_helper_update_plane,
+	.disable_plane	= drm_atomic_helper_disable_plane,
+	.destroy	= drm_plane_cleanup,
+	.set_property	= drm_atomic_helper_plane_set_property,
+	.reset = dm_drm_plane_reset,
+	.atomic_duplicate_state = dm_drm_plane_duplicate_state,
+	.atomic_destroy_state = dm_drm_plane_destroy_state,
 };
 
 static int dm_plane_helper_prepare_fb(
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 69aeec3..a96047b 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -721,7 +721,7 @@ EXPORT_SYMBOL(drm_atomic_get_plane_state);
  * RETURNS:
  * Zero on success, error code on failure
  */
-static int drm_atomic_plane_set_property(struct drm_plane *plane,
+int drm_atomic_plane_set_property(struct drm_plane *plane,
 		struct drm_plane_state *state, struct drm_property *property,
 		uint64_t val)
 {
@@ -778,6 +778,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
 
 	return 0;
 }
+EXPORT_SYMBOL(drm_atomic_plane_set_property);
 
 /**
  * drm_atomic_plane_get_property - get property value from plane state
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index decb9f8f..db5af8e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2367,6 +2367,61 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 EXPORT_SYMBOL(drm_atomic_helper_swap_state);
 
 /**
+ * drm_atomic_helper_plane_set_property - helper for plane properties
+ * @plane: DRM plane
+ * @property: DRM property
+ * @val: value of property
+ *
+ * Provides a default plane set_property handler using the atomic driver
+ * interface.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+int
+drm_atomic_helper_plane_set_property(struct drm_plane *plane,
+                                    struct drm_property *property,
+                                    uint64_t val)
+{
+        struct drm_atomic_state *state;
+        struct drm_plane_state *plane_state;
+        int ret = 0;
+
+        state = drm_atomic_state_alloc(plane->dev);
+        if (!state)
+                return -ENOMEM;
+
+        /* ->set_property is always called with all locks held. */
+        state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
+retry:
+        plane_state = drm_atomic_get_plane_state(state, plane);
+        if (IS_ERR(plane_state)) {
+                ret = PTR_ERR(plane_state);
+                goto fail;
+        }
+
+        ret = drm_atomic_plane_set_property(plane, plane_state,
+                        property, val);
+        if (ret)
+                goto fail;
+
+        ret = drm_atomic_commit(state);
+fail:
+        if (ret == -EDEADLK)
+                goto backoff;
+
+        drm_atomic_state_put(state);
+        return ret;
+
+backoff:
+        drm_atomic_state_clear(state);
+        drm_atomic_legacy_backoff(state);
+
+        goto retry;
+}
+EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
+
+/**
  * drm_atomic_helper_update_plane - Helper for primary plane update using atomic
  * @plane: plane object to update
  * @crtc: owning CRTC of owning plane
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 7c0f63c..f5ce777 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -315,6 +315,9 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
 struct drm_plane_state * __must_check
 drm_atomic_get_plane_state(struct drm_atomic_state *state,
 			   struct drm_plane *plane);
+int drm_atomic_plane_set_property(struct drm_plane *plane,
+		 struct drm_plane_state *state, struct drm_property *property,
+		 uint64_t val);
 struct drm_connector_state * __must_check
 drm_atomic_get_connector_state(struct drm_atomic_state *state,
 			       struct drm_connector *connector);
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index f3743d9..a02abab 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -127,6 +127,9 @@ int drm_atomic_helper_resume(struct drm_device *dev,
 int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
                                         struct drm_property *property,
                                         uint64_t val);
+int drm_atomic_helper_plane_set_property(struct drm_plane *plane,
+                                        struct drm_property *property,
+                                        uint64_t val);
 int drm_atomic_helper_connector_set_property(struct drm_connector *connector,
                                         struct drm_property *property,
                                         uint64_t val);
-- 
2.7.4