dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/6] 180° rotation support for NVIDIA Tegra DRM
@ 2020-06-14 19:03 Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 1/6] drm/panel: Add helper for reading DT rotation Dmitry Osipenko
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2020-06-14 19:03 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul
  Cc: linux-tegra, linux-kernel, dri-devel

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 handles the rotated display panel [2], but this
is good enough for the start.

Note that later on it should be possible to implement a transparent 180°
display rotation for Tegra DRM driver which will remove the need to have
a bleeding edge userspace that knows how to rotate display planes and I'm
slowly working on it. For the starter we can go with the minimal rotation
support, so it's not a blocker.

This series is based on the work that was made by Derek Basehore for the
Mediatek driver [3], his patches are included into this patchset. I added
my tested-by tags to the Derek's patches.

Please review and apply, thanks in advance!

[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://lkml.org/lkml/2020/3/5/1119

Derek Basehore (2):
  drm/panel: Add helper for reading DT rotation
  drm/panel: Set display info in panel attach

Dmitry Osipenko (4):
  drm/panel: lvds: Set up panel orientation
  drm/tegra: plane: Rename bottom_up to reflect_y
  drm/tegra: plane: Support horizontal reflection mode
  drm/tegra: plane: Support 180° rotation

 drivers/gpu/drm/drm_panel.c        | 56 ++++++++++++++++++++++++++++
 drivers/gpu/drm/panel/panel-lvds.c |  6 +++
 drivers/gpu/drm/tegra/dc.c         | 43 ++++++++++++++++++----
 drivers/gpu/drm/tegra/dc.h         |  3 +-
 drivers/gpu/drm/tegra/plane.c      |  3 +-
 drivers/gpu/drm/tegra/plane.h      |  3 +-
 include/drm/drm_panel.h            | 59 ++++++++++++++++++++++++++++++
 7 files changed, 162 insertions(+), 11 deletions(-)

-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 1/6] drm/panel: Add helper for reading DT rotation
  2020-06-14 19:03 [PATCH v1 0/6] 180° rotation support for NVIDIA Tegra DRM Dmitry Osipenko
