linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform
@ 2013-08-15  8:01 Alison Wang
  2013-08-15  8:01 ` [PATCH v3 1/5] ARM: dts: vf610: Add DCU and TCON nodes Alison Wang
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Alison Wang @ 2013-08-15  8:01 UTC (permalink / raw)
  To: linux-arm-kernel

This series contain DCU framebuffer driver for Freescale Vybrid VF610 platform.

The Display Controller Unit (DCU) module is a system master that
fetches graphics stored in internal or external memory and displays
them on a TFT LCD panel. A wide range of panel sizes is supported
and the timing of the interface signals is highly configurable.
Graphics are read directly from memory and then blended in real-time,
which allows for dynamic content creation with minimal CPU intervention.

The features:
(1) Full RGB888 output to TFT LCD panel.
(2) For the current LCD panel, WQVGA "480x272" is tested.
(3) Blending of each pixel using up to 4 source layers dependent on size of panel.
(4) Each graphic layer can be placed with one pixel resolution in either axis.
(5) Each graphic layer support RGB565 and RGB888 direct colors without alpha channel
and BGRA8888 direct colors with an alpha channel.
(6) Each graphic layer support alpha blending with 8-bit resolution.

Changes in v3:
- Correct DCU_MODE_BLEND_ITER macro definition.
- Remove hardcode panel description in the driver. Use the videomode helpers to get the relevant data from devicetree.
- Correct the wrong indentation.
- Use dev_* for printing messages in drivers.
- Change calc_div_ratio() to fsl_dcu_calc_div(), and rewrite this function.
- Use devm_request_irq() instead of request_irq().
- Drop useless code.
- Increase the layers number to the maximum 6.
- Use dma_alloc_writecombine() instead of dma_alloc_coherent().
- Use runtime PM.

Changes in v2:
- Add a document for DCU framebuffer driver under Documentation/devicetree/bindings/fb/.

----------------------------------------------------------------
Alison Wang (5):
      ARM: dts: vf610: Add DCU and TCON nodes
      ARM: dts: vf610-twr: Enable DCU and TCON devices
      ARM: clk: vf610: Add DCU and TCON clock support
      fb: Add DCU framebuffer driver for Vybrid VF610 platform
      Documentation: DT: Add DCU framebuffer driver

 Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt |   67 +++++
 arch/arm/boot/dts/vf610-twr.dts                     |   32 +++
 arch/arm/boot/dts/vf610.dtsi                        |   19 +-
 arch/arm/mach-imx/clk-vf610.c                       |    5 +
 drivers/video/Kconfig                               |   10 +
 drivers/video/Makefile                              |    1 +
 drivers/video/fsl-dcu-fb.c                          | 1095 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/vf610-clock.h             |    3 +-
 8 files changed, 1230 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt
 create mode 100644 drivers/video/fsl-dcu-fb.c

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

* [PATCH v3 1/5] ARM: dts: vf610: Add DCU and TCON nodes
  2013-08-15  8:01 [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
@ 2013-08-15  8:01 ` Alison Wang
  2013-08-15  8:01 ` [PATCH v3 2/5] ARM: dts: vf610-twr: Enable DCU and TCON devices Alison Wang
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Alison Wang @ 2013-08-15  8:01 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds DCU and TCON nodes in SoC level DTS for Freescale Vybrid VF610.
It also removes useless pin for DCU0 pinctrl.

Signed-off-by: Alison Wang <b18965@freescale.com>
---
Changes in v3: None
Changes in v2: None

 arch/arm/boot/dts/vf610.dtsi | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 67d929c..145e1f4 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -140,6 +140,14 @@
 				clock-names = "pit";
 			};
 
+			tcon0: tcon at 4003d000 {
+				compatible = "fsl,vf610-tcon";
+				reg = <0x4003d000 0x1000>;
+				clocks = <&clks VF610_CLK_TCON0>;
+				clock-names = "tcon";
+				status = "disabled";
+			};
+
 			wdog at 4003e000 {
 				compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
 				reg = <0x4003e000 0x1000>;
@@ -169,7 +177,6 @@
 				dcu0 {
 					pinctrl_dcu0_1: dcu0grp_1 {
 						fsl,pins = <
-						VF610_PAD_PTB8__GPIO_30		0x42
 						VF610_PAD_PTE0__DCU0_HSYNC	0x42
 						VF610_PAD_PTE1__DCU0_VSYNC	0x42
 						VF610_PAD_PTE2__DCU0_PCLK	0x42
@@ -395,6 +402,16 @@
 				reg = <0x40050000 0x1000>;
 			};
 
+			dcu0: dcu at 40058000 {
+				compatible = "fsl,vf610-dcu";
+				reg = <0x40058000 0x1200>;
+				interrupts = <0 30 0x04>;
+				clocks = <&clks VF610_CLK_DCU0>;
+				clock-names = "dcu";
+				tcon-controller = <&tcon0>;
+				status = "disabled";
+			};
+
 			i2c0: i2c at 40066000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-- 
1.8.0

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

* [PATCH v3 2/5] ARM: dts: vf610-twr: Enable DCU and TCON devices
  2013-08-15  8:01 [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
  2013-08-15  8:01 ` [PATCH v3 1/5] ARM: dts: vf610: Add DCU and TCON nodes Alison Wang
@ 2013-08-15  8:01 ` Alison Wang
  2013-08-15  8:01 ` [PATCH v3 3/5] ARM: clk: vf610: Add DCU and TCON clock support Alison Wang
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Alison Wang @ 2013-08-15  8:01 UTC (permalink / raw)
  To: linux-arm-kernel

This patch enables DCU and TCON devices for Vybrid VF610 TOWER board.

Signed-off-by: Alison Wang <b18965@freescale.com>
---
Changes in v3: Add panel description in devicetree.
Changes in v2: None

 arch/arm/boot/dts/vf610-twr.dts | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index b3905f5..82c03fe 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -36,6 +36,34 @@
 
 };
 
+&dcu0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_dcu0_1>;
+	display = <&display>;
+	status = "okay";
+
+	display: display at 0 {
+		bits-per-pixel = <24>;
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: nl4827hc19 {
+				clock-frequency = <10870000>;
+				hactive = <480>;
+				vactive = <272>;
+				hback-porch = <2>;
+				hfront-porch = <2>;
+				vback-porch = <1>;
+				vfront-porch = <1>;
+				hsync-len = <41>;
+				vsync-len = <2>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
+};
+
 &fec0 {
 	phy-mode = "rmii";
 	pinctrl-names = "default";
@@ -50,6 +78,10 @@
 	status = "okay";
 };
 
+&tcon0 {
+	status = "okay";
+};
+
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1_1>;
-- 
1.8.0

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

* [PATCH v3 3/5] ARM: clk: vf610: Add DCU and TCON clock support
  2013-08-15  8:01 [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
  2013-08-15  8:01 ` [PATCH v3 1/5] ARM: dts: vf610: Add DCU and TCON nodes Alison Wang
  2013-08-15  8:01 ` [PATCH v3 2/5] ARM: dts: vf610-twr: Enable DCU and TCON devices Alison Wang
@ 2013-08-15  8:01 ` Alison Wang
  2013-08-15  8:01 ` [PATCH v3 4/5] fb: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Alison Wang @ 2013-08-15  8:01 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds DCU and TCON clock support for Vybrid VF610 platform.

Signed-off-by: Alison Wang <b18965@freescale.com>
---
Changes in v3: None
Changes in v2: None

 arch/arm/mach-imx/clk-vf610.c           | 5 +++++
 include/dt-bindings/clock/vf610-clock.h | 3 ++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
index b169a39..689d3da 100644
--- a/arch/arm/mach-imx/clk-vf610.c
+++ b/arch/arm/mach-imx/clk-vf610.c
@@ -247,6 +247,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 	clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
 	clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8));
 
+	clk[VF610_CLK_TCON0] = imx_clk_gate2("tcon0", "platform_bus", CCM_CCGR1, CCM_CCGRx_CGn(13));
+
 	clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
 	clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30);
 	clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", CCM_CSCDR2, 24, 4);
@@ -313,6 +315,9 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 	clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]);
 	clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]);
 
+	clk_set_parent(clk[VF610_CLK_DCU0_SEL], clk[VF610_CLK_PLL1_PFD2]);
+	clk_set_rate(clk[VF610_CLK_DCU0_DIV], 113200000);
+
 	/* Add the clocks to provider list */
 	clk_data.clks = clk;
 	clk_data.clk_num = ARRAY_SIZE(clk);
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index 4aa2b48..4ccf563 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -160,6 +160,7 @@
 #define VF610_CLK_GPU2D			147
 #define VF610_CLK_ENET0			148
 #define VF610_CLK_ENET1			149
