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