This source file includes following definitions.
- get_connectors_for_crtc
- drm_plane_helper_check_update
- drm_primary_helper_update
- drm_primary_helper_disable
- drm_primary_helper_destroy
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 #include <linux/list.h>
27
28 #include <drm/drm_atomic.h>
29 #include <drm/drm_atomic_helper.h>
30 #include <drm/drm_atomic_uapi.h>
31 #include <drm/drm_crtc_helper.h>
32 #include <drm/drm_device.h>
33 #include <drm/drm_encoder.h>
34 #include <drm/drm_plane_helper.h>
35 #include <drm/drm_rect.h>
36
37 #define SUBPIXEL_MASK 0xffff
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 static int get_connectors_for_crtc(struct drm_crtc *crtc,
72 struct drm_connector **connector_list,
73 int num_connectors)
74 {
75 struct drm_device *dev = crtc->dev;
76 struct drm_connector *connector;
77 struct drm_connector_list_iter conn_iter;
78 int count = 0;
79
80
81
82
83
84
85 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
86
87 drm_connector_list_iter_begin(dev, &conn_iter);
88 drm_for_each_connector_iter(connector, &conn_iter) {
89 if (connector->encoder && connector->encoder->crtc == crtc) {
90 if (connector_list != NULL && count < num_connectors)
91 *(connector_list++) = connector;
92
93 count++;
94 }
95 }
96 drm_connector_list_iter_end(&conn_iter);
97
98 return count;
99 }
100
101 static int drm_plane_helper_check_update(struct drm_plane *plane,
102 struct drm_crtc *crtc,
103 struct drm_framebuffer *fb,
104 struct drm_rect *src,
105 struct drm_rect *dst,
106 unsigned int rotation,
107 int min_scale,
108 int max_scale,
109 bool can_position,
110 bool can_update_disabled,
111 bool *visible)
112 {
113 struct drm_plane_state plane_state = {
114 .plane = plane,
115 .crtc = crtc,
116 .fb = fb,
117 .src_x = src->x1,
118 .src_y = src->y1,
119 .src_w = drm_rect_width(src),
120 .src_h = drm_rect_height(src),
121 .crtc_x = dst->x1,
122 .crtc_y = dst->y1,
123 .crtc_w = drm_rect_width(dst),
124 .crtc_h = drm_rect_height(dst),
125 .rotation = rotation,
126 .visible = *visible,
127 };
128 struct drm_crtc_state crtc_state = {
129 .crtc = crtc,
130 .enable = crtc->enabled,
131 .mode = crtc->mode,
132 };
133 int ret;
134
135 ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
136 min_scale, max_scale,
137 can_position,
138 can_update_disabled);
139 if (ret)
140 return ret;
141
142 *src = plane_state.src;
143 *dst = plane_state.dst;
144 *visible = plane_state.visible;
145
146 return 0;
147 }
148
149 static int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
150 struct drm_framebuffer *fb,
151 int crtc_x, int crtc_y,
152 unsigned int crtc_w, unsigned int crtc_h,
153 uint32_t src_x, uint32_t src_y,
154 uint32_t src_w, uint32_t src_h,
155 struct drm_modeset_acquire_ctx *ctx)
156 {
157 struct drm_mode_set set = {
158 .crtc = crtc,
159 .fb = fb,
160 .mode = &crtc->mode,
161 .x = src_x >> 16,
162 .y = src_y >> 16,
163 };
164 struct drm_rect src = {
165 .x1 = src_x,
166 .y1 = src_y,
167 .x2 = src_x + src_w,
168 .y2 = src_y + src_h,
169 };
170 struct drm_rect dest = {
171 .x1 = crtc_x,
172 .y1 = crtc_y,
173 .x2 = crtc_x + crtc_w,
174 .y2 = crtc_y + crtc_h,
175 };
176 struct drm_connector **connector_list;
177 int num_connectors, ret;
178 bool visible;
179
180 ret = drm_plane_helper_check_update(plane, crtc, fb,
181 &src, &dest,
182 DRM_MODE_ROTATE_0,
183 DRM_PLANE_HELPER_NO_SCALING,
184 DRM_PLANE_HELPER_NO_SCALING,
185 false, false, &visible);
186 if (ret)
187 return ret;
188
189 if (!visible)
190
191
192
193
194
195 return plane->funcs->disable_plane(plane, ctx);
196
197
198 num_connectors = get_connectors_for_crtc(crtc, NULL, 0);
199 BUG_ON(num_connectors == 0);
200 connector_list = kcalloc(num_connectors, sizeof(*connector_list),
201 GFP_KERNEL);
202 if (!connector_list)
203 return -ENOMEM;
204 get_connectors_for_crtc(crtc, connector_list, num_connectors);
205
206 set.connectors = connector_list;
207 set.num_connectors = num_connectors;
208
209
210
211
212
213
214
215
216
217 ret = crtc->funcs->set_config(&set, ctx);
218
219 kfree(connector_list);
220 return ret;
221 }
222
223 static int drm_primary_helper_disable(struct drm_plane *plane,
224 struct drm_modeset_acquire_ctx *ctx)
225 {
226 return -EINVAL;
227 }
228
229
230
231
232
233
234
235
236
237 void drm_primary_helper_destroy(struct drm_plane *plane)
238 {
239 drm_plane_cleanup(plane);
240 kfree(plane);
241 }
242 EXPORT_SYMBOL(drm_primary_helper_destroy);
243
244 const struct drm_plane_funcs drm_primary_helper_funcs = {
245 .update_plane = drm_primary_helper_update,
246 .disable_plane = drm_primary_helper_disable,
247 .destroy = drm_primary_helper_destroy,
248 };
249 EXPORT_SYMBOL(drm_primary_helper_funcs);