2 * Copyright 2012-15 Advanced Micro Devices, Inc.cls
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
27 #include <linux/slab.h>
29 #include "dm_services.h"
32 #include "stream_encoder.h"
34 #include "include/irq_service_interface.h"
35 #include "dce120_resource.h"
37 #include "dce112/dce112_resource.h"
39 #include "dce110/dce110_resource.h"
40 #include "../virtual/virtual_stream_encoder.h"
41 #include "dce120_timing_generator.h"
42 #include "irq/dce120/irq_service_dce120.h"
43 #include "dce/dce_opp.h"
44 #include "dce/dce_clock_source.h"
45 #include "dce/dce_ipp.h"
46 #include "dce/dce_mem_input.h"
48 #include "dce110/dce110_hw_sequencer.h"
49 #include "dce120/dce120_hw_sequencer.h"
50 #include "dce/dce_transform.h"
52 #include "dce/dce_audio.h"
53 #include "dce/dce_link_encoder.h"
54 #include "dce/dce_stream_encoder.h"
55 #include "dce/dce_hwseq.h"
56 #include "dce/dce_abm.h"
57 #include "dce/dce_dmcu.h"
58 #include "dce/dce_aux.h"
59 #include "dce/dce_i2c.h"
61 #include "dce/dce_12_0_offset.h"
62 #include "dce/dce_12_0_sh_mask.h"
63 #include "soc15_hw_ip.h"
64 #include "vega10_ip_offset.h"
65 #include "nbio/nbio_6_1_offset.h"
66 #include "mmhub/mmhub_1_0_offset.h"
67 #include "mmhub/mmhub_1_0_sh_mask.h"
68 #include "reg_helper.h"
70 #include "dce100/dce100_resource.h"
72 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
73 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
74 #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
75 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
76 #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
77 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
78 #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
79 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
80 #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
81 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
82 #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
83 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f
84 #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
85 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f
86 #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
89 enum dce120_clk_src_array_id
{
100 static const struct dce110_timing_generator_offsets dce120_tg_offsets
[] = {
102 .crtc
= (mmCRTC0_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
105 .crtc
= (mmCRTC1_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
108 .crtc
= (mmCRTC2_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
111 .crtc
= (mmCRTC3_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
114 .crtc
= (mmCRTC4_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
117 .crtc
= (mmCRTC5_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
121 /* begin *********************
122 * macros to expend register list macro defined in HW object header file */
124 #define BASE_INNER(seg) \
125 DCE_BASE__INST0_SEG ## seg
127 #define NBIO_BASE_INNER(seg) \
128 NBIF_BASE__INST0_SEG ## seg
130 #define NBIO_BASE(seg) \
133 /* compile time expand base address. */
137 #define SR(reg_name)\
138 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
141 #define SRI(reg_name, block, id)\
142 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
143 mm ## block ## id ## _ ## reg_name
146 #define MMHUB_BASE_INNER(seg) \
147 MMHUB_BASE__INST0_SEG ## seg
149 #define MMHUB_BASE(seg) \
150 MMHUB_BASE_INNER(seg)
152 #define MMHUB_SR(reg_name)\
153 .reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) + \
156 /* macros to expend register list macro defined in HW object header file
157 * end *********************/
160 static const struct dce_dmcu_registers dmcu_regs
= {
161 DMCU_DCE110_COMMON_REG_LIST()
164 static const struct dce_dmcu_shift dmcu_shift
= {
165 DMCU_MASK_SH_LIST_DCE110(__SHIFT
)
168 static const struct dce_dmcu_mask dmcu_mask
= {
169 DMCU_MASK_SH_LIST_DCE110(_MASK
)
172 static const struct dce_abm_registers abm_regs
= {
173 ABM_DCE110_COMMON_REG_LIST()
176 static const struct dce_abm_shift abm_shift
= {
177 ABM_MASK_SH_LIST_DCE110(__SHIFT
)
180 static const struct dce_abm_mask abm_mask
= {
181 ABM_MASK_SH_LIST_DCE110(_MASK
)
184 #define ipp_regs(id)\
186 IPP_DCE110_REG_LIST_DCE_BASE(id)\
189 static const struct dce_ipp_registers ipp_regs
[] = {
198 static const struct dce_ipp_shift ipp_shift
= {
199 IPP_DCE120_MASK_SH_LIST_SOC_BASE(__SHIFT
)
202 static const struct dce_ipp_mask ipp_mask
= {
203 IPP_DCE120_MASK_SH_LIST_SOC_BASE(_MASK
)
206 #define transform_regs(id)\
208 XFM_COMMON_REG_LIST_DCE110(id)\
211 static const struct dce_transform_registers xfm_regs
[] = {
220 static const struct dce_transform_shift xfm_shift
= {
221 XFM_COMMON_MASK_SH_LIST_SOC_BASE(__SHIFT
)
224 static const struct dce_transform_mask xfm_mask
= {
225 XFM_COMMON_MASK_SH_LIST_SOC_BASE(_MASK
)
228 #define aux_regs(id)\
233 static const struct dce110_link_enc_aux_registers link_enc_aux_regs
[] = {
242 #define hpd_regs(id)\
247 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs
[] = {
256 #define link_regs(id)\
258 LE_DCE120_REG_LIST(id), \
259 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
262 static const struct dce110_link_enc_registers link_enc_regs
[] = {
273 #define stream_enc_regs(id)\
275 SE_COMMON_REG_LIST(id),\
279 static const struct dce110_stream_enc_registers stream_enc_regs
[] = {
288 static const struct dce_stream_encoder_shift se_shift
= {
289 SE_COMMON_MASK_SH_LIST_DCE120(__SHIFT
)
292 static const struct dce_stream_encoder_mask se_mask
= {
293 SE_COMMON_MASK_SH_LIST_DCE120(_MASK
)
296 static const struct dce110_aux_registers_shift aux_shift
= {
297 DCE12_AUX_MASK_SH_LIST(__SHIFT
)
300 static const struct dce110_aux_registers_mask aux_mask
= {
301 DCE12_AUX_MASK_SH_LIST(_MASK
)
304 #define opp_regs(id)\
306 OPP_DCE_120_REG_LIST(id),\
309 static const struct dce_opp_registers opp_regs
[] = {
318 static const struct dce_opp_shift opp_shift
= {
319 OPP_COMMON_MASK_SH_LIST_DCE_120(__SHIFT
)
322 static const struct dce_opp_mask opp_mask
= {
323 OPP_COMMON_MASK_SH_LIST_DCE_120(_MASK
)
325 #define aux_engine_regs(id)\
327 AUX_COMMON_REG_LIST(id), \
328 .AUX_RESET_MASK = 0 \
331 static const struct dce110_aux_registers aux_engine_regs
[] = {
340 #define audio_regs(id)\
342 AUD_COMMON_REG_LIST(id)\
345 static const struct dce_audio_registers audio_regs
[] = {
354 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
355 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
356 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
357 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
359 static const struct dce_audio_shift audio_shift
= {
360 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT
)
363 static const struct dce_audio_mask audio_mask
= {
364 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK
)
367 static int map_transmitter_id_to_phy_instance(
368 enum transmitter transmitter
)
370 switch (transmitter
) {
371 case TRANSMITTER_UNIPHY_A
:
374 case TRANSMITTER_UNIPHY_B
:
377 case TRANSMITTER_UNIPHY_C
:
380 case TRANSMITTER_UNIPHY_D
:
383 case TRANSMITTER_UNIPHY_E
:
386 case TRANSMITTER_UNIPHY_F
:
389 case TRANSMITTER_UNIPHY_G
:
398 #define clk_src_regs(index, id)\
400 CS_COMMON_REG_LIST_DCE_112(id),\
403 static const struct dce110_clk_src_regs clk_src_regs
[] = {
412 static const struct dce110_clk_src_shift cs_shift
= {
413 CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT
)
416 static const struct dce110_clk_src_mask cs_mask
= {
417 CS_COMMON_MASK_SH_LIST_DCE_112(_MASK
)
420 struct output_pixel_processor
*dce120_opp_create(
421 struct dc_context
*ctx
,
424 struct dce110_opp
*opp
=
425 kzalloc(sizeof(struct dce110_opp
), GFP_KERNEL
);
430 dce110_opp_construct(opp
,
431 ctx
, inst
, &opp_regs
[inst
], &opp_shift
, &opp_mask
);
434 struct dce_aux
*dce120_aux_engine_create(
435 struct dc_context
*ctx
,
438 struct aux_engine_dce110
*aux_engine
=
439 kzalloc(sizeof(struct aux_engine_dce110
), GFP_KERNEL
);
444 dce110_aux_engine_construct(aux_engine
, ctx
, inst
,
445 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER
* AUX_TIMEOUT_PERIOD
,
446 &aux_engine_regs
[inst
],
449 ctx
->dc
->caps
.extended_aux_timeout_support
);
451 return &aux_engine
->base
;
453 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
455 static const struct dce_i2c_registers i2c_hw_regs
[] = {
464 static const struct dce_i2c_shift i2c_shifts
= {
465 I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT
)
468 static const struct dce_i2c_mask i2c_masks
= {
469 I2C_COMMON_MASK_SH_LIST_DCE110(_MASK
)
472 struct dce_i2c_hw
*dce120_i2c_hw_create(
473 struct dc_context
*ctx
,
476 struct dce_i2c_hw
*dce_i2c_hw
=
477 kzalloc(sizeof(struct dce_i2c_hw
), GFP_KERNEL
);
482 dce112_i2c_hw_construct(dce_i2c_hw
, ctx
, inst
,
483 &i2c_hw_regs
[inst
], &i2c_shifts
, &i2c_masks
);
487 static const struct bios_registers bios_regs
= {
488 .BIOS_SCRATCH_3
= mmBIOS_SCRATCH_3
+ NBIO_BASE(mmBIOS_SCRATCH_3_BASE_IDX
),
489 .BIOS_SCRATCH_6
= mmBIOS_SCRATCH_6
+ NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX
)
492 static const struct resource_caps res_cap
= {
493 .num_timing_generator
= 6,
495 .num_stream_encoder
= 6,
500 static const struct dc_plane_cap plane_cap
= {
501 .type
= DC_PLANE_TYPE_DCE_RGB
,
503 .pixel_format_support
= {
509 .max_upscale_factor
= {
515 .max_downscale_factor
= {
522 static const struct dc_debug_options debug_defaults
= {
523 .disable_clock_gate
= true,
526 static struct clock_source
*dce120_clock_source_create(
527 struct dc_context
*ctx
,
528 struct dc_bios
*bios
,
529 enum clock_source_id id
,
530 const struct dce110_clk_src_regs
*regs
,
533 struct dce110_clk_src
*clk_src
=
534 kzalloc(sizeof(*clk_src
), GFP_KERNEL
);
539 if (dce112_clk_src_construct(clk_src
, ctx
, bios
, id
,
540 regs
, &cs_shift
, &cs_mask
)) {
541 clk_src
->base
.dp_clk_src
= dp_clk_src
;
542 return &clk_src
->base
;
550 static void dce120_clock_source_destroy(struct clock_source
**clk_src
)
552 kfree(TO_DCE110_CLK_SRC(*clk_src
));
557 static bool dce120_hw_sequencer_create(struct dc
*dc
)
559 /* All registers used by dce11.2 match those in dce11 in offset and
562 dce120_hw_sequencer_construct(dc
);
564 /*TODO Move to separate file and Override what is needed */
569 static struct timing_generator
*dce120_timing_generator_create(
570 struct dc_context
*ctx
,
572 const struct dce110_timing_generator_offsets
*offsets
)
574 struct dce110_timing_generator
*tg110
=
575 kzalloc(sizeof(struct dce110_timing_generator
), GFP_KERNEL
);
580 dce120_timing_generator_construct(tg110
, ctx
, instance
, offsets
);
584 static void dce120_transform_destroy(struct transform
**xfm
)
586 kfree(TO_DCE_TRANSFORM(*xfm
));
590 static void dce120_resource_destruct(struct dce110_resource_pool
*pool
)
594 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
595 if (pool
->base
.opps
[i
] != NULL
)
596 dce110_opp_destroy(&pool
->base
.opps
[i
]);
598 if (pool
->base
.transforms
[i
] != NULL
)
599 dce120_transform_destroy(&pool
->base
.transforms
[i
]);
601 if (pool
->base
.ipps
[i
] != NULL
)
602 dce_ipp_destroy(&pool
->base
.ipps
[i
]);
604 if (pool
->base
.mis
[i
] != NULL
) {
605 kfree(TO_DCE_MEM_INPUT(pool
->base
.mis
[i
]));
606 pool
->base
.mis
[i
] = NULL
;
609 if (pool
->base
.irqs
!= NULL
) {
610 dal_irq_service_destroy(&pool
->base
.irqs
);
613 if (pool
->base
.timing_generators
[i
] != NULL
) {
614 kfree(DCE110TG_FROM_TG(pool
->base
.timing_generators
[i
]));
615 pool
->base
.timing_generators
[i
] = NULL
;
619 for (i
= 0; i
< pool
->base
.res_cap
->num_ddc
; i
++) {
620 if (pool
->base
.engines
[i
] != NULL
)
621 dce110_engine_destroy(&pool
->base
.engines
[i
]);
622 if (pool
->base
.hw_i2cs
[i
] != NULL
) {
623 kfree(pool
->base
.hw_i2cs
[i
]);
624 pool
->base
.hw_i2cs
[i
] = NULL
;
626 if (pool
->base
.sw_i2cs
[i
] != NULL
) {
627 kfree(pool
->base
.sw_i2cs
[i
]);
628 pool
->base
.sw_i2cs
[i
] = NULL
;
632 for (i
= 0; i
< pool
->base
.audio_count
; i
++) {
633 if (pool
->base
.audios
[i
])
634 dce_aud_destroy(&pool
->base
.audios
[i
]);
637 for (i
= 0; i
< pool
->base
.stream_enc_count
; i
++) {
638 if (pool
->base
.stream_enc
[i
] != NULL
)
639 kfree(DCE110STRENC_FROM_STRENC(pool
->base
.stream_enc
[i
]));
642 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
643 if (pool
->base
.clock_sources
[i
] != NULL
)
644 dce120_clock_source_destroy(
645 &pool
->base
.clock_sources
[i
]);
648 if (pool
->base
.dp_clock_source
!= NULL
)
649 dce120_clock_source_destroy(&pool
->base
.dp_clock_source
);
651 if (pool
->base
.abm
!= NULL
)
652 dce_abm_destroy(&pool
->base
.abm
);
654 if (pool
->base
.dmcu
!= NULL
)
655 dce_dmcu_destroy(&pool
->base
.dmcu
);
658 static void read_dce_straps(
659 struct dc_context
*ctx
,
660 struct resource_straps
*straps
)
662 uint32_t reg_val
= dm_read_reg_soc15(ctx
, mmCC_DC_MISC_STRAPS
, 0);
664 straps
->audio_stream_number
= get_reg_field_value(reg_val
,
666 AUDIO_STREAM_NUMBER
);
667 straps
->hdmi_disable
= get_reg_field_value(reg_val
,
671 reg_val
= dm_read_reg_soc15(ctx
, mmDC_PINSTRAPS
, 0);
672 straps
->dc_pinstraps_audio
= get_reg_field_value(reg_val
,
677 static struct audio
*create_audio(
678 struct dc_context
*ctx
, unsigned int inst
)
680 return dce_audio_create(ctx
, inst
,
681 &audio_regs
[inst
], &audio_shift
, &audio_mask
);
684 static const struct encoder_feature_support link_enc_feature
= {
685 .max_hdmi_deep_color
= COLOR_DEPTH_121212
,
686 .max_hdmi_pixel_clock
= 600000,
687 .hdmi_ycbcr420_supported
= true,
688 .dp_ycbcr420_supported
= false,
689 .flags
.bits
.IS_HBR2_CAPABLE
= true,
690 .flags
.bits
.IS_HBR3_CAPABLE
= true,
691 .flags
.bits
.IS_TPS3_CAPABLE
= true,
692 .flags
.bits
.IS_TPS4_CAPABLE
= true,
695 static struct link_encoder
*dce120_link_encoder_create(
696 const struct encoder_init_data
*enc_init_data
)
698 struct dce110_link_encoder
*enc110
=
699 kzalloc(sizeof(struct dce110_link_encoder
), GFP_KERNEL
);
706 map_transmitter_id_to_phy_instance(enc_init_data
->transmitter
);
708 dce110_link_encoder_construct(enc110
,
711 &link_enc_regs
[link_regs_id
],
712 &link_enc_aux_regs
[enc_init_data
->channel
- 1],
713 &link_enc_hpd_regs
[enc_init_data
->hpd_source
]);
715 return &enc110
->base
;
718 static struct input_pixel_processor
*dce120_ipp_create(
719 struct dc_context
*ctx
, uint32_t inst
)
721 struct dce_ipp
*ipp
= kzalloc(sizeof(struct dce_ipp
), GFP_KERNEL
);
728 dce_ipp_construct(ipp
, ctx
, inst
,
729 &ipp_regs
[inst
], &ipp_shift
, &ipp_mask
);
733 static struct stream_encoder
*dce120_stream_encoder_create(
734 enum engine_id eng_id
,
735 struct dc_context
*ctx
)
737 struct dce110_stream_encoder
*enc110
=
738 kzalloc(sizeof(struct dce110_stream_encoder
), GFP_KERNEL
);
743 dce110_stream_encoder_construct(enc110
, ctx
, ctx
->dc_bios
, eng_id
,
744 &stream_enc_regs
[eng_id
],
745 &se_shift
, &se_mask
);
746 return &enc110
->base
;
749 #define SRII(reg_name, block, id)\
750 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
751 mm ## block ## id ## _ ## reg_name
753 static const struct dce_hwseq_registers hwseq_reg
= {
754 HWSEQ_DCE120_REG_LIST()
757 static const struct dce_hwseq_shift hwseq_shift
= {
758 HWSEQ_DCE12_MASK_SH_LIST(__SHIFT
)
761 static const struct dce_hwseq_mask hwseq_mask
= {
762 HWSEQ_DCE12_MASK_SH_LIST(_MASK
)
765 /* HWSEQ regs for VG20 */
766 static const struct dce_hwseq_registers dce121_hwseq_reg
= {
767 HWSEQ_VG20_REG_LIST()
770 static const struct dce_hwseq_shift dce121_hwseq_shift
= {
771 HWSEQ_VG20_MASK_SH_LIST(__SHIFT
)
774 static const struct dce_hwseq_mask dce121_hwseq_mask
= {
775 HWSEQ_VG20_MASK_SH_LIST(_MASK
)
778 static struct dce_hwseq
*dce120_hwseq_create(
779 struct dc_context
*ctx
)
781 struct dce_hwseq
*hws
= kzalloc(sizeof(struct dce_hwseq
), GFP_KERNEL
);
785 hws
->regs
= &hwseq_reg
;
786 hws
->shifts
= &hwseq_shift
;
787 hws
->masks
= &hwseq_mask
;
792 static struct dce_hwseq
*dce121_hwseq_create(
793 struct dc_context
*ctx
)
795 struct dce_hwseq
*hws
= kzalloc(sizeof(struct dce_hwseq
), GFP_KERNEL
);
799 hws
->regs
= &dce121_hwseq_reg
;
800 hws
->shifts
= &dce121_hwseq_shift
;
801 hws
->masks
= &dce121_hwseq_mask
;
806 static const struct resource_create_funcs res_create_funcs
= {
807 .read_dce_straps
= read_dce_straps
,
808 .create_audio
= create_audio
,
809 .create_stream_encoder
= dce120_stream_encoder_create
,
810 .create_hwseq
= dce120_hwseq_create
,
813 static const struct resource_create_funcs dce121_res_create_funcs
= {
814 .read_dce_straps
= read_dce_straps
,
815 .create_audio
= create_audio
,
816 .create_stream_encoder
= dce120_stream_encoder_create
,
817 .create_hwseq
= dce121_hwseq_create
,
821 #define mi_inst_regs(id) { MI_DCE12_REG_LIST(id) }
822 static const struct dce_mem_input_registers mi_regs
[] = {
831 static const struct dce_mem_input_shift mi_shifts
= {
832 MI_DCE12_MASK_SH_LIST(__SHIFT
)
835 static const struct dce_mem_input_mask mi_masks
= {
836 MI_DCE12_MASK_SH_LIST(_MASK
)
839 static struct mem_input
*dce120_mem_input_create(
840 struct dc_context
*ctx
,
843 struct dce_mem_input
*dce_mi
= kzalloc(sizeof(struct dce_mem_input
),
851 dce120_mem_input_construct(dce_mi
, ctx
, inst
, &mi_regs
[inst
], &mi_shifts
, &mi_masks
);
852 return &dce_mi
->base
;
855 static struct transform
*dce120_transform_create(
856 struct dc_context
*ctx
,
859 struct dce_transform
*transform
=
860 kzalloc(sizeof(struct dce_transform
), GFP_KERNEL
);
865 dce_transform_construct(transform
, ctx
, inst
,
866 &xfm_regs
[inst
], &xfm_shift
, &xfm_mask
);
867 transform
->lb_memory_size
= 0x1404; /*5124*/
868 return &transform
->base
;
871 static void dce120_destroy_resource_pool(struct resource_pool
**pool
)
873 struct dce110_resource_pool
*dce110_pool
= TO_DCE110_RES_POOL(*pool
);
875 dce120_resource_destruct(dce110_pool
);
880 static const struct resource_funcs dce120_res_pool_funcs
= {
881 .destroy
= dce120_destroy_resource_pool
,
882 .link_enc_create
= dce120_link_encoder_create
,
883 .validate_bandwidth
= dce112_validate_bandwidth
,
884 .validate_plane
= dce100_validate_plane
,
885 .add_stream_to_ctx
= dce112_add_stream_to_ctx
,
886 .find_first_free_match_stream_enc_for_link
= dce110_find_first_free_match_stream_enc_for_link
889 static void bw_calcs_data_update_from_pplib(struct dc
*dc
)
891 struct dm_pp_clock_levels_with_latency eng_clks
= {0};
892 struct dm_pp_clock_levels_with_latency mem_clks
= {0};
893 struct dm_pp_wm_sets_with_clock_ranges clk_ranges
= {0};
896 unsigned int latency
;
897 /*original logic in dal3*/
898 int memory_type_multiplier
= MEMORY_TYPE_MULTIPLIER_CZ
;
901 if (!dm_pp_get_clock_levels_by_type_with_latency(
903 DM_PP_CLOCK_TYPE_ENGINE_CLK
,
904 &eng_clks
) || eng_clks
.num_levels
== 0) {
906 eng_clks
.num_levels
= 8;
909 for (i
= 0; i
< eng_clks
.num_levels
; i
++) {
910 eng_clks
.data
[i
].clocks_in_khz
= clk
;
915 /* convert all the clock fro kHz to fix point mHz TODO: wloop data */
916 dc
->bw_vbios
->high_sclk
= bw_frc_to_fixed(
917 eng_clks
.data
[eng_clks
.num_levels
-1].clocks_in_khz
, 1000);
918 dc
->bw_vbios
->mid1_sclk
= bw_frc_to_fixed(
919 eng_clks
.data
[eng_clks
.num_levels
/8].clocks_in_khz
, 1000);
920 dc
->bw_vbios
->mid2_sclk
= bw_frc_to_fixed(
921 eng_clks
.data
[eng_clks
.num_levels
*2/8].clocks_in_khz
, 1000);
922 dc
->bw_vbios
->mid3_sclk
= bw_frc_to_fixed(
923 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
, 1000);
924 dc
->bw_vbios
->mid4_sclk
= bw_frc_to_fixed(
925 eng_clks
.data
[eng_clks
.num_levels
*4/8].clocks_in_khz
, 1000);
926 dc
->bw_vbios
->mid5_sclk
= bw_frc_to_fixed(
927 eng_clks
.data
[eng_clks
.num_levels
*5/8].clocks_in_khz
, 1000);
928 dc
->bw_vbios
->mid6_sclk
= bw_frc_to_fixed(
929 eng_clks
.data
[eng_clks
.num_levels
*6/8].clocks_in_khz
, 1000);
930 dc
->bw_vbios
->low_sclk
= bw_frc_to_fixed(
931 eng_clks
.data
[0].clocks_in_khz
, 1000);
934 if (!dm_pp_get_clock_levels_by_type_with_latency(
936 DM_PP_CLOCK_TYPE_MEMORY_CLK
,
937 &mem_clks
) || mem_clks
.num_levels
== 0) {
939 mem_clks
.num_levels
= 3;
943 for (i
= 0; i
< eng_clks
.num_levels
; i
++) {
944 mem_clks
.data
[i
].clocks_in_khz
= clk
;
945 mem_clks
.data
[i
].latency_in_us
= latency
;
952 /* we don't need to call PPLIB for validation clock since they
953 * also give us the highest sclk and highest mclk (UMA clock).
954 * ALSO always convert UMA clock (from PPLIB) to YCLK (HW formula):
955 * YCLK = UMACLK*m_memoryTypeMultiplier
957 if (dc
->bw_vbios
->memory_type
== bw_def_hbm
)
958 memory_type_multiplier
= MEMORY_TYPE_HBM
;
960 dc
->bw_vbios
->low_yclk
= bw_frc_to_fixed(
961 mem_clks
.data
[0].clocks_in_khz
* memory_type_multiplier
, 1000);
962 dc
->bw_vbios
->mid_yclk
= bw_frc_to_fixed(
963 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
* memory_type_multiplier
,
965 dc
->bw_vbios
->high_yclk
= bw_frc_to_fixed(
966 mem_clks
.data
[mem_clks
.num_levels
-1].clocks_in_khz
* memory_type_multiplier
,
969 /* Now notify PPLib/SMU about which Watermarks sets they should select
970 * depending on DPM state they are in. And update BW MGR GFX Engine and
971 * Memory clock member variables for Watermarks calculations for each
974 clk_ranges
.num_wm_sets
= 4;
975 clk_ranges
.wm_clk_ranges
[0].wm_set_id
= WM_SET_A
;
976 clk_ranges
.wm_clk_ranges
[0].wm_min_eng_clk_in_khz
=
977 eng_clks
.data
[0].clocks_in_khz
;
978 clk_ranges
.wm_clk_ranges
[0].wm_max_eng_clk_in_khz
=
979 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
- 1;
980 clk_ranges
.wm_clk_ranges
[0].wm_min_mem_clk_in_khz
=
981 mem_clks
.data
[0].clocks_in_khz
;
982 clk_ranges
.wm_clk_ranges
[0].wm_max_mem_clk_in_khz
=
983 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
- 1;
985 clk_ranges
.wm_clk_ranges
[1].wm_set_id
= WM_SET_B
;
986 clk_ranges
.wm_clk_ranges
[1].wm_min_eng_clk_in_khz
=
987 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
;
988 /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
989 clk_ranges
.wm_clk_ranges
[1].wm_max_eng_clk_in_khz
= 5000000;
990 clk_ranges
.wm_clk_ranges
[1].wm_min_mem_clk_in_khz
=
991 mem_clks
.data
[0].clocks_in_khz
;
992 clk_ranges
.wm_clk_ranges
[1].wm_max_mem_clk_in_khz
=
993 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
- 1;
995 clk_ranges
.wm_clk_ranges
[2].wm_set_id
= WM_SET_C
;
996 clk_ranges
.wm_clk_ranges
[2].wm_min_eng_clk_in_khz
=
997 eng_clks
.data
[0].clocks_in_khz
;
998 clk_ranges
.wm_clk_ranges
[2].wm_max_eng_clk_in_khz
=
999 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
- 1;
1000 clk_ranges
.wm_clk_ranges
[2].wm_min_mem_clk_in_khz
=
1001 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
;
1002 /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1003 clk_ranges
.wm_clk_ranges
[2].wm_max_mem_clk_in_khz
= 5000000;
1005 clk_ranges
.wm_clk_ranges
[3].wm_set_id
= WM_SET_D
;
1006 clk_ranges
.wm_clk_ranges
[3].wm_min_eng_clk_in_khz
=
1007 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
;
1008 /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1009 clk_ranges
.wm_clk_ranges
[3].wm_max_eng_clk_in_khz
= 5000000;
1010 clk_ranges
.wm_clk_ranges
[3].wm_min_mem_clk_in_khz
=
1011 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
;
1012 /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1013 clk_ranges
.wm_clk_ranges
[3].wm_max_mem_clk_in_khz
= 5000000;
1015 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1016 dm_pp_notify_wm_clock_changes(dc
->ctx
, &clk_ranges
);
1019 static uint32_t read_pipe_fuses(struct dc_context
*ctx
)
1021 uint32_t value
= dm_read_reg_soc15(ctx
, mmCC_DC_PIPE_DIS
, 0);
1022 /* VG20 support max 6 pipes */
1023 value
= value
& 0x3f;
1027 static bool dce120_resource_construct(
1028 uint8_t num_virtual_links
,
1030 struct dce110_resource_pool
*pool
)
1034 struct dc_context
*ctx
= dc
->ctx
;
1035 struct irq_service_init_data irq_init_data
;
1036 static const struct resource_create_funcs
*res_funcs
;
1037 bool is_vg20
= ASICREV_IS_VEGA20_P(ctx
->asic_id
.hw_internal_rev
);
1038 uint32_t pipe_fuses
;
1040 ctx
->dc_bios
->regs
= &bios_regs
;
1042 pool
->base
.res_cap
= &res_cap
;
1043 pool
->base
.funcs
= &dce120_res_pool_funcs
;
1045 /* TODO: Fill more data from GreenlandAsicCapability.cpp */
1046 pool
->base
.pipe_count
= res_cap
.num_timing_generator
;
1047 pool
->base
.timing_generator_count
= pool
->base
.res_cap
->num_timing_generator
;
1048 pool
->base
.underlay_pipe_index
= NO_UNDERLAY_PIPE
;
1050 dc
->caps
.max_downscale_ratio
= 200;
1051 dc
->caps
.i2c_speed_in_khz
= 100;
1052 dc
->caps
.max_cursor_size
= 128;
1053 dc
->caps
.dual_link_dvi
= true;
1054 dc
->caps
.psp_setup_panel_mode
= true;
1055 dc
->caps
.extended_aux_timeout_support
= false;
1056 dc
->debug
= debug_defaults
;
1058 /*************************************************
1059 * Create resources *
1060 *************************************************/
1062 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL0
] =
1063 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1064 CLOCK_SOURCE_COMBO_PHY_PLL0
,
1065 &clk_src_regs
[0], false);
1066 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL1
] =
1067 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1068 CLOCK_SOURCE_COMBO_PHY_PLL1
,
1069 &clk_src_regs
[1], false);
1070 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL2
] =
1071 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1072 CLOCK_SOURCE_COMBO_PHY_PLL2
,
1073 &clk_src_regs
[2], false);
1074 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL3
] =
1075 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1076 CLOCK_SOURCE_COMBO_PHY_PLL3
,
1077 &clk_src_regs
[3], false);
1078 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL4
] =
1079 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1080 CLOCK_SOURCE_COMBO_PHY_PLL4
,
1081 &clk_src_regs
[4], false);
1082 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL5
] =
1083 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1084 CLOCK_SOURCE_COMBO_PHY_PLL5
,
1085 &clk_src_regs
[5], false);
1086 pool
->base
.clk_src_count
= DCE120_CLK_SRC_TOTAL
;
1088 pool
->base
.dp_clock_source
=
1089 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1090 CLOCK_SOURCE_ID_DP_DTO
,
1091 &clk_src_regs
[0], true);
1093 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
1094 if (pool
->base
.clock_sources
[i
] == NULL
) {
1095 dm_error("DC: failed to create clock sources!\n");
1096 BREAK_TO_DEBUGGER();
1097 goto clk_src_create_fail
;
1101 pool
->base
.dmcu
= dce_dmcu_create(ctx
,
1105 if (pool
->base
.dmcu
== NULL
) {
1106 dm_error("DC: failed to create dmcu!\n");
1107 BREAK_TO_DEBUGGER();
1108 goto res_create_fail
;
1111 pool
->base
.abm
= dce_abm_create(ctx
,
1115 if (pool
->base
.abm
== NULL
) {
1116 dm_error("DC: failed to create abm!\n");
1117 BREAK_TO_DEBUGGER();
1118 goto res_create_fail
;
1122 irq_init_data
.ctx
= dc
->ctx
;
1123 pool
->base
.irqs
= dal_irq_service_dce120_create(&irq_init_data
);
1124 if (!pool
->base
.irqs
)
1125 goto irqs_create_fail
;
1127 /* VG20: Pipe harvesting enabled, retrieve valid pipe fuses */
1129 pipe_fuses
= read_pipe_fuses(ctx
);
1131 /* index to valid pipe resource */
1133 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
1135 if ((pipe_fuses
& (1 << i
)) != 0) {
1136 dm_error("DC: skip invalid pipe %d!\n", i
);
1141 pool
->base
.timing_generators
[j
] =
1142 dce120_timing_generator_create(
1145 &dce120_tg_offsets
[i
]);
1146 if (pool
->base
.timing_generators
[j
] == NULL
) {
1147 BREAK_TO_DEBUGGER();
1148 dm_error("DC: failed to create tg!\n");
1149 goto controller_create_fail
;
1152 pool
->base
.mis
[j
] = dce120_mem_input_create(ctx
, i
);
1154 if (pool
->base
.mis
[j
] == NULL
) {
1155 BREAK_TO_DEBUGGER();
1157 "DC: failed to create memory input!\n");
1158 goto controller_create_fail
;
1161 pool
->base
.ipps
[j
] = dce120_ipp_create(ctx
, i
);
1162 if (pool
->base
.ipps
[i
] == NULL
) {
1163 BREAK_TO_DEBUGGER();
1165 "DC: failed to create input pixel processor!\n");
1166 goto controller_create_fail
;
1169 pool
->base
.transforms
[j
] = dce120_transform_create(ctx
, i
);
1170 if (pool
->base
.transforms
[i
] == NULL
) {
1171 BREAK_TO_DEBUGGER();
1173 "DC: failed to create transform!\n");
1174 goto res_create_fail
;
1177 pool
->base
.opps
[j
] = dce120_opp_create(
1180 if (pool
->base
.opps
[j
] == NULL
) {
1181 BREAK_TO_DEBUGGER();
1183 "DC: failed to create output pixel processor!\n");
1186 /* check next valid pipe */
1190 for (i
= 0; i
< pool
->base
.res_cap
->num_ddc
; i
++) {
1191 pool
->base
.engines
[i
] = dce120_aux_engine_create(ctx
, i
);
1192 if (pool
->base
.engines
[i
] == NULL
) {
1193 BREAK_TO_DEBUGGER();
1195 "DC:failed to create aux engine!!\n");
1196 goto res_create_fail
;
1198 pool
->base
.hw_i2cs
[i
] = dce120_i2c_hw_create(ctx
, i
);
1199 if (pool
->base
.hw_i2cs
[i
] == NULL
) {
1200 BREAK_TO_DEBUGGER();
1202 "DC:failed to create i2c engine!!\n");
1203 goto res_create_fail
;
1205 pool
->base
.sw_i2cs
[i
] = NULL
;
1208 /* valid pipe num */
1209 pool
->base
.pipe_count
= j
;
1210 pool
->base
.timing_generator_count
= j
;
1213 res_funcs
= &dce121_res_create_funcs
;
1215 res_funcs
= &res_create_funcs
;
1217 if (!resource_construct(num_virtual_links
, dc
, &pool
->base
, res_funcs
))
1218 goto res_create_fail
;
1220 /* Create hardware sequencer */
1221 if (!dce120_hw_sequencer_create(dc
))
1222 goto controller_create_fail
;
1224 dc
->caps
.max_planes
= pool
->base
.pipe_count
;
1226 for (i
= 0; i
< dc
->caps
.max_planes
; ++i
)
1227 dc
->caps
.planes
[i
] = plane_cap
;
1229 bw_calcs_init(dc
->bw_dceip
, dc
->bw_vbios
, dc
->ctx
->asic_id
);
1231 bw_calcs_data_update_from_pplib(dc
);
1236 controller_create_fail
:
1237 clk_src_create_fail
:
1240 dce120_resource_destruct(pool
);
1245 struct resource_pool
*dce120_create_resource_pool(
1246 uint8_t num_virtual_links
,
1249 struct dce110_resource_pool
*pool
=
1250 kzalloc(sizeof(struct dce110_resource_pool
), GFP_KERNEL
);
1255 if (dce120_resource_construct(num_virtual_links
, dc
, pool
))
1259 BREAK_TO_DEBUGGER();