forked from Minki/linux
drm/tegra: Support bottom-up buffer objects
The gr3d engine renders images bottom-up. Allow buffers that are used for 3D content to be marked as such and implement support in the display controller to present them properly. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
773af77fc4
commit
db7fbdfd25
@ -47,6 +47,7 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
window.dst.h = crtc_h;
|
||||
window.format = tegra_dc_format(fb->pixel_format);
|
||||
window.bits_per_pixel = fb->bits_per_pixel;
|
||||
window.bottom_up = tegra_fb_is_bottom_up(fb);
|
||||
window.tiled = tegra_fb_is_tiled(fb);
|
||||
|
||||
for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
|
||||
@ -147,6 +148,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
|
||||
{
|
||||
unsigned int format = tegra_dc_format(fb->pixel_format);
|
||||
struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
|
||||
unsigned int h_offset = 0, v_offset = 0;
|
||||
unsigned long value;
|
||||
|
||||
tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
|
||||
@ -168,6 +170,22 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
|
||||
|
||||
tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
|
||||
|
||||
/* make sure bottom-up buffers are properly displayed */
|
||||
if (tegra_fb_is_bottom_up(fb)) {
|
||||
value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
|
||||
value |= INVERT_V;
|
||||
tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
|
||||
|
||||
v_offset += fb->height - 1;
|
||||
} else {
|
||||
value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
|
||||
value &= ~INVERT_V;
|
||||
tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
|
||||
}
|
||||
|
||||
tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
|
||||
tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
|
||||
|
||||
value = GENERAL_UPDATE | WIN_A_UPDATE;
|
||||
tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
|
||||
|
||||
@ -517,6 +535,9 @@ int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
|
||||
tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE);
|
||||
}
|
||||
|
||||
if (window->bottom_up)
|
||||
v_offset += window->src.h - 1;
|
||||
|
||||
tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
|
||||
tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
|
||||
|
||||
@ -548,6 +569,9 @@ int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
|
||||
value |= COLOR_EXPAND;
|
||||
}
|
||||
|
||||
if (window->bottom_up)
|
||||
value |= INVERT_V;
|
||||
|
||||
tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
|
||||
|
||||
/*
|
||||
|
@ -302,6 +302,7 @@
|
||||
#define DC_WIN_CSC_KVB 0x618
|
||||
|
||||
#define DC_WIN_WIN_OPTIONS 0x700
|
||||
#define INVERT_V (1 << 2)
|
||||
#define COLOR_EXPAND (1 << 6)
|
||||
#define CSC_ENABLE (1 << 18)
|
||||
#define WIN_ENABLE (1 << 30)
|
||||
|
@ -148,6 +148,7 @@ struct tegra_dc_window {
|
||||
unsigned int format;
|
||||
unsigned int stride[2];
|
||||
unsigned long base[3];
|
||||
bool bottom_up;
|
||||
bool tiled;
|
||||
};
|
||||
|
||||
@ -255,6 +256,7 @@ extern int tegra_output_exit(struct tegra_output *output);
|
||||
/* from fb.c */
|
||||
struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
|
||||
unsigned int index);
|
||||
bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer);
|
||||
bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer);
|
||||
extern int tegra_drm_fb_init(struct drm_device *drm);
|
||||
extern void tegra_drm_fb_exit(struct drm_device *drm);
|
||||
|
@ -34,6 +34,16 @@ struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
|
||||
return fb->planes[index];
|
||||
}
|
||||
|
||||
bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer)
|
||||
{
|
||||
struct tegra_fb *fb = to_tegra_fb(framebuffer);
|
||||
|
||||
if (fb->planes[0]->flags & TEGRA_BO_BOTTOM_UP)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer)
|
||||
{
|
||||
struct tegra_fb *fb = to_tegra_fb(framebuffer);
|
||||
|
@ -132,6 +132,9 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
|
||||
if (flags & DRM_TEGRA_GEM_CREATE_TILED)
|
||||
bo->flags |= TEGRA_BO_TILED;
|
||||
|
||||
if (flags & DRM_TEGRA_GEM_CREATE_BOTTOM_UP)
|
||||
bo->flags |= TEGRA_BO_BOTTOM_UP;
|
||||
|
||||
return bo;
|
||||
|
||||
err_mmap:
|
||||
|
@ -24,7 +24,8 @@
|
||||
#include <drm/drm.h>
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#define TEGRA_BO_TILED (1 << 0)
|
||||
#define TEGRA_BO_TILED (1 << 0)
|
||||
#define TEGRA_BO_BOTTOM_UP (1 << 1)
|
||||
|
||||
struct tegra_bo {
|
||||
struct drm_gem_object gem;
|
||||
|
@ -19,7 +19,8 @@
|
||||
|
||||
#include <drm/drm.h>
|
||||
|
||||
#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0)
|
||||
#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0)
|
||||
#define DRM_TEGRA_GEM_CREATE_BOTTOM_UP (1 << 1)
|
||||
|
||||
struct drm_tegra_gem_create {
|
||||
__u64 size;
|
||||
|
Loading…
Reference in New Issue
Block a user