xref: /dragonfly/sys/dev/drm/amd/display/dc/dce110/dce110_timing_generator.c (revision b843c749addef9340ee7d4e250b09fdd492602a1)
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 */
dce110_timing_generator_apply_front_porch_workaround(struct timing_generator * tg,struct dc_crtc_timing * timing)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  */
dce110_timing_generator_is_in_vertical_blank(struct timing_generator * tg)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 
dce110_timing_generator_set_early_control(struct timing_generator * tg,uint32_t early_cntl)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  */
dce110_timing_generator_enable_crtc(struct timing_generator * tg)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 
dce110_timing_generator_program_blank_color(struct timing_generator * tg,const struct tg_color * black_color)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  */
dce110_timing_generator_disable_crtc(struct timing_generator * tg)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 */
program_horz_count_by_2(struct timing_generator * tg,const struct dc_crtc_timing * timing)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  */
dce110_timing_generator_program_timing_generator(struct timing_generator * tg,const struct dc_crtc_timing * dc_crtc_timing)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  */
dce110_timing_generator_set_drr(struct timing_generator * tg,const struct drr_params * params)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_cntl,
435                                         0,
436                                         CRTC_V_TOTAL_CONTROL,
437                                         CRTC_V_TOTAL_MIN_SEL);
438                     set_reg_field_value(v_total_cntl,
439                                         0,
440                                         CRTC_V_TOTAL_CONTROL,
441                                         CRTC_V_TOTAL_MAX_SEL);
442                     set_reg_field_value(v_total_min,
443                                         0,
444                                         CRTC_V_TOTAL_MIN,
445                                         CRTC_V_TOTAL_MIN);
446                     set_reg_field_value(v_total_max,
447                                         0,
448                                         CRTC_V_TOTAL_MAX,
449                                         CRTC_V_TOTAL_MAX);
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 
dce110_timing_generator_set_static_screen_control(struct timing_generator * tg,uint32_t value)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  */
dce110_timing_generator_get_vblank_counter(struct timing_generator * tg)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  */
dce110_timing_generator_get_position(struct timing_generator * tg,struct crtc_position * position)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  */
dce110_timing_generator_get_crtc_scanoutpos(struct timing_generator * tg,uint32_t * v_blank_start,uint32_t * v_blank_end,uint32_t * h_position,uint32_t * v_position)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? */
dce110_timing_generator_program_blanking(struct timing_generator * tg,const struct dc_crtc_timing * timing)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 
dce110_timing_generator_set_test_pattern(struct timing_generator * tg,enum controller_dp_test_pattern test_pattern,enum dc_color_depth color_depth)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 */
dce110_timing_generator_validate_timing(struct timing_generator * tg,const struct dc_crtc_timing * timing,enum signal_type signal)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, hsync_offset, h_sync_start;
1116 
1117           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1118 
1119           ASSERT(timing != NULL);
1120 
1121           if (!timing)
1122                     return false;
1123 
1124           hsync_offset = timing->h_border_right + timing->h_front_porch;
1125           h_sync_start = timing->h_addressable + hsync_offset;
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 */
dce110_timing_generator_wait_for_vblank(struct timing_generator * tg)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 */
dce110_timing_generator_wait_for_vactive(struct timing_generator * tg)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 
dce110_timing_generator_setup_global_swap_lock(struct timing_generator * tg,const struct dcp_gsl_params * gsl_params)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           dm_write_reg(tg->ctx, CRTC_REG(mmDCP_GSL_CONTROL), value);
1249           value = 0;
1250 
1251           set_reg_field_value(value,
1252                                   gsl_params->gsl_master,
1253                                   DCIO_GSL0_CNTL,
1254                                   DCIO_GSL0_VSYNC_SEL);
1255 
1256           set_reg_field_value(value,
1257                                   0,
1258                                   DCIO_GSL0_CNTL,
1259                                   DCIO_GSL0_TIMING_SYNC_SEL);
1260 
1261           set_reg_field_value(value,
1262                                   0,
1263                                   DCIO_GSL0_CNTL,
1264                                   DCIO_GSL0_GLOBAL_UNLOCK_SEL);
1265 
1266           dm_write_reg(tg->ctx, CRTC_REG(mmDCIO_GSL0_CNTL), value);
1267 
1268 
1269           {
1270                     uint32_t value_crtc_vtotal;
1271 
1272                     value_crtc_vtotal = dm_read_reg(tg->ctx,
1273                                         CRTC_REG(mmCRTC_V_TOTAL));
1274 
1275                     set_reg_field_value(value,
1276                                             0,/* DCP_GSL_PURPOSE_SURFACE_FLIP */
1277                                             DCP_GSL_CONTROL,
1278                                             DCP_GSL_SYNC_SOURCE);
1279 
1280                     /* Checkpoint relative to end of frame */
1281                     check_point = get_reg_field_value(value_crtc_vtotal,
1282                                                               CRTC_V_TOTAL,
1283                                                               CRTC_V_TOTAL);
1284 
1285                     dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_GSL_WINDOW), 0);
1286           }
1287 
1288           set_reg_field_value(value,
1289                                   1,
1290                                   DCP_GSL_CONTROL,
1291                                   DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
1292 
1293           dm_write_reg(tg->ctx, address, value);
1294 
1295           /********************************************************************/
1296           address = CRTC_REG(mmCRTC_GSL_CONTROL);
1297 
1298           value = dm_read_reg(tg->ctx, address);
1299           set_reg_field_value(value,
1300                                   check_point - FLIP_READY_BACK_LOOKUP,
1301                                   CRTC_GSL_CONTROL,
1302                                   CRTC_GSL_CHECK_LINE_NUM);
1303 
1304           set_reg_field_value(value,
1305                                   VFLIP_READY_DELAY,
1306                                   CRTC_GSL_CONTROL,
1307                                   CRTC_GSL_FORCE_DELAY);
1308 
1309           dm_write_reg(tg->ctx, address, value);
1310 }
1311 
dce110_timing_generator_tear_down_global_swap_lock(struct timing_generator * tg)1312 void dce110_timing_generator_tear_down_global_swap_lock(
1313           struct timing_generator *tg)
1314 {
1315           /* Clear all the register writes done by
1316            * dce110_timing_generator_setup_global_swap_lock
1317            */
1318 
1319           uint32_t value;
1320           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1321           uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1322 
1323           value = 0;
1324 
1325           /* This pipe will belong to GSL Group zero. */
1326           /* Settig HW default values from reg specs */
1327           set_reg_field_value(value,
1328                               0,
1329                               DCP_GSL_CONTROL,
1330                               DCP_GSL0_EN);
1331 
1332           set_reg_field_value(value,
1333                               0,
1334                               DCP_GSL_CONTROL,
1335                               DCP_GSL_MASTER_EN);
1336 
1337           set_reg_field_value(value,
1338                               0x2,
1339                               DCP_GSL_CONTROL,
1340                               DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1341 
1342           set_reg_field_value(value,
1343                               0x6,
1344                               DCP_GSL_CONTROL,
1345                               DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1346 
1347           /* Restore DCP_GSL_PURPOSE_SURFACE_FLIP */
1348           {
1349                     uint32_t value_crtc_vtotal;
1350 
1351                     value_crtc_vtotal = dm_read_reg(tg->ctx,
1352                                         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  */
dce110_timing_generator_is_counter_moving(struct timing_generator * tg)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 
dce110_timing_generator_enable_advanced_request(struct timing_generator * tg,bool enable,const struct dc_crtc_timing * timing)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. */
dce110_timing_generator_set_lock_master(struct timing_generator * tg,bool lock)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 
dce110_timing_generator_enable_reset_trigger(struct timing_generator * tg,int source_tg_inst)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 
dce110_timing_generator_enable_crtc_reset(struct timing_generator * tg,int source_tg_inst,struct crtc_trigger_info * crtc_tp)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 }
dce110_timing_generator_disable_reset_trigger(struct timing_generator * tg)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  */
dce110_timing_generator_did_triggered_reset_occur(struct timing_generator * tg)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  */
dce110_timing_generator_disable_vga(struct timing_generator * tg)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 
dce110_timing_generator_set_overscan_color_black(struct timing_generator * tg,const struct tg_color * color)1846 void dce110_timing_generator_set_overscan_color_black(
1847           struct timing_generator *tg,
1848           const struct tg_color *color)
1849 {
1850           struct dc_context *ctx = tg->ctx;
1851           uint32_t addr;
1852           uint32_t value = 0;
1853           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1854 
1855           set_reg_field_value(
1856                               value,
1857                               color->color_b_cb,
1858                               CRTC_OVERSCAN_COLOR,
1859                               CRTC_OVERSCAN_COLOR_BLUE);
1860 
1861           set_reg_field_value(
1862                               value,
1863                               color->color_r_cr,
1864                               CRTC_OVERSCAN_COLOR,
1865                               CRTC_OVERSCAN_COLOR_RED);
1866 
1867           set_reg_field_value(
1868                               value,
1869                               color->color_g_y,
1870                               CRTC_OVERSCAN_COLOR,
1871                               CRTC_OVERSCAN_COLOR_GREEN);
1872 
1873           addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1874           dm_write_reg(ctx, addr, value);
1875           addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1876           dm_write_reg(ctx, addr, value);
1877           /* This is desirable to have a constant DAC output voltage during the
1878            * blank time that is higher than the 0 volt reference level that the
1879            * DAC outputs when the NBLANK signal
1880            * is asserted low, such as for output to an analog TV. */
1881           addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1882           dm_write_reg(ctx, addr, value);
1883 
1884           /* TO DO we have to program EXT registers and we need to know LB DATA
1885            * format because it is used when more 10 , i.e. 12 bits per color
1886            *
1887            * m_mmDxCRTC_OVERSCAN_COLOR_EXT
1888            * m_mmDxCRTC_BLACK_COLOR_EXT
1889            * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
1890            */
1891 
1892 }
1893 
dce110_tg_program_blank_color(struct timing_generator * tg,const struct tg_color * black_color)1894 void dce110_tg_program_blank_color(struct timing_generator *tg,
1895                     const struct tg_color *black_color)
1896 {
1897           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1898           uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1899           uint32_t value = dm_read_reg(tg->ctx, addr);
1900 
1901           set_reg_field_value(
1902                     value,
1903                     black_color->color_b_cb,
1904                     CRTC_BLACK_COLOR,
1905                     CRTC_BLACK_COLOR_B_CB);
1906           set_reg_field_value(
1907                     value,
1908                     black_color->color_g_y,
1909                     CRTC_BLACK_COLOR,
1910                     CRTC_BLACK_COLOR_G_Y);
1911           set_reg_field_value(
1912                     value,
1913                     black_color->color_r_cr,
1914                     CRTC_BLACK_COLOR,
1915                     CRTC_BLACK_COLOR_R_CR);
1916 
1917           dm_write_reg(tg->ctx, addr, value);
1918 
1919           addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1920           dm_write_reg(tg->ctx, addr, value);
1921 }
1922 
dce110_tg_set_overscan_color(struct timing_generator * tg,const struct tg_color * overscan_color)1923 void dce110_tg_set_overscan_color(struct timing_generator *tg,
1924           const struct tg_color *overscan_color)
1925 {
1926           struct dc_context *ctx = tg->ctx;
1927           uint32_t value = 0;
1928           uint32_t addr;
1929           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1930 
1931           set_reg_field_value(
1932                     value,
1933                     overscan_color->color_b_cb,
1934                     CRTC_OVERSCAN_COLOR,
1935                     CRTC_OVERSCAN_COLOR_BLUE);
1936 
1937           set_reg_field_value(
1938                     value,
1939                     overscan_color->color_g_y,
1940                     CRTC_OVERSCAN_COLOR,
1941                     CRTC_OVERSCAN_COLOR_GREEN);
1942 
1943           set_reg_field_value(
1944                     value,
1945                     overscan_color->color_r_cr,
1946                     CRTC_OVERSCAN_COLOR,
1947                     CRTC_OVERSCAN_COLOR_RED);
1948 
1949           addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1950           dm_write_reg(ctx, addr, value);
1951 }
1952 
dce110_tg_program_timing(struct timing_generator * tg,const struct dc_crtc_timing * timing,bool use_vbios)1953 void dce110_tg_program_timing(struct timing_generator *tg,
1954           const struct dc_crtc_timing *timing,
1955           bool use_vbios)
1956 {
1957           if (use_vbios)
1958                     dce110_timing_generator_program_timing_generator(tg, timing);
1959           else
1960                     dce110_timing_generator_program_blanking(tg, timing);
1961 }
1962 
dce110_tg_is_blanked(struct timing_generator * tg)1963 bool dce110_tg_is_blanked(struct timing_generator *tg)
1964 {
1965           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1966           uint32_t value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL));
1967 
1968           if (get_reg_field_value(
1969                               value,
1970                               CRTC_BLANK_CONTROL,
1971                               CRTC_BLANK_DATA_EN) == 1 &&
1972                     get_reg_field_value(
1973                               value,
1974                               CRTC_BLANK_CONTROL,
1975                               CRTC_CURRENT_BLANK_STATE) == 1)
1976                     return true;
1977           return false;
1978 }
1979 
dce110_tg_set_blank(struct timing_generator * tg,bool enable_blanking)1980 void dce110_tg_set_blank(struct timing_generator *tg,
1981                     bool enable_blanking)
1982 {
1983           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1984           uint32_t value = 0;
1985 
1986           set_reg_field_value(
1987                     value,
1988                     1,
1989                     CRTC_DOUBLE_BUFFER_CONTROL,
1990                     CRTC_BLANK_DATA_DOUBLE_BUFFER_EN);
1991 
1992           dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_DOUBLE_BUFFER_CONTROL), value);
1993           value = 0;
1994 
1995           if (enable_blanking) {
1996                     set_reg_field_value(
1997                               value,
1998                               1,
1999                               CRTC_BLANK_CONTROL,
2000                               CRTC_BLANK_DATA_EN);
2001 
2002                     dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), value);
2003 
2004           } else
2005                     dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), 0);
2006 }
2007 
dce110_tg_validate_timing(struct timing_generator * tg,const struct dc_crtc_timing * timing)2008 bool dce110_tg_validate_timing(struct timing_generator *tg,
2009           const struct dc_crtc_timing *timing)
2010 {
2011           return dce110_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
2012 }
2013 
dce110_tg_wait_for_state(struct timing_generator * tg,enum crtc_state state)2014 void dce110_tg_wait_for_state(struct timing_generator *tg,
2015           enum crtc_state state)
2016 {
2017           switch (state) {
2018           case CRTC_STATE_VBLANK:
2019                     dce110_timing_generator_wait_for_vblank(tg);
2020                     break;
2021 
2022           case CRTC_STATE_VACTIVE:
2023                     dce110_timing_generator_wait_for_vactive(tg);
2024                     break;
2025 
2026           default:
2027                     break;
2028           }
2029 }
2030 
dce110_tg_set_colors(struct timing_generator * tg,const struct tg_color * blank_color,const struct tg_color * overscan_color)2031 void dce110_tg_set_colors(struct timing_generator *tg,
2032           const struct tg_color *blank_color,
2033           const struct tg_color *overscan_color)
2034 {
2035           if (blank_color != NULL)
2036                     dce110_tg_program_blank_color(tg, blank_color);
2037           if (overscan_color != NULL)
2038                     dce110_tg_set_overscan_color(tg, overscan_color);
2039 }
2040 
2041 /* Gets first line of blank region of the display timing for CRTC
2042  * and programms is as a trigger to fire vertical interrupt
2043  */
dce110_arm_vert_intr(struct timing_generator * tg,uint8_t width)2044 bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
2045 {
2046           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2047           uint32_t v_blank_start = 0;
2048           uint32_t v_blank_end = 0;
2049           uint32_t val = 0;
2050           uint32_t h_position, v_position;
2051 
2052           tg->funcs->get_scanoutpos(
2053                               tg,
2054                               &v_blank_start,
2055                               &v_blank_end,
2056                               &h_position,
2057                               &v_position);
2058 
2059           if (v_blank_start == 0 || v_blank_end == 0)
2060                     return false;
2061 
2062           set_reg_field_value(
2063                     val,
2064                     v_blank_start,
2065                     CRTC_VERTICAL_INTERRUPT0_POSITION,
2066                     CRTC_VERTICAL_INTERRUPT0_LINE_START);
2067 
2068           /* Set interval width for interrupt to fire to 1 scanline */
2069           set_reg_field_value(
2070                     val,
2071                     v_blank_start + width,
2072                     CRTC_VERTICAL_INTERRUPT0_POSITION,
2073                     CRTC_VERTICAL_INTERRUPT0_LINE_END);
2074 
2075           dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERTICAL_INTERRUPT0_POSITION), val);
2076 
2077           return true;
2078 }
2079 
dce110_is_tg_enabled(struct timing_generator * tg)2080 static bool dce110_is_tg_enabled(struct timing_generator *tg)
2081 {
2082           uint32_t addr = 0;
2083           uint32_t value = 0;
2084           uint32_t field = 0;
2085           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2086 
2087           addr = CRTC_REG(mmCRTC_CONTROL);
2088           value = dm_read_reg(tg->ctx, addr);
2089           field = get_reg_field_value(value, CRTC_CONTROL,
2090                                             CRTC_CURRENT_MASTER_EN_STATE);
2091           return field == 1;
2092 }
2093 
dce110_configure_crc(struct timing_generator * tg,const struct crc_params * params)2094 bool dce110_configure_crc(struct timing_generator *tg,
2095                                 const struct crc_params *params)
2096 {
2097           uint32_t cntl_addr = 0;
2098           uint32_t addr = 0;
2099           uint32_t value;
2100           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2101 
2102           /* Cannot configure crc on a CRTC that is disabled */
2103           if (!dce110_is_tg_enabled(tg))
2104                     return false;
2105 
2106           cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL);
2107 
2108           /* First, disable CRC before we configure it. */
2109           dm_write_reg(tg->ctx, cntl_addr, 0);
2110 
2111           if (!params->enable)
2112                     return true;
2113 
2114           /* Program frame boundaries */
2115           /* Window A x axis start and end. */
2116           value = 0;
2117           addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL);
2118           set_reg_field_value(value, params->windowa_x_start,
2119                                   CRTC_CRC0_WINDOWA_X_CONTROL,
2120                                   CRTC_CRC0_WINDOWA_X_START);
2121           set_reg_field_value(value, params->windowa_x_end,
2122                                   CRTC_CRC0_WINDOWA_X_CONTROL,
2123                                   CRTC_CRC0_WINDOWA_X_END);
2124           dm_write_reg(tg->ctx, addr, value);
2125 
2126           /* Window A y axis start and end. */
2127           value = 0;
2128           addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL);
2129           set_reg_field_value(value, params->windowa_y_start,
2130                                   CRTC_CRC0_WINDOWA_Y_CONTROL,
2131                                   CRTC_CRC0_WINDOWA_Y_START);
2132           set_reg_field_value(value, params->windowa_y_end,
2133                                   CRTC_CRC0_WINDOWA_Y_CONTROL,
2134                                   CRTC_CRC0_WINDOWA_Y_END);
2135           dm_write_reg(tg->ctx, addr, value);
2136 
2137           /* Window B x axis start and end. */
2138           value = 0;
2139           addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL);
2140           set_reg_field_value(value, params->windowb_x_start,
2141                                   CRTC_CRC0_WINDOWB_X_CONTROL,
2142                                   CRTC_CRC0_WINDOWB_X_START);
2143           set_reg_field_value(value, params->windowb_x_end,
2144                                   CRTC_CRC0_WINDOWB_X_CONTROL,
2145                                   CRTC_CRC0_WINDOWB_X_END);
2146           dm_write_reg(tg->ctx, addr, value);
2147 
2148           /* Window B y axis start and end. */
2149           value = 0;
2150           addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL);
2151           set_reg_field_value(value, params->windowb_y_start,
2152                                   CRTC_CRC0_WINDOWB_Y_CONTROL,
2153                                   CRTC_CRC0_WINDOWB_Y_START);
2154           set_reg_field_value(value, params->windowb_y_end,
2155                                   CRTC_CRC0_WINDOWB_Y_CONTROL,
2156                                   CRTC_CRC0_WINDOWB_Y_END);
2157           dm_write_reg(tg->ctx, addr, value);
2158 
2159           /* Set crc mode and selection, and enable. Only using CRC0*/
2160           value = 0;
2161           set_reg_field_value(value, params->continuous_mode ? 1 : 0,
2162                                   CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
2163           set_reg_field_value(value, params->selection,
2164                                   CRTC_CRC_CNTL, CRTC_CRC0_SELECT);
2165           set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
2166           dm_write_reg(tg->ctx, cntl_addr, value);
2167 
2168           return true;
2169 }
2170 
dce110_get_crc(struct timing_generator * tg,uint32_t * r_cr,uint32_t * g_y,uint32_t * b_cb)2171 bool dce110_get_crc(struct timing_generator *tg,
2172                         uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
2173 {
2174           uint32_t addr = 0;
2175           uint32_t value = 0;
2176           uint32_t field = 0;
2177           struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2178 
2179           addr = CRTC_REG(mmCRTC_CRC_CNTL);
2180           value = dm_read_reg(tg->ctx, addr);
2181           field = get_reg_field_value(value, CRTC_CRC_CNTL, CRTC_CRC_EN);
2182 
2183           /* Early return if CRC is not enabled for this CRTC */
2184           if (!field)
2185                     return false;
2186 
2187           addr = CRTC_REG(mmCRTC_CRC0_DATA_RG);
2188           value = dm_read_reg(tg->ctx, addr);
2189           *r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR);
2190           *g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y);
2191 
2192           addr = CRTC_REG(mmCRTC_CRC0_DATA_B);
2193           value = dm_read_reg(tg->ctx, addr);
2194           *b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB);
2195 
2196           return true;
2197 }
2198 
2199 static const struct timing_generator_funcs dce110_tg_funcs = {
2200                     .validate_timing = dce110_tg_validate_timing,
2201                     .program_timing = dce110_tg_program_timing,
2202                     .enable_crtc = dce110_timing_generator_enable_crtc,
2203                     .disable_crtc = dce110_timing_generator_disable_crtc,
2204                     .is_counter_moving = dce110_timing_generator_is_counter_moving,
2205                     .get_position = dce110_timing_generator_get_position,
2206                     .get_frame_count = dce110_timing_generator_get_vblank_counter,
2207                     .get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos,
2208                     .set_early_control = dce110_timing_generator_set_early_control,
2209                     .wait_for_state = dce110_tg_wait_for_state,
2210                     .set_blank = dce110_tg_set_blank,
2211                     .is_blanked = dce110_tg_is_blanked,
2212                     .set_colors = dce110_tg_set_colors,
2213                     .set_overscan_blank_color =
2214                                         dce110_timing_generator_set_overscan_color_black,
2215                     .set_blank_color = dce110_timing_generator_program_blank_color,
2216                     .disable_vga = dce110_timing_generator_disable_vga,
2217                     .did_triggered_reset_occur =
2218                                         dce110_timing_generator_did_triggered_reset_occur,
2219                     .setup_global_swap_lock =
2220                                         dce110_timing_generator_setup_global_swap_lock,
2221                     .enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
2222                     .enable_crtc_reset = dce110_timing_generator_enable_crtc_reset,
2223                     .disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
2224                     .tear_down_global_swap_lock =
2225                                         dce110_timing_generator_tear_down_global_swap_lock,
2226                     .enable_advanced_request =
2227                                         dce110_timing_generator_enable_advanced_request,
2228                     .set_drr =
2229                                         dce110_timing_generator_set_drr,
2230                     .set_static_screen_control =
2231                               dce110_timing_generator_set_static_screen_control,
2232                     .set_test_pattern = dce110_timing_generator_set_test_pattern,
2233                     .arm_vert_intr = dce110_arm_vert_intr,
2234                     .is_tg_enabled = dce110_is_tg_enabled,
2235                     .configure_crc = dce110_configure_crc,
2236                     .get_crc = dce110_get_crc,
2237 };
2238 
dce110_timing_generator_construct(struct dce110_timing_generator * tg110,struct dc_context * ctx,uint32_t instance,const struct dce110_timing_generator_offsets * offsets)2239 void dce110_timing_generator_construct(
2240           struct dce110_timing_generator *tg110,
2241           struct dc_context *ctx,
2242           uint32_t instance,
2243           const struct dce110_timing_generator_offsets *offsets)
2244 {
2245           tg110->controller_id = CONTROLLER_ID_D0 + instance;
2246           tg110->base.inst = instance;
2247 
2248           tg110->offsets = *offsets;
2249 
2250           tg110->base.funcs = &dce110_tg_funcs;
2251 
2252           tg110->base.ctx = ctx;
2253           tg110->base.bp = ctx->dc_bios;
2254 
2255           tg110->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
2256           tg110->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
2257 
2258           tg110->min_h_blank = 56;
2259           tg110->min_h_front_porch = 4;
2260           tg110->min_h_back_porch = 4;
2261 }
2262