diff options
author | Inki Dae <inki.dae@samsung.com> | 2012-08-20 07:05:56 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2012-10-03 21:06:00 -0400 |
commit | 01ed812671c1163b35bf6ce9be221bd371bf9a8f (patch) | |
tree | f79d48db7a6ae3cda29beedb9a827e7ea45ba87f | |
parent | 3d05859fd78bbc0b04cca929aea494f5e6b8235b (diff) |
drm/exynos: check NV12M format specific to Exynos properly
this patch adds buf_cnt variable in exynos_drm_fb structure and
that means a buffer count to drm framebuffer and also adds two
functions to get/set the buffer count from/to exynos_drm_fb structure.
if pixel format is not DRM_FORMAT_NV12MT then it gets a buffer count
to drm framebuffer refering to mode_cmd->handles and offsets.
but when booted, the buffer count will always be 1 because pixel
format of console framebuffer is RGB format.
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 65 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.h | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 |
4 files changed, 73 insertions, 17 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 4ccfe4328fab..98f8b839673a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -41,10 +41,12 @@ | |||
41 | * exynos specific framebuffer structure. | 41 | * exynos specific framebuffer structure. |
42 | * | 42 | * |
43 | * @fb: drm framebuffer obejct. | 43 | * @fb: drm framebuffer obejct. |
44 | * @buf_cnt: a buffer count to drm framebuffer. | ||
44 | * @exynos_gem_obj: array of exynos specific gem object containing a gem object. | 45 | * @exynos_gem_obj: array of exynos specific gem object containing a gem object. |
45 | */ | 46 | */ |
46 | struct exynos_drm_fb { | 47 | struct exynos_drm_fb { |
47 | struct drm_framebuffer fb; | 48 | struct drm_framebuffer fb; |
49 | unsigned int buf_cnt; | ||
48 | struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER]; | 50 | struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER]; |
49 | }; | 51 | }; |
50 | 52 | ||
@@ -101,6 +103,25 @@ static struct drm_framebuffer_funcs exynos_drm_fb_funcs = { | |||
101 | .dirty = exynos_drm_fb_dirty, | 103 | .dirty = exynos_drm_fb_dirty, |
102 | }; | 104 | }; |
103 | 105 | ||
106 | void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb, | ||
107 | unsigned int cnt) | ||
108 | { | ||
109 | struct exynos_drm_fb *exynos_fb; | ||
110 | |||
111 | exynos_fb = to_exynos_fb(fb); | ||
112 | |||
113 | exynos_fb->buf_cnt = cnt; | ||
114 | } | ||
115 | |||
116 | unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb) | ||
117 | { | ||
118 | struct exynos_drm_fb *exynos_fb; | ||
119 | |||
120 | exynos_fb = to_exynos_fb(fb); | ||
121 | |||
122 | return exynos_fb->buf_cnt; | ||
123 | } | ||
124 | |||
104 | struct drm_framebuffer * | 125 | struct drm_framebuffer * |
105 | exynos_drm_framebuffer_init(struct drm_device *dev, | 126 | exynos_drm_framebuffer_init(struct drm_device *dev, |
106 | struct drm_mode_fb_cmd2 *mode_cmd, | 127 | struct drm_mode_fb_cmd2 *mode_cmd, |
@@ -127,6 +148,43 @@ exynos_drm_framebuffer_init(struct drm_device *dev, | |||
127 | return &exynos_fb->fb; | 148 | return &exynos_fb->fb; |
128 | } | 149 | } |
129 | 150 | ||
151 | static u32 exynos_drm_format_num_buffers(struct drm_mode_fb_cmd2 *mode_cmd) | ||
152 | { | ||
153 | unsigned int cnt = 0; | ||
154 | |||
155 | if (mode_cmd->pixel_format != DRM_FORMAT_NV12) | ||
156 | return drm_format_num_planes(mode_cmd->pixel_format); | ||
157 | |||
158 | while (cnt != MAX_FB_BUFFER) { | ||
159 | if (!mode_cmd->handles[cnt]) | ||
160 | break; | ||
161 | cnt++; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * check if NV12 or NV12M. | ||
166 | * | ||
167 | * NV12 | ||
168 | * handles[0] = base1, offsets[0] = 0 | ||
169 | * handles[1] = base1, offsets[1] = Y_size | ||
170 | * | ||
171 | * NV12M | ||
172 | * handles[0] = base1, offsets[0] = 0 | ||
173 | * handles[1] = base2, offsets[1] = 0 | ||
174 | */ | ||
175 | if (cnt == 2) { | ||
176 | /* | ||
177 | * in case of NV12 format, offsets[1] is not 0 and | ||
178 | * handles[0] is same as handles[1]. | ||
179 | */ | ||
180 | if (mode_cmd->offsets[1] && | ||
181 | mode_cmd->handles[0] == mode_cmd->handles[1]) | ||
182 | cnt = 1; | ||
183 | } | ||
184 | |||
185 | return cnt; | ||
186 | } | ||
187 | |||
130 | static struct drm_framebuffer * | 188 | static struct drm_framebuffer * |
131 | exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | 189 | exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, |
132 | struct drm_mode_fb_cmd2 *mode_cmd) | 190 | struct drm_mode_fb_cmd2 *mode_cmd) |
@@ -134,7 +192,6 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | |||
134 | struct drm_gem_object *obj; | 192 | struct drm_gem_object *obj; |
135 | struct drm_framebuffer *fb; | 193 | struct drm_framebuffer *fb; |
136 | struct exynos_drm_fb *exynos_fb; | 194 | struct exynos_drm_fb *exynos_fb; |
137 | int nr; | ||
138 | int i; | 195 | int i; |
139 | 196 | ||
140 | DRM_DEBUG_KMS("%s\n", __FILE__); | 197 | DRM_DEBUG_KMS("%s\n", __FILE__); |
@@ -152,9 +209,11 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | |||
152 | } | 209 | } |
153 | 210 | ||
154 | exynos_fb = to_exynos_fb(fb); | 211 | exynos_fb = to_exynos_fb(fb); |
155 | nr = exynos_drm_format_num_buffers(fb->pixel_format); | 212 | exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd); |
213 | |||
214 | DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt); | ||
156 | 215 | ||
157 | for (i = 1; i < nr; i++) { | 216 | for (i = 1; i < exynos_fb->buf_cnt; i++) { |
158 | obj = drm_gem_object_lookup(dev, file_priv, | 217 | obj = drm_gem_object_lookup(dev, file_priv, |
159 | mode_cmd->handles[i]); | 218 | mode_cmd->handles[i]); |
160 | if (!obj) { | 219 | if (!obj) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h b/drivers/gpu/drm/exynos/exynos_drm_fb.h index 50823756cdea..96262e54f76d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.h +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h | |||
@@ -28,19 +28,6 @@ | |||
28 | #ifndef _EXYNOS_DRM_FB_H_ | 28 | #ifndef _EXYNOS_DRM_FB_H_ |
29 | #define _EXYNOS_DRM_FB_H | 29 | #define _EXYNOS_DRM_FB_H |
30 | 30 | ||
31 | static inline int exynos_drm_format_num_buffers(uint32_t format) | ||
32 | { | ||
33 | switch (format) { | ||
34 | case DRM_FORMAT_NV12: | ||
35 | case DRM_FORMAT_NV12MT: | ||
36 | return 2; | ||
37 | case DRM_FORMAT_YUV420: | ||
38 | return 3; | ||
39 | default: | ||
40 | return 1; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | struct drm_framebuffer * | 31 | struct drm_framebuffer * |
45 | exynos_drm_framebuffer_init(struct drm_device *dev, | 32 | exynos_drm_framebuffer_init(struct drm_device *dev, |
46 | struct drm_mode_fb_cmd2 *mode_cmd, | 33 | struct drm_mode_fb_cmd2 *mode_cmd, |
@@ -52,4 +39,11 @@ struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, | |||
52 | 39 | ||
53 | void exynos_drm_mode_config_init(struct drm_device *dev); | 40 | void exynos_drm_mode_config_init(struct drm_device *dev); |
54 | 41 | ||
42 | /* set a buffer count to drm framebuffer. */ | ||
43 | void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb, | ||
44 | unsigned int cnt); | ||
45 | |||
46 | /* get a buffer count to drm framebuffer. */ | ||
47 | unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb); | ||
48 | |||
55 | #endif | 49 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index f4ac43356583..d7205f8b2301 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
@@ -79,6 +79,9 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, | |||
79 | return -EFAULT; | 79 | return -EFAULT; |
80 | } | 80 | } |
81 | 81 | ||
82 | /* buffer count to framebuffer always is 1 at booting time. */ | ||
83 | exynos_drm_fb_set_buf_cnt(fb, 1); | ||
84 | |||
82 | offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); | 85 | offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); |
83 | offset += fbi->var.yoffset * fb->pitches[0]; | 86 | offset += fbi->var.yoffset * fb->pitches[0]; |
84 | 87 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index e1f94b746bd7..8c3036dd512b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -47,7 +47,7 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, | |||
47 | 47 | ||
48 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 48 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
49 | 49 | ||
50 | nr = exynos_drm_format_num_buffers(fb->pixel_format); | 50 | nr = exynos_drm_fb_get_buf_cnt(fb); |
51 | for (i = 0; i < nr; i++) { | 51 | for (i = 0; i < nr; i++) { |
52 | struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i); | 52 | struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i); |
53 | 53 | ||