xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/amd/display/dc/dce110/amdgpu_dce110_mem_input_v.c (revision 6bda0fa7ce4700926b57d0328f147ac8a0ca147e)
1 /*	$NetBSD: amdgpu_dce110_mem_input_v.c,v 1.4 2021/12/19 10:59:37 riastradh Exp $	*/
2 
3 /*
4  * Copyright 2012-16 Advanced Micro Devices, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: AMD
25  *
26  */
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: amdgpu_dce110_mem_input_v.c,v 1.4 2021/12/19 10:59:37 riastradh Exp $");
29 
30 #include "dm_services.h"
31 
32 #include "dce/dce_11_0_d.h"
33 #include "dce/dce_11_0_sh_mask.h"
34 /* TODO: this needs to be looked at, used by Stella's workaround*/
35 #include "gmc/gmc_8_2_d.h"
36 #include "gmc/gmc_8_2_sh_mask.h"
37 
38 #include "include/logger_interface.h"
39 #include "inc/dce_calcs.h"
40 
41 #include "dce/dce_mem_input.h"
42 #include "dce110/dce110_mem_input_v.h"
43 
set_flip_control(struct dce_mem_input * mem_input110,bool immediate)44 static void set_flip_control(
45 	struct dce_mem_input *mem_input110,
46 	bool immediate)
47 {
48 	uint32_t value = 0;
49 
50 	value = dm_read_reg(
51 			mem_input110->base.ctx,
52 			mmUNP_FLIP_CONTROL);
53 
54 	set_reg_field_value(value, 1,
55 			UNP_FLIP_CONTROL,
56 			GRPH_SURFACE_UPDATE_PENDING_MODE);
57 
58 	dm_write_reg(
59 			mem_input110->base.ctx,
60 			mmUNP_FLIP_CONTROL,
61 			value);
62 }
63 
64 /* chroma part */
program_pri_addr_c(struct dce_mem_input * mem_input110,PHYSICAL_ADDRESS_LOC address)65 static void program_pri_addr_c(
66 	struct dce_mem_input *mem_input110,
67 	PHYSICAL_ADDRESS_LOC address)
68 {
69 	uint32_t value = 0;
70 	uint32_t temp = 0;
71 	/*high register MUST be programmed first*/
72 	temp = address.high_part &
73 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK;
74 
75 	set_reg_field_value(value, temp,
76 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
77 		GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C);
78 
79 	dm_write_reg(
80 		mem_input110->base.ctx,
81 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
82 		value);
83 
84 	temp = 0;
85 	value = 0;
86 	temp = address.low_part >>
87 	UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT;
88 
89 	set_reg_field_value(value, temp,
90 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
91 		GRPH_PRIMARY_SURFACE_ADDRESS_C);
92 
93 	dm_write_reg(
94 		mem_input110->base.ctx,
95 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
96 		value);
97 }
98 
99 /* luma part */
program_pri_addr_l(struct dce_mem_input * mem_input110,PHYSICAL_ADDRESS_LOC address)100 static void program_pri_addr_l(
101 	struct dce_mem_input *mem_input110,
102 	PHYSICAL_ADDRESS_LOC address)
103 {
104 	uint32_t value = 0;
105 	uint32_t temp = 0;
106 
107 	/*high register MUST be programmed first*/
108 	temp = address.high_part &
109 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK;
110 
111 	set_reg_field_value(value, temp,
112 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
113 		GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L);
114 
115 	dm_write_reg(
116 		mem_input110->base.ctx,
117 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
118 		value);
119 
120 	temp = 0;
121 	value = 0;
122 	temp = address.low_part >>
123 	UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT;
124 
125 	set_reg_field_value(value, temp,
126 		UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
127 		GRPH_PRIMARY_SURFACE_ADDRESS_L);
128 
129 	dm_write_reg(
130 		mem_input110->base.ctx,
131 		mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
132 		value);
133 }
134 
program_addr(struct dce_mem_input * mem_input110,const struct dc_plane_address * addr)135 static void program_addr(
136 	struct dce_mem_input *mem_input110,
137 	const struct dc_plane_address *addr)
138 {
139 	switch (addr->type) {
140 	case PLN_ADDR_TYPE_GRAPHICS:
141 		program_pri_addr_l(
142 			mem_input110,
143 			addr->grph.addr);
144 		break;
145 	case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
146 		program_pri_addr_c(
147 			mem_input110,
148 			addr->video_progressive.chroma_addr);
149 		program_pri_addr_l(
150 			mem_input110,
151 			addr->video_progressive.luma_addr);
152 		break;
153 	default:
154 		/* not supported */
155 		BREAK_TO_DEBUGGER();
156 	}
157 }
158 
enable(struct dce_mem_input * mem_input110)159 static void enable(struct dce_mem_input *mem_input110)
160 {
161 	uint32_t value = 0;
162 
163 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE);
164 	set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE);
165 	dm_write_reg(mem_input110->base.ctx,
166 		mmUNP_GRPH_ENABLE,
167 		value);
168 }
169 
program_tiling(struct dce_mem_input * mem_input110,const union dc_tiling_info * info,const enum surface_pixel_format pixel_format)170 static void program_tiling(
171 	struct dce_mem_input *mem_input110,
172 	const union dc_tiling_info *info,
173 	const enum surface_pixel_format pixel_format)
174 {
175 	uint32_t value = 0;
176 
177 	set_reg_field_value(value, info->gfx8.num_banks,
178 		UNP_GRPH_CONTROL, GRPH_NUM_BANKS);
179 
180 	set_reg_field_value(value, info->gfx8.bank_width,
181 		UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L);
182 
183 	set_reg_field_value(value, info->gfx8.bank_height,
184 		UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L);
185 
186 	set_reg_field_value(value, info->gfx8.tile_aspect,
187 		UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L);
188 
189 	set_reg_field_value(value, info->gfx8.tile_split,
190 		UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L);
191 
192 	set_reg_field_value(value, info->gfx8.tile_mode,
193 		UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L);
194 
195 	set_reg_field_value(value, info->gfx8.pipe_config,
196 		UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG);
197 
198 	set_reg_field_value(value, info->gfx8.array_mode,
199 		UNP_GRPH_CONTROL, GRPH_ARRAY_MODE);
200 
201 	set_reg_field_value(value, 1,
202 		UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
203 
204 	set_reg_field_value(value, 0,
205 		UNP_GRPH_CONTROL, GRPH_Z);
206 
207 	dm_write_reg(
208 		mem_input110->base.ctx,
209 		mmUNP_GRPH_CONTROL,
210 		value);
211 
212 	value = 0;
213 
214 	set_reg_field_value(value, info->gfx8.bank_width_c,
215 		UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C);
216 
217 	set_reg_field_value(value, info->gfx8.bank_height_c,
218 		UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C);
219 
220 	set_reg_field_value(value, info->gfx8.tile_aspect_c,
221 		UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C);
222 
223 	set_reg_field_value(value, info->gfx8.tile_split_c,
224 		UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C);
225 
226 	set_reg_field_value(value, info->gfx8.tile_mode_c,
227 		UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C);
228 
229 	dm_write_reg(
230 		mem_input110->base.ctx,
231 		mmUNP_GRPH_CONTROL_C,
232 		value);
233 }
234 
program_size_and_rotation(struct dce_mem_input * mem_input110,enum dc_rotation_angle rotation,const struct plane_size * plane_size)235 static void program_size_and_rotation(
236 	struct dce_mem_input *mem_input110,
237 	enum dc_rotation_angle rotation,
238 	const struct plane_size *plane_size)
239 {
240 	uint32_t value = 0;
241 	struct plane_size local_size = *plane_size;
242 
243 	if (rotation == ROTATION_ANGLE_90 ||
244 		rotation == ROTATION_ANGLE_270) {
245 
246 		swap(local_size.surface_size.x,
247 		     local_size.surface_size.y);
248 		swap(local_size.surface_size.width,
249 		     local_size.surface_size.height);
250 		swap(local_size.chroma_size.x,
251 		     local_size.chroma_size.y);
252 		swap(local_size.chroma_size.width,
253 		     local_size.chroma_size.height);
254 	}
255 
256 	value = 0;
257 	set_reg_field_value(value, local_size.surface_pitch,
258 			UNP_GRPH_PITCH_L, GRPH_PITCH_L);
259 
260 	dm_write_reg(
261 		mem_input110->base.ctx,
262 		mmUNP_GRPH_PITCH_L,
263 		value);
264 
265 	value = 0;
266 	set_reg_field_value(value, local_size.chroma_pitch,
267 			UNP_GRPH_PITCH_C, GRPH_PITCH_C);
268 	dm_write_reg(
269 		mem_input110->base.ctx,
270 		mmUNP_GRPH_PITCH_C,
271 		value);
272 
273 	value = 0;
274 	set_reg_field_value(value, 0,
275 			UNP_GRPH_X_START_L, GRPH_X_START_L);
276 	dm_write_reg(
277 		mem_input110->base.ctx,
278 		mmUNP_GRPH_X_START_L,
279 		value);
280 
281 	value = 0;
282 	set_reg_field_value(value, 0,
283 			UNP_GRPH_X_START_C, GRPH_X_START_C);
284 	dm_write_reg(
285 		mem_input110->base.ctx,
286 		mmUNP_GRPH_X_START_C,
287 		value);
288 
289 	value = 0;
290 	set_reg_field_value(value, 0,
291 			UNP_GRPH_Y_START_L, GRPH_Y_START_L);
292 	dm_write_reg(
293 		mem_input110->base.ctx,
294 		mmUNP_GRPH_Y_START_L,
295 		value);
296 
297 	value = 0;
298 	set_reg_field_value(value, 0,
299 			UNP_GRPH_Y_START_C, GRPH_Y_START_C);
300 	dm_write_reg(
301 		mem_input110->base.ctx,
302 		mmUNP_GRPH_Y_START_C,
303 		value);
304 
305 	value = 0;
306 	set_reg_field_value(value, local_size.surface_size.x +
307 			local_size.surface_size.width,
308 			UNP_GRPH_X_END_L, GRPH_X_END_L);
309 	dm_write_reg(
310 		mem_input110->base.ctx,
311 		mmUNP_GRPH_X_END_L,
312 		value);
313 
314 	value = 0;
315 	set_reg_field_value(value, local_size.chroma_size.x +
316 			local_size.chroma_size.width,
317 			UNP_GRPH_X_END_C, GRPH_X_END_C);
318 	dm_write_reg(
319 		mem_input110->base.ctx,
320 		mmUNP_GRPH_X_END_C,
321 		value);
322 
323 	value = 0;
324 	set_reg_field_value(value, local_size.surface_size.y +
325 			local_size.surface_size.height,
326 			UNP_GRPH_Y_END_L, GRPH_Y_END_L);
327 	dm_write_reg(
328 		mem_input110->base.ctx,
329 		mmUNP_GRPH_Y_END_L,
330 		value);
331 
332 	value = 0;
333 	set_reg_field_value(value, local_size.chroma_size.y +
334 			local_size.chroma_size.height,
335 			UNP_GRPH_Y_END_C, GRPH_Y_END_C);
336 	dm_write_reg(
337 		mem_input110->base.ctx,
338 		mmUNP_GRPH_Y_END_C,
339 		value);
340 
341 	value = 0;
342 	switch (rotation) {
343 	case ROTATION_ANGLE_90:
344 		set_reg_field_value(value, 3,
345 			UNP_HW_ROTATION, ROTATION_ANGLE);
346 		break;
347 	case ROTATION_ANGLE_180:
348 		set_reg_field_value(value, 2,
349 			UNP_HW_ROTATION, ROTATION_ANGLE);
350 		break;
351 	case ROTATION_ANGLE_270:
352 		set_reg_field_value(value, 1,
353 			UNP_HW_ROTATION, ROTATION_ANGLE);
354 		break;
355 	default:
356 		set_reg_field_value(value, 0,
357 			UNP_HW_ROTATION, ROTATION_ANGLE);
358 		break;
359 	}
360 
361 	dm_write_reg(
362 		mem_input110->base.ctx,
363 		mmUNP_HW_ROTATION,
364 		value);
365 }
366 
program_pixel_format(struct dce_mem_input * mem_input110,enum surface_pixel_format format)367 static void program_pixel_format(
368 	struct dce_mem_input *mem_input110,
369 	enum surface_pixel_format format)
370 {
371 	if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
372 		uint32_t value;
373 		uint8_t grph_depth;
374 		uint8_t grph_format;
375 
376 		value =	dm_read_reg(
377 				mem_input110->base.ctx,
378 				mmUNP_GRPH_CONTROL);
379 
380 		switch (format) {
381 		case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
382 			grph_depth = 0;
383 			grph_format = 0;
384 			break;
385 		case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
386 			grph_depth = 1;
387 			grph_format = 1;
388 			break;
389 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
390 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
391 			grph_depth = 2;
392 			grph_format = 0;
393 			break;
394 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
395 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
396 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
397 			grph_depth = 2;
398 			grph_format = 1;
399 			break;
400 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
401 		case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
402 		case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
403 			grph_depth = 3;
404 			grph_format = 0;
405 			break;
406 		default:
407 			grph_depth = 2;
408 			grph_format = 0;
409 			break;
410 		}
411 
412 		set_reg_field_value(
413 				value,
414 				grph_depth,
415 				UNP_GRPH_CONTROL,
416 				GRPH_DEPTH);
417 		set_reg_field_value(
418 				value,
419 				grph_format,
420 				UNP_GRPH_CONTROL,
421 				GRPH_FORMAT);
422 
423 		dm_write_reg(
424 				mem_input110->base.ctx,
425 				mmUNP_GRPH_CONTROL,
426 				value);
427 
428 		value =	dm_read_reg(
429 				mem_input110->base.ctx,
430 				mmUNP_GRPH_CONTROL_EXP);
431 
432 		/* VIDEO FORMAT 0 */
433 		set_reg_field_value(
434 				value,
435 				0,
436 				UNP_GRPH_CONTROL_EXP,
437 				VIDEO_FORMAT);
438 		dm_write_reg(
439 				mem_input110->base.ctx,
440 				mmUNP_GRPH_CONTROL_EXP,
441 				value);
442 
443 	} else {
444 		/* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */
445 		uint32_t value;
446 		uint8_t video_format;
447 
448 		value =	dm_read_reg(
449 				mem_input110->base.ctx,
450 				mmUNP_GRPH_CONTROL_EXP);
451 
452 		switch (format) {
453 		case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
454 			video_format = 2;
455 			break;
456 		case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
457 			video_format = 3;
458 			break;
459 		default:
460 			video_format = 0;
461 			break;
462 		}
463 
464 		set_reg_field_value(
465 			value,
466 			video_format,
467 			UNP_GRPH_CONTROL_EXP,
468 			VIDEO_FORMAT);
469 
470 		dm_write_reg(
471 			mem_input110->base.ctx,
472 			mmUNP_GRPH_CONTROL_EXP,
473 			value);
474 	}
475 }
476 
dce_mem_input_v_is_surface_pending(struct mem_input * mem_input)477 bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input)
478 {
479 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
480 	uint32_t value;
481 
482 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE);
483 
484 	if (get_reg_field_value(value, UNP_GRPH_UPDATE,
485 			GRPH_SURFACE_UPDATE_PENDING))
486 		return true;
487 
488 	mem_input->current_address = mem_input->request_address;
489 	return false;
490 }
491 
dce_mem_input_v_program_surface_flip_and_addr(struct mem_input * mem_input,const struct dc_plane_address * address,bool flip_immediate)492 bool dce_mem_input_v_program_surface_flip_and_addr(
493 	struct mem_input *mem_input,
494 	const struct dc_plane_address *address,
495 	bool flip_immediate)
496 {
497 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
498 
499 	set_flip_control(mem_input110, flip_immediate);
500 	program_addr(mem_input110,
501 		address);
502 
503 	mem_input->request_address = *address;
504 
505 	return true;
506 }
507 
508 /* Scatter Gather param tables */
509 static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = {
510 		{  8, 64, 64,  8,  8, 1, 4, 0, 0},
511 		{ 16, 64, 32,  8, 16, 1, 8, 0, 0},
512 		{ 32, 32, 32, 16, 16, 1, 8, 0, 0},
513 		{ 64,  8, 32, 16, 16, 1, 8, 0, 0}, /* fake */
514 };
515 
516 static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = {
517 		{  8, 512, 8, 1, 0, 1, 0, 0, 0},  /* 0 for invalid */
518 		{ 16, 256, 8, 2, 0, 1, 0, 0, 0},
519 		{ 32, 128, 8, 4, 0, 1, 0, 0, 0},
520 		{ 64,  64, 8, 4, 0, 1, 0, 0, 0}, /* fake */
521 };
522 
523 static const unsigned int dvmm_Hw_Setting_Linear[4][9] = {
524 		{  8, 4096, 1, 8, 0, 1, 0, 0, 0},
525 		{ 16, 2048, 1, 8, 0, 1, 0, 0, 0},
526 		{ 32, 1024, 1, 8, 0, 1, 0, 0, 0},
527 		{ 64,  512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */
528 };
529 
530 /* 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)531 static const unsigned int *get_dvmm_hw_setting(
532 		union dc_tiling_info *tiling_info,
533 		enum surface_pixel_format format,
534 		bool chroma)
535 {
536 	enum bits_per_pixel {
537 		bpp_8 = 0,
538 		bpp_16,
539 		bpp_32,
540 		bpp_64
541 	} bpp;
542 
543 	if (format >= SURFACE_PIXEL_FORMAT_INVALID)
544 		bpp = bpp_32;
545 	else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
546 		bpp = chroma ? bpp_16 : bpp_8;
547 	else
548 		bpp = bpp_8;
549 
550 	switch (tiling_info->gfx8.array_mode) {
551 	case DC_ARRAY_1D_TILED_THIN1:
552 	case DC_ARRAY_1D_TILED_THICK:
553 	case DC_ARRAY_PRT_TILED_THIN1:
554 		return dvmm_Hw_Setting_1DTiling[bpp];
555 	case DC_ARRAY_2D_TILED_THIN1:
556 	case DC_ARRAY_2D_TILED_THICK:
557 	case DC_ARRAY_2D_TILED_X_THICK:
558 	case DC_ARRAY_PRT_2D_TILED_THIN1:
559 	case DC_ARRAY_PRT_2D_TILED_THICK:
560 		return dvmm_Hw_Setting_2DTiling[bpp];
561 	case DC_ARRAY_LINEAR_GENERAL:
562 	case DC_ARRAY_LINEAR_ALLIGNED:
563 		return dvmm_Hw_Setting_Linear[bpp];
564 	default:
565 		return dvmm_Hw_Setting_2DTiling[bpp];
566 	}
567 }
568 
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)569 void dce_mem_input_v_program_pte_vm(
570 		struct mem_input *mem_input,
571 		enum surface_pixel_format format,
572 		union dc_tiling_info *tiling_info,
573 		enum dc_rotation_angle rotation)
574 {
575 	struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
576 	const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false);
577 	const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true);
578 
579 	unsigned int page_width = 0;
580 	unsigned int page_height = 0;
581 	unsigned int page_width_chroma = 0;
582 	unsigned int page_height_chroma = 0;
583 	unsigned int temp_page_width = pte[1];
584 	unsigned int temp_page_height = pte[2];
585 	unsigned int min_pte_before_flip = 0;
586 	unsigned int min_pte_before_flip_chroma = 0;
587 	uint32_t value = 0;
588 
589 	while ((temp_page_width >>= 1) != 0)
590 		page_width++;
591 	while ((temp_page_height >>= 1) != 0)
592 		page_height++;
593 
594 	temp_page_width = pte_chroma[1];
595 	temp_page_height = pte_chroma[2];
596 	while ((temp_page_width >>= 1) != 0)
597 		page_width_chroma++;
598 	while ((temp_page_height >>= 1) != 0)
599 		page_height_chroma++;
600 
601 	switch (rotation) {
602 	case ROTATION_ANGLE_90:
603 	case ROTATION_ANGLE_270:
604 		min_pte_before_flip = pte[4];
605 		min_pte_before_flip_chroma = pte_chroma[4];
606 		break;
607 	default:
608 		min_pte_before_flip = pte[3];
609 		min_pte_before_flip_chroma = pte_chroma[3];
610 		break;
611 	}
612 
613 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT);
614 	/* TODO: un-hardcode requestlimit */
615 	set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L);
616 	set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C);
617 	dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value);
618 
619 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL);
620 	set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH);
621 	set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT);
622 	set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP);
623 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value);
624 
625 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL);
626 	set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK);
627 	set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING);
628 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value);
629 
630 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C);
631 	set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C);
632 	set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C);
633 	set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C);
634 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value);
635 
636 	value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C);
637 	set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C);
638 	set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C);
639 	dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value);
640 }
641 
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)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 	struct 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 
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)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 
program_urgency_watermark_l(const struct dc_context * ctx,struct dce_watermarks marks_low,uint32_t total_dest_line_time_ns)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 
program_urgency_watermark_c(const struct dc_context * ctx,struct dce_watermarks marks_low,uint32_t total_dest_line_time_ns)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 
program_stutter_watermark(const struct dc_context * ctx,const uint32_t stutter_addr,const uint32_t wm_addr,struct dce_watermarks marks)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 
program_stutter_watermark_l(const struct dc_context * ctx,struct dce_watermarks marks)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 
program_stutter_watermark_c(const struct dc_context * ctx,struct dce_watermarks marks)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 
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)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 
program_nbp_watermark_l(const struct dc_context * ctx,struct dce_watermarks marks)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 
program_nbp_watermark_c(const struct dc_context * ctx,struct dce_watermarks marks)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 
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)928 void dce_mem_input_v_program_display_marks(
929 	struct mem_input *mem_input,
930 	struct dce_watermarks nbp,
931 	struct dce_watermarks stutter,
932 	struct dce_watermarks stutter_enter,
933 	struct dce_watermarks urgent,
934 	uint32_t total_dest_line_time_ns)
935 {
936 	program_urgency_watermark_l(
937 		mem_input->ctx,
938 		urgent,
939 		total_dest_line_time_ns);
940 
941 	program_nbp_watermark_l(
942 		mem_input->ctx,
943 		nbp);
944 
945 	program_stutter_watermark_l(
946 		mem_input->ctx,
947 		stutter);
948 
949 }
950 
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)951 void dce_mem_input_program_chroma_display_marks(
952 	struct mem_input *mem_input,
953 	struct dce_watermarks nbp,
954 	struct dce_watermarks stutter,
955 	struct dce_watermarks urgent,
956 	uint32_t total_dest_line_time_ns)
957 {
958 	program_urgency_watermark_c(
959 		mem_input->ctx,
960 		urgent,
961 		total_dest_line_time_ns);
962 
963 	program_nbp_watermark_c(
964 		mem_input->ctx,
965 		nbp);
966 
967 	program_stutter_watermark_c(
968 		mem_input->ctx,
969 		stutter);
970 }
971 
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)972 void dce110_allocate_mem_input_v(
973 	struct mem_input *mi,
974 	uint32_t h_total,/* for current stream */
975 	uint32_t v_total,/* for current stream */
976 	uint32_t pix_clk_khz,/* for current stream */
977 	uint32_t total_stream_num)
978 {
979 	uint32_t addr;
980 	uint32_t value;
981 	uint32_t pix_dur;
982 	if (pix_clk_khz != 0) {
983 		addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1;
984 		value = dm_read_reg(mi->ctx, addr);
985 		pix_dur = 1000000000ULL / pix_clk_khz;
986 		set_reg_field_value(
987 			value,
988 			pix_dur,
989 			DPGV0_PIPE_ARBITRATION_CONTROL1,
990 			PIXEL_DURATION);
991 		dm_write_reg(mi->ctx, addr, value);
992 
993 		addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1;
994 		value = dm_read_reg(mi->ctx, addr);
995 		pix_dur = 1000000000ULL / pix_clk_khz;
996 		set_reg_field_value(
997 			value,
998 			pix_dur,
999 			DPGV1_PIPE_ARBITRATION_CONTROL1,
1000 			PIXEL_DURATION);
1001 		dm_write_reg(mi->ctx, addr, value);
1002 
1003 		addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2;
1004 		value = 0x4000800;
1005 		dm_write_reg(mi->ctx, addr, value);
1006 
1007 		addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2;
1008 		value = 0x4000800;
1009 		dm_write_reg(mi->ctx, addr, value);
1010 	}
1011 
1012 }
1013 
dce110_free_mem_input_v(struct mem_input * mi,uint32_t total_stream_num)1014 void dce110_free_mem_input_v(
1015 	struct mem_input *mi,
1016 	uint32_t total_stream_num)
1017 {
1018 }
1019 
1020 static const struct mem_input_funcs dce110_mem_input_v_funcs = {
1021 	.mem_input_program_display_marks =
1022 			dce_mem_input_v_program_display_marks,
1023 	.mem_input_program_chroma_display_marks =
1024 			dce_mem_input_program_chroma_display_marks,
1025 	.allocate_mem_input = dce110_allocate_mem_input_v,
1026 	.free_mem_input = dce110_free_mem_input_v,
1027 	.mem_input_program_surface_flip_and_addr =
1028 			dce_mem_input_v_program_surface_flip_and_addr,
1029 	.mem_input_program_pte_vm =
1030 			dce_mem_input_v_program_pte_vm,
1031 	.mem_input_program_surface_config =
1032 			dce_mem_input_v_program_surface_config,
1033 	.mem_input_is_flip_pending =
1034 			dce_mem_input_v_is_surface_pending
1035 };
1036 /*****************************************/
1037 /* Constructor, Destructor               */
1038 /*****************************************/
1039 
dce110_mem_input_v_construct(struct dce_mem_input * dce_mi,struct dc_context * ctx)1040 void dce110_mem_input_v_construct(
1041 	struct dce_mem_input *dce_mi,
1042 	struct dc_context *ctx)
1043 {
1044 	dce_mi->base.funcs = &dce110_mem_input_v_funcs;
1045 	dce_mi->base.ctx = ctx;
1046 }
1047 
1048