diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-03-27 11:32:29 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-03-27 11:32:29 -0300 |
commit | 50953e0640b3473dcb409d5d0d938c2742c93b0d (patch) | |
tree | 3b0dc374e61564fbbd8adff92c8fae16fdeb423a /drivers/staging/omapdrm/omap_fb.c | |
parent | f92c97c8bd77992ff8bd6ef29a23dc82dca799cb (diff) | |
parent | 626cf236608505d376e4799adb4f7eb00a8594af (diff) | |
download | op-kernel-dev-50953e0640b3473dcb409d5d0d938c2742c93b0d.zip op-kernel-dev-50953e0640b3473dcb409d5d0d938c2742c93b0d.tar.gz |
Merge branch 'poll' into staging/for_v3.4
* poll: (5970 commits)
poll: add poll_requested_events() and poll_does_not_wait() functions
crc32: select an algorithm via Kconfig
crc32: add self-test code for crc32c
crypto: crc32c should use library implementation
crc32: bolt on crc32c
crc32: add note about this patchset to crc32.c
crc32: optimize loop counter for x86
crc32: add slice-by-8 algorithm to existing code
crc32: make CRC_*_BITS definition correspond to actual bit counts
crc32: fix mixing of endian-specific types
crc32: miscellaneous cleanups
crc32: simplify unit test code
crc32: move long comment about crc32 fundamentals to Documentation/
crc32: remove two instances of trailing whitespaces
checkpatch: check for quoted strings broken across lines
checkpatch: whitespace - add/remove blank lines
checkpatch: warn on use of yield()
checkpatch: add --strict tests for braces, comments and casts
checkpatch: add [] to type extensions
checkpatch: high precedence operators do not require additional parentheses in #defines
...
Diffstat (limited to 'drivers/staging/omapdrm/omap_fb.c')
-rw-r--r-- | drivers/staging/omapdrm/omap_fb.c | 124 |
1 files changed, 85 insertions, 39 deletions
diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c index d021a7e..04b235b 100644 --- a/drivers/staging/omapdrm/omap_fb.c +++ b/drivers/staging/omapdrm/omap_fb.c @@ -59,6 +59,20 @@ static const struct format formats[] = { { OMAP_DSS_COLOR_UYVY, DRM_FORMAT_UYVY, {{2, 1}}, true }, }; +/* convert from overlay's pixel formats bitmask to an array of fourcc's */ +uint32_t omap_framebuffer_get_formats(uint32_t *pixel_formats, + uint32_t max_formats, enum omap_color_mode supported_modes) +{ + uint32_t nformats = 0; + int i = 0; + + for (i = 0; i < ARRAY_SIZE(formats) && nformats < max_formats; i++) + if (formats[i].dss_format & supported_modes) + pixel_formats[nformats++] = formats[i].pixel_format; + + return nformats; +} + /* per-plane info for the fb: */ struct plane { struct drm_gem_object *bo; @@ -87,7 +101,7 @@ static int omap_framebuffer_create_handle(struct drm_framebuffer *fb, static void omap_framebuffer_destroy(struct drm_framebuffer *fb) { struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); - int i, n = drm_format_num_planes(omap_fb->format->pixel_format); + int i, n = drm_format_num_planes(fb->pixel_format); DBG("destroy: FB ID: %d (%p)", fb->base.id, fb); @@ -123,41 +137,6 @@ static const struct drm_framebuffer_funcs omap_framebuffer_funcs = { .dirty = omap_framebuffer_dirty, }; -/* pins buffer in preparation for scanout */ -int omap_framebuffer_pin(struct drm_framebuffer *fb) -{ - struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); - int ret, i, n = drm_format_num_planes(omap_fb->format->pixel_format); - - for (i = 0; i < n; i++) { - struct plane *plane = &omap_fb->planes[i]; - ret = omap_gem_get_paddr(plane->bo, &plane->paddr, true); - if (ret) - goto fail; - } - - return 0; - -fail: - while (--i > 0) { - struct plane *plane = &omap_fb->planes[i]; - omap_gem_put_paddr(plane->bo); - } - return ret; -} - -/* releases buffer when done with scanout */ -void omap_framebuffer_unpin(struct drm_framebuffer *fb) -{ - struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); - int i, n = drm_format_num_planes(omap_fb->format->pixel_format); - - for (i = 0; i < n; i++) { - struct plane *plane = &omap_fb->planes[i]; - omap_gem_put_paddr(plane->bo); - } -} - /* update ovl info for scanout, handles cases of multi-planar fb's, etc. */ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y, @@ -187,10 +166,59 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y, } } +/* Call for unpin 'a' (if not NULL), and pin 'b' (if not NULL). Although + * buffers to unpin are just just pushed to the unpin fifo so that the + * caller can defer unpin until vblank. + * + * Note if this fails (ie. something went very wrong!), all buffers are + * unpinned, and the caller disables the overlay. We could have tried + * to revert back to the previous set of pinned buffers but if things are + * hosed there is no guarantee that would succeed. + */ +int omap_framebuffer_replace(struct drm_framebuffer *a, + struct drm_framebuffer *b, void *arg, + void (*unpin)(void *arg, struct drm_gem_object *bo)) +{ + int ret = 0, i, na, nb; + struct omap_framebuffer *ofba = to_omap_framebuffer(a); + struct omap_framebuffer *ofbb = to_omap_framebuffer(b); + + na = a ? drm_format_num_planes(a->pixel_format) : 0; + nb = b ? drm_format_num_planes(b->pixel_format) : 0; + + for (i = 0; i < max(na, nb); i++) { + struct plane *pa, *pb; + + pa = (i < na) ? &ofba->planes[i] : NULL; + pb = (i < nb) ? &ofbb->planes[i] : NULL; + + if (pa) { + unpin(arg, pa->bo); + pa->paddr = 0; + } + + if (pb && !ret) + ret = omap_gem_get_paddr(pb->bo, &pb->paddr, true); + } + + if (ret) { + /* something went wrong.. unpin what has been pinned */ + for (i = 0; i < nb; i++) { + struct plane *pb = &ofba->planes[i]; + if (pb->paddr) { + unpin(arg, pb->bo); + pb->paddr = 0; + } + } + } + + return ret; +} + struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p) { struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); - if (p >= drm_format_num_planes(omap_fb->format->pixel_format)) + if (p >= drm_format_num_planes(fb->pixel_format)) return NULL; return omap_fb->planes[p].bo; } @@ -249,6 +277,24 @@ void omap_framebuffer_flush(struct drm_framebuffer *fb, } } +#ifdef CONFIG_DEBUG_FS +void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m) +{ + struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); + int i, n = drm_format_num_planes(fb->pixel_format); + + seq_printf(m, "fb: %dx%d@%4.4s\n", fb->width, fb->height, + (char *)&fb->pixel_format); + + for (i = 0; i < n; i++) { + struct plane *plane = &omap_fb->planes[i]; + seq_printf(m, " %d: offset=%d pitch=%d, obj: ", + i, plane->offset, plane->pitch); + omap_gem_describe(plane->bo, m); + } +} +#endif + struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev, struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd) { @@ -337,8 +383,8 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, plane->bo = bos[i]; plane->offset = mode_cmd->offsets[i]; - plane->pitch = mode_cmd->pitches[i]; - plane->paddr = pitch; + plane->pitch = pitch; + plane->paddr = 0; } drm_helper_mode_fill_fb_struct(fb, mode_cmd); |