Use the standard DT "rotation" attribute from
Documentation/devicetree/bindings/display/panel/panel.txt
to handle designs where the panel is mounted rotated
90 (or 270) degrees as in the ST-Ericsson HREF520
reference design.
Signed-off-by: Linus Walleij
---
drivers/gpu/drm/panel/panel-samsung-s6d16d0.c | 38 ++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c
b/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c
index f75bef24e050..d4c33781ade8 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
struct s6d16d0 {
@@ -20,6 +21,7 @@ struct s6d16d0 {
struct drm_panel panel;
struct regulator *supply;
struct gpio_desc *reset_gpio;
+ bool flipped;
};
/*
@@ -47,6 +49,28 @@ static const struct drm_display_mode samsung_s6d16d0_mode = {
.height_mm = 48,
};
+/* In the standing mode, things are just flipped around X/Y */
+static const struct drm_display_mode samsung_s6d16d0_standing_mode = {
+ /* HS clock, (htotal*vtotal*vrefresh)/1000 */
+ .clock = 420160,
+ .hdisplay = 480,
+ .hsync_start = 480 + 154,
+ .hsync_end = 480 + 154 + 16,
+ .htotal = 480 + 154 + 16 + 32,
+ .vdisplay = 864,
+ .vsync_start = 864 + 1,
+ .vsync_end = 864 + 1 + 1,
+ .vtotal = 864 + 1 + 1 + 1,
+ /*
+* This depends on the clocking HS vs LP rate, this value
+* is calculated as:
+* vrefresh = (clock * 1000) / (htotal*vtotal)
+*/
+ .vrefresh = 816,
+ .width_mm = 48,
+ .height_mm = 84,
+};
+
static inline struct s6d16d0 *panel_to_s6d16d0(struct drm_panel *panel)
{
return container_of(panel, struct s6d16d0, panel);
@@ -145,10 +169,16 @@ static int s6d16d0_disable(struct drm_panel *panel)
static int s6d16d0_get_modes(struct drm_panel *panel)
{
+ struct s6d16d0 *s6 = panel_to_s6d16d0(panel);
struct drm_connector *connector = panel->connector;
struct drm_display_mode *mode;
- mode = drm_mode_duplicate(panel->drm, _s6d16d0_mode);
+ if (s6->flipped)
+ mode = drm_mode_duplicate(panel->drm,
+ _s6d16d0_standing_mode);
+ else
+ mode = drm_mode_duplicate(panel->drm,
+ _s6d16d0_mode);
if (!mode) {
DRM_ERROR("bad mode or failed to add mode\n");
return -EINVAL;
@@ -176,6 +206,7 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = >dev;
struct s6d16d0 *s6;
+ u32 rot_angle;
int ret;
s6 = devm_kzalloc(dev, sizeof(struct s6d16d0), GFP_KERNEL);
@@ -215,6 +246,11 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi)
return ret;
}
+ /* Support rotation of the display panel */
+ ret = of_property_read_u32(dev->of_node, "rotation", _angle);
+ if (!ret && (rot_angle == 90 || rot_angle == 270))
+ s6->flipped = true;
+
drm_panel_init(>panel);
s6->panel.dev = dev;
s6->panel.funcs = _drm_funcs;
--
2.21.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel