summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/mgag200/mgag200_mode.c
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2020-05-15 10:32:33 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2020-05-19 09:41:34 +0200
commit913ec479bb5cc27f99f24d5fd111b3ef29a4deb9 (patch)
tree41927f9c52e618541008fc11014cad65f46e6220 /drivers/gpu/drm/mgag200/mgag200_mode.c
parent88fabb75ea9edf4a3eecf459a50b633bda2fe67f (diff)
drm/mgag200: Replace VRAM helpers with SHMEM helpers
The VRAM helpers managed the framebuffer memory for mgag200. This came with several problems, as some MGA device require the scanout address to be located at VRAM offset 0. It's incompatible with the page-flip semantics of DRM's atomic modesettting. With atomic modesetting, old and new framebuffers have to be located in VRAM at the same time. So at least one of them has to reside at a non-0 offset. This patch replaces VRAM helpers with SHMEM helpers. GEM SHMEM buffers reside in system memory, and are shadow-copied into VRAM during page flips. The shadow copy always starts at VRAM offset 0. v2: * revert dev->pdev changes Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Tested-by: John Donnelly <John.p.donnelly@oracle.com> Acked-by: Emil Velikov <emil.velikov@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200515083233.32036-16-tzimmermann@suse.de
Diffstat (limited to 'drivers/gpu/drm/mgag200/mgag200_mode.c')
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index b50c1beb7b7b..0155d4eb5fa6 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -14,6 +14,8 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_crtc_helper.h>
+#include <drm/drm_damage_helper.h>
+#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_plane_helper.h>
@@ -1574,6 +1576,26 @@ mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
}
static void
+mgag200_handle_damage(struct mga_device *mdev, struct drm_framebuffer *fb,
+ struct drm_rect *clip)
+{
+ struct drm_device *dev = mdev->dev;
+ void *vmap;
+
+ vmap = drm_gem_shmem_vmap(fb->obj[0]);
+ if (drm_WARN_ON(dev, !vmap))
+ return; /* BUG: SHMEM BO should always be vmapped */
+
+ drm_fb_memcpy_dstclip(mdev->vram, vmap, fb, clip);
+
+ drm_gem_shmem_vunmap(fb->obj[0], vmap);
+
+ /* Always scanout image at VRAM offset 0 */
+ mgag200_set_startadd(mdev, (u32)0);
+ mgag200_set_offset(mdev, fb);
+}
+
+static void
mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *crtc_state,
struct drm_plane_state *plane_state)
@@ -1583,14 +1605,12 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
struct mga_device *mdev = to_mga_device(dev);
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
struct drm_framebuffer *fb = plane_state->fb;
- struct drm_gem_vram_object *gbo;
- s64 gpu_addr;
-
- gbo = drm_gem_vram_of_gem(fb->obj[0]);
-
- gpu_addr = drm_gem_vram_offset(gbo);
- if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
- return; /* BUG: BO should have been pinned to VRAM. */
+ struct drm_rect fullscreen = {
+ .x1 = 0,
+ .x2 = fb->width,
+ .y1 = 0,
+ .y2 = fb->height,
+ };
mga_crtc_prepare(crtc);
@@ -1606,6 +1626,8 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
mgag200_g200ev_set_hiprilvl(mdev);
mga_crtc_commit(crtc);
+
+ mgag200_handle_damage(mdev, fb, &fullscreen);
}
static void
@@ -1646,20 +1668,13 @@ mgag200_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
struct mga_device *mdev = to_mga_device(dev);
struct drm_plane_state *state = plane->state;
struct drm_framebuffer *fb = state->fb;
- struct drm_gem_vram_object *gbo;
- s64 gpu_addr;
+ struct drm_rect damage;
if (!fb)
return;
- gbo = drm_gem_vram_of_gem(fb->obj[0]);
-
- gpu_addr = drm_gem_vram_offset(gbo);
- if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
- return; /* BUG: BO should have been pinned to VRAM. */
-
- mgag200_set_startadd(mdev, (unsigned long)gpu_addr);
- mgag200_set_offset(mdev, fb);
+ if (drm_atomic_helper_damage_merged(old_state, state, &damage))
+ mgag200_handle_damage(mdev, fb, &damage);
}
static const struct drm_simple_display_pipe_funcs
@@ -1669,8 +1684,7 @@ mgag200_simple_display_pipe_funcs = {
.disable = mgag200_simple_display_pipe_disable,
.check = mgag200_simple_display_pipe_check,
.update = mgag200_simple_display_pipe_update,
- .prepare_fb = drm_gem_vram_simple_display_pipe_prepare_fb,
- .cleanup_fb = drm_gem_vram_simple_display_pipe_cleanup_fb,
+ .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
};
static const uint32_t mgag200_simple_display_pipe_formats[] = {
@@ -1689,8 +1703,7 @@ static const uint64_t mgag200_simple_display_pipe_fmtmods[] = {
*/
static const struct drm_mode_config_funcs mgag200_mode_config_funcs = {
- .fb_create = drm_gem_fb_create,
- .mode_valid = drm_vram_helper_mode_valid,
+ .fb_create = drm_gem_fb_create_with_dirty,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
@@ -1729,7 +1742,6 @@ int mgag200_modeset_init(struct mga_device *mdev)
dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
dev->mode_config.preferred_depth = mgag200_preferred_depth(mdev);
- dev->mode_config.prefer_shadow = 1;
dev->mode_config.fb_base = mdev->mc.vram_base;