2 * Copyright 2016 Linaro Ltd.
3 * Copyright 2016 ZTE Corporation.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
11 #include <linux/clk.h>
12 #include <linux/component.h>
13 #include <linux/list.h>
14 #include <linux/module.h>
15 #include <linux/of_graph.h>
16 #include <linux/of_platform.h>
17 #include <linux/spinlock.h>
19 #include <drm/drm_atomic_helper.h>
20 #include <drm/drm_crtc.h>
21 #include <drm/drm_crtc_helper.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_gem_framebuffer_helper.h>
26 #include <drm/drm_of.h>
29 #include "zx_drm_drv.h"
32 static const struct drm_mode_config_funcs zx_drm_mode_config_funcs
= {
33 .fb_create
= drm_gem_fb_create
,
34 .output_poll_changed
= drm_fb_helper_output_poll_changed
,
35 .atomic_check
= drm_atomic_helper_check
,
36 .atomic_commit
= drm_atomic_helper_commit
,
39 DEFINE_DRM_GEM_CMA_FOPS(zx_drm_fops
);
41 static struct drm_driver zx_drm_driver
= {
42 .driver_features
= DRIVER_GEM
| DRIVER_MODESET
| DRIVER_PRIME
|
44 .lastclose
= drm_fb_helper_lastclose
,
45 .gem_free_object_unlocked
= drm_gem_cma_free_object
,
46 .gem_vm_ops
= &drm_gem_cma_vm_ops
,
47 .dumb_create
= drm_gem_cma_dumb_create
,
48 .prime_handle_to_fd
= drm_gem_prime_handle_to_fd
,
49 .prime_fd_to_handle
= drm_gem_prime_fd_to_handle
,
50 .gem_prime_export
= drm_gem_prime_export
,
51 .gem_prime_import
= drm_gem_prime_import
,
52 .gem_prime_get_sg_table
= drm_gem_cma_prime_get_sg_table
,
53 .gem_prime_import_sg_table
= drm_gem_cma_prime_import_sg_table
,
54 .gem_prime_vmap
= drm_gem_cma_prime_vmap
,
55 .gem_prime_vunmap
= drm_gem_cma_prime_vunmap
,
56 .gem_prime_mmap
= drm_gem_cma_prime_mmap
,
59 .desc
= "ZTE VOU Controller DRM",
65 static int zx_drm_bind(struct device
*dev
)
67 struct drm_device
*drm
;
70 drm
= drm_dev_alloc(&zx_drm_driver
, dev
);
74 dev_set_drvdata(dev
, drm
);
76 drm_mode_config_init(drm
);
77 drm
->mode_config
.min_width
= 16;
78 drm
->mode_config
.min_height
= 16;
79 drm
->mode_config
.max_width
= 4096;
80 drm
->mode_config
.max_height
= 4096;
81 drm
->mode_config
.funcs
= &zx_drm_mode_config_funcs
;
83 ret
= component_bind_all(dev
, drm
);
85 DRM_DEV_ERROR(dev
, "failed to bind all components: %d\n", ret
);
89 ret
= drm_vblank_init(drm
, drm
->mode_config
.num_crtc
);
91 DRM_DEV_ERROR(dev
, "failed to init vblank: %d\n", ret
);
96 * We will manage irq handler on our own. In this case, irq_enabled
97 * need to be true for using vblank core support.
99 drm
->irq_enabled
= true;
101 drm_mode_config_reset(drm
);
102 drm_kms_helper_poll_init(drm
);
104 ret
= drm_fb_cma_fbdev_init(drm
, 32, 0);
106 DRM_DEV_ERROR(dev
, "failed to init cma fbdev: %d\n", ret
);
110 ret
= drm_dev_register(drm
, 0);
117 drm_fb_cma_fbdev_fini(drm
);
119 drm_kms_helper_poll_fini(drm
);
120 drm_mode_config_cleanup(drm
);
122 component_unbind_all(dev
, drm
);
124 dev_set_drvdata(dev
, NULL
);
129 static void zx_drm_unbind(struct device
*dev
)
131 struct drm_device
*drm
= dev_get_drvdata(dev
);
133 drm_dev_unregister(drm
);
134 drm_fb_cma_fbdev_fini(drm
);
135 drm_kms_helper_poll_fini(drm
);
136 drm_mode_config_cleanup(drm
);
137 component_unbind_all(dev
, drm
);
138 dev_set_drvdata(dev
, NULL
);
142 static const struct component_master_ops zx_drm_master_ops
= {
144 .unbind
= zx_drm_unbind
,
147 static int compare_of(struct device
*dev
, void *data
)
149 return dev
->of_node
== data
;
152 static int zx_drm_probe(struct platform_device
*pdev
)
154 struct device
*dev
= &pdev
->dev
;
155 struct device_node
*parent
= dev
->of_node
;
156 struct device_node
*child
;
157 struct component_match
*match
= NULL
;
160 ret
= devm_of_platform_populate(dev
);
164 for_each_available_child_of_node(parent
, child
) {
165 component_match_add(dev
, &match
, compare_of
, child
);
169 return component_master_add_with_match(dev
, &zx_drm_master_ops
, match
);
172 static int zx_drm_remove(struct platform_device
*pdev
)
174 component_master_del(&pdev
->dev
, &zx_drm_master_ops
);
178 static const struct of_device_id zx_drm_of_match
[] = {
179 { .compatible
= "zte,zx296718-vou", },
182 MODULE_DEVICE_TABLE(of
, zx_drm_of_match
);
184 static struct platform_driver zx_drm_platform_driver
= {
185 .probe
= zx_drm_probe
,
186 .remove
= zx_drm_remove
,
189 .of_match_table
= zx_drm_of_match
,
193 static struct platform_driver
*drivers
[] = {
198 &zx_drm_platform_driver
,
201 static int zx_drm_init(void)
203 return platform_register_drivers(drivers
, ARRAY_SIZE(drivers
));
205 module_init(zx_drm_init
);
207 static void zx_drm_exit(void)
209 platform_unregister_drivers(drivers
, ARRAY_SIZE(drivers
));
211 module_exit(zx_drm_exit
);
213 MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
214 MODULE_DESCRIPTION("ZTE ZX VOU DRM driver");
215 MODULE_LICENSE("GPL v2");