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