Skip to content

Commit 854502f

Browse files
rodrigosiqueirapadovan
authored andcommitted
drm/vkms: Add basic CRTC initialization
This commit adds the essential infrastructure for around CRTCs which is composed of: a new data struct for output data information, a function for creating planes, and a simple encoder attached to the connector. Finally, due to the introduction of a new initialization function, connectors were moved from vkms_drv.c to vkms_display.c. Signed-off-by: Rodrigo Siqueira <[email protected]> Reviewed-by: Haneen Mohammed <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Signed-off-by: Gustavo Padovan <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/b6e27bc6a54f5cb340658fa5969f7b48fbfbf1b7.1526514457.git.rodrigosiqueiramelo@gmail.com
1 parent c04372e commit 854502f

File tree

6 files changed

+211
-47
lines changed

6 files changed

+211
-47
lines changed

drivers/gpu/drm/vkms/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
vkms-y := vkms_drv.o
1+
vkms-y := vkms_drv.o vkms_plane.o vkms_output.o vkms_crtc.o
22

33
obj-$(CONFIG_DRM_VKMS) += vkms.o

drivers/gpu/drm/vkms/vkms_crtc.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
13+
static 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+
22+
int 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+
}

drivers/gpu/drm/vkms/vkms_drv.c

Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
#include <linux/module.h>
9-
#include <drm/drmP.h>
109
#include <drm/drm_gem.h>
1110
#include <drm/drm_crtc_helper.h>
1211
#include <drm/drm_atomic_helper.h>
@@ -59,25 +58,24 @@ static struct drm_driver vkms_driver = {
5958
.minor = DRIVER_MINOR,
6059
};
6160

62-
static const u32 vkms_formats[] = {
63-
DRM_FORMAT_XRGB8888,
61+
static const struct drm_mode_config_funcs vkms_mode_funcs = {
62+
.atomic_check = drm_atomic_helper_check,
63+
.atomic_commit = drm_atomic_helper_commit,
6464
};
6565

66-
static void vkms_connector_destroy(struct drm_connector *connector)
66+
static int vkms_modeset_init(struct vkms_device *vkmsdev)
6767
{
68-
drm_connector_unregister(connector);
69-
drm_connector_cleanup(connector);
70-
}
68+
struct drm_device *dev = &vkmsdev->drm;
7169

72-
static const struct drm_connector_funcs vkms_connector_funcs = {
73-
.fill_modes = drm_helper_probe_single_connector_modes,
74-
.destroy = vkms_connector_destroy,
75-
};
70+
drm_mode_config_init(dev);
71+
dev->mode_config.funcs = &vkms_mode_funcs;
72+
dev->mode_config.min_width = XRES_MIN;
73+
dev->mode_config.min_height = YRES_MIN;
74+
dev->mode_config.max_width = XRES_MAX;
75+
dev->mode_config.max_height = YRES_MAX;
7676

77-
static const struct drm_mode_config_funcs vkms_mode_funcs = {
78-
.atomic_check = drm_atomic_helper_check,
79-
.atomic_commit = drm_atomic_helper_commit,
80-
};
77+
return vkms_output_init(vkmsdev);
78+
}
8179

8280
static int __init vkms_init(void)
8381
{
@@ -98,48 +96,24 @@ static int __init vkms_init(void)
9896
goto out_fini;
9997
}
10098

101-
drm_mode_config_init(&vkms_device->drm);
102-
vkms_device->drm.mode_config.funcs = &vkms_mode_funcs;
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");
99+
ret = vkms_modeset_init(vkms_device);
100+
if (ret)
125101
goto out_unregister;
126-
}
127102

128103
ret = drm_dev_register(&vkms_device->drm, 0);
129104
if (ret)
130105
goto out_unregister;
131106

132-
drm_connector_register(&vkms_device->connector);
133-
134107
return 0;
135108

136109
out_unregister:
137110
platform_device_unregister(vkms_device->platform);
111+
138112
out_fini:
139113
drm_dev_fini(&vkms_device->drm);
114+
140115
out_free:
141116
kfree(vkms_device);
142-
143117
return ret;
144118
}
145119

drivers/gpu/drm/vkms/vkms_drv.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
#ifndef _VKMS_DRV_H_
22
#define _VKMS_DRV_H_
33

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+
8+
static const u32 vkms_formats[] = {
9+
DRM_FORMAT_XRGB8888,
10+
};
11+
12+
struct vkms_output {
13+
struct drm_crtc crtc;
14+
struct drm_encoder encoder;
15+
struct drm_connector connector;
16+
};
517

618
struct vkms_device {
719
struct drm_device drm;
820
struct platform_device *platform;
9-
struct drm_simple_display_pipe pipe;
10-
struct drm_connector connector;
21+
struct vkms_output output;
1122
};
1223

24+
int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
25+
struct drm_plane *primary, struct drm_plane *cursor);
26+
27+
int vkms_output_init(struct vkms_device *vkmsdev);
28+
29+
struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev);
30+
1331
#endif /* _VKMS_DRV_H_ */

drivers/gpu/drm/vkms/vkms_output.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
12+
static void vkms_connector_destroy(struct drm_connector *connector)
13+
{
14+
drm_connector_unregister(connector);
15+
drm_connector_cleanup(connector);
16+
}
17+
18+
static const struct drm_connector_funcs vkms_connector_funcs = {
19+
.fill_modes = drm_helper_probe_single_connector_modes,
20+
.destroy = vkms_connector_destroy,
21+
};
22+
23+
static const struct drm_encoder_funcs vkms_encoder_funcs = {
24+
.destroy = drm_encoder_cleanup,
25+
};
26+
27+
int 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+
76+
err_attach:
77+
drm_encoder_cleanup(encoder);
78+
79+
err_encoder:
80+
drm_connector_unregister(connector);
81+
82+
err_connector_register:
83+
drm_connector_cleanup(connector);
84+
85+
err_connector:
86+
drm_crtc_cleanup(crtc);
87+
88+
err_crtc:
89+
drm_plane_cleanup(primary);
90+
return ret;
91+
}

drivers/gpu/drm/vkms/vkms_plane.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
13+
static 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+
22+
struct 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+
}

0 commit comments

Comments
 (0)