All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/3] drm: Add panel support
@ 2013-08-30 15:25 Thierry Reding
       [not found] ` <1377876321-26835-1-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 9+ messages in thread
From: Thierry Reding @ 2013-08-30 15:25 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi,

This patch series adds support for panels to DRM. The current implementation
is very basic and only provides hooks for a panel to handle DPMS changes and
return a list of supported modes. That should be enough to support a rather
large number of panels. It should also be easy to extend the framework for
more sophisticated panels such as DSI.

I'm aware of the existing efforts to create such a framework, called CDF. My
impression was that a lot of people thought it overengineered and that it
doesn't fit well into the existing DRM infrastructure. This alternative
proposal is an attempt to start with something simpler (yet extensible) that
fits into DRM more nicely.

Patch 1 adds the "framework" if one can call it that. At the moment it isn't
anything more than a global registry that panel drivers can register panels
with and display drivers can retrieve them. All of this is very device tree
centric right now, but it shouldn't be difficult to add support for platform
data.

Patch 2 implements a simple driver for dumb panels that can have a regulator
for the supply voltage of the panel and a separate GPIO to enable the panel.
Three simple panels are currently supported by that driver.

Finally patch 3 hooks up the panel framework with the Tegra DRM driver. Note
that the framework isn't tied to the core at the moment. That can easily be
changed if we want to, but I didn't see a need so far. Instead the driver
calls the .dpms() and .get_modes() hooks in it's encoder/connector
implementation.

Thierry

Thierry Reding (3):
  drm: Add panel support
  drm/panel: Add simple panel support
  drm/tegra: Implement panel support

 .../devicetree/bindings/panel/panel-simple.txt     |  25 ++
 drivers/gpu/drm/Kconfig                            |   2 +
 drivers/gpu/drm/Makefile                           |   2 +
 drivers/gpu/drm/drm_panel.c                        |  96 ++++++
 drivers/gpu/drm/panel/Kconfig                      |  17 ++
 drivers/gpu/drm/panel/Makefile                     |   1 +
 drivers/gpu/drm/panel/panel-simple.c               | 335 +++++++++++++++++++++
 drivers/gpu/host1x/drm/Kconfig                     |   1 +
 drivers/gpu/host1x/drm/drm.h                       |   1 +
 drivers/gpu/host1x/drm/output.c                    |  28 +-
 include/drm/drm_panel.h                            |  65 ++++
 11 files changed, 571 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/panel/panel-simple.txt
 create mode 100644 drivers/gpu/drm/drm_panel.c
 create mode 100644 drivers/gpu/drm/panel/Kconfig
 create mode 100644 drivers/gpu/drm/panel/Makefile
 create mode 100644 drivers/gpu/drm/panel/panel-simple.c
 create mode 100644 include/drm/drm_panel.h

-- 
1.8.4

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

* [RFC 1/3] drm: Add panel support
       [not found] ` <1377876321-26835-1-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-08-30 15:25   ` Thierry Reding
       [not found]     ` <1377876321-26835-2-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2013-08-30 15:25   ` [RFC 2/3] drm/panel: Add simple " Thierry Reding
  2013-08-30 15:25   ` [RFC 3/3] drm/tegra: Implement " Thierry Reding
  2 siblings, 1 reply; 9+ messages in thread
From: Thierry Reding @ 2013-08-30 15:25 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA

Add a very simple framework to register and lookup panels. Panel drivers
can initialize a DRM panel and register it with the framework, allowing
them to be retrieved and used by display drivers. Currently only support
for DPMS and obtaining panel modes is provided. However it should be
sufficient to enable a large number of panels. The framework should also
be easily extensible to support more sophisticated kinds of panels such
as DSI.

The framework hasn't been tied into the DRM core, even though it should
be easily possible to do so if that's what we want. In the current
implementation, display drivers can simple make use of it to retrieve a
panel, obtain its modes and control its DPMS mode.

Note that this is currently only tested on systems that boot from a
device tree. No glue code has been written yet for systems that use
platform data, but it should be easy to add.

Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/Kconfig       |  2 +
 drivers/gpu/drm/Makefile      |  1 +
 drivers/gpu/drm/drm_panel.c   | 96 +++++++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/panel/Kconfig |  4 ++
 include/drm/drm_panel.h       | 65 +++++++++++++++++++++++++++++
 5 files changed, 168 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_panel.c
 create mode 100644 drivers/gpu/drm/panel/Kconfig
 create mode 100644 include/drm/drm_panel.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 955555d..b4d8402 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -236,3 +236,5 @@ source "drivers/gpu/drm/tilcdc/Kconfig"
 source "drivers/gpu/drm/qxl/Kconfig"
 
 source "drivers/gpu/drm/msm/Kconfig"
+
+source "drivers/gpu/drm/panel/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index f089adf..9b009c7 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -18,6 +18,7 @@ drm-y       :=	drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
 drm-$(CONFIG_PCI) += ati_pcigart.o
