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