2 * Copyright 2016 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 <linux/slab.h>
28 #include "dm_services.h"
31 #include "dcn10_init.h"
34 #include "include/irq_service_interface.h"
35 #include "dcn10_resource.h"
36 #include "dcn10_ipp.h"
37 #include "dcn10_mpc.h"
38 #include "irq/dcn10/irq_service_dcn10.h"
39 #include "dcn10_dpp.h"
40 #include "dcn10_optc.h"
41 #include "dcn10_hw_sequencer.h"
42 #include "dce110/dce110_hw_sequencer.h"
43 #include "dcn10_opp.h"
44 #include "dcn10_link_encoder.h"
45 #include "dcn10_stream_encoder.h"
46 #include "dce/dce_clock_source.h"
47 #include "dce/dce_audio.h"
48 #include "dce/dce_hwseq.h"
49 #include "virtual/virtual_stream_encoder.h"
50 #include "dce110/dce110_resource.h"
51 #include "dce112/dce112_resource.h"
52 #include "dcn10_hubp.h"
53 #include "dcn10_hubbub.h"
55 #include "soc15_hw_ip.h"
56 #include "vega10_ip_offset.h"
58 #include "dcn/dcn_1_0_offset.h"
59 #include "dcn/dcn_1_0_sh_mask.h"
61 #include "nbio/nbio_7_0_offset.h"
63 #include "mmhub/mmhub_9_1_offset.h"
64 #include "mmhub/mmhub_9_1_sh_mask.h"
66 #include "reg_helper.h"
67 #include "dce/dce_abm.h"
68 #include "dce/dce_dmcu.h"
69 #include "dce/dce_aux.h"
70 #include "dce/dce_i2c.h"
72 const struct _vcs_dpi_ip_params_st dcn1_0_ip
= {
73 .rob_buffer_size_kbytes
= 64,
74 .det_buffer_size_kbytes
= 164,
75 .dpte_buffer_size_in_pte_reqs_luma
= 42,
76 .dpp_output_buffer_pixels
= 2560,
77 .opp_output_buffer_lines
= 1,
78 .pixel_chunk_size_kbytes
= 8,
80 .pte_chunk_size_kbytes
= 2,
81 .meta_chunk_size_kbytes
= 2,
82 .writeback_chunk_size_kbytes
= 2,
83 .line_buffer_size_bits
= 589824,
84 .max_line_buffer_lines
= 12,
85 .IsLineBufferBppFixed
= 0,
86 .LineBufferFixedBpp
= -1,
87 .writeback_luma_buffer_size_kbytes
= 12,
88 .writeback_chroma_buffer_size_kbytes
= 8,
91 .max_dchub_pscl_bw_pix_per_clk
= 4,
92 .max_pscl_lb_bw_pix_per_clk
= 2,
93 .max_lb_vscl_bw_pix_per_clk
= 4,
94 .max_vscl_hscl_bw_pix_per_clk
= 4,
101 .dispclk_ramp_margin_percent
= 1,
102 .underscan_factor
= 1.10,
103 .min_vblank_lines
= 14,
104 .dppclk_delay_subtotal
= 90,
105 .dispclk_delay_subtotal
= 42,
106 .dcfclk_cstate_latency
= 10,
107 .max_inter_dcn_tile_repeaters
= 8,
108 .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
= 0,
109 .bug_forcing_LC_req_same_size_fixed
= 0,
112 const struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc
= {
113 .sr_exit_time_us
= 9.0,
114 .sr_enter_plus_exit_time_us
= 11.0,
115 .urgent_latency_us
= 4.0,
116 .writeback_latency_us
= 12.0,
117 .ideal_dram_bw_after_urgent_percent
= 80.0,
118 .max_request_size_bytes
= 256,
119 .downspread_percent
= 0.5,
120 .dram_page_open_time_ns
= 50.0,
121 .dram_rw_turnaround_time_ns
= 17.5,
122 .dram_return_buffer_per_channel_bytes
= 8192,
123 .round_trip_ping_latency_dcfclk_cycles
= 128,
124 .urgent_out_of_order_return_per_channel_bytes
= 256,
125 .channel_interleave_bytes
= 256,
128 .vmm_page_size_bytes
= 4096,
129 .dram_clock_change_latency_us
= 17.0,
130 .writeback_dram_clock_change_latency_us
= 23.0,
131 .return_bus_width_bytes
= 64,
134 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
135 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
136 #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
137 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
138 #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
139 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
140 #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
141 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
142 #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
143 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
144 #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
145 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f
146 #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
147 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f
148 #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
152 enum dcn10_clk_src_array_id
{
158 DCN101_CLK_SRC_TOTAL
= DCN10_CLK_SRC_PLL3
161 /* begin *********************
162 * macros to expend register list macro defined in HW object header file */
165 #define BASE_INNER(seg) \
166 DCE_BASE__INST0_SEG ## seg
171 #define SR(reg_name)\
172 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
175 #define SRI(reg_name, block, id)\
176 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
177 mm ## block ## id ## _ ## reg_name
180 #define SRII(reg_name, block, id)\
181 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
182 mm ## block ## id ## _ ## reg_name
185 #define NBIO_BASE_INNER(seg) \
186 NBIF_BASE__INST0_SEG ## seg
188 #define NBIO_BASE(seg) \
191 #define NBIO_SR(reg_name)\
192 .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
196 #define MMHUB_BASE_INNER(seg) \
197 MMHUB_BASE__INST0_SEG ## seg
199 #define MMHUB_BASE(seg) \
200 MMHUB_BASE_INNER(seg)
202 #define MMHUB_SR(reg_name)\
203 .reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) + \
206 /* macros to expend register list macro defined in HW object header file
207 * end *********************/
210 static const struct dce_dmcu_registers dmcu_regs
= {
211 DMCU_DCN10_REG_LIST()
214 static const struct dce_dmcu_shift dmcu_shift
= {
215 DMCU_MASK_SH_LIST_DCN10(__SHIFT
)
218 static const struct dce_dmcu_mask dmcu_mask
= {
219 DMCU_MASK_SH_LIST_DCN10(_MASK
)
222 static const struct dce_abm_registers abm_regs
= {
223 ABM_DCN10_REG_LIST(0)
226 static const struct dce_abm_shift abm_shift
= {
227 ABM_MASK_SH_LIST_DCN10(__SHIFT
)
230 static const struct dce_abm_mask abm_mask
= {
231 ABM_MASK_SH_LIST_DCN10(_MASK
)
234 #define stream_enc_regs(id)\
239 static const struct dcn10_stream_enc_registers stream_enc_regs
[] = {
246 static const struct dcn10_stream_encoder_shift se_shift
= {
247 SE_COMMON_MASK_SH_LIST_DCN10(__SHIFT
)
250 static const struct dcn10_stream_encoder_mask se_mask
= {
251 SE_COMMON_MASK_SH_LIST_DCN10(_MASK
)
254 #define audio_regs(id)\
256 AUD_COMMON_REG_LIST(id)\
259 static const struct dce_audio_registers audio_regs
[] = {
266 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
267 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
268 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
269 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
271 static const struct dce_audio_shift audio_shift
= {
272 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT
)
275 static const struct dce_audio_mask audio_mask
= {
276 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK
)
279 #define aux_regs(id)\
284 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs
[] = {
291 #define hpd_regs(id)\
296 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs
[] = {
303 #define link_regs(id)\
305 LE_DCN10_REG_LIST(id), \
306 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
309 static const struct dcn10_link_enc_registers link_enc_regs
[] = {
316 static const struct dcn10_link_enc_shift le_shift
= {
317 LINK_ENCODER_MASK_SH_LIST_DCN10(__SHIFT
)
320 static const struct dcn10_link_enc_mask le_mask
= {
321 LINK_ENCODER_MASK_SH_LIST_DCN10(_MASK
)
324 static const struct dce110_aux_registers_shift aux_shift
= {
325 DCN10_AUX_MASK_SH_LIST(__SHIFT
)
328 static const struct dce110_aux_registers_mask aux_mask
= {
329 DCN10_AUX_MASK_SH_LIST(_MASK
)
332 #define ipp_regs(id)\
334 IPP_REG_LIST_DCN10(id),\
337 static const struct dcn10_ipp_registers ipp_regs
[] = {
344 static const struct dcn10_ipp_shift ipp_shift
= {
345 IPP_MASK_SH_LIST_DCN10(__SHIFT
)
348 static const struct dcn10_ipp_mask ipp_mask
= {
349 IPP_MASK_SH_LIST_DCN10(_MASK
),
352 #define opp_regs(id)\
354 OPP_REG_LIST_DCN10(id),\
357 static const struct dcn10_opp_registers opp_regs
[] = {
364 static const struct dcn10_opp_shift opp_shift
= {
365 OPP_MASK_SH_LIST_DCN10(__SHIFT
)
368 static const struct dcn10_opp_mask opp_mask
= {
369 OPP_MASK_SH_LIST_DCN10(_MASK
),
372 #define aux_engine_regs(id)\
374 AUX_COMMON_REG_LIST(id), \
375 .AUX_RESET_MASK = 0 \
378 static const struct dce110_aux_registers aux_engine_regs
[] = {
389 TF_REG_LIST_DCN10(id),\
392 static const struct dcn_dpp_registers tf_regs
[] = {
399 static const struct dcn_dpp_shift tf_shift
= {
400 TF_REG_LIST_SH_MASK_DCN10(__SHIFT
),
401 TF_DEBUG_REG_LIST_SH_DCN10
405 static const struct dcn_dpp_mask tf_mask
= {
406 TF_REG_LIST_SH_MASK_DCN10(_MASK
),
407 TF_DEBUG_REG_LIST_MASK_DCN10
410 static const struct dcn_mpc_registers mpc_regs
= {
411 MPC_COMMON_REG_LIST_DCN1_0(0),
412 MPC_COMMON_REG_LIST_DCN1_0(1),
413 MPC_COMMON_REG_LIST_DCN1_0(2),
414 MPC_COMMON_REG_LIST_DCN1_0(3),
415 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(0),
416 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(1),
417 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(2),
418 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(3)
421 static const struct dcn_mpc_shift mpc_shift
= {
422 MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
)
425 static const struct dcn_mpc_mask mpc_mask
= {
426 MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK
),
430 [id] = {TG_COMMON_REG_LIST_DCN1_0(id)}
432 static const struct dcn_optc_registers tg_regs
[] = {
439 static const struct dcn_optc_shift tg_shift
= {
440 TG_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
)
443 static const struct dcn_optc_mask tg_mask
= {
444 TG_COMMON_MASK_SH_LIST_DCN1_0(_MASK
)
447 static const struct bios_registers bios_regs
= {
448 NBIO_SR(BIOS_SCRATCH_3
),
449 NBIO_SR(BIOS_SCRATCH_6
)
452 #define hubp_regs(id)\
454 HUBP_REG_LIST_DCN10(id)\
457 static const struct dcn_mi_registers hubp_regs
[] = {
464 static const struct dcn_mi_shift hubp_shift
= {
465 HUBP_MASK_SH_LIST_DCN10(__SHIFT
)
468 static const struct dcn_mi_mask hubp_mask
= {
469 HUBP_MASK_SH_LIST_DCN10(_MASK
)
472 static const struct dcn_hubbub_registers hubbub_reg
= {
473 HUBBUB_REG_LIST_DCN10(0)
476 static const struct dcn_hubbub_shift hubbub_shift
= {
477 HUBBUB_MASK_SH_LIST_DCN10(__SHIFT
)
480 static const struct dcn_hubbub_mask hubbub_mask
= {
481 HUBBUB_MASK_SH_LIST_DCN10(_MASK
)
484 static int map_transmitter_id_to_phy_instance(
485 enum transmitter transmitter
)
487 switch (transmitter
) {
488 case TRANSMITTER_UNIPHY_A
:
491 case TRANSMITTER_UNIPHY_B
:
494 case TRANSMITTER_UNIPHY_C
:
497 case TRANSMITTER_UNIPHY_D
:
506 #define clk_src_regs(index, pllid)\
508 CS_COMMON_REG_LIST_DCN1_0(index, pllid),\
511 static const struct dce110_clk_src_regs clk_src_regs
[] = {
518 static const struct dce110_clk_src_shift cs_shift
= {
519 CS_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
)
522 static const struct dce110_clk_src_mask cs_mask
= {
523 CS_COMMON_MASK_SH_LIST_DCN1_0(_MASK
)
526 static const struct resource_caps res_cap
= {
527 .num_timing_generator
= 4,
529 .num_video_plane
= 4,
531 .num_stream_encoder
= 4,
536 static const struct resource_caps rv2_res_cap
= {
537 .num_timing_generator
= 3,
539 .num_video_plane
= 3,
541 .num_stream_encoder
= 3,
546 static const struct dc_plane_cap plane_cap
= {
547 .type
= DC_PLANE_TYPE_DCN_UNIVERSAL
,
548 .blends_with_above
= true,
549 .blends_with_below
= true,
550 .per_pixel_alpha
= true,
552 .pixel_format_support
= {
558 .max_upscale_factor
= {
564 .max_downscale_factor
= {
571 static const struct dc_debug_options debug_defaults_drv
= {
572 .sanity_checks
= true,
573 .disable_dmcu
= true,
574 .force_abm_enable
= false,
575 .timing_trace
= false,
578 /* raven smu dones't allow 0 disp clk,
579 * smu min disp clk limit is 50Mhz
580 * keep min disp clk 100Mhz avoid smu hang
582 .min_disp_clk_khz
= 100000,
584 .disable_pplib_clock_request
= false,
585 .disable_pplib_wm_range
= false,
586 .pplib_wm_report_mode
= WM_REPORT_DEFAULT
,
587 .pipe_split_policy
= MPC_SPLIT_AVOID_MULT_DISP
,
588 .force_single_disp_pipe_split
= true,
589 .disable_dcc
= DCC_ENABLE
,
590 .voltage_align_fclk
= true,
591 .disable_stereo_support
= true,
593 .performance_trace
= false,
594 .az_endpoint_mute_only
= true,
595 .recovery_enabled
= false, /*enable this by default after testing.*/
596 .max_downscale_src_width
= 3840,
597 .underflow_assert_delay_us
= 0xFFFFFFFF,
600 static const struct dc_debug_options debug_defaults_diags
= {
601 .disable_dmcu
= true,
602 .force_abm_enable
= false,
603 .timing_trace
= true,
605 .disable_stutter
= true,
606 .disable_pplib_clock_request
= true,
607 .disable_pplib_wm_range
= true,
608 .underflow_assert_delay_us
= 0xFFFFFFFF,
611 static void dcn10_dpp_destroy(struct dpp
**dpp
)
613 kfree(TO_DCN10_DPP(*dpp
));
617 static struct dpp
*dcn10_dpp_create(
618 struct dc_context
*ctx
,
621 struct dcn10_dpp
*dpp
=
622 kzalloc(sizeof(struct dcn10_dpp
), GFP_KERNEL
);
627 dpp1_construct(dpp
, ctx
, inst
,
628 &tf_regs
[inst
], &tf_shift
, &tf_mask
);
632 static struct input_pixel_processor
*dcn10_ipp_create(
633 struct dc_context
*ctx
, uint32_t inst
)
635 struct dcn10_ipp
*ipp
=
636 kzalloc(sizeof(struct dcn10_ipp
), GFP_KERNEL
);
643 dcn10_ipp_construct(ipp
, ctx
, inst
,
644 &ipp_regs
[inst
], &ipp_shift
, &ipp_mask
);
649 static struct output_pixel_processor
*dcn10_opp_create(
650 struct dc_context
*ctx
, uint32_t inst
)
652 struct dcn10_opp
*opp
=
653 kzalloc(sizeof(struct dcn10_opp
), GFP_KERNEL
);
660 dcn10_opp_construct(opp
, ctx
, inst
,
661 &opp_regs
[inst
], &opp_shift
, &opp_mask
);
665 struct dce_aux
*dcn10_aux_engine_create(
666 struct dc_context
*ctx
,
669 struct aux_engine_dce110
*aux_engine
=
670 kzalloc(sizeof(struct aux_engine_dce110
), GFP_KERNEL
);
675 dce110_aux_engine_construct(aux_engine
, ctx
, inst
,
676 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER
* AUX_TIMEOUT_PERIOD
,
677 &aux_engine_regs
[inst
],
680 ctx
->dc
->caps
.extended_aux_timeout_support
);
682 return &aux_engine
->base
;
684 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
686 static const struct dce_i2c_registers i2c_hw_regs
[] = {
695 static const struct dce_i2c_shift i2c_shifts
= {
696 I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT
)
699 static const struct dce_i2c_mask i2c_masks
= {
700 I2C_COMMON_MASK_SH_LIST_DCE110(_MASK
)
703 struct dce_i2c_hw
*dcn10_i2c_hw_create(
704 struct dc_context
*ctx
,
707 struct dce_i2c_hw
*dce_i2c_hw
=
708 kzalloc(sizeof(struct dce_i2c_hw
), GFP_KERNEL
);
713 dcn1_i2c_hw_construct(dce_i2c_hw
, ctx
, inst
,
714 &i2c_hw_regs
[inst
], &i2c_shifts
, &i2c_masks
);
718 static struct mpc
*dcn10_mpc_create(struct dc_context
*ctx
)
720 struct dcn10_mpc
*mpc10
= kzalloc(sizeof(struct dcn10_mpc
),
726 dcn10_mpc_construct(mpc10
, ctx
,
735 static struct hubbub
*dcn10_hubbub_create(struct dc_context
*ctx
)
737 struct dcn10_hubbub
*dcn10_hubbub
= kzalloc(sizeof(struct dcn10_hubbub
),
743 hubbub1_construct(&dcn10_hubbub
->base
, ctx
,
748 return &dcn10_hubbub
->base
;
751 static struct timing_generator
*dcn10_timing_generator_create(
752 struct dc_context
*ctx
,
756 kzalloc(sizeof(struct optc
), GFP_KERNEL
);
761 tgn10
->base
.inst
= instance
;
762 tgn10
->base
.ctx
= ctx
;
764 tgn10
->tg_regs
= &tg_regs
[instance
];
765 tgn10
->tg_shift
= &tg_shift
;
766 tgn10
->tg_mask
= &tg_mask
;
768 dcn10_timing_generator_init(tgn10
);
773 static const struct encoder_feature_support link_enc_feature
= {
774 .max_hdmi_deep_color
= COLOR_DEPTH_121212
,
775 .max_hdmi_pixel_clock
= 600000,
776 .hdmi_ycbcr420_supported
= true,
777 .dp_ycbcr420_supported
= false,
778 .flags
.bits
.IS_HBR2_CAPABLE
= true,
779 .flags
.bits
.IS_HBR3_CAPABLE
= true,
780 .flags
.bits
.IS_TPS3_CAPABLE
= true,
781 .flags
.bits
.IS_TPS4_CAPABLE
= true
784 struct link_encoder
*dcn10_link_encoder_create(
785 const struct encoder_init_data
*enc_init_data
)
787 struct dcn10_link_encoder
*enc10
=
788 kzalloc(sizeof(struct dcn10_link_encoder
), GFP_KERNEL
);
795 map_transmitter_id_to_phy_instance(enc_init_data
->transmitter
);
797 dcn10_link_encoder_construct(enc10
,
800 &link_enc_regs
[link_regs_id
],
801 &link_enc_aux_regs
[enc_init_data
->channel
- 1],
802 &link_enc_hpd_regs
[enc_init_data
->hpd_source
],
809 struct clock_source
*dcn10_clock_source_create(
810 struct dc_context
*ctx
,
811 struct dc_bios
*bios
,
812 enum clock_source_id id
,
813 const struct dce110_clk_src_regs
*regs
,
816 struct dce110_clk_src
*clk_src
=
817 kzalloc(sizeof(struct dce110_clk_src
), GFP_KERNEL
);
822 if (dce112_clk_src_construct(clk_src
, ctx
, bios
, id
,
823 regs
, &cs_shift
, &cs_mask
)) {
824 clk_src
->base
.dp_clk_src
= dp_clk_src
;
825 return &clk_src
->base
;
833 static void read_dce_straps(
834 struct dc_context
*ctx
,
835 struct resource_straps
*straps
)
837 generic_reg_get(ctx
, mmDC_PINSTRAPS
+ BASE(mmDC_PINSTRAPS_BASE_IDX
),
838 FN(DC_PINSTRAPS
, DC_PINSTRAPS_AUDIO
), &straps
->dc_pinstraps_audio
);
841 static struct audio
*create_audio(
842 struct dc_context
*ctx
, unsigned int inst
)
844 return dce_audio_create(ctx
, inst
,
845 &audio_regs
[inst
], &audio_shift
, &audio_mask
);
848 static struct stream_encoder
*dcn10_stream_encoder_create(
849 enum engine_id eng_id
,
850 struct dc_context
*ctx
)
852 struct dcn10_stream_encoder
*enc1
=
853 kzalloc(sizeof(struct dcn10_stream_encoder
), GFP_KERNEL
);
858 dcn10_stream_encoder_construct(enc1
, ctx
, ctx
->dc_bios
, eng_id
,
859 &stream_enc_regs
[eng_id
],
860 &se_shift
, &se_mask
);
864 static const struct dce_hwseq_registers hwseq_reg
= {
865 HWSEQ_DCN1_REG_LIST()
868 static const struct dce_hwseq_shift hwseq_shift
= {
869 HWSEQ_DCN1_MASK_SH_LIST(__SHIFT
)
872 static const struct dce_hwseq_mask hwseq_mask
= {
873 HWSEQ_DCN1_MASK_SH_LIST(_MASK
)
876 static struct dce_hwseq
*dcn10_hwseq_create(
877 struct dc_context
*ctx
)
879 struct dce_hwseq
*hws
= kzalloc(sizeof(struct dce_hwseq
), GFP_KERNEL
);
883 hws
->regs
= &hwseq_reg
;
884 hws
->shifts
= &hwseq_shift
;
885 hws
->masks
= &hwseq_mask
;
886 hws
->wa
.DEGVIDCN10_253
= true;
887 hws
->wa
.false_optc_underflow
= true;
888 hws
->wa
.DEGVIDCN10_254
= true;
893 static const struct resource_create_funcs res_create_funcs
= {
894 .read_dce_straps
= read_dce_straps
,
895 .create_audio
= create_audio
,
896 .create_stream_encoder
= dcn10_stream_encoder_create
,
897 .create_hwseq
= dcn10_hwseq_create
,
900 static const struct resource_create_funcs res_create_maximus_funcs
= {
901 .read_dce_straps
= NULL
,
902 .create_audio
= NULL
,
903 .create_stream_encoder
= NULL
,
904 .create_hwseq
= dcn10_hwseq_create
,
907 void dcn10_clock_source_destroy(struct clock_source
**clk_src
)
909 kfree(TO_DCE110_CLK_SRC(*clk_src
));
913 static struct pp_smu_funcs
*dcn10_pp_smu_create(struct dc_context
*ctx
)
915 struct pp_smu_funcs
*pp_smu
= kzalloc(sizeof(*pp_smu
), GFP_KERNEL
);
920 dm_pp_get_funcs(ctx
, pp_smu
);
924 static void dcn10_resource_destruct(struct dcn10_resource_pool
*pool
)
928 for (i
= 0; i
< pool
->base
.stream_enc_count
; i
++) {
929 if (pool
->base
.stream_enc
[i
] != NULL
) {
930 kfree(DCN10STRENC_FROM_STRENC(pool
->base
.stream_enc
[i
]));
931 pool
->base
.stream_enc
[i
] = NULL
;
935 if (pool
->base
.mpc
!= NULL
) {
936 kfree(TO_DCN10_MPC(pool
->base
.mpc
));
937 pool
->base
.mpc
= NULL
;
940 if (pool
->base
.hubbub
!= NULL
) {
941 kfree(pool
->base
.hubbub
);
942 pool
->base
.hubbub
= NULL
;
945 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
946 if (pool
->base
.opps
[i
] != NULL
)
947 pool
->base
.opps
[i
]->funcs
->opp_destroy(&pool
->base
.opps
[i
]);
949 if (pool
->base
.dpps
[i
] != NULL
)
950 dcn10_dpp_destroy(&pool
->base
.dpps
[i
]);
952 if (pool
->base
.ipps
[i
] != NULL
)
953 pool
->base
.ipps
[i
]->funcs
->ipp_destroy(&pool
->base
.ipps
[i
]);
955 if (pool
->base
.hubps
[i
] != NULL
) {
956 kfree(TO_DCN10_HUBP(pool
->base
.hubps
[i
]));
957 pool
->base
.hubps
[i
] = NULL
;
960 if (pool
->base
.irqs
!= NULL
) {
961 dal_irq_service_destroy(&pool
->base
.irqs
);
964 if (pool
->base
.timing_generators
[i
] != NULL
) {
965 kfree(DCN10TG_FROM_TG(pool
->base
.timing_generators
[i
]));
966 pool
->base
.timing_generators
[i
] = NULL
;
970 for (i
= 0; i
< pool
->base
.res_cap
->num_ddc
; i
++) {
971 if (pool
->base
.engines
[i
] != NULL
)
972 dce110_engine_destroy(&pool
->base
.engines
[i
]);
973 if (pool
->base
.hw_i2cs
[i
] != NULL
) {
974 kfree(pool
->base
.hw_i2cs
[i
]);
975 pool
->base
.hw_i2cs
[i
] = NULL
;
977 if (pool
->base
.sw_i2cs
[i
] != NULL
) {
978 kfree(pool
->base
.sw_i2cs
[i
]);
979 pool
->base
.sw_i2cs
[i
] = NULL
;
983 for (i
= 0; i
< pool
->base
.audio_count
; i
++) {
984 if (pool
->base
.audios
[i
])
985 dce_aud_destroy(&pool
->base
.audios
[i
]);
988 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
989 if (pool
->base
.clock_sources
[i
] != NULL
) {
990 dcn10_clock_source_destroy(&pool
->base
.clock_sources
[i
]);
991 pool
->base
.clock_sources
[i
] = NULL
;
995 if (pool
->base
.dp_clock_source
!= NULL
) {
996 dcn10_clock_source_destroy(&pool
->base
.dp_clock_source
);
997 pool
->base
.dp_clock_source
= NULL
;
1000 if (pool
->base
.abm
!= NULL
)
1001 dce_abm_destroy(&pool
->base
.abm
);
1003 if (pool
->base
.dmcu
!= NULL
)
1004 dce_dmcu_destroy(&pool
->base
.dmcu
);
1006 kfree(pool
->base
.pp_smu
);
1009 static struct hubp
*dcn10_hubp_create(
1010 struct dc_context
*ctx
,
1013 struct dcn10_hubp
*hubp1
=
1014 kzalloc(sizeof(struct dcn10_hubp
), GFP_KERNEL
);
1019 dcn10_hubp_construct(hubp1
, ctx
, inst
,
1020 &hubp_regs
[inst
], &hubp_shift
, &hubp_mask
);
1021 return &hubp1
->base
;
1024 static void get_pixel_clock_parameters(
1025 const struct pipe_ctx
*pipe_ctx
,
1026 struct pixel_clk_params
*pixel_clk_params
)
1028 const struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1029 pixel_clk_params
->requested_pix_clk_100hz
= stream
->timing
.pix_clk_100hz
;
1030 pixel_clk_params
->encoder_object_id
= stream
->link
->link_enc
->id
;
1031 pixel_clk_params
->signal_type
= pipe_ctx
->stream
->signal
;
1032 pixel_clk_params
->controller_id
= pipe_ctx
->stream_res
.tg
->inst
+ 1;
1033 /* TODO: un-hardcode*/
1034 pixel_clk_params
->requested_sym_clk
= LINK_RATE_LOW
*
1035 LINK_RATE_REF_FREQ_IN_KHZ
;
1036 pixel_clk_params
->flags
.ENABLE_SS
= 0;
1037 pixel_clk_params
->color_depth
=
1038 stream
->timing
.display_color_depth
;
1039 pixel_clk_params
->flags
.DISPLAY_BLANKED
= 1;
1040 pixel_clk_params
->pixel_encoding
= stream
->timing
.pixel_encoding
;
1042 if (stream
->timing
.pixel_encoding
== PIXEL_ENCODING_YCBCR422
)
1043 pixel_clk_params
->color_depth
= COLOR_DEPTH_888
;
1045 if (stream
->timing
.pixel_encoding
== PIXEL_ENCODING_YCBCR420
)
1046 pixel_clk_params
->requested_pix_clk_100hz
/= 2;
1047 if (stream
->timing
.timing_3d_format
== TIMING_3D_FORMAT_HW_FRAME_PACKING
)
1048 pixel_clk_params
->requested_pix_clk_100hz
*= 2;
1052 static void build_clamping_params(struct dc_stream_state
*stream
)
1054 stream
->clamping
.clamping_level
= CLAMPING_FULL_RANGE
;
1055 stream
->clamping
.c_depth
= stream
->timing
.display_color_depth
;
1056 stream
->clamping
.pixel_encoding
= stream
->timing
.pixel_encoding
;
1059 static void build_pipe_hw_param(struct pipe_ctx
*pipe_ctx
)
1062 get_pixel_clock_parameters(pipe_ctx
, &pipe_ctx
->stream_res
.pix_clk_params
);
1064 pipe_ctx
->clock_source
->funcs
->get_pix_clk_dividers(
1065 pipe_ctx
->clock_source
,
1066 &pipe_ctx
->stream_res
.pix_clk_params
,
1067 &pipe_ctx
->pll_settings
);
1069 pipe_ctx
->stream
->clamping
.pixel_encoding
= pipe_ctx
->stream
->timing
.pixel_encoding
;
1071 resource_build_bit_depth_reduction_params(pipe_ctx
->stream
,
1072 &pipe_ctx
->stream
->bit_depth_params
);
1073 build_clamping_params(pipe_ctx
->stream
);
1076 static enum dc_status
build_mapped_resource(
1077 const struct dc
*dc
,
1078 struct dc_state
*context
,
1079 struct dc_stream_state
*stream
)
1081 struct pipe_ctx
*pipe_ctx
= resource_get_head_pipe_for_stream(&context
->res_ctx
, stream
);
1083 /*TODO Seems unneeded anymore */
1084 /* if (old_context && resource_is_stream_unchanged(old_context, stream)) {
1085 if (stream != NULL && old_context->streams[i] != NULL) {
1086 todo: shouldn't have to copy missing parameter here
1087 resource_build_bit_depth_reduction_params(stream,
1088 &stream->bit_depth_params);
1089 stream->clamping.pixel_encoding =
1090 stream->timing.pixel_encoding;
1092 resource_build_bit_depth_reduction_params(stream,
1093 &stream->bit_depth_params);
1094 build_clamping_params(stream);
1102 return DC_ERROR_UNEXPECTED
;
1104 build_pipe_hw_param(pipe_ctx
);
1108 enum dc_status
dcn10_add_stream_to_ctx(
1110 struct dc_state
*new_ctx
,
1111 struct dc_stream_state
*dc_stream
)
1113 enum dc_status result
= DC_ERROR_UNEXPECTED
;
1115 result
= resource_map_pool_resources(dc
, new_ctx
, dc_stream
);
1117 if (result
== DC_OK
)
1118 result
= resource_map_phy_clock_resources(dc
, new_ctx
, dc_stream
);
1121 if (result
== DC_OK
)
1122 result
= build_mapped_resource(dc
, new_ctx
, dc_stream
);
1127 static struct pipe_ctx
*dcn10_acquire_idle_pipe_for_layer(
1128 struct dc_state
*context
,
1129 const struct resource_pool
*pool
,
1130 struct dc_stream_state
*stream
)
1132 struct resource_context
*res_ctx
= &context
->res_ctx
;
1133 struct pipe_ctx
*head_pipe
= resource_get_head_pipe_for_stream(res_ctx
, stream
);
1134 struct pipe_ctx
*idle_pipe
= find_idle_secondary_pipe(res_ctx
, pool
, head_pipe
);
1144 idle_pipe
->stream
= head_pipe
->stream
;
1145 idle_pipe
->stream_res
.tg
= head_pipe
->stream_res
.tg
;
1146 idle_pipe
->stream_res
.abm
= head_pipe
->stream_res
.abm
;
1147 idle_pipe
->stream_res
.opp
= head_pipe
->stream_res
.opp
;
1149 idle_pipe
->plane_res
.hubp
= pool
->hubps
[idle_pipe
->pipe_idx
];
1150 idle_pipe
->plane_res
.ipp
= pool
->ipps
[idle_pipe
->pipe_idx
];
1151 idle_pipe
->plane_res
.dpp
= pool
->dpps
[idle_pipe
->pipe_idx
];
1152 idle_pipe
->plane_res
.mpcc_inst
= pool
->dpps
[idle_pipe
->pipe_idx
]->inst
;
1157 static bool dcn10_get_dcc_compression_cap(const struct dc
*dc
,
1158 const struct dc_dcc_surface_param
*input
,
1159 struct dc_surface_dcc_cap
*output
)
1161 return dc
->res_pool
->hubbub
->funcs
->get_dcc_compression_cap(
1162 dc
->res_pool
->hubbub
,
1167 static void dcn10_destroy_resource_pool(struct resource_pool
**pool
)
1169 struct dcn10_resource_pool
*dcn10_pool
= TO_DCN10_RES_POOL(*pool
);
1171 dcn10_resource_destruct(dcn10_pool
);
1176 static enum dc_status
dcn10_validate_plane(const struct dc_plane_state
*plane_state
, struct dc_caps
*caps
)
1178 if (plane_state
->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
1179 && caps
->max_video_width
!= 0
1180 && plane_state
->src_rect
.width
> caps
->max_video_width
)
1181 return DC_FAIL_SURFACE_VALIDATE
;
1186 static enum dc_status
dcn10_validate_global(struct dc
*dc
, struct dc_state
*context
)
1189 bool video_down_scaled
= false;
1190 bool video_large
= false;
1191 bool desktop_large
= false;
1192 bool dcc_disabled
= false;
1194 for (i
= 0; i
< context
->stream_count
; i
++) {
1195 if (context
->stream_status
[i
].plane_count
== 0)
1198 if (context
->stream_status
[i
].plane_count
> 2)
1199 return DC_FAIL_UNSUPPORTED_1
;
1201 for (j
= 0; j
< context
->stream_status
[i
].plane_count
; j
++) {
1202 struct dc_plane_state
*plane
=
1203 context
->stream_status
[i
].plane_states
[j
];
1206 if (plane
->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
) {
1208 if (plane
->src_rect
.width
> plane
->dst_rect
.width
||
1209 plane
->src_rect
.height
> plane
->dst_rect
.height
)
1210 video_down_scaled
= true;
1212 if (plane
->src_rect
.width
>= 3840)
1216 if (plane
->src_rect
.width
>= 3840)
1217 desktop_large
= true;
1218 if (!plane
->dcc
.enable
)
1219 dcc_disabled
= true;
1225 * Workaround: On DCN10 there is UMC issue that causes underflow when
1226 * playing 4k video on 4k desktop with video downscaled and single channel
1229 if (video_large
&& desktop_large
&& video_down_scaled
&& dcc_disabled
&&
1230 dc
->dcn_soc
->number_of_channels
== 1)
1231 return DC_FAIL_SURFACE_VALIDATE
;
1236 static enum dc_status
dcn10_get_default_swizzle_mode(struct dc_plane_state
*plane_state
)
1238 enum dc_status result
= DC_OK
;
1240 enum surface_pixel_format surf_pix_format
= plane_state
->format
;
1241 unsigned int bpp
= resource_pixel_format_to_bpp(surf_pix_format
);
1243 enum swizzle_mode_values swizzle
= DC_SW_LINEAR
;
1246 swizzle
= DC_SW_64KB_D
;
1248 swizzle
= DC_SW_64KB_S
;
1250 plane_state
->tiling_info
.gfx9
.swizzle
= swizzle
;
1254 struct stream_encoder
*dcn10_find_first_free_match_stream_enc_for_link(
1255 struct resource_context
*res_ctx
,
1256 const struct resource_pool
*pool
,
1257 struct dc_stream_state
*stream
)
1261 struct dc_link
*link
= stream
->link
;
1263 for (i
= 0; i
< pool
->stream_enc_count
; i
++) {
1264 if (!res_ctx
->is_stream_enc_acquired
[i
] &&
1265 pool
->stream_enc
[i
]) {
1266 /* Store first available for MST second display
1267 * in daisy chain use case
1270 if (pool
->stream_enc
[i
]->id
==
1271 link
->link_enc
->preferred_engine
)
1272 return pool
->stream_enc
[i
];
1277 * For CZ and later, we can allow DIG FE and BE to differ for all display types
1281 return pool
->stream_enc
[j
];
1286 static const struct dc_cap_funcs cap_funcs
= {
1287 .get_dcc_compression_cap
= dcn10_get_dcc_compression_cap
1290 static const struct resource_funcs dcn10_res_pool_funcs
= {
1291 .destroy
= dcn10_destroy_resource_pool
,
1292 .link_enc_create
= dcn10_link_encoder_create
,
1293 .validate_bandwidth
= dcn_validate_bandwidth
,
1294 .acquire_idle_pipe_for_layer
= dcn10_acquire_idle_pipe_for_layer
,
1295 .validate_plane
= dcn10_validate_plane
,
1296 .validate_global
= dcn10_validate_global
,
1297 .add_stream_to_ctx
= dcn10_add_stream_to_ctx
,
1298 .get_default_swizzle_mode
= dcn10_get_default_swizzle_mode
,
1299 .find_first_free_match_stream_enc_for_link
= dcn10_find_first_free_match_stream_enc_for_link
1302 static uint32_t read_pipe_fuses(struct dc_context
*ctx
)
1304 uint32_t value
= dm_read_reg_soc15(ctx
, mmCC_DC_PIPE_DIS
, 0);
1305 /* RV1 support max 4 pipes */
1306 value
= value
& 0xf;
1310 static bool dcn10_resource_construct(
1311 uint8_t num_virtual_links
,
1313 struct dcn10_resource_pool
*pool
)
1317 struct dc_context
*ctx
= dc
->ctx
;
1318 uint32_t pipe_fuses
= read_pipe_fuses(ctx
);
1320 ctx
->dc_bios
->regs
= &bios_regs
;
1322 if (ctx
->dce_version
== DCN_VERSION_1_01
)
1323 pool
->base
.res_cap
= &rv2_res_cap
;
1325 pool
->base
.res_cap
= &res_cap
;
1326 pool
->base
.funcs
= &dcn10_res_pool_funcs
;
1329 * TODO fill in from actual raven resource when we create
1330 * more than virtual encoder
1333 /*************************************************
1334 * Resource + asic cap harcoding *
1335 *************************************************/
1336 pool
->base
.underlay_pipe_index
= NO_UNDERLAY_PIPE
;
1338 /* max pipe num for ASIC before check pipe fuses */
1339 pool
->base
.pipe_count
= pool
->base
.res_cap
->num_timing_generator
;
1341 if (dc
->ctx
->dce_version
== DCN_VERSION_1_01
)
1342 pool
->base
.pipe_count
= 3;
1343 dc
->caps
.max_video_width
= 3840;
1344 dc
->caps
.max_downscale_ratio
= 200;
1345 dc
->caps
.i2c_speed_in_khz
= 100;
1346 dc
->caps
.max_cursor_size
= 256;
1347 dc
->caps
.max_slave_planes
= 1;
1348 dc
->caps
.is_apu
= true;
1349 dc
->caps
.post_blend_color_processing
= false;
1350 dc
->caps
.extended_aux_timeout_support
= false;
1352 /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
1353 dc
->caps
.force_dp_tps4_for_cp2520
= true;
1355 if (dc
->ctx
->dce_environment
== DCE_ENV_PRODUCTION_DRV
)
1356 dc
->debug
= debug_defaults_drv
;
1358 dc
->debug
= debug_defaults_diags
;
1360 /*************************************************
1361 * Create resources *
1362 *************************************************/
1364 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL0
] =
1365 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1366 CLOCK_SOURCE_COMBO_PHY_PLL0
,
1367 &clk_src_regs
[0], false);
1368 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL1
] =
1369 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1370 CLOCK_SOURCE_COMBO_PHY_PLL1
,
1371 &clk_src_regs
[1], false);
1372 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL2
] =
1373 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1374 CLOCK_SOURCE_COMBO_PHY_PLL2
,
1375 &clk_src_regs
[2], false);
1377 if (dc
->ctx
->dce_version
== DCN_VERSION_1_0
) {
1378 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL3
] =
1379 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1380 CLOCK_SOURCE_COMBO_PHY_PLL3
,
1381 &clk_src_regs
[3], false);
1384 pool
->base
.clk_src_count
= DCN10_CLK_SRC_TOTAL
;
1386 if (dc
->ctx
->dce_version
== DCN_VERSION_1_01
)
1387 pool
->base
.clk_src_count
= DCN101_CLK_SRC_TOTAL
;
1389 pool
->base
.dp_clock_source
=
1390 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1391 CLOCK_SOURCE_ID_DP_DTO
,
1392 /* todo: not reuse phy_pll registers */
1393 &clk_src_regs
[0], true);
1395 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
1396 if (pool
->base
.clock_sources
[i
] == NULL
) {
1397 dm_error("DC: failed to create clock sources!\n");
1398 BREAK_TO_DEBUGGER();
1403 pool
->base
.dmcu
= dcn10_dmcu_create(ctx
,
1407 if (pool
->base
.dmcu
== NULL
) {
1408 dm_error("DC: failed to create dmcu!\n");
1409 BREAK_TO_DEBUGGER();
1413 pool
->base
.abm
= dce_abm_create(ctx
,
1417 if (pool
->base
.abm
== NULL
) {
1418 dm_error("DC: failed to create abm!\n");
1419 BREAK_TO_DEBUGGER();
1423 dml_init_instance(&dc
->dml
, &dcn1_0_soc
, &dcn1_0_ip
, DML_PROJECT_RAVEN1
);
1424 memcpy(dc
->dcn_ip
, &dcn10_ip_defaults
, sizeof(dcn10_ip_defaults
));
1425 memcpy(dc
->dcn_soc
, &dcn10_soc_defaults
, sizeof(dcn10_soc_defaults
));
1427 if (dc
->ctx
->dce_version
== DCN_VERSION_1_01
) {
1428 struct dcn_soc_bounding_box
*dcn_soc
= dc
->dcn_soc
;
1429 struct dcn_ip_params
*dcn_ip
= dc
->dcn_ip
;
1430 struct display_mode_lib
*dml
= &dc
->dml
;
1432 dml
->ip
.max_num_dpp
= 3;
1433 /* TODO how to handle 23.84? */
1434 dcn_soc
->dram_clock_change_latency
= 23;
1435 dcn_ip
->max_num_dpp
= 3;
1437 if (ASICREV_IS_RV1_F0(dc
->ctx
->asic_id
.hw_internal_rev
)) {
1438 dc
->dcn_soc
->urgent_latency
= 3;
1439 dc
->debug
.disable_dmcu
= true;
1440 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
= 41.60f
;
1444 dc
->dcn_soc
->number_of_channels
= dc
->ctx
->asic_id
.vram_width
/ ddr4_dram_width
;
1445 ASSERT(dc
->dcn_soc
->number_of_channels
< 3);
1446 if (dc
->dcn_soc
->number_of_channels
== 0)/*old sbios bug*/
1447 dc
->dcn_soc
->number_of_channels
= 2;
1449 if (dc
->dcn_soc
->number_of_channels
== 1) {
1450 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
= 19.2f
;
1451 dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
= 17.066f
;
1452 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
= 14.933f
;
1453 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
= 12.8f
;
1454 if (ASICREV_IS_RV1_F0(dc
->ctx
->asic_id
.hw_internal_rev
)) {
1455 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
= 20.80f
;
1459 pool
->base
.pp_smu
= dcn10_pp_smu_create(ctx
);
1462 * Right now SMU/PPLIB and DAL all have the AZ D3 force PME notification *
1463 * implemented. So AZ D3 should work.For issue 197007. *
1465 if (pool
->base
.pp_smu
!= NULL
1466 && pool
->base
.pp_smu
->rv_funcs
.set_pme_wa_enable
!= NULL
)
1467 dc
->debug
.az_endpoint_mute_only
= false;
1469 if (!dc
->debug
.disable_pplib_clock_request
)
1470 dcn_bw_update_from_pplib(dc
);
1471 dcn_bw_sync_calcs_and_dml(dc
);
1472 if (!dc
->debug
.disable_pplib_wm_range
) {
1473 dc
->res_pool
= &pool
->base
;
1474 dcn_bw_notify_pplib_of_wm_ranges(dc
);
1478 struct irq_service_init_data init_data
;
1479 init_data
.ctx
= dc
->ctx
;
1480 pool
->base
.irqs
= dal_irq_service_dcn10_create(&init_data
);
1481 if (!pool
->base
.irqs
)
1485 /* index to valid pipe resource */
1487 /* mem input -> ipp -> dpp -> opp -> TG */
1488 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
1489 /* if pipe is disabled, skip instance of HW pipe,
1490 * i.e, skip ASIC register instance
1492 if ((pipe_fuses
& (1 << i
)) != 0)
1495 pool
->base
.hubps
[j
] = dcn10_hubp_create(ctx
, i
);
1496 if (pool
->base
.hubps
[j
] == NULL
) {
1497 BREAK_TO_DEBUGGER();
1499 "DC: failed to create memory input!\n");
1503 pool
->base
.ipps
[j
] = dcn10_ipp_create(ctx
, i
);
1504 if (pool
->base
.ipps
[j
] == NULL
) {
1505 BREAK_TO_DEBUGGER();
1507 "DC: failed to create input pixel processor!\n");
1511 pool
->base
.dpps
[j
] = dcn10_dpp_create(ctx
, i
);
1512 if (pool
->base
.dpps
[j
] == NULL
) {
1513 BREAK_TO_DEBUGGER();
1515 "DC: failed to create dpp!\n");
1519 pool
->base
.opps
[j
] = dcn10_opp_create(ctx
, i
);
1520 if (pool
->base
.opps
[j
] == NULL
) {
1521 BREAK_TO_DEBUGGER();
1523 "DC: failed to create output pixel processor!\n");
1527 pool
->base
.timing_generators
[j
] = dcn10_timing_generator_create(
1529 if (pool
->base
.timing_generators
[j
] == NULL
) {
1530 BREAK_TO_DEBUGGER();
1531 dm_error("DC: failed to create tg!\n");
1534 /* check next valid pipe */
1538 for (i
= 0; i
< pool
->base
.res_cap
->num_ddc
; i
++) {
1539 pool
->base
.engines
[i
] = dcn10_aux_engine_create(ctx
, i
);
1540 if (pool
->base
.engines
[i
] == NULL
) {
1541 BREAK_TO_DEBUGGER();
1543 "DC:failed to create aux engine!!\n");
1546 pool
->base
.hw_i2cs
[i
] = dcn10_i2c_hw_create(ctx
, i
);
1547 if (pool
->base
.hw_i2cs
[i
] == NULL
) {
1548 BREAK_TO_DEBUGGER();
1550 "DC:failed to create hw i2c!!\n");
1553 pool
->base
.sw_i2cs
[i
] = NULL
;
1556 /* valid pipe num */
1557 pool
->base
.pipe_count
= j
;
1558 pool
->base
.timing_generator_count
= j
;
1560 /* within dml lib, it is hard code to 4. If ASIC pipe is fused,
1561 * the value may be changed
1563 dc
->dml
.ip
.max_num_dpp
= pool
->base
.pipe_count
;
1564 dc
->dcn_ip
->max_num_dpp
= pool
->base
.pipe_count
;
1566 pool
->base
.mpc
= dcn10_mpc_create(ctx
);
1567 if (pool
->base
.mpc
== NULL
) {
1568 BREAK_TO_DEBUGGER();
1569 dm_error("DC: failed to create mpc!\n");
1573 pool
->base
.hubbub
= dcn10_hubbub_create(ctx
);
1574 if (pool
->base
.hubbub
== NULL
) {
1575 BREAK_TO_DEBUGGER();
1576 dm_error("DC: failed to create hubbub!\n");
1580 if (!resource_construct(num_virtual_links
, dc
, &pool
->base
,
1581 (!IS_FPGA_MAXIMUS_DC(dc
->ctx
->dce_environment
) ?
1582 &res_create_funcs
: &res_create_maximus_funcs
)))
1585 dcn10_hw_sequencer_construct(dc
);
1586 dc
->caps
.max_planes
= pool
->base
.pipe_count
;
1588 for (i
= 0; i
< dc
->caps
.max_planes
; ++i
)
1589 dc
->caps
.planes
[i
] = plane_cap
;
1591 dc
->cap_funcs
= cap_funcs
;
1597 dcn10_resource_destruct(pool
);
1602 struct resource_pool
*dcn10_create_resource_pool(
1603 const struct dc_init_data
*init_data
,
1606 struct dcn10_resource_pool
*pool
=
1607 kzalloc(sizeof(struct dcn10_resource_pool
), GFP_KERNEL
);
1612 if (dcn10_resource_construct(init_data
->num_virtual_links
, dc
, pool
))
1616 BREAK_TO_DEBUGGER();