All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
@ 2014-02-12 11:31 Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 01/21] drm_mipi_dsi: add flags to DSI messages Andrzej Hajda
                   ` (17 more replies)
  0 siblings, 18 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

Hi,

This patchset adds drivers and bindings to the following devices:
- Exynos DSI master,
- S6E8AA0 DSI panel,
- TC358764 DSI/LVDS bridge,
- HV070WSA-100 LVDS panel.

It adds also display support in DTS files for the following boards:
- Exynos4210/Trats,
- Exynos4412/Trats2,
- Exynos5250/Arndale.

Things worth mentioning:

1. I have implemented DSI/LVDS bridge using drm_panel framework, ie.
the driver exposes drm_panel interface on DSI side, and interact with
panels on LVDS side using drm_panel framework. This approach seems to
me simpler and more natural than using drm_bridge.

2. I have used video interface bindings to make link between bridge and LVDS panel.
Other places where such links can be created are:
a) link between DSI master and slave, I wonder if it is always neccessary,
   DSI bus is also video bus,
b) link between FIMD(display controller) and DSI Master, currently Exynos DRM
   framework uses driver's hardcoded links, converting it to video interface
   bindings should be done (if required) by separate patches.

The patchset is based on Sean's Paul Exynos refactor patches v4 [1].
To work properly porch calculation should be fixed according to my comment [2].

It is the 2nd iteration of the patches, main changes:
- based on v4 refactor patches,
- added arndale related stuff.
Other changes are described in individual patches.

[1] http://permalink.gmane.org/gmane.comp.video.dri.devel/99264
[2] http://permalink.gmane.org/gmane.comp.video.dri.devel/99826

Regards
Andrzej


Andrzej Hajda (21):
  drm_mipi_dsi: add flags to DSI messages
  drm/exynos: delay fbdev initialization until an output is connected
  exynos/dsim: add DT bindings
  drm/exynos: add DSIM driver
  panel/s6e8aa0: add DT bindings
  drm/panel: add S6E8AA0 driver
  panel/tc358764: add DT bindings
  drm/panel: add TC358764 driver
  panel/simple: add video interface DT bindings
  panel/hv070wsa-100: add DT bindings
  drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
  ARM: dts: exynos4: add MIPI DSI Master node
  ARM: dts: exynos4210-trats: add panel node
  ARM: dts: exynos4412-trats2: add panel node
  ARM: dts: exynos5250: add mipi-phy node
  ARM: dts: exynos5250: add display power domain node
  ARM: dts: exynos5250: add DSI node
  ARM: dts: exynos5250-arndale: add display regulators
  ARM: dts: exynos5250-arndale: add dsi and panel nodes
  ARM: dts: exynos4210-trats: enable exynos/fimd node
  ARM: dts: exynos4412-trats2: enable exynos/fimd node

 .../devicetree/bindings/panel/boe,hv070wsa-100.txt |    7 +
 .../devicetree/bindings/panel/samsung,s6e8aa0.txt  |   51 +
 .../devicetree/bindings/panel/simple-panel.txt     |    6 +
 .../devicetree/bindings/panel/toshiba,tc358764.txt |   41 +
 .../devicetree/bindings/video/exynos_dsim.txt      |   53 +
 arch/arm/boot/dts/exynos4.dtsi                     |   14 +
 arch/arm/boot/dts/exynos4210-trats.dts             |   42 +
 arch/arm/boot/dts/exynos4412-trats2.dts            |   51 +
 arch/arm/boot/dts/exynos5250-arndale.dts           |   63 +
 arch/arm/boot/dts/exynos5250.dtsi                  |   25 +
 drivers/gpu/drm/exynos/Kconfig                     |    9 +
 drivers/gpu/drm/exynos/Makefile                    |    1 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c            |   26 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.h            |    1 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c            | 1402 ++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_fb.c             |    3 +
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c          |    4 +-
 drivers/gpu/drm/panel/Kconfig                      |   14 +
 drivers/gpu/drm/panel/Makefile                     |    2 +
 drivers/gpu/drm/panel/panel-s6e8aa0.c              | 1064 +++++++++++++++
 drivers/gpu/drm/panel/panel-simple.c               |   25 +
 drivers/gpu/drm/panel/panel-tc358764.c             |  505 +++++++
 include/drm/drm_mipi_dsi.h                         |    6 +
 23 files changed, 3402 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/panel/boe,hv070wsa-100.txt
 create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e8aa0.txt
 create mode 100644 Documentation/devicetree/bindings/panel/toshiba,tc358764.txt
 create mode 100644 Documentation/devicetree/bindings/video/exynos_dsim.txt
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_dsi.c
 create mode 100644 drivers/gpu/drm/panel/panel-s6e8aa0.c
 create mode 100644 drivers/gpu/drm/panel/panel-tc358764.c

-- 
1.8.3.2

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

* [RFC PATCH v2 01/21] drm_mipi_dsi: add flags to DSI messages
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 02/21] drm/exynos: delay fbdev initialization until an output is connected Andrzej Hajda
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

This patch adds flags field to mipi_dsi_msg structure and two flags:
- MIPI_DSI_MSG_REQ_ACK - request ACK from peripheral for given message,
- MIPI_DSI_MSG_USE_LPM - use Low Power Mode to transmit message.
The first flag is usually helpful during DSI diagnostic, the second
flag is required by some peripherals during configuration phase.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 include/drm/drm_mipi_dsi.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index d32628a..7209df1 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -17,6 +17,11 @@
 struct mipi_dsi_host;
 struct mipi_dsi_device;
 
+/* request ACK from peripheral */
+#define MIPI_DSI_MSG_REQ_ACK	BIT(0)
+/* use Low Power Mode to transmit message */
+#define MIPI_DSI_MSG_USE_LPM	BIT(1)
+
 /**
  * struct mipi_dsi_msg - read/write DSI buffer
  * @channel: virtual channel id
@@ -29,6 +34,7 @@ struct mipi_dsi_device;
 struct mipi_dsi_msg {
 	u8 channel;
 	u8 type;
+	u16 flags;
 
 	size_t tx_len;
 	const void *tx_buf;
-- 
1.8.3.2

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

* [RFC PATCH v2 02/21] drm/exynos: delay fbdev initialization until an output is connected
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 01/21] drm_mipi_dsi: add flags to DSI messages Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 12:03   ` Sachin Kamat
  2014-02-12 11:31 ` [RFC PATCH v2 03/21] exynos/dsim: add DT bindings Andrzej Hajda
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

In case fbdev is initialized before any output is connected,
fb resolution defaults to 1024x768. After that any output with
bigger resolution is ignored and fbdev is not displayed.
The patch postpones fbdev initialization to avoid such situation.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c   | 12 ------------
 drivers/gpu/drm/exynos/exynos_drm_fb.c    |  3 +++
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  4 +++-
 3 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index c8869de..0ef46fe 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -109,24 +109,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 	/* setup possible_clones. */
 	exynos_drm_encoder_setup(dev);
 
-	/*
-	 * create and configure fb helper and also exynos specific
-	 * fbdev object.
-	 */
-	ret = exynos_drm_fbdev_init(dev);
-	if (ret) {
-		DRM_ERROR("failed to initialize drm fbdev\n");
-		goto err_drm_device;
-	}
-
 	drm_vblank_offdelay = VBLANK_OFF_DELAY;
 
 	platform_set_drvdata(dev->platformdev, dev);
 
 	return 0;
 
-err_drm_device:
-	exynos_drm_device_unregister(dev);
 err_vblank:
 	drm_vblank_cleanup(dev);
 err_display_cleanup:
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index c7c08d0..65a22ca 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -20,6 +20,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
+#include "exynos_drm_fbdev.h"
 #include "exynos_drm_gem.h"
 #include "exynos_drm_iommu.h"
 #include "exynos_drm_crtc.h"
@@ -300,6 +301,8 @@ static void exynos_drm_output_poll_changed(struct drm_device *dev)
 
 	if (fb_helper)
 		drm_fb_helper_hotplug_event(fb_helper);
+	else
+		exynos_drm_fbdev_init(dev);
 }
 
 static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index e7c2f2d..9a5ec83 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -249,8 +249,10 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
 		return 0;
 
 	fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
-	if (!fbdev)
+	if (!fbdev) {
+		DRM_ERROR("failed to allocate fbdev.\n");
 		return -ENOMEM;
+	}
 
 	private->fb_helper = helper = &fbdev->drm_fb_helper;
 	helper->funcs = &exynos_drm_fb_helper_funcs;
-- 
1.8.3.2

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

* [RFC PATCH v2 03/21] exynos/dsim: add DT bindings
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 01/21] drm_mipi_dsi: add flags to DSI messages Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 02/21] drm/exynos: delay fbdev initialization until an output is connected Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-03-05  5:56   ` Inki Dae
  2014-02-12 11:31 ` [RFC PATCH v2 04/21] drm/exynos: add DSIM driver Andrzej Hajda
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds DT bindings for Exynos DSI Master. DSIM follows rules
for DSI bus host bindings [1].
Properties describes its resources: memory, interrupt, clocks,
phy, regulators and frequencies of clocks.

[1]: Documentation/devicetree/bindings/mipi/dsi/mipi-dsi-bus.txt

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
v2
- added burst and esc clock frequency properties
- add samsung prefix to all frequency props
---
 .../devicetree/bindings/video/exynos_dsim.txt      | 53 ++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/exynos_dsim.txt

diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
new file mode 100644
index 0000000..2a49704
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
@@ -0,0 +1,53 @@
+Exynos MIPI DSI Master
+
+Required properties:
+  - compatible: "samsung,exynos4210-mipi-dsi"
+  - 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
+    entry in clock-names
+  - clock-names: should include "bus_clk"and "pll_clk" entries
+  - phys: list of phy specifiers, must contain an entry for each required
+    entry in phy-names
+  - phy-names: should include "dsim" entry
+  - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)
+  - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
+  - samsung,pll-clock-frequency: specifies frequency of the "pll_clk" clock
+  - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
+    mode
+  - samsung,esc-clock-frequency: specifies DSI frequency in escape mode
+  - #address-cells, #size-cells: should be set respectively to <1> and <0>
+    according to DSI host bindings (see MIPI DSI bindings [1])
+
+Optional properties:
+  - samsung,power-domain: a phandle to DSIM power domain node
+
+Child nodes:
+  Should contain DSI peripheral nodes (see DSI bindings [1])
+
+[1]: Documentation/devicetree/bindings/mipi/dsi/mipi-dsi-bus.txt
+
+Example:
+
+	dsi@11C80000 {
+		compatible = "samsung,exynos4210-mipi-dsi";
+		reg = <0x11C80000 0x10000>;
+		interrupts = <0 79 0>;
+		clocks = <&clock 286>, <&clock 143>;
+		clock-names = "bus_clk", "pll_clk";
+		phys = <&mipi_phy 1>;
+		phy-names = "dsim";
+		vddcore-supply = <&vusb_reg>;
+		vddio-supply = <&vmipi_reg>;
+		samsung,power-domain = <&pd_lcd0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		samsung,pll-clock-frequency = <24000000>;
+		samsung,burst-clock-frequency = <500000000>;
+		samsung,esc-clock-frequency = <20000000>;
+
+		panel@0 {
+			reg = <0>;
+			...
+		};
+	};
-- 
1.8.3.2

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

* [RFC PATCH v2 04/21] drm/exynos: add DSIM driver
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (2 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 03/21] exynos/dsim: add DT bindings Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 05/21] panel/s6e8aa0: add DT bindings Andrzej Hajda
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds driver for Exynos DSI master (DSIM). It is a platform driver
which is registered as exynos_drm_display sub-driver of exynos_drm framework
and implements DRM encoder/connector pair.
It is also MIPI-DSI host driver and provides DSI bus for panels.
It interacts with its panel(s) using drm_panel framework.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
v2
- add support for DSI message flags,
- add support for new DT properties,
- remove brightness DRM property,
- corrected PM handlers,
- minor fixes/improvements
---
 drivers/gpu/drm/exynos/Kconfig          |    9 +
 drivers/gpu/drm/exynos/Makefile         |    1 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c |   14 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h |    1 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 1402 +++++++++++++++++++++++++++++++
 5 files changed, 1427 insertions(+)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_dsi.c

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 7eea698..f0fc681 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -31,6 +31,15 @@ config DRM_EXYNOS_FIMD
 	help
 	  Choose this option if you want to use Exynos FIMD for DRM.
 
+config DRM_EXYNOS_DSI
+	bool "EXYNOS DRM MIPI-DSI driver support"
+	depends on DRM_EXYNOS
+	select DRM_MIPI_DSI
+	select DRM_PANEL
+	default n
+	help
+	  This enables support for Exynos MIPI-DSI device.
+
 config DRM_EXYNOS_DP
 	bool "EXYNOS DRM DP driver support"
 	depends on DRM_EXYNOS && ARCH_EXYNOS
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index b1839e8..02dde22 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -11,6 +11,7 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_DSI)	+= exynos_drm_dsi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_DP)	+= exynos_dp_core.o exynos_dp_reg.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)	+= exynos_hdmi.o exynos_mixer.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI)	+= exynos_drm_vidi.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 0ef46fe..cba25b1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -444,6 +444,12 @@ static int __init exynos_drm_init(void)
 		goto out_dp;
 #endif
 
+#ifdef CONFIG_DRM_EXYNOS_DSI
+	ret = platform_driver_register(&dsi_driver);
+	if (ret < 0)
+		goto out_dsi;
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_FIMD
 	ret = platform_driver_register(&fimd_driver);
 	if (ret < 0)
@@ -559,6 +565,10 @@ out_hdmi:
 	platform_driver_unregister(&fimd_driver);
 out_fimd:
 #endif
+#ifdef CONFIG_DRM_EXYNOS_DSI
+	platform_driver_unregister(&dsi_driver);
+out_dsi:
+#endif
 #ifdef CONFIG_DRM_EXYNOS_DP
 	platform_driver_unregister(&dp_driver);
 out_dp:
@@ -606,6 +616,10 @@ static void __exit exynos_drm_exit(void)
 	platform_driver_unregister(&fimd_driver);
 #endif
 
+#ifdef CONFIG_DRM_EXYNOS_DSI
+	platform_driver_unregister(&dsi_driver);
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_DP
 	platform_driver_unregister(&dp_driver);
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 1c78806..6135135 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -362,6 +362,7 @@ int exynos_platform_device_ipp_register(void);
 void exynos_platform_device_ipp_unregister(void);
 
 extern struct platform_driver dp_driver;
+extern struct platform_driver dsi_driver;
 extern struct platform_driver fimd_driver;
 extern struct platform_driver hdmi_driver;
 extern struct platform_driver mixer_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
new file mode 100644
index 0000000..6d3d994
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -0,0 +1,1402 @@
+/*
+ * Samsung SoC MIPI DSI Master driver.
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *
+ * Contacts: Tomasz Figa <t.figa@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_crtc_helper.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/phy/phy.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+#include <video/videomode.h>
+
+#include "exynos_drm_drv.h"
+
+/* returns true iff both arguments logically differs */
+#define NEQV(a, b) (!(a) ^ !(b))
+
+#define DSIM_STATUS_REG		0x0	/* Status register */
+#define DSIM_SWRST_REG		0x4	/* Software reset register */
+#define DSIM_CLKCTRL_REG	0x8	/* Clock control register */
+#define DSIM_TIMEOUT_REG	0xc	/* Time out register */
+#define DSIM_CONFIG_REG		0x10	/* Configuration register */
+#define DSIM_ESCMODE_REG	0x14	/* Escape mode register */
+
+/* Main display image resolution register */
+#define DSIM_MDRESOL_REG	0x18
+#define DSIM_MVPORCH_REG	0x1c	/* Main display Vporch register */
+#define DSIM_MHPORCH_REG	0x20	/* Main display Hporch register */
+#define DSIM_MSYNC_REG		0x24	/* Main display sync area register */
+
+/* Sub display image resolution register */
+#define DSIM_SDRESOL_REG	0x28
+#define DSIM_INTSRC_REG		0x2c	/* Interrupt source register */
+#define DSIM_INTMSK_REG		0x30	/* Interrupt mask register */
+#define DSIM_PKTHDR_REG		0x34	/* Packet Header FIFO register */
+#define DSIM_PAYLOAD_REG	0x38	/* Payload FIFO register */
+#define DSIM_RXFIFO_REG		0x3c	/* Read FIFO register */
+#define DSIM_FIFOTHLD_REG	0x40	/* FIFO threshold level register */
+#define DSIM_FIFOCTRL_REG	0x44	/* FIFO status and control register */
+
+/* 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 */
+
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x)		(((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK		(1 << 8)
+#define DSIM_TX_READY_HS_CLK		(1 << 10)
+#define DSIM_PLL_STABLE			(1 << 31)
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST			(1 << 16)
+#define DSIM_SWRST			(1 << 0)
+
+/* DSIM_TIMEOUT */
+#define DSIM_LPDR_TIMEOUT(x)		((x) << 0)
+#define DSIM_BTA_TIMEOUT(x)		((x) << 16)
+
+/* DSIM_CLKCTRL */
+#define DSIM_ESC_PRESCALER(x)		(((x) & 0xffff) << 0)
+#define DSIM_ESC_PRESCALER_MASK		(0xffff << 0)
+#define DSIM_LANE_ESC_CLK_EN_CLK	(1 << 19)
+#define DSIM_LANE_ESC_CLK_EN_DATA(x)	(((x) & 0xf) << 20)
+#define DSIM_LANE_ESC_CLK_EN_DATA_MASK	(0xf << 20)
+#define DSIM_BYTE_CLKEN			(1 << 24)
+#define DSIM_BYTE_CLK_SRC(x)		(((x) & 0x3) << 25)
+#define DSIM_BYTE_CLK_SRC_MASK		(0x3 << 25)
+#define DSIM_PLL_BYPASS			(1 << 27)
+#define DSIM_ESC_CLKEN			(1 << 28)
+#define DSIM_TX_REQUEST_HSCLK		(1 << 31)
+
+/* DSIM_CONFIG */
+#define DSIM_LANE_EN_CLK		(1 << 0)
+#define DSIM_LANE_EN(x)			(((x) & 0xf) << 1)
+#define DSIM_NUM_OF_DATA_LANE(x)	(((x) & 0x3) << 5)
+#define DSIM_SUB_PIX_FORMAT(x)		(((x) & 0x7) << 8)
+#define DSIM_MAIN_PIX_FORMAT_MASK	(0x7 << 12)
+#define DSIM_MAIN_PIX_FORMAT_RGB888	(0x7 << 12)
+#define DSIM_MAIN_PIX_FORMAT_RGB666	(0x6 << 12)
+#define DSIM_MAIN_PIX_FORMAT_RGB666_P	(0x5 << 12)
+#define DSIM_MAIN_PIX_FORMAT_RGB565	(0x4 << 12)
+#define DSIM_SUB_VC			(((x) & 0x3) << 16)
+#define DSIM_MAIN_VC			(((x) & 0x3) << 18)
+#define DSIM_HSA_MODE			(1 << 20)
+#define DSIM_HBP_MODE			(1 << 21)
+#define DSIM_HFP_MODE			(1 << 22)
+#define DSIM_HSE_MODE			(1 << 23)
+#define DSIM_AUTO_MODE			(1 << 24)
+#define DSIM_VIDEO_MODE			(1 << 25)
+#define DSIM_BURST_MODE			(1 << 26)
+#define DSIM_SYNC_INFORM		(1 << 27)
+#define DSIM_EOT_DISABLE		(1 << 28)
+#define DSIM_MFLUSH_VS			(1 << 29)
+
+/* DSIM_ESCMODE */
+#define DSIM_TX_TRIGGER_RST		(1 << 4)
+#define DSIM_TX_LPDT_LP			(1 << 6)
+#define DSIM_CMD_LPDT_LP		(1 << 7)
+#define DSIM_FORCE_BTA			(1 << 16)
+#define DSIM_FORCE_STOP_STATE		(1 << 20)
+#define DSIM_STOP_STATE_CNT(x)		(((x) & 0x7ff) << 21)
+#define DSIM_STOP_STATE_CNT_MASK	(0x7ff << 21)
+
+/* DSIM_MDRESOL */
+#define DSIM_MAIN_STAND_BY		(1 << 31)
+#define DSIM_MAIN_VRESOL(x)		(((x) & 0x7ff) << 16)
+#define DSIM_MAIN_HRESOL(x)		(((x) & 0X7ff) << 0)
+
+/* DSIM_MVPORCH */
+#define DSIM_CMD_ALLOW(x)		((x) << 28)
+#define DSIM_STABLE_VFP(x)		((x) << 16)
+#define DSIM_MAIN_VBP(x)		((x) << 0)
+#define DSIM_CMD_ALLOW_MASK		(0xf << 28)
+#define DSIM_STABLE_VFP_MASK		(0x7ff << 16)
+#define DSIM_MAIN_VBP_MASK		(0x7ff << 0)
+
+/* DSIM_MHPORCH */
+#define DSIM_MAIN_HFP(x)		((x) << 16)
+#define DSIM_MAIN_HBP(x)		((x) << 0)
+#define DSIM_MAIN_HFP_MASK		((0xffff) << 16)
+#define DSIM_MAIN_HBP_MASK		((0xffff) << 0)
+
+/* DSIM_MSYNC */
+#define DSIM_MAIN_VSA(x)		((x) << 22)
+#define DSIM_MAIN_HSA(x)		((x) << 0)
+#define DSIM_MAIN_VSA_MASK		((0x3ff) << 22)
+#define DSIM_MAIN_HSA_MASK		((0xffff) << 0)
+
+/* DSIM_SDRESOL */
+#define DSIM_SUB_STANDY(x)		((x) << 31)
+#define DSIM_SUB_VRESOL(x)		((x) << 16)
+#define DSIM_SUB_HRESOL(x)		((x) << 0)
+#define DSIM_SUB_STANDY_MASK		((0x1) << 31)
+#define DSIM_SUB_VRESOL_MASK		((0x7ff) << 16)
+#define DSIM_SUB_HRESOL_MASK		((0x7ff) << 0)
+
+/* DSIM_INTSRC */
+#define DSIM_INT_PLL_STABLE		(1 << 31)
+#define DSIM_INT_SW_RST_RELEASE		(1 << 30)
+#define DSIM_INT_SFR_FIFO_EMPTY		(1 << 29)
+#define DSIM_INT_BTA			(1 << 25)
+#define DSIM_INT_FRAME_DONE		(1 << 24)
+#define DSIM_INT_RX_TIMEOUT		(1 << 21)
+#define DSIM_INT_BTA_TIMEOUT		(1 << 20)
+#define DSIM_INT_RX_DONE		(1 << 18)
+#define DSIM_INT_RX_TE			(1 << 17)
+#define DSIM_INT_RX_ACK			(1 << 16)
+#define DSIM_INT_RX_ECC_ERR		(1 << 15)
+#define DSIM_INT_RX_CRC_ERR		(1 << 14)
+
+/* DSIM_FIFOCTRL */
+#define DSIM_RX_DATA_FULL		(1 << 25)
+#define DSIM_RX_DATA_EMPTY		(1 << 24)
+#define DSIM_SFR_HEADER_FULL		(1 << 23)
+#define DSIM_SFR_HEADER_EMPTY		(1 << 22)
+#define DSIM_SFR_PAYLOAD_FULL		(1 << 21)
+#define DSIM_SFR_PAYLOAD_EMPTY		(1 << 20)
+#define DSIM_I80_HEADER_FULL		(1 << 19)
+#define DSIM_I80_HEADER_EMPTY		(1 << 18)
+#define DSIM_I80_PAYLOAD_FULL		(1 << 17)
+#define DSIM_I80_PAYLOAD_EMPTY		(1 << 16)
+#define DSIM_SD_HEADER_FULL		(1 << 15)
+#define DSIM_SD_HEADER_EMPTY		(1 << 14)
+#define DSIM_SD_PAYLOAD_FULL		(1 << 13)
+#define DSIM_SD_PAYLOAD_EMPTY		(1 << 12)
+#define DSIM_MD_HEADER_FULL		(1 << 11)
+#define DSIM_MD_HEADER_EMPTY		(1 << 10)
+#define DSIM_MD_PAYLOAD_FULL		(1 << 9)
+#define DSIM_MD_PAYLOAD_EMPTY		(1 << 8)
+#define DSIM_RX_FIFO			(1 << 4)
+#define DSIM_SFR_FIFO			(1 << 3)
+#define DSIM_I80_FIFO			(1 << 2)
+#define DSIM_SD_FIFO			(1 << 1)
+#define DSIM_MD_FIFO			(1 << 0)
+
+/* DSIM_PHYACCHR */
+#define DSIM_AFC_EN			(1 << 14)
+#define DSIM_AFC_CTL(x)			(((x) & 0x7) << 5)
+
+/* DSIM_PLLCTRL */
+#define DSIM_FREQ_BAND(x)		((x) << 24)
+#define DSIM_PLL_EN			(1 << 23)
+#define DSIM_PLL_P(x)			((x) << 13)
+#define DSIM_PLL_M(x)			((x) << 4)
+#define DSIM_PLL_S(x)			((x) << 1)
+
+#define DSI_MAX_BUS_WIDTH		4
+#define DSI_NUM_VIRTUAL_CHANNELS	4
+#define DSI_TX_FIFO_SIZE		2048
+#define DSI_RX_FIFO_SIZE		256
+#define DSI_XFER_TIMEOUT_MS		100
+#define DSI_RX_FIFO_EMPTY		0x30800002
+
+enum exynos_dsi_transfer_type {
+	EXYNOS_DSI_TX,
+	EXYNOS_DSI_RX,
+};
+
+struct exynos_dsi_transfer {
+	struct list_head list;
+	struct completion completed;
+	int result;
+	u8 data_id;
+	u8 data[2];
+	u16 flags;
+
+	const u8 *tx_payload;
+	u16 tx_len;
+	u16 tx_done;
+
+	u8 *rx_payload;
+	u16 rx_len;
+	u16 rx_done;
+};
+
+#define DSIM_STATE_INITIALIZED		BIT(0)
+#define DSIM_STATE_CMD_LPM		BIT(1)
+
+struct exynos_dsi {
+	struct mipi_dsi_host dsi_host;
+	struct drm_connector connector;
+	struct drm_device *drm_dev;
+	struct drm_encoder *encoder;
+	struct drm_panel *panel;
+	struct device *dev;
+
+	void __iomem *reg_base;
+	struct phy *phy;
+	struct clk *pll_clk;
+	struct clk *bus_clk;
+	struct regulator_bulk_data supplies[2];
+	int irq;
+
+	u32 pll_clk_rate;
+	u32 burst_clk_rate;
+	u32 esc_clk_rate;
+	u32 lanes;
+	u32 mode_flags;
+	u32 format;
+	struct videomode vm;
+
+	int dpms_mode;
+	int state;
+	struct drm_property *brightness;
+	struct completion completed;
+
+	spinlock_t transfer_lock; /* protects transfer_list */
+	struct list_head transfer_list;
+};
+
+#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 void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi)
+{
+	if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300)))
+		return;
+
+	dev_err(dsi->dev, "timeout waiting for reset\n");
+}
+
+static void exynos_dsi_reset(struct exynos_dsi *dsi)
+{
+	reinit_completion(&dsi->completed);
+	writel(DSIM_SWRST, dsi->reg_base + DSIM_SWRST_REG);
+}
+
+#ifndef MHZ
+#define MHZ	(1000*1000)
+#endif
+
+static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi,
+		unsigned long fin, unsigned long fout, u8 *p, u16 *m, u8 *s)
+{
+	unsigned long best_freq = 0;
+	u32 min_delta = 0xffffffff;
+	u8 p_min, p_max;
+	u8 _p, uninitialized_var(best_p);
+	u16 _m, uninitialized_var(best_m);
+	u8 _s, uninitialized_var(best_s);
+
+	p_min = DIV_ROUND_UP(fin, (12 * MHZ));
+	p_max = fin / (6 * MHZ);
+
+	for (_p = p_min; _p <= p_max; ++_p) {
+		for (_s = 0; _s <= 5; ++_s) {
+			u64 tmp;
+			u32 delta;
+
+			tmp = (u64)fout * (_p << _s);
+			do_div(tmp, fin);
+			_m = tmp;
+			if (_m < 41 || _m > 125)
+				continue;
+
+			tmp = (u64)_m * fin;
+			do_div(tmp, _p);
+			if (tmp < 500 * MHZ || tmp > 1000 * MHZ)
+				continue;
+
+			tmp = (u64)_m * fin;
+			do_div(tmp, _p << _s);
+
+			delta = abs(fout - tmp);
+			if (delta < min_delta) {
+				best_p = _p;
+				best_m = _m;
+				best_s = _s;
+				min_delta = delta;
+				best_freq = tmp;
+			}
+		}
+	}
+
+	if (best_freq) {
+		*p = best_p;
+		*m = best_m;
+		*s = best_s;
+	}
+
+	return best_freq;
+}
+
+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,
+	};
+	unsigned long fin, fout;
+	int timeout, band;
+	u8 p, s;
+	u16 m;
+	u32 reg;
+
+	clk_set_rate(dsi->pll_clk, dsi->pll_clk_rate);
+
+	fin = clk_get_rate(dsi->pll_clk);
+	if (!fin) {
+		dev_err(dsi->dev, "failed to get PLL clock frequency\n");
+		return 0;
+	}
+
+	dev_dbg(dsi->dev, "PLL input frequency: %lu\n", fin);
+
+	fout = exynos_dsi_pll_find_pms(dsi, fin, freq, &p, &m, &s);
+	if (!fout) {
+		dev_err(dsi->dev,
+			"failed to find PLL PMS for requested frequency\n");
+		return -EFAULT;
+	}
+
+	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);
+
+	writel(500, dsi->reg_base + DSIM_PLLTMR_REG);
+
+	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;
+	do {
+		if (timeout-- == 0) {
+			dev_err(dsi->dev, "PLL failed to stabilize\n");
+			return -EFAULT;
+		}
+		reg = readl(dsi->reg_base + DSIM_STATUS_REG);
+	} while ((reg & DSIM_PLL_STABLE) == 0);
+
+	return fout;
+}
+
+static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
+{
+	unsigned long hs_clk, byte_clk, esc_clk;
+	unsigned long esc_div;
+	u32 reg;
+
+	hs_clk = exynos_dsi_set_pll(dsi, dsi->burst_clk_rate);
+	if (!hs_clk) {
+		dev_err(dsi->dev, "failed to configure DSI PLL\n");
+		return -EFAULT;
+	}
+
+	byte_clk = hs_clk / 8;
+	esc_div = DIV_ROUND_UP(byte_clk, dsi->esc_clk_rate);
+	esc_clk = byte_clk / esc_div;
+
+	if (esc_clk > 20 * MHZ) {
+		++esc_div;
+		esc_clk = byte_clk / esc_div;
+	}
+
+	dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",
+		hs_clk, byte_clk, esc_clk);
+
+	reg = readl(dsi->reg_base + DSIM_CLKCTRL_REG);
+	reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK
+			| DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS
+			| DSIM_BYTE_CLK_SRC_MASK);
+	reg |= DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN
+			| DSIM_ESC_PRESCALER(esc_div)
+			| DSIM_LANE_ESC_CLK_EN_CLK
+			| DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1)
+			| DSIM_BYTE_CLK_SRC(0)
+			| DSIM_TX_REQUEST_HSCLK;
+	writel(reg, dsi->reg_base + DSIM_CLKCTRL_REG);
+
+	return 0;
+}
+
+static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
+{
+	u32 reg;
+
+	reg = readl(dsi->reg_base + DSIM_CLKCTRL_REG);
+	reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK
+			| DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN);
+	writel(reg, dsi->reg_base + DSIM_CLKCTRL_REG);
+
+	reg = readl(dsi->reg_base + DSIM_PLLCTRL_REG);
+	reg &= ~DSIM_PLL_EN;
+	writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG);
+}
+
+static int exynos_dsi_init_link(struct exynos_dsi *dsi)
+{
+	int timeout;
+	u32 reg;
+	u32 lanes_mask;
+
+	/* Initialize FIFO pointers */
+	reg = readl(dsi->reg_base + DSIM_FIFOCTRL_REG);
+	reg &= ~0x1f;
+	writel(reg, dsi->reg_base + DSIM_FIFOCTRL_REG);
+
+	usleep_range(9000, 11000);
+
+	reg |= 0x1f;
+	writel(reg, dsi->reg_base + DSIM_FIFOCTRL_REG);
+
+	usleep_range(9000, 11000);
+
+	/* DSI configuration */
+	reg = 0;
+
+	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
+		reg |= DSIM_VIDEO_MODE;
+
+		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)
+			reg |= DSIM_BURST_MODE;
+		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_AUTO_VERT)
+			reg |= DSIM_AUTO_MODE;
+		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HSE)
+			reg |= DSIM_HSE_MODE;
+		if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HFP))
+			reg |= DSIM_HFP_MODE;
+		if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HBP))
+			reg |= DSIM_HBP_MODE;
+		if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HSA))
+			reg |= DSIM_HSA_MODE;
+	}
+
+	switch (dsi->format) {
+	case MIPI_DSI_FMT_RGB888:
+		reg |= DSIM_MAIN_PIX_FORMAT_RGB888;
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		reg |= DSIM_MAIN_PIX_FORMAT_RGB666;
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		reg |= DSIM_MAIN_PIX_FORMAT_RGB666_P;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		reg |= DSIM_MAIN_PIX_FORMAT_RGB565;
+		break;
+	default:
+		dev_err(dsi->dev, "invalid pixel format\n");
+		return -EINVAL;
+	}
+
+	reg |= DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1);
+
+	writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
+
+	reg |= DSIM_LANE_EN_CLK;
+	writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
+
+	lanes_mask = BIT(dsi->lanes) - 1;
+	reg |= DSIM_LANE_EN(lanes_mask);
+	writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
+
+	/* Check clock and data lane state are stop state */
+	timeout = 100;
+	do {
+		if (timeout-- == 0) {
+			dev_err(dsi->dev, "waiting for bus lanes timed out\n");
+			return -EFAULT;
+		}
+
+		reg = readl(dsi->reg_base + DSIM_STATUS_REG);
+		if ((reg & DSIM_STOP_STATE_DAT(lanes_mask))
+		    != DSIM_STOP_STATE_DAT(lanes_mask))
+			continue;
+	} while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));
+
+	reg = readl(dsi->reg_base + DSIM_ESCMODE_REG);
+	reg &= ~DSIM_STOP_STATE_CNT_MASK;
+	reg |= DSIM_STOP_STATE_CNT(0xf);
+	writel(reg, dsi->reg_base + DSIM_ESCMODE_REG);
+
+	reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);
+	writel(reg, dsi->reg_base + DSIM_TIMEOUT_REG);
+
+	return 0;
+}
+
+static int exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
+{
+	struct videomode *vm = &dsi->vm;
+	u32 reg;
+
+	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
+		reg = DSIM_CMD_ALLOW(0xf)
+			| DSIM_STABLE_VFP(vm->vfront_porch)
+			| DSIM_MAIN_VBP(vm->vback_porch);
+		writel(reg, dsi->reg_base + DSIM_MVPORCH_REG);
+
+		reg = DSIM_MAIN_HFP(vm->hfront_porch)
+			| DSIM_MAIN_HBP(vm->hback_porch);
+		writel(reg, dsi->reg_base + DSIM_MHPORCH_REG);
+
+		reg = DSIM_MAIN_VSA(vm->vsync_len)
+			| DSIM_MAIN_HSA(vm->hsync_len);
+		writel(reg, dsi->reg_base + DSIM_MSYNC_REG);
+	}
+
+	reg = DSIM_MAIN_HRESOL(vm->hactive) | DSIM_MAIN_VRESOL(vm->vactive);
+	writel(reg, dsi->reg_base + DSIM_MDRESOL_REG);
+
+	dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive);
+
+	return 0;
+}
+
+static void exynos_dsi_set_display_enable(struct exynos_dsi *dsi, bool enable)
+{
+	u32 reg;
+
+	reg = readl(dsi->reg_base + DSIM_MDRESOL_REG);
+	if (enable)
+		reg |= DSIM_MAIN_STAND_BY;
+	else
+		reg &= ~DSIM_MAIN_STAND_BY;
+	writel(reg, dsi->reg_base + DSIM_MDRESOL_REG);
+}
+
+static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
+{
+	int timeout = 2000;
+
+	do {
+		u32 reg = readl(dsi->reg_base + DSIM_FIFOCTRL_REG);
+
+		if (!(reg & DSIM_SFR_HEADER_FULL))
+			return 0;
+
+		if (!cond_resched())
+			usleep_range(950, 1050);
+	} while (--timeout);
+
+	return -ETIMEDOUT;
+}
+
+static void exynos_dsi_set_cmd_lpm(struct exynos_dsi *dsi, bool lpm)
+{
+	u32 v = readl(dsi->reg_base + DSIM_ESCMODE_REG);
+
+	if (lpm)
+		v |= DSIM_CMD_LPDT_LP;
+	else
+		v &= ~DSIM_CMD_LPDT_LP;
+
+	writel(v, dsi->reg_base + DSIM_ESCMODE_REG);
+}
+
+static void exynos_dsi_force_bta(struct exynos_dsi *dsi)
+{
+	u32 v = readl(dsi->reg_base + DSIM_ESCMODE_REG);
+
+	v |= DSIM_FORCE_BTA;
+	writel(v, dsi->reg_base + DSIM_ESCMODE_REG);
+}
+
+static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
+					struct exynos_dsi_transfer *xfer)
+{
+	struct device *dev = dsi->dev;
+	const u8 *payload = xfer->tx_payload + xfer->tx_done;
+	u16 length = xfer->tx_len - xfer->tx_done;
+	bool first = !xfer->tx_done;
+	u32 reg;
+
+	dev_dbg(dev, "< xfer %p: tx len %u, done %u, rx len %u, done %u\n",
+		xfer, xfer->tx_len, xfer->tx_done, xfer->rx_len, xfer->rx_done);
+
+	if (length > DSI_TX_FIFO_SIZE)
+		length = DSI_TX_FIFO_SIZE;
+
+	xfer->tx_done += length;
+
+	/* Send payload */
+	while (length >= 4) {
+		reg = (payload[3] << 24) | (payload[2] << 16)
+					| (payload[1] << 8) | payload[0];
+		writel(reg, dsi->reg_base + DSIM_PAYLOAD_REG);
+		payload += 4;
+		length -= 4;
+	}
+
+	reg = 0;
+	switch (length) {
+	case 3:
+		reg |= payload[2] << 16;
+		/* Fall through */
+	case 2:
+		reg |= payload[1] << 8;
+		/* Fall through */
+	case 1:
+		reg |= payload[0];
+		writel(reg, dsi->reg_base + DSIM_PAYLOAD_REG);
+		break;
+	case 0:
+		/* Do nothing */
+		break;
+	}
+
+	/* Send packet header */
+	if (!first)
+		return;
+
+	reg = (xfer->data[1] << 16) | (xfer->data[0] << 8) | xfer->data_id;
+	if (exynos_dsi_wait_for_hdr_fifo(dsi)) {
+		dev_err(dev, "waiting for header FIFO timed out\n");
+		return;
+	}
+
+	if (NEQV(xfer->flags & MIPI_DSI_MSG_USE_LPM,
+		 dsi->state & DSIM_STATE_CMD_LPM)) {
+		exynos_dsi_set_cmd_lpm(dsi, xfer->flags & MIPI_DSI_MSG_USE_LPM);
+		dsi->state ^= DSIM_STATE_CMD_LPM;
+	}
+
+	writel(reg, dsi->reg_base + DSIM_PKTHDR_REG);
+
+	if (xfer->flags & MIPI_DSI_MSG_REQ_ACK)
+		exynos_dsi_force_bta(dsi);
+}
+
+static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
+					struct exynos_dsi_transfer *xfer)
+{
+	u8 *payload = xfer->rx_payload + xfer->rx_done;
+	bool first = !xfer->rx_done;
+	struct device *dev = dsi->dev;
+	u16 length;
+	u32 reg;
+
+	if (first) {
+		reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
+
+		switch (reg & 0x3f) {
+		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
+		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
+			if (xfer->rx_len >= 2) {
+				payload[1] = reg >> 16;
+				++xfer->rx_done;
+			}
+			/* Fall through */
+		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
+		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
+			payload[0] = reg >> 8;
+			++xfer->rx_done;
+			xfer->rx_len = xfer->rx_done;
+			xfer->result = 0;
+			goto clear_fifo;
+		case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
+			dev_err(dev, "DSI Error Report: 0x%04x\n",
+				(reg >> 8) & 0xffff);
+			xfer->result = 0;
+			goto clear_fifo;
+		}
+
+		length = (reg >> 8) & 0xffff;
+		if (length > xfer->rx_len) {
+			dev_err(dev,
+				"response too long (%u > %u bytes), stripping\n",
+				xfer->rx_len, length);
+			length = xfer->rx_len;
+		} else if (length < xfer->rx_len)
+			xfer->rx_len = length;
+	}
+
+	length = xfer->rx_len - xfer->rx_done;
+	xfer->rx_done += length;
+
+	/* Receive payload */
+	while (length >= 4) {
+		reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
+		payload[0] = (reg >>  0) & 0xff;
+		payload[1] = (reg >>  8) & 0xff;
+		payload[2] = (reg >> 16) & 0xff;
+		payload[3] = (reg >> 24) & 0xff;
+		payload += 4;
+		length -= 4;
+	}
+
+	if (length) {
+		reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
+		switch (length) {
+		case 3:
+			payload[2] = (reg >> 16) & 0xff;
+			/* Fall through */
+		case 2:
+			payload[1] = (reg >> 8) & 0xff;
+			/* Fall through */
+		case 1:
+			payload[0] = reg & 0xff;
+		}
+	}
+
+	if (xfer->rx_done == xfer->rx_len)
+		xfer->result = 0;
+
+clear_fifo:
+	length = DSI_RX_FIFO_SIZE / 4;
+	do {
+		reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
+		if (reg == DSI_RX_FIFO_EMPTY)
+			break;
+	} while (--length);
+}
+
+static void exynos_dsi_transfer_start(struct exynos_dsi *dsi)
+{
+	unsigned long flags;
+	struct exynos_dsi_transfer *xfer;
+	bool start = false;
+
+again:
+	spin_lock_irqsave(&dsi->transfer_lock, flags);
+
+	if (list_empty(&dsi->transfer_list)) {
+		spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+		return;
+	}
+
+	xfer = list_first_entry(&dsi->transfer_list,
+					struct exynos_dsi_transfer, list);
+
+	spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+
+	if (xfer->tx_len && xfer->tx_done == xfer->tx_len)
+		/* waiting for RX */
+		return;
+
+	exynos_dsi_send_to_fifo(dsi, xfer);
+
+	if (xfer->tx_len || xfer->rx_len)
+		return;
+
+	xfer->result = 0;
+	complete(&xfer->completed);
+
+	spin_lock_irqsave(&dsi->transfer_lock, flags);
+
+	list_del_init(&xfer->list);
+	start = !list_empty(&dsi->transfer_list);
+
+	spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+
+	if (start)
+		goto again;
+}
+
+static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
+{
+	struct exynos_dsi_transfer *xfer;
+	unsigned long flags;
+	bool start = true;
+
+	spin_lock_irqsave(&dsi->transfer_lock, flags);
+
+	if (list_empty(&dsi->transfer_list)) {
+		spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+		return false;
+	}
+
+	xfer = list_first_entry(&dsi->transfer_list,
+					struct exynos_dsi_transfer, list);
+
+	spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+
+	dev_dbg(dsi->dev,
+		"> xfer %p, tx_len %u, tx_done %u, rx_len %u, rx_done %u\n",
+		xfer, xfer->tx_len, xfer->tx_done, xfer->rx_len, xfer->rx_done);
+
+	if (xfer->tx_done != xfer->tx_len)
+		return true;
+
+	if (xfer->rx_done != xfer->rx_len)
+		exynos_dsi_read_from_fifo(dsi, xfer);
+
+	if (xfer->rx_done != xfer->rx_len)
+		return true;
+
+	spin_lock_irqsave(&dsi->transfer_lock, flags);
+
+	list_del_init(&xfer->list);
+	start = !list_empty(&dsi->transfer_list);
+
+	spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+
+	if (!xfer->rx_len)
+		xfer->result = 0;
+	complete(&xfer->completed);
+
+	return start;
+}
+
+static void exynos_dsi_remove_transfer(struct exynos_dsi *dsi,
+					struct exynos_dsi_transfer *xfer)
+{
+	unsigned long flags;
+	bool start;
+
+	spin_lock_irqsave(&dsi->transfer_lock, flags);
+
+	if (!list_empty(&dsi->transfer_list) &&
+	    xfer == list_first_entry(&dsi->transfer_list,
+				     struct exynos_dsi_transfer, list)) {
+		list_del_init(&xfer->list);
+		start = !list_empty(&dsi->transfer_list);
+		spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+		if (start)
+			exynos_dsi_transfer_start(dsi);
+		return;
+	}
+
+	list_del_init(&xfer->list);
+
+	spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+}
+
+static int exynos_dsi_transfer(struct exynos_dsi *dsi,
+					struct exynos_dsi_transfer *xfer)
+{
+	unsigned long flags;
+	bool stopped;
+
+	xfer->tx_done = 0;
+	xfer->rx_done = 0;
+	xfer->result = -ETIMEDOUT;
+	init_completion(&xfer->completed);
+
+	spin_lock_irqsave(&dsi->transfer_lock, flags);
+
+	stopped = list_empty(&dsi->transfer_list);
+	list_add_tail(&xfer->list, &dsi->transfer_list);
+
+	spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+
+	if (stopped)
+		exynos_dsi_transfer_start(dsi);
+
+	wait_for_completion_timeout(&xfer->completed,
+				    msecs_to_jiffies(DSI_XFER_TIMEOUT_MS));
+	if (xfer->result == -ETIMEDOUT) {
+		exynos_dsi_remove_transfer(dsi, xfer);
+		dev_err(dsi->dev, "xfer timed out: %*ph %*ph\n", 2, xfer->data,
+			xfer->tx_len, xfer->tx_payload);
+		return -ETIMEDOUT;
+	}
+
+	/* Also covers hardware timeout condition */
+	return xfer->result;
+}
+
+static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
+{
+	struct exynos_dsi *dsi = dev_id;
+	u32 status;
+
+	status = readl(dsi->reg_base + DSIM_INTSRC_REG);
+	if (!status) {
+		static unsigned long int j;
+		if (printk_timed_ratelimit(&j, 500))
+			dev_warn(dsi->dev, "spurious interrupt\n");
+		return IRQ_HANDLED;
+	}
+	writel(status, dsi->reg_base + DSIM_INTSRC_REG);
+
+	if (status & DSIM_INT_SW_RST_RELEASE) {
+		u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY);
+		writel(mask, dsi->reg_base + DSIM_INTMSK_REG);
+		complete(&dsi->completed);
+		return IRQ_HANDLED;
+	}
+
+	if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY)))
+		return IRQ_HANDLED;
+
+	if (exynos_dsi_transfer_finish(dsi))
+		exynos_dsi_transfer_start(dsi);
+
+	return IRQ_HANDLED;
+}
+
+static int exynos_dsi_init(struct exynos_dsi *dsi)
+{
+	exynos_dsi_enable_clock(dsi);
+	exynos_dsi_reset(dsi);
+	enable_irq(dsi->irq);
+	exynos_dsi_wait_for_reset(dsi);
+	exynos_dsi_init_link(dsi);
+
+	return 0;
+}
+
+static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
+				  struct mipi_dsi_device *device)
+{
+	struct exynos_dsi *dsi = host_to_dsi(host);
+
+	dsi->lanes = device->lanes;
+	dsi->format = device->format;
+	dsi->mode_flags = device->mode_flags;
+
+	dsi->panel = of_drm_find_panel(device->dev.of_node);
+	if (dsi->panel && dsi->connector.dev) {
+		drm_panel_attach(dsi->panel, &dsi->connector);
+		drm_helper_hpd_irq_event(dsi->connector.dev);
+	}
+
+	return 0;
+}
+
+static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
+				  struct mipi_dsi_device *device)
+{
+	struct exynos_dsi *dsi = host_to_dsi(host);
+
+	dsi->panel = NULL;
+
+	return 0;
+}
+
+/* distinguish between short and long DSI packet types */
+static bool exynos_dsi_is_short_dsi_type(u8 type)
+{
+	return (type & 0x0f) <= 8;
+}
+
+static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
+				       struct mipi_dsi_msg *msg)
+{
+	struct exynos_dsi *dsi = host_to_dsi(host);
+	struct exynos_dsi_transfer xfer;
+	int ret;
+
+	if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
+		ret = exynos_dsi_init(dsi);
+		if (ret)
+			return ret;
+		dsi->state |= DSIM_STATE_INITIALIZED;
+	}
+
+	if (msg->tx_len == 0)
+		return -EINVAL;
+
+	xfer.data_id = msg->type | (msg->channel << 6);
+
+	if (exynos_dsi_is_short_dsi_type(msg->type)) {
+		const char *tx_buf = msg->tx_buf;
+
+		if (msg->tx_len > 2)
+			return -EINVAL;
+		xfer.tx_len = 0;
+		xfer.data[0] = tx_buf[0];
+		xfer.data[1] = (msg->tx_len == 2) ? tx_buf[1] : 0;
+	} else {
+		xfer.tx_len = msg->tx_len;
+		xfer.data[0] = msg->tx_len & 0xff;
+		xfer.data[1] = msg->tx_len >> 8;
+		xfer.tx_payload = msg->tx_buf;
+	}
+
+	xfer.rx_len = msg->rx_len;
+	xfer.rx_payload = msg->rx_buf;
+	xfer.flags = msg->flags;
+
+	ret = exynos_dsi_transfer(dsi, &xfer);
+	return (ret < 0) ? ret : xfer.rx_done;
+}
+
+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,
+};
+
+static enum drm_connector_status
+exynos_dsi_detect(struct drm_connector *connector, bool force)
+{
+	struct exynos_dsi *dsi = connector_to_dsi(connector);
+
+	if (dsi->panel)
+		return connector_status_connected;
+	else
+		return connector_status_disconnected;
+}
+
+static void exynos_dsi_connector_destroy(struct drm_connector *connector)
+{
+}
+
+static struct drm_connector_funcs exynos_dsi_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.detect = exynos_dsi_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = exynos_dsi_connector_destroy,
+};
+
+static int exynos_dsi_get_modes(struct drm_connector *connector)
+{
+	struct exynos_dsi *dsi = connector_to_dsi(connector);
+
+	if (dsi->panel)
+		return dsi->panel->funcs->get_modes(dsi->panel);
+
+	return 0;
+}
+
+static int exynos_dsi_mode_valid(struct drm_connector *connector,
+				 struct drm_display_mode *mode)
+{
+	return MODE_OK;
+}
+
+static struct drm_encoder *
+exynos_dsi_best_encoder(struct drm_connector *connector)
+{
+	struct exynos_dsi *dsi = connector_to_dsi(connector);
+
+	return dsi->encoder;
+}
+
+static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
+	.get_modes = exynos_dsi_get_modes,
+	.mode_valid = exynos_dsi_mode_valid,
+	.best_encoder = exynos_dsi_best_encoder,
+};
+
+static int exynos_dsi_initialize(struct exynos_drm_display *display,
+				 struct drm_device *drm_dev)
+{
+	struct exynos_dsi *dsi = display->ctx;
+
+	dsi->drm_dev = drm_dev;
+
+	return 0;
+}
+
+static int exynos_dsi_create_connector(struct exynos_drm_display *display,
+				       struct drm_encoder *encoder)
+{
+	struct exynos_dsi *dsi = display->ctx;
+	struct drm_connector *connector = &dsi->connector;
+	int ret;
+
+	dsi->encoder = encoder;
+
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	ret = drm_connector_init(dsi->drm_dev, connector,
+				 &exynos_dsi_connector_funcs,
+				 DRM_MODE_CONNECTOR_DSI);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector with drm\n");
+		return ret;
+	}
+
+	drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
+	drm_sysfs_connector_add(connector);
+	drm_mode_connector_attach_encoder(connector, encoder);
+
+	return 0;
+}
+
+static void exynos_dsi_poweron(struct exynos_dsi *dsi)
+{
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
+	if (ret < 0)
+		dev_err(dsi->dev, "cannot enable regulators %d\n", ret);
+
+	clk_prepare_enable(dsi->bus_clk);
+	clk_prepare_enable(dsi->pll_clk);
+
+	phy_power_on(dsi->phy);
+}
+
+static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
+{
+	int ret;
+
+	usleep_range(10000, 20000);
+
+	if (dsi->state & DSIM_STATE_INITIALIZED) {
+		dsi->state &= ~DSIM_STATE_INITIALIZED;
+
+		exynos_dsi_disable_clock(dsi);
+
+		disable_irq(dsi->irq);
+	}
+
+	dsi->state &= ~DSIM_STATE_CMD_LPM;
+
+	phy_power_off(dsi->phy);
+
+	clk_disable_unprepare(dsi->pll_clk);
+	clk_disable_unprepare(dsi->bus_clk);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
+	if (ret < 0)
+		dev_err(dsi->dev, "cannot disable regulators %d\n", ret);
+}
+
+void exynos_dsi_mode_set(struct exynos_drm_display *display,
+			 struct drm_display_mode *mode)
+{
+	struct exynos_dsi *dsi = display->ctx;
+	struct videomode *vm = &dsi->vm;
+
+	vm->hactive = mode->hdisplay;
+	vm->vactive = mode->vdisplay;
+	vm->vfront_porch = mode->vsync_start - mode->vdisplay;
+	vm->vback_porch = mode->vtotal - mode->vsync_end;
+	vm->vsync_len = mode->vsync_end - mode->vsync_start;
+	vm->hfront_porch = mode->hsync_start - mode->hdisplay;
+	vm->hback_porch = mode->htotal - mode->hsync_end;
+	vm->hsync_len = mode->hsync_end - mode->hsync_start;
+}
+
+static void exynos_dsi_enable(struct exynos_dsi *dsi)
+{
+	exynos_dsi_poweron(dsi);
+	drm_panel_enable(dsi->panel);
+	exynos_dsi_set_display_mode(dsi);
+	exynos_dsi_set_display_enable(dsi, true);
+}
+
+static void exynos_dsi_disable(struct exynos_dsi *dsi)
+{
+	exynos_dsi_set_display_enable(dsi, false);
+	drm_panel_disable(dsi->panel);
+	exynos_dsi_poweroff(dsi);
+}
+
+static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode)
+{
+	struct exynos_dsi *dsi = display->ctx;
+
+	if (dsi->panel) {
+		switch (mode) {
+		case DRM_MODE_DPMS_ON:
+			if (dsi->dpms_mode != DRM_MODE_DPMS_ON)
+				exynos_dsi_enable(dsi);
+			break;
+		case DRM_MODE_DPMS_STANDBY:
+		case DRM_MODE_DPMS_SUSPEND:
+		case DRM_MODE_DPMS_OFF:
+			if (dsi->dpms_mode == DRM_MODE_DPMS_ON)
+				exynos_dsi_disable(dsi);
+			break;
+		default:
+			break;
+		};
+	}
+	dsi->dpms_mode = mode;
+}
+
+static struct exynos_drm_display_ops exynos_dsi_display_ops = {
+	.initialize = exynos_dsi_initialize,
+	.create_connector = exynos_dsi_create_connector,
+	.mode_set = exynos_dsi_mode_set,
+	.dpms = exynos_dsi_dpms
+};
+
+static struct exynos_drm_display exynos_dsi_display = {
+	.type = EXYNOS_DISPLAY_TYPE_LCD,
+	.ops = &exynos_dsi_display_ops,
+};
+
+static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
+{
+	struct device *dev = dsi->dev;
+	struct device_node *node = dev->of_node;
+	struct {
+		const char * const name;
+		u32 *val;
+	} props[] = {
+		{ "samsung,pll-clock-frequency", &dsi->pll_clk_rate },
+		{ "samsung,burst-clock-frequency", &dsi->burst_clk_rate },
+		{ "samsung,esc-clock-frequency", &dsi->esc_clk_rate },
+	};
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(props); ++i) {
+		ret = of_property_read_u32(node, props[i].name, props[i].val);
+		if (ret) {
+			dev_err(dev, "failed to get '%s' property\n",
+				props[i].name);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int exynos_dsi_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct exynos_dsi *dsi;
+	int ret;
+
+	dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
+	if (!dsi) {
+		dev_err(&pdev->dev, "failed to allocate dsi object.\n");
+		return -ENOMEM;
+	}
+
+	init_completion(&dsi->completed);
+	spin_lock_init(&dsi->transfer_lock);
+	INIT_LIST_HEAD(&dsi->transfer_list);
+
+	dsi->dsi_host.ops = &exynos_dsi_ops;
+	dsi->dsi_host.dev = &pdev->dev;
+
+	dsi->dev = &pdev->dev;
+	dsi->dpms_mode = DRM_MODE_DPMS_OFF;
+
+	ret = exynos_dsi_parse_dt(dsi);
+	if (ret)
+		return ret;
+
+	dsi->supplies[0].supply = "vddcore";
+	dsi->supplies[1].supply = "vddio";
+	ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(dsi->supplies),
+				      dsi->supplies);
+	if (ret) {
+		dev_info(&pdev->dev, "failed to get regulators: %d\n", ret);
+		return -EPROBE_DEFER;
+	}
+
+	dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk");
+	if (IS_ERR(dsi->pll_clk)) {
+		dev_info(&pdev->dev, "failed to get dsi pll input clock\n");
+		return -EPROBE_DEFER;
+	}
+
+	dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");
+	if (IS_ERR(dsi->bus_clk)) {
+		dev_info(&pdev->dev, "failed to get dsi bus clock\n");
+		return -EPROBE_DEFER;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dsi->reg_base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!dsi->reg_base) {
+		dev_err(&pdev->dev, "failed to remap io region\n");
+		return -EADDRNOTAVAIL;
+	}
+
+	dsi->phy = devm_phy_get(&pdev->dev, "dsim");
+	if (IS_ERR(dsi->phy)) {
+		dev_info(&pdev->dev, "failed to get dsim phy\n");
+		return -EPROBE_DEFER;
+	}
+
+	dsi->irq = platform_get_irq(pdev, 0);
+	if (dsi->irq < 0) {
+		dev_err(&pdev->dev, "failed to request dsi irq resource\n");
+		return dsi->irq;
+	}
+
+	irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(&pdev->dev, dsi->irq, NULL,
+					exynos_dsi_irq, IRQF_ONESHOT,
+					dev_name(&pdev->dev), dsi);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request dsi irq\n");
+		return ret;
+	}
+
+	exynos_dsi_display.ctx = dsi;
+
+	platform_set_drvdata(pdev, &exynos_dsi_display);
+	exynos_drm_display_register(&exynos_dsi_display);
+
+	return mipi_dsi_host_register(&dsi->dsi_host);
+}
+
+static int exynos_dsi_remove(struct platform_device *pdev)
+{
+	struct exynos_dsi *dsi = exynos_dsi_display.ctx;
+
+	exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF);
+
+	exynos_drm_display_unregister(&exynos_dsi_display);
+	mipi_dsi_host_unregister(&dsi->dsi_host);
+
+	return 0;
+}
+
+#if CONFIG_PM_SLEEP
+static int exynos_dsi_resume(struct device *dev)
+{
+	struct exynos_dsi *dsi = exynos_dsi_display.ctx;
+
+	if (dsi->dpms_mode == DRM_MODE_DPMS_ON)
+		exynos_dsi_enable(dsi);
+
+	return 0;
+}
+
+static int exynos_dsi_suspend(struct device *dev)
+{
+	struct exynos_dsi *dsi = exynos_dsi_display.ctx;
+
+	if (dsi->dpms_mode == DRM_MODE_DPMS_ON)
+		exynos_dsi_disable(dsi);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops exynos_dsi_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(exynos_dsi_suspend, exynos_dsi_resume)
+};
+
+static struct of_device_id exynos_dsi_of_match[] = {
+	{ .compatible = "samsung,exynos4210-mipi-dsi" },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
+struct platform_driver dsi_driver = {
+	.probe = exynos_dsi_probe,
+	.remove = exynos_dsi_remove,
+	.driver = {
+		   .name = "exynos-dsi",
+		   .owner = THIS_MODULE,
+		   .pm = &exynos_dsi_pm_ops,
+		   .of_match_table = exynos_dsi_of_match,
+	},
+};
+
+MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
+MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
+MODULE_DESCRIPTION("Samsung SoC MIPI DSI Master");
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2

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

* [RFC PATCH v2 05/21] panel/s6e8aa0: add DT bindings
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (3 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 04/21] drm/exynos: add DSIM driver Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 06/21] drm/panel: add S6E8AA0 driver Andrzej Hajda
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds bindings for s6e8aa0 panel.
Bindings describes panel resources, boot delays,
display timings, orientation and physical size.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
v2
- removed samsung prefix from panel physical size props,
- renamed file to follow convention of panel bindings
---
 .../devicetree/bindings/panel/samsung,s6e8aa0.txt  | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e8aa0.txt

diff --git a/Documentation/devicetree/bindings/panel/samsung,s6e8aa0.txt b/Documentation/devicetree/bindings/panel/samsung,s6e8aa0.txt
new file mode 100644
index 0000000..75a64db
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/samsung,s6e8aa0.txt
@@ -0,0 +1,51 @@
+Samsung S6E8AA0 AMOLED LCD 5.3 inch panel
+
+Required properties:
+  - compatible: "samsung,s6e8aa0"
+  - reg: the virtual channel number of a DSI peripheral
+  - vdd3-supply: core voltage supply
+  - vci-supply: voltage supply for analog circuits
+  - reset-gpio: a GPIO spec for the reset pin
+  - display-timings: timings for the connected panel as described by [1]
+
+Optional properties:
+  - power-on-delay: delay after turning regulators on [ms]
+  - reset-delay: delay after reset sequence [ms]
+  - init-delay: delay after initialization sequence [ms]
+  - panel-width-mm: physical panel width [mm]
+  - panel-height-mm: physical panel height [mm]
+  - flip-horizontal: boolean to flip image horizontally
+  - flip-vertical: boolean to flip image vertically
+
+[1]: Documentation/devicetree/bindings/video/display-timing.txt
+
+Example:
+
+	panel {
+		compatible = "samsung,s6e8aa0";
+		reg = <0>;
+		vdd3-supply = <&vcclcd_reg>;
+		vci-supply = <&vlcd_reg>;
+		reset-gpio = <&gpy4 5 0>;
+		power-on-delay= <50>;
+		reset-delay = <100>;
+		init-delay = <100>;
+		panel-width-mm = <58>;
+		panel-height-mm = <103>;
+		flip-horizontal;
+		flip-vertical;
+
+		display-timings {
+			timing0: timing-0 {
+				clock-frequency = <57153600>;
+				hactive = <720>;
+				vactive = <1280>;
+				hfront-porch = <5>;
+				hback-porch = <5>;
+				hsync-len = <5>;
+				vfront-porch = <13>;
+				vback-porch = <1>;
+				vsync-len = <2>;
+			};
+		};
+	};
-- 
1.8.3.2

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

* [RFC PATCH v2 06/21] drm/panel: add S6E8AA0 driver
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (4 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 05/21] panel/s6e8aa0: add DT bindings Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 07/21] panel/tc358764: add DT bindings Andrzej Hajda
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds MIPI-DSI based S6E8AA0 AMOLED LCD panel driver.
Driver uses mipi_dsi bus to communicate with panel and exposes drm_panel
interface.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
v2
- added bus error handling,
- set maxmimum DSI packet size on init,
- removed unsupported brightness drm_panel callbacks,
- minor improvements
---
 drivers/gpu/drm/panel/Kconfig         |    7 +
 drivers/gpu/drm/panel/Makefile        |    1 +
 drivers/gpu/drm/panel/panel-s6e8aa0.c | 1064 +++++++++++++++++++++++++++++++++
 3 files changed, 1072 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-s6e8aa0.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 3e0f13d..7527557 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -16,4 +16,11 @@ config DRM_PANEL_SIMPLE
 	  that it can be automatically turned off when the panel goes into a
 	  low power state.
 
+config DRM_PANEL_S6E8AA0
+	tristate "S6E8AA0 DSI video mode panel"
+	depends on DRM && DRM_PANEL
+	depends on OF
+	select DRM_MIPI_DSI
+	select VIDEOMODE_HELPERS
+
 endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index af9dfa2..181265b 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
+obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
diff --git a/drivers/gpu/drm/panel/panel-s6e8aa0.c b/drivers/gpu/drm/panel/panel-s6e8aa0.c
new file mode 100644
index 0000000..f762c9d
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-s6e8aa0.c
@@ -0,0 +1,1064 @@
+/*
+ * MIPI-DSI based s6e8aa0 AMOLED LCD 5.3 inch panel driver.
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd
+ *
+ * Inki Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ * Joongmock Shin <jmock.shin@samsung.com>
+ * Eunchul Kim <chulspro.kim@samsung.com>
+ * Tomasz Figa <t.figa@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.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#define LDI_MTP_LENGTH			24
+#define GAMMA_LEVEL_NUM			25
+#define GAMMA_TABLE_LEN			26
+
+#define PANELCTL_SS_MASK		(1 << 5)
+#define PANELCTL_SS_1_800		(0 << 5)
+#define PANELCTL_SS_800_1		(1 << 5)
+#define PANELCTL_GTCON_MASK		(7 << 2)
+#define PANELCTL_GTCON_110		(6 << 2)
+#define PANELCTL_GTCON_111		(7 << 2)
+
+#define PANELCTL_CLK1_CON_MASK		(7 << 3)
+#define PANELCTL_CLK1_000		(0 << 3)
+#define PANELCTL_CLK1_001		(1 << 3)
+#define PANELCTL_CLK2_CON_MASK		(7 << 0)
+#define PANELCTL_CLK2_000		(0 << 0)
+#define PANELCTL_CLK2_001		(1 << 0)
+
+#define PANELCTL_INT1_CON_MASK		(7 << 3)
+#define PANELCTL_INT1_000		(0 << 3)
+#define PANELCTL_INT1_001		(1 << 3)
+#define PANELCTL_INT2_CON_MASK		(7 << 0)
+#define PANELCTL_INT2_000		(0 << 0)
+#define PANELCTL_INT2_001		(1 << 0)
+
+#define PANELCTL_BICTL_CON_MASK		(7 << 3)
+#define PANELCTL_BICTL_000		(0 << 3)
+#define PANELCTL_BICTL_001		(1 << 3)
+#define PANELCTL_BICTLB_CON_MASK	(7 << 0)
+#define PANELCTL_BICTLB_000		(0 << 0)
+#define PANELCTL_BICTLB_001		(1 << 0)
+
+#define PANELCTL_EM_CLK1_CON_MASK	(7 << 3)
+#define PANELCTL_EM_CLK1_110		(6 << 3)
+#define PANELCTL_EM_CLK1_111		(7 << 3)
+#define PANELCTL_EM_CLK1B_CON_MASK	(7 << 0)
+#define PANELCTL_EM_CLK1B_110		(6 << 0)
+#define PANELCTL_EM_CLK1B_111		(7 << 0)
+
+#define PANELCTL_EM_CLK2_CON_MASK	(7 << 3)
+#define PANELCTL_EM_CLK2_110		(6 << 3)
+#define PANELCTL_EM_CLK2_111		(7 << 3)
+#define PANELCTL_EM_CLK2B_CON_MASK	(7 << 0)
+#define PANELCTL_EM_CLK2B_110		(6 << 0)
+#define PANELCTL_EM_CLK2B_111		(7 << 0)
+
+#define PANELCTL_EM_INT1_CON_MASK	(7 << 3)
+#define PANELCTL_EM_INT1_000		(0 << 3)
+#define PANELCTL_EM_INT1_001		(1 << 3)
+#define PANELCTL_EM_INT2_CON_MASK	(7 << 0)
+#define PANELCTL_EM_INT2_000		(0 << 0)
+#define PANELCTL_EM_INT2_001		(1 << 0)
+
+#define AID_DISABLE			(0x4)
+#define AID_1				(0x5)
+#define AID_2				(0x6)
+#define AID_3				(0x7)
+
+typedef u8 s6e8aa0_gamma_table[GAMMA_TABLE_LEN];
+
+struct s6e8aa0_variant {
+	u8 version;
+	const s6e8aa0_gamma_table *gamma_tables;
+};
+
+struct s6e8aa0 {
+	struct device *dev;
+	struct drm_panel panel;
+
+	struct regulator_bulk_data supplies[2];
+	int reset_gpio;
+	u32 power_on_delay;
+	u32 reset_delay;
+	u32 init_delay;
+	bool flip_horizontal;
+	bool flip_vertical;
+	struct videomode vm;
+	u32 width_mm;
+	u32 height_mm;
+
+	u8 version;
+	u8 id;
+	const struct s6e8aa0_variant *variant;
+	int brightness;
+
+	/* This field is tested by functions directly accessing DSI bus before
+	 * transfer, transfer is skipped if it is set. In case of transfer
+	 * failure or unexpected response the field is set to error value.
+	 * Such construct allows to eliminate many checks in higher level
+	 * functions.
+	 */
+	int error;
+};
+
+#define panel_to_s6e8aa0(p) container_of(p, struct s6e8aa0, panel)
+
+static int s6e8aa0_clear_error(struct s6e8aa0 *ctx)
+{
+	int ret = ctx->error;
+
+	ctx->error = 0;
+	return ret;
+}
+
+static void s6e8aa0_dcs_write(struct s6e8aa0 *ctx, const void *data, size_t len)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	int ret;
+
+	if (ctx->error < 0)
+		return;
+
+	ret = mipi_dsi_dcs_write(dsi, dsi->channel, data, len);
+	if (ret < 0) {
+		dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret, len,
+			data);
+		ctx->error = ret;
+	}
+}
+
+static int s6e8aa0_dcs_read(struct s6e8aa0 *ctx, u8 cmd, void *data, size_t len)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	int ret;
+
+	if (ctx->error < 0)
+		return ctx->error;
+
+	ret = mipi_dsi_dcs_read(dsi, dsi->channel, cmd, data, len);
+	if (ret < 0) {
+		dev_err(ctx->dev, "error %d reading dcs seq(%#x)\n", ret, cmd);
+		ctx->error = ret;
+	}
+
+	return ret;
+}
+
+#define s6e8aa0_dcs_write_seq(ctx, seq...) \
+({\
+	const u8 d[] = { seq };\
+	BUILD_BUG_ON_MSG(ARRAY_SIZE(d) > 64, "DCS sequence too big for stack");\
+	s6e8aa0_dcs_write(ctx, d, ARRAY_SIZE(d));\
+})
+
+#define s6e8aa0_dcs_write_seq_static(ctx, seq...) \
+({\
+	static const u8 d[] = { seq };\
+	s6e8aa0_dcs_write(ctx, d, ARRAY_SIZE(d));\
+})
+
+static void s6e8aa0_apply_level_1_key(struct s6e8aa0 *ctx)
+{
+	s6e8aa0_dcs_write_seq_static(ctx, 0xf0, 0x5a, 0x5a);
+}
+
+static void s6e8aa0_panel_cond_set_v142(struct s6e8aa0 *ctx)
+{
+	static const u8 aids[] = {
+		0x04, 0x04, 0x04, 0x04, 0x04, 0x60, 0x80, 0xA0
+	};
+	u8 aid = aids[ctx->id >> 5];
+	u8 cfg = 0x3d;
+	u8 clk_con = 0xc8;
+	u8 int_con = 0x08;
+	u8 bictl_con = 0x48;
+	u8 em_clk1_con = 0xff;
+	u8 em_clk2_con = 0xff;
+	u8 em_int_con = 0xc8;
+
+	if (ctx->flip_vertical) {
+		/* GTCON */
+		cfg &= ~(PANELCTL_GTCON_MASK);
+		cfg |= (PANELCTL_GTCON_110);
+	}
+
+	if (ctx->flip_horizontal) {
+		/* SS */
+		cfg &= ~(PANELCTL_SS_MASK);
+		cfg |= (PANELCTL_SS_1_800);
+	}
+
+	if (ctx->flip_horizontal || ctx->flip_vertical) {
+		/* CLK1,2_CON */
+		clk_con &= ~(PANELCTL_CLK1_CON_MASK |
+			PANELCTL_CLK2_CON_MASK);
+		clk_con |= (PANELCTL_CLK1_000 | PANELCTL_CLK2_001);
+
+		/* INT1,2_CON */
+		int_con &= ~(PANELCTL_INT1_CON_MASK |
+			PANELCTL_INT2_CON_MASK);
+		int_con |= (PANELCTL_INT1_000 | PANELCTL_INT2_001);
+
+		/* BICTL,B_CON */
+		bictl_con &= ~(PANELCTL_BICTL_CON_MASK |
+			PANELCTL_BICTLB_CON_MASK);
+		bictl_con |= (PANELCTL_BICTL_000 |
+			PANELCTL_BICTLB_001);
+
+		/* EM_CLK1,1B_CON */
+		em_clk1_con &= ~(PANELCTL_EM_CLK1_CON_MASK |
+			PANELCTL_EM_CLK1B_CON_MASK);
+		em_clk1_con |= (PANELCTL_EM_CLK1_110 |
+			PANELCTL_EM_CLK1B_110);
+
+		/* EM_CLK2,2B_CON */
+		em_clk2_con &= ~(PANELCTL_EM_CLK2_CON_MASK |
+			PANELCTL_EM_CLK2B_CON_MASK);
+		em_clk2_con |= (PANELCTL_EM_CLK2_110 |
+			PANELCTL_EM_CLK2B_110);
+
+		/* EM_INT1,2_CON */
+		em_int_con &= ~(PANELCTL_EM_INT1_CON_MASK |
+			PANELCTL_EM_INT2_CON_MASK);
+		em_int_con |= (PANELCTL_EM_INT1_000 |
+			PANELCTL_EM_INT2_001);
+	}
+
+	s6e8aa0_dcs_write_seq(ctx,
+		0xf8, cfg, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00,
+		0x3c, 0x78, 0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00,
+		0x00, 0x20, aid, 0x08, 0x6e, 0x00, 0x00, 0x00,
+		0x02, 0x07, 0x07, 0x23, 0x23, 0xc0, clk_con, int_con,
+		bictl_con, 0xc1, 0x00, 0xc1, em_clk1_con, em_clk2_con,
+		em_int_con);
+}
+
+static void s6e8aa0_panel_cond_set(struct s6e8aa0 *ctx)
+{
+	if (ctx->version < 142)
+		s6e8aa0_dcs_write_seq_static(ctx,
+			0xf8, 0x19, 0x35, 0x00, 0x00, 0x00, 0x94, 0x00,
+			0x3c, 0x78, 0x10, 0x27, 0x08, 0x6e, 0x00, 0x00,
+			0x00, 0x00, 0x04, 0x08, 0x6e, 0x00, 0x00, 0x00,
+			0x00, 0x07, 0x07, 0x23, 0x6e, 0xc0, 0xc1, 0x01,
+			0x81, 0xc1, 0x00, 0xc3, 0xf6, 0xf6, 0xc1
+		);
+	else
+		s6e8aa0_panel_cond_set_v142(ctx);
+}
+
+static void s6e8aa0_display_condition_set(struct s6e8aa0 *ctx)
+{
+	s6e8aa0_dcs_write_seq_static(ctx, 0xf2, 0x80, 0x03, 0x0d);
+}
+
+static void s6e8aa0_etc_source_control(struct s6e8aa0 *ctx)
+{
+	s6e8aa0_dcs_write_seq_static(ctx, 0xf6, 0x00, 0x02, 0x00);
+}
+
+static void s6e8aa0_etc_pentile_control(struct s6e8aa0 *ctx)
+{
+	static const u8 pent32[] = {
+		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xc0, 0x44, 0x44, 0xc0, 0x00
+	};
+
+	static const u8 pent142[] = {
+		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0, 0x00
+	};
+
+	if (ctx->version < 142)
+		s6e8aa0_dcs_write(ctx, pent32, ARRAY_SIZE(pent32));
+	else
+		s6e8aa0_dcs_write(ctx, pent142, ARRAY_SIZE(pent142));
+}
+
+static void s6e8aa0_etc_power_control(struct s6e8aa0 *ctx)
+{
+	static const u8 pwr142[] = {
+		0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x1e, 0x33, 0x02
+	};
+
+	static const u8 pwr32[] = {
+		0xf4, 0xcf, 0x0a, 0x15, 0x10, 0x19, 0x33, 0x02
+	};
+
+	if (ctx->version < 142)
+		s6e8aa0_dcs_write(ctx, pwr32, ARRAY_SIZE(pwr32));
+	else
+		s6e8aa0_dcs_write(ctx, pwr142, ARRAY_SIZE(pwr142));
+}
+
+static void s6e8aa0_etc_elvss_control(struct s6e8aa0 *ctx)
+{
+	u8 id = ctx->id ? 0 : 0x95;
+
+	s6e8aa0_dcs_write_seq(ctx, 0xb1, 0x04, id);
+}
+
+static void s6e8aa0_elvss_nvm_set_v142(struct s6e8aa0 *ctx)
+{
+	u8 br;
+
+	switch (ctx->brightness) {
+	case 0 ... 6: /* 30cd ~ 100cd */
+		br = 0xdf;
+		break;
+	case 7 ... 11: /* 120cd ~ 150cd */
+		br = 0xdd;
+		break;
+	case 12 ... 15: /* 180cd ~ 210cd */
+	default:
+		br = 0xd9;
+		break;
+	case 16 ... 24: /* 240cd ~ 300cd */
+		br = 0xd0;
+		break;
+	}
+
+	s6e8aa0_dcs_write_seq(ctx, 0xd9, 0x14, 0x40, 0x0c, 0xcb, 0xce, 0x6e,
+		0xc4, 0x0f, 0x40, 0x41, br, 0x00, 0x60, 0x19);
+}
+
+static void s6e8aa0_elvss_nvm_set(struct s6e8aa0 *ctx)
+{
+	if (ctx->version < 142)
+		s6e8aa0_dcs_write_seq_static(ctx,
+			0xd9, 0x14, 0x40, 0x0c, 0xcb, 0xce, 0x6e, 0xc4, 0x07,
+			0x40, 0x41, 0xc1, 0x00, 0x60, 0x19);
+	else
+		s6e8aa0_elvss_nvm_set_v142(ctx);
+};
+
+static void s6e8aa0_apply_level_2_key(struct s6e8aa0 *ctx)
+{
+	s6e8aa0_dcs_write_seq_static(ctx, 0xfc, 0x5a, 0x5a);
+}
+
+static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v142[GAMMA_LEVEL_NUM] = {
+	{
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x62, 0x55, 0x55,
+		0xaf, 0xb1, 0xb1, 0xbd, 0xce, 0xb7, 0x9a, 0xb1,
+		0x90, 0xb2, 0xc4, 0xae, 0x00, 0x60, 0x00, 0x40,
+		0x00, 0x70,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x74, 0x68, 0x69,
+		0xb8, 0xc1, 0xb7, 0xbd, 0xcd, 0xb8, 0x93, 0xab,
+		0x88, 0xb4, 0xc4, 0xb1, 0x00, 0x6b, 0x00, 0x4d,
+		0x00, 0x7d,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x95, 0x8a, 0x89,
+		0xb4, 0xc6, 0xb2, 0xc5, 0xd2, 0xbf, 0x90, 0xa8,
+		0x85, 0xb5, 0xc4, 0xb3, 0x00, 0x7b, 0x00, 0x5d,
+		0x00, 0x8f,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9f, 0x98, 0x92,
+		0xb3, 0xc4, 0xb0, 0xbc, 0xcc, 0xb4, 0x91, 0xa6,
+		0x87, 0xb5, 0xc5, 0xb4, 0x00, 0x87, 0x00, 0x6a,
+		0x00, 0x9e,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x99, 0x93, 0x8b,
+		0xb2, 0xc2, 0xb0, 0xbd, 0xce, 0xb4, 0x90, 0xa6,
+		0x87, 0xb3, 0xc3, 0xb2, 0x00, 0x8d, 0x00, 0x70,
+		0x00, 0xa4,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xa5, 0x99,
+		0xb2, 0xc2, 0xb0, 0xbb, 0xcd, 0xb1, 0x93, 0xa7,
+		0x8a, 0xb2, 0xc1, 0xb0, 0x00, 0x92, 0x00, 0x75,
+		0x00, 0xaa,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa0, 0xa0, 0x93,
+		0xb6, 0xc4, 0xb4, 0xb5, 0xc8, 0xaa, 0x94, 0xa9,
+		0x8c, 0xb2, 0xc0, 0xb0, 0x00, 0x97, 0x00, 0x7a,
+		0x00, 0xaf,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xa7, 0x96,
+		0xb3, 0xc2, 0xb0, 0xba, 0xcb, 0xb0, 0x94, 0xa8,
+		0x8c, 0xb0, 0xbf, 0xaf, 0x00, 0x9f, 0x00, 0x83,
+		0x00, 0xb9,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9d, 0xa2, 0x90,
+		0xb6, 0xc5, 0xb3, 0xb8, 0xc9, 0xae, 0x94, 0xa8,
+		0x8d, 0xaf, 0xbd, 0xad, 0x00, 0xa4, 0x00, 0x88,
+		0x00, 0xbf,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa6, 0xac, 0x97,
+		0xb4, 0xc4, 0xb1, 0xbb, 0xcb, 0xb2, 0x93, 0xa7,
+		0x8d, 0xae, 0xbc, 0xad, 0x00, 0xa7, 0x00, 0x8c,
+		0x00, 0xc3,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa2, 0xa9, 0x93,
+		0xb6, 0xc5, 0xb2, 0xba, 0xc9, 0xb0, 0x93, 0xa7,
+		0x8d, 0xae, 0xbb, 0xac, 0x00, 0xab, 0x00, 0x90,
+		0x00, 0xc8,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9e, 0xa6, 0x8f,
+		0xb7, 0xc6, 0xb3, 0xb8, 0xc8, 0xb0, 0x93, 0xa6,
+		0x8c, 0xae, 0xbb, 0xad, 0x00, 0xae, 0x00, 0x93,
+		0x00, 0xcc,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xab, 0xb4, 0x9c,
+		0xb3, 0xc3, 0xaf, 0xb7, 0xc7, 0xaf, 0x93, 0xa6,
+		0x8c, 0xaf, 0xbc, 0xad, 0x00, 0xb1, 0x00, 0x97,
+		0x00, 0xcf,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa6, 0xb1, 0x98,
+		0xb1, 0xc2, 0xab, 0xba, 0xc9, 0xb2, 0x93, 0xa6,
+		0x8d, 0xae, 0xba, 0xab, 0x00, 0xb5, 0x00, 0x9b,
+		0x00, 0xd4,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xae, 0x94,
+		0xb2, 0xc3, 0xac, 0xbb, 0xca, 0xb4, 0x91, 0xa4,
+		0x8a, 0xae, 0xba, 0xac, 0x00, 0xb8, 0x00, 0x9e,
+		0x00, 0xd8,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xab, 0xb7, 0x9c,
+		0xae, 0xc0, 0xa9, 0xba, 0xc9, 0xb3, 0x92, 0xa5,
+		0x8b, 0xad, 0xb9, 0xab, 0x00, 0xbb, 0x00, 0xa1,
+		0x00, 0xdc,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb4, 0x97,
+		0xb0, 0xc1, 0xaa, 0xb9, 0xc8, 0xb2, 0x92, 0xa5,
+		0x8c, 0xae, 0xb9, 0xab, 0x00, 0xbe, 0x00, 0xa4,
+		0x00, 0xdf,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xb0, 0x94,
+		0xb0, 0xc2, 0xab, 0xbb, 0xc9, 0xb3, 0x91, 0xa4,
+		0x8b, 0xad, 0xb8, 0xaa, 0x00, 0xc1, 0x00, 0xa8,
+		0x00, 0xe2,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xb0, 0x94,
+		0xae, 0xbf, 0xa8, 0xb9, 0xc8, 0xb3, 0x92, 0xa4,
+		0x8b, 0xad, 0xb7, 0xa9, 0x00, 0xc4, 0x00, 0xab,
+		0x00, 0xe6,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb6, 0x98,
+		0xaf, 0xc0, 0xa8, 0xb8, 0xc7, 0xb2, 0x93, 0xa5,
+		0x8d, 0xad, 0xb7, 0xa9, 0x00, 0xc7, 0x00, 0xae,
+		0x00, 0xe9,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb3, 0x95,
+		0xaf, 0xc1, 0xa9, 0xb9, 0xc8, 0xb3, 0x92, 0xa4,
+		0x8b, 0xad, 0xb7, 0xaa, 0x00, 0xc9, 0x00, 0xb0,
+		0x00, 0xec,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb3, 0x95,
+		0xac, 0xbe, 0xa6, 0xbb, 0xc9, 0xb4, 0x90, 0xa3,
+		0x8a, 0xad, 0xb7, 0xa9, 0x00, 0xcc, 0x00, 0xb4,
+		0x00, 0xf0,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa0, 0xb0, 0x91,
+		0xae, 0xc0, 0xa6, 0xba, 0xc8, 0xb4, 0x91, 0xa4,
+		0x8b, 0xad, 0xb7, 0xa9, 0x00, 0xcf, 0x00, 0xb7,
+		0x00, 0xf3,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb8, 0x98,
+		0xab, 0xbd, 0xa4, 0xbb, 0xc9, 0xb5, 0x91, 0xa3,
+		0x8b, 0xac, 0xb6, 0xa8, 0x00, 0xd1, 0x00, 0xb9,
+		0x00, 0xf6,
+	}, {
+		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb5, 0x95,
+		0xa9, 0xbc, 0xa1, 0xbb, 0xc9, 0xb5, 0x91, 0xa3,
+		0x8a, 0xad, 0xb6, 0xa8, 0x00, 0xd6, 0x00, 0xbf,
+		0x00, 0xfc,
+	},
+};
+
+static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v96[GAMMA_LEVEL_NUM] = {
+	{
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
+		0xdf, 0x1f, 0xd7, 0xdc, 0xb7, 0xe1, 0xc0, 0xaf,
+		0xc4, 0xd2, 0xd0, 0xcf, 0x00, 0x4d, 0x00, 0x40,
+		0x00, 0x5f,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
+		0xd5, 0x35, 0xcf, 0xdc, 0xc1, 0xe1, 0xbf, 0xb3,
+		0xc1, 0xd2, 0xd1, 0xce,	0x00, 0x53, 0x00, 0x46,
+		0x00, 0x67,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
+		0xd2, 0x64, 0xcf, 0xdb, 0xc6, 0xe1, 0xbd, 0xb3,
+		0xbd, 0xd2, 0xd2, 0xce,	0x00, 0x59, 0x00, 0x4b,
+		0x00, 0x6e,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
+		0xd0, 0x7c, 0xcf, 0xdb, 0xc9, 0xe0, 0xbc, 0xb4,
+		0xbb, 0xcf, 0xd1, 0xcc, 0x00, 0x5f, 0x00, 0x50,
+		0x00, 0x75,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
+		0xd0, 0x8e, 0xd1, 0xdb, 0xcc, 0xdf, 0xbb, 0xb6,
+		0xb9, 0xd0, 0xd1, 0xcd,	0x00, 0x63, 0x00, 0x54,
+		0x00, 0x7a,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
+		0xd1, 0x9e, 0xd5, 0xda, 0xcd, 0xdd, 0xbb, 0xb7,
+		0xb9, 0xce, 0xce, 0xc9,	0x00, 0x68, 0x00, 0x59,
+		0x00, 0x81,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
+		0xd0, 0xa5, 0xd6, 0xda, 0xcf, 0xdd, 0xbb, 0xb7,
+		0xb8, 0xcc, 0xcd, 0xc7,	0x00, 0x6c, 0x00, 0x5c,
+		0x00, 0x86,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xfe,
+		0xd0, 0xae, 0xd7, 0xd9, 0xd0, 0xdb, 0xb9, 0xb6,
+		0xb5, 0xca, 0xcc, 0xc5,	0x00, 0x74, 0x00, 0x63,
+		0x00, 0x90,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xf9,
+		0xcf, 0xb0, 0xd6, 0xd9, 0xd1, 0xdb, 0xb9, 0xb6,
+		0xb4, 0xca, 0xcb, 0xc5,	0x00, 0x77, 0x00, 0x66,
+		0x00, 0x94,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xf7,
+		0xcf, 0xb3, 0xd7, 0xd8, 0xd1, 0xd9, 0xb7, 0xb6,
+		0xb3, 0xc9, 0xca, 0xc3,	0x00, 0x7b, 0x00, 0x69,
+		0x00, 0x99,
+
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xfd, 0x2f, 0xf7,
+		0xdf, 0xb5, 0xd6, 0xd8, 0xd1, 0xd8, 0xb6, 0xb5,
+		0xb2, 0xca, 0xcb, 0xc4,	0x00, 0x7e, 0x00, 0x6c,
+		0x00, 0x9d,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xfa, 0x2f, 0xf5,
+		0xce, 0xb6, 0xd5, 0xd7, 0xd2, 0xd8, 0xb6, 0xb4,
+		0xb0, 0xc7, 0xc9, 0xc1,	0x00, 0x84, 0x00, 0x71,
+		0x00, 0xa5,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf7, 0x2f, 0xf2,
+		0xce, 0xb9, 0xd5, 0xd8, 0xd2, 0xd8, 0xb4, 0xb4,
+		0xaf, 0xc7, 0xc9, 0xc1,	0x00, 0x87, 0x00, 0x73,
+		0x00, 0xa8,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf5, 0x2f, 0xf0,
+		0xdf, 0xba, 0xd5, 0xd7, 0xd2, 0xd7, 0xb4, 0xb4,
+		0xaf, 0xc5, 0xc7, 0xbf,	0x00, 0x8a, 0x00, 0x76,
+		0x00, 0xac,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf2, 0x2f, 0xed,
+		0xcE, 0xbb, 0xd4, 0xd6, 0xd2, 0xd6, 0xb5, 0xb4,
+		0xaF, 0xc5, 0xc7, 0xbf,	0x00, 0x8c, 0x00, 0x78,
+		0x00, 0xaf,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xef, 0x2f, 0xeb,
+		0xcd, 0xbb, 0xd2, 0xd7, 0xd3, 0xd6, 0xb3, 0xb4,
+		0xae, 0xc5, 0xc6, 0xbe,	0x00, 0x91, 0x00, 0x7d,
+		0x00, 0xb6,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xee, 0x2f, 0xea,
+		0xce, 0xbd, 0xd4, 0xd6, 0xd2, 0xd5, 0xb2, 0xb3,
+		0xad, 0xc3, 0xc4, 0xbb,	0x00, 0x94, 0x00, 0x7f,
+		0x00, 0xba,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xec, 0x2f, 0xe8,
+		0xce, 0xbe, 0xd3, 0xd6, 0xd3, 0xd5, 0xb2, 0xb2,
+		0xac, 0xc3, 0xc5, 0xbc,	0x00, 0x96, 0x00, 0x81,
+		0x00, 0xbd,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xeb, 0x2f, 0xe7,
+		0xce, 0xbf, 0xd3, 0xd6, 0xd2, 0xd5, 0xb1, 0xb2,
+		0xab, 0xc2, 0xc4, 0xbb,	0x00, 0x99, 0x00, 0x83,
+		0x00, 0xc0,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xef, 0x5f, 0xe9,
+		0xca, 0xbf, 0xd3, 0xd5, 0xd2, 0xd4, 0xb2, 0xb2,
+		0xab, 0xc1, 0xc4, 0xba,	0x00, 0x9b, 0x00, 0x85,
+		0x00, 0xc3,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xea, 0x5f, 0xe8,
+		0xee, 0xbf, 0xd2, 0xd5, 0xd2, 0xd4, 0xb1, 0xb2,
+		0xab, 0xc1, 0xc2, 0xb9,	0x00, 0x9D, 0x00, 0x87,
+		0x00, 0xc6,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe9, 0x5f, 0xe7,
+		0xcd, 0xbf, 0xd2, 0xd6, 0xd2, 0xd4, 0xb1, 0xb2,
+		0xab, 0xbe, 0xc0, 0xb7,	0x00, 0xa1, 0x00, 0x8a,
+		0x00, 0xca,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe8, 0x61, 0xe6,
+		0xcd, 0xbf, 0xd1, 0xd6, 0xd3, 0xd4, 0xaf, 0xb0,
+		0xa9, 0xbe, 0xc1, 0xb7,	0x00, 0xa3, 0x00, 0x8b,
+		0x00, 0xce,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe8, 0x62, 0xe5,
+		0xcc, 0xc0, 0xd0, 0xd6, 0xd2, 0xd4, 0xaf, 0xb1,
+		0xa9, 0xbd, 0xc0, 0xb6,	0x00, 0xa5, 0x00, 0x8d,
+		0x00, 0xd0,
+	}, {
+		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe7, 0x7f, 0xe3,
+		0xcc, 0xc1, 0xd0, 0xd5, 0xd3, 0xd3, 0xae, 0xaf,
+		0xa8, 0xbe, 0xc0, 0xb7,	0x00, 0xa8, 0x00, 0x90,
+		0x00, 0xd3,
+	}
+};
+
+static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v32[GAMMA_LEVEL_NUM] = {
+	{
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0x72, 0x5e, 0x6b,
+		0xa1, 0xa7, 0x9a, 0xb4, 0xcb, 0xb8, 0x92, 0xac,
+		0x97, 0xb4, 0xc3, 0xb5, 0x00, 0x4e, 0x00, 0x37,
+		0x00, 0x58,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0x85, 0x71, 0x7d,
+		0xa6, 0xb6, 0xa1, 0xb5, 0xca, 0xba, 0x93, 0xac,
+		0x98, 0xb2, 0xc0, 0xaf, 0x00, 0x59, 0x00, 0x43,
+		0x00, 0x64,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa4, 0x94, 0x9e,
+		0xa0, 0xbb, 0x9c, 0xc3, 0xd2, 0xc6, 0x93, 0xaa,
+		0x95, 0xb7, 0xc2, 0xb4, 0x00, 0x65, 0x00, 0x50,
+		0x00, 0x74,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xa1, 0xa6,
+		0xa0, 0xb9, 0x9b, 0xc3, 0xd1, 0xc8, 0x90, 0xa6,
+		0x90, 0xbb, 0xc3, 0xb7, 0x00, 0x6f, 0x00, 0x5b,
+		0x00, 0x80,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa6, 0x9d, 0x9f,
+		0x9f, 0xb8, 0x9a, 0xc7, 0xd5, 0xcc, 0x90, 0xa5,
+		0x8f, 0xb8, 0xc1, 0xb6, 0x00, 0x74, 0x00, 0x60,
+		0x00, 0x85,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb3, 0xae, 0xae,
+		0x9e, 0xb7, 0x9a, 0xc8, 0xd6, 0xce, 0x91, 0xa6,
+		0x90, 0xb6, 0xc0, 0xb3, 0x00, 0x78, 0x00, 0x65,
+		0x00, 0x8a,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xa9, 0xa8,
+		0xa3, 0xb9, 0x9e, 0xc4, 0xd3, 0xcb, 0x94, 0xa6,
+		0x90, 0xb6, 0xbf, 0xb3, 0x00, 0x7c, 0x00, 0x69,
+		0x00, 0x8e,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xaf, 0xaf, 0xa9,
+		0xa5, 0xbc, 0xa2, 0xc7, 0xd5, 0xcd, 0x93, 0xa5,
+		0x8f, 0xb4, 0xbd, 0xb1, 0x00, 0x83, 0x00, 0x70,
+		0x00, 0x96,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xab, 0xa3,
+		0xaa, 0xbf, 0xa7, 0xc5, 0xd3, 0xcb, 0x93, 0xa5,
+		0x8f, 0xb2, 0xbb, 0xb0, 0x00, 0x86, 0x00, 0x74,
+		0x00, 0x9b,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb1, 0xb5, 0xab,
+		0xab, 0xc0, 0xa9, 0xc7, 0xd4, 0xcc, 0x94, 0xa4,
+		0x8f, 0xb1, 0xbb, 0xaf, 0x00, 0x8a, 0x00, 0x77,
+		0x00, 0x9e,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb2, 0xa7,
+		0xae, 0xc2, 0xab, 0xc5, 0xd3, 0xca, 0x93, 0xa4,
+		0x8f, 0xb1, 0xba, 0xae, 0x00, 0x8d, 0x00, 0x7b,
+		0x00, 0xa2,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xaf, 0xa3,
+		0xb0, 0xc3, 0xae, 0xc4, 0xd1, 0xc8, 0x93, 0xa4,
+		0x8f, 0xb1, 0xba, 0xaf, 0x00, 0x8f, 0x00, 0x7d,
+		0x00, 0xa5,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb4, 0xbd, 0xaf,
+		0xae, 0xc1, 0xab, 0xc2, 0xd0, 0xc6, 0x94, 0xa4,
+		0x8f, 0xb1, 0xba, 0xaf, 0x00, 0x92, 0x00, 0x80,
+		0x00, 0xa8,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xb9, 0xac,
+		0xad, 0xc1, 0xab, 0xc4, 0xd1, 0xc7, 0x95, 0xa4,
+		0x90, 0xb0, 0xb9, 0xad, 0x00, 0x95, 0x00, 0x84,
+		0x00, 0xac,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb6, 0xa7,
+		0xaf, 0xc2, 0xae, 0xc5, 0xd1, 0xc7, 0x93, 0xa3,
+		0x8e, 0xb0, 0xb9, 0xad, 0x00, 0x98, 0x00, 0x86,
+		0x00, 0xaf,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb4, 0xbf, 0xaf,
+		0xad, 0xc1, 0xab, 0xc3, 0xd0, 0xc6, 0x94, 0xa3,
+		0x8f, 0xaf, 0xb8, 0xac, 0x00, 0x9a, 0x00, 0x89,
+		0x00, 0xb2,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xbc, 0xac,
+		0xaf, 0xc2, 0xad, 0xc2, 0xcf, 0xc4, 0x94, 0xa3,
+		0x90, 0xaf, 0xb8, 0xad, 0x00, 0x9c, 0x00, 0x8b,
+		0x00, 0xb5,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb9, 0xa7,
+		0xb1, 0xc4, 0xaf, 0xc3, 0xcf, 0xc5, 0x94, 0xa3,
+		0x8f, 0xae, 0xb7, 0xac, 0x00, 0x9f, 0x00, 0x8e,
+		0x00, 0xb8,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb9, 0xa7,
+		0xaf, 0xc2, 0xad, 0xc1, 0xce, 0xc3, 0x95, 0xa3,
+		0x90, 0xad, 0xb6, 0xab, 0x00, 0xa2, 0x00, 0x91,
+		0x00, 0xbb,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb1, 0xbe, 0xac,
+		0xb1, 0xc4, 0xaf, 0xc1, 0xcd, 0xc1, 0x95, 0xa4,
+		0x91, 0xad, 0xb6, 0xab, 0x00, 0xa4, 0x00, 0x93,
+		0x00, 0xbd,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbb, 0xa8,
+		0xb3, 0xc5, 0xb2, 0xc1, 0xcd, 0xc2, 0x95, 0xa3,
+		0x90, 0xad, 0xb6, 0xab, 0x00, 0xa6, 0x00, 0x95,
+		0x00, 0xc0,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbb, 0xa8,
+		0xb0, 0xc3, 0xaf, 0xc2, 0xce, 0xc2, 0x94, 0xa2,
+		0x90, 0xac, 0xb6, 0xab, 0x00, 0xa8, 0x00, 0x98,
+		0x00, 0xc3,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xb8, 0xa5,
+		0xb3, 0xc5, 0xb2, 0xc1, 0xcc, 0xc0, 0x95, 0xa2,
+		0x90, 0xad, 0xb6, 0xab, 0x00, 0xaa, 0x00, 0x9a,
+		0x00, 0xc5,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xc0, 0xac,
+		0xb0, 0xc3, 0xaf, 0xc1, 0xcd, 0xc1, 0x95, 0xa2,
+		0x90, 0xac, 0xb5, 0xa9, 0x00, 0xac, 0x00, 0x9c,
+		0x00, 0xc8,
+	}, {
+		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbd, 0xa8,
+		0xaf, 0xc2, 0xaf, 0xc1, 0xcc, 0xc0, 0x95, 0xa2,
+		0x90, 0xac, 0xb5, 0xaa, 0x00, 0xb1, 0x00, 0xa1,
+		0x00, 0xcc,
+	},
+};
+
+static const struct s6e8aa0_variant s6e8aa0_variants[] = {
+	{
+		.version = 32,
+		.gamma_tables = s6e8aa0_gamma_tables_v32,
+	}, {
+		.version = 96,
+		.gamma_tables = s6e8aa0_gamma_tables_v96,
+	}, {
+		.version = 142,
+		.gamma_tables = s6e8aa0_gamma_tables_v142,
+	}, {
+		.version = 210,
+		.gamma_tables = s6e8aa0_gamma_tables_v142,
+	}
+};
+
+static void s6e8aa0_brightness_set(struct s6e8aa0 *ctx)
+{
+	const u8 *gamma = ctx->variant->gamma_tables[ctx->brightness];
+
+	if (ctx->version >= 142)
+		s6e8aa0_elvss_nvm_set(ctx);
+
+	s6e8aa0_dcs_write(ctx, gamma, GAMMA_TABLE_LEN);
+
+	/* update gamma table. */
+	s6e8aa0_dcs_write_seq_static(ctx, 0xf7, 0x03);
+}
+
+static void s6e8aa0_panel_init(struct s6e8aa0 *ctx)
+{
+	s6e8aa0_apply_level_1_key(ctx);
+	s6e8aa0_apply_level_2_key(ctx);
+	msleep(20);
+
+	s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_EXIT_SLEEP_MODE);
+	msleep(40);
+
+	s6e8aa0_panel_cond_set(ctx);
+	s6e8aa0_display_condition_set(ctx);
+	s6e8aa0_brightness_set(ctx);
+	s6e8aa0_etc_source_control(ctx);
+	s6e8aa0_etc_pentile_control(ctx);
+	s6e8aa0_elvss_nvm_set(ctx);
+	s6e8aa0_etc_power_control(ctx);
+	s6e8aa0_etc_elvss_control(ctx);
+	msleep(ctx->init_delay);
+}
+
+static void s6e8aa0_set_maximum_return_packet_size(struct s6e8aa0 *ctx,
+						   int size)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+	u8 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
+	};
+	int ret;
+
+	if (ctx->error < 0)
+		return;
+
+	if (!ops || !ops->transfer)
+		ret = -EIO;
+	else
+		ret = ops->transfer(dsi->host, &msg);
+
+	if (ret < 0) {
+		dev_err(ctx->dev,
+			"error %d setting maximum return packet size to %d\n",
+			ret, size);
+		ctx->error = ret;
+	}
+}
+
+static void s6e8aa0_read_mtp_id(struct s6e8aa0 *ctx)
+{
+	u8 id[3];
+	int ret, i;
+
+	ret = s6e8aa0_dcs_read(ctx, 0xd1, id, ARRAY_SIZE(id));
+	if (ret < ARRAY_SIZE(id) || id[0] == 0x00) {
+		dev_err(ctx->dev, "read id failed\n");
+		ctx->error = -EIO;
+		return;
+	}
+
+	dev_info(ctx->dev, "ID: 0x%2x, 0x%2x, 0x%2x\n", id[0], id[1], id[2]);
+
+	for (i = 0; i < ARRAY_SIZE(s6e8aa0_variants); ++i) {
+		if (id[1] == s6e8aa0_variants[i].version)
+			break;
+	}
+	if (i >= ARRAY_SIZE(s6e8aa0_variants)) {
+		dev_err(ctx->dev, "unsupported display version %d\n", id[1]);
+		ctx->error = -EINVAL;
+	}
+
+	ctx->variant = &s6e8aa0_variants[i];
+	ctx->version = id[1];
+	ctx->id = id[2];
+}
+
+static void s6e8aa0_set_sequence(struct s6e8aa0 *ctx)
+{
+	s6e8aa0_set_maximum_return_packet_size(ctx, 3);
+	s6e8aa0_read_mtp_id(ctx);
+	s6e8aa0_panel_init(ctx);
+	s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_ON);
+}
+
+static int s6e8aa0_power_on(struct s6e8aa0 *ctx)
+{
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret < 0)
+		return ret;
+
+	msleep(ctx->power_on_delay);
+
+	gpio_set_value(ctx->reset_gpio, 1);
+	usleep_range(10000, 11000);
+	gpio_set_value(ctx->reset_gpio, 0);
+	usleep_range(10000, 11000);
+	gpio_set_value(ctx->reset_gpio, 1);
+
+	msleep(ctx->reset_delay);
+
+	return 0;
+}
+
+static int s6e8aa0_power_off(struct s6e8aa0 *ctx)
+{
+	return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+}
+
+static int s6e8aa0_disable(struct drm_panel *panel)
+{
+	struct s6e8aa0 *ctx = panel_to_s6e8aa0(panel);
+
+	s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_ENTER_SLEEP_MODE);
+	s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_OFF);
+	msleep(40);
+
+	s6e8aa0_clear_error(ctx);
+
+	return s6e8aa0_power_off(ctx);
+}
+
+static int s6e8aa0_enable(struct drm_panel *panel)
+{
+	struct s6e8aa0 *ctx = panel_to_s6e8aa0(panel);
+	int ret;
+
+	ret = s6e8aa0_power_on(ctx);
+	if (ret < 0)
+		return ret;
+
+	s6e8aa0_set_sequence(ctx);
+	ret = ctx->error;
+
+	if (ret < 0)
+		s6e8aa0_disable(panel);
+
+	return ret;
+}
+
+static int s6e8aa0_get_modes(struct drm_panel *panel)
+{
+	struct drm_connector *connector = panel->connector;
+	struct s6e8aa0 *ctx = panel_to_s6e8aa0(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_videomode(&ctx->vm, 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 s6e8aa0_drm_funcs = {
+	.disable = s6e8aa0_disable,
+	.enable = s6e8aa0_enable,
+	.get_modes = s6e8aa0_get_modes,
+};
+
+static int s6e8aa0_parse_dt(struct s6e8aa0 *ctx)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	ret = of_get_videomode(np, &ctx->vm, 0);
+	if (ret < 0)
+		return ret;
+
+	ctx->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
+	if (ctx->reset_gpio < 0) {
+		dev_err(dev, "failed to get reset-gpio DT property\n");
+		return ctx->reset_gpio;
+	}
+
+	of_property_read_u32(np, "power-on-delay", &ctx->power_on_delay);
+	of_property_read_u32(np, "reset-delay", &ctx->reset_delay);
+	of_property_read_u32(np, "init-delay", &ctx->init_delay);
+	of_property_read_u32(np, "panel-width-mm", &ctx->width_mm);
+	of_property_read_u32(np, "panel-height-mm", &ctx->height_mm);
+
+	ctx->flip_horizontal = of_property_read_bool(np, "flip-horizontal");
+	ctx->flip_vertical = of_property_read_bool(np, "flip-vertical");
+
+	return 0;
+}
+
+static int s6e8aa0_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct s6e8aa0 *ctx;
+	int ret;
+
+	ctx = devm_kzalloc(dev, sizeof(struct s6e8aa0), GFP_KERNEL);
+	if (!ctx) {
+		dev_err(dev, "failed to allocate s6e8aa0 structure.\n");
+		return -ENOMEM;
+	}
+
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	ctx->dev = dev;
+
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
+		| MIPI_DSI_MODE_VIDEO_HFP | MIPI_DSI_MODE_VIDEO_HBP
+		| MIPI_DSI_MODE_VIDEO_HSA | MIPI_DSI_MODE_EOT_PACKET
+		| MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_AUTO_VERT;
+
+	ret = s6e8aa0_parse_dt(ctx);
+	if (ret < 0)
+		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 < 0) {
+		dev_info(dev, "failed to get regulators: %d\n", ret);
+		return ret;
+	}
+
+	ctx->brightness = GAMMA_LEVEL_NUM - 1;
+
+	drm_panel_init(&ctx->panel);
+	ctx->panel.dev = dev;
+	ctx->panel.funcs = &s6e8aa0_drm_funcs;
+
+	ret = drm_panel_add(&ctx->panel);
+	if (ret < 0)
+		return ret;
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0)
+		drm_panel_remove(&ctx->panel);
+
+	return ret;
+}
+
+static int s6e8aa0_remove(struct mipi_dsi_device *dsi)
+{
+	struct s6e8aa0 *ctx = mipi_dsi_get_drvdata(dsi);
+
+	s6e8aa0_power_off(ctx);
+
+	mipi_dsi_detach(dsi);
+	drm_panel_remove(&ctx->panel);
+
+	return 0;
+}
+
+static struct of_device_id s6e8aa0_of_match[] = {
+	{ .compatible = "samsung,s6e8aa0" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, s6e8aa0_of_match);
+
+static struct mipi_dsi_driver s6e8aa0_driver = {
+	.probe = s6e8aa0_probe,
+	.remove = s6e8aa0_remove,
+	.driver = {
+		.name = "panel_s6e8aa0",
+		.owner = THIS_MODULE,
+		.of_match_table = s6e8aa0_of_match,
+	},
+};
+module_mipi_dsi_driver(s6e8aa0_driver);
+
+MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
+MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
+MODULE_AUTHOR("Joongmock Shin <jmock.shin@samsung.com>");
+MODULE_AUTHOR("Eunchul Kim <chulspro.kim@samsung.com>");
+MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
+MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
+MODULE_DESCRIPTION("MIPI-DSI based s6e8aa0 AMOLED LCD Panel Driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2

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

* [RFC PATCH v2 07/21] panel/tc358764: add DT bindings
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (5 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 06/21] drm/panel: add S6E8AA0 driver Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 10/21] panel/hv070wsa-100: " Andrzej Hajda
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch add bindings to Toshiba DSI/LVDS bridge TC358764.
Bindings describes power supplies, reset gpio and video interfaces.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 .../devicetree/bindings/panel/toshiba,tc358764.txt | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/panel/toshiba,tc358764.txt

diff --git a/Documentation/devicetree/bindings/panel/toshiba,tc358764.txt b/Documentation/devicetree/bindings/panel/toshiba,tc358764.txt
new file mode 100644
index 0000000..fe3e2f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/toshiba,tc358764.txt
@@ -0,0 +1,41 @@
+TC358764 MIPI-DSI to LVDS panel bridge
+
+Required properties:
+  - compatible: "toshiba,tc358764"
+  - reg: the virtual channel number of a DSI peripheral
+  - vddc-supply: core voltage supply
+  - vddio-supply: I/O voltage supply
+  - vddmipi-supply: MIPI voltage supply
+  - vddlvds133-supply: LVDS1 3.3V voltage supply
+  - vddlvds112-supply: LVDS1 1.2V voltage supply
+  - reset-gpio: a GPIO spec for the reset pin
+
+The device node can contain zero to two 'port' child nodes, each with one child
+'endpoint' node, according to the bindings defined in [1].
+The following are properties specific to those nodes.
+
+port:
+  - reg: (required) can be 0 for DSI port or 1 for LVDS port;
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+	bridge@0 {
+		reg = <0>;
+		compatible = "toshiba,tc358764";
+		vddc-supply = <&vcc_1v2_reg>;
+		vddio-supply = <&vcc_1v8_reg>;
+		vddmipi-supply = <&vcc_1v2_reg>;
+		vddlvds133-supply = <&vcc_3v3_reg>;
+		vddlvds112-supply = <&vcc_1v2_reg>;
+		reset-gpio = <&gpd1 6 1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port@1 {
+			reg = <1>;
+			lvds_ep: endpoint {
+				remote-endpoint = <&panel_ep>;
+			};
+		};
+	};
-- 
1.8.3.2

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

* [RFC PATCH v2 08/21] drm/panel: add TC358764 driver
       [not found] ` <1392204688-4591-1-git-send-email-a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2014-02-12 11:31   ` Andrzej Hajda
  2014-03-05  6:46     ` Inki Dae
  2014-02-12 11:31   ` [RFC PATCH v2 09/21] panel/simple: add video interface DT bindings Andrzej Hajda
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Andrzej Hajda, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds driver for Toshiba DSI/LVDS TC358764 bridge.
Driver registers itself as mipi_dsi_driver. It is exposed to the
system via drm_panel interface, it uses also drm_panel framework
to interact with LVDS panel connected to it.
Driver supports only DT bindings.

Signed-off-by: Andrzej Hajda <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 drivers/gpu/drm/panel/Kconfig          |   7 +
 drivers/gpu/drm/panel/Makefile         |   1 +
 drivers/gpu/drm/panel/panel-tc358764.c | 505 +++++++++++++++++++++++++++++++++
 3 files changed, 513 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-tc358764.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 7527557..b98a485 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -23,4 +23,11 @@ config DRM_PANEL_S6E8AA0
 	select DRM_MIPI_DSI
 	select VIDEOMODE_HELPERS
 
+config DRM_PANEL_TC358764
+	tristate "TC358764 DSI/LVDS bridge"
+	depends on DRM && DRM_PANEL
+	depends on OF
+	select DRM_MIPI_DSI
+	select VIDEOMODE_HELPERS
+
 endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 181265b..7cbb0cf 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
 obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
+obj-$(CONFIG_DRM_PANEL_TC358764) += panel-tc358764.o
diff --git a/drivers/gpu/drm/panel/panel-tc358764.c b/drivers/gpu/drm/panel/panel-tc358764.c
new file mode 100644
index 0000000..f9c1289
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-tc358764.c
@@ -0,0 +1,505 @@
+/*
+ * TC358764 MIPI-DSI to LVDS bridge panel driver.
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd
+ *
+ * Andrzej Hajda <a.hajda-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 <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#define FLD_MASK(start, end)    (((1 << ((start) - (end) + 1)) - 1) << (end))
+#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
+
+/* PPI layer registers */
+#define PPI_STARTPPI		0x0104 /* START control bit */
+#define PPI_LPTXTIMECNT		0x0114 /* LPTX timing signal */
+#define PPI_LANEENABLE		0x0134 /* Enables each lane */
+#define PPI_TX_RX_TA		0x013C /* BTA timing parameters */
+#define PPI_D0S_CLRSIPOCOUNT	0x0164 /* Assertion timer for Lane 0 */
+#define PPI_D1S_CLRSIPOCOUNT	0x0168 /* Assertion timer for Lane 1 */
+#define PPI_D2S_CLRSIPOCOUNT	0x016C /* Assertion timer for Lane 2 */
+#define PPI_D3S_CLRSIPOCOUNT	0x0170 /* Assertion timer for Lane 3 */
+
+/* DSI layer registers */
+#define DSI_STARTDSI		0x0204 /* START control bit of DSI-TX */
+#define DSI_LANEENABLE		0x0210 /* Enables each lane */
+
+/* Video path registers */
+#define VP_CTRL			0x0450 /* Video Path Control */
+#define VP_CTRL_MSF(v)		FLD_VAL(v, 0, 0) /* Magic square in RGB666 */
+#define VP_CTRL_VTGEN(v)	FLD_VAL(v, 4, 4) /* Use chip clock for timing */
+#define VP_CTRL_EVTMODE(v)	FLD_VAL(v, 5, 5) /* Event mode */
+#define VP_CTRL_RGB888(v)	FLD_VAL(v, 8, 8) /* RGB888 mode */
+#define VP_CTRL_VSDELAY(v)	FLD_VAL(v, 31, 20) /* VSYNC delay */
+#define VP_HTIM1		0x0454 /* Horizontal Timing Control 1 */
+#define VP_HTIM1_HBP(v)		FLD_VAL(v, 24, 16)
+#define VP_HTIM1_HSYNC(v)	FLD_VAL(v, 8, 0)
+#define VP_HTIM2		0x0458 /* Horizontal Timing Control 2 */
+#define VP_HTIM2_HFP(v)		FLD_VAL(v, 24, 16)
+#define VP_HTIM2_HACT(v)	FLD_VAL(v, 10, 0)
+#define VP_VTIM1		0x045C /* Vertical Timing Control 1 */
+#define VP_VTIM1_VBP(v)		FLD_VAL(v, 23, 16)
+#define VP_VTIM1_VSYNC(v)	FLD_VAL(v, 7, 0)
+#define VP_VTIM2		0x0460 /* Vertical Timing Control 2 */
+#define VP_VTIM2_VFP(v)		FLD_VAL(v, 23, 16)
+#define VP_VTIM2_VACT(v)	FLD_VAL(v, 10, 0)
+#define VP_VFUEN		0x0464 /* Video Frame Timing Update Enable */
+
+/* LVDS registers */
+#define LV_MX0003		0x0480 /* Mux input bit 0 to 3 */
+#define LV_MX0407		0x0484 /* Mux input bit 4 to 7 */
+#define LV_MX0811		0x0488 /* Mux input bit 8 to 11 */
+#define LV_MX1215		0x048C /* Mux input bit 12 to 15 */
+#define LV_MX1619		0x0490 /* Mux input bit 16 to 19 */
+#define LV_MX2023		0x0494 /* Mux input bit 20 to 23 */
+#define LV_MX2427		0x0498 /* Mux input bit 24 to 27 */
+#define LV_MX(b0, b1, b2, b3)	(FLD_VAL(b0, 4, 0) | FLD_VAL(b1, 12, 8) | \
+				FLD_VAL(b2, 20, 16) | FLD_VAL(b3, 28, 24))
+
+/* Input bit numbers used in mux registers */
+enum {
+	LVI_R0,
+	LVI_R1,
+	LVI_R2,
+	LVI_R3,
+	LVI_R4,
+	LVI_R5,
+	LVI_R6,
+	LVI_R7,
+	LVI_G0,
+	LVI_G1,
+	LVI_G2,
+	LVI_G3,
+	LVI_G4,
+	LVI_G5,
+	LVI_G6,
+	LVI_G7,
+	LVI_B0,
+	LVI_B1,
+	LVI_B2,
+	LVI_B3,
+	LVI_B4,
+	LVI_B5,
+	LVI_B6,
+	LVI_B7,
+	LVI_HS,
+	LVI_VS,
+	LVI_DE,
+	LVI_L0
+};
+
+#define LV_CFG			0x049C /* LVDS Configuration */
+#define LV_PHY0			0x04A0 /* LVDS PHY 0 */
+#define LV_PHY0_RST(v)		FLD_VAL(v, 22, 22) /* PHY reset */
+#define LV_PHY0_IS(v)		FLD_VAL(v, 15, 14)
+#define LV_PHY0_ND(v)		FLD_VAL(v, 4, 0)
+
+/* System registers */
+#define SYS_RST			0x0504 /* System Reset */
+#define SYS_ID			0x0580 /* System ID */
+
+static const char * const tc358764_supplies[] = {
+	"vddc", "vddio", "vddmipi", "vddlvds133", "vddlvds112"
+};
+
+struct tc358764 {
+	struct device *dev;
+	struct drm_panel bridge;
+
+	struct regulator_bulk_data supplies[ARRAY_SIZE(tc358764_supplies)];
+	int reset_gpio;
+	struct drm_panel *panel;
+};
+
+int tc358764_read(struct tc358764 *ctx, u16 addr, u32 *val)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+	struct mipi_dsi_msg msg = {
+		.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM,
+		.channel = dsi->channel,
+		.flags = MIPI_DSI_MSG_USE_LPM,
+		.tx_buf = &addr,
+		.tx_len = 2,
+		.rx_buf = val,
+		.rx_len = 4
+	};
+	ssize_t ret;
+
+	if (!ops || !ops->transfer)
+		return -ENOSYS;
+
+	addr = cpu_to_le16(addr);
+
+	ret = ops->transfer(dsi->host, &msg);
+	if (ret >= 0)
+		*val = le32_to_cpu(*val);
+
+	return ret;
+}
+
+int tc358764_write(struct tc358764 *ctx, u16 addr, u32 val)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+	u8 data[6];
+	struct mipi_dsi_msg msg = {
+		.type = MIPI_DSI_GENERIC_LONG_WRITE,
+		.channel = dsi->channel,
+		.flags = MIPI_DSI_MSG_USE_LPM | MIPI_DSI_MSG_REQ_ACK,
+		.tx_buf = data,
+		.tx_len = 6
+	};
+
+	if (!ops || !ops->transfer)
+		return -ENOSYS;
+
+	data[0] = addr;
+	data[1] = addr >> 8;
+	data[2] = val;
+	data[3] = val >> 8;
+	data[4] = val >> 16;
+	data[5] = val >> 24;
+
+	return ops->transfer(dsi->host, &msg);
+}
+
+#define bridge_to_tc358764(p) container_of(p, struct tc358764, bridge)
+
+static int tc358764_init(struct tc358764 *ctx)
+{
+	u32 v = 0;
+
+	tc358764_read(ctx, SYS_ID, &v);
+	dev_info(ctx->dev, "ID: %#x\n", v);
+
+	/* configure PPI counters */
+	tc358764_write(ctx, PPI_TX_RX_TA, 0x20003);
+	tc358764_write(ctx, PPI_LPTXTIMECNT, 2);
+	tc358764_write(ctx, PPI_D0S_CLRSIPOCOUNT, 5);
+	tc358764_write(ctx, PPI_D1S_CLRSIPOCOUNT, 5);
+	tc358764_write(ctx, PPI_D2S_CLRSIPOCOUNT, 5);
+	tc358764_write(ctx, PPI_D3S_CLRSIPOCOUNT, 5);
+
+	/* enable four data lanes and clock lane */
+	tc358764_write(ctx, PPI_LANEENABLE, 0x1f);
+	tc358764_write(ctx, DSI_LANEENABLE, 0x1f);
+
+	/* start */
+	tc358764_write(ctx, PPI_STARTPPI, 1);
+	tc358764_write(ctx, DSI_STARTDSI, 1);
+
+	/* configure video path */
+	tc358764_write(ctx, VP_CTRL, VP_CTRL_VSDELAY(15) | VP_CTRL_RGB888(1) |
+		       VP_CTRL_EVTMODE(1) | BIT(17) | BIT(19));
+
+	/* reset PHY */
+	tc358764_write(ctx, LV_PHY0, LV_PHY0_RST(1)
+		       | BIT(18) | LV_PHY0_IS(2) | LV_PHY0_ND(6));
+	tc358764_write(ctx, LV_PHY0, BIT(18) | LV_PHY0_IS(2) | LV_PHY0_ND(6));
+
+	/* reset bridge */
+	tc358764_write(ctx, SYS_RST, BIT(2));
+
+	/* set bit order */
+	tc358764_write(ctx, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3));
+	tc358764_write(ctx, LV_MX0407, LV_MX(LVI_R4, LVI_R7, LVI_R5, LVI_G0));
+	tc358764_write(ctx, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_G6, LVI_G7));
+	tc358764_write(ctx, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0));
+	tc358764_write(ctx, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, LVI_B2));
+	tc358764_write(ctx, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0));
+	tc358764_write(ctx, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R6));
+	tc358764_write(ctx, LV_CFG, 0xd);
+
+	return 0;
+}
+
+static void tc358764_reset(struct tc358764 *ctx)
+{
+	msleep(20);
+	gpio_set_value(ctx->reset_gpio, 0);
+	msleep(20);
+	gpio_set_value(ctx->reset_gpio, 1);
+	msleep(40);
+}
+
+static void tc358764_poweron(struct tc358764 *ctx)
+{
+	int ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies),
+					ctx->supplies);
+	if (ret < 0)
+		dev_err(ctx->dev, "error enabling regulators (%d)\n", ret);
+
+	tc358764_reset(ctx);
+
+	drm_panel_enable(ctx->panel);
+	msleep(40);
+}
+
+static void tc358764_poweroff(struct tc358764 *ctx)
+{
+	int ret;
+
+	tc358764_reset(ctx);
+
+	drm_panel_disable(ctx->panel);
+	msleep(40);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret < 0)
+		dev_err(ctx->dev, "error enabling regulators (%d)\n", ret);
+}
+
+int tc358764_disable(struct drm_panel *bridge)
+{
+	struct tc358764 *ctx = bridge_to_tc358764(bridge);
+
+	tc358764_poweroff(ctx);
+
+	return 0;
+}
+
+int tc358764_enable(struct drm_panel *bridge)
+{
+	struct tc358764 *ctx = bridge_to_tc358764(bridge);
+
+	tc358764_poweron(ctx);
+
+	return tc358764_init(ctx);
+}
+
+int tc358764_get_modes(struct drm_panel *bridge)
+{
+	struct tc358764 *ctx = bridge_to_tc358764(bridge);
+
+	if (!ctx->panel->drm)
+		drm_panel_attach(ctx->panel, ctx->bridge.connector);
+
+	return ctx->panel->funcs->get_modes(ctx->panel);
+}
+
+static const struct drm_panel_funcs tc358764_drm_funcs = {
+	.disable = tc358764_disable,
+	.enable = tc358764_enable,
+	.get_modes = tc358764_get_modes,
+};
+
+/* of_* functions will be removed after acceptance of of_graph patches */
+static struct device_node *
+of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
+{
+	struct device_node *np;
+
+	for_each_child_of_node(parent, np) {
+		u32 r;
+
+		if (!np->name || of_node_cmp(np->name, name))
+			continue;
+
+		if (of_property_read_u32(np, "reg", &r) < 0)
+			r = 0;
+
+		if (reg == r)
+			break;
+	}
+
+	return np;
+}
+
+static struct device_node *of_graph_get_port_by_reg(struct device_node *parent,
+						    u32 reg)
+{
+	struct device_node *ports, *port;
+
+	ports = of_get_child_by_name(parent, "ports");
+	if (ports) {
+		port = of_get_child_by_name_reg(ports, "port", reg);
+		of_node_put(ports);
+	} else {
+		port = of_get_child_by_name_reg(parent, "port", reg);
+	}
+	return port;
+}
+
+static struct device_node *
+of_graph_get_endpoint_by_reg(struct device_node *port, u32 reg)
+{
+	return of_get_child_by_name_reg(port, "endpoint", reg);
+}
+
+static struct device_node *
+of_graph_get_remote_port_parent(const struct device_node *node)
+{
+	struct device_node *np;
+	unsigned int depth;
+
+	/* Get remote endpoint node. */
+	np = of_parse_phandle(node, "remote-endpoint", 0);
+
+	/* Walk 3 levels up only if there is 'ports' node. */
+	for (depth = 3; depth && np; depth--) {
+		np = of_get_next_parent(np);
+		if (depth == 2 && of_node_cmp(np->name, "ports"))
+			break;
+	}
+	return np;
+}
+
+static struct device_node *tc358764_of_find_panel_node(struct device *dev)
+{
+	struct device_node *np, *ep;
+
+	np = of_graph_get_port_by_reg(dev->of_node, 1);
+	if (!np)
+		return NULL;
+
+	ep = of_graph_get_endpoint_by_reg(np, 0);
+	of_node_put(np);
+	if (!ep)
+		return NULL;
+
+	np = of_graph_get_remote_port_parent(ep);
+	of_node_put(ep);
+
+	return np;
+}
+
+static int tc358764_parse_dt(struct tc358764 *ctx)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *lvds;
+
+	ctx->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
+	if (ctx->reset_gpio < 0) {
+		dev_err(dev, "no reset GPIO pin provided\n");
+		//return ctx->reset_gpio;
+	}
+
+	lvds = tc358764_of_find_panel_node(ctx->dev);
+	if (!lvds) {
+		dev_err(dev, "cannot find panel node\n");
+		return -EINVAL;
+	}
+	ctx->panel = of_drm_find_panel(lvds);
+	if (!ctx->panel) {
+		dev_info(dev, "panel not registered\n");
+		return -EPROBE_DEFER;
+	}
+
+	return 0;
+}
+
+static int tc358764_configure_regulators(struct tc358764 *ctx)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(ctx->supplies); ++i)
+		ctx->supplies[i].supply = tc358764_supplies[i];
+
+	ret = devm_regulator_bulk_get(ctx->dev, ARRAY_SIZE(ctx->supplies),
+				      ctx->supplies);
+	if (ret < 0)
+		dev_info(ctx->dev, "failed to get regulators: %d\n", ret);
+
+	return ret;
+}
+
+static int tc358764_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct tc358764 *ctx;
+	int ret;
+
+	ctx = devm_kzalloc(dev, sizeof(struct tc358764), GFP_KERNEL);
+	if (!ctx) {
+		dev_err(dev, "failed to allocate tc358764 structure.\n");
+		return -ENOMEM;
+	}
+
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	ctx->dev = dev;
+
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
+		| MIPI_DSI_MODE_VIDEO_AUTO_VERT;
+
+	ret = tc358764_parse_dt(ctx);
+	if (ret < 0)
+		return ret;
+
+	ret = tc358764_configure_regulators(ctx);
+	if (ret < 0)
+		return ret;
+
+	ret = devm_gpio_request_one(dev, ctx->reset_gpio, GPIOF_DIR_OUT,
+				    "TC358764_RESET");
+	if (ret < 0) {
+		dev_info(dev, "failed to request reset gpio\n");
+		return ret;
+	}
+
+	drm_panel_init(&ctx->bridge);
+	ctx->bridge.dev = dev;
+	ctx->bridge.funcs = &tc358764_drm_funcs;
+
+	ret = drm_panel_add(&ctx->bridge);
+	if (ret < 0)
+		return ret;
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0)
+		drm_panel_remove(&ctx->bridge);
+
+	return ret;
+}
+
+static int tc358764_remove(struct mipi_dsi_device *dsi)
+{
+	struct tc358764 *ctx = mipi_dsi_get_drvdata(dsi);
+
+	tc358764_poweroff(ctx);
+
+	mipi_dsi_detach(dsi);
+	drm_panel_remove(&ctx->bridge);
+
+	return 0;
+}
+
+static struct of_device_id tc358764_of_match[] = {
+	{ .compatible = "toshiba,tc358764" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, tc358764_of_match);
+
+static struct mipi_dsi_driver tc358764_driver = {
+	.probe = tc358764_probe,
+	.remove = tc358764_remove,
+	.driver = {
+		.name = "panel_tc358764",
+		.owner = THIS_MODULE,
+		.of_match_table = tc358764_of_match,
+	},
+};
+module_mipi_dsi_driver(tc358764_driver);
+
+MODULE_AUTHOR("Andrzej Hajda <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
+MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358764 DSI/LVDS Bridge");
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2

--
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] 49+ messages in thread

* [RFC PATCH v2 09/21] panel/simple: add video interface DT bindings
       [not found] ` <1392204688-4591-1-git-send-email-a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2014-02-12 11:31   ` [RFC PATCH v2 08/21] drm/panel: add TC358764 driver Andrzej Hajda
@ 2014-02-12 11:31   ` Andrzej Hajda
  2014-02-12 11:31   ` [RFC PATCH v2 12/21] ARM: dts: exynos4: add MIPI DSI Master node Andrzej Hajda
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Andrzej Hajda, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The bindings allow to create explicit link between devices
providing video signal and the panel.

Signed-off-by: Andrzej Hajda <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 Documentation/devicetree/bindings/panel/simple-panel.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/panel/simple-panel.txt b/Documentation/devicetree/bindings/panel/simple-panel.txt
index 1341bbf..4b1612e 100644
--- a/Documentation/devicetree/bindings/panel/simple-panel.txt
+++ b/Documentation/devicetree/bindings/panel/simple-panel.txt
@@ -8,6 +8,12 @@ Optional properties:
 - enable-gpios: GPIO pin to enable or disable the panel
 - backlight: phandle of the backlight device attached to the panel
 
+The device node can contain one 'port' child node with one child
+'endpoint' node, according to the bindings defined in [1]. This
+node should describe panel's video bus.
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
 Example:
 
 	panel: panel {
-- 
1.8.3.2

--
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] 49+ messages in thread

* [RFC PATCH v2 10/21] panel/hv070wsa-100: add DT bindings
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (6 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 07/21] panel/tc358764: add DT bindings Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 11/21] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel Andrzej Hajda
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds bindings to BOE HV070-WSA WSVGA panel.
Bindings are compatible with simple panel bindings.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 Documentation/devicetree/bindings/panel/boe,hv070wsa-100.txt | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/panel/boe,hv070wsa-100.txt

diff --git a/Documentation/devicetree/bindings/panel/boe,hv070wsa-100.txt b/Documentation/devicetree/bindings/panel/boe,hv070wsa-100.txt
new file mode 100644
index 0000000..bfc20ac
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/boe,hv070wsa-100.txt
@@ -0,0 +1,7 @@
+BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
+
+Required properties:
+- compatible: should be "boe,hv070wsa-100"
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
-- 
1.8.3.2

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

* [RFC PATCH v2 11/21] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (7 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 10/21] panel/hv070wsa-100: " Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 13/21] ARM: dts: exynos4210-trats: add panel node Andrzej Hajda
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds support for BOE HV070WSA-100 WSVGA 7.01 inch panel
in panel-simple driver. The panel is used in Exynos5250-arndale boards.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 3e611af..8aa8aab 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -338,6 +338,28 @@ static const struct panel_desc chunghwa_claa101wb01 = {
 	},
 };
 
+static const struct drm_display_mode boe_hv070wsa_mode = {
+	.clock = 40800,
+	.hdisplay = 1024,
+	.hsync_start = 1024 + 90,
+	.hsync_end = 1024 + 90 + 90,
+	.htotal = 1024 + 90 + 90 + 90,
+	.vdisplay = 600,
+	.vsync_start = 600 + 3,
+	.vsync_end = 600 + 3 + 4,
+	.vtotal = 600 + 3 + 4 + 3,
+	.vrefresh = 60,
+};
+
+static const struct panel_desc boe_hv070wsa = {
+	.modes = &boe_hv070wsa_mode,
+	.num_modes = 1,
+	.size = {
+		.width = 154,
+		.height = 90,
+	},
+};
+
 static const struct of_device_id platform_of_match[] = {
 	{
 		.compatible = "auo,b101aw03",
@@ -346,6 +368,9 @@ static const struct of_device_id platform_of_match[] = {
 		.compatible = "chunghwa,claa101wb01",
 		.data = &chunghwa_claa101wb01
 	}, {
+		.compatible = "boe,hv070wsa-100",
+		.data = &boe_hv070wsa
+	}, {
 		.compatible = "simple-panel",
 	}, {
 		/* sentinel */
-- 
1.8.3.2

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

* [RFC PATCH v2 12/21] ARM: dts: exynos4: add MIPI DSI Master node
       [not found] ` <1392204688-4591-1-git-send-email-a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2014-02-12 11:31   ` [RFC PATCH v2 08/21] drm/panel: add TC358764 driver Andrzej Hajda
  2014-02-12 11:31   ` [RFC PATCH v2 09/21] panel/simple: add video interface DT bindings Andrzej Hajda
