1 /*
2  * Copyright 2012-16 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 #include "dm_services.h"
26 
27 #include "dce/dce_11_0_d.h"
28 #include "dce/dce_11_0_sh_mask.h"
29 /* TODO: this needs to be looked at, used by Stella's workaround*/
30 #include "gmc/gmc_8_2_d.h"
31 #include "gmc/gmc_8_2_sh_mask.h"
32 
33 #include "include/logger_interface.h"
34 #include "inc/dce_calcs.h"
35 
36 #include "dce/dce_mem_input.h"
37 
38 #include "dce110/dce110_mem_input_v.h"
39 
40 static void set_flip_control(
41 	struct dce_mem_input *mem_input110,
42 	bool immediate)
43 {
44 	uint32_t value = 0;
45 
46 	value = dm_read_reg(
47 			mem_input110->base.ctx,
48 			mmUNP_FLIP_CONTROL);
49 
50 	set_reg_field_value(value, 1,
51 			UNP_FLIP_CONTROL,
52 			GRPH_SURFACE_UPDATE_PENDING_MODE);
53 
54 	dm_write_reg(
55 			mem_input110->base.ctx,
56 			mmUNP_FLIP_CONTROL,
57 			value);
58 }
59 
60 /* chroma part */
61 static void program_pri_addr_c(
62 	struct dce_mem_input *mem_input110,
63 	PHYSICAL_ADDRESS_LOC address)
64 {
65 	uint32_t value = 0;
66 	uint32_t temp = 0;
67 	/*high register MUST be programmed first*/
68 	temp = address.high_part &
69 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK;
70 
71 	set_reg_field_value(value, temp,
72 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
73 		GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C);
74 
75 	dm_write_reg(
76 		mem_input110->base.ctx,
77 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
78 		value);
79 
80 	temp = 0;
81 	value = 0;
82 	temp = address.low_part >>
83 	UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT;
84 
85 	set_reg_field_value(value, temp,
86 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
87 		GRPH_PRIMARY_SURFACE_ADDRESS_C);
88 
89 	dm_write_reg(
90 		mem_input110->base.ctx,
91 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
92 		value);
93 }
94 
95 /* luma part */
96 static void program_pri_addr_l(
97 	struct dce_mem_input *mem_input110,
98 	PHYSICAL_ADDRESS_LOC address)
99 {
100 	uint32_t value = 0;
101 	uint32_t temp = 0;
102 
103 	/*high register MUST be programmed first*/
104 	temp = address.high_part &
105 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK;
106 
107 	set_reg_field_value(value, temp,
108 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
109 		GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L);
110 
111 	dm_write_reg(
112 		mem_input110->base.ctx,
113 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
114 		value);
115 
116 	temp = 0;
117 	value = 0;
118 	temp = address.low_part >>
119 	UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT;
120 
121 	set_reg_field_value(value, temp,
122 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
123 		GRPH_PRIMARY_SURFACE_ADDRESS_L);
124 
125 	dm_write_reg(
126 		mem_input110->base.ctx,
127 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
128 		value);
129 }
130 
131 static void program_addr(
132 	struct dce_mem_input *mem_input110,
133 	const struct dc_plane_address *addr)
134 {
135 	switch (addr->type) {
136 	case PLN_ADDR_TYPE_GRAPHICS:
137 		program_pri_addr_l(
138 			mem_input110,
139 			addr->grph.addr);
140 		break;
141 	case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
142 		program_pri_addr_c(
143 			mem_input110,
144 			addr->video_progressive.chroma_addr);
145 		program_pri_addr_l(
146 			mem_input110,
147 			addr->video_progressive.luma_addr);
148 		break;
149 	default:
150 		/* not supported */
151 		BREAK_TO_DEBUGGER();
152 	}
153 }
154 
155 static void enable(struct dce_mem_input *mem_input110)
156 {
157 	uint32_t value = 0;
158 
159 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE);
160 	set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE);
161 	dm_write_reg(mem_input110->base.ctx,
162 		mmUNP_GRPH_ENABLE,
163 		value);
164 }
165 
166 static void program_tiling(
167 	struct dce_mem_input *mem_input110,
168 	const union dc_tiling_info *info,
169 	const enum surface_pixel_format pixel_format)
170 {
171 	uint32_t value = 0;
172 
173 	set_reg_field_value(value, info->gfx8.num_banks,
174 		UNP_GRPH_CONTROL, GRPH_NUM_BANKS);
175 
176 	set_reg_field_value(value, info->gfx8.bank_width,
177 		UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L);
178 
179 	set_reg_field_value(value, info->gfx8.bank_height,
180 		UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L);
181 
182 	set_reg_field_value(value, info->gfx8.tile_aspect,
183 		UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L);
184 
185 	set_reg_field_value(value, info->gfx8.tile_split,
186 		UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L);
187 
188 	set_reg_field_value(value, info->gfx8.tile_mode,
189 		UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L);
190 
191 	set_reg_field_value(value, info->gfx8.pipe_config,
192 		UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG);
193 
194 	set_reg_field_value(value, info->gfx8.array_mode,
195 		UNP_GRPH_CONTROL, GRPH_ARRAY_MODE);
196 
197 	set_reg_field_value(value, 1,
198 		UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
199 
200 	set_reg_field_value(value, 0,
201 		UNP_GRPH_CONTROL, GRPH_Z);
202 
203 	dm_write_reg(
204 		mem_input110->base.ctx,
205 		mmUNP_GRPH_CONTROL,
206 		value);
207 
208 	value = 0;
209 
210 	set_reg_field_value(value, info->gfx8.bank_width_c,
211 		UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C);
212 
213 	set_reg_field_value(value, info->gfx8.bank_height_c,
214 		UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C);
215 
216 	set_reg_field_value(value, info->gfx8.tile_aspect_c,
217 		UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C);
218 
219 	set_reg_field_value(value, info->gfx8.tile_split_c,
220 		UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C);
221 
222 	set_reg_field_value(value, info->gfx8.tile_mode_c,
223 		UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C);
224 
225 	dm_write_reg(
226 		mem_input110->base.ctx,
227 		mmUNP_GRPH_CONTROL_C,
228 		value);
229 }
230 
231 static void program_size_and_rotation(
232 	struct dce_mem_input *mem_input110,
233 	enum dc_rotation_angle rotation,
234 	const union plane_size *plane_size)
235 {
236 	uint32_t value = 0;
237 	union plane_size local_size = *plane_size;
238 
239 	if (rotation == ROTATION_ANGLE_90 ||
240 		rotation == ROTATION_ANGLE_270) {
241 
242 		swap(local_size.video.luma_size.x,
243 		     local_size.video.luma_size.y);
244 		swap(local_size.video.luma_size.width,
245 		     local_size.video.luma_size.height);
246 		swap(local_size.video.chroma_size.x,
247 		     local_size.video.chroma_size.y);
248 		swap(local_size.video.chroma_size.width,
249 		     local_size.video.chroma_size.height);
250 	}
251 
252 	value = 0;
253 	set_reg_field_value(value, local_size.video.luma_pitch,
254 			UNP_GRPH_PITCH_L, GRPH_PITCH_L);
255 
256 	dm_write_reg(
257 		mem_input110->base.ctx,
258 		mmUNP_GRPH_PITCH_L,
259 		value);
260 
261 	value = 0;
262 	set_reg_field_value(value, local_size.video.chroma_pitch,
263 			UNP_GRPH_PITCH_C, GRPH_PITCH_C);
264 	dm_write_reg(
265 		mem_input110->base.ctx,
266 		mmUNP_GRPH_PITCH_C,
267 		value);
268 
269 	value = 0;
270 	set_reg_field_value(value, 0,
271 			UNP_GRPH_X_START_L, GRPH_X_START_L);
272 	dm_write_reg(
273 		mem_input110->base.ctx,
274 		mmUNP_GRPH_X_START_L,
275 		value);
276 
277 	value = 0;
278 	set_reg_field_value(value, 0,
279 			UNP_GRPH_X_START_C, GRPH_X_START_C);
280 	dm_write_reg(
281 		mem_input110->base.ctx,
282 		mmUNP_GRPH_X_START_C,
283 		value);
284 
285 	value = 0;
286 	set_reg_field_value(value, 0,
287 			UNP_GRPH_Y_START_L, GRPH_Y_START_L);
288 	dm_write_reg(
289 		mem_input110->base.ctx,
290 		mmUNP_GRPH_Y_START_L,
291 		value);
292 
293 	value = 0;
294 	set_reg_field_value(value, 0,
295 			UNP_GRPH_Y_START_C, GRPH_Y_START_C);
296 	dm_write_reg(
297 		mem_input110->base.ctx,
298 		mmUNP_GRPH_Y_START_C,
299 		value);
300 
301 	value = 0;
302 	set_reg_field_value(value, local_size.video.luma_size.x +
303 			local_size.video.luma_size.width,
304 			UNP_GRPH_X_END_L, GRPH_X_END_L);
305 	dm_write_reg(
306 		mem_input110->base.ctx,
307 		mmUNP_GRPH_X_END_L,
308 		value);
309 
310 	value = 0;
311 	set_reg_field_value(value, local_size.video.chroma_size.x +
312 			local_size.video.chroma_size.width,
313 			UNP_GRPH_X_END_C, GRPH_X_END_C);
314 	dm_write_reg(
315 		mem_input110->base.ctx,
316 		mmUNP_GRPH_X_END_C,
317 		value);
318 
319 	value = 0;
320 	set_reg_field_value(value, local_size.video.luma_size.y +
321 			local_size.video.luma_size.height,
322 			UNP_GRPH_Y_END_L, GRPH_Y_END_L);
323 	dm_write_reg(
324 		mem_input110->base.ctx,
325 		mmUNP_GRPH_Y_END_L,
326 		value);
327 
328 	value = 0;
329 	set_reg_field_value(value, local_size.video.chroma_size.y +
330 			local_size.video.chroma_size.height,
331 			UNP_GRPH_Y_END_C, GRPH_Y_END_C);
332 	dm_write_reg(
333 		mem_input110->base.ctx,
334 		mmUNP_GRPH_Y_END_C,
335 		value);
336 
337 	value = 0;
338 	switch (rotation) {
339 	case ROTATION_ANGLE_90:
340 		set_reg_field_value(value, 3,
341 			UNP_HW_ROTATION, ROTATION_ANGLE);
342 		break;
343 	case ROTATION_ANGLE_180:
344 		set_reg_field_value(value, 2,
345 			UNP_HW_ROTATION, ROTATION_ANGLE);
346 		break;
347 	case ROTATION_ANGLE_270:
348 		set_reg_field_value(value, 1,
349 			UNP_HW_ROTATION, ROTATION_ANGLE);
350 		break;
351 	default:
352 		set_reg_field_value(value, 0,
353 			UNP_HW_ROTATION, ROTATION_ANGLE);
354 		break;
355 	}
356 
357 	dm_write_reg(
358 		mem_input110->base.ctx,
359 		mmUNP_HW_ROTATION,
360 		value);
361 }
362 
363 static void program_pixel_format(
364 	struct dce_mem_input *mem_input110,
365 	enum surface_pixel_format format)
366 {
367 	if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
368 		uint32_t value;
369 		uint8_t grph_depth;
370 		uint8_t grph_format;
371 
372 		value =	dm_read_reg(
373 				mem_input110->base.ctx,
374 				mmUNP_GRPH_CONTROL);
375 
376 		switch (format) {
377 		case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
378 			grph_depth = 0;
379 			grph_format = 0;
380 			break;
381 		case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
382 			grph_depth = 1;
383 			grph_format = 1;
384 			break;
385 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
386 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
387 			grph_depth = 2;
388 			grph_format = 0;
389 			break;
390 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
391 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
392 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
393 			grph_depth = 2;
394 			grph_format = 1;
395 			break;
396 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
397 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
398 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
399 			grph_depth = 3;
400 			grph_format = 0;
401 			break;
402 		default:
403 			grph_depth = 2;
404 			grph_format = 0;
405 			break;
406 		}
407 
408 		set_reg_field_value(
409 				value,
410 				grph_depth,
411 				UNP_GRPH_CONTROL,
412 				GRPH_DEPTH);
413 		set_reg_field_value(
414 				value,
415 				grph_format,
416 				UNP_GRPH_CONTROL,
417 				GRPH_FORMAT);
418 
419 		dm_write_reg(
420 				mem_input110->base.ctx,
421 				mmUNP_GRPH_CONTROL,
422 				value);
423 
424 		value =	dm_read_reg(
425 				mem_input110->base.ctx,
426 				mmUNP_GRPH_CONTROL_EXP);
427 
428 		/* VIDEO FORMAT 0 */
429 		set_reg_field_value(
430 				value,
431 				0,
432 				UNP_GRPH_CONTROL_EXP,
433 				VIDEO_FORMAT);
434 		dm_write_reg(
435 				mem_input110->base.ctx,
436 				mmUNP_GRPH_CONTROL_EXP,
437 				value);
438 
439 	} else {
440 		/* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */
441 		uint32_t value;
442 		uint8_t video_format;
443 
444 		value =	dm_read_reg(
445 				mem_input110->base.ctx,
446 				mmUNP_GRPH_CONTROL_EXP);
447 
448 		switch (format) {
449 		case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
450 			video_format = 2;
451 			break;
452 		case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
453 			video_format = 3;
454 			break;
455 		default:
456 			video_format = 0;
457 			break;
458 		}
459 
460 		set_reg_field_value(
461 			value,
462 			video_format,
463 			UNP_GRPH_CONTROL_EXP,
464 			VIDEO_FORMAT);
465 
466 		dm_write_reg(
467 			mem_input110->base.ctx,
468 			mmUNP_GRPH_CONTROL_EXP,
469 			value);
470 	}
471 }
472 
473 static
474 bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input)
475 {
476 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
477 	uint32_t value;
478 
479 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE);
480 
481 	if (get_reg_field_value(value, UNP_GRPH_UPDATE,
482 			GRPH_SURFACE_UPDATE_PENDING))
483 		return true;
484 
485 	mem_input->current_address = mem_input->request_address;
486 	return false;
487 }
488 
489 static
490 bool dce_mem_input_v_program_surface_flip_and_addr(
491 	struct mem_input *mem_input,
492 	const struct dc_plane_address *address,
493 	bool flip_immediate)
494 {
495 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
496 
497 	set_flip_control(mem_input110, flip_immediate);
498 	program_addr(mem_input110,
499 		address);
500 
501 	mem_input->request_address = *address;
502 
503 	return true;
504 }
505 
506 /* Scatter Gather param tables */
507 static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = {
508 		{  8, 64, 64,  8,  8, 1, 4, 0, 0},
509 		{ 16, 64, 32,  8, 16, 1, 8, 0, 0},
510 		{ 32, 32, 32, 16, 16, 1, 8, 0, 0},
511 		{ 64,  8, 32, 16, 16, 1, 8, 0, 0}, /* fake */
512 };
513 
514 static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = {
515 		{  8, 512, 8, 1, 0, 1, 0, 0, 0},  /* 0 for invalid */
516 		{ 16, 256, 8, 2, 0, 1, 0, 0, 0},
517 		{ 32, 128, 8, 4, 0, 1, 0, 0, 0},
518 		{ 64,  64, 8, 4, 0, 1, 0, 0, 0}, /* fake */
519 };
520 
521 static const unsigned int dvmm_Hw_Setting_Linear[4][9] = {
522 		{  8, 4096, 1, 8, 0, 1, 0, 0, 0},
523 		{ 16, 2048, 1, 8, 0, 1, 0, 0, 0},
524 		{ 32, 1024, 1, 8, 0, 1, 0, 0, 0},
525 		{ 64,  512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */
526 };
527 
528 /* Helper to get table entry from surface info */
529 static const unsigned int *get_dvmm_hw_setting(
530 		union dc_tiling_info *tiling_info,
531 		enum surface_pixel_format format,
532 		bool chroma)
533 {
534 	enum bits_per_pixel {
535 		bpp_8 = 0,
536 		bpp_16,
537 		bpp_32,
538 		bpp_64
539 	} bpp;
540 
541 	if (format >= SURFACE_PIXEL_FORMAT_INVALID)
542 		bpp = bpp_32;
543 	else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
544 		bpp = chroma ? bpp_16 : bpp_8;
545 	else
546 		bpp = bpp_8;
547 
548 	switch (tiling_info->gfx8.array_mode) {
549 	case DC_ARRAY_1D_TILED_THIN1:
550 	case DC_ARRAY_1D_TILED_THICK:
551 	case DC_ARRAY_PRT_TILED_THIN1:
552 		return dvmm_Hw_Setting_1DTiling[bpp];
553 	case DC_ARRAY_2D_TILED_THIN1:
554 	case DC_ARRAY_2D_TILED_THICK:
555 	case DC_ARRAY_2D_TILED_X_THICK:
556 	case DC_ARRAY_PRT_2D_TILED_THIN1:
557 	case DC_ARRAY_PRT_2D_TILED_THICK:
558 		return dvmm_Hw_Setting_2DTiling[bpp];
559 	case DC_ARRAY_LINEAR_GENERAL:
560 	case DC_ARRAY_LINEAR_ALLIGNED:
561 		return dvmm_Hw_Setting_Linear[bpp];
562 	default:
563 		return dvmm_Hw_Setting_2DTiling[bpp];
564 	}
565 }
566 
567 static
568 void dce_mem_input_v_program_pte_vm(
569 		struct mem_input *mem_input,
570 		enum surface_pixel_format format,
571 		union dc_tiling_info *tiling_info,
572 		enum dc_rotation_angle rotation)
573 {
574 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
575 	const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false);
576 	const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true);
577 
578 	unsigned int page_width = 0;
579 	unsigned int page_height = 0;
580 	unsigned int page_width_chroma = 0;
581 	unsigned int page_height_chroma = 0;
582 	unsigned int temp_page_width = pte[1];
583 	unsigned int temp_page_height = pte[2];
584 	unsigned int min_pte_before_flip = 0;
585 	unsigned int min_pte_before_flip_chroma = 0;
586 	uint32_t value = 0;
587 
588 	while ((temp_page_width >>= 1) != 0)
589 		page_width++;
590 	while ((temp_page_height >>= 1) != 0)
591 		page_height++;
592 
593 	temp_page_width = pte_chroma[1];
594 	temp_page_height = pte_chroma[2];
595 	while ((temp_page_width >>= 1) != 0)
596 		page_width_chroma++;
597 	while ((temp_page_height >>= 1) != 0)
598 		page_height_chroma++;
599 
600 	switch (rotation) {
601 	case ROTATION_ANGLE_90:
602 	case ROTATION_ANGLE_270:
603 		min_pte_before_flip = pte[4];
604 		min_pte_before_flip_chroma = pte_chroma[4];
605 		break;
606 	default:
607 		min_pte_before_flip = pte[3];
608 		min_pte_before_flip_chroma = pte_chroma[3];
609 		break;
610 	}
611 
612 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT);
613 	/* TODO: un-hardcode requestlimit */
614 	set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L);
615 	set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C);
616 	dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value);
617 
618 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL);
619 	set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH);
620 	set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT);
621 	set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP);
622 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value);
623 
624 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL);
625 	set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK);
626 	set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING);
627 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value);
628 
629 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C);
630 	set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C);
631 	set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C);
632 	set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C);
633 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value);
634 
635 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C);
636 	set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C);
637 	set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C);
638 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value);
639 }
640 
641 static
642 void dce_mem_input_v_program_surface_config(
643 	struct mem_input *mem_input,
644 	enum surface_pixel_format format,
645 	union dc_tiling_info *tiling_info,
646 	union plane_size *plane_size,
647 	enum dc_rotation_angle rotation,
648 	struct dc_plane_dcc_param *dcc,
649 	bool horizotal_mirror)
650 {
651 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
652 
653 	enable(mem_input110);
654 	program_tiling(mem_input110, tiling_info, format);
655 	program_size_and_rotation(mem_input110, rotation, plane_size);
656 	program_pixel_format(mem_input110, format);
657 }
658 
659 static void program_urgency_watermark(
660 	const struct dc_context *ctx,
661 	const uint32_t urgency_addr,
662 	const uint32_t wm_addr,
663 	struct dce_watermarks marks_low,
664 	uint32_t total_dest_line_time_ns)
665 {
666 	/* register value */
667 	uint32_t urgency_cntl = 0;
668 	uint32_t wm_mask_cntl = 0;
669 
670 	/*Write mask to enable reading/writing of watermark set A*/
671 	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
672 	set_reg_field_value(wm_mask_cntl,
673 			1,
674 			DPGV0_WATERMARK_MASK_CONTROL,
675 			URGENCY_WATERMARK_MASK);
676 	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
677 
678 	urgency_cntl = dm_read_reg(ctx, urgency_addr);
679 
680 	set_reg_field_value(
681 		urgency_cntl,
682 		marks_low.a_mark,
683 		DPGV0_PIPE_URGENCY_CONTROL,
684 		URGENCY_LOW_WATERMARK);
685 
686 	set_reg_field_value(
687 		urgency_cntl,
688 		total_dest_line_time_ns,
689 		DPGV0_PIPE_URGENCY_CONTROL,
690 		URGENCY_HIGH_WATERMARK);
691 	dm_write_reg(ctx, urgency_addr, urgency_cntl);
692 
693 	/*Write mask to enable reading/writing of watermark set B*/
694 	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
695 	set_reg_field_value(wm_mask_cntl,
696 			2,
697 			DPGV0_WATERMARK_MASK_CONTROL,
698 			URGENCY_WATERMARK_MASK);
699 	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
700 
701 	urgency_cntl = dm_read_reg(ctx, urgency_addr);
702 
703 	set_reg_field_value(urgency_cntl,
704 		marks_low.b_mark,
705 		DPGV0_PIPE_URGENCY_CONTROL,
706 		URGENCY_LOW_WATERMARK);
707 
708 	set_reg_field_value(urgency_cntl,
709 		total_dest_line_time_ns,
710 		DPGV0_PIPE_URGENCY_CONTROL,
711 		URGENCY_HIGH_WATERMARK);
712 
713 	dm_write_reg(ctx, urgency_addr, urgency_cntl);
714 }
715 
716 static void program_urgency_watermark_l(
717 	const struct dc_context *ctx,
718 	struct dce_watermarks marks_low,
719 	uint32_t total_dest_line_time_ns)
720 {
721 	program_urgency_watermark(
722 		ctx,
723 		mmDPGV0_PIPE_URGENCY_CONTROL,
724 		mmDPGV0_WATERMARK_MASK_CONTROL,
725 		marks_low,
726 		total_dest_line_time_ns);
727 }
728 
729 static void program_urgency_watermark_c(
730 	const struct dc_context *ctx,
731 	struct dce_watermarks marks_low,
732 	uint32_t total_dest_line_time_ns)
733 {
734 	program_urgency_watermark(
735 		ctx,
736 		mmDPGV1_PIPE_URGENCY_CONTROL,
737 		mmDPGV1_WATERMARK_MASK_CONTROL,
738 		marks_low,
739 		total_dest_line_time_ns);
740 }
741 
742 static void program_stutter_watermark(
743 	const struct dc_context *ctx,
744 	const uint32_t stutter_addr,
745 	const uint32_t wm_addr,
746 	struct dce_watermarks marks)
747 {
748 	/* register value */
749 	uint32_t stutter_cntl = 0;
750 	uint32_t wm_mask_cntl = 0;
751 
752 	/*Write mask to enable reading/writing of watermark set A*/
753 
754 	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
755 	set_reg_field_value(wm_mask_cntl,
756 		1,
757 		DPGV0_WATERMARK_MASK_CONTROL,
758 		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
759 	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
760 
761 	stutter_cntl = dm_read_reg(ctx, stutter_addr);
762 
763 	if (ctx->dc->debug.disable_stutter) {
764 		set_reg_field_value(stutter_cntl,
765 			0,
766 			DPGV0_PIPE_STUTTER_CONTROL,
767 			STUTTER_ENABLE);
768 	} else {
769 		set_reg_field_value(stutter_cntl,
770 			1,
771 			DPGV0_PIPE_STUTTER_CONTROL,
772 			STUTTER_ENABLE);
773 	}
774 
775 	set_reg_field_value(stutter_cntl,
776 		1,
777 		DPGV0_PIPE_STUTTER_CONTROL,
778 		STUTTER_IGNORE_FBC);
779 
780 	/*Write watermark set A*/
781 	set_reg_field_value(stutter_cntl,
782 		marks.a_mark,
783 		DPGV0_PIPE_STUTTER_CONTROL,
784 		STUTTER_EXIT_SELF_REFRESH_WATERMARK);
785 	dm_write_reg(ctx, stutter_addr, stutter_cntl);
786 
787 	/*Write mask to enable reading/writing of watermark set B*/
788 	wm_mask_cntl = dm_read_reg(ctx, wm_addr);
789 	set_reg_field_value(wm_mask_cntl,
790 		2,
791 		DPGV0_WATERMARK_MASK_CONTROL,
792 		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
793 	dm_write_reg(ctx, wm_addr, wm_mask_cntl);
794 
795 	stutter_cntl = dm_read_reg(ctx, stutter_addr);
796 	/*Write watermark set B*/
797 	set_reg_field_value(stutter_cntl,
798 		marks.b_mark,
799 		DPGV0_PIPE_STUTTER_CONTROL,
800 		STUTTER_EXIT_SELF_REFRESH_WATERMARK);
801 	dm_write_reg(ctx, stutter_addr, stutter_cntl);
802 }
803 
804 static void program_stutter_watermark_l(
805 	const struct dc_context *ctx,
806 	struct dce_watermarks marks)
807 {
808 	program_stutter_watermark(ctx,
809 			mmDPGV0_PIPE_STUTTER_CONTROL,
810 			mmDPGV0_WATERMARK_MASK_CONTROL,
811 			marks);
812 }
813 
814 static void program_stutter_watermark_c(
815 	const struct dc_context *ctx,
816 	struct dce_watermarks marks)
817 {
818 	program_stutter_watermark(ctx,
819 			mmDPGV1_PIPE_STUTTER_CONTROL,
820 			mmDPGV1_WATERMARK_MASK_CONTROL,
821 			marks);
822 }
823 
824 static void program_nbp_watermark(
825 	const struct dc_context *ctx,
826 	const uint32_t wm_mask_ctrl_addr,
827 	const uint32_t nbp_pstate_ctrl_addr,
828 	struct dce_watermarks marks)
829 {
830 	uint32_t value;
831 
832 	/* Write mask to enable reading/writing of watermark set A */
833 
834 	value = dm_read_reg(ctx, wm_mask_ctrl_addr);
835 
836 	set_reg_field_value(
837 		value,
838 		1,
839 		DPGV0_WATERMARK_MASK_CONTROL,
840 		NB_PSTATE_CHANGE_WATERMARK_MASK);
841 	dm_write_reg(ctx, wm_mask_ctrl_addr, value);
842 
843 	value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
844 
845 	set_reg_field_value(
846 		value,
847 		1,
848 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
849 		NB_PSTATE_CHANGE_ENABLE);
850 	set_reg_field_value(
851 		value,
852 		1,
853 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
854 		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
855 	set_reg_field_value(
856 		value,
857 		1,
858 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
859 		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
860 	dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
861 
862 	/* Write watermark set A */
863 	value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
864 	set_reg_field_value(
865 		value,
866 		marks.a_mark,
867 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
868 		NB_PSTATE_CHANGE_WATERMARK);
869 	dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
870 
871 	/* Write mask to enable reading/writing of watermark set B */
872 	value = dm_read_reg(ctx, wm_mask_ctrl_addr);
873 	set_reg_field_value(
874 		value,
875 		2,
876 		DPGV0_WATERMARK_MASK_CONTROL,
877 		NB_PSTATE_CHANGE_WATERMARK_MASK);
878 	dm_write_reg(ctx, wm_mask_ctrl_addr, value);
879 
880 	value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
881 	set_reg_field_value(
882 		value,
883 		1,
884 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
885 		NB_PSTATE_CHANGE_ENABLE);
886 	set_reg_field_value(
887 		value,
888 		1,
889 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
890 		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
891 	set_reg_field_value(
892 		value,
893 		1,
894 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
895 		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
896 	dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
897 
898 	/* Write watermark set B */
899 	value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
900 	set_reg_field_value(
901 		value,
902 		marks.b_mark,
903 		DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
904 		NB_PSTATE_CHANGE_WATERMARK);
905 	dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
906 }
907 
908 static void program_nbp_watermark_l(
909 	const struct dc_context *ctx,
910 	struct dce_watermarks marks)
911 {
912 	program_nbp_watermark(ctx,
913 			mmDPGV0_WATERMARK_MASK_CONTROL,
914 			mmDPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
915 			marks);
916 }
917 
918 static void program_nbp_watermark_c(
919 	const struct dc_context *ctx,
920 	struct dce_watermarks marks)
921 {
922 	program_nbp_watermark(ctx,
923 			mmDPGV1_WATERMARK_MASK_CONTROL,
924 			mmDPGV1_PIPE_NB_PSTATE_CHANGE_CONTROL,
925 			marks);
926 }
927 
928 static
929 void dce_mem_input_v_program_display_marks(
930 	struct mem_input *mem_input,
931 	struct dce_watermarks nbp,
932 	struct dce_watermarks stutter,
933 	struct dce_watermarks stutter_enter,
934 	struct dce_watermarks urgent,
935 	uint32_t total_dest_line_time_ns)
936 {
937 	program_urgency_watermark_l(
938 		mem_input->ctx,
939 		urgent,
940 		total_dest_line_time_ns);
941 
942 	program_nbp_watermark_l(
943 		mem_input->ctx,
944 		nbp);
945 
946 	program_stutter_watermark_l(
947 		mem_input->ctx,
948 		stutter);
949 
950 }
951 
952 static
953 void dce_mem_input_program_chroma_display_marks(
954 	struct mem_input *mem_input,
955 	struct dce_watermarks nbp,
956 	struct dce_watermarks stutter,
957 	struct dce_watermarks urgent,
958 	uint32_t total_dest_line_time_ns)
959 {
960 	program_urgency_watermark_c(
961 		mem_input->ctx,
962 		urgent,
963 		total_dest_line_time_ns);
964 
965 	program_nbp_watermark_c(
966 		mem_input->ctx,
967 		nbp);
968 
969 	program_stutter_watermark_c(
970 		mem_input->ctx,
971 		stutter);
972 }
973 
974 static
975 void dce110_allocate_mem_input_v(
976 	struct mem_input *mi,
977 	uint32_t h_total,/* for current stream */
978 	uint32_t v_total,/* for current stream */
979 	uint32_t pix_clk_khz,/* for current stream */
980 	uint32_t total_stream_num)
981 {
982 	uint32_t addr;
983 	uint32_t value;
984 	uint32_t pix_dur;
985 	if (pix_clk_khz != 0) {
986 		addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1;
987 		value = dm_read_reg(mi->ctx, addr);
988 		pix_dur = 1000000000ULL / pix_clk_khz;
989 		set_reg_field_value(
990 			value,
991 			pix_dur,
992 			DPGV0_PIPE_ARBITRATION_CONTROL1,
993 			PIXEL_DURATION);
994 		dm_write_reg(mi->ctx, addr, value);
995 
996 		addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1;
997 		value = dm_read_reg(mi->ctx, addr);
998 		pix_dur = 1000000000ULL / pix_clk_khz;
999 		set_reg_field_value(
1000 			value,
1001 			pix_dur,
1002 			DPGV1_PIPE_ARBITRATION_CONTROL1,
1003 			PIXEL_DURATION);
1004 		dm_write_reg(mi->ctx, addr, value);
1005 
1006 		addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2;
1007 		value = 0x4000800;
1008 		dm_write_reg(mi->ctx, addr, value);
1009 
1010 		addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2;
1011 		value = 0x4000800;
1012 		dm_write_reg(mi->ctx, addr, value);
1013 	}
1014 
1015 }
1016 
1017 static
1018 void dce110_free_mem_input_v(
1019 	struct mem_input *mi,
1020 	uint32_t total_stream_num)
1021 {
1022 }
1023 
1024 static const struct mem_input_funcs dce110_mem_input_v_funcs = {
1025 	.mem_input_program_display_marks =
1026 			dce_mem_input_v_program_display_marks,
1027 	.mem_input_program_chroma_display_marks =
1028 			dce_mem_input_program_chroma_display_marks,
1029 	.allocate_mem_input = dce110_allocate_mem_input_v,
1030 	.free_mem_input = dce110_free_mem_input_v,
1031 	.mem_input_program_surface_flip_and_addr =
1032 			dce_mem_input_v_program_surface_flip_and_addr,
1033 	.mem_input_program_pte_vm =
1034 			dce_mem_input_v_program_pte_vm,
1035 	.mem_input_program_surface_config =
1036 			dce_mem_input_v_program_surface_config,
1037 	.mem_input_is_flip_pending =
1038 			dce_mem_input_v_is_surface_pending
1039 };
1040 /*****************************************/
1041 /* Constructor, Destructor               */
1042 /*****************************************/
1043 
1044 void dce110_mem_input_v_construct(
1045 	struct dce_mem_input *dce_mi,
1046 	struct dc_context *ctx)
1047 {
1048 	dce_mi->base.funcs = &dce110_mem_input_v_funcs;
1049 	dce_mi->base.ctx = ctx;
1050 }
1051 
1052