qxl: refactor to use drm_fb_helper_fbdev_setup

Lots of code can be removed by relying on fb-helper:
- "struct drm_framebuffer" moves to fb_helper.fb.
- "struct drm_gem_object" moves to fb_helper.obj[0].
- "struct qxl_device" can be inferred as drm_fb_helper is embedded.
- qxl_user_framebuffer_create -> drm_gem_fb_create.
- qxl_user_framebuffer_destroy -> drm_gem_fb_destroy.
- qxl_fbdev_destroy -> drm_fb_helper_fbdev_teardown + vfree(shadow).

Remove unused code:
- qxl_fbdev_qobj_is_fb, qxl_fbdev_set_suspend.
- Unused fields of qxl_fbdev: delayed_ops, delayed_ops_lock, size.

Misc notes:
- The dirty callback is preserved as it is necessary to trigger update
  commands in the hw (the screen stays black otherwise).
- No idea when .create_handle in drm_framebuffer_funcs is used, but use
  the same drm_gem_fb_create_handle to match drm_gem_fb_funcs.
- I don't know why qxl_fb_find_or_create_single used to check for an
  existing framebuffer and removed that check to match other drivers.
- Use of drm_fb_helper_fbdev_teardown also requires "info->fbdefio" to
  be dynamically allocated. Replace the existing defio config by
  drm_fb_helper_defio_init to accomodate this.

Testing results: startx with fbdev, modesetting and qxl all seems to
work. Tested also with CONFIG_DRM_FBDEV_EMULATION=n, fbdev obviously
fails but others are fine. QEMU -spice and QEMU -spice with vdagent and
multiple (resized) displays (via remote-viewer) also works.
unbind vtconsole and rmmod has *not* regressed (i.e. it still trips on a
use-after-free in qxl_check_idle via qxl_ttm_fini).

Ideally setup/teardown is replaced by drm_fbdev_generic_setup as that
would result in further code reduction, improve error handling (like not
leaking shadow memory), but unfortunately QXL has no implementation for
qxl_gem_prime_vmap.

Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Link: http://patchwork.freedesktop.org/patch/msgid/20180910132156.23201-1-peter@lekensteyn.nl
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Peter Wu
2018-09-10 15:21:56 +02:00
committed by Gerd Hoffmann
父節點 33f35429fc
當前提交 bf8744e40c
共有 4 個文件被更改,包括 60 次插入276 次删除

查看文件

@@ -38,6 +38,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_encoder.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem.h>
#include <drm/drmP.h>
#include <drm/ttm/ttm_bo_api.h>
@@ -121,15 +122,9 @@ struct qxl_output {
struct drm_encoder enc;
};
struct qxl_framebuffer {
struct drm_framebuffer base;
struct drm_gem_object *obj;
};
#define to_qxl_crtc(x) container_of(x, struct qxl_crtc, base)
#define drm_connector_to_qxl_output(x) container_of(x, struct qxl_output, base)
#define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, enc)
#define to_qxl_framebuffer(x) container_of(x, struct qxl_framebuffer, base)
struct qxl_mman {
struct ttm_bo_global_ref bo_global_ref;
@@ -138,13 +133,6 @@ struct qxl_mman {
struct ttm_bo_device bdev;
};
struct qxl_mode_info {
bool mode_config_initialized;
/* pointer to fbdev info structure */
struct qxl_fbdev *qfbdev;
};
struct qxl_memslot {
uint8_t generation;
@@ -232,10 +220,9 @@ struct qxl_device {
void *ram;
struct qxl_mman mman;
struct qxl_gem gem;
struct qxl_mode_info mode_info;
struct fb_info *fbdev_info;
struct qxl_framebuffer *fbdev_qfb;
struct drm_fb_helper fb_helper;
void *ram_physical;
struct qxl_ring *release_ring;
@@ -349,19 +336,8 @@ qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo,
int qxl_fbdev_init(struct qxl_device *qdev);
void qxl_fbdev_fini(struct qxl_device *qdev);
int qxl_get_handle_for_primary_fb(struct qxl_device *qdev,
struct drm_file *file_priv,
uint32_t *handle);
void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state);
/* qxl_display.c */
void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb);
int
qxl_framebuffer_init(struct drm_device *dev,
struct qxl_framebuffer *rfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj,
const struct drm_framebuffer_funcs *funcs);
void qxl_display_read_client_monitors_config(struct qxl_device *qdev);
int qxl_create_monitors_object(struct qxl_device *qdev);
int qxl_destroy_monitors_object(struct qxl_device *qdev);
@@ -471,7 +447,7 @@ void qxl_draw_opaque_fb(const struct qxl_fb_image *qxl_fb_image,
int stride /* filled in if 0 */);
void qxl_draw_dirty_fb(struct qxl_device *qdev,
struct qxl_framebuffer *qxl_fb,
struct drm_framebuffer *fb,
struct qxl_bo *bo,
unsigned flags, unsigned color,
struct drm_clip_rect *clips,