Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 773af77f authored by Thierry Reding's avatar Thierry Reding Committed by Thierry Reding
Browse files

drm/tegra: Add support for tiled buffer objects



The gr2d and gr3d engines work more efficiently on buffers with a tiled
memory layout. Allow created buffers to be marked as tiled so that the
display controller can scan them out properly.

Signed-off-by: default avatarThierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 5f60ed0d
Loading
Loading
Loading
Loading
+21 −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.tiled = tegra_fb_is_tiled(fb);

	for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
		struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
@@ -157,6 +158,16 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
	tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
	tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH);

	if (tegra_fb_is_tiled(fb)) {
		value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
			DC_WIN_BUFFER_ADDR_MODE_TILE;
	} else {
		value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
			DC_WIN_BUFFER_ADDR_MODE_LINEAR;
	}

	tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);

	value = GENERAL_UPDATE | WIN_A_UPDATE;
	tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);

@@ -509,6 +520,16 @@ int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
	tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
	tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);

	if (window->tiled) {
		value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
			DC_WIN_BUFFER_ADDR_MODE_TILE;
	} else {
		value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
			DC_WIN_BUFFER_ADDR_MODE_LINEAR;
	}

	tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);

	value = WIN_ENABLE;

	if (yuv) {
+4 −0
Original line number Diff line number Diff line
@@ -365,6 +365,10 @@
#define DC_WIN_BUF_STRIDE			0x70b
#define DC_WIN_UV_BUF_STRIDE			0x70c
#define DC_WIN_BUFFER_ADDR_MODE			0x70d
#define DC_WIN_BUFFER_ADDR_MODE_LINEAR		(0 <<  0)
#define DC_WIN_BUFFER_ADDR_MODE_TILE		(1 <<  0)
#define DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV	(0 << 16)
#define DC_WIN_BUFFER_ADDR_MODE_TILE_UV		(1 << 16)
#define DC_WIN_DV_CONTROL			0x70e

#define DC_WIN_BLEND_NOKEY			0x70f
+1 −1
Original line number Diff line number Diff line
@@ -262,7 +262,7 @@ static int tegra_gem_create(struct drm_device *drm, void *data,
	struct drm_tegra_gem_create *args = data;
	struct tegra_bo *bo;

	bo = tegra_bo_create_with_handle(file, drm, args->size,
	bo = tegra_bo_create_with_handle(file, drm, args->size, args->flags,
					 &args->handle);
	if (IS_ERR(bo))
		return PTR_ERR(bo);
+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 tiled;
};

/* from dc.c */
@@ -254,6 +255,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_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);
extern void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
+11 −1
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_tiled(struct drm_framebuffer *framebuffer)
{
	struct tegra_fb *fb = to_tegra_fb(framebuffer);

	if (fb->planes[0]->flags & TEGRA_BO_TILED)
		return true;

	return false;
}

static void tegra_fb_destroy(struct drm_framebuffer *framebuffer)
{
	struct tegra_fb *fb = to_tegra_fb(framebuffer);
@@ -188,7 +198,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,

	size = cmd.pitches[0] * cmd.height;

	bo = tegra_bo_create(drm, size);
	bo = tegra_bo_create(drm, size, 0);
	if (IS_ERR(bo))
		return PTR_ERR(bo);

Loading