forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/gpu/drm/bochs/bochs_kms.c
....@@ -1,12 +1,14 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
2
- * This program is free software; you can redistribute it and/or modify
3
- * it under the terms of the GNU General Public License as published by
4
- * the Free Software Foundation; either version 2 of the License, or
5
- * (at your option) any later version.
63 */
74
5
+#include <linux/moduleparam.h>
6
+
7
+#include <drm/drm_atomic_helper.h>
8
+#include <drm/drm_gem_framebuffer_helper.h>
9
+#include <drm/drm_probe_helper.h>
10
+
811 #include "bochs.h"
9
-#include <drm/drm_plane_helper.h>
1012
1113 static int defx = 1024;
1214 static int defy = 768;
....@@ -18,215 +20,84 @@
1820
1921 /* ---------------------------------------------------------------------- */
2022
21
-static void bochs_crtc_dpms(struct drm_crtc *crtc, int mode)
23
+static const uint32_t bochs_formats[] = {
24
+ DRM_FORMAT_XRGB8888,
25
+ DRM_FORMAT_BGRX8888,
26
+};
27
+
28
+static void bochs_plane_update(struct bochs_device *bochs,
29
+ struct drm_plane_state *state)
2230 {
23
- switch (mode) {
24
- case DRM_MODE_DPMS_ON:
25
- case DRM_MODE_DPMS_STANDBY:
26
- case DRM_MODE_DPMS_SUSPEND:
27
- case DRM_MODE_DPMS_OFF:
28
- default:
31
+ struct drm_gem_vram_object *gbo;
32
+ s64 gpu_addr;
33
+
34
+ if (!state->fb || !bochs->stride)
2935 return;
30
- }
36
+
37
+ gbo = drm_gem_vram_of_gem(state->fb->obj[0]);
38
+ gpu_addr = drm_gem_vram_offset(gbo);
39
+ if (WARN_ON_ONCE(gpu_addr < 0))
40
+ return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
41
+
42
+ bochs_hw_setbase(bochs,
43
+ state->crtc_x,
44
+ state->crtc_y,
45
+ state->fb->pitches[0],
46
+ state->fb->offsets[0] + gpu_addr);
47
+ bochs_hw_setformat(bochs, state->fb->format);
3148 }
3249
33
-static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
34
- struct drm_framebuffer *old_fb)
50
+static void bochs_pipe_enable(struct drm_simple_display_pipe *pipe,
51
+ struct drm_crtc_state *crtc_state,
52
+ struct drm_plane_state *plane_state)
3553 {
36
- struct bochs_device *bochs =
37
- container_of(crtc, struct bochs_device, crtc);
38
- struct bochs_framebuffer *bochs_fb;
39
- struct bochs_bo *bo;
40
- u64 gpu_addr = 0;
41
- int ret;
54
+ struct bochs_device *bochs = pipe->crtc.dev->dev_private;
4255
43
- if (old_fb) {
44
- bochs_fb = to_bochs_framebuffer(old_fb);
45
- bo = gem_to_bochs_bo(bochs_fb->obj);
46
- ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
47
- if (ret) {
48
- DRM_ERROR("failed to reserve old_fb bo\n");
49
- } else {
50
- bochs_bo_unpin(bo);
51
- ttm_bo_unreserve(&bo->bo);
52
- }
53
- }
54
-
55
- if (WARN_ON(crtc->primary->fb == NULL))
56
- return -EINVAL;
57
-
58
- bochs_fb = to_bochs_framebuffer(crtc->primary->fb);
59
- bo = gem_to_bochs_bo(bochs_fb->obj);
60
- ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
61
- if (ret)
62
- return ret;
63
-
64
- ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
65
- if (ret) {
66
- ttm_bo_unreserve(&bo->bo);
67
- return ret;
68
- }
69
-
70
- ttm_bo_unreserve(&bo->bo);
71
- bochs_hw_setbase(bochs, x, y, gpu_addr);
72
- return 0;
56
+ bochs_hw_setmode(bochs, &crtc_state->mode);
57
+ bochs_plane_update(bochs, plane_state);
7358 }
7459
75
-static int bochs_crtc_mode_set(struct drm_crtc *crtc,
76
- struct drm_display_mode *mode,
77
- struct drm_display_mode *adjusted_mode,
78
- int x, int y, struct drm_framebuffer *old_fb)
60
+static void bochs_pipe_update(struct drm_simple_display_pipe *pipe,
61
+ struct drm_plane_state *old_state)
7962 {
80
- struct bochs_device *bochs =
81
- container_of(crtc, struct bochs_device, crtc);
63
+ struct bochs_device *bochs = pipe->crtc.dev->dev_private;
8264
83
- bochs_hw_setmode(bochs, mode);
84
- bochs_crtc_mode_set_base(crtc, x, y, old_fb);
85
- return 0;
65
+ bochs_plane_update(bochs, pipe->plane.state);
8666 }
8767
88
-static void bochs_crtc_prepare(struct drm_crtc *crtc)
89
-{
90
-}
91
-
92
-static void bochs_crtc_commit(struct drm_crtc *crtc)
93
-{
94
-}
95
-
96
-static int bochs_crtc_page_flip(struct drm_crtc *crtc,
97
- struct drm_framebuffer *fb,
98
- struct drm_pending_vblank_event *event,
99
- uint32_t page_flip_flags,
100
- struct drm_modeset_acquire_ctx *ctx)
101
-{
102
- struct bochs_device *bochs =
103
- container_of(crtc, struct bochs_device, crtc);
104
- struct drm_framebuffer *old_fb = crtc->primary->fb;
105
- unsigned long irqflags;
106
-
107
- crtc->primary->fb = fb;
108
- bochs_crtc_mode_set_base(crtc, 0, 0, old_fb);
109
- if (event) {
110
- spin_lock_irqsave(&bochs->dev->event_lock, irqflags);
111
- drm_crtc_send_vblank_event(crtc, event);
112
- spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags);
113
- }
114
- return 0;
115
-}
116
-
117
-/* These provide the minimum set of functions required to handle a CRTC */
118
-static const struct drm_crtc_funcs bochs_crtc_funcs = {
119
- .set_config = drm_crtc_helper_set_config,
120
- .destroy = drm_crtc_cleanup,
121
- .page_flip = bochs_crtc_page_flip,
68
+static const struct drm_simple_display_pipe_funcs bochs_pipe_funcs = {
69
+ .enable = bochs_pipe_enable,
70
+ .update = bochs_pipe_update,
71
+ .prepare_fb = drm_gem_vram_simple_display_pipe_prepare_fb,
72
+ .cleanup_fb = drm_gem_vram_simple_display_pipe_cleanup_fb,
12273 };
123
-
124
-static const struct drm_crtc_helper_funcs bochs_helper_funcs = {
125
- .dpms = bochs_crtc_dpms,
126
- .mode_set = bochs_crtc_mode_set,
127
- .mode_set_base = bochs_crtc_mode_set_base,
128
- .prepare = bochs_crtc_prepare,
129
- .commit = bochs_crtc_commit,
130
-};
131
-
132
-static void bochs_crtc_init(struct drm_device *dev)
133
-{
134
- struct bochs_device *bochs = dev->dev_private;
135
- struct drm_crtc *crtc = &bochs->crtc;
136
-
137
- drm_crtc_init(dev, crtc, &bochs_crtc_funcs);
138
- drm_crtc_helper_add(crtc, &bochs_helper_funcs);
139
-}
140
-
141
-static void bochs_encoder_mode_set(struct drm_encoder *encoder,
142
- struct drm_display_mode *mode,
143
- struct drm_display_mode *adjusted_mode)
144
-{
145
-}
146
-
147
-static void bochs_encoder_dpms(struct drm_encoder *encoder, int state)
148
-{
149
-}
150
-
151
-static void bochs_encoder_prepare(struct drm_encoder *encoder)
152
-{
153
-}
154
-
155
-static void bochs_encoder_commit(struct drm_encoder *encoder)
156
-{
157
-}
158
-
159
-static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = {
160
- .dpms = bochs_encoder_dpms,
161
- .mode_set = bochs_encoder_mode_set,
162
- .prepare = bochs_encoder_prepare,
163
- .commit = bochs_encoder_commit,
164
-};
165
-
166
-static const struct drm_encoder_funcs bochs_encoder_encoder_funcs = {
167
- .destroy = drm_encoder_cleanup,
168
-};
169
-
170
-static void bochs_encoder_init(struct drm_device *dev)
171
-{
172
- struct bochs_device *bochs = dev->dev_private;
173
- struct drm_encoder *encoder = &bochs->encoder;
174
-
175
- encoder->possible_crtcs = 0x1;
176
- drm_encoder_init(dev, encoder, &bochs_encoder_encoder_funcs,
177
- DRM_MODE_ENCODER_DAC, NULL);
178
- drm_encoder_helper_add(encoder, &bochs_encoder_helper_funcs);
179
-}
180
-
18174
18275 static int bochs_connector_get_modes(struct drm_connector *connector)
18376 {
184
- int count;
185
-
186
- count = drm_add_modes_noedid(connector, 8192, 8192);
187
- drm_set_preferred_mode(connector, defx, defy);
188
- return count;
189
-}
190
-
191
-static enum drm_mode_status bochs_connector_mode_valid(struct drm_connector *connector,
192
- struct drm_display_mode *mode)
193
-{
19477 struct bochs_device *bochs =
19578 container_of(connector, struct bochs_device, connector);
196
- unsigned long size = mode->hdisplay * mode->vdisplay * 4;
79
+ int count = 0;
19780
198
- /*
199
- * Make sure we can fit two framebuffers into video memory.
200
- * This allows up to 1600x1200 with 16 MB (default size).
201
- * If you want more try this:
202
- * 'qemu -vga std -global VGA.vgamem_mb=32 $otherargs'
203
- */
204
- if (size * 2 > bochs->fb_size)
205
- return MODE_BAD;
81
+ if (bochs->edid)
82
+ count = drm_add_edid_modes(connector, bochs->edid);
20683
207
- return MODE_OK;
208
-}
209
-
210
-static struct drm_encoder *
211
-bochs_connector_best_encoder(struct drm_connector *connector)
212
-{
213
- int enc_id = connector->encoder_ids[0];
214
- /* pick the encoder ids */
215
- if (enc_id)
216
- return drm_encoder_find(connector->dev, NULL, enc_id);
217
- return NULL;
84
+ if (!count) {
85
+ count = drm_add_modes_noedid(connector, 8192, 8192);
86
+ drm_set_preferred_mode(connector, defx, defy);
87
+ }
88
+ return count;
21889 }
21990
22091 static const struct drm_connector_helper_funcs bochs_connector_connector_helper_funcs = {
22192 .get_modes = bochs_connector_get_modes,
222
- .mode_valid = bochs_connector_mode_valid,
223
- .best_encoder = bochs_connector_best_encoder,
22493 };
22594
22695 static const struct drm_connector_funcs bochs_connector_connector_funcs = {
227
- .dpms = drm_helper_connector_dpms,
22896 .fill_modes = drm_helper_probe_single_connector_modes,
22997 .destroy = drm_connector_cleanup,
98
+ .reset = drm_atomic_helper_connector_reset,
99
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
100
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
230101 };
231102
232103 static void bochs_connector_init(struct drm_device *dev)
....@@ -238,14 +109,40 @@
238109 DRM_MODE_CONNECTOR_VIRTUAL);
239110 drm_connector_helper_add(connector,
240111 &bochs_connector_connector_helper_funcs);
241
- drm_connector_register(connector);
112
+
113
+ bochs_hw_load_edid(bochs);
114
+ if (bochs->edid) {
115
+ DRM_INFO("Found EDID data blob.\n");
116
+ drm_connector_attach_edid_property(connector);
117
+ drm_connector_update_edid_property(connector, bochs->edid);
118
+ }
242119 }
243120
121
+static struct drm_framebuffer *
122
+bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file,
123
+ const struct drm_mode_fb_cmd2 *mode_cmd)
124
+{
125
+ if (mode_cmd->pixel_format != DRM_FORMAT_XRGB8888 &&
126
+ mode_cmd->pixel_format != DRM_FORMAT_BGRX8888)
127
+ return ERR_PTR(-EINVAL);
128
+
129
+ return drm_gem_fb_create(dev, file, mode_cmd);
130
+}
131
+
132
+const struct drm_mode_config_funcs bochs_mode_funcs = {
133
+ .fb_create = bochs_gem_fb_create,
134
+ .mode_valid = drm_vram_helper_mode_valid,
135
+ .atomic_check = drm_atomic_helper_check,
136
+ .atomic_commit = drm_atomic_helper_commit,
137
+};
244138
245139 int bochs_kms_init(struct bochs_device *bochs)
246140 {
247
- drm_mode_config_init(bochs->dev);
248
- bochs->mode_config_initialized = true;
141
+ int ret;
142
+
143
+ ret = drmm_mode_config_init(bochs->dev);
144
+ if (ret)
145
+ return ret;
249146
250147 bochs->dev->mode_config.max_width = 8192;
251148 bochs->dev->mode_config.max_height = 8192;
....@@ -253,22 +150,22 @@
253150 bochs->dev->mode_config.fb_base = bochs->fb_base;
254151 bochs->dev->mode_config.preferred_depth = 24;
255152 bochs->dev->mode_config.prefer_shadow = 0;
153
+ bochs->dev->mode_config.prefer_shadow_fbdev = 1;
154
+ bochs->dev->mode_config.fbdev_use_iomem = true;
155
+ bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
256156
257157 bochs->dev->mode_config.funcs = &bochs_mode_funcs;
258158
259
- bochs_crtc_init(bochs->dev);
260
- bochs_encoder_init(bochs->dev);
261159 bochs_connector_init(bochs->dev);
262
- drm_connector_attach_encoder(&bochs->connector,
263
- &bochs->encoder);
160
+ drm_simple_display_pipe_init(bochs->dev,
161
+ &bochs->pipe,
162
+ &bochs_pipe_funcs,
163
+ bochs_formats,
164
+ ARRAY_SIZE(bochs_formats),
165
+ NULL,
166
+ &bochs->connector);
167
+
168
+ drm_mode_config_reset(bochs->dev);
264169
265170 return 0;
266
-}
267
-
268
-void bochs_kms_fini(struct bochs_device *bochs)
269
-{
270
- if (bochs->mode_config_initialized) {
271
- drm_mode_config_cleanup(bochs->dev);
272
- bochs->mode_config_initialized = false;
273
- }
274171 }