All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-03  9:15 ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:15 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel,
	linux-kernel, Xiubo Li

Framebuffer driver for the Freescale SoC Display Controller.


Change in V2:
- Use the native-mode timing as default.
- Add to_fsl_private().


Xiubo Li (4):
  video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
  video: fsl-dcfb: Add devicetree binding support
  ARM: ls1021a: dtsi: Add dt node support for dcfb.
  ARM: ls1021a: dts: Add and enable dt node for dcfb.

 .../devicetree/bindings/video/fsl,dcfb.txt         |  52 ++
 arch/arm/boot/dts/ls1021a-twr.dts                  |  26 +
 arch/arm/boot/dts/ls1021a.dtsi                     |  10 +
 drivers/video/fbdev/Kconfig                        |  19 +
 drivers/video/fbdev/Makefile                       |   1 +
 drivers/video/fbdev/fsl-dcfb.c                     | 814 +++++++++++++++++++++
 6 files changed, 922 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt
 create mode 100644 drivers/video/fbdev/fsl-dcfb.c

-- 
2.1.0.27.g96db324


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

* [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-03  9:15 ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

Framebuffer driver for the Freescale SoC Display Controller.


Change in V2:
- Use the native-mode timing as default.
- Add to_fsl_private().


Xiubo Li (4):
  video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
  video: fsl-dcfb: Add devicetree binding support
  ARM: ls1021a: dtsi: Add dt node support for dcfb.
  ARM: ls1021a: dts: Add and enable dt node for dcfb.

 .../devicetree/bindings/video/fsl,dcfb.txt         |  52 ++
 arch/arm/boot/dts/ls1021a-twr.dts                  |  26 +
 arch/arm/boot/dts/ls1021a.dtsi                     |  10 +
 drivers/video/fbdev/Kconfig                        |  19 +
 drivers/video/fbdev/Makefile                       |   1 +
 drivers/video/fbdev/fsl-dcfb.c                     | 814 +++++++++++++++++++++
 6 files changed, 922 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt
 create mode 100644 drivers/video/fbdev/fsl-dcfb.c

-- 
2.1.0.27.g96db324


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

* [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-03  9:15 ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

Framebuffer driver for the Freescale SoC Display Controller.


Change in V2:
- Use the native-mode timing as default.
- Add to_fsl_private().


Xiubo Li (4):
  video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
  video: fsl-dcfb: Add devicetree binding support
  ARM: ls1021a: dtsi: Add dt node support for dcfb.
  ARM: ls1021a: dts: Add and enable dt node for dcfb.

 .../devicetree/bindings/video/fsl,dcfb.txt         |  52 ++
 arch/arm/boot/dts/ls1021a-twr.dts                  |  26 +
 arch/arm/boot/dts/ls1021a.dtsi                     |  10 +
 drivers/video/fbdev/Kconfig                        |  19 +
 drivers/video/fbdev/Makefile                       |   1 +
 drivers/video/fbdev/fsl-dcfb.c                     | 814 +++++++++++++++++++++
 6 files changed, 922 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt
 create mode 100644 drivers/video/fbdev/fsl-dcfb.c

-- 
2.1.0.27.g96db324

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

* [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
  2014-12-03  9:15 ` Xiubo Li
  (?)
@ 2014-12-03  9:15   ` Xiubo Li
  -1 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:15 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel,
	linux-kernel, Xiubo Li

The Display Controller module is a system master that fetches graphics
stored in internal/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 configurable.

The dcfb has these features:
o Full RGB888 output to TFT LCD panel.
o Optional output to system memory dependent on implementation.
o Supports Programmable panel size upto a maximum of 2032x2047. The actual
  resolution supported depends upon the pixel clock and bus bandwidth
  available.
o Gamma correction with 8-bit resolution on each color component.
o Dedicated memory blocks to store a cursor and Color Look Up Tables(CLUTs).
o Temporal Dithering.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 drivers/video/fbdev/Kconfig    |  19 +
 drivers/video/fbdev/Makefile   |   1 +
 drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 834 insertions(+)
 create mode 100644 drivers/video/fbdev/fsl-dcfb.c

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 4916c97..460fe39 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1948,6 +1948,25 @@ config FB_MBX_DEBUG
 
          If unsure, say N.
 
+config FB_FSL_DCFB
+	tristate "Freescale Display Control Framebuffer Support"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	select REGMAP_MMIO
+	---help---
+	  Framebuffer driver for the Freescale SoC Display Control.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want).
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+
 config FB_FSL_DIU
 	tristate "Freescale DIU framebuffer support"
 	depends on FB && FSL_SOC
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 1979aff..9015138 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
 obj-$(CONFIG_FB_IMX)              += imxfb.o
 obj-$(CONFIG_FB_S3C)		  += s3c-fb.o
 obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
+obj-$(CONFIG_FB_FSL_DCFB)	  += fsl-dcfb.o
 obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
 obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
 obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
diff --git a/drivers/video/fbdev/fsl-dcfb.c b/drivers/video/fbdev/fsl-dcfb.c
new file mode 100644
index 0000000..c3843bf
--- /dev/null
+++ b/drivers/video/fbdev/fsl-dcfb.c
@@ -0,0 +1,814 @@
+/*
+ * Copyright 2012-2014 Freescale Semiconductor, Inc.
+ *
+ * Freescale Dispaly Controller Framebuffer 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/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
+
+#define FSL_SCFG_CTRL		0x28
+#define FSL_SCFG_PIXEL_EN	BIT(31)
+
+#define FSL_DCFB_MODE		0x10
+#define FSL_DCFB_BGND		0x14
+#define FSL_DCFB_FIX_SIZE	0x18
+#define FSL_DCFB_HSYN		0x1c
+#define FSL_DCFB_VSYN		0x20
+#define FSL_DCFB_SP		0x24
+#define FSL_DCFB_TS		0x28
+#define FSL_DCFB_DIV_RATIO	0x54
+#define FSL_DCFB_UPDATE		0xcc
+#define FSL_DCFB_VAR_SIZE	0x200
+#define FSL_DCFB_POS		0x204
+#define FSL_DCFB_BASE		0x208
+#define FSL_DCFB_CTRL		0x20c
+#define FSL_DCFB_CKMAX		0x210
+#define FSL_DCFB_CKMIN		0x214
+#define FSL_DCFB_FCOLOR		0x21c
+#define FSL_DCFB_BCOLOR		0x220
+#define FSL_DCFB_SKIP		0x224
+#define FSL_DCFB_MAX		0x300
+
+#define FSL_DCFB_HSYN_BP(x)	((x) << 22)
+#define FSL_DCFB_HSYN_PW(x)	((x) << 11)
+#define FSL_DCFB_HSYN_FP(x)	(x)
+#define FSL_DCFB_VSYN_BP(x)	((x) << 22)
+#define FSL_DCFB_VSYN_PW(x)	((x) << 11)
+#define FSL_DCFB_VSYN_FP(x)	(x)
+
+#define FSL_DCFB_SP_VS		BIT(1)
+#define FSL_DCFB_SP_HS		BIT(0)
+
+#define FSL_DCFB_TS_LBV(x)	((x) << 16)
+#define FSL_DCFB_TS_OBH(x)	((x) << 8)
+#define FSL_DCFB_TS_OBL(x)	(x)
+
+#define FSL_DCFB_UPDATE_MODE	BIT(31)
+#define FSL_DCFB_UPDATE_READREG	BIT(30)
+
+#define FSL_DCFB_VAR_SIZE_H(x)	((x) << 16)
+#define FSL_DCFB_VAR_SIZE_W(x)	(x)
+
+#define FSL_DCFB_POSY(x)	((x) << 16)
+#define FSL_DCFB_POSX(x)	(x)
+
+#define FSL_DCFB_CTRL_EN	BIT(31)
+#define FSL_DCFB_CTRL_TILE_EN	BIT(30)
+#define FSL_DCFB_CTRL_DATA_SEL_CLUT	BIT(29)
+#define FSL_DCFB_CTRL_SAFETY_EN	BIT(28)
+#define FSL_DCFB_CTRL_TRANS(x)	((x) << 20)
+#define FSL_DCFB_CTRL_BPP(x)	((x) << 16)
+#define FSL_DCFB_CTRL_RLE_EN	BIT(15)
+#define FSL_DCFB_CTRL_LUOFFS(x)	((x) << 4)
+#define FSL_DCFB_CTRL_BB_ON	BIT(2)
+
+#define FSL_DCFB_CKMAX_R(x)	((x) << 16)
+#define FSL_DCFB_CKMAX_G(x)	((x) << 8)
+#define FSL_DCFB_CKMAX_B(x)	(x)
+
+#define FSL_DCFB_CKMIN_R(x)	((x) << 16)
+#define FSL_DCFB_CKMIN_G(x)	((x) << 8)
+#define FSL_DCFB_CKMIN_B(x)	(x)
+
+#define FSL_DCFB_TILE_SIZE_W(x)	((x) << 16)
+#define FSL_DCFB_TILE_SIZE_H(x)	(x)
+
+#define FSL_DCFB_FCOLOR_OFF(x)	(x)
+#define FSL_DCFB_BCOLOR_OFF(x)	(x)
+
+#define FSL_DCFB_MODE_BITER(x)	((x) << 20)
+#define FSL_DCFB_MODE_RASTER_EN	BIT(14)
+#define FSL_DCFB_MODE_MODE(x)	(x)
+#define FSL_DCFB_MODE_MODE_MASK	0x03
+
+#define FSL_DCFB_BGND_R(x)	((x) << 16)
+#define FSL_DCFB_BGND_G(x)	((x) << 8)
+#define FSL_DCFB_BGND_B(x)	(x)
+
+#define FSL_DCFB_FIX_SIZE_Y(x)	((x) << 16)
+#define FSL_DCFB_FIX_SIZE_X(x)	(x)
+
+enum fsl_dcfb_fmt {
+	FSL_DCFB_RGB565 = 4,
+	FSL_DCFB_RGB888,
+	FSL_DCFB_ARGB8888,
+};
+
+enum fsl_dcfb_mode {
+	FSL_DCFB_MOD_OFF = 0,
+	FSL_DCFB_MOD_NORMAL,
+	FSL_DCFB_MOD_TEST,
+	FSL_DCFB_MOD_COLORBAR,
+};
+
+struct fsl_dcfb_fb_private {
+	struct fb_info *fsl_dcfb_info;
+	struct device *dev;
+	struct regmap *regmap;
+	struct clk *clk;
+};
+
+struct fsl_dcfb_fb_info {
+	unsigned long pseudo_palette[16];
+	unsigned int count;
+	struct fsl_dcfb_fb_private *parent;
+};
+
+static inline struct fsl_dcfb_fb_private *to_fsl_private(struct fb_info *info)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+
+	return (struct fsl_dcfb_fb_private *)fsl_info->parent;
+}
+
+static int fsl_dcfb_get_bpp(unsigned int bits_per_pixel)
+{
+	int bpp;
+
+	switch (bits_per_pixel) {
+	case 16:
+		bpp = FSL_DCFB_RGB565;
+		break;
+	case 24:
+		bpp = FSL_DCFB_RGB888;
+		break;
+	case 32:
+		bpp = FSL_DCFB_ARGB8888;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return bpp;
+}
+
+static int fsl_dcfb_set_panel(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	int bpp;
+
+	regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE,
+		     FSL_DCFB_VAR_SIZE_H(var->yres) |
+		     FSL_DCFB_VAR_SIZE_W(var->xres));
+	regmap_write(dcfb->regmap, FSL_DCFB_POS,
+		     FSL_DCFB_POSY(0) | FSL_DCFB_POSX(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, info->fix.smem_start);
+
+	bpp = fsl_dcfb_get_bpp(var->bits_per_pixel);
+	if (bpp < 0) {
+		dev_err(dcfb->dev, "unsupported color depth: %u\n",
+				var->bits_per_pixel);
+		return bpp;
+	}
+
+	regmap_write(dcfb->regmap, FSL_DCFB_CTRL, FSL_DCFB_CTRL_EN |
+		     FSL_DCFB_CTRL_TRANS(0xFF) | FSL_DCFB_CTRL_BPP(bpp));
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, FSL_DCFB_CKMAX_R(0xFF) |
+		     FSL_DCFB_CKMAX_G(0xFF) | FSL_DCFB_CKMAX_B(0xFF));
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, FSL_DCFB_CKMIN_R(0) |
+		     FSL_DCFB_CKMIN_G(0) | FSL_DCFB_CKMIN_B(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, FSL_DCFB_FCOLOR_OFF(0));
+	regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, FSL_DCFB_BCOLOR_OFF(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static int fsl_dcfb_reset_panel(struct fsl_dcfb_fb_private *dcfb)
+{
+	regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_POS, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CTRL, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_SKIP, 0x0);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static void fsl_dcfb_modeset(struct fsl_dcfb_fb_private *dcfb,
+			     enum fsl_dcfb_mode mode)
+{
+	regmap_update_bits(dcfb->regmap, FSL_DCFB_MODE,
+			   FSL_DCFB_MODE_MODE_MASK,
+			   FSL_DCFB_MODE_MODE(mode));
+}
+
+static int fsl_dcfb_check_var(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+
+	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(dcfb->dev, "unsupported color depth: %u\n",
+			var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int fsl_dcfb_alloc_mem(struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	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(dcfb->dev, "unable to allocate fb memory\n");
+		return -ENOMEM;
+	}
+
+	memset(info->screen_base, 0, info->fix.smem_len);
+
+	return 0;
+}
+
+static void fsl_dcfb_free_mem(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_dcfb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fb_fix_screeninfo *fix = &info->fix;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	unsigned int div, len;
+
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->accel = FB_ACCEL_NONE;
+	fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->xpanstep = fix->ypanstep = 1;
+
+	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+	len = info->var.yres_virtual * info->fix.line_length;
+	if (len != info->fix.smem_len) {
+		if (info->fix.smem_start)
+			fsl_dcfb_free_mem(info);
+
+		if (fsl_dcfb_alloc_mem(info)) {
+			dev_err(dcfb->dev, "unable to allocate FB memory\n");
+			return -ENOMEM;
+		}
+	}
+
+	div = KHZ2PICOS(clk_get_rate(dcfb->clk) / 1000);
+	regmap_write(dcfb->regmap, FSL_DCFB_DIV_RATIO,
+		     info->var.pixclock / div);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_FIX_SIZE,
+		     FSL_DCFB_FIX_SIZE_Y(var->yres) |
+		     FSL_DCFB_FIX_SIZE_X(var->xres / 16));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_HSYN,
+		     FSL_DCFB_HSYN_BP(var->left_margin) |
+		     FSL_DCFB_HSYN_PW(var->hsync_len) |
+		     FSL_DCFB_HSYN_FP(var->right_margin));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_VSYN,
+		     FSL_DCFB_VSYN_BP(var->upper_margin) |
+		     FSL_DCFB_VSYN_PW(var->vsync_len) |
+		     FSL_DCFB_VSYN_FP(var->lower_margin));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_SP,
+		     FSL_DCFB_SP_VS | FSL_DCFB_SP_HS);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BGND, FSL_DCFB_BGND_R(0) |
+		     FSL_DCFB_BGND_G(0) | FSL_DCFB_BGND_B(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_MODE,
+		     FSL_DCFB_MODE_BITER(1) | FSL_DCFB_MODE_RASTER_EN);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_TS, FSL_DCFB_TS_LBV(0x03) |
+		     FSL_DCFB_TS_OBH(0x78) | FSL_DCFB_TS_OBL(0x0A));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_NORMAL);
+	fsl_dcfb_set_panel(info);
+
+	return 0;
+}
+
+#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
+static int fsl_dcfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *info)
+{
+	int ret = 1;
+
+	/*
+	 * 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:
+		if (regno < 16) {
+			u32 *pal = info->pseudo_palette;
+			u32 value;
+
+			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);
+
+			value = (red << info->var.red.offset) |
+				(green << info->var.green.offset) |
+				(blue << info->var.blue.offset) |
+				(transp << info->var.transp.offset);
+
+			pal[regno] = value;
+			ret = 0;
+		}
+		break;
+	case FB_VISUAL_STATIC_PSEUDOCOLOR:
+	case FB_VISUAL_PSEUDOCOLOR:
+		break;
+	}
+
+	return ret;
+}
+#undef CNVT_TOHW
+
+static int fsl_dcfb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	unsigned long addr;
+	int offset;
+
+	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;
+
+	offset = (info->var.yoffset * info->var.xres_virtual);
+	offset += info->var.xoffset;
+	addr = info->fix.smem_start +
+		(offset * (info->var.bits_per_pixel >> 3));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, addr);
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static int fsl_dcfb_blank(int blank_mode, struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+
+	switch (blank_mode) {
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		fsl_dcfb_reset_panel(dcfb);
+		break;
+	case FB_BLANK_POWERDOWN:
+		fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF);
+		break;
+	case FB_BLANK_UNBLANK:
+		fsl_dcfb_set_panel(info);
+		break;
+	}
+
+	return 0;
+}
+
+static int fsl_dcfb_open(struct fb_info *info, int user)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+	int ret = 0;
+
+	fsl_info->count++;
+	if (fsl_info->count == 1) {
+		fsl_dcfb_check_var(&info->var, info);
+		ret = fsl_dcfb_set_par(info);
+		if (ret < 0)
+			fsl_info->count--;
+	}
+
+	return ret;
+}
+
+static int fsl_dcfb_release(struct fb_info *info, int user)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	int ret = 0;
+
+	fsl_info->count--;
+	if (fsl_info->count == 0)
+		ret = fsl_dcfb_reset_panel(dcfb);
+
+	return ret;
+}
+
+static struct fb_ops fsl_dcfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = fsl_dcfb_check_var,
+	.fb_set_par = fsl_dcfb_set_par,
+	.fb_setcolreg = fsl_dcfb_setcolreg,
+	.fb_blank = fsl_dcfb_blank,
+	.fb_pan_display = fsl_dcfb_pan_display,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_open = fsl_dcfb_open,
+	.fb_release = fsl_dcfb_release,
+};
+
+static int fsl_dcfb_init_fbinfo(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	struct device_node *np = dcfb->dev->of_node;
+	struct device_node *dnp, *tnp;
+	struct display_timings *timings;
+	struct fb_videomode fb_vm;
+	int i, ret;
+
+	INIT_LIST_HEAD(&info->modelist);
+
+	dnp = of_parse_phandle(np, "display", 0);
+	if (!dnp) {
+		dev_err(dcfb->dev, "failed to find \"display\" phandle.\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(dnp, "bits-per-pixel",
+				   &var->bits_per_pixel);
+	if (ret < 0) {
+		dev_err(dcfb->dev, "failed to get \"bits-per-pixel\" property.\n");
+		goto put_dnp;
+	}
+
+	timings = of_get_display_timings(dnp);
+	if (!timings) {
+		dev_err(dcfb->dev, "failed to get display timings\n");
+		return -ENODEV;
+		goto put_dnp;
+	}
+
+	tnp = of_find_node_by_name(dnp, "display-timings");
+	if (!tnp) {
+		dev_err(dcfb->dev, "failed to find \"display-timings\" node\n");
+		return -ENODEV;
+		goto put_dnp;
+	}
+
+	for (i = 0; i < of_get_child_count(tnp); i++) {
+		struct videomode vm;
+
+		ret = videomode_from_timings(timings, &vm, i);
+		if (ret < 0)
+			goto put_tnp;
+
+		ret = fb_videomode_from_videomode(&vm, &fb_vm);
+		if (ret < 0)
+			goto put_tnp;
+
+		fb_add_videomode(&fb_vm, &info->modelist);
+	}
+
+	ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE);
+	if (ret)
+		goto put_dnp;
+
+	fb_videomode_to_var(&info->var, &fb_vm);
+	ret = fsl_dcfb_check_var(&info->var, info);
+
+put_tnp:
+	of_node_put(tnp);
+put_dnp:
+	of_node_put(dnp);
+
+	return ret;
+}
+
+static const struct regmap_config fsl_scfg_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.max_register = FSL_SCFG_CTRL,
+};
+
+static int scfg_config(struct fsl_dcfb_fb_private *dcfb, struct device_node *np)
+{
+	struct device_node *snp;
+	struct platform_device *pdev;
+	struct resource *res;
+	void __iomem *base;
+	struct regmap *regmap;
+	int ret = 0;
+
+	snp = of_parse_phandle(np, "scfg-controller", 0);
+	if (!snp)
+		return -ENODEV;
+
+	pdev = of_find_device_by_node(snp);
+	if (!pdev) {
+		ret = -ENODEV;
+		goto put_snp;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		goto put_snp;
+	}
+
+	base = ioremap(res->start, SZ_4K);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "could not ioremap scfg resource\n");
+		ret = PTR_ERR(base);
+		goto put_snp;
+	}
+
+	regmap = regmap_init_mmio(&pdev->dev, base,
+				  &fsl_scfg_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		ret = PTR_ERR(regmap);
+		goto ioremap;
+	}
+
+	regmap_write(regmap, FSL_SCFG_CTRL, FSL_SCFG_PIXEL_EN);
+
+	regmap_exit(regmap);
+ioremap:
+	iounmap(base);
+put_snp:
+	of_node_put(snp);
+
+	return ret;
+}
+
+static int fsl_dcfb_dev_init(struct device_node *np,
+			     struct fsl_dcfb_fb_private *dcfb)
+{
+	int ret;
+
+	ret = scfg_config(dcfb, np);
+	if (ret) {
+		dev_err(dcfb->dev, "could not config scfg\n");
+		return -EINVAL;
+	}
+
+	return fsl_dcfb_reset_panel(dcfb);
+}
+
+static const struct regmap_config fsl_dcfb_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.max_register = FSL_DCFB_MAX,
+};
+
+static int fsl_dcfb_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct fsl_dcfb_fb_private *dcfb;
+	struct fsl_dcfb_fb_info *fsl_info;
+	struct fb_info *info;
+	struct resource *res;
+	void __iomem *base;
+	int ret = 0;
+
+	dcfb = devm_kzalloc(&pdev->dev,
+		sizeof(struct fsl_dcfb_fb_private), GFP_KERNEL);
+	if (!dcfb)
+		return -ENOMEM;
+
+	dcfb->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "could not get memory IO resource\n");
+		return -ENODEV;
+	}
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "could not ioremap resource\n");
+		return PTR_ERR(base);
+	}
+
+	dcfb->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+				NULL, base, &fsl_dcfb_regmap_config);
+	if (IS_ERR(dcfb->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(dcfb->regmap);
+	}
+
+	dcfb->clk = devm_clk_get(&pdev->dev, "dcfb");
+	if (IS_ERR(dcfb->clk)) {
+		ret = PTR_ERR(dcfb->clk);
+		dev_err(&pdev->dev, "could not get clock\n");
+		return -EINVAL;
+	}
+	clk_prepare_enable(dcfb->clk);
+
+	fsl_dcfb_dev_init(np, dcfb);
+
+	dcfb->fsl_dcfb_info =
+		framebuffer_alloc(sizeof(struct fsl_dcfb_fb_info), &pdev->dev);
+	if (!dcfb->fsl_dcfb_info) {
+		ret = -ENOMEM;
+		goto err_clk;
+	}
+
+	dcfb->fsl_dcfb_info->fix.smem_start = 0;
+
+	fsl_info = dcfb->fsl_dcfb_info->par;
+	fsl_info->count = 0,
+	fsl_info->parent = dcfb;
+
+	info = dcfb->fsl_dcfb_info;
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->fbops = &fsl_dcfb_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->pseudo_palette = &fsl_info->pseudo_palette;
+
+	ret = fb_alloc_cmap(&info->cmap, 16, 0);
+	if (ret) {
+		ret = -ENOMEM;
+		goto err_mem;
+	}
+
+	ret = fsl_dcfb_init_fbinfo(info);
+	if (ret)
+		goto err_cmap;
+
+	ret = register_framebuffer(info);
+	if (ret < 0) {
+		dev_err(dcfb->dev, "failed to register framebuffer device\n");
+		goto err_cmap;
+	}
+
+	dev_set_drvdata(&pdev->dev, dcfb);
+
+	goto out;
+
+err_cmap:
+	fb_dealloc_cmap(&info->cmap);
+err_mem:
+	framebuffer_release(dcfb->fsl_dcfb_info);
+err_clk:
+	clk_disable_unprepare(dcfb->clk);
+out:
+	return ret;
+}
+
+static int fsl_dcfb_remove(struct platform_device *pdev)
+{
+	struct fsl_dcfb_fb_private *dcfb = dev_get_drvdata(&pdev->dev);
+	struct fb_info *info = dcfb->fsl_dcfb_info;
+
+	fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF);
+	fsl_dcfb_free_mem(info);
+
+	unregister_framebuffer(info);
+	fb_dealloc_cmap(&info->cmap);
+	framebuffer_release(dcfb->fsl_dcfb_info);
+	clk_disable_unprepare(dcfb->clk);
+
+	return 0;
+}
+
+static struct of_device_id fsl_dcfb_dt_ids[] = {
+	{ .compatible = "fsl,ls1021a-dcfb", },
+	{}
+};
+
+static struct platform_driver fsl_dcfb_driver = {
+	.driver = {
+		.name = "fsl-dcfb",
+		.owner = THIS_MODULE,
+		.of_match_table = fsl_dcfb_dt_ids,
+	},
+	.probe = fsl_dcfb_probe,
+	.remove = fsl_dcfb_remove,
+};
+
+module_platform_driver(fsl_dcfb_driver);
+
+MODULE_DESCRIPTION("Freescale Simple Display Controller FB Driver");
+MODULE_ALIAS("platform:fsl-dcfb");
+MODULE_LICENSE("GPL v2");
-- 
2.1.0.27.g96db324


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

* [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
@ 2014-12-03  9:15   ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

The Display Controller module is a system master that fetches graphics
stored in internal/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 configurable.

The dcfb has these features:
o Full RGB888 output to TFT LCD panel.
o Optional output to system memory dependent on implementation.
o Supports Programmable panel size upto a maximum of 2032x2047. The actual
  resolution supported depends upon the pixel clock and bus bandwidth
  available.
o Gamma correction with 8-bit resolution on each color component.
o Dedicated memory blocks to store a cursor and Color Look Up Tables(CLUTs).
o Temporal Dithering.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 drivers/video/fbdev/Kconfig    |  19 +
 drivers/video/fbdev/Makefile   |   1 +
 drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 834 insertions(+)
 create mode 100644 drivers/video/fbdev/fsl-dcfb.c

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 4916c97..460fe39 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1948,6 +1948,25 @@ config FB_MBX_DEBUG
 
          If unsure, say N.
 
+config FB_FSL_DCFB
+	tristate "Freescale Display Control Framebuffer Support"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	select REGMAP_MMIO
+	---help---
+	  Framebuffer driver for the Freescale SoC Display Control.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want).
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+
 config FB_FSL_DIU
 	tristate "Freescale DIU framebuffer support"
 	depends on FB && FSL_SOC
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 1979aff..9015138 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
 obj-$(CONFIG_FB_IMX)              += imxfb.o
 obj-$(CONFIG_FB_S3C)		  += s3c-fb.o
 obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
+obj-$(CONFIG_FB_FSL_DCFB)	  += fsl-dcfb.o
 obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
 obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
 obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
diff --git a/drivers/video/fbdev/fsl-dcfb.c b/drivers/video/fbdev/fsl-dcfb.c
new file mode 100644
index 0000000..c3843bf
--- /dev/null
+++ b/drivers/video/fbdev/fsl-dcfb.c
@@ -0,0 +1,814 @@
+/*
+ * Copyright 2012-2014 Freescale Semiconductor, Inc.
+ *
+ * Freescale Dispaly Controller Framebuffer 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/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
+
+#define FSL_SCFG_CTRL		0x28
+#define FSL_SCFG_PIXEL_EN	BIT(31)
+
+#define FSL_DCFB_MODE		0x10
+#define FSL_DCFB_BGND		0x14
+#define FSL_DCFB_FIX_SIZE	0x18
+#define FSL_DCFB_HSYN		0x1c
+#define FSL_DCFB_VSYN		0x20
+#define FSL_DCFB_SP		0x24
+#define FSL_DCFB_TS		0x28
+#define FSL_DCFB_DIV_RATIO	0x54
+#define FSL_DCFB_UPDATE		0xcc
+#define FSL_DCFB_VAR_SIZE	0x200
+#define FSL_DCFB_POS		0x204
+#define FSL_DCFB_BASE		0x208
+#define FSL_DCFB_CTRL		0x20c
+#define FSL_DCFB_CKMAX		0x210
+#define FSL_DCFB_CKMIN		0x214
+#define FSL_DCFB_FCOLOR		0x21c
+#define FSL_DCFB_BCOLOR		0x220
+#define FSL_DCFB_SKIP		0x224
+#define FSL_DCFB_MAX		0x300
+
+#define FSL_DCFB_HSYN_BP(x)	((x) << 22)
+#define FSL_DCFB_HSYN_PW(x)	((x) << 11)
+#define FSL_DCFB_HSYN_FP(x)	(x)
+#define FSL_DCFB_VSYN_BP(x)	((x) << 22)
+#define FSL_DCFB_VSYN_PW(x)	((x) << 11)
+#define FSL_DCFB_VSYN_FP(x)	(x)
+
+#define FSL_DCFB_SP_VS		BIT(1)
+#define FSL_DCFB_SP_HS		BIT(0)
+
+#define FSL_DCFB_TS_LBV(x)	((x) << 16)
+#define FSL_DCFB_TS_OBH(x)	((x) << 8)
+#define FSL_DCFB_TS_OBL(x)	(x)
+
+#define FSL_DCFB_UPDATE_MODE	BIT(31)
+#define FSL_DCFB_UPDATE_READREG	BIT(30)
+
+#define FSL_DCFB_VAR_SIZE_H(x)	((x) << 16)
+#define FSL_DCFB_VAR_SIZE_W(x)	(x)
+
+#define FSL_DCFB_POSY(x)	((x) << 16)
+#define FSL_DCFB_POSX(x)	(x)
+
+#define FSL_DCFB_CTRL_EN	BIT(31)
+#define FSL_DCFB_CTRL_TILE_EN	BIT(30)
+#define FSL_DCFB_CTRL_DATA_SEL_CLUT	BIT(29)
+#define FSL_DCFB_CTRL_SAFETY_EN	BIT(28)
+#define FSL_DCFB_CTRL_TRANS(x)	((x) << 20)
+#define FSL_DCFB_CTRL_BPP(x)	((x) << 16)
+#define FSL_DCFB_CTRL_RLE_EN	BIT(15)
+#define FSL_DCFB_CTRL_LUOFFS(x)	((x) << 4)
+#define FSL_DCFB_CTRL_BB_ON	BIT(2)
+
+#define FSL_DCFB_CKMAX_R(x)	((x) << 16)
+#define FSL_DCFB_CKMAX_G(x)	((x) << 8)
+#define FSL_DCFB_CKMAX_B(x)	(x)
+
+#define FSL_DCFB_CKMIN_R(x)	((x) << 16)
+#define FSL_DCFB_CKMIN_G(x)	((x) << 8)
+#define FSL_DCFB_CKMIN_B(x)	(x)
+
+#define FSL_DCFB_TILE_SIZE_W(x)	((x) << 16)
+#define FSL_DCFB_TILE_SIZE_H(x)	(x)
+
+#define FSL_DCFB_FCOLOR_OFF(x)	(x)
+#define FSL_DCFB_BCOLOR_OFF(x)	(x)
+
+#define FSL_DCFB_MODE_BITER(x)	((x) << 20)
+#define FSL_DCFB_MODE_RASTER_EN	BIT(14)
+#define FSL_DCFB_MODE_MODE(x)	(x)
+#define FSL_DCFB_MODE_MODE_MASK	0x03
+
+#define FSL_DCFB_BGND_R(x)	((x) << 16)
+#define FSL_DCFB_BGND_G(x)	((x) << 8)
+#define FSL_DCFB_BGND_B(x)	(x)
+
+#define FSL_DCFB_FIX_SIZE_Y(x)	((x) << 16)
+#define FSL_DCFB_FIX_SIZE_X(x)	(x)
+
+enum fsl_dcfb_fmt {
+	FSL_DCFB_RGB565 = 4,
+	FSL_DCFB_RGB888,
+	FSL_DCFB_ARGB8888,
+};
+
+enum fsl_dcfb_mode {
+	FSL_DCFB_MOD_OFF = 0,
+	FSL_DCFB_MOD_NORMAL,
+	FSL_DCFB_MOD_TEST,
+	FSL_DCFB_MOD_COLORBAR,
+};
+
+struct fsl_dcfb_fb_private {
+	struct fb_info *fsl_dcfb_info;
+	struct device *dev;
+	struct regmap *regmap;
+	struct clk *clk;
+};
+
+struct fsl_dcfb_fb_info {
+	unsigned long pseudo_palette[16];
+	unsigned int count;
+	struct fsl_dcfb_fb_private *parent;
+};
+
+static inline struct fsl_dcfb_fb_private *to_fsl_private(struct fb_info *info)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+
+	return (struct fsl_dcfb_fb_private *)fsl_info->parent;
+}
+
+static int fsl_dcfb_get_bpp(unsigned int bits_per_pixel)
+{
+	int bpp;
+
+	switch (bits_per_pixel) {
+	case 16:
+		bpp = FSL_DCFB_RGB565;
+		break;
+	case 24:
+		bpp = FSL_DCFB_RGB888;
+		break;
+	case 32:
+		bpp = FSL_DCFB_ARGB8888;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return bpp;
+}
+
+static int fsl_dcfb_set_panel(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	int bpp;
+
+	regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE,
+		     FSL_DCFB_VAR_SIZE_H(var->yres) |
+		     FSL_DCFB_VAR_SIZE_W(var->xres));
+	regmap_write(dcfb->regmap, FSL_DCFB_POS,
+		     FSL_DCFB_POSY(0) | FSL_DCFB_POSX(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, info->fix.smem_start);
+
+	bpp = fsl_dcfb_get_bpp(var->bits_per_pixel);
+	if (bpp < 0) {
+		dev_err(dcfb->dev, "unsupported color depth: %u\n",
+				var->bits_per_pixel);
+		return bpp;
+	}
+
+	regmap_write(dcfb->regmap, FSL_DCFB_CTRL, FSL_DCFB_CTRL_EN |
+		     FSL_DCFB_CTRL_TRANS(0xFF) | FSL_DCFB_CTRL_BPP(bpp));
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, FSL_DCFB_CKMAX_R(0xFF) |
+		     FSL_DCFB_CKMAX_G(0xFF) | FSL_DCFB_CKMAX_B(0xFF));
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, FSL_DCFB_CKMIN_R(0) |
+		     FSL_DCFB_CKMIN_G(0) | FSL_DCFB_CKMIN_B(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, FSL_DCFB_FCOLOR_OFF(0));
+	regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, FSL_DCFB_BCOLOR_OFF(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static int fsl_dcfb_reset_panel(struct fsl_dcfb_fb_private *dcfb)
+{
+	regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_POS, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CTRL, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_SKIP, 0x0);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static void fsl_dcfb_modeset(struct fsl_dcfb_fb_private *dcfb,
+			     enum fsl_dcfb_mode mode)
+{
+	regmap_update_bits(dcfb->regmap, FSL_DCFB_MODE,
+			   FSL_DCFB_MODE_MODE_MASK,
+			   FSL_DCFB_MODE_MODE(mode));
+}
+
+static int fsl_dcfb_check_var(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+
+	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(dcfb->dev, "unsupported color depth: %u\n",
+			var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int fsl_dcfb_alloc_mem(struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	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(dcfb->dev, "unable to allocate fb memory\n");
+		return -ENOMEM;
+	}
+
+	memset(info->screen_base, 0, info->fix.smem_len);
+
+	return 0;
+}
+
+static void fsl_dcfb_free_mem(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_dcfb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fb_fix_screeninfo *fix = &info->fix;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	unsigned int div, len;
+
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->accel = FB_ACCEL_NONE;
+	fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->xpanstep = fix->ypanstep = 1;
+
+	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+	len = info->var.yres_virtual * info->fix.line_length;
+	if (len != info->fix.smem_len) {
+		if (info->fix.smem_start)
+			fsl_dcfb_free_mem(info);
+
+		if (fsl_dcfb_alloc_mem(info)) {
+			dev_err(dcfb->dev, "unable to allocate FB memory\n");
+			return -ENOMEM;
+		}
+	}
+
+	div = KHZ2PICOS(clk_get_rate(dcfb->clk) / 1000);
+	regmap_write(dcfb->regmap, FSL_DCFB_DIV_RATIO,
+		     info->var.pixclock / div);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_FIX_SIZE,
+		     FSL_DCFB_FIX_SIZE_Y(var->yres) |
+		     FSL_DCFB_FIX_SIZE_X(var->xres / 16));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_HSYN,
+		     FSL_DCFB_HSYN_BP(var->left_margin) |
+		     FSL_DCFB_HSYN_PW(var->hsync_len) |
+		     FSL_DCFB_HSYN_FP(var->right_margin));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_VSYN,
+		     FSL_DCFB_VSYN_BP(var->upper_margin) |
+		     FSL_DCFB_VSYN_PW(var->vsync_len) |
+		     FSL_DCFB_VSYN_FP(var->lower_margin));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_SP,
+		     FSL_DCFB_SP_VS | FSL_DCFB_SP_HS);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BGND, FSL_DCFB_BGND_R(0) |
+		     FSL_DCFB_BGND_G(0) | FSL_DCFB_BGND_B(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_MODE,
+		     FSL_DCFB_MODE_BITER(1) | FSL_DCFB_MODE_RASTER_EN);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_TS, FSL_DCFB_TS_LBV(0x03) |
+		     FSL_DCFB_TS_OBH(0x78) | FSL_DCFB_TS_OBL(0x0A));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_NORMAL);
+	fsl_dcfb_set_panel(info);
+
+	return 0;
+}
+
+#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
+static int fsl_dcfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *info)
+{
+	int ret = 1;
+
+	/*
+	 * 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:
+		if (regno < 16) {
+			u32 *pal = info->pseudo_palette;
+			u32 value;
+
+			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);
+
+			value = (red << info->var.red.offset) |
+				(green << info->var.green.offset) |
+				(blue << info->var.blue.offset) |
+				(transp << info->var.transp.offset);
+
+			pal[regno] = value;
+			ret = 0;
+		}
+		break;
+	case FB_VISUAL_STATIC_PSEUDOCOLOR:
+	case FB_VISUAL_PSEUDOCOLOR:
+		break;
+	}
+
+	return ret;
+}
+#undef CNVT_TOHW
+
+static int fsl_dcfb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	unsigned long addr;
+	int offset;
+
+	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;
+
+	offset = (info->var.yoffset * info->var.xres_virtual);
+	offset += info->var.xoffset;
+	addr = info->fix.smem_start +
+		(offset * (info->var.bits_per_pixel >> 3));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, addr);
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static int fsl_dcfb_blank(int blank_mode, struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+
+	switch (blank_mode) {
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		fsl_dcfb_reset_panel(dcfb);
+		break;
+	case FB_BLANK_POWERDOWN:
+		fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF);
+		break;
+	case FB_BLANK_UNBLANK:
+		fsl_dcfb_set_panel(info);
+		break;
+	}
+
+	return 0;
+}
+
+static int fsl_dcfb_open(struct fb_info *info, int user)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+	int ret = 0;
+
+	fsl_info->count++;
+	if (fsl_info->count = 1) {
+		fsl_dcfb_check_var(&info->var, info);
+		ret = fsl_dcfb_set_par(info);
+		if (ret < 0)
+			fsl_info->count--;
+	}
+
+	return ret;
+}
+
+static int fsl_dcfb_release(struct fb_info *info, int user)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	int ret = 0;
+
+	fsl_info->count--;
+	if (fsl_info->count = 0)
+		ret = fsl_dcfb_reset_panel(dcfb);
+
+	return ret;
+}
+
+static struct fb_ops fsl_dcfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = fsl_dcfb_check_var,
+	.fb_set_par = fsl_dcfb_set_par,
+	.fb_setcolreg = fsl_dcfb_setcolreg,
+	.fb_blank = fsl_dcfb_blank,
+	.fb_pan_display = fsl_dcfb_pan_display,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_open = fsl_dcfb_open,
+	.fb_release = fsl_dcfb_release,
+};
+
+static int fsl_dcfb_init_fbinfo(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	struct device_node *np = dcfb->dev->of_node;
+	struct device_node *dnp, *tnp;
+	struct display_timings *timings;
+	struct fb_videomode fb_vm;
+	int i, ret;
+
+	INIT_LIST_HEAD(&info->modelist);
+
+	dnp = of_parse_phandle(np, "display", 0);
+	if (!dnp) {
+		dev_err(dcfb->dev, "failed to find \"display\" phandle.\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(dnp, "bits-per-pixel",
+				   &var->bits_per_pixel);
+	if (ret < 0) {
+		dev_err(dcfb->dev, "failed to get \"bits-per-pixel\" property.\n");
+		goto put_dnp;
+	}
+
+	timings = of_get_display_timings(dnp);
+	if (!timings) {
+		dev_err(dcfb->dev, "failed to get display timings\n");
+		return -ENODEV;
+		goto put_dnp;
+	}
+
+	tnp = of_find_node_by_name(dnp, "display-timings");
+	if (!tnp) {
+		dev_err(dcfb->dev, "failed to find \"display-timings\" node\n");
+		return -ENODEV;
+		goto put_dnp;
+	}
+
+	for (i = 0; i < of_get_child_count(tnp); i++) {
+		struct videomode vm;
+
+		ret = videomode_from_timings(timings, &vm, i);
+		if (ret < 0)
+			goto put_tnp;
+
+		ret = fb_videomode_from_videomode(&vm, &fb_vm);
+		if (ret < 0)
+			goto put_tnp;
+
+		fb_add_videomode(&fb_vm, &info->modelist);
+	}
+
+	ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE);
+	if (ret)
+		goto put_dnp;
+
+	fb_videomode_to_var(&info->var, &fb_vm);
+	ret = fsl_dcfb_check_var(&info->var, info);
+
+put_tnp:
+	of_node_put(tnp);
+put_dnp:
+	of_node_put(dnp);
+
+	return ret;
+}
+
+static const struct regmap_config fsl_scfg_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.max_register = FSL_SCFG_CTRL,
+};
+
+static int scfg_config(struct fsl_dcfb_fb_private *dcfb, struct device_node *np)
+{
+	struct device_node *snp;
+	struct platform_device *pdev;
+	struct resource *res;
+	void __iomem *base;
+	struct regmap *regmap;
+	int ret = 0;
+
+	snp = of_parse_phandle(np, "scfg-controller", 0);
+	if (!snp)
+		return -ENODEV;
+
+	pdev = of_find_device_by_node(snp);
+	if (!pdev) {
+		ret = -ENODEV;
+		goto put_snp;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		goto put_snp;
+	}
+
+	base = ioremap(res->start, SZ_4K);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "could not ioremap scfg resource\n");
+		ret = PTR_ERR(base);
+		goto put_snp;
+	}
+
+	regmap = regmap_init_mmio(&pdev->dev, base,
+				  &fsl_scfg_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		ret = PTR_ERR(regmap);
+		goto ioremap;
+	}
+
+	regmap_write(regmap, FSL_SCFG_CTRL, FSL_SCFG_PIXEL_EN);
+
+	regmap_exit(regmap);
+ioremap:
+	iounmap(base);
+put_snp:
+	of_node_put(snp);
+
+	return ret;
+}
+
+static int fsl_dcfb_dev_init(struct device_node *np,
+			     struct fsl_dcfb_fb_private *dcfb)
+{
+	int ret;
+
+	ret = scfg_config(dcfb, np);
+	if (ret) {
+		dev_err(dcfb->dev, "could not config scfg\n");
+		return -EINVAL;
+	}
+
+	return fsl_dcfb_reset_panel(dcfb);
+}
+
+static const struct regmap_config fsl_dcfb_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.max_register = FSL_DCFB_MAX,
+};
+
+static int fsl_dcfb_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct fsl_dcfb_fb_private *dcfb;
+	struct fsl_dcfb_fb_info *fsl_info;
+	struct fb_info *info;
+	struct resource *res;
+	void __iomem *base;
+	int ret = 0;
+
+	dcfb = devm_kzalloc(&pdev->dev,
+		sizeof(struct fsl_dcfb_fb_private), GFP_KERNEL);
+	if (!dcfb)
+		return -ENOMEM;
+
+	dcfb->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "could not get memory IO resource\n");
+		return -ENODEV;
+	}
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "could not ioremap resource\n");
+		return PTR_ERR(base);
+	}
+
+	dcfb->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+				NULL, base, &fsl_dcfb_regmap_config);
+	if (IS_ERR(dcfb->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(dcfb->regmap);
+	}
+
+	dcfb->clk = devm_clk_get(&pdev->dev, "dcfb");
+	if (IS_ERR(dcfb->clk)) {
+		ret = PTR_ERR(dcfb->clk);
+		dev_err(&pdev->dev, "could not get clock\n");
+		return -EINVAL;
+	}
+	clk_prepare_enable(dcfb->clk);
+
+	fsl_dcfb_dev_init(np, dcfb);
+
+	dcfb->fsl_dcfb_info +		framebuffer_alloc(sizeof(struct fsl_dcfb_fb_info), &pdev->dev);
+	if (!dcfb->fsl_dcfb_info) {
+		ret = -ENOMEM;
+		goto err_clk;
+	}
+
+	dcfb->fsl_dcfb_info->fix.smem_start = 0;
+
+	fsl_info = dcfb->fsl_dcfb_info->par;
+	fsl_info->count = 0,
+	fsl_info->parent = dcfb;
+
+	info = dcfb->fsl_dcfb_info;
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->fbops = &fsl_dcfb_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->pseudo_palette = &fsl_info->pseudo_palette;
+
+	ret = fb_alloc_cmap(&info->cmap, 16, 0);
+	if (ret) {
+		ret = -ENOMEM;
+		goto err_mem;
+	}
+
+	ret = fsl_dcfb_init_fbinfo(info);
+	if (ret)
+		goto err_cmap;
+
+	ret = register_framebuffer(info);
+	if (ret < 0) {
+		dev_err(dcfb->dev, "failed to register framebuffer device\n");
+		goto err_cmap;
+	}
+
+	dev_set_drvdata(&pdev->dev, dcfb);
+
+	goto out;
+
+err_cmap:
+	fb_dealloc_cmap(&info->cmap);
+err_mem:
+	framebuffer_release(dcfb->fsl_dcfb_info);
+err_clk:
+	clk_disable_unprepare(dcfb->clk);
+out:
+	return ret;
+}
+
+static int fsl_dcfb_remove(struct platform_device *pdev)
+{
+	struct fsl_dcfb_fb_private *dcfb = dev_get_drvdata(&pdev->dev);
+	struct fb_info *info = dcfb->fsl_dcfb_info;
+
+	fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF);
+	fsl_dcfb_free_mem(info);
+
+	unregister_framebuffer(info);
+	fb_dealloc_cmap(&info->cmap);
+	framebuffer_release(dcfb->fsl_dcfb_info);
+	clk_disable_unprepare(dcfb->clk);
+
+	return 0;
+}
+
+static struct of_device_id fsl_dcfb_dt_ids[] = {
+	{ .compatible = "fsl,ls1021a-dcfb", },
+	{}
+};
+
+static struct platform_driver fsl_dcfb_driver = {
+	.driver = {
+		.name = "fsl-dcfb",
+		.owner = THIS_MODULE,
+		.of_match_table = fsl_dcfb_dt_ids,
+	},
+	.probe = fsl_dcfb_probe,
+	.remove = fsl_dcfb_remove,
+};
+
+module_platform_driver(fsl_dcfb_driver);
+
+MODULE_DESCRIPTION("Freescale Simple Display Controller FB Driver");
+MODULE_ALIAS("platform:fsl-dcfb");
+MODULE_LICENSE("GPL v2");
-- 
2.1.0.27.g96db324


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

* [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
@ 2014-12-03  9:15   ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

The Display Controller module is a system master that fetches graphics
stored in internal/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 configurable.

The dcfb has these features:
o Full RGB888 output to TFT LCD panel.
o Optional output to system memory dependent on implementation.
o Supports Programmable panel size upto a maximum of 2032x2047. The actual
  resolution supported depends upon the pixel clock and bus bandwidth
  available.
o Gamma correction with 8-bit resolution on each color component.
o Dedicated memory blocks to store a cursor and Color Look Up Tables(CLUTs).
o Temporal Dithering.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 drivers/video/fbdev/Kconfig    |  19 +
 drivers/video/fbdev/Makefile   |   1 +
 drivers/video/fbdev/fsl-dcfb.c | 814 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 834 insertions(+)
 create mode 100644 drivers/video/fbdev/fsl-dcfb.c

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 4916c97..460fe39 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1948,6 +1948,25 @@ config FB_MBX_DEBUG
 
          If unsure, say N.
 
+config FB_FSL_DCFB
+	tristate "Freescale Display Control Framebuffer Support"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	select REGMAP_MMIO
+	---help---
+	  Framebuffer driver for the Freescale SoC Display Control.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want).
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+
 config FB_FSL_DIU
 	tristate "Freescale DIU framebuffer support"
 	depends on FB && FSL_SOC
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 1979aff..9015138 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
 obj-$(CONFIG_FB_IMX)              += imxfb.o
 obj-$(CONFIG_FB_S3C)		  += s3c-fb.o
 obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
+obj-$(CONFIG_FB_FSL_DCFB)	  += fsl-dcfb.o
 obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
 obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
 obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
diff --git a/drivers/video/fbdev/fsl-dcfb.c b/drivers/video/fbdev/fsl-dcfb.c
new file mode 100644
index 0000000..c3843bf
--- /dev/null
+++ b/drivers/video/fbdev/fsl-dcfb.c
@@ -0,0 +1,814 @@
+/*
+ * Copyright 2012-2014 Freescale Semiconductor, Inc.
+ *
+ * Freescale Dispaly Controller Framebuffer 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/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
+
+#define FSL_SCFG_CTRL		0x28
+#define FSL_SCFG_PIXEL_EN	BIT(31)
+
+#define FSL_DCFB_MODE		0x10
+#define FSL_DCFB_BGND		0x14
+#define FSL_DCFB_FIX_SIZE	0x18
+#define FSL_DCFB_HSYN		0x1c
+#define FSL_DCFB_VSYN		0x20
+#define FSL_DCFB_SP		0x24
+#define FSL_DCFB_TS		0x28
+#define FSL_DCFB_DIV_RATIO	0x54
+#define FSL_DCFB_UPDATE		0xcc
+#define FSL_DCFB_VAR_SIZE	0x200
+#define FSL_DCFB_POS		0x204
+#define FSL_DCFB_BASE		0x208
+#define FSL_DCFB_CTRL		0x20c
+#define FSL_DCFB_CKMAX		0x210
+#define FSL_DCFB_CKMIN		0x214
+#define FSL_DCFB_FCOLOR		0x21c
+#define FSL_DCFB_BCOLOR		0x220
+#define FSL_DCFB_SKIP		0x224
+#define FSL_DCFB_MAX		0x300
+
+#define FSL_DCFB_HSYN_BP(x)	((x) << 22)
+#define FSL_DCFB_HSYN_PW(x)	((x) << 11)
+#define FSL_DCFB_HSYN_FP(x)	(x)
+#define FSL_DCFB_VSYN_BP(x)	((x) << 22)
+#define FSL_DCFB_VSYN_PW(x)	((x) << 11)
+#define FSL_DCFB_VSYN_FP(x)	(x)
+
+#define FSL_DCFB_SP_VS		BIT(1)
+#define FSL_DCFB_SP_HS		BIT(0)
+
+#define FSL_DCFB_TS_LBV(x)	((x) << 16)
+#define FSL_DCFB_TS_OBH(x)	((x) << 8)
+#define FSL_DCFB_TS_OBL(x)	(x)
+
+#define FSL_DCFB_UPDATE_MODE	BIT(31)
+#define FSL_DCFB_UPDATE_READREG	BIT(30)
+
+#define FSL_DCFB_VAR_SIZE_H(x)	((x) << 16)
+#define FSL_DCFB_VAR_SIZE_W(x)	(x)
+
+#define FSL_DCFB_POSY(x)	((x) << 16)
+#define FSL_DCFB_POSX(x)	(x)
+
+#define FSL_DCFB_CTRL_EN	BIT(31)
+#define FSL_DCFB_CTRL_TILE_EN	BIT(30)
+#define FSL_DCFB_CTRL_DATA_SEL_CLUT	BIT(29)
+#define FSL_DCFB_CTRL_SAFETY_EN	BIT(28)
+#define FSL_DCFB_CTRL_TRANS(x)	((x) << 20)
+#define FSL_DCFB_CTRL_BPP(x)	((x) << 16)
+#define FSL_DCFB_CTRL_RLE_EN	BIT(15)
+#define FSL_DCFB_CTRL_LUOFFS(x)	((x) << 4)
+#define FSL_DCFB_CTRL_BB_ON	BIT(2)
+
+#define FSL_DCFB_CKMAX_R(x)	((x) << 16)
+#define FSL_DCFB_CKMAX_G(x)	((x) << 8)
+#define FSL_DCFB_CKMAX_B(x)	(x)
+
+#define FSL_DCFB_CKMIN_R(x)	((x) << 16)
+#define FSL_DCFB_CKMIN_G(x)	((x) << 8)
+#define FSL_DCFB_CKMIN_B(x)	(x)
+
+#define FSL_DCFB_TILE_SIZE_W(x)	((x) << 16)
+#define FSL_DCFB_TILE_SIZE_H(x)	(x)
+
+#define FSL_DCFB_FCOLOR_OFF(x)	(x)
+#define FSL_DCFB_BCOLOR_OFF(x)	(x)
+
+#define FSL_DCFB_MODE_BITER(x)	((x) << 20)
+#define FSL_DCFB_MODE_RASTER_EN	BIT(14)
+#define FSL_DCFB_MODE_MODE(x)	(x)
+#define FSL_DCFB_MODE_MODE_MASK	0x03
+
+#define FSL_DCFB_BGND_R(x)	((x) << 16)
+#define FSL_DCFB_BGND_G(x)	((x) << 8)
+#define FSL_DCFB_BGND_B(x)	(x)
+
+#define FSL_DCFB_FIX_SIZE_Y(x)	((x) << 16)
+#define FSL_DCFB_FIX_SIZE_X(x)	(x)
+
+enum fsl_dcfb_fmt {
+	FSL_DCFB_RGB565 = 4,
+	FSL_DCFB_RGB888,
+	FSL_DCFB_ARGB8888,
+};
+
+enum fsl_dcfb_mode {
+	FSL_DCFB_MOD_OFF = 0,
+	FSL_DCFB_MOD_NORMAL,
+	FSL_DCFB_MOD_TEST,
+	FSL_DCFB_MOD_COLORBAR,
+};
+
+struct fsl_dcfb_fb_private {
+	struct fb_info *fsl_dcfb_info;
+	struct device *dev;
+	struct regmap *regmap;
+	struct clk *clk;
+};
+
+struct fsl_dcfb_fb_info {
+	unsigned long pseudo_palette[16];
+	unsigned int count;
+	struct fsl_dcfb_fb_private *parent;
+};
+
+static inline struct fsl_dcfb_fb_private *to_fsl_private(struct fb_info *info)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+
+	return (struct fsl_dcfb_fb_private *)fsl_info->parent;
+}
+
+static int fsl_dcfb_get_bpp(unsigned int bits_per_pixel)
+{
+	int bpp;
+
+	switch (bits_per_pixel) {
+	case 16:
+		bpp = FSL_DCFB_RGB565;
+		break;
+	case 24:
+		bpp = FSL_DCFB_RGB888;
+		break;
+	case 32:
+		bpp = FSL_DCFB_ARGB8888;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return bpp;
+}
+
+static int fsl_dcfb_set_panel(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	int bpp;
+
+	regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE,
+		     FSL_DCFB_VAR_SIZE_H(var->yres) |
+		     FSL_DCFB_VAR_SIZE_W(var->xres));
+	regmap_write(dcfb->regmap, FSL_DCFB_POS,
+		     FSL_DCFB_POSY(0) | FSL_DCFB_POSX(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, info->fix.smem_start);
+
+	bpp = fsl_dcfb_get_bpp(var->bits_per_pixel);
+	if (bpp < 0) {
+		dev_err(dcfb->dev, "unsupported color depth: %u\n",
+				var->bits_per_pixel);
+		return bpp;
+	}
+
+	regmap_write(dcfb->regmap, FSL_DCFB_CTRL, FSL_DCFB_CTRL_EN |
+		     FSL_DCFB_CTRL_TRANS(0xFF) | FSL_DCFB_CTRL_BPP(bpp));
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, FSL_DCFB_CKMAX_R(0xFF) |
+		     FSL_DCFB_CKMAX_G(0xFF) | FSL_DCFB_CKMAX_B(0xFF));
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, FSL_DCFB_CKMIN_R(0) |
+		     FSL_DCFB_CKMIN_G(0) | FSL_DCFB_CKMIN_B(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, FSL_DCFB_FCOLOR_OFF(0));
+	regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, FSL_DCFB_BCOLOR_OFF(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static int fsl_dcfb_reset_panel(struct fsl_dcfb_fb_private *dcfb)
+{
+	regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_POS, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CTRL, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_SKIP, 0x0);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static void fsl_dcfb_modeset(struct fsl_dcfb_fb_private *dcfb,
+			     enum fsl_dcfb_mode mode)
+{
+	regmap_update_bits(dcfb->regmap, FSL_DCFB_MODE,
+			   FSL_DCFB_MODE_MODE_MASK,
+			   FSL_DCFB_MODE_MODE(mode));
+}
+
+static int fsl_dcfb_check_var(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+
+	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(dcfb->dev, "unsupported color depth: %u\n",
+			var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int fsl_dcfb_alloc_mem(struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	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(dcfb->dev, "unable to allocate fb memory\n");
+		return -ENOMEM;
+	}
+
+	memset(info->screen_base, 0, info->fix.smem_len);
+
+	return 0;
+}
+
+static void fsl_dcfb_free_mem(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_dcfb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fb_fix_screeninfo *fix = &info->fix;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	unsigned int div, len;
+
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->accel = FB_ACCEL_NONE;
+	fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->xpanstep = fix->ypanstep = 1;
+
+	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+	len = info->var.yres_virtual * info->fix.line_length;
+	if (len != info->fix.smem_len) {
+		if (info->fix.smem_start)
+			fsl_dcfb_free_mem(info);
+
+		if (fsl_dcfb_alloc_mem(info)) {
+			dev_err(dcfb->dev, "unable to allocate FB memory\n");
+			return -ENOMEM;
+		}
+	}
+
+	div = KHZ2PICOS(clk_get_rate(dcfb->clk) / 1000);
+	regmap_write(dcfb->regmap, FSL_DCFB_DIV_RATIO,
+		     info->var.pixclock / div);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_FIX_SIZE,
+		     FSL_DCFB_FIX_SIZE_Y(var->yres) |
+		     FSL_DCFB_FIX_SIZE_X(var->xres / 16));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_HSYN,
+		     FSL_DCFB_HSYN_BP(var->left_margin) |
+		     FSL_DCFB_HSYN_PW(var->hsync_len) |
+		     FSL_DCFB_HSYN_FP(var->right_margin));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_VSYN,
+		     FSL_DCFB_VSYN_BP(var->upper_margin) |
+		     FSL_DCFB_VSYN_PW(var->vsync_len) |
+		     FSL_DCFB_VSYN_FP(var->lower_margin));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_SP,
+		     FSL_DCFB_SP_VS | FSL_DCFB_SP_HS);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BGND, FSL_DCFB_BGND_R(0) |
+		     FSL_DCFB_BGND_G(0) | FSL_DCFB_BGND_B(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_MODE,
+		     FSL_DCFB_MODE_BITER(1) | FSL_DCFB_MODE_RASTER_EN);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_TS, FSL_DCFB_TS_LBV(0x03) |
+		     FSL_DCFB_TS_OBH(0x78) | FSL_DCFB_TS_OBL(0x0A));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_NORMAL);
+	fsl_dcfb_set_panel(info);
+
+	return 0;
+}
+
+#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
+static int fsl_dcfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *info)
+{
+	int ret = 1;
+
+	/*
+	 * 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:
+		if (regno < 16) {
+			u32 *pal = info->pseudo_palette;
+			u32 value;
+
+			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);
+
+			value = (red << info->var.red.offset) |
+				(green << info->var.green.offset) |
+				(blue << info->var.blue.offset) |
+				(transp << info->var.transp.offset);
+
+			pal[regno] = value;
+			ret = 0;
+		}
+		break;
+	case FB_VISUAL_STATIC_PSEUDOCOLOR:
+	case FB_VISUAL_PSEUDOCOLOR:
+		break;
+	}
+
+	return ret;
+}
+#undef CNVT_TOHW
+
+static int fsl_dcfb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	unsigned long addr;
+	int offset;
+
+	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;
+
+	offset = (info->var.yoffset * info->var.xres_virtual);
+	offset += info->var.xoffset;
+	addr = info->fix.smem_start +
+		(offset * (info->var.bits_per_pixel >> 3));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, addr);
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static int fsl_dcfb_blank(int blank_mode, struct fb_info *info)
+{
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+
+	switch (blank_mode) {
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		fsl_dcfb_reset_panel(dcfb);
+		break;
+	case FB_BLANK_POWERDOWN:
+		fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF);
+		break;
+	case FB_BLANK_UNBLANK:
+		fsl_dcfb_set_panel(info);
+		break;
+	}
+
+	return 0;
+}
+
+static int fsl_dcfb_open(struct fb_info *info, int user)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+	int ret = 0;
+
+	fsl_info->count++;
+	if (fsl_info->count == 1) {
+		fsl_dcfb_check_var(&info->var, info);
+		ret = fsl_dcfb_set_par(info);
+		if (ret < 0)
+			fsl_info->count--;
+	}
+
+	return ret;
+}
+
+static int fsl_dcfb_release(struct fb_info *info, int user)
+{
+	struct fsl_dcfb_fb_info *fsl_info = info->par;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	int ret = 0;
+
+	fsl_info->count--;
+	if (fsl_info->count == 0)
+		ret = fsl_dcfb_reset_panel(dcfb);
+
+	return ret;
+}
+
+static struct fb_ops fsl_dcfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = fsl_dcfb_check_var,
+	.fb_set_par = fsl_dcfb_set_par,
+	.fb_setcolreg = fsl_dcfb_setcolreg,
+	.fb_blank = fsl_dcfb_blank,
+	.fb_pan_display = fsl_dcfb_pan_display,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_open = fsl_dcfb_open,
+	.fb_release = fsl_dcfb_release,
+};
+
+static int fsl_dcfb_init_fbinfo(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fsl_dcfb_fb_private *dcfb = to_fsl_private(info);
+	struct device_node *np = dcfb->dev->of_node;
+	struct device_node *dnp, *tnp;
+	struct display_timings *timings;
+	struct fb_videomode fb_vm;
+	int i, ret;
+
+	INIT_LIST_HEAD(&info->modelist);
+
+	dnp = of_parse_phandle(np, "display", 0);
+	if (!dnp) {
+		dev_err(dcfb->dev, "failed to find \"display\" phandle.\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(dnp, "bits-per-pixel",
+				   &var->bits_per_pixel);
+	if (ret < 0) {
+		dev_err(dcfb->dev, "failed to get \"bits-per-pixel\" property.\n");
+		goto put_dnp;
+	}
+
+	timings = of_get_display_timings(dnp);
+	if (!timings) {
+		dev_err(dcfb->dev, "failed to get display timings\n");
+		return -ENODEV;
+		goto put_dnp;
+	}
+
+	tnp = of_find_node_by_name(dnp, "display-timings");
+	if (!tnp) {
+		dev_err(dcfb->dev, "failed to find \"display-timings\" node\n");
+		return -ENODEV;
+		goto put_dnp;
+	}
+
+	for (i = 0; i < of_get_child_count(tnp); i++) {
+		struct videomode vm;
+
+		ret = videomode_from_timings(timings, &vm, i);
+		if (ret < 0)
+			goto put_tnp;
+
+		ret = fb_videomode_from_videomode(&vm, &fb_vm);
+		if (ret < 0)
+			goto put_tnp;
+
+		fb_add_videomode(&fb_vm, &info->modelist);
+	}
+
+	ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE);
+	if (ret)
+		goto put_dnp;
+
+	fb_videomode_to_var(&info->var, &fb_vm);
+	ret = fsl_dcfb_check_var(&info->var, info);
+
+put_tnp:
+	of_node_put(tnp);
+put_dnp:
+	of_node_put(dnp);
+
+	return ret;
+}
+
+static const struct regmap_config fsl_scfg_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.max_register = FSL_SCFG_CTRL,
+};
+
+static int scfg_config(struct fsl_dcfb_fb_private *dcfb, struct device_node *np)
+{
+	struct device_node *snp;
+	struct platform_device *pdev;
+	struct resource *res;
+	void __iomem *base;
+	struct regmap *regmap;
+	int ret = 0;
+
+	snp = of_parse_phandle(np, "scfg-controller", 0);
+	if (!snp)
+		return -ENODEV;
+
+	pdev = of_find_device_by_node(snp);
+	if (!pdev) {
+		ret = -ENODEV;
+		goto put_snp;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		goto put_snp;
+	}
+
+	base = ioremap(res->start, SZ_4K);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "could not ioremap scfg resource\n");
+		ret = PTR_ERR(base);
+		goto put_snp;
+	}
+
+	regmap = regmap_init_mmio(&pdev->dev, base,
+				  &fsl_scfg_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		ret = PTR_ERR(regmap);
+		goto ioremap;
+	}
+
+	regmap_write(regmap, FSL_SCFG_CTRL, FSL_SCFG_PIXEL_EN);
+
+	regmap_exit(regmap);
+ioremap:
+	iounmap(base);
+put_snp:
+	of_node_put(snp);
+
+	return ret;
+}
+
+static int fsl_dcfb_dev_init(struct device_node *np,
+			     struct fsl_dcfb_fb_private *dcfb)
+{
+	int ret;
+
+	ret = scfg_config(dcfb, np);
+	if (ret) {
+		dev_err(dcfb->dev, "could not config scfg\n");
+		return -EINVAL;
+	}
+
+	return fsl_dcfb_reset_panel(dcfb);
+}
+
+static const struct regmap_config fsl_dcfb_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.max_register = FSL_DCFB_MAX,
+};
+
+static int fsl_dcfb_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct fsl_dcfb_fb_private *dcfb;
+	struct fsl_dcfb_fb_info *fsl_info;
+	struct fb_info *info;
+	struct resource *res;
+	void __iomem *base;
+	int ret = 0;
+
+	dcfb = devm_kzalloc(&pdev->dev,
+		sizeof(struct fsl_dcfb_fb_private), GFP_KERNEL);
+	if (!dcfb)
+		return -ENOMEM;
+
+	dcfb->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "could not get memory IO resource\n");
+		return -ENODEV;
+	}
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "could not ioremap resource\n");
+		return PTR_ERR(base);
+	}
+
+	dcfb->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+				NULL, base, &fsl_dcfb_regmap_config);
+	if (IS_ERR(dcfb->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(dcfb->regmap);
+	}
+
+	dcfb->clk = devm_clk_get(&pdev->dev, "dcfb");
+	if (IS_ERR(dcfb->clk)) {
+		ret = PTR_ERR(dcfb->clk);
+		dev_err(&pdev->dev, "could not get clock\n");
+		return -EINVAL;
+	}
+	clk_prepare_enable(dcfb->clk);
+
+	fsl_dcfb_dev_init(np, dcfb);
+
+	dcfb->fsl_dcfb_info =
+		framebuffer_alloc(sizeof(struct fsl_dcfb_fb_info), &pdev->dev);
+	if (!dcfb->fsl_dcfb_info) {
+		ret = -ENOMEM;
+		goto err_clk;
+	}
+
+	dcfb->fsl_dcfb_info->fix.smem_start = 0;
+
+	fsl_info = dcfb->fsl_dcfb_info->par;
+	fsl_info->count = 0,
+	fsl_info->parent = dcfb;
+
+	info = dcfb->fsl_dcfb_info;
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->fbops = &fsl_dcfb_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->pseudo_palette = &fsl_info->pseudo_palette;
+
+	ret = fb_alloc_cmap(&info->cmap, 16, 0);
+	if (ret) {
+		ret = -ENOMEM;
+		goto err_mem;
+	}
+
+	ret = fsl_dcfb_init_fbinfo(info);
+	if (ret)
+		goto err_cmap;
+
+	ret = register_framebuffer(info);
+	if (ret < 0) {
+		dev_err(dcfb->dev, "failed to register framebuffer device\n");
+		goto err_cmap;
+	}
+
+	dev_set_drvdata(&pdev->dev, dcfb);
+
+	goto out;
+
+err_cmap:
+	fb_dealloc_cmap(&info->cmap);
+err_mem:
+	framebuffer_release(dcfb->fsl_dcfb_info);
+err_clk:
+	clk_disable_unprepare(dcfb->clk);
+out:
+	return ret;
+}
+
+static int fsl_dcfb_remove(struct platform_device *pdev)
+{
+	struct fsl_dcfb_fb_private *dcfb = dev_get_drvdata(&pdev->dev);
+	struct fb_info *info = dcfb->fsl_dcfb_info;
+
+	fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF);
+	fsl_dcfb_free_mem(info);
+
+	unregister_framebuffer(info);
+	fb_dealloc_cmap(&info->cmap);
+	framebuffer_release(dcfb->fsl_dcfb_info);
+	clk_disable_unprepare(dcfb->clk);
+
+	return 0;
+}
+
+static struct of_device_id fsl_dcfb_dt_ids[] = {
+	{ .compatible = "fsl,ls1021a-dcfb", },
+	{}
+};
+
+static struct platform_driver fsl_dcfb_driver = {
+	.driver = {
+		.name = "fsl-dcfb",
+		.owner = THIS_MODULE,
+		.of_match_table = fsl_dcfb_dt_ids,
+	},
+	.probe = fsl_dcfb_probe,
+	.remove = fsl_dcfb_remove,
+};
+
+module_platform_driver(fsl_dcfb_driver);
+
+MODULE_DESCRIPTION("Freescale Simple Display Controller FB Driver");
+MODULE_ALIAS("platform:fsl-dcfb");
+MODULE_LICENSE("GPL v2");
-- 
2.1.0.27.g96db324

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

* [PATCHv2 2/4] video: fsl-dcfb: Add devicetree binding support
  2014-12-03  9:15 ` Xiubo Li
  (?)
@ 2014-12-03  9:16   ` Xiubo Li
  -1 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel,
	linux-kernel, Xiubo Li

Add devicetree binding support for fsl-dcfb framebuffer driver. It
uses the generic display bindings and helper functions.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 .../devicetree/bindings/video/fsl,dcfb.txt         | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt

diff --git a/Documentation/devicetree/bindings/video/fsl,dcfb.txt b/Documentation/devicetree/bindings/video/fsl,dcfb.txt
new file mode 100644
index 0000000..2f3d02b
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fsl,dcfb.txt
@@ -0,0 +1,52 @@
+* Freescale Simple Display Controller FB Driver
+
+=== For dcfb node ===
+Required properties:
+- compatible:		Should be one of "fsl,ls1021a-dcfb".
+- reg:			Address and length of the register set for dcfb.
+- clocks:		From common clock binding: handle to dcfb clock.
+- clock-names:		From common clock binding: Shall be "dcfb".
+- display:		The phandle to display node.
+
+Optional properties:
+- scfg-controller:	The phandle of scfg node.
+
+=== For display sub-node ===
+Required properties:
+- bits-per-pixel:	<16> for RGB565,
+			<24> for RGB888,
+			<32> for RGB8888.
+
+Required timing node for dispplay sub-node:
+- display-timings:	Refer to binding doc display-timing.txt for details.
+
+Examples:
+dcfb: dcfb@2ce0000 {
+	compatible = "fsl,ls1021a-dcfb";
+	reg = <0x0 0x2ce0000 0x0 0x10000>;
+	clocks = <&platform_clk 0>;
+	clock-names = "dcfb";
+	scfg-controller = <&scfg>;
+	display = <&display>;
+
+	display: display@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>;
+			};
+		};
+	};
+};
-- 
2.1.0.27.g96db324


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

* [PATCHv2 2/4] video: fsl-dcfb: Add devicetree binding support
@ 2014-12-03  9:16   ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

Add devicetree binding support for fsl-dcfb framebuffer driver. It
uses the generic display bindings and helper functions.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 .../devicetree/bindings/video/fsl,dcfb.txt         | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt

diff --git a/Documentation/devicetree/bindings/video/fsl,dcfb.txt b/Documentation/devicetree/bindings/video/fsl,dcfb.txt
new file mode 100644
index 0000000..2f3d02b
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fsl,dcfb.txt
@@ -0,0 +1,52 @@
+* Freescale Simple Display Controller FB Driver
+
+== For dcfb node =+Required properties:
+- compatible:		Should be one of "fsl,ls1021a-dcfb".
+- reg:			Address and length of the register set for dcfb.
+- clocks:		From common clock binding: handle to dcfb clock.
+- clock-names:		From common clock binding: Shall be "dcfb".
+- display:		The phandle to display node.
+
+Optional properties:
+- scfg-controller:	The phandle of scfg node.
+
+== For display sub-node =+Required properties:
+- bits-per-pixel:	<16> for RGB565,
+			<24> for RGB888,
+			<32> for RGB8888.
+
+Required timing node for dispplay sub-node:
+- display-timings:	Refer to binding doc display-timing.txt for details.
+
+Examples:
+dcfb: dcfb@2ce0000 {
+	compatible = "fsl,ls1021a-dcfb";
+	reg = <0x0 0x2ce0000 0x0 0x10000>;
+	clocks = <&platform_clk 0>;
+	clock-names = "dcfb";
+	scfg-controller = <&scfg>;
+	display = <&display>;
+
+	display: display@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>;
+			};
+		};
+	};
+};
-- 
2.1.0.27.g96db324


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

* [PATCHv2 2/4] video: fsl-dcfb: Add devicetree binding support
@ 2014-12-03  9:16   ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

Add devicetree binding support for fsl-dcfb framebuffer driver. It
uses the generic display bindings and helper functions.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 .../devicetree/bindings/video/fsl,dcfb.txt         | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt

diff --git a/Documentation/devicetree/bindings/video/fsl,dcfb.txt b/Documentation/devicetree/bindings/video/fsl,dcfb.txt
new file mode 100644
index 0000000..2f3d02b
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fsl,dcfb.txt
@@ -0,0 +1,52 @@
+* Freescale Simple Display Controller FB Driver
+
+=== For dcfb node ===
+Required properties:
+- compatible:		Should be one of "fsl,ls1021a-dcfb".
+- reg:			Address and length of the register set for dcfb.
+- clocks:		From common clock binding: handle to dcfb clock.
+- clock-names:		From common clock binding: Shall be "dcfb".
+- display:		The phandle to display node.
+
+Optional properties:
+- scfg-controller:	The phandle of scfg node.
+
+=== For display sub-node ===
+Required properties:
+- bits-per-pixel:	<16> for RGB565,
+			<24> for RGB888,
+			<32> for RGB8888.
+
+Required timing node for dispplay sub-node:
+- display-timings:	Refer to binding doc display-timing.txt for details.
+
+Examples:
+dcfb: dcfb at 2ce0000 {
+	compatible = "fsl,ls1021a-dcfb";
+	reg = <0x0 0x2ce0000 0x0 0x10000>;
+	clocks = <&platform_clk 0>;
+	clock-names = "dcfb";
+	scfg-controller = <&scfg>;
+	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>;
+			};
+		};
+	};
+};
-- 
2.1.0.27.g96db324

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

* [PATCHv2 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb.
  2014-12-03  9:15 ` Xiubo Li
  (?)
@ 2014-12-03  9:16   ` Xiubo Li
  -1 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel,
	linux-kernel, Xiubo Li

On LS1021A SoC, the dcfb device is in BE mode.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..740a04e 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -383,6 +383,16 @@
 				 <&platform_clk 1>;
 		};
 
+		dcfb: dcfb@2ce0000 {
+			compatible = "fsl,ls1021a-dcfb";
+			reg = <0x0 0x2ce0000 0x0 0x10000>;
+			clocks = <&platform_clk 0>;
+			clock-names = "dcfb";
+			scfg-controller = <&scfg>;
+			big-endian;
+			status = "disabled";
+		};
+
 		mdio0: mdio@2d24000 {
 			compatible = "gianfar";
 			device_type = "mdio";
-- 
2.1.0.27.g96db324


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

* [PATCHv2 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb.
@ 2014-12-03  9:16   ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

On LS1021A SoC, the dcfb device is in BE mode.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..740a04e 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -383,6 +383,16 @@
 				 <&platform_clk 1>;
 		};
 
+		dcfb: dcfb@2ce0000 {
+			compatible = "fsl,ls1021a-dcfb";
+			reg = <0x0 0x2ce0000 0x0 0x10000>;
+			clocks = <&platform_clk 0>;
+			clock-names = "dcfb";
+			scfg-controller = <&scfg>;
+			big-endian;
+			status = "disabled";
+		};
+
 		mdio0: mdio@2d24000 {
 			compatible = "gianfar";
 			device_type = "mdio";
-- 
2.1.0.27.g96db324


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

* [PATCHv2 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb.
@ 2014-12-03  9:16   ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

On LS1021A SoC, the dcfb device is in BE mode.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..740a04e 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -383,6 +383,16 @@
 				 <&platform_clk 1>;
 		};
 
+		dcfb: dcfb at 2ce0000 {
+			compatible = "fsl,ls1021a-dcfb";
+			reg = <0x0 0x2ce0000 0x0 0x10000>;
+			clocks = <&platform_clk 0>;
+			clock-names = "dcfb";
+			scfg-controller = <&scfg>;
+			big-endian;
+			status = "disabled";
+		};
+
 		mdio0: mdio at 2d24000 {
 			compatible = "gianfar";
 			device_type = "mdio";
-- 
2.1.0.27.g96db324

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

* [PATCHv2 4/4] ARM: ls1021a: dts: Add and enable dt node for dcfb.
  2014-12-03  9:15 ` Xiubo Li
  (?)
@ 2014-12-03  9:16   ` Xiubo Li
  -1 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: plagnioj, tomi.valkeinen
  Cc: alexander.stein, shawn.guo, linux-fbdev, linux-arm-kernel,
	linux-kernel, Xiubo Li

On LS1021A TWR board, the TFT LCD panel is WQVGA "480x272", and
the bpp is 24.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 arch/arm/boot/dts/ls1021a-twr.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index a2c591e..3602286 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -58,6 +58,32 @@
 	};
 };
 
+&dcfb {
+	display = <&display>;
+	status = "okay";
+
+	display: display@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 = <2>;
+				vfront-porch = <2>;
+				hsync-len = <41>;
+				vsync-len = <4>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
+};
+
 &dspi1 {
 	bus-num = <0>;
 	status = "okay";
-- 
2.1.0.27.g96db324


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

* [PATCHv2 4/4] ARM: ls1021a: dts: Add and enable dt node for dcfb.
@ 2014-12-03  9:16   ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

On LS1021A TWR board, the TFT LCD panel is WQVGA "480x272", and
the bpp is 24.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 arch/arm/boot/dts/ls1021a-twr.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index a2c591e..3602286 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -58,6 +58,32 @@
 	};
 };
 
+&dcfb {
+	display = <&display>;
+	status = "okay";
+
+	display: display@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 = <2>;
+				vfront-porch = <2>;
+				hsync-len = <41>;
+				vsync-len = <4>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
+};
+
 &dspi1 {
 	bus-num = <0>;
 	status = "okay";
-- 
2.1.0.27.g96db324


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

* [PATCHv2 4/4] ARM: ls1021a: dts: Add and enable dt node for dcfb.
@ 2014-12-03  9:16   ` Xiubo Li
  0 siblings, 0 replies; 35+ messages in thread
From: Xiubo Li @ 2014-12-03  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

On LS1021A TWR board, the TFT LCD panel is WQVGA "480x272", and
the bpp is 24.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 arch/arm/boot/dts/ls1021a-twr.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index a2c591e..3602286 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -58,6 +58,32 @@
 	};
 };
 
+&dcfb {
+	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 = <2>;
+				vfront-porch = <2>;
+				hsync-len = <41>;
+				vsync-len = <4>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
+};
+
 &dspi1 {
 	bus-num = <0>;
 	status = "okay";
-- 
2.1.0.27.g96db324

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

* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
  2014-12-03  9:15 ` Xiubo Li
  (?)
@ 2014-12-03  9:51   ` Arnd Bergmann
  -1 siblings, 0 replies; 35+ messages in thread
From: Arnd Bergmann @ 2014-12-03  9:51 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Xiubo Li, plagnioj, tomi.valkeinen, linux-fbdev, linux-kernel,
	shawn.guo, alexander.stein

On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote:
> Framebuffer driver for the Freescale SoC Display Controller.
> 
> 
> Change in V2:
> - Use the native-mode timing as default.
> - Add to_fsl_private().

<standard reply>

We try to not have any new framebuffer drivers. Please consider making
this a DRM/KMS driver instead.

</standard reply>

	Arnd

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

* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-03  9:51   ` Arnd Bergmann
  0 siblings, 0 replies; 35+ messages in thread
From: Arnd Bergmann @ 2014-12-03  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote:
> Framebuffer driver for the Freescale SoC Display Controller.
> 
> 
> Change in V2:
> - Use the native-mode timing as default.
> - Add to_fsl_private().

<standard reply>

We try to not have any new framebuffer drivers. Please consider making
this a DRM/KMS driver instead.

</standard reply>

	Arnd

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

* [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-03  9:51   ` Arnd Bergmann
  0 siblings, 0 replies; 35+ messages in thread
From: Arnd Bergmann @ 2014-12-03  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote:
> Framebuffer driver for the Freescale SoC Display Controller.
> 
> 
> Change in V2:
> - Use the native-mode timing as default.
> - Add to_fsl_private().

<standard reply>

We try to not have any new framebuffer drivers. Please consider making
this a DRM/KMS driver instead.

</standard reply>

	Arnd

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

* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
  2014-12-03  9:51   ` Arnd Bergmann
@ 2014-12-04  1:56     ` Li.Xiubo
  -1 siblings, 0 replies; 35+ messages in thread
From: Li.Xiubo @ 2014-12-04  1:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: plagnioj, tomi.valkeinen, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

Hi Arnd,

Thanks for you advice.

Because this is very emergency for customers and have delayed for monthes, and the
DRM/KMS will have a little long time to be supported. So I'd like to add this first
and will add DRM/KMS version later.

Thanks very much,

BRs
Xiubo


> -----Original Message-----
> From: linux-fbdev-owner@vger.kernel.org [mailto:linux-fbdev-
> owner@vger.kernel.org] On Behalf Of Arnd Bergmann
> Sent: Wednesday, December 03, 2014 5:52 PM
> To: linux-arm-kernel@lists.infradead.org
> Cc: Xiubo Li-B47053; plagnioj@jcrosoft.com; tomi.valkeinen@ti.com; linux-
> fbdev@vger.kernel.org; linux-kernel@vger.kernel.org; shawn.guo@linaro.org;
> alexander.stein@systec-electronic.com
> Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
> 
> On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote:
> > Framebuffer driver for the Freescale SoC Display Controller.
> >
> >
> > Change in V2:
> > - Use the native-mode timing as default.
> > - Add to_fsl_private().
> 
> <standard reply>
> 
> We try to not have any new framebuffer drivers. Please consider making
> this a DRM/KMS driver instead.
> 
> </standard reply>
> 
> 	Arnd
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-04  1:56     ` Li.Xiubo
  0 siblings, 0 replies; 35+ messages in thread
From: Li.Xiubo @ 2014-12-04  1:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: plagnioj, tomi.valkeinen, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

Hi Arnd,

Thanks for you advice.

Because this is very emergency for customers and have delayed for monthes, and the
DRM/KMS will have a little long time to be supported. So I'd like to add this first
and will add DRM/KMS version later.

Thanks very much,

BRs
Xiubo


> -----Original Message-----
> From: linux-fbdev-owner@vger.kernel.org [mailto:linux-fbdev-
> owner@vger.kernel.org] On Behalf Of Arnd Bergmann
> Sent: Wednesday, December 03, 2014 5:52 PM
> To: linux-arm-kernel@lists.infradead.org
> Cc: Xiubo Li-B47053; plagnioj@jcrosoft.com; tomi.valkeinen@ti.com; linux-
> fbdev@vger.kernel.org; linux-kernel@vger.kernel.org; shawn.guo@linaro.org;
> alexander.stein@systec-electronic.com
> Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
> 
> On Wednesday 03 December 2014 17:15:58 Xiubo Li wrote:
> > Framebuffer driver for the Freescale SoC Display Controller.
> >
> >
> > Change in V2:
> > - Use the native-mode timing as default.
> > - Add to_fsl_private().
> 
> <standard reply>
> 
> We try to not have any new framebuffer drivers. Please consider making
> this a DRM/KMS driver instead.
> 
> </standard reply>
> 
> 	Arnd
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
  2014-12-04  1:56     ` Li.Xiubo
@ 2014-12-04  8:10       ` Tomi Valkeinen
  -1 siblings, 0 replies; 35+ messages in thread
From: Tomi Valkeinen @ 2014-12-04  8:10 UTC (permalink / raw)
  To: Li.Xiubo, Arnd Bergmann
  Cc: plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein

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

Hi Xiubo,

On 04/12/14 03:56, Li.Xiubo@freescale.com wrote:
> Hi Arnd,
> 
> Thanks for you advice.
> 
> Because this is very emergency for customers and have delayed for monthes, and the
> DRM/KMS will have a little long time to be supported. So I'd like to add this first
> and will add DRM/KMS version later.

I would also suggest to just write a drm driver for this. I don't see
anything special in this driver that would be better supported via
fbdev. With drm you'll get a more modern framework, and you will still
have the same /dev/fbX device to use for legacy userspace software.

What do you mean with "delayed for months"? The first version of this
series (that I can find) was posted less than two weeks ago.

 Tomi



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

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

* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-04  8:10       ` Tomi Valkeinen
  0 siblings, 0 replies; 35+ messages in thread
From: Tomi Valkeinen @ 2014-12-04  8:10 UTC (permalink / raw)
  To: Li.Xiubo, Arnd Bergmann
  Cc: plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein

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

Hi Xiubo,

On 04/12/14 03:56, Li.Xiubo@freescale.com wrote:
> Hi Arnd,
> 
> Thanks for you advice.
> 
> Because this is very emergency for customers and have delayed for monthes, and the
> DRM/KMS will have a little long time to be supported. So I'd like to add this first
> and will add DRM/KMS version later.

I would also suggest to just write a drm driver for this. I don't see
anything special in this driver that would be better supported via
fbdev. With drm you'll get a more modern framework, and you will still
have the same /dev/fbX device to use for legacy userspace software.

What do you mean with "delayed for months"? The first version of this
series (that I can find) was posted less than two weeks ago.

 Tomi



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

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

* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
  2014-12-04  8:10       ` Tomi Valkeinen
@ 2014-12-04  8:30         ` Li.Xiubo
  -1 siblings, 0 replies; 35+ messages in thread
From: Li.Xiubo @ 2014-12-04  8:30 UTC (permalink / raw)
  To: Tomi Valkeinen, Arnd Bergmann
  Cc: plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein

Hi Tomi,



> -----Original Message-----
> From: Tomi Valkeinen [mailto:tomi.valkeinen@ti.com]
> Sent: Thursday, December 04, 2014 4:10 PM
> To: Xiubo Li-B47053; Arnd Bergmann
> Cc: plagnioj@jcrosoft.com; linux-fbdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; shawn.guo@linaro.org; alexander.stein@systec-
> electronic.com
> Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
> 
> Hi Xiubo,
> 
> On 04/12/14 03:56, Li.Xiubo@freescale.com wrote:
> > Hi Arnd,
> >
> > Thanks for you advice.
> >
> > Because this is very emergency for customers and have delayed for monthes,
> and the
> > DRM/KMS will have a little long time to be supported. So I'd like to add
> this first
> > and will add DRM/KMS version later.
> 
> I would also suggest to just write a drm driver for this. I don't see
> anything special in this driver that would be better supported via
> fbdev. With drm you'll get a more modern framework, and you will still
> have the same /dev/fbX device to use for legacy userspace software.
> 
> What do you mean with "delayed for months"? The first version of this
> series (that I can find) was posted less than two weeks ago.
> 

Sorry for confusing, it was delayed for other reasons internal.

I am not familiar about the DRM, and I'd like to know if the DRM driver will be
support, should I also develop the libdrm too ? Or just coding in kernel level ?
Is there any Document about how to have /dev/fbX device to use ?

If possible, I'd like this could be accept for this time. And I will add the DRM
Version later(for developing and testing will take a long time).

Thanks very much,

BRs
Xiubo


>  Tomi
> 


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

* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-04  8:30         ` Li.Xiubo
  0 siblings, 0 replies; 35+ messages in thread
From: Li.Xiubo @ 2014-12-04  8:30 UTC (permalink / raw)
  To: Tomi Valkeinen, Arnd Bergmann
  Cc: plagnioj, linux-fbdev, linux-kernel, shawn.guo, alexander.stein

Hi Tomi,



> -----Original Message-----
> From: Tomi Valkeinen [mailto:tomi.valkeinen@ti.com]
> Sent: Thursday, December 04, 2014 4:10 PM
> To: Xiubo Li-B47053; Arnd Bergmann
> Cc: plagnioj@jcrosoft.com; linux-fbdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; shawn.guo@linaro.org; alexander.stein@systec-
> electronic.com
> Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
> 
> Hi Xiubo,
> 
> On 04/12/14 03:56, Li.Xiubo@freescale.com wrote:
> > Hi Arnd,
> >
> > Thanks for you advice.
> >
> > Because this is very emergency for customers and have delayed for monthes,
> and the
> > DRM/KMS will have a little long time to be supported. So I'd like to add
> this first
> > and will add DRM/KMS version later.
> 
> I would also suggest to just write a drm driver for this. I don't see
> anything special in this driver that would be better supported via
> fbdev. With drm you'll get a more modern framework, and you will still
> have the same /dev/fbX device to use for legacy userspace software.
> 
> What do you mean with "delayed for months"? The first version of this
> series (that I can find) was posted less than two weeks ago.
> 

Sorry for confusing, it was delayed for other reasons internal.

I am not familiar about the DRM, and I'd like to know if the DRM driver will be
support, should I also develop the libdrm too ? Or just coding in kernel level ?
Is there any Document about how to have /dev/fbX device to use ?

If possible, I'd like this could be accept for this time. And I will add the DRM
Version later(for developing and testing will take a long time).

Thanks very much,

BRs
Xiubo


>  Tomi
> 


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

* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
  2014-12-04  8:30         ` Li.Xiubo
@ 2014-12-04  9:09           ` Tomi Valkeinen
  -1 siblings, 0 replies; 35+ messages in thread
From: Tomi Valkeinen @ 2014-12-04  9:09 UTC (permalink / raw)
  To: Li.Xiubo
  Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

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

On 04/12/14 10:30, Li.Xiubo@freescale.com wrote:

> Sorry for confusing, it was delayed for other reasons internal.
> 
> I am not familiar about the DRM, and I'd like to know if the DRM driver will be
> support, should I also develop the libdrm too ? Or just coding in kernel level ?

For simple drm drivers (this looks like it would be a simple one), I
don't think there's any need for libdrm support. The generic DRM
interfaces should be enough, so just kernel level coding needed.

> Is there any Document about how to have /dev/fbX device to use ?

There's DRM documentation here:

https://www.kernel.org/doc/htmldocs/drm/index.html

And many existing drivers to use as examples. The dri-devel list
(http://lists.freedesktop.org/mailman/listinfo/dri-devel), which is the
mailing list used for DRM development, is active and you probably can
get more support from there than from the fbdev list.

It should not be a huge effort to write a drm driver for a simple LCD
controller like this. I would bet that you can write a working driver in
a week.

> If possible, I'd like this could be accept for this time. And I will add the DRM
> Version later(for developing and testing will take a long time).

I'm sorry but "it was delayed for internal reasons" and "our customer
needs this driver" are not very good reasons for getting a driver merged
to mainline Linux.

You can provide your driver to your customer as a separate patch series
which they can apply. There should be no conflicts or other issues
there, so it should be simple.

 Tomi



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

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

* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-04  9:09           ` Tomi Valkeinen
  0 siblings, 0 replies; 35+ messages in thread
From: Tomi Valkeinen @ 2014-12-04  9:09 UTC (permalink / raw)
  To: Li.Xiubo
  Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

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

On 04/12/14 10:30, Li.Xiubo@freescale.com wrote:

> Sorry for confusing, it was delayed for other reasons internal.
> 
> I am not familiar about the DRM, and I'd like to know if the DRM driver will be
> support, should I also develop the libdrm too ? Or just coding in kernel level ?

For simple drm drivers (this looks like it would be a simple one), I
don't think there's any need for libdrm support. The generic DRM
interfaces should be enough, so just kernel level coding needed.

> Is there any Document about how to have /dev/fbX device to use ?

There's DRM documentation here:

https://www.kernel.org/doc/htmldocs/drm/index.html

And many existing drivers to use as examples. The dri-devel list
(http://lists.freedesktop.org/mailman/listinfo/dri-devel), which is the
mailing list used for DRM development, is active and you probably can
get more support from there than from the fbdev list.

It should not be a huge effort to write a drm driver for a simple LCD
controller like this. I would bet that you can write a working driver in
a week.

> If possible, I'd like this could be accept for this time. And I will add the DRM
> Version later(for developing and testing will take a long time).

I'm sorry but "it was delayed for internal reasons" and "our customer
needs this driver" are not very good reasons for getting a driver merged
to mainline Linux.

You can provide your driver to your customer as a separate patch series
which they can apply. There should be no conflicts or other issues
there, so it should be simple.

 Tomi



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

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

* Re: [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
  2014-12-03  9:15   ` Xiubo Li
  (?)
@ 2014-12-04  9:21     ` Alexander Stein
  -1 siblings, 0 replies; 35+ messages in thread
From: Alexander Stein @ 2014-12-04  9:21 UTC (permalink / raw)
  To: Xiubo Li
  Cc: plagnioj, tomi.valkeinen, shawn.guo, linux-fbdev,
	linux-arm-kernel, linux-kernel

On Wednesday 03 December 2014 17:15:59, Xiubo Li wrote:
> +	tnp = of_find_node_by_name(dnp, "display-timings");
> +	if (!tnp) {
> +		dev_err(dcfb->dev, "failed to find \"display-timings\" node\n");
> +		return -ENODEV;
> +		goto put_dnp;
> +	}
> +
> +	for (i = 0; i < of_get_child_count(tnp); i++) {
> +		struct videomode vm;
> +
> +		ret = videomode_from_timings(timings, &vm, i);
> +		if (ret < 0)
> +			goto put_tnp;
> +
> +		ret = fb_videomode_from_videomode(&vm, &fb_vm);
> +		if (ret < 0)
> +			goto put_tnp;
> +
> +		fb_add_videomode(&fb_vm, &info->modelist);
> +	}
> +
> +	ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE);
> +	if (ret)
> +		goto put_dnp;

Souldn't this be put_tnp like in the loop above? 

> +	fb_videomode_to_var(&info->var, &fb_vm);
> +	ret = fsl_dcfb_check_var(&info->var, info);

But picking the native mode per default looks nice to be! :)

Best regards,
Alexander
-- 
Dipl.-Inf. Alexander Stein

SYS TEC electronic GmbH
Am Windrad 2
08468 Heinsdorfergrund
Tel.: 03765 38600-1156
Fax: 03765 38600-4100
Email: alexander.stein@systec-electronic.com
Website: www.systec-electronic.com
 
Managing Director: Dipl.-Phys. Siegmar Schmidt
Commercial registry: Amtsgericht Chemnitz, HRB 28082


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

* Re: [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
@ 2014-12-04  9:21     ` Alexander Stein
  0 siblings, 0 replies; 35+ messages in thread
From: Alexander Stein @ 2014-12-04  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 03 December 2014 17:15:59, Xiubo Li wrote:
> +	tnp = of_find_node_by_name(dnp, "display-timings");
> +	if (!tnp) {
> +		dev_err(dcfb->dev, "failed to find \"display-timings\" node\n");
> +		return -ENODEV;
> +		goto put_dnp;
> +	}
> +
> +	for (i = 0; i < of_get_child_count(tnp); i++) {
> +		struct videomode vm;
> +
> +		ret = videomode_from_timings(timings, &vm, i);
> +		if (ret < 0)
> +			goto put_tnp;
> +
> +		ret = fb_videomode_from_videomode(&vm, &fb_vm);
> +		if (ret < 0)
> +			goto put_tnp;
> +
> +		fb_add_videomode(&fb_vm, &info->modelist);
> +	}
> +
> +	ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE);
> +	if (ret)
> +		goto put_dnp;

Souldn't this be put_tnp like in the loop above? 

> +	fb_videomode_to_var(&info->var, &fb_vm);
> +	ret = fsl_dcfb_check_var(&info->var, info);

But picking the native mode per default looks nice to be! :)

Best regards,
Alexander
-- 
Dipl.-Inf. Alexander Stein

SYS TEC electronic GmbH
Am Windrad 2
08468 Heinsdorfergrund
Tel.: 03765 38600-1156
Fax: 03765 38600-4100
Email: alexander.stein@systec-electronic.com
Website: www.systec-electronic.com
 
Managing Director: Dipl.-Phys. Siegmar Schmidt
Commercial registry: Amtsgericht Chemnitz, HRB 28082


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

* [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
@ 2014-12-04  9:21     ` Alexander Stein
  0 siblings, 0 replies; 35+ messages in thread
From: Alexander Stein @ 2014-12-04  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 03 December 2014 17:15:59, Xiubo Li wrote:
> +	tnp = of_find_node_by_name(dnp, "display-timings");
> +	if (!tnp) {
> +		dev_err(dcfb->dev, "failed to find \"display-timings\" node\n");
> +		return -ENODEV;
> +		goto put_dnp;
> +	}
> +
> +	for (i = 0; i < of_get_child_count(tnp); i++) {
> +		struct videomode vm;
> +
> +		ret = videomode_from_timings(timings, &vm, i);
> +		if (ret < 0)
> +			goto put_tnp;
> +
> +		ret = fb_videomode_from_videomode(&vm, &fb_vm);
> +		if (ret < 0)
> +			goto put_tnp;
> +
> +		fb_add_videomode(&fb_vm, &info->modelist);
> +	}
> +
> +	ret = of_get_fb_videomode(dnp, &fb_vm, OF_USE_NATIVE_MODE);
> +	if (ret)
> +		goto put_dnp;

Souldn't this be put_tnp like in the loop above? 

> +	fb_videomode_to_var(&info->var, &fb_vm);
> +	ret = fsl_dcfb_check_var(&info->var, info);

But picking the native mode per default looks nice to be! :)

Best regards,
Alexander
-- 
Dipl.-Inf. Alexander Stein

SYS TEC electronic GmbH
Am Windrad 2
08468 Heinsdorfergrund
Tel.: 03765 38600-1156
Fax: 03765 38600-4100
Email: alexander.stein at systec-electronic.com
Website: www.systec-electronic.com
 
Managing Director: Dipl.-Phys. Siegmar Schmidt
Commercial registry: Amtsgericht Chemnitz, HRB 28082

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

* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
  2014-12-04  9:09           ` Tomi Valkeinen
@ 2014-12-04  9:54             ` Li.Xiubo
  -1 siblings, 0 replies; 35+ messages in thread
From: Li.Xiubo @ 2014-12-04  9:54 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

Hi Tomi,

Thanks for your information very much.

> > Sorry for confusing, it was delayed for other reasons internal.
> >
> > I am not familiar about the DRM, and I'd like to know if the DRM driver will
> be
> > support, should I also develop the libdrm too ? Or just coding in kernel
> level ?
> 
> For simple drm drivers (this looks like it would be a simple one), I
> don't think there's any need for libdrm support. The generic DRM
> interfaces should be enough, so just kernel level coding needed.
> 

That's to say, if I am using the X11 server without any code in usrspace,
If the DRM driver will support /dev/fbX, it could work correctly ?

Thanks,

BRs
Xiubo





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

* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-04  9:54             ` Li.Xiubo
  0 siblings, 0 replies; 35+ messages in thread
From: Li.Xiubo @ 2014-12-04  9:54 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

Hi Tomi,

Thanks for your information very much.

> > Sorry for confusing, it was delayed for other reasons internal.
> >
> > I am not familiar about the DRM, and I'd like to know if the DRM driver will
> be
> > support, should I also develop the libdrm too ? Or just coding in kernel
> level ?
> 
> For simple drm drivers (this looks like it would be a simple one), I
> don't think there's any need for libdrm support. The generic DRM
> interfaces should be enough, so just kernel level coding needed.
> 

That's to say, if I am using the X11 server without any code in usrspace,
If the DRM driver will support /dev/fbX, it could work correctly ?

Thanks,

BRs
Xiubo





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

* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
  2014-12-04  9:54             ` Li.Xiubo
@ 2014-12-04  9:59               ` Tomi Valkeinen
  -1 siblings, 0 replies; 35+ messages in thread
From: Tomi Valkeinen @ 2014-12-04  9:59 UTC (permalink / raw)
  To: Li.Xiubo
  Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

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

On 04/12/14 11:54, Li.Xiubo@freescale.com wrote:
> Hi Tomi,
> 
> Thanks for your information very much.
> 
>>> Sorry for confusing, it was delayed for other reasons internal.
>>>
>>> I am not familiar about the DRM, and I'd like to know if the DRM driver will
>> be
>>> support, should I also develop the libdrm too ? Or just coding in kernel
>> level ?
>>
>> For simple drm drivers (this looks like it would be a simple one), I
>> don't think there's any need for libdrm support. The generic DRM
>> interfaces should be enough, so just kernel level coding needed.
>>
> 
> That's to say, if I am using the X11 server without any code in usrspace,
> If the DRM driver will support /dev/fbX, it could work correctly ?

Yes. DRM offers helper code to add /dev/fbX with not too many lines. You
can look at the docs and drm_fb_helper.c.

And X11 should work fine on top of that, using the X11 fbdev support.

 Tomi



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

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

* Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-04  9:59               ` Tomi Valkeinen
  0 siblings, 0 replies; 35+ messages in thread
From: Tomi Valkeinen @ 2014-12-04  9:59 UTC (permalink / raw)
  To: Li.Xiubo
  Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

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

On 04/12/14 11:54, Li.Xiubo@freescale.com wrote:
> Hi Tomi,
> 
> Thanks for your information very much.
> 
>>> Sorry for confusing, it was delayed for other reasons internal.
>>>
>>> I am not familiar about the DRM, and I'd like to know if the DRM driver will
>> be
>>> support, should I also develop the libdrm too ? Or just coding in kernel
>> level ?
>>
>> For simple drm drivers (this looks like it would be a simple one), I
>> don't think there's any need for libdrm support. The generic DRM
>> interfaces should be enough, so just kernel level coding needed.
>>
> 
> That's to say, if I am using the X11 server without any code in usrspace,
> If the DRM driver will support /dev/fbX, it could work correctly ?

Yes. DRM offers helper code to add /dev/fbX with not too many lines. You
can look at the docs and drm_fb_helper.c.

And X11 should work fine on top of that, using the X11 fbdev support.

 Tomi



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

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

* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
  2014-12-04  9:59               ` Tomi Valkeinen
@ 2014-12-04 10:03                 ` Li.Xiubo
  -1 siblings, 0 replies; 35+ messages in thread
From: Li.Xiubo @ 2014-12-04 10:03 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

Hi Tomi,

Thanks very much for your help.

I will have a try these days.

BRs
Xiubo


> -----Original Message-----
> From: Tomi Valkeinen [mailto:tomi.valkeinen@ti.com]
> Sent: Thursday, December 04, 2014 6:00 PM
> To: Xiubo Li-B47053
> Cc: Arnd Bergmann; plagnioj@jcrosoft.com; linux-fbdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; shawn.guo@linaro.org; alexander.stein@systec-
> electronic.com
> Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
> 
> On 04/12/14 11:54, Li.Xiubo@freescale.com wrote:
> > Hi Tomi,
> >
> > Thanks for your information very much.
> >
> >>> Sorry for confusing, it was delayed for other reasons internal.
> >>>
> >>> I am not familiar about the DRM, and I'd like to know if the DRM driver
> will
> >> be
> >>> support, should I also develop the libdrm too ? Or just coding in kernel
> >> level ?
> >>
> >> For simple drm drivers (this looks like it would be a simple one), I
> >> don't think there's any need for libdrm support. The generic DRM
> >> interfaces should be enough, so just kernel level coding needed.
> >>
> >
> > That's to say, if I am using the X11 server without any code in usrspace,
> > If the DRM driver will support /dev/fbX, it could work correctly ?
> 
> Yes. DRM offers helper code to add /dev/fbX with not too many lines. You
> can look at the docs and drm_fb_helper.c.
> 
> And X11 should work fine on top of that, using the X11 fbdev support.
> 
>  Tomi
> 


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

* RE: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
@ 2014-12-04 10:03                 ` Li.Xiubo
  0 siblings, 0 replies; 35+ messages in thread
From: Li.Xiubo @ 2014-12-04 10:03 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Arnd Bergmann, plagnioj, linux-fbdev, linux-kernel, shawn.guo,
	alexander.stein

Hi Tomi,

Thanks very much for your help.

I will have a try these days.

BRs
Xiubo


> -----Original Message-----
> From: Tomi Valkeinen [mailto:tomi.valkeinen@ti.com]
> Sent: Thursday, December 04, 2014 6:00 PM
> To: Xiubo Li-B47053
> Cc: Arnd Bergmann; plagnioj@jcrosoft.com; linux-fbdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; shawn.guo@linaro.org; alexander.stein@systec-
> electronic.com
> Subject: Re: [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support.
> 
> On 04/12/14 11:54, Li.Xiubo@freescale.com wrote:
> > Hi Tomi,
> >
> > Thanks for your information very much.
> >
> >>> Sorry for confusing, it was delayed for other reasons internal.
> >>>
> >>> I am not familiar about the DRM, and I'd like to know if the DRM driver
> will
> >> be
> >>> support, should I also develop the libdrm too ? Or just coding in kernel
> >> level ?
> >>
> >> For simple drm drivers (this looks like it would be a simple one), I
> >> don't think there's any need for libdrm support. The generic DRM
> >> interfaces should be enough, so just kernel level coding needed.
> >>
> >
> > That's to say, if I am using the X11 server without any code in usrspace,
> > If the DRM driver will support /dev/fbX, it could work correctly ?
> 
> Yes. DRM offers helper code to add /dev/fbX with not too many lines. You
> can look at the docs and drm_fb_helper.c.
> 
> And X11 should work fine on top of that, using the X11 fbdev support.
> 
>  Tomi
> 


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

end of thread, other threads:[~2014-12-04 10:19 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-03  9:15 [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support Xiubo Li
2014-12-03  9:15 ` Xiubo Li
2014-12-03  9:15 ` Xiubo Li
2014-12-03  9:15 ` [PATCHv2 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform Xiubo Li
2014-12-03  9:15   ` Xiubo Li
2014-12-03  9:15   ` Xiubo Li
2014-12-04  9:21   ` Alexander Stein
2014-12-04  9:21     ` Alexander Stein
2014-12-04  9:21     ` Alexander Stein
2014-12-03  9:16 ` [PATCHv2 2/4] video: fsl-dcfb: Add devicetree binding support Xiubo Li
2014-12-03  9:16   ` Xiubo Li
2014-12-03  9:16   ` Xiubo Li
2014-12-03  9:16 ` [PATCHv2 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb Xiubo Li
2014-12-03  9:16   ` Xiubo Li
2014-12-03  9:16   ` Xiubo Li
2014-12-03  9:16 ` [PATCHv2 4/4] ARM: ls1021a: dts: Add and enable dt node " Xiubo Li
2014-12-03  9:16   ` Xiubo Li
2014-12-03  9:16   ` Xiubo Li
2014-12-03  9:51 ` [PATCHv2 0/4] LS1021A: Add dcfb framebuffer driver support Arnd Bergmann
2014-12-03  9:51   ` Arnd Bergmann
2014-12-03  9:51   ` Arnd Bergmann
2014-12-04  1:56   ` Li.Xiubo
2014-12-04  1:56     ` Li.Xiubo
2014-12-04  8:10     ` Tomi Valkeinen
2014-12-04  8:10       ` Tomi Valkeinen
2014-12-04  8:30       ` Li.Xiubo
2014-12-04  8:30         ` Li.Xiubo
2014-12-04  9:09         ` Tomi Valkeinen
2014-12-04  9:09           ` Tomi Valkeinen
2014-12-04  9:54           ` Li.Xiubo
2014-12-04  9:54             ` Li.Xiubo
2014-12-04  9:59             ` Tomi Valkeinen
2014-12-04  9:59               ` Tomi Valkeinen
2014-12-04 10:03               ` Li.Xiubo
2014-12-04 10:03                 ` Li.Xiubo

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.