ad729c54aae32fc90ad6240eed8d5a100f176669
[oweals/openwrt.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,