drm/amd/display: Enable double buffer as per vertical interrupt enabled.
[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
29 #define REG(reg)\
30         tgn10->tg_regs->reg
31
32 #define CTX \
33         tgn10->base.ctx
34
35 #undef FN
36 #define FN(reg_name, field_name) \
37         tgn10->tg_shift->field_name, tgn10->tg_mask->field_name
38
39 #define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100
40
41 /**
42 * apply_front_porch_workaround  TODO FPGA still need?
43 *
44 * This is a workaround for a bug that has existed since R5xx and has not been
45 * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
46 */
47 static void tgn10_apply_front_porch_workaround(
48         struct timing_generator *tg,
49         struct dc_crtc_timing *timing)
50 {
51         if (timing->flags.INTERLACE == 1) {
52                 if (timing->v_front_porch < 2)
53                         timing->v_front_porch = 2;
54         } else {
55                 if (timing->v_front_porch < 1)
56                         timing->v_front_porch = 1;
57         }
58 }
59
60 static void tgn10_program_global_sync(
61                 struct timing_generator *tg)
62 {
63         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
64
65         if (tg->dlg_otg_param.vstartup_start == 0) {
66                 BREAK_TO_DEBUGGER();
67                 return;
68         }
69
70         REG_SET(OTG_VSTARTUP_PARAM, 0,
71                 VSTARTUP_START, tg->dlg_otg_param.vstartup_start);
72
73         REG_SET_2(OTG_VUPDATE_PARAM, 0,
74                         VUPDATE_OFFSET, tg->dlg_otg_param.vupdate_offset,
75                         VUPDATE_WIDTH, tg->dlg_otg_param.vupdate_width);
76
77         REG_SET(OTG_VREADY_PARAM, 0,
78                         VREADY_OFFSET, tg->dlg_otg_param.vready_offset);
79 }
80
81 static void tgn10_disable_stereo(struct timing_generator *tg)
82 {
83         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
84
85         REG_SET(OTG_STEREO_CONTROL, 0,
86                 OTG_STEREO_EN, 0);
87
88         REG_SET_3(OTG_3D_STRUCTURE_CONTROL, 0,
89                 OTG_3D_STRUCTURE_EN, 0,
90                 OTG_3D_STRUCTURE_V_UPDATE_MODE, 0,
91                 OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
92
93         REG_UPDATE(OPPBUF_CONTROL,
94                 OPPBUF_ACTIVE_WIDTH, 0);
95         REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
96                 OPPBUF_3D_VACT_SPACE1_SIZE, 0);
97 }
98
99 /**
100  * program_timing_generator   used by mode timing set
101  * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition.
102  * Including SYNC. Call BIOS command table to program Timings.
103  */
104 static void tgn10_program_timing(
105         struct timing_generator *tg,
106         const struct dc_crtc_timing *dc_crtc_timing,
107         bool use_vbios)
108 {
109         struct dc_crtc_timing patched_crtc_timing;
110         uint32_t vesa_sync_start;
111         uint32_t asic_blank_end;
112         uint32_t asic_blank_start;
113         uint32_t v_total;
114         uint32_t v_sync_end;
115         uint32_t v_init, v_fp2;
116         uint32_t h_sync_polarity, v_sync_polarity;
117         uint32_t interlace_factor;
118         uint32_t start_point = 0;
119         uint32_t field_num = 0;
120         uint32_t h_div_2;
121         int32_t vertical_line_start;
122
123         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
124
125         patched_crtc_timing = *dc_crtc_timing;
126         tgn10_apply_front_porch_workaround(tg, &patched_crtc_timing);
127
128         /* Load horizontal timing */
129
130         /* CRTC_H_TOTAL = vesa.h_total - 1 */
131         REG_SET(OTG_H_TOTAL, 0,
132                         OTG_H_TOTAL,  patched_crtc_timing.h_total - 1);
133
134         /* h_sync_start = 0, h_sync_end = vesa.h_sync_width */
135         REG_UPDATE_2(OTG_H_SYNC_A,
136                         OTG_H_SYNC_A_START, 0,
137                         OTG_H_SYNC_A_END, patched_crtc_timing.h_sync_width);
138
139         /* asic_h_blank_end = HsyncWidth + HbackPorch =
140          * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart -
141          * vesa.h_left_border
142          */
143         vesa_sync_start = patched_crtc_timing.h_addressable +
144                         patched_crtc_timing.h_border_right +
145                         patched_crtc_timing.h_front_porch;
146
147         asic_blank_end = patched_crtc_timing.h_total -
148                         vesa_sync_start -
149                         patched_crtc_timing.h_border_left;
150
151         /* h_blank_start = v_blank_end + v_active */
152         asic_blank_start = asic_blank_end +
153                         patched_crtc_timing.h_border_left +
154                         patched_crtc_timing.h_addressable +
155                         patched_crtc_timing.h_border_right;
156
157         REG_UPDATE_2(OTG_H_BLANK_START_END,
158                         OTG_H_BLANK_START, asic_blank_start,
159                         OTG_H_BLANK_END, asic_blank_end);
160
161         /* h_sync polarity */
162         h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ?
163                         0 : 1;
164
165         REG_UPDATE(OTG_H_SYNC_A_CNTL,
166                         OTG_H_SYNC_A_POL, h_sync_polarity);
167
168         /* Load vertical timing */
169
170         /* CRTC_V_TOTAL = v_total - 1 */
171         if (patched_crtc_timing.flags.INTERLACE) {
172                 interlace_factor = 2;
173                 v_total = 2 * patched_crtc_timing.v_total;
174         } else {
175                 interlace_factor = 1;
176                 v_total = patched_crtc_timing.v_total - 1;
177         }
178         REG_SET(OTG_V_TOTAL, 0,
179                         OTG_V_TOTAL, v_total);
180
181         /* In case of V_TOTAL_CONTROL is on, make sure OTG_V_TOTAL_MAX and
182          * OTG_V_TOTAL_MIN are equal to V_TOTAL.
183          */
184         REG_SET(OTG_V_TOTAL_MAX, 0,
185                 OTG_V_TOTAL_MAX, v_total);
186         REG_SET(OTG_V_TOTAL_MIN, 0,
187                 OTG_V_TOTAL_MIN, v_total);
188
189         /* v_sync_start = 0, v_sync_end = v_sync_width */
190         v_sync_end = patched_crtc_timing.v_sync_width * interlace_factor;
191
192         REG_UPDATE_2(OTG_V_SYNC_A,
193                         OTG_V_SYNC_A_START, 0,
194                         OTG_V_SYNC_A_END, v_sync_end);
195
196         vesa_sync_start = patched_crtc_timing.v_addressable +
197                         patched_crtc_timing.v_border_bottom +
198                         patched_crtc_timing.v_front_porch;
199
200         asic_blank_end = (patched_crtc_timing.v_total -
201                         vesa_sync_start -
202                         patched_crtc_timing.v_border_top)
203                         * interlace_factor;
204
205         /* v_blank_start = v_blank_end + v_active */
206         asic_blank_start = asic_blank_end +
207                         (patched_crtc_timing.v_border_top +
208                         patched_crtc_timing.v_addressable +
209                         patched_crtc_timing.v_border_bottom)
210                         * interlace_factor;
211
212         REG_UPDATE_2(OTG_V_BLANK_START_END,
213                         OTG_V_BLANK_START, asic_blank_start,
214                         OTG_V_BLANK_END, asic_blank_end);
215
216         /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
217          * program the reg for interrupt postition.
218          */
219         vertical_line_start = asic_blank_end - tg->dlg_otg_param.vstartup_start + 1;
220         if (vertical_line_start < 0) {
221                 ASSERT(0);
222                 vertical_line_start = 0;
223         }
224         REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
225                         OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start);
226
227         /* v_sync polarity */
228         v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ?
229                         0 : 1;
230
231         REG_UPDATE(OTG_V_SYNC_A_CNTL,
232                         OTG_V_SYNC_A_POL, v_sync_polarity);
233
234         v_init = asic_blank_start;
235         if (tg->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT ||
236                 tg->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
237                 tg->dlg_otg_param.signal == SIGNAL_TYPE_EDP) {
238                 v_init = asic_blank_start;
239                 start_point = 1;
240                 if (patched_crtc_timing.flags.INTERLACE == 1)
241                         field_num = 1;
242         }
243         if (v_init < 0)
244                 v_init = 0;
245         v_fp2 = 0;
246         if (tg->dlg_otg_param.vstartup_start > asic_blank_end)
247                 v_fp2 = tg->dlg_otg_param.vstartup_start > asic_blank_end;
248
249         /* Interlace */
250         if (patched_crtc_timing.flags.INTERLACE == 1) {
251                 REG_UPDATE(OTG_INTERLACE_CONTROL,
252                                 OTG_INTERLACE_ENABLE, 1);
253                 v_init = v_init / 2;
254                 if ((tg->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end)
255                         v_fp2 = v_fp2 / 2;
256         }
257         else
258                 REG_UPDATE(OTG_INTERLACE_CONTROL,
259                                 OTG_INTERLACE_ENABLE, 0);
260
261
262         /* VTG enable set to 0 first VInit */
263         REG_UPDATE(CONTROL,
264                         VTG0_ENABLE, 0);
265
266         REG_UPDATE_2(CONTROL,
267                         VTG0_FP2, v_fp2,
268                         VTG0_VCOUNT_INIT, v_init);
269
270         /* original code is using VTG offset to address OTG reg, seems wrong */
271         REG_UPDATE_2(OTG_CONTROL,
272                         OTG_START_POINT_CNTL, start_point,
273                         OTG_FIELD_NUMBER_CNTL, field_num);
274
275         tgn10_program_global_sync(tg);
276
277         /* TODO
278          * patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1
279          * program_horz_count_by_2
280          * for DVI 30bpp mode, 0 otherwise
281          * program_horz_count_by_2(tg, &patched_crtc_timing);
282          */
283
284         /* Enable stereo - only when we need to pack 3D frame. Other types
285          * of stereo handled in explicit call
286          */
287         h_div_2 = (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ?
288                         1 : 0;
289
290         REG_UPDATE(OTG_H_TIMING_CNTL,
291                         OTG_H_TIMING_DIV_BY2, h_div_2);
292
293 }
294
295 /**
296  * unblank_crtc
297  * Call ASIC Control Object to UnBlank CRTC.
298  */
299 static void tgn10_unblank_crtc(struct timing_generator *tg)
300 {
301         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
302         uint32_t vertical_interrupt_enable = 0;
303
304         REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
305                         OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
306
307         /* temporary work around for vertical interrupt, once vertical interrupt enabled,
308          * this check will be removed.
309          */
310         if (vertical_interrupt_enable)
311                 REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
312                                 OTG_BLANK_DATA_DOUBLE_BUFFER_EN, 1);
313
314         REG_UPDATE_2(OTG_BLANK_CONTROL,
315                         OTG_BLANK_DATA_EN, 0,
316                         OTG_BLANK_DE_MODE, 0);
317 }
318
319 /**
320  * blank_crtc
321  * Call ASIC Control Object to Blank CRTC.
322  */
323
324 static void tgn10_blank_crtc(struct timing_generator *tg)
325 {
326         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
327
328         REG_UPDATE_2(OTG_BLANK_CONTROL,
329                         OTG_BLANK_DATA_EN, 1,
330                         OTG_BLANK_DE_MODE, 0);
331
332         /* todo: why are we waiting for BLANK_DATA_EN?  shouldn't we be waiting
333          * for status?
334          */
335         REG_WAIT(OTG_BLANK_CONTROL,
336                         OTG_BLANK_DATA_EN, 1,
337                         1, 100000);
338
339         REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
340                         OTG_BLANK_DATA_DOUBLE_BUFFER_EN, 0);
341 }
342
343 static void tgn10_set_blank(struct timing_generator *tg,
344                 bool enable_blanking)
345 {
346         if (enable_blanking)
347                 tgn10_blank_crtc(tg);
348         else
349                 tgn10_unblank_crtc(tg);
350 }
351
352 static bool tgn10_is_blanked(struct timing_generator *tg)
353 {
354         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
355         uint32_t blank_en;
356         uint32_t blank_state;
357
358         REG_GET_2(OTG_BLANK_CONTROL,
359                         OTG_BLANK_DATA_EN, &blank_en,
360                         OTG_CURRENT_BLANK_STATE, &blank_state);
361
362         return blank_en && blank_state;
363 }
364
365 static void tgn10_enable_optc_clock(struct timing_generator *tg, bool enable)
366 {
367         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
368
369         if (enable) {
370                 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
371                                 OPTC_INPUT_CLK_EN, 1,
372                                 OPTC_INPUT_CLK_GATE_DIS, 1);
373
374                 REG_WAIT(OPTC_INPUT_CLOCK_CONTROL,
375                                 OPTC_INPUT_CLK_ON, 1,
376                                 1, 1000);
377
378                 /* Enable clock */
379                 REG_UPDATE_2(OTG_CLOCK_CONTROL,
380                                 OTG_CLOCK_EN, 1,
381                                 OTG_CLOCK_GATE_DIS, 1);
382                 REG_WAIT(OTG_CLOCK_CONTROL,
383                                 OTG_CLOCK_ON, 1,
384                                 1, 1000);
385         } else  {
386                 REG_UPDATE_2(OTG_CLOCK_CONTROL,
387                                 OTG_CLOCK_GATE_DIS, 0,
388                                 OTG_CLOCK_EN, 0);
389
390                 if (tg->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
391                         REG_WAIT(OTG_CLOCK_CONTROL,
392                                         OTG_CLOCK_ON, 0,
393                                         1, 1000);
394
395                 REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL,
396                                 OPTC_INPUT_CLK_GATE_DIS, 0,
397                                 OPTC_INPUT_CLK_EN, 0);
398
399                 if (tg->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
400                         REG_WAIT(OPTC_INPUT_CLOCK_CONTROL,
401                                         OPTC_INPUT_CLK_ON, 0,
402                                         1, 1000);
403         }
404 }
405
406 /**
407  * Enable CRTC
408  * Enable CRTC - call ASIC Control Object to enable Timing generator.
409  */
410 static bool tgn10_enable_crtc(struct timing_generator *tg)
411 {
412         /* TODO FPGA wait for answer
413          * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE
414          * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK
415          */
416         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
417
418         /* opp instance for OTG. For DCN1.0, ODM is remoed.
419          * OPP and OPTC should 1:1 mapping
420          */
421         REG_UPDATE(OPTC_DATA_SOURCE_SELECT,
422                         OPTC_SRC_SEL, tg->inst);
423
424         /* VTG enable first is for HW workaround */
425         REG_UPDATE(CONTROL,
426                         VTG0_ENABLE, 1);
427
428         /* Enable CRTC */
429         REG_UPDATE_2(OTG_CONTROL,
430                         OTG_DISABLE_POINT_CNTL, 3,
431                         OTG_MASTER_EN, 1);
432
433         return true;
434 }
435
436 /* disable_crtc - call ASIC Control Object to disable Timing generator. */
437 static bool tgn10_disable_crtc(struct timing_generator *tg)
438 {
439         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
440
441         /* disable otg request until end of the first line
442          * in the vertical blank region
443          */
444         REG_UPDATE_2(OTG_CONTROL,
445                         OTG_DISABLE_POINT_CNTL, 3,
446                         OTG_MASTER_EN, 0);
447
448         REG_UPDATE(CONTROL,
449                         VTG0_ENABLE, 0);
450
451         /* CRTC disabled, so disable  clock. */
452         REG_WAIT(OTG_CLOCK_CONTROL,
453                         OTG_BUSY, 0,
454                         1, 100000);
455
456         return true;
457 }
458
459
460 static void tgn10_program_blank_color(
461                 struct timing_generator *tg,
462                 const struct tg_color *black_color)
463 {
464         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
465
466         REG_SET_3(OTG_BLACK_COLOR, 0,
467                         OTG_BLACK_COLOR_B_CB, black_color->color_b_cb,
468                         OTG_BLACK_COLOR_G_Y, black_color->color_g_y,
469                         OTG_BLACK_COLOR_R_CR, black_color->color_r_cr);
470 }
471
472 static bool tgn10_validate_timing(
473         struct timing_generator *tg,
474         const struct dc_crtc_timing *timing)
475 {
476         uint32_t interlace_factor;
477         uint32_t v_blank;
478         uint32_t h_blank;
479         uint32_t min_v_blank;
480         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
481
482         ASSERT(timing != NULL);
483
484         interlace_factor = timing->flags.INTERLACE ? 2 : 1;
485         v_blank = (timing->v_total - timing->v_addressable -
486                                         timing->v_border_top - timing->v_border_bottom) *
487                                         interlace_factor;
488
489         h_blank = (timing->h_total - timing->h_addressable -
490                 timing->h_border_right -
491                 timing->h_border_left);
492
493         if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
494                 timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING &&
495                 timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM &&
496                 timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE &&
497                 timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE &&
498                 timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
499                 return false;
500
501         /* Temporarily blocking interlacing mode until it's supported */
502         if (timing->flags.INTERLACE == 1)
503                 return false;
504
505         /* Check maximum number of pixels supported by Timing Generator
506          * (Currently will never fail, in order to fail needs display which
507          * needs more than 8192 horizontal and
508          * more than 8192 vertical total pixels)
509          */
510         if (timing->h_total > tgn10->max_h_total ||
511                 timing->v_total > tgn10->max_v_total)
512                 return false;
513
514
515         if (h_blank < tgn10->min_h_blank)
516                 return false;
517
518         if (timing->h_sync_width  < tgn10->min_h_sync_width ||
519                  timing->v_sync_width  < tgn10->min_v_sync_width)
520                 return false;
521
522         min_v_blank = timing->flags.INTERLACE?tgn10->min_v_blank_interlace:tgn10->min_v_blank;
523
524         if (v_blank < min_v_blank)
525                 return false;
526
527         return true;
528
529 }
530
531 /*
532  * get_vblank_counter
533  *
534  * @brief
535  * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
536  * holds the counter of frames.
537  *
538  * @param
539  * struct timing_generator *tg - [in] timing generator which controls the
540  * desired CRTC
541  *
542  * @return
543  * Counter of frames, which should equal to number of vblanks.
544  */
545 static uint32_t tgn10_get_vblank_counter(struct timing_generator *tg)
546 {
547         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
548         uint32_t frame_count;
549
550         REG_GET(OTG_STATUS_FRAME_COUNT,
551                 OTG_FRAME_COUNT, &frame_count);
552
553         return frame_count;
554 }
555
556 static void tgn10_lock(struct timing_generator *tg)
557 {
558         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
559
560         REG_SET(OTG_GLOBAL_CONTROL0, 0,
561                         OTG_MASTER_UPDATE_LOCK_SEL, tg->inst);
562         REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
563                         OTG_MASTER_UPDATE_LOCK, 1);
564
565         if (tg->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
566                 REG_WAIT(OTG_MASTER_UPDATE_LOCK,
567                                 UPDATE_LOCK_STATUS, 1,
568                                 1, 100);
569 }
570
571 static void tgn10_unlock(struct timing_generator *tg)
572 {
573         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
574
575         REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
576                         OTG_MASTER_UPDATE_LOCK, 0);
577
578         /* why are we waiting here? */
579         REG_WAIT(OTG_DOUBLE_BUFFER_CONTROL,
580                         OTG_UPDATE_PENDING, 0,
581                         1, 100000);
582 }
583
584 static void tgn10_get_position(struct timing_generator *tg,
585                 struct crtc_position *position)
586 {
587         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
588
589         REG_GET_2(OTG_STATUS_POSITION,
590                         OTG_HORZ_COUNT, &position->horizontal_count,
591                         OTG_VERT_COUNT, &position->vertical_count);
592
593         REG_GET(OTG_NOM_VERT_POSITION,
594                         OTG_VERT_COUNT_NOM, &position->nominal_vcount);
595 }
596
597 static bool tgn10_is_counter_moving(struct timing_generator *tg)
598 {
599         struct crtc_position position1, position2;
600
601         tg->funcs->get_position(tg, &position1);
602         tg->funcs->get_position(tg, &position2);
603
604         if (position1.horizontal_count == position2.horizontal_count &&
605                 position1.vertical_count == position2.vertical_count)
606                 return false;
607         else
608                 return true;
609 }
610
611 static bool tgn10_did_triggered_reset_occur(
612         struct timing_generator *tg)
613 {
614         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
615         uint32_t occurred;
616
617         REG_GET(OTG_FORCE_COUNT_NOW_CNTL,
618                 OTG_FORCE_COUNT_NOW_OCCURRED, &occurred);
619
620         return occurred != 0;
621 }
622
623 static void tgn10_enable_reset_trigger(struct timing_generator *tg, int source_tg_inst)
624 {
625         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
626         uint32_t falling_edge;
627
628         REG_GET(OTG_V_SYNC_A_CNTL,
629                         OTG_V_SYNC_A_POL, &falling_edge);
630
631         if (falling_edge)
632                 REG_SET_3(OTG_TRIGA_CNTL, 0,
633                                 /* vsync signal from selected OTG pipe based
634                                  * on OTG_TRIG_SOURCE_PIPE_SELECT setting
635                                  */
636                                 OTG_TRIGA_SOURCE_SELECT, 20,
637                                 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
638                                 /* always detect falling edge */
639                                 OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 1);
640         else
641                 REG_SET_3(OTG_TRIGA_CNTL, 0,
642                                 /* vsync signal from selected OTG pipe based
643                                  * on OTG_TRIG_SOURCE_PIPE_SELECT setting
644                                  */
645                                 OTG_TRIGA_SOURCE_SELECT, 20,
646                                 OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst,
647                                 /* always detect rising edge */
648                                 OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1);
649
650         REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
651                         /* force H count to H_TOTAL and V count to V_TOTAL in
652                          * progressive mode and V_TOTAL-1 in interlaced mode
653                          */
654                         OTG_FORCE_COUNT_NOW_MODE, 2);
655 }
656
657 static void tgn10_disable_reset_trigger(struct timing_generator *tg)
658 {
659         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
660
661         REG_WRITE(OTG_TRIGA_CNTL, 0);
662
663         REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0,
664                         OTG_FORCE_COUNT_NOW_CLEAR, 1);
665 }
666
667 static void tgn10_wait_for_state(struct timing_generator *tg,
668                 enum crtc_state state)
669 {
670         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
671
672         switch (state) {
673         case CRTC_STATE_VBLANK:
674                 REG_WAIT(OTG_STATUS,
675                                 OTG_V_BLANK, 1,
676                                 1, 100000); /* 1 vupdate at 10hz */
677                 break;
678
679         case CRTC_STATE_VACTIVE:
680                 REG_WAIT(OTG_STATUS,
681                                 OTG_V_ACTIVE_DISP, 1,
682                                 1, 100000); /* 1 vupdate at 10hz */
683                 break;
684
685         default:
686                 break;
687         }
688 }
689
690 static void tgn10_set_early_control(
691         struct timing_generator *tg,
692         uint32_t early_cntl)
693 {
694         /* asic design change, do not need this control
695          * empty for share caller logic
696          */
697 }
698
699
700 static void tgn10_set_static_screen_control(
701         struct timing_generator *tg,
702         uint32_t value)
703 {
704         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
705
706         /* Bit 8 is no longer applicable in RV for PSR case,
707          * set bit 8 to 0 if given
708          */
709         if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
710                         != 0)
711                 value = value &
712                 ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN;
713
714         REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0,
715                         OTG_STATIC_SCREEN_EVENT_MASK, value,
716                         OTG_STATIC_SCREEN_FRAME_COUNT, 2);
717 }
718
719
720 /**
721  *****************************************************************************
722  *  Function: set_drr
723  *
724  *  @brief
725  *     Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*.
726  *
727  *****************************************************************************
728  */
729 static void tgn10_set_drr(
730         struct timing_generator *tg,
731         const struct drr_params *params)
732 {
733         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
734
735         if (params != NULL &&
736                 params->vertical_total_max > 0 &&
737                 params->vertical_total_min > 0) {
738
739                 REG_SET(OTG_V_TOTAL_MAX, 0,
740                         OTG_V_TOTAL_MAX, params->vertical_total_max - 1);
741
742                 REG_SET(OTG_V_TOTAL_MIN, 0,
743                         OTG_V_TOTAL_MIN, params->vertical_total_min - 1);
744
745                 REG_UPDATE_5(OTG_V_TOTAL_CONTROL,
746                                 OTG_V_TOTAL_MIN_SEL, 1,
747                                 OTG_V_TOTAL_MAX_SEL, 1,
748                                 OTG_FORCE_LOCK_ON_EVENT, 0,
749                                 OTG_SET_V_TOTAL_MIN_MASK_EN, 0,
750                                 OTG_SET_V_TOTAL_MIN_MASK, 0);
751         } else {
752                 REG_SET(OTG_V_TOTAL_MIN, 0,
753                         OTG_V_TOTAL_MIN, 0);
754
755                 REG_SET(OTG_V_TOTAL_MAX, 0,
756                         OTG_V_TOTAL_MAX, 0);
757
758                 REG_UPDATE_4(OTG_V_TOTAL_CONTROL,
759                                 OTG_SET_V_TOTAL_MIN_MASK, 0,
760                                 OTG_V_TOTAL_MIN_SEL, 0,
761                                 OTG_V_TOTAL_MAX_SEL, 0,
762                                 OTG_FORCE_LOCK_ON_EVENT, 0);
763         }
764 }
765
766 static void tgn10_set_test_pattern(
767         struct timing_generator *tg,
768         /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
769          * because this is not DP-specific (which is probably somewhere in DP
770          * encoder) */
771         enum controller_dp_test_pattern test_pattern,
772         enum dc_color_depth color_depth)
773 {
774         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
775         enum test_pattern_color_format bit_depth;
776         enum test_pattern_dyn_range dyn_range;
777         enum test_pattern_mode mode;
778         uint32_t pattern_mask;
779         uint32_t pattern_data;
780         /* color ramp generator mixes 16-bits color */
781         uint32_t src_bpc = 16;
782         /* requested bpc */
783         uint32_t dst_bpc;
784         uint32_t index;
785         /* RGB values of the color bars.
786          * Produce two RGB colors: RGB0 - white (all Fs)
787          * and RGB1 - black (all 0s)
788          * (three RGB components for two colors)
789          */
790         uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
791                                                 0x0000, 0x0000};
792         /* dest color (converted to the specified color format) */
793         uint16_t dst_color[6];
794         uint32_t inc_base;
795
796         /* translate to bit depth */
797         switch (color_depth) {
798         case COLOR_DEPTH_666:
799                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
800         break;
801         case COLOR_DEPTH_888:
802                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
803         break;
804         case COLOR_DEPTH_101010:
805                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
806         break;
807         case COLOR_DEPTH_121212:
808                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
809         break;
810         default:
811                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
812         break;
813         }
814
815         switch (test_pattern) {
816         case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
817         case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
818         {
819                 dyn_range = (test_pattern ==
820                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
821                                 TEST_PATTERN_DYN_RANGE_CEA :
822                                 TEST_PATTERN_DYN_RANGE_VESA);
823                 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
824
825                 REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS,
826                                 OTG_TEST_PATTERN_VRES, 6,
827                                 OTG_TEST_PATTERN_HRES, 6);
828
829                 REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
830                                 OTG_TEST_PATTERN_EN, 1,
831                                 OTG_TEST_PATTERN_MODE, mode,
832                                 OTG_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
833                                 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
834         }
835         break;
836
837         case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
838         case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
839         {
840                 mode = (test_pattern ==
841                         CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
842                         TEST_PATTERN_MODE_VERTICALBARS :
843                         TEST_PATTERN_MODE_HORIZONTALBARS);
844
845                 switch (bit_depth) {
846                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
847                         dst_bpc = 6;
848                 break;
849                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
850                         dst_bpc = 8;
851                 break;
852                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
853                         dst_bpc = 10;
854                 break;
855                 default:
856                         dst_bpc = 8;
857                 break;
858                 }
859
860                 /* adjust color to the required colorFormat */
861                 for (index = 0; index < 6; index++) {
862                         /* dst = 2^dstBpc * src / 2^srcBpc = src >>
863                          * (srcBpc - dstBpc);
864                          */
865                         dst_color[index] =
866                                 src_color[index] >> (src_bpc - dst_bpc);
867                 /* CRTC_TEST_PATTERN_DATA has 16 bits,
868                  * lowest 6 are hardwired to ZERO
869                  * color bits should be left aligned aligned to MSB
870                  * XXXXXXXXXX000000 for 10 bit,
871                  * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
872                  */
873                         dst_color[index] <<= (16 - dst_bpc);
874                 }
875
876                 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
877
878                 /* We have to write the mask before data, similar to pipeline.
879                  * For example, for 8 bpc, if we want RGB0 to be magenta,
880                  * and RGB1 to be cyan,
881                  * we need to make 7 writes:
882                  * MASK   DATA
883                  * 000001 00000000 00000000                     set mask to R0
884                  * 000010 11111111 00000000     R0 255, 0xFF00, set mask to G0
885                  * 000100 00000000 00000000     G0 0,   0x0000, set mask to B0
886                  * 001000 11111111 00000000     B0 255, 0xFF00, set mask to R1
887                  * 010000 00000000 00000000     R1 0,   0x0000, set mask to G1
888                  * 100000 11111111 00000000     G1 255, 0xFF00, set mask to B1
889                  * 100000 11111111 00000000     B1 255, 0xFF00
890                  *
891                  * we will make a loop of 6 in which we prepare the mask,
892                  * then write, then prepare the color for next write.
893                  * first iteration will write mask only,
894                  * but each next iteration color prepared in
895                  * previous iteration will be written within new mask,
896                  * the last component will written separately,
897                  * mask is not changing between 6th and 7th write
898                  * and color will be prepared by last iteration
899                  */
900
901                 /* write color, color values mask in CRTC_TEST_PATTERN_MASK
902                  * is B1, G1, R1, B0, G0, R0
903                  */
904                 pattern_data = 0;
905                 for (index = 0; index < 6; index++) {
906                         /* prepare color mask, first write PATTERN_DATA
907                          * will have all zeros
908                          */
909                         pattern_mask = (1 << index);
910
911                         /* write color component */
912                         REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
913                                         OTG_TEST_PATTERN_MASK, pattern_mask,
914                                         OTG_TEST_PATTERN_DATA, pattern_data);
915
916                         /* prepare next color component,
917                          * will be written in the next iteration
918                          */
919                         pattern_data = dst_color[index];
920                 }
921                 /* write last color component,
922                  * it's been already prepared in the loop
923                  */
924                 REG_SET_2(OTG_TEST_PATTERN_COLOR, 0,
925                                 OTG_TEST_PATTERN_MASK, pattern_mask,
926                                 OTG_TEST_PATTERN_DATA, pattern_data);
927
928                 /* enable test pattern */
929                 REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL,
930                                 OTG_TEST_PATTERN_EN, 1,
931                                 OTG_TEST_PATTERN_MODE, mode,
932                                 OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
933                                 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
934         }
935         break;
936
937         case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
938         {
939                 mode = (bit_depth ==
940                         TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
941                         TEST_PATTERN_MODE_DUALRAMP_RGB :
942                         TEST_PATTERN_MODE_SINGLERAMP_RGB);
943
944                 switch (bit_depth) {
945                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
946                         dst_bpc = 6;
947                 break;
948                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
949                         dst_bpc = 8;
950                 break;
951                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
952                         dst_bpc = 10;
953                 break;
954                 default:
955                         dst_bpc = 8;
956                 break;
957                 }
958
959                 /* increment for the first ramp for one color gradation
960                  * 1 gradation for 6-bit color is 2^10
961                  * gradations in 16-bit color
962                  */
963                 inc_base = (src_bpc - dst_bpc);
964
965                 switch (bit_depth) {
966                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
967                 {
968                         REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
969                                         OTG_TEST_PATTERN_INC0, inc_base,
970                                         OTG_TEST_PATTERN_INC1, 0,
971                                         OTG_TEST_PATTERN_HRES, 6,
972                                         OTG_TEST_PATTERN_VRES, 6,
973                                         OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
974                 }
975                 break;
976                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
977                 {
978                         REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
979                                         OTG_TEST_PATTERN_INC0, inc_base,
980                                         OTG_TEST_PATTERN_INC1, 0,
981                                         OTG_TEST_PATTERN_HRES, 8,
982                                         OTG_TEST_PATTERN_VRES, 6,
983                                         OTG_TEST_PATTERN_RAMP0_OFFSET, 0);
984                 }
985                 break;
986                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
987                 {
988                         REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS,
989                                         OTG_TEST_PATTERN_INC0, inc_base,
990                                         OTG_TEST_PATTERN_INC1, inc_base + 2,
991                                         OTG_TEST_PATTERN_HRES, 8,
992                                         OTG_TEST_PATTERN_VRES, 5,
993                                         OTG_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
994                 }
995                 break;
996                 default:
997                 break;
998                 }
999
1000                 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
1001
1002                 /* enable test pattern */
1003                 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
1004
1005                 REG_SET_4(OTG_TEST_PATTERN_CONTROL, 0,
1006                                 OTG_TEST_PATTERN_EN, 1,
1007                                 OTG_TEST_PATTERN_MODE, mode,
1008                                 OTG_TEST_PATTERN_DYNAMIC_RANGE, 0,
1009                                 OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth);
1010         }
1011         break;
1012         case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1013         {
1014                 REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0);
1015                 REG_WRITE(OTG_TEST_PATTERN_COLOR, 0);
1016                 REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0);
1017         }
1018         break;
1019         default:
1020                 break;
1021
1022         }
1023 }
1024
1025 static void tgn10_get_crtc_scanoutpos(
1026         struct timing_generator *tg,
1027         uint32_t *v_blank_start,
1028         uint32_t *v_blank_end,
1029         uint32_t *h_position,
1030         uint32_t *v_position)
1031 {
1032         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1033         struct crtc_position position;
1034
1035         REG_GET_2(OTG_V_BLANK_START_END,
1036                         OTG_V_BLANK_START, v_blank_start,
1037                         OTG_V_BLANK_END, v_blank_end);
1038
1039         tgn10_get_position(tg, &position);
1040
1041         *h_position = position.horizontal_count;
1042         *v_position = position.vertical_count;
1043 }
1044
1045
1046
1047 static void tgn10_enable_stereo(struct timing_generator *tg,
1048         const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
1049 {
1050         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1051
1052         uint32_t active_width = timing->h_addressable;
1053         uint32_t space1_size = timing->v_total - timing->v_addressable;
1054
1055         if (flags) {
1056                 uint32_t stereo_en;
1057                 stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0;
1058
1059                 if (flags->PROGRAM_STEREO)
1060                         REG_UPDATE_3(OTG_STEREO_CONTROL,
1061                                 OTG_STEREO_EN, stereo_en,
1062                                 OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0,
1063                                 OTG_STEREO_SYNC_OUTPUT_POLARITY, 0);
1064
1065                 if (flags->PROGRAM_POLARITY)
1066                         REG_UPDATE(OTG_STEREO_CONTROL,
1067                                 OTG_STEREO_EYE_FLAG_POLARITY,
1068                                 flags->RIGHT_EYE_POLARITY == 0 ? 0 : 1);
1069
1070                 if (flags->DISABLE_STEREO_DP_SYNC)
1071                         REG_UPDATE(OTG_STEREO_CONTROL,
1072                                 OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1);
1073
1074                 if (flags->PROGRAM_STEREO)
1075                         REG_UPDATE_3(OTG_3D_STRUCTURE_CONTROL,
1076                                 OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED,
1077                                 OTG_3D_STRUCTURE_V_UPDATE_MODE, flags->FRAME_PACKED,
1078                                 OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED);
1079
1080         }
1081
1082         REG_UPDATE(OPPBUF_CONTROL,
1083                 OPPBUF_ACTIVE_WIDTH, active_width);
1084
1085         REG_UPDATE(OPPBUF_3D_PARAMETERS_0,
1086                 OPPBUF_3D_VACT_SPACE1_SIZE, space1_size);
1087 }
1088
1089 static void tgn10_program_stereo(struct timing_generator *tg,
1090         const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags)
1091 {
1092         if (flags->PROGRAM_STEREO)
1093                 tgn10_enable_stereo(tg, timing, flags);
1094         else
1095                 tgn10_disable_stereo(tg);
1096 }
1097
1098
1099 static bool tgn10_is_stereo_left_eye(struct timing_generator *tg)
1100 {
1101         bool ret = false;
1102         uint32_t left_eye = 0;
1103         struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
1104
1105         REG_GET(OTG_STEREO_STATUS,
1106                 OTG_STEREO_CURRENT_EYE, &left_eye);
1107         if (left_eye == 1)
1108                 ret = true;
1109         else
1110                 ret = false;
1111
1112         return ret;
1113 }
1114
1115 void tgn10_read_otg_state(struct dcn10_timing_generator *tgn10,
1116                 struct dcn_otg_state *s)
1117 {
1118         REG_GET(OTG_CONTROL,
1119                         OTG_MASTER_EN, &s->otg_enabled);
1120
1121         REG_GET_2(OTG_V_BLANK_START_END,
1122                         OTG_V_BLANK_START, &s->v_blank_start,
1123                         OTG_V_BLANK_END, &s->v_blank_end);
1124
1125         REG_GET(OTG_V_SYNC_A_CNTL,
1126                         OTG_V_SYNC_A_POL, &s->v_sync_a_pol);
1127
1128         REG_GET(OTG_V_TOTAL,
1129                         OTG_V_TOTAL, &s->v_total);
1130
1131         REG_GET(OTG_V_TOTAL_MAX,
1132                         OTG_V_TOTAL_MAX, &s->v_total_max);
1133
1134         REG_GET(OTG_V_TOTAL_MIN,
1135                         OTG_V_TOTAL_MIN, &s->v_total_min);
1136
1137         REG_GET_2(OTG_V_SYNC_A,
1138                         OTG_V_SYNC_A_START, &s->v_sync_a_start,
1139                         OTG_V_SYNC_A_END, &s->v_sync_a_end);
1140
1141         REG_GET_2(OTG_H_BLANK_START_END,
1142                         OTG_H_BLANK_START, &s->h_blank_start,
1143                         OTG_H_BLANK_END, &s->h_blank_end);
1144
1145         REG_GET_2(OTG_H_SYNC_A,
1146                         OTG_H_SYNC_A_START, &s->h_sync_a_start,
1147                         OTG_H_SYNC_A_END, &s->h_sync_a_end);
1148
1149         REG_GET(OTG_H_SYNC_A_CNTL,
1150                         OTG_H_SYNC_A_POL, &s->h_sync_a_pol);
1151
1152         REG_GET(OTG_H_TOTAL,
1153                         OTG_H_TOTAL, &s->h_total);
1154
1155         REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
1156                         OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status);
1157 }
1158
1159
1160 static const struct timing_generator_funcs dcn10_tg_funcs = {
1161                 .validate_timing = tgn10_validate_timing,
1162                 .program_timing = tgn10_program_timing,
1163                 .program_global_sync = tgn10_program_global_sync,
1164                 .enable_crtc = tgn10_enable_crtc,
1165                 .disable_crtc = tgn10_disable_crtc,
1166                 /* used by enable_timing_synchronization. Not need for FPGA */
1167                 .is_counter_moving = tgn10_is_counter_moving,
1168                 .get_position = tgn10_get_position,
1169                 .get_frame_count = tgn10_get_vblank_counter,
1170                 .get_scanoutpos = tgn10_get_crtc_scanoutpos,
1171                 .set_early_control = tgn10_set_early_control,
1172                 /* used by enable_timing_synchronization. Not need for FPGA */
1173                 .wait_for_state = tgn10_wait_for_state,
1174                 .set_blank = tgn10_set_blank,
1175                 .is_blanked = tgn10_is_blanked,
1176                 .set_blank_color = tgn10_program_blank_color,
1177                 .did_triggered_reset_occur = tgn10_did_triggered_reset_occur,
1178                 .enable_reset_trigger = tgn10_enable_reset_trigger,
1179                 .disable_reset_trigger = tgn10_disable_reset_trigger,
1180                 .lock = tgn10_lock,
1181                 .unlock = tgn10_unlock,
1182                 .enable_optc_clock = tgn10_enable_optc_clock,
1183                 .set_drr = tgn10_set_drr,
1184                 .set_static_screen_control = tgn10_set_static_screen_control,
1185                 .set_test_pattern = tgn10_set_test_pattern,
1186                 .program_stereo = tgn10_program_stereo,
1187                 .is_stereo_left_eye = tgn10_is_stereo_left_eye
1188 };
1189
1190 void dcn10_timing_generator_init(struct dcn10_timing_generator *tgn10)
1191 {
1192         tgn10->base.funcs = &dcn10_tg_funcs;
1193
1194         tgn10->max_h_total = tgn10->tg_mask->OTG_H_TOTAL + 1;
1195         tgn10->max_v_total = tgn10->tg_mask->OTG_V_TOTAL + 1;
1196
1197         tgn10->min_h_blank = 32;
1198         tgn10->min_v_blank = 3;
1199         tgn10->min_v_blank_interlace = 5;
1200         tgn10->min_h_sync_width = 8;
1201         tgn10->min_v_sync_width = 1;
1202 }