+drm-$(CONFIG_DRM_PANEL) += drm_panel.o
 
 drm-usb-y   := drm_usb.o
 
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
new file mode 100644
index 0000000..ff6e459
--- /dev/null
+++ b/drivers/gpu/drm/drm_panel.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/err.h>
+#include <linux/export.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_panel.h>
+
+static DEFINE_MUTEX(panel_lock);
+static LIST_HEAD(panel_list);
+
+void drm_panel_init(struct drm_panel *panel)
+{
+	INIT_LIST_HEAD(&panel->list);
+}
+EXPORT_SYMBOL(drm_panel_init);
+
+int drm_panel_add(struct drm_panel *panel)
+{
+	mutex_lock(&panel_lock);
+	list_add_tail(&panel->list, &panel_list);
+	mutex_unlock(&panel_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_panel_add);
+
+void drm_panel_remove(struct drm_panel *panel)
+{
+	mutex_lock(&panel_lock);
+	list_del_init(&panel->list);
+	mutex_unlock(&panel_lock);
+}
+EXPORT_SYMBOL(drm_panel_remove);
+
+int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
+{
+	if (panel->connector)
+		return -EBUSY;
+
+	panel->connector = connector;
+	panel->drm = connector->dev;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_panel_attach);
+
+int drm_panel_detach(struct drm_panel *panel)
+{
+	panel->connector = NULL;
+	panel->drm = NULL;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_panel_detach);
+
+#ifdef CONFIG_OF
+struct drm_panel *of_drm_find_panel(struct device_node *np)
+{
+	struct drm_panel *panel;
+
+	mutex_lock(&panel_lock);
+
+	list_for_each_entry(panel, &panel_list, list) {
+		if (panel->dev->of_node == np) {
+			mutex_unlock(&panel_lock);
+			return panel;
+		}
+	}
+
+	mutex_unlock(&panel_lock);
+	return NULL;
+}
+EXPORT_SYMBOL(of_drm_find_panel);
+#endif
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
new file mode 100644
index 0000000..2ddd5bd
--- /dev/null
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -0,0 +1,4 @@
+menuconfig DRM_PANEL
+	bool "DRM panel support"
+	help
+	  Panel registration and lookup framework.
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
new file mode 100644
index 0000000..f02b615
--- /dev/null
+++ b/include/drm/drm_panel.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __DRM_PANEL_H__
+#define __DRM_PANEL_H__
+
+#include <linux/list.h>
+
+struct drm_connector;
+struct drm_device;
+struct drm_panel;
+
+struct drm_panel_funcs {
+	void (*dpms)(struct drm_panel *panel, int mode);
+	int (*get_modes)(struct drm_panel *panel);
+};
+
+struct drm_panel {
+	struct drm_device *drm;
+	struct drm_connector *connector;
+	struct device *dev;
+
+	const struct drm_panel_funcs *funcs;
+
+	struct list_head list;
+};
+
+void drm_panel_init(struct drm_panel *panel);
+
+int drm_panel_add(struct drm_panel *panel);
+void drm_panel_remove(struct drm_panel *panel);
+
+int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector);
+int drm_panel_detach(struct drm_panel *panel);
+
+#ifdef CONFIG_OF
+struct drm_panel *of_drm_find_panel(struct device_node *np);
+#else
+static inline struct drm_panel *of_drm_find_panel(struct device_node *np)
+{
+	return NULL;
+}
+#endif
+
+#endif
-- 
1.8.4

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

* [RFC 2/3] drm/panel: Add simple panel support
       [not found] ` <1377876321-26835-1-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2013-08-30 15:25   ` [RFC 1/3] " Thierry Reding