@ 2014-02-12 11:31   ` Andrzej Hajda
  2014-02-12 11:31   ` [RFC PATCH v2 20/21] ARM: dts: exynos4210-trats: enable exynos/fimd node Andrzej Hajda
  2014-02-12 11:31   ` [RFC PATCH v2 21/21] ARM: dts: exynos4412-trats2: " Andrzej Hajda
  4 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Andrzej Hajda, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

This is a common part of DSI node for all Exynos4 boards.

Signed-off-by: Andrzej Hajda <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/exynos4.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index a73eeb5..7102f29 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -104,6 +104,20 @@
 		reg = <0x10010000 0x400>;
 	};
 
+	dsi_0: dsi@11C80000 {
+		compatible = "samsung,exynos4210-mipi-dsi";
+		reg = <0x11C80000 0x10000>;
+		interrupts = <0 79 0>;
+		samsung,power-domain = <&pd_lcd0>;
+		phys = <&mipi_phy 1>;
+		phy-names = "dsim";
+		clocks = <&clock 286>, <&clock 143>;
+		clock-names = "bus_clk", "pll_clk";
+		status = "disabled";
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
 	camera {
 		compatible = "samsung,fimc", "simple-bus";
 		status = "disabled";
-- 
1.8.3.2

--
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] 49+ messages in thread

* [RFC PATCH v2 13/21] ARM: dts: exynos4210-trats: add panel node
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (8 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 11/21] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 14/21] ARM: dts: exynos4412-trats2: " Andrzej Hajda
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds s6e8aa0 panel node for trats.
It adds also trats specific properties for DSI.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 arch/arm/boot/dts/exynos4210-trats.dts | 38 ++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 63cc571..5483969 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -353,6 +353,44 @@
 		};
 	};
 
+	dsi_0: dsi@11C80000 {
+		vddcore-supply = <&vusb_reg>;
+		vddio-supply = <&vmipi_reg>;
+		samsung,pll-clock-frequency = <24000000>;
+		samsung,burst-clock-frequency = <500000000>;
+		samsung,esc-clock-frequency = <20000000>;
+		status = "okay";
+
+		panel@0 {
+			reg = <0>;
+			compatible = "samsung,s6e8aa0";
+			vdd3-supply = <&vcclcd_reg>;
+			vci-supply = <&vlcd_reg>;
+			reset-gpio = <&gpy4 5 0>;
+			power-on-delay= <50>;
+			reset-delay = <100>;
+			init-delay = <100>;
+			flip-horizontal;
+			flip-vertical;
+			panel-width-mm = <58>;
+			panel-height-mm = <103>;
+
+			display-timings {
+				timing-0 {
+					clock-frequency = <57153600>;
+					hactive = <720>;
+					vactive = <1280>;
+					hfront-porch = <5>;
+					hback-porch = <5>;
+					hsync-len = <5>;
+					vfront-porch = <13>;
+					vback-porch = <1>;
+					vsync-len = <2>;
+				};
+			};
+		};
+	};
+
 	camera {
 		pinctrl-names = "default";
 		pinctrl-0 = <>;
-- 
1.8.3.2

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

* [RFC PATCH v2 14/21] ARM: dts: exynos4412-trats2: add panel node
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (9 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 13/21] ARM: dts: exynos4210-trats: add panel node Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-28 13:33   ` Tomi Valkeinen
  2014-02-12 11:31 ` [RFC PATCH v2 15/21] ARM: dts: exynos5250: add mipi-phy node Andrzej Hajda
                   ` (6 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds s6e8aa0 panel node for trats2.
It adds also trats2 specific properties for DSI
and regulator required by panel.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 arch/arm/boot/dts/exynos4412-trats2.dts | 47 +++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index fb7b9ae..0986d08 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -442,6 +442,15 @@
 		};
 	};
 
