1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#include "dm_services.h"
27
28/* include DCE11 register header files */
29#include "dce/dce_11_0_d.h"
30#include "dce/dce_11_0_sh_mask.h"
31
32#include "dc_types.h"
33#include "dc_bios_types.h"
34#include "dc.h"
35
36#include "include/grph_object_id.h"
37#include "include/logger_interface.h"
38#include "dce110_timing_generator.h"
39
40#include "timing_generator.h"
41
42
43#define NUMBER_OF_FRAME_TO_WAIT_ON_TRIGGERED_RESET 10
44
45#define MAX_H_TOTAL (CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1)
46#define MAX_V_TOTAL (CRTC_V_TOTAL__CRTC_V_TOTAL_MASKhw + 1)
47
48#define CRTC_REG(reg) (reg + tg110->offsets.crtc)
49#define DCP_REG(reg) (reg + tg110->offsets.dcp)
50
51/* Flowing register offsets are same in files of
52 * dce/dce_11_0_d.h
53 * dce/vi_polaris10_p/vi_polaris10_d.h
54 *
55 * So we can create dce110 timing generator to use it.
56 */
57
58
59/*
60* apply_front_porch_workaround
61*
62* This is a workaround for a bug that has existed since R5xx and has not been
63* fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
64*/
65static void dce110_timing_generator_apply_front_porch_workaround(
66	struct timing_generator *tg,
67	struct dc_crtc_timing *timing)
68{
69	if (timing->flags.INTERLACE == 1) {
70		if (timing->v_front_porch < 2)
71			timing->v_front_porch = 2;
72	} else {
73		if (timing->v_front_porch < 1)
74			timing->v_front_porch = 1;
75	}
76}
77
78/*
79 *****************************************************************************
80 *  Function: is_in_vertical_blank
81 *
82 *  @brief
83 *     check the current status of CRTC to check if we are in Vertical Blank
84 *     regioneased" state
85 *
86 *  @return
87 *     true if currently in blank region, false otherwise
88 *
89 *****************************************************************************
90 */
91static bool dce110_timing_generator_is_in_vertical_blank(
92		struct timing_generator *tg)
93{
94	uint32_t addr = 0;
95	uint32_t value = 0;
96	uint32_t field = 0;
97	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
98
99	addr = CRTC_REG(mmCRTC_STATUS);
100	value = dm_read_reg(tg->ctx, addr);
101	field = get_reg_field_value(value, CRTC_STATUS, CRTC_V_BLANK);
102	return field == 1;
103}
104
105void dce110_timing_generator_set_early_control(
106		struct timing_generator *tg,
107		uint32_t early_cntl)
108{
109	uint32_t regval;
110	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
111	uint32_t address = CRTC_REG(mmCRTC_CONTROL);
112
113	regval = dm_read_reg(tg->ctx, address);
114	set_reg_field_value(regval, early_cntl,
115			CRTC_CONTROL, CRTC_HBLANK_EARLY_CONTROL);
116	dm_write_reg(tg->ctx, address, regval);
117}
118
119/*
120 * Enable CRTC
121 * Enable CRTC - call ASIC Control Object to enable Timing generator.
122 */
123bool dce110_timing_generator_enable_crtc(struct timing_generator *tg)
124{
125	enum bp_result result;
126
127	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
128	uint32_t value = 0;
129
130	/*
131	 * 3 is used to make sure V_UPDATE occurs at the beginning of the first
132	 * line of vertical front porch
133	 */
134	set_reg_field_value(
135		value,
136		0,
137		CRTC_MASTER_UPDATE_MODE,
138		MASTER_UPDATE_MODE);
139
140	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value);
141
142	/* TODO: may want this on to catch underflow */
143	value = 0;
144	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_LOCK), value);
145
146	result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, true);
147
148	return result == BP_RESULT_OK;
149}
150
151void dce110_timing_generator_program_blank_color(
152		struct timing_generator *tg,
153		const struct tg_color *black_color)
154{
155	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
156	uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR);
157	uint32_t value = dm_read_reg(tg->ctx, addr);
158
159	set_reg_field_value(
160		value,
161		black_color->color_b_cb,
162		CRTC_BLACK_COLOR,
163		CRTC_BLACK_COLOR_B_CB);
164	set_reg_field_value(
165		value,
166		black_color->color_g_y,
167		CRTC_BLACK_COLOR,
168		CRTC_BLACK_COLOR_G_Y);
169	set_reg_field_value(
170		value,
171		black_color->color_r_cr,
172		CRTC_BLACK_COLOR,
173		CRTC_BLACK_COLOR_R_CR);
174
175	dm_write_reg(tg->ctx, addr, value);
176}
177
178/*
179 *****************************************************************************
180 *  Function: disable_stereo
181 *
182 *  @brief
183 *     Disables active stereo on controller
184 *     Frame Packing need to be disabled in vBlank or when CRTC not running
185 *****************************************************************************
186 */
187#if 0
188@TODOSTEREO
189static void disable_stereo(struct timing_generator *tg)
190{
191	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
192	uint32_t addr = CRTC_REG(mmCRTC_3D_STRUCTURE_CONTROL);
193	uint32_t value = 0;
194	uint32_t test = 0;
195	uint32_t field = 0;
196	uint32_t struc_en = 0;
197	uint32_t struc_stereo_sel_ovr = 0;
198
199	value = dm_read_reg(tg->ctx, addr);
200	struc_en = get_reg_field_value(
201			value,
202			CRTC_3D_STRUCTURE_CONTROL,
203			CRTC_3D_STRUCTURE_EN);
204
205	struc_stereo_sel_ovr = get_reg_field_value(
206			value,
207			CRTC_3D_STRUCTURE_CONTROL,
208			CRTC_3D_STRUCTURE_STEREO_SEL_OVR);
209
210	/*
211	 * When disabling Frame Packing in 2 step mode, we need to program both
212	 * registers at the same frame
213	 * Programming it in the beginning of VActive makes sure we are ok
214	 */
215
216	if (struc_en != 0 && struc_stereo_sel_ovr == 0) {
217		tg->funcs->wait_for_vblank(tg);
218		tg->funcs->wait_for_vactive(tg);
219	}
220
221	value = 0;
222	dm_write_reg(tg->ctx, addr, value);
223
224	addr = tg->regs[IDX_CRTC_STEREO_CONTROL];
225	dm_write_reg(tg->ctx, addr, value);
226}
227#endif
228
229/*
230 * disable_crtc - call ASIC Control Object to disable Timing generator.
231 */
232bool dce110_timing_generator_disable_crtc(struct timing_generator *tg)
233{
234	enum bp_result result;
235
236	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
237
238	result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, false);
239
240	/* Need to make sure stereo is disabled according to the DCE5.0 spec */
241
242	/*
243	 * @TODOSTEREO call this when adding stereo support
244	 * tg->funcs->disable_stereo(tg);
245	 */
246
247	return result == BP_RESULT_OK;
248}
249
250/*
251 * program_horz_count_by_2
252 * Programs DxCRTC_HORZ_COUNT_BY2_EN - 1 for DVI 30bpp mode, 0 otherwise
253 */
254static void program_horz_count_by_2(
255	struct timing_generator *tg,
256	const struct dc_crtc_timing *timing)
257{
258	uint32_t regval;
259	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
260
261	regval = dm_read_reg(tg->ctx,
262			CRTC_REG(mmCRTC_COUNT_CONTROL));
263
264	set_reg_field_value(regval, 0, CRTC_COUNT_CONTROL,
265			CRTC_HORZ_COUNT_BY2_EN);
266
267	if (timing->flags.HORZ_COUNT_BY_TWO)
268		set_reg_field_value(regval, 1, CRTC_COUNT_CONTROL,
269					CRTC_HORZ_COUNT_BY2_EN);
270
271	dm_write_reg(tg->ctx,
272			CRTC_REG(mmCRTC_COUNT_CONTROL), regval);
273}
274
275/*
276 * program_timing_generator
277 * Program CRTC Timing Registers - DxCRTC_H_*, DxCRTC_V_*, Pixel repetition.
278 * Call ASIC Control Object to program Timings.
279 */
280bool dce110_timing_generator_program_timing_generator(
281	struct timing_generator *tg,
282	const struct dc_crtc_timing *dc_crtc_timing)
283{
284	enum bp_result result;
285	struct bp_hw_crtc_timing_parameters bp_params;
286	struct dc_crtc_timing patched_crtc_timing;
287	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
288
289	uint32_t vsync_offset = dc_crtc_timing->v_border_bottom +
290			dc_crtc_timing->v_front_porch;
291	uint32_t v_sync_start = dc_crtc_timing->v_addressable + vsync_offset;
292
293	uint32_t hsync_offset = dc_crtc_timing->h_border_right +
294			dc_crtc_timing->h_front_porch;
295	uint32_t h_sync_start = dc_crtc_timing->h_addressable + hsync_offset;
296
297	memset(&bp_params, 0, sizeof(struct bp_hw_crtc_timing_parameters));
298
299	/* Due to an asic bug we need to apply the Front Porch workaround prior
300	 * to programming the timing.
301	 */
302
303	patched_crtc_timing = *dc_crtc_timing;
304
305	dce110_timing_generator_apply_front_porch_workaround(tg, &patched_crtc_timing);
306
307	bp_params.controller_id = tg110->controller_id;
308
309	bp_params.h_total = patched_crtc_timing.h_total;
310	bp_params.h_addressable =
311		patched_crtc_timing.h_addressable;
312	bp_params.v_total = patched_crtc_timing.v_total;
313	bp_params.v_addressable = patched_crtc_timing.v_addressable;
314
315	bp_params.h_sync_start = h_sync_start;
316	bp_params.h_sync_width = patched_crtc_timing.h_sync_width;
317	bp_params.v_sync_start = v_sync_start;
318	bp_params.v_sync_width = patched_crtc_timing.v_sync_width;
319
320	/* Set overscan */
321	bp_params.h_overscan_left =
322		patched_crtc_timing.h_border_left;
323	bp_params.h_overscan_right =
324		patched_crtc_timing.h_border_right;
325	bp_params.v_overscan_top = patched_crtc_timing.v_border_top;
326	bp_params.v_overscan_bottom =
327		patched_crtc_timing.v_border_bottom;
328
329	/* Set flags */
330	if (patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY == 1)
331		bp_params.flags.HSYNC_POSITIVE_POLARITY = 1;
332
333	if (patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY == 1)
334		bp_params.flags.VSYNC_POSITIVE_POLARITY = 1;
335
336	if (patched_crtc_timing.flags.INTERLACE == 1)
337		bp_params.flags.INTERLACE = 1;
338
339	if (patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1)
340		bp_params.flags.HORZ_COUNT_BY_TWO = 1;
341
342	result = tg->bp->funcs->program_crtc_timing(tg->bp, &bp_params);
343
344	program_horz_count_by_2(tg, &patched_crtc_timing);
345
346	tg110->base.funcs->enable_advanced_request(tg, true, &patched_crtc_timing);
347
348	/* Enable stereo - only when we need to pack 3D frame. Other types
349	 * of stereo handled in explicit call */
350
351	return result == BP_RESULT_OK;
352}
353
354/*
355 *****************************************************************************
356 *  Function: set_drr
357 *
358 *  @brief
359 *     Program dynamic refresh rate registers m_DxCRTC_V_TOTAL_*.
360 *
361 *  @param [in] pHwCrtcTiming: point to H
362 *  wCrtcTiming struct
363 *****************************************************************************
364 */
365void dce110_timing_generator_set_drr(
366	struct timing_generator *tg,
367	const struct drr_params *params)
368{
369	/* register values */
370	uint32_t v_total_min = 0;
371	uint32_t v_total_max = 0;
372	uint32_t v_total_cntl = 0;
373	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
374
375	uint32_t addr = 0;
376
377	addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
378	v_total_min = dm_read_reg(tg->ctx, addr);
379
380	addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
381	v_total_max = dm_read_reg(tg->ctx, addr);
382
383	addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL);
384	v_total_cntl = dm_read_reg(tg->ctx, addr);
385
386	if (params != NULL &&
387		params->vertical_total_max > 0 &&
388		params->vertical_total_min > 0) {
389
390		set_reg_field_value(v_total_max,
391				params->vertical_total_max - 1,
392				CRTC_V_TOTAL_MAX,
393				CRTC_V_TOTAL_MAX);
394
395		set_reg_field_value(v_total_min,
396				params->vertical_total_min - 1,
397				CRTC_V_TOTAL_MIN,
398				CRTC_V_TOTAL_MIN);
399
400		set_reg_field_value(v_total_cntl,
401				1,
402				CRTC_V_TOTAL_CONTROL,
403				CRTC_V_TOTAL_MIN_SEL);
404
405		set_reg_field_value(v_total_cntl,
406				1,
407				CRTC_V_TOTAL_CONTROL,
408				CRTC_V_TOTAL_MAX_SEL);
409
410		set_reg_field_value(v_total_cntl,
411				0,
412				CRTC_V_TOTAL_CONTROL,
413				CRTC_FORCE_LOCK_ON_EVENT);
414		set_reg_field_value(v_total_cntl,
415				0,
416				CRTC_V_TOTAL_CONTROL,
417				CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
418
419		set_reg_field_value(v_total_cntl,
420				0,
421				CRTC_V_TOTAL_CONTROL,
422				CRTC_SET_V_TOTAL_MIN_MASK_EN);
423
424		set_reg_field_value(v_total_cntl,
425				0,
426				CRTC_V_TOTAL_CONTROL,
427				CRTC_SET_V_TOTAL_MIN_MASK);
428	} else {
429		set_reg_field_value(v_total_cntl,
430			0,
431			CRTC_V_TOTAL_CONTROL,
432			CRTC_SET_V_TOTAL_MIN_MASK);
433		set_reg_field_value(v_total_cntl,
434				0,
435				CRTC_V_TOTAL_CONTROL,
436				CRTC_V_TOTAL_MIN_SEL);
437		set_reg_field_value(v_total_cntl,
438				0,
439				CRTC_V_TOTAL_CONTROL,
440				CRTC_V_TOTAL_MAX_SEL);
441		set_reg_field_value(v_total_min,
442				0,
443				CRTC_V_TOTAL_MIN,
444				CRTC_V_TOTAL_MIN);
445		set_reg_field_value(v_total_max,
446				0,
447				CRTC_V_TOTAL_MAX,
448				CRTC_V_TOTAL_MAX);
449		set_reg_field_value(v_total_cntl,
450				0,
451				CRTC_V_TOTAL_CONTROL,
452				CRTC_FORCE_LOCK_ON_EVENT);
453		set_reg_field_value(v_total_cntl,
454				0,
455				CRTC_V_TOTAL_CONTROL,
456				CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
457	}
458
459	addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
460	dm_write_reg(tg->ctx, addr, v_total_min);
461
462	addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
463	dm_write_reg(tg->ctx, addr, v_total_max);
464
465	addr = CRTC_REG(mmCRTC_V_TOTAL_CONTROL);
466	dm_write_reg(tg->ctx, addr, v_total_cntl);
467}
468
469void dce110_timing_generator_set_static_screen_control(
470	struct timing_generator *tg,
471	uint32_t event_triggers,
472	uint32_t num_frames)
473{
474	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
475	uint32_t static_screen_cntl = 0;
476	uint32_t addr = 0;
477
478	// By register spec, it only takes 8 bit value
479	if (num_frames > 0xFF)
480		num_frames = 0xFF;
481
482	addr = CRTC_REG(mmCRTC_STATIC_SCREEN_CONTROL);
483	static_screen_cntl = dm_read_reg(tg->ctx, addr);
484
485	set_reg_field_value(static_screen_cntl,
486				event_triggers,
487				CRTC_STATIC_SCREEN_CONTROL,
488				CRTC_STATIC_SCREEN_EVENT_MASK);
489
490	set_reg_field_value(static_screen_cntl,
491				num_frames,
492				CRTC_STATIC_SCREEN_CONTROL,
493				CRTC_STATIC_SCREEN_FRAME_COUNT);
494
495	dm_write_reg(tg->ctx, addr, static_screen_cntl);
496}
497
498/*
499 * get_vblank_counter
500 *
501 * @brief
502 * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
503 * holds the counter of frames.
504 *
505 * @param
506 * struct timing_generator *tg - [in] timing generator which controls the
507 * desired CRTC
508 *
509 * @return
510 * Counter of frames, which should equal to number of vblanks.
511 */
512uint32_t dce110_timing_generator_get_vblank_counter(struct timing_generator *tg)
513{
514	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
515	uint32_t addr = CRTC_REG(mmCRTC_STATUS_FRAME_COUNT);
516	uint32_t value = dm_read_reg(tg->ctx, addr);
517	uint32_t field = get_reg_field_value(
518			value, CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT);
519
520	return field;
521}
522
523/*
524 *****************************************************************************
525 *  Function: dce110_timing_generator_get_position
526 *
527 *  @brief
528 *     Returns CRTC vertical/horizontal counters
529 *
530 *  @param [out] position
531 *****************************************************************************
532 */
533void dce110_timing_generator_get_position(struct timing_generator *tg,
534	struct crtc_position *position)
535{
536	uint32_t value;
537	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
538
539	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_STATUS_POSITION));
540
541	position->horizontal_count = get_reg_field_value(
542			value,
543			CRTC_STATUS_POSITION,
544			CRTC_HORZ_COUNT);
545
546	position->vertical_count = get_reg_field_value(
547			value,
548			CRTC_STATUS_POSITION,
549			CRTC_VERT_COUNT);
550
551	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_NOM_VERT_POSITION));
552
553	position->nominal_vcount = get_reg_field_value(
554			value,
555			CRTC_NOM_VERT_POSITION,
556			CRTC_VERT_COUNT_NOM);
557}
558
559/*
560 *****************************************************************************
561 *  Function: get_crtc_scanoutpos
562 *
563 *  @brief
564 *     Returns CRTC vertical/horizontal counters
565 *
566 *  @param [out] vpos, hpos
567 *****************************************************************************
568 */
569void dce110_timing_generator_get_crtc_scanoutpos(
570	struct timing_generator *tg,
571	uint32_t *v_blank_start,
572	uint32_t *v_blank_end,
573	uint32_t *h_position,
574	uint32_t *v_position)
575{
576	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
577	struct crtc_position position;
578
579	uint32_t value  = dm_read_reg(tg->ctx,
580			CRTC_REG(mmCRTC_V_BLANK_START_END));
581
582	*v_blank_start = get_reg_field_value(value,
583					     CRTC_V_BLANK_START_END,
584					     CRTC_V_BLANK_START);
585	*v_blank_end = get_reg_field_value(value,
586					   CRTC_V_BLANK_START_END,
587					   CRTC_V_BLANK_END);
588
589	dce110_timing_generator_get_position(
590			tg, &position);
591
592	*h_position = position.horizontal_count;
593	*v_position = position.vertical_count;
594}
595
596/* TODO: is it safe to assume that mask/shift of Primary and Underlay
597 * are the same?
598 * For example: today CRTC_H_TOTAL == CRTCV_H_TOTAL but is it always
599 * guaranteed? */
600void dce110_timing_generator_program_blanking(
601	struct timing_generator *tg,
602	const struct dc_crtc_timing *timing)
603{
604	uint32_t vsync_offset = timing->v_border_bottom +
605			timing->v_front_porch;
606	uint32_t v_sync_start = timing->v_addressable + vsync_offset;
607
608	uint32_t hsync_offset = timing->h_border_right +
609			timing->h_front_porch;
610	uint32_t h_sync_start = timing->h_addressable + hsync_offset;
611	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
612
613	struct dc_context *ctx = tg->ctx;
614	uint32_t value = 0;
615	uint32_t addr = 0;
616	uint32_t tmp = 0;
617
618	addr = CRTC_REG(mmCRTC_H_TOTAL);
619	value = dm_read_reg(ctx, addr);
620	set_reg_field_value(
621		value,
622		timing->h_total - 1,
623		CRTC_H_TOTAL,
624		CRTC_H_TOTAL);
625	dm_write_reg(ctx, addr, value);
626
627	addr = CRTC_REG(mmCRTC_V_TOTAL);
628	value = dm_read_reg(ctx, addr);
629	set_reg_field_value(
630		value,
631		timing->v_total - 1,
632		CRTC_V_TOTAL,
633		CRTC_V_TOTAL);
634	dm_write_reg(ctx, addr, value);
635
636	/* In case of V_TOTAL_CONTROL is on, make sure V_TOTAL_MAX and
637	 * V_TOTAL_MIN are equal to V_TOTAL.
638	 */
639	addr = CRTC_REG(mmCRTC_V_TOTAL_MAX);
640	value = dm_read_reg(ctx, addr);
641	set_reg_field_value(
642		value,
643		timing->v_total - 1,
644		CRTC_V_TOTAL_MAX,
645		CRTC_V_TOTAL_MAX);
646	dm_write_reg(ctx, addr, value);
647
648	addr = CRTC_REG(mmCRTC_V_TOTAL_MIN);
649	value = dm_read_reg(ctx, addr);
650	set_reg_field_value(
651		value,
652		timing->v_total - 1,
653		CRTC_V_TOTAL_MIN,
654		CRTC_V_TOTAL_MIN);
655	dm_write_reg(ctx, addr, value);
656
657	addr = CRTC_REG(mmCRTC_H_BLANK_START_END);
658	value = dm_read_reg(ctx, addr);
659
660	tmp = timing->h_total -
661		(h_sync_start + timing->h_border_left);
662
663	set_reg_field_value(
664		value,
665		tmp,
666		CRTC_H_BLANK_START_END,
667		CRTC_H_BLANK_END);
668
669	tmp = tmp + timing->h_addressable +
670		timing->h_border_left + timing->h_border_right;
671
672	set_reg_field_value(
673		value,
674		tmp,
675		CRTC_H_BLANK_START_END,
676		CRTC_H_BLANK_START);
677
678	dm_write_reg(ctx, addr, value);
679
680	addr = CRTC_REG(mmCRTC_V_BLANK_START_END);
681	value = dm_read_reg(ctx, addr);
682
683	tmp = timing->v_total - (v_sync_start + timing->v_border_top);
684
685	set_reg_field_value(
686		value,
687		tmp,
688		CRTC_V_BLANK_START_END,
689		CRTC_V_BLANK_END);
690
691	tmp = tmp + timing->v_addressable + timing->v_border_top +
692		timing->v_border_bottom;
693
694	set_reg_field_value(
695		value,
696		tmp,
697		CRTC_V_BLANK_START_END,
698		CRTC_V_BLANK_START);
699
700	dm_write_reg(ctx, addr, value);
701}
702
703void dce110_timing_generator_set_test_pattern(
704	struct timing_generator *tg,
705	/* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
706	 * because this is not DP-specific (which is probably somewhere in DP
707	 * encoder) */
708	enum controller_dp_test_pattern test_pattern,
709	enum dc_color_depth color_depth)
710{
711	struct dc_context *ctx = tg->ctx;
712	uint32_t value;
713	uint32_t addr;
714	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
715	enum test_pattern_color_format bit_depth;
716	enum test_pattern_dyn_range dyn_range;
717	enum test_pattern_mode mode;
718	/* color ramp generator mixes 16-bits color */
719	uint32_t src_bpc = 16;
720	/* requested bpc */
721	uint32_t dst_bpc;
722	uint32_t index;
723	/* RGB values of the color bars.
724	 * Produce two RGB colors: RGB0 - white (all Fs)
725	 * and RGB1 - black (all 0s)
726	 * (three RGB components for two colors)
727	 */
728	uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
729						0x0000, 0x0000};
730	/* dest color (converted to the specified color format) */
731	uint16_t dst_color[6];
732	uint32_t inc_base;
733
734	/* translate to bit depth */
735	switch (color_depth) {
736	case COLOR_DEPTH_666:
737		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
738	break;
739	case COLOR_DEPTH_888:
740		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
741	break;
742	case COLOR_DEPTH_101010:
743		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
744	break;
745	case COLOR_DEPTH_121212:
746		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
747	break;
748	default:
749		bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
750	break;
751	}
752
753	switch (test_pattern) {
754	case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
755	case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
756	{
757		dyn_range = (test_pattern ==
758				CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
759				TEST_PATTERN_DYN_RANGE_CEA :
760				TEST_PATTERN_DYN_RANGE_VESA);
761		mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
762		value = 0;
763		addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
764
765		set_reg_field_value(
766			value,
767			6,
768			CRTC_TEST_PATTERN_PARAMETERS,
769			CRTC_TEST_PATTERN_VRES);
770		set_reg_field_value(
771			value,
772			6,
773			CRTC_TEST_PATTERN_PARAMETERS,
774			CRTC_TEST_PATTERN_HRES);
775
776		dm_write_reg(ctx, addr, value);
777
778		addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
779		value = 0;
780
781		set_reg_field_value(
782			value,
783			1,
784			CRTC_TEST_PATTERN_CONTROL,
785			CRTC_TEST_PATTERN_EN);
786
787		set_reg_field_value(
788			value,
789			mode,
790			CRTC_TEST_PATTERN_CONTROL,
791			CRTC_TEST_PATTERN_MODE);
792
793		set_reg_field_value(
794			value,
795			dyn_range,
796			CRTC_TEST_PATTERN_CONTROL,
797			CRTC_TEST_PATTERN_DYNAMIC_RANGE);
798		set_reg_field_value(
799			value,
800			bit_depth,
801			CRTC_TEST_PATTERN_CONTROL,
802			CRTC_TEST_PATTERN_COLOR_FORMAT);
803		dm_write_reg(ctx, addr, value);
804	}
805	break;
806
807	case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
808	case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
809	{
810		mode = (test_pattern ==
811			CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
812			TEST_PATTERN_MODE_VERTICALBARS :
813			TEST_PATTERN_MODE_HORIZONTALBARS);
814
815		switch (bit_depth) {
816		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
817			dst_bpc = 6;
818		break;
819		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
820			dst_bpc = 8;
821		break;
822		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
823			dst_bpc = 10;
824		break;
825		default:
826			dst_bpc = 8;
827		break;
828		}
829
830		/* adjust color to the required colorFormat */
831		for (index = 0; index < 6; index++) {
832			/* dst = 2^dstBpc * src / 2^srcBpc = src >>
833			 * (srcBpc - dstBpc);
834			 */
835			dst_color[index] =
836				src_color[index] >> (src_bpc - dst_bpc);
837		/* CRTC_TEST_PATTERN_DATA has 16 bits,
838		 * lowest 6 are hardwired to ZERO
839		 * color bits should be left aligned aligned to MSB
840		 * XXXXXXXXXX000000 for 10 bit,
841		 * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6
842		 */
843			dst_color[index] <<= (16 - dst_bpc);
844		}
845
846		value = 0;
847		addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
848		dm_write_reg(ctx, addr, value);
849
850		/* We have to write the mask before data, similar to pipeline.
851		 * For example, for 8 bpc, if we want RGB0 to be magenta,
852		 * and RGB1 to be cyan,
853		 * we need to make 7 writes:
854		 * MASK   DATA
855		 * 000001 00000000 00000000                     set mask to R0
856		 * 000010 11111111 00000000     R0 255, 0xFF00, set mask to G0
857		 * 000100 00000000 00000000     G0 0,   0x0000, set mask to B0
858		 * 001000 11111111 00000000     B0 255, 0xFF00, set mask to R1
859		 * 010000 00000000 00000000     R1 0,   0x0000, set mask to G1
860		 * 100000 11111111 00000000     G1 255, 0xFF00, set mask to B1
861		 * 100000 11111111 00000000     B1 255, 0xFF00
862		 *
863		 * we will make a loop of 6 in which we prepare the mask,
864		 * then write, then prepare the color for next write.
865		 * first iteration will write mask only,
866		 * but each next iteration color prepared in
867		 * previous iteration will be written within new mask,
868		 * the last component will written separately,
869		 * mask is not changing between 6th and 7th write
870		 * and color will be prepared by last iteration
871		 */
872
873		/* write color, color values mask in CRTC_TEST_PATTERN_MASK
874		 * is B1, G1, R1, B0, G0, R0
875		 */
876		value = 0;
877		addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR);
878		for (index = 0; index < 6; index++) {
879			/* prepare color mask, first write PATTERN_DATA
880			 * will have all zeros
881			 */
882			set_reg_field_value(
883				value,
884				(1 << index),
885				CRTC_TEST_PATTERN_COLOR,
886				CRTC_TEST_PATTERN_MASK);
887			/* write color component */
888			dm_write_reg(ctx, addr, value);
889			/* prepare next color component,
890			 * will be written in the next iteration
891			 */
892			set_reg_field_value(
893				value,
894				dst_color[index],
895				CRTC_TEST_PATTERN_COLOR,
896				CRTC_TEST_PATTERN_DATA);
897		}
898		/* write last color component,
899		 * it's been already prepared in the loop
900		 */
901		dm_write_reg(ctx, addr, value);
902
903		/* enable test pattern */
904		addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
905		value = 0;
906
907		set_reg_field_value(
908			value,
909			1,
910			CRTC_TEST_PATTERN_CONTROL,
911			CRTC_TEST_PATTERN_EN);
912
913		set_reg_field_value(
914			value,
915			mode,
916			CRTC_TEST_PATTERN_CONTROL,
917			CRTC_TEST_PATTERN_MODE);
918
919		set_reg_field_value(
920			value,
921			0,
922			CRTC_TEST_PATTERN_CONTROL,
923			CRTC_TEST_PATTERN_DYNAMIC_RANGE);
924
925		set_reg_field_value(
926			value,
927			bit_depth,
928			CRTC_TEST_PATTERN_CONTROL,
929			CRTC_TEST_PATTERN_COLOR_FORMAT);
930
931		dm_write_reg(ctx, addr, value);
932	}
933	break;
934
935	case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
936	{
937		mode = (bit_depth ==
938			TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
939			TEST_PATTERN_MODE_DUALRAMP_RGB :
940			TEST_PATTERN_MODE_SINGLERAMP_RGB);
941
942		switch (bit_depth) {
943		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
944			dst_bpc = 6;
945		break;
946		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
947			dst_bpc = 8;
948		break;
949		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
950			dst_bpc = 10;
951		break;
952		default:
953			dst_bpc = 8;
954		break;
955		}
956
957		/* increment for the first ramp for one color gradation
958		 * 1 gradation for 6-bit color is 2^10
959		 * gradations in 16-bit color
960		 */
961		inc_base = (src_bpc - dst_bpc);
962
963		value = 0;
964		addr = CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS);
965
966		switch (bit_depth) {
967		case TEST_PATTERN_COLOR_FORMAT_BPC_6:
968		{
969			set_reg_field_value(
970				value,
971				inc_base,
972				CRTC_TEST_PATTERN_PARAMETERS,
973				CRTC_TEST_PATTERN_INC0);
974			set_reg_field_value(
975				value,
976				0,
977				CRTC_TEST_PATTERN_PARAMETERS,
978				CRTC_TEST_PATTERN_INC1);
979			set_reg_field_value(
980				value,
981				6,
982				CRTC_TEST_PATTERN_PARAMETERS,
983				CRTC_TEST_PATTERN_HRES);
984			set_reg_field_value(
985				value,
986				6,
987				CRTC_TEST_PATTERN_PARAMETERS,
988				CRTC_TEST_PATTERN_VRES);
989			set_reg_field_value(
990				value,
991				0,
992				CRTC_TEST_PATTERN_PARAMETERS,
993				CRTC_TEST_PATTERN_RAMP0_OFFSET);
994		}
995		break;
996		case TEST_PATTERN_COLOR_FORMAT_BPC_8:
997		{
998			set_reg_field_value(
999				value,
1000				inc_base,
1001				CRTC_TEST_PATTERN_PARAMETERS,
1002				CRTC_TEST_PATTERN_INC0);
1003			set_reg_field_value(
1004				value,
1005				0,
1006				CRTC_TEST_PATTERN_PARAMETERS,
1007				CRTC_TEST_PATTERN_INC1);
1008			set_reg_field_value(
1009				value,
1010				8,
1011				CRTC_TEST_PATTERN_PARAMETERS,
1012				CRTC_TEST_PATTERN_HRES);
1013			set_reg_field_value(
1014				value,
1015				6,
1016				CRTC_TEST_PATTERN_PARAMETERS,
1017				CRTC_TEST_PATTERN_VRES);
1018			set_reg_field_value(
1019				value,
1020				0,
1021				CRTC_TEST_PATTERN_PARAMETERS,
1022				CRTC_TEST_PATTERN_RAMP0_OFFSET);
1023		}
1024		break;
1025		case TEST_PATTERN_COLOR_FORMAT_BPC_10:
1026		{
1027			set_reg_field_value(
1028				value,
1029				inc_base,
1030				CRTC_TEST_PATTERN_PARAMETERS,
1031				CRTC_TEST_PATTERN_INC0);
1032			set_reg_field_value(
1033				value,
1034				inc_base + 2,
1035				CRTC_TEST_PATTERN_PARAMETERS,
1036				CRTC_TEST_PATTERN_INC1);
1037			set_reg_field_value(
1038				value,
1039				8,
1040				CRTC_TEST_PATTERN_PARAMETERS,
1041				CRTC_TEST_PATTERN_HRES);
1042			set_reg_field_value(
1043				value,
1044				5,
1045				CRTC_TEST_PATTERN_PARAMETERS,
1046				CRTC_TEST_PATTERN_VRES);
1047			set_reg_field_value(
1048				value,
1049				384 << 6,
1050				CRTC_TEST_PATTERN_PARAMETERS,
1051				CRTC_TEST_PATTERN_RAMP0_OFFSET);
1052		}
1053		break;
1054		default:
1055		break;
1056		}
1057		dm_write_reg(ctx, addr, value);
1058
1059		value = 0;
1060		addr = CRTC_REG(mmCRTC_TEST_PATTERN_COLOR);
1061		dm_write_reg(ctx, addr, value);
1062
1063		/* enable test pattern */
1064		addr = CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL);
1065		value = 0;
1066
1067		set_reg_field_value(
1068			value,
1069			1,
1070			CRTC_TEST_PATTERN_CONTROL,
1071			CRTC_TEST_PATTERN_EN);
1072
1073		set_reg_field_value(
1074			value,
1075			mode,
1076			CRTC_TEST_PATTERN_CONTROL,
1077			CRTC_TEST_PATTERN_MODE);
1078
1079		set_reg_field_value(
1080			value,
1081			0,
1082			CRTC_TEST_PATTERN_CONTROL,
1083			CRTC_TEST_PATTERN_DYNAMIC_RANGE);
1084		/* add color depth translation here */
1085		set_reg_field_value(
1086			value,
1087			bit_depth,
1088			CRTC_TEST_PATTERN_CONTROL,
1089			CRTC_TEST_PATTERN_COLOR_FORMAT);
1090
1091		dm_write_reg(ctx, addr, value);
1092	}
1093	break;
1094	case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
1095	{
1096		value = 0;
1097		dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_CONTROL), value);
1098		dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_COLOR), value);
1099		dm_write_reg(ctx, CRTC_REG(mmCRTC_TEST_PATTERN_PARAMETERS),
1100				value);
1101	}
1102	break;
1103	default:
1104	break;
1105	}
1106}
1107
1108/*
1109 * dce110_timing_generator_validate_timing
1110 * The timing generators support a maximum display size of is 8192 x 8192 pixels,
1111 * including both active display and blanking periods. Check H Total and V Total.
1112 */
1113bool dce110_timing_generator_validate_timing(
1114	struct timing_generator *tg,
1115	const struct dc_crtc_timing *timing,
1116	enum signal_type signal)
1117{
1118	uint32_t h_blank;
1119	uint32_t h_back_porch, hsync_offset, h_sync_start;
1120
1121	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1122
1123	ASSERT(timing != NULL);
1124
1125	if (!timing)
1126		return false;
1127
1128	hsync_offset = timing->h_border_right + timing->h_front_porch;
1129	h_sync_start = timing->h_addressable + hsync_offset;
1130
1131	/* Currently we don't support 3D, so block all 3D timings */
1132	if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE)
1133		return false;
1134
1135	/* Temporarily blocking interlacing mode until it's supported */
1136	if (timing->flags.INTERLACE == 1)
1137		return false;
1138
1139	/* Check maximum number of pixels supported by Timing Generator
1140	 * (Currently will never fail, in order to fail needs display which
1141	 * needs more than 8192 horizontal and
1142	 * more than 8192 vertical total pixels)
1143	 */
1144	if (timing->h_total > tg110->max_h_total ||
1145		timing->v_total > tg110->max_v_total)
1146		return false;
1147
1148	h_blank = (timing->h_total - timing->h_addressable -
1149		timing->h_border_right -
1150		timing->h_border_left);
1151
1152	if (h_blank < tg110->min_h_blank)
1153		return false;
1154
1155	if (timing->h_front_porch < tg110->min_h_front_porch)
1156		return false;
1157
1158	h_back_porch = h_blank - (h_sync_start -
1159		timing->h_addressable -
1160		timing->h_border_right -
1161		timing->h_sync_width);
1162
1163	if (h_back_porch < tg110->min_h_back_porch)
1164		return false;
1165
1166	return true;
1167}
1168
1169/*
1170 * Wait till we are at the beginning of VBlank.
1171 */
1172void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg)
1173{
1174	/* We want to catch beginning of VBlank here, so if the first try are
1175	 * in VBlank, we might be very close to Active, in this case wait for
1176	 * another frame
1177	 */
1178	while (dce110_timing_generator_is_in_vertical_blank(tg)) {
1179		if (!dce110_timing_generator_is_counter_moving(tg)) {
1180			/* error - no point to wait if counter is not moving */
1181			break;
1182		}
1183	}
1184
1185	while (!dce110_timing_generator_is_in_vertical_blank(tg)) {
1186		if (!dce110_timing_generator_is_counter_moving(tg)) {
1187			/* error - no point to wait if counter is not moving */
1188			break;
1189		}
1190	}
1191}
1192
1193/*
1194 * Wait till we are in VActive (anywhere in VActive)
1195 */
1196void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg)
1197{
1198	while (dce110_timing_generator_is_in_vertical_blank(tg)) {
1199		if (!dce110_timing_generator_is_counter_moving(tg)) {
1200			/* error - no point to wait if counter is not moving */
1201			break;
1202		}
1203	}
1204}
1205
1206/*
1207 *****************************************************************************
1208 *  Function: dce110_timing_generator_setup_global_swap_lock
1209 *
1210 *  @brief
1211 *     Setups Global Swap Lock group for current pipe
1212 *     Pipe can join or leave GSL group, become a TimingServer or TimingClient
1213 *
1214 *  @param [in] gsl_params: setup data
1215 *****************************************************************************
1216 */
1217void dce110_timing_generator_setup_global_swap_lock(
1218	struct timing_generator *tg,
1219	const struct dcp_gsl_params *gsl_params)
1220{
1221	uint32_t value;
1222	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1223	uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1224	uint32_t check_point = FLIP_READY_BACK_LOOKUP;
1225
1226	value = dm_read_reg(tg->ctx, address);
1227
1228	/* This pipe will belong to GSL Group zero. */
1229	set_reg_field_value(value,
1230			    1,
1231			    DCP_GSL_CONTROL,
1232			    DCP_GSL0_EN);
1233
1234	set_reg_field_value(value,
1235			    gsl_params->gsl_master == tg->inst,
1236			    DCP_GSL_CONTROL,
1237			    DCP_GSL_MASTER_EN);
1238
1239	set_reg_field_value(value,
1240			    HFLIP_READY_DELAY,
1241			    DCP_GSL_CONTROL,
1242			    DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1243
1244	/* Keep signal low (pending high) during 6 lines.
1245	 * Also defines minimum interval before re-checking signal. */
1246	set_reg_field_value(value,
1247			    HFLIP_CHECK_DELAY,
1248			    DCP_GSL_CONTROL,
1249			    DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1250
1251	dm_write_reg(tg->ctx, CRTC_REG(mmDCP_GSL_CONTROL), value);
1252	value = 0;
1253
1254	set_reg_field_value(value,
1255			    gsl_params->gsl_master,
1256			    DCIO_GSL0_CNTL,
1257			    DCIO_GSL0_VSYNC_SEL);
1258
1259	set_reg_field_value(value,
1260			    0,
1261			    DCIO_GSL0_CNTL,
1262			    DCIO_GSL0_TIMING_SYNC_SEL);
1263
1264	set_reg_field_value(value,
1265			    0,
1266			    DCIO_GSL0_CNTL,
1267			    DCIO_GSL0_GLOBAL_UNLOCK_SEL);
1268
1269	dm_write_reg(tg->ctx, CRTC_REG(mmDCIO_GSL0_CNTL), value);
1270
1271
1272	{
1273		uint32_t value_crtc_vtotal;
1274
1275		value_crtc_vtotal = dm_read_reg(tg->ctx,
1276				CRTC_REG(mmCRTC_V_TOTAL));
1277
1278		set_reg_field_value(value,
1279				    0,/* DCP_GSL_PURPOSE_SURFACE_FLIP */
1280				    DCP_GSL_CONTROL,
1281				    DCP_GSL_SYNC_SOURCE);
1282
1283		/* Checkpoint relative to end of frame */
1284		check_point = get_reg_field_value(value_crtc_vtotal,
1285						  CRTC_V_TOTAL,
1286						  CRTC_V_TOTAL);
1287
1288		dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_GSL_WINDOW), 0);
1289	}
1290
1291	set_reg_field_value(value,
1292			    1,
1293			    DCP_GSL_CONTROL,
1294			    DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
1295
1296	dm_write_reg(tg->ctx, address, value);
1297
1298	/********************************************************************/
1299	address = CRTC_REG(mmCRTC_GSL_CONTROL);
1300
1301	value = dm_read_reg(tg->ctx, address);
1302	set_reg_field_value(value,
1303			    check_point - FLIP_READY_BACK_LOOKUP,
1304			    CRTC_GSL_CONTROL,
1305			    CRTC_GSL_CHECK_LINE_NUM);
1306
1307	set_reg_field_value(value,
1308			    VFLIP_READY_DELAY,
1309			    CRTC_GSL_CONTROL,
1310			    CRTC_GSL_FORCE_DELAY);
1311
1312	dm_write_reg(tg->ctx, address, value);
1313}
1314
1315void dce110_timing_generator_tear_down_global_swap_lock(
1316	struct timing_generator *tg)
1317{
1318	/* Clear all the register writes done by
1319	 * dce110_timing_generator_setup_global_swap_lock
1320	 */
1321
1322	uint32_t value;
1323	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1324	uint32_t address = DCP_REG(mmDCP_GSL_CONTROL);
1325
1326	value = 0;
1327
1328	/* This pipe will belong to GSL Group zero. */
1329	/* Settig HW default values from reg specs */
1330	set_reg_field_value(value,
1331			0,
1332			DCP_GSL_CONTROL,
1333			DCP_GSL0_EN);
1334
1335	set_reg_field_value(value,
1336			0,
1337			DCP_GSL_CONTROL,
1338			DCP_GSL_MASTER_EN);
1339
1340	set_reg_field_value(value,
1341			0x2,
1342			DCP_GSL_CONTROL,
1343			DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
1344
1345	set_reg_field_value(value,
1346			0x6,
1347			DCP_GSL_CONTROL,
1348			DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
1349
1350	/* Restore DCP_GSL_PURPOSE_SURFACE_FLIP */
1351	{
1352		dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_V_TOTAL));
1353
1354		set_reg_field_value(value,
1355				0,
1356				DCP_GSL_CONTROL,
1357				DCP_GSL_SYNC_SOURCE);
1358	}
1359
1360	set_reg_field_value(value,
1361			0,
1362			DCP_GSL_CONTROL,
1363			DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
1364
1365	dm_write_reg(tg->ctx, address, value);
1366
1367	/********************************************************************/
1368	address = CRTC_REG(mmCRTC_GSL_CONTROL);
1369
1370	value = 0;
1371	set_reg_field_value(value,
1372			0,
1373			CRTC_GSL_CONTROL,
1374			CRTC_GSL_CHECK_LINE_NUM);
1375
1376	set_reg_field_value(value,
1377			0x2,
1378			CRTC_GSL_CONTROL,
1379			CRTC_GSL_FORCE_DELAY);
1380
1381	dm_write_reg(tg->ctx, address, value);
1382}
1383/*
1384 *****************************************************************************
1385 *  Function: is_counter_moving
1386 *
1387 *  @brief
1388 *     check if the timing generator is currently going
1389 *
1390 *  @return
1391 *     true if currently going, false if currently paused or stopped.
1392 *
1393 *****************************************************************************
1394 */
1395bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg)
1396{
1397	struct crtc_position position1, position2;
1398
1399	tg->funcs->get_position(tg, &position1);
1400	tg->funcs->get_position(tg, &position2);
1401
1402	if (position1.horizontal_count == position2.horizontal_count &&
1403		position1.vertical_count == position2.vertical_count)
1404		return false;
1405	else
1406		return true;
1407}
1408
1409void dce110_timing_generator_enable_advanced_request(
1410	struct timing_generator *tg,
1411	bool enable,
1412	const struct dc_crtc_timing *timing)
1413{
1414	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1415	uint32_t addr = CRTC_REG(mmCRTC_START_LINE_CONTROL);
1416	uint32_t value = dm_read_reg(tg->ctx, addr);
1417
1418	if (enable) {
1419		set_reg_field_value(
1420			value,
1421			0,
1422			CRTC_START_LINE_CONTROL,
1423			CRTC_LEGACY_REQUESTOR_EN);
1424	} else {
1425		set_reg_field_value(
1426			value,
1427			1,
1428			CRTC_START_LINE_CONTROL,
1429			CRTC_LEGACY_REQUESTOR_EN);
1430	}
1431
1432	if ((timing->v_sync_width + timing->v_front_porch) <= 3) {
1433		set_reg_field_value(
1434			value,
1435			3,
1436			CRTC_START_LINE_CONTROL,
1437			CRTC_ADVANCED_START_LINE_POSITION);
1438		set_reg_field_value(
1439			value,
1440			0,
1441			CRTC_START_LINE_CONTROL,
1442			CRTC_PREFETCH_EN);
1443	} else {
1444		set_reg_field_value(
1445			value,
1446			4,
1447			CRTC_START_LINE_CONTROL,
1448			CRTC_ADVANCED_START_LINE_POSITION);
1449		set_reg_field_value(
1450			value,
1451			1,
1452			CRTC_START_LINE_CONTROL,
1453			CRTC_PREFETCH_EN);
1454	}
1455
1456	set_reg_field_value(
1457		value,
1458		1,
1459		CRTC_START_LINE_CONTROL,
1460		CRTC_PROGRESSIVE_START_LINE_EARLY);
1461
1462	set_reg_field_value(
1463		value,
1464		1,
1465		CRTC_START_LINE_CONTROL,
1466		CRTC_INTERLACE_START_LINE_EARLY);
1467
1468	dm_write_reg(tg->ctx, addr, value);
1469}
1470
1471/*TODO: Figure out if we need this function. */
1472void dce110_timing_generator_set_lock_master(struct timing_generator *tg,
1473		bool lock)
1474{
1475	struct dc_context *ctx = tg->ctx;
1476	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1477	uint32_t addr = CRTC_REG(mmCRTC_MASTER_UPDATE_LOCK);
1478	uint32_t value = dm_read_reg(ctx, addr);
1479
1480	set_reg_field_value(
1481		value,
1482		lock ? 1 : 0,
1483		CRTC_MASTER_UPDATE_LOCK,
1484		MASTER_UPDATE_LOCK);
1485
1486	dm_write_reg(ctx, addr, value);
1487}
1488
1489void dce110_timing_generator_enable_reset_trigger(
1490	struct timing_generator *tg,
1491	int source_tg_inst)
1492{
1493	uint32_t value;
1494	uint32_t rising_edge = 0;
1495	uint32_t falling_edge = 0;
1496	enum trigger_source_select trig_src_select = TRIGGER_SOURCE_SELECT_LOGIC_ZERO;
1497	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1498
1499	/* Setup trigger edge */
1500	{
1501		uint32_t pol_value = dm_read_reg(tg->ctx,
1502				CRTC_REG(mmCRTC_V_SYNC_A_CNTL));
1503
1504		/* Register spec has reversed definition:
1505		 *	0 for positive, 1 for negative */
1506		if (get_reg_field_value(pol_value,
1507				CRTC_V_SYNC_A_CNTL,
1508				CRTC_V_SYNC_A_POL) == 0) {
1509			rising_edge = 1;
1510		} else {
1511			falling_edge = 1;
1512		}
1513	}
1514
1515	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
1516
1517	trig_src_select = TRIGGER_SOURCE_SELECT_GSL_GROUP0;
1518
1519	set_reg_field_value(value,
1520			trig_src_select,
1521			CRTC_TRIGB_CNTL,
1522			CRTC_TRIGB_SOURCE_SELECT);
1523
1524	set_reg_field_value(value,
1525			TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
1526			CRTC_TRIGB_CNTL,
1527			CRTC_TRIGB_POLARITY_SELECT);
1528
1529	set_reg_field_value(value,
1530			rising_edge,
1531			CRTC_TRIGB_CNTL,
1532			CRTC_TRIGB_RISING_EDGE_DETECT_CNTL);
1533
1534	set_reg_field_value(value,
1535			falling_edge,
1536			CRTC_TRIGB_CNTL,
1537			CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL);
1538
1539	set_reg_field_value(value,
1540			0, /* send every signal */
1541			CRTC_TRIGB_CNTL,
1542			CRTC_TRIGB_FREQUENCY_SELECT);
1543
1544	set_reg_field_value(value,
1545			0, /* no delay */
1546			CRTC_TRIGB_CNTL,
1547			CRTC_TRIGB_DELAY);
1548
1549	set_reg_field_value(value,
1550			1, /* clear trigger status */
1551			CRTC_TRIGB_CNTL,
1552			CRTC_TRIGB_CLEAR);
1553
1554	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
1555
1556	/**************************************************************/
1557
1558	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1559
1560	set_reg_field_value(value,
1561			2, /* force H count to H_TOTAL and V count to V_TOTAL */
1562			CRTC_FORCE_COUNT_NOW_CNTL,
1563			CRTC_FORCE_COUNT_NOW_MODE);
1564
1565	set_reg_field_value(value,
1566			1, /* TriggerB - we never use TriggerA */
1567			CRTC_FORCE_COUNT_NOW_CNTL,
1568			CRTC_FORCE_COUNT_NOW_TRIG_SEL);
1569
1570	set_reg_field_value(value,
1571			1, /* clear trigger status */
1572			CRTC_FORCE_COUNT_NOW_CNTL,
1573			CRTC_FORCE_COUNT_NOW_CLEAR);
1574
1575	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1576}
1577
1578void dce110_timing_generator_enable_crtc_reset(
1579		struct timing_generator *tg,
1580		int source_tg_inst,
1581		struct crtc_trigger_info *crtc_tp)
1582{
1583	uint32_t value = 0;
1584	uint32_t rising_edge = 0;
1585	uint32_t falling_edge = 0;
1586	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1587
1588	/* Setup trigger edge */
1589	switch (crtc_tp->event) {
1590	case CRTC_EVENT_VSYNC_RISING:
1591			rising_edge = 1;
1592			break;
1593
1594	case CRTC_EVENT_VSYNC_FALLING:
1595		falling_edge = 1;
1596		break;
1597	}
1598
1599	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
1600
1601	set_reg_field_value(value,
1602			    source_tg_inst,
1603			    CRTC_TRIGB_CNTL,
1604			    CRTC_TRIGB_SOURCE_SELECT);
1605
1606	set_reg_field_value(value,
1607			    TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
1608			    CRTC_TRIGB_CNTL,
1609			    CRTC_TRIGB_POLARITY_SELECT);
1610
1611	set_reg_field_value(value,
1612			    rising_edge,
1613			    CRTC_TRIGB_CNTL,
1614			    CRTC_TRIGB_RISING_EDGE_DETECT_CNTL);
1615
1616	set_reg_field_value(value,
1617			    falling_edge,
1618			    CRTC_TRIGB_CNTL,
1619			    CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL);
1620
1621	set_reg_field_value(value,
1622			    1, /* clear trigger status */
1623			    CRTC_TRIGB_CNTL,
1624			    CRTC_TRIGB_CLEAR);
1625
1626	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
1627
1628	/**************************************************************/
1629
1630	switch (crtc_tp->delay) {
1631	case TRIGGER_DELAY_NEXT_LINE:
1632		value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1633
1634		set_reg_field_value(value,
1635				    0, /* force H count to H_TOTAL and V count to V_TOTAL */
1636				    CRTC_FORCE_COUNT_NOW_CNTL,
1637				    CRTC_FORCE_COUNT_NOW_MODE);
1638
1639		set_reg_field_value(value,
1640				    0, /* TriggerB - we never use TriggerA */
1641				    CRTC_FORCE_COUNT_NOW_CNTL,
1642				    CRTC_FORCE_COUNT_NOW_TRIG_SEL);
1643
1644		set_reg_field_value(value,
1645				    1, /* clear trigger status */
1646				    CRTC_FORCE_COUNT_NOW_CNTL,
1647				    CRTC_FORCE_COUNT_NOW_CLEAR);
1648
1649		dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1650
1651		value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
1652
1653		set_reg_field_value(value,
1654				    1,
1655				    CRTC_VERT_SYNC_CONTROL,
1656				    CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
1657
1658		set_reg_field_value(value,
1659				    2,
1660				    CRTC_VERT_SYNC_CONTROL,
1661				    CRTC_AUTO_FORCE_VSYNC_MODE);
1662
1663		break;
1664
1665	case TRIGGER_DELAY_NEXT_PIXEL:
1666		value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
1667
1668		set_reg_field_value(value,
1669				    1,
1670				    CRTC_VERT_SYNC_CONTROL,
1671				    CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
1672
1673		set_reg_field_value(value,
1674				    0,
1675				    CRTC_VERT_SYNC_CONTROL,
1676				    CRTC_AUTO_FORCE_VSYNC_MODE);
1677
1678		dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL), value);
1679
1680		value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1681
1682		set_reg_field_value(value,
1683				    2, /* force H count to H_TOTAL and V count to V_TOTAL */
1684				    CRTC_FORCE_COUNT_NOW_CNTL,
1685				    CRTC_FORCE_COUNT_NOW_MODE);
1686
1687		set_reg_field_value(value,
1688				    1, /* TriggerB - we never use TriggerA */
1689				    CRTC_FORCE_COUNT_NOW_CNTL,
1690				    CRTC_FORCE_COUNT_NOW_TRIG_SEL);
1691
1692		set_reg_field_value(value,
1693				    1, /* clear trigger status */
1694				    CRTC_FORCE_COUNT_NOW_CNTL,
1695				    CRTC_FORCE_COUNT_NOW_CLEAR);
1696
1697		dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1698		break;
1699	}
1700
1701	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE));
1702
1703	set_reg_field_value(value,
1704			    2,
1705			    CRTC_MASTER_UPDATE_MODE,
1706			    MASTER_UPDATE_MODE);
1707
1708	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value);
1709}
1710void dce110_timing_generator_disable_reset_trigger(
1711	struct timing_generator *tg)
1712{
1713	uint32_t value;
1714	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1715
1716	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1717
1718	set_reg_field_value(value,
1719			    0, /* force counter now mode is disabled */
1720			    CRTC_FORCE_COUNT_NOW_CNTL,
1721			    CRTC_FORCE_COUNT_NOW_MODE);
1722
1723	set_reg_field_value(value,
1724			    1, /* clear trigger status */
1725			    CRTC_FORCE_COUNT_NOW_CNTL,
1726			    CRTC_FORCE_COUNT_NOW_CLEAR);
1727
1728	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
1729
1730	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
1731
1732	set_reg_field_value(value,
1733			    1,
1734			    CRTC_VERT_SYNC_CONTROL,
1735			    CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
1736
1737	set_reg_field_value(value,
1738			    0,
1739			    CRTC_VERT_SYNC_CONTROL,
1740			    CRTC_AUTO_FORCE_VSYNC_MODE);
1741
1742	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL), value);
1743
1744	/********************************************************************/
1745	value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
1746
1747	set_reg_field_value(value,
1748			    TRIGGER_SOURCE_SELECT_LOGIC_ZERO,
1749			    CRTC_TRIGB_CNTL,
1750			    CRTC_TRIGB_SOURCE_SELECT);
1751
1752	set_reg_field_value(value,
1753			    TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
1754			    CRTC_TRIGB_CNTL,
1755			    CRTC_TRIGB_POLARITY_SELECT);
1756
1757	set_reg_field_value(value,
1758			    1, /* clear trigger status */
1759			    CRTC_TRIGB_CNTL,
1760			    CRTC_TRIGB_CLEAR);
1761
1762	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
1763}
1764
1765/*
1766 *****************************************************************************
1767 *  @brief
1768 *     Checks whether CRTC triggered reset occurred
1769 *
1770 *  @return
1771 *     true if triggered reset occurred, false otherwise
1772 *****************************************************************************
1773 */
1774bool dce110_timing_generator_did_triggered_reset_occur(
1775	struct timing_generator *tg)
1776{
1777	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1778	uint32_t value = dm_read_reg(tg->ctx,
1779			CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
1780	uint32_t value1 = dm_read_reg(tg->ctx,
1781			CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
1782	bool force = get_reg_field_value(value,
1783					 CRTC_FORCE_COUNT_NOW_CNTL,
1784					 CRTC_FORCE_COUNT_NOW_OCCURRED) != 0;
1785	bool vert_sync = get_reg_field_value(value1,
1786					     CRTC_VERT_SYNC_CONTROL,
1787					     CRTC_FORCE_VSYNC_NEXT_LINE_OCCURRED) != 0;
1788
1789	return (force || vert_sync);
1790}
1791
1792/*
1793 * dce110_timing_generator_disable_vga
1794 * Turn OFF VGA Mode and Timing  - DxVGA_CONTROL
1795 * VGA Mode and VGA Timing is used by VBIOS on CRT Monitors;
1796 */
1797void dce110_timing_generator_disable_vga(
1798	struct timing_generator *tg)
1799{
1800	uint32_t addr = 0;
1801	uint32_t value = 0;
1802
1803	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1804
1805	switch (tg110->controller_id) {
1806	case CONTROLLER_ID_D0:
1807		addr = mmD1VGA_CONTROL;
1808		break;
1809	case CONTROLLER_ID_D1:
1810		addr = mmD2VGA_CONTROL;
1811		break;
1812	case CONTROLLER_ID_D2:
1813		addr = mmD3VGA_CONTROL;
1814		break;
1815	case CONTROLLER_ID_D3:
1816		addr = mmD4VGA_CONTROL;
1817		break;
1818	case CONTROLLER_ID_D4:
1819		addr = mmD5VGA_CONTROL;
1820		break;
1821	case CONTROLLER_ID_D5:
1822		addr = mmD6VGA_CONTROL;
1823		break;
1824	default:
1825		break;
1826	}
1827	value = dm_read_reg(tg->ctx, addr);
1828
1829	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE);
1830	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT);
1831	set_reg_field_value(
1832			value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT);
1833	set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN);
1834
1835	dm_write_reg(tg->ctx, addr, value);
1836}
1837
1838/*
1839 * set_overscan_color_black
1840 *
1841 * @param :black_color is one of the color space
1842 *    :this routine will set overscan black color according to the color space.
1843 * @return none
1844 */
1845void dce110_timing_generator_set_overscan_color_black(
1846	struct timing_generator *tg,
1847	const struct tg_color *color)
1848{
1849	struct dc_context *ctx = tg->ctx;
1850	uint32_t addr;
1851	uint32_t value = 0;
1852	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1853
1854	set_reg_field_value(
1855			value,
1856			color->color_b_cb,
1857			CRTC_OVERSCAN_COLOR,
1858			CRTC_OVERSCAN_COLOR_BLUE);
1859
1860	set_reg_field_value(
1861			value,
1862			color->color_r_cr,
1863			CRTC_OVERSCAN_COLOR,
1864			CRTC_OVERSCAN_COLOR_RED);
1865
1866	set_reg_field_value(
1867			value,
1868			color->color_g_y,
1869			CRTC_OVERSCAN_COLOR,
1870			CRTC_OVERSCAN_COLOR_GREEN);
1871
1872	addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1873	dm_write_reg(ctx, addr, value);
1874	addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1875	dm_write_reg(ctx, addr, value);
1876	/* This is desirable to have a constant DAC output voltage during the
1877	 * blank time that is higher than the 0 volt reference level that the
1878	 * DAC outputs when the NBLANK signal
1879	 * is asserted low, such as for output to an analog TV. */
1880	addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1881	dm_write_reg(ctx, addr, value);
1882
1883	/* TO DO we have to program EXT registers and we need to know LB DATA
1884	 * format because it is used when more 10 , i.e. 12 bits per color
1885	 *
1886	 * m_mmDxCRTC_OVERSCAN_COLOR_EXT
1887	 * m_mmDxCRTC_BLACK_COLOR_EXT
1888	 * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
1889	 */
1890
1891}
1892
1893void dce110_tg_program_blank_color(struct timing_generator *tg,
1894		const struct tg_color *black_color)
1895{
1896	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1897	uint32_t addr = CRTC_REG(mmCRTC_BLACK_COLOR);
1898	uint32_t value = dm_read_reg(tg->ctx, addr);
1899
1900	set_reg_field_value(
1901		value,
1902		black_color->color_b_cb,
1903		CRTC_BLACK_COLOR,
1904		CRTC_BLACK_COLOR_B_CB);
1905	set_reg_field_value(
1906		value,
1907		black_color->color_g_y,
1908		CRTC_BLACK_COLOR,
1909		CRTC_BLACK_COLOR_G_Y);
1910	set_reg_field_value(
1911		value,
1912		black_color->color_r_cr,
1913		CRTC_BLACK_COLOR,
1914		CRTC_BLACK_COLOR_R_CR);
1915
1916	dm_write_reg(tg->ctx, addr, value);
1917
1918	addr = CRTC_REG(mmCRTC_BLANK_DATA_COLOR);
1919	dm_write_reg(tg->ctx, addr, value);
1920}
1921
1922void dce110_tg_set_overscan_color(struct timing_generator *tg,
1923	const struct tg_color *overscan_color)
1924{
1925	struct dc_context *ctx = tg->ctx;
1926	uint32_t value = 0;
1927	uint32_t addr;
1928	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1929
1930	set_reg_field_value(
1931		value,
1932		overscan_color->color_b_cb,
1933		CRTC_OVERSCAN_COLOR,
1934		CRTC_OVERSCAN_COLOR_BLUE);
1935
1936	set_reg_field_value(
1937		value,
1938		overscan_color->color_g_y,
1939		CRTC_OVERSCAN_COLOR,
1940		CRTC_OVERSCAN_COLOR_GREEN);
1941
1942	set_reg_field_value(
1943		value,
1944		overscan_color->color_r_cr,
1945		CRTC_OVERSCAN_COLOR,
1946		CRTC_OVERSCAN_COLOR_RED);
1947
1948	addr = CRTC_REG(mmCRTC_OVERSCAN_COLOR);
1949	dm_write_reg(ctx, addr, value);
1950}
1951
1952void dce110_tg_program_timing(struct timing_generator *tg,
1953	const struct dc_crtc_timing *timing,
1954	int vready_offset,
1955	int vstartup_start,
1956	int vupdate_offset,
1957	int vupdate_width,
1958	const enum signal_type signal,
1959	bool use_vbios)
1960{
1961	if (use_vbios)
1962		dce110_timing_generator_program_timing_generator(tg, timing);
1963	else
1964		dce110_timing_generator_program_blanking(tg, timing);
1965}
1966
1967bool dce110_tg_is_blanked(struct timing_generator *tg)
1968{
1969	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1970	uint32_t value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL));
1971
1972	if (get_reg_field_value(
1973			value,
1974			CRTC_BLANK_CONTROL,
1975			CRTC_BLANK_DATA_EN) == 1 &&
1976		get_reg_field_value(
1977			value,
1978			CRTC_BLANK_CONTROL,
1979			CRTC_CURRENT_BLANK_STATE) == 1)
1980		return true;
1981	return false;
1982}
1983
1984void dce110_tg_set_blank(struct timing_generator *tg,
1985		bool enable_blanking)
1986{
1987	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1988	uint32_t value = 0;
1989
1990	set_reg_field_value(
1991		value,
1992		1,
1993		CRTC_DOUBLE_BUFFER_CONTROL,
1994		CRTC_BLANK_DATA_DOUBLE_BUFFER_EN);
1995
1996	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_DOUBLE_BUFFER_CONTROL), value);
1997	value = 0;
1998
1999	if (enable_blanking) {
2000		set_reg_field_value(
2001			value,
2002			1,
2003			CRTC_BLANK_CONTROL,
2004			CRTC_BLANK_DATA_EN);
2005
2006		dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), value);
2007
2008	} else
2009		dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), 0);
2010}
2011
2012bool dce110_tg_validate_timing(struct timing_generator *tg,
2013	const struct dc_crtc_timing *timing)
2014{
2015	return dce110_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
2016}
2017
2018void dce110_tg_wait_for_state(struct timing_generator *tg,
2019	enum crtc_state state)
2020{
2021	switch (state) {
2022	case CRTC_STATE_VBLANK:
2023		dce110_timing_generator_wait_for_vblank(tg);
2024		break;
2025
2026	case CRTC_STATE_VACTIVE:
2027		dce110_timing_generator_wait_for_vactive(tg);
2028		break;
2029
2030	default:
2031		break;
2032	}
2033}
2034
2035void dce110_tg_set_colors(struct timing_generator *tg,
2036	const struct tg_color *blank_color,
2037	const struct tg_color *overscan_color)
2038{
2039	if (blank_color != NULL)
2040		dce110_tg_program_blank_color(tg, blank_color);
2041	if (overscan_color != NULL)
2042		dce110_tg_set_overscan_color(tg, overscan_color);
2043}
2044
2045/* Gets first line of blank region of the display timing for CRTC
2046 * and programms is as a trigger to fire vertical interrupt
2047 */
2048bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
2049{
2050	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2051	uint32_t v_blank_start = 0;
2052	uint32_t v_blank_end = 0;
2053	uint32_t val = 0;
2054	uint32_t h_position, v_position;
2055
2056	tg->funcs->get_scanoutpos(
2057			tg,
2058			&v_blank_start,
2059			&v_blank_end,
2060			&h_position,
2061			&v_position);
2062
2063	if (v_blank_start == 0 || v_blank_end == 0)
2064		return false;
2065
2066	set_reg_field_value(
2067		val,
2068		v_blank_start,
2069		CRTC_VERTICAL_INTERRUPT0_POSITION,
2070		CRTC_VERTICAL_INTERRUPT0_LINE_START);
2071
2072	/* Set interval width for interrupt to fire to 1 scanline */
2073	set_reg_field_value(
2074		val,
2075		v_blank_start + width,
2076		CRTC_VERTICAL_INTERRUPT0_POSITION,
2077		CRTC_VERTICAL_INTERRUPT0_LINE_END);
2078
2079	dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERTICAL_INTERRUPT0_POSITION), val);
2080
2081	return true;
2082}
2083
2084static bool dce110_is_tg_enabled(struct timing_generator *tg)
2085{
2086	uint32_t addr = 0;
2087	uint32_t value = 0;
2088	uint32_t field = 0;
2089	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2090
2091	addr = CRTC_REG(mmCRTC_CONTROL);
2092	value = dm_read_reg(tg->ctx, addr);
2093	field = get_reg_field_value(value, CRTC_CONTROL,
2094				    CRTC_CURRENT_MASTER_EN_STATE);
2095	return field == 1;
2096}
2097
2098bool dce110_configure_crc(struct timing_generator *tg,
2099			  const struct crc_params *params)
2100{
2101	uint32_t cntl_addr = 0;
2102	uint32_t addr = 0;
2103	uint32_t value;
2104	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2105
2106	/* Cannot configure crc on a CRTC that is disabled */
2107	if (!dce110_is_tg_enabled(tg))
2108		return false;
2109
2110	cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL);
2111
2112	/* First, disable CRC before we configure it. */
2113	dm_write_reg(tg->ctx, cntl_addr, 0);
2114
2115	if (!params->enable)
2116		return true;
2117
2118	/* Program frame boundaries */
2119	/* Window A x axis start and end. */
2120	value = 0;
2121	addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL);
2122	set_reg_field_value(value, params->windowa_x_start,
2123			    CRTC_CRC0_WINDOWA_X_CONTROL,
2124			    CRTC_CRC0_WINDOWA_X_START);
2125	set_reg_field_value(value, params->windowa_x_end,
2126			    CRTC_CRC0_WINDOWA_X_CONTROL,
2127			    CRTC_CRC0_WINDOWA_X_END);
2128	dm_write_reg(tg->ctx, addr, value);
2129
2130	/* Window A y axis start and end. */
2131	value = 0;
2132	addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL);
2133	set_reg_field_value(value, params->windowa_y_start,
2134			    CRTC_CRC0_WINDOWA_Y_CONTROL,
2135			    CRTC_CRC0_WINDOWA_Y_START);
2136	set_reg_field_value(value, params->windowa_y_end,
2137			    CRTC_CRC0_WINDOWA_Y_CONTROL,
2138			    CRTC_CRC0_WINDOWA_Y_END);
2139	dm_write_reg(tg->ctx, addr, value);
2140
2141	/* Window B x axis start and end. */
2142	value = 0;
2143	addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL);
2144	set_reg_field_value(value, params->windowb_x_start,
2145			    CRTC_CRC0_WINDOWB_X_CONTROL,
2146			    CRTC_CRC0_WINDOWB_X_START);
2147	set_reg_field_value(value, params->windowb_x_end,
2148			    CRTC_CRC0_WINDOWB_X_CONTROL,
2149			    CRTC_CRC0_WINDOWB_X_END);
2150	dm_write_reg(tg->ctx, addr, value);
2151
2152	/* Window B y axis start and end. */
2153	value = 0;
2154	addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL);
2155	set_reg_field_value(value, params->windowb_y_start,
2156			    CRTC_CRC0_WINDOWB_Y_CONTROL,
2157			    CRTC_CRC0_WINDOWB_Y_START);
2158	set_reg_field_value(value, params->windowb_y_end,
2159			    CRTC_CRC0_WINDOWB_Y_CONTROL,
2160			    CRTC_CRC0_WINDOWB_Y_END);
2161	dm_write_reg(tg->ctx, addr, value);
2162
2163	/* Set crc mode and selection, and enable. Only using CRC0*/
2164	value = 0;
2165	set_reg_field_value(value, params->continuous_mode ? 1 : 0,
2166			    CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
2167	set_reg_field_value(value, params->selection,
2168			    CRTC_CRC_CNTL, CRTC_CRC0_SELECT);
2169	set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
2170	dm_write_reg(tg->ctx, cntl_addr, value);
2171
2172	return true;
2173}
2174
2175bool dce110_get_crc(struct timing_generator *tg,
2176		    uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
2177{
2178	uint32_t addr = 0;
2179	uint32_t value = 0;
2180	uint32_t field = 0;
2181	struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
2182
2183	addr = CRTC_REG(mmCRTC_CRC_CNTL);
2184	value = dm_read_reg(tg->ctx, addr);
2185	field = get_reg_field_value(value, CRTC_CRC_CNTL, CRTC_CRC_EN);
2186
2187	/* Early return if CRC is not enabled for this CRTC */
2188	if (!field)
2189		return false;
2190
2191	addr = CRTC_REG(mmCRTC_CRC0_DATA_RG);
2192	value = dm_read_reg(tg->ctx, addr);
2193	*r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR);
2194	*g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y);
2195
2196	addr = CRTC_REG(mmCRTC_CRC0_DATA_B);
2197	value = dm_read_reg(tg->ctx, addr);
2198	*b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB);
2199
2200	return true;
2201}
2202
2203static const struct timing_generator_funcs dce110_tg_funcs = {
2204		.validate_timing = dce110_tg_validate_timing,
2205		.program_timing = dce110_tg_program_timing,
2206		.enable_crtc = dce110_timing_generator_enable_crtc,
2207		.disable_crtc = dce110_timing_generator_disable_crtc,
2208		.is_counter_moving = dce110_timing_generator_is_counter_moving,
2209		.get_position = dce110_timing_generator_get_position,
2210		.get_frame_count = dce110_timing_generator_get_vblank_counter,
2211		.get_scanoutpos = dce110_timing_generator_get_crtc_scanoutpos,
2212		.set_early_control = dce110_timing_generator_set_early_control,
2213		.wait_for_state = dce110_tg_wait_for_state,
2214		.set_blank = dce110_tg_set_blank,
2215		.is_blanked = dce110_tg_is_blanked,
2216		.set_colors = dce110_tg_set_colors,
2217		.set_overscan_blank_color =
2218				dce110_timing_generator_set_overscan_color_black,
2219		.set_blank_color = dce110_timing_generator_program_blank_color,
2220		.disable_vga = dce110_timing_generator_disable_vga,
2221		.did_triggered_reset_occur =
2222				dce110_timing_generator_did_triggered_reset_occur,
2223		.setup_global_swap_lock =
2224				dce110_timing_generator_setup_global_swap_lock,
2225		.enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
2226		.enable_crtc_reset = dce110_timing_generator_enable_crtc_reset,
2227		.disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
2228		.tear_down_global_swap_lock =
2229				dce110_timing_generator_tear_down_global_swap_lock,
2230		.enable_advanced_request =
2231				dce110_timing_generator_enable_advanced_request,
2232		.set_drr =
2233				dce110_timing_generator_set_drr,
2234		.get_last_used_drr_vtotal = NULL,
2235		.set_static_screen_control =
2236			dce110_timing_generator_set_static_screen_control,
2237		.set_test_pattern = dce110_timing_generator_set_test_pattern,
2238		.arm_vert_intr = dce110_arm_vert_intr,
2239		.is_tg_enabled = dce110_is_tg_enabled,
2240		.configure_crc = dce110_configure_crc,
2241		.get_crc = dce110_get_crc,
2242};
2243
2244void dce110_timing_generator_construct(
2245	struct dce110_timing_generator *tg110,
2246	struct dc_context *ctx,
2247	uint32_t instance,
2248	const struct dce110_timing_generator_offsets *offsets)
2249{
2250	tg110->controller_id = CONTROLLER_ID_D0 + instance;
2251	tg110->base.inst = instance;
2252
2253	tg110->offsets = *offsets;
2254
2255	tg110->base.funcs = &dce110_tg_funcs;
2256
2257	tg110->base.ctx = ctx;
2258	tg110->base.bp = ctx->dc_bios;
2259
2260	tg110->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
2261	tg110->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
2262
2263	tg110->min_h_blank = 56;
2264	tg110->min_h_front_porch = 4;
2265	tg110->min_h_back_porch = 4;
2266}
2267