@ 2013-08-30 15:25   ` Thierry Reding
       [not found]     ` <1377876321-26835-3-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2013-08-30 15:25   ` [RFC 3/3] drm/tegra: Implement " Thierry Reding
  2 siblings, 1 reply; 9+ messages in thread
From: Thierry Reding @ 2013-08-30 15:25 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA

Add a driver for simple panels. Such panels can have a regulator that
provides the supply voltage and a separate GPIO to enable the panel.
Optionally the panels can have a backlight associated with them so it
can be enabled or disabled according to the panel's power management
mode.

Support is added for three panels: An AU Optronics 10.1" WSVGA, a
Chunghwa Picture Tubes 10.1" WXGA and a Panasonic 10.1 WUXGA TFT LCD
panel.

Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 .../devicetree/bindings/panel/panel-simple.txt     |  25 ++
 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/panel/Kconfig                      |  13 +
 drivers/gpu/drm/panel/Makefile                     |   1 +
 drivers/gpu/drm/panel/panel-simple.c               | 335 +++++++++++++++++++++
 5 files changed, 375 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/panel/panel-simple.txt
 create mode 100644 drivers/gpu/drm/panel/Makefile
 create mode 100644 drivers/gpu/drm/panel/panel-simple.c

diff --git a/Documentation/devicetree/bindings/panel/panel-simple.txt b/Documentation/devicetree/bindings/panel/panel-simple.txt
new file mode 100644
index 0000000..dfd4b76
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/panel-simple.txt
@@ -0,0 +1,25 @@
+Simple display panel
+
+Required properties:
+- compatible: should be one of:
+  - "auo,b101aw03": AU Optronics Corporation 10.1" WSVGA TFT LCD panel
+  - "cptt,claa101wb03": Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel
+  - "pc,vvx10f004b00": Panasonic Corporation 10.1" WUXGA TFT LCD panel
+
+Optional properties:
+- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
+- power-supply: regulator to provide the supply voltage
+- enable-gpios: GPIO pin to enable or disable the panel
+- backlight: phandle of the backlight device attached to the panel
+
+Example:
+
+	panel: panel {
+		compatible = "cptt,claa101wb01";
+		ddc-i2c-bus = <&panelddc>;
+
+		power-supply = <&vdd_pnl_reg>;
+		enable-gpios = <&gpio 90 0>;
+
+		backlight = <&backlight>;
+	};
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 9b009c7..764a5ec 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_DRM_TILCDC)	+= tilcdc/
 obj-$(CONFIG_DRM_QXL) += qxl/
 obj-$(CONFIG_DRM_MSM) += msm/
 obj-y			+= i2c/
+obj-y			+= panel/
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 2ddd5bd..843087b 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -2,3 +2,16 @@ menuconfig DRM_PANEL
 	bool "DRM panel support"
 	help
 	  Panel registration and lookup framework.
+
+if DRM_PANEL
+
+config DRM_PANEL_SIMPLE
+	bool "support for simple panels"
+	depends on OF
+	help
+	  DRM panel driver for dumb panels that need at most a regulator and
+	  a GPIO to be powered up. Optionally a backlight can be attached so
+	  that it can be automatically turned off when the panel goes into a
+	  low power state.
+
+endif
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
new file mode 100644
index 0000000..af9dfa2
--- /dev/null
+++ b/drivers/gpu/drm/panel/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
new file mode 100644
index 0000000..e38cd6f
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/backlight.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_panel.h>
+
+struct panel_desc {
+	const struct drm_display_mode *modes;
+	unsigned int num_modes;
+
+	struct {
+		unsigned int width;
+		unsigned int height;
+	} size;
+};
+
+struct panel_simple {
+	struct drm_panel base;
+
+	const struct panel_desc *desc;
+
+	struct backlight_device *backlight;
+	struct regulator *supply;
+
+	unsigned long enable_gpio_flags;
+	int enable_gpio;
+};
+
+static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
+{
+	return container_of(panel, struct panel_simple, base);
+}
+
+static void panel_simple_dpms(struct drm_panel *panel, int mode)
+{
+	struct panel_simple *p = to_panel_simple(panel);
+	int err;
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		if (p->supply) {
+			err = regulator_enable(p->supply);
+			if (err < 0)
+				dev_err(panel->dev,
+					"failed to enable supply: %d\n",
+					err);
+		}
+
+		if (gpio_is_valid(p->enable_gpio)) {
+			if (p->enable_gpio_flags & GPIO_ACTIVE_LOW)
+				gpio_set_value(p->enable_gpio, 0);
+			else
+				gpio_set_value(p->enable_gpio, 1);
+		}
+	}
+
+	if (p->backlight) {
+		if (mode != DRM_MODE_DPMS_ON)
+			p->backlight->props.power = FB_BLANK_POWERDOWN;
+		else
+			p->backlight->props.power = FB_BLANK_UNBLANK;
+
+		backlight_update_status(p->backlight);
+	}
+
+	if (mode == DRM_MODE_DPMS_OFF) {
+		if (gpio_is_valid(p->enable_gpio)) {
+			if (p->enable_gpio_flags & GPIO_ACTIVE_LOW)
+				gpio_set_value(p->enable_gpio, 1);
+			else
+				gpio_set_value(p->enable_gpio, 0);
+		}
+
+		if (p->supply)
+			regulator_disable(p->supply);
+	}
+}
+
+static int panel_simple_get_modes(struct drm_panel *panel)
+{
+	struct panel_simple *p = to_panel_simple(panel);
+	struct drm_display_mode *mode;
+	unsigned int i;
+
+	for (i = 0; i < p->desc->num_modes; i++) {
+		mode = drm_mode_duplicate(panel->drm, &p->desc->modes[i]);
+		if (!mode)
+			return -ENOMEM;
+
+		drm_mode_set_name(mode);
+
+		drm_mode_probed_add(panel->connector, mode);
+	}
+
+	return p->desc->num_modes;
+}
+
+static const struct drm_panel_funcs panel_simple_funcs = {
+	.dpms = panel_simple_dpms,
+	.get_modes = panel_simple_get_modes,
+};
+
+static const struct drm_display_mode auo_b101aw03_mode = {
+	.clock = 51450,
+	.hdisplay = 1024,
+	.hsync_start = 1024 + 156,
+	.hsync_end = 1024 + 156 + 8,
+	.htotal = 1024 + 156 + 8 + 156,
+	.vdisplay = 600,
+	.vsync_start = 600 + 16,
+	.vsync_end = 600 + 16 + 6,
+	.vtotal = 600 + 16 + 6 + 16,
+	.vrefresh = 60,
+};
+
+static const struct panel_desc auo_b101aw03 = {
+	.modes = &auo_b101aw03_mode,
+	.num_modes = 1,
+	.size = {
+		.width = 223,
+		.height = 125,
+	},
+};
+
+static const struct drm_display_mode chunghwa_claa101wb01_mode = {
+	.clock = 69300,
+	.hdisplay = 1366,
+	.hsync_start = 1366 + 48,
+	.hsync_end = 1366 + 48 + 32,
+	.htotal = 1366 + 48 + 32 + 20,
+	.vdisplay = 768,
+	.vsync_start = 768 + 16,
+	.vsync_end = 768 + 16 + 8,
+	.vtotal = 768 + 16 + 8 + 16,
+	.vrefresh = 60,
+};
+
+static const struct panel_desc chunghwa_claa101wb01 = {
+	.modes = &chunghwa_claa101wb01_mode,
+	.num_modes = 1,
+	.size = {
+		.width = 223,
+		.height = 125,
+	},
+};
+
+static const struct drm_display_mode panasonic_vvx10f004b00_mode = {
+	.clock = 154700,
+	.hdisplay = 1920,
+	.hsync_start = 1920 + 154,
+	.hsync_end = 1920 + 154 + 16,
+	.htotal = 1920 + 154 + 16 + 32,
+	.vdisplay = 1200,
+	.vsync_start = 1200 + 17,
+	.vsync_end = 1200 + 17 + 2,
+	.vtotal = 1200 + 17 + 2 + 16,
+	.vrefresh = 60,
+};
+
+static const struct panel_desc panasonic_vvx10f004b00 = {
+	.modes = &panasonic_vvx10f004b00_mode,
+	.num_modes = 1,
+	.size = {
+		.width = 217,
+		.height = 136,
+	},
+};
+
+static const struct of_device_id panel_simple_of_match[] = {
+	{
+		.compatible = "auo,b101aw03",
+		.data = &auo_b101aw03,
+	}, {
+		.compatible = "cptt,claa101wb01",
+		.data = &chunghwa_claa101wb01
+	}, {
+		.compatible = "pc,vvx10f004b00",
+		.data = &panasonic_vvx10f004b00
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, panel_simple_of_match);
+
+static int panel_simple_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *id;
+	struct device_node *backlight;
+	struct panel_simple *panel;
+	enum of_gpio_flags flags;
+	int err;
+
+	panel = devm_kzalloc(&pdev->dev, sizeof(*panel), GFP_KERNEL);
+	if (!panel)
+		return -ENOMEM;
+
+	id = of_match_node(panel_simple_of_match, pdev->dev.of_node);
+	if (!id)
+		return -ENODEV;
+
+	panel->desc = id->data;
+
+	panel->supply = devm_regulator_get_optional(&pdev->dev, "power");
+	if (IS_ERR(panel->supply)) {
+		if (PTR_ERR(panel->supply) != -ENODEV) {
+			dev_err(&pdev->dev, "failed to get regulator: %ld\n",
+				PTR_ERR(panel->supply));
+			return PTR_ERR(panel->supply);
+		}
+
+		panel->supply = NULL;
+	}
+
+	panel->enable_gpio = of_get_named_gpio_flags(pdev->dev.of_node,
+						     "enable-gpios", 0,
+						     &flags);
+	if (gpio_is_valid(panel->enable_gpio)) {
+		unsigned int value;
+
+		if (flags & OF_GPIO_ACTIVE_LOW)
+			panel->enable_gpio_flags |= GPIO_ACTIVE_LOW;
+
+		err = gpio_request(panel->enable_gpio, "enable");
+		if (err < 0) {
+			dev_err(&pdev->dev, "failed to request GPIO#%u: %d\n",
+				panel->enable_gpio, err);
+			return err;
+		}
+
+		value = (panel->enable_gpio_flags & GPIO_ACTIVE_LOW) != 0;
+
+		err = gpio_direction_output(panel->enable_gpio, value);
+		if (err < 0) {
+			dev_err(&pdev->dev, "failed to setup GPIO%u: %d\n",
+				panel->enable_gpio, err);
+			goto free_gpio;
+		}
+	}
+
+	backlight = of_parse_phandle(pdev->dev.of_node, "backlight", 0);
+	if (backlight) {
+		panel->backlight = of_find_backlight_by_node(backlight);
+		if (!panel->backlight) {
+			err = -EPROBE_DEFER;
+			goto free_gpio;
+		}
+
+		of_node_put(backlight);
+	}
+
+	drm_panel_init(&panel->base);
+	panel->base.dev = &pdev->dev;
+	panel->base.funcs = &panel_simple_funcs;
+
+	err = drm_panel_add(&panel->base);
+	if (err < 0)
+		goto free_gpio;
+
+	platform_set_drvdata(pdev, panel);
+
+	return 0;
+
+free_gpio:
+	if (gpio_is_valid(panel->enable_gpio))
+		gpio_free(panel->enable_gpio);
+
+	return err;
+}
+
+static int panel_simple_remove(struct platform_device *pdev)
+{
+	struct panel_simple *panel = platform_get_drvdata(pdev);
+
+	if (gpio_is_valid(panel->enable_gpio)) {
+		if (panel->enable_gpio_flags & GPIO_ACTIVE_LOW)
+			gpio_set_value(panel->enable_gpio, 1);
+		else
+			gpio_set_value(panel->enable_gpio, 0);
+
+		gpio_free(panel->enable_gpio);
+	}
+
+	if (panel->supply)
+		regulator_disable(panel->supply);
+
+	if (panel->backlight)
+		put_device(&panel->backlight->dev);
+
+	drm_panel_detach(&panel->base);
+	drm_panel_remove(&panel->base);
+
+	return 0;
+}
+
+static struct platform_driver panel_simple_driver = {
+	.driver = {
+		.name = "panel-simple",
+		.owner = THIS_MODULE,
+		.of_match_table = panel_simple_of_match,
+	},
+	.probe = panel_simple_probe,
+	.remove = panel_simple_remove,
+};
+module_platform_driver(panel_simple_driver);
+
+MODULE_DESCRIPTION("DRM Driver for Simple Panels");
+MODULE_AUTHOR("Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
-- 
1.8.4

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

* [RFC 3/3] drm/tegra: Implement panel support
       [not found] ` <1377876321-26835-1-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2013-08-30 15:25   ` [RFC 1/3] " Thierry Reding
  2013-08-30 15:25   ` [RFC 2/3] drm/panel: Add simple " Thierry Reding
