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