ASoC: mediatek: update MT2701 AFE documentation to adapt mfd device
[linux-2.6-block.git] / drivers / gpu / drm / amd / display / dc / dce110 / dce110_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 "dm_services.h"
27
28 /* include DCE11 register header files */
29 #include "dce/dce_11_0_d.h"
30 #include "dce/dce_11_0_sh_mask.h"
31
32 #include "dc_types.h"
33 #include "dc_bios_types.h"
34 #include "dc.h"
35
36 #include "include/grph_object_id.h"
37 #include "include/logger_interface.h"
38 #include "dce110_timing_generator.h"
39
40 #include "timing_generator.h"
41
42
43 #define NUMBER_OF_FRAME_TO_WAIT_ON_TRIGGERED_RESET 10
44
45 #define MAX_H_TOTAL (CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1)
46 #define MAX_V_TOTAL (CRTC_V_TOTAL__CRTC_V_TOTAL_MASKhw + 1)
47
48 #define CRTC_REG(reg) (reg + tg110->offsets.crtc)
49 #define DCP_REG(reg) (reg + tg110->offsets.dcp)
50
51 /* Flowing register offsets are same in files of
52  * dce/dce_11_0_d.h
53  * dce/vi_polaris10_p/vi_polaris10_d.h
54  *
55  * So we can create dce110 timing generator to use it.
56  */
57
58
59 /*
60 * apply_front_porch_workaround
61 *
62 * This is a workaround for a bug that has existed since R5xx and has not been
63 * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
64 */
65 static void dce110_timing_generator_apply_front_porch_workaround(
66         struct timing_generator *tg,
67         struct dc_crtc_timing *timing)
68 {
69         if (timing->flags.INTERLACE == 1) {
70                 if (timing->v_front_porch < 2)
71                         timing->v_front_porch = 2;
72         } else {
73                 if (timing->v_front_porch < 1)
74                         timing->v_front_porch = 1;
75         }
76 }
77
78 /**
79  *****************************************************************************
80  *  Function: is_in_vertical_blank
81  *
82  *  @brief
83  *     check the current status of CRTC to check if we are in Vertical Blank
84  *     regioneased" state
85  *
86  *  @return
87  *     true if currently in blank region, false otherwise
88  *
89  *****************************************************************************
90  */
91 static bool dce110_timing_generator_is_in_vertical_blank(
92                 struct timing_generator *tg)
93 {
94         uint32_t addr = 0;
95         uint32_t value = 0;
96         uint32_t field = 0;
97         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
98
99         addr = CRTC_REG(mmCRTC_STATUS);
100         value = dm_read_reg(tg->ctx, addr);
101         field = get_reg_field_value(value, CRTC_STATUS, CRTC_V_BLANK);
102         return field == 1;
103 }
104
105 void dce110_timing_generator_set_early_control(
106                 struct timing_generator *tg,
107                 uint32_t early_cntl)
108 {
109         uint32_t regval;
110         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
111         uint32_t address = CRTC_REG(mmCRTC_CONTROL);
112
113         regval = dm_read_reg(tg->ctx, address);
114         set_reg_field_value(regval, early_cntl,
115                         CRTC_CONTROL, CRTC_HBLANK_EARLY_CONTROL);
116         dm_write_reg(tg->ctx, address, regval);
117 }
118
119 /**
120  * Enable CRTC
121  * Enable CRTC - call ASIC Control Object to enable Timing generator.
122  */
123 bool dce110_timing_generator_enable_crtc(struct timing_generator *tg)
124 {
125         enum bp_result result;
126
127         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
128         uint32_t value = 0;
129
130         /*
131          * 3 is used to make sure V_UPDATE occurs at the beginning of the first
132          * line of vertical front porch
133          */
134         set_reg_field_value(
135                 value,
136                 0,
137                 CRTC_MASTER_UPDATE_MODE,
138                 MASTER_UPDATE_MODE);
139
140         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value);
141
142         /* TODO: may want this on to catch underflow */
143         value = 0;
144         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_LOCK), value);
145
146         result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, true);
147
148         return result == BP_RESULT_OK;
149 }
150
151 void dce110_timing_generator_program_blank_color(
152                 struct timing_generator *tg,
153                 const struct tg_color *black_color)
154 {
155         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
156         uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR);
157         uint32_t value = dm_read_reg(tg->ctx, addr);
158
159         set_reg_field_value(
160                 value,
161                 black_color->color_b_cb,
162                 CRTC_BLACK_COLOR,
163                 CRTC_BLACK_COLOR_B_CB);
164         set_reg_field_value(
165                 value,
166                 black_color->color_g_y,
167                 CRTC_BLACK_COLOR,
168                 CRTC_BLACK_COLOR_G_Y);
169         set_reg_field_value(
170                 value,
171                 black_color->color_r_cr,
172                 CRTC_BLACK_COLOR,
173                 CRTC_BLACK_COLOR_R_CR);
174
175         dm_write_reg(tg->ctx, addr, value);
176 }
177
178 /**
179  *****************************************************************************
180  *  Function: disable_stereo
181  *
182  *  @brief
183  *     Disables active stereo on controller
184  *     Frame Packing need to be disabled in vBlank or when CRTC not running
185  *****************************************************************************
186  */
187 #if 0
188 @TODOSTEREO
189 static void disable_stereo(struct timing_generator *tg)
190 {
191         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
192         uint32_t addr = CRTC_REG(mmCRTC_3D_STRUCTURE_CONTROL);
193         uint32_t value = 0;
194         uint32_t test = 0;
195         uint32_t field = 0;
196         uint32_t struc_en = 0;
197         uint32_t struc_stereo_sel_ovr = 0;
198
199         value = dm_read_reg(tg->ctx, addr);
200         struc_en = get_reg_field_value(
201                         value,
202                         CRTC_3D_STRUCTURE_CONTROL,
203                         CRTC_3D_STRUCTURE_EN);
204
205         struc_stereo_sel_ovr = get_reg_field_value(
206                         value,
207                         CRTC_3D_STRUCTURE_CONTROL,
208                         CRTC_3D_STRUCTURE_STEREO_SEL_OVR);
209
210         /*
211          * When disabling Frame Packing in 2 step mode, we need to program both
212          * registers at the same frame
213          * Programming it in the beginning of VActive makes sure we are ok
214          */
215
216         if (struc_en != 0 && struc_stereo_sel_ovr == 0) {
217                 tg->funcs->wait_for_vblank(tg);
218                 tg->funcs->wait_for_vactive(tg);
219         }
220
221         value = 0;
222         dm_write_reg(tg->ctx, addr, value);
223
224         addr = tg->regs[IDX_CRTC_STEREO_CONTROL];
225         dm_write_reg(tg->ctx, addr, value);
226 }
227 #endif
228
229 /**
230  * disable_crtc - call ASIC Control Object to disable Timing generator.
231  */
232 bool dce110_timing_generator_disable_crtc(struct timing_generator *tg)
233 {
234         enum bp_result result;
235
236         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
237
238         result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, false);
239
240         /* Need to make sure stereo is disabled according to the DCE5.0 spec */
241
242         /*
243          * @TODOSTEREO call this when adding stereo support
244          * tg->funcs->disable_stereo(tg);
245          */
246
247         return result == BP_RESULT_OK;
248 }
249
250 /**
251 * program_horz_count_by_2
252 * Programs DxCRTC_HORZ_COUNT_BY2_EN - 1 for DVI 30bpp mode, 0 otherwise
253 *
254 */
255 static void program_horz_count_by_2(
256         struct timing_generator *tg,
257         const struct dc_crtc_timing *timing)
258 {
259         uint32_t regval;
260         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
261
262         regval = dm_read_reg(tg->ctx,
263                         CRTC_REG(mmCRTC_COUNT_CONTROL));
264
265         set_reg_field_value(regval, 0, CRTC_COUNT_CONTROL,
266                         CRTC_HORZ_COUNT_BY2_EN);
267
268         if (timing->flags.HORZ_COUNT_BY_TWO)
269                 set_reg_field_value(regval, 1, CRTC_COUNT_CONTROL,
270                                         CRTC_HORZ_COUNT_BY2_EN);
271
272         dm_write_reg(tg->ctx,
273                         CRTC_REG(mmCRTC_COUNT_CONTROL), regval);
274 }
275
276 /**
277  * program_timing_generator
278  * Program CRTC Timing Registers - DxCRTC_H_*, DxCRTC_V_*, Pixel repetition.
279  * Call ASIC Control Object to program Timings.
280  */
281 bool dce110_timing_generator_program_timing_generator(
282         struct timing_generator *tg,
283         const struct dc_crtc_timing *dc_crtc_timing)
284 {
285         enum bp_result result;
286         struct bp_hw_crtc_timing_parameters bp_params;
287         struct dc_crtc_timing patched_crtc_timing;
288         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
289
290         uint32_t vsync_offset = dc_crtc_timing->v_border_bottom +
291                         dc_crtc_timing->v_front_porch;
292         uint32_t v_sync_start =dc_crtc_timing->v_addressable + vsync_offset;
293
294         uint32_t hsync_offset = dc_crtc_timing->h_border_right +
295                         dc_crtc_timing->h_front_porch;
296         uint32_t h_sync_start = dc_crtc_timing->h_addressable + hsync_offset;
297
298         memset(&bp_params, 0, sizeof(struct bp_hw_crtc_timing_parameters));
299
300         /* Due to an asic bug we need to apply the Front Porch workaround prior
301          * to programming the timing.
302          */
303
304         patched_crtc_timing = *dc_crtc_timing;
305
306         dce110_timing_generator_apply_front_porch_workaround(tg, &patched_crtc_timing);
307
308         bp_params.controller_id = tg110->controller_id;
309
310         bp_params.h_total = patched_crtc_timing.h_total;
311         bp_params.h_addressable =
312                 patched_crtc_timing.h_addressable;
313         bp_params.v_total = patched_crtc_timing.v_total;
314         bp_params.v_addressable = patched_crtc_timing.v_addressable;
315
316         bp_params.h_sync_start = h_sync_start;
317         bp_params.h_sync_width = patched_crtc_timing.h_sync_width;
318         bp_params.v_sync_start = v_sync_start;
319         bp_params.v_sync_width = patched_crtc_timing.v_sync_width;
320
321         /* Set overscan */
322         bp_params.h_overscan_left =
323                 patched_crtc_timing.h_border_left;
324         bp_params.h_overscan_right =
325                 patched_crtc_timing.h_border_right;
326         bp_params.v_overscan_top = patched_crtc_timing.v_border_top;
327         bp_params.v_overscan_bottom =
328                 patched_crtc_timing.v_border_bottom;
329
330         /* Set flags */
331         if (patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY == 1)
332                 bp_params.flags.HSYNC_POSITIVE_POLARITY = 1;
333
334         if (patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY == 1)
335                 bp_params.flags.VSYNC_POSITIVE_POLARITY = 1;
336
337         if (patched_crtc_timing.flags.INTERLACE == 1)
338                 bp_params.flags.INTERLACE = 1;
339
340         if (patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1)
341                 bp_params.flags.HORZ_COUNT_BY_TWO = 1;
342
343         result = tg->bp->funcs->program_crtc_timing(tg->bp, &bp_params);
344
345         program_horz_count_by_2(tg, &patched_crtc_timing);
346
347         tg110->base.funcs->enable_advanced_request(tg, true, &patched_crtc_timing);
348
349         /* Enable stereo - only when we need to pack 3D frame. Other types
350          * of stereo handled in explicit call */
351
352         return result == BP_RESULT_OK;
353 }
354
355 /**
356  *****************************************************************************
357  *  Function: set_drr
358  *
359  *  @brief
360  *     Program dynamic refresh rate registers m_DxCRTC_V_TOTAL_*.
361  *
362  *  @param [in] pHwCrtcTiming: point to H
363  *  wCrtcTiming struct
364  *****************************************************************************
365  */
366 void dce110_timing_generator_set_drr(
367         struct timing_generator *tg,
368         const struct drr_params *params)
369 {
370         /* register values */
371         uint32_t v_total_min = 0;
372         uint32_t v_total_max = 0;
373         uint32_t v_total_cntl = 0;
374         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
375
376         uint32_t addr = 0;
377
378         addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
379         v_total_min = dm_read_reg(tg->ctx, addr);
380
381         addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
382         v_total_max = dm_read_reg(tg->ctx, addr);
383
384         addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL);
385         v_total_cntl = dm_read_reg(tg->ctx, addr);
386
387         if (params != NULL &&
388                 params->vertical_total_max > 0 &&
389                 params->vertical_total_min > 0) {
390
391                 set_reg_field_value(v_total_max,
392                                 params->vertical_total_max - 1,
393                                 CRTC_V_TOTAL_MAX,
394                                 CRTC_V_TOTAL_MAX);
395
396                 set_reg_field_value(v_total_min,
397                                 params->vertical_total_min - 1,
398                                 CRTC_V_TOTAL_MIN,
399                                 CRTC_V_TOTAL_MIN);
400
401                 set_reg_field_value(v_total_cntl,
402                                 1,
403                                 CRTC_V_TOTAL_CONTROL,
404                                 CRTC_V_TOTAL_MIN_SEL);
405
406                 set_reg_field_value(v_total_cntl,
407                                 1,
408                                 CRTC_V_TOTAL_CONTROL,
409                                 CRTC_V_TOTAL_MAX_SEL);
410
411                 set_reg_field_value(v_total_cntl,
412                                 0,
413                                 CRTC_V_TOTAL_CONTROL,
414                                 CRTC_FORCE_LOCK_ON_EVENT);
415                 set_reg_field_value(v_total_cntl,
416                                 0,
417                                 CRTC_V_TOTAL_CONTROL,
418                                 CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
419
420                 set_reg_field_value(v_total_cntl,
421                                 0,
422                                 CRTC_V_TOTAL_CONTROL,
423                                 CRTC_SET_V_TOTAL_MIN_MASK_EN);
424
425                 set_reg_field_value(v_total_cntl,
426                                 0,
427                                 CRTC_V_TOTAL_CONTROL,
428                                 CRTC_SET_V_TOTAL_MIN_MASK);
429         } else {
430                 set_reg_field_value(v_total_cntl,
431                         0,
432                         CRTC_V_TOTAL_CONTROL,
433                         CRTC_SET_V_TOTAL_MIN_MASK);
434                 set_reg_field_value(v_total_min,
435                                 0,
436                                 CRTC_V_TOTAL_MIN,
437                                 CRTC_V_TOTAL_MIN);
438                 set_reg_field_value(v_total_max,
439                                 0,
440                                 CRTC_V_TOTAL_MAX,
441                                 CRTC_V_TOTAL_MAX);
442                 set_reg_field_value(v_total_cntl,
443                                 0,
444                                 CRTC_V_TOTAL_CONTROL,
445                                 CRTC_V_TOTAL_MIN_SEL);
446                 set_reg_field_value(v_total_cntl,
447                                 0,
448                                 CRTC_V_TOTAL_CONTROL,
449                                 CRTC_V_TOTAL_MAX_SEL);
450                 set_reg_field_value(v_total_cntl,
451                                 0,
452                                 CRTC_V_TOTAL_CONTROL,
453                                 CRTC_FORCE_LOCK_ON_EVENT);
454                 set_reg_field_value(v_total_cntl,
455                                 0,
456                                 CRTC_V_TOTAL_CONTROL,
457                                 CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
458         }
459
460         addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
461         dm_write_reg(tg->ctx, addr, v_total_min);
462
463         addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
464         dm_write_reg(tg->ctx, addr, v_total_max);
465
466         addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL);
467         dm_write_reg(tg->ctx, addr, v_total_cntl);
468 }
469
470 void dce110_timing_generator_set_static_screen_control(
471         struct timing_generator *tg,
472         uint32_t value)
473 {
474         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
475         uint32_t static_screen_cntl = 0;
476         uint32_t addr = 0;
477
478         addr = CRTC_REG(mmCRTC_STATIC_SCREEN_CONTROL);
479         static_screen_cntl = dm_read_reg(tg->ctx, addr);
480
481         set_reg_field_value(static_screen_cntl,
482                                 value,
483                                 CRTC_STATIC_SCREEN_CONTROL,
484                                 CRTC_STATIC_SCREEN_EVENT_MASK);
485
486         set_reg_field_value(static_screen_cntl,
487                                 2,
488                                 CRTC_STATIC_SCREEN_CONTROL,
489                                 CRTC_STATIC_SCREEN_FRAME_COUNT);
490
491         dm_write_reg(tg->ctx, addr, static_screen_cntl);
492 }
493
494 /*
495  * get_vblank_counter
496  *
497  * @brief
498  * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
499  * holds the counter of frames.
500  *
501  * @param
502  * struct timing_generator *tg - [in] timing generator which controls the
503  * desired CRTC
504  *
505  * @return
506  * Counter of frames, which should equal to number of vblanks.
507  */
508 uint32_t dce110_timing_generator_get_vblank_counter(struct timing_generator *tg)
509 {
510         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
511         uint32_t addr = CRTC_REG(mmCRTC_STATUS_FRAME_COUNT);
512         uint32_t value = dm_read_reg(tg->ctx, addr);
513         uint32_t field = get_reg_field_value(
514                         value, CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT);
515
516         return field;
517 }
518
519 /**
520  *****************************************************************************
521  *  Function: dce110_timing_generator_get_position
522  *
523  *  @brief
524  *     Returns CRTC vertical/horizontal counters
525  *
526  *  @param [out] position
527  *****************************************************************************
528  */
529 void dce110_timing_generator_get_position(struct timing_generator *tg,
530         struct crtc_position *position)
531 {
532         uint32_t value;
533         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
534
535         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_STATUS_POSITION));
536
537         position->horizontal_count = get_reg_field_value(
538                         value,
539                         CRTC_STATUS_POSITION,
540                         CRTC_HORZ_COUNT);
541
542         position->vertical_count = get_reg_field_value(
543                         value,
544                         CRTC_STATUS_POSITION,
545                         CRTC_VERT_COUNT);
546
547         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_NOM_VERT_POSITION));
548
549         position->nominal_vcount = get_reg_field_value(
550                         value,
551                         CRTC_NOM_VERT_POSITION,
552                         CRTC_VERT_COUNT_NOM);
553 }
554
555 /**
556  *****************************************************************************
557  *  Function: get_crtc_scanoutpos
558  *
559  *  @brief
560  *     Returns CRTC vertical/horizontal counters
561  *
562  *  @param [out] vpos, hpos
563  *****************************************************************************
564  */
565 void dce110_timing_generator_get_crtc_scanoutpos(
566         struct timing_generator *tg,
567         uint32_t *v_blank_start,
568         uint32_t *v_blank_end,
569         uint32_t *h_position,
570         uint32_t *v_position)
571 {
572         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
573         struct crtc_position position;
574
575         uint32_t value  = dm_read_reg(tg->ctx,
576                         CRTC_REG(mmCRTC_V_BLANK_START_END));
577
578         *v_blank_start = get_reg_field_value(value,
579                                              CRTC_V_BLANK_START_END,
580                                              CRTC_V_BLANK_START);
581         *v_blank_end = get_reg_field_value(value,
582                                            CRTC_V_BLANK_START_END,
583                                            CRTC_V_BLANK_END);
584
585         dce110_timing_generator_get_position(
586                         tg, &position);
587
588         *h_position = position.horizontal_count;
589         *v_position = position.vertical_count;
590 }
591
592 /* TODO: is it safe to assume that mask/shift of Primary and Underlay
593  * are the same?
594  * For example: today CRTC_H_TOTAL == CRTCV_H_TOTAL but is it always
595  * guaranteed? */
596 void dce110_timing_generator_program_blanking(
597         struct timing_generator *tg,
598         const struct dc_crtc_timing *timing)
599 {
600         uint32_t vsync_offset = timing->v_border_bottom +
601                         timing->v_front_porch;
602         uint32_t v_sync_start =timing->v_addressable + vsync_offset;
603
604         uint32_t hsync_offset = timing->h_border_right +
605                         timing->h_front_porch;
606         uint32_t h_sync_start = timing->h_addressable + hsync_offset;
607         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
608
609         struct dc_context *ctx = tg->ctx;
610         uint32_t value = 0;
611         uint32_t addr = 0;
612         uint32_t tmp = 0;
613
614         addr = CRTC_REG(mmCRTC_H_TOTAL);
615         value = dm_read_reg(ctx, addr);
616         set_reg_field_value(
617                 value,
618                 timing->h_total - 1,
619                 CRTC_H_TOTAL,
620                 CRTC_H_TOTAL);
621         dm_write_reg(ctx, addr, value);
622
623         addr = CRTC_REG(mmCRTC_V_TOTAL);
624         value = dm_read_reg(ctx, addr);
625         set_reg_field_value(
626                 value,
627                 timing->v_total - 1,
628                 CRTC_V_TOTAL,
629                 CRTC_V_TOTAL);
630         dm_write_reg(ctx, addr, value);
631
632         /* In case of V_TOTAL_CONTROL is on, make sure V_TOTAL_MAX and
633          * V_TOTAL_MIN are equal to V_TOTAL.
634          */
635         addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
636         value = dm_read_reg(ctx, addr);
637         set_reg_field_value(
638                 value,
639                 timing->v_total - 1,
640                 CRTC_V_TOTAL_MAX,
641                 CRTC_V_TOTAL_MAX);
642         dm_write_reg(ctx, addr, value);
643
644         addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
645         value = dm_read_reg(ctx, addr);
646         set_reg_field_value(
647                 value,
648                 timing->v_total - 1,
649                 CRTC_V_TOTAL_MIN,
650                 CRTC_V_TOTAL_MIN);
651         dm_write_reg(ctx, addr, value);
652
653         addr = CRTC_REG(mmCRTC_H_BLANK_START_END);
654         value = dm_read_reg(ctx, addr);
655
656         tmp = timing->h_total -
657                 (h_sync_start + timing->h_border_left);
658
659         set_reg_field_value(
660                 value,
661                 tmp,
662                 CRTC_H_BLANK_START_END,
663                 CRTC_H_BLANK_END);
664
665         tmp = tmp + timing->h_addressable +
666                 timing->h_border_left + timing->h_border_right;
667
668         set_reg_field_value(
669                 value,
670                 tmp,
671                 CRTC_H_BLANK_START_END,
672                 CRTC_H_BLANK_START);
673
674         dm_write_reg(ctx, addr, value);
675
676         addr = CRTC_REG(mmCRTC_V_BLANK_START_END);
677         value = dm_read_reg(ctx, addr);
678
679         tmp = timing->v_total - (v_sync_start + timing->v_border_top);
680
681         set_reg_field_value(
682                 value,
683                 tmp,
684                 CRTC_V_BLANK_START_END,
685                 CRTC_V_BLANK_END);
686
687         tmp = tmp + timing->v_addressable + timing->v_border_top +
688                 timing->v_border_bottom;
689
690         set_reg_field_value(
691                 value,
692                 tmp,
693                 CRTC_V_BLANK_START_END,
694                 CRTC_V_BLANK_START);
695
696         dm_write_reg(ctx, addr, value);
697 }
698
699 void dce110_timing_generator_set_test_pattern(
700         struct timing_generator *tg,
701         /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
702          * because this is not DP-specific (which is probably somewhere in DP
703          * encoder) */
704         enum controller_dp_test_pattern test_pattern,
705         enum dc_color_depth color_depth)
706 {
707         struct dc_context *ctx = tg->ctx;
708         uint32_t value;
709         uint32_t addr;
710         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
711         enum test_pattern_color_format bit_depth;
712         enum test_pattern_dyn_range dyn_range;
713         enum test_pattern_mode mode;
714         /* color ramp generator mixes 16-bits color */
715         uint32_t src_bpc = 16;
716         /* requested bpc */
717         uint32_t dst_bpc;
718         uint32_t index;
719         /* RGB values of the color bars.
720          * Produce two RGB colors: RGB0 - white (all Fs)
721          * and RGB1 - black (all 0s)
722          * (three RGB components for two colors)
723          */
724         uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
725                                                 0x0000, 0x0000};
726         /* dest color (converted to the specified color format) */
727         uint16_t dst_color[6];
728         uint32_t inc_base;
729
730         /* translate to bit depth */
731         switch (color_depth) {
732         case COLOR_DEPTH_666:
733                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
734         break;
735         case COLOR_DEPTH_888:
736                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
737         break;
738         case COLOR_DEPTH_101010:
739                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
740         break;
741         case COLOR_DEPTH_121212:
742                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
743         break;
744         default:
745                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
746         break;
747         }
748
749         switch (test_pattern) {
750         case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
751         case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
752         {
753                 dyn_range = (test_pattern ==
754                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
755                                 TEST_PATTERN_DYN_RANGE_CEA :
756                                 TEST_PATTERN_DYN_RANGE_VESA);
757                 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
758                 value = 0;
759                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
760
761                 set_reg_field_value(
762                         value,
763                         6,
764                         CRTC_TEST_PATTERN_PARAMETERS,
765                         CRTC_TEST_PATTERN_VRES);
766                 set_reg_field_value(
767                         value,
768                         6,
769                         CRTC_TEST_PATTERN_PARAMETERS,
770                         CRTC_TEST_PATTERN_HRES);
771
772                 dm_write_reg(ctx, addr, value);
773
774                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
775                 value = 0;
776
777                 set_reg_field_value(
778                         value,
779                         1,
780                         CRTC_TEST_PATTERN_CONTROL,
781                         CRTC_TEST_PATTERN_EN);
782
783                 set_reg_field_value(
784                         value,
785                         mode,
786                         CRTC_TEST_PATTERN_CONTROL,
787                         CRTC_TEST_PATTERN_MODE);
788
789                 set_reg_field_value(
790                         value,
791                         dyn_range,
792                         CRTC_TEST_PATTERN_CONTROL,
793                         CRTC_TEST_PATTERN_DYNAMIC_RANGE);
794                 set_reg_field_value(
795                         value,
796                         bit_depth,
797                         CRTC_TEST_PATTERN_CONTROL,
798                         CRTC_TEST_PATTERN_COLOR_FORMAT);
799                 dm_write_reg(ctx, addr, value);
800         }
801         break;
802
803         case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
804         case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
805         {
806                 mode = (test_pattern ==
807                         CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
808                         TEST_PATTERN_MODE_VERTICALBARS :
809                         TEST_PATTERN_MODE_HORIZONTALBARS);
810
811                 switch (bit_depth) {
812                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
813                         dst_bpc = 6;
814                 break;
815                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
816                         dst_bpc = 8;
817                 break;
818                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
819                         dst_bpc = 10;
820                 break;
821                 default:
822                         dst_bpc = 8;
823                 break;
824                 }
825
826                 /* adjust color to the required colorFormat */
827                 for (index = 0; index < 6; index++) {
828                         /* dst = 2^dstBpc * src / 2^srcBpc = src >>
829                          * (srcBpc - dstBpc);
830                          */
831                         dst_color[index] =
832                                 src_color[index] >> (src_bpc - dst_bpc);
833                 /* CRTC_TEST_PATTERN_DATA has 16 bits,
834                  * lowest 6 are hardwired to ZERO
835                  * color bits should be left aligned aligned to MSB
836                  * XXXXXXXXXX000000 for 10 bit,
837                  * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
838                  */
839                         dst_color[index] <<= (16 - dst_bpc);
840                 }
841
842                 value = 0;
843                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
844                 dm_write_reg(ctx, addr, value);
845
846                 /* We have to write the mask before data, similar to pipeline.
847                  * For example, for 8 bpc, if we want RGB0 to be magenta,
848                  * and RGB1 to be cyan,
849                  * we need to make 7 writes:
850                  * MASK   DATA
851                  * 000001 00000000 00000000                     set mask to R0
852                  * 000010 11111111 00000000     R0 255, 0xFF00, set mask to G0
853                  * 000100 00000000 00000000     G0 0,   0x0000, set mask to B0
854                  * 001000 11111111 00000000     B0 255, 0xFF00, set mask to R1
855                  * 010000 00000000 00000000     R1 0,   0x0000, set mask to G1
856                  * 100000 11111111 00000000     G1 255, 0xFF00, set mask to B1
857                  * 100000 11111111 00000000     B1 255, 0xFF00
858                  *
859                  * we will make a loop of 6 in which we prepare the mask,
860                  * then write, then prepare the color for next write.
861                  * first iteration will write mask only,
862                  * but each next iteration color prepared in
863                  * previous iteration will be written within new mask,
864                  * the last component will written separately,
865                  * mask is not changing between 6th and 7th write
866                  * and color will be prepared by last iteration
867                  */
868
869                 /* write color, color values mask in CRTC_TEST_PATTERN_MASK
870                  * is B1, G1, R1, B0, G0, R0
871                  */
872                 value = 0;
873                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR);
874                 for (index = 0; index < 6; index++) {
875                         /* prepare color mask, first write PATTERN_DATA
876                          * will have all zeros
877                          */
878                         set_reg_field_value(
879                                 value,
880                                 (1 << index),
881                                 CRTC_TEST_PATTERN_COLOR,
882                                 CRTC_TEST_PATTERN_MASK);
883                         /* write color component */
884                         dm_write_reg(ctx, addr, value);
885                         /* prepare next color component,
886                          * will be written in the next iteration
887                          */
888                         set_reg_field_value(
889                                 value,
890                                 dst_color[index],
891                                 CRTC_TEST_PATTERN_COLOR,
892                                 CRTC_TEST_PATTERN_DATA);
893                 }
894                 /* write last color component,
895                  * it's been already prepared in the loop
896                  */
897                 dm_write_reg(ctx, addr, value);
898
899                 /* enable test pattern */
900                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
901                 value = 0;
902
903                 set_reg_field_value(
904                         value,
905                         1,
906                         CRTC_TEST_PATTERN_CONTROL,
907                         CRTC_TEST_PATTERN_EN);
908
909                 set_reg_field_value(
910                         value,
911                         mode,
912                         CRTC_TEST_PATTERN_CONTROL,
913                         CRTC_TEST_PATTERN_MODE);
914
915                 set_reg_field_value(
916                         value,
917                         0,
918                         CRTC_TEST_PATTERN_CONTROL,
919                         CRTC_TEST_PATTERN_DYNAMIC_RANGE);
920
921                 set_reg_field_value(
922                         value,
923                         bit_depth,
924                         CRTC_TEST_PATTERN_CONTROL,
925                         CRTC_TEST_PATTERN_COLOR_FORMAT);
926
927                 dm_write_reg(ctx, addr, value);
928         }
929         break;
930
931         case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
932         {
933                 mode = (bit_depth ==
934                         TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
935                         TEST_PATTERN_MODE_DUALRAMP_RGB :
936                         TEST_PATTERN_MODE_SINGLERAMP_RGB);
937
938                 switch (bit_depth) {
939                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
940                         dst_bpc = 6;
941                 break;
942                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
943                         dst_bpc = 8;
944                 break;
945                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
946                         dst_bpc = 10;
947                 break;
948                 default:
949                         dst_bpc = 8;
950                 break;
951                 }
952
953                 /* increment for the first ramp for one color gradation
954                  * 1 gradation for 6-bit color is 2^10
955                  * gradations in 16-bit color
956                  */
957                 inc_base = (src_bpc - dst_bpc);
958
959                 value = 0;
960                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
961
962                 switch (bit_depth) {
963                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
964                 {
965                         set_reg_field_value(
966                                 value,
967                                 inc_base,
968                                 CRTC_TEST_PATTERN_PARAMETERS,
969                                 CRTC_TEST_PATTERN_INC0);
970                         set_reg_field_value(
971                                 value,
972                                 0,
973                                 CRTC_TEST_PATTERN_PARAMETERS,
974                                 CRTC_TEST_PATTERN_INC1);
975                         set_reg_field_value(
976                                 value,
977                                 6,
978                                 CRTC_TEST_PATTERN_PARAMETERS,
979                                 CRTC_TEST_PATTERN_HRES);
980                         set_reg_field_value(
981                                 value,
982                                 6,
983                                 CRTC_TEST_PATTERN_PARAMETERS,
984                                 CRTC_TEST_PATTERN_VRES);
985                         set_reg_field_value(
986                                 value,
987                                 0,
988                                 CRTC_TEST_PATTERN_PARAMETERS,
989                                 CRTC_TEST_PATTERN_RAMP0_OFFSET);
990                 }
991                 break;
992                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
993                 {
994                         set_reg_field_value(
995                                 value,
996                                 inc_base,
997                                 CRTC_TEST_PATTERN_PARAMETERS,
998                                 CRTC_TEST_PATTERN_INC0);
999                         set_reg_field_value(
1000                                 value,
1001                                 0,
1002                                 CRTC_TEST_PATTERN_PARAMETERS,
1003                                 CRTC_TEST_PATTERN_INC1);
1004                         set_reg_field_value(
1005                                 value,
1006                                 8,
1007                                 CRTC_TEST_PATTERN_PARAMETERS,
1008                                 CRTC_TEST_PATTERN_HRES);
1009                         set_reg_field_value(
1010                                 value,
1011                                 6,
1012                                 CRTC_TEST_PATTERN_PARAMETERS,
1013                                 CRTC_TEST_PATTERN_VRES);
1014                         set_reg_field_value(
1015                                 value,
1016                                 0,
1017                                 CRTC_TEST_PATTERN_PARAMETERS,
1018                                 CRTC_TEST_PATTERN_RAMP0_OFFSET);
1019                 }
1020                 break;
1021                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1022                 {
1023                         set_reg_field_value(
1024                                 value,
1025                                 inc_base,
1026                                 CRTC_TEST_PATTERN_PARAMETERS,
1027                                 CRTC_TEST_PATTERN_INC0);
1028                         set_reg_field_value(
1029                                 value,
1030                                 inc_base + 2,
1031                                 CRTC_TEST_PATTERN_PARAMETERS,
1032                                 CRTC_TEST_PATTERN_INC1);
1033                         set_reg_field_value(
1034                                 value,
1035                                 8,
1036                                 CRTC_TEST_PATTERN_PARAMETERS,
1037                                 CRTC_TEST_PATTERN_HRES);
1038                         set_reg_field_value(
1039                                 value,
1040                                 5,
1041                                 CRTC_TEST_PATTERN_PARAMETERS,
1042                                 CRTC_TEST_PATTERN_VRES);
1043                         set_reg_field_value(
1044                                 value,
1045                                 384 << 6,
1046                                 CRTC_TEST_PATTERN_PARAMETERS,
1047                                 CRTC_TEST_PATTERN_RAMP0_OFFSET);
1048                 }
1049                 break;
1050                 default:
1051                 break;
1052                 }
1053                 dm_write_reg(ctx, addr, value);
1054
1055                 value = 0;
1056                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR);
1057                 dm_write_reg(ctx, addr, value);
1058
1059                 /* enable test pattern */
1060                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
1061                 value = 0;
1062
1063                 set_reg_field_value(
1064                         value,
1065                         1,
1066                         CRTC_TEST_PATTERN_CONTROL,
1067                         CRTC_TEST_PATTERN_EN);
1068
1069                 set_reg_field_value(
1070                         value,
1071                         mode,
1072                         CRTC_TEST_PATTERN_CONTROL,
1073                         CRTC_TEST_PATTERN_MODE);
1074
1075                 set_reg_field_value(
1076                         value,
1077                         0,
1078                         CRTC_TEST_PATTERN_CONTROL,
1079                         CRTC_TEST_PATTERN_DYNAMIC_RANGE);
1080                 /* add color depth translation here */
1081                 set_reg_field_value(
1082                         value,
1083                         bit_depth,
1084                         CRTC_TEST_PATTERN_CONTROL,
1085                         CRTC_TEST_PATTERN_COLOR_FORMAT);
1086
1087                 dm_write_reg(ctx, addr, value);
1088         }
1089         break;
1090         case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1091         {
1092                 value = 0;
1093                 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL), value);
1094                 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_COLOR), value);
1095                 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS),
1096                                 value);
1097         }
1098         break;
1099         default:
1100         break;
1101         }
1102 }
1103
1104 /**
1105 * dce110_timing_generator_validate_timing
1106 * The timing generators support a maximum display size of is 8192 x 8192 pixels,
1107 * including both active display and blanking periods. Check H Total and V Total.
1108 */
1109 bool dce110_timing_generator_validate_timing(
1110         struct timing_generator *tg,
1111         const struct dc_crtc_timing *timing,
1112         enum signal_type signal)
1113 {
1114         uint32_t h_blank;
1115         uint32_t h_back_porch;
1116         uint32_t hsync_offset = timing->h_border_right +
1117                         timing->h_front_porch;
1118         uint32_t h_sync_start = timing->h_addressable + hsync_offset;
1119
1120         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1121
1122         ASSERT(timing != NULL);
1123
1124         if (!timing)
1125                 return false;
1126
1127         /* Currently we don't support 3D, so block all 3D timings */
1128         if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE)
1129                 return false;
1130
1131         /* Temporarily blocking interlacing mode until it's supported */
1132         if (timing->flags.INTERLACE == 1)
1133                 return false;
1134
1135         /* Check maximum number of pixels supported by Timing Generator
1136          * (Currently will never fail, in order to fail needs display which
1137          * needs more than 8192 horizontal and
1138          * more than 8192 vertical total pixels)
1139          */
1140         if (timing->h_total > tg110->max_h_total ||
1141                 timing->v_total > tg110->max_v_total)
1142                 return false;
1143
1144         h_blank = (timing->h_total - timing->h_addressable -
1145                 timing->h_border_right -
1146                 timing->h_border_left);
1147
1148         if (h_blank < tg110->min_h_blank)
1149                 return false;
1150
1151         if (timing->h_front_porch < tg110->min_h_front_porch)
1152                 return false;
1153
1154         h_back_porch = h_blank - (h_sync_start -
1155                 timing->h_addressable -
1156                 timing->h_border_right -
1157                 timing->h_sync_width);
1158
1159         if (h_back_porch < tg110->min_h_back_porch)
1160                 return false;
1161
1162         return true;
1163 }
1164
1165 /**
1166 * Wait till we are at the beginning of VBlank.
1167 */
1168 void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg)
1169 {
1170         /* We want to catch beginning of VBlank here, so if the first try are
1171          * in VBlank, we might be very close to Active, in this case wait for
1172          * another frame
1173          */
1174         while (dce110_timing_generator_is_in_vertical_blank(tg)) {
1175                 if (!dce110_timing_generator_is_counter_moving(tg)) {
1176                         /* error - no point to wait if counter is not moving */
1177                         break;
1178                 }
1179         }
1180
1181         while (!dce110_timing_generator_is_in_vertical_blank(tg)) {
1182                 if (!dce110_timing_generator_is_counter_moving(tg)) {
1183                         /* error - no point to wait if counter is not moving */
1184                         break;
1185                 }
1186         }
1187 }
1188
1189 /**
1190 * Wait till we are in VActive (anywhere in VActive)
1191 */
1192 void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg)
1193 {
1194         while (dce110_timing_generator_is_in_vertical_blank(tg)) {
1195                 if (!dce110_timing_generator_is_counter_moving(tg)) {
1196                         /* error - no point to wait if counter is not moving */
1197                         break;
1198                 }
1199         }
1200 }
1201
1202 /**
1203  *****************************************************************************
1204  *  Function: dce110_timing_generator_setup_global_swap_lock
1205  *
1206  *  @brief
1207  *     Setups Global Swap Lock group for current pipe
1208  *     Pipe can join or leave GSL group, become a TimingServer or TimingClient
1209  *
1210  *  @param [in] gsl_params: setup data
1211  *****************************************************************************
1212  */
1213
1214 void dce110_timing_generator_setup_global_swap_lock(
1215         struct timing_generator *tg,
1216         const struct dcp_gsl_params *gsl_params)
1217 {
1218         uint32_t value;
1219         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1220         uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1221         uint32_t check_point = FLIP_READY_BACK_LOOKUP;
1222
1223         value = dm_read_reg(tg->ctx, address);
1224
1225         /* This pipe will belong to GSL Group zero. */
1226         set_reg_field_value(value,
1227                         1,
1228                         DCP_GSL_CONTROL,
1229                         DCP_GSL0_EN);
1230
1231         set_reg_field_value(value,
1232                         gsl_params->gsl_master == tg->inst,
1233                         DCP_GSL_CONTROL,
1234                         DCP_GSL_MASTER_EN);
1235
1236         set_reg_field_value(value,
1237                         HFLIP_READY_DELAY,
1238                         DCP_GSL_CONTROL,
1239                         DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1240
1241         /* Keep signal low (pending high) during 6 lines.
1242          * Also defines minimum interval before re-checking signal. */
1243         set_reg_field_value(value,
1244                         HFLIP_CHECK_DELAY,
1245                         DCP_GSL_CONTROL,
1246                         DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1247
1248
1249         {
1250                 uint32_t value_crtc_vtotal;
1251
1252                 value_crtc_vtotal = dm_read_reg(tg->ctx,
1253                                 CRTC_REG(mmCRTC_V_TOTAL));
1254
1255                 set_reg_field_value(value,
1256                                 0,/* DCP_GSL_PURPOSE_SURFACE_FLIP */
1257                                 DCP_GSL_CONTROL,
1258                                 DCP_GSL_SYNC_SOURCE);
1259
1260                 /* Checkpoint relative to end of frame */
1261                 check_point = get_reg_field_value(value_crtc_vtotal,
1262                                 CRTC_V_TOTAL,
1263                                 CRTC_V_TOTAL);
1264
1265                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_GSL_WINDOW), 0);
1266         }
1267
1268         set_reg_field_value(value,
1269                         1,
1270                         DCP_GSL_CONTROL,
1271                         DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
1272
1273         dm_write_reg(tg->ctx, address, value);
1274
1275         /********************************************************************/
1276         address = CRTC_REG(mmCRTC_GSL_CONTROL);
1277
1278         value = 0;
1279         set_reg_field_value(value,
1280                         check_point - FLIP_READY_BACK_LOOKUP,
1281                         CRTC_GSL_CONTROL,
1282                         CRTC_GSL_CHECK_LINE_NUM);
1283
1284         set_reg_field_value(value,
1285                         VFLIP_READY_DELAY,
1286                         CRTC_GSL_CONTROL,
1287                         CRTC_GSL_FORCE_DELAY);
1288
1289         dm_write_reg(tg->ctx, address, value);
1290 }
1291
1292 void dce110_timing_generator_tear_down_global_swap_lock(
1293         struct timing_generator *tg)
1294 {
1295         /* Clear all the register writes done by
1296          * dce110_timing_generator_setup_global_swap_lock
1297          */
1298
1299         uint32_t value;
1300         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1301         uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1302
1303         value = 0;
1304
1305         /* This pipe will belong to GSL Group zero. */
1306         /* Settig HW default values from reg specs */
1307         set_reg_field_value(value,
1308                         0,
1309                         DCP_GSL_CONTROL,
1310                         DCP_GSL0_EN);
1311
1312         set_reg_field_value(value,
1313                         0,
1314                         DCP_GSL_CONTROL,
1315                         DCP_GSL_MASTER_EN);
1316
1317         set_reg_field_value(value,
1318                         0x2,
1319                         DCP_GSL_CONTROL,
1320                         DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1321
1322         set_reg_field_value(value,
1323                         0x6,
1324                         DCP_GSL_CONTROL,
1325                         DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1326
1327         /* Restore DCP_GSL_PURPOSE_SURFACE_FLIP */
1328         {
1329                 uint32_t value_crtc_vtotal;
1330
1331                 value_crtc_vtotal = dm_read_reg(tg->ctx,
1332                                 CRTC_REG(mmCRTC_V_TOTAL));
1333
1334                 set_reg_field_value(value,
1335                                 0,
1336                                 DCP_GSL_CONTROL,
1337                                 DCP_GSL_SYNC_SOURCE);
1338         }
1339
1340         set_reg_field_value(value,
1341                         0,
1342                         DCP_GSL_CONTROL,
1343                         DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
1344
1345         dm_write_reg(tg->ctx, address, value);
1346
1347         /********************************************************************/
1348         address = CRTC_REG(mmCRTC_GSL_CONTROL);
1349
1350         value = 0;
1351         set_reg_field_value(value,
1352                         0,
1353                         CRTC_GSL_CONTROL,
1354                         CRTC_GSL_CHECK_LINE_NUM);
1355
1356         set_reg_field_value(value,
1357                         0x2,
1358                         CRTC_GSL_CONTROL,
1359                         CRTC_GSL_FORCE_DELAY);
1360
1361         dm_write_reg(tg->ctx, address, value);
1362 }
1363 /**
1364  *****************************************************************************
1365  *  Function: is_counter_moving
1366  *
1367  *  @brief
1368  *     check if the timing generator is currently going
1369  *
1370  *  @return
1371  *     true if currently going, false if currently paused or stopped.
1372  *
1373  *****************************************************************************
1374  */
1375 bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg)
1376 {
1377         struct crtc_position position1, position2;
1378
1379         tg->funcs->get_position(tg, &position1);
1380         tg->funcs->get_position(tg, &position2);
1381
1382         if (position1.horizontal_count == position2.horizontal_count &&
1383                 position1.vertical_count == position2.vertical_count)
1384                 return false;
1385         else
1386                 return true;
1387 }
1388
1389 void dce110_timing_generator_enable_advanced_request(
1390         struct timing_generator *tg,
1391         bool enable,
1392         const struct dc_crtc_timing *timing)
1393 {
1394         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1395         uint32_t addr = CRTC_REG(mmCRTC_START_LINE_CONTROL);
1396         uint32_t value = dm_read_reg(tg->ctx, addr);
1397
1398         if (enable) {
1399                 set_reg_field_value(
1400                         value,
1401                         0,
1402                         CRTC_START_LINE_CONTROL,
1403                         CRTC_LEGACY_REQUESTOR_EN);
1404         } else {
1405                 set_reg_field_value(
1406                         value,
1407                         1,
1408                         CRTC_START_LINE_CONTROL,
1409                         CRTC_LEGACY_REQUESTOR_EN);
1410         }
1411
1412         if ((timing->v_sync_width + timing->v_front_porch) <= 3) {
1413                 set_reg_field_value(
1414                         value,
1415                         3,
1416                         CRTC_START_LINE_CONTROL,
1417                         CRTC_ADVANCED_START_LINE_POSITION);
1418                 set_reg_field_value(
1419                         value,
1420                         0,
1421                         CRTC_START_LINE_CONTROL,
1422                         CRTC_PREFETCH_EN);
1423         } else {
1424                 set_reg_field_value(
1425                         value,
1426                         4,
1427                         CRTC_START_LINE_CONTROL,
1428                         CRTC_ADVANCED_START_LINE_POSITION);
1429                 set_reg_field_value(
1430                         value,
1431                         1,
1432                         CRTC_START_LINE_CONTROL,
1433                         CRTC_PREFETCH_EN);
1434         }
1435
1436         set_reg_field_value(
1437                 value,
1438                 1,
1439                 CRTC_START_LINE_CONTROL,
1440                 CRTC_PROGRESSIVE_START_LINE_EARLY);
1441
1442         set_reg_field_value(
1443                 value,
1444                 1,
1445                 CRTC_START_LINE_CONTROL,
1446                 CRTC_INTERLACE_START_LINE_EARLY);
1447
1448         dm_write_reg(tg->ctx, addr, value);
1449 }
1450
1451 /*TODO: Figure out if we need this function. */
1452 void dce110_timing_generator_set_lock_master(struct timing_generator *tg,
1453                 bool lock)
1454 {
1455         struct dc_context *ctx = tg->ctx;
1456         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1457         uint32_t addr = CRTC_REG(mmCRTC_MASTER_UPDATE_LOCK);
1458         uint32_t value = dm_read_reg(ctx, addr);
1459
1460         set_reg_field_value(
1461                 value,
1462                 lock ? 1 : 0,
1463                 CRTC_MASTER_UPDATE_LOCK,
1464                 MASTER_UPDATE_LOCK);
1465
1466         dm_write_reg(ctx, addr, value);
1467 }
1468
1469 void dce110_timing_generator_enable_reset_trigger(
1470         struct timing_generator *tg,
1471         int source_tg_inst)
1472 {
1473         uint32_t value;
1474         uint32_t rising_edge = 0;
1475         uint32_t falling_edge = 0;
1476         enum trigger_source_select trig_src_select = TRIGGER_SOURCE_SELECT_LOGIC_ZERO;
1477         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1478
1479         /* Setup trigger edge */
1480         {
1481                 uint32_t pol_value = dm_read_reg(tg->ctx,
1482                                 CRTC_REG(mmCRTC_V_SYNC_A_CNTL));
1483
1484                 /* Register spec has reversed definition:
1485                  *      0 for positive, 1 for negative */
1486                 if (get_reg_field_value(pol_value,
1487                                 CRTC_V_SYNC_A_CNTL,
1488                                 CRTC_V_SYNC_A_POL) == 0) {
1489                         rising_edge = 1;
1490                 } else {
1491                         falling_edge = 1;
1492                 }
1493         }
1494
1495         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
1496
1497         trig_src_select = TRIGGER_SOURCE_SELECT_GSL_GROUP0;
1498
1499         set_reg_field_value(value,
1500                         trig_src_select,
1501                         CRTC_TRIGB_CNTL,
1502                         CRTC_TRIGB_SOURCE_SELECT);
1503
1504         set_reg_field_value(value,
1505                         TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
1506                         CRTC_TRIGB_CNTL,
1507                         CRTC_TRIGB_POLARITY_SELECT);
1508
1509         set_reg_field_value(value,
1510                         rising_edge,
1511                         CRTC_TRIGB_CNTL,
1512                         CRTC_TRIGB_RISING_EDGE_DETECT_CNTL);
1513
1514         set_reg_field_value(value,
1515                         falling_edge,
1516                         CRTC_TRIGB_CNTL,
1517                         CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL);
1518
1519         set_reg_field_value(value,
1520                         0, /* send every signal */
1521                         CRTC_TRIGB_CNTL,
1522                         CRTC_TRIGB_FREQUENCY_SELECT);
1523
1524         set_reg_field_value(value,
1525                         0, /* no delay */
1526                         CRTC_TRIGB_CNTL,
1527                         CRTC_TRIGB_DELAY);
1528
1529         set_reg_field_value(value,
1530                         1, /* clear trigger status */
1531                         CRTC_TRIGB_CNTL,
1532                         CRTC_TRIGB_CLEAR);
1533
1534         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
1535
1536         /**************************************************************/
1537
1538         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1539
1540         set_reg_field_value(value,
1541                         2, /* force H count to H_TOTAL and V count to V_TOTAL */
1542                         CRTC_FORCE_COUNT_NOW_CNTL,
1543                         CRTC_FORCE_COUNT_NOW_MODE);
1544
1545         set_reg_field_value(value,
1546                         1, /* TriggerB - we never use TriggerA */
1547                         CRTC_FORCE_COUNT_NOW_CNTL,
1548                         CRTC_FORCE_COUNT_NOW_TRIG_SEL);
1549
1550         set_reg_field_value(value,
1551                         1, /* clear trigger status */
1552                         CRTC_FORCE_COUNT_NOW_CNTL,
1553                         CRTC_FORCE_COUNT_NOW_CLEAR);
1554
1555         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1556 }
1557
1558 void dce110_timing_generator_disable_reset_trigger(
1559         struct timing_generator *tg)
1560 {
1561         uint32_t value;
1562         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1563
1564         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1565
1566         set_reg_field_value(value,
1567                         0, /* force counter now mode is disabled */
1568                         CRTC_FORCE_COUNT_NOW_CNTL,
1569                         CRTC_FORCE_COUNT_NOW_MODE);
1570
1571         set_reg_field_value(value,
1572                         1, /* clear trigger status */
1573                         CRTC_FORCE_COUNT_NOW_CNTL,
1574                         CRTC_FORCE_COUNT_NOW_CLEAR);
1575
1576         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1577
1578         /********************************************************************/
1579         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
1580
1581         set_reg_field_value(value,
1582                         TRIGGER_SOURCE_SELECT_LOGIC_ZERO,
1583                         CRTC_TRIGB_CNTL,
1584                         CRTC_TRIGB_SOURCE_SELECT);
1585
1586         set_reg_field_value(value,
1587                         TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
1588                         CRTC_TRIGB_CNTL,
1589                         CRTC_TRIGB_POLARITY_SELECT);
1590
1591         set_reg_field_value(value,
1592                         1, /* clear trigger status */
1593                         CRTC_TRIGB_CNTL,
1594                         CRTC_TRIGB_CLEAR);
1595
1596         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
1597 }
1598
1599 /**
1600  *****************************************************************************
1601  *  @brief
1602  *     Checks whether CRTC triggered reset occurred
1603  *
1604  *  @return
1605  *     true if triggered reset occurred, false otherwise
1606  *****************************************************************************
1607  */
1608 bool dce110_timing_generator_did_triggered_reset_occur(
1609         struct timing_generator *tg)
1610 {
1611         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1612         uint32_t value = dm_read_reg(tg->ctx,
1613                         CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1614
1615         return get_reg_field_value(value,
1616                         CRTC_FORCE_COUNT_NOW_CNTL,
1617                         CRTC_FORCE_COUNT_NOW_OCCURRED) != 0;
1618 }
1619
1620 /**
1621  * dce110_timing_generator_disable_vga
1622  * Turn OFF VGA Mode and Timing  - DxVGA_CONTROL
1623  * VGA Mode and VGA Timing is used by VBIOS on CRT Monitors;
1624  */
1625 void dce110_timing_generator_disable_vga(
1626         struct timing_generator *tg)
1627 {
1628         uint32_t addr = 0;
1629         uint32_t value = 0;
1630
1631         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1632
1633         switch (tg110->controller_id) {
1634         case CONTROLLER_ID_D0:
1635                 addr = mmD1VGA_CONTROL;
1636                 break;
1637         case CONTROLLER_ID_D1:
1638                 addr = mmD2VGA_CONTROL;
1639                 break;
1640         case CONTROLLER_ID_D2:
1641                 addr = mmD3VGA_CONTROL;
1642                 break;
1643         case CONTROLLER_ID_D3:
1644                 addr = mmD4VGA_CONTROL;
1645                 break;
1646         case CONTROLLER_ID_D4:
1647                 addr = mmD5VGA_CONTROL;
1648                 break;
1649         case CONTROLLER_ID_D5:
1650                 addr = mmD6VGA_CONTROL;
1651                 break;
1652         default:
1653                 break;
1654         }
1655         value = dm_read_reg(tg->ctx, addr);
1656
1657         set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE);
1658         set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT);
1659         set_reg_field_value(
1660                         value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT);
1661         set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN);
1662
1663         dm_write_reg(tg->ctx, addr, value);
1664 }
1665
1666 /**
1667 * set_overscan_color_black
1668 *
1669 * @param :black_color is one of the color space
1670 *    :this routine will set overscan black color according to the color space.
1671 * @return none
1672 */
1673
1674 void dce110_timing_generator_set_overscan_color_black(
1675         struct timing_generator *tg,
1676         const struct tg_color *color)
1677 {
1678         struct dc_context *ctx = tg->ctx;
1679         uint32_t addr;
1680         uint32_t value = 0;
1681         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1682
1683         set_reg_field_value(
1684                         value,
1685                         color->color_b_cb,
1686                         CRTC_OVERSCAN_COLOR,
1687                         CRTC_OVERSCAN_COLOR_BLUE);
1688
1689         set_reg_field_value(
1690                         value,
1691                         color->color_r_cr,
1692                         CRTC_OVERSCAN_COLOR,
1693                         CRTC_OVERSCAN_COLOR_RED);
1694
1695         set_reg_field_value(
1696                         value,
1697                         color->color_g_y,
1698                         CRTC_OVERSCAN_COLOR,
1699                         CRTC_OVERSCAN_COLOR_GREEN);
1700
1701         addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1702         dm_write_reg(ctx, addr, value);
1703         addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1704         dm_write_reg(ctx, addr, value);
1705         /* This is desirable to have a constant DAC output voltage during the
1706          * blank time that is higher than the 0 volt reference level that the
1707          * DAC outputs when the NBLANK signal
1708          * is asserted low, such as for output to an analog TV. */
1709         addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1710         dm_write_reg(ctx, addr, value);
1711
1712         /* TO DO we have to program EXT registers and we need to know LB DATA
1713          * format because it is used when more 10 , i.e. 12 bits per color
1714          *
1715          * m_mmDxCRTC_OVERSCAN_COLOR_EXT
1716          * m_mmDxCRTC_BLACK_COLOR_EXT
1717          * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
1718          */
1719
1720 }
1721
1722 void dce110_tg_program_blank_color(struct timing_generator *tg,
1723                 const struct tg_color *black_color)
1724 {
1725         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1726         uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1727         uint32_t value = dm_read_reg(tg->ctx, addr);
1728
1729         set_reg_field_value(
1730                 value,
1731                 black_color->color_b_cb,
1732                 CRTC_BLACK_COLOR,
1733                 CRTC_BLACK_COLOR_B_CB);
1734         set_reg_field_value(
1735                 value,
1736                 black_color->color_g_y,
1737                 CRTC_BLACK_COLOR,
1738                 CRTC_BLACK_COLOR_G_Y);
1739         set_reg_field_value(
1740                 value,
1741                 black_color->color_r_cr,
1742                 CRTC_BLACK_COLOR,
1743                 CRTC_BLACK_COLOR_R_CR);
1744
1745         dm_write_reg(tg->ctx, addr, value);
1746
1747         addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1748         dm_write_reg(tg->ctx, addr, value);
1749 }
1750
1751 void dce110_tg_set_overscan_color(struct timing_generator *tg,
1752         const struct tg_color *overscan_color)
1753 {
1754         struct dc_context *ctx = tg->ctx;
1755         uint32_t value = 0;
1756         uint32_t addr;
1757         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1758
1759         set_reg_field_value(
1760                 value,
1761                 overscan_color->color_b_cb,
1762                 CRTC_OVERSCAN_COLOR,
1763                 CRTC_OVERSCAN_COLOR_BLUE);
1764
1765         set_reg_field_value(
1766                 value,
1767                 overscan_color->color_g_y,
1768                 CRTC_OVERSCAN_COLOR,
1769                 CRTC_OVERSCAN_COLOR_GREEN);
1770
1771         set_reg_field_value(
1772                 value,
1773                 overscan_color->color_r_cr,
1774                 CRTC_OVERSCAN_COLOR,
1775                 CRTC_OVERSCAN_COLOR_RED);
1776
1777         addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1778         dm_write_reg(ctx, addr, value);
1779 }
1780
1781 void dce110_tg_program_timing(struct timing_generator *tg,
1782         const struct dc_crtc_timing *timing,
1783         bool use_vbios)
1784 {
1785         if (use_vbios)
1786                 dce110_timing_generator_program_timing_generator(tg, timing);
1787         else
1788                 dce110_timing_generator_program_blanking(tg, timing);
1789 }
1790
1791 bool dce110_tg_is_blanked(struct timing_generator *tg)
1792 {
1793         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1794         uint32_t value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL));
1795
1796         if (get_reg_field_value(
1797                         value,
1798                         CRTC_BLANK_CONTROL,
1799                         CRTC_BLANK_DATA_EN) == 1 &&
1800                 get_reg_field_value(
1801                         value,
1802                         CRTC_BLANK_CONTROL,
1803                         CRTC_CURRENT_BLANK_STATE) == 1)
1804                 return true;
1805         return false;
1806 }
1807
1808 void dce110_tg_set_blank(struct timing_generator *tg,
1809                 bool enable_blanking)
1810 {
1811         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1812         uint32_t value = 0;
1813
1814         set_reg_field_value(
1815                 value,
1816                 1,
1817                 CRTC_DOUBLE_BUFFER_CONTROL,
1818                 CRTC_BLANK_DATA_DOUBLE_BUFFER_EN);
1819
1820         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_DOUBLE_BUFFER_CONTROL), value);
1821         value = 0;
1822
1823         if (enable_blanking) {
1824                 set_reg_field_value(
1825                         value,
1826                         1,
1827                         CRTC_BLANK_CONTROL,
1828                         CRTC_BLANK_DATA_EN);
1829
1830                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), value);
1831
1832         } else
1833                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), 0);
1834 }
1835
1836 bool dce110_tg_validate_timing(struct timing_generator *tg,
1837         const struct dc_crtc_timing *timing)
1838 {
1839         return dce110_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
1840 }
1841
1842 void dce110_tg_wait_for_state(struct timing_generator *tg,
1843         enum crtc_state state)
1844 {
1845         switch (state) {
1846         case CRTC_STATE_VBLANK:
1847                 dce110_timing_generator_wait_for_vblank(tg);
1848                 break;
1849
1850         case CRTC_STATE_VACTIVE:
1851                 dce110_timing_generator_wait_for_vactive(tg);
1852                 break;
1853
1854         default:
1855                 break;
1856         }
1857 }
1858
1859 void dce110_tg_set_colors(struct timing_generator *tg,
1860         const struct tg_color *blank_color,
1861         const struct tg_color *overscan_color)
1862 {
1863         if (blank_color != NULL)
1864                 dce110_tg_program_blank_color(tg, blank_color);
1865         if (overscan_color != NULL)
1866                 dce110_tg_set_overscan_color(tg, overscan_color);
1867 }
1868
1869 /* Gets first line of blank region of the display timing for CRTC
1870  * and programms is as a trigger to fire vertical interrupt
1871  */
1872 bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
1873 {
1874         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1875         uint32_t v_blank_start = 0;
1876         uint32_t v_blank_end = 0;
1877         uint32_t val = 0;
1878         uint32_t h_position, v_position;
1879
1880         tg->funcs->get_scanoutpos(
1881                         tg,
1882                         &v_blank_start,
1883                         &v_blank_end,
1884                         &h_position,
1885                         &v_position);
1886
1887         if (v_blank_start == 0 || v_blank_end == 0)
1888                 return false;
1889
1890         set_reg_field_value(
1891                 val,
1892                 v_blank_start,
1893                 CRTC_VERTICAL_INTERRUPT0_POSITION,
1894                 CRTC_VERTICAL_INTERRUPT0_LINE_START);
1895
1896         /* Set interval width for interrupt to fire to 1 scanline */
1897         set_reg_field_value(
1898                 val,
1899                 v_blank_start + width,
1900                 CRTC_VERTICAL_INTERRUPT0_POSITION,
1901                 CRTC_VERTICAL_INTERRUPT0_LINE_END);
1902
1903         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERTICAL_INTERRUPT0_POSITION), val);
1904
1905         return true;
1906 }
1907
1908 static const struct timing_generator_funcs dce110_tg_funcs = {
1909                 .validate_timing = dce110_tg_validate_timing,
1910                 .program_timing = dce110_tg_program_timing,
1911                 .enable_crtc = dce110_timing_generator_enable_crtc,
1912                 .disable_crtc = dce110_timing_generator_disable_crtc,
1913                 .is_counter_moving = dce110_timing_generator_is_counter_moving,
1914                 .get_position = dce110_timing_generator_get_position,
1915                 .get_frame_count = dce110_timing_generator_get_vblank_counter,
1916                 .get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos,
1917                 .set_early_control = dce110_timing_generator_set_early_control,
1918                 .wait_for_state = dce110_tg_wait_for_state,
1919                 .set_blank = dce110_tg_set_blank,
1920                 .is_blanked = dce110_tg_is_blanked,
1921                 .set_colors = dce110_tg_set_colors,
1922                 .set_overscan_blank_color =
1923                                 dce110_timing_generator_set_overscan_color_black,
1924                 .set_blank_color = dce110_timing_generator_program_blank_color,
1925                 .disable_vga = dce110_timing_generator_disable_vga,
1926                 .did_triggered_reset_occur =
1927                                 dce110_timing_generator_did_triggered_reset_occur,
1928                 .setup_global_swap_lock =
1929                                 dce110_timing_generator_setup_global_swap_lock,
1930                 .enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
1931                 .disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
1932                 .tear_down_global_swap_lock =
1933                                 dce110_timing_generator_tear_down_global_swap_lock,
1934                 .enable_advanced_request =
1935                                 dce110_timing_generator_enable_advanced_request,
1936                 .set_drr =
1937                                 dce110_timing_generator_set_drr,
1938                 .set_static_screen_control =
1939                         dce110_timing_generator_set_static_screen_control,
1940                 .set_test_pattern = dce110_timing_generator_set_test_pattern,
1941                 .arm_vert_intr = dce110_arm_vert_intr,
1942 };
1943
1944 void dce110_timing_generator_construct(
1945         struct dce110_timing_generator *tg110,
1946         struct dc_context *ctx,
1947         uint32_t instance,
1948         const struct dce110_timing_generator_offsets *offsets)
1949 {
1950         tg110->controller_id = CONTROLLER_ID_D0 + instance;
1951         tg110->base.inst = instance;
1952
1953         tg110->offsets = *offsets;
1954
1955         tg110->base.funcs = &dce110_tg_funcs;
1956
1957         tg110->base.ctx = ctx;
1958         tg110->base.bp = ctx->dc_bios;
1959
1960         tg110->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
1961         tg110->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
1962
1963         tg110->min_h_blank = 56;
1964         tg110->min_h_front_porch = 4;
1965         tg110->min_h_back_porch = 4;
1966 }