8aa937f496c4ffb5e81b222b98c9ce97793eda02
[linux-2.6-microblaze.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 static void dce120_program_urgency_watermark(
178         struct dce_mem_input *dce_mi,
179         uint32_t wm_select,
180         uint32_t urgency_low_wm,
181         uint32_t urgency_high_wm)
182 {
183         REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
184                 URGENCY_WATERMARK_MASK, wm_select);
185
186         REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
187                 URGENCY_LOW_WATERMARK, urgency_low_wm,
188                 URGENCY_HIGH_WATERMARK, urgency_high_wm);
189
190         REG_SET_2(DPG_PIPE_URGENT_LEVEL_CONTROL, 0,
191                 URGENT_LEVEL_LOW_WATERMARK, urgency_low_wm,
192                 URGENT_LEVEL_HIGH_WATERMARK, urgency_high_wm);
193
194 }
195
196 static void program_nbp_watermark(
197         struct dce_mem_input *dce_mi,
198         uint32_t wm_select,
199         uint32_t nbp_wm)
200 {
201         if (REG(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL)) {
202                 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
203                                 NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);
204
205                 REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
206                                 NB_PSTATE_CHANGE_ENABLE, 1,
207                                 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
208                                 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
209
210                 REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
211                                 NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
212         }
213
214         if (REG(DPG_PIPE_LOW_POWER_CONTROL)) {
215                 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
216                                 PSTATE_CHANGE_WATERMARK_MASK, wm_select);
217
218                 REG_UPDATE_3(DPG_PIPE_LOW_POWER_CONTROL,
219                                 PSTATE_CHANGE_ENABLE, 1,
220                                 PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
221                                 PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
222
223                 REG_UPDATE(DPG_PIPE_LOW_POWER_CONTROL,
224                                 PSTATE_CHANGE_WATERMARK, nbp_wm);
225         }
226 }
227
228 static void dce120_program_stutter_watermark(
229         struct dce_mem_input *dce_mi,
230         uint32_t wm_select,
231         uint32_t stutter_mark,
232         uint32_t stutter_entry)
233 {
234         REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
235                 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
236
237         if (REG(DPG_PIPE_STUTTER_CONTROL2))
238                 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL2,
239                                 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
240                                 STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
241         else
242                 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
243                                 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
244                                 STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
245 }
246
247 static void program_stutter_watermark(
248         struct dce_mem_input *dce_mi,
249         uint32_t wm_select,
250         uint32_t stutter_mark)
251 {
252         REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
253                 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
254
255         if (REG(DPG_PIPE_STUTTER_CONTROL2))
256                 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL2,
257                                 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
258         else
259                 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
260                                 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
261 }
262
263 static void dce_mi_program_display_marks(
264         struct mem_input *mi,
265         struct dce_watermarks nbp,
266         struct dce_watermarks stutter_exit,
267         struct dce_watermarks stutter_enter,
268         struct dce_watermarks urgent,
269         uint32_t total_dest_line_time_ns)
270 {
271         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
272         uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
273
274         program_urgency_watermark(dce_mi, 2, /* set a */
275                         urgent.a_mark, total_dest_line_time_ns);
276         program_urgency_watermark(dce_mi, 1, /* set d */
277                         urgent.d_mark, total_dest_line_time_ns);
278
279         REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
280                 STUTTER_ENABLE, stutter_en,
281                 STUTTER_IGNORE_FBC, 1);
282         program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */
283         program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */
284
285         program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark); /* set a */
286         program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark); /* set d */
287 }
288
289 static void dce112_mi_program_display_marks(struct mem_input *mi,
290         struct dce_watermarks nbp,
291         struct dce_watermarks stutter_exit,
292         struct dce_watermarks stutter_entry,
293         struct dce_watermarks urgent,
294         uint32_t total_dest_line_time_ns)
295 {
296         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
297         uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
298
299         program_urgency_watermark(dce_mi, 0, /* set a */
300                         urgent.a_mark, total_dest_line_time_ns);
301         program_urgency_watermark(dce_mi, 1, /* set b */
302                         urgent.b_mark, total_dest_line_time_ns);
303         program_urgency_watermark(dce_mi, 2, /* set c */
304                         urgent.c_mark, total_dest_line_time_ns);
305         program_urgency_watermark(dce_mi, 3, /* set d */
306                         urgent.d_mark, total_dest_line_time_ns);
307
308         REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
309                 STUTTER_ENABLE, stutter_en,
310                 STUTTER_IGNORE_FBC, 1);
311         program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */
312         program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */
313         program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */
314         program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */
315
316         program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark); /* set a */
317         program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark); /* set b */
318         program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark); /* set c */
319         program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark); /* set d */
320 }
321
322 static void dce120_mi_program_display_marks(struct mem_input *mi,
323         struct dce_watermarks nbp,
324         struct dce_watermarks stutter_exit,
325         struct dce_watermarks stutter_entry,
326         struct dce_watermarks urgent,
327         uint32_t total_dest_line_time_ns)
328 {
329         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
330         uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
331
332         dce120_program_urgency_watermark(dce_mi, 0, /* set a */
333                         urgent.a_mark, total_dest_line_time_ns);
334         dce120_program_urgency_watermark(dce_mi, 1, /* set b */
335                         urgent.b_mark, total_dest_line_time_ns);
336         dce120_program_urgency_watermark(dce_mi, 2, /* set c */
337                         urgent.c_mark, total_dest_line_time_ns);
338         dce120_program_urgency_watermark(dce_mi, 3, /* set d */
339                         urgent.d_mark, total_dest_line_time_ns);
340
341         REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
342                 STUTTER_ENABLE, stutter_en,
343                 STUTTER_IGNORE_FBC, 1);
344         program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */
345         program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */
346         program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */
347         program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */
348
349         dce120_program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark, stutter_entry.a_mark); /* set a */
350         dce120_program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark, stutter_entry.b_mark); /* set b */
351         dce120_program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark, stutter_entry.c_mark); /* set c */
352         dce120_program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark, stutter_entry.d_mark); /* set d */
353 }
354
355 static void program_tiling(
356         struct dce_mem_input *dce_mi, const union dc_tiling_info *info)
357 {
358         if (dce_mi->masks->GRPH_SW_MODE) { /* GFX9 */
359                 REG_UPDATE_6(GRPH_CONTROL,
360                                 GRPH_SW_MODE, info->gfx9.swizzle,
361                                 GRPH_NUM_BANKS, log_2(info->gfx9.num_banks),
362                                 GRPH_NUM_SHADER_ENGINES, log_2(info->gfx9.num_shader_engines),
363                                 GRPH_NUM_PIPES, log_2(info->gfx9.num_pipes),
364                                 GRPH_COLOR_EXPANSION_MODE, 1,
365                                 GRPH_SE_ENABLE, info->gfx9.shaderEnable);
366                 /* TODO: DCP0_GRPH_CONTROL__GRPH_SE_ENABLE where to get info
367                 GRPH_SE_ENABLE, 1,
368                 GRPH_Z, 0);
369                  */
370         }
371
372         if (dce_mi->masks->GRPH_ARRAY_MODE) { /* GFX8 */
373                 REG_UPDATE_9(GRPH_CONTROL,
374                                 GRPH_NUM_BANKS, info->gfx8.num_banks,
375                                 GRPH_BANK_WIDTH, info->gfx8.bank_width,
376                                 GRPH_BANK_HEIGHT, info->gfx8.bank_height,
377                                 GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect,
378                                 GRPH_TILE_SPLIT, info->gfx8.tile_split,
379                                 GRPH_MICRO_TILE_MODE, info->gfx8.tile_mode,
380                                 GRPH_PIPE_CONFIG, info->gfx8.pipe_config,
381                                 GRPH_ARRAY_MODE, info->gfx8.array_mode,
382                                 GRPH_COLOR_EXPANSION_MODE, 1);
383                 /* 01 - DCP_GRPH_COLOR_EXPANSION_MODE_ZEXP: zero expansion for YCbCr */
384                 /*
385                                 GRPH_Z, 0);
386                                 */
387         }
388 }
389
390
391 static void program_size_and_rotation(
392         struct dce_mem_input *dce_mi,
393         enum dc_rotation_angle rotation,
394         const struct plane_size *plane_size)
395 {
396         const struct rect *in_rect = &plane_size->surface_size;
397         struct rect hw_rect = plane_size->surface_size;
398         const uint32_t rotation_angles[ROTATION_ANGLE_COUNT] = {
399                         [ROTATION_ANGLE_0] = 0,
400                         [ROTATION_ANGLE_90] = 1,
401                         [ROTATION_ANGLE_180] = 2,
402                         [ROTATION_ANGLE_270] = 3,
403         };
404
405         if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270) {
406                 hw_rect.x = in_rect->y;
407                 hw_rect.y = in_rect->x;
408
409                 hw_rect.height = in_rect->width;
410                 hw_rect.width = in_rect->height;
411         }
412
413         REG_SET(GRPH_X_START, 0,
414                         GRPH_X_START, hw_rect.x);
415
416         REG_SET(GRPH_Y_START, 0,
417                         GRPH_Y_START, hw_rect.y);
418
419         REG_SET(GRPH_X_END, 0,
420                         GRPH_X_END, hw_rect.width);
421
422         REG_SET(GRPH_Y_END, 0,
423                         GRPH_Y_END, hw_rect.height);
424
425         REG_SET(GRPH_PITCH, 0,
426                         GRPH_PITCH, plane_size->surface_pitch);
427
428         REG_SET(HW_ROTATION, 0,
429                         GRPH_ROTATION_ANGLE, rotation_angles[rotation]);
430 }
431
432 static void program_grph_pixel_format(
433         struct dce_mem_input *dce_mi,
434         enum surface_pixel_format format)
435 {
436         uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
437         uint32_t grph_depth = 0, grph_format = 0;
438         uint32_t sign = 0, floating = 0;
439
440         if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
441                         /*todo: doesn't look like we handle BGRA here,
442                          *  should problem swap endian*/
443                 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
444                 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ||
445                 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
446                 /* ABGR formats */
447                 red_xbar = 2;
448                 blue_xbar = 2;
449         }
450
451         REG_SET_2(GRPH_SWAP_CNTL, 0,
452                         GRPH_RED_CROSSBAR, red_xbar,
453                         GRPH_BLUE_CROSSBAR, blue_xbar);
454
455         switch (format) {
456         case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
457                 grph_depth = 0;
458                 grph_format = 0;
459                 break;
460         case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
461                 grph_depth = 1;
462                 grph_format = 0;
463                 break;
464         case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
465                 grph_depth = 1;
466                 grph_format = 1;
467                 break;
468         case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
469         case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
470                 grph_depth = 2;
471                 grph_format = 0;
472                 break;
473         case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
474         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
475         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
476                 grph_depth = 2;
477                 grph_format = 1;
478                 break;
479         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
480                 sign = 1;
481                 floating = 1;
482                 /* fall through */
483         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */
484         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
485                 grph_depth = 3;
486                 grph_format = 0;
487                 break;
488         default:
489                 DC_ERR("unsupported grph pixel format");
490                 break;
491         }
492
493         REG_UPDATE_2(GRPH_CONTROL,
494                         GRPH_DEPTH, grph_depth,
495                         GRPH_FORMAT, grph_format);
496
497         REG_UPDATE_4(PRESCALE_GRPH_CONTROL,
498                         GRPH_PRESCALE_SELECT, floating,
499                         GRPH_PRESCALE_R_SIGN, sign,
500                         GRPH_PRESCALE_G_SIGN, sign,
501                         GRPH_PRESCALE_B_SIGN, sign);
502 }
503
504 static void dce_mi_program_surface_config(
505         struct mem_input *mi,
506         enum surface_pixel_format format,
507         union dc_tiling_info *tiling_info,
508         struct plane_size *plane_size,
509         enum dc_rotation_angle rotation,
510         struct dc_plane_dcc_param *dcc,
511         bool horizontal_mirror)
512 {
513         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
514         REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);
515
516         program_tiling(dce_mi, tiling_info);
517         program_size_and_rotation(dce_mi, rotation, plane_size);
518
519         if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
520                 format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
521                 program_grph_pixel_format(dce_mi, format);
522 }
523
524 static uint32_t get_dmif_switch_time_us(
525         uint32_t h_total,
526         uint32_t v_total,
527         uint32_t pix_clk_khz)
528 {
529         uint32_t frame_time;
530         uint32_t pixels_per_second;
531         uint32_t pixels_per_frame;
532         uint32_t refresh_rate;
533         const uint32_t us_in_sec = 1000000;
534         const uint32_t min_single_frame_time_us = 30000;
535         /*return double of frame time*/
536         const uint32_t single_frame_time_multiplier = 2;
537
538         if (!h_total || v_total || !pix_clk_khz)
539                 return single_frame_time_multiplier * min_single_frame_time_us;
540
541         /*TODO: should we use pixel format normalized pixel clock here?*/
542         pixels_per_second = pix_clk_khz * 1000;
543         pixels_per_frame = h_total * v_total;
544
545         if (!pixels_per_second || !pixels_per_frame) {
546                 /* avoid division by zero */
547                 ASSERT(pixels_per_frame);
548                 ASSERT(pixels_per_second);
549                 return single_frame_time_multiplier * min_single_frame_time_us;
550         }
551
552         refresh_rate = pixels_per_second / pixels_per_frame;
553
554         if (!refresh_rate) {
555                 /* avoid division by zero*/
556                 ASSERT(refresh_rate);
557                 return single_frame_time_multiplier * min_single_frame_time_us;
558         }
559
560         frame_time = us_in_sec / refresh_rate;
561
562         if (frame_time < min_single_frame_time_us)
563                 frame_time = min_single_frame_time_us;
564
565         frame_time *= single_frame_time_multiplier;
566
567         return frame_time;
568 }
569
570 static void dce_mi_allocate_dmif(
571         struct mem_input *mi,
572         uint32_t h_total,
573         uint32_t v_total,
574         uint32_t pix_clk_khz,
575         uint32_t total_stream_num)
576 {
577         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
578         const uint32_t retry_delay = 10;
579         uint32_t retry_count = get_dmif_switch_time_us(
580                         h_total,
581                         v_total,
582                         pix_clk_khz) / retry_delay;
583
584         uint32_t pix_dur;
585         uint32_t buffers_allocated;
586         uint32_t dmif_buffer_control;
587
588         dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
589                         DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
590
591         if (buffers_allocated == 2)
592                 return;
593
594         REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
595                         DMIF_BUFFERS_ALLOCATED, 2);
596
597         REG_WAIT(DMIF_BUFFER_CONTROL,
598                         DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
599                         retry_delay, retry_count);
600
601         if (pix_clk_khz != 0) {
602                 pix_dur = 1000000000ULL / pix_clk_khz;
603
604                 REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1,
605                         PIXEL_DURATION, pix_dur);
606         }
607
608         if (dce_mi->wa.single_head_rdreq_dmif_limit) {
609                 uint32_t enable =  (total_stream_num > 1) ? 0 :
610                                 dce_mi->wa.single_head_rdreq_dmif_limit;
611
612                 REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
613                                 ENABLE, enable);
614         }
615 }
616
617 static void dce_mi_free_dmif(
618                 struct mem_input *mi,
619                 uint32_t total_stream_num)
620 {
621         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
622         uint32_t buffers_allocated;
623         uint32_t dmif_buffer_control;
624
625         dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
626                         DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
627
628         if (buffers_allocated == 0)
629                 return;
630
631         REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
632                         DMIF_BUFFERS_ALLOCATED, 0);
633
634         REG_WAIT(DMIF_BUFFER_CONTROL,
635                         DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
636                         10, 3500);
637
638         if (dce_mi->wa.single_head_rdreq_dmif_limit) {
639                 uint32_t enable =  (total_stream_num > 1) ? 0 :
640                                 dce_mi->wa.single_head_rdreq_dmif_limit;
641
642                 REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
643                                 ENABLE, enable);
644         }
645 }
646
647
648 static void program_sec_addr(
649         struct dce_mem_input *dce_mi,
650         PHYSICAL_ADDRESS_LOC address)
651 {
652         /*high register MUST be programmed first*/
653         REG_SET(GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
654                 GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
655                 address.high_part);
656
657         REG_SET_2(GRPH_SECONDARY_SURFACE_ADDRESS, 0,
658                 GRPH_SECONDARY_SURFACE_ADDRESS, address.low_part >> 8,
659                 GRPH_SECONDARY_DFQ_ENABLE, 0);
660 }
661
662 static void program_pri_addr(
663         struct dce_mem_input *dce_mi,
664         PHYSICAL_ADDRESS_LOC address)
665 {
666         /*high register MUST be programmed first*/
667         REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
668                 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
669                 address.high_part);
670
671         REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS, 0,
672                 GRPH_PRIMARY_SURFACE_ADDRESS,
673                 address.low_part >> 8);
674 }
675
676
677 static bool dce_mi_is_flip_pending(struct mem_input *mem_input)
678 {
679         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
680         uint32_t update_pending;
681
682         REG_GET(GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING, &update_pending);
683         if (update_pending)
684                 return true;
685
686         mem_input->current_address = mem_input->request_address;
687         return false;
688 }
689
690 static bool dce_mi_program_surface_flip_and_addr(
691         struct mem_input *mem_input,
692         const struct dc_plane_address *address,
693         bool flip_immediate)
694 {
695         struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
696
697         REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 1);
698
699         REG_UPDATE(
700                 GRPH_FLIP_CONTROL,
701                 GRPH_SURFACE_UPDATE_H_RETRACE_EN, flip_immediate ? 1 : 0);
702
703         switch (address->type) {
704         case PLN_ADDR_TYPE_GRAPHICS:
705                 if (address->grph.addr.quad_part == 0)
706                         break;
707                 program_pri_addr(dce_mi, address->grph.addr);
708                 break;
709         case PLN_ADDR_TYPE_GRPH_STEREO:
710                 if (address->grph_stereo.left_addr.quad_part == 0 ||
711                     address->grph_stereo.right_addr.quad_part == 0)
712                         break;
713                 program_pri_addr(dce_mi, address->grph_stereo.left_addr);
714                 program_sec_addr(dce_mi, address->grph_stereo.right_addr);
715                 break;
716         default:
717                 /* not supported */
718                 BREAK_TO_DEBUGGER();
719                 break;
720         }
721
722         mem_input->request_address = *address;
723
724         if (flip_immediate)
725                 mem_input->current_address = *address;
726
727         REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 0);
728
729         return true;
730 }
731
732 static const struct mem_input_funcs dce_mi_funcs = {
733         .mem_input_program_display_marks = dce_mi_program_display_marks,
734         .allocate_mem_input = dce_mi_allocate_dmif,
735         .free_mem_input = dce_mi_free_dmif,
736         .mem_input_program_surface_flip_and_addr =
737                         dce_mi_program_surface_flip_and_addr,
738         .mem_input_program_pte_vm = dce_mi_program_pte_vm,
739         .mem_input_program_surface_config =
740                         dce_mi_program_surface_config,
741         .mem_input_is_flip_pending = dce_mi_is_flip_pending
742 };
743
744 static const struct mem_input_funcs dce112_mi_funcs = {
745         .mem_input_program_display_marks = dce112_mi_program_display_marks,
746         .allocate_mem_input = dce_mi_allocate_dmif,
747         .free_mem_input = dce_mi_free_dmif,
748         .mem_input_program_surface_flip_and_addr =
749                         dce_mi_program_surface_flip_and_addr,
750         .mem_input_program_pte_vm = dce_mi_program_pte_vm,
751         .mem_input_program_surface_config =
752                         dce_mi_program_surface_config,
753         .mem_input_is_flip_pending = dce_mi_is_flip_pending
754 };
755
756 static const struct mem_input_funcs dce120_mi_funcs = {
757         .mem_input_program_display_marks = dce120_mi_program_display_marks,
758         .allocate_mem_input = dce_mi_allocate_dmif,
759         .free_mem_input = dce_mi_free_dmif,
760         .mem_input_program_surface_flip_and_addr =
761                         dce_mi_program_surface_flip_and_addr,
762         .mem_input_program_pte_vm = dce_mi_program_pte_vm,
763         .mem_input_program_surface_config =
764                         dce_mi_program_surface_config,
765         .mem_input_is_flip_pending = dce_mi_is_flip_pending
766 };
767
768 void dce_mem_input_construct(
769         struct dce_mem_input *dce_mi,
770         struct dc_context *ctx,
771         int inst,
772         const struct dce_mem_input_registers *regs,
773         const struct dce_mem_input_shift *mi_shift,
774         const struct dce_mem_input_mask *mi_mask)
775 {
776         dce_mi->base.ctx = ctx;
777
778         dce_mi->base.inst = inst;
779         dce_mi->base.funcs = &dce_mi_funcs;
780
781         dce_mi->regs = regs;
782         dce_mi->shifts = mi_shift;
783         dce_mi->masks = mi_mask;
784 }
785
786 void dce112_mem_input_construct(
787         struct dce_mem_input *dce_mi,
788         struct dc_context *ctx,
789         int inst,
790         const struct dce_mem_input_registers *regs,
791         const struct dce_mem_input_shift *mi_shift,
792         const struct dce_mem_input_mask *mi_mask)
793 {
794         dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
795         dce_mi->base.funcs = &dce112_mi_funcs;
796 }
797
798 void dce120_mem_input_construct(
799         struct dce_mem_input *dce_mi,
800         struct dc_context *ctx,
801         int inst,
802         const struct dce_mem_input_registers *regs,
803         const struct dce_mem_input_shift *mi_shift,
804         const struct dce_mem_input_mask *mi_mask)
805 {
806         dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
807         dce_mi->base.funcs = &dce120_mi_funcs;
808 }