summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos/exynos_drm_fb.c
diff options
context:
space:
mode:
authorSeung-Woo Kim <sw0312.kim@samsung.com>2011-12-15 14:36:22 +0900
committerInki Dae <inki.dae@samsung.com>2011-12-29 11:21:42 +0900
commit229d3534f5bd73fe6247a9e2a92ab0ef69fbc980 (patch)
tree29adacc9826be07a9628ef7fedeb6dc85ca9db63 /drivers/gpu/drm/exynos/exynos_drm_fb.c
parent83052d4d5cd518332440bb4ee63d68bb5f744e0f (diff)
downloadlinux-3.10-229d3534f5bd73fe6247a9e2a92ab0ef69fbc980.tar.gz
linux-3.10-229d3534f5bd73fe6247a9e2a92ab0ef69fbc980.tar.bz2
linux-3.10-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.c44
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 8f36ae5e5d7..3733fe6723d 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;