fc84f535dea0777698f8399d93ffe41e355079f6
[oweals/openwrt.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: