aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_fb.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2014-09-03 15:25:54 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2015-03-24 07:33:25 -0400
commitf36eb5a899d3ea57e3d167427260848e116e27a0 (patch)
treef92b2050b1fc2b8341dec645071e34efa5faea1e /drivers/gpu/drm/omapdrm/omap_fb.c
parent3f4d17c4eca9769d56218a38dbfc482794fbde2f (diff)
drm/omap: add pin refcounting to omap_framebuffer
omap_framebuffer_pin() and omap_framebuffer_unpin() are currently broken, as they cannot be called multiple times (i.e. pin, pin, unpin, unpin), which is what happens in certain cases. This issue causes the driver to possibly use 0 as an address for a displayed buffer, leading to OCP error from DSS. This patch fixes the issue by adding a simple pin_count, used to track the number of pins. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_fb.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fb.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 45dd9eed9c57..d1e5f6da30d4 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -86,6 +86,7 @@ struct plane {
86 86
87struct omap_framebuffer { 87struct omap_framebuffer {
88 struct drm_framebuffer base; 88 struct drm_framebuffer base;
89 int pin_count;
89 const struct format *format; 90 const struct format *format;
90 struct plane planes[4]; 91 struct plane planes[4];
91}; 92};
@@ -249,6 +250,11 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
249 struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); 250 struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
250 int ret, i, n = drm_format_num_planes(fb->pixel_format); 251 int ret, i, n = drm_format_num_planes(fb->pixel_format);
251 252
253 if (omap_fb->pin_count > 0) {
254 omap_fb->pin_count++;
255 return 0;
256 }
257
252 for (i = 0; i < n; i++) { 258 for (i = 0; i < n; i++) {
253 struct plane *plane = &omap_fb->planes[i]; 259 struct plane *plane = &omap_fb->planes[i];
254 ret = omap_gem_get_paddr(plane->bo, &plane->paddr, true); 260 ret = omap_gem_get_paddr(plane->bo, &plane->paddr, true);
@@ -257,6 +263,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
257 omap_gem_dma_sync(plane->bo, DMA_TO_DEVICE); 263 omap_gem_dma_sync(plane->bo, DMA_TO_DEVICE);
258 } 264 }
259 265
266 omap_fb->pin_count++;
267
260 return 0; 268 return 0;
261 269
262fail: 270fail:
@@ -275,6 +283,11 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
275 struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); 283 struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
276 int ret, i, n = drm_format_num_planes(fb->pixel_format); 284 int ret, i, n = drm_format_num_planes(fb->pixel_format);
277 285
286 omap_fb->pin_count--;
287
288 if (omap_fb->pin_count > 0)
289 return 0;
290
278 for (i = 0; i < n; i++) { 291 for (i = 0; i < n; i++) {
279 struct plane *plane = &omap_fb->planes[i]; 292 struct plane *plane = &omap_fb->planes[i];
280 ret = omap_gem_put_paddr(plane->bo); 293 ret = omap_gem_put_paddr(plane->bo);