LCD

From Qi-Hardware
Jump to: navigation, search

Contents

[edit] Specifications

  • GPM940B0
  • 3.0" (60mm x 45mm)
  • 320x240
  • 24-bit color depth
  • 8-bit passive matrix interface
  • Datasheet

[edit] Pixel Layout

Ben-NanoNote-pixels.png
The image on the left shows the arrangement of the pixels on the LCD on the Ben NanoNote.

The components of pixels in even-numbered rows are laid out in the common R G B manner.

In odd-numbered rows the components are laid out G B R and are offset 1/6th of a pixel width to the left

This pixel arrangement causes jaggies on vertical lines.

If the lines to be drawn are monochrome ( from black to white through any gray) then the jaggies can be removed by "borrowing" color components from neighboring pixels like so:

  1. Pixels on even-numbered rows use RGB=#fff (for a white line)
  2. For odd-numbered rows, use a #f8f pixel AND a #080 pixel to the right (in other words, reduce the green to 50% and "borrow" 50% green from the pixel to the right)

[edit] Observations

The datasheet is somewhat confusing in this regard: R13h of the 3-wire interface registers refers to two "color filter" modes ("delta" and "stripe"), with the "delta" mode corresponding to the above pixel layout and the "stripe" mode corresponding to a more conventional arrangement; section 10.4, however, is illustrated with the above layout. However, the Ben NanoNote does not use the 3-wire interface anyway.

[edit] Pin Description

Name LCD_PLK LCD_VSYNC LCD_HSYNC LCD_DE LCD_D[17:0] LCD_SPL LCD_CLS LCD_PS LCD_REV
I/O INPUT/OUTPUT INPUT/OUTPUT INPUT/OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT
Description Display pixel clock Display device vertical pulse Display device horizontal pulse Display device is STN: AC BIAS Pin
 Display device is NOT STN: data enable Pin
Display device data pins Programming special pin for generating control signals Programming special pin for generating control signals Programming special pin for generating control signals Programming special pin for generating control signals



[edit] Introduction to LCD Controllers Registers and Kernel definitions

On the next table we can see the JZ4720 LCD controller registers

Name register Type Initial value Address Size
LCDCFG RW 0x00000000 0x13050000 32
LCDVSYNC RW 0x00000000 0x13050004 32
LCDHSYNC RW 0x00000000 0x13050008 32
LCDVAT RW 0x00000000 0x1305000C 32
LCDDAH RW 0x00000000 0x13050010 32
LCDDAV RW 0x00000000 0x13050014 32
LCDPS RW 0x00000000 0x13050018 32
LCDCLS RW 0x00000000 0x1305001C 32
LCDSPL RW 0x00000000 0x13050020 32
LCDREV RW 0x00000000 0x13050024 32
LCDCTRL RW 0x00000000 0x13050030 32
LCDSTATE RW 0x00000000 0x13050034 32
LCDIID R 0x00000000 0x13050038 32
LCDDA0 RW 0x00000000 0x13050040 32
LCDSA0 R 0x00000000 0x13050044 32
LCDFID0 R 0x00000000 0x13050048 32
LCDCMD0 R 0x00000000 0x1305004C 32
LCDDA1 RW 0x00000000 0x13050050 32
LCDSA1 R 0x00000000 0x13050054 32
LCDFID1 R 0x00000000 0x13050058 32
LCDCMD1 R 0x00000000 0x1305005C 32


Kernel Source

We going to analyze the file arch/mips/include/asm/mach-jz4740/regs.h, in this file are defined the registers of the table above, and we going to know a little about the LCD Configure Register.

LCD controller base registers definition.

...
 #define	LCD_BASE	0xB3050000
 #define	SLCD_BASE	0xB3050000
...
 /*************************************************************************
  * LCD (LCD Controller)
  *************************************************************************/
 #define LCD_CFG	(LCD_BASE + 0x00) /* LCD Configure Register */
 #define LCD_VSYNC	(LCD_BASE + 0x04) /* Vertical Synchronize Register */
 #define LCD_HSYNC	(LCD_BASE + 0x08) /* Horizontal Synchronize Register */
 #define LCD_VAT	(LCD_BASE + 0x0c) /* Virtual Area Setting Register */
 #define LCD_DAH	(LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */
 #define LCD_DAV	(LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */
 #define LCD_PS	(LCD_BASE + 0x18) /* PS Signal Setting */
 #define LCD_CLS	(LCD_BASE + 0x1c) /* CLS Signal Setting */
 #define LCD_SPL	(LCD_BASE + 0x20) /* SPL Signal Setting */
 #define LCD_REV	(LCD_BASE + 0x24) /* REV Signal Setting */
 #define LCD_CTRL	(LCD_BASE + 0x30) /* LCD Control Register */
 #define LCD_STATE	(LCD_BASE + 0x34) /* LCD Status Register */
 #define LCD_IID	(LCD_BASE + 0x38) /* Interrupt ID Register */
 #define LCD_DA0	(LCD_BASE + 0x40) /* Descriptor Address Register 0 */
 #define LCD_SA0	(LCD_BASE + 0x44) /* Source Address Register 0 */
 #define LCD_FID0	(LCD_BASE + 0x48) /* Frame ID Register 0 */
 #define LCD_CMD0	(LCD_BASE + 0x4c) /* DMA Command Register 0 */
 #define LCD_DA1	(LCD_BASE + 0x50) /* Descriptor Address Register 1 */
 #define LCD_SA1	(LCD_BASE + 0x54) /* Source Address Register 1 */
 #define LCD_FID1	(LCD_BASE + 0x58) /* Frame ID Register 1 */
 #define LCD_CMD1	(LCD_BASE + 0x5c) /* DMA Command Register 1 */
 .
 #define REG_LCD_CFG	REG32(LCD_CFG)
 #define REG_LCD_VSYNC	REG32(LCD_VSYNC)
 #define REG_LCD_HSYNC	REG32(LCD_HSYNC)
 #define REG_LCD_VAT	REG32(LCD_VAT)
 #define REG_LCD_DAH	REG32(LCD_DAH)
 #define REG_LCD_DAV	REG32(LCD_DAV)
 #define REG_LCD_PS	REG32(LCD_PS)
 #define REG_LCD_CLS	REG32(LCD_CLS)
 #define REG_LCD_SPL	REG32(LCD_SPL)
 #define REG_LCD_REV	REG32(LCD_REV)
 #define REG_LCD_CTRL	REG32(LCD_CTRL)
 #define REG_LCD_STATE	REG32(LCD_STATE)
 #define REG_LCD_IID	REG32(LCD_IID)
 #define REG_LCD_DA0	REG32(LCD_DA0)
 #define REG_LCD_SA0	REG32(LCD_SA0)
 #define REG_LCD_FID0	REG32(LCD_FID0)
 #define REG_LCD_CMD0	REG32(LCD_CMD0)
 #define REG_LCD_DA1	REG32(LCD_DA1)
 #define REG_LCD_SA1	REG32(LCD_SA1)
 #define REG_LCD_FID1	REG32(LCD_FID1)
 #define REG_LCD_CMD1	REG32(LCD_CMD1)
...

LCD Configure Register definition.

Selection Bit:

...
 /* LCD Configure Register */
 #define LCD_CFG_LCDPIN_BIT	31  /* LCD pins selection */
...

LCD Pin Select bit function description:

LCDPIN Value Function
0 LCD PIN, select standard LCD
1 SLCD PIN, select smart LCD
...
 #define LCD_CFG_LCDPIN_MASK	(0x1 << LCD_CFG_LCDPIN_BIT)
 #define LCD_CFG_LCDPIN_LCD	(0x0 << LCD_CFG_LCDPIN_BIT)
 #define LCD_CFG_LCDPIN_SLCD	(0x1 << LCD_CFG_LCDPIN_BIT)
...

All 30:24 bits are reserved. when they are being read, they return '0' and do not write anything. 23:8 Bits definition:

...
 #define LCD_CFG_PSM		(1 << 23) /* PS signal mode */
 #define LCD_CFG_CLSM		(1 << 22) /* CLS signal mode */
 #define LCD_CFG_SPLM		(1 << 21) /* SPL signal mode */
 #define LCD_CFG_REVM		(1 << 20) /* REV signal mode */
 #define LCD_CFG_HSYNM		(1 << 19) /* HSYNC signal mode */
 #define LCD_CFG_PCLKM		(1 << 18) /* PCLK signal mode */
 #define LCD_CFG_INVDAT	(1 << 17) /* Inverse output data */
 #define LCD_CFG_SYNDIR_IN	(1 << 16) /* VSYNC&HSYNC direction */
 #define LCD_CFG_PSP		(1 << 15) /* PS pin reset state */
 #define LCD_CFG_CLSP		(1 << 14) /* CLS pin reset state */
 #define LCD_CFG_SPLP		(1 << 13) /* SPL pin reset state */
 #define LCD_CFG_REVP		(1 << 12) /* REV pin reset state */
 #define LCD_CFG_HSP		(1 << 11) /* HSYNC pority:0-active high,1-active low */
 #define LCD_CFG_PCP		(1 << 10) /* PCLK pority:0-rising,1-falling */
 #define LCD_CFG_DEP		(1 << 9)  /* DE pority:0-active high,1-active low */
 #define LCD_CFG_VSP		(1 << 8)  /* VSYNC pority:0-rising,1-falling */
...

Bit 7 is reserved , when you attempt to read returns '0' and nothing is written in it. The PDW configuration takes the bits 5:4

...
 #define LCD_CFG_PDW_BIT	4  /* STN pins utilization */
 #define LCD_CFG_PDW_MASK	(0x3 << LCD_DEV_PDW_BIT)
...

The configuration options are as follows:

PDW_BIT value Signal Panel
00 Lcd_d[0]
01 Lcd_d[0:1]
10 Lcd_d[0:3]
11 Lcd_d[0:7]
Dual-Monochrome Panel
00 Reserved
01 Reserved
10 Upper panel: lcd_d[3:0], lower panel: lcd_d[11:8]
11 Upper panel: lcd_d[7:0], lower panel: lcd_d[15:8]

And so are defined in the file:

...
 #define LCD_CFG_PDW_1		(0 << LCD_CFG_PDW_BIT) /* LCD_D[0] */
 #define LCD_CFG_PDW_2		(1 << LCD_CFG_PDW_BIT) /* LCD_D[0:1] */
 #define LCD_CFG_PDW_4		(2 << LCD_CFG_PDW_BIT) /* LCD_D[0:3]/LCD_D[8:11] */
 #define LCD_CFG_PDW_8		(3 << LCD_CFG_PDW_BIT) /* LCD_D[0:7]/LCD_D[8:15] */
...

Now we have the settings for the operating mode of the device.

...
 #define LCD_CFG_MODE_BIT	0  /* Display Device Mode Select */
 #define LCD_CFG_MODE_MASK	(0x0f << LCD_CFG_MODE_BIT)
...

3:0 bits are taken to a configuration as follows

MODE_BIT value LCD Panel type
0000 Generic 16-bit/18-bit Parallel TFT Panel
0001 Special TFT Panel Mode1
0010 Special TFT Panel Mode2
0011 Special TFT Panel Mode3
0100 Non-Interlaced CCIR656
0101 Reserved
0110 Interlaced CCIR656
0111 Reserved
1000 Single-Color STN Panel
1001 Single-Monochrome STN Panel
1010 Dual-Color STN Panel
1011 Dual-Monochrome STN Panel
1100 8-bit Serial TFT
1101 Reserved
1110 Reserved
1111 Reserved

As defined in the header as shown below:

...
 #define LCD_CFG_MODE_GENERIC_TFT	 (0 << LCD_CFG_MODE_BIT) /* 16,18 bit TFT */
 #define LCD_CFG_MODE_SPECIAL_TFT_1	 (1 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_SPECIAL_TFT_2	 (2 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_SPECIAL_TFT_3	 (3 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_NONINTER_CCIR656	 (4 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_INTER_CCIR656	 (6 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_SINGLE_CSTN	 (8 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_SINGLE_MSTN	 (9 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_DUAL_CSTN	 (10 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_DUAL_MSTN	 (11 << LCD_CFG_MODE_BIT)
 #define LCD_CFG_MODE_SERIAL_TFT	 (12 << LCD_CFG_MODE_BIT)
...

You are invited to review the others registers in the file reg.h. As in previous definitions these are properly annotated to give an idea of the role of each.

[edit] Frame Buffer

First we'll see the files of the kernel for the Frame Buffer (FB).Let's start with the files located in drivers/video/jz4740_fb.c and include/linux/jz4740_fb.h, in this driver are defined the functions necessary to control the FB, for example, there is a definition of registers similar to the file reg.h well

