ad729c54aae32fc90ad6240eed8d5a100f176669
[openwrt/staging/luka.git] /
1 From 3819888738de087ba726ceaa2ab20503f164f1ed Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Tue, 26 Mar 2019 14:43:06 +0000
4 Subject: [PATCH] gpu: vc4-fkms: Switch to the newer mailbox frame
5 buffer API.
6
7 The old mailbox FB API was ideally deprecated but still used by
8 the FKMS driver.
9 Update to the newer API.
10
11 NB This needs current firmware that accepts ARM allocated buffers
12 through the newer API.
13
14 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
15 ---
16 drivers/gpu/drm/vc4/vc4_firmware_kms.c | 109 +++++++++++----------
17 include/soc/bcm2835/raspberrypi-firmware.h | 10 ++
18 2 files changed, 67 insertions(+), 52 deletions(-)
19
20 --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
21 +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
22 @@ -28,6 +28,25 @@
23 #include "vc4_regs.h"
24 #include <soc/bcm2835/raspberrypi-firmware.h>
25
26 +struct fb_alloc_tags {
27 + struct rpi_firmware_property_tag_header tag1;
28 + u32 xres, yres;
29 + struct rpi_firmware_property_tag_header tag2;
30 + u32 xres_virtual, yres_virtual;
31 + struct rpi_firmware_property_tag_header tag3;
32 + u32 bpp;
33 + struct rpi_firmware_property_tag_header tag4;
34 + u32 xoffset, yoffset;
35 + struct rpi_firmware_property_tag_header tag5;
36 + u32 base, screen_size;
37 + struct rpi_firmware_property_tag_header tag6;
38 + u32 pitch;
39 + struct rpi_firmware_property_tag_header tag7;
40 + u32 alpha_mode;
41 + struct rpi_firmware_property_tag_header tag8;
42 + u32 layer;
43 +};
44 +
45 /* The firmware delivers a vblank interrupt to us through the SMI
46 * hardware, which has only this one register.
47 */
48 @@ -121,45 +140,39 @@ static void vc4_primary_plane_atomic_upd
49 struct drm_plane_state *old_state)
50 {
51 struct vc4_dev *vc4 = to_vc4_dev(plane->dev);
52 - struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane);
53 struct drm_plane_state *state = plane->state;
54 struct drm_framebuffer *fb = state->fb;
55 struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
56 - volatile struct fbinfo_s *fbinfo = vc4_plane->fbinfo;
57 + u32 format = fb->format->format;
58 + struct fb_alloc_tags fbinfo = {
59 + .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT,
60 + 8, 0, },
61 + .xres = state->crtc_w,
62 + .yres = state->crtc_h,
63 + .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT,
64 + 8, 0, },
65 + .xres_virtual = state->crtc_w,
66 + .yres_virtual = state->crtc_h,
67 + .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 },
68 + .bpp = 32,
69 + .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 },
70 + .xoffset = 0,
71 + .yoffset = 0,
72 + .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 },
73 + .base = bo->paddr + fb->offsets[0],
74 + .screen_size = state->crtc_w * state->crtc_h * 4,
75 + .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 },
76 + .pitch = fb->pitches[0],
77 + .tag7 = { RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE, 4, 0 },
78 + .alpha_mode = format == DRM_FORMAT_ARGB8888 ? 0 : 2,
79 + .tag8 = { RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER, 4, 0 },
80 + .layer = -127,
81 + };
82 u32 bpp = 32;
83 int ret;
84
85 - fbinfo->xres = state->crtc_w;
86 - fbinfo->yres = state->crtc_h;
87 - fbinfo->xres_virtual = state->crtc_w;
88 - fbinfo->yres_virtual = state->crtc_h;
89 - fbinfo->bpp = bpp;
90 - fbinfo->xoffset = state->crtc_x;
91 - fbinfo->yoffset = state->crtc_y;
92 - fbinfo->base = bo->paddr + fb->offsets[0];
93 - fbinfo->pitch = fb->pitches[0];
94 -
95 if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED)
96 - fbinfo->bpp |= BIT(31);
97 -
98 - /* A bug in the firmware makes it so that if the fb->base is
99 - * set to nonzero, the configured pitch gets overwritten with
100 - * the previous pitch. So, to get the configured pitch
101 - * recomputed, we have to make it allocate itself a new buffer
102 - * in VC memory, first.
103 - */
104 - if (vc4_plane->pitch != fb->pitches[0]) {
105 - u32 saved_base = fbinfo->base;
106 - fbinfo->base = 0;
107 -
108 - ret = rpi_firmware_transaction(vc4->firmware,
109 - RPI_FIRMWARE_CHAN_FB,
110 - vc4_plane->fbinfo_bus_addr);
111 - fbinfo->base = saved_base;
112 -
113 - vc4_plane->pitch = fbinfo->pitch;
114 - WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]);
115 - }
116 + fbinfo.bpp |= BIT(31);
117
118 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%d\n",
119 plane->base.id, plane->name,
120 @@ -168,14 +181,13 @@ static void vc4_primary_plane_atomic_upd
121 bpp,
122 state->crtc_x,
123 state->crtc_y,
124 - &fbinfo->base,
125 + &fbinfo.base,
126 fb->pitches[0]);
127
128 - ret = rpi_firmware_transaction(vc4->firmware,
129 - RPI_FIRMWARE_CHAN_FB,
130 - vc4_plane->fbinfo_bus_addr);
131 - WARN_ON_ONCE(fbinfo->pitch != fb->pitches[0]);
132 - WARN_ON_ONCE(fbinfo->base != bo->paddr + fb->offsets[0]);
133 + ret = rpi_firmware_property_list(vc4->firmware, &fbinfo,
134 + sizeof(fbinfo));
135 + WARN_ON_ONCE(fbinfo.pitch != fb->pitches[0]);
136 + WARN_ON_ONCE(fbinfo.base != bo->paddr + fb->offsets[0]);
137
138 /* If the CRTC is on (or going to be on) and we're enabled,
139 * then unblank. Otherwise, stay blank until CRTC enable.
140 @@ -332,10 +344,10 @@ static const struct drm_plane_helper_fun
141 static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,
142 enum drm_plane_type type)
143 {
144 + /* Primary and cursor planes only */
145 struct drm_plane *plane = NULL;
146 struct vc4_fkms_plane *vc4_plane;
147 - u32 xrgb8888 = DRM_FORMAT_XRGB8888;
148 - u32 argb8888 = DRM_FORMAT_ARGB8888;
149 + u32 formats[] = {DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888};
150 int ret = 0;
151 bool primary = (type == DRM_PLANE_TYPE_PRIMARY);
152 static const uint64_t modifiers[] = {
153 @@ -357,22 +369,15 @@ static struct drm_plane *vc4_fkms_plane_
154 plane = &vc4_plane->base;
155 ret = drm_universal_plane_init(dev, plane, 0xff,
156 &vc4_plane_funcs,
157 - primary ? &xrgb8888 : &argb8888, 1,
158 - modifiers,
159 + formats, primary ? 2 : 1, modifiers,
160 type, primary ? "primary" : "cursor");
161
162 - if (type == DRM_PLANE_TYPE_PRIMARY) {
163 - vc4_plane->fbinfo =
164 - dma_alloc_coherent(dev->dev,
165 - sizeof(*vc4_plane->fbinfo),
166 - &vc4_plane->fbinfo_bus_addr,
167 - GFP_KERNEL);
168 - memset(vc4_plane->fbinfo, 0, sizeof(*vc4_plane->fbinfo));
169 -
170 + if (type == DRM_PLANE_TYPE_PRIMARY)
171 drm_plane_helper_add(plane, &vc4_primary_plane_helper_funcs);
172 - } else {
173 + else
174 drm_plane_helper_add(plane, &vc4_cursor_plane_helper_funcs);
175 - }
176 +
177 + drm_plane_create_alpha_property(plane);
178
179 return plane;
180 fail:
181 --- a/include/soc/bcm2835/raspberrypi-firmware.h
182 +++ b/include/soc/bcm2835/raspberrypi-firmware.h
183 @@ -111,9 +111,15 @@ enum rpi_firmware_property_tag {
184 RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009,
185 RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a,
186 RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b,
187 + RPI_FIRMWARE_FRAMEBUFFER_GET_LAYER = 0x0004000c,
188 + RPI_FIRMWARE_FRAMEBUFFER_GET_TRANSFORM = 0x0004000d,
189 + RPI_FIRMWARE_FRAMEBUFFER_GET_VSYNC = 0x0004000e,
190 RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f,
191 RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010,
192 RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001,
193 + RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM = 0x00048013,
194 + RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS = 0x00040013,
195 + RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS = 0x00040014,
196 RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
197 RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004,
198 RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005,
199 @@ -122,6 +128,8 @@ enum rpi_firmware_property_tag {
200 RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009,
201 RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a,
202 RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b,
203 + RPI_FIRMWARE_FRAMEBUFFER_TEST_LAYER = 0x0004400c,
204 + RPI_FIRMWARE_FRAMEBUFFER_TEST_TRANSFORM = 0x0004400d,
205 RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e,
206 RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003,
207 RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004,
208 @@ -134,6 +142,8 @@ enum rpi_firmware_property_tag {
209 RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f,
210 RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020,
211 RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e,
212 + RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER = 0x0004800c,
213 + RPI_FIRMWARE_FRAMEBUFFER_SET_TRANSFORM = 0x0004800d,
214 RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f,
215
216 RPI_FIRMWARE_VCHIQ_INIT = 0x00048010,