All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display
@ 2014-05-21  4:42 YoungJun Cho
  2014-05-21  4:42 ` [PATCH v2 01/18] drm/exynos: dsi: move the EoT packets configuration point YoungJun Cho
                   ` (14 more replies)
  0 siblings, 15 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:42 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: devicetree, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux-samsung-soc, thierry.reding, laurent.pinchart,
	s.trumtrar, djkurtz, kyungmin.park, inki.dae, kgene.kim,
	jy0922.shim, sw0312.kim, a.hajda

Hi,

This series is for the Exynos DRM driver to support MIPI DSI command mode
display and based on exynos-drm-next branch.

The previous patches,
RFC: http://www.spinics.net/lists/dri-devel/msg58898.html
V1: http://www.spinics.net/lists/dri-devel/msg59291.html

Changelog v2:
- Rebases for latest exynos-drm-next branch
- Fixes typo and removes unnecessary error log (commented by Andrzej Hazda)
- Adds missed pendlig_flip flag clear points (commented by Daniel Kurtz)

Patches 1 and 2 fix trivial bugs.

Patches 3 and 4 introduce command mode and command mode display timing.
These are based on video mode and (video mode) display timing.
The MIPI DSI command mode interface panel does not require (video mode) display
timing, but it requires signal timings to distinguish command data and video
data so command mode and command mode display timing are used for it.

Patch 5 converts command mode to drm display mode.

Patches 6, 7, 8, 9 and 10 implement FIMD(display controller) I80 interface.
The MIPI DSI command mode interface panel generates Tearing Effect
synchronization signal between MCU and FB to display video image,
and FIMD should trigger to transfer video image at this signal.
So the panel should receive the TE IRQ then calls TE handler chains to notify
it to the FIMD.

Patches 11 and 12 implement to use Exynos5420 SoC DSI driver which is different
from previous Exynos4 SoCs for some registers control.

Patches 13 and 14 introduce MIPI DSI command interface Samsung S6E3FA0 AMOLED
5.7" LCD panel driver.

Patch 15 is device tree source file for Exynos4 SoCs to support MIPI DSI
command mode.

The others are device tree source files for Exynos5420 to support MIPI DSI
(command mode) driver.

I welcome any comments.

Thank you.
Best regards YJ

YoungJun Cho (18):
  drm/exynos: dsi: move the EoT packets configuration point
  drm/exynos: use wait_event_timeout() for safety usage
  ARM: dts: video: add command mode display timing DT bindings
  video: add command mode and command mode display timing
  drm_modes: add command mode helpers
  ARM: dts: sysreg: add exynos5 compatible to DT bindings
  ARM: dts: samsung-fimd: add I80 specific properties
  drm/exynos: add TE handler to support MIPI DSI command mode interface
  drm/exynos: dsi: add TE handler to support command mode interface
  drm/exynos: fimd: support I80 interface
  ARM: dts: exynos_dsim: add exynos5420 compatible to DT bindings
  drm/exynos: dsi: add driver data to support Exynos5420
  ARM: dts: s6e3fa0: add DT bindings
  drm/panel: add S6E3FA0 driver
  ARM: dts: exynos4: add system register node
  ARM: dts: exynos5: add system register support
  ARM: dts: exynos5420: add mipi-phy node
  ARM: dts: exynos5420: add dsi node

 .../devicetree/bindings/arm/samsung/sysreg.txt     |    1 +
 .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++
 .../bindings/video/cmdmode-display-timing.txt      |   64 +++
 .../devicetree/bindings/video/exynos_dsim.txt      |    4 +-
 .../devicetree/bindings/video/samsung-fimd.txt     |    2 +
 arch/arm/boot/dts/exynos4.dtsi                     |    1 +
 arch/arm/boot/dts/exynos5.dtsi                     |    6 +
 arch/arm/boot/dts/exynos5420.dtsi                  |   20 +
 drivers/gpu/drm/drm_modes.c                        |   59 ++
 drivers/gpu/drm/exynos/Kconfig                     |    1 +
 drivers/gpu/drm/exynos/exynos_drm_crtc.c           |   18 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.h           |    7 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h            |    3 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c            |  175 +++++-
 drivers/gpu/drm/exynos/exynos_drm_fimd.c           |  277 ++++++++--
 drivers/gpu/drm/panel/Kconfig                      |    7 +
 drivers/gpu/drm/panel/Makefile                     |    1 +
 drivers/gpu/drm/panel/panel-s6e3fa0.c              |  568 ++++++++++++++++++++
 drivers/video/Kconfig                              |    3 +
 drivers/video/Makefile                             |    2 +
 drivers/video/cmdmode.c                            |   42 ++
 drivers/video/cmdmode_display_timing.c             |   26 +
 drivers/video/of_cmdmode.c                         |   55 ++
 drivers/video/of_cmdmode_display_timing.c          |  212 ++++++++
 include/drm/drm_mipi_dsi.h                         |    8 +
 include/drm/drm_modes.h                            |   12 +
 include/video/cmdmode.h                            |   67 +++
 include/video/cmdmode_display_timing.h             |   59 ++
 include/video/of_cmdmode.h                         |   19 +
 include/video/of_cmdmode_display_timing.h          |   26 +
 include/video/samsung_fimd.h                       |    3 +-
 31 files changed, 1722 insertions(+), 71 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
 create mode 100644 Documentation/devicetree/bindings/video/cmdmode-display-timing.txt
 create mode 100644 drivers/gpu/drm/panel/panel-s6e3fa0.c
 create mode 100644 drivers/video/cmdmode.c
 create mode 100644 drivers/video/cmdmode_display_timing.c
 create mode 100644 drivers/video/of_cmdmode.c
 create mode 100644 drivers/video/of_cmdmode_display_timing.c
 create mode 100644 include/video/cmdmode.h
 create mode 100644 include/video/cmdmode_display_timing.h
 create mode 100644 include/video/of_cmdmode.h
 create mode 100644 include/video/of_cmdmode_display_timing.h

-- 
1.7.9.5

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

* [PATCH v2 01/18] drm/exynos: dsi: move the EoT packets configuration point
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
@ 2014-05-21  4:42 ` YoungJun Cho
  2014-05-21  4:42 ` [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage YoungJun Cho
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:42 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

This configuration could be used in MIPI DSI command mode also.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 84661fe..0a4e3ce 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -473,8 +473,6 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 
 		if (!(dsi->mode_flags & MIPI_DSI_MODE_VSYNC_FLUSH))
 			reg |= DSIM_MFLUSH_VS;
-		if (!(dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET))
-			reg |= DSIM_EOT_DISABLE;
 		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
 			reg |= DSIM_SYNC_INFORM;
 		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
@@ -491,6 +489,9 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 			reg |= DSIM_HSA_MODE;
 	}
 