@ 2020-06-14 19:03 ` Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 2/6] drm/panel: Set display info in panel attach Dmitry Osipenko
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2020-06-14 19:03 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul
  Cc: linux-tegra, linux-kernel, dri-devel

From: Derek Basehore <dbasehore@chromium.org>

This adds a helper function for reading the rotation (panel
orientation) from the device tree.

Signed-off-by: Derek Basehore <dbasehore@chromium.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/drm_panel.c | 43 +++++++++++++++++++++++++++++++++++++
 include/drm/drm_panel.h     |  9 ++++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 8c7bac85a793..5557c75301f1 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -300,6 +300,49 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
 	return ERR_PTR(-EPROBE_DEFER);
 }
 EXPORT_SYMBOL(of_drm_find_panel);
+
+/**
+ * of_drm_get_panel_orientation - look up the orientation of the panel through
+ * the "rotation" binding from a device tree node
+ * @np: device tree node of the panel
+ * @orientation: orientation enum to be filled in
+ *
+ * Looks up the rotation of a panel in the device tree. The orientation of the
+ * panel is expressed as a property name "rotation" in the device tree. The
+ * rotation in the device tree is counter clockwise.
+ *
+ * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
+ * rotation property doesn't exist. -EERROR otherwise.
+ */
+int of_drm_get_panel_orientation(const struct device_node *np,
+				 enum drm_panel_orientation *orientation)
+{
+	int rotation, ret;
+
+	ret = of_property_read_u32(np, "rotation", &rotation);
+	if (ret == -EINVAL) {
+		/* Don't return an error if there's no rotation property. */
+		*orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+		return 0;
+	}
+
+	if (ret < 0)
+		return ret;
+
+	if (rotation == 0)
+		*orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
+	else if (rotation == 90)
+		*orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
+	else if (rotation == 180)
+		*orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
+	else if (rotation == 270)
+		*orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL(of_drm_get_panel_orientation);
 #endif
 
 #if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE)
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 6193cb555acc..781c735f0f9b 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -35,6 +35,8 @@ struct drm_device;
 struct drm_panel;
 struct display_timing;
 
+enum drm_panel_orientation;
+
 /**
  * struct drm_panel_funcs - perform operations on a given panel
  *
@@ -191,11 +193,18 @@ int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector
 
 #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL)
 struct drm_panel *of_drm_find_panel(const struct device_node *np);
+int of_drm_get_panel_orientation(const struct device_node *np,
+				 enum drm_panel_orientation *orientation);
 #else
 static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
 {
 	return ERR_PTR(-ENODEV);
 }
+static inline int of_drm_get_panel_orientation(const struct device_node *np,
+		enum drm_panel_orientation *orientation)
+{
+	return -ENODEV;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_DRM_PANEL) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 2/6] drm/panel: Set display info in panel attach
  2020-06-14 19:03 [PATCH v1 0/6] 180° rotation support for NVIDIA Tegra DRM Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 1/6] drm/panel: Add helper for reading DT rotation Dmitry Osipenko
@ 2020-06-14 19:03 ` Dmitry Osipenko
  2020-06-14 19:36   ` Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 3/6] drm/panel: lvds: Set up panel orientation Dmitry Osipenko
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Dmitry Osipenko @ 2020-06-14 19:03 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul
  Cc: linux-tegra, linux-kernel, dri-devel

From: Derek Basehore <dbasehore@chromium.org>

Devicetree systems can set panel orientation via a panel binding, but
there's no way, as is, to propagate this setting to the connector,
where the property need to be added.
To address this, this patch sets orientation, as well as other fixed
values for the panel, in the drm_panel_attach function. These values
are stored from probe in the drm_panel struct.

Signed-off-by: Derek Basehore <dbasehore@chromium.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/drm_panel.c | 13 ++++++++++
 include/drm/drm_panel.h     | 50 +++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 5557c75301f1..9748972f2e7c 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -114,6 +114,19 @@ EXPORT_SYMBOL(drm_panel_remove);
  */
 int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
 {
+	struct drm_display_info *info;
+
+	info = &connector->display_info;
+	info->width_mm = panel->width_mm;
+	info->height_mm = panel->height_mm;
+	info->bpc = panel->bpc;
+	info->panel_orientation = panel->orientation;
+	info->bus_flags = panel->bus_flags;
+	if (panel->bus_formats)
+		drm_display_info_set_bus_formats(&connector->display_info,
+						 panel->bus_formats,
+						 panel->num_bus_formats);
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_panel_attach);
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 781c735f0f9b..97ac5f12a07c 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -165,6 +165,56 @@ struct drm_panel {
 	 */
 	int connector_type;
 
+	/**
+	 * @width_mm:
+	 *
+	 * Physical width in mm.
+	 */
+	unsigned int width_mm;
+
+	/**
+	 * @height_mm:
+	 *
+	 * Physical height in mm.
+	 */
+	unsigned int height_mm;
+
+	/**
+	 * @bpc:
+	 *
+	 * Maximum bits per color channel. Used by HDMI and DP outputs.
+	 */
+	unsigned int bpc;
+
+	/**
+	 * @orientation
+	 *
+	 * Installation orientation of the panel with respect to the chassis.
+	 */
+	int orientation;
+
+	/**
+	 * @bus_formats
+	 *
+	 * Pixel data format on the wire.
+	 */
+	const u32 *bus_formats;
+
+	/**
+	 * @num_bus_formats:
+	 *
+	 * Number of elements pointed to by @bus_formats
+	 */
+	unsigned int num_bus_formats;
+
+	/**
+	 * @bus_flags:
+	 *
+	 * Additional information (like pixel signal polarity) for the pixel
+	 * data on the bus.
+	 */
+	u32 bus_flags;
+
 	/**
 	 * @list:
 	 *
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 3/6] drm/panel: lvds: Set up panel orientation
  2020-06-14 19:03 [PATCH v1 0/6] 180° rotation support for NVIDIA Tegra DRM Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 1/6] drm/panel: Add helper for reading DT rotation Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 2/6] drm/panel: Set display info in panel attach Dmitry Osipenko
@ 2020-06-14 19:03 ` Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 4/6] drm/tegra: plane: Rename bottom_up to reflect_y Dmitry Osipenko
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2020-06-14 19:03 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul
  Cc: linux-tegra, linux-kernel, dri-devel

