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_of.h>
28 #include "zx_drm_drv.h"
31 struct zx_drm_private
{
32 struct drm_fbdev_cma
*fbdev
;
35 static void zx_drm_fb_output_poll_changed(struct drm_device
*drm
)
37 struct zx_drm_private
*priv
= drm
->dev_private
;
39 drm_fbdev_cma_hotplug_event(priv
->fbdev
);
42 static const struct drm_mode_config_funcs zx_drm_mode_config_funcs
= {
43 .fb_create
= drm_fb_cma_create
,
44 .output_poll_changed
= zx_drm_fb_output_poll_changed
,
45 .atomic_check
= drm_atomic_helper_check
,
46 .atomic_commit
= drm_atomic_helper_commit
,
49 static void zx_drm_lastclose(struct drm_device
*drm
)
51 struct zx_drm_private
*priv
= drm
->dev_private
;
53 drm_fbdev_cma_restore_mode(priv
->fbdev
);
56 DEFINE_DRM_GEM_CMA_FOPS(zx_drm_fops
);
58 static struct drm_driver zx_drm_driver
= {
59 .driver_features
= DRIVER_GEM
| DRIVER_MODESET
| DRIVER_PRIME
|
61 .lastclose
= zx_drm_lastclose
,
62 .gem_free_object
= drm_gem_cma_free_object
,
63 .gem_vm_ops
= &drm_gem_cma_vm_ops
,
64 .dumb_create
= drm_gem_cma_dumb_create
,
65 .dumb_map_offset
= drm_gem_cma_dumb_map_offset
,
66 .dumb_destroy
= drm_gem_dumb_destroy
,
67 .prime_handle_to_fd
= drm_gem_prime_handle_to_fd
,
68 .prime_fd_to_handle
= drm_gem_prime_fd_to_handle
,
69 .gem_prime_export
= drm_gem_prime_export
,
70 .gem_prime_import
= drm_gem_prime_import
,
71 .gem_prime_get_sg_table
= drm_gem_cma_prime_get_sg_table
,
72 .gem_prime_import_sg_table
= drm_gem_cma_prime_import_sg_table
,
73 .gem_prime_vmap
= drm_gem_cma_prime_vmap
,
74 .gem_prime_vunmap
= drm_gem_cma_prime_vunmap
,
75 .gem_prime_mmap
= drm_gem_cma_prime_mmap
,
78 .desc
= "ZTE VOU Controller DRM",
84 static int zx_drm_bind(struct device
*dev
)
86 struct drm_device
*drm
;
87 struct zx_drm_private
*priv
;
90 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
94 drm
= drm_dev_alloc(&zx_drm_driver
, dev
);
98 drm
->dev_private
= priv
;
99 dev_set_drvdata(dev
, drm
);
101 drm_mode_config_init(drm
);
102 drm
->mode_config
.min_width
= 16;
103 drm
->mode_config
.min_height
= 16;
104 drm
->mode_config
.max_width
= 4096;
105 drm
->mode_config
.max_height
= 4096;
106 drm
->mode_config
.funcs
= &zx_drm_mode_config_funcs
;
108 ret
= component_bind_all(dev
, drm
);
110 DRM_DEV_ERROR(dev
, "failed to bind all components: %d\n", ret
);
114 ret
= drm_vblank_init(drm
, drm
->mode_config
.num_crtc
);
116 DRM_DEV_ERROR(dev
, "failed to init vblank: %d\n", ret
);
121 * We will manage irq handler on our own. In this case, irq_enabled
122 * need to be true for using vblank core support.
124 drm
->irq_enabled
= true;
126 drm_mode_config_reset(drm
);
127 drm_kms_helper_poll_init(drm
);
129 priv
->fbdev
= drm_fbdev_cma_init(drm
, 32,
130 drm
->mode_config
.num_connector
);
131 if (IS_ERR(priv
->fbdev
)) {
132 ret
= PTR_ERR(priv
->fbdev
);
133 DRM_DEV_ERROR(dev
, "failed to init cma fbdev: %d\n", ret
);
138 ret
= drm_dev_register(drm
, 0);
146 drm_fbdev_cma_fini(priv
->fbdev
);
150 drm_kms_helper_poll_fini(drm
);
151 drm_mode_config_cleanup(drm
);
152 drm_vblank_cleanup(drm
);
154 component_unbind_all(dev
, drm
);
156 dev_set_drvdata(dev
, NULL
);
157 drm
->dev_private
= NULL
;
162 static void zx_drm_unbind(struct device
*dev
)
164 struct drm_device
*drm
= dev_get_drvdata(dev
);
165 struct zx_drm_private
*priv
= drm
->dev_private
;
167 drm_dev_unregister(drm
);
169 drm_fbdev_cma_fini(priv
->fbdev
);
172 drm_kms_helper_poll_fini(drm
);
173 drm_mode_config_cleanup(drm
);
174 drm_vblank_cleanup(drm
);
175 component_unbind_all(dev
, drm
);
176 dev_set_drvdata(dev
, NULL
);
177 drm
->dev_private
= NULL
;
181 static const struct component_master_ops zx_drm_master_ops
= {
183 .unbind
= zx_drm_unbind
,
186 static int compare_of(struct device
*dev
, void *data
)
188 return dev
->of_node
== data
;
191 static int zx_drm_probe(struct platform_device
*pdev
)
193 struct device
*dev
= &pdev
->dev
;
194 struct device_node
*parent
= dev
->of_node
;
195 struct device_node
*child
;
196 struct component_match
*match
= NULL
;
199 ret
= devm_of_platform_populate(dev
);
203 for_each_available_child_of_node(parent
, child
) {
204 component_match_add(dev
, &match
, compare_of
, child
);
208 return component_master_add_with_match(dev
, &zx_drm_master_ops
, match
);
211 static int zx_drm_remove(struct platform_device
*pdev
)
213 component_master_del(&pdev
->dev
, &zx_drm_master_ops
);
217 static const struct of_device_id zx_drm_of_match
[] = {
218 { .compatible
= "zte,zx296718-vou", },
221 MODULE_DEVICE_TABLE(of
, zx_drm_of_match
);
223 static struct platform_driver zx_drm_platform_driver
= {
224 .probe
= zx_drm_probe
,
225 .remove
= zx_drm_remove
,
228 .of_match_table
= zx_drm_of_match
,
232 static struct platform_driver
*drivers
[] = {
237 &zx_drm_platform_driver
,
240 static int zx_drm_init(void)
242 return platform_register_drivers(drivers
, ARRAY_SIZE(drivers
));
244 module_init(zx_drm_init
);
246 static void zx_drm_exit(void)
248 platform_unregister_drivers(drivers
, ARRAY_SIZE(drivers
));
250 module_exit(zx_drm_exit
);
252 MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
253 MODULE_DESCRIPTION("ZTE ZX VOU DRM driver");
254 MODULE_LICENSE("GPL v2");