aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-07-11 02:29:14 -0400
committerThierry Reding <treding@nvidia.com>2014-08-04 04:07:38 -0400
commitd1f3e1e0b38d49cbb996dcf0fde5b5205d12a23d (patch)
treead6a7bb3489938730f1d7b95e472889880ba7bb4
parent3f4f3b5fede02d338383619ff57744a8415ccceb (diff)
drm/tegra: Properly align stride for framebuffers
Tegra20 and Tegra30 both required the buffer line stride to be aligned on 8 byte boundaries. Tegra114 and Tegra124 increased the alignment to 64 bytes. Introduce a parameter to specify the alignment requirements for each display controller and round up the pitch of newly allocated framebuffers appropriately. Originally-by: Stéphane Marchesin <marcheu@chromium.org> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dc.c19
-rw-r--r--drivers/gpu/drm/tegra/drm.h2
-rw-r--r--drivers/gpu/drm/tegra/fb.c4
-rw-r--r--drivers/gpu/drm/tegra/gem.c3
4 files changed, 27 insertions, 1 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index afcca04f5367..8886907d44b0 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -19,6 +19,7 @@ struct tegra_dc_soc_info {
19 bool supports_interlacing; 19 bool supports_interlacing;
20 bool supports_cursor; 20 bool supports_cursor;
21 bool supports_block_linear; 21 bool supports_block_linear;
22 unsigned int pitch_align;
22}; 23};
23 24
24struct tegra_plane { 25struct tegra_plane {
@@ -1283,12 +1284,20 @@ static int tegra_dc_init(struct host1x_client *client)
1283{ 1284{
1284 struct drm_device *drm = dev_get_drvdata(client->parent); 1285 struct drm_device *drm = dev_get_drvdata(client->parent);
1285 struct tegra_dc *dc = host1x_client_to_dc(client); 1286 struct tegra_dc *dc = host1x_client_to_dc(client);
1287 struct tegra_drm *tegra = drm->dev_private;
1286 int err; 1288 int err;
1287 1289
1288 drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs); 1290 drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs);
1289 drm_mode_crtc_set_gamma_size(&dc->base, 256); 1291 drm_mode_crtc_set_gamma_size(&dc->base, 256);
1290 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); 1292 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
1291 1293
1294 /*
1295 * Keep track of the minimum pitch alignment across all display
1296 * controllers.
1297 */
1298 if (dc->soc->pitch_align > tegra->pitch_align)
1299 tegra->pitch_align = dc->soc->pitch_align;
1300
1292 err = tegra_dc_rgb_init(drm, dc); 1301 err = tegra_dc_rgb_init(drm, dc);
1293 if (err < 0 && err != -ENODEV) { 1302 if (err < 0 && err != -ENODEV) {
1294 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err); 1303 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
@@ -1347,18 +1356,28 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
1347 .supports_interlacing = false, 1356 .supports_interlacing = false,
1348 .supports_cursor = false, 1357 .supports_cursor = false,
1349 .supports_block_linear = false, 1358 .supports_block_linear = false,
1359 .pitch_align = 8,
1350}; 1360};
1351 1361
1352static const struct tegra_dc_soc_info tegra30_dc_soc_info = { 1362static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
1353 .supports_interlacing = false, 1363 .supports_interlacing = false,
1354 .supports_cursor = false, 1364 .supports_cursor = false,
1355 .supports_block_linear = false, 1365 .supports_block_linear = false,
1366 .pitch_align = 8,
1367};
1368
1369static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
1370 .supports_interlacing = false,
1371 .supports_cursor = false,
1372 .supports_block_linear = false,
1373 .pitch_align = 64,
1356}; 1374};
1357 1375
1358static const struct tegra_dc_soc_info tegra124_dc_soc_info = { 1376static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
1359 .supports_interlacing = true, 1377 .supports_interlacing = true,
1360 .supports_cursor = true, 1378 .supports_cursor = true,
1361 .supports_block_linear = true, 1379 .supports_block_linear = true,
1380 .pitch_align = 64,
1362}; 1381};
1363 1382
1364static const struct of_device_id tegra_dc_of_match[] = { 1383static const struct of_device_id tegra_dc_of_match[] = {
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 96d754e7b3eb..e89c70fa82d5 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -45,6 +45,8 @@ struct tegra_drm {
45#ifdef CONFIG_DRM_TEGRA_FBDEV 45#ifdef CONFIG_DRM_TEGRA_FBDEV
46 struct tegra_fbdev *fbdev; 46 struct tegra_fbdev *fbdev;
47#endif 47#endif
48
49 unsigned int pitch_align;
48}; 50};
49 51
50struct tegra_drm_client; 52struct tegra_drm_client;
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 7790d43ad082..3513d12d5aa1 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -194,6 +194,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
194 struct drm_fb_helper_surface_size *sizes) 194 struct drm_fb_helper_surface_size *sizes)
195{ 195{
196 struct tegra_fbdev *fbdev = to_tegra_fbdev(helper); 196 struct tegra_fbdev *fbdev = to_tegra_fbdev(helper);
197 struct tegra_drm *tegra = helper->dev->dev_private;
197 struct drm_device *drm = helper->dev; 198 struct drm_device *drm = helper->dev;
198 struct drm_mode_fb_cmd2 cmd = { 0 }; 199 struct drm_mode_fb_cmd2 cmd = { 0 };
199 unsigned int bytes_per_pixel; 200 unsigned int bytes_per_pixel;
@@ -208,7 +209,8 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
208 209
209 cmd.width = sizes->surface_width; 210 cmd.width = sizes->surface_width;
210 cmd.height = sizes->surface_height; 211 cmd.height = sizes->surface_height;
211 cmd.pitches[0] = sizes->surface_width * bytes_per_pixel; 212 cmd.pitches[0] = round_up(sizes->surface_width * bytes_per_pixel,
213 tegra->pitch_align);
212 cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, 214 cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
213 sizes->surface_depth); 215 sizes->surface_depth);
214 216
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index c1e4e8b6e5ca..2545c7a468a2 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -16,6 +16,7 @@
16#include <linux/dma-buf.h> 16#include <linux/dma-buf.h>
17#include <drm/tegra_drm.h> 17#include <drm/tegra_drm.h>
18 18
19#include "drm.h"
19#include "gem.h" 20#include "gem.h"
20 21
21static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo) 22static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo)
@@ -259,8 +260,10 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
259 struct drm_mode_create_dumb *args) 260 struct drm_mode_create_dumb *args)
260{ 261{
261 int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); 262 int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
263 struct tegra_drm *tegra = drm->dev_private;
262 struct tegra_bo *bo; 264 struct tegra_bo *bo;
263 265
266 min_pitch = round_up(min_pitch, tegra->pitch_align);
264 if (args->pitch < min_pitch) 267 if (args->pitch < min_pitch)
265 args->pitch = min_pitch; 268 args->pitch = min_pitch;
266 269