2 * Freescale i.MX drm driver
4 * Copyright (C) 2011 Sascha Hauer, Pengutronix
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/component.h>
17 #include <linux/device.h>
18 #include <linux/platform_device.h>
20 #include <drm/drm_fb_helper.h>
21 #include <drm/drm_crtc_helper.h>
23 #include <linux/module.h>
24 #include <drm/drm_gem_cma_helper.h>
25 #include <drm/drm_fb_cma_helper.h>
34 struct list_head list
;
39 struct imx_drm_device
{
40 struct drm_device
*drm
;
42 struct imx_drm_crtc
*crtc
[MAX_CRTC
];
43 struct list_head encoder_list
;
44 struct list_head connector_list
;
47 struct drm_fbdev_cma
*fbhelper
;
51 struct drm_crtc
*crtc
;
52 struct imx_drm_device
*imxdrm
;
54 struct imx_drm_crtc_helper_funcs imx_drm_helper_funcs
;
56 struct crtc_cookie cookie
;
60 struct imx_drm_encoder
{
61 struct drm_encoder
*encoder
;
62 struct list_head list
;
64 struct list_head possible_crtcs
;
67 struct imx_drm_connector
{
68 struct drm_connector
*connector
;
69 struct list_head list
;
73 static int legacyfb_depth
= 16;
74 module_param(legacyfb_depth
, int, 0444);
76 static void imx_drm_device_put(void);
77 static struct imx_drm_device
*__imx_drm_device(void);
79 int imx_drm_crtc_id(struct imx_drm_crtc
*crtc
)
83 EXPORT_SYMBOL_GPL(imx_drm_crtc_id
);
85 static void imx_drm_driver_lastclose(struct drm_device
*drm
)
87 #if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
88 struct imx_drm_device
*imxdrm
= drm
->dev_private
;
91 drm_fbdev_cma_restore_mode(imxdrm
->fbhelper
);
95 static int imx_drm_driver_unload(struct drm_device
*drm
)
97 #if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
98 struct imx_drm_device
*imxdrm
= drm
->dev_private
;
100 if (imxdrm
->fbhelper
)
101 drm_fbdev_cma_fini(imxdrm
->fbhelper
);
104 component_unbind_all(drm
->dev
, drm
);
106 imx_drm_device_put();
108 drm_vblank_cleanup(drm
);
109 drm_kms_helper_poll_fini(drm
);
110 drm_mode_config_cleanup(drm
);
115 struct imx_drm_crtc
*imx_drm_find_crtc(struct drm_crtc
*crtc
)
117 struct imx_drm_device
*imxdrm
= __imx_drm_device();
120 for (i
= 0; i
< MAX_CRTC
; i
++)
121 if (imxdrm
->crtc
[i
] && imxdrm
->crtc
[i
]->crtc
== crtc
)
122 return imxdrm
->crtc
[i
];
127 int imx_drm_panel_format_pins(struct drm_encoder
*encoder
,
128 u32 interface_pix_fmt
, int hsync_pin
, int vsync_pin
)
130 struct imx_drm_crtc_helper_funcs
*helper
;
131 struct imx_drm_crtc
*imx_crtc
;
133 imx_crtc
= imx_drm_find_crtc(encoder
->crtc
);
137 helper
= &imx_crtc
->imx_drm_helper_funcs
;
138 if (helper
->set_interface_pix_fmt
)
139 return helper
->set_interface_pix_fmt(encoder
->crtc
,
140 encoder
->encoder_type
, interface_pix_fmt
,
141 hsync_pin
, vsync_pin
);
144 EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins
);
146 int imx_drm_panel_format(struct drm_encoder
*encoder
, u32 interface_pix_fmt
)
148 return imx_drm_panel_format_pins(encoder
, interface_pix_fmt
, 2, 3);
150 EXPORT_SYMBOL_GPL(imx_drm_panel_format
);
152 int imx_drm_crtc_vblank_get(struct imx_drm_crtc
*imx_drm_crtc
)
154 return drm_vblank_get(imx_drm_crtc
->crtc
->dev
, imx_drm_crtc
->pipe
);
156 EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get
);
158 void imx_drm_crtc_vblank_put(struct imx_drm_crtc
*imx_drm_crtc
)
160 drm_vblank_put(imx_drm_crtc
->crtc
->dev
, imx_drm_crtc
->pipe
);
162 EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put
);
164 void imx_drm_handle_vblank(struct imx_drm_crtc
*imx_drm_crtc
)
166 drm_handle_vblank(imx_drm_crtc
->crtc
->dev
, imx_drm_crtc
->pipe
);
168 EXPORT_SYMBOL_GPL(imx_drm_handle_vblank
);
170 static int imx_drm_enable_vblank(struct drm_device
*drm
, int crtc
)
172 struct imx_drm_device
*imxdrm
= drm
->dev_private
;
173 struct imx_drm_crtc
*imx_drm_crtc
= imxdrm
->crtc
[crtc
];
179 if (!imx_drm_crtc
->imx_drm_helper_funcs
.enable_vblank
)
182 ret
= imx_drm_crtc
->imx_drm_helper_funcs
.enable_vblank(
188 static void imx_drm_disable_vblank(struct drm_device
*drm
, int crtc
)
190 struct imx_drm_device
*imxdrm
= drm
->dev_private
;
191 struct imx_drm_crtc
*imx_drm_crtc
= imxdrm
->crtc
[crtc
];
196 if (!imx_drm_crtc
->imx_drm_helper_funcs
.disable_vblank
)
199 imx_drm_crtc
->imx_drm_helper_funcs
.disable_vblank(imx_drm_crtc
->crtc
);
202 static void imx_drm_driver_preclose(struct drm_device
*drm
,
203 struct drm_file
*file
)
207 if (!file
->is_master
)
210 for (i
= 0; i
< MAX_CRTC
; i
++)
211 imx_drm_disable_vblank(drm
, i
);
214 static const struct file_operations imx_drm_driver_fops
= {
215 .owner
= THIS_MODULE
,
217 .release
= drm_release
,
218 .unlocked_ioctl
= drm_ioctl
,
219 .mmap
= drm_gem_cma_mmap
,
222 .llseek
= noop_llseek
,
225 int imx_drm_connector_mode_valid(struct drm_connector
*connector
,
226 struct drm_display_mode
*mode
)
230 EXPORT_SYMBOL(imx_drm_connector_mode_valid
);
232 static struct imx_drm_device
*imx_drm_device
;
234 static struct imx_drm_device
*__imx_drm_device(void)
236 return imx_drm_device
;
239 static struct drm_device
*imx_drm_device_get(void)
241 struct imx_drm_device
*imxdrm
= __imx_drm_device();
242 struct imx_drm_encoder
*enc
;
243 struct imx_drm_connector
*con
;
244 struct imx_drm_crtc
*crtc
;
246 list_for_each_entry(enc
, &imxdrm
->encoder_list
, list
) {
247 if (!try_module_get(enc
->owner
)) {
248 dev_err(imxdrm
->dev
, "could not get module %s\n",
249 module_name(enc
->owner
));
254 list_for_each_entry(con
, &imxdrm
->connector_list
, list
) {
255 if (!try_module_get(con
->owner
)) {
256 dev_err(imxdrm
->dev
, "could not get module %s\n",
257 module_name(con
->owner
));
262 list_for_each_entry(crtc
, &imxdrm
->crtc_list
, list
) {
263 if (!try_module_get(crtc
->owner
)) {
264 dev_err(imxdrm
->dev
, "could not get module %s\n",
265 module_name(crtc
->owner
));
273 list_for_each_entry_continue_reverse(crtc
, &imxdrm
->crtc_list
, list
)
274 module_put(crtc
->owner
);
276 list_for_each_entry_continue_reverse(con
, &imxdrm
->connector_list
, list
)
277 module_put(con
->owner
);
279 list_for_each_entry_continue_reverse(enc
, &imxdrm
->encoder_list
, list
)
280 module_put(enc
->owner
);
282 mutex_unlock(&imxdrm
->mutex
);
288 static void imx_drm_device_put(void)
290 struct imx_drm_device
*imxdrm
= __imx_drm_device();
291 struct imx_drm_encoder
*enc
;
292 struct imx_drm_connector
*con
;
293 struct imx_drm_crtc
*crtc
;
295 mutex_lock(&imxdrm
->mutex
);
297 list_for_each_entry(crtc
, &imxdrm
->crtc_list
, list
)
298 module_put(crtc
->owner
);
300 list_for_each_entry(con
, &imxdrm
->connector_list
, list
)
301 module_put(con
->owner
);
303 list_for_each_entry(enc
, &imxdrm
->encoder_list
, list
)
304 module_put(enc
->owner
);
306 mutex_unlock(&imxdrm
->mutex
);
309 static int drm_mode_group_reinit(struct drm_device
*dev
)
311 struct drm_mode_group
*group
= &dev
->primary
->mode_group
;
312 uint32_t *id_list
= group
->id_list
;
315 ret
= drm_mode_group_init_legacy_group(dev
, group
);
324 * register an encoder to the drm core
326 static int imx_drm_encoder_register(struct imx_drm_encoder
*imx_drm_encoder
)
328 struct imx_drm_device
*imxdrm
= __imx_drm_device();
330 INIT_LIST_HEAD(&imx_drm_encoder
->possible_crtcs
);
332 drm_encoder_init(imxdrm
->drm
, imx_drm_encoder
->encoder
,
333 imx_drm_encoder
->encoder
->funcs
,
334 imx_drm_encoder
->encoder
->encoder_type
);
336 drm_mode_group_reinit(imxdrm
->drm
);
342 * unregister an encoder from the drm core
344 static void imx_drm_encoder_unregister(struct imx_drm_encoder
347 struct imx_drm_device
*imxdrm
= __imx_drm_device();
349 drm_encoder_cleanup(imx_drm_encoder
->encoder
);
351 drm_mode_group_reinit(imxdrm
->drm
);
355 * register a connector to the drm core
357 static int imx_drm_connector_register(
358 struct imx_drm_connector
*imx_drm_connector
)
360 struct imx_drm_device
*imxdrm
= __imx_drm_device();
362 drm_connector_init(imxdrm
->drm
, imx_drm_connector
->connector
,
363 imx_drm_connector
->connector
->funcs
,
364 imx_drm_connector
->connector
->connector_type
);
365 drm_mode_group_reinit(imxdrm
->drm
);
371 * unregister a connector from the drm core
373 static void imx_drm_connector_unregister(
374 struct imx_drm_connector
*imx_drm_connector
)
376 struct imx_drm_device
*imxdrm
= __imx_drm_device();
378 drm_sysfs_connector_remove(imx_drm_connector
->connector
);
379 drm_connector_cleanup(imx_drm_connector
->connector
);
381 drm_mode_group_reinit(imxdrm
->drm
);
385 * Main DRM initialisation. This binds, initialises and registers
386 * with DRM the subcomponents of the driver.
388 static int imx_drm_driver_load(struct drm_device
*drm
, unsigned long flags
)
390 struct imx_drm_device
*imxdrm
= __imx_drm_device();
391 struct drm_connector
*connector
;
396 drm
->dev_private
= imxdrm
;
399 * enable drm irq mode.
400 * - with irq_enabled = true, we can use the vblank feature.
402 * P.S. note that we wouldn't use drm irq handler but
403 * just specific driver own one instead because
404 * drm framework supports only one irq handler and
405 * drivers can well take care of their interrupts
407 drm
->irq_enabled
= true;
409 drm_mode_config_init(drm
);
410 imx_drm_mode_config_init(drm
);
412 mutex_lock(&imxdrm
->mutex
);
414 drm_kms_helper_poll_init(drm
);
416 /* setup the grouping for the legacy output */
417 ret
= drm_mode_group_init_legacy_group(drm
,
418 &drm
->primary
->mode_group
);
422 ret
= drm_vblank_init(drm
, MAX_CRTC
);
427 * with vblank_disable_allowed = true, vblank interrupt will be disabled
428 * by drm timer once a current process gives up ownership of
429 * vblank event.(after drm_vblank_put function is called)
431 drm
->vblank_disable_allowed
= true;
433 if (!imx_drm_device_get()) {
438 platform_set_drvdata(drm
->platformdev
, drm
);
439 mutex_unlock(&imxdrm
->mutex
);
441 /* Now try and bind all our sub-components */
442 ret
= component_bind_all(drm
->dev
, drm
);
447 * All components are now added, we can publish the connector sysfs
448 * entries to userspace. This will generate hotplug events and so
449 * userspace will expect to be able to access DRM at this point.
451 list_for_each_entry(connector
, &drm
->mode_config
.connector_list
, head
) {
452 ret
= drm_sysfs_connector_add(connector
);
455 "[CONNECTOR:%d:%s] drm_sysfs_connector_add failed: %d\n",
457 drm_get_connector_name(connector
), ret
);
463 * All components are now initialised, so setup the fb helper.
464 * The fb helper takes copies of key hardware information, so the
465 * crtcs/connectors/encoders must not change after this point.
467 #if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
468 if (legacyfb_depth
!= 16 && legacyfb_depth
!= 32) {
469 dev_warn(drm
->dev
, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
472 imxdrm
->fbhelper
= drm_fbdev_cma_init(drm
, legacyfb_depth
,
473 drm
->mode_config
.num_crtc
, MAX_CRTC
);
474 if (IS_ERR(imxdrm
->fbhelper
)) {
475 ret
= PTR_ERR(imxdrm
->fbhelper
);
476 imxdrm
->fbhelper
= NULL
;
483 component_unbind_all(drm
->dev
, drm
);
485 mutex_lock(&imxdrm
->mutex
);
487 drm_vblank_cleanup(drm
);
489 drm_kms_helper_poll_fini(drm
);
490 drm_mode_config_cleanup(drm
);
491 mutex_unlock(&imxdrm
->mutex
);
496 static void imx_drm_update_possible_crtcs(void)
498 struct imx_drm_device
*imxdrm
= __imx_drm_device();
499 struct imx_drm_crtc
*imx_drm_crtc
;
500 struct imx_drm_encoder
*enc
;
501 struct crtc_cookie
*cookie
;
503 list_for_each_entry(enc
, &imxdrm
->encoder_list
, list
) {
504 u32 possible_crtcs
= 0;
506 list_for_each_entry(cookie
, &enc
->possible_crtcs
, list
) {
507 list_for_each_entry(imx_drm_crtc
, &imxdrm
->crtc_list
, list
) {
508 if (imx_drm_crtc
->cookie
.cookie
== cookie
->cookie
&&
509 imx_drm_crtc
->cookie
.id
== cookie
->id
) {
510 possible_crtcs
|= 1 << imx_drm_crtc
->pipe
;
514 enc
->encoder
->possible_crtcs
= possible_crtcs
;
515 enc
->encoder
->possible_clones
= possible_crtcs
;
520 * imx_drm_add_crtc - add a new crtc
522 * The return value if !NULL is a cookie for the caller to pass to
523 * imx_drm_remove_crtc later.
525 int imx_drm_add_crtc(struct drm_crtc
*crtc
,
526 struct imx_drm_crtc
**new_crtc
,
527 const struct imx_drm_crtc_helper_funcs
*imx_drm_helper_funcs
,
528 struct module
*owner
, void *cookie
, int id
)
530 struct imx_drm_device
*imxdrm
= __imx_drm_device();
531 struct imx_drm_crtc
*imx_drm_crtc
;
534 mutex_lock(&imxdrm
->mutex
);
537 * The vblank arrays are dimensioned by MAX_CRTC - we can't
538 * pass IDs greater than this to those functions.
540 if (imxdrm
->pipes
>= MAX_CRTC
) {
545 if (imxdrm
->drm
->open_count
) {
550 imx_drm_crtc
= kzalloc(sizeof(*imx_drm_crtc
), GFP_KERNEL
);
556 imx_drm_crtc
->imx_drm_helper_funcs
= *imx_drm_helper_funcs
;
557 imx_drm_crtc
->pipe
= imxdrm
->pipes
++;
558 imx_drm_crtc
->cookie
.cookie
= cookie
;
559 imx_drm_crtc
->cookie
.id
= id
;
560 imx_drm_crtc
->mux_id
= imx_drm_crtc
->pipe
;
561 imx_drm_crtc
->crtc
= crtc
;
562 imx_drm_crtc
->imxdrm
= imxdrm
;
564 imx_drm_crtc
->owner
= owner
;
566 imxdrm
->crtc
[imx_drm_crtc
->pipe
] = imx_drm_crtc
;
568 *new_crtc
= imx_drm_crtc
;
570 ret
= drm_mode_crtc_set_gamma_size(imx_drm_crtc
->crtc
, 256);
574 drm_crtc_helper_add(crtc
,
575 imx_drm_crtc
->imx_drm_helper_funcs
.crtc_helper_funcs
);
577 drm_crtc_init(imxdrm
->drm
, crtc
,
578 imx_drm_crtc
->imx_drm_helper_funcs
.crtc_funcs
);
580 drm_mode_group_reinit(imxdrm
->drm
);
582 imx_drm_update_possible_crtcs();
584 mutex_unlock(&imxdrm
->mutex
);
589 imxdrm
->crtc
[imx_drm_crtc
->pipe
] = NULL
;
593 mutex_unlock(&imxdrm
->mutex
);
596 EXPORT_SYMBOL_GPL(imx_drm_add_crtc
);
599 * imx_drm_remove_crtc - remove a crtc
601 int imx_drm_remove_crtc(struct imx_drm_crtc
*imx_drm_crtc
)
603 struct imx_drm_device
*imxdrm
= imx_drm_crtc
->imxdrm
;
605 mutex_lock(&imxdrm
->mutex
);
607 drm_crtc_cleanup(imx_drm_crtc
->crtc
);
609 imxdrm
->crtc
[imx_drm_crtc
->pipe
] = NULL
;
611 drm_mode_group_reinit(imxdrm
->drm
);
613 mutex_unlock(&imxdrm
->mutex
);
619 EXPORT_SYMBOL_GPL(imx_drm_remove_crtc
);
622 * imx_drm_add_encoder - add a new encoder
624 int imx_drm_add_encoder(struct drm_encoder
*encoder
,
625 struct imx_drm_encoder
**newenc
, struct module
*owner
)
627 struct imx_drm_device
*imxdrm
= __imx_drm_device();
628 struct imx_drm_encoder
*imx_drm_encoder
;
631 mutex_lock(&imxdrm
->mutex
);
633 if (imxdrm
->drm
->open_count
) {
638 imx_drm_encoder
= kzalloc(sizeof(*imx_drm_encoder
), GFP_KERNEL
);
639 if (!imx_drm_encoder
) {
644 imx_drm_encoder
->encoder
= encoder
;
645 imx_drm_encoder
->owner
= owner
;
647 ret
= imx_drm_encoder_register(imx_drm_encoder
);
653 list_add_tail(&imx_drm_encoder
->list
, &imxdrm
->encoder_list
);
655 *newenc
= imx_drm_encoder
;
657 mutex_unlock(&imxdrm
->mutex
);
662 kfree(imx_drm_encoder
);
665 mutex_unlock(&imxdrm
->mutex
);
669 EXPORT_SYMBOL_GPL(imx_drm_add_encoder
);
671 int imx_drm_encoder_add_possible_crtcs(
672 struct imx_drm_encoder
*imx_drm_encoder
,
673 struct device_node
*np
)
675 struct imx_drm_device
*imxdrm
= __imx_drm_device();
676 struct of_phandle_args args
;
677 struct crtc_cookie
*c
;
681 if (!list_empty(&imx_drm_encoder
->possible_crtcs
))
684 for (i
= 0; !ret
; i
++) {
685 ret
= of_parse_phandle_with_args(np
, "crtcs",
686 "#crtc-cells", i
, &args
);
690 c
= kzalloc(sizeof(*c
), GFP_KERNEL
);
692 of_node_put(args
.np
);
697 c
->id
= args
.args_count
> 0 ? args
.args
[0] : 0;
699 of_node_put(args
.np
);
701 mutex_lock(&imxdrm
->mutex
);
703 list_add_tail(&c
->list
, &imx_drm_encoder
->possible_crtcs
);
705 mutex_unlock(&imxdrm
->mutex
);
708 imx_drm_update_possible_crtcs();
712 EXPORT_SYMBOL_GPL(imx_drm_encoder_add_possible_crtcs
);
714 int imx_drm_encoder_get_mux_id(struct drm_encoder
*encoder
)
716 struct imx_drm_crtc
*imx_crtc
= imx_drm_find_crtc(encoder
->crtc
);
718 return imx_crtc
? imx_crtc
->mux_id
: -EINVAL
;
720 EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id
);
723 * imx_drm_remove_encoder - remove an encoder
725 int imx_drm_remove_encoder(struct imx_drm_encoder
*imx_drm_encoder
)
727 struct imx_drm_device
*imxdrm
= __imx_drm_device();
728 struct crtc_cookie
*c
, *tmp
;
730 mutex_lock(&imxdrm
->mutex
);
732 imx_drm_encoder_unregister(imx_drm_encoder
);
734 list_del(&imx_drm_encoder
->list
);
736 list_for_each_entry_safe(c
, tmp
, &imx_drm_encoder
->possible_crtcs
,
740 mutex_unlock(&imxdrm
->mutex
);
742 kfree(imx_drm_encoder
);
746 EXPORT_SYMBOL_GPL(imx_drm_remove_encoder
);
749 * imx_drm_add_connector - add a connector
751 int imx_drm_add_connector(struct drm_connector
*connector
,
752 struct imx_drm_connector
**new_con
,
753 struct module
*owner
)
755 struct imx_drm_device
*imxdrm
= __imx_drm_device();
756 struct imx_drm_connector
*imx_drm_connector
;
759 mutex_lock(&imxdrm
->mutex
);
761 if (imxdrm
->drm
->open_count
) {
766 imx_drm_connector
= kzalloc(sizeof(*imx_drm_connector
), GFP_KERNEL
);
767 if (!imx_drm_connector
) {
772 imx_drm_connector
->connector
= connector
;
773 imx_drm_connector
->owner
= owner
;
775 ret
= imx_drm_connector_register(imx_drm_connector
);
779 list_add_tail(&imx_drm_connector
->list
, &imxdrm
->connector_list
);
781 *new_con
= imx_drm_connector
;
783 mutex_unlock(&imxdrm
->mutex
);
788 kfree(imx_drm_connector
);
791 mutex_unlock(&imxdrm
->mutex
);
795 EXPORT_SYMBOL_GPL(imx_drm_add_connector
);
798 * imx_drm_remove_connector - remove a connector
800 int imx_drm_remove_connector(struct imx_drm_connector
*imx_drm_connector
)
802 struct imx_drm_device
*imxdrm
= __imx_drm_device();
804 mutex_lock(&imxdrm
->mutex
);
806 imx_drm_connector_unregister(imx_drm_connector
);
808 list_del(&imx_drm_connector
->list
);
810 mutex_unlock(&imxdrm
->mutex
);
812 kfree(imx_drm_connector
);
816 EXPORT_SYMBOL_GPL(imx_drm_remove_connector
);
818 static const struct drm_ioctl_desc imx_drm_ioctls
[] = {
822 static struct drm_driver imx_drm_driver
= {
823 .driver_features
= DRIVER_MODESET
| DRIVER_GEM
| DRIVER_PRIME
,
824 .load
= imx_drm_driver_load
,
825 .unload
= imx_drm_driver_unload
,
826 .lastclose
= imx_drm_driver_lastclose
,
827 .preclose
= imx_drm_driver_preclose
,
828 .gem_free_object
= drm_gem_cma_free_object
,
829 .gem_vm_ops
= &drm_gem_cma_vm_ops
,
830 .dumb_create
= drm_gem_cma_dumb_create
,
831 .dumb_map_offset
= drm_gem_cma_dumb_map_offset
,
832 .dumb_destroy
= drm_gem_dumb_destroy
,
834 .prime_handle_to_fd
= drm_gem_prime_handle_to_fd
,
835 .prime_fd_to_handle
= drm_gem_prime_fd_to_handle
,
836 .gem_prime_import
= drm_gem_prime_import
,
837 .gem_prime_export
= drm_gem_prime_export
,
838 .gem_prime_get_sg_table
= drm_gem_cma_prime_get_sg_table
,
839 .gem_prime_import_sg_table
= drm_gem_cma_prime_import_sg_table
,
840 .gem_prime_vmap
= drm_gem_cma_prime_vmap
,
841 .gem_prime_vunmap
= drm_gem_cma_prime_vunmap
,
842 .gem_prime_mmap
= drm_gem_cma_prime_mmap
,
843 .get_vblank_counter
= drm_vblank_count
,
844 .enable_vblank
= imx_drm_enable_vblank
,
845 .disable_vblank
= imx_drm_disable_vblank
,
846 .ioctls
= imx_drm_ioctls
,
847 .num_ioctls
= ARRAY_SIZE(imx_drm_ioctls
),
848 .fops
= &imx_drm_driver_fops
,
850 .desc
= "i.MX DRM graphics",
857 static int compare_parent_of(struct device
*dev
, void *data
)
859 struct of_phandle_args
*args
= data
;
860 return dev
->parent
&& dev
->parent
->of_node
== args
->np
;
863 static int compare_of(struct device
*dev
, void *data
)
865 return dev
->of_node
== data
;
868 static int imx_drm_add_components(struct device
*master
, struct master
*m
)
870 struct device_node
*np
= master
->of_node
;
875 struct of_phandle_args args
;
877 ret
= of_parse_phandle_with_fixed_args(np
, "crtcs", 1,
882 ret
= component_master_add_child(m
, compare_parent_of
, &args
);
883 of_node_put(args
.np
);
890 struct device_node
*node
;
892 node
= of_parse_phandle(np
, "connectors", i
);
896 ret
= component_master_add_child(m
, compare_of
, node
);
905 static int imx_drm_bind(struct device
*dev
)
907 return drm_platform_init(&imx_drm_driver
, to_platform_device(dev
));
910 static void imx_drm_unbind(struct device
*dev
)
912 drm_put_dev(dev_get_drvdata(dev
));
915 static const struct component_master_ops imx_drm_ops
= {
916 .add_components
= imx_drm_add_components
,
917 .bind
= imx_drm_bind
,
918 .unbind
= imx_drm_unbind
,
921 static int imx_drm_platform_probe(struct platform_device
*pdev
)
925 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
929 imx_drm_device
->dev
= &pdev
->dev
;
931 return component_master_add(&pdev
->dev
, &imx_drm_ops
);
934 static int imx_drm_platform_remove(struct platform_device
*pdev
)
936 component_master_del(&pdev
->dev
, &imx_drm_ops
);
940 static const struct of_device_id imx_drm_dt_ids
[] = {
941 { .compatible
= "fsl,imx-drm", },
944 MODULE_DEVICE_TABLE(of
, imx_drm_dt_ids
);
946 static struct platform_driver imx_drm_pdrv
= {
947 .probe
= imx_drm_platform_probe
,
948 .remove
= imx_drm_platform_remove
,
950 .owner
= THIS_MODULE
,
952 .of_match_table
= imx_drm_dt_ids
,
956 static int __init
imx_drm_init(void)
960 imx_drm_device
= kzalloc(sizeof(*imx_drm_device
), GFP_KERNEL
);
964 mutex_init(&imx_drm_device
->mutex
);
965 INIT_LIST_HEAD(&imx_drm_device
->connector_list
);
966 INIT_LIST_HEAD(&imx_drm_device
->encoder_list
);
968 ret
= platform_driver_register(&imx_drm_pdrv
);
975 kfree(imx_drm_device
);
980 static void __exit
imx_drm_exit(void)
982 platform_driver_unregister(&imx_drm_pdrv
);
984 kfree(imx_drm_device
);
987 module_init(imx_drm_init
);
988 module_exit(imx_drm_exit
);
990 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
991 MODULE_DESCRIPTION("i.MX drm driver core");
992 MODULE_LICENSE("GPL");