Skip to contentSkip to conversation

video: sh7760fb: SH7760/SH7763 LCDC framebuffer driver

PATCH Superseded Nobuhiro Iwamatsu 4 participants 4 messages Jul 1, 2008 – Jul 2, 2008

Subsystems (3)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/1 video: sh7760fb: SH7760/SH7763 LCDC framebuffer driver

Driver for the LCDC interface on the SH7760 and SH7763 SoCs.

---
 Documentation/fb/sh7760fb.txt |  129 +++++++++
 drivers/video/Kconfig         |   13 +
 drivers/video/Makefile        |    1 +
 drivers/video/sh7760fb.c      |  640 +++++++++++++++++++++++++++++++++++++++++
 include/asm-sh/sh7760fb.h     |  175 +++++++++++
 5 files changed, 958 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/fb/sh7760fb.txt
 create mode 100644 drivers/video/sh7760fb.c
 create mode 100644 include/asm-sh/sh7760fb.h
Documentation/fb/sh7760fb.txt new file +128 -0
new file mode 100644
index 0000000..b8bf844
@@ -0,0 +1,129 @@
+SH7760 integrated LCDC Framebuffer driver
+====================+
+0. Overwiew
+-----------
+The SH7760/SH7763 have an integrated LCD Display controller (LCDC) which
+supports (in theory) resolutions ranging from 1x1 to 1024x1024,
+with color depths ranging from 1 to 16 bit.
+Supports STN, DSTN and TFT Panels.
+
+* Framebuffer memory must be a large chunk allocated at the top
+  of Area3 (HW requirement). Because of this requirement you should NOT
+  make the driver a module since at runtime it may become impossible to
+  get a large enough contiguous chunk of memory.
+
+* The driver does not support changing resolution while loaded
+  (LCD's aren't hotpluggable anyway)
+
+* Heavy flickering may be observed
+  a) if you're using 15/16bit color modes at >= 640x480 px resolutions,
+  b) during PCMCIA (or any other slow bus) activity.
+
+* Rotation works only 90degress clockwise, and only if horizontal
+  resolution is <= 320 pixels.
+
+files:   drivers/video/sh7760fb.c
+	 include/asm-sh/sh7760fb.h
+	 Documentation/fb/sh7760fb.txt
+
+1. Platform setup
+-----------------
+Video data is fetched via the DMABRG DMA engine, so you have to
+configure the SH DMAC for DMABRG mode (write 0x94808080 to the
+DMARSRA register somewhere at boot).
+
+PFC registers PCCR and PCDR must be set to peripheral mode.
+(write zeros to both).
+
+The driver does NOT do the above for you (since board setup is, well, job
+of the board setup code).
+
+2. Panel definitions
+--------------------
+The LCDC must explicitly be told about the type of LCD panel
+attached. Data must be wrapped in a "struct sh7760fb_platdata" and
+passed to the driver as platform_data.
+
+Suggest you take a closer look at the SH7760 Manual, Section 30.
+(http://documentation.renesas.com/eng/products/mpumcu/e602291_sh7760.pdf)
+
+The following code illustrates what needs to be done to
+get the framebuffer working on a 640x480 TFT:
+
+=========== cut here ===================
+
+#include <linux/fb.h>
+#include <asm/sh7760fb.h>
+
+/*
+ * NEC NL6440bc26-01 640x480 TFT
+ * dotclock 25175 kHz
+ * Xres		640	Yres		480
+ * Htotal	800	Vtotal		525
+ * HsynStart	656	VsynStart	490
+ * HsynLenn	30	VsynLenn	2
+ *
+ * The linux framebuffer layer does not use the syncstart/synclen
+ * values but right/left/upper/lower margin values. The comments
+ * for the x_margin explain how to calculate those from given
+ * panel sync timings.
+ */
+static struct fb_videomode nl6448bc26 = {
+/*	.name		= "NL6448BC26",*/
+/*	.refresh	= 60,	*/
+	.xres		= 640,
+	.yres		= 480,
+	.pixclock	= 39683,	/* in picoseconds! */
+	.hsync_len	= 30,
+	.vsync_len	= 2,
+	.left_margin	= 114,	/* HTOT - (HSYNSLEN + HSYNSTART) */
+	.right_margin	= 16,	/* HSYNSTART - XRES */
+	.upper_margin	= 33,	/* VTOT - (VSYNLEN + VSYNSTART) */
+	.lower_margin	= 10,	/* VSYNSTART - YRES */
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode		= FB_VMODE_NONINTERLACED,
+	.flag		= 0,
+};
+
+static struct sh7760fb_platdata sh7760fb_nl6448 = {
+	.def_mode	= &nl6448bc26,
+	.ldmtr		= LDMTR_TFT_COLOR_16,	/* 16bit TFT panel */
+	.lddfr		= LDDFR_8BPP,		/* we want 8bit output */
+	.ldpmmr		= 0x0070,
+	.ldpspr		= 0x0500,
+	.ldaclnr	= 0,
+	.ldickr		= LDICKR_CLKSRC(LCDC_CLKSRC_EXTERNAL) |
+			  LDICKR_CLKDIV(1),
+	.rotate		= 0,
+	.novsync	= 1,
+	.blank		= NULL,
+};
+
+/* 0xFE300800: 256 * 4byte xRGB palette ram
+ * 0xFE300C00: 42 bytes ctrl registers
+ */
+static struct resource sh7760_lcdc_res[] = {
+	[0] = {
+		.start	= 0xFE300800,
+		.end	= 0xFE300CFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 65,
+		.end	= 65,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sh7760_lcdc_dev = {
+	.dev	= {
+		.platform_data = &sh7760fb_nl6448,
+	},
+	.name		= "sh7760-lcdc",
+	.id		= -1,
+	.resource	= sh7760_lcdc_res,
+	.num_resources	= ARRAY_SIZE(sh7760_lcdc_res),
+};
+
+=========== cut here ===================
drivers/video/Kconfig +13 -0
index 002b61b..f79634d 100644
@@ -1950,6 +1950,19 @@ config FB_AM200EPD
          This enables support for the Metronome display controller used on
          the E-Ink AM-200 EPD devkit.
 
+config FB_SH7760
+	bool "SH7760/SH7763 LCDC support"
+	depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the SH7760/SH7763 integrated (D)STN/TFT LCD Controller.
+	  Supports display resolutions up to 1024x1024 pixel, grayscale and
+	  color operation, with depths ranging from 1 bpp to 8 bpp monochrome
+	  and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
+	  panels <= 320 pixel horizontal resolution.
+
 config FB_VIRTUAL
 	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
 	depends on FB
drivers/video/Makefile +1 -0
index 04bca35..0dcd740 100644
@@ -117,6 +117,7 @@ obj-$(CONFIG_FB_SM501)            += sm501fb.o
 obj-$(CONFIG_FB_XILINX)           += xilinxfb.o
 obj-$(CONFIG_FB_OMAP)             += omap/
 obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o
+obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o
drivers/video/sh7760fb.c new file +639 -0

639 lines not on this page · raw message

include/asm-sh/sh7760fb.h new file +175 -0

175 lines not on this page · raw message

Signature · 1 line
1.5.5.1
Reviewed-by on v3 1/1
#1 lore raw
Quoted 13 lines · Nobuhiro Iwamatsu

+=========== cut here ===================

Documentation/fb/sh7760fb.txt new file +12 -0
+
+#include <linux/fb.h>
+#include <asm/sh7760fb.h>
+
+/*
+ * NEC NL6440bc26-01 640x480 TFT
+ * dotclock 25175 kHz
+ * Xres		640	Yres		480
+ * Htotal	800	Vtotal		525
+ * HsynStart	656	VsynStart	490
+ * HsynLenn	30	VsynLenn	2
+ *

Documentation/fb/sh7760fb.txt line 75

Quoted 10 lines
Documentation/fb/sh7760fb.txt new file +10 -0
+ * The linux framebuffer layer does not use the syncstart/synclen
+ * values but right/left/upper/lower margin values. The comments
+ * for the x_margin explain how to calculate those from given
+ * panel sync timings.
+ */
+static struct fb_videomode nl6448bc26 = {
+/*	.name		= "NL6448BC26",*/
+/*	.refresh	= 60,	*/
+	.xres		= 640,
+	.yres		= 480,

Why are .name and .refresh commented out?

drivers/video/sh7760fb.c line 54

Quoted 8 lines
drivers/video/sh7760fb.c new file +8 -0
+static void sh7760fb_wait_vsync(struct fb_info *info)
+{
+	struct sh7760fb_par *par = info->par;
+
+	if (par->pd->novsync)
+		return;
+}
+

This doesn't do anything, and you never use ->novsync for anything anywhere else either. I'd suggest killing both of them off until such a time that you plan to do something with it.

drivers/video/sh7760fb.c line 121

Quoted 5 lines
drivers/video/sh7760fb.c new file +5 -0
+	/* poll for access grant */
+	tmo = 100;
+	while (!(ioread16(par->base + LDPALCR) & (1 << 4)) && (--tmo))
+		msleep(0);
+

Err.. you are sleeping for 0ms? Just use cpu_relax() here instead if you don't have an explicit timing requirement.

drivers/video/sh7760fb.c line 348

Quoted 5 lines
drivers/video/sh7760fb.c new file +5 -0
+	if (((ldmtr & 0x003f) >= LDMTR_DSTN_MONO_8) &&
+	    ((ldmtr & 0x003f) <= LDMTR_DSTN_COLOR_16)) {
+
+		pr_debug(" ***** DSTN untested! *****\n");
+

This should still use dev_dbg() for consistency.

Looks good to me otherwise, fix those up and feel free to add a:

to the next version.

#2 lore raw

Hello Paul, Iwamatsu-san,

Quoted 12 lines · Paul Mundt

drivers/video/sh7760fb.c line 54

Quoted 8 lines · Nobuhiro Iwamatsu
drivers/video/sh7760fb.c new file +8 -0
+static void sh7760fb_wait_vsync(struct fb_info *info)
+{
+	struct sh7760fb_par *par = info->par;
+
+	if (par->pd->novsync)
+		return;
+}
+

This doesn't do anything, and you never use ->novsync for anything anywhere else either. I'd suggest killing both of them off until such a time that you plan to do something with it.

I'm working on reimplementing it. I'll submit a patch when it's ready.

Quoted 7 lines

drivers/video/sh7760fb.c line 121

Quoted 5 lines
drivers/video/sh7760fb.c new file +5 -0
+	/* poll for access grant */
+	tmo = 100;
+	while (!(ioread16(par->base + LDPALCR) & (1 << 4)) && (--tmo))
+		msleep(0);
+

Err.. you are sleeping for 0ms? Just use cpu_relax() here instead if you don't have an explicit timing requirement.

I put the msleep here to prevent gcc from removing the loop.

Best regards,
Manuel Lauss

#3 lore raw
In reply to Paul Mundt

2008/7/1 Paul Mundt <[email protected]>:

Quoted 53 lines · Nobuhiro Iwamatsu
Quoted 13 lines

+=========== cut here ===================

Documentation/fb/sh7760fb.txt new file +12 -0
+
+#include <linux/fb.h>
+#include <asm/sh7760fb.h>
+
+/*
+ * NEC NL6440bc26-01 640x480 TFT
+ * dotclock 25175 kHz
+ * Xres              640     Yres            480
+ * Htotal    800     Vtotal          525
+ * HsynStart 656     VsynStart       490
+ * HsynLenn  30      VsynLenn        2
+ *

Documentation/fb/sh7760fb.txt line 75

Quoted 10 lines
Documentation/fb/sh7760fb.txt new file +10 -0
+ * The linux framebuffer layer does not use the syncstart/synclen
+ * values but right/left/upper/lower margin values. The comments
+ * for the x_margin explain how to calculate those from given
+ * panel sync timings.
+ */
+static struct fb_videomode nl6448bc26 = {
+/*   .name           = "NL6448BC26",*/
+/*   .refresh        = 60,   */
+     .xres           = 640,
+     .yres           = 480,

Why are .name and .refresh commented out?

drivers/video/sh7760fb.c line 54

Quoted 8 lines
drivers/video/sh7760fb.c new file +8 -0
+static void sh7760fb_wait_vsync(struct fb_info *info)
+{
+     struct sh7760fb_par *par = info->par;
+
+     if (par->pd->novsync)
+             return;
+}
+

This doesn't do anything, and you never use ->novsync for anything anywhere else either. I'd suggest killing both of them off until such a time that you plan to do something with it.

drivers/video/sh7760fb.c line 121

Quoted 5 lines
drivers/video/sh7760fb.c new file +5 -0
+     /* poll for access grant */
+     tmo = 100;
+     while (!(ioread16(par->base + LDPALCR) & (1 << 4)) && (--tmo))
+             msleep(0);
+

Err.. you are sleeping for 0ms? Just use cpu_relax() here instead if you don't have an explicit timing requirement.

drivers/video/sh7760fb.c line 348

Quoted 5 lines
drivers/video/sh7760fb.c new file +5 -0
+     if (((ldmtr & 0x003f) >= LDMTR_DSTN_MONO_8) &&
+         ((ldmtr & 0x003f) <= LDMTR_DSTN_COLOR_16)) {
+
+             pr_debug(" ***** DSTN untested! *****\n");
+

This should still use dev_dbg() for consistency.

Quoted 6 lines

Looks good to me otherwise, fix those up and feel free to add a:

to the next version.

Thank for your work.

I got message and patch which revised the place that you pointed out from Manuel.
I will check patch and operation check on SH7763.

Best regards,
Nobuhiro.