1 /*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26
27 #include "reg_helper.h"
28 #include "dcn10_optc.h"
29 #include "dc.h"
30 #include "dc_trace.h"
31
32 #define REG(reg)\
33 optc1->tg_regs->reg
34
35 #define CTX \
36 optc1->base.ctx
37
38 #undef FN
39 #define FN(reg_name, field_name) \
40 optc1->tg_shift->field_name, optc1->tg_mask->field_name
41
42 #define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100
43
44 /**
45 * apply_front_porch_workaround() - This is a workaround for a bug that has
46 * existed since R5xx and has not been fixed
47 * keep Front porch at minimum 2 for Interlaced
48 * mode or 1 for progressive.
49 *
50 * @timing: Timing parameters used to configure DCN blocks.
51 */
apply_front_porch_workaround(struct dc_crtc_timing * timing)52 static void apply_front_porch_workaround(struct dc_crtc_timing *timing)
53 {
54 if (timing->flags.INTERLACE == 1) {
55 if (timing->v_front_porch < 2)
56 timing->v_front_porch = 2;
57 } else {
58 if (timing->v_front_porch < 1)
59 timing->v_front_porch = 1;
60 }
61 }
62
optc1_program_global_sync(struct timing_generator * optc,int vready_offset,int vstartup_start,int vupdate_offset,int vupdate_width)63 void optc1_program_global_sync(
64 struct timing_generator *optc,
65 int vready_offset,
66 int vstartup_start,
67 int vupdate_offset,
68 int vupdate_width)
69 {
70 struct optc *optc1 = DCN10TG_FROM_TG(optc);
71
72 optc1->vready_offset = vready_offset;
73 optc1->vstartup_start = vstartup_start;
74 optc1->vupdate_offset = vupdate_offset;
75 optc1->vupdate_width = vupdate_width;
76
77 if (optc1->vstartup_start == 0) {
78 BREAK_TO_DEBUGGER();
79 return;
80 }
81
82 REG_SET(OTG_VSTARTUP_PARAM, 0,
83 VSTARTUP_START, optc1->vstartup_start);
84
85 REG_SET_2(OTG_VUPDATE_PARAM, 0,
86 VUPDATE_OFFSET, optc1->vupdate_offset,
87 VUPDATE_WIDTH, optc1->vupdate_width);
88
89 REG_SET(OTG_VREADY_PARAM, 0,
90 VREADY_OFFSET, optc1->vready_offset);
91 }
92
optc1_disable_stereo(struct timing_generator * optc)93 static void optc1_disable_stereo(struct timing_generator *optc)
94 {
95 struct optc *optc1 = DCN10TG_FROM_TG(optc);
96
97 REG_SET(OTG_STEREO_CONTROL, 0,
98 OTG_STEREO_EN, 0);
99
100 REG_SET_2(OTG_3D_STRUCTURE_CONTROL, 0,
101 OTG_3D_STRUCTURE_EN, 0,
102 OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
103 }
104
optc1_setup_vertical_interrupt0(struct timing_generator * optc,uint32_t start_line,uint32_t end_line)105 void optc1_setup_vertical_interrupt0(
106 struct timing_generator *optc,
107 uint32_t start_line,
108 uint32_t end_line)
109 {
110 struct optc *optc1 = DCN10TG_FROM_TG(optc);
111
112 REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
113 OTG_VERTICAL_INTERRUPT0_LINE_START, start_line,
114 OTG_VERTICAL_INTERRUPT0_LINE_END, end_line);
115 }
116
optc1_setup_vertical_interrupt1(struct timing_generator * optc,uint32_t start_line)117 void optc1_setup_vertical_interrupt1(
118 struct timing_generator *optc,
119 uint32_t start_line)
120 {
121 struct optc *optc1 = DCN10TG_FROM_TG(optc);
122
123 REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0,
124 OTG_VERTICAL_INTERRUPT1_LINE_START, start_line);
125 }
126
optc1_setup_vertical_interrupt2(struct timing_generator * optc,uint32_t start_line)127 void optc1_setup_vertical_interrupt2(
128 struct timing_generator *optc,
129 uint32_t start_line)
130 {
131 struct optc *optc1 = DCN10TG_FROM_TG(optc);
132
133 REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
134 OTG_VERTICAL_INTERRUPT2_LINE_START, start_line);
135 }
136
137 /**
138 * optc1_program_timing() - used by mode timing set Program
139 * CRTC Timing Registers - OTG_H_*,
140 * OTG_V_*, Pixel repetition.
141 * Including SYNC. Call BIOS command table to program Timings.
142 *
143 * @optc: timing_generator instance.
144 * @dc_crtc_timing: Timing parameters used to configure DCN blocks.
145 * @vready_offset: Vready's starting position.
146 * @vstartup_start: Vstartup period.
147 * @vupdate_offset: Vupdate starting position.
148 * @vupdate_width: Vupdate duration.
149 * @signal: DC signal types.
150 * @use_vbios: to program timings from BIOS command table.
151 *
152 */
optc1_program_timing(struct timing_generator * optc,const struct dc_crtc_timing * dc_crtc_timing,int vready_offset,int vstartup_start,int vupdate_offset,int vupdate_width,const enum amd_signal_type signal,bool use_vbios)153 void optc1_program_timing(
154 struct timing_generator *optc,
155 const struct dc_crtc_timing *dc_crtc_timing,
156 int vready_offset,
157 int vstartup_start,
158 int vupdate_offset,
159 int vupdate_width,
160 const enum amd_signal_type signal,
161 bool use_vbios)
162 {
163 struct dc_crtc_timing patched_crtc_timing;
164 uint32_t asic_blank_end;
165 uint32_t asic_blank_start;
166 uint32_t v_total;
167 uint32_t v_sync_end;
168 uint32_t h_sync_polarity, v_sync_polarity;
169 uint32_t start_point = 0;
170 uint32_t field_num = 0;
171 enum h_timing_div_mode h_div = H_TIMING_NO_DIV;
172
173 struct optc *optc1 = DCN10TG_FROM_TG(optc);
174
175 optc1->signal = signal;
176 optc1->vready_offset = vready_offset;
177 optc1->vstartup_start = vstartup_start;
178 optc1->vupdate_offset = vupdate_offset;
179 optc1->vupdate_width = vupdate_width;
180 patched_crtc_timing = *dc_crtc_timing;
181 apply_front_porch_workaround(&patched_crtc_timing);
182 optc1->orginal_patched_timing = patched_crtc_timing;
183
184 /* Load horizontal timing */
185
186 /* CRTC_H_TOTAL = vesa.h_total - 1 */
187 REG_SET(OTG_H_TOTAL, 0,
188 OTG_H_TOTAL, patched_crtc_timing.h_total - 1);
189
190 /* h_sync_start = 0, h_sync_end = vesa.h_sync_width */
191 REG_UPDATE_2(OTG_H_SYNC_A,
192 OTG_H_SYNC_A_START, 0,
193 OTG_H_SYNC_A_END, patched_crtc_timing.h_sync_width);
194
195 /* blank_start = line end - front porch */
196 asic_blank_start = patched_crtc_timing.h_total -
197 patched_crtc_timing.h_front_porch;
198
199 /* blank_end = blank_start - active */
200 asic_blank_end = asic_blank_start -
201 patched_crtc_timing.h_border_right -
202 patched_crtc_timing.h_addressable -
203 patched_crtc_timing.h_border_left;
204
205 REG_UPDATE_2(OTG_H_BLANK_START_END,
206 OTG_H_BLANK_START, asic_blank_start,
207 OTG_H_BLANK_END, asic_blank_end);
208
209 /* h_sync polarity */
210 h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ?
211 0 : 1;
212
213 REG_UPDATE(OTG_H_SYNC_A_CNTL,
214 OTG_H_SYNC_A_POL, h_sync_polarity);
215
216 v_total = patched_crtc_timing.v_total - 1;
217
218 REG_SET(OTG_V_TOTAL, 0,
219 OTG_V_TOTAL, v_total);
220
221 /* In case of V_TOTAL_CONTROL is on, make sure OTG_V_TOTAL_MAX and
222 * OTG_V_TOTAL_MIN are equal to V_TOTAL.
223 */
224 optc->funcs->set_vtotal_min_max(optc, v_total, v_total);
225
226 /* v_sync_start = 0, v_sync_end = v_sync_width */
227 v_sync_end = patched_crtc_timing.v_sync_width;
228
229 REG_UPDATE_2(OTG_V_SYNC_A,
230 OTG_V_SYNC_A_START, 0,
231 OTG_V_SYNC_A_END, v_sync_end);
232
233 /* blank_start = frame end - front porch */
234 asic_blank_start = patched_crtc_timing.v_total -
235 patched_crtc_timing.v_front_porch;
236
237 /* blank_end = blank_start - active */
238 asic_blank_end = asic_blank_start -
239 patched_crtc_timing.v_border_bottom -
240 patched_crtc_timing.v_addressable -
241 patched_crtc_timing.v_border_top;
242
243 REG_UPDATE_2(OTG_V_BLANK_START_END,
244 OTG_V_BLANK_START, asic_blank_start,
245 OTG_V_BLANK_END, asic_blank_end);
246
247 /* v_sync polarity */
248 v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ?
249 0 : 1;
250
251 REG_UPDATE(OTG_V_SYNC_A_CNTL,
252 OTG_V_SYNC_A_POL, v_sync_polarity);
253
254 if (optc1->signal == SIGNAL_TYPE_DISPLAY_PORT ||
255 optc1->signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
256 optc1->signal == SIGNAL_TYPE_EDP) {
257 start_point = 1;
258 if (patched_crtc_timing.flags.INTERLACE == 1)
259 field_num = 1;
260 }
261
262 /* Interlace */
263 if (REG(OTG_INTERLACE_CONTROL)) {
264 if (patched_crtc_timing.flags.INTERLACE == 1)
265 REG_UPDATE(OTG_INTERLACE_CONTROL,
266 OTG_INTERLACE_ENABLE, 1);
267 else
268 REG_UPDATE(OTG_INTERLACE_CONTROL,
269 OTG_INTERLACE_ENABLE, 0);
270 }
271
272 /* VTG enable set to 0 first VInit */
273 REG_UPDATE(CONTROL,
274 VTG0_ENABLE, 0);
275
276 /* original code is using VTG offset to address OTG reg, seems wrong */
277 REG_UPDATE_2(OTG_CONTROL,
278 OTG_START_POINT_CNTL, start_point,
279 OTG_FIELD_NUMBER_CNTL, field_num);
280
281 optc->funcs->program_global_sync(optc,
282 vready_offset,
283 vstartup_start,
284 vupdate_offset,
285 vupdate_width);
286
287 optc->funcs->set_vtg_params(optc, dc_crtc_timing, true);
288
289 /* TODO
290 * patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1
291 * program_horz_count_by_2
292 * for DVI 30bpp mode, 0 otherwise
293 * program_horz_count_by_2(optc, &patched_crtc_timing);
294 */
295
296 /* Enable stereo - only when we need to pack 3D frame. Other types
297 * of stereo handled in explicit call
298 */
299
300 if (optc1_is_two_pixels_per_containter(&patched_crtc_timing) || optc1->opp_count == 2)
301 h_div = H_TIMING_DIV_BY2;
302
303 if (REG(OPTC_DATA_FORMAT_CONTROL) && optc1->tg_mask->OPTC_DATA_FORMAT != 0) {
304 uint32_t data_fmt = 0;
305
306 if (patched_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
307 data_fmt = 1;
308 else if (patched_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
309 data_fmt = 2;
310
311 REG_UPDATE(OPTC_DATA_FORMAT_CONTROL, OPTC_DATA_FORMAT, data_fmt);
312 }
313
314 if (optc1->tg_mask->OTG_H_TIMING_DIV_MODE != 0) {
315 if (optc1->opp_count == 4)
316 h_div = H_TIMING_DIV_BY4;
317
318 REG_UPDATE(OTG_H_TIMING_CNTL,
319 OTG_H_TIMING_DIV_MODE, h_div);
320 } else {
321 REG_UPDATE(OTG_H_TIMING_CNTL,
322 OTG_H_TIMING_DIV_BY2, h_div);
323 }
324 }
325
326 /**
327 * optc1_set_vtg_params - Set Vertical Timing Generator (VTG) parameters
328 *
329 * @optc: timing_generator struct used to extract the optc parameters
330 * @dc_crtc_timing: Timing parameters configured
331 * @program_fp2: Boolean value indicating if FP2 will be programmed or not
332 *
333 * OTG is responsible for generating the global sync signals, including
334 * vertical timing information for each HUBP in the dcfclk domain. Each VTG is
335 * associated with one OTG that provides HUBP with vertical timing information
336 * (i.e., there is 1:1 correspondence between OTG and VTG). This function is
337 * responsible for setting the OTG parameters to the VTG during the pipe
338 * programming.
339 */
optc1_set_vtg_params(struct timing_generator * optc,const struct dc_crtc_timing * dc_crtc_timing,bool program_fp2)340 void optc1_set_vtg_params(struct timing_generator *optc,
341 const struct dc_crtc_timing *dc_crtc_timing, bool program_fp2)
342 {
343 struct dc_crtc_timing patched_crtc_timing;
344 uint32_t asic_blank_end;
345 uint32_t v_init;
346 uint32_t v_fp2 = 0;
347 int32_t vertical_line_start;
348
349 struct optc *optc1 = DCN10TG_FROM_TG(optc);
350
351 patched_crtc_timing = *dc_crtc_timing;
352 apply_front_porch_workaround(&patched_crtc_timing);
353
354 /* VCOUNT_INIT is the start of blank */
355 v_init = patched_crtc_timing.v_total - patched_crtc_timing.v_front_porch;
356
357 /* end of blank = v_init - active */
358 asic_blank_end = v_init -
359 patched_crtc_timing.v_border_bottom -
360 patched_crtc_timing.v_addressable -
361 patched_crtc_timing.v_border_top;
362
363 /* if VSTARTUP is before VSYNC, FP2 is the offset, otherwise 0 */
364 vertical_line_start = asic_blank_end - optc1->vstartup_start + 1;
365 if (vertical_line_start < 0)
366 v_fp2 = -vertical_line_start;
367
368 /* Interlace */
369 if (REG(OTG_INTERLACE_CONTROL)) {
370 if (patched_crtc_timing.flags.INTERLACE == 1) {
371 v_init = v_init / 2;
372 if ((optc1->vstartup_start/2)*2 > asic_blank_end)
373 v_fp2 = v_fp2 / 2;
374 }
375 }
376
377 if (program_fp2)
378 REG_UPDATE_2(CONTROL,
379 VTG0_FP2, v_fp2,
380 VTG0_VCOUNT_INIT, v_init);
381 else
382 REG_UPDATE(CONTROL, VTG0_VCOUNT_INIT, v_init);
383 }
384
optc1_set_blank_data_double_buffer(struct timing_generator * optc,bool enable)385 void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable)
386 {
387 struct optc *optc1 = DCN10TG_FROM_TG(optc);
388
389 uint32_t blank_data_double_buffer_enable = enable ? 1 : 0;
390
391 REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
392 OTG_BLANK_DATA_DOUBLE_BUFFER_EN, blank_data_double_buffer_enable);
393 }
394
395 /**
396 * optc1_set_timing_double_buffer() - DRR double buffering control
397 *
398 * Sets double buffer point for V_TOTAL, H_TOTAL, VTOTAL_MIN,
399 * VTOTAL_MAX, VTOTAL_MIN_SEL and VTOTAL_MAX_SEL registers.
400 *
401 * @optc: timing_generator instance.
402 * @enable: Enable DRR double buffering control if true, disable otherwise.
403 *
404 * Options: any time, start of frame, dp start of frame (range timing)
405 */
optc1_set_timing_double_buffer(struct timing_generator * optc,bool enable)406 void optc1_set_timing_double_buffer(struct timing_generator *optc, bool enable)
407 {
408 struct optc *optc1 = DCN10TG_FROM_TG(optc);
409 uint32_t mode = enable ? 2 : 0;
410
411 REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
412 OTG_RANGE_TIMING_DBUF_UPDATE_MODE, mode);
413 }
414
415 /**
416 * optc1_unblank_crtc() - Call ASIC Control Object to UnBlank CRTC.
417 *
418 * @optc: timing_generator instance.
419 */
optc1_unblank_crtc(struct timing_generator * optc)420 static void optc1_unblank_crtc(struct timing_generator *optc)
421 {
422 struct optc *optc1 = DCN10TG_FROM_TG(optc);
423
424 REG_UPDATE_2(OTG_BLANK_CONTROL,
425 OTG_BLANK_DATA_EN, 0,
426 OTG_BLANK_DE_MODE, 0);
427
428 /* W/A for automated testing
429 * Automated testing will fail underflow test as there
430 * sporadic underflows which occur during the optc blank
431 * sequence. As a w/a, clear underflow on unblank.
432 * This prevents the failure, but will not mask actual
433 * underflow that affect real use cases.
434 */
435 optc1_clear_optc_underflow(optc);
436 }
437
438 /**
439 * optc1_blank_crtc() - Call ASIC Control Object to Blank CRTC.
440 *
441 * @optc: timing_generator instance.
442 */
443
optc1_blank_crtc(struct timing_generator * optc)444 static void optc1_blank_crtc(struct timing_generator *optc)
445 {
446 struct optc *optc1 = DCN10TG_FROM_TG(optc);
447
448 REG_UPDATE_2(OTG_BLANK_CONTROL,
449 OTG_BLANK_DATA_EN, 1,
450 OTG_BLANK_DE_MODE, 0);
451
452 optc1_set_blank_data_double_buffer(optc, false);
453 }
454
optc1_set_blank(struct timing_generator * optc,bool enable_blanking)455 void optc1_set_blank(struct timing_generator *optc,
456 bool enable_blanking)
457 {
458 if (enable_blanking)
459 optc1_blank_crtc(optc);
460 else
461 optc1_unblank_crtc(optc);
462 }
463
optc1_is_blanked(struct timing_generator * optc)464 bool optc1_is_blanked(struct timing_generator *optc)
465 {
466 struct optc *optc1 = DCN10TG_FROM_TG(optc);
467 uint32_t blank_en;
468 uint32_t blank_state;
469
470 REG_GET_2(OTG_BLANK_CONTROL,
471 OTG_BLANK_DATA_EN, &blank_en,
472 OTG_CURRENT_BLANK_STATE, &blank_state);
473
474 return blank_en && blank_state;
475 }
476
optc1_enable_optc_clock(struct timing_generator * optc,bool enable)477 void optc1_enable_optc_clock(struct timing_generator *optc, bool enable)
478 {
479 struct optc *optc1 = DCN10TG_FROM_TG(optc);
480
481 if (enable) {
482 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
483 OPTC_INPUT_CLK_EN, 1,
484 OPTC_INPUT_CLK_GATE_DIS, 1);
485
486 REG_WAIT(OPTC_INPUT_CLOCK_CONTROL,
487 OPTC_INPUT_CLK_ON, 1,
488 1, 1000);
489
490 /* Enable clock */
491 REG_UPDATE_2(OTG_CLOCK_CONTROL,
492 OTG_CLOCK_EN, 1,
493 OTG_CLOCK_GATE_DIS, 1);
494 REG_WAIT(OTG_CLOCK_CONTROL,
495 OTG_CLOCK_ON, 1,
496 1, 1000);
497 } else {
498
499 //last chance to clear underflow, otherwise, it will always there due to clock is off.
500 if (optc->funcs->is_optc_underflow_occurred(optc) == true)
501 optc->funcs->clear_optc_underflow(optc);
502
503 REG_UPDATE_2(OTG_CLOCK_CONTROL,
504 OTG_CLOCK_GATE_DIS, 0,
505 OTG_CLOCK_EN, 0);
506
507 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
508 OPTC_INPUT_CLK_GATE_DIS, 0,
509 OPTC_INPUT_CLK_EN, 0);
510 }
511 }
512
513 /**
514 * optc1_enable_crtc() - Enable CRTC - call ASIC Control Object to enable Timing generator.
515 *
516 * @optc: timing_generator instance.
517 */
optc1_enable_crtc(struct timing_generator * optc)518 static bool optc1_enable_crtc(struct timing_generator *optc)
519 {
520 /* TODO FPGA wait for answer
521 * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE
522 * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK
523 */
524 struct optc *optc1 = DCN10TG_FROM_TG(optc);
525
526 /* opp instance for OTG. For DCN1.0, ODM is remoed.
527 * OPP and OPTC should 1:1 mapping
528 */
529 REG_UPDATE(OPTC_DATA_SOURCE_SELECT,
530 OPTC_SRC_SEL, optc->inst);
531
532 /* VTG enable first is for HW workaround */
533 REG_UPDATE(CONTROL,
534 VTG0_ENABLE, 1);
535
536 REG_SEQ_START();
537
538 /* Enable CRTC */
539 REG_UPDATE_2(OTG_CONTROL,
540 OTG_DISABLE_POINT_CNTL, 3,
541 OTG_MASTER_EN, 1);
542
543 REG_SEQ_SUBMIT();
544 REG_SEQ_WAIT_DONE();
545
546 return true;
547 }
548
549 /* disable_crtc - call ASIC Control Object to disable Timing generator. */
optc1_disable_crtc(struct timing_generator * optc)550 bool optc1_disable_crtc(struct timing_generator *optc)
551 {
552 struct optc *optc1 = DCN10TG_FROM_TG(optc);
553
554 /* disable otg request until end of the first line
555 * in the vertical blank region
556 */
557 REG_UPDATE_2(OTG_CONTROL,
558 OTG_DISABLE_POINT_CNTL, 3,
559 OTG_MASTER_EN, 0);
560
561 REG_UPDATE(CONTROL,
562 VTG0_ENABLE, 0);
563
564 /* CRTC disabled, so disable clock. */
565 REG_WAIT(OTG_CLOCK_CONTROL,
566 OTG_BUSY, 0,
567 1, 100000);
568
569 return true;
570 }
571
572
optc1_program_blank_color(struct timing_generator * optc,const struct tg_color * black_color)573 void optc1_program_blank_color(
574 struct timing_generator *optc,
575 const struct tg_color *black_color)
576 {
577 struct optc *optc1 = DCN10TG_FROM_TG(optc);
578
579 REG_SET_3(OTG_BLACK_COLOR, 0,
580 OTG_BLACK_COLOR_B_CB, black_color->color_b_cb,
581 OTG_BLACK_COLOR_G_Y, black_color->color_g_y,
582 OTG_BLACK_COLOR_R_CR, black_color->color_r_cr);
583 }
584
optc1_validate_timing(struct timing_generator * optc,const struct dc_crtc_timing * timing)585 bool optc1_validate_timing(
586 struct timing_generator *optc,
587 const struct dc_crtc_timing *timing)
588 {
589 uint32_t v_blank;
590 uint32_t h_blank;
591 uint32_t min_v_blank;
592 struct optc *optc1 = DCN10TG_FROM_TG(optc);
593
594 ASSERT(timing != NULL);
595
596 v_blank = (timing->v_total - timing->v_addressable -
597 timing->v_border_top - timing->v_border_bottom);
598
599 h_blank = (timing->h_total - timing->h_addressable -
600 timing->h_border_right -
601 timing->h_border_left);
602
603 if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
604 timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING &&
605 timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM &&
606 timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE &&
607 timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE &&
608 timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
609 return false;
610
611 /* Temporarily blocking interlacing mode until it's supported */
612 if (timing->flags.INTERLACE == 1)
613 return false;
614
615 /* Check maximum number of pixels supported by Timing Generator
616 * (Currently will never fail, in order to fail needs display which
617 * needs more than 8192 horizontal and
618 * more than 8192 vertical total pixels)
619 */
620 if (timing->h_total > optc1->max_h_total ||
621 timing->v_total > optc1->max_v_total)
622 return false;
623
624
625 if (h_blank < optc1->min_h_blank)
626 return false;
627
628 if (timing->h_sync_width < optc1->min_h_sync_width ||
629 timing->v_sync_width < optc1->min_v_sync_width)
630 return false;
631
632 min_v_blank = timing->flags.INTERLACE?optc1->min_v_blank_interlace:optc1->min_v_blank;
633
634 if (v_blank < min_v_blank)
635 return false;
636
637 return true;
638
639 }
640
641 /*
642 * get_vblank_counter
643 *
644 * @brief
645 * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
646 * holds the counter of frames.
647 *
648 * @param
649 * struct timing_generator *optc - [in] timing generator which controls the
650 * desired CRTC
651 *
652 * @return
653 * Counter of frames, which should equal to number of vblanks.
654 */
optc1_get_vblank_counter(struct timing_generator * optc)655 uint32_t optc1_get_vblank_counter(struct timing_generator *optc)
656 {
657 struct optc *optc1 = DCN10TG_FROM_TG(optc);
658 uint32_t frame_count;
659
660 REG_GET(OTG_STATUS_FRAME_COUNT,
661 OTG_FRAME_COUNT, &frame_count);
662
663 return frame_count;
664 }
665
optc1_lock(struct timing_generator * optc)666 void optc1_lock(struct timing_generator *optc)
667 {
668 struct optc *optc1 = DCN10TG_FROM_TG(optc);
669
670 REG_SET(OTG_GLOBAL_CONTROL0, 0,
671 OTG_MASTER_UPDATE_LOCK_SEL, optc->inst);
672 REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
673 OTG_MASTER_UPDATE_LOCK, 1);
674
675 REG_WAIT(OTG_MASTER_UPDATE_LOCK,
676 UPDATE_LOCK_STATUS, 1,
677 1, 10);
678
679 TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, true);
680 }
681
optc1_unlock(struct timing_generator * optc)682 void optc1_unlock(struct timing_generator *optc)
683 {
684 struct optc *optc1 = DCN10TG_FROM_TG(optc);
685
686 REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
687 OTG_MASTER_UPDATE_LOCK, 0);
688
689 TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, false);
690 }
691
optc1_get_position(struct timing_generator * optc,struct crtc_position * position)692 void optc1_get_position(struct timing_generator *optc,
693 struct crtc_position *position)
694 {
695 struct optc *optc1 = DCN10TG_FROM_TG(optc);
696
697 REG_GET_2(OTG_STATUS_POSITION,
698 OTG_HORZ_COUNT, &position->horizontal_count,
699 OTG_VERT_COUNT, &position->vertical_count);
700
701 REG_GET(OTG_NOM_VERT_POSITION,
702 OTG_VERT_COUNT_NOM, &position->nominal_vcount);
703 }
704
optc1_is_counter_moving(struct timing_generator * optc)705 bool optc1_is_counter_moving(struct timing_generator *optc)
706 {
707 struct crtc_position position1, position2;
708
709 optc->funcs->get_position(optc, &position1);
710 optc->funcs->get_position(optc, &position2);
711
712 if (position1.horizontal_count == position2.horizontal_count &&
713 position1.vertical_count == position2.vertical_count)
714 return false;
715 else
716 return true;
717 }
718
optc1_did_triggered_reset_occur(struct timing_generator * optc)719 bool optc1_did_triggered_reset_occur(
720 struct timing_generator *optc)
721 {
722 struct optc *optc1 = DCN10TG_FROM_TG(optc);
723 uint32_t occurred_force, occurred_vsync;
724
725 REG_GET(OTG_FORCE_COUNT_NOW_CNTL,
726 OTG_FORCE_COUNT_NOW_OCCURRED, &occurred_force);
727
728 REG_GET(OTG_VERT_SYNC_CONTROL,
729 OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, &occurred_vsync);
730
731 return occurred_vsync != 0 || occurred_force != 0;
732 }
733
optc1_disable_reset_trigger(struct timing_generator * optc)734 void optc1_disable_reset_trigger(struct timing_generator *optc)
735 {
736 struct optc *optc1 = DCN10TG_FROM_TG(optc);
737
738 REG_WRITE(OTG_TRIGA_CNTL, 0);
739
740 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
741 OTG_FORCE_COUNT_NOW_CLEAR, 1);
742
743 REG_SET(OTG_VERT_SYNC_CONTROL, 0,
744 OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, 1);
745 }
746
optc1_enable_reset_trigger(struct timing_generator * optc,int source_tg_inst)747 void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst)
748 {
749 struct optc *optc1 = DCN10TG_FROM_TG(optc);
750 uint32_t falling_edge;
751
752 REG_GET(OTG_V_SYNC_A_CNTL,
753 OTG_V_SYNC_A_POL, &falling_edge);
754
755 if (falling_edge)
756 REG_SET_3(OTG_TRIGA_CNTL, 0,
757 /* vsync signal from selected OTG pipe based
758 * on OTG_TRIG_SOURCE_PIPE_SELECT setting
759 */
760 OTG_TRIGA_SOURCE_SELECT, 20,
761 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
762 /* always detect falling edge */
763 OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 1);
764 else
765 REG_SET_3(OTG_TRIGA_CNTL, 0,
766 /* vsync signal from selected OTG pipe based
767 * on OTG_TRIG_SOURCE_PIPE_SELECT setting
768 */
769 OTG_TRIGA_SOURCE_SELECT, 20,
770 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
771 /* always detect rising edge */
772 OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1);
773
774 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
775 /* force H count to H_TOTAL and V count to V_TOTAL in
776 * progressive mode and V_TOTAL-1 in interlaced mode
777 */
778 OTG_FORCE_COUNT_NOW_MODE, 2);
779 }
780
optc1_enable_crtc_reset(struct timing_generator * optc,int source_tg_inst,struct crtc_trigger_info * crtc_tp)781 void optc1_enable_crtc_reset(
782 struct timing_generator *optc,
783 int source_tg_inst,
784 struct crtc_trigger_info *crtc_tp)
785 {
786 struct optc *optc1 = DCN10TG_FROM_TG(optc);
787 uint32_t falling_edge = 0;
788 uint32_t rising_edge = 0;
789
790 switch (crtc_tp->event) {
791
792 case CRTC_EVENT_VSYNC_RISING:
793 rising_edge = 1;
794 break;
795
796 case CRTC_EVENT_VSYNC_FALLING:
797 falling_edge = 1;
798 break;
799 }
800
801 REG_SET_4(OTG_TRIGA_CNTL, 0,
802 /* vsync signal from selected OTG pipe based
803 * on OTG_TRIG_SOURCE_PIPE_SELECT setting
804 */
805 OTG_TRIGA_SOURCE_SELECT, 20,
806 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
807 /* always detect falling edge */
808 OTG_TRIGA_RISING_EDGE_DETECT_CNTL, rising_edge,
809 OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, falling_edge);
810
811 switch (crtc_tp->delay) {
812 case TRIGGER_DELAY_NEXT_LINE:
813 REG_SET(OTG_VERT_SYNC_CONTROL, 0,
814 OTG_AUTO_FORCE_VSYNC_MODE, 1);
815 break;
816 case TRIGGER_DELAY_NEXT_PIXEL:
817 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
818 /* force H count to H_TOTAL and V count to V_TOTAL in
819 * progressive mode and V_TOTAL-1 in interlaced mode
820 */
821 OTG_FORCE_COUNT_NOW_MODE, 2);
822 break;
823 }
824 }
825
optc1_wait_for_state(struct timing_generator * optc,enum crtc_state state)826 void optc1_wait_for_state(struct timing_generator *optc,
827 enum crtc_state state)
828 {
829 struct optc *optc1 = DCN10TG_FROM_TG(optc);
830
831 switch (state) {
832 case CRTC_STATE_VBLANK:
833 REG_WAIT(OTG_STATUS,
834 OTG_V_BLANK, 1,
835 1, 100000); /* 1 vupdate at 10hz */
836 break;
837
838 case CRTC_STATE_VACTIVE:
839 REG_WAIT(OTG_STATUS,
840 OTG_V_ACTIVE_DISP, 1,
841 1, 100000); /* 1 vupdate at 10hz */
842 break;
843
844 default:
845 break;
846 }
847 }
848
optc1_set_early_control(struct timing_generator * optc,uint32_t early_cntl)849 void optc1_set_early_control(
850 struct timing_generator *optc,
851 uint32_t early_cntl)
852 {
853 /* asic design change, do not need this control
854 * empty for share caller logic
855 */
856 }
857
858
optc1_set_static_screen_control(struct timing_generator * optc,uint32_t event_triggers,uint32_t num_frames)859 void optc1_set_static_screen_control(
860 struct timing_generator *optc,
861 uint32_t event_triggers,
862 uint32_t num_frames)
863 {
864 struct optc *optc1 = DCN10TG_FROM_TG(optc);
865
866 // By register spec, it only takes 8 bit value
867 if (num_frames > 0xFF)
868 num_frames = 0xFF;
869
870 /* Bit 8 is no longer applicable in RV for PSR case,
871 * set bit 8 to 0 if given
872 */
873 if ((event_triggers & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
874 != 0)
875 event_triggers = event_triggers &
876 ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN;
877
878 REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0,
879 OTG_STATIC_SCREEN_EVENT_MASK, event_triggers,
880 OTG_STATIC_SCREEN_FRAME_COUNT, num_frames);
881 }
882
optc1_setup_manual_trigger(struct timing_generator * optc)883 static void optc1_setup_manual_trigger(struct timing_generator *optc)
884 {
885 struct optc *optc1 = DCN10TG_FROM_TG(optc);
886
887 REG_SET(OTG_GLOBAL_CONTROL2, 0,
888 MANUAL_FLOW_CONTROL_SEL, optc->inst);
889
890 REG_SET_8(OTG_TRIGA_CNTL, 0,
891 OTG_TRIGA_SOURCE_SELECT, 22,
892 OTG_TRIGA_SOURCE_PIPE_SELECT, optc->inst,
893 OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1,
894 OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 0,
895 OTG_TRIGA_POLARITY_SELECT, 0,
896 OTG_TRIGA_FREQUENCY_SELECT, 0,
897 OTG_TRIGA_DELAY, 0,
898 OTG_TRIGA_CLEAR, 1);
899 }
900
optc1_program_manual_trigger(struct timing_generator * optc)901 static void optc1_program_manual_trigger(struct timing_generator *optc)
902 {
903 struct optc *optc1 = DCN10TG_FROM_TG(optc);
904
905 REG_SET(OTG_MANUAL_FLOW_CONTROL, 0,
906 MANUAL_FLOW_CONTROL, 1);
907
908 REG_SET(OTG_MANUAL_FLOW_CONTROL, 0,
909 MANUAL_FLOW_CONTROL, 0);
910 }
911
912 /**
913 * optc1_set_drr() - Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*.
914 *
915 * @optc: timing_generator instance.
916 * @params: parameters used for Dynamic Refresh Rate.
917 */
optc1_set_drr(struct timing_generator * optc,const struct drr_params * params)918 void optc1_set_drr(
919 struct timing_generator *optc,
920 const struct drr_params *params)
921 {
922 struct optc *optc1 = DCN10TG_FROM_TG(optc);
923
924 if (params != NULL &&
925 params->vertical_total_max > 0 &&
926 params->vertical_total_min > 0) {
927
928 if (params->vertical_total_mid != 0) {
929
930 REG_SET(OTG_V_TOTAL_MID, 0,
931 OTG_V_TOTAL_MID, params->vertical_total_mid - 1);
932
933 REG_UPDATE_2(OTG_V_TOTAL_CONTROL,
934 OTG_VTOTAL_MID_REPLACING_MAX_EN, 1,
935 OTG_VTOTAL_MID_FRAME_NUM,
936 (uint8_t)params->vertical_total_mid_frame_num);
937
938 }
939
940 optc->funcs->set_vtotal_min_max(optc, params->vertical_total_min - 1, params->vertical_total_max - 1);
941
942 REG_UPDATE_5(OTG_V_TOTAL_CONTROL,
943 OTG_V_TOTAL_MIN_SEL, 1,
944 OTG_V_TOTAL_MAX_SEL, 1,
945 OTG_FORCE_LOCK_ON_EVENT, 0,
946 OTG_SET_V_TOTAL_MIN_MASK_EN, 0,
947 OTG_SET_V_TOTAL_MIN_MASK, 0);
948 }
949
950 // Setup manual flow control for EOF via TRIG_A
951 optc->funcs->setup_manual_trigger(optc);
952 }
953
optc1_set_vtotal_min_max(struct timing_generator * optc,int vtotal_min,int vtotal_max)954 void optc1_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, int vtotal_max)
955 {
956 struct optc *optc1 = DCN10TG_FROM_TG(optc);
957
958 REG_SET(OTG_V_TOTAL_MAX, 0,
959 OTG_V_TOTAL_MAX, vtotal_max);
960
961 REG_SET(OTG_V_TOTAL_MIN, 0,
962 OTG_V_TOTAL_MIN, vtotal_min);
963 }
964
optc1_set_test_pattern(struct timing_generator * optc,enum controller_dp_test_pattern test_pattern,enum dc_color_depth color_depth)965 static void optc1_set_test_pattern(
966 struct timing_generator *optc,
967 /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
968 * because this is not DP-specific (which is probably somewhere in DP
969 * encoder) */
970 enum controller_dp_test_pattern test_pattern,
971 enum dc_color_depth color_depth)
972 {
973 struct optc *optc1 = DCN10TG_FROM_TG(optc);
974 enum test_pattern_color_format bit_depth;
975 enum test_pattern_dyn_range dyn_range;
976 enum test_pattern_mode mode;
977 uint32_t pattern_mask;
978 uint32_t pattern_data;
979 /* color ramp generator mixes 16-bits color */
980 uint32_t src_bpc = 16;
981 /* requested bpc */
982 uint32_t dst_bpc;
983 uint32_t index;
984 /* RGB values of the color bars.
985 * Produce two RGB colors: RGB0 - white (all Fs)
986 * and RGB1 - black (all 0s)
987 * (three RGB components for two colors)
988 */
989 uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
990 0x0000, 0x0000};
991 /* dest color (converted to the specified color format) */
992 uint16_t dst_color[6];
993 uint32_t inc_base;
994
995 /* translate to bit depth */
996 switch (color_depth) {
997 case COLOR_DEPTH_666:
998 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
999 break;
1000 case COLOR_DEPTH_888:
1001 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
1002 break;
1003 case COLOR_DEPTH_101010:
1004 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
1005 break;
1006 case COLOR_DEPTH_121212:
1007 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
1008 break;
1009 default:
1010 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
1011 break;
1012 }
1013
1014 switch (test_pattern) {
1015 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
1016 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
1017 {
1018 dyn_range = (test_pattern ==
1019 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
1020 TEST_PATTERN_DYN_RANGE_CEA :
1021 TEST_PATTERN_DYN_RANGE_VESA);
1022 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
1023
1024 REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS,
1025 OTG_TEST_PATTERN_VRES, 6,
1026 OTG_TEST_PATTERN_HRES, 6);
1027
1028 REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
1029 OTG_TEST_PATTERN_EN, 1,
1030 OTG_TEST_PATTERN_MODE, mode,
1031 OTG_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
1032 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
1033 }
1034 break;
1035
1036 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
1037 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
1038 {
1039 mode = (test_pattern ==
1040 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
1041 TEST_PATTERN_MODE_VERTICALBARS :
1042 TEST_PATTERN_MODE_HORIZONTALBARS);
1043
1044 switch (bit_depth) {
1045 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1046 dst_bpc = 6;
1047 break;
1048 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1049 dst_bpc = 8;
1050 break;
1051 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1052 dst_bpc = 10;
1053 break;
1054 default:
1055 dst_bpc = 8;
1056 break;
1057 }
1058
1059 /* adjust color to the required colorFormat */
1060 for (index = 0; index < 6; index++) {
1061 /* dst = 2^dstBpc * src / 2^srcBpc = src >>
1062 * (srcBpc - dstBpc);
1063 */
1064 dst_color[index] =
1065 src_color[index] >> (src_bpc - dst_bpc);
1066 /* CRTC_TEST_PATTERN_DATA has 16 bits,
1067 * lowest 6 are hardwired to ZERO
1068 * color bits should be left aligned to MSB
1069 * XXXXXXXXXX000000 for 10 bit,
1070 * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
1071 */
1072 dst_color[index] <<= (16 - dst_bpc);
1073 }
1074
1075 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
1076
1077 /* We have to write the mask before data, similar to pipeline.
1078 * For example, for 8 bpc, if we want RGB0 to be magenta,
1079 * and RGB1 to be cyan,
1080 * we need to make 7 writes:
1081 * MASK DATA
1082 * 000001 00000000 00000000 set mask to R0
1083 * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0
1084 * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0
1085 * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1
1086 * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1
1087 * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1
1088 * 100000 11111111 00000000 B1 255, 0xFF00
1089 *
1090 * we will make a loop of 6 in which we prepare the mask,
1091 * then write, then prepare the color for next write.
1092 * first iteration will write mask only,
1093 * but each next iteration color prepared in
1094 * previous iteration will be written within new mask,
1095 * the last component will written separately,
1096 * mask is not changing between 6th and 7th write
1097 * and color will be prepared by last iteration
1098 */
1099
1100 /* write color, color values mask in CRTC_TEST_PATTERN_MASK
1101 * is B1, G1, R1, B0, G0, R0
1102 */
1103 pattern_data = 0;
1104 for (index = 0; index < 6; index++) {
1105 /* prepare color mask, first write PATTERN_DATA
1106 * will have all zeros
1107 */
1108 pattern_mask = (1 << index);
1109
1110 /* write color component */
1111 REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
1112 OTG_TEST_PATTERN_MASK, pattern_mask,
1113 OTG_TEST_PATTERN_DATA, pattern_data);
1114
1115 /* prepare next color component,
1116 * will be written in the next iteration
1117 */
1118 pattern_data = dst_color[index];
1119 }
1120 /* write last color component,
1121 * it's been already prepared in the loop
1122 */
1123 REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
1124 OTG_TEST_PATTERN_MASK, pattern_mask,
1125 OTG_TEST_PATTERN_DATA, pattern_data);
1126
1127 /* enable test pattern */
1128 REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
1129 OTG_TEST_PATTERN_EN, 1,
1130 OTG_TEST_PATTERN_MODE, mode,
1131 OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
1132 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
1133 }
1134 break;
1135
1136 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
1137 {
1138 mode = (bit_depth ==
1139 TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
1140 TEST_PATTERN_MODE_DUALRAMP_RGB :
1141 TEST_PATTERN_MODE_SINGLERAMP_RGB);
1142
1143 switch (bit_depth) {
1144 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1145 dst_bpc = 6;
1146 break;
1147 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1148 dst_bpc = 8;
1149 break;
1150 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1151 dst_bpc = 10;
1152 break;
1153 default:
1154 dst_bpc = 8;
1155 break;
1156 }
1157
1158 /* increment for the first ramp for one color gradation
1159 * 1 gradation for 6-bit color is 2^10
1160 * gradations in 16-bit color
1161 */
1162 inc_base = (src_bpc - dst_bpc);
1163
1164 switch (bit_depth) {
1165 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1166 {
1167 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
1168 OTG_TEST_PATTERN_INC0, inc_base,
1169 OTG_TEST_PATTERN_INC1, 0,
1170 OTG_TEST_PATTERN_HRES, 6,
1171 OTG_TEST_PATTERN_VRES, 6,
1172 OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
1173 }
1174 break;
1175 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1176 {
1177 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
1178 OTG_TEST_PATTERN_INC0, inc_base,
1179 OTG_TEST_PATTERN_INC1, 0,
1180 OTG_TEST_PATTERN_HRES, 8,
1181 OTG_TEST_PATTERN_VRES, 6,
1182 OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
1183 }
1184 break;
1185 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1186 {
1187 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
1188 OTG_TEST_PATTERN_INC0, inc_base,
1189 OTG_TEST_PATTERN_INC1, inc_base + 2,
1190 OTG_TEST_PATTERN_HRES, 8,
1191 OTG_TEST_PATTERN_VRES, 5,
1192 OTG_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
1193 }
1194 break;
1195 default:
1196 break;
1197 }
1198
1199 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
1200
1201 /* enable test pattern */
1202 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
1203
1204 REG_SET_4(OTG_TEST_PATTERN_CONTROL, 0,
1205 OTG_TEST_PATTERN_EN, 1,
1206 OTG_TEST_PATTERN_MODE, mode,
1207 OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
1208 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
1209 }
1210 break;
1211 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1212 {
1213 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
1214 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
1215 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
1216 }
1217 break;
1218 default:
1219 break;
1220
1221 }
1222 }
1223
optc1_get_crtc_scanoutpos(struct timing_generator * optc,uint32_t * v_blank_start,uint32_t * v_blank_end,uint32_t * h_position,uint32_t * v_position)1224 void optc1_get_crtc_scanoutpos(
1225 struct timing_generator *optc,
1226 uint32_t *v_blank_start,
1227 uint32_t *v_blank_end,
1228 uint32_t *h_position,
1229 uint32_t *v_position)
1230 {
1231 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1232 struct crtc_position position;
1233
1234 REG_GET_2(OTG_V_BLANK_START_END,
1235 OTG_V_BLANK_START, v_blank_start,
1236 OTG_V_BLANK_END, v_blank_end);
1237
1238 optc1_get_position(optc, &position);
1239
1240 *h_position = position.horizontal_count;
1241 *v_position = position.vertical_count;
1242 }
1243
optc1_enable_stereo(struct timing_generator * optc,const struct dc_crtc_timing * timing,struct crtc_stereo_flags * flags)1244 static void optc1_enable_stereo(struct timing_generator *optc,
1245 const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
1246 {
1247 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1248
1249 if (flags) {
1250 uint32_t stereo_en;
1251 stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0;
1252
1253 if (flags->PROGRAM_STEREO)
1254 REG_UPDATE_3(OTG_STEREO_CONTROL,
1255 OTG_STEREO_EN, stereo_en,
1256 OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0,
1257 OTG_STEREO_SYNC_OUTPUT_POLARITY, flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1);
1258
1259 if (flags->PROGRAM_POLARITY)
1260 REG_UPDATE(OTG_STEREO_CONTROL,
1261 OTG_STEREO_EYE_FLAG_POLARITY,
1262 flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1);
1263
1264 if (flags->DISABLE_STEREO_DP_SYNC)
1265 REG_UPDATE(OTG_STEREO_CONTROL,
1266 OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1);
1267
1268 if (flags->PROGRAM_STEREO)
1269 REG_UPDATE_2(OTG_3D_STRUCTURE_CONTROL,
1270 OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED,
1271 OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED);
1272
1273 }
1274 }
1275
optc1_program_stereo(struct timing_generator * optc,const struct dc_crtc_timing * timing,struct crtc_stereo_flags * flags)1276 void optc1_program_stereo(struct timing_generator *optc,
1277 const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
1278 {
1279 if (flags->PROGRAM_STEREO)
1280 optc1_enable_stereo(optc, timing, flags);
1281 else
1282 optc1_disable_stereo(optc);
1283 }
1284
1285
optc1_is_stereo_left_eye(struct timing_generator * optc)1286 bool optc1_is_stereo_left_eye(struct timing_generator *optc)
1287 {
1288 bool ret = false;
1289 uint32_t left_eye = 0;
1290 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1291
1292 REG_GET(OTG_STEREO_STATUS,
1293 OTG_STEREO_CURRENT_EYE, &left_eye);
1294 if (left_eye == 1)
1295 ret = true;
1296 else
1297 ret = false;
1298
1299 return ret;
1300 }
1301
optc1_get_hw_timing(struct timing_generator * tg,struct dc_crtc_timing * hw_crtc_timing)1302 bool optc1_get_hw_timing(struct timing_generator *tg,
1303 struct dc_crtc_timing *hw_crtc_timing)
1304 {
1305 struct dcn_otg_state s = {0};
1306
1307 if (tg == NULL || hw_crtc_timing == NULL)
1308 return false;
1309
1310 optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
1311
1312 hw_crtc_timing->h_total = s.h_total + 1;
1313 hw_crtc_timing->h_addressable = s.h_total - ((s.h_total - s.h_blank_start) + s.h_blank_end);
1314 hw_crtc_timing->h_front_porch = s.h_total + 1 - s.h_blank_start;
1315 hw_crtc_timing->h_sync_width = s.h_sync_a_end - s.h_sync_a_start;
1316
1317 hw_crtc_timing->v_total = s.v_total + 1;
1318 hw_crtc_timing->v_addressable = s.v_total - ((s.v_total - s.v_blank_start) + s.v_blank_end);
1319 hw_crtc_timing->v_front_porch = s.v_total + 1 - s.v_blank_start;
1320 hw_crtc_timing->v_sync_width = s.v_sync_a_end - s.v_sync_a_start;
1321
1322 return true;
1323 }
1324
1325
optc1_read_otg_state(struct optc * optc1,struct dcn_otg_state * s)1326 void optc1_read_otg_state(struct optc *optc1,
1327 struct dcn_otg_state *s)
1328 {
1329 REG_GET(OTG_CONTROL,
1330 OTG_MASTER_EN, &s->otg_enabled);
1331
1332 REG_GET_2(OTG_V_BLANK_START_END,
1333 OTG_V_BLANK_START, &s->v_blank_start,
1334 OTG_V_BLANK_END, &s->v_blank_end);
1335
1336 REG_GET(OTG_V_SYNC_A_CNTL,
1337 OTG_V_SYNC_A_POL, &s->v_sync_a_pol);
1338
1339 REG_GET(OTG_V_TOTAL,
1340 OTG_V_TOTAL, &s->v_total);
1341
1342 REG_GET(OTG_V_TOTAL_MAX,
1343 OTG_V_TOTAL_MAX, &s->v_total_max);
1344
1345 REG_GET(OTG_V_TOTAL_MIN,
1346 OTG_V_TOTAL_MIN, &s->v_total_min);
1347
1348 REG_GET(OTG_V_TOTAL_CONTROL,
1349 OTG_V_TOTAL_MAX_SEL, &s->v_total_max_sel);
1350
1351 REG_GET(OTG_V_TOTAL_CONTROL,
1352 OTG_V_TOTAL_MIN_SEL, &s->v_total_min_sel);
1353
1354 REG_GET_2(OTG_V_SYNC_A,
1355 OTG_V_SYNC_A_START, &s->v_sync_a_start,
1356 OTG_V_SYNC_A_END, &s->v_sync_a_end);
1357
1358 REG_GET_2(OTG_H_BLANK_START_END,
1359 OTG_H_BLANK_START, &s->h_blank_start,
1360 OTG_H_BLANK_END, &s->h_blank_end);
1361
1362 REG_GET_2(OTG_H_SYNC_A,
1363 OTG_H_SYNC_A_START, &s->h_sync_a_start,
1364 OTG_H_SYNC_A_END, &s->h_sync_a_end);
1365
1366 REG_GET(OTG_H_SYNC_A_CNTL,
1367 OTG_H_SYNC_A_POL, &s->h_sync_a_pol);
1368
1369 REG_GET(OTG_H_TOTAL,
1370 OTG_H_TOTAL, &s->h_total);
1371
1372 REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
1373 OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
1374
1375 REG_GET(OTG_VERTICAL_INTERRUPT1_CONTROL,
1376 OTG_VERTICAL_INTERRUPT1_INT_ENABLE, &s->vertical_interrupt1_en);
1377
1378 REG_GET(OTG_VERTICAL_INTERRUPT1_POSITION,
1379 OTG_VERTICAL_INTERRUPT1_LINE_START, &s->vertical_interrupt1_line);
1380
1381 REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
1382 OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &s->vertical_interrupt2_en);
1383
1384 REG_GET(OTG_VERTICAL_INTERRUPT2_POSITION,
1385 OTG_VERTICAL_INTERRUPT2_LINE_START, &s->vertical_interrupt2_line);
1386 }
1387
optc1_get_otg_active_size(struct timing_generator * optc,uint32_t * otg_active_width,uint32_t * otg_active_height)1388 bool optc1_get_otg_active_size(struct timing_generator *optc,
1389 uint32_t *otg_active_width,
1390 uint32_t *otg_active_height)
1391 {
1392 uint32_t otg_enabled;
1393 uint32_t v_blank_start;
1394 uint32_t v_blank_end;
1395 uint32_t h_blank_start;
1396 uint32_t h_blank_end;
1397 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1398
1399
1400 REG_GET(OTG_CONTROL,
1401 OTG_MASTER_EN, &otg_enabled);
1402
1403 if (otg_enabled == 0)
1404 return false;
1405
1406 REG_GET_2(OTG_V_BLANK_START_END,
1407 OTG_V_BLANK_START, &v_blank_start,
1408 OTG_V_BLANK_END, &v_blank_end);
1409
1410 REG_GET_2(OTG_H_BLANK_START_END,
1411 OTG_H_BLANK_START, &h_blank_start,
1412 OTG_H_BLANK_END, &h_blank_end);
1413
1414 *otg_active_width = v_blank_start - v_blank_end;
1415 *otg_active_height = h_blank_start - h_blank_end;
1416 return true;
1417 }
1418
optc1_clear_optc_underflow(struct timing_generator * optc)1419 void optc1_clear_optc_underflow(struct timing_generator *optc)
1420 {
1421 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1422
1423 REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
1424 }
1425
optc1_tg_init(struct timing_generator * optc)1426 void optc1_tg_init(struct timing_generator *optc)
1427 {
1428 optc1_set_blank_data_double_buffer(optc, true);
1429 optc1_set_timing_double_buffer(optc, true);
1430 optc1_clear_optc_underflow(optc);
1431 }
1432
optc1_is_tg_enabled(struct timing_generator * optc)1433 bool optc1_is_tg_enabled(struct timing_generator *optc)
1434 {
1435 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1436 uint32_t otg_enabled = 0;
1437
1438 REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled);
1439
1440 return (otg_enabled != 0);
1441
1442 }
1443
optc1_is_optc_underflow_occurred(struct timing_generator * optc)1444 bool optc1_is_optc_underflow_occurred(struct timing_generator *optc)
1445 {
1446 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1447 uint32_t underflow_occurred = 0;
1448
1449 REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
1450 OPTC_UNDERFLOW_OCCURRED_STATUS,
1451 &underflow_occurred);
1452
1453 return (underflow_occurred == 1);
1454 }
1455
optc1_configure_crc(struct timing_generator * optc,const struct crc_params * params)1456 bool optc1_configure_crc(struct timing_generator *optc,
1457 const struct crc_params *params)
1458 {
1459 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1460
1461 /* Cannot configure crc on a CRTC that is disabled */
1462 if (!optc1_is_tg_enabled(optc))
1463 return false;
1464
1465 REG_WRITE(OTG_CRC_CNTL, 0);
1466
1467 if (!params->enable)
1468 return true;
1469
1470 /* Program frame boundaries */
1471 /* Window A x axis start and end. */
1472 REG_UPDATE_2(OTG_CRC0_WINDOWA_X_CONTROL,
1473 OTG_CRC0_WINDOWA_X_START, params->windowa_x_start,
1474 OTG_CRC0_WINDOWA_X_END, params->windowa_x_end);
1475
1476 /* Window A y axis start and end. */
1477 REG_UPDATE_2(OTG_CRC0_WINDOWA_Y_CONTROL,
1478 OTG_CRC0_WINDOWA_Y_START, params->windowa_y_start,
1479 OTG_CRC0_WINDOWA_Y_END, params->windowa_y_end);
1480
1481 /* Window B x axis start and end. */
1482 REG_UPDATE_2(OTG_CRC0_WINDOWB_X_CONTROL,
1483 OTG_CRC0_WINDOWB_X_START, params->windowb_x_start,
1484 OTG_CRC0_WINDOWB_X_END, params->windowb_x_end);
1485
1486 /* Window B y axis start and end. */
1487 REG_UPDATE_2(OTG_CRC0_WINDOWB_Y_CONTROL,
1488 OTG_CRC0_WINDOWB_Y_START, params->windowb_y_start,
1489 OTG_CRC0_WINDOWB_Y_END, params->windowb_y_end);
1490
1491 /* Set crc mode and selection, and enable. Only using CRC0*/
1492 REG_UPDATE_3(OTG_CRC_CNTL,
1493 OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0,
1494 OTG_CRC0_SELECT, params->selection,
1495 OTG_CRC_EN, 1);
1496
1497 return true;
1498 }
1499
1500 /**
1501 * optc1_get_crc - Capture CRC result per component
1502 *
1503 * @optc: timing_generator instance.
1504 * @r_cr: 16-bit primary CRC signature for red data.
1505 * @g_y: 16-bit primary CRC signature for green data.
1506 * @b_cb: 16-bit primary CRC signature for blue data.
1507 *
1508 * This function reads the CRC signature from the OPTC registers. Notice that
1509 * we have three registers to keep the CRC result per color component (RGB).
1510 *
1511 * Returns:
1512 * If CRC is disabled, return false; otherwise, return true, and the CRC
1513 * results in the parameters.
1514 */
optc1_get_crc(struct timing_generator * optc,uint32_t * r_cr,uint32_t * g_y,uint32_t * b_cb)1515 bool optc1_get_crc(struct timing_generator *optc,
1516 uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
1517 {
1518 uint32_t field = 0;
1519 struct optc *optc1 = DCN10TG_FROM_TG(optc);
1520
1521 REG_GET(OTG_CRC_CNTL, OTG_CRC_EN, &field);
1522
1523 /* Early return if CRC is not enabled for this CRTC */
1524 if (!field)
1525 return false;
1526
1527 /* OTG_CRC0_DATA_RG has the CRC16 results for the red and green component */
1528 REG_GET_2(OTG_CRC0_DATA_RG,
1529 CRC0_R_CR, r_cr,
1530 CRC0_G_Y, g_y);
1531
1532 /* OTG_CRC0_DATA_B has the CRC16 results for the blue component */
1533 REG_GET(OTG_CRC0_DATA_B,
1534 CRC0_B_CB, b_cb);
1535
1536 return true;
1537 }
1538
1539 static const struct timing_generator_funcs dcn10_tg_funcs = {
1540 .validate_timing = optc1_validate_timing,
1541 .program_timing = optc1_program_timing,
1542 .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0,
1543 .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1,
1544 .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2,
1545 .program_global_sync = optc1_program_global_sync,
1546 .enable_crtc = optc1_enable_crtc,
1547 .disable_crtc = optc1_disable_crtc,
1548 /* used by enable_timing_synchronization. Not need for FPGA */
1549 .is_counter_moving = optc1_is_counter_moving,
1550 .get_position = optc1_get_position,
1551 .get_frame_count = optc1_get_vblank_counter,
1552 .get_scanoutpos = optc1_get_crtc_scanoutpos,
1553 .get_otg_active_size = optc1_get_otg_active_size,
1554 .set_early_control = optc1_set_early_control,
1555 /* used by enable_timing_synchronization. Not need for FPGA */
1556 .wait_for_state = optc1_wait_for_state,
1557 .set_blank = optc1_set_blank,
1558 .is_blanked = optc1_is_blanked,
1559 .set_blank_color = optc1_program_blank_color,
1560 .did_triggered_reset_occur = optc1_did_triggered_reset_occur,
1561 .enable_reset_trigger = optc1_enable_reset_trigger,
1562 .enable_crtc_reset = optc1_enable_crtc_reset,
1563 .disable_reset_trigger = optc1_disable_reset_trigger,
1564 .lock = optc1_lock,
1565 .unlock = optc1_unlock,
1566 .enable_optc_clock = optc1_enable_optc_clock,
1567 .set_drr = optc1_set_drr,
1568 .get_last_used_drr_vtotal = NULL,
1569 .set_vtotal_min_max = optc1_set_vtotal_min_max,
1570 .set_static_screen_control = optc1_set_static_screen_control,
1571 .set_test_pattern = optc1_set_test_pattern,
1572 .program_stereo = optc1_program_stereo,
1573 .is_stereo_left_eye = optc1_is_stereo_left_eye,
1574 .set_blank_data_double_buffer = optc1_set_blank_data_double_buffer,
1575 .tg_init = optc1_tg_init,
1576 .is_tg_enabled = optc1_is_tg_enabled,
1577 .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred,
1578 .clear_optc_underflow = optc1_clear_optc_underflow,
1579 .get_crc = optc1_get_crc,
1580 .configure_crc = optc1_configure_crc,
1581 .set_vtg_params = optc1_set_vtg_params,
1582 .program_manual_trigger = optc1_program_manual_trigger,
1583 .setup_manual_trigger = optc1_setup_manual_trigger,
1584 .get_hw_timing = optc1_get_hw_timing,
1585 };
1586
dcn10_timing_generator_init(struct optc * optc1)1587 void dcn10_timing_generator_init(struct optc *optc1)
1588 {
1589 optc1->base.funcs = &dcn10_tg_funcs;
1590
1591 optc1->max_h_total = optc1->tg_mask->OTG_H_TOTAL + 1;
1592 optc1->max_v_total = optc1->tg_mask->OTG_V_TOTAL + 1;
1593
1594 optc1->min_h_blank = 32;
1595 optc1->min_v_blank = 3;
1596 optc1->min_v_blank_interlace = 5;
1597 optc1->min_h_sync_width = 4;
1598 optc1->min_v_sync_width = 1;
1599 }
1600
1601 /* "Containter" vs. "pixel" is a concept within HW blocks, mostly those closer to the back-end. It works like this:
1602 *
1603 * - In most of the formats (RGB or YCbCr 4:4:4, 4:2:2 uncompressed and DSC 4:2:2 Simple) pixel rate is the same as
1604 * containter rate.
1605 *
1606 * - In 4:2:0 (DSC or uncompressed) there are two pixels per container, hence the target container rate has to be
1607 * halved to maintain the correct pixel rate.
1608 *
1609 * - Unlike 4:2:2 uncompressed, DSC 4:2:2 Native also has two pixels per container (this happens when DSC is applied
1610 * to it) and has to be treated the same as 4:2:0, i.e. target containter rate has to be halved in this case as well.
1611 *
1612 */
optc1_is_two_pixels_per_containter(const struct dc_crtc_timing * timing)1613 bool optc1_is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
1614 {
1615 bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
1616
1617 two_pix = two_pix || (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
1618 && !timing->dsc_cfg.ycbcr422_simple);
1619 return two_pix;
1620 }
1621
1622