This source file includes following definitions.
- intel_plane_alloc
- intel_plane_free
- intel_plane_duplicate_state
- intel_plane_destroy_state
- intel_plane_data_rate
- intel_plane_atomic_check_with_state
- get_crtc_from_states
- intel_plane_atomic_check
- skl_next_plane_to_commit
- intel_update_plane
- intel_update_slave
- intel_disable_plane
- skl_update_planes_on_crtc
- i9xx_update_planes_on_crtc
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 #include <drm/drm_atomic_helper.h>
35 #include <drm/drm_fourcc.h>
36 #include <drm/drm_plane_helper.h>
37
38 #include "i915_trace.h"
39 #include "intel_atomic_plane.h"
40 #include "intel_display_types.h"
41 #include "intel_pm.h"
42 #include "intel_sprite.h"
43
44 struct intel_plane *intel_plane_alloc(void)
45 {
46 struct intel_plane_state *plane_state;
47 struct intel_plane *plane;
48
49 plane = kzalloc(sizeof(*plane), GFP_KERNEL);
50 if (!plane)
51 return ERR_PTR(-ENOMEM);
52
53 plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
54 if (!plane_state) {
55 kfree(plane);
56 return ERR_PTR(-ENOMEM);
57 }
58
59 __drm_atomic_helper_plane_reset(&plane->base, &plane_state->base);
60 plane_state->scaler_id = -1;
61
62 return plane;
63 }
64
65 void intel_plane_free(struct intel_plane *plane)
66 {
67 intel_plane_destroy_state(&plane->base, plane->base.state);
68 kfree(plane);
69 }
70
71
72
73
74
75
76
77
78
79
80 struct drm_plane_state *
81 intel_plane_duplicate_state(struct drm_plane *plane)
82 {
83 struct drm_plane_state *state;
84 struct intel_plane_state *intel_state;
85
86 intel_state = kmemdup(plane->state, sizeof(*intel_state), GFP_KERNEL);
87
88 if (!intel_state)
89 return NULL;
90
91 state = &intel_state->base;
92
93 __drm_atomic_helper_plane_duplicate_state(plane, state);
94
95 intel_state->vma = NULL;
96 intel_state->flags = 0;
97
98 return state;
99 }
100
101
102
103
104
105
106
107
108
109 void
110 intel_plane_destroy_state(struct drm_plane *plane,
111 struct drm_plane_state *state)
112 {
113 WARN_ON(to_intel_plane_state(state)->vma);
114
115 drm_atomic_helper_plane_destroy_state(plane, state);
116 }
117
118 unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
119 const struct intel_plane_state *plane_state)
120 {
121 const struct drm_framebuffer *fb = plane_state->base.fb;
122 unsigned int cpp;
123
124 if (!plane_state->base.visible)
125 return 0;
126
127 cpp = fb->format->cpp[0];
128
129
130
131
132
133
134
135 if (fb->format->is_yuv && fb->format->num_planes > 1)
136 cpp *= 4;
137
138 return cpp * crtc_state->pixel_rate;
139 }
140
141 int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
142 struct intel_crtc_state *new_crtc_state,
143 const struct intel_plane_state *old_plane_state,
144 struct intel_plane_state *new_plane_state)
145 {
146 struct intel_plane *plane = to_intel_plane(new_plane_state->base.plane);
147 int ret;
148
149 new_crtc_state->active_planes &= ~BIT(plane->id);
150 new_crtc_state->nv12_planes &= ~BIT(plane->id);
151 new_crtc_state->c8_planes &= ~BIT(plane->id);
152 new_crtc_state->data_rate[plane->id] = 0;
153 new_plane_state->base.visible = false;
154
155 if (!new_plane_state->base.crtc && !old_plane_state->base.crtc)
156 return 0;
157
158 ret = plane->check_plane(new_crtc_state, new_plane_state);
159 if (ret)
160 return ret;
161
162
163 if (new_plane_state->base.visible)
164 new_crtc_state->active_planes |= BIT(plane->id);
165
166 if (new_plane_state->base.visible &&
167 is_planar_yuv_format(new_plane_state->base.fb->format->format))
168 new_crtc_state->nv12_planes |= BIT(plane->id);
169
170 if (new_plane_state->base.visible &&
171 new_plane_state->base.fb->format->format == DRM_FORMAT_C8)
172 new_crtc_state->c8_planes |= BIT(plane->id);
173
174 if (new_plane_state->base.visible || old_plane_state->base.visible)
175 new_crtc_state->update_planes |= BIT(plane->id);
176
177 new_crtc_state->data_rate[plane->id] =
178 intel_plane_data_rate(new_crtc_state, new_plane_state);
179
180 return intel_plane_atomic_calc_changes(old_crtc_state, new_crtc_state,
181 old_plane_state, new_plane_state);
182 }
183
184 static struct intel_crtc *
185 get_crtc_from_states(const struct intel_plane_state *old_plane_state,
186 const struct intel_plane_state *new_plane_state)
187 {
188 if (new_plane_state->base.crtc)
189 return to_intel_crtc(new_plane_state->base.crtc);
190
191 if (old_plane_state->base.crtc)
192 return to_intel_crtc(old_plane_state->base.crtc);
193
194 return NULL;
195 }
196
197 static int intel_plane_atomic_check(struct drm_plane *_plane,
198 struct drm_plane_state *_new_plane_state)
199 {
200 struct intel_plane *plane = to_intel_plane(_plane);
201 struct intel_atomic_state *state =
202 to_intel_atomic_state(_new_plane_state->state);
203 struct intel_plane_state *new_plane_state =
204 to_intel_plane_state(_new_plane_state);
205 const struct intel_plane_state *old_plane_state =
206 intel_atomic_get_old_plane_state(state, plane);
207 struct intel_crtc *crtc =
208 get_crtc_from_states(old_plane_state, new_plane_state);
209 const struct intel_crtc_state *old_crtc_state;
210 struct intel_crtc_state *new_crtc_state;
211
212 new_plane_state->base.visible = false;
213 if (!crtc)
214 return 0;
215
216 old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
217 new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
218
219 return intel_plane_atomic_check_with_state(old_crtc_state,
220 new_crtc_state,
221 old_plane_state,
222 new_plane_state);
223 }
224
225 static struct intel_plane *
226 skl_next_plane_to_commit(struct intel_atomic_state *state,
227 struct intel_crtc *crtc,
228 struct skl_ddb_entry entries_y[I915_MAX_PLANES],
229 struct skl_ddb_entry entries_uv[I915_MAX_PLANES],
230 unsigned int *update_mask)
231 {
232 struct intel_crtc_state *crtc_state =
233 intel_atomic_get_new_crtc_state(state, crtc);
234 struct intel_plane_state *plane_state;
235 struct intel_plane *plane;
236 int i;
237
238 if (*update_mask == 0)
239 return NULL;
240
241 for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
242 enum plane_id plane_id = plane->id;
243
244 if (crtc->pipe != plane->pipe ||
245 !(*update_mask & BIT(plane_id)))
246 continue;
247
248 if (skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_y[plane_id],
249 entries_y,
250 I915_MAX_PLANES, plane_id) ||
251 skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_uv[plane_id],
252 entries_uv,
253 I915_MAX_PLANES, plane_id))
254 continue;
255
256 *update_mask &= ~BIT(plane_id);
257 entries_y[plane_id] = crtc_state->wm.skl.plane_ddb_y[plane_id];
258 entries_uv[plane_id] = crtc_state->wm.skl.plane_ddb_uv[plane_id];
259
260 return plane;
261 }
262
263
264 WARN_ON(1);
265
266 return NULL;
267 }
268
269 void intel_update_plane(struct intel_plane *plane,
270 const struct intel_crtc_state *crtc_state,
271 const struct intel_plane_state *plane_state)
272 {
273 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
274
275 trace_intel_update_plane(&plane->base, crtc);
276 plane->update_plane(plane, crtc_state, plane_state);
277 }
278
279 void intel_update_slave(struct intel_plane *plane,
280 const struct intel_crtc_state *crtc_state,
281 const struct intel_plane_state *plane_state)
282 {
283 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
284
285 trace_intel_update_plane(&plane->base, crtc);
286 plane->update_slave(plane, crtc_state, plane_state);
287 }
288
289 void intel_disable_plane(struct intel_plane *plane,
290 const struct intel_crtc_state *crtc_state)
291 {
292 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
293
294 trace_intel_disable_plane(&plane->base, crtc);
295 plane->disable_plane(plane, crtc_state);
296 }
297
298 void skl_update_planes_on_crtc(struct intel_atomic_state *state,
299 struct intel_crtc *crtc)
300 {
301 struct intel_crtc_state *old_crtc_state =
302 intel_atomic_get_old_crtc_state(state, crtc);
303 struct intel_crtc_state *new_crtc_state =
304 intel_atomic_get_new_crtc_state(state, crtc);
305 struct skl_ddb_entry entries_y[I915_MAX_PLANES];
306 struct skl_ddb_entry entries_uv[I915_MAX_PLANES];
307 u32 update_mask = new_crtc_state->update_planes;
308 struct intel_plane *plane;
309
310 memcpy(entries_y, old_crtc_state->wm.skl.plane_ddb_y,
311 sizeof(old_crtc_state->wm.skl.plane_ddb_y));
312 memcpy(entries_uv, old_crtc_state->wm.skl.plane_ddb_uv,
313 sizeof(old_crtc_state->wm.skl.plane_ddb_uv));
314
315 while ((plane = skl_next_plane_to_commit(state, crtc,
316 entries_y, entries_uv,
317 &update_mask))) {
318 struct intel_plane_state *new_plane_state =
319 intel_atomic_get_new_plane_state(state, plane);
320
321 if (new_plane_state->base.visible) {
322 intel_update_plane(plane, new_crtc_state, new_plane_state);
323 } else if (new_plane_state->slave) {
324 struct intel_plane *master =
325 new_plane_state->linked_plane;
326
327
328
329
330
331
332
333
334
335
336 new_plane_state =
337 intel_atomic_get_new_plane_state(state, master);
338
339 intel_update_slave(plane, new_crtc_state, new_plane_state);
340 } else {
341 intel_disable_plane(plane, new_crtc_state);
342 }
343 }
344 }
345
346 void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
347 struct intel_crtc *crtc)
348 {
349 struct intel_crtc_state *new_crtc_state =
350 intel_atomic_get_new_crtc_state(state, crtc);
351 u32 update_mask = new_crtc_state->update_planes;
352 struct intel_plane_state *new_plane_state;
353 struct intel_plane *plane;
354 int i;
355
356 for_each_new_intel_plane_in_state(state, plane, new_plane_state, i) {
357 if (crtc->pipe != plane->pipe ||
358 !(update_mask & BIT(plane->id)))
359 continue;
360
361 if (new_plane_state->base.visible)
362 intel_update_plane(plane, new_crtc_state, new_plane_state);
363 else
364 intel_disable_plane(plane, new_crtc_state);
365 }
366 }
367
368 const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
369 .prepare_fb = intel_prepare_plane_fb,
370 .cleanup_fb = intel_cleanup_plane_fb,
371 .atomic_check = intel_plane_atomic_check,
372 };