drm/i915: Implement dedicated fbdev I/O helpers

Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the fbdev callbacks. i915 was the only
caller of the DRM helpers, so remove them from the helper module.

i915's fbdev emulation is still incomplete as it doesn't implement
deferred I/O and damage handling for mmaped pages.

v4:
	* generate deferred-I/O helpers
	* use initializer macros for fb_ops
v2:
	* use FB_IO_HELPERS options

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230530151228.22979-14-tzimmermann@suse.de
This commit is contained in:
Thomas Zimmermann 2023-05-30 17:12:28 +02:00 committed by Junxiao Chang
parent 02e05c091b
commit cda92b382e
5 changed files with 9 additions and 155 deletions

View File

@ -133,9 +133,6 @@ config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM_KMS_HELPER
depends on FB=y || FB=DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y

View File

@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagerefli
}
EXPORT_SYMBOL(drm_fb_helper_deferred_io);
/**
* drm_fb_helper_cfb_read - Implements struct &fb_ops.fb_read for I/O memory
* @info: fb_info struct pointer
* @buf: userspace buffer to read from framebuffer memory
* @count: number of bytes to read from framebuffer memory
* @ppos: read offset within framebuffer memory
*
* Returns:
* The number of bytes read on success, or an error code otherwise.
*/
ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos)
{
return fb_io_read(info, buf, count, ppos);
}
EXPORT_SYMBOL(drm_fb_helper_cfb_read);
/**
* drm_fb_helper_cfb_write - Implements struct &fb_ops.fb_write for I/O memory
* @info: fb_info struct pointer
* @buf: userspace buffer to write to framebuffer memory
* @count: number of bytes to write to framebuffer memory
* @ppos: write offset within framebuffer memory
*
* Returns:
* The number of bytes written on success, or an error code otherwise.
*/
ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
{
struct drm_fb_helper *helper = info->par;
loff_t pos = *ppos;
ssize_t ret;
struct drm_rect damage_area;
ret = fb_io_write(info, buf, count, ppos);
if (ret <= 0)
return ret;
if (helper->funcs->fb_dirty) {
drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area);
drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
drm_rect_width(&damage_area),
drm_rect_height(&damage_area));
}
return ret;
}
EXPORT_SYMBOL(drm_fb_helper_cfb_write);
/**
* drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect
* @info: fbdev registered by the helper
* @rect: info about rectangle to fill
*
* A wrapper around cfb_fillrect implemented by fbdev core
*/
void drm_fb_helper_cfb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
struct drm_fb_helper *helper = info->par;
cfb_fillrect(info, rect);
if (helper->funcs->fb_dirty)
drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, rect->height);
}
EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect);
/**
* drm_fb_helper_cfb_copyarea - wrapper around cfb_copyarea
* @info: fbdev registered by the helper
* @area: info about area to copy
*
* A wrapper around cfb_copyarea implemented by fbdev core
*/
void drm_fb_helper_cfb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
struct drm_fb_helper *helper = info->par;
cfb_copyarea(info, area);
if (helper->funcs->fb_dirty)
drm_fb_helper_damage(helper, area->dx, area->dy, area->width, area->height);
}
EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea);
/**
* drm_fb_helper_cfb_imageblit - wrapper around cfb_imageblit
* @info: fbdev registered by the helper
* @image: info about image to blit
*
* A wrapper around cfb_imageblit implemented by fbdev core
*/
void drm_fb_helper_cfb_imageblit(struct fb_info *info,
const struct fb_image *image)
{
struct drm_fb_helper *helper = info->par;
cfb_imageblit(info, image);
if (helper->funcs->fb_dirty)
drm_fb_helper_damage(helper, image->dx, image->dy, image->width, image->height);
}
EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit);
/**
* drm_fb_helper_set_suspend - wrapper around fb_set_suspend
* @fb_helper: driver-allocated fbdev helper, can be NULL

View File

@ -17,6 +17,7 @@ config DRM_I915
select DRM_KMS_HELPER
select DRM_PANEL
select DRM_MIPI_DSI
select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select RELAY
select I2C
select I2C_ALGOBIT

View File

@ -28,6 +28,7 @@
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@ -84,6 +85,10 @@ static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev)
intel_frontbuffer_invalidate(to_frontbuffer(ifbdev), ORIGIN_CPU);
}
FB_GEN_DEFAULT_DEFERRED_IO_OPS(intel_fbdev,
drm_fb_helper_damage_range,
drm_fb_helper_damage_area)
static int intel_fbdev_set_par(struct fb_info *info)
{
struct intel_fbdev *ifbdev = to_intel_fbdev(info->par);
@ -135,15 +140,12 @@ __diag_ignore_all("-Woverride-init", "Allow overriding the default ops");
static const struct fb_ops intelfb_ops = {
.owner = THIS_MODULE,
__FB_DEFAULT_DEFERRED_OPS_RDWR(intel_fbdev),
DRM_FB_HELPER_DEFAULT_OPS,
.fb_set_par = intel_fbdev_set_par,
.fb_read = drm_fb_helper_cfb_read,
.fb_write = drm_fb_helper_cfb_write,
.fb_fillrect = drm_fb_helper_cfb_fillrect,
.fb_copyarea = drm_fb_helper_cfb_copyarea,
.fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_pan_display = intel_fbdev_pan_display,
.fb_blank = intel_fbdev_blank,
.fb_pan_display = intel_fbdev_pan_display,
__FB_DEFAULT_DEFERRED_OPS_DRAW(intel_fbdev),
.fb_mmap = intel_fbdev_mmap,
};

View File

@ -258,18 +258,6 @@ void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u3
void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist);
ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
void drm_fb_helper_cfb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect);
void drm_fb_helper_cfb_copyarea(struct fb_info *info,
const struct fb_copyarea *area);
void drm_fb_helper_cfb_imageblit(struct fb_info *info,
const struct fb_image *image);
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend);
void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
bool suspend);
@ -385,33 +373,6 @@ static inline int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper)
return -ENODEV;
}
static inline ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos)
{
return -ENODEV;
}
static inline ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
{
return -ENODEV;
}
static inline void drm_fb_helper_cfb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
}
static inline void drm_fb_helper_cfb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
}
static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info,
const struct fb_image *image)
{
}
static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
bool suspend)
{