]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
Merge tag 'trace-v5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux.git] / drivers / gpu / drm / amd / display / dc / dce / dce_mem_input.c
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_ABGR16161616F) {
570                 /* ABGR formats */
571                 red_xbar = 2;
572                 blue_xbar = 2;
573         }
574
575         REG_SET_2(GRPH_SWAP_CNTL, 0,
576                         GRPH_RED_CROSSBAR, red_xbar,
577                         GRPH_BLUE_CROSSBAR, blue_xbar);
578
579         switch (format) {
580         case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
581                 grph_depth = 0;
582                 grph_format = 0;
583                 break;
584         case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
585                 grph_depth = 1;
586                 grph_format = 0;
587                 break;
588         case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
589                 grph_depth = 1;
590                 grph_format = 1;
591                 break;
592         case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
593         case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
594                 grph_depth = 2;
595                 grph_format = 0;
596                 break;
597         case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
598         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
599         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
600                 grph_depth = 2;
601                 grph_format = 1;
602                 break;
603         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
604                 sign = 1;
605                 floating = 1;
606                 fallthrough;
607         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */
608         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
609                 grph_depth = 3;
610                 grph_format = 0;
611                 break;
612         default:
613                 DC_ERR("unsupported grph pixel format");
614                 break;
615         }
616
617         REG_UPDATE_2(GRPH_CONTROL,
618                         GRPH_DEPTH, grph_depth,
619                         GRPH_FORMAT, grph_format);
620
621         REG_UPDATE_4(PRESCALE_GRPH_CONTROL,
622                         GRPH_PRESCALE_SELECT, floating,
623                         GRPH_PRESCALE_R_SIGN, sign,
624                         GRPH_PRESCALE_G_SIGN, sign,
625                         GRPH_PRESCALE_B_SIGN, sign);
626 }
627
628 static void dce_mi_program_surface_config(
629         struct mem_input *mi,
630         enum surface_pixel_format format,
631         union dc_tiling_info *tiling_info,
632         struct plane_size *plane_size,
633         enum dc_rotation_angle rotation,
634         struct dc_plane_dcc_param *dcc,
635         bool horizontal_mirror)
636 {
637         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
638         REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);
639
640         program_tiling(dce_mi, tiling_info);
641         program_size_and_rotation(dce_mi, rotation, plane_size);
642
643         if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
644                 format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
645                 program_grph_pixel_format(dce_mi, format);
646 }
647
648 #if defined(CONFIG_DRM_AMD_DC_SI)
649 static void dce60_mi_program_surface_config(
650         struct mem_input *mi,
651         enum surface_pixel_format format,
652         union dc_tiling_info *tiling_info,
653         struct plane_size *plane_size,
654         enum dc_rotation_angle rotation, /* not used in DCE6 */
655         struct dc_plane_dcc_param *dcc,
656         bool horizontal_mirror)
657 {
658         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
659         REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);
660
661         program_tiling(dce_mi, tiling_info);
662         dce60_program_size(dce_mi, rotation, plane_size);
663
664         if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
665                 format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
666                 program_grph_pixel_format(dce_mi, format);
667 }
668 #endif
669
670 static uint32_t get_dmif_switch_time_us(
671         uint32_t h_total,
672         uint32_t v_total,
673         uint32_t pix_clk_khz)
674 {
675         uint32_t frame_time;
676         uint32_t pixels_per_second;
677         uint32_t pixels_per_frame;
678         uint32_t refresh_rate;
679         const uint32_t us_in_sec = 1000000;
680         const uint32_t min_single_frame_time_us = 30000;
681         /*return double of frame time*/
682         const uint32_t single_frame_time_multiplier = 2;
683
684         if (!h_total || v_total || !pix_clk_khz)
685                 return single_frame_time_multiplier * min_single_frame_time_us;
686
687         /*TODO: should we use pixel format normalized pixel clock here?*/
688         pixels_per_second = pix_clk_khz * 1000;
689         pixels_per_frame = h_total * v_total;
690
691         if (!pixels_per_second || !pixels_per_frame) {
692                 /* avoid division by zero */
693                 ASSERT(pixels_per_frame);
694                 ASSERT(pixels_per_second);
695                 return single_frame_time_multiplier * min_single_frame_time_us;
696         }
697
698         refresh_rate = pixels_per_second / pixels_per_frame;
699
700         if (!refresh_rate) {
701                 /* avoid division by zero*/
702                 ASSERT(refresh_rate);
703                 return single_frame_time_multiplier * min_single_frame_time_us;
704         }
705
706         frame_time = us_in_sec / refresh_rate;
707
708         if (frame_time < min_single_frame_time_us)
709                 frame_time = min_single_frame_time_us;
710
711         frame_time *= single_frame_time_multiplier;
712
713         return frame_time;
714 }
715
716 static void dce_mi_allocate_dmif(
717         struct mem_input *mi,
718         uint32_t h_total,
719         uint32_t v_total,
720         uint32_t pix_clk_khz,
721         uint32_t total_stream_num)
722 {
723         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
724         const uint32_t retry_delay = 10;
725         uint32_t retry_count = get_dmif_switch_time_us(
726                         h_total,
727                         v_total,
728                         pix_clk_khz) / retry_delay;
729
730         uint32_t pix_dur;
731         uint32_t buffers_allocated;
732         uint32_t dmif_buffer_control;
733
734         dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
735                         DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
736
737         if (buffers_allocated == 2)
738                 return;
739
740         REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
741                         DMIF_BUFFERS_ALLOCATED, 2);
742
743         REG_WAIT(DMIF_BUFFER_CONTROL,
744                         DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
745                         retry_delay, retry_count);
746
747         if (pix_clk_khz != 0) {
748                 pix_dur = 1000000000ULL / pix_clk_khz;
749
750                 REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1,
751                         PIXEL_DURATION, pix_dur);
752         }
753
754         if (dce_mi->wa.single_head_rdreq_dmif_limit) {
755                 uint32_t enable =  (total_stream_num > 1) ? 0 :
756                                 dce_mi->wa.single_head_rdreq_dmif_limit;
757
758                 REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
759                                 ENABLE, enable);
760         }
761 }
762
763 static void dce_mi_free_dmif(
764                 struct mem_input *mi,
765                 uint32_t total_stream_num)
766 {
767         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
768         uint32_t buffers_allocated;
769         uint32_t dmif_buffer_control;
770
771         dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
772                         DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
773
774         if (buffers_allocated == 0)
775                 return;
776
777         REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
778                         DMIF_BUFFERS_ALLOCATED, 0);
779
780         REG_WAIT(DMIF_BUFFER_CONTROL,
781                         DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
782                         10, 3500);
783
784         if (dce_mi->wa.single_head_rdreq_dmif_limit) {
785                 uint32_t enable =  (total_stream_num > 1) ? 0 :
786                                 dce_mi->wa.single_head_rdreq_dmif_limit;
787
788                 REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
789                                 ENABLE, enable);
790         }
791 }
792
793
794 static void program_sec_addr(
795         struct dce_mem_input *dce_mi,
796         PHYSICAL_ADDRESS_LOC address)
797 {
798         /*high register MUST be programmed first*/
799         REG_SET(GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
800                 GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
801                 address.high_part);
802
803         REG_SET_2(GRPH_SECONDARY_SURFACE_ADDRESS, 0,
804                 GRPH_SECONDARY_SURFACE_ADDRESS, address.low_part >> 8,
805                 GRPH_SECONDARY_DFQ_ENABLE, 0);
806 }
807
808 static void program_pri_addr(
809         struct dce_mem_input *dce_mi,
810         PHYSICAL_ADDRESS_LOC address)
811 {
812         /*high register MUST be programmed first*/
813         REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
814                 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
815                 address.high_part);
816
817         REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS, 0,
818                 GRPH_PRIMARY_SURFACE_ADDRESS,
819                 address.low_part >> 8);
820 }
821
822
823 static bool dce_mi_is_flip_pending(struct mem_input *mem_input)
824 {
825         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
826         uint32_t update_pending;
827
828         REG_GET(GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING, &update_pending);
829         if (update_pending)
830                 return true;
831
832         mem_input->current_address = mem_input->request_address;
833         return false;
834 }
835
836 static bool dce_mi_program_surface_flip_and_addr(
837         struct mem_input *mem_input,
838         const struct dc_plane_address *address,
839         bool flip_immediate)
840 {
841         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
842
843         REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 1);
844
845         REG_UPDATE(
846                 GRPH_FLIP_CONTROL,
847                 GRPH_SURFACE_UPDATE_H_RETRACE_EN, flip_immediate ? 1 : 0);
848
849         switch (address->type) {
850         case PLN_ADDR_TYPE_GRAPHICS:
851                 if (address->grph.addr.quad_part == 0)
852                         break;
853                 program_pri_addr(dce_mi, address->grph.addr);
854                 break;
855         case PLN_ADDR_TYPE_GRPH_STEREO:
856                 if (address->grph_stereo.left_addr.quad_part == 0 ||
857                     address->grph_stereo.right_addr.quad_part == 0)
858                         break;
859                 program_pri_addr(dce_mi, address->grph_stereo.left_addr);
860                 program_sec_addr(dce_mi, address->grph_stereo.right_addr);
861                 break;
862         default:
863                 /* not supported */
864                 BREAK_TO_DEBUGGER();
865                 break;
866         }
867
868         mem_input->request_address = *address;
869
870         if (flip_immediate)
871                 mem_input->current_address = *address;
872
873         REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 0);
874
875         return true;
876 }
877
878 static const struct mem_input_funcs dce_mi_funcs = {
879         .mem_input_program_display_marks = dce_mi_program_display_marks,
880         .allocate_mem_input = dce_mi_allocate_dmif,
881         .free_mem_input = dce_mi_free_dmif,
882         .mem_input_program_surface_flip_and_addr =
883                         dce_mi_program_surface_flip_and_addr,
884         .mem_input_program_pte_vm = dce_mi_program_pte_vm,
885         .mem_input_program_surface_config =
886                         dce_mi_program_surface_config,
887         .mem_input_is_flip_pending = dce_mi_is_flip_pending
888 };
889
890 #if defined(CONFIG_DRM_AMD_DC_SI)
891 static const struct mem_input_funcs dce60_mi_funcs = {
892         .mem_input_program_display_marks = dce60_mi_program_display_marks,
893         .allocate_mem_input = dce_mi_allocate_dmif,
894         .free_mem_input = dce_mi_free_dmif,
895         .mem_input_program_surface_flip_and_addr =
896                         dce_mi_program_surface_flip_and_addr,
897         .mem_input_program_pte_vm = dce_mi_program_pte_vm,
898         .mem_input_program_surface_config =
899                         dce60_mi_program_surface_config,
900         .mem_input_is_flip_pending = dce_mi_is_flip_pending
901 };
902 #endif
903
904 static const struct mem_input_funcs dce112_mi_funcs = {
905         .mem_input_program_display_marks = dce112_mi_program_display_marks,
906         .allocate_mem_input = dce_mi_allocate_dmif,
907         .free_mem_input = dce_mi_free_dmif,
908         .mem_input_program_surface_flip_and_addr =
909                         dce_mi_program_surface_flip_and_addr,
910         .mem_input_program_pte_vm = dce_mi_program_pte_vm,
911         .mem_input_program_surface_config =
912                         dce_mi_program_surface_config,
913         .mem_input_is_flip_pending = dce_mi_is_flip_pending
914 };
915
916 static const struct mem_input_funcs dce120_mi_funcs = {
917         .mem_input_program_display_marks = dce120_mi_program_display_marks,
918         .allocate_mem_input = dce_mi_allocate_dmif,
919         .free_mem_input = dce_mi_free_dmif,
920         .mem_input_program_surface_flip_and_addr =
921                         dce_mi_program_surface_flip_and_addr,
922         .mem_input_program_pte_vm = dce_mi_program_pte_vm,
923         .mem_input_program_surface_config =
924                         dce_mi_program_surface_config,
925         .mem_input_is_flip_pending = dce_mi_is_flip_pending
926 };
927
928 void dce_mem_input_construct(
929         struct dce_mem_input *dce_mi,
930         struct dc_context *ctx,
931         int inst,
932         const struct dce_mem_input_registers *regs,
933         const struct dce_mem_input_shift *mi_shift,
934         const struct dce_mem_input_mask *mi_mask)
935 {
936         dce_mi->base.ctx = ctx;
937
938         dce_mi->base.inst = inst;
939         dce_mi->base.funcs = &dce_mi_funcs;
940
941         dce_mi->regs = regs;
942         dce_mi->shifts = mi_shift;
943         dce_mi->masks = mi_mask;
944 }
945
946 #if defined(CONFIG_DRM_AMD_DC_SI)
947 void dce60_mem_input_construct(
948         struct dce_mem_input *dce_mi,
949         struct dc_context *ctx,
950         int inst,
951         const struct dce_mem_input_registers *regs,
952         const struct dce_mem_input_shift *mi_shift,
953         const struct dce_mem_input_mask *mi_mask)
954 {
955         dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
956         dce_mi->base.funcs = &dce60_mi_funcs;
957 }
958 #endif
959
960 void dce112_mem_input_construct(
961         struct dce_mem_input *dce_mi,
962         struct dc_context *ctx,
963         int inst,
964         const struct dce_mem_input_registers *regs,
965         const struct dce_mem_input_shift *mi_shift,
966         const struct dce_mem_input_mask *mi_mask)
967 {
968         dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
969         dce_mi->base.funcs = &dce112_mi_funcs;
970 }
971
972 void dce120_mem_input_construct(
973         struct dce_mem_input *dce_mi,
974         struct dc_context *ctx,
975         int inst,
976         const struct dce_mem_input_registers *regs,
977         const struct dce_mem_input_shift *mi_shift,
978         const struct dce_mem_input_mask *mi_mask)
979 {
980         dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
981         dce_mi->base.funcs = &dce120_mi_funcs;
982 }
This page took 0.094137 seconds and 4 git commands to generate.