2 * Copyright (C) 2016 Noralf Trønnes
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
10 #include <drm/drm_atomic.h>
11 #include <drm/drm_atomic_helper.h>
12 #include <drm/drm_crtc_helper.h>
13 #include <drm/drm_fb_helper.h>
14 #include <drm/drm_gem_framebuffer_helper.h>
15 #include <drm/tinydrm/tinydrm.h>
16 #include <linux/device.h>
17 #include <linux/dma-buf.h>
22 * This library provides driver helpers for very simple display hardware.
24 * It is based on &drm_simple_display_pipe coupled with a &drm_connector which
25 * has only one fixed &drm_display_mode. The framebuffers are backed by the
26 * cma helper and have support for framebuffer flushing (dirty).
27 * fbdev support is also included.
34 * The driver allocates &tinydrm_device, initializes it using
35 * devm_tinydrm_init(), sets up the pipeline using tinydrm_display_pipe_init()
36 * and registers the DRM device using devm_tinydrm_register().
39 static struct drm_framebuffer *
40 tinydrm_fb_create(struct drm_device *drm, struct drm_file *file_priv,
41 const struct drm_mode_fb_cmd2 *mode_cmd)
43 struct tinydrm_device *tdev = drm->dev_private;
45 return drm_gem_fb_create_with_funcs(drm, file_priv, mode_cmd,
49 static const struct drm_mode_config_funcs tinydrm_mode_config_funcs = {
50 .fb_create = tinydrm_fb_create,
51 .atomic_check = drm_atomic_helper_check,
52 .atomic_commit = drm_atomic_helper_commit,
55 static int tinydrm_init(struct device *parent, struct tinydrm_device *tdev,
56 const struct drm_framebuffer_funcs *fb_funcs,
57 struct drm_driver *driver)
59 struct drm_device *drm;
61 mutex_init(&tdev->dirty_lock);
62 tdev->fb_funcs = fb_funcs;
65 * We don't embed drm_device, because that prevent us from using
66 * devm_kzalloc() to allocate tinydrm_device in the driver since
67 * drm_dev_put() frees the structure. The devm_ functions provide
68 * for easy error handling.
70 drm = drm_dev_alloc(driver, parent);
75 drm->dev_private = tdev;
76 drm_mode_config_init(drm);
77 drm->mode_config.funcs = &tinydrm_mode_config_funcs;
78 drm->mode_config.allow_fb_modifiers = true;
83 static void tinydrm_fini(struct tinydrm_device *tdev)
85 drm_mode_config_cleanup(tdev->drm);
86 mutex_destroy(&tdev->dirty_lock);
87 tdev->drm->dev_private = NULL;
88 drm_dev_put(tdev->drm);
91 static void devm_tinydrm_release(void *data)
97 * devm_tinydrm_init - Initialize tinydrm device
98 * @parent: Parent device object
99 * @tdev: tinydrm device
100 * @fb_funcs: Framebuffer functions
101 * @driver: DRM driver
103 * This function initializes @tdev, the underlying DRM device and it's
104 * mode_config. Resources will be automatically freed on driver detach (devres)
105 * using drm_mode_config_cleanup() and drm_dev_put().
108 * Zero on success, negative error code on failure.
110 int devm_tinydrm_init(struct device *parent, struct tinydrm_device *tdev,
111 const struct drm_framebuffer_funcs *fb_funcs,
112 struct drm_driver *driver)
116 ret = tinydrm_init(parent, tdev, fb_funcs, driver);
120 ret = devm_add_action(parent, devm_tinydrm_release, tdev);
126 EXPORT_SYMBOL(devm_tinydrm_init);
128 static int tinydrm_register(struct tinydrm_device *tdev)
130 struct drm_device *drm = tdev->drm;
133 ret = drm_dev_register(tdev->drm, 0);
137 ret = drm_fbdev_generic_setup(drm, 0);
139 DRM_ERROR("Failed to initialize fbdev: %d\n", ret);
144 static void tinydrm_unregister(struct tinydrm_device *tdev)
146 drm_atomic_helper_shutdown(tdev->drm);
147 drm_dev_unregister(tdev->drm);
150 static void devm_tinydrm_register_release(void *data)
152 tinydrm_unregister(data);
156 * devm_tinydrm_register - Register tinydrm device
157 * @tdev: tinydrm device
159 * This function registers the underlying DRM device and fbdev.
160 * These resources will be automatically unregistered on driver detach (devres)
161 * and the display pipeline will be disabled.
164 * Zero on success, negative error code on failure.
166 int devm_tinydrm_register(struct tinydrm_device *tdev)
168 struct device *dev = tdev->drm->dev;
171 ret = tinydrm_register(tdev);
175 ret = devm_add_action(dev, devm_tinydrm_register_release, tdev);
177 tinydrm_unregister(tdev);
181 EXPORT_SYMBOL(devm_tinydrm_register);
184 * tinydrm_shutdown - Shutdown tinydrm
185 * @tdev: tinydrm device
187 * This function makes sure that the display pipeline is disabled.
188 * Used by drivers in their shutdown callback to turn off the display
189 * on machine shutdown and reboot.
191 void tinydrm_shutdown(struct tinydrm_device *tdev)
193 drm_atomic_helper_shutdown(tdev->drm);
195 EXPORT_SYMBOL(tinydrm_shutdown);
197 MODULE_LICENSE("GPL");