Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.20 204 lines 5.0 kB view raw
1/* 2 * Copyright 2016 Linaro Ltd. 3 * Copyright 2016 ZTE Corporation. 4 * 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. 8 * 9 */ 10 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> 18 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> 27#include <drm/drmP.h> 28 29#include "zx_drm_drv.h" 30#include "zx_vou.h" 31 32static const struct drm_mode_config_funcs zx_drm_mode_config_funcs = { 33 .fb_create = drm_gem_fb_create, 34 .atomic_check = drm_atomic_helper_check, 35 .atomic_commit = drm_atomic_helper_commit, 36}; 37 38DEFINE_DRM_GEM_CMA_FOPS(zx_drm_fops); 39 40static struct drm_driver zx_drm_driver = { 41 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | 42 DRIVER_ATOMIC, 43 .gem_free_object_unlocked = drm_gem_cma_free_object, 44 .gem_vm_ops = &drm_gem_cma_vm_ops, 45 .dumb_create = drm_gem_cma_dumb_create, 46 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 47 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 48 .gem_prime_export = drm_gem_prime_export, 49 .gem_prime_import = drm_gem_prime_import, 50 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, 51 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, 52 .gem_prime_vmap = drm_gem_cma_prime_vmap, 53 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 54 .gem_prime_mmap = drm_gem_cma_prime_mmap, 55 .fops = &zx_drm_fops, 56 .name = "zx-vou", 57 .desc = "ZTE VOU Controller DRM", 58 .date = "20160811", 59 .major = 1, 60 .minor = 0, 61}; 62 63static int zx_drm_bind(struct device *dev) 64{ 65 struct drm_device *drm; 66 int ret; 67 68 drm = drm_dev_alloc(&zx_drm_driver, dev); 69 if (IS_ERR(drm)) 70 return PTR_ERR(drm); 71 72 dev_set_drvdata(dev, drm); 73 74 drm_mode_config_init(drm); 75 drm->mode_config.min_width = 16; 76 drm->mode_config.min_height = 16; 77 drm->mode_config.max_width = 4096; 78 drm->mode_config.max_height = 4096; 79 drm->mode_config.funcs = &zx_drm_mode_config_funcs; 80 81 ret = component_bind_all(dev, drm); 82 if (ret) { 83 DRM_DEV_ERROR(dev, "failed to bind all components: %d\n", ret); 84 goto out_unregister; 85 } 86 87 ret = drm_vblank_init(drm, drm->mode_config.num_crtc); 88 if (ret < 0) { 89 DRM_DEV_ERROR(dev, "failed to init vblank: %d\n", ret); 90 goto out_unbind; 91 } 92 93 /* 94 * We will manage irq handler on our own. In this case, irq_enabled 95 * need to be true for using vblank core support. 96 */ 97 drm->irq_enabled = true; 98 99 drm_mode_config_reset(drm); 100 drm_kms_helper_poll_init(drm); 101 102 ret = drm_dev_register(drm, 0); 103 if (ret) 104 goto out_poll_fini; 105 106 drm_fbdev_generic_setup(drm, 32); 107 108 return 0; 109 110out_poll_fini: 111 drm_kms_helper_poll_fini(drm); 112 drm_mode_config_cleanup(drm); 113out_unbind: 114 component_unbind_all(dev, drm); 115out_unregister: 116 dev_set_drvdata(dev, NULL); 117 drm_dev_unref(drm); 118 return ret; 119} 120 121static void zx_drm_unbind(struct device *dev) 122{ 123 struct drm_device *drm = dev_get_drvdata(dev); 124 125 drm_dev_unregister(drm); 126 drm_kms_helper_poll_fini(drm); 127 drm_mode_config_cleanup(drm); 128 component_unbind_all(dev, drm); 129 dev_set_drvdata(dev, NULL); 130 drm_dev_unref(drm); 131} 132 133static const struct component_master_ops zx_drm_master_ops = { 134 .bind = zx_drm_bind, 135 .unbind = zx_drm_unbind, 136}; 137 138static int compare_of(struct device *dev, void *data) 139{ 140 return dev->of_node == data; 141} 142 143static int zx_drm_probe(struct platform_device *pdev) 144{ 145 struct device *dev = &pdev->dev; 146 struct device_node *parent = dev->of_node; 147 struct device_node *child; 148 struct component_match *match = NULL; 149 int ret; 150 151 ret = devm_of_platform_populate(dev); 152 if (ret) 153 return ret; 154 155 for_each_available_child_of_node(parent, child) 156 component_match_add(dev, &match, compare_of, child); 157 158 return component_master_add_with_match(dev, &zx_drm_master_ops, match); 159} 160 161static int zx_drm_remove(struct platform_device *pdev) 162{ 163 component_master_del(&pdev->dev, &zx_drm_master_ops); 164 return 0; 165} 166 167static const struct of_device_id zx_drm_of_match[] = { 168 { .compatible = "zte,zx296718-vou", }, 169 { /* end */ }, 170}; 171MODULE_DEVICE_TABLE(of, zx_drm_of_match); 172 173static struct platform_driver zx_drm_platform_driver = { 174 .probe = zx_drm_probe, 175 .remove = zx_drm_remove, 176 .driver = { 177 .name = "zx-drm", 178 .of_match_table = zx_drm_of_match, 179 }, 180}; 181 182static struct platform_driver *drivers[] = { 183 &zx_crtc_driver, 184 &zx_hdmi_driver, 185 &zx_tvenc_driver, 186 &zx_vga_driver, 187 &zx_drm_platform_driver, 188}; 189 190static int zx_drm_init(void) 191{ 192 return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 193} 194module_init(zx_drm_init); 195 196static void zx_drm_exit(void) 197{ 198 platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); 199} 200module_exit(zx_drm_exit); 201 202MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>"); 203MODULE_DESCRIPTION("ZTE ZX VOU DRM driver"); 204MODULE_LICENSE("GPL v2");