mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-20 14:13:16 +00:00
f07e572f64
bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G bcm2710: boot tested on RPi 3B v1.2 bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
180 lines
6.1 KiB
Diff
180 lines
6.1 KiB
Diff
From b721bcc62759ae7a2d9730d1121974702be96d7c 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 +++++++++++++------------
|
|
1 file changed, 57 insertions(+), 52 deletions(-)
|
|
|
|
--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
|
|
+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
|
|
@@ -30,6 +30,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.
|
|
*/
|
|
@@ -123,45 +142,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,
|
|
@@ -170,14 +183,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.
|
|
@@ -333,10 +345,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[] = {
|
|
@@ -358,22 +370,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:
|