interfaz mipi_dsi para pantalla lvds (GM8775C)

Tabla de contenido


prefacio

Este artículo explica principalmente el protocolo mipi DSI, el registro de depuración de mipi y el registro de depuración del chip adaptador de mipi a LVDS GM8775C.

Escenario: dado que nuestra empresa necesita usar la interfaz mipi dsi para LVDS, necesitamos usar el chip adaptador GM8775C. El chip es de doble canal, lo que significa que se pueden conectar dos pantallas LVDS externamente. Pero nuestra empresa solo conecta una pantalla LVDS externamente, por supuesto, depende del método de conexión con su circuito.

Análisis: en este caso, necesitamos depurar dos módulos, uno es el extremo de la pantalla mipi, el otro extremo es el extremo del chip de conversión GM8775C, y GM8775C no tiene código de controlador, debemos escribirlo y agregarlo nosotros mismos, pero esto también es muy simple, porque en realidad es un dispositivo I2C.


1. Introducción al protocolo MIPI_DSI

MIPI-DSI es una interfaz serial aplicada a la tecnología de visualización, compatible con DPI (Display Pixel Interface, Display Pixel Interface), DBI (Display Bus Interface, Display Bus Interface) y DCS (Display Command Set, Display Command Set), para enviar píxeles información o instrucciones a los periféricos en serie, y lea la información de estado o la información de píxeles de los periféricos, y disfrute de su propio protocolo de comunicación independiente durante la transmisión, incluido el formato de paquete de datos y el mecanismo de corrección y detección de errores.

