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 "dm_services.h"
30 #include "include/irq_service_interface.h"
31 #include "dcn10/dcn10_resource.h"
33 #include "dcn10/dcn10_ipp.h"
34 #include "dcn10/dcn10_mpc.h"
35 #include "irq/dcn10/irq_service_dcn10.h"
36 #include "dcn10/dcn10_transform.h"
37 #include "dcn10/dcn10_timing_generator.h"
38 #include "dcn10/dcn10_hw_sequencer.h"
39 #include "dce110/dce110_hw_sequencer.h"
40 #include "dcn10/dcn10_opp.h"
41 #include "dce/dce_link_encoder.h"
42 #include "dce/dce_stream_encoder.h"
43 #include "dce/dce_clocks.h"
44 #include "dce/dce_clock_source.h"
45 #include "dcn10/dcn10_mem_input.h"
46 #include "dce/dce_audio.h"
47 #include "dce/dce_hwseq.h"
48 #include "../virtual/virtual_stream_encoder.h"
49 #include "dce110/dce110_resource.h"
51 #include "vega10/soc15ip.h"
53 #include "raven1/DCN/dcn_1_0_offset.h"
54 #include "raven1/DCN/dcn_1_0_sh_mask.h"
56 #include "raven1/NBIO/nbio_7_0_offset.h"
58 #include "raven1/MMHUB/mmhub_9_1_offset.h"
59 #include "raven1/MMHUB/mmhub_9_1_sh_mask.h"
61 #include "reg_helper.h"
62 #include "dce/dce_abm.h"
63 #include "dce/dce_dmcu.h"
65 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
66 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
67 #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
68 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
69 #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
70 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
71 #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
72 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
73 #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
74 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
75 #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
76 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f
77 #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
78 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f
79 #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
83 enum dcn10_clk_src_array_id
{
91 /* begin *********************
92 * macros to expend register list macro defined in HW object header file */
95 #define BASE_INNER(seg) \
96 DCE_BASE__INST0_SEG ## seg
101 #define SR(reg_name)\
102 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
105 #define SRI(reg_name, block, id)\
106 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
107 mm ## block ## id ## _ ## reg_name
110 #define SRII(reg_name, block, id)\
111 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
112 mm ## block ## id ## _ ## reg_name
115 #define NBIO_BASE_INNER(seg) \
116 NBIF_BASE__INST0_SEG ## seg
118 #define NBIO_BASE(seg) \
121 #define NBIO_SR(reg_name)\
122 .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
126 #define GC_BASE_INNER(seg) \
127 GC_BASE__INST0_SEG ## seg
129 #define GC_BASE(seg) \
132 #define GC_SR(reg_name)\
133 .reg_name = GC_BASE(mm ## reg_name ## _BASE_IDX) + \
136 /* macros to expend register list macro defined in HW object header file
137 * end *********************/
139 static const struct dce_disp_clk_registers disp_clk_regs
= {
143 static const struct dce_disp_clk_shift disp_clk_shift
= {
144 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT
)
147 static const struct dce_disp_clk_mask disp_clk_mask
= {
148 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK
)
151 static const struct dce_dmcu_registers dmcu_regs
= {
152 DMCU_DCN10_REG_LIST()
155 static const struct dce_dmcu_shift dmcu_shift
= {
156 DMCU_MASK_SH_LIST_DCN10(__SHIFT
)
159 static const struct dce_dmcu_mask dmcu_mask
= {
160 DMCU_MASK_SH_LIST_DCN10(_MASK
)
163 static const struct dce_abm_registers abm_regs
= {
164 ABM_DCN10_REG_LIST(0)
167 static const struct dce_abm_shift abm_shift
= {
168 ABM_MASK_SH_LIST_DCN10(__SHIFT
)
171 static const struct dce_abm_mask abm_mask
= {
172 ABM_MASK_SH_LIST_DCN10(_MASK
)
175 #define stream_enc_regs(id)\
177 SE_DCN_REG_LIST(id),\
179 .AFMT_AVI_INFO0 = 0,\
180 .AFMT_AVI_INFO1 = 0,\
181 .AFMT_AVI_INFO2 = 0,\
182 .AFMT_AVI_INFO3 = 0,\
185 static const struct dce110_stream_enc_registers stream_enc_regs
[] = {
192 static const struct dce_stream_encoder_shift se_shift
= {
193 SE_COMMON_MASK_SH_LIST_DCN10(__SHIFT
)
196 static const struct dce_stream_encoder_mask se_mask
= {
197 SE_COMMON_MASK_SH_LIST_DCN10(_MASK
),
198 .AFMT_GENERIC0_UPDATE
= 0,
199 .AFMT_GENERIC2_UPDATE
= 0,
202 .HDMI_AVI_INFO_SEND
= 0,
203 .HDMI_AVI_INFO_CONT
= 0,
204 .HDMI_AVI_INFO_LINE
= 0,
205 .DP_SEC_AVI_ENABLE
= 0,
206 .AFMT_AVI_INFO_VERSION
= 0
209 #define audio_regs(id)\
211 AUD_COMMON_REG_LIST(id)\
214 static const struct dce_audio_registers audio_regs
[] = {
221 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
222 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
223 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
224 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
226 static const struct dce_audio_shift audio_shift
= {
227 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT
)
230 static const struct dce_aduio_mask audio_mask
= {
231 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK
)
234 #define aux_regs(id)\
239 static const struct dce110_link_enc_aux_registers link_enc_aux_regs
[] = {
248 #define hpd_regs(id)\
253 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs
[] = {
262 #define link_regs(id)\
264 LE_DCN10_REG_LIST(id), \
265 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
268 static const struct dce110_link_enc_registers link_enc_regs
[] = {
278 #define ipp_regs(id)\
280 IPP_DCN10_REG_LIST(id),\
283 static const struct dcn10_ipp_registers ipp_regs
[] = {
290 static const struct dcn10_ipp_shift ipp_shift
= {
291 IPP_DCN10_MASK_SH_LIST(__SHIFT
)
294 static const struct dcn10_ipp_mask ipp_mask
= {
295 IPP_DCN10_MASK_SH_LIST(_MASK
),
298 #define opp_regs(id)\
300 OPP_DCN10_REG_LIST(id),\
303 static const struct dcn10_opp_registers opp_regs
[] = {
310 static const struct dcn10_opp_shift opp_shift
= {
311 OPP_DCN10_MASK_SH_LIST(__SHIFT
)
314 static const struct dcn10_opp_mask opp_mask
= {
315 OPP_DCN10_MASK_SH_LIST(_MASK
),
320 TF_REG_LIST_DCN(id),\
323 static const struct dcn_transform_registers tf_regs
[] = {
330 static const struct dcn_transform_shift tf_shift
= {
331 TF_REG_LIST_SH_MASK_DCN(__SHIFT
)
334 static const struct dcn_transform_mask tf_mask
= {
335 TF_REG_LIST_SH_MASK_DCN(_MASK
),
339 static const struct dcn_mpc_registers mpc_regs
= {
340 MPC_COMMON_REG_LIST_DCN1_0(0),
341 MPC_COMMON_REG_LIST_DCN1_0(1),
342 MPC_COMMON_REG_LIST_DCN1_0(2),
343 MPC_COMMON_REG_LIST_DCN1_0(3),
346 static const struct dcn_mpc_shift mpc_shift
= {
347 MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
)
350 static const struct dcn_mpc_mask mpc_mask
= {
351 MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK
),
355 [id] = {TG_COMMON_REG_LIST_DCN1_0(id)}
357 static const struct dcn_tg_registers tg_regs
[] = {
364 static const struct dcn_tg_shift tg_shift
= {
365 TG_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
)
368 static const struct dcn_tg_mask tg_mask
= {
369 TG_COMMON_MASK_SH_LIST_DCN1_0(_MASK
)
373 static const struct bios_registers bios_regs
= {
374 NBIO_SR(BIOS_SCRATCH_6
)
379 MI_DCN10_REG_LIST(id)\
383 static const struct dcn_mi_registers mi_regs
[] = {
390 static const struct dcn_mi_shift mi_shift
= {
391 MI_DCN10_MASK_SH_LIST(__SHIFT
)
394 static const struct dcn_mi_mask mi_mask
= {
395 MI_DCN10_MASK_SH_LIST(_MASK
)
398 #define clk_src_regs(index, pllid)\
400 CS_COMMON_REG_LIST_DCN1_0(index, pllid),\
403 static const struct dce110_clk_src_regs clk_src_regs
[] = {
410 static const struct dce110_clk_src_shift cs_shift
= {
411 CS_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT
)
414 static const struct dce110_clk_src_mask cs_mask
= {
415 CS_COMMON_MASK_SH_LIST_DCN1_0(_MASK
)
419 static const struct resource_caps res_cap
= {
420 .num_timing_generator
= 4,
421 .num_video_plane
= 4,
423 .num_stream_encoder
= 4,
427 static const struct dc_debug debug_defaults_drv
= {
428 .disable_dcc
= false,
429 .disable_dpp_power_gate
= false,
430 .disable_hubp_power_gate
= false,
431 .disable_dmcu
= true,
432 .force_abm_enable
= false,
433 .timing_trace
= false,
434 .disable_pplib_clock_request
= true,
435 .disable_pplib_wm_range
= true,
436 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
438 .use_max_voltage
= true
442 static const struct dc_debug debug_defaults_diags
= {
443 .disable_dpp_power_gate
= false,
444 .disable_hubp_power_gate
= false,
445 .disable_clock_gate
= true,
446 .disable_dmcu
= true,
447 .force_abm_enable
= false,
448 .timing_trace
= true,
449 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
450 .disable_pplib_clock_request
= true,
451 .disable_pplib_wm_range
= true,
453 .use_max_voltage
= false
457 static void dcn10_transform_destroy(struct transform
**xfm
)
459 dm_free(TO_DCN10_TRANSFORM(*xfm
));
463 static struct transform
*dcn10_transform_create(
464 struct dc_context
*ctx
,
467 struct dcn10_transform
*transform
=
468 dm_alloc(sizeof(struct dcn10_transform
));
473 if (dcn10_transform_construct(transform
, ctx
,
474 &tf_regs
[inst
], &tf_shift
, &tf_mask
))
475 return &transform
->base
;
482 static struct input_pixel_processor
*dcn10_ipp_create(
483 struct dc_context
*ctx
, uint32_t inst
)
485 struct dcn10_ipp
*ipp
=
486 dm_alloc(sizeof(struct dcn10_ipp
));
493 dcn10_ipp_construct(ipp
, ctx
, inst
,
494 &ipp_regs
[inst
], &ipp_shift
, &ipp_mask
);
499 static struct output_pixel_processor
*dcn10_opp_create(
500 struct dc_context
*ctx
, uint32_t inst
)
502 struct dcn10_opp
*opp
=
503 dm_alloc(sizeof(struct dcn10_opp
));
510 dcn10_opp_construct(opp
, ctx
, inst
,
511 &opp_regs
[inst
], &opp_shift
, &opp_mask
);
515 static struct mpc
*dcn10_mpc_create(
516 struct dc_context
*ctx
)
518 struct dcn10_mpc
*mpc
= dm_alloc(sizeof(struct dcn10_mpc
));
524 mpc
->mpc_regs
= &mpc_regs
;
525 mpc
->mpc_shift
= &mpc_shift
;
526 mpc
->mpc_mask
= &mpc_mask
;
531 static void dcn10_mpc_destroy(struct mpc
**mpc_base
)
534 dm_free(TO_DCN10_MPC(*mpc_base
));
539 static struct timing_generator
*dcn10_timing_generator_create(
540 struct dc_context
*ctx
,
543 struct dcn10_timing_generator
*tgn10
=
544 dm_alloc(sizeof(struct dcn10_timing_generator
));
549 tgn10
->base
.inst
= instance
;
550 tgn10
->base
.ctx
= ctx
;
552 tgn10
->tg_regs
= &tg_regs
[instance
];
553 tgn10
->tg_shift
= &tg_shift
;
554 tgn10
->tg_mask
= &tg_mask
;
556 dcn10_timing_generator_init(tgn10
);
561 static const struct encoder_feature_support link_enc_feature
= {
562 .max_hdmi_deep_color
= COLOR_DEPTH_121212
,
563 .max_hdmi_pixel_clock
= 600000,
564 .ycbcr420_supported
= true,
565 .flags
.bits
.IS_HBR2_CAPABLE
= true,
566 .flags
.bits
.IS_HBR3_CAPABLE
= true,
567 .flags
.bits
.IS_TPS3_CAPABLE
= true,
568 .flags
.bits
.IS_TPS4_CAPABLE
= true,
569 .flags
.bits
.IS_YCBCR_CAPABLE
= true
572 struct link_encoder
*dcn10_link_encoder_create(
573 const struct encoder_init_data
*enc_init_data
)
575 struct dce110_link_encoder
*enc110
=
576 dm_alloc(sizeof(struct dce110_link_encoder
));
581 if (dce110_link_encoder_construct(
585 &link_enc_regs
[enc_init_data
->transmitter
],
586 &link_enc_aux_regs
[enc_init_data
->channel
- 1],
587 &link_enc_hpd_regs
[enc_init_data
->hpd_source
])) {
589 return &enc110
->base
;
597 struct clock_source
*dcn10_clock_source_create(
598 struct dc_context
*ctx
,
599 struct dc_bios
*bios
,
600 enum clock_source_id id
,
601 const struct dce110_clk_src_regs
*regs
,
604 struct dce110_clk_src
*clk_src
=
605 dm_alloc(sizeof(struct dce110_clk_src
));
610 if (dce110_clk_src_construct(clk_src
, ctx
, bios
, id
,
611 regs
, &cs_shift
, &cs_mask
)) {
612 clk_src
->base
.dp_clk_src
= dp_clk_src
;
613 return &clk_src
->base
;
620 static void read_dce_straps(
621 struct dc_context
*ctx
,
622 struct resource_straps
*straps
)
624 /* TODO: Registers are missing */
625 /*REG_GET_2(CC_DC_HDMI_STRAPS,
626 HDMI_DISABLE, &straps->hdmi_disable,
627 AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
629 REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);*/
632 static struct audio
*create_audio(
633 struct dc_context
*ctx
, unsigned int inst
)
635 return dce_audio_create(ctx
, inst
,
636 &audio_regs
[inst
], &audio_shift
, &audio_mask
);
639 static struct stream_encoder
*dcn10_stream_encoder_create(
640 enum engine_id eng_id
,
641 struct dc_context
*ctx
)
643 struct dce110_stream_encoder
*enc110
=
644 dm_alloc(sizeof(struct dce110_stream_encoder
));
649 if (dce110_stream_encoder_construct(
650 enc110
, ctx
, ctx
->dc_bios
, eng_id
,
651 &stream_enc_regs
[eng_id
], &se_shift
, &se_mask
))
652 return &enc110
->base
;
659 static const struct dce_hwseq_registers hwseq_reg
= {
660 HWSEQ_DCN1_REG_LIST()
663 static const struct dce_hwseq_shift hwseq_shift
= {
664 HWSEQ_DCN1_MASK_SH_LIST(__SHIFT
)
667 static const struct dce_hwseq_mask hwseq_mask
= {
668 HWSEQ_DCN1_MASK_SH_LIST(_MASK
)
671 static struct dce_hwseq
*dcn10_hwseq_create(
672 struct dc_context
*ctx
)
674 struct dce_hwseq
*hws
= dm_alloc(sizeof(struct dce_hwseq
));
678 hws
->regs
= &hwseq_reg
;
679 hws
->shifts
= &hwseq_shift
;
680 hws
->masks
= &hwseq_mask
;
685 static const struct resource_create_funcs res_create_funcs
= {
686 .read_dce_straps
= read_dce_straps
,
687 .create_audio
= create_audio
,
688 .create_stream_encoder
= dcn10_stream_encoder_create
,
689 .create_hwseq
= dcn10_hwseq_create
,
692 static const struct resource_create_funcs res_create_maximus_funcs
= {
693 .read_dce_straps
= NULL
,
694 .create_audio
= NULL
,
695 .create_stream_encoder
= NULL
,
696 .create_hwseq
= dcn10_hwseq_create
,
699 void dcn10_clock_source_destroy(struct clock_source
**clk_src
)
701 dm_free(TO_DCE110_CLK_SRC(*clk_src
));
705 static void destruct(struct dcn10_resource_pool
*pool
)
709 for (i
= 0; i
< pool
->base
.stream_enc_count
; i
++) {
710 if (pool
->base
.stream_enc
[i
] != NULL
) {
711 /* TODO: free dcn version of stream encoder once implemented
712 * rather than using virtual stream encoder
714 dm_free(pool
->base
.stream_enc
[i
]);
715 pool
->base
.stream_enc
[i
] = NULL
;
719 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
720 if (pool
->base
.opps
[i
] != NULL
)
721 pool
->base
.opps
[i
]->funcs
->opp_destroy(&pool
->base
.opps
[i
]);
723 if (pool
->base
.transforms
[i
] != NULL
)
724 dcn10_transform_destroy(&pool
->base
.transforms
[i
]);
726 if (pool
->base
.ipps
[i
] != NULL
)
727 pool
->base
.ipps
[i
]->funcs
->ipp_destroy(&pool
->base
.ipps
[i
]);
729 if (pool
->base
.mis
[i
] != NULL
) {
730 dm_free(TO_DCN10_MEM_INPUT(pool
->base
.mis
[i
]));
731 pool
->base
.mis
[i
] = NULL
;
734 if (pool
->base
.irqs
!= NULL
) {
735 dal_irq_service_destroy(&pool
->base
.irqs
);
738 if (pool
->base
.timing_generators
[i
] != NULL
) {
739 dm_free(DCN10TG_FROM_TG(pool
->base
.timing_generators
[i
]));
740 pool
->base
.timing_generators
[i
] = NULL
;
744 for (i
= 0; i
< pool
->base
.stream_enc_count
; i
++) {
745 if (pool
->base
.stream_enc
[i
] != NULL
)
746 dm_free(DCE110STRENC_FROM_STRENC(pool
->base
.stream_enc
[i
]));
749 for (i
= 0; i
< pool
->base
.audio_count
; i
++) {
750 if (pool
->base
.audios
[i
])
751 dce_aud_destroy(&pool
->base
.audios
[i
]);
754 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
755 if (pool
->base
.clock_sources
[i
] != NULL
) {
756 dcn10_clock_source_destroy(&pool
->base
.clock_sources
[i
]);
757 pool
->base
.clock_sources
[i
] = NULL
;
761 if (pool
->base
.dp_clock_source
!= NULL
) {
762 dcn10_clock_source_destroy(&pool
->base
.dp_clock_source
);
763 pool
->base
.dp_clock_source
= NULL
;
766 if (pool
->base
.mpc
!= NULL
)
767 dcn10_mpc_destroy(&pool
->base
.mpc
);
769 if (pool
->base
.abm
!= NULL
)
770 dce_abm_destroy(&pool
->base
.abm
);
772 if (pool
->base
.dmcu
!= NULL
)
773 dce_dmcu_destroy(&pool
->base
.dmcu
);
775 if (pool
->base
.display_clock
!= NULL
)
776 dce_disp_clk_destroy(&pool
->base
.display_clock
);
779 static struct mem_input
*dcn10_mem_input_create(
780 struct dc_context
*ctx
,
783 struct dcn10_mem_input
*mem_inputn10
=
784 dm_alloc(sizeof(struct dcn10_mem_input
));
789 if (dcn10_mem_input_construct(mem_inputn10
, ctx
, inst
,
790 &mi_regs
[inst
], &mi_shift
, &mi_mask
))
791 return &mem_inputn10
->base
;
794 dm_free(mem_inputn10
);
798 static void get_pixel_clock_parameters(
799 const struct pipe_ctx
*pipe_ctx
,
800 struct pixel_clk_params
*pixel_clk_params
)
802 const struct core_stream
*stream
= pipe_ctx
->stream
;
803 pixel_clk_params
->requested_pix_clk
= stream
->public.timing
.pix_clk_khz
;
804 pixel_clk_params
->encoder_object_id
= stream
->sink
->link
->link_enc
->id
;
805 pixel_clk_params
->signal_type
= pipe_ctx
->stream
->signal
;
806 pixel_clk_params
->controller_id
= pipe_ctx
->pipe_idx
+ 1;
807 /* TODO: un-hardcode*/
808 pixel_clk_params
->requested_sym_clk
= LINK_RATE_LOW
*
809 LINK_RATE_REF_FREQ_IN_KHZ
;
810 pixel_clk_params
->flags
.ENABLE_SS
= 0;
811 pixel_clk_params
->color_depth
=
812 stream
->public.timing
.display_color_depth
;
813 pixel_clk_params
->flags
.DISPLAY_BLANKED
= 1;
814 pixel_clk_params
->pixel_encoding
= stream
->public.timing
.pixel_encoding
;
816 if (stream
->public.timing
.pixel_encoding
== PIXEL_ENCODING_YCBCR422
)
817 pixel_clk_params
->color_depth
= COLOR_DEPTH_888
;
819 if (stream
->public.timing
.pixel_encoding
== PIXEL_ENCODING_YCBCR420
)
820 pixel_clk_params
->requested_pix_clk
/= 2;
822 if (stream
->public.timing
. timing_3d_format
== TIMING_3D_FORMAT_HW_FRAME_PACKING
||
823 stream
->public.timing
. timing_3d_format
== TIMING_3D_FORMAT_SW_FRAME_PACKING
||
824 stream
->public.timing
. timing_3d_format
== TIMING_3D_FORMAT_DP_HDMI_INBAND_FA
)
825 pixel_clk_params
->requested_pix_clk
*= 2;
828 static void build_clamping_params(struct core_stream
*stream
)
830 stream
->clamping
.clamping_level
= CLAMPING_FULL_RANGE
;
831 stream
->clamping
.c_depth
= stream
->public.timing
.display_color_depth
;
832 stream
->clamping
.pixel_encoding
= stream
->public.timing
.pixel_encoding
;
835 static enum dc_status
build_pipe_hw_param(struct pipe_ctx
*pipe_ctx
)
838 get_pixel_clock_parameters(pipe_ctx
, &pipe_ctx
->pix_clk_params
);
840 pipe_ctx
->clock_source
->funcs
->get_pix_clk_dividers(
841 pipe_ctx
->clock_source
,
842 &pipe_ctx
->pix_clk_params
,
843 &pipe_ctx
->pll_settings
);
845 pipe_ctx
->stream
->clamping
.pixel_encoding
= pipe_ctx
->stream
->public.timing
.pixel_encoding
;
847 resource_build_bit_depth_reduction_params(pipe_ctx
->stream
,
848 &pipe_ctx
->stream
->bit_depth_params
);
849 build_clamping_params(pipe_ctx
->stream
);
854 static enum dc_status
validate_mapped_resource(
855 const struct core_dc
*dc
,
856 struct validate_context
*context
)
858 enum dc_status status
= DC_OK
;
861 for (i
= 0; i
< context
->stream_count
; i
++) {
862 struct core_stream
*stream
= context
->streams
[i
];
863 struct core_link
*link
= stream
->sink
->link
;
865 if (resource_is_stream_unchanged(dc
->current_context
, stream
)) {
866 if (stream
!= NULL
&& dc
->current_context
->streams
[i
] != NULL
) {
867 /* todo: shouldn't have to copy missing parameter here */
868 resource_build_bit_depth_reduction_params(stream
,
869 &stream
->bit_depth_params
);
870 stream
->clamping
.pixel_encoding
=
871 stream
->public.timing
.pixel_encoding
;
873 resource_build_bit_depth_reduction_params(stream
,
874 &stream
->bit_depth_params
);
875 build_clamping_params(stream
);
881 for (j
= 0; j
< dc
->res_pool
->pipe_count
; j
++) {
882 struct pipe_ctx
*pipe_ctx
=
883 &context
->res_ctx
.pipe_ctx
[j
];
885 if (context
->res_ctx
.pipe_ctx
[j
].stream
!= stream
)
889 if (!pipe_ctx
->tg
->funcs
->validate_timing(
890 pipe_ctx
->tg
, &stream
->public.timing
))
891 return DC_FAIL_CONTROLLER_VALIDATE
;
893 status
= build_pipe_hw_param(pipe_ctx
);
898 if (!link
->link_enc
->funcs
->validate_output_with_stream(
899 link
->link_enc
, pipe_ctx
))
900 return DC_FAIL_ENC_VALIDATE
;
902 /* TODO: validate audio ASIC caps, encoder */
904 status
= dc_link_validate_mode_timing(
905 stream
, link
, &stream
->public.timing
);
911 /* do not need to validate non root pipes */
919 enum dc_status
dcn10_validate_with_context(
920 const struct core_dc
*dc
,
921 const struct dc_validation_set set
[],
923 struct validate_context
*context
)
925 enum dc_status result
= DC_OK
;
931 for (i
= 0; i
< set_count
; i
++) {
932 context
->streams
[i
] = DC_STREAM_TO_CORE(set
[i
].stream
);
933 dc_stream_retain(&context
->streams
[i
]->public);
934 context
->stream_count
++;
937 result
= resource_map_pool_resources(dc
, context
);
941 result
= resource_map_phy_clock_resources(dc
, context
);
945 result
= validate_mapped_resource(dc
, context
);
949 if (!resource_validate_attach_surfaces(set
, set_count
,
950 dc
->current_context
, context
, dc
->res_pool
))
951 return DC_FAIL_ATTACH_SURFACES
;
953 result
= resource_build_scaling_params_for_context(dc
, context
);
957 if (!dcn_validate_bandwidth(dc
, context
))
958 return DC_FAIL_BANDWIDTH_VALIDATE
;
963 enum dc_status
dcn10_validate_guaranteed(
964 const struct core_dc
*dc
,
965 const struct dc_stream
*dc_stream
,
966 struct validate_context
*context
)
968 enum dc_status result
= DC_ERROR_UNEXPECTED
;
970 context
->streams
[0] = DC_STREAM_TO_CORE(dc_stream
);
971 dc_stream_retain(&context
->streams
[0]->public);
972 context
->stream_count
++;
974 result
= resource_map_pool_resources(dc
, context
);
977 result
= resource_map_phy_clock_resources(dc
, context
);
980 result
= validate_mapped_resource(dc
, context
);
982 if (result
== DC_OK
) {
983 validate_guaranteed_copy_streams(
984 context
, dc
->public.caps
.max_streams
);
985 result
= resource_build_scaling_params_for_context(dc
, context
);
987 if (result
== DC_OK
&& !dcn_validate_bandwidth(dc
, context
))
988 return DC_FAIL_BANDWIDTH_VALIDATE
;
993 static struct pipe_ctx
*dcn10_acquire_idle_pipe_for_layer(
994 struct validate_context
*context
,
995 const struct resource_pool
*pool
,
996 struct core_stream
*stream
)
998 struct resource_context
*res_ctx
= &context
->res_ctx
;
999 struct pipe_ctx
*head_pipe
= resource_get_head_pipe_for_stream(res_ctx
, stream
);
1000 struct pipe_ctx
*idle_pipe
= find_idle_secondary_pipe(res_ctx
, pool
);
1008 idle_pipe
->stream
= head_pipe
->stream
;
1009 idle_pipe
->tg
= head_pipe
->tg
;
1011 idle_pipe
->mi
= pool
->mis
[idle_pipe
->pipe_idx
];
1012 idle_pipe
->ipp
= pool
->ipps
[idle_pipe
->pipe_idx
];
1013 idle_pipe
->xfm
= pool
->transforms
[idle_pipe
->pipe_idx
];
1014 idle_pipe
->opp
= pool
->opps
[idle_pipe
->pipe_idx
];
1020 dcc_control__256_256_xxx
,
1021 dcc_control__128_128_xxx
,
1022 dcc_control__256_64_64
,
1025 enum segment_order
{
1027 segment_order__contiguous
,
1028 segment_order__non_contiguous
,
1031 static bool dcc_support_pixel_format(
1032 enum surface_pixel_format format
,
1033 unsigned int *bytes_per_element
)
1035 /* DML: get_bytes_per_element */
1037 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555
:
1038 case SURFACE_PIXEL_FORMAT_GRPH_RGB565
:
1039 *bytes_per_element
= 2;
1041 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888
:
1042 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
:
1043 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010
:
1044 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
:
1045 *bytes_per_element
= 4;
1047 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616
:
1048 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F
:
1049 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F
:
1050 *bytes_per_element
= 8;
1057 static bool dcc_support_swizzle(
1058 enum swizzle_mode_values swizzle
,
1059 unsigned int bytes_per_element
,
1060 enum segment_order
*segment_order_horz
,
1061 enum segment_order
*segment_order_vert
)
1063 bool standard_swizzle
= false;
1064 bool display_swizzle
= false;
1071 case DC_SW_64KB_S_X
:
1073 standard_swizzle
= true;
1079 case DC_SW_64KB_D_X
:
1081 display_swizzle
= true;
1087 if (bytes_per_element
== 1 && standard_swizzle
) {
1088 *segment_order_horz
= segment_order__contiguous
;
1089 *segment_order_vert
= segment_order__na
;
1092 if (bytes_per_element
== 2 && standard_swizzle
) {
1093 *segment_order_horz
= segment_order__non_contiguous
;
1094 *segment_order_vert
= segment_order__contiguous
;
1097 if (bytes_per_element
== 4 && standard_swizzle
) {
1098 *segment_order_horz
= segment_order__non_contiguous
;
1099 *segment_order_vert
= segment_order__contiguous
;
1102 if (bytes_per_element
== 8 && standard_swizzle
) {
1103 *segment_order_horz
= segment_order__na
;
1104 *segment_order_vert
= segment_order__contiguous
;
1107 if (bytes_per_element
== 8 && display_swizzle
) {
1108 *segment_order_horz
= segment_order__contiguous
;
1109 *segment_order_vert
= segment_order__non_contiguous
;
1116 static void get_blk256_size(unsigned int *blk256_width
, unsigned int *blk256_height
,
1117 unsigned int bytes_per_element
)
1119 /* copied from DML. might want to refactor DML to leverage from DML */
1120 /* DML : get_blk256_size */
1121 if (bytes_per_element
== 1) {
1123 *blk256_height
= 16;
1124 } else if (bytes_per_element
== 2) {
1127 } else if (bytes_per_element
== 4) {
1130 } else if (bytes_per_element
== 8) {
1136 static void det_request_size(
1137 unsigned int height
,
1140 bool *req128_horz_wc
,
1141 bool *req128_vert_wc
)
1143 unsigned int detile_buf_size
= 164 * 1024; /* 164KB for DCN1.0 */
1145 unsigned int blk256_height
= 0;
1146 unsigned int blk256_width
= 0;
1147 unsigned int swath_bytes_horz_wc
, swath_bytes_vert_wc
;
1149 get_blk256_size(&blk256_width
, &blk256_height
, bpe
);
1151 swath_bytes_horz_wc
= height
* blk256_height
* bpe
;
1152 swath_bytes_vert_wc
= width
* blk256_width
* bpe
;
1154 *req128_horz_wc
= (2 * swath_bytes_horz_wc
<= detile_buf_size
) ?
1155 false : /* full 256B request */
1156 true; /* half 128b request */
1158 *req128_vert_wc
= (2 * swath_bytes_vert_wc
<= detile_buf_size
) ?
1159 false : /* full 256B request */
1160 true; /* half 128b request */
1163 static bool get_dcc_compression_cap(const struct dc
*dc
,
1164 const struct dc_dcc_surface_param
*input
,
1165 struct dc_surface_dcc_cap
*output
)
1167 /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */
1168 enum dcc_control dcc_control
;
1170 enum segment_order segment_order_horz
, segment_order_vert
;
1171 bool req128_horz_wc
, req128_vert_wc
;
1173 memset(output
, 0, sizeof(*output
));
1175 if (dc
->debug
.disable_dcc
)
1178 if (!dcc_support_pixel_format(input
->format
,
1182 if (!dcc_support_swizzle(input
->swizzle_mode
, bpe
,
1183 &segment_order_horz
, &segment_order_vert
))
1186 det_request_size(input
->surface_size
.height
, input
->surface_size
.width
,
1187 bpe
, &req128_horz_wc
, &req128_vert_wc
);
1189 if (!req128_horz_wc
&& !req128_vert_wc
) {
1190 dcc_control
= dcc_control__256_256_xxx
;
1191 } else if (input
->scan
== SCAN_DIRECTION_HORIZONTAL
) {
1192 if (!req128_horz_wc
)
1193 dcc_control
= dcc_control__256_256_xxx
;
1194 else if (segment_order_horz
== segment_order__contiguous
)
1195 dcc_control
= dcc_control__128_128_xxx
;
1197 dcc_control
= dcc_control__256_64_64
;
1198 } else if (input
->scan
== SCAN_DIRECTION_VERTICAL
) {
1199 if (!req128_vert_wc
)
1200 dcc_control
= dcc_control__256_256_xxx
;
1201 else if (segment_order_vert
== segment_order__contiguous
)
1202 dcc_control
= dcc_control__128_128_xxx
;
1204 dcc_control
= dcc_control__256_64_64
;
1206 if ((req128_horz_wc
&&
1207 segment_order_horz
== segment_order__non_contiguous
) ||
1209 segment_order_vert
== segment_order__non_contiguous
))
1210 /* access_dir not known, must use most constraining */
1211 dcc_control
= dcc_control__256_64_64
;
1213 /* reg128 is true for either horz and vert
1214 * but segment_order is contiguous
1216 dcc_control
= dcc_control__128_128_xxx
;
1219 switch (dcc_control
) {
1220 case dcc_control__256_256_xxx
:
1221 output
->grph
.rgb
.max_uncompressed_blk_size
= 256;
1222 output
->grph
.rgb
.max_compressed_blk_size
= 256;
1223 output
->grph
.rgb
.independent_64b_blks
= false;
1225 case dcc_control__128_128_xxx
:
1226 output
->grph
.rgb
.max_uncompressed_blk_size
= 128;
1227 output
->grph
.rgb
.max_compressed_blk_size
= 128;
1228 output
->grph
.rgb
.independent_64b_blks
= false;
1230 case dcc_control__256_64_64
:
1231 output
->grph
.rgb
.max_uncompressed_blk_size
= 256;
1232 output
->grph
.rgb
.max_compressed_blk_size
= 64;
1233 output
->grph
.rgb
.independent_64b_blks
= true;
1236 output
->capable
= true;
1237 output
->const_color_support
= false;
1243 static void dcn10_destroy_resource_pool(struct resource_pool
**pool
)
1245 struct dcn10_resource_pool
*dcn10_pool
= TO_DCN10_RES_POOL(*pool
);
1247 destruct(dcn10_pool
);
1248 dm_free(dcn10_pool
);
1253 static struct dc_cap_funcs cap_funcs
= {
1254 .get_dcc_compression_cap
= get_dcc_compression_cap
1257 static struct resource_funcs dcn10_res_pool_funcs
= {
1258 .destroy
= dcn10_destroy_resource_pool
,
1259 .link_enc_create
= dcn10_link_encoder_create
,
1260 .validate_with_context
= dcn10_validate_with_context
,
1261 .validate_guaranteed
= dcn10_validate_guaranteed
,
1262 .validate_bandwidth
= dcn_validate_bandwidth
,
1263 .acquire_idle_pipe_for_layer
= dcn10_acquire_idle_pipe_for_layer
,
1266 static bool construct(
1267 uint8_t num_virtual_links
,
1269 struct dcn10_resource_pool
*pool
)
1272 struct dc_context
*ctx
= dc
->ctx
;
1274 ctx
->dc_bios
->regs
= &bios_regs
;
1276 pool
->base
.res_cap
= &res_cap
;
1277 pool
->base
.funcs
= &dcn10_res_pool_funcs
;
1280 * TODO fill in from actual raven resource when we create
1281 * more than virtual encoder
1284 /*************************************************
1285 * Resource + asic cap harcoding *
1286 *************************************************/
1287 pool
->base
.underlay_pipe_index
= NO_UNDERLAY_PIPE
;
1289 /* TODO: Hardcode to correct number of functional controllers */
1290 pool
->base
.pipe_count
= 4;
1291 dc
->public.caps
.max_downscale_ratio
= 200;
1292 dc
->public.caps
.i2c_speed_in_khz
= 100;
1293 dc
->public.caps
.max_cursor_size
= 256;
1295 if (dc
->ctx
->dce_environment
== DCE_ENV_PRODUCTION_DRV
)
1296 dc
->public.debug
= debug_defaults_drv
;
1298 dc
->public.debug
= debug_defaults_diags
;
1300 /*************************************************
1301 * Create resources *
1302 *************************************************/
1304 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL0
] =
1305 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1306 CLOCK_SOURCE_COMBO_PHY_PLL0
,
1307 &clk_src_regs
[0], false);
1308 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL1
] =
1309 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1310 CLOCK_SOURCE_COMBO_PHY_PLL1
,
1311 &clk_src_regs
[1], false);
1312 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL2
] =
1313 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1314 CLOCK_SOURCE_COMBO_PHY_PLL2
,
1315 &clk_src_regs
[2], false);
1316 pool
->base
.clock_sources
[DCN10_CLK_SRC_PLL3
] =
1317 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1318 CLOCK_SOURCE_COMBO_PHY_PLL3
,
1319 &clk_src_regs
[3], false);
1321 pool
->base
.clk_src_count
= DCN10_CLK_SRC_TOTAL
;
1323 pool
->base
.dp_clock_source
=
1324 dcn10_clock_source_create(ctx
, ctx
->dc_bios
,
1325 CLOCK_SOURCE_ID_DP_DTO
,
1326 /* todo: not reuse phy_pll registers */
1327 &clk_src_regs
[0], true);
1329 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
1330 if (pool
->base
.clock_sources
[i
] == NULL
) {
1331 dm_error("DC: failed to create clock sources!\n");
1332 BREAK_TO_DEBUGGER();
1333 goto clock_source_create_fail
;
1337 if (!IS_FPGA_MAXIMUS_DC(dc
->ctx
->dce_environment
)) {
1338 pool
->base
.display_clock
= dce120_disp_clk_create(ctx
,
1342 if (pool
->base
.display_clock
== NULL
) {
1343 dm_error("DC: failed to create display clock!\n");
1344 BREAK_TO_DEBUGGER();
1345 goto disp_clk_create_fail
;
1349 pool
->base
.dmcu
= dcn10_dmcu_create(ctx
,
1353 if (pool
->base
.dmcu
== NULL
) {
1354 dm_error("DC: failed to create dmcu!\n");
1355 BREAK_TO_DEBUGGER();
1356 goto res_create_fail
;
1359 pool
->base
.abm
= dce_abm_create(ctx
,
1363 if (pool
->base
.abm
== NULL
) {
1364 dm_error("DC: failed to create abm!\n");
1365 BREAK_TO_DEBUGGER();
1366 goto res_create_fail
;
1369 dml_init_instance(&dc
->dml
, DML_PROJECT_RAVEN1
);
1370 dc
->dcn_ip
= dcn10_ip_defaults
;
1371 dc
->dcn_soc
= dcn10_soc_defaults
;
1372 if (!dc
->public.debug
.disable_pplib_clock_request
)
1373 dcn_bw_update_from_pplib(dc
);
1374 dcn_bw_sync_calcs_and_dml(dc
);
1375 if (!dc
->public.debug
.disable_pplib_wm_range
)
1376 dcn_bw_notify_pplib_of_wm_ranges(dc
);
1379 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
1380 struct irq_service_init_data init_data
;
1381 init_data
.ctx
= dc
->ctx
;
1382 pool
->base
.irqs
= dal_irq_service_dcn10_create(&init_data
);
1383 if (!pool
->base
.irqs
)
1384 goto irqs_create_fail
;
1388 /* mem input -> ipp -> transform -> opp -> TG */
1389 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
1390 pool
->base
.mis
[i
] = dcn10_mem_input_create(ctx
, i
);
1391 if (pool
->base
.mis
[i
] == NULL
) {
1392 BREAK_TO_DEBUGGER();
1394 "DC: failed to create memory input!\n");
1395 goto mi_create_fail
;
1398 pool
->base
.ipps
[i
] = dcn10_ipp_create(ctx
, i
);
1399 if (pool
->base
.ipps
[i
] == NULL
) {
1400 BREAK_TO_DEBUGGER();
1402 "DC: failed to create input pixel processor!\n");
1403 goto ipp_create_fail
;
1406 pool
->base
.transforms
[i
] = dcn10_transform_create(ctx
, i
);
1407 if (pool
->base
.transforms
[i
] == NULL
) {
1408 BREAK_TO_DEBUGGER();
1410 "DC: failed to create transform!\n");
1411 goto transform_create_fail
;
1414 pool
->base
.opps
[i
] = dcn10_opp_create(ctx
, i
);
1415 if (pool
->base
.opps
[i
] == NULL
) {
1416 BREAK_TO_DEBUGGER();
1418 "DC: failed to create output pixel processor!\n");
1419 goto opp_create_fail
;
1422 pool
->base
.timing_generators
[i
] = dcn10_timing_generator_create(
1424 if (pool
->base
.timing_generators
[i
] == NULL
) {
1425 BREAK_TO_DEBUGGER();
1426 dm_error("DC: failed to create tg!\n");
1427 goto otg_create_fail
;
1431 pool
->base
.mpc
= dcn10_mpc_create(ctx
);
1433 if (!resource_construct(num_virtual_links
, dc
, &pool
->base
,
1434 (!IS_FPGA_MAXIMUS_DC(dc
->ctx
->dce_environment
) ?
1435 &res_create_funcs
: &res_create_maximus_funcs
)))
1436 goto res_create_fail
;
1438 dcn10_hw_sequencer_construct(dc
);
1439 dc
->public.caps
.max_surfaces
= pool
->base
.pipe_count
;
1441 dc
->public.cap_funcs
= cap_funcs
;
1445 disp_clk_create_fail
:
1448 transform_create_fail
:
1453 clock_source_create_fail
:
1460 struct resource_pool
*dcn10_create_resource_pool(
1461 uint8_t num_virtual_links
,
1464 struct dcn10_resource_pool
*pool
=
1465 dm_alloc(sizeof(struct dcn10_resource_pool
));
1470 if (construct(num_virtual_links
, dc
, pool
))
1473 BREAK_TO_DEBUGGER();