diff options
author | Seung-Woo Kim <sw0312.kim@samsung.com> | 2011-12-15 00:36:22 -0500 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2011-12-28 21:21:42 -0500 |
commit | 229d3534f5bd73fe6247a9e2a92ab0ef69fbc980 (patch) | |
tree | 29adacc9826be07a9628ef7fedeb6dc85ca9db63 /drivers/gpu/drm/exynos/exynos_drm_fb.c | |
parent | 83052d4d5cd518332440bb4ee63d68bb5f744e0f (diff) |
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 @@ | |||
33 | 33 | ||
34 | #include "exynos_drm_drv.h" | 34 | #include "exynos_drm_drv.h" |
35 | #include "exynos_drm_fb.h" | 35 | #include "exynos_drm_fb.h" |
36 | #include "exynos_drm_buf.h" | ||
37 | #include "exynos_drm_gem.h" | 36 | #include "exynos_drm_gem.h" |
38 | 37 | ||
39 | #define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) | 38 | #define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) |
@@ -42,11 +41,11 @@ | |||
42 | * exynos specific framebuffer structure. | 41 | * exynos specific framebuffer structure. |
43 | * | 42 | * |
44 | * @fb: drm framebuffer obejct. | 43 | * @fb: drm framebuffer obejct. |
45 | * @exynos_gem_obj: exynos specific gem object containing a gem object. | 44 | * @exynos_gem_obj: array of exynos specific gem object containing a gem object. |
46 | */ | 45 | */ |
47 | struct exynos_drm_fb { | 46 | struct exynos_drm_fb { |
48 | struct drm_framebuffer fb; | 47 | struct drm_framebuffer fb; |
49 | struct exynos_drm_gem_obj *exynos_gem_obj; | 48 | struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER]; |
50 | }; | 49 | }; |
51 | 50 | ||
52 | static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) | 51 | 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, | |||
70 | DRM_DEBUG_KMS("%s\n", __FILE__); | 69 | DRM_DEBUG_KMS("%s\n", __FILE__); |
71 | 70 | ||
72 | return drm_gem_handle_create(file_priv, | 71 | return drm_gem_handle_create(file_priv, |
73 | &exynos_fb->exynos_gem_obj->base, handle); | 72 | &exynos_fb->exynos_gem_obj[0]->base, handle); |
74 | } | 73 | } |
75 | 74 | ||
76 | static int exynos_drm_fb_dirty(struct drm_framebuffer *fb, | 75 | static int exynos_drm_fb_dirty(struct drm_framebuffer *fb, |
@@ -112,7 +111,7 @@ exynos_drm_framebuffer_init(struct drm_device *dev, | |||
112 | } | 111 | } |
113 | 112 | ||
114 | drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); | 113 | drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); |
115 | exynos_fb->exynos_gem_obj = to_exynos_gem_obj(obj); | 114 | exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj); |
116 | 115 | ||
117 | return &exynos_fb->fb; | 116 | return &exynos_fb->fb; |
118 | } | 117 | } |
@@ -122,6 +121,10 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | |||
122 | struct drm_mode_fb_cmd2 *mode_cmd) | 121 | struct drm_mode_fb_cmd2 *mode_cmd) |
123 | { | 122 | { |
124 | struct drm_gem_object *obj; | 123 | struct drm_gem_object *obj; |
124 | struct drm_framebuffer *fb; | ||
125 | struct exynos_drm_fb *exynos_fb; | ||
126 | int nr; | ||
127 | int i; | ||
125 | 128 | ||
126 | DRM_DEBUG_KMS("%s\n", __FILE__); | 129 | DRM_DEBUG_KMS("%s\n", __FILE__); |
127 | 130 | ||
@@ -133,17 +136,42 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | |||
133 | 136 | ||
134 | drm_gem_object_unreference_unlocked(obj); | 137 | drm_gem_object_unreference_unlocked(obj); |
135 | 138 | ||
136 | return exynos_drm_framebuffer_init(dev, mode_cmd, obj); | 139 | fb = exynos_drm_framebuffer_init(dev, mode_cmd, obj); |
140 | if (IS_ERR(fb)) | ||
141 | return fb; | ||
142 | |||
143 | exynos_fb = to_exynos_fb(fb); | ||
144 | nr = exynos_drm_format_num_buffers(fb->pixel_format); | ||
145 | |||
146 | for (i = 1; i < nr; i++) { | ||
147 | obj = drm_gem_object_lookup(dev, file_priv, | ||
148 | mode_cmd->handles[i]); | ||
149 | if (!obj) { | ||
150 | DRM_ERROR("failed to lookup gem object\n"); | ||
151 | exynos_drm_fb_destroy(fb); | ||
152 | return ERR_PTR(-ENOENT); | ||
153 | } | ||
154 | |||
155 | drm_gem_object_unreference_unlocked(obj); | ||
156 | |||
157 | exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj); | ||
158 | } | ||
159 | |||
160 | return fb; | ||
137 | } | 161 | } |
138 | 162 | ||
139 | struct exynos_drm_gem_buf *exynos_drm_fb_get_buf(struct drm_framebuffer *fb) | 163 | struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, |
164 | int index) | ||
140 | { | 165 | { |
141 | struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); | 166 | struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); |
142 | struct exynos_drm_gem_buf *buffer; | 167 | struct exynos_drm_gem_buf *buffer; |
143 | 168 | ||
144 | DRM_DEBUG_KMS("%s\n", __FILE__); | 169 | DRM_DEBUG_KMS("%s\n", __FILE__); |
145 | 170 | ||
146 | buffer = exynos_fb->exynos_gem_obj->buffer; | 171 | if (index >= MAX_FB_BUFFER) |
172 | return NULL; | ||
173 | |||
174 | buffer = exynos_fb->exynos_gem_obj[index]->buffer; | ||
147 | if (!buffer) | 175 | if (!buffer) |
148 | return NULL; | 176 | return NULL; |
149 | 177 | ||