Hi
Am 07.11.25 um 21:46 schrieb Ian Forbes:
Sets up VRAM as the scanout buffer then switches to legacy mode.
Suggested-by: Ryosuke Yasuoka <[email protected]>
Signed-off-by: Ian Forbes <[email protected]>
---
v2:
- Set SVGA_REG_CONFIG_DONE=false so that SVGA3 works correctly
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 35 ++++++++++++++++++++++++++++
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 5 ++++
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 2 ++
3 files changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index efdbb67a4966..87448e86d3b3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -20,6 +20,7 @@
#include <drm/drm_rect.h>
#include <drm/drm_sysfs.h>
#include <drm/drm_edid.h>
+#include <drm/drm_panic.h>
void vmw_du_init(struct vmw_display_unit *du)
{
@@ -2025,3 +2026,37 @@ bool vmw_user_object_is_null(struct vmw_user_object *uo)
{
return !uo->buffer && !uo->surface;
}
+
+int
+vmw_get_scanout_buffer(struct drm_plane *plane, struct drm_scanout_buffer *sb)
+{
+ void *vram;
+ struct vmw_private *vmw_priv = container_of(plane->dev, struct
vmw_private, drm);
+
+ // Only call on the primary display
+ if (container_of(plane, struct vmw_display_unit, primary)->unit != 0)
+ return -EINVAL;
+
+ vmw_write(vmw_priv, SVGA_REG_CONFIG_DONE, false);
+
+ vram = memremap(vmw_priv->vram_start, vmw_priv->vram_size,
+ MEMREMAP_WB | MEMREMAP_DEC);
Does that really work? We just had a kernel panic, so remapping might be
difficult.
+ if (!vram)
+ return -ENOMEM;
+
+ sb->map[0].vaddr = vram;
+ sb->format = drm_format_info(DRM_FORMAT_RGB565);
+ sb->width = vmw_priv->initial_width;
+ sb->height = vmw_priv->initial_height;
+ sb->pitch[0] = sb->width * 2;
+ return 0;
+}
+
+void vmw_panic_flush(struct drm_plane *plane)
+{
+ struct vmw_private *vmw_priv = container_of(plane->dev, struct
vmw_private, drm);
+
+ vmw_kms_write_svga(vmw_priv,
+ vmw_priv->initial_width, vmw_priv->initial_height,
+ vmw_priv->initial_width * 2, 16, 16);
+}
I think we should consider adding a callback table for these operations.
There's flush here and the vmap above is another possible candidate.
Best regards
Thomas
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 445471fe9be6..8e37561cd527 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -500,6 +500,11 @@ int vmw_kms_stdu_readback(struct vmw_private *dev_priv,
int vmw_du_helper_plane_update(struct vmw_du_update_plane *update);
+struct drm_scanout_buffer;
+
+int vmw_get_scanout_buffer(struct drm_plane *pl, struct drm_scanout_buffer
*sb);
+void vmw_panic_flush(struct drm_plane *plane);
+
/**
* vmw_du_translate_to_crtc - Translate a rect from framebuffer to crtc
* @state: Plane state.
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index add13294fb7c..faacfef7baa5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -1506,6 +1506,8 @@ drm_plane_helper_funcs
vmw_stdu_primary_plane_helper_funcs = {
.atomic_update = vmw_stdu_primary_plane_atomic_update,
.prepare_fb = vmw_stdu_primary_plane_prepare_fb,
.cleanup_fb = vmw_stdu_primary_plane_cleanup_fb,
+ .get_scanout_buffer = vmw_get_scanout_buffer,
+ .panic_flush = vmw_panic_flush,
};
static const struct drm_crtc_helper_funcs vmw_stdu_crtc_helper_funcs = {
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)