hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/gpu/drm/rcar-du/rcar_du_drv.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * rcar_du_drv.c -- R-Car Display Unit DRM driver
34 *
45 * Copyright (C) 2013-2015 Renesas Electronics Corporation
56 *
67 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
128 */
139
1410 #include <linux/clk.h>
....@@ -21,11 +17,12 @@
2117 #include <linux/slab.h>
2218 #include <linux/wait.h>
2319
24
-#include <drm/drmP.h>
2520 #include <drm/drm_atomic_helper.h>
26
-#include <drm/drm_crtc_helper.h>
2721 #include <drm/drm_fb_cma_helper.h>
22
+#include <drm/drm_fb_helper.h>
23
+#include <drm/drm_drv.h>
2824 #include <drm/drm_gem_cma_helper.h>
25
+#include <drm/drm_probe_helper.h>
2926
3027 #include "rcar_du_drv.h"
3128 #include "rcar_du_kms.h"
....@@ -39,11 +36,12 @@
3936 static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
4037 .gen = 2,
4138 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
42
- | RCAR_DU_FEATURE_EXT_CTRL_REGS,
39
+ | RCAR_DU_FEATURE_INTERLACED
40
+ | RCAR_DU_FEATURE_TVM_SYNC,
4341 .channels_mask = BIT(1) | BIT(0),
4442 .routes = {
4543 /*
46
- * R8A7743 has one RGB output and one LVDS output
44
+ * R8A774[34] has one RGB output and one LVDS output
4745 */
4846 [RCAR_DU_OUTPUT_DPAD0] = {
4947 .possible_crtcs = BIT(1) | BIT(0),
....@@ -60,7 +58,8 @@
6058 static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
6159 .gen = 2,
6260 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
63
- | RCAR_DU_FEATURE_EXT_CTRL_REGS,
61
+ | RCAR_DU_FEATURE_INTERLACED
62
+ | RCAR_DU_FEATURE_TVM_SYNC,
6463 .channels_mask = BIT(1) | BIT(0),
6564 .routes = {
6665 /*
....@@ -77,9 +76,149 @@
7776 },
7877 };
7978
80
-static const struct rcar_du_device_info rcar_du_r8a7779_info = {
79
+static const struct rcar_du_device_info rzg1_du_r8a77470_info = {
8180 .gen = 2,
82
- .features = 0,
81
+ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
82
+ | RCAR_DU_FEATURE_INTERLACED
83
+ | RCAR_DU_FEATURE_TVM_SYNC,
84
+ .channels_mask = BIT(1) | BIT(0),
85
+ .routes = {
86
+ /*
87
+ * R8A77470 has two RGB outputs, one LVDS output, and
88
+ * one (currently unsupported) analog video output
89
+ */
90
+ [RCAR_DU_OUTPUT_DPAD0] = {
91
+ .possible_crtcs = BIT(0),
92
+ .port = 0,
93
+ },
94
+ [RCAR_DU_OUTPUT_DPAD1] = {
95
+ .possible_crtcs = BIT(1),
96
+ .port = 1,
97
+ },
98
+ [RCAR_DU_OUTPUT_LVDS0] = {
99
+ .possible_crtcs = BIT(0) | BIT(1),
100
+ .port = 2,
101
+ },
102
+ },
103
+};
104
+
105
+static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
106
+ .gen = 3,
107
+ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
108
+ | RCAR_DU_FEATURE_VSP1_SOURCE
109
+ | RCAR_DU_FEATURE_INTERLACED
110
+ | RCAR_DU_FEATURE_TVM_SYNC,
111
+ .channels_mask = BIT(2) | BIT(1) | BIT(0),
112
+ .routes = {
113
+ /*
114
+ * R8A774A1 has one RGB output, one LVDS output and one HDMI
115
+ * output.
116
+ */
117
+ [RCAR_DU_OUTPUT_DPAD0] = {
118
+ .possible_crtcs = BIT(2),
119
+ .port = 0,
120
+ },
121
+ [RCAR_DU_OUTPUT_HDMI0] = {
122
+ .possible_crtcs = BIT(1),
123
+ .port = 1,
124
+ },
125
+ [RCAR_DU_OUTPUT_LVDS0] = {
126
+ .possible_crtcs = BIT(0),
127
+ .port = 2,
128
+ },
129
+ },
130
+ .num_lvds = 1,
131
+ .dpll_mask = BIT(1),
132
+};
133
+
134
+static const struct rcar_du_device_info rcar_du_r8a774b1_info = {
135
+ .gen = 3,
136
+ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
137
+ | RCAR_DU_FEATURE_VSP1_SOURCE
138
+ | RCAR_DU_FEATURE_INTERLACED
139
+ | RCAR_DU_FEATURE_TVM_SYNC,
140
+ .channels_mask = BIT(3) | BIT(1) | BIT(0),
141
+ .routes = {
142
+ /*
143
+ * R8A774B1 has one RGB output, one LVDS output and one HDMI
144
+ * output.
145
+ */
146
+ [RCAR_DU_OUTPUT_DPAD0] = {
147
+ .possible_crtcs = BIT(2),
148
+ .port = 0,
149
+ },
150
+ [RCAR_DU_OUTPUT_HDMI0] = {
151
+ .possible_crtcs = BIT(1),
152
+ .port = 1,
153
+ },
154
+ [RCAR_DU_OUTPUT_LVDS0] = {
155
+ .possible_crtcs = BIT(0),
156
+ .port = 2,
157
+ },
158
+ },
159
+ .num_lvds = 1,
160
+ .dpll_mask = BIT(1),
161
+};
162
+
163
+static const struct rcar_du_device_info rcar_du_r8a774c0_info = {
164
+ .gen = 3,
165
+ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
166
+ | RCAR_DU_FEATURE_VSP1_SOURCE,
167
+ .channels_mask = BIT(1) | BIT(0),
168
+ .routes = {
169
+ /*
170
+ * R8A774C0 has one RGB output and two LVDS outputs
171
+ */
172
+ [RCAR_DU_OUTPUT_DPAD0] = {
173
+ .possible_crtcs = BIT(0) | BIT(1),
174
+ .port = 0,
175
+ },
176
+ [RCAR_DU_OUTPUT_LVDS0] = {
177
+ .possible_crtcs = BIT(0),
178
+ .port = 1,
179
+ },
180
+ [RCAR_DU_OUTPUT_LVDS1] = {
181
+ .possible_crtcs = BIT(1),
182
+ .port = 2,
183
+ },
184
+ },
185
+ .num_lvds = 2,
186
+ .lvds_clk_mask = BIT(1) | BIT(0),
187
+};
188
+
189
+static const struct rcar_du_device_info rcar_du_r8a774e1_info = {
190
+ .gen = 3,
191
+ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
192
+ | RCAR_DU_FEATURE_VSP1_SOURCE
193
+ | RCAR_DU_FEATURE_INTERLACED
194
+ | RCAR_DU_FEATURE_TVM_SYNC,
195
+ .channels_mask = BIT(3) | BIT(1) | BIT(0),
196
+ .routes = {
197
+ /*
198
+ * R8A774E1 has one RGB output, one LVDS output and one HDMI
199
+ * output.
200
+ */
201
+ [RCAR_DU_OUTPUT_DPAD0] = {
202
+ .possible_crtcs = BIT(2),
203
+ .port = 0,
204
+ },
205
+ [RCAR_DU_OUTPUT_HDMI0] = {
206
+ .possible_crtcs = BIT(1),
207
+ .port = 1,
208
+ },
209
+ [RCAR_DU_OUTPUT_LVDS0] = {
210
+ .possible_crtcs = BIT(0),
211
+ .port = 2,
212
+ },
213
+ },
214
+ .num_lvds = 1,
215
+ .dpll_mask = BIT(1),
216
+};
217
+
218
+static const struct rcar_du_device_info rcar_du_r8a7779_info = {
219
+ .gen = 1,
220
+ .features = RCAR_DU_FEATURE_INTERLACED
221
+ | RCAR_DU_FEATURE_TVM_SYNC,
83222 .channels_mask = BIT(1) | BIT(0),
84223 .routes = {
85224 /*
....@@ -100,13 +239,15 @@
100239 static const struct rcar_du_device_info rcar_du_r8a7790_info = {
101240 .gen = 2,
102241 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
103
- | RCAR_DU_FEATURE_EXT_CTRL_REGS,
242
+ | RCAR_DU_FEATURE_INTERLACED
243
+ | RCAR_DU_FEATURE_TVM_SYNC,
104244 .quirks = RCAR_DU_QUIRK_ALIGN_128B,
105245 .channels_mask = BIT(2) | BIT(1) | BIT(0),
106246 .routes = {
107247 /*
108
- * R8A7790 has one RGB output, two LVDS outputs and one
109
- * (currently unsupported) TCON output.
248
+ * R8A7742 and R8A7790 each have one RGB output and two LVDS
249
+ * outputs. Additionally R8A7790 supports one TCON output
250
+ * (currently unsupported by the driver).
110251 */
111252 [RCAR_DU_OUTPUT_DPAD0] = {
112253 .possible_crtcs = BIT(2) | BIT(1) | BIT(0),
....@@ -128,7 +269,8 @@
128269 static const struct rcar_du_device_info rcar_du_r8a7791_info = {
129270 .gen = 2,
130271 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
131
- | RCAR_DU_FEATURE_EXT_CTRL_REGS,
272
+ | RCAR_DU_FEATURE_INTERLACED
273
+ | RCAR_DU_FEATURE_TVM_SYNC,
132274 .channels_mask = BIT(1) | BIT(0),
133275 .routes = {
134276 /*
....@@ -150,7 +292,8 @@
150292 static const struct rcar_du_device_info rcar_du_r8a7792_info = {
151293 .gen = 2,
152294 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
153
- | RCAR_DU_FEATURE_EXT_CTRL_REGS,
295
+ | RCAR_DU_FEATURE_INTERLACED
296
+ | RCAR_DU_FEATURE_TVM_SYNC,
154297 .channels_mask = BIT(1) | BIT(0),
155298 .routes = {
156299 /* R8A7792 has two RGB outputs. */
....@@ -168,7 +311,8 @@
168311 static const struct rcar_du_device_info rcar_du_r8a7794_info = {
169312 .gen = 2,
170313 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
171
- | RCAR_DU_FEATURE_EXT_CTRL_REGS,
314
+ | RCAR_DU_FEATURE_INTERLACED
315
+ | RCAR_DU_FEATURE_TVM_SYNC,
172316 .channels_mask = BIT(1) | BIT(0),
173317 .routes = {
174318 /*
....@@ -189,8 +333,9 @@
189333 static const struct rcar_du_device_info rcar_du_r8a7795_info = {
190334 .gen = 3,
191335 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
192
- | RCAR_DU_FEATURE_EXT_CTRL_REGS
193
- | RCAR_DU_FEATURE_VSP1_SOURCE,
336
+ | RCAR_DU_FEATURE_VSP1_SOURCE
337
+ | RCAR_DU_FEATURE_INTERLACED
338
+ | RCAR_DU_FEATURE_TVM_SYNC,
194339 .channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
195340 .routes = {
196341 /*
....@@ -215,14 +360,15 @@
215360 },
216361 },
217362 .num_lvds = 1,
218
- .dpll_ch = BIT(2) | BIT(1),
363
+ .dpll_mask = BIT(2) | BIT(1),
219364 };
220365
221366 static const struct rcar_du_device_info rcar_du_r8a7796_info = {
222367 .gen = 3,
223368 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
224
- | RCAR_DU_FEATURE_EXT_CTRL_REGS
225
- | RCAR_DU_FEATURE_VSP1_SOURCE,
369
+ | RCAR_DU_FEATURE_VSP1_SOURCE
370
+ | RCAR_DU_FEATURE_INTERLACED
371
+ | RCAR_DU_FEATURE_TVM_SYNC,
226372 .channels_mask = BIT(2) | BIT(1) | BIT(0),
227373 .routes = {
228374 /*
....@@ -243,14 +389,15 @@
243389 },
244390 },
245391 .num_lvds = 1,
246
- .dpll_ch = BIT(1),
392
+ .dpll_mask = BIT(1),
247393 };
248394
249395 static const struct rcar_du_device_info rcar_du_r8a77965_info = {
250396 .gen = 3,
251397 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
252
- | RCAR_DU_FEATURE_EXT_CTRL_REGS
253
- | RCAR_DU_FEATURE_VSP1_SOURCE,
398
+ | RCAR_DU_FEATURE_VSP1_SOURCE
399
+ | RCAR_DU_FEATURE_INTERLACED
400
+ | RCAR_DU_FEATURE_TVM_SYNC,
254401 .channels_mask = BIT(3) | BIT(1) | BIT(0),
255402 .routes = {
256403 /*
....@@ -271,17 +418,21 @@
271418 },
272419 },
273420 .num_lvds = 1,
274
- .dpll_ch = BIT(1),
421
+ .dpll_mask = BIT(1),
275422 };
276423
277424 static const struct rcar_du_device_info rcar_du_r8a77970_info = {
278425 .gen = 3,
279426 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
280
- | RCAR_DU_FEATURE_EXT_CTRL_REGS
281
- | RCAR_DU_FEATURE_VSP1_SOURCE,
427
+ | RCAR_DU_FEATURE_VSP1_SOURCE
428
+ | RCAR_DU_FEATURE_INTERLACED
429
+ | RCAR_DU_FEATURE_TVM_SYNC,
282430 .channels_mask = BIT(0),
283431 .routes = {
284
- /* R8A77970 has one RGB output and one LVDS output. */
432
+ /*
433
+ * R8A77970 and R8A77980 have one RGB output and one LVDS
434
+ * output.
435
+ */
285436 [RCAR_DU_OUTPUT_DPAD0] = {
286437 .possible_crtcs = BIT(0),
287438 .port = 0,
....@@ -294,9 +445,43 @@
294445 .num_lvds = 1,
295446 };
296447
448
+static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
449
+ .gen = 3,
450
+ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
451
+ | RCAR_DU_FEATURE_VSP1_SOURCE,
452
+ .channels_mask = BIT(1) | BIT(0),
453
+ .routes = {
454
+ /*
455
+ * R8A77990 and R8A77995 have one RGB output and two LVDS
456
+ * outputs.
457
+ */
458
+ [RCAR_DU_OUTPUT_DPAD0] = {
459
+ .possible_crtcs = BIT(0) | BIT(1),
460
+ .port = 0,
461
+ },
462
+ [RCAR_DU_OUTPUT_LVDS0] = {
463
+ .possible_crtcs = BIT(0),
464
+ .port = 1,
465
+ },
466
+ [RCAR_DU_OUTPUT_LVDS1] = {
467
+ .possible_crtcs = BIT(1),
468
+ .port = 2,
469
+ },
470
+ },
471
+ .num_lvds = 2,
472
+ .lvds_clk_mask = BIT(1) | BIT(0),
473
+};
474
+
297475 static const struct of_device_id rcar_du_of_table[] = {
476
+ { .compatible = "renesas,du-r8a7742", .data = &rcar_du_r8a7790_info },
298477 { .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
478
+ { .compatible = "renesas,du-r8a7744", .data = &rzg1_du_r8a7743_info },
299479 { .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
480
+ { .compatible = "renesas,du-r8a77470", .data = &rzg1_du_r8a77470_info },
481
+ { .compatible = "renesas,du-r8a774a1", .data = &rcar_du_r8a774a1_info },
482
+ { .compatible = "renesas,du-r8a774b1", .data = &rcar_du_r8a774b1_info },
483
+ { .compatible = "renesas,du-r8a774c0", .data = &rcar_du_r8a774c0_info },
484
+ { .compatible = "renesas,du-r8a774e1", .data = &rcar_du_r8a774e1_info },
300485 { .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
301486 { .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
302487 { .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info },
....@@ -305,8 +490,12 @@
305490 { .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info },
306491 { .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info },
307492 { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
493
+ { .compatible = "renesas,du-r8a77961", .data = &rcar_du_r8a7796_info },
308494 { .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
309495 { .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info },
496
+ { .compatible = "renesas,du-r8a77980", .data = &rcar_du_r8a77970_info },
497
+ { .compatible = "renesas,du-r8a77990", .data = &rcar_du_r8a7799x_info },
498
+ { .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a7799x_info },
310499 { }
311500 };
312501
....@@ -316,31 +505,11 @@
316505 * DRM operations
317506 */
318507
319
-static void rcar_du_lastclose(struct drm_device *dev)
320
-{
321
- struct rcar_du_device *rcdu = dev->dev_private;
322
-
323
- drm_fbdev_cma_restore_mode(rcdu->fbdev);
324
-}
325
-
326508 DEFINE_DRM_GEM_CMA_FOPS(rcar_du_fops);
327509
328510 static struct drm_driver rcar_du_driver = {
329
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME
330
- | DRIVER_ATOMIC,
331
- .lastclose = rcar_du_lastclose,
332
- .gem_free_object_unlocked = drm_gem_cma_free_object,
333
- .gem_vm_ops = &drm_gem_cma_vm_ops,
334
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
335
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
336
- .gem_prime_import = drm_gem_prime_import,
337
- .gem_prime_export = drm_gem_prime_export,
338
- .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
339
- .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
340
- .gem_prime_vmap = drm_gem_cma_prime_vmap,
341
- .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
342
- .gem_prime_mmap = drm_gem_cma_prime_mmap,
343
- .dumb_create = rcar_du_dumb_create,
511
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
512
+ DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(rcar_du_dumb_create),
344513 .fops = &rcar_du_fops,
345514 .name = "rcar-du",
346515 .desc = "Renesas R-Car Display Unit",
....@@ -357,32 +526,15 @@
357526 static int rcar_du_pm_suspend(struct device *dev)
358527 {
359528 struct rcar_du_device *rcdu = dev_get_drvdata(dev);
360
- struct drm_atomic_state *state;
361529
362
- drm_kms_helper_poll_disable(rcdu->ddev);
363
- drm_fbdev_cma_set_suspend_unlocked(rcdu->fbdev, true);
364
-
365
- state = drm_atomic_helper_suspend(rcdu->ddev);
366
- if (IS_ERR(state)) {
367
- drm_fbdev_cma_set_suspend_unlocked(rcdu->fbdev, false);
368
- drm_kms_helper_poll_enable(rcdu->ddev);
369
- return PTR_ERR(state);
370
- }
371
-
372
- rcdu->suspend_state = state;
373
-
374
- return 0;
530
+ return drm_mode_config_helper_suspend(rcdu->ddev);
375531 }
376532
377533 static int rcar_du_pm_resume(struct device *dev)
378534 {
379535 struct rcar_du_device *rcdu = dev_get_drvdata(dev);
380536
381
- drm_atomic_helper_resume(rcdu->ddev, rcdu->suspend_state);
382
- drm_fbdev_cma_set_suspend_unlocked(rcdu->fbdev, false);
383
- drm_kms_helper_poll_enable(rcdu->ddev);
384
-
385
- return 0;
537
+ return drm_mode_config_helper_resume(rcdu->ddev);
386538 }
387539 #endif
388540
....@@ -401,13 +553,9 @@
401553
402554 drm_dev_unregister(ddev);
403555
404
- if (rcdu->fbdev)
405
- drm_fbdev_cma_fini(rcdu->fbdev);
406
-
407556 drm_kms_helper_poll_fini(ddev);
408
- drm_mode_config_cleanup(ddev);
409557
410
- drm_dev_unref(ddev);
558
+ drm_dev_put(ddev);
411559
412560 return 0;
413561 }
....@@ -463,6 +611,8 @@
463611
464612 DRM_INFO("Device %s probed\n", dev_name(&pdev->dev));
465613
614
+ drm_fbdev_generic_setup(ddev, 32);
615
+
466616 return 0;
467617
468618 error: