1b8fdfcc6SHarry Wentland /*
2b8fdfcc6SHarry Wentland  * Copyright 2012-15 Advanced Micro Devices, Inc.
3b8fdfcc6SHarry Wentland  *
4b8fdfcc6SHarry Wentland  * Permission is hereby granted, free of charge, to any person obtaining a
5b8fdfcc6SHarry Wentland  * copy of this software and associated documentation files (the "Software"),
6b8fdfcc6SHarry Wentland  * to deal in the Software without restriction, including without limitation
7b8fdfcc6SHarry Wentland  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8fdfcc6SHarry Wentland  * and/or sell copies of the Software, and to permit persons to whom the
9b8fdfcc6SHarry Wentland  * Software is furnished to do so, subject to the following conditions:
10b8fdfcc6SHarry Wentland  *
11b8fdfcc6SHarry Wentland  * The above copyright notice and this permission notice shall be included in
12b8fdfcc6SHarry Wentland  * all copies or substantial portions of the Software.
13b8fdfcc6SHarry Wentland  *
14b8fdfcc6SHarry Wentland  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15b8fdfcc6SHarry Wentland  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16b8fdfcc6SHarry Wentland  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17b8fdfcc6SHarry Wentland  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18b8fdfcc6SHarry Wentland  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19b8fdfcc6SHarry Wentland  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20b8fdfcc6SHarry Wentland  * OTHER DEALINGS IN THE SOFTWARE.
21b8fdfcc6SHarry Wentland  *
22b8fdfcc6SHarry Wentland  * Authors: AMD
23b8fdfcc6SHarry Wentland  *
24b8fdfcc6SHarry Wentland  */
25b8fdfcc6SHarry Wentland 
26b8fdfcc6SHarry Wentland #include "dm_services.h"
27b8fdfcc6SHarry Wentland 
28b8fdfcc6SHarry Wentland #include "vega10/DC/dce_12_0_offset.h"
29b8fdfcc6SHarry Wentland #include "vega10/DC/dce_12_0_sh_mask.h"
30b8fdfcc6SHarry Wentland #include "vega10/soc15ip.h"
31b8fdfcc6SHarry Wentland 
32b8fdfcc6SHarry Wentland #include "dc_types.h"
33b8fdfcc6SHarry Wentland #include "dc_bios_types.h"
34b8fdfcc6SHarry Wentland 
35b8fdfcc6SHarry Wentland #include "include/grph_object_id.h"
36b8fdfcc6SHarry Wentland #include "include/logger_interface.h"
37b8fdfcc6SHarry Wentland #include "dce120_timing_generator.h"
38b8fdfcc6SHarry Wentland 
39b8fdfcc6SHarry Wentland #include "timing_generator.h"
40b8fdfcc6SHarry Wentland 
41b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_N(reg_name, n, ...)	\
42b8fdfcc6SHarry Wentland 		generic_reg_update_soc15(tg110->base.ctx, tg110->offsets.crtc, reg_name, n, __VA_ARGS__)
43b8fdfcc6SHarry Wentland 
44b8fdfcc6SHarry Wentland #define CRTC_REG_SET_N(reg_name, n, ...)	\
45b8fdfcc6SHarry Wentland 		generic_reg_set_soc15(tg110->base.ctx, tg110->offsets.crtc, reg_name, n, __VA_ARGS__)
46b8fdfcc6SHarry Wentland 
47b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE(reg, field, val)	\
48b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
49b8fdfcc6SHarry Wentland 
50b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_2(reg, field1, val1, field2, val2)	\
51b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
52b8fdfcc6SHarry Wentland 
53b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3)	\
54b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
55b8fdfcc6SHarry Wentland 
56b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_4(reg, field1, val1, field2, val2, field3, val3, field4, val4)	\
57b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3, FD(reg##__##field4), val4)
58b8fdfcc6SHarry Wentland 
59b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_5(reg, field1, val1, field2, val2, field3, val3, field4, val4, field5, val5)	\
60b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3, FD(reg##__##field4), val4, FD(reg##__##field5), val5)
61b8fdfcc6SHarry Wentland 
62b8fdfcc6SHarry Wentland #define CRTC_REG_SET(reg, field, val)	\
63b8fdfcc6SHarry Wentland 		CRTC_REG_SET_N(reg, 1, FD(reg##__##field), val)
64b8fdfcc6SHarry Wentland 
65b8fdfcc6SHarry Wentland #define CRTC_REG_SET_2(reg, field1, val1, field2, val2)	\
66b8fdfcc6SHarry Wentland 		CRTC_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
67b8fdfcc6SHarry Wentland 
68b8fdfcc6SHarry Wentland #define CRTC_REG_SET_3(reg, field1, val1, field2, val2, field3, val3)	\
69b8fdfcc6SHarry Wentland 		CRTC_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
70b8fdfcc6SHarry Wentland 
71b8fdfcc6SHarry Wentland /**
72b8fdfcc6SHarry Wentland  *****************************************************************************
73b8fdfcc6SHarry Wentland  *  Function: is_in_vertical_blank
74b8fdfcc6SHarry Wentland  *
75b8fdfcc6SHarry Wentland  *  @brief
76b8fdfcc6SHarry Wentland  *     check the current status of CRTC to check if we are in Vertical Blank
77b8fdfcc6SHarry Wentland  *     regioneased" state
78b8fdfcc6SHarry Wentland  *
79b8fdfcc6SHarry Wentland  *  @return
80b8fdfcc6SHarry Wentland  *     true if currently in blank region, false otherwise
81b8fdfcc6SHarry Wentland  *
82b8fdfcc6SHarry Wentland  *****************************************************************************
83b8fdfcc6SHarry Wentland  */
84b8fdfcc6SHarry Wentland static bool dce120_timing_generator_is_in_vertical_blank(
85b8fdfcc6SHarry Wentland 		struct timing_generator *tg)
86b8fdfcc6SHarry Wentland {
87b8fdfcc6SHarry Wentland 	uint32_t field = 0;
88b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
89b8fdfcc6SHarry Wentland 	uint32_t value = dm_read_reg_soc15(
90b8fdfcc6SHarry Wentland 					tg->ctx,
91b8fdfcc6SHarry Wentland 					mmCRTC0_CRTC_STATUS,
92b8fdfcc6SHarry Wentland 					tg110->offsets.crtc);
93b8fdfcc6SHarry Wentland 
94b8fdfcc6SHarry Wentland 	field = get_reg_field_value(value, CRTC0_CRTC_STATUS, CRTC_V_BLANK);
95b8fdfcc6SHarry Wentland 	return field == 1;
96b8fdfcc6SHarry Wentland }
97b8fdfcc6SHarry Wentland 
98b8fdfcc6SHarry Wentland 
99b8fdfcc6SHarry Wentland /* determine if given timing can be supported by TG */
100b8fdfcc6SHarry Wentland bool dce120_timing_generator_validate_timing(
101b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
102b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing,
103b8fdfcc6SHarry Wentland 	enum signal_type signal)
104b8fdfcc6SHarry Wentland {
105b8fdfcc6SHarry Wentland 	uint32_t interlace_factor = timing->flags.INTERLACE ? 2 : 1;
106b8fdfcc6SHarry Wentland 	uint32_t v_blank =
107b8fdfcc6SHarry Wentland 					(timing->v_total - timing->v_addressable -
108b8fdfcc6SHarry Wentland 					timing->v_border_top - timing->v_border_bottom) *
109b8fdfcc6SHarry Wentland 					interlace_factor;
110b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
111b8fdfcc6SHarry Wentland 
112b8fdfcc6SHarry Wentland 	if (!dce110_timing_generator_validate_timing(
113b8fdfcc6SHarry Wentland 					tg,
114b8fdfcc6SHarry Wentland 					timing,
115b8fdfcc6SHarry Wentland 					signal))
116b8fdfcc6SHarry Wentland 		return false;
117b8fdfcc6SHarry Wentland 
118b8fdfcc6SHarry Wentland 
119b8fdfcc6SHarry Wentland 	if (v_blank < tg110->min_v_blank	||
120b8fdfcc6SHarry Wentland 		 timing->h_sync_width  < tg110->min_h_sync_width ||
121b8fdfcc6SHarry Wentland 		 timing->v_sync_width  < tg110->min_v_sync_width)
122b8fdfcc6SHarry Wentland 		return false;
123b8fdfcc6SHarry Wentland 
124b8fdfcc6SHarry Wentland 	return true;
125b8fdfcc6SHarry Wentland }
126b8fdfcc6SHarry Wentland 
127b8fdfcc6SHarry Wentland bool dce120_tg_validate_timing(struct timing_generator *tg,
128b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing)
129b8fdfcc6SHarry Wentland {
130b8fdfcc6SHarry Wentland 	return dce120_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
131b8fdfcc6SHarry Wentland }
132b8fdfcc6SHarry Wentland 
133b8fdfcc6SHarry Wentland /******** HW programming ************/
134b8fdfcc6SHarry Wentland /* Disable/Enable Timing Generator */
135b8fdfcc6SHarry Wentland bool dce120_timing_generator_enable_crtc(struct timing_generator *tg)
136b8fdfcc6SHarry Wentland {
137b8fdfcc6SHarry Wentland 	enum bp_result result;
138b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
139b8fdfcc6SHarry Wentland 
140b8fdfcc6SHarry Wentland 	/* Set MASTER_UPDATE_MODE to 0
141b8fdfcc6SHarry Wentland 	 * This is needed for DRR, and also suggested to be default value by Syed.*/
142b8fdfcc6SHarry Wentland 
143b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE(CRTC0_CRTC_MASTER_UPDATE_MODE,
144b8fdfcc6SHarry Wentland 			MASTER_UPDATE_MODE, 0);
145b8fdfcc6SHarry Wentland 
146b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE(CRTC0_CRTC_MASTER_UPDATE_LOCK,
147b8fdfcc6SHarry Wentland 			UNDERFLOW_UPDATE_LOCK, 0);
148b8fdfcc6SHarry Wentland 
149b8fdfcc6SHarry Wentland 	/* TODO API for AtomFirmware didn't change*/
150b8fdfcc6SHarry Wentland 	result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, true);
151b8fdfcc6SHarry Wentland 
152b8fdfcc6SHarry Wentland 	return result == BP_RESULT_OK;
153b8fdfcc6SHarry Wentland }
154b8fdfcc6SHarry Wentland 
155b8fdfcc6SHarry Wentland void dce120_timing_generator_set_early_control(
156b8fdfcc6SHarry Wentland 		struct timing_generator *tg,
157b8fdfcc6SHarry Wentland 		uint32_t early_cntl)
158b8fdfcc6SHarry Wentland {
159b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
160b8fdfcc6SHarry Wentland 
161b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE(CRTC0_CRTC_CONTROL,
162b8fdfcc6SHarry Wentland 			CRTC_HBLANK_EARLY_CONTROL, early_cntl);
163b8fdfcc6SHarry Wentland }
164b8fdfcc6SHarry Wentland 
165b8fdfcc6SHarry Wentland /**************** TG current status ******************/
166b8fdfcc6SHarry Wentland 
167b8fdfcc6SHarry Wentland /* return the current frame counter. Used by Linux kernel DRM */
168b8fdfcc6SHarry Wentland uint32_t dce120_timing_generator_get_vblank_counter(
169b8fdfcc6SHarry Wentland 		struct timing_generator *tg)
170b8fdfcc6SHarry Wentland {
171b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
172b8fdfcc6SHarry Wentland 	uint32_t value = dm_read_reg_soc15(
173b8fdfcc6SHarry Wentland 				tg->ctx,
174b8fdfcc6SHarry Wentland 				mmCRTC0_CRTC_STATUS_FRAME_COUNT,
175b8fdfcc6SHarry Wentland 				tg110->offsets.crtc);
176b8fdfcc6SHarry Wentland 	uint32_t field = get_reg_field_value(
177b8fdfcc6SHarry Wentland 				value, CRTC0_CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT);
178b8fdfcc6SHarry Wentland 
179b8fdfcc6SHarry Wentland 	return field;
180b8fdfcc6SHarry Wentland }
181b8fdfcc6SHarry Wentland 
182b8fdfcc6SHarry Wentland /* Get current H and V position */
18372ada5f7SEric Cook void dce120_timing_generator_get_crtc_position(
184b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
18572ada5f7SEric Cook 	struct crtc_position *position)
186b8fdfcc6SHarry Wentland {
187b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
188b8fdfcc6SHarry Wentland 	uint32_t value = dm_read_reg_soc15(
189b8fdfcc6SHarry Wentland 				tg->ctx,
190b8fdfcc6SHarry Wentland 				mmCRTC0_CRTC_STATUS_POSITION,
191b8fdfcc6SHarry Wentland 				tg110->offsets.crtc);
192b8fdfcc6SHarry Wentland 
19372ada5f7SEric Cook 	position->horizontal_count = get_reg_field_value(value,
19472ada5f7SEric Cook 			CRTC0_CRTC_STATUS_POSITION, CRTC_HORZ_COUNT);
195b8fdfcc6SHarry Wentland 
19672ada5f7SEric Cook 	position->vertical_count = get_reg_field_value(value,
19772ada5f7SEric Cook 			CRTC0_CRTC_STATUS_POSITION, CRTC_VERT_COUNT);
19872ada5f7SEric Cook 
19972ada5f7SEric Cook 	value = dm_read_reg_soc15(
20072ada5f7SEric Cook 				tg->ctx,
20172ada5f7SEric Cook 				mmCRTC0_CRTC_NOM_VERT_POSITION,
20272ada5f7SEric Cook 				tg110->offsets.crtc);
20372ada5f7SEric Cook 
20472ada5f7SEric Cook 	position->nominal_vcount = get_reg_field_value(value,
20572ada5f7SEric Cook 			CRTC0_CRTC_NOM_VERT_POSITION, CRTC_VERT_COUNT_NOM);
206b8fdfcc6SHarry Wentland }
207b8fdfcc6SHarry Wentland 
208b8fdfcc6SHarry Wentland /* wait until TG is in beginning of vertical blank region */
209b8fdfcc6SHarry Wentland void dce120_timing_generator_wait_for_vblank(struct timing_generator *tg)
210b8fdfcc6SHarry Wentland {
211b8fdfcc6SHarry Wentland 	/* We want to catch beginning of VBlank here, so if the first try are
212b8fdfcc6SHarry Wentland 	 * in VBlank, we might be very close to Active, in this case wait for
213b8fdfcc6SHarry Wentland 	 * another frame
214b8fdfcc6SHarry Wentland 	 */
215b8fdfcc6SHarry Wentland 	while (dce120_timing_generator_is_in_vertical_blank(tg)) {
216b8fdfcc6SHarry Wentland 		if (!tg->funcs->is_counter_moving(tg)) {
217b8fdfcc6SHarry Wentland 			/* error - no point to wait if counter is not moving */
218b8fdfcc6SHarry Wentland 			break;
219b8fdfcc6SHarry Wentland 		}
220b8fdfcc6SHarry Wentland 	}
221b8fdfcc6SHarry Wentland 
222b8fdfcc6SHarry Wentland 	while (!dce120_timing_generator_is_in_vertical_blank(tg)) {
223b8fdfcc6SHarry Wentland 		if (!tg->funcs->is_counter_moving(tg)) {
224b8fdfcc6SHarry Wentland 			/* error - no point to wait if counter is not moving */
225b8fdfcc6SHarry Wentland 			break;
226b8fdfcc6SHarry Wentland 		}
227b8fdfcc6SHarry Wentland 	}
228b8fdfcc6SHarry Wentland }
229b8fdfcc6SHarry Wentland 
230b8fdfcc6SHarry Wentland /* wait until TG is in beginning of active region */
231b8fdfcc6SHarry Wentland void dce120_timing_generator_wait_for_vactive(struct timing_generator *tg)
232b8fdfcc6SHarry Wentland {
233b8fdfcc6SHarry Wentland 	while (dce120_timing_generator_is_in_vertical_blank(tg)) {
234b8fdfcc6SHarry Wentland 		if (!tg->funcs->is_counter_moving(tg)) {
235b8fdfcc6SHarry Wentland 			/* error - no point to wait if counter is not moving */
236b8fdfcc6SHarry Wentland 			break;
237b8fdfcc6SHarry Wentland 		}
238b8fdfcc6SHarry Wentland 	}
239b8fdfcc6SHarry Wentland }
240b8fdfcc6SHarry Wentland 
241b8fdfcc6SHarry Wentland /*********** Timing Generator Synchronization routines ****/
242b8fdfcc6SHarry Wentland 
243b8fdfcc6SHarry Wentland /* Setups Global Swap Lock group, TimingServer or TimingClient*/
244b8fdfcc6SHarry Wentland void dce120_timing_generator_setup_global_swap_lock(
245b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
246b8fdfcc6SHarry Wentland 	const struct dcp_gsl_params *gsl_params)
247b8fdfcc6SHarry Wentland {
248b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
249b8fdfcc6SHarry Wentland 	uint32_t value_crtc_vtotal =
250b8fdfcc6SHarry Wentland 							dm_read_reg_soc15(tg->ctx,
251b8fdfcc6SHarry Wentland 							mmCRTC0_CRTC_V_TOTAL,
252b8fdfcc6SHarry Wentland 							tg110->offsets.crtc);
253b8fdfcc6SHarry Wentland 	/* Checkpoint relative to end of frame */
254b8fdfcc6SHarry Wentland 	uint32_t check_point =
255b8fdfcc6SHarry Wentland 							get_reg_field_value(value_crtc_vtotal,
256b8fdfcc6SHarry Wentland 							CRTC0_CRTC_V_TOTAL,
257b8fdfcc6SHarry Wentland 							CRTC_V_TOTAL);
258b8fdfcc6SHarry Wentland 
259b8fdfcc6SHarry Wentland 
260b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_GSL_WINDOW, tg110->offsets.crtc, 0);
261b8fdfcc6SHarry Wentland 
262b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_N(DCP0_DCP_GSL_CONTROL, 6,
263b8fdfcc6SHarry Wentland 		/* This pipe will belong to GSL Group zero. */
264b8fdfcc6SHarry Wentland 		FD(DCP0_DCP_GSL_CONTROL__DCP_GSL0_EN), 1,
265b8fdfcc6SHarry Wentland 		FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_MASTER_EN), gsl_params->gsl_master == tg->inst,
266b8fdfcc6SHarry Wentland 		FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_FORCE_DELAY), HFLIP_READY_DELAY,
267b8fdfcc6SHarry Wentland 		/* Keep signal low (pending high) during 6 lines.
268b8fdfcc6SHarry Wentland 		 * Also defines minimum interval before re-checking signal. */
269b8fdfcc6SHarry Wentland 		FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_CHECK_DELAY), HFLIP_CHECK_DELAY,
270b8fdfcc6SHarry Wentland 		/* DCP_GSL_PURPOSE_SURFACE_FLIP */
271b8fdfcc6SHarry Wentland 		FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_SYNC_SOURCE), 0,
272b8fdfcc6SHarry Wentland 		FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_DELAY_SURFACE_UPDATE_PENDING), 1);
273b8fdfcc6SHarry Wentland 
274b8fdfcc6SHarry Wentland 	CRTC_REG_SET_2(
275b8fdfcc6SHarry Wentland 			CRTC0_CRTC_GSL_CONTROL,
276b8fdfcc6SHarry Wentland 			CRTC_GSL_CHECK_LINE_NUM, check_point - FLIP_READY_BACK_LOOKUP,
277b8fdfcc6SHarry Wentland 			CRTC_GSL_FORCE_DELAY, VFLIP_READY_DELAY);
278b8fdfcc6SHarry Wentland }
279b8fdfcc6SHarry Wentland 
280b8fdfcc6SHarry Wentland /* Clear all the register writes done by setup_global_swap_lock */
281b8fdfcc6SHarry Wentland void dce120_timing_generator_tear_down_global_swap_lock(
282b8fdfcc6SHarry Wentland 	struct timing_generator *tg)
283b8fdfcc6SHarry Wentland {
284b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
285b8fdfcc6SHarry Wentland 
286b8fdfcc6SHarry Wentland 	/* Settig HW default values from reg specs */
287b8fdfcc6SHarry Wentland 	CRTC_REG_SET_N(DCP0_DCP_GSL_CONTROL, 6,
288b8fdfcc6SHarry Wentland 			FD(DCP0_DCP_GSL_CONTROL__DCP_GSL0_EN), 0,
289b8fdfcc6SHarry Wentland 			FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_MASTER_EN), 0,
290b8fdfcc6SHarry Wentland 			FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_FORCE_DELAY), HFLIP_READY_DELAY,
291b8fdfcc6SHarry Wentland 			FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_CHECK_DELAY), HFLIP_CHECK_DELAY,
292b8fdfcc6SHarry Wentland 			/* DCP_GSL_PURPOSE_SURFACE_FLIP */
293b8fdfcc6SHarry Wentland 			FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_SYNC_SOURCE), 0,
294b8fdfcc6SHarry Wentland 			FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_DELAY_SURFACE_UPDATE_PENDING), 0);
295b8fdfcc6SHarry Wentland 
296b8fdfcc6SHarry Wentland 		CRTC_REG_SET_2(
297b8fdfcc6SHarry Wentland 			CRTC0_CRTC_GSL_CONTROL,
298b8fdfcc6SHarry Wentland 			CRTC_GSL_CHECK_LINE_NUM, 0,
299b8fdfcc6SHarry Wentland 			CRTC_GSL_FORCE_DELAY, 0x2); /*TODO Why this value here ?*/
300b8fdfcc6SHarry Wentland }
301b8fdfcc6SHarry Wentland 
302b8fdfcc6SHarry Wentland /* Reset slave controllers on master VSync */
303b8fdfcc6SHarry Wentland void dce120_timing_generator_enable_reset_trigger(
304b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
305b8fdfcc6SHarry Wentland 	int source)
306b8fdfcc6SHarry Wentland {
307b8fdfcc6SHarry Wentland 	enum trigger_source_select trig_src_select = TRIGGER_SOURCE_SELECT_LOGIC_ZERO;
308b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
309b8fdfcc6SHarry Wentland 	uint32_t rising_edge = 0;
310b8fdfcc6SHarry Wentland 	uint32_t falling_edge = 0;
311b8fdfcc6SHarry Wentland 	/* Setup trigger edge */
312b8fdfcc6SHarry Wentland 	uint32_t pol_value = dm_read_reg_soc15(
313b8fdfcc6SHarry Wentland 									tg->ctx,
314b8fdfcc6SHarry Wentland 									mmCRTC0_CRTC_V_SYNC_A_CNTL,
315b8fdfcc6SHarry Wentland 									tg110->offsets.crtc);
316b8fdfcc6SHarry Wentland 
317b8fdfcc6SHarry Wentland 	/* Register spec has reversed definition:
318b8fdfcc6SHarry Wentland 	 *	0 for positive, 1 for negative */
319b8fdfcc6SHarry Wentland 	if (get_reg_field_value(pol_value,
320b8fdfcc6SHarry Wentland 			CRTC0_CRTC_V_SYNC_A_CNTL,
321b8fdfcc6SHarry Wentland 			CRTC_V_SYNC_A_POL) == 0) {
322b8fdfcc6SHarry Wentland 		rising_edge = 1;
323b8fdfcc6SHarry Wentland 	} else {
324b8fdfcc6SHarry Wentland 		falling_edge = 1;
325b8fdfcc6SHarry Wentland 	}
326b8fdfcc6SHarry Wentland 
327b8fdfcc6SHarry Wentland 	/* TODO What about other sources ?*/
328b8fdfcc6SHarry Wentland 	trig_src_select = TRIGGER_SOURCE_SELECT_GSL_GROUP0;
329b8fdfcc6SHarry Wentland 
330b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_N(CRTC0_CRTC_TRIGB_CNTL, 7,
331b8fdfcc6SHarry Wentland 		FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_SOURCE_SELECT), trig_src_select,
332b8fdfcc6SHarry Wentland 		FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_POLARITY_SELECT), TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
333b8fdfcc6SHarry Wentland 		FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_RISING_EDGE_DETECT_CNTL), rising_edge,
334b8fdfcc6SHarry Wentland 		FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL), falling_edge,
335b8fdfcc6SHarry Wentland 		/* send every signal */
336b8fdfcc6SHarry Wentland 		FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_FREQUENCY_SELECT), 0,
337b8fdfcc6SHarry Wentland 		/* no delay */
338b8fdfcc6SHarry Wentland 		FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_DELAY), 0,
339b8fdfcc6SHarry Wentland 		/* clear trigger status */
340b8fdfcc6SHarry Wentland 		FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_CLEAR), 1);
341b8fdfcc6SHarry Wentland 
342b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_3(
343b8fdfcc6SHarry Wentland 			CRTC0_CRTC_FORCE_COUNT_NOW_CNTL,
344b8fdfcc6SHarry Wentland 			CRTC_FORCE_COUNT_NOW_MODE, 2,
345b8fdfcc6SHarry Wentland 			CRTC_FORCE_COUNT_NOW_TRIG_SEL, 1,
346b8fdfcc6SHarry Wentland 			CRTC_FORCE_COUNT_NOW_CLEAR, 1);
347b8fdfcc6SHarry Wentland }
348b8fdfcc6SHarry Wentland 
349b8fdfcc6SHarry Wentland /* disabling trigger-reset */
350b8fdfcc6SHarry Wentland void dce120_timing_generator_disable_reset_trigger(
351b8fdfcc6SHarry Wentland 	struct timing_generator *tg)
352b8fdfcc6SHarry Wentland {
353b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
354b8fdfcc6SHarry Wentland 
355b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_2(
356b8fdfcc6SHarry Wentland 		CRTC0_CRTC_FORCE_COUNT_NOW_CNTL,
357b8fdfcc6SHarry Wentland 		CRTC_FORCE_COUNT_NOW_MODE, 0,
358b8fdfcc6SHarry Wentland 		CRTC_FORCE_COUNT_NOW_CLEAR, 1);
359b8fdfcc6SHarry Wentland 
360b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_3(
361b8fdfcc6SHarry Wentland 		CRTC0_CRTC_TRIGB_CNTL,
362b8fdfcc6SHarry Wentland 		CRTC_TRIGB_SOURCE_SELECT, TRIGGER_SOURCE_SELECT_LOGIC_ZERO,
363b8fdfcc6SHarry Wentland 		CRTC_TRIGB_POLARITY_SELECT, TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
364b8fdfcc6SHarry Wentland 		/* clear trigger status */
365b8fdfcc6SHarry Wentland 		CRTC_TRIGB_CLEAR, 1);
366b8fdfcc6SHarry Wentland 
367b8fdfcc6SHarry Wentland }
368b8fdfcc6SHarry Wentland 
369b8fdfcc6SHarry Wentland /* Checks whether CRTC triggered reset occurred */
370b8fdfcc6SHarry Wentland bool dce120_timing_generator_did_triggered_reset_occur(
371b8fdfcc6SHarry Wentland 	struct timing_generator *tg)
372b8fdfcc6SHarry Wentland {
373b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
374b8fdfcc6SHarry Wentland 	uint32_t value = dm_read_reg_soc15(
375b8fdfcc6SHarry Wentland 			tg->ctx,
376b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_FORCE_COUNT_NOW_CNTL,
377b8fdfcc6SHarry Wentland 			tg110->offsets.crtc);
378b8fdfcc6SHarry Wentland 
379b8fdfcc6SHarry Wentland 	return get_reg_field_value(value,
380b8fdfcc6SHarry Wentland 			CRTC0_CRTC_FORCE_COUNT_NOW_CNTL,
381b8fdfcc6SHarry Wentland 			CRTC_FORCE_COUNT_NOW_OCCURRED) != 0;
382b8fdfcc6SHarry Wentland }
383b8fdfcc6SHarry Wentland 
384b8fdfcc6SHarry Wentland 
385b8fdfcc6SHarry Wentland /******** Stuff to move to other virtual HW objects *****************/
386b8fdfcc6SHarry Wentland /* Move to enable accelerated mode */
387b8fdfcc6SHarry Wentland void dce120_timing_generator_disable_vga(struct timing_generator *tg)
388b8fdfcc6SHarry Wentland {
389b8fdfcc6SHarry Wentland 	uint32_t addr = 0;
390b8fdfcc6SHarry Wentland 	uint32_t offset = 0;
391b8fdfcc6SHarry Wentland 	uint32_t value = 0;
392b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
393b8fdfcc6SHarry Wentland 
394b8fdfcc6SHarry Wentland 	switch (tg110->controller_id) {
395b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D0:
396b8fdfcc6SHarry Wentland 		addr = mmD1VGA_CONTROL;
397b8fdfcc6SHarry Wentland 		offset = 0;
398b8fdfcc6SHarry Wentland 		break;
399b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D1:
400b8fdfcc6SHarry Wentland 		addr = mmD2VGA_CONTROL;
401b8fdfcc6SHarry Wentland 		offset = mmD2VGA_CONTROL - mmD1VGA_CONTROL;
402b8fdfcc6SHarry Wentland 		break;
403b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D2:
404b8fdfcc6SHarry Wentland 		addr = mmD3VGA_CONTROL;
405b8fdfcc6SHarry Wentland 		offset = mmD3VGA_CONTROL - mmD1VGA_CONTROL;
406b8fdfcc6SHarry Wentland 		break;
407b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D3:
408b8fdfcc6SHarry Wentland 		addr = mmD4VGA_CONTROL;
409b8fdfcc6SHarry Wentland 		offset = mmD4VGA_CONTROL - mmD1VGA_CONTROL;
410b8fdfcc6SHarry Wentland 		break;
411b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D4:
412b8fdfcc6SHarry Wentland 		addr = mmD1VGA_CONTROL;
413ccaf31ecSRoman Li 		offset = mmD5VGA_CONTROL - mmD1VGA_CONTROL;
414b8fdfcc6SHarry Wentland 		break;
415b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D5:
416b8fdfcc6SHarry Wentland 		addr = mmD6VGA_CONTROL;
417b8fdfcc6SHarry Wentland 		offset = mmD6VGA_CONTROL - mmD1VGA_CONTROL;
418b8fdfcc6SHarry Wentland 		break;
419b8fdfcc6SHarry Wentland 	default:
420b8fdfcc6SHarry Wentland 		break;
421b8fdfcc6SHarry Wentland 	}
422b8fdfcc6SHarry Wentland 
423b8fdfcc6SHarry Wentland 	value = dm_read_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset);
424b8fdfcc6SHarry Wentland 
425b8fdfcc6SHarry Wentland 	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE);
426b8fdfcc6SHarry Wentland 	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT);
427b8fdfcc6SHarry Wentland 	set_reg_field_value(
428b8fdfcc6SHarry Wentland 			value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT);
429b8fdfcc6SHarry Wentland 	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN);
430b8fdfcc6SHarry Wentland 
431b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset, value);
432b8fdfcc6SHarry Wentland }
433b8fdfcc6SHarry Wentland /* TODO: Should we move it to transform */
434b8fdfcc6SHarry Wentland /* Fully program CRTC timing in timing generator */
435b8fdfcc6SHarry Wentland void dce120_timing_generator_program_blanking(
436b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
437b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing)
438b8fdfcc6SHarry Wentland {
439b8fdfcc6SHarry Wentland 	uint32_t tmp1 = 0;
440b8fdfcc6SHarry Wentland 	uint32_t tmp2 = 0;
441b8fdfcc6SHarry Wentland 	uint32_t vsync_offset = timing->v_border_bottom +
442b8fdfcc6SHarry Wentland 			timing->v_front_porch;
443b8fdfcc6SHarry Wentland 	uint32_t v_sync_start = timing->v_addressable + vsync_offset;
444b8fdfcc6SHarry Wentland 
445b8fdfcc6SHarry Wentland 	uint32_t hsync_offset = timing->h_border_right +
446b8fdfcc6SHarry Wentland 			timing->h_front_porch;
447b8fdfcc6SHarry Wentland 	uint32_t h_sync_start = timing->h_addressable + hsync_offset;
448b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
449b8fdfcc6SHarry Wentland 
450b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE(
451b8fdfcc6SHarry Wentland 			CRTC0_CRTC_H_TOTAL,
452b8fdfcc6SHarry Wentland 			CRTC_H_TOTAL,
453b8fdfcc6SHarry Wentland 			timing->h_total - 1);
454b8fdfcc6SHarry Wentland 
455b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE(
456b8fdfcc6SHarry Wentland 		CRTC0_CRTC_V_TOTAL,
457b8fdfcc6SHarry Wentland 		CRTC_V_TOTAL,
458b8fdfcc6SHarry Wentland 		timing->v_total - 1);
459b8fdfcc6SHarry Wentland 
460b8fdfcc6SHarry Wentland 	tmp1 = timing->h_total -
461b8fdfcc6SHarry Wentland 			(h_sync_start + timing->h_border_left);
462b8fdfcc6SHarry Wentland 	tmp2 = tmp1 + timing->h_addressable +
463b8fdfcc6SHarry Wentland 			timing->h_border_left + timing->h_border_right;
464b8fdfcc6SHarry Wentland 
465b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_2(
466b8fdfcc6SHarry Wentland 			CRTC0_CRTC_H_BLANK_START_END,
467b8fdfcc6SHarry Wentland 			CRTC_H_BLANK_END, tmp1,
468b8fdfcc6SHarry Wentland 			CRTC_H_BLANK_START, tmp2);
469b8fdfcc6SHarry Wentland 
470b8fdfcc6SHarry Wentland 	tmp1 = timing->v_total - (v_sync_start + timing->v_border_top);
471b8fdfcc6SHarry Wentland 	tmp2 = tmp1 + timing->v_addressable + timing->v_border_top +
472b8fdfcc6SHarry Wentland 			timing->v_border_bottom;
473b8fdfcc6SHarry Wentland 
474b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_2(
475b8fdfcc6SHarry Wentland 		CRTC0_CRTC_V_BLANK_START_END,
476b8fdfcc6SHarry Wentland 		CRTC_V_BLANK_END, tmp1,
477b8fdfcc6SHarry Wentland 		CRTC_V_BLANK_START, tmp2);
478b8fdfcc6SHarry Wentland }
479b8fdfcc6SHarry Wentland 
480b8fdfcc6SHarry Wentland /* TODO: Should we move it to opp? */
481b8fdfcc6SHarry Wentland /* Combine with below and move YUV/RGB color conversion to SW layer */
482b8fdfcc6SHarry Wentland void dce120_timing_generator_program_blank_color(
483b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
484b8fdfcc6SHarry Wentland 	const struct tg_color *black_color)
485b8fdfcc6SHarry Wentland {
486b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
487b8fdfcc6SHarry Wentland 
488b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_3(
489b8fdfcc6SHarry Wentland 		CRTC0_CRTC_BLACK_COLOR,
490b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb,
491b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_G_Y, black_color->color_g_y,
492b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr);
493b8fdfcc6SHarry Wentland }
494b8fdfcc6SHarry Wentland /* Combine with above and move YUV/RGB color conversion to SW layer */
495b8fdfcc6SHarry Wentland void dce120_timing_generator_set_overscan_color_black(
496b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
497b8fdfcc6SHarry Wentland 	const struct tg_color *color)
498b8fdfcc6SHarry Wentland {
499b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
500b8fdfcc6SHarry Wentland 	uint32_t value = 0;
501b8fdfcc6SHarry Wentland 	CRTC_REG_SET_3(
502b8fdfcc6SHarry Wentland 		CRTC0_CRTC_OVERSCAN_COLOR,
503b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_BLUE, color->color_b_cb,
504b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_GREEN, color->color_g_y,
505b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_RED, color->color_r_cr);
506b8fdfcc6SHarry Wentland 
507b8fdfcc6SHarry Wentland 	value = dm_read_reg_soc15(
508b8fdfcc6SHarry Wentland 			tg->ctx,
509b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_OVERSCAN_COLOR,
510b8fdfcc6SHarry Wentland 			tg110->offsets.crtc);
511b8fdfcc6SHarry Wentland 
512b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(
513b8fdfcc6SHarry Wentland 			tg->ctx,
514b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_BLACK_COLOR,
515b8fdfcc6SHarry Wentland 			tg110->offsets.crtc,
516b8fdfcc6SHarry Wentland 			value);
517b8fdfcc6SHarry Wentland 
518b8fdfcc6SHarry Wentland 	/* This is desirable to have a constant DAC output voltage during the
519b8fdfcc6SHarry Wentland 	 * blank time that is higher than the 0 volt reference level that the
520b8fdfcc6SHarry Wentland 	 * DAC outputs when the NBLANK signal
521b8fdfcc6SHarry Wentland 	 * is asserted low, such as for output to an analog TV. */
522b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(
523b8fdfcc6SHarry Wentland 		tg->ctx,
524b8fdfcc6SHarry Wentland 		mmCRTC0_CRTC_BLANK_DATA_COLOR,
525b8fdfcc6SHarry Wentland 		tg110->offsets.crtc,
526b8fdfcc6SHarry Wentland 		value);
527b8fdfcc6SHarry Wentland 
528b8fdfcc6SHarry Wentland 	/* TO DO we have to program EXT registers and we need to know LB DATA
529b8fdfcc6SHarry Wentland 	 * format because it is used when more 10 , i.e. 12 bits per color
530b8fdfcc6SHarry Wentland 	 *
531b8fdfcc6SHarry Wentland 	 * m_mmDxCRTC_OVERSCAN_COLOR_EXT
532b8fdfcc6SHarry Wentland 	 * m_mmDxCRTC_BLACK_COLOR_EXT
533b8fdfcc6SHarry Wentland 	 * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
534b8fdfcc6SHarry Wentland 	 */
535b8fdfcc6SHarry Wentland }
536b8fdfcc6SHarry Wentland 
537b8fdfcc6SHarry Wentland void dce120_timing_generator_set_drr(
538b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
539b8fdfcc6SHarry Wentland 	const struct drr_params *params)
540b8fdfcc6SHarry Wentland {
541b8fdfcc6SHarry Wentland 
542b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
543b8fdfcc6SHarry Wentland 
544b8fdfcc6SHarry Wentland 	if (params != NULL &&
545b8fdfcc6SHarry Wentland 		params->vertical_total_max > 0 &&
546b8fdfcc6SHarry Wentland 		params->vertical_total_min > 0) {
547b8fdfcc6SHarry Wentland 
548b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
549b8fdfcc6SHarry Wentland 				CRTC0_CRTC_V_TOTAL_MIN,
5506c626ffbSYongqiang Sun 				CRTC_V_TOTAL_MIN, params->vertical_total_min - 1);
551b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
552b8fdfcc6SHarry Wentland 				CRTC0_CRTC_V_TOTAL_MAX,
5536c626ffbSYongqiang Sun 				CRTC_V_TOTAL_MAX, params->vertical_total_max - 1);
554b8fdfcc6SHarry Wentland 		CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 6,
555b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 1,
556b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 1,
557b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0,
558b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0,
559b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK_EN), 0,
560b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0);
561b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
562b8fdfcc6SHarry Wentland 				CRTC0_CRTC_STATIC_SCREEN_CONTROL,
563b8fdfcc6SHarry Wentland 				CRTC_STATIC_SCREEN_EVENT_MASK,
564b8fdfcc6SHarry Wentland 				0x180);
565b8fdfcc6SHarry Wentland 
566b8fdfcc6SHarry Wentland 	} else {
567b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
568b8fdfcc6SHarry Wentland 				CRTC0_CRTC_V_TOTAL_MIN,
569b8fdfcc6SHarry Wentland 				CRTC_V_TOTAL_MIN, 0);
570b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
571b8fdfcc6SHarry Wentland 				CRTC0_CRTC_V_TOTAL_MAX,
572b8fdfcc6SHarry Wentland 				CRTC_V_TOTAL_MAX, 0);
573b8fdfcc6SHarry Wentland 		CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 5,
574b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 0,
575b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 0,
576b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0,
577b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0,
578b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0);
579b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
580b8fdfcc6SHarry Wentland 				CRTC0_CRTC_STATIC_SCREEN_CONTROL,
581b8fdfcc6SHarry Wentland 				CRTC_STATIC_SCREEN_EVENT_MASK,
582b8fdfcc6SHarry Wentland 				0);
583b8fdfcc6SHarry Wentland 	}
584b8fdfcc6SHarry Wentland }
585b8fdfcc6SHarry Wentland 
58672ada5f7SEric Cook /**
58772ada5f7SEric Cook  *****************************************************************************
58872ada5f7SEric Cook  *  Function: dce120_timing_generator_get_position
58972ada5f7SEric Cook  *
59072ada5f7SEric Cook  *  @brief
59172ada5f7SEric Cook  *     Returns CRTC vertical/horizontal counters
59272ada5f7SEric Cook  *
59372ada5f7SEric Cook  *  @param [out] position
59472ada5f7SEric Cook  *****************************************************************************
59572ada5f7SEric Cook  */
59672ada5f7SEric Cook void dce120_timing_generator_get_position(struct timing_generator *tg,
59772ada5f7SEric Cook 	struct crtc_position *position)
59872ada5f7SEric Cook {
59972ada5f7SEric Cook 	uint32_t value;
60072ada5f7SEric Cook 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
60172ada5f7SEric Cook 
60272ada5f7SEric Cook 	value = dm_read_reg_soc15(
60372ada5f7SEric Cook 			tg->ctx,
60472ada5f7SEric Cook 			mmCRTC0_CRTC_STATUS_POSITION,
60572ada5f7SEric Cook 			tg110->offsets.crtc);
60672ada5f7SEric Cook 
60772ada5f7SEric Cook 	position->horizontal_count = get_reg_field_value(
60872ada5f7SEric Cook 			value,
60972ada5f7SEric Cook 			CRTC0_CRTC_STATUS_POSITION,
61072ada5f7SEric Cook 			CRTC_HORZ_COUNT);
61172ada5f7SEric Cook 
61272ada5f7SEric Cook 	position->vertical_count = get_reg_field_value(
61372ada5f7SEric Cook 			value,
61472ada5f7SEric Cook 			CRTC0_CRTC_STATUS_POSITION,
61572ada5f7SEric Cook 			CRTC_VERT_COUNT);
61672ada5f7SEric Cook 
61772ada5f7SEric Cook 	value = dm_read_reg_soc15(
61872ada5f7SEric Cook 			tg->ctx,
61972ada5f7SEric Cook 			mmCRTC0_CRTC_NOM_VERT_POSITION,
62072ada5f7SEric Cook 			tg110->offsets.crtc);
62172ada5f7SEric Cook 
62272ada5f7SEric Cook 	position->nominal_vcount = get_reg_field_value(
62372ada5f7SEric Cook 			value,
62472ada5f7SEric Cook 			CRTC0_CRTC_NOM_VERT_POSITION,
62572ada5f7SEric Cook 			CRTC_VERT_COUNT_NOM);
62672ada5f7SEric Cook }
62772ada5f7SEric Cook 
62872ada5f7SEric Cook 
62981c50963SSylvia Tsai void dce120_timing_generator_get_crtc_scanoutpos(
630b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
63181c50963SSylvia Tsai 	uint32_t *v_blank_start,
63281c50963SSylvia Tsai 	uint32_t *v_blank_end,
63381c50963SSylvia Tsai 	uint32_t *h_position,
63481c50963SSylvia Tsai 	uint32_t *v_position)
635b8fdfcc6SHarry Wentland {
636b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
63772ada5f7SEric Cook 	struct crtc_position position;
638b8fdfcc6SHarry Wentland 
63981c50963SSylvia Tsai 	uint32_t v_blank_start_end = dm_read_reg_soc15(
640b8fdfcc6SHarry Wentland 			tg->ctx,
641b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_V_BLANK_START_END,
642b8fdfcc6SHarry Wentland 			tg110->offsets.crtc);
643b8fdfcc6SHarry Wentland 
64481c50963SSylvia Tsai 	*v_blank_start = get_reg_field_value(v_blank_start_end,
64581c50963SSylvia Tsai 					     CRTC0_CRTC_V_BLANK_START_END,
64681c50963SSylvia Tsai 					     CRTC_V_BLANK_START);
64781c50963SSylvia Tsai 	*v_blank_end = get_reg_field_value(v_blank_start_end,
64881c50963SSylvia Tsai 					   CRTC0_CRTC_V_BLANK_START_END,
64981c50963SSylvia Tsai 					   CRTC_V_BLANK_END);
650b8fdfcc6SHarry Wentland 
65172ada5f7SEric Cook 	dce120_timing_generator_get_crtc_position(
65272ada5f7SEric Cook 			tg, &position);
65372ada5f7SEric Cook 
65472ada5f7SEric Cook 	*h_position = position.horizontal_count;
65572ada5f7SEric Cook 	*v_position = position.vertical_count;
656b8fdfcc6SHarry Wentland }
657b8fdfcc6SHarry Wentland 
658b8fdfcc6SHarry Wentland void dce120_timing_generator_enable_advanced_request(
659b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
660b8fdfcc6SHarry Wentland 	bool enable,
661b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing)
662b8fdfcc6SHarry Wentland {
663b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
664b8fdfcc6SHarry Wentland 	uint32_t v_sync_width_and_b_porch =
665b8fdfcc6SHarry Wentland 				timing->v_total - timing->v_addressable -
666b8fdfcc6SHarry Wentland 				timing->v_border_bottom - timing->v_front_porch;
667b8fdfcc6SHarry Wentland 	uint32_t value = dm_read_reg_soc15(
668b8fdfcc6SHarry Wentland 				tg->ctx,
669b8fdfcc6SHarry Wentland 				mmCRTC0_CRTC_START_LINE_CONTROL,
670b8fdfcc6SHarry Wentland 				tg110->offsets.crtc);
671b8fdfcc6SHarry Wentland 
672b8fdfcc6SHarry Wentland 	set_reg_field_value(
673b8fdfcc6SHarry Wentland 		value,
674*a4b0a5b8STom St Denis 		enable ? 0 : 1,
675b8fdfcc6SHarry Wentland 		CRTC0_CRTC_START_LINE_CONTROL,
676b8fdfcc6SHarry Wentland 		CRTC_LEGACY_REQUESTOR_EN);
677b8fdfcc6SHarry Wentland 
678b8fdfcc6SHarry Wentland 	/* Program advanced line position acc.to the best case from fetching data perspective to hide MC latency
679b8fdfcc6SHarry Wentland 	 * and prefilling Line Buffer in V Blank (to 10 lines as LB can store max 10 lines)
680b8fdfcc6SHarry Wentland 	 */
681b8fdfcc6SHarry Wentland 	if (v_sync_width_and_b_porch > 10)
682*a4b0a5b8STom St Denis 		v_sync_width_and_b_porch = 10;
683*a4b0a5b8STom St Denis 
684b8fdfcc6SHarry Wentland 	set_reg_field_value(
685b8fdfcc6SHarry Wentland 		value,
686b8fdfcc6SHarry Wentland 		v_sync_width_and_b_porch,
687b8fdfcc6SHarry Wentland 		CRTC0_CRTC_START_LINE_CONTROL,
688b8fdfcc6SHarry Wentland 		CRTC_ADVANCED_START_LINE_POSITION);
689b8fdfcc6SHarry Wentland 
690b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(tg->ctx,
691b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_START_LINE_CONTROL,
692b8fdfcc6SHarry Wentland 			tg110->offsets.crtc,
693b8fdfcc6SHarry Wentland 			value);
694b8fdfcc6SHarry Wentland }
695b8fdfcc6SHarry Wentland 
696b8fdfcc6SHarry Wentland void dce120_tg_program_blank_color(struct timing_generator *tg,
697b8fdfcc6SHarry Wentland 	const struct tg_color *black_color)
698b8fdfcc6SHarry Wentland {
699b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
700b8fdfcc6SHarry Wentland 	uint32_t value = 0;
701b8fdfcc6SHarry Wentland 
702b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_3(
703b8fdfcc6SHarry Wentland 		CRTC0_CRTC_BLACK_COLOR,
704b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb,
705b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_G_Y, black_color->color_g_y,
706b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr);
707b8fdfcc6SHarry Wentland 
708b8fdfcc6SHarry Wentland 	value = dm_read_reg_soc15(
709b8fdfcc6SHarry Wentland 				tg->ctx,
710b8fdfcc6SHarry Wentland 				mmCRTC0_CRTC_BLACK_COLOR,
711b8fdfcc6SHarry Wentland 				tg110->offsets.crtc);
712b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(
713b8fdfcc6SHarry Wentland 		tg->ctx,
714b8fdfcc6SHarry Wentland 		mmCRTC0_CRTC_BLANK_DATA_COLOR,
715b8fdfcc6SHarry Wentland 		tg110->offsets.crtc,
716b8fdfcc6SHarry Wentland 		value);
717b8fdfcc6SHarry Wentland }
718b8fdfcc6SHarry Wentland 
719b8fdfcc6SHarry Wentland void dce120_tg_set_overscan_color(struct timing_generator *tg,
720b8fdfcc6SHarry Wentland 	const struct tg_color *overscan_color)
721b8fdfcc6SHarry Wentland {
722b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
723b8fdfcc6SHarry Wentland 
724b8fdfcc6SHarry Wentland 	CRTC_REG_SET_3(
725b8fdfcc6SHarry Wentland 		CRTC0_CRTC_OVERSCAN_COLOR,
726b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_BLUE, overscan_color->color_b_cb,
727b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_GREEN, overscan_color->color_g_y,
728b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_RED, overscan_color->color_r_cr);
729b8fdfcc6SHarry Wentland }
730b8fdfcc6SHarry Wentland 
731b8fdfcc6SHarry Wentland void dce120_tg_program_timing(struct timing_generator *tg,
732b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing,
733b8fdfcc6SHarry Wentland 	bool use_vbios)
734b8fdfcc6SHarry Wentland {
735b8fdfcc6SHarry Wentland 	if (use_vbios)
736b8fdfcc6SHarry Wentland 			dce110_timing_generator_program_timing_generator(tg, timing);
737b8fdfcc6SHarry Wentland 		else
738b8fdfcc6SHarry Wentland 			dce120_timing_generator_program_blanking(tg, timing);
739b8fdfcc6SHarry Wentland }
740b8fdfcc6SHarry Wentland 
741b8fdfcc6SHarry Wentland bool dce120_tg_is_blanked(struct timing_generator *tg)
742b8fdfcc6SHarry Wentland {
743b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
744b8fdfcc6SHarry Wentland 	uint32_t value = dm_read_reg_soc15(
745b8fdfcc6SHarry Wentland 			tg->ctx,
746b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_BLANK_CONTROL,
747b8fdfcc6SHarry Wentland 			tg110->offsets.crtc);
748b8fdfcc6SHarry Wentland 
749b8fdfcc6SHarry Wentland 	if (
750b8fdfcc6SHarry Wentland 		get_reg_field_value(
751b8fdfcc6SHarry Wentland 			value,
752b8fdfcc6SHarry Wentland 			CRTC0_CRTC_BLANK_CONTROL,
753b8fdfcc6SHarry Wentland 			CRTC_BLANK_DATA_EN) == 1	&&
754b8fdfcc6SHarry Wentland 		get_reg_field_value(
755b8fdfcc6SHarry Wentland 			value,
756b8fdfcc6SHarry Wentland 			CRTC0_CRTC_BLANK_CONTROL,
757b8fdfcc6SHarry Wentland 			CRTC_CURRENT_BLANK_STATE) == 1)
758b8fdfcc6SHarry Wentland 			return true;
759b8fdfcc6SHarry Wentland 
760b8fdfcc6SHarry Wentland 	return false;
761b8fdfcc6SHarry Wentland }
762b8fdfcc6SHarry Wentland 
763b8fdfcc6SHarry Wentland void dce120_tg_set_blank(struct timing_generator *tg,
764b8fdfcc6SHarry Wentland 		bool enable_blanking)
765b8fdfcc6SHarry Wentland {
766b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
767b8fdfcc6SHarry Wentland 
768b8fdfcc6SHarry Wentland 	CRTC_REG_SET(
769b8fdfcc6SHarry Wentland 		CRTC0_CRTC_DOUBLE_BUFFER_CONTROL,
770b8fdfcc6SHarry Wentland 		CRTC_BLANK_DATA_DOUBLE_BUFFER_EN, 0);
771b8fdfcc6SHarry Wentland 
772b8fdfcc6SHarry Wentland 	if (enable_blanking) {
773b8fdfcc6SHarry Wentland 		CRTC_REG_SET(
774b8fdfcc6SHarry Wentland 			CRTC0_CRTC_BLANK_CONTROL,
775b8fdfcc6SHarry Wentland 			CRTC_BLANK_DATA_EN, 1);
776b8fdfcc6SHarry Wentland 
777b8fdfcc6SHarry Wentland 	} else
778b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(
779b8fdfcc6SHarry Wentland 			tg->ctx,
780b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_BLANK_CONTROL,
781b8fdfcc6SHarry Wentland 			tg110->offsets.crtc,
782b8fdfcc6SHarry Wentland 			0);
783b8fdfcc6SHarry Wentland }
784b8fdfcc6SHarry Wentland 
785b8fdfcc6SHarry Wentland bool dce120_tg_validate_timing(struct timing_generator *tg,
786b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing);
787b8fdfcc6SHarry Wentland 
788b8fdfcc6SHarry Wentland void dce120_tg_wait_for_state(struct timing_generator *tg,
789b8fdfcc6SHarry Wentland 	enum crtc_state state)
790b8fdfcc6SHarry Wentland {
791b8fdfcc6SHarry Wentland 	switch (state) {
792b8fdfcc6SHarry Wentland 	case CRTC_STATE_VBLANK:
793b8fdfcc6SHarry Wentland 		dce120_timing_generator_wait_for_vblank(tg);
794b8fdfcc6SHarry Wentland 		break;
795b8fdfcc6SHarry Wentland 
796b8fdfcc6SHarry Wentland 	case CRTC_STATE_VACTIVE:
797b8fdfcc6SHarry Wentland 		dce120_timing_generator_wait_for_vactive(tg);
798b8fdfcc6SHarry Wentland 		break;
799b8fdfcc6SHarry Wentland 
800b8fdfcc6SHarry Wentland 	default:
801b8fdfcc6SHarry Wentland 		break;
802b8fdfcc6SHarry Wentland 	}
803b8fdfcc6SHarry Wentland }
804b8fdfcc6SHarry Wentland 
805b8fdfcc6SHarry Wentland void dce120_tg_set_colors(struct timing_generator *tg,
806b8fdfcc6SHarry Wentland 	const struct tg_color *blank_color,
807b8fdfcc6SHarry Wentland 	const struct tg_color *overscan_color)
808b8fdfcc6SHarry Wentland {
809b8fdfcc6SHarry Wentland 	if (blank_color != NULL)
810b8fdfcc6SHarry Wentland 		dce120_tg_program_blank_color(tg, blank_color);
811b8fdfcc6SHarry Wentland 
812b8fdfcc6SHarry Wentland 	if (overscan_color != NULL)
813b8fdfcc6SHarry Wentland 		dce120_tg_set_overscan_color(tg, overscan_color);
814b8fdfcc6SHarry Wentland }
815b8fdfcc6SHarry Wentland 
816b8fdfcc6SHarry Wentland static void dce120_timing_generator_set_static_screen_control(
817b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
818b8fdfcc6SHarry Wentland 	uint32_t value)
819b8fdfcc6SHarry Wentland {
820b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
821b8fdfcc6SHarry Wentland 
822b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_2(CRTC0_CRTC_STATIC_SCREEN_CONTROL,
823b8fdfcc6SHarry Wentland 			CRTC_STATIC_SCREEN_EVENT_MASK, value,
824b8fdfcc6SHarry Wentland 			CRTC_STATIC_SCREEN_FRAME_COUNT, 2);
825b8fdfcc6SHarry Wentland }
826b8fdfcc6SHarry Wentland 
827b8fdfcc6SHarry Wentland void dce120_timing_generator_set_test_pattern(
828b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
829b8fdfcc6SHarry Wentland 	/* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
830b8fdfcc6SHarry Wentland 	 * because this is not DP-specific (which is probably somewhere in DP
831b8fdfcc6SHarry Wentland 	 * encoder) */
832b8fdfcc6SHarry Wentland 	enum controller_dp_test_pattern test_pattern,
833b8fdfcc6SHarry Wentland 	enum dc_color_depth color_depth)
834b8fdfcc6SHarry Wentland {
835b8fdfcc6SHarry Wentland 	struct dc_context *ctx = tg->ctx;
836b8fdfcc6SHarry Wentland 	uint32_t value;
837b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
838b8fdfcc6SHarry Wentland 	enum test_pattern_color_format bit_depth;
839b8fdfcc6SHarry Wentland 	enum test_pattern_dyn_range dyn_range;
840b8fdfcc6SHarry Wentland 	enum test_pattern_mode mode;
841b8fdfcc6SHarry Wentland 	/* color ramp generator mixes 16-bits color */
842b8fdfcc6SHarry Wentland 	uint32_t src_bpc = 16;
843b8fdfcc6SHarry Wentland 	/* requested bpc */
844b8fdfcc6SHarry Wentland 	uint32_t dst_bpc;
845b8fdfcc6SHarry Wentland 	uint32_t index;
846b8fdfcc6SHarry Wentland 	/* RGB values of the color bars.
847b8fdfcc6SHarry Wentland 	 * Produce two RGB colors: RGB0 - white (all Fs)
848b8fdfcc6SHarry Wentland 	 * and RGB1 - black (all 0s)
849b8fdfcc6SHarry Wentland 	 * (three RGB components for two colors)
850b8fdfcc6SHarry Wentland 	 */
851b8fdfcc6SHarry Wentland 	uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
852b8fdfcc6SHarry Wentland 						0x0000, 0x0000};
853b8fdfcc6SHarry Wentland 	/* dest color (converted to the specified color format) */
854b8fdfcc6SHarry Wentland 	uint16_t dst_color[6];
855b8fdfcc6SHarry Wentland 	uint32_t inc_base;
856b8fdfcc6SHarry Wentland 
857b8fdfcc6SHarry Wentland 	/* translate to bit depth */
858b8fdfcc6SHarry Wentland 	switch (color_depth) {
859b8fdfcc6SHarry Wentland 	case COLOR_DEPTH_666:
860b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
861b8fdfcc6SHarry Wentland 	break;
862b8fdfcc6SHarry Wentland 	case COLOR_DEPTH_888:
863b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
864b8fdfcc6SHarry Wentland 	break;
865b8fdfcc6SHarry Wentland 	case COLOR_DEPTH_101010:
866b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
867b8fdfcc6SHarry Wentland 	break;
868b8fdfcc6SHarry Wentland 	case COLOR_DEPTH_121212:
869b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
870b8fdfcc6SHarry Wentland 	break;
871b8fdfcc6SHarry Wentland 	default:
872b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
873b8fdfcc6SHarry Wentland 	break;
874b8fdfcc6SHarry Wentland 	}
875b8fdfcc6SHarry Wentland 
876b8fdfcc6SHarry Wentland 	switch (test_pattern) {
877b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
878b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
879b8fdfcc6SHarry Wentland 	{
880b8fdfcc6SHarry Wentland 		dyn_range = (test_pattern ==
881b8fdfcc6SHarry Wentland 				CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
882b8fdfcc6SHarry Wentland 				TEST_PATTERN_DYN_RANGE_CEA :
883b8fdfcc6SHarry Wentland 				TEST_PATTERN_DYN_RANGE_VESA);
884b8fdfcc6SHarry Wentland 		mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
885b8fdfcc6SHarry Wentland 
886b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_2(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
887b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_VRES, 6,
888b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_HRES, 6);
889b8fdfcc6SHarry Wentland 
890b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
891b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_EN, 1,
892b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_MODE, mode,
893b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
894b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
895b8fdfcc6SHarry Wentland 	}
896b8fdfcc6SHarry Wentland 	break;
897b8fdfcc6SHarry Wentland 
898b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
899b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
900b8fdfcc6SHarry Wentland 	{
901b8fdfcc6SHarry Wentland 		mode = (test_pattern ==
902b8fdfcc6SHarry Wentland 			CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
903b8fdfcc6SHarry Wentland 			TEST_PATTERN_MODE_VERTICALBARS :
904b8fdfcc6SHarry Wentland 			TEST_PATTERN_MODE_HORIZONTALBARS);
905b8fdfcc6SHarry Wentland 
906b8fdfcc6SHarry Wentland 		switch (bit_depth) {
907b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
908b8fdfcc6SHarry Wentland 			dst_bpc = 6;
909b8fdfcc6SHarry Wentland 		break;
910b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
911b8fdfcc6SHarry Wentland 			dst_bpc = 8;
912b8fdfcc6SHarry Wentland 		break;
913b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
914b8fdfcc6SHarry Wentland 			dst_bpc = 10;
915b8fdfcc6SHarry Wentland 		break;
916b8fdfcc6SHarry Wentland 		default:
917b8fdfcc6SHarry Wentland 			dst_bpc = 8;
918b8fdfcc6SHarry Wentland 		break;
919b8fdfcc6SHarry Wentland 		}
920b8fdfcc6SHarry Wentland 
921b8fdfcc6SHarry Wentland 		/* adjust color to the required colorFormat */
922b8fdfcc6SHarry Wentland 		for (index = 0; index < 6; index++) {
923b8fdfcc6SHarry Wentland 			/* dst = 2^dstBpc * src / 2^srcBpc = src >>
924b8fdfcc6SHarry Wentland 			 * (srcBpc - dstBpc);
925b8fdfcc6SHarry Wentland 			 */
926b8fdfcc6SHarry Wentland 			dst_color[index] =
927b8fdfcc6SHarry Wentland 				src_color[index] >> (src_bpc - dst_bpc);
928b8fdfcc6SHarry Wentland 		/* CRTC_TEST_PATTERN_DATA has 16 bits,
929b8fdfcc6SHarry Wentland 		 * lowest 6 are hardwired to ZERO
930b8fdfcc6SHarry Wentland 		 * color bits should be left aligned aligned to MSB
931b8fdfcc6SHarry Wentland 		 * XXXXXXXXXX000000 for 10 bit,
932b8fdfcc6SHarry Wentland 		 * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
933b8fdfcc6SHarry Wentland 		 */
934b8fdfcc6SHarry Wentland 			dst_color[index] <<= (16 - dst_bpc);
935b8fdfcc6SHarry Wentland 		}
936b8fdfcc6SHarry Wentland 
937b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, 0);
938b8fdfcc6SHarry Wentland 
939b8fdfcc6SHarry Wentland 		/* We have to write the mask before data, similar to pipeline.
940b8fdfcc6SHarry Wentland 		 * For example, for 8 bpc, if we want RGB0 to be magenta,
941b8fdfcc6SHarry Wentland 		 * and RGB1 to be cyan,
942b8fdfcc6SHarry Wentland 		 * we need to make 7 writes:
943b8fdfcc6SHarry Wentland 		 * MASK   DATA
944b8fdfcc6SHarry Wentland 		 * 000001 00000000 00000000                     set mask to R0
945b8fdfcc6SHarry Wentland 		 * 000010 11111111 00000000     R0 255, 0xFF00, set mask to G0
946b8fdfcc6SHarry Wentland 		 * 000100 00000000 00000000     G0 0,   0x0000, set mask to B0
947b8fdfcc6SHarry Wentland 		 * 001000 11111111 00000000     B0 255, 0xFF00, set mask to R1
948b8fdfcc6SHarry Wentland 		 * 010000 00000000 00000000     R1 0,   0x0000, set mask to G1
949b8fdfcc6SHarry Wentland 		 * 100000 11111111 00000000     G1 255, 0xFF00, set mask to B1
950b8fdfcc6SHarry Wentland 		 * 100000 11111111 00000000     B1 255, 0xFF00
951b8fdfcc6SHarry Wentland 		 *
952b8fdfcc6SHarry Wentland 		 * we will make a loop of 6 in which we prepare the mask,
953b8fdfcc6SHarry Wentland 		 * then write, then prepare the color for next write.
954b8fdfcc6SHarry Wentland 		 * first iteration will write mask only,
955b8fdfcc6SHarry Wentland 		 * but each next iteration color prepared in
956b8fdfcc6SHarry Wentland 		 * previous iteration will be written within new mask,
957b8fdfcc6SHarry Wentland 		 * the last component will written separately,
958b8fdfcc6SHarry Wentland 		 * mask is not changing between 6th and 7th write
959b8fdfcc6SHarry Wentland 		 * and color will be prepared by last iteration
960b8fdfcc6SHarry Wentland 		 */
961b8fdfcc6SHarry Wentland 
962b8fdfcc6SHarry Wentland 		/* write color, color values mask in CRTC_TEST_PATTERN_MASK
963b8fdfcc6SHarry Wentland 		 * is B1, G1, R1, B0, G0, R0
964b8fdfcc6SHarry Wentland 		 */
965b8fdfcc6SHarry Wentland 		value = 0;
966b8fdfcc6SHarry Wentland 		for (index = 0; index < 6; index++) {
967b8fdfcc6SHarry Wentland 			/* prepare color mask, first write PATTERN_DATA
968b8fdfcc6SHarry Wentland 			 * will have all zeros
969b8fdfcc6SHarry Wentland 			 */
970b8fdfcc6SHarry Wentland 			set_reg_field_value(
971b8fdfcc6SHarry Wentland 				value,
972b8fdfcc6SHarry Wentland 				(1 << index),
973b8fdfcc6SHarry Wentland 				CRTC0_CRTC_TEST_PATTERN_COLOR,
974b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_MASK);
975b8fdfcc6SHarry Wentland 			/* write color component */
976b8fdfcc6SHarry Wentland 			dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
977b8fdfcc6SHarry Wentland 			/* prepare next color component,
978b8fdfcc6SHarry Wentland 			 * will be written in the next iteration
979b8fdfcc6SHarry Wentland 			 */
980b8fdfcc6SHarry Wentland 			set_reg_field_value(
981b8fdfcc6SHarry Wentland 				value,
982b8fdfcc6SHarry Wentland 				dst_color[index],
983b8fdfcc6SHarry Wentland 				CRTC0_CRTC_TEST_PATTERN_COLOR,
984b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_DATA);
985b8fdfcc6SHarry Wentland 		}
986b8fdfcc6SHarry Wentland 		/* write last color component,
987b8fdfcc6SHarry Wentland 		 * it's been already prepared in the loop
988b8fdfcc6SHarry Wentland 		 */
989b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
990b8fdfcc6SHarry Wentland 
991b8fdfcc6SHarry Wentland 		/* enable test pattern */
992b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
993b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_EN, 1,
994b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_MODE, mode,
995b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0,
996b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
997b8fdfcc6SHarry Wentland 	}
998b8fdfcc6SHarry Wentland 	break;
999b8fdfcc6SHarry Wentland 
1000b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
1001b8fdfcc6SHarry Wentland 	{
1002b8fdfcc6SHarry Wentland 		mode = (bit_depth ==
1003b8fdfcc6SHarry Wentland 			TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
1004b8fdfcc6SHarry Wentland 			TEST_PATTERN_MODE_DUALRAMP_RGB :
1005b8fdfcc6SHarry Wentland 			TEST_PATTERN_MODE_SINGLERAMP_RGB);
1006b8fdfcc6SHarry Wentland 
1007b8fdfcc6SHarry Wentland 		switch (bit_depth) {
1008b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1009b8fdfcc6SHarry Wentland 			dst_bpc = 6;
1010b8fdfcc6SHarry Wentland 		break;
1011b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1012b8fdfcc6SHarry Wentland 			dst_bpc = 8;
1013b8fdfcc6SHarry Wentland 		break;
1014b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1015b8fdfcc6SHarry Wentland 			dst_bpc = 10;
1016b8fdfcc6SHarry Wentland 		break;
1017b8fdfcc6SHarry Wentland 		default:
1018b8fdfcc6SHarry Wentland 			dst_bpc = 8;
1019b8fdfcc6SHarry Wentland 		break;
1020b8fdfcc6SHarry Wentland 		}
1021b8fdfcc6SHarry Wentland 
1022b8fdfcc6SHarry Wentland 		/* increment for the first ramp for one color gradation
1023b8fdfcc6SHarry Wentland 		 * 1 gradation for 6-bit color is 2^10
1024b8fdfcc6SHarry Wentland 		 * gradations in 16-bit color
1025b8fdfcc6SHarry Wentland 		 */
1026b8fdfcc6SHarry Wentland 		inc_base = (src_bpc - dst_bpc);
1027b8fdfcc6SHarry Wentland 
1028b8fdfcc6SHarry Wentland 		switch (bit_depth) {
1029b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1030b8fdfcc6SHarry Wentland 		{
1031b8fdfcc6SHarry Wentland 			CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
1032b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC0, inc_base,
1033b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC1, 0,
1034b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_HRES, 6,
1035b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_VRES, 6,
1036b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_RAMP0_OFFSET, 0);
1037b8fdfcc6SHarry Wentland 		}
1038b8fdfcc6SHarry Wentland 		break;
1039b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1040b8fdfcc6SHarry Wentland 		{
1041b8fdfcc6SHarry Wentland 			CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
1042b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC0, inc_base,
1043b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC1, 0,
1044b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_HRES, 8,
1045b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_VRES, 6,
1046b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_RAMP0_OFFSET, 0);
1047b8fdfcc6SHarry Wentland 		}
1048b8fdfcc6SHarry Wentland 		break;
1049b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1050b8fdfcc6SHarry Wentland 		{
1051b8fdfcc6SHarry Wentland 			CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
1052b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC0, inc_base,
1053b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC1, inc_base + 2,
1054b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_HRES, 8,
1055b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_VRES, 5,
1056b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
1057b8fdfcc6SHarry Wentland 		}
1058b8fdfcc6SHarry Wentland 		break;
1059b8fdfcc6SHarry Wentland 		default:
1060b8fdfcc6SHarry Wentland 		break;
1061b8fdfcc6SHarry Wentland 		}
1062b8fdfcc6SHarry Wentland 
1063b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, 0);
1064b8fdfcc6SHarry Wentland 
1065b8fdfcc6SHarry Wentland 		/* enable test pattern */
1066b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc, 0);
1067b8fdfcc6SHarry Wentland 
1068b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
1069b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_EN, 1,
1070b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_MODE, mode,
1071b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0,
1072b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
1073b8fdfcc6SHarry Wentland 	}
1074b8fdfcc6SHarry Wentland 	break;
1075b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1076b8fdfcc6SHarry Wentland 	{
1077b8fdfcc6SHarry Wentland 		value = 0;
1078b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc,  value);
1079b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
1080b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, value);
1081b8fdfcc6SHarry Wentland 	}
1082b8fdfcc6SHarry Wentland 	break;
1083b8fdfcc6SHarry Wentland 	default:
1084b8fdfcc6SHarry Wentland 	break;
1085b8fdfcc6SHarry Wentland 	}
1086b8fdfcc6SHarry Wentland }
1087b8fdfcc6SHarry Wentland 
1088667e1498SAndrey Grodzovsky static bool dce120_arm_vert_intr(
1089667e1498SAndrey Grodzovsky 		struct timing_generator *tg,
1090667e1498SAndrey Grodzovsky 		uint8_t width)
1091667e1498SAndrey Grodzovsky {
1092667e1498SAndrey Grodzovsky 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
109381c50963SSylvia Tsai 	uint32_t v_blank_start, v_blank_end, h_position, v_position;
1094667e1498SAndrey Grodzovsky 
1095667e1498SAndrey Grodzovsky 	tg->funcs->get_scanoutpos(
1096667e1498SAndrey Grodzovsky 				tg,
109781c50963SSylvia Tsai 				&v_blank_start,
109881c50963SSylvia Tsai 				&v_blank_end,
109981c50963SSylvia Tsai 				&h_position,
110081c50963SSylvia Tsai 				&v_position);
1101667e1498SAndrey Grodzovsky 
110281c50963SSylvia Tsai 	if (v_blank_start == 0 || v_blank_end == 0)
1103667e1498SAndrey Grodzovsky 		return false;
1104667e1498SAndrey Grodzovsky 
1105667e1498SAndrey Grodzovsky 	CRTC_REG_SET_2(
1106667e1498SAndrey Grodzovsky 			CRTC0_CRTC_VERTICAL_INTERRUPT0_POSITION,
110781c50963SSylvia Tsai 			CRTC_VERTICAL_INTERRUPT0_LINE_START, v_blank_start,
110881c50963SSylvia Tsai 			CRTC_VERTICAL_INTERRUPT0_LINE_END, v_blank_start + width);
1109667e1498SAndrey Grodzovsky 
1110667e1498SAndrey Grodzovsky 	return true;
1111667e1498SAndrey Grodzovsky }
1112667e1498SAndrey Grodzovsky 
1113b8fdfcc6SHarry Wentland static struct timing_generator_funcs dce120_tg_funcs = {
1114b8fdfcc6SHarry Wentland 		.validate_timing = dce120_tg_validate_timing,
1115b8fdfcc6SHarry Wentland 		.program_timing = dce120_tg_program_timing,
1116b8fdfcc6SHarry Wentland 		.enable_crtc = dce120_timing_generator_enable_crtc,
1117b8fdfcc6SHarry Wentland 		.disable_crtc = dce110_timing_generator_disable_crtc,
1118b8fdfcc6SHarry Wentland 		/* used by enable_timing_synchronization. Not need for FPGA */
1119b8fdfcc6SHarry Wentland 		.is_counter_moving = dce110_timing_generator_is_counter_moving,
1120b8fdfcc6SHarry Wentland 		/* never be called */
112172ada5f7SEric Cook 		.get_position = dce120_timing_generator_get_crtc_position,
1122b8fdfcc6SHarry Wentland 		.get_frame_count = dce120_timing_generator_get_vblank_counter,
1123b8fdfcc6SHarry Wentland 		.get_scanoutpos = dce120_timing_generator_get_crtc_scanoutpos,
1124b8fdfcc6SHarry Wentland 		.set_early_control = dce120_timing_generator_set_early_control,
1125b8fdfcc6SHarry Wentland 		/* used by enable_timing_synchronization. Not need for FPGA */
1126b8fdfcc6SHarry Wentland 		.wait_for_state = dce120_tg_wait_for_state,
1127b8fdfcc6SHarry Wentland 		.set_blank = dce120_tg_set_blank,
1128b8fdfcc6SHarry Wentland 		.is_blanked = dce120_tg_is_blanked,
1129b8fdfcc6SHarry Wentland 		/* never be called */
1130b8fdfcc6SHarry Wentland 		.set_colors = dce120_tg_set_colors,
1131b8fdfcc6SHarry Wentland 		.set_overscan_blank_color = dce120_timing_generator_set_overscan_color_black,
1132b8fdfcc6SHarry Wentland 		.set_blank_color = dce120_timing_generator_program_blank_color,
1133b8fdfcc6SHarry Wentland 		.disable_vga = dce120_timing_generator_disable_vga,
1134b8fdfcc6SHarry Wentland 		.did_triggered_reset_occur = dce120_timing_generator_did_triggered_reset_occur,
1135b8fdfcc6SHarry Wentland 		.setup_global_swap_lock = dce120_timing_generator_setup_global_swap_lock,
1136b8fdfcc6SHarry Wentland 		.enable_reset_trigger = dce120_timing_generator_enable_reset_trigger,
1137b8fdfcc6SHarry Wentland 		.disable_reset_trigger = dce120_timing_generator_disable_reset_trigger,
1138b8fdfcc6SHarry Wentland 		.tear_down_global_swap_lock = dce120_timing_generator_tear_down_global_swap_lock,
1139b8fdfcc6SHarry Wentland 		.enable_advanced_request = dce120_timing_generator_enable_advanced_request,
1140b8fdfcc6SHarry Wentland 		.set_drr = dce120_timing_generator_set_drr,
1141b8fdfcc6SHarry Wentland 		.set_static_screen_control = dce120_timing_generator_set_static_screen_control,
1142667e1498SAndrey Grodzovsky 		.set_test_pattern = dce120_timing_generator_set_test_pattern,
1143667e1498SAndrey Grodzovsky 		.arm_vert_intr = dce120_arm_vert_intr,
1144b8fdfcc6SHarry Wentland };
1145b8fdfcc6SHarry Wentland 
1146b8fdfcc6SHarry Wentland 
1147b8fdfcc6SHarry Wentland bool dce120_timing_generator_construct(
1148b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110,
1149b8fdfcc6SHarry Wentland 	struct dc_context *ctx,
1150b8fdfcc6SHarry Wentland 	uint32_t instance,
1151b8fdfcc6SHarry Wentland 	const struct dce110_timing_generator_offsets *offsets)
1152b8fdfcc6SHarry Wentland {
1153b8fdfcc6SHarry Wentland 	if (!tg110)
1154b8fdfcc6SHarry Wentland 			return false;
1155b8fdfcc6SHarry Wentland 
1156b8fdfcc6SHarry Wentland 	tg110->controller_id = CONTROLLER_ID_D0 + instance;
1157b8fdfcc6SHarry Wentland 	tg110->base.inst = instance;
1158b8fdfcc6SHarry Wentland 
1159b8fdfcc6SHarry Wentland 	tg110->offsets = *offsets;
1160b8fdfcc6SHarry Wentland 
1161b8fdfcc6SHarry Wentland 	tg110->base.funcs = &dce120_tg_funcs;
1162b8fdfcc6SHarry Wentland 
1163b8fdfcc6SHarry Wentland 	tg110->base.ctx = ctx;
1164b8fdfcc6SHarry Wentland 	tg110->base.bp = ctx->dc_bios;
1165b8fdfcc6SHarry Wentland 
1166b8fdfcc6SHarry Wentland 	tg110->max_h_total = CRTC0_CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
1167b8fdfcc6SHarry Wentland 	tg110->max_v_total = CRTC0_CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
1168b8fdfcc6SHarry Wentland 
1169b8fdfcc6SHarry Wentland 	/*//CRTC requires a minimum HBLANK = 32 pixels and o
1170b8fdfcc6SHarry Wentland 	 * Minimum HSYNC = 8 pixels*/
1171b8fdfcc6SHarry Wentland 	tg110->min_h_blank = 32;
1172b8fdfcc6SHarry Wentland 	/*DCE12_CRTC_Block_ARch.doc*/
1173b8fdfcc6SHarry Wentland 	tg110->min_h_front_porch = 0;
1174b8fdfcc6SHarry Wentland 	tg110->min_h_back_porch = 0;
1175b8fdfcc6SHarry Wentland 
1176b8fdfcc6SHarry Wentland 	tg110->min_h_sync_width = 8;
1177b8fdfcc6SHarry Wentland 	tg110->min_v_sync_width = 1;
1178b8fdfcc6SHarry Wentland 	tg110->min_v_blank = 3;
1179b8fdfcc6SHarry Wentland 
1180b8fdfcc6SHarry Wentland 	return true;
1181b8fdfcc6SHarry Wentland }
1182