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