Commit db7fbdfd authored by Thierry Reding's avatar Thierry Reding Committed by Thierry Reding
Browse files

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: default avatarThierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 773af77f
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -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);

	/*
+1 −0
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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);
+10 −0
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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:
Loading