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"
54 #include "dce/dce_panel_cntl.h"
56 #include "soc15_hw_ip.h"
57 #include "vega10_ip_offset.h"
59 #include "dcn/dcn_1_0_offset.h"
60 #include "dcn/dcn_1_0_sh_mask.h"
62 #include "nbio/nbio_7_0_offset.h"
64 #include "mmhub/mmhub_9_1_offset.h"
65 #include "mmhub/mmhub_9_1_sh_mask.h"
67 #include "reg_helper.h"
68 #include "dce/dce_abm.h"
69 #include "dce/dce_dmcu.h"
70 #include "dce/dce_aux.h"
71 #include "dce/dce_i2c.h"
73 const struct _vcs_dpi_ip_params_st dcn1_0_ip
= {
74 .rob_buffer_size_kbytes
= 64,
75 .det_buffer_size_kbytes
= 164,
76 .dpte_buffer_size_in_pte_reqs_luma
= 42,
77 .dpp_output_buffer_pixels
= 2560,
78 .opp_output_buffer_lines
= 1,
79 .pixel_chunk_size_kbytes
= 8,
81 .pte_chunk_size_kbytes
= 2,
82 .meta_chunk_size_kbytes
= 2,
83 .writeback_chunk_size_kbytes
= 2,
84 .line_buffer_size_bits
= 589824,
85 .max_line_buffer_lines
= 12,
86 .IsLineBufferBppFixed
= 0,
87 .LineBufferFixedBpp
= -1,
88 .writeback_luma_buffer_size_kbytes
= 12,
89 .writeback_chroma_buffer_size_kbytes
= 8,
92 .max_dchub_pscl_bw_pix_per_clk
= 4,
93 .max_pscl_lb_bw_pix_per_clk
= 2,
94 .max_lb_vscl_bw_pix_per_clk
= 4,
95 .max_vscl_hscl_bw_pix_per_clk
= 4,
102 .dispclk_ramp_margin_percent
= 1,
103 .underscan_factor
= 1.10,
104 .min_vblank_lines
= 14,
105 .dppclk_delay_subtotal
= 90,
106 .dispclk_delay_subtotal
= 42,
107 .dcfclk_cstate_latency
= 10,
108 .max_inter_dcn_tile_repeaters
= 8,
109 .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
= 0,
110 .bug_forcing_LC_req_same_size_fixed
= 0,
113 const struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc
= {
114 .sr_exit_time_us
= 9.0,
115 .sr_enter_plus_exit_time_us
= 11.0,
116 .urgent_latency_us
= 4.0,
117 .writeback_latency_us
= 12.0,
118 .ideal_dram_bw_after_urgent_percent
= 80.0,
119 .max_request_size_bytes
= 256,
120 .downspread_percent
= 0.5,
121 .dram_page_open_time_ns
= 50.0,
122 .dram_rw_turnaround_time_ns
= 17.5,
123 .dram_return_buffer_per_channel_bytes
= 8192,
124 .round_trip_ping_latency_dcfclk_cycles
= 128,
125 .urgent_out_of_order_return_per_channel_bytes
= 256,
126 .channel_interleave_bytes
= 256,
129 .vmm_page_size_bytes
= 4096,
130 .dram_clock_change_latency_us
= 17.0,
131 .writeback_dram_clock_change_latency_us
= 23.0,
132 .return_bus_width_bytes
= 64,
135 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
136 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
137 #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
138 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
139 #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
140 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
141 #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
142 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
143 #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
144 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
145 #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
146 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f
147 #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
148 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f
149 #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
153 enum dcn10_clk_src_array_id
{
159 DCN101_CLK_SRC_TOTAL
= DCN10_CLK_SRC_PLL3
162 /* begin *********************
163 * macros to expend register list macro defined in HW object header file */
166 #define BASE_INNER(seg) \
167 DCE_BASE__INST0_SEG ## seg
172 #define SR(reg_name)\
173 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
176 #define SRI(reg_name, block, id)\
177 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
178 mm ## block ## id ## _ ## reg_name
181 #define SRII(reg_name, block, id)\
182 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
183 mm ## block ## id ## _ ## reg_name
185 #define VUPDATE_SRII(reg_name, block, id)\
186 .reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \
187 mm ## reg_name ## 0 ## _ ## block ## id
189 /* set field/register/bitfield name */
190 #define SFRB(field_name, reg_name, bitfield, post_fix)\
191 .field_name = reg_name ## __ ## bitfield ## post_fix
194 #define NBIO_BASE_INNER(seg) \
195 NBIF_BASE__INST0_SEG ## seg
197 #define NBIO_BASE(seg) \
200 #define NBIO_SR(reg_name)\
201 .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
205 #define MMHUB_BASE_INNER(seg) \
206 MMHUB_BASE__INST0_SEG ## seg
208 #define MMHUB_BASE(seg) \
209 MMHUB_BASE_INNER(seg)
211 #define MMHUB_SR(reg_name)\
212 .reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) + \
215 /* macros to expend register list macro defined in HW object header file
216 * end *********************/
219 static const struct dce_dmcu_registers dmcu_regs
= {
220 DMCU_DCN10_REG_LIST()
223 static const struct dce_dmcu_shift dmcu_shift
= {
224 DMCU_MASK_SH_LIST_DCN10(__SHIFT
)
227 static const struct dce_dmcu_mask dmcu_mask
= {
228 DMCU_MASK_SH_LIST_DCN10(_MASK
)
231 static const struct dce_abm_registers abm_regs
= {
232 ABM_DCN10_REG_LIST(0)
235 static const struct dce_abm_shift abm_shift
= {
236 ABM_MASK_SH_LIST_DCN10(__SHIFT
)
239 static const struct dce_abm_mask abm_mask
= {
240 ABM_MASK_SH_LIST_DCN10(_MASK
)
243 #define stream_enc_regs(id)\
248 static const struct dcn10_stream_enc_registers stream_enc_regs
[] = {
255 static const struct dcn10_stream_encoder_shift se_shift
= {
256 SE_COMMON_MASK_SH_LIST_DCN10(__SHIFT
)
259 static const struct dcn10_stream_encoder_mask se_mask
= {
260 SE_COMMON_MASK_SH_LIST_DCN10(_MASK
)
263 #define audio_regs(id)\
265 AUD_COMMON_REG_LIST(id)\
268 static const struct dce_audio_registers audio_regs
[] = {
275 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
276 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
277 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
278 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
280 static const struct dce_audio_shift audio_shift
= {
281 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT
)
284 static const struct dce_audio_mask audio_mask
= {
285 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK
)
288 #define aux_regs(id)\
293 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs
[] = {
300 #define hpd_regs(id)\
305 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs
[] = {
312 #define link_regs(id)\
314 LE_DCN10_REG_LIST(id), \
315 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
318 static const struct dcn10_link_enc_registers link_enc_regs
[] = {
325 static const struct dcn10_link_enc_shift le_shift
= {
326 LINK_ENCODER_MASK_SH_LIST_DCN10(__SHIFT
)
329 static const struct dcn10_link_enc_mask le_mask
= {
330 LINK_ENCODER_MASK_SH_LIST_DCN10(_MASK
)
333 static const struct dce_panel_cntl_registers panel_cntl_regs
[] = {
334 { DCN_PANEL_CNTL_REG_LIST() }
337 static const struct dce_panel_cntl_shift panel_cntl_shift
= {
338 DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT
)
341 static const struct dce_panel_cntl_mask panel_cntl_mask
= {
342 DCE_PANEL_CNTL_MASK_SH_LIST(_MASK
)
345 static const struct dce110_aux_registers_shift aux_shift
= {
346 DCN10_AUX_MASK_SH_LIST(__SHIFT
)
349 static const struct dce110_aux_registers_mask aux_mask
= {
350 DCN10_AUX_MASK_SH_LIST(_MASK
)
353 #define ipp_regs(id)\
355 IPP_REG_LIST_DCN10(id),\
358 static const struct dcn10_ipp_registers ipp_regs
[] = {
365 static const struct dcn10_ipp_shift ipp_shift
= {
366 IPP_MASK_SH_LIST_DCN10(__SHIFT
)
369 static const struct dcn10_ipp_mask ipp_mask
= {
370 IPP_MASK_SH_LIST_DCN10(_MASK
),
373 #define opp_regs(id)\
375 OPP_REG_LIST_DCN10(id),\
378 static const struct dcn10_opp_registers opp_regs
[] = {
385 static const struct dcn10_opp_shift opp_shift
= {
386 OPP_MASK_SH_LIST_DCN10(__SHIFT
)
389 static const struct dcn10_opp_mask opp_mask
= {
390 OPP_MASK_SH_LIST_DCN10(_MASK
),
393 #define aux_engine_regs(id)\
395 AUX_COMMON_REG_LIST(id), \
396 .AUX_RESET_MASK = 0 \
399 static const struct dce110_aux_registers aux_engine_regs
[] = {
410 TF_REG_LIST_DCN10(id),\
413 static const struct dcn_dpp_registers tf_regs
[] = {
420 static const struct dcn_dpp_shift tf_shift
= {
421 TF_REG_LIST_SH_MASK_DCN10(__SHIFT
),
422 TF_DEBUG_REG_LIST_SH_DCN10
426 static const struct dcn_dpp_mask tf_mask
= {
427 TF_REG_LIST_SH_MASK_DCN10(_MASK
),
428 TF_DEBUG_REG_LIST_MASK_DCN10
431 static const struct dcn_mpc_registers mpc_regs
= {
432 MPC_COMMON_REG_LIST_DCN1_0(0),
433 MPC_COMMON_REG_LIST_DCN1_0(1),
434 MPC_COMMON_REG_LIST_DCN1_0(2),
435 MPC_COMMON_REG_LIST_DCN1_0(3),
436 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(0),
437 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(1),
438 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(2),
439 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(3)
442 static const struct dcn_mpc_shift mpc_shift
= {
443 MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
),\
444 SFRB(CUR_VUPDATE_LOCK_SET
, CUR0_VUPDATE_LOCK_SET0
, CUR0_VUPDATE_LOCK_SET
, __SHIFT
)
447 static const struct dcn_mpc_mask mpc_mask
= {
448 MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK
),\
449 SFRB(CUR_VUPDATE_LOCK_SET
, CUR0_VUPDATE_LOCK_SET0
, CUR0_VUPDATE_LOCK_SET
, _MASK
)
453 [id] = {TG_COMMON_REG_LIST_DCN1_0(id)}
455 static const struct dcn_optc_registers tg_regs
[] = {
462 static const struct dcn_optc_shift tg_shift
= {
463 TG_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
)
466 static const struct dcn_optc_mask tg_mask
= {
467 TG_COMMON_MASK_SH_LIST_DCN1_0(_MASK
)
470 static const struct bios_registers bios_regs
= {
471 NBIO_SR(BIOS_SCRATCH_3
),
472 NBIO_SR(BIOS_SCRATCH_6
)
475 #define hubp_regs(id)\
477 HUBP_REG_LIST_DCN10(id)\
480 static const struct dcn_mi_registers hubp_regs
[] = {
487 static const struct dcn_mi_shift hubp_shift
= {
488 HUBP_MASK_SH_LIST_DCN10(__SHIFT
)
491 static const struct dcn_mi_mask hubp_mask
= {
492 HUBP_MASK_SH_LIST_DCN10(_MASK
)
495 static const struct dcn_hubbub_registers hubbub_reg
= {
496 HUBBUB_REG_LIST_DCN10(0)
499 static const struct dcn_hubbub_shift hubbub_shift
= {
500 HUBBUB_MASK_SH_LIST_DCN10(__SHIFT
)
503 static const struct dcn_hubbub_mask hubbub_mask
= {
504 HUBBUB_MASK_SH_LIST_DCN10(_MASK
)
507 static int map_transmitter_id_to_phy_instance(
508 enum transmitter transmitter
)
510 switch (transmitter
) {
511 case TRANSMITTER_UNIPHY_A
:
514 case TRANSMITTER_UNIPHY_B
:
517 case TRANSMITTER_UNIPHY_C
:
520 case TRANSMITTER_UNIPHY_D
:
529 #define clk_src_regs(index, pllid)\
531 CS_COMMON_REG_LIST_DCN1_0(index, pllid),\
534 static const struct dce110_clk_src_regs clk_src_regs
[] = {
541 static const struct dce110_clk_src_shift cs_shift
= {
542 CS_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
)
545 static const struct dce110_clk_src_mask cs_mask
= {
546 CS_COMMON_MASK_SH_LIST_DCN1_0(_MASK
)
549 static const struct resource_caps res_cap
= {
550 .num_timing_generator
= 4,
552 .num_video_plane
= 4,
554 .num_stream_encoder
= 4,
559 static const struct resource_caps rv2_res_cap
= {
560 .num_timing_generator
= 3,
562 .num_video_plane
= 3,
564 .num_stream_encoder
= 3,
569 static const struct dc_plane_cap plane_cap
= {
570 .type
= DC_PLANE_TYPE_DCN_UNIVERSAL
,
571 .blends_with_above
= true,
572 .blends_with_below
= true,
573 .per_pixel_alpha
= true,
575 .pixel_format_support
= {
582 .max_upscale_factor
= {
588 .max_downscale_factor
= {
595 static const struct dc_debug_options debug_defaults_drv
= {
596 .sanity_checks
= true,
597 .disable_dmcu
= false,
598 .force_abm_enable
= false,
599 .timing_trace
= false,
602 /* raven smu dones't allow 0 disp clk,
603 * smu min disp clk limit is 50Mhz
604 * keep min disp clk 100Mhz avoid smu hang
606 .min_disp_clk_khz
= 100000,
608 .disable_pplib_clock_request
= false,
609 .disable_pplib_wm_range
= false,
610 .pplib_wm_report_mode
= WM_REPORT_DEFAULT
,
611 .pipe_split_policy
= MPC_SPLIT_DYNAMIC
,
612 .force_single_disp_pipe_split
= true,
613 .disable_dcc
= DCC_ENABLE
,
614 .voltage_align_fclk
= true,
615 .disable_stereo_support
= true,
617 .performance_trace
= false,
618 .az_endpoint_mute_only
= true,
619 .recovery_enabled
= false, /*enable this by default after testing.*/
620 .max_downscale_src_width
= 3840,
621 .underflow_assert_delay_us
= 0xFFFFFFFF,
624 static const struct dc_debug_options debug_defaults_diags
= {
625 .disable_dmcu
= false,
626 .force_abm_enable
= false,
627 .timing_trace
= true,
629 .disable_stutter
= true,
630 .disable_pplib_clock_request
= true,
631 .disable_pplib_wm_range
= true,
632 .underflow_assert_delay_us
= 0xFFFFFFFF,
635 static void dcn10_dpp_destroy(struct dpp
**dpp
)
637 kfree(TO_DCN10_DPP(*dpp
));
641 static struct dpp
*dcn10_dpp_create(
642 struct dc_context
*ctx
,
645 struct dcn10_dpp
*dpp
=
646 kzalloc(sizeof(struct dcn10_dpp
), GFP_KERNEL
);
651 dpp1_construct(dpp
, ctx
, inst
,
652 &tf_regs
[inst
], &tf_shift
, &tf_mask
);
656 static struct input_pixel_processor
*dcn10_ipp_create(
657 struct dc_context
*ctx
, uint32_t inst
)
659 struct dcn10_ipp
*ipp
=
660 kzalloc(sizeof(struct dcn10_ipp
), GFP_KERNEL
);
667 dcn10_ipp_construct(ipp
, ctx
, inst
,
668 &ipp_regs
[inst
], &ipp_shift
, &ipp_mask
);
673 static struct output_pixel_processor
*dcn10_opp_create(
674 struct dc_context
*ctx
, uint32_t inst
)
676 struct dcn10_opp
*opp
=
677 kzalloc(sizeof(struct dcn10_opp
), GFP_KERNEL
);
684 dcn10_opp_construct(opp
, ctx
, inst
,
685 &opp_regs
[inst
], &opp_shift
, &opp_mask
);
689 struct dce_aux
*dcn10_aux_engine_create(
690 struct dc_context
*ctx
,
693 struct aux_engine_dce110
*aux_engine
=
694 kzalloc(sizeof(struct aux_engine_dce110
), GFP_KERNEL
);
699 dce110_aux_engine_construct(aux_engine
, ctx
, inst
,
700 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER
* AUX_TIMEOUT_PERIOD
,
701 &aux_engine_regs
[inst
],
704 ctx
->dc
->caps
.extended_aux_timeout_support
);
706 return &aux_engine
->base
;
708 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
710 static const struct dce_i2c_registers i2c_hw_regs
[] = {
719 static const struct dce_i2c_shift i2c_shifts
= {
720 I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT
)
723 static const struct dce_i2c_mask i2c_masks
= {
724 I2C_COMMON_MASK_SH_LIST_DCE110(_MASK
)
727 struct dce_i2c_hw
*dcn10_i2c_hw_create(
728 struct dc_context
*ctx
,
731 struct dce_i2c_hw
*dce_i2c_hw
=
732 kzalloc(sizeof(struct dce_i2c_hw
), GFP_KERNEL
);
737 dcn1_i2c_hw_construct(dce_i2c_hw
, ctx
, inst
,
738 &i2c_hw_regs
[inst
], &i2c_shifts
, &i2c_masks
);
742 static struct mpc
*dcn10_mpc_create(struct dc_context
*ctx
)
744 struct dcn10_mpc
*mpc10
= kzalloc(sizeof(struct dcn10_mpc
),
750 dcn10_mpc_construct(mpc10
, ctx
,
759 static struct hubbub
*dcn10_hubbub_create(struct dc_context
*ctx
)
761 struct dcn10_hubbub
*dcn10_hubbub
= kzalloc(sizeof(struct dcn10_hubbub
),
767 hubbub1_construct(&dcn10_hubbub
->base
, ctx
,
772 return &dcn10_hubbub
->base
;
775 static struct timing_generator
*dcn10_timing_generator_create(
776 struct dc_context
*ctx
,
780 kzalloc(sizeof(struct optc
), GFP_KERNEL
);
785 tgn10
->base
.inst
= instance
;
786 tgn10
->base
.ctx
= ctx
;
788 tgn10
->tg_regs
= &tg_regs
[instance
];
789 tgn10
->tg_shift
= &tg_shift
;
790 tgn10
->tg_mask
= &tg_mask
;
792 dcn10_timing_generator_init(tgn10
);
797 static const struct encoder_feature_support link_enc_feature
= {
798 .max_hdmi_deep_color
= COLOR_DEPTH_121212
,
799 .max_hdmi_pixel_clock
= 600000,
800 .hdmi_ycbcr420_supported
= true,
801 .dp_ycbcr420_supported
= true,
802 .flags
.bits
.IS_HBR2_CAPABLE
= true,
803 .flags
.bits
.IS_HBR3_CAPABLE
= true,
804 .flags
.bits
.IS_TPS3_CAPABLE
= true,
805 .flags
.bits
.IS_TPS4_CAPABLE
= true
808 struct link_encoder
*dcn10_link_encoder_create(
809 const struct encoder_init_data
*enc_init_data
)
811 struct dcn10_link_encoder
*enc10
=
812 kzalloc(sizeof(struct dcn10_link_encoder
), GFP_KERNEL
);
819 map_transmitter_id_to_phy_instance(enc_init_data
->transmitter
);
821 dcn10_link_encoder_construct(enc10
,
824 &link_enc_regs
[link_regs_id
],
825 &link_enc_aux_regs
[enc_init_data
->channel
- 1],
826 &link_enc_hpd_regs
[enc_init_data
->hpd_source
],
833 static struct panel_cntl
*dcn10_panel_cntl_create(const struct panel_cntl_init_data
*init_data
)
835 struct dce_panel_cntl
*panel_cntl
=
836 kzalloc(sizeof(struct dce_panel_cntl
), GFP_KERNEL
);
841 dce_panel_cntl_construct(panel_cntl
,
843 &panel_cntl_regs
[init_data
->inst
],
847 return &panel_cntl
->base
;
850 struct clock_source
*dcn10_clock_source_create(
851 struct dc_context
*ctx
,
852 struct dc_bios
*bios
,
853 enum clock_source_id id
,
854 const struct dce110_clk_src_regs
*regs
,
857 struct dce110_clk_src
*clk_src
=
858 kzalloc(sizeof(struct dce110_clk_src
), GFP_KERNEL
);
863 if (dce112_clk_src_construct(clk_src
, ctx
, bios
, id
,
864 regs
, &cs_shift
, &cs_mask
)) {
865 clk_src
->base
.dp_clk_src
= dp_clk_src
;
866 return &clk_src
->base
;
874 static void read_dce_straps(
875 struct dc_context
*ctx
,
876 struct resource_straps
*straps
)
878 generic_reg_get(ctx
, mmDC_PINSTRAPS
+ BASE(mmDC_PINSTRAPS_BASE_IDX
),
879 FN(DC_PINSTRAPS
, DC_PINSTRAPS_AUDIO
), &straps
->dc_pinstraps_audio
);
882 static struct audio
*create_audio(
883 struct dc_context
*ctx
, unsigned int inst
)
885 return dce_audio_create(ctx
, inst
,
886 &audio_regs
[inst
], &audio_shift
, &audio_mask
);
889 static struct stream_encoder
*dcn10_stream_encoder_create(
890 enum engine_id eng_id
,
891 struct dc_context
*ctx
)
893 struct dcn10_stream_encoder
*enc1
=
894 kzalloc(sizeof(struct dcn10_stream_encoder
), GFP_KERNEL
);
899 dcn10_stream_encoder_construct(enc1
, ctx
, ctx
->dc_bios
, eng_id
,
900 &stream_enc_regs
[eng_id
],
901 &se_shift
, &se_mask
);
905 static const struct dce_hwseq_registers hwseq_reg
= {
906 HWSEQ_DCN1_REG_LIST()
909 static const struct dce_hwseq_shift hwseq_shift
= {
910 HWSEQ_DCN1_MASK_SH_LIST(__SHIFT
)
913 static const struct dce_hwseq_mask hwseq_mask
= {
914 HWSEQ_DCN1_MASK_SH_LIST(_MASK
)
917 static struct dce_hwseq
*dcn10_hwseq_create(
918 struct dc_context
*ctx
)
920 struct dce_hwseq
*hws
= kzalloc(sizeof(struct dce_hwseq
), GFP_KERNEL
);
924 hws
->regs
= &hwseq_reg
;
925 hws
->shifts
= &hwseq_shift
;
926 hws
->masks
= &hwseq_mask
;
927 hws
->wa
.DEGVIDCN10_253
= true;
928 hws
->wa
.false_optc_underflow
= true;
929 hws
->wa
.DEGVIDCN10_254
= true;
934 static const struct resource_create_funcs res_create_funcs
= {
935 .read_dce_straps
= read_dce_straps
,
936 .create_audio
= create_audio
,
937 .create_stream_encoder
= dcn10_stream_encoder_create
,
938 .create_hwseq
= dcn10_hwseq_create
,
941 static const struct resource_create_funcs res_create_maximus_funcs
= {
942 .read_dce_straps
= NULL
,
943 .create_audio
= NULL
,
944 .create_stream_encoder
= NULL
,
945 .create_hwseq
= dcn10_hwseq_create
,
948 void dcn10_clock_source_destroy(struct clock_source
**clk_src
)
950 kfree(TO_DCE110_CLK_SRC(*clk_src
));
954 static struct pp_smu_funcs
*dcn10_pp_smu_create(struct dc_context
*ctx
)
956 struct pp_smu_funcs
*pp_smu
= kzalloc(sizeof(*pp_smu
), GFP_KERNEL
);
961 dm_pp_get_funcs(ctx
, pp_smu
);
965 static void dcn10_resource_destruct(struct dcn10_resource_pool
*pool
)
969 for (i
= 0; i
< pool
->base
.stream_enc_count
; i
++) {
970 if (pool
->base
.stream_enc
[i
] != NULL
) {
971 kfree(DCN10STRENC_FROM_STRENC(pool
->base
.stream_enc
[i
]));
972 pool
->base
.stream_enc
[i
] = NULL
;
976 if (pool
->base
.mpc
!= NULL
) {
977 kfree(TO_DCN10_MPC(pool
->base
.mpc
));
978 pool
->base
.mpc
= NULL
;
981 if (pool
->base
.hubbub
!= NULL
) {
982 kfree(pool
->base
.hubbub
);
983 pool
->base
.hubbub
= NULL
;
986 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
987 if (pool
->base
.opps
[i
] != NULL
)
988 pool
->base
.opps
[i
]->funcs
->opp_destroy(&pool
->base
.opps
[i
]);
990 if (pool
->base
.dpps
[i
] != NULL
)
991 dcn10_dpp_destroy(&pool
->base
.dpps
[i
]);
993 if (pool
->base
.ipps
[i
] != NULL
)
994 pool
->base
.ipps
[i
]->funcs
->ipp_destroy(&pool
->base
.ipps
[i
]);
996 if (pool
->base
.hubps
[i
] != NULL
) {
997 kfree(TO_DCN10_HUBP(pool
->base
.hubps
[i
]));
998 pool
->base
.hubps
[i
] = NULL
;
1001 if (pool
->base
.irqs
!= NULL
) {
1002 dal_irq_service_destroy(&pool
->base
.irqs
);
1005 if (pool
->base
.timing_generators
[i
] != NULL
) {
1006 kfree(DCN10TG_FROM_TG(pool
->base
.timing_generators
[i
]));
1007 pool
->base
.timing_generators
[i
] = NULL
;
1011 for (i
= 0; i
< pool
->base
.res_cap
->num_ddc
; i
++) {
1012 if (pool
->base
.engines
[i
] != NULL
)
1013 dce110_engine_destroy(&pool
->base
.engines
[i
]);
1014 if (pool
->base
.hw_i2cs
[i
] != NULL
) {
1015 kfree(pool
->base
.hw_i2cs
[i
]);
1016 pool
->base
.hw_i2cs
[i
] = NULL
;
1018 if (pool
->base
.sw_i2cs
[i
] != NULL
) {
1019 kfree(pool
->base
.sw_i2cs
[i
]);
1020 pool
->base
.sw_i2cs
[i
] = NULL
;
1024 for (i
= 0; i
< pool
->base
.audio_count
; i
++) {
1025 if (pool
->base
.audios
[i
])
1026 dce_aud_destroy(&pool
->base
.audios
[i
]);
1029 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
1030 if (pool
->base
.clock_sources
[i
] != NULL
) {
1031 dcn10_clock_source_destroy(&pool
->base
.clock_sources
[i
]);
1032 pool
->base
.clock_sources
[i
] = NULL
;
1036 if (pool
->base
.dp_clock_source
!= NULL
) {
1037 dcn10_clock_source_destroy(&pool
->base
.dp_clock_source
);
1038 pool
->base
.dp_clock_source
= NULL
;
1041 if (pool
->base
.abm
!= NULL
)
1042 dce_abm_destroy(&pool
->base
.abm
);
1044 if (pool
->base
.dmcu
!= NULL
)
1045 dce_dmcu_destroy(&pool
->base
.dmcu
);
1047 kfree(pool
->base
.pp_smu
);
1050 static struct hubp
*dcn10_hubp_create(
1051 struct dc_context
*ctx
,
1054 struct dcn10_hubp
*hubp1
=
1055 kzalloc(sizeof(struct dcn10_hubp
), GFP_KERNEL
);
1060 dcn10_hubp_construct(hubp1
, ctx
, inst
,
1061 &hubp_regs
[inst
], &hubp_shift
, &hubp_mask
);
1062 return &hubp1
->base
;
1065 static void get_pixel_clock_parameters(
1066 const struct pipe_ctx
*pipe_ctx
,
1067 struct pixel_clk_params
*pixel_clk_params
)
1069 const struct dc_stream_state
*stream
= pipe_ctx
->stream
;
1070 pixel_clk_params
->requested_pix_clk_100hz
= stream
->timing
.pix_clk_100hz
;
1071 pixel_clk_params
->encoder_object_id
= stream
->link
->link_enc
->id
;
1072 pixel_clk_params
->signal_type
= pipe_ctx
->stream
->signal
;
1073 pixel_clk_params
->controller_id
= pipe_ctx
->stream_res
.tg
->inst
+ 1;
1074 /* TODO: un-hardcode*/
1075 pixel_clk_params
->requested_sym_clk
= LINK_RATE_LOW
*
1076 LINK_RATE_REF_FREQ_IN_KHZ
;
1077 pixel_clk_params
->flags
.ENABLE_SS
= 0;
1078 pixel_clk_params
->color_depth
=
1079 stream
->timing
.display_color_depth
;
1080 pixel_clk_params
->flags
.DISPLAY_BLANKED
= 1;
1081 pixel_clk_params
->pixel_encoding
= stream
->timing
.pixel_encoding
;
1083 if (stream
->timing
.pixel_encoding
== PIXEL_ENCODING_YCBCR422
)
1084 pixel_clk_params
->color_depth
= COLOR_DEPTH_888
;
1086 if (stream
->timing
.pixel_encoding
== PIXEL_ENCODING_YCBCR420
)
1087 pixel_clk_params
->requested_pix_clk_100hz
/= 2;
1088 if (stream
->timing
.timing_3d_format
== TIMING_3D_FORMAT_HW_FRAME_PACKING
)
1089 pixel_clk_params
->requested_pix_clk_100hz
*= 2;
1093 static void build_clamping_params(struct dc_stream_state
*stream
)
1095 stream
->clamping
.clamping_level
= CLAMPING_FULL_RANGE
;
1096 stream
->clamping
.c_depth
= stream
->timing
.display_color_depth
;
1097 stream
->clamping
.pixel_encoding
= stream
->timing
.pixel_encoding
;
1100 static void build_pipe_hw_param(struct pipe_ctx
*pipe_ctx
)
1103 get_pixel_clock_parameters(pipe_ctx
, &pipe_ctx
->stream_res
.pix_clk_params
);
1105 pipe_ctx
->clock_source
->funcs
->get_pix_clk_dividers(
1106 pipe_ctx
->clock_source
,
1107 &pipe_ctx
->stream_res
.pix_clk_params
,
1108 &pipe_ctx
->pll_settings
);
1110 pipe_ctx
->stream
->clamping
.pixel_encoding
= pipe_ctx
->stream
->timing
.pixel_encoding
;
1112 resource_build_bit_depth_reduction_params(pipe_ctx
->stream
,
1113 &pipe_ctx
->stream
->bit_depth_params
);
1114 build_clamping_params(pipe_ctx
->stream
);
1117 static enum dc_status
build_mapped_resource(
1118 const struct dc
*dc
,
1119 struct dc_state
*context
,
1120 struct dc_stream_state
*stream
)
1122 struct pipe_ctx
*pipe_ctx
= resource_get_head_pipe_for_stream(&context
->res_ctx
, stream
);
1125 return DC_ERROR_UNEXPECTED
;
1127 build_pipe_hw_param(pipe_ctx
);
1131 enum dc_status
dcn10_add_stream_to_ctx(
1133 struct dc_state
*new_ctx
,
1134 struct dc_stream_state
*dc_stream
)
1136 enum dc_status result
= DC_ERROR_UNEXPECTED
;
1138 result
= resource_map_pool_resources(dc
, new_ctx
, dc_stream
);
1140 if (result
== DC_OK
)
1141 result
= resource_map_phy_clock_resources(dc
, new_ctx
, dc_stream
);
1144 if (result
== DC_OK
)
1145 result
= build_mapped_resource(dc
, new_ctx
, dc_stream
);
1150 static struct pipe_ctx
*dcn10_acquire_idle_pipe_for_layer(
1151 struct dc_state
*context
,
1152 const struct resource_pool
*pool
,
1153 struct dc_stream_state
*stream
)
1155 struct resource_context
*res_ctx
= &context
->res_ctx
;
1156 struct pipe_ctx
*head_pipe
= resource_get_head_pipe_for_stream(res_ctx
, stream
);
1157 struct pipe_ctx
*idle_pipe
= find_idle_secondary_pipe(res_ctx
, pool
, head_pipe
);
1167 idle_pipe
->stream
= head_pipe
->stream
;
1168 idle_pipe
->stream_res
.tg
= head_pipe
->stream_res
.tg
;
1169 idle_pipe
->stream_res
.abm
= head_pipe
->stream_res
.abm
;
1170 idle_pipe
->stream_res
.opp
= head_pipe
->stream_res
.opp
;
1172 idle_pipe
->plane_res
.hubp
= pool
->hubps
[idle_pipe
->pipe_idx
];
1173 idle_pipe
->plane_res
.ipp
= pool
->ipps
[idle_pipe
->pipe_idx
];
1174 idle_pipe
->plane_res
.dpp
= pool
->dpps
[idle_pipe
->pipe_idx
];
1175 idle_pipe
->plane_res
.mpcc_inst
= pool
->dpps
[idle_pipe
->pipe_idx
]->inst
;
1180 static bool dcn10_get_dcc_compression_cap(const struct dc
*dc
,
1181 const struct dc_dcc_surface_param
*input
,
1182 struct dc_surface_dcc_cap
*output
)
1184 return dc
->res_pool
->hubbub
->funcs
->get_dcc_compression_cap(
1185 dc
->res_pool
->hubbub
,
1190 static void dcn10_destroy_resource_pool(struct resource_pool
**pool
)
1192 struct dcn10_resource_pool
*dcn10_pool
= TO_DCN10_RES_POOL(*pool
);
1194 dcn10_resource_destruct(dcn10_pool
);
1199 static enum dc_status
dcn10_validate_plane(const struct dc_plane_state
*plane_state
, struct dc_caps
*caps
)
1201 if (plane_state
->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
1202 && caps
->max_video_width
!= 0
1203 && plane_state
->src_rect
.width
> caps
->max_video_width
)
1204 return DC_FAIL_SURFACE_VALIDATE
;
1209 static enum dc_status
dcn10_validate_global(struct dc
*dc
, struct dc_state
*context
)
1212 bool video_down_scaled
= false;
1213 bool video_large
= false;
1214 bool desktop_large
= false;
1215 bool dcc_disabled
= false;
1216 bool mpo_enabled
= false;
1218 for (i
= 0; i
< context
->stream_count
; i
++) {
1219 if (context
->stream_status
[i
].plane_count
== 0)
1222 if (context
->stream_status
[i
].plane_count
> 2)
1223 return DC_FAIL_UNSUPPORTED_1
;
1225 if (context
->stream_status
[i
].plane_count
> 1)
1228 for (j
= 0; j
< context
->stream_status
[i
].plane_count
; j
++) {
1229 struct dc_plane_state
*plane
=
1230 context
->stream_status
[i
].plane_states
[j
];
1233 if (plane
->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
) {
1235 if (plane
->src_rect
.width
> plane
->dst_rect
.width
||
1236 plane
->src_rect
.height
> plane
->dst_rect
.height
)
1237 video_down_scaled
= true;
1239 if (plane
->src_rect
.width
>= 3840)
1243 if (plane
->src_rect
.width
>= 3840)
1244 desktop_large
= true;
1245 if (!plane
->dcc
.enable
)
1246 dcc_disabled
= true;
1251 /* Disable MPO in multi-display configurations. */
1252 if (context
->stream_count
> 1 && mpo_enabled
)
1253 return DC_FAIL_UNSUPPORTED_1
;
1256 * Workaround: On DCN10 there is UMC issue that causes underflow when
1257 * playing 4k video on 4k desktop with video downscaled and single channel
1260 if (video_large
&& desktop_large
&& video_down_scaled
&& dcc_disabled
&&
1261 dc
->dcn_soc
->number_of_channels
== 1)
1262 return DC_FAIL_SURFACE_VALIDATE
;
1267 static enum dc_status
dcn10_patch_unknown_plane_state(struct dc_plane_state
*plane_state
)
1269 enum dc_status result
= DC_OK
;
1271 enum surface_pixel_format surf_pix_format
= plane_state
->format
;
1272 unsigned int bpp
= resource_pixel_format_to_bpp(surf_pix_format
);
1274 enum swizzle_mode_values swizzle
= DC_SW_LINEAR
;
1277 swizzle
= DC_SW_64KB_D
;
1279 swizzle
= DC_SW_64KB_S
;
1281 plane_state
->tiling_info
.gfx9
.swizzle
= swizzle
;
1285 struct stream_encoder
*dcn10_find_first_free_match_stream_enc_for_link(
1286 struct resource_context
*res_ctx
,
1287 const struct resource_pool
*pool
,
1288 struct dc_stream_state
*stream
)
1292 struct dc_link
*link
= stream
->link
;
1294 for (i
= 0; i
< pool
->stream_enc_count
; i
++) {
1295 if (!res_ctx
->is_stream_enc_acquired
[i
] &&
1296 pool
->stream_enc
[i
]) {
1297 /* Store first available for MST second display
1298 * in daisy chain use case
1301 if (pool
->stream_enc
[i
]->id
==
1302 link
->link_enc
->preferred_engine
)
1303 return pool
->stream_enc
[i
];
1308 * For CZ and later, we can allow DIG FE and BE to differ for all display types
1312 return pool
->stream_enc
[j
];
1317 static const struct dc_cap_funcs cap_funcs
= {
1318 .get_dcc_compression_cap
= dcn10_get_dcc_compression_cap
1321 static const struct resource_funcs dcn10_res_pool_funcs
= {
1322 .destroy
= dcn10_destroy_resource_pool
,
1323 .link_enc_create
= dcn10_link_encoder_create
,
1324 .panel_cntl_create
= dcn10_panel_cntl_create
,
1325 .validate_bandwidth
= dcn_validate_bandwidth
,
1326 .acquire_idle_pipe_for_layer
= dcn10_acquire_idle_pipe_for_layer
,
1327 .validate_plane
= dcn10_validate_plane
,
1328 .validate_global
= dcn10_validate_global
,
1329 .add_stream_to_ctx
= dcn10_add_stream_to_ctx
,
1330 .patch_unknown_plane_state
= dcn10_patch_unknown_plane_state
,
1331 .find_first_free_match_stream_enc_for_link
= dcn10_find_first_free_match_stream_enc_for_link
1334 static uint32_t read_pipe_fuses(struct dc_context
*ctx
)
1336 uint32_t value
= dm_read_reg_soc15(ctx
, mmCC_DC_PIPE_DIS
, 0);
1337 /* RV1 support max 4 pipes */
1338 value
= value
& 0xf;
1343 * Some architectures don't support soft-float (e.g. aarch64), on those
1344 * this function has to be called with hardfloat enabled, make sure not
1345 * to inline it so whatever fp stuff is done stays inside
1347 static noinline
void dcn10_resource_construct_fp(
1350 if (dc
->ctx
->dce_version
== DCN_VERSION_1_01
) {
1351 struct dcn_soc_bounding_box
*dcn_soc
= dc
->dcn_soc
;
1352 struct dcn_ip_params
*dcn_ip
= dc
->dcn_ip
;
1353 struct display_mode_lib
*dml
= &dc
->dml
;
1355 dml
->ip
.max_num_dpp
= 3;
1356 /* TODO how to handle 23.84? */
1357 dcn_soc
->dram_clock_change_latency
= 23;
1358 dcn_ip
->max_num_dpp
= 3;
1360 if (ASICREV_IS_RV1_F0(dc
->ctx
->asic_id
.hw_internal_rev
)) {
1361 dc
->dcn_soc
->urgent_latency
= 3;
1362 dc
->debug
.disable_dmcu
= true;
1363 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
= 41.60f
;
1367 dc
->dcn_soc
->number_of_channels
= dc
->ctx
->asic_id
.vram_width
/ ddr4_dram_width
;
1368 ASSERT(dc
->dcn_soc
->number_of_channels
< 3);
1369 if (dc
->dcn_soc
->number_of_channels
== 0)/*old sbios bug*/
1370 dc
->dcn_soc
->number_of_channels
= 2;
1372 if (dc
->dcn_soc
->number_of_channels
== 1) {
1373 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
= 19.2f
;
1374 dc
->dcn_soc
->fabric_and_dram_bandwidth_vnom0p8
= 17.066f
;
1375 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmid0p72
= 14.933f
;
1376 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmin0p65
= 12.8f
;
1377 if (ASICREV_IS_RV1_F0(dc
->ctx
->asic_id
.hw_internal_rev
)) {
1378 dc
->dcn_soc
->fabric_and_dram_bandwidth_vmax0p9
= 20.80f
;
1383 static bool dcn10_resource_construct(
1384 uint8_t num_virtual_links
,
1386 struct dcn10_resource_pool
*pool
)
1390 struct dc_context
*ctx
= dc
->ctx
;
1391 uint32_t pipe_fuses
= read_pipe_fuses(ctx
);
1393 ctx
->dc_bios
->regs
= &bios_regs
;
1395 if (ctx
->dce_version
== DCN_VERSION_1_01
)
1396 pool
->base
.res_cap
= &rv2_res_cap
;
1398 pool
->base
.res_cap
= &res_cap
;
1399 pool
->base
.funcs
= &dcn10_res_pool_funcs
;
1402 * TODO fill in from actual raven resource when we create
1403 * more than virtual encoder
1406 /*************************************************
1407 * Resource + asic cap harcoding *
1408 *************************************************/
1409 pool
->base
.underlay_pipe_index
= NO_UNDERLAY_PIPE
;
1411 /* max pipe num for ASIC before check pipe fuses */
1412 pool
->base
.pipe_count
= pool
->base
.res_cap
->num_timing_generator
;
1414 if (dc
->ctx
->dce_version
== DCN_VERSION_1_01
)
1415 pool
->base
.pipe_count
= 3;
1416 dc
->caps
.max_video_width
= 3840;
1417 dc
->caps
.max_downscale_ratio
= 200;
1418 dc
->caps
.i2c_speed_in_khz
= 100;
1419 dc
->caps
.i2c_speed_in_khz_hdcp
= 100; /*1.4 w/a not applied by default*/
1420 dc
->caps
.max_cursor_size
= 256;
1421 dc
->caps
.min_horizontal_blanking_period
= 80;
1422 dc
->caps
.max_slave_planes
= 1;
1423 dc
->caps
.is_apu
= true;
1424 dc
->caps
.post_blend_color_processing
= false;
1425 dc
->caps
.extended_aux_timeout_support
= false;
1427 /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
1428 dc
->caps
.force_dp_tps4_for_cp2520
= true;
1430 /* Color pipeline capabilities */
1431 dc
->caps
.color
.dpp
.dcn_arch
= 1;
1432 dc
->caps
.color
.dpp
.input_lut_shared
= 1;
1433 dc
->caps
.color
.dpp
.icsc
= 1;
1434 dc
->caps
.color
.dpp
.dgam_ram
= 1;
1435 dc
->caps
.color
.dpp
.dgam_rom_caps
.srgb
= 1;
1436 dc
->caps
.color
.dpp
.dgam_rom_caps
.bt2020
= 1;
1437 dc
->caps
.color
.dpp
.dgam_rom_caps
.gamma2_2
= 0;
1438 dc
->caps
.color
.dpp
.dgam_rom_caps
.pq
= 0;
1439 dc
->caps
.color
.dpp
.dgam_rom_caps
.hlg
= 0;
1440 dc
->caps
.color
.dpp
.post_csc
= 0;
1441 dc
->caps
.color
.dpp
.gamma_corr
= 0;
1442 dc
->caps
.color
.dpp
.dgam_rom_for_yuv
= 1;
1444 dc
->caps
.color
.dpp
.hw_3d_lut
= 0;
1445 dc
->caps
.color
.dpp
.ogam_ram
= 1; // RGAM on DCN1
1446 dc
->caps
.color
.dpp
.ogam_rom_caps
.srgb
= 1;
1447 dc
->caps
.color
.dpp
.ogam_rom_caps
.bt2020
= 1;
1448 dc
->caps
.color
.dpp
.ogam_rom_caps
.gamma2_2
= 0;
1449 dc
->caps
.color
.dpp
.ogam_rom_caps
.pq
= 0;
1450 dc
->caps
.color
.dpp
.ogam_rom_caps
.hlg
= 0;
1451 dc
->caps
.color
.dpp
.ocsc
= 1;
1453 /* no post-blend color operations */
1454 dc
->caps
.color
.mpc
.gamut_remap
= 0;
1455 dc
->caps
.color
.mpc
.num_3dluts
= 0;
1456 dc
->caps
.color
.mpc
.shared_3d_lut
= 0;
1457 dc
->caps
.color
.mpc
.ogam_ram
= 0;
1458 dc
->caps
.color
.mpc
.ogam_rom_caps
.srgb
= 0;
1459 dc
->caps
.color
.mpc
.ogam_rom_caps
.bt2020
= 0;
1460 dc
->caps
.color
.mpc
.ogam_rom_caps
.gamma2_2
= 0;
1461 dc
->caps
.color
.mpc
.ogam_rom_caps
.pq
= 0;
1462 dc
->caps
.color
.mpc
.ogam_rom_caps
.hlg
= 0;
1463 dc
->caps
.color
.mpc
.ocsc
= 0;
1465 if (dc
->ctx
->dce_environment
== DCE_ENV_PRODUCTION_DRV
)
1466 dc
->debug
= debug_defaults_drv
;
1468 dc
->debug
= debug_defaults_diags
;
1470 /*************************************************
1471 * Create resources *
1472 *************************************************/
1474 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL0
] =
1475 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1476 CLOCK_SOURCE_COMBO_PHY_PLL0
,
1477 &clk_src_regs
[0], false);
1478 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL1
] =
1479 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1480 CLOCK_SOURCE_COMBO_PHY_PLL1
,
1481 &clk_src_regs
[1], false);
1482 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL2
] =
1483 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1484 CLOCK_SOURCE_COMBO_PHY_PLL2
,
1485 &clk_src_regs
[2], false);
1487 if (dc
->ctx
->dce_version
== DCN_VERSION_1_0
) {
1488 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL3
] =
1489 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1490 CLOCK_SOURCE_COMBO_PHY_PLL3
,
1491 &clk_src_regs
[3], false);
1494 pool
->base
.clk_src_count
= DCN10_CLK_SRC_TOTAL
;
1496 if (dc
->ctx
->dce_version
== DCN_VERSION_1_01
)
1497 pool
->base
.clk_src_count
= DCN101_CLK_SRC_TOTAL
;
1499 pool
->base
.dp_clock_source
=
1500 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1501 CLOCK_SOURCE_ID_DP_DTO
,
1502 /* todo: not reuse phy_pll registers */
1503 &clk_src_regs
[0], true);
1505 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
1506 if (pool
->base
.clock_sources
[i
] == NULL
) {
1507 dm_error("DC: failed to create clock sources!\n");
1508 BREAK_TO_DEBUGGER();
1513 pool
->base
.dmcu
= dcn10_dmcu_create(ctx
,
1517 if (pool
->base
.dmcu
== NULL
) {
1518 dm_error("DC: failed to create dmcu!\n");
1519 BREAK_TO_DEBUGGER();
1523 pool
->base
.abm
= dce_abm_create(ctx
,
1527 if (pool
->base
.abm
== NULL
) {
1528 dm_error("DC: failed to create abm!\n");
1529 BREAK_TO_DEBUGGER();
1533 dml_init_instance(&dc
->dml
, &dcn1_0_soc
, &dcn1_0_ip
, DML_PROJECT_RAVEN1
);
1534 memcpy(dc
->dcn_ip
, &dcn10_ip_defaults
, sizeof(dcn10_ip_defaults
));
1535 memcpy(dc
->dcn_soc
, &dcn10_soc_defaults
, sizeof(dcn10_soc_defaults
));
1537 /* Other architectures we build for build this with soft-float */
1538 dcn10_resource_construct_fp(dc
);
1540 pool
->base
.pp_smu
= dcn10_pp_smu_create(ctx
);
1543 * Right now SMU/PPLIB and DAL all have the AZ D3 force PME notification *
1544 * implemented. So AZ D3 should work.For issue 197007. *
1546 if (pool
->base
.pp_smu
!= NULL
1547 && pool
->base
.pp_smu
->rv_funcs
.set_pme_wa_enable
!= NULL
)
1548 dc
->debug
.az_endpoint_mute_only
= false;
1550 if (!dc
->debug
.disable_pplib_clock_request
)
1551 dcn_bw_update_from_pplib(dc
);
1552 dcn_bw_sync_calcs_and_dml(dc
);
1553 if (!dc
->debug
.disable_pplib_wm_range
) {
1554 dc
->res_pool
= &pool
->base
;
1555 dcn_bw_notify_pplib_of_wm_ranges(dc
);
1559 struct irq_service_init_data init_data
;
1560 init_data
.ctx
= dc
->ctx
;
1561 pool
->base
.irqs
= dal_irq_service_dcn10_create(&init_data
);
1562 if (!pool
->base
.irqs
)
1566 /* index to valid pipe resource */
1568 /* mem input -> ipp -> dpp -> opp -> TG */
1569 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
1570 /* if pipe is disabled, skip instance of HW pipe,
1571 * i.e, skip ASIC register instance
1573 if ((pipe_fuses
& (1 << i
)) != 0)
1576 pool
->base
.hubps
[j
] = dcn10_hubp_create(ctx
, i
);
1577 if (pool
->base
.hubps
[j
] == NULL
) {
1578 BREAK_TO_DEBUGGER();
1580 "DC: failed to create memory input!\n");
1584 pool
->base
.ipps
[j
] = dcn10_ipp_create(ctx
, i
);
1585 if (pool
->base
.ipps
[j
] == NULL
) {
1586 BREAK_TO_DEBUGGER();
1588 "DC: failed to create input pixel processor!\n");
1592 pool
->base
.dpps
[j
] = dcn10_dpp_create(ctx
, i
);
1593 if (pool
->base
.dpps
[j
] == NULL
) {
1594 BREAK_TO_DEBUGGER();
1596 "DC: failed to create dpp!\n");
1600 pool
->base
.opps
[j
] = dcn10_opp_create(ctx
, i
);
1601 if (pool
->base
.opps
[j
] == NULL
) {
1602 BREAK_TO_DEBUGGER();
1604 "DC: failed to create output pixel processor!\n");
1608 pool
->base
.timing_generators
[j
] = dcn10_timing_generator_create(
1610 if (pool
->base
.timing_generators
[j
] == NULL
) {
1611 BREAK_TO_DEBUGGER();
1612 dm_error("DC: failed to create tg!\n");
1615 /* check next valid pipe */
1619 for (i
= 0; i
< pool
->base
.res_cap
->num_ddc
; i
++) {
1620 pool
->base
.engines
[i
] = dcn10_aux_engine_create(ctx
, i
);
1621 if (pool
->base
.engines
[i
] == NULL
) {
1622 BREAK_TO_DEBUGGER();
1624 "DC:failed to create aux engine!!\n");
1627 pool
->base
.hw_i2cs
[i
] = dcn10_i2c_hw_create(ctx
, i
);
1628 if (pool
->base
.hw_i2cs
[i
] == NULL
) {
1629 BREAK_TO_DEBUGGER();
1631 "DC:failed to create hw i2c!!\n");
1634 pool
->base
.sw_i2cs
[i
] = NULL
;
1637 /* valid pipe num */
1638 pool
->base
.pipe_count
= j
;
1639 pool
->base
.timing_generator_count
= j
;
1641 /* within dml lib, it is hard code to 4. If ASIC pipe is fused,
1642 * the value may be changed
1644 dc
->dml
.ip
.max_num_dpp
= pool
->base
.pipe_count
;
1645 dc
->dcn_ip
->max_num_dpp
= pool
->base
.pipe_count
;
1647 pool
->base
.mpc
= dcn10_mpc_create(ctx
);
1648 if (pool
->base
.mpc
== NULL
) {
1649 BREAK_TO_DEBUGGER();
1650 dm_error("DC: failed to create mpc!\n");
1654 pool
->base
.hubbub
= dcn10_hubbub_create(ctx
);
1655 if (pool
->base
.hubbub
== NULL
) {
1656 BREAK_TO_DEBUGGER();
1657 dm_error("DC: failed to create hubbub!\n");
1661 if (!resource_construct(num_virtual_links
, dc
, &pool
->base
,
1662 (!IS_FPGA_MAXIMUS_DC(dc
->ctx
->dce_environment
) ?
1663 &res_create_funcs
: &res_create_maximus_funcs
)))
1666 dcn10_hw_sequencer_construct(dc
);
1667 dc
->caps
.max_planes
= pool
->base
.pipe_count
;
1669 for (i
= 0; i
< dc
->caps
.max_planes
; ++i
)
1670 dc
->caps
.planes
[i
] = plane_cap
;
1672 dc
->cap_funcs
= cap_funcs
;
1678 dcn10_resource_destruct(pool
);
1683 struct resource_pool
*dcn10_create_resource_pool(
1684 const struct dc_init_data
*init_data
,
1687 struct dcn10_resource_pool
*pool
=
1688 kzalloc(sizeof(struct dcn10_resource_pool
), GFP_KERNEL
);
1693 if (dcn10_resource_construct(init_data
->num_virtual_links
, dc
, pool
))
1697 BREAK_TO_DEBUGGER();