All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
@ 2017-11-25 17:33 ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Hi All,

Here is v6 of my series to add a "panel orientation" property to
the drm-connector for the LCD panel to let userspace know about LCD
panels which are not mounted upright, as well as detecting upside-down
panels without needing quirks (like we do for 90 degree rotated screens).

Bartlomiej, can we please have your Acked-by for merging patches 1,
6 and 7 through the drm tree?

New in v6:
-Fix / reference kernel-doc comments
-Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
-Move i915 dsi hardware rotation state read-out to intel_dsi_init()

New in v5:
-Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
-drm_fb_helper: Only use hardware (crtc primary plane) rotation for
 180 degrees for now as 9-/270 degrees rotation requires special handling

New in v4:
-Fix drm_fb_helper code setting an invalid rotation value on the primary
 plane of disabled/unused crtcs (caught by Fi.CI)

New in v3:
-As requested by Daniel v3 moves the quirks over from the fbdev
 subsys to the drm subsys. I've done this by simpy starting with a copy of
 the quirk table and eventually removing the fbdev version.

The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
discussed previously the plan is to merge all 7 patches through the
drm tree.

Regards,

Hans


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

* [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
@ 2017-11-25 17:33 ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Hi All,

Here is v6 of my series to add a "panel orientation" property to
the drm-connector for the LCD panel to let userspace know about LCD
panels which are not mounted upright, as well as detecting upside-down
panels without needing quirks (like we do for 90 degree rotated screens).

Bartlomiej, can we please have your Acked-by for merging patches 1,
6 and 7 through the drm tree?

New in v6:
-Fix / reference kernel-doc comments
-Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
-Move i915 dsi hardware rotation state read-out to intel_dsi_init()

New in v5:
-Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
-drm_fb_helper: Only use hardware (crtc primary plane) rotation for
 180 degrees for now as 9-/270 degrees rotation requires special handling

New in v4:
-Fix drm_fb_helper code setting an invalid rotation value on the primary
 plane of disabled/unused crtcs (caught by Fi.CI)

New in v3:
-As requested by Daniel v3 moves the quirks over from the fbdev
 subsys to the drm subsys. I've done this by simpy starting with a copy of
 the quirk table and eventually removing the fbdev version.

The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
discussed previously the plan is to merge all 7 patches through the
drm tree.

Regards,

Hans

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 1/7] fbcon: Add fbcon_rotate_hint to struct fb_info
  2017-11-25 17:33 ` Hans de Goede
@ 2017-11-25 17:33   ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some hardware the LCD panel is not mounted upright in the casing,
but upside-down or rotated 90 degrees. In this case we want the console
to automatically be rotated to compensate.

The fbdev-driver may know about the need to rotate. Add a new
fbcon_rotate_hint field to struct fb_info, which gets initialized to -1.
If the fbdev-driver knows that some sort of rotation is necessary then
it can set this field to a FB_ROTATE_* value to tell the fbcon console
driver to rotate the console.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/core/fbcon.c   | 18 ++++++++++++------
 drivers/video/fbdev/core/fbsysfs.c |  1 +
 include/linux/fb.h                 |  5 +++++
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 929ca472c524..30014e5867db 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -964,10 +964,13 @@ static const char *fbcon_startup(void)
 	ops->cur_blink_jiffies = HZ / 5;
 	ops->info = info;
 	info->fbcon_par = ops;
-	if (initial_rotation != -1)
-		p->con_rotate = initial_rotation;
-	else
+
+	p->con_rotate = initial_rotation;
+	if (p->con_rotate = -1)
+		p->con_rotate = info->fbcon_rotate_hint;
+	if (p->con_rotate = -1)
 		p->con_rotate = fbcon_platform_get_rotate(info);
+
 	set_blitting_type(vc, info);
 
 	if (info->fix.type != FB_TYPE_TEXT) {
@@ -1104,10 +1107,13 @@ static void fbcon_init(struct vc_data *vc, int init)
 
 	ops = info->fbcon_par;
 	ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
-	if (initial_rotation != -1)
-		p->con_rotate = initial_rotation;
-	else
+
+	p->con_rotate = initial_rotation;
+	if (p->con_rotate = -1)
+		p->con_rotate = info->fbcon_rotate_hint;
+	if (p->con_rotate = -1)
 		p->con_rotate = fbcon_platform_get_rotate(info);
+
 	set_blitting_type(vc, info);
 
 	cols = vc->vc_cols;
diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c
index 15755ce1d26c..e31a182b42bf 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -58,6 +58,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
 		info->par = p + fb_info_size;
 
 	info->device = dev;
+	info->fbcon_rotate_hint = -1;
 
 #ifdef CONFIG_FB_BACKLIGHT
 	mutex_init(&info->bl_curve_mutex);
diff --git a/include/linux/fb.h b/include/linux/fb.h
index bc24e48e396d..d1e5bed39140 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -465,6 +465,11 @@ struct fb_info {
 	atomic_t count;
 	int node;
 	int flags;
+	/*
+	 * -1 by default, set to a FB_ROTATE_* value by the driver, if it knows
+	 * a lcd is not mounted upright and fbcon should rotate to compensate.
+	 */
+	int fbcon_rotate_hint;
 	struct mutex lock;		/* Lock for open/release/ioctl funcs */
 	struct mutex mm_lock;		/* Lock for fb_mmap and smem_* fields */
 	struct fb_var_screeninfo var;	/* Current var */
-- 
2.14.3


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

* [PATCH v6 1/7] fbcon: Add fbcon_rotate_hint to struct fb_info
@ 2017-11-25 17:33   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some hardware the LCD panel is not mounted upright in the casing,
but upside-down or rotated 90 degrees. In this case we want the console
to automatically be rotated to compensate.

The fbdev-driver may know about the need to rotate. Add a new
fbcon_rotate_hint field to struct fb_info, which gets initialized to -1.
If the fbdev-driver knows that some sort of rotation is necessary then
it can set this field to a FB_ROTATE_* value to tell the fbcon console
driver to rotate the console.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/core/fbcon.c   | 18 ++++++++++++------
 drivers/video/fbdev/core/fbsysfs.c |  1 +
 include/linux/fb.h                 |  5 +++++
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 929ca472c524..30014e5867db 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -964,10 +964,13 @@ static const char *fbcon_startup(void)
 	ops->cur_blink_jiffies = HZ / 5;
 	ops->info = info;
 	info->fbcon_par = ops;
-	if (initial_rotation != -1)
-		p->con_rotate = initial_rotation;
-	else
+
+	p->con_rotate = initial_rotation;
+	if (p->con_rotate == -1)
+		p->con_rotate = info->fbcon_rotate_hint;
+	if (p->con_rotate == -1)
 		p->con_rotate = fbcon_platform_get_rotate(info);
+
 	set_blitting_type(vc, info);
 
 	if (info->fix.type != FB_TYPE_TEXT) {
@@ -1104,10 +1107,13 @@ static void fbcon_init(struct vc_data *vc, int init)
 
 	ops = info->fbcon_par;
 	ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
-	if (initial_rotation != -1)
-		p->con_rotate = initial_rotation;
-	else
+
+	p->con_rotate = initial_rotation;
+	if (p->con_rotate == -1)
+		p->con_rotate = info->fbcon_rotate_hint;
+	if (p->con_rotate == -1)
 		p->con_rotate = fbcon_platform_get_rotate(info);
+
 	set_blitting_type(vc, info);
 
 	cols = vc->vc_cols;
diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c
index 15755ce1d26c..e31a182b42bf 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -58,6 +58,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
 		info->par = p + fb_info_size;
 
 	info->device = dev;
+	info->fbcon_rotate_hint = -1;
 
 #ifdef CONFIG_FB_BACKLIGHT
 	mutex_init(&info->bl_curve_mutex);
diff --git a/include/linux/fb.h b/include/linux/fb.h
index bc24e48e396d..d1e5bed39140 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -465,6 +465,11 @@ struct fb_info {
 	atomic_t count;
 	int node;
 	int flags;
+	/*
+	 * -1 by default, set to a FB_ROTATE_* value by the driver, if it knows
+	 * a lcd is not mounted upright and fbcon should rotate to compensate.
+	 */
+	int fbcon_rotate_hint;
 	struct mutex lock;		/* Lock for open/release/ioctl funcs */
 	struct mutex mm_lock;		/* Lock for fb_mmap and smem_* fields */
 	struct fb_var_screeninfo var;	/* Current var */
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 2/7] drm: Add panel orientation quirks, v6.
  2017-11-25 17:33 ` Hans de Goede
@ 2017-11-25 17:33   ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Some x86 clamshell design devices use portrait tablet screens and a display
engine which cannot rotate in hardware, so the firmware just leaves things
as is and we cannot figure out that the display is oriented non upright
from the hardware.

So at least on x86, we need a quirk table for this. This commit adds a DMI
based quirk table which is initially populated with 5 such devices: Asus
T100HA, GPD Pocket, GPD win, I.T.Works TW891 and the VIOS LTH17.

This quirk table will be used by the drm code to let userspace know that
the display is not mounted upright inside the devices case through a new
panel orientation drm-connector property, as well as to tell fbcon to
rotate the console so that it shows the right way up.

Changes in v5:
-Add a kernel-doc comment documenting drm_get_panel_orientation_quirk()
-Remove board_* matches from the dmi-matches for the VIOS LTH17 laptop,
 keeping only the (identical) sys_vendor and product_name matches.
 This is necessary because an older version of the bios has
 board_vendor set to VOIS instead of VIOS

Changes in v6:
-Add reference to added kernel-docs in Documentation/gpu/drm-kms-helpers.rst

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 Documentation/gpu/drm-kms-helpers.rst          |   3 +
 drivers/gpu/drm/Kconfig                        |   3 +
 drivers/gpu/drm/Makefile                       |   1 +
 drivers/gpu/drm/drm_panel_orientation_quirks.c | 174 +++++++++++++++++++++++++
 include/drm/drm_utils.h                        |  18 +++
 5 files changed, 199 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_panel_orientation_quirks.c
 create mode 100644 include/drm/drm_utils.h

diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 13dd237418cc..3ea622876b67 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -163,6 +163,9 @@ Panel Helper Reference
 .. kernel-doc:: drivers/gpu/drm/drm_panel.c
    :export:
 
+.. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
+   :export:
+
 Display Port Helper Functions Reference
 =================== 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 4d9f21831741..9d005ac98c2b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -26,6 +26,9 @@ config DRM_MIPI_DSI
 	bool
 	depends on DRM
 
+config DRM_PANEL_ORIENTATION_QUIRKS
+	tristate
+
 config DRM_DP_AUX_CHARDEV
 	bool "DRM DP AUX Interface"
 	depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e9500844333e..e5bf68b9c171 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/
 
 obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
+obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
 obj-$(CONFIG_DRM_ARM)	+= arm/
 obj-$(CONFIG_DRM_TTM)	+= ttm/
 obj-$(CONFIG_DRM_TDFX)	+= tdfx/
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
new file mode 100644
index 000000000000..b8765e2ed1d6
--- /dev/null
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -0,0 +1,174 @@
+/*
+ *  drm_panel_orientation_quirks.c -- Quirks for non-normal panel orientation
+ *
+ *	Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/dmi.h>
+#include <drm/drm_connector.h>
+
+#ifdef CONFIG_DMI
+
+/*
+ * Some x86 clamshell design devices use portrait tablet screens and a display
+ * engine which cannot rotate in hardware, so we need to rotate the fbcon to
+ * compensate. Unfortunately these (cheap) devices also typically have quite
+ * generic DMI data, so we match on a combination of DMI data, screen resolution
+ * and a list of known BIOS dates to avoid false positives.
+ */
+
+struct drm_dmi_panel_orientation_data {
+	int width;
+	int height;
+	const char * const *bios_dates;
+	int orientation;
+};
+
+static const struct drm_dmi_panel_orientation_data asus_t100ha = {
+	.width = 800,
+	.height = 1280,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data gpd_pocket = {
+	.width = 1200,
+	.height = 1920,
+	.bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
+		"07/05/2017", "08/07/2017", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data gpd_win = {
+	.width = 720,
+	.height = 1280,
+	.bios_dates = (const char * const []){
+		"10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
+		"02/21/2017", "03/20/2017", "05/25/2017", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data itworks_tw891 = {
+	.width = 800,
+	.height = 1280,
+	.bios_dates = (const char * const []){ "10/16/2015", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data vios_lth17 = {
+	.width = 800,
+	.height = 1280,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct dmi_system_id orientation_data[] = {
+	{	/* Asus T100HA */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
+		},
+		.driver_data = (void *)&asus_t100ha,
+	}, {	/*
+		 * GPD Pocket, note that the the DMI data is less generic then
+		 * it seems, devices with a board-vendor of "AMI Corporation"
+		 * are quite rare, as are devices which have both board- *and*
+		 * product-id set to "Default String"
+		 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+		.driver_data = (void *)&gpd_pocket,
+	}, {	/* GPD Win (same note on DMI match as GPD Pocket) */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+		.driver_data = (void *)&gpd_win,
+	}, {	/* I.T.Works TW891 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
+		},
+		.driver_data = (void *)&itworks_tw891,
+	}, {	/* VIOS LTH17 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
+		},
+		.driver_data = (void *)&vios_lth17,
+	},
+	{}
+};
+
+/**
+ * drm_get_panel_orientation_quirk - Check for panel orientation quirks
+ * @width: width in pixels of the panel
+ * @height: height in pixels of the panel
+ *
+ * This function checks for platform specific (e.g. DMI based) quirks
+ * providing info on panel_orientation for systems where this cannot be
+ * probed from the hard-/firm-ware. To avoid false-positive this function
+ * takes the panel resolution as argument and checks that against the
+ * resolution expected by the quirk-table entry.
+ *
+ * Note this function is also used outside of the drm-subsys, by for example
+ * the efifb code. Because of this this function gets compiled into its own
+ * kernel-module when built as a module.
+ *
+ * Returns:
+ * A DRM_MODE_PANEL_ORIENTATION_* value if there is a quirk for this system,
+ * or DRM_MODE_PANEL_ORIENTATION_UNKNOWN if there is no quirk.
+ */
+int drm_get_panel_orientation_quirk(int width, int height)
+{
+	const struct dmi_system_id *match;
+	const struct drm_dmi_panel_orientation_data *data;
+	const char *bios_date;
+	int i;
+
+	for (match = dmi_first_match(orientation_data);
+	     match;
+	     match = dmi_first_match(match + 1)) {
+		data = match->driver_data;
+
+		if (data->width != width ||
+		    data->height != height)
+			continue;
+
+		if (!data->bios_dates)
+			return data->orientation;
+
+		bios_date = dmi_get_system_info(DMI_BIOS_DATE);
+		if (!bios_date)
+			continue;
+
+		for (i = 0; data->bios_dates[i]; i++) {
+			if (!strcmp(data->bios_dates[i], bios_date))
+				return data->orientation;
+		}
+	}
+
+	return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+}
+EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
+
+#else
+
+/* There are no quirks for non x86 devices yet */
+int drm_get_panel_orientation_quirk(int width, int height)
+{
+	return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+}
+EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
+
+#endif
diff --git a/include/drm/drm_utils.h b/include/drm/drm_utils.h
new file mode 100644
index 000000000000..cea362aeaffe
--- /dev/null
+++ b/include/drm/drm_utils.h
@@ -0,0 +1,18 @@
+/*
+ * Function prototypes for misc. drm utility functions.
+ * Specifically this file is for function prototypes for functions which
+ * may also be used outside of drm code (e.g. in fbdev drivers).
+ *
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRM_UTILS_H__
+#define __DRM_UTILS_H__
+
+int drm_get_panel_orientation_quirk(int width, int height);
+
+#endif
-- 
2.14.3


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

* [PATCH v6 2/7] drm: Add panel orientation quirks, v6.
@ 2017-11-25 17:33   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Some x86 clamshell design devices use portrait tablet screens and a display
engine which cannot rotate in hardware, so the firmware just leaves things
as is and we cannot figure out that the display is oriented non upright
from the hardware.

So at least on x86, we need a quirk table for this. This commit adds a DMI
based quirk table which is initially populated with 5 such devices: Asus
T100HA, GPD Pocket, GPD win, I.T.Works TW891 and the VIOS LTH17.

This quirk table will be used by the drm code to let userspace know that
the display is not mounted upright inside the devices case through a new
panel orientation drm-connector property, as well as to tell fbcon to
rotate the console so that it shows the right way up.

Changes in v5:
-Add a kernel-doc comment documenting drm_get_panel_orientation_quirk()
-Remove board_* matches from the dmi-matches for the VIOS LTH17 laptop,
 keeping only the (identical) sys_vendor and product_name matches.
 This is necessary because an older version of the bios has
 board_vendor set to VOIS instead of VIOS

Changes in v6:
-Add reference to added kernel-docs in Documentation/gpu/drm-kms-helpers.rst

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 Documentation/gpu/drm-kms-helpers.rst          |   3 +
 drivers/gpu/drm/Kconfig                        |   3 +
 drivers/gpu/drm/Makefile                       |   1 +
 drivers/gpu/drm/drm_panel_orientation_quirks.c | 174 +++++++++++++++++++++++++
 include/drm/drm_utils.h                        |  18 +++
 5 files changed, 199 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_panel_orientation_quirks.c
 create mode 100644 include/drm/drm_utils.h

diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 13dd237418cc..3ea622876b67 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -163,6 +163,9 @@ Panel Helper Reference
 .. kernel-doc:: drivers/gpu/drm/drm_panel.c
    :export:
 
+.. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
+   :export:
+
 Display Port Helper Functions Reference
 =======================================
 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 4d9f21831741..9d005ac98c2b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -26,6 +26,9 @@ config DRM_MIPI_DSI
 	bool
 	depends on DRM
 
+config DRM_PANEL_ORIENTATION_QUIRKS
+	tristate
+
 config DRM_DP_AUX_CHARDEV
 	bool "DRM DP AUX Interface"
 	depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e9500844333e..e5bf68b9c171 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/
 
 obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
+obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
 obj-$(CONFIG_DRM_ARM)	+= arm/
 obj-$(CONFIG_DRM_TTM)	+= ttm/
 obj-$(CONFIG_DRM_TDFX)	+= tdfx/
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
new file mode 100644
index 000000000000..b8765e2ed1d6
--- /dev/null
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -0,0 +1,174 @@
+/*
+ *  drm_panel_orientation_quirks.c -- Quirks for non-normal panel orientation
+ *
+ *	Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/dmi.h>
+#include <drm/drm_connector.h>
+
+#ifdef CONFIG_DMI
+
+/*
+ * Some x86 clamshell design devices use portrait tablet screens and a display
+ * engine which cannot rotate in hardware, so we need to rotate the fbcon to
+ * compensate. Unfortunately these (cheap) devices also typically have quite
+ * generic DMI data, so we match on a combination of DMI data, screen resolution
+ * and a list of known BIOS dates to avoid false positives.
+ */
+
+struct drm_dmi_panel_orientation_data {
+	int width;
+	int height;
+	const char * const *bios_dates;
+	int orientation;
+};
+
+static const struct drm_dmi_panel_orientation_data asus_t100ha = {
+	.width = 800,
+	.height = 1280,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data gpd_pocket = {
+	.width = 1200,
+	.height = 1920,
+	.bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
+		"07/05/2017", "08/07/2017", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data gpd_win = {
+	.width = 720,
+	.height = 1280,
+	.bios_dates = (const char * const []){
+		"10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
+		"02/21/2017", "03/20/2017", "05/25/2017", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data itworks_tw891 = {
+	.width = 800,
+	.height = 1280,
+	.bios_dates = (const char * const []){ "10/16/2015", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data vios_lth17 = {
+	.width = 800,
+	.height = 1280,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct dmi_system_id orientation_data[] = {
+	{	/* Asus T100HA */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
+		},
+		.driver_data = (void *)&asus_t100ha,
+	}, {	/*
+		 * GPD Pocket, note that the the DMI data is less generic then
+		 * it seems, devices with a board-vendor of "AMI Corporation"
+		 * are quite rare, as are devices which have both board- *and*
+		 * product-id set to "Default String"
+		 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+		.driver_data = (void *)&gpd_pocket,
+	}, {	/* GPD Win (same note on DMI match as GPD Pocket) */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+		.driver_data = (void *)&gpd_win,
+	}, {	/* I.T.Works TW891 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
+		},
+		.driver_data = (void *)&itworks_tw891,
+	}, {	/* VIOS LTH17 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
+		},
+		.driver_data = (void *)&vios_lth17,
+	},
+	{}
+};
+
+/**
+ * drm_get_panel_orientation_quirk - Check for panel orientation quirks
+ * @width: width in pixels of the panel
+ * @height: height in pixels of the panel
+ *
+ * This function checks for platform specific (e.g. DMI based) quirks
+ * providing info on panel_orientation for systems where this cannot be
+ * probed from the hard-/firm-ware. To avoid false-positive this function
+ * takes the panel resolution as argument and checks that against the
+ * resolution expected by the quirk-table entry.
+ *
+ * Note this function is also used outside of the drm-subsys, by for example
+ * the efifb code. Because of this this function gets compiled into its own
+ * kernel-module when built as a module.
+ *
+ * Returns:
+ * A DRM_MODE_PANEL_ORIENTATION_* value if there is a quirk for this system,
+ * or DRM_MODE_PANEL_ORIENTATION_UNKNOWN if there is no quirk.
+ */
+int drm_get_panel_orientation_quirk(int width, int height)
+{
+	const struct dmi_system_id *match;
+	const struct drm_dmi_panel_orientation_data *data;
+	const char *bios_date;
+	int i;
+
+	for (match = dmi_first_match(orientation_data);
+	     match;
+	     match = dmi_first_match(match + 1)) {
+		data = match->driver_data;
+
+		if (data->width != width ||
+		    data->height != height)
+			continue;
+
+		if (!data->bios_dates)
+			return data->orientation;
+
+		bios_date = dmi_get_system_info(DMI_BIOS_DATE);
+		if (!bios_date)
+			continue;
+
+		for (i = 0; data->bios_dates[i]; i++) {
+			if (!strcmp(data->bios_dates[i], bios_date))
+				return data->orientation;
+		}
+	}
+
+	return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+}
+EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
+
+#else
+
+/* There are no quirks for non x86 devices yet */
+int drm_get_panel_orientation_quirk(int width, int height)
+{
+	return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+}
+EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
+
+#endif
diff --git a/include/drm/drm_utils.h b/include/drm/drm_utils.h
new file mode 100644
index 000000000000..cea362aeaffe
--- /dev/null
+++ b/include/drm/drm_utils.h
@@ -0,0 +1,18 @@
+/*
+ * Function prototypes for misc. drm utility functions.
+ * Specifically this file is for function prototypes for functions which
+ * may also be used outside of drm code (e.g. in fbdev drivers).
+ *
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRM_UTILS_H__
+#define __DRM_UTILS_H__
+
+int drm_get_panel_orientation_quirk(int width, int height);
+
+#endif
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 3/7] drm: Add support for a panel-orientation connector property, v6
  2017-11-25 17:33 ` Hans de Goede
@ 2017-11-25 17:33   ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some devices the LCD panel is mounted in the casing in such a way that
the up/top side of the panel does not match with the top side of the
device (e.g. it is mounted upside-down).

This commit adds the necessary infra for lcd-panel drm_connector-s to
have a "panel orientation" property to communicate how the panel is
orientated vs the casing.

Userspace can use this property to check for non-normal orientation and
then adjust the displayed image accordingly by rotating it to compensate.

Changes in v2:
-Store panel_orientation in drm_display_info, so that drm_fb_helper.c can
 access it easily
-Have a single drm_connector_init_panel_orientation_property rather then
 create and attach functions. The caller is expected to set
 drm_display_info.panel_orientation before calling this, then this will
 check for platform specific quirks overriding the panel_orientation and if
 the panel_orientation is set after this then it will attach the property.

Changes in v6:
-Use an enum (with kerneldoc) rather then #defines for
 DRM_MODE_PANEL_ORIENTATION_*

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/Kconfig         |  1 +
 drivers/gpu/drm/drm_connector.c | 73 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     | 40 ++++++++++++++++++++++
 include/drm/drm_mode_config.h   |  7 ++++
 4 files changed, 121 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 9d005ac98c2b..0b166e626eb6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -7,6 +7,7 @@
 menuconfig DRM
 	tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
 	depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select HDMI
 	select FB_CMDLINE
 	select I2C
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 25f4b2e9a44f..624edeb5c50d 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -24,6 +24,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
+#include <drm/drm_utils.h>
 
 #include "drm_crtc_internal.h"
 #include "drm_internal.h"
@@ -212,6 +213,8 @@ int drm_connector_init(struct drm_device *dev,
 	mutex_init(&connector->mutex);
 	connector->edid_blob_ptr = NULL;
 	connector->status = connector_status_unknown;
+	connector->display_info.panel_orientation +		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
 
 	drm_connector_get_cmdline_mode(connector);
 
@@ -668,6 +671,13 @@ static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
 	{ DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
 };
 
+static const struct drm_prop_enum_list drm_panel_orientation_enum_list[] = {
+	{ DRM_MODE_PANEL_ORIENTATION_NORMAL,	"Normal"	},
+	{ DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,	"Upside Down"	},
+	{ DRM_MODE_PANEL_ORIENTATION_LEFT_UP,	"Left Side Up"	},
+	{ DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,	"Right Side Up"	},
+};
+
 static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
 	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
 	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
@@ -776,6 +786,18 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
  *
  * CRTC_ID:
  * 	Mode object ID of the &drm_crtc this connector should be connected to.
+ *
+ * Connectors for LCD panels may also have one standardized property:
+ *
+ * panel orientation:
+ *	On some devices the LCD panel is mounted in the casing in such a way
+ *	that the up/top side of the panel does not match with the top side of
+ *	the device. Userspace can use this property to check for this.
+ *	Note that input coordinates from touchscreens (input devices with
+ *	INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel
+ *	coordinates, so if userspace rotates the picture to adjust for
+ *	the orientation it must also apply the same transformation to the
+ *	touchscreen input coordinates.
  */
 
 int drm_connector_create_standard_properties(struct drm_device *dev)
@@ -1251,6 +1273,57 @@ void drm_mode_connector_set_link_status_property(struct drm_connector *connector
 }
 EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
 
+/**
+ * drm_connector_init_panel_orientation_property -
+ *	initialize the connecters panel_orientation property
+ * @connector: connector for which to init the panel-orientation property.
+ * @width: width in pixels of the panel, used for panel quirk detection
+ * @height: height in pixels of the panel, used for panel quirk detection
+ *
+ * This function should only be called for built-in panels, after setting
+ * connector->display_info.panel_orientation first (if known).
+ *
+ * This function will check for platform specific (e.g. DMI based) quirks
+ * overriding display_info.panel_orientation first, then if panel_orientation
+ * is not DRM_MODE_PANEL_ORIENTATION_UNKNOWN it will attach the
+ * "panel orientation" property to the connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_init_panel_orientation_property(
+	struct drm_connector *connector, int width, int height)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_display_info *info = &connector->display_info;
+	struct drm_property *prop;
+	int orientation_quirk;
+
+	orientation_quirk = drm_get_panel_orientation_quirk(width, height);
+	if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
+		info->panel_orientation = orientation_quirk;
+
+	if (info->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
+		return 0;
+
+	prop = dev->mode_config.panel_orientation_property;
+	if (!prop) {
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
+				"panel orientation",
+				drm_panel_orientation_enum_list,
+				ARRAY_SIZE(drm_panel_orientation_enum_list));
+		if (!prop)
+			return -ENOMEM;
+
+		dev->mode_config.panel_orientation_property = prop;
+	}
+
+	drm_object_attach_property(&connector->base, prop,
+				   info->panel_orientation);
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
+
 int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index df9807a3caae..51365551a57f 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -175,6 +175,35 @@ enum drm_link_status {
 	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
 };
 
+/**
+ * enum drm_panel_orientation - panel_orientation info for &drm_display_info
+ *
+ * This enum is used to track the (LCD) panel orientation. There are no
+ * separate #defines for the uapi!
+ *
+ * @DRM_MODE_PANEL_ORIENTATION_UNKNOWN: The drm driver has not provided any
+ *					panel orientation information (normal
+ *					for non panels) in this case the "panel
+ *					orientation" connector prop will not be
+ *					attached.
+ * @DRM_MODE_PANEL_ORIENTATION_NORMAL:	The top side of the panel matches the
+ *					top side of the device's casing.
+ * @DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: The top side of the panel matches the
+ *					bottom side of the device's casing, iow
+ *					the panel is mounted upside-down.
+ * @DRM_MODE_PANEL_ORIENTATION_LEFT_UP:	The left side of the panel matches the
+ *					top side of the device's casing.
+ * @DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: The right side of the panel matches the
+ *					top side of the device's casing.
+ */
+enum drm_panel_orientation {
+	DRM_MODE_PANEL_ORIENTATION_UNKNOWN = -1,
+	DRM_MODE_PANEL_ORIENTATION_NORMAL = 0,
+	DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,
+	DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
+	DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
 /**
  * struct drm_display_info - runtime data about the connected sink
  *
@@ -222,6 +251,15 @@ struct drm_display_info {
 #define DRM_COLOR_FORMAT_YCRCB422	(1<<2)
 #define DRM_COLOR_FORMAT_YCRCB420	(1<<3)
 
+	/**
+	 * @panel_orientation: Read only connector property for built-in panels,
+	 * indicating the orientation of the panel vs the device's casing.
+	 * drm_connector_init() sets this to DRM_MODE_PANEL_ORIENTATION_UNKNOWN.
+	 * When not UNKNOWN this gets used by the drm_fb_helpers to rotate the
+	 * fb to compensate and gets exported as prop to userspace.
+	 */
+	int panel_orientation;
+
 	/**
 	 * @color_formats: HDMI Color formats, selects between RGB and YCrCb
 	 * modes. Used DRM_COLOR_FORMAT\_ defines, which are _not_ the same ones
@@ -1025,6 +1063,8 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 					    const struct edid *edid);
 void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
 						 uint64_t link_status);
+int drm_connector_init_panel_orientation_property(
+	struct drm_connector *connector, int width, int height);
 
 /**
  * struct drm_tile_group - Tile group metadata
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index b21e827c5c78..3716e6b8fed5 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -735,6 +735,13 @@ struct drm_mode_config {
 	 */
 	struct drm_property *non_desktop_property;
 
+	/**
+	 * @panel_orientation_property: Optional connector property indicating
+	 * how the lcd-panel is mounted inside the casing (e.g. normal or
+	 * upside-down).
+	 */
+	struct drm_property *panel_orientation_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
-- 
2.14.3


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

* [PATCH v6 3/7] drm: Add support for a panel-orientation connector property, v6
@ 2017-11-25 17:33   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some devices the LCD panel is mounted in the casing in such a way that
the up/top side of the panel does not match with the top side of the
device (e.g. it is mounted upside-down).

This commit adds the necessary infra for lcd-panel drm_connector-s to
have a "panel orientation" property to communicate how the panel is
orientated vs the casing.

Userspace can use this property to check for non-normal orientation and
then adjust the displayed image accordingly by rotating it to compensate.

Changes in v2:
-Store panel_orientation in drm_display_info, so that drm_fb_helper.c can
 access it easily
-Have a single drm_connector_init_panel_orientation_property rather then
 create and attach functions. The caller is expected to set
 drm_display_info.panel_orientation before calling this, then this will
 check for platform specific quirks overriding the panel_orientation and if
 the panel_orientation is set after this then it will attach the property.

Changes in v6:
-Use an enum (with kerneldoc) rather then #defines for
 DRM_MODE_PANEL_ORIENTATION_*

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/Kconfig         |  1 +
 drivers/gpu/drm/drm_connector.c | 73 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     | 40 ++++++++++++++++++++++
 include/drm/drm_mode_config.h   |  7 ++++
 4 files changed, 121 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 9d005ac98c2b..0b166e626eb6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -7,6 +7,7 @@
 menuconfig DRM
 	tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
 	depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select HDMI
 	select FB_CMDLINE
 	select I2C
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 25f4b2e9a44f..624edeb5c50d 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -24,6 +24,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
+#include <drm/drm_utils.h>
 
 #include "drm_crtc_internal.h"
 #include "drm_internal.h"
@@ -212,6 +213,8 @@ int drm_connector_init(struct drm_device *dev,
 	mutex_init(&connector->mutex);
 	connector->edid_blob_ptr = NULL;
 	connector->status = connector_status_unknown;
+	connector->display_info.panel_orientation =
+		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
 
 	drm_connector_get_cmdline_mode(connector);
 
@@ -668,6 +671,13 @@ static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
 	{ DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
 };
 
+static const struct drm_prop_enum_list drm_panel_orientation_enum_list[] = {
+	{ DRM_MODE_PANEL_ORIENTATION_NORMAL,	"Normal"	},
+	{ DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,	"Upside Down"	},
+	{ DRM_MODE_PANEL_ORIENTATION_LEFT_UP,	"Left Side Up"	},
+	{ DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,	"Right Side Up"	},
+};
+
 static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
 	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
 	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
@@ -776,6 +786,18 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
  *
  * CRTC_ID:
  * 	Mode object ID of the &drm_crtc this connector should be connected to.
+ *
+ * Connectors for LCD panels may also have one standardized property:
+ *
+ * panel orientation:
+ *	On some devices the LCD panel is mounted in the casing in such a way
+ *	that the up/top side of the panel does not match with the top side of
+ *	the device. Userspace can use this property to check for this.
+ *	Note that input coordinates from touchscreens (input devices with
+ *	INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel
+ *	coordinates, so if userspace rotates the picture to adjust for
+ *	the orientation it must also apply the same transformation to the
+ *	touchscreen input coordinates.
  */
 
 int drm_connector_create_standard_properties(struct drm_device *dev)
@@ -1251,6 +1273,57 @@ void drm_mode_connector_set_link_status_property(struct drm_connector *connector
 }
 EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
 
+/**
+ * drm_connector_init_panel_orientation_property -
+ *	initialize the connecters panel_orientation property
+ * @connector: connector for which to init the panel-orientation property.
+ * @width: width in pixels of the panel, used for panel quirk detection
+ * @height: height in pixels of the panel, used for panel quirk detection
+ *
+ * This function should only be called for built-in panels, after setting
+ * connector->display_info.panel_orientation first (if known).
+ *
+ * This function will check for platform specific (e.g. DMI based) quirks
+ * overriding display_info.panel_orientation first, then if panel_orientation
+ * is not DRM_MODE_PANEL_ORIENTATION_UNKNOWN it will attach the
+ * "panel orientation" property to the connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_init_panel_orientation_property(
+	struct drm_connector *connector, int width, int height)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_display_info *info = &connector->display_info;
+	struct drm_property *prop;
+	int orientation_quirk;
+
+	orientation_quirk = drm_get_panel_orientation_quirk(width, height);
+	if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
+		info->panel_orientation = orientation_quirk;
+
+	if (info->panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
+		return 0;
+
+	prop = dev->mode_config.panel_orientation_property;
+	if (!prop) {
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
+				"panel orientation",
+				drm_panel_orientation_enum_list,
+				ARRAY_SIZE(drm_panel_orientation_enum_list));
+		if (!prop)
+			return -ENOMEM;
+
+		dev->mode_config.panel_orientation_property = prop;
+	}
+
+	drm_object_attach_property(&connector->base, prop,
+				   info->panel_orientation);
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
+
 int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index df9807a3caae..51365551a57f 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -175,6 +175,35 @@ enum drm_link_status {
 	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
 };
 
+/**
+ * enum drm_panel_orientation - panel_orientation info for &drm_display_info
+ *
+ * This enum is used to track the (LCD) panel orientation. There are no
+ * separate #defines for the uapi!
+ *
+ * @DRM_MODE_PANEL_ORIENTATION_UNKNOWN: The drm driver has not provided any
+ *					panel orientation information (normal
+ *					for non panels) in this case the "panel
+ *					orientation" connector prop will not be
+ *					attached.
+ * @DRM_MODE_PANEL_ORIENTATION_NORMAL:	The top side of the panel matches the
+ *					top side of the device's casing.
+ * @DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: The top side of the panel matches the
+ *					bottom side of the device's casing, iow
+ *					the panel is mounted upside-down.
+ * @DRM_MODE_PANEL_ORIENTATION_LEFT_UP:	The left side of the panel matches the
+ *					top side of the device's casing.
+ * @DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: The right side of the panel matches the
+ *					top side of the device's casing.
+ */
+enum drm_panel_orientation {
+	DRM_MODE_PANEL_ORIENTATION_UNKNOWN = -1,
+	DRM_MODE_PANEL_ORIENTATION_NORMAL = 0,
+	DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,
+	DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
+	DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
 /**
  * struct drm_display_info - runtime data about the connected sink
  *
@@ -222,6 +251,15 @@ struct drm_display_info {
 #define DRM_COLOR_FORMAT_YCRCB422	(1<<2)
 #define DRM_COLOR_FORMAT_YCRCB420	(1<<3)
 
+	/**
+	 * @panel_orientation: Read only connector property for built-in panels,
+	 * indicating the orientation of the panel vs the device's casing.
+	 * drm_connector_init() sets this to DRM_MODE_PANEL_ORIENTATION_UNKNOWN.
+	 * When not UNKNOWN this gets used by the drm_fb_helpers to rotate the
+	 * fb to compensate and gets exported as prop to userspace.
+	 */
+	int panel_orientation;
+
 	/**
 	 * @color_formats: HDMI Color formats, selects between RGB and YCrCb
 	 * modes. Used DRM_COLOR_FORMAT\_ defines, which are _not_ the same ones
@@ -1025,6 +1063,8 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 					    const struct edid *edid);
 void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
 						 uint64_t link_status);
+int drm_connector_init_panel_orientation_property(
+	struct drm_connector *connector, int width, int height);
 
 /**
  * struct drm_tile_group - Tile group metadata
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index b21e827c5c78..3716e6b8fed5 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -735,6 +735,13 @@ struct drm_mode_config {
 	 */
 	struct drm_property *non_desktop_property;
 
+	/**
+	 * @panel_orientation_property: Optional connector property indicating
+	 * how the lcd-panel is mounted inside the casing (e.g. normal or
+	 * upside-down).
+	 */
+	struct drm_property *panel_orientation_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 4/7] drm/fb-helper: Apply panel orientation connector prop to the primary plane, v6.
  2017-11-25 17:33 ` Hans de Goede
@ 2017-11-25 17:33   ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Apply the "panel orientation" drm connector prop to the primary plane so
that fbcon and fbdev using userspace programs display the right way up.

Changes in v3:
-Use a rotation member in struct drm_fb_helper_crtc and set that from
 drm_setup_crtcs instead of looping over all crtc's to find the right one
 later
-Since we now no longer look at rotation quirks directly in the fbcon
 code, set fb_info.fbcon_rotate_hint when the panel is not mounted upright
 and we cannot use hardware rotation

Changes in v4:
-Make drm_fb_helper_init() init drm_fb_helper_crtc.rotation to
 DRM_MODE_ROTATE_0 for all crtcs, so that we do not end up setting the
 plane_state's rotation to an invalid value for disabled crtcs
 (caught by Fi.CI)

Changes in v5:
-Only use hardware (crtc primary plane) rotation for DRM_ROTATE_180,
 90 / 270 degree rotation requires special handling which we lack atm
-Add a TODO comment for 90 / 270 degree hardware rotation
-Add some comments to better document the default case when mapping
 sw_rotations to fbcon_rotate_hints

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id”894
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/drm_fb_helper.c | 90 ++++++++++++++++++++++++++++++++++++++++-
 include/drm/drm_fb_helper.h     |  8 ++++
 2 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 07374008f146..3d20b77f3fb9 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -41,6 +41,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 
+#include "drm_crtc_internal.h"
 #include "drm_crtc_helper_internal.h"
 
 static bool drm_fbdev_emulation = true;
@@ -350,6 +351,7 @@ EXPORT_SYMBOL(drm_fb_helper_debug_leave);
 static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active)
 {
 	struct drm_device *dev = fb_helper->dev;
+	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	struct drm_atomic_state *state;
 	int i, ret;
@@ -368,8 +370,6 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 retry:
 	plane_mask = 0;
 	drm_for_each_plane(plane, dev) {
-		struct drm_plane_state *plane_state;
-
 		plane_state = drm_atomic_get_plane_state(state, plane);
 		if (IS_ERR(plane_state)) {
 			ret = PTR_ERR(plane_state);
@@ -392,6 +392,11 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
+		struct drm_plane *primary = mode_set->crtc->primary;
+
+		/* Cannot fail as we've already gotten the plane state above */
+		plane_state = drm_atomic_get_new_plane_state(state, primary);
+		plane_state->rotation = fb_helper->crtc_info[i].rotation;
 
 		ret = __drm_atomic_helper_set_config(mode_set, state);
 		if (ret != 0)
@@ -821,6 +826,7 @@ int drm_fb_helper_init(struct drm_device *dev,
 		if (!fb_helper->crtc_info[i].mode_set.connectors)
 			goto out_free;
 		fb_helper->crtc_info[i].mode_set.num_connectors = 0;
+		fb_helper->crtc_info[i].rotation = DRM_MODE_ROTATE_0;
 	}
 
 	i = 0;
@@ -2338,6 +2344,62 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
 	return best_score;
 }
 
+/*
+ * This function checks if rotation is necessary because of panel orientation
+ * and if it is, if it is supported.
+ * If rotation is necessary and supported, its gets set in fb_crtc.rotation.
+ * If rotation is necessary but not supported, a DRM_MODE_ROTATE_* flag gets
+ * or-ed into fb_helper->sw_rotations. In drm_setup_crtcs_fb() we check if only
+ * one bit is set and then we set fb_info.fbcon_rotate_hint to make fbcon do
+ * the unsupported rotation.
+ */
+static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper,
+				    struct drm_fb_helper_crtc *fb_crtc,
+				    struct drm_connector *connector)
+{
+	struct drm_plane *plane = fb_crtc->mode_set.crtc->primary;
+	uint64_t valid_mask = 0;
+	int i, rotation;
+
+	fb_crtc->rotation = DRM_MODE_ROTATE_0;
+
+	switch (connector->display_info.panel_orientation) {
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		rotation = DRM_MODE_ROTATE_180;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		rotation = DRM_MODE_ROTATE_90;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		rotation = DRM_MODE_ROTATE_270;
+		break;
+	default:
+		rotation = DRM_MODE_ROTATE_0;
+	}
+
+	/*
+	 * TODO: support 90 / 270 degree hardware rotation,
+	 * depending on the hardware this may require the framebuffer
+	 * to be in a specific tiling format.
+	 */
+	if (rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) {
+		fb_helper->sw_rotations |= rotation;
+		return;
+	}
+
+	for (i = 0; i < plane->rotation_property->num_values; i++)
+		valid_mask |= (1ULL << plane->rotation_property->values[i]);
+
+	if (!(rotation & valid_mask)) {
+		fb_helper->sw_rotations |= rotation;
+		return;
+	}
+
+	fb_crtc->rotation = rotation;
+	/* Rotating in hardware, fbcon should not rotate */
+	fb_helper->sw_rotations |= DRM_MODE_ROTATE_0;
+}
+
 static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			    u32 width, u32 height)
 {
@@ -2397,6 +2459,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 		drm_fb_helper_modeset_release(fb_helper,
 					      &fb_helper->crtc_info[i].mode_set);
 
+	fb_helper->sw_rotations = 0;
 	drm_fb_helper_for_each_connector(fb_helper, i) {
 		struct drm_display_mode *mode = modes[i];
 		struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
@@ -2416,6 +2479,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			modeset->mode = drm_mode_duplicate(dev,
 							   fb_crtc->desired_mode);
 			drm_connector_get(connector);
+			drm_setup_crtc_rotation(fb_helper, fb_crtc, connector);
 			modeset->connectors[modeset->num_connectors++] = connector;
 			modeset->x = offset->x;
 			modeset->y = offset->y;
@@ -2457,6 +2521,28 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
 		}
 	}
 	mutex_unlock(&fb_helper->dev->mode_config.mutex);
+
+	switch (fb_helper->sw_rotations) {
+	case DRM_MODE_ROTATE_0:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_ROTATE_90:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_ROTATE_180:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_ROTATE_270:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	default:
+		/*
+		 * Multiple bits are set / multiple rotations requested
+		 * fbcon cannot handle separate rotation settings per
+		 * output, so fallback to unrotated.
+		 */
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+	}
 }
 
 /* Note: Drops fb_helper->lock before returning. */
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 33fe95927742..d0667e4ba886 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -48,6 +48,7 @@ struct drm_fb_helper_crtc {
 	struct drm_mode_set mode_set;
 	struct drm_display_mode *desired_mode;
 	int x, y;
+	int rotation;
 };
 
 /**
@@ -158,6 +159,13 @@ struct drm_fb_helper {
 	struct drm_fb_helper_crtc *crtc_info;
 	int connector_count;
 	int connector_info_alloc_count;
+	/**
+	 * @sw_rotations:
+	 * Bitmask of all rotations requested for panel-orientation which
+	 * could not be handled in hardware. If only one bit is set
+	 * fbdev->fbcon_rotate_hint gets set to the requested rotation.
+	 */
+	int sw_rotations;
 	/**
 	 * @connector_info:
 	 *
-- 
2.14.3


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

* [PATCH v6 4/7] drm/fb-helper: Apply panel orientation connector prop to the primary plane, v6.
@ 2017-11-25 17:33   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Apply the "panel orientation" drm connector prop to the primary plane so
that fbcon and fbdev using userspace programs display the right way up.

Changes in v3:
-Use a rotation member in struct drm_fb_helper_crtc and set that from
 drm_setup_crtcs instead of looping over all crtc's to find the right one
 later
-Since we now no longer look at rotation quirks directly in the fbcon
 code, set fb_info.fbcon_rotate_hint when the panel is not mounted upright
 and we cannot use hardware rotation

Changes in v4:
-Make drm_fb_helper_init() init drm_fb_helper_crtc.rotation to
 DRM_MODE_ROTATE_0 for all crtcs, so that we do not end up setting the
 plane_state's rotation to an invalid value for disabled crtcs
 (caught by Fi.CI)

Changes in v5:
-Only use hardware (crtc primary plane) rotation for DRM_ROTATE_180,
 90 / 270 degree rotation requires special handling which we lack atm
-Add a TODO comment for 90 / 270 degree hardware rotation
-Add some comments to better document the default case when mapping
 sw_rotations to fbcon_rotate_hints

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=94894
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/drm_fb_helper.c | 90 ++++++++++++++++++++++++++++++++++++++++-
 include/drm/drm_fb_helper.h     |  8 ++++
 2 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 07374008f146..3d20b77f3fb9 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -41,6 +41,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 
+#include "drm_crtc_internal.h"
 #include "drm_crtc_helper_internal.h"
 
 static bool drm_fbdev_emulation = true;
@@ -350,6 +351,7 @@ EXPORT_SYMBOL(drm_fb_helper_debug_leave);
 static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active)
 {
 	struct drm_device *dev = fb_helper->dev;
+	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	struct drm_atomic_state *state;
 	int i, ret;
@@ -368,8 +370,6 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 retry:
 	plane_mask = 0;
 	drm_for_each_plane(plane, dev) {
-		struct drm_plane_state *plane_state;
-
 		plane_state = drm_atomic_get_plane_state(state, plane);
 		if (IS_ERR(plane_state)) {
 			ret = PTR_ERR(plane_state);
@@ -392,6 +392,11 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
+		struct drm_plane *primary = mode_set->crtc->primary;
+
+		/* Cannot fail as we've already gotten the plane state above */
+		plane_state = drm_atomic_get_new_plane_state(state, primary);
+		plane_state->rotation = fb_helper->crtc_info[i].rotation;
 
 		ret = __drm_atomic_helper_set_config(mode_set, state);
 		if (ret != 0)
@@ -821,6 +826,7 @@ int drm_fb_helper_init(struct drm_device *dev,
 		if (!fb_helper->crtc_info[i].mode_set.connectors)
 			goto out_free;
 		fb_helper->crtc_info[i].mode_set.num_connectors = 0;
+		fb_helper->crtc_info[i].rotation = DRM_MODE_ROTATE_0;
 	}
 
 	i = 0;
@@ -2338,6 +2344,62 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
 	return best_score;
 }
 
+/*
+ * This function checks if rotation is necessary because of panel orientation
+ * and if it is, if it is supported.
+ * If rotation is necessary and supported, its gets set in fb_crtc.rotation.
+ * If rotation is necessary but not supported, a DRM_MODE_ROTATE_* flag gets
+ * or-ed into fb_helper->sw_rotations. In drm_setup_crtcs_fb() we check if only
+ * one bit is set and then we set fb_info.fbcon_rotate_hint to make fbcon do
+ * the unsupported rotation.
+ */
+static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper,
+				    struct drm_fb_helper_crtc *fb_crtc,
+				    struct drm_connector *connector)
+{
+	struct drm_plane *plane = fb_crtc->mode_set.crtc->primary;
+	uint64_t valid_mask = 0;
+	int i, rotation;
+
+	fb_crtc->rotation = DRM_MODE_ROTATE_0;
+
+	switch (connector->display_info.panel_orientation) {
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		rotation = DRM_MODE_ROTATE_180;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		rotation = DRM_MODE_ROTATE_90;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		rotation = DRM_MODE_ROTATE_270;
+		break;
+	default:
+		rotation = DRM_MODE_ROTATE_0;
+	}
+
+	/*
+	 * TODO: support 90 / 270 degree hardware rotation,
+	 * depending on the hardware this may require the framebuffer
+	 * to be in a specific tiling format.
+	 */
+	if (rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) {
+		fb_helper->sw_rotations |= rotation;
+		return;
+	}
+
+	for (i = 0; i < plane->rotation_property->num_values; i++)
+		valid_mask |= (1ULL << plane->rotation_property->values[i]);
+
+	if (!(rotation & valid_mask)) {
+		fb_helper->sw_rotations |= rotation;
+		return;
+	}
+
+	fb_crtc->rotation = rotation;
+	/* Rotating in hardware, fbcon should not rotate */
+	fb_helper->sw_rotations |= DRM_MODE_ROTATE_0;
+}
+
 static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			    u32 width, u32 height)
 {
@@ -2397,6 +2459,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 		drm_fb_helper_modeset_release(fb_helper,
 					      &fb_helper->crtc_info[i].mode_set);
 
+	fb_helper->sw_rotations = 0;
 	drm_fb_helper_for_each_connector(fb_helper, i) {
 		struct drm_display_mode *mode = modes[i];
 		struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
@@ -2416,6 +2479,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			modeset->mode = drm_mode_duplicate(dev,
 							   fb_crtc->desired_mode);
 			drm_connector_get(connector);
+			drm_setup_crtc_rotation(fb_helper, fb_crtc, connector);
 			modeset->connectors[modeset->num_connectors++] = connector;
 			modeset->x = offset->x;
 			modeset->y = offset->y;
@@ -2457,6 +2521,28 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
 		}
 	}
 	mutex_unlock(&fb_helper->dev->mode_config.mutex);
+
+	switch (fb_helper->sw_rotations) {
+	case DRM_MODE_ROTATE_0:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_ROTATE_90:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_ROTATE_180:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_ROTATE_270:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	default:
+		/*
+		 * Multiple bits are set / multiple rotations requested
+		 * fbcon cannot handle separate rotation settings per
+		 * output, so fallback to unrotated.
+		 */
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+	}
 }
 
 /* Note: Drops fb_helper->lock before returning. */
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 33fe95927742..d0667e4ba886 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -48,6 +48,7 @@ struct drm_fb_helper_crtc {
 	struct drm_mode_set mode_set;
 	struct drm_display_mode *desired_mode;
 	int x, y;
+	int rotation;
 };
 
 /**
@@ -158,6 +159,13 @@ struct drm_fb_helper {
 	struct drm_fb_helper_crtc *crtc_info;
 	int connector_count;
 	int connector_info_alloc_count;
+	/**
+	 * @sw_rotations:
+	 * Bitmask of all rotations requested for panel-orientation which
+	 * could not be handled in hardware. If only one bit is set
+	 * fbdev->fbcon_rotate_hint gets set to the requested rotation.
+	 */
+	int sw_rotations;
 	/**
 	 * @connector_info:
 	 *
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6.
  2017-11-25 17:33 ` Hans de Goede
@ 2017-11-25 17:33   ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Ideally we could use the VBT for this, that would be simple, in
intel_dsi_init() check dev_priv->vbt.dsi.config->rotation, set
connector->display_info.panel_orientation accordingly and call
drm_connector_init_panel_orientation_property(), done.

Unfortunately vbt.dsi.config->rotation is always 0 even on tablets
with an upside down LCD and where the GOP is properly rotating the
EFI fb in hardware.

So instead we end up reading the rotation from the primary plane.

This commit only implements the panel orientation property for DSI
panels on BYT / CHT hardware, as all known non normal oriented panels
sofar are only found on this hardware.

Changes in v2:
-Read back the rotation applied by the GOP from the primary plane
 instead of relying on dev_priv->vbt.dsi.config->rotation, because it
 seems that the VBT rotation filed is always 0 even on devices where the
 GOP does apply a rotation

Changes in v3:
-Rewrite the code to read back the orientation from the primary
 plane to contain all of this in intel_dsi.c instead of poking a bunch
 of holes between all the different layers

Changes in v6:
-Move hardware readout to intel_dsi_init()

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/i915/intel_dsi.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index f09474b0c4d3..f67d321376e4 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1666,6 +1666,27 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
 	.atomic_duplicate_state = intel_digital_connector_duplicate_state,
 };
 
+static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
+	enum i9xx_plane_id plane;
+	u32 val;
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		if (connector->encoder->crtc_mask = BIT(PIPE_B))
+			plane = PLANE_B;
+		else
+			plane = PLANE_A;
+
+		val = I915_READ(DSPCNTR(plane));
+		if (val & DISPPLANE_ROTATE_180)
+			orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
+	}
+
+	return orientation;
+}
+
 static void intel_dsi_add_properties(struct intel_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1681,6 +1702,13 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
 								allowed_scalers);
 
 		connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
+
+		connector->base.display_info.panel_orientation +			intel_dsi_get_panel_orientation(connector);
+		drm_connector_init_panel_orientation_property(
+				&connector->base,
+				connector->panel.fixed_mode->hdisplay,
+				connector->panel.fixed_mode->vdisplay);
 	}
 }
 
-- 
2.14.3


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

* [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6.
@ 2017-11-25 17:33   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Ideally we could use the VBT for this, that would be simple, in
intel_dsi_init() check dev_priv->vbt.dsi.config->rotation, set
connector->display_info.panel_orientation accordingly and call
drm_connector_init_panel_orientation_property(), done.

Unfortunately vbt.dsi.config->rotation is always 0 even on tablets
with an upside down LCD and where the GOP is properly rotating the
EFI fb in hardware.

So instead we end up reading the rotation from the primary plane.

This commit only implements the panel orientation property for DSI
panels on BYT / CHT hardware, as all known non normal oriented panels
sofar are only found on this hardware.

Changes in v2:
-Read back the rotation applied by the GOP from the primary plane
 instead of relying on dev_priv->vbt.dsi.config->rotation, because it
 seems that the VBT rotation filed is always 0 even on devices where the
 GOP does apply a rotation

Changes in v3:
-Rewrite the code to read back the orientation from the primary
 plane to contain all of this in intel_dsi.c instead of poking a bunch
 of holes between all the different layers

Changes in v6:
-Move hardware readout to intel_dsi_init()

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/i915/intel_dsi.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index f09474b0c4d3..f67d321376e4 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1666,6 +1666,27 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
 	.atomic_duplicate_state = intel_digital_connector_duplicate_state,
 };
 
+static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
+	enum i9xx_plane_id plane;
+	u32 val;
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		if (connector->encoder->crtc_mask == BIT(PIPE_B))
+			plane = PLANE_B;
+		else
+			plane = PLANE_A;
+
+		val = I915_READ(DSPCNTR(plane));
+		if (val & DISPPLANE_ROTATE_180)
+			orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
+	}
+
+	return orientation;
+}
+
 static void intel_dsi_add_properties(struct intel_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1681,6 +1702,13 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
 								allowed_scalers);
 
 		connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
+
+		connector->base.display_info.panel_orientation =
+			intel_dsi_get_panel_orientation(connector);
+		drm_connector_init_panel_orientation_property(
+				&connector->base,
+				connector->panel.fixed_mode->hdisplay,
+				connector->panel.fixed_mode->vdisplay);
 	}
 }
 
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk
  2017-11-25 17:33 ` Hans de Goede
@ 2017-11-25 17:33   ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some hardware the LCD panel is not mounted upright in the casing,
but rotated by 90 degrees. In this case we want the console to
automatically be rotated to compensate.

The drm subsys has a quirk table for this, use the
drm_get_panel_orientation_quirk function to get the panel orientation
and set info->fbcon_rotate_hint based on this, so that the fbcon console
on top of efifb gets automatically rotated to compensate for the panel
orientation.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/Kconfig |  1 +
 drivers/video/fbdev/efifb.c | 21 ++++++++++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 2f615b7f1c9f..2566cfbdebfb 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -772,6 +772,7 @@ config FB_VESA
 config FB_EFI
 	bool "EFI-based Framebuffer Support"
 	depends on (FB = y) && !IA64 && EFI
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index d1bf9c2a78a7..88697ab1005b 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -16,6 +16,8 @@
 #include <linux/screen_info.h>
 #include <video/vga.h>
 #include <asm/efi.h>
+#include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */
+#include <drm/drm_mode.h>  /* For DRM_MODE_PANEL_ORIENTATION_* */
 
 static bool request_mem_succeeded = false;
 static bool nowc = false;
@@ -157,7 +159,7 @@ static u64 bar_offset;
 static int efifb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
-	int err;
+	int err, orientation;
 	unsigned int size_vmode;
 	unsigned int size_remap;
 	unsigned int size_total;
@@ -329,6 +331,23 @@ static int efifb_probe(struct platform_device *dev)
 	info->fix = efifb_fix;
 	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
 
+	orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
+						      efifb_defined.yres);
+	switch (orientation) {
+	default:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	}
+
 	err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
 	if (err) {
 		pr_err("efifb: cannot add sysfs attrs\n");
-- 
2.14.3


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

* [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk
@ 2017-11-25 17:33   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some hardware the LCD panel is not mounted upright in the casing,
but rotated by 90 degrees. In this case we want the console to
automatically be rotated to compensate.

The drm subsys has a quirk table for this, use the
drm_get_panel_orientation_quirk function to get the panel orientation
and set info->fbcon_rotate_hint based on this, so that the fbcon console
on top of efifb gets automatically rotated to compensate for the panel
orientation.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/Kconfig |  1 +
 drivers/video/fbdev/efifb.c | 21 ++++++++++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 2f615b7f1c9f..2566cfbdebfb 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -772,6 +772,7 @@ config FB_VESA
 config FB_EFI
 	bool "EFI-based Framebuffer Support"
 	depends on (FB = y) && !IA64 && EFI
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index d1bf9c2a78a7..88697ab1005b 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -16,6 +16,8 @@
 #include <linux/screen_info.h>
 #include <video/vga.h>
 #include <asm/efi.h>
+#include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */
+#include <drm/drm_mode.h>  /* For DRM_MODE_PANEL_ORIENTATION_* */
 
 static bool request_mem_succeeded = false;
 static bool nowc = false;
@@ -157,7 +159,7 @@ static u64 bar_offset;
 static int efifb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
-	int err;
+	int err, orientation;
 	unsigned int size_vmode;
 	unsigned int size_remap;
 	unsigned int size_total;
@@ -329,6 +331,23 @@ static int efifb_probe(struct platform_device *dev)
 	info->fix = efifb_fix;
 	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
 
+	orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
+						      efifb_defined.yres);
+	switch (orientation) {
+	default:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	}
+
 	err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
 	if (err) {
 		pr_err("efifb: cannot add sysfs attrs\n");
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 7/7] fbcon: Remove dmi quirk table
  2017-11-25 17:33 ` Hans de Goede
@ 2017-11-25 17:33   ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

This is now all handled in the drivers and communicated through
fb_info.fbcon_rotate_hint.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/core/Makefile           |   3 -
 drivers/video/fbdev/core/fbcon.c            |   4 +-
 drivers/video/fbdev/core/fbcon.h            |   6 --
 drivers/video/fbdev/core/fbcon_dmi_quirks.c | 145 ----------------------------
 4 files changed, 2 insertions(+), 156 deletions(-)
 delete mode 100644 drivers/video/fbdev/core/fbcon_dmi_quirks.c

diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
index d34fd182ca68..37710316a680 100644
--- a/drivers/video/fbdev/core/Makefile
+++ b/drivers/video/fbdev/core/Makefile
@@ -15,9 +15,6 @@ ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
 fb-y				  += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
 				     fbcon_ccw.o
 endif
-ifeq ($(CONFIG_DMI),y)
-fb-y				  += fbcon_dmi_quirks.o
-endif
 endif
 fb-objs                           := $(fb-y)
 
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 30014e5867db..5baf7bc054e1 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -969,7 +969,7 @@ static const char *fbcon_startup(void)
 	if (p->con_rotate = -1)
 		p->con_rotate = info->fbcon_rotate_hint;
 	if (p->con_rotate = -1)
-		p->con_rotate = fbcon_platform_get_rotate(info);
+		p->con_rotate = FB_ROTATE_UR;
 
 	set_blitting_type(vc, info);
 
@@ -1112,7 +1112,7 @@ static void fbcon_init(struct vc_data *vc, int init)
 	if (p->con_rotate = -1)
 		p->con_rotate = info->fbcon_rotate_hint;
 	if (p->con_rotate = -1)
-		p->con_rotate = fbcon_platform_get_rotate(info);
+		p->con_rotate = FB_ROTATE_UR;
 
 	set_blitting_type(vc, info);
 
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 9f7744fbc962..21912a3ba32f 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -262,10 +262,4 @@ extern void fbcon_set_rotate(struct fbcon_ops *ops);
 #define fbcon_set_rotate(x) do {} while(0)
 #endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
 
-#ifdef CONFIG_DMI
-int fbcon_platform_get_rotate(struct fb_info *info);
-#else
-#define fbcon_platform_get_rotate(i) FB_ROTATE_UR
-#endif /* CONFIG_DMI */
-
 #endif /* _VIDEO_FBCON_H */
diff --git a/drivers/video/fbdev/core/fbcon_dmi_quirks.c b/drivers/video/fbdev/core/fbcon_dmi_quirks.c
deleted file mode 100644
index 6904e47d1e51..000000000000
--- a/drivers/video/fbdev/core/fbcon_dmi_quirks.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- *  fbcon_dmi_quirks.c -- DMI based quirk detection for fbcon
- *
- *	Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/dmi.h>
-#include <linux/fb.h>
-#include <linux/kernel.h>
-#include "fbcon.h"
-
-/*
- * Some x86 clamshell design devices use portrait tablet screens and a display
- * engine which cannot rotate in hardware, so we need to rotate the fbcon to
- * compensate. Unfortunately these (cheap) devices also typically have quite
- * generic DMI data, so we match on a combination of DMI data, screen resolution
- * and a list of known BIOS dates to avoid false positives.
- */
-
-struct fbcon_dmi_rotate_data {
-	int width;
-	int height;
-	const char * const *bios_dates;
-	int rotate;
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_asus_t100ha = {
-	.width = 800,
-	.height = 1280,
-	.rotate = FB_ROTATE_CCW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_gpd_pocket = {
-	.width = 1200,
-	.height = 1920,
-	.bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
-		"07/05/2017", "08/07/2017", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_gpd_win = {
-	.width = 720,
-	.height = 1280,
-	.bios_dates = (const char * const []){
-		"10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
-		"02/21/2017", "03/20/2017", "05/25/2017", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_itworks_tw891 = {
-	.width = 800,
-	.height = 1280,
-	.bios_dates = (const char * const []){ "10/16/2015", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_vios_lth17 = {
-	.width = 800,
-	.height = 1280,
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct dmi_system_id rotate_data[] = {
-	{	/* Asus T100HA */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
-		},
-		.driver_data = (void *)&rotate_data_asus_t100ha,
-	}, {	/*
-		 * GPD Pocket, note that the the DMI data is less generic then
-		 * it seems, devices with a board-vendor of "AMI Corporation"
-		 * are quite rare, as are devices which have both board- *and*
-		 * product-id set to "Default String"
-		 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
-		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
-		},
-		.driver_data = (void *)&rotate_data_gpd_pocket,
-	}, {	/* GPD Win (same note on DMI match as GPD Pocket) */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
-		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
-		},
-		.driver_data = (void *)&rotate_data_gpd_win,
-	}, {	/* I.T.Works TW891 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
-		},
-		.driver_data = (void *)&rotate_data_itworks_tw891,
-	}, {	/* VIOS LTH17 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "VIOS"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "LTH17"),
-		},
-		.driver_data = (void *)&rotate_data_vios_lth17,
-	},
-	{}
-};
-
-int fbcon_platform_get_rotate(struct fb_info *info)
-{
-	const struct dmi_system_id *match;
-	const struct fbcon_dmi_rotate_data *data;
-	const char *bios_date;
-	int i;
-
-	for (match = dmi_first_match(rotate_data);
-	     match;
-	     match = dmi_first_match(match + 1)) {
-		data = match->driver_data;
-
-		if (data->width != info->var.xres ||
-		    data->height != info->var.yres)
-			continue;
-
-		if (!data->bios_dates)
-			return data->rotate;
-
-		bios_date = dmi_get_system_info(DMI_BIOS_DATE);
-		if (!bios_date)
-			continue;
-
-		for (i = 0; data->bios_dates[i]; i++) {
-			if (!strcmp(data->bios_dates[i], bios_date))
-				return data->rotate;
-		}
-	}
-
-	return FB_ROTATE_UR;
-}
-- 
2.14.3


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

* [PATCH v6 7/7] fbcon: Remove dmi quirk table
@ 2017-11-25 17:33   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 17:33 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

This is now all handled in the drivers and communicated through
fb_info.fbcon_rotate_hint.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/core/Makefile           |   3 -
 drivers/video/fbdev/core/fbcon.c            |   4 +-
 drivers/video/fbdev/core/fbcon.h            |   6 --
 drivers/video/fbdev/core/fbcon_dmi_quirks.c | 145 ----------------------------
 4 files changed, 2 insertions(+), 156 deletions(-)
 delete mode 100644 drivers/video/fbdev/core/fbcon_dmi_quirks.c

diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
index d34fd182ca68..37710316a680 100644
--- a/drivers/video/fbdev/core/Makefile
+++ b/drivers/video/fbdev/core/Makefile
@@ -15,9 +15,6 @@ ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
 fb-y				  += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
 				     fbcon_ccw.o
 endif
-ifeq ($(CONFIG_DMI),y)
-fb-y				  += fbcon_dmi_quirks.o
-endif
 endif
 fb-objs                           := $(fb-y)
 
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 30014e5867db..5baf7bc054e1 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -969,7 +969,7 @@ static const char *fbcon_startup(void)
 	if (p->con_rotate == -1)
 		p->con_rotate = info->fbcon_rotate_hint;
 	if (p->con_rotate == -1)
-		p->con_rotate = fbcon_platform_get_rotate(info);
+		p->con_rotate = FB_ROTATE_UR;
 
 	set_blitting_type(vc, info);
 
@@ -1112,7 +1112,7 @@ static void fbcon_init(struct vc_data *vc, int init)
 	if (p->con_rotate == -1)
 		p->con_rotate = info->fbcon_rotate_hint;
 	if (p->con_rotate == -1)
-		p->con_rotate = fbcon_platform_get_rotate(info);
+		p->con_rotate = FB_ROTATE_UR;
 
 	set_blitting_type(vc, info);
 
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 9f7744fbc962..21912a3ba32f 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -262,10 +262,4 @@ extern void fbcon_set_rotate(struct fbcon_ops *ops);
 #define fbcon_set_rotate(x) do {} while(0)
 #endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
 
-#ifdef CONFIG_DMI
-int fbcon_platform_get_rotate(struct fb_info *info);
-#else
-#define fbcon_platform_get_rotate(i) FB_ROTATE_UR
-#endif /* CONFIG_DMI */
-
 #endif /* _VIDEO_FBCON_H */
diff --git a/drivers/video/fbdev/core/fbcon_dmi_quirks.c b/drivers/video/fbdev/core/fbcon_dmi_quirks.c
deleted file mode 100644
index 6904e47d1e51..000000000000
--- a/drivers/video/fbdev/core/fbcon_dmi_quirks.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- *  fbcon_dmi_quirks.c -- DMI based quirk detection for fbcon
- *
- *	Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/dmi.h>
-#include <linux/fb.h>
-#include <linux/kernel.h>
-#include "fbcon.h"
-
-/*
- * Some x86 clamshell design devices use portrait tablet screens and a display
- * engine which cannot rotate in hardware, so we need to rotate the fbcon to
- * compensate. Unfortunately these (cheap) devices also typically have quite
- * generic DMI data, so we match on a combination of DMI data, screen resolution
- * and a list of known BIOS dates to avoid false positives.
- */
-
-struct fbcon_dmi_rotate_data {
-	int width;
-	int height;
-	const char * const *bios_dates;
-	int rotate;
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_asus_t100ha = {
-	.width = 800,
-	.height = 1280,
-	.rotate = FB_ROTATE_CCW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_gpd_pocket = {
-	.width = 1200,
-	.height = 1920,
-	.bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
-		"07/05/2017", "08/07/2017", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_gpd_win = {
-	.width = 720,
-	.height = 1280,
-	.bios_dates = (const char * const []){
-		"10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
-		"02/21/2017", "03/20/2017", "05/25/2017", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_itworks_tw891 = {
-	.width = 800,
-	.height = 1280,
-	.bios_dates = (const char * const []){ "10/16/2015", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_vios_lth17 = {
-	.width = 800,
-	.height = 1280,
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct dmi_system_id rotate_data[] = {
-	{	/* Asus T100HA */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
-		},
-		.driver_data = (void *)&rotate_data_asus_t100ha,
-	}, {	/*
-		 * GPD Pocket, note that the the DMI data is less generic then
-		 * it seems, devices with a board-vendor of "AMI Corporation"
-		 * are quite rare, as are devices which have both board- *and*
-		 * product-id set to "Default String"
-		 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
-		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
-		},
-		.driver_data = (void *)&rotate_data_gpd_pocket,
-	}, {	/* GPD Win (same note on DMI match as GPD Pocket) */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
-		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
-		},
-		.driver_data = (void *)&rotate_data_gpd_win,
-	}, {	/* I.T.Works TW891 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
-		},
-		.driver_data = (void *)&rotate_data_itworks_tw891,
-	}, {	/* VIOS LTH17 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "VIOS"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "LTH17"),
-		},
-		.driver_data = (void *)&rotate_data_vios_lth17,
-	},
-	{}
-};
-
-int fbcon_platform_get_rotate(struct fb_info *info)
-{
-	const struct dmi_system_id *match;
-	const struct fbcon_dmi_rotate_data *data;
-	const char *bios_date;
-	int i;
-
-	for (match = dmi_first_match(rotate_data);
-	     match;
-	     match = dmi_first_match(match + 1)) {
-		data = match->driver_data;
-
-		if (data->width != info->var.xres ||
-		    data->height != info->var.yres)
-			continue;
-
-		if (!data->bios_dates)
-			return data->rotate;
-
-		bios_date = dmi_get_system_info(DMI_BIOS_DATE);
-		if (!bios_date)
-			continue;
-
-		for (i = 0; data->bios_dates[i]; i++) {
-			if (!strcmp(data->bios_dates[i], bios_date))
-				return data->rotate;
-		}
-	}
-
-	return FB_ROTATE_UR;
-}
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✗ Fi.CI.BAT: failure for drm/fbdev: Panel orientation connector property support (rev4)
  2017-11-25 17:33 ` Hans de Goede
                   ` (7 preceding siblings ...)
  (?)
@ 2017-11-25 17:37 ` Patchwork
  -1 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2017-11-25 17:37 UTC (permalink / raw)
  To: Hans de Goede; +Cc: intel-gfx

== Series Details ==

Series: drm/fbdev: Panel orientation connector property support (rev4)
URL   : https://patchwork.freedesktop.org/series/32447/
State : failure

== Summary ==

Applying: fbcon: Add fbcon_rotate_hint to struct fb_info
Patch failed at 0001 fbcon: Add fbcon_rotate_hint to struct fb_info

Current HEAD:
commit ea65c53f1511f198e580aea65799baf9bc85d723
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Nov 25 16:18:37 2017 +0000

    drm-tip: 2017y-11m-25d-16h-18m-05s UTC integration manifest

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
@ 2017-11-25 19:16   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Hi All,

Here is v6 of my series to add a "panel orientation" property to
the drm-connector for the LCD panel to let userspace know about LCD
panels which are not mounted upright, as well as detecting upside-down
panels without needing quirks (like we do for 90 degree rotated screens).

Bartlomiej, can we please have your Acked-by for merging patches 1,
6 and 7 through the drm tree?

New in v6:
-Fix / reference kernel-doc comments
-Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
-Move i915 dsi hardware rotation state read-out to intel_dsi_init()

New in v5:
-Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
-drm_fb_helper: Only use hardware (crtc primary plane) rotation for
 180 degrees for now as 9-/270 degrees rotation requires special handling

New in v4:
-Fix drm_fb_helper code setting an invalid rotation value on the primary
 plane of disabled/unused crtcs (caught by Fi.CI)

New in v3:
-As requested by Daniel v3 moves the quirks over from the fbdev
 subsys to the drm subsys. I've done this by simpy starting with a copy of
 the quirk table and eventually removing the fbdev version.

The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
discussed previously the plan is to merge all 7 patches through the
drm tree.

Regards,

Hans


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

* [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
@ 2017-11-25 19:16   ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Hi All,

Here is v6 of my series to add a "panel orientation" property to
the drm-connector for the LCD panel to let userspace know about LCD
panels which are not mounted upright, as well as detecting upside-down
panels without needing quirks (like we do for 90 degree rotated screens).

Bartlomiej, can we please have your Acked-by for merging patches 1,
6 and 7 through the drm tree?

New in v6:
-Fix / reference kernel-doc comments
-Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
-Move i915 dsi hardware rotation state read-out to intel_dsi_init()

New in v5:
-Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
-drm_fb_helper: Only use hardware (crtc primary plane) rotation for
 180 degrees for now as 9-/270 degrees rotation requires special handling

New in v4:
-Fix drm_fb_helper code setting an invalid rotation value on the primary
 plane of disabled/unused crtcs (caught by Fi.CI)

New in v3:
-As requested by Daniel v3 moves the quirks over from the fbdev
 subsys to the drm subsys. I've done this by simpy starting with a copy of
 the quirk table and eventually removing the fbdev version.

The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
discussed previously the plan is to merge all 7 patches through the
drm tree.

Regards,

Hans

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 1/7] fbcon: Add fbcon_rotate_hint to struct fb_info
  2017-11-25 19:16   ` Hans de Goede
@ 2017-11-25 19:16     ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some hardware the LCD panel is not mounted upright in the casing,
but upside-down or rotated 90 degrees. In this case we want the console
to automatically be rotated to compensate.

The fbdev-driver may know about the need to rotate. Add a new
fbcon_rotate_hint field to struct fb_info, which gets initialized to -1.
If the fbdev-driver knows that some sort of rotation is necessary then
it can set this field to a FB_ROTATE_* value to tell the fbcon console
driver to rotate the console.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/core/fbcon.c   | 18 ++++++++++++------
 drivers/video/fbdev/core/fbsysfs.c |  1 +
 include/linux/fb.h                 |  5 +++++
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 04612f938bab..fb317ed76b45 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -963,10 +963,13 @@ static const char *fbcon_startup(void)
 	ops->cur_rotate = -1;
 	ops->cur_blink_jiffies = HZ / 5;
 	info->fbcon_par = ops;
-	if (initial_rotation != -1)
-		p->con_rotate = initial_rotation;
-	else
+
+	p->con_rotate = initial_rotation;
+	if (p->con_rotate = -1)
+		p->con_rotate = info->fbcon_rotate_hint;
+	if (p->con_rotate = -1)
 		p->con_rotate = fbcon_platform_get_rotate(info);
+
 	set_blitting_type(vc, info);
 
 	if (info->fix.type != FB_TYPE_TEXT) {
@@ -1103,10 +1106,13 @@ static void fbcon_init(struct vc_data *vc, int init)
 
 	ops = info->fbcon_par;
 	ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
-	if (initial_rotation != -1)
-		p->con_rotate = initial_rotation;
-	else
+
+	p->con_rotate = initial_rotation;
+	if (p->con_rotate = -1)
+		p->con_rotate = info->fbcon_rotate_hint;
+	if (p->con_rotate = -1)
 		p->con_rotate = fbcon_platform_get_rotate(info);
+
 	set_blitting_type(vc, info);
 
 	cols = vc->vc_cols;
diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c
index 15755ce1d26c..e31a182b42bf 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -58,6 +58,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
 		info->par = p + fb_info_size;
 
 	info->device = dev;
+	info->fbcon_rotate_hint = -1;
 
 #ifdef CONFIG_FB_BACKLIGHT
 	mutex_init(&info->bl_curve_mutex);
diff --git a/include/linux/fb.h b/include/linux/fb.h
index bc24e48e396d..d1e5bed39140 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -465,6 +465,11 @@ struct fb_info {
 	atomic_t count;
 	int node;
 	int flags;
+	/*
+	 * -1 by default, set to a FB_ROTATE_* value by the driver, if it knows
+	 * a lcd is not mounted upright and fbcon should rotate to compensate.
+	 */
+	int fbcon_rotate_hint;
 	struct mutex lock;		/* Lock for open/release/ioctl funcs */
 	struct mutex mm_lock;		/* Lock for fb_mmap and smem_* fields */
 	struct fb_var_screeninfo var;	/* Current var */
-- 
2.14.3


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

* [PATCH v6 1/7] fbcon: Add fbcon_rotate_hint to struct fb_info
@ 2017-11-25 19:16     ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some hardware the LCD panel is not mounted upright in the casing,
but upside-down or rotated 90 degrees. In this case we want the console
to automatically be rotated to compensate.

The fbdev-driver may know about the need to rotate. Add a new
fbcon_rotate_hint field to struct fb_info, which gets initialized to -1.
If the fbdev-driver knows that some sort of rotation is necessary then
it can set this field to a FB_ROTATE_* value to tell the fbcon console
driver to rotate the console.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/core/fbcon.c   | 18 ++++++++++++------
 drivers/video/fbdev/core/fbsysfs.c |  1 +
 include/linux/fb.h                 |  5 +++++
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 04612f938bab..fb317ed76b45 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -963,10 +963,13 @@ static const char *fbcon_startup(void)
 	ops->cur_rotate = -1;
 	ops->cur_blink_jiffies = HZ / 5;
 	info->fbcon_par = ops;
-	if (initial_rotation != -1)
-		p->con_rotate = initial_rotation;
-	else
+
+	p->con_rotate = initial_rotation;
+	if (p->con_rotate == -1)
+		p->con_rotate = info->fbcon_rotate_hint;
+	if (p->con_rotate == -1)
 		p->con_rotate = fbcon_platform_get_rotate(info);
+
 	set_blitting_type(vc, info);
 
 	if (info->fix.type != FB_TYPE_TEXT) {
@@ -1103,10 +1106,13 @@ static void fbcon_init(struct vc_data *vc, int init)
 
 	ops = info->fbcon_par;
 	ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
-	if (initial_rotation != -1)
-		p->con_rotate = initial_rotation;
-	else
+
+	p->con_rotate = initial_rotation;
+	if (p->con_rotate == -1)
+		p->con_rotate = info->fbcon_rotate_hint;
+	if (p->con_rotate == -1)
 		p->con_rotate = fbcon_platform_get_rotate(info);
+
 	set_blitting_type(vc, info);
 
 	cols = vc->vc_cols;
diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c
index 15755ce1d26c..e31a182b42bf 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -58,6 +58,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
 		info->par = p + fb_info_size;
 
 	info->device = dev;
+	info->fbcon_rotate_hint = -1;
 
 #ifdef CONFIG_FB_BACKLIGHT
 	mutex_init(&info->bl_curve_mutex);
diff --git a/include/linux/fb.h b/include/linux/fb.h
index bc24e48e396d..d1e5bed39140 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -465,6 +465,11 @@ struct fb_info {
 	atomic_t count;
 	int node;
 	int flags;
+	/*
+	 * -1 by default, set to a FB_ROTATE_* value by the driver, if it knows
+	 * a lcd is not mounted upright and fbcon should rotate to compensate.
+	 */
+	int fbcon_rotate_hint;
 	struct mutex lock;		/* Lock for open/release/ioctl funcs */
 	struct mutex mm_lock;		/* Lock for fb_mmap and smem_* fields */
 	struct fb_var_screeninfo var;	/* Current var */
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 2/7] drm: Add panel orientation quirks, v6.
  2017-11-25 19:16   ` Hans de Goede
@ 2017-11-25 19:16     ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Some x86 clamshell design devices use portrait tablet screens and a display
engine which cannot rotate in hardware, so the firmware just leaves things
as is and we cannot figure out that the display is oriented non upright
from the hardware.

So at least on x86, we need a quirk table for this. This commit adds a DMI
based quirk table which is initially populated with 5 such devices: Asus
T100HA, GPD Pocket, GPD win, I.T.Works TW891 and the VIOS LTH17.

This quirk table will be used by the drm code to let userspace know that
the display is not mounted upright inside the devices case through a new
panel orientation drm-connector property, as well as to tell fbcon to
rotate the console so that it shows the right way up.

Changes in v5:
-Add a kernel-doc comment documenting drm_get_panel_orientation_quirk()
-Remove board_* matches from the dmi-matches for the VIOS LTH17 laptop,
 keeping only the (identical) sys_vendor and product_name matches.
 This is necessary because an older version of the bios has
 board_vendor set to VOIS instead of VIOS

Changes in v6:
-Add reference to added kernel-docs in Documentation/gpu/drm-kms-helpers.rst

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 Documentation/gpu/drm-kms-helpers.rst          |   3 +
 drivers/gpu/drm/Kconfig                        |   3 +
 drivers/gpu/drm/Makefile                       |   1 +
 drivers/gpu/drm/drm_panel_orientation_quirks.c | 174 +++++++++++++++++++++++++
 include/drm/drm_utils.h                        |  18 +++
 5 files changed, 199 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_panel_orientation_quirks.c
 create mode 100644 include/drm/drm_utils.h

diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 13dd237418cc..3ea622876b67 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -163,6 +163,9 @@ Panel Helper Reference
 .. kernel-doc:: drivers/gpu/drm/drm_panel.c
    :export:
 
+.. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
+   :export:
+
 Display Port Helper Functions Reference
 =================== 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 4d9f21831741..9d005ac98c2b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -26,6 +26,9 @@ config DRM_MIPI_DSI
 	bool
 	depends on DRM
 
+config DRM_PANEL_ORIENTATION_QUIRKS
+	tristate
+
 config DRM_DP_AUX_CHARDEV
 	bool "DRM DP AUX Interface"
 	depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e9500844333e..e5bf68b9c171 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/
 
 obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
+obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
 obj-$(CONFIG_DRM_ARM)	+= arm/
 obj-$(CONFIG_DRM_TTM)	+= ttm/
 obj-$(CONFIG_DRM_TDFX)	+= tdfx/
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
new file mode 100644
index 000000000000..b8765e2ed1d6
--- /dev/null
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -0,0 +1,174 @@
+/*
+ *  drm_panel_orientation_quirks.c -- Quirks for non-normal panel orientation
+ *
+ *	Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/dmi.h>
+#include <drm/drm_connector.h>
+
+#ifdef CONFIG_DMI
+
+/*
+ * Some x86 clamshell design devices use portrait tablet screens and a display
+ * engine which cannot rotate in hardware, so we need to rotate the fbcon to
+ * compensate. Unfortunately these (cheap) devices also typically have quite
+ * generic DMI data, so we match on a combination of DMI data, screen resolution
+ * and a list of known BIOS dates to avoid false positives.
+ */
+
+struct drm_dmi_panel_orientation_data {
+	int width;
+	int height;
+	const char * const *bios_dates;
+	int orientation;
+};
+
+static const struct drm_dmi_panel_orientation_data asus_t100ha = {
+	.width = 800,
+	.height = 1280,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data gpd_pocket = {
+	.width = 1200,
+	.height = 1920,
+	.bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
+		"07/05/2017", "08/07/2017", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data gpd_win = {
+	.width = 720,
+	.height = 1280,
+	.bios_dates = (const char * const []){
+		"10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
+		"02/21/2017", "03/20/2017", "05/25/2017", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data itworks_tw891 = {
+	.width = 800,
+	.height = 1280,
+	.bios_dates = (const char * const []){ "10/16/2015", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data vios_lth17 = {
+	.width = 800,
+	.height = 1280,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct dmi_system_id orientation_data[] = {
+	{	/* Asus T100HA */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
+		},
+		.driver_data = (void *)&asus_t100ha,
+	}, {	/*
+		 * GPD Pocket, note that the the DMI data is less generic then
+		 * it seems, devices with a board-vendor of "AMI Corporation"
+		 * are quite rare, as are devices which have both board- *and*
+		 * product-id set to "Default String"
+		 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+		.driver_data = (void *)&gpd_pocket,
+	}, {	/* GPD Win (same note on DMI match as GPD Pocket) */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+		.driver_data = (void *)&gpd_win,
+	}, {	/* I.T.Works TW891 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
+		},
+		.driver_data = (void *)&itworks_tw891,
+	}, {	/* VIOS LTH17 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
+		},
+		.driver_data = (void *)&vios_lth17,
+	},
+	{}
+};
+
+/**
+ * drm_get_panel_orientation_quirk - Check for panel orientation quirks
+ * @width: width in pixels of the panel
+ * @height: height in pixels of the panel
+ *
+ * This function checks for platform specific (e.g. DMI based) quirks
+ * providing info on panel_orientation for systems where this cannot be
+ * probed from the hard-/firm-ware. To avoid false-positive this function
+ * takes the panel resolution as argument and checks that against the
+ * resolution expected by the quirk-table entry.
+ *
+ * Note this function is also used outside of the drm-subsys, by for example
+ * the efifb code. Because of this this function gets compiled into its own
+ * kernel-module when built as a module.
+ *
+ * Returns:
+ * A DRM_MODE_PANEL_ORIENTATION_* value if there is a quirk for this system,
+ * or DRM_MODE_PANEL_ORIENTATION_UNKNOWN if there is no quirk.
+ */
+int drm_get_panel_orientation_quirk(int width, int height)
+{
+	const struct dmi_system_id *match;
+	const struct drm_dmi_panel_orientation_data *data;
+	const char *bios_date;
+	int i;
+
+	for (match = dmi_first_match(orientation_data);
+	     match;
+	     match = dmi_first_match(match + 1)) {
+		data = match->driver_data;
+
+		if (data->width != width ||
+		    data->height != height)
+			continue;
+
+		if (!data->bios_dates)
+			return data->orientation;
+
+		bios_date = dmi_get_system_info(DMI_BIOS_DATE);
+		if (!bios_date)
+			continue;
+
+		for (i = 0; data->bios_dates[i]; i++) {
+			if (!strcmp(data->bios_dates[i], bios_date))
+				return data->orientation;
+		}
+	}
+
+	return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+}
+EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
+
+#else
+
+/* There are no quirks for non x86 devices yet */
+int drm_get_panel_orientation_quirk(int width, int height)
+{
+	return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+}
+EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
+
+#endif
diff --git a/include/drm/drm_utils.h b/include/drm/drm_utils.h
new file mode 100644
index 000000000000..cea362aeaffe
--- /dev/null
+++ b/include/drm/drm_utils.h
@@ -0,0 +1,18 @@
+/*
+ * Function prototypes for misc. drm utility functions.
+ * Specifically this file is for function prototypes for functions which
+ * may also be used outside of drm code (e.g. in fbdev drivers).
+ *
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRM_UTILS_H__
+#define __DRM_UTILS_H__
+
+int drm_get_panel_orientation_quirk(int width, int height);
+
+#endif
-- 
2.14.3


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

* [PATCH v6 2/7] drm: Add panel orientation quirks, v6.
@ 2017-11-25 19:16     ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Some x86 clamshell design devices use portrait tablet screens and a display
engine which cannot rotate in hardware, so the firmware just leaves things
as is and we cannot figure out that the display is oriented non upright
from the hardware.

So at least on x86, we need a quirk table for this. This commit adds a DMI
based quirk table which is initially populated with 5 such devices: Asus
T100HA, GPD Pocket, GPD win, I.T.Works TW891 and the VIOS LTH17.

This quirk table will be used by the drm code to let userspace know that
the display is not mounted upright inside the devices case through a new
panel orientation drm-connector property, as well as to tell fbcon to
rotate the console so that it shows the right way up.

Changes in v5:
-Add a kernel-doc comment documenting drm_get_panel_orientation_quirk()
-Remove board_* matches from the dmi-matches for the VIOS LTH17 laptop,
 keeping only the (identical) sys_vendor and product_name matches.
 This is necessary because an older version of the bios has
 board_vendor set to VOIS instead of VIOS

Changes in v6:
-Add reference to added kernel-docs in Documentation/gpu/drm-kms-helpers.rst

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 Documentation/gpu/drm-kms-helpers.rst          |   3 +
 drivers/gpu/drm/Kconfig                        |   3 +
 drivers/gpu/drm/Makefile                       |   1 +
 drivers/gpu/drm/drm_panel_orientation_quirks.c | 174 +++++++++++++++++++++++++
 include/drm/drm_utils.h                        |  18 +++
 5 files changed, 199 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_panel_orientation_quirks.c
 create mode 100644 include/drm/drm_utils.h

diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 13dd237418cc..3ea622876b67 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -163,6 +163,9 @@ Panel Helper Reference
 .. kernel-doc:: drivers/gpu/drm/drm_panel.c
    :export:
 
+.. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
+   :export:
+
 Display Port Helper Functions Reference
 =======================================
 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 4d9f21831741..9d005ac98c2b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -26,6 +26,9 @@ config DRM_MIPI_DSI
 	bool
 	depends on DRM
 
+config DRM_PANEL_ORIENTATION_QUIRKS
+	tristate
+
 config DRM_DP_AUX_CHARDEV
 	bool "DRM DP AUX Interface"
 	depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e9500844333e..e5bf68b9c171 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/
 
 obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
+obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
 obj-$(CONFIG_DRM_ARM)	+= arm/
 obj-$(CONFIG_DRM_TTM)	+= ttm/
 obj-$(CONFIG_DRM_TDFX)	+= tdfx/
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
new file mode 100644
index 000000000000..b8765e2ed1d6
--- /dev/null
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -0,0 +1,174 @@
+/*
+ *  drm_panel_orientation_quirks.c -- Quirks for non-normal panel orientation
+ *
+ *	Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/dmi.h>
+#include <drm/drm_connector.h>
+
+#ifdef CONFIG_DMI
+
+/*
+ * Some x86 clamshell design devices use portrait tablet screens and a display
+ * engine which cannot rotate in hardware, so we need to rotate the fbcon to
+ * compensate. Unfortunately these (cheap) devices also typically have quite
+ * generic DMI data, so we match on a combination of DMI data, screen resolution
+ * and a list of known BIOS dates to avoid false positives.
+ */
+
+struct drm_dmi_panel_orientation_data {
+	int width;
+	int height;
+	const char * const *bios_dates;
+	int orientation;
+};
+
+static const struct drm_dmi_panel_orientation_data asus_t100ha = {
+	.width = 800,
+	.height = 1280,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data gpd_pocket = {
+	.width = 1200,
+	.height = 1920,
+	.bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
+		"07/05/2017", "08/07/2017", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data gpd_win = {
+	.width = 720,
+	.height = 1280,
+	.bios_dates = (const char * const []){
+		"10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
+		"02/21/2017", "03/20/2017", "05/25/2017", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data itworks_tw891 = {
+	.width = 800,
+	.height = 1280,
+	.bios_dates = (const char * const []){ "10/16/2015", NULL },
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct drm_dmi_panel_orientation_data vios_lth17 = {
+	.width = 800,
+	.height = 1280,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
+static const struct dmi_system_id orientation_data[] = {
+	{	/* Asus T100HA */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
+		},
+		.driver_data = (void *)&asus_t100ha,
+	}, {	/*
+		 * GPD Pocket, note that the the DMI data is less generic then
+		 * it seems, devices with a board-vendor of "AMI Corporation"
+		 * are quite rare, as are devices which have both board- *and*
+		 * product-id set to "Default String"
+		 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+		.driver_data = (void *)&gpd_pocket,
+	}, {	/* GPD Win (same note on DMI match as GPD Pocket) */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+		.driver_data = (void *)&gpd_win,
+	}, {	/* I.T.Works TW891 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
+		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
+		},
+		.driver_data = (void *)&itworks_tw891,
+	}, {	/* VIOS LTH17 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
+		},
+		.driver_data = (void *)&vios_lth17,
+	},
+	{}
+};
+
+/**
+ * drm_get_panel_orientation_quirk - Check for panel orientation quirks
+ * @width: width in pixels of the panel
+ * @height: height in pixels of the panel
+ *
+ * This function checks for platform specific (e.g. DMI based) quirks
+ * providing info on panel_orientation for systems where this cannot be
+ * probed from the hard-/firm-ware. To avoid false-positive this function
+ * takes the panel resolution as argument and checks that against the
+ * resolution expected by the quirk-table entry.
+ *
+ * Note this function is also used outside of the drm-subsys, by for example
+ * the efifb code. Because of this this function gets compiled into its own
+ * kernel-module when built as a module.
+ *
+ * Returns:
+ * A DRM_MODE_PANEL_ORIENTATION_* value if there is a quirk for this system,
+ * or DRM_MODE_PANEL_ORIENTATION_UNKNOWN if there is no quirk.
+ */
+int drm_get_panel_orientation_quirk(int width, int height)
+{
+	const struct dmi_system_id *match;
+	const struct drm_dmi_panel_orientation_data *data;
+	const char *bios_date;
+	int i;
+
+	for (match = dmi_first_match(orientation_data);
+	     match;
+	     match = dmi_first_match(match + 1)) {
+		data = match->driver_data;
+
+		if (data->width != width ||
+		    data->height != height)
+			continue;
+
+		if (!data->bios_dates)
+			return data->orientation;
+
+		bios_date = dmi_get_system_info(DMI_BIOS_DATE);
+		if (!bios_date)
+			continue;
+
+		for (i = 0; data->bios_dates[i]; i++) {
+			if (!strcmp(data->bios_dates[i], bios_date))
+				return data->orientation;
+		}
+	}
+
+	return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+}
+EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
+
+#else
+
+/* There are no quirks for non x86 devices yet */
+int drm_get_panel_orientation_quirk(int width, int height)
+{
+	return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+}
+EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
+
+#endif
diff --git a/include/drm/drm_utils.h b/include/drm/drm_utils.h
new file mode 100644
index 000000000000..cea362aeaffe
--- /dev/null
+++ b/include/drm/drm_utils.h
@@ -0,0 +1,18 @@
+/*
+ * Function prototypes for misc. drm utility functions.
+ * Specifically this file is for function prototypes for functions which
+ * may also be used outside of drm code (e.g. in fbdev drivers).
+ *
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRM_UTILS_H__
+#define __DRM_UTILS_H__
+
+int drm_get_panel_orientation_quirk(int width, int height);
+
+#endif
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 3/7] drm: Add support for a panel-orientation connector property, v6
  2017-11-25 19:16   ` Hans de Goede
@ 2017-11-25 19:16     ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some devices the LCD panel is mounted in the casing in such a way that
the up/top side of the panel does not match with the top side of the
device (e.g. it is mounted upside-down).

This commit adds the necessary infra for lcd-panel drm_connector-s to
have a "panel orientation" property to communicate how the panel is
orientated vs the casing.

Userspace can use this property to check for non-normal orientation and
then adjust the displayed image accordingly by rotating it to compensate.

Changes in v2:
-Store panel_orientation in drm_display_info, so that drm_fb_helper.c can
 access it easily
-Have a single drm_connector_init_panel_orientation_property rather then
 create and attach functions. The caller is expected to set
 drm_display_info.panel_orientation before calling this, then this will
 check for platform specific quirks overriding the panel_orientation and if
 the panel_orientation is set after this then it will attach the property.

Changes in v6:
-Use an enum (with kerneldoc) rather then #defines for
 DRM_MODE_PANEL_ORIENTATION_*

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/Kconfig         |  1 +
 drivers/gpu/drm/drm_connector.c | 73 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     | 40 ++++++++++++++++++++++
 include/drm/drm_mode_config.h   |  7 ++++
 4 files changed, 121 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 9d005ac98c2b..0b166e626eb6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -7,6 +7,7 @@
 menuconfig DRM
 	tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
 	depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select HDMI
 	select FB_CMDLINE
 	select I2C
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 25f4b2e9a44f..624edeb5c50d 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -24,6 +24,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
+#include <drm/drm_utils.h>
 
 #include "drm_crtc_internal.h"
 #include "drm_internal.h"
@@ -212,6 +213,8 @@ int drm_connector_init(struct drm_device *dev,
 	mutex_init(&connector->mutex);
 	connector->edid_blob_ptr = NULL;
 	connector->status = connector_status_unknown;
+	connector->display_info.panel_orientation +		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
 
 	drm_connector_get_cmdline_mode(connector);
 
@@ -668,6 +671,13 @@ static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
 	{ DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
 };
 
+static const struct drm_prop_enum_list drm_panel_orientation_enum_list[] = {
+	{ DRM_MODE_PANEL_ORIENTATION_NORMAL,	"Normal"	},
+	{ DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,	"Upside Down"	},
+	{ DRM_MODE_PANEL_ORIENTATION_LEFT_UP,	"Left Side Up"	},
+	{ DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,	"Right Side Up"	},
+};
+
 static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
 	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
 	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
@@ -776,6 +786,18 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
  *
  * CRTC_ID:
  * 	Mode object ID of the &drm_crtc this connector should be connected to.
+ *
+ * Connectors for LCD panels may also have one standardized property:
+ *
+ * panel orientation:
+ *	On some devices the LCD panel is mounted in the casing in such a way
+ *	that the up/top side of the panel does not match with the top side of
+ *	the device. Userspace can use this property to check for this.
+ *	Note that input coordinates from touchscreens (input devices with
+ *	INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel
+ *	coordinates, so if userspace rotates the picture to adjust for
+ *	the orientation it must also apply the same transformation to the
+ *	touchscreen input coordinates.
  */
 
 int drm_connector_create_standard_properties(struct drm_device *dev)
@@ -1251,6 +1273,57 @@ void drm_mode_connector_set_link_status_property(struct drm_connector *connector
 }
 EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
 
+/**
+ * drm_connector_init_panel_orientation_property -
+ *	initialize the connecters panel_orientation property
+ * @connector: connector for which to init the panel-orientation property.
+ * @width: width in pixels of the panel, used for panel quirk detection
+ * @height: height in pixels of the panel, used for panel quirk detection
+ *
+ * This function should only be called for built-in panels, after setting
+ * connector->display_info.panel_orientation first (if known).
+ *
+ * This function will check for platform specific (e.g. DMI based) quirks
+ * overriding display_info.panel_orientation first, then if panel_orientation
+ * is not DRM_MODE_PANEL_ORIENTATION_UNKNOWN it will attach the
+ * "panel orientation" property to the connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_init_panel_orientation_property(
+	struct drm_connector *connector, int width, int height)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_display_info *info = &connector->display_info;
+	struct drm_property *prop;
+	int orientation_quirk;
+
+	orientation_quirk = drm_get_panel_orientation_quirk(width, height);
+	if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
+		info->panel_orientation = orientation_quirk;
+
+	if (info->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
+		return 0;
+
+	prop = dev->mode_config.panel_orientation_property;
+	if (!prop) {
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
+				"panel orientation",
+				drm_panel_orientation_enum_list,
+				ARRAY_SIZE(drm_panel_orientation_enum_list));
+		if (!prop)
+			return -ENOMEM;
+
+		dev->mode_config.panel_orientation_property = prop;
+	}
+
+	drm_object_attach_property(&connector->base, prop,
+				   info->panel_orientation);
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
+
 int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 66d6c99d15e5..f39ff52feb3b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -175,6 +175,35 @@ enum drm_link_status {
 	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
 };
 
+/**
+ * enum drm_panel_orientation - panel_orientation info for &drm_display_info
+ *
+ * This enum is used to track the (LCD) panel orientation. There are no
+ * separate #defines for the uapi!
+ *
+ * @DRM_MODE_PANEL_ORIENTATION_UNKNOWN: The drm driver has not provided any
+ *					panel orientation information (normal
+ *					for non panels) in this case the "panel
+ *					orientation" connector prop will not be
+ *					attached.
+ * @DRM_MODE_PANEL_ORIENTATION_NORMAL:	The top side of the panel matches the
+ *					top side of the device's casing.
+ * @DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: The top side of the panel matches the
+ *					bottom side of the device's casing, iow
+ *					the panel is mounted upside-down.
+ * @DRM_MODE_PANEL_ORIENTATION_LEFT_UP:	The left side of the panel matches the
+ *					top side of the device's casing.
+ * @DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: The right side of the panel matches the
+ *					top side of the device's casing.
+ */
+enum drm_panel_orientation {
+	DRM_MODE_PANEL_ORIENTATION_UNKNOWN = -1,
+	DRM_MODE_PANEL_ORIENTATION_NORMAL = 0,
+	DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,
+	DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
+	DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
 /**
  * struct drm_display_info - runtime data about the connected sink
  *
@@ -222,6 +251,15 @@ struct drm_display_info {
 #define DRM_COLOR_FORMAT_YCRCB422	(1<<2)
 #define DRM_COLOR_FORMAT_YCRCB420	(1<<3)
 
+	/**
+	 * @panel_orientation: Read only connector property for built-in panels,
+	 * indicating the orientation of the panel vs the device's casing.
+	 * drm_connector_init() sets this to DRM_MODE_PANEL_ORIENTATION_UNKNOWN.
+	 * When not UNKNOWN this gets used by the drm_fb_helpers to rotate the
+	 * fb to compensate and gets exported as prop to userspace.
+	 */
+	int panel_orientation;
+
 	/**
 	 * @color_formats: HDMI Color formats, selects between RGB and YCrCb
 	 * modes. Used DRM_COLOR_FORMAT\_ defines, which are _not_ the same ones
@@ -1035,6 +1073,8 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 					    const struct edid *edid);
 void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
 						 uint64_t link_status);
+int drm_connector_init_panel_orientation_property(
+	struct drm_connector *connector, int width, int height);
 
 /**
  * struct drm_tile_group - Tile group metadata
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 5306ebd537b2..cb9ffbda36cc 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -735,6 +735,13 @@ struct drm_mode_config {
 	 */
 	struct drm_property *non_desktop_property;
 
+	/**
+	 * @panel_orientation_property: Optional connector property indicating
+	 * how the lcd-panel is mounted inside the casing (e.g. normal or
+	 * upside-down).
+	 */
+	struct drm_property *panel_orientation_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
-- 
2.14.3


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

* [PATCH v6 3/7] drm: Add support for a panel-orientation connector property, v6
@ 2017-11-25 19:16     ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some devices the LCD panel is mounted in the casing in such a way that
the up/top side of the panel does not match with the top side of the
device (e.g. it is mounted upside-down).

This commit adds the necessary infra for lcd-panel drm_connector-s to
have a "panel orientation" property to communicate how the panel is
orientated vs the casing.

Userspace can use this property to check for non-normal orientation and
then adjust the displayed image accordingly by rotating it to compensate.

Changes in v2:
-Store panel_orientation in drm_display_info, so that drm_fb_helper.c can
 access it easily
-Have a single drm_connector_init_panel_orientation_property rather then
 create and attach functions. The caller is expected to set
 drm_display_info.panel_orientation before calling this, then this will
 check for platform specific quirks overriding the panel_orientation and if
 the panel_orientation is set after this then it will attach the property.

Changes in v6:
-Use an enum (with kerneldoc) rather then #defines for
 DRM_MODE_PANEL_ORIENTATION_*

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/Kconfig         |  1 +
 drivers/gpu/drm/drm_connector.c | 73 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     | 40 ++++++++++++++++++++++
 include/drm/drm_mode_config.h   |  7 ++++
 4 files changed, 121 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 9d005ac98c2b..0b166e626eb6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -7,6 +7,7 @@
 menuconfig DRM
 	tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
 	depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select HDMI
 	select FB_CMDLINE
 	select I2C
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 25f4b2e9a44f..624edeb5c50d 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -24,6 +24,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
+#include <drm/drm_utils.h>
 
 #include "drm_crtc_internal.h"
 #include "drm_internal.h"
@@ -212,6 +213,8 @@ int drm_connector_init(struct drm_device *dev,
 	mutex_init(&connector->mutex);
 	connector->edid_blob_ptr = NULL;
 	connector->status = connector_status_unknown;
+	connector->display_info.panel_orientation =
+		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
 
 	drm_connector_get_cmdline_mode(connector);
 
@@ -668,6 +671,13 @@ static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
 	{ DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
 };
 
+static const struct drm_prop_enum_list drm_panel_orientation_enum_list[] = {
+	{ DRM_MODE_PANEL_ORIENTATION_NORMAL,	"Normal"	},
+	{ DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,	"Upside Down"	},
+	{ DRM_MODE_PANEL_ORIENTATION_LEFT_UP,	"Left Side Up"	},
+	{ DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,	"Right Side Up"	},
+};
+
 static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
 	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
 	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
@@ -776,6 +786,18 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
  *
  * CRTC_ID:
  * 	Mode object ID of the &drm_crtc this connector should be connected to.
+ *
+ * Connectors for LCD panels may also have one standardized property:
+ *
+ * panel orientation:
+ *	On some devices the LCD panel is mounted in the casing in such a way
+ *	that the up/top side of the panel does not match with the top side of
+ *	the device. Userspace can use this property to check for this.
+ *	Note that input coordinates from touchscreens (input devices with
+ *	INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel
+ *	coordinates, so if userspace rotates the picture to adjust for
+ *	the orientation it must also apply the same transformation to the
+ *	touchscreen input coordinates.
  */
 
 int drm_connector_create_standard_properties(struct drm_device *dev)
@@ -1251,6 +1273,57 @@ void drm_mode_connector_set_link_status_property(struct drm_connector *connector
 }
 EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
 
+/**
+ * drm_connector_init_panel_orientation_property -
+ *	initialize the connecters panel_orientation property
+ * @connector: connector for which to init the panel-orientation property.
+ * @width: width in pixels of the panel, used for panel quirk detection
+ * @height: height in pixels of the panel, used for panel quirk detection
+ *
+ * This function should only be called for built-in panels, after setting
+ * connector->display_info.panel_orientation first (if known).
+ *
+ * This function will check for platform specific (e.g. DMI based) quirks
+ * overriding display_info.panel_orientation first, then if panel_orientation
+ * is not DRM_MODE_PANEL_ORIENTATION_UNKNOWN it will attach the
+ * "panel orientation" property to the connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_init_panel_orientation_property(
+	struct drm_connector *connector, int width, int height)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_display_info *info = &connector->display_info;
+	struct drm_property *prop;
+	int orientation_quirk;
+
+	orientation_quirk = drm_get_panel_orientation_quirk(width, height);
+	if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
+		info->panel_orientation = orientation_quirk;
+
+	if (info->panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
+		return 0;
+
+	prop = dev->mode_config.panel_orientation_property;
+	if (!prop) {
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
+				"panel orientation",
+				drm_panel_orientation_enum_list,
+				ARRAY_SIZE(drm_panel_orientation_enum_list));
+		if (!prop)
+			return -ENOMEM;
+
+		dev->mode_config.panel_orientation_property = prop;
+	}
+
+	drm_object_attach_property(&connector->base, prop,
+				   info->panel_orientation);
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
+
 int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 66d6c99d15e5..f39ff52feb3b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -175,6 +175,35 @@ enum drm_link_status {
 	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
 };
 
+/**
+ * enum drm_panel_orientation - panel_orientation info for &drm_display_info
+ *
+ * This enum is used to track the (LCD) panel orientation. There are no
+ * separate #defines for the uapi!
+ *
+ * @DRM_MODE_PANEL_ORIENTATION_UNKNOWN: The drm driver has not provided any
+ *					panel orientation information (normal
+ *					for non panels) in this case the "panel
+ *					orientation" connector prop will not be
+ *					attached.
+ * @DRM_MODE_PANEL_ORIENTATION_NORMAL:	The top side of the panel matches the
+ *					top side of the device's casing.
+ * @DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: The top side of the panel matches the
+ *					bottom side of the device's casing, iow
+ *					the panel is mounted upside-down.
+ * @DRM_MODE_PANEL_ORIENTATION_LEFT_UP:	The left side of the panel matches the
+ *					top side of the device's casing.
+ * @DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: The right side of the panel matches the
+ *					top side of the device's casing.
+ */
+enum drm_panel_orientation {
+	DRM_MODE_PANEL_ORIENTATION_UNKNOWN = -1,
+	DRM_MODE_PANEL_ORIENTATION_NORMAL = 0,
+	DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,
+	DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
+	DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
 /**
  * struct drm_display_info - runtime data about the connected sink
  *
@@ -222,6 +251,15 @@ struct drm_display_info {
 #define DRM_COLOR_FORMAT_YCRCB422	(1<<2)
 #define DRM_COLOR_FORMAT_YCRCB420	(1<<3)
 
+	/**
+	 * @panel_orientation: Read only connector property for built-in panels,
+	 * indicating the orientation of the panel vs the device's casing.
+	 * drm_connector_init() sets this to DRM_MODE_PANEL_ORIENTATION_UNKNOWN.
+	 * When not UNKNOWN this gets used by the drm_fb_helpers to rotate the
+	 * fb to compensate and gets exported as prop to userspace.
+	 */
+	int panel_orientation;
+
 	/**
 	 * @color_formats: HDMI Color formats, selects between RGB and YCrCb
 	 * modes. Used DRM_COLOR_FORMAT\_ defines, which are _not_ the same ones
@@ -1035,6 +1073,8 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 					    const struct edid *edid);
 void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
 						 uint64_t link_status);
+int drm_connector_init_panel_orientation_property(
+	struct drm_connector *connector, int width, int height);
 
 /**
  * struct drm_tile_group - Tile group metadata
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 5306ebd537b2..cb9ffbda36cc 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -735,6 +735,13 @@ struct drm_mode_config {
 	 */
 	struct drm_property *non_desktop_property;
 
+	/**
+	 * @panel_orientation_property: Optional connector property indicating
+	 * how the lcd-panel is mounted inside the casing (e.g. normal or
+	 * upside-down).
+	 */
+	struct drm_property *panel_orientation_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 4/7] drm/fb-helper: Apply panel orientation connector prop to the primary plane, v6.
  2017-11-25 19:16   ` Hans de Goede
@ 2017-11-25 19:16     ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Apply the "panel orientation" drm connector prop to the primary plane so
that fbcon and fbdev using userspace programs display the right way up.

Changes in v3:
-Use a rotation member in struct drm_fb_helper_crtc and set that from
 drm_setup_crtcs instead of looping over all crtc's to find the right one
 later
-Since we now no longer look at rotation quirks directly in the fbcon
 code, set fb_info.fbcon_rotate_hint when the panel is not mounted upright
 and we cannot use hardware rotation

Changes in v4:
-Make drm_fb_helper_init() init drm_fb_helper_crtc.rotation to
 DRM_MODE_ROTATE_0 for all crtcs, so that we do not end up setting the
 plane_state's rotation to an invalid value for disabled crtcs
 (caught by Fi.CI)

Changes in v5:
-Only use hardware (crtc primary plane) rotation for DRM_ROTATE_180,
 90 / 270 degree rotation requires special handling which we lack atm
-Add a TODO comment for 90 / 270 degree hardware rotation
-Add some comments to better document the default case when mapping
 sw_rotations to fbcon_rotate_hints

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id”894
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/drm_fb_helper.c | 90 ++++++++++++++++++++++++++++++++++++++++-
 include/drm/drm_fb_helper.h     |  8 ++++
 2 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 832739ff58bf..57d6bad379f8 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -41,6 +41,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 
+#include "drm_crtc_internal.h"
 #include "drm_crtc_helper_internal.h"
 
 static bool drm_fbdev_emulation = true;
@@ -356,6 +357,7 @@ EXPORT_SYMBOL(drm_fb_helper_debug_leave);
 static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active)
 {
 	struct drm_device *dev = fb_helper->dev;
+	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	struct drm_atomic_state *state;
 	int i, ret;
@@ -374,8 +376,6 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 retry:
 	plane_mask = 0;
 	drm_for_each_plane(plane, dev) {
-		struct drm_plane_state *plane_state;
-
 		plane_state = drm_atomic_get_plane_state(state, plane);
 		if (IS_ERR(plane_state)) {
 			ret = PTR_ERR(plane_state);
@@ -398,6 +398,11 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
+		struct drm_plane *primary = mode_set->crtc->primary;
+
+		/* Cannot fail as we've already gotten the plane state above */
+		plane_state = drm_atomic_get_new_plane_state(state, primary);
+		plane_state->rotation = fb_helper->crtc_info[i].rotation;
 
 		ret = __drm_atomic_helper_set_config(mode_set, state);
 		if (ret != 0)
@@ -829,6 +834,7 @@ int drm_fb_helper_init(struct drm_device *dev,
 		if (!fb_helper->crtc_info[i].mode_set.connectors)
 			goto out_free;
 		fb_helper->crtc_info[i].mode_set.num_connectors = 0;
+		fb_helper->crtc_info[i].rotation = DRM_MODE_ROTATE_0;
 	}
 
 	i = 0;
@@ -2353,6 +2359,62 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
 	return best_score;
 }
 
+/*
+ * This function checks if rotation is necessary because of panel orientation
+ * and if it is, if it is supported.
+ * If rotation is necessary and supported, its gets set in fb_crtc.rotation.
+ * If rotation is necessary but not supported, a DRM_MODE_ROTATE_* flag gets
+ * or-ed into fb_helper->sw_rotations. In drm_setup_crtcs_fb() we check if only
+ * one bit is set and then we set fb_info.fbcon_rotate_hint to make fbcon do
+ * the unsupported rotation.
+ */
+static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper,
+				    struct drm_fb_helper_crtc *fb_crtc,
+				    struct drm_connector *connector)
+{
+	struct drm_plane *plane = fb_crtc->mode_set.crtc->primary;
+	uint64_t valid_mask = 0;
+	int i, rotation;
+
+	fb_crtc->rotation = DRM_MODE_ROTATE_0;
+
+	switch (connector->display_info.panel_orientation) {
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		rotation = DRM_MODE_ROTATE_180;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		rotation = DRM_MODE_ROTATE_90;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		rotation = DRM_MODE_ROTATE_270;
+		break;
+	default:
+		rotation = DRM_MODE_ROTATE_0;
+	}
+
+	/*
+	 * TODO: support 90 / 270 degree hardware rotation,
+	 * depending on the hardware this may require the framebuffer
+	 * to be in a specific tiling format.
+	 */
+	if (rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) {
+		fb_helper->sw_rotations |= rotation;
+		return;
+	}
+
+	for (i = 0; i < plane->rotation_property->num_values; i++)
+		valid_mask |= (1ULL << plane->rotation_property->values[i]);
+
+	if (!(rotation & valid_mask)) {
+		fb_helper->sw_rotations |= rotation;
+		return;
+	}
+
+	fb_crtc->rotation = rotation;
+	/* Rotating in hardware, fbcon should not rotate */
+	fb_helper->sw_rotations |= DRM_MODE_ROTATE_0;
+}
+
 static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			    u32 width, u32 height)
 {
@@ -2412,6 +2474,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 		drm_fb_helper_modeset_release(fb_helper,
 					      &fb_helper->crtc_info[i].mode_set);
 
+	fb_helper->sw_rotations = 0;
 	drm_fb_helper_for_each_connector(fb_helper, i) {
 		struct drm_display_mode *mode = modes[i];
 		struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
@@ -2431,6 +2494,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			modeset->mode = drm_mode_duplicate(dev,
 							   fb_crtc->desired_mode);
 			drm_connector_get(connector);
+			drm_setup_crtc_rotation(fb_helper, fb_crtc, connector);
 			modeset->connectors[modeset->num_connectors++] = connector;
 			modeset->x = offset->x;
 			modeset->y = offset->y;
@@ -2472,6 +2536,28 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
 		}
 	}
 	mutex_unlock(&fb_helper->dev->mode_config.mutex);
+
+	switch (fb_helper->sw_rotations) {
+	case DRM_MODE_ROTATE_0:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_ROTATE_90:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_ROTATE_180:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_ROTATE_270:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	default:
+		/*
+		 * Multiple bits are set / multiple rotations requested
+		 * fbcon cannot handle separate rotation settings per
+		 * output, so fallback to unrotated.
+		 */
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+	}
 }
 
 /* Note: Drops fb_helper->lock before returning. */
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 877e5b395c02..1494b12a984a 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -48,6 +48,7 @@ struct drm_fb_helper_crtc {
 	struct drm_mode_set mode_set;
 	struct drm_display_mode *desired_mode;
 	int x, y;
+	int rotation;
 };
 
 /**
@@ -158,6 +159,13 @@ struct drm_fb_helper {
 	struct drm_fb_helper_crtc *crtc_info;
 	int connector_count;
 	int connector_info_alloc_count;
+	/**
+	 * @sw_rotations:
+	 * Bitmask of all rotations requested for panel-orientation which
+	 * could not be handled in hardware. If only one bit is set
+	 * fbdev->fbcon_rotate_hint gets set to the requested rotation.
+	 */
+	int sw_rotations;
 	/**
 	 * @connector_info:
 	 *
-- 
2.14.3


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

* [PATCH v6 4/7] drm/fb-helper: Apply panel orientation connector prop to the primary plane, v6.
@ 2017-11-25 19:16     ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Apply the "panel orientation" drm connector prop to the primary plane so
that fbcon and fbdev using userspace programs display the right way up.

Changes in v3:
-Use a rotation member in struct drm_fb_helper_crtc and set that from
 drm_setup_crtcs instead of looping over all crtc's to find the right one
 later
-Since we now no longer look at rotation quirks directly in the fbcon
 code, set fb_info.fbcon_rotate_hint when the panel is not mounted upright
 and we cannot use hardware rotation

Changes in v4:
-Make drm_fb_helper_init() init drm_fb_helper_crtc.rotation to
 DRM_MODE_ROTATE_0 for all crtcs, so that we do not end up setting the
 plane_state's rotation to an invalid value for disabled crtcs
 (caught by Fi.CI)

Changes in v5:
-Only use hardware (crtc primary plane) rotation for DRM_ROTATE_180,
 90 / 270 degree rotation requires special handling which we lack atm
-Add a TODO comment for 90 / 270 degree hardware rotation
-Add some comments to better document the default case when mapping
 sw_rotations to fbcon_rotate_hints

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=94894
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/drm_fb_helper.c | 90 ++++++++++++++++++++++++++++++++++++++++-
 include/drm/drm_fb_helper.h     |  8 ++++
 2 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 832739ff58bf..57d6bad379f8 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -41,6 +41,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 
+#include "drm_crtc_internal.h"
 #include "drm_crtc_helper_internal.h"
 
 static bool drm_fbdev_emulation = true;
@@ -356,6 +357,7 @@ EXPORT_SYMBOL(drm_fb_helper_debug_leave);
 static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active)
 {
 	struct drm_device *dev = fb_helper->dev;
+	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	struct drm_atomic_state *state;
 	int i, ret;
@@ -374,8 +376,6 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 retry:
 	plane_mask = 0;
 	drm_for_each_plane(plane, dev) {
-		struct drm_plane_state *plane_state;
-
 		plane_state = drm_atomic_get_plane_state(state, plane);
 		if (IS_ERR(plane_state)) {
 			ret = PTR_ERR(plane_state);
@@ -398,6 +398,11 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
+		struct drm_plane *primary = mode_set->crtc->primary;
+
+		/* Cannot fail as we've already gotten the plane state above */
+		plane_state = drm_atomic_get_new_plane_state(state, primary);
+		plane_state->rotation = fb_helper->crtc_info[i].rotation;
 
 		ret = __drm_atomic_helper_set_config(mode_set, state);
 		if (ret != 0)
@@ -829,6 +834,7 @@ int drm_fb_helper_init(struct drm_device *dev,
 		if (!fb_helper->crtc_info[i].mode_set.connectors)
 			goto out_free;
 		fb_helper->crtc_info[i].mode_set.num_connectors = 0;
+		fb_helper->crtc_info[i].rotation = DRM_MODE_ROTATE_0;
 	}
 
 	i = 0;
@@ -2353,6 +2359,62 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
 	return best_score;
 }
 
+/*
+ * This function checks if rotation is necessary because of panel orientation
+ * and if it is, if it is supported.
+ * If rotation is necessary and supported, its gets set in fb_crtc.rotation.
+ * If rotation is necessary but not supported, a DRM_MODE_ROTATE_* flag gets
+ * or-ed into fb_helper->sw_rotations. In drm_setup_crtcs_fb() we check if only
+ * one bit is set and then we set fb_info.fbcon_rotate_hint to make fbcon do
+ * the unsupported rotation.
+ */
+static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper,
+				    struct drm_fb_helper_crtc *fb_crtc,
+				    struct drm_connector *connector)
+{
+	struct drm_plane *plane = fb_crtc->mode_set.crtc->primary;
+	uint64_t valid_mask = 0;
+	int i, rotation;
+
+	fb_crtc->rotation = DRM_MODE_ROTATE_0;
+
+	switch (connector->display_info.panel_orientation) {
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		rotation = DRM_MODE_ROTATE_180;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		rotation = DRM_MODE_ROTATE_90;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		rotation = DRM_MODE_ROTATE_270;
+		break;
+	default:
+		rotation = DRM_MODE_ROTATE_0;
+	}
+
+	/*
+	 * TODO: support 90 / 270 degree hardware rotation,
+	 * depending on the hardware this may require the framebuffer
+	 * to be in a specific tiling format.
+	 */
+	if (rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) {
+		fb_helper->sw_rotations |= rotation;
+		return;
+	}
+
+	for (i = 0; i < plane->rotation_property->num_values; i++)
+		valid_mask |= (1ULL << plane->rotation_property->values[i]);
+
+	if (!(rotation & valid_mask)) {
+		fb_helper->sw_rotations |= rotation;
+		return;
+	}
+
+	fb_crtc->rotation = rotation;
+	/* Rotating in hardware, fbcon should not rotate */
+	fb_helper->sw_rotations |= DRM_MODE_ROTATE_0;
+}
+
 static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			    u32 width, u32 height)
 {
@@ -2412,6 +2474,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 		drm_fb_helper_modeset_release(fb_helper,
 					      &fb_helper->crtc_info[i].mode_set);
 
+	fb_helper->sw_rotations = 0;
 	drm_fb_helper_for_each_connector(fb_helper, i) {
 		struct drm_display_mode *mode = modes[i];
 		struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
@@ -2431,6 +2494,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			modeset->mode = drm_mode_duplicate(dev,
 							   fb_crtc->desired_mode);
 			drm_connector_get(connector);
+			drm_setup_crtc_rotation(fb_helper, fb_crtc, connector);
 			modeset->connectors[modeset->num_connectors++] = connector;
 			modeset->x = offset->x;
 			modeset->y = offset->y;
@@ -2472,6 +2536,28 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
 		}
 	}
 	mutex_unlock(&fb_helper->dev->mode_config.mutex);
+
+	switch (fb_helper->sw_rotations) {
+	case DRM_MODE_ROTATE_0:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_ROTATE_90:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_ROTATE_180:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_ROTATE_270:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	default:
+		/*
+		 * Multiple bits are set / multiple rotations requested
+		 * fbcon cannot handle separate rotation settings per
+		 * output, so fallback to unrotated.
+		 */
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+	}
 }
 
 /* Note: Drops fb_helper->lock before returning. */
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 877e5b395c02..1494b12a984a 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -48,6 +48,7 @@ struct drm_fb_helper_crtc {
 	struct drm_mode_set mode_set;
 	struct drm_display_mode *desired_mode;
 	int x, y;
+	int rotation;
 };
 
 /**
@@ -158,6 +159,13 @@ struct drm_fb_helper {
 	struct drm_fb_helper_crtc *crtc_info;
 	int connector_count;
 	int connector_info_alloc_count;
+	/**
+	 * @sw_rotations:
+	 * Bitmask of all rotations requested for panel-orientation which
+	 * could not be handled in hardware. If only one bit is set
+	 * fbdev->fbcon_rotate_hint gets set to the requested rotation.
+	 */
+	int sw_rotations;
 	/**
 	 * @connector_info:
 	 *
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6.
  2017-11-25 19:16   ` Hans de Goede
@ 2017-11-25 19:16     ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Ideally we could use the VBT for this, that would be simple, in
intel_dsi_init() check dev_priv->vbt.dsi.config->rotation, set
connector->display_info.panel_orientation accordingly and call
drm_connector_init_panel_orientation_property(), done.

Unfortunately vbt.dsi.config->rotation is always 0 even on tablets
with an upside down LCD and where the GOP is properly rotating the
EFI fb in hardware.

So instead we end up reading the rotation from the primary plane.

This commit only implements the panel orientation property for DSI
panels on BYT / CHT hardware, as all known non normal oriented panels
sofar are only found on this hardware.

Changes in v2:
-Read back the rotation applied by the GOP from the primary plane
 instead of relying on dev_priv->vbt.dsi.config->rotation, because it
 seems that the VBT rotation filed is always 0 even on devices where the
 GOP does apply a rotation

Changes in v3:
-Rewrite the code to read back the orientation from the primary
 plane to contain all of this in intel_dsi.c instead of poking a bunch
 of holes between all the different layers

Changes in v6:
-Move hardware readout to intel_dsi_init()

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/i915/intel_dsi.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index f09474b0c4d3..f67d321376e4 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1666,6 +1666,27 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
 	.atomic_duplicate_state = intel_digital_connector_duplicate_state,
 };
 
+static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
+	enum i9xx_plane_id plane;
+	u32 val;
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		if (connector->encoder->crtc_mask = BIT(PIPE_B))
+			plane = PLANE_B;
+		else
+			plane = PLANE_A;
+
+		val = I915_READ(DSPCNTR(plane));
+		if (val & DISPPLANE_ROTATE_180)
+			orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
+	}
+
+	return orientation;
+}
+
 static void intel_dsi_add_properties(struct intel_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1681,6 +1702,13 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
 								allowed_scalers);
 
 		connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
+
+		connector->base.display_info.panel_orientation +			intel_dsi_get_panel_orientation(connector);
+		drm_connector_init_panel_orientation_property(
+				&connector->base,
+				connector->panel.fixed_mode->hdisplay,
+				connector->panel.fixed_mode->vdisplay);
 	}
 }
 
-- 
2.14.3


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

* [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6.
@ 2017-11-25 19:16     ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

Ideally we could use the VBT for this, that would be simple, in
intel_dsi_init() check dev_priv->vbt.dsi.config->rotation, set
connector->display_info.panel_orientation accordingly and call
drm_connector_init_panel_orientation_property(), done.

Unfortunately vbt.dsi.config->rotation is always 0 even on tablets
with an upside down LCD and where the GOP is properly rotating the
EFI fb in hardware.

So instead we end up reading the rotation from the primary plane.

This commit only implements the panel orientation property for DSI
panels on BYT / CHT hardware, as all known non normal oriented panels
sofar are only found on this hardware.

Changes in v2:
-Read back the rotation applied by the GOP from the primary plane
 instead of relying on dev_priv->vbt.dsi.config->rotation, because it
 seems that the VBT rotation filed is always 0 even on devices where the
 GOP does apply a rotation

Changes in v3:
-Rewrite the code to read back the orientation from the primary
 plane to contain all of this in intel_dsi.c instead of poking a bunch
 of holes between all the different layers

Changes in v6:
-Move hardware readout to intel_dsi_init()

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/i915/intel_dsi.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index f09474b0c4d3..f67d321376e4 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1666,6 +1666,27 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
 	.atomic_duplicate_state = intel_digital_connector_duplicate_state,
 };
 
+static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
+	enum i9xx_plane_id plane;
+	u32 val;
+
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		if (connector->encoder->crtc_mask == BIT(PIPE_B))
+			plane = PLANE_B;
+		else
+			plane = PLANE_A;
+
+		val = I915_READ(DSPCNTR(plane));
+		if (val & DISPPLANE_ROTATE_180)
+			orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
+	}
+
+	return orientation;
+}
+
 static void intel_dsi_add_properties(struct intel_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1681,6 +1702,13 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
 								allowed_scalers);
 
 		connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
+
+		connector->base.display_info.panel_orientation =
+			intel_dsi_get_panel_orientation(connector);
+		drm_connector_init_panel_orientation_property(
+				&connector->base,
+				connector->panel.fixed_mode->hdisplay,
+				connector->panel.fixed_mode->vdisplay);
 	}
 }
 
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk
  2017-11-25 19:16   ` Hans de Goede
@ 2017-11-25 19:16     ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some hardware the LCD panel is not mounted upright in the casing,
but rotated by 90 degrees. In this case we want the console to
automatically be rotated to compensate.

The drm subsys has a quirk table for this, use the
drm_get_panel_orientation_quirk function to get the panel orientation
and set info->fbcon_rotate_hint based on this, so that the fbcon console
on top of efifb gets automatically rotated to compensate for the panel
orientation.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/Kconfig |  1 +
 drivers/video/fbdev/efifb.c | 21 ++++++++++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 5e58f5ec0a28..c4a90c497839 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -772,6 +772,7 @@ config FB_VESA
 config FB_EFI
 	bool "EFI-based Framebuffer Support"
 	depends on (FB = y) && !IA64 && EFI
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index d1bf9c2a78a7..88697ab1005b 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -16,6 +16,8 @@
 #include <linux/screen_info.h>
 #include <video/vga.h>
 #include <asm/efi.h>
+#include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */
+#include <drm/drm_mode.h>  /* For DRM_MODE_PANEL_ORIENTATION_* */
 
 static bool request_mem_succeeded = false;
 static bool nowc = false;
@@ -157,7 +159,7 @@ static u64 bar_offset;
 static int efifb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
-	int err;
+	int err, orientation;
 	unsigned int size_vmode;
 	unsigned int size_remap;
 	unsigned int size_total;
@@ -329,6 +331,23 @@ static int efifb_probe(struct platform_device *dev)
 	info->fix = efifb_fix;
 	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
 
+	orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
+						      efifb_defined.yres);
+	switch (orientation) {
+	default:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	}
+
 	err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
 	if (err) {
 		pr_err("efifb: cannot add sysfs attrs\n");
-- 
2.14.3


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

* [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk
@ 2017-11-25 19:16     ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

On some hardware the LCD panel is not mounted upright in the casing,
but rotated by 90 degrees. In this case we want the console to
automatically be rotated to compensate.

The drm subsys has a quirk table for this, use the
drm_get_panel_orientation_quirk function to get the panel orientation
and set info->fbcon_rotate_hint based on this, so that the fbcon console
on top of efifb gets automatically rotated to compensate for the panel
orientation.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/Kconfig |  1 +
 drivers/video/fbdev/efifb.c | 21 ++++++++++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 5e58f5ec0a28..c4a90c497839 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -772,6 +772,7 @@ config FB_VESA
 config FB_EFI
 	bool "EFI-based Framebuffer Support"
 	depends on (FB = y) && !IA64 && EFI
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index d1bf9c2a78a7..88697ab1005b 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -16,6 +16,8 @@
 #include <linux/screen_info.h>
 #include <video/vga.h>
 #include <asm/efi.h>
+#include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */
+#include <drm/drm_mode.h>  /* For DRM_MODE_PANEL_ORIENTATION_* */
 
 static bool request_mem_succeeded = false;
 static bool nowc = false;
@@ -157,7 +159,7 @@ static u64 bar_offset;
 static int efifb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
-	int err;
+	int err, orientation;
 	unsigned int size_vmode;
 	unsigned int size_remap;
 	unsigned int size_total;
@@ -329,6 +331,23 @@ static int efifb_probe(struct platform_device *dev)
 	info->fix = efifb_fix;
 	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
 
+	orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
+						      efifb_defined.yres);
+	switch (orientation) {
+	default:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	}
+
 	err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
 	if (err) {
 		pr_err("efifb: cannot add sysfs attrs\n");
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v6 7/7] fbcon: Remove dmi quirk table
  2017-11-25 19:16   ` Hans de Goede
@ 2017-11-25 19:16     ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

This is now all handled in the drivers and communicated through
fb_info.fbcon_rotate_hint.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/core/Makefile           |   3 -
 drivers/video/fbdev/core/fbcon.c            |   4 +-
 drivers/video/fbdev/core/fbcon.h            |   6 --
 drivers/video/fbdev/core/fbcon_dmi_quirks.c | 145 ----------------------------
 4 files changed, 2 insertions(+), 156 deletions(-)
 delete mode 100644 drivers/video/fbdev/core/fbcon_dmi_quirks.c

diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
index d34fd182ca68..37710316a680 100644
--- a/drivers/video/fbdev/core/Makefile
+++ b/drivers/video/fbdev/core/Makefile
@@ -15,9 +15,6 @@ ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
 fb-y				  += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
 				     fbcon_ccw.o
 endif
-ifeq ($(CONFIG_DMI),y)
-fb-y				  += fbcon_dmi_quirks.o
-endif
 endif
 fb-objs                           := $(fb-y)
 
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index fb317ed76b45..157a40670a47 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -968,7 +968,7 @@ static const char *fbcon_startup(void)
 	if (p->con_rotate = -1)
 		p->con_rotate = info->fbcon_rotate_hint;
 	if (p->con_rotate = -1)
-		p->con_rotate = fbcon_platform_get_rotate(info);
+		p->con_rotate = FB_ROTATE_UR;
 
 	set_blitting_type(vc, info);
 
@@ -1111,7 +1111,7 @@ static void fbcon_init(struct vc_data *vc, int init)
 	if (p->con_rotate = -1)
 		p->con_rotate = info->fbcon_rotate_hint;
 	if (p->con_rotate = -1)
-		p->con_rotate = fbcon_platform_get_rotate(info);
+		p->con_rotate = FB_ROTATE_UR;
 
 	set_blitting_type(vc, info);
 
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 18f3ac144237..3746828356ed 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -261,10 +261,4 @@ extern void fbcon_set_rotate(struct fbcon_ops *ops);
 #define fbcon_set_rotate(x) do {} while(0)
 #endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
 
-#ifdef CONFIG_DMI
-int fbcon_platform_get_rotate(struct fb_info *info);
-#else
-#define fbcon_platform_get_rotate(i) FB_ROTATE_UR
-#endif /* CONFIG_DMI */
-
 #endif /* _VIDEO_FBCON_H */
diff --git a/drivers/video/fbdev/core/fbcon_dmi_quirks.c b/drivers/video/fbdev/core/fbcon_dmi_quirks.c
deleted file mode 100644
index 6904e47d1e51..000000000000
--- a/drivers/video/fbdev/core/fbcon_dmi_quirks.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- *  fbcon_dmi_quirks.c -- DMI based quirk detection for fbcon
- *
- *	Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/dmi.h>
-#include <linux/fb.h>
-#include <linux/kernel.h>
-#include "fbcon.h"
-
-/*
- * Some x86 clamshell design devices use portrait tablet screens and a display
- * engine which cannot rotate in hardware, so we need to rotate the fbcon to
- * compensate. Unfortunately these (cheap) devices also typically have quite
- * generic DMI data, so we match on a combination of DMI data, screen resolution
- * and a list of known BIOS dates to avoid false positives.
- */
-
-struct fbcon_dmi_rotate_data {
-	int width;
-	int height;
-	const char * const *bios_dates;
-	int rotate;
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_asus_t100ha = {
-	.width = 800,
-	.height = 1280,
-	.rotate = FB_ROTATE_CCW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_gpd_pocket = {
-	.width = 1200,
-	.height = 1920,
-	.bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
-		"07/05/2017", "08/07/2017", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_gpd_win = {
-	.width = 720,
-	.height = 1280,
-	.bios_dates = (const char * const []){
-		"10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
-		"02/21/2017", "03/20/2017", "05/25/2017", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_itworks_tw891 = {
-	.width = 800,
-	.height = 1280,
-	.bios_dates = (const char * const []){ "10/16/2015", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_vios_lth17 = {
-	.width = 800,
-	.height = 1280,
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct dmi_system_id rotate_data[] = {
-	{	/* Asus T100HA */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
-		},
-		.driver_data = (void *)&rotate_data_asus_t100ha,
-	}, {	/*
-		 * GPD Pocket, note that the the DMI data is less generic then
-		 * it seems, devices with a board-vendor of "AMI Corporation"
-		 * are quite rare, as are devices which have both board- *and*
-		 * product-id set to "Default String"
-		 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
-		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
-		},
-		.driver_data = (void *)&rotate_data_gpd_pocket,
-	}, {	/* GPD Win (same note on DMI match as GPD Pocket) */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
-		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
-		},
-		.driver_data = (void *)&rotate_data_gpd_win,
-	}, {	/* I.T.Works TW891 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
-		},
-		.driver_data = (void *)&rotate_data_itworks_tw891,
-	}, {	/* VIOS LTH17 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "VIOS"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "LTH17"),
-		},
-		.driver_data = (void *)&rotate_data_vios_lth17,
-	},
-	{}
-};
-
-int fbcon_platform_get_rotate(struct fb_info *info)
-{
-	const struct dmi_system_id *match;
-	const struct fbcon_dmi_rotate_data *data;
-	const char *bios_date;
-	int i;
-
-	for (match = dmi_first_match(rotate_data);
-	     match;
-	     match = dmi_first_match(match + 1)) {
-		data = match->driver_data;
-
-		if (data->width != info->var.xres ||
-		    data->height != info->var.yres)
-			continue;
-
-		if (!data->bios_dates)
-			return data->rotate;
-
-		bios_date = dmi_get_system_info(DMI_BIOS_DATE);
-		if (!bios_date)
-			continue;
-
-		for (i = 0; data->bios_dates[i]; i++) {
-			if (!strcmp(data->bios_dates[i], bios_date))
-				return data->rotate;
-		}
-	}
-
-	return FB_ROTATE_UR;
-}
-- 
2.14.3


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

* [PATCH v6 7/7] fbcon: Remove dmi quirk table
@ 2017-11-25 19:16     ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-25 19:16 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula, Sean Paul, Dave Airlie,
	Bartlomiej Zolnierkiewicz
  Cc: Hans de Goede, intel-gfx, linux-fbdev, dri-devel

This is now all handled in the drivers and communicated through
fb_info.fbcon_rotate_hint.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/core/Makefile           |   3 -
 drivers/video/fbdev/core/fbcon.c            |   4 +-
 drivers/video/fbdev/core/fbcon.h            |   6 --
 drivers/video/fbdev/core/fbcon_dmi_quirks.c | 145 ----------------------------
 4 files changed, 2 insertions(+), 156 deletions(-)
 delete mode 100644 drivers/video/fbdev/core/fbcon_dmi_quirks.c

diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
index d34fd182ca68..37710316a680 100644
--- a/drivers/video/fbdev/core/Makefile
+++ b/drivers/video/fbdev/core/Makefile
@@ -15,9 +15,6 @@ ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
 fb-y				  += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
 				     fbcon_ccw.o
 endif
-ifeq ($(CONFIG_DMI),y)
-fb-y				  += fbcon_dmi_quirks.o
-endif
 endif
 fb-objs                           := $(fb-y)
 
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index fb317ed76b45..157a40670a47 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -968,7 +968,7 @@ static const char *fbcon_startup(void)
 	if (p->con_rotate == -1)
 		p->con_rotate = info->fbcon_rotate_hint;
 	if (p->con_rotate == -1)
-		p->con_rotate = fbcon_platform_get_rotate(info);
+		p->con_rotate = FB_ROTATE_UR;
 
 	set_blitting_type(vc, info);
 
@@ -1111,7 +1111,7 @@ static void fbcon_init(struct vc_data *vc, int init)
 	if (p->con_rotate == -1)
 		p->con_rotate = info->fbcon_rotate_hint;
 	if (p->con_rotate == -1)
-		p->con_rotate = fbcon_platform_get_rotate(info);
+		p->con_rotate = FB_ROTATE_UR;
 
 	set_blitting_type(vc, info);
 
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 18f3ac144237..3746828356ed 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -261,10 +261,4 @@ extern void fbcon_set_rotate(struct fbcon_ops *ops);
 #define fbcon_set_rotate(x) do {} while(0)
 #endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
 
-#ifdef CONFIG_DMI
-int fbcon_platform_get_rotate(struct fb_info *info);
-#else
-#define fbcon_platform_get_rotate(i) FB_ROTATE_UR
-#endif /* CONFIG_DMI */
-
 #endif /* _VIDEO_FBCON_H */
diff --git a/drivers/video/fbdev/core/fbcon_dmi_quirks.c b/drivers/video/fbdev/core/fbcon_dmi_quirks.c
deleted file mode 100644
index 6904e47d1e51..000000000000
--- a/drivers/video/fbdev/core/fbcon_dmi_quirks.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- *  fbcon_dmi_quirks.c -- DMI based quirk detection for fbcon
- *
- *	Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/dmi.h>
-#include <linux/fb.h>
-#include <linux/kernel.h>
-#include "fbcon.h"
-
-/*
- * Some x86 clamshell design devices use portrait tablet screens and a display
- * engine which cannot rotate in hardware, so we need to rotate the fbcon to
- * compensate. Unfortunately these (cheap) devices also typically have quite
- * generic DMI data, so we match on a combination of DMI data, screen resolution
- * and a list of known BIOS dates to avoid false positives.
- */
-
-struct fbcon_dmi_rotate_data {
-	int width;
-	int height;
-	const char * const *bios_dates;
-	int rotate;
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_asus_t100ha = {
-	.width = 800,
-	.height = 1280,
-	.rotate = FB_ROTATE_CCW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_gpd_pocket = {
-	.width = 1200,
-	.height = 1920,
-	.bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
-		"07/05/2017", "08/07/2017", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_gpd_win = {
-	.width = 720,
-	.height = 1280,
-	.bios_dates = (const char * const []){
-		"10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
-		"02/21/2017", "03/20/2017", "05/25/2017", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_itworks_tw891 = {
-	.width = 800,
-	.height = 1280,
-	.bios_dates = (const char * const []){ "10/16/2015", NULL },
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct fbcon_dmi_rotate_data rotate_data_vios_lth17 = {
-	.width = 800,
-	.height = 1280,
-	.rotate = FB_ROTATE_CW,
-};
-
-static const struct dmi_system_id rotate_data[] = {
-	{	/* Asus T100HA */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
-		},
-		.driver_data = (void *)&rotate_data_asus_t100ha,
-	}, {	/*
-		 * GPD Pocket, note that the the DMI data is less generic then
-		 * it seems, devices with a board-vendor of "AMI Corporation"
-		 * are quite rare, as are devices which have both board- *and*
-		 * product-id set to "Default String"
-		 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
-		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
-		},
-		.driver_data = (void *)&rotate_data_gpd_pocket,
-	}, {	/* GPD Win (same note on DMI match as GPD Pocket) */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
-		  DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
-		},
-		.driver_data = (void *)&rotate_data_gpd_win,
-	}, {	/* I.T.Works TW891 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
-		},
-		.driver_data = (void *)&rotate_data_itworks_tw891,
-	}, {	/* VIOS LTH17 */
-		.matches = {
-		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
-		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
-		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "VIOS"),
-		  DMI_EXACT_MATCH(DMI_BOARD_NAME, "LTH17"),
-		},
-		.driver_data = (void *)&rotate_data_vios_lth17,
-	},
-	{}
-};
-
-int fbcon_platform_get_rotate(struct fb_info *info)
-{
-	const struct dmi_system_id *match;
-	const struct fbcon_dmi_rotate_data *data;
-	const char *bios_date;
-	int i;
-
-	for (match = dmi_first_match(rotate_data);
-	     match;
-	     match = dmi_first_match(match + 1)) {
-		data = match->driver_data;
-
-		if (data->width != info->var.xres ||
-		    data->height != info->var.yres)
-			continue;
-
-		if (!data->bios_dates)
-			return data->rotate;
-
-		bios_date = dmi_get_system_info(DMI_BIOS_DATE);
-		if (!bios_date)
-			continue;
-
-		for (i = 0; data->bios_dates[i]; i++) {
-			if (!strcmp(data->bios_dates[i], bios_date))
-				return data->rotate;
-		}
-	}
-
-	return FB_ROTATE_UR;
-}
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✗ Fi.CI.BAT: failure for drm/fbdev: Panel orientation connector property support (rev5)
  2017-11-25 19:16   ` Hans de Goede
                     ` (7 preceding siblings ...)
  (?)
@ 2017-11-25 19:20   ` Patchwork
  -1 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2017-11-25 19:20 UTC (permalink / raw)
  To: Hans de Goede; +Cc: intel-gfx

== Series Details ==

Series: drm/fbdev: Panel orientation connector property support (rev5)
URL   : https://patchwork.freedesktop.org/series/32447/
State : failure

== Summary ==

  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  CHK     include/generated/bounds.h
  CHK     include/generated/timeconst.h
  CHK     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
  DESCEND  objtool
  CHK     scripts/mod/devicetable-offsets.h
  CHK     include/generated/compile.h
  CHK     kernel/config_data.h
  CC      drivers/video/fbdev/efifb.o
drivers/video/fbdev/efifb.c: In function ‘efifb_probe’:
drivers/video/fbdev/efifb.c:340:7: error: ‘DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP’ undeclared (first use in this function)
  case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/video/fbdev/efifb.c:340:7: note: each undeclared identifier is reported only once for each function it appears in
drivers/video/fbdev/efifb.c:343:7: error: ‘DRM_MODE_PANEL_ORIENTATION_LEFT_UP’ undeclared (first use in this function)
  case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/video/fbdev/efifb.c:346:7: error: ‘DRM_MODE_PANEL_ORIENTATION_RIGHT_UP’ undeclared (first use in this function)
  case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
scripts/Makefile.build:314: recipe for target 'drivers/video/fbdev/efifb.o' failed
make[3]: *** [drivers/video/fbdev/efifb.o] Error 1
scripts/Makefile.build:573: recipe for target 'drivers/video/fbdev' failed
make[2]: *** [drivers/video/fbdev] Error 2
scripts/Makefile.build:573: recipe for target 'drivers/video' failed
make[1]: *** [drivers/video] Error 2
Makefile:1024: recipe for target 'drivers' failed
make: *** [drivers] Error 2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6
  2017-11-25 17:33   ` Hans de Goede
@ 2017-11-28 10:25     ` Daniel Vetter
  -1 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2017-11-28 10:25 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, Bartlomiej Zolnierkiewicz, intel-gfx, Hans de Goede,
	dri-devel, Dave Airlie, Daniel Vetter

On Sat, Nov 25, 2017 at 06:33:39PM +0100, Hans de Goede wrote:
> Ideally we could use the VBT for this, that would be simple, in
> intel_dsi_init() check dev_priv->vbt.dsi.config->rotation, set
> connector->display_info.panel_orientation accordingly and call
> drm_connector_init_panel_orientation_property(), done.
> 
> Unfortunately vbt.dsi.config->rotation is always 0 even on tablets
> with an upside down LCD and where the GOP is properly rotating the
> EFI fb in hardware.
> 
> So instead we end up reading the rotation from the primary plane.
> 
> This commit only implements the panel orientation property for DSI
> panels on BYT / CHT hardware, as all known non normal oriented panels
> sofar are only found on this hardware.
> 
> Changes in v2:
> -Read back the rotation applied by the GOP from the primary plane
>  instead of relying on dev_priv->vbt.dsi.config->rotation, because it
>  seems that the VBT rotation filed is always 0 even on devices where the
>  GOP does apply a rotation
> 
> Changes in v3:
> -Rewrite the code to read back the orientation from the primary
>  plane to contain all of this in intel_dsi.c instead of poking a bunch
>  of holes between all the different layers
> 
> Changes in v6:
> -Move hardware readout to intel_dsi_init()

Yeah, this is what I had in mind. A small hack, but much more well
contained.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/gpu/drm/i915/intel_dsi.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index f09474b0c4d3..f67d321376e4 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -1666,6 +1666,27 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
>  	.atomic_duplicate_state = intel_digital_connector_duplicate_state,
>  };
>  
> +static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> +	enum i9xx_plane_id plane;
> +	u32 val;
> +
> +	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
> +		if (connector->encoder->crtc_mask = BIT(PIPE_B))
> +			plane = PLANE_B;
> +		else
> +			plane = PLANE_A;
> +
> +		val = I915_READ(DSPCNTR(plane));
> +		if (val & DISPPLANE_ROTATE_180)
> +			orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
> +	}
> +
> +	return orientation;
> +}
> +
>  static void intel_dsi_add_properties(struct intel_connector *connector)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -1681,6 +1702,13 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
>  								allowed_scalers);
>  
>  		connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
> +
> +		connector->base.display_info.panel_orientation > +			intel_dsi_get_panel_orientation(connector);
> +		drm_connector_init_panel_orientation_property(
> +				&connector->base,
> +				connector->panel.fixed_mode->hdisplay,
> +				connector->panel.fixed_mode->vdisplay);
>  	}
>  }
>  
> -- 
> 2.14.3
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6.
@ 2017-11-28 10:25     ` Daniel Vetter
  0 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2017-11-28 10:25 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, Bartlomiej Zolnierkiewicz, intel-gfx, Hans de Goede,
	dri-devel, Dave Airlie, Daniel Vetter

On Sat, Nov 25, 2017 at 06:33:39PM +0100, Hans de Goede wrote:
> Ideally we could use the VBT for this, that would be simple, in
> intel_dsi_init() check dev_priv->vbt.dsi.config->rotation, set
> connector->display_info.panel_orientation accordingly and call
> drm_connector_init_panel_orientation_property(), done.
> 
> Unfortunately vbt.dsi.config->rotation is always 0 even on tablets
> with an upside down LCD and where the GOP is properly rotating the
> EFI fb in hardware.
> 
> So instead we end up reading the rotation from the primary plane.
> 
> This commit only implements the panel orientation property for DSI
> panels on BYT / CHT hardware, as all known non normal oriented panels
> sofar are only found on this hardware.
> 
> Changes in v2:
> -Read back the rotation applied by the GOP from the primary plane
>  instead of relying on dev_priv->vbt.dsi.config->rotation, because it
>  seems that the VBT rotation filed is always 0 even on devices where the
>  GOP does apply a rotation
> 
> Changes in v3:
> -Rewrite the code to read back the orientation from the primary
>  plane to contain all of this in intel_dsi.c instead of poking a bunch
>  of holes between all the different layers
> 
> Changes in v6:
> -Move hardware readout to intel_dsi_init()

Yeah, this is what I had in mind. A small hack, but much more well
contained.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/gpu/drm/i915/intel_dsi.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index f09474b0c4d3..f67d321376e4 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -1666,6 +1666,27 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
>  	.atomic_duplicate_state = intel_digital_connector_duplicate_state,
>  };
>  
> +static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> +	enum i9xx_plane_id plane;
> +	u32 val;
> +
> +	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
> +		if (connector->encoder->crtc_mask == BIT(PIPE_B))
> +			plane = PLANE_B;
> +		else
> +			plane = PLANE_A;
> +
> +		val = I915_READ(DSPCNTR(plane));
> +		if (val & DISPPLANE_ROTATE_180)
> +			orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
> +	}
> +
> +	return orientation;
> +}
> +
>  static void intel_dsi_add_properties(struct intel_connector *connector)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -1681,6 +1702,13 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
>  								allowed_scalers);
>  
>  		connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
> +
> +		connector->base.display_info.panel_orientation =
> +			intel_dsi_get_panel_orientation(connector);
> +		drm_connector_init_panel_orientation_property(
> +				&connector->base,
> +				connector->panel.fixed_mode->hdisplay,
> +				connector->panel.fixed_mode->vdisplay);
>  	}
>  }
>  
> -- 
> 2.14.3
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
  2017-11-25 17:33 ` Hans de Goede
@ 2017-11-28 10:27   ` Daniel Vetter
  -1 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2017-11-28 10:27 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, Bartlomiej Zolnierkiewicz, intel-gfx, Hans de Goede,
	dri-devel, Dave Airlie, Daniel Vetter

On Sat, Nov 25, 2017 at 06:33:34PM +0100, Hans de Goede wrote:
> Hi All,
> 
> Here is v6 of my series to add a "panel orientation" property to
> the drm-connector for the LCD panel to let userspace know about LCD
> panels which are not mounted upright, as well as detecting upside-down
> panels without needing quirks (like we do for 90 degree rotated screens).
> 
> Bartlomiej, can we please have your Acked-by for merging patches 1,
> 6 and 7 through the drm tree?
> 
> New in v6:
> -Fix / reference kernel-doc comments
> -Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
> -Move i915 dsi hardware rotation state read-out to intel_dsi_init()
> 
> New in v5:
> -Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
> -drm_fb_helper: Only use hardware (crtc primary plane) rotation for
>  180 degrees for now as 9-/270 degrees rotation requires special handling
> 
> New in v4:
> -Fix drm_fb_helper code setting an invalid rotation value on the primary
>  plane of disabled/unused crtcs (caught by Fi.CI)
> 
> New in v3:
> -As requested by Daniel v3 moves the quirks over from the fbdev
>  subsys to the drm subsys. I've done this by simpy starting with a copy of
>  the quirk table and eventually removing the fbdev version.
> 
> The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
> are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
> discussed previously the plan is to merge all 7 patches through the
> drm tree.

I think from the drm and i915 side of things this all looks ready (well
pls double-check that CI also approves before merging).

Just needs an ack/review from Bart, and then it's probably simplest if you
merge it all through drm-misc - the i915 side is tiny.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [Intel-gfx] [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
@ 2017-11-28 10:27   ` Daniel Vetter
  0 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2017-11-28 10:27 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, Bartlomiej Zolnierkiewicz, intel-gfx, Hans de Goede,
	dri-devel, Dave Airlie, Daniel Vetter

On Sat, Nov 25, 2017 at 06:33:34PM +0100, Hans de Goede wrote:
> Hi All,
> 
> Here is v6 of my series to add a "panel orientation" property to
> the drm-connector for the LCD panel to let userspace know about LCD
> panels which are not mounted upright, as well as detecting upside-down
> panels without needing quirks (like we do for 90 degree rotated screens).
> 
> Bartlomiej, can we please have your Acked-by for merging patches 1,
> 6 and 7 through the drm tree?
> 
> New in v6:
> -Fix / reference kernel-doc comments
> -Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
> -Move i915 dsi hardware rotation state read-out to intel_dsi_init()
> 
> New in v5:
> -Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
> -drm_fb_helper: Only use hardware (crtc primary plane) rotation for
>  180 degrees for now as 9-/270 degrees rotation requires special handling
> 
> New in v4:
> -Fix drm_fb_helper code setting an invalid rotation value on the primary
>  plane of disabled/unused crtcs (caught by Fi.CI)
> 
> New in v3:
> -As requested by Daniel v3 moves the quirks over from the fbdev
>  subsys to the drm subsys. I've done this by simpy starting with a copy of
>  the quirk table and eventually removing the fbdev version.
> 
> The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
> are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
> discussed previously the plan is to merge all 7 patches through the
> drm tree.

I think from the drm and i915 side of things this all looks ready (well
pls double-check that CI also approves before merging).

Just needs an ack/review from Bart, and then it's probably simplest if you
merge it all through drm-misc - the i915 side is tiny.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
  2017-11-28 10:27   ` Daniel Vetter
@ 2017-11-28 13:36     ` Hans de Goede
  -1 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-28 13:36 UTC (permalink / raw)
  To: Daniel Vetter, Hans de Goede
  Cc: linux-fbdev, Bartlomiej Zolnierkiewicz, intel-gfx, dri-devel,
	Dave Airlie, Daniel Vetter

Hi,

On 28-11-17 11:27, Daniel Vetter wrote:
> On Sat, Nov 25, 2017 at 06:33:34PM +0100, Hans de Goede wrote:
>> Hi All,
>>
>> Here is v6 of my series to add a "panel orientation" property to
>> the drm-connector for the LCD panel to let userspace know about LCD
>> panels which are not mounted upright, as well as detecting upside-down
>> panels without needing quirks (like we do for 90 degree rotated screens).
>>
>> Bartlomiej, can we please have your Acked-by for merging patches 1,
>> 6 and 7 through the drm tree?
>>
>> New in v6:
>> -Fix / reference kernel-doc comments
>> -Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
>> -Move i915 dsi hardware rotation state read-out to intel_dsi_init()
>>
>> New in v5:
>> -Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
>> -drm_fb_helper: Only use hardware (crtc primary plane) rotation for
>>   180 degrees for now as 9-/270 degrees rotation requires special handling
>>
>> New in v4:
>> -Fix drm_fb_helper code setting an invalid rotation value on the primary
>>   plane of disabled/unused crtcs (caught by Fi.CI)
>>
>> New in v3:
>> -As requested by Daniel v3 moves the quirks over from the fbdev
>>   subsys to the drm subsys. I've done this by simpy starting with a copy of
>>   the quirk table and eventually removing the fbdev version.
>>
>> The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
>> are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
>> discussed previously the plan is to merge all 7 patches through the
>> drm tree.
> 
> I think from the drm and i915 side of things this all looks ready (well
> pls double-check that CI also approves before merging).

The CI says state is warning, see:
https://patchwork.freedesktop.org/series/32447/
and specifically:
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7290/shards.html

Which I find hard to read as I see no tests going to orange, only
3 tests moving to red, which AFAICT is failed. Clicking on the tests
link to get history all 3 tests seem to fail in the same way quite
often (2 out of 3) or somewhat often (the last one). Also the failures
seem unrelated to my changes

So how do I deal with this, resend v7 to get CI to run again and hope
I get a success result for all tests this time ?

> Just needs an ack/review from Bart, and then it's probably simplest if you
> merge it all through drm-misc - the i915 side is tiny.

Ok, I will wait for an Ack from Bart and then merge this through drm-misc,
thank you for the review.

Regards,

Hans


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

* Re: [Intel-gfx] [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
@ 2017-11-28 13:36     ` Hans de Goede
  0 siblings, 0 replies; 52+ messages in thread
From: Hans de Goede @ 2017-11-28 13:36 UTC (permalink / raw)
  To: Daniel Vetter, Hans de Goede
  Cc: linux-fbdev, Bartlomiej Zolnierkiewicz, intel-gfx, dri-devel,
	Dave Airlie, Daniel Vetter

Hi,

On 28-11-17 11:27, Daniel Vetter wrote:
> On Sat, Nov 25, 2017 at 06:33:34PM +0100, Hans de Goede wrote:
>> Hi All,
>>
>> Here is v6 of my series to add a "panel orientation" property to
>> the drm-connector for the LCD panel to let userspace know about LCD
>> panels which are not mounted upright, as well as detecting upside-down
>> panels without needing quirks (like we do for 90 degree rotated screens).
>>
>> Bartlomiej, can we please have your Acked-by for merging patches 1,
>> 6 and 7 through the drm tree?
>>
>> New in v6:
>> -Fix / reference kernel-doc comments
>> -Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
>> -Move i915 dsi hardware rotation state read-out to intel_dsi_init()
>>
>> New in v5:
>> -Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
>> -drm_fb_helper: Only use hardware (crtc primary plane) rotation for
>>   180 degrees for now as 9-/270 degrees rotation requires special handling
>>
>> New in v4:
>> -Fix drm_fb_helper code setting an invalid rotation value on the primary
>>   plane of disabled/unused crtcs (caught by Fi.CI)
>>
>> New in v3:
>> -As requested by Daniel v3 moves the quirks over from the fbdev
>>   subsys to the drm subsys. I've done this by simpy starting with a copy of
>>   the quirk table and eventually removing the fbdev version.
>>
>> The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
>> are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
>> discussed previously the plan is to merge all 7 patches through the
>> drm tree.
> 
> I think from the drm and i915 side of things this all looks ready (well
> pls double-check that CI also approves before merging).

The CI says state is warning, see:
https://patchwork.freedesktop.org/series/32447/
and specifically:
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7290/shards.html

Which I find hard to read as I see no tests going to orange, only
3 tests moving to red, which AFAICT is failed. Clicking on the tests
link to get history all 3 tests seem to fail in the same way quite
often (2 out of 3) or somewhat often (the last one). Also the failures
seem unrelated to my changes

So how do I deal with this, resend v7 to get CI to run again and hope
I get a success result for all tests this time ?

> Just needs an ack/review from Bart, and then it's probably simplest if you
> merge it all through drm-misc - the i915 side is tiny.

Ok, I will wait for an Ack from Bart and then merge this through drm-misc,
thank you for the review.

Regards,

Hans

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

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

* Re: [Intel-gfx] [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation
  2017-11-25 17:33   ` Hans de Goede
@ 2017-11-28 15:47 ` kbuild test robot
  -1 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 15:47 UTC (permalink / raw)
  To: linux-fbdev

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.15-rc1 next-20171128]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171128-225025
config: i386-randconfig-x003-201748 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/video/fbdev/efifb.c: In function 'efifb_probe':
>> drivers/video/fbdev/efifb.c:340:7: error: 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PRESENT_BOTTOM_FIELD'?
     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PRESENT_BOTTOM_FIELD
   drivers/video/fbdev/efifb.c:340:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/video/fbdev/efifb.c:343:7: error: 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP'?
     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP
>> drivers/video/fbdev/efifb.c:346:7: error: 'DRM_MODE_PANEL_ORIENTATION_RIGHT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP'?
     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_LEFT_UP

vim +340 drivers/video/fbdev/efifb.c

   158	
   159	static int efifb_probe(struct platform_device *dev)
   160	{
   161		struct fb_info *info;
   162		int err, orientation;
   163		unsigned int size_vmode;
   164		unsigned int size_remap;
   165		unsigned int size_total;
   166		char *option = NULL;
   167	
   168		if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
   169			return -ENODEV;
   170	
   171		if (fb_get_options("efifb", &option))
   172			return -ENODEV;
   173		efifb_setup(option);
   174	
   175		/* We don't get linelength from UGA Draw Protocol, only from
   176		 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
   177		 * passed in from the user, we really can't use the framebuffer.
   178		 */
   179		if (!screen_info.lfb_linelength)
   180			return -ENODEV;
   181	
   182		if (!screen_info.lfb_depth)
   183			screen_info.lfb_depth = 32;
   184		if (!screen_info.pages)
   185			screen_info.pages = 1;
   186		if (!fb_base_is_valid()) {
   187			printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
   188			return -ENODEV;
   189		}
   190		printk(KERN_INFO "efifb: probing for efifb\n");
   191	
   192		/* just assume they're all unset if any are */
   193		if (!screen_info.blue_size) {
   194			screen_info.blue_size = 8;
   195			screen_info.blue_pos = 0;
   196			screen_info.green_size = 8;
   197			screen_info.green_pos = 8;
   198			screen_info.red_size = 8;
   199			screen_info.red_pos = 16;
   200			screen_info.rsvd_size = 8;
   201			screen_info.rsvd_pos = 24;
   202		}
   203	
   204		efifb_fix.smem_start = screen_info.lfb_base;
   205	
   206		if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
   207			u64 ext_lfb_base;
   208	
   209			ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
   210			efifb_fix.smem_start |= ext_lfb_base;
   211		}
   212	
   213		if (bar_resource &&
   214		    bar_resource->start + bar_offset != efifb_fix.smem_start) {
   215			dev_info(&efifb_pci_dev->dev,
   216				 "BAR has moved, updating efifb address\n");
   217			efifb_fix.smem_start = bar_resource->start + bar_offset;
   218		}
   219	
   220		efifb_defined.bits_per_pixel = screen_info.lfb_depth;
   221		efifb_defined.xres = screen_info.lfb_width;
   222		efifb_defined.yres = screen_info.lfb_height;
   223		efifb_fix.line_length = screen_info.lfb_linelength;
   224	
   225		/*   size_vmode -- that is the amount of memory needed for the
   226		 *                 used video mode, i.e. the minimum amount of
   227		 *                 memory we need. */
   228		size_vmode = efifb_defined.yres * efifb_fix.line_length;
   229	
   230		/*   size_total -- all video memory we have. Used for
   231		 *                 entries, ressource allocation and bounds
   232		 *                 checking. */
   233		size_total = screen_info.lfb_size;
   234		if (size_total < size_vmode)
   235			size_total = size_vmode;
   236	
   237		/*   size_remap -- the amount of video memory we are going to
   238		 *                 use for efifb.  With modern cards it is no
   239		 *                 option to simply use size_total as that
   240		 *                 wastes plenty of kernel address space. */
   241		size_remap  = size_vmode * 2;
   242		if (size_remap > size_total)
   243			size_remap = size_total;
   244		if (size_remap % PAGE_SIZE)
   245			size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
   246		efifb_fix.smem_len = size_remap;
   247	
   248		if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
   249			request_mem_succeeded = true;
   250		} else {
   251			/* We cannot make this fatal. Sometimes this comes from magic
   252			   spaces our resource handlers simply don't know about */
   253			pr_warn("efifb: cannot reserve video memory at 0x%lx\n",
   254				efifb_fix.smem_start);
   255		}
   256	
   257		info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   258		if (!info) {
   259			pr_err("efifb: cannot allocate framebuffer\n");
   260			err = -ENOMEM;
   261			goto err_release_mem;
   262		}
   263		platform_set_drvdata(dev, info);
   264		info->pseudo_palette = info->par;
   265		info->par = NULL;
   266	
   267		info->apertures = alloc_apertures(1);
   268		if (!info->apertures) {
   269			err = -ENOMEM;
   270			goto err_release_fb;
   271		}
   272		info->apertures->ranges[0].base = efifb_fix.smem_start;
   273		info->apertures->ranges[0].size = size_remap;
   274	
   275		if (nowc)
   276			info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
   277		else
   278			info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
   279		if (!info->screen_base) {
   280			pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
   281				efifb_fix.smem_len, efifb_fix.smem_start);
   282			err = -EIO;
   283			goto err_release_fb;
   284		}
   285	
   286		pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
   287		       efifb_fix.smem_start, size_remap/1024, size_total/1024);
   288		pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
   289		       efifb_defined.xres, efifb_defined.yres,
   290		       efifb_defined.bits_per_pixel, efifb_fix.line_length,
   291		       screen_info.pages);
   292	
   293		efifb_defined.xres_virtual = efifb_defined.xres;
   294		efifb_defined.yres_virtual = efifb_fix.smem_len /
   295						efifb_fix.line_length;
   296		pr_info("efifb: scrolling: redraw\n");
   297		efifb_defined.yres_virtual = efifb_defined.yres;
   298	
   299		/* some dummy values for timing to make fbset happy */
   300		efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
   301						1000 / efifb_defined.yres;
   302		efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
   303		efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
   304	
   305		efifb_defined.red.offset    = screen_info.red_pos;
   306		efifb_defined.red.length    = screen_info.red_size;
   307		efifb_defined.green.offset  = screen_info.green_pos;
   308		efifb_defined.green.length  = screen_info.green_size;
   309		efifb_defined.blue.offset   = screen_info.blue_pos;
   310		efifb_defined.blue.length   = screen_info.blue_size;
   311		efifb_defined.transp.offset = screen_info.rsvd_pos;
   312		efifb_defined.transp.length = screen_info.rsvd_size;
   313	
   314		pr_info("efifb: %s: "
   315		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
   316		       "Truecolor",
   317		       screen_info.rsvd_size,
   318		       screen_info.red_size,
   319		       screen_info.green_size,
   320		       screen_info.blue_size,
   321		       screen_info.rsvd_pos,
   322		       screen_info.red_pos,
   323		       screen_info.green_pos,
   324		       screen_info.blue_pos);
   325	
   326		efifb_fix.ypanstep  = 0;
   327		efifb_fix.ywrapstep = 0;
   328	
   329		info->fbops = &efifb_ops;
   330		info->var = efifb_defined;
   331		info->fix = efifb_fix;
   332		info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
   333	
   334		orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
   335							      efifb_defined.yres);
   336		switch (orientation) {
   337		default:
   338			info->fbcon_rotate_hint = FB_ROTATE_UR;
   339			break;
 > 340		case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
   341			info->fbcon_rotate_hint = FB_ROTATE_UD;
   342			break;
 > 343		case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
   344			info->fbcon_rotate_hint = FB_ROTATE_CCW;
   345			break;
 > 346		case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
   347			info->fbcon_rotate_hint = FB_ROTATE_CW;
   348			break;
   349		}
   350	
   351		err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
   352		if (err) {
   353			pr_err("efifb: cannot add sysfs attrs\n");
   354			goto err_unmap;
   355		}
   356		err = fb_alloc_cmap(&info->cmap, 256, 0);
   357		if (err < 0) {
   358			pr_err("efifb: cannot allocate colormap\n");
   359			goto err_groups;
   360		}
   361		err = register_framebuffer(info);
   362		if (err < 0) {
   363			pr_err("efifb: cannot register framebuffer\n");
   364			goto err_fb_dealoc;
   365		}
   366		fb_info(info, "%s frame buffer device\n", info->fix.id);
   367		return 0;
   368	
   369	err_fb_dealoc:
   370		fb_dealloc_cmap(&info->cmap);
   371	err_groups:
   372		sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
   373	err_unmap:
   374		iounmap(info->screen_base);
   375	err_release_fb:
   376		framebuffer_release(info);
   377	err_release_mem:
   378		if (request_mem_succeeded)
   379			release_mem_region(efifb_fix.smem_start, size_total);
   380		return err;
   381	}
   382	

---
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: 33909 bytes --]

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

* Re: [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk
@ 2017-11-28 15:47 ` kbuild test robot
  0 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 15:47 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, dri-devel, Bartlomiej Zolnierkiewicz, intel-gfx,
	Hans de Goede, kbuild-all, Dave Airlie, Daniel Vetter

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.15-rc1 next-20171128]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171128-225025
config: i386-randconfig-x003-201748 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/video/fbdev/efifb.c: In function 'efifb_probe':
>> drivers/video/fbdev/efifb.c:340:7: error: 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PRESENT_BOTTOM_FIELD'?
     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PRESENT_BOTTOM_FIELD
   drivers/video/fbdev/efifb.c:340:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/video/fbdev/efifb.c:343:7: error: 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP'?
     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP
>> drivers/video/fbdev/efifb.c:346:7: error: 'DRM_MODE_PANEL_ORIENTATION_RIGHT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP'?
     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_LEFT_UP

vim +340 drivers/video/fbdev/efifb.c

   158	
   159	static int efifb_probe(struct platform_device *dev)
   160	{
   161		struct fb_info *info;
   162		int err, orientation;
   163		unsigned int size_vmode;
   164		unsigned int size_remap;
   165		unsigned int size_total;
   166		char *option = NULL;
   167	
   168		if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
   169			return -ENODEV;
   170	
   171		if (fb_get_options("efifb", &option))
   172			return -ENODEV;
   173		efifb_setup(option);
   174	
   175		/* We don't get linelength from UGA Draw Protocol, only from
   176		 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
   177		 * passed in from the user, we really can't use the framebuffer.
   178		 */
   179		if (!screen_info.lfb_linelength)
   180			return -ENODEV;
   181	
   182		if (!screen_info.lfb_depth)
   183			screen_info.lfb_depth = 32;
   184		if (!screen_info.pages)
   185			screen_info.pages = 1;
   186		if (!fb_base_is_valid()) {
   187			printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
   188			return -ENODEV;
   189		}
   190		printk(KERN_INFO "efifb: probing for efifb\n");
   191	
   192		/* just assume they're all unset if any are */
   193		if (!screen_info.blue_size) {
   194			screen_info.blue_size = 8;
   195			screen_info.blue_pos = 0;
   196			screen_info.green_size = 8;
   197			screen_info.green_pos = 8;
   198			screen_info.red_size = 8;
   199			screen_info.red_pos = 16;
   200			screen_info.rsvd_size = 8;
   201			screen_info.rsvd_pos = 24;
   202		}
   203	
   204		efifb_fix.smem_start = screen_info.lfb_base;
   205	
   206		if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
   207			u64 ext_lfb_base;
   208	
   209			ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
   210			efifb_fix.smem_start |= ext_lfb_base;
   211		}
   212	
   213		if (bar_resource &&
   214		    bar_resource->start + bar_offset != efifb_fix.smem_start) {
   215			dev_info(&efifb_pci_dev->dev,
   216				 "BAR has moved, updating efifb address\n");
   217			efifb_fix.smem_start = bar_resource->start + bar_offset;
   218		}
   219	
   220		efifb_defined.bits_per_pixel = screen_info.lfb_depth;
   221		efifb_defined.xres = screen_info.lfb_width;
   222		efifb_defined.yres = screen_info.lfb_height;
   223		efifb_fix.line_length = screen_info.lfb_linelength;
   224	
   225		/*   size_vmode -- that is the amount of memory needed for the
   226		 *                 used video mode, i.e. the minimum amount of
   227		 *                 memory we need. */
   228		size_vmode = efifb_defined.yres * efifb_fix.line_length;
   229	
   230		/*   size_total -- all video memory we have. Used for
   231		 *                 entries, ressource allocation and bounds
   232		 *                 checking. */
   233		size_total = screen_info.lfb_size;
   234		if (size_total < size_vmode)
   235			size_total = size_vmode;
   236	
   237		/*   size_remap -- the amount of video memory we are going to
   238		 *                 use for efifb.  With modern cards it is no
   239		 *                 option to simply use size_total as that
   240		 *                 wastes plenty of kernel address space. */
   241		size_remap  = size_vmode * 2;
   242		if (size_remap > size_total)
   243			size_remap = size_total;
   244		if (size_remap % PAGE_SIZE)
   245			size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
   246		efifb_fix.smem_len = size_remap;
   247	
   248		if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
   249			request_mem_succeeded = true;
   250		} else {
   251			/* We cannot make this fatal. Sometimes this comes from magic
   252			   spaces our resource handlers simply don't know about */
   253			pr_warn("efifb: cannot reserve video memory at 0x%lx\n",
   254				efifb_fix.smem_start);
   255		}
   256	
   257		info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   258		if (!info) {
   259			pr_err("efifb: cannot allocate framebuffer\n");
   260			err = -ENOMEM;
   261			goto err_release_mem;
   262		}
   263		platform_set_drvdata(dev, info);
   264		info->pseudo_palette = info->par;
   265		info->par = NULL;
   266	
   267		info->apertures = alloc_apertures(1);
   268		if (!info->apertures) {
   269			err = -ENOMEM;
   270			goto err_release_fb;
   271		}
   272		info->apertures->ranges[0].base = efifb_fix.smem_start;
   273		info->apertures->ranges[0].size = size_remap;
   274	
   275		if (nowc)
   276			info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
   277		else
   278			info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
   279		if (!info->screen_base) {
   280			pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
   281				efifb_fix.smem_len, efifb_fix.smem_start);
   282			err = -EIO;
   283			goto err_release_fb;
   284		}
   285	
   286		pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
   287		       efifb_fix.smem_start, size_remap/1024, size_total/1024);
   288		pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
   289		       efifb_defined.xres, efifb_defined.yres,
   290		       efifb_defined.bits_per_pixel, efifb_fix.line_length,
   291		       screen_info.pages);
   292	
   293		efifb_defined.xres_virtual = efifb_defined.xres;
   294		efifb_defined.yres_virtual = efifb_fix.smem_len /
   295						efifb_fix.line_length;
   296		pr_info("efifb: scrolling: redraw\n");
   297		efifb_defined.yres_virtual = efifb_defined.yres;
   298	
   299		/* some dummy values for timing to make fbset happy */
   300		efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
   301						1000 / efifb_defined.yres;
   302		efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
   303		efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
   304	
   305		efifb_defined.red.offset    = screen_info.red_pos;
   306		efifb_defined.red.length    = screen_info.red_size;
   307		efifb_defined.green.offset  = screen_info.green_pos;
   308		efifb_defined.green.length  = screen_info.green_size;
   309		efifb_defined.blue.offset   = screen_info.blue_pos;
   310		efifb_defined.blue.length   = screen_info.blue_size;
   311		efifb_defined.transp.offset = screen_info.rsvd_pos;
   312		efifb_defined.transp.length = screen_info.rsvd_size;
   313	
   314		pr_info("efifb: %s: "
   315		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
   316		       "Truecolor",
   317		       screen_info.rsvd_size,
   318		       screen_info.red_size,
   319		       screen_info.green_size,
   320		       screen_info.blue_size,
   321		       screen_info.rsvd_pos,
   322		       screen_info.red_pos,
   323		       screen_info.green_pos,
   324		       screen_info.blue_pos);
   325	
   326		efifb_fix.ypanstep  = 0;
   327		efifb_fix.ywrapstep = 0;
   328	
   329		info->fbops = &efifb_ops;
   330		info->var = efifb_defined;
   331		info->fix = efifb_fix;
   332		info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
   333	
   334		orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
   335							      efifb_defined.yres);
   336		switch (orientation) {
   337		default:
   338			info->fbcon_rotate_hint = FB_ROTATE_UR;
   339			break;
 > 340		case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
   341			info->fbcon_rotate_hint = FB_ROTATE_UD;
   342			break;
 > 343		case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
   344			info->fbcon_rotate_hint = FB_ROTATE_CCW;
   345			break;
 > 346		case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
   347			info->fbcon_rotate_hint = FB_ROTATE_CW;
   348			break;
   349		}
   350	
   351		err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
   352		if (err) {
   353			pr_err("efifb: cannot add sysfs attrs\n");
   354			goto err_unmap;
   355		}
   356		err = fb_alloc_cmap(&info->cmap, 256, 0);
   357		if (err < 0) {
   358			pr_err("efifb: cannot allocate colormap\n");
   359			goto err_groups;
   360		}
   361		err = register_framebuffer(info);
   362		if (err < 0) {
   363			pr_err("efifb: cannot register framebuffer\n");
   364			goto err_fb_dealoc;
   365		}
   366		fb_info(info, "%s frame buffer device\n", info->fix.id);
   367		return 0;
   368	
   369	err_fb_dealoc:
   370		fb_dealloc_cmap(&info->cmap);
   371	err_groups:
   372		sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
   373	err_unmap:
   374		iounmap(info->screen_base);
   375	err_release_fb:
   376		framebuffer_release(info);
   377	err_release_mem:
   378		if (request_mem_succeeded)
   379			release_mem_region(efifb_fix.smem_start, size_total);
   380		return err;
   381	}
   382	

---
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: 33909 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6
  2017-11-25 17:33   ` Hans de Goede
@ 2017-11-28 16:48       ` kbuild test robot
  -1 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 16:48 UTC (permalink / raw)
  To: linux-fbdev

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.15-rc1 next-20171128]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171128-225025
config: i386-randconfig-x074-201748 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/intel_dsi.c: In function 'intel_dsi_get_panel_orientation':
>> drivers/gpu/drm/i915/intel_dsi.c:1672:21: error: storage size of 'plane' isn't known
     enum i9xx_plane_id plane;
                        ^~~~~
   drivers/gpu/drm/i915/intel_dsi.c:1672:21: warning: unused variable 'plane' [-Wunused-variable]

vim +1672 drivers/gpu/drm/i915/intel_dsi.c

  1667	
  1668	static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
  1669	{
  1670		struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
  1671		int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> 1672		enum i9xx_plane_id plane;
  1673		u32 val;
  1674	
  1675		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
  1676			if (connector->encoder->crtc_mask == BIT(PIPE_B))
  1677				plane = PLANE_B;
  1678			else
  1679				plane = PLANE_A;
  1680	
  1681			val = I915_READ(DSPCNTR(plane));
  1682			if (val & DISPPLANE_ROTATE_180)
  1683				orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
  1684		}
  1685	
  1686		return orientation;
  1687	}
  1688	

---
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: 26541 bytes --]

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

* Re: [Intel-gfx] [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6.
@ 2017-11-28 16:48       ` kbuild test robot
  0 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 16:48 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, dri-devel, Bartlomiej Zolnierkiewicz, intel-gfx,
	Hans de Goede, kbuild-all, Dave Airlie, Daniel Vetter

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.15-rc1 next-20171128]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171128-225025
config: i386-randconfig-x074-201748 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/intel_dsi.c: In function 'intel_dsi_get_panel_orientation':
>> drivers/gpu/drm/i915/intel_dsi.c:1672:21: error: storage size of 'plane' isn't known
     enum i9xx_plane_id plane;
                        ^~~~~
   drivers/gpu/drm/i915/intel_dsi.c:1672:21: warning: unused variable 'plane' [-Wunused-variable]

vim +1672 drivers/gpu/drm/i915/intel_dsi.c

  1667	
  1668	static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
  1669	{
  1670		struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
  1671		int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> 1672		enum i9xx_plane_id plane;
  1673		u32 val;
  1674	
  1675		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
  1676			if (connector->encoder->crtc_mask == BIT(PIPE_B))
  1677				plane = PLANE_B;
  1678			else
  1679				plane = PLANE_A;
  1680	
  1681			val = I915_READ(DSPCNTR(plane));
  1682			if (val & DISPPLANE_ROTATE_180)
  1683				orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
  1684		}
  1685	
  1686		return orientation;
  1687	}
  1688	

---
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: 26541 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6
  2017-11-25 17:33   ` Hans de Goede
@ 2017-11-28 20:46       ` kbuild test robot
  -1 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 20:46 UTC (permalink / raw)
  To: linux-fbdev

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.15-rc1 next-20171128]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171128-225025
config: x86_64-randconfig-x012-201748 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/intel_dsi.c: In function 'intel_dsi_get_panel_orientation':
   drivers/gpu/drm/i915/intel_dsi.c:1672:21: error: storage size of 'plane' isn't known
     enum i9xx_plane_id plane;
                        ^~~~~
>> drivers/gpu/drm/i915/intel_dsi.c:1672:21: error: unused variable 'plane' [-Werror=unused-variable]
   cc1: all warnings being treated as errors

vim +/plane +1672 drivers/gpu/drm/i915/intel_dsi.c

  1667	
  1668	static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
  1669	{
  1670		struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
  1671		int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> 1672		enum i9xx_plane_id plane;
  1673		u32 val;
  1674	
  1675		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
  1676			if (connector->encoder->crtc_mask == BIT(PIPE_B))
  1677				plane = PLANE_B;
  1678			else
  1679				plane = PLANE_A;
  1680	
  1681			val = I915_READ(DSPCNTR(plane));
  1682			if (val & DISPPLANE_ROTATE_180)
  1683				orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
  1684		}
  1685	
  1686		return orientation;
  1687	}
  1688	

---
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: 28526 bytes --]

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

* Re: [Intel-gfx] [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6.
@ 2017-11-28 20:46       ` kbuild test robot
  0 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 20:46 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, dri-devel, Bartlomiej Zolnierkiewicz, intel-gfx,
	Hans de Goede, kbuild-all, Dave Airlie, Daniel Vetter

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.15-rc1 next-20171128]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171128-225025
config: x86_64-randconfig-x012-201748 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/intel_dsi.c: In function 'intel_dsi_get_panel_orientation':
   drivers/gpu/drm/i915/intel_dsi.c:1672:21: error: storage size of 'plane' isn't known
     enum i9xx_plane_id plane;
                        ^~~~~
>> drivers/gpu/drm/i915/intel_dsi.c:1672:21: error: unused variable 'plane' [-Werror=unused-variable]
   cc1: all warnings being treated as errors

vim +/plane +1672 drivers/gpu/drm/i915/intel_dsi.c

  1667	
  1668	static int intel_dsi_get_panel_orientation(struct intel_connector *connector)
  1669	{
  1670		struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
  1671		int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> 1672		enum i9xx_plane_id plane;
  1673		u32 val;
  1674	
  1675		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
  1676			if (connector->encoder->crtc_mask == BIT(PIPE_B))
  1677				plane = PLANE_B;
  1678			else
  1679				plane = PLANE_A;
  1680	
  1681			val = I915_READ(DSPCNTR(plane));
  1682			if (val & DISPPLANE_ROTATE_180)
  1683				orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
  1684		}
  1685	
  1686		return orientation;
  1687	}
  1688	

---
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: 28526 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation
  2017-11-25 19:16     ` Hans de Goede
@ 2017-11-28 21:07   ` kbuild test robot
  -1 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 21:07 UTC (permalink / raw)
  To: linux-fbdev

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.15-rc1 next-20171128]
[cannot apply to linus/master]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171129-001142
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: x86_64-randconfig-s1-11282357 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/video/fbdev/efifb.c: In function 'efifb_probe':
   drivers/video/fbdev/efifb.c:339:7: error: 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/video/fbdev/efifb.c:339:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/video/fbdev/efifb.c:342:7: error: 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/video/fbdev/efifb.c:345:7: error: 'DRM_MODE_PANEL_ORIENTATION_RIGHT_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/DRM_MODE_PANEL_ORIENTATION_LEFT_UP +342 drivers/video/fbdev/efifb.c

   157	
   158	static int efifb_probe(struct platform_device *dev)
   159	{
   160		struct fb_info *info;
   161		int err, orientation;
   162		unsigned int size_vmode;
   163		unsigned int size_remap;
   164		unsigned int size_total;
   165		char *option = NULL;
   166	
   167		if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
   168			return -ENODEV;
   169	
   170		if (fb_get_options("efifb", &option))
   171			return -ENODEV;
   172		efifb_setup(option);
   173	
   174		/* We don't get linelength from UGA Draw Protocol, only from
   175		 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
   176		 * passed in from the user, we really can't use the framebuffer.
   177		 */
   178		if (!screen_info.lfb_linelength)
   179			return -ENODEV;
   180	
   181		if (!screen_info.lfb_depth)
   182			screen_info.lfb_depth = 32;
   183		if (!screen_info.pages)
   184			screen_info.pages = 1;
   185		if (!fb_base_is_valid()) {
   186			printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
   187			return -ENODEV;
   188		}
   189		printk(KERN_INFO "efifb: probing for efifb\n");
   190	
   191		/* just assume they're all unset if any are */
   192		if (!screen_info.blue_size) {
   193			screen_info.blue_size = 8;
   194			screen_info.blue_pos = 0;
   195			screen_info.green_size = 8;
   196			screen_info.green_pos = 8;
   197			screen_info.red_size = 8;
   198			screen_info.red_pos = 16;
   199			screen_info.rsvd_size = 8;
   200			screen_info.rsvd_pos = 24;
   201		}
   202	
   203		efifb_fix.smem_start = screen_info.lfb_base;
   204	
   205		if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
   206			u64 ext_lfb_base;
   207	
   208			ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
   209			efifb_fix.smem_start |= ext_lfb_base;
   210		}
   211	
   212		if (bar_resource &&
   213		    bar_resource->start + bar_offset != efifb_fix.smem_start) {
   214			dev_info(&efifb_pci_dev->dev,
   215				 "BAR has moved, updating efifb address\n");
   216			efifb_fix.smem_start = bar_resource->start + bar_offset;
   217		}
   218	
   219		efifb_defined.bits_per_pixel = screen_info.lfb_depth;
   220		efifb_defined.xres = screen_info.lfb_width;
   221		efifb_defined.yres = screen_info.lfb_height;
   222		efifb_fix.line_length = screen_info.lfb_linelength;
   223	
   224		/*   size_vmode -- that is the amount of memory needed for the
   225		 *                 used video mode, i.e. the minimum amount of
   226		 *                 memory we need. */
   227		size_vmode = efifb_defined.yres * efifb_fix.line_length;
   228	
   229		/*   size_total -- all video memory we have. Used for
   230		 *                 entries, ressource allocation and bounds
   231		 *                 checking. */
   232		size_total = screen_info.lfb_size;
   233		if (size_total < size_vmode)
   234			size_total = size_vmode;
   235	
   236		/*   size_remap -- the amount of video memory we are going to
   237		 *                 use for efifb.  With modern cards it is no
   238		 *                 option to simply use size_total as that
   239		 *                 wastes plenty of kernel address space. */
   240		size_remap  = size_vmode * 2;
   241		if (size_remap > size_total)
   242			size_remap = size_total;
   243		if (size_remap % PAGE_SIZE)
   244			size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
   245		efifb_fix.smem_len = size_remap;
   246	
   247		if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
   248			request_mem_succeeded = true;
   249		} else {
   250			/* We cannot make this fatal. Sometimes this comes from magic
   251			   spaces our resource handlers simply don't know about */
   252			pr_warn("efifb: cannot reserve video memory at 0x%lx\n",
   253				efifb_fix.smem_start);
   254		}
   255	
   256		info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   257		if (!info) {
   258			pr_err("efifb: cannot allocate framebuffer\n");
   259			err = -ENOMEM;
   260			goto err_release_mem;
   261		}
   262		platform_set_drvdata(dev, info);
   263		info->pseudo_palette = info->par;
   264		info->par = NULL;
   265	
   266		info->apertures = alloc_apertures(1);
   267		if (!info->apertures) {
   268			err = -ENOMEM;
   269			goto err_release_fb;
   270		}
   271		info->apertures->ranges[0].base = efifb_fix.smem_start;
   272		info->apertures->ranges[0].size = size_remap;
   273	
   274		if (nowc)
   275			info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
   276		else
   277			info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
   278		if (!info->screen_base) {
   279			pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
   280				efifb_fix.smem_len, efifb_fix.smem_start);
   281			err = -EIO;
   282			goto err_release_fb;
   283		}
   284	
   285		pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
   286		       efifb_fix.smem_start, size_remap/1024, size_total/1024);
   287		pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
   288		       efifb_defined.xres, efifb_defined.yres,
   289		       efifb_defined.bits_per_pixel, efifb_fix.line_length,
   290		       screen_info.pages);
   291	
   292		efifb_defined.xres_virtual = efifb_defined.xres;
   293		efifb_defined.yres_virtual = efifb_fix.smem_len /
   294						efifb_fix.line_length;
   295		pr_info("efifb: scrolling: redraw\n");
   296		efifb_defined.yres_virtual = efifb_defined.yres;
   297	
   298		/* some dummy values for timing to make fbset happy */
   299		efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
   300						1000 / efifb_defined.yres;
   301		efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
   302		efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
   303	
   304		efifb_defined.red.offset    = screen_info.red_pos;
   305		efifb_defined.red.length    = screen_info.red_size;
   306		efifb_defined.green.offset  = screen_info.green_pos;
   307		efifb_defined.green.length  = screen_info.green_size;
   308		efifb_defined.blue.offset   = screen_info.blue_pos;
   309		efifb_defined.blue.length   = screen_info.blue_size;
   310		efifb_defined.transp.offset = screen_info.rsvd_pos;
   311		efifb_defined.transp.length = screen_info.rsvd_size;
   312	
   313		pr_info("efifb: %s: "
   314		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
   315		       "Truecolor",
   316		       screen_info.rsvd_size,
   317		       screen_info.red_size,
   318		       screen_info.green_size,
   319		       screen_info.blue_size,
   320		       screen_info.rsvd_pos,
   321		       screen_info.red_pos,
   322		       screen_info.green_pos,
   323		       screen_info.blue_pos);
   324	
   325		efifb_fix.ypanstep  = 0;
   326		efifb_fix.ywrapstep = 0;
   327	
   328		info->fbops = &efifb_ops;
   329		info->var = efifb_defined;
   330		info->fix = efifb_fix;
   331		info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
   332	
   333		orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
   334							      efifb_defined.yres);
   335		switch (orientation) {
   336		default:
   337			info->fbcon_rotate_hint = FB_ROTATE_UR;
   338			break;
 > 339		case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
   340			info->fbcon_rotate_hint = FB_ROTATE_UD;
   341			break;
 > 342		case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
   343			info->fbcon_rotate_hint = FB_ROTATE_CCW;
   344			break;
 > 345		case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
   346			info->fbcon_rotate_hint = FB_ROTATE_CW;
   347			break;
   348		}
   349	
   350		err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
   351		if (err) {
   352			pr_err("efifb: cannot add sysfs attrs\n");
   353			goto err_unmap;
   354		}
   355		err = fb_alloc_cmap(&info->cmap, 256, 0);
   356		if (err < 0) {
   357			pr_err("efifb: cannot allocate colormap\n");
   358			goto err_groups;
   359		}
   360		err = register_framebuffer(info);
   361		if (err < 0) {
   362			pr_err("efifb: cannot register framebuffer\n");
   363			goto err_fb_dealoc;
   364		}
   365		fb_info(info, "%s frame buffer device\n", info->fix.id);
   366		return 0;
   367	
   368	err_fb_dealoc:
   369		fb_dealloc_cmap(&info->cmap);
   370	err_groups:
   371		sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
   372	err_unmap:
   373		iounmap(info->screen_base);
   374	err_release_fb:
   375		framebuffer_release(info);
   376	err_release_mem:
   377		if (request_mem_succeeded)
   378			release_mem_region(efifb_fix.smem_start, size_total);
   379		return err;
   380	}
   381	

---
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: 26325 bytes --]

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

* Re: [Intel-gfx] [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk
@ 2017-11-28 21:07   ` kbuild test robot
  0 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 21:07 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, dri-devel, Bartlomiej Zolnierkiewicz, intel-gfx,
	Hans de Goede, kbuild-all, Dave Airlie, Daniel Vetter

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.15-rc1 next-20171128]
[cannot apply to linus/master]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171129-001142
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: x86_64-randconfig-s1-11282357 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/video/fbdev/efifb.c: In function 'efifb_probe':
   drivers/video/fbdev/efifb.c:339:7: error: 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/video/fbdev/efifb.c:339:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/video/fbdev/efifb.c:342:7: error: 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/video/fbdev/efifb.c:345:7: error: 'DRM_MODE_PANEL_ORIENTATION_RIGHT_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/DRM_MODE_PANEL_ORIENTATION_LEFT_UP +342 drivers/video/fbdev/efifb.c

   157	
   158	static int efifb_probe(struct platform_device *dev)
   159	{
   160		struct fb_info *info;
   161		int err, orientation;
   162		unsigned int size_vmode;
   163		unsigned int size_remap;
   164		unsigned int size_total;
   165		char *option = NULL;
   166	
   167		if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
   168			return -ENODEV;
   169	
   170		if (fb_get_options("efifb", &option))
   171			return -ENODEV;
   172		efifb_setup(option);
   173	
   174		/* We don't get linelength from UGA Draw Protocol, only from
   175		 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
   176		 * passed in from the user, we really can't use the framebuffer.
   177		 */
   178		if (!screen_info.lfb_linelength)
   179			return -ENODEV;
   180	
   181		if (!screen_info.lfb_depth)
   182			screen_info.lfb_depth = 32;
   183		if (!screen_info.pages)
   184			screen_info.pages = 1;
   185		if (!fb_base_is_valid()) {
   186			printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
   187			return -ENODEV;
   188		}
   189		printk(KERN_INFO "efifb: probing for efifb\n");
   190	
   191		/* just assume they're all unset if any are */
   192		if (!screen_info.blue_size) {
   193			screen_info.blue_size = 8;
   194			screen_info.blue_pos = 0;
   195			screen_info.green_size = 8;
   196			screen_info.green_pos = 8;
   197			screen_info.red_size = 8;
   198			screen_info.red_pos = 16;
   199			screen_info.rsvd_size = 8;
   200			screen_info.rsvd_pos = 24;
   201		}
   202	
   203		efifb_fix.smem_start = screen_info.lfb_base;
   204	
   205		if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
   206			u64 ext_lfb_base;
   207	
   208			ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
   209			efifb_fix.smem_start |= ext_lfb_base;
   210		}
   211	
   212		if (bar_resource &&
   213		    bar_resource->start + bar_offset != efifb_fix.smem_start) {
   214			dev_info(&efifb_pci_dev->dev,
   215				 "BAR has moved, updating efifb address\n");
   216			efifb_fix.smem_start = bar_resource->start + bar_offset;
   217		}
   218	
   219		efifb_defined.bits_per_pixel = screen_info.lfb_depth;
   220		efifb_defined.xres = screen_info.lfb_width;
   221		efifb_defined.yres = screen_info.lfb_height;
   222		efifb_fix.line_length = screen_info.lfb_linelength;
   223	
   224		/*   size_vmode -- that is the amount of memory needed for the
   225		 *                 used video mode, i.e. the minimum amount of
   226		 *                 memory we need. */
   227		size_vmode = efifb_defined.yres * efifb_fix.line_length;
   228	
   229		/*   size_total -- all video memory we have. Used for
   230		 *                 entries, ressource allocation and bounds
   231		 *                 checking. */
   232		size_total = screen_info.lfb_size;
   233		if (size_total < size_vmode)
   234			size_total = size_vmode;
   235	
   236		/*   size_remap -- the amount of video memory we are going to
   237		 *                 use for efifb.  With modern cards it is no
   238		 *                 option to simply use size_total as that
   239		 *                 wastes plenty of kernel address space. */
   240		size_remap  = size_vmode * 2;
   241		if (size_remap > size_total)
   242			size_remap = size_total;
   243		if (size_remap % PAGE_SIZE)
   244			size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
   245		efifb_fix.smem_len = size_remap;
   246	
   247		if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
   248			request_mem_succeeded = true;
   249		} else {
   250			/* We cannot make this fatal. Sometimes this comes from magic
   251			   spaces our resource handlers simply don't know about */
   252			pr_warn("efifb: cannot reserve video memory at 0x%lx\n",
   253				efifb_fix.smem_start);
   254		}
   255	
   256		info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   257		if (!info) {
   258			pr_err("efifb: cannot allocate framebuffer\n");
   259			err = -ENOMEM;
   260			goto err_release_mem;
   261		}
   262		platform_set_drvdata(dev, info);
   263		info->pseudo_palette = info->par;
   264		info->par = NULL;
   265	
   266		info->apertures = alloc_apertures(1);
   267		if (!info->apertures) {
   268			err = -ENOMEM;
   269			goto err_release_fb;
   270		}
   271		info->apertures->ranges[0].base = efifb_fix.smem_start;
   272		info->apertures->ranges[0].size = size_remap;
   273	
   274		if (nowc)
   275			info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
   276		else
   277			info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
   278		if (!info->screen_base) {
   279			pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
   280				efifb_fix.smem_len, efifb_fix.smem_start);
   281			err = -EIO;
   282			goto err_release_fb;
   283		}
   284	
   285		pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
   286		       efifb_fix.smem_start, size_remap/1024, size_total/1024);
   287		pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
   288		       efifb_defined.xres, efifb_defined.yres,
   289		       efifb_defined.bits_per_pixel, efifb_fix.line_length,
   290		       screen_info.pages);
   291	
   292		efifb_defined.xres_virtual = efifb_defined.xres;
   293		efifb_defined.yres_virtual = efifb_fix.smem_len /
   294						efifb_fix.line_length;
   295		pr_info("efifb: scrolling: redraw\n");
   296		efifb_defined.yres_virtual = efifb_defined.yres;
   297	
   298		/* some dummy values for timing to make fbset happy */
   299		efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
   300						1000 / efifb_defined.yres;
   301		efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
   302		efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
   303	
   304		efifb_defined.red.offset    = screen_info.red_pos;
   305		efifb_defined.red.length    = screen_info.red_size;
   306		efifb_defined.green.offset  = screen_info.green_pos;
   307		efifb_defined.green.length  = screen_info.green_size;
   308		efifb_defined.blue.offset   = screen_info.blue_pos;
   309		efifb_defined.blue.length   = screen_info.blue_size;
   310		efifb_defined.transp.offset = screen_info.rsvd_pos;
   311		efifb_defined.transp.length = screen_info.rsvd_size;
   312	
   313		pr_info("efifb: %s: "
   314		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
   315		       "Truecolor",
   316		       screen_info.rsvd_size,
   317		       screen_info.red_size,
   318		       screen_info.green_size,
   319		       screen_info.blue_size,
   320		       screen_info.rsvd_pos,
   321		       screen_info.red_pos,
   322		       screen_info.green_pos,
   323		       screen_info.blue_pos);
   324	
   325		efifb_fix.ypanstep  = 0;
   326		efifb_fix.ywrapstep = 0;
   327	
   328		info->fbops = &efifb_ops;
   329		info->var = efifb_defined;
   330		info->fix = efifb_fix;
   331		info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
   332	
   333		orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
   334							      efifb_defined.yres);
   335		switch (orientation) {
   336		default:
   337			info->fbcon_rotate_hint = FB_ROTATE_UR;
   338			break;
 > 339		case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
   340			info->fbcon_rotate_hint = FB_ROTATE_UD;
   341			break;
 > 342		case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
   343			info->fbcon_rotate_hint = FB_ROTATE_CCW;
   344			break;
 > 345		case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
   346			info->fbcon_rotate_hint = FB_ROTATE_CW;
   347			break;
   348		}
   349	
   350		err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
   351		if (err) {
   352			pr_err("efifb: cannot add sysfs attrs\n");
   353			goto err_unmap;
   354		}
   355		err = fb_alloc_cmap(&info->cmap, 256, 0);
   356		if (err < 0) {
   357			pr_err("efifb: cannot allocate colormap\n");
   358			goto err_groups;
   359		}
   360		err = register_framebuffer(info);
   361		if (err < 0) {
   362			pr_err("efifb: cannot register framebuffer\n");
   363			goto err_fb_dealoc;
   364		}
   365		fb_info(info, "%s frame buffer device\n", info->fix.id);
   366		return 0;
   367	
   368	err_fb_dealoc:
   369		fb_dealloc_cmap(&info->cmap);
   370	err_groups:
   371		sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
   372	err_unmap:
   373		iounmap(info->screen_base);
   374	err_release_fb:
   375		framebuffer_release(info);
   376	err_release_mem:
   377		if (request_mem_succeeded)
   378			release_mem_region(efifb_fix.smem_start, size_total);
   379		return err;
   380	}
   381	

---
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: 26325 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation
  2017-11-25 19:16     ` Hans de Goede
@ 2017-11-28 22:19   ` kbuild test robot
  -1 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 22:19 UTC (permalink / raw)
  To: linux-fbdev

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.15-rc1 next-20171128]
[cannot apply to linus/master]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171129-001142
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: x86_64-kexec (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/video/fbdev/efifb.c: In function 'efifb_probe':
>> drivers/video/fbdev/efifb.c:339:7: error: 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PRESENT_BOTTOM_FIELD'?
     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PRESENT_BOTTOM_FIELD
   drivers/video/fbdev/efifb.c:339:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/video/fbdev/efifb.c:342:7: error: 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP'?
     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP
>> drivers/video/fbdev/efifb.c:345:7: error: 'DRM_MODE_PANEL_ORIENTATION_RIGHT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP'?
     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_LEFT_UP

vim +339 drivers/video/fbdev/efifb.c

   157	
   158	static int efifb_probe(struct platform_device *dev)
   159	{
   160		struct fb_info *info;
   161		int err, orientation;
   162		unsigned int size_vmode;
   163		unsigned int size_remap;
   164		unsigned int size_total;
   165		char *option = NULL;
   166	
   167		if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
   168			return -ENODEV;
   169	
   170		if (fb_get_options("efifb", &option))
   171			return -ENODEV;
   172		efifb_setup(option);
   173	
   174		/* We don't get linelength from UGA Draw Protocol, only from
   175		 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
   176		 * passed in from the user, we really can't use the framebuffer.
   177		 */
   178		if (!screen_info.lfb_linelength)
   179			return -ENODEV;
   180	
   181		if (!screen_info.lfb_depth)
   182			screen_info.lfb_depth = 32;
   183		if (!screen_info.pages)
   184			screen_info.pages = 1;
   185		if (!fb_base_is_valid()) {
   186			printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
   187			return -ENODEV;
   188		}
   189		printk(KERN_INFO "efifb: probing for efifb\n");
   190	
   191		/* just assume they're all unset if any are */
   192		if (!screen_info.blue_size) {
   193			screen_info.blue_size = 8;
   194			screen_info.blue_pos = 0;
   195			screen_info.green_size = 8;
   196			screen_info.green_pos = 8;
   197			screen_info.red_size = 8;
   198			screen_info.red_pos = 16;
   199			screen_info.rsvd_size = 8;
   200			screen_info.rsvd_pos = 24;
   201		}
   202	
   203		efifb_fix.smem_start = screen_info.lfb_base;
   204	
   205		if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
   206			u64 ext_lfb_base;
   207	
   208			ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
   209			efifb_fix.smem_start |= ext_lfb_base;
   210		}
   211	
   212		if (bar_resource &&
   213		    bar_resource->start + bar_offset != efifb_fix.smem_start) {
   214			dev_info(&efifb_pci_dev->dev,
   215				 "BAR has moved, updating efifb address\n");
   216			efifb_fix.smem_start = bar_resource->start + bar_offset;
   217		}
   218	
   219		efifb_defined.bits_per_pixel = screen_info.lfb_depth;
   220		efifb_defined.xres = screen_info.lfb_width;
   221		efifb_defined.yres = screen_info.lfb_height;
   222		efifb_fix.line_length = screen_info.lfb_linelength;
   223	
   224		/*   size_vmode -- that is the amount of memory needed for the
   225		 *                 used video mode, i.e. the minimum amount of
   226		 *                 memory we need. */
   227		size_vmode = efifb_defined.yres * efifb_fix.line_length;
   228	
   229		/*   size_total -- all video memory we have. Used for
   230		 *                 entries, ressource allocation and bounds
   231		 *                 checking. */
   232		size_total = screen_info.lfb_size;
   233		if (size_total < size_vmode)
   234			size_total = size_vmode;
   235	
   236		/*   size_remap -- the amount of video memory we are going to
   237		 *                 use for efifb.  With modern cards it is no
   238		 *                 option to simply use size_total as that
   239		 *                 wastes plenty of kernel address space. */
   240		size_remap  = size_vmode * 2;
   241		if (size_remap > size_total)
   242			size_remap = size_total;
   243		if (size_remap % PAGE_SIZE)
   244			size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
   245		efifb_fix.smem_len = size_remap;
   246	
   247		if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
   248			request_mem_succeeded = true;
   249		} else {
   250			/* We cannot make this fatal. Sometimes this comes from magic
   251			   spaces our resource handlers simply don't know about */
   252			pr_warn("efifb: cannot reserve video memory at 0x%lx\n",
   253				efifb_fix.smem_start);
   254		}
   255	
   256		info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   257		if (!info) {
   258			pr_err("efifb: cannot allocate framebuffer\n");
   259			err = -ENOMEM;
   260			goto err_release_mem;
   261		}
   262		platform_set_drvdata(dev, info);
   263		info->pseudo_palette = info->par;
   264		info->par = NULL;
   265	
   266		info->apertures = alloc_apertures(1);
   267		if (!info->apertures) {
   268			err = -ENOMEM;
   269			goto err_release_fb;
   270		}
   271		info->apertures->ranges[0].base = efifb_fix.smem_start;
   272		info->apertures->ranges[0].size = size_remap;
   273	
   274		if (nowc)
   275			info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
   276		else
   277			info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
   278		if (!info->screen_base) {
   279			pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
   280				efifb_fix.smem_len, efifb_fix.smem_start);
   281			err = -EIO;
   282			goto err_release_fb;
   283		}
   284	
   285		pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
   286		       efifb_fix.smem_start, size_remap/1024, size_total/1024);
   287		pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
   288		       efifb_defined.xres, efifb_defined.yres,
   289		       efifb_defined.bits_per_pixel, efifb_fix.line_length,
   290		       screen_info.pages);
   291	
   292		efifb_defined.xres_virtual = efifb_defined.xres;
   293		efifb_defined.yres_virtual = efifb_fix.smem_len /
   294						efifb_fix.line_length;
   295		pr_info("efifb: scrolling: redraw\n");
   296		efifb_defined.yres_virtual = efifb_defined.yres;
   297	
   298		/* some dummy values for timing to make fbset happy */
   299		efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
   300						1000 / efifb_defined.yres;
   301		efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
   302		efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
   303	
   304		efifb_defined.red.offset    = screen_info.red_pos;
   305		efifb_defined.red.length    = screen_info.red_size;
   306		efifb_defined.green.offset  = screen_info.green_pos;
   307		efifb_defined.green.length  = screen_info.green_size;
   308		efifb_defined.blue.offset   = screen_info.blue_pos;
   309		efifb_defined.blue.length   = screen_info.blue_size;
   310		efifb_defined.transp.offset = screen_info.rsvd_pos;
   311		efifb_defined.transp.length = screen_info.rsvd_size;
   312	
   313		pr_info("efifb: %s: "
   314		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
   315		       "Truecolor",
   316		       screen_info.rsvd_size,
   317		       screen_info.red_size,
   318		       screen_info.green_size,
   319		       screen_info.blue_size,
   320		       screen_info.rsvd_pos,
   321		       screen_info.red_pos,
   322		       screen_info.green_pos,
   323		       screen_info.blue_pos);
   324	
   325		efifb_fix.ypanstep  = 0;
   326		efifb_fix.ywrapstep = 0;
   327	
   328		info->fbops = &efifb_ops;
   329		info->var = efifb_defined;
   330		info->fix = efifb_fix;
   331		info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
   332	
   333		orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
   334							      efifb_defined.yres);
   335		switch (orientation) {
   336		default:
   337			info->fbcon_rotate_hint = FB_ROTATE_UR;
   338			break;
 > 339		case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
   340			info->fbcon_rotate_hint = FB_ROTATE_UD;
   341			break;
 > 342		case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
   343			info->fbcon_rotate_hint = FB_ROTATE_CCW;
   344			break;
 > 345		case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
   346			info->fbcon_rotate_hint = FB_ROTATE_CW;
   347			break;
   348		}
   349	
   350		err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
   351		if (err) {
   352			pr_err("efifb: cannot add sysfs attrs\n");
   353			goto err_unmap;
   354		}
   355		err = fb_alloc_cmap(&info->cmap, 256, 0);
   356		if (err < 0) {
   357			pr_err("efifb: cannot allocate colormap\n");
   358			goto err_groups;
   359		}
   360		err = register_framebuffer(info);
   361		if (err < 0) {
   362			pr_err("efifb: cannot register framebuffer\n");
   363			goto err_fb_dealoc;
   364		}
   365		fb_info(info, "%s frame buffer device\n", info->fix.id);
   366		return 0;
   367	
   368	err_fb_dealoc:
   369		fb_dealloc_cmap(&info->cmap);
   370	err_groups:
   371		sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
   372	err_unmap:
   373		iounmap(info->screen_base);
   374	err_release_fb:
   375		framebuffer_release(info);
   376	err_release_mem:
   377		if (request_mem_succeeded)
   378			release_mem_region(efifb_fix.smem_start, size_total);
   379		return err;
   380	}
   381	

---
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: 26185 bytes --]

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

* Re: [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk
@ 2017-11-28 22:19   ` kbuild test robot
  0 siblings, 0 replies; 52+ messages in thread
From: kbuild test robot @ 2017-11-28 22:19 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, dri-devel, Bartlomiej Zolnierkiewicz, intel-gfx,
	Hans de Goede, kbuild-all, Dave Airlie, Daniel Vetter

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

Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.15-rc1 next-20171128]
[cannot apply to linus/master]
[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/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171129-001142
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: x86_64-kexec (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/video/fbdev/efifb.c: In function 'efifb_probe':
>> drivers/video/fbdev/efifb.c:339:7: error: 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PRESENT_BOTTOM_FIELD'?
     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PRESENT_BOTTOM_FIELD
   drivers/video/fbdev/efifb.c:339:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/video/fbdev/efifb.c:342:7: error: 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP'?
     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP
>> drivers/video/fbdev/efifb.c:345:7: error: 'DRM_MODE_PANEL_ORIENTATION_RIGHT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP'?
     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_LEFT_UP

vim +339 drivers/video/fbdev/efifb.c

   157	
   158	static int efifb_probe(struct platform_device *dev)
   159	{
   160		struct fb_info *info;
   161		int err, orientation;
   162		unsigned int size_vmode;
   163		unsigned int size_remap;
   164		unsigned int size_total;
   165		char *option = NULL;
   166	
   167		if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
   168			return -ENODEV;
   169	
   170		if (fb_get_options("efifb", &option))
   171			return -ENODEV;
   172		efifb_setup(option);
   173	
   174		/* We don't get linelength from UGA Draw Protocol, only from
   175		 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
   176		 * passed in from the user, we really can't use the framebuffer.
   177		 */
   178		if (!screen_info.lfb_linelength)
   179			return -ENODEV;
   180	
   181		if (!screen_info.lfb_depth)
   182			screen_info.lfb_depth = 32;
   183		if (!screen_info.pages)
   184			screen_info.pages = 1;
   185		if (!fb_base_is_valid()) {
   186			printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
   187			return -ENODEV;
   188		}
   189		printk(KERN_INFO "efifb: probing for efifb\n");
   190	
   191		/* just assume they're all unset if any are */
   192		if (!screen_info.blue_size) {
   193			screen_info.blue_size = 8;
   194			screen_info.blue_pos = 0;
   195			screen_info.green_size = 8;
   196			screen_info.green_pos = 8;
   197			screen_info.red_size = 8;
   198			screen_info.red_pos = 16;
   199			screen_info.rsvd_size = 8;
   200			screen_info.rsvd_pos = 24;
   201		}
   202	
   203		efifb_fix.smem_start = screen_info.lfb_base;
   204	
   205		if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
   206			u64 ext_lfb_base;
   207	
   208			ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
   209			efifb_fix.smem_start |= ext_lfb_base;
   210		}
   211	
   212		if (bar_resource &&
   213		    bar_resource->start + bar_offset != efifb_fix.smem_start) {
   214			dev_info(&efifb_pci_dev->dev,
   215				 "BAR has moved, updating efifb address\n");
   216			efifb_fix.smem_start = bar_resource->start + bar_offset;
   217		}
   218	
   219		efifb_defined.bits_per_pixel = screen_info.lfb_depth;
   220		efifb_defined.xres = screen_info.lfb_width;
   221		efifb_defined.yres = screen_info.lfb_height;
   222		efifb_fix.line_length = screen_info.lfb_linelength;
   223	
   224		/*   size_vmode -- that is the amount of memory needed for the
   225		 *                 used video mode, i.e. the minimum amount of
   226		 *                 memory we need. */
   227		size_vmode = efifb_defined.yres * efifb_fix.line_length;
   228	
   229		/*   size_total -- all video memory we have. Used for
   230		 *                 entries, ressource allocation and bounds
   231		 *                 checking. */
   232		size_total = screen_info.lfb_size;
   233		if (size_total < size_vmode)
   234			size_total = size_vmode;
   235	
   236		/*   size_remap -- the amount of video memory we are going to
   237		 *                 use for efifb.  With modern cards it is no
   238		 *                 option to simply use size_total as that
   239		 *                 wastes plenty of kernel address space. */
   240		size_remap  = size_vmode * 2;
   241		if (size_remap > size_total)
   242			size_remap = size_total;
   243		if (size_remap % PAGE_SIZE)
   244			size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
   245		efifb_fix.smem_len = size_remap;
   246	
   247		if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
   248			request_mem_succeeded = true;
   249		} else {
   250			/* We cannot make this fatal. Sometimes this comes from magic
   251			   spaces our resource handlers simply don't know about */
   252			pr_warn("efifb: cannot reserve video memory at 0x%lx\n",
   253				efifb_fix.smem_start);
   254		}
   255	
   256		info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   257		if (!info) {
   258			pr_err("efifb: cannot allocate framebuffer\n");
   259			err = -ENOMEM;
   260			goto err_release_mem;
   261		}
   262		platform_set_drvdata(dev, info);
   263		info->pseudo_palette = info->par;
   264		info->par = NULL;
   265	
   266		info->apertures = alloc_apertures(1);
   267		if (!info->apertures) {
   268			err = -ENOMEM;
   269			goto err_release_fb;
   270		}
   271		info->apertures->ranges[0].base = efifb_fix.smem_start;
   272		info->apertures->ranges[0].size = size_remap;
   273	
   274		if (nowc)
   275			info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
   276		else
   277			info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
   278		if (!info->screen_base) {
   279			pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
   280				efifb_fix.smem_len, efifb_fix.smem_start);
   281			err = -EIO;
   282			goto err_release_fb;
   283		}
   284	
   285		pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
   286		       efifb_fix.smem_start, size_remap/1024, size_total/1024);
   287		pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
   288		       efifb_defined.xres, efifb_defined.yres,
   289		       efifb_defined.bits_per_pixel, efifb_fix.line_length,
   290		       screen_info.pages);
   291	
   292		efifb_defined.xres_virtual = efifb_defined.xres;
   293		efifb_defined.yres_virtual = efifb_fix.smem_len /
   294						efifb_fix.line_length;
   295		pr_info("efifb: scrolling: redraw\n");
   296		efifb_defined.yres_virtual = efifb_defined.yres;
   297	
   298		/* some dummy values for timing to make fbset happy */
   299		efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
   300						1000 / efifb_defined.yres;
   301		efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
   302		efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
   303	
   304		efifb_defined.red.offset    = screen_info.red_pos;
   305		efifb_defined.red.length    = screen_info.red_size;
   306		efifb_defined.green.offset  = screen_info.green_pos;
   307		efifb_defined.green.length  = screen_info.green_size;
   308		efifb_defined.blue.offset   = screen_info.blue_pos;
   309		efifb_defined.blue.length   = screen_info.blue_size;
   310		efifb_defined.transp.offset = screen_info.rsvd_pos;
   311		efifb_defined.transp.length = screen_info.rsvd_size;
   312	
   313		pr_info("efifb: %s: "
   314		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
   315		       "Truecolor",
   316		       screen_info.rsvd_size,
   317		       screen_info.red_size,
   318		       screen_info.green_size,
   319		       screen_info.blue_size,
   320		       screen_info.rsvd_pos,
   321		       screen_info.red_pos,
   322		       screen_info.green_pos,
   323		       screen_info.blue_pos);
   324	
   325		efifb_fix.ypanstep  = 0;
   326		efifb_fix.ywrapstep = 0;
   327	
   328		info->fbops = &efifb_ops;
   329		info->var = efifb_defined;
   330		info->fix = efifb_fix;
   331		info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
   332	
   333		orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
   334							      efifb_defined.yres);
   335		switch (orientation) {
   336		default:
   337			info->fbcon_rotate_hint = FB_ROTATE_UR;
   338			break;
 > 339		case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
   340			info->fbcon_rotate_hint = FB_ROTATE_UD;
   341			break;
 > 342		case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
   343			info->fbcon_rotate_hint = FB_ROTATE_CCW;
   344			break;
 > 345		case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
   346			info->fbcon_rotate_hint = FB_ROTATE_CW;
   347			break;
   348		}
   349	
   350		err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
   351		if (err) {
   352			pr_err("efifb: cannot add sysfs attrs\n");
   353			goto err_unmap;
   354		}
   355		err = fb_alloc_cmap(&info->cmap, 256, 0);
   356		if (err < 0) {
   357			pr_err("efifb: cannot allocate colormap\n");
   358			goto err_groups;
   359		}
   360		err = register_framebuffer(info);
   361		if (err < 0) {
   362			pr_err("efifb: cannot register framebuffer\n");
   363			goto err_fb_dealoc;
   364		}
   365		fb_info(info, "%s frame buffer device\n", info->fix.id);
   366		return 0;
   367	
   368	err_fb_dealoc:
   369		fb_dealloc_cmap(&info->cmap);
   370	err_groups:
   371		sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
   372	err_unmap:
   373		iounmap(info->screen_base);
   374	err_release_fb:
   375		framebuffer_release(info);
   376	err_release_mem:
   377		if (request_mem_succeeded)
   378			release_mem_region(efifb_fix.smem_start, size_total);
   379		return err;
   380	}
   381	

---
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: 26185 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
  2017-11-28 13:36     ` Hans de Goede
@ 2017-11-29  9:59       ` Daniel Vetter
  -1 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2017-11-29  9:59 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, Hans de Goede, Bartlomiej Zolnierkiewicz, intel-gfx,
	dri-devel, Dave Airlie, Daniel Vetter

On Tue, Nov 28, 2017 at 02:36:09PM +0100, Hans de Goede wrote:
> Hi,
> 
> On 28-11-17 11:27, Daniel Vetter wrote:
> > On Sat, Nov 25, 2017 at 06:33:34PM +0100, Hans de Goede wrote:
> > > Hi All,
> > > 
> > > Here is v6 of my series to add a "panel orientation" property to
> > > the drm-connector for the LCD panel to let userspace know about LCD
> > > panels which are not mounted upright, as well as detecting upside-down
> > > panels without needing quirks (like we do for 90 degree rotated screens).
> > > 
> > > Bartlomiej, can we please have your Acked-by for merging patches 1,
> > > 6 and 7 through the drm tree?
> > > 
> > > New in v6:
> > > -Fix / reference kernel-doc comments
> > > -Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
> > > -Move i915 dsi hardware rotation state read-out to intel_dsi_init()
> > > 
> > > New in v5:
> > > -Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
> > > -drm_fb_helper: Only use hardware (crtc primary plane) rotation for
> > >   180 degrees for now as 9-/270 degrees rotation requires special handling
> > > 
> > > New in v4:
> > > -Fix drm_fb_helper code setting an invalid rotation value on the primary
> > >   plane of disabled/unused crtcs (caught by Fi.CI)
> > > 
> > > New in v3:
> > > -As requested by Daniel v3 moves the quirks over from the fbdev
> > >   subsys to the drm subsys. I've done this by simpy starting with a copy of
> > >   the quirk table and eventually removing the fbdev version.
> > > 
> > > The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
> > > are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
> > > discussed previously the plan is to merge all 7 patches through the
> > > drm tree.
> > 
> > I think from the drm and i915 side of things this all looks ready (well
> > pls double-check that CI also approves before merging).
> 
> The CI says state is warning, see:
> https://patchwork.freedesktop.org/series/32447/
> and specifically:
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7290/shards.html
> 
> Which I find hard to read as I see no tests going to orange, only
> 3 tests moving to red, which AFAICT is failed. Clicking on the tests
> link to get history all 3 tests seem to fail in the same way quite
> often (2 out of 3) or somewhat often (the last one). Also the failures
> seem unrelated to my changes
> 
> So how do I deal with this, resend v7 to get CI to run again and hope
> I get a success result for all tests this time ?

-rc1 set CI on fire, we had to entirely disable reporting shard results.

Note that in the mail report you get annotations of known bugs, and the
skip<->pass flip-floppers are fallout from CI being on fire.

So looks all good to go.
-Daniel


> 
> > Just needs an ack/review from Bart, and then it's probably simplest if you
> > merge it all through drm-misc - the i915 side is tiny.
> 
> Ok, I will wait for an Ack from Bart and then merge this through drm-misc,
> thank you for the review.
> 
> Regards,
> 
> Hans
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support
@ 2017-11-29  9:59       ` Daniel Vetter
  0 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2017-11-29  9:59 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-fbdev, Hans de Goede, Bartlomiej Zolnierkiewicz, intel-gfx,
	dri-devel, Dave Airlie, Daniel Vetter

On Tue, Nov 28, 2017 at 02:36:09PM +0100, Hans de Goede wrote:
> Hi,
> 
> On 28-11-17 11:27, Daniel Vetter wrote:
> > On Sat, Nov 25, 2017 at 06:33:34PM +0100, Hans de Goede wrote:
> > > Hi All,
> > > 
> > > Here is v6 of my series to add a "panel orientation" property to
> > > the drm-connector for the LCD panel to let userspace know about LCD
> > > panels which are not mounted upright, as well as detecting upside-down
> > > panels without needing quirks (like we do for 90 degree rotated screens).
> > > 
> > > Bartlomiej, can we please have your Acked-by for merging patches 1,
> > > 6 and 7 through the drm tree?
> > > 
> > > New in v6:
> > > -Fix / reference kernel-doc comments
> > > -Don't export the DRM_MODE_PANEL_ORIENTATION_* defines in the UAPI
> > > -Move i915 dsi hardware rotation state read-out to intel_dsi_init()
> > > 
> > > New in v5:
> > > -Add kernel-doc comment documenting drm_get_panel_orientation_quirk()
> > > -drm_fb_helper: Only use hardware (crtc primary plane) rotation for
> > >   180 degrees for now as 9-/270 degrees rotation requires special handling
> > > 
> > > New in v4:
> > > -Fix drm_fb_helper code setting an invalid rotation value on the primary
> > >   plane of disabled/unused crtcs (caught by Fi.CI)
> > > 
> > > New in v3:
> > > -As requested by Daniel v3 moves the quirks over from the fbdev
> > >   subsys to the drm subsys. I've done this by simpy starting with a copy of
> > >   the quirk table and eventually removing the fbdev version.
> > > 
> > > The 1st patch in this series is a small fbdev/fbcon patch, patches 2-5
> > > are all drm patches and patches 6-7 are fbdev/fbcon patches again. As
> > > discussed previously the plan is to merge all 7 patches through the
> > > drm tree.
> > 
> > I think from the drm and i915 side of things this all looks ready (well
> > pls double-check that CI also approves before merging).
> 
> The CI says state is warning, see:
> https://patchwork.freedesktop.org/series/32447/
> and specifically:
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7290/shards.html
> 
> Which I find hard to read as I see no tests going to orange, only
> 3 tests moving to red, which AFAICT is failed. Clicking on the tests
> link to get history all 3 tests seem to fail in the same way quite
> often (2 out of 3) or somewhat often (the last one). Also the failures
> seem unrelated to my changes
> 
> So how do I deal with this, resend v7 to get CI to run again and hope
> I get a success result for all tests this time ?

-rc1 set CI on fire, we had to entirely disable reporting shard results.

Note that in the mail report you get annotations of known bugs, and the
skip<->pass flip-floppers are fallout from CI being on fire.

So looks all good to go.
-Daniel


> 
> > Just needs an ack/review from Bart, and then it's probably simplest if you
> > merge it all through drm-misc - the i915 side is tiny.
> 
> Ok, I will wait for an Ack from Bart and then merge this through drm-misc,
> thank you for the review.
> 
> Regards,
> 
> Hans
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2017-11-29  9:59 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-25 17:33 [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support Hans de Goede
2017-11-25 17:33 ` Hans de Goede
2017-11-25 17:33 ` [PATCH v6 1/7] fbcon: Add fbcon_rotate_hint to struct fb_info Hans de Goede
2017-11-25 17:33   ` Hans de Goede
2017-11-25 17:33 ` [PATCH v6 2/7] drm: Add panel orientation quirks, v6 Hans de Goede
2017-11-25 17:33   ` Hans de Goede
2017-11-25 17:33 ` [PATCH v6 3/7] drm: Add support for a panel-orientation connector property, v6 Hans de Goede
2017-11-25 17:33   ` Hans de Goede
2017-11-25 17:33 ` [PATCH v6 4/7] drm/fb-helper: Apply panel orientation connector prop to the primary plane, v6 Hans de Goede
2017-11-25 17:33   ` Hans de Goede
2017-11-25 17:33 ` [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6 Hans de Goede
2017-11-25 17:33   ` Hans de Goede
2017-11-28 10:25   ` [Intel-gfx] " Daniel Vetter
2017-11-28 10:25     ` Daniel Vetter
2017-11-28 16:48     ` [Intel-gfx] " kbuild test robot
2017-11-28 16:48       ` kbuild test robot
2017-11-28 20:46     ` kbuild test robot
2017-11-28 20:46       ` kbuild test robot
2017-11-25 17:33 ` [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk Hans de Goede
2017-11-25 17:33   ` Hans de Goede
2017-11-25 17:33 ` [PATCH v6 7/7] fbcon: Remove dmi quirk table Hans de Goede
2017-11-25 17:33   ` Hans de Goede
2017-11-25 17:37 ` ✗ Fi.CI.BAT: failure for drm/fbdev: Panel orientation connector property support (rev4) Patchwork
2017-11-25 19:16 ` [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support Hans de Goede
2017-11-25 19:16   ` Hans de Goede
2017-11-25 19:16   ` [PATCH v6 1/7] fbcon: Add fbcon_rotate_hint to struct fb_info Hans de Goede
2017-11-25 19:16     ` Hans de Goede
2017-11-25 19:16   ` [PATCH v6 2/7] drm: Add panel orientation quirks, v6 Hans de Goede
2017-11-25 19:16     ` Hans de Goede
2017-11-25 19:16   ` [PATCH v6 3/7] drm: Add support for a panel-orientation connector property, v6 Hans de Goede
2017-11-25 19:16     ` Hans de Goede
2017-11-25 19:16   ` [PATCH v6 4/7] drm/fb-helper: Apply panel orientation connector prop to the primary plane, v6 Hans de Goede
2017-11-25 19:16     ` Hans de Goede
2017-11-25 19:16   ` [PATCH v6 5/7] drm/i915: Add "panel orientation" property to the panel connector, v6 Hans de Goede
2017-11-25 19:16     ` Hans de Goede
2017-11-25 19:16   ` [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk Hans de Goede
2017-11-25 19:16     ` Hans de Goede
2017-11-25 19:16   ` [PATCH v6 7/7] fbcon: Remove dmi quirk table Hans de Goede
2017-11-25 19:16     ` Hans de Goede
2017-11-25 19:20   ` ✗ Fi.CI.BAT: failure for drm/fbdev: Panel orientation connector property support (rev5) Patchwork
2017-11-28 10:27 ` [Intel-gfx] [PATCH v6 0/7] drm/fbdev: Panel orientation connector property support Daniel Vetter
2017-11-28 10:27   ` Daniel Vetter
2017-11-28 13:36   ` Hans de Goede
2017-11-28 13:36     ` Hans de Goede
2017-11-29  9:59     ` Daniel Vetter
2017-11-29  9:59       ` Daniel Vetter
2017-11-28 15:47 [Intel-gfx] [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation kbuild test robot
2017-11-28 15:47 ` [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk kbuild test robot
2017-11-28 21:07 ` [Intel-gfx] [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation kbuild test robot
2017-11-28 21:07   ` [Intel-gfx] [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk kbuild test robot
2017-11-28 22:19 ` [Intel-gfx] [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation kbuild test robot
2017-11-28 22:19   ` [PATCH v6 6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk kbuild test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.