aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/vkms/Makefile2
-rw-r--r--drivers/gpu/drm/vkms/vkms_crtc.c35
-rw-r--r--drivers/gpu/drm/vkms/vkms_drv.c60
-rw-r--r--drivers/gpu/drm/vkms/vkms_drv.h24
-rw-r--r--drivers/gpu/drm/vkms/vkms_output.c91
-rw-r--r--drivers/gpu/drm/vkms/vkms_plane.c46
6 files changed, 211 insertions, 47 deletions
diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
index 2aef948d3a34..3f774a6a9c58 100644
--- a/drivers/gpu/drm/vkms/Makefile
+++ b/drivers/gpu/drm/vkms/Makefile
@@ -1,3 +1,3 @@
1vkms-y := vkms_drv.o 1vkms-y := vkms_drv.o vkms_plane.o vkms_output.o vkms_crtc.o
2 2
3obj-$(CONFIG_DRM_VKMS) += vkms.o 3obj-$(CONFIG_DRM_VKMS) += vkms.o
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
new file mode 100644
index 000000000000..bf76cd39ece7
--- /dev/null
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -0,0 +1,35 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 */
8
9#include "vkms_drv.h"
10#include <drm/drm_atomic_helper.h>
11#include <drm/drm_crtc_helper.h>
12
13static const struct drm_crtc_funcs vkms_crtc_funcs = {
14 .set_config = drm_atomic_helper_set_config,
15 .destroy = drm_crtc_cleanup,
16 .page_flip = drm_atomic_helper_page_flip,
17 .reset = drm_atomic_helper_crtc_reset,
18 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
19 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
20};
21
22int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
23 struct drm_plane *primary, struct drm_plane *cursor)
24{
25 int ret;
26
27 ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
28 &vkms_crtc_funcs, NULL);
29 if (ret) {
30 DRM_ERROR("Failed to init CRTC\n");
31 return ret;
32 }
33
34 return ret;
35}
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index aec3f180f96d..070613e32934 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -6,7 +6,6 @@
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
9#include <drm/drmP.h>
10#include <drm/drm_gem.h> 9#include <drm/drm_gem.h>
11#include <drm/drm_crtc_helper.h> 10#include <drm/drm_crtc_helper.h>
12#include <drm/drm_atomic_helper.h> 11#include <drm/drm_atomic_helper.h>
@@ -59,25 +58,24 @@ static struct drm_driver vkms_driver = {
59 .minor = DRIVER_MINOR, 58 .minor = DRIVER_MINOR,
60}; 59};
61 60
62static const u32 vkms_formats[] = { 61static const struct drm_mode_config_funcs vkms_mode_funcs = {
63 DRM_FORMAT_XRGB8888, 62 .atomic_check = drm_atomic_helper_check,
63 .atomic_commit = drm_atomic_helper_commit,
64}; 64};
65 65
66static void vkms_connector_destroy(struct drm_connector *connector) 66static int vkms_modeset_init(struct vkms_device *vkmsdev)
67{ 67{
68 drm_connector_unregister(connector); 68 struct drm_device *dev = &vkmsdev->drm;
69 drm_connector_cleanup(connector);
70}
71 69
72static const struct drm_connector_funcs vkms_connector_funcs = { 70 drm_mode_config_init(dev);
73 .fill_modes = drm_helper_probe_single_connector_modes, 71 dev->mode_config.funcs = &vkms_mode_funcs;
74 .destroy = vkms_connector_destroy, 72 dev->mode_config.min_width = XRES_MIN;
75}; 73 dev->mode_config.min_height = YRES_MIN;
74 dev->mode_config.max_width = XRES_MAX;
75 dev->mode_config.max_height = YRES_MAX;
76 76
77static const struct drm_mode_config_funcs vkms_mode_funcs = { 77 return vkms_output_init(vkmsdev);
78 .atomic_check = drm_atomic_helper_check, 78}
79 .atomic_commit = drm_atomic_helper_commit,
80};
81 79
82static int __init vkms_init(void) 80static int __init vkms_init(void)
83{ 81{
@@ -98,48 +96,24 @@ static int __init vkms_init(void)
98 goto out_fini; 96 goto out_fini;
99 } 97 }
100 98
101 drm_mode_config_init(&vkms_device->drm); 99 ret = vkms_modeset_init(vkms_device);
102 vkms_device->drm.mode_config.funcs = &vkms_mode_funcs; 100 if (ret)
103 vkms_device->drm.mode_config.min_width = XRES_MIN;
104 vkms_device->drm.mode_config.min_height = YRES_MIN;
105 vkms_device->drm.mode_config.max_width = XRES_MAX;
106 vkms_device->drm.mode_config.max_height = YRES_MAX;
107
108 ret = drm_connector_init(&vkms_device->drm, &vkms_device->connector,
109 &vkms_connector_funcs,
110 DRM_MODE_CONNECTOR_VIRTUAL);
111 if (ret < 0) {
112 DRM_ERROR("Failed to init connector\n");
113 goto out_unregister;
114 }
115
116 ret = drm_simple_display_pipe_init(&vkms_device->drm,
117 &vkms_device->pipe,
118 NULL,
119 vkms_formats,
120 ARRAY_SIZE(vkms_formats),
121 NULL,
122 &vkms_device->connector);
123 if (ret < 0) {
124 DRM_ERROR("Cannot setup simple display pipe\n");
125 goto out_unregister; 101 goto out_unregister;
126 }
127 102
128 ret = drm_dev_register(&vkms_device->drm, 0); 103 ret = drm_dev_register(&vkms_device->drm, 0);
129 if (ret) 104 if (ret)
130 goto out_unregister; 105 goto out_unregister;
131 106
132 drm_connector_register(&vkms_device->connector);
133
134 return 0; 107 return 0;
135 108
136out_unregister: 109out_unregister:
137 platform_device_unregister(vkms_device->platform); 110 platform_device_unregister(vkms_device->platform);
111
138out_fini: 112out_fini:
139 drm_dev_fini(&vkms_device->drm); 113 drm_dev_fini(&vkms_device->drm);
114
140out_free: 115out_free:
141 kfree(vkms_device); 116 kfree(vkms_device);
142
143 return ret; 117 return ret;
144} 118}
145 119
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index c77c5bf5032a..b0f9d2e61a42 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -1,13 +1,31 @@
1#ifndef _VKMS_DRV_H_ 1#ifndef _VKMS_DRV_H_
2#define _VKMS_DRV_H_ 2#define _VKMS_DRV_H_
3 3
4#include <drm/drm_simple_kms_helper.h> 4#include <drm/drmP.h>
5#include <drm/drm.h>
6#include <drm/drm_encoder.h>
7
8static const u32 vkms_formats[] = {
9 DRM_FORMAT_XRGB8888,
10};
11
12struct vkms_output {
13 struct drm_crtc crtc;
14 struct drm_encoder encoder;
15 struct drm_connector connector;
16};
5 17
6struct vkms_device { 18struct vkms_device {
7 struct drm_device drm; 19 struct drm_device drm;
8 struct platform_device *platform; 20 struct platform_device *platform;
9 struct drm_simple_display_pipe pipe; 21 struct vkms_output output;
10 struct drm_connector connector;
11}; 22};
12 23
24int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
25 struct drm_plane *primary, struct drm_plane *cursor);
26
27int vkms_output_init(struct vkms_device *vkmsdev);
28
29struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev);
30
13#endif /* _VKMS_DRV_H_ */ 31#endif /* _VKMS_DRV_H_ */
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
new file mode 100644
index 000000000000..48143eac3c12
--- /dev/null
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -0,0 +1,91 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 */
8
9#include "vkms_drv.h"
10#include <drm/drm_crtc_helper.h>
11
12static void vkms_connector_destroy(struct drm_connector *connector)
13{
14 drm_connector_unregister(connector);
15 drm_connector_cleanup(connector);
16}
17
18static const struct drm_connector_funcs vkms_connector_funcs = {
19 .fill_modes = drm_helper_probe_single_connector_modes,
20 .destroy = vkms_connector_destroy,
21};
22
23static const struct drm_encoder_funcs vkms_encoder_funcs = {
24 .destroy = drm_encoder_cleanup,
25};
26
27int vkms_output_init(struct vkms_device *vkmsdev)
28{
29 struct vkms_output *output = &vkmsdev->output;
30 struct drm_device *dev = &vkmsdev->drm;
31 struct drm_connector *connector = &output->connector;
32 struct drm_encoder *encoder = &output->encoder;
33 struct drm_crtc *crtc = &output->crtc;
34 struct drm_plane *primary;
35 int ret;
36
37 primary = vkms_plane_init(vkmsdev);
38 if (IS_ERR(primary))
39 return PTR_ERR(primary);
40
41 ret = vkms_crtc_init(dev, crtc, primary, NULL);
42 if (ret)
43 goto err_crtc;
44
45 ret = drm_connector_init(dev, connector, &vkms_connector_funcs,
46 DRM_MODE_CONNECTOR_VIRTUAL);
47 if (ret) {
48 DRM_ERROR("Failed to init connector\n");
49 goto err_connector;
50 }
51
52 ret = drm_connector_register(connector);
53 if (ret) {
54 DRM_ERROR("Failed to register connector\n");
55 goto err_connector_register;
56 }
57
58 ret = drm_encoder_init(dev, encoder, &vkms_encoder_funcs,
59 DRM_MODE_ENCODER_VIRTUAL, NULL);
60 if (ret) {
61 DRM_ERROR("Failed to init encoder\n");
62 goto err_encoder;
63 }
64 encoder->possible_crtcs = 1;
65
66 ret = drm_mode_connector_attach_encoder(connector, encoder);
67 if (ret) {
68 DRM_ERROR("Failed to attach connector to encoder\n");
69 goto err_attach;
70 }
71
72 drm_mode_config_reset(dev);
73
74 return 0;
75
76err_attach:
77 drm_encoder_cleanup(encoder);
78
79err_encoder:
80 drm_connector_unregister(connector);
81
82err_connector_register:
83 drm_connector_cleanup(connector);
84
85err_connector:
86 drm_crtc_cleanup(crtc);
87
88err_crtc:
89 drm_plane_cleanup(primary);
90 return ret;
91}
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
new file mode 100644
index 000000000000..2c25b1d6ab5b
--- /dev/null
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -0,0 +1,46 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 */
8
9#include "vkms_drv.h"
10#include <drm/drm_plane_helper.h>
11#include <drm/drm_atomic_helper.h>
12
13static const struct drm_plane_funcs vkms_plane_funcs = {
14 .update_plane = drm_atomic_helper_update_plane,
15 .disable_plane = drm_atomic_helper_disable_plane,
16 .destroy = drm_plane_cleanup,
17 .reset = drm_atomic_helper_plane_reset,
18 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
19 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
20};
21
22struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev)
23{
24 struct drm_device *dev = &vkmsdev->drm;
25 struct drm_plane *plane;
26 const u32 *formats;
27 int ret, nformats;
28
29 plane = kzalloc(sizeof(*plane), GFP_KERNEL);
30 if (!plane)
31 return ERR_PTR(-ENOMEM);
32
33 formats = vkms_formats;
34 nformats = ARRAY_SIZE(vkms_formats);
35
36 ret = drm_universal_plane_init(dev, plane, 0,
37 &vkms_plane_funcs,
38 formats, nformats,
39 NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
40 if (ret) {
41 kfree(plane);
42 return ERR_PTR(ret);
43 }
44
45 return plane;
46}