brcm2708: update to latest patches from RPi foundation
[openwrt/staging/chunkeey.git] / target / linux / brcm2708 / patches-4.19 / 950-0517-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0517-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch b/target/linux/brcm2708/patches-4.19/950-0517-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch
new file mode 100644 (file)
index 0000000..ad729c5
--- /dev/null
@@ -0,0 +1,216 @@
+From 3819888738de087ba726ceaa2ab20503f164f1ed Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Tue, 26 Mar 2019 14:43:06 +0000
+Subject: [PATCH] gpu: vc4-fkms: Switch to the newer mailbox frame
+ buffer API.
+
+The old mailbox FB API was ideally deprecated but still used by
+the FKMS driver.
+Update to the newer API.
+
+NB This needs current firmware that accepts ARM allocated buffers
+through the newer API.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c     | 109 +++++++++++----------
+ include/soc/bcm2835/raspberrypi-firmware.h |  10 ++
+ 2 files changed, 67 insertions(+), 52 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -28,6 +28,25 @@
+ #include "vc4_regs.h"
+ #include <soc/bcm2835/raspberrypi-firmware.h>
++struct fb_alloc_tags {
++      struct rpi_firmware_property_tag_header tag1;
++      u32 xres, yres;
++      struct rpi_firmware_property_tag_header tag2;
++      u32 xres_virtual, yres_virtual;
++      struct rpi_firmware_property_tag_header tag3;
++      u32 bpp;
++      struct rpi_firmware_property_tag_header tag4;
++      u32 xoffset, yoffset;
++      struct rpi_firmware_property_tag_header tag5;
++      u32 base, screen_size;
++      struct rpi_firmware_property_tag_header tag6;
++      u32 pitch;
++      struct rpi_firmware_property_tag_header tag7;
++      u32 alpha_mode;
++      struct rpi_firmware_property_tag_header tag8;
++      u32 layer;
++};
++
+ /* The firmware delivers a vblank interrupt to us through the SMI
+  * hardware, which has only this one register.
+  */
+@@ -121,45 +140,39 @@ static void vc4_primary_plane_atomic_upd
+                                           struct drm_plane_state *old_state)
+ {
+       struct vc4_dev *vc4 = to_vc4_dev(plane->dev);
+-      struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane);
+       struct drm_plane_state *state = plane->state;
+       struct drm_framebuffer *fb = state->fb;
+       struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+-      volatile struct fbinfo_s *fbinfo = vc4_plane->fbinfo;
++      u32 format = fb->format->format;
++      struct fb_alloc_tags fbinfo = {
++              .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT,
++                        8, 0, },
++                      .xres = state->crtc_w,
++                      .yres = state->crtc_h,
++              .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT,
++                        8, 0, },
++                      .xres_virtual = state->crtc_w,
++                      .yres_virtual = state->crtc_h,
++              .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 },
++                      .bpp = 32,
++              .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 },
++                      .xoffset = 0,
++                      .yoffset = 0,
++              .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 },
++                      .base = bo->paddr + fb->offsets[0],
++                      .screen_size = state->crtc_w * state->crtc_h * 4,
++              .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 },
++                      .pitch = fb->pitches[0],
++              .tag7 = { RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE, 4, 0 },
++                      .alpha_mode = format == DRM_FORMAT_ARGB8888 ? 0 : 2,
++              .tag8 = { RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER, 4, 0 },
++                      .layer = -127,
++      };
+       u32 bpp = 32;
+       int ret;
+-      fbinfo->xres = state->crtc_w;
+-      fbinfo->yres = state->crtc_h;
+-      fbinfo->xres_virtual = state->crtc_w;
+-      fbinfo->yres_virtual = state->crtc_h;
+-      fbinfo->bpp = bpp;
+-      fbinfo->xoffset = state->crtc_x;
+-      fbinfo->yoffset = state->crtc_y;
+-      fbinfo->base = bo->paddr + fb->offsets[0];
+-      fbinfo->pitch = fb->pitches[0];
+-
+       if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED)
+-              fbinfo->bpp |= BIT(31);
+-
+-      /* A bug in the firmware makes it so that if the fb->base is
+-       * set to nonzero, the configured pitch gets overwritten with
+-       * the previous pitch.  So, to get the configured pitch
+-       * recomputed, we have to make it allocate itself a new buffer
+-       * in VC memory, first.
+-       */
+-      if (vc4_plane->pitch != fb->pitches[0]) {
+-              u32 saved_base = fbinfo->base;
+-              fbinfo->base = 0;
+-
+-              ret = rpi_firmware_transaction(vc4->firmware,
+-                                             RPI_FIRMWARE_CHAN_FB,
+-                                             vc4_plane->fbinfo_bus_addr);
+-              fbinfo->base = saved_base;
+-
+-              vc4_plane->pitch = fbinfo->pitch;
+-              WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]);
+-      }
++              fbinfo.bpp |= BIT(31);
+       DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%d\n",
+                        plane->base.id, plane->name,
+@@ -168,14 +181,13 @@ static void vc4_primary_plane_atomic_upd
+                        bpp,
+                        state->crtc_x,
+                        state->crtc_y,
+-                       &fbinfo->base,
++                       &fbinfo.base,
+                        fb->pitches[0]);
+-      ret = rpi_firmware_transaction(vc4->firmware,
+-                                     RPI_FIRMWARE_CHAN_FB,
+-                                     vc4_plane->fbinfo_bus_addr);
+-      WARN_ON_ONCE(fbinfo->pitch != fb->pitches[0]);
+-      WARN_ON_ONCE(fbinfo->base != bo->paddr + fb->offsets[0]);
++      ret = rpi_firmware_property_list(vc4->firmware, &fbinfo,
++                                       sizeof(fbinfo));
++      WARN_ON_ONCE(fbinfo.pitch != fb->pitches[0]);
++      WARN_ON_ONCE(fbinfo.base != bo->paddr + fb->offsets[0]);
+       /* If the CRTC is on (or going to be on) and we're enabled,
+        * then unblank.  Otherwise, stay blank until CRTC enable.
+@@ -332,10 +344,10 @@ static const struct drm_plane_helper_fun
+ static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,
+                                            enum drm_plane_type type)
+ {
++      /* Primary and cursor planes only */
+       struct drm_plane *plane = NULL;
+       struct vc4_fkms_plane *vc4_plane;
+-      u32 xrgb8888 = DRM_FORMAT_XRGB8888;
+-      u32 argb8888 = DRM_FORMAT_ARGB8888;
++      u32 formats[] = {DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888};
+       int ret = 0;
+       bool primary = (type == DRM_PLANE_TYPE_PRIMARY);
+       static const uint64_t modifiers[] = {
+@@ -357,22 +369,15 @@ static struct drm_plane *vc4_fkms_plane_
+       plane = &vc4_plane->base;
+       ret = drm_universal_plane_init(dev, plane, 0xff,
+                                      &vc4_plane_funcs,
+-                                     primary ? &xrgb8888 : &argb8888, 1,
+-                                     modifiers,
++                                     formats, primary ? 2 : 1, modifiers,
+                                      type, primary ? "primary" : "cursor");
+-      if (type == DRM_PLANE_TYPE_PRIMARY) {
+-              vc4_plane->fbinfo =
+-                      dma_alloc_coherent(dev->dev,
+-                                         sizeof(*vc4_plane->fbinfo),
+-                                         &vc4_plane->fbinfo_bus_addr,
+-                                         GFP_KERNEL);
+-              memset(vc4_plane->fbinfo, 0, sizeof(*vc4_plane->fbinfo));
+-
++      if (type == DRM_PLANE_TYPE_PRIMARY)
+               drm_plane_helper_add(plane, &vc4_primary_plane_helper_funcs);
+-      } else {
++      else
+               drm_plane_helper_add(plane, &vc4_cursor_plane_helper_funcs);
+-      }
++
++      drm_plane_create_alpha_property(plane);
+       return plane;
+ fail:
+--- a/include/soc/bcm2835/raspberrypi-firmware.h
++++ b/include/soc/bcm2835/raspberrypi-firmware.h
+@@ -111,9 +111,15 @@ enum rpi_firmware_property_tag {
+       RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET =         0x00040009,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN =               0x0004000a,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE =                0x0004000b,
++      RPI_FIRMWARE_FRAMEBUFFER_GET_LAYER =                  0x0004000c,
++      RPI_FIRMWARE_FRAMEBUFFER_GET_TRANSFORM =              0x0004000d,
++      RPI_FIRMWARE_FRAMEBUFFER_GET_VSYNC =                  0x0004000e,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF =               0x0004000f,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF =            0x00040010,
+       RPI_FIRMWARE_FRAMEBUFFER_RELEASE =                    0x00048001,
++      RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM =            0x00048013,
++      RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS =           0x00040013,
++      RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS =       0x00040014,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT =  0x00044004,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH =                 0x00044005,
+@@ -122,6 +128,8 @@ enum rpi_firmware_property_tag {
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET =        0x00044009,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN =              0x0004400a,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE =               0x0004400b,
++      RPI_FIRMWARE_FRAMEBUFFER_TEST_LAYER =                 0x0004400c,
++      RPI_FIRMWARE_FRAMEBUFFER_TEST_TRANSFORM =             0x0004400d,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC =                 0x0004400e,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT =  0x00048003,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT =   0x00048004,
+@@ -134,6 +142,8 @@ enum rpi_firmware_property_tag {
+       RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF =               0x0004801f,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF =            0x00048020,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC =                  0x0004800e,
++      RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER =                  0x0004800c,
++      RPI_FIRMWARE_FRAMEBUFFER_SET_TRANSFORM =              0x0004800d,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT =              0x0004800f,
+       RPI_FIRMWARE_VCHIQ_INIT =                             0x00048010,