@ 2013-08-30 15:25   ` Thierry Reding
  2 siblings, 0 replies; 9+ messages in thread
From: Thierry Reding @ 2013-08-30 15:25 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA

Use the DRM panel framework to attach a panel to an output.

Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/host1x/drm/Kconfig  |  1 +
 drivers/gpu/host1x/drm/drm.h    |  1 +
 drivers/gpu/host1x/drm/output.c | 28 ++++++++++++++++++++++++++--
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index 69853a4..01b036d 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -2,6 +2,7 @@ config DRM_TEGRA
 	bool "NVIDIA Tegra DRM"
 	depends on DRM
 	select DRM_KMS_HELPER
+	select DRM_PANEL
 	select FB_SYS_FILLRECT
 	select FB_SYS_COPYAREA
 	select FB_SYS_IMAGEBLIT
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index 02ce020..a30276c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -195,6 +195,7 @@ struct tegra_output {
 	const struct tegra_output_ops *ops;
 	enum tegra_output_type type;
 
+	struct drm_panel *panel;
 	struct i2c_adapter *ddc;
 	const struct edid *edid;
 	unsigned int hpd_irq;
diff --git a/drivers/gpu/host1x/drm/output.c b/drivers/gpu/host1x/drm/output.c
index 137ae81..2ce03c1 100644
--- a/drivers/gpu/host1x/drm/output.c
+++ b/drivers/gpu/host1x/drm/output.c
@@ -11,6 +11,7 @@
 #include <linux/of_gpio.h>
 #include <linux/i2c.h>
 
+#include <drm/drm_panel.h>
 #include "drm.h"
 
 static int tegra_connector_get_modes(struct drm_connector *connector)
@@ -19,6 +20,9 @@ static int tegra_connector_get_modes(struct drm_connector *connector)
 	struct edid *edid = NULL;
 	int err = 0;
 
+	if (output->panel)
+		return output->panel->funcs->get_modes(output->panel);
+
 	if (output->edid)
 		edid = kmemdup(output->edid, sizeof(*edid), GFP_KERNEL);
 	else if (output->ddc)
@@ -74,6 +78,9 @@ tegra_connector_detect(struct drm_connector *connector, bool force)
 		else
 			status = connector_status_connected;
 	} else {
+		if (output->panel)
+			status = connector_status_connected;
+
 		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
 			status = connector_status_connected;
 	}
@@ -105,6 +112,11 @@ static const struct drm_encoder_funcs encoder_funcs = {
 
 static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
 {
+	struct tegra_output *output = encoder_to_output(encoder);
+	struct drm_panel *panel = output->panel;
+
+	if (panel && panel->funcs && panel->funcs->dpms)
+		panel->funcs->dpms(panel, mode);
 }
 
 static bool tegra_encoder_mode_fixup(struct drm_encoder *encoder,
@@ -153,14 +165,23 @@ static irqreturn_t hpd_irq(int irq, void *data)
 
 int tegra_output_parse_dt(struct tegra_output *output)
 {
+	struct device_node *ddc, *panel;
 	enum of_gpio_flags flags;
-	struct device_node *ddc;
 	size_t size;
 	int err;
 
 	if (!output->of_node)
 		output->of_node = output->dev->of_node;
 
+	panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
+	if (panel) {
+		output->panel = of_drm_find_panel(panel);
+		if (!output->panel)
+			return -EPROBE_DEFER;
+
+		of_node_put(panel);
+	}
+
 	output->edid = of_get_property(output->of_node, "nvidia,edid", &size);
 
 	ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0);
@@ -175,7 +196,7 @@ int tegra_output_parse_dt(struct tegra_output *output)
 		of_node_put(ddc);
 	}
 
-	if (!output->edid && !output->ddc)
+	if (!output->panel && !output->edid && !output->ddc)
 		return -ENODEV;
 
 	output->hpd_gpio = of_get_named_gpio_flags(output->of_node,
@@ -242,6 +263,9 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
 			   connector);
 	drm_connector_helper_add(&output->connector, &connector_helper_funcs);
 
+	if (output->panel)
+		drm_panel_attach(output->panel, &output->connector);
+
 	drm_encoder_init(drm, &output->encoder, &encoder_funcs, encoder);
 	drm_encoder_helper_add(&output->encoder, &encoder_helper_funcs);
 
-- 
1.8.4

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

* Re: [RFC 2/3] drm/panel: Add simple panel support
       [not found]     ` <1377876321-26835-3-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-08-30 19:24       ` Kumar Gala
       [not found]         ` <60046BAF-42E8-40FB-A45D-045B7C92513E-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2013-09-03 18:52       ` Stephen Warren
  1 sibling, 1 reply; 9+ messages in thread
From: Kumar Gala @ 2013-08-30 19:24 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA


On Aug 30, 2013, at 10:25 AM, Thierry Reding wrote:

> Add a driver for simple panels. Such panels can have a regulator that
> provides the supply voltage and a separate GPIO to enable the panel.
> Optionally the panels can have a backlight associated with them so it
> can be enabled or disabled according to the panel's power management
> mode.
> 
> Support is added for three panels: An AU Optronics 10.1" WSVGA, a
> Chunghwa Picture Tubes 10.1" WXGA and a Panasonic 10.1 WUXGA TFT LCD
> panel.
> 
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
> .../devicetree/bindings/panel/panel-simple.txt     |  25 ++
> drivers/gpu/drm/Makefile                           |   1 +
> drivers/gpu/drm/panel/Kconfig                      |  13 +
> drivers/gpu/drm/panel/Makefile                     |   1 +
> drivers/gpu/drm/panel/panel-simple.c               | 335 +++++++++++++++++++++
> 5 files changed, 375 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/panel/panel-simple.txt
> create mode 100644 drivers/gpu/drm/panel/Makefile
> create mode 100644 drivers/gpu/drm/panel/panel-simple.c
> 
> diff --git a/Documentation/devicetree/bindings/panel/panel-simple.txt b/Documentation/devicetree/bindings/panel/panel-simple.txt
> new file mode 100644
> index 0000000..dfd4b76
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/panel/panel-simple.txt
> @@ -0,0 +1,25 @@
> +Simple display panel
> +
> +Required properties:
> +- compatible: should be one of:
> +  - "auo,b101aw03": AU Optronics Corporation 10.1" WSVGA TFT LCD panel
> +  - "cptt,claa101wb03": Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel
> +  - "pc,vvx10f004b00": Panasonic Corporation 10.1" WUXGA TFT LCD panel
> +

It would seem there should be a more generic compatible to cover the basic "panel-simple" case.

> +Optional properties:
> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> +- power-supply: regulator to provide the supply voltage
> +- enable-gpios: GPIO pin to enable or disable the panel
> +- backlight: phandle of the backlight device attached to the panel
> +

If these are all optional, what does it mean to be a "panel-simple"?

> +Example:
> +
> +	panel: panel {
> +		compatible = "cptt,claa101wb01";
> +		ddc-i2c-bus = <&panelddc>;
> +
> +		power-supply = <&vdd_pnl_reg>;
> +		enable-gpios = <&gpio 90 0>;
> +
> +		backlight = <&backlight>;
> +	};

We'd normally do this as unique binding specs for the specific devices and a generic one to cover the concepts of a simple panel.  Who know if in the future a 'auo,b101aw03' might want some other unique properties.

[snip]

- k

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [RFC 1/3] drm: Add panel support
       [not found]     ` <1377876321-26835-2-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-09-03  2:20       ` Alex Courbot
  0 siblings, 0 replies; 9+ messages in thread
From: Alex Courbot @ 2013-09-03  2:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Thierry,

On 08/31/2013 12:25 AM, Thierry Reding wrote:
> Add a very simple framework to register and lookup panels. Panel drivers
> can initialize a DRM panel and register it with the framework, allowing
> them to be retrieved and used by display drivers. Currently only support
> for DPMS and obtaining panel modes is provided. However it should be
> sufficient to enable a large number of panels. The framework should also
> be easily extensible to support more sophisticated kinds of panels such
> as DSI.
>
> The framework hasn't been tied into the DRM core, even though it should
> be easily possible to do so if that's what we want. In the current
> implementation, display drivers can simple make use of it to retrieve a
> panel, obtain its modes and control its DPMS mode.
>
> Note that this is currently only tested on systems that boot from a
> device tree. No glue code has been written yet for systems that use
> platform data, but it should be easy to add.

Really like this. It's simple and to the point, and much needed since I 
guess many vendors have come with their own custom solution to handle 
panels. Do you know if it would be possible to convert these 
implementations to use your framework instead and consolidate the code 
around it?

Eventually this might be superseeded by the CDF, but if this happens it 
should not be too hard to convert the code, and we need something to use 
panels conveniently in the meantime.

> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>   drivers/gpu/drm/Kconfig       |  2 +
>   drivers/gpu/drm/Makefile      |  1 +
>   drivers/gpu/drm/drm_panel.c   | 96 +++++++++++++++++++++++++++++++++++++++++++
>   drivers/gpu/drm/panel/Kconfig |  4 ++
>   include/drm/drm_panel.h       | 65 +++++++++++++++++++++++++++++
>   5 files changed, 168 insertions(+)
>   create mode 100644 drivers/gpu/drm/drm_panel.c
>   create mode 100644 drivers/gpu/drm/panel/Kconfig
>   create mode 100644 include/drm/drm_panel.h
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 955555d..b4d8402 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -236,3 +236,5 @@ source "drivers/gpu/drm/tilcdc/Kconfig"
>   source "drivers/gpu/drm/qxl/Kconfig"
>
>   source "drivers/gpu/drm/msm/Kconfig"
> +
> +source "drivers/gpu/drm/panel/Kconfig"
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index f089adf..9b009c7 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -18,6 +18,7 @@ drm-y       :=        drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
>   drm-$(CONFIG_COMPAT) += drm_ioc32.o
>   drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
>   drm-$(CONFIG_PCI) += ati_pcigart.o
> +drm-$(CONFIG_DRM_PANEL) += drm_panel.o
>
>   drm-usb-y   := drm_usb.o
>
> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> new file mode 100644
> index 0000000..ff6e459
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_panel.c
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sub license,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/export.h>
> +
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_panel.h>
> +
> +static DEFINE_MUTEX(panel_lock);
> +static LIST_HEAD(panel_list);
> +
> +void drm_panel_init(struct drm_panel *panel)
> +{
> +       INIT_LIST_HEAD(&panel->list);
> +}
> +EXPORT_SYMBOL(drm_panel_init);
> +
> +int drm_panel_add(struct drm_panel *panel)
> +{
> +       mutex_lock(&panel_lock);
> +       list_add_tail(&panel->list, &panel_list);
> +       mutex_unlock(&panel_lock);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_panel_add);
> +
> +void drm_panel_remove(struct drm_panel *panel)
> +{
> +       mutex_lock(&panel_lock);
> +       list_del_init(&panel->list);
> +       mutex_unlock(&panel_lock);
> +}
> +EXPORT_SYMBOL(drm_panel_remove);
> +
> +int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
> +{
> +       if (panel->connector)
> +               return -EBUSY;
> +
> +       panel->connector = connector;
> +       panel->drm = connector->dev;

Since connector and drm both seem to only be set here, and drm can 
easily be derived from connector (connector->dev), do you need the drm 
member at all?

> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_panel_attach);
> +
> +int drm_panel_detach(struct drm_panel *panel)
> +{
> +       panel->connector = NULL;
> +       panel->drm = NULL;
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_panel_detach);
> +
> +#ifdef CONFIG_OF
> +struct drm_panel *of_drm_find_panel(struct device_node *np)
> +{
> +       struct drm_panel *panel;
> +
> +       mutex_lock(&panel_lock);
> +
> +       list_for_each_entry(panel, &panel_list, list) {
> +               if (panel->dev->of_node == np) {
> +                       mutex_unlock(&panel_lock);
> +                       return panel;
> +               }
> +       }
> +
> +       mutex_unlock(&panel_lock);
> +       return NULL;
> +}
> +EXPORT_SYMBOL(of_drm_find_panel);
> +#endif
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> new file mode 100644
> index 0000000..2ddd5bd
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -0,0 +1,4 @@
> +menuconfig DRM_PANEL
> +       bool "DRM panel support"
> +       help
> +         Panel registration and lookup framework.
> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> new file mode 100644
> index 0000000..f02b615
> --- /dev/null
> +++ b/include/drm/drm_panel.h
> @@ -0,0 +1,65 @@
> +/*
> + * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sub license,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifndef __DRM_PANEL_H__
> +#define __DRM_PANEL_H__
> +
> +#include <linux/list.h>
> +
> +struct drm_connector;
> +struct drm_device;
> +struct drm_panel;
> +
> +struct drm_panel_funcs {
> +       void (*dpms)(struct drm_panel *panel, int mode);
> +       int (*get_modes)(struct drm_panel *panel);
> +};
> +
> +struct drm_panel {
> +       struct drm_device *drm;
> +       struct drm_connector *connector;
> +       struct device *dev;
> +
> +       const struct drm_panel_funcs *funcs;
> +
> +       struct list_head list;
> +};
> +
> +void drm_panel_init(struct drm_panel *panel);
> +
> +int drm_panel_add(struct drm_panel *panel);
> +void drm_panel_remove(struct drm_panel *panel);
> +
> +int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector);
> +int drm_panel_detach(struct drm_panel *panel);
> +
> +#ifdef CONFIG_OF
> +struct drm_panel *of_drm_find_panel(struct device_node *np);
> +#else
> +static inline struct drm_panel *of_drm_find_panel(struct device_node *np)
> +{
> +       return NULL;
> +}
> +#endif
> +
> +#endif
> --
> 1.8.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

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

* Re: [RFC 2/3] drm/panel: Add simple panel support
       [not found]         ` <60046BAF-42E8-40FB-A45D-045B7C92513E-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2013-09-03 18:49           ` Stephen Warren
  0 siblings, 0 replies; 9+ messages in thread
From: Stephen Warren @ 2013-09-03 18:49 UTC (permalink / raw)
  To: Kumar Gala
  Cc: Thierry Reding, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On 08/30/2013 01:24 PM, Kumar Gala wrote:
> 
> On Aug 30, 2013, at 10:25 AM, Thierry Reding wrote:
> 
>> Add a driver for simple panels. Such panels can have a regulator that
>> provides the supply voltage and a separate GPIO to enable the panel.
>> Optionally the panels can have a backlight associated with them so it
>> can be enabled or disabled according to the panel's power management
>> mode.
>>
>> Support is added for three panels: An AU Optronics 10.1" WSVGA, a
>> Chunghwa Picture Tubes 10.1" WXGA and a Panasonic 10.1 WUXGA TFT LCD
>> panel.

>> diff --git a/Documentation/devicetree/bindings/panel/panel-simple.txt b/Documentation/devicetree/bindings/panel/panel-simple.txt

>> +Required properties:
>> +- compatible: should be one of:
>> +  - "auo,b101aw03": AU Optronics Corporation 10.1" WSVGA TFT LCD panel
>> +  - "cptt,claa101wb03": Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel
>> +  - "pc,vvx10f004b00": Panasonic Corporation 10.1" WUXGA TFT LCD panel
>> +
> 
> It would seem there should be a more generic compatible to cover the basic "panel-simple" case.

I would suggest only documenting "simple-panel" here, and not
documenting the specific panels at all; the panel-specific compatible
values would show up simply due to the rule that all compatible values
in *.dts should contain the exact HW model (e.g. "auo,b101aw03"), plus
any HW they're compatible with (i.e. "simple-panel").

I'd suggest "simple-panel" rather than "panel-simple" since IIRC other
simple bindings are "simple-xxx" rather than "xxx-simple".

>> +Optional properties:
>> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
>> +- power-supply: regulator to provide the supply voltage
>> +- enable-gpios: GPIO pin to enable or disable the panel
>> +- backlight: phandle of the backlight device attached to the panel
>> +
> 
> If these are all optional, what does it mean to be a "panel-simple"?

I think at least ddc-i2c-bus and backlight should be required
properties. I suppose it might be possible for the panel to be
always-on, and hence enable-gpios/power-supply could be optional?

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

* Re: [RFC 2/3] drm/panel: Add simple panel support
       [not found]     ` <1377876321-26835-3-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2013-08-30 19:24       ` Kumar Gala
@ 2013-09-03 18:52       ` Stephen Warren
       [not found]         ` <52262FF4.6050605-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  1 sibling, 1 reply; 9+ messages in thread
From: Stephen Warren @ 2013-09-03 18:52 UTC (permalink / raw)
  To: Thierry Reding
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On 08/30/2013 09:25 AM, Thierry Reding wrote:
> Add a driver for simple panels. Such panels can have a regulator that
> provides the supply voltage and a separate GPIO to enable the panel.
> Optionally the panels can have a backlight associated with them so it
> can be enabled or disabled according to the panel's power management
> mode.

> diff --git a/Documentation/devicetree/bindings/panel/panel-simple.txt b/Documentation/devicetree/bindings/panel/panel-simple.txt

> +Simple display panel
> +
> +Required properties:
> +- compatible: should be one of:
> +  - "auo,b101aw03": AU Optronics Corporation 10.1" WSVGA TFT LCD panel
> +  - "cptt,claa101wb03": Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel
> +  - "pc,vvx10f004b00": Panasonic Corporation 10.1" WUXGA TFT LCD panel
> +
> +Optional properties:
> +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> +- power-supply: regulator to provide the supply voltage
> +- enable-gpios: GPIO pin to enable or disable the panel
> +- backlight: phandle of the backlight device attached to the panel

Do we need to represent the timing requirements e.g. between panel
enable and backlight enable, or do you expect the driver to hard-code
this based on the compatible value?

Looking at the driver code, it seems that it has direct knowledge of the
video mode that each panel supports, so DDC is actually optional unlike
what I asserted/assumed in my previous response. As such, I guess we
should have a separate DT binding document for each of the three panels
(compatible values) listed above that pretty much just says "go look at
simple-panel.txt".

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

* Re: [RFC 2/3] drm/panel: Add simple panel support
       [not found]         ` <52262FF4.6050605-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2013-09-04 14:38           ` Thierry Reding
  0 siblings, 0 replies; 9+ messages in thread
From: Thierry Reding @ 2013-09-04 14:38 UTC (permalink / raw)
  To: Stephen Warren
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA

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

On Tue, Sep 03, 2013 at 12:52:36PM -0600, Stephen Warren wrote:
> On 08/30/2013 09:25 AM, Thierry Reding wrote:
> > Add a driver for simple panels. Such panels can have a regulator that
> > provides the supply voltage and a separate GPIO to enable the panel.
> > Optionally the panels can have a backlight associated with them so it
> > can be enabled or disabled according to the panel's power management
> > mode.
> 
> > diff --git a/Documentation/devicetree/bindings/panel/panel-simple.txt b/Documentation/devicetree/bindings/panel/panel-simple.txt
> 
> > +Simple display panel
> > +
> > +Required properties:
> > +- compatible: should be one of:
> > +  - "auo,b101aw03": AU Optronics Corporation 10.1" WSVGA TFT LCD panel
> > +  - "cptt,claa101wb03": Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel
> > +  - "pc,vvx10f004b00": Panasonic Corporation 10.1" WUXGA TFT LCD panel
> > +
> > +Optional properties:
> > +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
> > +- power-supply: regulator to provide the supply voltage
> > +- enable-gpios: GPIO pin to enable or disable the panel
> > +- backlight: phandle of the backlight device attached to the panel
> 
> Do we need to represent the timing requirements e.g. between panel
> enable and backlight enable, or do you expect the driver to hard-code
> this based on the compatible value?

Yes, I'd expect the driver to hard-code that, similar to how the video
mode is hardcoded. ddc-i2c-bus support hasn't even been implemented yet.
I was planning to do that because one of the panels (the Chunghwa I
think) actually is connected via DDC. What I was going to do was prefer
a hardcoded mode over EDID to allow a driver to override a faulty EDID.

> Looking at the driver code, it seems that it has direct knowledge of the
> video mode that each panel supports, so DDC is actually optional unlike
> what I asserted/assumed in my previous response. As such, I guess we
> should have a separate DT binding document for each of the three panels
> (compatible values) listed above that pretty much just says "go look at
> simple-panel.txt".

Okay, I suppose that makes sense.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

end of thread, other threads:[~2013-09-04 14:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-30 15:25 [RFC 0/3] drm: Add panel support Thierry Reding
     [not found] ` <1377876321-26835-1-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-08-30 15:25   ` [RFC 1/3] " Thierry Reding
     [not found]     ` <1377876321-26835-2-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-09-03  2:20       ` Alex Courbot
2013-08-30 15:25   ` [RFC 2/3] drm/panel: Add simple " Thierry Reding
     [not found]     ` <1377876321-26835-3-git-send-email-treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-08-30 19:24       ` Kumar Gala
     [not found]         ` <60046BAF-42E8-40FB-A45D-045B7C92513E-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2013-09-03 18:49           ` Stephen Warren
2013-09-03 18:52       ` Stephen Warren
     [not found]         ` <52262FF4.6050605-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-09-04 14:38           ` Thierry Reding
2013-08-30 15:25   ` [RFC 3/3] drm/tegra: Implement " Thierry Reding

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.