blob: cc96cc85c3d69a6da3d434fd0e791f0c8d875a71 [file] [log] [blame]
Jitao Shi56126602021-05-29 16:26:00 +08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <console/console.h>
4#include <device/mmio.h>
5#include <delay.h>
6#include <edid.h>
7#include <soc/dptx.h>
8#include <soc/dptx_hal.h>
9#include <soc/dptx_reg.h>
10#include <string.h>
11#include <timer.h>
Yu-Ping Wu941db0e2021-07-23 16:17:11 +080012#include <types.h>
Jitao Shi56126602021-05-29 16:26:00 +080013
14#define REG_OFFSET_LIMIT 0x8000
15
16struct shift_mask {
17 u32 shift;
18 u32 mask;
19};
20static const struct shift_mask volt_swing[DPTX_LANE_MAX] = {
21 [DPTX_LANE0] = { DP_TX0_VOLT_SWING_FLDMASK_POS, DP_TX0_VOLT_SWING_FLDMASK },
22 [DPTX_LANE1] = { DP_TX1_VOLT_SWING_FLDMASK_POS, DP_TX1_VOLT_SWING_FLDMASK },
23 [DPTX_LANE2] = { DP_TX2_VOLT_SWING_FLDMASK_POS, DP_TX2_VOLT_SWING_FLDMASK },
24 [DPTX_LANE3] = { DP_TX3_VOLT_SWING_FLDMASK_POS, DP_TX3_VOLT_SWING_FLDMASK },
25};
26static const struct shift_mask volt_preemphasis[DPTX_LANE_MAX] = {
27 [DPTX_LANE0] = { DP_TX0_PRE_EMPH_FLDMASK_POS, DP_TX0_PRE_EMPH_FLDMASK },
28 [DPTX_LANE1] = { DP_TX1_PRE_EMPH_FLDMASK_POS, DP_TX1_PRE_EMPH_FLDMASK },
29 [DPTX_LANE2] = { DP_TX2_PRE_EMPH_FLDMASK_POS, DP_TX2_PRE_EMPH_FLDMASK },
30 [DPTX_LANE3] = { DP_TX3_PRE_EMPH_FLDMASK_POS, DP_TX3_PRE_EMPH_FLDMASK },
31};
32
33u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
34{
35 void *addr = mtk_dp->regs + offset;
36
37 if (offset % 4 != 0 || offset > REG_OFFSET_LIMIT) {
38 printk(BIOS_ERR, "[%s] invalid offset %#x for reg %p\n",
39 __func__, offset, mtk_dp->regs);
40 return 0;
41 }
42
43 return read32(addr);
44}
45
46void mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
47{
48 void *addr = mtk_dp->regs + offset;
49
50 if (offset % 4 != 0 || offset > REG_OFFSET_LIMIT) {
51 printk(BIOS_ERR, "[%s] invalid offset %#x for reg %p\n",
52 __func__, offset, mtk_dp->regs);
53 return;
54 }
55
56 write32(addr, val);
57}
58
59void mtk_dp_mask(struct mtk_dp *mtk_dp, u32 offset, u32 val, u32 mask)
60{
61 void *addr = mtk_dp->regs + offset;
62
63 if (offset % 4 != 0 || offset > REG_OFFSET_LIMIT) {
64 printk(BIOS_ERR, "[%s] invalid offset %#x for reg %p\n",
65 __func__, offset, mtk_dp->regs);
66 return;
67 }
68
69 /*
70 * TODO: modify to clrsetbits32(addr, mask, val);
71 * There is asserion error when testing assert((val & mask) == val).
72 */
73 clrsetbits32(addr, mask, val & mask);
74}
75
76void mtk_dp_write_byte(struct mtk_dp *mtk_dp, u32 addr, u8 val, u32 mask)
77{
78 if (addr % 2) {
79 mtk_dp_write(mtk_dp, DP_TX_TOP_APB_WSTRB, 0x12);
80 mtk_dp_mask(mtk_dp, addr - 1, val << 8, mask << 8);
81 } else {
82 mtk_dp_write(mtk_dp, DP_TX_TOP_APB_WSTRB, 0x11);
83 mtk_dp_mask(mtk_dp, addr, val, mask);
84 }
85
86 mtk_dp_write(mtk_dp, DP_TX_TOP_APB_WSTRB, 0x0);
87}
88
89void dptx_hal_verify_clock(struct mtk_dp *mtk_dp)
90{
91 u32 m, n, ls_clk, pix_clk;
92
93 m = mtk_dp_read(mtk_dp, REG_33C8_DP_ENCODER1_P0);
94 n = 0x8000;
95 ls_clk = mtk_dp->train_info.linkrate;
96 ls_clk *= 27;
97
98 pix_clk = m * ls_clk / n;
99 printk(BIOS_DEBUG, "DPTX calc pixel clock = %d MHz, dp_intf clock = %dMHz\n",
100 pix_clk, pix_clk / 4);
101}
102
103void dptx_hal_init_setting(struct mtk_dp *mtk_dp)
104{
105 DP_WRITE1BYTE(mtk_dp, REG_342C_DP_TRANS_P0, 0x69);
106 mtk_dp_mask(mtk_dp, REG_3540_DP_TRANS_P0, BIT(3), BIT(3));
107 mtk_dp_mask(mtk_dp, REG_31EC_DP_ENCODER0_P0, BIT(4), BIT(4));
108 mtk_dp_mask(mtk_dp, REG_304C_DP_ENCODER0_P0, 0, BIT(8));
109 mtk_dp_mask(mtk_dp, DP_TX_TOP_IRQ_MASK, BIT(2), BIT(2));
110}
111
112void dptx_hal_bypassmsa_en(struct mtk_dp *mtk_dp, bool enable)
113{
114 mtk_dp_mask(mtk_dp, REG_3030_DP_ENCODER0_P0,
115 enable ? 0 : 0x3ff, 0x3ff);
116}
117
118void dptx_hal_set_msa(struct mtk_dp *mtk_dp)
119{
120 u32 va, vsync, vbp, vfp, vtotal, ha, hsync, hbp, hfp, htotal;
121 struct edid *edid = mtk_dp->edid;
122
123 va = edid->mode.va;
124 vsync = edid->mode.vspw;
125 vbp = edid->mode.vbl - edid->mode.vso -
126 edid->mode.vspw - edid->mode.vborder;
127 vfp = edid->mode.vso - edid->mode.vborder;
128
129 ha = edid->mode.ha;
130 hsync = edid->mode.hspw;
131 hbp = edid->mode.hbl - edid->mode.hso -
132 edid->mode.hspw - edid->mode.hborder;
133 hfp = edid->mode.hso - edid->mode.hborder;
134
135 htotal = ha + hsync + hbp + hfp;
136 vtotal = va + vsync + vbp + vfp;
137
138 DP_WRITE2BYTE(mtk_dp, REG_3010_DP_ENCODER0_P0, htotal);
139 DP_WRITE2BYTE(mtk_dp, REG_3018_DP_ENCODER0_P0, hsync + hbp);
140 mtk_dp_mask(mtk_dp, REG_3028_DP_ENCODER0_P0,
141 hsync << HSW_SW_DP_ENCODER0_P0_FLDMASK_POS,
142 HSW_SW_DP_ENCODER0_P0_FLDMASK);
143 mtk_dp_mask(mtk_dp, REG_3028_DP_ENCODER0_P0,
144 0 << HSP_SW_DP_ENCODER0_P0_FLDMASK_POS,
145 HSP_SW_DP_ENCODER0_P0_FLDMASK);
146 DP_WRITE2BYTE(mtk_dp, REG_3020_DP_ENCODER0_P0, ha);
147 DP_WRITE2BYTE(mtk_dp, REG_3014_DP_ENCODER0_P0, va);
148 DP_WRITE2BYTE(mtk_dp, REG_301C_DP_ENCODER0_P0, vsync + vbp);
149 mtk_dp_mask(mtk_dp, REG_302C_DP_ENCODER0_P0,
150 vsync << VSW_SW_DP_ENCODER0_P0_FLDMASK_POS,
151 VSW_SW_DP_ENCODER0_P0_FLDMASK);
152 mtk_dp_mask(mtk_dp, REG_302C_DP_ENCODER0_P0,
153 0 << VSP_SW_DP_ENCODER0_P0_FLDMASK_POS,
154 VSP_SW_DP_ENCODER0_P0_FLDMASK);
155 DP_WRITE2BYTE(mtk_dp, REG_3024_DP_ENCODER0_P0, va);
156 DP_WRITE2BYTE(mtk_dp, REG_3064_DP_ENCODER0_P0, ha);
157 DP_WRITE2BYTE(mtk_dp, REG_3154_DP_ENCODER0_P0, htotal);
158 DP_WRITE2BYTE(mtk_dp, REG_3158_DP_ENCODER0_P0, hfp);
159 DP_WRITE2BYTE(mtk_dp, REG_315C_DP_ENCODER0_P0, vsync);
160 DP_WRITE2BYTE(mtk_dp, REG_3160_DP_ENCODER0_P0, hsync + hbp);
161 DP_WRITE2BYTE(mtk_dp, REG_3164_DP_ENCODER0_P0, ha);
162 DP_WRITE2BYTE(mtk_dp, REG_3168_DP_ENCODER0_P0, vtotal);
163 DP_WRITE2BYTE(mtk_dp, REG_316C_DP_ENCODER0_P0, hfp);
164 DP_WRITE2BYTE(mtk_dp, REG_3170_DP_ENCODER0_P0, vsync);
165 DP_WRITE2BYTE(mtk_dp, REG_3174_DP_ENCODER0_P0, vsync + vbp);
166 DP_WRITE2BYTE(mtk_dp, REG_3178_DP_ENCODER0_P0, va);
167
168 printk(BIOS_INFO, "MSA:Htt(%d), Vtt(%d), Hact(%d), Vact(%d), FPS(%d)\n",
169 htotal, vtotal, ha, va,
170 edid->mode.pixel_clock * 1000 / htotal / vtotal);
171}
172
173void dptx_hal_set_color_format(struct mtk_dp *mtk_dp, u8 out_format)
174{
175 /* MISC0 */
176 mtk_dp_write_byte(mtk_dp, REG_3034_DP_ENCODER0_P0,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800177 out_format << 0x1, GENMASK(2, 1));
Jitao Shi56126602021-05-29 16:26:00 +0800178
179 switch (out_format) {
180 case DP_COLOR_FORMAT_RGB_444:
181 case DP_COLOR_FORMAT_YUV_444:
182 mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800183 0, GENMASK(6, 4));
Jitao Shi56126602021-05-29 16:26:00 +0800184 break;
185 case DP_COLOR_FORMAT_YUV_422:
186 mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800187 BIT(4), GENMASK(6, 4));
Jitao Shi56126602021-05-29 16:26:00 +0800188 break;
189 case DP_COLOR_FORMAT_YUV_420:
190 mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1, BIT(5),
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800191 GENMASK(6, 4));
Jitao Shi56126602021-05-29 16:26:00 +0800192 break;
193 default:
194 break;
195 }
196}
197
198void dptx_hal_set_color_depth(struct mtk_dp *mtk_dp, u8 color_depth)
199{
200 u8 val;
201
202 mtk_dp_write_byte(mtk_dp, REG_3034_DP_ENCODER0_P0,
203 color_depth << 0x5, 0xe0);
204
205 switch (color_depth) {
206 case DP_COLOR_DEPTH_6BIT:
207 val = 4;
208 break;
209 case DP_COLOR_DEPTH_8BIT:
210 val = 3;
211 break;
212 case DP_COLOR_DEPTH_10BIT:
213 val = 2;
214 break;
215 case DP_COLOR_DEPTH_12BIT:
216 val = 1;
217 break;
218 case DP_COLOR_DEPTH_16BIT:
219 val = 0;
220 break;
221 default:
222 return;
223 }
224 mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1, val, 0x7);
225}
226
227void dptx_hal_setmisc(struct mtk_dp *mtk_dp, u8 cmisc[2])
228{
229 mtk_dp_write_byte(mtk_dp, REG_3034_DP_ENCODER0_P0, cmisc[0], 0xfe);
230 mtk_dp_write_byte(mtk_dp, REG_3034_DP_ENCODER0_P0 + 1, cmisc[1], 0xff);
231}
232
233void dptx_hal_overwrite_mn(struct mtk_dp *mtk_dp,
234 bool enable, u32 video_m, u32 video_n)
235{
236 if (enable) {
237 /* Turn on overwrite MN */
238 DP_WRITE2BYTE(mtk_dp, REG_3008_DP_ENCODER0_P0,
239 video_m & 0xffff);
240 DP_WRITE1BYTE(mtk_dp, REG_300C_DP_ENCODER0_P0,
241 (video_m >> 16) & 0xff);
242 DP_WRITE2BYTE(mtk_dp, REG_3044_DP_ENCODER0_P0,
243 video_n & 0xffff);
244 DP_WRITE1BYTE(mtk_dp, REG_3048_DP_ENCODER0_P0,
245 (video_n >> 16) & 0xff);
246 DP_WRITE2BYTE(mtk_dp, REG_3050_DP_ENCODER0_P0,
247 video_n & 0xffff);
248
249 /* Add legerII. */
250 DP_WRITE1BYTE(mtk_dp, REG_3054_DP_ENCODER0_P0,
251 (video_n >> 16) & 0xff);
252 mtk_dp_write_byte(mtk_dp, REG_3004_DP_ENCODER0_P0 + 1,
253 BIT(0), BIT(0));
254 } else {
255 /* Turn off overwrite MN */
256 mtk_dp_write_byte(mtk_dp, REG_3004_DP_ENCODER0_P0 + 1,
257 0, BIT(0));
258 }
259}
260
261u8 dptx_hal_get_colorbpp(struct mtk_dp *mtk_dp)
262{
263 u8 color_bpp;
264 u8 color_depth = mtk_dp->info.depth;
265 u8 color_format = mtk_dp->info.format;
266
267 switch (color_depth) {
268 case DP_COLOR_DEPTH_6BIT:
269 if (color_format == DP_COLOR_FORMAT_YUV_422)
270 color_bpp = 16;
271 else if (color_format == DP_COLOR_FORMAT_YUV_420)
272 color_bpp = 12;
273 else
274 color_bpp = 18;
275 break;
276 case DP_COLOR_DEPTH_8BIT:
277 if (color_format == DP_COLOR_FORMAT_YUV_422)
278 color_bpp = 16;
279 else if (color_format == DP_COLOR_FORMAT_YUV_420)
280 color_bpp = 12;
281 else
282 color_bpp = 24;
283 break;
284 case DP_COLOR_DEPTH_10BIT:
285 if (color_format == DP_COLOR_FORMAT_YUV_422)
286 color_bpp = 20;
287 else if (color_format == DP_COLOR_FORMAT_YUV_420)
288 color_bpp = 15;
289 else
290 color_bpp = 30;
291 break;
292 case DP_COLOR_DEPTH_12BIT:
293 if (color_format == DP_COLOR_FORMAT_YUV_422)
294 color_bpp = 24;
295 else if (color_format == DP_COLOR_FORMAT_YUV_420)
296 color_bpp = 18;
297 else
298 color_bpp = 36;
299 break;
300 case DP_COLOR_DEPTH_16BIT:
301 if (color_format == DP_COLOR_FORMAT_YUV_422)
302 color_bpp = 32;
303 else if (color_format == DP_COLOR_FORMAT_YUV_420)
304 color_bpp = 24;
305 else
306 color_bpp = 48;
307 break;
308 default:
309 color_bpp = 24;
310 printk(BIOS_ERR, "Set wrong bpp = %d\n", color_bpp);
311 break;
312 }
313
314 return color_bpp;
315}
316
317void dptx_hal_settu_sramrd_start(struct mtk_dp *mtk_dp, u16 value)
318{
319 /*
320 * [5:0] video sram start address
321 * modify in 480P case only, default=0x1f
322 */
323 mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0, (u8)value, 0x3f);
324}
325
326void dptx_hal_setsdp_downcnt_init_inhblanking(struct mtk_dp *mtk_dp, u16 value)
327{
328 mtk_dp_mask(mtk_dp, REG_3364_DP_ENCODER1_P0, value, 0xfff);
329
330}
331
332void dptx_hal_setsdp_downcnt_init(struct mtk_dp *mtk_dp, u16 value)
333{
334 mtk_dp_mask(mtk_dp, REG_3040_DP_ENCODER0_P0, value, 0xfff);
335}
336
337void dptx_hal_settu_setencoder(struct mtk_dp *mtk_dp)
338{
339 mtk_dp_write_byte(mtk_dp, REG_303C_DP_ENCODER0_P0 + 1,
340 BIT(7), BIT(7));
341 DP_WRITE2BYTE(mtk_dp, REG_3040_DP_ENCODER0_P0, 0x2020);
342 mtk_dp_mask(mtk_dp, REG_3364_DP_ENCODER1_P0, 0x2020, 0xfff);
343 mtk_dp_write_byte(mtk_dp, REG_3300_DP_ENCODER1_P0 + 1,
344 0x2, BIT(1) | BIT(0));
345 mtk_dp_write_byte(mtk_dp, REG_3364_DP_ENCODER1_P0 + 1,
346 0x40, 0x70);
347 DP_WRITE2BYTE(mtk_dp, REG_3368_DP_ENCODER1_P0, 0x1111);
348}
349
350bool dptx_hal_hpd_high(struct mtk_dp *mtk_dp)
351{
352 return mtk_dp_read(mtk_dp, REG_3414_DP_TRANS_P0) & BIT(2);
353}
354
355bool dptx_hal_auxread_bytes(struct mtk_dp *mtk_dp, u8 cmd,
356 u32 dpcd_addr, size_t length, u8 *rx_buf)
357{
358 bool valid_cmd = false;
359 u8 reply_cmd, aux_irq_status;
360 int rd_count;
361 u32 wait_reply_count = AUX_WAITREPLY_LPNUM;
362
363 DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
364 mdelay(1);
365
366 if (length > 16 || (cmd == AUX_CMD_NATIVE_R && length == 0x0))
367 return false;
368
369 DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
370 DP_WRITE1BYTE(mtk_dp, REG_3644_AUX_TX_P0, cmd);
371 DP_WRITE2BYTE(mtk_dp, REG_3648_AUX_TX_P0, dpcd_addr & 0xffff);
372 DP_WRITE1BYTE(mtk_dp, REG_364C_AUX_TX_P0, (dpcd_addr >> 16) & 0xf);
373
374 if (length > 0) {
375 mtk_dp_mask(mtk_dp, REG_3650_AUX_TX_P0,
376 (length - 1) << MCU_REQ_DATA_NUM_AUX_TX_P0_FLDMASK_POS,
377 MCU_REQUEST_DATA_NUM_AUX_TX_P0_FLDMASK);
378 DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x0);
379 }
380
381 if (cmd == AUX_CMD_I2C_R || cmd == AUX_CMD_I2C_R_MOT0)
382 if (length == 0x0)
383 mtk_dp_mask(mtk_dp, REG_362C_AUX_TX_P0,
384 0x1 << AUX_NO_LENGTH_AUX_TX_P0_FLDMASK_POS,
385 AUX_NO_LENGTH_AUX_TX_P0_FLDMASK);
386
387 mtk_dp_mask(mtk_dp, REG_3630_AUX_TX_P0,
388 0x1 << AUX_TX_REQUEST_READY_AUX_TX_P0_FLDMASK_POS,
389 AUX_TX_REQUEST_READY_AUX_TX_P0_FLDMASK);
390
391 while (--wait_reply_count) {
392 if (mtk_dp_read(mtk_dp, REG_3618_AUX_TX_P0) &
393 AUX_RX_FIFO_WRITE_POINTER_AUX_TX_P0_FLDMASK) {
394 valid_cmd = true;
395 break;
396 }
397
398 if (mtk_dp_read(mtk_dp, REG_3618_AUX_TX_P0) &
399 AUX_RX_FIFO_FULL_AUX_TX_P0_FLDMASK) {
400 valid_cmd = true;
401 break;
402 }
403
404 aux_irq_status = mtk_dp_read(mtk_dp, REG_3640_AUX_TX_P0) & 0xff;
405
406 if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_FLDMASK) {
407 valid_cmd = true;
408 break;
409 }
410
411 if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_FLDMASK) {
412 printk(BIOS_ERR, "(AUX Read)HW Timeout 400us irq\n");
413 break;
414 }
415 }
416
417 reply_cmd = mtk_dp_read(mtk_dp, REG_3624_AUX_TX_P0) & 0xf;
418 if (reply_cmd)
419 printk(BIOS_ERR, "reply_cmd(%#x), NACK or Defer\n", reply_cmd);
420
421 if (wait_reply_count == 0x0 || reply_cmd) {
422 u8 phy_status = 0x0;
423
424 phy_status = mtk_dp_read(mtk_dp, REG_3628_AUX_TX_P0);
425 if (phy_status != 0x1)
426 printk(BIOS_ERR, "Aux read: aux hang, need sw reset\n");
427
428 mtk_dp_mask(mtk_dp, REG_3650_AUX_TX_P0,
429 0x1 << MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_FLDMASK_POS,
430 MCU_ACK_TRANSACTION_COMPLETE_AUX_TX_P0_FLDMASK);
431 DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
432
433 mdelay(1);
434 printk(BIOS_ERR, "wait_reply_count(%#x), TimeOut\n",
435 wait_reply_count);
436 return false;
437 }
438
439 if (length == 0) {
440 DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x0);
441 } else {
442 if (valid_cmd) {
443 mtk_dp_mask(mtk_dp, REG_3620_AUX_TX_P0,
444 0x0 << AUX_RD_MODE_AUX_TX_P0_FLDMASK_POS,
445 AUX_RD_MODE_AUX_TX_P0_FLDMASK);
446
447 for (rd_count = 0; rd_count < length; rd_count++) {
448 mtk_dp_mask(mtk_dp, REG_3620_AUX_TX_P0,
449 0x1 << AUX_RX_FIFO_R_PULSE_TX_P0_FLDMASK_POS,
450 AUX_RX_FIFO_READ_PULSE_TX_P0_FLDMASK);
451 mdelay(1);
452 *(rx_buf + rd_count) = mtk_dp_read(mtk_dp,
453 REG_3620_AUX_TX_P0);
454 }
455 } else {
456 printk(BIOS_INFO, "Read TimeOut %#x\n", dpcd_addr);
457 }
458 }
459
460 mtk_dp_mask(mtk_dp, REG_3650_AUX_TX_P0,
461 0x1 << MCU_ACK_TRAN_COMPLETE_AUX_TX_P0_FLDMASK_POS,
462 MCU_ACK_TRANSACTION_COMPLETE_AUX_TX_P0_FLDMASK);
463 DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
464
465 mdelay(1);
466 return valid_cmd;
467}
468
469bool dptx_hal_auxwrite_bytes(struct mtk_dp *mtk_dp, u8 cmd,
470 u32 dpcd_addr, size_t length, u8 *data)
471{
472 bool valid_cmd = false;
473 u8 reply_cmd;
474 int i;
475 u16 wait_reply_count = AUX_WAITREPLY_LPNUM;
476 int reg_idx;
477
478 mtk_dp_write_byte(mtk_dp, REG_3704_AUX_TX_P0,
479 1 << AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_FLDMASK_POS,
480 AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0_FLDMASK);
481 DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
482 DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
483 mdelay(1);
484
485 DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
486 DP_WRITE1BYTE(mtk_dp, REG_3644_AUX_TX_P0, cmd);
487 DP_WRITE1BYTE(mtk_dp, REG_3648_AUX_TX_P0, dpcd_addr & 0xff);
488 DP_WRITE1BYTE(mtk_dp, REG_3648_AUX_TX_P0 + 1,
489 (dpcd_addr >> 8) & 0xff);
490 DP_WRITE1BYTE(mtk_dp, REG_364C_AUX_TX_P0,
491 (dpcd_addr >> 16) & 0xf);
492
493 if (length > 0) {
494 DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x0);
495 for (i = 0; i < (length + 1) / 2; i++)
496 for (reg_idx = 0; reg_idx < 2; reg_idx++)
497 if ((i * 2 + reg_idx) < length)
498 DP_WRITE1BYTE(mtk_dp,
499 REG_3708_AUX_TX_P0 + i * 4 + reg_idx,
500 data[i * 2 + reg_idx]);
501 DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1,
502 ((length - 1) & 0xf) << 4);
503 } else {
504 DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x1);
505 }
506
507 mtk_dp_write_byte(mtk_dp, REG_3704_AUX_TX_P0,
508 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_FLDMASK,
509 AUX_TX_FIFO_WRITE_DATA_NEW_MODE_TOGGLE_AUX_TX_P0_FLDMASK);
510 DP_WRITE1BYTE(mtk_dp, REG_3630_AUX_TX_P0, 0x8);
511
512 while (--wait_reply_count) {
513 u8 aux_irq_status;
514
515 aux_irq_status = mtk_dp_read(mtk_dp, REG_3640_AUX_TX_P0) & 0xff;
516 mdelay(1);
517 if (aux_irq_status & AUX_RX_RECV_COMPLETE_IRQ_TX_P0_FLDMASK) {
518 valid_cmd = true;
519 break;
520 }
521
522 if (aux_irq_status & AUX_400US_TIMEOUT_IRQ_AUX_TX_P0_FLDMASK)
523 break;
524 }
525
526 reply_cmd = mtk_dp_read(mtk_dp, REG_3624_AUX_TX_P0) & 0xf;
527 if (reply_cmd)
528 printk(BIOS_ERR, "reply_cmd(%#x), NACK or Defer\n", reply_cmd);
529
530 if (wait_reply_count == 0x0 || reply_cmd) {
531 u8 phy_status = 0x0;
532
533 phy_status = mtk_dp_read(mtk_dp, REG_3628_AUX_TX_P0);
534 if (phy_status != 0x1)
535 printk(BIOS_ERR,
536 "Aux write: aux hang, need SW reset!\n");
537
538 DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
539 DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
540
541 mdelay(1);
542
543 printk(BIOS_INFO, "reply_cmd(%#x), wait_reply_count(%d)\n",
544 reply_cmd, wait_reply_count);
545 return false;
546 }
547
548 DP_WRITE1BYTE(mtk_dp, REG_3650_AUX_TX_P0 + 1, 0x1);
549
550 if (length == 0)
551 DP_WRITE1BYTE(mtk_dp, REG_362C_AUX_TX_P0, 0x0);
552
553 DP_WRITE1BYTE(mtk_dp, REG_3640_AUX_TX_P0, 0x7f);
554
555 mdelay(1);
556
557 return valid_cmd;
558}
559
560bool dptx_hal_setswing_preemphasis(struct mtk_dp *mtk_dp, int lane_num,
561 int swing_value, int preemphasis)
562{
563 printk(BIOS_DEBUG, "lane(%d), set swing(%#x), emp(%#x)\n",
564 lane_num, swing_value, preemphasis);
565
566 if (lane_num >= DPTX_LANE_MAX) {
567 printk(BIOS_ERR, "invalid lane number: %d\n", lane_num);
568 return false;
569 }
570
571 mtk_dp_mask(mtk_dp, DP_TX_TOP_SWING_EMP,
572 swing_value << volt_swing[lane_num].shift,
573 volt_swing[lane_num].mask);
574 mtk_dp_mask(mtk_dp, DP_TX_TOP_SWING_EMP,
575 preemphasis << volt_preemphasis[lane_num].shift,
576 volt_preemphasis[lane_num].mask);
577 return true;
578}
579
580void dptx_hal_reset_swing_preemphasis(struct mtk_dp *mtk_dp)
581{
582 int lane;
583
584 for (lane = 0; lane < DPTX_LANE_MAX; lane++)
585 mtk_dp_mask(mtk_dp, DP_TX_TOP_SWING_EMP,
586 0, volt_swing[lane].mask);
587 for (lane = 0; lane < DPTX_LANE_MAX; lane++)
588 mtk_dp_mask(mtk_dp, DP_TX_TOP_SWING_EMP,
589 0, volt_preemphasis[lane].mask);
590}
591
592void dptx_hal_hpd_int_en(struct mtk_dp *mtk_dp, bool enable)
593{
594 /* [7]:int, [6]:Con, [5]DisCon, [4]No-Use: UnMASK HPD Port */
595 mtk_dp_write_byte(mtk_dp, REG_3418_DP_TRANS_P0,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800596 enable ? 0 : GENMASK(7, 5), GENMASK(7, 5));
Jitao Shi56126602021-05-29 16:26:00 +0800597}
598
599void dptx_hal_hpd_detect_setting(struct mtk_dp *mtk_dp)
600{
601 mtk_dp_write_byte(mtk_dp, REG_3410_DP_TRANS_P0,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800602 0x8, GENMASK(3, 0));
Jitao Shi56126602021-05-29 16:26:00 +0800603 mtk_dp_write_byte(mtk_dp, REG_3410_DP_TRANS_P0,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800604 0xa << 4, GENMASK(7, 4));
Jitao Shi56126602021-05-29 16:26:00 +0800605
606 DP_WRITE1BYTE(mtk_dp, REG_3410_DP_TRANS_P0 + 1, 0x55);
607 DP_WRITE1BYTE(mtk_dp, REG_3430_DP_TRANS_P0, 0x2);
608}
609
610void dptx_hal_phy_setting(struct mtk_dp *mtk_dp)
611{
612 mtk_dp_mask(mtk_dp, DP_TX_TOP_PWR_STATE,
613 0x3 << DP_PWR_STATE_FLDMASK_POS, DP_PWR_STATE_FLDMASK);
614
615 mtk_dp_write(mtk_dp, 0x2000, 0x00000001);
616 mtk_dp_write(mtk_dp, 0x103c, 0x00000000);
617 mtk_dp_write(mtk_dp, 0x2000, 0x00000003);
618 mtk_dp_write(mtk_dp, 0x1138, 0x20181410);
619 mtk_dp_write(mtk_dp, 0x1238, 0x20181410);
620 mtk_dp_write(mtk_dp, 0x1338, 0x20181410);
621 mtk_dp_write(mtk_dp, 0x1438, 0x20181410);
622 mtk_dp_write(mtk_dp, 0x113C, 0x20241e18);
623 mtk_dp_write(mtk_dp, 0x123C, 0x20241e18);
624 mtk_dp_write(mtk_dp, 0x133C, 0x20241e18);
625 mtk_dp_write(mtk_dp, 0x143C, 0x20241e18);
626 mtk_dp_write(mtk_dp, 0x1140, 0x00003028);
627 mtk_dp_write(mtk_dp, 0x1240, 0x00003028);
628 mtk_dp_write(mtk_dp, 0x1340, 0x00003028);
629 mtk_dp_write(mtk_dp, 0x1440, 0x00003028);
630 mtk_dp_write(mtk_dp, 0x1144, 0x10080400);
631 mtk_dp_write(mtk_dp, 0x1244, 0x10080400);
632 mtk_dp_write(mtk_dp, 0x1344, 0x10080400);
633 mtk_dp_write(mtk_dp, 0x1444, 0x10080400);
634 mtk_dp_write(mtk_dp, 0x1148, 0x000c0600);
635 mtk_dp_write(mtk_dp, 0x1248, 0x000c0600);
636 mtk_dp_write(mtk_dp, 0x1348, 0x000c0600);
637 mtk_dp_write(mtk_dp, 0x1448, 0x000c0600);
638 mtk_dp_write(mtk_dp, 0x114C, 0x00000008);
639 mtk_dp_write(mtk_dp, 0x124C, 0x00000008);
640 mtk_dp_write(mtk_dp, 0x134C, 0x00000008);
641 mtk_dp_write(mtk_dp, 0x144C, 0x00000008);
642 mtk_dp_mask(mtk_dp, 0x3690, BIT(8), BIT(8));
643}
644
645void dptx_hal_ssc_en(struct mtk_dp *mtk_dp, bool enable)
646{
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800647 mtk_dp_mask(mtk_dp, 0x2000, BIT(0), GENMASK(1, 0));
Jitao Shi56126602021-05-29 16:26:00 +0800648
649 if (enable)
650 mtk_dp_mask(mtk_dp, 0x1014, BIT(3), BIT(3));
651 else
652 mtk_dp_mask(mtk_dp, 0x1014, 0x0, BIT(3));
653
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800654 mtk_dp_mask(mtk_dp, 0x2000, GENMASK(1, 0), GENMASK(1, 0));
Jitao Shi56126602021-05-29 16:26:00 +0800655
656 mdelay(1);
657}
658
659void dptx_hal_aux_setting(struct mtk_dp *mtk_dp)
660{
661 /* [12 : 8]: modify timeout threshold = 1595 */
662 mtk_dp_mask(mtk_dp, REG_360C_AUX_TX_P0,
663 0x1595, AUX_TIMEOUT_THR_AUX_TX_P0_FLDMASK);
664 mtk_dp_write_byte(mtk_dp, REG_3658_AUX_TX_P0, 0, BIT(0));
665
666 /* 0x19 for 26M */
667 DP_WRITE1BYTE(mtk_dp, REG_3634_AUX_TX_P0 + 1, 0x19);
668 /* 0xd for 26M */
669 mtk_dp_write_byte(mtk_dp, REG_3614_AUX_TX_P0,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800670 0xd, GENMASK(6, 0));
Jitao Shi56126602021-05-29 16:26:00 +0800671 mtk_dp_mask(mtk_dp, REG_37C8_AUX_TX_P0,
672 0x01 << MTK_ATOP_EN_AUX_TX_P0_FLDMASK_POS,
673 MTK_ATOP_EN_AUX_TX_P0_FLDMASK);
674}
675
676void dptx_hal_digital_setting(struct mtk_dp *mtk_dp)
677{
678 mtk_dp_write_byte(mtk_dp, REG_304C_DP_ENCODER0_P0,
679 0, VBID_VIDEO_MUTE_DP_ENCODER0_P0_FLDMASK);
680 /* MISC0 */
681 dptx_hal_set_color_format(mtk_dp, DP_COLOR_FORMAT_RGB_444);
682
683 dptx_hal_set_color_depth(mtk_dp, DP_COLOR_DEPTH_8BIT);
684 mtk_dp_write_byte(mtk_dp, REG_3368_DP_ENCODER1_P0 + 1,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800685 BIT(4), GENMASK(5, 4));
Jitao Shi56126602021-05-29 16:26:00 +0800686 /* DPtx encoder reset all sw. */
687 mtk_dp_write_byte(mtk_dp, REG_3004_DP_ENCODER0_P0 + 1, BIT(1), BIT(1));
688
689 mdelay(1);
690
691 /* DPtx encoder reset all sw. */
692 mtk_dp_write_byte(mtk_dp, REG_3004_DP_ENCODER0_P0 + 1, 0, BIT(1));
693}
694
695void dptx_hal_digital_swreset(struct mtk_dp *mtk_dp)
696{
697 mtk_dp_write_byte(mtk_dp, REG_340C_DP_TRANS_P0 + 1, BIT(5), BIT(5));
698 mdelay(1);
699 mtk_dp_write_byte(mtk_dp, REG_340C_DP_TRANS_P0 + 1, 0, BIT(5));
700}
701
702void dptx_hal_phyd_reset(struct mtk_dp *mtk_dp)
703{
704 mtk_dp_write_byte(mtk_dp, 0x1038, 0, BIT(0));
705 mdelay(1);
706 mtk_dp_write_byte(mtk_dp, 0x1038, BIT(0), BIT(0));
707}
708
709void dptx_hal_set_txlane(struct mtk_dp *mtk_dp, int value)
710{
711 if (value == 0)
712 mtk_dp_write_byte(mtk_dp, REG_35F0_DP_TRANS_P0,
713 0, BIT(3) | BIT(2));
714 else
715 mtk_dp_write_byte(mtk_dp, REG_35F0_DP_TRANS_P0,
716 BIT(3), BIT(3) | BIT(2));
717
718 if ((value << 2) <= UINT8_MAX) {
719 mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
720 value, BIT(1) | BIT(0));
721 mtk_dp_write_byte(mtk_dp, REG_34A4_DP_TRANS_P0,
722 value << 2, BIT(3) | BIT(2));
723 } else {
724 printk(BIOS_ERR, "ERROR: [%s]value << 2 > 0xff\n", __func__);
725 }
726}
727
728void dptx_hal_set_txrate(struct mtk_dp *mtk_dp, int value)
729{
730 /* Power off TPLL and lane */
731 mtk_dp_write(mtk_dp, 0x2000, 0x00000001);
732 /* Set gear : 0x0 : RBR, 0x1 : HBR, 0x2 : HBR2, 0x3 : HBR3 */
733 switch (value) {
734 case DP_LINKRATE_RBR:
735 mtk_dp_write(mtk_dp, 0x103C, 0x0);
736 break;
737 case DP_LINKRATE_HBR:
738 mtk_dp_write(mtk_dp, 0x103C, 0x1);
739 break;
740 case DP_LINKRATE_HBR2:
741 mtk_dp_write(mtk_dp, 0x103C, 0x2);
742 break;
743 case DP_LINKRATE_HBR3:
744 mtk_dp_write(mtk_dp, 0x103C, 0x3);
745 break;
746 default:
747 printk(BIOS_ERR, "ERROR: Link rate not support(%d)\n", value);
748 break;
749 }
750
751 /* Power on BandGap, TPLL and Lane */
752 mtk_dp_write(mtk_dp, 0x2000, 0x3);
753}
754
755void dptx_hal_set_txtrainingpattern(struct mtk_dp *mtk_dp, int value)
756{
757 /* if Set TPS1. */
758 if (value == BIT(4))
759 dptx_hal_phy_setidlepattern(mtk_dp, false);
760
761 mtk_dp_write_byte(mtk_dp, REG_3400_DP_TRANS_P0 + 1,
Yu-Ping Wu941db0e2021-07-23 16:17:11 +0800762 value, GENMASK(7, 4));
Jitao Shi56126602021-05-29 16:26:00 +0800763}
764
765void dptx_hal_phy_setidlepattern(struct mtk_dp *mtk_dp, bool enable)
766{
767 mtk_dp_write_byte(mtk_dp, REG_3580_DP_TRANS_P0 + 1,
768 enable ? 0xf : 0x0, 0xf);
769}
770
771void dptx_hal_set_ef_mode(struct mtk_dp *mtk_dp, bool enable)
772{
773 /*
774 * [4]: REG_enhanced_frame_mode
775 * [1 : 0]: REG_lane_num
776 */
777 if (enable)
778 mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
779 BIT(4), BIT(4));
780 else
781 mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
782 0, BIT(4));
783}
784
785void dptx_hal_setscramble(struct mtk_dp *mtk_dp, bool enable)
786{
787 /* [0]: dp tx transmitter scramble enable. */
788 if (enable)
789 mtk_dp_write_byte(mtk_dp, REG_3404_DP_TRANS_P0,
790 BIT(0), BIT(0));
791 else
792 mtk_dp_write_byte(mtk_dp, REG_3404_DP_TRANS_P0,
793 0, BIT(0));
794}
795
796void dptx_hal_videomute(struct mtk_dp *mtk_dp, bool enable)
797{
798 if (enable) {
799 mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
800 BIT(3) | BIT(2), BIT(3) | BIT(2));
801 mtk_dp_write_byte(mtk_dp, DP_TX_SECURE_REG11,
802 BIT(3) | BIT(4), BIT(3) | BIT(4));
803 } else {
804 mtk_dp_write_byte(mtk_dp, REG_3000_DP_ENCODER0_P0,
805 BIT(3), BIT(3) | BIT(2));
806 mtk_dp_write_byte(mtk_dp, DP_TX_SECURE_REG11,
807 BIT(4), BIT(3) | BIT(4));
808 }
809 printk(BIOS_DEBUG, "mute = %#x\n", read32(mtk_dp->regs + 0x402c));
810}
811
812void dptx_hal_analog_power_en(struct mtk_dp *mtk_dp, bool enable)
813{
814 if (enable) {
815 mtk_dp_write_byte(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
816 0, BIT(4));
817 mdelay(1);
818 mtk_dp_write_byte(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
819 BIT(4), BIT(4));
820 } else {
821 DP_WRITE2BYTE(mtk_dp, TOP_OFFSET, 0x0);
822 mdelay(1);
823 DP_WRITE2BYTE(mtk_dp, 0x0034, 0x4aa);
824 DP_WRITE2BYTE(mtk_dp, 0x1040, 0x0);
825 DP_WRITE2BYTE(mtk_dp, 0x0038, 0x555);
826 }
827}