]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
Merge remote-tracking branch 'spi/for-5.14' into spi-linus
[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_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 }
This page took 0.093616 seconds and 4 git commands to generate.