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