MIPI-DSI tiene dos modos de trabajo: modo de alta velocidad y modo de baja velocidad Todos los canales de datos (1 ~ 4 conjuntos de canales de datos se pueden usar para transmisión unidireccional de alta velocidad, pero solo el primer canal de datos se puede usar para baja -velocidad de transmisión bidireccional (si es Si hay 4 líneas de datos, data0 se puede usar para transmisión bidireccional en modo de baja velocidad, mientras que data1-data3 solo se puede transmitir en una dirección) Información de estado del periférico, formato de píxel y otra información se devuelve a través del primer canal de datos.El canal del reloj se utiliza En el proceso de transmisión de datos, se transmiten señales de reloj síncronas (estrictamente hablando, en modo de baja velocidad, los parámetros generalmente se envían o se lee el estado periférico, y la sincronización del reloj no se requiere en el modo de baja velocidad, porque el canal de datos En un modo de baja velocidad, la sincronización se puede lograr usando una señal diferencial).

1. Explicación de términos

1. DCS (DisplayCommandSet): DCS es un conjunto de comandos estandarizados para módulos de visualización en modo de comando.

• DSI, CSI (DisplaySerialInterface, CameraSerialInterface

  • DSI define una interfaz serial de alta velocidad entre el procesador y el módulo de visualización.

  • CSI define una interfaz serial de alta velocidad entre el procesador y el módulo de la cámara.

• D-PHY: proporciona definiciones de capa física para DSI y CSI

 2. Estructura jerárquica de DSI

DSI se divide en cuatro capas, correspondientes a las especificaciones D-PHY, DSI y DCS, y el diagrama de estructura en capas es el siguiente: •
PHY define el medio de transmisión, los circuitos de entrada/salida y los mecanismos de reloj y señal.
• Capa de gestión de carriles: envíe y recopile el flujo de datos a cada carril.
• Capa de protocolo de bajo nivel: define cómo enmarcar, analizar y detectar errores.
• Capa de aplicación: describe el flujo de datos de análisis y codificación de alto nivel.

3. Modo de comando y video
• Los periféricos compatibles con DSI admiten el modo de operación de comando o video, cuyo modo está determinado por la arquitectura periférica
• El modo de comando se refiere al envío de comandos y datos al controlador con el búfer de visualización. El host controla indirectamente los periféricos a través de comandos. El modo de comando utiliza una interfaz bidireccional.
• El modo de video se refiere a la transmisión de píxeles en tiempo real desde el host al periférico. Este modo solo puede transmitir a alta velocidad. Para reducir la complejidad y ahorrar costos, los sistemas que solo usan el modo Video pueden tener solo una ruta de datos unidireccional.

4. Tres tipos de carriles principales

  • Carril de reloj unidireccional

  • Carril de datos unidireccional

  • Carril de datos bidireccional

5. Modo de transmisión D-PHY

  • Modo de señalización de baja potencia (para control): 10 MHz (máx.)

  • Modo de señal de alta velocidad (High-Speed) (para transmisión de datos de alta velocidad): 80Mbps ~ 1Gbps/Lane

• El protocolo de bajo nivel D-PHY estipula que la unidad de datos mínima es un byte

  • Al enviar datos, el bit bajo debe ir primero y el bit alto debe seguir.

• D-PHY para aplicaciones móviles

  • DSI: interfaz serie de pantalla

     • Un carril de reloj, uno o más carriles de datos 

  • CSI: interfaz serie de la cámara

6. Módulo de carril

• PHY consta de D-PHY (módulo Lane)

• D-PHY puede contener:

  • Transmisor de baja potencia (LP-TX) 

  • Receptor de baja potencia (LP-RX)

  • Transmisor de alta velocidad (HS-TX)  

  • Receptor de alta velocidad (HS-RX)

  • Detector de contención de baja potencia (LP-CD)

7. Tres tipos de carriles principales

  • Carril de reloj unidireccional

    • Maestro: HS-TX, LP-TX

    • Esclavo: HS-RX, LP-RX

  • Carril de datos unidireccional

    • Maestro: HS-TX, LP-TX

    • Esclavo: HS-RX, LP-RX

  • Carril de datos bidireccional

    • Maestro, Esclavo: HS-TX, LP-TX, HS-RX, LP-RX, LP-CD

8. Estado del carril y voltaje

  • Estado del carril 

    • LP-00, LP-01, LP-10, LP-11 (terminal simple)

    • HS-0, HS-1 (diferencial)

  • Voltaje de carril (típico) 

    • LP: 0-1,2 V

    • SA:100-300mV (200mV)

2. Capas de circuitos de aplicación DSI

MIPI-DSI se divide en cuatro capas: capa de aplicación , capa de protocolo, capa de gestión de canales y capa física. MIPI-DSI es un protocolo de comunicación aplicado a la interfaz, y su trabajo de circuito general coopera con cada capa definida por el protocolo. Como se muestra abajo:

Capa de aplicación : según las necesidades del módulo de aplicación, el comando y los datos enviados se codifican inicialmente y se convierten al formato especificado por MIPI-DSI en el extremo de envío, y los datos recibidos se restauran al formato de datos admitido por el módulo de aplicación. en el extremo receptor requisitos de secuencia. 

Capa de protocolo : la transmisión de información adopta el formato de paquete de datos, incluido el paquete de datos largo y el paquete de datos corto. Al enviar datos, los datos se comprimen según el tipo de información y el contenido, y se completa la generación del código ECC y la adición del código CRC. Al recibir datos, la detección y corrección de errores se realiza en todo el paquete de datos de acuerdo con el código ECC y el código CRC, y la decodificación del encabezado del paquete y el contenido de los datos se completa y se envía razonablemente a la capa de aplicación.

Capa de gestión de canales : Según los N (como máximo 4) canales de datos establecidos por el diseño, esta capa divide los datos a enviar en N grupos según el orden de los canales y los envía a los canales de datos correspondientes para que puedan ser enviado simultáneamente a través de los canales de datos al lado esclavo. En el extremo receptor, lo que debe hacer esta capa es combinar los N conjuntos de datos recibidos para restaurar la secuencia de datos original. 

Capa física : al recibir una solicitud de transmisión de baja velocidad, el circuito lógico serializa la instrucción o los datos que se enviarán, y controla la salida de un nivel de baja potencia de oscilación alta para realizar una solicitud de transmisión de baja potencia, y luego serializa la instrucciones o datos cargados en el canal, el extremo receptor reconoce el modo de transmisión para completar la conversión paralela de datos en serie. Después de recibir una solicitud de alta velocidad, el circuito envía un nivel de consumo de energía alto y bajo para la solicitud de transmisión de alta velocidad, y luego impulsa el módulo de transmisión diferencial para transmitir en el canal con una señal de bajo cambio después de la conversión en serie de los datos que se enviarán y el extremo receptor los reconoce Después del modo de alta velocidad, la señal síncrona se detecta correctamente y los datos en serie de alta velocidad se reciben con éxito después de la conversión de serie a paralelo. Además, el derecho de control del bus se puede intercambiar entre el maestro y el esclavo. El remitente envía una solicitud de abandono del bus y el receptor controla el bus para iniciar una respuesta después de recibir la solicitud. El proceso general es un TA (giro). operación. Cuando el host necesita obtener los datos recibidos por el esclavo o leer los parámetros del módulo de visualización o mostrar los datos, el host inicia una operación TA e inicia automáticamente la operación TA después de que el esclavo envía datos para devolver el control del bus. (En general, es un proceso interactivo, un poco como el protocolo de enlace de tres vías TCP y la onda de cuatro vías. En el proceso de interacción, se enviarán algunas instrucciones y el rendimiento específico de los datos de respuesta depende del análisis del módulo específico También se puede utilizar en los datos analizados en la forma de onda.)

Capa física MIPI-DSI (protocolo D-PHY)

        En la capa física de todo el protocolo, se usa una conexión síncrona entre el extremo maestro y el extremo esclavo, el canal de reloj se usa para transmitir relojes de alta velocidad y uno o más canales de datos se usan para transmitir señales de datos de baja potencia. o señales de datos de alta velocidad. Cada canal utiliza dos cables de interconexión para realizar la conexión entre el extremo maestro y el extremo esclavo, y admite el modo de alta velocidad y el modo ESCAPE de baja velocidad. En el modo de alta velocidad, el transmisor impulsa las únicas dos líneas de interconexión del canal al mismo tiempo, emitiendo señales diferenciales de oscilación baja, como 200 mV; Amplitud relativamente grande, como 1,2 V.
                            

Resumen clave:

       

La señal tiene dos estados de trabajo, estado de modo de alta velocidad (HS) y estado de modo de baja velocidad (LP).
La capa física es para controlar la señal de hardware (sincronización), dos tipos de señal MIPI-DSI: carril de reloj, dos líneas, una Dp, Dn.
Lane de datos, dos lineas, una Dp, Dn; existen multiples lanes de datos segun requerimientos, al menos una lane (lane0), como maximo 4 lanes (lane0, lane1, lane2, lan3), de las cuales solo lane0 es bidireccional (low modo de velocidad bidireccional, el modo de alta velocidad solo puede ser unidireccional), otros solo pueden ser unidireccionales (modo de alta velocidad unidireccional), como mencionamos antes.

Los dos extremos de la línea de interconexión son la unidad de accionamiento y la unidad de recepción. La unidad de accionamiento tiene un módulo de transmisión diferencial (HS_TX) y un módulo de transmisión de un solo extremo de baja potencia (LP_TX), y la unidad receptora tiene un módulo de recepción diferencial (HS_RX) y un módulo de recepción de un solo extremo de baja potencia (LP_RX) .

Nivel de línea de datos:

Modo de baja velocidad LP: 0-1,2 V, nivel inactivo (LP11) Dp, Dn es 1,2 V.
Modo de alta velocidad HS: 100-300 mV (200 mV)
Diagrama de la tabla de estado del canal de datos:

         El canal de datos tiene 6 estados: HS-0, HS-1, LP00, LP01, LP10, LP11
Entre ellos, HS-0 indica que el Dp del carril de datos en modo de alta velocidad es bajo, y el bit Dn es alto, y LP01 indica que el Dp del carril de datos en modo de baja velocidad es bajo y Dn es alto. Después de encender el sistema, LP11 permanece durante aproximadamente 100 us (inicialización del hardware) y luego ingresa al estado de parada. La transición entre modos debe volver a este estado. El estado de control general también es el estado LP11. La conversión entre modos se describirá más adelante. Ahora que se mencionan estos 6 estados, se debe adjuntar una imagen. Los seis diagramas de transición de estado son los siguientes:

El módulo de transmisión diferencial (HS_TX) impulsa la línea de interconexión con una señal diferencial y hay dos estados en el canal de alta velocidad: diferencial-0 y diferencial-1. El módulo de transmisión de extremo único de baja potencia (LP_TX) controla dos líneas de interconexión de forma independiente y hay cuatro estados diferentes en el canal: LP00, LP01, LP10 y LP11. El protocolo define específicamente el nivel de línea y establece tres modos de trabajo: modo de alta velocidad, modo de control y modo ESCAPE. El canal pasa por defecto al modo de control y la línea está en estado de PARADA. Cuando el canal necesita ingresar al modo de alta velocidad o al modo ESCAPE, el módulo de envío debe controlar la línea LP01 o LP10 para enviar una solicitud al extremo receptor. Después de enviar la secuencia de solicitud, se llevará a cabo el modo de trabajo correspondiente y se enviará el LP11 para salir y volver al estado de control STOP. El extremo receptor debe realizar la recepción LP-RX en todo momento, detectar el nivel de línea y aclarar el modo de funcionamiento del canal.

El proceso de operación específico:

 • Tres modos de operación de Data Lane 

    • Modo de escape, modo de alta velocidad (ráfaga), modo de control

  • Los posibles eventos del estado de parada del modo de control son: 

    • Solicitud de modo de escape (LP-11→LP-10→LP-00→LP-01→LP-00)

    • Solicitud de modo de alta velocidad (LP-11→LP-01→LP-00)

    • Solicitud de respuesta (LP-11→LP-10→LP-00→LP-10→LP-00)

  •  El modo de escape es una operación especial de carril de datos en estado LP 

    • En este modo, se pueden ingresar algunas funciones adicionales: LPDT, ULPS, Trigger

    •Data Lane entra en modo Escape a través de LP-11→LP-10→LP-00→LP-01→LP-00

    • Una vez en modo Escape, el remitente debe enviar un comando de 8 bits para responder a la acción solicitada

    • Modo de escape Use la codificación Spaced-One-Hot

  • Estado de energía ultra baja (Ultra-Low Power State)
    • En este estado, las líneas están en un estado vacío (LP-00)
  • El estado de energía ultra baja del carril del reloj
    • El carril del reloj pasa por LP-11 →LP-10→LP- 00 para ingresar al estado ULPS
    • Salga de este estado a través de LP-10 → TWAKEUP → LP-11, el tiempo mínimo de TWAKEUP es 1ms

  • Transferencia de datos a alta velocidad
    • El acto de enviar datos en serie a alta velocidad se denomina transferencia de datos a alta velocidad o ráfaga (burst)

    • Todas las puertas de los carriles se inician sincrónicamente y pueden finalizar en diferentes momentos.
    • El reloj debe estar en modo de alta velocidad

  • Proceso de transmisión en cada modo de operación

    •El proceso de entrar en modo Escape: LP-11→LP-10→LP-00→LP-01→LP-00→Código de entrada → LPD (10MHz) •El proceso de salir del modo Escape: LP-10→LP-11
    •
    Entrar en el proceso del modo de alta velocidad: LP-11→LP-01→LP-00→SoT(00011101)→HSD (80Mbps ~ 1Gbps)
    Proceso de salida del modo de alta velocidad: EoT→LP-11
    Modo de control - Proceso de transmisión BTA ( el proceso Cuando el intercambio maestro-esclavo, como el parámetro de comando enviado por el maestro): LP-11→LP-10→LP-00→LP-10→LP-00 • Modo de control - Proceso de recepción BTA (ACK es la máquina
    esclava respuesta a los parámetros del comando maestro): LP-00→LP-10→LP-11

Nota: ¿Es un poco como el protocolo de enlace TCP de tres vías y el protocolo de enlace de cuatro vías que mencioné anteriormente?

¡Continúa abajo! ! ! ! ! ! ! ! !

La transmisión de datos entre el maestro y el esclavo es sincrónica, y está en modo DDR, es decir, activación de doble filo ; esto puede duplicar la velocidad de transmisión de datos sin cambiar la frecuencia del reloj y usar los recursos de ancho de banda de manera más efectiva. La capa física del host convierte en serie los datos distribuidos por la capa de gestión de canales en señales diferenciales y las envía a la línea de datos, y genera relojes diferenciales al mismo tiempo. Cada canal de datos se envía en paralelo, con un máximo de 4 canales. y un mínimo de 1 canal, dependiendo de los requisitos de ancho de banda. La capa física del esclavo se encarga de capturar 0 o 1 del flujo de bits serie diferencial, es decir, cuando Dp es mayor que Dn, es 1, y cuando Dn es mayor que Dp, es 0, y luego forma 8 -bit datos y los envía a la capa de gestión de canales. Al mismo tiempo, la señal de sincronización horizontal y la señal de sincronización vertical también pueden detectarse a partir del paquete de datos. El modo HS necesita depender de un reloj de alta velocidad, y el modo LP no necesita un reloj de alta velocidad, solo se requiere una línea de señal diferencial.El reloj en este momento se obtiene mediante el OR exclusivo de las líneas diferenciales Dp y Dn .

                                                             Modo HS (gráfico de temporización del modo de alta velocidad)

                                                             Modo LP (diagrama de temporización del modo de bajo consumo)        

Aquí debe analizar cuidadosamente el diagrama y luego hacer una comparación con el proceso que mencionamos anteriormente, ¡y lo encontrará de repente claro! ! , Buen chico, en realidad usé un modismo, ¡jajajaja! ! ! !

Siento que todavía hay mucho por saber, ¡así que lo actualizaré lentamente en el futuro! ! Sirva el plato principal primero. ! ! !

2. Depuración de MIPI

         El código del lado MIPI no requiere que toquemos su arquitectura, lo más importante es la configuración del archivo dts, no hay mucho que decir, ¡servimos! ! !

#include <dt-bindings/display/media-bus-format.h>


/*---------mipi-dsi------------------*/

&dsi0_in_vp0 {
	status = "disabled";
};

&dsi0_in_vp1 {
        status = "okay";
};

&mipi_dphy0 {
        status = "okay";
};

&mipi_dphy1 {
        status = "disabled";
};

&route_dsi0 {
        status = "okay";
	connect = <&vp1_out_dsi0>;
};

&dsi0 {
	//rockchip,lane-rate = <1000>;
        status = "okay";
	dsi0_panel: panel@0 {
		compatible = "simple-panel-dsi";
		reg = <0>;
		//power-supply = <&vcc3v3_lcd0_n>;
		//reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
		enable-gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
		pinctrl-0 = <&lcd_pwr_en_mipi &lcd_blk_en_mipi>;
		pinctrl-names = "default";
		backlight = <&backlight>;
		reset-delay-ms = <10>;
		enable-delay-ms = <10>;
		prepare-delay-ms = <5>;
		init-delay-ms = <20> ;
		unprepare-delay-ms = <10>;
		disable-delay-ms = <10>;
		dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
			MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
		dsi,format = <MIPI_DSI_FMT_RGB888>;
		dsi,lanes  = <4>;
		panel-init-sequence = [
					39 02 04 FF 98 81 03
					15 02 02 01 00
					15 02 02 02 00
					15 02 02 03 53    
					15 02 02 04 53    
					15 02 02 05 13
					15 02 02 06 04
					15 02 02 07 02
					15 02 02 08 02
					15 02 02 09 00
					15 02 02 0a 00
					15 02 02 0b 00
					15 02 02 0c 00
					15 02 02 0d 00
					15 02 02 0e 00
					15 02 02 0f 00
					15 02 02 10 00
					15 02 02 11 00
					15 02 02 12 00
					15 02 02 13 00
					15 02 02 14 00
					15 02 02 15 05  //gpm
					15 02 02 16 05  //gpm
					15 02 02 17 03  //gpm
					15 02 02 18 03  //gpm
					15 02 02 19 00
					15 02 02 1a 00
					15 02 02 1b 00
					15 02 02 1c 00
					15 02 02 1d 00
					15 02 02 1e c0
					15 02 02 1f 00
					15 02 02 20 02
					15 02 02 21 09
					15 02 02 22 00
					15 02 02 23 00
					15 02 02 24 00
					15 02 02 25 00
					15 02 02 26 00
					15 02 02 27 00
					15 02 02 28 55
					15 02 02 29 03
					15 02 02 2a 00
					15 02 02 2b 00
					15 02 02 2c 00
					15 02 02 2d 00
					15 02 02 2e 00
					15 02 02 2f 00
					15 02 02 30 00
					15 02 02 31 00
					15 02 02 32 00
					15 02 02 33 00
					15 02 02 34 00
					15 02 02 35 00
					15 02 02 36 00
					15 02 02 37 00
					15 02 02 38 3C
					15 02 02 39 00
					15 02 02 3a 00
					15 02 02 3b 00
					15 02 02 3c 00
					15 02 02 3d 00
					15 02 02 3e 00
					15 02 02 3f 00
					15 02 02 40 00
					15 02 02 41 00
					15 02 02 42 00
					15 02 02 43 00
					15 02 02 44 00
					15 02 02 50 01
					15 02 02 51 23
					15 02 02 52 45
					15 02 02 53 67
					15 02 02 54 89
					15 02 02 55 ab
					15 02 02 56 01
					15 02 02 57 23
					15 02 02 58 45
					15 02 02 59 67
					15 02 02 5a 89
					15 02 02 5b ab
					15 02 02 5c cd
					15 02 02 5d ef
					15 02 02 5e 01
					15 02 02 5f 0A     //FW_CGOUT_L[1] RESE_ODD
					15 02 02 60 02     //FW_CGOUT_L[2] VSSG_ODD
					15 02 02 61 02     //FW_CGOUT_L[3] VSSG_ODD
					15 02 02 62 08     //FW_CGOUT_L[4] STV2_ODD
					15 02 02 63 15     //FW_CGOUT_L[5] VDD2_ODD
					15 02 02 64 14     //FW_CGOUT_L[6] VDD1_ODD
					15 02 02 65 02     //FW_CGOUT_L[7]
					15 02 02 66 11     //FW_CGOUT_L[8] CK11
					15 02 02 67 10     //FW_CGOUT_L[9] CK9
					15 02 02 68 02     //FW_CGOUT_L[10]
					15 02 02 69 0F     //FW_CGOUT_L[11] CK7
					15 02 02 6a 0E     //FW_CGOUT_L[12] CK5
					15 02 02 6b 02     //FW_CGOUT_L[13]   
					15 02 02 6c 0D     //FW_CGOUT_L[14] CK3  
					15 02 02 6d 0C     //FW_CGOUT_L[15] CK1  
					15 02 02 6e 06     //FW_CGOUT_L[16] STV1_ODD  
					15 02 02 6f 02     //FW_CGOUT_L[17]   
					15 02 02 70 02     //FW_CGOUT_L[18]   
					15 02 02 71 02     //FW_CGOUT_L[19]   
					15 02 02 72 02     //FW_CGOUT_L[20]   
					15 02 02 73 02     //FW_CGOUT_L[21]   
					15 02 02 74 02     //FW_CGOUT_L[22]   
					15 02 02 75 0A     //BW_CGOUT_L[1]   RESE_ODD 
					15 02 02 76 02     //BW_CGOUT_L[2]   VSSG_ODD 
					15 02 02 77 02     //BW_CGOUT_L[3]   VSSG_ODD  
					15 02 02 78 06     //BW_CGOUT_L[4]   STV2_ODD 
					15 02 02 79 15     //BW_CGOUT_L[5]   VDD2_ODD 
					15 02 02 7a 14     //BW_CGOUT_L[6]   VDD1_ODD 
					15 02 02 7b 02     //BW_CGOUT_L[7]    
					15 02 02 7c 10     //BW_CGOUT_L[8]   CK11 
					15 02 02 7d 11     //BW_CGOUT_L[9]   CK9 
					15 02 02 7e 02     //BW_CGOUT_L[10]   
					15 02 02 7f 0C     //BW_CGOUT_L[11]  CK7
					15 02 02 80 0D     //BW_CGOUT_L[12]  CK5 
					15 02 02 81 02     //BW_CGOUT_L[13]   
					15 02 02 82 0E     //BW_CGOUT_L[14]  CK3 
					15 02 02 83 0F     //BW_CGOUT_L[15]  CK1 
					15 02 02 84 08     //BW_CGOUT_L[16]  STV1_ODD 
					15 02 02 85 02     //BW_CGOUT_L[17]   
					15 02 02 86 02     //BW_CGOUT_L[18]   
					15 02 02 87 02     //BW_CGOUT_L[19]   
					15 02 02 88 02     //BW_CGOUT_L[20]   
					15 02 02 89 02     //BW_CGOUT_L[21]   
					15 02 02 8A 02     //BW_CGOUT_L[22] 
					39 02 04 FF 98 81 04 	//self test  15 00 02 2F 01
					15 02 02 3B C0     // ILI4003D sel 
					15 02 02 6C 15
					15 02 02 6E 30     //VGH 16V   vgh Clamp level
					15 02 02 6F 33     //Pump ratio VGH=VSPX3 VGL=VSNX2
					15 02 02 8D 1F   // VGL clamp -12.03    LCD SPEC -12
					15 02 02 3A A4     //power saving
					15 02 02 35 17    // Source OP drive time
					15 02 02 87 BA
					15 02 02 26 76
					15 02 02 B2 D1
					15 02 02 B5 07
					15 02 02 88 0B
					15 02 02 21 30
					39 02 04 FF 98 81 01
					15 02 02 22 0A
					15 02 02 31 09   //zig-zag type1 09
					15 02 02 40 33   //for ext_cpck_sel
					15 02 02 42 44   //VGHL-CLK-SELA   VGHL-CLK-SELB
					15 02 02 53 2E  // FW VCOM
					15 02 02 55 88  // BW VCOM
					15 02 02 50 95    //Source 4.5, 95    AE 4.8
					15 02 02 51 95    //Source -4.5 95    AE -4.8
					15 02 02 60 30
					15 02 02 2E C8
					15 02 02 A0 0F        //VP255Gamma P
					15 02 02 A1 19               //VP251
					15 02 02 A2 28              //VP247
					15 02 02 A3 12              //VP243
					15 02 02 A4 14               //VP239
					15 02 02 A5 26               //VP231
					15 02 02 A6 1A               //VP219
					15 02 02 A7 1C               //VP203
					15 02 02 A8 7C               //VP175
					15 02 02 A9 1D               //VP144
					15 02 02 AA 2A               //VP111
					15 02 02 AB 6A               //VP80
					15 02 02 AC 18               //VP52
					15 02 02 AD 17               //VP36
					15 02 02 AE 4B               //VP24
					15 02 02 AF 21               //VP16
					15 02 02 B0 26               //VP12
					15 02 02 B1 4B               //VP8
					15 02 02 B2 6C               //VP4
					15 02 02 B3 3F               //VP0
					15 02 02 C0 01         //VN255 GAMMA N
					15 02 02 C1 18               //VN251
					15 02 02 C2 26               //VN247
					15 02 02 C3 0F              //VN243
					15 02 02 C4 12               //VN239
					15 02 02 C5 23               //VN231
					15 02 02 C6 18               //VN219
					15 02 02 C7 1C               //VN203
					15 02 02 C8 76               //VN175
					15 02 02 C9 1A               //VN144
					15 02 02 CA 26               //VN111
					15 02 02 CB 63               //VN80
					15 02 02 CC 1B              //VN52
					15 02 02 CD 1A               //VN36
					15 02 02 CE 4E               //VN24
					15 02 02 CF 21              //VN16
					15 02 02 D0 29               //VN12
					15 02 02 D1 47               //VN8
					15 02 02 D2 6A               //VN4
					15 02 02 D3 3F               //VN0
					39 02 04 FF 98 81 00
					05 02 01 35               //TE OUT
					05 78 01 11        //sleep out
					05 05 01 29        //display on
				];

		panel-exit-sequence = [
					05 16 01 28
					05 78 01 10
				];



               disp_timings0: display-timings {
                        native-mode = <&dsi0_timing0>;
                        dsi0_timing0: timing0 {
						clock-frequency = <145000000>;//mipi时钟的算法,根据如下的配置算出来的,如果不准确,或者时钟太低会导致屏闪的问题出现。
dsi clock = H-total * V-total * fps*位深 / lane numberl / 2  
          =(HSYNC+HBP+HACTIVE+HFP)*(VSYNC+VBP+VACTIVE+VFP) * 60 * 24 / 4 / 2 
						hactive = <1920>;//行有效像素
						vactive = <1200>;//场有效像素
						hback-porch = <12>;//行后肩
						hfront-porch = <128>;//行前肩
						hsync-len = <20>;//行同步
						vback-porch = <20>;//场后肩
						vfront-porch = <19>;//场前肩
						vsync-len = <4>;//场同步
						hsync-active = <0>;
						vsync-active = <0>;
						de-active = <0>;
						pixelclk-active = <0>;
						swap-rb = <0>;
						swap-rg = <0>;
						swap-gb = <0>;
                    };
                };

		ports {
			#address-cells = <1>;
			#size-cells = <0>;

			port@0 {
				reg = <0>;
				panel_in_dsi: endpoint {
					remote-endpoint = <&dsi_out_panel>;
				};
			};
		};
	};

	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@1 {
			reg = <1>;
			dsi_out_panel: endpoint {
				remote-endpoint = <&panel_in_dsi>;
			};
		};
	};
};
&pinctrl {
	mipi_gpio {
		lcd_pwr_en_mipi:lcd_pwr_en_mipi {
			rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_output_high>;
		};
		lcd_blk_en_mipi:lcd_blk_en_mipi {
			rockchip,pins = <3 RK_PA1 RK_FUNC_GPIO &pcfg_output_high>;
		};
	};

};






&i2c1 { //这是I2C的dts配置,我GM8775C是挂载到I2C1上的。
	status = "okay";
	
       gm8775c@2c {
               compatible = "gm8775c,mipi_to_lvds";
               reg = <0x2c>;
               status = "okay";
       };
}

3. Introducción a GM8775C y escritura de archivos de controlador

       

        GM8775C tendrá un GM8775C_A1.1__IIC20190819.exe, que se usa para generar archivos de configuración, registros y los valores correspondientes en los registros. Al principio, escribí el archivo de configuración a través de la dirección del i2c a través del script de shell, pero una vez la energía está apagada, el valor en el registro se restaura al valor predeterminado (pero cuando depuramos, necesitamos usar el método de script de shell, que es más conveniente. Hay artículos relacionados con el script de shell y cómo usarlo en mi blog), lo que conducirá a La pantalla LVDS externa no es brillante, por lo que debemos cargar el archivo generado por GM8775C_A1.1__IIC20190819 en el controlador y escribir un controlador I2C por nosotros mismos, lo cual es relativamente simple.

         La configuración anterior se configura de acuerdo con los parámetros de su propia pantalla LVDS. Y mi pantalla tiene algunos parámetros de configuración en la imagen de arriba.

El siguiente es el archivo del controlador de GM8775C.

#include <linux/clk.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/of_gpio.h>
#include <linux/proc_fs.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/regmap.h>

#define REGISTER_NUM 34

struct gm8775c_priv {
	struct regmap *regmap;
	struct i2c_client *client;
	
};

//Modify screen parameters and modify default values
static const struct reg_default gm8775c_reg_defaults[] = {   
		{0x00,0xAA},
		{0x48,0x02},
		{0xB6,0x20},
		{0x01,0x80},
		{0x02,0xB0},
		{0x03,0x47},
		{0x04,0x80},
		{0x05,0x14},
		{0x06,0x0C},
		{0x07,0x00},
	    {0x08,0x13},
		{0x09,0x04},
		{0x0A,0x14},
		{0x0B,0x82},
		{0x0C,0x14},
		{0x0D,0x01},
		{0x0E,0x80},
		{0x0F,0x20},
		{0x10,0x20},
		{0x11,0x03},
		{0x12,0x1B},
		{0x13,0x63},
		{0x14,0x32},
		{0x15,0x10},
		{0x16,0x40},
		{0x17,0x00},
		{0x18,0x32},
		{0x19,0x10},
     	{0x1A,0x40},
		{0x1B,0x00},
		{0x1E,0x46},
		{0x51,0x30},
		{0x1F,0x10},
		{0x2A,0x01},
};

static int gm8775c_read(u8 reg, u8 * rt_value, struct i2c_client *client)
{
	int ret;
	u8 read_cmd[3] = { 0 };
	u8 cmd_len = 0;

	read_cmd[0] = reg;
	cmd_len = 1;

	if (client->adapter == NULL)
		printk("gm8775c_read client->adapter==NULL\n");

	ret = i2c_master_send(client, read_cmd, cmd_len);
	if (ret != cmd_len) {
		printk("gm8775c_read error1\n");
		return -1;
	}

	ret = i2c_master_recv(client, rt_value, 1);
	if (ret != 1) {
		printk("gm8775c_read error2, ret = %d.\n", ret);
		return -1;
	}

	return 0;
}

static int gm8775c_write(u8 reg, unsigned char value, struct i2c_client *client)
{
	int ret = 0;
	u8 write_cmd[2] = { 0 };

	write_cmd[0] = reg;
	write_cmd[1] = value;

	ret = i2c_master_send(client, write_cmd, 2);
	if (ret != 2) {
		printk("gm8775c_write error->[REG-0x%02x,val-0x%02x]\n",
		       reg, value);
		return -1;
	}

	return 0;
}

static const struct of_device_id gm8775_of_match[] = { 
	{
		.compatible = "gm8775c,mipi_to_lvds",
	}, 
	{ }
};
MODULE_DEVICE_TABLE(of, gm8775_of_match);

static const struct i2c_device_id gm8775_i2c_id[] = {
	{"GM8775C_MTL", 0},
	{}
};

static ssize_t gm8775c_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	int val=0, flag=0;
	u8 i=0, reg, num, value_w, value_r;

	
	struct gm8775c_priv *gm8775c = dev_get_drvdata(dev);
	
	val = simple_strtol(buf, NULL, 16);
	flag = (val >> 16) & 0xFF;
	
	if (flag) {
		reg = (val >> 8) & 0xFF;
		value_w = val & 0xFF;
		printk("\nWrite: start REG:0x%02x,val:0x%02x,count:0x%02x\n", reg, value_w, flag);
		while(flag--) {
			gm8775c_write(reg, value_w,  gm8775c->client);
			printk("Write 0x%02x to REG:0x%02x\n", value_w, reg);
			reg++;
		}
	} else {
		reg = (val >> 8) & 0xFF;
		num = val & 0xff;
		printk("\nRead: start REG:0x%02x,count:0x%02x\n", reg, num);
		do {
			value_r = 0;
			gm8775c_read(reg, &value_r, gm8775c->client);
			printk("REG[0x%02x]: 0x%02x;  ", reg, value_r);
			reg++;
			i++;
			if ((i==num) || (i%4==0))	printk("\n");
		} while (i<num);
	}
	
	return count;
}

