1 /*
2  * Copyright (c) 2022 ITE.
3  * Copyright 2022 NXP
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_it6161.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 /*******************************************************************************
15  * Variables
16  ******************************************************************************/
17 it6161_cfg_t it6161                   = {0};
18 const display_operations_t it6161_ops = {
19     .init   = IT6161_Init,
20     .deinit = IT6161_Deinit,
21     .start  = IT6161_Start,
22     .stop   = IT6161_Stop,
23 };
24 
25 /*******************************************************************************
26  * Code
27  ******************************************************************************/
28 
IT6161_Identify(display_handle_t * handle)29 static status_t IT6161_Identify(display_handle_t *handle)
30 {
31     status_t status;
32     uint8_t reg[2]  = {0U};
33     uint8_t i2cAddr = (((const it6161_resource_t *)(handle->resource))->i2cAddr);
34 
35     status = IT6161_I2C_ReadRegs(handle, i2cAddr, IT6161_VENDER_ID_REG, &reg, sizeof(reg));
36     if ((kStatus_Success != status) || (IT6161_VENDER_ID_VALUE_L != reg[0]) || (IT6161_VENDER_ID_VALUE_H != reg[1]))
37     {
38         return status;
39     }
40 
41     status = IT6161_I2C_ReadRegs(handle, i2cAddr, IT6161_DEVICE_ID_REG, &reg, sizeof(reg));
42     if ((kStatus_Success != status) || (IT6161_DEVICE_ID_VALUE_L != reg[0]) || (IT6161_DEVICE_ID_VALUE_H != reg[1]))
43     {
44         return status;
45     }
46 
47     return status;
48 }
49 
it6161_MIPIRX_LogicReset(display_handle_t * handle)50 static void it6161_MIPIRX_LogicReset(display_handle_t *handle)
51 {
52     /* software REFCLK clock domain reset */
53     MIPIRX_SetI2C_Byte(handle, MIPI_RX_SOFT_RESET_REG05, MIPI_RX_SOFT_RESET_REG05_RefSoftREFRst_MASK,
54                        MIPI_RX_SOFT_RESET_REG05_RefSoftREFRst(0x01U));
55 }
56 
it6161_MIPIRX_LogicResetRelease(display_handle_t * handle)57 static void it6161_MIPIRX_LogicResetRelease(display_handle_t *handle)
58 {
59     /* software REFCLK clock domain reset */
60     MIPIRX_SetI2C_Byte(handle, MIPI_RX_SOFT_RESET_REG05, MIPI_RX_SOFT_RESET_REG05_RefSoftREFRst_MASK,
61                        MIPI_RX_SOFT_RESET_REG05_RefSoftREFRst(0x00U));
62 }
63 
it6161_MIPIRX_IntMaskDisable(display_handle_t * handle)64 static void it6161_MIPIRX_IntMaskDisable(display_handle_t *handle)
65 {
66     MIPIRX_SetI2C_Byte(handle, MIPI_RX_SYS_STATUS_REG0F, 0x03U,
67                        0x00U); /* Don't know what's meaning about this from it6161 programming guide */
68 
69     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_INT_MASK_REG09, 0x00U);
70     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_INT_MASK_REG0A, 0x00U);
71 
72     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_INT_MASK_REG0B, 0x00U);
73 }
74 
it6161_MIPIRX_CONF(display_handle_t * handle)75 static void it6161_MIPIRX_CONF(display_handle_t *handle)
76 {
77     /* power down OCLK, MCLK, PCLK, RCLK */
78     MIPIRX_SetI2C_Byte(handle, MIPI_RX_CLKBUF_CTRL_REG10,
79                        MIPI_RX_CLKBUF_CTRL_REG10_RegGateOCLK_MASK | MIPI_RX_CLKBUF_CTRL_REG10_RegGateMCLK_MASK |
80                            MIPI_RX_CLKBUF_CTRL_REG10_RegGatePCLK_MASK | MIPI_RX_CLKBUF_CTRL_REG10_RegGateRCLK_MASK,
81                        MIPI_RX_CLKBUF_CTRL_REG10_RegGateOCLK(0x00U) | MIPI_RX_CLKBUF_CTRL_REG10_RegGateMCLK(0x00U) |
82                            MIPI_RX_CLKBUF_CTRL_REG10_RegGatePCLK(0x00U) | MIPI_RX_CLKBUF_CTRL_REG10_RegGateRCLK(0x00U));
83 
84     it6161_MIPIRX_LogicReset(handle);
85     it6161_MIPIRX_LogicResetRelease(handle);
86 
87     it6161_MIPIRX_IntMaskDisable(handle);
88     /* Setup INT pin: active low */
89     MIPIRX_SetI2C_Byte(handle, MIPI_RX_SYS_CONF_REG0D, MIPI_RX_SYS_CONF_REG0D_REGINTPOL_MASK,
90                        MIPI_RX_SYS_CONF_REG0D_REGINTPOL(0x00U));
91     /* Setup swap(dp/dn, lane), lane numbers */
92     MIPIRX_SetI2C_Byte(handle, MIPI_RX_SYS_CONF_REG0C,
93                        MIPI_RX_SYS_CONF_REG0C_RegLaneNum_MASK | MIPI_RX_SYS_CONF_REG0C_RegEnPNSwap_MASK |
94                            MIPI_RX_SYS_CONF_REG0C_RegEnLaneSwap_MASK,
95                        MIPI_RX_SYS_CONF_REG0C_RegEnLaneSwap((uint32_t)it6161.mipi_rx.mipirx_lane_swap) |
96                            MIPI_RX_SYS_CONF_REG0C_RegEnPNSwap((uint32_t)it6161.mipi_rx.mipirx_dpdn_swap) |
97                            MIPI_RX_SYS_CONF_REG0C_RegLaneNum((uint32_t)it6161.mipi_rx.lanes));
98     /* Setup mclk, pclk, standby mode, standby to reset, iddq mode */
99     MIPIRX_SetI2C_Byte(handle, MIPI_RX_CLKBUF_CTRL_REG11,
100                        MIPI_RX_CLKBUF_CTRL_REG11_RegInvMCLK_MASK | MIPI_RX_CLKBUF_CTRL_REG11_RegInvPCLK_MASK |
101                            MIPI_RX_CLKBUF_CTRL_REG11_RegEnStandby_MASK | MIPI_RX_CLKBUF_CTRL_REG11_RegEnStb2Rst_MASK |
102                            MIPI_RX_CLKBUF_CTRL_REG11_RegEnIDDQ_MASK,
103                        MIPI_RX_CLKBUF_CTRL_REG11_RegInvMCLK((uint32_t)it6161.mipi_rx.inverse_mclk) |
104                            MIPI_RX_CLKBUF_CTRL_REG11_RegInvPCLK((uint32_t)it6161.mipi_rx.inverse_pclk) |
105                            MIPI_RX_CLKBUF_CTRL_REG11_RegEnStandby((uint32_t)it6161.mipi_rx.enable_standby_mode) |
106                            MIPI_RX_CLKBUF_CTRL_REG11_RegEnStb2Rst((uint32_t)it6161.mipi_rx.enable_standby_to_reset) |
107                            MIPI_RX_CLKBUF_CTRL_REG11_RegEnIDDQ((uint32_t)it6161.mipi_rx.enable_iddq_mode));
108     /* Setup reference clock */
109     MIPIRX_SetI2C_Byte(handle, MIPI_RX_CLKBUF_CTRL_REG12,
110                        MIPI_RX_CLKBUF_CTRL_REG12_RegPDREFCLK_MASK | MIPI_RX_CLKBUF_CTRL_REG12_RegPDREFCNT_MASK,
111                        MIPI_RX_CLKBUF_CTRL_REG12_RegPDREFCLK((uint32_t)it6161.mipi_rx.pd_ref_clk) |
112                            MIPI_RX_CLKBUF_CTRL_REG12_RegPDREFCNT((uint32_t)it6161.mipi_rx.pd_ref_cnt));
113     /* Setup PHY-Protocol Interface(hs settle numbers, hs trailing skip stage, enable sync bit error tolerance) */
114     MIPIRX_SetI2C_Byte(
115         handle, MIPI_RX_PPI_REG18,
116         MIPI_RX_PPI_REG18_RegHSSetNum_MASK | MIPI_RX_PPI_REG18_RegSkipStg_MASK | MIPI_RX_PPI_REG18_RegEnSyncErr_MASK,
117         MIPI_RX_PPI_REG18_RegHSSetNum((uint32_t)it6161.mipi_rx.hs_settle_num) |
118             MIPI_RX_PPI_REG18_RegSkipStg((uint32_t)it6161.mipi_rx.hs_trailing_skip_stage) |
119             MIPI_RX_PPI_REG18_RegEnSyncErr((uint32_t)it6161.mipi_rx.enable_sync_bit_error_tolerance));
120     /* Setup PHY-Protocol Interface(enable multi lane deskew, force continuous clock mode, ppi debug selection)*/
121     MIPIRX_SetI2C_Byte(
122         handle, MIPI_RX_PPI_REG19,
123         MIPI_RX_PPI_REG19_RegEnDeSkew_MASK | MIPI_RX_PPI_REG19_RegEnContCK_MASK | MIPI_RX_PPI_REG19_RegPPIDbgSel_MASK,
124         MIPI_RX_PPI_REG19_RegEnDeSkew((uint32_t)it6161.mipi_rx.enable_multi_lane_deskew) |
125             MIPI_RX_PPI_REG19_RegEnContCK((uint32_t)it6161.mipi_rx.force_continuous_clock_mode) |
126             MIPI_RX_PPI_REG19_RegPPIDbgSel((uint32_t)it6161.mipi_rx.ppi_debug_selection));
127     /* Setup lane merge & packet decoder (ignore null packet, ignore blank packet, dummy ecc error, recognize EOTP) */
128     MIPIRX_SetI2C_Byte(
129         handle, MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20,
130         MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20_RegIgnrNull_MASK |
131             MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20_RegIgnrBlk_MASK |
132             MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20_RegEnDummyECC_MASK |
133             MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20_RegSelEOTP_MASK,
134         MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20_RegIgnrNull((uint32_t)it6161.mipi_rx.ignore_null_packet) |
135             MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20_RegIgnrBlk((uint32_t)it6161.mipi_rx.ignore_blank_packet) |
136             MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20_RegEnDummyECC((uint32_t)it6161.mipi_rx.enable_dummy_ecc_error) |
137             MIPI_RX_LANE_MERGE_PACKET_DECODER_REG20_RegSelEOTP((uint32_t)it6161.mipi_rx.sel_eotp));
138     MIPIRX_SetI2C_Byte(
139         handle, MIPI_RX_LANE_MERGE_PACKET_DECODER_REG21, MIPI_RX_LANE_MERGE_PACKET_DECODER_REG21_RegSelLMDbg_MASK,
140         MIPI_RX_LANE_MERGE_PACKET_DECODER_REG21_RegSelLMDbg((uint32_t)it6161.mipi_rx.lm_debug_selection));
141     /* Setup packed pixel stream, timing generator and pattern generation(auto sync falling, interlaced mode, user
142      * define timming register, prec and mrec update) */
143     MIPIRX_SetI2C_Byte(
144         handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44,
145         MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegAutoSyncF_MASK |
146             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegMipi_Interlaced_MASK |
147             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegSEModeUdef_MASK |
148             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegPRec_UPdate_MASK |
149             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegMRec_UPdate_MASK,
150         MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegAutoSyncF(
151             (uint32_t)it6161.mipi_rx.auto_sync_falling) |
152             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegMipi_Interlaced(
153                 (uint32_t)it6161.mipi_rx.interlaced_mode) |
154             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegSEModeUdef(
155                 (uint32_t)it6161.mipi_rx.user_define_timming) |
156             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegPRec_UPdate(
157                 (uint32_t)it6161.mipi_rx.prec_update) |
158             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG44_RegMRec_UPdate(
159                 (uint32_t)it6161.mipi_rx.mrec_update));
160     MIPIRX_SetI2C_Byte(handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4B,
161                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4B_RegVREnhSel_MASK |
162                            MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4B_RegVREnh_MASK |
163                            MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4B_RegFReSyncEn_MASK,
164                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4B_RegVREnhSel(
165                            (uint32_t)it6161.mipi_rx.v_timing_resync_selction) |
166                            MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4B_RegVREnh(
167                                (uint32_t)it6161.mipi_rx.enable_v_timing_resync_enhance_mode) |
168                            MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4B_RegFReSyncEn(
169                                (uint32_t)it6161.mipi_rx.enable_frame_resync));
170     MIPIRX_SetI2C_Byte(handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4C,
171                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4C_RegFFRdStg_MASK,
172                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4C_RegFFRdStg(
173                            (uint32_t)it6161.mipi_rx.pps_fifo_read_start_point & 0xFFU));
174     MIPIRX_SetI2C_Byte(handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4E,
175                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4E_RegHReSyncEn_MASK |
176                            MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4E_RegVReSyncEn_MASK,
177                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4E_RegHReSyncEn(
178                            (uint32_t)it6161.mipi_rx.enable_h_timing_resync) |
179                            MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4E_RegVReSyncEn(
180                                (uint32_t)it6161.mipi_rx.enable_v_timing_resync));
181     MIPIRX_SetI2C_Byte(
182         handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4F,
183         MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4F_RegPPSFFAutoRst_MASK |
184             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4F_RegEnPPSFFOv2Rst_MASK,
185         MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4F_RegPPSFFAutoRst(
186             (uint32_t)it6161.mipi_rx.enable_fifo_auto_reset) |
187             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG4F_RegEnPPSFFOv2Rst(
188                 (uint32_t)it6161.mipi_rx.enable_overflow_auto_reset));
189     MIPIRX_SetI2C_Byte(handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG70,
190                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG70_RegEnMAvg_MASK,
191                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG70_RegEnMAvg(
192                            (uint32_t)it6161.mipi_rx.enable_mclk_horizontal_average));
193     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG72,
194                          MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG72_RegMShift(
195                              (uint32_t)it6161.mipi_rx.allowable_mclk_horizontal_shift_value));
196     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG73,
197                          MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG73_RegPShift(
198                              (uint32_t)it6161.mipi_rx.allowable_pclk_horizontal_shift_value));
199     MIPIRX_SetI2C_Byte(handle, MIPI_RX_AFE_REG80, MIPI_RX_AFE_REG80_RegEnExtPCLK_MASK,
200                        MIPI_RX_AFE_REG80_RegEnExtPCLK((uint32_t)it6161.mipi_rx.enable_external_pclk));
201     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_LANE_MERGE_PACKET_DECODER_REG21, 0x00U);
202     /* Select termination value of all of the channels: 116 ohm */
203     MIPIRX_SetI2C_Byte(handle, MIPI_RX_AFE_REG84, MIPI_RX_AFE_REG84_REGRTERM_MASK, MIPI_RX_AFE_REG84_REGRTERM(0x00U));
204     MIPIRX_SetI2C_Byte(handle, MIPI_RX_TX_PATTERN_CONTENT_REGA0, MIPI_RX_TX_PATTERN_CONTENT_REGA0_RegMBPM_MASK,
205                        MIPI_RX_TX_PATTERN_CONTENT_REGA0_RegMBPM((uint32_t)it6161.mipi_rx.bypass_through_mode));
206     /* Enable auto detect format */
207     MIPIRX_SetI2C_Byte(handle, MIPI_RX_LANE_MERGE_PACKET_DECODER_REG21, 0x08U, 0x08U);
208 
209     MIPIRX_SetI2C_Byte(handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG70,
210                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG70_RegEnMAvg_MASK,
211                        MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG70_RegEnMAvg(
212                            (uint32_t)it6161.mipi_rx.enable_mclk_horizontal_average));
213 
214     /* Video Clock Domain Reset */
215     MIPIRX_SetI2C_Byte(handle, MIPI_RX_SOFT_RESET_REG05, MIPI_RX_SOFT_RESET_REG05_RegSoftMRst_MASK,
216                        MIPI_RX_SOFT_RESET_REG05_RegSoftMRst(0x01U));
217     if (it6161.mipi_rx.bypass_through_mode != 0x0U)
218     {
219         /* Setup BYPASS MODE HFP OFFSET */
220         MIPIRX_WriteI2C_Byte(handle, MIPI_RX_TX_PATTERN_CONTENT_REGA1, 0x00U);
221 
222         /* Setup BYPASS MODE VFP OFFSET */
223         MIPIRX_WriteI2C_Byte(handle, MIPI_RX_TX_PATTERN_CONTENT_REGA2, 0x00U);
224 
225         /* Setup BYPASS MODE HSW */
226         MIPIRX_WriteI2C_Byte(handle, MIPI_RX_TX_PATTERN_CONTENT_REGA3, 0x08U);
227         /* Setup BYPASS MODE VSW */
228         MIPIRX_WriteI2C_Byte(handle, MIPI_RX_TX_PATTERN_CONTENT_REGA5, 0x04U);
229     }
230 
231     if (it6161.mipi_rx.user_define_timming == 0x0U)
232     {
233         MIPIRX_SetI2C_Byte(
234             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG31,
235             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG31_RegEnUsrHFP_MASK,
236             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG31_RegEnUsrHFP(0x00U));
237         MIPIRX_SetI2C_Byte(
238             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG33,
239             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG33_RegEnUsrHSW_MASK,
240             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG33_RegEnUsrHSW(0x00U));
241         MIPIRX_SetI2C_Byte(
242             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG35,
243             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG35_RegEnUsrHBP_MASK,
244             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG35_RegEnUsrHBP(0x00U));
245         MIPIRX_SetI2C_Byte(
246             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG37,
247             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG37_RegEnUsrHDEW_MASK,
248             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG37_RegEnUsrHDEW(0x00U));
249         MIPIRX_SetI2C_Byte(
250             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG39,
251             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG39_RegEnUsrHVR2nd_MASK,
252             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG39_RegEnUsrHVR2nd(0x00U));
253         MIPIRX_SetI2C_Byte(
254             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG3A, 0x80U,
255             0x00U); /* Does it means to disable User defined Mipi_VFP of REG3B? if yes, need change 3A to 3B */
256         MIPIRX_SetI2C_Byte(
257             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG3C, 0x80U,
258             0x00U); /* Does it means to disable User defined Mipi_VSW of REG3D? if yes, need change 3C to 3D */
259         MIPIRX_SetI2C_Byte(
260             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG3E, 0x80U,
261             0x00U); /* Does it means to disable User defined Mipi_VBP of REG3F? if yes, need change 3E to 3F */
262         MIPIRX_SetI2C_Byte(
263             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG41,
264             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG41_RegEnUsrVDEW_MASK,
265             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG41_RegEnUsrVDEW(0x00U));
266         MIPIRX_SetI2C_Byte(
267             handle, MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG43,
268             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG43_RegEnUsrVFP2nd_MASK,
269             MIPI_RX_PACKED_PIXEL_STREAM_TIMING_GENERATOR_AND_PATTERN_GENERATION_REG43_RegEnUsrVFP2nd(0x00U));
270     }
271 }
272 
273 static RegSetTable_t HDMITX_Init_Table[] = {
274 
275     {0x0F, 0x40, 0x00},
276 
277     /* PLL Reset */
278     {0x62, 0x08, 0x00}, /* XP_RESETB */
279     {0x64, 0x04, 0x00}, /* IP_RESETB */
280 
281     {0x0F, 0x01, 0x00}, // bank 0;
282 
283     {0x8D, 0xFF, HDMI_TX_CEC_I2C_SLAVE_ADDR},
284     {HDMI_TX_PATTERN_GENERATOR_REGA9, HDMI_TX_PATTERN_GENERATOR_REGA9_RegHBPM_SHIFT,
285      HDMI_TX_PATTERN_GENERATOR_REGA9_RegHBPM(EN_HDMITX_BYPASS_MODE)},
286     {HDMI_TX_PATTERN_GENERATOR_REGBF, 0x80, NRTXRCLK << 7}, /* Cannot find it from it6161 programming guide */
287 
288     {0xF8, 0xFF, 0xC3},
289     {0xF8, 0xFF, 0xA5},
290     {0xF4, 0x0C, 0x00},
291     {0xF3, 0x02, 0x00},
292     {0xF8, 0xFF, 0xFF},
293 
294     {0x5A, 0x0C, 0x0C},
295     {HDMI_TX_HDMI_CONTROL_REGD1, HDMI_TX_HDMI_CONTROL_REGD1_RegStableDbgMd_MASK,
296      (FORCE_TXCLK_STABLE << 3) | (STABLE_LINEPIEXELCNT_SENSITIVITY << 1)},
297     {HDMI_TX_CLOCK_CONTROL_REG5D, 0x04, (RCLK_FREQ_SEL << 2)}, /* Cannot find it from it6161 programming guide */
298     {0x65, 0x03, 0x00},
299     {0x71, 0xF9,
300      0x18}, /* XP_Lock stable time: 00: 75us; check XP_lock for TX fifo reset: 0: disable; reset TX fifo when PLL
301                unlock: 0: disable; TX fifo auto reset enable: 1: enable; TX fifo manual reset: 0: disable */
302     {0xCF, 0xFF, 0x00}, /* packet blan guard band option: 00: +4; packet limit guard band option: 00: +32; packet keep
303                            out guard band option: 00: +8; guard band for packet transmission in blank period: 0:
304                            disable; guard band for packet transmission in limit period: 0: disable */
305     {0xD1, 0x02, 0x00}, /* stable linepixelcnt sensitivity: 0: low sensitivity */
306 
307     {0x59, 0xD0, 0x40}, /* VCLK frequncy depends on REGManualPLLPR when REGDisLockPR=1: 01: 2x; 0: internal pixel clock
308                            frequency depends on pixel repetition factor in AVI infoframe */
309     {0xE1, 0x20, 0x00}, /* 0: use rising edge to sample WS and I2S */
310     {0xF5, 0x40, 0x00}, /* cannot find the field from it6161 programming guide */
311     {0x05, 0xC0, 0x40}, /* 0: INT active low; 1: Open-Drain mode */
312     {0x0C, 0xFF, 0xFF}, /* Clear the interrupt */
313     {0x0D, 0xFF, 0x00}, /* Don't know what's meaning? */
314     {0x0E, 0x02, 0x00}, /* Clear AduCTS interrupt? unsure */
315 
316     {0x0C, 0xFF, 0x00},
317     {0x0D, 0xFF, 0x00},
318     {0x0E, 0x02, 0x00},
319     {0x20, 0x01, 0x00},
320 };
321 
322 static RegSetTable_t HDMITX_PwrOn_Table[] = {
323     /* PwrOn RCLK , IACLK ,TXCLK */
324     {0x0F, 0x70, 0x00},
325     /* PLL PwrOn */
326     /* PwrOn DRV */
327     {0x61, 0x20, 0x00},
328     /* PwrOn XPLL */
329     {0x62, 0x44, 0x00},
330     /* PwrOn IPLL */
331     {0x64, 0x40, 0x00},
332     /* PLL Reset OFF */
333     /* DRV_RST */
334     {0x61, 0x10, 0x00},
335     /* XP_RESETB */
336     {0x62, 0x08, 0x08},
337     /* IP_RESETB */
338     {0x64, 0x04, 0x04},
339 };
340 
it6161_HDMITX_Init(display_handle_t * handle)341 void it6161_HDMITX_Init(display_handle_t *handle)
342 {
343     HDMITX_LoadRegSetting(handle, HDMITX_Init_Table, sizeof(HDMITX_Init_Table));
344     HDMITX_LoadRegSetting(handle, HDMITX_PwrOn_Table, sizeof(HDMITX_PwrOn_Table));
345 }
346 
it6161_MIPIRX_Init(display_handle_t * handle)347 static void it6161_MIPIRX_Init(display_handle_t *handle)
348 {
349     it6161_MIPIRX_CONF(handle);
350     /* Enable MIPI RX clock domain */
351     MIPIRX_SetI2C_Byte(handle, MIPI_RX_SOFT_RESET_REG05,
352                        MIPI_RX_SOFT_RESET_REG05_RegSoftORst_MASK | MIPI_RX_SOFT_RESET_REG05_RegSoftMRst_MASK, 0x00U);
353 }
354 
it6161_SetIntActiveLevel(display_handle_t * handle,enum it6161_active_level level)355 void it6161_SetIntActiveLevel(display_handle_t *handle, enum it6161_active_level level)
356 {
357     MIPIRX_SetI2C_Byte(
358         handle, MIPI_RX_SYS_CONF_REG0D, MIPI_RX_SYS_CONF_REG0D_REGINTPOL_MASK,
359         ((level == HIGH_LVL) ? (MIPI_RX_SYS_CONF_REG0D_REGINTPOL(0x01U)) : (MIPI_RX_SYS_CONF_REG0D_REGINTPOL(0x00U))));
360     HDMITX_SetI2C_Byte(
361         handle, HDMI_TX_GENERAL_REG05, HDMI_TX_GENERAL_REG05_REGINTPOL_MASK | HDMI_TX_GENERAL_REG05_REGINTIOMODE_MASK,
362         ((level == HIGH_LVL) ? (HDMI_TX_GENERAL_REG05_REGINTPOL(0x01U) | HDMI_TX_GENERAL_REG05_REGINTIOMODE(0x00U)) :
363                                (HDMI_TX_GENERAL_REG05_REGINTPOL(0x00U) | HDMI_TX_GENERAL_REG05_REGINTIOMODE(0x01U))));
364 }
it6161_IntMaskEnable(display_handle_t * handle)365 void it6161_IntMaskEnable(display_handle_t *handle)
366 {
367     MIPIRX_SetI2C_Byte(handle, MIPI_RX_SYS_STATUS_REG0F, 0x03U,
368                        0x00U); /* Cannot find relative information about these fields from it6161 programming guide */
369 
370     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_INT_MASK_REG09,
371                          MIPI_RX_INT_MASK_REG09_REnPPSMVidStbChgInt | MIPI_RX_INT_MASK_REG09_REnPPSPVidStbChgInt);
372     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_INT_MASK_REG0A,
373                          MIPI_RX_INT_MASK_REG0A_REnPPGVidStbChgInt | MIPI_RX_INT_MASK_REG0A_REnPPSDByteErrInt |
374                              MIPI_RX_INT_MASK_REG0A_REnCMOffInt | MIPI_RX_INT_MASK_REG0A_REnCMOnInt |
375                              MIPI_RX_INT_MASK_REG0A_REnShutDoneInt | MIPI_RX_INT_MASK_REG0A_REnTurnOnInt);
376     // MIPI_RX_INT_MASK_REG0A_REnFIFOOvRdInt | MIPI_RX_INT_MASK_REG0A_REnFIFOOvWrInt);
377     // MIPI_RX_INT_MASK_REG0A_REnFIFOOvRdInt);
378 
379     MIPIRX_WriteI2C_Byte(handle, MIPI_RX_INT_MASK_REG0B,
380                          MIPI_RX_INT_MASK_REG0B_REnECC1bErrInt | MIPI_RX_INT_MASK_REG0B_REnECC2bErrInt |
381                              MIPI_RX_INT_MASK_REG0B_REnLMFIFOErrInt | MIPI_RX_INT_MASK_REG0B_REnCRCErrInt |
382                              MIPI_RX_INT_MASK_REG0B_REnMCLKOffInt | MIPI_RX_INT_MASK_REG0B_REnPPIFifoOvWrInt);
383 
384     /* select bank0, 0x00~0xff */
385     HDMITX_SetI2C_Byte(handle, HDMI_TX_SYS_STATUS_REG0F, HDMI_TX_SYS_STATUS_REG0F_REGBANKSEL_MASK,
386                        HDMI_TX_SYS_STATUS_REG0F_REGBANKSEL(0x00U));
387     HDMITX_WriteI2C_Byte(handle, HDMI_TX_INT_MASK_REG09,
388                          HDMI_TX_INT_MASK_REG09_REG_AudioOvFlw(0x00U) | HDMI_TX_INT_MASK_REG09_REG_DDCNoACK(0x00U) |
389                              HDMI_TX_INT_MASK_REG09_REG_DDCFIFOErr(0x00U) |
390                              HDMI_TX_INT_MASK_REG09_REG_DDCBusHang(0x00U) | HDMI_TX_INT_MASK_REG09_REG_RxSEN(0x00U) |
391                              HDMI_TX_INT_MASK_REG09_REG_HPD(0x00U));
392     HDMITX_SetI2C_Byte(handle, HDMI_TX_INT_MASK_REG0B, HDMI_TX_INT_MASK_REG0B_REG_VidStable_MASK,
393                        HDMI_TX_INT_MASK_REG0B_REG_VidStable(0x00U));
394 }
395 
IT6161_Init(display_handle_t * handle,const display_config_t * config)396 status_t IT6161_Init(display_handle_t *handle, const display_config_t *config)
397 {
398     status_t status;
399 
400     assert(handle);
401 
402     status = IT6161_Identify(handle);
403     if (kStatus_Success != status)
404     {
405         return status;
406     }
407 
408     it6161.mipi_rx.hs_settle_num                   = 0x01U;
409     it6161.mipi_rx.hs_trailing_skip_stage          = 0x04U;
410     it6161.mipi_rx.enable_sync_bit_error_tolerance = 0x00U;
411     it6161.mipi_rx.enable_multi_lane_deskew        = 0x01U;
412     it6161.mipi_rx.force_continuous_clock_mode     = 0x01U;
413     it6161.mipi_rx.ppi_debug_selection             = 0x0CU;
414     it6161.mipi_rx.ignore_null_packet              = 0x01U;
415     it6161.mipi_rx.ignore_blank_packet             = 0x01U;
416     it6161.mipi_rx.enable_dummy_ecc_error          = 0x00U;
417     it6161.mipi_rx.sel_eotp                        = 0x00U;
418     it6161.mipi_rx.lm_debug_selection              = 0x00U;
419 
420     it6161.mipi_rx.auto_sync_falling   = 0x01U;
421     it6161.mipi_rx.interlaced_mode     = 0x00U;
422     it6161.mipi_rx.user_define_timming = 0x00U;
423     it6161.mipi_rx.prec_update         = PREC_UPDATE;
424     it6161.mipi_rx.mrec_update         = MREC_UPDATE;
425 
426     it6161.mipi_rx.v_timing_resync_selction              = 0x01U;
427     it6161.mipi_rx.enable_v_timing_resync_enhance_mode   = 0x00U;
428     it6161.mipi_rx.enable_frame_resync                   = 0x00U;
429     it6161.mipi_rx.pps_fifo_read_start_point             = 0x04U;
430     it6161.mipi_rx.enable_h_timing_resync                = 0x00U;
431     it6161.mipi_rx.enable_v_timing_resync                = 0x00U;
432     it6161.mipi_rx.enable_fifo_auto_reset                = 0x01U;
433     it6161.mipi_rx.enable_overflow_auto_reset            = 0x00U;
434     it6161.mipi_rx.enable_mclk_horizontal_average        = 0x01U;
435     it6161.mipi_rx.allowable_mclk_horizontal_shift_value = 0x08U;
436     it6161.mipi_rx.allowable_pclk_horizontal_shift_value = 0x03U;
437     it6161.mipi_rx.enable_external_pclk                  = 0x00U;
438     it6161.mipi_rx.bypass_through_mode                   = EN_MIPIRX_BYPASS_MODE;
439     it6161.mipi_rx.enable_ttl_tx_crc                     = 0x01U;
440     it6161.mipi_rx.crc_frame_number                      = 0x20U;
441 
442     it6161.mipi_rx.mipirx_lane_swap = 0x00U;
443     it6161.mipi_rx.mipirx_dpdn_swap = 0x00U;
444     it6161.mipi_rx.lanes            = config->dsiLanes;
445     it6161.mipi_rx.inverse_mclk     = 0x01U;
446 
447     it6161.hdmi_tx.hdmitx_bypass_mode       = EN_HDMITX_BYPASS_MODE;
448     it6161.hdmi_tx.tx_clk_stable            = FORCE_TX_CLK_STABLE;
449     it6161.hdmi_tx.tx_vid_stable            = FORCE_TX_VID_STABLE;
450     it6161.hdmi_tx.de_generation_enable     = 0x00U; /* The DE input received are used for HDMI output */
451     it6161.hdmi_tx.vertical_sync_polarity   = V_SYNC_POL;
452     it6161.hdmi_tx.horizontal_sync_polarity = H_SYNC_POL;
453     it6161.hdmi_tx.de_only_in               = 0x01U;
454 
455     /* Use these arguments to generate hdmi blank timing */
456     it6161.hdmi_tx.mode.hdisplay    = FSL_VIDEO_EXTRACT_WIDTH(config->resolution);
457     it6161.hdmi_tx.mode.hsync_start = FSL_VIDEO_EXTRACT_WIDTH(config->resolution) + config->hfp;
458     it6161.hdmi_tx.mode.hsync_end   = FSL_VIDEO_EXTRACT_WIDTH(config->resolution) + config->hfp + config->hsw;
459     it6161.hdmi_tx.mode.htotal = FSL_VIDEO_EXTRACT_WIDTH(config->resolution) + config->hfp + config->hsw + config->hbp;
460     it6161.hdmi_tx.mode.vdisplay    = FSL_VIDEO_EXTRACT_HEIGHT(config->resolution);
461     it6161.hdmi_tx.mode.vsync_start = FSL_VIDEO_EXTRACT_HEIGHT(config->resolution) + config->vfp;
462     it6161.hdmi_tx.mode.vsync_end   = FSL_VIDEO_EXTRACT_HEIGHT(config->resolution) + config->vfp + config->vsw;
463     it6161.hdmi_tx.mode.vtotal = FSL_VIDEO_EXTRACT_HEIGHT(config->resolution) + config->vfp + config->vsw + config->vbp;
464     it6161.hdmi_tx.support_audio = HDMI_TX_SUPPORT_AUDIO;
465     if (it6161.hdmi_tx.support_audio != 0x0U)
466     {
467         it6161.hdmi_tx.output_channel          = HDMI_TX_OUTPUT_CHANNEL;
468         it6161.hdmi_tx.input_audio_type        = HDMI_TX_INPUT_AUDIO_TYPE;
469         it6161.hdmi_tx.input_audio_interface   = (uint8_t)HDMI_TX_INPUT_AUDIO_INTERFACE;
470         it6161.hdmi_tx.input_audio_sample_freq = HDMI_TX_INPUT_AUDIO_SAMPLE_FREQ;
471     }
472     it6161.hdmi_tx.pclk_div2 = HDMI_TX_PCLK_DIV2;
473 
474     it6161_MIPIRX_Init(handle);
475     it6161_HDMITX_Init(handle);
476     /* set it6161's active level as high level */
477     it6161_SetIntActiveLevel(handle, HIGH_LVL);
478 
479     it6161_IntMaskEnable(handle);
480 
481     return status;
482 }
483 
IT6161_Deinit(display_handle_t * handle)484 status_t IT6161_Deinit(display_handle_t *handle)
485 {
486     return kStatus_Success;
487 }
488 
IT6161_Start(display_handle_t * handle)489 status_t IT6161_Start(display_handle_t *handle)
490 {
491     return kStatus_Success;
492 }
493 
IT6161_Stop(display_handle_t * handle)494 status_t IT6161_Stop(display_handle_t *handle)
495 {
496     return kStatus_Success;
497 }
498 
IT6161_Interrupt(display_handle_t * handle)499 void IT6161_Interrupt(display_handle_t *handle)
500 {
501     MIPIRX_DevLoopProc(handle);
502     HDMITX_DevLoopProc(handle);
503 }
504