]> Git Repo - linux.git/blob - drivers/gpu/drm/rcar-du/rcar_du_drv.c
Merge tag 'at91-soc-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux...
[linux.git] / drivers / gpu / drm / rcar-du / rcar_du_drv.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * rcar_du_drv.c  --  R-Car Display Unit DRM driver
4  *
5  * Copyright (C) 2013-2015 Renesas Electronics Corporation
6  *
7  * Contact: Laurent Pinchart ([email protected])
8  */
9
10 #include <linux/clk.h>
11 #include <linux/io.h>
12 #include <linux/mm.h>
13 #include <linux/module.h>
14 #include <linux/of_device.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm.h>
17 #include <linux/slab.h>
18 #include <linux/wait.h>
19
20 #include <drm/drm_atomic_helper.h>
21 #include <drm/drm_drv.h>
22 #include <drm/drm_fb_cma_helper.h>
23 #include <drm/drm_fb_helper.h>
24 #include <drm/drm_gem_cma_helper.h>
25 #include <drm/drm_managed.h>
26 #include <drm/drm_probe_helper.h>
27
28 #include "rcar_du_drv.h"
29 #include "rcar_du_kms.h"
30 #include "rcar_du_of.h"
31 #include "rcar_du_regs.h"
32
33 /* -----------------------------------------------------------------------------
34  * Device Information
35  */
36
37 static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
38         .gen = 2,
39         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
40                   | RCAR_DU_FEATURE_INTERLACED
41                   | RCAR_DU_FEATURE_TVM_SYNC,
42         .channels_mask = BIT(1) | BIT(0),
43         .routes = {
44                 /*
45                  * R8A774[34] has one RGB output and one LVDS output
46                  */
47                 [RCAR_DU_OUTPUT_DPAD0] = {
48                         .possible_crtcs = BIT(1) | BIT(0),
49                         .port = 0,
50                 },
51                 [RCAR_DU_OUTPUT_LVDS0] = {
52                         .possible_crtcs = BIT(0),
53                         .port = 1,
54                 },
55         },
56         .num_lvds = 1,
57 };
58
59 static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
60         .gen = 2,
61         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
62                   | RCAR_DU_FEATURE_INTERLACED
63                   | RCAR_DU_FEATURE_TVM_SYNC,
64         .channels_mask = BIT(1) | BIT(0),
65         .routes = {
66                 /*
67                  * R8A7745 has two RGB outputs
68                  */
69                 [RCAR_DU_OUTPUT_DPAD0] = {
70                         .possible_crtcs = BIT(0),
71                         .port = 0,
72                 },
73                 [RCAR_DU_OUTPUT_DPAD1] = {
74                         .possible_crtcs = BIT(1),
75                         .port = 1,
76                 },
77         },
78 };
79
80 static const struct rcar_du_device_info rzg1_du_r8a77470_info = {
81         .gen = 2,
82         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
83                   | RCAR_DU_FEATURE_INTERLACED
84                   | RCAR_DU_FEATURE_TVM_SYNC,
85         .channels_mask = BIT(1) | BIT(0),
86         .routes = {
87                 /*
88                  * R8A77470 has two RGB outputs, one LVDS output, and
89                  * one (currently unsupported) analog video output
90                  */
91                 [RCAR_DU_OUTPUT_DPAD0] = {
92                         .possible_crtcs = BIT(0),
93                         .port = 0,
94                 },
95                 [RCAR_DU_OUTPUT_DPAD1] = {
96                         .possible_crtcs = BIT(1),
97                         .port = 1,
98                 },
99                 [RCAR_DU_OUTPUT_LVDS0] = {
100                         .possible_crtcs = BIT(0) | BIT(1),
101                         .port = 2,
102                 },
103         },
104 };
105
106 static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
107         .gen = 3,
108         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
109                   | RCAR_DU_FEATURE_VSP1_SOURCE
110                   | RCAR_DU_FEATURE_INTERLACED
111                   | RCAR_DU_FEATURE_TVM_SYNC,
112         .channels_mask = BIT(2) | BIT(1) | BIT(0),
113         .routes = {
114                 /*
115                  * R8A774A1 has one RGB output, one LVDS output and one HDMI
116                  * output.
117                  */
118                 [RCAR_DU_OUTPUT_DPAD0] = {
119                         .possible_crtcs = BIT(2),
120                         .port = 0,
121                 },
122                 [RCAR_DU_OUTPUT_HDMI0] = {
123                         .possible_crtcs = BIT(1),
124                         .port = 1,
125                 },
126                 [RCAR_DU_OUTPUT_LVDS0] = {
127                         .possible_crtcs = BIT(0),
128                         .port = 2,
129                 },
130         },
131         .num_lvds = 1,
132         .dpll_mask =  BIT(1),
133 };
134
135 static const struct rcar_du_device_info rcar_du_r8a774b1_info = {
136         .gen = 3,
137         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
138                   | RCAR_DU_FEATURE_VSP1_SOURCE
139                   | RCAR_DU_FEATURE_INTERLACED
140                   | RCAR_DU_FEATURE_TVM_SYNC,
141         .channels_mask = BIT(3) | BIT(1) | BIT(0),
142         .routes = {
143                 /*
144                  * R8A774B1 has one RGB output, one LVDS output and one HDMI
145                  * output.
146                  */
147                 [RCAR_DU_OUTPUT_DPAD0] = {
148                         .possible_crtcs = BIT(2),
149                         .port = 0,
150                 },
151                 [RCAR_DU_OUTPUT_HDMI0] = {
152                         .possible_crtcs = BIT(1),
153                         .port = 1,
154                 },
155                 [RCAR_DU_OUTPUT_LVDS0] = {
156                         .possible_crtcs = BIT(0),
157                         .port = 2,
158                 },
159         },
160         .num_lvds = 1,
161         .dpll_mask =  BIT(1),
162 };
163
164 static const struct rcar_du_device_info rcar_du_r8a774c0_info = {
165         .gen = 3,
166         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
167                   | RCAR_DU_FEATURE_VSP1_SOURCE,
168         .channels_mask = BIT(1) | BIT(0),
169         .routes = {
170                 /*
171                  * R8A774C0 has one RGB output and two LVDS outputs
172                  */
173                 [RCAR_DU_OUTPUT_DPAD0] = {
174                         .possible_crtcs = BIT(0) | BIT(1),
175                         .port = 0,
176                 },
177                 [RCAR_DU_OUTPUT_LVDS0] = {
178                         .possible_crtcs = BIT(0),
179                         .port = 1,
180                 },
181                 [RCAR_DU_OUTPUT_LVDS1] = {
182                         .possible_crtcs = BIT(1),
183                         .port = 2,
184                 },
185         },
186         .num_lvds = 2,
187         .lvds_clk_mask =  BIT(1) | BIT(0),
188 };
189
190 static const struct rcar_du_device_info rcar_du_r8a774e1_info = {
191         .gen = 3,
192         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
193                   | RCAR_DU_FEATURE_VSP1_SOURCE
194                   | RCAR_DU_FEATURE_INTERLACED
195                   | RCAR_DU_FEATURE_TVM_SYNC,
196         .channels_mask = BIT(3) | BIT(1) | BIT(0),
197         .routes = {
198                 /*
199                  * R8A774E1 has one RGB output, one LVDS output and one HDMI
200                  * output.
201                  */
202                 [RCAR_DU_OUTPUT_DPAD0] = {
203                         .possible_crtcs = BIT(2),
204                         .port = 0,
205                 },
206                 [RCAR_DU_OUTPUT_HDMI0] = {
207                         .possible_crtcs = BIT(1),
208                         .port = 1,
209                 },
210                 [RCAR_DU_OUTPUT_LVDS0] = {
211                         .possible_crtcs = BIT(0),
212                         .port = 2,
213                 },
214         },
215         .num_lvds = 1,
216         .dpll_mask =  BIT(1),
217 };
218
219 static const struct rcar_du_device_info rcar_du_r8a7779_info = {
220         .gen = 1,
221         .features = RCAR_DU_FEATURE_INTERLACED
222                   | RCAR_DU_FEATURE_TVM_SYNC,
223         .channels_mask = BIT(1) | BIT(0),
224         .routes = {
225                 /*
226                  * R8A7779 has two RGB outputs and one (currently unsupported)
227                  * TCON output.
228                  */
229                 [RCAR_DU_OUTPUT_DPAD0] = {
230                         .possible_crtcs = BIT(0),
231                         .port = 0,
232                 },
233                 [RCAR_DU_OUTPUT_DPAD1] = {
234                         .possible_crtcs = BIT(1) | BIT(0),
235                         .port = 1,
236                 },
237         },
238 };
239
240 static const struct rcar_du_device_info rcar_du_r8a7790_info = {
241         .gen = 2,
242         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
243                   | RCAR_DU_FEATURE_INTERLACED
244                   | RCAR_DU_FEATURE_TVM_SYNC,
245         .quirks = RCAR_DU_QUIRK_ALIGN_128B,
246         .channels_mask = BIT(2) | BIT(1) | BIT(0),
247         .routes = {
248                 /*
249                  * R8A7742 and R8A7790 each have one RGB output and two LVDS
250                  * outputs. Additionally R8A7790 supports one TCON output
251                  * (currently unsupported by the driver).
252                  */
253                 [RCAR_DU_OUTPUT_DPAD0] = {
254                         .possible_crtcs = BIT(2) | BIT(1) | BIT(0),
255                         .port = 0,
256                 },
257                 [RCAR_DU_OUTPUT_LVDS0] = {
258                         .possible_crtcs = BIT(0),
259                         .port = 1,
260                 },
261                 [RCAR_DU_OUTPUT_LVDS1] = {
262                         .possible_crtcs = BIT(2) | BIT(1),
263                         .port = 2,
264                 },
265         },
266         .num_lvds = 2,
267 };
268
269 /* M2-W (r8a7791) and M2-N (r8a7793) are identical */
270 static const struct rcar_du_device_info rcar_du_r8a7791_info = {
271         .gen = 2,
272         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
273                   | RCAR_DU_FEATURE_INTERLACED
274                   | RCAR_DU_FEATURE_TVM_SYNC,
275         .channels_mask = BIT(1) | BIT(0),
276         .routes = {
277                 /*
278                  * R8A779[13] has one RGB output, one LVDS output and one
279                  * (currently unsupported) TCON output.
280                  */
281                 [RCAR_DU_OUTPUT_DPAD0] = {
282                         .possible_crtcs = BIT(1) | BIT(0),
283                         .port = 0,
284                 },
285                 [RCAR_DU_OUTPUT_LVDS0] = {
286                         .possible_crtcs = BIT(0),
287                         .port = 1,
288                 },
289         },
290         .num_lvds = 1,
291 };
292
293 static const struct rcar_du_device_info rcar_du_r8a7792_info = {
294         .gen = 2,
295         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
296                   | RCAR_DU_FEATURE_INTERLACED
297                   | RCAR_DU_FEATURE_TVM_SYNC,
298         .channels_mask = BIT(1) | BIT(0),
299         .routes = {
300                 /* R8A7792 has two RGB outputs. */
301                 [RCAR_DU_OUTPUT_DPAD0] = {
302                         .possible_crtcs = BIT(0),
303                         .port = 0,
304                 },
305                 [RCAR_DU_OUTPUT_DPAD1] = {
306                         .possible_crtcs = BIT(1),
307                         .port = 1,
308                 },
309         },
310 };
311
312 static const struct rcar_du_device_info rcar_du_r8a7794_info = {
313         .gen = 2,
314         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
315                   | RCAR_DU_FEATURE_INTERLACED
316                   | RCAR_DU_FEATURE_TVM_SYNC,
317         .channels_mask = BIT(1) | BIT(0),
318         .routes = {
319                 /*
320                  * R8A7794 has two RGB outputs and one (currently unsupported)
321                  * TCON output.
322                  */
323                 [RCAR_DU_OUTPUT_DPAD0] = {
324                         .possible_crtcs = BIT(0),
325                         .port = 0,
326                 },
327                 [RCAR_DU_OUTPUT_DPAD1] = {
328                         .possible_crtcs = BIT(1),
329                         .port = 1,
330                 },
331         },
332 };
333
334 static const struct rcar_du_device_info rcar_du_r8a7795_info = {
335         .gen = 3,
336         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
337                   | RCAR_DU_FEATURE_VSP1_SOURCE
338                   | RCAR_DU_FEATURE_INTERLACED
339                   | RCAR_DU_FEATURE_TVM_SYNC,
340         .channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
341         .routes = {
342                 /*
343                  * R8A7795 has one RGB output, two HDMI outputs and one
344                  * LVDS output.
345                  */
346                 [RCAR_DU_OUTPUT_DPAD0] = {
347                         .possible_crtcs = BIT(3),
348                         .port = 0,
349                 },
350                 [RCAR_DU_OUTPUT_HDMI0] = {
351                         .possible_crtcs = BIT(1),
352                         .port = 1,
353                 },
354                 [RCAR_DU_OUTPUT_HDMI1] = {
355                         .possible_crtcs = BIT(2),
356                         .port = 2,
357                 },
358                 [RCAR_DU_OUTPUT_LVDS0] = {
359                         .possible_crtcs = BIT(0),
360                         .port = 3,
361                 },
362         },
363         .num_lvds = 1,
364         .dpll_mask =  BIT(2) | BIT(1),
365 };
366
367 static const struct rcar_du_device_info rcar_du_r8a7796_info = {
368         .gen = 3,
369         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
370                   | RCAR_DU_FEATURE_VSP1_SOURCE
371                   | RCAR_DU_FEATURE_INTERLACED
372                   | RCAR_DU_FEATURE_TVM_SYNC,
373         .channels_mask = BIT(2) | BIT(1) | BIT(0),
374         .routes = {
375                 /*
376                  * R8A7796 has one RGB output, one LVDS output and one HDMI
377                  * output.
378                  */
379                 [RCAR_DU_OUTPUT_DPAD0] = {
380                         .possible_crtcs = BIT(2),
381                         .port = 0,
382                 },
383                 [RCAR_DU_OUTPUT_HDMI0] = {
384                         .possible_crtcs = BIT(1),
385                         .port = 1,
386                 },
387                 [RCAR_DU_OUTPUT_LVDS0] = {
388                         .possible_crtcs = BIT(0),
389                         .port = 2,
390                 },
391         },
392         .num_lvds = 1,
393         .dpll_mask =  BIT(1),
394 };
395
396 static const struct rcar_du_device_info rcar_du_r8a77965_info = {
397         .gen = 3,
398         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
399                   | RCAR_DU_FEATURE_VSP1_SOURCE
400                   | RCAR_DU_FEATURE_INTERLACED
401                   | RCAR_DU_FEATURE_TVM_SYNC,
402         .channels_mask = BIT(3) | BIT(1) | BIT(0),
403         .routes = {
404                 /*
405                  * R8A77965 has one RGB output, one LVDS output and one HDMI
406                  * output.
407                  */
408                 [RCAR_DU_OUTPUT_DPAD0] = {
409                         .possible_crtcs = BIT(2),
410                         .port = 0,
411                 },
412                 [RCAR_DU_OUTPUT_HDMI0] = {
413                         .possible_crtcs = BIT(1),
414                         .port = 1,
415                 },
416                 [RCAR_DU_OUTPUT_LVDS0] = {
417                         .possible_crtcs = BIT(0),
418                         .port = 2,
419                 },
420         },
421         .num_lvds = 1,
422         .dpll_mask =  BIT(1),
423 };
424
425 static const struct rcar_du_device_info rcar_du_r8a77970_info = {
426         .gen = 3,
427         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
428                   | RCAR_DU_FEATURE_VSP1_SOURCE
429                   | RCAR_DU_FEATURE_INTERLACED
430                   | RCAR_DU_FEATURE_TVM_SYNC,
431         .channels_mask = BIT(0),
432         .routes = {
433                 /*
434                  * R8A77970 and R8A77980 have one RGB output and one LVDS
435                  * output.
436                  */
437                 [RCAR_DU_OUTPUT_DPAD0] = {
438                         .possible_crtcs = BIT(0),
439                         .port = 0,
440                 },
441                 [RCAR_DU_OUTPUT_LVDS0] = {
442                         .possible_crtcs = BIT(0),
443                         .port = 1,
444                 },
445         },
446         .num_lvds = 1,
447 };
448
449 static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
450         .gen = 3,
451         .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
452                   | RCAR_DU_FEATURE_VSP1_SOURCE,
453         .channels_mask = BIT(1) | BIT(0),
454         .routes = {
455                 /*
456                  * R8A77990 and R8A77995 have one RGB output and two LVDS
457                  * outputs.
458                  */
459                 [RCAR_DU_OUTPUT_DPAD0] = {
460                         .possible_crtcs = BIT(0) | BIT(1),
461                         .port = 0,
462                 },
463                 [RCAR_DU_OUTPUT_LVDS0] = {
464                         .possible_crtcs = BIT(0),
465                         .port = 1,
466                 },
467                 [RCAR_DU_OUTPUT_LVDS1] = {
468                         .possible_crtcs = BIT(1),
469                         .port = 2,
470                 },
471         },
472         .num_lvds = 2,
473         .lvds_clk_mask =  BIT(1) | BIT(0),
474 };
475
476 static const struct of_device_id rcar_du_of_table[] = {
477         { .compatible = "renesas,du-r8a7742", .data = &rcar_du_r8a7790_info },
478         { .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
479         { .compatible = "renesas,du-r8a7744", .data = &rzg1_du_r8a7743_info },
480         { .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
481         { .compatible = "renesas,du-r8a77470", .data = &rzg1_du_r8a77470_info },
482         { .compatible = "renesas,du-r8a774a1", .data = &rcar_du_r8a774a1_info },
483         { .compatible = "renesas,du-r8a774b1", .data = &rcar_du_r8a774b1_info },
484         { .compatible = "renesas,du-r8a774c0", .data = &rcar_du_r8a774c0_info },
485         { .compatible = "renesas,du-r8a774e1", .data = &rcar_du_r8a774e1_info },
486         { .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
487         { .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
488         { .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info },
489         { .compatible = "renesas,du-r8a7792", .data = &rcar_du_r8a7792_info },
490         { .compatible = "renesas,du-r8a7793", .data = &rcar_du_r8a7791_info },
491         { .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info },
492         { .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info },
493         { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
494         { .compatible = "renesas,du-r8a77961", .data = &rcar_du_r8a7796_info },
495         { .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
496         { .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info },
497         { .compatible = "renesas,du-r8a77980", .data = &rcar_du_r8a77970_info },
498         { .compatible = "renesas,du-r8a77990", .data = &rcar_du_r8a7799x_info },
499         { .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a7799x_info },
500         { }
501 };
502
503 MODULE_DEVICE_TABLE(of, rcar_du_of_table);
504
505 /* -----------------------------------------------------------------------------
506  * DRM operations
507  */
508
509 DEFINE_DRM_GEM_CMA_FOPS(rcar_du_fops);
510
511 static const struct drm_driver rcar_du_driver = {
512         .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
513         DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(rcar_du_dumb_create),
514         .fops                   = &rcar_du_fops,
515         .name                   = "rcar-du",
516         .desc                   = "Renesas R-Car Display Unit",
517         .date                   = "20130110",
518         .major                  = 1,
519         .minor                  = 0,
520 };
521
522 /* -----------------------------------------------------------------------------
523  * Power management
524  */
525
526 #ifdef CONFIG_PM_SLEEP
527 static int rcar_du_pm_suspend(struct device *dev)
528 {
529         struct rcar_du_device *rcdu = dev_get_drvdata(dev);
530
531         return drm_mode_config_helper_suspend(&rcdu->ddev);
532 }
533
534 static int rcar_du_pm_resume(struct device *dev)
535 {
536         struct rcar_du_device *rcdu = dev_get_drvdata(dev);
537
538         return drm_mode_config_helper_resume(&rcdu->ddev);
539 }
540 #endif
541
542 static const struct dev_pm_ops rcar_du_pm_ops = {
543         SET_SYSTEM_SLEEP_PM_OPS(rcar_du_pm_suspend, rcar_du_pm_resume)
544 };
545
546 /* -----------------------------------------------------------------------------
547  * Platform driver
548  */
549
550 static int rcar_du_remove(struct platform_device *pdev)
551 {
552         struct rcar_du_device *rcdu = platform_get_drvdata(pdev);
553         struct drm_device *ddev = &rcdu->ddev;
554
555         drm_dev_unregister(ddev);
556
557         drm_kms_helper_poll_fini(ddev);
558
559         drm_dev_put(ddev);
560
561         return 0;
562 }
563
564 static int rcar_du_probe(struct platform_device *pdev)
565 {
566         struct rcar_du_device *rcdu;
567         struct resource *mem;
568         int ret;
569
570         /* Allocate and initialize the R-Car device structure. */
571         rcdu = devm_drm_dev_alloc(&pdev->dev, &rcar_du_driver,
572                                   struct rcar_du_device, ddev);
573         if (IS_ERR(rcdu))
574                 return PTR_ERR(rcdu);
575
576         rcdu->dev = &pdev->dev;
577         rcdu->info = of_device_get_match_data(rcdu->dev);
578
579         platform_set_drvdata(pdev, rcdu);
580
581         /* I/O resources */
582         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
583         rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem);
584         if (IS_ERR(rcdu->mmio))
585                 return PTR_ERR(rcdu->mmio);
586
587         /* DRM/KMS objects */
588         ret = rcar_du_modeset_init(rcdu);
589         if (ret < 0) {
590                 if (ret != -EPROBE_DEFER)
591                         dev_err(&pdev->dev,
592                                 "failed to initialize DRM/KMS (%d)\n", ret);
593                 goto error;
594         }
595
596         rcdu->ddev.irq_enabled = 1;
597
598         /*
599          * Register the DRM device with the core and the connectors with
600          * sysfs.
601          */
602         ret = drm_dev_register(&rcdu->ddev, 0);
603         if (ret)
604                 goto error;
605
606         DRM_INFO("Device %s probed\n", dev_name(&pdev->dev));
607
608         drm_fbdev_generic_setup(&rcdu->ddev, 32);
609
610         return 0;
611
612 error:
613         drm_kms_helper_poll_fini(&rcdu->ddev);
614         return ret;
615 }
616
617 static struct platform_driver rcar_du_platform_driver = {
618         .probe          = rcar_du_probe,
619         .remove         = rcar_du_remove,
620         .driver         = {
621                 .name   = "rcar-du",
622                 .pm     = &rcar_du_pm_ops,
623                 .of_match_table = rcar_du_of_table,
624         },
625 };
626
627 static int __init rcar_du_init(void)
628 {
629         rcar_du_of_init(rcar_du_of_table);
630
631         return platform_driver_register(&rcar_du_platform_driver);
632 }
633 module_init(rcar_du_init);
634
635 static void __exit rcar_du_exit(void)
636 {
637         platform_driver_unregister(&rcar_du_platform_driver);
638 }
639 module_exit(rcar_du_exit);
640
641 MODULE_AUTHOR("Laurent Pinchart <[email protected]>");
642 MODULE_DESCRIPTION("Renesas R-Car Display Unit DRM Driver");
643 MODULE_LICENSE("GPL");
This page took 0.069749 seconds and 4 git commands to generate.