static ssize_t gm8775c_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	printk("echo flag|reg|val > gm8775c\n");
	printk("eg read star addres=0x06,count 0x10:echo 0610 >gm8775c\n");
	printk("eg write star addres=0x90,value=0x3c,count=4:echo 4903c >gm8775c\n");
	return 0;
}

static DEVICE_ATTR(gm8775c, 0644, gm8775c_show, gm8775c_store);

static struct attribute *egm8775c_debug_attrs[] = {
	&dev_attr_gm8775c.attr,
	NULL,
};

static struct attribute_group gm8775c_debug_attr_group = {
	.name   = "gm8775c_debug",
	.attrs  = egm8775c_debug_attrs,
};

/*
 *****************************************************************************
 *
 *	Driver Interface
 *
 *****************************************************************************
 */

static int gm8775c_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct gm8775c_priv *gm8775c;
	int i;	
	int ret;
	
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
						 I2C_FUNC_SMBUS_BYTE_DATA)) {
			dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n");
			return -ENODEV;
		}
	
	gm8775c = devm_kzalloc(&client->dev, sizeof(*gm8775c), GFP_KERNEL);
	if (!gm8775c)
		return -ENOMEM;
	
  	gm8775c->client = client;
	i2c_set_clientdata(client, gm8775c);
	for(i = 0;i < REGISTER_NUM; i++)
			gm8775c_write(gm8775c_reg_defaults[i].reg, gm8775c_reg_defaults[i].def, gm8775c->client);	

	ret = sysfs_create_group(&client->dev.kobj, &gm8775c_debug_attr_group);
	if (ret) {
		pr_err("failed to create attr group\n");
	}
	
	return ret;
}

static int gm8775c_remove(struct i2c_client *client)
{ 
	return 0;
}

static struct i2c_driver gm8775c_driver = {
	.driver = {
		.name = "gm8775c-mipi-to-lvds",
		.of_match_table = of_match_ptr(gm8775_of_match),
	},
	.probe = gm8775c_probe,
	.remove = gm8775c_remove,
	.id_table = gm8775_i2c_id,
};

static int __init gm8775c_modinit(void)
{
	int ret;
	ret = i2c_add_driver(&gm8775c_driver);
	if (ret != 0)
		printk("Failed to register gm8775c i2c driver : %d \n", ret);
	return ret;
}
late_initcall(gm8775c_modinit);

static void __exit gm8775c_exit(void)
{
	i2c_del_driver(&gm8775c_driver);
}

module_exit(gm8775c_exit);


//module_i2c_driver(gm8775c_driver);

MODULE_AUTHOR("Alexander Bigga <[email protected]>");
MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
MODULE_LICENSE("GPL");

Resumir

        La conexión de hardware GM8775C debe conectarse a él en la medida de lo posible sin apagar el sistema, de modo que no se pueda apagar, de lo contrario, después de apagar la pantalla, todavía tenemos que tratar con él para inicializarlo.

        El archivo. el lado 8775C es correcto.

        Nota: Primero, asegúrese de que la salida de señal del terminal mipi pueda iluminar la pantalla mipi y luego considere el problema en el terminal GM8775C.

Supongo que te gusta

Origin blog.csdn.net/qq_48709036/article/details/124296103
Recomendado
Clasificación