fc84f535dea0777698f8399d93ffe41e355079f6
[openwrt/staging/adrian.git] /
1 From b721bcc62759ae7a2d9730d1121974702be96d7c 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 1 file changed, 57 insertions(+), 52 deletions(-)
18
19 --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
20 +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
21 @@ -30,6 +30,25 @@
22 #include "vc4_regs.h"
23 #include <soc/bcm2835/raspberrypi-firmware.h>
24
25 +struct fb_alloc_tags {
26 + struct rpi_firmware_property_tag_header tag1;
27 + u32 xres, yres;
28 + struct rpi_firmware_property_tag_header tag2;
29 + u32 xres_virtual, yres_virtual;
30 + struct rpi_firmware_property_tag_header tag3;
31 + u32 bpp;
32 + struct rpi_firmware_property_tag_header tag4;
33 + u32 xoffset, yoffset;
34 + struct rpi_firmware_property_tag_header tag5;
35 + u32 base, screen_size;
36 + struct rpi_firmware_property_tag_header tag6;
37 + u32 pitch;
38 + struct rpi_firmware_property_tag_header tag7;
39 + u32 alpha_mode;
40 + struct rpi_firmware_property_tag_header tag8;
41 + u32 layer;
42 +};
43 +
44 /* The firmware delivers a vblank interrupt to us through the SMI
45 * hardware, which has only this one register.
46 */
47 @@ -123,45 +142,39 @@ static void vc4_primary_plane_atomic_upd
48 struct drm_plane_state *old_state)
49 {
50 struct vc4_dev *vc4 = to_vc4_dev(plane->dev);
51 - struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane);
52 struct drm_plane_state *state = plane->state;
53 struct drm_framebuffer *fb = state->fb;
54 struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
55 - volatile struct fbinfo_s *fbinfo = vc4_plane->fbinfo;
56 + u32 format = fb->format->format;
57 + struct fb_alloc_tags fbinfo = {
58 + .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT,
59 + 8, 0, },
60 + .xres = state->crtc_w,
61 + .yres = state->crtc_h,
62 + .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT,
63 + 8, 0, },
64 + .xres_virtual = state->crtc_w,
65 + .yres_virtual = state->crtc_h,
66 + .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 },
67 + .bpp = 32,
68 + .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 },
69 + .xoffset = 0,
70 + .yoffset = 0,
71 + .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 },
72 + .base = bo->paddr + fb->offsets[0],
73 + .screen_size = state->crtc_w * state->crtc_h * 4,
74 + .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 },
75 + .pitch = fb->pitches[0],
76 + .tag7 = { RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE, 4, 0 },
77 + .alpha_mode = format == DRM_FORMAT_ARGB8888 ? 0 : 2,
78 + .tag8 = { RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER, 4, 0 },
79 + .layer = -127,
80 + };
81 u32 bpp = 32;
82 int ret;
83
84 - fbinfo->xres = state->crtc_w;
85 - fbinfo->yres = state->crtc_h;
86 - fbinfo->xres_virtual = state->crtc_w;
87 - fbinfo->yres_virtual = state->crtc_h;
88 - fbinfo->bpp = bpp;
89 - fbinfo->xoffset = state->crtc_x;
90 - fbinfo->yoffset = state->crtc_y;
91 - fbinfo->base = bo->paddr + fb->offsets[0];
92 - fbinfo->pitch = fb->pitches[0];
93 -
94 if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED)
95 - fbinfo->bpp |= BIT(31);
96 -
97 - /* A bug in the firmware makes it so that if the fb->base is
98 - * set to nonzero, the configured pitch gets overwritten with
99 - * the previous pitch. So, to get the configured pitch
100 - * recomputed, we have to make it allocate itself a new buffer
101 - * in VC memory, first.
102 - */
103 - if (vc4_plane->pitch != fb->pitches[0]) {
104 - u32 saved_base = fbinfo->base;
105 - fbinfo->base = 0;
106 -
107 - ret = rpi_firmware_transaction(vc4->firmware,
108 - RPI_FIRMWARE_CHAN_FB,
109 - vc4_plane->fbinfo_bus_addr);
110 - fbinfo->base = saved_base;
111 -
112 - vc4_plane->pitch = fbinfo->pitch;
113 - WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]);
114 - }
115 + fbinfo.bpp |= BIT(31);
116
117 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%d\n",
118 plane->base.id, plane->name,
119 @@ -170,14 +183,13 @@ static void vc4_primary_plane_atomic_upd
120 bpp,
121 state->crtc_x,
122 state->crtc_y,
123 - &fbinfo->base,
124 + &fbinfo.base,
125 fb->pitches[0]);
126
127 - ret = rpi_firmware_transaction(vc4->firmware,
128 - RPI_FIRMWARE_CHAN_FB,
129 - vc4_plane->fbinfo_bus_addr);
130 - WARN_ON_ONCE(fbinfo->pitch != fb->pitches[0]);
131 - WARN_ON_ONCE(fbinfo->base != bo->paddr + fb->offsets[0]);
132 + ret = rpi_firmware_property_list(vc4->firmware, &fbinfo,
133 + sizeof(fbinfo));
134 + WARN_ON_ONCE(fbinfo.pitch != fb->pitches[0]);
135 + WARN_ON_ONCE(fbinfo.base != bo->paddr + fb->offsets[0]);
136
137 /* If the CRTC is on (or going to be on) and we're enabled,
138 * then unblank. Otherwise, stay blank until CRTC enable.
139 @@ -333,10 +345,10 @@ static const struct drm_plane_helper_fun
140 static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,
141 enum drm_plane_type type)
142 {
143 + /* Primary and cursor planes only */
144 struct drm_plane *plane = NULL;
145 struct vc4_fkms_plane *vc4_plane;
146 - u32 xrgb8888 = DRM_FORMAT_XRGB8888;
147 - u32 argb8888 = DRM_FORMAT_ARGB8888;
148 + u32 formats[] = {DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888};
149 int ret = 0;
150 bool primary = (type == DRM_PLANE_TYPE_PRIMARY);
151 static const uint64_t modifiers[] = {
152 @@ -358,22 +370,15 @@ static struct drm_plane *vc4_fkms_plane_
153 plane = &vc4_plane->base;
154 ret = drm_universal_plane_init(dev, plane, 0xff,
155 &vc4_plane_funcs,
156 - primary ? &xrgb8888 : &argb8888, 1,
157 - modifiers,
158 + formats, primary ? 2 : 1, modifiers,
159 type, primary ? "primary" : "cursor");
160
161 - if (type == DRM_PLANE_TYPE_PRIMARY) {
162 - vc4_plane->fbinfo =
163 - dma_alloc_coherent(dev->dev,
164 - sizeof(*vc4_plane->fbinfo),
165 - &vc4_plane->fbinfo_bus_addr,
166 - GFP_KERNEL);
167 - memset(vc4_plane->fbinfo, 0, sizeof(*vc4_plane->fbinfo));
168 -
169 + if (type == DRM_PLANE_TYPE_PRIMARY)
170 drm_plane_helper_add(plane, &vc4_primary_plane_helper_funcs);
171 - } else {
172 + else
173 drm_plane_helper_add(plane, &vc4_cursor_plane_helper_funcs);
174 - }
175 +
176 + drm_plane_create_alpha_property(plane);
177
178 return plane;
179 fail: