hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
....@@ -1,191 +1,254 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
34 * Author:Mark Yao <mark.yao@rock-chips.com>
4
- *
5
- * This software is licensed under the terms of the GNU General Public
6
- * License version 2, as published by the Free Software Foundation, and
7
- * may be copied, distributed, and modified under those terms.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
135 */
146
157 #include <linux/kernel.h>
8
+#include <linux/devfreq.h>
9
+
1610 #include <drm/drm.h>
17
-#include <drm/drmP.h>
1811 #include <drm/drm_atomic.h>
12
+#include <drm/drm_damage_helper.h>
1913 #include <drm/drm_fb_helper.h>
20
-#include <drm/drm_crtc_helper.h>
14
+#include <drm/drm_fourcc.h>
2115 #include <drm/drm_gem_framebuffer_helper.h>
22
-#include <linux/memblock.h>
16
+#include <drm/drm_probe_helper.h>
2317 #include <soc/rockchip/rockchip_dmc.h>
2418
2519 #include "rockchip_drm_drv.h"
2620 #include "rockchip_drm_fb.h"
2721 #include "rockchip_drm_gem.h"
28
-#include "rockchip_drm_psr.h"
22
+#include "rockchip_drm_logo.h"
2923
30
-bool rockchip_fb_is_logo(struct drm_framebuffer *fb)
24
+static bool is_rockchip_logo_fb(struct drm_framebuffer *fb)
3125 {
32
- struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb);
33
-
34
- return rk_fb && rk_fb->logo;
26
+ return fb->flags & ROCKCHIP_DRM_MODE_LOGO_FB ? true : false;
3527 }
3628
37
-dma_addr_t rockchip_fb_get_dma_addr(struct drm_framebuffer *fb,
38
- unsigned int plane)
29
+static void __rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
3930 {
40
- struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb);
31
+ int i = 0;
4132
42
- if (WARN_ON(plane >= ROCKCHIP_MAX_FB_BUFFER))
43
- return 0;
33
+ drm_framebuffer_cleanup(fb);
4434
45
- return rk_fb->dma_addr[plane];
35
+ if (is_rockchip_logo_fb(fb)) {
36
+ struct rockchip_drm_logo_fb *rockchip_logo_fb = to_rockchip_logo_fb(fb);
37
+
38
+#ifndef MODULE
39
+ rockchip_free_loader_memory(fb->dev);
40
+#endif
41
+ drm_gem_object_release(rockchip_logo_fb->fb.obj[0]);
42
+ kfree(rockchip_logo_fb);
43
+ } else {
44
+ for (i = 0; i < 4; i++) {
45
+ if (fb->obj[i])
46
+ drm_gem_object_put(fb->obj[i]);
47
+ }
48
+
49
+ kfree(fb);
50
+ }
4651 }
4752
48
-void *rockchip_fb_get_kvaddr(struct drm_framebuffer *fb, unsigned int plane)
53
+static void rockchip_drm_fb_destroy_work(struct work_struct *work)
4954 {
50
- struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb);
55
+ struct rockchip_drm_logo_fb *fb;
5156
52
- if (WARN_ON(plane >= ROCKCHIP_MAX_FB_BUFFER))
53
- return 0;
57
+ fb = container_of(to_delayed_work(work), struct rockchip_drm_logo_fb, destroy_work);
5458
55
- return rk_fb->kvaddr[plane];
59
+ __rockchip_drm_fb_destroy(&fb->fb);
5660 }
5761
5862 static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
5963 {
60
- struct drm_gem_object *obj;
61
- int i;
62
- struct rockchip_drm_fb *rockchip_fb = to_rockchip_fb(fb);
6364
64
- for (i = 0; i < ROCKCHIP_MAX_FB_BUFFER; i++) {
65
- obj = rockchip_fb->obj[i];
66
- if (obj)
67
- drm_gem_object_unreference_unlocked(obj);
65
+ if (is_rockchip_logo_fb(fb)) {
66
+ struct rockchip_drm_logo_fb *rockchip_logo_fb = to_rockchip_logo_fb(fb);
67
+
68
+ schedule_delayed_work(&rockchip_logo_fb->destroy_work, HZ);
69
+ } else {
70
+ __rockchip_drm_fb_destroy(fb);
6871 }
69
-
70
-#ifndef MODULE
71
- if (rockchip_fb->logo)
72
- rockchip_free_loader_memory(fb->dev);
73
-#else
74
- WARN_ON(rockchip_fb->logo);
75
-#endif
76
-
77
- drm_framebuffer_cleanup(fb);
78
- kfree(rockchip_fb);
7972 }
8073
81
-static int rockchip_drm_fb_create_handle(struct drm_framebuffer *fb,
82
- struct drm_file *file_priv,
83
- unsigned int *handle)
74
+static int rockchip_drm_gem_fb_create_handle(struct drm_framebuffer *fb,
75
+ struct drm_file *file,
76
+ unsigned int *handle)
8477 {
85
- struct rockchip_drm_fb *rockchip_fb = to_rockchip_fb(fb);
86
-
87
- if (rockchip_fb_is_logo(fb))
78
+ if (is_rockchip_logo_fb(fb))
8879 return -EOPNOTSUPP;
8980
90
- return drm_gem_handle_create(file_priv,
91
- rockchip_fb->obj[0], handle);
92
-}
93
-
94
-static int rockchip_drm_fb_dirty(struct drm_framebuffer *fb,
95
- struct drm_file *file,
96
- unsigned int flags, unsigned int color,
97
- struct drm_clip_rect *clips,
98
- unsigned int num_clips)
99
-{
100
- rockchip_drm_psr_flush_all(fb->dev);
101
- return 0;
81
+ return drm_gem_fb_create_handle(fb, file, handle);
10282 }
10383
10484 static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = {
10585 .destroy = rockchip_drm_fb_destroy,
106
- .create_handle = rockchip_drm_fb_create_handle,
107
- .dirty = rockchip_drm_fb_dirty,
86
+ .create_handle = rockchip_drm_gem_fb_create_handle,
10887 };
10988
11089 struct drm_framebuffer *
11190 rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd,
112
- struct drm_gem_object **obj, struct rockchip_logo *logo,
113
- unsigned int num_planes)
114
-{
115
- struct rockchip_drm_fb *rockchip_fb;
116
- struct rockchip_gem_object *rk_obj;
117
- struct rockchip_drm_private *private = dev->dev_private;
118
- struct drm_fb_helper *fb_helper = private->fbdev_helper;
119
- int ret = 0;
120
- int i;
121
-
122
- rockchip_fb = kzalloc(sizeof(*rockchip_fb), GFP_KERNEL);
123
- if (!rockchip_fb)
124
- return ERR_PTR(-ENOMEM);
125
-
126
- drm_helper_mode_fill_fb_struct(dev, &rockchip_fb->fb, mode_cmd);
127
-
128
- ret = drm_framebuffer_init(dev, &rockchip_fb->fb,
129
- &rockchip_drm_fb_funcs);
130
- if (ret) {
131
- dev_err(dev->dev, "Failed to initialize framebuffer: %d\n",
132
- ret);
133
- goto err_free_fb;
134
- }
135
-
136
- if (obj) {
137
- for (i = 0; i < num_planes; i++)
138
- rockchip_fb->obj[i] = obj[i];
139
-
140
- for (i = 0; i < num_planes; i++) {
141
- rk_obj = to_rockchip_obj(obj[i]);
142
- rockchip_fb->dma_addr[i] = rk_obj->dma_addr;
143
- rockchip_fb->kvaddr[i] = rk_obj->kvaddr;
144
- private->fbdev_bo = &rk_obj->base;
145
- if (fb_helper && fb_helper->fbdev && rk_obj->kvaddr)
146
- fb_helper->fbdev->screen_base = rk_obj->kvaddr;
147
- }
148
-#ifndef MODULE
149
- } else if (logo) {
150
- rockchip_fb->dma_addr[0] = logo->dma_addr;
151
- rockchip_fb->kvaddr[0] = logo->kvaddr;
152
- rockchip_fb->logo = logo;
153
- logo->count++;
154
-#endif
155
- } else {
156
- ret = -EINVAL;
157
- dev_err(dev->dev, "Failed to find available buffer\n");
158
- goto err_deinit_drm_fb;
159
- }
160
-
161
- return &rockchip_fb->fb;
162
-
163
-err_deinit_drm_fb:
164
- drm_framebuffer_cleanup(&rockchip_fb->fb);
165
-err_free_fb:
166
- kfree(rockchip_fb);
167
- return ERR_PTR(ret);
168
-}
169
-
170
-static struct drm_framebuffer *
171
-rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
172
- const struct drm_mode_fb_cmd2 *mode_cmd)
91
+ struct drm_gem_object **obj, unsigned int num_planes)
17392 {
17493 struct drm_framebuffer *fb;
175
- struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
176
- struct drm_gem_object *obj;
177
- unsigned int hsub;
178
- unsigned int vsub;
179
- int num_planes;
18094 int ret;
18195 int i;
18296
183
- hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
184
- vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
185
- num_planes = min(drm_format_num_planes(mode_cmd->pixel_format),
186
- ROCKCHIP_MAX_FB_BUFFER);
97
+ fb = kzalloc(sizeof(*fb), GFP_KERNEL);
98
+ if (!fb)
99
+ return ERR_PTR(-ENOMEM);
187100
188
- for (i = 0; i < num_planes; ++i) {
101
+ drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
102
+
103
+ for (i = 0; i < num_planes; i++)
104
+ fb->obj[i] = obj[i];
105
+
106
+ ret = drm_framebuffer_init(dev, fb, &rockchip_drm_fb_funcs);
107
+ if (ret) {
108
+ DRM_DEV_ERROR(dev->dev,
109
+ "Failed to initialize framebuffer: %d\n",
110
+ ret);
111
+ kfree(fb);
112
+ return ERR_PTR(ret);
113
+ }
114
+
115
+ return fb;
116
+}
117
+
118
+struct drm_framebuffer *
119
+rockchip_drm_logo_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd,
120
+ struct rockchip_logo *logo)
121
+{
122
+ int ret = 0;
123
+ struct rockchip_drm_logo_fb *rockchip_logo_fb;
124
+ struct drm_framebuffer *fb;
125
+
126
+ rockchip_logo_fb = kzalloc(sizeof(*rockchip_logo_fb), GFP_KERNEL);
127
+ if (!rockchip_logo_fb)
128
+ return ERR_PTR(-ENOMEM);
129
+ fb = &rockchip_logo_fb->fb;
130
+
131
+ drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
132
+
133
+ ret = drm_framebuffer_init(dev, fb, &rockchip_drm_fb_funcs);
134
+ if (ret) {
135
+ DRM_DEV_ERROR(dev->dev,
136
+ "Failed to initialize rockchip logo fb: %d\n",
137
+ ret);
138
+ kfree(rockchip_logo_fb);
139
+ return ERR_PTR(ret);
140
+ }
141
+
142
+ fb->flags |= ROCKCHIP_DRM_MODE_LOGO_FB;
143
+ rockchip_logo_fb->logo = logo;
144
+ rockchip_logo_fb->fb.obj[0] = &rockchip_logo_fb->rk_obj.base;
145
+ drm_gem_object_init(dev, rockchip_logo_fb->fb.obj[0], PAGE_ALIGN(logo->size));
146
+ rockchip_logo_fb->rk_obj.dma_addr = logo->dma_addr;
147
+ rockchip_logo_fb->rk_obj.kvaddr = logo->kvaddr;
148
+ logo->count++;
149
+ INIT_DELAYED_WORK(&rockchip_logo_fb->destroy_work, rockchip_drm_fb_destroy_work);
150
+ return &rockchip_logo_fb->fb;
151
+}
152
+
153
+static int rockchip_drm_bandwidth_atomic_check(struct drm_device *dev,
154
+ struct drm_atomic_state *state,
155
+ struct dmcfreq_vop_info *vop_bw_info)
156
+{
157
+ struct rockchip_drm_private *priv = dev->dev_private;
158
+ struct drm_crtc_state *old_crtc_state;
159
+ const struct rockchip_crtc_funcs *funcs;
160
+ struct drm_crtc *crtc;
161
+ int i;
162
+
163
+ vop_bw_info->line_bw_mbyte = 0;
164
+ vop_bw_info->frame_bw_mbyte = 0;
165
+ vop_bw_info->plane_num = 0;
166
+ vop_bw_info->plane_num_4k = 0;
167
+
168
+ for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
169
+ funcs = priv->crtc_funcs[drm_crtc_index(crtc)];
170
+
171
+ if (funcs && funcs->bandwidth)
172
+ funcs->bandwidth(crtc, old_crtc_state, vop_bw_info);
173
+ }
174
+
175
+ return 0;
176
+}
177
+
178
+static void drm_atomic_helper_connector_commit(struct drm_device *dev,
179
+ struct drm_atomic_state *old_state)
180
+{
181
+ struct drm_connector *connector;
182
+ struct drm_connector_state *new_conn_state;
183
+ int i;
184
+
185
+ for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
186
+ const struct drm_connector_helper_funcs *funcs;
187
+
188
+ funcs = connector->helper_private;
189
+ if (!funcs->atomic_commit)
190
+ continue;
191
+
192
+ funcs->atomic_commit(connector, new_conn_state);
193
+ }
194
+}
195
+
196
+/**
197
+ * rockchip_drm_atomic_helper_commit_tail_rpm - commit atomic update to hardware
198
+ * @old_state: new modeset state to be committed
199
+ *
200
+ * This is an alternative implementation for the
201
+ * &drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers
202
+ * that support runtime_pm or need the CRTC to be enabled to perform a
203
+ * commit. Otherwise, one should use the default implementation
204
+ * drm_atomic_helper_commit_tail().
205
+ */
206
+static void rockchip_drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
207
+{
208
+ struct drm_device *dev = old_state->dev;
209
+ struct rockchip_drm_private *prv = dev->dev_private;
210
+ struct dmcfreq_vop_info vop_bw_info;
211
+
212
+ drm_atomic_helper_commit_modeset_disables(dev, old_state);
213
+
214
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
215
+
216
+ rockchip_drm_bandwidth_atomic_check(dev, old_state, &vop_bw_info);
217
+
218
+ rockchip_dmcfreq_vop_bandwidth_update(&vop_bw_info);
219
+
220
+ mutex_lock(&prv->ovl_lock);
221
+ drm_atomic_helper_commit_planes(dev, old_state, DRM_PLANE_COMMIT_ACTIVE_ONLY);
222
+ mutex_unlock(&prv->ovl_lock);
223
+
224
+ drm_atomic_helper_fake_vblank(old_state);
225
+
226
+ drm_atomic_helper_connector_commit(dev, old_state);
227
+
228
+ drm_atomic_helper_commit_hw_done(old_state);
229
+
230
+ drm_atomic_helper_wait_for_vblanks(dev, old_state);
231
+
232
+ drm_atomic_helper_cleanup_planes(dev, old_state);
233
+}
234
+
235
+static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
236
+ .atomic_commit_tail = rockchip_drm_atomic_helper_commit_tail_rpm,
237
+};
238
+
239
+static struct drm_framebuffer *
240
+rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
241
+ const struct drm_mode_fb_cmd2 *mode_cmd)
242
+{
243
+ struct drm_afbc_framebuffer *afbc_fb;
244
+ const struct drm_format_info *info;
245
+ int ret, i;
246
+
247
+ info = drm_get_format_info(dev, mode_cmd);
248
+ if (!info)
249
+ return ERR_PTR(-ENOMEM);
250
+
251
+ for (i = 0; i < info->num_planes; ++i) {
189252 if (mode_cmd->pitches[i] % 4) {
190253 DRM_DEV_ERROR_RATELIMITED(dev->dev,
191254 "fb pitch[%d] must be 4 byte aligned: %d\n", i, mode_cmd->pitches[i]);
....@@ -193,43 +256,31 @@
193256 }
194257 }
195258
196
- for (i = 0; i < num_planes; i++) {
197
- unsigned int width = mode_cmd->width / (i ? hsub : 1);
198
- unsigned int height = mode_cmd->height / (i ? vsub : 1);
199
- unsigned int min_size;
259
+ afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
260
+ if (!afbc_fb)
261
+ return ERR_PTR(-ENOMEM);
200262
201
- obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
202
- if (!obj) {
203
- DRM_DEV_ERROR(dev->dev,
204
- "Failed to lookup GEM object\n");
205
- ret = -ENXIO;
206
- goto err_gem_object_unreference;
207
- }
208
-
209
- min_size = (height - 1) * mode_cmd->pitches[i] +
210
- mode_cmd->offsets[i] +
211
- width * drm_format_plane_cpp(mode_cmd->pixel_format, i);
212
-
213
- if (obj->size < min_size) {
214
- drm_gem_object_put_unlocked(obj);
215
- ret = -EINVAL;
216
- goto err_gem_object_unreference;
217
- }
218
- objs[i] = obj;
263
+ ret = drm_gem_fb_init_with_funcs(dev, &afbc_fb->base, file, mode_cmd,
264
+ &rockchip_drm_fb_funcs);
265
+ if (ret) {
266
+ kfree(afbc_fb);
267
+ return ERR_PTR(ret);
219268 }
220269
221
- fb = rockchip_fb_alloc(dev, mode_cmd, objs, NULL, i);
222
- if (IS_ERR(fb)) {
223
- ret = PTR_ERR(fb);
224
- goto err_gem_object_unreference;
270
+ if (drm_is_afbc(mode_cmd->modifier[0])) {
271
+ ret = drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb);
272
+ if (ret) {
273
+ struct drm_gem_object **obj = afbc_fb->base.obj;
274
+
275
+ for (i = 0; i < info->num_planes; ++i)
276
+ drm_gem_object_put(obj[i]);
277
+
278
+ kfree(afbc_fb);
279
+ return ERR_PTR(ret);
280
+ }
225281 }
226282
227
- return fb;
228
-
229
-err_gem_object_unreference:
230
- for (i--; i >= 0; i--)
231
- drm_gem_object_put_unlocked(objs[i]);
232
- return ERR_PTR(ret);
283
+ return &afbc_fb->base;
233284 }
234285
235286 static void rockchip_drm_output_poll_changed(struct drm_device *dev)
....@@ -241,302 +292,11 @@
241292 drm_fb_helper_hotplug_event(fb_helper);
242293 }
243294
244
-static int rockchip_drm_bandwidth_atomic_check(struct drm_device *dev,
245
- struct drm_atomic_state *state,
246
- size_t *line_bw_mbyte,
247
- size_t *frame_bw_mbyte,
248
- unsigned int *plane_num)
249
-{
250
- struct rockchip_drm_private *priv = dev->dev_private;
251
- struct drm_crtc_state *crtc_state;
252
- const struct rockchip_crtc_funcs *funcs;
253
- struct drm_crtc *crtc;
254
- int i, ret = 0;
255
-
256
- *line_bw_mbyte = 0;
257
- *frame_bw_mbyte = 0;
258
- *plane_num = 0;
259
- for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
260
- funcs = priv->crtc_funcs[drm_crtc_index(crtc)];
261
-
262
- if (funcs && funcs->bandwidth)
263
- *line_bw_mbyte += funcs->bandwidth(crtc, crtc_state,
264
- frame_bw_mbyte,
265
- plane_num);
266
- }
267
-
268
- /*
269
- * Check ddr frequency support here here.
270
- */
271
- if (priv->dmc_support && !priv->devfreq) {
272
- priv->devfreq = devfreq_get_devfreq_by_phandle(dev->dev, 0);
273
- if (IS_ERR(priv->devfreq))
274
- priv->devfreq = NULL;
275
- }
276
-
277
- if (priv->devfreq)
278
- ret = rockchip_dmcfreq_vop_bandwidth_request(priv->devfreq,
279
- *line_bw_mbyte);
280
-
281
- return ret;
282
-}
283
-
284
-static void rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state)
285
-{
286
- struct drm_crtc *crtc;
287
- struct drm_crtc_state *crtc_state;
288
- struct drm_encoder *encoder;
289
- u32 encoder_mask = 0;
290
- int i;
291
-
292
- for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
293
- encoder_mask |= crtc_state->encoder_mask;
294
- encoder_mask |= crtc->state->encoder_mask;
295
- }
296
-
297
- drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
298
- rockchip_drm_psr_inhibit_get(encoder);
299
-}
300
-
301
-static void
302
-rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state)
303
-{
304
- struct drm_crtc *crtc;
305
- struct drm_crtc_state *crtc_state;
306
- struct drm_encoder *encoder;
307
- u32 encoder_mask = 0;
308
- int i;
309
-
310
- for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
311
- encoder_mask |= crtc_state->encoder_mask;
312
- encoder_mask |= crtc->state->encoder_mask;
313
- }
314
-
315
- drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
316
- rockchip_drm_psr_inhibit_put(encoder);
317
-}
318
-
319
-static void
320
-rockchip_drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
321
- struct drm_atomic_state *old_state)
322
-{
323
- struct drm_crtc *crtc;
324
- struct drm_crtc_state *old_crtc_state, *new_crtc_state;
325
- int i, ret;
326
- unsigned int crtc_mask = 0;
327
- struct rockchip_crtc_state *s;
328
-
329
- /*
330
- * Legacy cursor ioctls are completely unsynced, and userspace
331
- * relies on that (by doing tons of cursor updates).
332
- */
333
- if (old_state->legacy_cursor_update)
334
- return;
335
-
336
- for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
337
- if (!new_crtc_state->active)
338
- continue;
339
-
340
- ret = drm_crtc_vblank_get(crtc);
341
- if (ret != 0)
342
- continue;
343
-
344
- crtc_mask |= drm_crtc_mask(crtc);
345
- old_state->crtcs[i].last_vblank_count =
346
- drm_crtc_vblank_count(crtc);
347
- }
348
-
349
- for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
350
- if (!(crtc_mask & drm_crtc_mask(crtc)))
351
- continue;
352
-
353
- ret = wait_event_timeout(dev->vblank[i].queue,
354
- old_state->crtcs[i].last_vblank_count !=
355
- drm_crtc_vblank_count(crtc),
356
- msecs_to_jiffies(50));
357
-
358
- s = to_rockchip_crtc_state(crtc->state);
359
-
360
- if (!s->mode_update && !ret)
361
- DRM_WARN("[CRTC:%d:%s] state:%d, vblank wait timed out\n",
362
- crtc->base.id, crtc->name, old_crtc_state->active);
363
-
364
- drm_crtc_vblank_put(crtc);
365
- s->mode_update = false;
366
- }
367
-}
368
-
369
-static void
370
-rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
371
-{
372
- struct drm_device *dev = old_state->dev;
373
-
374
- rockchip_drm_psr_inhibit_get_state(old_state);
375
-
376
- drm_atomic_helper_commit_modeset_disables(dev, old_state);
377
-
378
- drm_atomic_helper_commit_modeset_enables(dev, old_state);
379
-
380
- drm_atomic_helper_commit_planes(dev, old_state,
381
- DRM_PLANE_COMMIT_ACTIVE_ONLY);
382
-
383
- rockchip_drm_psr_inhibit_put_state(old_state);
384
-
385
- drm_atomic_helper_commit_hw_done(old_state);
386
-
387
- rockchip_drm_atomic_helper_wait_for_vblanks(dev, old_state);
388
-
389
- drm_atomic_helper_cleanup_planes(dev, old_state);
390
-}
391
-
392
-static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
393
- .atomic_commit_tail = rockchip_atomic_helper_commit_tail_rpm,
394
-};
395
-
396
-static void
397
-rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
398
-{
399
- struct drm_atomic_state *state = commit->state;
400
- struct drm_device *dev = commit->dev;
401
- struct rockchip_drm_private *prv = dev->dev_private;
402
- size_t line_bw_mbyte = commit->line_bw_mbyte;
403
- size_t frame_bw_mbyte = commit->frame_bw_mbyte;
404
- unsigned int plane_num = commit->plane_num;
405
-
406
- /*
407
- * TODO: do fence wait here.
408
- */
409
-
410
- /*
411
- * Rockchip crtc support runtime PM, can't update display planes
412
- * when crtc is disabled.
413
- *
414
- * drm_atomic_helper_commit comments detail that:
415
- * For drivers supporting runtime PM the recommended sequence is
416
- *
417
- * drm_atomic_helper_commit_modeset_disables(dev, state);
418
- *
419
- * drm_atomic_helper_commit_modeset_enables(dev, state);
420
- *
421
- * drm_atomic_helper_commit_planes(dev, state, true);
422
- *
423
- * See the kerneldoc entries for these three functions for more details.
424
- */
425
- drm_atomic_helper_wait_for_dependencies(state);
426
-
427
- rockchip_drm_psr_inhibit_get_state(state);
428
-
429
- drm_atomic_helper_commit_modeset_disables(dev, state);
430
-
431
- drm_atomic_helper_commit_modeset_enables(dev, state);
432
-
433
- if (prv->dmc_support && !prv->devfreq) {
434
- prv->devfreq = devfreq_get_devfreq_by_phandle(dev->dev, 0);
435
- if (IS_ERR(prv->devfreq))
436
- prv->devfreq = NULL;
437
- }
438
- if (prv->devfreq)
439
- rockchip_dmcfreq_vop_bandwidth_update(prv->devfreq, line_bw_mbyte, frame_bw_mbyte,
440
- plane_num);
441
-
442
- mutex_lock(&prv->ovl_lock);
443
- drm_atomic_helper_commit_planes(dev, state, true);
444
- mutex_unlock(&prv->ovl_lock);
445
-
446
- rockchip_drm_psr_inhibit_put_state(state);
447
-
448
- drm_atomic_helper_commit_hw_done(state);
449
-
450
- rockchip_drm_atomic_helper_wait_for_vblanks(dev, state);
451
-
452
- drm_atomic_helper_cleanup_planes(dev, state);
453
-
454
- drm_atomic_helper_commit_cleanup_done(state);
455
-
456
- drm_atomic_state_put(state);
457
-
458
- kfree(commit);
459
-}
460
-
461
-void rockchip_drm_atomic_work(struct work_struct *work)
462
-{
463
- struct rockchip_drm_private *private = container_of(work,
464
- struct rockchip_drm_private, commit_work);
465
-
466
- rockchip_atomic_commit_complete(private->commit);
467
- private->commit = NULL;
468
-}
469
-
470
-static int rockchip_drm_atomic_commit(struct drm_device *dev,
471
- struct drm_atomic_state *state,
472
- bool async)
473
-{
474
- struct rockchip_drm_private *private = dev->dev_private;
475
- struct rockchip_atomic_commit *commit;
476
- size_t line_bw_mbyte;
477
- size_t frame_bw_mbyte;
478
- unsigned int plane_num;
479
- int ret;
480
-
481
- ret = drm_atomic_helper_setup_commit(state, false);
482
- if (ret)
483
- return ret;
484
-
485
- ret = drm_atomic_helper_prepare_planes(dev, state);
486
- if (ret)
487
- return ret;
488
-
489
- ret = rockchip_drm_bandwidth_atomic_check(dev, state,
490
- &line_bw_mbyte,
491
- &frame_bw_mbyte,
492
- &plane_num);
493
- if (ret) {
494
- /*
495
- * TODO:
496
- * Just report bandwidth can't support now.
497
- */
498
- DRM_ERROR("vop bandwidth too large %zd\n", line_bw_mbyte);
499
- }
500
-
501
- ret = drm_atomic_helper_swap_state(state, true);
502
- if (ret < 0) {
503
- DRM_ERROR("swap atomic state for %s failed: %d\n", current->comm, ret);
504
- drm_atomic_helper_cleanup_planes(dev, state);
505
- return ret;
506
- }
507
-
508
- drm_atomic_state_get(state);
509
- commit = kmalloc(sizeof(*commit), GFP_KERNEL);
510
- if (!commit)
511
- return -ENOMEM;
512
-
513
- commit->dev = dev;
514
- commit->state = state;
515
- commit->line_bw_mbyte = line_bw_mbyte;
516
- commit->frame_bw_mbyte = frame_bw_mbyte;
517
- commit->plane_num = plane_num;
518
-
519
- if (async) {
520
- mutex_lock(&private->commit_lock);
521
-
522
- flush_work(&private->commit_work);
523
- WARN_ON(private->commit);
524
- private->commit = commit;
525
- schedule_work(&private->commit_work);
526
-
527
- mutex_unlock(&private->commit_lock);
528
- } else {
529
- rockchip_atomic_commit_complete(commit);
530
- }
531
-
532
- return 0;
533
-}
534
-
535295 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
536
- .fb_create = rockchip_user_fb_create,
296
+ .fb_create = rockchip_fb_create,
537297 .output_poll_changed = rockchip_drm_output_poll_changed,
538298 .atomic_check = drm_atomic_helper_check,
539
- .atomic_commit = rockchip_drm_atomic_commit,
299
+ .atomic_commit = drm_atomic_helper_commit,
540300 };
541301
542302 struct drm_framebuffer *
....@@ -546,7 +306,7 @@
546306 {
547307 struct drm_framebuffer *fb;
548308
549
- fb = rockchip_fb_alloc(dev, mode_cmd, &obj, NULL, 1);
309
+ fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1);
550310 if (IS_ERR(fb))
551311 return ERR_CAST(fb);
552312
....@@ -559,12 +319,12 @@
559319 dev->mode_config.min_height = 0;
560320
561321 /*
562
- * set max width and height as default value(4096x4096).
322
+ * set max width and height as default value(16384x16384).
563323 * this value would be used to check framebuffer size limitation
564324 * at drm_mode_addfb().
565325 */
566
- dev->mode_config.max_width = 8192;
567
- dev->mode_config.max_height = 8192;
326
+ dev->mode_config.max_width = 16384;
327
+ dev->mode_config.max_height = 16384;
568328 dev->mode_config.async_page_flip = true;
569329
570330 dev->mode_config.funcs = &rockchip_drm_mode_config_funcs;