drm/amd/display: Add dependant changes for DCN32/321
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn32 / dcn32_hwseq.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
27 #include "dm_services.h"
28 #include "dm_helpers.h"
29 #include "core_types.h"
30 #include "resource.h"
31 #include "dccg.h"
32 #include "dce/dce_hwseq.h"
33 #include "dcn30/dcn30_cm_common.h"
34 #include "reg_helper.h"
35 #include "abm.h"
36 #include "hubp.h"
37 #include "dchubbub.h"
38 #include "timing_generator.h"
39 #include "opp.h"
40 #include "ipp.h"
41 #include "mpc.h"
42 #include "mcif_wb.h"
43 #include "dc_dmub_srv.h"
44 #include "link_hwss.h"
45 #include "dpcd_defs.h"
46 #include "dcn32_hwseq.h"
47 #include "clk_mgr.h"
48 #include "dsc.h"
49 #include "dcn20/dcn20_optc.h"
50
51 #define DC_LOGGER_INIT(logger)
52
53 #define CTX \
54         hws->ctx
55 #define REG(reg)\
56         hws->regs->reg
57 #define DC_LOGGER \
58                 dc->ctx->logger
59
60
61 #undef FN
62 #define FN(reg_name, field_name) \
63         hws->shifts->field_name, hws->masks->field_name
64
65 void dcn32_dsc_pg_control(
66                 struct dce_hwseq *hws,
67                 unsigned int dsc_inst,
68                 bool power_on)
69 {
70         uint32_t power_gate = power_on ? 0 : 1;
71         uint32_t pwr_status = power_on ? 0 : 2;
72         uint32_t org_ip_request_cntl = 0;
73
74         if (hws->ctx->dc->debug.disable_dsc_power_gate)
75                 return;
76
77         REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
78         if (org_ip_request_cntl == 0)
79                 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
80
81         switch (dsc_inst) {
82         case 0: /* DSC0 */
83                 REG_UPDATE(DOMAIN16_PG_CONFIG,
84                                 DOMAIN_POWER_GATE, power_gate);
85
86                 REG_WAIT(DOMAIN16_PG_STATUS,
87                                 DOMAIN_PGFSM_PWR_STATUS, pwr_status,
88                                 1, 1000);
89                 break;
90         case 1: /* DSC1 */
91                 REG_UPDATE(DOMAIN17_PG_CONFIG,
92                                 DOMAIN_POWER_GATE, power_gate);
93
94                 REG_WAIT(DOMAIN17_PG_STATUS,
95                                 DOMAIN_PGFSM_PWR_STATUS, pwr_status,
96                                 1, 1000);
97                 break;
98         case 2: /* DSC2 */
99                 REG_UPDATE(DOMAIN18_PG_CONFIG,
100                                 DOMAIN_POWER_GATE, power_gate);
101
102                 REG_WAIT(DOMAIN18_PG_STATUS,
103                                 DOMAIN_PGFSM_PWR_STATUS, pwr_status,
104                                 1, 1000);
105                 break;
106         case 3: /* DSC3 */
107                 REG_UPDATE(DOMAIN19_PG_CONFIG,
108                                 DOMAIN_POWER_GATE, power_gate);
109
110                 REG_WAIT(DOMAIN19_PG_STATUS,
111                                 DOMAIN_PGFSM_PWR_STATUS, pwr_status,
112                                 1, 1000);
113                 break;
114         default:
115                 BREAK_TO_DEBUGGER();
116                 break;
117         }
118
119         if (org_ip_request_cntl == 0)
120                 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
121 }
122
123
124 void dcn32_enable_power_gating_plane(
125         struct dce_hwseq *hws,
126         bool enable)
127 {
128         bool force_on = true; /* disable power gating */
129
130         if (enable)
131                 force_on = false;
132
133         /* DCHUBP0/1/2/3 */
134         REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
135         REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
136         REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
137         REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
138
139         /* DCS0/1/2/3 */
140         REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
141         REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
142         REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
143         REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
144 }
145
146 void dcn32_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
147 {
148         uint32_t power_gate = power_on ? 0 : 1;
149         uint32_t pwr_status = power_on ? 0 : 2;
150
151         if (hws->ctx->dc->debug.disable_hubp_power_gate)
152                 return;
153
154         if (REG(DOMAIN0_PG_CONFIG) == 0)
155                 return;
156
157         switch (hubp_inst) {
158         case 0:
159                 REG_SET(DOMAIN0_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
160                 REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
161                 break;
162         case 1:
163                 REG_SET(DOMAIN1_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
164                 REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
165                 break;
166         case 2:
167                 REG_SET(DOMAIN2_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
168                 REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
169                 break;
170         case 3:
171                 REG_SET(DOMAIN3_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
172                 REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
173                 break;
174         default:
175                 BREAK_TO_DEBUGGER();
176                 break;
177         }
178 }
179
180 static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
181 {
182         int i;
183
184     /* First, check no-memory-request case */
185         for (i = 0; i < dc->current_state->stream_count; i++) {
186                 if (dc->current_state->stream_status[i].plane_count)
187                         /* Fail eligibility on a visible stream */
188                         break;
189         }
190
191         if (i == dc->current_state->stream_count)
192                 return true;
193
194         return false;
195 }
196
197 /* This function takes in the start address and surface size to be cached in CAB
198  * and calculates the total number of cache lines required to store the surface.
199  * The number of cache lines used for each surface is calculated independently of
200  * one another. For example, if there is a primary surface(1), meta surface(2), and
201  * cursor(3), this function should be called 3 times to calculate the number of cache
202  * lines used for each of those surfaces.
203  */
204 static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_size, uint64_t start_address)
205 {
206         uint32_t lines_used = 1;
207         uint32_t num_cached_bytes = 0;
208         uint32_t remaining_size = 0;
209         uint32_t cache_line_size = dc->caps.cache_line_size;
210
211         /* 1. Calculate surface size minus the number of bytes stored
212          * in the first cache line (all bytes in first cache line might
213          * not be fully used).
214          */
215         num_cached_bytes = cache_line_size - (start_address % cache_line_size);
216         remaining_size = surface_size - num_cached_bytes;
217
218         /* 2. Calculate number of cache lines that will be fully used with
219          * the remaining number of bytes to be stored.
220          */
221         lines_used += (remaining_size / cache_line_size);
222
223         /* 3. Check if we need an extra line due to the remaining size not being
224          * a multiple of CACHE_LINE_SIZE.
225          */
226         if (remaining_size % cache_line_size > 0)
227                 lines_used++;
228
229         return lines_used;
230 }
231
232 /* This function loops through every surface that needs to be cached in CAB for SS,
233  * and calculates the total number of ways required to store all surfaces (primary,
234  * meta, cursor).
235  */
236 static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
237 {
238         uint8_t i, j;
239         struct dc_stream_state *stream = NULL;
240         struct dc_plane_state *plane = NULL;
241         uint32_t surface_size = 0;
242         uint32_t cursor_size = 0;
243         uint32_t cache_lines_used = 0;
244         uint32_t total_lines = 0;
245         uint32_t lines_per_way = 0;
246         uint32_t num_ways = 0;
247
248         for (i = 0; i < ctx->stream_count; i++) {
249                 stream = ctx->streams[i];
250
251                 // Don't include PSR surface in the total surface size for CAB allocation
252                 if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
253                         continue;
254
255                 if (ctx->stream_status[i].plane_count == 0)
256                         continue;
257
258                 // For each stream, loop through each plane to calculate the number of cache
259                 // lines required to store the surface in CAB
260                 for (j = 0; j < ctx->stream_status[i].plane_count; j++) {
261                         plane = ctx->stream_status[i].plane_states[j];
262
263                         // Calculate total surface size
264                         surface_size = plane->plane_size.surface_pitch *
265                                         plane->plane_size.surface_size.height *
266                                         (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
267
268                         // Convert surface size + starting address to number of cache lines required
269                         // (alignment accounted for)
270                         cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
271                                         plane->address.grph.addr.quad_part);
272
273                         if (plane->address.grph.meta_addr.quad_part) {
274                                 // Meta surface
275                                 cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
276                                                 plane->address.grph.meta_addr.quad_part);
277                         }
278                 }
279
280                 // Include cursor size for CAB allocation
281                 if (stream->cursor_position.enable && plane->address.grph.cursor_cache_addr.quad_part) {
282                         cursor_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size;
283                         switch (stream->cursor_attributes.color_format) {
284                         case CURSOR_MODE_MONO:
285                                 cursor_size /= 2;
286                                 break;
287                         case CURSOR_MODE_COLOR_1BIT_AND:
288                         case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
289                         case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
290                                 cursor_size *= 4;
291                                 break;
292
293                         case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
294                         case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
295                                 cursor_size *= 8;
296                                 break;
297                         }
298                         cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
299                                         plane->address.grph.cursor_cache_addr.quad_part);
300                 }
301         }
302
303         // Convert number of cache lines required to number of ways
304         total_lines = dc->caps.max_cab_allocation_bytes / dc->caps.cache_line_size;
305         lines_per_way = total_lines / dc->caps.cache_num_ways;
306         num_ways = cache_lines_used / lines_per_way;
307
308         if (cache_lines_used % lines_per_way > 0)
309                 num_ways++;
310
311         return num_ways;
312 }
313
314 bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
315 {
316         union dmub_rb_cmd cmd;
317         uint8_t ways;
318
319         if (!dc->ctx->dmub_srv)
320                 return false;
321
322         if (enable) {
323                 if (dc->current_state) {
324
325                         /* 1. Check no memory request case for CAB.
326                          * If no memory request case, send CAB_ACTION NO_DF_REQ DMUB message
327                          */
328                         if (dcn32_check_no_memory_request_for_cab(dc)) {
329                                 /* Enable no-memory-requests case */
330                                 memset(&cmd, 0, sizeof(cmd));
331                                 cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
332                                 cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_DCN_REQ;
333                                 cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
334
335                                 dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
336                                 dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
337
338                                 return true;
339                         }
340
341                         /* 2. Check if all surfaces can fit in CAB.
342                          * If surfaces can fit into CAB, send CAB_ACTION_ALLOW DMUB message
343                          * and configure HUBP's to fetch from MALL
344                          */
345                         ways = dcn32_calculate_cab_allocation(dc, dc->current_state);
346                         if (ways <= dc->caps.cache_num_ways) {
347                                 memset(&cmd, 0, sizeof(cmd));
348                                 cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
349                                 cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
350                                 cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
351                                 cmd.cab.cab_alloc_ways = ways;
352
353                                 dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
354                                 dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
355
356                                 return true;
357                         }
358
359                 }
360                 return false;
361         }
362
363         /* Disable CAB */
364         memset(&cmd, 0, sizeof(cmd));
365         cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
366         cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_IDLE_OPTIMIZATION;
367         cmd.cab.header.payload_bytes =
368                         sizeof(cmd.cab) - sizeof(cmd.cab.header);
369
370         dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
371         dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
372         dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
373
374         return false;
375 }
376
377 /* Send DMCUB message with SubVP pipe info
378  * - For each pipe in context, populate payload with required SubVP information
379  *   if the pipe is using SubVP for MCLK switch
380  * - This function must be called while the DMUB HW lock is acquired by driver
381  */
382 void dcn32_commit_subvp_config(struct dc *dc, struct dc_state *context)
383 {
384 /*
385         int i;
386         bool enable_subvp = false;
387
388         if (!dc->ctx || !dc->ctx->dmub_srv)
389                 return;
390
391         for (i = 0; i < dc->res_pool->pipe_count; i++) {
392                 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
393
394                 if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.paired_stream &&
395                                 pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN) {
396                         // There is at least 1 SubVP pipe, so enable SubVP
397                         enable_subvp = true;
398                         break;
399                 }
400         }
401         dc_dmub_setup_subvp_dmub_command(dc, context, enable_subvp);
402 */
403 }
404
405 static bool dcn32_set_mpc_shaper_3dlut(
406         struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream)
407 {
408         struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
409         int mpcc_id = pipe_ctx->plane_res.hubp->inst;
410         struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
411         bool result = false;
412
413         const struct pwl_params *shaper_lut = NULL;
414         //get the shaper lut params
415         if (stream->func_shaper) {
416                 if (stream->func_shaper->type == TF_TYPE_HWPWL)
417                         shaper_lut = &stream->func_shaper->pwl;
418                 else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
419                         cm_helper_translate_curve_to_hw_format(
420                                         stream->func_shaper,
421                                         &dpp_base->shaper_params, true);
422                         shaper_lut = &dpp_base->shaper_params;
423                 }
424         }
425
426         if (stream->lut3d_func &&
427                 stream->lut3d_func->state.bits.initialized == 1) {
428
429                 result = mpc->funcs->program_3dlut(mpc,
430                                                                 &stream->lut3d_func->lut_3d,
431                                                                 mpcc_id);
432
433                 result = mpc->funcs->program_shaper(mpc,
434                                                                 shaper_lut,
435                                                                 mpcc_id);
436         }
437
438         return result;
439 }
440 bool dcn32_set_output_transfer_func(struct dc *dc,
441                                 struct pipe_ctx *pipe_ctx,
442                                 const struct dc_stream_state *stream)
443 {
444         int mpcc_id = pipe_ctx->plane_res.hubp->inst;
445         struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
446         struct pwl_params *params = NULL;
447         bool ret = false;
448
449         /* program OGAM or 3DLUT only for the top pipe*/
450         if (pipe_ctx->top_pipe == NULL) {
451                 /*program shaper and 3dlut in MPC*/
452                 ret = dcn32_set_mpc_shaper_3dlut(pipe_ctx, stream);
453                 if (ret == false && mpc->funcs->set_output_gamma && stream->out_transfer_func) {
454                         if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
455                                 params = &stream->out_transfer_func->pwl;
456                         else if (pipe_ctx->stream->out_transfer_func->type ==
457                                         TF_TYPE_DISTRIBUTED_POINTS &&
458                                         cm3_helper_translate_curve_to_hw_format(
459                                         stream->out_transfer_func,
460                                         &mpc->blender_params, false))
461                                 params = &mpc->blender_params;
462                  /* there are no ROM LUTs in OUTGAM */
463                 if (stream->out_transfer_func->type == TF_TYPE_PREDEFINED)
464                         BREAK_TO_DEBUGGER();
465                 }
466         }
467
468         mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
469         return ret;
470 }
471
472 /* Program P-State force value according to if pipe is using SubVP or not:
473  * 1. Reset P-State force on all pipes first
474  * 2. For each main pipe, force P-State disallow (P-State allow moderated by DMUB)
475  */
476 void dcn32_subvp_update_force_pstate(struct dc *dc, struct dc_state *context)
477 {
478         int i;
479         int num_subvp = 0;
480         /* Unforce p-state for each pipe
481          */
482         for (i = 0; i < dc->res_pool->pipe_count; i++) {
483                 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
484                 struct hubp *hubp = pipe->plane_res.hubp;
485
486                 if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
487                         hubp->funcs->hubp_update_force_pstate_disallow(hubp, false);
488                 if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN)
489                         num_subvp++;
490         }
491
492         if (num_subvp == 0)
493                 return;
494
495         /* Loop through each pipe -- for each subvp main pipe force p-state allow equal to false.
496          */
497         for (i = 0; i < dc->res_pool->pipe_count; i++) {
498                 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
499
500                 if (pipe->stream && pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
501                         struct hubp *hubp = pipe->plane_res.hubp;
502
503                         if (hubp && hubp->funcs->hubp_update_force_pstate_disallow)
504                                 hubp->funcs->hubp_update_force_pstate_disallow(hubp, true);
505                 }
506         }
507 }
508
509 /* Update MALL_SEL register based on if pipe / plane
510  * is a phantom pipe, main pipe, and if using MALL
511  * for SS.
512  */
513 void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)
514 {
515         int i;
516         unsigned int num_ways = dcn32_calculate_cab_allocation(dc, context);
517
518         for (i = 0; i < dc->res_pool->pipe_count; i++) {
519                 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
520                 struct hubp *hubp = pipe->plane_res.hubp;
521
522                 if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) {
523                         if (pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
524                                         hubp->funcs->hubp_update_mall_sel(hubp, 1);
525                         } else {
526                                 hubp->funcs->hubp_update_mall_sel(hubp,
527                                         num_ways <= dc->caps.cache_num_ways &&
528                                         pipe->stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED ? 2 : 0);
529                         }
530                 }
531         }
532 }
533
534 /* Program the sub-viewport pipe configuration after the main / phantom pipes
535  * have been programmed in hardware.
536  * 1. Update force P-State for all the main pipes (disallow P-state)
537  * 2. Update MALL_SEL register
538  * 3. Program FORCE_ONE_ROW_FOR_FRAME for main subvp pipes
539  */
540 void dcn32_program_mall_pipe_config(struct dc *dc, struct dc_state *context)
541 {
542         int i;
543         struct dce_hwseq *hws = dc->hwseq;
544         // Update force P-state for each pipe accordingly
545         if (hws && hws->funcs.subvp_update_force_pstate)
546                 hws->funcs.subvp_update_force_pstate(dc, context);
547
548         // Update MALL_SEL register for each pipe
549         if (hws && hws->funcs.update_mall_sel)
550                 hws->funcs.update_mall_sel(dc, context);
551
552         // Program FORCE_ONE_ROW_FOR_FRAME and CURSOR_REQ_MODE for main subvp pipes
553         for (i = 0; i < dc->res_pool->pipe_count; i++) {
554                 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
555                 struct hubp *hubp = pipe->plane_res.hubp;
556
557                 if (pipe->stream && hubp && hubp->funcs->hubp_prepare_subvp_buffering) {
558                         if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
559                                 hubp->funcs->hubp_prepare_subvp_buffering(hubp, true);
560                         } else {
561                                 hubp->funcs->hubp_prepare_subvp_buffering(hubp, false);
562                         }
563                 }
564         }
565 }
566
567 void dcn32_init_hw(struct dc *dc)
568 {
569         struct abm **abms = dc->res_pool->multiple_abms;
570         struct dce_hwseq *hws = dc->hwseq;
571         struct dc_bios *dcb = dc->ctx->dc_bios;
572         struct resource_pool *res_pool = dc->res_pool;
573         int i;
574         int edp_num;
575         uint32_t backlight = MAX_BACKLIGHT_LEVEL;
576
577         dc->debug.disable_idle_power_optimizations = true;
578         if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
579                 dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
580
581         // Initialize the dccg
582         if (res_pool->dccg->funcs->dccg_init)
583                 res_pool->dccg->funcs->dccg_init(res_pool->dccg);
584
585         if (!dcb->funcs->is_accelerated_mode(dcb)) {
586                 hws->funcs.bios_golden_init(dc);
587                 hws->funcs.disable_vga(dc->hwseq);
588         }
589
590         // Set default OPTC memory power states
591         if (dc->debug.enable_mem_low_power.bits.optc) {
592                 // Shutdown when unassigned and light sleep in VBLANK
593                 REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
594         }
595
596         if (dc->debug.enable_mem_low_power.bits.vga) {
597                 // Power down VGA memory
598                 REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
599         }
600
601         if (dc->ctx->dc_bios->fw_info_valid) {
602                 res_pool->ref_clocks.xtalin_clock_inKhz =
603                                 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
604
605                 if (res_pool->dccg && res_pool->hubbub) {
606                         (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
607                                         dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
608                                         &res_pool->ref_clocks.dccg_ref_clock_inKhz);
609
610                         (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
611                                         res_pool->ref_clocks.dccg_ref_clock_inKhz,
612                                         &res_pool->ref_clocks.dchub_ref_clock_inKhz);
613                 } else {
614                         // Not all ASICs have DCCG sw component
615                         res_pool->ref_clocks.dccg_ref_clock_inKhz =
616                                         res_pool->ref_clocks.xtalin_clock_inKhz;
617                         res_pool->ref_clocks.dchub_ref_clock_inKhz =
618                                         res_pool->ref_clocks.xtalin_clock_inKhz;
619                 }
620         } else
621                 ASSERT_CRITICAL(false);
622
623         for (i = 0; i < dc->link_count; i++) {
624                 /* Power up AND update implementation according to the
625                  * required signal (which may be different from the
626                  * default signal on connector).
627                  */
628                 struct dc_link *link = dc->links[i];
629
630                 link->link_enc->funcs->hw_init(link->link_enc);
631
632                 /* Check for enabled DIG to identify enabled display */
633                 if (link->link_enc->funcs->is_dig_enabled &&
634                         link->link_enc->funcs->is_dig_enabled(link->link_enc))
635                         link->link_status.link_active = true;
636         }
637
638         /* Power gate DSCs */
639         for (i = 0; i < res_pool->res_cap->num_dsc; i++)
640                 if (hws->funcs.dsc_pg_control != NULL)
641                         hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
642
643         /* we want to turn off all dp displays before doing detection */
644         dc_link_blank_all_dp_displays(dc);
645
646         /* If taking control over from VBIOS, we may want to optimize our first
647          * mode set, so we need to skip powering down pipes until we know which
648          * pipes we want to use.
649          * Otherwise, if taking control is not possible, we need to power
650          * everything down.
651          */
652         if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.seamless_boot_edp_requested) {
653                 hws->funcs.init_pipes(dc, dc->current_state);
654                 if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
655                         dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
656                                         !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
657         }
658
659         /* In headless boot cases, DIG may be turned
660          * on which causes HW/SW discrepancies.
661          * To avoid this, power down hardware on boot
662          * if DIG is turned on and seamless boot not enabled
663          */
664         if (dc->config.seamless_boot_edp_requested) {
665                 struct dc_link *edp_links[MAX_NUM_EDP];
666                 struct dc_link *edp_link;
667
668                 get_edp_links(dc, edp_links, &edp_num);
669                 if (edp_num) {
670                         for (i = 0; i < edp_num; i++) {
671                                 edp_link = edp_links[i];
672                                 if (edp_link->link_enc->funcs->is_dig_enabled &&
673                                                 edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
674                                                 dc->hwss.edp_backlight_control &&
675                                                 dc->hwss.power_down &&
676                                                 dc->hwss.edp_power_control) {
677                                         dc->hwss.edp_backlight_control(edp_link, false);
678                                         dc->hwss.power_down(dc);
679                                         dc->hwss.edp_power_control(edp_link, false);
680                                 }
681                         }
682                 } else {
683                         for (i = 0; i < dc->link_count; i++) {
684                                 struct dc_link *link = dc->links[i];
685
686                                 if (link->link_enc->funcs->is_dig_enabled &&
687                                                 link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
688                                                 dc->hwss.power_down) {
689                                         dc->hwss.power_down(dc);
690                                         break;
691                                 }
692
693                         }
694                 }
695         }
696
697         for (i = 0; i < res_pool->audio_count; i++) {
698                 struct audio *audio = res_pool->audios[i];
699
700                 audio->funcs->hw_init(audio);
701         }
702
703         for (i = 0; i < dc->link_count; i++) {
704                 struct dc_link *link = dc->links[i];
705
706                 if (link->panel_cntl)
707                         backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
708         }
709
710         for (i = 0; i < dc->res_pool->pipe_count; i++) {
711                 if (abms[i] != NULL && abms[i]->funcs != NULL)
712                         abms[i]->funcs->abm_init(abms[i], backlight);
713         }
714
715         /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
716         REG_WRITE(DIO_MEM_PWR_CTRL, 0);
717
718         if (!dc->debug.disable_clock_gate) {
719                 /* enable all DCN clock gating */
720                 REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
721
722                 REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
723
724                 REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
725         }
726         if (hws->funcs.enable_power_gating_plane)
727                 hws->funcs.enable_power_gating_plane(dc->hwseq, true);
728
729         if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
730                 dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
731
732         if (dc->clk_mgr->funcs->notify_wm_ranges)
733                 dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
734
735         if (dc->clk_mgr->funcs->set_hard_max_memclk)
736                 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
737
738         if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
739                 dc->res_pool->hubbub->funcs->force_pstate_change_control(
740                                 dc->res_pool->hubbub, false, false);
741
742         if (dc->res_pool->hubbub->funcs->init_crb)
743                 dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
744
745         // Get DMCUB capabilities
746     if (dc->ctx->dmub_srv) {
747         dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub);
748         dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
749     }
750 }
751
752 static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
753                 int opp_cnt)
754 {
755         bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
756         int flow_ctrl_cnt;
757
758         if (opp_cnt >= 2)
759                 hblank_halved = true;
760
761         flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
762                         stream->timing.h_border_left -
763                         stream->timing.h_border_right;
764
765         if (hblank_halved)
766                 flow_ctrl_cnt /= 2;
767
768         /* ODM combine 4:1 case */
769         if (opp_cnt == 4)
770                 flow_ctrl_cnt /= 2;
771
772         return flow_ctrl_cnt;
773 }
774
775 static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
776 {
777         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
778         struct dc_stream_state *stream = pipe_ctx->stream;
779         struct pipe_ctx *odm_pipe;
780         int opp_cnt = 1;
781
782         ASSERT(dsc);
783         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
784                 opp_cnt++;
785
786         if (enable) {
787                 struct dsc_config dsc_cfg;
788                 struct dsc_optc_config dsc_optc_cfg;
789                 enum optc_dsc_mode optc_dsc_mode;
790
791                 /* Enable DSC hw block */
792                 dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
793                 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
794                 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
795                 dsc_cfg.color_depth = stream->timing.display_color_depth;
796                 dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
797                 dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
798                 ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
799                 dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
800
801                 dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
802                 dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
803                 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
804                         struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
805
806                         ASSERT(odm_dsc);
807                         odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
808                         odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
809                 }
810                 dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
811                 dsc_cfg.pic_width *= opp_cnt;
812
813                 optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
814
815                 /* Enable DSC in OPTC */
816                 DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
817                 pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
818                                                         optc_dsc_mode,
819                                                         dsc_optc_cfg.bytes_per_pixel,
820                                                         dsc_optc_cfg.slice_width);
821         } else {
822                 /* disable DSC in OPTC */
823                 pipe_ctx->stream_res.tg->funcs->set_dsc_config(
824                                 pipe_ctx->stream_res.tg,
825                                 OPTC_DSC_DISABLED, 0, 0);
826
827                 /* disable DSC block */
828                 dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
829                 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
830                         ASSERT(odm_pipe->stream_res.dsc);
831                         odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
832                 }
833         }
834 }
835
836 void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
837 {
838         struct pipe_ctx *odm_pipe;
839         int opp_cnt = 1;
840         int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst };
841         bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
842         struct mpc_dwb_flow_control flow_control;
843         struct mpc *mpc = dc->res_pool->mpc;
844         int i;
845
846         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
847                 opp_inst[opp_cnt] = odm_pipe->stream_res.opp->inst;
848                 opp_cnt++;
849         }
850
851         if (opp_cnt > 1)
852                 pipe_ctx->stream_res.tg->funcs->set_odm_combine(
853                                 pipe_ctx->stream_res.tg,
854                                 opp_inst, opp_cnt,
855                                 &pipe_ctx->stream->timing);
856         else
857                 pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
858                                 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
859
860         rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
861         flow_control.flow_ctrl_mode = 0;
862         flow_control.flow_ctrl_cnt0 = 0x80;
863         flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
864         if (mpc->funcs->set_out_rate_control) {
865                 for (i = 0; i < opp_cnt; ++i) {
866                         mpc->funcs->set_out_rate_control(
867                                         mpc, opp_inst[i],
868                                         true,
869                                         rate_control_2x_pclk,
870                                         &flow_control);
871                 }
872         }
873
874         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
875                 odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
876                                 odm_pipe->stream_res.opp,
877                                 true);
878         }
879
880         // Don't program pixel clock after link is already enabled
881 /*      if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
882                         pipe_ctx->clock_source,
883                         &pipe_ctx->stream_res.pix_clk_params,
884                         &pipe_ctx->pll_settings)) {
885                 BREAK_TO_DEBUGGER();
886         }*/
887
888         if (pipe_ctx->stream_res.dsc)
889                 update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
890 }
891