+	lcd_vdd3_reg: voltage-regulator@1 {
+		compatible = "regulator-fixed";
+		regulator-name = "LCD_VDD_2.2V";
+		regulator-min-microvolt = <2200000>;
+		regulator-max-microvolt = <2200000>;
+		gpio = <&gpc0 1 0>;
+		enable-active-high;
+	};
+
 	sdhci@12510000 {
 		bus-width = <8>;
 		non-removable;
@@ -498,6 +507,44 @@
 		};
 	};
 
+	dsi_0: dsi@11C80000 {
+		vddcore-supply = <&ldo8_reg>;
+		vddio-supply = <&ldo10_reg>;
+		samsung,pll-clock-frequency = <24000000>;
+		samsung,burst-clock-frequency = <500000000>;
+		samsung,esc-clock-frequency = <20000000>;
+		status = "okay";
+
+		panel@0 {
+			compatible = "samsung,s6e8aa0";
+			reg = <0>;
+			vdd3-supply = <&lcd_vdd3_reg>;
+			vci-supply = <&ldo25_reg>;
+			reset-gpio = <&gpy4 5 0>;
+			power-on-delay= <50>;
+			reset-delay = <100>;
+			init-delay = <100>;
+			flip-horizontal;
+			flip-vertical;
+			panel-width-mm = <58>;
+			panel-height-mm = <103>;
+
+			display-timings {
+				timing-0 {
+					clock-frequency = <0>;
+					hactive = <720>;
+					vactive = <1280>;
+					hfront-porch = <5>;
+					hback-porch = <5>;
+					hsync-len = <5>;
+					vfront-porch = <13>;
+					vback-porch = <1>;
+					vsync-len = <2>;
+				};
+			};
+		};
+	};
+
 	camera {
 		pinctrl-0 = <&cam_port_b_clk_active>;
 		pinctrl-names = "default";
-- 
1.8.3.2

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

* [RFC PATCH v2 15/21] ARM: dts: exynos5250: add mipi-phy node
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (10 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 14/21] ARM: dts: exynos4412-trats2: " Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 16/21] ARM: dts: exynos5250: add display power domain node Andrzej Hajda
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds phy node, required by MIPI devices.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 177becd..c8745a0 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -68,6 +68,12 @@
 		};
 	};
 
