xref: /aosp_15_r20/external/coreboot/src/drivers/analogix/anx7625/anx7625.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <commonlib/bsd/gcd.h>
5 #include <delay.h>
6 #include <device/i2c_simple.h>
7 #include <edid.h>
8 #include <gpio.h>
9 #include <string.h>
10 #include <types.h>
11 
12 #include "anx7625.h"
13 
14 #define ANXERROR(format, ...) \
15 		printk(BIOS_ERR, "%s: " format, __func__, ##__VA_ARGS__)
16 #define ANXINFO(format, ...) \
17 		printk(BIOS_INFO, "%s: " format, __func__, ##__VA_ARGS__)
18 #define ANXDEBUG(format, ...) \
19 		printk(BIOS_DEBUG, "%s: " format, __func__, ##__VA_ARGS__)
20 
21 /*
22  * There is a sync issue while accessing I2C register between AP(CPU) and
23  * internal firmware(OCM). To avoid the race condition, AP should access the
24  * reserved slave address before slave address changes.
25  */
i2c_access_workaround(uint8_t bus,uint8_t saddr)26 static int i2c_access_workaround(uint8_t bus, uint8_t saddr)
27 {
28 	uint8_t offset;
29 	static uint8_t saddr_backup = 0;
30 	int ret = 0;
31 
32 	if (saddr == saddr_backup)
33 		return ret;
34 
35 	saddr_backup = saddr;
36 
37 	switch (saddr) {
38 	case TCPC_INTERFACE_ADDR:
39 		offset = RSVD_00_ADDR;
40 		break;
41 	case TX_P0_ADDR:
42 		offset = RSVD_D1_ADDR;
43 		break;
44 	case TX_P1_ADDR:
45 		offset = RSVD_60_ADDR;
46 		break;
47 	case RX_P0_ADDR:
48 		offset = RSVD_39_ADDR;
49 		break;
50 	case RX_P1_ADDR:
51 		offset = RSVD_7F_ADDR;
52 		break;
53 	default:
54 		offset = RSVD_00_ADDR;
55 		break;
56 	}
57 
58 	ret = i2c_writeb(bus, saddr, offset, 0x00);
59 	if (ret < 0) {
60 		ANXERROR("Failed to access %#x:%#x\n", saddr, offset);
61 		return ret;
62 	}
63 	return 0;
64 }
65 
anx7625_reg_read(uint8_t bus,uint8_t saddr,uint8_t offset,uint8_t * val)66 static int anx7625_reg_read(uint8_t bus, uint8_t saddr, uint8_t offset,
67 			    uint8_t *val)
68 {
69 	int ret;
70 
71 	i2c_access_workaround(bus, saddr);
72 	ret = i2c_readb(bus, saddr, offset, val);
73 	if (ret < 0) {
74 		ANXERROR("Failed to read i2c reg=%#x:%#x\n", saddr, offset);
75 		return ret;
76 	}
77 	return 0;
78 }
79 
anx7625_reg_block_read(uint8_t bus,uint8_t saddr,uint8_t reg_addr,uint8_t len,uint8_t * buf)80 static int anx7625_reg_block_read(uint8_t bus, uint8_t saddr, uint8_t reg_addr,
81 				  uint8_t len, uint8_t *buf)
82 {
83 	int ret;
84 
85 	i2c_access_workaround(bus, saddr);
86 	ret = i2c_read_bytes(bus, saddr, reg_addr, buf, len);
87 	if (ret < 0) {
88 		ANXERROR("Failed to read i2c block=%#x:%#x[len=%#x]\n", saddr,
89 			 reg_addr, len);
90 		return ret;
91 	}
92 	return 0;
93 }
94 
anx7625_reg_write(uint8_t bus,uint8_t saddr,uint8_t reg_addr,uint8_t reg_val)95 static int anx7625_reg_write(uint8_t bus, uint8_t saddr, uint8_t reg_addr,
96 			     uint8_t reg_val)
97 {
98 	int ret;
99 
100 	i2c_access_workaround(bus, saddr);
101 	ret = i2c_writeb(bus, saddr, reg_addr, reg_val);
102 	if (ret < 0) {
103 		ANXERROR("Failed to write i2c id=%#x:%#x\n", saddr, reg_addr);
104 		return ret;
105 	}
106 	return 0;
107 }
108 
anx7625_write_or(uint8_t bus,uint8_t saddr,uint8_t offset,uint8_t mask)109 static int anx7625_write_or(uint8_t bus, uint8_t saddr, uint8_t offset,
110 			    uint8_t mask)
111 {
112 	uint8_t val;
113 	int ret;
114 
115 	ret = anx7625_reg_read(bus, saddr, offset, &val);
116 	if (ret < 0)
117 		return ret;
118 
119 	return anx7625_reg_write(bus, saddr, offset, val | mask);
120 }
121 
anx7625_write_and(uint8_t bus,uint8_t saddr,uint8_t offset,uint8_t mask)122 static int anx7625_write_and(uint8_t bus, uint8_t saddr, uint8_t offset,
123 			     uint8_t mask)
124 {
125 	int ret;
126 	uint8_t val;
127 
128 	ret = anx7625_reg_read(bus, saddr, offset, &val);
129 	if (ret < 0)
130 		return ret;
131 
132 	return anx7625_reg_write(bus, saddr, offset, val & mask);
133 }
134 
wait_aux_op_finish(uint8_t bus)135 static int wait_aux_op_finish(uint8_t bus)
136 {
137 	uint8_t val;
138 	int ret;
139 
140 	if (!retry(150,
141 		   (anx7625_reg_read(bus, RX_P0_ADDR, AP_AUX_CTRL_STATUS, &val),
142 		    !(val & AP_AUX_CTRL_OP_EN)), mdelay(2))) {
143 		ANXERROR("Timed out waiting aux operation.\n");
144 		return -1;
145 	}
146 
147 	ret = anx7625_reg_read(bus, RX_P0_ADDR, AP_AUX_CTRL_STATUS, &val);
148 	if (ret < 0 || val & 0x0F) {
149 		ANXDEBUG("aux status %02x\n", val);
150 		return -1;
151 	}
152 
153 	return 0;
154 }
155 
156 /* Reduce fraction a/b */
anx7625_reduction_of_a_fraction(u32 * _a,u32 * _b)157 static void anx7625_reduction_of_a_fraction(u32 *_a, u32 *_b)
158 {
159 	u32 gcd_num;
160 	u32 a = *_a, b = *_b, old_a, old_b;
161 	u32 denom = 1;
162 
163 	gcd_num = gcd(a, b);
164 	a /= gcd_num;
165 	b /= gcd_num;
166 
167 	old_a = a;
168 	old_b = b;
169 
170 	while (a > MAX_UNSIGNED_24BIT || b > MAX_UNSIGNED_24BIT) {
171 		denom++;
172 		a = old_a / denom;
173 		b = old_b / denom;
174 	}
175 
176 	/* Increase a, b to have higher ODFC PLL output frequency accuracy. */
177 	while ((a << 1) < MAX_UNSIGNED_24BIT && (b << 1) < MAX_UNSIGNED_24BIT) {
178 		a <<= 1;
179 		b <<= 1;
180 	}
181 
182 	*_a = a;
183 	*_b = b;
184 }
185 
anx7625_calculate_m_n(u32 pixelclock,u32 * m,u32 * n,uint8_t * pd)186 static int anx7625_calculate_m_n(u32 pixelclock, u32 *m, u32 *n, uint8_t *pd)
187 {
188 	uint8_t post_divider = *pd;
189 	if (pixelclock > PLL_OUT_FREQ_ABS_MAX / POST_DIVIDER_MIN) {
190 		/* pixel clock frequency is too high */
191 		ANXERROR("pixelclock %u higher than %lu, "
192 			 "output may be unstable\n",
193 			 pixelclock, PLL_OUT_FREQ_ABS_MAX / POST_DIVIDER_MIN);
194 		return -1;
195 	}
196 
197 	if (pixelclock < PLL_OUT_FREQ_ABS_MIN / POST_DIVIDER_MAX) {
198 		/* pixel clock frequency is too low */
199 		ANXERROR("pixelclock %u lower than %lu, "
200 			 "output may be unstable\n",
201 			 pixelclock, PLL_OUT_FREQ_ABS_MIN / POST_DIVIDER_MAX);
202 		return -1;
203 	}
204 
205 	post_divider = 1;
206 
207 	for (post_divider = 1;
208 	     pixelclock < PLL_OUT_FREQ_MIN / post_divider;
209 	     post_divider++)
210 		;
211 
212 	if (post_divider > POST_DIVIDER_MAX) {
213 		for (post_divider = 1;
214 		     pixelclock < PLL_OUT_FREQ_ABS_MIN / post_divider;
215 		     post_divider++)
216 			;
217 
218 		if (post_divider > POST_DIVIDER_MAX) {
219 			ANXERROR("cannot find property post_divider(%d)\n",
220 				 post_divider);
221 			return -1;
222 		}
223 	}
224 
225 	/* Patch to improve the accuracy */
226 	if (post_divider == 7) {
227 		/* 27,000,000 is not divisible by 7 */
228 		post_divider = 8;
229 	} else if (post_divider == 11) {
230 		/* 27,000,000 is not divisible by 11 */
231 		post_divider = 12;
232 	} else if (post_divider == 13 || post_divider == 14) {
233 		/*27,000,000 is not divisible by 13 or 14*/
234 		post_divider = 15;
235 	}
236 
237 	if (pixelclock * post_divider > PLL_OUT_FREQ_ABS_MAX) {
238 		ANXINFO("act clock(%u) large than maximum(%lu)\n",
239 			pixelclock * post_divider, PLL_OUT_FREQ_ABS_MAX);
240 		return -1;
241 	}
242 
243 	*m = pixelclock;
244 	*n = XTAL_FRQ / post_divider;
245 	*pd = post_divider;
246 
247 	anx7625_reduction_of_a_fraction(m, n);
248 
249 	return 0;
250 }
251 
anx7625_odfc_config(uint8_t bus,uint8_t post_divider)252 static int anx7625_odfc_config(uint8_t bus, uint8_t post_divider)
253 {
254 	int ret;
255 
256 	/* config input reference clock frequency 27MHz/19.2MHz */
257 	ret = anx7625_write_and(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_16,
258 			~(REF_CLK_27000kHz << MIPI_FREF_D_IND));
259 	ret |= anx7625_write_or(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_16,
260 			(REF_CLK_27000kHz << MIPI_FREF_D_IND));
261 	/* post divider */
262 	ret |= anx7625_write_and(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_8, 0x0f);
263 	ret |= anx7625_write_or(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_8,
264 			post_divider << 4);
265 
266 	/* add patch for MIS2-125 (5pcs ANX7625 fail ATE MBIST test) */
267 	ret |= anx7625_write_and(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_7,
268 			~MIPI_PLL_VCO_TUNE_REG_VAL);
269 
270 	/* reset ODFC PLL */
271 	ret |= anx7625_write_and(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_7,
272 			~MIPI_PLL_RESET_N);
273 	ret |= anx7625_write_or(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_7,
274 			MIPI_PLL_RESET_N);
275 
276 	if (ret < 0) {
277 		ANXERROR("IO error.\n");
278 		return ret;
279 	}
280 
281 	return 0;
282 }
283 
anx7625_dsi_video_config(uint8_t bus,struct display_timing * dt)284 static int anx7625_dsi_video_config(uint8_t bus, struct display_timing *dt)
285 {
286 	u32 m, n;
287 	u16 htotal;
288 	int ret;
289 	uint8_t post_divider = 0;
290 
291 	if (anx7625_calculate_m_n(dt->pixelclock * 1000, &m, &n,
292 				  &post_divider) < 0) {
293 		ANXERROR("cannot get property m n value.\n");
294 		return -1;
295 	}
296 
297 	ANXINFO("compute M(%u), N(%u), divider(%d).\n", m, n, post_divider);
298 
299 	/* configure pixel clock */
300 	ret = anx7625_reg_write(bus, RX_P0_ADDR, PIXEL_CLOCK_L,
301 		(dt->pixelclock / 1000) & 0xFF);
302 	ret |= anx7625_reg_write(bus, RX_P0_ADDR, PIXEL_CLOCK_H,
303 		(dt->pixelclock / 1000) >> 8);
304 	/* lane count */
305 	ret |= anx7625_write_and(bus, RX_P1_ADDR, MIPI_LANE_CTRL_0, 0xfc);
306 
307 	ret |= anx7625_write_or(bus, RX_P1_ADDR, MIPI_LANE_CTRL_0, 3);
308 
309 	/* Htotal */
310 	htotal = dt->hactive + dt->hfront_porch +
311 		 dt->hback_porch + dt->hsync_len;
312 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
313 				 HORIZONTAL_TOTAL_PIXELS_L, htotal & 0xFF);
314 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
315 				 HORIZONTAL_TOTAL_PIXELS_H, htotal >> 8);
316 	/* Hactive */
317 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
318 				 HORIZONTAL_ACTIVE_PIXELS_L, dt->hactive & 0xFF);
319 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
320 				 HORIZONTAL_ACTIVE_PIXELS_H, dt->hactive >> 8);
321 	/* HFP */
322 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
323 				 HORIZONTAL_FRONT_PORCH_L, dt->hfront_porch);
324 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
325 				 HORIZONTAL_FRONT_PORCH_H,
326 				 dt->hfront_porch >> 8);
327 	/* HWS */
328 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
329 				 HORIZONTAL_SYNC_WIDTH_L, dt->hsync_len);
330 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
331 				 HORIZONTAL_SYNC_WIDTH_H, dt->hsync_len >> 8);
332 	/* HBP */
333 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
334 				 HORIZONTAL_BACK_PORCH_L, dt->hback_porch);
335 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
336 				 HORIZONTAL_BACK_PORCH_H, dt->hback_porch >> 8);
337 	/* Vactive */
338 	ret |= anx7625_reg_write(bus, RX_P2_ADDR, ACTIVE_LINES_L, dt->vactive);
339 	ret |= anx7625_reg_write(bus, RX_P2_ADDR, ACTIVE_LINES_H,
340 				 dt->vactive >> 8);
341 	/* VFP */
342 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
343 				 VERTICAL_FRONT_PORCH, dt->vfront_porch);
344 	/* VWS */
345 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
346 				 VERTICAL_SYNC_WIDTH, dt->vsync_len);
347 	/* VBP */
348 	ret |= anx7625_reg_write(bus, RX_P2_ADDR,
349 				 VERTICAL_BACK_PORCH, dt->vback_porch);
350 	/* M value */
351 	ret |= anx7625_reg_write(bus, RX_P1_ADDR,
352 				 MIPI_PLL_M_NUM_23_16, (m >> 16) & 0xff);
353 	ret |= anx7625_reg_write(bus, RX_P1_ADDR,
354 				 MIPI_PLL_M_NUM_15_8, (m >> 8) & 0xff);
355 	ret |= anx7625_reg_write(bus, RX_P1_ADDR,
356 				 MIPI_PLL_M_NUM_7_0, (m & 0xff));
357 	/* N value */
358 	ret |= anx7625_reg_write(bus, RX_P1_ADDR,
359 				 MIPI_PLL_N_NUM_23_16, (n >> 16) & 0xff);
360 	ret |= anx7625_reg_write(bus, RX_P1_ADDR,
361 				 MIPI_PLL_N_NUM_15_8, (n >> 8) & 0xff);
362 	ret |= anx7625_reg_write(bus, RX_P1_ADDR, MIPI_PLL_N_NUM_7_0,
363 				 (n & 0xff));
364 	/* diff */
365 	ret |= anx7625_reg_write(bus, RX_P1_ADDR, MIPI_DIGITAL_ADJ_1, dt->k_val);
366 
367 	ret |= anx7625_odfc_config(bus, post_divider - 1);
368 
369 	if (ret < 0) {
370 		ANXERROR("mipi dsi setup IO error.\n");
371 		return ret;
372 	}
373 
374 	return 0;
375 }
376 
anx7625_swap_dsi_lane3(uint8_t bus)377 static int anx7625_swap_dsi_lane3(uint8_t bus)
378 {
379 	int ret;
380 	uint8_t val;
381 
382 	/* swap MIPI-DSI data lane 3 P and N */
383 	ret = anx7625_reg_read(bus, RX_P1_ADDR, MIPI_SWAP, &val);
384 	if (ret < 0) {
385 		ANXERROR("IO error: access MIPI_SWAP.\n");
386 		return ret;
387 	}
388 
389 	val |= (1 << MIPI_SWAP_CH3);
390 	return anx7625_reg_write(bus, RX_P1_ADDR, MIPI_SWAP, val);
391 }
392 
anx7625_api_dsi_config(uint8_t bus,struct display_timing * dt)393 static int anx7625_api_dsi_config(uint8_t bus, struct display_timing *dt)
394 
395 {
396 	int val, ret;
397 
398 	/* swap MIPI-DSI data lane 3 P and N */
399 	ret = anx7625_swap_dsi_lane3(bus);
400 	if (ret < 0) {
401 		ANXERROR("IO error: swap dsi lane 3 failed.\n");
402 		return ret;
403 	}
404 
405 	/* DSI clock settings */
406 	val = (0 << MIPI_HS_PWD_CLK)		|
407 		(0 << MIPI_HS_RT_CLK)		|
408 		(0 << MIPI_PD_CLK)		|
409 		(1 << MIPI_CLK_RT_MANUAL_PD_EN)	|
410 		(1 << MIPI_CLK_HS_MANUAL_PD_EN)	|
411 		(0 << MIPI_CLK_DET_DET_BYPASS)	|
412 		(0 << MIPI_CLK_MISS_CTRL)	|
413 		(0 << MIPI_PD_LPTX_CH_MANUAL_PD_EN);
414 	ret = anx7625_reg_write(bus, RX_P1_ADDR, MIPI_PHY_CONTROL_3, val);
415 
416 	/*
417 	 * Decreased HS prepare tg delay from 160ns to 80ns work with
418 	 *     a) Dragon board 810 series (Qualcomm AP)
419 	 *     b) Moving Pixel DSI source (PG3A pattern generator +
420 	 *        P332 D-PHY Probe) default D-PHY tg 5ns/step
421 	 */
422 	ret |= anx7625_reg_write(bus, RX_P1_ADDR, MIPI_TIME_HS_PRPR, 0x10);
423 
424 	/* enable DSI mode */
425 	ret |= anx7625_write_or(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_18,
426 				SELECT_DSI << MIPI_DPI_SELECT);
427 
428 	ret |= anx7625_dsi_video_config(bus, dt);
429 	if (ret < 0) {
430 		ANXERROR("dsi video tg config failed\n");
431 		return ret;
432 	}
433 
434 	/* toggle m, n ready */
435 	ret = anx7625_write_and(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_6,
436 				~(MIPI_M_NUM_READY | MIPI_N_NUM_READY));
437 	mdelay(1);
438 	ret |= anx7625_write_or(bus, RX_P1_ADDR, MIPI_DIGITAL_PLL_6,
439 				MIPI_M_NUM_READY | MIPI_N_NUM_READY);
440 
441 	/* configure integer stable register */
442 	ret |= anx7625_reg_write(bus, RX_P1_ADDR, MIPI_VIDEO_STABLE_CNT, 0x02);
443 	/* power on MIPI RX */
444 	ret |= anx7625_reg_write(bus, RX_P1_ADDR, MIPI_LANE_CTRL_10, 0x00);
445 	ret |= anx7625_reg_write(bus, RX_P1_ADDR, MIPI_LANE_CTRL_10, 0x80);
446 
447 	if (ret < 0) {
448 		ANXERROR("IO error: mipi dsi enable init failed.\n");
449 		return ret;
450 	}
451 
452 	return 0;
453 }
454 
anx7625_dsi_config(uint8_t bus,struct display_timing * dt)455 static int anx7625_dsi_config(uint8_t bus, struct display_timing *dt)
456 {
457 	int ret;
458 
459 	ANXINFO("config dsi.\n");
460 
461 	/* DSC disable */
462 	ret = anx7625_write_and(bus, RX_P0_ADDR, R_DSC_CTRL_0, ~DSC_EN);
463 	ret |= anx7625_api_dsi_config(bus, dt);
464 
465 	if (ret < 0) {
466 		ANXERROR("IO error: api dsi config error.\n");
467 		return ret;
468 	}
469 
470 	/* set MIPI RX EN */
471 	ret = anx7625_write_or(bus, RX_P0_ADDR, AP_AV_STATUS, AP_MIPI_RX_EN);
472 	/* clear mute flag */
473 	ret |= anx7625_write_and(bus, RX_P0_ADDR, AP_AV_STATUS, ~AP_MIPI_MUTE);
474 
475 	if (ret < 0) {
476 		ANXERROR("IO error: enable mipi rx failed.\n");
477 		return ret;
478 	}
479 
480 	ANXINFO("success to config DSI\n");
481 	return 0;
482 }
483 
sp_tx_rst_aux(uint8_t bus)484 static int sp_tx_rst_aux(uint8_t bus)
485 {
486 	int ret;
487 
488 	ret = anx7625_write_or(bus, TX_P2_ADDR, RST_CTRL2, AUX_RST);
489 	ret |= anx7625_write_and(bus, TX_P2_ADDR, RST_CTRL2, ~AUX_RST);
490 	return ret;
491 }
492 
sp_tx_aux_wr(uint8_t bus,uint8_t offset)493 static int sp_tx_aux_wr(uint8_t bus, uint8_t offset)
494 {
495 	int ret;
496 
497 	ret = anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_BUFF_START, offset);
498 	ret |= anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_COMMAND, 0x04);
499 	ret |= anx7625_write_or(bus, RX_P0_ADDR,
500 				AP_AUX_CTRL_STATUS, AP_AUX_CTRL_OP_EN);
501 	return ret | wait_aux_op_finish(bus);
502 }
503 
sp_tx_aux_rd(uint8_t bus,uint8_t len_cmd)504 static int sp_tx_aux_rd(uint8_t bus, uint8_t len_cmd)
505 {
506 	int ret;
507 
508 	ret = anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_COMMAND, len_cmd);
509 	ret |= anx7625_write_or(bus, RX_P0_ADDR,
510 				AP_AUX_CTRL_STATUS, AP_AUX_CTRL_OP_EN);
511 	return ret | wait_aux_op_finish(bus);
512 }
513 
sp_tx_get_edid_block(uint8_t bus)514 static int sp_tx_get_edid_block(uint8_t bus)
515 {
516 	int ret;
517 	uint8_t val = 0;
518 
519 	sp_tx_aux_wr(bus, 0x7e);
520 	sp_tx_aux_rd(bus, 0x01);
521 	ret = anx7625_reg_read(bus, RX_P0_ADDR, AP_AUX_BUFF_START, &val);
522 
523 	if (ret < 0) {
524 		ANXERROR("IO error: access AUX BUFF.\n");
525 		return -1;
526 	}
527 
528 	ANXINFO("EDID Block = %d\n", val + 1);
529 
530 	if (val > 3)
531 		val = 1;
532 
533 	return val;
534 }
535 
edid_read(uint8_t bus,uint8_t offset,uint8_t * pblock_buf)536 static int edid_read(uint8_t bus, uint8_t offset, uint8_t *pblock_buf)
537 {
538 	int ret, cnt;
539 
540 	for (cnt = 0; cnt < 3; cnt++) {
541 		sp_tx_aux_wr(bus, offset);
542 		/* set I2C read com 0x01 mot = 0 and read 16 bytes */
543 		ret = sp_tx_aux_rd(bus, 0xf1);
544 
545 		if (ret < 0) {
546 			sp_tx_rst_aux(bus);
547 			ANXERROR("edid read failed, reset!\n");
548 		} else {
549 			if (anx7625_reg_block_read(bus, RX_P0_ADDR,
550 						   AP_AUX_BUFF_START,
551 						   MAX_DPCD_BUFFER_SIZE,
552 						   pblock_buf) >= 0)
553 				return 0;
554 		}
555 	}
556 
557 	return -1;
558 }
559 
segments_edid_read(uint8_t bus,uint8_t segment,uint8_t * buf,uint8_t offset)560 static int segments_edid_read(uint8_t bus, uint8_t segment, uint8_t *buf,
561 			      uint8_t offset)
562 {
563 	int ret, cnt;
564 
565 	/* write address only */
566 	ret = anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_ADDR_7_0, 0x30);
567 	ret |= anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_COMMAND, 0x04);
568 	ret |= anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_CTRL_STATUS,
569 				 AP_AUX_CTRL_ADDRONLY | AP_AUX_CTRL_OP_EN);
570 
571 	ret |= wait_aux_op_finish(bus);
572 	/* write segment address */
573 	ret |= sp_tx_aux_wr(bus, segment);
574 	/* data read */
575 	ret |= anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_ADDR_7_0, 0x50);
576 
577 	if (ret < 0) {
578 		ANXERROR("IO error: aux initial failed.\n");
579 		return ret;
580 	}
581 
582 	for (cnt = 0; cnt < 3; cnt++) {
583 		sp_tx_aux_wr(bus, offset);
584 		/* set I2C read com 0x01 mot = 0 and read 16 bytes */
585 		ret = sp_tx_aux_rd(bus, 0xf1);
586 
587 		if (ret < 0) {
588 			sp_tx_rst_aux(bus);
589 			ANXERROR("segment read failed, reset!\n");
590 		} else {
591 			if (anx7625_reg_block_read(bus, RX_P0_ADDR,
592 						   AP_AUX_BUFF_START,
593 						   MAX_DPCD_BUFFER_SIZE,
594 						   buf) >= 0)
595 				return 0;
596 		}
597 	}
598 
599 	return -1;
600 }
601 
sp_tx_edid_read(uint8_t bus,uint8_t * pedid_blocks_buf,uint32_t size)602 static int sp_tx_edid_read(uint8_t bus, uint8_t *pedid_blocks_buf,
603 			   uint32_t size)
604 {
605 	uint8_t offset, edid_pos;
606 	int count, blocks_num;
607 	uint8_t pblock_buf[MAX_DPCD_BUFFER_SIZE];
608 	int i, ret, g_edid_break = 0;
609 
610 	/* address initial */
611 	ret = anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_ADDR_7_0, 0x50);
612 	ret |= anx7625_reg_write(bus, RX_P0_ADDR, AP_AUX_ADDR_15_8, 0);
613 	ret |= anx7625_write_and(bus, RX_P0_ADDR, AP_AUX_ADDR_19_16, 0xf0);
614 
615 	if (ret < 0) {
616 		ANXERROR("access aux channel IO error.\n");
617 		return -1;
618 	}
619 
620 	blocks_num = sp_tx_get_edid_block(bus);
621 	if (blocks_num < 0)
622 		return -1;
623 
624 	count = 0;
625 
626 	do {
627 		switch (count) {
628 		case 0:
629 		case 1:
630 			for (i = 0; i < 8; i++) {
631 				offset = (i + count * 8) * MAX_DPCD_BUFFER_SIZE;
632 				g_edid_break = !!edid_read(bus, offset,
633 							   pblock_buf);
634 
635 				if (g_edid_break)
636 					break;
637 
638 				if (offset <= size - MAX_DPCD_BUFFER_SIZE)
639 					memcpy(&pedid_blocks_buf[offset],
640 					       pblock_buf,
641 					       MAX_DPCD_BUFFER_SIZE);
642 			}
643 
644 			break;
645 		case 2:
646 		case 3:
647 			offset = (count == 2) ? 0x00 : 0x80;
648 
649 			for (i = 0; i < 8; i++) {
650 				edid_pos = (i + count * 8) *
651 					MAX_DPCD_BUFFER_SIZE;
652 
653 				if (g_edid_break)
654 					break;
655 
656 				segments_edid_read(bus, count / 2,
657 						   pblock_buf, offset);
658 				if (edid_pos <= size - MAX_DPCD_BUFFER_SIZE)
659 					memcpy(&pedid_blocks_buf[edid_pos],
660 					       pblock_buf,
661 					       MAX_DPCD_BUFFER_SIZE);
662 				offset = offset + 0x10;
663 			}
664 
665 			break;
666 		default:
667 			die("%s: count should be <= 3", __func__);
668 			break;
669 		}
670 
671 		count++;
672 
673 	} while (blocks_num >= count);
674 
675 	/* reset aux channel */
676 	sp_tx_rst_aux(bus);
677 
678 	return blocks_num;
679 }
680 
anx7625_disable_pd_protocol(uint8_t bus)681 static void anx7625_disable_pd_protocol(uint8_t bus)
682 {
683 	int ret;
684 
685 	/* reset main ocm */
686 	ret = anx7625_reg_write(bus, RX_P0_ADDR, 0x88, 0x40);
687 	/* Disable PD */
688 	ret |= anx7625_reg_write(bus, RX_P0_ADDR, AP_AV_STATUS, AP_DISABLE_PD);
689 	/* release main ocm */
690 	ret |= anx7625_reg_write(bus, RX_P0_ADDR, 0x88, 0x00);
691 
692 	if (ret < 0)
693 		ANXERROR("Failed to disable PD feature.\n");
694 	else
695 		ANXINFO("Disabled PD feature.\n");
696 }
697 
698 #define FLASH_LOAD_STA 0x05
699 #define FLASH_LOAD_STA_CHK	(1 << 7)
700 
anx7625_power_on_init(uint8_t bus)701 static int anx7625_power_on_init(uint8_t bus)
702 {
703 	int i, ret;
704 	uint8_t val, version, revision;
705 
706 	anx7625_reg_write(bus, RX_P0_ADDR, XTAL_FRQ_SEL, XTAL_FRQ_27M);
707 
708 	for (i = 0; i < OCM_LOADING_TIME; i++) {
709 		/* check interface */
710 		ret = anx7625_reg_read(bus, RX_P0_ADDR, FLASH_LOAD_STA, &val);
711 		if (ret < 0) {
712 			ANXERROR("Failed to load flash\n");
713 			return ret;
714 		}
715 
716 		if ((val & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK) {
717 			mdelay(1);
718 			continue;
719 		}
720 		ANXINFO("Init interface.\n");
721 
722 		anx7625_disable_pd_protocol(bus);
723 		anx7625_reg_read(bus, RX_P0_ADDR, OCM_FW_VERSION, &version);
724 		anx7625_reg_read(bus, RX_P0_ADDR, OCM_FW_REVERSION, &revision);
725 		ANXINFO("Firmware: ver %#02x, rev %#02x.\n", version, revision);
726 		return 0;
727 	}
728 	return -1;
729 }
730 
anx7625_start_dp_work(uint8_t bus)731 static void anx7625_start_dp_work(uint8_t bus)
732 {
733 	int ret;
734 	uint8_t val;
735 
736 	/* not support HDCP */
737 	ret = anx7625_write_and(bus, RX_P1_ADDR, 0xee, 0x9f);
738 
739 	/* try auth flag */
740 	ret |= anx7625_write_or(bus, RX_P1_ADDR, 0xec, 0x10);
741 	/* interrupt for DRM */
742 	ret |= anx7625_write_or(bus, RX_P1_ADDR, 0xff, 0x01);
743 	if (ret < 0)
744 		return;
745 
746 	ret = anx7625_reg_read(bus, RX_P1_ADDR, 0x86, &val);
747 	if (ret < 0)
748 		return;
749 
750 	ANXINFO("Secure OCM version=%02x\n", val);
751 }
752 
anx7625_hpd_change_detect(uint8_t bus)753 static int anx7625_hpd_change_detect(uint8_t bus)
754 {
755 	int ret;
756 	uint8_t status;
757 
758 	ret = anx7625_reg_read(bus, RX_P0_ADDR, SYSTEM_STSTUS, &status);
759 	if (ret < 0) {
760 		ANXERROR("IO error: Failed to clear interrupt status.\n");
761 		return ret;
762 	}
763 
764 	if (status & HPD_STATUS) {
765 		anx7625_start_dp_work(bus);
766 		ANXINFO("HPD received 0x7e:0x45=%#x\n", status);
767 		return 1;
768 	}
769 	return 0;
770 }
771 
anx7625_parse_edid(const struct edid * edid,struct display_timing * dt)772 static void anx7625_parse_edid(const struct edid *edid,
773 			       struct display_timing *dt)
774 {
775 	dt->pixelclock = edid->mode.pixel_clock;
776 
777 	dt->hactive = edid->mode.ha;
778 	dt->hsync_len = edid->mode.hspw;
779 	dt->hback_porch = (edid->mode.hbl - edid->mode.hso -
780 			   edid->mode.hborder - edid->mode.hspw);
781 	dt->hfront_porch = edid->mode.hso - edid->mode.hborder;
782 
783 	dt->vactive = edid->mode.va;
784 	dt->vsync_len = edid->mode.vspw;
785 	dt->vfront_porch = edid->mode.vso - edid->mode.vborder;
786 	dt->vback_porch = (edid->mode.vbl - edid->mode.vso -
787 			   edid->mode.vspw - edid->mode.vborder);
788 
789 	/*
790 	 * The k_val is a ratio to match MIPI input and DP output video clocks.
791 	 * Most panels can follow the default value (0x3d).
792 	 * IVO panels have smaller variation than DP CTS spec and need smaller
793 	 * k_val (0x3b).
794 	 */
795 	if (!strncmp(edid->manufacturer_name, "IVO", 3)) {
796 		dt->k_val = 0x3b;
797 		ANXINFO("detected IVO panel, use k value 0x3b\n");
798 	} else {
799 		dt->k_val = 0x3d;
800 		ANXINFO("set default k value to 0x3d for panel\n");
801 	}
802 
803 	ANXINFO("pixelclock(%d).\n"
804 		" hactive(%d), hsync(%d), hfp(%d), hbp(%d)\n"
805 		" vactive(%d), vsync(%d), vfp(%d), vbp(%d)\n",
806 		dt->pixelclock,
807 		dt->hactive, dt->hsync_len, dt->hfront_porch, dt->hback_porch,
808 		dt->vactive, dt->vsync_len, dt->vfront_porch, dt->vback_porch);
809 }
810 
anx7625_dp_start(uint8_t bus,const struct edid * edid)811 int anx7625_dp_start(uint8_t bus, const struct edid *edid)
812 {
813 	int ret;
814 	struct display_timing dt;
815 
816 	anx7625_parse_edid(edid, &dt);
817 
818 	ret = anx7625_dsi_config(bus, &dt);
819 	if (ret < 0) {
820 		ANXERROR("MIPI phy setup error.\n");
821 		return ret;
822 	}
823 
824 	ANXINFO("MIPI phy setup OK.\n");
825 	return 0;
826 }
827 
anx7625_dp_get_edid(uint8_t bus,struct edid * out)828 int anx7625_dp_get_edid(uint8_t bus, struct edid *out)
829 {
830 	int block_num;
831 	int ret;
832 	u8 edid[FOUR_BLOCK_SIZE];
833 
834 	block_num = sp_tx_edid_read(bus, edid, FOUR_BLOCK_SIZE);
835 	if (block_num < 0) {
836 		ANXERROR("Failed to get eDP EDID.\n");
837 		return -1;
838 	}
839 
840 	ret = decode_edid(edid, (block_num + 1) * ONE_BLOCK_SIZE, out);
841 	if (ret != EDID_CONFORMANT) {
842 		ANXERROR("Failed to decode EDID.\n");
843 		return -1;
844 	}
845 
846 	return 0;
847 }
848 
anx7625_init(uint8_t bus)849 int anx7625_init(uint8_t bus)
850 {
851 	int retry_hpd_change = 50;
852 
853 	if (!retry(3, anx7625_power_on_init(bus) >= 0)) {
854 		ANXERROR("Failed to power on.\n");
855 		return -1;
856 	}
857 
858 	while (--retry_hpd_change) {
859 		mdelay(10);
860 		int detected = anx7625_hpd_change_detect(bus);
861 		if (detected < 0)
862 			return -1;
863 		if (detected > 0)
864 			return 0;
865 	}
866 
867 	ANXERROR("Timed out to detect HPD change on bus %d.\n", bus);
868 	return -1;
869 }
870