* [PATCH v3 0/3] 180 degrees rotation support for NVIDIA Tegra DRM
@ 2020-06-17 23:40 Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 1/3] drm/tegra: plane: Rename bottom_up to reflect_y Dmitry Osipenko
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Dmitry Osipenko @ 2020-06-17 23:40 UTC (permalink / raw)
To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
Laurent Pinchart, Sean Paul, Daniel Vetter,
Ville Syrjälä, Emil Velikov, Daniel Stone
Cc: dri-devel, linux-tegra, linux-kernel
Hello!
This series adds 180° display plane rotation support to the NVIDIA Tegra
DRM driver which is needed for devices that have display panel physically
mounted upside-down, like Nexus 7 tablet device for example [1]. Since
DRM panel rotation is a new thing for a userspace, currently only
Opentegra Xorg driver [2] and a recent Weston [3] have support for the
rotated display panels, but this is more than good enough for the starter.
[1] https://patchwork.ozlabs.org/project/linux-tegra/patch/20200607154327.18589-3-digetx@gmail.com/
[2] https://github.com/grate-driver/xf86-video-opentegra/commit/28eb20a3959bbe5bc3a3b67e55977093fd5114ca
[3] https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/315
Changelog:
v3: - Factored out the panel patches into standalone series [4] because
this series doesn't have hard dependency on the panel patches and it
should be nicer to review and apply the properly grouped patches.
- The DRM_MODE_ROTATE_180 now isn't passed to drm_rotation_simplify(),
like it was suggested by Ville Syrjälä in the comment to v2.
- Added clarifying comment for the tegra_fb_is_bottom_up() in the code.
[4] https://lore.kernel.org/lkml/20200617231842.30671-1-digetx@gmail.com/T/#t
Dmitry Osipenko (3):
drm/tegra: plane: Rename bottom_up to reflect_y
drm/tegra: plane: Support horizontal reflection
drm/tegra: plane: Support 180° rotation
drivers/gpu/drm/tegra/dc.c | 46 ++++++++++++++++++++++++++++-------
drivers/gpu/drm/tegra/dc.h | 3 ++-
drivers/gpu/drm/tegra/plane.c | 3 ++-
drivers/gpu/drm/tegra/plane.h | 3 ++-
4 files changed, 43 insertions(+), 12 deletions(-)
--
2.26.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 1/3] drm/tegra: plane: Rename bottom_up to reflect_y
2020-06-17 23:40 [PATCH v3 0/3] 180 degrees rotation support for NVIDIA Tegra DRM Dmitry Osipenko
@ 2020-06-17 23:40 ` Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 2/3] drm/tegra: plane: Support horizontal reflection Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 3/3] drm/tegra: plane: Support 180° rotation Dmitry Osipenko
2 siblings, 0 replies; 4+ messages in thread
From: Dmitry Osipenko @ 2020-06-17 23:40 UTC (permalink / raw)
To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
Laurent Pinchart, Sean Paul, Daniel Vetter,
Ville Syrjälä, Emil Velikov, Daniel Stone
Cc: dri-devel, linux-tegra, linux-kernel
This makes the naming consistent with the DRM core.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/gpu/drm/tegra/dc.c | 10 +++++-----
drivers/gpu/drm/tegra/dc.h | 2 +-
drivers/gpu/drm/tegra/plane.c | 2 +-
drivers/gpu/drm/tegra/plane.h | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 04d6848d19fc..bb92c1ed44e9 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -404,7 +404,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
tegra_plane_writel(plane, window->stride[0], DC_WIN_LINE_STRIDE);
}
- if (window->bottom_up)
+ if (window->reflect_y)
v_offset += window->src.h - 1;
tegra_plane_writel(plane, h_offset, DC_WINBUF_ADDR_H_OFFSET);
@@ -470,7 +470,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
value |= COLOR_EXPAND;
}
- if (window->bottom_up)
+ if (window->reflect_y)
value |= V_DIRECTION;
if (tegra_plane_use_horizontal_filtering(plane, window)) {
@@ -642,9 +642,9 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
rotation = drm_rotation_simplify(state->rotation, rotation);
if (rotation & DRM_MODE_REFLECT_Y)
- plane_state->bottom_up = true;
+ plane_state->reflect_y = true;
else
- plane_state->bottom_up = false;
+ plane_state->reflect_y = false;
/*
* Tegra doesn't support different strides for U and V planes so we
@@ -706,7 +706,7 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
window.dst.w = drm_rect_width(&plane->state->dst);
window.dst.h = drm_rect_height(&plane->state->dst);
window.bits_per_pixel = fb->format->cpp[0] * 8;
- window.bottom_up = tegra_fb_is_bottom_up(fb) || state->bottom_up;
+ window.reflect_y = tegra_fb_is_bottom_up(fb) || state->reflect_y;
/* copy from state */
window.zpos = plane->state->normalized_zpos;
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 3d8ddccd758f..98e1b625168e 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -136,7 +136,7 @@ struct tegra_dc_window {
unsigned int stride[2];
unsigned long base[3];
unsigned int zpos;
- bool bottom_up;
+ bool reflect_y;
struct tegra_bo_tiling tiling;
u32 format;
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56e9b01..e05ef6013a97 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -61,7 +61,7 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
copy->tiling = state->tiling;
copy->format = state->format;
copy->swap = state->swap;
- copy->bottom_up = state->bottom_up;
+ copy->reflect_y = state->reflect_y;
copy->opaque = state->opaque;
for (i = 0; i < 2; i++)
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
index a158a915109a..8047fc916d8c 100644
--- a/drivers/gpu/drm/tegra/plane.h
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -46,7 +46,7 @@ struct tegra_plane_state {
u32 format;
u32 swap;
- bool bottom_up;
+ bool reflect_y;
/* used for legacy blending support only */
struct tegra_plane_legacy_blending_state blending[2];
--
2.26.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 2/3] drm/tegra: plane: Support horizontal reflection
2020-06-17 23:40 [PATCH v3 0/3] 180 degrees rotation support for NVIDIA Tegra DRM Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 1/3] drm/tegra: plane: Rename bottom_up to reflect_y Dmitry Osipenko
@ 2020-06-17 23:40 ` Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 3/3] drm/tegra: plane: Support 180° rotation Dmitry Osipenko
2 siblings, 0 replies; 4+ messages in thread
From: Dmitry Osipenko @ 2020-06-17 23:40 UTC (permalink / raw)
To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
Laurent Pinchart, Sean Paul, Daniel Vetter,
Ville Syrjälä, Emil Velikov, Daniel Stone
Cc: dri-devel, linux-tegra, linux-kernel
Support horizontal reflection mode which will allow to support 180°
rotation mode when combined with the vertical reflection.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/gpu/drm/tegra/dc.c | 38 +++++++++++++++++++++++++++++------
drivers/gpu/drm/tegra/dc.h | 1 +
drivers/gpu/drm/tegra/plane.c | 1 +
drivers/gpu/drm/tegra/plane.h | 1 +
4 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index bb92c1ed44e9..f8149dc3b1b4 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -368,6 +368,12 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
h_size = window->src.w * bpp;
v_size = window->src.h;
+ if (window->reflect_x)
+ h_offset += (window->src.w - 1) * bpp;
+
+ if (window->reflect_y)
+ v_offset += window->src.h - 1;
+
value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
tegra_plane_writel(plane, value, DC_WIN_PRESCALED_SIZE);
@@ -404,9 +410,6 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
tegra_plane_writel(plane, window->stride[0], DC_WIN_LINE_STRIDE);
}
- if (window->reflect_y)
- v_offset += window->src.h - 1;
-
tegra_plane_writel(plane, h_offset, DC_WINBUF_ADDR_H_OFFSET);
tegra_plane_writel(plane, v_offset, DC_WINBUF_ADDR_V_OFFSET);
@@ -470,6 +473,9 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
value |= COLOR_EXPAND;
}
+ if (window->reflect_x)
+ value |= H_DIRECTION;
+
if (window->reflect_y)
value |= V_DIRECTION;
@@ -601,7 +607,10 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
struct tegra_plane_state *plane_state = to_tegra_plane_state(state);
- unsigned int rotation = DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y;
+ unsigned int supported_rotation = DRM_MODE_ROTATE_0 |
+ DRM_MODE_REFLECT_X |
+ DRM_MODE_REFLECT_Y;
+ unsigned int rotation = state->rotation;
struct tegra_bo_tiling *tiling = &plane_state->tiling;
struct tegra_plane *tegra = to_tegra_plane(plane);
struct tegra_dc *dc = to_tegra_dc(state->crtc);
@@ -639,7 +648,21 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
}
- rotation = drm_rotation_simplify(state->rotation, rotation);
+ /*
+ * Older userspace used custom BO flag in order to specify the Y
+ * reflection, while modern userspace uses the generic DRM rotation
+ * property in order to achieve the same result. The legacy BO flag
+ * duplicates the DRM rotation property when both are set.
+ */
+ if (tegra_fb_is_bottom_up(state->fb))
+ rotation |= DRM_MODE_REFLECT_Y;
+
+ rotation = drm_rotation_simplify(rotation, supported_rotation);
+
+ if (rotation & DRM_MODE_REFLECT_X)
+ plane_state->reflect_x = true;
+ else
+ plane_state->reflect_x = false;
if (rotation & DRM_MODE_REFLECT_Y)
plane_state->reflect_y = true;
@@ -706,7 +729,8 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
window.dst.w = drm_rect_width(&plane->state->dst);
window.dst.h = drm_rect_height(&plane->state->dst);
window.bits_per_pixel = fb->format->cpp[0] * 8;
- window.reflect_y = tegra_fb_is_bottom_up(fb) || state->reflect_y;
+ window.reflect_x = state->reflect_x;
+ window.reflect_y = state->reflect_y;
/* copy from state */
window.zpos = plane->state->normalized_zpos;
@@ -792,6 +816,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
err = drm_plane_create_rotation_property(&plane->base,
DRM_MODE_ROTATE_0,
DRM_MODE_ROTATE_0 |
+ DRM_MODE_REFLECT_X |
DRM_MODE_REFLECT_Y);
if (err < 0)
dev_err(dc->dev, "failed to create rotation property: %d\n",
@@ -1080,6 +1105,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
err = drm_plane_create_rotation_property(&plane->base,
DRM_MODE_ROTATE_0,
DRM_MODE_ROTATE_0 |
+ DRM_MODE_REFLECT_X |
DRM_MODE_REFLECT_Y);
if (err < 0)
dev_err(dc->dev, "failed to create rotation property: %d\n",
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 98e1b625168e..051d03dcb9b0 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -136,6 +136,7 @@ struct tegra_dc_window {
unsigned int stride[2];
unsigned long base[3];
unsigned int zpos;
+ bool reflect_x;
bool reflect_y;
struct tegra_bo_tiling tiling;
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index e05ef6013a97..4cd0461cc508 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -61,6 +61,7 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
copy->tiling = state->tiling;
copy->format = state->format;
copy->swap = state->swap;
+ copy->reflect_x = state->reflect_x;
copy->reflect_y = state->reflect_y;
copy->opaque = state->opaque;
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
index 8047fc916d8c..c691dd79b27b 100644
--- a/drivers/gpu/drm/tegra/plane.h
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -46,6 +46,7 @@ struct tegra_plane_state {
u32 format;
u32 swap;
+ bool reflect_x;
bool reflect_y;
/* used for legacy blending support only */
--
2.26.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 3/3] drm/tegra: plane: Support 180° rotation
2020-06-17 23:40 [PATCH v3 0/3] 180 degrees rotation support for NVIDIA Tegra DRM Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 1/3] drm/tegra: plane: Rename bottom_up to reflect_y Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 2/3] drm/tegra: plane: Support horizontal reflection Dmitry Osipenko
@ 2020-06-17 23:40 ` Dmitry Osipenko
2 siblings, 0 replies; 4+ messages in thread
From: Dmitry Osipenko @ 2020-06-17 23:40 UTC (permalink / raw)
To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
Laurent Pinchart, Sean Paul, Daniel Vetter,
Ville Syrjälä, Emil Velikov, Daniel Stone
Cc: dri-devel, linux-tegra, linux-kernel
Combining horizontal and vertical reflections gives us 180 degrees of
rotation. Both reflection modes are already supported, and thus, we just
need to mark the 180 rotation mode as supported. The 180 rotation mode is
needed for devices like Nexus 7 tablet, which have display panel mounted
upside-down.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/gpu/drm/tegra/dc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index f8149dc3b1b4..1a9a5f8bba34 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -816,6 +816,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
err = drm_plane_create_rotation_property(&plane->base,
DRM_MODE_ROTATE_0,
DRM_MODE_ROTATE_0 |
+ DRM_MODE_ROTATE_180 |
DRM_MODE_REFLECT_X |
DRM_MODE_REFLECT_Y);
if (err < 0)
@@ -1105,6 +1106,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
err = drm_plane_create_rotation_property(&plane->base,
DRM_MODE_ROTATE_0,
DRM_MODE_ROTATE_0 |
+ DRM_MODE_ROTATE_180 |
DRM_MODE_REFLECT_X |
DRM_MODE_REFLECT_Y);
if (err < 0)
--
2.26.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-06-17 23:41 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-17 23:40 [PATCH v3 0/3] 180 degrees rotation support for NVIDIA Tegra DRM Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 1/3] drm/tegra: plane: Rename bottom_up to reflect_y Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 2/3] drm/tegra: plane: Support horizontal reflection Dmitry Osipenko
2020-06-17 23:40 ` [PATCH v3 3/3] drm/tegra: plane: Support 180° rotation Dmitry Osipenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox