LCD
Contents |
[edit] Specifications
- GPM940B0
- 3.0" (60mm x 45mm)
- 320x240
- 24-bit color depth
- 8-bit passive matrix interface
- Datasheet
[edit] Pixel Layout
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:
- Pixels on even-numbered rows use RGB=#fff (for a white line)
- 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
In the datasheet, 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. The Ben NanoNote uses the 3-wire interface to configure R13h for the "delta color filter" (CF_SEL = 0) using "alignment mode" (IN_SEL = 1). Thus, data can be sent in red, green, blue order without needing to be concerned with the filter layout.
[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