2 * Copyright 2018 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include "dm_services.h"
30 #include "include/irq_service_interface.h"
31 #include "dcn20/dcn20_resource.h"
34 #include "dcn10/dcn10_hubp.h"
35 #include "dcn10/dcn10_ipp.h"
36 #include "dcn20/dcn20_hubbub.h"
37 #include "dcn20/dcn20_mpc.h"
38 #include "dcn20/dcn20_hubp.h"
39 #include "dcn21_hubp.h"
40 #include "irq/dcn21/irq_service_dcn21.h"
41 #include "dcn20/dcn20_dpp.h"
42 #include "dcn20/dcn20_optc.h"
43 #include "dcn21/dcn21_hwseq.h"
44 #include "dce110/dce110_hw_sequencer.h"
45 #include "dcn20/dcn20_opp.h"
46 #include "dcn20/dcn20_dsc.h"
47 #include "dcn21/dcn21_link_encoder.h"
48 #include "dcn20/dcn20_stream_encoder.h"
49 #include "dce/dce_clock_source.h"
50 #include "dce/dce_audio.h"
51 #include "dce/dce_hwseq.h"
52 #include "virtual/virtual_stream_encoder.h"
53 #include "dce110/dce110_resource.h"
54 #include "dml/display_mode_vba.h"
55 #include "dcn20/dcn20_dccg.h"
56 #include "dcn21_hubbub.h"
57 #include "dcn10/dcn10_resource.h"
59 #include "dcn20/dcn20_dwb.h"
60 #include "dcn20/dcn20_mmhubbub.h"
62 #include "renoir_ip_offset.h"
63 #include "dcn/dcn_2_1_0_offset.h"
64 #include "dcn/dcn_2_1_0_sh_mask.h"
66 #include "nbio/nbio_7_0_offset.h"
68 #include "mmhub/mmhub_2_0_0_offset.h"
69 #include "mmhub/mmhub_2_0_0_sh_mask.h"
71 #include "reg_helper.h"
72 #include "dce/dce_abm.h"
73 #include "dce/dce_dmcu.h"
74 #include "dce/dce_aux.h"
75 #include "dce/dce_i2c.h"
76 #include "dcn21_resource.h"
77 #include "vm_helper.h"
78 #include "dcn20/dcn20_vmid.h"
80 #define SOC_BOUNDING_BOX_VALID false
81 #define DC_LOGGER_INIT(logger)
84 struct _vcs_dpi_ip_params_st dcn2_1_ip = {
88 .gpuvm_max_page_table_levels = 1,
89 .hostvm_max_page_table_levels = 4,
90 .hostvm_cached_page_table_levels = 2,
91 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
96 .rob_buffer_size_kbytes = 168,
97 .det_buffer_size_kbytes = 164,
98 .dpte_buffer_size_in_pte_reqs_luma = 44,
99 .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
100 .dpp_output_buffer_pixels = 2560,
101 .opp_output_buffer_lines = 1,
102 .pixel_chunk_size_kbytes = 8,
104 .max_page_table_levels = 4,
105 .pte_chunk_size_kbytes = 2,
106 .meta_chunk_size_kbytes = 2,
107 .writeback_chunk_size_kbytes = 2,
108 .line_buffer_size_bits = 789504,
109 .is_line_buffer_bpp_fixed = 0,
110 .line_buffer_fixed_bpp = 0,
111 .dcc_supported = true,
112 .max_line_buffer_lines = 12,
113 .writeback_luma_buffer_size_kbytes = 12,
114 .writeback_chroma_buffer_size_kbytes = 8,
115 .writeback_chroma_line_buffer_width_pixels = 4,
116 .writeback_max_hscl_ratio = 1,
117 .writeback_max_vscl_ratio = 1,
118 .writeback_min_hscl_ratio = 1,
119 .writeback_min_vscl_ratio = 1,
120 .writeback_max_hscl_taps = 12,
121 .writeback_max_vscl_taps = 12,
122 .writeback_line_buffer_luma_buffer_size = 0,
123 .writeback_line_buffer_chroma_buffer_size = 14643,
124 .cursor_buffer_size = 8,
125 .cursor_chunk_size = 2,
129 .max_dchub_pscl_bw_pix_per_clk = 4,
130 .max_pscl_lb_bw_pix_per_clk = 2,
131 .max_lb_vscl_bw_pix_per_clk = 4,
132 .max_vscl_hscl_bw_pix_per_clk = 4,
139 .dispclk_ramp_margin_percent = 1,
140 .underscan_factor = 1.10,
141 .min_vblank_lines = 32, //
142 .dppclk_delay_subtotal = 77, //
143 .dppclk_delay_scl_lb_only = 16,
144 .dppclk_delay_scl = 50,
145 .dppclk_delay_cnvc_formatter = 8,
146 .dppclk_delay_cnvc_cursor = 6,
147 .dispclk_delay_subtotal = 87, //
148 .dcfclk_cstate_latency = 10, // SRExitTime
149 .max_inter_dcn_tile_repeaters = 8,
151 .xfc_supported = false,
152 .xfc_fill_bw_overhead_percent = 10.0,
153 .xfc_fill_constant_bytes = 0,
157 struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
162 .fabricclk_mhz = 600.0,
163 .dispclk_mhz = 618.0,
167 .dscclk_mhz = 205.67,
168 .dram_speed_mts = 1600.0,
173 .fabricclk_mhz = 600.0,
174 .dispclk_mhz = 618.0,
178 .dscclk_mhz = 205.67,
179 .dram_speed_mts = 1600.0,
184 .fabricclk_mhz = 1066.0,
185 .dispclk_mhz = 888.0,
189 .dscclk_mhz = 287.67,
190 .dram_speed_mts = 2133.0,
195 .fabricclk_mhz = 1600.0,
196 .dispclk_mhz = 1015.0,
197 .dppclk_mhz = 1015.0,
200 .dscclk_mhz = 318.334,
201 .dram_speed_mts = 4266.0,
206 .fabricclk_mhz = 1600.0,
207 .dispclk_mhz = 1395.0,
208 .dppclk_mhz = 1285.0,
209 .phyclk_mhz = 1325.0,
212 .dram_speed_mts = 4266.0,
214 /*Extra state, no dispclk ramping*/
218 .fabricclk_mhz = 1600.0,
219 .dispclk_mhz = 1395.0,
220 .dppclk_mhz = 1285.0,
221 .phyclk_mhz = 1325.0,
224 .dram_speed_mts = 4266.0,
229 .sr_exit_time_us = 12.5,
230 .sr_enter_plus_exit_time_us = 17.0,
231 .urgent_latency_us = 4.0,
232 .urgent_latency_pixel_data_only_us = 4.0,
233 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
234 .urgent_latency_vm_data_only_us = 4.0,
235 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
236 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
237 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
238 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
239 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
240 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
241 .max_avg_sdp_bw_use_normal_percent = 60.0,
242 .max_avg_dram_bw_use_normal_percent = 100.0,
243 .writeback_latency_us = 12.0,
244 .max_request_size_bytes = 256,
245 .dram_channel_width_bytes = 4,
246 .fabric_datapath_to_dcn_data_return_bytes = 32,
247 .dcn_downspread_percent = 0.5,
248 .downspread_percent = 0.5,
249 .dram_page_open_time_ns = 50.0,
250 .dram_rw_turnaround_time_ns = 17.5,
251 .dram_return_buffer_per_channel_bytes = 8192,
252 .round_trip_ping_latency_dcfclk_cycles = 128,
253 .urgent_out_of_order_return_per_channel_bytes = 4096,
254 .channel_interleave_bytes = 256,
257 .vmm_page_size_bytes = 4096,
258 .dram_clock_change_latency_us = 23.84,
259 .return_bus_width_bytes = 64,
260 .dispclk_dppclk_vco_speed_mhz = 3550,
261 .xfc_bus_transport_time_us = 4,
262 .xfc_xbuf_latency_tolerance_us = 4,
263 .use_urgent_burst_bw = 1,
268 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
271 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
274 /* begin *********************
275 * macros to expend register list macro defined in HW object header file */
278 /* TODO awful hack. fixup dcn20_dwb.h */
280 #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
282 #define BASE(seg) BASE_INNER(seg)
284 #define SR(reg_name)\
285 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
288 #define SRI(reg_name, block, id)\
289 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
290 mm ## block ## id ## _ ## reg_name
292 #define SRIR(var_name, reg_name, block, id)\
293 .var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
294 mm ## block ## id ## _ ## reg_name
296 #define SRII(reg_name, block, id)\
297 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
298 mm ## block ## id ## _ ## reg_name
300 #define DCCG_SRII(reg_name, block, id)\
301 .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
302 mm ## block ## id ## _ ## reg_name
305 #define NBIO_BASE_INNER(seg) \
306 NBIF0_BASE__INST0_SEG ## seg
308 #define NBIO_BASE(seg) \
311 #define NBIO_SR(reg_name)\
312 .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
316 #define MMHUB_BASE_INNER(seg) \
317 MMHUB_BASE__INST0_SEG ## seg
319 #define MMHUB_BASE(seg) \
320 MMHUB_BASE_INNER(seg)
322 #define MMHUB_SR(reg_name)\
323 .reg_name = MMHUB_BASE(mmMM ## reg_name ## _BASE_IDX) + \
326 #define clk_src_regs(index, pllid)\
328 CS_COMMON_REG_LIST_DCN2_1(index, pllid),\
331 static const struct dce110_clk_src_regs clk_src_regs[] = {
339 static const struct dce110_clk_src_shift cs_shift = {
340 CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
343 static const struct dce110_clk_src_mask cs_mask = {
344 CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
347 static const struct bios_registers bios_regs = {
348 NBIO_SR(BIOS_SCRATCH_3),
349 NBIO_SR(BIOS_SCRATCH_6)
352 static const struct dce_dmcu_registers dmcu_regs = {
353 DMCU_DCN20_REG_LIST()
356 static const struct dce_dmcu_shift dmcu_shift = {
357 DMCU_MASK_SH_LIST_DCN10(__SHIFT)
360 static const struct dce_dmcu_mask dmcu_mask = {
361 DMCU_MASK_SH_LIST_DCN10(_MASK)
364 static const struct dce_abm_registers abm_regs = {
368 static const struct dce_abm_shift abm_shift = {
369 ABM_MASK_SH_LIST_DCN20(__SHIFT)
372 static const struct dce_abm_mask abm_mask = {
373 ABM_MASK_SH_LIST_DCN20(_MASK)
376 #define audio_regs(id)\
378 AUD_COMMON_REG_LIST(id)\
381 static const struct dce_audio_registers audio_regs[] = {
390 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
391 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
392 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
393 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
395 static const struct dce_audio_shift audio_shift = {
396 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
399 static const struct dce_audio_mask audio_mask = {
400 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
403 static const struct dccg_registers dccg_regs = {
404 DCCG_COMMON_REG_LIST_DCN_BASE()
407 static const struct dccg_shift dccg_shift = {
408 DCCG_MASK_SH_LIST_DCN2(__SHIFT)
411 static const struct dccg_mask dccg_mask = {
412 DCCG_MASK_SH_LIST_DCN2(_MASK)
415 #define opp_regs(id)\
417 OPP_REG_LIST_DCN20(id),\
420 static const struct dcn20_opp_registers opp_regs[] = {
429 static const struct dcn20_opp_shift opp_shift = {
430 OPP_MASK_SH_LIST_DCN20(__SHIFT)
433 static const struct dcn20_opp_mask opp_mask = {
434 OPP_MASK_SH_LIST_DCN20(_MASK)
438 [id] = {TG_COMMON_REG_LIST_DCN2_0(id)}
440 static const struct dcn_optc_registers tg_regs[] = {
447 static const struct dcn_optc_shift tg_shift = {
448 TG_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
451 static const struct dcn_optc_mask tg_mask = {
452 TG_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
455 static const struct dcn20_mpc_registers mpc_regs = {
456 MPC_REG_LIST_DCN2_0(0),
457 MPC_REG_LIST_DCN2_0(1),
458 MPC_REG_LIST_DCN2_0(2),
459 MPC_REG_LIST_DCN2_0(3),
460 MPC_REG_LIST_DCN2_0(4),
461 MPC_REG_LIST_DCN2_0(5),
462 MPC_OUT_MUX_REG_LIST_DCN2_0(0),
463 MPC_OUT_MUX_REG_LIST_DCN2_0(1),
464 MPC_OUT_MUX_REG_LIST_DCN2_0(2),
465 MPC_OUT_MUX_REG_LIST_DCN2_0(3)
468 static const struct dcn20_mpc_shift mpc_shift = {
469 MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
472 static const struct dcn20_mpc_mask mpc_mask = {
473 MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
476 #define hubp_regs(id)\
478 HUBP_REG_LIST_DCN21(id)\
481 static const struct dcn_hubp2_registers hubp_regs[] = {
488 static const struct dcn_hubp2_shift hubp_shift = {
489 HUBP_MASK_SH_LIST_DCN21(__SHIFT)
492 static const struct dcn_hubp2_mask hubp_mask = {
493 HUBP_MASK_SH_LIST_DCN21(_MASK)
496 static const struct dcn_hubbub_registers hubbub_reg = {
497 HUBBUB_REG_LIST_DCN21()
500 static const struct dcn_hubbub_shift hubbub_shift = {
501 HUBBUB_MASK_SH_LIST_DCN21(__SHIFT)
504 static const struct dcn_hubbub_mask hubbub_mask = {
505 HUBBUB_MASK_SH_LIST_DCN21(_MASK)
509 #define vmid_regs(id)\
511 DCN20_VMID_REG_LIST(id)\
514 static const struct dcn_vmid_registers vmid_regs[] = {
533 static const struct dcn20_vmid_shift vmid_shifts = {
534 DCN20_VMID_MASK_SH_LIST(__SHIFT)
537 static const struct dcn20_vmid_mask vmid_masks = {
538 DCN20_VMID_MASK_SH_LIST(_MASK)
541 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
542 #define dsc_regsDCN20(id)\
544 DSC_REG_LIST_DCN20(id)\
547 static const struct dcn20_dsc_registers dsc_regs[] = {
556 static const struct dcn20_dsc_shift dsc_shift = {
557 DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
560 static const struct dcn20_dsc_mask dsc_mask = {
561 DSC_REG_LIST_SH_MASK_DCN20(_MASK)
565 #define ipp_regs(id)\
567 IPP_REG_LIST_DCN20(id),\
570 static const struct dcn10_ipp_registers ipp_regs[] = {
577 static const struct dcn10_ipp_shift ipp_shift = {
578 IPP_MASK_SH_LIST_DCN20(__SHIFT)
581 static const struct dcn10_ipp_mask ipp_mask = {
582 IPP_MASK_SH_LIST_DCN20(_MASK),
585 #define opp_regs(id)\
587 OPP_REG_LIST_DCN20(id),\
591 #define aux_engine_regs(id)\
593 AUX_COMMON_REG_LIST0(id), \
596 .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
599 static const struct dce110_aux_registers aux_engine_regs[] = {
609 TF_REG_LIST_DCN20(id),\
612 static const struct dcn2_dpp_registers tf_regs[] = {
619 static const struct dcn2_dpp_shift tf_shift = {
620 TF_REG_LIST_SH_MASK_DCN20(__SHIFT)
623 static const struct dcn2_dpp_mask tf_mask = {
624 TF_REG_LIST_SH_MASK_DCN20(_MASK)
627 #define stream_enc_regs(id)\
629 SE_DCN2_REG_LIST(id)\
632 static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
640 static const struct dce110_aux_registers_shift aux_shift = {
641 DCN_AUX_MASK_SH_LIST(__SHIFT)
644 static const struct dce110_aux_registers_mask aux_mask = {
645 DCN_AUX_MASK_SH_LIST(_MASK)
648 static const struct dcn10_stream_encoder_shift se_shift = {
649 SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT)
652 static const struct dcn10_stream_encoder_mask se_mask = {
653 SE_COMMON_MASK_SH_LIST_DCN20(_MASK)
656 static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
658 static int dcn21_populate_dml_pipes_from_context(
659 struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
661 static struct input_pixel_processor *dcn21_ipp_create(
662 struct dc_context *ctx, uint32_t inst)
664 struct dcn10_ipp *ipp =
665 kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL);
672 dcn20_ipp_construct(ipp, ctx, inst,
673 &ipp_regs[inst], &ipp_shift, &ipp_mask);
677 static struct dpp *dcn21_dpp_create(
678 struct dc_context *ctx,
681 struct dcn20_dpp *dpp =
682 kzalloc(sizeof(struct dcn20_dpp), GFP_KERNEL);
687 if (dpp2_construct(dpp, ctx, inst,
688 &tf_regs[inst], &tf_shift, &tf_mask))
696 static struct dce_aux *dcn21_aux_engine_create(
697 struct dc_context *ctx,
700 struct aux_engine_dce110 *aux_engine =
701 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
706 dce110_aux_engine_construct(aux_engine, ctx, inst,
707 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
708 &aux_engine_regs[inst],
711 ctx->dc->caps.extended_aux_timeout_support);
713 return &aux_engine->base;
716 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
718 static const struct dce_i2c_registers i2c_hw_regs[] = {
726 static const struct dce_i2c_shift i2c_shifts = {
727 I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT)
730 static const struct dce_i2c_mask i2c_masks = {
731 I2C_COMMON_MASK_SH_LIST_DCN2(_MASK)
734 struct dce_i2c_hw *dcn21_i2c_hw_create(
735 struct dc_context *ctx,
738 struct dce_i2c_hw *dce_i2c_hw =
739 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
744 dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
745 &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
750 static const struct resource_caps res_cap_rn = {
751 .num_timing_generator = 4,
753 .num_video_plane = 4,
754 .num_audio = 4, // 4 audio endpoints. 4 audio streams
755 .num_stream_encoder = 5,
756 .num_pll = 5, // maybe 3 because the last two used for USB-c
760 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
766 static const struct resource_caps res_cap_rn_FPGA_4pipe = {
767 .num_timing_generator = 4,
769 .num_video_plane = 4,
771 .num_stream_encoder = 4,
778 static const struct resource_caps res_cap_rn_FPGA_2pipe_dsc = {
779 .num_timing_generator = 2,
781 .num_video_plane = 2,
783 .num_stream_encoder = 2,
787 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
793 static const struct dc_plane_cap plane_cap = {
794 .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
795 .blends_with_above = true,
796 .blends_with_below = true,
797 .per_pixel_alpha = true,
799 .pixel_format_support = {
805 .max_upscale_factor = {
811 .max_downscale_factor = {
818 static const struct dc_debug_options debug_defaults_drv = {
819 .disable_dmcu = true,
820 .force_abm_enable = false,
821 .timing_trace = false,
823 .disable_pplib_clock_request = true,
824 .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
825 .force_single_disp_pipe_split = false,
826 .disable_dcc = DCC_ENABLE,
828 .performance_trace = false,
829 .max_downscale_src_width = 3840,
830 .disable_pplib_wm_range = false,
831 .scl_reset_length10 = true,
832 .sanity_checks = true,
833 .disable_48mhz_pwrdwn = false,
836 static const struct dc_debug_options debug_defaults_diags = {
837 .disable_dmcu = true,
838 .force_abm_enable = false,
839 .timing_trace = true,
841 .disable_dpp_power_gate = true,
842 .disable_hubp_power_gate = true,
843 .disable_clock_gate = true,
844 .disable_pplib_clock_request = true,
845 .disable_pplib_wm_range = true,
846 .disable_stutter = true,
847 .disable_48mhz_pwrdwn = true,
850 enum dcn20_clk_src_array_id {
853 DCN20_CLK_SRC_TOTAL_DCN21
856 static void destruct(struct dcn21_resource_pool *pool)
860 for (i = 0; i < pool->base.stream_enc_count; i++) {
861 if (pool->base.stream_enc[i] != NULL) {
862 kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
863 pool->base.stream_enc[i] = NULL;
867 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
868 for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
869 if (pool->base.dscs[i] != NULL)
870 dcn20_dsc_destroy(&pool->base.dscs[i]);
874 if (pool->base.mpc != NULL) {
875 kfree(TO_DCN20_MPC(pool->base.mpc));
876 pool->base.mpc = NULL;
878 if (pool->base.hubbub != NULL) {
879 kfree(pool->base.hubbub);
880 pool->base.hubbub = NULL;
882 for (i = 0; i < pool->base.pipe_count; i++) {
883 if (pool->base.dpps[i] != NULL)
884 dcn20_dpp_destroy(&pool->base.dpps[i]);
886 if (pool->base.ipps[i] != NULL)
887 pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
889 if (pool->base.hubps[i] != NULL) {
890 kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
891 pool->base.hubps[i] = NULL;
894 if (pool->base.irqs != NULL) {
895 dal_irq_service_destroy(&pool->base.irqs);
899 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
900 if (pool->base.engines[i] != NULL)
901 dce110_engine_destroy(&pool->base.engines[i]);
902 if (pool->base.hw_i2cs[i] != NULL) {
903 kfree(pool->base.hw_i2cs[i]);
904 pool->base.hw_i2cs[i] = NULL;
906 if (pool->base.sw_i2cs[i] != NULL) {
907 kfree(pool->base.sw_i2cs[i]);
908 pool->base.sw_i2cs[i] = NULL;
912 for (i = 0; i < pool->base.res_cap->num_opp; i++) {
913 if (pool->base.opps[i] != NULL)
914 pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
917 for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
918 if (pool->base.timing_generators[i] != NULL) {
919 kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
920 pool->base.timing_generators[i] = NULL;
924 for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
925 if (pool->base.dwbc[i] != NULL) {
926 kfree(TO_DCN20_DWBC(pool->base.dwbc[i]));
927 pool->base.dwbc[i] = NULL;
929 if (pool->base.mcif_wb[i] != NULL) {
930 kfree(TO_DCN20_MMHUBBUB(pool->base.mcif_wb[i]));
931 pool->base.mcif_wb[i] = NULL;
935 for (i = 0; i < pool->base.audio_count; i++) {
936 if (pool->base.audios[i])
937 dce_aud_destroy(&pool->base.audios[i]);
940 for (i = 0; i < pool->base.clk_src_count; i++) {
941 if (pool->base.clock_sources[i] != NULL) {
942 dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
943 pool->base.clock_sources[i] = NULL;
947 if (pool->base.dp_clock_source != NULL) {
948 dcn20_clock_source_destroy(&pool->base.dp_clock_source);
949 pool->base.dp_clock_source = NULL;
953 if (pool->base.abm != NULL)
954 dce_abm_destroy(&pool->base.abm);
956 if (pool->base.dmcu != NULL)
957 dce_dmcu_destroy(&pool->base.dmcu);
959 if (pool->base.dccg != NULL)
960 dcn_dccg_destroy(&pool->base.dccg);
962 if (pool->base.pp_smu != NULL)
963 dcn21_pp_smu_destroy(&pool->base.pp_smu);
967 static void calculate_wm_set_for_vlevel(
969 struct wm_range_table_entry *table_entry,
970 struct dcn_watermarks *wm_set,
971 struct display_mode_lib *dml,
972 display_e2e_pipe_params_st *pipes,
975 double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
977 ASSERT(vlevel < dml->soc.num_states);
978 /* only pipe 0 is read for voltage and dcf/soc clocks */
979 pipes[0].clks_cfg.voltage = vlevel;
980 pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
981 pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
983 dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
985 wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
986 wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
987 wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
988 wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
989 wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
990 #if defined(CONFIG_DRM_AMD_DC_DCN2_1)
991 wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
992 wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
993 wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
995 dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
999 static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
1002 if (dc->bb_overrides.sr_exit_time_ns) {
1003 bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
1006 if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {
1007 bb->sr_enter_plus_exit_time_us =
1008 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
1011 if (dc->bb_overrides.urgent_latency_ns) {
1012 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
1015 if (dc->bb_overrides.dram_clock_change_latency_ns) {
1016 bb->dram_clock_change_latency_us =
1017 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
1022 void dcn21_calculate_wm(
1023 struct dc *dc, struct dc_state *context,
1024 display_e2e_pipe_params_st *pipes,
1026 int *pipe_split_from,
1029 int pipe_cnt, i, pipe_idx;
1030 int vlevel, vlevel_max;
1031 struct wm_range_table_entry *table_entry;
1032 struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
1036 patch_bounding_box(dc, &context->bw_ctx.dml.soc);
1038 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1039 if (!context->res_ctx.pipe_ctx[i].stream)
1042 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
1043 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb];
1045 if (pipe_split_from[i] < 0) {
1046 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
1047 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
1048 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
1049 pipes[pipe_cnt].pipe.dest.odm_combine =
1050 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx];
1052 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
1055 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
1056 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
1057 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
1058 pipes[pipe_cnt].pipe.dest.odm_combine =
1059 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]];
1061 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
1066 if (pipe_cnt != pipe_idx) {
1067 if (dc->res_pool->funcs->populate_dml_pipes)
1068 pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
1069 &context->res_ctx, pipes);
1071 pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
1072 &context->res_ctx, pipes);
1075 *out_pipe_cnt = pipe_cnt;
1077 vlevel_max = bw_params->clk_table.num_entries - 1;
1081 table_entry = &bw_params->wm_table.entries[WM_D];
1082 if (table_entry->wm_type == WM_TYPE_RETRAINING)
1085 vlevel = vlevel_max;
1086 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
1087 &context->bw_ctx.dml, pipes, pipe_cnt);
1089 table_entry = &bw_params->wm_table.entries[WM_C];
1090 vlevel = MIN(MAX(vlevel_req, 2), vlevel_max);
1091 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
1092 &context->bw_ctx.dml, pipes, pipe_cnt);
1094 table_entry = &bw_params->wm_table.entries[WM_B];
1095 vlevel = MIN(MAX(vlevel_req, 1), vlevel_max);
1096 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
1097 &context->bw_ctx.dml, pipes, pipe_cnt);
1100 table_entry = &bw_params->wm_table.entries[WM_A];
1101 vlevel = MIN(vlevel_req, vlevel_max);
1102 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
1103 &context->bw_ctx.dml, pipes, pipe_cnt);
1107 bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context,
1112 BW_VAL_TRACE_SETUP();
1115 int pipe_split_from[MAX_PIPES];
1117 display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
1118 DC_LOGGER_INIT(dc->ctx->logger);
1120 BW_VAL_TRACE_COUNT();
1122 out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel);
1130 BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1132 if (fast_validate) {
1133 BW_VAL_TRACE_SKIP(fast);
1137 dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel);
1138 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
1140 BW_VAL_TRACE_END_WATERMARKS();
1145 DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
1146 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
1148 BW_VAL_TRACE_SKIP(fail);
1154 BW_VAL_TRACE_FINISH();
1158 static void dcn21_destroy_resource_pool(struct resource_pool **pool)
1160 struct dcn21_resource_pool *dcn21_pool = TO_DCN21_RES_POOL(*pool);
1162 destruct(dcn21_pool);
1167 static struct clock_source *dcn21_clock_source_create(
1168 struct dc_context *ctx,
1169 struct dc_bios *bios,
1170 enum clock_source_id id,
1171 const struct dce110_clk_src_regs *regs,
1174 struct dce110_clk_src *clk_src =
1175 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
1180 if (dcn20_clk_src_construct(clk_src, ctx, bios, id,
1181 regs, &cs_shift, &cs_mask)) {
1182 clk_src->base.dp_clk_src = dp_clk_src;
1183 return &clk_src->base;
1186 BREAK_TO_DEBUGGER();
1190 static struct hubp *dcn21_hubp_create(
1191 struct dc_context *ctx,
1194 struct dcn21_hubp *hubp21 =
1195 kzalloc(sizeof(struct dcn21_hubp), GFP_KERNEL);
1200 if (hubp21_construct(hubp21, ctx, inst,
1201 &hubp_regs[inst], &hubp_shift, &hubp_mask))
1202 return &hubp21->base;
1204 BREAK_TO_DEBUGGER();
1209 static struct hubbub *dcn21_hubbub_create(struct dc_context *ctx)
1213 struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub),
1219 hubbub21_construct(hubbub, ctx,
1224 for (i = 0; i < res_cap_rn.num_vmid; i++) {
1225 struct dcn20_vmid *vmid = &hubbub->vmid[i];
1229 vmid->regs = &vmid_regs[i];
1230 vmid->shifts = &vmid_shifts;
1231 vmid->masks = &vmid_masks;
1234 return &hubbub->base;
1237 struct output_pixel_processor *dcn21_opp_create(
1238 struct dc_context *ctx, uint32_t inst)
1240 struct dcn20_opp *opp =
1241 kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
1244 BREAK_TO_DEBUGGER();
1248 dcn20_opp_construct(opp, ctx, inst,
1249 &opp_regs[inst], &opp_shift, &opp_mask);
1253 struct timing_generator *dcn21_timing_generator_create(
1254 struct dc_context *ctx,
1257 struct optc *tgn10 =
1258 kzalloc(sizeof(struct optc), GFP_KERNEL);
1263 tgn10->base.inst = instance;
1264 tgn10->base.ctx = ctx;
1266 tgn10->tg_regs = &tg_regs[instance];
1267 tgn10->tg_shift = &tg_shift;
1268 tgn10->tg_mask = &tg_mask;
1270 dcn20_timing_generator_init(tgn10);
1272 return &tgn10->base;
1275 struct mpc *dcn21_mpc_create(struct dc_context *ctx)
1277 struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc),
1283 dcn20_mpc_construct(mpc20, ctx,
1289 return &mpc20->base;
1292 static void read_dce_straps(
1293 struct dc_context *ctx,
1294 struct resource_straps *straps)
1296 generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX),
1297 FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
1301 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1303 struct display_stream_compressor *dcn21_dsc_create(
1304 struct dc_context *ctx, uint32_t inst)
1306 struct dcn20_dsc *dsc =
1307 kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
1310 BREAK_TO_DEBUGGER();
1314 dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
1319 static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
1322 TODO: Fix this function to calcualte correct values.
1323 There are known issues with this function currently
1324 that will need to be investigated. Use hardcoded known good values for now.
1327 struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
1328 struct clk_limit_table *clk_table = &bw_params->clk_table;
1331 dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
1332 dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
1333 dcn2_1_soc.num_chans = bw_params->num_channels;
1335 for (i = 0; i < clk_table->num_entries; i++) {
1337 dcn2_1_soc.clock_limits[i].state = i;
1338 dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
1339 dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
1340 dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
1341 dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000;
1343 dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i];
1344 dcn2_1_soc.num_states = i;
1348 /* Temporary Place holder until we can get them from fuse */
1349 static struct dpm_clocks dummy_clocks = {
1351 {.Freq = 400, .Vol = 1},
1352 {.Freq = 483, .Vol = 1},
1353 {.Freq = 602, .Vol = 1},
1354 {.Freq = 738, .Vol = 1} },
1356 {.Freq = 300, .Vol = 1},
1357 {.Freq = 400, .Vol = 1},
1358 {.Freq = 400, .Vol = 1},
1359 {.Freq = 400, .Vol = 1} },
1361 {.Freq = 400, .Vol = 1},
1362 {.Freq = 800, .Vol = 1},
1363 {.Freq = 1067, .Vol = 1},
1364 {.Freq = 1600, .Vol = 1} },
1366 {.Freq = 800, .Vol = 1},
1367 {.Freq = 1600, .Vol = 1},
1368 {.Freq = 1067, .Vol = 1},
1369 {.Freq = 1600, .Vol = 1} },
1373 static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp,
1374 struct pp_smu_wm_range_sets *ranges)
1376 return PP_SMU_RESULT_OK;
1379 static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp,
1380 struct dpm_clocks *clock_table)
1382 *clock_table = dummy_clocks;
1383 return PP_SMU_RESULT_OK;
1386 static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx)
1388 struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
1393 if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) {
1394 pp_smu->ctx.ver = PP_SMU_VER_RN;
1395 pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table;
1396 pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges;
1399 dm_pp_get_funcs(ctx, pp_smu);
1401 if (pp_smu->ctx.ver != PP_SMU_VER_RN)
1402 pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs));
1408 static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
1410 if (pp_smu && *pp_smu) {
1416 static struct audio *dcn21_create_audio(
1417 struct dc_context *ctx, unsigned int inst)
1419 return dce_audio_create(ctx, inst,
1420 &audio_regs[inst], &audio_shift, &audio_mask);
1423 static struct dc_cap_funcs cap_funcs = {
1424 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
1427 struct stream_encoder *dcn21_stream_encoder_create(
1428 enum engine_id eng_id,
1429 struct dc_context *ctx)
1431 struct dcn10_stream_encoder *enc1 =
1432 kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
1437 dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id,
1438 &stream_enc_regs[eng_id],
1439 &se_shift, &se_mask);
1444 static const struct dce_hwseq_registers hwseq_reg = {
1445 HWSEQ_DCN21_REG_LIST()
1448 static const struct dce_hwseq_shift hwseq_shift = {
1449 HWSEQ_DCN21_MASK_SH_LIST(__SHIFT)
1452 static const struct dce_hwseq_mask hwseq_mask = {
1453 HWSEQ_DCN21_MASK_SH_LIST(_MASK)
1456 static struct dce_hwseq *dcn21_hwseq_create(
1457 struct dc_context *ctx)
1459 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
1463 hws->regs = &hwseq_reg;
1464 hws->shifts = &hwseq_shift;
1465 hws->masks = &hwseq_mask;
1466 hws->wa.DEGVIDCN21 = true;
1471 static const struct resource_create_funcs res_create_funcs = {
1472 .read_dce_straps = read_dce_straps,
1473 .create_audio = dcn21_create_audio,
1474 .create_stream_encoder = dcn21_stream_encoder_create,
1475 .create_hwseq = dcn21_hwseq_create,
1478 static const struct resource_create_funcs res_create_maximus_funcs = {
1479 .read_dce_straps = NULL,
1480 .create_audio = NULL,
1481 .create_stream_encoder = NULL,
1482 .create_hwseq = dcn21_hwseq_create,
1485 static const struct encoder_feature_support link_enc_feature = {
1486 .max_hdmi_deep_color = COLOR_DEPTH_121212,
1487 .max_hdmi_pixel_clock = 600000,
1488 .hdmi_ycbcr420_supported = true,
1489 .dp_ycbcr420_supported = true,
1490 .flags.bits.IS_HBR2_CAPABLE = true,
1491 .flags.bits.IS_HBR3_CAPABLE = true,
1492 .flags.bits.IS_TPS3_CAPABLE = true,
1493 .flags.bits.IS_TPS4_CAPABLE = true
1497 #define link_regs(id, phyid)\
1499 LE_DCN10_REG_LIST(id), \
1500 UNIPHY_DCN2_REG_LIST(phyid), \
1501 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
1504 static const struct dcn10_link_enc_registers link_enc_regs[] = {
1512 #define aux_regs(id)\
1514 DCN2_AUX_REG_LIST(id)\
1517 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
1525 #define hpd_regs(id)\
1530 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
1538 static const struct dcn10_link_enc_shift le_shift = {
1539 LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT)
1542 static const struct dcn10_link_enc_mask le_mask = {
1543 LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK)
1546 static int map_transmitter_id_to_phy_instance(
1547 enum transmitter transmitter)
1549 switch (transmitter) {
1550 case TRANSMITTER_UNIPHY_A:
1553 case TRANSMITTER_UNIPHY_B:
1556 case TRANSMITTER_UNIPHY_C:
1559 case TRANSMITTER_UNIPHY_D:
1562 case TRANSMITTER_UNIPHY_E:
1571 static struct link_encoder *dcn21_link_encoder_create(
1572 const struct encoder_init_data *enc_init_data)
1574 struct dcn21_link_encoder *enc21 =
1575 kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL);
1582 map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
1584 dcn21_link_encoder_construct(enc21,
1587 &link_enc_regs[link_regs_id],
1588 &link_enc_aux_regs[enc_init_data->channel - 1],
1589 &link_enc_hpd_regs[enc_init_data->hpd_source],
1593 return &enc21->enc10.base;
1597 #define REG(reg_name) \
1598 (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
1600 static uint32_t read_pipe_fuses(struct dc_context *ctx)
1602 uint32_t value = REG_READ(CC_DC_PIPE_DIS);
1603 /* RV1 support max 4 pipes */
1604 value = value & 0xf;
1608 static int dcn21_populate_dml_pipes_from_context(
1609 struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
1611 uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, res_ctx, pipes);
1614 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1616 if (!res_ctx->pipe_ctx[i].stream)
1619 pipes[i].pipe.src.hostvm = 1;
1620 pipes[i].pipe.src.gpuvm = 1;
1626 static struct resource_funcs dcn21_res_pool_funcs = {
1627 .destroy = dcn21_destroy_resource_pool,
1628 .link_enc_create = dcn21_link_encoder_create,
1629 .validate_bandwidth = dcn21_validate_bandwidth,
1630 .populate_dml_pipes = dcn21_populate_dml_pipes_from_context,
1631 .add_stream_to_ctx = dcn20_add_stream_to_ctx,
1632 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
1633 .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
1634 .populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
1635 .get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
1636 .set_mcif_arb_params = dcn20_set_mcif_arb_params,
1637 .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
1638 .update_bw_bounding_box = update_bw_bounding_box
1641 static bool construct(
1642 uint8_t num_virtual_links,
1644 struct dcn21_resource_pool *pool)
1647 struct dc_context *ctx = dc->ctx;
1648 struct irq_service_init_data init_data;
1649 uint32_t pipe_fuses = read_pipe_fuses(ctx);
1652 ctx->dc_bios->regs = &bios_regs;
1654 pool->base.res_cap = &res_cap_rn;
1656 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
1657 //pool->base.res_cap = &res_cap_nv10_FPGA_2pipe_dsc;
1658 pool->base.res_cap = &res_cap_rn_FPGA_4pipe;
1661 pool->base.funcs = &dcn21_res_pool_funcs;
1663 /*************************************************
1664 * Resource + asic cap harcoding *
1665 *************************************************/
1666 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1668 /* max pipe num for ASIC before check pipe fuses */
1669 pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1671 dc->caps.max_downscale_ratio = 200;
1672 dc->caps.i2c_speed_in_khz = 100;
1673 dc->caps.max_cursor_size = 256;
1674 dc->caps.dmdata_alloc_size = 2048;
1675 dc->caps.hw_3d_lut = true;
1677 dc->caps.max_slave_planes = 1;
1678 dc->caps.post_blend_color_processing = true;
1679 dc->caps.force_dp_tps4_for_cp2520 = true;
1680 dc->caps.extended_aux_timeout_support = true;
1681 #ifdef CONFIG_DRM_AMD_DC_DMUB
1682 dc->caps.dmcub_support = true;
1685 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
1686 dc->debug = debug_defaults_drv;
1687 else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
1688 pool->base.pipe_count = 4;
1689 dc->debug = debug_defaults_diags;
1691 dc->debug = debug_defaults_diags;
1693 // Init the vm_helper
1695 vm_helper_init(dc->vm_helper, 16);
1697 /*************************************************
1698 * Create resources *
1699 *************************************************/
1701 pool->base.clock_sources[DCN20_CLK_SRC_PLL0] =
1702 dcn21_clock_source_create(ctx, ctx->dc_bios,
1703 CLOCK_SOURCE_COMBO_PHY_PLL0,
1704 &clk_src_regs[0], false);
1705 pool->base.clock_sources[DCN20_CLK_SRC_PLL1] =
1706 dcn21_clock_source_create(ctx, ctx->dc_bios,
1707 CLOCK_SOURCE_COMBO_PHY_PLL1,
1708 &clk_src_regs[1], false);
1710 pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21;
1712 /* todo: not reuse phy_pll registers */
1713 pool->base.dp_clock_source =
1714 dcn21_clock_source_create(ctx, ctx->dc_bios,
1715 CLOCK_SOURCE_ID_DP_DTO,
1716 &clk_src_regs[0], true);
1718 for (i = 0; i < pool->base.clk_src_count; i++) {
1719 if (pool->base.clock_sources[i] == NULL) {
1720 dm_error("DC: failed to create clock sources!\n");
1721 BREAK_TO_DEBUGGER();
1726 pool->base.dccg = dccg2_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
1727 if (pool->base.dccg == NULL) {
1728 dm_error("DC: failed to create dccg!\n");
1729 BREAK_TO_DEBUGGER();
1733 pool->base.dmcu = dcn21_dmcu_create(ctx,
1737 if (pool->base.dmcu == NULL) {
1738 dm_error("DC: failed to create dmcu!\n");
1739 BREAK_TO_DEBUGGER();
1743 pool->base.abm = dce_abm_create(ctx,
1747 if (pool->base.abm == NULL) {
1748 dm_error("DC: failed to create abm!\n");
1749 BREAK_TO_DEBUGGER();
1753 pool->base.pp_smu = dcn21_pp_smu_create(ctx);
1755 num_pipes = dcn2_1_ip.max_num_dpp;
1757 for (i = 0; i < dcn2_1_ip.max_num_dpp; i++)
1758 if (pipe_fuses & 1 << i)
1760 dcn2_1_ip.max_num_dpp = num_pipes;
1761 dcn2_1_ip.max_num_otg = num_pipes;
1763 dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
1765 init_data.ctx = dc->ctx;
1766 pool->base.irqs = dal_irq_service_dcn21_create(&init_data);
1767 if (!pool->base.irqs)
1771 /* mem input -> ipp -> dpp -> opp -> TG */
1772 for (i = 0; i < pool->base.pipe_count; i++) {
1773 /* if pipe is disabled, skip instance of HW pipe,
1774 * i.e, skip ASIC register instance
1776 if ((pipe_fuses & (1 << i)) != 0)
1779 pool->base.hubps[i] = dcn21_hubp_create(ctx, i);
1780 if (pool->base.hubps[i] == NULL) {
1781 BREAK_TO_DEBUGGER();
1783 "DC: failed to create memory input!\n");
1787 pool->base.ipps[i] = dcn21_ipp_create(ctx, i);
1788 if (pool->base.ipps[i] == NULL) {
1789 BREAK_TO_DEBUGGER();
1791 "DC: failed to create input pixel processor!\n");
1795 pool->base.dpps[i] = dcn21_dpp_create(ctx, i);
1796 if (pool->base.dpps[i] == NULL) {
1797 BREAK_TO_DEBUGGER();
1799 "DC: failed to create dpps!\n");
1803 pool->base.opps[i] = dcn21_opp_create(ctx, i);
1804 if (pool->base.opps[i] == NULL) {
1805 BREAK_TO_DEBUGGER();
1807 "DC: failed to create output pixel processor!\n");
1811 pool->base.timing_generators[i] = dcn21_timing_generator_create(
1813 if (pool->base.timing_generators[i] == NULL) {
1814 BREAK_TO_DEBUGGER();
1815 dm_error("DC: failed to create tg!\n");
1821 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1822 pool->base.engines[i] = dcn21_aux_engine_create(ctx, i);
1823 if (pool->base.engines[i] == NULL) {
1824 BREAK_TO_DEBUGGER();
1826 "DC:failed to create aux engine!!\n");
1829 pool->base.hw_i2cs[i] = dcn21_i2c_hw_create(ctx, i);
1830 if (pool->base.hw_i2cs[i] == NULL) {
1831 BREAK_TO_DEBUGGER();
1833 "DC:failed to create hw i2c!!\n");
1836 pool->base.sw_i2cs[i] = NULL;
1839 pool->base.timing_generator_count = j;
1840 pool->base.pipe_count = j;
1841 pool->base.mpcc_count = j;
1843 pool->base.mpc = dcn21_mpc_create(ctx);
1844 if (pool->base.mpc == NULL) {
1845 BREAK_TO_DEBUGGER();
1846 dm_error("DC: failed to create mpc!\n");
1850 pool->base.hubbub = dcn21_hubbub_create(ctx);
1851 if (pool->base.hubbub == NULL) {
1852 BREAK_TO_DEBUGGER();
1853 dm_error("DC: failed to create hubbub!\n");
1857 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1858 for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
1859 pool->base.dscs[i] = dcn21_dsc_create(ctx, i);
1860 if (pool->base.dscs[i] == NULL) {
1861 BREAK_TO_DEBUGGER();
1862 dm_error("DC: failed to create display stream compressor %d!\n", i);
1868 if (!dcn20_dwbc_create(ctx, &pool->base)) {
1869 BREAK_TO_DEBUGGER();
1870 dm_error("DC: failed to create dwbc!\n");
1873 if (!dcn20_mmhubbub_create(ctx, &pool->base)) {
1874 BREAK_TO_DEBUGGER();
1875 dm_error("DC: failed to create mcif_wb!\n");
1879 if (!resource_construct(num_virtual_links, dc, &pool->base,
1880 (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
1881 &res_create_funcs : &res_create_maximus_funcs)))
1884 dcn21_hw_sequencer_construct(dc);
1886 dc->caps.max_planes = pool->base.pipe_count;
1888 for (i = 0; i < dc->caps.max_planes; ++i)
1889 dc->caps.planes[i] = plane_cap;
1891 dc->cap_funcs = cap_funcs;
1902 struct resource_pool *dcn21_create_resource_pool(
1903 const struct dc_init_data *init_data,
1906 struct dcn21_resource_pool *pool =
1907 kzalloc(sizeof(struct dcn21_resource_pool), GFP_KERNEL);
1912 if (construct(init_data->num_virtual_links, dc, pool))
1915 BREAK_TO_DEBUGGER();