diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fb.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 65 |
1 files changed, 62 insertions, 3 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) { |