drm/amd/display: Implement work around for optc underflow.
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn10 / dcn10_timing_generator.c
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 #include "reg_helper.h"
27 #include "dcn10_timing_generator.h"
28 #include "dc.h"
29
30 #define REG(reg)\
31         tgn10->tg_regs->reg
32
33 #define CTX \
34         tgn10->base.ctx
35
36 #undef FN
37 #define FN(reg_name, field_name) \
38         tgn10->tg_shift->field_name, tgn10->tg_mask->field_name
39
40 #define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100
41
42 /**
43 * apply_front_porch_workaround  TODO FPGA still need?
44 *
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.
47 */
48 static void tgn10_apply_front_porch_workaround(
49         struct timing_generator *tg,
50         struct dc_crtc_timing *timing)
51 {
52         if (timing->flags.INTERLACE == 1) {
53                 if (timing->v_front_porch < 2)
54                         timing->v_front_porch = 2;
55         } else {
56                 if (timing->v_front_porch < 1)
57                         timing->v_front_porch = 1;
58         }
59 }
60
61 static void tgn10_program_global_sync(
62                 struct timing_generator *tg)
63 {
64         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
65
66         if (tg->dlg_otg_param.vstartup_start == 0) {
67                 BREAK_TO_DEBUGGER();
68                 return;
69         }
70
71         REG_SET(OTG_VSTARTUP_PARAM, 0,
72                 VSTARTUP_START, tg->dlg_otg_param.vstartup_start);
73
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);
77
78         REG_SET(OTG_VREADY_PARAM, 0,
79                         VREADY_OFFSET, tg->dlg_otg_param.vready_offset);
80 }
81
82 static void tgn10_disable_stereo(struct timing_generator *tg)
83 {
84         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
85
86         REG_SET(OTG_STEREO_CONTROL, 0,
87                 OTG_STEREO_EN, 0);
88
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);
93
94         REG_UPDATE(OPPBUF_CONTROL,
95                 OPPBUF_ACTIVE_WIDTH, 0);
96         REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
97                 OPPBUF_3D_VACT_SPACE1_SIZE, 0);
98 }
99
100 /**
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.
104  */
105 static void tgn10_program_timing(
106         struct timing_generator *tg,
107         const struct dc_crtc_timing *dc_crtc_timing,
108         bool use_vbios)
109 {
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;
114         uint32_t v_total;
115         uint32_t v_sync_end;
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;
121         uint32_t h_div_2;
122         int32_t vertical_line_start;
123
124         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
125
126         patched_crtc_timing = *dc_crtc_timing;
127         tgn10_apply_front_porch_workaround(tg, &patched_crtc_timing);
128
129         /* Load horizontal timing */
130
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);
134
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);
139
140         /* asic_h_blank_end = HsyncWidth + HbackPorch =
141          * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart -
142          * vesa.h_left_border
143          */
144         vesa_sync_start = patched_crtc_timing.h_addressable +
145                         patched_crtc_timing.h_border_right +
146                         patched_crtc_timing.h_front_porch;
147
148         asic_blank_end = patched_crtc_timing.h_total -
149                         vesa_sync_start -
150                         patched_crtc_timing.h_border_left;
151
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;
157
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);
161
162         /* h_sync polarity */
163         h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ?
164                         0 : 1;
165
166         REG_UPDATE(OTG_H_SYNC_A_CNTL,
167                         OTG_H_SYNC_A_POL, h_sync_polarity);
168
169         /* Load vertical timing */
170
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;
175         } else {
176                 interlace_factor = 1;
177                 v_total = patched_crtc_timing.v_total - 1;
178         }
179         REG_SET(OTG_V_TOTAL, 0,
180                         OTG_V_TOTAL, v_total);
181
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.
184          */
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);
189
190         /* v_sync_start = 0, v_sync_end = v_sync_width */
191         v_sync_end = patched_crtc_timing.v_sync_width * interlace_factor;
192
193         REG_UPDATE_2(OTG_V_SYNC_A,
194                         OTG_V_SYNC_A_START, 0,
195                         OTG_V_SYNC_A_END, v_sync_end);
196
197         vesa_sync_start = patched_crtc_timing.v_addressable +
198                         patched_crtc_timing.v_border_bottom +
199                         patched_crtc_timing.v_front_porch;
200
201         asic_blank_end = (patched_crtc_timing.v_total -
202                         vesa_sync_start -
203                         patched_crtc_timing.v_border_top)
204                         * interlace_factor;
205
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)
211                         * interlace_factor;
212
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);
216
217         /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
218          * program the reg for interrupt postition.
219          */
220         vertical_line_start = asic_blank_end - tg->dlg_otg_param.vstartup_start + 1;
221         if (vertical_line_start < 0) {
222                 ASSERT(0);
223                 vertical_line_start = 0;
224         }
225         REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
226                         OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start);
227
228         /* v_sync polarity */
229         v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ?
230                         0 : 1;
231
232         REG_UPDATE(OTG_V_SYNC_A_CNTL,
233                         OTG_V_SYNC_A_POL, v_sync_polarity);
234
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) {
239                 start_point = 1;
240                 if (patched_crtc_timing.flags.INTERLACE == 1)
241                         field_num = 1;
242         }
243         v_fp2 = 0;
244         if (tg->dlg_otg_param.vstartup_start > asic_blank_end)
245                 v_fp2 = tg->dlg_otg_param.vstartup_start > asic_blank_end;
246
247         /* Interlace */
248         if (patched_crtc_timing.flags.INTERLACE == 1) {
249                 REG_UPDATE(OTG_INTERLACE_CONTROL,
250                                 OTG_INTERLACE_ENABLE, 1);
251                 v_init = v_init / 2;
252                 if ((tg->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end)
253                         v_fp2 = v_fp2 / 2;
254         }
255         else
256                 REG_UPDATE(OTG_INTERLACE_CONTROL,
257                                 OTG_INTERLACE_ENABLE, 0);
258
259
260         /* VTG enable set to 0 first VInit */
261         REG_UPDATE(CONTROL,
262                         VTG0_ENABLE, 0);
263
264         REG_UPDATE_2(CONTROL,
265                         VTG0_FP2, v_fp2,
266                         VTG0_VCOUNT_INIT, v_init);
267
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);
272
273         tgn10_program_global_sync(tg);
274
275         /* TODO
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);
280          */
281
282         /* Enable stereo - only when we need to pack 3D frame. Other types
283          * of stereo handled in explicit call
284          */
285         h_div_2 = (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ?
286                         1 : 0;
287
288         REG_UPDATE(OTG_H_TIMING_CNTL,
289                         OTG_H_TIMING_DIV_BY2, h_div_2);
290
291 }
292
293 static void tgn10_set_blank_data_double_buffer(struct timing_generator *tg, bool enable)
294 {
295         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
296
297         uint32_t blank_data_double_buffer_enable = enable ? 1 : 0;
298
299         REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
300                         OTG_BLANK_DATA_DOUBLE_BUFFER_EN, blank_data_double_buffer_enable);
301 }
302
303 /**
304  * unblank_crtc
305  * Call ASIC Control Object to UnBlank CRTC.
306  */
307 static void tgn10_unblank_crtc(struct timing_generator *tg)
308 {
309         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
310         uint32_t vertical_interrupt_enable = 0;
311
312         REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
313                         OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
314
315         /* temporary work around for vertical interrupt, once vertical interrupt enabled,
316          * this check will be removed.
317          */
318         if (vertical_interrupt_enable)
319                 tgn10_set_blank_data_double_buffer(tg, true);
320
321         REG_UPDATE_2(OTG_BLANK_CONTROL,
322                         OTG_BLANK_DATA_EN, 0,
323                         OTG_BLANK_DE_MODE, 0);
324 }
325
326 /**
327  * blank_crtc
328  * Call ASIC Control Object to Blank CRTC.
329  */
330
331 static void tgn10_blank_crtc(struct timing_generator *tg)
332 {
333         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
334
335         REG_UPDATE_2(OTG_BLANK_CONTROL,
336                         OTG_BLANK_DATA_EN, 1,
337                         OTG_BLANK_DE_MODE, 0);
338
339         tgn10_set_blank_data_double_buffer(tg, false);
340 }
341
342 static void tgn10_set_blank(struct timing_generator *tg,
343                 bool enable_blanking)
344 {
345         if (enable_blanking)
346                 tgn10_blank_crtc(tg);
347         else
348                 tgn10_unblank_crtc(tg);
349 }
350
351 static bool tgn10_is_blanked(struct timing_generator *tg)
352 {
353         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
354         uint32_t blank_en;
355         uint32_t blank_state;
356
357         REG_GET_2(OTG_BLANK_CONTROL,
358                         OTG_BLANK_DATA_EN, &blank_en,
359                         OTG_CURRENT_BLANK_STATE, &blank_state);
360
361         return blank_en && blank_state;
362 }
363
364 static void tgn10_enable_optc_clock(struct timing_generator *tg, bool enable)
365 {
366         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
367
368         if (enable) {
369                 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
370                                 OPTC_INPUT_CLK_EN, 1,
371                                 OPTC_INPUT_CLK_GATE_DIS, 1);
372
373                 REG_WAIT(OPTC_INPUT_CLOCK_CONTROL,
374                                 OPTC_INPUT_CLK_ON, 1,
375                                 1, 1000);
376
377                 /* Enable clock */
378                 REG_UPDATE_2(OTG_CLOCK_CONTROL,
379                                 OTG_CLOCK_EN, 1,
380                                 OTG_CLOCK_GATE_DIS, 1);
381                 REG_WAIT(OTG_CLOCK_CONTROL,
382                                 OTG_CLOCK_ON, 1,
383                                 1, 1000);
384         } else  {
385                 REG_UPDATE_2(OTG_CLOCK_CONTROL,
386                                 OTG_CLOCK_GATE_DIS, 0,
387                                 OTG_CLOCK_EN, 0);
388
389                 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
390                                 OPTC_INPUT_CLK_GATE_DIS, 0,
391                                 OPTC_INPUT_CLK_EN, 0);
392         }
393 }
394
395 /**
396  * Enable CRTC
397  * Enable CRTC - call ASIC Control Object to enable Timing generator.
398  */
399 static bool tgn10_enable_crtc(struct timing_generator *tg)
400 {
401         /* TODO FPGA wait for answer
402          * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE
403          * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK
404          */
405         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
406
407         /* opp instance for OTG. For DCN1.0, ODM is remoed.
408          * OPP and OPTC should 1:1 mapping
409          */
410         REG_UPDATE(OPTC_DATA_SOURCE_SELECT,
411                         OPTC_SRC_SEL, tg->inst);
412
413         /* VTG enable first is for HW workaround */
414         REG_UPDATE(CONTROL,
415                         VTG0_ENABLE, 1);
416
417         /* Enable CRTC */
418         REG_UPDATE_2(OTG_CONTROL,
419                         OTG_DISABLE_POINT_CNTL, 3,
420                         OTG_MASTER_EN, 1);
421
422         return true;
423 }
424
425 /* disable_crtc - call ASIC Control Object to disable Timing generator. */
426 static bool tgn10_disable_crtc(struct timing_generator *tg)
427 {
428         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
429
430         /* disable otg request until end of the first line
431          * in the vertical blank region
432          */
433         REG_UPDATE_2(OTG_CONTROL,
434                         OTG_DISABLE_POINT_CNTL, 3,
435                         OTG_MASTER_EN, 0);
436
437         REG_UPDATE(CONTROL,
438                         VTG0_ENABLE, 0);
439
440         /* CRTC disabled, so disable  clock. */
441         REG_WAIT(OTG_CLOCK_CONTROL,
442                         OTG_BUSY, 0,
443                         1, 100000);
444
445         return true;
446 }
447
448
449 static void tgn10_program_blank_color(
450                 struct timing_generator *tg,
451                 const struct tg_color *black_color)
452 {
453         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
454
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);
459 }
460
461 static bool tgn10_validate_timing(
462         struct timing_generator *tg,
463         const struct dc_crtc_timing *timing)
464 {
465         uint32_t interlace_factor;
466         uint32_t v_blank;
467         uint32_t h_blank;
468         uint32_t min_v_blank;
469         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
470
471         ASSERT(timing != NULL);
472
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) *
476                                         interlace_factor;
477
478         h_blank = (timing->h_total - timing->h_addressable -
479                 timing->h_border_right -
480                 timing->h_border_left);
481
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)
488                 return false;
489
490         /* Temporarily blocking interlacing mode until it's supported */
491         if (timing->flags.INTERLACE == 1)
492                 return false;
493
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)
498          */
499         if (timing->h_total > tgn10->max_h_total ||
500                 timing->v_total > tgn10->max_v_total)
501                 return false;
502
503
504         if (h_blank < tgn10->min_h_blank)
505                 return false;
506
507         if (timing->h_sync_width  < tgn10->min_h_sync_width ||
508                  timing->v_sync_width  < tgn10->min_v_sync_width)
509                 return false;
510
511         min_v_blank = timing->flags.INTERLACE?tgn10->min_v_blank_interlace:tgn10->min_v_blank;
512
513         if (v_blank < min_v_blank)
514                 return false;
515
516         return true;
517
518 }
519
520 /*
521  * get_vblank_counter
522  *
523  * @brief
524  * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
525  * holds the counter of frames.
526  *
527  * @param
528  * struct timing_generator *tg - [in] timing generator which controls the
529  * desired CRTC
530  *
531  * @return
532  * Counter of frames, which should equal to number of vblanks.
533  */
534 static uint32_t tgn10_get_vblank_counter(struct timing_generator *tg)
535 {
536         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
537         uint32_t frame_count;
538
539         REG_GET(OTG_STATUS_FRAME_COUNT,
540                 OTG_FRAME_COUNT, &frame_count);
541
542         return frame_count;
543 }
544
545 static void tgn10_lock(struct timing_generator *tg)
546 {
547         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
548
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);
553
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,
558                                 1, 10);
559 }
560
561 static void tgn10_unlock(struct timing_generator *tg)
562 {
563         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
564
565         REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
566                         OTG_MASTER_UPDATE_LOCK, 0);
567 }
568
569 static void tgn10_get_position(struct timing_generator *tg,
570                 struct crtc_position *position)
571 {
572         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
573
574         REG_GET_2(OTG_STATUS_POSITION,
575                         OTG_HORZ_COUNT, &position->horizontal_count,
576                         OTG_VERT_COUNT, &position->vertical_count);
577
578         REG_GET(OTG_NOM_VERT_POSITION,
579                         OTG_VERT_COUNT_NOM, &position->nominal_vcount);
580 }
581
582 static bool tgn10_is_counter_moving(struct timing_generator *tg)
583 {
584         struct crtc_position position1, position2;
585
586         tg->funcs->get_position(tg, &position1);
587         tg->funcs->get_position(tg, &position2);
588
589         if (position1.horizontal_count == position2.horizontal_count &&
590                 position1.vertical_count == position2.vertical_count)
591                 return false;
592         else
593                 return true;
594 }
595
596 static bool tgn10_did_triggered_reset_occur(
597         struct timing_generator *tg)
598 {
599         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
600         uint32_t occurred_force, occurred_vsync;
601
602         REG_GET(OTG_FORCE_COUNT_NOW_CNTL,
603                 OTG_FORCE_COUNT_NOW_OCCURRED, &occurred_force);
604
605         REG_GET(OTG_VERT_SYNC_CONTROL,
606                 OTG_FORCE_VSYNC_NEXT_LINE_OCCURRED, &occurred_vsync);
607
608         return occurred_vsync != 0 || occurred_force != 0;
609 }
610
611 static void tgn10_disable_reset_trigger(struct timing_generator *tg)
612 {
613         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
614
615         REG_WRITE(OTG_TRIGA_CNTL, 0);
616
617         REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
618                 OTG_FORCE_COUNT_NOW_CLEAR, 1);
619
620         REG_SET(OTG_VERT_SYNC_CONTROL, 0,
621                 OTG_FORCE_VSYNC_NEXT_LINE_CLEAR, 1);
622 }
623
624 static void tgn10_enable_reset_trigger(struct timing_generator *tg, int source_tg_inst)
625 {
626         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
627         uint32_t falling_edge;
628
629         REG_GET(OTG_V_SYNC_A_CNTL,
630                         OTG_V_SYNC_A_POL, &falling_edge);
631
632         if (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
636                                  */
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);
641         else
642                 REG_SET_3(OTG_TRIGA_CNTL, 0,
643                                 /* vsync signal from selected OTG pipe based
644                                  * on OTG_TRIG_SOURCE_PIPE_SELECT setting
645                                  */
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);
650
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
654                          */
655                         OTG_FORCE_COUNT_NOW_MODE, 2);
656 }
657
658 void tgn10_enable_crtc_reset(
659                 struct timing_generator *tg,
660                 int source_tg_inst,
661                 struct crtc_trigger_info *crtc_tp)
662 {
663         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
664         uint32_t falling_edge = 0;
665         uint32_t rising_edge = 0;
666
667         switch (crtc_tp->event) {
668
669         case CRTC_EVENT_VSYNC_RISING:
670                 rising_edge = 1;
671                 break;
672
673         case CRTC_EVENT_VSYNC_FALLING:
674                 falling_edge = 1;
675                 break;
676         }
677
678         REG_SET_4(OTG_TRIGA_CNTL, 0,
679                  /* vsync signal from selected OTG pipe based
680                   * on OTG_TRIG_SOURCE_PIPE_SELECT setting
681                   */
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);
687
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);
692                 break;
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
697                          */
698                         OTG_FORCE_COUNT_NOW_MODE, 2);
699                 break;
700         }
701 }
702
703 static void tgn10_wait_for_state(struct timing_generator *tg,
704                 enum crtc_state state)
705 {
706         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
707
708         switch (state) {
709         case CRTC_STATE_VBLANK:
710                 REG_WAIT(OTG_STATUS,
711                                 OTG_V_BLANK, 1,
712                                 1, 100000); /* 1 vupdate at 10hz */
713                 break;
714
715         case CRTC_STATE_VACTIVE:
716                 REG_WAIT(OTG_STATUS,
717                                 OTG_V_ACTIVE_DISP, 1,
718                                 1, 100000); /* 1 vupdate at 10hz */
719                 break;
720
721         default:
722                 break;
723         }
724 }
725
726 static void tgn10_set_early_control(
727         struct timing_generator *tg,
728         uint32_t early_cntl)
729 {
730         /* asic design change, do not need this control
731          * empty for share caller logic
732          */
733 }
734
735
736 static void tgn10_set_static_screen_control(
737         struct timing_generator *tg,
738         uint32_t value)
739 {
740         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
741
742         /* Bit 8 is no longer applicable in RV for PSR case,
743          * set bit 8 to 0 if given
744          */
745         if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
746                         != 0)
747                 value = value &
748                 ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN;
749
750         REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0,
751                         OTG_STATIC_SCREEN_EVENT_MASK, value,
752                         OTG_STATIC_SCREEN_FRAME_COUNT, 2);
753 }
754
755
756 /**
757  *****************************************************************************
758  *  Function: set_drr
759  *
760  *  @brief
761  *     Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*.
762  *
763  *****************************************************************************
764  */
765 static void tgn10_set_drr(
766         struct timing_generator *tg,
767         const struct drr_params *params)
768 {
769         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
770
771         if (params != NULL &&
772                 params->vertical_total_max > 0 &&
773                 params->vertical_total_min > 0) {
774
775                 REG_SET(OTG_V_TOTAL_MAX, 0,
776                         OTG_V_TOTAL_MAX, params->vertical_total_max - 1);
777
778                 REG_SET(OTG_V_TOTAL_MIN, 0,
779                         OTG_V_TOTAL_MIN, params->vertical_total_min - 1);
780
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);
787         } else {
788                 REG_SET(OTG_V_TOTAL_MIN, 0,
789                         OTG_V_TOTAL_MIN, 0);
790
791                 REG_SET(OTG_V_TOTAL_MAX, 0,
792                         OTG_V_TOTAL_MAX, 0);
793
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);
799         }
800 }
801
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
806          * encoder) */
807         enum controller_dp_test_pattern test_pattern,
808         enum dc_color_depth color_depth)
809 {
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;
818         /* requested bpc */
819         uint32_t dst_bpc;
820         uint32_t index;
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)
825          */
826         uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
827                                                 0x0000, 0x0000};
828         /* dest color (converted to the specified color format) */
829         uint16_t dst_color[6];
830         uint32_t inc_base;
831
832         /* translate to bit depth */
833         switch (color_depth) {
834         case COLOR_DEPTH_666:
835                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
836         break;
837         case COLOR_DEPTH_888:
838                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
839         break;
840         case COLOR_DEPTH_101010:
841                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
842         break;
843         case COLOR_DEPTH_121212:
844                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
845         break;
846         default:
847                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
848         break;
849         }
850
851         switch (test_pattern) {
852         case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
853         case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
854         {
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;
860
861                 REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS,
862                                 OTG_TEST_PATTERN_VRES, 6,
863                                 OTG_TEST_PATTERN_HRES, 6);
864
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);
870         }
871         break;
872
873         case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
874         case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
875         {
876                 mode = (test_pattern ==
877                         CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
878                         TEST_PATTERN_MODE_VERTICALBARS :
879                         TEST_PATTERN_MODE_HORIZONTALBARS);
880
881                 switch (bit_depth) {
882                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
883                         dst_bpc = 6;
884                 break;
885                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
886                         dst_bpc = 8;
887                 break;
888                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
889                         dst_bpc = 10;
890                 break;
891                 default:
892                         dst_bpc = 8;
893                 break;
894                 }
895
896                 /* adjust color to the required colorFormat */
897                 for (index = 0; index < 6; index++) {
898                         /* dst = 2^dstBpc * src / 2^srcBpc = src >>
899                          * (srcBpc - dstBpc);
900                          */
901                         dst_color[index] =
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
908                  */
909                         dst_color[index] <<= (16 - dst_bpc);
910                 }
911
912                 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
913
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:
918                  * MASK   DATA
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
926                  *
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
935                  */
936
937                 /* write color, color values mask in CRTC_TEST_PATTERN_MASK
938                  * is B1, G1, R1, B0, G0, R0
939                  */
940                 pattern_data = 0;
941                 for (index = 0; index < 6; index++) {
942                         /* prepare color mask, first write PATTERN_DATA
943                          * will have all zeros
944                          */
945                         pattern_mask = (1 << index);
946
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);
951
952                         /* prepare next color component,
953                          * will be written in the next iteration
954                          */
955                         pattern_data = dst_color[index];
956                 }
957                 /* write last color component,
958                  * it's been already prepared in the loop
959                  */
960                 REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
961                                 OTG_TEST_PATTERN_MASK, pattern_mask,
962                                 OTG_TEST_PATTERN_DATA, pattern_data);
963
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);
970         }
971         break;
972
973         case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
974         {
975                 mode = (bit_depth ==
976                         TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
977                         TEST_PATTERN_MODE_DUALRAMP_RGB :
978                         TEST_PATTERN_MODE_SINGLERAMP_RGB);
979
980                 switch (bit_depth) {
981                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
982                         dst_bpc = 6;
983                 break;
984                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
985                         dst_bpc = 8;
986                 break;
987                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
988                         dst_bpc = 10;
989                 break;
990                 default:
991                         dst_bpc = 8;
992                 break;
993                 }
994
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
998                  */
999                 inc_base = (src_bpc - dst_bpc);
1000
1001                 switch (bit_depth) {
1002                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1003                 {
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);
1010                 }
1011                 break;
1012                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1013                 {
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);
1020                 }
1021                 break;
1022                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1023                 {
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);
1030                 }
1031                 break;
1032                 default:
1033                 break;
1034                 }
1035
1036                 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
1037
1038                 /* enable test pattern */
1039                 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
1040
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);
1046         }
1047         break;
1048         case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1049         {
1050                 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
1051                 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
1052                 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
1053         }
1054         break;
1055         default:
1056                 break;
1057
1058         }
1059 }
1060
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)
1067 {
1068         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1069         struct crtc_position position;
1070
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);
1074
1075         tgn10_get_position(tg, &position);
1076
1077         *h_position = position.horizontal_count;
1078         *v_position = position.vertical_count;
1079 }
1080
1081
1082
1083 static void tgn10_enable_stereo(struct timing_generator *tg,
1084         const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
1085 {
1086         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1087
1088         uint32_t active_width = timing->h_addressable;
1089         uint32_t space1_size = timing->v_total - timing->v_addressable;
1090
1091         if (flags) {
1092                 uint32_t stereo_en;
1093                 stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0;
1094
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);
1100
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);
1105
1106                 if (flags->DISABLE_STEREO_DP_SYNC)
1107                         REG_UPDATE(OTG_STEREO_CONTROL,
1108                                 OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1);
1109
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);
1115
1116         }
1117
1118         REG_UPDATE(OPPBUF_CONTROL,
1119                 OPPBUF_ACTIVE_WIDTH, active_width);
1120
1121         REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
1122                 OPPBUF_3D_VACT_SPACE1_SIZE, space1_size);
1123 }
1124
1125 static void tgn10_program_stereo(struct timing_generator *tg,
1126         const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
1127 {
1128         if (flags->PROGRAM_STEREO)
1129                 tgn10_enable_stereo(tg, timing, flags);
1130         else
1131                 tgn10_disable_stereo(tg);
1132 }
1133
1134
1135 static bool tgn10_is_stereo_left_eye(struct timing_generator *tg)
1136 {
1137         bool ret = false;
1138         uint32_t left_eye = 0;
1139         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1140
1141         REG_GET(OTG_STEREO_STATUS,
1142                 OTG_STEREO_CURRENT_EYE, &left_eye);
1143         if (left_eye == 1)
1144                 ret = true;
1145         else
1146                 ret = false;
1147
1148         return ret;
1149 }
1150
1151 void tgn10_read_otg_state(struct dcn10_timing_generator *tgn10,
1152                 struct dcn_otg_state *s)
1153 {
1154         REG_GET(OTG_CONTROL,
1155                         OTG_MASTER_EN, &s->otg_enabled);
1156
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);
1160
1161         REG_GET(OTG_V_SYNC_A_CNTL,
1162                         OTG_V_SYNC_A_POL, &s->v_sync_a_pol);
1163
1164         REG_GET(OTG_V_TOTAL,
1165                         OTG_V_TOTAL, &s->v_total);
1166
1167         REG_GET(OTG_V_TOTAL_MAX,
1168                         OTG_V_TOTAL_MAX, &s->v_total_max);
1169
1170         REG_GET(OTG_V_TOTAL_MIN,
1171                         OTG_V_TOTAL_MIN, &s->v_total_min);
1172
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);
1176
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);
1180
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);
1184
1185         REG_GET(OTG_H_SYNC_A_CNTL,
1186                         OTG_H_SYNC_A_POL, &s->h_sync_a_pol);
1187
1188         REG_GET(OTG_H_TOTAL,
1189                         OTG_H_TOTAL, &s->h_total);
1190
1191         REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
1192                         OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
1193 }
1194
1195 static void tgn10_clear_optc_underflow(struct timing_generator *tg)
1196 {
1197         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1198
1199         REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
1200 }
1201
1202 static void tgn10_tg_init(struct timing_generator *tg)
1203 {
1204         tgn10_set_blank_data_double_buffer(tg, true);
1205         tgn10_clear_optc_underflow(tg);
1206 }
1207
1208 static bool tgn10_is_tg_enabled(struct timing_generator *tg)
1209 {
1210         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1211         uint32_t otg_enabled = 0;
1212
1213         REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled);
1214
1215         return (otg_enabled != 0);
1216
1217 }
1218
1219 static bool tgn10_is_optc_underflow_occurred(struct timing_generator *tg)
1220 {
1221         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1222         uint32_t underflow_occurred = 0;
1223
1224         REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
1225                         OPTC_UNDERFLOW_OCCURRED_STATUS,
1226                         &underflow_occurred);
1227
1228         return (underflow_occurred == 1);
1229 }
1230
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,
1252                 .lock = tgn10_lock,
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,
1265 };
1266
1267 void dcn10_timing_generator_init(struct dcn10_timing_generator *tgn10)
1268 {
1269         tgn10->base.funcs = &dcn10_tg_funcs;
1270
1271         tgn10->max_h_total = tgn10->tg_mask->OTG_H_TOTAL + 1;
1272         tgn10->max_v_total = tgn10->tg_mask->OTG_V_TOTAL + 1;
1273
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;
1279 }