forked from Minki/linux
132a5b915f
The exynos drm driver has several subdrv. They each can be module but it causes unfixed probe order of exynodr drm driver and each subdrv. It also needs some weird codes such as exynos_drm_fbdev_reinit and exynos_drm_mode_group_reinit. This patch can remove weird codes and clear codes through we doesn't modularity each subdrv. Also this removes unnecessary codes related module. Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
214 lines
5.7 KiB
C
214 lines
5.7 KiB
C
/* exynos_drm_fb.c
|
|
*
|
|
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
|
|
* Authors:
|
|
* Inki Dae <inki.dae@samsung.com>
|
|
* Joonyoung Shim <jy0922.shim@samsung.com>
|
|
* Seung-Woo Kim <sw0312.kim@samsung.com>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include "drmP.h"
|
|
#include "drm_crtc.h"
|
|
#include "drm_crtc_helper.h"
|
|
#include "drm_fb_helper.h"
|
|
|
|
#include "exynos_drm_drv.h"
|
|
#include "exynos_drm_fb.h"
|
|
#include "exynos_drm_gem.h"
|
|
|
|
#define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb)
|
|
|
|
/*
|
|
* exynos specific framebuffer structure.
|
|
*
|
|
* @fb: drm framebuffer obejct.
|
|
* @exynos_gem_obj: array of exynos specific gem object containing a gem object.
|
|
*/
|
|
struct exynos_drm_fb {
|
|
struct drm_framebuffer fb;
|
|
struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER];
|
|
};
|
|
|
|
static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
|
|
{
|
|
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
|
|
|
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
|
|
|
drm_framebuffer_cleanup(fb);
|
|
|
|
kfree(exynos_fb);
|
|
exynos_fb = NULL;
|
|
}
|
|
|
|
static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
|
|
struct drm_file *file_priv,
|
|
unsigned int *handle)
|
|
{
|
|
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
|
|
|
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
|
|
|
return drm_gem_handle_create(file_priv,
|
|
&exynos_fb->exynos_gem_obj[0]->base, handle);
|
|
}
|
|
|
|
static int exynos_drm_fb_dirty(struct drm_framebuffer *fb,
|
|
struct drm_file *file_priv, unsigned flags,
|
|
unsigned color, struct drm_clip_rect *clips,
|
|
unsigned num_clips)
|
|
{
|
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
|
|
|
/* TODO */
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
|
|
.destroy = exynos_drm_fb_destroy,
|
|
.create_handle = exynos_drm_fb_create_handle,
|
|
.dirty = exynos_drm_fb_dirty,
|
|
};
|
|
|
|
struct drm_framebuffer *
|
|
exynos_drm_framebuffer_init(struct drm_device *dev,
|
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
|
struct drm_gem_object *obj)
|
|
{
|
|
struct exynos_drm_fb *exynos_fb;
|
|
int ret;
|
|
|
|
exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
|
|
if (!exynos_fb) {
|
|
DRM_ERROR("failed to allocate exynos drm framebuffer\n");
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
|
|
ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs);
|
|
if (ret) {
|
|
DRM_ERROR("failed to initialize framebuffer\n");
|
|
return ERR_PTR(ret);
|
|
}
|
|
|
|
drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
|
|
exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj);
|
|
|
|
return &exynos_fb->fb;
|
|
}
|
|
|
|
static struct drm_framebuffer *
|
|
exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
|
|
struct drm_mode_fb_cmd2 *mode_cmd)
|
|
{
|
|
struct drm_gem_object *obj;
|
|
struct drm_framebuffer *fb;
|
|
struct exynos_drm_fb *exynos_fb;
|
|
int nr;
|
|
int i;
|
|
|
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
|
|
|
obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
|
|
if (!obj) {
|
|
DRM_ERROR("failed to lookup gem object\n");
|
|
return ERR_PTR(-ENOENT);
|
|
}
|
|
|
|
drm_gem_object_unreference_unlocked(obj);
|
|
|
|
fb = exynos_drm_framebuffer_init(dev, mode_cmd, obj);
|
|
if (IS_ERR(fb))
|
|
return fb;
|
|
|
|
exynos_fb = to_exynos_fb(fb);
|
|
nr = exynos_drm_format_num_buffers(fb->pixel_format);
|
|
|
|
for (i = 1; i < nr; i++) {
|
|
obj = drm_gem_object_lookup(dev, file_priv,
|
|
mode_cmd->handles[i]);
|
|
if (!obj) {
|
|
DRM_ERROR("failed to lookup gem object\n");
|
|
exynos_drm_fb_destroy(fb);
|
|
return ERR_PTR(-ENOENT);
|
|
}
|
|
|
|
drm_gem_object_unreference_unlocked(obj);
|
|
|
|
exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj);
|
|
}
|
|
|
|
return fb;
|
|
}
|
|
|
|
struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb,
|
|
int index)
|
|
{
|
|
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
|
|
struct exynos_drm_gem_buf *buffer;
|
|
|
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
|
|
|
if (index >= MAX_FB_BUFFER)
|
|
return NULL;
|
|
|
|
buffer = exynos_fb->exynos_gem_obj[index]->buffer;
|
|
if (!buffer)
|
|
return NULL;
|
|
|
|
DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n",
|
|
(unsigned long)buffer->kvaddr,
|
|
(unsigned long)buffer->dma_addr);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
static void exynos_drm_output_poll_changed(struct drm_device *dev)
|
|
{
|
|
struct exynos_drm_private *private = dev->dev_private;
|
|
struct drm_fb_helper *fb_helper = private->fb_helper;
|
|
|
|
if (fb_helper)
|
|
drm_fb_helper_hotplug_event(fb_helper);
|
|
}
|
|
|
|
static struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
|
|
.fb_create = exynos_user_fb_create,
|
|
.output_poll_changed = exynos_drm_output_poll_changed,
|
|
};
|
|
|
|
void exynos_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 = &exynos_drm_mode_config_funcs;
|
|
}
|