linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1] drm/tegra: Correct timeout in tegra_syncpt_wait
@ 2017-12-17 17:25 Dmitry Osipenko
  2017-12-17 17:25 ` [PATCH v1] drm/tegra: gem: Correct iommu_map_sg() error checking Dmitry Osipenko
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Dmitry Osipenko @ 2017-12-17 17:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: dri-devel, linux-tegra, linux-kernel

host1x_syncpt_wait() takes timeout value in jiffies, but DRM passes it in
milliseconds.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/drm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index bb98336fa8d7..57396388341b 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -629,7 +629,8 @@ static int tegra_syncpt_wait(struct drm_device *drm, void *data,
 	if (!sp)
 		return -EINVAL;
 
-	return host1x_syncpt_wait(sp, args->thresh, args->timeout,
+	return host1x_syncpt_wait(sp, args->thresh,
+				  msecs_to_jiffies(args->timeout),
 				  &args->value);
 }
 
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v1] drm/tegra: gem: Correct iommu_map_sg() error checking
  2017-12-17 17:25 [PATCH v1] drm/tegra: Correct timeout in tegra_syncpt_wait Dmitry Osipenko
@ 2017-12-17 17:25 ` Dmitry Osipenko
  2017-12-20  6:19   ` kbuild test robot
  2017-12-17 17:25 ` [PATCH v1] drm/tegra: Restore opaque formats on Tegra20/30 Dmitry Osipenko
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Dmitry Osipenko @ 2017-12-17 17:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: dri-devel, linux-tegra, linux-kernel

iommu_map_sg() doesn't return a error value, but a size of the requested
IOMMU mapping or zero in case of error.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/gem.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index ab1e53d434e8..710d3c289b2e 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -114,7 +114,7 @@ static const struct host1x_bo_ops tegra_bo_ops = {
 static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
 {
 	int prot = IOMMU_READ | IOMMU_WRITE;
-	ssize_t err;
+	int err;
 
 	if (bo->mm)
 		return -EBUSY;
@@ -135,15 +135,14 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
 
 	bo->paddr = bo->mm->start;
 
-	err = iommu_map_sg(tegra->domain, bo->paddr, bo->sgt->sgl,
-			   bo->sgt->nents, prot);
-	if (err < 0) {
-		dev_err(tegra->drm->dev, "failed to map buffer: %zd\n", err);
+	bo->size = iommu_map_sg(tegra->domain, bo->paddr, bo->sgt->sgl,
+				bo->sgt->nents, prot);
+	if (!bo->size) {
+		dev_err(tegra->drm->dev, "failed to map buffer\n");
+		err = -ENOMEM;
 		goto remove;
 	}
 
-	bo->size = err;
-
 	mutex_unlock(&tegra->mm_lock);
 
 	return 0;
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v1] drm/tegra: Restore opaque formats on Tegra20/30
  2017-12-17 17:25 [PATCH v1] drm/tegra: Correct timeout in tegra_syncpt_wait Dmitry Osipenko
  2017-12-17 17:25 ` [PATCH v1] drm/tegra: gem: Correct iommu_map_sg() error checking Dmitry Osipenko
@ 2017-12-17 17:25 ` Dmitry Osipenko
  2017-12-17 17:25 ` [PATCH v1] drm/tegra: Trade overlay plane for cursor on older Tegra's Dmitry Osipenko
  2017-12-17 17:25 ` [PATCH v2] drm/tegra: dc: Link DC1 to DC0 on Tegra20 Dmitry Osipenko
  3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Osipenko @ 2017-12-17 17:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: dri-devel, linux-tegra, linux-kernel

Commit 7772fdaef939 ("drm/tegra: Support ARGB and ABGR formats") broke
DRM's MODE_ADDFB IOCTL on Tegra20/30, because it uses XRGBA format if
requested FB depth is 24bpp. As a result, Xorg doesn't work anymore with
both modesetting and opentegra drivers. On all Tegra's each plane has a
blending configuration which should be used to enable / disable alpha
blending and right now the blending configs are hardcoded with alpha
blending being disabled. In order to support alpha formats properly,
planes blending configuration must be adjusted, until then the alpha
formats are equal to non-alpha.

Fixes: 7772fdaef939 ("drm/tegra: Support ARGB and ABGR formats")
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/dc.c    | 19 ++++++++++++++++++-
 drivers/gpu/drm/tegra/dc.h    |  1 +
 drivers/gpu/drm/tegra/fb.c    | 13 -------------
 drivers/gpu/drm/tegra/hub.c   |  3 ++-
 drivers/gpu/drm/tegra/plane.c | 22 +++++++++++++++++-----
 drivers/gpu/drm/tegra/plane.h |  2 +-
 6 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index be84c36ad81f..7e58143f4145 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -305,6 +305,11 @@ static const u32 tegra20_primary_formats[] = {
 	DRM_FORMAT_RGBA5551,
 	DRM_FORMAT_ABGR8888,
 	DRM_FORMAT_ARGB8888,
+	/* non-native formats */
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_RGBX5551,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
 };
 
 static const u32 tegra114_primary_formats[] = {
@@ -369,7 +374,8 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 
 	err = tegra_plane_format(state->fb->format->format,
 				 &plane_state->format,
-				 &plane_state->swap);
+				 &plane_state->swap,
+				 dc->soc->supports_opaque_formats);
 	if (err < 0)
 		return err;
 
@@ -698,6 +704,11 @@ static const u32 tegra20_overlay_formats[] = {
 	DRM_FORMAT_RGBA5551,
 	DRM_FORMAT_ABGR8888,
 	DRM_FORMAT_ARGB8888,
+	/* non-native formats */
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_RGBX5551,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
 	/* planar formats */
 	DRM_FORMAT_UYVY,
 	DRM_FORMAT_YUYV,
@@ -1848,6 +1859,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
 	.primary_formats = tegra20_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats),
 	.overlay_formats = tegra20_overlay_formats,
+	.supports_opaque_formats = false,
 };
 
 static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
@@ -1863,6 +1875,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
 	.primary_formats = tegra20_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats),
 	.overlay_formats = tegra20_overlay_formats,
+	.supports_opaque_formats = false,
 };
 
 static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
@@ -1878,6 +1891,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
 	.primary_formats = tegra114_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats),
 	.overlay_formats = tegra114_overlay_formats,
+	.supports_opaque_formats = true,
 };
 
 static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
@@ -1893,6 +1907,7 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
 	.primary_formats = tegra114_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats),
 	.overlay_formats = tegra114_overlay_formats,
+	.supports_opaque_formats = true,
 };
 
 static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
@@ -1908,6 +1923,7 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
 	.primary_formats = tegra114_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats),
 	.overlay_formats = tegra114_overlay_formats,
+	.supports_opaque_formats = true,
 };
 
 static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = {
@@ -1955,6 +1971,7 @@ static const struct tegra_dc_soc_info tegra186_dc_soc_info = {
 	.has_nvdisplay = true,
 	.wgrps = tegra186_dc_wgrps,
 	.num_wgrps = ARRAY_SIZE(tegra186_dc_wgrps),
+	.supports_opaque_formats = true,
 };
 
 static const struct of_device_id tegra_dc_of_match[] = {
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 8098f49c0d96..3a66a1127ee7 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -65,6 +65,7 @@ struct tegra_dc_soc_info {
 	unsigned int num_primary_formats;
 	const u32 *overlay_formats;
 	unsigned int num_overlay_formats;
+	bool supports_opaque_formats;
 };
 
 struct tegra_dc {
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 5f6289c4e56a..bd8c9da1ed0d 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -253,19 +253,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
 	cmd.height = sizes->surface_height;
 	cmd.pitches[0] = round_up(sizes->surface_width * bytes_per_pixel,
 				  tegra->pitch_align);
-
-	/*
-	 * Early generations of Tegra (Tegra20 and Tegra30) do not support any
-	 * of the X* or *X formats, only their A* or *A equivalents. Force the
-	 * legacy framebuffer format to include an alpha component so that the
-	 * framebuffer emulation can be supported on all generations.
-	 */
-	if (sizes->surface_bpp == 32 && sizes->surface_depth == 24)
-		sizes->surface_depth = 32;
-
-	if (sizes->surface_bpp == 16 && sizes->surface_depth == 15)
-		sizes->surface_depth = 16;
-
 	cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
 						     sizes->surface_depth);
 
diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
index cccd44711d68..68c31fd7fd91 100644
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -332,7 +332,8 @@ static int tegra_shared_plane_atomic_check(struct drm_plane *plane,
 
 	err = tegra_plane_format(state->fb->format->format,
 				 &plane_state->format,
-				 &plane_state->swap);
+				 &plane_state->swap,
+				 true);
 	if (err < 0)
 		return err;
 
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 326700cd0d80..345ec37c7481 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -103,7 +103,7 @@ int tegra_plane_state_add(struct tegra_plane *plane,
 	return 0;
 }
 
-int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
+int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap, bool opaque_fmt)
 {
 	/* assume no swapping of fetched data */
 	if (swap)
@@ -147,11 +147,17 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
 		break;
 
 	case DRM_FORMAT_XRGB1555:
-		*format = WIN_COLOR_DEPTH_B5G5R5X1;
+		if (opaque_fmt)
+			*format = WIN_COLOR_DEPTH_B5G5R5X1;
+		else
+			*format = WIN_COLOR_DEPTH_B5G5R5A;
 		break;
 
 	case DRM_FORMAT_RGBX5551:
-		*format = WIN_COLOR_DEPTH_X1B5G5R5;
+		if (opaque_fmt)
+			*format = WIN_COLOR_DEPTH_X1B5G5R5;
+		else
+			*format = WIN_COLOR_DEPTH_AB5G5R5;
 		break;
 
 	case DRM_FORMAT_XBGR1555:
@@ -175,11 +181,17 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
 		break;
 
 	case DRM_FORMAT_XRGB8888:
-		*format = WIN_COLOR_DEPTH_B8G8R8X8;
+		if (opaque_fmt)
+			*format = WIN_COLOR_DEPTH_B8G8R8X8;
+		else
+			*format = WIN_COLOR_DEPTH_B8G8R8A8;
 		break;
 
 	case DRM_FORMAT_XBGR8888:
-		*format = WIN_COLOR_DEPTH_R8G8B8X8;
+		if (opaque_fmt)
+			*format = WIN_COLOR_DEPTH_R8G8B8X8;
+		else
+			*format = WIN_COLOR_DEPTH_R8G8B8A8;
 		break;
 
 	case DRM_FORMAT_UYVY:
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
index fc7566f630fa..27145d64ad90 100644
--- a/drivers/gpu/drm/tegra/plane.h
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -55,7 +55,7 @@ extern const struct drm_plane_funcs tegra_plane_funcs;
 int tegra_plane_state_add(struct tegra_plane *plane,
 			  struct drm_plane_state *state);
 
-int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap);
+int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap, bool opaque_fmt);
 bool tegra_plane_format_is_yuv(unsigned int format, bool *planar);
 
 #endif /* TEGRA_PLANE_H */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v1] drm/tegra: Trade overlay plane for cursor on older Tegra's
  2017-12-17 17:25 [PATCH v1] drm/tegra: Correct timeout in tegra_syncpt_wait Dmitry Osipenko
  2017-12-17 17:25 ` [PATCH v1] drm/tegra: gem: Correct iommu_map_sg() error checking Dmitry Osipenko
  2017-12-17 17:25 ` [PATCH v1] drm/tegra: Restore opaque formats on Tegra20/30 Dmitry Osipenko
@ 2017-12-17 17:25 ` Dmitry Osipenko
  2017-12-17 17:25 ` [PATCH v2] drm/tegra: dc: Link DC1 to DC0 on Tegra20 Dmitry Osipenko
  3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Osipenko @ 2017-12-17 17:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: dri-devel, linux-tegra, linux-kernel

Older Tegra's do not support RGBA format for the cursor, but instead
overlay plane could be used for it. Since there is no much use for the
overlays on a regular desktop and HW-accelerated cursor is much nicer
than the jerky SW cursor, let's trade one overlay plane for the cursor.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/dc.c | 52 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 7e58143f4145..3282aa911351 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -125,9 +125,10 @@ static inline u32 compute_initial_dda(unsigned int in)
 	return dfixed_frac(inf);
 }
 
-static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
+static void tegra_dc_setup_window(struct tegra_dc *dc, struct drm_plane *plane,
 				  const struct tegra_dc_window *window)
 {
+	struct tegra_plane *p = to_tegra_plane(plane);
 	unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
 	unsigned long value, flags;
 	bool yuv, planar;
@@ -144,7 +145,7 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
 
 	spin_lock_irqsave(&dc->lock, flags);
 
-	value = WINDOW_A_SELECT << index;
+	value = WINDOW_A_SELECT << p->index;
 	tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
 
 	tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH);
@@ -275,23 +276,29 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
 	tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_NOKEY);
 	tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_1WIN);
 
-	switch (index) {
+	switch (p->index) {
 	case 0:
 		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_X);
-		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
+		tegra_dc_writel(dc, 0x000008, DC_WIN_BLEND_2WIN_Y);
 		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
 		break;
 
 	case 1:
 		tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
 		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
-		tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
+		tegra_dc_writel(dc, 0x000008, DC_WIN_BLEND_3WIN_XY);
 		break;
 
 	case 2:
-		tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
-		tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_Y);
-		tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_3WIN_XY);
+		if (plane->type == DRM_PLANE_TYPE_CURSOR) {
+			tegra_dc_writel(dc, 0xffff04, DC_WIN_BLEND_2WIN_X);
+			tegra_dc_writel(dc, 0xffff04, DC_WIN_BLEND_2WIN_Y);
+			tegra_dc_writel(dc, 0xffff04, DC_WIN_BLEND_3WIN_XY);
+		} else {
+			tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
+			tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_Y);
+			tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_3WIN_XY);
+		}
 		break;
 	}
 
@@ -438,7 +445,6 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
 	struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
 	struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
 	struct drm_framebuffer *fb = plane->state->fb;
-	struct tegra_plane *p = to_tegra_plane(plane);
 	struct tegra_dc_window window;
 	unsigned int i;
 
@@ -480,7 +486,7 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
 			window.stride[i] = fb->pitches[i];
 	}
 
-	tegra_dc_setup_window(dc, p->index, &window);
+	tegra_dc_setup_window(dc, plane, &window);
 }
 
 static const struct drm_plane_helper_funcs tegra_plane_helper_funcs = {
@@ -775,9 +781,11 @@ static const u32 tegra124_overlay_formats[] = {
 
 static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
 						       struct tegra_dc *dc,
-						       unsigned int index)
+						       unsigned int index,
+						       bool cursor)
 {
 	struct tegra_plane *plane;
+	enum drm_plane_type type;
 	unsigned int num_formats;
 	const u32 *formats;
 	int err;
@@ -793,11 +801,14 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
 
 	num_formats = dc->soc->num_overlay_formats;
 	formats = dc->soc->overlay_formats;
+	type = DRM_PLANE_TYPE_OVERLAY;
+
+	if (cursor)
+		type = DRM_PLANE_TYPE_CURSOR;
 
 	err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
 				       &tegra_plane_funcs, formats,
-				       num_formats, NULL,
-				       DRM_PLANE_TYPE_OVERLAY, NULL);
+				       num_formats, NULL, type, NULL);
 	if (err < 0) {
 		kfree(plane);
 		return ERR_PTR(err);
@@ -846,14 +857,18 @@ static struct drm_plane *tegra_dc_add_planes(struct drm_device *drm,
 					     struct tegra_dc *dc)
 {
 	struct drm_plane *plane, *primary;
+	unsigned int planes_num = 2;
 	unsigned int i;
 
 	primary = tegra_primary_plane_create(drm, dc);
 	if (IS_ERR(primary))
 		return primary;
 
-	for (i = 0; i < 2; i++) {
-		plane = tegra_dc_overlay_plane_create(drm, dc, 1 + i);
+	if (!dc->soc->supports_cursor)
+		planes_num--;
+
+	for (i = 0; i < planes_num; i++) {
+		plane = tegra_dc_overlay_plane_create(drm, dc, 1 + i, false);
 		if (IS_ERR(plane)) {
 			/* XXX tegra_plane_destroy() */
 			drm_plane_cleanup(primary);
@@ -1770,6 +1785,13 @@ static int tegra_dc_init(struct host1x_client *client)
 			err = PTR_ERR(cursor);
 			goto cleanup;
 		}
+	} else {
+		/* trade overlay for RGBA cursor plane on older Tegra's */
+		cursor = tegra_dc_overlay_plane_create(drm, dc, 2, true);
+		if (IS_ERR(cursor)) {
+			err = PTR_ERR(cursor);
+			goto cleanup;
+		}
 	}
 
 	err = drm_crtc_init_with_planes(drm, &dc->base, primary, cursor,
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2] drm/tegra: dc: Link DC1 to DC0 on Tegra20
  2017-12-17 17:25 [PATCH v1] drm/tegra: Correct timeout in tegra_syncpt_wait Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2017-12-17 17:25 ` [PATCH v1] drm/tegra: Trade overlay plane for cursor on older Tegra's Dmitry Osipenko
@ 2017-12-17 17:25 ` Dmitry Osipenko
  3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Osipenko @ 2017-12-17 17:25 UTC (permalink / raw)
  To: Thierry Reding; +Cc: dri-devel, linux-tegra, linux-kernel

HW reset isn't actually broken on Tegra20, but there is a dependency on
first display controller to be taken out of reset for the second to be
enabled successfully.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---

Change log:
v2:	Got rid of global variable and now use driver_find_device() instead.

 drivers/gpu/drm/tegra/dc.c | 80 +++++++++++++++++++++++++++++-----------------
 drivers/gpu/drm/tegra/dc.h |  2 +-
 2 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index e963e40d8a25..be84c36ad81f 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1842,7 +1842,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
 	.supports_block_linear = false,
 	.pitch_align = 8,
 	.has_powergate = false,
-	.broken_reset = true,
+	.coupled_pm = true,
 	.has_nvdisplay = false,
 	.num_primary_formats = ARRAY_SIZE(tegra20_primary_formats),
 	.primary_formats = tegra20_primary_formats,
@@ -1857,7 +1857,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
 	.supports_block_linear = false,
 	.pitch_align = 8,
 	.has_powergate = false,
-	.broken_reset = false,
+	.coupled_pm = false,
 	.has_nvdisplay = false,
 	.num_primary_formats = ARRAY_SIZE(tegra20_primary_formats),
 	.primary_formats = tegra20_primary_formats,
@@ -1872,7 +1872,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
 	.supports_block_linear = false,
 	.pitch_align = 64,
 	.has_powergate = true,
-	.broken_reset = false,
+	.coupled_pm = false,
 	.has_nvdisplay = false,
 	.num_primary_formats = ARRAY_SIZE(tegra114_primary_formats),
 	.primary_formats = tegra114_primary_formats,
@@ -1887,7 +1887,7 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
 	.supports_block_linear = true,
 	.pitch_align = 64,
 	.has_powergate = true,
-	.broken_reset = false,
+	.coupled_pm = false,
 	.has_nvdisplay = false,
 	.num_primary_formats = ARRAY_SIZE(tegra124_primary_formats),
 	.primary_formats = tegra114_primary_formats,
@@ -1902,7 +1902,7 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
 	.supports_block_linear = true,
 	.pitch_align = 64,
 	.has_powergate = true,
-	.broken_reset = false,
+	.coupled_pm = false,
 	.has_nvdisplay = false,
 	.num_primary_formats = ARRAY_SIZE(tegra114_primary_formats),
 	.primary_formats = tegra114_primary_formats,
@@ -1951,7 +1951,7 @@ static const struct tegra_dc_soc_info tegra186_dc_soc_info = {
 	.supports_block_linear = true,
 	.pitch_align = 64,
 	.has_powergate = false,
-	.broken_reset = false,
+	.coupled_pm = false,
 	.has_nvdisplay = true,
 	.wgrps = tegra186_dc_wgrps,
 	.num_wgrps = ARRAY_SIZE(tegra186_dc_wgrps),
@@ -2019,6 +2019,11 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc)
 	return 0;
 }
 
+static int tegra_dc_match(struct device *dev, void *data)
+{
+	return of_device_is_compatible(dev->of_node, "nvidia,tegra20-dc");
+}
+
 static int tegra_dc_probe(struct platform_device *pdev)
 {
 	struct resource *regs;
@@ -2039,6 +2044,28 @@ static int tegra_dc_probe(struct platform_device *pdev)
 	if (err < 0)
 		return err;
 
+	/*
+	 * On Tegra20 DC1 requires DC0 to be taken out of reset in order to
+	 * be enabled, otherwise CPU hangs on writing to CMD_DISPLAY_COMMAND /
+	 * POWER_CONTROL registers during CRTC enabling.
+	 */
+	if (dc->pipe == 1 && dc->soc->coupled_pm) {
+		struct device_link *link;
+		struct device *dc0_dev;
+
+		dc0_dev = driver_find_device(pdev->dev.driver, NULL, NULL,
+					     tegra_dc_match);
+		if (!dc0_dev)
+			return -EPROBE_DEFER;
+
+		link = device_link_add(&pdev->dev, dc0_dev,
+				       DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE);
+		if (!link) {
+			dev_err(&pdev->dev, "failed to link to DC0\n");
+			return -EINVAL;
+		}
+	}
+
 	dc->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(dc->clk)) {
 		dev_err(&pdev->dev, "failed to get clock\n");
@@ -2052,21 +2079,19 @@ static int tegra_dc_probe(struct platform_device *pdev)
 	}
 
 	/* assert reset and disable clock */
-	if (!dc->soc->broken_reset) {
-		err = clk_prepare_enable(dc->clk);
-		if (err < 0)
-			return err;
+	err = clk_prepare_enable(dc->clk);
+	if (err < 0)
+		return err;
 
-		usleep_range(2000, 4000);
+	usleep_range(2000, 4000);
 
-		err = reset_control_assert(dc->rst);
-		if (err < 0)
-			return err;
+	err = reset_control_assert(dc->rst);
+	if (err < 0)
+		return err;
 
-		usleep_range(2000, 4000);
+	usleep_range(2000, 4000);
 
-		clk_disable_unprepare(dc->clk);
-	}
+	clk_disable_unprepare(dc->clk);
 
 	if (dc->soc->has_powergate) {
 		if (dc->pipe == 0)
@@ -2140,12 +2165,10 @@ static int tegra_dc_suspend(struct device *dev)
 	struct tegra_dc *dc = dev_get_drvdata(dev);
 	int err;
 
-	if (!dc->soc->broken_reset) {
-		err = reset_control_assert(dc->rst);
-		if (err < 0) {
-			dev_err(dev, "failed to assert reset: %d\n", err);
-			return err;
-		}
+	err = reset_control_assert(dc->rst);
+	if (err < 0) {
+		dev_err(dev, "failed to assert reset: %d\n", err);
+		return err;
 	}
 
 	if (dc->soc->has_powergate)
@@ -2175,13 +2198,10 @@ static int tegra_dc_resume(struct device *dev)
 			return err;
 		}
 
-		if (!dc->soc->broken_reset) {
-			err = reset_control_deassert(dc->rst);
-			if (err < 0) {
-				dev_err(dev,
-					"failed to deassert reset: %d\n", err);
-				return err;
-			}
+		err = reset_control_deassert(dc->rst);
+		if (err < 0) {
+			dev_err(dev, "failed to deassert reset: %d\n", err);
+			return err;
 		}
 	}
 
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 8d68997e6263..8098f49c0d96 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -57,7 +57,7 @@ struct tegra_dc_soc_info {
 	bool supports_block_linear;
 	unsigned int pitch_align;
 	bool has_powergate;
-	bool broken_reset;
+	bool coupled_pm;
 	bool has_nvdisplay;
 	const struct tegra_windowgroup_soc *wgrps;
 	unsigned int num_wgrps;
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v1] drm/tegra: gem: Correct iommu_map_sg() error checking
  2017-12-17 17:25 ` [PATCH v1] drm/tegra: gem: Correct iommu_map_sg() error checking Dmitry Osipenko
@ 2017-12-20  6:19   ` kbuild test robot
  0 siblings, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2017-12-20  6:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: kbuild-all, Thierry Reding, dri-devel, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5790 bytes --]

Hi Dmitry,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on tegra/for-next]
[also build test WARNING on v4.15-rc4 next-20171220]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/drm-tegra-gem-Correct-iommu_map_sg-error-checking/20171220-123700
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next
config: arm64-allmodconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm64 

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/tegra/gem.c: In function 'tegra_bo_iommu_map':
>> drivers/gpu/drm/tegra/gem.c:131:58: warning: format '%zd' expects argument of type 'signed size_t', but argument 3 has type 'int' [-Wformat=]
      dev_err(tegra->drm->dev, "out of I/O virtual memory: %zd\n",
                                                           ~~^
                                                           %d

vim +131 drivers/gpu/drm/tegra/gem.c

de2ba664c drivers/gpu/host1x/drm/gem.c Arto Merilainen 2013-03-22  113  
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  114  static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  115  {
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  116  	int prot = IOMMU_READ | IOMMU_WRITE;
e1ad592fa drivers/gpu/drm/tegra/gem.c  Dmitry Osipenko 2017-12-17  117  	int err;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  118  
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  119  	if (bo->mm)
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  120  		return -EBUSY;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  121  
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  122  	bo->mm = kzalloc(sizeof(*bo->mm), GFP_KERNEL);
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  123  	if (!bo->mm)
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  124  		return -ENOMEM;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  125  
347ad49d3 drivers/gpu/drm/tegra/gem.c  Thierry Reding  2017-03-09  126  	mutex_lock(&tegra->mm_lock);
347ad49d3 drivers/gpu/drm/tegra/gem.c  Thierry Reding  2017-03-09  127  
4e64e5539 drivers/gpu/drm/tegra/gem.c  Chris Wilson    2017-02-02  128  	err = drm_mm_insert_node_generic(&tegra->mm,
4e64e5539 drivers/gpu/drm/tegra/gem.c  Chris Wilson    2017-02-02  129  					 bo->mm, bo->gem.size, PAGE_SIZE, 0, 0);
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  130  	if (err < 0) {
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26 @131  		dev_err(tegra->drm->dev, "out of I/O virtual memory: %zd\n",
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  132  			err);
347ad49d3 drivers/gpu/drm/tegra/gem.c  Thierry Reding  2017-03-09  133  		goto unlock;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  134  	}
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  135  
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  136  	bo->paddr = bo->mm->start;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  137  
e1ad592fa drivers/gpu/drm/tegra/gem.c  Dmitry Osipenko 2017-12-17  138  	bo->size = iommu_map_sg(tegra->domain, bo->paddr, bo->sgt->sgl,
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  139  				bo->sgt->nents, prot);
e1ad592fa drivers/gpu/drm/tegra/gem.c  Dmitry Osipenko 2017-12-17  140  	if (!bo->size) {
e1ad592fa drivers/gpu/drm/tegra/gem.c  Dmitry Osipenko 2017-12-17  141  		dev_err(tegra->drm->dev, "failed to map buffer\n");
e1ad592fa drivers/gpu/drm/tegra/gem.c  Dmitry Osipenko 2017-12-17  142  		err = -ENOMEM;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  143  		goto remove;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  144  	}
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  145  
347ad49d3 drivers/gpu/drm/tegra/gem.c  Thierry Reding  2017-03-09  146  	mutex_unlock(&tegra->mm_lock);
347ad49d3 drivers/gpu/drm/tegra/gem.c  Thierry Reding  2017-03-09  147  
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  148  	return 0;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  149  
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  150  remove:
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  151  	drm_mm_remove_node(bo->mm);
347ad49d3 drivers/gpu/drm/tegra/gem.c  Thierry Reding  2017-03-09  152  unlock:
347ad49d3 drivers/gpu/drm/tegra/gem.c  Thierry Reding  2017-03-09  153  	mutex_unlock(&tegra->mm_lock);
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  154  	kfree(bo->mm);
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  155  	return err;
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  156  }
df06b759f drivers/gpu/drm/tegra/gem.c  Thierry Reding  2014-06-26  157  

:::::: The code at line 131 was first introduced by commit
:::::: df06b759f2cf4690fa9991edb1504ba39932b2bb drm/tegra: Add IOMMU support

:::::: TO: Thierry Reding <treding@nvidia.com>
:::::: CC: Thierry Reding <treding@nvidia.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 58535 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-12-20  6:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-17 17:25 [PATCH v1] drm/tegra: Correct timeout in tegra_syncpt_wait Dmitry Osipenko
2017-12-17 17:25 ` [PATCH v1] drm/tegra: gem: Correct iommu_map_sg() error checking Dmitry Osipenko
2017-12-20  6:19   ` kbuild test robot
2017-12-17 17:25 ` [PATCH v1] drm/tegra: Restore opaque formats on Tegra20/30 Dmitry Osipenko
2017-12-17 17:25 ` [PATCH v1] drm/tegra: Trade overlay plane for cursor on older Tegra's Dmitry Osipenko
2017-12-17 17:25 ` [PATCH v2] drm/tegra: dc: Link DC1 to DC0 on Tegra20 Dmitry Osipenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).