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