1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include "dce_mem_input.h"
27 #include "reg_helper.h"
28 #include "basics/conversion.h"
29 
30 #define CTX \
31 	dce_mi->base.ctx
32 #define REG(reg)\
33 	dce_mi->regs->reg
34 
35 #undef FN
36 #define FN(reg_name, field_name) \
37 	dce_mi->shifts->field_name, dce_mi->masks->field_name
38 
39 struct pte_setting {
40 	unsigned int bpp;
41 	unsigned int page_width;
42 	unsigned int page_height;
43 	unsigned char min_pte_before_flip_horiz_scan;
44 	unsigned char min_pte_before_flip_vert_scan;
45 	unsigned char pte_req_per_chunk;
46 	unsigned char param_6;
47 	unsigned char param_7;
48 	unsigned char param_8;
49 };
50 
51 enum mi_bits_per_pixel {
52 	mi_bpp_8 = 0,
53 	mi_bpp_16,
54 	mi_bpp_32,
55 	mi_bpp_64,
56 	mi_bpp_count,
57 };
58 
59 enum mi_tiling_format {
60 	mi_tiling_linear = 0,
61 	mi_tiling_1D,
62 	mi_tiling_2D,
63 	mi_tiling_count,
64 };
65 
66 static const struct pte_setting pte_settings[mi_tiling_count][mi_bpp_count] = {
67 	[mi_tiling_linear] = {
68 		{  8, 4096, 1, 8, 0, 1, 0, 0, 0},
69 		{ 16, 2048, 1, 8, 0, 1, 0, 0, 0},
70 		{ 32, 1024, 1, 8, 0, 1, 0, 0, 0},
71 		{ 64,  512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */
72 	},
73 	[mi_tiling_1D] = {
74 		{  8, 512, 8, 1, 0, 1, 0, 0, 0},  /* 0 for invalid */
75 		{ 16, 256, 8, 2, 0, 1, 0, 0, 0},
76 		{ 32, 128, 8, 4, 0, 1, 0, 0, 0},
77 		{ 64,  64, 8, 4, 0, 1, 0, 0, 0}, /* fake */
78 	},
79 	[mi_tiling_2D] = {
80 		{  8, 64, 64,  8,  8, 1, 4, 0, 0},
81 		{ 16, 64, 32,  8, 16, 1, 8, 0, 0},
82 		{ 32, 32, 32, 16, 16, 1, 8, 0, 0},
83 		{ 64,  8, 32, 16, 16, 1, 8, 0, 0}, /* fake */
84 	},
85 };
86 
87 static enum mi_bits_per_pixel get_mi_bpp(
88 		enum surface_pixel_format format)
89 {
90 	if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616)
91 		return mi_bpp_64;
92 	else if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888)
93 		return mi_bpp_32;
94 	else if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB1555)
95 		return mi_bpp_16;
96 	else
97 		return mi_bpp_8;
98 }
99 
100 static enum mi_tiling_format get_mi_tiling(
101 		union dc_tiling_info *tiling_info)
102 {
103 	switch (tiling_info->gfx8.array_mode) {
104 	case DC_ARRAY_1D_TILED_THIN1:
105 	case DC_ARRAY_1D_TILED_THICK:
106 	case DC_ARRAY_PRT_TILED_THIN1:
107 		return mi_tiling_1D;
108 	case DC_ARRAY_2D_TILED_THIN1:
109 	case DC_ARRAY_2D_TILED_THICK:
110 	case DC_ARRAY_2D_TILED_X_THICK:
111 	case DC_ARRAY_PRT_2D_TILED_THIN1:
112 	case DC_ARRAY_PRT_2D_TILED_THICK:
113 		return mi_tiling_2D;
114 	case DC_ARRAY_LINEAR_GENERAL:
115 	case DC_ARRAY_LINEAR_ALLIGNED:
116 		return mi_tiling_linear;
117 	default:
118 		return mi_tiling_2D;
119 	}
120 }
121 
122 static bool is_vert_scan(enum dc_rotation_angle rotation)
123 {
124 	switch (rotation) {
125 	case ROTATION_ANGLE_90:
126 	case ROTATION_ANGLE_270:
127 		return true;
128 	default:
129 		return false;
130 	}
131 }
132 
133 static void dce_mi_program_pte_vm(
134 		struct mem_input *mi,
135 		enum surface_pixel_format format,
136 		union dc_tiling_info *tiling_info,
137 		enum dc_rotation_angle rotation)
138 {
139 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
140 	enum mi_bits_per_pixel mi_bpp = get_mi_bpp(format);
141 	enum mi_tiling_format mi_tiling = get_mi_tiling(tiling_info);
142 	const struct pte_setting *pte = &pte_settings[mi_tiling][mi_bpp];
143 
144 	unsigned int page_width = log_2(pte->page_width);
145 	unsigned int page_height = log_2(pte->page_height);
146 	unsigned int min_pte_before_flip = is_vert_scan(rotation) ?
147 			pte->min_pte_before_flip_vert_scan :
148 			pte->min_pte_before_flip_horiz_scan;
149 
150 	REG_UPDATE(GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT,
151 			GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT, 0x7f);
152 
153 	REG_UPDATE_3(DVMM_PTE_CONTROL,
154 			DVMM_PAGE_WIDTH, page_width,
155 			DVMM_PAGE_HEIGHT, page_height,
156 			DVMM_MIN_PTE_BEFORE_FLIP, min_pte_before_flip);
157 
158 	REG_UPDATE_2(DVMM_PTE_ARB_CONTROL,
159 			DVMM_PTE_REQ_PER_CHUNK, pte->pte_req_per_chunk,
160 			DVMM_MAX_PTE_REQ_OUTSTANDING, 0x7f);
161 }
162 
163 static void program_urgency_watermark(
164 	struct dce_mem_input *dce_mi,
165 	uint32_t wm_select,
166 	uint32_t urgency_low_wm,
167 	uint32_t urgency_high_wm)
168 {
169 	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
170 		URGENCY_WATERMARK_MASK, wm_select);
171 
172 	REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
173 		URGENCY_LOW_WATERMARK, urgency_low_wm,
174 		URGENCY_HIGH_WATERMARK, urgency_high_wm);
175 }
176 
177 #if defined(CONFIG_DRM_AMD_DC_SI)
178 static void dce60_program_urgency_watermark(
179 	struct dce_mem_input *dce_mi,
180 	uint32_t wm_select,
181 	uint32_t urgency_low_wm,
182 	uint32_t urgency_high_wm)
183 {
184 	REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL3,
185 		URGENCY_WATERMARK_MASK, wm_select);
186 
187 	REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
188 		URGENCY_LOW_WATERMARK, urgency_low_wm,
189 		URGENCY_HIGH_WATERMARK, urgency_high_wm);
190 }
191 #endif
192 
193 static void dce120_program_urgency_watermark(
194 	struct dce_mem_input *dce_mi,
195 	uint32_t wm_select,
196 	uint32_t urgency_low_wm,
197 	uint32_t urgency_high_wm)
198 {
199 	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
200 		URGENCY_WATERMARK_MASK, wm_select);
201 
202 	REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
203 		URGENCY_LOW_WATERMARK, urgency_low_wm,
204 		URGENCY_HIGH_WATERMARK, urgency_high_wm);
205 
206 	REG_SET_2(DPG_PIPE_URGENT_LEVEL_CONTROL, 0,
207 		URGENT_LEVEL_LOW_WATERMARK, urgency_low_wm,
208 		URGENT_LEVEL_HIGH_WATERMARK, urgency_high_wm);
209 
210 }
211 
212 #if defined(CONFIG_DRM_AMD_DC_SI)
213 static void dce60_program_nbp_watermark(
214 	struct dce_mem_input *dce_mi,
215 	uint32_t wm_select,
216 	uint32_t nbp_wm)
217 {
218 	REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
219 		NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);
220 
221 	REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
222 		NB_PSTATE_CHANGE_ENABLE, 1,
223 		NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
224 		NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
225 
226 	REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
227 		NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
228 }
229 #endif
230 
231 static void program_nbp_watermark(
232 	struct dce_mem_input *dce_mi,
233 	uint32_t wm_select,
234 	uint32_t nbp_wm)
235 {
236 	if (REG(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL)) {
237 		REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
238 				NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);
239 
240 		REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
241 				NB_PSTATE_CHANGE_ENABLE, 1,
242 				NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
243 				NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
244 
245 		REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
246 				NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
247 	}
248 
249 	if (REG(DPG_PIPE_LOW_POWER_CONTROL)) {
250 		REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
251 				PSTATE_CHANGE_WATERMARK_MASK, wm_select);
252 
253 		REG_UPDATE_3(DPG_PIPE_LOW_POWER_CONTROL,
254 				PSTATE_CHANGE_ENABLE, 1,
255 				PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
256 				PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
257 
258 		REG_UPDATE(DPG_PIPE_LOW_POWER_CONTROL,
259 				PSTATE_CHANGE_WATERMARK, nbp_wm);
260 	}
261 }
262 
263 #if defined(CONFIG_DRM_AMD_DC_SI)
264 static void dce60_program_stutter_watermark(
265 	struct dce_mem_input *dce_mi,
266 	uint32_t wm_select,
267 	uint32_t stutter_mark)
268 {
269 	REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
270 		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
271 
272 	REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
273 		STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
274 }
275 #endif
276 
277 static void dce120_program_stutter_watermark(
278 	struct dce_mem_input *dce_mi,
279 	uint32_t wm_select,
280 	uint32_t stutter_mark,
281 	uint32_t stutter_entry)
282 {
283 	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
284 		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
285 
286 	if (REG(DPG_PIPE_STUTTER_CONTROL2))
287 		REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL2,
288 				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
289 				STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
290 	else
291 		REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
292 				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
293 				STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
294 }
295 
296 static void program_stutter_watermark(
297 	struct dce_mem_input *dce_mi,
298 	uint32_t wm_select,
299 	uint32_t stutter_mark)
300 {
301 	REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
302 		STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
303 
304 	if (REG(DPG_PIPE_STUTTER_CONTROL2))
305 		REG_UPDATE(DPG_PIPE_STUTTER_CONTROL2,
306 				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
307 	else
308 		REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
309 				STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
310 }
311 
312 static void dce_mi_program_display_marks(
313 	struct mem_input *mi,
314 	struct dce_watermarks nbp,
315 	struct dce_watermarks stutter_exit,
316 	struct dce_watermarks stutter_enter,
317 	struct dce_watermarks urgent,
318 	uint32_t total_dest_line_time_ns)
319 {
320 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
321 	uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
322 
323 	program_urgency_watermark(dce_mi, 2, /* set a */
324 			urgent.a_mark, total_dest_line_time_ns);
325 	program_urgency_watermark(dce_mi, 1, /* set d */
326 			urgent.d_mark, total_dest_line_time_ns);
327 
328 	REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
329 		STUTTER_ENABLE, stutter_en,
330 		STUTTER_IGNORE_FBC, 1);
331 	program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */
332 	program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */
333 
334 	program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark); /* set a */
335 	program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark); /* set d */
336 }
337 
338 #if defined(CONFIG_DRM_AMD_DC_SI)
339 static void dce60_mi_program_display_marks(
340 	struct mem_input *mi,
341 	struct dce_watermarks nbp,
342 	struct dce_watermarks stutter_exit,
343 	struct dce_watermarks stutter_enter,
344 	struct dce_watermarks urgent,
345 	uint32_t total_dest_line_time_ns)
346 {
347 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
348 	uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
349 
350 	dce60_program_urgency_watermark(dce_mi, 2, /* set a */
351 			urgent.a_mark, total_dest_line_time_ns);
352 	dce60_program_urgency_watermark(dce_mi, 1, /* set d */
353 			urgent.d_mark, total_dest_line_time_ns);
354 
355 	REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
356 		STUTTER_ENABLE, stutter_en,
357 		STUTTER_IGNORE_FBC, 1);
358 	dce60_program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */
359 	dce60_program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */
360 
361 	dce60_program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark); /* set a */
362 	dce60_program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark); /* set d */
363 }
364 #endif
365 
366 static void dce112_mi_program_display_marks(struct mem_input *mi,
367 	struct dce_watermarks nbp,
368 	struct dce_watermarks stutter_exit,
369 	struct dce_watermarks stutter_entry,
370 	struct dce_watermarks urgent,
371 	uint32_t total_dest_line_time_ns)
372 {
373 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
374 	uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
375 
376 	program_urgency_watermark(dce_mi, 0, /* set a */
377 			urgent.a_mark, total_dest_line_time_ns);
378 	program_urgency_watermark(dce_mi, 1, /* set b */
379 			urgent.b_mark, total_dest_line_time_ns);
380 	program_urgency_watermark(dce_mi, 2, /* set c */
381 			urgent.c_mark, total_dest_line_time_ns);
382 	program_urgency_watermark(dce_mi, 3, /* set d */
383 			urgent.d_mark, total_dest_line_time_ns);
384 
385 	REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
386 		STUTTER_ENABLE, stutter_en,
387 		STUTTER_IGNORE_FBC, 1);
388 	program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */
389 	program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */
390 	program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */
391 	program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */
392 
393 	program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark); /* set a */
394 	program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark); /* set b */
395 	program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark); /* set c */
396 	program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark); /* set d */
397 }
398 
399 static void dce120_mi_program_display_marks(struct mem_input *mi,
400 	struct dce_watermarks nbp,
401 	struct dce_watermarks stutter_exit,
402 	struct dce_watermarks stutter_entry,
403 	struct dce_watermarks urgent,
404 	uint32_t total_dest_line_time_ns)
405 {
406 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
407 	uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
408 
409 	dce120_program_urgency_watermark(dce_mi, 0, /* set a */
410 			urgent.a_mark, total_dest_line_time_ns);
411 	dce120_program_urgency_watermark(dce_mi, 1, /* set b */
412 			urgent.b_mark, total_dest_line_time_ns);
413 	dce120_program_urgency_watermark(dce_mi, 2, /* set c */
414 			urgent.c_mark, total_dest_line_time_ns);
415 	dce120_program_urgency_watermark(dce_mi, 3, /* set d */
416 			urgent.d_mark, total_dest_line_time_ns);
417 
418 	REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
419 		STUTTER_ENABLE, stutter_en,
420 		STUTTER_IGNORE_FBC, 1);
421 	program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */
422 	program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */
423 	program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */
424 	program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */
425 
426 	dce120_program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark, stutter_entry.a_mark); /* set a */
427 	dce120_program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark, stutter_entry.b_mark); /* set b */
428 	dce120_program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark, stutter_entry.c_mark); /* set c */
429 	dce120_program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark, stutter_entry.d_mark); /* set d */
430 }
431 
432 static void program_tiling(
433 	struct dce_mem_input *dce_mi, const union dc_tiling_info *info)
434 {
435 	if (dce_mi->masks->GRPH_SW_MODE) { /* GFX9 */
436 		REG_UPDATE_6(GRPH_CONTROL,
437 				GRPH_SW_MODE, info->gfx9.swizzle,
438 				GRPH_NUM_BANKS, log_2(info->gfx9.num_banks),
439 				GRPH_NUM_SHADER_ENGINES, log_2(info->gfx9.num_shader_engines),
440 				GRPH_NUM_PIPES, log_2(info->gfx9.num_pipes),
441 				GRPH_COLOR_EXPANSION_MODE, 1,
442 				GRPH_SE_ENABLE, info->gfx9.shaderEnable);
443 		/* TODO: DCP0_GRPH_CONTROL__GRPH_SE_ENABLE where to get info
444 		GRPH_SE_ENABLE, 1,
445 		GRPH_Z, 0);
446 		 */
447 	}
448 
449 	if (dce_mi->masks->GRPH_MICRO_TILE_MODE) { /* GFX8 */
450 		REG_UPDATE_9(GRPH_CONTROL,
451 				GRPH_NUM_BANKS, info->gfx8.num_banks,
452 				GRPH_BANK_WIDTH, info->gfx8.bank_width,
453 				GRPH_BANK_HEIGHT, info->gfx8.bank_height,
454 				GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect,
455 				GRPH_TILE_SPLIT, info->gfx8.tile_split,
456 				GRPH_MICRO_TILE_MODE, info->gfx8.tile_mode,
457 				GRPH_PIPE_CONFIG, info->gfx8.pipe_config,
458 				GRPH_ARRAY_MODE, info->gfx8.array_mode,
459 				GRPH_COLOR_EXPANSION_MODE, 1);
460 		/* 01 - DCP_GRPH_COLOR_EXPANSION_MODE_ZEXP: zero expansion for YCbCr */
461 		/*
462 				GRPH_Z, 0);
463 				*/
464 	}
465 
466 	if (dce_mi->masks->GRPH_ARRAY_MODE) { /* GFX6 but reuses gfx8 struct */
467 		REG_UPDATE_8(GRPH_CONTROL,
468 				GRPH_NUM_BANKS, info->gfx8.num_banks,
469 				GRPH_BANK_WIDTH, info->gfx8.bank_width,
470 				GRPH_BANK_HEIGHT, info->gfx8.bank_height,
471 				GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect,
472 				GRPH_TILE_SPLIT, info->gfx8.tile_split,
473 				/* DCE6 has no GRPH_MICRO_TILE_MODE mask */
474 				GRPH_PIPE_CONFIG, info->gfx8.pipe_config,
475 				GRPH_ARRAY_MODE, info->gfx8.array_mode,
476 				GRPH_COLOR_EXPANSION_MODE, 1);
477 		/* 01 - DCP_GRPH_COLOR_EXPANSION_MODE_ZEXP: zero expansion for YCbCr */
478 		/*
479 				GRPH_Z, 0);
480 				*/
481 	}
482 }
483 
484 
485 static void program_size_and_rotation(
486 	struct dce_mem_input *dce_mi,
487 	enum dc_rotation_angle rotation,
488 	const struct plane_size *plane_size)
489 {
490 	const struct rect *in_rect = &plane_size->surface_size;
491 	struct rect hw_rect = plane_size->surface_size;
492 	const uint32_t rotation_angles[ROTATION_ANGLE_COUNT] = {
493 			[ROTATION_ANGLE_0] = 0,
494 			[ROTATION_ANGLE_90] = 1,
495 			[ROTATION_ANGLE_180] = 2,
496 			[ROTATION_ANGLE_270] = 3,
497 	};
498 
499 	if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270) {
500 		hw_rect.x = in_rect->y;
501 		hw_rect.y = in_rect->x;
502 
503 		hw_rect.height = in_rect->width;
504 		hw_rect.width = in_rect->height;
505 	}
506 
507 	REG_SET(GRPH_X_START, 0,
508 			GRPH_X_START, hw_rect.x);
509 
510 	REG_SET(GRPH_Y_START, 0,
511 			GRPH_Y_START, hw_rect.y);
512 
513 	REG_SET(GRPH_X_END, 0,
514 			GRPH_X_END, hw_rect.width);
515 
516 	REG_SET(GRPH_Y_END, 0,
517 			GRPH_Y_END, hw_rect.height);
518 
519 	REG_SET(GRPH_PITCH, 0,
520 			GRPH_PITCH, plane_size->surface_pitch);
521 
522 	REG_SET(HW_ROTATION, 0,
523 			GRPH_ROTATION_ANGLE, rotation_angles[rotation]);
524 }
525 
526 #if defined(CONFIG_DRM_AMD_DC_SI)
527 static void dce60_program_size(
528 	struct dce_mem_input *dce_mi,
529 	enum dc_rotation_angle rotation, /* not used in DCE6 */
530 	const struct plane_size *plane_size)
531 {
532 	struct rect hw_rect = plane_size->surface_size;
533 	/* DCE6 has no HW rotation, skip rotation_angles declaration */
534 
535 	/* DCE6 has no HW rotation, skip ROTATION_ANGLE_* processing */
536 
537 	REG_SET(GRPH_X_START, 0,
538 			GRPH_X_START, hw_rect.x);
539 
540 	REG_SET(GRPH_Y_START, 0,
541 			GRPH_Y_START, hw_rect.y);
542 
543 	REG_SET(GRPH_X_END, 0,
544 			GRPH_X_END, hw_rect.width);
545 
546 	REG_SET(GRPH_Y_END, 0,
547 			GRPH_Y_END, hw_rect.height);
548 
549 	REG_SET(GRPH_PITCH, 0,
550 			GRPH_PITCH, plane_size->surface_pitch);
551 
552 	/* DCE6 has no HW_ROTATION register, skip setting rotation_angles */
553 }
554 #endif
555 
556 static void program_grph_pixel_format(
557 	struct dce_mem_input *dce_mi,
558 	enum surface_pixel_format format)
559 {
560 	uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
561 	uint32_t grph_depth = 0, grph_format = 0;
562 	uint32_t sign = 0, floating = 0;
563 
564 	if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
565 			/*todo: doesn't look like we handle BGRA here,
566 			 *  should problem swap endian*/
567 		format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
568 		format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ||
569 		format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 ||
570 		format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
571 		/* ABGR formats */
572 		red_xbar = 2;
573 		blue_xbar = 2;
574 	}
575 
576 	REG_SET_2(GRPH_SWAP_CNTL, 0,
577 			GRPH_RED_CROSSBAR, red_xbar,
578 			GRPH_BLUE_CROSSBAR, blue_xbar);
579 
580 	switch (format) {
581 	case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
582 		grph_depth = 0;
583 		grph_format = 0;
584 		break;
585 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
586 		grph_depth = 1;
587 		grph_format = 0;
588 		break;
589 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
590 		grph_depth = 1;
591 		grph_format = 1;
592 		break;
593 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
594 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
595 		grph_depth = 2;
596 		grph_format = 0;
597 		break;
598 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
599 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
600 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
601 		grph_depth = 2;
602 		grph_format = 1;
603 		break;
604 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
605 		sign = 1;
606 		floating = 1;
607 		fallthrough;
608 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */
609 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
610 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
611 		grph_depth = 3;
612 		grph_format = 0;
613 		break;
614 	default:
615 		DC_ERR("unsupported grph pixel format");
616 		break;
617 	}
618 
619 	REG_UPDATE_2(GRPH_CONTROL,
620 			GRPH_DEPTH, grph_depth,
621 			GRPH_FORMAT, grph_format);
622 
623 	REG_UPDATE_4(PRESCALE_GRPH_CONTROL,
624 			GRPH_PRESCALE_SELECT, floating,
625 			GRPH_PRESCALE_R_SIGN, sign,
626 			GRPH_PRESCALE_G_SIGN, sign,
627 			GRPH_PRESCALE_B_SIGN, sign);
628 }
629 
630 static void dce_mi_program_surface_config(
631 	struct mem_input *mi,
632 	enum surface_pixel_format format,
633 	union dc_tiling_info *tiling_info,
634 	struct plane_size *plane_size,
635 	enum dc_rotation_angle rotation,
636 	struct dc_plane_dcc_param *dcc,
637 	bool horizontal_mirror)
638 {
639 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
640 	REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);
641 
642 	program_tiling(dce_mi, tiling_info);
643 	program_size_and_rotation(dce_mi, rotation, plane_size);
644 
645 	if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
646 		format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
647 		program_grph_pixel_format(dce_mi, format);
648 }
649 
650 #if defined(CONFIG_DRM_AMD_DC_SI)
651 static void dce60_mi_program_surface_config(
652 	struct mem_input *mi,
653 	enum surface_pixel_format format,
654 	union dc_tiling_info *tiling_info,
655 	struct plane_size *plane_size,
656 	enum dc_rotation_angle rotation, /* not used in DCE6 */
657 	struct dc_plane_dcc_param *dcc,
658 	bool horizontal_mirror)
659 {
660 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
661 	REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);
662 
663 	program_tiling(dce_mi, tiling_info);
664 	dce60_program_size(dce_mi, rotation, plane_size);
665 
666 	if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
667 		format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
668 		program_grph_pixel_format(dce_mi, format);
669 }
670 #endif
671 
672 static uint32_t get_dmif_switch_time_us(
673 	uint32_t h_total,
674 	uint32_t v_total,
675 	uint32_t pix_clk_khz)
676 {
677 	uint32_t frame_time;
678 	uint32_t pixels_per_second;
679 	uint32_t pixels_per_frame;
680 	uint32_t refresh_rate;
681 	const uint32_t us_in_sec = 1000000;
682 	const uint32_t min_single_frame_time_us = 30000;
683 	/*return double of frame time*/
684 	const uint32_t single_frame_time_multiplier = 2;
685 
686 	if (!h_total || v_total || !pix_clk_khz)
687 		return single_frame_time_multiplier * min_single_frame_time_us;
688 
689 	/*TODO: should we use pixel format normalized pixel clock here?*/
690 	pixels_per_second = pix_clk_khz * 1000;
691 	pixels_per_frame = h_total * v_total;
692 
693 	if (!pixels_per_second || !pixels_per_frame) {
694 		/* avoid division by zero */
695 		ASSERT(pixels_per_frame);
696 		ASSERT(pixels_per_second);
697 		return single_frame_time_multiplier * min_single_frame_time_us;
698 	}
699 
700 	refresh_rate = pixels_per_second / pixels_per_frame;
701 
702 	if (!refresh_rate) {
703 		/* avoid division by zero*/
704 		ASSERT(refresh_rate);
705 		return single_frame_time_multiplier * min_single_frame_time_us;
706 	}
707 
708 	frame_time = us_in_sec / refresh_rate;
709 
710 	if (frame_time < min_single_frame_time_us)
711 		frame_time = min_single_frame_time_us;
712 
713 	frame_time *= single_frame_time_multiplier;
714 
715 	return frame_time;
716 }
717 
718 static void dce_mi_allocate_dmif(
719 	struct mem_input *mi,
720 	uint32_t h_total,
721 	uint32_t v_total,
722 	uint32_t pix_clk_khz,
723 	uint32_t total_stream_num)
724 {
725 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
726 	const uint32_t retry_delay = 10;
727 	uint32_t retry_count = get_dmif_switch_time_us(
728 			h_total,
729 			v_total,
730 			pix_clk_khz) / retry_delay;
731 
732 	uint32_t pix_dur;
733 	uint32_t buffers_allocated;
734 	uint32_t dmif_buffer_control;
735 
736 	dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
737 			DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
738 
739 	if (buffers_allocated == 2)
740 		return;
741 
742 	REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
743 			DMIF_BUFFERS_ALLOCATED, 2);
744 
745 	REG_WAIT(DMIF_BUFFER_CONTROL,
746 			DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
747 			retry_delay, retry_count);
748 
749 	if (pix_clk_khz != 0) {
750 		pix_dur = 1000000000ULL / pix_clk_khz;
751 
752 		REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1,
753 			PIXEL_DURATION, pix_dur);
754 	}
755 
756 	if (dce_mi->wa.single_head_rdreq_dmif_limit) {
757 		uint32_t enable =  (total_stream_num > 1) ? 0 :
758 				dce_mi->wa.single_head_rdreq_dmif_limit;
759 
760 		REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
761 				ENABLE, enable);
762 	}
763 }
764 
765 static void dce_mi_free_dmif(
766 		struct mem_input *mi,
767 		uint32_t total_stream_num)
768 {
769 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
770 	uint32_t buffers_allocated;
771 	uint32_t dmif_buffer_control;
772 
773 	dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
774 			DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
775 
776 	if (buffers_allocated == 0)
777 		return;
778 
779 	REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
780 			DMIF_BUFFERS_ALLOCATED, 0);
781 
782 	REG_WAIT(DMIF_BUFFER_CONTROL,
783 			DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
784 			10, 3500);
785 
786 	if (dce_mi->wa.single_head_rdreq_dmif_limit) {
787 		uint32_t enable =  (total_stream_num > 1) ? 0 :
788 				dce_mi->wa.single_head_rdreq_dmif_limit;
789 
790 		REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
791 				ENABLE, enable);
792 	}
793 }
794 
795 
796 static void program_sec_addr(
797 	struct dce_mem_input *dce_mi,
798 	PHYSICAL_ADDRESS_LOC address)
799 {
800 	/*high register MUST be programmed first*/
801 	REG_SET(GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
802 		GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
803 		address.high_part);
804 
805 	REG_SET_2(GRPH_SECONDARY_SURFACE_ADDRESS, 0,
806 		GRPH_SECONDARY_SURFACE_ADDRESS, address.low_part >> 8,
807 		GRPH_SECONDARY_DFQ_ENABLE, 0);
808 }
809 
810 static void program_pri_addr(
811 	struct dce_mem_input *dce_mi,
812 	PHYSICAL_ADDRESS_LOC address)
813 {
814 	/*high register MUST be programmed first*/
815 	REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
816 		GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
817 		address.high_part);
818 
819 	REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS, 0,
820 		GRPH_PRIMARY_SURFACE_ADDRESS,
821 		address.low_part >> 8);
822 }
823 
824 
825 static bool dce_mi_is_flip_pending(struct mem_input *mem_input)
826 {
827 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
828 	uint32_t update_pending;
829 
830 	REG_GET(GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING, &update_pending);
831 	if (update_pending)
832 		return true;
833 
834 	mem_input->current_address = mem_input->request_address;
835 	return false;
836 }
837 
838 static bool dce_mi_program_surface_flip_and_addr(
839 	struct mem_input *mem_input,
840 	const struct dc_plane_address *address,
841 	bool flip_immediate)
842 {
843 	struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
844 
845 	REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 1);
846 
847 	REG_UPDATE(
848 		GRPH_FLIP_CONTROL,
849 		GRPH_SURFACE_UPDATE_H_RETRACE_EN, flip_immediate ? 1 : 0);
850 
851 	switch (address->type) {
852 	case PLN_ADDR_TYPE_GRAPHICS:
853 		if (address->grph.addr.quad_part == 0)
854 			break;
855 		program_pri_addr(dce_mi, address->grph.addr);
856 		break;
857 	case PLN_ADDR_TYPE_GRPH_STEREO:
858 		if (address->grph_stereo.left_addr.quad_part == 0 ||
859 		    address->grph_stereo.right_addr.quad_part == 0)
860 			break;
861 		program_pri_addr(dce_mi, address->grph_stereo.left_addr);
862 		program_sec_addr(dce_mi, address->grph_stereo.right_addr);
863 		break;
864 	default:
865 		/* not supported */
866 		BREAK_TO_DEBUGGER();
867 		break;
868 	}
869 
870 	mem_input->request_address = *address;
871 
872 	if (flip_immediate)
873 		mem_input->current_address = *address;
874 
875 	REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 0);
876 
877 	return true;
878 }
879 
880 static const struct mem_input_funcs dce_mi_funcs = {
881 	.mem_input_program_display_marks = dce_mi_program_display_marks,
882 	.allocate_mem_input = dce_mi_allocate_dmif,
883 	.free_mem_input = dce_mi_free_dmif,
884 	.mem_input_program_surface_flip_and_addr =
885 			dce_mi_program_surface_flip_and_addr,
886 	.mem_input_program_pte_vm = dce_mi_program_pte_vm,
887 	.mem_input_program_surface_config =
888 			dce_mi_program_surface_config,
889 	.mem_input_is_flip_pending = dce_mi_is_flip_pending
890 };
891 
892 #if defined(CONFIG_DRM_AMD_DC_SI)
893 static const struct mem_input_funcs dce60_mi_funcs = {
894 	.mem_input_program_display_marks = dce60_mi_program_display_marks,
895 	.allocate_mem_input = dce_mi_allocate_dmif,
896 	.free_mem_input = dce_mi_free_dmif,
897 	.mem_input_program_surface_flip_and_addr =
898 			dce_mi_program_surface_flip_and_addr,
899 	.mem_input_program_pte_vm = dce_mi_program_pte_vm,
900 	.mem_input_program_surface_config =
901 			dce60_mi_program_surface_config,
902 	.mem_input_is_flip_pending = dce_mi_is_flip_pending
903 };
904 #endif
905 
906 static const struct mem_input_funcs dce112_mi_funcs = {
907 	.mem_input_program_display_marks = dce112_mi_program_display_marks,
908 	.allocate_mem_input = dce_mi_allocate_dmif,
909 	.free_mem_input = dce_mi_free_dmif,
910 	.mem_input_program_surface_flip_and_addr =
911 			dce_mi_program_surface_flip_and_addr,
912 	.mem_input_program_pte_vm = dce_mi_program_pte_vm,
913 	.mem_input_program_surface_config =
914 			dce_mi_program_surface_config,
915 	.mem_input_is_flip_pending = dce_mi_is_flip_pending
916 };
917 
918 static const struct mem_input_funcs dce120_mi_funcs = {
919 	.mem_input_program_display_marks = dce120_mi_program_display_marks,
920 	.allocate_mem_input = dce_mi_allocate_dmif,
921 	.free_mem_input = dce_mi_free_dmif,
922 	.mem_input_program_surface_flip_and_addr =
923 			dce_mi_program_surface_flip_and_addr,
924 	.mem_input_program_pte_vm = dce_mi_program_pte_vm,
925 	.mem_input_program_surface_config =
926 			dce_mi_program_surface_config,
927 	.mem_input_is_flip_pending = dce_mi_is_flip_pending
928 };
929 
930 void dce_mem_input_construct(
931 	struct dce_mem_input *dce_mi,
932 	struct dc_context *ctx,
933 	int inst,
934 	const struct dce_mem_input_registers *regs,
935 	const struct dce_mem_input_shift *mi_shift,
936 	const struct dce_mem_input_mask *mi_mask)
937 {
938 	dce_mi->base.ctx = ctx;
939 
940 	dce_mi->base.inst = inst;
941 	dce_mi->base.funcs = &dce_mi_funcs;
942 
943 	dce_mi->regs = regs;
944 	dce_mi->shifts = mi_shift;
945 	dce_mi->masks = mi_mask;
946 }
947 
948 #if defined(CONFIG_DRM_AMD_DC_SI)
949 void dce60_mem_input_construct(
950 	struct dce_mem_input *dce_mi,
951 	struct dc_context *ctx,
952 	int inst,
953 	const struct dce_mem_input_registers *regs,
954 	const struct dce_mem_input_shift *mi_shift,
955 	const struct dce_mem_input_mask *mi_mask)
956 {
957 	dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
958 	dce_mi->base.funcs = &dce60_mi_funcs;
959 }
960 #endif
961 
962 void dce112_mem_input_construct(
963 	struct dce_mem_input *dce_mi,
964 	struct dc_context *ctx,
965 	int inst,
966 	const struct dce_mem_input_registers *regs,
967 	const struct dce_mem_input_shift *mi_shift,
968 	const struct dce_mem_input_mask *mi_mask)
969 {
970 	dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
971 	dce_mi->base.funcs = &dce112_mi_funcs;
972 }
973 
974 void dce120_mem_input_construct(
975 	struct dce_mem_input *dce_mi,
976 	struct dc_context *ctx,
977 	int inst,
978 	const struct dce_mem_input_registers *regs,
979 	const struct dce_mem_input_shift *mi_shift,
980 	const struct dce_mem_input_mask *mi_mask)
981 {
982 	dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
983 	dce_mi->base.funcs = &dce120_mi_funcs;
984 }
985