-#define VF610_CLK_END			150
+#define VF610_CLK_TCON0			150
+#define VF610_CLK_END			151
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
-- 
1.8.0

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

* [PATCH v3 4/5] fb: Add DCU framebuffer driver for Vybrid VF610 platform
  2013-08-15  8:01 [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
                   ` (2 preceding siblings ...)
  2013-08-15  8:01 ` [PATCH v3 3/5] ARM: clk: vf610: Add DCU and TCON clock support Alison Wang
@ 2013-08-15  8:01 ` Alison Wang
  2013-08-15  8:01 ` [PATCH v3 5/5] Documentation: DT: Add DCU framebuffer driver Alison Wang
  2013-08-26  9:51 ` [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Wang Huan-B18965
  5 siblings, 0 replies; 12+ messages in thread
From: Alison Wang @ 2013-08-15  8:01 UTC (permalink / raw)
  To: linux-arm-kernel

The Display Controller Unit (DCU) module is a system master that
fetches graphics stored in internal or external memory and displays
them on a TFT LCD panel. A wide range of panel sizes is supported
and the timing of the interface signals is highly configurable.
Graphics are read directly from memory and then blended in real-time,
which allows for dynamic content creation with minimal CPU intervention.

The features:

(1) Full RGB888 output to TFT LCD panel.
(2) For the current LCD panel, WQVGA "480x272" is supported.
(3) Blending of each pixel using up to 4 source layers dependent on size of panel.
(4) Each graphic layer can be placed with one pixel resolution in either axis.
(5) Each graphic layer support RGB565 and RGB888 direct colors without alpha channel
and BGRA8888 direct colors with an alpha channel.
(6) Each graphic layer support alpha blending with 8-bit resolution.

This driver has been tested on Vybrid VF610TWR board.

Signed-off-by: Alison Wang <b18965@freescale.com>
---
Changes in v3:
- Correct DCU_MODE_BLEND_ITER macro definition.
- Remove hardcode panel description in the driver. Use the videomode helpers to get the relevant data from devicetree.
- Correct the wrong indentation.
- Use dev_* for printing messages in drivers.
- Change calc_div_ratio() to fsl_dcu_calc_div(), and rewrite this function.
- Use devm_request_irq() instead of request_irq().
- Drop useless code.
- Increase the layers number to the maximum 6.
- Use dma_alloc_writecombine() instead of dma_alloc_coherent().
- Use runtime PM.
Changes in v2: None

 drivers/video/Kconfig      |   10 +
 drivers/video/Makefile     |    1 +
 drivers/video/fsl-dcu-fb.c | 1095 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1106 insertions(+)
 create mode 100644 drivers/video/fsl-dcu-fb.c

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index c4d5b44..59a6b86 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1978,6 +1978,16 @@ config FB_FSL_DIU
 	---help---
 	  Framebuffer driver for the Freescale SoC DIU
 
+config FB_FSL_DCU
+	tristate "Freescale DCU framebuffer support"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VIDEOMODE_HELPERS
+	---help---
+	  Framebuffer driver for the Freescale SoC DCU
+
 config FB_W100
 	tristate "W100 frame buffer support"
 	depends on FB && ARCH_PXA
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index e8bae8d..3707a7d 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -129,6 +129,7 @@ obj-$(CONFIG_FB_IMX)              += imxfb.o
 obj-$(CONFIG_FB_S3C)		  += s3c-fb.o
 obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
 obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
+obj-$(CONFIG_FB_FSL_DCU)	  += fsl-dcu-fb.o
 obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
 obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
 obj-$(CONFIG_FB_PS3)		  += ps3fb.o
diff --git a/drivers/video/fsl-dcu-fb.c b/drivers/video/fsl-dcu-fb.c
new file mode 100644
index 0000000..6b45357
--- /dev/null
+++ b/drivers/video/fsl-dcu-fb.c
@@ -0,0 +1,1095 @@
+/*
+ * Copyright 2012-2013 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU framebuffer device driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/clk.h>
+#include <linux/of_platform.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
+#include <linux/pm_runtime.h>
+
+#define DRIVER_NAME			"fsl-dcu-fb"
+
+#define DCU_DCU_MODE			0x0010
+#define DCU_MODE_BLEND_ITER(x)		((x) << 20)
+#define DCU_MODE_RASTER_EN		(1 << 14)
+#define DCU_MODE_DCU_MODE(x)		(x)
+#define DCU_MODE_DCU_MODE_MASK		0x03
+#define DCU_MODE_OFF			0
+#define DCU_MODE_NORMAL			1
+#define DCU_MODE_TEST			2
+#define DCU_MODE_COLORBAR		3
+
+#define DCU_BGND			0x0014
+#define DCU_BGND_R(x)			((x) << 16)
+#define DCU_BGND_G(x)			((x) << 8)
+#define DCU_BGND_B(x)			(x)
+
+#define DCU_DISP_SIZE			0x0018
+#define DCU_DISP_SIZE_DELTA_Y(x)	((x) << 16)
+#define DCU_DISP_SIZE_DELTA_X(x)	(x)
+
+#define DCU_HSYN_PARA			0x001c
+#define DCU_HSYN_PARA_BP(x)		((x) << 22)
+#define DCU_HSYN_PARA_PW(x)		((x) << 11)
+#define DCU_HSYN_PARA_FP(x)		(x)
+
+#define DCU_VSYN_PARA			0x0020
+#define DCU_VSYN_PARA_BP(x)		((x) << 22)
+#define DCU_VSYN_PARA_PW(x)		((x) << 11)
+#define DCU_VSYN_PARA_FP(x)		(x)
+
+#define DCU_SYN_POL			0x0024
+#define DCU_SYN_POL_INV_PXCK_FALL	(0 << 6)
+#define DCU_SYN_POL_NEG_REMAIN		(0 << 5)
+#define DCU_SYN_POL_INV_VS_LOW		(1 << 1)
+#define DCU_SYN_POL_INV_HS_LOW		(1)
+
+#define DCU_THRESHOLD			0x0028
+#define DCU_THRESHOLD_LS_BF_VS(x)	((x) << 16)
+#define DCU_THRESHOLD_OUT_BUF_HIGH(x)	((x) << 8)
+#define DCU_THRESHOLD_OUT_BUF_LOW(x)	(x)
+
+#define DCU_INT_STATUS			0x002C
+#define DCU_INT_STATUS_UNDRUN		(1 << 1)
+
+#define DCU_INT_MASK			0x0030
+#define DCU_INT_MASK_UNDRUN		(1 << 1)
+
+#define DCU_DIV_RATIO			0x0054
+
+#define DCU_UPDATE_MODE			0x00cc
+#define DCU_UPDATE_MODE_MODE		(1 << 31)
+#define DCU_UPDATE_MODE_READREG		(1 << 30)
+
+#define DCU_CTRLDESCLN_1(x)		(0x200 + (x) * 0x40)
+#define DCU_CTRLDESCLN_1_HEIGHT(x)	((x) << 16)
+#define DCU_CTRLDESCLN_1_WIDTH(x)	(x)
+
+#define DCU_CTRLDESCLN_2(x)		(0x204 + (x) * 0x40)
+#define DCU_CTRLDESCLN_2_POSY(x)	((x) << 16)
+#define DCU_CTRLDESCLN_2_POSX(x)	(x)
+
+#define DCU_CTRLDESCLN_3(x)		(0x208 + (x) * 0x40)
+
+#define DCU_CTRLDESCLN_4(x)		(0x20c + (x) * 0x40)
+#define DCU_CTRLDESCLN_4_EN		(1 << 31)
+#define DCU_CTRLDESCLN_4_TILE_EN	(1 << 30)
+#define DCU_CTRLDESCLN_4_DATA_SEL_CLUT	(1 << 29)
+#define DCU_CTRLDESCLN_4_SAFETY_EN	(1 << 28)
+#define DCU_CTRLDESCLN_4_TRANS(x)	((x) << 20)
+#define DCU_CTRLDESCLN_4_BPP(x)		((x) << 16)
+#define DCU_CTRLDESCLN_4_RLE_EN		(1 << 15)
+#define DCU_CTRLDESCLN_4_LUOFFS(x)	((x) << 4)
+#define DCU_CTRLDESCLN_4_BB_ON		(1 << 2)
+#define DCU_CTRLDESCLN_4_AB(x)		(x)
+
+#define DCU_CTRLDESCLN_5(x)		(0x210 + (x) * 0x40)
+#define DCU_CTRLDESCLN_5_CKMAX_R(x)	((x) << 16)
+#define DCU_CTRLDESCLN_5_CKMAX_G(x)	((x) << 8)
+#define DCU_CTRLDESCLN_5_CKMAX_B(x)	(x)
+
+#define DCU_CTRLDESCLN_6(x)		(0x214 + (x) * 0x40)
+#define DCU_CTRLDESCLN_6_CKMIN_R(x)	((x) << 16)
+#define DCU_CTRLDESCLN_6_CKMIN_G(x)	((x) << 8)
+#define DCU_CTRLDESCLN_6_CKMIN_B(x)	(x)
+
+#define DCU_CTRLDESCLN_7(x)		(0x218 + (x) * 0x40)
+#define DCU_CTRLDESCLN_7_TILE_VER(x)	((x) << 16)
+#define DCU_CTRLDESCLN_7_TILE_HOR(x)	(x)
+
+#define DCU_CTRLDESCLN_8(x)		(0x21c + (x) * 0x40)
+#define DCU_CTRLDESCLN_8_FG_FCOLOR(x)	(x)
+
+#define DCU_CTRLDESCLN_9(x)		(0x220 + (x) * 0x40)
+#define DCU_CTRLDESCLN_9_BG_BCOLOR(x)	(x)
+
+#define DCU_TOTAL_LAYER_NUM		64
+#define DCU_LAYER_NUM_MAX		6
+
+#define BPP_16_RGB565			4
+#define BPP_24_RGB888			5
+#define BPP_32_ARGB8888			6
+
+#define TCON_CTRL1			0x0000
+#define TCON_BYPASS_ENABLE		(1 << 29)
+
+#define MFB_SET_ALPHA		_IOW('M', 0, __u8)
+#define MFB_GET_ALPHA		_IOR('M', 0, __u8)
+#define MFB_SET_LAYER		_IOW('M', 4, struct layer_display_offset)
+#define MFB_GET_LAYER		_IOR('M', 4, struct layer_display_offset)
+
+struct dcu_fb_data {
+	struct fb_info *fsl_dcu_info[DCU_LAYER_NUM_MAX];
+	struct device *dev;
+	void __iomem *reg_base;
+	unsigned int irq;
+	struct clk *clk;
+};
+
+struct layer_display_offset {
+	int x_layer_d;
+	int y_layer_d;
+};
+
+struct mfb_info {
+	int index;
+	char *id;
+	unsigned long pseudo_palette[16];
+	unsigned char alpha;
+	unsigned char blend;
+	unsigned int count;
+	int x_layer_d;	/* layer display x offset to physical screen */
+	int y_layer_d;	/* layer display y offset to physical screen */
+	struct dcu_fb_data *parent;
+};
+
+enum mfb_index {
+	LAYER0 = 0,
+	LAYER1,
+	LAYER2,
+	LAYER3,
+	LAYER4,
+	LAYER5,
+};
+
+static struct mfb_info mfb_template[] = {
+	{
+		.index = LAYER0,
+		.id = "Layer0",
+		.alpha = 0xff,
+		.blend = 0,
+		.count = 0,
+		.x_layer_d = 0,
+		.y_layer_d = 0,
+	},
+	{
+		.index = LAYER1,
+		.id = "Layer1",
+		.alpha = 0xff,
+		.blend = 0,
+		.count = 0,
+		.x_layer_d = 50,
+		.y_layer_d = 50,
+	},
+	{
+		.index = LAYER2,
+		.id = "Layer2",
+		.alpha = 0xff,
+		.blend = 0,
+		.count = 0,
+		.x_layer_d = 100,
+		.y_layer_d = 100,
+	},
+	{
+		.index = LAYER3,
+		.id = "Layer3",
+		.alpha = 0xff,
+		.blend = 0,
+		.count = 0,
+		.x_layer_d = 150,
+		.y_layer_d = 150,
+	},
+	{
+		.index = LAYER4,
+		.id = "Layer4",
+		.alpha = 0xff,
+		.blend = 0,
+		.count = 0,
+		.x_layer_d = 200,
+		.y_layer_d = 200,
+	},
+	{
+		.index = LAYER5,
+		.id = "Layer5",
+		.alpha = 0xff,
+		.blend = 0,
+		.count = 0,
+		.x_layer_d = 250,
+		.y_layer_d = 250,
+	},
+};
+
+static int enable_panel(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	unsigned int bpp;
+
+	writel(DCU_CTRLDESCLN_1_HEIGHT(var->yres) |
+		DCU_CTRLDESCLN_1_WIDTH(var->xres),
+		dcufb->reg_base + DCU_CTRLDESCLN_1(mfbi->index));
+	writel(DCU_CTRLDESCLN_2_POSY(mfbi->y_layer_d) |
+		DCU_CTRLDESCLN_2_POSX(mfbi->x_layer_d),
+		dcufb->reg_base + DCU_CTRLDESCLN_2(mfbi->index));
+
+	writel(info->fix.smem_start,
+		dcufb->reg_base + DCU_CTRLDESCLN_3(mfbi->index));
+
+	switch (var->bits_per_pixel) {
+	case 16:
+		bpp = BPP_16_RGB565;
+		break;
+	case 24:
+		bpp = BPP_24_RGB888;
+		break;
+	case 32:
+		bpp = BPP_32_ARGB8888;
+		break;
+	default:
+		dev_err(dcufb->dev, "unsupported color depth: %u\n",
+			var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	writel(DCU_CTRLDESCLN_4_EN |
+		DCU_CTRLDESCLN_4_TRANS(mfbi->alpha) |
+		DCU_CTRLDESCLN_4_BPP(bpp) |
+		DCU_CTRLDESCLN_4_AB(mfbi->blend),
+		dcufb->reg_base + DCU_CTRLDESCLN_4(mfbi->index));
+
+	writel(DCU_CTRLDESCLN_5_CKMAX_R(0xff) |
+		DCU_CTRLDESCLN_5_CKMAX_G(0xff) |
+		DCU_CTRLDESCLN_5_CKMAX_B(0xff),
+		dcufb->reg_base + DCU_CTRLDESCLN_5(mfbi->index));
+	writel(DCU_CTRLDESCLN_6_CKMIN_R(0) |
+		DCU_CTRLDESCLN_6_CKMIN_G(0) |
+		DCU_CTRLDESCLN_6_CKMIN_B(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_6(mfbi->index));
+
+	writel(DCU_CTRLDESCLN_7_TILE_VER(0) | DCU_CTRLDESCLN_7_TILE_HOR(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_7(mfbi->index));
+
+	writel(DCU_CTRLDESCLN_8_FG_FCOLOR(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_8(mfbi->index));
+	writel(DCU_CTRLDESCLN_9_BG_BCOLOR(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_9(mfbi->index));
+
+	writel(DCU_UPDATE_MODE_READREG, dcufb->reg_base + DCU_UPDATE_MODE);
+	return 0;
+}
+
+static int disable_panel(struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+
+	writel(DCU_CTRLDESCLN_1_HEIGHT(0) |
+		DCU_CTRLDESCLN_1_WIDTH(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_1(mfbi->index));
+	writel(DCU_CTRLDESCLN_2_POSY(0) | DCU_CTRLDESCLN_2_POSX(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_2(mfbi->index));
+
+	writel(0, dcufb->reg_base + DCU_CTRLDESCLN_3(mfbi->index));
+	writel(0, dcufb->reg_base + DCU_CTRLDESCLN_4(mfbi->index));
+
+	writel(DCU_CTRLDESCLN_5_CKMAX_R(0) |
+		DCU_CTRLDESCLN_5_CKMAX_G(0) |
+		DCU_CTRLDESCLN_5_CKMAX_B(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_5(mfbi->index));
+	writel(DCU_CTRLDESCLN_6_CKMIN_R(0) |
+		DCU_CTRLDESCLN_6_CKMIN_G(0) |
+		DCU_CTRLDESCLN_6_CKMIN_B(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_6(mfbi->index));
+
+	writel(DCU_CTRLDESCLN_7_TILE_VER(0) | DCU_CTRLDESCLN_7_TILE_HOR(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_7(mfbi->index));
+
+	writel(DCU_CTRLDESCLN_8_FG_FCOLOR(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_8(mfbi->index));
+	writel(DCU_CTRLDESCLN_9_BG_BCOLOR(0),
+		dcufb->reg_base + DCU_CTRLDESCLN_9(mfbi->index));
+
+	writel(DCU_UPDATE_MODE_READREG, dcufb->reg_base + DCU_UPDATE_MODE);
+	return 0;
+}
+
+static void enable_controller(struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	unsigned int dcu_mode;
+
+	dcu_mode = readl(dcufb->reg_base + DCU_DCU_MODE);
+	writel(dcu_mode | DCU_MODE_DCU_MODE(DCU_MODE_NORMAL),
+		dcufb->reg_base + DCU_DCU_MODE);
+}
+
+static void disable_controller(struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+
+	writel(DCU_MODE_DCU_MODE(DCU_MODE_OFF),
+		dcufb->reg_base + DCU_DCU_MODE);
+}
+
+static int fsl_dcu_check_var(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+
+	if (var->xoffset + info->var.xres > info->var.xres_virtual)
+		var->xoffset = info->var.xres_virtual - info->var.xres;
+
+	if (var->yoffset + info->var.yres > info->var.yres_virtual)
+		var->yoffset = info->var.yres_virtual - info->var.yres;
+
+	switch (var->bits_per_pixel) {
+	case 16:
+		var->red.length = 5;
+		var->red.offset = 11;
+		var->red.msb_right = 0;
+
+		var->green.length = 6;
+		var->green.offset = 5;
+		var->green.msb_right = 0;
+
+		var->blue.length = 5;
+		var->blue.offset = 0;
+		var->blue.msb_right = 0;
+
+		var->transp.length = 0;
+		var->transp.offset = 0;
+		var->transp.msb_right = 0;
+		break;
+	case 24:
+		var->red.length = 8;
+		var->red.offset = 16;
+		var->red.msb_right = 0;
+
+		var->green.length = 8;
+		var->green.offset = 8;
+		var->green.msb_right = 0;
+
+		var->blue.length = 8;
+		var->blue.offset = 0;
+		var->blue.msb_right = 0;
+
+		var->transp.length = 0;
+		var->transp.offset = 0;
+		var->transp.msb_right = 0;
+		break;
+	case 32:
+		var->red.length = 8;
+		var->red.offset = 16;
+		var->red.msb_right = 0;
+
+		var->green.length = 8;
+		var->green.offset = 8;
+		var->green.msb_right = 0;
+
+		var->blue.length = 8;
+		var->blue.offset = 0;
+		var->blue.msb_right = 0;
+
+		var->transp.length = 8;
+		var->transp.offset = 24;
+		var->transp.msb_right = 0;
+		break;
+	default:
+		dev_err(dcufb->dev, "unsupported color depth: %u\n",
+			var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int fsl_dcu_calc_div(struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	unsigned long long div;
+
+	div = (unsigned long long)(clk_get_rate(dcufb->clk) / 1000);
+	div *= info->var.pixclock;
+	do_div(div, 1000000000);
+
+	return div;
+}
+
+static void update_controller(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	unsigned int div;
+
+	div = fsl_dcu_calc_div(info);
+	writel((div - 1), dcufb->reg_base + DCU_DIV_RATIO);
+
+	writel(DCU_DISP_SIZE_DELTA_Y(var->yres) |
+		DCU_DISP_SIZE_DELTA_X(var->xres / 16),
+		dcufb->reg_base + DCU_DISP_SIZE);
+
+	/* Horizontal and vertical sync parameters */
+	writel(DCU_HSYN_PARA_BP(var->left_margin) |
+		DCU_HSYN_PARA_PW(var->hsync_len) |
+		DCU_HSYN_PARA_FP(var->right_margin),
+		dcufb->reg_base + DCU_HSYN_PARA);
+
+	writel(DCU_VSYN_PARA_BP(var->upper_margin) |
+		DCU_VSYN_PARA_PW(var->vsync_len) |
+		DCU_VSYN_PARA_FP(var->lower_margin),
+		dcufb->reg_base + DCU_VSYN_PARA);
+
+	writel(DCU_SYN_POL_INV_PXCK_FALL | DCU_SYN_POL_NEG_REMAIN |
+		DCU_SYN_POL_INV_VS_LOW | DCU_SYN_POL_INV_HS_LOW,
+		dcufb->reg_base + DCU_SYN_POL);
+
+	writel(DCU_BGND_R(0) | DCU_BGND_G(0) | DCU_BGND_B(0),
+		dcufb->reg_base + DCU_BGND);
+
+	writel(DCU_MODE_BLEND_ITER(DCU_LAYER_NUM_MAX) | DCU_MODE_RASTER_EN,
+			dcufb->reg_base + DCU_DCU_MODE);
+
+	writel(DCU_THRESHOLD_LS_BF_VS(0x3) | DCU_THRESHOLD_OUT_BUF_HIGH(0x78) |
+		DCU_THRESHOLD_OUT_BUF_LOW(0), dcufb->reg_base + DCU_THRESHOLD);
+}
+
+static int map_video_memory(struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	u32 smem_len = info->fix.line_length * info->var.yres_virtual;
+
+	info->fix.smem_len = smem_len;
+
+	info->screen_base = dma_alloc_writecombine(info->device,
+		info->fix.smem_len, (dma_addr_t *)&info->fix.smem_start,
+		GFP_KERNEL);
+	if (!info->screen_base) {
+		dev_err(dcufb->dev, "unable to allocate fb memory\n");
+		return -ENOMEM;
+	}
+
+	memset(info->screen_base, 0, info->fix.smem_len);
+
+	return 0;
+}
+
+static void unmap_video_memory(struct fb_info *info)
+{
+	if (!info->screen_base)
+		return;
+
+	dma_free_writecombine(info->device, info->fix.smem_len,
+		info->screen_base, info->fix.smem_start);
+
+	info->screen_base = NULL;
+	info->fix.smem_start = 0;
+	info->fix.smem_len = 0;
+}
+
+static int fsl_dcu_set_layer(struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct fb_var_screeninfo *var = &info->var;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	int pixel_offset;
+	unsigned long addr;
+
+	pixel_offset = (var->yoffset * var->xres_virtual) + var->xoffset;
+	addr = info->fix.smem_start +
+		(pixel_offset * (var->bits_per_pixel >> 3));
+
+	writel(addr, dcufb->reg_base + DCU_CTRLDESCLN_3(mfbi->index));
+	writel(DCU_UPDATE_MODE_READREG, dcufb->reg_base + DCU_UPDATE_MODE);
+
+	return 0;
+}
+
+static int fsl_dcu_set_par(struct fb_info *info)
+{
+	unsigned long len;
+	struct fb_var_screeninfo *var = &info->var;
+	struct fb_fix_screeninfo *fix = &info->fix;
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+
+	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->accel = FB_ACCEL_NONE;
+	fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+
+	len = info->var.yres_virtual * info->fix.line_length;
+	if (len != info->fix.smem_len) {
+		if (info->fix.smem_start)
+			unmap_video_memory(info);
+
+		if (map_video_memory(info)) {
+			dev_err(dcufb->dev, "unable to allocate fb memory\n");
+			return -ENOMEM;
+		}
+	}
+
+	/* Only layer 0 could update LCD controller */
+	if (mfbi->index == LAYER0) {
+		update_controller(info);
+		enable_controller(info);
+	}
+
+	enable_panel(info);
+	return 0;
+}
+
+static inline __u32 CNVT_TOHW(__u32 val, __u32 width)
+{
+	return ((val<<width) + 0x7FFF - val) >> 16;
+}
+
+static int fsl_dcu_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp, struct fb_info *info)
+{
+	unsigned int val;
+	int ret = -EINVAL;
+
+	/*
+	 * If greyscale is true, then we convert the RGB value
+	 * to greyscale no matter what visual we are using.
+	 */
+	if (info->var.grayscale)
+		red = green = blue = (19595 * red + 38470 * green +
+				      7471 * blue) >> 16;
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		/*
+		 * 16-bit True Colour.  We encode the RGB value
+		 * according to the RGB bitfield information.
+		 */
+		if (regno < 16) {
+			u32 *pal = info->pseudo_palette;
+
+			red = CNVT_TOHW(red, info->var.red.length);
+			green = CNVT_TOHW(green, info->var.green.length);
+			blue = CNVT_TOHW(blue, info->var.blue.length);
+			transp = CNVT_TOHW(transp, info->var.transp.length);
+
+			val = (red << info->var.red.offset) |
+			    (green << info->var.green.offset) |
+			    (blue << info->var.blue.offset) |
+			    (transp << info->var.transp.offset);
+
+			pal[regno] = val;
+			ret = 0;
+		}
+		break;
+	case FB_VISUAL_STATIC_PSEUDOCOLOR:
+	case FB_VISUAL_PSEUDOCOLOR:
+		break;
+	}
+
+	return ret;
+}
+
+static int fsl_dcu_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
+{
+	if ((info->var.xoffset == var->xoffset) &&
+	    (info->var.yoffset == var->yoffset))
+		return 0;
+
+	if ((var->xoffset + info->var.xres) > info->var.xres_virtual
+	    || (var->yoffset + info->var.yres) > info->var.yres_virtual)
+		return -EINVAL;
+
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
+
+	if (var->vmode & FB_VMODE_YWRAP)
+		info->var.vmode |= FB_VMODE_YWRAP;
+	else
+		info->var.vmode &= ~FB_VMODE_YWRAP;
+
+	fsl_dcu_set_layer(info);
+
+	return 0;
+}
+
+static int fsl_dcu_blank(int blank_mode, struct fb_info *info)
+{
+	switch (blank_mode) {
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		disable_panel(info);
+		break;
+	case FB_BLANK_POWERDOWN:
+		disable_controller(info);
+		break;
+	case FB_BLANK_UNBLANK:
+		enable_panel(info);
+		break;
+	}
+
+	return 0;
+}
+
+static int fsl_dcu_ioctl(struct fb_info *info, unsigned int cmd,
+		unsigned long arg)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	struct layer_display_offset layer_d;
+	void __user *buf = (void __user *)arg;
+	unsigned char alpha;
+
+	switch (cmd) {
+	case MFB_SET_LAYER:
+		if (copy_from_user(&layer_d, buf, sizeof(layer_d)))
+			return -EFAULT;
+		mfbi->x_layer_d = layer_d.x_layer_d;
+		mfbi->y_layer_d = layer_d.y_layer_d;
+		fsl_dcu_set_par(info);
+		break;
+	case MFB_GET_LAYER:
+		layer_d.x_layer_d = mfbi->x_layer_d;
+		layer_d.y_layer_d = mfbi->y_layer_d;
+		if (copy_to_user(buf, &layer_d, sizeof(layer_d)))
+			return -EFAULT;
+		break;
+	case MFB_GET_ALPHA:
+		alpha = mfbi->alpha;
+		if (copy_to_user(buf, &alpha, sizeof(alpha)))
+			return -EFAULT;
+		break;
+	case MFB_SET_ALPHA:
+		if (copy_from_user(&alpha, buf, sizeof(alpha)))
+			return -EFAULT;
+		mfbi->blend = 1;
+		mfbi->alpha = alpha;
+		fsl_dcu_set_par(info);
+		break;
+	default:
+		dev_err(dcufb->dev, "unknown ioctl command (0x%08X)\n", cmd);
+		return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
+static void reset_total_layers(struct dcu_fb_data *dcufb)
+{
+	int i;
+
+	for (i = 1; i < DCU_TOTAL_LAYER_NUM; i++) {
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_1(i));
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_2(i));
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_3(i));
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_4(i));
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_5(i));
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_6(i));
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_7(i));
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_8(i));
+		writel(0, dcufb->reg_base + DCU_CTRLDESCLN_9(i));
+	}
+	writel(DCU_UPDATE_MODE_READREG, dcufb->reg_base + DCU_UPDATE_MODE);
+}
+
+static int fsl_dcu_open(struct fb_info *info, int user)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	u32 int_mask = readl(dcufb->reg_base + DCU_INT_MASK);
+	int ret = 0;
+
+	mfbi->index = info->node;
+
+	mfbi->count++;
+	if (mfbi->count == 1) {
+		fsl_dcu_check_var(&info->var, info);
+		ret = fsl_dcu_set_par(info);
+		if (ret < 0)
+			mfbi->count--;
+		else
+			writel(int_mask & ~DCU_INT_MASK_UNDRUN,
+				dcufb->reg_base + DCU_INT_MASK);
+	}
+
+	return ret;
+}
+
+static int fsl_dcu_release(struct fb_info *info, int user)
+{
+	struct mfb_info *mfbi = info->par;
+	int ret = 0;
+
+	mfbi->count--;
+	if (mfbi->count == 0)
+		ret = disable_panel(info);
+
+	return ret;
+}
+
+static struct fb_ops fsl_dcu_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = fsl_dcu_check_var,
+	.fb_set_par = fsl_dcu_set_par,
+	.fb_setcolreg = fsl_dcu_setcolreg,
+	.fb_blank = fsl_dcu_blank,
+	.fb_pan_display = fsl_dcu_pan_display,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_ioctl = fsl_dcu_ioctl,
+	.fb_open = fsl_dcu_open,
+	.fb_release = fsl_dcu_release,
+};
+
+static int fsl_dcu_init_fbinfo(struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct fb_var_screeninfo *var = &info->var;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	struct device_node *np = dcufb->dev->of_node;
+	struct device_node *display_np;
+	struct device_node *timings_np;
+	struct display_timings *timings;
+	int i;
+	int ret = 0;
+
+	display_np = of_parse_phandle(np, "display", 0);
+	if (!display_np) {
+		dev_err(dcufb->dev, "failed to find display phandle\n");
+		return -ENOENT;
+	}
+
+	ret = of_property_read_u32(display_np, "bits-per-pixel",
+				   &var->bits_per_pixel);
+	if (ret < 0) {
+		dev_err(dcufb->dev, "failed to get property bits-per-pixel\n");
+		goto put_display_node;
+	}
+
+	timings = of_get_display_timings(display_np);
+	if (!timings) {
+		dev_err(dcufb->dev, "failed to get display timings\n");
+		ret = -ENOENT;
+		goto put_display_node;
+	}
+
+	timings_np = of_find_node_by_name(display_np,
+					  "display-timings");
+	if (!timings_np) {
+		dev_err(dcufb->dev, "failed to find display-timings node\n");
+		ret = -ENOENT;
+		goto put_display_node;
+	}
+
+	for (i = 0; i < of_get_child_count(timings_np); i++) {
+		struct videomode vm;
+		struct fb_videomode fb_vm;
+
+		ret = videomode_from_timings(timings, &vm, i);
+		if (ret < 0)
+			goto put_timings_node;
+
+		ret = fb_videomode_from_videomode(&vm, &fb_vm);
+		if (ret < 0)
+			goto put_timings_node;
+
+		fb_add_videomode(&fb_vm, &info->modelist);
+	}
+
+	return 0;
+put_timings_node:
+	of_node_put(timings_np);
+put_display_node:
+	of_node_put(display_np);
+	return ret;
+}
+
+static int install_framebuffer(struct fb_info *info)
+{
+	struct mfb_info *mfbi = info->par;
+	struct dcu_fb_data *dcufb = mfbi->parent;
+	struct fb_modelist *modelist;
+	int ret;
+
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->fbops = &fsl_dcu_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->pseudo_palette = &mfbi->pseudo_palette;
+
+	fb_alloc_cmap(&info->cmap, 16, 0);
+
+	INIT_LIST_HEAD(&info->modelist);
+
+	ret = fsl_dcu_init_fbinfo(info);
+	if (ret)
+		return ret;
+
+	modelist = list_first_entry(&info->modelist,
+			struct fb_modelist, list);
+	fb_videomode_to_var(&info->var, &modelist->mode);
+
+	fsl_dcu_check_var(&info->var, info);
+	ret = register_framebuffer(info);
+	if (ret < 0) {
+		dev_err(dcufb->dev, "failed to register framebuffer device\n");
+		return ret;
+	}
+
+	printk(KERN_INFO "fb%d: fb device registered successfully.\n",
+			info->node);
+	return 0;
+}
+
+static void uninstall_framebuffer(struct fb_info *info)
+{
+	unregister_framebuffer(info);
+	unmap_video_memory(info);
+
+	if (&info->cmap)
+		fb_dealloc_cmap(&info->cmap);
+}
+
+static irqreturn_t fsl_dcu_irq(int irq, void *dev_id)
+{
+	struct dcu_fb_data *dcufb = dev_id;
+	unsigned int status = readl(dcufb->reg_base + DCU_INT_STATUS);
+	u32 dcu_mode;
+
+	if (status & DCU_INT_STATUS_UNDRUN) {
+		dcu_mode = readl(dcufb->reg_base + DCU_DCU_MODE);
+		dcu_mode &= ~DCU_MODE_DCU_MODE_MASK;
+		writel(dcu_mode | DCU_MODE_DCU_MODE(DCU_MODE_OFF),
+			dcufb->reg_base + DCU_DCU_MODE);
+		udelay(1);
+		writel(dcu_mode | DCU_MODE_DCU_MODE(DCU_MODE_NORMAL),
+			dcufb->reg_base + DCU_DCU_MODE);
+	}
+
+	writel(status, dcufb->reg_base + DCU_INT_STATUS);
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int fsl_dcu_runtime_suspend(struct device *dev)
+{
+	struct dcu_fb_data *dcufb = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(dcufb->clk);
+
+	return 0;
+}
+
+static int fsl_dcu_runtime_resume(struct device *dev)
+{
+	struct dcu_fb_data *dcufb = dev_get_drvdata(dev);
+
+	clk_prepare_enable(dcufb->clk);
+
+	return 0;
+}
+#endif
+
+static int bypass_tcon(struct device_node *np)
+{
+	struct device_node *tcon_np;
+	struct platform_device *tcon_pdev;
+	struct clk *tcon_clk;
+	struct resource *res;
+	void __iomem *tcon_reg;
+
+	tcon_np = of_parse_phandle(np, "tcon-controller", 0);
+	if (!tcon_np)
+		return -EINVAL;
+
+	tcon_pdev = of_find_device_by_node(tcon_np);
+	if (!tcon_pdev)
+		return -EINVAL;
+
+	tcon_clk = devm_clk_get(&tcon_pdev->dev, "tcon");
+	if (IS_ERR(tcon_clk))
+		return PTR_ERR(tcon_clk);
+	clk_prepare_enable(tcon_clk);
+
+	res = platform_get_resource(tcon_pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	tcon_reg = devm_ioremap_resource(&tcon_pdev->dev, res);
+	if (IS_ERR(tcon_reg))
+		return PTR_ERR(tcon_reg);
+
+	writel(TCON_BYPASS_ENABLE, tcon_reg + TCON_CTRL1);
+	return 0;
+}
+
+static int fsl_dcu_probe(struct platform_device *pdev)
+{
+	struct dcu_fb_data *dcufb;
+	struct mfb_info *mfbi;
+	struct resource *res;
+	int ret = 0;
+	int i;
+
+	dcufb = devm_kzalloc(&pdev->dev,
+		sizeof(struct dcu_fb_data), GFP_KERNEL);
+	if (!dcufb)
+		return -ENOMEM;
+
+	dcufb->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, dcufb);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "could not get memory IO resource\n");
+		return -ENODEV;
+	}
+
+	dcufb->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dcufb->reg_base)) {
+		dev_err(&pdev->dev, "could not ioremap resource\n");
+		return PTR_ERR(dcufb->reg_base);
+	}
+
+	dcufb->irq = platform_get_irq(pdev, 0);
+	if (!dcufb->irq) {
+		dev_err(&pdev->dev, "could not get irq\n");
+		return -EINVAL;
+	}
+
+	ret = devm_request_irq(&pdev->dev, dcufb->irq, fsl_dcu_irq,
+			0, DRIVER_NAME, dcufb);
+	if (ret) {
+		dev_err(&pdev->dev, "could not request irq\n");
+		goto failed_ioremap;
+	}
+
+	/* Put TCON in bypass mode, so the input signals from DCU are passed
+	 * through TCON unchanged */
+	ret = bypass_tcon(pdev->dev.of_node);
+	if (ret) {
+		dev_err(&pdev->dev, "could not bypass TCON\n");
+		goto failed_bypasstcon;
+	}
+
+	dcufb->clk = devm_clk_get(&pdev->dev, "dcu");
+	if (IS_ERR(dcufb->clk)) {
+		ret = PTR_ERR(dcufb->clk);
+		dev_err(&pdev->dev, "could not get clock\n");
+		goto failed_getclock;
+	}
+	clk_prepare_enable(dcufb->clk);
+
+	pm_runtime_enable(dcufb->dev);
+	pm_runtime_get_sync(dcufb->dev);
+
+	for (i = 0; i < ARRAY_SIZE(dcufb->fsl_dcu_info); i++) {
+		dcufb->fsl_dcu_info[i] =
+			framebuffer_alloc(sizeof(struct mfb_info), &pdev->dev);
+		if (!dcufb->fsl_dcu_info[i]) {
+			ret = -ENOMEM;
+			goto failed_alloc_framebuffer;
+		}
+
+		dcufb->fsl_dcu_info[i]->fix.smem_start = 0;
+
+		mfbi = dcufb->fsl_dcu_info[i]->par;
+		memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info));
+		mfbi->parent = dcufb;
+
+		ret = install_framebuffer(dcufb->fsl_dcu_info[i]);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"could not register framebuffer %d\n", i);
+			goto failed_register_framebuffer;
+		}
+	}
+
+	reset_total_layers(mfbi->parent);
+	return 0;
+
+failed_register_framebuffer:
+	for (i = 0; i < ARRAY_SIZE(dcufb->fsl_dcu_info); i++) {
+		if (dcufb->fsl_dcu_info[i])
+			framebuffer_release(dcufb->fsl_dcu_info[i]);
+	}
+failed_alloc_framebuffer:
+	pm_runtime_put_sync(dcufb->dev);
+	pm_runtime_disable(dcufb->dev);
+failed_getclock:
+failed_bypasstcon:
+	free_irq(dcufb->irq, dcufb);
+failed_ioremap:
+	return ret;
+}
+
+static int fsl_dcu_remove(struct platform_device *pdev)
+{
+	struct dcu_fb_data *dcufb = dev_get_drvdata(&pdev->dev);
+	int i;
+
+	pm_runtime_get_sync(dcufb->dev);
+
+	disable_controller(dcufb->fsl_dcu_info[0]);
+
+	clk_disable_unprepare(dcufb->clk);
+	free_irq(dcufb->irq, dcufb);
+
+	for (i = 0; i < ARRAY_SIZE(dcufb->fsl_dcu_info); i++) {
+		uninstall_framebuffer(dcufb->fsl_dcu_info[i]);
+		framebuffer_release(dcufb->fsl_dcu_info[i]);
+	}
+
+	pm_runtime_put_sync(dcufb->dev);
+	pm_runtime_disable(dcufb->dev);
+
+	return 0;
+}
+
+static const struct dev_pm_ops fsl_dcu_pm_ops = {
+	SET_RUNTIME_PM_OPS(fsl_dcu_runtime_suspend,
+			fsl_dcu_runtime_resume, NULL)
+};
+
+static struct of_device_id fsl_dcu_dt_ids[] = {
+	{
+		.compatible = "fsl,vf610-dcu",
+	},
+	{}
+};
+
+static struct platform_driver fsl_dcu_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = fsl_dcu_dt_ids,
+		.pm = &fsl_dcu_pm_ops,
+	},
+	.probe = fsl_dcu_probe,
+	.remove = fsl_dcu_remove,
+};
+
+module_platform_driver(fsl_dcu_driver);
+
+MODULE_AUTHOR("Alison Wang");
+MODULE_DESCRIPTION("Freescale DCU framebuffer driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.0

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

* [PATCH v3 5/5] Documentation: DT: Add DCU framebuffer driver
  2013-08-15  8:01 [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
                   ` (3 preceding siblings ...)
  2013-08-15  8:01 ` [PATCH v3 4/5] fb: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
@ 2013-08-15  8:01 ` Alison Wang
  2013-08-26  9:51 ` [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Wang Huan-B18965
  5 siblings, 0 replies; 12+ messages in thread
From: Alison Wang @ 2013-08-15  8:01 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the document for DCU framebuffer driver under
Documentation/devicetree/bindings/fb/.

Signed-off-by: Alison Wang <b18965@freescale.com>
---
Changes in v3: Add display node description
Changes in v2: New

 .../devicetree/bindings/fb/fsl-dcu-fb.txt          | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt

diff --git a/Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt b/Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt
new file mode 100644
index 0000000..d0d50dd
--- /dev/null
+++ b/Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt
@@ -0,0 +1,67 @@
+* Freescale Display Control Unit (DCU)
+
+Required properties:
+- compatible: Should be "fsl,vf610-dcu". Supported chips include
+  Vybrid VF610.
+- reg: Address and length of the register set for DCU.
+- interrupts: Should contain DCU interrupts.
+- clocks: From common clock binding: handle to DCU clock.
+- clock-names: From common clock binding: Shall be "dcu".
+- tcon-controller: The phandle of TCON controller.
+- display: The phandle to display node.
+
+For the DCU initialization, we read data from TCON node.
+Required properties for TCON:
+- compatible: Should be "fsl,vf610-tcon". Supported chips include
+  Vybrid VF610.
+- reg: Address and length of the register set for TCON.
+- clocks: From common clock binding: handle to TCON clock.
+- clock-names: From common clock binding: Shall be "tcon".
+
+* display node
+
+Required properties:
+- bits-per-pixel: <24> for RGB888.
+
+Required sub-node:
+- display-timings: Refer to binding doc display-timing.txt for details.
+
+Examples:
+
+dcu0: dcu at 40058000 {
+	compatible = "fsl,vf610-dcu";
+	reg = <0x40058000 0x1200>;
+	interrupts = <0 30 0x04>;
+	clocks = <&clks VF610_CLK_DCU0>;
+	clock-names = "dcu";
+	tcon-controller = <&tcon0>;
+	display = <&display>;
+
+	display: display at 0 {
+		bits-per-pixel = <24>;
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: nl4827hc19 {
+				clock-frequency = <10870000>;
+				hactive = <480>;
+				vactive = <272>;
+				hback-porch = <2>;
+				hfront-porch = <2>;
+				vback-porch = <1>;
+				vfront-porch = <1>;
+				hsync-len = <41>;
+				vsync-len = <2>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
+};
+
+tcon0: tcon at 4003d000 {
+	compatible = "fsl,vf610-tcon";
+	reg = <0x4003d000 0x1000>;
+	clocks = <&clks VF610_CLK_TCON0>;
+	clock-names = "tcon";
+};
-- 
1.8.0

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

* [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform
  2013-08-15  8:01 [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
                   ` (4 preceding siblings ...)
  2013-08-15  8:01 ` [PATCH v3 5/5] Documentation: DT: Add DCU framebuffer driver Alison Wang
@ 2013-08-26  9:51 ` Wang Huan-B18965
  2013-09-03  8:21   ` Wang Huan-B18965
  5 siblings, 1 reply; 12+ messages in thread
From: Wang Huan-B18965 @ 2013-08-26  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, Jean-Christophe, Tomi,

       Do you have any comments for these patches?

       Thanks!


Best Regards,
Alison Wang

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-
> bounces at lists.infradead.org] On Behalf Of Alison Wang
> Sent: Thursday, August 15, 2013 4:02 PM
> To: plagnioj at jcrosoft.com; tomi.valkeinen at ti.com; shawn.guo at linaro.org;
> Estevam Fabio-R49496; linux-fbdev at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org
> Cc: Jin Zhengxiong-R64188
> Subject: [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for
> Vybrid VF610 platform
> 
> This series contain DCU framebuffer driver for Freescale Vybrid VF610
> platform.
> 
> The Display Controller Unit (DCU) module is a system master that
> fetches graphics stored in internal or external memory and displays
> them on a TFT LCD panel. A wide range of panel sizes is supported and
> the timing of the interface signals is highly configurable.
> Graphics are read directly from memory and then blended in real-time,
> which allows for dynamic content creation with minimal CPU intervention.
> 
> The features:
> (1) Full RGB888 output to TFT LCD panel.
> (2) For the current LCD panel, WQVGA "480x272" is tested.
> (3) Blending of each pixel using up to 4 source layers dependent on
> size of panel.
> (4) Each graphic layer can be placed with one pixel resolution in
> either axis.
> (5) Each graphic layer support RGB565 and RGB888 direct colors without
> alpha channel and BGRA8888 direct colors with an alpha channel.
> (6) Each graphic layer support alpha blending with 8-bit resolution.
> 
> Changes in v3:
> - Correct DCU_MODE_BLEND_ITER macro definition.
> - Remove hardcode panel description in the driver. Use the videomode
> helpers to get the relevant data from devicetree.
> - Correct the wrong indentation.
> - Use dev_* for printing messages in drivers.
> - Change calc_div_ratio() to fsl_dcu_calc_div(), and rewrite this
> function.
> - Use devm_request_irq() instead of request_irq().
> - Drop useless code.
> - Increase the layers number to the maximum 6.
> - Use dma_alloc_writecombine() instead of dma_alloc_coherent().
> - Use runtime PM.
> 
> Changes in v2:
> - Add a document for DCU framebuffer driver under
> Documentation/devicetree/bindings/fb/.
> 
> ----------------------------------------------------------------
> Alison Wang (5):
>       ARM: dts: vf610: Add DCU and TCON nodes
>       ARM: dts: vf610-twr: Enable DCU and TCON devices
>       ARM: clk: vf610: Add DCU and TCON clock support
>       fb: Add DCU framebuffer driver for Vybrid VF610 platform
>       Documentation: DT: Add DCU framebuffer driver
> 
>  Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt |   67 +++++
>  arch/arm/boot/dts/vf610-twr.dts                     |   32 +++
>  arch/arm/boot/dts/vf610.dtsi                        |   19 +-
>  arch/arm/mach-imx/clk-vf610.c                       |    5 +
>  drivers/video/Kconfig                               |   10 +
>  drivers/video/Makefile                              |    1 +
>  drivers/video/fsl-dcu-fb.c                          | 1095
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++
>  include/dt-bindings/clock/vf610-clock.h             |    3 +-
>  8 files changed, 1230 insertions(+), 2 deletions(-)  create mode
> 100644 Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt
>  create mode 100644 drivers/video/fsl-dcu-fb.c
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform
  2013-08-26  9:51 ` [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Wang Huan-B18965
@ 2013-09-03  8:21   ` Wang Huan-B18965
  2013-09-04 10:33     ` Tomi Valkeinen
  0 siblings, 1 reply; 12+ messages in thread
From: Wang Huan-B18965 @ 2013-09-03  8:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, Jean-Christophe, Tomi,

      Could you please help to review these patches?
      Thanks!


Best Regards,
Alison Wang

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-
> bounces at lists.infradead.org] On Behalf Of Wang Huan-B18965
> Sent: Monday, August 26, 2013 5:52 PM
> To: plagnioj at jcrosoft.com; tomi.valkeinen at ti.com; linux-
> fbdev at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Cc: Jin Zhengxiong-R64188; Estevam Fabio-R49496; shawn.guo at linaro.org
> Subject: RE: [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for
> Vybrid VF610 platform
> 
> Hi, Jean-Christophe, Tomi,
> 
>        Do you have any comments for these patches?
> 
>        Thanks!
> 
> 
> Best Regards,
> Alison Wang
> 
> > -----Original Message-----
> > From: linux-arm-kernel [mailto:linux-arm-kernel-
> > bounces at lists.infradead.org] On Behalf Of Alison Wang
> > Sent: Thursday, August 15, 2013 4:02 PM
> > To: plagnioj at jcrosoft.com; tomi.valkeinen at ti.com;
> > shawn.guo at linaro.org; Estevam Fabio-R49496;
> > linux-fbdev at vger.kernel.org; linux-arm- kernel at lists.infradead.org
> > Cc: Jin Zhengxiong-R64188
> > Subject: [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for
> > Vybrid VF610 platform
> >
> > This series contain DCU framebuffer driver for Freescale Vybrid VF610
> > platform.
> >
> > The Display Controller Unit (DCU) module is a system master that
> > fetches graphics stored in internal or external memory and displays
> > them on a TFT LCD panel. A wide range of panel sizes is supported and
> > the timing of the interface signals is highly configurable.
> > Graphics are read directly from memory and then blended in real-time,
> > which allows for dynamic content creation with minimal CPU
> intervention.
> >
> > The features:
> > (1) Full RGB888 output to TFT LCD panel.
> > (2) For the current LCD panel, WQVGA "480x272" is tested.
> > (3) Blending of each pixel using up to 4 source layers dependent on
> > size of panel.
> > (4) Each graphic layer can be placed with one pixel resolution in
> > either axis.
> > (5) Each graphic layer support RGB565 and RGB888 direct colors
> without
> > alpha channel and BGRA8888 direct colors with an alpha channel.
> > (6) Each graphic layer support alpha blending with 8-bit resolution.
> >
> > Changes in v3:
> > - Correct DCU_MODE_BLEND_ITER macro definition.
> > - Remove hardcode panel description in the driver. Use the videomode
> > helpers to get the relevant data from devicetree.
> > - Correct the wrong indentation.
> > - Use dev_* for printing messages in drivers.
> > - Change calc_div_ratio() to fsl_dcu_calc_div(), and rewrite this
> > function.
> > - Use devm_request_irq() instead of request_irq().
> > - Drop useless code.
> > - Increase the layers number to the maximum 6.
> > - Use dma_alloc_writecombine() instead of dma_alloc_coherent().
> > - Use runtime PM.
> >
> > Changes in v2:
> > - Add a document for DCU framebuffer driver under
> > Documentation/devicetree/bindings/fb/.
> >
> > ----------------------------------------------------------------
> > Alison Wang (5):
> >       ARM: dts: vf610: Add DCU and TCON nodes
> >       ARM: dts: vf610-twr: Enable DCU and TCON devices
> >       ARM: clk: vf610: Add DCU and TCON clock support
> >       fb: Add DCU framebuffer driver for Vybrid VF610 platform
> >       Documentation: DT: Add DCU framebuffer driver
> >
> >  Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt |   67 +++++
> >  arch/arm/boot/dts/vf610-twr.dts                     |   32 +++
> >  arch/arm/boot/dts/vf610.dtsi                        |   19 +-
> >  arch/arm/mach-imx/clk-vf610.c                       |    5 +
> >  drivers/video/Kconfig                               |   10 +
> >  drivers/video/Makefile                              |    1 +
> >  drivers/video/fsl-dcu-fb.c                          | 1095
> >
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > +++++++++
> >  include/dt-bindings/clock/vf610-clock.h             |    3 +-
> >  8 files changed, 1230 insertions(+), 2 deletions(-)  create mode
> > 100644 Documentation/devicetree/bindings/fb/fsl-dcu-fb.txt
> >  create mode 100644 drivers/video/fsl-dcu-fb.c
> >
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform
  2013-09-03  8:21   ` Wang Huan-B18965
@ 2013-09-04 10:33     ` Tomi Valkeinen
  2013-09-13  7:07       ` Wang Huan-B18965
  0 siblings, 1 reply; 12+ messages in thread
From: Tomi Valkeinen @ 2013-09-04 10:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 03/09/13 11:21, Wang Huan-B18965 wrote:
> Hi, Jean-Christophe, Tomi,
> 
>       Could you please help to review these patches?
>       Thanks!

There seemed to be some strong opinions that there should be a drm
driver for this hardware, instead of an fb driver. So as there seems to
be disagreements about this, I'll leave this series to Jean-Christophe,
who's the primary maintainer.

 Tomi


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130904/90321e33/attachment.sig>

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

* [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform
  2013-09-04 10:33     ` Tomi Valkeinen
@ 2013-09-13  7:07       ` Wang Huan-B18965
  2013-09-20 10:04         ` Tomi Valkeinen
  0 siblings, 1 reply; 12+ messages in thread
From: Wang Huan-B18965 @ 2013-09-13  7:07 UTC (permalink / raw)
  To: linux-arm-kernel

My comments inline.

> -----Original Message-----
> From: Tomi Valkeinen [mailto:tomi.valkeinen at ti.com]
> Sent: Wednesday, September 04, 2013 6:33 PM
> To: Wang Huan-B18965
> Cc: plagnioj at jcrosoft.com; linux-fbdev at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; Jin Zhengxiong-R64188; Estevam Fabio-R49496;
> shawn.guo at linaro.org
> Subject: Re: [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for
> Vybrid VF610 platform
> 
> Hi,
> 
> On 03/09/13 11:21, Wang Huan-B18965 wrote:
> > Hi, Jean-Christophe, Tomi,
> >
> >       Could you please help to review these patches?
> >       Thanks!
> 
> There seemed to be some strong opinions that there should be a drm
> driver for this hardware, instead of an fb driver. So as there seems to
> be disagreements about this, I'll leave this series to Jean-Christophe,
> who's the primary maintainer.
[Alison Wang] 

Thanks for Tomi's comments. 

I agree that we can implement the DRM driver for the DCU. As the bandwidth limitation, I suggest we use the fb driver firstly. On the other hand, the fb driver can meet the application requirement based on this SoC. We'll try to provide the DRM driver when this IP integrated into other SoC. 

Jean-Christophe, Do you have any comments. Thanks.  


Best Regards,
Alison Wang

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

* [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform
  2013-09-13  7:07       ` Wang Huan-B18965
@ 2013-09-20 10:04         ` Tomi Valkeinen
  2013-09-27  5:29           ` Wang Huan-B18965
  0 siblings, 1 reply; 12+ messages in thread
From: Tomi Valkeinen @ 2013-09-20 10:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/09/13 10:07, Wang Huan-B18965 wrote:
> My comments inline.
> 
>> -----Original Message----- From: Tomi Valkeinen
>> [mailto:tomi.valkeinen at ti.com] Sent: Wednesday, September 04, 2013
>> 6:33 PM To: Wang Huan-B18965 Cc: plagnioj at jcrosoft.com;
>> linux-fbdev at vger.kernel.org; linux-arm- kernel at lists.infradead.org;
>> Jin Zhengxiong-R64188; Estevam Fabio-R49496; shawn.guo at linaro.org 
>> Subject: Re: [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver
>> for Vybrid VF610 platform
>> 
>> Hi,
>> 
>> On 03/09/13 11:21, Wang Huan-B18965 wrote:
>>> Hi, Jean-Christophe, Tomi,
>>> 
>>> Could you please help to review these patches? Thanks!
>> 
>> There seemed to be some strong opinions that there should be a drm 
>> driver for this hardware, instead of an fb driver. So as there
>> seems to be disagreements about this, I'll leave this series to
>> Jean-Christophe, who's the primary maintainer.
> [Alison Wang]
> 
> Thanks for Tomi's comments.
> 
> I agree that we can implement the DRM driver for the DCU. As the
> bandwidth limitation, I suggest we use the fb driver firstly. On the
> other hand, the fb driver can meet the application requirement based
> on this SoC. We'll try to provide the DRM driver when this IP
> integrated into other SoC.

If you plan to move to DRM driver anyway, I would strongly suggest
merging only the DRM driver. If we merge the fb driver, and a bit later
the DRM driver for the same hardware, we'll have two drivers of which
the other is already deprecated.

 Tomi

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130920/3c8b5632/attachment.sig>

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

* [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform
  2013-09-20 10:04         ` Tomi Valkeinen
@ 2013-09-27  5:29           ` Wang Huan-B18965
  0 siblings, 0 replies; 12+ messages in thread
From: Wang Huan-B18965 @ 2013-09-27  5:29 UTC (permalink / raw)
  To: linux-arm-kernel

> >> On 03/09/13 11:21, Wang Huan-B18965 wrote:
> >>> Hi, Jean-Christophe, Tomi,
> >>>
> >>> Could you please help to review these patches? Thanks!
> >>
> >> There seemed to be some strong opinions that there should be a drm
> >> driver for this hardware, instead of an fb driver. So as there seems
> >> to be disagreements about this, I'll leave this series to
> >> Jean-Christophe, who's the primary maintainer.
> > [Alison Wang]
> >
> > Thanks for Tomi's comments.
> >
> > I agree that we can implement the DRM driver for the DCU. As the
> > bandwidth limitation, I suggest we use the fb driver firstly. On the
> > other hand, the fb driver can meet the application requirement based
> > on this SoC. We'll try to provide the DRM driver when this IP
> > integrated into other SoC.
> 
> If you plan to move to DRM driver anyway, I would strongly suggest
> merging only the DRM driver. If we merge the fb driver, and a bit later
> the DRM driver for the same hardware, we'll have two drivers of which
> the other is already deprecated.
> 
[Alison Wang] We will not have bandwidth and develop the DRM driver in the near future. On the other hand, this IP is not integrated into other high-end SOC. So this fb driver will be used for some kind of long time for current SoC. We can try to remove the fb driver when we developed the DRM driver for other SoC.

Jean-Christophe, Do you have any comments? Thanks.


Best Regards,
Alison Wang

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

end of thread, other threads:[~2013-09-27  5:29 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-15  8:01 [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
2013-08-15  8:01 ` [PATCH v3 1/5] ARM: dts: vf610: Add DCU and TCON nodes Alison Wang
2013-08-15  8:01 ` [PATCH v3 2/5] ARM: dts: vf610-twr: Enable DCU and TCON devices Alison Wang
2013-08-15  8:01 ` [PATCH v3 3/5] ARM: clk: vf610: Add DCU and TCON clock support Alison Wang
2013-08-15  8:01 ` [PATCH v3 4/5] fb: Add DCU framebuffer driver for Vybrid VF610 platform Alison Wang
2013-08-15  8:01 ` [PATCH v3 5/5] Documentation: DT: Add DCU framebuffer driver Alison Wang
2013-08-26  9:51 ` [PATCH v3 0/5] ARM: vf610: Add DCU framebuffer driver for Vybrid VF610 platform Wang Huan-B18965
2013-09-03  8:21   ` Wang Huan-B18965
2013-09-04 10:33     ` Tomi Valkeinen
2013-09-13  7:07       ` Wang Huan-B18965
2013-09-20 10:04         ` Tomi Valkeinen
2013-09-27  5:29           ` Wang Huan-B18965

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).