The panel orientation needs to parsed from a device-tree and assigned to
the panel's connector in order to make orientation property available to
userspace. That's what this patch does for the generic LVDS panel.

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

diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index 5ce3f4a2b7a1..9421246ac80f 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -99,6 +99,7 @@ static int panel_lvds_get_modes(struct drm_panel *panel,
 	connector->display_info.bus_flags = lvds->data_mirror
 					  ? DRM_BUS_FLAG_DATA_LSB_TO_MSB
 					  : DRM_BUS_FLAG_DATA_MSB_TO_LSB;
+	drm_connector_set_panel_orientation(connector, lvds->panel.orientation);
 
 	return 1;
 }
@@ -223,6 +224,11 @@ static int panel_lvds_probe(struct platform_device *pdev)
 	drm_panel_init(&lvds->panel, lvds->dev, &panel_lvds_funcs,
 		       DRM_MODE_CONNECTOR_LVDS);
 
+	ret = of_drm_get_panel_orientation(lvds->dev->of_node,
+					   &lvds->panel.orientation);
+	if (ret)
+		return ret;
+
 	ret = drm_panel_of_backlight(&lvds->panel);
 	if (ret)
 		return ret;
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 4/6] drm/tegra: plane: Rename bottom_up to reflect_y
  2020-06-14 19:03 [PATCH v1 0/6] 180° rotation support for NVIDIA Tegra DRM Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2020-06-14 19:03 ` [PATCH v1 3/6] drm/panel: lvds: Set up panel orientation Dmitry Osipenko
@ 2020-06-14 19:03 ` Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 5/6] drm/tegra: plane: Support horizontal reflection mode Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 6/6] drm/tegra: plane: Support 180° rotation Dmitry Osipenko
  5 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2020-06-14 19:03 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul
  Cc: linux-tegra, linux-kernel, dri-devel

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 83f31c6e891c..ed282f88e409 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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 5/6] drm/tegra: plane: Support horizontal reflection mode
  2020-06-14 19:03 [PATCH v1 0/6] 180° rotation support for NVIDIA Tegra DRM Dmitry Osipenko
                   ` (3 preceding siblings ...)
  2020-06-14 19:03 ` [PATCH v1 4/6] drm/tegra: plane: Rename bottom_up to reflect_y Dmitry Osipenko
@ 2020-06-14 19:03 ` Dmitry Osipenko
  2020-06-14 19:03 ` [PATCH v1 6/6] drm/tegra: plane: Support 180° rotation Dmitry Osipenko
  5 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2020-06-14 19:03 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul
  Cc: linux-tegra, linux-kernel, dri-devel

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    | 24 ++++++++++++++++++++----
 drivers/gpu/drm/tegra/dc.h    |  1 +
 drivers/gpu/drm/tegra/plane.c |  1 +
 drivers/gpu/drm/tegra/plane.h |  1 +
 4 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index ed282f88e409..f31bca27cde4 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,9 @@ 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 rotation = DRM_MODE_ROTATE_0 |
+				DRM_MODE_REFLECT_X |
+				DRM_MODE_REFLECT_Y;
 	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);
@@ -641,6 +649,11 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 
 	rotation = drm_rotation_simplify(state->rotation, 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;
 	else
@@ -706,6 +719,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.reflect_x = state->reflect_x;
 	window.reflect_y = tegra_fb_is_bottom_up(fb) || state->reflect_y;
 
 	/* copy from state */
@@ -792,6 +806,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",
@@ -1079,6 +1094,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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v1 6/6] drm/tegra: plane: Support 180° rotation
  2020-06-14 19:03 [PATCH v1 0/6] 180° rotation support for NVIDIA Tegra DRM Dmitry Osipenko
                   ` (4 preceding siblings ...)
  2020-06-14 19:03 ` [PATCH v1 5/6] drm/tegra: plane: Support horizontal reflection mode Dmitry Osipenko
