1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 */
5
6 #ifdef __linux__
7 //#include <linux/bits.h>
8 #include <linux/of_graph.h>
9 #include <linux/platform_device.h>
10
11 #include <linux/delay.h>
12 #include <linux/device.h>
13 #include <linux/err.h>
14 #include <linux/extcon.h>
15 #include <linux/fs.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/i2c.h>
18 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/regmap.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/types.h>
25 #include <linux/wait.h>
26 #include <drm/drm_mipi_dsi.h>
27
28 #include <crypto/hash.h>
29 #include <crypto/sha.h>
30
31 #include <drm/drm_atomic_helper.h>
32 #include <drm/drm_bridge.h>
33 #include <drm/drm_crtc.h>
34 #include <drm/drm_crtc_helper.h>
35 #include <drm/drm_dp_helper.h>
36 #include <drm/drm_edid.h>
37 #include <drm/drm_print.h>
38 #include <drm/drm_mipi_dsi.h>
39 #include <drm/drm_probe_helper.h>
40
41 #include <sound/hdmi-codec.h>
42 #else
43
44 #include "platform.h"
45
46 #endif
47 #define IT6161_PRINT(fmt, ...) \
48 _DRM_PRINTK(, WARNING, fmt, ##__VA_ARGS__)
49
50 static int ite_debug = 0;
51
52 #define it6161_debug(fmt, ...) do { \
53 if (ite_debug) \
54 _DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__); \
55 } while (0)
56
57 /* Vendor option */
58 #define AUDIO_SELECT I2S
59 #define AUDIO_TYPE LPCM
60 #define AUDIO_SAMPLE_RATE SAMPLE_RATE_48K
61 #define AUDIO_CHANNEL_COUNT 2
62
63 /*
64 * 0: Standard I2S
65 * 1: 32bit I2S
66 */
67 #define I2S_INPUT_FORMAT 1
68
69 /*
70 * 0: Left-justified
71 * 1: Right-justified
72 */
73 #define I2S_JUSTIFIED 0
74
75 /*
76 * 0: Data delay 1T correspond to WS
77 * 1: No data delay correspond to WS
78 */
79 #define I2S_DATA_DELAY 0
80
81 /*
82 * 0: Left channel
83 * 1: Right channel
84 */
85 #define I2S_WS_CHANNEL 0
86
87 /*
88 * 0: MSB shift first
89 * 1: LSB shift first
90 */
91 #define I2S_DATA_SEQUENCE 0
92
93 #define AUX_WAIT_TIMEOUT_MS 100
94 #define PIXEL_CLK_DELAY 1
95 #define PIXEL_CLK_INVERSE 0
96 #define ADJUST_PHASE_THRESHOLD 80000
97 #define MAX_PIXEL_CLK 95000
98 #define DEFAULT_DRV_HOLD 0
99 #define DEFAULT_PWR_ON 0
100
101 enum hdmi_tx_mode {
102 HDMI_TX_NONE,
103 HDMI_TX_BY_PASS,
104 HDMI_TX_ENABLE_DE_ONLY,
105 HDMI_TX_ENABLE_PATTERN_GENERATOR,
106 };
107
108 enum it6161_audio_select {
109 I2S = 0,
110 SPDIF,
111 TDM,
112 };
113
114 enum it6161_audio_sample_rate {
115 SAMPLE_RATE_24K = 0x6,
116 SAMPLE_RATE_32K = 0x3,
117 SAMPLE_RATE_48K = 0x2,
118 SAMPLE_RATE_96K = 0xA,
119 SAMPLE_RATE_192K = 0xE,
120 SAMPLE_RATE_44_1K = 0x0,
121 SAMPLE_RATE_88_2K = 0x8,
122 SAMPLE_RATE_176_4K = 0xC,
123 };
124
125 enum it6161_audio_type {
126 LPCM = 0,
127 NLPCM,
128 DSS,
129 };
130
131 enum it6161_audio_u32_length {
132 u32_LENGTH_16BIT = 0,
133 u32_LENGTH_18BIT,
134 u32_LENGTH_20BIT,
135 u32_LENGTH_24BIT,
136 };
137
138 /*
139 * Audio Sample u32 Length
140 * u32_LENGTH_16BIT
141 * u32_LENGTH_18BIT
142 * u32_LENGTH_20BIT
143 * u32_LENGTH_24BIT
144 */
145 #define AUDIO_u32_LENGTH u32_LENGTH_24BIT
146
147 enum it6161_active_level {
148 LOW,
149 HIGH,
150 };
151
152 enum dsi_data_id {
153 RGB_24b = 0x3E,
154 RGB_30b = 0x0D,
155 RGB_36b = 0x1D,
156 RGB_18b = 0x1E,
157 RGB_18b_L = 0x2E,
158 YCbCr_16b = 0x2C,
159 YCbCr_20b = 0x0C,
160 YCbCr_24b = 0x1C,
161 };
162
163 #include "ite_it6161_hdmi_tx.h"
164 #include "ite_it6161_mipi_rx.h"
165
166 // for sample clock
167 #define AUDFS_22p05KHz 4
168 #define AUDFS_44p1KHz 0
169 #define AUDFS_88p2KHz 8
170 #define AUDFS_176p4KHz 12
171
172 #define AUDFS_24KHz 6
173 #define AUDFS_48KHz 2
174 #define AUDFS_96KHz 10
175 #define AUDFS_192KHz 14
176
177 #define AUDFS_768KHz 9
178
179 #define AUDFS_32KHz 3
180 #define AUDFS_OTHER 1
181
182 ////////////////////////////////////////////////////////////////////////////////
183 // HDMI VTable
184 ////////////////////////////////////////////////////////////////////////////////
185 static HDMI_VTiming const s_VMTable[] = {
186 { 1,0,640,480,800,525,25175000L,0x89,16,96,48,10,2,33,PROG,Vneg,Hneg},//640x480@60Hz
187 { 2,0,720,480,858,525,27000000L,0x80,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@60Hz
188 { 3,0,720,480,858,525,27000000L,0x80,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@60Hz
189 { 4,0,1280,720,1650,750,74250000L,0x2E,110,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@60Hz
190 { 5,0,1920,540,2200,562,74250000L,0x2E,88,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@60Hz
191 { 6,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz
192 { 7,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz
193 { 8,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz
194 { 9,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz
195 {10,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz
196 {11,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz
197 {12,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz
198 {13,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz
199 {14,1,1440,480,1716,525,54000000L,0x40,32,124,120,9,6,30,PROG,Vneg,Hneg},//1440x480@60Hz
200 {15,1,1440,480,1716,525,54000000L,0x40,32,124,120,9,6,30,PROG,Vneg,Hneg},//1440x480@60Hz
201 {16,0,1920,1080,2200,1125,148500000L,0x17,88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@60Hz
202 {17,0,720,576,864,625,27000000L,0x80,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@50Hz
203 {18,0,720,576,864,625,27000000L,0x80,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@50Hz
204 {19,0,1280,720,1980,750,74250000L,0x2E,440,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@50Hz
205 {20,0,1920,540,2640,562,74250000L,0x2E,528,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@50Hz
206 {21,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz
207 {22,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz
208 {23,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz
209 {24,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz
210 {25,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz
211 {26,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz
212 {27,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz
213 {28,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz
214 {29,1,1440,576,1728,625,54000000L,0x40,24,128,136,5,5,39,PROG,Vpos,Hneg},//1440x576@50Hz
215 {30,1,1440,576,1728,625,54000000L,0x40,24,128,136,5,5,39,PROG,Vpos,Hneg},//1440x576@50Hz
216 {31,0,1920,1080,2640,1125,148500000L,0x17,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@50Hz
217 {32,0,1920,1080,2750,1125,74250000L,0x2E,638,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@24Hz
218 {33,0,1920,1080,2640,1125,74250000L,0x2E,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@25Hz
219 {34,0,1920,1080,2200,1125,74250000L,0x2E,88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@30Hz
220 {35,2,2880,480,1716*2,525,108000000L,0x20,32*2,124*2,120*2,9,6,30,PROG,Vneg,Hneg},//2880x480@60Hz
221 {36,2,2880,480,1716*2,525,108000000L,0x20,32*2,124*2,120*2,9,6,30,PROG,Vneg,Hneg},//2880x480@60Hz
222 {37,1,2880,576,3456,625,108000000L,0x20,24*2,128*2,136*2,5,5,39,PROG,Vneg,Hneg},//2880x576@50Hz
223 {38,2,2880,576,3456,625,108000000L,0x20,24*2,128*2,136*2,5,5,39,PROG,Vneg,Hneg},//2880x576@50Hz
224 {39,0,1920,540,2304,625,72000000L,0x17,32,168,184,23,5,57,INTERLACE,Vneg,Hpos},//1920x1080@50Hz
225 // 100Hz
226 {40,0,1920,540,2640,562,148500000L,0x17,528,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@100Hz
227 {41,0,1280,720,1980,750,148500000L,0x17,440,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@100Hz
228 {42,0,720,576,864,625, 54000000L,0x40,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@100Hz
229 {43,0,720,576,864,625, 54000000L,0x40,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@100Hz
230 {44,1,720,288,864,312, 27000000L,0x80,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@100Hz
231 {45,1,720,288,864,312, 27000000L,0x80,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@100Hz
232 // 120Hz
233 {46,0,1920,540,2200,562,148500000L,0x17,88,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@120Hz
234 {47,0,1280,720,1650,750,148500000L,0x17,110,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@120Hz
235 {48,0, 720,480, 858,525, 54000000L,0x40,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz
236 {49,0, 720,480, 858,525, 54000000L,0x40,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz
237 {50,1, 720,240, 858,262, 27000000L,0x80,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz
238 {51,1, 720,240, 858,262, 27000000L,0x80,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz
239
240 // 200Hz
241 {52,0,720,576,864,625,108000000L,0x20,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@200Hz
242 {53,0,720,576,864,625,108000000L,0x20,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@200Hz
243 {54,1,720,288,864,312, 54000000L,0x40,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@200Hz
244 {55,1,720,288,864,312, 54000000L,0x40,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@200Hz
245 // 240Hz
246 {56,0,720,480,858,525,108000000L,0x20,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz
247 {57,0,720,480,858,525,108000000L,0x20,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz
248 {58,1,720,240,858,262, 54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz
249 {59,1,720,240,858,262, 54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz
250 // 720p low resolution
251 {60,0,1280, 720,3300, 750, 59400000L,0x3A,1760,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@24Hz
252 {61,0,1280, 720,3960, 750, 74250000L,0x2E,2420,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@25Hz
253 {62,0,1280, 720,3300, 750, 74250000L,0x2E,1760,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@30Hz
254 // 1080p high refresh rate
255 {63,0,1920,1080,2200,1125,297000000L,0x0B, 88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@120Hz
256 {64,0,1920,1080,2640,1125,297000000L,0x0B,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@100Hz
257 // VESA mode
258 {0,0,640,350,832,445,31500000L,0x6D,32,64,96,32,3,60,PROG,Vneg,Hpos},// 640x350@85
259 {0,0,640,400,832,445,31500000L,0x6D,32,64,96,1,3,41,PROG,Vneg,Hneg},// 640x400@85
260 {0,0,832,624,1152,667,57283000L,0x3C,32,64,224,1,3,39,PROG,Vneg,Hneg},// 832x624@75Hz
261 {0,0,720,350,900,449,28322000L,0x7A,18,108,54,59,2,38,PROG,Vneg,Hneg},// 720x350@70Hz
262 {0,0,720,400,900,449,28322000L,0x7A,18,108,54,13,2,34,PROG,Vpos,Hneg},// 720x400@70Hz
263 {0,0,720,400,936,446,35500000L,0x61,36,72,108,1,3,42,PROG,Vpos,Hneg},// 720x400@85
264 {0,0,640,480,800,525,25175000L,0x89,16,96,48,10,2,33,PROG,Vneg,Hneg},// 640x480@60
265 {0,0,640,480,832,520,31500000L,0x6D,24,40,128,9,3,28,PROG,Vneg,Hneg},// 640x480@72
266 {0,0,640,480,840,500,31500000L,0x6D,16,64,120,1,3,16,PROG,Vneg,Hneg},// 640x480@75
267 {0,0,640,480,832,509,36000000L,0x60,56,56,80,1,3,25,PROG,Vneg,Hneg},// 640x480@85
268 {0,0,800,600,1024,625,36000000L,0x60,24,72,128,1,2,22,PROG,Vpos,Hpos},// 800x600@56
269 {0,0,800,600,1056,628,40000000L,0x56,40,128,88,1,4,23,PROG,Vpos,Hpos},// 800x600@60
270 {0,0,800,600,1040,666,50000000L,0x45,56,120,64,37,6,23,PROG,Vpos,Hpos},// 800x600@72
271 {0,0,800,600,1056,625,49500000L,0x45,16,80,160,1,3,21,PROG,Vpos,Hpos},// 800x600@75
272 {0,0,800,600,1048,631,56250000L,0x3D,32,64,152,1,3,27,PROG,Vpos,Hpos},// 800X600@85
273 {0,0,848,480,1088,517,33750000L,0x66,16,112,112,6,8,23,PROG,Vpos,Hpos},// 840X480@60
274 {0,0,1024,384,1264,408,44900000L,0x4C,8,176,56,0,4,20,INTERLACE,Vpos,Hpos},//1024x768(I)@87Hz
275 {0,0,1024,768,1344,806,65000000L,0x35,24,136,160,3,6,29,PROG,Vneg,Hneg},// 1024x768@60
276 {0,0,1024,768,1328,806,75000000L,0x2E,24,136,144,3,6,29,PROG,Vneg,Hneg},// 1024x768@70
277 {0,0,1024,768,1312,800,78750000L,0x2B,16,96,176,1,3,28,PROG,Vpos,Hpos},// 1024x768@75
278 {0,0,1024,768,1376,808,94500000L,0x24,48,96,208,1,3,36,PROG,Vpos,Hpos},// 1024x768@85
279 {0,0,1152,864,1600,900,108000000L,0x20,64,128,256,1,3,32,PROG,Vpos,Hpos},// 1152x864@75
280 {0,0,1280,768,1440,790,68250000L,0x32,48,32,80,3,7,12,PROG,Vneg,Hpos},// 1280x768@60-R
281 {0,0,1280,768,1664,798,79500000L,0x2B,64,128,192,3,7,20,PROG,Vpos,Hneg},// 1280x768@60
282 {0,0,1280,768,1696,805,102250000L,0x21,80,128,208,3,7,27,PROG,Vpos,Hneg},// 1280x768@75
283 {0,0,1280,768,1712,809,117500000L,0x1D,80,136,216,3,7,31,PROG,Vpos,Hneg},// 1280x768@85
284 {0,0,1280,800,1440, 823, 71000000L,0x31, 48, 32, 80,3,6,14,PROG,Vpos,Hneg},// 1280x800@60Hz
285 {0,0,1280,800,1680, 831, 83500000L,0x29, 72,128,200,3,6,22,PROG,Vpos,Hneg},// 1280x800@60Hz
286 {0,0,1280,800,1696, 838,106500000L,0x20, 80,128,208,3,6,29,PROG,Vpos,Hneg},// 1280x800@75Hz
287 {0,0,1280,800,1712, 843,122500000L,0x1C, 80,136,216,3,6,34,PROG,Vpos,Hneg},// 1280x800@85Hz
288 {0,0,1280,960,1800,1000,108000000L,0x20,96,112,312,1,3,36,PROG,Vpos,Hpos},// 1280x960@60
289 {0,0,1280,960,1728,1011,148500000L,0x17,64,160,224,1,3,47,PROG,Vpos,Hpos},// 1280x960@85
290 {0,0,1280,1024,1688,1066,108000000L,0x20,48,112,248,1,3,38,PROG,Vpos,Hpos},// 1280x1024@60
291 {0,0,1280,1024,1688,1066,135000000L,0x19,16,144,248,1,3,38,PROG,Vpos,Hpos},// 1280x1024@75
292 {0,0,1280,1024,1728,1072,157500000L,0x15,64,160,224,1,3,44,PROG,Vpos,Hpos},// 1280X1024@85
293 {0,0,1360,768,1792,795,85500000L,0x28,64,112,256,3,6,18,PROG,Vpos,Hpos},// 1360X768@60
294 {0,0,1366,768,1792,798,85500000L,0x28, 70,143,213,3,3,24,PROG,Vpos,Hpos},// 1366X768@60
295 {0,0,1366,768,1500,800,72000000L,0x30, 14, 56, 64,1,3,28,PROG,Vpos,Hpos},// 1360X768@60
296 {0,0,1400,1050,1560,1080,101000000L,0x22,48,32,80,3,4,23,PROG,Vneg,Hpos},// 1400x768@60-R
297 {0,0,1400,1050,1864,1089,121750000L,0x1C,88,144,232,3,4,32,PROG,Vpos,Hneg},// 1400x768@60
298 {0,0,1400,1050,1896,1099,156000000L,0x16,104,144,248,3,4,42,PROG,Vpos,Hneg},// 1400x1050@75
299 {0,0,1400,1050,1912,1105,179500000L,0x13,104,152,256,3,4,48,PROG,Vpos,Hneg},// 1400x1050@85
300 {0,0,1440,900,1600,926,88750000L,0x26,48,32,80,3,6,17,PROG,Vneg,Hpos},// 1440x900@60-R
301 {0,0,1440,900,1904,934,106500000L,0x20,80,152,232,3,6,25,PROG,Vpos,Hneg},// 1440x900@60
302 {0,0,1440,900,1936,942,136750000L,0x19,96,152,248,3,6,33,PROG,Vpos,Hneg},// 1440x900@75
303 {0,0,1440,900,1952,948,157000000L,0x16,104,152,256,3,6,39,PROG,Vpos,Hneg},// 1440x900@85
304 {0,0,1600,1200,2160,1250,162000000L,0x15,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@60
305 {0,0,1600,1200,2160,1250,175500000L,0x13,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@65
306 {0,0,1600,1200,2160,1250,189000000L,0x12,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@70
307 {0,0,1600,1200,2160,1250,202500000L,0x11,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@75
308 {0,0,1600,1200,2160,1250,229500000L,0x0F,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@85
309 {0,0,1680,1050,1840,1080,119000000L,0x1D,48,32,80,3,6,21,PROG,Vneg,Hpos},// 1680x1050@60-R
310 {0,0,1680,1050,2240,1089,146250000L,0x17,104,176,280,3,6,30,PROG,Vpos,Hneg},// 1680x1050@60
311 {0,0,1680,1050,2272,1099,187000000L,0x12,120,176,296,3,6,40,PROG,Vpos,Hneg},// 1680x1050@75
312 {0,0,1680,1050,2288,1105,214750000L,0x10,128,176,304,3,6,46,PROG,Vpos,Hneg},// 1680x1050@85
313 {0,0,1792,1344,2448,1394,204750000L,0x10,128,200,328,1,3,46,PROG,Vpos,Hneg},// 1792x1344@60
314 {0,0,1792,1344,2456,1417,261000000L,0x0D,96,216,352,1,3,69,PROG,Vpos,Hneg},// 1792x1344@75
315 {0,0,1856,1392,2528,1439,218250000L,0x0F,96,224,352,1,3,43,PROG,Vpos,Hneg},// 1856x1392@60
316 {0,0,1856,1392,2560,1500,288000000L,0x0C,128,224,352,1,3,104,PROG,Vpos,Hneg},// 1856x1392@75
317 {0,0,1920,1200,2080,1235,154000000L,0x16,48,32,80,3,6,26,PROG,Vneg,Hpos},// 1920x1200@60-R
318 {0,0,1920,1200,2592,1245,193250000L,0x11,136,200,336,3,6,36,PROG,Vpos,Hneg},// 1920x1200@60
319 {0,0,1920,1200,2608,1255,245250000L,0x0E,136,208,344,3,6,46,PROG,Vpos,Hneg},// 1920x1200@75
320 {0,0,1920,1200,2624,1262,281250000L,0x0C,144,208,352,3,6,53,PROG,Vpos,Hneg},// 1920x1200@85
321 {0,0,1920,1440,2600,1500,234000000L,0x0E,128,208,344,1,3,56,PROG,Vpos,Hneg},// 1920x1440@60
322 {0,0,1920,1440,2640,1500,297000000L,0x0B,144,224,352,1,3,56,PROG,Vpos,Hneg},// 1920x1440@75
323 };
324
325 #define DIFF(a,b) (((a)>(b))?((a)-(b)):((b)-(a)))
326
327 static bool bChangeMode = false ;
328 static unsigned char CommunBuff[128] ;
329
330 static const u8 CA[] = { 0,0,0, 02, 0x3, 0x7, 0xB, 0xF, 0x1F } ;
331
332 static u32 VideoPixelClock ;
333 static u8 pixelrep ; // no pixelrepeating
334 // static HDMI_Aspec aspec ;
335 // static HDMI_Colorimetry Colorimetry ;
336
337 static u32 ulAudioSampleFS = INPUT_SAMPLE_FREQ_HZ;
338 // u8 bAudioSampleFreq = INPUT_SAMPLE_FREQ ;
339 static u8 bOutputAudioChannel = OUTPUT_CHANNEL;
340 static u8 bOutputAudioType=CNOFIG_INPUT_AUDIO_TYPE;
341
342 #define MSCOUNT 1000
343 #define LOADING_UPDATE_TIMEOUT (3000/32) // 3sec
344
345 static HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT];
346
347 /* configuration */
348 //#define ENABLE_HDCP
349 #define ENABLE_MIPI_RX_EXTERNAL_CLOCK false
350 #define MPLaneSwap FALSE
351 #define MPPNSwap FALSE /* TRUE: MTK , FALSE: Solomon */
352 #define MIPI_RX_LANE_COUNT 4 /* 1~4 */
353
354 #define OUTPUT_COLOR_MODE F_MODE_RGB444 /* F_MODE_YUV444, F_MODE_YUV422, F_MODE_RGB444 */
355 #define HDMI_TX_MODE HDMI_TX_ENABLE_DE_ONLY /* HDMI_TX_NONE, HDMI_TX_BY_PASS, HDMI_TX_ENABLE_DE_ONLY, HDMI_TX_ENABLE_PATTERN_GENERATOR */
356 #define HDMI_TX_PATTERN_GENERATOR_FORMAT 16 /* support format 2, 4, 16*/
357 #define HDMI_TX_PATTERN_COLLOR_R 0x03
358 #define HDMI_TX_PATTERN_COLLOR_G 0x00
359 #define HDMI_TX_PATTERN_COLLOR_B 0x00
360
361 /* vendor option */
362 #define EOTPSel 0 /* LM option 0~15 */
363 #define EnDeSkew TRUE
364 #define PPIDbgSel 12/* 0~15 */
365 #define RegIgnrNull 1
366 #define RegIgnrBlk 1
367 #define RegEnDummyECC 0
368 #define LMDbgSel 0 /* 0~7 */
369 #define EnContCK TRUE
370 #define HSSetNum 3
371 #define EnMBPM FALSE /* enable MIPI Bypass Mode */
372
373 #if (EnMBPM == TRUE)
374 #define PREC_Update TRUE//int PREC_Update = FALSE; // enable P-timing update
375 #define MREC_Update TRUE//int MREC_Update = FALSE; // enable M-timing update
376 #define EnTBPM TRUE /* enable HDMITX Bypass Mode */
377 #else
378 #define PREC_Update FALSE//int PREC_Update = FALSE; // enable P-timing update
379 #define MREC_Update FALSE//int MREC_Update = FALSE; // enable M-timing update
380 #define EnTBPM FALSE /* enable HDMITX Bypass Mode */
381 #endif
382
383 #define REGSELDEF FALSE
384 #define MPForceStb FALSE
385 #define EnHReSync FALSE
386 #define EnVReSync FALSE
387 #define EnFReSync FALSE
388 #define EnVREnh FALSE
389 #define EnVREnhSel 1 /* 0:Div2, 1:Div4, 2:Div8, 3:Div16, 4:Div32 */
390 #define EnMAvg TRUE
391
392 #if (IC_VERSION == 0xC0)
393 #define SkipStg 4
394 #else
395 #define SkipStg 2
396 #endif
397
398 #if (IC_VERSION == 0xC0)
399 #define PDREFCLK FALSE
400 #else
401 #define PDREFCLK TRUE
402 #endif
403
404 #define PDREFCNT 0 /* when PDREFCLK=TRUE, 0:div2, 1:div4, 2:div8, 3:divg16 */
405 #define EnIntWakeU3 FALSE
406 #define EnIOIDDQ FALSE
407 #define EnStb2Rst FALSE
408 #define EnExtStdby FALSE
409 #define EnStandby FALSE
410
411 #if (IC_VERSION == 0xC0)
412 #define MShift 4//int MShift = 5; // default: 0 //fmt2 fmt4 :4
413 #define PPSFFRdStg 0x04//int PPSFFRdStg = 0x10; //PPSFFRdStg(2:0)
414 #define RegAutoSync TRUE//int RegAutoSync = TRUE;//add sync falling //pet:D0 20200211
415 #else
416 #define MShift 5//int MShift = 5; // default: 0 //fmt2 fmt4 :4
417 #define PPSFFRdStg 0x10//int PPSFFRdStg = 0x10; //PPSFFRdStg(2:0)
418 #endif //#if (IC_VERSION == 0xC0)
419
420 #define PShift 3
421 #define EnFFAutoRst TRUE
422
423 #define RegEnSyncErr FALSE//int RegEnSyncErr = FALSE;
424 #define EnTxCRC TRUE//int EnTxCRC = TRUE;
425 #define TxCRCnum (0x20) //D0 20200211//(0x00)//TxCRCnum(6:0)//int TxCRCnum = 0x00; //TxCRCnum(6:0)
426
427 #if (IC_VERSION == 0xC0)
428 #define InvMCLK TRUE //FALSE for solomon, if NonUFO, MCLK max = 140MHz with InvMCLK=TRUE
429 #else
430 #define InvMCLK FALSE //FALSE for solomon, if NonUFO, MCLK max = 140MHz with InvMCLK=TRUE
431 #endif
432
433 #define InvPCLK FALSE
434
435 #ifndef INV_INPUT_PCLK
436 #define PCLKINV 0
437 #else
438 #define PCLKINV B_TX_VDO_LATCH_EDGE
439 #endif
440
441 #ifndef INV_INPUT_ACLK
442 #define InvAudCLK 0
443 #else
444 #define InvAudCLK B_TX_AUDFMT_FALL_EDGE_SAMPLE_WS
445 #endif
446
447 // #define INIT_CLK_LOW
448
449 #define TxChSwap 0
450 #define TxPNSwap 0
451
452 #define NRTXRCLK 1//int NRTXRCLK = true;//it6161b0 option true:set TRCLK by self
453 #define RCLKFreqSel 1// int RCLKFreqSel = true; // false: 10MHz(div1), true : 20 MHz(OSSDIV2)
454 // #ifdef REDUCE_HDMITX_SRC_JITTER
455 // #define ForceTxCLKStb true// int ForceTxCLKStb = false; //true:define _hdmitx_jitter_
456 // #else
457 #define ForceTxCLKStb true //20200220 C code set true-> false
458 // #endif //#ifdef REDUCE_HDMITX_SRC_JITTER
459 static const RegSetEntry HDMITX_Init_Table[] = {
460 {0x0F, 0x40, 0x00},
461 //PLL Reset
462 {0x62, 0x08, 0x00}, // XP_RESETB
463 {0x64, 0x04, 0x00}, // IP_RESETB
464 {0x0F, 0x01, 0x00}, // bank 0 ;3
465 #ifdef INIT_CLK_LOW
466 {0x62, 0x90, 0x10},
467 {0x64, 0x89, 0x09},
468 {0x68, 0x10, 0x10},
469 #endif
470
471
472
473 // {0xD1, 0x0E, 0x0C},
474 // {0x65, 0x03, 0x00},
475 // #ifdef NON_SEQUENTIAL_YCBCR422 // for ITE HDMIRX
476 // {0x71, 0xFC, 0x1C},
477 // #else
478 // {0x71, 0xFC, 0x18},
479 // #endif
480
481 {0x8D, 0xFF, CEC_I2C_SLAVE_ADDR},//EnCEC
482 //{0x0F, 0x08, 0x08},
483 {0xA9, 0x80, (EnTBPM<<7)},// hdmitxset(0xa9, 0xc0, (EnTBPM<<7) + (EnTxPatMux<<6))
484 {0xBF, 0x80, (NRTXRCLK<<7)},//from c code hdmitxset(0xbf, 0x80, (NRTXRCLK<<7));
485
486 // Initial Value
487 {0xF8,0xFF,0xC3},
488 {0xF8,0xFF,0xA5},
489 //{0x05,0x1E,0x0C},//hdmitxset(0x05, 0x1E, (ForceRxOn<<4)+(RCLKPDSel<<2)+(RCLKPDEn<<1));ForceRxOn:F,RCLKPDSel=3,RCLKPDSel=false
490 {0xF4,0x0C,0x00},//hdmitxset(0xF4, 0x0C, DDCSpeed<<2);//DDC75K
491 {0xF3,0x02,0x00},//hdmitxset(0xF3, 0x02, ForceVOut<<1);//ForceVOut:false
492 // {0x20, 0x80, 0x80},//TODO: check need or not?
493 // {0x37, 0x01, 0x00},//TODO: check need or not?
494 // {0x20, 0x80, 0x00},//TODO: check need or not?
495 {0xF8,0xFF,0xFF},
496 {0x5A,0x0C,0x0C},//hdmitxset(0x5A, 0x0C, 0x0C);
497 {0xD1,0x0A,((ForceTxCLKStb)<<3)+0x02},//hdmitxset(0xD1, 0x0A, (ForceTxCLKStb<<3)+0x02); // High Sensitivity , modified by junjie force "CLK_stable"
498 {0x5D,0x04,((RCLKFreqSel)<<2)},//hdmitxset(0x5D, 0x04, (RCLKFreqSel<<2));//int RCLKFreqSel = true; // false: 10MHz(div1), true : 20 MHz(OSSDIV2)
499 {0x65,0x03,0x00},//hdmitxset(0x65, 0x03, RINGOSC);
500 {0x71,0xF9,((0<<6)+(0<<5)+(1<<4)+(1<<3)+0)},//hdmitxset(0x71, 0xF9, (XPStableTime<<6)+(EnXPLockChk<<5)+(EnPLLBufRst<<4)+(EnFFAutoRst<<3)+ EnFFManualRst);
501 {0xCF,0xFF,(0<<7)+(0<<6)+(0<<4)+(0<<2)+0},//hdmitxset(0xCF, 0xFF, (EnPktLimitGB<<7)+(EnPktBlankGB<<6)+(KeepOutGBSel<<4)+(PktLimitGBSel<<2)+PktBlankGBSel);
502
503 {0xd1,0x02,0x00},//hdmitxset(0xd1, 0x02, 0x00);//VidStbSen = false
504 // 2014/01/07 HW Request for ROSC stable
505
506 // {0x5D,0x03,0x01},
507 //~2014/01/07
508 // #ifdef USE_IT66120
509 // {0x5A, 0x02, 0x00},
510 // {0xE2, 0xFF, 0xFF},
511 // #endif
512
513 {0x59, 0xD0, (((2-1)<<6)+(0<<4))},//hdmitxset(0x59, 0xD0, ((ManuallPR-1)<<6)+(DisLockPR<<4));ManuallPR=2, DisLockPR = 0
514 // {0x59, 0xD8, 0x40|PCLKINV},
515 #if((TxChSwap == 1) || (TxPNSwap == 1))
516 {0x6b,0xC0,((TxChSwap<<7)+ (TxPNSwap<<6))},// hdmitxset(0x6b, 0xC0,(TxChSwap<<7)+ (TxPNSwap<<6));
517 {0x61,0x40,0x40},// hdmitxset(0x61, 0x40,0x40);
518 #endif //#if((TxChSwap ==true) || (TxPNSwap ==true))
519
520
521 {0xE1, 0x20, InvAudCLK},// Inverse Audio Latch Edge of IACLK
522 {0xF5, 0x40, 0x00},//hdmitxset(0xF5,0x40,ForceTMDSStable<<6);
523
524 {0x05, 0xC0, 0x40},// Setup INT Pin: Active Low & Open-Drain
525
526 // {REG_TX_INT_MASK1, 0xFF, ~(B_TX_RXSEN_MASK|B_TX_HPD_MASK)},
527 // {REG_TX_INT_MASK2, 0xFF, ~(B_TX_KSVLISTCHK_MASK|B_TX_AUTH_DONE_MASK|B_TX_AUTH_FAIL_MASK)},
528 // {REG_TX_INT_MASK3, 0xFF, ~(B_TX_VIDSTABLE_MASK)},
529 {0x0C, 0xFF, 0xFF},
530 {0x0D, 0xFF, 0xFF},
531 {0x0E, 0x03, 0x03},// Clear all Interrupt
532
533 {0x0C, 0xFF, 0x00},
534 {0x0D, 0xFF, 0x00},
535 {0x0E, 0x02, 0x00},
536 //{0x09, 0x03, 0x00}, // Enable HPD and RxSen Interrupt//remove for interrupt mode allen
537 {0x20,0x01,0x00}
538 };
539
540 static const RegSetEntry HDMITX_DefaultVideo_Table[] = {
541
542 ////////////////////////////////////////////////////
543 // Config default output format.
544 ////////////////////////////////////////////////////
545 {0x72, 0xff, 0x00},
546 {0x70, 0xff, 0x00},
547 #ifndef DEFAULT_INPUT_YCBCR
548 // GenCSC\RGB2YUV_ITU709_16_235.c
549 {0x72, 0xFF, 0x02},
550 {0x73, 0xFF, 0x00},
551 {0x74, 0xFF, 0x80},
552 {0x75, 0xFF, 0x00},
553 {0x76, 0xFF, 0xB8},
554 {0x77, 0xFF, 0x05},
555 {0x78, 0xFF, 0xB4},
556 {0x79, 0xFF, 0x01},
557 {0x7A, 0xFF, 0x93},
558 {0x7B, 0xFF, 0x00},
559 {0x7C, 0xFF, 0x49},
560 {0x7D, 0xFF, 0x3C},
561 {0x7E, 0xFF, 0x18},
562 {0x7F, 0xFF, 0x04},
563 {0x80, 0xFF, 0x9F},
564 {0x81, 0xFF, 0x3F},
565 {0x82, 0xFF, 0xD9},
566 {0x83, 0xFF, 0x3C},
567 {0x84, 0xFF, 0x10},
568 {0x85, 0xFF, 0x3F},
569 {0x86, 0xFF, 0x18},
570 {0x87, 0xFF, 0x04},
571 #else
572 // GenCSC\YUV2RGB_ITU709_16_235.c
573 {0x0F, 0x01, 0x00},
574 {0x72, 0xFF, 0x03},
575 {0x73, 0xFF, 0x00},
576 {0x74, 0xFF, 0x80},
577 {0x75, 0xFF, 0x00},
578 {0x76, 0xFF, 0x00},
579 {0x77, 0xFF, 0x08},
580 {0x78, 0xFF, 0x53},
581 {0x79, 0xFF, 0x3C},
582 {0x7A, 0xFF, 0x89},
583 {0x7B, 0xFF, 0x3E},
584 {0x7C, 0xFF, 0x00},
585 {0x7D, 0xFF, 0x08},
586 {0x7E, 0xFF, 0x51},
587 {0x7F, 0xFF, 0x0C},
588 {0x80, 0xFF, 0x00},
589 {0x81, 0xFF, 0x00},
590 {0x82, 0xFF, 0x00},
591 {0x83, 0xFF, 0x08},
592 {0x84, 0xFF, 0x00},
593 {0x85, 0xFF, 0x00},
594 {0x86, 0xFF, 0x87},
595 {0x87, 0xFF, 0x0E},
596 #endif
597 // 2012/12/20 added by Keming's suggestion test
598 {0x88, 0xF0, 0x00},
599 };
600 static const RegSetEntry HDMITX_SetHDMI_Table[] = {
601
602 ////////////////////////////////////////////////////
603 // Config default HDMI Mode
604 ////////////////////////////////////////////////////
605 {0xC0, 0x01, 0x01},
606 {0xC1, 0x03, 0x03},
607 {0xC6, 0x03, 0x03}
608 };
609
610 static const RegSetEntry HDMITX_SetDVI_Table[] = {
611
612 ////////////////////////////////////////////////////
613 // Config default HDMI Mode
614 ////////////////////////////////////////////////////
615 {0x0F, 0x01, 0x01},
616 {0x58, 0xFF, 0x00},
617 {0x0F, 0x01, 0x00},
618 {0xC0, 0x01, 0x00},
619 {0xC1, 0x03, 0x02},
620 {0xC6, 0x03, 0x00}
621 };
622
623 static const RegSetEntry HDMITX_DefaultAVIInfo_Table[] = {
624
625 ////////////////////////////////////////////////////
626 // Config default avi infoframe
627 ////////////////////////////////////////////////////
628 {0x0F, 0x01, 0x01},
629 {0x58, 0xFF, 0x10},
630 {0x59, 0xFF, 0x08},
631 {0x5A, 0xFF, 0x00},
632 {0x5B, 0xFF, 0x00},
633 {0x5C, 0xFF, 0x00},
634 {0x5D, 0xFF, 0x57},
635 {0x5E, 0xFF, 0x00},
636 {0x5F, 0xFF, 0x00},
637 {0x60, 0xFF, 0x00},
638 {0x61, 0xFF, 0x00},
639 {0x62, 0xFF, 0x00},
640 {0x63, 0xFF, 0x00},
641 {0x64, 0xFF, 0x00},
642 {0x65, 0xFF, 0x00},
643 {0x0F, 0x01, 0x00},
644 {0xCD, 0x03, 0x03}
645 };
646 static const RegSetEntry HDMITX_DeaultAudioInfo_Table[] = {
647
648 ////////////////////////////////////////////////////
649 // Config default audio infoframe
650 ////////////////////////////////////////////////////
651 {0x0F, 0x01, 0x01},
652 {0x68, 0xFF, 0x00},
653 {0x69, 0xFF, 0x00},
654 {0x6A, 0xFF, 0x00},
655 {0x6B, 0xFF, 0x00},
656 {0x6C, 0xFF, 0x00},
657 {0x6D, 0xFF, 0x71},
658 {0x0F, 0x01, 0x00},
659 {0xCE, 0x03, 0x03}
660 };
661
662 static const RegSetEntry HDMITX_Aud_CHStatus_LPCM_20bit_48Khz[] =
663 {
664 {0x0F, 0x01, 0x01},
665 {0x33, 0xFF, 0x00},
666 {0x34, 0xFF, 0x18},
667 {0x35, 0xFF, 0x00},
668 {0x91, 0xFF, 0x00},
669 {0x92, 0xFF, 0x00},
670 {0x93, 0xFF, 0x01},
671 {0x94, 0xFF, 0x00},
672 {0x98, 0xFF, 0x02},
673 {0x99, 0xFF, 0xDA},
674 {0x0F, 0x01, 0x00}
675 } ;
676
677 static const RegSetEntry HDMITX_AUD_SPDIF_2ch_24bit[] =
678 {
679 {0x0F, 0x11, 0x00},
680 {0x04, 0x14, 0x04},
681 {0xE0, 0xFF, 0xD1},
682 {0xE1, 0xFF, 0x01},
683 {0xE2, 0xFF, 0xE4},
684 {0xE3, 0xFF, 0x10},
685 {0xE4, 0xFF, 0x00},
686 {0xE5, 0xFF, 0x00},
687 {0x04, 0x14, 0x00}
688 } ;
689
690 static const RegSetEntry HDMITX_AUD_I2S_2ch_24bit[] =
691 {
692 {0x0F, 0x11, 0x00},
693 {0x04, 0x14, 0x04},
694 {0xE0, 0xFF, 0xC1},
695 {0xE1, 0xFF, 0x01},
696 #ifdef USE_IT66120
697 {0x5A, 0x02, 0x00},
698 {0xE2, 0xFF, 0xFF},
699 #else
700 {0xE2, 0xFF, 0xE4},
701 #endif
702 {0xE3, 0xFF, 0x00},
703 {0xE4, 0xFF, 0x00},
704 {0xE5, 0xFF, 0x00},
705 {0x04, 0x14, 0x00}
706 } ;
707
708 static const RegSetEntry HDMITX_DefaultAudio_Table[] = {
709
710 ////////////////////////////////////////////////////
711 // Config default audio output format.
712 ////////////////////////////////////////////////////
713 {0x0F, 0x21, 0x00},
714 {0x04, 0x14, 0x04},
715 {0xE0, 0xFF, 0xC1},
716 {0xE1, 0xFF, 0x01},
717 #ifdef USE_IT66120
718 {0xE2, 0xFF, 0xFF},
719 #else
720 {0xE2, 0xFF, 0xE4},
721 #endif
722 {0xE3, 0xFF, 0x00},
723 {0xE4, 0xFF, 0x00},
724 {0xE5, 0xFF, 0x00},
725 {0x0F, 0x01, 0x01},
726 {0x33, 0xFF, 0x00},
727 {0x34, 0xFF, 0x18},
728 {0x35, 0xFF, 0x00},
729 {0x91, 0xFF, 0x00},
730 {0x92, 0xFF, 0x00},
731 {0x93, 0xFF, 0x01},
732 {0x94, 0xFF, 0x00},
733 {0x98, 0xFF, 0x02},
734 {0x99, 0xFF, 0xDB},
735 {0x0F, 0x01, 0x00},
736 {0x04, 0x14, 0x00}
737 } ;
738
739 static const RegSetEntry HDMITX_PwrDown_Table[] = {
740 {0x05, 0x60, 0x60},
741 {0xf8, 0xc3},
742 {0xf8, 0xa5},
743 {0xe8, 0x60},
744 {0xE0, 0x0F, 0x00},
745 // Enable GRCLK
746 // #if (IC_VERSION == 0xC0)
747 // {0x0F, 0x40, 0x00},
748 // #else
749 // {0x0F, 0x70, 0x70},// PwrDown RCLK , IACLK ,TXCLK
750 // #endif //#if (IC_VERSION == 0xC0)
751 // PLL Reset
752 {0x61, 0x10, 0x10}, // DRV_RST
753 {0x62, 0x08, 0x00}, // XP_RESETB
754 {0x64, 0x04, 0x00}, // IP_RESETB
755 {0x01, 0x00, 0x00}, // idle(100);
756
757 {0x61, 0x60, 0x60},
758
759 {0x70, 0xFF, 0x00},//hdmitxwr(0x70, 0x00); // Select TXCLK power-down path
760 // PLL PwrDn
761 // {0x61, 0x20, 0x20}, // PwrDn DRV
762 // {0x62, 0x44, 0x44}, // PwrDn XPLL
763 // {0x64, 0x40, 0x40}, // PwrDn IPLL
764
765 // HDMITX PwrDn
766 // {0x05, 0x01, 0x01}, // PwrDn PCLK
767 // {0xE0, 0x0F, 0x00},// hdmitxset(0xE0, 0x0F, 0x00); // PwrDn GIACLK, IACLK
768 // {0x72, 0x03, 0x00},// hdmitxset(0x72, 0x03, 0x00); // PwrDn GTxCLK (QCLK)
769 // {0x0F, 0x78, 0x78}, // PwrDn GRCLK
770 {0x0F, 0x70, 0x70}//Gate RCLK IACLK TXCLK
771 };
772
773 static const RegSetEntry HDMITX_PwrOn_Table[] = {
774 {0x0F, 0x70, 0x00}, // // PwrOn RCLK , IACLK ,TXCLK
775 // {0x0F, 0x78, 0x38}, // PwrOn GRCLK
776 // {0x05, 0x01, 0x00}, // PwrOn PCLK
777
778 // PLL PwrOn
779 {0x61, 0x20, 0x00}, // PwrOn DRV
780 {0x62, 0x44, 0x00}, // PwrOn XPLL
781 {0x64, 0x40, 0x00}, // PwrOn IPLL
782
783 // PLL Reset OFF
784 {0x61, 0x10, 0x00}, // DRV_RST
785 {0x62, 0x08, 0x08}, // XP_RESETB
786 {0x64, 0x04, 0x04} // IP_RESETB
787 // {0x0F, 0x78, 0x08}, // PwrOn IACLK
788 };
789
790 static const RegSetEntry hdmi_tx_pg_1080p60_table[] = {
791 // 1920x1080@60.00Hz VIC = 16
792 {0x0F, 0xFF, 0x00},
793 {0x90, 0xFF, 0x76},
794 {0x91, 0xFF, 0x89},
795 {0x92, 0xFF, 0xC0},
796 {0x93, 0xFF, 0x40},
797 {0x94, 0xFF, 0x80},
798 {0x95, 0xFF, 0x00},
799 {0x96, 0xFF, 0x2C},
800 {0x97, 0xFF, 0x00},
801 {0x98, 0xFF, 0x64},
802 {0x99, 0xFF, 0x04},
803 {0x9A, 0xFF, 0x28},
804 {0x9B, 0xFF, 0x60},
805 {0x9C, 0xFF, 0x40},
806 {0x9D, 0xFF, 0xFF},
807 {0x9E, 0xFF, 0xFF},
808 {0x9F, 0xFF, 0xFF},
809 {0xA0, 0xFF, 0x00},
810 {0xA1, 0xFF, 0x50},
811 {0xA2, 0xFF, 0xFF},
812 {0xA3, 0xFF, 0xFF},
813 {0xA4, 0xFF, 0x4C},
814 {0xA5, 0xFF, 0x04},
815 {0xA6, 0xFF, 0xF0},
816 {0xB1, 0xFF, 0x00},
817 {0xB2, 0xFF, 0x00},
818 {0xA9, 0xFF, 0x70},
819 {0xAA, 0xFF, 0x00},
820 {0xAB, 0xFF, 0x00},
821 {0xAC, 0xFF, 0x00},
822 {0xAF, 0xFF, 0x00},
823 {0xB0, 0xFF, 0x00}
824 };
825
826 static const RegSetEntry hdmi_tx_pg_720p60_table[] = {
827 // PatGen\fmt4_PatGen.c
828 // 1280x720@60.00Hz VIC = 4
829 {0x0F, 0x01, 0x00},
830 {0x90, 0xFF, 0x16},
831 {0x91, 0xFF, 0x67},
832 {0x92, 0xFF, 0x04},
833 {0x93, 0xFF, 0x04},
834 {0x94, 0xFF, 0x61},
835 {0x95, 0xFF, 0x00},
836 {0x96, 0xFF, 0x28},
837 {0x97, 0xFF, 0x00},
838 {0x98, 0xFF, 0xED},
839 {0x99, 0xFF, 0x02},
840 {0x9A, 0xFF, 0x18},
841 {0x9B, 0xFF, 0xE8},
842 {0x9C, 0xFF, 0x20},
843 {0x9D, 0xFF, 0xFF},
844 {0x9E, 0xFF, 0xFF},
845 {0x9F, 0xFF, 0xFF},
846 {0xA0, 0xFF, 0x00},
847 {0xA1, 0xFF, 0x50},
848 {0xA2, 0xFF, 0xFF},
849 {0xA3, 0xFF, 0xFF},
850 {0xA4, 0xFF, 0x39},
851 {0xA5, 0xFF, 0x03},
852 {0xA6, 0xFF, 0xF0},
853 {0xB1, 0xFF, 0x00},
854 {0xB2, 0xFF, 0x00},
855 {0xA9, 0xFF, 0x70},
856 {0xAA, 0xFF, 0x00},
857 {0xAB, 0xFF, 0x00},
858 {0xAC, 0xFF, 0x00},
859 {0xAF, 0xFF, 0x00},
860 {0xB0, 0xFF, 0x00}
861 };
862 static const RegSetEntry hdmi_tx_pg_480p60_table[] = {
863 // PatGen\fmt2_PatGen.c
864 // 720x480@59.94Hz VIC = 2
865 {0x0F, 0x01, 0x00},
866 {0x90, 0xFF, 0x90},
867 {0x91, 0xFF, 0x35},
868 {0x92, 0xFF, 0x7A},
869 {0x93, 0xFF, 0x4A},
870 {0x94, 0xFF, 0x30},
871 {0x95, 0xFF, 0x00},
872 {0x96, 0xFF, 0x3E},
873 {0x97, 0xFF, 0x00},
874 {0x98, 0xFF, 0x0C},
875 {0x99, 0xFF, 0x02},
876 {0x9A, 0xFF, 0x23},
877 {0x9B, 0xFF, 0x03},
878 {0x9C, 0xFF, 0x20},
879 {0x9D, 0xFF, 0x30},
880 {0x9E, 0xFF, 0x10},
881 {0x9F, 0xFF, 0x42},
882 {0xA0, 0xFF, 0x00},
883 {0xA1, 0xFF, 0x60},
884 {0xA2, 0xFF, 0x0D},
885 {0xA3, 0xFF, 0x32},
886 {0xA4, 0xFF, 0xAC},
887 {0xA5, 0xFF, 0x01},
888 {0xA6, 0xFF, 0x10},
889 {0xB1, 0xFF, 0x00},
890 {0xB2, 0xFF, 0x00},
891 // {0xA9, 0xFF, 0x7F},
892 {0xA9, 0xFF, 0x70},
893 {0xAA, 0xFF, 0x00},
894 {0xAB, 0xFF, 0x00},
895 {0xAC, 0xFF, 0x00},
896 {0xAF, 0xFF, 0x00},
897 {0xB0, 0xFF, 0x00}
898 };
899
900 #ifdef DETECT_VSYNC_CHG_IN_SAV
901 static bool EnSavVSync = false ;
902 #endif
903
904 /* Period of hdcp checks (to ensure we're still authenticated) */
905 #define DRM_HDCP_CHECK_PERIOD_MS (128 * 16)
906 #define DRM_HDCP2_CHECK_PERIOD_MS 500
907
908 /* Shared lengths/masks between HDMI/DVI/DisplayPort */
909 #define DRM_HDCP_AN_LEN 8
910 #define DRM_HDCP_BSTATUS_LEN 2
911 #define DRM_HDCP_KSV_LEN 5
912 #define DRM_HDCP_RI_LEN 2
913 #define DRM_HDCP_V_PRIME_PART_LEN 4
914 #define DRM_HDCP_V_PRIME_NUM_PARTS 5
915 #define DRM_HDCP_NUM_DOWNSTREAM(x) (x & 0x7f)
916 #define DRM_HDCP_MAX_CASCADE_EXCEEDED(x) (x & BIT(3))
917 #define DRM_HDCP_MAX_DEVICE_EXCEEDED(x) (x & BIT(7))
918
919 /* Slave address for the HDCP registers in the receiver */
920 #define DRM_HDCP_DDC_ADDR 0x3A
921
922 /* Value to use at the end of the SHA-1 bytestream used for repeaters */
923 #define DRM_HDCP_SHA1_TERMINATOR 0x80
924
925 /* HDCP register offsets for HDMI/DVI devices */
926 #define DRM_HDCP_DDC_BKSV 0x00
927 #define DRM_HDCP_DDC_RI_PRIME 0x08
928 #define DRM_HDCP_DDC_AKSV 0x10
929 #define DRM_HDCP_DDC_AN 0x18
930 #define DRM_HDCP_DDC_V_PRIME(h) (0x20 + h * 4)
931 #define DRM_HDCP_DDC_BCAPS 0x40
932 #define DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT BIT(6)
933 #define DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY BIT(5)
934 #define DRM_HDCP_DDC_BSTATUS 0x41
935 #define DRM_HDCP_DDC_KSV_FIFO 0x43
936
937 #define MAX_HDCP_DOWN_STREAM_COUNT 10
938 #define HDCP_SHA1_FIFO_LEN (MAX_HDCP_DOWN_STREAM_COUNT * 5 + 10)
939 #define HDMI_TX_HDCP_RETRY 3
940 #define HDMI_TX_PCLK_DIV2 false
941
942 #ifndef __linux__
943
944 extern const struct drm_display_mode edid_cea_modes[];
945
946 #endif
947
948 struct it6161 {
949 struct device *dev;
950 struct drm_bridge bridge;
951 struct i2c_client *i2c_mipi_rx;
952 struct i2c_client *i2c_hdmi_tx;
953 struct i2c_client *i2c_cec;
954 struct edid *edid;
955 struct drm_connector connector;
956 struct mutex mode_lock;
957 struct regmap *regmap_mipi_rx;
958 struct regmap *regmap_hdmi_tx;
959 struct regmap *regmap_cec;
960 u32 it6161_addr_hdmi_tx;
961 u32 it6161_addr_cec;
962 struct device_node *host_node;
963 struct mipi_dsi_device *dsi;
964 struct completion wait_hdcp_event;
965 struct completion wait_edid_complete;
966 struct delayed_work hdcp_work;
967 struct work_struct wait_hdcp_ksv_list;
968 u8 hdmi_tx_hdcp_retry;
969 /* kHz */
970 u32 hdmi_tx_rclk;
971 /* kHz */
972 u32 hdmi_tx_pclk;
973 /* kHz */
974 u32 mipi_rx_mclk;
975 /* kHz */
976 u32 mipi_rx_rclk;
977 /* kHz */
978 u32 mipi_rx_pclk;
979 struct drm_display_mode mipi_rx_p_display_mode;
980 struct drm_display_mode hdmi_tx_display_mode;
981 struct drm_display_mode source_display_mode;
982 struct hdmi_avi_infoframe source_avi_infoframe;
983 u32 vic;
984 u8 mipi_rx_lane_count;
985 bool is_repeater;
986 u8 hdcp_downstream_count;
987 u8 bksv[DRM_HDCP_KSV_LEN];
988 u8 sha1_transform_input[HDCP_SHA1_FIFO_LEN];
989 u16 bstatus;
990 bool enable_drv_hold;
991 u8 hdmi_tx_output_color_space;
992 u8 hdmi_tx_input_color_space;
993 u8 hdmi_tx_mode;
994 u8 support_audio;
995
996 u8 bOutputAudioMode;
997 u8 bAudioChannelSwap;
998 u8 bAudioChannelEnable;
999 u8 bAudFs ;
1000 u32 TMDSClock ;
1001 u32 RCLK ;
1002 #ifdef _SUPPORT_HDCP_REPEATER_
1003 HDMITX_HDCP_State TxHDCP_State ;
1004 u16 usHDCPTimeOut ;
1005 u16 Tx_BStatus ;
1006 #endif
1007 u8 bAuthenticated:1 ;
1008 bool hdmi_mode;
1009 u8 bAudInterface;
1010
1011 struct gpio_desc *reset_gpio;
1012 struct gpio_desc *enable_gpio;
1013 struct gpio_desc *test_gpio;
1014
1015 struct timer_list timer;
1016 struct delayed_work restart;
1017 };
1018
1019 static struct it6161 *it6161;
1020 //static struct it6161 *it6161_dump;
1021 static struct drm_bridge *it6161_bridge;
1022
1023 static const struct regmap_range it6161_mipi_rx_bridge_volatile_ranges[] = {
1024 { .range_min = 0, .range_max = 0xFF },
1025 };
1026
1027 static const struct regmap_access_table it6161_mipi_rx_bridge_volatile_table = {
1028 .yes_ranges = it6161_mipi_rx_bridge_volatile_ranges,
1029 .n_yes_ranges = ARRAY_SIZE(it6161_mipi_rx_bridge_volatile_ranges),
1030 };
1031
1032 static const struct regmap_config it6161_mipi_rx_bridge_regmap_config = {
1033 .reg_bits = 8,
1034 .val_bits = 8,
1035 .volatile_table = &it6161_mipi_rx_bridge_volatile_table,
1036 .cache_type = REGCACHE_NONE,
1037 };
1038
1039 static const struct regmap_range it6161_hdmi_tx_bridge_volatile_ranges[] = {
1040 { .range_min = 0, .range_max = 0xFF },
1041 };
1042
1043 static const struct regmap_access_table it6161_hdmi_tx_bridge_volatile_table = {
1044 .yes_ranges = it6161_hdmi_tx_bridge_volatile_ranges,
1045 .n_yes_ranges = ARRAY_SIZE(it6161_hdmi_tx_bridge_volatile_ranges),
1046 };
1047
1048 static const struct regmap_config it6161_hdmi_tx_bridge_regmap_config = {
1049 .reg_bits = 8,
1050 .val_bits = 8,
1051 .volatile_table = &it6161_hdmi_tx_bridge_volatile_table,
1052 .cache_type = REGCACHE_NONE,
1053 };
1054
1055 static const struct regmap_range it6161_cec_bridge_volatile_ranges[] = {
1056 { .range_min = 0, .range_max = 0xFF },
1057 };
1058
1059 static const struct regmap_access_table it6161_cec_bridge_volatile_table = {
1060 .yes_ranges = it6161_cec_bridge_volatile_ranges,
1061 .n_yes_ranges = ARRAY_SIZE(it6161_cec_bridge_volatile_ranges),
1062 };
1063
1064 static const struct regmap_config it6161_cec_bridge_regmap_config = {
1065 .reg_bits = 8,
1066 .val_bits = 8,
1067 .volatile_table = &it6161_cec_bridge_volatile_table,
1068 .cache_type = REGCACHE_NONE,
1069 };
1070
it6161_mipi_rx_read(struct it6161 * it6161,unsigned int reg_addr)1071 static int it6161_mipi_rx_read(struct it6161 *it6161, unsigned int reg_addr)
1072 {
1073 unsigned int value;
1074 int err;
1075 struct device *dev = &it6161->i2c_mipi_rx->dev;
1076
1077 err = regmap_read(it6161->regmap_mipi_rx, reg_addr, &value);
1078 if (err < 0) {
1079 DRM_DEV_ERROR(dev, "mipi rx read failed reg[0x%x] err: %d", reg_addr,
1080 err);
1081 return err;
1082 }
1083
1084 return value;
1085 }
1086
mipi_rx_read_word(struct it6161 * it6161,unsigned int reg)1087 static int mipi_rx_read_word(struct it6161 *it6161, unsigned int reg)
1088 {
1089 int val_0, val_1;
1090
1091 val_0 = it6161_mipi_rx_read(it6161, reg);
1092
1093 if (val_0 < 0)
1094 return val_0;
1095
1096 val_1 = it6161_mipi_rx_read(it6161, reg + 1);
1097
1098 if (val_1 < 0)
1099 return val_1;
1100
1101 return (val_1 << 8) | val_0;
1102 }
1103
it6161_mipi_rx_write(struct it6161 * it6161,unsigned int reg_addr,unsigned int reg_val)1104 static int it6161_mipi_rx_write(struct it6161 *it6161, unsigned int reg_addr,
1105 unsigned int reg_val)
1106 {
1107 int err;
1108 struct device *dev = &it6161->i2c_mipi_rx->dev;
1109
1110 err = regmap_write(it6161->regmap_mipi_rx, reg_addr, reg_val);
1111
1112 if (err < 0) {
1113 DRM_DEV_ERROR(dev, "mipi rx write failed reg[0x%x] = 0x%x err = %d",
1114 reg_addr, reg_val, err);
1115 return err;
1116 }
1117
1118 return 0;
1119 }
1120
it6161_mipi_rx_set_bits(struct it6161 * it6161,unsigned int reg,unsigned int mask,unsigned int value)1121 static int it6161_mipi_rx_set_bits(struct it6161 *it6161, unsigned int reg,
1122 unsigned int mask, unsigned int value)
1123 {
1124 int err;
1125 struct device *dev = &it6161->i2c_mipi_rx->dev;
1126
1127 err = regmap_update_bits(it6161->regmap_mipi_rx, reg, mask, value);
1128 if (err < 0) {
1129 DRM_DEV_ERROR(
1130 dev, "mipi rx set reg[0x%x] = 0x%x mask = 0x%x failed err %d",
1131 reg, value, mask, err);
1132 return err;
1133 }
1134
1135 return 0;
1136 }
1137
1138 #if 0
1139 static void it6161_mipi_rx_dump(struct it6161 *it6161)
1140 {
1141 unsigned int i, j;
1142 u8 regs[16];
1143 //struct device *dev = &it6161->i2c_mipi_rx->dev;
1144
1145 it6161_debug("mipi rx dump:");
1146 for (i = 0; i <= 0xff; i += 16) {
1147 for (j = 0; j < 16; j++)
1148 regs[j] = it6161_mipi_rx_read(it6161, i + j);
1149
1150 it6161_debug("[0x%02x] = %16ph", i, regs);
1151 }
1152 }
1153 #endif
1154
it6161_hdmi_tx_read(struct it6161 * it6161,unsigned int reg_addr)1155 static int it6161_hdmi_tx_read(struct it6161 *it6161, unsigned int reg_addr)
1156 {
1157 unsigned int value;
1158 int err;
1159 struct device *dev = &it6161->i2c_mipi_rx->dev;
1160
1161 err = regmap_read(it6161->regmap_hdmi_tx, reg_addr, &value);
1162 if (err < 0) {
1163 DRM_DEV_ERROR(dev, "hdmi tx read failed reg[0x%x] err: %d", reg_addr,
1164 err);
1165 return err;
1166 }
1167
1168 return value;
1169 }
1170
hdmi_tx_read_word(struct it6161 * it6161,unsigned int reg)1171 static int hdmi_tx_read_word(struct it6161 *it6161, unsigned int reg)
1172 {
1173 int val_0, val_1;
1174
1175 val_0 = it6161_hdmi_tx_read(it6161, reg);
1176
1177 if (val_0 < 0)
1178 return val_0;
1179
1180 val_1 = it6161_hdmi_tx_read(it6161, reg + 1);
1181
1182 if (val_1 < 0)
1183 return val_1;
1184
1185 return (val_1 << 8) | val_0;
1186 }
1187
1188 #ifdef HDCP
it6161_hdmi_tx_burst_read(struct it6161 * it6161,unsigned int reg_addr,void * buffer,size_t size)1189 static int it6161_hdmi_tx_burst_read(struct it6161 *it6161, unsigned int reg_addr, void *buffer, size_t size)
1190 {
1191 struct device *dev = &it6161->i2c_mipi_rx->dev;
1192 int ret;
1193
1194 ret = regmap_bulk_read(it6161->regmap_hdmi_tx, reg_addr, buffer, size);
1195 if (ret < 0)
1196 DRM_DEV_ERROR(dev, "hdmi tx burst read failed reg[0x%x] ret: %d",
1197 reg_addr, ret);
1198
1199 return ret;
1200 }
1201 #endif
it6161_hdmi_tx_write(struct it6161 * it6161,unsigned int reg_addr,unsigned int reg_val)1202 static int it6161_hdmi_tx_write(struct it6161 *it6161, unsigned int reg_addr,
1203 unsigned int reg_val)
1204 {
1205 struct device *dev = &it6161->i2c_mipi_rx->dev;
1206 int err;
1207
1208 err = regmap_write(it6161->regmap_hdmi_tx, reg_addr, reg_val);
1209
1210 if (err < 0) {
1211 DRM_DEV_ERROR(dev, "hdmi tx write failed reg[0x%x] = 0x%x err = %d",
1212 reg_addr, reg_val, err);
1213 return err;
1214 }
1215
1216 return 0;
1217 }
1218
1219 #if 0
1220 static int hdmi_tx_burst_write(struct it6161 *it6161, unsigned int reg_addr,
1221 void *buffer, size_t size)
1222 {
1223 struct device *dev = &it6161->i2c_hdmi_tx->dev;
1224 int ret;
1225
1226 ret = regmap_bulk_write(it6161->regmap_hdmi_tx, reg_addr,
1227 (u8 *)buffer, size);
1228
1229 if (ret < 0) {
1230 DRM_DEV_ERROR(dev, "hdmi tx burst write failed reg[0x%x] ret = %d",
1231 reg_addr, ret);
1232 return ret;
1233 }
1234
1235 return ret;
1236 }
1237 #endif
1238
it6161_hdmi_tx_set_bits(struct it6161 * it6161,unsigned int reg,unsigned int mask,unsigned int value)1239 static int it6161_hdmi_tx_set_bits(struct it6161 *it6161, unsigned int reg,
1240 unsigned int mask, unsigned int value)
1241 {
1242 int err;
1243 struct device *dev = &it6161->i2c_mipi_rx->dev;
1244
1245 err = regmap_update_bits(it6161->regmap_hdmi_tx, reg, mask, value);
1246 if (err < 0) {
1247 DRM_DEV_ERROR(
1248 dev, "hdmi tx set reg[0x%x] = 0x%x mask = 0x%x failed err %d",
1249 reg, value, mask, err);
1250 return err;
1251 }
1252
1253 return 0;
1254 }
1255
it6161_hdmi_tx_change_bank(struct it6161 * it6161,int x)1256 static int inline it6161_hdmi_tx_change_bank(struct it6161 *it6161, int x)
1257 {
1258 return it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, x & 0x03);
1259 }
1260
1261 #if 0
1262 static void it6161_hdmi_tx_dump(struct it6161 *it6161, unsigned int bank)
1263 {
1264 unsigned int i, j;
1265 u8 regs[16];
1266 //struct device *dev = &it6161->i2c_mipi_rx->dev;
1267
1268 it6161_debug("hdmi tx dump bank: %d", bank);
1269 it6161_hdmi_tx_change_bank(it6161, bank);
1270
1271 for (i = 0; i <= 0xff; i += 16) {
1272 for (j = 0; j < 16; j++)
1273 regs[j] = it6161_hdmi_tx_read(it6161, i + j);
1274
1275 it6161_debug("[0x%02x] = %16ph", i, regs);
1276 }
1277 }
1278 #endif
1279
it6161_cec_read(struct it6161 * it6161,unsigned int reg_addr)1280 static int it6161_cec_read(struct it6161 *it6161, unsigned int reg_addr)
1281 {
1282 unsigned int value;
1283 int err;
1284 struct device *dev = &it6161->i2c_mipi_rx->dev;
1285
1286 err = regmap_read(it6161->regmap_cec, reg_addr, &value);
1287 if (err < 0) {
1288 DRM_DEV_ERROR(dev, "cec read failed reg[0x%x] err: %d", reg_addr,
1289 err);
1290 return err;
1291 }
1292
1293 return value;
1294 }
1295
it6161_cec_write(struct it6161 * it6161,unsigned int reg_addr,unsigned int reg_val)1296 static int it6161_cec_write(struct it6161 *it6161, unsigned int reg_addr,
1297 unsigned int reg_val)
1298 {
1299 int err;
1300 struct device *dev = &it6161->i2c_mipi_rx->dev;
1301
1302 err = regmap_write(it6161->regmap_cec, reg_addr, reg_val);
1303
1304 if (err < 0) {
1305 DRM_DEV_ERROR(dev, "cec write failed reg[0x%x] = 0x%x err = %d",
1306 reg_addr, reg_val, err);
1307 return err;
1308 }
1309
1310 return 0;
1311 }
1312
1313 #if 0
1314 static int it6161_cec_set_bits(struct it6161 *it6161, unsigned int reg,
1315 unsigned int mask, unsigned int value)
1316 {
1317 int err;
1318 struct device *dev = &it6161->i2c_mipi_rx->dev;
1319
1320 err = regmap_update_bits(it6161->regmap_cec, reg, mask, value);
1321 if (err < 0) {
1322 DRM_DEV_ERROR(
1323 dev, "cec set reg[0x%x] = 0x%x mask = 0x%x failed err %d",
1324 reg, value, mask, err);
1325 return err;
1326 }
1327
1328 return 0;
1329 }
1330 #endif
1331
connector_to_it6161(struct drm_connector * c)1332 static inline struct it6161 *connector_to_it6161(struct drm_connector *c)
1333 {
1334 return container_of(c, struct it6161, connector);
1335 }
1336
bridge_to_it6161(struct drm_bridge * bridge)1337 static inline struct it6161 *bridge_to_it6161(struct drm_bridge *bridge)
1338 {
1339 return container_of(bridge, struct it6161, bridge);
1340 }
1341
mipi_rx_logic_reset(struct it6161 * it6161)1342 static void mipi_rx_logic_reset(struct it6161 *it6161)
1343 {
1344 it6161_mipi_rx_set_bits(it6161, 0x05, 0x08, 0x08);
1345 }
1346
mipi_rx_logic_reset_release(struct it6161 * it6161)1347 static void mipi_rx_logic_reset_release(struct it6161 *it6161)
1348 {
1349 it6161_mipi_rx_set_bits(it6161, 0x05, 0x08, 0x00);
1350 }
1351
hdmi_tx_logic_reset(struct it6161 * it6161)1352 static void hdmi_tx_logic_reset(struct it6161 *it6161)
1353 {
1354 it6161_hdmi_tx_set_bits(it6161, 0x04, 0x20, 0x20);
1355 }
1356
it6161_mipi_rx_int_mask_disable(struct it6161 * it6161)1357 static void it6161_mipi_rx_int_mask_disable(struct it6161 *it6161)
1358 {
1359 it6161_mipi_rx_set_bits(it6161, 0x0F, 0x03, 0x00);
1360 it6161_mipi_rx_write(it6161, 0x09, 0x00);
1361 it6161_mipi_rx_write(it6161, 0x0A, 0x00);
1362 it6161_mipi_rx_write(it6161, 0x0B, 0x00);
1363 }
1364
it6161_mipi_rx_int_mask_enable(struct it6161 * it6161)1365 static void it6161_mipi_rx_int_mask_enable(struct it6161 *it6161)
1366 {
1367 it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, 0x00);
1368 it6161_mipi_rx_write(it6161, 0x09, EnMBPM ? 0x11 : 0xBF);
1369 it6161_mipi_rx_write(it6161, 0x0A, 0xFF);
1370 it6161_mipi_rx_write(it6161, 0x0B, 0x3F);
1371 }
1372
hdmi_tx_hdcp_int_mask_disable(struct it6161 * it6161)1373 static void hdmi_tx_hdcp_int_mask_disable(struct it6161 *it6161)
1374 {
1375 it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, 0x00);
1376 it6161_hdmi_tx_set_bits(it6161, REG_TX_INT_MASK2, B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK, B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK);
1377 }
1378
1379 #ifdef HDCP
hdmi_tx_hdcp_int_mask_enable(struct it6161 * it6161)1380 static void hdmi_tx_hdcp_int_mask_enable(struct it6161 *it6161)
1381 {
1382 it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, 0x00);
1383 it6161_hdmi_tx_set_bits(it6161, REG_TX_INT_MASK2, B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK, ~(B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK));
1384 }
1385 #endif
1386 /*
1387 static void it6161_hdmi_tx_int_mask_disable(struct it6161 *it6161)
1388 {
1389 it6161_mipi_rx_set_bits(it6161, 0x0F, 0x03, 0x00);
1390 it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK1, 0xFF);
1391 it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK2, 0xFF);
1392 it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK3, 0xFF);
1393 }
1394 */
it6161_hdmi_tx_int_mask_enable(struct it6161 * it6161)1395 static void it6161_hdmi_tx_int_mask_enable(struct it6161 *it6161)
1396 {
1397 it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, 0x00);
1398 it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK1, ~(B_TX_AUDIO_OVFLW_MASK | B_TX_DDC_FIFO_ERR_MASK | B_TX_DDC_BUS_HANG_MASK | B_TX_HPD_MASK | B_TX_RXSEN_MASK));//0x7C);
1399 it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK2, ~(B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK | B_TX_PKT_VID_UNSTABLE_MASK));
1400 it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK3, ~B_TX_VIDSTABLE_MASK);
1401 }
1402
it6161_hdmi_tx_write_table(struct it6161 * it6161,const RegSetEntry table[],int size)1403 static void it6161_hdmi_tx_write_table(struct it6161 *it6161, const RegSetEntry table[], int size)
1404 {
1405 int i ;
1406
1407 for (i = 0; i < size; i++) {
1408 if (table[i].mask == 0 && table[i].value == 0) {
1409 msleep(table[i].offset);
1410 } else if (table[i].mask == 0xFF) {
1411 it6161_hdmi_tx_write(it6161, table[i].offset,
1412 table[i].value);
1413 } else {
1414 it6161_hdmi_tx_set_bits(it6161, table[i].offset, table[i].mask,
1415 table[i].value);
1416 }
1417 }
1418 }
1419
hdmi_tx_enable_pattern_generator(struct it6161 * it6161)1420 static inline void hdmi_tx_enable_pattern_generator(struct it6161 *it6161)
1421 {
1422 it6161_debug("enable pattern generator");
1423 it6161_hdmi_tx_set_bits(it6161, 0xA8, 0x01, 0x01);
1424 }
1425
hdmi_tx_disable_pattern_generator(struct it6161 * it6161)1426 static inline void hdmi_tx_disable_pattern_generator(struct it6161 *it6161)
1427 {
1428 it6161_hdmi_tx_set_bits(it6161, 0xA8, 0x01, 0x00);
1429 }
1430
hdmi_tx_pattern_generator_setup_color(struct it6161 * it6161)1431 static inline void hdmi_tx_pattern_generator_setup_color(struct it6161 *it6161)
1432 {
1433 it6161_hdmi_tx_set_bits(it6161, 0xA9, 0x3F, (HDMI_TX_PATTERN_COLLOR_B << 4) | (HDMI_TX_PATTERN_COLLOR_G << 2) | HDMI_TX_PATTERN_COLLOR_R);
1434 }
1435
hdmi_tx_setup_pattern_generator(struct it6161 * it6161)1436 static void hdmi_tx_setup_pattern_generator(struct it6161 *it6161)
1437 {
1438 switch (HDMI_TX_PATTERN_GENERATOR_FORMAT) {
1439 case 2:
1440 it6161_hdmi_tx_write_table(it6161, hdmi_tx_pg_480p60_table, sizeof(hdmi_tx_pg_480p60_table) / sizeof(RegSetEntry));
1441 DRM_INFO("use 480p60 pattern");
1442 break;
1443
1444 case 4:
1445 it6161_hdmi_tx_write_table(it6161, hdmi_tx_pg_720p60_table, sizeof(hdmi_tx_pg_720p60_table) / sizeof(RegSetEntry));
1446 DRM_INFO("use 720p60 pattern");
1447 break;
1448
1449 case 16:
1450 it6161_hdmi_tx_write_table(it6161, hdmi_tx_pg_1080p60_table, sizeof(hdmi_tx_pg_1080p60_table) / sizeof(RegSetEntry));
1451 DRM_INFO("use 1080p60 pattern");
1452 break;
1453
1454 default:
1455 it6161_hdmi_tx_write_table(it6161, hdmi_tx_pg_1080p60_table, sizeof(hdmi_tx_pg_1080p60_table) / sizeof(RegSetEntry));
1456 DRM_INFO("other format, will use 1080p60 pattern");
1457 }
1458
1459 hdmi_tx_pattern_generator_setup_color(it6161);
1460 hdmi_tx_enable_pattern_generator(it6161);
1461 }
1462
show_display_mode(struct it6161 * it6161,struct drm_display_mode * display_mode,u8 select)1463 static void show_display_mode(struct it6161 *it6161, struct drm_display_mode *display_mode, u8 select)
1464 {
1465 char *name[3] = { "source output", "it6161 hdmi tx receive", "mipi rx p receive" };
1466
1467 DRM_INFO("%s timing:", name[select]);
1468 DRM_INFO("timing name:%s", display_mode->name);
1469 DRM_INFO("clock = %dkHz", display_mode->clock);
1470 DRM_INFO("htotal = %d", display_mode->htotal);
1471 DRM_INFO("hactive = %d", display_mode->hdisplay);
1472 DRM_INFO("hfront_porch = %d", display_mode->hsync_start - display_mode->hdisplay);
1473 DRM_INFO("hsyncw = %d", display_mode->hsync_end - display_mode->hsync_start);
1474 DRM_INFO("hback_porch = %d", display_mode->htotal - display_mode->hsync_end);
1475
1476 DRM_INFO("vtotal = %d", display_mode->vtotal);
1477 DRM_INFO("vactive = %d", display_mode->vdisplay);
1478 DRM_INFO("vfront_porch = %d", display_mode->vsync_start - display_mode->vdisplay);
1479 DRM_INFO("vsyncw = %d", display_mode->vsync_end - display_mode->vsync_start);
1480 DRM_INFO("vback_porch = %d", display_mode->vtotal - display_mode->vsync_end);
1481 DRM_INFO("drm_display_mode flags = 0x%04x", display_mode->flags);
1482
1483 }
1484
it6161_set_interrupts_active_level(enum it6161_active_level level)1485 static void inline it6161_set_interrupts_active_level(enum it6161_active_level level)
1486 {
1487 it6161_mipi_rx_set_bits(it6161, 0x0D, 0x02, level == HIGH ? 0x02 : 0x00);
1488 it6161_hdmi_tx_set_bits(it6161, 0x05, 0xC0, level == HIGH ? 0x80 : 0x40);
1489 }
1490
hdmi_tx_init(struct it6161 * it6161)1491 static void hdmi_tx_init(struct it6161 *it6161)
1492 {
1493 it6161_debug("init hdmi tx");
1494
1495 it6161_hdmi_tx_write_table(it6161, HDMITX_Init_Table, ARRAY_SIZE(HDMITX_Init_Table));
1496 it6161_hdmi_tx_write_table(it6161, HDMITX_PwrOn_Table, ARRAY_SIZE(HDMITX_PwrOn_Table));
1497 it6161_hdmi_tx_write_table(it6161, HDMITX_DefaultVideo_Table, ARRAY_SIZE(HDMITX_DefaultVideo_Table));
1498 it6161_hdmi_tx_write_table(it6161, HDMITX_SetHDMI_Table, ARRAY_SIZE(HDMITX_SetHDMI_Table));
1499 it6161_hdmi_tx_write_table(it6161, HDMITX_DefaultAVIInfo_Table, ARRAY_SIZE(HDMITX_DefaultAVIInfo_Table));
1500 it6161_hdmi_tx_write_table(it6161, HDMITX_DeaultAudioInfo_Table, ARRAY_SIZE(HDMITX_DeaultAudioInfo_Table));
1501 it6161_hdmi_tx_write_table(it6161, HDMITX_Aud_CHStatus_LPCM_20bit_48Khz, ARRAY_SIZE(HDMITX_Aud_CHStatus_LPCM_20bit_48Khz));
1502 it6161_hdmi_tx_write_table(it6161, HDMITX_AUD_SPDIF_2ch_24bit, ARRAY_SIZE(HDMITX_AUD_SPDIF_2ch_24bit));
1503
1504 #ifdef SUPPORT_CEC
1505 it6161_hdmi_tx_change_bank(it6161, 0);
1506 it6161_hdmi_tx_set_bits(it6161, 0x8D, 0x01, 0x01);//it6161_hdmi_tx_write(it6161, 0xf, 0 ); //pet
1507
1508 Initial_Ext_Int1();
1509 HDMITX_CEC_Init();
1510 #endif // SUPPORT_CEC
1511 }
1512
mipi_rx_get_m_video_stable(struct it6161 * it6161)1513 static bool mipi_rx_get_m_video_stable(struct it6161 *it6161)
1514 {
1515 return !!(it6161_mipi_rx_read(it6161, 0x0D) & 0x10);
1516 }
1517
mipi_rx_get_p_video_stable(struct it6161 * it6161)1518 static bool mipi_rx_get_p_video_stable(struct it6161 *it6161)
1519 {
1520 return !!(it6161_mipi_rx_read(it6161, 0x0D) & 0x20);
1521 }
1522
mipi_rx_setup_polarity(struct it6161 * it6161)1523 static void mipi_rx_setup_polarity(struct it6161 *it6161)
1524 {
1525 struct drm_display_mode *display_mode = &it6161->source_display_mode;
1526 u8 polarity;
1527
1528 polarity = ((display_mode->flags & DRM_MODE_FLAG_PHSYNC) == DRM_MODE_FLAG_PHSYNC) ? 0x01 : 0x00;
1529 polarity |= ((display_mode->flags & DRM_MODE_FLAG_PVSYNC) == DRM_MODE_FLAG_PVSYNC) ? 0x02 : 0x00;
1530
1531 it6161_mipi_rx_set_bits(it6161, 0x4E, 0x03, polarity);
1532 }
1533
mipi_rx_afe_configuration(struct it6161 * it6161,u8 data_id)1534 static void mipi_rx_afe_configuration(struct it6161 *it6161, u8 data_id)
1535 {
1536 //struct device *dev = &it6161->i2c_mipi_rx->dev;
1537 u8 MPLaneNum = (it6161->mipi_rx_lane_count - 1);
1538
1539 it6161_debug("afe configuration data_id:0x%02x", data_id);
1540
1541 if (data_id == RGB_18b) {
1542 if( MPLaneNum==3 ) {
1543 // if( EnMPx1PCLK )
1544 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x02); // MPPCLKSel = 1; // 4-lane : MCLK = 1/1 PCLK
1545 // else
1546 // {
1547 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x02); // MPPCLKSel = 1; // 4-lane : MCLK = 1/1 PCLK
1548 DRM_INFO("Solomon is impossible TXPLL= 9/2 PCLK !!! \n");
1549 DRM_INFO("MCLK=3/4PCLK Change to MCLK=PCLK ...\n");
1550 // }
1551 } else if( MPLaneNum==1 ) {
1552 // if( EnMPx1PCLK )
1553 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x05); // MPPCLKSel = 6; // 2-lane : MCLK = 1/1 PCLK
1554 // else
1555 // {
1556 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x05); // MPPCLKSel = 6; // 2-lane : MCLK = 1/1 PCLK
1557 DRM_INFO("IT6121 is impossible RXPLL= 2/9 PCLK !!! \n");
1558 DRM_INFO("MCLK=3/4PCLK Change to MCLK=PCLK ...\n");
1559 // }
1560 } else if( MPLaneNum==0 ) {
1561 // if( EnMPx1PCLK )
1562 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x0b);// MPPCLKSel = 7; // 1-lane : MCLK = 1/1 PCLK
1563 // else
1564 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x08); // MPPCLKSel = 8; // 1-lane : MCLK = 3/4 PCLK
1565 }
1566 } else {
1567 if( MPLaneNum==3 ) {
1568 // if( EnMPx1PCLK )
1569 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x03);// MPPCLKSel = 0; // 4-lane : MCLK = 1/1 PCLK
1570 // else
1571 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x02);// MPPCLKSel = 1; // 4-lane : MCLK = 3/4 PCLK
1572 } else if( MPLaneNum==1 ) {
1573 // if( EnMPx1PCLK )
1574 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x07); // MPPCLKSel = 2; // 2-lane : MCLK = 1/1 PCLK
1575 // else
1576 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x05); // MPPCLKSel = 3; // 2-lane : MCLK = 3/4 PCLK
1577 } else if( MPLaneNum==0 ) {
1578 // if( EnMPx1PCLK )
1579 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x0f);// MPPCLKSel = 4; // 1-lane : MCLK = 1/1 PCLK
1580 // else
1581 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x0b); // MPPCLKSel = 5; // 1-lane : MCLK = 3/4 PCLK
1582 }
1583 }
1584 }
1585
mipi_rx_configuration(struct it6161 * it6161)1586 static void mipi_rx_configuration(struct it6161 *it6161)
1587 {
1588 //struct device *dev = &it6161->i2c_mipi_rx->dev;
1589 u8 mipi_lane_config = (it6161->mipi_rx_lane_count - 1);
1590
1591 //20200211 D0
1592 it6161_mipi_rx_set_bits(it6161, 0x10, 0x0F, 0x0F);
1593 msleep(1);//idle(100);
1594 it6161_mipi_rx_set_bits(it6161, 0x10, 0x0F, 0x00);
1595
1596 // MPRX Software Reset
1597 // it6161_mipi_rx_set_bits(it6161, 0x05, 0x07, 0x07);
1598 // msleep(1);
1599 // it6161_mipi_rx_set_bits(it6161, 0x05, 0x08, 0x08);
1600 mipi_rx_logic_reset(it6161);
1601 msleep(1);
1602 mipi_rx_logic_reset_release(it6161);
1603
1604 it6161_mipi_rx_int_mask_disable(it6161);
1605
1606 /* setup INT pin: active low */
1607 it6161_mipi_rx_set_bits(it6161, 0x0d, 0x02, 0x00);
1608
1609 it6161_mipi_rx_set_bits(it6161, 0x0C, 0x0F, (MPLaneSwap<<3) + (MPPNSwap<<2) + mipi_lane_config);
1610
1611 it6161_mipi_rx_set_bits(it6161, 0x11, 0x3F, (EnIOIDDQ<<5)+(EnStb2Rst<<4)+(EnExtStdby<<3)+(EnStandby<<2)+(InvPCLK<<1)+InvMCLK);
1612 it6161_mipi_rx_set_bits(it6161, 0x12, 0x03, (PDREFCNT<<1)+PDREFCLK);
1613
1614 it6161_mipi_rx_set_bits(it6161, 0x18, 0xf7, (RegEnSyncErr<<7)+(SkipStg<<4)+HSSetNum);
1615 it6161_mipi_rx_set_bits(it6161, 0x19, 0xf3, (PPIDbgSel<<4)+(EnContCK<<1)+EnDeSkew);
1616 it6161_mipi_rx_set_bits(it6161, 0x20, 0xf7, (EOTPSel<<4)+(RegEnDummyECC<<2)+(RegIgnrBlk<<1)+RegIgnrNull);
1617 it6161_mipi_rx_set_bits(it6161, 0x21, 0x07, LMDbgSel);
1618
1619 // it6161_mipi_rx_set_bits(it6161, 0x44, 0x38, (MREC_Update<<5)+(PREC_Update<<4)+(REGSELDEF<<3));
1620 it6161_mipi_rx_set_bits(it6161, 0x44, 0x3a, (MREC_Update<<5)+(PREC_Update<<4)+(REGSELDEF<<3)+(RegAutoSync<<1));//D0 20200211
1621 it6161_mipi_rx_set_bits(it6161, 0x4B, 0x1f, (EnFReSync<<4)+(EnVREnh<<3)+EnVREnhSel);
1622 it6161_mipi_rx_write(it6161, 0x4C, PPSFFRdStg);
1623 it6161_mipi_rx_set_bits(it6161, 0x4D, 0x01, (PPSFFRdStg>>8)&0x01);
1624 it6161_mipi_rx_set_bits(it6161, 0x4E, 0x0C, (EnVReSync<<3)+(EnHReSync<<2));
1625 it6161_mipi_rx_set_bits(it6161, 0x4F, 0x03, EnFFAutoRst);
1626
1627 //it6161_mipi_rx_write(it6161, 0x27, MPVidType);
1628 it6161_mipi_rx_set_bits(it6161, 0x70, 0x01, EnMAvg);
1629 it6161_mipi_rx_write(it6161, 0x72, MShift);
1630 it6161_mipi_rx_write(it6161, 0x73, PShift);
1631 it6161_mipi_rx_set_bits(it6161, 0x80, 0x20, ENABLE_MIPI_RX_EXTERNAL_CLOCK << 5);
1632 it6161_mipi_rx_write(it6161, 0x21, 0x00); //debug sel
1633 // it6161_mipi_rx_set_bits(it6161, 0x84, 0x70, 0x70); // max swing
1634 // it6161_mipi_rx_set_bits(it6161, 0x84, 0x70, 0x40); // def swing
1635 it6161_mipi_rx_set_bits(it6161, 0x84, 0x70, 0x00); // min swing
1636
1637 it6161_mipi_rx_set_bits(it6161, 0xA0, 0x01, EnMBPM);
1638
1639 /* enable auto detect format */
1640 it6161_mipi_rx_set_bits(it6161, 0x21, 0x08, 0x08);
1641
1642
1643 // if( REGSELDEF == true )
1644 // {
1645 // DRM_INFO("REGSELDEF MODE !!! ...\n");
1646 // PHFP = 0x10;
1647 // PHSW = 0x3e;
1648 // PHBP = 0x3c;
1649 // it6161_mipi_rx_write(it6161, 0x30, PHFP); // HFP
1650 // it6161_mipi_rx_write(it6161, 0x31, 0x80+((PHFP&0x3F00)>>8));
1651 // it6161_mipi_rx_write(it6161, 0x32, PHSW); // HBP
1652 // it6161_mipi_rx_write(it6161, 0x33, 0x80+((PHSW&0x3F00)>>8));
1653 // it6161_mipi_rx_write(it6161, 0x34, PHBP); // HBP
1654 // it6161_mipi_rx_write(it6161, 0x35, 0x80+((PHFP&0x3F00)>>8));
1655 // }
1656
1657 it6161_mipi_rx_set_bits(it6161, 0x70, 0x01, EnMAvg);
1658
1659 it6161_mipi_rx_set_bits(it6161, 0x05, 0x02, 0x02); // Video Clock Domain Reset
1660
1661 if( EnMBPM ) {
1662 //HSW = pSetVTiming->HSyncWidth;
1663 //VSW = pSetVTiming->VSyncWidth;
1664
1665 it6161_mipi_rx_write(it6161, 0xA1, 0x00); // HRS offset
1666 it6161_mipi_rx_write(it6161, 0xA2, 0x00); // VRS offset
1667
1668 // it6161_mipi_rx_write(it6161, 0xA3, 44);//HSW); // HSW
1669 // it6161_mipi_rx_write(it6161, 0xA5, 5);//VSW); // VSW
1670 it6161_mipi_rx_write(it6161, 0xA3, 0x08);//0x10); // HSW
1671 it6161_mipi_rx_write(it6161, 0xA5, 0x04); // VSw
1672
1673 // it6161_hdmi_tx_set_bits(it6161, 0xa9, 0xc0, (EnTBPM<<7)/* + (EnTxPatMux<<6)*/);
1674 // it6161_hdmi_tx_set_bits(it6161, 0xbf, 0x80, (NRTXRCLK<<7));
1675 }
1676 if( MPForceStb == true ){
1677 // mprxwr(0x30, HFP); // HSP
1678 // mprxwr(0x31, 0x80+((HFP&0x3F00)>>8));
1679 // mprxwr(0x32, HSW); // HSW
1680 // mprxwr(0x33, 0x80+((HSW&0x3F00)>>8));
1681 // mprxwr(0x34, HBP&0xFF); // HBP
1682 // mprxwr(0x35, 0x80+((HBP&0x3F00)>>8));
1683 // mprxwr(0x36, HDEW&0xFF); // HDEW
1684 // mprxwr(0x37, 0x80+((HDEW&0x3F00)>>8));
1685 // mprxwr(0x38, HVR2nd&0xFF); // HVR2nd
1686 // mprxwr(0x39, 0x80+((HVR2nd&0x3F00)>>8));
1687
1688 // mprxwr(0x3A, VFP); // VSP
1689 // mprxwr(0x3B, 0x80+((VFP&0x3F00)>>8));
1690 // mprxwr(0x3C, VSW); // VSW
1691 // mprxwr(0x3D, 0x80+((VSW&0x3F00)>>8));
1692 // mprxwr(0x3E, VBP&0xFF); // VBP
1693 // mprxwr(0x3F, 0x80+((VBP&0x3F00)>>8));
1694 // mprxwr(0x40, VDEW&0xFF); // VDEW
1695 // mprxwr(0x41, 0x80+((VDEW&0x3F00)>>8));
1696 // mprxwr(0x42, VFP2nd&0xFF); // VFP2nd
1697 // mprxwr(0x43, 0x80+((VFP2nd&0x3F00)>>8));
1698
1699 // mprxset(0x4e, 0x03, 0xC0+(VPol<<1)+HPol);
1700 }
1701 else
1702 {
1703 if( REGSELDEF == false ) {
1704 it6161_mipi_rx_set_bits(it6161, 0x31, 0x80, 0x00);
1705 it6161_mipi_rx_set_bits(it6161, 0x33, 0x80, 0x00);
1706 it6161_mipi_rx_set_bits(it6161, 0x35, 0x80, 0x00);
1707 it6161_mipi_rx_set_bits(it6161, 0x37, 0x80, 0x00);
1708 it6161_mipi_rx_set_bits(it6161, 0x39, 0x80, 0x00);
1709 it6161_mipi_rx_set_bits(it6161, 0x3A, 0x80, 0x00);
1710 it6161_mipi_rx_set_bits(it6161, 0x3C, 0x80, 0x00);
1711 it6161_mipi_rx_set_bits(it6161, 0x3E, 0x80, 0x00);
1712 it6161_mipi_rx_set_bits(it6161, 0x41, 0x80, 0x00);
1713 it6161_mipi_rx_set_bits(it6161, 0x43, 0x80, 0x00);
1714 }
1715
1716 // mprxset(0x4e, 0x03, 0x00+(VPol<<1)+HPol);
1717 }
1718 }
1719
mipi_rx_init(struct it6161 * it6161)1720 static void mipi_rx_init(struct it6161 *it6161)
1721 {
1722 //struct device *dev = &it6161->i2c_mipi_rx->dev;
1723
1724 it6161_debug("init mpip rx");
1725 mipi_rx_configuration(it6161);
1726 it6161_mipi_rx_set_bits(it6161, 0x05, 0x03, 0x00); // Enable MPRX clock domain
1727 }
1728
hdmi_tx_video_reset(struct it6161 * it6161)1729 static void hdmi_tx_video_reset(struct it6161 *it6161)
1730 {
1731 //struct device *dev = &it6161->i2c_mipi_rx->dev;
1732
1733 it6161_debug("%s reg04:0x%02x reg05:0x%02x reg6:0x%02x reg07:0x%02x reg08:0x%02x reg0e:0x%02x", __func__, it6161_hdmi_tx_read(it6161, 0x04), it6161_hdmi_tx_read(it6161, 0x05), it6161_hdmi_tx_read(it6161, 0x06), it6161_hdmi_tx_read(it6161, 0x07), it6161_hdmi_tx_read(it6161, 0x08), it6161_hdmi_tx_read(it6161, 0x0e));
1734 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_VID_RST, B_HDMITX_VID_RST);
1735 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_VID_RST, 0x00);
1736 msleep(10);
1737 }
1738 /*
1739 static void hdmi_tx_audio_fifo_reset(struct it6161 *it6161)
1740 {
1741 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST, B_HDMITX_AUD_RST);
1742 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST, 0x00);
1743 }
1744 */
1745 /* DDC master will set to be host */
1746
it6161_hdmi_tx_clear_ddc_fifo(struct it6161 * it6161)1747 static void it6161_hdmi_tx_clear_ddc_fifo(struct it6161 *it6161)
1748 {
1749 it6161_hdmi_tx_change_bank(it6161, 0);
1750 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
1751 it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, CMD_FIFO_CLR);
1752 it6161_hdmi_tx_set_bits(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERHOST, 0x00);
1753 }
1754
1755 #ifdef HDCP
it6161_hdmi_tx_generate_ddc_sclk(struct it6161 * it6161)1756 static void it6161_hdmi_tx_generate_ddc_sclk(struct it6161 *it6161)
1757 {
1758 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST);
1759 it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD,CMD_GEN_SCLCLK);
1760 }
1761 #endif
hdmi_tx_generate_blank_timing(struct it6161 * it6161)1762 static void hdmi_tx_generate_blank_timing(struct it6161 *it6161)
1763 {
1764 struct drm_display_mode *display_mode = &it6161->source_display_mode;
1765 bool force_hdmi_tx_clock_stable = true, force_hdmi_tx_video_stable = true, hdmi_tx_by_pass_mode = false, de_generation = false, enable_de_only = true;
1766 u8 polarity;
1767 u16 hsync_start, hsync_end, vsync_start, vsync_end, htotal, hde_start, vtotal;
1768 u16 vsync_start_2nd = 0, vsync_end_2nd = 0, vsync_rising_at_h_2nd;
1769
1770 it6161_debug("start %s", __func__);
1771 polarity = ((display_mode->flags & DRM_MODE_FLAG_PHSYNC) == DRM_MODE_FLAG_PHSYNC) ? 0x02 : 0x00;
1772 polarity |= ((display_mode->flags & DRM_MODE_FLAG_PVSYNC) == DRM_MODE_FLAG_PVSYNC) ? 0x04 : 0x00;
1773
1774 hsync_start = display_mode->hsync_start - display_mode->hdisplay - 1;
1775 hsync_end = hsync_start + display_mode->hsync_end - display_mode->hsync_start;
1776 vsync_rising_at_h_2nd = hsync_start + display_mode->htotal / 2;
1777 hde_start = display_mode->htotal - display_mode->hsync_start;
1778
1779 it6161_hdmi_tx_set_bits(it6161, 0xD1, 0x0C, force_hdmi_tx_clock_stable << 3 | force_hdmi_tx_video_stable << 2);
1780 it6161_hdmi_tx_set_bits(it6161, 0xA9, 0x80, hdmi_tx_by_pass_mode << 7);
1781 it6161_hdmi_tx_set_bits(it6161, 0x90, 0x01, de_generation);
1782 it6161_hdmi_tx_write(it6161, 0x91, vsync_rising_at_h_2nd >> 4);
1783 it6161_hdmi_tx_set_bits(it6161, 0x90, 0xF0, (vsync_rising_at_h_2nd & 0x00F) << 4);
1784 it6161_hdmi_tx_set_bits(it6161, 0x90, 0x06, polarity);
1785 it6161_hdmi_tx_write(it6161, 0x95, (u8)hsync_start);
1786 it6161_hdmi_tx_write(it6161, 0x96, (u8)hsync_end);
1787 it6161_hdmi_tx_write(it6161, 0x97, (hsync_end & 0x0F00) >> 4 | hsync_start >> 8);
1788
1789 vsync_start = display_mode->vsync_start - display_mode->vdisplay;
1790 vsync_end = display_mode->vsync_end - display_mode->vdisplay;
1791
1792 if ((display_mode->flags & DRM_MODE_FLAG_INTERLACE) != DRM_MODE_FLAG_INTERLACE) {
1793 vsync_start_2nd = 0x0FFF;
1794 vsync_end_2nd = 0x3F;
1795 vtotal = display_mode->vtotal - 1;
1796 it6161_hdmi_tx_set_bits(it6161, 0xA5, 0x10, 0x00);
1797 } else {
1798 vtotal = display_mode->vtotal * 2;
1799 it6161_hdmi_tx_set_bits(it6161, 0xA5, 0x10, 0x10);
1800 }
1801 it6161_hdmi_tx_write(it6161, 0xA0, (u8)vsync_start);
1802 it6161_hdmi_tx_write(it6161, 0xA1, (vsync_end & 0x0F) << 4 | vsync_start >> 8);
1803 it6161_hdmi_tx_write(it6161, 0xA2, (u8)vsync_start_2nd);
1804 it6161_hdmi_tx_write(it6161, 0xA6, (vsync_end_2nd & 0xF0) | vsync_end >> 4);
1805 it6161_hdmi_tx_write(it6161, 0xA3, (vsync_end_2nd & 0x0F) << 4 | vsync_start_2nd >> 8);
1806 it6161_hdmi_tx_write(it6161, 0xA4, vsync_rising_at_h_2nd);
1807 it6161_hdmi_tx_set_bits(it6161, 0xB1, 0x51, (hsync_end & 0x1000) >> 6 | (hsync_start & 0x1000) >> 8 | hde_start >> 12);
1808 it6161_hdmi_tx_set_bits(it6161, 0xA5, 0x2F, enable_de_only << 5 | vsync_rising_at_h_2nd >> 8);
1809 it6161_hdmi_tx_set_bits(it6161, 0xB2, 0x05, (vsync_rising_at_h_2nd & 0x1000) >> 10 | (vsync_rising_at_h_2nd & 0x1000) >> 12);
1810
1811 htotal = display_mode->htotal - 1;
1812 it6161_hdmi_tx_set_bits(it6161, 0x90, 0xF0, (htotal & 0x0F) << 4);
1813 it6161_hdmi_tx_write(it6161, 0x91, (htotal & 0x0FF0) >> 4);
1814 it6161_hdmi_tx_set_bits(it6161, 0xB2, 0x01, (htotal & 0x1000) >> 12);
1815 it6161_hdmi_tx_write(it6161, 0x98, vtotal & 0x0FF);
1816 it6161_hdmi_tx_write(it6161, 0x99, (vtotal & 0xF00) >> 8);
1817 }
1818
1819 /* force abort DDC and reset DDC bus */
1820
it6161_hdmi_tx_abort_ddc(struct it6161 * it6161)1821 static void it6161_hdmi_tx_abort_ddc(struct it6161 *it6161)
1822 {
1823 u8 cp_desire, sw_reset, ddc_master, retry = 2;
1824 u8 uc, timeout, i;
1825
1826 it6161_debug("%s", __func__);
1827 /* save the sw reset, ddc master and cp desire setting */
1828 sw_reset = it6161_hdmi_tx_read(it6161, REG_TX_SW_RST);
1829 cp_desire = it6161_hdmi_tx_read(it6161, REG_TX_HDCP_DESIRE);
1830 ddc_master = it6161_hdmi_tx_read(it6161, REG_TX_DDC_MASTER_CTRL);
1831
1832 // it6161_hdmi_tx_write(it6161, REG_TX_HDCP_DESIRE,CPDesire&(~B_TX_CPDESIRE)); // @emily change order
1833 it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, sw_reset | B_TX_HDCP_RST_HDMITX); // @emily change order
1834 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
1835
1836 /* do abort DDC */
1837 for (i = 0; i < retry; i++) {
1838 it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, CMD_DDC_ABORT);
1839 it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, CMD_GEN_SCLCLK);//hdmitxwr(0x15, 0x0A); //it6161A0 // Generate SCL Clock
1840
1841 for (timeout = 0; timeout < 200; timeout++) {
1842 uc = it6161_hdmi_tx_read(it6161, REG_TX_DDC_STATUS);
1843 if (uc&B_TX_DDC_DONE)
1844 break ;
1845
1846 if (uc & (B_TX_DDC_NOACK | B_TX_DDC_WAITBUS | B_TX_DDC_ARBILOSE)) {
1847 DRM_INFO("it6161_hdmi_tx_abort_ddc Fail by reg16=%02X\n",(int)uc);//pet
1848 break ;
1849 }
1850 /* delay 1 ms to stable */
1851 msleep(1);
1852 }
1853 }
1854 }
1855
hdmi_tx_get_video_state(struct it6161 * it6161)1856 static bool hdmi_tx_get_video_state(struct it6161 *it6161)
1857 {
1858 return !!(B_TXVIDSTABLE & it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS));
1859 }
1860
hdmi_tx_get_sink_hpd(struct it6161 * it6161)1861 static bool inline hdmi_tx_get_sink_hpd(struct it6161 *it6161)
1862 {
1863 return !!(it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS) & B_TX_HPDETECT);
1864 }
1865
it6161_ddc_op_finished(struct it6161 * it6161)1866 static bool it6161_ddc_op_finished(struct it6161 *it6161)
1867 {
1868 int reg16 = it6161_hdmi_tx_read(it6161, REG_TX_DDC_STATUS);
1869
1870 if (reg16 < 0)
1871 return false;
1872
1873 return (reg16 & B_TX_DDC_DONE) == B_TX_DDC_DONE;
1874 }
1875
it6161_ddc_wait(struct it6161 * it6161)1876 static int it6161_ddc_wait(struct it6161 *it6161)
1877 {
1878 int status;
1879 unsigned long timeout;
1880 //struct device *dev = &it6161->client->dev;
1881
1882 timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1;
1883
1884 while (!it6161_ddc_op_finished(it6161)) {
1885 if (time_after(jiffies, timeout)) {
1886 DRM_INFO("Timed out waiting AUX to finish");
1887 return -ETIMEDOUT;
1888 }
1889 usleep_range(1000, 2000);
1890 }
1891
1892 status = it6161_hdmi_tx_read(it6161, REG_TX_DDC_STATUS);
1893 if (status < 0) {
1894 DRM_INFO("Failed to read DDC channel: 0x%02x", status);
1895 return status;
1896 }
1897
1898 if(status & B_TX_DDC_DONE) {
1899 return 0;
1900 } else {
1901 DRM_INFO("DDC error: 0x%02x", status);
1902 return -EIO;
1903 }
1904 }
1905
hdmi_tx_ddc_operation(struct it6161 * it6161,u8 addr,u8 offset,u8 size,u8 segment,u8 cmd)1906 static void hdmi_tx_ddc_operation(struct it6161 *it6161, u8 addr, u8 offset, u8 size, u8 segment, u8 cmd)
1907 {
1908 size = min(size, (u8)DDC_FIFO_MAXREQ);
1909 it6161_hdmi_tx_change_bank(it6161, 0);
1910 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
1911 it6161_hdmi_tx_write(it6161, REG_TX_DDC_HEADER, addr);
1912 it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQOFF, offset);
1913 it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQCOUNT, size);
1914 it6161_hdmi_tx_write(it6161, REG_TX_DDC_EDIDSEG, segment);
1915 it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, cmd);
1916 }
1917
1918 //////////////////////////////////////////////////////////////////////
1919 // Function: it6161_ddc_get_edid_operation
1920 // Parameter: buffer - the pointer of buffer to receive EDID ucdata.
1921 // segment - the segment of EDID readback.
1922 // offset - the offset of EDID ucdata in the segment. in byte.
1923 // size - the read back bytes count,cannot exceed 32
1924 // Return: ER_SUCCESS if successfully getting EDID. ER_FAIL otherwise.
1925 // Remark: function for read EDID ucdata from reciever.
1926 // Side-Effect: DDC master will set to be HOST. DDC FIFO will be used and dirty.
1927 //////////////////////////////////////////////////////////////////////
1928
it6161_ddc_get_edid_operation(struct it6161 * it6161,u8 * buffer,u8 segment,u8 offset,int size)1929 static int it6161_ddc_get_edid_operation(struct it6161 *it6161, u8 *buffer, u8 segment, u8 offset, int size)
1930 {
1931 u8 status, i;
1932
1933 if(!buffer)
1934 return -ENOMEM;
1935
1936 if(it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1) & B_TX_INT_DDC_BUS_HANG) {
1937 DRM_INFO("Called it6161_hdmi_tx_abort_ddc()");
1938 it6161_hdmi_tx_abort_ddc(it6161);
1939 }
1940
1941 it6161_hdmi_tx_clear_ddc_fifo(it6161);
1942 status = it6161_ddc_wait(it6161);
1943
1944 if (status < 0)
1945 goto error;
1946
1947 hdmi_tx_ddc_operation(it6161, DDC_EDID_ADDRESS, offset, size, segment, CMD_EDID_READ);
1948 status = it6161_ddc_wait(it6161);
1949
1950 if (status < 0)
1951 goto error;
1952
1953 for (i = 0; i < size; i++) {
1954 status = it6161_hdmi_tx_read(it6161, REG_TX_DDC_READFIFO);
1955
1956 if (status < 0)
1957 goto error;
1958
1959 buffer[i] = status;
1960 }
1961
1962 return i;
1963
1964 error:
1965 return status;
1966 }
1967
it6161_get_edid_block(void * data,u8 * buf,unsigned int block_num,size_t len)1968 static int it6161_get_edid_block(void *data, u8 *buf, unsigned int block_num,
1969 size_t len)
1970 {
1971 struct it6161 *it6161 = data;
1972 u8 offset, ret, step = 8;
1973
1974 step = min(step, (u8)DDC_FIFO_MAXREQ);
1975 DRM_INFO("[%s] edid block number:%d read step:%d", __func__, block_num, step);
1976
1977 for (offset = 0; offset < len; offset += step) {
1978 ret = it6161_ddc_get_edid_operation(it6161, buf + offset, block_num / 2, (block_num % 2) * EDID_LENGTH + offset, step);
1979
1980 if(ret < 0)
1981 return ret;
1982 #ifdef __linux__
1983 DRM_INFO("[0x%02x]: %*ph", offset, step, buf + offset);
1984 #else
1985 DRM_INFO("[0x%02x]:", offset);
1986
1987 for (ret = 0; ret < step; ret++)
1988 printf(" 0x%02x", (buf + offset)[ret]);
1989 printf("\n\r");
1990 #endif
1991 }
1992 return 0;
1993 }
1994
hdmi_tx_set_capability_from_edid_parse(struct it6161 * it6161)1995 static void hdmi_tx_set_capability_from_edid_parse(struct it6161 *it6161)
1996 {
1997 struct drm_display_info *info = &it6161->connector.display_info;
1998
1999 it6161->hdmi_mode = drm_detect_hdmi_monitor(it6161->edid);
2000 it6161->support_audio = drm_detect_monitor_audio(it6161->edid);
2001 if (it6161->hdmi_tx_output_color_space == F_MODE_YUV444) {
2002 if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) != DRM_COLOR_FORMAT_YCRCB444) {
2003 it6161->hdmi_tx_output_color_space &= ~F_MODE_CLRMOD_MASK;
2004 it6161->hdmi_tx_output_color_space |= F_MODE_RGB444;
2005 }
2006 }
2007
2008 if (it6161->hdmi_tx_output_color_space == F_MODE_YUV422) {
2009 if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) != DRM_COLOR_FORMAT_YCRCB422) {
2010 it6161->hdmi_tx_output_color_space &= ~F_MODE_CLRMOD_MASK;
2011 it6161->hdmi_tx_output_color_space |= F_MODE_RGB444;
2012 }
2013 }
2014 DRM_INFO("%s mode, monitor %ssupport audio, outputcolormode:%d color_formats:0x%08x color_depth:%d",
2015 it6161->hdmi_mode ? "HDMI" : "DVI", it6161->support_audio ? "" : "not ", it6161->hdmi_tx_output_color_space, info->color_formats, info->bpc);
2016
2017 if ((info->color_formats & DRM_COLOR_FORMAT_RGB444) == DRM_COLOR_FORMAT_RGB444)
2018 DRM_INFO("support RGB444 output");
2019 if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) == DRM_COLOR_FORMAT_YCRCB444)
2020 DRM_INFO("support YUV444 output");
2021 if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) == DRM_COLOR_FORMAT_YCRCB422)
2022 DRM_INFO("support YUV422 output");
2023 }
2024
it6161_variable_config(struct it6161 * it6161)2025 static void it6161_variable_config(struct it6161 *it6161)
2026 {
2027 it6161->hdmi_tx_hdcp_retry = HDMI_TX_HDCP_RETRY;
2028 it6161->hdmi_tx_mode = HDMI_TX_MODE;
2029 it6161->mipi_rx_lane_count = MIPI_RX_LANE_COUNT;
2030 }
2031
2032 #ifdef __linux__
2033
it6161_get_modes(struct drm_connector * connector)2034 static int it6161_get_modes(struct drm_connector *connector)
2035 {
2036 struct it6161 *it6161 = connector_to_it6161(connector);
2037 int err, num_modes = 0, i, retry = 3;
2038 struct device *dev = &it6161->i2c_mipi_rx->dev;
2039
2040 it6161_debug("%s start", __func__);
2041
2042 if (it6161->edid)
2043 return drm_add_edid_modes(connector, it6161->edid);
2044 mutex_lock(&it6161->mode_lock);
2045 reinit_completion(&it6161->wait_edid_complete);
2046
2047 for (i = 0; i < retry; i++) {
2048 it6161->edid =
2049 drm_do_get_edid(&it6161->connector, it6161_get_edid_block, it6161);
2050
2051 if (it6161->edid)
2052 break;
2053 }
2054 if (!it6161->edid) {
2055 DRM_DEV_ERROR(dev, "Failed to read EDID");
2056 goto unlock;
2057 }
2058
2059 err = drm_connector_update_edid_property(connector, it6161->edid);
2060 if (err) {
2061 DRM_DEV_ERROR(dev, "Failed to update EDID property: %d", err);
2062 goto unlock;
2063 }
2064
2065 num_modes = drm_add_edid_modes(connector, it6161->edid);
2066
2067 unlock:
2068 complete(&it6161->wait_edid_complete);
2069 DRM_INFO("edid mode number:%d", num_modes);
2070 mutex_unlock(&it6161->mode_lock);
2071
2072 return num_modes;
2073 }
2074
2075 static const struct drm_connector_helper_funcs it6161_connector_helper_funcs = {
2076 .get_modes = it6161_get_modes,
2077 };
2078
it6161_detect(struct drm_connector * connector,bool force)2079 static enum drm_connector_status it6161_detect(struct drm_connector *connector,
2080 bool force)
2081 {
2082 struct it6161 *it6161 = connector_to_it6161(connector);
2083 enum drm_connector_status status = connector_status_disconnected;
2084 bool hpd = hdmi_tx_get_sink_hpd(it6161);
2085
2086 DRM_INFO("hpd:%s", hpd ? "high" : "low");
2087 //mutex_lock(&it6161->mode_lock);
2088
2089 if (hpd) {
2090 it6161_variable_config(it6161);
2091 status = connector_status_connected;
2092 }
2093
2094 it6161_set_interrupts_active_level(HIGH);
2095 it6161_mipi_rx_int_mask_enable(it6161);
2096 it6161_hdmi_tx_int_mask_enable(it6161);
2097
2098 //mutex_lock(&it6161->mode_lock);
2099 return status;
2100 }
2101
2102 static const struct drm_connector_funcs it6161_connector_funcs = {
2103 .fill_modes = drm_helper_probe_single_connector_modes,
2104 .detect = it6161_detect,
2105 .destroy = drm_connector_cleanup,
2106 .reset = drm_atomic_helper_connector_reset,
2107 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
2108 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
2109 };
2110
it6161_attach_dsi(struct it6161 * it6161)2111 static int it6161_attach_dsi(struct it6161 *it6161)
2112 {
2113 struct mipi_dsi_host *host;
2114 struct mipi_dsi_device *dsi;
2115 int ret = 0;
2116 const struct mipi_dsi_device_info info = { .type = "it6161",
2117 };
2118
2119 host = of_find_mipi_dsi_host_by_node(it6161->host_node);
2120 if (!host) {
2121 DRM_INFO("it6161 failed to find dsi host\n");
2122 return -EPROBE_DEFER;
2123 }
2124
2125 dsi = mipi_dsi_device_register_full(host, &info);
2126 if (IS_ERR(dsi)) {
2127 DRM_INFO("it6161 failed to create dsi device\n");
2128 ret = PTR_ERR(dsi);
2129 goto err_dsi_device;
2130 }
2131
2132 it6161->dsi = dsi;
2133
2134 dsi->lanes = 4;
2135 dsi->format = MIPI_DSI_FMT_RGB888;
2136 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
2137 MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE;
2138
2139 ret = mipi_dsi_attach(dsi);
2140 if (ret < 0) {
2141 DRM_INFO("it6161 failed to attach dsi to host\n");
2142 goto err_dsi_attach;
2143 }
2144
2145 return 0;
2146
2147 err_dsi_attach:
2148 mipi_dsi_device_unregister(dsi);
2149 err_dsi_device:
2150 return ret;
2151 }
2152
it6161_bridge_attach(struct drm_bridge * bridge,enum drm_bridge_attach_flags flags)2153 static int it6161_bridge_attach(struct drm_bridge *bridge,
2154 enum drm_bridge_attach_flags flags)
2155 {
2156 struct it6161 *it6161 = bridge_to_it6161(bridge);
2157 struct device *dev;
2158 int err;
2159
2160 dev = &it6161->i2c_mipi_rx->dev;
2161 if (!bridge->encoder) {
2162 DRM_DEV_ERROR(dev, "Parent encoder object not found");
2163 return -ENODEV;
2164 }
2165
2166 err = drm_connector_init(bridge->dev, &it6161->connector,
2167 &it6161_connector_funcs,
2168 DRM_MODE_CONNECTOR_HDMIA);
2169 if (err < 0) {
2170 DRM_DEV_ERROR(dev, "Failed to initialize connector: %d", err);
2171 return err;
2172 }
2173
2174 drm_connector_helper_add(&it6161->connector,
2175 &it6161_connector_helper_funcs);
2176
2177 it6161->connector.polled = DRM_CONNECTOR_POLL_HPD;
2178
2179 err = drm_connector_attach_encoder(&it6161->connector, bridge->encoder);
2180 if (err < 0) {
2181 DRM_DEV_ERROR(dev, "Failed to link up connector to encoder: %d",
2182 err);
2183 goto cleanup_connector;
2184 }
2185
2186 DRM_INFO("%s, ret:%d", __func__, it6161_attach_dsi(it6161));
2187
2188 err = drm_connector_register(&it6161->connector);
2189 if (err < 0) {
2190 DRM_DEV_ERROR(dev, "Failed to register connector: %d", err);
2191 goto cleanup_connector;
2192 }
2193 it6161_debug("%s finish", __func__);
2194
2195 return 0;
2196
2197 // unregister_connector:
2198 // drm_connector_unregister(&it6161->connector);
2199 cleanup_connector:
2200 drm_connector_cleanup(&it6161->connector);
2201 return err;
2202 }
2203
it6161_detach_dsi(struct it6161 * it6161)2204 static void it6161_detach_dsi(struct it6161 *it6161)
2205 {
2206 mipi_dsi_detach(it6161->dsi);
2207 mipi_dsi_device_unregister(it6161->dsi);
2208 }
2209
it6161_bridge_detach(struct drm_bridge * bridge)2210 static void it6161_bridge_detach(struct drm_bridge *bridge)
2211 {
2212 struct it6161 *it6161 = bridge_to_it6161(bridge);
2213
2214 drm_connector_unregister(&it6161->connector);
2215 drm_connector_cleanup(&it6161->connector);
2216 it6161_detach_dsi(it6161);
2217 }
2218
2219 static enum drm_mode_status
it6161_bridge_mode_valid(struct drm_bridge * bridge,const struct drm_display_info * info,const struct drm_display_mode * mode)2220 it6161_bridge_mode_valid(struct drm_bridge *bridge,
2221 const struct drm_display_info *info,
2222 const struct drm_display_mode *mode)
2223 {
2224 //struct it6161 *it6161 = bridge_to_it6161(bridge);
2225
2226 // if (mode->flags & DRM_MODE_FLAG_INTERLACE)
2227 // return MODE_NO_INTERLACE;
2228 it6161_debug("%s\n", __func__);
2229 // /* Max 1200p at 5.4 Ghz, one lane */
2230 // if (mode->clock > MAX_PIXEL_CLK)
2231 // return MODE_CLOCK_HIGH;
2232
2233 if (mode->clock == 27027)
2234 return MODE_BAD;
2235
2236 if (mode->clock > 165000)
2237 return MODE_CLOCK_HIGH;
2238
2239 //DRM_INFO("%s end", __func__);
2240
2241 return MODE_OK;
2242 }
2243
2244 // static int it6161_send_video_infoframe(struct it6161 *it6161,
2245 // struct hdmi_avi_infoframe *frame)
2246 // {
2247 // u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
2248 // int err;
2249 // struct device *dev = &it6161->i2c_mipi_rx->dev;
2250
2251 // err = hdmi_avi_infoframe_pack(frame, buffer, sizeof(buffer));
2252 // if (err < 0) {
2253 // DRM_DEV_ERROR(dev, "Failed to pack AVI infoframe: %d\n", err);
2254 // return err;
2255 // }
2256
2257 // err = dptx_set_bits(it6161, 0xE8, 0x01, 0x00);
2258 // if (err)
2259 // return err;
2260
2261 // err = regmap_bulk_write(it6161->regmap_mipi_rx, 0xE9,
2262 // buffer + HDMI_INFOFRAME_HEADER_SIZE,
2263 // frame->length);
2264 // if (err)
2265 // return err;
2266
2267 // err = dptx_set_bits(it6161, 0xE8, 0x01, 0x01);
2268 // if (err)
2269 // return err;
2270
2271 // return 0;
2272 // }
2273
it6161_bridge_mode_set(struct drm_bridge * bridge,const struct drm_display_mode * mode,const struct drm_display_mode * adjusted_mode)2274 static void it6161_bridge_mode_set(struct drm_bridge *bridge,
2275 const struct drm_display_mode *mode,
2276 const struct drm_display_mode *adjusted_mode)
2277 {
2278 struct it6161 *it6161 = bridge_to_it6161(bridge);
2279 struct device *dev = &it6161->i2c_mipi_rx->dev;
2280 struct drm_display_mode *display_mode = &it6161->source_display_mode;
2281 int err;
2282
2283 mutex_lock(&it6161->mode_lock);
2284 err = drm_hdmi_avi_infoframe_from_display_mode(&it6161->source_avi_infoframe, &it6161->connector,
2285 mode);
2286 if (err) {
2287 DRM_DEV_ERROR(dev, "Failed to setup AVI infoframe: %d", err);
2288 goto unlock;
2289 }
2290
2291 //it6161->hdmi_tx_display_mode.base.id = adjusted_mode->base.id;
2292 strlcpy(it6161->hdmi_tx_display_mode.name, adjusted_mode->name,
2293 DRM_DISPLAY_MODE_LEN);
2294 it6161->hdmi_tx_display_mode.type = adjusted_mode->type;
2295 it6161->hdmi_tx_display_mode.flags = adjusted_mode->flags;
2296 //err = it6161_send_video_infoframe(it6161, &frame);
2297 strlcpy(display_mode->name, adjusted_mode->name,
2298 DRM_DISPLAY_MODE_LEN);
2299 display_mode->clock = mode->clock;
2300 display_mode->hdisplay = mode->hdisplay;
2301 display_mode->hsync_start = mode->hsync_start;
2302 display_mode->hsync_end = mode->hsync_end;
2303 display_mode->htotal = mode->htotal;
2304 display_mode->vdisplay = mode->vdisplay;
2305 display_mode->vsync_start = mode->vsync_start;
2306 display_mode->vsync_end = mode->vsync_end;
2307 display_mode->vtotal = mode->vtotal;
2308 display_mode->flags = mode->flags;
2309 it6161->vic = it6161->source_avi_infoframe.video_code;
2310 DRM_INFO("config display mode clk: %d\n", display_mode->clock);
2311 DRM_INFO("config display mode hdisplay: %d\n", display_mode->hdisplay);
2312 DRM_INFO("config display mode hsync_start: %d\n", display_mode->hsync_start);
2313 DRM_INFO("config display mode hsync_end: %d\n", display_mode->hsync_end);
2314 DRM_INFO("config display mode htotal: %d\n", display_mode->htotal);
2315 DRM_INFO("config display mode vdisplay: %d\n", display_mode->vdisplay);
2316 DRM_INFO("config display mode vsync_start: %d\n", display_mode->vsync_start);
2317 DRM_INFO("config display mode vsync_end: %d\n", display_mode->vsync_end);
2318 DRM_INFO("config display mode vtotal: %d\n", display_mode->vtotal);
2319
2320 if (err)
2321 DRM_DEV_ERROR(dev, "Failed to send AVI infoframe: %d", err);
2322
2323 unlock:
2324 mutex_unlock(&it6161->mode_lock);
2325 }
2326
it6161_bridge_enable(struct drm_bridge * bridge)2327 static void it6161_bridge_enable(struct drm_bridge *bridge)
2328 {
2329 struct it6161 *it6161 = bridge_to_it6161(bridge);
2330 it6161_bridge = bridge;
2331
2332 it6161_debug("%s start", __func__);
2333 mipi_rx_init(it6161);//allen
2334 hdmi_tx_init(it6161);//allen
2335 it6161_set_interrupts_active_level(HIGH);
2336 it6161_mipi_rx_int_mask_enable(it6161);
2337 it6161_hdmi_tx_int_mask_enable(it6161);
2338
2339 it6161_debug("%s start restart delayed work\n", __func__);
2340 schedule_delayed_work(&it6161->restart, msecs_to_jiffies(2000));
2341
2342 //if (enable_de_only)
2343 // hdmi_tx_generate_blank_timing(it6161);
2344
2345 //hdmi_tx_video_reset(it6161);
2346 // if (!it6161->enable_drv_hold) {
2347 // it6161_int_mask_on(it6161);
2348 // dptx_sys_chg(it6161, SYS_HPD);
2349 // }
2350 }
2351
it6161_bridge_disable(struct drm_bridge * bridge)2352 static void it6161_bridge_disable(struct drm_bridge *bridge)
2353 {
2354 struct it6161 *it6161 = bridge_to_it6161(bridge);
2355
2356 it6161_debug("%s start", __func__);//----TODO
2357 mipi_rx_logic_reset(it6161);
2358 hdmi_tx_logic_reset(it6161);
2359 it6161_set_interrupts_active_level(HIGH);
2360 it6161_mipi_rx_int_mask_enable(it6161);
2361 it6161_hdmi_tx_int_mask_enable(it6161);//---
2362 //kfree(it6161->edid);
2363 //it6161->edid = NULL;
2364 }
2365
2366 static const struct drm_bridge_funcs it6161_bridge_funcs = {
2367 .attach = it6161_bridge_attach,
2368 .detach = it6161_bridge_detach,
2369 .mode_valid = it6161_bridge_mode_valid,
2370 .mode_set = it6161_bridge_mode_set,
2371 .enable = it6161_bridge_enable,// set NULL for old linux version
2372 .disable = it6161_bridge_disable,
2373 };
2374
2375 #endif
2376
2377 #define InitCEC() it6161_hdmi_tx_write(it6161, 0x8D, (CEC_I2C_SLAVE_ADDR|0x01))//HDMITX_SetI2C_Byte(0x8D, 0x01, 0x01)//HDMITX_SetI2C_Byte(0x0F, 0x08, 0x00)
2378 #define DisableCEC() it6161_hdmi_tx_set_bits(it6161, 0x8D, 0x01, 0x00)//HDMITX_SetI2C_Byte(0x0F, 0x08, 0x08)
2379
it6161_check_device_ready(struct it6161 * it6161)2380 static bool it6161_check_device_ready(struct it6161 *it6161)
2381 {
2382 u8 Vendor_ID[2], Device_ID[2];
2383
2384 Vendor_ID[0] = it6161_mipi_rx_read(it6161, 0x00);
2385 Vendor_ID[1] = it6161_mipi_rx_read(it6161, 0x01);
2386 Device_ID[0] = it6161_mipi_rx_read(it6161, 0x02);
2387 Device_ID[1] = it6161_mipi_rx_read(it6161, 0x03);
2388 // Version_ID = MIPIRX_ReadI2C_Byte(0x04);
2389 if (Vendor_ID[0] == 0x54 && Vendor_ID[1] == 0x49 && Device_ID[0] == 0x61 && Device_ID[1] == 0x61)
2390 {
2391 DRM_INFO("Find 6161 revision: 0x%2x", (u32)it6161_mipi_rx_read(it6161, 0x04));
2392 return true;
2393 }
2394 DRM_INFO("find it6161 Fail");
2395 return false;
2396 }
2397
hdmi_tx_calc_rclk(struct it6161 * it6161)2398 static u32 hdmi_tx_calc_rclk(struct it6161 *it6161)//in c code: cal_txrclk
2399 {
2400 // u8 uc ;
2401 int i ;
2402 long sum = 0, RCLKCNT, TimeLoMax, retry = 5;
2403
2404 InitCEC();
2405 // it6161_hdmi_tx_write(it6161, 0x8D, (CEC_I2C_SLAVE_ADDR|0x01));// Enable CRCLK
2406 msleep(10);
2407
2408 for (i = 0; i < retry; i++) {
2409 // uc = it6161_cec_read(it6161, 0x09) & 0xFE ;
2410 it6161_cec_write(it6161, 0x09, 1);
2411 msleep(100);
2412 it6161_cec_write(it6161, 0x09, 0);
2413 RCLKCNT = it6161_cec_read(it6161, 0x47);
2414 RCLKCNT <<= 8 ;
2415 RCLKCNT |= it6161_cec_read(it6161, 0x46);
2416 RCLKCNT <<= 8 ;
2417 RCLKCNT |= it6161_cec_read(it6161, 0x45);
2418 // DRM_INFO1(("RCLK = %d\n",RCLKCNT) );
2419 sum += RCLKCNT ;
2420 }
2421 sum /= retry;
2422 RCLKCNT = sum/1000;
2423 it6161_cec_write(it6161, 0x0C, (RCLKCNT & 0xFF));
2424
2425 DisableCEC();
2426
2427 // it6161->hdmi_tx_rclk = (sum << 4) / 108;//actually nxp platform msleep(100) is 108ms
2428 it6161->hdmi_tx_rclk = (sum << 4) / 104;//actually nxp platform msleep(100) is 108ms
2429 DRM_INFO("hdmi tx rclk = %d.%dMHz", it6161->hdmi_tx_rclk / 1000, it6161->hdmi_tx_rclk % 1000);
2430
2431 TimeLoMax = (sum << 4)/10;//10*TxRCLK;
2432
2433 // add HDCP TimeLomax over-flow protection
2434 if(TimeLoMax>0x3FFFF)
2435 TimeLoMax = 0x3FFFF;
2436
2437 DRM_INFO("TimeLoMax=%08lx\n", TimeLoMax);
2438 it6161_hdmi_tx_write(it6161, 0x47, (TimeLoMax&0xFF));
2439 it6161_hdmi_tx_write(it6161, 0x48, ((TimeLoMax&0xFF00)>>8));
2440 it6161_hdmi_tx_set_bits(it6161, 0x49, 0x03, ((TimeLoMax&0x30000)>>16));
2441
2442 return it6161->hdmi_tx_rclk;
2443 }
2444
hdmi_tx_calc_pclk(struct it6161 * it6161)2445 static u32 hdmi_tx_calc_pclk(struct it6161 *it6161) //c code void cal_txclk( void )
2446 {
2447 u8 uc, RCLKFreqSelRead;
2448 int div, i;
2449 u32 sum , count;
2450
2451 it6161_hdmi_tx_change_bank(it6161, 0);
2452 // uc = it6161_hdmi_tx_read(it6161, 0x5F) & 0x80 ;
2453
2454 // if( ! uc )
2455 // {
2456 // return 0 ;
2457 // }
2458 RCLKFreqSelRead = (it6161_hdmi_tx_read(it6161, 0x5D) & 0x04)>>2;//hdmitxset(0x5D, 0x04, (RCLKFreqSel<<2));
2459 /* PCLK Count Pre-Test */
2460 it6161_hdmi_tx_set_bits(it6161, 0xD7, 0xF0, 0x80);
2461 msleep(1);
2462 it6161_hdmi_tx_set_bits(it6161, 0xD7, 0x80, 0x00);
2463
2464 count = it6161_hdmi_tx_read(it6161, 0xD7) & 0xF ;
2465 count <<= 8 ;
2466 count |= it6161_hdmi_tx_read(it6161, 0xD8);
2467
2468 if (RCLKFreqSelRead)
2469 count <<= 1;
2470
2471 for ( div = 7 ; div > 0 ; div-- ) {
2472 if (count < (1<<(11-div)))
2473 break ;
2474 }
2475
2476 if (div < 0)
2477 {
2478 div = 0;
2479 }
2480
2481 it6161_hdmi_tx_set_bits(it6161, 0xD7, 0x70, div<<4);
2482
2483 uc = it6161_hdmi_tx_read(it6161, 0xD7) & 0x7F ;
2484 for( i = 0 , sum = 0 ; i < 100 ; i ++ )
2485 {
2486 it6161_hdmi_tx_write(it6161, 0xD7, uc|0x80) ;
2487 msleep(1);
2488 it6161_hdmi_tx_write(it6161, 0xD7, uc) ;
2489
2490 count = it6161_hdmi_tx_read(it6161, 0xD7) & 0xF ;
2491 count <<= 8 ;
2492 count |= it6161_hdmi_tx_read(it6161, 0xD8);
2493 if (RCLKFreqSelRead)
2494 {
2495 count <<= 1;
2496 }
2497 sum += count;
2498 }
2499 sum /= 100;
2500 count = sum;
2501
2502 it6161->hdmi_tx_pclk = it6161->hdmi_tx_rclk * 128 / count * 16 ;//128*16=2048
2503 it6161->hdmi_tx_pclk *= (1<<div);
2504
2505 // if( it6161_hdmi_tx_read(it6161, 0x70) & 0x10 )
2506 // {
2507 // it6161->hdmi_tx_pclk /= 2 ;
2508 // }
2509
2510 DRM_INFO("hdmi tx pclk = %d.%dMHz", it6161->hdmi_tx_pclk / 1000, it6161->hdmi_tx_pclk % 1000);
2511 return it6161->hdmi_tx_pclk;
2512 }
2513
hdmi_tx_get_display_mode(struct it6161 * it6161)2514 static void hdmi_tx_get_display_mode(struct it6161 *it6161)
2515 {
2516 struct drm_display_mode *display_mode = &it6161->hdmi_tx_display_mode;
2517 u32 hsyncpol, vsyncpol, interlaced;
2518 u32 htotal, hdes, hdee, hsyncw, hactive, hfront_porch, H2ndVRRise;
2519 u32 vtotal, vdes, vdee, vsyncw, vactive, vfront_porch, vdes2nd, vdee2nd, vsyncw2nd, VRS2nd;
2520 u32 vdew2nd, vfph2nd, vbph2nd;
2521 u8 rega9;
2522
2523 hdmi_tx_calc_rclk(it6161);
2524 hdmi_tx_calc_pclk(it6161);
2525
2526 /* enable video timing read back */
2527 it6161_hdmi_tx_set_bits(it6161, 0xA8, 0x08, 0x08);
2528
2529 rega9 = it6161_hdmi_tx_read(it6161, 0xa9);
2530
2531 hsyncpol = rega9 & 0x01;
2532 vsyncpol = (rega9 & 0x02) >> 1;
2533 interlaced = (rega9 & 0x04) >> 2;
2534
2535 htotal = hdmi_tx_read_word(it6161, 0x98) & 0x0FFF;
2536 hdes = hdmi_tx_read_word(it6161, 0x90) & 0x0FFF;
2537 hdee = hdmi_tx_read_word(it6161, 0x92) & 0x0FFF;
2538 hsyncw = hdmi_tx_read_word(it6161, 0x94) & 0x0FFF;
2539 hactive = hdee - hdes;
2540 hfront_porch = htotal - hdee;
2541
2542 vtotal = hdmi_tx_read_word(it6161, 0xA6) & 0x0FFF;
2543 vdes = hdmi_tx_read_word(it6161, 0x9C) & 0x0FFF;
2544 vdee = hdmi_tx_read_word(it6161, 0x9E) & 0x0FFF;
2545 vsyncw = it6161_hdmi_tx_read(it6161, 0xA0);
2546 vactive = vdee - vdes;
2547 vfront_porch = (interlaced == 0x01) ? (vtotal / 2 - vdee) : (vtotal - vdee);
2548
2549 display_mode->clock = it6161->hdmi_tx_pclk;
2550 display_mode->hdisplay = hactive;
2551 display_mode->hsync_start = hactive + hfront_porch;
2552 display_mode->hsync_end = hactive + hfront_porch + hsyncw;
2553 display_mode->htotal = htotal;
2554 display_mode->vdisplay = vactive;
2555 display_mode->vsync_start = vactive + vfront_porch;
2556 display_mode->vsync_end = vactive + vfront_porch + vsyncw;
2557 display_mode->vtotal = vtotal;
2558 display_mode->flags = ((hsyncpol == 0x01) ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC) |
2559 ((vsyncpol == 0x01) ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC) |
2560 ((interlaced == 0x01) ? DRM_MODE_FLAG_INTERLACE : 0x00);
2561
2562 if (interlaced) {
2563 vdes2nd = hdmi_tx_read_word(it6161, 0xA2) & 0x0FFF;
2564 vdee2nd = hdmi_tx_read_word(it6161, 0xA4) & 0x0FFF;
2565 VRS2nd = hdmi_tx_read_word(it6161, 0xB1) & 0x0FFF;
2566 vsyncw2nd = it6161_hdmi_tx_read(it6161, 0xA1);
2567 H2ndVRRise = hdmi_tx_read_word(it6161, 0x96) & 0x0FFF;
2568 vdew2nd = vdee2nd-vdes2nd;
2569 vfph2nd = VRS2nd-vdee;
2570 vbph2nd = vdes2nd-VRS2nd-vsyncw2nd;
2571 DRM_INFO("vdew2nd = %d\n", vdew2nd);
2572 DRM_INFO("vfph2nd = %d\n", vfph2nd);
2573 DRM_INFO("VSyncW2nd = %d\n", vsyncw2nd);
2574 DRM_INFO("vbph2nd = %d\n", vbph2nd);
2575 DRM_INFO("H2ndVRRise = %d\n", H2ndVRRise);
2576 }
2577
2578 /* disable video timing read back */
2579 it6161_hdmi_tx_set_bits(it6161, 0xA8, 0x08, 0x00);
2580 }
2581
it6161_hdmi_tx_set_av_mute(struct it6161 * it6161,u8 bEnable)2582 static void it6161_hdmi_tx_set_av_mute(struct it6161 *it6161, u8 bEnable)
2583 {
2584 it6161_hdmi_tx_change_bank(it6161, 0);
2585 it6161_hdmi_tx_set_bits(it6161, REG_TX_GCP,B_TX_SETAVMUTE, bEnable?B_TX_SETAVMUTE:0 );
2586 it6161_hdmi_tx_write(it6161, REG_TX_PKT_GENERAL_CTRL,B_TX_ENABLE_PKT|B_TX_REPEAT_PKT);
2587 }
2588
2589 #ifdef HDCP
2590 #ifdef SUPPORT_SHA
2591 static u8 SHABuff[64] ;
2592 static u8 V[20] ;
2593 static u8 KSVList[32] ;
2594 static u8 Vr[20] ;
2595 static u8 M0[8] ;
2596 #endif
2597
hdmi_tx_hdcp_auth_status(struct it6161 * it6161)2598 static bool hdmi_tx_hdcp_auth_status(struct it6161 *it6161)
2599 {
2600 return !!(it6161_hdmi_tx_read(it6161, REG_TX_AUTH_STAT) & B_TX_AUTH_DONE);
2601 }
2602
hdmi_tx_hdcp_get_auth_done(struct it6161 * it6161)2603 static bool hdmi_tx_hdcp_get_auth_done(struct it6161 *it6161)
2604 {
2605 return hdmiTxDev[0].bAuthenticated;
2606 }
2607
hdmi_tx_hdcp_clear_auth_interrupt(struct it6161 * it6161)2608 static void hdmi_tx_hdcp_clear_auth_interrupt(struct it6161 *it6161)
2609 {
2610 it6161_hdmi_tx_set_bits(it6161, REG_TX_INT_MASK2, B_TX_KSVLISTCHK_MASK | B_TX_AUTH_DONE_MASK | B_TX_AUTH_FAIL_MASK, 0x00);
2611 it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR0, B_TX_CLR_AUTH_FAIL | B_TX_CLR_AUTH_DONE | B_TX_CLR_KSVLISTCHK);
2612 it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR1, 0x00);
2613 it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS, B_TX_INTACTDONE);
2614 }
2615
hdmi_tx_hdcp_reset_auth(struct it6161 * it6161)2616 static void hdmi_tx_hdcp_reset_auth(struct it6161 *it6161)
2617 {
2618 it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, 0x00);
2619 it6161_hdmi_tx_write(it6161, REG_TX_HDCP_DESIRE, 0x00);
2620 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_TX_HDCP_RST_HDMITX, B_TX_HDCP_RST_HDMITX);
2621 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
2622 it6161_hdmi_tx_clear_ddc_fifo(it6161);
2623 it6161_hdmi_tx_abort_ddc(it6161);
2624 }
2625
2626 /* write anything to reg21 to enable HDCP authentication by HW */
2627
hdmi_tx_hdcp_auth_fire(struct it6161 * it6161)2628 static void hdmi_tx_hdcp_auth_fire(struct it6161 *it6161)
2629 {
2630 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHDCP); // MASTERHDCP,no need command but fire.
2631 it6161_hdmi_tx_write(it6161, REG_TX_AUTHFIRE, 0x01);
2632 }
2633
2634 /*
2635 * Start the Cipher to free run for random number. When stop
2636 * An is ready in Reg30
2637 */
2638
hdmi_tx_hdcp_start_an_cipher(struct it6161 * it6161)2639 static void hdmi_tx_hdcp_start_an_cipher(struct it6161 *it6161)
2640 {
2641 it6161_hdmi_tx_write(it6161, REG_TX_AN_GENERATE, B_TX_START_CIPHER_GEN);
2642 }
2643
2644 /* Stop the Cipher,and An is ready in Reg30 */
2645
hdmi_tx_hdcp_stop_an_cipher(struct it6161 * it6161)2646 static void hdmi_tx_hdcp_stop_an_cipher(struct it6161 *it6161)
2647 {
2648 it6161_hdmi_tx_write(it6161, REG_TX_AN_GENERATE, B_TX_STOP_CIPHER_GEN);
2649 }
2650
2651 /*
2652 * start An ciper random run at first,then stop it. Software can get
2653 * An in reg30~reg38,the write to reg28~2F
2654 */
2655
hdmi_tx_hdcp_generate_an(struct it6161 * it6161)2656 static void hdmi_tx_hdcp_generate_an(struct it6161 *it6161)
2657 {
2658 u8 an[DRM_HDCP_AN_LEN], i;
2659
2660 hdmi_tx_hdcp_start_an_cipher(it6161);
2661 usleep_range(2000, 3000);
2662 hdmi_tx_hdcp_stop_an_cipher(it6161);
2663 it6161_hdmi_tx_change_bank(it6161, 0);
2664 /* new An is ready in reg30 */
2665 it6161_hdmi_tx_burst_read(it6161, REG_TX_AN_GEN, an, DRM_HDCP_AN_LEN);
2666
2667 for (i = 0; i < DRM_HDCP_AN_LEN; i++)
2668 it6161_hdmi_tx_write(it6161, REG_TX_AN + i, an[i]);
2669 }
2670
2671 /*
2672 * Parameter: pBCaps - pointer of byte to get BCaps.
2673 * pBStatus - pointer of two bytes to get BStatus
2674 * Return: ER_SUCCESS if successfully got BCaps and BStatus.
2675 * Remark: get B status and capability from HDCP reciever via DDC bus.
2676 */
2677
hdmi_tx_get_hdcp_bcaps_bstatus(struct it6161 * it6161,u8 * pBCaps,u16 * pBStatus)2678 static SYS_STATUS hdmi_tx_get_hdcp_bcaps_bstatus(struct it6161 *it6161, u8 *pBCaps, u16 *pBStatus)
2679 {
2680 int ucdata;
2681
2682 it6161_hdmi_tx_change_bank(it6161, 0);
2683 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST);
2684 it6161_hdmi_tx_write(it6161, REG_TX_DDC_HEADER,DDC_HDCP_ADDRESS);
2685 it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQOFF,0x40); // BCaps offset
2686 it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQCOUNT,3);
2687 it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD);
2688
2689 ucdata = it6161_ddc_wait(it6161);
2690
2691 if (ucdata < 0) {
2692 DRM_INFO("get bcaps/bstatus failed");
2693 return ER_FAIL;
2694 }
2695
2696 #if 1
2697 ucdata = it6161_hdmi_tx_read(it6161, REG_TX_BSTAT + 1);
2698 *pBStatus = (u16)ucdata;
2699 *pBStatus <<= 8;
2700 ucdata = it6161_hdmi_tx_read(it6161, REG_TX_BSTAT);
2701 *pBStatus |= ((u16)ucdata & 0xFF);
2702 *pBCaps = it6161_hdmi_tx_read(it6161, REG_TX_BCAP);
2703 #else
2704 *pBCaps = it6161_hdmi_tx_read(it6161, 0x17);
2705 *pBStatus = it6161_hdmi_tx_read(it6161, 0x17) & 0xFF ;
2706 *pBStatus |= (int)(it6161_hdmi_tx_read(it6161, 0x17)&0xFF)<<8;
2707 DRM_INFO("hdmi_tx_get_hdcp_bcaps_bstatus(): ucdata = %02X\n",(int)it6161_hdmi_tx_read(it6161, 0x16));
2708 #endif
2709 #ifdef _SUPPORT_HDCP_REPEATER_
2710 TxBstatus = *pBStatus;
2711 #endif
2712 return ER_SUCCESS;
2713 }
2714
2715 /* Get bksv from HDCP sink */
2716
hdmi_tx_hdcp_get_bksv(struct it6161 * it6161,u8 * bksv,size_t size)2717 static int hdmi_tx_hdcp_get_bksv(struct it6161 *it6161, u8 *bksv, size_t size)
2718 {
2719 int ret;
2720 #ifdef _SUPPORT_HDMI_REPEATER_
2721 int timeout;
2722 #endif
2723
2724 hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_BKSV, size, 0x00, CMD_DDC_SEQ_BURSTREAD);
2725
2726 ret = it6161_ddc_wait(it6161);
2727
2728 if (ret < 0) {
2729 DRM_INFO("ddc get bksv failed");
2730 return ret;
2731 }
2732
2733 ret = it6161_hdmi_tx_burst_read(it6161, REG_TX_BKSV, bksv, size);
2734
2735 if (ret < 0)
2736 DRM_INFO("i2c get bksv failed");
2737
2738 return ret;
2739
2740 #ifdef _SUPPORT_HDMI_REPEATER_
2741 for (timeout = 0; timeout < 5; timeout++)
2742 KSVList[timeout] = *(bksv+timeout);
2743 #endif
2744 }
2745
countbit(u8 b)2746 static u8 countbit(u8 b)
2747 {
2748 u8 i, count ;
2749
2750 for (i = 0, count = 0; i < 8; i++) {
2751 if (b & (1 << i))
2752 count++;
2753 }
2754
2755 return count;
2756 }
2757
hdmitx_hdcp_CancelRepeaterAuthenticate(struct it6161 * it6161)2758 static void hdmitx_hdcp_CancelRepeaterAuthenticate(struct it6161 *it6161)
2759 {
2760 it6161_debug("hdmitx_hdcp_CancelRepeaterAuthenticate");
2761 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
2762 it6161_hdmi_tx_abort_ddc(it6161);
2763 it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, B_TX_LISTFAIL | B_TX_LISTDONE);
2764 it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, 0x00);
2765 hdmi_tx_hdcp_clear_auth_interrupt(it6161);
2766 }
2767
hdmitx_hdcp_ResumeRepeaterAuthenticate(struct it6161 * it6161)2768 static void hdmitx_hdcp_ResumeRepeaterAuthenticate(struct it6161 *it6161)
2769 {
2770 it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, B_TX_LISTDONE);
2771 it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, 0x00);
2772 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERHDCP);
2773 }
2774
2775 #define WCOUNT 17
2776 u32 VH[5];
2777 u32 w[WCOUNT];
2778
2779 #define rol(x,y)(((x)<< (y))| (((u32)x)>> (32-y)))
2780
SHATransform(u32 * h)2781 static void SHATransform(u32 * h)
2782 {
2783 int t;
2784 u32 tmp;
2785
2786 h[0]=0x67452301;
2787 h[1]=0xefcdab89;
2788 h[2]=0x98badcfe;
2789 h[3]=0x10325476;
2790 h[4]=0xc3d2e1f0;
2791
2792 for (t=0; t < 20; t++){
2793 if(t>=16)
2794 {
2795 tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT];
2796 w[(t)% WCOUNT]=rol(tmp,1);
2797 }
2798 DRM_INFO("w[%d]=%08X\n",t,w[(t)% WCOUNT]);
2799
2800 tmp=rol(h[0],5)+ ((h[1] & h[2])| (h[3] & ~h[1]))+ h[4] + w[(t)% WCOUNT] + 0x5a827999;
2801 DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2802
2803 h[4]=h[3];
2804 h[3]=h[2];
2805 h[2]=rol(h[1],30);
2806 h[1]=h[0];
2807 h[0]=tmp;
2808
2809 }
2810 for (t=20; t < 40; t++){
2811 tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT];
2812 w[(t)% WCOUNT]=rol(tmp,1);
2813 DRM_INFO("w[%d]=%08X\n",t,w[(t)% WCOUNT]);
2814 tmp=rol(h[0],5)+ (h[1] ^ h[2] ^ h[3])+ h[4] + w[(t)% WCOUNT] + 0x6ed9eba1;
2815 DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2816 h[4]=h[3];
2817 h[3]=h[2];
2818 h[2]=rol(h[1],30);
2819 h[1]=h[0];
2820 h[0]=tmp;
2821 }
2822 for (t=40; t < 60; t++){
2823 tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT];
2824 w[(t)% WCOUNT]=rol(tmp,1);
2825 DRM_INFO("w[%d]=%08X\n",t,w[(t)% WCOUNT]);
2826 tmp=rol(h[0],5)+ ((h[1] & h[2])| (h[1] & h[3])| (h[2] & h[3]))+ h[4] + w[(t)% WCOUNT] + 0x8f1bbcdc;
2827 DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2828 h[4]=h[3];
2829 h[3]=h[2];
2830 h[2]=rol(h[1],30);
2831 h[1]=h[0];
2832 h[0]=tmp;
2833 }
2834 for (t=60; t < 80; t++)
2835 {
2836 tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT];
2837 w[(t)% WCOUNT]=rol(tmp,1);
2838 DRM_INFO("w[%d]=%08X\n",t,w[(t)% WCOUNT]);
2839 tmp=rol(h[0],5)+ (h[1] ^ h[2] ^ h[3])+ h[4] + w[(t)% WCOUNT] + 0xca62c1d6;
2840 DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2841 h[4]=h[3];
2842 h[3]=h[2];
2843 h[2]=rol(h[1],30);
2844 h[1]=h[0];
2845 h[0]=tmp;
2846 }
2847 DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2848 h[0] +=0x67452301;
2849 h[1] +=0xefcdab89;
2850 h[2] +=0x98badcfe;
2851 h[3] +=0x10325476;
2852 h[4] +=0xc3d2e1f0;
2853
2854 DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2855 }
2856
SHA_Simple(void * p,u32 len,u8 * output)2857 static void SHA_Simple(void *p,u32 len,u8 *output)
2858 {
2859 // SHA_State s;
2860 u32 i,t;
2861 u32 c;
2862 u8 *pBuff=p;
2863
2864 for(i=0;i < len;i++)
2865 {
2866 t=i/4;
2867 if(i%4==0)
2868 {
2869 w[t]=0;
2870 }
2871 c=pBuff[i];
2872 c <<=(3-(i%4))*8;
2873 w[t] |=c;
2874 DRM_INFO("pBuff[%d]=%02X,c=%08X,w[%d]=%08X\n",(int)i,(int)pBuff[i],c,(int)t,w[t]);
2875 }
2876 t=i/4;
2877 if(i%4==0)
2878 {
2879 w[t]=0;
2880 }
2881 //c=0x80 << ((3-i%4)*24);
2882 c=0x80;
2883 c <<=((3-i%4)*8);
2884 w[t]|=c;t++;
2885 for(; t < 15;t++)
2886 {
2887 w[t]=0;
2888 }
2889 w[15]=len*8;
2890
2891 for(i = 0; i < 16; i++)
2892 {
2893 DRM_INFO("w[%d] = %08X\n",i,w[i]);
2894 }
2895 SHATransform(VH);
2896
2897 for(i=0;i < 5;i++)
2898 {
2899 output[i*4+3]=(u8)((VH[i]>>24)&0xFF);
2900 output[i*4+2]=(u8)((VH[i]>>16)&0xFF);
2901 output[i*4+1]=(u8)((VH[i]>>8)&0xFF);
2902 output[i*4+0]=(u8)(VH[i]&0xFF);
2903 }
2904 }
2905
2906 #ifdef SUPPORT_SHA
2907
hdmitx_hdcp_CheckSHA(u8 pM0[],u16 BStatus,u8 pKSVList[],int cDownStream,u8 Vr[])2908 static SYS_STATUS hdmitx_hdcp_CheckSHA(u8 pM0[],u16 BStatus,u8 pKSVList[],int cDownStream,u8 Vr[])
2909 {
2910 int i,n ;
2911
2912 for(i = 0 ; i < cDownStream*5 ; i++)
2913 {
2914 SHABuff[i] = pKSVList[i] ;
2915 }
2916 SHABuff[i++] = BStatus & 0xFF ;
2917 SHABuff[i++] = (BStatus>>8) & 0xFF ;
2918 for(n = 0 ; n < 8 ; n++,i++)
2919 {
2920 SHABuff[i] = pM0[n] ;
2921 }
2922 n = i ;
2923 // SHABuff[i++] = 0x80 ; // end mask
2924 for(; i < 64 ; i++)
2925 {
2926 SHABuff[i] = 0 ;
2927 }
2928 // n = cDownStream * 5 + 2 /* for BStatus */ + 8 /* for M0 */ ;
2929 // n *= 8 ;
2930 // SHABuff[62] = (n>>8) & 0xff ;
2931 // SHABuff[63] = (n>>8) & 0xff ;
2932 /*
2933 for(i = 0 ; i < 64 ; i++)
2934 {
2935 if(i % 16 == 0)
2936 {
2937 DRM_INFO("SHA[]: ");
2938 }
2939 DRM_INFO(" %02X",SHABuff[i]);
2940 if((i%16)==15)
2941 {
2942 DRM_INFO("\n");
2943 }
2944 }
2945 */
2946 SHA_Simple(SHABuff,n,V);
2947 for(i = 0 ; i < 20 ; i++)
2948 {
2949 if(V[i] != Vr[i])
2950 {
2951 DRM_INFO("V[] =");
2952 for(i = 0 ; i < 20 ; i++)
2953 {
2954 DRM_INFO(" %02X",(int)V[i]);
2955 }
2956 DRM_INFO("\nVr[] =");
2957 for(i = 0 ; i < 20 ; i++)
2958 {
2959 DRM_INFO(" %02X",(int)Vr[i]);
2960 }
2961 return ER_FAIL ;
2962 }
2963 }
2964 return ER_SUCCESS ;
2965 }
2966
2967 #endif // SUPPORT_SHA
2968
hdmi_tx_hdcp_get_ksv_list(struct it6161 * it6161,u8 * pKSVList,u8 cDownStream)2969 static SYS_STATUS hdmi_tx_hdcp_get_ksv_list(struct it6161 *it6161, u8 *pKSVList,u8 cDownStream)
2970 {
2971 u8 timeout = 100, ucdata;
2972
2973 if( cDownStream == 0 )
2974 {
2975 return ER_SUCCESS ;
2976 }
2977 if( /* cDownStream == 0 || */ pKSVList == NULL)
2978 {
2979 return ER_FAIL ;
2980 }
2981 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERHOST);
2982 it6161_hdmi_tx_write(it6161, REG_TX_DDC_HEADER, 0x74);
2983 it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQOFF, 0x43);
2984 it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQCOUNT, cDownStream * 5);
2985 it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, CMD_DDC_SEQ_BURSTREAD);
2986
2987 ucdata = it6161_ddc_wait(it6161);
2988
2989 if (ucdata < 0)
2990 {
2991 return ER_FAIL ;
2992 }
2993 DRM_INFO("hdmi_tx_hdcp_get_ksv_list(): KSV");
2994 for(timeout = 0 ; timeout < cDownStream * 5 ; timeout++)
2995 {
2996 pKSVList[timeout] = it6161_hdmi_tx_read(it6161, REG_TX_DDC_READFIFO);
2997 #ifdef _SUPPORT_HDCP_REPEATER_
2998 KSVList[timeout] = pKSVList[timeout];
2999 DRM_INFO(" %x",(int)pKSVList[timeout]);
3000 DRM_INFO(" %02X",(int)pKSVList[timeout]);
3001 #endif
3002 }
3003
3004 return ER_SUCCESS ;
3005 }
3006
hdmitx_hdcp_GetVr(struct it6161 * it6161,u8 * pVr)3007 static SYS_STATUS hdmitx_hdcp_GetVr(struct it6161 *it6161, u8 *pVr)
3008 {
3009 u8 timeout, ucdata;
3010
3011 if(pVr == NULL)
3012 {
3013 return ER_FAIL ;
3014 }
3015 it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL,B_TX_MASTERHOST);
3016 it6161_hdmi_tx_write(it6161, REG_TX_DDC_HEADER,0x74);
3017 it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQOFF,0x20);
3018 it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQCOUNT,20);
3019 it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD);
3020
3021 ucdata = it6161_ddc_wait(it6161);
3022 if (ucdata < 0)
3023 {
3024 DRM_INFO("hdmitx_hdcp_GetVr(): DDC fail by timeout.\n");
3025 return ER_FAIL ;
3026 }
3027 it6161_hdmi_tx_change_bank(it6161, 0);
3028
3029 for(timeout = 0 ; timeout < 5 ; timeout++)
3030 {
3031 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL ,timeout);
3032 pVr[timeout*4] = (u32)it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE1);
3033 pVr[timeout*4+1] = (u32)it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE2);
3034 pVr[timeout*4+2] = (u32)it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE3);
3035 pVr[timeout*4+3] = (u32)it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE4);
3036 // DRM_INFO("V' = %02X %02X %02X %02X\n",(int)pVr[timeout*4],(int)pVr[timeout*4+1],(int)pVr[timeout*4+2],(int)pVr[timeout*4+3]);
3037 }
3038 return ER_SUCCESS ;
3039 }
3040
hdmitx_hdcp_GetM0(struct it6161 * it6161,u8 * pM0)3041 static SYS_STATUS hdmitx_hdcp_GetM0(struct it6161 *it6161, u8 *pM0)
3042 {
3043 int i ;
3044
3045 if(!pM0)
3046 {
3047 return ER_FAIL ;
3048 }
3049 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,5); // read m0[31:0] from reg51~reg54
3050 pM0[0] = it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE1);
3051 pM0[1] = it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE2);
3052 pM0[2] = it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE3);
3053 pM0[3] = it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE4);
3054 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,0); // read m0[39:32] from reg55
3055 pM0[4] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3056 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,1); // read m0[47:40] from reg55
3057 pM0[5] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3058 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,2); // read m0[55:48] from reg55
3059 pM0[6] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3060 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,3); // read m0[63:56] from reg55
3061 pM0[7] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3062
3063 DRM_INFO("M[] =");
3064 for(i = 0 ; i < 8 ; i++)
3065 {
3066 DRM_INFO("0x%02x,",(int)pM0[i]);
3067 }
3068 DRM_INFO("\n");
3069 return ER_SUCCESS ;
3070 }
3071
3072 #ifdef _SUPPORT_HDCP_REPEATER_
3073
TxHDCP_chg(HDMITX_HDCP_State state)3074 static void TxHDCP_chg(HDMITX_HDCP_State state)
3075 {
3076 if( state == hdmiTxDev[0].TxHDCP_State )
3077 {
3078 return ;
3079 }
3080 DRM_INFO("TxHDCP %d -> %d\n",hdmiTxDev[0].TxHDCP_State,state);
3081 hdmiTxDev[0].TxHDCP_State = state ;
3082
3083 switch(state)
3084 {
3085 case TxHDCP_Off:
3086 hdmiTxDev[0].bAuthenticated=false;
3087 hdmiTxDev[0].usHDCPTimeOut = 0 ;
3088 hdmi_tx_hdcp_reset_auth(it6161);
3089 break;
3090
3091 case TxHDCP_AuthRestart:
3092 hdmiTxDev[0].bAuthenticated = false ;
3093 hdmi_tx_hdcp_reset_auth(it6161);
3094 hdmiTxDev[0].usHDCPTimeOut = 5 ;
3095 break;
3096
3097 case TxHDCP_AuthStart:
3098 hdmi_tx_hdcp_reset_auth(it6161);
3099 hdmiTxDev[0].bAuthenticated = false ;
3100 hdmiTxDev[0].usHDCPTimeOut = 80 ;
3101 break;
3102
3103 case TxHDCP_Receiver:
3104 hdmiTxDev[0].usHDCPTimeOut = 250 ; // set the count as the 5000ms/interval
3105 break;
3106
3107 case TxHDCP_Repeater:
3108 hdmiTxDev[0].usHDCPTimeOut = 250 ; // set the count as the 5000ms/interval
3109 break;
3110
3111 case TxHDCP_CheckFIFORDY:
3112
3113 hdmiTxDev[0].usHDCPTimeOut = 300 ; // set the count as the 6000ms/interval
3114 break;
3115
3116 case TxHDCP_VerifyRevocationList:
3117 break;
3118
3119
3120 case TxHDCP_AuthFail:
3121 hdmi_tx_hdcp_reset_auth(it6161);
3122 hdmiTxDev[0].bAuthenticated = false ;
3123 break;
3124
3125 case TxHDCP_RepeaterFail:
3126 hdmitx_hdcp_CancelRepeaterAuthenticate(it6161);
3127 hdmi_tx_hdcp_reset_auth(it6161);
3128 hdmiTxDev[0].bAuthenticated = false ;
3129 break;
3130
3131 case TxHDCP_RepeaterSuccess:
3132 hdmitx_hdcp_ResumeRepeaterAuthenticate(it6161);
3133 case TxHDCP_Authenticated:
3134 it6161_hdmi_tx_set_av_mute(it6161, false) ;
3135 hdmiTxDev[0].bAuthenticated = true ;
3136 break;
3137
3138 }
3139 }
3140
TxHDCP_fsm()3141 static void TxHDCP_fsm()
3142 {
3143 u8 ucdata ;
3144 int i ;
3145
3146 static u8 BCaps ;
3147 static u16 BStatus ;
3148 static u8 cDownStream ;// this value will be use in the function....
3149 static u8 bksv[5] ;
3150
3151
3152 switch(hdmiTxDev[0].TxHDCP_State)
3153 {
3154 case TxHDCP_Off:
3155 break;
3156
3157 case TxHDCP_AuthRestart:
3158 if(hdmiTxDev[0].usHDCPTimeOut>0)
3159 {
3160 hdmiTxDev[0].usHDCPTimeOut -- ;
3161 }
3162 if( hdmiTxDev[0].usHDCPTimeOut == 0 )
3163 {
3164 TxHDCP_chg(TxHDCP_AuthStart) ;
3165 }
3166 break;
3167
3168 case TxHDCP_AuthStart:
3169 cDownStream = 0 ;
3170 it6161_hdmi_tx_change_bank(it6161, 0);
3171 if(hdmiTxDev[0].usHDCPTimeOut>0)
3172 {
3173 hdmiTxDev[0].usHDCPTimeOut -- ;
3174 ucdata = it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS)& (B_TX_HPDETECT|B_TX_RXSENDETECT);
3175
3176 if(ucdata != (B_TX_HPDETECT|B_TX_RXSENDETECT))
3177 {
3178 // if no Rx sense, do not start authentication.
3179 // Eventhough start it, cannot work.
3180 return ;
3181 }
3182
3183 if(hdmi_tx_get_hdcp_bcaps_bstatus(it6161, &BCaps,&BStatus) != ER_SUCCESS)
3184 {
3185 DRM_INFO("hdmi_tx_get_hdcp_bcaps_bstatus fail.\n");
3186 return;
3187 }
3188 // wait for HDMI State
3189
3190 if(B_TX_HDMI_MODE == (it6161_hdmi_tx_read(it6161, REG_TX_HDMI_MODE) & B_TX_HDMI_MODE ))
3191 {
3192 if((BStatus & B_TX_CAP_HDMI_MODE)!=B_TX_CAP_HDMI_MODE)
3193 {
3194 return;
3195 }
3196 }
3197 else
3198 {
3199 if((BStatus & B_TX_CAP_HDMI_MODE)==B_TX_CAP_HDMI_MODE)
3200 {
3201 return ;
3202 }
3203 }
3204
3205 }
3206 else
3207 {
3208 TxHDCP_chg(TxHDCP_AuthRestart) ;
3209 }
3210
3211 DRM_INFO("BCAPS = %x BSTATUS = %X\n", (int)BCaps, BStatus);
3212 hdmi_tx_hdcp_get_bksv(it6161, bksv, ARRAY_SIZE(bksv));
3213 DRM_INFO("bksv %X %X %X %X %X\n",(int)bksv[0],(int)bksv[1],(int)bksv[2],(int)bksv[3],(int)bksv[4]);
3214
3215 for(i = 0, ucdata = 0 ; i < 5 ; i ++)
3216 {
3217 ucdata += countbit(bksv[i]);
3218 }
3219 if( ucdata != 20 )
3220 {
3221 DRM_INFO("countbit error\n");
3222 TxHDCP_chg(TxHDCP_AuthFail) ;
3223 return ;
3224
3225 }
3226
3227 it6161_hdmi_tx_change_bank(it6161, 0); // switch bank action should start on direct register writting of each function.
3228
3229 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_TX_HDCP_RST_HDMITX, 0x00);
3230
3231 it6161_hdmi_tx_write(it6161, REG_TX_HDCP_DESIRE,8|B_TX_CPDESIRE);
3232 hdmi_tx_hdcp_clear_auth_interrupt(it6161);
3233
3234 hdmi_tx_hdcp_generate_an(it6161);
3235 it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL,0);
3236 hdmiTxDev[0].bAuthenticated = false ;
3237
3238 it6161_hdmi_tx_clear_ddc_fifo(it6161);
3239 hdmi_tx_hdcp_auth_fire(it6161);
3240 hdmiTxDev[0].Tx_BStatus = BStatus ;
3241 if(BCaps & B_TX_CAP_HDMI_REPEATER)
3242 {
3243 TxHDCP_chg(TxHDCP_Repeater) ;
3244 }
3245 else
3246 {
3247
3248 for(i = 0; i < 5 ; i ++)
3249 {
3250 KSVList[i] = bksv[i] ;
3251 }
3252 TxHDCP_chg(TxHDCP_Receiver) ;
3253 }
3254 break;
3255
3256 case TxHDCP_Receiver:
3257
3258 if(hdmiTxDev[0].usHDCPTimeOut >0)
3259 {
3260 hdmiTxDev[0].usHDCPTimeOut -- ;
3261 }
3262
3263 if(hdmiTxDev[0].usHDCPTimeOut==0)
3264 {
3265 TxHDCP_chg(TxHDCP_AuthFail) ;
3266 return ;
3267 }
3268 else
3269 {
3270 DRM_INFO("[Fsm] Receiver: usHDCPTimeOut = %d\n",hdmiTxDev[0].usHDCPTimeOut);
3271 ucdata = it6161_hdmi_tx_read(it6161, REG_TX_AUTH_STAT);
3272 DRM_INFO("[Fsm] Receiver: ucdata = %X, BStatus = %X\n",ucdata,BStatus);
3273
3274 if(ucdata & B_TX_AUTH_DONE)
3275 {
3276 //BStatus += 0x101 ;
3277 IT680X_DownStream_AuthDoneCallback(bksv, BStatus);
3278 TxHDCP_chg(TxHDCP_Authenticated) ;
3279 break ;
3280 }
3281 }
3282 break;
3283
3284 case TxHDCP_Repeater:
3285 if(hdmiTxDev[0].usHDCPTimeOut >0)
3286 {
3287 hdmiTxDev[0].usHDCPTimeOut -- ;
3288 }
3289
3290 if(hdmiTxDev[0].usHDCPTimeOut==0)
3291 {
3292 TxHDCP_chg(TxHDCP_AuthFail) ;
3293 return ;
3294 }
3295 break;
3296
3297 case TxHDCP_CheckFIFORDY:
3298 if(hdmiTxDev[0].usHDCPTimeOut >0)
3299 {
3300 hdmiTxDev[0].usHDCPTimeOut -- ;
3301 }
3302
3303 if(hdmiTxDev[0].usHDCPTimeOut==0)
3304 {
3305 TxHDCP_chg(TxHDCP_RepeaterFail) ;
3306 return ;
3307 }
3308
3309 if(hdmi_tx_get_hdcp_bcaps_bstatus(it6161, &BCaps,&BStatus) == ER_FAIL)
3310 {
3311 DRM_INFO("Get BCaps fail\n");
3312 break ; // get fail, again.
3313 }
3314
3315
3316 if(BCaps & B_TX_CAP_KSV_FIFO_RDY)
3317 {
3318 DRM_INFO("FIFO Ready\n");
3319
3320
3321 it6161_hdmi_tx_clear_ddc_fifo(it6161);
3322 it6161_hdmi_tx_generate_ddc_sclk(it6161);
3323 hdmiTxDev[0].Tx_BStatus = BStatus ;
3324 cDownStream=(BStatus & M_TX_DOWNSTREAM_COUNT);
3325 //+++++++++++++++++++++++++++++++++++++
3326 DRM_INFO("Downstream=%X \n",cDownStream);
3327
3328 if( cDownStream > (MAX_REPEATER_DOWNSTREAM_COUNT-1))
3329 {
3330 hdmiTxDev[0].Tx_BStatus |= B_TX_DOWNSTREAM_OVER ;
3331 }
3332 if( cDownStream > (MAX_REPEATER_DOWNSTREAM_COUNT-1) ||
3333 BStatus & (B_TX_MAX_CASCADE_EXCEEDED|B_TX_DOWNSTREAM_OVER))
3334 {
3335 DRM_INFO("Invalid Down stream count,fail\n");
3336
3337 // RxAuthSetBStatus(B_DOWNSTREAM_OVER|B_MAX_CASCADE_EXCEEDED); //for ALLION HDCP 3C-2-06
3338 // ForceKSVFIFOReady(B_DOWNSTREAM_OVER|B_MAX_CASCADE_EXCEEDED) ;
3339 IT680X_DownStream_AuthDoneCallback(KSVList, 0xFFF);
3340 TxHDCP_chg(TxHDCP_RepeaterFail);
3341 break;
3342 }
3343
3344 TxHDCP_chg(TxHDCP_VerifyRevocationList) ;
3345 break ;
3346 }
3347
3348 break;
3349
3350 case TxHDCP_VerifyRevocationList:
3351
3352 #ifdef SUPPORT_SHA
3353 DRM_INFO("TxHDCP_VerifyRevocationList: cDownStream = %d",cDownStream);
3354 if(hdmi_tx_hdcp_get_ksv_list(it6161, KSVList,cDownStream) == ER_FAIL)
3355 {
3356 DRM_INFO("hdmitx_hdcp_Repeater_Fail 2\n");
3357 TxHDCP_chg(TxHDCP_RepeaterFail);
3358 break;
3359 }
3360
3361 if(hdmitx_hdcp_GetVr(it6161, Vr) == ER_FAIL)
3362 {
3363 DRM_INFO("hdmitx_hdcp_Repeater_Fail 3\n");
3364 TxHDCP_chg(TxHDCP_RepeaterFail);
3365 break;
3366 }
3367 if(hdmitx_hdcp_GetM0(it6161, M0) == ER_FAIL)
3368 {
3369 DRM_INFO("hdmitx_hdcp_Repeater_Fail 4\n");
3370 TxHDCP_chg(TxHDCP_RepeaterFail);
3371 break;
3372 }
3373 // do check SHA
3374 if(hdmitx_hdcp_CheckSHA(M0,BStatus,KSVList,cDownStream,Vr) == ER_FAIL)
3375 {
3376 DRM_INFO("hdmitx_hdcp_Repeater_Fail 5\n");
3377 TxHDCP_chg(TxHDCP_RepeaterFail);
3378 break;
3379 }
3380 #endif // SUPPORT_SHA
3381 // checkSHA success, append the bksv to KSV List
3382 for(i = 0; i < 5 ; i ++)
3383 {
3384 KSVList[cDownStream*5+i] = bksv[i] ;
3385 }
3386
3387 for( i = 0 ; i < ((cDownStream+1)*5) ; i ++ )
3388 {
3389 DRM_INFO("KSVLIST[%d] = %X\n",i,KSVList[i]);
3390 }
3391
3392 //BStatus += 0x101 ;
3393 IT680X_DownStream_AuthDoneCallback(KSVList, BStatus);
3394
3395 TxHDCP_chg(TxHDCP_RepeaterSuccess) ;
3396 break;
3397
3398
3399 case TxHDCP_Authenticated:
3400 break;
3401
3402 case TxHDCP_AuthFail:
3403 // force revoke the KSVList
3404 // IT680X_DownStream_AuthDoneCallback(KSVList, 0xFFF);
3405 TxHDCP_chg(TxHDCP_AuthRestart);
3406 break;
3407
3408 case TxHDCP_RepeaterFail:
3409 TxHDCP_chg(TxHDCP_AuthFail);
3410 break;
3411
3412 case TxHDCP_RepeaterSuccess:
3413 TxHDCP_chg(TxHDCP_Authenticated);
3414 break;
3415
3416 }
3417 }
3418
3419 #else
3420
3421 //////////////////////////////////////////////////////////////////////
3422 // Function: hdmi_tx_hdcp_auth_process_Repeater
3423 // Parameter: BCaps and BStatus
3424 // Return: ER_SUCCESS if success,if AUTH_FAIL interrupt status,return fail.
3425 // Remark:
3426 // Side-Effect: as Authentication
3427 //////////////////////////////////////////////////////////////////////
3428 #ifdef HDCP
hdmi_tx_hdcp_auth_process_Repeater(struct it6161 * it6161)3429 static SYS_STATUS hdmi_tx_hdcp_auth_process_Repeater(struct it6161 *it6161)
3430 {
3431 u8 uc ,ii;
3432 // u8 revoked ;
3433 // int i ;
3434 u8 cDownStream ;
3435
3436 u8 BCaps;
3437 u16 BStatus ;
3438 u16 timeout ;
3439
3440 DRM_INFO("Authentication for repeater\n");
3441 // emily add for test,abort HDCP
3442 // 2007/10/01 marked by jj_tseng@chipadvanced.com
3443 // it6161_hdmi_tx_write(it6161, 0x20,0x00);
3444 // it6161_hdmi_tx_write(it6161, 0x04,0x01);
3445 // it6161_hdmi_tx_write(it6161, 0x10,0x01);
3446 // it6161_hdmi_tx_write(it6161, 0x15,0x0F);
3447 // msleep(100);
3448 // it6161_hdmi_tx_write(it6161, 0x04,0x00);
3449 // it6161_hdmi_tx_write(it6161, 0x10,0x00);
3450 // it6161_hdmi_tx_write(it6161, 0x20,0x01);
3451 // msleep(100);
3452 // test07 = it6161_hdmi_tx_read(it6161, 0x7);
3453 // test06 = it6161_hdmi_tx_read(it6161, 0x6);
3454 // test08 = it6161_hdmi_tx_read(it6161, 0x8);
3455 //~jj_tseng@chipadvanced.com
3456 // end emily add for test
3457 //////////////////////////////////////
3458 // Authenticate Fired
3459 //////////////////////////////////////
3460
3461 hdmi_tx_get_hdcp_bcaps_bstatus(it6161, &BCaps,&BStatus);
3462 msleep(2);
3463 if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3464 {
3465 DRM_INFO("HPD Before Fire Auth\n");
3466 goto hdmitx_hdcp_Repeater_Fail ;
3467 }
3468 hdmi_tx_hdcp_auth_fire(it6161);
3469 //msleep(550); // emily add for test
3470 for(ii=0;ii<55;ii++) //msleep(550); // emily add for test
3471 {
3472 if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3473 {
3474 goto hdmitx_hdcp_Repeater_Fail ;
3475 }
3476 msleep(10);
3477 }
3478 for(timeout = /*250*6*/10 ; timeout > 0 ; timeout --)
3479 {
3480 DRM_INFO("timeout = %d wait part 1\n",timeout);
3481 if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3482 {
3483 DRM_INFO("HPD at wait part 1\n");
3484 goto hdmitx_hdcp_Repeater_Fail ;
3485 }
3486 uc = it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1);
3487 if(uc & B_TX_INT_DDC_BUS_HANG)
3488 {
3489 DRM_INFO("DDC Bus hang\n");
3490 goto hdmitx_hdcp_Repeater_Fail ;
3491 }
3492 uc = it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT2);
3493
3494 if(uc & B_TX_INT_AUTH_FAIL)
3495 {
3496 /*
3497 it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR0,B_TX_CLR_AUTH_FAIL);
3498 it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR1,0);
3499 it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS,B_TX_INTACTDONE);
3500 it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS,0);
3501 */
3502 DRM_INFO("hdmi_tx_hdcp_auth_process_Repeater(): B_TX_INT_AUTH_FAIL.\n");
3503 goto hdmitx_hdcp_Repeater_Fail ;
3504 }
3505 // emily add for test
3506 // test =(it6161_hdmi_tx_read(it6161, 0x7)&0x4)>>2 ;
3507 if(uc & B_TX_INT_KSVLIST_CHK)
3508 {
3509 it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR0,B_TX_CLR_KSVLISTCHK);
3510 it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR1,0);
3511 it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS,B_TX_INTACTDONE);
3512 it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS,0);
3513 DRM_INFO("B_TX_INT_KSVLIST_CHK\n");
3514 break ;
3515 }
3516 msleep(5);
3517 }
3518 if(timeout == 0)
3519 {
3520 DRM_INFO("Time out for wait KSV List checking interrupt\n");
3521 goto hdmitx_hdcp_Repeater_Fail ;
3522 }
3523 ///////////////////////////////////////
3524 // clear KSVList check interrupt.
3525 ///////////////////////////////////////
3526
3527 for(timeout = 500 ; timeout > 0 ; timeout --)
3528 {
3529 DRM_INFO("timeout=%d at wait FIFO ready\n",timeout);
3530 if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3531 {
3532 DRM_INFO("HPD at wait FIFO ready\n");
3533 goto hdmitx_hdcp_Repeater_Fail ;
3534 }
3535 if(hdmi_tx_get_hdcp_bcaps_bstatus(it6161, &BCaps,&BStatus) == ER_FAIL)
3536 {
3537 DRM_INFO("Get BCaps fail\n");
3538 goto hdmitx_hdcp_Repeater_Fail ;
3539 }
3540 if(BCaps & B_TX_CAP_KSV_FIFO_RDY)
3541 {
3542 DRM_INFO("FIFO Ready\n");
3543 break ;
3544 }
3545 msleep(5);
3546
3547 }
3548 if(timeout == 0)
3549 {
3550 DRM_INFO("Get KSV FIFO ready timeout\n");
3551 goto hdmitx_hdcp_Repeater_Fail ;
3552 }
3553 DRM_INFO("Wait timeout = %d\n",timeout);
3554
3555 it6161_hdmi_tx_clear_ddc_fifo(it6161);
3556 it6161_hdmi_tx_generate_ddc_sclk(it6161);
3557 cDownStream = (BStatus & M_TX_DOWNSTREAM_COUNT);
3558
3559 if(/*cDownStream == 0 ||*/ cDownStream > 6 || BStatus & (B_TX_MAX_CASCADE_EXCEEDED|B_TX_DOWNSTREAM_OVER))
3560 {
3561 DRM_INFO("Invalid Down stream count,fail\n");
3562 goto hdmitx_hdcp_Repeater_Fail ;
3563 }
3564 #ifdef SUPPORT_SHA
3565 if(hdmi_tx_hdcp_get_ksv_list(it6161, KSVList,cDownStream) == ER_FAIL)
3566 {
3567 goto hdmitx_hdcp_Repeater_Fail ;
3568 }
3569 #if 0
3570 for(i = 0 ; i < cDownStream ; i++)
3571 {
3572 revoked=false ; uc = 0 ;
3573 for( timeout = 0 ; timeout < 5 ; timeout++ )
3574 {
3575 // check bit count
3576 uc += countbit(KSVList[i*5+timeout]);
3577 }
3578 if( uc != 20 ) revoked = true ;
3579
3580 if(revoked)
3581 {
3582 DRM_INFO("KSVFIFO[%d] = %02X %02X %02X %02X %02X is revoked\n",i,(int)KSVList[i*5],(int)KSVList[i*5+1],(int)KSVList[i*5+2],(int)KSVList[i*5+3],(int)KSVList[i*5+4]);
3583 goto hdmitx_hdcp_Repeater_Fail ;
3584 }
3585 }
3586 #endif
3587
3588 if(hdmitx_hdcp_GetVr(it6161, Vr) == ER_FAIL)
3589 {
3590 goto hdmitx_hdcp_Repeater_Fail ;
3591 }
3592 if(hdmitx_hdcp_GetM0(it6161, M0) == ER_FAIL)
3593 {
3594 goto hdmitx_hdcp_Repeater_Fail ;
3595 }
3596 // do check SHA
3597 if(hdmitx_hdcp_CheckSHA(M0,BStatus,KSVList,cDownStream,Vr) == ER_FAIL)
3598 {
3599 goto hdmitx_hdcp_Repeater_Fail ;
3600 }
3601 if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3602 {
3603 DRM_INFO("HPD at Final\n");
3604 goto hdmitx_hdcp_Repeater_Fail ;
3605 }
3606 #endif // SUPPORT_SHA
3607
3608 hdmitx_hdcp_ResumeRepeaterAuthenticate(it6161);
3609 hdmiTxDev[0].bAuthenticated = true ;
3610 return ER_SUCCESS ;
3611
3612 hdmitx_hdcp_Repeater_Fail:
3613 hdmitx_hdcp_CancelRepeaterAuthenticate(it6161);
3614 return ER_FAIL ;
3615 }
3616 #endif
3617 #if 0
3618 static int hdmi_tx_hdcp_get_m0(struct it6161 *it6161, u8 *m0)
3619 {
3620 int ret, i;
3621
3622 if(!m0)
3623 return -ENOMEM;
3624
3625 /* read m0[31:0] from reg51~reg54 */
3626 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL, 5);
3627 ret = it6161_hdmi_tx_burst_read(it6161, REG_TX_SHA_RD_BYTE1, m0, 4);
3628
3629 if (ret < 0) {
3630 DRM_INFO("i2c read m0 failed");
3631 return ret;
3632 }
3633
3634 /* read m0[39 + i * 8 : 32 + i * 8] from reg55 */
3635 for (i = 0; i < 4; i++) {
3636 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL, i);
3637 m0[4 + i] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3638 }
3639
3640 return ret;
3641 }
3642 #endif
3643
hdmi_tx_hdcp_get_bcaps(struct it6161 * it6161)3644 static int hdmi_tx_hdcp_get_bcaps(struct it6161 *it6161)
3645 {
3646 int ret;
3647
3648 hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_BCAPS, 0x01, 0x00, CMD_DDC_SEQ_BURSTREAD);
3649 ret = it6161_ddc_wait(it6161);
3650
3651 if (ret < 0) {
3652 DRM_INFO("ddc get bcaps failed");
3653 return ret;
3654 }
3655
3656 ret = it6161_hdmi_tx_read(it6161, REG_TX_BCAP);
3657
3658 if (ret < 0) {
3659 DRM_INFO("i2c get bcaps failed");
3660 return ret;
3661 }
3662
3663 return ret;
3664 }
3665
hdmi_tx_hdcp_get_bstatus(struct it6161 * it6161)3666 static int hdmi_tx_hdcp_get_bstatus(struct it6161 *it6161)
3667 {
3668 int ret, bstatus;
3669
3670 hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_BSTATUS, 0x02, 0x00, CMD_DDC_SEQ_BURSTREAD);
3671 ret = it6161_ddc_wait(it6161);
3672
3673 if (ret < 0) {
3674 DRM_INFO("ddc get bstatus failed");
3675 return ret;
3676 }
3677
3678 ret = it6161_hdmi_tx_read(it6161, REG_TX_BSTAT);
3679
3680 if (ret < 0) {
3681 DRM_INFO("i2c get bstatus failed");
3682 return ret;
3683 }
3684
3685 bstatus = ret;
3686
3687 ret = it6161_hdmi_tx_read(it6161, REG_TX_BSTAT + 1);
3688
3689 if (ret < 0) {
3690 DRM_INFO("i2c get bstatus failed");
3691 return ret;
3692 }
3693
3694 bstatus |= ret << 8;
3695
3696 return bstatus;
3697 }
3698
3699 #if 0
3700 static void hdmi_tx_hdcp_show_ksv_list(struct it6161 *it6161, u8 *ksvlist)
3701 {
3702 u8 i;
3703
3704 for (i = 0; i < it6161->hdcp_downstream_count; i++, ksvlist += DRM_HDCP_KSV_LEN)
3705 DRM_INFO("device%d ksv:0x %*ph", i, DRM_HDCP_KSV_LEN, ksvlist);
3706 }
3707
3708 static int hdmi_tx_hdcp_get_ksv_list1(struct it6161 *it6161, u8 *ksvlist, size_t size)
3709 {
3710 int i, ret;
3711
3712 hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_KSV_FIFO, size, 0x00, CMD_DDC_SEQ_BURSTREAD);
3713 ret = it6161_ddc_wait(it6161);
3714
3715 if (ret < 0) {
3716 DRM_INFO("ddc get ksv list failed");
3717 return ret;
3718 }
3719
3720 for (i = 0; i < size; i++) {
3721 ret = it6161_hdmi_tx_read(it6161, REG_TX_DDC_READFIFO);
3722
3723 if (ret < 0) {
3724 DRM_INFO("i2c get ksv list failed");
3725 return ret;
3726 }
3727
3728 ksvlist[i] = ret;
3729 }
3730
3731 return 0;
3732 }
3733
3734 static int hdmi_tx_hdcp_get_v_prime(struct it6161 *it6161, u8 *v_prime, size_t size)
3735 {
3736 int i, ret;
3737
3738 hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_V_PRIME(0), size, 0x00, CMD_DDC_SEQ_BURSTREAD);
3739 ret = it6161_ddc_wait(it6161);
3740
3741 if (ret < 0) {
3742 DRM_INFO("ddc get v prime failed");
3743 return ret;
3744 }
3745
3746 for(i = 0 ; i < DRM_HDCP_V_PRIME_NUM_PARTS ; i++) {
3747 it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL ,i);
3748 ret = it6161_hdmi_tx_burst_read(it6161, REG_TX_SHA_RD_BYTE1, v_prime, DRM_HDCP_V_PRIME_PART_LEN);
3749 if (ret < 0) {
3750 DRM_INFO("i2c get v prime failed");
3751 return ret;
3752 }
3753
3754 v_prime += DRM_HDCP_V_PRIME_PART_LEN;
3755 }
3756
3757 return 0;
3758 }
3759
3760 static int hdmi_tx_setup_sha1_input(struct it6161 *it6161, u8 *ksvlist, u8 *sha1_input)
3761 {
3762 u8 i, m0[8], msg_count = 0;
3763
3764 hdmi_tx_hdcp_get_m0(it6161, m0);
3765
3766 for (i = 0; i < it6161->hdcp_downstream_count * DRM_HDCP_KSV_LEN; i++)
3767 sha1_input[i] = ksvlist[i];
3768
3769 msg_count += i;
3770 sha1_input[msg_count++] = (u8)it6161->bstatus;
3771 sha1_input[msg_count++] = (u8)(it6161->bstatus >> 8);
3772 i = 0;
3773
3774 while (i < ARRAY_SIZE(m0))
3775 sha1_input[msg_count++] = m0[i++];
3776
3777 return msg_count;
3778 }
3779
3780 static int it6161_sha1_digest(struct it6161 *it6161, u8 *sha1_input,
3781 unsigned int size, u8 *output_av)
3782 {
3783 struct shash_desc *desc;
3784 struct crypto_shash *tfm;
3785 int err;
3786 struct device *dev = &it6161->i2c_mipi_rx->dev;
3787
3788 tfm = crypto_alloc_shash("sha1", 0, 0);
3789 if (IS_ERR(tfm)) {
3790 DRM_DEV_ERROR(dev, "crypto_alloc_shash sha1 failed");
3791 return PTR_ERR(tfm);
3792 }
3793 desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
3794 if (!desc) {
3795 crypto_free_shash(tfm);
3796 return -ENOMEM;
3797 }
3798
3799 desc->tfm = tfm;
3800 err = crypto_shash_digest(desc, sha1_input, size, output_av);
3801 if (err)
3802 DRM_DEV_ERROR(dev, "crypto_shash_digest sha1 failed");
3803
3804 crypto_free_shash(tfm);
3805 kfree(desc);
3806 return err;
3807 }
3808
3809 static bool hdmi_tX_hdcp_compare_sha1_v_prime_v(struct it6161 *it6161, u8 *v_array, u8 *v_prime_array)
3810 {
3811 int i, j;
3812
3813 u8 (*v)[DRM_HDCP_V_PRIME_PART_LEN] = (u8 (*)[DRM_HDCP_V_PRIME_PART_LEN])v_array;
3814 u8 (*v_prime)[DRM_HDCP_V_PRIME_PART_LEN] = (u8 (*)[DRM_HDCP_V_PRIME_PART_LEN])v_prime_array;
3815
3816 for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++) {
3817 for (j = 0; j < DRM_HDCP_V_PRIME_PART_LEN; j++) {
3818 if (v[i][j] !=
3819 v_prime[i][DRM_HDCP_V_PRIME_PART_LEN - 1- j])
3820 return false;
3821 }
3822 }
3823
3824 return true;
3825 }
3826
3827 static void hdmi_tx_hdcp_auth_part2_process(struct work_struct *work)
3828 {
3829 struct it6161 *it6161 = container_of(work, struct it6161,
3830 wait_hdcp_ksv_list);
3831 int timeout = 5000, ret, i;
3832 //u8 bcaps, ksvlist[DRM_HDCP_KSV_LEN * it6161->hdcp_downstream_count], *tmp;
3833 u8 bcaps, ksvlist[DRM_HDCP_KSV_LEN], *tmp;
3834 u8 v[DRM_HDCP_V_PRIME_NUM_PARTS][DRM_HDCP_V_PRIME_PART_LEN], v_prime[DRM_HDCP_V_PRIME_NUM_PARTS][DRM_HDCP_V_PRIME_PART_LEN];
3835
3836 while (timeout > 0) {
3837 if (!hdmi_tx_get_sink_hpd(it6161))
3838 return;
3839
3840 ret = hdmi_tx_hdcp_get_bcaps(it6161);
3841
3842 if (ret < 0)
3843 return;
3844
3845 bcaps = ret;
3846 if (!!(bcaps & DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY)) {
3847 DRM_INFO("ksv list fifo ready");
3848 break;
3849 }
3850 usleep_range(1000, 2000);
3851 }
3852
3853 if (timeout <= 0) {
3854 DRM_INFO("wait ksv list ready timeout");
3855 return;
3856 }
3857
3858 ret = hdmi_tx_hdcp_get_ksv_list1(it6161, ksvlist, ARRAY_SIZE(ksvlist));
3859
3860 if (ret != 0)
3861 return;
3862
3863 hdmi_tx_hdcp_show_ksv_list(it6161, ksvlist);
3864 ret = hdmi_tx_setup_sha1_input(it6161, ksvlist, it6161->sha1_transform_input);
3865 DRM_INFO("sha1 msg_count :%d \nsha1_input:0x %*ph", ret, ret, it6161->sha1_transform_input);
3866 ret = it6161_sha1_digest(it6161, it6161->sha1_transform_input, ret, (u8 *)v);
3867 if (ret != 0)
3868 return;
3869
3870 tmp = (u8 *)v;
3871 for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++, tmp += DRM_HDCP_V_PRIME_PART_LEN)
3872 DRM_INFO("v:0x %*ph", DRM_HDCP_V_PRIME_PART_LEN, tmp);
3873
3874 ret = hdmi_tx_hdcp_get_v_prime(it6161, (u8 *)v_prime, sizeof(v_prime));
3875
3876 if (ret != 0)
3877 return;
3878
3879 tmp = (u8 *)v_prime;
3880 for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++, tmp += DRM_HDCP_V_PRIME_PART_LEN)
3881 DRM_INFO("v_prime:0x %*ph", DRM_HDCP_V_PRIME_PART_LEN, tmp);
3882
3883 ret = hdmi_tX_hdcp_compare_sha1_v_prime_v(it6161, (u8 *)v, (u8 *)v_prime);
3884 DRM_INFO("sha1 check result: %s", ret ? "pass" : "failed");
3885
3886 if (ret) {
3887 it6161_hdmi_tx_set_bits(it6161, REG_TX_LISTCTRL, B_TX_LISTDONE , B_TX_LISTDONE);
3888 } else {
3889 it6161_hdmi_tx_set_bits(it6161, REG_TX_LISTCTRL, B_TX_LISTDONE | B_TX_LISTFAIL, B_TX_LISTDONE | B_TX_LISTFAIL);
3890 }
3891 it6161_hdmi_tx_set_bits(it6161, REG_TX_LISTCTRL, B_TX_LISTDONE | B_TX_LISTFAIL, 0x00);
3892 }
3893 #endif
3894
hdmi_tx_hdcp_enable_auth_part1(struct it6161 * it6161)3895 static bool hdmi_tx_hdcp_enable_auth_part1(struct it6161 *it6161)
3896 {
3897 int ret;
3898 u8 i, count = 0;
3899
3900 ret = hdmi_tx_hdcp_get_bksv(it6161, it6161->bksv, (int)ARRAY_SIZE(it6161->bksv));
3901 if (ret < 0)
3902 return hdmiTxDev[0].bAuthenticated;
3903 DRM_INFO("bksv: 0x %*ph", (int)ARRAY_SIZE(it6161->bksv), it6161->bksv);
3904
3905 for (i = 0; i < ARRAY_SIZE(it6161->bksv); i++)
3906 count += countbit(it6161->bksv[i]);
3907
3908 if (count != 20) {
3909 DRM_INFO("not a valid bksv");
3910 return hdmiTxDev[0].bAuthenticated;
3911 }
3912
3913 if ((it6161->bksv[4] == 0x93) &&
3914 (it6161->bksv[3] == 0x43) &&
3915 (it6161->bksv[2] == 0x5C) &&
3916 (it6161->bksv[1] == 0xDE) &&
3917 (it6161->bksv[0] == 0x23)) {
3918 DRM_INFO("Revoked bksv");
3919 return hdmiTxDev[0].bAuthenticated ;
3920 }
3921
3922 it6161_hdmi_tx_write(it6161, REG_TX_HDCP_DESIRE, 0x08 | B_TX_CPDESIRE);
3923 hdmi_tx_hdcp_generate_an(it6161);
3924 hdmi_tx_hdcp_auth_fire(it6161);
3925
3926 return true;
3927 }
3928
hdmi_tx_hdcp_auth_process(struct it6161 * it6161)3929 static bool hdmi_tx_hdcp_auth_process(struct it6161 *it6161)
3930 {
3931 u8 bcaps;
3932 u16 i, retry = 3;
3933 int ret;
3934
3935 /* Authenticate should be called after AFE setup up */
3936
3937 DRM_INFO("start");
3938 hdmiTxDev[0].bAuthenticated = false ;
3939 it6161->hdmi_tx_hdcp_retry--;
3940 hdmi_tx_hdcp_reset_auth(it6161);
3941 it6161_hdmi_tx_change_bank(it6161, 0);
3942 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_TX_HDCP_RST_HDMITX, 0x00);
3943 it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, 0x00);
3944 it6161_hdmi_tx_clear_ddc_fifo(it6161);
3945 hdmi_tx_hdcp_int_mask_enable(it6161);
3946
3947 for (i = 0; i < retry; i++) {
3948 ret = hdmi_tx_hdcp_get_bstatus(it6161);
3949 if(ret < 0)
3950 continue;
3951 it6161->bstatus = (u16)ret;
3952
3953 ret = hdmi_tx_hdcp_get_bcaps(it6161);
3954 if (ret < 0)
3955 continue;
3956 bcaps = ret;
3957 break;
3958 }
3959
3960 if (i == retry)
3961 return hdmiTxDev[0].bAuthenticated;
3962
3963 DRM_INFO("bcaps: 0x%02x, bstatus: 0x%04x, hdmi_mode: %d", bcaps, it6161->bstatus,
3964 it6161->bstatus & B_TX_CAP_HDMI_MODE);
3965 it6161->is_repeater = !!(bcaps & DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT);
3966 DRM_INFO("downstream is hdcp %s", it6161->is_repeater ? "repeater" : "receiver");
3967 if (it6161->is_repeater) {
3968 it6161->hdcp_downstream_count = (u8)DRM_HDCP_NUM_DOWNSTREAM(it6161->bstatus);
3969 DRM_INFO("down stream Count %d", it6161->hdcp_downstream_count);
3970 if (it6161->hdcp_downstream_count > 6) {
3971 DRM_INFO("over maximum supported number 6");
3972 return hdmiTxDev[0].bAuthenticated;
3973 }
3974 }
3975
3976 ret = hdmi_tx_hdcp_enable_auth_part1(it6161);
3977
3978 if (!ret)
3979 return ret;
3980
3981 if (!it6161->is_repeater) {
3982 ret = wait_for_completion_timeout(&it6161->wait_hdcp_event, msecs_to_jiffies(1000));
3983 DRM_INFO("completion:%d", ret);
3984 if (ret == 0)
3985 DRM_INFO("hdcp-receiver: timeout");
3986
3987 return hdmiTxDev[0].bAuthenticated;
3988 }
3989 return hdmiTxDev[0].bAuthenticated;
3990 }
3991 #endif
3992
hdmitx_hdcp_ResumeAuthentication(struct it6161 * it6161)3993 static void hdmitx_hdcp_ResumeAuthentication(struct it6161 *it6161)
3994 {
3995 it6161_hdmi_tx_set_av_mute(it6161, true);
3996 if(hdmi_tx_hdcp_auth_process(it6161) == ER_SUCCESS)
3997 {
3998 }
3999 it6161_hdmi_tx_set_av_mute(it6161, false);
4000 }
4001
hdmi_tx_hdcp_work(struct work_struct * work)4002 static void hdmi_tx_hdcp_work(struct work_struct *work)
4003 {
4004 struct it6161 *it6161 = container_of(work, struct it6161,
4005 hdcp_work.work);
4006 //struct device *dev = &it6161->i2c_hdmi_tx->dev;
4007 bool ret, sink_hpd = hdmi_tx_get_sink_hpd(it6161), video_state = hdmi_tx_get_video_state(it6161);
4008
4009 if (it6161->hdmi_tx_hdcp_retry <= 0 || !sink_hpd || !video_state) {
4010 DRM_INFO("hdcp_retry:%d sink_hpd:%d video_stable_state:%d", it6161->hdmi_tx_hdcp_retry, sink_hpd, video_state);
4011 return;
4012 }
4013
4014 ret = hdmi_tx_hdcp_auth_process(it6161);
4015 if (it6161->is_repeater) {
4016 DRM_INFO("is repeater and wait for ksv list interrupt");
4017 return;
4018 }
4019
4020 DRM_INFO("hdcp_auth_process %s", ret ? "pass" : "failed");
4021 }
4022
hdmi_tx_enable_hdcp(struct it6161 * it6161)4023 static void hdmi_tx_enable_hdcp(struct it6161 *it6161)
4024 {
4025 struct device *dev = &it6161->i2c_hdmi_tx->dev;
4026
4027 DRM_DEV_DEBUG_DRIVER(dev, "start");
4028 queue_delayed_work(system_wq, &it6161->hdcp_work,
4029 msecs_to_jiffies(500));
4030 }
4031 #endif
4032
getHDMITX_LinkStatus()4033 static bool getHDMITX_LinkStatus()
4034 {
4035 it6161_debug("%s reg0E:0x%02x reg0x61:0x%02x", __func__, it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS), it6161_hdmi_tx_read(it6161, REG_TX_AFE_DRV_CTRL));//allen
4036 if(B_TX_RXSENDETECT & it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS)) {
4037 if(0==it6161_hdmi_tx_read(it6161, REG_TX_AFE_DRV_CTRL))
4038 {
4039 //DRM_INFO("getHDMITX_LinkStatus()!!\n");
4040 return true;
4041 }
4042 }
4043 DRM_INFO("GetTMDS not Ready()!!\n");
4044
4045 return false;
4046 }
4047
4048 // static void HDMITX_PowerDown()
4049 // {
4050 // it6161_hdmi_tx_write_table(it6161, HDMITX_PwrDown_Table, ARRAY_SIZE(HDMITX_PwrDown_Table));
4051 // }
4052
hdmi_tx_setup_pclk_div2(struct it6161 * it6161)4053 static void hdmi_tx_setup_pclk_div2(struct it6161 *it6161)
4054 {
4055 if (HDMI_TX_PCLK_DIV2) {
4056 DRM_INFO("PCLK Divided by 2 mode");
4057 it6161_hdmi_tx_set_bits(it6161, REG_TX_INPUT_MODE, B_TX_PCLKDIV2, B_TX_PCLKDIV2);
4058 }
4059 }
4060
4061 //////////////////////////////////////////////////////////////////////
4062 // Function: hdmi_tx_setup_csc
4063 // Parameter: input_mode -
4064 // D[1:0] - Color Mode
4065 // D[4] - Colorimetry 0: ITU_BT601 1: ITU_BT709
4066 // D[5] - Quantization 0: 0_255 1: 16_235
4067 // D[6] - Up/Dn Filter 'Required'
4068 // 0: no up/down filter
4069 // 1: enable up/down filter when csc need.
4070 // D[7] - Dither Filter 'Required'
4071 // 0: no dither enabled.
4072 // 1: enable dither and dither free go "when required".
4073 // output_mode -
4074 // D[1:0] - Color mode.
4075 // Return: N/A
4076 // Remark: reg72~reg8D will be programmed depended the input with table.
4077 // Side-Effect:
4078 //////////////////////////////////////////////////////////////////////
4079
hdmi_tx_setup_csc(struct it6161 * it6161)4080 static void hdmi_tx_setup_csc(struct it6161 *it6161)
4081 {
4082 u8 ucData, csc = 0, i, filter = 0; // filter is for Video CTRL DN_FREE_GO,EN_DITHER,and ENUDFILT
4083 u8 input_mode = it6161->hdmi_tx_input_color_space;
4084 u8 output_mode = it6161->hdmi_tx_output_color_space;
4085
4086 // (1) YUV422 in,RGB/YUV444 output (Output is 8-bit,input is 12-bit)
4087 // (2) YUV444/422 in,RGB output (CSC enable,and output is not YUV422)
4088 // (3) RGB in,YUV444 output (CSC enable,and output is not YUV422)
4089 //
4090 // YUV444/RGB24 <-> YUV422 need set up/down filter.
4091 DRM_INFO("hdmi_tx_setup_csc(u8 input_mode = %x,u8 output_mode = %x)\n", (int)input_mode, (int)output_mode);
4092 switch(input_mode&F_MODE_CLRMOD_MASK)
4093 {
4094 #ifdef SUPPORT_INPUTYUV444
4095 case F_MODE_YUV444:
4096 DRM_INFO("Input mode is YUV444 ");
4097 switch(output_mode&F_MODE_CLRMOD_MASK)
4098 {
4099 case F_MODE_YUV444:
4100 DRM_INFO("Output mode is YUV444\n");
4101 csc = B_HDMITX_CSC_BYPASS ;
4102 break ;
4103
4104 case F_MODE_YUV422:
4105 DRM_INFO("Output mode is YUV422\n");
4106 if(input_mode & F_VIDMODE_EN_UDFILT) // YUV444 to YUV422 need up/down filter for processing.
4107 {
4108 filter |= B_TX_EN_UDFILTER ;
4109 }
4110 csc = B_HDMITX_CSC_BYPASS ;
4111 break ;
4112 case F_MODE_RGB444:
4113 DRM_INFO("Output mode is RGB24\n");
4114 csc = B_HDMITX_CSC_YUV2RGB ;
4115 if(input_mode & F_VIDMODE_EN_DITHER) // YUV444 to RGB24 need dither
4116 {
4117 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4118 }
4119 break ;
4120 }
4121 break ;
4122 #endif
4123
4124 #ifdef SUPPORT_INPUTYUV422
4125 case F_MODE_YUV422:
4126 DRM_INFO("Input mode is YUV422\n");
4127 switch(output_mode&F_MODE_CLRMOD_MASK)
4128 {
4129 case F_MODE_YUV444:
4130 DRM_INFO("Output mode is YUV444\n");
4131 csc = B_HDMITX_CSC_BYPASS ;
4132 if(input_mode & F_VIDMODE_EN_UDFILT) // YUV422 to YUV444 need up filter
4133 {
4134 filter |= B_TX_EN_UDFILTER ;
4135 }
4136 if(input_mode & F_VIDMODE_EN_DITHER) // YUV422 to YUV444 need dither
4137 {
4138 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4139 }
4140 break ;
4141 case F_MODE_YUV422:
4142 DRM_INFO("Output mode is YUV422\n");
4143 csc = B_HDMITX_CSC_BYPASS ;
4144
4145 break ;
4146
4147 case F_MODE_RGB444:
4148 DRM_INFO("Output mode is RGB24\n");
4149 csc = B_HDMITX_CSC_YUV2RGB ;
4150 if(input_mode & F_VIDMODE_EN_UDFILT) // YUV422 to RGB24 need up/dn filter.
4151 {
4152 filter |= B_TX_EN_UDFILTER ;
4153 }
4154 if(input_mode & F_VIDMODE_EN_DITHER) // YUV422 to RGB24 need dither
4155 {
4156 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4157 }
4158 break ;
4159 }
4160 break ;
4161 #endif
4162
4163 #ifdef SUPPORT_INPUTRGB
4164 case F_MODE_RGB444:
4165 DRM_INFO("Input mode is RGB24\n");
4166 switch(output_mode&F_MODE_CLRMOD_MASK)
4167 {
4168 case F_MODE_YUV444:
4169 DRM_INFO("Output mode is YUV444\n");
4170 csc = B_HDMITX_CSC_RGB2YUV ;
4171
4172 if(input_mode & F_VIDMODE_EN_DITHER) // RGB24 to YUV444 need dither
4173 {
4174 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4175 }
4176 break ;
4177
4178 case F_MODE_YUV422:
4179 DRM_INFO("Output mode is YUV422\n");
4180 if(input_mode & F_VIDMODE_EN_UDFILT) // RGB24 to YUV422 need down filter.
4181 {
4182 filter |= B_TX_EN_UDFILTER ;
4183 }
4184 if(input_mode & F_VIDMODE_EN_DITHER) // RGB24 to YUV422 need dither
4185 {
4186 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4187 }
4188 csc = B_HDMITX_CSC_RGB2YUV ;
4189 break ;
4190
4191 case F_MODE_RGB444:
4192 DRM_INFO("Output mode is RGB24\n");
4193 csc = B_HDMITX_CSC_BYPASS ;
4194 break ;
4195 }
4196 break ;
4197 #endif
4198 }
4199 #ifndef DISABLE_HDMITX_CSC
4200
4201 #ifdef SUPPORT_INPUTRGB
4202 // set the CSC metrix registers by colorimetry and quantization
4203 if(csc == B_HDMITX_CSC_RGB2YUV)
4204 {
4205 DRM_INFO("CSC = RGB2YUV %x ",csc);
4206 switch(input_mode&(F_VIDMODE_ITU709|F_VIDMODE_16_235))
4207 {
4208 case F_VIDMODE_ITU709|F_VIDMODE_16_235:
4209 DRM_INFO("ITU709 16-235 ");
4210 for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU709_16_235[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU709_16_235[i]);}
4211 break ;
4212 case F_VIDMODE_ITU709|F_VIDMODE_0_255:
4213 DRM_INFO("ITU709 0-255 ");
4214 for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU709_0_255[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU709_0_255[i]);}
4215 break ;
4216 case F_VIDMODE_ITU601|F_VIDMODE_16_235:
4217 DRM_INFO("ITU601 16-235 ");
4218 for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU601_16_235[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU601_16_235[i]);}
4219 break ;
4220 case F_VIDMODE_ITU601|F_VIDMODE_0_255:
4221 default:
4222 DRM_INFO("ITU601 0-255 ");
4223 for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU601_0_255[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU601_0_255[i]);}
4224 break ;
4225 }
4226 }
4227 #endif
4228
4229 #ifdef SUPPORT_INPUTYUV
4230 if (csc == B_HDMITX_CSC_YUV2RGB)
4231 {
4232 DRM_INFO("CSC = YUV2RGB %x ",csc);
4233
4234 switch(input_mode&(F_VIDMODE_ITU709|F_VIDMODE_16_235))
4235 {
4236 case F_VIDMODE_ITU709|F_VIDMODE_16_235:
4237 DRM_INFO("ITU709 16-235 ");
4238 for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU709_16_235[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU709_16_235[i]);}
4239 break ;
4240 case F_VIDMODE_ITU709|F_VIDMODE_0_255:
4241 DRM_INFO("ITU709 0-255 ");
4242 for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU709_0_255[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU709_0_255[i]);}
4243 break ;
4244 case F_VIDMODE_ITU601|F_VIDMODE_16_235:
4245 DRM_INFO("ITU601 16-235 ");
4246 for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU601_16_235[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU601_16_235[i]);}
4247 break ;
4248 case F_VIDMODE_ITU601|F_VIDMODE_0_255:
4249 default:
4250 DRM_INFO("ITU601 0-255 ");
4251 for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU601_0_255[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU601_0_255[i]);}
4252 break ;
4253 }
4254 }
4255 #endif
4256 #else// DISABLE_HDMITX_CSC
4257 csc = B_HDMITX_CSC_BYPASS ;
4258 #endif// DISABLE_HDMITX_CSC
4259
4260 if( csc == B_HDMITX_CSC_BYPASS )
4261 {
4262 it6161_hdmi_tx_set_bits(it6161, 0xF, 0x10, 0x10);
4263 }
4264 else
4265 {
4266 it6161_hdmi_tx_set_bits(it6161, 0xF, 0x10, 0x00);
4267 }
4268 ucData = it6161_hdmi_tx_read(it6161, REG_TX_CSC_CTRL) & ~(M_TX_CSC_SEL|B_TX_DNFREE_GO|B_TX_EN_DITHER|B_TX_EN_UDFILTER);
4269 ucData |= filter|csc ;
4270
4271 it6161_hdmi_tx_write(it6161, REG_TX_CSC_CTRL,ucData);
4272 }
4273
4274 // Parameter: VIDEOPCLKLEVEL level
4275 // PCLK_LOW - for 13.5MHz (for mode less than 1080p)
4276 // PCLK MEDIUM - for 25MHz~74MHz
4277 // PCLK HIGH - PCLK > 80Hz (for 1080p mode or above)
4278 // Remark: set reg62~reg65 depended on HighFreqMode
4279 // reg61 have to be programmed at last and after video stable input.
4280
hdmi_tx_setup_afe(struct it6161 * it6161,VIDEOPCLKLEVEL level)4281 static void hdmi_tx_setup_afe(struct it6161 *it6161, VIDEOPCLKLEVEL level)
4282 {
4283
4284 it6161_hdmi_tx_write(it6161, REG_TX_AFE_DRV_CTRL, B_TX_AFE_DRV_RST);
4285 switch(level)
4286 {
4287 case PCLK_HIGH:
4288 it6161_hdmi_tx_set_bits(it6161, 0x62, 0x90, 0x80);
4289 it6161_hdmi_tx_set_bits(it6161, 0x64, 0x89, 0x80);
4290 it6161_hdmi_tx_set_bits(it6161, 0x68, 0x10, 0x00);
4291 it6161_hdmi_tx_set_bits(it6161, 0x66, 0x80, 0x80);//hdmitxset(0x66, 0x80, 0x80);// mark fix 6017
4292 break ;
4293 default:
4294 it6161_hdmi_tx_set_bits(it6161, 0x62, 0x90, 0x10);
4295 it6161_hdmi_tx_set_bits(it6161, 0x64, 0x89, 0x09);
4296 it6161_hdmi_tx_set_bits(it6161, 0x68, 0x10, 0x10);
4297 break ;
4298 }
4299 DRM_INFO("setup afe: %s", level ? "high" : "low");
4300 #ifdef REDUCE_HDMITX_SRC_JITTER
4301 //it6161_hdmi_tx_set_bits(it6161, 0x64, 0x01, 0x00); //pet: TODO need check
4302 // it6161_hdmi_tx_set_bits(it6161, 0x6A, 0xFF, 0xFF);
4303
4304 // 2019/02/15 modified by jjtseng,
4305 // Dr. Liu:
4306 // it6161 �b�� Solomon mipi TX (�Ψ�Ljitter �ܤj��source��), �Х[�H�U�]�w
4307 // reg[6A]=0x5D
4308 // Note: Register 6A is REG_XP_TEST[7:0], its eye and jitter CTS report please see attached file
4309 //
4310 // it6161 �b�� ite mipi TX (��Ljitter OK��source��), keep
4311 // [6A]=0x00 (default setting)
4312
4313 it6161_hdmi_tx_set_bits(it6161, 0x6A, 0xFF, 0x5D);
4314 #endif
4315 }
4316
4317 // Remark: write reg61 with 0x04
4318 // When program reg61 with 0x04,then audio and video circuit work.
4319
hdmi_tx_fire_afe(struct it6161 * it6161)4320 static void hdmi_tx_fire_afe(struct it6161 *it6161)
4321 {
4322 it6161_hdmi_tx_change_bank(it6161, 0x00);
4323 it6161_hdmi_tx_write(it6161, REG_TX_AFE_DRV_CTRL, 0x00);
4324 }
4325
4326 //////////////////////////////////////////////////////////////////////
4327 // utility function for main..
4328 //////////////////////////////////////////////////////////////////////
4329
4330 // #ifndef DISABLE_HDMITX_CSC
4331 // #if (defined (SUPPORT_OUTPUTYUV)) && (defined (SUPPORT_INPUTRGB))
4332 // extern const u8 bCSCMtx_RGB2YUV_ITU601_16_235[] ;
4333 // extern const u8 bCSCMtx_RGB2YUV_ITU601_0_255[] ;
4334 // extern const u8 bCSCMtx_RGB2YUV_ITU709_16_235[] ;
4335 // extern const u8 bCSCMtx_RGB2YUV_ITU709_0_255[] ;
4336 // #endif
4337
4338 // #if (defined (SUPPORT_OUTPUTRGB)) && (defined (SUPPORT_INPUTYUV))
4339 // extern const u8 bCSCMtx_YUV2RGB_ITU601_16_235[] ;
4340 // extern const u8 bCSCMtx_YUV2RGB_ITU601_0_255[] ;
4341 // extern const u8 bCSCMtx_YUV2RGB_ITU709_16_235[] ;
4342 // extern const u8 bCSCMtx_YUV2RGB_ITU709_0_255[] ;
4343
4344 // #endif
4345 // #endif// DISABLE_HDMITX_CSC
4346
4347
hdmi_tx_disable_video_output(struct it6161 * it6161)4348 static void hdmi_tx_disable_video_output(struct it6161 *it6161)
4349 {
4350 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_VID_RST, B_HDMITX_VID_RST);
4351 it6161_hdmi_tx_write(it6161, REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST|B_TX_AFE_DRV_PWD);
4352 it6161_hdmi_tx_set_bits(it6161, 0x62, 0x90, 0x00);
4353 it6161_hdmi_tx_set_bits(it6161, 0x64, 0x89, 0x00);
4354 }
4355
hdmi_tx_enable_video_output(struct it6161 * it6161,VIDEOPCLKLEVEL level)4356 static void hdmi_tx_enable_video_output(struct it6161 *it6161, VIDEOPCLKLEVEL level)
4357 {
4358 it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST | B_TX_AREF_RST | B_TX_HDCP_RST_HDMITX);
4359 it6161_hdmi_tx_change_bank(it6161, 1);
4360 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB1, 0x00);
4361 it6161_hdmi_tx_change_bank(it6161, 0);
4362
4363 if(it6161->hdmi_mode)
4364 it6161_hdmi_tx_set_av_mute(it6161, true);
4365
4366 hdmi_tx_setup_pclk_div2(it6161);
4367 hdmi_tx_setup_csc(it6161);
4368 it6161_hdmi_tx_write(it6161, REG_TX_HDMI_MODE, it6161->hdmi_mode ? B_TX_HDMI_MODE : B_TX_DVI_MODE);
4369 hdmi_tx_setup_afe(it6161, level);
4370 hdmi_tx_fire_afe(it6161);
4371 }
4372
4373 static u8 AudioDelayCnt=0;
4374 static u8 LastRefaudfreqnum=0;
4375 static bool bForceCTS = false;
4376
setHDMITX_ChStat(struct it6161 * it6161,u8 ucIEC60958ChStat[])4377 static void setHDMITX_ChStat(struct it6161 *it6161, u8 ucIEC60958ChStat[])
4378 {
4379 u8 uc ;
4380
4381 it6161_hdmi_tx_change_bank(it6161, 1);
4382 uc = (ucIEC60958ChStat[0] <<1)& 0x7C ;
4383 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_MODE,uc);
4384 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_CAT,ucIEC60958ChStat[1]); // 192, audio CATEGORY
4385 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_SRCNUM,ucIEC60958ChStat[2]&0xF);
4386 it6161_hdmi_tx_write(it6161, REG_TX_AUD0CHST_CHTNUM,(ucIEC60958ChStat[2]>>4)&0xF);
4387 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_CA_FS,ucIEC60958ChStat[3]); // choose clock
4388 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_OFS_WL,ucIEC60958ChStat[4]);
4389 it6161_hdmi_tx_change_bank(it6161, 0);
4390 }
4391 /*
4392 void setHDMITX_UpdateChStatFs(u32 Fs)
4393 {
4394 u8 uc ;
4395
4396 /////////////////////////////////////
4397 // Fs should be the following value.
4398 // #define AUDFS_22p05KHz 4
4399 // #define AUDFS_44p1KHz 0
4400 // #define AUDFS_88p2KHz 8
4401 // #define AUDFS_176p4KHz 12
4402 //
4403 // #define AUDFS_24KHz 6
4404 // #define AUDFS_48KHz 2
4405 // #define AUDFS_96KHz 10
4406 // #define AUDFS_192KHz 14
4407 //
4408 // #define AUDFS_768KHz 9
4409 //
4410 // #define AUDFS_32KHz 3
4411 // #define AUDFS_OTHER 1
4412 /////////////////////////////////////
4413
4414 it6161_hdmi_tx_change_bank(it6161, 1);
4415 uc = it6161_hdmi_tx_read(it6161, REG_TX_AUDCHST_CA_FS); // choose clock
4416 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_CA_FS,uc); // choose clock
4417 uc &= 0xF0 ;
4418 uc |= (Fs&0xF);
4419
4420 uc = it6161_hdmi_tx_read(it6161, REG_TX_AUDCHST_OFS_WL);
4421 uc &= 0xF ;
4422 uc |= ((~Fs) << 4)&0xF0 ;
4423 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_OFS_WL,uc);
4424
4425 it6161_hdmi_tx_change_bank(it6161, 0);
4426 }
4427 */
setHDMITX_LPCMAudio(u8 AudioSrcNum,u8 AudSWL,u8 bAudInterface)4428 static void setHDMITX_LPCMAudio(u8 AudioSrcNum, u8 AudSWL, u8 bAudInterface /*I2S/SPDIF/TDM*/)
4429 {
4430
4431 u8 AudioEnable, AudioFormat ;
4432 u8 bTDMSetting ;
4433 AudioEnable = 0 ;
4434 AudioFormat = hdmiTxDev[0].bOutputAudioMode ;
4435
4436 switch(AudSWL)
4437 {
4438 case 16:
4439 AudioEnable |= M_TX_AUD_16BIT ;
4440 break ;
4441 case 18:
4442 AudioEnable |= M_TX_AUD_18BIT ;
4443 break ;
4444 case 20:
4445 AudioEnable |= M_TX_AUD_20BIT ;
4446 break ;
4447 case 24:
4448 default:
4449 AudioEnable |= M_TX_AUD_24BIT ;
4450 break ;
4451 }
4452 if( bAudInterface == SPDIF )
4453 {
4454 AudioFormat &= ~0x40 ;
4455 AudioEnable |= B_TX_AUD_SPDIF|B_TX_AUD_EN_I2S0 ;
4456 }
4457 else
4458 {
4459 AudioFormat |= 0x40 ;
4460 switch(AudioSrcNum)
4461 {
4462 case 4:
4463 AudioEnable |= B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ;
4464 break ;
4465
4466 case 3:
4467 AudioEnable |= B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ;
4468 break ;
4469
4470 case 2:
4471 AudioEnable |= B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ;
4472 break ;
4473
4474 case 1:
4475 default:
4476 AudioFormat &= ~0x40 ;
4477 AudioEnable |= B_TX_AUD_EN_I2S0 ;
4478 break ;
4479
4480 }
4481 }
4482 AudioFormat|=0x01;//mingchih add
4483 hdmiTxDev[0].bAudioChannelEnable=AudioEnable;
4484
4485 it6161_hdmi_tx_change_bank(it6161, 0);
4486 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0,AudioEnable&0xF0);
4487
4488 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL1,AudioFormat); // regE1 bOutputAudioMode should be loaded from ROM image.
4489 #ifdef USE_IT66120
4490 it6161_hdmi_tx_set_bits(it6161, 0x5A,0x02, 0x00);
4491 if( bAudInterface == SPDIF )
4492 {
4493 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4494 }
4495 else
4496 {
4497 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xFF); // default mapping.
4498 }
4499 #else
4500 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4501 #endif
4502
4503 #ifdef USE_SPDIF_CHSTAT
4504 if( bAudInterface == SPDIF )
4505 {
4506 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL);
4507 }
4508 else
4509 {
4510 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4511 }
4512 #else // not USE_SPDIF_CHSTAT
4513 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4514 #endif // USE_SPDIF_CHSTAT
4515
4516 it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0x00);
4517 it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO,0x00); // regE5 = 0 ;
4518
4519 if( bAudInterface == SPDIF )
4520 {
4521 u8 i ;
4522 it6161_hdmi_tx_set_bits(it6161, 0x5c,(1<<6), (1<<6));
4523 for( i = 0 ; i < 100 ; i++ )
4524 {
4525 if(it6161_hdmi_tx_read(it6161, REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK)
4526 {
4527 break ; // stable clock.
4528 }
4529 }
4530 }
4531 else
4532 {
4533 bTDMSetting = it6161_hdmi_tx_read(it6161, REG_TX_AUD_HDAUDIO) ;
4534 if( bAudInterface == TDM )
4535 {
4536 bTDMSetting |= B_TX_TDM ;
4537 bTDMSetting &= 0x9F ;
4538 bTDMSetting |= (AudioSrcNum-1)<< 5;
4539 }
4540 else
4541 {
4542 bTDMSetting &= ~B_TX_TDM ;
4543 }
4544 it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO, bTDMSetting) ; // 2 channel NLPCM, no TDM mode.
4545 }
4546 }
4547
setHDMITX_NLPCMAudio(u8 bAudInterface)4548 static void setHDMITX_NLPCMAudio(u8 bAudInterface /*I2S/SPDIF/TDM*/) // no Source Num, no I2S.
4549 {
4550 u8 AudioEnable, AudioFormat ;
4551 u8 i ;
4552
4553 AudioFormat = 0x01 ; // NLPCM must use standard I2S mode.
4554 if( bAudInterface == SPDIF )
4555 {
4556 AudioEnable = M_TX_AUD_24BIT|B_TX_AUD_SPDIF;
4557 }
4558 else
4559 {
4560 AudioEnable = M_TX_AUD_24BIT;
4561 }
4562
4563 it6161_hdmi_tx_change_bank(it6161, 0);
4564 // it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF);
4565 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, AudioEnable);
4566 //it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST|B_TX_AREF_RST, 0x00);
4567
4568 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL1,0x01); // regE1 bOutputAudioMode should be loaded from ROM image.
4569 #ifdef USE_IT66120
4570 if( bAudInterface == SPDIF )
4571 {
4572 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4573 }
4574 else
4575 {
4576 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xFF); // default mapping.
4577 }
4578 #else
4579 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4580 #endif
4581
4582 #ifdef USE_SPDIF_CHSTAT
4583 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL);
4584 #else // not USE_SPDIF_CHSTAT
4585 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4586 #endif // USE_SPDIF_CHSTAT
4587
4588 it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0x00);
4589 it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO,0x00); // regE5 = 0 ;
4590
4591 if( bAudInterface == SPDIF )
4592 {
4593 for( i = 0 ; i < 100 ; i++ )
4594 {
4595 if(it6161_hdmi_tx_read(it6161, REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK)
4596 {
4597 break ; // stable clock.
4598 }
4599 }
4600 }
4601 else
4602 {
4603 i = it6161_hdmi_tx_read(it6161, REG_TX_AUD_HDAUDIO) ;
4604 i &= ~B_TX_TDM ;
4605 it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO, i) ; // 2 channel NLPCM, no TDM mode.
4606 }
4607 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, AudioEnable|B_TX_AUD_EN_I2S0);
4608 }
4609
setHDMITX_HBRAudio(u8 bAudInterface)4610 static void setHDMITX_HBRAudio(u8 bAudInterface /*I2S/SPDIF/TDM*/)
4611 {
4612 // u8 rst;
4613 it6161_hdmi_tx_change_bank(it6161, 0);
4614
4615 // rst = it6161_hdmi_tx_read(it6161, REG_TX_SW_RST);
4616 // rst &= ~(B_HDMITX_AUD_RST|B_TX_AREF_RST);
4617
4618 // it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst | B_HDMITX_AUD_RST );
4619
4620 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL1,0x47); // regE1 bOutputAudioMode should be loaded from ROM image.
4621 #ifdef USE_IT66120
4622 if( bAudInterface == SPDIF )
4623 {
4624 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4625 }
4626 else
4627 {
4628 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xFF); // default mapping.
4629 }
4630 #else
4631 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4632 #endif
4633
4634 if( bAudInterface == SPDIF )
4635 {
4636 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF);
4637 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL);
4638 }
4639 else
4640 {
4641 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT);
4642 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4643 }
4644 it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0x08);
4645 it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO,B_TX_HBR); // regE5 = 0 ;
4646
4647 //uc = it6161_hdmi_tx_read(it6161, REG_TX_CLK_CTRL1);
4648 //uc &= ~M_TX_AUD_DIV ;
4649 //it6161_hdmi_tx_write(it6161, REG_TX_CLK_CTRL1, uc);
4650
4651 if( bAudInterface == SPDIF )
4652 {
4653 u8 i ;
4654 for( i = 0 ; i < 100 ; i++ )
4655 {
4656 if(it6161_hdmi_tx_read(it6161, REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK)
4657 {
4658 break ; // stable clock.
4659 }
4660 }
4661 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF|B_TX_AUD_EN_SPDIF);
4662 }
4663 else
4664 {
4665 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0);
4666 }
4667 it6161_hdmi_tx_set_bits(it6161, 0x5c, BIT(6), 0x00);
4668 hdmiTxDev[0].bAudioChannelEnable=it6161_hdmi_tx_read(it6161, REG_TX_AUDIO_CTRL0);
4669 // it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst );
4670 }
4671
setHDMITX_DSDAudio()4672 static void setHDMITX_DSDAudio()
4673 {
4674 // to be continue
4675 // u8 rst;
4676 // rst = it6161_hdmi_tx_read(it6161, REG_TX_SW_RST);
4677
4678 //it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst | (B_HDMITX_AUD_RST|B_TX_AREF_RST) );
4679
4680 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL1,0x41); // regE1 bOutputAudioMode should be loaded from ROM image.
4681 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4682
4683 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT);
4684 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4685
4686 it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0x00);
4687 it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO,B_TX_DSD); // regE5 = 0 ;
4688 //it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst & ~(B_HDMITX_AUD_RST|B_TX_AREF_RST) );
4689
4690 //uc = it6161_hdmi_tx_read(it6161, REG_TX_CLK_CTRL1);
4691 //uc &= ~M_TX_AUD_DIV ;
4692 //it6161_hdmi_tx_write(it6161, REG_TX_CLK_CTRL1, uc);
4693
4694 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0);
4695 }
4696
HDMITX_DisableAudioOutput(struct it6161 * it6161)4697 static void HDMITX_DisableAudioOutput(struct it6161 *it6161)
4698 {
4699 //u8 uc = (it6161_hdmi_tx_read(it6161, REG_TX_SW_RST) | (B_HDMITX_AUD_RST | B_TX_AREF_RST));
4700 //it6161_hdmi_tx_write(it6161, REG_TX_SW_RST,uc);
4701 AudioDelayCnt=AudioOutDelayCnt;
4702 LastRefaudfreqnum=0;
4703 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, (B_HDMITX_AUD_RST | B_TX_AREF_RST), (B_HDMITX_AUD_RST | B_TX_AREF_RST) );
4704 it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x10, 0x10 );
4705 }
4706
HDMITX_EnableAudioOutput(struct it6161 * it6161,u8 AudioType,u8 bAudInterface,u32 SampleFreq,u8 ChNum,u8 * pIEC60958ChStat,u32 TMDSClock)4707 static void HDMITX_EnableAudioOutput(struct it6161 *it6161, u8 AudioType, u8 bAudInterface /*I2S/SPDIF/TDM*/, u32 SampleFreq, u8 ChNum, u8 *pIEC60958ChStat, u32 TMDSClock)
4708 {
4709 static u8 ucIEC60958ChStat[5] ;
4710
4711 u8 Fs ;
4712 AudioDelayCnt=36;
4713 LastRefaudfreqnum=0;
4714 hdmiTxDev[0].TMDSClock=TMDSClock;
4715 hdmiTxDev[0].bAudioChannelEnable=0;
4716 hdmiTxDev[0].bAudInterface=bAudInterface;
4717
4718 //DRM_INFO1(("HDMITX_EnableAudioOutput(%02X, %s, %d, %d, %p, %d);\n",
4719 // AudioType, bSPDIF?"SPDIF":"I2S",SampleFreq, ChNum, pIEC60958ChStat, TMDSClock
4720 // ));
4721
4722 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST,(B_HDMITX_AUD_RST | B_TX_AREF_RST), (B_HDMITX_AUD_RST | B_TX_AREF_RST));
4723 it6161_hdmi_tx_write(it6161, REG_TX_CLK_CTRL0,B_TX_AUTO_OVER_SAMPLING_CLOCK|B_TX_EXT_256FS|0x01);
4724
4725 it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x10, 0x00 ); // power on the ACLK
4726
4727 if(bAudInterface == SPDIF)
4728 {
4729 if(AudioType==T_AUDIO_HBR)
4730 {
4731 it6161_hdmi_tx_write(it6161, REG_TX_CLK_CTRL0,0x81);
4732 }
4733 it6161_hdmi_tx_set_bits(it6161, REG_TX_AUDIO_CTRL0,B_TX_AUD_SPDIF, B_TX_AUD_SPDIF);
4734 }
4735 else
4736 {
4737 it6161_hdmi_tx_set_bits(it6161, REG_TX_AUDIO_CTRL0, B_TX_AUD_SPDIF, 0x00);
4738 }
4739 if( AudioType != T_AUDIO_DSD)
4740 {
4741 // one bit audio have no channel status.
4742 switch(SampleFreq)
4743 {
4744 case 44100L: Fs = AUDFS_44p1KHz ; break ;
4745 case 88200L: Fs = AUDFS_88p2KHz ; break ;
4746 case 176400L: Fs = AUDFS_176p4KHz ; break ;
4747 case 32000L: Fs = AUDFS_32KHz ; break ;
4748 case 48000L: Fs = AUDFS_48KHz ; break ;
4749 case 96000L: Fs = AUDFS_96KHz ; break ;
4750 case 192000L: Fs = AUDFS_192KHz ; break ;
4751 case 768000L: Fs = AUDFS_768KHz ; break ;
4752 default:
4753 SampleFreq = 48000L ;
4754 Fs = AUDFS_48KHz ;
4755 break ; // default, set Fs = 48KHz.
4756 }
4757 #ifdef SUPPORT_AUDIO_MONITOR
4758 hdmiTxDev[0].bAudFs=Fs;// AUDFS_OTHER;
4759 #else
4760 hdmiTxDev[0].bAudFs=Fs;
4761 #endif
4762 setHDMITX_NCTS(hdmiTxDev[0].bAudFs);
4763 if( pIEC60958ChStat == NULL )
4764 {
4765 ucIEC60958ChStat[0] = 0 ;
4766 ucIEC60958ChStat[1] = 0 ;
4767 ucIEC60958ChStat[2] = (ChNum+1)/2 ;
4768
4769 if(ucIEC60958ChStat[2]<1)
4770 {
4771 ucIEC60958ChStat[2] = 1 ;
4772 }
4773 else if( ucIEC60958ChStat[2] >4 )
4774 {
4775 ucIEC60958ChStat[2] = 4 ;
4776 }
4777 ucIEC60958ChStat[3] = Fs ;
4778 ucIEC60958ChStat[4] = (((~Fs)<<4) & 0xF0) | CHTSTS_SWCODE ; // Fs | 24bit u32 length
4779 pIEC60958ChStat = ucIEC60958ChStat ;
4780 }
4781 }
4782 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST),B_TX_AREF_RST);
4783
4784 switch(AudioType)
4785 {
4786 case T_AUDIO_HBR:
4787 DRM_INFO("T_AUDIO_HBR\n");
4788 pIEC60958ChStat[0] |= 1<<1 ;
4789 pIEC60958ChStat[2] = 0;
4790 pIEC60958ChStat[3] &= 0xF0 ;
4791 pIEC60958ChStat[3] |= AUDFS_768KHz ;
4792 pIEC60958ChStat[4] |= (((~AUDFS_768KHz)<<4) & 0xF0)| 0xB ;
4793 setHDMITX_ChStat(it6161, pIEC60958ChStat);
4794 setHDMITX_HBRAudio(bAudInterface);
4795
4796 break ;
4797 case T_AUDIO_DSD:
4798 DRM_INFO("T_AUDIO_DSD\n");
4799 setHDMITX_DSDAudio();
4800 break ;
4801 case T_AUDIO_NLPCM:
4802 DRM_INFO("T_AUDIO_NLPCM\n");
4803 pIEC60958ChStat[0] |= 1<<1 ;
4804 setHDMITX_ChStat(it6161, pIEC60958ChStat);
4805 setHDMITX_NLPCMAudio(bAudInterface);
4806 break ;
4807 case T_AUDIO_LPCM:
4808 DRM_INFO("T_AUDIO_LPCM\n");
4809 pIEC60958ChStat[0] &= ~(1<<1);
4810
4811 setHDMITX_ChStat(it6161, pIEC60958ChStat);
4812 setHDMITX_LPCMAudio((ChNum+1)/2, SUPPORT_AUDI_AudSWL, bAudInterface);
4813 // can add auto adjust
4814 break ;
4815 }
4816 it6161_hdmi_tx_set_bits(it6161, REG_TX_INT_MASK1, B_TX_AUDIO_OVFLW_MASK, 0x00);
4817 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, hdmiTxDev[0].bAudioChannelEnable);
4818
4819 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST),0);
4820 }
4821 #ifdef SUPPORT_AUDIO_MONITOR
hdmitx_AutoAdjustAudio()4822 void hdmitx_AutoAdjustAudio()
4823 {
4824 u32 SampleFreq,cTMDSClock ;
4825 u32 N ;
4826 u32 aCTS=0;
4827 u8 fs, uc,LoopCnt=10;
4828 if(bForceCTS)
4829 {
4830 it6161_hdmi_tx_change_bank(it6161, 0);
4831 it6161_hdmi_tx_write(it6161, 0xF8, 0xC3);
4832 it6161_hdmi_tx_write(it6161, 0xF8, 0xA5);
4833 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL, B_TX_SW_CTS, 0x00); // D[1] = 0, HW auto count CTS
4834 it6161_hdmi_tx_write(it6161, 0xF8, 0xFF);
4835 }
4836 //msleep(50);
4837 it6161_hdmi_tx_change_bank(it6161, 1);
4838 N = ((u32)it6161_hdmi_tx_read(it6161, REGPktAudN2)&0xF) << 16 ;
4839 N |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudN1)) <<8 ;
4840 N |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudN0));
4841
4842 while(LoopCnt--)
4843 { u32 TempCTS=0;
4844 aCTS = ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt2)) << 12 ;
4845 aCTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt1)) <<4 ;
4846 aCTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt0)&0xf0)>>4 ;
4847 if(aCTS==TempCTS)
4848 {break;}
4849 TempCTS=aCTS;
4850 }
4851 it6161_hdmi_tx_change_bank(it6161, 0);
4852 if( aCTS == 0)
4853 {
4854 DRM_INFO("aCTS== 0");
4855 return;
4856 }
4857 uc = it6161_hdmi_tx_read(it6161, REG_TX_GCP);
4858
4859 cTMDSClock = hdmiTxDev[0].TMDSClock ;
4860 //TMDSClock=GetInputPclk();
4861 DRM_INFO("PCLK = %u0,000\n",(u32)(cTMDSClock/10000));
4862 switch(uc & 0x70)
4863 {
4864 case 0x50:
4865 cTMDSClock *= 5 ;
4866 cTMDSClock /= 4 ;
4867 break ;
4868 case 0x60:
4869 cTMDSClock *= 3 ;
4870 cTMDSClock /= 2 ;
4871 }
4872 SampleFreq = cTMDSClock/aCTS ;
4873 SampleFreq *= N ;
4874 SampleFreq /= 128 ;
4875 //SampleFreq=48000;
4876
4877 DRM_INFO("SampleFreq = %u0\n",(u32)(SampleFreq/10));
4878 if( SampleFreq>31000L && SampleFreq<=38050L ){fs = AUDFS_32KHz ;}
4879 else if (SampleFreq < 46550L ) {fs = AUDFS_44p1KHz ;}//46050
4880 else if (SampleFreq < 68100L ) {fs = AUDFS_48KHz ;}
4881 else if (SampleFreq < 92100L ) {fs = AUDFS_88p2KHz ;}
4882 else if (SampleFreq < 136200L ) {fs = AUDFS_96KHz ;}
4883 else if (SampleFreq < 184200L ) {fs = AUDFS_176p4KHz ;}
4884 else if (SampleFreq < 240200L ) {fs = AUDFS_192KHz ;}
4885 else if (SampleFreq < 800000L ) {fs = AUDFS_768KHz ;}
4886 else
4887 {
4888 fs = AUDFS_OTHER;
4889 DRM_INFO("fs = AUDFS_OTHER\n");
4890 }
4891 if(hdmiTxDev[0].bAudFs != fs)
4892 {
4893 hdmiTxDev[0].bAudFs=fs;
4894 setHDMITX_NCTS(hdmiTxDev[0].bAudFs); // set N, CTS by new generated clock.
4895 //CurrCTS=0;
4896 return;
4897 }
4898 return;
4899 }
4900
hdmitx_IsAudioChang()4901 bool hdmitx_IsAudioChang()
4902 {
4903 //u32 pCTS=0;
4904 u8 FreDiff=0,Refaudfreqnum;
4905
4906 //it6161_hdmi_tx_change_bank(it6161, 1);
4907 //pCTS = ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt2)) << 12 ;
4908 //pCTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt1)) <<4 ;
4909 //pCTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt0)&0xf0)>>4 ;
4910 //it6161_hdmi_tx_change_bank(it6161, 0);
4911 it6161_hdmi_tx_change_bank(it6161, 0);
4912 Refaudfreqnum=it6161_hdmi_tx_read(it6161, 0x60);
4913 //"Refaudfreqnum=%X pCTS= %u",(u32)Refaudfreqnum,(u32)(pCTS/10000)));
4914 //if((pCTS%10000)<1000)DRM_INFO("0");
4915 //if((pCTS%10000)<100)DRM_INFO("0");
4916 //if((pCTS%10000)<10)DRM_INFO("0");
4917 //DRM_INFO("%u\n",(u32)(pCTS%10000));
4918 if((1<<4)&it6161_hdmi_tx_read(it6161, 0x5f))
4919 {
4920 //printf("=======XXXXXXXXXXX=========\n");
4921 return false;
4922 }
4923 if(LastRefaudfreqnum>Refaudfreqnum)
4924 {FreDiff=LastRefaudfreqnum-Refaudfreqnum;}
4925 else
4926 {FreDiff=Refaudfreqnum-LastRefaudfreqnum;}
4927 LastRefaudfreqnum=Refaudfreqnum;
4928 if(3<FreDiff)
4929 {
4930 DRM_INFO("Aduio FreDiff=%d\n",(int)FreDiff);
4931 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL,(1<<5), (1<<5));
4932 it6161_hdmi_tx_set_bits(it6161, REG_TX_AUDIO_CTRL0, 0x0F, 0x00);
4933 return true;
4934 }
4935 else
4936 {
4937 return false;
4938 }
4939 }
4940 /*
4941 void setHDMITX_AudioChannelEnable(bool EnableAudio_b)
4942 {
4943 static bool AudioOutStatus=false;
4944 if(EnableAudio_b)
4945 {
4946 if(AudioDelayCnt==0)
4947 {
4948 //if(hdmiTxDev[0].bAuthenticated==false)
4949 //{
4950 #ifdef SUPPORT_AUDIO_MONITOR
4951 if(hdmitx_IsAudioChang())
4952 {
4953 hdmitx_AutoAdjustAudio();
4954 #else
4955 if(AudioOutStatus==false)
4956 {
4957 setHDMITX_NCTS(hdmiTxDev[0].bAudFs);
4958 #endif
4959 it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0);
4960 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL,(1<<5), (1<<5));
4961 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, hdmiTxDev[0].bAudioChannelEnable);
4962 //it6161_hdmi_tx_set_bits(it6161, 0x59,(1<<2), (1<<2)); //for test
4963 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL, 0x3C, 0x00);
4964 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL, 1<<5, 0x00);
4965 printf("Audio Out Enable\n");
4966 #ifndef SUPPORT_AUDIO_MONITOR
4967 AudioOutStatus=true;
4968 #endif
4969 }
4970 }
4971 else
4972 {
4973 AudioOutStatus=false;
4974 if(0==(it6161_hdmi_tx_read(it6161, REG_TX_CLK_STATUS2)&0x10))
4975 {
4976 AudioDelayCnt--;
4977 }
4978 else
4979 {
4980 AudioDelayCnt=AudioOutDelayCnt;
4981 }
4982 }
4983 }
4984 else
4985 {
4986 // CurrCTS=0;
4987 }
4988 }*/
4989 #endif //#ifdef SUPPORT_AUDIO_MONITOR
4990 //////////////////////////////////////////////////////////////////////
4991 // Function: setHDMITX_NCTS
4992 // Parameter: PCLK - video clock in Hz.
4993 // Fs - Encoded audio sample rate
4994 // AUDFS_22p05KHz 4
4995 // AUDFS_44p1KHz 0
4996 // AUDFS_88p2KHz 8
4997 // AUDFS_176p4KHz 12
4998 //
4999 // AUDFS_24KHz 6
5000 // AUDFS_48KHz 2
5001 // AUDFS_96KHz 10
5002 // AUDFS_192KHz 14
5003 //
5004 // AUDFS_768KHz 9
5005 //
5006 // AUDFS_32KHz 3
5007 // AUDFS_OTHER 1
5008 // Return: ER_SUCCESS if success
5009 // Remark: set N value,the CTS will be auto generated by HW.
5010 // Side-Effect: register bank will reset to bank 0.
5011 //////////////////////////////////////////////////////////////////////
5012
setHDMITX_NCTS(u8 Fs)5013 static void setHDMITX_NCTS(u8 Fs)
5014 {
5015 u32 n;
5016 u8 LoopCnt=255,CTSStableCnt=0;
5017 u32 diff;
5018 u32 CTS=0,LastCTS=0;
5019 bool HBR_mode;
5020 // u8 aVIC;
5021
5022 if(B_TX_HBR & it6161_hdmi_tx_read(it6161, REG_TX_AUD_HDAUDIO))
5023 {
5024 HBR_mode=true;
5025 }
5026 else
5027 {
5028 HBR_mode=false;
5029 }
5030 switch(Fs)
5031 {
5032 case AUDFS_32KHz: n = 4096; break;
5033 case AUDFS_44p1KHz: n = 6272; break;
5034 case AUDFS_48KHz: n = 6144; break;
5035 case AUDFS_88p2KHz: n = 12544; break;
5036 case AUDFS_96KHz: n = 12288; break;
5037 case AUDFS_176p4KHz: n = 25088; break;
5038 case AUDFS_192KHz: n = 24576; break;
5039 case AUDFS_768KHz: n = 24576; break ;
5040 default: n = 6144;
5041 }
5042 // tr_printf((" n = %d\n",n));
5043 it6161_hdmi_tx_change_bank(it6161, 1);
5044 it6161_hdmi_tx_write(it6161, REGPktAudN0,(u8)((n)&0xFF));
5045 it6161_hdmi_tx_write(it6161, REGPktAudN1,(u8)((n>>8)&0xFF));
5046 it6161_hdmi_tx_write(it6161, REGPktAudN2,(u8)((n>>16)&0xF));
5047
5048 if(bForceCTS)
5049 {
5050 u32 SumCTS=0;
5051 while(LoopCnt--)
5052 {
5053 msleep(30);
5054 CTS = ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt2)) << 12 ;
5055 CTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt1)) <<4 ;
5056 CTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt0)&0xf0)>>4 ;
5057 if( CTS == 0)
5058 {
5059 continue;
5060 }
5061 else
5062 {
5063 if(LastCTS>CTS )
5064 {diff=LastCTS-CTS;}
5065 else
5066 {diff=CTS-LastCTS;}
5067 //DRM_INFO("LastCTS= %u%u",(u32)(LastCTS/10000),(u32)(LastCTS%10000));
5068 //DRM_INFO(" CTS= %u%u\n",(u32)(CTS/10000),(u32)(CTS%10000));
5069 LastCTS=CTS;
5070 if(5>diff)
5071 {
5072 CTSStableCnt++;
5073 SumCTS+=CTS;
5074 }
5075 else
5076 {
5077 CTSStableCnt=0;
5078 SumCTS=0;
5079 continue;
5080 }
5081 if(CTSStableCnt>=32)
5082 {
5083 LastCTS=(SumCTS>>5);
5084 break;
5085 }
5086 }
5087 }
5088 }
5089 it6161_hdmi_tx_write(it6161, REGPktAudCTS0,(u8)((LastCTS)&0xFF));
5090 it6161_hdmi_tx_write(it6161, REGPktAudCTS1,(u8)((LastCTS>>8)&0xFF));
5091 it6161_hdmi_tx_write(it6161, REGPktAudCTS2,(u8)((LastCTS>>16)&0xF));
5092 it6161_hdmi_tx_change_bank(it6161, 0);
5093 #ifdef Force_CTS
5094 bForceCTS = true;
5095 #endif
5096 it6161_hdmi_tx_write(it6161, 0xF8, 0xC3);
5097 it6161_hdmi_tx_write(it6161, 0xF8, 0xA5);
5098 if(bForceCTS)
5099 {
5100 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL,B_TX_SW_CTS, B_TX_SW_CTS); // D[1] = 0, HW auto count CTS
5101 }
5102 else
5103 {
5104 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL, B_TX_SW_CTS, 0x00); // D[1] = 0, HW auto count CTS
5105 }
5106 it6161_hdmi_tx_write(it6161, 0xF8, 0xFF);
5107
5108 if(false==HBR_mode) //LPCM
5109 {
5110 u8 uData;
5111 it6161_hdmi_tx_change_bank(it6161, 1);
5112 Fs = AUDFS_768KHz ;
5113 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_CA_FS,0x00|Fs);
5114 Fs = ~Fs ; // OFS is the one's complement of FS
5115 uData = (0x0f&it6161_hdmi_tx_read(it6161, REG_TX_AUDCHST_OFS_WL));
5116 it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_OFS_WL,(Fs<<4)|uData);
5117 it6161_hdmi_tx_change_bank(it6161, 0);
5118 }
5119 }
5120
5121 //////////////////////////////////////////////////////////////////////
5122 // Function: hdmitx_SetAudioInfoFrame()
5123 // Parameter: pAudioInfoFrame - the pointer to HDMI Audio Infoframe ucData
5124 // Return: N/A
5125 // Remark: Fill the Audio InfoFrame ucData,and count checksum,then fill into
5126 // Audio InfoFrame registers.
5127 // Side-Effect: N/A
5128 //////////////////////////////////////////////////////////////////////
5129
hdmitx_SetAudioInfoFrame(struct it6161 * it6161,Audio_InfoFrame * pAudioInfoFrame)5130 static SYS_STATUS hdmitx_SetAudioInfoFrame(struct it6161 *it6161, Audio_InfoFrame *pAudioInfoFrame)
5131 {
5132 u8 checksum ;
5133
5134 if(!pAudioInfoFrame)
5135 {
5136 return ER_FAIL ;
5137 }
5138 it6161_hdmi_tx_change_bank(it6161, 1);
5139 checksum = 0x100-(AUDIO_INFOFRAME_VER+AUDIO_INFOFRAME_TYPE+AUDIO_INFOFRAME_LEN );
5140 it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_CC,pAudioInfoFrame->pktbyte.AUD_DB[0]);
5141 checksum -= it6161_hdmi_tx_read(it6161, REG_TX_PKT_AUDINFO_CC); checksum &= 0xFF ;
5142 it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_SF,pAudioInfoFrame->pktbyte.AUD_DB[1]);
5143 checksum -= it6161_hdmi_tx_read(it6161, REG_TX_PKT_AUDINFO_SF); checksum &= 0xFF ;
5144 it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_CA,pAudioInfoFrame->pktbyte.AUD_DB[3]);
5145 checksum -= it6161_hdmi_tx_read(it6161, REG_TX_PKT_AUDINFO_CA); checksum &= 0xFF ;
5146 it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_DM_LSV,pAudioInfoFrame->pktbyte.AUD_DB[4]);
5147 checksum -= it6161_hdmi_tx_read(it6161, REG_TX_PKT_AUDINFO_DM_LSV); checksum &= 0xFF ;
5148
5149 it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_SUM,checksum);
5150
5151 it6161_hdmi_tx_change_bank(it6161, 0);
5152 hdmitx_ENABLE_AUD_INFOFRM_PKT();
5153 return ER_SUCCESS ;
5154 }
5155
5156 //////////////////////////////////////////////////////////////////////
5157 // Function: hdmitx_SetAVIInfoFrame()
5158 // Parameter: pAVIInfoFrame - the pointer to HDMI AVI Infoframe ucData
5159 // Return: N/A
5160 // Remark: Fill the AVI InfoFrame ucData,and count checksum,then fill into
5161 // AVI InfoFrame registers.
5162 // Side-Effect: N/A
5163 //////////////////////////////////////////////////////////////////////
5164 #if 0
5165 static SYS_STATUS hdmitx_SetAVIInfoFrame(struct it6161 *it6161, AVI_InfoFrame *pAVIInfoFrame)
5166 {
5167 int i ;
5168 u8 checksum ;
5169
5170 if(!pAVIInfoFrame)
5171 {
5172 return ER_FAIL ;
5173 }
5174 it6161_hdmi_tx_change_bank(it6161, 1);
5175 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB1,pAVIInfoFrame->pktbyte.AVI_DB[0]);
5176 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB2,pAVIInfoFrame->pktbyte.AVI_DB[1]);
5177 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB3,pAVIInfoFrame->pktbyte.AVI_DB[2]);
5178 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB4,pAVIInfoFrame->pktbyte.AVI_DB[3]);
5179 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB5,pAVIInfoFrame->pktbyte.AVI_DB[4]);
5180 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB6,pAVIInfoFrame->pktbyte.AVI_DB[5]);
5181 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB7,pAVIInfoFrame->pktbyte.AVI_DB[6]);
5182 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB8,pAVIInfoFrame->pktbyte.AVI_DB[7]);
5183 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB9,pAVIInfoFrame->pktbyte.AVI_DB[8]);
5184 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB10,pAVIInfoFrame->pktbyte.AVI_DB[9]);
5185 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB11,pAVIInfoFrame->pktbyte.AVI_DB[10]);
5186 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB12,pAVIInfoFrame->pktbyte.AVI_DB[11]);
5187 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB13,pAVIInfoFrame->pktbyte.AVI_DB[12]);
5188 for(i = 0,checksum = 0; i < 13 ; i++)
5189 {
5190 checksum -= pAVIInfoFrame->pktbyte.AVI_DB[i] ;
5191 }
5192 /*
5193 DRM_INFO("SetAVIInfo(): ");
5194 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB1));
5195 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB2));
5196 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB3));
5197 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB4));
5198 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB5));
5199 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB6));
5200 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB7));
5201 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB8));
5202 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB9));
5203 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB10));
5204 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB11));
5205 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB12));
5206 DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB13));
5207 DRM_INFO("\n");
5208 */
5209 checksum -= AVI_INFOFRAME_VER+AVI_INFOFRAME_TYPE+AVI_INFOFRAME_LEN ;
5210 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_SUM,checksum);
5211
5212 it6161_hdmi_tx_change_bank(it6161, 0);
5213 hdmitx_ENABLE_AVI_INFOFRM_PKT();
5214 return ER_SUCCESS ;
5215 }
5216 #endif
hdmitx_SetVSIInfoFrame(struct it6161 * it6161,VendorSpecific_InfoFrame * pVSIInfoFrame)5217 static SYS_STATUS hdmitx_SetVSIInfoFrame(struct it6161 *it6161, VendorSpecific_InfoFrame *pVSIInfoFrame)
5218 {
5219 u8 ucData=0 ;
5220
5221 if(!pVSIInfoFrame)
5222 {
5223 return ER_FAIL ;
5224 }
5225
5226 it6161_hdmi_tx_change_bank(it6161, 1);
5227 it6161_hdmi_tx_write(it6161, 0x80,pVSIInfoFrame->pktbyte.VS_DB[3]);
5228 it6161_hdmi_tx_write(it6161, 0x81,pVSIInfoFrame->pktbyte.VS_DB[4]);
5229
5230 ucData -= pVSIInfoFrame->pktbyte.VS_DB[3] ;
5231 ucData -= pVSIInfoFrame->pktbyte.VS_DB[4] ;
5232
5233 if( pVSIInfoFrame->pktbyte.VS_DB[4] & (1<<7 ))
5234 {
5235 ucData -= pVSIInfoFrame->pktbyte.VS_DB[5] ;
5236 it6161_hdmi_tx_write(it6161, 0x82,pVSIInfoFrame->pktbyte.VS_DB[5]);
5237 ucData -= VENDORSPEC_INFOFRAME_TYPE + VENDORSPEC_INFOFRAME_VER + 6 + 0x0C + 0x03 ;
5238 }
5239 else
5240 {
5241 ucData -= VENDORSPEC_INFOFRAME_TYPE + VENDORSPEC_INFOFRAME_VER + 5 + 0x0C + 0x03 ;
5242 }
5243
5244 pVSIInfoFrame->pktbyte.CheckSum=ucData;
5245
5246 it6161_hdmi_tx_write(it6161, 0x83,pVSIInfoFrame->pktbyte.CheckSum);
5247 it6161_hdmi_tx_change_bank(it6161, 0);
5248 it6161_hdmi_tx_write(it6161, REG_TX_3D_INFO_CTRL,B_TX_ENABLE_PKT|B_TX_REPEAT_PKT);
5249 return ER_SUCCESS ;
5250 }
5251
HDMITX_EnableVSInfoFrame(struct it6161 * it6161,u8 bEnable,u8 * pVSInfoFrame)5252 static bool HDMITX_EnableVSInfoFrame(struct it6161 *it6161, u8 bEnable,u8 *pVSInfoFrame)
5253 {
5254 if(!bEnable)
5255 {
5256 hdmitx_DISABLE_VSDB_PKT();
5257 return true ;
5258 }
5259 if(hdmitx_SetVSIInfoFrame(it6161, (VendorSpecific_InfoFrame *)pVSInfoFrame) == ER_SUCCESS)
5260 {
5261 return true ;
5262 }
5263 return false ;
5264 }
5265 /*
5266 static bool HDMITX_EnableAVIInfoFrame(struct it6161 *it6161, u8 bEnable,u8 *pAVIInfoFrame)
5267 {
5268 if(!bEnable)
5269 {
5270 hdmitx_DISABLE_AVI_INFOFRM_PKT();
5271 return true ;
5272 }
5273 if(hdmitx_SetAVIInfoFrame(it6161, (AVI_InfoFrame *)pAVIInfoFrame) == ER_SUCCESS)
5274 {
5275 return true ;
5276 }
5277 return false ;
5278 }
5279 */
HDMITX_EnableAudioInfoFrame(struct it6161 * it6161,u8 bEnable,u8 * pAudioInfoFrame)5280 static bool HDMITX_EnableAudioInfoFrame(struct it6161 *it6161, u8 bEnable,u8 *pAudioInfoFrame)
5281 {
5282 if(!bEnable)
5283 {
5284 hdmitx_DISABLE_AVI_INFOFRM_PKT();
5285 return true ;
5286 }
5287 if(hdmitx_SetAudioInfoFrame(it6161, (Audio_InfoFrame *)pAudioInfoFrame) == ER_SUCCESS)
5288 {
5289 return true ;
5290 }
5291 return false ;
5292 }
5293
5294 //////////////////////////////////////////////////////////////////////
5295 // Function: hdmitx_SetSPDInfoFrame()
5296 // Parameter: pSPDInfoFrame - the pointer to HDMI SPD Infoframe ucData
5297 // Return: N/A
5298 // Remark: Fill the SPD InfoFrame ucData,and count checksum,then fill into
5299 // SPD InfoFrame registers.
5300 // Side-Effect: N/A
5301 //////////////////////////////////////////////////////////////////////
5302 /*
5303 SYS_STATUS hdmitx_SetSPDInfoFrame(SPD_InfoFrame *pSPDInfoFrame)
5304 {
5305 int i ;
5306 u8 ucData ;
5307
5308 if(!pSPDInfoFrame)
5309 {
5310 return ER_FAIL ;
5311 }
5312 it6161_hdmi_tx_change_bank(it6161, 1);
5313 for(i = 0,ucData = 0 ; i < 25 ; i++)
5314 {
5315 ucData -= pSPDInfoFrame->pktbyte.SPD_DB[i] ;
5316 it6161_hdmi_tx_write(it6161, REG_TX_PKT_SPDINFO_PB1+i,pSPDInfoFrame->pktbyte.SPD_DB[i]);
5317 }
5318 ucData -= SPD_INFOFRAME_VER+SPD_INFOFRAME_TYPE+SPD_INFOFRAME_LEN ;
5319 it6161_hdmi_tx_write(it6161, REG_TX_PKT_SPDINFO_SUM,ucData); // checksum
5320 it6161_hdmi_tx_change_bank(it6161, 0);
5321 hdmitx_ENABLE_SPD_INFOFRM_PKT();
5322 return ER_SUCCESS ;
5323 }
5324 */
5325 //////////////////////////////////////////////////////////////////////
5326 // Function: hdmitx_SetMPEGInfoFrame()
5327 // Parameter: pMPEGInfoFrame - the pointer to HDMI MPEG Infoframe ucData
5328 // Return: N/A
5329 // Remark: Fill the MPEG InfoFrame ucData,and count checksum,then fill into
5330 // MPEG InfoFrame registers.
5331 // Side-Effect: N/A
5332 //////////////////////////////////////////////////////////////////////
5333 /*
5334 SYS_STATUS hdmitx_SetMPEGInfoFrame(MPEG_InfoFrame *pMPGInfoFrame)
5335 {
5336 int i ;
5337 u8 ucData ;
5338
5339 if(!pMPGInfoFrame)
5340 {
5341 return ER_FAIL ;
5342 }
5343 it6161_hdmi_tx_change_bank(it6161, 1);
5344
5345 it6161_hdmi_tx_write(it6161, REG_TX_PKT_MPGINFO_FMT,pMPGInfoFrame->info.FieldRepeat|(pMPGInfoFrame->info.MpegFrame<<1));
5346 it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_DB0,pMPGInfoFrame->pktbyte.MPG_DB[0]);
5347 it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_DB1,pMPGInfoFrame->pktbyte.MPG_DB[1]);
5348 it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_DB2,pMPGInfoFrame->pktbyte.MPG_DB[2]);
5349 it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_DB3,pMPGInfoFrame->pktbyte.MPG_DB[3]);
5350
5351 for(ucData = 0,i = 0 ; i < 5 ; i++)
5352 {
5353 ucData -= pMPGInfoFrame->pktbyte.MPG_DB[i] ;
5354 }
5355 ucData -= MPEG_INFOFRAME_VER+MPEG_INFOFRAME_TYPE+MPEG_INFOFRAME_LEN ;
5356
5357 it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_SUM,ucData);
5358
5359 it6161_hdmi_tx_change_bank(it6161, 0);
5360 hdmitx_ENABLE_SPD_INFOFRM_PKT();
5361
5362 return ER_SUCCESS ;
5363 }
5364 */
5365 // 2009/12/04 added by Ming-chih.lung@ite.com.tw
5366
5367 /*
5368 SYS_STATUS hdmitx_Set_GeneralPurpose_PKT(u8 *pData)
5369 {
5370 int i ;
5371
5372 if( pData == NULL )
5373 {
5374 return ER_FAIL ;
5375
5376 }
5377 it6161_hdmi_tx_change_bank(it6161, 1);
5378 for( i = 0x38 ; i <= 0x56 ; i++)
5379 {
5380 it6161_hdmi_tx_write(it6161, i, pData[i-0x38] );
5381 }
5382 it6161_hdmi_tx_change_bank(it6161, 0);
5383 hdmitx_ENABLE_GeneralPurpose_PKT();
5384 //hdmitx_ENABLE_NULL_PKT();
5385 return ER_SUCCESS ;
5386 }
5387 */
5388 /*
5389 static void ConfigAVIInfoFrame(u8 VIC, u8 pixelrep)
5390 {
5391 AVI_InfoFrame *AviInfo;
5392 AviInfo = (AVI_InfoFrame *)CommunBuff ;
5393
5394 AviInfo->pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ;
5395 AviInfo->pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ;
5396 AviInfo->pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ;
5397
5398 switch(it6161->hdmi_tx_output_color_space)
5399 {
5400 case F_MODE_YUV444:
5401 // AviInfo->info.ColorMode = 2 ;
5402 AviInfo->pktbyte.AVI_DB[0] = (2<<5)|(1<<4);
5403 break ;
5404 case F_MODE_YUV422:
5405 // AviInfo->info.ColorMode = 1 ;
5406 AviInfo->pktbyte.AVI_DB[0] = (1<<5)|(1<<4);
5407 break ;
5408 case F_MODE_RGB444:
5409 default:
5410 // AviInfo->info.ColorMode = 0 ;
5411 AviInfo->pktbyte.AVI_DB[0] = (0<<5)|(1<<4);
5412 break ;
5413 }
5414 AviInfo->pktbyte.AVI_DB[1] = 8 ;
5415 AviInfo->pktbyte.AVI_DB[1] |= (aspec != HDMI_16x9)?(1<<4):(2<<4); // 4:3 or 16:9
5416 AviInfo->pktbyte.AVI_DB[1] |= (Colorimetry != HDMI_ITU709)?(1<<6):(2<<6); // 4:3 or 16:9
5417 AviInfo->pktbyte.AVI_DB[2] = 0 ;
5418 AviInfo->pktbyte.AVI_DB[3] = VIC ;
5419 AviInfo->pktbyte.AVI_DB[4] = pixelrep & 3 ;
5420 AviInfo->pktbyte.AVI_DB[5] = 0 ;
5421 AviInfo->pktbyte.AVI_DB[6] = 0 ;
5422 AviInfo->pktbyte.AVI_DB[7] = 0 ;
5423 AviInfo->pktbyte.AVI_DB[8] = 0 ;
5424 AviInfo->pktbyte.AVI_DB[9] = 0 ;
5425 AviInfo->pktbyte.AVI_DB[10] = 0 ;
5426 AviInfo->pktbyte.AVI_DB[11] = 0 ;
5427 AviInfo->pktbyte.AVI_DB[12] = 0 ;
5428
5429 HDMITX_EnableAVIInfoFrame(it6161, true, (unsigned char *)AviInfo);
5430 }
5431 */
ConfigAudioInfoFrm(struct it6161 * it6161,u8 channel_count)5432 static void ConfigAudioInfoFrm(struct it6161 *it6161, u8 channel_count)
5433 {
5434 int i;
5435 Audio_InfoFrame *AudioInfo ;
5436 AudioInfo = (Audio_InfoFrame *)CommunBuff ;
5437
5438 DRM_INFO("ConfigAudioInfoFrm channel count: %d", channel_count);
5439
5440 AudioInfo->pktbyte.AUD_HB[0] = AUDIO_INFOFRAME_TYPE ;
5441 AudioInfo->pktbyte.AUD_HB[1] = 1 ;
5442 AudioInfo->pktbyte.AUD_HB[2] = AUDIO_INFOFRAME_LEN ;
5443 AudioInfo->pktbyte.AUD_DB[0] = channel_count - 1;
5444
5445 for (i = 1 ;i < AUDIO_INFOFRAME_LEN ; i++) {
5446 AudioInfo->pktbyte.AUD_DB[i] = 0 ;
5447 }
5448
5449 /* audio_infoframe_ca */
5450 switch (channel_count) {
5451 case 0 :
5452 AudioInfo->pktbyte.AUD_DB[3] = 0xFF;
5453 break; // no audio
5454 case 2 :
5455 AudioInfo->pktbyte.AUD_DB[3] = 0x00;
5456 break;
5457 case 3 :
5458 AudioInfo->pktbyte.AUD_DB[3] = 0x01;
5459 break; // 0x01,0x02,0x04
5460 case 4 :
5461 AudioInfo->pktbyte.AUD_DB[3] = 0x03;
5462 break; // 0x03,0x05,0x06,0x08,0x14
5463 case 5 :
5464 AudioInfo->pktbyte.AUD_DB[3] = 0x07;
5465 break; // 0x07,0x09,0x0A,0x0C,0x15,0x16,0x18
5466 case 6 :
5467 AudioInfo->pktbyte.AUD_DB[3] = 0x0B;
5468 break; // 0x0B,0x0D,0x0E,0x10,0x17,0x19,0x1A,0x1C
5469 case 7 :
5470 AudioInfo->pktbyte.AUD_DB[3] = 0x0F;
5471 break; // 0x0F,0x11,0x12,0x1B,0x1D,0x1E
5472 case 8 :
5473 AudioInfo->pktbyte.AUD_DB[3] = 0x1F;
5474 break; // 0x13,0x1F
5475 default :
5476 DRM_INFO("Error: Audio Channel Number Error!");
5477 }
5478
5479 HDMITX_EnableAudioInfoFrame(it6161, TRUE, (unsigned char *)AudioInfo);
5480 }
5481
5482 #ifdef OUTPUT_3D_MODE
ConfigfHdmiVendorSpecificInfoFrame(struct it6161 * it6161,u8 _3D_Stru)5483 void ConfigfHdmiVendorSpecificInfoFrame(struct it6161 *it6161, u8 _3D_Stru)
5484 {
5485 VendorSpecific_InfoFrame *VS_Info;
5486
5487 VS_Info=(VendorSpecific_InfoFrame *)CommunBuff ;
5488
5489 VS_Info->pktbyte.VS_HB[0] = VENDORSPEC_INFOFRAME_TYPE|0x80;
5490 VS_Info->pktbyte.VS_HB[1] = VENDORSPEC_INFOFRAME_VER;
5491 VS_Info->pktbyte.VS_HB[2] = (_3D_Stru == Side_by_Side)?6:5;
5492 VS_Info->pktbyte.VS_DB[0] = 0x03;
5493 VS_Info->pktbyte.VS_DB[1] = 0x0C;
5494 VS_Info->pktbyte.VS_DB[2] = 0x00;
5495 VS_Info->pktbyte.VS_DB[3] = 0x40;
5496 switch(_3D_Stru)
5497 {
5498 case Side_by_Side:
5499 case Frame_Pcaking:
5500 case Top_and_Botton:
5501 VS_Info->pktbyte.VS_DB[4] = (_3D_Stru<<4);
5502 break;
5503 default:
5504 VS_Info->pktbyte.VS_DB[4] = (Frame_Pcaking<<4);
5505 break ;
5506 }
5507 VS_Info->pktbyte.VS_DB[5] = 0x00;
5508 HDMITX_EnableVSInfoFrame(it6161, true,(u8 *)VS_Info);
5509 }
5510 #endif //#ifdef OUTPUT_3D_MODE
5511
hdmi_tx_audio_process(struct it6161 * it6161)5512 static void hdmi_tx_audio_process(struct it6161 *it6161)
5513 {
5514 if (it6161->support_audio) {
5515 ConfigAudioInfoFrm(it6161, bOutputAudioChannel);
5516 // HDMITX_EnableAudioOutput(T_AUDIO_LPCM, false, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,TMDSClock);
5517 HDMITX_EnableAudioOutput(it6161,
5518 //CNOFIG_INPUT_AUDIO_TYPE,
5519 bOutputAudioType,
5520 CONFIG_INPUT_AUDIO_INTERFACE,
5521 ulAudioSampleFS,
5522 bOutputAudioChannel,
5523 NULL, // pointer to cahnnel status.
5524 VideoPixelClock*(pixelrep+1));
5525 // if you have channel status , set here.
5526 // setHDMITX_ChStat(it6161, u8 ucIEC60958ChStat[]);
5527 }
5528 }
5529
5530 #if 0
5531 static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
5532 {
5533 u8 csum = 0;
5534 size_t i;
5535
5536 /* compute checksum */
5537 for (i = 0; i < size; i++)
5538 csum += ptr[i];
5539
5540 return 256 - csum;
5541 }
5542
5543 static void hdmi_infoframe_set_checksum(void *buffer, size_t size)
5544 {
5545 u8 *ptr = buffer;
5546
5547 ptr[3] = hdmi_infoframe_checksum(buffer, size);
5548 }
5549 #endif
5550
hdmi_tx_get_avi_infoframe_from_source(struct it6161 * it6161,u8 * buffer,size_t size)5551 static int hdmi_tx_get_avi_infoframe_from_source(struct it6161 *it6161, u8 *buffer, size_t size)
5552 {
5553 struct device *dev = &it6161->i2c_mipi_rx->dev;
5554 int err;
5555
5556 err = hdmi_avi_infoframe_pack(&it6161->source_avi_infoframe, buffer, size);
5557 if (err < 0) {
5558 DRM_DEV_ERROR(dev, "Failed to pack AVI infoframe: %d", err);
5559 return err;
5560 }
5561
5562 return 0;
5563 }
5564
hdmi_tx_get_avi_infoframe_from_user_define(struct it6161 * it6161,u8 * buffer,size_t size)5565 static int hdmi_tx_get_avi_infoframe_from_user_define(struct it6161 *it6161, u8 *buffer, size_t size)
5566 {
5567 struct device *dev = &it6161->i2c_hdmi_tx->dev;
5568 struct hdmi_avi_infoframe *frame = &it6161->source_avi_infoframe;
5569 struct drm_display_mode *display_mode = &it6161->source_display_mode;
5570 int ret;
5571
5572 DRM_INFO( "user define to setup AVI infoframe");
5573
5574 ret = drm_hdmi_avi_infoframe_from_display_mode(frame, &it6161->connector, display_mode);
5575 if (ret) {
5576 DRM_DEV_ERROR(dev, "Failed to setup AVI infoframe: %d", ret);
5577 return ret;
5578 }
5579
5580 if ((it6161->hdmi_tx_output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_RGB444)
5581 frame->colorspace = HDMI_COLORSPACE_RGB;
5582
5583 if ((it6161->hdmi_tx_output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_YUV444)
5584 frame->colorspace = HDMI_COLORSPACE_YUV444;
5585
5586 if ((it6161->hdmi_tx_output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_YUV422)
5587 frame->colorspace = HDMI_COLORSPACE_YUV422;
5588
5589 ret = hdmi_tx_get_avi_infoframe_from_source(it6161, buffer, size);
5590 if (ret) {
5591 DRM_DEV_ERROR(dev, "Failed to pack AVI infoframe: %d", ret);
5592 return ret;
5593 }
5594
5595 return 0;
5596 }
5597
5598 static int (*hdmi_tx_get_avi_infoframe)(struct it6161*, u8*, size_t) = hdmi_tx_get_avi_infoframe_from_user_define;
5599
hdmi_tx_setup_avi_infoframe(struct it6161 * it6161,u8 * buffer,size_t size)5600 static void hdmi_tx_setup_avi_infoframe(struct it6161 *it6161, u8 *buffer, size_t size)
5601 {
5602 u8 i, *ptr = buffer + HDMI_INFOFRAME_HEADER_SIZE;
5603
5604 it6161_hdmi_tx_change_bank(it6161, 1);
5605
5606 for (i = 0; i < it6161->source_avi_infoframe.length; i++)
5607 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB1 + i, ptr[i]);
5608
5609 it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_SUM, buffer[3]);
5610 }
5611
hdmi_tx_disable_avi_infoframe(struct it6161 * it6161)5612 static inline void hdmi_tx_disable_avi_infoframe(struct it6161 *it6161)
5613 {
5614 it6161_hdmi_tx_change_bank(it6161, 0);
5615 it6161_hdmi_tx_write(it6161, REG_TX_AVI_INFOFRM_CTRL, 0x00);
5616 }
5617
hdmi_tx_enable_avi_infoframe(struct it6161 * it6161)5618 static inline void hdmi_tx_enable_avi_infoframe(struct it6161 *it6161)
5619 {
5620 it6161_hdmi_tx_change_bank(it6161, 0);
5621 it6161_hdmi_tx_write(it6161, REG_TX_AVI_INFOFRM_CTRL, B_TX_ENABLE_PKT | B_TX_REPEAT_PKT);
5622 }
5623
hdmi_tx_avi_infoframe_process(struct it6161 * it6161)5624 static int hdmi_tx_avi_infoframe_process(struct it6161 *it6161)
5625 {
5626 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
5627 int err;
5628
5629 hdmi_tx_disable_avi_infoframe(it6161);
5630 err = hdmi_tx_get_avi_infoframe(it6161, buffer, sizeof(buffer));
5631
5632 if (err)
5633 return err;
5634
5635 hdmi_tx_setup_avi_infoframe(it6161, buffer, sizeof(buffer));
5636 hdmi_tx_enable_avi_infoframe(it6161);
5637
5638 DRM_INFO("avi_infoframe:0x%*ph", (int)ARRAY_SIZE(buffer), buffer);
5639
5640 return 0;
5641 }
5642
hdmi_tx_set_output_process(struct it6161 * it6161)5643 static void hdmi_tx_set_output_process(struct it6161 *it6161)
5644 {
5645 VIDEOPCLKLEVEL level;
5646 u32 TMDSClock;
5647
5648 TMDSClock = it6161->hdmi_tx_pclk * 1000 * (it6161->source_avi_infoframe.pixel_repeat + 1);
5649
5650 HDMITX_DisableAudioOutput(it6161);
5651 //hdmi_tx_hdcp_reset_auth(it6161);
5652 hdmi_tx_disable_avi_infoframe(it6161);
5653 HDMITX_EnableVSInfoFrame(it6161, false,NULL);
5654
5655 if (TMDSClock > 80000000L) {
5656 level = PCLK_HIGH ;
5657 } else if(TMDSClock > 20000000L) {
5658 level = PCLK_MEDIUM ;
5659 } else {
5660 level = PCLK_LOW ;
5661 }
5662
5663 hdmi_tx_enable_video_output(it6161, level);
5664
5665 if (it6161->hdmi_mode) {
5666 #ifdef OUTPUT_3D_MODE
5667 ConfigfHdmiVendorSpecificInfoFrame(it6161, OUTPUT_3D_MODE);
5668 #endif
5669
5670 hdmi_tx_avi_infoframe_process(it6161);
5671 hdmi_tx_audio_process(it6161);
5672
5673 // if( it6161->support_audio )
5674 // {
5675 // ConfigAudioInfoFrm(it6161);
5676 // #ifdef SUPPORT_HBR_AUDIO
5677 // HDMITX_EnableAudioOutput(it6161, T_AUDIO_HBR, CONFIG_INPUT_AUDIO_INTERFACE, 768000L,8,NULL,TMDSClock);
5678 // #else
5679 // // HDMITX_EnableAudioOutput(it6161, T_AUDIO_LPCM, false, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,TMDSClock);
5680 // HDMITX_EnableAudioOutput(it6161, CNOFIG_INPUT_AUDIO_TYPE, CONFIG_INPUT_AUDIO_INTERFACE, ulAudioSampleFS,bOutputAudioChannel,NULL,TMDSClock);
5681 // #endif
5682 // }
5683
5684 }
5685
5686 #ifdef SUPPORT_CEC
5687 it6161_hdmi_tx_change_bank(it6161, 0);
5688 it6161_hdmi_tx_write(it6161, 0xf, 0 );
5689 Initial_Ext_Int1();
5690 HDMITX_CEC_Init();
5691 #endif // SUPPORT_CEC
5692 it6161_hdmi_tx_set_av_mute(it6161, false);
5693 bChangeMode = false ;
5694 }
5695
5696 /*void HDMITX_ChangeAudioOption(u8 Option, u8 channelNum, u8 AudioFs)
5697 {
5698
5699 switch(Option )
5700 {
5701 case T_AUDIO_HBR :
5702 bOutputAudioType = T_AUDIO_HBR ;
5703 ulAudioSampleFS = 768000L ;
5704 bOutputAudioChannel = 8 ;
5705 return ;
5706 case T_AUDIO_NLPCM :
5707 bOutputAudioType = T_AUDIO_NLPCM ;
5708 bOutputAudioChannel = 2 ;
5709 break ;
5710 default:
5711 bOutputAudioType = T_AUDIO_LPCM ;
5712 if( channelNum < 1 )
5713 {
5714 bOutputAudioChannel = 1 ;
5715 }
5716 else if( channelNum > 8 )
5717 {
5718 bOutputAudioChannel = 8 ;
5719 }
5720 else
5721 {
5722 bOutputAudioChannel = channelNum ;
5723 }
5724 break ;
5725 }
5726
5727 switch(AudioFs)
5728 {
5729 case AUDFS_44p1KHz:
5730 ulAudioSampleFS = 44100L ;
5731 break ;
5732 case AUDFS_88p2KHz:
5733 ulAudioSampleFS = 88200L ;
5734 break ;
5735 case AUDFS_176p4KHz:
5736 ulAudioSampleFS = 176400L ;
5737 break ;
5738
5739 case AUDFS_48KHz:
5740 ulAudioSampleFS = 48000L ;
5741 break ;
5742 case AUDFS_96KHz:
5743 ulAudioSampleFS = 96000L ;
5744 break ;
5745 case AUDFS_192KHz:
5746 ulAudioSampleFS = 192000L ;
5747 break ;
5748
5749 case AUDFS_768KHz:
5750 ulAudioSampleFS = 768000L ;
5751 break ;
5752
5753 case AUDFS_32KHz:
5754 ulAudioSampleFS = 32000L ;
5755 break ;
5756 default:
5757 ulAudioSampleFS = 48000L ;
5758 break ;
5759 }
5760 DRM_INFO("HDMITX_ChangeAudioOption():bOutputAudioType = %02X, ulAudioSampleFS = %8ld, bOutputAudioChannel = %d\n",(int)bOutputAudioType,ulAudioSampleFS,(int)bOutputAudioChannel);
5761 }
5762 */
5763
5764 #ifdef HDMITX_AUTO_MONITOR_INPUT
5765
HDMITX_MonitorInputAudioChange()5766 void HDMITX_MonitorInputAudioChange()
5767 {
5768 static u32 prevAudioSampleFS = 0 ;
5769 u32 AudioFS ;
5770
5771 if( !it6161->support_audio )
5772 {
5773 prevAudioSampleFS = 0 ;
5774 }
5775 else
5776 {
5777 AudioFS = CalcAudFS() ;
5778 DRM_INFO1(("Audio Chagne, Audio clock = %dHz\n",AudioFS)) ;
5779 if( AudioFS > 188000L ) // 192KHz
5780 {
5781 ulAudioSampleFS = 192000L ;
5782 }
5783 else if( AudioFS > 144000L ) // 176.4KHz
5784 {
5785 ulAudioSampleFS = 176400L ;
5786 }
5787 else if( AudioFS > 93000L ) // 96KHz
5788 {
5789 ulAudioSampleFS = 96000L ;
5790 }
5791 else if( AudioFS > 80000L ) // 88.2KHz
5792 {
5793 ulAudioSampleFS = 88200L ;
5794 }
5795 else if( AudioFS > 45000L ) // 48 KHz
5796 {
5797 ulAudioSampleFS = 48000L ;
5798 }
5799 else if( AudioFS > 36000L ) // 44.1KHz
5800 {
5801 ulAudioSampleFS = 44100L ;
5802 }
5803 else // 32KHz
5804 {
5805 ulAudioSampleFS = 32000L ;
5806 }
5807
5808 if(!bChangeMode)
5809 {
5810 if( ulAudioSampleFS != prevAudioSampleFS )
5811 {
5812 DRM_INFO("ulAudioSampleFS = %dHz -> %dHz\n",ulAudioSampleFS,ulAudioSampleFS);
5813 ConfigAudioInfoFrm(it6161, 2);
5814 HDMITX_EnableAudioOutput(it6161, CNOFIG_INPUT_AUDIO_TYPE, CONFIG_INPUT_AUDIO_INTERFACE, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,0);
5815 // HDMITX_EnableAudioOutput(it6161, T_AUDIO_LPCM, false, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,0);
5816
5817 }
5818 }
5819
5820 prevAudioSampleFS = ulAudioSampleFS ;
5821
5822 }
5823 }
5824
5825 #endif // HDMITX_AUTO_MONITOR_INPUT
5826
mipi_rx_calc_rclk(struct it6161 * it6161)5827 static void mipi_rx_calc_rclk(struct it6161 *it6161)
5828 {
5829 u32 sum = 0, i, retry = 5;
5830 int t10usint;
5831
5832 //it6161_hdmi_tx_write(it6161, 0x8D, (CEC_I2C_SLAVE_ADDR|0x01));// Enable CRCLK
5833 for (i = 0; i < retry; i++) {
5834 it6161_mipi_rx_set_bits(it6161, 0x94, 0x80, 0x80); // Enable RCLK 100ms count
5835 msleep(100);
5836 it6161_mipi_rx_set_bits(it6161, 0x94, 0x80, 0x00); // Disable RCLK 100ms count
5837
5838 it6161->mipi_rx_rclk = it6161_mipi_rx_read(it6161, 0x97);
5839 it6161->mipi_rx_rclk <<= 8;
5840 it6161->mipi_rx_rclk += it6161_mipi_rx_read(it6161, 0x96);
5841 it6161->mipi_rx_rclk <<=8;
5842 it6161->mipi_rx_rclk += it6161_mipi_rx_read(it6161, 0x95);
5843 sum += it6161->mipi_rx_rclk;
5844 }
5845
5846 sum /= retry;
5847 DRM_INFO("rclk: %d\n", sum);
5848 //it6161->mipi_rx_rclk = sum / 100;
5849 it6161->mipi_rx_rclk = sum / 104;
5850 t10usint = it6161->mipi_rx_rclk / 108;//actually nxp platform msleep(100) is 108ms
5851 DRM_INFO("it6161->mipi_rx_rclk = %d,%03d,%03d\n",(sum*10)/1000000,((sum*10)%1000000)/1000,((sum*10)%100));
5852 DRM_INFO("T10usInt=0x%03X\n", (int)t10usint);
5853 it6161_mipi_rx_write(it6161, 0x91, t10usint&0xFF);
5854 }
5855
mipi_rx_calc_mclk(struct it6161 * it6161)5856 static void mipi_rx_calc_mclk(struct it6161 *it6161)
5857 {
5858 u32 i, rddata, sum = 0, calc_time = 3;
5859
5860 for (i = 0; i < calc_time; i++) {
5861 it6161_mipi_rx_set_bits(it6161, 0x9B, 0x80, 0x80);
5862 msleep(5);
5863 it6161_mipi_rx_set_bits(it6161, 0x9B, 0x80, 0x00);
5864
5865 rddata = it6161_mipi_rx_read(it6161, 0x9B) & 0x0F;
5866 rddata <<= 8;
5867 rddata += it6161_mipi_rx_read(it6161, 0x9A);
5868
5869 sum += rddata;
5870 }
5871
5872 sum /= calc_time;
5873 it6161->mipi_rx_mclk = it6161->mipi_rx_rclk * 2048 / sum;
5874 DRM_INFO("MCLK = %d.%03dMHz", it6161->mipi_rx_mclk / 1000, it6161->mipi_rx_mclk % 1000);
5875 }
5876
mipi_rx_calc_pclk(struct it6161 * it6161)5877 static void mipi_rx_calc_pclk(struct it6161 *it6161)
5878 {
5879 u32 rddata, sum = 0, retry = 3;
5880 u8 i;
5881
5882 it6161_mipi_rx_set_bits(it6161, 0x99, 0x80, 0x00);
5883
5884 for (i = 0; i < retry; i++) {
5885 it6161_mipi_rx_set_bits(it6161, 0x99, 0x80, 0x80);
5886 msleep(5);
5887 it6161_mipi_rx_set_bits(it6161, 0x99, 0x80, 0x00);
5888 msleep(1);
5889
5890 rddata = it6161_mipi_rx_read(it6161, 0x99) & 0x0F;
5891 rddata <<= 8;
5892 rddata += it6161_mipi_rx_read(it6161, 0x98);
5893 sum += rddata;
5894 }
5895
5896 sum /= retry;
5897 DRM_INFO("pclk: %d\n", sum);
5898 it6161->mipi_rx_pclk = it6161->mipi_rx_rclk * 2048 / sum;
5899 //it6161->mipi_rx_pclk = it6161->mipi_rx_rclk * 1960 / sum;
5900 DRM_INFO("it6161->mipi_rx_pclk = %d.%03dMHz", it6161->mipi_rx_pclk / 1000, it6161->mipi_rx_pclk % 1000);
5901 }
5902
mipi_rx_show_mrec(struct it6161 * it6161)5903 static void mipi_rx_show_mrec(struct it6161 *it6161)
5904 {
5905 int m_hfront_porch, m_hsyncw, m_hback_porch, m_hactive, MHVR2nd, MHBlank;
5906 int m_vfront_porch, m_vsyncw, m_vback_porch, m_vactive, MVFP2nd, MVTotal;
5907
5908
5909 m_hfront_porch = mipi_rx_read_word(it6161, 0x50) & 0x3FFF;
5910 m_hsyncw = mipi_rx_read_word(it6161, 0x52) & 0x3FFF;
5911 m_hback_porch = mipi_rx_read_word(it6161, 0x54) & 0x3FFF;
5912 m_hactive = mipi_rx_read_word(it6161, 0x56) & 0x3FFF;
5913 MHVR2nd = mipi_rx_read_word(it6161, 0x58) & 0x3FFF;
5914
5915 MHBlank = m_hfront_porch + m_hsyncw + m_hback_porch;
5916
5917 m_vfront_porch = mipi_rx_read_word(it6161, 0x5A) & 0x3FFF;
5918 m_vsyncw = mipi_rx_read_word(it6161, 0x5C) & 0x3FFF;
5919 m_vback_porch = mipi_rx_read_word(it6161, 0x5E) & 0x3FFF;
5920 m_vactive = mipi_rx_read_word(it6161, 0x60) & 0x3FFF;
5921 MVFP2nd = mipi_rx_read_word(it6161, 0x62) & 0x3FFF;
5922
5923 MVTotal = m_vfront_porch + m_vsyncw + m_vback_porch + m_vactive ;
5924
5925 DRM_INFO("m_hfront_porch = %d\n", m_hfront_porch);
5926 DRM_INFO("m_hsyncw = %d\n", m_hsyncw);
5927 DRM_INFO("m_hback_porch = %d\n", m_hback_porch);
5928 DRM_INFO("m_hactive = %d\n", m_hactive);
5929 DRM_INFO("MHVR2nd = %d\n", MHVR2nd);
5930 DRM_INFO("MHBlank = %d\n", MHBlank);
5931
5932 DRM_INFO("m_vfront_porch = %d\n", m_vfront_porch);
5933 DRM_INFO("m_vsyncw = %d\n", m_vsyncw);
5934 DRM_INFO("m_vback_porch = %d\n", m_vback_porch);
5935 DRM_INFO("m_vactive = %d\n", m_vactive);
5936 DRM_INFO("MVFP2nd = %d\n", MVFP2nd);
5937 DRM_INFO("MVTotal = %d\n", MVTotal);
5938 }
5939
mipi_rx_prec_get_display_mode(struct it6161 * it6161)5940 static void mipi_rx_prec_get_display_mode(struct it6161 *it6161)
5941 {
5942 struct drm_display_mode *display_mode = &it6161->mipi_rx_p_display_mode;
5943 struct device *dev = &it6161->i2c_hdmi_tx->dev;
5944 int p_hfront_porch, p_hsyncw, p_hback_porch, p_hactive, p_htotal;
5945 int p_vfront_porch, p_vsyncw, p_vback_porch, p_vactive, p_vtotal;
5946
5947 p_hfront_porch = mipi_rx_read_word(it6161, 0x30) & 0x3FFF;
5948 p_hsyncw = mipi_rx_read_word(it6161, 0x32) & 0x3FFF;
5949 p_hback_porch = mipi_rx_read_word(it6161, 0x34) & 0x3FFF;
5950 p_hactive = mipi_rx_read_word(it6161, 0x36) & 0x3FFF;
5951 p_htotal = mipi_rx_read_word(it6161, 0x38) & 0x3FFF;
5952
5953 //p_htotal = p_hfront_porch + p_hsyncw + p_hback_porch + p_hactive ;
5954
5955 p_vfront_porch = mipi_rx_read_word(it6161, 0x3A) & 0x3FFF;
5956 p_vsyncw = mipi_rx_read_word(it6161, 0x3C) & 0x3FFF;
5957 p_vback_porch = mipi_rx_read_word(it6161, 0x3E) & 0x3FFF;
5958 p_vactive = mipi_rx_read_word(it6161, 0x40) & 0x3FFF;
5959 p_vtotal = mipi_rx_read_word(it6161, 0x42) & 0x3FFF;
5960
5961 //p_vtotal = p_vfront_porch + p_vsyncw + p_vback_porch + p_vactive ;
5962
5963 display_mode->clock = it6161->mipi_rx_pclk;
5964 display_mode->hdisplay = p_hactive;
5965 display_mode->hsync_start = p_hactive + p_hfront_porch;
5966 display_mode->hsync_end = p_hactive + p_hfront_porch + p_hsyncw;
5967 display_mode->htotal = p_htotal;
5968 display_mode->vdisplay = p_vactive;
5969 display_mode->vsync_start = p_vactive + p_vfront_porch;
5970 display_mode->vsync_end = p_vactive + p_vfront_porch + p_vsyncw;
5971 display_mode->vtotal = p_vtotal;
5972
5973 DRM_DEV_DEBUG_DRIVER(dev, "mipi pixel clock: %d KHz", display_mode->clock);
5974 DRM_INFO("p_hfront_porch = %d\r\n", p_hfront_porch);
5975 DRM_INFO("p_hsyncw = %d\r\n", p_hsyncw);
5976 DRM_INFO("p_hback_porch = %d\r\n", p_hback_porch);
5977 DRM_INFO("p_hactive = %d\r\n", p_hactive);
5978 DRM_INFO("p_htotal = %d\r\n", p_htotal);
5979
5980 DRM_INFO("p_vfront_porch = %d\r\n", p_vfront_porch);
5981 DRM_INFO("p_vsyncw = %d\r\n", p_vsyncw);
5982 DRM_INFO("p_vback_porch = %d\r\n", p_vback_porch);
5983 DRM_INFO("p_vactive = %d\r\n", p_vactive);
5984 DRM_INFO("p_vtotal = %d\r\n", p_vtotal);
5985 }
5986
mipi_rx_reset_p_domain(struct it6161 * it6161)5987 static void mipi_rx_reset_p_domain(struct it6161 *it6161)
5988 {
5989 it6161_mipi_rx_set_bits(it6161, 0x05, 0x04, 0x04); // Video Clock Domain Reset
5990 it6161_mipi_rx_set_bits(it6161, 0x05, 0x04, 0x00); // Release Video Clock Domain Reset
5991 }
5992
it6161_mipi_rx_interrupt_clear(struct it6161 * it6161,u8 reg06,u8 reg07,u8 reg08)5993 static void it6161_mipi_rx_interrupt_clear(struct it6161 *it6161, u8 reg06, u8 reg07, u8 reg08)
5994 {
5995 it6161_mipi_rx_write(it6161, 0x06, reg06);
5996 it6161_mipi_rx_write(it6161, 0x07, reg07);
5997 it6161_mipi_rx_write(it6161, 0x08, reg08);
5998 it6161_debug("mipi rx i2c read reg06:0x%02x reg07:0x%02x reg08:0x%02x",
5999 it6161_mipi_rx_read(it6161, 0x06), it6161_mipi_rx_read(it6161, 0x07), it6161_mipi_rx_read(it6161, 0x08));
6000 }
6001
it6161_mipi_rx_interrupt_reg06_process(struct it6161 * it6161,u8 reg06)6002 static void it6161_mipi_rx_interrupt_reg06_process(struct it6161 *it6161, u8 reg06)
6003 {
6004 bool m_video_stable, p_video_stable;
6005 #ifndef __linux__
6006 struct drm_display_mode *dmt_display_mode;
6007 #endif
6008 u8 data_id;
6009
6010 if (reg06 == 0x00)
6011 return;
6012
6013 if (reg06 & 0x01) {
6014 m_video_stable = mipi_rx_get_m_video_stable(it6161);
6015 DRM_INFO("PPS M video stable Change Interrupt, %sstable", m_video_stable ? "" : "un");
6016
6017 if (m_video_stable) {
6018 data_id = it6161_mipi_rx_read(it6161, 0x28);
6019 DRM_INFO("mipi receive video format: 0x%02x", data_id);
6020 mipi_rx_calc_rclk(it6161);
6021 mipi_rx_calc_mclk(it6161);
6022 mipi_rx_show_mrec(it6161);
6023 mipi_rx_afe_configuration(it6161, data_id);
6024 mipi_rx_reset_p_domain(it6161);
6025 }
6026 }
6027
6028 if(reg06 & 0x02)
6029 {
6030 DRM_INFO("PPS MHSync error interrupt");
6031 }
6032
6033 if(reg06 & 0x04)
6034 {
6035 DRM_INFO("PPS MHDE Error Interrupt");
6036 }
6037
6038 if(reg06 & 0x08)
6039 {
6040 DRM_INFO("PPS MVSync Error Interrupt");
6041 }
6042
6043 if (reg06 & 0x10) {
6044 p_video_stable = mipi_rx_get_p_video_stable(it6161);
6045 DRM_INFO("PPS P video stable Change Interrupt, %sstable", p_video_stable ? "" : "un");
6046 it6161_debug("cancel restart work\n");
6047 cancel_delayed_work(&it6161->restart);
6048
6049 if (p_video_stable) {
6050 DRM_INFO("PVidStb Change to HIGH");
6051 mipi_rx_calc_rclk(it6161);
6052 mipi_rx_calc_pclk(it6161);
6053 mipi_rx_prec_get_display_mode(it6161);
6054 it6161->vic = drm_match_cea_mode(&it6161->mipi_rx_p_display_mode);
6055
6056 #ifndef __linux__
6057 if (it6161->vic == 0) {
6058 dmt_display_mode = drm_match_dmt_mode(&it6161->mipi_rx_p_display_mode);
6059
6060 if (dmt_display_mode)
6061 it6161->source_display_mode = *dmt_display_mode;
6062
6063 DRM_INFO("%sfind dmt timing", dmt_display_mode ? "" : "not ");
6064 } else {
6065 it6161->source_display_mode = edid_cea_modes[it6161->vic];
6066 }
6067 #endif
6068
6069 DRM_INFO("source output vic: %d, %s cea timing", it6161->vic, it6161->vic ? " standard" : " not");
6070 show_display_mode(it6161, &it6161->source_display_mode, 0);
6071
6072 show_display_mode(it6161, &it6161->mipi_rx_p_display_mode, 2);
6073 mipi_rx_setup_polarity(it6161);
6074 it6161_mipi_rx_write(it6161, 0xC0,(EnTxCRC<<7) +TxCRCnum);
6075 // setup 1 sec timer interrupt
6076 it6161_mipi_rx_set_bits(it6161, 0x0b,0x40, 0x40);
6077
6078 switch (it6161->hdmi_tx_mode) {
6079 case HDMI_TX_BY_PASS:
6080 it6161_hdmi_tx_set_bits(it6161, 0xA9, 0x80, 0x80);
6081 break;
6082
6083 case HDMI_TX_ENABLE_DE_ONLY:
6084 hdmi_tx_generate_blank_timing(it6161);
6085 break;
6086
6087 case HDMI_TX_ENABLE_PATTERN_GENERATOR:
6088 hdmi_tx_setup_pattern_generator(it6161);
6089 break;
6090
6091 default:
6092 DRM_INFO("use hdmi tx normal mode");
6093 break;
6094 }
6095
6096 hdmi_tx_video_reset(it6161);
6097 }
6098 }
6099
6100 if(reg06 & 0x20)
6101 {
6102 if(DisPHSyncErr == false)
6103 {
6104 DRM_INFO("PPS PHSync Error Interrupt");
6105 }
6106 }
6107
6108 if(reg06 & 0x40)
6109 {
6110 DRM_INFO("PPS PHDE Error Interrupt");
6111 }
6112
6113 if(reg06 & 0x80)
6114 {
6115 DRM_INFO("PPS MVDE Error Interrupt");
6116 }
6117 }
6118
it6161_mipi_rx_interrupt_reg07_process(struct it6161 * it6161,u8 reg07)6119 static void it6161_mipi_rx_interrupt_reg07_process(struct it6161 *it6161, u8 reg07)
6120 {
6121 if (reg07 == 0x00)
6122 return;
6123
6124 if(reg07 & 0x01)
6125 {
6126 DRM_INFO("PatGen PPGVidStb change interrupt !!!\n");
6127 }
6128
6129 if(reg07 & 0x02)
6130 {
6131 DRM_INFO("PPS Data Byte Error Interrupt !!!\n");
6132 }
6133
6134 if(reg07 & 0x04)
6135 {
6136 DRM_INFO("PPS CMOff Interrupt !!!\n");
6137 }
6138
6139 if(reg07 & 0x08)
6140 {
6141 DRM_INFO("PPS CMOn Interrupt !!!\n");
6142 }
6143
6144 if(reg07 & 0x10)
6145 {
6146 DRM_INFO("PPS ShutDone cmd Interrupt !!! \n");
6147 }
6148
6149 if(reg07 & 0x20)
6150 {
6151 DRM_INFO("PPS TurnOn Interrupt !!!\n");
6152 }
6153
6154 if((reg07 & 0x40) || (reg07 & 0x80))
6155 {
6156 if( reg07&0x40 ) {
6157 DRM_INFO("PPS FIFO over read Interrupt !!! tx video stable:%d", hdmi_tx_get_video_state(it6161));
6158 it6161_mipi_rx_set_bits(it6161, 0x07, 0x40, 0x40);
6159 }
6160 if( reg07&0x80 ) {
6161 DRM_INFO("PPS FIFO over write Interrupt !!!\n");
6162 it6161_mipi_rx_set_bits(it6161, 0x07, 0x80, 0x80);
6163 }
6164 }
6165 }
6166
it6161_mipi_rx_interrupt_reg08_process(struct it6161 * it6161,u8 reg08)6167 static void it6161_mipi_rx_interrupt_reg08_process(struct it6161 *it6161, u8 reg08)
6168 {
6169 int crc;
6170
6171 if (reg08 == 0x00)
6172 return;
6173
6174 if(reg08 & 0x01)
6175 {
6176 if(DisECCErr == false)
6177 {
6178 DRM_INFO("ECC 1-bit Error Interrupt !!!\n");
6179 }
6180 }
6181
6182 if(reg08 & 0x02)
6183 {
6184 if(DisECCErr == false)
6185 {
6186 DRM_INFO("ECC 2-bit Error Interrupt !!!\n");
6187 }
6188 }
6189
6190 if(reg08 & 0x04)
6191 {
6192 DRM_INFO("LM FIFO Error Interrupt !!!\n");
6193 }
6194
6195 if(reg08 & 0x08)
6196 {
6197 DRM_INFO("CRC Error Interrupt !!!\n");
6198 }
6199
6200 if(reg08 & 0x10)
6201 {
6202 DRM_INFO("MCLK Off Interrupt !!!\n");
6203 //DRM_INFO("setP1_6 High Mipi not Stable\n");
6204 //P1_6=1;
6205 }
6206
6207 if(reg08 & 0x20)
6208 {
6209 DRM_INFO("PPI FIFO OverWrite Interrupt !!!\n");
6210 }
6211
6212 if(reg08 & 0x40)
6213 {
6214 DRM_INFO("FW Timer Interrupt !!!\n");
6215 it6161_mipi_rx_set_bits(it6161, 0x0b, 0x40, 0x00);
6216
6217 if((it6161_mipi_rx_read(it6161, 0xC1)&0x03) == 0x03)
6218 {
6219 DRM_INFO("CRC Fail !!!\n");
6220 }
6221 if((it6161_mipi_rx_read(it6161, 0xC1)&0x05) == 0x05)
6222 {
6223 DRM_INFO("CRC Pass !!!\n");
6224 crc = it6161_mipi_rx_read(it6161, 0xC2) + (it6161_mipi_rx_read(it6161, 0xC3) <<8);
6225 DRM_INFO("CRCR = 0x%x !!!\n" , crc);
6226 crc = it6161_mipi_rx_read(it6161, 0xC4) + (it6161_mipi_rx_read(it6161, 0xC5) <<8);
6227 DRM_INFO("CRCG = 0x%x !!!\n" , crc);
6228 crc = it6161_mipi_rx_read(it6161, 0xC6) + (it6161_mipi_rx_read(it6161, 0xC7) <<8);
6229 DRM_INFO("CRCB = 0x%x !!!\n" , crc);
6230 }
6231 }
6232 }
6233
it6161_hdmi_tx_interrupt_clear(struct it6161 * it6161,u8 reg06,u8 reg07,u8 reg08,u8 regee)6234 static void it6161_hdmi_tx_interrupt_clear(struct it6161 *it6161, u8 reg06, u8 reg07, u8 reg08, u8 regee)
6235 {
6236 u8 int_clear;
6237
6238 if(reg06 & B_TX_INT_AUD_OVERFLOW) {
6239 DRM_INFO("B_TX_INT_AUD_OVERFLOW");
6240 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST), (B_HDMITX_AUD_RST|B_TX_AREF_RST));
6241 it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST|B_TX_AREF_RST, 0x00);
6242 //AudioDelayCnt=AudioOutDelayCnt;
6243 //LastRefaudfreqnum=0;
6244 }
6245
6246 if(reg06 & B_TX_INT_DDCFIFO_ERR) {
6247 DRM_INFO("DDC FIFO Error");
6248 it6161_hdmi_tx_clear_ddc_fifo(it6161);
6249 hdmiTxDev[0].bAuthenticated= false ;
6250 }
6251
6252 if(reg06 & B_TX_INT_DDC_BUS_HANG) {
6253 DRM_INFO("DDC BUS HANG");
6254 it6161_hdmi_tx_abort_ddc(it6161);
6255
6256 if (hdmiTxDev[0].bAuthenticated) {
6257 DRM_INFO("when DDC hang,and aborted DDC,the HDCP authentication need to restart");
6258 #ifndef _SUPPORT_HDCP_REPEATER_
6259 #ifdef ENABLE_HDCP
6260 hdmitx_hdcp_ResumeAuthentication(it6161);
6261 #endif
6262 #else
6263 TxHDCP_chg(TxHDCP_AuthFail);
6264 #endif
6265 }
6266 }
6267
6268 /* clear ext interrupt */
6269 it6161_hdmi_tx_write(it6161, 0xEE, regee);
6270 it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR0, 0xFF);
6271 it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR1, 0xFF);
6272 /* write B_TX_INTACTDONE '1' to trigger clear interrupt */
6273 int_clear = (it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS)) | B_TX_CLR_AUD_CTS | B_TX_INTACTDONE ;
6274 it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS, int_clear);
6275
6276 it6161_debug("hdmi tx i2c read reg06:0x%02x reg07:0x%02x reg08:0x%02x regee:0x%02x", it6161_hdmi_tx_read(it6161, 0x06), it6161_hdmi_tx_read(it6161, 0x07), it6161_hdmi_tx_read(it6161, 0x08), it6161_hdmi_tx_read(it6161, 0xEE));
6277 }
6278
it6161_hdmi_tx_interrupt_reg06_process(struct it6161 * it6161,u8 reg06)6279 static void it6161_hdmi_tx_interrupt_reg06_process(struct it6161 *it6161, u8 reg06)
6280 {
6281 //struct device *dev = &it6161->i2c_mipi_rx->dev;
6282 u8 ret;//, reg0e = it6161_hdmi_tx_read(it6161, 0x0e);
6283
6284 if(reg06 & B_TX_INT_HPD_PLUG) {
6285 drm_helper_hpd_irq_event(it6161->connector.dev);
6286 if(hdmi_tx_get_sink_hpd(it6161)) {
6287 DRM_INFO("hpd on");
6288 ret = wait_for_completion_timeout(&it6161->wait_edid_complete, msecs_to_jiffies(2000));
6289
6290 if (ret == 0)
6291 DRM_INFO("wait edid timeout");
6292
6293 it6161->hdmi_tx_output_color_space = OUTPUT_COLOR_MODE;
6294 it6161->hdmi_tx_input_color_space = INPUT_COLOR_MODE;
6295 hdmi_tx_set_capability_from_edid_parse(it6161);
6296 reinit_completion(&it6161->wait_hdcp_event);
6297 hdmi_tx_video_reset(it6161);
6298
6299 bChangeMode=true;
6300 // 1. not only HDMI but DVI need the set the upstream HPD
6301 // 2. Before set upstream HPD , the EDID must be ready.
6302 } else {
6303 DRM_INFO("hpd off");
6304 hdmi_tx_disable_video_output(it6161);
6305 kfree(it6161->edid);
6306 it6161->edid = NULL;
6307
6308 if (it6161->hdmi_tx_mode == HDMI_TX_ENABLE_PATTERN_GENERATOR)
6309 hdmi_tx_disable_pattern_generator(it6161);
6310 }
6311 }
6312
6313 if (reg06 & B_TX_INT_RX_SENSE) {
6314 DRM_INFO("rx sense interrupt");
6315 hdmiTxDev[0].bAuthenticated = false;
6316 }
6317 }
6318
it6161_hdmi_tx_interrupt_reg07_process(struct it6161 * it6161,u8 reg07)6319 static void it6161_hdmi_tx_interrupt_reg07_process(struct it6161 *it6161, u8 reg07)
6320 {
6321 bool video_state = hdmi_tx_get_video_state(it6161);
6322
6323 if(reg07 & B_TX_INT_AUTH_DONE) {
6324 DRM_INFO("hdmi tx authenticate done interrupt");
6325 hdmi_tx_hdcp_int_mask_disable(it6161);
6326 hdmiTxDev[0].bAuthenticated = true ;
6327 it6161_hdmi_tx_set_av_mute(it6161, false);
6328 complete(&it6161->wait_hdcp_event);
6329 }
6330 if(reg07 & B_TX_INT_AUTH_FAIL) {
6331 hdmiTxDev[0].bAuthenticated = false;
6332 DRM_INFO("hdmi tx interrupt authenticate fail reg46:0x%02x, start HDCP again", it6161_hdmi_tx_read(it6161, 0x46));
6333 complete(&it6161->wait_hdcp_event);
6334 #ifdef ENABLE_HDCP
6335 hdmi_tx_enable_hdcp(it6161);
6336 #ifdef _SUPPORT_HDCP_REPEATER_
6337 TxHDCP_chg(TxHDCP_AuthFail) ;
6338 #endif
6339 #endif
6340 }
6341
6342 if(reg07 & B_TX_INT_KSVLIST_CHK ) {
6343 DRM_INFO("ksv list event interrupt");
6344 schedule_work(&it6161->wait_hdcp_ksv_list);
6345 }
6346
6347 if (reg07 & B_TX_INT_VID_UNSTABLE) {
6348 if (!video_state)
6349 DRM_INFO("hdmi tx interrupt video unstable!");
6350 }
6351 }
6352
it6161_hdmi_tx_interrupt_reg08_process(struct it6161 * it6161,u8 reg08)6353 static void it6161_hdmi_tx_interrupt_reg08_process(struct it6161 *it6161, u8 reg08)
6354 {
6355 if (reg08 & B_TX_INT_VIDSTABLE) {
6356 it6161_hdmi_tx_write(it6161, REG_TX_INT_STAT3, reg08);
6357 if (hdmi_tx_get_video_state(it6161)) {
6358 DRM_INFO("hdmi tx interrupt video stable link status:%d, rx reg0d:0x%02x start HDCP", getHDMITX_LinkStatus(), it6161_mipi_rx_read(it6161, 0x0D));
6359 hdmi_tx_get_display_mode(it6161);
6360 show_display_mode(it6161, &it6161->source_display_mode, 0);
6361 show_display_mode(it6161, &it6161->hdmi_tx_display_mode, 1);
6362 hdmi_tx_set_output_process(it6161);
6363 #ifdef ENABLE_HDCP
6364 hdmi_tx_enable_hdcp(it6161);
6365 #endif
6366 }
6367 }
6368 }
6369
it6161_hdmi_tx_interrupt_regee_process(struct it6161 * it6161,u8 regee)6370 static void it6161_hdmi_tx_interrupt_regee_process(struct it6161 *it6161, u8 regee)
6371 {
6372 if (regee != 0x00) {
6373 DRM_INFO("%s%s%s%s%s%s%s",
6374 (regee & 0x40) ? "video parameter change ":"",
6375 (regee & 0x20) ? "HDCP Pj check done ":"",
6376 (regee & 0x10) ? "HDCP Ri check done ":"",
6377 (regee & 0x8) ? "DDC bus hang ":"",
6378 (regee & 0x4) ? "Video input FIFO auto reset ":"",
6379 (regee & 0x2) ? "No audio input interrupt ":"",
6380 (regee & 0x1) ? "Audio decode error interrupt ":"");
6381 }
6382 }
6383
it6161_intp_threaded_handler(int unused,void * data)6384 static irqreturn_t it6161_intp_threaded_handler(int unused, void *data)
6385 {
6386 struct it6161 *it6161 = data;
6387 //struct device *dev = &it6161->i2c_mipi_rx->dev;
6388 u8 mipi_rx_reg06, mipi_rx_reg07, mipi_rx_reg08, mipi_rx_reg0d;
6389 u8 hdmi_tx_reg06, hdmi_tx_reg07, hdmi_tx_reg08, hdmi_tx_regee, hdmi_tx_reg0e;
6390 //it6161_dump = data;
6391
6392 if (it6161->enable_drv_hold)
6393 goto unlock;
6394
6395 mipi_rx_reg06 = it6161_mipi_rx_read(it6161, 0x06);
6396 mipi_rx_reg07 = it6161_mipi_rx_read(it6161, 0x07);
6397 mipi_rx_reg08 = it6161_mipi_rx_read(it6161, 0x08);
6398 mipi_rx_reg0d = it6161_mipi_rx_read(it6161, 0x0D);
6399
6400 hdmi_tx_reg06 = it6161_hdmi_tx_read(it6161, 0x06);
6401 hdmi_tx_reg07 = it6161_hdmi_tx_read(it6161, 0x07);
6402 hdmi_tx_reg08 = it6161_hdmi_tx_read(it6161, 0x08);
6403 hdmi_tx_reg0e = it6161_hdmi_tx_read(it6161, 0x0E);
6404 hdmi_tx_regee = it6161_hdmi_tx_read(it6161, 0xEE);
6405
6406 if ((mipi_rx_reg06 != 0) || (mipi_rx_reg07 != 0) || (mipi_rx_reg08 != 0)) {
6407 it6161_debug("rx reg06: 0x%02x reg07:0x%02x reg08:0x%02x reg0d:0x%02x", mipi_rx_reg06, mipi_rx_reg07, mipi_rx_reg08, mipi_rx_reg0d);
6408 it6161_mipi_rx_interrupt_clear(it6161, mipi_rx_reg06, mipi_rx_reg07, mipi_rx_reg08);
6409 }
6410
6411 if ((hdmi_tx_reg06 != 0) || (hdmi_tx_reg07 != 0) || (hdmi_tx_reg08 != 0)) {
6412 it6161_debug("tx reg06: 0x%02x reg07: 0x%02x reg08: 0x%02x reg0e: 0x%02x regee: 0x%02x", hdmi_tx_reg06, hdmi_tx_reg07, hdmi_tx_reg08, hdmi_tx_reg0e, hdmi_tx_regee);
6413 it6161_hdmi_tx_interrupt_clear(it6161, hdmi_tx_reg06, hdmi_tx_reg07, hdmi_tx_reg08, hdmi_tx_regee);
6414 }
6415
6416 it6161_mipi_rx_interrupt_reg08_process(it6161, mipi_rx_reg08);
6417 it6161_mipi_rx_interrupt_reg06_process(it6161, mipi_rx_reg06);
6418 it6161_mipi_rx_interrupt_reg07_process(it6161, mipi_rx_reg07);
6419 it6161_hdmi_tx_interrupt_reg06_process(it6161, hdmi_tx_reg06);
6420 it6161_hdmi_tx_interrupt_reg07_process(it6161, hdmi_tx_reg07);
6421 it6161_hdmi_tx_interrupt_reg08_process(it6161, hdmi_tx_reg08);
6422 it6161_hdmi_tx_interrupt_regee_process(it6161, hdmi_tx_regee);
6423 it6161_debug("end %s", __func__);
6424
6425 unlock:
6426 return IRQ_HANDLED;
6427 }
6428
mipirx_restart(struct work_struct * work)6429 static void mipirx_restart(struct work_struct *work)
6430 {
6431 it6161_debug("****it6161: %s\n", __func__);
6432 it6161_bridge_enable(it6161_bridge);
6433 }
6434
6435 #if 0
6436 static ssize_t enable_drv_hold_show(struct device *dev,
6437 struct device_attribute *attr, char *buf)
6438 {
6439 struct it6161 *it6161 = dev_get_drvdata(dev);
6440
6441 return scnprintf(buf, PAGE_SIZE, "drv_hold: %d\n", it6161->enable_drv_hold);
6442 }
6443
6444 static ssize_t enable_drv_hold_store(struct device *dev,
6445 struct device_attribute *attr,
6446 const char *buf, size_t count)
6447 {
6448 struct it6161 *it6161 = dev_get_drvdata(dev);
6449 unsigned int drv_hold;
6450
6451 if (kstrtoint(buf, 10, &drv_hold) < 0)
6452 return -EINVAL;
6453
6454 it6161->enable_drv_hold = !!drv_hold;
6455
6456 if (it6161->enable_drv_hold) {
6457 it6161_mipi_rx_int_mask_disable(it6161);
6458 it6161_hdmi_tx_int_mask_disable(it6161);
6459 } else {
6460 it6161_mipi_rx_interrupt_clear(it6161, 0xFF, 0xFF, 0xFF);
6461 it6161_hdmi_tx_interrupt_clear(it6161, 0xFF, 0xFF, 0xFF, 0xFF);
6462 it6161_mipi_rx_int_mask_enable(it6161);
6463 it6161_hdmi_tx_int_mask_enable(it6161);
6464 }
6465 return count;
6466 }
6467
6468 static ssize_t hdmi_output_color_space_store(struct device *dev,
6469 struct device_attribute *attr,
6470 const char *buf, size_t count)
6471 {
6472 struct it6161 *it6161 = dev_get_drvdata(dev);
6473
6474 DRM_INFO("config color space: %s", buf);
6475 it6161->hdmi_tx_output_color_space &= ~F_MODE_CLRMOD_MASK;
6476
6477 if (strncmp(buf, "ycbcr444", strlen(buf) - 1) == 0 || strncmp(buf, "yuv444", strlen(buf) - 1) == 0) {
6478 it6161->hdmi_tx_output_color_space |= F_MODE_YUV444;
6479 goto end;
6480 }
6481
6482 if (strncmp(buf, "ycbcr422", strlen(buf) - 1) == 0 || strncmp(buf, "yuv422", strlen(buf) - 1) == 0) {
6483 it6161->hdmi_tx_output_color_space |= F_MODE_YUV422;
6484 goto end;
6485 }
6486
6487 if (strncmp(buf, "rgb444", strlen(buf) - 1) == 0) {
6488 it6161->hdmi_tx_output_color_space |= F_MODE_RGB444;
6489 goto end;
6490 }
6491
6492 DRM_INFO("not support this color space, only support ycbcr444/yuv444, ycbcr422/yuv422, rgb444");
6493 return count;
6494
6495 end:
6496 DRM_INFO("config color space: %s value:0x%02x", buf, it6161->hdmi_tx_output_color_space);
6497 return count;
6498 }
6499
6500 static ssize_t hdmi_output_color_space_show(struct device *dev,
6501 struct device_attribute *attr, char *buf)
6502 {
6503 struct it6161 *it6161 = dev_get_drvdata(dev);
6504 char *str = buf, *end = buf + PAGE_SIZE;
6505
6506 str += scnprintf(str, end - str, "it6161->hdmi_tx_output_color_space:%d\n", it6161->hdmi_tx_output_color_space);
6507
6508 return str - buf;
6509 }
6510 #endif
6511
6512 #if 0
6513 static ssize_t print_timing_show(struct device *dev,
6514 struct device_attribute *attr, char *buf)
6515 {
6516 struct it6161 *it6161 = dev_get_drvdata(dev);
6517 struct drm_display_mode *vid = &it6161->source_display_mode;
6518 char *str = buf, *end = buf + PAGE_SIZE;
6519
6520 str += scnprintf(str, end - str, "---video timing---\n");
6521 str += scnprintf(str, end - str, "PCLK:%d.%03dMHz\n", vid->clock / 1000,
6522 vid->clock % 1000);
6523 str += scnprintf(str, end - str, "HTotal:%d\n", vid->htotal);
6524 str += scnprintf(str, end - str, "HActive:%d\n", vid->hdisplay);
6525 str += scnprintf(str, end - str, "HFrontPorch:%d\n",
6526 vid->hsync_start - vid->hdisplay);
6527 str += scnprintf(str, end - str, "HSyncWidth:%d\n",
6528 vid->hsync_end - vid->hsync_start);
6529 str += scnprintf(str, end - str, "HBackPorch:%d\n",
6530 vid->htotal - vid->hsync_end);
6531 str += scnprintf(str, end - str, "VTotal:%d\n", vid->vtotal);
6532 str += scnprintf(str, end - str, "VActive:%d\n", vid->vdisplay);
6533 str += scnprintf(str, end - str, "VFrontPorch:%d\n",
6534 vid->vsync_start - vid->vdisplay);
6535 str += scnprintf(str, end - str, "VSyncWidth:%d\n",
6536 vid->vsync_end - vid->vsync_start);
6537 str += scnprintf(str, end - str, "VBackPorch:%d\n",
6538 vid->vtotal - vid->vsync_end);
6539
6540 return str - buf;
6541 }
6542
6543 static ssize_t sha_debug_show(struct device *dev, struct device_attribute *attr,
6544 char *buf)
6545 {
6546 int i = 0;
6547 char *str = buf, *end = buf + PAGE_SIZE;
6548 struct it6161 *it6161 = dev_get_drvdata(dev);
6549
6550 str += scnprintf(str, end - str, "sha input:\n");
6551 for (i = 0; i < ARRAY_SIZE(it6161->sha1_input); i += 16)
6552 str += scnprintf(str, end - str, "%16ph\n",
6553 it6161->sha1_input + i);
6554
6555 str += scnprintf(str, end - str, "av:\n");
6556 for (i = 0; i < ARRAY_SIZE(it6161->av); i++)
6557 str += scnprintf(str, end - str, "%4ph\n", it6161->av[i]);
6558
6559 str += scnprintf(str, end - str, "bv:\n");
6560 for (i = 0; i < ARRAY_SIZE(it6161->bv); i++)
6561 str += scnprintf(str, end - str, "%4ph\n", it6161->bv[i]);
6562
6563 return end - str;
6564 }
6565
6566 static ssize_t enable_hdcp_show(struct device *dev,
6567 struct device_attribute *attr, char *buf)
6568 {
6569 struct it6161 *it6161 = dev_get_drvdata(dev);
6570
6571 return scnprintf(buf, PAGE_SIZE, "%d\n", it6161->enable_hdcp);
6572 }
6573
6574 static ssize_t enable_hdcp_store(struct device *dev,
6575 struct device_attribute *attr,
6576 const char *buf, size_t count)
6577 {
6578 struct it6161 *it6161 = dev_get_drvdata(dev);
6579 unsigned int reg3f, hdcp;
6580
6581 if (kstrtoint(buf, 10, &hdcp) < 0)
6582 return -EINVAL;
6583
6584 if (!it6161->powered || it6161->state == SYS_UNPLUG) {
6585 DRM_DEV_DEBUG_DRIVER(dev,
6586 "power down or unplug, can not fire HDCP");
6587 return -EINVAL;
6588 }
6589 it6161->enable_hdcp = hdcp ? true : false;
6590
6591 if (it6161->enable_hdcp) {
6592 if (it6161->cp_capable) {
6593 dptx_sys_chg(it6161, SYS_HDCP);
6594 dptx_sys_fsm(it6161);
6595 } else {
6596 DRM_DEV_ERROR(dev, "sink not support HDCP");
6597 }
6598 } else {
6599 dptx_set_bits(it6161, 0x05, 0x10, 0x10);
6600 dptx_set_bits(it6161, 0x05, 0x10, 0x00);
6601 reg3f = dptx_read(it6161, 0x3F);
6602 hdcp = (reg3f & BIT(7)) >> 7;
6603 DRM_DEV_DEBUG_DRIVER(dev, "%s to disable hdcp",
6604 hdcp ? "failed" : "succeeded");
6605 }
6606 return count;
6607 }
6608
6609 static ssize_t force_pwronoff_store(struct device *dev,
6610 struct device_attribute *attr,
6611 const char *buf, size_t count)
6612 {
6613 struct it6161 *it6161 = dev_get_drvdata(dev);
6614 int pwr;
6615
6616 if (kstrtoint(buf, 10, &pwr) < 0)
6617 return -EINVAL;
6618 if (pwr)
6619 it6161_poweron(it6161);
6620 else
6621 it6161_poweroff(it6161);
6622 return count;
6623 }
6624
6625 static ssize_t pwr_state_show(struct device *dev,
6626 struct device_attribute *attr, char *buf)
6627 {
6628 struct it6161 *it6161 = dev_get_drvdata(dev);
6629
6630 return scnprintf(buf, PAGE_SIZE, "%d\n", it6161->powered);
6631 }
6632
6633 static DEVICE_ATTR_RO(print_timing);
6634 static DEVICE_ATTR_RO(pwr_state);
6635 static DEVICE_ATTR_RO(sha_debug);
6636 static DEVICE_ATTR_WO(force_pwronoff);
6637 static DEVICE_ATTR_RW(enable_hdcp);
6638
6639 static const struct attribute *it6161_attrs[] = {
6640 &dev_attr_enable_drv_hold.attr,
6641 &dev_attr_print_timing.attr,
6642 &dev_attr_sha_debug.attr,
6643 &dev_attr_enable_hdcp.attr,
6644 &dev_attr_force_pwronoff.attr,
6645 &dev_attr_pwr_state.attr,
6646 NULL,
6647 };
6648
6649 static void it6161_shutdown(struct i2c_client *i2c_mipi_rx)
6650 {
6651 struct it6161 *it6161 = dev_get_drvdata(&i2c_mipi_rx->dev);
6652
6653 dptx_sys_chg(it6161, SYS_UNPLUG);
6654 }
6655
6656 #endif
6657
6658 #if 0
6659 static DEVICE_ATTR_RW(enable_drv_hold);
6660 static DEVICE_ATTR_RW(hdmi_output_color_space);
6661
6662 static const struct attribute *it6161_attrs[] = {
6663 &dev_attr_enable_drv_hold.attr,
6664 &dev_attr_hdmi_output_color_space.attr,
6665 NULL,
6666 };
6667 #endif
it6161_parse_dt(struct it6161 * it6161,struct device_node * np)6668 static int it6161_parse_dt(struct it6161 *it6161, struct device_node *np)
6669 {
6670 //struct device *dev = &adv->i2c_mipi_rx->dev;
6671
6672 it6161->host_node = of_graph_get_remote_node(np, 0, 0);
6673 if (!it6161->host_node) {
6674 DRM_INFO("no host node");
6675 return -ENODEV;
6676 }
6677 DRM_INFO("%s", __func__);
6678 of_node_put(it6161->host_node);
6679
6680 return 0;
6681 }
6682
it6161_gpio_init(struct it6161 * it6161)6683 static int it6161_gpio_init(struct it6161 *it6161)
6684 {
6685 struct device *dev = it6161->dev;
6686
6687 it6161->enable_gpio = devm_gpiod_get_optional(dev, "enable",
6688 GPIOD_OUT_LOW);
6689 if (IS_ERR(it6161->enable_gpio)) {
6690 dev_err(dev, "failed to acquire enable gpio\n");
6691 return PTR_ERR(it6161->enable_gpio);
6692 }
6693
6694 it6161->test_gpio = devm_gpiod_get_optional(dev, "test",
6695 GPIOD_OUT_LOW);
6696 if (IS_ERR(it6161->test_gpio)) {
6697 dev_info(dev, "failed to acquire test gpio\n");
6698 }
6699
6700 msleep(20);
6701 gpiod_set_value_cansleep(it6161->enable_gpio, 1);
6702 msleep(20);
6703
6704 return 0;
6705 }
6706
it6161_i2c_probe(struct i2c_client * i2c_mipi_rx,const struct i2c_device_id * id)6707 static int it6161_i2c_probe(struct i2c_client *i2c_mipi_rx,
6708 const struct i2c_device_id *id)
6709 {
6710 //struct it6161 *it6161;
6711 struct device *dev = &i2c_mipi_rx->dev;
6712 int err, intp_irq;
6713
6714 it6161 = devm_kzalloc(dev, sizeof(*it6161), GFP_KERNEL);
6715 if (!it6161)
6716 return -ENOMEM;
6717
6718 it6161_bridge = devm_kzalloc(dev, sizeof(*it6161), GFP_KERNEL);
6719 if (!it6161_bridge)
6720 return -ENOMEM;
6721
6722 it6161->i2c_mipi_rx = i2c_mipi_rx;
6723 it6161->dev = &i2c_mipi_rx->dev;
6724 // mutex_init(&it6161->lock);
6725 mutex_init(&it6161->mode_lock);
6726 //init_completion(&it6161->wait_hdcp_event);
6727 init_completion(&it6161->wait_edid_complete);
6728
6729 //INIT_DELAYED_WORK(&it6161->hdcp_work, hdmi_tx_hdcp_work);
6730 //INIT_WORK(&it6161->wait_hdcp_ksv_list, hdmi_tx_hdcp_auth_part2_process);
6731 // init_waitqueue_head(&it6161->edid_wait);
6732
6733 /* set up mipirx restart work*/
6734 INIT_DELAYED_WORK(&it6161->restart, mipirx_restart);
6735
6736 it6161->bridge.of_node = i2c_mipi_rx->dev.of_node;
6737
6738 it6161_parse_dt(it6161, dev->of_node);
6739 it6161_gpio_init(it6161);
6740
6741 it6161->regmap_mipi_rx =
6742 devm_regmap_init_i2c(i2c_mipi_rx, &it6161_mipi_rx_bridge_regmap_config);
6743 if (IS_ERR(it6161->regmap_mipi_rx)) {
6744 DRM_DEV_ERROR(dev, "regmap_mipi_rx i2c init failed");
6745 return PTR_ERR(it6161->regmap_mipi_rx);
6746 }
6747
6748 if (device_property_read_u32(dev, "it6161-addr-hdmi-tx", &it6161->it6161_addr_hdmi_tx) < 0)
6749 it6161->it6161_addr_hdmi_tx = 0x4c;
6750
6751 it6161->i2c_hdmi_tx = i2c_new_dummy_device(i2c_mipi_rx->adapter, it6161->it6161_addr_hdmi_tx);
6752 if (IS_ERR(it6161->i2c_hdmi_tx)) {
6753 DRM_DEV_ERROR(dev, "Failed to register it6161 I2C device\n");
6754 return PTR_ERR(it6161->i2c_hdmi_tx);
6755 }
6756
6757 it6161->regmap_hdmi_tx =
6758 devm_regmap_init_i2c(it6161->i2c_hdmi_tx, &it6161_hdmi_tx_bridge_regmap_config);
6759
6760 if (IS_ERR(it6161->regmap_hdmi_tx)) {
6761 DRM_DEV_ERROR(dev, "regmap_hdmi_tx i2c init failed");
6762 err = PTR_ERR(it6161->regmap_hdmi_tx);
6763 goto err_hdmitx;
6764 }
6765
6766 if (device_property_read_u32(dev, "it6161-addr-cec", &it6161->it6161_addr_cec) < 0)
6767 it6161->it6161_addr_cec = 0x4E;
6768
6769 it6161->i2c_cec = i2c_new_dummy_device(i2c_mipi_rx->adapter, it6161->it6161_addr_cec);
6770 if (IS_ERR(it6161->i2c_cec)) {
6771 DRM_DEV_ERROR(dev, "i2c_cec init failed");
6772 err = PTR_ERR(it6161->i2c_cec);
6773 goto err_hdmitx;
6774 }
6775
6776 it6161->regmap_cec =
6777 devm_regmap_init_i2c(it6161->i2c_cec, &it6161_cec_bridge_regmap_config);
6778
6779 if (IS_ERR(it6161->regmap_cec)) {
6780 DRM_DEV_ERROR(dev, "regmap_cec i2c init failed");
6781 err = PTR_ERR(it6161->regmap_cec);
6782 goto err_cec;
6783 }
6784
6785 if (!it6161_check_device_ready(it6161)) {
6786 err = -ENODEV;
6787 goto err_cec;
6788 }
6789
6790 it6161->enable_drv_hold = DEFAULT_DRV_HOLD;
6791 it6161_set_interrupts_active_level(HIGH);
6792
6793 intp_irq = i2c_mipi_rx->irq;
6794
6795 if (!intp_irq) {
6796 DRM_DEV_ERROR(dev, "it6112 failed to get INTP IRQ");
6797 err = -ENODEV;
6798 goto err_cec;
6799 }
6800
6801 err = devm_request_threaded_irq(&i2c_mipi_rx->dev, intp_irq, NULL,
6802 /*it6161_intp_threaded_handler,*/it6161_intp_threaded_handler,
6803 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
6804 "it6161-intp", it6161);
6805 if (err) {
6806 DRM_DEV_ERROR(dev, "it6112 failed to request INTP threaded IRQ: %d",
6807 err);
6808 goto err_cec;
6809 }
6810
6811 i2c_set_clientdata(i2c_mipi_rx, it6161);
6812 it6161->bridge.funcs = &it6161_bridge_funcs;
6813 drm_bridge_add(&it6161->bridge);
6814
6815 return 0;
6816
6817 err_cec:
6818 i2c_unregister_device(it6161->i2c_cec);
6819 err_hdmitx:
6820 i2c_unregister_device(it6161->i2c_hdmi_tx);
6821
6822 return err;
6823 }
6824
6825 #if 0
6826 static int it6161_remove(struct i2c_client *i2c_mipi_rx)
6827 {
6828 struct it6161 *it6161 = i2c_get_clientdata(i2c_mipi_rx);
6829
6830 drm_connector_unregister(&it6161->connector);
6831 drm_connector_cleanup(&it6161->connector);
6832 drm_bridge_remove(&it6161->bridge);
6833 // sysfs_remove_files(&i2c_mipi_rx->dev.kobj, it6161_attrs);
6834 // drm_dp_aux_unregister(&it6161->aux);
6835 // it6161_poweroff(it6161);
6836 return 0;
6837 }
6838 #endif
6839 static const struct i2c_device_id it6161_id[] = {
6840 { "it6161", 0 },
6841 { }
6842 };
6843
6844 MODULE_DEVICE_TABLE(i2c, it6161_id);
6845
6846 static const struct of_device_id it6161_of_match[] = {
6847 { .compatible = "ite,it6161" },
6848 { }
6849 };
6850
6851 static struct i2c_driver it6161_i2c_driver = {
6852 .driver = {
6853 .name = "it6161_mipirx_hdmitx",
6854 .of_match_table = it6161_of_match,
6855 //.pm = &it6161_bridge_pm_ops,
6856 },
6857 .probe = it6161_i2c_probe,
6858 //.remove = it6161_remove,
6859 //.shutdown = it6161_shutdown,
6860 .id_table = it6161_id,
6861 };
6862
6863 module_i2c_driver(it6161_i2c_driver);
6864
6865 MODULE_AUTHOR("allen chen <allen.chen@ite.com.tw>");
6866 MODULE_DESCRIPTION("it6161 HDMI Transmitter driver");
6867 MODULE_LICENSE("GPL v2");
6868