...
 #define JZ_REG_LCD_CFG	0x00
 #define JZ_REG_LCD_VSYNC	0x04
 #define JZ_REG_LCD_HSYNC	0x08
 #define JZ_REG_LCD_VAT	0x0C
 #define JZ_REG_LCD_DAH	0x10
 #define JZ_REG_LCD_DAV	0x14
 #define JZ_REG_LCD_PS		0x18
 #define JZ_REG_LCD_CLS	0x1C
 #define JZ_REG_LCD_SPL	0x20
 #define JZ_REG_LCD_REV	0x24
 #define JZ_REG_LCD_CTRL	0x30
 #define JZ_REG_LCD_STATE	0x34
 #define JZ_REG_LCD_IID	0x38
 #define JZ_REG_LCD_DA0	0x40
 #define JZ_REG_LCD_SA0	0x44
 #define JZ_REG_LCD_FID0	0x48
 #define JZ_REG_LCD_CMD0	0x4C
 #define JZ_REG_LCD_DA1	0x50
 #define JZ_REG_LCD_SA1	0x54
 #define JZ_REG_LCD_FID1	0x58
 #define JZ_REG_LCD_CMD1	0x5C
 
 #define JZ_LCD_CFG_SLCD     BIT(31)
 #define JZ_LCD_CFG_PSM      BIT(23)
 #define JZ_LCD_CFG_CLSM     BIT(22)
 #define JZ_LCD_CFG_SPLM     BIT(21)
 #define JZ_LCD_CFG_REVM     BIT(20)
 #define JZ_LCD_CFG_HSYNCM   BIT(19)
 #define JZ_LCD_CFG_PCLKM    BIT(18)
 #define JZ_LCD_CFG_INV      BIT(17)
 #define JZ_LCD_CFG_SYNC_    DIR BIT(16)
 #define JZ_LCD_CFG_PSP      BIT(15)
 #define JZ_LCD_CFG_CLSP     BIT(14)
 #define JZ_LCD_CFG_SPLP     BIT(13)
 #define JZ_LCD_CFG_REVP     BIT(12)
 #define JZ_LCD_CFG_HSYNCP   BIT(11)
 #define JZ_LCD_CFG_PCLKP    BIT(10)
 #define JZ_LCD_CFG_DEP      BIT(9)
 #dfine JZ_LCD_CFG_VSYNCP    BIT(8)
 #define JZ_LCD_CFG_18_BIT   BIT(7)
 #define JZ_LCD_CFG_PDW      BIT(5) | BIT(4)
 #define JZ_LCD_CFG_MODE_MASK 0xf
...

Now, observing the file: arch/mips/jz4740/platform.c , we find the following code related with FB

static struct fb_videomode qi_lb60_video_modes[] = {
	{
		.name = "320x240",
		.xres = 320,
		.yres = 240,
		.pixclock = 700000,
		.left_margin = 140,
		.right_margin = 273,
		.upper_margin = 20,
		.lower_margin = 2,
		.hsync_len = 1,
		.vsync_len = 1,
		.sync = 0,
		.vmode = FB_VMODE_NONINTERLACED,
	},
 };
 
 static struct jz4740_fb_platform_data qi_lb60_fb_data = {
	.width	    = 60,
	.height	    = 45,
	.num_modes  = ARRAY_SIZE(qi_lb60_video_modes),
	.modes	    = qi_lb60_video_modes,
	.bpp	    = 24,
	.lcd_type   = JZ_LCD_TYPE_8BIT_SERIAL,
 };
 
 static struct resource fb_resources[] = {
	[0] = {
		.start	= CPHYSADDR(LCD_BASE),
		.end	= CPHYSADDR(LCD_BASE) + 0x10000 - 1,
		.flags	= IORESOURCE_MEM,
	},
 };
 
 static u64 jz_fb_dmamask = ~(u32)0;
 
 static struct platform_device qi_lb60_fb = {
	.name = "jz4740-fb",
	.id = -1,
	.num_resources = ARRAY_SIZE(fb_resources),
	.resource = fb_resources,
	.dev = {
		.dma_mask = &jz_fb_dmamask,
		.coherent_dma_mask = 0xffffffff,
		.platform_data = &qi_lb60_fb_data,
	},
 };

[edit] References

Tables based on Jz4740 Multimedia Application Processor Programming Manual


[edit] TO DO ¿?

Add here things to do.

FILE: drivers/video/jz4740_fb.c

Personal tools
Namespaces
Variants
Actions
Navigation
interactive
Toolbox
Print/export