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/drmP.h>
35#include <drm/drm_atomic_helper.h>
36#include <drm/drm_plane_helper.h>
37#include "intel_drv.h"
38
39
40
41
42
43
44
45
46
47
48struct intel_plane_state *
49intel_create_plane_state(struct drm_plane *plane)
50{
51 struct intel_plane_state *state;
52
53 state = kzalloc(sizeof(*state), GFP_KERNEL);
54 if (!state)
55 return NULL;
56
57 state->base.plane = plane;
58 state->base.rotation = DRM_MODE_ROTATE_0;
59 state->ckey.flags = I915_SET_COLORKEY_NONE;
60
61 return state;
62}
63
64
65
66
67
68
69
70
71
72
73struct drm_plane_state *
74intel_plane_duplicate_state(struct drm_plane *plane)
75{
76 struct drm_plane_state *state;
77 struct intel_plane_state *intel_state;
78
79 intel_state = kmemdup(plane->state, sizeof(*intel_state), GFP_KERNEL);
80
81 if (!intel_state)
82 return NULL;
83
84 state = &intel_state->base;
85
86 __drm_atomic_helper_plane_duplicate_state(plane, state);
87
88 intel_state->vma = NULL;
89
90 return state;
91}
92
93
94
95
96
97
98
99
100
101void
102intel_plane_destroy_state(struct drm_plane *plane,
103 struct drm_plane_state *state)
104{
105 WARN_ON(to_intel_plane_state(state)->vma);
106
107 drm_atomic_helper_plane_destroy_state(plane, state);
108}
109
110int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state,
111 struct intel_plane_state *intel_state)
112{
113 struct drm_plane *plane = intel_state->base.plane;
114 struct drm_i915_private *dev_priv = to_i915(plane->dev);
115 struct drm_plane_state *state = &intel_state->base;
116 struct intel_plane *intel_plane = to_intel_plane(plane);
117 const struct drm_display_mode *adjusted_mode =
118 &crtc_state->base.adjusted_mode;
119 int ret;
120
121
122
123
124
125
126
127 if (!intel_state->base.crtc && !plane->state->crtc)
128 return 0;
129
130
131 intel_state->clip.x1 = 0;
132 intel_state->clip.y1 = 0;
133 intel_state->clip.x2 =
134 crtc_state->base.enable ? crtc_state->pipe_src_w : 0;
135 intel_state->clip.y2 =
136 crtc_state->base.enable ? crtc_state->pipe_src_h : 0;
137
138 if (state->fb && drm_rotation_90_or_270(state->rotation)) {
139 struct drm_format_name_buf format_name;
140
141 if (state->fb->modifier != I915_FORMAT_MOD_Y_TILED &&
142 state->fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
143 DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
144 return -EINVAL;
145 }
146
147
148
149
150
151
152 switch (state->fb->format->format) {
153 case DRM_FORMAT_C8:
154 case DRM_FORMAT_RGB565:
155 DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
156 drm_get_format_name(state->fb->format->format,
157 &format_name));
158 return -EINVAL;
159
160 default:
161 break;
162 }
163 }
164
165
166 if (IS_CHERRYVIEW(dev_priv) &&
167 state->rotation & DRM_MODE_ROTATE_180 &&
168 state->rotation & DRM_MODE_REFLECT_X) {
169 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
170 return -EINVAL;
171 }
172
173 intel_state->base.visible = false;
174 ret = intel_plane->check_plane(intel_plane, crtc_state, intel_state);
175 if (ret)
176 return ret;
177
178
179
180
181
182 if (state->fb && INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
183 adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
184 if (state->fb->modifier == I915_FORMAT_MOD_Y_TILED ||
185 state->fb->modifier == I915_FORMAT_MOD_Yf_TILED) {
186 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
187 return -EINVAL;
188 }
189 }
190
191
192 if (intel_state->base.visible)
193 crtc_state->active_planes |= BIT(intel_plane->id);
194 else
195 crtc_state->active_planes &= ~BIT(intel_plane->id);
196
197 return intel_plane_atomic_calc_changes(&crtc_state->base, state);
198}
199
200static int intel_plane_atomic_check(struct drm_plane *plane,
201 struct drm_plane_state *state)
202{
203 struct drm_crtc *crtc = state->crtc;
204 struct drm_crtc_state *drm_crtc_state;
205
206 crtc = crtc ? crtc : plane->state->crtc;
207
208
209
210
211
212
213
214 if (!crtc)
215 return 0;
216
217 drm_crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
218 if (WARN_ON(!drm_crtc_state))
219 return -EINVAL;
220
221 return intel_plane_atomic_check_with_state(to_intel_crtc_state(drm_crtc_state),
222 to_intel_plane_state(state));
223}
224
225static void intel_plane_atomic_update(struct drm_plane *plane,
226 struct drm_plane_state *old_state)
227{
228 struct intel_plane *intel_plane = to_intel_plane(plane);
229 struct intel_plane_state *intel_state =
230 to_intel_plane_state(plane->state);
231 struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc;
232
233 if (intel_state->base.visible) {
234 trace_intel_update_plane(plane,
235 to_intel_crtc(crtc));
236
237 intel_plane->update_plane(intel_plane,
238 to_intel_crtc_state(crtc->state),
239 intel_state);
240 } else {
241 trace_intel_disable_plane(plane,
242 to_intel_crtc(crtc));
243
244 intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
245 }
246}
247
248const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
249 .prepare_fb = intel_prepare_plane_fb,
250 .cleanup_fb = intel_cleanup_plane_fb,
251 .atomic_check = intel_plane_atomic_check,
252 .atomic_update = intel_plane_atomic_update,
253};
254
255
256
257
258
259
260
261
262
263
264
265
266int
267intel_plane_atomic_get_property(struct drm_plane *plane,
268 const struct drm_plane_state *state,
269 struct drm_property *property,
270 uint64_t *val)
271{
272 DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name);
273 return -EINVAL;
274}
275
276
277
278
279
280
281
282
283
284
285
286
287
288int
289intel_plane_atomic_set_property(struct drm_plane *plane,
290 struct drm_plane_state *state,
291 struct drm_property *property,
292 uint64_t val)
293{
294 DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name);
295 return -EINVAL;
296}
297