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