+	if (!(dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET))
+		reg |= DSIM_EOT_DISABLE;
+
 	switch (dsi->format) {
 	case MIPI_DSI_FMT_RGB888:
 		reg |= DSIM_MAIN_PIX_FORMAT_RGB888;
-- 
1.7.9.5

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

* [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
  2014-05-21  4:42 ` [PATCH v2 01/18] drm/exynos: dsi: move the EoT packets configuration point YoungJun Cho
@ 2014-05-21  4:42 ` YoungJun Cho
  2014-05-21  6:01   ` Daniel Kurtz
  2014-05-21  4:42 ` [PATCH v2 04/18] video: add command mode and command mode display timing YoungJun Cho
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:42 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

There could be the case that the page flip operation isn't finished correctly
with some abnormal condition such as panel reset. So this patch replaces
wait_event() with wait_event_timeout() to avoid waiting for page flip completion
infinitely.
And clears exynos_crtc->pending_flip in exynos_drm_crtc_page_flip() when
exynos_drm_crtc_mode_set_commit() is failed.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 95c9435..3bf091d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -69,8 +69,10 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
 
 	if (mode > DRM_MODE_DPMS_ON) {
 		/* wait for the completion of page flip. */
-		wait_event(exynos_crtc->pending_flip_queue,
-				atomic_read(&exynos_crtc->pending_flip) == 0);
+		if (!wait_event_timeout(exynos_crtc->pending_flip_queue,
+				!atomic_read(&exynos_crtc->pending_flip),
+				HZ/20))
+			atomic_set(&exynos_crtc->pending_flip, 0);
 		drm_vblank_off(crtc->dev, exynos_crtc->pipe);
 	}
 
@@ -259,6 +261,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
 			spin_lock_irq(&dev->event_lock);
 			drm_vblank_put(dev, exynos_crtc->pipe);
 			list_del(&event->base.link);
+			atomic_set(&exynos_crtc->pending_flip, 0);
 			spin_unlock_irq(&dev->event_lock);
 
 			goto out;
-- 
1.7.9.5

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

* [PATCH v2 03/18] ARM: dts: video: add command mode display timing DT bindings
       [not found] ` <1400647390-26590-1-git-send-email-yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2014-05-21  4:42   ` YoungJun Cho
  2014-05-21  4:43   ` [PATCH v2 08/18] drm/exynos: add TE handler to support MIPI DSI command mode interface YoungJun Cho
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:42 UTC (permalink / raw)
  To: airlied-cv59FeDIM0c, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw,
	s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ,
	djkurtz-F7+t8E8rja9g9hUCZPvPmw,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	inki.dae-Sze3O3UU22JBDgjK7y7TUQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	a.hajda-Sze3O3UU22JBDgjK7y7TUQ

This patch adds DT bindings for command mode display timing.

Signed-off-by: YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Inki Dae <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 .../bindings/video/cmdmode-display-timing.txt      |   64 ++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/cmdmode-display-timing.txt

diff --git a/Documentation/devicetree/bindings/video/cmdmode-display-timing.txt b/Documentation/devicetree/bindings/video/cmdmode-display-timing.txt
new file mode 100644
index 0000000..7cedfe4
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/cmdmode-display-timing.txt
@@ -0,0 +1,64 @@
+cmdmode-display-timing bindings
+===================================
+
+cmdmode-display-timings node
+--------------------------------
+
+required properties:
+ - none
+
+optional properties:
+ - native-mode: The native mode for the display, in case multiple modes are
+		provided. When omitted, assume the first node is the native.
+
+timing subnode
+--------------
+
+required properties:
+ - clock-frequency: display clock in Hz
+ - hactive, vactive: display resolution
+ - cs-setup: clock cycles for the active period of address signal is enabled
+		until chip select is enabled.
+ - wr-setup: clock cycles for the active period of CS signal is enabled until
+		write signal is enabled.
+ - wr-active: clock cycles for the active period of CS is enabled.
+ - wr-hold: clock cycles for the active period of CS is disabled until write
+		signal is disabled.
+
+optional properties:
+
+There are different ways of describing the capabilities of a display. The
+devicetree representation corresponds to the one commonly found in datasheets
+for displays. If a display supports multiple signal timings, the native-mode
+can be specified.
+
+The parameters are defined as:
+
+  VCLK(internal)  __|¯¯¯¯¯¯|_____|¯¯¯¯¯¯|_____|¯¯¯¯¯¯|_____|¯¯¯¯¯¯|_____|¯¯
+                    :            :            :            :            :
+  Address Output  --:<XXXXXXXXXXX:XXXXXXXXXXXX:XXXXXXXXXXXX:XXXXXXXXXXXX:XX
+                    | CS-SETUP+1 |            :            :            :
+                    |<---------->|            :            :            :
+  Chip Select     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|____________:____________:____________|¯¯
+                                 | WR-SETUP+1 |            | WR-HOLD+1  |
+                                 |<---------->|            |<---------->|
+  Write Enable    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|____________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+                                              | WR-ACTIVE+1|
+                                              |<---------->|
+  Video Data      ----------------------------<XXXXXXXXXXXXXXXXXXXXXXXXX>--
+
+Example:
+
+	cmdmode-display-timings {
+		native-mode = <&timing0>;
+		timing0: 1080p24 {
+			/* 1920x1080p24 */
+			clock-frequency = <52000000>;
+			hactive = <1920>;
+			vactive = <1080>;
+			cs-setup = <0>;
+			wr-setup = <0>;
+			wr-active = <1>;
+			wr-hold = <0>;
+		};
+	};
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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 related	[flat|nested] 39+ messages in thread

* [PATCH v2 04/18] video: add command mode and command mode display timing
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
  2014-05-21  4:42 ` [PATCH v2 01/18] drm/exynos: dsi: move the EoT packets configuration point YoungJun Cho
  2014-05-21  4:42 ` [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage YoungJun Cho
@ 2014-05-21  4:42 ` YoungJun Cho
  2014-05-21 11:02   ` Thierry Reding
  2014-05-26 10:14   ` Thierry Reding
  2014-05-21  4:42 ` [PATCH v2 05/18] drm_modes: add command mode helpers YoungJun Cho
                   ` (11 subsequent siblings)
  14 siblings, 2 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:42 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: devicetree, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux-samsung-soc, thierry.reding, laurent.pinchart,
	s.trumtrar, djkurtz, kyungmin.park, inki.dae, kgene.kim,
	jy0922.shim, sw0312.kim, a.hajda

This patch is based on videomode and display_timing relevant codes.
To support command mode panel, it does not need to guide its timing
information to the display controller like video mode panel,
but it requires signal timings to transfer video data.
So this patch adds cmdmode struct, cmdmode_display_timing struct and
the according helper functions to convert cmdmode_display_timing
to a generic cmdmode.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/video/Kconfig                     |    3 +
 drivers/video/Makefile                    |    2 +
 drivers/video/cmdmode.c                   |   42 ++++++
 drivers/video/cmdmode_display_timing.c    |   26 ++++
 drivers/video/of_cmdmode.c                |   55 ++++++++
 drivers/video/of_cmdmode_display_timing.c |  212 +++++++++++++++++++++++++++++
 include/video/cmdmode.h                   |   67 +++++++++
 include/video/cmdmode_display_timing.h    |   59 ++++++++
 include/video/of_cmdmode.h                |   19 +++
 include/video/of_cmdmode_display_timing.h |   26 ++++
 10 files changed, 511 insertions(+)
 create mode 100644 drivers/video/cmdmode.c
 create mode 100644 drivers/video/cmdmode_display_timing.c
 create mode 100644 drivers/video/of_cmdmode.c
 create mode 100644 drivers/video/of_cmdmode_display_timing.c
 create mode 100644 include/video/cmdmode.h
 create mode 100644 include/video/cmdmode_display_timing.h
 create mode 100644 include/video/of_cmdmode.h
 create mode 100644 include/video/of_cmdmode_display_timing.h

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index c7b4f0f..7090ee5 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -38,6 +38,9 @@ config VGASTATE
 config VIDEOMODE_HELPERS
 	bool
 
+config CMDMODE_HELPERS
+	bool
+
 config HDMI
 	bool
 
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 9ad3c17..619dd99 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -8,6 +8,8 @@ obj-y				  += backlight/
 obj-y				  += fbdev/
 
 obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o
+obj-$(CONFIG_CMDMODE_HELPERS) += cmdmode_display_timing.o cmdmode.o
 ifeq ($(CONFIG_OF),y)
 obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o
+obj-$(CONFIG_CMDMODE_HELPERS) += of_cmdmode_display_timing.o of_cmdmode.o
 endif
diff --git a/drivers/video/cmdmode.c b/drivers/video/cmdmode.c
new file mode 100644
index 0000000..3d3eeb8
--- /dev/null
+++ b/drivers/video/cmdmode.c
@@ -0,0 +1,42 @@
+/*
+ * generic cmdmode display timing functions
+ *
+ * Copyright (c) 2014 YoungJun Cho <yj44.cho@samsung.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.
+ */
+
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <video/cmdmode_display_timing.h>
+#include <video/cmdmode.h>
+
+void cmdmode_from_timing(const struct cmdmode_display_timing *cmdt,
+				struct cmdmode *cm)
+{
+	cm->pixelclock = cmdt->pixelclock;
+	cm->hactive = cmdt->hactive;
+	cm->vactive = cmdt->vactive;
+	cm->cs_setup = cmdt->cs_setup;
+	cm->wr_setup = cmdt->wr_setup;
+	cm->wr_active = cmdt->wr_active;
+	cm->wr_hold = cmdt->wr_hold;
+}
+EXPORT_SYMBOL_GPL(cmdmode_from_timing);
+
+int cmdmode_from_timings(const struct cmdmode_display_timings *cmdts,
+				struct cmdmode *cm, unsigned int index)
+{
+	struct cmdmode_display_timing *cmdt;
+
+	cmdt = cmdmode_display_timings_get(cmdts, index);
+	if (!cmdt)
+		return -EINVAL;
+
+	cmdmode_from_timing(cmdt, cm);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cmdmode_from_timings);
diff --git a/drivers/video/cmdmode_display_timing.c b/drivers/video/cmdmode_display_timing.c
new file mode 100644
index 0000000..88bab08
--- /dev/null
+++ b/drivers/video/cmdmode_display_timing.c
@@ -0,0 +1,26 @@
+/*
+ * generic cmdmode display timing functions
+ *
+ * Copyright (c) 2014 YoungJun Cho <yj44.cho@samsung.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.
+ */
+
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <video/cmdmode_display_timing.h>
+
+void cmdmode_display_timings_release(struct cmdmode_display_timings *cmdts)
+{
+	if (cmdts->timings) {
+		unsigned int i;
+
+		for (i = 0; i < cmdts->num_timings; i++)
+			kfree(cmdts->timings[i]);
+		kfree(cmdts->timings);
+	}
+	kfree(cmdts);
+}
+EXPORT_SYMBOL_GPL(cmdmode_display_timings_release);
diff --git a/drivers/video/of_cmdmode.c b/drivers/video/of_cmdmode.c
new file mode 100644
index 0000000..d63294e
--- /dev/null
+++ b/drivers/video/of_cmdmode.c
@@ -0,0 +1,55 @@
+/*
+ * generic cmdmode helper
+ *
+ * Copyright (c) 2014 YoungJun Cho <yj44.cho@samsung.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.
+ */
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/of.h>
+#include <video/cmdmode_display_timing.h>
+#include <video/of_cmdmode_display_timing.h>
+#include <video/of_cmdmode.h>
+#include <video/cmdmode.h>
+
+/**
+ * of_get_cmdmode - get the cmdmode #<index> from devicetree
+ * @np - devicenode with the cmdmode_display_timings
+ * @cm - set to return value
+ * @index - index into list of cmdmode_display_timings
+ *	    (Set this to OF_USE_CMDMODE_NATIVE_MODE to use whatever mode is
+ *	     specified as native mode in the DT.)
+ *
+ * DESCRIPTION:
+ * Get a list of all display timings and put the one
+ * specified by index into *cm. This function should only be used, if
+ * only one cmdmode is to be retrieved. A driver that needs to work
+ * with multiple/all cmdmodes should work with
+ * of_get_cmdmode_display_timings instead.
+ **/
+int of_get_cmdmode(struct device_node *np, struct cmdmode *cm, int index)
+{
+	struct cmdmode_display_timings *cmdts;
+	int ret;
+
+	cmdts = of_get_cmdmode_display_timings(np);
+	if (!cmdts) {
+		pr_err("%s: no timings specified\n", of_node_full_name(np));
+		return -EINVAL;
+	}
+
+	if (index == OF_USE_CMDMODE_NATIVE_MODE)
+		index = cmdts->native_mode;
+
+	ret = cmdmode_from_timings(cmdts, cm, index);
+	if (ret)
+		return ret;
+
+	cmdmode_display_timings_release(cmdts);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_cmdmode);
diff --git a/drivers/video/of_cmdmode_display_timing.c b/drivers/video/of_cmdmode_display_timing.c
new file mode 100644
index 0000000..fcf2b35
--- /dev/null
+++ b/drivers/video/of_cmdmode_display_timing.c
@@ -0,0 +1,212 @@
+/*
+ * OF helpers for parsing cmdmode display timings
+ *
+ * Copyright (c) 2014 YoungJun Cho <yj44.cho@samsung.com>
+ *
+ * based on of_cmdmode.c
+ *
+ * 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.
+ */
+#include <linux/export.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <video/cmdmode_display_timing.h>
+#include <video/of_cmdmode_display_timing.h>
+
+/**
+ * of_parse_cmdmode_display_timing - parse cmdmode_display_timing entry
+ *					from device_node
+ * @np: device_node with the properties
+ **/
+static int of_parse_cmdmode_display_timing(const struct device_node *np,
+					struct cmdmode_display_timing *cmdt)
+{
+	int ret = 0;
+
+	memset(cmdt, 0, sizeof(*cmdt));
+
+	ret |= of_property_read_u32(np, "clock-frequency", &cmdt->pixelclock);
+	ret |= of_property_read_u32(np, "hactive", &cmdt->hactive);
+	ret |= of_property_read_u32(np, "vactive", &cmdt->vactive);
+	ret |= of_property_read_u32(np, "cs-setup", &cmdt->cs_setup);
+	ret |= of_property_read_u32(np, "wr-setup", &cmdt->wr_setup);
+	ret |= of_property_read_u32(np, "wr-active", &cmdt->wr_active);
+	ret |= of_property_read_u32(np, "wr-hold", &cmdt->wr_hold);
+
+	if (ret) {
+		pr_err("%s: error reading cmdmode timing properties\n",
+			of_node_full_name(np));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * of_get_cmdmode_display_timing - parse a cmdmode_display_timing entry
+ * @np: device_node with the timing subnode
+ * @name: name of the timing node
+ * @cmdt: cmdmode_display_timing struct to fill
+ **/
+int of_get_cmdmode_display_timing(struct device_node *np, const char *name,
+					struct cmdmode_display_timing *cmdt)
+{
+	struct device_node *timing_np;
+
+	if (!np) {
+		pr_err("%s: no devicenode given\n", of_node_full_name(np));
+		return -EINVAL;
+	}
+
+	timing_np = of_get_child_by_name(np, name);
+	if (!timing_np) {
+		pr_err("%s: could not find node '%s'\n",
+			of_node_full_name(np), name);
+		return -ENOENT;
+	}
+
+	return of_parse_cmdmode_display_timing(timing_np, cmdt);
+}
+EXPORT_SYMBOL_GPL(of_get_cmdmode_display_timing);
+
+/**
+ * of_get_cmdmode_display_timings - parse all cmdmode_display_timing
+ * entries from a device_node
+ * @np: device_node with the subnodes
+ **/
+struct cmdmode_display_timings*
+of_get_cmdmode_display_timings(struct device_node *np)
+{
+	struct device_node *timings_np;
+	struct device_node *entry;
+	struct device_node *native_mode;
+	struct cmdmode_display_timings *cmdts;
+
+	if (!np) {
+		pr_err("%s: no device node given\n", of_node_full_name(np));
+		return NULL;
+	}
+
+	timings_np = of_get_child_by_name(np, "cmdmode-display-timings");
+	if (!timings_np) {
+		pr_err("%s: could not find cmdmode-display-timings node\n",
+			of_node_full_name(np));
+		return NULL;
+	}
+
+	cmdts = kzalloc(sizeof(*cmdts), GFP_KERNEL);
+	if (!cmdts) {
+		pr_err("%s: could not allocate struct cmdts'\n",
+			of_node_full_name(np));
+		goto cmdtsfail;
+	}
+
+	entry = of_parse_phandle(timings_np, "native-mode", 0);
+	/* assume first child as native mode if none provided */
+	if (!entry)
+		entry = of_get_next_child(np, NULL);
+	/* if there is no child, it is useless to go on */
+	if (!entry) {
+		pr_err("%s: no timing specifications given\n",
+			of_node_full_name(np));
+		goto entryfail;
+	}
+
+	pr_debug("%s: using %s as default timing\n",
+		of_node_full_name(np), entry->name);
+
+	native_mode = entry;
+
+	cmdts->num_timings = of_get_child_count(timings_np);
+	if (cmdts->num_timings == 0) {
+		/* should never happen, as entry was already found above */
+		pr_err("%s: no timings specified\n", of_node_full_name(np));
+		goto entryfail;
+	}
+
+	cmdts->timings = kzalloc(sizeof(struct cmdmode_display_timing *) *
+				cmdts->num_timings, GFP_KERNEL);
+	if (!cmdts->timings) {
+		pr_err("%s: could not allocate timings array\n",
+			of_node_full_name(np));
+		goto entryfail;
+	}
+
+	cmdts->num_timings = 0;
+	cmdts->native_mode = 0;
+
+	for_each_child_of_node(timings_np, entry) {
+		struct cmdmode_display_timing *cmdt;
+		int r;
+
+		cmdt = kzalloc(sizeof(*cmdt), GFP_KERNEL);
+		if (!cmdt) {
+			pr_err("%s: could not allocate cmdmode_display_timing\n"
+				, of_node_full_name(np));
+			goto timingfail;
+		}
+
+		r = of_parse_cmdmode_display_timing(entry, cmdt);
+		if (r) {
+			/*
+			 * to not encourage wrong devicetrees, fail in case of
+			 * an error
+			 */
+			pr_err("%s: error in timing %d\n",
+				of_node_full_name(np), cmdts->num_timings + 1);
+			goto timingfail;
+		}
+
+		if (native_mode == entry)
+			cmdts->native_mode = cmdts->num_timings;
+
+		cmdts->timings[cmdts->num_timings] = cmdt;
+		cmdts->num_timings++;
+	}
+	of_node_put(timings_np);
+	/*
+	 * native_mode points to the device_node returned by of_parse_phandle
+	 * therefore call of_node_put on it
+	 */
+	of_node_put(native_mode);
+
+	pr_debug("%s: got %d timings. Using timing #%d as default\n",
+		of_node_full_name(np), cmdts->num_timings,
+		cmdts->native_mode + 1);
+
+	return cmdts;
+
+timingfail:
+	if (native_mode)
+		of_node_put(native_mode);
+	cmdmode_display_timings_release(cmdts);
+entryfail:
+	kfree(cmdts);
+cmdtsfail:
+	of_node_put(timings_np);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(of_get_cmdmode_display_timings);
+
+/**
+ * of_cmdmode_display_timings_exist - check if a display-timings node is
+ * provided
+ * @np: device_node with the timing
+ **/
+int of_cmdmode_display_timings_exist(struct device_node *np)
+{
+	struct device_node *timings_np;
+
+	if (!np)
+		return -EINVAL;
+
+	timings_np = of_parse_phandle(np, "cmdmode-display-timings", 0);
+	if (!timings_np)
+		return -EINVAL;
+
+	of_node_put(timings_np);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(of_cmdmode_display_timings_exist);
diff --git a/include/video/cmdmode.h b/include/video/cmdmode.h
new file mode 100644
index 0000000..61ee71e
--- /dev/null
+++ b/include/video/cmdmode.h
@@ -0,0 +1,67 @@
+/*
+ * generic cmdmode description
+ *
+ * Copyright 2014 YoungJun Cho <yj44.cho@samsung.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 __LINUX_CMDMODE_H
+#define __LINUX_CMDMODE_H
+
+#include <linux/types.h>
+#include <video/cmdmode_display_timing.h>
+
+/*
+ * Subsystem independent description of a cmdmode.
+ * Can be generated from struct cmdmode_display_timing.
+ * @pixelclock: display clock in Hz
+ * @hactive: horizontal active video
+ * @vactive: vertical active video
+ * @cs_setup: clock cycles for the active period of address signal is enabled
+ *		until chip select is enabled
+ * @wr_setup: clock cycles for the active period of CS signal is enabled until
+ *		write signal is enabled
+ * @wr_active: clock cycles for the active period of CS is enabled
+ * @wr_hold: clock cycles for the active period of CS is disabled until write
+ *		signal is disabled
+ */
+struct cmdmode {
+	unsigned long pixelclock;
+
+	u32 hactive;
+	u32 vactive;
+
+	u32 cs_setup;
+	u32 wr_setup;
+	u32 wr_active;
+	u32 wr_hold;
+};
+
+/**
+ * cmdmode_from_timing - convert display timing to cmdmode
+ * @cmdt: cmdmode_display_timing structure
+ * @cm: return value
+ *
+ * DESCRIPTION:
+ * This function converts a struct cmdmode_display_timing to a struct cmdmode.
+ */
+void cmdmode_from_timing(const struct cmdmode_display_timing *cmdt,
+				struct cmdmode *cm);
+
+/**
+ * cmdmode_from_timings - convert one display timings entry to cmdmode
+ * @disp: structure with all possible timing entries
+ * @cm: return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * DESCRIPTION:
+ * This function converts one struct cmdmode_display_timing entry to a
+ * struct cmdmode.
+ */
+int cmdmode_from_timings(const struct cmdmode_display_timings *cmdts,
+				struct cmdmode *cm, unsigned int index);
+
+#endif /* __LINUX_CMDMODE_H */
diff --git a/include/video/cmdmode_display_timing.h b/include/video/cmdmode_display_timing.h
new file mode 100644
index 0000000..5005660
--- /dev/null
+++ b/include/video/cmdmode_display_timing.h
@@ -0,0 +1,59 @@
+/*
+ * description of cmdmode display timings
+ *
+ * Copyright 2014 YoungJun Cho <yj44.cho@samsung.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 __LINUX_CMDMODE_DISPLAY_TIMING_H
+#define __LINUX_CMDMODE_DISPLAY_TIMING_H
+
+#include <linux/types.h>
+
+/*
+ * Single "mode" entry. This describes one set of signal timings a display can
+ * have in one setting. This struct can later be converted to struct cmdmode
+ * (see include/video/cmdmode.h).
+ */
+struct cmdmode_display_timing {
+	u32	pixelclock;
+
+	u32	hactive;
+	u32	vactive;
+
+	u32	cs_setup;
+	u32	wr_setup;
+	u32	wr_active;
+	u32	wr_hold;
+};
+
+/*
+ * This describes all timing settings a display provides.
+ * The native_mode is the default setting for this display.
+ * Drivers that can handle multiple cmdmodes should work with this struct
+ * and convert each entry to the desired end result.
+ */
+struct cmdmode_display_timings {
+	unsigned int num_timings;
+	unsigned int native_mode;
+
+	struct cmdmode_display_timing **timings;
+};
+
+/* get one entry from struct cmdmode_display_timings */
+static inline struct cmdmode_display_timing*
+cmdmode_display_timings_get(const struct cmdmode_display_timings *cmdts,
+				unsigned int index)
+{
+	if (cmdts->num_timings > index)
+		return cmdts->timings[index];
+	else
+		return NULL;
+}
+
+void cmdmode_display_timings_release(struct cmdmode_display_timings *cmdts);
+
+#endif /* __LINUX_CMDDMODE_DISPLAY_TIMING_H */
diff --git a/include/video/of_cmdmode.h b/include/video/of_cmdmode.h
new file mode 100644
index 0000000..fb7c6c7
--- /dev/null
+++ b/include/video/of_cmdmode.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2014 YoungJun Cho <yj44.cho@samsung.com>
+ *
+ * cmdmode of-helpers
+ *
+ * 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 __LINUX_OF_CMDMODE_H
+#define __LINUX_OF_CMDMODE_H
+
+struct device_node;
+struct cmdmode;
+
+int of_get_cmdmode(struct device_node *np, struct cmdmode *cm, int index);
+
+#endif /* __LINUX_OF_CMDMODE_H */
diff --git a/include/video/of_cmdmode_display_timing.h b/include/video/of_cmdmode_display_timing.h
new file mode 100644
index 0000000..6be91ba
--- /dev/null
+++ b/include/video/of_cmdmode_display_timing.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014 YoungJun Cho <yj44.cho@samsung.com>
+ *
+ * cmdmode display timings of helpers
+ *
+ * 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 __LINUX_OF_CMDMODE_DISPLAY_TIMING_H
+#define __LINUX_OF_CMDMODE_DISPLAY_TIMING_H
+
+struct device_node;
+struct cmdmode_display_timing;
+struct cmdmode_display_timings;
+
+#define OF_USE_CMDMODE_NATIVE_MODE -1
+
+int of_get_cmdmode_display_timing(struct device_node *np, const char *name,
+					struct cmdmode_display_timing *cmdt);
+struct cmdmode_display_timings*
+	of_get_cmdmode_display_timings(struct device_node *np);
+int of_cmdmode_display_timings_exist(struct device_node *np);
+
+#endif /* __LINUX_OF_CMDMODE_DISPLAY_TIMING_H */
-- 
1.7.9.5

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

* [PATCH v2 05/18] drm_modes: add command mode helpers
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (2 preceding siblings ...)
  2014-05-21  4:42 ` [PATCH v2 04/18] video: add command mode and command mode display timing YoungJun Cho
@ 2014-05-21  4:42 ` YoungJun Cho
  2014-05-21  4:42 ` [PATCH v2 06/18] ARM: dts: sysreg: add exynos5 compatible to DT bindings YoungJun Cho
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:42 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

This patch adds helper functions to convert cmdmode
to drm_display_mode

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/drm_modes.c |   59 +++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_modes.h     |   12 +++++++++
 2 files changed, 71 insertions(+)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index bedf189..8977381 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -37,6 +37,8 @@
 #include <drm/drm_crtc.h>
 #include <video/of_videomode.h>
 #include <video/videomode.h>
+#include <video/of_cmdmode.h>
+#include <video/cmdmode.h>
 #include <drm/drm_modes.h>
 
 #include "drm_crtc_internal.h"
@@ -651,6 +653,63 @@ EXPORT_SYMBOL_GPL(of_get_drm_display_mode);
 #endif /* CONFIG_OF */
 #endif /* CONFIG_VIDEOMODE_HELPERS */
 
+#ifdef CONFIG_CMDMODE_HELPERS
+int drm_display_mode_from_cmdmode(const struct cmdmode *cm,
+				    struct drm_display_mode *dmode)
+{
+	dmode->hdisplay = cm->hactive;
+	dmode->htotal = dmode->hsync_end = dmode->hsync_start = dmode->hdisplay;
+
+	dmode->vdisplay = cm->vactive;
+	dmode->vtotal = dmode->vsync_end = dmode->vsync_start = dmode->vdisplay;
+
+	dmode->clock = cm->pixelclock / 1000;
+
+	dmode->cs_setup = cm->cs_setup;
+	dmode->wr_setup = cm->wr_setup;
+	dmode->wr_active = cm->wr_active;
+	dmode->wr_hold = cm->wr_hold;
+
+	dmode->flags = 0;
+	drm_mode_set_name(dmode);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(drm_display_mode_from_cmdmode);
+
+#ifdef CONFIG_OF
+/**
+ * of_get_drm_cmdmode_display_mode - get a drm_display_mode from devicetree
+ * @np: device_node with the timing specification
+ * @dmode: will be set to the return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * This function is expensive and should only be used, if only one mode is to be
+ * read from DT. To get multiple modes start with
+ * of_get_cmdmode_display_timings and work with that instead.
+ */
+int of_get_drm_cmdmode_display_mode(struct device_node *np,
+				    struct drm_display_mode *dmode, int index)
+{
+	struct cmdmode cm;
+	int ret;
+
+	ret = of_get_cmdmode(np, &cm, index);
+	if (ret)
+		return ret;
+
+	drm_display_mode_from_cmdmode(&cm, dmode);
+
+	pr_debug("%s: got %dx%d display mode from %s\n",
+		of_node_full_name(np), cm.hactive, cm.vactive, np->name);
+	drm_mode_debug_printmodeline(dmode);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_drm_cmdmode_display_mode);
+#endif /* CONFIG_OF */
+#endif /* CONFIG_CMDMODE_HELPERS */
+
 /**
  * drm_mode_set_name - set the name on a mode
  * @mode: name will be set in this mode
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index 91d0582..0d29754 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -144,6 +144,12 @@ struct drm_display_mode {
 	int vrefresh;		/* in Hz */
 	int hsync;		/* in kHz */
 	enum hdmi_picture_aspect picture_aspect_ratio;
+
+	/* Command mode info - refers to video/cmdmode.h */
+	int cs_setup;
+	int wr_setup;
+	int wr_active;
+	int wr_hold;
 };
 
 /* mode specified on the command line */
@@ -176,6 +182,7 @@ static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode)
 
 struct drm_connector;
 struct drm_cmdline_mode;
+struct cmdmode;
 
 struct drm_display_mode *drm_mode_create(struct drm_device *dev);
 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
@@ -200,6 +207,11 @@ void drm_display_mode_from_videomode(const struct videomode *vm,
 int of_get_drm_display_mode(struct device_node *np,
 			    struct drm_display_mode *dmode,
 			    int index);
+extern int drm_display_mode_from_cmdmode(const struct cmdmode *cm,
+					   struct drm_display_mode *dmode);
+extern int of_get_drm_cmdmode_display_mode(struct device_node *np,
+					   struct drm_display_mode *dmode,
+					   int index);
 
 void drm_mode_set_name(struct drm_display_mode *mode);
 int drm_mode_hsync(const struct drm_display_mode *mode);
-- 
1.7.9.5

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

* [PATCH v2 06/18] ARM: dts: sysreg: add exynos5 compatible to DT bindings
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (3 preceding siblings ...)
  2014-05-21  4:42 ` [PATCH v2 05/18] drm_modes: add command mode helpers YoungJun Cho
@ 2014-05-21  4:42 ` YoungJun Cho
  2014-05-21  4:42 ` [PATCH v2 07/18] ARM: dts: samsung-fimd: add I80 specific properties YoungJun Cho
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:42 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

This patch adds relevant to exynos5 compatible for exynos5 SoCs.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 .../devicetree/bindings/arm/samsung/sysreg.txt     |    1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
index 0ab3251..fd71581 100644
--- a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
@@ -3,6 +3,7 @@ SAMSUNG S5P/Exynos SoC series System Registers (SYSREG)
 Properties:
  - compatible : should contain "samsung,<chip name>-sysreg", "syscon";
    For Exynos4 SoC series it should be "samsung,exynos4-sysreg", "syscon";
+   For Exynos5 SoC series it should be "samsung,exynos5-sysreg", "syscon";
  - reg : offset and length of the register set.
 
 Example:
-- 
1.7.9.5

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

* [PATCH v2 07/18] ARM: dts: samsung-fimd: add I80 specific properties
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (4 preceding siblings ...)
  2014-05-21  4:42 ` [PATCH v2 06/18] ARM: dts: sysreg: add exynos5 compatible to DT bindings YoungJun Cho
@ 2014-05-21  4:42 ` YoungJun Cho
       [not found] ` <1400647390-26590-1-git-send-email-yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:42 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

In case of using MIPI command mode interface panel,
the relevant registers should be set.
So this patch adds relevant DT bindings.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 .../devicetree/bindings/video/samsung-fimd.txt     |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/video/samsung-fimd.txt b/Documentation/devicetree/bindings/video/samsung-fimd.txt
index 2dad41b..6bf93e9 100644
--- a/Documentation/devicetree/bindings/video/samsung-fimd.txt
+++ b/Documentation/devicetree/bindings/video/samsung-fimd.txt
@@ -44,6 +44,8 @@ Optional Properties:
 - display-timings: timing settings for FIMD, as described in document [1].
 		Can be used in case timings cannot be provided otherwise
 		or to override timings provided by the panel.
+- samsung,sysreg: handle to syscon used to control the system registers
+- vidout-i80-ldi: boolean to support i80 interface instead of rgb one
 
 The device node can contain 'port' child nodes according to the bindings defined
 in [2]. The following are properties specific to those nodes:
-- 
1.7.9.5

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

* [PATCH v2 08/18] drm/exynos: add TE handler to support MIPI DSI command mode interface
       [not found] ` <1400647390-26590-1-git-send-email-yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2014-05-21  4:42   ` [PATCH v2 03/18] ARM: dts: video: add command mode display timing DT bindings YoungJun Cho
@ 2014-05-21  4:43   ` YoungJun Cho
  2014-05-21  4:43   ` [PATCH v2 15/18] ARM: dts: exynos4: add system register node YoungJun Cho
  2014-05-21  4:43   ` [PATCH v2 16/18] ARM: dts: exynos5: add system register support YoungJun Cho
  3 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied-cv59FeDIM0c, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw,
	s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ,
	djkurtz-F7+t8E8rja9g9hUCZPvPmw,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	inki.dae-Sze3O3UU22JBDgjK7y7TUQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	a.hajda-Sze3O3UU22JBDgjK7y7TUQ

To support MIPI DSI command mode interface, the panel should generates
Tearing Effect synchronization signal between MCU and FB to display
video images.
And the display controller should trigger to transfer video image at
this signal.
So the panel receives the TE IRQ, then calls this handler chains
to notify it to the display controller.

Signed-off-by: YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Inki Dae <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c |   11 +++++++++++
 drivers/gpu/drm/exynos/exynos_drm_crtc.h |    7 +++++++
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |    3 +++
 include/drm/drm_mipi_dsi.h               |    8 ++++++++
 4 files changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 3bf091d..504e023 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -511,3 +511,14 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
 
 	return -EPERM;
 }
+
+int exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
+{
+	struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
+	int ret = 0;
+
+	if (manager->ops->te_handler)
+		ret = manager->ops->te_handler(manager);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index 9f74b10..875d93d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -36,4 +36,11 @@ void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos);
 int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
 					unsigned int out_type);
 
+/*
+ * This function calls the crtc device(manager)'s te_handler() callback
+ * to trigger to transfer video image at the tearing effect synchronization
+ * signal.
+ */
+int exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
+
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index e82e620..54b08d7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -181,6 +181,8 @@ struct exynos_drm_display {
  * @win_commit: apply hardware specific overlay data to registers.
  * @win_enable: enable hardware specific overlay.
  * @win_disable: disable hardware specific overlay.
+ * @te_handler: trigger to transfer video image at the tearing effect
+ *	synchronization signal if there is a page flip request.
  */
 struct exynos_drm_manager;
 struct exynos_drm_manager_ops {
@@ -199,6 +201,7 @@ struct exynos_drm_manager_ops {
 	void (*win_commit)(struct exynos_drm_manager *mgr, int zpos);
 	void (*win_enable)(struct exynos_drm_manager *mgr, int zpos);
 	void (*win_disable)(struct exynos_drm_manager *mgr, int zpos);
+	int (*te_handler)(struct exynos_drm_manager *mgr);
 };
 
 /*
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 7209df1..f6d4c85 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -49,6 +49,13 @@ struct mipi_dsi_msg {
  * @detach: detach DSI device from DSI host
  * @transfer: send and/or receive DSI packet, return number of received bytes,
  * 	      or error
+ * @te_handler: call the crtc te_handler() callback from DSI host.
+ *		The panel generates tearing effect synchronization signal
+ *		between MCU and FB to display video images.
+ *		And the display controller should trigger to transfer video
+ *		image at this signal.
+ *		So the panel receives the TE IRQ, then calls this handler
+ *		to notify it to the display controller.
  */
 struct mipi_dsi_host_ops {
 	int (*attach)(struct mipi_dsi_host *host,
@@ -57,6 +64,7 @@ struct mipi_dsi_host_ops {
 		      struct mipi_dsi_device *dsi);
 	ssize_t (*transfer)(struct mipi_dsi_host *host,
 			    struct mipi_dsi_msg *msg);
+	int (*te_handler)(struct mipi_dsi_host *host);
 };
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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 related	[flat|nested] 39+ messages in thread

* [PATCH v2 09/18] drm/exynos: dsi: add TE handler to support command mode interface
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (6 preceding siblings ...)
       [not found] ` <1400647390-26590-1-git-send-email-yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2014-05-21  4:43 ` YoungJun Cho
  2014-05-21  4:43 ` [PATCH v2 10/18] drm/exynos: fimd: support I80 interface YoungJun Cho
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

To support command mode interface, the DSI host calls this handler
to notify the panel tearing effect synchronization signal to the
CRTC device manager to trigger to transfer video image.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0a4e3ce..783d7a5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -24,6 +24,7 @@
 #include <video/mipi_display.h>
 #include <video/videomode.h>
 
+#include "exynos_drm_crtc.h"
 #include "exynos_drm_drv.h"
 
 /* returns true iff both arguments logically differs */
@@ -1033,10 +1034,22 @@ static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
 	return (ret < 0) ? ret : xfer.rx_done;
 }
 
+static int exynos_dsi_host_te_handler(struct mipi_dsi_host *host)
+{
+	struct exynos_dsi *dsi = host_to_dsi(host);
+	struct drm_encoder *encoder = dsi->encoder;
+
+	if (!(dsi->state & DSIM_STATE_ENABLED))
+		return -EPERM;
+
+	return exynos_drm_crtc_te_handler(encoder->crtc);
+}
+
 static const struct mipi_dsi_host_ops exynos_dsi_ops = {
 	.attach = exynos_dsi_host_attach,
 	.detach = exynos_dsi_host_detach,
 	.transfer = exynos_dsi_host_transfer,
+	.te_handler = exynos_dsi_host_te_handler,
 };
 
 static int exynos_dsi_poweron(struct exynos_dsi *dsi)
-- 
1.7.9.5

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

* [PATCH v2 10/18] drm/exynos: fimd: support I80 interface
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (7 preceding siblings ...)
  2014-05-21  4:43 ` [PATCH v2 09/18] drm/exynos: dsi: add TE handler to support command mode interface YoungJun Cho
@ 2014-05-21  4:43 ` YoungJun Cho
  2014-05-26  9:00   ` Daniel Kurtz
  2014-05-21  4:43 ` [PATCH v2 11/18] ARM: dts: exynos_dsim: add exynos5420 compatible to DT bindings YoungJun Cho
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

To support MIPI DSI command mode interface, FIMD should do followings:
- Sets LCD block configuration for I80 interface.
- Uses "lcd_sys" as an IRQ resource and sets relevant IRQ configuration.
- Implements trigger feature which transfers image date if there is
  page flip request, and implements TE handler to call trigger function.
- Sets command mode timings configuration.
- Sets ideal(pixel) clock is 2 times faster than the original one to
  generate frame done IRQ prior to the next TE signal.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/exynos/Kconfig           |    1 +
 drivers/gpu/drm/exynos/exynos_drm_fimd.c |  277 +++++++++++++++++++++++++-----
 include/video/samsung_fimd.h             |    3 +-
 3 files changed, 237 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 5bf5bca..f4d34f0 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -28,6 +28,7 @@ config DRM_EXYNOS_FIMD
 	bool "Exynos DRM FIMD"
 	depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM
 	select FB_MODE_HELPERS
+	select MFD_SYSCON
 	help
 	  Choose this option if you want to use Exynos FIMD for DRM.
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 173ee97..9d585f9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -20,11 +20,14 @@
 #include <linux/of_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <video/of_display_timing.h>
 #include <video/of_videomode.h>
 #include <video/samsung_fimd.h>
 #include <drm/exynos_drm.h>
+#include <drm/drm_panel.h>
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fbdev.h"
@@ -60,6 +63,24 @@
 /* color key value register for hardware window 1 ~ 4. */
 #define WKEYCON1_BASE(x)		((WKEYCON1 + 0x140) + ((x - 1) * 8))
 
+/* i80 / RGB trigger control register */
+#define TRIGCON				0x1A4
+#define TRGMODE_I80_RGB_ENABLE_I80	(1 << 0)
+#define SWTRGCMD_I80_RGB_ENABLE		(1 << 1)
+
+/* display mode change control register except exynos4 */
+#define VIDOUT_CON			0x000
+#define VIDOUT_CON_F_I80_LDI0		(0x2 << 8)
+
+/* i80 interface control for main LDI register */
+#define I80IFCONFAx(x)			(0x1B0 + (x) * 4)
+#define I80IFCONFBx(x)			(0x1B8 + (x) * 4)
+#define LCD_CS_SETUP(x)			((x) << 16)
+#define LCD_WR_SETUP(x)			((x) << 12)
+#define LCD_WR_ACT(x)			((x) << 8)
+#define LCD_WR_HOLD(x)			((x) << 4)
+#define I80IFEN_ENABLE			(1 << 0)
+
 /* FIMD has totally five hardware windows. */
 #define WINDOWS_NR	5
 
@@ -67,10 +88,14 @@
 
 struct fimd_driver_data {
 	unsigned int timing_base;
+	unsigned int lcdblk_off;
+	unsigned int lcdblk_vt_shift;
+	unsigned int lcdblk_bypass_shift;
 
 	unsigned int has_shadowcon:1;
 	unsigned int has_clksel:1;
 	unsigned int has_limited_fmt:1;
+	unsigned int has_vidoutcon:1;
 };
 
 static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -81,12 +106,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
 
 static struct fimd_driver_data exynos4_fimd_driver_data = {
 	.timing_base = 0x0,
+	.lcdblk_off = 0x210,
+	.lcdblk_vt_shift = 10,
+	.lcdblk_bypass_shift = 1,
 	.has_shadowcon = 1,
 };
 
 static struct fimd_driver_data exynos5_fimd_driver_data = {
 	.timing_base = 0x20000,
+	.lcdblk_off = 0x214,
+	.lcdblk_vt_shift = 24,
+	.lcdblk_bypass_shift = 15,
 	.has_shadowcon = 1,
+	.has_vidoutcon = 1,
 };
 
 struct fimd_win_data {
@@ -111,15 +143,23 @@ struct fimd_context {
 	struct clk			*bus_clk;
 	struct clk			*lcd_clk;
 	void __iomem			*regs;
+	struct regmap			*sysreg;
 	struct drm_display_mode		mode;
 	struct fimd_win_data		win_data[WINDOWS_NR];
 	unsigned int			default_win;
 	unsigned long			irq_flags;
+	u32				vidcon0;
 	u32				vidcon1;
+	u32				vidout_con;
+	u32				i80ifcon;
+	bool				i80_if;
 	bool				suspended;
 	int				pipe;
 	wait_queue_head_t		wait_vsync_queue;
 	atomic_t			wait_vsync_event;
+	atomic_t			win_updated;
+	atomic_t			triggering;
+	spinlock_t			win_updated_lock;
 
 	struct exynos_drm_panel_info panel;
 	struct fimd_driver_data *driver_data;
@@ -242,6 +282,14 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
 	unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
 	u32 clkdiv;
 
+	if (ctx->i80_if) {
+		/*
+		 * The frame done interrupt should be occurred prior to the
+		 * next TE signal.
+		 */
+		ideal_clk *= 2;
+	}
+
 	/* Find the clock divider value that gets us closest to ideal_clk */
 	clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->lcd_clk), ideal_clk);
 
@@ -264,17 +312,23 @@ static void fimd_mode_set(struct exynos_drm_manager *mgr,
 	struct fimd_context *ctx = mgr->ctx;
 
 	drm_mode_copy(&ctx->mode, in_mode);
+
+	if (ctx->i80_if) {
+		ctx->i80ifcon = LCD_CS_SETUP(in_mode->cs_setup);
+		ctx->i80ifcon |= LCD_WR_SETUP(in_mode->wr_setup);
+		ctx->i80ifcon |= LCD_WR_ACT(in_mode->wr_active);
+		ctx->i80ifcon |= LCD_WR_HOLD(in_mode->wr_hold);
+	}
 }
 
 static void fimd_commit(struct exynos_drm_manager *mgr)
 {
 	struct fimd_context *ctx = mgr->ctx;
 	struct drm_display_mode *mode = &ctx->mode;
-	struct fimd_driver_data *driver_data;
-	u32 val, clkdiv, vidcon1;
-	int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
+	struct fimd_driver_data *driver_data = ctx->driver_data;
+	void *timing_base = ctx->regs + driver_data->timing_base;
+	u32 val, clkdiv;
 
-	driver_data = ctx->driver_data;
 	if (ctx->suspended)
 		return;
 
@@ -282,33 +336,65 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
 	if (mode->htotal == 0 || mode->vtotal == 0)
 		return;
 
-	/* setup polarity values */
-	vidcon1 = ctx->vidcon1;
-	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
-		vidcon1 |= VIDCON1_INV_VSYNC;
-	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
-		vidcon1 |= VIDCON1_INV_HSYNC;
-	writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
-
-	/* setup vertical timing values. */
-	vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
-	vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
-	vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
-
-	val = VIDTCON0_VBPD(vbpd - 1) |
-		VIDTCON0_VFPD(vfpd - 1) |
-		VIDTCON0_VSPW(vsync_len - 1);
-	writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
-
-	/* setup horizontal timing values.  */
-	hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
-	hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
-	hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
-
-	val = VIDTCON1_HBPD(hbpd - 1) |
-		VIDTCON1_HFPD(hfpd - 1) |
-		VIDTCON1_HSPW(hsync_len - 1);
-	writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
+	if (ctx->i80_if) {
+		val = ctx->i80ifcon | I80IFEN_ENABLE;
+		writel(val, timing_base + I80IFCONFAx(0));
+
+		/* disable auto frame rate */
+		writel(0, timing_base + I80IFCONFBx(0));
+
+		if (ctx->vidout_con)
+			writel(ctx->vidout_con, timing_base + VIDOUT_CON);
+
+		/* set video type selection to i80 interface */
+		if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
+					driver_data->lcdblk_off,
+					0x3 << driver_data->lcdblk_vt_shift,
+					0x1 << driver_data->lcdblk_vt_shift)) {
+			DRM_ERROR("Failed to update sysreg for i80 i/f.\n");
+			return;
+		}
+	} else {
+		int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
+		u32 vidcon1;
+
+		/* setup polarity values */
+		vidcon1 = ctx->vidcon1;
+		if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+			vidcon1 |= VIDCON1_INV_VSYNC;
+		if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+			vidcon1 |= VIDCON1_INV_HSYNC;
+		writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
+
+		/* setup vertical timing values. */
+		vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
+		vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
+		vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
+
+		val = VIDTCON0_VBPD(vbpd - 1) |
+			VIDTCON0_VFPD(vfpd - 1) |
+			VIDTCON0_VSPW(vsync_len - 1);
+		writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
+
+		/* setup horizontal timing values.  */
+		hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+		hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
+		hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
+
+		val = VIDTCON1_HBPD(hbpd - 1) |
+			VIDTCON1_HFPD(hfpd - 1) |
+			VIDTCON1_HSPW(hsync_len - 1);
+		writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
+	}
+
+	/* set bypass selection */
+	if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
+				driver_data->lcdblk_off,
+				0x1 << driver_data->lcdblk_bypass_shift,
+				0x1 << driver_data->lcdblk_bypass_shift)) {
+		DRM_ERROR("Failed to update sysreg for bypass setting.\n");
+		return;
+	}
 
 	/* setup horizontal and vertical display size. */
 	val = VIDTCON2_LINEVAL(mode->vdisplay - 1) |
@@ -646,6 +732,14 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
 	}
 
 	win_data->enabled = true;
+
+	if (ctx->i80_if) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&ctx->win_updated_lock, flags);
+		atomic_set(&ctx->win_updated, 1);
+		spin_unlock_irqrestore(&ctx->win_updated_lock, flags);
+	}
 }
 
 static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
@@ -835,6 +929,68 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
 	}
 }
 
+static void fimd_trigger(struct device *dev)
+{
+	struct exynos_drm_manager *mgr = get_fimd_manager(dev);
+	struct fimd_context *ctx = mgr->ctx;
+	struct fimd_driver_data *driver_data = ctx->driver_data;
+	void *timing_base = ctx->regs + driver_data->timing_base;
+	u32 reg;
+
+	atomic_set(&ctx->triggering, 1);
+
+	reg = readl(ctx->regs + VIDINTCON0);
+	reg |= (VIDINTCON0_INT_ENABLE | VIDINTCON0_INT_I80IFDONE |
+						VIDINTCON0_INT_SYSMAINCON);
+	writel(reg, ctx->regs + VIDINTCON0);
+
+	reg = readl(timing_base + TRIGCON);
+	reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE);
+	writel(reg, timing_base + TRIGCON);
+}
+
+static int fimd_te_handler(struct exynos_drm_manager *mgr)
+{
+	struct fimd_context *ctx = mgr->ctx;
+	unsigned long flags;
+
+	/* check the crtc is detached already from encoder */
+	if (ctx->pipe < 0 || !ctx->drm_dev)
+		return -EINVAL;
+
+	 /*
+	 * Skips to trigger if in triggering state, because multiple triggering
+	 * requests can cause panel reset.
+	 */
+	if (atomic_read(&ctx->triggering))
+		return 0;
+
+	spin_lock_irqsave(&ctx->win_updated_lock, flags);
+
+	/*
+	 * If there is a page flip request, triggers and handles the page flip
+	 * event so that current fb can be updated into panel GRAM.
+	 */
+	if (atomic_read(&ctx->win_updated)) {
+		atomic_set(&ctx->win_updated, 0);
+
+		fimd_trigger(ctx->dev);
+	}
+
+	spin_unlock_irqrestore(&ctx->win_updated_lock, flags);
+
+	/* wake up vsync event queue */
+	if (atomic_read(&ctx->wait_vsync_event)) {
+		atomic_set(&ctx->wait_vsync_event, 0);
+		wake_up(&ctx->wait_vsync_queue);
+
+		if (!atomic_read(&ctx->triggering))
+			drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+	}
+
+	return 0;
+}
+
 static struct exynos_drm_manager_ops fimd_manager_ops = {
 	.dpms = fimd_dpms,
 	.mode_fixup = fimd_mode_fixup,
@@ -846,6 +1002,7 @@ static struct exynos_drm_manager_ops fimd_manager_ops = {
 	.win_mode_set = fimd_win_mode_set,
 	.win_commit = fimd_win_commit,
 	.win_disable = fimd_win_disable,
+	.te_handler = fimd_te_handler,
 };
 
 static struct exynos_drm_manager fimd_manager = {
@@ -856,26 +1013,40 @@ static struct exynos_drm_manager fimd_manager = {
 static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
 {
 	struct fimd_context *ctx = (struct fimd_context *)dev_id;
-	u32 val;
+	u32 val, clear_bit;
 
 	val = readl(ctx->regs + VIDINTCON1);
 
-	if (val & VIDINTCON1_INT_FRAME)
-		/* VSYNC interrupt */
-		writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1);
+	clear_bit = ctx->i80_if ? VIDINTCON1_INT_I80 : VIDINTCON1_INT_FRAME;
+	if (val & clear_bit)
+		writel(clear_bit, ctx->regs + VIDINTCON1);
 
 	/* check the crtc is detached already from encoder */
 	if (ctx->pipe < 0 || !ctx->drm_dev)
 		goto out;
 
-	drm_handle_vblank(ctx->drm_dev, ctx->pipe);
-	exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+	if (ctx->i80_if) {
+		/* unset i80 frame done interrupt */
+		val = readl(ctx->regs + VIDINTCON0);
+		val &= ~(VIDINTCON0_INT_I80IFDONE | VIDINTCON0_INT_SYSMAINCON);
+		writel(val, ctx->regs + VIDINTCON0);
 
-	/* set wait vsync event to zero and wake up queue. */
-	if (atomic_read(&ctx->wait_vsync_event)) {
-		atomic_set(&ctx->wait_vsync_event, 0);
-		wake_up(&ctx->wait_vsync_queue);
+		/* exit triggering mode */
+		atomic_set(&ctx->triggering, 0);
+
+		drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+		exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+	} else {
+		drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+		exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+
+		/* set wait vsync event to zero and wake up queue. */
+		if (atomic_read(&ctx->wait_vsync_event)) {
+			atomic_set(&ctx->wait_vsync_event, 0);
+			wake_up(&ctx->wait_vsync_queue);
+		}
 	}
+
 out:
 	return IRQ_HANDLED;
 }
@@ -936,12 +1107,32 @@ static int fimd_probe(struct platform_device *pdev)
 
 	ctx->dev = dev;
 	ctx->suspended = true;
+	ctx->driver_data = drm_fimd_get_driver_data(pdev);
 
 	if (of_property_read_bool(dev->of_node, "samsung,invert-vden"))
 		ctx->vidcon1 |= VIDCON1_INV_VDEN;
 	if (of_property_read_bool(dev->of_node, "samsung,invert-vclk"))
 		ctx->vidcon1 |= VIDCON1_INV_VCLK;
 
+	if (of_property_read_bool(dev->of_node, "vidout-i80-ldi")) {
+		ctx->i80_if = true;
+
+		if (ctx->driver_data->has_vidoutcon)
+			ctx->vidout_con |= VIDOUT_CON_F_I80_LDI0;
+		else
+			ctx->vidcon0 |= VIDCON0_VIDOUT_I80_LDI0;
+		ctx->vidcon0 |= VIDCON0_DSI_EN;
+
+		spin_lock_init(&ctx->win_updated_lock);
+	}
+
+	ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+							"samsung,sysreg");
+	if (IS_ERR(ctx->sysreg)) {
+		dev_warn(dev, "failed to get system register.\n");
+		ctx->sysreg = NULL;
+	}
+
 	ctx->bus_clk = devm_clk_get(dev, "fimd");
 	if (IS_ERR(ctx->bus_clk)) {
 		dev_err(dev, "failed to get bus clock\n");
@@ -960,7 +1151,8 @@ static int fimd_probe(struct platform_device *pdev)
 	if (IS_ERR(ctx->regs))
 		return PTR_ERR(ctx->regs);
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync");
+	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+					ctx->i80_if ? "lcd_sys" : "vsync");
 	if (!res) {
 		dev_err(dev, "irq request failed.\n");
 		return -ENXIO;
@@ -973,7 +1165,6 @@ static int fimd_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ctx->driver_data = drm_fimd_get_driver_data(pdev);
 	init_waitqueue_head(&ctx->wait_vsync_queue);
 	atomic_set(&ctx->wait_vsync_event, 0);
 
diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
index b039320..eaad58b 100644
--- a/include/video/samsung_fimd.h
+++ b/include/video/samsung_fimd.h
@@ -19,6 +19,7 @@
 /* VIDCON0 */
 
 #define VIDCON0					0x00
+#define VIDCON0_DSI_EN				(1 << 30)
 #define VIDCON0_INTERLACE			(1 << 29)
 #define VIDCON0_VIDOUT_MASK			(0x7 << 26)
 #define VIDCON0_VIDOUT_SHIFT			26
@@ -355,7 +356,7 @@
 #define VIDINTCON0_INT_ENABLE			(1 << 0)
 
 #define VIDINTCON1				0x134
-#define VIDINTCON1_INT_I180			(1 << 2)
+#define VIDINTCON1_INT_I80			(1 << 2)
 #define VIDINTCON1_INT_FRAME			(1 << 1)
 #define VIDINTCON1_INT_FIFO			(1 << 0)
 
-- 
1.7.9.5

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

* [PATCH v2 11/18] ARM: dts: exynos_dsim: add exynos5420 compatible to DT bindings
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (8 preceding siblings ...)
  2014-05-21  4:43 ` [PATCH v2 10/18] drm/exynos: fimd: support I80 interface YoungJun Cho
@ 2014-05-21  4:43 ` YoungJun Cho
  2014-05-21  4:43 ` [PATCH v2 12/18] drm/exynos: dsi: add driver data to support Exynos5420 YoungJun Cho
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: devicetree, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux-samsung-soc, thierry.reding, laurent.pinchart,
	s.trumtrar, djkurtz, kyungmin.park, inki.dae, kgene.kim,
	jy0922.shim, sw0312.kim, a.hajda

This patch adds relevant to exynos5420 compatible for exynos5420 SoC support.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 .../devicetree/bindings/video/exynos_dsim.txt      |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
index 33b5730..29bf3b2 100644
--- a/Documentation/devicetree/bindings/video/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
@@ -1,7 +1,9 @@
 Exynos MIPI DSI Master
 
 Required properties:
-  - compatible: "samsung,exynos4210-mipi-dsi"
+  - compatible: value should be one of the following
+			"samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
+			"samsung,exynos5420-mipi-dsi" /* for Exynos5420 SoCs */
   - reg: physical base address and length of the registers set for the device
   - interrupts: should contain DSI interrupt
   - clocks: list of clock specifiers, must contain an entry for each required
-- 
1.7.9.5

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

* [PATCH v2 12/18] drm/exynos: dsi: add driver data to support Exynos5420
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (9 preceding siblings ...)
  2014-05-21  4:43 ` [PATCH v2 11/18] ARM: dts: exynos_dsim: add exynos5420 compatible to DT bindings YoungJun Cho
@ 2014-05-21  4:43 ` YoungJun Cho
  2014-05-21  4:43 ` [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings YoungJun Cho
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

The offset of register DSIM_PLLTMR_REG in Exynos5420 is different
from the one in Exynos4 SoC.

In case of Exynos5420 SoC, there is no frequency band bit in DSIM_PLLCTRL_REG,
and it uses DSIM_PHYCTRL_REG and DSIM_PHYTIMING*_REG instead.
So this patch adds driver data to distinguish it.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c |  157 ++++++++++++++++++++++++++-----
 1 file changed, 135 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 783d7a5..35d636b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -17,6 +17,7 @@
 
 #include <linux/clk.h>
 #include <linux/irq.h>
+#include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
@@ -55,9 +56,12 @@
 
 /* FIFO memory AC characteristic register */
 #define DSIM_PLLCTRL_REG	0x4c	/* PLL control register */
-#define DSIM_PLLTMR_REG		0x50	/* PLL timer register */
 #define DSIM_PHYACCHR_REG	0x54	/* D-PHY AC characteristic register */
 #define DSIM_PHYACCHR1_REG	0x58	/* D-PHY AC characteristic register1 */
+#define DSIM_PHYCTRL_REG	0x5c
+#define DSIM_PHYTIMING_REG	0x64
+#define DSIM_PHYTIMING1_REG	0x68
+#define DSIM_PHYTIMING2_REG	0x6c
 
 /* DSIM_STATUS */
 #define DSIM_STOP_STATE_DAT(x)		(((x) & 0xf) << 0)
@@ -201,6 +205,24 @@
 #define DSIM_PLL_M(x)			((x) << 4)
 #define DSIM_PLL_S(x)			((x) << 1)
 
+/* DSIM_PHYCTRL */
+#define DSIM_PHYCTRL_ULPS_EXIT(x)	(((x) & 0x1ff) << 0)
+
+/* DSIM_PHYTIMING */
+#define DSIM_PHYTIMING_LPX(x)		((x) << 8)
+#define DSIM_PHYTIMING_HS_EXIT(x)	((x) << 0)
+
+/* DSIM_PHYTIMING1 */
+#define DSIM_PHYTIMING1_CLK_PREPARE(x)	((x) << 24)
+#define DSIM_PHYTIMING1_CLK_ZERO(x)	((x) << 16)
+#define DSIM_PHYTIMING1_CLK_POST(x)	((x) << 8)
+#define DSIM_PHYTIMING1_CLK_TRAIL(x)	((x) << 0)
+
+/* DSIM_PHYTIMING2 */
+#define DSIM_PHYTIMING2_HS_PREPARE(x)	((x) << 16)
+#define DSIM_PHYTIMING2_HS_ZERO(x)	((x) << 8)
+#define DSIM_PHYTIMING2_HS_TRAIL(x)	((x) << 0)
+
 #define DSI_MAX_BUS_WIDTH		4
 #define DSI_NUM_VIRTUAL_CHANNELS	4
 #define DSI_TX_FIFO_SIZE		2048
@@ -234,6 +256,12 @@ struct exynos_dsi_transfer {
 #define DSIM_STATE_INITIALIZED		BIT(1)
 #define DSIM_STATE_CMD_LPM		BIT(2)
 
+struct exynos_dsi_driver_data {
+	unsigned int plltmr_reg;
+
+	unsigned int has_freqband:1;
+};
+
 struct exynos_dsi {
 	struct mipi_dsi_host dsi_host;
 	struct drm_connector connector;
@@ -263,11 +291,39 @@ struct exynos_dsi {
 
 	spinlock_t transfer_lock; /* protects transfer_list */
 	struct list_head transfer_list;
+
+	struct exynos_dsi_driver_data *driver_data;
 };
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
+static struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
+	.plltmr_reg = 0x50,
+	.has_freqband = 1,
+};
+
+static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
+	.plltmr_reg = 0x58,
+};
+
+static struct of_device_id exynos_dsi_of_match[] = {
+	{ .compatible = "samsung,exynos4210-mipi-dsi",
+	  .data = &exynos4_dsi_driver_data },
+	{ .compatible = "samsung,exynos5420-mipi-dsi",
+	  .data = &exynos5_dsi_driver_data },
+	{ }
+};
+
+static inline struct exynos_dsi_driver_data *exynos_dsi_get_driver_data(
+						struct platform_device *pdev)
+{
+	const struct of_device_id *of_id =
+			of_match_device(exynos_dsi_of_match, &pdev->dev);
+
+	return (struct exynos_dsi_driver_data *)of_id->data;
+}
+
 static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi)
 {
 	if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300)))
@@ -341,14 +397,9 @@ static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi,
 static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
 					unsigned long freq)
 {
-	static const unsigned long freq_bands[] = {
-		100 * MHZ, 120 * MHZ, 160 * MHZ, 200 * MHZ,
-		270 * MHZ, 320 * MHZ, 390 * MHZ, 450 * MHZ,
-		510 * MHZ, 560 * MHZ, 640 * MHZ, 690 * MHZ,
-		770 * MHZ, 870 * MHZ, 950 * MHZ,
-	};
+	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
 	unsigned long fin, fout;
-	int timeout, band;
+	int timeout;
 	u8 p, s;
 	u16 m;
 	u32 reg;
@@ -369,18 +420,30 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
 			"failed to find PLL PMS for requested frequency\n");
 		return -EFAULT;
 	}
+	dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);
 
-	for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)
-		if (fout < freq_bands[band])
-			break;
+	writel(500, dsi->reg_base + driver_data->plltmr_reg);
+
+	reg = DSIM_PLL_EN | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
+
+	if (driver_data->has_freqband) {
+		static const unsigned long freq_bands[] = {
+			100 * MHZ, 120 * MHZ, 160 * MHZ, 200 * MHZ,
+			270 * MHZ, 320 * MHZ, 390 * MHZ, 450 * MHZ,
+			510 * MHZ, 560 * MHZ, 640 * MHZ, 690 * MHZ,
+			770 * MHZ, 870 * MHZ, 950 * MHZ,
+		};
+		int band;
+
+		for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)
+			if (fout < freq_bands[band])
+				break;
 
-	dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d), band %d\n", fout,
-		p, m, s, band);
+		dev_dbg(dsi->dev, "band %d\n", band);
 
-	writel(500, dsi->reg_base + DSIM_PLLTMR_REG);
+		reg |= DSIM_FREQ_BAND(band);
+	}
 
-	reg = DSIM_FREQ_BAND(band) | DSIM_PLL_EN
-			| DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
 	writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG);
 
 	timeout = 1000;
@@ -434,6 +497,59 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
 	return 0;
 }
 
+static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
+{
+	struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
+	u32 reg;
+
+	if (driver_data->has_freqband)
+		return;
+
+	/* B D-PHY: D-PHY Master & Slave Analog Block control */
+	reg = DSIM_PHYCTRL_ULPS_EXIT(0x0af);
+	writel(reg, dsi->reg_base + DSIM_PHYCTRL_REG);
+
+	/*
+	 * T LPX: Transmitted length of any Low-Power state period
+	 * T HS-EXIT: Time that the transmitter drives LP-11 following a HS
+	 *	burst
+	 */
+	reg = DSIM_PHYTIMING_LPX(0x06) | DSIM_PHYTIMING_HS_EXIT(0x0b);
+	writel(reg, dsi->reg_base + DSIM_PHYTIMING_REG);
+
+	/*
+	 * T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00
+	 *	Line state immediately before the HS-0 Line state starting the
+	 *	HS transmission
+	 * T CLK-ZERO: Time that the transmitter drives the HS-0 state prior to
+	 *	transmitting the Clock.
+	 * T CLK_POST: Time that the transmitter continues to send HS clock
+	 *	after the last associated Data Lane has transitioned to LP Mode
+	 *	Interval is defined as the period from the end of T HS-TRAIL to
+	 *	the beginning of T CLK-TRAIL
+	 * T CLK-TRAIL: Time that the transmitter drives the HS-0 state after
+	 *	the last payload clock bit of a HS transmission burst
+	 */
+	reg = DSIM_PHYTIMING1_CLK_PREPARE(0x07) |
+			DSIM_PHYTIMING1_CLK_ZERO(0x27) |
+			DSIM_PHYTIMING1_CLK_POST(0x0d) |
+			DSIM_PHYTIMING1_CLK_TRAIL(0x08);
+	writel(reg, dsi->reg_base + DSIM_PHYTIMING1_REG);
+
+	/*
+	 * T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00
+	 *	Line state immediately before the HS-0 Line state starting the
+	 *	HS transmission
+	 * T HS-ZERO: Time that the transmitter drives the HS-0 state prior to
+	 *	transmitting the Sync sequence.
+	 * T HS-TRAIL: Time that the transmitter drives the flipped differential
+	 *	state after last payload data bit of a HS transmission burst
+	 */
+	reg = DSIM_PHYTIMING2_HS_PREPARE(0x09) | DSIM_PHYTIMING2_HS_ZERO(0x0d) |
+			DSIM_PHYTIMING2_HS_TRAIL(0x0b);
+	writel(reg, dsi->reg_base + DSIM_PHYTIMING2_REG);
+}
+
 static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
 {
 	u32 reg;
@@ -948,10 +1064,11 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 
 static int exynos_dsi_init(struct exynos_dsi *dsi)
 {
-	exynos_dsi_enable_clock(dsi);
 	exynos_dsi_reset(dsi);
 	enable_irq(dsi->irq);
+	exynos_dsi_enable_clock(dsi);
 	exynos_dsi_wait_for_reset(dsi);
+	exynos_dsi_set_phy_ctrl(dsi);
 	exynos_dsi_init_link(dsi);
 
 	return 0;
@@ -1451,6 +1568,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	dsi->dsi_host.dev = &pdev->dev;
 
 	dsi->dev = &pdev->dev;
+	dsi->driver_data = exynos_dsi_get_driver_data(pdev);
 
 	ret = exynos_dsi_parse_dt(dsi);
 	if (ret)
@@ -1518,11 +1636,6 @@ static int exynos_dsi_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct of_device_id exynos_dsi_of_match[] = {
-	{ .compatible = "samsung,exynos4210-mipi-dsi" },
-	{ }
-};
-
 struct platform_driver dsi_driver = {
 	.probe = exynos_dsi_probe,
 	.remove = exynos_dsi_remove,
-- 
1.7.9.5

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

* [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (10 preceding siblings ...)
  2014-05-21  4:43 ` [PATCH v2 12/18] drm/exynos: dsi: add driver data to support Exynos5420 YoungJun Cho
@ 2014-05-21  4:43 ` YoungJun Cho
  2014-05-26 13:41   ` Thierry Reding
  2014-05-21  4:43 ` [PATCH v2 14/18] drm/panel: add S6E3FA0 driver YoungJun Cho
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

This patch adds DT bindings for s6e3fa0 panel.
The bindings describes panel resources, display timings and cpu mode timings.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt

diff --git a/Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt b/Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
new file mode 100644
index 0000000..c9a3fbd
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
@@ -0,0 +1,45 @@
+Samsung S6E3FA0 AMOLED LCD 5.7 inch panel
+
+Required properties:
+  - compatible: "samsung,s6e3fa0"
+  - reg: the virtual channel number of a DSI peripheral
+  - vdd3-supply: core voltage supply
+  - vci-supply: voltage supply for analog circuits
+  - reset-gpios: a GPIO spec for the reset pin
+  - det-gpios: a GPIO spec for the OLED detection pin
+  - te-gpios: a GPIO spec for the TE pin
+  - cmdmode-display-timings: command mode interface timings for the connected
+      panel as described by [1]
+
+Optional properties:
+
+The device node can contain one 'port' child node with one child 'endpoint'
+node, according to the bindings defined in [2]. This node should describe
+panel's video bus.
+
+[1]: Documentation/devicetree/bindings/video/cmdmode-display-timing.txt
+[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+	panel@0 {
+		compatible = "samsung,s6e3fa0";
+		reg = <0>;
+		vdd3-supply = <&vcclcd_reg>;
+		vci-supply = <&vlcd_reg>;
+		reset-gpios = <&gpy7 4 0>;
+		det-gpios = <&gpg0 6 0>;
+		te-gpios = <&gpd1 7 0>;
+
+		cmdmode-display-timings {
+			timing-0 {
+				clock-frequency = <0>;
+				hactive = <1080>;
+				vactive = <1920>;
+				cs-setup = <0>;
+				wr-setup = <0>;
+				wr-active = <1>;
+				wr-hold = <0>;
+			};
+		};
+	};
-- 
1.7.9.5

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

* [PATCH v2 14/18] drm/panel: add S6E3FA0 driver
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (11 preceding siblings ...)
  2014-05-21  4:43 ` [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings YoungJun Cho
@ 2014-05-21  4:43 ` YoungJun Cho
  2014-05-21  4:43 ` [PATCH v2 17/18] ARM: dts: exynos5420: add mipi-phy node YoungJun Cho
  2014-05-21  4:43 ` [PATCH v2 18/18] ARM: dts: exynos5420: add dsi node YoungJun Cho
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: devicetree, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, linux-samsung-soc, thierry.reding, laurent.pinchart,
	s.trumtrar, djkurtz, kyungmin.park, inki.dae, kgene.kim,
	jy0922.shim, sw0312.kim, a.hajda

This patch adds MIPI-DSI command mode based S6E3FA0 AMOLED LCD Panel driver.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/gpu/drm/panel/Kconfig         |    7 +
 drivers/gpu/drm/panel/Makefile        |    1 +
 drivers/gpu/drm/panel/panel-s6e3fa0.c |  568 +++++++++++++++++++++++++++++++++
 3 files changed, 576 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-s6e3fa0.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4ec874d..fa51237 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -30,4 +30,11 @@ config DRM_PANEL_S6E8AA0
 	select DRM_MIPI_DSI
 	select VIDEOMODE_HELPERS
 
+config DRM_PANEL_S6E3FA0
+	tristate "S6E3FA0 DSI command mode panel"
+	depends on DRM && DRM_PANEL
+	depends on OF
+	select DRM_MIPI_DSI
+	select CMDMODE_HELPERS
+
 endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 8b92921..85c6738 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
 obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
 obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
+obj-$(CONFIG_DRM_PANEL_S6E3FA0) += panel-s6e3fa0.o
diff --git a/drivers/gpu/drm/panel/panel-s6e3fa0.c b/drivers/gpu/drm/panel/panel-s6e3fa0.c
new file mode 100644
index 0000000..da73916
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-s6e3fa0.c
@@ -0,0 +1,568 @@
+/*
+ * MIPI-DSI based s6e3fa0 AMOLED LCD 5.7 inch panel driver.
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *
+ * YoungJun Cho <yj44.cho@samsung.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.
+*/
+
+#include <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+#include <video/of_cmdmode.h>
+#include <video/cmdmode.h>
+
+/* Manufacturer Command Set */
+#define MCS_GLOBAL_PARAMETER	0xb0
+#define MCS_AID			0xb2
+#define MCS_ELVSSOPT		0xb6
+#define MCS_TEMPERATURE_SET	0xb8
+#define MCS_PENTILE_CTRL	0xc0
+#define MCS_GAMMA_MODE		0xca
+#define MCS_VDDM		0xd7
+#define MCS_ALS			0xe3
+#define MCS_ERR_FG		0xed
+#define MCS_KEY_LEV1		0xf0
+#define MCS_PANEL_UPDATE	0xf7
+#define MCS_KEY_LEV2		0xfc
+#define MCS_RE			0xfe
+#define MCS_TOUT2_HSYNC		0xff
+
+/* Content Adaptive Brightness Control */
+#define DCS_WRITE_CABC		0x55
+
+#define MTP_ID_LEN		3
+#define GAMMA_LEVEL_NUM		30
+
+#define DEFAULT_VDDM_VAL	0x15
+
+struct s6e3fa0 {
+	struct device				*dev;
+	struct drm_panel			panel;
+
+	struct regulator_bulk_data		supplies[2];
+	struct gpio_desc			*reset_gpio;
+	struct gpio_desc			*det_gpio;
+	struct gpio_desc			*te_gpio;
+	struct cmdmode				cm;
+
+	unsigned int				power_on_delay;
+	unsigned int				reset_delay;
+	unsigned int				init_delay;
+	unsigned int				width_mm;
+	unsigned int				height_mm;
+
+	unsigned char				id;
+	unsigned char				vddm;
+	unsigned int				brightness;
+};
+
+#define panel_to_s6e3fa0(p) container_of(p, struct s6e3fa0, panel)
+
+/* VDD Memory Lookup Table contains pairs of {ReadValue, WriteValue} */
+static const unsigned char s6e3fa0_vddm_lut[][2] = {
+	{0x00, 0x0d}, {0x01, 0x0d}, {0x02, 0x0e}, {0x03, 0x0f}, {0x04, 0x10},
+	{0x05, 0x11}, {0x06, 0x12}, {0x07, 0x13}, {0x08, 0x14}, {0x09, 0x15},
+	{0x0a, 0x16}, {0x0b, 0x17}, {0x0c, 0x18}, {0x0d, 0x19}, {0x0e, 0x1a},
+	{0x0f, 0x1b}, {0x10, 0x1c}, {0x11, 0x1d}, {0x12, 0x1e}, {0x13, 0x1f},
+	{0x14, 0x20}, {0x15, 0x21}, {0x16, 0x22}, {0x17, 0x23}, {0x18, 0x24},
+	{0x19, 0x25}, {0x1a, 0x26}, {0x1b, 0x27}, {0x1c, 0x28}, {0x1d, 0x29},
+	{0x1e, 0x2a}, {0x1f, 0x2b}, {0x20, 0x2c}, {0x21, 0x2d}, {0x22, 0x2e},
+	{0x23, 0x2f}, {0x24, 0x30}, {0x25, 0x31}, {0x26, 0x32}, {0x27, 0x33},
+	{0x28, 0x34}, {0x29, 0x35}, {0x2a, 0x36}, {0x2b, 0x37}, {0x2c, 0x38},
+	{0x2d, 0x39}, {0x2e, 0x3a}, {0x2f, 0x3b}, {0x30, 0x3c}, {0x31, 0x3d},
+	{0x32, 0x3e}, {0x33, 0x3f}, {0x34, 0x3f}, {0x35, 0x3f}, {0x36, 0x3f},
+	{0x37, 0x3f}, {0x38, 0x3f}, {0x39, 0x3f}, {0x3a, 0x3f}, {0x3b, 0x3f},
+	{0x3c, 0x3f}, {0x3d, 0x3f}, {0x3e, 0x3f}, {0x3f, 0x3f}, {0x40, 0x0c},
+	{0x41, 0x0b}, {0x42, 0x0a}, {0x43, 0x09}, {0x44, 0x08}, {0x45, 0x07},
+	{0x46, 0x06}, {0x47, 0x05}, {0x48, 0x04}, {0x49, 0x03}, {0x4a, 0x02},
+	{0x4b, 0x01}, {0x4c, 0x40}, {0x4d, 0x41}, {0x4e, 0x42}, {0x4f, 0x43},
+	{0x50, 0x44}, {0x51, 0x45}, {0x52, 0x46}, {0x53, 0x47}, {0x54, 0x48},
+	{0x55, 0x49}, {0x56, 0x4a}, {0x57, 0x4b}, {0x58, 0x4c}, {0x59, 0x4d},
+	{0x5a, 0x4e}, {0x5b, 0x4f}, {0x5c, 0x50}, {0x5d, 0x51}, {0x5e, 0x52},
+	{0x5f, 0x53}, {0x60, 0x54}, {0x61, 0x55}, {0x62, 0x56}, {0x63, 0x57},
+	{0x64, 0x58}, {0x65, 0x59}, {0x66, 0x5a}, {0x67, 0x5b}, {0x68, 0x5c},
+	{0x69, 0x5d}, {0x6a, 0x5e}, {0x6b, 0x5f}, {0x6c, 0x60}, {0x6d, 0x61},
+	{0x6e, 0x62}, {0x6f, 0x63}, {0x70, 0x64}, {0x71, 0x65}, {0x72, 0x66},
+	{0x73, 0x67}, {0x74, 0x68}, {0x75, 0x69}, {0x76, 0x6a}, {0x77, 0x6b},
+	{0x78, 0x6c}, {0x79, 0x6d}, {0x7a, 0x6e}, {0x7b, 0x6f}, {0x7c, 0x70},
+	{0x7d, 0x71}, {0x7e, 0x72}, {0x7f, 0x73},
+};
+
+static int s6e3fa0_dcs_read(struct s6e3fa0 *ctx, unsigned char cmd,
+							void *data, size_t len)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+	return mipi_dsi_dcs_read(dsi, dsi->channel, cmd, data, len);
+}
+
+static void s6e3fa0_dcs_write(struct s6e3fa0 *ctx, const void *data, size_t len)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+	mipi_dsi_dcs_write(dsi, dsi->channel, data, len);
+}
+
+#define s6e3fa0_dcs_write_seq(ctx, seq...)				\
+do {									\
+	const unsigned char d[] = { seq };				\
+	BUILD_BUG_ON_MSG(ARRAY_SIZE(d) > 64, "too big seq for stack");	\
+	s6e3fa0_dcs_write(ctx, d, ARRAY_SIZE(d));			\
+} while (0)
+
+#define s6e3fa0_dcs_write_seq_static(ctx, seq...)			\
+do {									\
+	static const unsigned char d[] = { seq };			\
+	s6e3fa0_dcs_write(ctx, d, ARRAY_SIZE(d));			\
+} while (0)
+
+static void s6e3fa0_apply_level_1_key(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_KEY_LEV1, 0x5a, 0x5a);
+}
+
+static void s6e3fa0_apply_level_2_key(struct s6e3fa0 *ctx, bool on)
+{
+	if (on)
+		s6e3fa0_dcs_write_seq_static(ctx, MCS_KEY_LEV2, 0x5a, 0x5a);
+	else
+		s6e3fa0_dcs_write_seq_static(ctx, MCS_KEY_LEV2, 0xa5, 0xa5);
+}
+
+static void s6e3fa0_set_maximum_return_packet_size(struct s6e3fa0 *ctx,
+							unsigned int size)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+
+	if (ops && ops->transfer) {
+		unsigned char buf[] = {size, 0};
+		struct mipi_dsi_msg msg = {
+			.channel = dsi->channel,
+			.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
+			.tx_len = sizeof(buf),
+			.tx_buf = buf
+		};
+
+		ops->transfer(dsi->host, &msg);
+	}
+}
+
+static void s6e3fa0_read_mtp_id(struct s6e3fa0 *ctx)
+{
+	unsigned char id[MTP_ID_LEN];
+	int ret;
+
+	s6e3fa0_set_maximum_return_packet_size(ctx, MTP_ID_LEN);
+	ret = s6e3fa0_dcs_read(ctx, MIPI_DCS_GET_DISPLAY_ID, id, MTP_ID_LEN);
+	if (ret < MTP_ID_LEN || id[0] == 0x00) {
+		dev_err(ctx->dev, "failed to read id\n");
+		return;
+	}
+
+	dev_info(ctx->dev, "ID: 0x%02x, 0x%02x, 0x%02x\n", id[0], id[1], id[2]);
+
+	ctx->id = id[2];
+}
+
+static void s6e3fa0_read_vddm(struct s6e3fa0 *ctx)
+{
+	unsigned char vddm;
+	int ret;
+
+	s6e3fa0_apply_level_2_key(ctx, true);
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_GLOBAL_PARAMETER, 0x16);
+	s6e3fa0_set_maximum_return_packet_size(ctx, 1);
+	ret = s6e3fa0_dcs_read(ctx, MCS_VDDM, &vddm, 1);
+	s6e3fa0_apply_level_2_key(ctx, false);
+
+	if (ret < 1 || vddm > 0x7f) {
+		dev_err(ctx->dev, "failed to read vddm, use default val.\n");
+		vddm = DEFAULT_VDDM_VAL;
+	}
+
+	ctx->vddm = s6e3fa0_vddm_lut[vddm][1];
+}
+
+static void s6e3fa0_set_pentile_control(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_PENTILE_CTRL, 0x00, 0x02, 0x03,
+					0x32, 0x03, 0x44, 0x44, 0xc0, 0x00,
+					0x1c, 0x20, 0xe8);
+}
+
+static void s6e3fa0_write_ambient_light_sensor(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_ALS, 0xff, 0xff, 0xff, 0xff);
+}
+
+static void s6e3fa0_set_readability_enhancement(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_RE, 0x00, 0x03,
+					MCS_GLOBAL_PARAMETER, 0x2b,
+					MCS_RE, 0xe4);
+}
+
+static void s6e3fa0_set_common_control(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_set_pentile_control(ctx);
+	s6e3fa0_write_ambient_light_sensor(ctx);
+	s6e3fa0_set_readability_enhancement(ctx);
+}
+
+static void s6e3fa0_set_gamma(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_GAMMA_MODE, 0x01, 0x00, 0x01,
+					0x00, 0x01, 0x00, 0x80, 0x80, 0x80,
+					0x80, 0x80, 0x00, 0x80, 0x80, 0x80,
+					0x80, 0x80, 0x00, 0x80, 0x80, 0x80,
+					0x80, 0x80, 0x00, 0x80, 0x80, 0x80,
+					0x80, 0x80, 0x00, 0x00, 0x00);
+}
+
+static void s6e3fa0_set_amoled_impulse_driving(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_AID, 0x00, 0x06, 0x00, 0x06);
+}
+
+static void s6e3fa0_set_elvss(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_ELVSSOPT, 0x88, 0x0a);
+}
+
+static void s6e3fa0_update_panel(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_PANEL_UPDATE, 0x03);
+}
+
+static void s6e3fa0_write_automatic_current_limit(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, DCS_WRITE_CABC, 0x02);
+}
+
+static void s6e3fa0_set_brightness_control(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_set_gamma(ctx);
+	s6e3fa0_set_amoled_impulse_driving(ctx);
+	s6e3fa0_set_elvss(ctx);
+	s6e3fa0_update_panel(ctx);
+	s6e3fa0_write_automatic_current_limit(ctx);
+}
+
+static void s6e3fa0_set_temperature(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MCS_GLOBAL_PARAMETER, 0x05,
+					MCS_TEMPERATURE_SET, 0x19);
+}
+
+static void s6e3fa0_set_elvss_control(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_set_temperature(ctx);
+	s6e3fa0_set_elvss(ctx);
+}
+
+static void s6e3fa0_set_te_on(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_dcs_write_seq_static(ctx, MIPI_DCS_SET_TEAR_ON, 0x00);
+}
+
+static void s6e3fa0_set_etc_and_write_vddm(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_apply_level_2_key(ctx, true);
+	s6e3fa0_dcs_write_seq(ctx, MCS_ERR_FG, 0x0c, 0x04,
+				MCS_TOUT2_HSYNC, 0x01,
+				MCS_GLOBAL_PARAMETER, 0x16,
+				MCS_VDDM, ctx->vddm);
+	s6e3fa0_apply_level_2_key(ctx, false);
+}
+
+static void s6e3fa0_set_etc_condition(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_set_te_on(ctx);
+	s6e3fa0_set_etc_and_write_vddm(ctx);
+}
+
+static void s6e3fa0_panel_init(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_set_common_control(ctx);
+	s6e3fa0_set_brightness_control(ctx);
+	s6e3fa0_set_elvss_control(ctx);
+	s6e3fa0_set_etc_condition(ctx);
+
+	msleep(ctx->init_delay);
+}
+
+static int s6e3fa0_power_off(struct s6e3fa0 *ctx)
+{
+	gpiod_set_value(ctx->reset_gpio, 0);
+
+	return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+}
+
+static int s6e3fa0_power_on(struct s6e3fa0 *ctx)
+{
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret)
+		return ret;
+
+	msleep(ctx->power_on_delay);
+
+	gpiod_set_value(ctx->reset_gpio, 1);
+	gpiod_set_value(ctx->reset_gpio, 0);
+	usleep_range(1000, 2000);
+	gpiod_set_value(ctx->reset_gpio, 1);
+
+	msleep(ctx->reset_delay);
+
+	return 0;
+}
+
+static void s6e3fa0_set_sequence(struct s6e3fa0 *ctx)
+{
+	s6e3fa0_apply_level_1_key(ctx);
+	s6e3fa0_dcs_write_seq_static(ctx, MIPI_DCS_EXIT_SLEEP_MODE);
+	msleep(20);
+
+	s6e3fa0_read_mtp_id(ctx);
+	s6e3fa0_read_vddm(ctx);
+
+	s6e3fa0_panel_init(ctx);
+
+	s6e3fa0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_ON);
+}
+
+static int s6e3fa0_disable(struct drm_panel *panel)
+{
+	struct s6e3fa0 *ctx = panel_to_s6e3fa0(panel);
+
+	s6e3fa0_dcs_write_seq_static(ctx, MIPI_DCS_ENTER_SLEEP_MODE);
+	s6e3fa0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_OFF);
+	msleep(35);
+
+	return s6e3fa0_power_off(ctx);
+}
+
+static int s6e3fa0_enable(struct drm_panel *panel)
+{
+	struct s6e3fa0 *ctx = panel_to_s6e3fa0(panel);
+	int ret;
+
+	ret = s6e3fa0_power_on(ctx);
+	if (ret)
+		return ret;
+
+	s6e3fa0_set_sequence(ctx);
+
+	return ret;
+}
+
+static int s6e3fa0_get_modes(struct drm_panel *panel)
+{
+	struct drm_connector *connector = panel->connector;
+	struct s6e3fa0 *ctx = panel_to_s6e3fa0(panel);
+	struct drm_display_mode *mode;
+
+	mode = drm_mode_create(connector->dev);
+	if (!mode) {
+		DRM_ERROR("failed to create a new display mode\n");
+		return 0;
+	}
+
+	drm_display_mode_from_cmdmode(&ctx->cm, mode);
+	mode->width_mm = ctx->width_mm;
+	mode->height_mm = ctx->height_mm;
+	connector->display_info.width_mm = mode->width_mm;
+	connector->display_info.height_mm = mode->height_mm;
+
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	drm_mode_probed_add(connector, mode);
+
+	return 1;
+}
+
+static const struct drm_panel_funcs s6e3fa0_drm_funcs = {
+	.disable	= s6e3fa0_disable,
+	.enable		= s6e3fa0_enable,
+	.get_modes	= s6e3fa0_get_modes,
+};
+
+static int s6e3fa0_parse_dt(struct s6e3fa0 *ctx)
+{
+	struct device *dev = ctx->dev;
+	int ret;
+
+	ret = of_get_cmdmode(dev->of_node, &ctx->cm, 0);
+	if (ret) {
+		dev_err(dev, "failed to get command mode: %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+irqreturn_t s6e3fa0_det_interrupt(int irq, void *dev_id)
+{
+	/* TODO */
+	return IRQ_HANDLED;
+}
+
+irqreturn_t s6e3fa0_te_interrupt(int irq, void *dev_id)
+{
+	struct s6e3fa0 *ctx = dev_id;
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	struct mipi_dsi_host *host = dsi->host;
+	const struct mipi_dsi_host_ops *ops = host->ops;
+
+	if (ops && ops->te_handler)
+		ops->te_handler(host);
+
+	return IRQ_HANDLED;
+}
+
+static int s6e3fa0_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct s6e3fa0 *ctx;
+	int ret;
+
+	ctx = devm_kzalloc(dev, sizeof(struct s6e3fa0), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	ctx->dev = dev;
+
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+
+	ret = s6e3fa0_parse_dt(ctx);
+	if (ret)
+		return ret;
+
+	ctx->supplies[0].supply = "vdd3";
+	ctx->supplies[1].supply = "vci";
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
+					ctx->supplies);
+	if (ret) {
+		dev_err(dev, "failed to get regulators: %d\n", ret);
+		return ret;
+	}
+
+	ctx->reset_gpio = devm_gpiod_get(dev, "reset");
+	if (IS_ERR(ctx->reset_gpio)) {
+		dev_err(dev, "failed to get reset gpio: %ld\n",
+						PTR_ERR(ctx->reset_gpio));
+		return PTR_ERR(ctx->reset_gpio);
+	}
+	ret = gpiod_direction_output(ctx->reset_gpio, 1);
+	if (ret < 0) {
+		dev_err(dev, "failed to configure reset gpio: %d\n", ret);
+		return ret;
+	}
+
+	ctx->det_gpio = devm_gpiod_get(dev, "det");
+	if (IS_ERR(ctx->det_gpio)) {
+		dev_err(dev, "failed to get det gpio: %ld\n",
+						PTR_ERR(ctx->det_gpio));
+		return PTR_ERR(ctx->det_gpio);
+	}
+	ret = gpiod_direction_input(ctx->det_gpio);
+	if (ret < 0) {
+		dev_err(dev, "failed to configure det gpio: %d\n", ret);
+		return ret;
+	}
+	ret = devm_request_irq(dev, gpiod_to_irq(ctx->det_gpio),
+						s6e3fa0_det_interrupt,
+						IRQF_TRIGGER_FALLING,
+						"oled-det", ctx);
+	if (ret) {
+		dev_err(dev, "failed to request det irq: %d\n", ret);
+		return ret;
+	}
+
+	ctx->te_gpio = devm_gpiod_get(dev, "te");
+	if (IS_ERR(ctx->te_gpio)) {
+		dev_err(dev, "failed to get te gpio: %ld\n",
+						PTR_ERR(ctx->te_gpio));
+		return PTR_ERR(ctx->te_gpio);
+	}
+	ret = gpiod_direction_input(ctx->te_gpio);
+	if (ret < 0) {
+		dev_err(dev, "failed to configure te gpio: %d\n", ret);
+		return ret;
+	}
+	ret = devm_request_irq(dev, gpiod_to_irq(ctx->te_gpio),
+						s6e3fa0_te_interrupt,
+						IRQF_TRIGGER_RISING,
+						"TE", ctx);
+	if (ret) {
+		dev_err(dev, "failed to request det irq: %d\n", ret);
+		return ret;
+	}
+
+	ctx->power_on_delay = 10;
+	ctx->reset_delay = 5;
+	ctx->init_delay = 120;
+	ctx->width_mm = 71;
+	ctx->height_mm = 126;
+
+	ctx->brightness = GAMMA_LEVEL_NUM - 1;
+
+	drm_panel_init(&ctx->panel);
+	ctx->panel.dev = dev;
+	ctx->panel.funcs = &s6e3fa0_drm_funcs;
+
+	ret = drm_panel_add(&ctx->panel);
+	if (ret)
+		return ret;
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret)
+		drm_panel_remove(&ctx->panel);
+
+	return ret;
+}
+
+static int s6e3fa0_remove(struct mipi_dsi_device *dsi)
+{
+	struct s6e3fa0 *ctx = mipi_dsi_get_drvdata(dsi);
+
+	mipi_dsi_detach(dsi);
+	drm_panel_remove(&ctx->panel);
+
+	return 0;
+}
+
+static struct of_device_id s6e3fa0_of_match[] = {
+	{ .compatible = "samsung,s6e3fa0" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, s6e3fa0_of_match);
+
+static struct mipi_dsi_driver s6e3fa0_driver = {
+	.probe = s6e3fa0_probe,
+	.remove = s6e3fa0_remove,
+	.driver = {
+		.name = "panel_s6e3fa0",
+		.owner = THIS_MODULE,
+		.of_match_table = s6e3fa0_of_match,
+	},
+};
+module_mipi_dsi_driver(s6e3fa0_driver);
+
+MODULE_AUTHOR("YoungJun Cho <yj44.cho@samsung.com>");
+MODULE_DESCRIPTION("MIPI-DSI based s6e3fa0 AMOLED LCD Panel Driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5

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

* [PATCH v2 15/18] ARM: dts: exynos4: add system register node
       [not found] ` <1400647390-26590-1-git-send-email-yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2014-05-21  4:42   ` [PATCH v2 03/18] ARM: dts: video: add command mode display timing DT bindings YoungJun Cho
  2014-05-21  4:43   ` [PATCH v2 08/18] drm/exynos: add TE handler to support MIPI DSI command mode interface YoungJun Cho
@ 2014-05-21  4:43   ` YoungJun Cho
  2014-05-21  4:43   ` [PATCH v2 16/18] ARM: dts: exynos5: add system register support YoungJun Cho
  3 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied-cv59FeDIM0c, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw,
	s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ,
	djkurtz-F7+t8E8rja9g9hUCZPvPmw,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	inki.dae-Sze3O3UU22JBDgjK7y7TUQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	a.hajda-Sze3O3UU22JBDgjK7y7TUQ

This patch adds sysreg property to fimd device node which is required
to use I80 interface.

Signed-off-by: YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Inki Dae <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/exynos4.dtsi |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 2f8bcd0..abfcbe2 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -534,6 +534,7 @@
 		clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
 		clock-names = "sclk_fimd", "fimd";
 		samsung,power-domain = <&pd_lcd0>;
+		samsung,sysreg = <&sys_reg>;
 		status = "disabled";
 	};
 };
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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 related	[flat|nested] 39+ messages in thread

* [PATCH v2 16/18] ARM: dts: exynos5: add system register support
       [not found] ` <1400647390-26590-1-git-send-email-yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (2 preceding siblings ...)
  2014-05-21  4:43   ` [PATCH v2 15/18] ARM: dts: exynos4: add system register node YoungJun Cho
@ 2014-05-21  4:43   ` YoungJun Cho
  3 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied-cv59FeDIM0c, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw,
	s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ,
	djkurtz-F7+t8E8rja9g9hUCZPvPmw,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	inki.dae-Sze3O3UU22JBDgjK7y7TUQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	a.hajda-Sze3O3UU22JBDgjK7y7TUQ

This patch adds sysreg device node, and sysreg property to fimd device node
which is required to use I80 interface.

Signed-off-by: YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Inki Dae <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/exynos5.dtsi |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
index 79d0608..95ee496 100644
--- a/arch/arm/boot/dts/exynos5.dtsi
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -81,12 +81,18 @@
 		status = "disabled";
 	};
 
+	sys_reg: syscon@10050000 {
+		compatible = "samsung,exynos5-sysreg", "syscon";
+		reg = <0x10050000 0x500>;
+	};
+
 	fimd@14400000 {
 		compatible = "samsung,exynos5250-fimd";
 		interrupt-parent = <&combiner>;
 		reg = <0x14400000 0x40000>;
 		interrupt-names = "fifo", "vsync", "lcd_sys";
 		interrupts = <18 4>, <18 5>, <18 6>;
+		samsung,sysreg = <&sys_reg>;
 		status = "disabled";
 	};
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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 related	[flat|nested] 39+ messages in thread

* [PATCH v2 17/18] ARM: dts: exynos5420: add mipi-phy node
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (12 preceding siblings ...)
  2014-05-21  4:43 ` [PATCH v2 14/18] drm/panel: add S6E3FA0 driver YoungJun Cho
@ 2014-05-21  4:43 ` YoungJun Cho
  2014-05-21  4:43 ` [PATCH v2 18/18] ARM: dts: exynos5420: add dsi node YoungJun Cho
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

This patch adds mipi-phy node for MIPI-DSI device.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/boot/dts/exynos5420.dtsi |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index c3a9a66..6fde5fd 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -472,6 +472,12 @@
 		phy-names = "dp";
 	};
 
+	mipi_phy: video-phy@10040714 {
+		compatible = "samsung,s5pv210-mipi-video-phy";
+		reg = <0x10040714 12>;
+		#phy-cells = <1>;
+	};
+
 	fimd@14400000 {
 		samsung,power-domain = <&disp_pd>;
 		clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
-- 
1.7.9.5

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

* [PATCH v2 18/18] ARM: dts: exynos5420: add dsi node
  2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
                   ` (13 preceding siblings ...)
  2014-05-21  4:43 ` [PATCH v2 17/18] ARM: dts: exynos5420: add mipi-phy node YoungJun Cho
@ 2014-05-21  4:43 ` YoungJun Cho
  14 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  4:43 UTC (permalink / raw)
  To: airlied, dri-devel
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, a.hajda, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

This patch adds common part of dsi node.

Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/boot/dts/exynos5420.dtsi |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 6fde5fd..43b6852 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -478,6 +478,20 @@
 		#phy-cells = <1>;
 	};
 
+	dsi@14500000 {
+		compatible = "samsung,exynos5420-mipi-dsi";
+		reg = <0x14500000 0x10000>;
+		interrupts = <0 82 0>;
+		samsung,power-domain = <&disp_pd>;
+		phys = <&mipi_phy 1>;
+		phy-names = "dsim";
+		clocks = <&clock CLK_DSIM1>, <&clock CLK_SCLK_MIPI1>;
+		clock-names = "bus_clk", "pll_clk";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	fimd@14400000 {
 		samsung,power-domain = <&disp_pd>;
 		clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
-- 
1.7.9.5

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

* Re: [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage
  2014-05-21  4:42 ` [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage YoungJun Cho
@ 2014-05-21  6:01   ` Daniel Kurtz
  2014-05-21  6:28     ` YoungJun Cho
  0 siblings, 1 reply; 39+ messages in thread
From: Daniel Kurtz @ 2014-05-21  6:01 UTC (permalink / raw)
  To: YoungJun Cho
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Seung-Woo Kim, dri-devel, Andrzej Hajda,
	Kyungmin Park, Rob Herring, Laurent Pinchart, Kumar Gala,
	Kukjin Kim, s.trumtrar

On Wed, May 21, 2014 at 12:42 PM, YoungJun Cho <yj44.cho@samsung.com> wrote:
> There could be the case that the page flip operation isn't finished correctly
> with some abnormal condition such as panel reset. So this patch replaces
> wait_event() with wait_event_timeout() to avoid waiting for page flip completion
> infinitely.
> And clears exynos_crtc->pending_flip in exynos_drm_crtc_page_flip() when
> exynos_drm_crtc_mode_set_commit() is failed.
>
> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
> Acked-by: Inki Dae <inki.dae@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_crtc.c |    7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
> index 95c9435..3bf091d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
> @@ -69,8 +69,10 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
>
>         if (mode > DRM_MODE_DPMS_ON) {
>                 /* wait for the completion of page flip. */
> -               wait_event(exynos_crtc->pending_flip_queue,
> -                               atomic_read(&exynos_crtc->pending_flip) == 0);
> +               if (!wait_event_timeout(exynos_crtc->pending_flip_queue,
> +                               !atomic_read(&exynos_crtc->pending_flip),
> +                               HZ/20))
> +                       atomic_set(&exynos_crtc->pending_flip, 0);

I meant that changing this to wait_event_timeout() seems to be masking
the original problem, that pending_flip wasn't being cleared.
Now that you are now clearing pending_flip in the error path, you
don't need the timeout, right?

-Dan

>                 drm_vblank_off(crtc->dev, exynos_crtc->pipe);
>         }
>
> @@ -259,6 +261,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
>                         spin_lock_irq(&dev->event_lock);
>                         drm_vblank_put(dev, exynos_crtc->pipe);
>                         list_del(&event->base.link);
> +                       atomic_set(&exynos_crtc->pending_flip, 0);
>                         spin_unlock_irq(&dev->event_lock);
>
>                         goto out;
> --
> 1.7.9.5
>

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

* Re: [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage
  2014-05-21  6:01   ` Daniel Kurtz
@ 2014-05-21  6:28     ` YoungJun Cho
  2014-05-21  6:45       ` Daniel Kurtz
  0 siblings, 1 reply; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21  6:28 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Seung-Woo Kim, dri-devel, Andrzej Hajda,
	Kyungmin Park, Rob Herring, Laurent Pinchart, Kumar Gala,
	Kukjin Kim, s.trumtrar

Hi Daniel

On 05/21/2014 03:01 PM, Daniel Kurtz wrote:
> On Wed, May 21, 2014 at 12:42 PM, YoungJun Cho <yj44.cho@samsung.com> wrote:
>> There could be the case that the page flip operation isn't finished correctly
>> with some abnormal condition such as panel reset. So this patch replaces
>> wait_event() with wait_event_timeout() to avoid waiting for page flip completion
>> infinitely.
>> And clears exynos_crtc->pending_flip in exynos_drm_crtc_page_flip() when
>> exynos_drm_crtc_mode_set_commit() is failed.
>>
>> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>> Acked-by: Inki Dae <inki.dae@samsung.com>
>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> ---
>>   drivers/gpu/drm/exynos/exynos_drm_crtc.c |    7 +++++--
>>   1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>> index 95c9435..3bf091d 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>> @@ -69,8 +69,10 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
>>
>>          if (mode > DRM_MODE_DPMS_ON) {
>>                  /* wait for the completion of page flip. */
>> -               wait_event(exynos_crtc->pending_flip_queue,
>> -                               atomic_read(&exynos_crtc->pending_flip) == 0);
>> +               if (!wait_event_timeout(exynos_crtc->pending_flip_queue,
>> +                               !atomic_read(&exynos_crtc->pending_flip),
>> +                               HZ/20))
>> +                       atomic_set(&exynos_crtc->pending_flip, 0);
>
> I meant that changing this to wait_event_timeout() seems to be masking
> the original problem, that pending_flip wasn't being cleared.

Yes, I agree.

The original purpose of this patch is to avoid lock-up during modetest 
(with test_vsync) with command mode panel.
In MIPI DSI command mode interface, the display controller can not 
generate VSYNC signal and uses TE signal instead which is generated by 
panel.
If there is an abnormal power off or reset condition, it is possible 
that the display controller misses the TE signal and it makes lock-up.
So I needed this patch.

> Now that you are now clearing pending_flip in the error path, you
> don't need the timeout, right?
>

There might be my missing point. Would you explain more detail?

Thank you.
Best regards YJ

> -Dan
>
>>                  drm_vblank_off(crtc->dev, exynos_crtc->pipe);
>>          }
>>
>> @@ -259,6 +261,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
>>                          spin_lock_irq(&dev->event_lock);
>>                          drm_vblank_put(dev, exynos_crtc->pipe);
>>                          list_del(&event->base.link);
>> +                       atomic_set(&exynos_crtc->pending_flip, 0);
>>                          spin_unlock_irq(&dev->event_lock);
>>
>>                          goto out;
>> --
>> 1.7.9.5
>>
>

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

* Re: [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage
  2014-05-21  6:28     ` YoungJun Cho
@ 2014-05-21  6:45       ` Daniel Kurtz
  2014-05-21 10:37         ` YoungJun Cho
  0 siblings, 1 reply; 39+ messages in thread
From: Daniel Kurtz @ 2014-05-21  6:45 UTC (permalink / raw)
  To: YoungJun Cho
  Cc: David Airlie, dri-devel, devicetree, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, linux-samsung-soc,
	Thierry Reding, Laurent Pinchart, s.trumtrar, Kyungmin Park,
	InKi Dae, Kukjin Kim, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda

On Wed, May 21, 2014 at 2:28 PM, YoungJun Cho <yj44.cho@samsung.com> wrote:
> Hi Daniel
>
>
> On 05/21/2014 03:01 PM, Daniel Kurtz wrote:
>>
>> On Wed, May 21, 2014 at 12:42 PM, YoungJun Cho <yj44.cho@samsung.com>
>> wrote:
>>>
>>> There could be the case that the page flip operation isn't finished
>>> correctly
>>> with some abnormal condition such as panel reset. So this patch replaces
>>> wait_event() with wait_event_timeout() to avoid waiting for page flip
>>> completion
>>> infinitely.
>>> And clears exynos_crtc->pending_flip in exynos_drm_crtc_page_flip() when
>>> exynos_drm_crtc_mode_set_commit() is failed.
>>>
>>> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>>> Acked-by: Inki Dae <inki.dae@samsung.com>
>>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>>> ---
>>>   drivers/gpu/drm/exynos/exynos_drm_crtc.c |    7 +++++--
>>>   1 file changed, 5 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>>> b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>>> index 95c9435..3bf091d 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>>> @@ -69,8 +69,10 @@ static void exynos_drm_crtc_dpms(struct drm_crtc
>>> *crtc, int mode)
>>>
>>>          if (mode > DRM_MODE_DPMS_ON) {
>>>                  /* wait for the completion of page flip. */
>>> -               wait_event(exynos_crtc->pending_flip_queue,
>>> -                               atomic_read(&exynos_crtc->pending_flip)
>>> == 0);
>>> +               if (!wait_event_timeout(exynos_crtc->pending_flip_queue,
>>> +                               !atomic_read(&exynos_crtc->pending_flip),
>>> +                               HZ/20))
>>> +                       atomic_set(&exynos_crtc->pending_flip, 0);
>>
>>
>> I meant that changing this to wait_event_timeout() seems to be masking
>> the original problem, that pending_flip wasn't being cleared.
>
>
> Yes, I agree.
>
> The original purpose of this patch is to avoid lock-up during modetest (with
> test_vsync) with command mode panel.
> In MIPI DSI command mode interface, the display controller can not generate
> VSYNC signal and uses TE signal instead which is generated by panel.
> If there is an abnormal power off or reset condition, it is possible that
> the display controller misses the TE signal and it makes lock-up.
> So I needed this patch.

If flips are not completing on MIPI DSI, may I recommend that you
start a timer when scheduling such a flip in the MIPI DSI driver that
will expire after a timeout.  In that timer's expiration handler, you
can then go through the normal process of completing a flip.  This
would make the timeout transparent to the generic exynos_drm_crtc
layer, which can then do its normal flip complete processing: send
pending vblank events, put vblank, clear pending_flip, etc.
Does that make sense?
Is it possible?

-Dan

>> Now that you are now clearing pending_flip in the error path, you
>> don't need the timeout, right?
>>
>
> There might be my missing point. Would you explain more detail?
>
>
> Thank you.
> Best regards YJ
>
>> -Dan
>>
>>>                  drm_vblank_off(crtc->dev, exynos_crtc->pipe);
>>>          }
>>>
>>> @@ -259,6 +261,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc
>>> *crtc,
>>>                          spin_lock_irq(&dev->event_lock);
>>>                          drm_vblank_put(dev, exynos_crtc->pipe);
>>>                          list_del(&event->base.link);
>>> +                       atomic_set(&exynos_crtc->pending_flip, 0);
>>>                          spin_unlock_irq(&dev->event_lock);
>>>
>>>                          goto out;
>>> --
>>> 1.7.9.5
>>>
>>
>

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

* Re: [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage
  2014-05-21  6:45       ` Daniel Kurtz
@ 2014-05-21 10:37         ` YoungJun Cho
  0 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21 10:37 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: David Airlie, dri-devel, devicetree, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, linux-samsung-soc,
	Thierry Reding, Laurent Pinchart, s.trumtrar, Kyungmin Park,
	InKi Dae, Kukjin Kim, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda

Hi Daniel,

On 05/21/2014 03:45 PM, Daniel Kurtz wrote:
> On Wed, May 21, 2014 at 2:28 PM, YoungJun Cho <yj44.cho@samsung.com> wrote:
>> Hi Daniel
>>
>>
>> On 05/21/2014 03:01 PM, Daniel Kurtz wrote:
>>>
>>> On Wed, May 21, 2014 at 12:42 PM, YoungJun Cho <yj44.cho@samsung.com>
>>> wrote:
>>>>
>>>> There could be the case that the page flip operation isn't finished
>>>> correctly
>>>> with some abnormal condition such as panel reset. So this patch replaces
>>>> wait_event() with wait_event_timeout() to avoid waiting for page flip
>>>> completion
>>>> infinitely.
>>>> And clears exynos_crtc->pending_flip in exynos_drm_crtc_page_flip() when
>>>> exynos_drm_crtc_mode_set_commit() is failed.
>>>>
>>>> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>>>> Acked-by: Inki Dae <inki.dae@samsung.com>
>>>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>>>> ---
>>>>    drivers/gpu/drm/exynos/exynos_drm_crtc.c |    7 +++++--
>>>>    1 file changed, 5 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>>>> b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>>>> index 95c9435..3bf091d 100644
>>>> --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
>>>> @@ -69,8 +69,10 @@ static void exynos_drm_crtc_dpms(struct drm_crtc
>>>> *crtc, int mode)
>>>>
>>>>           if (mode > DRM_MODE_DPMS_ON) {
>>>>                   /* wait for the completion of page flip. */
>>>> -               wait_event(exynos_crtc->pending_flip_queue,
>>>> -                               atomic_read(&exynos_crtc->pending_flip)
>>>> == 0);
>>>> +               if (!wait_event_timeout(exynos_crtc->pending_flip_queue,
>>>> +                               !atomic_read(&exynos_crtc->pending_flip),
>>>> +                               HZ/20))
>>>> +                       atomic_set(&exynos_crtc->pending_flip, 0);
>>>
>>>
>>> I meant that changing this to wait_event_timeout() seems to be masking
>>> the original problem, that pending_flip wasn't being cleared.
>>
>>
>> Yes, I agree.
>>
>> The original purpose of this patch is to avoid lock-up during modetest (with
>> test_vsync) with command mode panel.
>> In MIPI DSI command mode interface, the display controller can not generate
>> VSYNC signal and uses TE signal instead which is generated by panel.
>> If there is an abnormal power off or reset condition, it is possible that

At first, I omitted the keyword "panel" at previous reply.
The abnormal power off or reset condition could be happened in panel
which generates TE signal.

>> the display controller misses the TE signal and it makes lock-up.
>> So I needed this patch.
>
> If flips are not completing on MIPI DSI, may I recommend that you
> start a timer when scheduling such a flip in the MIPI DSI driver that
> will expire after a timeout.  In that timer's expiration handler, you

The MIPI DSI doesn't take care page flip operation at all.
And the exynos_drm_crtc_finish_page_flip() is called only by interrupt 
handler of display controllers.
So there is no suitable place to set time-out for this.

> can then go through the normal process of completing a flip.  This
> would make the timeout transparent to the generic exynos_drm_crtc
> layer, which can then do its normal flip complete processing: send
> pending vblank events, put vblank, clear pending_flip, etc.
> Does that make sense?
> Is it possible?

This function is exynos_drm_crtc_dpms() and my patch is for DPMS OFF case.
That means all page flip operations should be finished already to
control DPMS off and in almost every case, there is no problem.

But if there is an issue like this lock-up, I think it should escape 
this condition.

Thank you.
Best regards YJ

>
> -Dan
>
>>> Now that you are now clearing pending_flip in the error path, you
>>> don't need the timeout, right?
>>>
>>
>> There might be my missing point. Would you explain more detail?
>>
>>
>> Thank you.
>> Best regards YJ
>>
>>> -Dan
>>>
>>>>                   drm_vblank_off(crtc->dev, exynos_crtc->pipe);
>>>>           }
>>>>
>>>> @@ -259,6 +261,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc
>>>> *crtc,
>>>>                           spin_lock_irq(&dev->event_lock);
>>>>                           drm_vblank_put(dev, exynos_crtc->pipe);
>>>>                           list_del(&event->base.link);
>>>> +                       atomic_set(&exynos_crtc->pending_flip, 0);
>>>>                           spin_unlock_irq(&dev->event_lock);
>>>>
>>>>                           goto out;
>>>> --
>>>> 1.7.9.5
>>>>
>>>
>>
>

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

* Re: [PATCH v2 04/18] video: add command mode and command mode display timing
  2014-05-21  4:42 ` [PATCH v2 04/18] video: add command mode and command mode display timing YoungJun Cho
@ 2014-05-21 11:02   ` Thierry Reding
  2014-05-21 11:41     ` YoungJun Cho
  2014-05-26 10:14   ` Thierry Reding
  1 sibling, 1 reply; 39+ messages in thread
From: Thierry Reding @ 2014-05-21 11:02 UTC (permalink / raw)
  To: YoungJun Cho
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, a.hajda, kyungmin.park,
	robh+dt, laurent.pinchart, galak, kgene.kim, s.trumtrar


[-- Attachment #1.1: Type: text/plain, Size: 610 bytes --]

On Wed, May 21, 2014 at 01:42:56PM +0900, YoungJun Cho wrote:
> This patch is based on videomode and display_timing relevant codes.
> To support command mode panel, it does not need to guide its timing
> information to the display controller like video mode panel,
> but it requires signal timings to transfer video data.
> So this patch adds cmdmode struct, cmdmode_display_timing struct and
> the according helper functions to convert cmdmode_display_timing
> to a generic cmdmode.

Can you point me to relevant documentation? I wasn't able to find it by
a quick scan through the DSI specification.

Thierry

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v2 04/18] video: add command mode and command mode display timing
  2014-05-21 11:02   ` Thierry Reding
@ 2014-05-21 11:41     ` YoungJun Cho
  2014-05-22 13:07       ` Inki Dae
  0 siblings, 1 reply; 39+ messages in thread
From: YoungJun Cho @ 2014-05-21 11:41 UTC (permalink / raw)
  To: Thierry Reding
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, a.hajda, kyungmin.park,
	robh+dt, laurent.pinchart, galak, kgene.kim, s.trumtrar

Hi Therry

On 05/21/2014 08:02 PM, Thierry Reding wrote:
> On Wed, May 21, 2014 at 01:42:56PM +0900, YoungJun Cho wrote:
>> This patch is based on videomode and display_timing relevant codes.
>> To support command mode panel, it does not need to guide its timing
>> information to the display controller like video mode panel,
>> but it requires signal timings to transfer video data.
>> So this patch adds cmdmode struct, cmdmode_display_timing struct and
>> the according helper functions to convert cmdmode_display_timing
>> to a generic cmdmode.
>
> Can you point me to relevant documentation? I wasn't able to find it by
> a quick scan through the DSI specification.
>

I'm sorry to say that there is no specific one document.

I referred to several ones, CPU interface, I80 interface and
DBI document(last time you said it).
I think this is good to check it.
[ http://cache.freescale.com/files/dsp/doc/app_note/AN4180.pdf ]

And I asked panel vendor custom service centre also.

Thank you.
Best regards YJ

> Thierry
>

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

* Re: [PATCH v2 04/18] video: add command mode and command mode display timing
  2014-05-21 11:41     ` YoungJun Cho
@ 2014-05-22 13:07       ` Inki Dae
  2014-05-22 13:53         ` Thierry Reding
  0 siblings, 1 reply; 39+ messages in thread
From: Inki Dae @ 2014-05-22 13:07 UTC (permalink / raw)
  To: YoungJun Cho
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, robh+dt, a.hajda, kyungmin.park,
	dri-devel, galak, kgene.kim, s.trumtrar, laurent.pinchart

On 2014년 05월 21일 20:41, YoungJun Cho wrote:
> Hi Therry
> 
> On 05/21/2014 08:02 PM, Thierry Reding wrote:
>> On Wed, May 21, 2014 at 01:42:56PM +0900, YoungJun Cho wrote:
>>> This patch is based on videomode and display_timing relevant codes.
>>> To support command mode panel, it does not need to guide its timing
>>> information to the display controller like video mode panel,
>>> but it requires signal timings to transfer video data.
>>> So this patch adds cmdmode struct, cmdmode_display_timing struct and
>>> the according helper functions to convert cmdmode_display_timing
>>> to a generic cmdmode.
>>
>> Can you point me to relevant documentation? I wasn't able to find it by
>> a quick scan through the DSI specification.
>>
> 
> I'm sorry to say that there is no specific one document.
> 
> I referred to several ones, CPU interface, I80 interface and
> DBI document(last time you said it).
> I think this is good to check it.
> [ http://cache.freescale.com/files/dsp/doc/app_note/AN4180.pdf ]
> 

Ping~. Is there other comment? If so then I'd like to pick them up. We
would be happy for you leave reviewed-by or acked-by.

Thanks,
Inki Dae

> And I asked panel vendor custom service centre also.
> 
> Thank you.
> Best regards YJ
> 
>> Thierry
>>
> 
> -- 
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

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

* Re: [PATCH v2 04/18] video: add command mode and command mode display timing
  2014-05-22 13:07       ` Inki Dae
@ 2014-05-22 13:53         ` Thierry Reding
  0 siblings, 0 replies; 39+ messages in thread
From: Thierry Reding @ 2014-05-22 13:53 UTC (permalink / raw)
  To: Inki Dae
  Cc: YoungJun Cho, airlied, dri-devel, devicetree, robh+dt,
	pawel.moll, mark.rutland, ijc+devicetree, galak,
	linux-samsung-soc, laurent.pinchart, s.trumtrar, djkurtz,
	kyungmin.park, kgene.kim, jy0922.shim, sw0312.kim, a.hajda,
	Philipp Zabel, Russell King

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

On Thu, May 22, 2014 at 10:07:50PM +0900, Inki Dae wrote:
> On 2014년 05월 21일 20:41, YoungJun Cho wrote:
> > Hi Therry
> > 
> > On 05/21/2014 08:02 PM, Thierry Reding wrote:
> >> On Wed, May 21, 2014 at 01:42:56PM +0900, YoungJun Cho wrote:
> >>> This patch is based on videomode and display_timing relevant codes.
> >>> To support command mode panel, it does not need to guide its timing
> >>> information to the display controller like video mode panel,
> >>> but it requires signal timings to transfer video data.
> >>> So this patch adds cmdmode struct, cmdmode_display_timing struct and
> >>> the according helper functions to convert cmdmode_display_timing
> >>> to a generic cmdmode.
> >>
> >> Can you point me to relevant documentation? I wasn't able to find it by
> >> a quick scan through the DSI specification.
> >>
> > 
> > I'm sorry to say that there is no specific one document.
> > 
> > I referred to several ones, CPU interface, I80 interface and
> > DBI document(last time you said it).
> > I think this is good to check it.
> > [ http://cache.freescale.com/files/dsp/doc/app_note/AN4180.pdf ]
> > 
> 
> Ping~. Is there other comment? If so then I'd like to pick them up. We
> would be happy for you leave reviewed-by or acked-by.

I'd rather not see this merged yet. Can somebody from the i.MX crowd
perhaps look at this, to see if they've had to solve a similar problem
(since the above document refers to i.MX)?

Adding Russell and Philipp for a second opinion.

Thierry

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

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

* Re: [PATCH v2 10/18] drm/exynos: fimd: support I80 interface
  2014-05-21  4:43 ` [PATCH v2 10/18] drm/exynos: fimd: support I80 interface YoungJun Cho
@ 2014-05-26  9:00   ` Daniel Kurtz
  2014-05-29  5:45     ` YoungJun Cho
  0 siblings, 1 reply; 39+ messages in thread
From: Daniel Kurtz @ 2014-05-26  9:00 UTC (permalink / raw)
  To: YoungJun Cho
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Seung-Woo Kim, dri-devel, Andrzej Hajda,
	Kyungmin Park, Rob Herring, Laurent Pinchart, Kumar Gala,
	Kukjin Kim, s.trumtrar

Hi YoungJun,

I am not famiilar with i80.  Reading through this patch, it looks like
it works something like below for a page flip...

-> page_flip ioctl
exynos_drm_crtc_page_flip()
  exynos_drm_crtc_mode_set_commit()
    exynos_plane_mode_set()
    exynos_drm_crtc_commit()
      exynos_plane_commit()
        exynos_drm_crtc_plane_commit()
          ops->win_commit() => fimd_win_commit()
            update BASE (scanout) register
            atomic_set(&ctx->win_updated, 1);

... at the next TE event ...
fimd_te_handler()
  atomic_set(&ctx->win_updated, 0);
  fimd_trigger(ctx->dev);
    atomic_set(&ctx->triggering, 1);
    VIDINTCON0 |= VIDINTCON0_INT_ENABLE;
    TRIGCON |= TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE
    ... start an i80 transaction to transfer frame data from BASE to
the panel ...

... write complete signalled by ...
-> FIMD interrupt: source =  VIDINTCON0_INT_I80IFDONE |
VIDINTCON0_INT_SYSMAINCON (which one?)
fimd_irq_handler()
  atomic_set(&ctx->triggering, 0);
  drm_handle_vblank(ctx->drm_dev, ctx->pipe);
  exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);

Some questions/points:
 (1) does the "i80 done" interrupt mean that the panel is now
displaying the new frame?  Or just that the new frame is pending in a
panel-side scanout buffer?  Is there a separate interrupt for (a) "i80
transfer complete", and (b) "new frame now on main display"?

 (2) from the "DPMS off" patch, you mentioned that the panel sometimes
has an issue.  Do you mean that sometimes when you trigger the i80
transaction, there is no corresponding "i80ifdone / sysmaincon"
interrupt?   If so, then I think you want to start a timer in
fimd_trigger(), that, if it expires before an I80IFDONE irq, will call
exynos_drm_crtc_finish_pageflip(), rather than hiding handling this
condition in dpms off of the exynos_drm_crtc.c layer.

Thanks,
-djk




On Wed, May 21, 2014 at 12:43 PM, YoungJun Cho <yj44.cho@samsung.com> wrote:
> To support MIPI DSI command mode interface, FIMD should do followings:
> - Sets LCD block configuration for I80 interface.
> - Uses "lcd_sys" as an IRQ resource and sets relevant IRQ configuration.
> - Implements trigger feature which transfers image date if there is
>   page flip request, and implements TE handler to call trigger function.
> - Sets command mode timings configuration.
> - Sets ideal(pixel) clock is 2 times faster than the original one to
>   generate frame done IRQ prior to the next TE signal.
>
> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
> Acked-by: Inki Dae <inki.dae@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  drivers/gpu/drm/exynos/Kconfig           |    1 +
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c |  277 +++++++++++++++++++++++++-----
>  include/video/samsung_fimd.h             |    3 +-
>  3 files changed, 237 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
> index 5bf5bca..f4d34f0 100644
> --- a/drivers/gpu/drm/exynos/Kconfig
> +++ b/drivers/gpu/drm/exynos/Kconfig
> @@ -28,6 +28,7 @@ config DRM_EXYNOS_FIMD
>         bool "Exynos DRM FIMD"
>         depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM
>         select FB_MODE_HELPERS
> +       select MFD_SYSCON
>         help
>           Choose this option if you want to use Exynos FIMD for DRM.
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 173ee97..9d585f9 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -20,11 +20,14 @@
>  #include <linux/of_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/component.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
>
>  #include <video/of_display_timing.h>
>  #include <video/of_videomode.h>
>  #include <video/samsung_fimd.h>
>  #include <drm/exynos_drm.h>
> +#include <drm/drm_panel.h>
>
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_fbdev.h"
> @@ -60,6 +63,24 @@
>  /* color key value register for hardware window 1 ~ 4. */
>  #define WKEYCON1_BASE(x)               ((WKEYCON1 + 0x140) + ((x - 1) * 8))
>
> +/* i80 / RGB trigger control register */
> +#define TRIGCON                                0x1A4
> +#define TRGMODE_I80_RGB_ENABLE_I80     (1 << 0)
> +#define SWTRGCMD_I80_RGB_ENABLE                (1 << 1)
> +
> +/* display mode change control register except exynos4 */
> +#define VIDOUT_CON                     0x000
> +#define VIDOUT_CON_F_I80_LDI0          (0x2 << 8)
> +
> +/* i80 interface control for main LDI register */
> +#define I80IFCONFAx(x)                 (0x1B0 + (x) * 4)
> +#define I80IFCONFBx(x)                 (0x1B8 + (x) * 4)
> +#define LCD_CS_SETUP(x)                        ((x) << 16)
> +#define LCD_WR_SETUP(x)                        ((x) << 12)
> +#define LCD_WR_ACT(x)                  ((x) << 8)
> +#define LCD_WR_HOLD(x)                 ((x) << 4)
> +#define I80IFEN_ENABLE                 (1 << 0)
> +
>  /* FIMD has totally five hardware windows. */
>  #define WINDOWS_NR     5
>
> @@ -67,10 +88,14 @@
>
>  struct fimd_driver_data {
>         unsigned int timing_base;
> +       unsigned int lcdblk_off;
> +       unsigned int lcdblk_vt_shift;
> +       unsigned int lcdblk_bypass_shift;
>
>         unsigned int has_shadowcon:1;
>         unsigned int has_clksel:1;
>         unsigned int has_limited_fmt:1;
> +       unsigned int has_vidoutcon:1;
>  };
>
>  static struct fimd_driver_data s3c64xx_fimd_driver_data = {
> @@ -81,12 +106,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
>
>  static struct fimd_driver_data exynos4_fimd_driver_data = {
>         .timing_base = 0x0,
> +       .lcdblk_off = 0x210,
> +       .lcdblk_vt_shift = 10,
> +       .lcdblk_bypass_shift = 1,
>         .has_shadowcon = 1,
>  };
>
>  static struct fimd_driver_data exynos5_fimd_driver_data = {
>         .timing_base = 0x20000,
> +       .lcdblk_off = 0x214,
> +       .lcdblk_vt_shift = 24,
> +       .lcdblk_bypass_shift = 15,
>         .has_shadowcon = 1,
> +       .has_vidoutcon = 1,
>  };
>
>  struct fimd_win_data {
> @@ -111,15 +143,23 @@ struct fimd_context {
>         struct clk                      *bus_clk;
>         struct clk                      *lcd_clk;
>         void __iomem                    *regs;
> +       struct regmap                   *sysreg;
>         struct drm_display_mode         mode;
>         struct fimd_win_data            win_data[WINDOWS_NR];
>         unsigned int                    default_win;
>         unsigned long                   irq_flags;
> +       u32                             vidcon0;
>         u32                             vidcon1;
> +       u32                             vidout_con;
> +       u32                             i80ifcon;
> +       bool                            i80_if;
>         bool                            suspended;
>         int                             pipe;
>         wait_queue_head_t               wait_vsync_queue;
>         atomic_t                        wait_vsync_event;
> +       atomic_t                        win_updated;
> +       atomic_t                        triggering;
> +       spinlock_t                      win_updated_lock;
>
>         struct exynos_drm_panel_info panel;
>         struct fimd_driver_data *driver_data;
> @@ -242,6 +282,14 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
>         unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
>         u32 clkdiv;
>
> +       if (ctx->i80_if) {
> +               /*
> +                * The frame done interrupt should be occurred prior to the
> +                * next TE signal.
> +                */
> +               ideal_clk *= 2;
> +       }
> +
>         /* Find the clock divider value that gets us closest to ideal_clk */
>         clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->lcd_clk), ideal_clk);
>
> @@ -264,17 +312,23 @@ static void fimd_mode_set(struct exynos_drm_manager *mgr,
>         struct fimd_context *ctx = mgr->ctx;
>
>         drm_mode_copy(&ctx->mode, in_mode);
> +
> +       if (ctx->i80_if) {
> +               ctx->i80ifcon = LCD_CS_SETUP(in_mode->cs_setup);
> +               ctx->i80ifcon |= LCD_WR_SETUP(in_mode->wr_setup);
> +               ctx->i80ifcon |= LCD_WR_ACT(in_mode->wr_active);
> +               ctx->i80ifcon |= LCD_WR_HOLD(in_mode->wr_hold);
> +       }
>  }
>
>  static void fimd_commit(struct exynos_drm_manager *mgr)
>  {
>         struct fimd_context *ctx = mgr->ctx;
>         struct drm_display_mode *mode = &ctx->mode;
> -       struct fimd_driver_data *driver_data;
> -       u32 val, clkdiv, vidcon1;
> -       int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
> +       struct fimd_driver_data *driver_data = ctx->driver_data;
> +       void *timing_base = ctx->regs + driver_data->timing_base;
> +       u32 val, clkdiv;
>
> -       driver_data = ctx->driver_data;
>         if (ctx->suspended)
>                 return;
>
> @@ -282,33 +336,65 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
>         if (mode->htotal == 0 || mode->vtotal == 0)
>                 return;
>
> -       /* setup polarity values */
> -       vidcon1 = ctx->vidcon1;
> -       if (mode->flags & DRM_MODE_FLAG_NVSYNC)
> -               vidcon1 |= VIDCON1_INV_VSYNC;
> -       if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> -               vidcon1 |= VIDCON1_INV_HSYNC;
> -       writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
> -
> -       /* setup vertical timing values. */
> -       vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
> -       vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
> -       vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
> -
> -       val = VIDTCON0_VBPD(vbpd - 1) |
> -               VIDTCON0_VFPD(vfpd - 1) |
> -               VIDTCON0_VSPW(vsync_len - 1);
> -       writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
> -
> -       /* setup horizontal timing values.  */
> -       hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
> -       hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
> -       hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
> -
> -       val = VIDTCON1_HBPD(hbpd - 1) |
> -               VIDTCON1_HFPD(hfpd - 1) |
> -               VIDTCON1_HSPW(hsync_len - 1);
> -       writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
> +       if (ctx->i80_if) {
> +               val = ctx->i80ifcon | I80IFEN_ENABLE;
> +               writel(val, timing_base + I80IFCONFAx(0));
> +
> +               /* disable auto frame rate */
> +               writel(0, timing_base + I80IFCONFBx(0));
> +
> +               if (ctx->vidout_con)
> +                       writel(ctx->vidout_con, timing_base + VIDOUT_CON);
> +
> +               /* set video type selection to i80 interface */
> +               if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
> +                                       driver_data->lcdblk_off,
> +                                       0x3 << driver_data->lcdblk_vt_shift,
> +                                       0x1 << driver_data->lcdblk_vt_shift)) {
> +                       DRM_ERROR("Failed to update sysreg for i80 i/f.\n");
> +                       return;
> +               }
> +       } else {
> +               int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
> +               u32 vidcon1;
> +
> +               /* setup polarity values */
> +               vidcon1 = ctx->vidcon1;
> +               if (mode->flags & DRM_MODE_FLAG_NVSYNC)
> +                       vidcon1 |= VIDCON1_INV_VSYNC;
> +               if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> +                       vidcon1 |= VIDCON1_INV_HSYNC;
> +               writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
> +
> +               /* setup vertical timing values. */
> +               vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
> +               vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
> +               vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
> +
> +               val = VIDTCON0_VBPD(vbpd - 1) |
> +                       VIDTCON0_VFPD(vfpd - 1) |
> +                       VIDTCON0_VSPW(vsync_len - 1);
> +               writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
> +
> +               /* setup horizontal timing values.  */
> +               hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
> +               hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
> +               hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
> +
> +               val = VIDTCON1_HBPD(hbpd - 1) |
> +                       VIDTCON1_HFPD(hfpd - 1) |
> +                       VIDTCON1_HSPW(hsync_len - 1);
> +               writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
> +       }
> +
> +       /* set bypass selection */
> +       if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
> +                               driver_data->lcdblk_off,
> +                               0x1 << driver_data->lcdblk_bypass_shift,
> +                               0x1 << driver_data->lcdblk_bypass_shift)) {
> +               DRM_ERROR("Failed to update sysreg for bypass setting.\n");
> +               return;
> +       }
>
>         /* setup horizontal and vertical display size. */
>         val = VIDTCON2_LINEVAL(mode->vdisplay - 1) |
> @@ -646,6 +732,14 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
>         }
>
>         win_data->enabled = true;
> +
> +       if (ctx->i80_if) {
> +               unsigned long flags;
> +
> +               spin_lock_irqsave(&ctx->win_updated_lock, flags);
> +               atomic_set(&ctx->win_updated, 1);
> +               spin_unlock_irqrestore(&ctx->win_updated_lock, flags);
> +       }
>  }
>
>  static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
> @@ -835,6 +929,68 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
>         }
>  }
>
> +static void fimd_trigger(struct device *dev)
> +{
> +       struct exynos_drm_manager *mgr = get_fimd_manager(dev);
> +       struct fimd_context *ctx = mgr->ctx;
> +       struct fimd_driver_data *driver_data = ctx->driver_data;
> +       void *timing_base = ctx->regs + driver_data->timing_base;
> +       u32 reg;
> +
> +       atomic_set(&ctx->triggering, 1);
> +
> +       reg = readl(ctx->regs + VIDINTCON0);
> +       reg |= (VIDINTCON0_INT_ENABLE | VIDINTCON0_INT_I80IFDONE |
> +                                               VIDINTCON0_INT_SYSMAINCON);
> +       writel(reg, ctx->regs + VIDINTCON0);
> +
> +       reg = readl(timing_base + TRIGCON);
> +       reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE);
> +       writel(reg, timing_base + TRIGCON);
> +}
> +
> +static int fimd_te_handler(struct exynos_drm_manager *mgr)
> +{
> +       struct fimd_context *ctx = mgr->ctx;
> +       unsigned long flags;
> +
> +       /* check the crtc is detached already from encoder */
> +       if (ctx->pipe < 0 || !ctx->drm_dev)
> +               return -EINVAL;
> +
> +        /*
> +        * Skips to trigger if in triggering state, because multiple triggering
> +        * requests can cause panel reset.
> +        */
> +       if (atomic_read(&ctx->triggering))
> +               return 0;
> +
> +       spin_lock_irqsave(&ctx->win_updated_lock, flags);
> +
> +       /*
> +        * If there is a page flip request, triggers and handles the page flip
> +        * event so that current fb can be updated into panel GRAM.
> +        */
> +       if (atomic_read(&ctx->win_updated)) {
> +               atomic_set(&ctx->win_updated, 0);
> +
> +               fimd_trigger(ctx->dev);
> +       }
> +
> +       spin_unlock_irqrestore(&ctx->win_updated_lock, flags);
> +
> +       /* wake up vsync event queue */
> +       if (atomic_read(&ctx->wait_vsync_event)) {
> +               atomic_set(&ctx->wait_vsync_event, 0);
> +               wake_up(&ctx->wait_vsync_queue);
> +
> +               if (!atomic_read(&ctx->triggering))
> +                       drm_handle_vblank(ctx->drm_dev, ctx->pipe);
> +       }
> +
> +       return 0;
> +}
> +
>  static struct exynos_drm_manager_ops fimd_manager_ops = {
>         .dpms = fimd_dpms,
>         .mode_fixup = fimd_mode_fixup,
> @@ -846,6 +1002,7 @@ static struct exynos_drm_manager_ops fimd_manager_ops = {
>         .win_mode_set = fimd_win_mode_set,
>         .win_commit = fimd_win_commit,
>         .win_disable = fimd_win_disable,
> +       .te_handler = fimd_te_handler,
>  };
>
>  static struct exynos_drm_manager fimd_manager = {
> @@ -856,26 +1013,40 @@ static struct exynos_drm_manager fimd_manager = {
>  static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
>  {
>         struct fimd_context *ctx = (struct fimd_context *)dev_id;
> -       u32 val;
> +       u32 val, clear_bit;
>
>         val = readl(ctx->regs + VIDINTCON1);
>
> -       if (val & VIDINTCON1_INT_FRAME)
> -               /* VSYNC interrupt */
> -               writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1);
> +       clear_bit = ctx->i80_if ? VIDINTCON1_INT_I80 : VIDINTCON1_INT_FRAME;
> +       if (val & clear_bit)
> +               writel(clear_bit, ctx->regs + VIDINTCON1);
>
>         /* check the crtc is detached already from encoder */
>         if (ctx->pipe < 0 || !ctx->drm_dev)
>                 goto out;
>
> -       drm_handle_vblank(ctx->drm_dev, ctx->pipe);
> -       exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
> +       if (ctx->i80_if) {
> +               /* unset i80 frame done interrupt */
> +               val = readl(ctx->regs + VIDINTCON0);
> +               val &= ~(VIDINTCON0_INT_I80IFDONE | VIDINTCON0_INT_SYSMAINCON);
> +               writel(val, ctx->regs + VIDINTCON0);
>
> -       /* set wait vsync event to zero and wake up queue. */
> -       if (atomic_read(&ctx->wait_vsync_event)) {
> -               atomic_set(&ctx->wait_vsync_event, 0);
> -               wake_up(&ctx->wait_vsync_queue);
> +               /* exit triggering mode */
> +               atomic_set(&ctx->triggering, 0);
> +
> +               drm_handle_vblank(ctx->drm_dev, ctx->pipe);
> +               exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
> +       } else {
> +               drm_handle_vblank(ctx->drm_dev, ctx->pipe);
> +               exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
> +
> +               /* set wait vsync event to zero and wake up queue. */
> +               if (atomic_read(&ctx->wait_vsync_event)) {
> +                       atomic_set(&ctx->wait_vsync_event, 0);
> +                       wake_up(&ctx->wait_vsync_queue);
> +               }
>         }
> +
>  out:
>         return IRQ_HANDLED;
>  }
> @@ -936,12 +1107,32 @@ static int fimd_probe(struct platform_device *pdev)
>
>         ctx->dev = dev;
>         ctx->suspended = true;
> +       ctx->driver_data = drm_fimd_get_driver_data(pdev);
>
>         if (of_property_read_bool(dev->of_node, "samsung,invert-vden"))
>                 ctx->vidcon1 |= VIDCON1_INV_VDEN;
>         if (of_property_read_bool(dev->of_node, "samsung,invert-vclk"))
>                 ctx->vidcon1 |= VIDCON1_INV_VCLK;
>
> +       if (of_property_read_bool(dev->of_node, "vidout-i80-ldi")) {
> +               ctx->i80_if = true;
> +
> +               if (ctx->driver_data->has_vidoutcon)
> +                       ctx->vidout_con |= VIDOUT_CON_F_I80_LDI0;
> +               else
> +                       ctx->vidcon0 |= VIDCON0_VIDOUT_I80_LDI0;
> +               ctx->vidcon0 |= VIDCON0_DSI_EN;
> +
> +               spin_lock_init(&ctx->win_updated_lock);
> +       }
> +
> +       ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
> +                                                       "samsung,sysreg");
> +       if (IS_ERR(ctx->sysreg)) {
> +               dev_warn(dev, "failed to get system register.\n");
> +               ctx->sysreg = NULL;
> +       }
> +
>         ctx->bus_clk = devm_clk_get(dev, "fimd");
>         if (IS_ERR(ctx->bus_clk)) {
>                 dev_err(dev, "failed to get bus clock\n");
> @@ -960,7 +1151,8 @@ static int fimd_probe(struct platform_device *pdev)
>         if (IS_ERR(ctx->regs))
>                 return PTR_ERR(ctx->regs);
>
> -       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync");
> +       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
> +                                       ctx->i80_if ? "lcd_sys" : "vsync");
>         if (!res) {
>                 dev_err(dev, "irq request failed.\n");
>                 return -ENXIO;
> @@ -973,7 +1165,6 @@ static int fimd_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> -       ctx->driver_data = drm_fimd_get_driver_data(pdev);
>         init_waitqueue_head(&ctx->wait_vsync_queue);
>         atomic_set(&ctx->wait_vsync_event, 0);
>
> diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
> index b039320..eaad58b 100644
> --- a/include/video/samsung_fimd.h
> +++ b/include/video/samsung_fimd.h
> @@ -19,6 +19,7 @@
>  /* VIDCON0 */
>
>  #define VIDCON0                                        0x00
> +#define VIDCON0_DSI_EN                         (1 << 30)
>  #define VIDCON0_INTERLACE                      (1 << 29)
>  #define VIDCON0_VIDOUT_MASK                    (0x7 << 26)
>  #define VIDCON0_VIDOUT_SHIFT                   26
> @@ -355,7 +356,7 @@
>  #define VIDINTCON0_INT_ENABLE                  (1 << 0)
>
>  #define VIDINTCON1                             0x134
> -#define VIDINTCON1_INT_I180                    (1 << 2)
> +#define VIDINTCON1_INT_I80                     (1 << 2)
>  #define VIDINTCON1_INT_FRAME                   (1 << 1)
>  #define VIDINTCON1_INT_FIFO                    (1 << 0)
>
> --
> 1.7.9.5
>

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

* Re: [PATCH v2 04/18] video: add command mode and command mode display timing
  2014-05-21  4:42 ` [PATCH v2 04/18] video: add command mode and command mode display timing YoungJun Cho
  2014-05-21 11:02   ` Thierry Reding
@ 2014-05-26 10:14   ` Thierry Reding
  2014-05-26 11:10     ` Heiko Stübner
  1 sibling, 1 reply; 39+ messages in thread
From: Thierry Reding @ 2014-05-26 10:14 UTC (permalink / raw)
  To: YoungJun Cho, Heiko Stuebner
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, a.hajda, kyungmin.park,
	robh+dt, laurent.pinchart, galak, kgene.kim, s.trumtrar


[-- Attachment #1.1: Type: text/plain, Size: 20844 bytes --]

On Wed, May 21, 2014 at 01:42:56PM +0900, YoungJun Cho wrote:
> This patch is based on videomode and display_timing relevant codes.
> To support command mode panel, it does not need to guide its timing
> information to the display controller like video mode panel,
> but it requires signal timings to transfer video data.
> So this patch adds cmdmode struct, cmdmode_display_timing struct and
> the according helper functions to convert cmdmode_display_timing
> to a generic cmdmode.
> 
> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
> Acked-by: Inki Dae <inki.dae@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  drivers/video/Kconfig                     |    3 +
>  drivers/video/Makefile                    |    2 +
>  drivers/video/cmdmode.c                   |   42 ++++++
>  drivers/video/cmdmode_display_timing.c    |   26 ++++
>  drivers/video/of_cmdmode.c                |   55 ++++++++
>  drivers/video/of_cmdmode_display_timing.c |  212 +++++++++++++++++++++++++++++
>  include/video/cmdmode.h                   |   67 +++++++++
>  include/video/cmdmode_display_timing.h    |   59 ++++++++
>  include/video/of_cmdmode.h                |   19 +++
>  include/video/of_cmdmode_display_timing.h |   26 ++++
>  10 files changed, 511 insertions(+)
>  create mode 100644 drivers/video/cmdmode.c
>  create mode 100644 drivers/video/cmdmode_display_timing.c
>  create mode 100644 drivers/video/of_cmdmode.c
>  create mode 100644 drivers/video/of_cmdmode_display_timing.c
>  create mode 100644 include/video/cmdmode.h
>  create mode 100644 include/video/cmdmode_display_timing.h
>  create mode 100644 include/video/of_cmdmode.h
>  create mode 100644 include/video/of_cmdmode_display_timing.h

Cc'ing Heiko Stübner on this. Heiko, you seem to have done some work on
i80 in the past[0] and I'm wondering if you could share any insights you
may have here.

In particular I'd like your take on the approach taken in this patch to
describe i80 parameters to a generic command-mode display timings
structure. However it seems to me that these timings are really very i80
specific and don't apply in general to command-mode displays.

As such I'm beginning to think that this should rather be a property of
the attached display/panel rather than the interface that generates the
signal.

Thierry

[0]: https://lkml.org/lkml/2011/5/17/170

> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index c7b4f0f..7090ee5 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -38,6 +38,9 @@ config VGASTATE
>  config VIDEOMODE_HELPERS
>  	bool
>  
> +config CMDMODE_HELPERS
> +	bool
> +
>  config HDMI
>  	bool
>  
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index 9ad3c17..619dd99 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -8,6 +8,8 @@ obj-y				  += backlight/
>  obj-y				  += fbdev/
>  
>  obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o
> +obj-$(CONFIG_CMDMODE_HELPERS) += cmdmode_display_timing.o cmdmode.o
>  ifeq ($(CONFIG_OF),y)
>  obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o
> +obj-$(CONFIG_CMDMODE_HELPERS) += of_cmdmode_display_timing.o of_cmdmode.o
>  endif
> diff --git a/drivers/video/cmdmode.c b/drivers/video/cmdmode.c
> new file mode 100644
> index 0000000..3d3eeb8
> --- /dev/null
> +++ b/drivers/video/cmdmode.c
> @@ -0,0 +1,42 @@
> +/*
> + * generic cmdmode display timing functions
> + *
> + * Copyright (c) 2014 YoungJun Cho <yj44.cho@samsung.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.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/export.h>
> +#include <video/cmdmode_display_timing.h>
> +#include <video/cmdmode.h>
> +
> +void cmdmode_from_timing(const struct cmdmode_display_timing *cmdt,
> +				struct cmdmode *cm)
> +{
> +	cm->pixelclock = cmdt->pixelclock;
> +	cm->hactive = cmdt->hactive;
> +	cm->vactive = cmdt->vactive;
> +	cm->cs_setup = cmdt->cs_setup;
> +	cm->wr_setup = cmdt->wr_setup;
> +	cm->wr_active = cmdt->wr_active;
> +	cm->wr_hold = cmdt->wr_hold;
> +}
> +EXPORT_SYMBOL_GPL(cmdmode_from_timing);
> +
> +int cmdmode_from_timings(const struct cmdmode_display_timings *cmdts,
> +				struct cmdmode *cm, unsigned int index)
> +{
> +	struct cmdmode_display_timing *cmdt;
> +
> +	cmdt = cmdmode_display_timings_get(cmdts, index);
> +	if (!cmdt)
> +		return -EINVAL;
> +
> +	cmdmode_from_timing(cmdt, cm);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(cmdmode_from_timings);
> diff --git a/drivers/video/cmdmode_display_timing.c b/drivers/video/cmdmode_display_timing.c
> new file mode 100644
> index 0000000..88bab08
> --- /dev/null
> +++ b/drivers/video/cmdmode_display_timing.c
> @@ -0,0 +1,26 @@
> +/*
> + * generic cmdmode display timing functions
> + *
> + * Copyright (c) 2014 YoungJun Cho <yj44.cho@samsung.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.
> + */
> +
> +#include <linux/export.h>
> +#include <linux/slab.h>
> +#include <video/cmdmode_display_timing.h>
> +
> +void cmdmode_display_timings_release(struct cmdmode_display_timings *cmdts)
> +{
> +	if (cmdts->timings) {
> +		unsigned int i;
> +
> +		for (i = 0; i < cmdts->num_timings; i++)
> +			kfree(cmdts->timings[i]);
> +		kfree(cmdts->timings);
> +	}
> +	kfree(cmdts);
> +}
> +EXPORT_SYMBOL_GPL(cmdmode_display_timings_release);
> diff --git a/drivers/video/of_cmdmode.c b/drivers/video/of_cmdmode.c
> new file mode 100644
> index 0000000..d63294e
> --- /dev/null
> +++ b/drivers/video/of_cmdmode.c
> @@ -0,0 +1,55 @@
> +/*
> + * generic cmdmode helper
> + *
> + * Copyright (c) 2014 YoungJun Cho <yj44.cho@samsung.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.
> + */
> +#include <linux/errno.h>
> +#include <linux/export.h>
> +#include <linux/of.h>
> +#include <video/cmdmode_display_timing.h>
> +#include <video/of_cmdmode_display_timing.h>
> +#include <video/of_cmdmode.h>
> +#include <video/cmdmode.h>
> +
> +/**
> + * of_get_cmdmode - get the cmdmode #<index> from devicetree
> + * @np - devicenode with the cmdmode_display_timings
> + * @cm - set to return value
> + * @index - index into list of cmdmode_display_timings
> + *	    (Set this to OF_USE_CMDMODE_NATIVE_MODE to use whatever mode is
> + *	     specified as native mode in the DT.)
> + *
> + * DESCRIPTION:
> + * Get a list of all display timings and put the one
> + * specified by index into *cm. This function should only be used, if
> + * only one cmdmode is to be retrieved. A driver that needs to work
> + * with multiple/all cmdmodes should work with
> + * of_get_cmdmode_display_timings instead.
> + **/
> +int of_get_cmdmode(struct device_node *np, struct cmdmode *cm, int index)
> +{
> +	struct cmdmode_display_timings *cmdts;
> +	int ret;
> +
> +	cmdts = of_get_cmdmode_display_timings(np);
> +	if (!cmdts) {
> +		pr_err("%s: no timings specified\n", of_node_full_name(np));
> +		return -EINVAL;
> +	}
> +
> +	if (index == OF_USE_CMDMODE_NATIVE_MODE)
> +		index = cmdts->native_mode;
> +
> +	ret = cmdmode_from_timings(cmdts, cm, index);
> +	if (ret)
> +		return ret;
> +
> +	cmdmode_display_timings_release(cmdts);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_get_cmdmode);
> diff --git a/drivers/video/of_cmdmode_display_timing.c b/drivers/video/of_cmdmode_display_timing.c
> new file mode 100644
> index 0000000..fcf2b35
> --- /dev/null
> +++ b/drivers/video/of_cmdmode_display_timing.c
> @@ -0,0 +1,212 @@
> +/*
> + * OF helpers for parsing cmdmode display timings
> + *
> + * Copyright (c) 2014 YoungJun Cho <yj44.cho@samsung.com>
> + *
> + * based on of_cmdmode.c
> + *
> + * 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.
> + */
> +#include <linux/export.h>
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +#include <video/cmdmode_display_timing.h>
> +#include <video/of_cmdmode_display_timing.h>
> +
> +/**
> + * of_parse_cmdmode_display_timing - parse cmdmode_display_timing entry
> + *					from device_node
> + * @np: device_node with the properties
> + **/
> +static int of_parse_cmdmode_display_timing(const struct device_node *np,
> +					struct cmdmode_display_timing *cmdt)
> +{
> +	int ret = 0;
> +
> +	memset(cmdt, 0, sizeof(*cmdt));
> +
> +	ret |= of_property_read_u32(np, "clock-frequency", &cmdt->pixelclock);
> +	ret |= of_property_read_u32(np, "hactive", &cmdt->hactive);
> +	ret |= of_property_read_u32(np, "vactive", &cmdt->vactive);
> +	ret |= of_property_read_u32(np, "cs-setup", &cmdt->cs_setup);
> +	ret |= of_property_read_u32(np, "wr-setup", &cmdt->wr_setup);
> +	ret |= of_property_read_u32(np, "wr-active", &cmdt->wr_active);
> +	ret |= of_property_read_u32(np, "wr-hold", &cmdt->wr_hold);
> +
> +	if (ret) {
> +		pr_err("%s: error reading cmdmode timing properties\n",
> +			of_node_full_name(np));
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * of_get_cmdmode_display_timing - parse a cmdmode_display_timing entry
> + * @np: device_node with the timing subnode
> + * @name: name of the timing node
> + * @cmdt: cmdmode_display_timing struct to fill
> + **/
> +int of_get_cmdmode_display_timing(struct device_node *np, const char *name,
> +					struct cmdmode_display_timing *cmdt)
> +{
> +	struct device_node *timing_np;
> +
> +	if (!np) {
> +		pr_err("%s: no devicenode given\n", of_node_full_name(np));
> +		return -EINVAL;
> +	}
> +
> +	timing_np = of_get_child_by_name(np, name);
> +	if (!timing_np) {
> +		pr_err("%s: could not find node '%s'\n",
> +			of_node_full_name(np), name);
> +		return -ENOENT;
> +	}
> +
> +	return of_parse_cmdmode_display_timing(timing_np, cmdt);
> +}
> +EXPORT_SYMBOL_GPL(of_get_cmdmode_display_timing);
> +
> +/**
> + * of_get_cmdmode_display_timings - parse all cmdmode_display_timing
> + * entries from a device_node
> + * @np: device_node with the subnodes
> + **/
> +struct cmdmode_display_timings*
> +of_get_cmdmode_display_timings(struct device_node *np)
> +{
> +	struct device_node *timings_np;
> +	struct device_node *entry;
> +	struct device_node *native_mode;
> +	struct cmdmode_display_timings *cmdts;
> +
> +	if (!np) {
> +		pr_err("%s: no device node given\n", of_node_full_name(np));
> +		return NULL;
> +	}
> +
> +	timings_np = of_get_child_by_name(np, "cmdmode-display-timings");
> +	if (!timings_np) {
> +		pr_err("%s: could not find cmdmode-display-timings node\n",
> +			of_node_full_name(np));
> +		return NULL;
> +	}
> +
> +	cmdts = kzalloc(sizeof(*cmdts), GFP_KERNEL);
> +	if (!cmdts) {
> +		pr_err("%s: could not allocate struct cmdts'\n",
> +			of_node_full_name(np));
> +		goto cmdtsfail;
> +	}
> +
> +	entry = of_parse_phandle(timings_np, "native-mode", 0);
> +	/* assume first child as native mode if none provided */
> +	if (!entry)
> +		entry = of_get_next_child(np, NULL);
> +	/* if there is no child, it is useless to go on */
> +	if (!entry) {
> +		pr_err("%s: no timing specifications given\n",
> +			of_node_full_name(np));
> +		goto entryfail;
> +	}
> +
> +	pr_debug("%s: using %s as default timing\n",
> +		of_node_full_name(np), entry->name);
> +
> +	native_mode = entry;
> +
> +	cmdts->num_timings = of_get_child_count(timings_np);
> +	if (cmdts->num_timings == 0) {
> +		/* should never happen, as entry was already found above */
> +		pr_err("%s: no timings specified\n", of_node_full_name(np));
> +		goto entryfail;
> +	}
> +
> +	cmdts->timings = kzalloc(sizeof(struct cmdmode_display_timing *) *
> +				cmdts->num_timings, GFP_KERNEL);
> +	if (!cmdts->timings) {
> +		pr_err("%s: could not allocate timings array\n",
> +			of_node_full_name(np));
> +		goto entryfail;
> +	}
> +
> +	cmdts->num_timings = 0;
> +	cmdts->native_mode = 0;
> +
> +	for_each_child_of_node(timings_np, entry) {
> +		struct cmdmode_display_timing *cmdt;
> +		int r;
> +
> +		cmdt = kzalloc(sizeof(*cmdt), GFP_KERNEL);
> +		if (!cmdt) {
> +			pr_err("%s: could not allocate cmdmode_display_timing\n"
> +				, of_node_full_name(np));
> +			goto timingfail;
> +		}
> +
> +		r = of_parse_cmdmode_display_timing(entry, cmdt);
> +		if (r) {
> +			/*
> +			 * to not encourage wrong devicetrees, fail in case of
> +			 * an error
> +			 */
> +			pr_err("%s: error in timing %d\n",
> +				of_node_full_name(np), cmdts->num_timings + 1);
> +			goto timingfail;
> +		}
> +
> +		if (native_mode == entry)
> +			cmdts->native_mode = cmdts->num_timings;
> +
> +		cmdts->timings[cmdts->num_timings] = cmdt;
> +		cmdts->num_timings++;
> +	}
> +	of_node_put(timings_np);
> +	/*
> +	 * native_mode points to the device_node returned by of_parse_phandle
> +	 * therefore call of_node_put on it
> +	 */
> +	of_node_put(native_mode);
> +
> +	pr_debug("%s: got %d timings. Using timing #%d as default\n",
> +		of_node_full_name(np), cmdts->num_timings,
> +		cmdts->native_mode + 1);
> +
> +	return cmdts;
> +
> +timingfail:
> +	if (native_mode)
> +		of_node_put(native_mode);
> +	cmdmode_display_timings_release(cmdts);
> +entryfail:
> +	kfree(cmdts);
> +cmdtsfail:
> +	of_node_put(timings_np);
> +	return NULL;
> +}
> +EXPORT_SYMBOL_GPL(of_get_cmdmode_display_timings);
> +
> +/**
> + * of_cmdmode_display_timings_exist - check if a display-timings node is
> + * provided
> + * @np: device_node with the timing
> + **/
> +int of_cmdmode_display_timings_exist(struct device_node *np)
> +{
> +	struct device_node *timings_np;
> +
> +	if (!np)
> +		return -EINVAL;
> +
> +	timings_np = of_parse_phandle(np, "cmdmode-display-timings", 0);
> +	if (!timings_np)
> +		return -EINVAL;
> +
> +	of_node_put(timings_np);
> +	return 1;
> +}
> +EXPORT_SYMBOL_GPL(of_cmdmode_display_timings_exist);
> diff --git a/include/video/cmdmode.h b/include/video/cmdmode.h
> new file mode 100644
> index 0000000..61ee71e
> --- /dev/null
> +++ b/include/video/cmdmode.h
> @@ -0,0 +1,67 @@
> +/*
> + * generic cmdmode description
> + *
> + * Copyright 2014 YoungJun Cho <yj44.cho@samsung.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 __LINUX_CMDMODE_H
> +#define __LINUX_CMDMODE_H
> +
> +#include <linux/types.h>
> +#include <video/cmdmode_display_timing.h>
> +
> +/*
> + * Subsystem independent description of a cmdmode.
> + * Can be generated from struct cmdmode_display_timing.
> + * @pixelclock: display clock in Hz
> + * @hactive: horizontal active video
> + * @vactive: vertical active video
> + * @cs_setup: clock cycles for the active period of address signal is enabled
> + *		until chip select is enabled
> + * @wr_setup: clock cycles for the active period of CS signal is enabled until
> + *		write signal is enabled
> + * @wr_active: clock cycles for the active period of CS is enabled
> + * @wr_hold: clock cycles for the active period of CS is disabled until write
> + *		signal is disabled
> + */
> +struct cmdmode {
> +	unsigned long pixelclock;
> +
> +	u32 hactive;
> +	u32 vactive;
> +
> +	u32 cs_setup;
> +	u32 wr_setup;
> +	u32 wr_active;
> +	u32 wr_hold;
> +};
> +
> +/**
> + * cmdmode_from_timing - convert display timing to cmdmode
> + * @cmdt: cmdmode_display_timing structure
> + * @cm: return value
> + *
> + * DESCRIPTION:
> + * This function converts a struct cmdmode_display_timing to a struct cmdmode.
> + */
> +void cmdmode_from_timing(const struct cmdmode_display_timing *cmdt,
> +				struct cmdmode *cm);
> +
> +/**
> + * cmdmode_from_timings - convert one display timings entry to cmdmode
> + * @disp: structure with all possible timing entries
> + * @cm: return value
> + * @index: index into the list of display timings in devicetree
> + *
> + * DESCRIPTION:
> + * This function converts one struct cmdmode_display_timing entry to a
> + * struct cmdmode.
> + */
> +int cmdmode_from_timings(const struct cmdmode_display_timings *cmdts,
> +				struct cmdmode *cm, unsigned int index);
> +
> +#endif /* __LINUX_CMDMODE_H */
> diff --git a/include/video/cmdmode_display_timing.h b/include/video/cmdmode_display_timing.h
> new file mode 100644
> index 0000000..5005660
> --- /dev/null
> +++ b/include/video/cmdmode_display_timing.h
> @@ -0,0 +1,59 @@
> +/*
> + * description of cmdmode display timings
> + *
> + * Copyright 2014 YoungJun Cho <yj44.cho@samsung.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 __LINUX_CMDMODE_DISPLAY_TIMING_H
> +#define __LINUX_CMDMODE_DISPLAY_TIMING_H
> +
> +#include <linux/types.h>
> +
> +/*
> + * Single "mode" entry. This describes one set of signal timings a display can
> + * have in one setting. This struct can later be converted to struct cmdmode
> + * (see include/video/cmdmode.h).
> + */
> +struct cmdmode_display_timing {
> +	u32	pixelclock;
> +
> +	u32	hactive;
> +	u32	vactive;
> +
> +	u32	cs_setup;
> +	u32	wr_setup;
> +	u32	wr_active;
> +	u32	wr_hold;
> +};
> +
> +/*
> + * This describes all timing settings a display provides.
> + * The native_mode is the default setting for this display.
> + * Drivers that can handle multiple cmdmodes should work with this struct
> + * and convert each entry to the desired end result.
> + */
> +struct cmdmode_display_timings {
> +	unsigned int num_timings;
> +	unsigned int native_mode;
> +
> +	struct cmdmode_display_timing **timings;
> +};
> +
> +/* get one entry from struct cmdmode_display_timings */
> +static inline struct cmdmode_display_timing*
> +cmdmode_display_timings_get(const struct cmdmode_display_timings *cmdts,
> +				unsigned int index)
> +{
> +	if (cmdts->num_timings > index)
> +		return cmdts->timings[index];
> +	else
> +		return NULL;
> +}
> +
> +void cmdmode_display_timings_release(struct cmdmode_display_timings *cmdts);
> +
> +#endif /* __LINUX_CMDDMODE_DISPLAY_TIMING_H */
> diff --git a/include/video/of_cmdmode.h b/include/video/of_cmdmode.h
> new file mode 100644
> index 0000000..fb7c6c7
> --- /dev/null
> +++ b/include/video/of_cmdmode.h
> @@ -0,0 +1,19 @@
> +/*
> + * Copyright 2014 YoungJun Cho <yj44.cho@samsung.com>
> + *
> + * cmdmode of-helpers
> + *
> + * 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 __LINUX_OF_CMDMODE_H
> +#define __LINUX_OF_CMDMODE_H
> +
> +struct device_node;
> +struct cmdmode;
> +
> +int of_get_cmdmode(struct device_node *np, struct cmdmode *cm, int index);
> +
> +#endif /* __LINUX_OF_CMDMODE_H */
> diff --git a/include/video/of_cmdmode_display_timing.h b/include/video/of_cmdmode_display_timing.h
> new file mode 100644
> index 0000000..6be91ba
> --- /dev/null
> +++ b/include/video/of_cmdmode_display_timing.h
> @@ -0,0 +1,26 @@
> +/*
> + * Copyright 2014 YoungJun Cho <yj44.cho@samsung.com>
> + *
> + * cmdmode display timings of helpers
> + *
> + * 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 __LINUX_OF_CMDMODE_DISPLAY_TIMING_H
> +#define __LINUX_OF_CMDMODE_DISPLAY_TIMING_H
> +
> +struct device_node;
> +struct cmdmode_display_timing;
> +struct cmdmode_display_timings;
> +
> +#define OF_USE_CMDMODE_NATIVE_MODE -1
> +
> +int of_get_cmdmode_display_timing(struct device_node *np, const char *name,
> +					struct cmdmode_display_timing *cmdt);
> +struct cmdmode_display_timings*
> +	of_get_cmdmode_display_timings(struct device_node *np);
> +int of_cmdmode_display_timings_exist(struct device_node *np);
> +
> +#endif /* __LINUX_OF_CMDMODE_DISPLAY_TIMING_H */
> -- 
> 1.7.9.5
> 

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v2 04/18] video: add command mode and command mode display timing
  2014-05-26 10:14   ` Thierry Reding
@ 2014-05-26 11:10     ` Heiko Stübner
  0 siblings, 0 replies; 39+ messages in thread
From: Heiko Stübner @ 2014-05-26 11:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: YoungJun Cho, airlied-cv59FeDIM0c,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw,
	s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ,
	djkurtz-F7+t8E8rja9g9hUCZPvPmw,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	inki.dae-Sze3O3UU22JBDgjK7y7TUQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ,
	sw0312.kim-Sze3O3UU22JBDgjK7y7TUQ,
	a.hajda-Sze3O3UU22JBDgjK7y7TUQ

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

Am Montag, 26. Mai 2014, 12:14:43 schrieb Thierry Reding:
> On Wed, May 21, 2014 at 01:42:56PM +0900, YoungJun Cho wrote:
> > This patch is based on videomode and display_timing relevant codes.
> > To support command mode panel, it does not need to guide its timing
> > information to the display controller like video mode panel,
> > but it requires signal timings to transfer video data.
> > So this patch adds cmdmode struct, cmdmode_display_timing struct and
> > the according helper functions to convert cmdmode_display_timing
> > to a generic cmdmode.
> > 
> > Signed-off-by: YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > Acked-by: Inki Dae <inki.dae-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > ---
> > 
> >  drivers/video/Kconfig                     |    3 +
> >  drivers/video/Makefile                    |    2 +
> >  drivers/video/cmdmode.c                   |   42 ++++++
> >  drivers/video/cmdmode_display_timing.c    |   26 ++++
> >  drivers/video/of_cmdmode.c                |   55 ++++++++
> >  drivers/video/of_cmdmode_display_timing.c |  212
> >  +++++++++++++++++++++++++++++ include/video/cmdmode.h                  
> >  |   67 +++++++++
> >  include/video/cmdmode_display_timing.h    |   59 ++++++++
> >  include/video/of_cmdmode.h                |   19 +++
> >  include/video/of_cmdmode_display_timing.h |   26 ++++
> >  10 files changed, 511 insertions(+)
> >  create mode 100644 drivers/video/cmdmode.c
> >  create mode 100644 drivers/video/cmdmode_display_timing.c
> >  create mode 100644 drivers/video/of_cmdmode.c
> >  create mode 100644 drivers/video/of_cmdmode_display_timing.c
> >  create mode 100644 include/video/cmdmode.h
> >  create mode 100644 include/video/cmdmode_display_timing.h
> >  create mode 100644 include/video/of_cmdmode.h
> >  create mode 100644 include/video/of_cmdmode_display_timing.h
> 
> Cc'ing Heiko Stübner on this. Heiko, you seem to have done some work on
> i80 in the past[0] and I'm wondering if you could share any insights you
> may have here.
> 
> In particular I'd like your take on the approach taken in this patch to
> describe i80 parameters to a generic command-mode display timings
> structure. However it seems to me that these timings are really very i80
> specific and don't apply in general to command-mode displays.
> 
> As such I'm beginning to think that this should rather be a property of
> the attached display/panel rather than the interface that generates the
> signal.

OMG ... your digging in my ancient history :-D

I always got the impression, i80 is somehow related to the MIPI-DBI protocol 
[1].

Also the display I was working on (AUO-K190x epaper controller) used the 
command mode to also transfer the display region to update and had a 
completely dfferent command set [2].

In the end, I temporarily settled in adding a glue driver, driving the s3c2416 
i80 controller [3]. But someday I'd like to integrate this into a real 
solution, as the s3c2416 lcd-controller can do the i80 also in hardware, maybe 
speeding things up a little.

So I guess the transfer method itself is generic, but the commands used seem 
to differ. But I of course don't know if "regular" MIPI-DBI/i80 displays use a 
command set of commands for their timings.


Heiko


[1] https://www.mail-archive.com/linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org/msg29100.html
[2] 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/video/fbdev/auo_k190x.h
[3] https://github.com/mmind/linux-es600/blob/topic/es600-devel/drivers/video/es600-epd.c

> > diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> > index c7b4f0f..7090ee5 100644
> > --- a/drivers/video/Kconfig
> > +++ b/drivers/video/Kconfig
> > @@ -38,6 +38,9 @@ config VGASTATE
> > 
> >  config VIDEOMODE_HELPERS
> >  
> >  	bool
> > 
> > +config CMDMODE_HELPERS
> > +	bool
> > +
> > 
> >  config HDMI
> >  
> >  	bool
> > 
> > diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> > index 9ad3c17..619dd99 100644
> > --- a/drivers/video/Makefile
> > +++ b/drivers/video/Makefile
> > @@ -8,6 +8,8 @@ obj-y				  += backlight/
> > 
> >  obj-y				  += fbdev/
> >  
> >  obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o
> > 
> > +obj-$(CONFIG_CMDMODE_HELPERS) += cmdmode_display_timing.o cmdmode.o
> > 
> >  ifeq ($(CONFIG_OF),y)
> >  obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o
> > 
> > +obj-$(CONFIG_CMDMODE_HELPERS) += of_cmdmode_display_timing.o of_cmdmode.o
> > 
> >  endif
> > 
> > diff --git a/drivers/video/cmdmode.c b/drivers/video/cmdmode.c
> > new file mode 100644
> > index 0000000..3d3eeb8
> > --- /dev/null
> > +++ b/drivers/video/cmdmode.c
> > @@ -0,0 +1,42 @@
> > +/*
> > + * generic cmdmode display timing functions
> > + *
> > + * Copyright (c) 2014 YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > + *
> > + * 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.
> > + */
> > +
> > +#include <linux/errno.h>
> > +#include <linux/export.h>
> > +#include <video/cmdmode_display_timing.h>
> > +#include <video/cmdmode.h>
> > +
> > +void cmdmode_from_timing(const struct cmdmode_display_timing *cmdt,
> > +				struct cmdmode *cm)
> > +{
> > +	cm->pixelclock = cmdt->pixelclock;
> > +	cm->hactive = cmdt->hactive;
> > +	cm->vactive = cmdt->vactive;
> > +	cm->cs_setup = cmdt->cs_setup;
> > +	cm->wr_setup = cmdt->wr_setup;
> > +	cm->wr_active = cmdt->wr_active;
> > +	cm->wr_hold = cmdt->wr_hold;
> > +}
> > +EXPORT_SYMBOL_GPL(cmdmode_from_timing);
> > +
> > +int cmdmode_from_timings(const struct cmdmode_display_timings *cmdts,
> > +				struct cmdmode *cm, unsigned int index)
> > +{
> > +	struct cmdmode_display_timing *cmdt;
> > +
> > +	cmdt = cmdmode_display_timings_get(cmdts, index);
> > +	if (!cmdt)
> > +		return -EINVAL;
> > +
> > +	cmdmode_from_timing(cmdt, cm);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(cmdmode_from_timings);
> > diff --git a/drivers/video/cmdmode_display_timing.c
> > b/drivers/video/cmdmode_display_timing.c new file mode 100644
> > index 0000000..88bab08
> > --- /dev/null
> > +++ b/drivers/video/cmdmode_display_timing.c
> > @@ -0,0 +1,26 @@
> > +/*
> > + * generic cmdmode display timing functions
> > + *
> > + * Copyright (c) 2014 YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > + *
> > + * 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.
> > + */
> > +
> > +#include <linux/export.h>
> > +#include <linux/slab.h>
> > +#include <video/cmdmode_display_timing.h>
> > +
> > +void cmdmode_display_timings_release(struct cmdmode_display_timings
> > *cmdts) +{
> > +	if (cmdts->timings) {
> > +		unsigned int i;
> > +
> > +		for (i = 0; i < cmdts->num_timings; i++)
> > +			kfree(cmdts->timings[i]);
> > +		kfree(cmdts->timings);
> > +	}
> > +	kfree(cmdts);
> > +}
> > +EXPORT_SYMBOL_GPL(cmdmode_display_timings_release);
> > diff --git a/drivers/video/of_cmdmode.c b/drivers/video/of_cmdmode.c
> > new file mode 100644
> > index 0000000..d63294e
> > --- /dev/null
> > +++ b/drivers/video/of_cmdmode.c
> > @@ -0,0 +1,55 @@
> > +/*
> > + * generic cmdmode helper
> > + *
> > + * Copyright (c) 2014 YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > + *
> > + * 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.
> > + */
> > +#include <linux/errno.h>
> > +#include <linux/export.h>
> > +#include <linux/of.h>
> > +#include <video/cmdmode_display_timing.h>
> > +#include <video/of_cmdmode_display_timing.h>
> > +#include <video/of_cmdmode.h>
> > +#include <video/cmdmode.h>
> > +
> > +/**
> > + * of_get_cmdmode - get the cmdmode #<index> from devicetree
> > + * @np - devicenode with the cmdmode_display_timings
> > + * @cm - set to return value
> > + * @index - index into list of cmdmode_display_timings
> > + *	    (Set this to OF_USE_CMDMODE_NATIVE_MODE to use whatever mode is
> > + *	     specified as native mode in the DT.)
> > + *
> > + * DESCRIPTION:
> > + * Get a list of all display timings and put the one
> > + * specified by index into *cm. This function should only be used, if
> > + * only one cmdmode is to be retrieved. A driver that needs to work
> > + * with multiple/all cmdmodes should work with
> > + * of_get_cmdmode_display_timings instead.
> > + **/
> > +int of_get_cmdmode(struct device_node *np, struct cmdmode *cm, int index)
> > +{
> > +	struct cmdmode_display_timings *cmdts;
> > +	int ret;
> > +
> > +	cmdts = of_get_cmdmode_display_timings(np);
> > +	if (!cmdts) {
> > +		pr_err("%s: no timings specified\n", of_node_full_name(np));
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (index == OF_USE_CMDMODE_NATIVE_MODE)
> > +		index = cmdts->native_mode;
> > +
> > +	ret = cmdmode_from_timings(cmdts, cm, index);
> > +	if (ret)
> > +		return ret;
> > +
> > +	cmdmode_display_timings_release(cmdts);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(of_get_cmdmode);
> > diff --git a/drivers/video/of_cmdmode_display_timing.c
> > b/drivers/video/of_cmdmode_display_timing.c new file mode 100644
> > index 0000000..fcf2b35
> > --- /dev/null
> > +++ b/drivers/video/of_cmdmode_display_timing.c
> > @@ -0,0 +1,212 @@
> > +/*
> > + * OF helpers for parsing cmdmode display timings
> > + *
> > + * Copyright (c) 2014 YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > + *
> > + * based on of_cmdmode.c
> > + *
> > + * 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.
> > + */
> > +#include <linux/export.h>
> > +#include <linux/of.h>
> > +#include <linux/slab.h>
> > +#include <video/cmdmode_display_timing.h>
> > +#include <video/of_cmdmode_display_timing.h>
> > +
> > +/**
> > + * of_parse_cmdmode_display_timing - parse cmdmode_display_timing entry
> > + *					from device_node
> > + * @np: device_node with the properties
> > + **/
> > +static int of_parse_cmdmode_display_timing(const struct device_node *np,
> > +					struct cmdmode_display_timing *cmdt)
> > +{
> > +	int ret = 0;
> > +
> > +	memset(cmdt, 0, sizeof(*cmdt));
> > +
> > +	ret |= of_property_read_u32(np, "clock-frequency", &cmdt-
>pixelclock);
> > +	ret |= of_property_read_u32(np, "hactive", &cmdt->hactive);
> > +	ret |= of_property_read_u32(np, "vactive", &cmdt->vactive);
> > +	ret |= of_property_read_u32(np, "cs-setup", &cmdt->cs_setup);
> > +	ret |= of_property_read_u32(np, "wr-setup", &cmdt->wr_setup);
> > +	ret |= of_property_read_u32(np, "wr-active", &cmdt->wr_active);
> > +	ret |= of_property_read_u32(np, "wr-hold", &cmdt->wr_hold);
> > +
> > +	if (ret) {
> > +		pr_err("%s: error reading cmdmode timing properties\n",
> > +			of_node_full_name(np));
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * of_get_cmdmode_display_timing - parse a cmdmode_display_timing entry
> > + * @np: device_node with the timing subnode
> > + * @name: name of the timing node
> > + * @cmdt: cmdmode_display_timing struct to fill
> > + **/
> > +int of_get_cmdmode_display_timing(struct device_node *np, const char
> > *name, +					struct cmdmode_display_timing *cmdt)
> > +{
> > +	struct device_node *timing_np;
> > +
> > +	if (!np) {
> > +		pr_err("%s: no devicenode given\n", of_node_full_name(np));
> > +		return -EINVAL;
> > +	}
> > +
> > +	timing_np = of_get_child_by_name(np, name);
> > +	if (!timing_np) {
> > +		pr_err("%s: could not find node '%s'\n",
> > +			of_node_full_name(np), name);
> > +		return -ENOENT;
> > +	}
> > +
> > +	return of_parse_cmdmode_display_timing(timing_np, cmdt);
> > +}
> > +EXPORT_SYMBOL_GPL(of_get_cmdmode_display_timing);
> > +
> > +/**
> > + * of_get_cmdmode_display_timings - parse all cmdmode_display_timing
> > + * entries from a device_node
> > + * @np: device_node with the subnodes
> > + **/
> > +struct cmdmode_display_timings*
> > +of_get_cmdmode_display_timings(struct device_node *np)
> > +{
> > +	struct device_node *timings_np;
> > +	struct device_node *entry;
> > +	struct device_node *native_mode;
> > +	struct cmdmode_display_timings *cmdts;
> > +
> > +	if (!np) {
> > +		pr_err("%s: no device node given\n", of_node_full_name(np));
> > +		return NULL;
> > +	}
> > +
> > +	timings_np = of_get_child_by_name(np, "cmdmode-display-timings");
> > +	if (!timings_np) {
> > +		pr_err("%s: could not find cmdmode-display-timings node\n",
> > +			of_node_full_name(np));
> > +		return NULL;
> > +	}
> > +
> > +	cmdts = kzalloc(sizeof(*cmdts), GFP_KERNEL);
> > +	if (!cmdts) {
> > +		pr_err("%s: could not allocate struct cmdts'\n",
> > +			of_node_full_name(np));
> > +		goto cmdtsfail;
> > +	}
> > +
> > +	entry = of_parse_phandle(timings_np, "native-mode", 0);
> > +	/* assume first child as native mode if none provided */
> > +	if (!entry)
> > +		entry = of_get_next_child(np, NULL);
> > +	/* if there is no child, it is useless to go on */
> > +	if (!entry) {
> > +		pr_err("%s: no timing specifications given\n",
> > +			of_node_full_name(np));
> > +		goto entryfail;
> > +	}
> > +
> > +	pr_debug("%s: using %s as default timing\n",
> > +		of_node_full_name(np), entry->name);
> > +
> > +	native_mode = entry;
> > +
> > +	cmdts->num_timings = of_get_child_count(timings_np);
> > +	if (cmdts->num_timings == 0) {
> > +		/* should never happen, as entry was already found above */
> > +		pr_err("%s: no timings specified\n", of_node_full_name(np));
> > +		goto entryfail;
> > +	}
> > +
> > +	cmdts->timings = kzalloc(sizeof(struct cmdmode_display_timing *) *
> > +				cmdts->num_timings, GFP_KERNEL);
> > +	if (!cmdts->timings) {
> > +		pr_err("%s: could not allocate timings array\n",
> > +			of_node_full_name(np));
> > +		goto entryfail;
> > +	}
> > +
> > +	cmdts->num_timings = 0;
> > +	cmdts->native_mode = 0;
> > +
> > +	for_each_child_of_node(timings_np, entry) {
> > +		struct cmdmode_display_timing *cmdt;
> > +		int r;
> > +
> > +		cmdt = kzalloc(sizeof(*cmdt), GFP_KERNEL);
> > +		if (!cmdt) {
> > +			pr_err("%s: could not allocate cmdmode_display_timing\n"
> > +				, of_node_full_name(np));
> > +			goto timingfail;
> > +		}
> > +
> > +		r = of_parse_cmdmode_display_timing(entry, cmdt);
> > +		if (r) {
> > +			/*
> > +			 * to not encourage wrong devicetrees, fail in case of
> > +			 * an error
> > +			 */
> > +			pr_err("%s: error in timing %d\n",
> > +				of_node_full_name(np), cmdts->num_timings + 1);
> > +			goto timingfail;
> > +		}
> > +
> > +		if (native_mode == entry)
> > +			cmdts->native_mode = cmdts->num_timings;
> > +
> > +		cmdts->timings[cmdts->num_timings] = cmdt;
> > +		cmdts->num_timings++;
> > +	}
> > +	of_node_put(timings_np);
> > +	/*
> > +	 * native_mode points to the device_node returned by of_parse_phandle
> > +	 * therefore call of_node_put on it
> > +	 */
> > +	of_node_put(native_mode);
> > +
> > +	pr_debug("%s: got %d timings. Using timing #%d as default\n",
> > +		of_node_full_name(np), cmdts->num_timings,
> > +		cmdts->native_mode + 1);
> > +
> > +	return cmdts;
> > +
> > +timingfail:
> > +	if (native_mode)
> > +		of_node_put(native_mode);
> > +	cmdmode_display_timings_release(cmdts);
> > +entryfail:
> > +	kfree(cmdts);
> > +cmdtsfail:
> > +	of_node_put(timings_np);
> > +	return NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(of_get_cmdmode_display_timings);
> > +
> > +/**
> > + * of_cmdmode_display_timings_exist - check if a display-timings node is
> > + * provided
> > + * @np: device_node with the timing
> > + **/
> > +int of_cmdmode_display_timings_exist(struct device_node *np)
> > +{
> > +	struct device_node *timings_np;
> > +
> > +	if (!np)
> > +		return -EINVAL;
> > +
> > +	timings_np = of_parse_phandle(np, "cmdmode-display-timings", 0);
> > +	if (!timings_np)
> > +		return -EINVAL;
> > +
> > +	of_node_put(timings_np);
> > +	return 1;
> > +}
> > +EXPORT_SYMBOL_GPL(of_cmdmode_display_timings_exist);
> > diff --git a/include/video/cmdmode.h b/include/video/cmdmode.h
> > new file mode 100644
> > index 0000000..61ee71e
> > --- /dev/null
> > +++ b/include/video/cmdmode.h
> > @@ -0,0 +1,67 @@
> > +/*
> > + * generic cmdmode description
> > + *
> > + * Copyright 2014 YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > + *
> > + * 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 __LINUX_CMDMODE_H
> > +#define __LINUX_CMDMODE_H
> > +
> > +#include <linux/types.h>
> > +#include <video/cmdmode_display_timing.h>
> > +
> > +/*
> > + * Subsystem independent description of a cmdmode.
> > + * Can be generated from struct cmdmode_display_timing.
> > + * @pixelclock: display clock in Hz
> > + * @hactive: horizontal active video
> > + * @vactive: vertical active video
> > + * @cs_setup: clock cycles for the active period of address signal is
> > enabled + *		until chip select is enabled
> > + * @wr_setup: clock cycles for the active period of CS signal is enabled
> > until + *		write signal is enabled
> > + * @wr_active: clock cycles for the active period of CS is enabled
> > + * @wr_hold: clock cycles for the active period of CS is disabled until
> > write + *		signal is disabled
> > + */
> > +struct cmdmode {
> > +	unsigned long pixelclock;
> > +
> > +	u32 hactive;
> > +	u32 vactive;
> > +
> > +	u32 cs_setup;
> > +	u32 wr_setup;
> > +	u32 wr_active;
> > +	u32 wr_hold;
> > +};
> > +
> > +/**
> > + * cmdmode_from_timing - convert display timing to cmdmode
> > + * @cmdt: cmdmode_display_timing structure
> > + * @cm: return value
> > + *
> > + * DESCRIPTION:
> > + * This function converts a struct cmdmode_display_timing to a struct
> > cmdmode. + */
> > +void cmdmode_from_timing(const struct cmdmode_display_timing *cmdt,
> > +				struct cmdmode *cm);
> > +
> > +/**
> > + * cmdmode_from_timings - convert one display timings entry to cmdmode
> > + * @disp: structure with all possible timing entries
> > + * @cm: return value
> > + * @index: index into the list of display timings in devicetree
> > + *
> > + * DESCRIPTION:
> > + * This function converts one struct cmdmode_display_timing entry to a
> > + * struct cmdmode.
> > + */
> > +int cmdmode_from_timings(const struct cmdmode_display_timings *cmdts,
> > +				struct cmdmode *cm, unsigned int index);
> > +
> > +#endif /* __LINUX_CMDMODE_H */
> > diff --git a/include/video/cmdmode_display_timing.h
> > b/include/video/cmdmode_display_timing.h new file mode 100644
> > index 0000000..5005660
> > --- /dev/null
> > +++ b/include/video/cmdmode_display_timing.h
> > @@ -0,0 +1,59 @@
> > +/*
> > + * description of cmdmode display timings
> > + *
> > + * Copyright 2014 YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > + *
> > + * 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 __LINUX_CMDMODE_DISPLAY_TIMING_H
> > +#define __LINUX_CMDMODE_DISPLAY_TIMING_H
> > +
> > +#include <linux/types.h>
> > +
> > +/*
> > + * Single "mode" entry. This describes one set of signal timings a
> > display can + * have in one setting. This struct can later be converted
> > to struct cmdmode + * (see include/video/cmdmode.h).
> > + */
> > +struct cmdmode_display_timing {
> > +	u32	pixelclock;
> > +
> > +	u32	hactive;
> > +	u32	vactive;
> > +
> > +	u32	cs_setup;
> > +	u32	wr_setup;
> > +	u32	wr_active;
> > +	u32	wr_hold;
> > +};
> > +
> > +/*
> > + * This describes all timing settings a display provides.
> > + * The native_mode is the default setting for this display.
> > + * Drivers that can handle multiple cmdmodes should work with this struct
> > + * and convert each entry to the desired end result.
> > + */
> > +struct cmdmode_display_timings {
> > +	unsigned int num_timings;
> > +	unsigned int native_mode;
> > +
> > +	struct cmdmode_display_timing **timings;
> > +};
> > +
> > +/* get one entry from struct cmdmode_display_timings */
> > +static inline struct cmdmode_display_timing*
> > +cmdmode_display_timings_get(const struct cmdmode_display_timings *cmdts,
> > +				unsigned int index)
> > +{
> > +	if (cmdts->num_timings > index)
> > +		return cmdts->timings[index];
> > +	else
> > +		return NULL;
> > +}
> > +
> > +void cmdmode_display_timings_release(struct cmdmode_display_timings
> > *cmdts); +
> > +#endif /* __LINUX_CMDDMODE_DISPLAY_TIMING_H */
> > diff --git a/include/video/of_cmdmode.h b/include/video/of_cmdmode.h
> > new file mode 100644
> > index 0000000..fb7c6c7
> > --- /dev/null
> > +++ b/include/video/of_cmdmode.h
> > @@ -0,0 +1,19 @@
> > +/*
> > + * Copyright 2014 YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > + *
> > + * cmdmode of-helpers
> > + *
> > + * 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 __LINUX_OF_CMDMODE_H
> > +#define __LINUX_OF_CMDMODE_H
> > +
> > +struct device_node;
> > +struct cmdmode;
> > +
> > +int of_get_cmdmode(struct device_node *np, struct cmdmode *cm, int
> > index);
> > +
> > +#endif /* __LINUX_OF_CMDMODE_H */
> > diff --git a/include/video/of_cmdmode_display_timing.h
> > b/include/video/of_cmdmode_display_timing.h new file mode 100644
> > index 0000000..6be91ba
> > --- /dev/null
> > +++ b/include/video/of_cmdmode_display_timing.h
> > @@ -0,0 +1,26 @@
> > +/*
> > + * Copyright 2014 YoungJun Cho <yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > + *
> > + * cmdmode display timings of helpers
> > + *
> > + * 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 __LINUX_OF_CMDMODE_DISPLAY_TIMING_H
> > +#define __LINUX_OF_CMDMODE_DISPLAY_TIMING_H
> > +
> > +struct device_node;
> > +struct cmdmode_display_timing;
> > +struct cmdmode_display_timings;
> > +
> > +#define OF_USE_CMDMODE_NATIVE_MODE -1
> > +
> > +int of_get_cmdmode_display_timing(struct device_node *np, const char
> > *name, +					struct cmdmode_display_timing *cmdt);
> > +struct cmdmode_display_timings*
> > +	of_get_cmdmode_display_timings(struct device_node *np);
> > +int of_cmdmode_display_timings_exist(struct device_node *np);
> > +
> > +#endif /* __LINUX_OF_CMDMODE_DISPLAY_TIMING_H */

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

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

* Re: [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-21  4:43 ` [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings YoungJun Cho
@ 2014-05-26 13:41   ` Thierry Reding
  2014-05-27  6:28     ` Andrzej Hajda
  0 siblings, 1 reply; 39+ messages in thread
From: Thierry Reding @ 2014-05-26 13:41 UTC (permalink / raw)
  To: YoungJun Cho
  Cc: airlied, dri-devel, devicetree, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak, linux-samsung-soc,
	laurent.pinchart, s.trumtrar, djkurtz, kyungmin.park, inki.dae,
	kgene.kim, jy0922.shim, sw0312.kim, a.hajda

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

On Wed, May 21, 2014 at 01:43:05PM +0900, YoungJun Cho wrote:
> This patch adds DT bindings for s6e3fa0 panel.
> The bindings describes panel resources, display timings and cpu mode timings.
> 
> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
> Acked-by: Inki Dae <inki.dae@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt

You're totally confusing me here. Half of this patch series is about
adding i80 support to Exynos FIMD, and then you go and add what is
apparently a DSI peripheral driver here that's supposed to be used by
this new i80 support. Nothing I've been able to dig up indicates that
i80 or DSI are in anyway related.

Even the Exynos DSI Master bindings[0] say that these two are not at all
the same thing:

	port node:
	    - reg: (required) can be 0 for input RGB/I80 port or 1 for
	      DSI port;

Am I missing something here?

Thierry

[0]: https://www.kernel.org/doc/Documentation/devicetree/bindings/video/exynos_dsim.txt

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

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

* Re: [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-26 13:41   ` Thierry Reding
@ 2014-05-27  6:28     ` Andrzej Hajda
  2014-05-27  7:53       ` Thierry Reding
  0 siblings, 1 reply; 39+ messages in thread
From: Andrzej Hajda @ 2014-05-27  6:28 UTC (permalink / raw)
  To: Thierry Reding, YoungJun Cho
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

Hi Thierry,

On 05/26/2014 03:41 PM, Thierry Reding wrote:
> On Wed, May 21, 2014 at 01:43:05PM +0900, YoungJun Cho wrote:
>> This patch adds DT bindings for s6e3fa0 panel.
>> The bindings describes panel resources, display timings and cpu mode timings.
>>
>> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>> Acked-by: Inki Dae <inki.dae@samsung.com>
>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> ---
>>  .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
>>  1 file changed, 45 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
> You're totally confusing me here. Half of this patch series is about
> adding i80 support to Exynos FIMD, and then you go and add what is
> apparently a DSI peripheral driver here that's supposed to be used by
> this new i80 support. Nothing I've been able to dig up indicates that
> i80 or DSI are in anyway related.

FIMD can produce parallel RGB output or command mode in i80 style output
via parallel lines.
DSIM can accept parallel RGB stream in this case it produces MIPI DSI
video mode signal or it can accept i80 and in this case it translates it
to MIPI DSI command mode.

Regards
Andrzej

>
> Even the Exynos DSI Master bindings[0] say that these two are not at all
> the same thing:
>
> 	port node:
> 	    - reg: (required) can be 0 for input RGB/I80 port or 1 for
> 	      DSI port;
>
> Am I missing something here?

>
> Thierry
>
> [0]: https://www.kernel.org/doc/Documentation/devicetree/bindings/video/exynos_dsim.txt

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

* Re: [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-27  6:28     ` Andrzej Hajda
@ 2014-05-27  7:53       ` Thierry Reding
  2014-05-27 14:24         ` Inki Dae
  0 siblings, 1 reply; 39+ messages in thread
From: Thierry Reding @ 2014-05-27  7:53 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, kyungmin.park, robh+dt,
	galak, kgene.kim, s.trumtrar, laurent.pinchart


[-- Attachment #1.1: Type: text/plain, Size: 1500 bytes --]

On Tue, May 27, 2014 at 08:28:52AM +0200, Andrzej Hajda wrote:
> Hi Thierry,
> 
> On 05/26/2014 03:41 PM, Thierry Reding wrote:
> > On Wed, May 21, 2014 at 01:43:05PM +0900, YoungJun Cho wrote:
> >> This patch adds DT bindings for s6e3fa0 panel.
> >> The bindings describes panel resources, display timings and cpu mode timings.
> >>
> >> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
> >> Acked-by: Inki Dae <inki.dae@samsung.com>
> >> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> >> ---
> >>  .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
> >>  1 file changed, 45 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
> > You're totally confusing me here. Half of this patch series is about
> > adding i80 support to Exynos FIMD, and then you go and add what is
> > apparently a DSI peripheral driver here that's supposed to be used by
> > this new i80 support. Nothing I've been able to dig up indicates that
> > i80 or DSI are in anyway related.
> 
> FIMD can produce parallel RGB output or command mode in i80 style output
> via parallel lines.
> DSIM can accept parallel RGB stream in this case it produces MIPI DSI
> video mode signal or it can accept i80 and in this case it translates it
> to MIPI DSI command mode.

Then the command mode timings aren't a property of the panel at all.
They describe what DSIM expects, so that's where they should be defined.

Thierry

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-27  7:53       ` Thierry Reding
@ 2014-05-27 14:24         ` Inki Dae
  2014-05-27 20:21           ` Thierry Reding
  0 siblings, 1 reply; 39+ messages in thread
From: Inki Dae @ 2014-05-27 14:24 UTC (permalink / raw)
  To: Thierry Reding
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, Andrzej Hajda,
	kyungmin.park, robh+dt, laurent.pinchart, galak, kgene.kim,
	s.trumtrar

2014-05-27 16:53 GMT+09:00 Thierry Reding <thierry.reding@gmail.com>:
> On Tue, May 27, 2014 at 08:28:52AM +0200, Andrzej Hajda wrote:
>> Hi Thierry,
>>
>> On 05/26/2014 03:41 PM, Thierry Reding wrote:
>> > On Wed, May 21, 2014 at 01:43:05PM +0900, YoungJun Cho wrote:
>> >> This patch adds DT bindings for s6e3fa0 panel.
>> >> The bindings describes panel resources, display timings and cpu mode timings.
>> >>
>> >> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>> >> Acked-by: Inki Dae <inki.dae@samsung.com>
>> >> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> >> ---
>> >>  .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
>> >>  1 file changed, 45 insertions(+)
>> >>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
>> > You're totally confusing me here. Half of this patch series is about
>> > adding i80 support to Exynos FIMD, and then you go and add what is
>> > apparently a DSI peripheral driver here that's supposed to be used by
>> > this new i80 support. Nothing I've been able to dig up indicates that
>> > i80 or DSI are in anyway related.
>>
>> FIMD can produce parallel RGB output or command mode in i80 style output
>> via parallel lines.
>> DSIM can accept parallel RGB stream in this case it produces MIPI DSI
>> video mode signal or it can accept i80 and in this case it translates it
>> to MIPI DSI command mode.
>
> Then the command mode timings aren't a property of the panel at all.

Then the video mode timings aren't also a property of the panel.

Which interface mipi and display controller should use would be
decided by lcd panel type: display controller can use i80 interface
based lcd panel, and also mipi controller can use i80 interface based
lcd panel.
In here, the only difference is that lcd panel receives  packets,
which includes video data or command data, packed with mipi protocol
via lane lines or receives video data or command data via parallel
lines.

And the below is LCD types,
        RGB interface panel.
        i80 interface panel.
        MIPI based RGB interface panel.
        MIPI based i80 interface panel.

RGB interface also is called video mode, and i80 interface also is
called cpu mode. In case of omap SoC, it is also called Smart panel.
i80 interface is just one of LCD types. So I think this interface
timings should be handled by frameworks related to mode in same way as
RGB interface.

Thanks,
Inki Dae

> They describe what DSIM expects, so that's where they should be defined.
>
> Thierry
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>

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

* Re: [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-27 14:24         ` Inki Dae
@ 2014-05-27 20:21           ` Thierry Reding
  2014-05-28  4:50             ` Inki Dae
  0 siblings, 1 reply; 39+ messages in thread
From: Thierry Reding @ 2014-05-27 20:21 UTC (permalink / raw)
  To: Inki Dae
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, Andrzej Hajda,
	kyungmin.park, robh+dt, laurent.pinchart, galak, kgene.kim,
	s.trumtrar


[-- Attachment #1.1: Type: text/plain, Size: 4090 bytes --]

On Tue, May 27, 2014 at 11:24:49PM +0900, Inki Dae wrote:
> 2014-05-27 16:53 GMT+09:00 Thierry Reding <thierry.reding@gmail.com>:
> > On Tue, May 27, 2014 at 08:28:52AM +0200, Andrzej Hajda wrote:
> >> Hi Thierry,
> >>
> >> On 05/26/2014 03:41 PM, Thierry Reding wrote:
> >> > On Wed, May 21, 2014 at 01:43:05PM +0900, YoungJun Cho wrote:
> >> >> This patch adds DT bindings for s6e3fa0 panel.
> >> >> The bindings describes panel resources, display timings and cpu mode timings.
> >> >>
> >> >> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
> >> >> Acked-by: Inki Dae <inki.dae@samsung.com>
> >> >> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> >> >> ---
> >> >>  .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
> >> >>  1 file changed, 45 insertions(+)
> >> >>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
> >> > You're totally confusing me here. Half of this patch series is about
> >> > adding i80 support to Exynos FIMD, and then you go and add what is
> >> > apparently a DSI peripheral driver here that's supposed to be used by
> >> > this new i80 support. Nothing I've been able to dig up indicates that
> >> > i80 or DSI are in anyway related.
> >>
> >> FIMD can produce parallel RGB output or command mode in i80 style output
> >> via parallel lines.
> >> DSIM can accept parallel RGB stream in this case it produces MIPI DSI
> >> video mode signal or it can accept i80 and in this case it translates it
> >> to MIPI DSI command mode.
> >
> > Then the command mode timings aren't a property of the panel at all.
> 
> Then the video mode timings aren't also a property of the panel.
> 
> Which interface mipi and display controller should use would be
> decided by lcd panel type: display controller can use i80 interface
> based lcd panel, and also mipi controller can use i80 interface based
> lcd panel.
> In here, the only difference is that lcd panel receives  packets,
> which includes video data or command data, packed with mipi protocol
> via lane lines or receives video data or command data via parallel
> lines.
> 
> And the below is LCD types,
>         RGB interface panel.
>         i80 interface panel.
>         MIPI based RGB interface panel.
>         MIPI based i80 interface panel.
> 
> RGB interface also is called video mode, and i80 interface also is
> called cpu mode. In case of omap SoC, it is also called Smart panel.
> i80 interface is just one of LCD types. So I think this interface
> timings should be handled by frameworks related to mode in same way as
> RGB interface.

LCD is a display technology, it has nothing to do with the interface. My
point is that from Andrzej's description, and in fact from this patch
series in general, the S6E3FA0 panel is a DSI panel. Associating timings
that are i80 specific to it is therefore wrong.

Consider for instance what would happen if somebody were to use the same
panel on some other device (connected to a DSI controller). If you
specify i80 timings for the panel then the new device won't know what to
do with them because it expects DSI-related timings.

Let me try to summarize the above to make sure we're all on the same
page:

	- FIMD is a display controller that can be configured to either
	  send RGB data or i80 data
	- DSIM takes either RGB as input and outputs DSI (video mode) or
	  i80 as input and outputs DSI (command mode)

In both cases the panel is connected to DSIM and it takes DSI as input,
because it is a DSI panel (it doesn't understand RGB or i80). The panel
needs to describe the properties of the DSI interface so that DSIM can
be configured appropriately. DSIM in turn works as a bridge or encoder
that converts RGB or i80 to DSI (video or command mode). So it makes no
sense to describe the i80 timings for the panel because it has nothing
to do with i80. Instead the DSIM is the hardware that needs to specify
the i80 timings, so that FIMD can be configured to generate the timings
that DSIM needs.

Thierry

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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-27 20:21           ` Thierry Reding
@ 2014-05-28  4:50             ` Inki Dae
  2014-05-28  6:44               ` Andrzej Hajda
  0 siblings, 1 reply; 39+ messages in thread
From: Inki Dae @ 2014-05-28  4:50 UTC (permalink / raw)
  To: Thierry Reding
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, Andrzej Hajda,
	kyungmin.park, robh+dt, laurent.pinchart, galak, kgene.kim,
	s.trumtrar

On 2014년 05월 28일 05:21, Thierry Reding wrote:
> On Tue, May 27, 2014 at 11:24:49PM +0900, Inki Dae wrote:
>> 2014-05-27 16:53 GMT+09:00 Thierry Reding <thierry.reding@gmail.com>:
>>> On Tue, May 27, 2014 at 08:28:52AM +0200, Andrzej Hajda wrote:
>>>> Hi Thierry,
>>>>
>>>> On 05/26/2014 03:41 PM, Thierry Reding wrote:
>>>>> On Wed, May 21, 2014 at 01:43:05PM +0900, YoungJun Cho wrote:
>>>>>> This patch adds DT bindings for s6e3fa0 panel.
>>>>>> The bindings describes panel resources, display timings and cpu mode timings.
>>>>>>
>>>>>> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>>>>>> Acked-by: Inki Dae <inki.dae@samsung.com>
>>>>>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>>>>>> ---
>>>>>>  .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
>>>>>>  1 file changed, 45 insertions(+)
>>>>>>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
>>>>> You're totally confusing me here. Half of this patch series is about
>>>>> adding i80 support to Exynos FIMD, and then you go and add what is
>>>>> apparently a DSI peripheral driver here that's supposed to be used by
>>>>> this new i80 support. Nothing I've been able to dig up indicates that
>>>>> i80 or DSI are in anyway related.
>>>>
>>>> FIMD can produce parallel RGB output or command mode in i80 style output
>>>> via parallel lines.
>>>> DSIM can accept parallel RGB stream in this case it produces MIPI DSI
>>>> video mode signal or it can accept i80 and in this case it translates it
>>>> to MIPI DSI command mode.
>>>
>>> Then the command mode timings aren't a property of the panel at all.
>>
>> Then the video mode timings aren't also a property of the panel.
>>
>> Which interface mipi and display controller should use would be
>> decided by lcd panel type: display controller can use i80 interface
>> based lcd panel, and also mipi controller can use i80 interface based
>> lcd panel.
>> In here, the only difference is that lcd panel receives  packets,
>> which includes video data or command data, packed with mipi protocol
>> via lane lines or receives video data or command data via parallel
>> lines.
>>
>> And the below is LCD types,
>>         RGB interface panel.
>>         i80 interface panel.
>>         MIPI based RGB interface panel.
>>         MIPI based i80 interface panel.
>>
>> RGB interface also is called video mode, and i80 interface also is
>> called cpu mode. In case of omap SoC, it is also called Smart panel.
>> i80 interface is just one of LCD types. So I think this interface
>> timings should be handled by frameworks related to mode in same way as
>> RGB interface.
> 
> LCD is a display technology, it has nothing to do with the interface. My
> point is that from Andrzej's description, and in fact from this patch
> series in general, the S6E3FA0 panel is a DSI panel. Associating timings
> that are i80 specific to it is therefore wrong.
> 
> Consider for instance what would happen if somebody were to use the same
> panel on some other device (connected to a DSI controller). If you
> specify i80 timings for the panel then the new device won't know what to
> do with them because it expects DSI-related timings.
> 
> Let me try to summarize the above to make sure we're all on the same
> page:
> 
> 	- FIMD is a display controller that can be configured to either
> 	  send RGB data or i80 data
> 	- DSIM takes either RGB as input and outputs DSI (video mode) or
> 	  i80 as input and outputs DSI (command mode)
> 
> In both cases the panel is connected to DSIM and it takes DSI as input,
> because it is a DSI panel (it doesn't understand RGB or i80). The panel
> needs to describe the properties of the DSI interface so that DSIM can
> be configured appropriately. DSIM in turn works as a bridge or encoder
> that converts RGB or i80 to DSI (video or command mode). So it makes no
> sense to describe the i80 timings for the panel because it has nothing
> to do with i80. Instead the DSIM is the hardware that needs to specify
> the i80 timings, so that FIMD can be configured to generate the timings
> that DSIM needs.

            CPU interface                     MIPI lane
FIMD ----------------------- DSIM --------------------- LCD Panel

Hmm... reasonable. So your point is that command mode timing should be
placed in fimd device node, not panel device node? And panel device node
should provide only a property that DSIM driver can set LCD mode
properly to i80 or rgb interface mode, and also FIMD driver can set LCD
mode to i80 or rgb interface mode.

Is there my missing point?

And in case of Exynos, now video timing property is also placed in panel
device node so it needs to move to fimd device node.

Andrzej, do you have other opinion? I have looked into dts files for
other SoC and In most SoC, it seems that display controller node has
video timing property, not panel node. Thierry's pointing seems
reasonable to me.

Thanks,
Inki Dae

> 
> Thierry
> 

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

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

* Re: [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-28  4:50             ` Inki Dae
@ 2014-05-28  6:44               ` Andrzej Hajda
  2014-05-30  3:08                 ` YoungJun Cho
  0 siblings, 1 reply; 39+ messages in thread
From: Andrzej Hajda @ 2014-05-28  6:44 UTC (permalink / raw)
  To: Inki Dae, Thierry Reding
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, kyungmin.park, robh+dt,
	galak, kgene.kim, s.trumtrar, laurent.pinchart

On 05/28/2014 06:50 AM, Inki Dae wrote:
> On 2014년 05월 28일 05:21, Thierry Reding wrote:
>> On Tue, May 27, 2014 at 11:24:49PM +0900, Inki Dae wrote:
>>> 2014-05-27 16:53 GMT+09:00 Thierry Reding <thierry.reding@gmail.com>:
>>>> On Tue, May 27, 2014 at 08:28:52AM +0200, Andrzej Hajda wrote:
>>>>> Hi Thierry,
>>>>>
>>>>> On 05/26/2014 03:41 PM, Thierry Reding wrote:
>>>>>> On Wed, May 21, 2014 at 01:43:05PM +0900, YoungJun Cho wrote:
>>>>>>> This patch adds DT bindings for s6e3fa0 panel.
>>>>>>> The bindings describes panel resources, display timings and cpu mode timings.
>>>>>>>
>>>>>>> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>>>>>>> Acked-by: Inki Dae <inki.dae@samsung.com>
>>>>>>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>>>>>>> ---
>>>>>>>  .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
>>>>>>>  1 file changed, 45 insertions(+)
>>>>>>>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
>>>>>> You're totally confusing me here. Half of this patch series is about
>>>>>> adding i80 support to Exynos FIMD, and then you go and add what is
>>>>>> apparently a DSI peripheral driver here that's supposed to be used by
>>>>>> this new i80 support. Nothing I've been able to dig up indicates that
>>>>>> i80 or DSI are in anyway related.
>>>>> FIMD can produce parallel RGB output or command mode in i80 style output
>>>>> via parallel lines.
>>>>> DSIM can accept parallel RGB stream in this case it produces MIPI DSI
>>>>> video mode signal or it can accept i80 and in this case it translates it
>>>>> to MIPI DSI command mode.
>>>> Then the command mode timings aren't a property of the panel at all.
>>> Then the video mode timings aren't also a property of the panel.
>>>
>>> Which interface mipi and display controller should use would be
>>> decided by lcd panel type: display controller can use i80 interface
>>> based lcd panel, and also mipi controller can use i80 interface based
>>> lcd panel.
>>> In here, the only difference is that lcd panel receives  packets,
>>> which includes video data or command data, packed with mipi protocol
>>> via lane lines or receives video data or command data via parallel
>>> lines.
>>>
>>> And the below is LCD types,
>>>         RGB interface panel.
>>>         i80 interface panel.
>>>         MIPI based RGB interface panel.
>>>         MIPI based i80 interface panel.
>>>
>>> RGB interface also is called video mode, and i80 interface also is
>>> called cpu mode. In case of omap SoC, it is also called Smart panel.
>>> i80 interface is just one of LCD types. So I think this interface
>>> timings should be handled by frameworks related to mode in same way as
>>> RGB interface.

Some clarification about names.
I am not an expert in command/cpu mode interface, so feel free to
correct me.
Those different terms were quite confusing for me so after some digging
(for example here [1])
I have found/ensured  there is a following relation between different names:
MIPI DPI - RGB interface
MIPI DBI type A - CPU mode m68 style
MIPI DBI type B - CPU mode i80 style
MIPI DBI type C - SPI, maybe also other serial interfaces (?)
MIPI DSI - based on D-PHY-s serial protocol which can work in video or
command mode.

To add more confusion CPU mode is also named MPU mode or sys mode.

To avoid confusion in the discussion I propose use i80 only to describe
DBI type B interface,
and DSI command mode, DSI video mode to describe DSI modes.

[1]: http://www.allshore.com/pdf/DA8620.pdf


>> LCD is a display technology, it has nothing to do with the interface. My
>> point is that from Andrzej's description, and in fact from this patch
>> series in general, the S6E3FA0 panel is a DSI panel. Associating timings
>> that are i80 specific to it is therefore wrong.
>>
>> Consider for instance what would happen if somebody were to use the same
>> panel on some other device (connected to a DSI controller). If you
>> specify i80 timings for the panel then the new device won't know what to
>> do with them because it expects DSI-related timings.
>>
>> Let me try to summarize the above to make sure we're all on the same
>> page:
>>
>> 	- FIMD is a display controller that can be configured to either
>> 	  send RGB data or i80 data
>> 	- DSIM takes either RGB as input and outputs DSI (video mode) or
>> 	  i80 as input and outputs DSI (command mode)
>>
>> In both cases the panel is connected to DSIM and it takes DSI as input,
>> because it is a DSI panel (it doesn't understand RGB or i80). The panel
>> needs to describe the properties of the DSI interface so that DSIM can
>> be configured appropriately. DSIM in turn works as a bridge or encoder
>> that converts RGB or i80 to DSI (video or command mode). So it makes no
>> sense to describe the i80 timings for the panel because it has nothing
>> to do with i80. Instead the DSIM is the hardware that needs to specify
>> the i80 timings, so that FIMD can be configured to generate the timings
>> that DSIM needs.
>             CPU interface                     MIPI lane
> FIMD ----------------------- DSIM --------------------- LCD Panel
>
> Hmm... reasonable. So your point is that command mode timing should be
> placed in fimd device node, not panel device node? And panel device node
> should provide only a property that DSIM driver can set LCD mode
> properly to i80 or rgb interface mode, and also FIMD driver can set LCD
> mode to i80 or rgb interface mode.

I have no access to s6e3fa0 datasheet and Exynos datasheet I have access to
is not very verbose on the subject but it seems to be reasonable that
cs-setup, wr-setup, wr-active and wr-hold are properties only of i80
interface,
ie interface between FIMD and DSIM and they have nothing to do with DSI
command mode panel.
Those properties should be provided by DSIM to FIMD, I guess they can be
even hardcoded
in DSIM driver, no bindings required. There is still a question how DSIM
should tell FIMD about them.
I am not sure about mechanism of passing them from DSIM to FIMD, maybe
adjusting drm_display_mode
is a solution, maybe different way of communication should be used (I
see here again interface_tracker use case [2]).

[2]:
http://permalink.gmane.org/gmane.linux.drivers.video-input-infrastructure/77451

On the other side width, height and clock are properties of the panel so
they should stay
with the panel, maybe width and height could be moved from dts to
driver, I am not sure about frequency.

>
> Is there my missing point?
>
> And in case of Exynos, now video timing property is also placed in panel
> device node so it needs to move to fimd device node.

No, video timings are properties of panels so they should stay in
panels, display
controllers should just ask panels about them.

>
> Andrzej, do you have other opinion? I have looked into dts files for
> other SoC and In most SoC, it seems that display controller node has
> video timing property, not panel node. Thierry's pointing seems
> reasonable to me.
I guess there could be many reasons: historical, backward compatibility,
laziness of developers :).
I agree with Thierry also.

So if everybody agrees there is only one serious issue: how the i80
properties
should be passed from DSIM to FIMD, am I right?

Regards
Andrzej

>
> Thanks,
> Inki Dae
>
>> Thierry
>>
>

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

* Re: [PATCH v2 10/18] drm/exynos: fimd: support I80 interface
  2014-05-26  9:00   ` Daniel Kurtz
@ 2014-05-29  5:45     ` YoungJun Cho
  0 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-29  5:45 UTC (permalink / raw)
  To: Daniel Kurtz
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Seung-Woo Kim, dri-devel, Andrzej Hajda,
	Kyungmin Park, Rob Herring, Laurent Pinchart, Kumar Gala,
	Kukjin Kim, s.trumtrar

Hi Daniel,

On 05/26/2014 06:00 PM, Daniel Kurtz wrote:
> Hi YoungJun,
>
> I am not famiilar with i80.  Reading through this patch, it looks like
> it works something like below for a page flip...
>
> -> page_flip ioctl
> exynos_drm_crtc_page_flip()
>    exynos_drm_crtc_mode_set_commit()
>      exynos_plane_mode_set()
>      exynos_drm_crtc_commit()
>        exynos_plane_commit()
>          exynos_drm_crtc_plane_commit()
>            ops->win_commit() => fimd_win_commit()
>              update BASE (scanout) register
>              atomic_set(&ctx->win_updated, 1);
>
> ... at the next TE event ...
> fimd_te_handler()
>    atomic_set(&ctx->win_updated, 0);
>    fimd_trigger(ctx->dev);
>      atomic_set(&ctx->triggering, 1);
>      VIDINTCON0 |= VIDINTCON0_INT_ENABLE;
>      TRIGCON |= TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE
>      ... start an i80 transaction to transfer frame data from BASE to
> the panel ...
>
> ... write complete signalled by ...
> -> FIMD interrupt: source =  VIDINTCON0_INT_I80IFDONE |
> VIDINTCON0_INT_SYSMAINCON (which one?)

VIDINTCON0_INT_SYSMAINCON is for main LCD interrupt.
So both are required.

> fimd_irq_handler()
>    atomic_set(&ctx->triggering, 0);
>    drm_handle_vblank(ctx->drm_dev, ctx->pipe);
>    exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
>
> Some questions/points:
>   (1) does the "i80 done" interrupt mean that the panel is now
> displaying the new frame?  Or just that the new frame is pending in a
> panel-side scanout buffer?  Is there a separate interrupt for (a) "i80

The 'i80 done' interrupt means that display controller(FIMD) completes
sending the last line of screen(framebuffer) to DSI master.

> transfer complete", and (b) "new frame now on main display"?

The TE signal indicates that the panel completes dispatching gram.
So like this:
[ fimd ] : fimd_trigger() => frame done irq
[ panel ] :                                 te signal => show gram img

>
>   (2) from the "DPMS off" patch, you mentioned that the panel sometimes
> has an issue.  Do you mean that sometimes when you trigger the i80
> transaction, there is no corresponding "i80ifdone / sysmaincon"

No, I meant that fimd could miss TE signal if panel was reset / power
off before generating it.

> interrupt?   If so, then I think you want to start a timer in
> fimd_trigger(), that, if it expires before an I80IFDONE irq, will call
> exynos_drm_crtc_finish_pageflip(), rather than hiding handling this
> condition in dpms off of the exynos_drm_crtc.c layer.

As you know that even though display controller missed TE signal and
didn't trigger, the panel kept previous screen by self-refresh.
After the panel recovers well and display controller sets next fb,
then the panel would show it well without problem except current fb
overwritten issue.
But the dpms off case before the panel recovers well, there is no way
to resolving pending event.

Thank you.
Best regards YJ


>
> Thanks,
> -djk
>
>
>
>
> On Wed, May 21, 2014 at 12:43 PM, YoungJun Cho <yj44.cho@samsung.com> wrote:
>> To support MIPI DSI command mode interface, FIMD should do followings:
>> - Sets LCD block configuration for I80 interface.
>> - Uses "lcd_sys" as an IRQ resource and sets relevant IRQ configuration.
>> - Implements trigger feature which transfers image date if there is
>>    page flip request, and implements TE handler to call trigger function.
>> - Sets command mode timings configuration.
>> - Sets ideal(pixel) clock is 2 times faster than the original one to
>>    generate frame done IRQ prior to the next TE signal.
>>
>> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>> Acked-by: Inki Dae <inki.dae@samsung.com>
>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> ---
>>   drivers/gpu/drm/exynos/Kconfig           |    1 +
>>   drivers/gpu/drm/exynos/exynos_drm_fimd.c |  277 +++++++++++++++++++++++++-----
>>   include/video/samsung_fimd.h             |    3 +-
>>   3 files changed, 237 insertions(+), 44 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
>> index 5bf5bca..f4d34f0 100644
>> --- a/drivers/gpu/drm/exynos/Kconfig
>> +++ b/drivers/gpu/drm/exynos/Kconfig
>> @@ -28,6 +28,7 @@ config DRM_EXYNOS_FIMD
>>          bool "Exynos DRM FIMD"
>>          depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM
>>          select FB_MODE_HELPERS
>> +       select MFD_SYSCON
>>          help
>>            Choose this option if you want to use Exynos FIMD for DRM.
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
>> index 173ee97..9d585f9 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
>> @@ -20,11 +20,14 @@
>>   #include <linux/of_device.h>
>>   #include <linux/pm_runtime.h>
>>   #include <linux/component.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/regmap.h>
>>
>>   #include <video/of_display_timing.h>
>>   #include <video/of_videomode.h>
>>   #include <video/samsung_fimd.h>
>>   #include <drm/exynos_drm.h>
>> +#include <drm/drm_panel.h>
>>
>>   #include "exynos_drm_drv.h"
>>   #include "exynos_drm_fbdev.h"
>> @@ -60,6 +63,24 @@
>>   /* color key value register for hardware window 1 ~ 4. */
>>   #define WKEYCON1_BASE(x)               ((WKEYCON1 + 0x140) + ((x - 1) * 8))
>>
>> +/* i80 / RGB trigger control register */
>> +#define TRIGCON                                0x1A4
>> +#define TRGMODE_I80_RGB_ENABLE_I80     (1 << 0)
>> +#define SWTRGCMD_I80_RGB_ENABLE                (1 << 1)
>> +
>> +/* display mode change control register except exynos4 */
>> +#define VIDOUT_CON                     0x000
>> +#define VIDOUT_CON_F_I80_LDI0          (0x2 << 8)
>> +
>> +/* i80 interface control for main LDI register */
>> +#define I80IFCONFAx(x)                 (0x1B0 + (x) * 4)
>> +#define I80IFCONFBx(x)                 (0x1B8 + (x) * 4)
>> +#define LCD_CS_SETUP(x)                        ((x) << 16)
>> +#define LCD_WR_SETUP(x)                        ((x) << 12)
>> +#define LCD_WR_ACT(x)                  ((x) << 8)
>> +#define LCD_WR_HOLD(x)                 ((x) << 4)
>> +#define I80IFEN_ENABLE                 (1 << 0)
>> +
>>   /* FIMD has totally five hardware windows. */
>>   #define WINDOWS_NR     5
>>
>> @@ -67,10 +88,14 @@
>>
>>   struct fimd_driver_data {
>>          unsigned int timing_base;
>> +       unsigned int lcdblk_off;
>> +       unsigned int lcdblk_vt_shift;
>> +       unsigned int lcdblk_bypass_shift;
>>
>>          unsigned int has_shadowcon:1;
>>          unsigned int has_clksel:1;
>>          unsigned int has_limited_fmt:1;
>> +       unsigned int has_vidoutcon:1;
>>   };
>>
>>   static struct fimd_driver_data s3c64xx_fimd_driver_data = {
>> @@ -81,12 +106,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
>>
>>   static struct fimd_driver_data exynos4_fimd_driver_data = {
>>          .timing_base = 0x0,
>> +       .lcdblk_off = 0x210,
>> +       .lcdblk_vt_shift = 10,
>> +       .lcdblk_bypass_shift = 1,
>>          .has_shadowcon = 1,
>>   };
>>
>>   static struct fimd_driver_data exynos5_fimd_driver_data = {
>>          .timing_base = 0x20000,
>> +       .lcdblk_off = 0x214,
>> +       .lcdblk_vt_shift = 24,
>> +       .lcdblk_bypass_shift = 15,
>>          .has_shadowcon = 1,
>> +       .has_vidoutcon = 1,
>>   };
>>
>>   struct fimd_win_data {
>> @@ -111,15 +143,23 @@ struct fimd_context {
>>          struct clk                      *bus_clk;
>>          struct clk                      *lcd_clk;
>>          void __iomem                    *regs;
>> +       struct regmap                   *sysreg;
>>          struct drm_display_mode         mode;
>>          struct fimd_win_data            win_data[WINDOWS_NR];
>>          unsigned int                    default_win;
>>          unsigned long                   irq_flags;
>> +       u32                             vidcon0;
>>          u32                             vidcon1;
>> +       u32                             vidout_con;
>> +       u32                             i80ifcon;
>> +       bool                            i80_if;
>>          bool                            suspended;
>>          int                             pipe;
>>          wait_queue_head_t               wait_vsync_queue;
>>          atomic_t                        wait_vsync_event;
>> +       atomic_t                        win_updated;
>> +       atomic_t                        triggering;
>> +       spinlock_t                      win_updated_lock;
>>
>>          struct exynos_drm_panel_info panel;
>>          struct fimd_driver_data *driver_data;
>> @@ -242,6 +282,14 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
>>          unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
>>          u32 clkdiv;
>>
>> +       if (ctx->i80_if) {
>> +               /*
>> +                * The frame done interrupt should be occurred prior to the
>> +                * next TE signal.
>> +                */
>> +               ideal_clk *= 2;
>> +       }
>> +
>>          /* Find the clock divider value that gets us closest to ideal_clk */
>>          clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->lcd_clk), ideal_clk);
>>
>> @@ -264,17 +312,23 @@ static void fimd_mode_set(struct exynos_drm_manager *mgr,
>>          struct fimd_context *ctx = mgr->ctx;
>>
>>          drm_mode_copy(&ctx->mode, in_mode);
>> +
>> +       if (ctx->i80_if) {
>> +               ctx->i80ifcon = LCD_CS_SETUP(in_mode->cs_setup);
>> +               ctx->i80ifcon |= LCD_WR_SETUP(in_mode->wr_setup);
>> +               ctx->i80ifcon |= LCD_WR_ACT(in_mode->wr_active);
>> +               ctx->i80ifcon |= LCD_WR_HOLD(in_mode->wr_hold);
>> +       }
>>   }
>>
>>   static void fimd_commit(struct exynos_drm_manager *mgr)
>>   {
>>          struct fimd_context *ctx = mgr->ctx;
>>          struct drm_display_mode *mode = &ctx->mode;
>> -       struct fimd_driver_data *driver_data;
>> -       u32 val, clkdiv, vidcon1;
>> -       int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
>> +       struct fimd_driver_data *driver_data = ctx->driver_data;
>> +       void *timing_base = ctx->regs + driver_data->timing_base;
>> +       u32 val, clkdiv;
>>
>> -       driver_data = ctx->driver_data;
>>          if (ctx->suspended)
>>                  return;
>>
>> @@ -282,33 +336,65 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
>>          if (mode->htotal == 0 || mode->vtotal == 0)
>>                  return;
>>
>> -       /* setup polarity values */
>> -       vidcon1 = ctx->vidcon1;
>> -       if (mode->flags & DRM_MODE_FLAG_NVSYNC)
>> -               vidcon1 |= VIDCON1_INV_VSYNC;
>> -       if (mode->flags & DRM_MODE_FLAG_NHSYNC)
>> -               vidcon1 |= VIDCON1_INV_HSYNC;
>> -       writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
>> -
>> -       /* setup vertical timing values. */
>> -       vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
>> -       vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
>> -       vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
>> -
>> -       val = VIDTCON0_VBPD(vbpd - 1) |
>> -               VIDTCON0_VFPD(vfpd - 1) |
>> -               VIDTCON0_VSPW(vsync_len - 1);
>> -       writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
>> -
>> -       /* setup horizontal timing values.  */
>> -       hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
>> -       hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
>> -       hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
>> -
>> -       val = VIDTCON1_HBPD(hbpd - 1) |
>> -               VIDTCON1_HFPD(hfpd - 1) |
>> -               VIDTCON1_HSPW(hsync_len - 1);
>> -       writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
>> +       if (ctx->i80_if) {
>> +               val = ctx->i80ifcon | I80IFEN_ENABLE;
>> +               writel(val, timing_base + I80IFCONFAx(0));
>> +
>> +               /* disable auto frame rate */
>> +               writel(0, timing_base + I80IFCONFBx(0));
>> +
>> +               if (ctx->vidout_con)
>> +                       writel(ctx->vidout_con, timing_base + VIDOUT_CON);
>> +
>> +               /* set video type selection to i80 interface */
>> +               if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
>> +                                       driver_data->lcdblk_off,
>> +                                       0x3 << driver_data->lcdblk_vt_shift,
>> +                                       0x1 << driver_data->lcdblk_vt_shift)) {
>> +                       DRM_ERROR("Failed to update sysreg for i80 i/f.\n");
>> +                       return;
>> +               }
>> +       } else {
>> +               int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
>> +               u32 vidcon1;
>> +
>> +               /* setup polarity values */
>> +               vidcon1 = ctx->vidcon1;
>> +               if (mode->flags & DRM_MODE_FLAG_NVSYNC)
>> +                       vidcon1 |= VIDCON1_INV_VSYNC;
>> +               if (mode->flags & DRM_MODE_FLAG_NHSYNC)
>> +                       vidcon1 |= VIDCON1_INV_HSYNC;
>> +               writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
>> +
>> +               /* setup vertical timing values. */
>> +               vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
>> +               vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
>> +               vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
>> +
>> +               val = VIDTCON0_VBPD(vbpd - 1) |
>> +                       VIDTCON0_VFPD(vfpd - 1) |
>> +                       VIDTCON0_VSPW(vsync_len - 1);
>> +               writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
>> +
>> +               /* setup horizontal timing values.  */
>> +               hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
>> +               hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
>> +               hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
>> +
>> +               val = VIDTCON1_HBPD(hbpd - 1) |
>> +                       VIDTCON1_HFPD(hfpd - 1) |
>> +                       VIDTCON1_HSPW(hsync_len - 1);
>> +               writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
>> +       }
>> +
>> +       /* set bypass selection */
>> +       if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
>> +                               driver_data->lcdblk_off,
>> +                               0x1 << driver_data->lcdblk_bypass_shift,
>> +                               0x1 << driver_data->lcdblk_bypass_shift)) {
>> +               DRM_ERROR("Failed to update sysreg for bypass setting.\n");
>> +               return;
>> +       }
>>
>>          /* setup horizontal and vertical display size. */
>>          val = VIDTCON2_LINEVAL(mode->vdisplay - 1) |
>> @@ -646,6 +732,14 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
>>          }
>>
>>          win_data->enabled = true;
>> +
>> +       if (ctx->i80_if) {
>> +               unsigned long flags;
>> +
>> +               spin_lock_irqsave(&ctx->win_updated_lock, flags);
>> +               atomic_set(&ctx->win_updated, 1);
>> +               spin_unlock_irqrestore(&ctx->win_updated_lock, flags);
>> +       }
>>   }
>>
>>   static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
>> @@ -835,6 +929,68 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
>>          }
>>   }
>>
>> +static void fimd_trigger(struct device *dev)
>> +{
>> +       struct exynos_drm_manager *mgr = get_fimd_manager(dev);
>> +       struct fimd_context *ctx = mgr->ctx;
>> +       struct fimd_driver_data *driver_data = ctx->driver_data;
>> +       void *timing_base = ctx->regs + driver_data->timing_base;
>> +       u32 reg;
>> +
>> +       atomic_set(&ctx->triggering, 1);
>> +
>> +       reg = readl(ctx->regs + VIDINTCON0);
>> +       reg |= (VIDINTCON0_INT_ENABLE | VIDINTCON0_INT_I80IFDONE |
>> +                                               VIDINTCON0_INT_SYSMAINCON);
>> +       writel(reg, ctx->regs + VIDINTCON0);
>> +
>> +       reg = readl(timing_base + TRIGCON);
>> +       reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE);
>> +       writel(reg, timing_base + TRIGCON);
>> +}
>> +
>> +static int fimd_te_handler(struct exynos_drm_manager *mgr)
>> +{
>> +       struct fimd_context *ctx = mgr->ctx;
>> +       unsigned long flags;
>> +
>> +       /* check the crtc is detached already from encoder */
>> +       if (ctx->pipe < 0 || !ctx->drm_dev)
>> +               return -EINVAL;
>> +
>> +        /*
>> +        * Skips to trigger if in triggering state, because multiple triggering
>> +        * requests can cause panel reset.
>> +        */
>> +       if (atomic_read(&ctx->triggering))
>> +               return 0;
>> +
>> +       spin_lock_irqsave(&ctx->win_updated_lock, flags);
>> +
>> +       /*
>> +        * If there is a page flip request, triggers and handles the page flip
>> +        * event so that current fb can be updated into panel GRAM.
>> +        */
>> +       if (atomic_read(&ctx->win_updated)) {
>> +               atomic_set(&ctx->win_updated, 0);
>> +
>> +               fimd_trigger(ctx->dev);
>> +       }
>> +
>> +       spin_unlock_irqrestore(&ctx->win_updated_lock, flags);
>> +
>> +       /* wake up vsync event queue */
>> +       if (atomic_read(&ctx->wait_vsync_event)) {
>> +               atomic_set(&ctx->wait_vsync_event, 0);
>> +               wake_up(&ctx->wait_vsync_queue);
>> +
>> +               if (!atomic_read(&ctx->triggering))
>> +                       drm_handle_vblank(ctx->drm_dev, ctx->pipe);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>>   static struct exynos_drm_manager_ops fimd_manager_ops = {
>>          .dpms = fimd_dpms,
>>          .mode_fixup = fimd_mode_fixup,
>> @@ -846,6 +1002,7 @@ static struct exynos_drm_manager_ops fimd_manager_ops = {
>>          .win_mode_set = fimd_win_mode_set,
>>          .win_commit = fimd_win_commit,
>>          .win_disable = fimd_win_disable,
>> +       .te_handler = fimd_te_handler,
>>   };
>>
>>   static struct exynos_drm_manager fimd_manager = {
>> @@ -856,26 +1013,40 @@ static struct exynos_drm_manager fimd_manager = {
>>   static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
>>   {
>>          struct fimd_context *ctx = (struct fimd_context *)dev_id;
>> -       u32 val;
>> +       u32 val, clear_bit;
>>
>>          val = readl(ctx->regs + VIDINTCON1);
>>
>> -       if (val & VIDINTCON1_INT_FRAME)
>> -               /* VSYNC interrupt */
>> -               writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1);
>> +       clear_bit = ctx->i80_if ? VIDINTCON1_INT_I80 : VIDINTCON1_INT_FRAME;
>> +       if (val & clear_bit)
>> +               writel(clear_bit, ctx->regs + VIDINTCON1);
>>
>>          /* check the crtc is detached already from encoder */
>>          if (ctx->pipe < 0 || !ctx->drm_dev)
>>                  goto out;
>>
>> -       drm_handle_vblank(ctx->drm_dev, ctx->pipe);
>> -       exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
>> +       if (ctx->i80_if) {
>> +               /* unset i80 frame done interrupt */
>> +               val = readl(ctx->regs + VIDINTCON0);
>> +               val &= ~(VIDINTCON0_INT_I80IFDONE | VIDINTCON0_INT_SYSMAINCON);
>> +               writel(val, ctx->regs + VIDINTCON0);
>>
>> -       /* set wait vsync event to zero and wake up queue. */
>> -       if (atomic_read(&ctx->wait_vsync_event)) {
>> -               atomic_set(&ctx->wait_vsync_event, 0);
>> -               wake_up(&ctx->wait_vsync_queue);
>> +               /* exit triggering mode */
>> +               atomic_set(&ctx->triggering, 0);
>> +
>> +               drm_handle_vblank(ctx->drm_dev, ctx->pipe);
>> +               exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
>> +       } else {
>> +               drm_handle_vblank(ctx->drm_dev, ctx->pipe);
>> +               exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
>> +
>> +               /* set wait vsync event to zero and wake up queue. */
>> +               if (atomic_read(&ctx->wait_vsync_event)) {
>> +                       atomic_set(&ctx->wait_vsync_event, 0);
>> +                       wake_up(&ctx->wait_vsync_queue);
>> +               }
>>          }
>> +
>>   out:
>>          return IRQ_HANDLED;
>>   }
>> @@ -936,12 +1107,32 @@ static int fimd_probe(struct platform_device *pdev)
>>
>>          ctx->dev = dev;
>>          ctx->suspended = true;
>> +       ctx->driver_data = drm_fimd_get_driver_data(pdev);
>>
>>          if (of_property_read_bool(dev->of_node, "samsung,invert-vden"))
>>                  ctx->vidcon1 |= VIDCON1_INV_VDEN;
>>          if (of_property_read_bool(dev->of_node, "samsung,invert-vclk"))
>>                  ctx->vidcon1 |= VIDCON1_INV_VCLK;
>>
>> +       if (of_property_read_bool(dev->of_node, "vidout-i80-ldi")) {
>> +               ctx->i80_if = true;
>> +
>> +               if (ctx->driver_data->has_vidoutcon)
>> +                       ctx->vidout_con |= VIDOUT_CON_F_I80_LDI0;
>> +               else
>> +                       ctx->vidcon0 |= VIDCON0_VIDOUT_I80_LDI0;
>> +               ctx->vidcon0 |= VIDCON0_DSI_EN;
>> +
>> +               spin_lock_init(&ctx->win_updated_lock);
>> +       }
>> +
>> +       ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
>> +                                                       "samsung,sysreg");
>> +       if (IS_ERR(ctx->sysreg)) {
>> +               dev_warn(dev, "failed to get system register.\n");
>> +               ctx->sysreg = NULL;
>> +       }
>> +
>>          ctx->bus_clk = devm_clk_get(dev, "fimd");
>>          if (IS_ERR(ctx->bus_clk)) {
>>                  dev_err(dev, "failed to get bus clock\n");
>> @@ -960,7 +1151,8 @@ static int fimd_probe(struct platform_device *pdev)
>>          if (IS_ERR(ctx->regs))
>>                  return PTR_ERR(ctx->regs);
>>
>> -       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync");
>> +       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
>> +                                       ctx->i80_if ? "lcd_sys" : "vsync");
>>          if (!res) {
>>                  dev_err(dev, "irq request failed.\n");
>>                  return -ENXIO;
>> @@ -973,7 +1165,6 @@ static int fimd_probe(struct platform_device *pdev)
>>                  return ret;
>>          }
>>
>> -       ctx->driver_data = drm_fimd_get_driver_data(pdev);
>>          init_waitqueue_head(&ctx->wait_vsync_queue);
>>          atomic_set(&ctx->wait_vsync_event, 0);
>>
>> diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
>> index b039320..eaad58b 100644
>> --- a/include/video/samsung_fimd.h
>> +++ b/include/video/samsung_fimd.h
>> @@ -19,6 +19,7 @@
>>   /* VIDCON0 */
>>
>>   #define VIDCON0                                        0x00
>> +#define VIDCON0_DSI_EN                         (1 << 30)
>>   #define VIDCON0_INTERLACE                      (1 << 29)
>>   #define VIDCON0_VIDOUT_MASK                    (0x7 << 26)
>>   #define VIDCON0_VIDOUT_SHIFT                   26
>> @@ -355,7 +356,7 @@
>>   #define VIDINTCON0_INT_ENABLE                  (1 << 0)
>>
>>   #define VIDINTCON1                             0x134
>> -#define VIDINTCON1_INT_I180                    (1 << 2)
>> +#define VIDINTCON1_INT_I80                     (1 << 2)
>>   #define VIDINTCON1_INT_FRAME                   (1 << 1)
>>   #define VIDINTCON1_INT_FIFO                    (1 << 0)
>>
>> --
>> 1.7.9.5
>>
>

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

* Re: [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings
  2014-05-28  6:44               ` Andrzej Hajda
@ 2014-05-30  3:08                 ` YoungJun Cho
  0 siblings, 0 replies; 39+ messages in thread
From: YoungJun Cho @ 2014-05-30  3:08 UTC (permalink / raw)
  To: Andrzej Hajda, Inki Dae, Thierry Reding
  Cc: mark.rutland, devicetree, linux-samsung-soc, pawel.moll,
	ijc+devicetree, sw0312.kim, dri-devel, kyungmin.park, robh+dt,
	laurent.pinchart, galak, kgene.kim, s.trumtrar

Hi ALL,

On 05/28/2014 03:44 PM, Andrzej Hajda wrote:
> On 05/28/2014 06:50 AM, Inki Dae wrote:
>> On 2014년 05월 28일 05:21, Thierry Reding wrote:
>>> On Tue, May 27, 2014 at 11:24:49PM +0900, Inki Dae wrote:
>>>> 2014-05-27 16:53 GMT+09:00 Thierry Reding <thierry.reding@gmail.com>:
>>>>> On Tue, May 27, 2014 at 08:28:52AM +0200, Andrzej Hajda wrote:
>>>>>> Hi Thierry,
>>>>>>
>>>>>> On 05/26/2014 03:41 PM, Thierry Reding wrote:
>>>>>>> On Wed, May 21, 2014 at 01:43:05PM +0900, YoungJun Cho wrote:
>>>>>>>> This patch adds DT bindings for s6e3fa0 panel.
>>>>>>>> The bindings describes panel resources, display timings and cpu mode timings.
>>>>>>>>
>>>>>>>> Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
>>>>>>>> Acked-by: Inki Dae <inki.dae@samsung.com>
>>>>>>>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>>>>>>>> ---
>>>>>>>>   .../devicetree/bindings/panel/samsung,s6e3fa0.txt  |   45 ++++++++++++++++++++
>>>>>>>>   1 file changed, 45 insertions(+)
>>>>>>>>   create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e3fa0.txt
>>>>>>> You're totally confusing me here. Half of this patch series is about
>>>>>>> adding i80 support to Exynos FIMD, and then you go and add what is
>>>>>>> apparently a DSI peripheral driver here that's supposed to be used by
>>>>>>> this new i80 support. Nothing I've been able to dig up indicates that
>>>>>>> i80 or DSI are in anyway related.
>>>>>> FIMD can produce parallel RGB output or command mode in i80 style output
>>>>>> via parallel lines.
>>>>>> DSIM can accept parallel RGB stream in this case it produces MIPI DSI
>>>>>> video mode signal or it can accept i80 and in this case it translates it
>>>>>> to MIPI DSI command mode.
>>>>> Then the command mode timings aren't a property of the panel at all.
>>>> Then the video mode timings aren't also a property of the panel.
>>>>
>>>> Which interface mipi and display controller should use would be
>>>> decided by lcd panel type: display controller can use i80 interface
>>>> based lcd panel, and also mipi controller can use i80 interface based
>>>> lcd panel.
>>>> In here, the only difference is that lcd panel receives  packets,
>>>> which includes video data or command data, packed with mipi protocol
>>>> via lane lines or receives video data or command data via parallel
>>>> lines.
>>>>
>>>> And the below is LCD types,
>>>>          RGB interface panel.
>>>>          i80 interface panel.
>>>>          MIPI based RGB interface panel.
>>>>          MIPI based i80 interface panel.
>>>>
>>>> RGB interface also is called video mode, and i80 interface also is
>>>> called cpu mode. In case of omap SoC, it is also called Smart panel.
>>>> i80 interface is just one of LCD types. So I think this interface
>>>> timings should be handled by frameworks related to mode in same way as
>>>> RGB interface.
>
> Some clarification about names.
> I am not an expert in command/cpu mode interface, so feel free to
> correct me.
> Those different terms were quite confusing for me so after some digging
> (for example here [1])
> I have found/ensured  there is a following relation between different names:
> MIPI DPI - RGB interface
> MIPI DBI type A - CPU mode m68 style
> MIPI DBI type B - CPU mode i80 style
> MIPI DBI type C - SPI, maybe also other serial interfaces (?)
> MIPI DSI - based on D-PHY-s serial protocol which can work in video or
> command mode.
>
> To add more confusion CPU mode is also named MPU mode or sys mode.
>
> To avoid confusion in the discussion I propose use i80 only to describe
> DBI type B interface,
> and DSI command mode, DSI video mode to describe DSI modes.
>
> [1]: http://www.allshore.com/pdf/DA8620.pdf
>
>
>>> LCD is a display technology, it has nothing to do with the interface. My
>>> point is that from Andrzej's description, and in fact from this patch
>>> series in general, the S6E3FA0 panel is a DSI panel. Associating timings
>>> that are i80 specific to it is therefore wrong.
>>>
>>> Consider for instance what would happen if somebody were to use the same
>>> panel on some other device (connected to a DSI controller). If you
>>> specify i80 timings for the panel then the new device won't know what to
>>> do with them because it expects DSI-related timings.
>>>
>>> Let me try to summarize the above to make sure we're all on the same
>>> page:
>>>
>>> 	- FIMD is a display controller that can be configured to either
>>> 	  send RGB data or i80 data
>>> 	- DSIM takes either RGB as input and outputs DSI (video mode) or
>>> 	  i80 as input and outputs DSI (command mode)
>>>
>>> In both cases the panel is connected to DSIM and it takes DSI as input,
>>> because it is a DSI panel (it doesn't understand RGB or i80). The panel
>>> needs to describe the properties of the DSI interface so that DSIM can
>>> be configured appropriately. DSIM in turn works as a bridge or encoder
>>> that converts RGB or i80 to DSI (video or command mode). So it makes no
>>> sense to describe the i80 timings for the panel because it has nothing
>>> to do with i80. Instead the DSIM is the hardware that needs to specify
>>> the i80 timings, so that FIMD can be configured to generate the timings
>>> that DSIM needs.
>>              CPU interface                     MIPI lane
>> FIMD ----------------------- DSIM --------------------- LCD Panel
>>
>> Hmm... reasonable. So your point is that command mode timing should be
>> placed in fimd device node, not panel device node? And panel device node
>> should provide only a property that DSIM driver can set LCD mode
>> properly to i80 or rgb interface mode, and also FIMD driver can set LCD
>> mode to i80 or rgb interface mode.
>
> I have no access to s6e3fa0 datasheet and Exynos datasheet I have access to
> is not very verbose on the subject but it seems to be reasonable that
> cs-setup, wr-setup, wr-active and wr-hold are properties only of i80
> interface,
> ie interface between FIMD and DSIM and they have nothing to do with DSI
> command mode panel.
> Those properties should be provided by DSIM to FIMD, I guess they can be
> even hardcoded
> in DSIM driver, no bindings required. There is still a question how DSIM
> should tell FIMD about them.
> I am not sure about mechanism of passing them from DSIM to FIMD, maybe
> adjusting drm_display_mode
> is a solution, maybe different way of communication should be used (I
> see here again interface_tracker use case [2]).
>
> [2]:
> http://permalink.gmane.org/gmane.linux.drivers.video-input-infrastructure/77451
>
> On the other side width, height and clock are properties of the panel so
> they should stay
> with the panel, maybe width and height could be moved from dts to
> driver, I am not sure about frequency.
>
>>
>> Is there my missing point?
>>
>> And in case of Exynos, now video timing property is also placed in panel
>> device node so it needs to move to fimd device node.
>
> No, video timings are properties of panels so they should stay in
> panels, display
> controllers should just ask panels about them.
>
>>
>> Andrzej, do you have other opinion? I have looked into dts files for
>> other SoC and In most SoC, it seems that display controller node has
>> video timing property, not panel node. Thierry's pointing seems
>> reasonable to me.
> I guess there could be many reasons: historical, backward compatibility,
> laziness of developers :).
> I agree with Thierry also.
>
> So if everybody agrees there is only one serious issue: how the i80
> properties
> should be passed from DSIM to FIMD, am I right?

Right, this issue was difficult for me.
So in my first RFC v1, I placed them in FIMD dts[1].
I didn't think of that(placed them in DSIM), moved them to panel.

[1] : http://www.spinics.net/lists/dri-devel/msg57960.html

And do you think that it is also required to rename cmdmode to i80mode?

Thank you.
Best regards YJ

>
> Regards
> Andrzej
>
>>
>> Thanks,
>> Inki Dae
>>
>>> Thierry
>>>
>>
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>

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

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

end of thread, other threads:[~2014-05-30  3:08 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-21  4:42 [PATCH v2 00/18] drm/exynos: support MIPI DSI command mode display YoungJun Cho
2014-05-21  4:42 ` [PATCH v2 01/18] drm/exynos: dsi: move the EoT packets configuration point YoungJun Cho
2014-05-21  4:42 ` [PATCH v2 02/18] drm/exynos: use wait_event_timeout() for safety usage YoungJun Cho
2014-05-21  6:01   ` Daniel Kurtz
2014-05-21  6:28     ` YoungJun Cho
2014-05-21  6:45       ` Daniel Kurtz
2014-05-21 10:37         ` YoungJun Cho
2014-05-21  4:42 ` [PATCH v2 04/18] video: add command mode and command mode display timing YoungJun Cho
2014-05-21 11:02   ` Thierry Reding
2014-05-21 11:41     ` YoungJun Cho
2014-05-22 13:07       ` Inki Dae
2014-05-22 13:53         ` Thierry Reding
2014-05-26 10:14   ` Thierry Reding
2014-05-26 11:10     ` Heiko Stübner
2014-05-21  4:42 ` [PATCH v2 05/18] drm_modes: add command mode helpers YoungJun Cho
2014-05-21  4:42 ` [PATCH v2 06/18] ARM: dts: sysreg: add exynos5 compatible to DT bindings YoungJun Cho
2014-05-21  4:42 ` [PATCH v2 07/18] ARM: dts: samsung-fimd: add I80 specific properties YoungJun Cho
     [not found] ` <1400647390-26590-1-git-send-email-yj44.cho-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2014-05-21  4:42   ` [PATCH v2 03/18] ARM: dts: video: add command mode display timing DT bindings YoungJun Cho
2014-05-21  4:43   ` [PATCH v2 08/18] drm/exynos: add TE handler to support MIPI DSI command mode interface YoungJun Cho
2014-05-21  4:43   ` [PATCH v2 15/18] ARM: dts: exynos4: add system register node YoungJun Cho
2014-05-21  4:43   ` [PATCH v2 16/18] ARM: dts: exynos5: add system register support YoungJun Cho
2014-05-21  4:43 ` [PATCH v2 09/18] drm/exynos: dsi: add TE handler to support command mode interface YoungJun Cho
2014-05-21  4:43 ` [PATCH v2 10/18] drm/exynos: fimd: support I80 interface YoungJun Cho
2014-05-26  9:00   ` Daniel Kurtz
2014-05-29  5:45     ` YoungJun Cho
2014-05-21  4:43 ` [PATCH v2 11/18] ARM: dts: exynos_dsim: add exynos5420 compatible to DT bindings YoungJun Cho
2014-05-21  4:43 ` [PATCH v2 12/18] drm/exynos: dsi: add driver data to support Exynos5420 YoungJun Cho
2014-05-21  4:43 ` [PATCH v2 13/18] ARM: dts: s6e3fa0: add DT bindings YoungJun Cho
2014-05-26 13:41   ` Thierry Reding
2014-05-27  6:28     ` Andrzej Hajda
2014-05-27  7:53       ` Thierry Reding
2014-05-27 14:24         ` Inki Dae
2014-05-27 20:21           ` Thierry Reding
2014-05-28  4:50             ` Inki Dae
2014-05-28  6:44               ` Andrzej Hajda
2014-05-30  3:08                 ` YoungJun Cho
2014-05-21  4:43 ` [PATCH v2 14/18] drm/panel: add S6E3FA0 driver YoungJun Cho
2014-05-21  4:43 ` [PATCH v2 17/18] ARM: dts: exynos5420: add mipi-phy node YoungJun Cho
2014-05-21  4:43 ` [PATCH v2 18/18] ARM: dts: exynos5420: add dsi node YoungJun Cho

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.