+	mipi_phy: video-phy@10040710 {
+		compatible = "samsung,s5pv210-mipi-video-phy";
+		reg = <0x10040710 8>;
+		#phy-cells = <1>;
+	};
+
 	pd_gsc: gsc-power-domain@10044000 {
 		compatible = "samsung,exynos4210-pd";
 		reg = <0x10044000 0x20>;
-- 
1.8.3.2

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

* [RFC PATCH v2 16/21] ARM: dts: exynos5250: add display power domain node
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (11 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 15/21] ARM: dts: exynos5250: add mipi-phy node Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:51   ` Sachin Kamat
  2014-02-12 11:31 ` [RFC PATCH v2 17/21] ARM: dts: exynos5250: add DSI node Andrzej Hajda
                   ` (4 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds power domain for display subsystem.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index c8745a0..0935dca 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -84,6 +84,11 @@
 		reg = <0x10044040 0x20>;
 	};
 
+	pd_disp: mfc-power-domain@100440a0 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x100440a0 0x20>;
+	};
+
 	clock: clock-controller@10010000 {
 		compatible = "samsung,exynos5250-clock";
 		reg = <0x10010000 0x30000>;
-- 
1.8.3.2

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

* [RFC PATCH v2 17/21] ARM: dts: exynos5250: add DSI node
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (12 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 16/21] ARM: dts: exynos5250: add display power domain node Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 18/21] ARM: dts: exynos5250-arndale: add display regulators Andrzej Hajda
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds common part of DSI node for Exynos5250 platforms.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 0935dca..bbe8ef4 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -656,6 +656,20 @@
 		phy-names = "dp";
 	};
 
+	dsi_0: dsi@14500000 {
+		compatible = "samsung,exynos4210-mipi-dsi";
+		reg = <0x14500000 0x10000>;
+		interrupts = <0 82 0>;
+		samsung,power-domain = <&pd_disp>;
+		phys = <&mipi_phy 3>;
+		phy-names = "dsim";
+		clocks = <&clock 341>, <&clock 134>;
+		clock-names = "bus_clk", "pll_clk";
+		status = "disabled";
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
 	fimd@14400000 {
 		clocks = <&clock 133>, <&clock 339>;
 		clock-names = "sclk_fimd", "fimd";
-- 
1.8.3.2

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

* [RFC PATCH v2 18/21] ARM: dts: exynos5250-arndale: add display regulators
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (13 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 17/21] ARM: dts: exynos5250: add DSI node Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-12 11:31 ` [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes Andrzej Hajda
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds fixed regulators used by DSI/LVDS bridge
and panel. Regulators are named according to schematics.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 arch/arm/boot/dts/exynos5250-arndale.dts | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 8aa8d8c..a0a985d 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -525,6 +525,30 @@
 			reg = <2>;
 			regulator-name = "hdmi-en";
 		};
+
+		vcc_1v2_reg: regulator@3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			regulator-name = "VCC_1V2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+		};
+
+		vcc_1v8_reg: regulator@4 {
+			compatible = "regulator-fixed";
+			reg = <4>;
+			regulator-name = "VCC_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+		vcc_3v3_reg: regulator@5 {
+			compatible = "regulator-fixed";
+			reg = <5>;
+			regulator-name = "VCC_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+		};
 	};
 
 	fixed-rate-clocks {
-- 
1.8.3.2

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

* [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (14 preceding siblings ...)
  2014-02-12 11:31 ` [RFC PATCH v2 18/21] ARM: dts: exynos5250-arndale: add display regulators Andrzej Hajda
@ 2014-02-12 11:31 ` Andrzej Hajda
  2014-02-28 13:31   ` Tomi Valkeinen
       [not found] ` <1392204688-4591-1-git-send-email-a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2014-03-05  2:56 ` [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Inki Dae
  17 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel
  Cc: Andrzej Hajda, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch adds bridge and panel nodes.
It adds also DSI properties specific for arndale board.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 arch/arm/boot/dts/exynos5250-arndale.dts | 39 ++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index a0a985d..7d666b1 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -584,6 +584,45 @@
 		};
 	};
 
+	panel: panel {
+		compatible = "boe,hv070wsa-100";
+		power-supply = <&vcc_3v3_reg>;
+		enable-gpios = <&gpd1 3 0>;
+		port {
+			panel_ep: endpoint {
+				remote-endpoint = <&bridge_out_ep>;
+			};
+		};
+	};
+
+	dsi_0: dsi@14500000 {
+		vddcore-supply = <&ldo8_reg>;
+		vddio-supply = <&ldo10_reg>;
+		samsung,pll-clock-frequency = <24000000>;
+		samsung,burst-clock-frequency = <320000000>;
+		samsung,esc-clock-frequency = <10000000>;
+		status = "okay";
+
+		bridge@0 {
+			reg = <0>;
+			compatible = "toshiba,tc358764";
+			vddc-supply = <&vcc_1v2_reg>;
+			vddio-supply = <&vcc_1v8_reg>;
+			vddmipi-supply = <&vcc_1v2_reg>;
+			vddlvds133-supply = <&vcc_3v3_reg>;
+			vddlvds112-supply = <&vcc_1v2_reg>;
+			reset-gpio = <&gpd1 6 1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@1 {
+				reg = <1>;
+				bridge_out_ep: endpoint {
+					remote-endpoint = <&panel_ep>;
+				};
+			};
+		};
+	};
+
 	fimd: fimd@14400000 {
 		status = "okay";
 	};
-- 
1.8.3.2

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

* [RFC PATCH v2 20/21] ARM: dts: exynos4210-trats: enable exynos/fimd node
       [not found] ` <1392204688-4591-1-git-send-email-a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (2 preceding siblings ...)
  2014-02-12 11:31   ` [RFC PATCH v2 12/21] ARM: dts: exynos4: add MIPI DSI Master node Andrzej Hajda
@ 2014-02-12 11:31   ` Andrzej Hajda
  2014-02-12 11:31   ` [RFC PATCH v2 21/21] ARM: dts: exynos4412-trats2: " Andrzej Hajda
  4 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Andrzej Hajda, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch changes fimd node status to OK.

Signed-off-by: Andrzej Hajda <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/exynos4210-trats.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 5483969..f121505 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -391,6 +391,10 @@
 		};
 	};
 
+	fimd@11c00000 {
+		status = "okay";
+	};
+
 	camera {
 		pinctrl-names = "default";
 		pinctrl-0 = <>;
-- 
1.8.3.2

--
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] 49+ messages in thread

* [RFC PATCH v2 21/21] ARM: dts: exynos4412-trats2: enable exynos/fimd node
       [not found] ` <1392204688-4591-1-git-send-email-a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
                     ` (3 preceding siblings ...)
  2014-02-12 11:31   ` [RFC PATCH v2 20/21] ARM: dts: exynos4210-trats: enable exynos/fimd node Andrzej Hajda
@ 2014-02-12 11:31   ` Andrzej Hajda
  4 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:31 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Andrzej Hajda, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

The patch changes fimd node status to OK.

Signed-off-by: Andrzej Hajda <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/exynos4412-trats2.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 0986d08..9296f86 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -545,6 +545,10 @@
 		};
 	};
 
+	fimd@11c00000 {
+		status = "okay";
+	};
+
 	camera {
 		pinctrl-0 = <&cam_port_b_clk_active>;
 		pinctrl-names = "default";
-- 
1.8.3.2

--
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] 49+ messages in thread

* Re: [RFC PATCH v2 16/21] ARM: dts: exynos5250: add display power domain node
  2014-02-12 11:31 ` [RFC PATCH v2 16/21] ARM: dts: exynos5250: add display power domain node Andrzej Hajda
@ 2014-02-12 11:51   ` Sachin Kamat
  2014-02-12 11:59     ` Andrzej Hajda
  0 siblings, 1 reply; 49+ messages in thread
From: Sachin Kamat @ 2014-02-12 11:51 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: dri-devel, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

Hi Andrzej,

On 12 February 2014 17:01, Andrzej Hajda <a.hajda@samsung.com> wrote:
> The patch adds power domain for display subsystem.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  arch/arm/boot/dts/exynos5250.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
> index c8745a0..0935dca 100644
> --- a/arch/arm/boot/dts/exynos5250.dtsi
> +++ b/arch/arm/boot/dts/exynos5250.dtsi
> @@ -84,6 +84,11 @@
>                 reg = <0x10044040 0x20>;
>         };
>
> +       pd_disp: mfc-power-domain@100440a0 {

Looks like a typo here.

-- 
With warm regards,
Sachin

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

* Re: [RFC PATCH v2 16/21] ARM: dts: exynos5250: add display power domain node
  2014-02-12 11:51   ` Sachin Kamat
@ 2014-02-12 11:59     ` Andrzej Hajda
  0 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-02-12 11:59 UTC (permalink / raw)
  To: Sachin Kamat
  Cc: dri-devel, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

On 02/12/2014 12:51 PM, Sachin Kamat wrote:
Hi Sachin,
> Hi Andrzej,
>
> On 12 February 2014 17:01, Andrzej Hajda <a.hajda@samsung.com> wrote:
>> The patch adds power domain for display subsystem.
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> ---
>>  arch/arm/boot/dts/exynos5250.dtsi | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
>> index c8745a0..0935dca 100644
>> --- a/arch/arm/boot/dts/exynos5250.dtsi
>> +++ b/arch/arm/boot/dts/exynos5250.dtsi
>> @@ -84,6 +84,11 @@
>>                 reg = <0x10044040 0x20>;
>>         };
>>
>> +       pd_disp: mfc-power-domain@100440a0 {
> Looks like a typo here.
>
Fortunately it is harmless, but thanks for pointing it out. Will be fixed.

Regards
Andrzej

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

* Re: [RFC PATCH v2 02/21] drm/exynos: delay fbdev initialization until an output is connected
  2014-02-12 11:31 ` [RFC PATCH v2 02/21] drm/exynos: delay fbdev initialization until an output is connected Andrzej Hajda
@ 2014-02-12 12:03   ` Sachin Kamat
  0 siblings, 0 replies; 49+ messages in thread
From: Sachin Kamat @ 2014-02-12 12:03 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: dri-devel, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski, Inki Dae

+cc Inki Dae

Looks like you missed CCing Exynos DRM maintainers.

On 12 February 2014 17:01, Andrzej Hajda <a.hajda@samsung.com> wrote:
> In case fbdev is initialized before any output is connected,
> fb resolution defaults to 1024x768. After that any output with
> bigger resolution is ignored and fbdev is not displayed.
> The patch postpones fbdev initialization to avoid such situation.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
[snip]

>  static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> index e7c2f2d..9a5ec83 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
> @@ -249,8 +249,10 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
>                 return 0;
>
>         fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
> -       if (!fbdev)
> +       if (!fbdev) {
> +               DRM_ERROR("failed to allocate fbdev.\n");

This message is not needed as kzalloc gives oom message.

>                 return -ENOMEM;
> +       }

-- 
With warm regards,
Sachin

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-02-12 11:31 ` [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes Andrzej Hajda
@ 2014-02-28 13:31   ` Tomi Valkeinen
  2014-02-28 13:39     ` Tomi Valkeinen
  0 siblings, 1 reply; 49+ messages in thread
From: Tomi Valkeinen @ 2014-02-28 13:31 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

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

On 12/02/14 13:31, Andrzej Hajda wrote:
> The patch adds bridge and panel nodes.
> It adds also DSI properties specific for arndale board.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  arch/arm/boot/dts/exynos5250-arndale.dts | 39 ++++++++++++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
> index a0a985d..7d666b1 100644
> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
> @@ -584,6 +584,45 @@
>  		};
>  	};
>  
> +	panel: panel {
> +		compatible = "boe,hv070wsa-100";
> +		power-supply = <&vcc_3v3_reg>;
> +		enable-gpios = <&gpd1 3 0>;
> +		port {
> +			panel_ep: endpoint {
> +				remote-endpoint = <&bridge_out_ep>;
> +			};
> +		};
> +	};
> +
> +	dsi_0: dsi@14500000 {
> +		vddcore-supply = <&ldo8_reg>;
> +		vddio-supply = <&ldo10_reg>;
> +		samsung,pll-clock-frequency = <24000000>;
> +		samsung,burst-clock-frequency = <320000000>;
> +		samsung,esc-clock-frequency = <10000000>;
> +		status = "okay";
> +
> +		bridge@0 {
> +			reg = <0>;
> +			compatible = "toshiba,tc358764";
> +			vddc-supply = <&vcc_1v2_reg>;
> +			vddio-supply = <&vcc_1v8_reg>;
> +			vddmipi-supply = <&vcc_1v2_reg>;
> +			vddlvds133-supply = <&vcc_3v3_reg>;
> +			vddlvds112-supply = <&vcc_1v2_reg>;
> +			reset-gpio = <&gpd1 6 1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			port@1 {
> +				reg = <1>;
> +				bridge_out_ep: endpoint {
> +					remote-endpoint = <&panel_ep>;
> +				};
> +			};
> +		};
> +	};

Compared to what I've done on OMAP, you don't seem to specify the video
inputs for the tc358764 at all. In this case it's obvious, as the chip
is a child of the DSI master. But the chip could as well be controlled
via i2c, and so be placed as a child of the i2c nodes.

So even if the driver doesn't use it, maybe it would be more future
proof to have both input and output endpoints for the tc358764?

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

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

* Re: [RFC PATCH v2 14/21] ARM: dts: exynos4412-trats2: add panel node
  2014-02-12 11:31 ` [RFC PATCH v2 14/21] ARM: dts: exynos4412-trats2: " Andrzej Hajda
@ 2014-02-28 13:33   ` Tomi Valkeinen
  2014-03-04 12:07     ` Andrzej Hajda
  0 siblings, 1 reply; 49+ messages in thread
From: Tomi Valkeinen @ 2014-02-28 13:33 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

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

On 12/02/14 13:31, Andrzej Hajda wrote:
> The patch adds s6e8aa0 panel node for trats2.
> It adds also trats2 specific properties for DSI
> and regulator required by panel.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  arch/arm/boot/dts/exynos4412-trats2.dts | 47 +++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
> index fb7b9ae..0986d08 100644
> --- a/arch/arm/boot/dts/exynos4412-trats2.dts
> +++ b/arch/arm/boot/dts/exynos4412-trats2.dts
> @@ -442,6 +442,15 @@
>  		};
>  	};
>  
> +	lcd_vdd3_reg: voltage-regulator@1 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "LCD_VDD_2.2V";
> +		regulator-min-microvolt = <2200000>;
> +		regulator-max-microvolt = <2200000>;
> +		gpio = <&gpc0 1 0>;
> +		enable-active-high;
> +	};
> +
>  	sdhci@12510000 {
>  		bus-width = <8>;
>  		non-removable;
> @@ -498,6 +507,44 @@
>  		};
>  	};
>  
> +	dsi_0: dsi@11C80000 {
> +		vddcore-supply = <&ldo8_reg>;
> +		vddio-supply = <&ldo10_reg>;
> +		samsung,pll-clock-frequency = <24000000>;
> +		samsung,burst-clock-frequency = <500000000>;
> +		samsung,esc-clock-frequency = <20000000>;
> +		status = "okay";
> +
> +		panel@0 {
> +			compatible = "samsung,s6e8aa0";
> +			reg = <0>;
> +			vdd3-supply = <&lcd_vdd3_reg>;
> +			vci-supply = <&ldo25_reg>;
> +			reset-gpio = <&gpy4 5 0>;
> +			power-on-delay= <50>;
> +			reset-delay = <100>;
> +			init-delay = <100>;
> +			flip-horizontal;
> +			flip-vertical;
> +			panel-width-mm = <58>;
> +			panel-height-mm = <103>;

I have the same comment here as for the bridge chip: I would specify the
video ports/endpoints between DSI master and the panel, even if you
don't use them at the moment.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-02-28 13:31   ` Tomi Valkeinen
@ 2014-02-28 13:39     ` Tomi Valkeinen
  2014-03-04 12:00       ` Andrzej Hajda
  0 siblings, 1 reply; 49+ messages in thread
From: Tomi Valkeinen @ 2014-02-28 13:39 UTC (permalink / raw)
  To: Tomi Valkeinen, Andrzej Hajda, dri-devel
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

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

On 28/02/14 15:31, Tomi Valkeinen wrote:

> Compared to what I've done on OMAP, you don't seem to specify the video
> inputs for the tc358764 at all. In this case it's obvious, as the chip
> is a child of the DSI master. But the chip could as well be controlled
> via i2c, and so be placed as a child of the i2c nodes.
> 
> So even if the driver doesn't use it, maybe it would be more future
> proof to have both input and output endpoints for the tc358764?

Oh, and one addition: how me and Laurent see the DSI case (and other
similar ones), the child/parent relationship gives the control bus path,
and the video ports give the video data path.

So both are always needed. A DSI panel may be controlled via DSI, i2c,
spi, but the video path will always go from DSI master to the panel.

Or, as a theoretical panel, you could have a DSI controlled panel, being
a child of the DSI master, but the video data would come via, say,
parallel RGB. You can actually do that with some panels/encoders, even
if the concept is silly.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-02-28 13:39     ` Tomi Valkeinen
@ 2014-03-04 12:00       ` Andrzej Hajda
  2014-03-04 12:40         ` Tomi Valkeinen
  2014-03-05 12:06         ` Inki Dae
  0 siblings, 2 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-04 12:00 UTC (permalink / raw)
  To: Tomi Valkeinen, dri-devel
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Marek Szyprowski

On 02/28/2014 02:39 PM, Tomi Valkeinen wrote:
> On 28/02/14 15:31, Tomi Valkeinen wrote:
>
>> Compared to what I've done on OMAP, you don't seem to specify the video
>> inputs for the tc358764 at all. In this case it's obvious, as the chip
>> is a child of the DSI master. But the chip could as well be controlled
>> via i2c, and so be placed as a child of the i2c nodes.
>>
>> So even if the driver doesn't use it, maybe it would be more future
>> proof to have both input and output endpoints for the tc358764?
> Oh, and one addition: how me and Laurent see the DSI case (and other
> similar ones), the child/parent relationship gives the control bus path,
> and the video ports give the video data path.
>
> So both are always needed. A DSI panel may be controlled via DSI, i2c,
> spi, but the video path will always go from DSI master to the panel.
I have made video path binding optional, in case of video bus
if the specific video path is not present driver uses the bus it is
connected to.
In case DSI panel is controlled via different bus the path should be
specified
explicitly.

I have no strong feelings against making this binding required but as
you have
stated above "in this case it's obvious" and for me quite redundant.

What is the gain in specifying explicitly video paths in such cases?
 

> Or, as a theoretical panel, you could have a DSI controlled panel, being
> a child of the DSI master, but the video data would come via, say,
> parallel RGB. You can actually do that with some panels/encoders, even
> if the concept is silly.

In this case explicit binding will work also.

Regards
Andrzej

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

* Re: [RFC PATCH v2 14/21] ARM: dts: exynos4412-trats2: add panel node
  2014-02-28 13:33   ` Tomi Valkeinen
@ 2014-03-04 12:07     ` Andrzej Hajda
  0 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-04 12:07 UTC (permalink / raw)
  To: Tomi Valkeinen, dri-devel
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

On 02/28/2014 02:33 PM, Tomi Valkeinen wrote:
> I have the same comment here as for the bridge chip: I would specify the
> video ports/endpoints between DSI master and the panel, even if you
> don't use them at the moment.
>
>  Tomi
>
>
I have sent my answer in bridge chip subthread.

Regards
Andrzej

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-03-04 12:00       ` Andrzej Hajda
@ 2014-03-04 12:40         ` Tomi Valkeinen
  2014-03-05 12:06         ` Inki Dae
  1 sibling, 0 replies; 49+ messages in thread
From: Tomi Valkeinen @ 2014-03-04 12:40 UTC (permalink / raw)
  To: Andrzej Hajda, dri-devel
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Sean Paul, Marek Szyprowski

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

On 04/03/14 14:00, Andrzej Hajda wrote:

> I have made video path binding optional, in case of video bus
> if the specific video path is not present driver uses the bus it is
> connected to.
> In case DSI panel is controlled via different bus the path should be
> specified
> explicitly.
> 
> I have no strong feelings against making this binding required but as
> you have
> stated above "in this case it's obvious" and for me quite redundant.

Yes, it's a good point. I didn't realize they were optional, I thought
they were not defined at all. I hadn't even thought that they could be
optional, I guess because in my uses there's always a reason to have
them. Even for a simple DSI command mode panel, I have information in
the DSI master's endpoint:

dsi {
	...

	dsi1_out_ep: endpoint {
		remote-endpoint = <&lcd0_in>;
		lanes = <0 1 2 3 4 5>;
	};
};

which forces to use an endpoint in the panel also.

And, actually, I think in your case also you would need an endpoint for
the dsi master, if you wanted to support multiple endpoints. You
currently have, for example, PLL clock freq as the DSI master's
property, but it should really be a property of the DSI master's endpoint.

I.e. if you have two DSI panels connected to the same DSI master, in a
way that only one can be enabled at a time (there would probably be a
mux to select where the DSI lanes go, we have that on some development
boards), you could well need different clock frequencies for the panels.

> What is the gain in specifying explicitly video paths in such cases?

- Until we (everyone interested in this) have thought about it fully and
agreed that video paths in cases like this are optional, you would be
safer to specify them explicitly. That way your bindings are valid in
either case.

- Uniformity. If in most cases we need to specify the video paths,
either because the control path is different than the data path, or
because there is need for endpoint specific information, having video
paths as optional for some specific cases may needlessly complicate the
code.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

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

* Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
  2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
                   ` (16 preceding siblings ...)
       [not found] ` <1392204688-4591-1-git-send-email-a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2014-03-05  2:56 ` Inki Dae
  2014-03-07 10:00   ` Andrzej Hajda
  17 siblings, 1 reply; 49+ messages in thread
From: Inki Dae @ 2014-03-05  2:56 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: DRI mailing list, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Marek Szyprowski

Hi Andrzej,

Thanks for your contributions.

2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
> Hi,
>
> This patchset adds drivers and bindings to the following devices:
> - Exynos DSI master,
> - S6E8AA0 DSI panel,
> - TC358764 DSI/LVDS bridge,
> - HV070WSA-100 LVDS panel.
>
> It adds also display support in DTS files for the following boards:
> - Exynos4210/Trats,
> - Exynos4412/Trats2,
> - Exynos5250/Arndale.
>
> Things worth mentioning:
>
> 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie.
> the driver exposes drm_panel interface on DSI side, and interact with
> panels on LVDS side using drm_panel framework. This approach seems to
> me simpler and more natural than using drm_bridge.

Can you give me more details about why you think better to use panel
framework than using drm_bridge?  "Simpler" and "more natural" are
ambiguous to me.

Using same drm_panel framework for LDVS bridge and real panel drivers
isn't reasonable to me as now because drm_panel framework would be for
real panel device even if the use of drm_panel framework looks like
suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver
using drm_bride stuff, is good enough, and that would be why
drm_bridge exists and why drm_encoder has drm_bridge.

And I'm finding more generic way, how to handle LVDS bridge using
super node so that  LVDS bridge driver isn't embedded to connector
drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be
done at top level of Exynos drm. Once the binding is done, encoder of
display bus driver will have drm_bridge object of LVDS bridge driver
so that display bus driver can handle LVDS bridge driver.

Will review your patch series soon.

Thanks,
Inki Dae

>
> 2. I have used video interface bindings to make link between bridge and LVDS panel.
> Other places where such links can be created are:
> a) link between DSI master and slave, I wonder if it is always neccessary,
>    DSI bus is also video bus,
> b) link between FIMD(display controller) and DSI Master, currently Exynos DRM
>    framework uses driver's hardcoded links, converting it to video interface
>    bindings should be done (if required) by separate patches.
>
> The patchset is based on Sean's Paul Exynos refactor patches v4 [1].
> To work properly porch calculation should be fixed according to my comment [2].
>
> It is the 2nd iteration of the patches, main changes:
> - based on v4 refactor patches,
> - added arndale related stuff.
> Other changes are described in individual patches.
>
> [1] http://permalink.gmane.org/gmane.comp.video.dri.devel/99264
> [2] http://permalink.gmane.org/gmane.comp.video.dri.devel/99826
>
> Regards
> Andrzej
>
>
> Andrzej Hajda (21):
>   drm_mipi_dsi: add flags to DSI messages
>   drm/exynos: delay fbdev initialization until an output is connected
>   exynos/dsim: add DT bindings
>   drm/exynos: add DSIM driver
>   panel/s6e8aa0: add DT bindings
>   drm/panel: add S6E8AA0 driver
>   panel/tc358764: add DT bindings
>   drm/panel: add TC358764 driver
>   panel/simple: add video interface DT bindings
>   panel/hv070wsa-100: add DT bindings
>   drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
>   ARM: dts: exynos4: add MIPI DSI Master node
>   ARM: dts: exynos4210-trats: add panel node
>   ARM: dts: exynos4412-trats2: add panel node
>   ARM: dts: exynos5250: add mipi-phy node
>   ARM: dts: exynos5250: add display power domain node
>   ARM: dts: exynos5250: add DSI node
>   ARM: dts: exynos5250-arndale: add display regulators
>   ARM: dts: exynos5250-arndale: add dsi and panel nodes
>   ARM: dts: exynos4210-trats: enable exynos/fimd node
>   ARM: dts: exynos4412-trats2: enable exynos/fimd node
>
>  .../devicetree/bindings/panel/boe,hv070wsa-100.txt |    7 +
>  .../devicetree/bindings/panel/samsung,s6e8aa0.txt  |   51 +
>  .../devicetree/bindings/panel/simple-panel.txt     |    6 +
>  .../devicetree/bindings/panel/toshiba,tc358764.txt |   41 +
>  .../devicetree/bindings/video/exynos_dsim.txt      |   53 +
>  arch/arm/boot/dts/exynos4.dtsi                     |   14 +
>  arch/arm/boot/dts/exynos4210-trats.dts             |   42 +
>  arch/arm/boot/dts/exynos4412-trats2.dts            |   51 +
>  arch/arm/boot/dts/exynos5250-arndale.dts           |   63 +
>  arch/arm/boot/dts/exynos5250.dtsi                  |   25 +
>  drivers/gpu/drm/exynos/Kconfig                     |    9 +
>  drivers/gpu/drm/exynos/Makefile                    |    1 +
>  drivers/gpu/drm/exynos/exynos_drm_drv.c            |   26 +-
>  drivers/gpu/drm/exynos/exynos_drm_drv.h            |    1 +
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c            | 1402 ++++++++++++++++++++
>  drivers/gpu/drm/exynos/exynos_drm_fb.c             |    3 +
>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c          |    4 +-
>  drivers/gpu/drm/panel/Kconfig                      |   14 +
>  drivers/gpu/drm/panel/Makefile                     |    2 +
>  drivers/gpu/drm/panel/panel-s6e8aa0.c              | 1064 +++++++++++++++
>  drivers/gpu/drm/panel/panel-simple.c               |   25 +
>  drivers/gpu/drm/panel/panel-tc358764.c             |  505 +++++++
>  include/drm/drm_mipi_dsi.h                         |    6 +
>  23 files changed, 3402 insertions(+), 13 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/panel/boe,hv070wsa-100.txt
>  create mode 100644 Documentation/devicetree/bindings/panel/samsung,s6e8aa0.txt
>  create mode 100644 Documentation/devicetree/bindings/panel/toshiba,tc358764.txt
>  create mode 100644 Documentation/devicetree/bindings/video/exynos_dsim.txt
>  create mode 100644 drivers/gpu/drm/exynos/exynos_drm_dsi.c
>  create mode 100644 drivers/gpu/drm/panel/panel-s6e8aa0.c
>  create mode 100644 drivers/gpu/drm/panel/panel-tc358764.c
>
> --
> 1.8.3.2
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 03/21] exynos/dsim: add DT bindings
  2014-02-12 11:31 ` [RFC PATCH v2 03/21] exynos/dsim: add DT bindings Andrzej Hajda
@ 2014-03-05  5:56   ` Inki Dae
  2014-03-07 10:54     ` Andrzej Hajda
  0 siblings, 1 reply; 49+ messages in thread
From: Inki Dae @ 2014-03-05  5:56 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: DRI mailing list, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Marek Szyprowski

2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
> The patch adds DT bindings for Exynos DSI Master. DSIM follows rules
> for DSI bus host bindings [1].
> Properties describes its resources: memory, interrupt, clocks,
> phy, regulators and frequencies of clocks.
>
> [1]: Documentation/devicetree/bindings/mipi/dsi/mipi-dsi-bus.txt
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
> v2
> - added burst and esc clock frequency properties
> - add samsung prefix to all frequency props
> ---
>  .../devicetree/bindings/video/exynos_dsim.txt      | 53 ++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/video/exynos_dsim.txt
>
> diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
> new file mode 100644
> index 0000000..2a49704
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
> @@ -0,0 +1,53 @@
> +Exynos MIPI DSI Master
> +
> +Required properties:
> +  - compatible: "samsung,exynos4210-mipi-dsi"
> +  - 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
> +    entry in clock-names
> +  - clock-names: should include "bus_clk"and "pll_clk" entries
> +  - phys: list of phy specifiers, must contain an entry for each required
> +    entry in phy-names
> +  - phy-names: should include "dsim" entry
> +  - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)
> +  - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
> +  - samsung,pll-clock-frequency: specifies frequency of the "pll_clk" clock
> +  - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
> +    mode
> +  - samsung,esc-clock-frequency: specifies DSI frequency in escape mode
> +  - #address-cells, #size-cells: should be set respectively to <1> and <0>
> +    according to DSI host bindings (see MIPI DSI bindings [1])
> +
> +Optional properties:
> +  - samsung,power-domain: a phandle to DSIM power domain node
> +
> +Child nodes:
> +  Should contain DSI peripheral nodes (see DSI bindings [1])
> +
> +[1]: Documentation/devicetree/bindings/mipi/dsi/mipi-dsi-bus.txt
> +
> +Example:
> +
> +       dsi@11C80000 {
> +               compatible = "samsung,exynos4210-mipi-dsi";
> +               reg = <0x11C80000 0x10000>;
> +               interrupts = <0 79 0>;
> +               clocks = <&clock 286>, <&clock 143>;
> +               clock-names = "bus_clk", "pll_clk";
> +               phys = <&mipi_phy 1>;
> +               phy-names = "dsim";
> +               vddcore-supply = <&vusb_reg>;
> +               vddio-supply = <&vmipi_reg>;
> +               samsung,power-domain = <&pd_lcd0>;
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +               samsung,pll-clock-frequency = <24000000>;
> +               samsung,burst-clock-frequency = <500000000>;
> +               samsung,esc-clock-frequency = <20000000>;

Isn't a property indicating cpu or video mode needed for the future
even though now DSI driver doesn't support CPU interface yet? Which
mode is used would depend on machine.

> +
> +               panel@0 {
> +                       reg = <0>;
> +                       ...
> +               };
> +       };
> --
> 1.8.3.2
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 08/21] drm/panel: add TC358764 driver
  2014-02-12 11:31   ` [RFC PATCH v2 08/21] drm/panel: add TC358764 driver Andrzej Hajda
@ 2014-03-05  6:46     ` Inki Dae
  2014-03-07 10:44       ` Andrzej Hajda
  0 siblings, 1 reply; 49+ messages in thread
From: Inki Dae @ 2014-03-05  6:46 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: DRI mailing list, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Marek Szyprowski

2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
> The patch adds driver for Toshiba DSI/LVDS TC358764 bridge.
> Driver registers itself as mipi_dsi_driver. It is exposed to the
> system via drm_panel interface, it uses also drm_panel framework
> to interact with LVDS panel connected to it.
> Driver supports only DT bindings.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/panel/Kconfig          |   7 +
>  drivers/gpu/drm/panel/Makefile         |   1 +
>  drivers/gpu/drm/panel/panel-tc358764.c | 505 +++++++++++++++++++++++++++++++++
>  3 files changed, 513 insertions(+)
>  create mode 100644 drivers/gpu/drm/panel/panel-tc358764.c
>
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 7527557..b98a485 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -23,4 +23,11 @@ config DRM_PANEL_S6E8AA0
>         select DRM_MIPI_DSI
>         select VIDEOMODE_HELPERS
>
> +config DRM_PANEL_TC358764
> +       tristate "TC358764 DSI/LVDS bridge"
> +       depends on DRM && DRM_PANEL
> +       depends on OF
> +       select DRM_MIPI_DSI
> +       select VIDEOMODE_HELPERS
> +
>  endmenu
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index 181265b..7cbb0cf 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -1,2 +1,3 @@
>  obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
>  obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
> +obj-$(CONFIG_DRM_PANEL_TC358764) += panel-tc358764.o
> diff --git a/drivers/gpu/drm/panel/panel-tc358764.c b/drivers/gpu/drm/panel/panel-tc358764.c
> new file mode 100644
> index 0000000..f9c1289
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-tc358764.c
> @@ -0,0 +1,505 @@
> +/*
> + * TC358764 MIPI-DSI to LVDS bridge panel driver.
> + *
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd
> + *
> + * Andrzej Hajda <a.hajda@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>
...
> +/* of_* functions will be removed after acceptance of of_graph patches */
> +static struct device_node *
> +of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
> +{
> +       struct device_node *np;
> +
> +       for_each_child_of_node(parent, np) {
> +               u32 r;
> +
> +               if (!np->name || of_node_cmp(np->name, name))
> +                       continue;
> +
> +               if (of_property_read_u32(np, "reg", &r) < 0)
> +                       r = 0;
> +
> +               if (reg == r)
> +                       break;
> +       }
> +
> +       return np;
> +}
> +
> +static struct device_node *of_graph_get_port_by_reg(struct device_node *parent,
> +                                                   u32 reg)
> +{
> +       struct device_node *ports, *port;
> +
> +       ports = of_get_child_by_name(parent, "ports");
> +       if (ports) {
> +               port = of_get_child_by_name_reg(ports, "port", reg);
> +               of_node_put(ports);
> +       } else {
> +               port = of_get_child_by_name_reg(parent, "port", reg);
> +       }
> +       return port;
> +}
> +
> +static struct device_node *
> +of_graph_get_endpoint_by_reg(struct device_node *port, u32 reg)
> +{
> +       return of_get_child_by_name_reg(port, "endpoint", reg);
> +}
> +
> +static struct device_node *
> +of_graph_get_remote_port_parent(const struct device_node *node)
> +{
> +       struct device_node *np;
> +       unsigned int depth;
> +
> +       /* Get remote endpoint node. */
> +       np = of_parse_phandle(node, "remote-endpoint", 0);
> +
> +       /* Walk 3 levels up only if there is 'ports' node. */
> +       for (depth = 3; depth && np; depth--) {
> +               np = of_get_next_parent(np);
> +               if (depth == 2 && of_node_cmp(np->name, "ports"))
> +                       break;
> +       }
> +       return np;
> +}
> +
> +static struct device_node *tc358764_of_find_panel_node(struct device *dev)
> +{
> +       struct device_node *np, *ep;
> +
> +       np = of_graph_get_port_by_reg(dev->of_node, 1);
> +       if (!np)
> +               return NULL;
> +
> +       ep = of_graph_get_endpoint_by_reg(np, 0);
> +       of_node_put(np);
> +       if (!ep)
> +               return NULL;
> +
> +       np = of_graph_get_remote_port_parent(ep);
> +       of_node_put(ep);
> +
> +       return np;
> +}
> +
> +static int tc358764_parse_dt(struct tc358764 *ctx)
> +{
> +       struct device *dev = ctx->dev;
> +       struct device_node *np = dev->of_node;
> +       struct device_node *lvds;
> +
> +       ctx->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
> +       if (ctx->reset_gpio < 0) {
> +               dev_err(dev, "no reset GPIO pin provided\n");
> +               //return ctx->reset_gpio;

Seem like your mistake.

> +       }
> +
> +       lvds = tc358764_of_find_panel_node(ctx->dev);

Isn't lvds device_node object of real lcd panel device, hv070wsa-100?
it seems like more meaningful to use panel instead of lvds.

> +       if (!lvds) {
> +               dev_err(dev, "cannot find panel node\n");
> +               return -EINVAL;
> +       }
> +       ctx->panel = of_drm_find_panel(lvds);
> +       if (!ctx->panel) {
> +               dev_info(dev, "panel not registered\n");
> +               return -EPROBE_DEFER;

That is what I concerned. This driver uses deferred probe feature
because real LCD panel driver couldn't be probed yet at this moment.
That isn't reasonable to me. There would be a better way than this
one.

> +       }
> +
> +       return 0;
> +}
> +
> +static int tc358764_configure_regulators(struct tc358764 *ctx)
> +{
> +       int i, ret;
> +
> +       for (i = 0; i < ARRAY_SIZE(ctx->supplies); ++i)
> +               ctx->supplies[i].supply = tc358764_supplies[i];
> +
> +       ret = devm_regulator_bulk_get(ctx->dev, ARRAY_SIZE(ctx->supplies),
> +                                     ctx->supplies);
> +       if (ret < 0)
> +               dev_info(ctx->dev, "failed to get regulators: %d\n", ret);
> +
> +       return ret;
> +}
> +
> +static int tc358764_probe(struct mipi_dsi_device *dsi)
> +{
> +       struct device *dev = &dsi->dev;
> +       struct tc358764 *ctx;
> +       int ret;
> +
> +       ctx = devm_kzalloc(dev, sizeof(struct tc358764), GFP_KERNEL);
> +       if (!ctx) {
> +               dev_err(dev, "failed to allocate tc358764 structure.\n");
> +               return -ENOMEM;
> +       }
> +
> +       mipi_dsi_set_drvdata(dsi, ctx);
> +
> +       ctx->dev = dev;
> +
> +       dsi->lanes = 4;
> +       dsi->format = MIPI_DSI_FMT_RGB888;
> +       dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
> +               | MIPI_DSI_MODE_VIDEO_AUTO_VERT;

Is it right for the pixel format, mode type and lane count are fixed?
I think these could be changed according to LCD type and its
resolution.

> +
> +       ret = tc358764_parse_dt(ctx);
> +       if (ret < 0)
> +               return ret;
> +
> +       ret = tc358764_configure_regulators(ctx);
> +       if (ret < 0)
> +               return ret;
> +
> +       ret = devm_gpio_request_one(dev, ctx->reset_gpio, GPIOF_DIR_OUT,
> +                                   "TC358764_RESET");
> +       if (ret < 0) {
> +               dev_info(dev, "failed to request reset gpio\n");
> +               return ret;
> +       }
> +
> +       drm_panel_init(&ctx->bridge);
> +       ctx->bridge.dev = dev;
> +       ctx->bridge.funcs = &tc358764_drm_funcs;
> +
> +       ret = drm_panel_add(&ctx->bridge);
> +       if (ret < 0)
> +               return ret;
> +
> +       ret = mipi_dsi_attach(dsi);
> +       if (ret < 0)
> +               drm_panel_remove(&ctx->bridge);
> +
> +       return ret;
> +}
> +
> +static int tc358764_remove(struct mipi_dsi_device *dsi)
> +{
> +       struct tc358764 *ctx = mipi_dsi_get_drvdata(dsi);
> +
> +       tc358764_poweroff(ctx);
> +
> +       mipi_dsi_detach(dsi);
> +       drm_panel_remove(&ctx->bridge);
> +
> +       return 0;
> +}
> +
> +static struct of_device_id tc358764_of_match[] = {
> +       { .compatible = "toshiba,tc358764" },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, tc358764_of_match);
> +
> +static struct mipi_dsi_driver tc358764_driver = {
> +       .probe = tc358764_probe,
> +       .remove = tc358764_remove,
> +       .driver = {
> +               .name = "panel_tc358764",
> +               .owner = THIS_MODULE,
> +               .of_match_table = tc358764_of_match,
> +       },
> +};
> +module_mipi_dsi_driver(tc358764_driver);
> +
> +MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
> +MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358764 DSI/LVDS Bridge");
> +MODULE_LICENSE("GPL v2");
> --
> 1.8.3.2
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-03-04 12:00       ` Andrzej Hajda
  2014-03-04 12:40         ` Tomi Valkeinen
@ 2014-03-05 12:06         ` Inki Dae
  2014-03-07 12:22           ` Andrzej Hajda
  1 sibling, 1 reply; 49+ messages in thread
From: Inki Dae @ 2014-03-05 12:06 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Tomi Valkeinen, DRI mailing list, Mark Rutland, devicetree,
	linux-samsung-soc, Pawel Moll, Ian Campbell, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

Sorry for interrupting,


2014-03-04 21:00 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
> On 02/28/2014 02:39 PM, Tomi Valkeinen wrote:
>> On 28/02/14 15:31, Tomi Valkeinen wrote:
>>
>>> Compared to what I've done on OMAP, you don't seem to specify the video
>>> inputs for the tc358764 at all. In this case it's obvious, as the chip
>>> is a child of the DSI master. But the chip could as well be controlled
>>> via i2c, and so be placed as a child of the i2c nodes.
>>>
>>> So even if the driver doesn't use it, maybe it would be more future
>>> proof to have both input and output endpoints for the tc358764?
>> Oh, and one addition: how me and Laurent see the DSI case (and other
>> similar ones), the child/parent relationship gives the control bus path,
>> and the video ports give the video data path.
>>
>> So both are always needed. A DSI panel may be controlled via DSI, i2c,
>> spi, but the video path will always go from DSI master to the panel.
> I have made video path binding optional, in case of video bus
> if the specific video path is not present driver uses the bus it is
> connected to.

You mean the case that video path isn't wrote in dt file for some
machine? If so, shouldn't we always write video patch in the dt file
correctly? I'm not sure the optional binding is needed because which
bus and which panel are used depends on machine.

And If I understood correctly the video interfaces document, it seems
that you don't deal with the document.

The below is simple dt binding I think in case that video path goes
from MIPI-DSI to LVDS bridge, and then from LVDS bridge to LCD Panel,

panel {
        ...
        port {
                ...
                panel_0: endpoint {
                        remote-endpoint=<&lvds_1>;
                };
        };
};

lvds {
       ...
       port@1 {
               ...
               lvds_0: endpoint {
                       remote-endpoint=<&dsi_0>;
               };
       };
       port@2 {
              ...
              lvds_1: endpoint {
                       remote-endpoint=<&panel_0>;
              };
       };
};

dsi {
        ...
        port {
                dsi_0: endpoint {
                        remote-endpoint=<&lvds_0>;
                };
        };
};

panel and lvds node could be a child of other masters, maybe i2c or spi.

Thanks,
Inki Dae


> In case DSI panel is controlled via different bus the path should be
> specified
> explicitly.
>
> I have no strong feelings against making this binding required but as
> you have
> stated above "in this case it's obvious" and for me quite redundant.
>
> What is the gain in specifying explicitly video paths in such cases?
>
>
>> Or, as a theoretical panel, you could have a DSI controlled panel, being
>> a child of the DSI master, but the video data would come via, say,
>> parallel RGB. You can actually do that with some panels/encoders, even
>> if the concept is silly.
>
> In this case explicit binding will work also.
>
> Regards
> Andrzej
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
  2014-03-05  2:56 ` [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Inki Dae
@ 2014-03-07 10:00   ` Andrzej Hajda
  2014-03-12 10:08     ` Inki Dae
  0 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-07 10:00 UTC (permalink / raw)
  To: Inki Dae
  Cc: DRI mailing list, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Marek Szyprowski

On 03/05/2014 03:56 AM, Inki Dae wrote:
> Hi Andrzej,
>
> Thanks for your contributions.
>
> 2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>> Hi,
>>
>> This patchset adds drivers and bindings to the following devices:
>> - Exynos DSI master,
>> - S6E8AA0 DSI panel,
>> - TC358764 DSI/LVDS bridge,
>> - HV070WSA-100 LVDS panel.
>>
>> It adds also display support in DTS files for the following boards:
>> - Exynos4210/Trats,
>> - Exynos4412/Trats2,
>> - Exynos5250/Arndale.
>>
>> Things worth mentioning:
>>
>> 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie.
>> the driver exposes drm_panel interface on DSI side, and interact with
>> panels on LVDS side using drm_panel framework. This approach seems to
>> me simpler and more natural than using drm_bridge.
> Can you give me more details about why you think better to use panel
> framework than using drm_bridge?  "Simpler" and "more natural" are
> ambiguous to me.
In this particular case DSI master expects on the other end
any device having DSI slave interface, it could be panel or bridge.
So it seems natural that both types of slave devices should expose
the same interface also  on programming level.
Another problem with drm_bridge is that it is not scalable -
if some manufacturer will decide to add another block between the bridge
and the panel there is no drm component which can be used for it.
Using drm_panel the way I have used in toshiba bridge makes scalability
possible,
it will be only a matter of adding a driver for new block and making
proper links in device tree, I see no easy way of doing it with
drm_bridge approach.


>
> Using same drm_panel framework for LDVS bridge and real panel drivers
> isn't reasonable to me as now because drm_panel framework would be for
> real panel device even if the use of drm_panel framework looks like
> suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver
> using drm_bride stuff, is good enough, and that would be why
> drm_bridge exists and why drm_encoder has drm_bridge.
>
> And I'm finding more generic way, how to handle LVDS bridge using
> super node so that  LVDS bridge driver isn't embedded to connector
> drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be
> done at top level of Exynos drm. Once the binding is done, encoder of
> display bus driver will have drm_bridge object of LVDS bridge driver
> so that display bus driver can handle LVDS bridge driver.
Could you explain what you mean by "dt binding of LVDS bridge can be
done at top level of Exynos drm" ? How it will look like if there
will be more bridges, one for DSI, one for HDMI, etc... What if there
will be two
bridges in one chain. How it will cope with video pipeline bindings?
>
> Will review your patch series soon.
Thanks in advance.

Regards
Andrzej

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

* Re: [RFC PATCH v2 08/21] drm/panel: add TC358764 driver
  2014-03-05  6:46     ` Inki Dae
@ 2014-03-07 10:44       ` Andrzej Hajda
  0 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-07 10:44 UTC (permalink / raw)
  To: Inki Dae
  Cc: DRI mailing list, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, Kyungmin Park, Rob Herring, Kumar Gala,
	Grant Likely, Marek Szyprowski

Hi Inki,

Thanks for the review.

On 03/05/2014 07:46 AM, Inki Dae wrote:
> 2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>> The patch adds driver for Toshiba DSI/LVDS TC358764 bridge.
>> Driver registers itself as mipi_dsi_driver. It is exposed to the
>> system via drm_panel interface, it uses also drm_panel framework
>> to interact with LVDS panel connected to it.
>> Driver supports only DT bindings.
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> ---
>>  drivers/gpu/drm/panel/Kconfig          |   7 +
>>  drivers/gpu/drm/panel/Makefile         |   1 +
>>  drivers/gpu/drm/panel/panel-tc358764.c | 505 +++++++++++++++++++++++++++++++++
>>  3 files changed, 513 insertions(+)
>>  create mode 100644 drivers/gpu/drm/panel/panel-tc358764.c
>>
>> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
>> index 7527557..b98a485 100644
>> --- a/drivers/gpu/drm/panel/Kconfig
>> +++ b/drivers/gpu/drm/panel/Kconfig
>> @@ -23,4 +23,11 @@ config DRM_PANEL_S6E8AA0
>>         select DRM_MIPI_DSI
>>         select VIDEOMODE_HELPERS
>>
>> +config DRM_PANEL_TC358764
>> +       tristate "TC358764 DSI/LVDS bridge"
>> +       depends on DRM && DRM_PANEL
>> +       depends on OF
>> +       select DRM_MIPI_DSI
>> +       select VIDEOMODE_HELPERS
>> +
>>  endmenu
>> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
>> index 181265b..7cbb0cf 100644
>> --- a/drivers/gpu/drm/panel/Makefile
>> +++ b/drivers/gpu/drm/panel/Makefile
>> @@ -1,2 +1,3 @@
>>  obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
>>  obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
>> +obj-$(CONFIG_DRM_PANEL_TC358764) += panel-tc358764.o
>> diff --git a/drivers/gpu/drm/panel/panel-tc358764.c b/drivers/gpu/drm/panel/panel-tc358764.c
>> new file mode 100644
>> index 0000000..f9c1289
>> --- /dev/null
>> +++ b/drivers/gpu/drm/panel/panel-tc358764.c
>> @@ -0,0 +1,505 @@
>> +/*
>> + * TC358764 MIPI-DSI to LVDS bridge panel driver.
>> + *
>> + * Copyright (c) 2013 Samsung Electronics Co., Ltd
>> + *
>> + * Andrzej Hajda <a.hajda@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>
> ...
>> +/* of_* functions will be removed after acceptance of of_graph patches */
>> +static struct device_node *
>> +of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
>> +{
>> +       struct device_node *np;
>> +
>> +       for_each_child_of_node(parent, np) {
>> +               u32 r;
>> +
>> +               if (!np->name || of_node_cmp(np->name, name))
>> +                       continue;
>> +
>> +               if (of_property_read_u32(np, "reg", &r) < 0)
>> +                       r = 0;
>> +
>> +               if (reg == r)
>> +                       break;
>> +       }
>> +
>> +       return np;
>> +}
>> +
>> +static struct device_node *of_graph_get_port_by_reg(struct device_node *parent,
>> +                                                   u32 reg)
>> +{
>> +       struct device_node *ports, *port;
>> +
>> +       ports = of_get_child_by_name(parent, "ports");
>> +       if (ports) {
>> +               port = of_get_child_by_name_reg(ports, "port", reg);
>> +               of_node_put(ports);
>> +       } else {
>> +               port = of_get_child_by_name_reg(parent, "port", reg);
>> +       }
>> +       return port;
>> +}
>> +
>> +static struct device_node *
>> +of_graph_get_endpoint_by_reg(struct device_node *port, u32 reg)
>> +{
>> +       return of_get_child_by_name_reg(port, "endpoint", reg);
>> +}
>> +
>> +static struct device_node *
>> +of_graph_get_remote_port_parent(const struct device_node *node)
>> +{
>> +       struct device_node *np;
>> +       unsigned int depth;
>> +
>> +       /* Get remote endpoint node. */
>> +       np = of_parse_phandle(node, "remote-endpoint", 0);
>> +
>> +       /* Walk 3 levels up only if there is 'ports' node. */
>> +       for (depth = 3; depth && np; depth--) {
>> +               np = of_get_next_parent(np);
>> +               if (depth == 2 && of_node_cmp(np->name, "ports"))
>> +                       break;
>> +       }
>> +       return np;
>> +}
>> +
>> +static struct device_node *tc358764_of_find_panel_node(struct device *dev)
>> +{
>> +       struct device_node *np, *ep;
>> +
>> +       np = of_graph_get_port_by_reg(dev->of_node, 1);
>> +       if (!np)
>> +               return NULL;
>> +
>> +       ep = of_graph_get_endpoint_by_reg(np, 0);
>> +       of_node_put(np);
>> +       if (!ep)
>> +               return NULL;
>> +
>> +       np = of_graph_get_remote_port_parent(ep);
>> +       of_node_put(ep);
>> +
>> +       return np;
>> +}
>> +
>> +static int tc358764_parse_dt(struct tc358764 *ctx)
>> +{
>> +       struct device *dev = ctx->dev;
>> +       struct device_node *np = dev->of_node;
>> +       struct device_node *lvds;
>> +
>> +       ctx->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
>> +       if (ctx->reset_gpio < 0) {
>> +               dev_err(dev, "no reset GPIO pin provided\n");
>> +               //return ctx->reset_gpio;
> Seem like your mistake.
Thanks, it should not be commented, it sneaked out somehow.
>
>> +       }
>> +
>> +       lvds = tc358764_of_find_panel_node(ctx->dev);
> Isn't lvds device_node object of real lcd panel device, hv070wsa-100?
> it seems like more meaningful to use panel instead of lvds.
Yes I will change it.
>
>> +       if (!lvds) {
>> +               dev_err(dev, "cannot find panel node\n");
>> +               return -EINVAL;
>> +       }
>> +       ctx->panel = of_drm_find_panel(lvds);
>> +       if (!ctx->panel) {
>> +               dev_info(dev, "panel not registered\n");
>> +               return -EPROBE_DEFER;
> That is what I concerned. This driver uses deferred probe feature
> because real LCD panel driver couldn't be probed yet at this moment.
> That isn't reasonable to me. There would be a better way than this
> one.
I think it can be avoided using your super-node patches.

Anyway deferred probe is used anyway, the bridge and the panel
can use other resources like regulators, clocks which can be also not
yet present during probe.

>
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int tc358764_configure_regulators(struct tc358764 *ctx)
>> +{
>> +       int i, ret;
>> +
>> +       for (i = 0; i < ARRAY_SIZE(ctx->supplies); ++i)
>> +               ctx->supplies[i].supply = tc358764_supplies[i];
>> +
>> +       ret = devm_regulator_bulk_get(ctx->dev, ARRAY_SIZE(ctx->supplies),
>> +                                     ctx->supplies);
>> +       if (ret < 0)
>> +               dev_info(ctx->dev, "failed to get regulators: %d\n", ret);
>> +
>> +       return ret;
>> +}
>> +
>> +static int tc358764_probe(struct mipi_dsi_device *dsi)
>> +{
>> +       struct device *dev = &dsi->dev;
>> +       struct tc358764 *ctx;
>> +       int ret;
>> +
>> +       ctx = devm_kzalloc(dev, sizeof(struct tc358764), GFP_KERNEL);
>> +       if (!ctx) {
>> +               dev_err(dev, "failed to allocate tc358764 structure.\n");
>> +               return -ENOMEM;
>> +       }
>> +
>> +       mipi_dsi_set_drvdata(dsi, ctx);
>> +
>> +       ctx->dev = dev;
>> +
>> +       dsi->lanes = 4;
>> +       dsi->format = MIPI_DSI_FMT_RGB888;
>> +       dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
>> +               | MIPI_DSI_MODE_VIDEO_AUTO_VERT;
> Is it right for the pixel format, mode type and lane count are fixed?
> I think these could be changed according to LCD type and its
> resolution.
I have no access to tc358764 datasheet so I can only guess
that some parameters are determined by LCD but the bridge
is also capable to perform some conversions.

I set parameters here as sane defaults. If there will be other use cases
than arndale it can be extended in the future.

Regards
Andrzej

>
>> +
>> +       ret = tc358764_parse_dt(ctx);
>> +       if (ret < 0)
>> +               return ret;
>> +
>> +       ret = tc358764_configure_regulators(ctx);
>> +       if (ret < 0)
>> +               return ret;
>> +
>> +       ret = devm_gpio_request_one(dev, ctx->reset_gpio, GPIOF_DIR_OUT,
>> +                                   "TC358764_RESET");
>> +       if (ret < 0) {
>> +               dev_info(dev, "failed to request reset gpio\n");
>> +               return ret;
>> +       }
>> +
>> +       drm_panel_init(&ctx->bridge);
>> +       ctx->bridge.dev = dev;
>> +       ctx->bridge.funcs = &tc358764_drm_funcs;
>> +
>> +       ret = drm_panel_add(&ctx->bridge);
>> +       if (ret < 0)
>> +               return ret;
>> +
>> +       ret = mipi_dsi_attach(dsi);
>> +       if (ret < 0)
>> +               drm_panel_remove(&ctx->bridge);
>> +
>> +       return ret;
>> +}
>> +
>> +static int tc358764_remove(struct mipi_dsi_device *dsi)
>> +{
>> +       struct tc358764 *ctx = mipi_dsi_get_drvdata(dsi);
>> +
>> +       tc358764_poweroff(ctx);
>> +
>> +       mipi_dsi_detach(dsi);
>> +       drm_panel_remove(&ctx->bridge);
>> +
>> +       return 0;
>> +}
>> +
>> +static struct of_device_id tc358764_of_match[] = {
>> +       { .compatible = "toshiba,tc358764" },
>> +       { }
>> +};
>> +MODULE_DEVICE_TABLE(of, tc358764_of_match);
>> +
>> +static struct mipi_dsi_driver tc358764_driver = {
>> +       .probe = tc358764_probe,
>> +       .remove = tc358764_remove,
>> +       .driver = {
>> +               .name = "panel_tc358764",
>> +               .owner = THIS_MODULE,
>> +               .of_match_table = tc358764_of_match,
>> +       },
>> +};
>> +module_mipi_dsi_driver(tc358764_driver);
>> +
>> +MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
>> +MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358764 DSI/LVDS Bridge");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 1.8.3.2
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 03/21] exynos/dsim: add DT bindings
  2014-03-05  5:56   ` Inki Dae
@ 2014-03-07 10:54     ` Andrzej Hajda
  0 siblings, 0 replies; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-07 10:54 UTC (permalink / raw)
  To: Inki Dae
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, DRI mailing list, Kyungmin Park, Rob Herring,
	Kumar Gala, Grant Likely, Marek Szyprowski

On 03/05/2014 06:56 AM, Inki Dae wrote:
> 2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>> The patch adds DT bindings for Exynos DSI Master. DSIM follows rules
>> for DSI bus host bindings [1].
>> Properties describes its resources: memory, interrupt, clocks,
>> phy, regulators and frequencies of clocks.
>>
>> [1]: Documentation/devicetree/bindings/mipi/dsi/mipi-dsi-bus.txt
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> ---
>> v2
>> - added burst and esc clock frequency properties
>> - add samsung prefix to all frequency props
>> ---
>>  .../devicetree/bindings/video/exynos_dsim.txt      | 53 ++++++++++++++++++++++
>>  1 file changed, 53 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/video/exynos_dsim.txt
>>
>> diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
>> new file mode 100644
>> index 0000000..2a49704
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
>> @@ -0,0 +1,53 @@
>> +Exynos MIPI DSI Master
>> +
>> +Required properties:
>> +  - compatible: "samsung,exynos4210-mipi-dsi"
>> +  - 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
>> +    entry in clock-names
>> +  - clock-names: should include "bus_clk"and "pll_clk" entries
>> +  - phys: list of phy specifiers, must contain an entry for each required
>> +    entry in phy-names
>> +  - phy-names: should include "dsim" entry
>> +  - vddcore-supply: MIPI DSIM Core voltage supply (e.g. 1.1V)
>> +  - vddio-supply: MIPI DSIM I/O and PLL voltage supply (e.g. 1.8V)
>> +  - samsung,pll-clock-frequency: specifies frequency of the "pll_clk" clock
>> +  - samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
>> +    mode
>> +  - samsung,esc-clock-frequency: specifies DSI frequency in escape mode
>> +  - #address-cells, #size-cells: should be set respectively to <1> and <0>
>> +    according to DSI host bindings (see MIPI DSI bindings [1])
>> +
>> +Optional properties:
>> +  - samsung,power-domain: a phandle to DSIM power domain node
>> +
>> +Child nodes:
>> +  Should contain DSI peripheral nodes (see DSI bindings [1])
>> +
>> +[1]: Documentation/devicetree/bindings/mipi/dsi/mipi-dsi-bus.txt
>> +
>> +Example:
>> +
>> +       dsi@11C80000 {
>> +               compatible = "samsung,exynos4210-mipi-dsi";
>> +               reg = <0x11C80000 0x10000>;
>> +               interrupts = <0 79 0>;
>> +               clocks = <&clock 286>, <&clock 143>;
>> +               clock-names = "bus_clk", "pll_clk";
>> +               phys = <&mipi_phy 1>;
>> +               phy-names = "dsim";
>> +               vddcore-supply = <&vusb_reg>;
>> +               vddio-supply = <&vmipi_reg>;
>> +               samsung,power-domain = <&pd_lcd0>;
>> +               #address-cells = <1>;
>> +               #size-cells = <0>;
>> +               samsung,pll-clock-frequency = <24000000>;
>> +               samsung,burst-clock-frequency = <500000000>;
>> +               samsung,esc-clock-frequency = <20000000>;
> Isn't a property indicating cpu or video mode needed for the future
> even though now DSI driver doesn't support CPU interface yet? Which
> mode is used would depend on machine.
Mode is determined by panel, ie. by dsi slave.

Regards
Andrzej
>
>> +
>> +               panel@0 {
>> +                       reg = <0>;
>> +                       ...
>> +               };
>> +       };
>> --
>> 1.8.3.2
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-03-05 12:06         ` Inki Dae
@ 2014-03-07 12:22           ` Andrzej Hajda
  2014-03-07 12:32             ` Tomi Valkeinen
  0 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-07 12:22 UTC (permalink / raw)
  To: Inki Dae
  Cc: Tomi Valkeinen, DRI mailing list, Mark Rutland, devicetree,
	linux-samsung-soc, Pawel Moll, Ian Campbell, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

On 03/05/2014 01:06 PM, Inki Dae wrote:
> Sorry for interrupting,
>
>
> 2014-03-04 21:00 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>> On 02/28/2014 02:39 PM, Tomi Valkeinen wrote:
>>> On 28/02/14 15:31, Tomi Valkeinen wrote:
>>>
>>>> Compared to what I've done on OMAP, you don't seem to specify the video
>>>> inputs for the tc358764 at all. In this case it's obvious, as the chip
>>>> is a child of the DSI master. But the chip could as well be controlled
>>>> via i2c, and so be placed as a child of the i2c nodes.
>>>>
>>>> So even if the driver doesn't use it, maybe it would be more future
>>>> proof to have both input and output endpoints for the tc358764?
>>> Oh, and one addition: how me and Laurent see the DSI case (and other
>>> similar ones), the child/parent relationship gives the control bus path,
>>> and the video ports give the video data path.
>>>
>>> So both are always needed. A DSI panel may be controlled via DSI, i2c,
>>> spi, but the video path will always go from DSI master to the panel.
>> I have made video path binding optional, in case of video bus
>> if the specific video path is not present driver uses the bus it is
>> connected to.
> You mean the case that video path isn't wrote in dt file for some
> machine? If so, shouldn't we always write video patch in the dt file
> correctly? I'm not sure the optional binding is needed because which
> bus and which panel are used depends on machine.
>
> And If I understood correctly the video interfaces document, it seems
> that you don't deal with the document.
I have followed the document, I have even specified it in bridge bindings.
I have just made those bindings optional in case control bus is the same
as video bus - DSI master/slave case.
>
> The below is simple dt binding I think in case that video path goes
> from MIPI-DSI to LVDS bridge, and then from LVDS bridge to LCD Panel,
>
> panel {
>         ...
>         port {
>                 ...
>                 panel_0: endpoint {
>                         remote-endpoint=<&lvds_1>;
>                 };
>         };
> };
>
> lvds {
>        ...
>        port@1 {
>                ...
>                lvds_0: endpoint {
>                        remote-endpoint=<&dsi_0>;
>                };
>        };
>        port@2 {
>               ...
>               lvds_1: endpoint {
>                        remote-endpoint=<&panel_0>;
>               };
>        };
> };
>
> dsi {
>         ...
>         port {
>                 dsi_0: endpoint {
>                         remote-endpoint=<&lvds_0>;
>                 };
>         };
> };
>
I think we should even extend the bindings to fimd:
dsi {
    port@0 {
        dsi_0: endpoint {
            remote-endpoint=<&fimd_0>;
        }
    }
    port@1 {
        dsi_1: endpoint {
            remote-endpoint=<&lvds_0>;
        }
    }
}

fimd {
    port@0 {
        fimd_0: endpoint {
            remote-endpoint=<&dsi_0>;
        }
    }
}


> panel and lvds node could be a child of other masters, maybe i2c or spi.
As I mentioned earlier, in such cases bindings should be specified
explicitly.
My proposition of omitting obvious bindings was made to simplify a bit
dts files,
but as I stated earlier it is not something I want to die for :)

Regards
Andrzej

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-03-07 12:22           ` Andrzej Hajda
@ 2014-03-07 12:32             ` Tomi Valkeinen
  2014-03-07 13:07               ` Andrzej Hajda
  0 siblings, 1 reply; 49+ messages in thread
From: Tomi Valkeinen @ 2014-03-07 12:32 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Inki Dae, DRI mailing list, Mark Rutland, devicetree,
	linux-samsung-soc, Pawel Moll, Ian Campbell, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

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

On 07/03/14 14:22, Andrzej Hajda wrote:

> I think we should even extend the bindings to fimd:
> dsi {
>     port@0 {
>         dsi_0: endpoint {
>             remote-endpoint=<&fimd_0>;
>         }
>     }
>     port@1 {
>         dsi_1: endpoint {
>             remote-endpoint=<&lvds_0>;
>         }
>     }
> }
> 
> fimd {
>     port@0 {
>         fimd_0: endpoint {
>             remote-endpoint=<&dsi_0>;
>         }
>     }
> }

If both fimd and dsi are SoC components, I don't see any strict need for
that. I think the ports/endpoints are only important when dealing with
external components, which can be used on any platform. For SoC internal
components you can have relevant data directly in the drivers, as it is
fixed (for that SoC).

Of course, if using ports for SoC internal components makes things
easier for you, I don't see any problems with it either.

For OMAP, the SoC's display blocks are all inside one bigger DSS
"container", so I have not seen need to represent the connections
between the internal components in the DT data.

If the display components were truly independent IPs on the SoC, then
using ports might make things easier.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-03-07 12:32             ` Tomi Valkeinen
@ 2014-03-07 13:07               ` Andrzej Hajda
  2014-03-07 13:28                 ` Tomi Valkeinen
  0 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-07 13:07 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Inki Dae, DRI mailing list, Mark Rutland, devicetree,
	linux-samsung-soc, Pawel Moll, Ian Campbell, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

On 03/07/2014 01:32 PM, Tomi Valkeinen wrote:
> On 07/03/14 14:22, Andrzej Hajda wrote:
>
>> I think we should even extend the bindings to fimd:
>> dsi {
>>     port@0 {
>>         dsi_0: endpoint {
>>             remote-endpoint=<&fimd_0>;
>>         }
>>     }
>>     port@1 {
>>         dsi_1: endpoint {
>>             remote-endpoint=<&lvds_0>;
>>         }
>>     }
>> }
>>
>> fimd {
>>     port@0 {
>>         fimd_0: endpoint {
>>             remote-endpoint=<&dsi_0>;
>>         }
>>     }
>> }
> If both fimd and dsi are SoC components, I don't see any strict need for
> that. I think the ports/endpoints are only important when dealing with
> external components, which can be used on any platform. For SoC internal
> components you can have relevant data directly in the drivers, as it is
> fixed (for that SoC).
>
> Of course, if using ports for SoC internal components makes things
> easier for you, I don't see any problems with it either.
There are many possible connections from FIMD, some of them:
FIMD ---> RGB panel, external
FIMD ---> DSI, on SoC
FIMD ---> eDP, on SoC
FIMD ---> ImageEnhacer, on SoC

In the first case port should be created.
In other cases connection could be determined by presence/absence
of specific nodes, so in fact the port can be optional, almost like in
my proposal :)


>
> For OMAP, the SoC's display blocks are all inside one bigger DSS
> "container", so I have not seen need to represent the connections
> between the internal components in the DT data.
How do you deal with situation when IPs in SoC can be connected in
different ways ?

Andrzej
> If the display components were truly independent IPs on the SoC, then
> using ports might make things easier.
>
>  Tomi
>
>

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-03-07 13:07               ` Andrzej Hajda
@ 2014-03-07 13:28                 ` Tomi Valkeinen
  2014-03-07 14:17                   ` Andrzej Hajda
  0 siblings, 1 reply; 49+ messages in thread
From: Tomi Valkeinen @ 2014-03-07 13:28 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Inki Dae, DRI mailing list, Mark Rutland, devicetree,
	linux-samsung-soc, Pawel Moll, Ian Campbell, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

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

On 07/03/14 15:07, Andrzej Hajda wrote:
> On 03/07/2014 01:32 PM, Tomi Valkeinen wrote:
>> On 07/03/14 14:22, Andrzej Hajda wrote:
>>
>>> I think we should even extend the bindings to fimd:
>>> dsi {
>>>     port@0 {
>>>         dsi_0: endpoint {
>>>             remote-endpoint=<&fimd_0>;
>>>         }
>>>     }
>>>     port@1 {
>>>         dsi_1: endpoint {
>>>             remote-endpoint=<&lvds_0>;
>>>         }
>>>     }
>>> }
>>>
>>> fimd {
>>>     port@0 {
>>>         fimd_0: endpoint {
>>>             remote-endpoint=<&dsi_0>;
>>>         }
>>>     }
>>> }
>> If both fimd and dsi are SoC components, I don't see any strict need for
>> that. I think the ports/endpoints are only important when dealing with
>> external components, which can be used on any platform. For SoC internal
>> components you can have relevant data directly in the drivers, as it is
>> fixed (for that SoC).
>>
>> Of course, if using ports for SoC internal components makes things
>> easier for you, I don't see any problems with it either.
> There are many possible connections from FIMD, some of them:
> FIMD ---> RGB panel, external
> FIMD ---> DSI, on SoC
> FIMD ---> eDP, on SoC
> FIMD ---> ImageEnhacer, on SoC

This sounds similar to OMAP, at least roughly.

> In the first case port should be created.
> In other cases connection could be determined by presence/absence
> of specific nodes, so in fact the port can be optional, almost like in
> my proposal :)

Well, I think not.

In the external encoder case, the ports are there, and they are used.
You just didn't specify them, and thus make the driver deduce them from
the DT.

In the FIMD case, if the the RGB port is needed, you need to specify it
in the DT data, and it's used. If you only need, say, DSI, the RGB port
is not used and thus it doesn't need to be present in the DT data.

It's fine to leave the port definition out if it is not used at all.

>> For OMAP, the SoC's display blocks are all inside one bigger DSS
>> "container", so I have not seen need to represent the connections
>> between the internal components in the DT data.
> How do you deal with situation when IPs in SoC can be connected in
> different ways ?

Basically so that (using exynos terms) if, say DSI panel is to be
enabled, the DSI panel driver will reserve the DSI master for itself,
and the DSI master will reserve the FIMD for itself, presuming FIMD has
not already been reserved. When the DSI panel is disabled, FIMD is freed.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-03-07 13:28                 ` Tomi Valkeinen
@ 2014-03-07 14:17                   ` Andrzej Hajda
  2014-03-07 14:36                     ` Tomi Valkeinen
  0 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-07 14:17 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Inki Dae, DRI mailing list, Mark Rutland, devicetree,
	linux-samsung-soc, Pawel Moll, Ian Campbell, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

On 03/07/2014 02:28 PM, Tomi Valkeinen wrote:
(...)
> There are many possible connections from FIMD, some of them:
> FIMD ---> RGB panel, external
> FIMD ---> DSI, on SoC
> FIMD ---> eDP, on SoC
> FIMD ---> ImageEnhacer, on SoC
> This sounds similar to OMAP, at least roughly.
>
>> In the first case port should be created.
>> In other cases connection could be determined by presence/absence
>> of specific nodes, so in fact the port can be optional, almost like in
>> my proposal :)
> Well, I think not.
>
> In the external encoder case, the ports are there, and they are used.
> You just didn't specify them, and thus make the driver deduce them from
> the DT.
>
> In the FIMD case, if the the RGB port is needed, you need to specify it
> in the DT data, and it's used. If you only need, say, DSI, the RGB port
> is not used and thus it doesn't need to be present in the DT data.
>
> It's fine to leave the port definition out if it is not used at all.
On Exynos, DSI is in fact RGB/DSI encoder (or I80/DSI). DSI and RGB pins
are connected to the same FIMD output. So from FIMD point of view
RGB port is used in both cases.
>
>>> For OMAP, the SoC's display blocks are all inside one bigger DSS
>>> "container", so I have not seen need to represent the connections
>>> between the internal components in the DT data.
>> How do you deal with situation when IPs in SoC can be connected in
>> different ways ?
> Basically so that (using exynos terms) if, say DSI panel is to be
> enabled, the DSI panel driver will reserve the DSI master for itself,
> and the DSI master will reserve the FIMD for itself, presuming FIMD has
> not already been reserved. When the DSI panel is disabled, FIMD is freed.
>
>  Tomi
>
>

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

* Re: [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes
  2014-03-07 14:17                   ` Andrzej Hajda
@ 2014-03-07 14:36                     ` Tomi Valkeinen
  0 siblings, 0 replies; 49+ messages in thread
From: Tomi Valkeinen @ 2014-03-07 14:36 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Inki Dae, DRI mailing list, Mark Rutland, devicetree,
	linux-samsung-soc, Pawel Moll, Ian Campbell, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

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

On 07/03/14 16:17, Andrzej Hajda wrote:
> On 03/07/2014 02:28 PM, Tomi Valkeinen wrote:
> (...)
>> There are many possible connections from FIMD, some of them:
>> FIMD ---> RGB panel, external
>> FIMD ---> DSI, on SoC
>> FIMD ---> eDP, on SoC
>> FIMD ---> ImageEnhacer, on SoC
>> This sounds similar to OMAP, at least roughly.
>>
>>> In the first case port should be created.
>>> In other cases connection could be determined by presence/absence
>>> of specific nodes, so in fact the port can be optional, almost like in
>>> my proposal :)
>> Well, I think not.
>>
>> In the external encoder case, the ports are there, and they are used.
>> You just didn't specify them, and thus make the driver deduce them from
>> the DT.
>>
>> In the FIMD case, if the the RGB port is needed, you need to specify it
>> in the DT data, and it's used. If you only need, say, DSI, the RGB port
>> is not used and thus it doesn't need to be present in the DT data.
>>
>> It's fine to leave the port definition out if it is not used at all.
> On Exynos, DSI is in fact RGB/DSI encoder (or I80/DSI). DSI and RGB pins
> are connected to the same FIMD output. So from FIMD point of view
> RGB port is used in both cases.

I guessed as much, as it's the same on OMAP.

But I think it's still fine to have a port only for RGB panel. For the
RGB panel, you have pins on the SoC to which the RGB data goes to. The
RGB port in DT represents these pins. You don't have pins for the
FIMD->DSI case.

But as I said, it's fine to use ports for internal connections also if
it works for you.

I still don't like the idea of having the port as optional in DT for
cases where the port comes from the parent device. Sure, it removes some
lines from the DT, but I think it makes it more confusing. Especially as
I think it's a very rare case where you could use that optional format,
as usually you will have some properties in the endpoint node.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

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

* Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
  2014-03-07 10:00   ` Andrzej Hajda
@ 2014-03-12 10:08     ` Inki Dae
  2014-03-12 11:16       ` Tomasz Figa
  0 siblings, 1 reply; 49+ messages in thread
From: Inki Dae @ 2014-03-12 10:08 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, DRI mailing list, Kyungmin Park, Rob Herring,
	Kumar Gala, Grant Likely, Marek Szyprowski

2014-03-07 19:00 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
> On 03/05/2014 03:56 AM, Inki Dae wrote:
>> Hi Andrzej,
>>
>> Thanks for your contributions.
>>
>> 2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>>> Hi,
>>>
>>> This patchset adds drivers and bindings to the following devices:
>>> - Exynos DSI master,
>>> - S6E8AA0 DSI panel,
>>> - TC358764 DSI/LVDS bridge,
>>> - HV070WSA-100 LVDS panel.
>>>
>>> It adds also display support in DTS files for the following boards:
>>> - Exynos4210/Trats,
>>> - Exynos4412/Trats2,
>>> - Exynos5250/Arndale.
>>>
>>> Things worth mentioning:
>>>
>>> 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie.
>>> the driver exposes drm_panel interface on DSI side, and interact with
>>> panels on LVDS side using drm_panel framework. This approach seems to
>>> me simpler and more natural than using drm_bridge.
>> Can you give me more details about why you think better to use panel
>> framework than using drm_bridge?  "Simpler" and "more natural" are
>> ambiguous to me.
> In this particular case DSI master expects on the other end
> any device having DSI slave interface, it could be panel or bridge.
> So it seems natural that both types of slave devices should expose
> the same interface also  on programming level.
> Another problem with drm_bridge is that it is not scalable -
> if some manufacturer will decide to add another block between the bridge
> and the panel there is no drm component which can be used for it.
> Using drm_panel the way I have used in toshiba bridge makes scalability
> possible,
> it will be only a matter of adding a driver for new block and making
> proper links in device tree, I see no easy way of doing it with
> drm_bridge approach.

Now drm_bridge may not cover all hardware. However drm_bridge has
already been merged to mainline so I think we need to use drm_bridge
somehow instead of using other one, and also we could extend
drm_bridge if needed. It would be definitely impossible for a new
framework to cover all hardware because there may be other hardware
not appeared yet. That is what we are doing for mainline until now.

>
>
>>
>> Using same drm_panel framework for LDVS bridge and real panel drivers
>> isn't reasonable to me as now because drm_panel framework would be for
>> real panel device even if the use of drm_panel framework looks like
>> suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver
>> using drm_bride stuff, is good enough, and that would be why
>> drm_bridge exists and why drm_encoder has drm_bridge.
>>
>> And I'm finding more generic way, how to handle LVDS bridge using
>> super node so that  LVDS bridge driver isn't embedded to connector
>> drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be
>> done at top level of Exynos drm. Once the binding is done, encoder of
>> display bus driver will have drm_bridge object of LVDS bridge driver
>> so that display bus driver can handle LVDS bridge driver.
> Could you explain what you mean by "dt binding of LVDS bridge can be
> done at top level of Exynos drm" ? How it will look like if there
> will be more bridges, one for DSI, one for HDMI, etc... What if there
> will be two
> bridges in one chain. How it will cope with video pipeline bindings?

it was just my idea so I have no implementation about it yet.

My idea is that crtc and encoder are binded at top level of Exynos drm
as is. And for bridge support, the only difference is, in case that
encoder driver has bridge, the dt binding of the encoder driver is
done once last one between encoder and bridge driver is binded. It
would mean that bridge driver can use driver model and it doesn't need
to concern about probe order issue.

For this, encoder driver with bridge, MIPI-DSI or eDP, would need to
use component interfaces specific to Exynos drm. As a result, once the
dt bindings of crtc and encoder are completed at top level, encoder
driver has its own drm_bridge for bridge, and dt binding you proposed
could be used without any change, and drm_panel could also be used
only for real lcd panel driver.

And below is a block diagram I think,

                                  DRM KMS
                   /                      |                 \
              /                           |                      \
         crtc                      encoder              connector
           |                           /     \                          |
           |                       /             \                      |
           |                      |           drm_bridge   drm_panel
           |                      |                   |                 |
           |                      |                   |                 |
        FIMD         MIPI-DSI    LVDS bridge    Panel


Thanks,
Inki Dae

>>
>> Will review your patch series soon.
> Thanks in advance.
>
> Regards
> Andrzej
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
  2014-03-12 10:08     ` Inki Dae
@ 2014-03-12 11:16       ` Tomasz Figa
  2014-03-13  7:08         ` Inki Dae
  0 siblings, 1 reply; 49+ messages in thread
From: Tomasz Figa @ 2014-03-12 11:16 UTC (permalink / raw)
  To: Inki Dae, Andrzej Hajda
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, DRI mailing list, Kyungmin Park, Rob Herring,
	Kumar Gala, Grant Likely, Marek Szyprowski

On 12.03.2014 11:08, Inki Dae wrote:
> 2014-03-07 19:00 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>> On 03/05/2014 03:56 AM, Inki Dae wrote:
>>> Hi Andrzej,
>>>
>>> Thanks for your contributions.
>>>
>>> 2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>>>> Hi,
>>>>
>>>> This patchset adds drivers and bindings to the following devices:
>>>> - Exynos DSI master,
>>>> - S6E8AA0 DSI panel,
>>>> - TC358764 DSI/LVDS bridge,
>>>> - HV070WSA-100 LVDS panel.
>>>>
>>>> It adds also display support in DTS files for the following boards:
>>>> - Exynos4210/Trats,
>>>> - Exynos4412/Trats2,
>>>> - Exynos5250/Arndale.
>>>>
>>>> Things worth mentioning:
>>>>
>>>> 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie.
>>>> the driver exposes drm_panel interface on DSI side, and interact with
>>>> panels on LVDS side using drm_panel framework. This approach seems to
>>>> me simpler and more natural than using drm_bridge.
>>> Can you give me more details about why you think better to use panel
>>> framework than using drm_bridge?  "Simpler" and "more natural" are
>>> ambiguous to me.
>> In this particular case DSI master expects on the other end
>> any device having DSI slave interface, it could be panel or bridge.
>> So it seems natural that both types of slave devices should expose
>> the same interface also  on programming level.
>> Another problem with drm_bridge is that it is not scalable -
>> if some manufacturer will decide to add another block between the bridge
>> and the panel there is no drm component which can be used for it.
>> Using drm_panel the way I have used in toshiba bridge makes scalability
>> possible,
>> it will be only a matter of adding a driver for new block and making
>> proper links in device tree, I see no easy way of doing it with
>> drm_bridge approach.
>
> Now drm_bridge may not cover all hardware. However drm_bridge has
> already been merged to mainline so I think we need to use drm_bridge
> somehow instead of using other one, and also we could extend
> drm_bridge if needed. It would be definitely impossible for a new
> framework to cover all hardware because there may be other hardware
> not appeared yet. That is what we are doing for mainline until now.
>

Well, maybe drm_bridge has been merged, but so has been drm_panel. 
Moreover, merged code is not carved in stone, if there is a better 
option that could replace it, users of it can be converted to the new 
approach and the old one can be removed.

As I believe Andrzej has demonstrated, drm_panel framework is clearly 
superior over drm_bridge and I can't think of any good reason why it 
couldn't become more generic and replace drm_bridge. Of course it can be 
renamed then to something more generic appropriately.

>>
>>
>>>
>>> Using same drm_panel framework for LDVS bridge and real panel drivers
>>> isn't reasonable to me as now because drm_panel framework would be for
>>> real panel device even if the use of drm_panel framework looks like
>>> suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver
>>> using drm_bride stuff, is good enough, and that would be why
>>> drm_bridge exists and why drm_encoder has drm_bridge.
>>>
>>> And I'm finding more generic way, how to handle LVDS bridge using
>>> super node so that  LVDS bridge driver isn't embedded to connector
>>> drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be
>>> done at top level of Exynos drm. Once the binding is done, encoder of
>>> display bus driver will have drm_bridge object of LVDS bridge driver
>>> so that display bus driver can handle LVDS bridge driver.
>> Could you explain what you mean by "dt binding of LVDS bridge can be
>> done at top level of Exynos drm" ? How it will look like if there
>> will be more bridges, one for DSI, one for HDMI, etc... What if there
>> will be two
>> bridges in one chain. How it will cope with video pipeline bindings?
>
> it was just my idea so I have no implementation about it yet.
>
> My idea is that crtc and encoder are binded at top level of Exynos drm
> as is. And for bridge support, the only difference is, in case that
> encoder driver has bridge, the dt binding of the encoder driver is
> done once last one between encoder and bridge driver is binded. It
> would mean that bridge driver can use driver model and it doesn't need
> to concern about probe order issue.
>
> For this, encoder driver with bridge, MIPI-DSI or eDP, would need to
> use component interfaces specific to Exynos drm. As a result, once the
> dt bindings of crtc and encoder are completed at top level, encoder
> driver has its own drm_bridge for bridge, and dt binding you proposed
> could be used without any change, and drm_panel could also be used
> only for real lcd panel driver.
>
> And below is a block diagram I think,
>
>                                    DRM KMS
>                     /                      |                 \
>                /                           |                      \
>           crtc                      encoder              connector
>             |                           /     \                          |
>             |                       /             \                      |
>             |                      |           drm_bridge   drm_panel
>             |                      |                   |                 |
>             |                      |                   |                 |
>          FIMD         MIPI-DSI    LVDS bridge    Panel
>

Hmm, this doesn't seem to be complete. Several bridges can be chained 
together. Also I believe "Panel" and "drm_panel" on your diagram should 
be basically the same. This leads to obvious conclusion that drm_bridge 
and drm_panel should be merged and Andrzej has shown an example (and 
IMHO good) way to do it, as drm_panel already provides a significant 
amount of existing infrastructure.

Best regards,
Tomasz

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

* Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
  2014-03-12 11:16       ` Tomasz Figa
@ 2014-03-13  7:08         ` Inki Dae
  2014-03-13 13:41           ` Andrzej Hajda
  0 siblings, 1 reply; 49+ messages in thread
From: Inki Dae @ 2014-03-13  7:08 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, DRI mailing list, Andrzej Hajda, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

2014-03-12 20:16 GMT+09:00 Tomasz Figa <t.figa@samsung.com>:
> On 12.03.2014 11:08, Inki Dae wrote:
>>
>> 2014-03-07 19:00 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>>>
>>> On 03/05/2014 03:56 AM, Inki Dae wrote:
>>>>
>>>> Hi Andrzej,
>>>>
>>>> Thanks for your contributions.
>>>>
>>>> 2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>>>>>
>>>>> Hi,
>>>>>
>>>>> This patchset adds drivers and bindings to the following devices:
>>>>> - Exynos DSI master,
>>>>> - S6E8AA0 DSI panel,
>>>>> - TC358764 DSI/LVDS bridge,
>>>>> - HV070WSA-100 LVDS panel.
>>>>>
>>>>> It adds also display support in DTS files for the following boards:
>>>>> - Exynos4210/Trats,
>>>>> - Exynos4412/Trats2,
>>>>> - Exynos5250/Arndale.
>>>>>
>>>>> Things worth mentioning:
>>>>>
>>>>> 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie.
>>>>> the driver exposes drm_panel interface on DSI side, and interact with
>>>>> panels on LVDS side using drm_panel framework. This approach seems to
>>>>> me simpler and more natural than using drm_bridge.
>>>>
>>>> Can you give me more details about why you think better to use panel
>>>> framework than using drm_bridge?  "Simpler" and "more natural" are
>>>> ambiguous to me.
>>>
>>> In this particular case DSI master expects on the other end
>>> any device having DSI slave interface, it could be panel or bridge.
>>> So it seems natural that both types of slave devices should expose
>>> the same interface also  on programming level.
>>> Another problem with drm_bridge is that it is not scalable -
>>> if some manufacturer will decide to add another block between the bridge
>>> and the panel there is no drm component which can be used for it.
>>> Using drm_panel the way I have used in toshiba bridge makes scalability
>>> possible,
>>> it will be only a matter of adding a driver for new block and making
>>> proper links in device tree, I see no easy way of doing it with
>>> drm_bridge approach.
>>
>>
>> Now drm_bridge may not cover all hardware. However drm_bridge has
>> already been merged to mainline so I think we need to use drm_bridge
>> somehow instead of using other one, and also we could extend
>> drm_bridge if needed. It would be definitely impossible for a new
>> framework to cover all hardware because there may be other hardware
>> not appeared yet. That is what we are doing for mainline until now.
>>
>
> Well, maybe drm_bridge has been merged, but so has been drm_panel. Moreover,
> merged code is not carved in stone, if there is a better option that could
> replace it, users of it can be converted to the new approach and the old one
> can be removed.
>
> As I believe Andrzej has demonstrated, drm_panel framework is clearly
> superior over drm_bridge and I can't think of any good reason why it
> couldn't become more generic and replace drm_bridge. Of course it can be
> renamed then to something more generic appropriately.
>
>
>>>
>>>
>>>>
>>>> Using same drm_panel framework for LDVS bridge and real panel drivers
>>>> isn't reasonable to me as now because drm_panel framework would be for
>>>> real panel device even if the use of drm_panel framework looks like
>>>> suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver
>>>> using drm_bride stuff, is good enough, and that would be why
>>>> drm_bridge exists and why drm_encoder has drm_bridge.
>>>>
>>>> And I'm finding more generic way, how to handle LVDS bridge using
>>>> super node so that  LVDS bridge driver isn't embedded to connector
>>>> drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be
>>>> done at top level of Exynos drm. Once the binding is done, encoder of
>>>> display bus driver will have drm_bridge object of LVDS bridge driver
>>>> so that display bus driver can handle LVDS bridge driver.
>>>
>>> Could you explain what you mean by "dt binding of LVDS bridge can be
>>> done at top level of Exynos drm" ? How it will look like if there
>>> will be more bridges, one for DSI, one for HDMI, etc... What if there
>>> will be two
>>> bridges in one chain. How it will cope with video pipeline bindings?
>>
>>
>> it was just my idea so I have no implementation about it yet.
>>
>> My idea is that crtc and encoder are binded at top level of Exynos drm
>> as is. And for bridge support, the only difference is, in case that
>> encoder driver has bridge, the dt binding of the encoder driver is
>> done once last one between encoder and bridge driver is binded. It
>> would mean that bridge driver can use driver model and it doesn't need
>> to concern about probe order issue.
>>
>> For this, encoder driver with bridge, MIPI-DSI or eDP, would need to
>> use component interfaces specific to Exynos drm. As a result, once the
>> dt bindings of crtc and encoder are completed at top level, encoder
>> driver has its own drm_bridge for bridge, and dt binding you proposed
>> could be used without any change, and drm_panel could also be used
>> only for real lcd panel driver.
>>
>> And below is a block diagram I think,
>>
>>                                    DRM KMS
>>                     /                      |                 \
>>                /                           |                      \
>>           crtc                      encoder              connector
>>             |                           /     \                          |
>>             |                       /             \                      |
>>             |                      |           drm_bridge   drm_panel
>>             |                      |                   |                 |
>>             |                      |                   |                 |
>>          FIMD         MIPI-DSI    LVDS bridge    Panel
>>
>
> Hmm, this doesn't seem to be complete. Several bridges can be chained
> together. Also I believe "Panel" and "drm_panel" on your diagram should be
> basically the same. This leads to obvious conclusion that drm_bridge and
> drm_panel should be merged and Andrzej has shown an example (and IMHO good)
> way to do it, as drm_panel already provides a significant amount of existing
> infrastructure.
>

Not opposite to using drm_panel framework. What I disagree is to
implement encoder/connector to crtc driver, and to use drm_panel
framework for bridge device.
I tend to believe that obvious fact is that crtc driver, fimd, is not
proper place that encoder and connector should be implemented. Is
there other SoC using such way? I think other SoC guys had ever
agonized about same issue.

And I'm not sure that how several bridges can be chained together so
can you show me the real case, real hardware? If there is my missing
something and we cannot really cover such hardware support with
drm_bridge framework, I think we could consider to use drm_panel
framework instead of drm_bridge. And maybe, we may need opinions from
other maintainers.

Thanks,
Inki Dae

> Best regards,
> Tomasz
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
  2014-03-13  7:08         ` Inki Dae
@ 2014-03-13 13:41           ` Andrzej Hajda
  2014-03-13 15:35             ` Inki Dae
  0 siblings, 1 reply; 49+ messages in thread
From: Andrzej Hajda @ 2014-03-13 13:41 UTC (permalink / raw)
  To: Inki Dae, Tomasz Figa
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Pawel Moll,
	Ian Campbell, DRI mailing list, Kyungmin Park, Rob Herring,
	Kumar Gala, Grant Likely, Marek Szyprowski

On 03/13/2014 08:08 AM, Inki Dae wrote:
> 2014-03-12 20:16 GMT+09:00 Tomasz Figa <t.figa@samsung.com>:
>> On 12.03.2014 11:08, Inki Dae wrote:
>>> 2014-03-07 19:00 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>>>> On 03/05/2014 03:56 AM, Inki Dae wrote:
>>>>> Hi Andrzej,
>>>>>
>>>>> Thanks for your contributions.
>>>>>
>>>>> 2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>>>>>> Hi,
>>>>>>
>>>>>> This patchset adds drivers and bindings to the following devices:
>>>>>> - Exynos DSI master,
>>>>>> - S6E8AA0 DSI panel,
>>>>>> - TC358764 DSI/LVDS bridge,
>>>>>> - HV070WSA-100 LVDS panel.
>>>>>>
>>>>>> It adds also display support in DTS files for the following boards:
>>>>>> - Exynos4210/Trats,
>>>>>> - Exynos4412/Trats2,
>>>>>> - Exynos5250/Arndale.
>>>>>>
>>>>>> Things worth mentioning:
>>>>>>
>>>>>> 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie.
>>>>>> the driver exposes drm_panel interface on DSI side, and interact with
>>>>>> panels on LVDS side using drm_panel framework. This approach seems to
>>>>>> me simpler and more natural than using drm_bridge.
>>>>> Can you give me more details about why you think better to use panel
>>>>> framework than using drm_bridge?  "Simpler" and "more natural" are
>>>>> ambiguous to me.
>>>> In this particular case DSI master expects on the other end
>>>> any device having DSI slave interface, it could be panel or bridge.
>>>> So it seems natural that both types of slave devices should expose
>>>> the same interface also  on programming level.
>>>> Another problem with drm_bridge is that it is not scalable -
>>>> if some manufacturer will decide to add another block between the bridge
>>>> and the panel there is no drm component which can be used for it.
>>>> Using drm_panel the way I have used in toshiba bridge makes scalability
>>>> possible,
>>>> it will be only a matter of adding a driver for new block and making
>>>> proper links in device tree, I see no easy way of doing it with
>>>> drm_bridge approach.
>>>
>>> Now drm_bridge may not cover all hardware. However drm_bridge has
>>> already been merged to mainline so I think we need to use drm_bridge
>>> somehow instead of using other one, and also we could extend
>>> drm_bridge if needed. It would be definitely impossible for a new
>>> framework to cover all hardware because there may be other hardware
>>> not appeared yet. That is what we are doing for mainline until now.
>>>
>> Well, maybe drm_bridge has been merged, but so has been drm_panel. Moreover,
>> merged code is not carved in stone, if there is a better option that could
>> replace it, users of it can be converted to the new approach and the old one
>> can be removed.
>>
>> As I believe Andrzej has demonstrated, drm_panel framework is clearly
>> superior over drm_bridge and I can't think of any good reason why it
>> couldn't become more generic and replace drm_bridge. Of course it can be
>> renamed then to something more generic appropriately.
>>
>>
>>>>
>>>>> Using same drm_panel framework for LDVS bridge and real panel drivers
>>>>> isn't reasonable to me as now because drm_panel framework would be for
>>>>> real panel device even if the use of drm_panel framework looks like
>>>>> suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver
>>>>> using drm_bride stuff, is good enough, and that would be why
>>>>> drm_bridge exists and why drm_encoder has drm_bridge.
>>>>>
>>>>> And I'm finding more generic way, how to handle LVDS bridge using
>>>>> super node so that  LVDS bridge driver isn't embedded to connector
>>>>> drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be
>>>>> done at top level of Exynos drm. Once the binding is done, encoder of
>>>>> display bus driver will have drm_bridge object of LVDS bridge driver
>>>>> so that display bus driver can handle LVDS bridge driver.
>>>> Could you explain what you mean by "dt binding of LVDS bridge can be
>>>> done at top level of Exynos drm" ? How it will look like if there
>>>> will be more bridges, one for DSI, one for HDMI, etc... What if there
>>>> will be two
>>>> bridges in one chain. How it will cope with video pipeline bindings?
>>>
>>> it was just my idea so I have no implementation about it yet.
>>>
>>> My idea is that crtc and encoder are binded at top level of Exynos drm
>>> as is. And for bridge support, the only difference is, in case that
>>> encoder driver has bridge, the dt binding of the encoder driver is
>>> done once last one between encoder and bridge driver is binded. It
>>> would mean that bridge driver can use driver model and it doesn't need
>>> to concern about probe order issue.
>>>
>>> For this, encoder driver with bridge, MIPI-DSI or eDP, would need to
>>> use component interfaces specific to Exynos drm. As a result, once the
>>> dt bindings of crtc and encoder are completed at top level, encoder
>>> driver has its own drm_bridge for bridge, and dt binding you proposed
>>> could be used without any change, and drm_panel could also be used
>>> only for real lcd panel driver.
>>>
>>> And below is a block diagram I think,
>>>
>>>                                    DRM KMS
>>>                     /                      |                 \
>>>                /                           |                      \
>>>           crtc                      encoder              connector
>>>             |                           /     \                          |
>>>             |                       /             \                      |
>>>             |                      |           drm_bridge   drm_panel
>>>             |                      |                   |                 |
>>>             |                      |                   |                 |
>>>          FIMD         MIPI-DSI    LVDS bridge    Panel
>>>
>> Hmm, this doesn't seem to be complete. Several bridges can be chained
>> together. Also I believe "Panel" and "drm_panel" on your diagram should be
>> basically the same. This leads to obvious conclusion that drm_bridge and
>> drm_panel should be merged and Andrzej has shown an example (and IMHO good)
>> way to do it, as drm_panel already provides a significant amount of existing
>> infrastructure.
>>
> Not opposite to using drm_panel framework. What I disagree is to
> implement encoder/connector to crtc driver, and to use drm_panel
> framework for bridge device.
> I tend to believe that obvious fact is that crtc driver, fimd, is not
> proper place that encoder and connector should be implemented. Is
> there other SoC using such way? I think other SoC guys had ever
> agonized about same issue.
Quick look at some mobile drm drivers:
1. tegra - in rgb pseudo-driver encoder/connector is bound to crtc device,
    it is separate file but the same device driver.
2. imx - crtc and encoder are separated, but parallel driver is a pure
    virtual device driver, no hw associated with it.
3. shmob - crtc, encoder and connector are in the same device.
4. omap - all drm components are created in omap_drv, physical devices
    are bound to them using internal framework.

I prefer to avoid creating virtual devices, I think the simpler solution
for parallel output for now could be something like in tegra.

Generally I tend to omap solution but instead of creating internal
framework use what we have already, ie drm_panel.

Btw I do not see drm_panel as sth strange in this context,
for example in the chain:
FIMD --> DSIM --> DSI/LVDS --> Panel
any device in the chain sees device on the right side of the link as a
panel. Ie.
FIMD sees RGB panel,
DSIM sees DSI panel,
bridge sees LVDS panel.

>
> And I'm not sure that how several bridges can be chained together so
> can you show me the real case, real hardware? If there is my missing
> something and we cannot really cover such hardware support with
> drm_bridge framework, I think we could consider to use drm_panel
> framework instead of drm_bridge. And maybe, we may need opinions from
> other maintainers.

Real cases I have showed in another thread:
FIMD --> MIE --> DSI --> DSI/LVDS --> Panel

Five hw devices in the chain, we are not able to map them
to 3+1 drm components 1:1, something should be squashed.
Probably squashing MIE with FIMD would be a some solution.
But in place of MIE there can be also mDNIe --> FIMDlite.
So we need another sub-framework or bunch of conditionals
to handle it.
On the other side drm_panel would solve these problems
in generic way.

Regards
Andrzej

>
> Thanks,
> Inki Dae
>
>> Best regards,
>> Tomasz
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
  2014-03-13 13:41           ` Andrzej Hajda
@ 2014-03-13 15:35             ` Inki Dae
  0 siblings, 0 replies; 49+ messages in thread
From: Inki Dae @ 2014-03-13 15:35 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Tomasz Figa, Mark Rutland, devicetree, linux-samsung-soc,
	Pawel Moll, Ian Campbell, DRI mailing list, Kyungmin Park,
	Rob Herring, Kumar Gala, Grant Likely, Marek Szyprowski

2014-03-13 22:41 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
> On 03/13/2014 08:08 AM, Inki Dae wrote:
>> 2014-03-12 20:16 GMT+09:00 Tomasz Figa <t.figa@samsung.com>:
>>> On 12.03.2014 11:08, Inki Dae wrote:
>>>> 2014-03-07 19:00 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>>>>> On 03/05/2014 03:56 AM, Inki Dae wrote:
>>>>>> Hi Andrzej,
>>>>>>
>>>>>> Thanks for your contributions.
>>>>>>
>>>>>> 2014-02-12 20:31 GMT+09:00 Andrzej Hajda <a.hajda@samsung.com>:
>>>>>>> Hi,
>>>>>>>
>>>>>>> This patchset adds drivers and bindings to the following devices:
>>>>>>> - Exynos DSI master,
>>>>>>> - S6E8AA0 DSI panel,
>>>>>>> - TC358764 DSI/LVDS bridge,
>>>>>>> - HV070WSA-100 LVDS panel.
>>>>>>>
>>>>>>> It adds also display support in DTS files for the following boards:
>>>>>>> - Exynos4210/Trats,
>>>>>>> - Exynos4412/Trats2,
>>>>>>> - Exynos5250/Arndale.
>>>>>>>
>>>>>>> Things worth mentioning:
>>>>>>>
>>>>>>> 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie.
>>>>>>> the driver exposes drm_panel interface on DSI side, and interact with
>>>>>>> panels on LVDS side using drm_panel framework. This approach seems to
>>>>>>> me simpler and more natural than using drm_bridge.
>>>>>> Can you give me more details about why you think better to use panel
>>>>>> framework than using drm_bridge?  "Simpler" and "more natural" are
>>>>>> ambiguous to me.
>>>>> In this particular case DSI master expects on the other end
>>>>> any device having DSI slave interface, it could be panel or bridge.
>>>>> So it seems natural that both types of slave devices should expose
>>>>> the same interface also  on programming level.
>>>>> Another problem with drm_bridge is that it is not scalable -
>>>>> if some manufacturer will decide to add another block between the bridge
>>>>> and the panel there is no drm component which can be used for it.
>>>>> Using drm_panel the way I have used in toshiba bridge makes scalability
>>>>> possible,
>>>>> it will be only a matter of adding a driver for new block and making
>>>>> proper links in device tree, I see no easy way of doing it with
>>>>> drm_bridge approach.
>>>>
>>>> Now drm_bridge may not cover all hardware. However drm_bridge has
>>>> already been merged to mainline so I think we need to use drm_bridge
>>>> somehow instead of using other one, and also we could extend
>>>> drm_bridge if needed. It would be definitely impossible for a new
>>>> framework to cover all hardware because there may be other hardware
>>>> not appeared yet. That is what we are doing for mainline until now.
>>>>
>>> Well, maybe drm_bridge has been merged, but so has been drm_panel. Moreover,
>>> merged code is not carved in stone, if there is a better option that could
>>> replace it, users of it can be converted to the new approach and the old one
>>> can be removed.
>>>
>>> As I believe Andrzej has demonstrated, drm_panel framework is clearly
>>> superior over drm_bridge and I can't think of any good reason why it
>>> couldn't become more generic and replace drm_bridge. Of course it can be
>>> renamed then to something more generic appropriately.
>>>
>>>
>>>>>
>>>>>> Using same drm_panel framework for LDVS bridge and real panel drivers
>>>>>> isn't reasonable to me as now because drm_panel framework would be for
>>>>>> real panel device even if the use of drm_panel framework looks like
>>>>>> suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver
>>>>>> using drm_bride stuff, is good enough, and that would be why
>>>>>> drm_bridge exists and why drm_encoder has drm_bridge.
>>>>>>
>>>>>> And I'm finding more generic way, how to handle LVDS bridge using
>>>>>> super node so that  LVDS bridge driver isn't embedded to connector
>>>>>> drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be
>>>>>> done at top level of Exynos drm. Once the binding is done, encoder of
>>>>>> display bus driver will have drm_bridge object of LVDS bridge driver
>>>>>> so that display bus driver can handle LVDS bridge driver.
>>>>> Could you explain what you mean by "dt binding of LVDS bridge can be
>>>>> done at top level of Exynos drm" ? How it will look like if there
>>>>> will be more bridges, one for DSI, one for HDMI, etc... What if there
>>>>> will be two
>>>>> bridges in one chain. How it will cope with video pipeline bindings?
>>>>
>>>> it was just my idea so I have no implementation about it yet.
>>>>
>>>> My idea is that crtc and encoder are binded at top level of Exynos drm
>>>> as is. And for bridge support, the only difference is, in case that
>>>> encoder driver has bridge, the dt binding of the encoder driver is
>>>> done once last one between encoder and bridge driver is binded. It
>>>> would mean that bridge driver can use driver model and it doesn't need
>>>> to concern about probe order issue.
>>>>
>>>> For this, encoder driver with bridge, MIPI-DSI or eDP, would need to
>>>> use component interfaces specific to Exynos drm. As a result, once the
>>>> dt bindings of crtc and encoder are completed at top level, encoder
>>>> driver has its own drm_bridge for bridge, and dt binding you proposed
>>>> could be used without any change, and drm_panel could also be used
>>>> only for real lcd panel driver.
>>>>
>>>> And below is a block diagram I think,
>>>>
>>>>                                    DRM KMS
>>>>                     /                      |                 \
>>>>                /                           |                      \
>>>>           crtc                      encoder              connector
>>>>             |                           /     \                          |
>>>>             |                       /             \                      |
>>>>             |                      |           drm_bridge   drm_panel
>>>>             |                      |                   |                 |
>>>>             |                      |                   |                 |
>>>>          FIMD         MIPI-DSI    LVDS bridge    Panel
>>>>
>>> Hmm, this doesn't seem to be complete. Several bridges can be chained
>>> together. Also I believe "Panel" and "drm_panel" on your diagram should be
>>> basically the same. This leads to obvious conclusion that drm_bridge and
>>> drm_panel should be merged and Andrzej has shown an example (and IMHO good)
>>> way to do it, as drm_panel already provides a significant amount of existing
>>> infrastructure.
>>>
>> Not opposite to using drm_panel framework. What I disagree is to
>> implement encoder/connector to crtc driver, and to use drm_panel
>> framework for bridge device.
>> I tend to believe that obvious fact is that crtc driver, fimd, is not
>> proper place that encoder and connector should be implemented. Is
>> there other SoC using such way? I think other SoC guys had ever
>> agonized about same issue.
> Quick look at some mobile drm drivers:
> 1. tegra - in rgb pseudo-driver encoder/connector is bound to crtc device,
>     it is separate file but the same device driver.
> 2. imx - crtc and encoder are separated, but parallel driver is a pure
>     virtual device driver, no hw associated with it.
> 3. shmob - crtc, encoder and connector are in the same device.
> 4. omap - all drm components are created in omap_drv, physical devices
>     are bound to them using internal framework.
>
> I prefer to avoid creating virtual devices, I think the simpler solution
> for parallel output for now could be something like in tegra.
>
> Generally I tend to omap solution but instead of creating internal
> framework use what we have already, ie drm_panel.

Doesn't it better to use internal framework like omap did ? Or, I
think it's better to change drm_panel to more generic name if you want
to use drm_panel so that drm_panel can be used commonly for other
hardware block devices. It's curious to control all hardware blocks
and real panel device using drm_panel.

>
> Btw I do not see drm_panel as sth strange in this context,
> for example in the chain:
> FIMD --> DSIM --> DSI/LVDS --> Panel
> any device in the chain sees device on the right side of the link as a
> panel. Ie.
> FIMD sees RGB panel,
> DSIM sees DSI panel,
> bridge sees LVDS panel.
>
>>
>> And I'm not sure that how several bridges can be chained together so
>> can you show me the real case, real hardware? If there is my missing
>> something and we cannot really cover such hardware support with
>> drm_bridge framework, I think we could consider to use drm_panel
>> framework instead of drm_bridge. And maybe, we may need opinions from
>> other maintainers.
>
> Real cases I have showed in another thread:
> FIMD --> MIE --> DSI --> DSI/LVDS --> Panel

I didn't see these hardware blocks are called bridge. :) Yes, right,
and also these can be chained together in more various ways.

>
> Five hw devices in the chain, we are not able to map them
> to 3+1 drm components 1:1, something should be squashed.
> Probably squashing MIE with FIMD would be a some solution.
> But in place of MIE there can be also mDNIe --> FIMDlite.
> So we need another sub-framework or bunch of conditionals
> to handle it.
> On the other side drm_panel would solve these problems
> in generic way.
>

Ok, but for more clear I think we would need to look into how other
SoC guys are handling similar hardware blocks in drm world.

Thanks,
Inki Dae

> Regards
> Andrzej
>
>>
>> Thanks,
>> Inki Dae
>>
>>> Best regards,
>>> Tomasz
>>>
>>> _______________________________________________
>>> 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] 49+ messages in thread

end of thread, other threads:[~2014-03-13 15:35 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-12 11:31 [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 01/21] drm_mipi_dsi: add flags to DSI messages Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 02/21] drm/exynos: delay fbdev initialization until an output is connected Andrzej Hajda
2014-02-12 12:03   ` Sachin Kamat
2014-02-12 11:31 ` [RFC PATCH v2 03/21] exynos/dsim: add DT bindings Andrzej Hajda
2014-03-05  5:56   ` Inki Dae
2014-03-07 10:54     ` Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 04/21] drm/exynos: add DSIM driver Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 05/21] panel/s6e8aa0: add DT bindings Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 06/21] drm/panel: add S6E8AA0 driver Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 07/21] panel/tc358764: add DT bindings Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 10/21] panel/hv070wsa-100: " Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 11/21] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 13/21] ARM: dts: exynos4210-trats: add panel node Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 14/21] ARM: dts: exynos4412-trats2: " Andrzej Hajda
2014-02-28 13:33   ` Tomi Valkeinen
2014-03-04 12:07     ` Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 15/21] ARM: dts: exynos5250: add mipi-phy node Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 16/21] ARM: dts: exynos5250: add display power domain node Andrzej Hajda
2014-02-12 11:51   ` Sachin Kamat
2014-02-12 11:59     ` Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 17/21] ARM: dts: exynos5250: add DSI node Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 18/21] ARM: dts: exynos5250-arndale: add display regulators Andrzej Hajda
2014-02-12 11:31 ` [RFC PATCH v2 19/21] ARM: dts: exynos5250-arndale: add dsi and panel nodes Andrzej Hajda
2014-02-28 13:31   ` Tomi Valkeinen
2014-02-28 13:39     ` Tomi Valkeinen
2014-03-04 12:00       ` Andrzej Hajda
2014-03-04 12:40         ` Tomi Valkeinen
2014-03-05 12:06         ` Inki Dae
2014-03-07 12:22           ` Andrzej Hajda
2014-03-07 12:32             ` Tomi Valkeinen
2014-03-07 13:07               ` Andrzej Hajda
2014-03-07 13:28                 ` Tomi Valkeinen
2014-03-07 14:17                   ` Andrzej Hajda
2014-03-07 14:36                     ` Tomi Valkeinen
     [not found] ` <1392204688-4591-1-git-send-email-a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2014-02-12 11:31   ` [RFC PATCH v2 08/21] drm/panel: add TC358764 driver Andrzej Hajda
2014-03-05  6:46     ` Inki Dae
2014-03-07 10:44       ` Andrzej Hajda
2014-02-12 11:31   ` [RFC PATCH v2 09/21] panel/simple: add video interface DT bindings Andrzej Hajda
2014-02-12 11:31   ` [RFC PATCH v2 12/21] ARM: dts: exynos4: add MIPI DSI Master node Andrzej Hajda
2014-02-12 11:31   ` [RFC PATCH v2 20/21] ARM: dts: exynos4210-trats: enable exynos/fimd node Andrzej Hajda
2014-02-12 11:31   ` [RFC PATCH v2 21/21] ARM: dts: exynos4412-trats2: " Andrzej Hajda
2014-03-05  2:56 ` [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards Inki Dae
2014-03-07 10:00   ` Andrzej Hajda
2014-03-12 10:08     ` Inki Dae
2014-03-12 11:16       ` Tomasz Figa
2014-03-13  7:08         ` Inki Dae
2014-03-13 13:41           ` Andrzej Hajda
2014-03-13 15:35             ` Inki Dae

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.