2 * Copyright 2012-15 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include "reg_helper.h"
27 #include "dcn10_timing_generator.h"
37 #define FN(reg_name, field_name) \
38 tgn10->tg_shift->field_name, tgn10->tg_mask->field_name
40 #define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100
43 * apply_front_porch_workaround TODO FPGA still need?
45 * This is a workaround for a bug that has existed since R5xx and has not been
46 * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
48 static void tgn10_apply_front_porch_workaround(
49 struct timing_generator *tg,
50 struct dc_crtc_timing *timing)
52 if (timing->flags.INTERLACE == 1) {
53 if (timing->v_front_porch < 2)
54 timing->v_front_porch = 2;
56 if (timing->v_front_porch < 1)
57 timing->v_front_porch = 1;
61 static void tgn10_program_global_sync(
62 struct timing_generator *tg)
64 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
66 if (tg->dlg_otg_param.vstartup_start == 0) {
71 REG_SET(OTG_VSTARTUP_PARAM, 0,
72 VSTARTUP_START, tg->dlg_otg_param.vstartup_start);
74 REG_SET_2(OTG_VUPDATE_PARAM, 0,
75 VUPDATE_OFFSET, tg->dlg_otg_param.vupdate_offset,
76 VUPDATE_WIDTH, tg->dlg_otg_param.vupdate_width);
78 REG_SET(OTG_VREADY_PARAM, 0,
79 VREADY_OFFSET, tg->dlg_otg_param.vready_offset);
82 static void tgn10_disable_stereo(struct timing_generator *tg)
84 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
86 REG_SET(OTG_STEREO_CONTROL, 0,
89 REG_SET_3(OTG_3D_STRUCTURE_CONTROL, 0,
90 OTG_3D_STRUCTURE_EN, 0,
91 OTG_3D_STRUCTURE_V_UPDATE_MODE, 0,
92 OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
94 REG_UPDATE(OPPBUF_CONTROL,
95 OPPBUF_ACTIVE_WIDTH, 0);
96 REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
97 OPPBUF_3D_VACT_SPACE1_SIZE, 0);
101 * program_timing_generator used by mode timing set
102 * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition.
103 * Including SYNC. Call BIOS command table to program Timings.
105 static void tgn10_program_timing(
106 struct timing_generator *tg,
107 const struct dc_crtc_timing *dc_crtc_timing,
110 struct dc_crtc_timing patched_crtc_timing;
111 uint32_t vesa_sync_start;
112 uint32_t asic_blank_end;
113 uint32_t asic_blank_start;
116 uint32_t v_init, v_fp2;
117 uint32_t h_sync_polarity, v_sync_polarity;
118 uint32_t interlace_factor;
119 uint32_t start_point = 0;
120 uint32_t field_num = 0;
122 int32_t vertical_line_start;
124 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
126 patched_crtc_timing = *dc_crtc_timing;
127 tgn10_apply_front_porch_workaround(tg, &patched_crtc_timing);
129 /* Load horizontal timing */
131 /* CRTC_H_TOTAL = vesa.h_total - 1 */
132 REG_SET(OTG_H_TOTAL, 0,
133 OTG_H_TOTAL, patched_crtc_timing.h_total - 1);
135 /* h_sync_start = 0, h_sync_end = vesa.h_sync_width */
136 REG_UPDATE_2(OTG_H_SYNC_A,
137 OTG_H_SYNC_A_START, 0,
138 OTG_H_SYNC_A_END, patched_crtc_timing.h_sync_width);
140 /* asic_h_blank_end = HsyncWidth + HbackPorch =
141 * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart -
144 vesa_sync_start = patched_crtc_timing.h_addressable +
145 patched_crtc_timing.h_border_right +
146 patched_crtc_timing.h_front_porch;
148 asic_blank_end = patched_crtc_timing.h_total -
150 patched_crtc_timing.h_border_left;
152 /* h_blank_start = v_blank_end + v_active */
153 asic_blank_start = asic_blank_end +
154 patched_crtc_timing.h_border_left +
155 patched_crtc_timing.h_addressable +
156 patched_crtc_timing.h_border_right;
158 REG_UPDATE_2(OTG_H_BLANK_START_END,
159 OTG_H_BLANK_START, asic_blank_start,
160 OTG_H_BLANK_END, asic_blank_end);
162 /* h_sync polarity */
163 h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ?
166 REG_UPDATE(OTG_H_SYNC_A_CNTL,
167 OTG_H_SYNC_A_POL, h_sync_polarity);
169 /* Load vertical timing */
171 /* CRTC_V_TOTAL = v_total - 1 */
172 if (patched_crtc_timing.flags.INTERLACE) {
173 interlace_factor = 2;
174 v_total = 2 * patched_crtc_timing.v_total;
176 interlace_factor = 1;
177 v_total = patched_crtc_timing.v_total - 1;
179 REG_SET(OTG_V_TOTAL, 0,
180 OTG_V_TOTAL, v_total);
182 /* In case of V_TOTAL_CONTROL is on, make sure OTG_V_TOTAL_MAX and
183 * OTG_V_TOTAL_MIN are equal to V_TOTAL.
185 REG_SET(OTG_V_TOTAL_MAX, 0,
186 OTG_V_TOTAL_MAX, v_total);
187 REG_SET(OTG_V_TOTAL_MIN, 0,
188 OTG_V_TOTAL_MIN, v_total);
190 /* v_sync_start = 0, v_sync_end = v_sync_width */
191 v_sync_end = patched_crtc_timing.v_sync_width * interlace_factor;
193 REG_UPDATE_2(OTG_V_SYNC_A,
194 OTG_V_SYNC_A_START, 0,
195 OTG_V_SYNC_A_END, v_sync_end);
197 vesa_sync_start = patched_crtc_timing.v_addressable +
198 patched_crtc_timing.v_border_bottom +
199 patched_crtc_timing.v_front_porch;
201 asic_blank_end = (patched_crtc_timing.v_total -
203 patched_crtc_timing.v_border_top)
206 /* v_blank_start = v_blank_end + v_active */
207 asic_blank_start = asic_blank_end +
208 (patched_crtc_timing.v_border_top +
209 patched_crtc_timing.v_addressable +
210 patched_crtc_timing.v_border_bottom)
213 REG_UPDATE_2(OTG_V_BLANK_START_END,
214 OTG_V_BLANK_START, asic_blank_start,
215 OTG_V_BLANK_END, asic_blank_end);
217 /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
218 * program the reg for interrupt postition.
220 vertical_line_start = asic_blank_end - tg->dlg_otg_param.vstartup_start + 1;
221 if (vertical_line_start < 0) {
223 vertical_line_start = 0;
225 REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
226 OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start);
228 /* v_sync polarity */
229 v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ?
232 REG_UPDATE(OTG_V_SYNC_A_CNTL,
233 OTG_V_SYNC_A_POL, v_sync_polarity);
235 v_init = asic_blank_start;
236 if (tg->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT ||
237 tg->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
238 tg->dlg_otg_param.signal == SIGNAL_TYPE_EDP) {
240 if (patched_crtc_timing.flags.INTERLACE == 1)
244 if (tg->dlg_otg_param.vstartup_start > asic_blank_end)
245 v_fp2 = tg->dlg_otg_param.vstartup_start > asic_blank_end;
248 if (patched_crtc_timing.flags.INTERLACE == 1) {
249 REG_UPDATE(OTG_INTERLACE_CONTROL,
250 OTG_INTERLACE_ENABLE, 1);
252 if ((tg->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end)
256 REG_UPDATE(OTG_INTERLACE_CONTROL,
257 OTG_INTERLACE_ENABLE, 0);
260 /* VTG enable set to 0 first VInit */
264 REG_UPDATE_2(CONTROL,
266 VTG0_VCOUNT_INIT, v_init);
268 /* original code is using VTG offset to address OTG reg, seems wrong */
269 REG_UPDATE_2(OTG_CONTROL,
270 OTG_START_POINT_CNTL, start_point,
271 OTG_FIELD_NUMBER_CNTL, field_num);
273 tgn10_program_global_sync(tg);
276 * patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1
277 * program_horz_count_by_2
278 * for DVI 30bpp mode, 0 otherwise
279 * program_horz_count_by_2(tg, &patched_crtc_timing);
282 /* Enable stereo - only when we need to pack 3D frame. Other types
283 * of stereo handled in explicit call
285 h_div_2 = (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ?
288 REG_UPDATE(OTG_H_TIMING_CNTL,
289 OTG_H_TIMING_DIV_BY2, h_div_2);
293 static void tgn10_set_blank_data_double_buffer(struct timing_generator *tg, bool enable)
295 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
297 uint32_t blank_data_double_buffer_enable = enable ? 1 : 0;
299 REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
300 OTG_BLANK_DATA_DOUBLE_BUFFER_EN, blank_data_double_buffer_enable);
305 * Call ASIC Control Object to UnBlank CRTC.
307 static void tgn10_unblank_crtc(struct timing_generator *tg)
309 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
310 uint32_t vertical_interrupt_enable = 0;
312 REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
313 OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
315 /* temporary work around for vertical interrupt, once vertical interrupt enabled,
316 * this check will be removed.
318 if (vertical_interrupt_enable)
319 tgn10_set_blank_data_double_buffer(tg, true);
321 REG_UPDATE_2(OTG_BLANK_CONTROL,
322 OTG_BLANK_DATA_EN, 0,
323 OTG_BLANK_DE_MODE, 0);
328 * Call ASIC Control Object to Blank CRTC.
331 static void tgn10_blank_crtc(struct timing_generator *tg)
333 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
335 REG_UPDATE_2(OTG_BLANK_CONTROL,
336 OTG_BLANK_DATA_EN, 1,
337 OTG_BLANK_DE_MODE, 0);
339 tgn10_set_blank_data_double_buffer(tg, false);
342 static void tgn10_set_blank(struct timing_generator *tg,
343 bool enable_blanking)
346 tgn10_blank_crtc(tg);
348 tgn10_unblank_crtc(tg);
351 static bool tgn10_is_blanked(struct timing_generator *tg)
353 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
355 uint32_t blank_state;
357 REG_GET_2(OTG_BLANK_CONTROL,
358 OTG_BLANK_DATA_EN, &blank_en,
359 OTG_CURRENT_BLANK_STATE, &blank_state);
361 return blank_en && blank_state;
364 static void tgn10_enable_optc_clock(struct timing_generator *tg, bool enable)
366 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
369 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
370 OPTC_INPUT_CLK_EN, 1,
371 OPTC_INPUT_CLK_GATE_DIS, 1);
373 REG_WAIT(OPTC_INPUT_CLOCK_CONTROL,
374 OPTC_INPUT_CLK_ON, 1,
378 REG_UPDATE_2(OTG_CLOCK_CONTROL,
380 OTG_CLOCK_GATE_DIS, 1);
381 REG_WAIT(OTG_CLOCK_CONTROL,
385 REG_UPDATE_2(OTG_CLOCK_CONTROL,
386 OTG_CLOCK_GATE_DIS, 0,
389 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
390 OPTC_INPUT_CLK_GATE_DIS, 0,
391 OPTC_INPUT_CLK_EN, 0);
397 * Enable CRTC - call ASIC Control Object to enable Timing generator.
399 static bool tgn10_enable_crtc(struct timing_generator *tg)
401 /* TODO FPGA wait for answer
402 * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE
403 * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK
405 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
407 /* opp instance for OTG. For DCN1.0, ODM is remoed.
408 * OPP and OPTC should 1:1 mapping
410 REG_UPDATE(OPTC_DATA_SOURCE_SELECT,
411 OPTC_SRC_SEL, tg->inst);
413 /* VTG enable first is for HW workaround */
418 REG_UPDATE_2(OTG_CONTROL,
419 OTG_DISABLE_POINT_CNTL, 3,
425 /* disable_crtc - call ASIC Control Object to disable Timing generator. */
426 static bool tgn10_disable_crtc(struct timing_generator *tg)
428 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
430 /* disable otg request until end of the first line
431 * in the vertical blank region
433 REG_UPDATE_2(OTG_CONTROL,
434 OTG_DISABLE_POINT_CNTL, 3,
440 /* CRTC disabled, so disable clock. */
441 REG_WAIT(OTG_CLOCK_CONTROL,
449 static void tgn10_program_blank_color(
450 struct timing_generator *tg,
451 const struct tg_color *black_color)
453 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
455 REG_SET_3(OTG_BLACK_COLOR, 0,
456 OTG_BLACK_COLOR_B_CB, black_color->color_b_cb,
457 OTG_BLACK_COLOR_G_Y, black_color->color_g_y,
458 OTG_BLACK_COLOR_R_CR, black_color->color_r_cr);
461 static bool tgn10_validate_timing(
462 struct timing_generator *tg,
463 const struct dc_crtc_timing *timing)
465 uint32_t interlace_factor;
468 uint32_t min_v_blank;
469 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
471 ASSERT(timing != NULL);
473 interlace_factor = timing->flags.INTERLACE ? 2 : 1;
474 v_blank = (timing->v_total - timing->v_addressable -
475 timing->v_border_top - timing->v_border_bottom) *
478 h_blank = (timing->h_total - timing->h_addressable -
479 timing->h_border_right -
480 timing->h_border_left);
482 if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
483 timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING &&
484 timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM &&
485 timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE &&
486 timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE &&
487 timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
490 /* Temporarily blocking interlacing mode until it's supported */
491 if (timing->flags.INTERLACE == 1)
494 /* Check maximum number of pixels supported by Timing Generator
495 * (Currently will never fail, in order to fail needs display which
496 * needs more than 8192 horizontal and
497 * more than 8192 vertical total pixels)
499 if (timing->h_total > tgn10->max_h_total ||
500 timing->v_total > tgn10->max_v_total)
504 if (h_blank < tgn10->min_h_blank)
507 if (timing->h_sync_width < tgn10->min_h_sync_width ||
508 timing->v_sync_width < tgn10->min_v_sync_width)
511 min_v_blank = timing->flags.INTERLACE?tgn10->min_v_blank_interlace:tgn10->min_v_blank;
513 if (v_blank < min_v_blank)
524 * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
525 * holds the counter of frames.
528 * struct timing_generator *tg - [in] timing generator which controls the
532 * Counter of frames, which should equal to number of vblanks.
534 static uint32_t tgn10_get_vblank_counter(struct timing_generator *tg)
536 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
537 uint32_t frame_count;
539 REG_GET(OTG_STATUS_FRAME_COUNT,
540 OTG_FRAME_COUNT, &frame_count);
545 static void tgn10_lock(struct timing_generator *tg)
547 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
549 REG_SET(OTG_GLOBAL_CONTROL0, 0,
550 OTG_MASTER_UPDATE_LOCK_SEL, tg->inst);
551 REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
552 OTG_MASTER_UPDATE_LOCK, 1);
554 /* Should be fast, status does not update on maximus */
555 if (tg->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
556 REG_WAIT(OTG_MASTER_UPDATE_LOCK,
557 UPDATE_LOCK_STATUS, 1,
561 static void tgn10_unlock(struct timing_generator *tg)
563 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
565 REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
566 OTG_MASTER_UPDATE_LOCK, 0);
569 static void tgn10_get_position(struct timing_generator *tg,
570 struct crtc_position *position)
572 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
574 REG_GET_2(OTG_STATUS_POSITION,
575 OTG_HORZ_COUNT, &position->horizontal_count,
576 OTG_VERT_COUNT, &position->vertical_count);
578 REG_GET(OTG_NOM_VERT_POSITION,
579 OTG_VERT_COUNT_NOM, &position->nominal_vcount);
582 static bool tgn10_is_counter_moving(struct timing_generator *tg)
584 struct crtc_position position1, position2;
586 tg->funcs->get_position(tg, &position1);
587 tg->funcs->get_position(tg, &position2);
589 if (position1.horizontal_count == position2.horizontal_count &&
590 position1.vertical_count == position2.vertical_count)
596 static bool tgn10_did_triggered_reset_occur(
597 struct timing_generator *tg)
599 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
600 uint32_t occurred_force, occurred_vsync;
602 REG_GET(OTG_FORCE_COUNT_NOW_CNTL,
603 OTG_FORCE_COUNT_NOW_OCCURRED, &occurred_force);
605 REG_GET(OTG_VERT_SYNC_CONTROL,
606 OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, &occurred_vsync);
608 return occurred_vsync != 0 || occurred_force != 0;
611 static void tgn10_disable_reset_trigger(struct timing_generator *tg)
613 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
615 REG_WRITE(OTG_TRIGA_CNTL, 0);
617 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
618 OTG_FORCE_COUNT_NOW_CLEAR, 1);
620 REG_SET(OTG_VERT_SYNC_CONTROL, 0,
621 OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, 1);
624 static void tgn10_enable_reset_trigger(struct timing_generator *tg, int source_tg_inst)
626 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
627 uint32_t falling_edge;
629 REG_GET(OTG_V_SYNC_A_CNTL,
630 OTG_V_SYNC_A_POL, &falling_edge);
633 REG_SET_3(OTG_TRIGA_CNTL, 0,
634 /* vsync signal from selected OTG pipe based
635 * on OTG_TRIG_SOURCE_PIPE_SELECT setting
637 OTG_TRIGA_SOURCE_SELECT, 20,
638 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
639 /* always detect falling edge */
640 OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 1);
642 REG_SET_3(OTG_TRIGA_CNTL, 0,
643 /* vsync signal from selected OTG pipe based
644 * on OTG_TRIG_SOURCE_PIPE_SELECT setting
646 OTG_TRIGA_SOURCE_SELECT, 20,
647 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
648 /* always detect rising edge */
649 OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1);
651 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
652 /* force H count to H_TOTAL and V count to V_TOTAL in
653 * progressive mode and V_TOTAL-1 in interlaced mode
655 OTG_FORCE_COUNT_NOW_MODE, 2);
658 void tgn10_enable_crtc_reset(
659 struct timing_generator *tg,
661 struct crtc_trigger_info *crtc_tp)
663 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
664 uint32_t falling_edge = 0;
665 uint32_t rising_edge = 0;
667 switch (crtc_tp->event) {
669 case CRTC_EVENT_VSYNC_RISING:
673 case CRTC_EVENT_VSYNC_FALLING:
678 REG_SET_4(OTG_TRIGA_CNTL, 0,
679 /* vsync signal from selected OTG pipe based
680 * on OTG_TRIG_SOURCE_PIPE_SELECT setting
682 OTG_TRIGA_SOURCE_SELECT, 20,
683 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
684 /* always detect falling edge */
685 OTG_TRIGA_RISING_EDGE_DETECT_CNTL, rising_edge,
686 OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, falling_edge);
688 switch (crtc_tp->delay) {
689 case TRIGGER_DELAY_NEXT_LINE:
690 REG_SET(OTG_VERT_SYNC_CONTROL, 0,
691 OTG_AUTO_FORCE_VSYNC_MODE, 1);
693 case TRIGGER_DELAY_NEXT_PIXEL:
694 REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
695 /* force H count to H_TOTAL and V count to V_TOTAL in
696 * progressive mode and V_TOTAL-1 in interlaced mode
698 OTG_FORCE_COUNT_NOW_MODE, 2);
703 static void tgn10_wait_for_state(struct timing_generator *tg,
704 enum crtc_state state)
706 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
709 case CRTC_STATE_VBLANK:
712 1, 100000); /* 1 vupdate at 10hz */
715 case CRTC_STATE_VACTIVE:
717 OTG_V_ACTIVE_DISP, 1,
718 1, 100000); /* 1 vupdate at 10hz */
726 static void tgn10_set_early_control(
727 struct timing_generator *tg,
730 /* asic design change, do not need this control
731 * empty for share caller logic
736 static void tgn10_set_static_screen_control(
737 struct timing_generator *tg,
740 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
742 /* Bit 8 is no longer applicable in RV for PSR case,
743 * set bit 8 to 0 if given
745 if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
748 ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN;
750 REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0,
751 OTG_STATIC_SCREEN_EVENT_MASK, value,
752 OTG_STATIC_SCREEN_FRAME_COUNT, 2);
757 *****************************************************************************
761 * Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*.
763 *****************************************************************************
765 static void tgn10_set_drr(
766 struct timing_generator *tg,
767 const struct drr_params *params)
769 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
771 if (params != NULL &&
772 params->vertical_total_max > 0 &&
773 params->vertical_total_min > 0) {
775 REG_SET(OTG_V_TOTAL_MAX, 0,
776 OTG_V_TOTAL_MAX, params->vertical_total_max - 1);
778 REG_SET(OTG_V_TOTAL_MIN, 0,
779 OTG_V_TOTAL_MIN, params->vertical_total_min - 1);
781 REG_UPDATE_5(OTG_V_TOTAL_CONTROL,
782 OTG_V_TOTAL_MIN_SEL, 1,
783 OTG_V_TOTAL_MAX_SEL, 1,
784 OTG_FORCE_LOCK_ON_EVENT, 0,
785 OTG_SET_V_TOTAL_MIN_MASK_EN, 0,
786 OTG_SET_V_TOTAL_MIN_MASK, 0);
788 REG_SET(OTG_V_TOTAL_MIN, 0,
791 REG_SET(OTG_V_TOTAL_MAX, 0,
794 REG_UPDATE_4(OTG_V_TOTAL_CONTROL,
795 OTG_SET_V_TOTAL_MIN_MASK, 0,
796 OTG_V_TOTAL_MIN_SEL, 0,
797 OTG_V_TOTAL_MAX_SEL, 0,
798 OTG_FORCE_LOCK_ON_EVENT, 0);
802 static void tgn10_set_test_pattern(
803 struct timing_generator *tg,
804 /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
805 * because this is not DP-specific (which is probably somewhere in DP
807 enum controller_dp_test_pattern test_pattern,
808 enum dc_color_depth color_depth)
810 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
811 enum test_pattern_color_format bit_depth;
812 enum test_pattern_dyn_range dyn_range;
813 enum test_pattern_mode mode;
814 uint32_t pattern_mask;
815 uint32_t pattern_data;
816 /* color ramp generator mixes 16-bits color */
817 uint32_t src_bpc = 16;
821 /* RGB values of the color bars.
822 * Produce two RGB colors: RGB0 - white (all Fs)
823 * and RGB1 - black (all 0s)
824 * (three RGB components for two colors)
826 uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
828 /* dest color (converted to the specified color format) */
829 uint16_t dst_color[6];
832 /* translate to bit depth */
833 switch (color_depth) {
834 case COLOR_DEPTH_666:
835 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
837 case COLOR_DEPTH_888:
838 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
840 case COLOR_DEPTH_101010:
841 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
843 case COLOR_DEPTH_121212:
844 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
847 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
851 switch (test_pattern) {
852 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
853 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
855 dyn_range = (test_pattern ==
856 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
857 TEST_PATTERN_DYN_RANGE_CEA :
858 TEST_PATTERN_DYN_RANGE_VESA);
859 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
861 REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS,
862 OTG_TEST_PATTERN_VRES, 6,
863 OTG_TEST_PATTERN_HRES, 6);
865 REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
866 OTG_TEST_PATTERN_EN, 1,
867 OTG_TEST_PATTERN_MODE, mode,
868 OTG_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
869 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
873 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
874 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
876 mode = (test_pattern ==
877 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
878 TEST_PATTERN_MODE_VERTICALBARS :
879 TEST_PATTERN_MODE_HORIZONTALBARS);
882 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
885 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
888 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
896 /* adjust color to the required colorFormat */
897 for (index = 0; index < 6; index++) {
898 /* dst = 2^dstBpc * src / 2^srcBpc = src >>
902 src_color[index] >> (src_bpc - dst_bpc);
903 /* CRTC_TEST_PATTERN_DATA has 16 bits,
904 * lowest 6 are hardwired to ZERO
905 * color bits should be left aligned aligned to MSB
906 * XXXXXXXXXX000000 for 10 bit,
907 * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
909 dst_color[index] <<= (16 - dst_bpc);
912 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
914 /* We have to write the mask before data, similar to pipeline.
915 * For example, for 8 bpc, if we want RGB0 to be magenta,
916 * and RGB1 to be cyan,
917 * we need to make 7 writes:
919 * 000001 00000000 00000000 set mask to R0
920 * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0
921 * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0
922 * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1
923 * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1
924 * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1
925 * 100000 11111111 00000000 B1 255, 0xFF00
927 * we will make a loop of 6 in which we prepare the mask,
928 * then write, then prepare the color for next write.
929 * first iteration will write mask only,
930 * but each next iteration color prepared in
931 * previous iteration will be written within new mask,
932 * the last component will written separately,
933 * mask is not changing between 6th and 7th write
934 * and color will be prepared by last iteration
937 /* write color, color values mask in CRTC_TEST_PATTERN_MASK
938 * is B1, G1, R1, B0, G0, R0
941 for (index = 0; index < 6; index++) {
942 /* prepare color mask, first write PATTERN_DATA
943 * will have all zeros
945 pattern_mask = (1 << index);
947 /* write color component */
948 REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
949 OTG_TEST_PATTERN_MASK, pattern_mask,
950 OTG_TEST_PATTERN_DATA, pattern_data);
952 /* prepare next color component,
953 * will be written in the next iteration
955 pattern_data = dst_color[index];
957 /* write last color component,
958 * it's been already prepared in the loop
960 REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
961 OTG_TEST_PATTERN_MASK, pattern_mask,
962 OTG_TEST_PATTERN_DATA, pattern_data);
964 /* enable test pattern */
965 REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
966 OTG_TEST_PATTERN_EN, 1,
967 OTG_TEST_PATTERN_MODE, mode,
968 OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
969 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
973 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
976 TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
977 TEST_PATTERN_MODE_DUALRAMP_RGB :
978 TEST_PATTERN_MODE_SINGLERAMP_RGB);
981 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
984 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
987 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
995 /* increment for the first ramp for one color gradation
996 * 1 gradation for 6-bit color is 2^10
997 * gradations in 16-bit color
999 inc_base = (src_bpc - dst_bpc);
1001 switch (bit_depth) {
1002 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1004 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
1005 OTG_TEST_PATTERN_INC0, inc_base,
1006 OTG_TEST_PATTERN_INC1, 0,
1007 OTG_TEST_PATTERN_HRES, 6,
1008 OTG_TEST_PATTERN_VRES, 6,
1009 OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
1012 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1014 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
1015 OTG_TEST_PATTERN_INC0, inc_base,
1016 OTG_TEST_PATTERN_INC1, 0,
1017 OTG_TEST_PATTERN_HRES, 8,
1018 OTG_TEST_PATTERN_VRES, 6,
1019 OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
1022 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1024 REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
1025 OTG_TEST_PATTERN_INC0, inc_base,
1026 OTG_TEST_PATTERN_INC1, inc_base + 2,
1027 OTG_TEST_PATTERN_HRES, 8,
1028 OTG_TEST_PATTERN_VRES, 5,
1029 OTG_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
1036 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
1038 /* enable test pattern */
1039 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
1041 REG_SET_4(OTG_TEST_PATTERN_CONTROL, 0,
1042 OTG_TEST_PATTERN_EN, 1,
1043 OTG_TEST_PATTERN_MODE, mode,
1044 OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
1045 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
1048 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1050 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
1051 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
1052 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
1061 static void tgn10_get_crtc_scanoutpos(
1062 struct timing_generator *tg,
1063 uint32_t *v_blank_start,
1064 uint32_t *v_blank_end,
1065 uint32_t *h_position,
1066 uint32_t *v_position)
1068 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1069 struct crtc_position position;
1071 REG_GET_2(OTG_V_BLANK_START_END,
1072 OTG_V_BLANK_START, v_blank_start,
1073 OTG_V_BLANK_END, v_blank_end);
1075 tgn10_get_position(tg, &position);
1077 *h_position = position.horizontal_count;
1078 *v_position = position.vertical_count;
1083 static void tgn10_enable_stereo(struct timing_generator *tg,
1084 const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
1086 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1088 uint32_t active_width = timing->h_addressable;
1089 uint32_t space1_size = timing->v_total - timing->v_addressable;
1093 stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0;
1095 if (flags->PROGRAM_STEREO)
1096 REG_UPDATE_3(OTG_STEREO_CONTROL,
1097 OTG_STEREO_EN, stereo_en,
1098 OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0,
1099 OTG_STEREO_SYNC_OUTPUT_POLARITY, 0);
1101 if (flags->PROGRAM_POLARITY)
1102 REG_UPDATE(OTG_STEREO_CONTROL,
1103 OTG_STEREO_EYE_FLAG_POLARITY,
1104 flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1);
1106 if (flags->DISABLE_STEREO_DP_SYNC)
1107 REG_UPDATE(OTG_STEREO_CONTROL,
1108 OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1);
1110 if (flags->PROGRAM_STEREO)
1111 REG_UPDATE_3(OTG_3D_STRUCTURE_CONTROL,
1112 OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED,
1113 OTG_3D_STRUCTURE_V_UPDATE_MODE, flags->FRAME_PACKED,
1114 OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED);
1118 REG_UPDATE(OPPBUF_CONTROL,
1119 OPPBUF_ACTIVE_WIDTH, active_width);
1121 REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
1122 OPPBUF_3D_VACT_SPACE1_SIZE, space1_size);
1125 static void tgn10_program_stereo(struct timing_generator *tg,
1126 const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
1128 if (flags->PROGRAM_STEREO)
1129 tgn10_enable_stereo(tg, timing, flags);
1131 tgn10_disable_stereo(tg);
1135 static bool tgn10_is_stereo_left_eye(struct timing_generator *tg)
1138 uint32_t left_eye = 0;
1139 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1141 REG_GET(OTG_STEREO_STATUS,
1142 OTG_STEREO_CURRENT_EYE, &left_eye);
1151 void tgn10_read_otg_state(struct dcn10_timing_generator *tgn10,
1152 struct dcn_otg_state *s)
1154 REG_GET(OTG_CONTROL,
1155 OTG_MASTER_EN, &s->otg_enabled);
1157 REG_GET_2(OTG_V_BLANK_START_END,
1158 OTG_V_BLANK_START, &s->v_blank_start,
1159 OTG_V_BLANK_END, &s->v_blank_end);
1161 REG_GET(OTG_V_SYNC_A_CNTL,
1162 OTG_V_SYNC_A_POL, &s->v_sync_a_pol);
1164 REG_GET(OTG_V_TOTAL,
1165 OTG_V_TOTAL, &s->v_total);
1167 REG_GET(OTG_V_TOTAL_MAX,
1168 OTG_V_TOTAL_MAX, &s->v_total_max);
1170 REG_GET(OTG_V_TOTAL_MIN,
1171 OTG_V_TOTAL_MIN, &s->v_total_min);
1173 REG_GET_2(OTG_V_SYNC_A,
1174 OTG_V_SYNC_A_START, &s->v_sync_a_start,
1175 OTG_V_SYNC_A_END, &s->v_sync_a_end);
1177 REG_GET_2(OTG_H_BLANK_START_END,
1178 OTG_H_BLANK_START, &s->h_blank_start,
1179 OTG_H_BLANK_END, &s->h_blank_end);
1181 REG_GET_2(OTG_H_SYNC_A,
1182 OTG_H_SYNC_A_START, &s->h_sync_a_start,
1183 OTG_H_SYNC_A_END, &s->h_sync_a_end);
1185 REG_GET(OTG_H_SYNC_A_CNTL,
1186 OTG_H_SYNC_A_POL, &s->h_sync_a_pol);
1188 REG_GET(OTG_H_TOTAL,
1189 OTG_H_TOTAL, &s->h_total);
1191 REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
1192 OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
1195 static void tgn10_clear_optc_underflow(struct timing_generator *tg)
1197 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1199 REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
1202 static void tgn10_tg_init(struct timing_generator *tg)
1204 tgn10_set_blank_data_double_buffer(tg, true);
1205 tgn10_clear_optc_underflow(tg);
1208 static bool tgn10_is_tg_enabled(struct timing_generator *tg)
1210 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1211 uint32_t otg_enabled = 0;
1213 REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled);
1215 return (otg_enabled != 0);
1219 static bool tgn10_is_optc_underflow_occurred(struct timing_generator *tg)
1221 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1222 uint32_t underflow_occurred = 0;
1224 REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
1225 OPTC_UNDERFLOW_OCCURRED_STATUS,
1226 &underflow_occurred);
1228 return (underflow_occurred == 1);
1231 static const struct timing_generator_funcs dcn10_tg_funcs = {
1232 .validate_timing = tgn10_validate_timing,
1233 .program_timing = tgn10_program_timing,
1234 .program_global_sync = tgn10_program_global_sync,
1235 .enable_crtc = tgn10_enable_crtc,
1236 .disable_crtc = tgn10_disable_crtc,
1237 /* used by enable_timing_synchronization. Not need for FPGA */
1238 .is_counter_moving = tgn10_is_counter_moving,
1239 .get_position = tgn10_get_position,
1240 .get_frame_count = tgn10_get_vblank_counter,
1241 .get_scanoutpos = tgn10_get_crtc_scanoutpos,
1242 .set_early_control = tgn10_set_early_control,
1243 /* used by enable_timing_synchronization. Not need for FPGA */
1244 .wait_for_state = tgn10_wait_for_state,
1245 .set_blank = tgn10_set_blank,
1246 .is_blanked = tgn10_is_blanked,
1247 .set_blank_color = tgn10_program_blank_color,
1248 .did_triggered_reset_occur = tgn10_did_triggered_reset_occur,
1249 .enable_reset_trigger = tgn10_enable_reset_trigger,
1250 .enable_crtc_reset = tgn10_enable_crtc_reset,
1251 .disable_reset_trigger = tgn10_disable_reset_trigger,
1253 .unlock = tgn10_unlock,
1254 .enable_optc_clock = tgn10_enable_optc_clock,
1255 .set_drr = tgn10_set_drr,
1256 .set_static_screen_control = tgn10_set_static_screen_control,
1257 .set_test_pattern = tgn10_set_test_pattern,
1258 .program_stereo = tgn10_program_stereo,
1259 .is_stereo_left_eye = tgn10_is_stereo_left_eye,
1260 .set_blank_data_double_buffer = tgn10_set_blank_data_double_buffer,
1261 .tg_init = tgn10_tg_init,
1262 .is_tg_enabled = tgn10_is_tg_enabled,
1263 .is_optc_underflow_occurred = tgn10_is_optc_underflow_occurred,
1264 .clear_optc_underflow = tgn10_clear_optc_underflow,
1267 void dcn10_timing_generator_init(struct dcn10_timing_generator *tgn10)
1269 tgn10->base.funcs = &dcn10_tg_funcs;
1271 tgn10->max_h_total = tgn10->tg_mask->OTG_H_TOTAL + 1;
1272 tgn10->max_v_total = tgn10->tg_mask->OTG_V_TOTAL + 1;
1274 tgn10->min_h_blank = 32;
1275 tgn10->min_v_blank = 3;
1276 tgn10->min_v_blank_interlace = 5;
1277 tgn10->min_h_sync_width = 8;
1278 tgn10->min_v_sync_width = 1;