LCD/es

From Qi-Hardware
< LCD
Jump to: navigation, search

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

Diagrama1.png

[edit] Diagrama temporal de la pantalla LCD

Diagrama2.png

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

  1. static struct fb_videomode qi_lb60_video_modes[] = {
  2. 	{
  3. 		.name = "320x240",
  4. 		.xres = 320,
  5. 		.yres = 240,
  6. 		.pixclock = 700000,
  7. 		.left_margin = 140,
  8. 		.right_margin = 273,
  9. 		.upper_margin = 20,
  10. 		.lower_margin = 2,
  11. 		.hsync_len = 1,
  12. 		.vsync_len = 1,
  13. 		.sync = 0,
  14. 		.vmode = FB_VMODE_NONINTERLACED,
  15. 	},
  16.  };
  17.  
  18.  static struct jz4740_fb_platform_data qi_lb60_fb_data = {
  19. 	.width	    = 60,
  20. 	.height	    = 45,
  21. 	.num_modes  = ARRAY_SIZE(qi_lb60_video_modes),
  22. 	.modes	    = qi_lb60_video_modes,
  23. 	.bpp	    = 24,
  24. 	.lcd_type   = JZ_LCD_TYPE_8BIT_SERIAL,
  25.  };
  26.  
  27.  static struct resource fb_resources[] = {
  28. 	[0] = {
  29. 		.start	= CPHYSADDR(LCD_BASE),
  30. 		.end	= CPHYSADDR(LCD_BASE) + 0x10000 - 1,
  31. 		.flags	= IORESOURCE_MEM,
  32. 	},
  33.  };
  34.  
  35.  static u64 jz_fb_dmamask = ~(u32)0;
  36.  
  37.  static struct platform_device qi_lb60_fb = {
  38. 	.name = "jz4740-fb",
  39. 	.id = -1,
  40. 	.num_resources = ARRAY_SIZE(fb_resources),
  41. 	.resource = fb_resources,
  42. 	.dev = {
  43. 		.dma_mask = &jz_fb_dmamask,
  44. 		.coherent_dma_mask = 0xffffffff,
  45. 		.platform_data = &qi_lb60_fb_data,
  46. 	},
  47.  };

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

Personal tools
Namespaces
Variants
Actions
Navigation
interactive
Toolbox
Print/export