2019-09-19 14:43:19 +00:00
|
|
|
From 3819888738de087ba726ceaa2ab20503f164f1ed Mon Sep 17 00:00:00 2001
|
2019-07-09 18:32:28 +00:00
|
|
|
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
|
|
|
Date: Tue, 26 Mar 2019 14:43:06 +0000
|
2019-12-23 12:42:55 +00:00
|
|
|
Subject: [PATCH] gpu: vc4-fkms: Switch to the newer mailbox frame
|
2019-07-09 18:32:28 +00:00
|
|
|
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,
|