diff options
author | Seung-Woo Kim <sw0312.kim@samsung.com> | 2011-12-15 14:36:22 +0900 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2011-12-29 11:21:42 +0900 |
commit | 229d3534f5bd73fe6247a9e2a92ab0ef69fbc980 (patch) | |
tree | 29adacc9826be07a9628ef7fedeb6dc85ca9db63 /drivers/gpu/drm/exynos/exynos_drm_fb.c | |
parent | 83052d4d5cd518332440bb4ee63d68bb5f744e0f (diff) | |
download | blackbird-op-linux-229d3534f5bd73fe6247a9e2a92ab0ef69fbc980.tar.gz blackbird-op-linux-229d3534f5bd73fe6247a9e2a92ab0ef69fbc980.zip |
drm/exynos: Support multi buffers
These formats(NV12M, NV12MT and YUV420M) have non contiguous multi
planes, so each plane uses different buffer. The exynos drm should
support multi buffer for them.
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
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>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fb.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 8f36ae5e5d71..3733fe6723d3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -33,7 +33,6 @@ #include "exynos_drm_drv.h" #include "exynos_drm_fb.h" -#include "exynos_drm_buf.h" #include "exynos_drm_gem.h" #define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) @@ -42,11 +41,11 @@ * exynos specific framebuffer structure. * * @fb: drm framebuffer obejct. - * @exynos_gem_obj: exynos specific gem object containing a gem object. + * @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; + struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER]; }; static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) @@ -70,7 +69,7 @@ static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb, DRM_DEBUG_KMS("%s\n", __FILE__); return drm_gem_handle_create(file_priv, - &exynos_fb->exynos_gem_obj->base, handle); + &exynos_fb->exynos_gem_obj[0]->base, handle); } static int exynos_drm_fb_dirty(struct drm_framebuffer *fb, @@ -112,7 +111,7 @@ exynos_drm_framebuffer_init(struct drm_device *dev, } drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); - exynos_fb->exynos_gem_obj = to_exynos_gem_obj(obj); + exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj); return &exynos_fb->fb; } @@ -122,6 +121,10 @@ 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__); @@ -133,17 +136,42 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, drm_gem_object_unreference_unlocked(obj); - return exynos_drm_framebuffer_init(dev, mode_cmd, 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_get_buf(struct drm_framebuffer *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__); - buffer = exynos_fb->exynos_gem_obj->buffer; + if (index >= MAX_FB_BUFFER) + return NULL; + + buffer = exynos_fb->exynos_gem_obj[index]->buffer; if (!buffer) return NULL; |