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 offset = 0;
390b8fdfcc6SHarry Wentland 	uint32_t value = 0;
391b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
392b8fdfcc6SHarry Wentland 
393b8fdfcc6SHarry Wentland 	switch (tg110->controller_id) {
394b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D0:
395b8fdfcc6SHarry Wentland 		offset = 0;
396b8fdfcc6SHarry Wentland 		break;
397b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D1:
398b8fdfcc6SHarry Wentland 		offset = mmD2VGA_CONTROL - mmD1VGA_CONTROL;
399b8fdfcc6SHarry Wentland 		break;
400b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D2:
401b8fdfcc6SHarry Wentland 		offset = mmD3VGA_CONTROL - mmD1VGA_CONTROL;
402b8fdfcc6SHarry Wentland 		break;
403b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D3:
404b8fdfcc6SHarry Wentland 		offset = mmD4VGA_CONTROL - mmD1VGA_CONTROL;
405b8fdfcc6SHarry Wentland 		break;
406b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D4:
407ccaf31ecSRoman Li 		offset = mmD5VGA_CONTROL - mmD1VGA_CONTROL;
408b8fdfcc6SHarry Wentland 		break;
409b8fdfcc6SHarry Wentland 	case CONTROLLER_ID_D5:
410b8fdfcc6SHarry Wentland 		offset = mmD6VGA_CONTROL - mmD1VGA_CONTROL;
411b8fdfcc6SHarry Wentland 		break;
412b8fdfcc6SHarry Wentland 	default:
413b8fdfcc6SHarry Wentland 		break;
414b8fdfcc6SHarry Wentland 	}
415b8fdfcc6SHarry Wentland 
416b8fdfcc6SHarry Wentland 	value = dm_read_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset);
417b8fdfcc6SHarry Wentland 
418b8fdfcc6SHarry Wentland 	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE);
419b8fdfcc6SHarry Wentland 	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT);
420b8fdfcc6SHarry Wentland 	set_reg_field_value(
421b8fdfcc6SHarry Wentland 			value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT);
422b8fdfcc6SHarry Wentland 	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN);
423b8fdfcc6SHarry Wentland 
424b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset, value);
425b8fdfcc6SHarry Wentland }
426b8fdfcc6SHarry Wentland /* TODO: Should we move it to transform */
427b8fdfcc6SHarry Wentland /* Fully program CRTC timing in timing generator */
428b8fdfcc6SHarry Wentland void dce120_timing_generator_program_blanking(
429b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
430b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing)
431b8fdfcc6SHarry Wentland {
432b8fdfcc6SHarry Wentland 	uint32_t tmp1 = 0;
433b8fdfcc6SHarry Wentland 	uint32_t tmp2 = 0;
434b8fdfcc6SHarry Wentland 	uint32_t vsync_offset = timing->v_border_bottom +
435b8fdfcc6SHarry Wentland 			timing->v_front_porch;
436b8fdfcc6SHarry Wentland 	uint32_t v_sync_start = timing->v_addressable + vsync_offset;
437b8fdfcc6SHarry Wentland 
438b8fdfcc6SHarry Wentland 	uint32_t hsync_offset = timing->h_border_right +
439b8fdfcc6SHarry Wentland 			timing->h_front_porch;
440b8fdfcc6SHarry Wentland 	uint32_t h_sync_start = timing->h_addressable + hsync_offset;
441b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
442b8fdfcc6SHarry Wentland 
443b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE(
444b8fdfcc6SHarry Wentland 		CRTC0_CRTC_H_TOTAL,
445b8fdfcc6SHarry Wentland 		CRTC_H_TOTAL,
446b8fdfcc6SHarry Wentland 		timing->h_total - 1);
447b8fdfcc6SHarry Wentland 
448b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE(
449b8fdfcc6SHarry Wentland 		CRTC0_CRTC_V_TOTAL,
450b8fdfcc6SHarry Wentland 		CRTC_V_TOTAL,
45197416d4cSYongqiang Sun 		timing->v_total - 1);
45297416d4cSYongqiang Sun 
45397416d4cSYongqiang Sun 	/* In case of V_TOTAL_CONTROL is on, make sure V_TOTAL_MAX and
45497416d4cSYongqiang Sun 	 * V_TOTAL_MIN are equal to V_TOTAL.
45597416d4cSYongqiang Sun 	 */
45697416d4cSYongqiang Sun 	CRTC_REG_UPDATE(
45797416d4cSYongqiang Sun 		CRTC0_CRTC_V_TOTAL_MAX,
45897416d4cSYongqiang Sun 		CRTC_V_TOTAL_MAX,
45997416d4cSYongqiang Sun 		timing->v_total - 1);
46097416d4cSYongqiang Sun 
46197416d4cSYongqiang Sun 	CRTC_REG_UPDATE(
46297416d4cSYongqiang Sun 		CRTC0_CRTC_V_TOTAL_MIN,
46397416d4cSYongqiang Sun 		CRTC_V_TOTAL_MIN,
464b8fdfcc6SHarry Wentland 		timing->v_total - 1);
465b8fdfcc6SHarry Wentland 
466b8fdfcc6SHarry Wentland 	tmp1 = timing->h_total -
467b8fdfcc6SHarry Wentland 			(h_sync_start + timing->h_border_left);
468b8fdfcc6SHarry Wentland 	tmp2 = tmp1 + timing->h_addressable +
469b8fdfcc6SHarry Wentland 			timing->h_border_left + timing->h_border_right;
470b8fdfcc6SHarry Wentland 
471b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_2(
472b8fdfcc6SHarry Wentland 			CRTC0_CRTC_H_BLANK_START_END,
473b8fdfcc6SHarry Wentland 			CRTC_H_BLANK_END, tmp1,
474b8fdfcc6SHarry Wentland 			CRTC_H_BLANK_START, tmp2);
475b8fdfcc6SHarry Wentland 
476b8fdfcc6SHarry Wentland 	tmp1 = timing->v_total - (v_sync_start + timing->v_border_top);
477b8fdfcc6SHarry Wentland 	tmp2 = tmp1 + timing->v_addressable + timing->v_border_top +
478b8fdfcc6SHarry Wentland 			timing->v_border_bottom;
479b8fdfcc6SHarry Wentland 
480b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_2(
481b8fdfcc6SHarry Wentland 		CRTC0_CRTC_V_BLANK_START_END,
482b8fdfcc6SHarry Wentland 		CRTC_V_BLANK_END, tmp1,
483b8fdfcc6SHarry Wentland 		CRTC_V_BLANK_START, tmp2);
484b8fdfcc6SHarry Wentland }
485b8fdfcc6SHarry Wentland 
486b8fdfcc6SHarry Wentland /* TODO: Should we move it to opp? */
487b8fdfcc6SHarry Wentland /* Combine with below and move YUV/RGB color conversion to SW layer */
488b8fdfcc6SHarry Wentland void dce120_timing_generator_program_blank_color(
489b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
490b8fdfcc6SHarry Wentland 	const struct tg_color *black_color)
491b8fdfcc6SHarry Wentland {
492b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
493b8fdfcc6SHarry Wentland 
494b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_3(
495b8fdfcc6SHarry Wentland 		CRTC0_CRTC_BLACK_COLOR,
496b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb,
497b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_G_Y, black_color->color_g_y,
498b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr);
499b8fdfcc6SHarry Wentland }
500b8fdfcc6SHarry Wentland /* Combine with above and move YUV/RGB color conversion to SW layer */
501b8fdfcc6SHarry Wentland void dce120_timing_generator_set_overscan_color_black(
502b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
503b8fdfcc6SHarry Wentland 	const struct tg_color *color)
504b8fdfcc6SHarry Wentland {
505b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
506b8fdfcc6SHarry Wentland 	uint32_t value = 0;
507b8fdfcc6SHarry Wentland 	CRTC_REG_SET_3(
508b8fdfcc6SHarry Wentland 		CRTC0_CRTC_OVERSCAN_COLOR,
509b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_BLUE, color->color_b_cb,
510b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_GREEN, color->color_g_y,
511b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_RED, color->color_r_cr);
512b8fdfcc6SHarry Wentland 
513b8fdfcc6SHarry Wentland 	value = dm_read_reg_soc15(
514b8fdfcc6SHarry Wentland 			tg->ctx,
515b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_OVERSCAN_COLOR,
516b8fdfcc6SHarry Wentland 			tg110->offsets.crtc);
517b8fdfcc6SHarry Wentland 
518b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(
519b8fdfcc6SHarry Wentland 			tg->ctx,
520b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_BLACK_COLOR,
521b8fdfcc6SHarry Wentland 			tg110->offsets.crtc,
522b8fdfcc6SHarry Wentland 			value);
523b8fdfcc6SHarry Wentland 
524b8fdfcc6SHarry Wentland 	/* This is desirable to have a constant DAC output voltage during the
525b8fdfcc6SHarry Wentland 	 * blank time that is higher than the 0 volt reference level that the
526b8fdfcc6SHarry Wentland 	 * DAC outputs when the NBLANK signal
527b8fdfcc6SHarry Wentland 	 * is asserted low, such as for output to an analog TV. */
528b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(
529b8fdfcc6SHarry Wentland 		tg->ctx,
530b8fdfcc6SHarry Wentland 		mmCRTC0_CRTC_BLANK_DATA_COLOR,
531b8fdfcc6SHarry Wentland 		tg110->offsets.crtc,
532b8fdfcc6SHarry Wentland 		value);
533b8fdfcc6SHarry Wentland 
534b8fdfcc6SHarry Wentland 	/* TO DO we have to program EXT registers and we need to know LB DATA
535b8fdfcc6SHarry Wentland 	 * format because it is used when more 10 , i.e. 12 bits per color
536b8fdfcc6SHarry Wentland 	 *
537b8fdfcc6SHarry Wentland 	 * m_mmDxCRTC_OVERSCAN_COLOR_EXT
538b8fdfcc6SHarry Wentland 	 * m_mmDxCRTC_BLACK_COLOR_EXT
539b8fdfcc6SHarry Wentland 	 * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
540b8fdfcc6SHarry Wentland 	 */
541b8fdfcc6SHarry Wentland }
542b8fdfcc6SHarry Wentland 
543b8fdfcc6SHarry Wentland void dce120_timing_generator_set_drr(
544b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
545b8fdfcc6SHarry Wentland 	const struct drr_params *params)
546b8fdfcc6SHarry Wentland {
547b8fdfcc6SHarry Wentland 
548b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
549b8fdfcc6SHarry Wentland 
550b8fdfcc6SHarry Wentland 	if (params != NULL &&
551b8fdfcc6SHarry Wentland 		params->vertical_total_max > 0 &&
552b8fdfcc6SHarry Wentland 		params->vertical_total_min > 0) {
553b8fdfcc6SHarry Wentland 
554b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
555b8fdfcc6SHarry Wentland 				CRTC0_CRTC_V_TOTAL_MIN,
5566c626ffbSYongqiang Sun 				CRTC_V_TOTAL_MIN, params->vertical_total_min - 1);
557b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
558b8fdfcc6SHarry Wentland 				CRTC0_CRTC_V_TOTAL_MAX,
5596c626ffbSYongqiang Sun 				CRTC_V_TOTAL_MAX, params->vertical_total_max - 1);
560b8fdfcc6SHarry Wentland 		CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 6,
561b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 1,
562b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 1,
563b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0,
564b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0,
565b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK_EN), 0,
566b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0);
567b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
568b8fdfcc6SHarry Wentland 				CRTC0_CRTC_STATIC_SCREEN_CONTROL,
569b8fdfcc6SHarry Wentland 				CRTC_STATIC_SCREEN_EVENT_MASK,
570b8fdfcc6SHarry Wentland 				0x180);
571b8fdfcc6SHarry Wentland 
572b8fdfcc6SHarry Wentland 	} else {
573b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
574b8fdfcc6SHarry Wentland 				CRTC0_CRTC_V_TOTAL_MIN,
575b8fdfcc6SHarry Wentland 				CRTC_V_TOTAL_MIN, 0);
576b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
577b8fdfcc6SHarry Wentland 				CRTC0_CRTC_V_TOTAL_MAX,
578b8fdfcc6SHarry Wentland 				CRTC_V_TOTAL_MAX, 0);
579b8fdfcc6SHarry Wentland 		CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 5,
580b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 0,
581b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 0,
582b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0,
583b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0,
584b8fdfcc6SHarry Wentland 				FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0);
585b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE(
586b8fdfcc6SHarry Wentland 				CRTC0_CRTC_STATIC_SCREEN_CONTROL,
587b8fdfcc6SHarry Wentland 				CRTC_STATIC_SCREEN_EVENT_MASK,
588b8fdfcc6SHarry Wentland 				0);
589b8fdfcc6SHarry Wentland 	}
590b8fdfcc6SHarry Wentland }
591b8fdfcc6SHarry Wentland 
59272ada5f7SEric Cook /**
59372ada5f7SEric Cook  *****************************************************************************
59472ada5f7SEric Cook  *  Function: dce120_timing_generator_get_position
59572ada5f7SEric Cook  *
59672ada5f7SEric Cook  *  @brief
59772ada5f7SEric Cook  *     Returns CRTC vertical/horizontal counters
59872ada5f7SEric Cook  *
59972ada5f7SEric Cook  *  @param [out] position
60072ada5f7SEric Cook  *****************************************************************************
60172ada5f7SEric Cook  */
60272ada5f7SEric Cook void dce120_timing_generator_get_position(struct timing_generator *tg,
60372ada5f7SEric Cook 	struct crtc_position *position)
60472ada5f7SEric Cook {
60572ada5f7SEric Cook 	uint32_t value;
60672ada5f7SEric Cook 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
60772ada5f7SEric Cook 
60872ada5f7SEric Cook 	value = dm_read_reg_soc15(
60972ada5f7SEric Cook 			tg->ctx,
61072ada5f7SEric Cook 			mmCRTC0_CRTC_STATUS_POSITION,
61172ada5f7SEric Cook 			tg110->offsets.crtc);
61272ada5f7SEric Cook 
61372ada5f7SEric Cook 	position->horizontal_count = get_reg_field_value(
61472ada5f7SEric Cook 			value,
61572ada5f7SEric Cook 			CRTC0_CRTC_STATUS_POSITION,
61672ada5f7SEric Cook 			CRTC_HORZ_COUNT);
61772ada5f7SEric Cook 
61872ada5f7SEric Cook 	position->vertical_count = get_reg_field_value(
61972ada5f7SEric Cook 			value,
62072ada5f7SEric Cook 			CRTC0_CRTC_STATUS_POSITION,
62172ada5f7SEric Cook 			CRTC_VERT_COUNT);
62272ada5f7SEric Cook 
62372ada5f7SEric Cook 	value = dm_read_reg_soc15(
62472ada5f7SEric Cook 			tg->ctx,
62572ada5f7SEric Cook 			mmCRTC0_CRTC_NOM_VERT_POSITION,
62672ada5f7SEric Cook 			tg110->offsets.crtc);
62772ada5f7SEric Cook 
62872ada5f7SEric Cook 	position->nominal_vcount = get_reg_field_value(
62972ada5f7SEric Cook 			value,
63072ada5f7SEric Cook 			CRTC0_CRTC_NOM_VERT_POSITION,
63172ada5f7SEric Cook 			CRTC_VERT_COUNT_NOM);
63272ada5f7SEric Cook }
63372ada5f7SEric Cook 
63472ada5f7SEric Cook 
63581c50963SSylvia Tsai void dce120_timing_generator_get_crtc_scanoutpos(
636b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
63781c50963SSylvia Tsai 	uint32_t *v_blank_start,
63881c50963SSylvia Tsai 	uint32_t *v_blank_end,
63981c50963SSylvia Tsai 	uint32_t *h_position,
64081c50963SSylvia Tsai 	uint32_t *v_position)
641b8fdfcc6SHarry Wentland {
642b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
64372ada5f7SEric Cook 	struct crtc_position position;
644b8fdfcc6SHarry Wentland 
64581c50963SSylvia Tsai 	uint32_t v_blank_start_end = dm_read_reg_soc15(
646b8fdfcc6SHarry Wentland 			tg->ctx,
647b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_V_BLANK_START_END,
648b8fdfcc6SHarry Wentland 			tg110->offsets.crtc);
649b8fdfcc6SHarry Wentland 
65081c50963SSylvia Tsai 	*v_blank_start = get_reg_field_value(v_blank_start_end,
65181c50963SSylvia Tsai 					     CRTC0_CRTC_V_BLANK_START_END,
65281c50963SSylvia Tsai 					     CRTC_V_BLANK_START);
65381c50963SSylvia Tsai 	*v_blank_end = get_reg_field_value(v_blank_start_end,
65481c50963SSylvia Tsai 					   CRTC0_CRTC_V_BLANK_START_END,
65581c50963SSylvia Tsai 					   CRTC_V_BLANK_END);
656b8fdfcc6SHarry Wentland 
65772ada5f7SEric Cook 	dce120_timing_generator_get_crtc_position(
65872ada5f7SEric Cook 			tg, &position);
65972ada5f7SEric Cook 
66072ada5f7SEric Cook 	*h_position = position.horizontal_count;
66172ada5f7SEric Cook 	*v_position = position.vertical_count;
662b8fdfcc6SHarry Wentland }
663b8fdfcc6SHarry Wentland 
664b8fdfcc6SHarry Wentland void dce120_timing_generator_enable_advanced_request(
665b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
666b8fdfcc6SHarry Wentland 	bool enable,
667b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing)
668b8fdfcc6SHarry Wentland {
669b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
670b8fdfcc6SHarry Wentland 	uint32_t v_sync_width_and_b_porch =
671b8fdfcc6SHarry Wentland 				timing->v_total - timing->v_addressable -
672b8fdfcc6SHarry Wentland 				timing->v_border_bottom - timing->v_front_porch;
673b8fdfcc6SHarry Wentland 	uint32_t value = dm_read_reg_soc15(
674b8fdfcc6SHarry Wentland 				tg->ctx,
675b8fdfcc6SHarry Wentland 				mmCRTC0_CRTC_START_LINE_CONTROL,
676b8fdfcc6SHarry Wentland 				tg110->offsets.crtc);
677b8fdfcc6SHarry Wentland 
678b8fdfcc6SHarry Wentland 	set_reg_field_value(
679b8fdfcc6SHarry Wentland 		value,
680a4b0a5b8STom St Denis 		enable ? 0 : 1,
681b8fdfcc6SHarry Wentland 		CRTC0_CRTC_START_LINE_CONTROL,
682b8fdfcc6SHarry Wentland 		CRTC_LEGACY_REQUESTOR_EN);
683b8fdfcc6SHarry Wentland 
684b8fdfcc6SHarry Wentland 	/* Program advanced line position acc.to the best case from fetching data perspective to hide MC latency
685b8fdfcc6SHarry Wentland 	 * and prefilling Line Buffer in V Blank (to 10 lines as LB can store max 10 lines)
686b8fdfcc6SHarry Wentland 	 */
687b8fdfcc6SHarry Wentland 	if (v_sync_width_and_b_porch > 10)
688a4b0a5b8STom St Denis 		v_sync_width_and_b_porch = 10;
689a4b0a5b8STom St Denis 
690b8fdfcc6SHarry Wentland 	set_reg_field_value(
691b8fdfcc6SHarry Wentland 		value,
692b8fdfcc6SHarry Wentland 		v_sync_width_and_b_porch,
693b8fdfcc6SHarry Wentland 		CRTC0_CRTC_START_LINE_CONTROL,
694b8fdfcc6SHarry Wentland 		CRTC_ADVANCED_START_LINE_POSITION);
695b8fdfcc6SHarry Wentland 
696b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(tg->ctx,
697b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_START_LINE_CONTROL,
698b8fdfcc6SHarry Wentland 			tg110->offsets.crtc,
699b8fdfcc6SHarry Wentland 			value);
700b8fdfcc6SHarry Wentland }
701b8fdfcc6SHarry Wentland 
702b8fdfcc6SHarry Wentland void dce120_tg_program_blank_color(struct timing_generator *tg,
703b8fdfcc6SHarry Wentland 	const struct tg_color *black_color)
704b8fdfcc6SHarry Wentland {
705b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
706b8fdfcc6SHarry Wentland 	uint32_t value = 0;
707b8fdfcc6SHarry Wentland 
708b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_3(
709b8fdfcc6SHarry Wentland 		CRTC0_CRTC_BLACK_COLOR,
710b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb,
711b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_G_Y, black_color->color_g_y,
712b8fdfcc6SHarry Wentland 		CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr);
713b8fdfcc6SHarry Wentland 
714b8fdfcc6SHarry Wentland 	value = dm_read_reg_soc15(
715b8fdfcc6SHarry Wentland 				tg->ctx,
716b8fdfcc6SHarry Wentland 				mmCRTC0_CRTC_BLACK_COLOR,
717b8fdfcc6SHarry Wentland 				tg110->offsets.crtc);
718b8fdfcc6SHarry Wentland 	dm_write_reg_soc15(
719b8fdfcc6SHarry Wentland 		tg->ctx,
720b8fdfcc6SHarry Wentland 		mmCRTC0_CRTC_BLANK_DATA_COLOR,
721b8fdfcc6SHarry Wentland 		tg110->offsets.crtc,
722b8fdfcc6SHarry Wentland 		value);
723b8fdfcc6SHarry Wentland }
724b8fdfcc6SHarry Wentland 
725b8fdfcc6SHarry Wentland void dce120_tg_set_overscan_color(struct timing_generator *tg,
726b8fdfcc6SHarry Wentland 	const struct tg_color *overscan_color)
727b8fdfcc6SHarry Wentland {
728b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
729b8fdfcc6SHarry Wentland 
730b8fdfcc6SHarry Wentland 	CRTC_REG_SET_3(
731b8fdfcc6SHarry Wentland 		CRTC0_CRTC_OVERSCAN_COLOR,
732b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_BLUE, overscan_color->color_b_cb,
733b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_GREEN, overscan_color->color_g_y,
734b8fdfcc6SHarry Wentland 		CRTC_OVERSCAN_COLOR_RED, overscan_color->color_r_cr);
735b8fdfcc6SHarry Wentland }
736b8fdfcc6SHarry Wentland 
737b8fdfcc6SHarry Wentland void dce120_tg_program_timing(struct timing_generator *tg,
738b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing,
739b8fdfcc6SHarry Wentland 	bool use_vbios)
740b8fdfcc6SHarry Wentland {
741b8fdfcc6SHarry Wentland 	if (use_vbios)
742b8fdfcc6SHarry Wentland 		dce110_timing_generator_program_timing_generator(tg, timing);
743b8fdfcc6SHarry Wentland 	else
744b8fdfcc6SHarry Wentland 		dce120_timing_generator_program_blanking(tg, timing);
745b8fdfcc6SHarry Wentland }
746b8fdfcc6SHarry Wentland 
747b8fdfcc6SHarry Wentland bool dce120_tg_is_blanked(struct timing_generator *tg)
748b8fdfcc6SHarry Wentland {
749b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
750b8fdfcc6SHarry Wentland 	uint32_t value = dm_read_reg_soc15(
751b8fdfcc6SHarry Wentland 			tg->ctx,
752b8fdfcc6SHarry Wentland 			mmCRTC0_CRTC_BLANK_CONTROL,
753b8fdfcc6SHarry Wentland 			tg110->offsets.crtc);
754b8fdfcc6SHarry Wentland 
7557b7d6865STom St Denis 	if (get_reg_field_value(
756b8fdfcc6SHarry Wentland 		value,
757b8fdfcc6SHarry Wentland 		CRTC0_CRTC_BLANK_CONTROL,
758b8fdfcc6SHarry Wentland 		CRTC_BLANK_DATA_EN) == 1 &&
759b8fdfcc6SHarry Wentland 	    get_reg_field_value(
760b8fdfcc6SHarry Wentland 		value,
761b8fdfcc6SHarry Wentland 		CRTC0_CRTC_BLANK_CONTROL,
762b8fdfcc6SHarry Wentland 		CRTC_CURRENT_BLANK_STATE) == 1)
763b8fdfcc6SHarry Wentland 			return true;
764b8fdfcc6SHarry Wentland 
765b8fdfcc6SHarry Wentland 	return false;
766b8fdfcc6SHarry Wentland }
767b8fdfcc6SHarry Wentland 
768b8fdfcc6SHarry Wentland void dce120_tg_set_blank(struct timing_generator *tg,
769b8fdfcc6SHarry Wentland 		bool enable_blanking)
770b8fdfcc6SHarry Wentland {
771b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
772b8fdfcc6SHarry Wentland 
773b8fdfcc6SHarry Wentland 	CRTC_REG_SET(
774b8fdfcc6SHarry Wentland 		CRTC0_CRTC_DOUBLE_BUFFER_CONTROL,
775b8fdfcc6SHarry Wentland 		CRTC_BLANK_DATA_DOUBLE_BUFFER_EN, 0);
776b8fdfcc6SHarry Wentland 
777cedaf307STom St Denis 	if (enable_blanking)
778cedaf307STom St Denis 		CRTC_REG_SET(CRTC0_CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1);
779cedaf307STom St Denis 	else
780cedaf307STom St Denis 		dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_BLANK_CONTROL,
781cedaf307STom St Denis 			tg110->offsets.crtc, 0);
782b8fdfcc6SHarry Wentland }
783b8fdfcc6SHarry Wentland 
784b8fdfcc6SHarry Wentland bool dce120_tg_validate_timing(struct timing_generator *tg,
785b8fdfcc6SHarry Wentland 	const struct dc_crtc_timing *timing);
786b8fdfcc6SHarry Wentland 
787b8fdfcc6SHarry Wentland void dce120_tg_wait_for_state(struct timing_generator *tg,
788b8fdfcc6SHarry Wentland 	enum crtc_state state)
789b8fdfcc6SHarry Wentland {
790b8fdfcc6SHarry Wentland 	switch (state) {
791b8fdfcc6SHarry Wentland 	case CRTC_STATE_VBLANK:
792b8fdfcc6SHarry Wentland 		dce120_timing_generator_wait_for_vblank(tg);
793b8fdfcc6SHarry Wentland 		break;
794b8fdfcc6SHarry Wentland 
795b8fdfcc6SHarry Wentland 	case CRTC_STATE_VACTIVE:
796b8fdfcc6SHarry Wentland 		dce120_timing_generator_wait_for_vactive(tg);
797b8fdfcc6SHarry Wentland 		break;
798b8fdfcc6SHarry Wentland 
799b8fdfcc6SHarry Wentland 	default:
800b8fdfcc6SHarry Wentland 		break;
801b8fdfcc6SHarry Wentland 	}
802b8fdfcc6SHarry Wentland }
803b8fdfcc6SHarry Wentland 
804b8fdfcc6SHarry Wentland void dce120_tg_set_colors(struct timing_generator *tg,
805b8fdfcc6SHarry Wentland 	const struct tg_color *blank_color,
806b8fdfcc6SHarry Wentland 	const struct tg_color *overscan_color)
807b8fdfcc6SHarry Wentland {
808b8fdfcc6SHarry Wentland 	if (blank_color != NULL)
809b8fdfcc6SHarry Wentland 		dce120_tg_program_blank_color(tg, blank_color);
810b8fdfcc6SHarry Wentland 
811b8fdfcc6SHarry Wentland 	if (overscan_color != NULL)
812b8fdfcc6SHarry Wentland 		dce120_tg_set_overscan_color(tg, overscan_color);
813b8fdfcc6SHarry Wentland }
814b8fdfcc6SHarry Wentland 
815b8fdfcc6SHarry Wentland static void dce120_timing_generator_set_static_screen_control(
816b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
817b8fdfcc6SHarry Wentland 	uint32_t value)
818b8fdfcc6SHarry Wentland {
819b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
820b8fdfcc6SHarry Wentland 
821b8fdfcc6SHarry Wentland 	CRTC_REG_UPDATE_2(CRTC0_CRTC_STATIC_SCREEN_CONTROL,
822b8fdfcc6SHarry Wentland 			CRTC_STATIC_SCREEN_EVENT_MASK, value,
823b8fdfcc6SHarry Wentland 			CRTC_STATIC_SCREEN_FRAME_COUNT, 2);
824b8fdfcc6SHarry Wentland }
825b8fdfcc6SHarry Wentland 
826b8fdfcc6SHarry Wentland void dce120_timing_generator_set_test_pattern(
827b8fdfcc6SHarry Wentland 	struct timing_generator *tg,
828b8fdfcc6SHarry Wentland 	/* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
829b8fdfcc6SHarry Wentland 	 * because this is not DP-specific (which is probably somewhere in DP
830b8fdfcc6SHarry Wentland 	 * encoder) */
831b8fdfcc6SHarry Wentland 	enum controller_dp_test_pattern test_pattern,
832b8fdfcc6SHarry Wentland 	enum dc_color_depth color_depth)
833b8fdfcc6SHarry Wentland {
834b8fdfcc6SHarry Wentland 	struct dc_context *ctx = tg->ctx;
835b8fdfcc6SHarry Wentland 	uint32_t value;
836b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
837b8fdfcc6SHarry Wentland 	enum test_pattern_color_format bit_depth;
838b8fdfcc6SHarry Wentland 	enum test_pattern_dyn_range dyn_range;
839b8fdfcc6SHarry Wentland 	enum test_pattern_mode mode;
840b8fdfcc6SHarry Wentland 	/* color ramp generator mixes 16-bits color */
841b8fdfcc6SHarry Wentland 	uint32_t src_bpc = 16;
842b8fdfcc6SHarry Wentland 	/* requested bpc */
843b8fdfcc6SHarry Wentland 	uint32_t dst_bpc;
844b8fdfcc6SHarry Wentland 	uint32_t index;
845b8fdfcc6SHarry Wentland 	/* RGB values of the color bars.
846b8fdfcc6SHarry Wentland 	 * Produce two RGB colors: RGB0 - white (all Fs)
847b8fdfcc6SHarry Wentland 	 * and RGB1 - black (all 0s)
848b8fdfcc6SHarry Wentland 	 * (three RGB components for two colors)
849b8fdfcc6SHarry Wentland 	 */
850b8fdfcc6SHarry Wentland 	uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
851b8fdfcc6SHarry Wentland 						0x0000, 0x0000};
852b8fdfcc6SHarry Wentland 	/* dest color (converted to the specified color format) */
853b8fdfcc6SHarry Wentland 	uint16_t dst_color[6];
854b8fdfcc6SHarry Wentland 	uint32_t inc_base;
855b8fdfcc6SHarry Wentland 
856b8fdfcc6SHarry Wentland 	/* translate to bit depth */
857b8fdfcc6SHarry Wentland 	switch (color_depth) {
858b8fdfcc6SHarry Wentland 	case COLOR_DEPTH_666:
859b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
860b8fdfcc6SHarry Wentland 	break;
861b8fdfcc6SHarry Wentland 	case COLOR_DEPTH_888:
862b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
863b8fdfcc6SHarry Wentland 	break;
864b8fdfcc6SHarry Wentland 	case COLOR_DEPTH_101010:
865b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
866b8fdfcc6SHarry Wentland 	break;
867b8fdfcc6SHarry Wentland 	case COLOR_DEPTH_121212:
868b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
869b8fdfcc6SHarry Wentland 	break;
870b8fdfcc6SHarry Wentland 	default:
871b8fdfcc6SHarry Wentland 		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
872b8fdfcc6SHarry Wentland 	break;
873b8fdfcc6SHarry Wentland 	}
874b8fdfcc6SHarry Wentland 
875b8fdfcc6SHarry Wentland 	switch (test_pattern) {
876b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
877b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
878b8fdfcc6SHarry Wentland 	{
879b8fdfcc6SHarry Wentland 		dyn_range = (test_pattern ==
880b8fdfcc6SHarry Wentland 				CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
881b8fdfcc6SHarry Wentland 				TEST_PATTERN_DYN_RANGE_CEA :
882b8fdfcc6SHarry Wentland 				TEST_PATTERN_DYN_RANGE_VESA);
883b8fdfcc6SHarry Wentland 		mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
884b8fdfcc6SHarry Wentland 
885b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_2(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
886b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_VRES, 6,
887b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_HRES, 6);
888b8fdfcc6SHarry Wentland 
889b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
890b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_EN, 1,
891b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_MODE, mode,
892b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_DYNAMIC_RANGE, dyn_range,
893b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
894b8fdfcc6SHarry Wentland 	}
895b8fdfcc6SHarry Wentland 	break;
896b8fdfcc6SHarry Wentland 
897b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
898b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
899b8fdfcc6SHarry Wentland 	{
900b8fdfcc6SHarry Wentland 		mode = (test_pattern ==
901b8fdfcc6SHarry Wentland 			CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
902b8fdfcc6SHarry Wentland 			TEST_PATTERN_MODE_VERTICALBARS :
903b8fdfcc6SHarry Wentland 			TEST_PATTERN_MODE_HORIZONTALBARS);
904b8fdfcc6SHarry Wentland 
905b8fdfcc6SHarry Wentland 		switch (bit_depth) {
906b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
907b8fdfcc6SHarry Wentland 			dst_bpc = 6;
908b8fdfcc6SHarry Wentland 		break;
909b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
910b8fdfcc6SHarry Wentland 			dst_bpc = 8;
911b8fdfcc6SHarry Wentland 		break;
912b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
913b8fdfcc6SHarry Wentland 			dst_bpc = 10;
914b8fdfcc6SHarry Wentland 		break;
915b8fdfcc6SHarry Wentland 		default:
916b8fdfcc6SHarry Wentland 			dst_bpc = 8;
917b8fdfcc6SHarry Wentland 		break;
918b8fdfcc6SHarry Wentland 		}
919b8fdfcc6SHarry Wentland 
920b8fdfcc6SHarry Wentland 		/* adjust color to the required colorFormat */
921b8fdfcc6SHarry Wentland 		for (index = 0; index < 6; index++) {
922b8fdfcc6SHarry Wentland 			/* dst = 2^dstBpc * src / 2^srcBpc = src >>
923b8fdfcc6SHarry Wentland 			 * (srcBpc - dstBpc);
924b8fdfcc6SHarry Wentland 			 */
925b8fdfcc6SHarry Wentland 			dst_color[index] =
926b8fdfcc6SHarry Wentland 				src_color[index] >> (src_bpc - dst_bpc);
927b8fdfcc6SHarry Wentland 		/* CRTC_TEST_PATTERN_DATA has 16 bits,
928b8fdfcc6SHarry Wentland 		 * lowest 6 are hardwired to ZERO
929b8fdfcc6SHarry Wentland 		 * color bits should be left aligned aligned to MSB
930b8fdfcc6SHarry Wentland 		 * XXXXXXXXXX000000 for 10 bit,
931b8fdfcc6SHarry Wentland 		 * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
932b8fdfcc6SHarry Wentland 		 */
933b8fdfcc6SHarry Wentland 			dst_color[index] <<= (16 - dst_bpc);
934b8fdfcc6SHarry Wentland 		}
935b8fdfcc6SHarry Wentland 
936b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, 0);
937b8fdfcc6SHarry Wentland 
938b8fdfcc6SHarry Wentland 		/* We have to write the mask before data, similar to pipeline.
939b8fdfcc6SHarry Wentland 		 * For example, for 8 bpc, if we want RGB0 to be magenta,
940b8fdfcc6SHarry Wentland 		 * and RGB1 to be cyan,
941b8fdfcc6SHarry Wentland 		 * we need to make 7 writes:
942b8fdfcc6SHarry Wentland 		 * MASK   DATA
943b8fdfcc6SHarry Wentland 		 * 000001 00000000 00000000                     set mask to R0
944b8fdfcc6SHarry Wentland 		 * 000010 11111111 00000000     R0 255, 0xFF00, set mask to G0
945b8fdfcc6SHarry Wentland 		 * 000100 00000000 00000000     G0 0,   0x0000, set mask to B0
946b8fdfcc6SHarry Wentland 		 * 001000 11111111 00000000     B0 255, 0xFF00, set mask to R1
947b8fdfcc6SHarry Wentland 		 * 010000 00000000 00000000     R1 0,   0x0000, set mask to G1
948b8fdfcc6SHarry Wentland 		 * 100000 11111111 00000000     G1 255, 0xFF00, set mask to B1
949b8fdfcc6SHarry Wentland 		 * 100000 11111111 00000000     B1 255, 0xFF00
950b8fdfcc6SHarry Wentland 		 *
951b8fdfcc6SHarry Wentland 		 * we will make a loop of 6 in which we prepare the mask,
952b8fdfcc6SHarry Wentland 		 * then write, then prepare the color for next write.
953b8fdfcc6SHarry Wentland 		 * first iteration will write mask only,
954b8fdfcc6SHarry Wentland 		 * but each next iteration color prepared in
955b8fdfcc6SHarry Wentland 		 * previous iteration will be written within new mask,
956b8fdfcc6SHarry Wentland 		 * the last component will written separately,
957b8fdfcc6SHarry Wentland 		 * mask is not changing between 6th and 7th write
958b8fdfcc6SHarry Wentland 		 * and color will be prepared by last iteration
959b8fdfcc6SHarry Wentland 		 */
960b8fdfcc6SHarry Wentland 
961b8fdfcc6SHarry Wentland 		/* write color, color values mask in CRTC_TEST_PATTERN_MASK
962b8fdfcc6SHarry Wentland 		 * is B1, G1, R1, B0, G0, R0
963b8fdfcc6SHarry Wentland 		 */
964b8fdfcc6SHarry Wentland 		value = 0;
965b8fdfcc6SHarry Wentland 		for (index = 0; index < 6; index++) {
966b8fdfcc6SHarry Wentland 			/* prepare color mask, first write PATTERN_DATA
967b8fdfcc6SHarry Wentland 			 * will have all zeros
968b8fdfcc6SHarry Wentland 			 */
969b8fdfcc6SHarry Wentland 			set_reg_field_value(
970b8fdfcc6SHarry Wentland 				value,
971b8fdfcc6SHarry Wentland 				(1 << index),
972b8fdfcc6SHarry Wentland 				CRTC0_CRTC_TEST_PATTERN_COLOR,
973b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_MASK);
974b8fdfcc6SHarry Wentland 			/* write color component */
975b8fdfcc6SHarry Wentland 			dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
976b8fdfcc6SHarry Wentland 			/* prepare next color component,
977b8fdfcc6SHarry Wentland 			 * will be written in the next iteration
978b8fdfcc6SHarry Wentland 			 */
979b8fdfcc6SHarry Wentland 			set_reg_field_value(
980b8fdfcc6SHarry Wentland 				value,
981b8fdfcc6SHarry Wentland 				dst_color[index],
982b8fdfcc6SHarry Wentland 				CRTC0_CRTC_TEST_PATTERN_COLOR,
983b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_DATA);
984b8fdfcc6SHarry Wentland 		}
985b8fdfcc6SHarry Wentland 		/* write last color component,
986b8fdfcc6SHarry Wentland 		 * it's been already prepared in the loop
987b8fdfcc6SHarry Wentland 		 */
988b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
989b8fdfcc6SHarry Wentland 
990b8fdfcc6SHarry Wentland 		/* enable test pattern */
991b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
992b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_EN, 1,
993b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_MODE, mode,
994b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0,
995b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
996b8fdfcc6SHarry Wentland 	}
997b8fdfcc6SHarry Wentland 	break;
998b8fdfcc6SHarry Wentland 
999b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
1000b8fdfcc6SHarry Wentland 	{
1001b8fdfcc6SHarry Wentland 		mode = (bit_depth ==
1002b8fdfcc6SHarry Wentland 			TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
1003b8fdfcc6SHarry Wentland 			TEST_PATTERN_MODE_DUALRAMP_RGB :
1004b8fdfcc6SHarry Wentland 			TEST_PATTERN_MODE_SINGLERAMP_RGB);
1005b8fdfcc6SHarry Wentland 
1006b8fdfcc6SHarry Wentland 		switch (bit_depth) {
1007b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1008b8fdfcc6SHarry Wentland 			dst_bpc = 6;
1009b8fdfcc6SHarry Wentland 		break;
1010b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1011b8fdfcc6SHarry Wentland 			dst_bpc = 8;
1012b8fdfcc6SHarry Wentland 		break;
1013b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1014b8fdfcc6SHarry Wentland 			dst_bpc = 10;
1015b8fdfcc6SHarry Wentland 		break;
1016b8fdfcc6SHarry Wentland 		default:
1017b8fdfcc6SHarry Wentland 			dst_bpc = 8;
1018b8fdfcc6SHarry Wentland 		break;
1019b8fdfcc6SHarry Wentland 		}
1020b8fdfcc6SHarry Wentland 
1021b8fdfcc6SHarry Wentland 		/* increment for the first ramp for one color gradation
1022b8fdfcc6SHarry Wentland 		 * 1 gradation for 6-bit color is 2^10
1023b8fdfcc6SHarry Wentland 		 * gradations in 16-bit color
1024b8fdfcc6SHarry Wentland 		 */
1025b8fdfcc6SHarry Wentland 		inc_base = (src_bpc - dst_bpc);
1026b8fdfcc6SHarry Wentland 
1027b8fdfcc6SHarry Wentland 		switch (bit_depth) {
1028b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
1029b8fdfcc6SHarry Wentland 		{
1030b8fdfcc6SHarry Wentland 			CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
1031b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC0, inc_base,
1032b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC1, 0,
1033b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_HRES, 6,
1034b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_VRES, 6,
1035b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_RAMP0_OFFSET, 0);
1036b8fdfcc6SHarry Wentland 		}
1037b8fdfcc6SHarry Wentland 		break;
1038b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
1039b8fdfcc6SHarry Wentland 		{
1040b8fdfcc6SHarry Wentland 			CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
1041b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC0, inc_base,
1042b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC1, 0,
1043b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_HRES, 8,
1044b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_VRES, 6,
1045b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_RAMP0_OFFSET, 0);
1046b8fdfcc6SHarry Wentland 		}
1047b8fdfcc6SHarry Wentland 		break;
1048b8fdfcc6SHarry Wentland 		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1049b8fdfcc6SHarry Wentland 		{
1050b8fdfcc6SHarry Wentland 			CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS,
1051b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC0, inc_base,
1052b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_INC1, inc_base + 2,
1053b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_HRES, 8,
1054b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_VRES, 5,
1055b8fdfcc6SHarry Wentland 					CRTC_TEST_PATTERN_RAMP0_OFFSET, 384 << 6);
1056b8fdfcc6SHarry Wentland 		}
1057b8fdfcc6SHarry Wentland 		break;
1058b8fdfcc6SHarry Wentland 		default:
1059b8fdfcc6SHarry Wentland 		break;
1060b8fdfcc6SHarry Wentland 		}
1061b8fdfcc6SHarry Wentland 
1062b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, 0);
1063b8fdfcc6SHarry Wentland 
1064b8fdfcc6SHarry Wentland 		/* enable test pattern */
1065b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc, 0);
1066b8fdfcc6SHarry Wentland 
1067b8fdfcc6SHarry Wentland 		CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL,
1068b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_EN, 1,
1069b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_MODE, mode,
1070b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0,
1071b8fdfcc6SHarry Wentland 				CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth);
1072b8fdfcc6SHarry Wentland 	}
1073b8fdfcc6SHarry Wentland 	break;
1074b8fdfcc6SHarry Wentland 	case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1075b8fdfcc6SHarry Wentland 	{
1076b8fdfcc6SHarry Wentland 		value = 0;
1077b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc,  value);
1078b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value);
1079b8fdfcc6SHarry Wentland 		dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, value);
1080b8fdfcc6SHarry Wentland 	}
1081b8fdfcc6SHarry Wentland 	break;
1082b8fdfcc6SHarry Wentland 	default:
1083b8fdfcc6SHarry Wentland 	break;
1084b8fdfcc6SHarry Wentland 	}
1085b8fdfcc6SHarry Wentland }
1086b8fdfcc6SHarry Wentland 
1087667e1498SAndrey Grodzovsky static bool dce120_arm_vert_intr(
1088667e1498SAndrey Grodzovsky 		struct timing_generator *tg,
1089667e1498SAndrey Grodzovsky 		uint8_t width)
1090667e1498SAndrey Grodzovsky {
1091667e1498SAndrey Grodzovsky 	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
109281c50963SSylvia Tsai 	uint32_t v_blank_start, v_blank_end, h_position, v_position;
1093667e1498SAndrey Grodzovsky 
1094667e1498SAndrey Grodzovsky 	tg->funcs->get_scanoutpos(
1095667e1498SAndrey Grodzovsky 				tg,
109681c50963SSylvia Tsai 				&v_blank_start,
109781c50963SSylvia Tsai 				&v_blank_end,
109881c50963SSylvia Tsai 				&h_position,
109981c50963SSylvia Tsai 				&v_position);
1100667e1498SAndrey Grodzovsky 
110181c50963SSylvia Tsai 	if (v_blank_start == 0 || v_blank_end == 0)
1102667e1498SAndrey Grodzovsky 		return false;
1103667e1498SAndrey Grodzovsky 
1104667e1498SAndrey Grodzovsky 	CRTC_REG_SET_2(
1105667e1498SAndrey Grodzovsky 			CRTC0_CRTC_VERTICAL_INTERRUPT0_POSITION,
110681c50963SSylvia Tsai 			CRTC_VERTICAL_INTERRUPT0_LINE_START, v_blank_start,
110781c50963SSylvia Tsai 			CRTC_VERTICAL_INTERRUPT0_LINE_END, v_blank_start + width);
1108667e1498SAndrey Grodzovsky 
1109667e1498SAndrey Grodzovsky 	return true;
1110667e1498SAndrey Grodzovsky }
1111667e1498SAndrey Grodzovsky 
1112*395f669eSDave Airlie static const struct timing_generator_funcs dce120_tg_funcs = {
1113b8fdfcc6SHarry Wentland 		.validate_timing = dce120_tg_validate_timing,
1114b8fdfcc6SHarry Wentland 		.program_timing = dce120_tg_program_timing,
1115b8fdfcc6SHarry Wentland 		.enable_crtc = dce120_timing_generator_enable_crtc,
1116b8fdfcc6SHarry Wentland 		.disable_crtc = dce110_timing_generator_disable_crtc,
1117b8fdfcc6SHarry Wentland 		/* used by enable_timing_synchronization. Not need for FPGA */
1118b8fdfcc6SHarry Wentland 		.is_counter_moving = dce110_timing_generator_is_counter_moving,
1119b8fdfcc6SHarry Wentland 		/* never be called */
112072ada5f7SEric Cook 		.get_position = dce120_timing_generator_get_crtc_position,
1121b8fdfcc6SHarry Wentland 		.get_frame_count = dce120_timing_generator_get_vblank_counter,
1122b8fdfcc6SHarry Wentland 		.get_scanoutpos = dce120_timing_generator_get_crtc_scanoutpos,
1123b8fdfcc6SHarry Wentland 		.set_early_control = dce120_timing_generator_set_early_control,
1124b8fdfcc6SHarry Wentland 		/* used by enable_timing_synchronization. Not need for FPGA */
1125b8fdfcc6SHarry Wentland 		.wait_for_state = dce120_tg_wait_for_state,
1126b8fdfcc6SHarry Wentland 		.set_blank = dce120_tg_set_blank,
1127b8fdfcc6SHarry Wentland 		.is_blanked = dce120_tg_is_blanked,
1128b8fdfcc6SHarry Wentland 		/* never be called */
1129b8fdfcc6SHarry Wentland 		.set_colors = dce120_tg_set_colors,
1130b8fdfcc6SHarry Wentland 		.set_overscan_blank_color = dce120_timing_generator_set_overscan_color_black,
1131b8fdfcc6SHarry Wentland 		.set_blank_color = dce120_timing_generator_program_blank_color,
1132b8fdfcc6SHarry Wentland 		.disable_vga = dce120_timing_generator_disable_vga,
1133b8fdfcc6SHarry Wentland 		.did_triggered_reset_occur = dce120_timing_generator_did_triggered_reset_occur,
1134b8fdfcc6SHarry Wentland 		.setup_global_swap_lock = dce120_timing_generator_setup_global_swap_lock,
1135b8fdfcc6SHarry Wentland 		.enable_reset_trigger = dce120_timing_generator_enable_reset_trigger,
1136b8fdfcc6SHarry Wentland 		.disable_reset_trigger = dce120_timing_generator_disable_reset_trigger,
1137b8fdfcc6SHarry Wentland 		.tear_down_global_swap_lock = dce120_timing_generator_tear_down_global_swap_lock,
1138b8fdfcc6SHarry Wentland 		.enable_advanced_request = dce120_timing_generator_enable_advanced_request,
1139b8fdfcc6SHarry Wentland 		.set_drr = dce120_timing_generator_set_drr,
1140b8fdfcc6SHarry Wentland 		.set_static_screen_control = dce120_timing_generator_set_static_screen_control,
1141667e1498SAndrey Grodzovsky 		.set_test_pattern = dce120_timing_generator_set_test_pattern,
1142667e1498SAndrey Grodzovsky 		.arm_vert_intr = dce120_arm_vert_intr,
1143b8fdfcc6SHarry Wentland };
1144b8fdfcc6SHarry Wentland 
1145b8fdfcc6SHarry Wentland 
1146b8fdfcc6SHarry Wentland bool dce120_timing_generator_construct(
1147b8fdfcc6SHarry Wentland 	struct dce110_timing_generator *tg110,
1148b8fdfcc6SHarry Wentland 	struct dc_context *ctx,
1149b8fdfcc6SHarry Wentland 	uint32_t instance,
1150b8fdfcc6SHarry Wentland 	const struct dce110_timing_generator_offsets *offsets)
1151b8fdfcc6SHarry Wentland {
1152b8fdfcc6SHarry Wentland 	if (!tg110)
1153b8fdfcc6SHarry Wentland 			return false;
1154b8fdfcc6SHarry Wentland 
1155b8fdfcc6SHarry Wentland 	tg110->controller_id = CONTROLLER_ID_D0 + instance;
1156b8fdfcc6SHarry Wentland 	tg110->base.inst = instance;
1157b8fdfcc6SHarry Wentland 
1158b8fdfcc6SHarry Wentland 	tg110->offsets = *offsets;
1159b8fdfcc6SHarry Wentland 
1160b8fdfcc6SHarry Wentland 	tg110->base.funcs = &dce120_tg_funcs;
1161b8fdfcc6SHarry Wentland 
1162b8fdfcc6SHarry Wentland 	tg110->base.ctx = ctx;
1163b8fdfcc6SHarry Wentland 	tg110->base.bp = ctx->dc_bios;
1164b8fdfcc6SHarry Wentland 
1165b8fdfcc6SHarry Wentland 	tg110->max_h_total = CRTC0_CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
1166b8fdfcc6SHarry Wentland 	tg110->max_v_total = CRTC0_CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
1167b8fdfcc6SHarry Wentland 
1168b8fdfcc6SHarry Wentland 	/*//CRTC requires a minimum HBLANK = 32 pixels and o
1169b8fdfcc6SHarry Wentland 	 * Minimum HSYNC = 8 pixels*/
1170b8fdfcc6SHarry Wentland 	tg110->min_h_blank = 32;
1171b8fdfcc6SHarry Wentland 	/*DCE12_CRTC_Block_ARch.doc*/
1172b8fdfcc6SHarry Wentland 	tg110->min_h_front_porch = 0;
1173b8fdfcc6SHarry Wentland 	tg110->min_h_back_porch = 0;
1174b8fdfcc6SHarry Wentland 
1175b8fdfcc6SHarry Wentland 	tg110->min_h_sync_width = 8;
1176b8fdfcc6SHarry Wentland 	tg110->min_v_sync_width = 1;
1177b8fdfcc6SHarry Wentland 	tg110->min_v_blank = 3;
1178b8fdfcc6SHarry Wentland 
1179b8fdfcc6SHarry Wentland 	return true;
1180b8fdfcc6SHarry Wentland }
1181