LCD/es
Contents |
[edit] Controlador de LCD JZXXX
[edit] Introducción
El microprocesador JZ tiene integrado un controlador interno compatible con los estándares industriales STN y Paneles LCD TFT[[1]]. Además soporta algunos tipos especiales de pantallas TFT usadas comúnmente en el mercado electrónico. El Controlador Usa esencialmente una Memoria Besada en un "Frame Buffer" y en un "Palette Buffer" y esto se transfiere al panel LCD por medio de DMA[[2]].
[edit] Descripción de Pines
Nombre | LCD_PLK | LCD_VSYNC | LCD_HSYNC | LCD_DE | LCD_D[17:0] | LCD_SPL | LCD_CLS | LCD_PS | LCD_REV |
E/S | Entrada/Salida | Entrada/Salida | Entrada/Salida | Salida | Salida | Salida | Salida | Salida | Salida |
Descripción | 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] Diagrama de Bloques del Controlador
[edit] Diagrama temporal de la pantalla LCD
Nota H: Horizontal D: Área de la pantalla S: Punto inicial V: Vertical P: Pulso E: Punto final T: Total
Este diagrama muestra, como se sincroniza la pantalla LCD, cuyo funcionamiento es muy similar al sincronismo de una pantalla VGA. Haciendo un paralelo ahí tanto una señal para sincronizar el barrido Vertical y el barrido Horizontal.
[edit] Introduction to LCD Controllers Registers and Kernel definitions
En la siguiente tabla podemos observar los registros del controlador LCD
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
Para comenzar analizaremos un poco el archivo ubicado en arch/mips/include/asm/mach-jz4740/regs.h, donde se definen los registros de la tabla anterior y podremos saber un poco sobre el 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 */ ...
El bit 7 es reservado, cuando se intenta leer devulve '0' y no se escribe nada en él.
La configuración del PDW toma los bits 5:4.
... #define LCD_CFG_PDW_BIT 4 /* STN pins utilization */ #define LCD_CFG_PDW_MASK (0x3 << LCD_DEV_PDW_BIT) ...
Las opciones de configuración son las siguientes
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] |
Y así están definidos en el archivo:
... #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] */ ...
Ahora tenemos la configuración para el modo de operación del dispositivo.
... #define LCD_CFG_MODE_BIT 0 /* Display Device Mode Select */ #define LCD_CFG_MODE_MASK (0x0f << LCD_CFG_MODE_BIT) ...
Se toman los bits 3:0 para una configuración como sigue
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 |
Siendo definidos en el encabezado como se muestra a continuación:
... #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) ...
Los demás registros no son menos importantes por lo que se invita al lector a revisar su definición en el archivo reg.h. como en las anteriores definiciones estos están debidamente comentados para dar una idea de la función que cumple cada uno.
[edit] Frame Buffer
Primero veremos brevemente los archivos del kernel para el Frame Buffer (FB). Comencemos con los archivos ubicados en drivers/video/jz4740_fb.c y include/linux/jz4740_fb.h, en este driver se define las funciones necesarias para controlar el FB, por ejemplo, en él se hace una definición de los registros parecida a la del archivo reg.h, así
... #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 ...
Ahora, observando el archivo arch/mips/jz4740/platform.c encontramos la siguiente porsicón de código relacionada con el 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,
},
};
Vemos que de la línea 374 a 389 se declara una estructura de tipo fb_videomode en la que se definen algunas características y configuraciones del módulo LCD que se usa en el Qi-NanoNote, a destacar la resolución de 320x240, la frecuencia de reloj de pixel de 0.7MHz, lo márgenes, el ancho del pulso de sincronismo horizontal y vertical y la no especificación del modo de sincronismo. De la línea 391 a 398 se declara una estructura de tipo jz4740_fb_platform_data en la que se usa la anterior estructura como datos para los modos y a destacar la profundidad de pixel de 24bbp, y el tipo de LCD, en este caso de tipo serial de 8-Bit. De la línea 400 a 406 se declara una estructura de tipo resource donde se define la dirección del comienzo y final donde se encuentra el recurso, para este caso el JZ LCD Controller, así vemos que se usa constante LCD_BASE definida en el encabezado regs.h que es incluido a su vez en el encabezado jzsoc.h. De la línea 408 a 420 se define finalmente una estructura de tipo platform_device en la que se recopila la información de las anteriores estructuras.
[edit] Usando el Frame Buffer
....
[edit] Referencias
Tablas basadas en Jz4740 Multimedia Application Processor Programming Manual
[edit] PARA HACER ¿?
Pagina BAJO CONSTRUCCIÓN