forked from Minki/linux
11b7e986da
If rockchip would switch over to the generic fbdev setup we could grabage collect even more of all this code (all of the remaining fb handling code really). v2: Actually use _with_dirty like the patch subject promised (Andrzej) Cc: Andrzej Pietrasiewicz <andrzej.p@collabora.com> Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Cc: Sandy Huang <hjc@rock-chips.com> Cc: "Heiko Stübner" <heiko@sntech.de> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-rockchip@lists.infradead.org Link: https://patchwork.freedesktop.org/patch/msgid/20191127180035.416209-1-daniel.vetter@ffwll.ch
97 lines
2.5 KiB
C
97 lines
2.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
|
|
* Author:Mark Yao <mark.yao@rock-chips.com>
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <drm/drm.h>
|
|
#include <drm/drm_atomic.h>
|
|
#include <drm/drm_damage_helper.h>
|
|
#include <drm/drm_fb_helper.h>
|
|
#include <drm/drm_fourcc.h>
|
|
#include <drm/drm_gem_framebuffer_helper.h>
|
|
#include <drm/drm_probe_helper.h>
|
|
|
|
#include "rockchip_drm_drv.h"
|
|
#include "rockchip_drm_fb.h"
|
|
#include "rockchip_drm_gem.h"
|
|
|
|
static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = {
|
|
.destroy = drm_gem_fb_destroy,
|
|
.create_handle = drm_gem_fb_create_handle,
|
|
.dirty = drm_atomic_helper_dirtyfb,
|
|
};
|
|
|
|
static struct drm_framebuffer *
|
|
rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd,
|
|
struct drm_gem_object **obj, unsigned int num_planes)
|
|
{
|
|
struct drm_framebuffer *fb;
|
|
int ret;
|
|
int i;
|
|
|
|
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
|
|
if (!fb)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
|
|
|
|
for (i = 0; i < num_planes; i++)
|
|
fb->obj[i] = obj[i];
|
|
|
|
ret = drm_framebuffer_init(dev, fb, &rockchip_drm_fb_funcs);
|
|
if (ret) {
|
|
DRM_DEV_ERROR(dev->dev,
|
|
"Failed to initialize framebuffer: %d\n",
|
|
ret);
|
|
kfree(fb);
|
|
return ERR_PTR(ret);
|
|
}
|
|
|
|
return fb;
|
|
}
|
|
|
|
static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
|
|
.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
|
|
};
|
|
|
|
static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
|
|
.fb_create = drm_gem_fb_create_with_dirty,
|
|
.output_poll_changed = drm_fb_helper_output_poll_changed,
|
|
.atomic_check = drm_atomic_helper_check,
|
|
.atomic_commit = drm_atomic_helper_commit,
|
|
};
|
|
|
|
struct drm_framebuffer *
|
|
rockchip_drm_framebuffer_init(struct drm_device *dev,
|
|
const struct drm_mode_fb_cmd2 *mode_cmd,
|
|
struct drm_gem_object *obj)
|
|
{
|
|
struct drm_framebuffer *fb;
|
|
|
|
fb = rockchip_fb_alloc(dev, mode_cmd, &obj, 1);
|
|
if (IS_ERR(fb))
|
|
return ERR_CAST(fb);
|
|
|
|
return fb;
|
|
}
|
|
|
|
void rockchip_drm_mode_config_init(struct drm_device *dev)
|
|
{
|
|
dev->mode_config.min_width = 0;
|
|
dev->mode_config.min_height = 0;
|
|
|
|
/*
|
|
* set max width and height as default value(4096x4096).
|
|
* this value would be used to check framebuffer size limitation
|
|
* at drm_mode_addfb().
|
|
*/
|
|
dev->mode_config.max_width = 4096;
|
|
dev->mode_config.max_height = 4096;
|
|
|
|
dev->mode_config.funcs = &rockchip_drm_mode_config_funcs;
|
|
dev->mode_config.helper_private = &rockchip_mode_config_helpers;
|
|
}
|