drm/amd/display: Return last used DRR VTOTAL from DC
[platform/kernel/linux-starfive.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 static void program_horz_count_by_2(
255         struct timing_generator *tg,
256         const struct dc_crtc_timing *timing)
257 {
258         uint32_t regval;
259         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
260
261         regval = dm_read_reg(tg->ctx,
262                         CRTC_REG(mmCRTC_COUNT_CONTROL));
263
264         set_reg_field_value(regval, 0, CRTC_COUNT_CONTROL,
265                         CRTC_HORZ_COUNT_BY2_EN);
266
267         if (timing->flags.HORZ_COUNT_BY_TWO)
268                 set_reg_field_value(regval, 1, CRTC_COUNT_CONTROL,
269                                         CRTC_HORZ_COUNT_BY2_EN);
270
271         dm_write_reg(tg->ctx,
272                         CRTC_REG(mmCRTC_COUNT_CONTROL), regval);
273 }
274
275 /*
276  * program_timing_generator
277  * Program CRTC Timing Registers - DxCRTC_H_*, DxCRTC_V_*, Pixel repetition.
278  * Call ASIC Control Object to program Timings.
279  */
280 bool dce110_timing_generator_program_timing_generator(
281         struct timing_generator *tg,
282         const struct dc_crtc_timing *dc_crtc_timing)
283 {
284         enum bp_result result;
285         struct bp_hw_crtc_timing_parameters bp_params;
286         struct dc_crtc_timing patched_crtc_timing;
287         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
288
289         uint32_t vsync_offset = dc_crtc_timing->v_border_bottom +
290                         dc_crtc_timing->v_front_porch;
291         uint32_t v_sync_start =dc_crtc_timing->v_addressable + vsync_offset;
292
293         uint32_t hsync_offset = dc_crtc_timing->h_border_right +
294                         dc_crtc_timing->h_front_porch;
295         uint32_t h_sync_start = dc_crtc_timing->h_addressable + hsync_offset;
296
297         memset(&bp_params, 0, sizeof(struct bp_hw_crtc_timing_parameters));
298
299         /* Due to an asic bug we need to apply the Front Porch workaround prior
300          * to programming the timing.
301          */
302
303         patched_crtc_timing = *dc_crtc_timing;
304
305         dce110_timing_generator_apply_front_porch_workaround(tg, &patched_crtc_timing);
306
307         bp_params.controller_id = tg110->controller_id;
308
309         bp_params.h_total = patched_crtc_timing.h_total;
310         bp_params.h_addressable =
311                 patched_crtc_timing.h_addressable;
312         bp_params.v_total = patched_crtc_timing.v_total;
313         bp_params.v_addressable = patched_crtc_timing.v_addressable;
314
315         bp_params.h_sync_start = h_sync_start;
316         bp_params.h_sync_width = patched_crtc_timing.h_sync_width;
317         bp_params.v_sync_start = v_sync_start;
318         bp_params.v_sync_width = patched_crtc_timing.v_sync_width;
319
320         /* Set overscan */
321         bp_params.h_overscan_left =
322                 patched_crtc_timing.h_border_left;
323         bp_params.h_overscan_right =
324                 patched_crtc_timing.h_border_right;
325         bp_params.v_overscan_top = patched_crtc_timing.v_border_top;
326         bp_params.v_overscan_bottom =
327                 patched_crtc_timing.v_border_bottom;
328
329         /* Set flags */
330         if (patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY == 1)
331                 bp_params.flags.HSYNC_POSITIVE_POLARITY = 1;
332
333         if (patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY == 1)
334                 bp_params.flags.VSYNC_POSITIVE_POLARITY = 1;
335
336         if (patched_crtc_timing.flags.INTERLACE == 1)
337                 bp_params.flags.INTERLACE = 1;
338
339         if (patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1)
340                 bp_params.flags.HORZ_COUNT_BY_TWO = 1;
341
342         result = tg->bp->funcs->program_crtc_timing(tg->bp, &bp_params);
343
344         program_horz_count_by_2(tg, &patched_crtc_timing);
345
346         tg110->base.funcs->enable_advanced_request(tg, true, &patched_crtc_timing);
347
348         /* Enable stereo - only when we need to pack 3D frame. Other types
349          * of stereo handled in explicit call */
350
351         return result == BP_RESULT_OK;
352 }
353
354 /*
355  *****************************************************************************
356  *  Function: set_drr
357  *
358  *  @brief
359  *     Program dynamic refresh rate registers m_DxCRTC_V_TOTAL_*.
360  *
361  *  @param [in] pHwCrtcTiming: point to H
362  *  wCrtcTiming struct
363  *****************************************************************************
364  */
365 void dce110_timing_generator_set_drr(
366         struct timing_generator *tg,
367         const struct drr_params *params)
368 {
369         /* register values */
370         uint32_t v_total_min = 0;
371         uint32_t v_total_max = 0;
372         uint32_t v_total_cntl = 0;
373         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
374
375         uint32_t addr = 0;
376
377         addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
378         v_total_min = dm_read_reg(tg->ctx, addr);
379
380         addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
381         v_total_max = dm_read_reg(tg->ctx, addr);
382
383         addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL);
384         v_total_cntl = dm_read_reg(tg->ctx, addr);
385
386         if (params != NULL &&
387                 params->vertical_total_max > 0 &&
388                 params->vertical_total_min > 0) {
389
390                 set_reg_field_value(v_total_max,
391                                 params->vertical_total_max - 1,
392                                 CRTC_V_TOTAL_MAX,
393                                 CRTC_V_TOTAL_MAX);
394
395                 set_reg_field_value(v_total_min,
396                                 params->vertical_total_min - 1,
397                                 CRTC_V_TOTAL_MIN,
398                                 CRTC_V_TOTAL_MIN);
399
400                 set_reg_field_value(v_total_cntl,
401                                 1,
402                                 CRTC_V_TOTAL_CONTROL,
403                                 CRTC_V_TOTAL_MIN_SEL);
404
405                 set_reg_field_value(v_total_cntl,
406                                 1,
407                                 CRTC_V_TOTAL_CONTROL,
408                                 CRTC_V_TOTAL_MAX_SEL);
409
410                 set_reg_field_value(v_total_cntl,
411                                 0,
412                                 CRTC_V_TOTAL_CONTROL,
413                                 CRTC_FORCE_LOCK_ON_EVENT);
414                 set_reg_field_value(v_total_cntl,
415                                 0,
416                                 CRTC_V_TOTAL_CONTROL,
417                                 CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
418
419                 set_reg_field_value(v_total_cntl,
420                                 0,
421                                 CRTC_V_TOTAL_CONTROL,
422                                 CRTC_SET_V_TOTAL_MIN_MASK_EN);
423
424                 set_reg_field_value(v_total_cntl,
425                                 0,
426                                 CRTC_V_TOTAL_CONTROL,
427                                 CRTC_SET_V_TOTAL_MIN_MASK);
428         } else {
429                 set_reg_field_value(v_total_cntl,
430                         0,
431                         CRTC_V_TOTAL_CONTROL,
432                         CRTC_SET_V_TOTAL_MIN_MASK);
433                 set_reg_field_value(v_total_cntl,
434                                 0,
435                                 CRTC_V_TOTAL_CONTROL,
436                                 CRTC_V_TOTAL_MIN_SEL);
437                 set_reg_field_value(v_total_cntl,
438                                 0,
439                                 CRTC_V_TOTAL_CONTROL,
440                                 CRTC_V_TOTAL_MAX_SEL);
441                 set_reg_field_value(v_total_min,
442                                 0,
443                                 CRTC_V_TOTAL_MIN,
444                                 CRTC_V_TOTAL_MIN);
445                 set_reg_field_value(v_total_max,
446                                 0,
447                                 CRTC_V_TOTAL_MAX,
448                                 CRTC_V_TOTAL_MAX);
449                 set_reg_field_value(v_total_cntl,
450                                 0,
451                                 CRTC_V_TOTAL_CONTROL,
452                                 CRTC_FORCE_LOCK_ON_EVENT);
453                 set_reg_field_value(v_total_cntl,
454                                 0,
455                                 CRTC_V_TOTAL_CONTROL,
456                                 CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
457         }
458
459         addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
460         dm_write_reg(tg->ctx, addr, v_total_min);
461
462         addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
463         dm_write_reg(tg->ctx, addr, v_total_max);
464
465         addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL);
466         dm_write_reg(tg->ctx, addr, v_total_cntl);
467 }
468
469 void dce110_timing_generator_set_static_screen_control(
470         struct timing_generator *tg,
471         uint32_t event_triggers,
472         uint32_t num_frames)
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         // By register spec, it only takes 8 bit value
479         if (num_frames > 0xFF)
480                 num_frames = 0xFF;
481
482         addr = CRTC_REG(mmCRTC_STATIC_SCREEN_CONTROL);
483         static_screen_cntl = dm_read_reg(tg->ctx, addr);
484
485         set_reg_field_value(static_screen_cntl,
486                                 event_triggers,
487                                 CRTC_STATIC_SCREEN_CONTROL,
488                                 CRTC_STATIC_SCREEN_EVENT_MASK);
489
490         set_reg_field_value(static_screen_cntl,
491                                 num_frames,
492                                 CRTC_STATIC_SCREEN_CONTROL,
493                                 CRTC_STATIC_SCREEN_FRAME_COUNT);
494
495         dm_write_reg(tg->ctx, addr, static_screen_cntl);
496 }
497
498 /*
499  * get_vblank_counter
500  *
501  * @brief
502  * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
503  * holds the counter of frames.
504  *
505  * @param
506  * struct timing_generator *tg - [in] timing generator which controls the
507  * desired CRTC
508  *
509  * @return
510  * Counter of frames, which should equal to number of vblanks.
511  */
512 uint32_t dce110_timing_generator_get_vblank_counter(struct timing_generator *tg)
513 {
514         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
515         uint32_t addr = CRTC_REG(mmCRTC_STATUS_FRAME_COUNT);
516         uint32_t value = dm_read_reg(tg->ctx, addr);
517         uint32_t field = get_reg_field_value(
518                         value, CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT);
519
520         return field;
521 }
522
523 /*
524  *****************************************************************************
525  *  Function: dce110_timing_generator_get_position
526  *
527  *  @brief
528  *     Returns CRTC vertical/horizontal counters
529  *
530  *  @param [out] position
531  *****************************************************************************
532  */
533 void dce110_timing_generator_get_position(struct timing_generator *tg,
534         struct crtc_position *position)
535 {
536         uint32_t value;
537         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
538
539         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_STATUS_POSITION));
540
541         position->horizontal_count = get_reg_field_value(
542                         value,
543                         CRTC_STATUS_POSITION,
544                         CRTC_HORZ_COUNT);
545
546         position->vertical_count = get_reg_field_value(
547                         value,
548                         CRTC_STATUS_POSITION,
549                         CRTC_VERT_COUNT);
550
551         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_NOM_VERT_POSITION));
552
553         position->nominal_vcount = get_reg_field_value(
554                         value,
555                         CRTC_NOM_VERT_POSITION,
556                         CRTC_VERT_COUNT_NOM);
557 }
558
559 /*
560  *****************************************************************************
561  *  Function: get_crtc_scanoutpos
562  *
563  *  @brief
564  *     Returns CRTC vertical/horizontal counters
565  *
566  *  @param [out] vpos, hpos
567  *****************************************************************************
568  */
569 void dce110_timing_generator_get_crtc_scanoutpos(
570         struct timing_generator *tg,
571         uint32_t *v_blank_start,
572         uint32_t *v_blank_end,
573         uint32_t *h_position,
574         uint32_t *v_position)
575 {
576         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
577         struct crtc_position position;
578
579         uint32_t value  = dm_read_reg(tg->ctx,
580                         CRTC_REG(mmCRTC_V_BLANK_START_END));
581
582         *v_blank_start = get_reg_field_value(value,
583                                              CRTC_V_BLANK_START_END,
584                                              CRTC_V_BLANK_START);
585         *v_blank_end = get_reg_field_value(value,
586                                            CRTC_V_BLANK_START_END,
587                                            CRTC_V_BLANK_END);
588
589         dce110_timing_generator_get_position(
590                         tg, &position);
591
592         *h_position = position.horizontal_count;
593         *v_position = position.vertical_count;
594 }
595
596 /* TODO: is it safe to assume that mask/shift of Primary and Underlay
597  * are the same?
598  * For example: today CRTC_H_TOTAL == CRTCV_H_TOTAL but is it always
599  * guaranteed? */
600 void dce110_timing_generator_program_blanking(
601         struct timing_generator *tg,
602         const struct dc_crtc_timing *timing)
603 {
604         uint32_t vsync_offset = timing->v_border_bottom +
605                         timing->v_front_porch;
606         uint32_t v_sync_start =timing->v_addressable + vsync_offset;
607
608         uint32_t hsync_offset = timing->h_border_right +
609                         timing->h_front_porch;
610         uint32_t h_sync_start = timing->h_addressable + hsync_offset;
611         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
612
613         struct dc_context *ctx = tg->ctx;
614         uint32_t value = 0;
615         uint32_t addr = 0;
616         uint32_t tmp = 0;
617
618         addr = CRTC_REG(mmCRTC_H_TOTAL);
619         value = dm_read_reg(ctx, addr);
620         set_reg_field_value(
621                 value,
622                 timing->h_total - 1,
623                 CRTC_H_TOTAL,
624                 CRTC_H_TOTAL);
625         dm_write_reg(ctx, addr, value);
626
627         addr = CRTC_REG(mmCRTC_V_TOTAL);
628         value = dm_read_reg(ctx, addr);
629         set_reg_field_value(
630                 value,
631                 timing->v_total - 1,
632                 CRTC_V_TOTAL,
633                 CRTC_V_TOTAL);
634         dm_write_reg(ctx, addr, value);
635
636         /* In case of V_TOTAL_CONTROL is on, make sure V_TOTAL_MAX and
637          * V_TOTAL_MIN are equal to V_TOTAL.
638          */
639         addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
640         value = dm_read_reg(ctx, addr);
641         set_reg_field_value(
642                 value,
643                 timing->v_total - 1,
644                 CRTC_V_TOTAL_MAX,
645                 CRTC_V_TOTAL_MAX);
646         dm_write_reg(ctx, addr, value);
647
648         addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
649         value = dm_read_reg(ctx, addr);
650         set_reg_field_value(
651                 value,
652                 timing->v_total - 1,
653                 CRTC_V_TOTAL_MIN,
654                 CRTC_V_TOTAL_MIN);
655         dm_write_reg(ctx, addr, value);
656
657         addr = CRTC_REG(mmCRTC_H_BLANK_START_END);
658         value = dm_read_reg(ctx, addr);
659
660         tmp = timing->h_total -
661                 (h_sync_start + timing->h_border_left);
662
663         set_reg_field_value(
664                 value,
665                 tmp,
666                 CRTC_H_BLANK_START_END,
667                 CRTC_H_BLANK_END);
668
669         tmp = tmp + timing->h_addressable +
670                 timing->h_border_left + timing->h_border_right;
671
672         set_reg_field_value(
673                 value,
674                 tmp,
675                 CRTC_H_BLANK_START_END,
676                 CRTC_H_BLANK_START);
677
678         dm_write_reg(ctx, addr, value);
679
680         addr = CRTC_REG(mmCRTC_V_BLANK_START_END);
681         value = dm_read_reg(ctx, addr);
682
683         tmp = timing->v_total - (v_sync_start + timing->v_border_top);
684
685         set_reg_field_value(
686                 value,
687                 tmp,
688                 CRTC_V_BLANK_START_END,
689                 CRTC_V_BLANK_END);
690
691         tmp = tmp + timing->v_addressable + timing->v_border_top +
692                 timing->v_border_bottom;
693
694         set_reg_field_value(
695                 value,
696                 tmp,
697                 CRTC_V_BLANK_START_END,
698                 CRTC_V_BLANK_START);
699
700         dm_write_reg(ctx, addr, value);
701 }
702
703 void dce110_timing_generator_set_test_pattern(
704         struct timing_generator *tg,
705         /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
706          * because this is not DP-specific (which is probably somewhere in DP
707          * encoder) */
708         enum controller_dp_test_pattern test_pattern,
709         enum dc_color_depth color_depth)
710 {
711         struct dc_context *ctx = tg->ctx;
712         uint32_t value;
713         uint32_t addr;
714         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
715         enum test_pattern_color_format bit_depth;
716         enum test_pattern_dyn_range dyn_range;
717         enum test_pattern_mode mode;
718         /* color ramp generator mixes 16-bits color */
719         uint32_t src_bpc = 16;
720         /* requested bpc */
721         uint32_t dst_bpc;
722         uint32_t index;
723         /* RGB values of the color bars.
724          * Produce two RGB colors: RGB0 - white (all Fs)
725          * and RGB1 - black (all 0s)
726          * (three RGB components for two colors)
727          */
728         uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
729                                                 0x0000, 0x0000};
730         /* dest color (converted to the specified color format) */
731         uint16_t dst_color[6];
732         uint32_t inc_base;
733
734         /* translate to bit depth */
735         switch (color_depth) {
736         case COLOR_DEPTH_666:
737                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
738         break;
739         case COLOR_DEPTH_888:
740                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
741         break;
742         case COLOR_DEPTH_101010:
743                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
744         break;
745         case COLOR_DEPTH_121212:
746                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
747         break;
748         default:
749                 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
750         break;
751         }
752
753         switch (test_pattern) {
754         case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
755         case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
756         {
757                 dyn_range = (test_pattern ==
758                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
759                                 TEST_PATTERN_DYN_RANGE_CEA :
760                                 TEST_PATTERN_DYN_RANGE_VESA);
761                 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
762                 value = 0;
763                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
764
765                 set_reg_field_value(
766                         value,
767                         6,
768                         CRTC_TEST_PATTERN_PARAMETERS,
769                         CRTC_TEST_PATTERN_VRES);
770                 set_reg_field_value(
771                         value,
772                         6,
773                         CRTC_TEST_PATTERN_PARAMETERS,
774                         CRTC_TEST_PATTERN_HRES);
775
776                 dm_write_reg(ctx, addr, value);
777
778                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
779                 value = 0;
780
781                 set_reg_field_value(
782                         value,
783                         1,
784                         CRTC_TEST_PATTERN_CONTROL,
785                         CRTC_TEST_PATTERN_EN);
786
787                 set_reg_field_value(
788                         value,
789                         mode,
790                         CRTC_TEST_PATTERN_CONTROL,
791                         CRTC_TEST_PATTERN_MODE);
792
793                 set_reg_field_value(
794                         value,
795                         dyn_range,
796                         CRTC_TEST_PATTERN_CONTROL,
797                         CRTC_TEST_PATTERN_DYNAMIC_RANGE);
798                 set_reg_field_value(
799                         value,
800                         bit_depth,
801                         CRTC_TEST_PATTERN_CONTROL,
802                         CRTC_TEST_PATTERN_COLOR_FORMAT);
803                 dm_write_reg(ctx, addr, value);
804         }
805         break;
806
807         case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
808         case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
809         {
810                 mode = (test_pattern ==
811                         CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
812                         TEST_PATTERN_MODE_VERTICALBARS :
813                         TEST_PATTERN_MODE_HORIZONTALBARS);
814
815                 switch (bit_depth) {
816                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
817                         dst_bpc = 6;
818                 break;
819                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
820                         dst_bpc = 8;
821                 break;
822                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
823                         dst_bpc = 10;
824                 break;
825                 default:
826                         dst_bpc = 8;
827                 break;
828                 }
829
830                 /* adjust color to the required colorFormat */
831                 for (index = 0; index < 6; index++) {
832                         /* dst = 2^dstBpc * src / 2^srcBpc = src >>
833                          * (srcBpc - dstBpc);
834                          */
835                         dst_color[index] =
836                                 src_color[index] >> (src_bpc - dst_bpc);
837                 /* CRTC_TEST_PATTERN_DATA has 16 bits,
838                  * lowest 6 are hardwired to ZERO
839                  * color bits should be left aligned aligned to MSB
840                  * XXXXXXXXXX000000 for 10 bit,
841                  * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
842                  */
843                         dst_color[index] <<= (16 - dst_bpc);
844                 }
845
846                 value = 0;
847                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
848                 dm_write_reg(ctx, addr, value);
849
850                 /* We have to write the mask before data, similar to pipeline.
851                  * For example, for 8 bpc, if we want RGB0 to be magenta,
852                  * and RGB1 to be cyan,
853                  * we need to make 7 writes:
854                  * MASK   DATA
855                  * 000001 00000000 00000000                     set mask to R0
856                  * 000010 11111111 00000000     R0 255, 0xFF00, set mask to G0
857                  * 000100 00000000 00000000     G0 0,   0x0000, set mask to B0
858                  * 001000 11111111 00000000     B0 255, 0xFF00, set mask to R1
859                  * 010000 00000000 00000000     R1 0,   0x0000, set mask to G1
860                  * 100000 11111111 00000000     G1 255, 0xFF00, set mask to B1
861                  * 100000 11111111 00000000     B1 255, 0xFF00
862                  *
863                  * we will make a loop of 6 in which we prepare the mask,
864                  * then write, then prepare the color for next write.
865                  * first iteration will write mask only,
866                  * but each next iteration color prepared in
867                  * previous iteration will be written within new mask,
868                  * the last component will written separately,
869                  * mask is not changing between 6th and 7th write
870                  * and color will be prepared by last iteration
871                  */
872
873                 /* write color, color values mask in CRTC_TEST_PATTERN_MASK
874                  * is B1, G1, R1, B0, G0, R0
875                  */
876                 value = 0;
877                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR);
878                 for (index = 0; index < 6; index++) {
879                         /* prepare color mask, first write PATTERN_DATA
880                          * will have all zeros
881                          */
882                         set_reg_field_value(
883                                 value,
884                                 (1 << index),
885                                 CRTC_TEST_PATTERN_COLOR,
886                                 CRTC_TEST_PATTERN_MASK);
887                         /* write color component */
888                         dm_write_reg(ctx, addr, value);
889                         /* prepare next color component,
890                          * will be written in the next iteration
891                          */
892                         set_reg_field_value(
893                                 value,
894                                 dst_color[index],
895                                 CRTC_TEST_PATTERN_COLOR,
896                                 CRTC_TEST_PATTERN_DATA);
897                 }
898                 /* write last color component,
899                  * it's been already prepared in the loop
900                  */
901                 dm_write_reg(ctx, addr, value);
902
903                 /* enable test pattern */
904                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
905                 value = 0;
906
907                 set_reg_field_value(
908                         value,
909                         1,
910                         CRTC_TEST_PATTERN_CONTROL,
911                         CRTC_TEST_PATTERN_EN);
912
913                 set_reg_field_value(
914                         value,
915                         mode,
916                         CRTC_TEST_PATTERN_CONTROL,
917                         CRTC_TEST_PATTERN_MODE);
918
919                 set_reg_field_value(
920                         value,
921                         0,
922                         CRTC_TEST_PATTERN_CONTROL,
923                         CRTC_TEST_PATTERN_DYNAMIC_RANGE);
924
925                 set_reg_field_value(
926                         value,
927                         bit_depth,
928                         CRTC_TEST_PATTERN_CONTROL,
929                         CRTC_TEST_PATTERN_COLOR_FORMAT);
930
931                 dm_write_reg(ctx, addr, value);
932         }
933         break;
934
935         case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
936         {
937                 mode = (bit_depth ==
938                         TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
939                         TEST_PATTERN_MODE_DUALRAMP_RGB :
940                         TEST_PATTERN_MODE_SINGLERAMP_RGB);
941
942                 switch (bit_depth) {
943                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
944                         dst_bpc = 6;
945                 break;
946                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
947                         dst_bpc = 8;
948                 break;
949                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
950                         dst_bpc = 10;
951                 break;
952                 default:
953                         dst_bpc = 8;
954                 break;
955                 }
956
957                 /* increment for the first ramp for one color gradation
958                  * 1 gradation for 6-bit color is 2^10
959                  * gradations in 16-bit color
960                  */
961                 inc_base = (src_bpc - dst_bpc);
962
963                 value = 0;
964                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
965
966                 switch (bit_depth) {
967                 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
968                 {
969                         set_reg_field_value(
970                                 value,
971                                 inc_base,
972                                 CRTC_TEST_PATTERN_PARAMETERS,
973                                 CRTC_TEST_PATTERN_INC0);
974                         set_reg_field_value(
975                                 value,
976                                 0,
977                                 CRTC_TEST_PATTERN_PARAMETERS,
978                                 CRTC_TEST_PATTERN_INC1);
979                         set_reg_field_value(
980                                 value,
981                                 6,
982                                 CRTC_TEST_PATTERN_PARAMETERS,
983                                 CRTC_TEST_PATTERN_HRES);
984                         set_reg_field_value(
985                                 value,
986                                 6,
987                                 CRTC_TEST_PATTERN_PARAMETERS,
988                                 CRTC_TEST_PATTERN_VRES);
989                         set_reg_field_value(
990                                 value,
991                                 0,
992                                 CRTC_TEST_PATTERN_PARAMETERS,
993                                 CRTC_TEST_PATTERN_RAMP0_OFFSET);
994                 }
995                 break;
996                 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
997                 {
998                         set_reg_field_value(
999                                 value,
1000                                 inc_base,
1001                                 CRTC_TEST_PATTERN_PARAMETERS,
1002                                 CRTC_TEST_PATTERN_INC0);
1003                         set_reg_field_value(
1004                                 value,
1005                                 0,
1006                                 CRTC_TEST_PATTERN_PARAMETERS,
1007                                 CRTC_TEST_PATTERN_INC1);
1008                         set_reg_field_value(
1009                                 value,
1010                                 8,
1011                                 CRTC_TEST_PATTERN_PARAMETERS,
1012                                 CRTC_TEST_PATTERN_HRES);
1013                         set_reg_field_value(
1014                                 value,
1015                                 6,
1016                                 CRTC_TEST_PATTERN_PARAMETERS,
1017                                 CRTC_TEST_PATTERN_VRES);
1018                         set_reg_field_value(
1019                                 value,
1020                                 0,
1021                                 CRTC_TEST_PATTERN_PARAMETERS,
1022                                 CRTC_TEST_PATTERN_RAMP0_OFFSET);
1023                 }
1024                 break;
1025                 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1026                 {
1027                         set_reg_field_value(
1028                                 value,
1029                                 inc_base,
1030                                 CRTC_TEST_PATTERN_PARAMETERS,
1031                                 CRTC_TEST_PATTERN_INC0);
1032                         set_reg_field_value(
1033                                 value,
1034                                 inc_base + 2,
1035                                 CRTC_TEST_PATTERN_PARAMETERS,
1036                                 CRTC_TEST_PATTERN_INC1);
1037                         set_reg_field_value(
1038                                 value,
1039                                 8,
1040                                 CRTC_TEST_PATTERN_PARAMETERS,
1041                                 CRTC_TEST_PATTERN_HRES);
1042                         set_reg_field_value(
1043                                 value,
1044                                 5,
1045                                 CRTC_TEST_PATTERN_PARAMETERS,
1046                                 CRTC_TEST_PATTERN_VRES);
1047                         set_reg_field_value(
1048                                 value,
1049                                 384 << 6,
1050                                 CRTC_TEST_PATTERN_PARAMETERS,
1051                                 CRTC_TEST_PATTERN_RAMP0_OFFSET);
1052                 }
1053                 break;
1054                 default:
1055                 break;
1056                 }
1057                 dm_write_reg(ctx, addr, value);
1058
1059                 value = 0;
1060                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR);
1061                 dm_write_reg(ctx, addr, value);
1062
1063                 /* enable test pattern */
1064                 addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
1065                 value = 0;
1066
1067                 set_reg_field_value(
1068                         value,
1069                         1,
1070                         CRTC_TEST_PATTERN_CONTROL,
1071                         CRTC_TEST_PATTERN_EN);
1072
1073                 set_reg_field_value(
1074                         value,
1075                         mode,
1076                         CRTC_TEST_PATTERN_CONTROL,
1077                         CRTC_TEST_PATTERN_MODE);
1078
1079                 set_reg_field_value(
1080                         value,
1081                         0,
1082                         CRTC_TEST_PATTERN_CONTROL,
1083                         CRTC_TEST_PATTERN_DYNAMIC_RANGE);
1084                 /* add color depth translation here */
1085                 set_reg_field_value(
1086                         value,
1087                         bit_depth,
1088                         CRTC_TEST_PATTERN_CONTROL,
1089                         CRTC_TEST_PATTERN_COLOR_FORMAT);
1090
1091                 dm_write_reg(ctx, addr, value);
1092         }
1093         break;
1094         case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1095         {
1096                 value = 0;
1097                 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL), value);
1098                 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_COLOR), value);
1099                 dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS),
1100                                 value);
1101         }
1102         break;
1103         default:
1104         break;
1105         }
1106 }
1107
1108 /*
1109  * dce110_timing_generator_validate_timing
1110  * The timing generators support a maximum display size of is 8192 x 8192 pixels,
1111  * including both active display and blanking periods. Check H Total and V Total.
1112  */
1113 bool dce110_timing_generator_validate_timing(
1114         struct timing_generator *tg,
1115         const struct dc_crtc_timing *timing,
1116         enum signal_type signal)
1117 {
1118         uint32_t h_blank;
1119         uint32_t h_back_porch, hsync_offset, h_sync_start;
1120
1121         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1122
1123         ASSERT(timing != NULL);
1124
1125         if (!timing)
1126                 return false;
1127
1128         hsync_offset = timing->h_border_right + timing->h_front_porch;
1129         h_sync_start = timing->h_addressable + hsync_offset;
1130
1131         /* Currently we don't support 3D, so block all 3D timings */
1132         if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE)
1133                 return false;
1134
1135         /* Temporarily blocking interlacing mode until it's supported */
1136         if (timing->flags.INTERLACE == 1)
1137                 return false;
1138
1139         /* Check maximum number of pixels supported by Timing Generator
1140          * (Currently will never fail, in order to fail needs display which
1141          * needs more than 8192 horizontal and
1142          * more than 8192 vertical total pixels)
1143          */
1144         if (timing->h_total > tg110->max_h_total ||
1145                 timing->v_total > tg110->max_v_total)
1146                 return false;
1147
1148         h_blank = (timing->h_total - timing->h_addressable -
1149                 timing->h_border_right -
1150                 timing->h_border_left);
1151
1152         if (h_blank < tg110->min_h_blank)
1153                 return false;
1154
1155         if (timing->h_front_porch < tg110->min_h_front_porch)
1156                 return false;
1157
1158         h_back_porch = h_blank - (h_sync_start -
1159                 timing->h_addressable -
1160                 timing->h_border_right -
1161                 timing->h_sync_width);
1162
1163         if (h_back_porch < tg110->min_h_back_porch)
1164                 return false;
1165
1166         return true;
1167 }
1168
1169 /*
1170  * Wait till we are at the beginning of VBlank.
1171  */
1172 void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg)
1173 {
1174         /* We want to catch beginning of VBlank here, so if the first try are
1175          * in VBlank, we might be very close to Active, in this case wait for
1176          * another frame
1177          */
1178         while (dce110_timing_generator_is_in_vertical_blank(tg)) {
1179                 if (!dce110_timing_generator_is_counter_moving(tg)) {
1180                         /* error - no point to wait if counter is not moving */
1181                         break;
1182                 }
1183         }
1184
1185         while (!dce110_timing_generator_is_in_vertical_blank(tg)) {
1186                 if (!dce110_timing_generator_is_counter_moving(tg)) {
1187                         /* error - no point to wait if counter is not moving */
1188                         break;
1189                 }
1190         }
1191 }
1192
1193 /*
1194  * Wait till we are in VActive (anywhere in VActive)
1195  */
1196 void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg)
1197 {
1198         while (dce110_timing_generator_is_in_vertical_blank(tg)) {
1199                 if (!dce110_timing_generator_is_counter_moving(tg)) {
1200                         /* error - no point to wait if counter is not moving */
1201                         break;
1202                 }
1203         }
1204 }
1205
1206 /*
1207  *****************************************************************************
1208  *  Function: dce110_timing_generator_setup_global_swap_lock
1209  *
1210  *  @brief
1211  *     Setups Global Swap Lock group for current pipe
1212  *     Pipe can join or leave GSL group, become a TimingServer or TimingClient
1213  *
1214  *  @param [in] gsl_params: setup data
1215  *****************************************************************************
1216  */
1217 void dce110_timing_generator_setup_global_swap_lock(
1218         struct timing_generator *tg,
1219         const struct dcp_gsl_params *gsl_params)
1220 {
1221         uint32_t value;
1222         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1223         uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1224         uint32_t check_point = FLIP_READY_BACK_LOOKUP;
1225
1226         value = dm_read_reg(tg->ctx, address);
1227
1228         /* This pipe will belong to GSL Group zero. */
1229         set_reg_field_value(value,
1230                             1,
1231                             DCP_GSL_CONTROL,
1232                             DCP_GSL0_EN);
1233
1234         set_reg_field_value(value,
1235                             gsl_params->gsl_master == tg->inst,
1236                             DCP_GSL_CONTROL,
1237                             DCP_GSL_MASTER_EN);
1238
1239         set_reg_field_value(value,
1240                             HFLIP_READY_DELAY,
1241                             DCP_GSL_CONTROL,
1242                             DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1243
1244         /* Keep signal low (pending high) during 6 lines.
1245          * Also defines minimum interval before re-checking signal. */
1246         set_reg_field_value(value,
1247                             HFLIP_CHECK_DELAY,
1248                             DCP_GSL_CONTROL,
1249                             DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1250
1251         dm_write_reg(tg->ctx, CRTC_REG(mmDCP_GSL_CONTROL), value);
1252         value = 0;
1253
1254         set_reg_field_value(value,
1255                             gsl_params->gsl_master,
1256                             DCIO_GSL0_CNTL,
1257                             DCIO_GSL0_VSYNC_SEL);
1258
1259         set_reg_field_value(value,
1260                             0,
1261                             DCIO_GSL0_CNTL,
1262                             DCIO_GSL0_TIMING_SYNC_SEL);
1263
1264         set_reg_field_value(value,
1265                             0,
1266                             DCIO_GSL0_CNTL,
1267                             DCIO_GSL0_GLOBAL_UNLOCK_SEL);
1268
1269         dm_write_reg(tg->ctx, CRTC_REG(mmDCIO_GSL0_CNTL), value);
1270
1271
1272         {
1273                 uint32_t value_crtc_vtotal;
1274
1275                 value_crtc_vtotal = dm_read_reg(tg->ctx,
1276                                 CRTC_REG(mmCRTC_V_TOTAL));
1277
1278                 set_reg_field_value(value,
1279                                     0,/* DCP_GSL_PURPOSE_SURFACE_FLIP */
1280                                     DCP_GSL_CONTROL,
1281                                     DCP_GSL_SYNC_SOURCE);
1282
1283                 /* Checkpoint relative to end of frame */
1284                 check_point = get_reg_field_value(value_crtc_vtotal,
1285                                                   CRTC_V_TOTAL,
1286                                                   CRTC_V_TOTAL);
1287
1288                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_GSL_WINDOW), 0);
1289         }
1290
1291         set_reg_field_value(value,
1292                             1,
1293                             DCP_GSL_CONTROL,
1294                             DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
1295
1296         dm_write_reg(tg->ctx, address, value);
1297
1298         /********************************************************************/
1299         address = CRTC_REG(mmCRTC_GSL_CONTROL);
1300
1301         value = dm_read_reg(tg->ctx, address);
1302         set_reg_field_value(value,
1303                             check_point - FLIP_READY_BACK_LOOKUP,
1304                             CRTC_GSL_CONTROL,
1305                             CRTC_GSL_CHECK_LINE_NUM);
1306
1307         set_reg_field_value(value,
1308                             VFLIP_READY_DELAY,
1309                             CRTC_GSL_CONTROL,
1310                             CRTC_GSL_FORCE_DELAY);
1311
1312         dm_write_reg(tg->ctx, address, value);
1313 }
1314
1315 void dce110_timing_generator_tear_down_global_swap_lock(
1316         struct timing_generator *tg)
1317 {
1318         /* Clear all the register writes done by
1319          * dce110_timing_generator_setup_global_swap_lock
1320          */
1321
1322         uint32_t value;
1323         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1324         uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1325
1326         value = 0;
1327
1328         /* This pipe will belong to GSL Group zero. */
1329         /* Settig HW default values from reg specs */
1330         set_reg_field_value(value,
1331                         0,
1332                         DCP_GSL_CONTROL,
1333                         DCP_GSL0_EN);
1334
1335         set_reg_field_value(value,
1336                         0,
1337                         DCP_GSL_CONTROL,
1338                         DCP_GSL_MASTER_EN);
1339
1340         set_reg_field_value(value,
1341                         0x2,
1342                         DCP_GSL_CONTROL,
1343                         DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1344
1345         set_reg_field_value(value,
1346                         0x6,
1347                         DCP_GSL_CONTROL,
1348                         DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1349
1350         /* Restore DCP_GSL_PURPOSE_SURFACE_FLIP */
1351         {
1352                 dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_V_TOTAL));
1353
1354                 set_reg_field_value(value,
1355                                 0,
1356                                 DCP_GSL_CONTROL,
1357                                 DCP_GSL_SYNC_SOURCE);
1358         }
1359
1360         set_reg_field_value(value,
1361                         0,
1362                         DCP_GSL_CONTROL,
1363                         DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
1364
1365         dm_write_reg(tg->ctx, address, value);
1366
1367         /********************************************************************/
1368         address = CRTC_REG(mmCRTC_GSL_CONTROL);
1369
1370         value = 0;
1371         set_reg_field_value(value,
1372                         0,
1373                         CRTC_GSL_CONTROL,
1374                         CRTC_GSL_CHECK_LINE_NUM);
1375
1376         set_reg_field_value(value,
1377                         0x2,
1378                         CRTC_GSL_CONTROL,
1379                         CRTC_GSL_FORCE_DELAY);
1380
1381         dm_write_reg(tg->ctx, address, value);
1382 }
1383 /*
1384  *****************************************************************************
1385  *  Function: is_counter_moving
1386  *
1387  *  @brief
1388  *     check if the timing generator is currently going
1389  *
1390  *  @return
1391  *     true if currently going, false if currently paused or stopped.
1392  *
1393  *****************************************************************************
1394  */
1395 bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg)
1396 {
1397         struct crtc_position position1, position2;
1398
1399         tg->funcs->get_position(tg, &position1);
1400         tg->funcs->get_position(tg, &position2);
1401
1402         if (position1.horizontal_count == position2.horizontal_count &&
1403                 position1.vertical_count == position2.vertical_count)
1404                 return false;
1405         else
1406                 return true;
1407 }
1408
1409 void dce110_timing_generator_enable_advanced_request(
1410         struct timing_generator *tg,
1411         bool enable,
1412         const struct dc_crtc_timing *timing)
1413 {
1414         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1415         uint32_t addr = CRTC_REG(mmCRTC_START_LINE_CONTROL);
1416         uint32_t value = dm_read_reg(tg->ctx, addr);
1417
1418         if (enable) {
1419                 set_reg_field_value(
1420                         value,
1421                         0,
1422                         CRTC_START_LINE_CONTROL,
1423                         CRTC_LEGACY_REQUESTOR_EN);
1424         } else {
1425                 set_reg_field_value(
1426                         value,
1427                         1,
1428                         CRTC_START_LINE_CONTROL,
1429                         CRTC_LEGACY_REQUESTOR_EN);
1430         }
1431
1432         if ((timing->v_sync_width + timing->v_front_porch) <= 3) {
1433                 set_reg_field_value(
1434                         value,
1435                         3,
1436                         CRTC_START_LINE_CONTROL,
1437                         CRTC_ADVANCED_START_LINE_POSITION);
1438                 set_reg_field_value(
1439                         value,
1440                         0,
1441                         CRTC_START_LINE_CONTROL,
1442                         CRTC_PREFETCH_EN);
1443         } else {
1444                 set_reg_field_value(
1445                         value,
1446                         4,
1447                         CRTC_START_LINE_CONTROL,
1448                         CRTC_ADVANCED_START_LINE_POSITION);
1449                 set_reg_field_value(
1450                         value,
1451                         1,
1452                         CRTC_START_LINE_CONTROL,
1453                         CRTC_PREFETCH_EN);
1454         }
1455
1456         set_reg_field_value(
1457                 value,
1458                 1,
1459                 CRTC_START_LINE_CONTROL,
1460                 CRTC_PROGRESSIVE_START_LINE_EARLY);
1461
1462         set_reg_field_value(
1463                 value,
1464                 1,
1465                 CRTC_START_LINE_CONTROL,
1466                 CRTC_INTERLACE_START_LINE_EARLY);
1467
1468         dm_write_reg(tg->ctx, addr, value);
1469 }
1470
1471 /*TODO: Figure out if we need this function. */
1472 void dce110_timing_generator_set_lock_master(struct timing_generator *tg,
1473                 bool lock)
1474 {
1475         struct dc_context *ctx = tg->ctx;
1476         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1477         uint32_t addr = CRTC_REG(mmCRTC_MASTER_UPDATE_LOCK);
1478         uint32_t value = dm_read_reg(ctx, addr);
1479
1480         set_reg_field_value(
1481                 value,
1482                 lock ? 1 : 0,
1483                 CRTC_MASTER_UPDATE_LOCK,
1484                 MASTER_UPDATE_LOCK);
1485
1486         dm_write_reg(ctx, addr, value);
1487 }
1488
1489 void dce110_timing_generator_enable_reset_trigger(
1490         struct timing_generator *tg,
1491         int source_tg_inst)
1492 {
1493         uint32_t value;
1494         uint32_t rising_edge = 0;
1495         uint32_t falling_edge = 0;
1496         enum trigger_source_select trig_src_select = TRIGGER_SOURCE_SELECT_LOGIC_ZERO;
1497         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1498
1499         /* Setup trigger edge */
1500         {
1501                 uint32_t pol_value = dm_read_reg(tg->ctx,
1502                                 CRTC_REG(mmCRTC_V_SYNC_A_CNTL));
1503
1504                 /* Register spec has reversed definition:
1505                  *      0 for positive, 1 for negative */
1506                 if (get_reg_field_value(pol_value,
1507                                 CRTC_V_SYNC_A_CNTL,
1508                                 CRTC_V_SYNC_A_POL) == 0) {
1509                         rising_edge = 1;
1510                 } else {
1511                         falling_edge = 1;
1512                 }
1513         }
1514
1515         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
1516
1517         trig_src_select = TRIGGER_SOURCE_SELECT_GSL_GROUP0;
1518
1519         set_reg_field_value(value,
1520                         trig_src_select,
1521                         CRTC_TRIGB_CNTL,
1522                         CRTC_TRIGB_SOURCE_SELECT);
1523
1524         set_reg_field_value(value,
1525                         TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
1526                         CRTC_TRIGB_CNTL,
1527                         CRTC_TRIGB_POLARITY_SELECT);
1528
1529         set_reg_field_value(value,
1530                         rising_edge,
1531                         CRTC_TRIGB_CNTL,
1532                         CRTC_TRIGB_RISING_EDGE_DETECT_CNTL);
1533
1534         set_reg_field_value(value,
1535                         falling_edge,
1536                         CRTC_TRIGB_CNTL,
1537                         CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL);
1538
1539         set_reg_field_value(value,
1540                         0, /* send every signal */
1541                         CRTC_TRIGB_CNTL,
1542                         CRTC_TRIGB_FREQUENCY_SELECT);
1543
1544         set_reg_field_value(value,
1545                         0, /* no delay */
1546                         CRTC_TRIGB_CNTL,
1547                         CRTC_TRIGB_DELAY);
1548
1549         set_reg_field_value(value,
1550                         1, /* clear trigger status */
1551                         CRTC_TRIGB_CNTL,
1552                         CRTC_TRIGB_CLEAR);
1553
1554         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
1555
1556         /**************************************************************/
1557
1558         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1559
1560         set_reg_field_value(value,
1561                         2, /* force H count to H_TOTAL and V count to V_TOTAL */
1562                         CRTC_FORCE_COUNT_NOW_CNTL,
1563                         CRTC_FORCE_COUNT_NOW_MODE);
1564
1565         set_reg_field_value(value,
1566                         1, /* TriggerB - we never use TriggerA */
1567                         CRTC_FORCE_COUNT_NOW_CNTL,
1568                         CRTC_FORCE_COUNT_NOW_TRIG_SEL);
1569
1570         set_reg_field_value(value,
1571                         1, /* clear trigger status */
1572                         CRTC_FORCE_COUNT_NOW_CNTL,
1573                         CRTC_FORCE_COUNT_NOW_CLEAR);
1574
1575         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1576 }
1577
1578 void dce110_timing_generator_enable_crtc_reset(
1579                 struct timing_generator *tg,
1580                 int source_tg_inst,
1581                 struct crtc_trigger_info *crtc_tp)
1582 {
1583         uint32_t value = 0;
1584         uint32_t rising_edge = 0;
1585         uint32_t falling_edge = 0;
1586         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1587
1588         /* Setup trigger edge */
1589         switch (crtc_tp->event) {
1590         case CRTC_EVENT_VSYNC_RISING:
1591                         rising_edge = 1;
1592                         break;
1593
1594         case CRTC_EVENT_VSYNC_FALLING:
1595                 falling_edge = 1;
1596                 break;
1597         }
1598
1599         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
1600
1601         set_reg_field_value(value,
1602                             source_tg_inst,
1603                             CRTC_TRIGB_CNTL,
1604                             CRTC_TRIGB_SOURCE_SELECT);
1605
1606         set_reg_field_value(value,
1607                             TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
1608                             CRTC_TRIGB_CNTL,
1609                             CRTC_TRIGB_POLARITY_SELECT);
1610
1611         set_reg_field_value(value,
1612                             rising_edge,
1613                             CRTC_TRIGB_CNTL,
1614                             CRTC_TRIGB_RISING_EDGE_DETECT_CNTL);
1615
1616         set_reg_field_value(value,
1617                             falling_edge,
1618                             CRTC_TRIGB_CNTL,
1619                             CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL);
1620
1621         set_reg_field_value(value,
1622                             1, /* clear trigger status */
1623                             CRTC_TRIGB_CNTL,
1624                             CRTC_TRIGB_CLEAR);
1625
1626         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
1627
1628         /**************************************************************/
1629
1630         switch (crtc_tp->delay) {
1631         case TRIGGER_DELAY_NEXT_LINE:
1632                 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1633
1634                 set_reg_field_value(value,
1635                                     0, /* force H count to H_TOTAL and V count to V_TOTAL */
1636                                     CRTC_FORCE_COUNT_NOW_CNTL,
1637                                     CRTC_FORCE_COUNT_NOW_MODE);
1638
1639                 set_reg_field_value(value,
1640                                     0, /* TriggerB - we never use TriggerA */
1641                                     CRTC_FORCE_COUNT_NOW_CNTL,
1642                                     CRTC_FORCE_COUNT_NOW_TRIG_SEL);
1643
1644                 set_reg_field_value(value,
1645                                     1, /* clear trigger status */
1646                                     CRTC_FORCE_COUNT_NOW_CNTL,
1647                                     CRTC_FORCE_COUNT_NOW_CLEAR);
1648
1649                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1650
1651                 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
1652
1653                 set_reg_field_value(value,
1654                                     1,
1655                                     CRTC_VERT_SYNC_CONTROL,
1656                                     CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
1657
1658                 set_reg_field_value(value,
1659                                     2,
1660                                     CRTC_VERT_SYNC_CONTROL,
1661                                     CRTC_AUTO_FORCE_VSYNC_MODE);
1662
1663                 break;
1664
1665         case TRIGGER_DELAY_NEXT_PIXEL:
1666                 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
1667
1668                 set_reg_field_value(value,
1669                                     1,
1670                                     CRTC_VERT_SYNC_CONTROL,
1671                                     CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
1672
1673                 set_reg_field_value(value,
1674                                     0,
1675                                     CRTC_VERT_SYNC_CONTROL,
1676                                     CRTC_AUTO_FORCE_VSYNC_MODE);
1677
1678                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL), value);
1679
1680                 value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1681
1682                 set_reg_field_value(value,
1683                                     2, /* force H count to H_TOTAL and V count to V_TOTAL */
1684                                     CRTC_FORCE_COUNT_NOW_CNTL,
1685                                     CRTC_FORCE_COUNT_NOW_MODE);
1686
1687                 set_reg_field_value(value,
1688                                     1, /* TriggerB - we never use TriggerA */
1689                                     CRTC_FORCE_COUNT_NOW_CNTL,
1690                                     CRTC_FORCE_COUNT_NOW_TRIG_SEL);
1691
1692                 set_reg_field_value(value,
1693                                     1, /* clear trigger status */
1694                                     CRTC_FORCE_COUNT_NOW_CNTL,
1695                                     CRTC_FORCE_COUNT_NOW_CLEAR);
1696
1697                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1698                 break;
1699         }
1700
1701         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE));
1702
1703         set_reg_field_value(value,
1704                             2,
1705                             CRTC_MASTER_UPDATE_MODE,
1706                             MASTER_UPDATE_MODE);
1707
1708         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value);
1709 }
1710 void dce110_timing_generator_disable_reset_trigger(
1711         struct timing_generator *tg)
1712 {
1713         uint32_t value;
1714         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1715
1716         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1717
1718         set_reg_field_value(value,
1719                             0, /* force counter now mode is disabled */
1720                             CRTC_FORCE_COUNT_NOW_CNTL,
1721                             CRTC_FORCE_COUNT_NOW_MODE);
1722
1723         set_reg_field_value(value,
1724                             1, /* clear trigger status */
1725                             CRTC_FORCE_COUNT_NOW_CNTL,
1726                             CRTC_FORCE_COUNT_NOW_CLEAR);
1727
1728         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1729
1730         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
1731
1732         set_reg_field_value(value,
1733                             1,
1734                             CRTC_VERT_SYNC_CONTROL,
1735                             CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
1736
1737         set_reg_field_value(value,
1738                             0,
1739                             CRTC_VERT_SYNC_CONTROL,
1740                             CRTC_AUTO_FORCE_VSYNC_MODE);
1741
1742         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL), value);
1743
1744         /********************************************************************/
1745         value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
1746
1747         set_reg_field_value(value,
1748                             TRIGGER_SOURCE_SELECT_LOGIC_ZERO,
1749                             CRTC_TRIGB_CNTL,
1750                             CRTC_TRIGB_SOURCE_SELECT);
1751
1752         set_reg_field_value(value,
1753                             TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
1754                             CRTC_TRIGB_CNTL,
1755                             CRTC_TRIGB_POLARITY_SELECT);
1756
1757         set_reg_field_value(value,
1758                             1, /* clear trigger status */
1759                             CRTC_TRIGB_CNTL,
1760                             CRTC_TRIGB_CLEAR);
1761
1762         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
1763 }
1764
1765 /*
1766  *****************************************************************************
1767  *  @brief
1768  *     Checks whether CRTC triggered reset occurred
1769  *
1770  *  @return
1771  *     true if triggered reset occurred, false otherwise
1772  *****************************************************************************
1773  */
1774 bool dce110_timing_generator_did_triggered_reset_occur(
1775         struct timing_generator *tg)
1776 {
1777         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1778         uint32_t value = dm_read_reg(tg->ctx,
1779                         CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1780         uint32_t value1 = dm_read_reg(tg->ctx,
1781                         CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
1782         bool force = get_reg_field_value(value,
1783                                          CRTC_FORCE_COUNT_NOW_CNTL,
1784                                          CRTC_FORCE_COUNT_NOW_OCCURRED) != 0;
1785         bool vert_sync = get_reg_field_value(value1,
1786                                              CRTC_VERT_SYNC_CONTROL,
1787                                              CRTC_FORCE_VSYNC_NEXT_LINE_OCCURRED) != 0;
1788
1789         return (force || vert_sync);
1790 }
1791
1792 /*
1793  * dce110_timing_generator_disable_vga
1794  * Turn OFF VGA Mode and Timing  - DxVGA_CONTROL
1795  * VGA Mode and VGA Timing is used by VBIOS on CRT Monitors;
1796  */
1797 void dce110_timing_generator_disable_vga(
1798         struct timing_generator *tg)
1799 {
1800         uint32_t addr = 0;
1801         uint32_t value = 0;
1802
1803         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1804
1805         switch (tg110->controller_id) {
1806         case CONTROLLER_ID_D0:
1807                 addr = mmD1VGA_CONTROL;
1808                 break;
1809         case CONTROLLER_ID_D1:
1810                 addr = mmD2VGA_CONTROL;
1811                 break;
1812         case CONTROLLER_ID_D2:
1813                 addr = mmD3VGA_CONTROL;
1814                 break;
1815         case CONTROLLER_ID_D3:
1816                 addr = mmD4VGA_CONTROL;
1817                 break;
1818         case CONTROLLER_ID_D4:
1819                 addr = mmD5VGA_CONTROL;
1820                 break;
1821         case CONTROLLER_ID_D5:
1822                 addr = mmD6VGA_CONTROL;
1823                 break;
1824         default:
1825                 break;
1826         }
1827         value = dm_read_reg(tg->ctx, addr);
1828
1829         set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE);
1830         set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT);
1831         set_reg_field_value(
1832                         value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT);
1833         set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN);
1834
1835         dm_write_reg(tg->ctx, addr, value);
1836 }
1837
1838 /*
1839  * set_overscan_color_black
1840  *
1841  * @param :black_color is one of the color space
1842  *    :this routine will set overscan black color according to the color space.
1843  * @return none
1844  */
1845 void dce110_timing_generator_set_overscan_color_black(
1846         struct timing_generator *tg,
1847         const struct tg_color *color)
1848 {
1849         struct dc_context *ctx = tg->ctx;
1850         uint32_t addr;
1851         uint32_t value = 0;
1852         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1853
1854         set_reg_field_value(
1855                         value,
1856                         color->color_b_cb,
1857                         CRTC_OVERSCAN_COLOR,
1858                         CRTC_OVERSCAN_COLOR_BLUE);
1859
1860         set_reg_field_value(
1861                         value,
1862                         color->color_r_cr,
1863                         CRTC_OVERSCAN_COLOR,
1864                         CRTC_OVERSCAN_COLOR_RED);
1865
1866         set_reg_field_value(
1867                         value,
1868                         color->color_g_y,
1869                         CRTC_OVERSCAN_COLOR,
1870                         CRTC_OVERSCAN_COLOR_GREEN);
1871
1872         addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1873         dm_write_reg(ctx, addr, value);
1874         addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1875         dm_write_reg(ctx, addr, value);
1876         /* This is desirable to have a constant DAC output voltage during the
1877          * blank time that is higher than the 0 volt reference level that the
1878          * DAC outputs when the NBLANK signal
1879          * is asserted low, such as for output to an analog TV. */
1880         addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1881         dm_write_reg(ctx, addr, value);
1882
1883         /* TO DO we have to program EXT registers and we need to know LB DATA
1884          * format because it is used when more 10 , i.e. 12 bits per color
1885          *
1886          * m_mmDxCRTC_OVERSCAN_COLOR_EXT
1887          * m_mmDxCRTC_BLACK_COLOR_EXT
1888          * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
1889          */
1890
1891 }
1892
1893 void dce110_tg_program_blank_color(struct timing_generator *tg,
1894                 const struct tg_color *black_color)
1895 {
1896         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1897         uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1898         uint32_t value = dm_read_reg(tg->ctx, addr);
1899
1900         set_reg_field_value(
1901                 value,
1902                 black_color->color_b_cb,
1903                 CRTC_BLACK_COLOR,
1904                 CRTC_BLACK_COLOR_B_CB);
1905         set_reg_field_value(
1906                 value,
1907                 black_color->color_g_y,
1908                 CRTC_BLACK_COLOR,
1909                 CRTC_BLACK_COLOR_G_Y);
1910         set_reg_field_value(
1911                 value,
1912                 black_color->color_r_cr,
1913                 CRTC_BLACK_COLOR,
1914                 CRTC_BLACK_COLOR_R_CR);
1915
1916         dm_write_reg(tg->ctx, addr, value);
1917
1918         addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1919         dm_write_reg(tg->ctx, addr, value);
1920 }
1921
1922 void dce110_tg_set_overscan_color(struct timing_generator *tg,
1923         const struct tg_color *overscan_color)
1924 {
1925         struct dc_context *ctx = tg->ctx;
1926         uint32_t value = 0;
1927         uint32_t addr;
1928         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1929
1930         set_reg_field_value(
1931                 value,
1932                 overscan_color->color_b_cb,
1933                 CRTC_OVERSCAN_COLOR,
1934                 CRTC_OVERSCAN_COLOR_BLUE);
1935
1936         set_reg_field_value(
1937                 value,
1938                 overscan_color->color_g_y,
1939                 CRTC_OVERSCAN_COLOR,
1940                 CRTC_OVERSCAN_COLOR_GREEN);
1941
1942         set_reg_field_value(
1943                 value,
1944                 overscan_color->color_r_cr,
1945                 CRTC_OVERSCAN_COLOR,
1946                 CRTC_OVERSCAN_COLOR_RED);
1947
1948         addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1949         dm_write_reg(ctx, addr, value);
1950 }
1951
1952 void dce110_tg_program_timing(struct timing_generator *tg,
1953         const struct dc_crtc_timing *timing,
1954         int vready_offset,
1955         int vstartup_start,
1956         int vupdate_offset,
1957         int vupdate_width,
1958         const enum signal_type signal,
1959         bool use_vbios)
1960 {
1961         if (use_vbios)
1962                 dce110_timing_generator_program_timing_generator(tg, timing);
1963         else
1964                 dce110_timing_generator_program_blanking(tg, timing);
1965 }
1966
1967 bool dce110_tg_is_blanked(struct timing_generator *tg)
1968 {
1969         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1970         uint32_t value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL));
1971
1972         if (get_reg_field_value(
1973                         value,
1974                         CRTC_BLANK_CONTROL,
1975                         CRTC_BLANK_DATA_EN) == 1 &&
1976                 get_reg_field_value(
1977                         value,
1978                         CRTC_BLANK_CONTROL,
1979                         CRTC_CURRENT_BLANK_STATE) == 1)
1980                 return true;
1981         return false;
1982 }
1983
1984 void dce110_tg_set_blank(struct timing_generator *tg,
1985                 bool enable_blanking)
1986 {
1987         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1988         uint32_t value = 0;
1989
1990         set_reg_field_value(
1991                 value,
1992                 1,
1993                 CRTC_DOUBLE_BUFFER_CONTROL,
1994                 CRTC_BLANK_DATA_DOUBLE_BUFFER_EN);
1995
1996         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_DOUBLE_BUFFER_CONTROL), value);
1997         value = 0;
1998
1999         if (enable_blanking) {
2000                 set_reg_field_value(
2001                         value,
2002                         1,
2003                         CRTC_BLANK_CONTROL,
2004                         CRTC_BLANK_DATA_EN);
2005
2006                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), value);
2007
2008         } else
2009                 dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), 0);
2010 }
2011
2012 bool dce110_tg_validate_timing(struct timing_generator *tg,
2013         const struct dc_crtc_timing *timing)
2014 {
2015         return dce110_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
2016 }
2017
2018 void dce110_tg_wait_for_state(struct timing_generator *tg,
2019         enum crtc_state state)
2020 {
2021         switch (state) {
2022         case CRTC_STATE_VBLANK:
2023                 dce110_timing_generator_wait_for_vblank(tg);
2024                 break;
2025
2026         case CRTC_STATE_VACTIVE:
2027                 dce110_timing_generator_wait_for_vactive(tg);
2028                 break;
2029
2030         default:
2031                 break;
2032         }
2033 }
2034
2035 void dce110_tg_set_colors(struct timing_generator *tg,
2036         const struct tg_color *blank_color,
2037         const struct tg_color *overscan_color)
2038 {
2039         if (blank_color != NULL)
2040                 dce110_tg_program_blank_color(tg, blank_color);
2041         if (overscan_color != NULL)
2042                 dce110_tg_set_overscan_color(tg, overscan_color);
2043 }
2044
2045 /* Gets first line of blank region of the display timing for CRTC
2046  * and programms is as a trigger to fire vertical interrupt
2047  */
2048 bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
2049 {
2050         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2051         uint32_t v_blank_start = 0;
2052         uint32_t v_blank_end = 0;
2053         uint32_t val = 0;
2054         uint32_t h_position, v_position;
2055
2056         tg->funcs->get_scanoutpos(
2057                         tg,
2058                         &v_blank_start,
2059                         &v_blank_end,
2060                         &h_position,
2061                         &v_position);
2062
2063         if (v_blank_start == 0 || v_blank_end == 0)
2064                 return false;
2065
2066         set_reg_field_value(
2067                 val,
2068                 v_blank_start,
2069                 CRTC_VERTICAL_INTERRUPT0_POSITION,
2070                 CRTC_VERTICAL_INTERRUPT0_LINE_START);
2071
2072         /* Set interval width for interrupt to fire to 1 scanline */
2073         set_reg_field_value(
2074                 val,
2075                 v_blank_start + width,
2076                 CRTC_VERTICAL_INTERRUPT0_POSITION,
2077                 CRTC_VERTICAL_INTERRUPT0_LINE_END);
2078
2079         dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERTICAL_INTERRUPT0_POSITION), val);
2080
2081         return true;
2082 }
2083
2084 static bool dce110_is_tg_enabled(struct timing_generator *tg)
2085 {
2086         uint32_t addr = 0;
2087         uint32_t value = 0;
2088         uint32_t field = 0;
2089         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2090
2091         addr = CRTC_REG(mmCRTC_CONTROL);
2092         value = dm_read_reg(tg->ctx, addr);
2093         field = get_reg_field_value(value, CRTC_CONTROL,
2094                                     CRTC_CURRENT_MASTER_EN_STATE);
2095         return field == 1;
2096 }
2097
2098 bool dce110_configure_crc(struct timing_generator *tg,
2099                           const struct crc_params *params)
2100 {
2101         uint32_t cntl_addr = 0;
2102         uint32_t addr = 0;
2103         uint32_t value;
2104         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2105
2106         /* Cannot configure crc on a CRTC that is disabled */
2107         if (!dce110_is_tg_enabled(tg))
2108                 return false;
2109
2110         cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL);
2111
2112         /* First, disable CRC before we configure it. */
2113         dm_write_reg(tg->ctx, cntl_addr, 0);
2114
2115         if (!params->enable)
2116                 return true;
2117
2118         /* Program frame boundaries */
2119         /* Window A x axis start and end. */
2120         value = 0;
2121         addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL);
2122         set_reg_field_value(value, params->windowa_x_start,
2123                             CRTC_CRC0_WINDOWA_X_CONTROL,
2124                             CRTC_CRC0_WINDOWA_X_START);
2125         set_reg_field_value(value, params->windowa_x_end,
2126                             CRTC_CRC0_WINDOWA_X_CONTROL,
2127                             CRTC_CRC0_WINDOWA_X_END);
2128         dm_write_reg(tg->ctx, addr, value);
2129
2130         /* Window A y axis start and end. */
2131         value = 0;
2132         addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL);
2133         set_reg_field_value(value, params->windowa_y_start,
2134                             CRTC_CRC0_WINDOWA_Y_CONTROL,
2135                             CRTC_CRC0_WINDOWA_Y_START);
2136         set_reg_field_value(value, params->windowa_y_end,
2137                             CRTC_CRC0_WINDOWA_Y_CONTROL,
2138                             CRTC_CRC0_WINDOWA_Y_END);
2139         dm_write_reg(tg->ctx, addr, value);
2140
2141         /* Window B x axis start and end. */
2142         value = 0;
2143         addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL);
2144         set_reg_field_value(value, params->windowb_x_start,
2145                             CRTC_CRC0_WINDOWB_X_CONTROL,
2146                             CRTC_CRC0_WINDOWB_X_START);
2147         set_reg_field_value(value, params->windowb_x_end,
2148                             CRTC_CRC0_WINDOWB_X_CONTROL,
2149                             CRTC_CRC0_WINDOWB_X_END);
2150         dm_write_reg(tg->ctx, addr, value);
2151
2152         /* Window B y axis start and end. */
2153         value = 0;
2154         addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL);
2155         set_reg_field_value(value, params->windowb_y_start,
2156                             CRTC_CRC0_WINDOWB_Y_CONTROL,
2157                             CRTC_CRC0_WINDOWB_Y_START);
2158         set_reg_field_value(value, params->windowb_y_end,
2159                             CRTC_CRC0_WINDOWB_Y_CONTROL,
2160                             CRTC_CRC0_WINDOWB_Y_END);
2161         dm_write_reg(tg->ctx, addr, value);
2162
2163         /* Set crc mode and selection, and enable. Only using CRC0*/
2164         value = 0;
2165         set_reg_field_value(value, params->continuous_mode ? 1 : 0,
2166                             CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
2167         set_reg_field_value(value, params->selection,
2168                             CRTC_CRC_CNTL, CRTC_CRC0_SELECT);
2169         set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
2170         dm_write_reg(tg->ctx, cntl_addr, value);
2171
2172         return true;
2173 }
2174
2175 bool dce110_get_crc(struct timing_generator *tg,
2176                     uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
2177 {
2178         uint32_t addr = 0;
2179         uint32_t value = 0;
2180         uint32_t field = 0;
2181         struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2182
2183         addr = CRTC_REG(mmCRTC_CRC_CNTL);
2184         value = dm_read_reg(tg->ctx, addr);
2185         field = get_reg_field_value(value, CRTC_CRC_CNTL, CRTC_CRC_EN);
2186
2187         /* Early return if CRC is not enabled for this CRTC */
2188         if (!field)
2189                 return false;
2190
2191         addr = CRTC_REG(mmCRTC_CRC0_DATA_RG);
2192         value = dm_read_reg(tg->ctx, addr);
2193         *r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR);
2194         *g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y);
2195
2196         addr = CRTC_REG(mmCRTC_CRC0_DATA_B);
2197         value = dm_read_reg(tg->ctx, addr);
2198         *b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB);
2199
2200         return true;
2201 }
2202
2203 static const struct timing_generator_funcs dce110_tg_funcs = {
2204                 .validate_timing = dce110_tg_validate_timing,
2205                 .program_timing = dce110_tg_program_timing,
2206                 .enable_crtc = dce110_timing_generator_enable_crtc,
2207                 .disable_crtc = dce110_timing_generator_disable_crtc,
2208                 .is_counter_moving = dce110_timing_generator_is_counter_moving,
2209                 .get_position = dce110_timing_generator_get_position,
2210                 .get_frame_count = dce110_timing_generator_get_vblank_counter,
2211                 .get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos,
2212                 .set_early_control = dce110_timing_generator_set_early_control,
2213                 .wait_for_state = dce110_tg_wait_for_state,
2214                 .set_blank = dce110_tg_set_blank,
2215                 .is_blanked = dce110_tg_is_blanked,
2216                 .set_colors = dce110_tg_set_colors,
2217                 .set_overscan_blank_color =
2218                                 dce110_timing_generator_set_overscan_color_black,
2219                 .set_blank_color = dce110_timing_generator_program_blank_color,
2220                 .disable_vga = dce110_timing_generator_disable_vga,
2221                 .did_triggered_reset_occur =
2222                                 dce110_timing_generator_did_triggered_reset_occur,
2223                 .setup_global_swap_lock =
2224                                 dce110_timing_generator_setup_global_swap_lock,
2225                 .enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
2226                 .enable_crtc_reset = dce110_timing_generator_enable_crtc_reset,
2227                 .disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
2228                 .tear_down_global_swap_lock =
2229                                 dce110_timing_generator_tear_down_global_swap_lock,
2230                 .enable_advanced_request =
2231                                 dce110_timing_generator_enable_advanced_request,
2232                 .set_drr =
2233                                 dce110_timing_generator_set_drr,
2234                 .get_last_used_drr_vtotal = NULL,
2235                 .set_static_screen_control =
2236                         dce110_timing_generator_set_static_screen_control,
2237                 .set_test_pattern = dce110_timing_generator_set_test_pattern,
2238                 .arm_vert_intr = dce110_arm_vert_intr,
2239                 .is_tg_enabled = dce110_is_tg_enabled,
2240                 .configure_crc = dce110_configure_crc,
2241                 .get_crc = dce110_get_crc,
2242 };
2243
2244 void dce110_timing_generator_construct(
2245         struct dce110_timing_generator *tg110,
2246         struct dc_context *ctx,
2247         uint32_t instance,
2248         const struct dce110_timing_generator_offsets *offsets)
2249 {
2250         tg110->controller_id = CONTROLLER_ID_D0 + instance;
2251         tg110->base.inst = instance;
2252
2253         tg110->offsets = *offsets;
2254
2255         tg110->base.funcs = &dce110_tg_funcs;
2256
2257         tg110->base.ctx = ctx;
2258         tg110->base.bp = ctx->dc_bios;
2259
2260         tg110->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
2261         tg110->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
2262
2263         tg110->min_h_blank = 56;
2264         tg110->min_h_front_porch = 4;
2265         tg110->min_h_back_porch = 4;
2266 }