@ 2020-06-14 19:03 ` Dmitry Osipenko
  5 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2020-06-14 19:03 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul
  Cc: linux-tegra, linux-kernel, dri-devel

Combining horizontal and vertical reflections gives us 180 degrees of
rotation.

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

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index f31bca27cde4..ddd9b88f8fce 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -608,6 +608,7 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 {
 	struct tegra_plane_state *plane_state = to_tegra_plane_state(state);
 	unsigned int rotation = DRM_MODE_ROTATE_0 |
+				DRM_MODE_ROTATE_180 |
 				DRM_MODE_REFLECT_X |
 				DRM_MODE_REFLECT_Y;
 	struct tegra_bo_tiling *tiling = &plane_state->tiling;
@@ -659,6 +660,14 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 	else
 		plane_state->reflect_y = false;
 
+	if (tegra_fb_is_bottom_up(state->fb))
+		plane_state->reflect_y = true;
+
+	if (rotation & DRM_MODE_ROTATE_180) {
+		plane_state->reflect_x = !plane_state->reflect_x;
+		plane_state->reflect_y = !plane_state->reflect_y;
+	}
+
 	/*
 	 * Tegra doesn't support different strides for U and V planes so we
 	 * error out if the user tries to display a framebuffer with such a
@@ -720,7 +729,7 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
 	window.dst.h = drm_rect_height(&plane->state->dst);
 	window.bits_per_pixel = fb->format->cpp[0] * 8;
 	window.reflect_x = state->reflect_x;
-	window.reflect_y = tegra_fb_is_bottom_up(fb) || state->reflect_y;
+	window.reflect_y = state->reflect_y;
 
 	/* copy from state */
 	window.zpos = plane->state->normalized_zpos;
@@ -806,6 +815,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)
@@ -1094,6 +1104,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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v1 2/6] drm/panel: Set display info in panel attach
  2020-06-14 19:03 ` [PATCH v1 2/6] drm/panel: Set display info in panel attach Dmitry Osipenko
@ 2020-06-14 19:36   ` Dmitry Osipenko
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2020-06-14 19:36 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul
  Cc: linux-tegra, linux-kernel, dri-devel

14.06.2020 22:03, Dmitry Osipenko пишет:
> From: Derek Basehore <dbasehore@chromium.org>
> 
> Devicetree systems can set panel orientation via a panel binding, but
> there's no way, as is, to propagate this setting to the connector,
> where the property need to be added.
> To address this, this patch sets orientation, as well as other fixed
> values for the panel, in the drm_panel_attach function. These values
> are stored from probe in the drm_panel struct.
> 
> Signed-off-by: Derek Basehore <dbasehore@chromium.org>
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> Tested-by: Dmitry Osipenko <digetx@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---

Ah, I just realized that this patch is obsolete now! I also got email
bounces saying that some email servers didn't like the UTF symbol in
name of the first email, so will make a v2 shortly.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2020-06-15  7:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-14 19:03 [PATCH v1 0/6] 180° rotation support for NVIDIA Tegra DRM Dmitry Osipenko
2020-06-14 19:03 ` [PATCH v1 1/6] drm/panel: Add helper for reading DT rotation Dmitry Osipenko
2020-06-14 19:03 ` [PATCH v1 2/6] drm/panel: Set display info in panel attach Dmitry Osipenko
2020-06-14 19:36   ` Dmitry Osipenko
2020-06-14 19:03 ` [PATCH v1 3/6] drm/panel: lvds: Set up panel orientation Dmitry Osipenko
2020-06-14 19:03 ` [PATCH v1 4/6] drm/tegra: plane: Rename bottom_up to reflect_y Dmitry Osipenko
2020-06-14 19:03 ` [PATCH v1 5/6] drm/tegra: plane: Support horizontal reflection mode Dmitry Osipenko
2020-06-14 19:03 ` [PATCH v1 6/6] 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;
as well as URLs for NNTP newsgroup(s).