--- Sascha, this is against your inital patch and I suppose it does not apply cleanly anymore to your current tree, but it shouldn't be to hard to make the changes manually. Can you test whether the generic cma fb helper functions works for you? --- drivers/gpu/drm/imx/Kconfig | 1 + drivers/gpu/drm/imx/Makefile | 2 +- drivers/gpu/drm/imx/imx-drm-core.c | 13 +- drivers/gpu/drm/imx/imx-fb.c | 137 +-------------------- drivers/gpu/drm/imx/imx-fbdev.c | 228 ++--------------------------------- drivers/gpu/drm/imx/imx-lcdc-crtc.c | 10 +- 6 files changed, 24 insertions(+), 367 deletions(-) diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig index 5fc3a44..6b5e3ef 100644 --- a/drivers/gpu/drm/imx/Kconfig +++ b/drivers/gpu/drm/imx/Kconfig @@ -5,6 +5,7 @@ config DRM_IMX config DRM_IMX_FB_HELPER tristate "provide legacy framebuffer /dev/fb0" + select DRM_KMS_CMA_HELPER depends on DRM_IMX config DRM_IMX_LCDC diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile index 0f7c038..6c7dd2d 100644 --- a/drivers/gpu/drm/imx/Makefile +++ b/drivers/gpu/drm/imx/Makefile @@ -1,5 +1,5 @@ -imxdrm-objs := imx-drm-core.o imx-fb.o imx-gem.o +imxdrm-objs := imx-drm-core.o imx-fb.o obj-$(CONFIG_DRM_IMX) += imxdrm.o diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 29f5f10..68cf4da 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -22,6 +22,7 @@ #include <linux/fb.h> #include <asm/fb.h> #include <linux/module.h> +#include <drm/drm_gem_cma_helper.h> #include "imx-drm.h" @@ -149,7 +150,7 @@ static void imx_drm_disable_vblank(struct drm_device *drm, int crtc) } static struct vm_operations_struct imx_drm_gem_vm_ops = { - .fault = imx_drm_gem_fault, + .fault = drm_gem_cma_fault, .open = drm_gem_vm_open, .close = drm_gem_vm_close, }; @@ -159,7 +160,7 @@ static const struct file_operations imx_drm_driver_fops = { .open = drm_open, .release = drm_release, .unlocked_ioctl = drm_ioctl, - .mmap = imx_drm_gem_mmap, + .mmap = drm_gem_cma_mmap, .poll = drm_poll, .fasync = drm_fasync, .read = drm_read, @@ -646,11 +647,11 @@ static struct drm_driver imx_drm_driver = { .unload = imx_drm_driver_unload, .firstopen = imx_drm_driver_firstopen, .lastclose = imx_drm_driver_lastclose, - .gem_free_object = imx_drm_gem_free_object, + .gem_free_object = drm_gem_cma_free_object, .gem_vm_ops = &imx_drm_gem_vm_ops, - .dumb_create = imx_drm_gem_dumb_create, - .dumb_map_offset = imx_drm_gem_dumb_map_offset, - .dumb_destroy = imx_drm_gem_dumb_destroy, + .dumb_create = drm_gem_cma_dumb_create, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, + .dumb_destroy = drm_gem_cma_dumb_destroy, .get_vblank_counter = drm_vblank_count, .enable_vblank = imx_drm_enable_vblank, diff --git a/drivers/gpu/drm/imx/imx-fb.c b/drivers/gpu/drm/imx/imx-fb.c index 5a08c86..dde738b 100644 --- a/drivers/gpu/drm/imx/imx-fb.c +++ b/drivers/gpu/drm/imx/imx-fb.c @@ -21,145 +21,12 @@ #include <drm/drmP.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_fb_cma_helper.h> #include "imx-drm.h" -#define to_imx_drm_fb(x) container_of(x, struct imx_drm_fb, fb) - -/* - * imx specific framebuffer structure. - * - * @fb: drm framebuffer obejct. - * @imx_drm_gem_obj: drm ec specific gem object containing a gem object. - * @entry: pointer to ec drm buffer entry object. - * - containing only the information to physically continuous memory - * region allocated at default framebuffer creation. - */ -struct imx_drm_fb { - struct drm_framebuffer fb; - struct imx_drm_gem_obj *imx_drm_gem_obj; - struct imx_drm_buf_entry *entry; -}; - -static void imx_drm_fb_destroy(struct drm_framebuffer *fb) -{ - struct imx_drm_fb *imx_drm_fb = to_imx_drm_fb(fb); - - drm_framebuffer_cleanup(fb); - - /* - * default framebuffer has no gem object so - * a buffer of the default framebuffer should be released at here. - */ - if (!imx_drm_fb->imx_drm_gem_obj && imx_drm_fb->entry) - imx_drm_buf_destroy(fb->dev, imx_drm_fb->entry); - - kfree(imx_drm_fb); -} - -static int imx_drm_fb_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, unsigned int *handle) -{ - struct imx_drm_fb *imx_drm_fb = to_imx_drm_fb(fb); - - return drm_gem_handle_create(file_priv, - &imx_drm_fb->imx_drm_gem_obj->base, handle); -} - -static struct drm_framebuffer_funcs imx_drm_fb_funcs = { - .destroy = imx_drm_fb_destroy, - .create_handle = imx_drm_fb_create_handle, -}; - -static struct drm_framebuffer *imx_drm_fb_create(struct drm_device *dev, - struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct imx_drm_fb *imx_drm_fb; - struct drm_framebuffer *fb; - struct drm_gem_object *obj; - unsigned int size; - int ret; - u32 bpp, depth; - - drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); - - mode_cmd->pitches[0] = max(mode_cmd->pitches[0], - mode_cmd->width * (bpp >> 3)); - - dev_dbg(dev->dev, "drm fb create(%dx%d)\n", - mode_cmd->width, mode_cmd->height); - - imx_drm_fb = kzalloc(sizeof(*imx_drm_fb), GFP_KERNEL); - if (!imx_drm_fb) { - dev_err(dev->dev, "failed to allocate drm framebuffer.\n"); - return ERR_PTR(-ENOMEM); - } - - fb = &imx_drm_fb->fb; - ret = drm_framebuffer_init(dev, fb, &imx_drm_fb_funcs); - if (ret) { - dev_err(dev->dev, "failed to initialize framebuffer.\n"); - goto err_init; - } - - dev_dbg(dev->dev, "create: fb id: %d\n", fb->base.id); - - size = mode_cmd->pitches[0] * mode_cmd->height; - - /* - * without file_priv we are called from imx_drm_fbdev_create in which - * case we only create a framebuffer without a handle. - */ - if (!file_priv) { - struct imx_drm_buf_entry *entry; - - entry = imx_drm_buf_create(dev, size); - if (IS_ERR(entry)) { - ret = PTR_ERR(entry); - goto err_buffer; - } - - imx_drm_fb->entry = entry; - } else { - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); - if (!obj) { - ret = -EINVAL; - goto err_buffer; - } - - imx_drm_fb->imx_drm_gem_obj = to_imx_drm_gem_obj(obj); - - drm_gem_object_unreference_unlocked(obj); - - imx_drm_fb->entry = imx_drm_fb->imx_drm_gem_obj->entry; - } - - drm_helper_mode_fill_fb_struct(fb, mode_cmd); - - return fb; - -err_buffer: - drm_framebuffer_cleanup(fb); - -err_init: - kfree(imx_drm_fb); - - return ERR_PTR(ret); -} - -struct imx_drm_buf_entry *imx_drm_fb_get_buf(struct drm_framebuffer *fb) -{ - struct imx_drm_fb *imx_drm_fb = to_imx_drm_fb(fb); - struct imx_drm_buf_entry *entry; - - entry = imx_drm_fb->entry; - - return entry; -} -EXPORT_SYMBOL_GPL(imx_drm_fb_get_buf); - static struct drm_mode_config_funcs imx_drm_mode_config_funcs = { - .fb_create = imx_drm_fb_create, + .fb_create = drm_fb_cma_create, }; void imx_drm_mode_config_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/imx/imx-fbdev.c b/drivers/gpu/drm/imx/imx-fbdev.c index f038797..a0e7ccd 100644 --- a/drivers/gpu/drm/imx/imx-fbdev.c +++ b/drivers/gpu/drm/imx/imx-fbdev.c @@ -20,229 +20,14 @@ #include <linux/module.h> #include <drm/drmP.h> #include <drm/drm_crtc.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_crtc_helper.h> +#include <drm/drm_fb_cma_helper.h> #include "imx-drm.h" #define MAX_CONNECTOR 4 #define PREFERRED_BPP 16 -static struct fb_ops imx_drm_fb_ops = { - .owner = THIS_MODULE, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_blank = drm_fb_helper_blank, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_setcmap = drm_fb_helper_setcmap, -}; - -static int imx_drm_fbdev_update(struct drm_fb_helper *helper, - struct drm_framebuffer *fb, - unsigned int fb_width, - unsigned int fb_height) -{ - struct fb_info *fbi = helper->fbdev; - struct drm_device *drm = helper->dev; - struct imx_drm_buf_entry *entry; - unsigned int size = fb_width * fb_height * (fb->bits_per_pixel >> 3); - unsigned long offset; - - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); - drm_fb_helper_fill_var(fbi, helper, fb_width, fb_height); - - entry = imx_drm_fb_get_buf(fb); - if (!entry) { - dev_dbg(drm->dev, "entry is null.\n"); - return -EFAULT; - } - - offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); - offset += fbi->var.yoffset * fb->pitches[0]; - - drm->mode_config.fb_base = entry->paddr; - fbi->screen_base = entry->vaddr + offset; - fbi->fix.smem_start = entry->paddr + offset; - fbi->screen_size = size; - fbi->fix.smem_len = size; - fbi->flags |= FBINFO_CAN_FORCE_OUTPUT; - - return 0; -} - -static int imx_drm_fbdev_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct drm_device *drm = helper->dev; - struct fb_info *fbi; - struct drm_framebuffer *fb; - struct drm_mode_fb_cmd2 mode_cmd = { 0 }; - struct platform_device *pdev = drm->platformdev; - int ret; - - dev_dbg(drm->dev, "surface width(%d), height(%d) and bpp(%d\n", - sizes->surface_width, sizes->surface_height, - sizes->surface_bpp); - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - mutex_lock(&drm->struct_mutex); - - fbi = framebuffer_alloc(0, &pdev->dev); - if (!fbi) { - ret = -ENOMEM; - goto err_fb_alloc; - } - - fb = drm->mode_config.funcs->fb_create(drm, NULL, &mode_cmd); - if (IS_ERR(fb)) { - dev_err(drm->dev, "failed to create drm framebuffer.\n"); - ret = PTR_ERR(fb); - goto err_fb_create; - } - - helper->fb = fb; - helper->fbdev = fbi; - - fbi->par = helper; - fbi->flags = FBINFO_FLAG_DEFAULT; - fbi->fbops = &imx_drm_fb_ops; - - ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) - goto err_alloc_cmap; - - ret = imx_drm_fbdev_update(helper, helper->fb, sizes->fb_width, - sizes->fb_height); - if (ret) - goto err_fbdev_update; - - mutex_unlock(&drm->struct_mutex); - - return 0; - -err_fbdev_update: - fb_dealloc_cmap(&fbi->cmap); - -err_alloc_cmap: - fb->funcs->destroy(fb); - -err_fb_create: - framebuffer_release(fbi); - -err_fb_alloc: - mutex_unlock(&drm->struct_mutex); - - return ret; -} - -static int imx_drm_fbdev_probe(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - int ret; - - BUG_ON(helper->fb); - - ret = imx_drm_fbdev_create(helper, sizes); - if (ret) { - dev_err(helper->dev->dev, "creating fbdev failed with %d\n", ret); - return ret; - } - - /* - * fb_helper expects a value more than 1 if succeed - * because register_framebuffer() should be called. - */ - return 1; -} - -static struct drm_fb_helper_funcs imx_drm_fb_helper_funcs = { - .fb_probe = imx_drm_fbdev_probe, -}; - -static struct drm_fb_helper *imx_drm_fbdev_init(struct drm_device *drm, - int preferred_bpp) -{ - struct drm_fb_helper *helper; - unsigned int num_crtc; - int ret; - - helper = kzalloc(sizeof(*helper), GFP_KERNEL); - if (!helper) - return NULL; - - helper->funcs = &imx_drm_fb_helper_funcs; - - num_crtc = drm->mode_config.num_crtc; - - ret = drm_fb_helper_init(drm, helper, num_crtc, MAX_CONNECTOR); - if (ret) { - dev_err(drm->dev, "initializing drm fb helper failed with %d\n", - ret); - goto err_init; - } - - ret = drm_fb_helper_single_add_all_connectors(helper); - if (ret) { - dev_err(drm->dev, "registering drm_fb_helper_connector failed with %d\n", - ret); - goto err_setup; - - } - - ret = drm_fb_helper_initial_config(helper, preferred_bpp); - if (ret) { - dev_err(drm->dev, "initial config failed with %d\n", ret); - goto err_setup; - } - - return helper; - -err_setup: - drm_fb_helper_fini(helper); - -err_init: - kfree(helper); - - return NULL; -} - -static void imx_drm_fbdev_fini(struct drm_fb_helper *helper) -{ - struct imx_drm_buf_entry *entry; - - if (helper->fbdev) { - struct fb_info *info; - int ret; - - info = helper->fbdev; - ret = unregister_framebuffer(info); - if (ret) - dev_err(helper->dev->dev, "unregister_framebuffer failed with %d\n", - ret); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - entry = imx_drm_fb_get_buf(helper->fb); - - imx_drm_buf_destroy(helper->dev, entry); - - framebuffer_release(info); - } - - drm_fb_helper_fini(helper); - - kfree(helper); -} - -static struct drm_fb_helper *imx_fb_helper; +static struct drm_fbdev_cma *fbdev_cma; static int __init imx_fb_helper_init(void) { @@ -252,10 +37,11 @@ static int __init imx_fb_helper_init(void) if (!drm) return -EINVAL; - imx_fb_helper = imx_drm_fbdev_init(drm, PREFERRED_BPP); - if (!imx_fb_helper) { + fbdev_cma = drm_fbdev_cma_init(drm, PREFERRED_BPP, drm->mode_config.num_crtc, MAX_CONNECTOR); + + if (IS_ERR(fbdev_cma)) { imx_drm_device_put(); - return -EINVAL; + return PTR_ERR(fbdev_cma); } return 0; @@ -263,7 +49,7 @@ static int __init imx_fb_helper_init(void) static void __exit imx_fb_helper_exit(void) { - imx_drm_fbdev_fini(imx_fb_helper); + drm_fbdev_cma_fini(fbdev_cma); imx_drm_device_put(); } diff --git a/drivers/gpu/drm/imx/imx-lcdc-crtc.c b/drivers/gpu/drm/imx/imx-lcdc-crtc.c index e77c015..eb066df 100644 --- a/drivers/gpu/drm/imx/imx-lcdc-crtc.c +++ b/drivers/gpu/drm/imx/imx-lcdc-crtc.c @@ -18,6 +18,8 @@ #include <drm/drmP.h> #include <drm/drm_fb_helper.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_gem_cma_helper.h> +#include <drm/drm_fb_cma_helper.h> #include <linux/fb.h> #include <linux/clk.h> #include <asm/fb.h> @@ -192,15 +194,15 @@ static int imx_drm_crtc_set(struct drm_crtc *crtc, static int imx_drm_set_base(struct drm_crtc *crtc, int x, int y) { struct imx_crtc *imx_crtc = to_imx_crtc(crtc); - struct imx_drm_buf_entry *entry; + struct drm_gem_cma_obj *obj; struct drm_framebuffer *fb = crtc->fb; unsigned long phys; - entry = imx_drm_fb_get_buf(fb); - if (!entry) + obj = drm_fb_cma_get_gem_obj(fb); + if (!obj) return -EFAULT; - phys = entry->paddr; + phys = obj->paddr; phys += x * (fb->bits_per_pixel >> 3); phys += y * fb->pitches[0]; -- 1.7.10 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel