* [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).