diff mbox

[1/3] drm/tegra: Align FB pitch

Message ID 1400896714-7092-1-git-send-email-marcheu@chromium.org (mailing list archive)
State New, archived
Headers show

Commit Message

Stéphane Marchesin May 24, 2014, 1:58 a.m. UTC
The display controller doesn't handle non-256 byte aligned buffer
pitches. If you give it an unaligned buffer, it will stop after the
first line and will report underflows in the debug registers
(DC_WINBUF_UFLOW_STATUS and friends). So let's make sure that all our
framebuffer pitches are 256-byte aligned.

Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>
---
 drivers/gpu/drm/tegra/drm.h | 2 ++
 drivers/gpu/drm/tegra/fb.c  | 3 ++-
 drivers/gpu/drm/tegra/gem.c | 2 ++
 3 files changed, 6 insertions(+), 1 deletion(-)

Comments

Thierry Reding June 5, 2014, 9:40 a.m. UTC | #1
On Fri, May 23, 2014 at 06:58:32PM -0700, Stéphane Marchesin wrote:
> The display controller doesn't handle non-256 byte aligned buffer
> pitches. If you give it an unaligned buffer, it will stop after the
> first line and will report underflows in the debug registers
> (DC_WINBUF_UFLOW_STATUS and friends). So let's make sure that all our
> framebuffer pitches are 256-byte aligned.
> 
> Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>
> ---
>  drivers/gpu/drm/tegra/drm.h | 2 ++
>  drivers/gpu/drm/tegra/fb.c  | 3 ++-
>  drivers/gpu/drm/tegra/gem.c | 2 ++
>  3 files changed, 6 insertions(+), 1 deletion(-)

Can you point me to where this requirement is documented? I've gone
through the TRM and all I can find is that the line stride needs to be
64 byte aligned. Also I seem to remember that resolutions such as
1366x768 used to work for HDMI at least on earlier Tegra generations.
Perhaps this is a requirement that's new on Tegra124?

Thierry
diff mbox

Patch

diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 126332c..6753598 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -251,6 +251,8 @@  static inline int tegra_output_check_mode(struct tegra_output *output,
 	return output ? -ENOSYS : -EINVAL;
 }
 
+#define DC_PITCH_ALIGNMENT 256
+
 /* from bus.c */
 int drm_host1x_init(struct drm_driver *driver, struct host1x_device *device);
 void drm_host1x_exit(struct drm_driver *driver, struct host1x_device *device);
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index f7fca09..691e83e 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -207,7 +207,8 @@  static int tegra_fbdev_probe(struct drm_fb_helper *helper,
 
 	cmd.width = sizes->surface_width;
 	cmd.height = sizes->surface_height;
-	cmd.pitches[0] = sizes->surface_width * bytes_per_pixel;
+	cmd.pitches[0] = round_up(sizes->surface_width * bytes_per_pixel,
+				  DC_PITCH_ALIGNMENT);
 	cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
 						     sizes->surface_depth);
 
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index bcf9895..9a92a9b 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -16,6 +16,7 @@ 
 #include <linux/dma-buf.h>
 #include <drm/tegra_drm.h>
 
+#include "drm.h"
 #include "gem.h"
 
 static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo)
@@ -260,6 +261,7 @@  int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
 	int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
 	struct tegra_bo *bo;
 
+	min_pitch = round_up(min_pitch, DC_PITCH_ALIGNMENT);
 	if (args->pitch < min_pitch)
 		args->pitch = min_pitch;