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"
47 #include "dce/dce_panel_cntl.h"
49 #include "dce110/dce110_hw_sequencer.h"
50 #include "dce120/dce120_hw_sequencer.h"
51 #include "dce/dce_transform.h"
53 #include "dce/dce_audio.h"
54 #include "dce/dce_link_encoder.h"
55 #include "dce/dce_stream_encoder.h"
56 #include "dce/dce_hwseq.h"
57 #include "dce/dce_abm.h"
58 #include "dce/dce_dmcu.h"
59 #include "dce/dce_aux.h"
60 #include "dce/dce_i2c.h"
62 #include "dce/dce_12_0_offset.h"
63 #include "dce/dce_12_0_sh_mask.h"
64 #include "soc15_hw_ip.h"
65 #include "vega10_ip_offset.h"
66 #include "nbio/nbio_6_1_offset.h"
67 #include "mmhub/mmhub_1_0_offset.h"
68 #include "mmhub/mmhub_1_0_sh_mask.h"
69 #include "reg_helper.h"
71 #include "dce100/dce100_resource.h"
73 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
74 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
75 #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
76 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
77 #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
78 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
79 #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
80 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
81 #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
82 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
83 #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
84 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f
85 #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
86 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f
87 #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
90 enum dce120_clk_src_array_id
{
101 static const struct dce110_timing_generator_offsets dce120_tg_offsets
[] = {
103 .crtc
= (mmCRTC0_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
106 .crtc
= (mmCRTC1_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
109 .crtc
= (mmCRTC2_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
112 .crtc
= (mmCRTC3_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
115 .crtc
= (mmCRTC4_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
118 .crtc
= (mmCRTC5_CRTC_CONTROL
- mmCRTC0_CRTC_CONTROL
),
122 /* begin *********************
123 * macros to expend register list macro defined in HW object header file */
125 #define BASE_INNER(seg) \
126 DCE_BASE__INST0_SEG ## seg
128 #define NBIO_BASE_INNER(seg) \
129 NBIF_BASE__INST0_SEG ## seg
131 #define NBIO_BASE(seg) \
134 /* compile time expand base address. */
138 #define SR(reg_name)\
139 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
142 #define SRI(reg_name, block, id)\
143 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
144 mm ## block ## id ## _ ## reg_name
147 #define MMHUB_BASE_INNER(seg) \
148 MMHUB_BASE__INST0_SEG ## seg
150 #define MMHUB_BASE(seg) \
151 MMHUB_BASE_INNER(seg)
153 #define MMHUB_SR(reg_name)\
154 .reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) + \
157 /* macros to expend register list macro defined in HW object header file
158 * end *********************/
161 static const struct dce_dmcu_registers dmcu_regs
= {
162 DMCU_DCE110_COMMON_REG_LIST()
165 static const struct dce_dmcu_shift dmcu_shift
= {
166 DMCU_MASK_SH_LIST_DCE110(__SHIFT
)
169 static const struct dce_dmcu_mask dmcu_mask
= {
170 DMCU_MASK_SH_LIST_DCE110(_MASK
)
173 static const struct dce_abm_registers abm_regs
= {
174 ABM_DCE110_COMMON_REG_LIST()
177 static const struct dce_abm_shift abm_shift
= {
178 ABM_MASK_SH_LIST_DCE110(__SHIFT
)
181 static const struct dce_abm_mask abm_mask
= {
182 ABM_MASK_SH_LIST_DCE110(_MASK
)
185 #define ipp_regs(id)\
187 IPP_DCE110_REG_LIST_DCE_BASE(id)\
190 static const struct dce_ipp_registers ipp_regs
[] = {
199 static const struct dce_ipp_shift ipp_shift
= {
200 IPP_DCE120_MASK_SH_LIST_SOC_BASE(__SHIFT
)
203 static const struct dce_ipp_mask ipp_mask
= {
204 IPP_DCE120_MASK_SH_LIST_SOC_BASE(_MASK
)
207 #define transform_regs(id)\
209 XFM_COMMON_REG_LIST_DCE110(id)\
212 static const struct dce_transform_registers xfm_regs
[] = {
221 static const struct dce_transform_shift xfm_shift
= {
222 XFM_COMMON_MASK_SH_LIST_SOC_BASE(__SHIFT
)
225 static const struct dce_transform_mask xfm_mask
= {
226 XFM_COMMON_MASK_SH_LIST_SOC_BASE(_MASK
)
229 #define aux_regs(id)\
234 static const struct dce110_link_enc_aux_registers link_enc_aux_regs
[] = {
243 #define hpd_regs(id)\
248 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs
[] = {
257 #define link_regs(id)\
259 LE_DCE120_REG_LIST(id), \
260 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
263 static const struct dce110_link_enc_registers link_enc_regs
[] = {
274 #define stream_enc_regs(id)\
276 SE_COMMON_REG_LIST(id),\
280 static const struct dce110_stream_enc_registers stream_enc_regs
[] = {
289 static const struct dce_stream_encoder_shift se_shift
= {
290 SE_COMMON_MASK_SH_LIST_DCE120(__SHIFT
)
293 static const struct dce_stream_encoder_mask se_mask
= {
294 SE_COMMON_MASK_SH_LIST_DCE120(_MASK
)
297 static const struct dce_panel_cntl_registers panel_cntl_regs
[] = {
298 { DCE_PANEL_CNTL_REG_LIST() }
301 static const struct dce_panel_cntl_shift panel_cntl_shift
= {
302 DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT
)
305 static const struct dce_panel_cntl_mask panel_cntl_mask
= {
306 DCE_PANEL_CNTL_MASK_SH_LIST(_MASK
)
309 static const struct dce110_aux_registers_shift aux_shift
= {
310 DCE12_AUX_MASK_SH_LIST(__SHIFT
)
313 static const struct dce110_aux_registers_mask aux_mask
= {
314 DCE12_AUX_MASK_SH_LIST(_MASK
)
317 #define opp_regs(id)\
319 OPP_DCE_120_REG_LIST(id),\
322 static const struct dce_opp_registers opp_regs
[] = {
331 static const struct dce_opp_shift opp_shift
= {
332 OPP_COMMON_MASK_SH_LIST_DCE_120(__SHIFT
)
335 static const struct dce_opp_mask opp_mask
= {
336 OPP_COMMON_MASK_SH_LIST_DCE_120(_MASK
)
338 #define aux_engine_regs(id)\
340 AUX_COMMON_REG_LIST(id), \
341 .AUX_RESET_MASK = 0 \
344 static const struct dce110_aux_registers aux_engine_regs
[] = {
353 #define audio_regs(id)\
355 AUD_COMMON_REG_LIST(id)\
358 static const struct dce_audio_registers audio_regs
[] = {
367 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
368 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
369 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
370 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
372 static const struct dce_audio_shift audio_shift
= {
373 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT
)
376 static const struct dce_audio_mask audio_mask
= {
377 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK
)
380 static int map_transmitter_id_to_phy_instance(
381 enum transmitter transmitter
)
383 switch (transmitter
) {
384 case TRANSMITTER_UNIPHY_A
:
386 case TRANSMITTER_UNIPHY_B
:
388 case TRANSMITTER_UNIPHY_C
:
390 case TRANSMITTER_UNIPHY_D
:
392 case TRANSMITTER_UNIPHY_E
:
394 case TRANSMITTER_UNIPHY_F
:
396 case TRANSMITTER_UNIPHY_G
:
404 #define clk_src_regs(index, id)\
406 CS_COMMON_REG_LIST_DCE_112(id),\
409 static const struct dce110_clk_src_regs clk_src_regs
[] = {
418 static const struct dce110_clk_src_shift cs_shift
= {
419 CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT
)
422 static const struct dce110_clk_src_mask cs_mask
= {
423 CS_COMMON_MASK_SH_LIST_DCE_112(_MASK
)
426 struct output_pixel_processor
*dce120_opp_create(
427 struct dc_context
*ctx
,
430 struct dce110_opp
*opp
=
431 kzalloc(sizeof(struct dce110_opp
), GFP_KERNEL
);
436 dce110_opp_construct(opp
,
437 ctx
, inst
, &opp_regs
[inst
], &opp_shift
, &opp_mask
);
440 struct dce_aux
*dce120_aux_engine_create(
441 struct dc_context
*ctx
,
444 struct aux_engine_dce110
*aux_engine
=
445 kzalloc(sizeof(struct aux_engine_dce110
), GFP_KERNEL
);
450 dce110_aux_engine_construct(aux_engine
, ctx
, inst
,
451 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER
* AUX_TIMEOUT_PERIOD
,
452 &aux_engine_regs
[inst
],
455 ctx
->dc
->caps
.extended_aux_timeout_support
);
457 return &aux_engine
->base
;
459 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
461 static const struct dce_i2c_registers i2c_hw_regs
[] = {
470 static const struct dce_i2c_shift i2c_shifts
= {
471 I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT
)
474 static const struct dce_i2c_mask i2c_masks
= {
475 I2C_COMMON_MASK_SH_LIST_DCE110(_MASK
)
478 struct dce_i2c_hw
*dce120_i2c_hw_create(
479 struct dc_context
*ctx
,
482 struct dce_i2c_hw
*dce_i2c_hw
=
483 kzalloc(sizeof(struct dce_i2c_hw
), GFP_KERNEL
);
488 dce112_i2c_hw_construct(dce_i2c_hw
, ctx
, inst
,
489 &i2c_hw_regs
[inst
], &i2c_shifts
, &i2c_masks
);
493 static const struct bios_registers bios_regs
= {
494 .BIOS_SCRATCH_3
= mmBIOS_SCRATCH_3
+ NBIO_BASE(mmBIOS_SCRATCH_3_BASE_IDX
),
495 .BIOS_SCRATCH_6
= mmBIOS_SCRATCH_6
+ NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX
)
498 static const struct resource_caps res_cap
= {
499 .num_timing_generator
= 6,
501 .num_stream_encoder
= 6,
506 static const struct dc_plane_cap plane_cap
= {
507 .type
= DC_PLANE_TYPE_DCE_RGB
,
509 .pixel_format_support
= {
515 .max_upscale_factor
= {
521 .max_downscale_factor
= {
528 static const struct dc_debug_options debug_defaults
= {
529 .disable_clock_gate
= true,
532 static struct clock_source
*dce120_clock_source_create(
533 struct dc_context
*ctx
,
534 struct dc_bios
*bios
,
535 enum clock_source_id id
,
536 const struct dce110_clk_src_regs
*regs
,
539 struct dce110_clk_src
*clk_src
=
540 kzalloc(sizeof(*clk_src
), GFP_KERNEL
);
545 if (dce112_clk_src_construct(clk_src
, ctx
, bios
, id
,
546 regs
, &cs_shift
, &cs_mask
)) {
547 clk_src
->base
.dp_clk_src
= dp_clk_src
;
548 return &clk_src
->base
;
556 static void dce120_clock_source_destroy(struct clock_source
**clk_src
)
558 kfree(TO_DCE110_CLK_SRC(*clk_src
));
563 static bool dce120_hw_sequencer_create(struct dc
*dc
)
565 /* All registers used by dce11.2 match those in dce11 in offset and
568 dce120_hw_sequencer_construct(dc
);
570 /*TODO Move to separate file and Override what is needed */
575 static struct timing_generator
*dce120_timing_generator_create(
576 struct dc_context
*ctx
,
578 const struct dce110_timing_generator_offsets
*offsets
)
580 struct dce110_timing_generator
*tg110
=
581 kzalloc(sizeof(struct dce110_timing_generator
), GFP_KERNEL
);
586 dce120_timing_generator_construct(tg110
, ctx
, instance
, offsets
);
590 static void dce120_transform_destroy(struct transform
**xfm
)
592 kfree(TO_DCE_TRANSFORM(*xfm
));
596 static void dce120_resource_destruct(struct dce110_resource_pool
*pool
)
600 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
601 if (pool
->base
.opps
[i
] != NULL
)
602 dce110_opp_destroy(&pool
->base
.opps
[i
]);
604 if (pool
->base
.transforms
[i
] != NULL
)
605 dce120_transform_destroy(&pool
->base
.transforms
[i
]);
607 if (pool
->base
.ipps
[i
] != NULL
)
608 dce_ipp_destroy(&pool
->base
.ipps
[i
]);
610 if (pool
->base
.mis
[i
] != NULL
) {
611 kfree(TO_DCE_MEM_INPUT(pool
->base
.mis
[i
]));
612 pool
->base
.mis
[i
] = NULL
;
615 if (pool
->base
.irqs
!= NULL
) {
616 dal_irq_service_destroy(&pool
->base
.irqs
);
619 if (pool
->base
.timing_generators
[i
] != NULL
) {
620 kfree(DCE110TG_FROM_TG(pool
->base
.timing_generators
[i
]));
621 pool
->base
.timing_generators
[i
] = NULL
;
625 for (i
= 0; i
< pool
->base
.res_cap
->num_ddc
; i
++) {
626 if (pool
->base
.engines
[i
] != NULL
)
627 dce110_engine_destroy(&pool
->base
.engines
[i
]);
628 if (pool
->base
.hw_i2cs
[i
] != NULL
) {
629 kfree(pool
->base
.hw_i2cs
[i
]);
630 pool
->base
.hw_i2cs
[i
] = NULL
;
632 if (pool
->base
.sw_i2cs
[i
] != NULL
) {
633 kfree(pool
->base
.sw_i2cs
[i
]);
634 pool
->base
.sw_i2cs
[i
] = NULL
;
638 for (i
= 0; i
< pool
->base
.audio_count
; i
++) {
639 if (pool
->base
.audios
[i
])
640 dce_aud_destroy(&pool
->base
.audios
[i
]);
643 for (i
= 0; i
< pool
->base
.stream_enc_count
; i
++) {
644 if (pool
->base
.stream_enc
[i
] != NULL
)
645 kfree(DCE110STRENC_FROM_STRENC(pool
->base
.stream_enc
[i
]));
648 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
649 if (pool
->base
.clock_sources
[i
] != NULL
)
650 dce120_clock_source_destroy(
651 &pool
->base
.clock_sources
[i
]);
654 if (pool
->base
.dp_clock_source
!= NULL
)
655 dce120_clock_source_destroy(&pool
->base
.dp_clock_source
);
657 if (pool
->base
.abm
!= NULL
)
658 dce_abm_destroy(&pool
->base
.abm
);
660 if (pool
->base
.dmcu
!= NULL
)
661 dce_dmcu_destroy(&pool
->base
.dmcu
);
664 static void read_dce_straps(
665 struct dc_context
*ctx
,
666 struct resource_straps
*straps
)
668 uint32_t reg_val
= dm_read_reg_soc15(ctx
, mmCC_DC_MISC_STRAPS
, 0);
670 straps
->audio_stream_number
= get_reg_field_value(reg_val
,
672 AUDIO_STREAM_NUMBER
);
673 straps
->hdmi_disable
= get_reg_field_value(reg_val
,
677 reg_val
= dm_read_reg_soc15(ctx
, mmDC_PINSTRAPS
, 0);
678 straps
->dc_pinstraps_audio
= get_reg_field_value(reg_val
,
683 static struct audio
*create_audio(
684 struct dc_context
*ctx
, unsigned int inst
)
686 return dce_audio_create(ctx
, inst
,
687 &audio_regs
[inst
], &audio_shift
, &audio_mask
);
690 static const struct encoder_feature_support link_enc_feature
= {
691 .max_hdmi_deep_color
= COLOR_DEPTH_121212
,
692 .max_hdmi_pixel_clock
= 600000,
693 .hdmi_ycbcr420_supported
= true,
694 .dp_ycbcr420_supported
= false,
695 .flags
.bits
.IS_HBR2_CAPABLE
= true,
696 .flags
.bits
.IS_HBR3_CAPABLE
= true,
697 .flags
.bits
.IS_TPS3_CAPABLE
= true,
698 .flags
.bits
.IS_TPS4_CAPABLE
= true,
701 static struct link_encoder
*dce120_link_encoder_create(
702 const struct encoder_init_data
*enc_init_data
)
704 struct dce110_link_encoder
*enc110
=
705 kzalloc(sizeof(struct dce110_link_encoder
), GFP_KERNEL
);
712 map_transmitter_id_to_phy_instance(enc_init_data
->transmitter
);
714 dce110_link_encoder_construct(enc110
,
717 &link_enc_regs
[link_regs_id
],
718 &link_enc_aux_regs
[enc_init_data
->channel
- 1],
719 &link_enc_hpd_regs
[enc_init_data
->hpd_source
]);
721 return &enc110
->base
;
724 static struct panel_cntl
*dce120_panel_cntl_create(const struct panel_cntl_init_data
*init_data
)
726 struct dce_panel_cntl
*panel_cntl
=
727 kzalloc(sizeof(struct dce_panel_cntl
), GFP_KERNEL
);
732 dce_panel_cntl_construct(panel_cntl
,
734 &panel_cntl_regs
[init_data
->inst
],
738 return &panel_cntl
->base
;
741 static struct input_pixel_processor
*dce120_ipp_create(
742 struct dc_context
*ctx
, uint32_t inst
)
744 struct dce_ipp
*ipp
= kzalloc(sizeof(struct dce_ipp
), GFP_KERNEL
);
751 dce_ipp_construct(ipp
, ctx
, inst
,
752 &ipp_regs
[inst
], &ipp_shift
, &ipp_mask
);
756 static struct stream_encoder
*dce120_stream_encoder_create(
757 enum engine_id eng_id
,
758 struct dc_context
*ctx
)
760 struct dce110_stream_encoder
*enc110
=
761 kzalloc(sizeof(struct dce110_stream_encoder
), GFP_KERNEL
);
766 dce110_stream_encoder_construct(enc110
, ctx
, ctx
->dc_bios
, eng_id
,
767 &stream_enc_regs
[eng_id
],
768 &se_shift
, &se_mask
);
769 return &enc110
->base
;
772 #define SRII(reg_name, block, id)\
773 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
774 mm ## block ## id ## _ ## reg_name
776 static const struct dce_hwseq_registers hwseq_reg
= {
777 HWSEQ_DCE120_REG_LIST()
780 static const struct dce_hwseq_shift hwseq_shift
= {
781 HWSEQ_DCE12_MASK_SH_LIST(__SHIFT
)
784 static const struct dce_hwseq_mask hwseq_mask
= {
785 HWSEQ_DCE12_MASK_SH_LIST(_MASK
)
788 /* HWSEQ regs for VG20 */
789 static const struct dce_hwseq_registers dce121_hwseq_reg
= {
790 HWSEQ_VG20_REG_LIST()
793 static const struct dce_hwseq_shift dce121_hwseq_shift
= {
794 HWSEQ_VG20_MASK_SH_LIST(__SHIFT
)
797 static const struct dce_hwseq_mask dce121_hwseq_mask
= {
798 HWSEQ_VG20_MASK_SH_LIST(_MASK
)
801 static struct dce_hwseq
*dce120_hwseq_create(
802 struct dc_context
*ctx
)
804 struct dce_hwseq
*hws
= kzalloc(sizeof(struct dce_hwseq
), GFP_KERNEL
);
808 hws
->regs
= &hwseq_reg
;
809 hws
->shifts
= &hwseq_shift
;
810 hws
->masks
= &hwseq_mask
;
815 static struct dce_hwseq
*dce121_hwseq_create(
816 struct dc_context
*ctx
)
818 struct dce_hwseq
*hws
= kzalloc(sizeof(struct dce_hwseq
), GFP_KERNEL
);
822 hws
->regs
= &dce121_hwseq_reg
;
823 hws
->shifts
= &dce121_hwseq_shift
;
824 hws
->masks
= &dce121_hwseq_mask
;
829 static const struct resource_create_funcs res_create_funcs
= {
830 .read_dce_straps
= read_dce_straps
,
831 .create_audio
= create_audio
,
832 .create_stream_encoder
= dce120_stream_encoder_create
,
833 .create_hwseq
= dce120_hwseq_create
,
836 static const struct resource_create_funcs dce121_res_create_funcs
= {
837 .read_dce_straps
= read_dce_straps
,
838 .create_audio
= create_audio
,
839 .create_stream_encoder
= dce120_stream_encoder_create
,
840 .create_hwseq
= dce121_hwseq_create
,
844 #define mi_inst_regs(id) { MI_DCE12_REG_LIST(id) }
845 static const struct dce_mem_input_registers mi_regs
[] = {
854 static const struct dce_mem_input_shift mi_shifts
= {
855 MI_DCE12_MASK_SH_LIST(__SHIFT
)
858 static const struct dce_mem_input_mask mi_masks
= {
859 MI_DCE12_MASK_SH_LIST(_MASK
)
862 static struct mem_input
*dce120_mem_input_create(
863 struct dc_context
*ctx
,
866 struct dce_mem_input
*dce_mi
= kzalloc(sizeof(struct dce_mem_input
),
874 dce120_mem_input_construct(dce_mi
, ctx
, inst
, &mi_regs
[inst
], &mi_shifts
, &mi_masks
);
875 return &dce_mi
->base
;
878 static struct transform
*dce120_transform_create(
879 struct dc_context
*ctx
,
882 struct dce_transform
*transform
=
883 kzalloc(sizeof(struct dce_transform
), GFP_KERNEL
);
888 dce_transform_construct(transform
, ctx
, inst
,
889 &xfm_regs
[inst
], &xfm_shift
, &xfm_mask
);
890 transform
->lb_memory_size
= 0x1404; /*5124*/
891 return &transform
->base
;
894 static void dce120_destroy_resource_pool(struct resource_pool
**pool
)
896 struct dce110_resource_pool
*dce110_pool
= TO_DCE110_RES_POOL(*pool
);
898 dce120_resource_destruct(dce110_pool
);
903 static const struct resource_funcs dce120_res_pool_funcs
= {
904 .destroy
= dce120_destroy_resource_pool
,
905 .link_enc_create
= dce120_link_encoder_create
,
906 .panel_cntl_create
= dce120_panel_cntl_create
,
907 .validate_bandwidth
= dce112_validate_bandwidth
,
908 .validate_plane
= dce100_validate_plane
,
909 .add_stream_to_ctx
= dce112_add_stream_to_ctx
,
910 .find_first_free_match_stream_enc_for_link
= dce110_find_first_free_match_stream_enc_for_link
913 static void bw_calcs_data_update_from_pplib(struct dc
*dc
)
915 struct dm_pp_clock_levels_with_latency eng_clks
= {0};
916 struct dm_pp_clock_levels_with_latency mem_clks
= {0};
917 struct dm_pp_wm_sets_with_clock_ranges clk_ranges
= {0};
920 unsigned int latency
;
921 /*original logic in dal3*/
922 int memory_type_multiplier
= MEMORY_TYPE_MULTIPLIER_CZ
;
925 if (!dm_pp_get_clock_levels_by_type_with_latency(
927 DM_PP_CLOCK_TYPE_ENGINE_CLK
,
928 &eng_clks
) || eng_clks
.num_levels
== 0) {
930 eng_clks
.num_levels
= 8;
933 for (i
= 0; i
< eng_clks
.num_levels
; i
++) {
934 eng_clks
.data
[i
].clocks_in_khz
= clk
;
939 /* convert all the clock fro kHz to fix point mHz TODO: wloop data */
940 dc
->bw_vbios
->high_sclk
= bw_frc_to_fixed(
941 eng_clks
.data
[eng_clks
.num_levels
-1].clocks_in_khz
, 1000);
942 dc
->bw_vbios
->mid1_sclk
= bw_frc_to_fixed(
943 eng_clks
.data
[eng_clks
.num_levels
/8].clocks_in_khz
, 1000);
944 dc
->bw_vbios
->mid2_sclk
= bw_frc_to_fixed(
945 eng_clks
.data
[eng_clks
.num_levels
*2/8].clocks_in_khz
, 1000);
946 dc
->bw_vbios
->mid3_sclk
= bw_frc_to_fixed(
947 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
, 1000);
948 dc
->bw_vbios
->mid4_sclk
= bw_frc_to_fixed(
949 eng_clks
.data
[eng_clks
.num_levels
*4/8].clocks_in_khz
, 1000);
950 dc
->bw_vbios
->mid5_sclk
= bw_frc_to_fixed(
951 eng_clks
.data
[eng_clks
.num_levels
*5/8].clocks_in_khz
, 1000);
952 dc
->bw_vbios
->mid6_sclk
= bw_frc_to_fixed(
953 eng_clks
.data
[eng_clks
.num_levels
*6/8].clocks_in_khz
, 1000);
954 dc
->bw_vbios
->low_sclk
= bw_frc_to_fixed(
955 eng_clks
.data
[0].clocks_in_khz
, 1000);
958 if (!dm_pp_get_clock_levels_by_type_with_latency(
960 DM_PP_CLOCK_TYPE_MEMORY_CLK
,
961 &mem_clks
) || mem_clks
.num_levels
== 0) {
963 mem_clks
.num_levels
= 3;
967 for (i
= 0; i
< eng_clks
.num_levels
; i
++) {
968 mem_clks
.data
[i
].clocks_in_khz
= clk
;
969 mem_clks
.data
[i
].latency_in_us
= latency
;
976 /* we don't need to call PPLIB for validation clock since they
977 * also give us the highest sclk and highest mclk (UMA clock).
978 * ALSO always convert UMA clock (from PPLIB) to YCLK (HW formula):
979 * YCLK = UMACLK*m_memoryTypeMultiplier
981 if (dc
->bw_vbios
->memory_type
== bw_def_hbm
)
982 memory_type_multiplier
= MEMORY_TYPE_HBM
;
984 dc
->bw_vbios
->low_yclk
= bw_frc_to_fixed(
985 mem_clks
.data
[0].clocks_in_khz
* memory_type_multiplier
, 1000);
986 dc
->bw_vbios
->mid_yclk
= bw_frc_to_fixed(
987 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
* memory_type_multiplier
,
989 dc
->bw_vbios
->high_yclk
= bw_frc_to_fixed(
990 mem_clks
.data
[mem_clks
.num_levels
-1].clocks_in_khz
* memory_type_multiplier
,
993 /* Now notify PPLib/SMU about which Watermarks sets they should select
994 * depending on DPM state they are in. And update BW MGR GFX Engine and
995 * Memory clock member variables for Watermarks calculations for each
998 clk_ranges
.num_wm_sets
= 4;
999 clk_ranges
.wm_clk_ranges
[0].wm_set_id
= WM_SET_A
;
1000 clk_ranges
.wm_clk_ranges
[0].wm_min_eng_clk_in_khz
=
1001 eng_clks
.data
[0].clocks_in_khz
;
1002 clk_ranges
.wm_clk_ranges
[0].wm_max_eng_clk_in_khz
=
1003 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
- 1;
1004 clk_ranges
.wm_clk_ranges
[0].wm_min_mem_clk_in_khz
=
1005 mem_clks
.data
[0].clocks_in_khz
;
1006 clk_ranges
.wm_clk_ranges
[0].wm_max_mem_clk_in_khz
=
1007 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
- 1;
1009 clk_ranges
.wm_clk_ranges
[1].wm_set_id
= WM_SET_B
;
1010 clk_ranges
.wm_clk_ranges
[1].wm_min_eng_clk_in_khz
=
1011 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
;
1012 /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1013 clk_ranges
.wm_clk_ranges
[1].wm_max_eng_clk_in_khz
= 5000000;
1014 clk_ranges
.wm_clk_ranges
[1].wm_min_mem_clk_in_khz
=
1015 mem_clks
.data
[0].clocks_in_khz
;
1016 clk_ranges
.wm_clk_ranges
[1].wm_max_mem_clk_in_khz
=
1017 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
- 1;
1019 clk_ranges
.wm_clk_ranges
[2].wm_set_id
= WM_SET_C
;
1020 clk_ranges
.wm_clk_ranges
[2].wm_min_eng_clk_in_khz
=
1021 eng_clks
.data
[0].clocks_in_khz
;
1022 clk_ranges
.wm_clk_ranges
[2].wm_max_eng_clk_in_khz
=
1023 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
- 1;
1024 clk_ranges
.wm_clk_ranges
[2].wm_min_mem_clk_in_khz
=
1025 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
;
1026 /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1027 clk_ranges
.wm_clk_ranges
[2].wm_max_mem_clk_in_khz
= 5000000;
1029 clk_ranges
.wm_clk_ranges
[3].wm_set_id
= WM_SET_D
;
1030 clk_ranges
.wm_clk_ranges
[3].wm_min_eng_clk_in_khz
=
1031 eng_clks
.data
[eng_clks
.num_levels
*3/8].clocks_in_khz
;
1032 /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1033 clk_ranges
.wm_clk_ranges
[3].wm_max_eng_clk_in_khz
= 5000000;
1034 clk_ranges
.wm_clk_ranges
[3].wm_min_mem_clk_in_khz
=
1035 mem_clks
.data
[mem_clks
.num_levels
>>1].clocks_in_khz
;
1036 /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1037 clk_ranges
.wm_clk_ranges
[3].wm_max_mem_clk_in_khz
= 5000000;
1039 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1040 dm_pp_notify_wm_clock_changes(dc
->ctx
, &clk_ranges
);
1043 static uint32_t read_pipe_fuses(struct dc_context
*ctx
)
1045 uint32_t value
= dm_read_reg_soc15(ctx
, mmCC_DC_PIPE_DIS
, 0);
1046 /* VG20 support max 6 pipes */
1047 value
= value
& 0x3f;
1051 static bool dce120_resource_construct(
1052 uint8_t num_virtual_links
,
1054 struct dce110_resource_pool
*pool
)
1058 struct dc_context
*ctx
= dc
->ctx
;
1059 struct irq_service_init_data irq_init_data
;
1060 static const struct resource_create_funcs
*res_funcs
;
1061 bool is_vg20
= ASICREV_IS_VEGA20_P(ctx
->asic_id
.hw_internal_rev
);
1062 uint32_t pipe_fuses
;
1064 ctx
->dc_bios
->regs
= &bios_regs
;
1066 pool
->base
.res_cap
= &res_cap
;
1067 pool
->base
.funcs
= &dce120_res_pool_funcs
;
1069 /* TODO: Fill more data from GreenlandAsicCapability.cpp */
1070 pool
->base
.pipe_count
= res_cap
.num_timing_generator
;
1071 pool
->base
.timing_generator_count
= pool
->base
.res_cap
->num_timing_generator
;
1072 pool
->base
.underlay_pipe_index
= NO_UNDERLAY_PIPE
;
1074 dc
->caps
.max_downscale_ratio
= 200;
1075 dc
->caps
.i2c_speed_in_khz
= 100;
1076 dc
->caps
.i2c_speed_in_khz_hdcp
= 100; /*1.4 w/a not applied by default*/
1077 dc
->caps
.max_cursor_size
= 128;
1078 dc
->caps
.min_horizontal_blanking_period
= 80;
1079 dc
->caps
.dual_link_dvi
= true;
1080 dc
->caps
.psp_setup_panel_mode
= true;
1081 dc
->caps
.extended_aux_timeout_support
= false;
1082 dc
->debug
= debug_defaults
;
1084 /*************************************************
1085 * Create resources *
1086 *************************************************/
1088 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL0
] =
1089 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1090 CLOCK_SOURCE_COMBO_PHY_PLL0
,
1091 &clk_src_regs
[0], false);
1092 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL1
] =
1093 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1094 CLOCK_SOURCE_COMBO_PHY_PLL1
,
1095 &clk_src_regs
[1], false);
1096 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL2
] =
1097 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1098 CLOCK_SOURCE_COMBO_PHY_PLL2
,
1099 &clk_src_regs
[2], false);
1100 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL3
] =
1101 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1102 CLOCK_SOURCE_COMBO_PHY_PLL3
,
1103 &clk_src_regs
[3], false);
1104 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL4
] =
1105 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1106 CLOCK_SOURCE_COMBO_PHY_PLL4
,
1107 &clk_src_regs
[4], false);
1108 pool
->base
.clock_sources
[DCE120_CLK_SRC_PLL5
] =
1109 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1110 CLOCK_SOURCE_COMBO_PHY_PLL5
,
1111 &clk_src_regs
[5], false);
1112 pool
->base
.clk_src_count
= DCE120_CLK_SRC_TOTAL
;
1114 pool
->base
.dp_clock_source
=
1115 dce120_clock_source_create(ctx
, ctx
->dc_bios
,
1116 CLOCK_SOURCE_ID_DP_DTO
,
1117 &clk_src_regs
[0], true);
1119 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
1120 if (pool
->base
.clock_sources
[i
] == NULL
) {
1121 dm_error("DC: failed to create clock sources!\n");
1122 BREAK_TO_DEBUGGER();
1123 goto clk_src_create_fail
;
1127 pool
->base
.dmcu
= dce_dmcu_create(ctx
,
1131 if (pool
->base
.dmcu
== NULL
) {
1132 dm_error("DC: failed to create dmcu!\n");
1133 BREAK_TO_DEBUGGER();
1134 goto res_create_fail
;
1137 pool
->base
.abm
= dce_abm_create(ctx
,
1141 if (pool
->base
.abm
== NULL
) {
1142 dm_error("DC: failed to create abm!\n");
1143 BREAK_TO_DEBUGGER();
1144 goto res_create_fail
;
1148 irq_init_data
.ctx
= dc
->ctx
;
1149 pool
->base
.irqs
= dal_irq_service_dce120_create(&irq_init_data
);
1150 if (!pool
->base
.irqs
)
1151 goto irqs_create_fail
;
1153 /* VG20: Pipe harvesting enabled, retrieve valid pipe fuses */
1155 pipe_fuses
= read_pipe_fuses(ctx
);
1157 /* index to valid pipe resource */
1159 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
1161 if ((pipe_fuses
& (1 << i
)) != 0) {
1162 dm_error("DC: skip invalid pipe %d!\n", i
);
1167 pool
->base
.timing_generators
[j
] =
1168 dce120_timing_generator_create(
1171 &dce120_tg_offsets
[i
]);
1172 if (pool
->base
.timing_generators
[j
] == NULL
) {
1173 BREAK_TO_DEBUGGER();
1174 dm_error("DC: failed to create tg!\n");
1175 goto controller_create_fail
;
1178 pool
->base
.mis
[j
] = dce120_mem_input_create(ctx
, i
);
1180 if (pool
->base
.mis
[j
] == NULL
) {
1181 BREAK_TO_DEBUGGER();
1183 "DC: failed to create memory input!\n");
1184 goto controller_create_fail
;
1187 pool
->base
.ipps
[j
] = dce120_ipp_create(ctx
, i
);
1188 if (pool
->base
.ipps
[i
] == NULL
) {
1189 BREAK_TO_DEBUGGER();
1191 "DC: failed to create input pixel processor!\n");
1192 goto controller_create_fail
;
1195 pool
->base
.transforms
[j
] = dce120_transform_create(ctx
, i
);
1196 if (pool
->base
.transforms
[i
] == NULL
) {
1197 BREAK_TO_DEBUGGER();
1199 "DC: failed to create transform!\n");
1200 goto res_create_fail
;
1203 pool
->base
.opps
[j
] = dce120_opp_create(
1206 if (pool
->base
.opps
[j
] == NULL
) {
1207 BREAK_TO_DEBUGGER();
1209 "DC: failed to create output pixel processor!\n");
1212 /* check next valid pipe */
1216 for (i
= 0; i
< pool
->base
.res_cap
->num_ddc
; i
++) {
1217 pool
->base
.engines
[i
] = dce120_aux_engine_create(ctx
, i
);
1218 if (pool
->base
.engines
[i
] == NULL
) {
1219 BREAK_TO_DEBUGGER();
1221 "DC:failed to create aux engine!!\n");
1222 goto res_create_fail
;
1224 pool
->base
.hw_i2cs
[i
] = dce120_i2c_hw_create(ctx
, i
);
1225 if (pool
->base
.hw_i2cs
[i
] == NULL
) {
1226 BREAK_TO_DEBUGGER();
1228 "DC:failed to create i2c engine!!\n");
1229 goto res_create_fail
;
1231 pool
->base
.sw_i2cs
[i
] = NULL
;
1234 /* valid pipe num */
1235 pool
->base
.pipe_count
= j
;
1236 pool
->base
.timing_generator_count
= j
;
1239 res_funcs
= &dce121_res_create_funcs
;
1241 res_funcs
= &res_create_funcs
;
1243 if (!resource_construct(num_virtual_links
, dc
, &pool
->base
, res_funcs
))
1244 goto res_create_fail
;
1246 /* Create hardware sequencer */
1247 if (!dce120_hw_sequencer_create(dc
))
1248 goto controller_create_fail
;
1250 dc
->caps
.max_planes
= pool
->base
.pipe_count
;
1252 for (i
= 0; i
< dc
->caps
.max_planes
; ++i
)
1253 dc
->caps
.planes
[i
] = plane_cap
;
1255 bw_calcs_init(dc
->bw_dceip
, dc
->bw_vbios
, dc
->ctx
->asic_id
);
1257 bw_calcs_data_update_from_pplib(dc
);
1262 controller_create_fail
:
1263 clk_src_create_fail
:
1266 dce120_resource_destruct(pool
);
1271 struct resource_pool
*dce120_create_resource_pool(
1272 uint8_t num_virtual_links
,
1275 struct dce110_resource_pool
*pool
=
1276 kzalloc(sizeof(struct dce110_resource_pool
), GFP_KERNEL
);
1281 if (dce120_resource_construct(num_virtual_links
, dc
, pool
))
1285 BREAK_TO_DEBUGGER();