2 * Copyright 2012-15 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"
28 #include "link_encoder.h"
29 #include "stream_encoder.h"
32 #include "dce110/dce110_resource.h"
34 #include "include/irq_service_interface.h"
35 #include "dce/dce_audio.h"
36 #include "dce110/dce110_timing_generator.h"
37 #include "irq/dce110/irq_service_dce110.h"
38 #include "dce110/dce110_timing_generator_v.h"
39 #include "dce/dce_link_encoder.h"
40 #include "dce/dce_stream_encoder.h"
41 #include "dce110/dce110_mem_input.h"
42 #include "dce110/dce110_mem_input_v.h"
43 #include "dce110/dce110_ipp.h"
44 #include "dce/dce_transform.h"
45 #include "dce110/dce110_transform_v.h"
46 #include "dce110/dce110_opp.h"
47 #include "dce110/dce110_opp_v.h"
48 #include "dce/dce_clock_source.h"
49 #include "dce/dce_hwseq.h"
50 #include "dce110/dce110_hw_sequencer.h"
52 #include "reg_helper.h"
54 #include "dce/dce_11_0_d.h"
55 #include "dce/dce_11_0_sh_mask.h"
57 #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
58 #include "gmc/gmc_8_2_d.h"
59 #include "gmc/gmc_8_2_sh_mask.h"
62 #ifndef mmDP_DPHY_INTERNAL_CTRL
63 #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
64 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
65 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
66 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
67 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
68 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
69 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
70 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
71 #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
72 #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
75 #ifndef mmBIOS_SCRATCH_2
76 #define mmBIOS_SCRATCH_2 0x05CB
77 #define mmBIOS_SCRATCH_6 0x05CF
80 #ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
81 #define mmDP_DPHY_BS_SR_SWAP_CNTL 0x4ADC
82 #define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL 0x4ADC
83 #define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL 0x4BDC
84 #define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL 0x4CDC
85 #define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL 0x4DDC
86 #define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL 0x4EDC
87 #define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL 0x4FDC
88 #define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL 0x54DC
91 #ifndef mmDP_DPHY_FAST_TRAINING
92 #define mmDP_DPHY_FAST_TRAINING 0x4ABC
93 #define mmDP0_DP_DPHY_FAST_TRAINING 0x4ABC
94 #define mmDP1_DP_DPHY_FAST_TRAINING 0x4BBC
95 #define mmDP2_DP_DPHY_FAST_TRAINING 0x4CBC
96 #define mmDP3_DP_DPHY_FAST_TRAINING 0x4DBC
97 #define mmDP4_DP_DPHY_FAST_TRAINING 0x4EBC
98 #define mmDP5_DP_DPHY_FAST_TRAINING 0x4FBC
99 #define mmDP6_DP_DPHY_FAST_TRAINING 0x54BC
102 #ifndef DPHY_RX_FAST_TRAINING_CAPABLE
103 #define DPHY_RX_FAST_TRAINING_CAPABLE 0x1
106 static const struct dce110_timing_generator_offsets dce110_tg_offsets
[] = {
108 .crtc
= (mmCRTC0_CRTC_CONTROL
- mmCRTC_CONTROL
),
109 .dcp
= (mmDCP0_GRPH_CONTROL
- mmGRPH_CONTROL
),
112 .crtc
= (mmCRTC1_CRTC_CONTROL
- mmCRTC_CONTROL
),
113 .dcp
= (mmDCP1_GRPH_CONTROL
- mmGRPH_CONTROL
),
116 .crtc
= (mmCRTC2_CRTC_CONTROL
- mmCRTC_CONTROL
),
117 .dcp
= (mmDCP2_GRPH_CONTROL
- mmGRPH_CONTROL
),
120 .crtc
= (mmCRTC3_CRTC_CONTROL
- mmCRTC_CONTROL
),
121 .dcp
= (mmDCP3_GRPH_CONTROL
- mmGRPH_CONTROL
),
124 .crtc
= (mmCRTC4_CRTC_CONTROL
- mmCRTC_CONTROL
),
125 .dcp
= (mmDCP4_GRPH_CONTROL
- mmGRPH_CONTROL
),
128 .crtc
= (mmCRTC5_CRTC_CONTROL
- mmCRTC_CONTROL
),
129 .dcp
= (mmDCP5_GRPH_CONTROL
- mmGRPH_CONTROL
),
133 static const struct dce110_mem_input_reg_offsets dce110_mi_reg_offsets
[] = {
135 .dcp
= (mmDCP0_GRPH_CONTROL
- mmGRPH_CONTROL
),
136 .dmif
= (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL
137 - mmDPG_WATERMARK_MASK_CONTROL
),
138 .pipe
= (mmPIPE0_DMIF_BUFFER_CONTROL
139 - mmPIPE0_DMIF_BUFFER_CONTROL
),
142 .dcp
= (mmDCP1_GRPH_CONTROL
- mmGRPH_CONTROL
),
143 .dmif
= (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
144 - mmDPG_WATERMARK_MASK_CONTROL
),
145 .pipe
= (mmPIPE1_DMIF_BUFFER_CONTROL
146 - mmPIPE0_DMIF_BUFFER_CONTROL
),
149 .dcp
= (mmDCP2_GRPH_CONTROL
- mmGRPH_CONTROL
),
150 .dmif
= (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
151 - mmDPG_WATERMARK_MASK_CONTROL
),
152 .pipe
= (mmPIPE2_DMIF_BUFFER_CONTROL
153 - mmPIPE0_DMIF_BUFFER_CONTROL
),
158 static const struct dce110_ipp_reg_offsets dce110_ipp_reg_offsets
[] = {
160 .dcp_offset
= (mmDCP0_CUR_CONTROL
- mmCUR_CONTROL
),
163 .dcp_offset
= (mmDCP1_CUR_CONTROL
- mmCUR_CONTROL
),
166 .dcp_offset
= (mmDCP2_CUR_CONTROL
- mmCUR_CONTROL
),
169 .dcp_offset
= (mmDCP3_CUR_CONTROL
- mmCUR_CONTROL
),
172 .dcp_offset
= (mmDCP4_CUR_CONTROL
- mmCUR_CONTROL
),
175 .dcp_offset
= (mmDCP5_CUR_CONTROL
- mmCUR_CONTROL
),
182 /* set register offset */
183 #define SR(reg_name)\
184 .reg_name = mm ## reg_name
186 /* set register offset with instance */
187 #define SRI(reg_name, block, id)\
188 .reg_name = mm ## block ## id ## _ ## reg_name
191 #define transform_regs(id)\
193 XFM_COMMON_REG_LIST_DCE110(id)\
196 static const struct dce_transform_registers xfm_regs
[] = {
202 static const struct dce_transform_shift xfm_shift
= {
203 XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT
)
206 static const struct dce_transform_mask xfm_mask
= {
207 XFM_COMMON_MASK_SH_LIST_DCE110(_MASK
)
210 #define aux_regs(id)\
215 static const struct dce110_link_enc_aux_registers link_enc_aux_regs
[] = {
224 #define hpd_regs(id)\
229 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs
[] = {
239 #define link_regs(id)\
241 LE_DCE110_REG_LIST(id)\
244 static const struct dce110_link_enc_registers link_enc_regs
[] = {
254 #define stream_enc_regs(id)\
256 SE_COMMON_REG_LIST(id),\
260 static const struct dce110_stream_enc_registers stream_enc_regs
[] = {
266 static const struct dce_stream_encoder_shift se_shift
= {
267 SE_COMMON_MASK_SH_LIST_DCE110(__SHIFT
)
270 static const struct dce_stream_encoder_mask se_mask
= {
271 SE_COMMON_MASK_SH_LIST_DCE110(_MASK
)
274 #define audio_regs(id)\
276 AUD_COMMON_REG_LIST(id)\
279 static const struct dce_audio_registers audio_regs
[] = {
289 static const struct dce_audio_shift audio_shift
= {
290 AUD_COMMON_MASK_SH_LIST(__SHIFT
)
293 static const struct dce_aduio_mask audio_mask
= {
294 AUD_COMMON_MASK_SH_LIST(_MASK
)
297 /* AG TBD Needs to be reduced back to 3 pipes once dce10 hw sequencer implemented. */
298 static const struct dce110_opp_reg_offsets dce110_opp_reg_offsets
[] = {
300 .fmt_offset
= (mmFMT0_FMT_CONTROL
- mmFMT0_FMT_CONTROL
),
301 .dcfe_offset
= (mmDCFE0_DCFE_MEM_PWR_CTRL
- mmDCFE0_DCFE_MEM_PWR_CTRL
),
302 .dcp_offset
= (mmDCP0_GRPH_CONTROL
- mmDCP0_GRPH_CONTROL
),
304 { .fmt_offset
= (mmFMT1_FMT_CONTROL
- mmFMT0_FMT_CONTROL
),
305 .dcfe_offset
= (mmDCFE1_DCFE_MEM_PWR_CTRL
- mmDCFE0_DCFE_MEM_PWR_CTRL
),
306 .dcp_offset
= (mmDCP1_GRPH_CONTROL
- mmDCP0_GRPH_CONTROL
),
308 { .fmt_offset
= (mmFMT2_FMT_CONTROL
- mmFMT0_FMT_CONTROL
),
309 .dcfe_offset
= (mmDCFE2_DCFE_MEM_PWR_CTRL
- mmDCFE0_DCFE_MEM_PWR_CTRL
),
310 .dcp_offset
= (mmDCP2_GRPH_CONTROL
- mmDCP0_GRPH_CONTROL
),
313 .fmt_offset
= (mmFMT3_FMT_CONTROL
- mmFMT0_FMT_CONTROL
),
314 .dcfe_offset
= (mmDCFE3_DCFE_MEM_PWR_CTRL
- mmDCFE0_DCFE_MEM_PWR_CTRL
),
315 .dcp_offset
= (mmDCP3_GRPH_CONTROL
- mmDCP0_GRPH_CONTROL
),
317 { .fmt_offset
= (mmFMT4_FMT_CONTROL
- mmFMT0_FMT_CONTROL
),
318 .dcfe_offset
= (mmDCFE4_DCFE_MEM_PWR_CTRL
- mmDCFE0_DCFE_MEM_PWR_CTRL
),
319 .dcp_offset
= (mmDCP4_GRPH_CONTROL
- mmDCP0_GRPH_CONTROL
),
321 { .fmt_offset
= (mmFMT5_FMT_CONTROL
- mmFMT0_FMT_CONTROL
),
322 .dcfe_offset
= (mmDCFE5_DCFE_MEM_PWR_CTRL
- mmDCFE0_DCFE_MEM_PWR_CTRL
),
323 .dcp_offset
= (mmDCP5_GRPH_CONTROL
- mmDCP0_GRPH_CONTROL
),
327 #define clk_src_regs(id)\
329 CS_COMMON_REG_LIST_DCE_100_110(id),\
332 static const struct dce110_clk_src_regs clk_src_regs
[] = {
338 static const struct dce110_clk_src_shift cs_shift
= {
339 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT
)
342 static const struct dce110_clk_src_mask cs_mask
= {
343 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK
)
346 static const struct bios_registers bios_regs
= {
347 .BIOS_SCRATCH_6
= mmBIOS_SCRATCH_6
350 static const struct resource_caps carrizo_resource_cap
= {
351 .num_timing_generator
= 3,
352 .num_video_plane
= 1,
354 .num_stream_encoder
= 3,
358 static const struct resource_caps stoney_resource_cap
= {
359 .num_timing_generator
= 2,
360 .num_video_plane
= 1,
362 .num_stream_encoder
= 3,
367 #define REG(reg) mm ## reg
369 #ifndef mmCC_DC_HDMI_STRAPS
370 #define mmCC_DC_HDMI_STRAPS 0x4819
371 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
372 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
373 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
374 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
377 static void read_dce_straps(
378 struct dc_context
*ctx
,
379 struct resource_straps
*straps
)
381 REG_GET_2(CC_DC_HDMI_STRAPS
,
382 HDMI_DISABLE
, &straps
->hdmi_disable
,
383 AUDIO_STREAM_NUMBER
, &straps
->audio_stream_number
);
385 REG_GET(DC_PINSTRAPS
, DC_PINSTRAPS_AUDIO
, &straps
->dc_pinstraps_audio
);
388 static struct audio
*create_audio(
389 struct dc_context
*ctx
, unsigned int inst
)
391 return dce_audio_create(ctx
, inst
,
392 &audio_regs
[inst
], &audio_shift
, &audio_mask
);
395 static struct timing_generator
*dce110_timing_generator_create(
396 struct dc_context
*ctx
,
398 const struct dce110_timing_generator_offsets
*offsets
)
400 struct dce110_timing_generator
*tg110
=
401 dm_alloc(sizeof(struct dce110_timing_generator
));
406 if (dce110_timing_generator_construct(tg110
, ctx
, instance
, offsets
))
414 static struct stream_encoder
*dce110_stream_encoder_create(
415 enum engine_id eng_id
,
416 struct dc_context
*ctx
)
418 struct dce110_stream_encoder
*enc110
=
419 dm_alloc(sizeof(struct dce110_stream_encoder
));
424 if (dce110_stream_encoder_construct(
425 enc110
, ctx
, ctx
->dc_bios
, eng_id
,
426 &stream_enc_regs
[eng_id
], &se_shift
, &se_mask
))
427 return &enc110
->base
;
434 #define SRII(reg_name, block, id)\
435 .reg_name[id] = mm ## block ## id ## _ ## reg_name
437 static const struct dce_hwseq_registers hwseq_stoney_reg
= {
441 static const struct dce_hwseq_registers hwseq_cz_reg
= {
445 static const struct dce_hwseq_shift hwseq_shift
= {
446 HWSEQ_DCE11_MASK_SH_LIST(__SHIFT
),
449 static const struct dce_hwseq_mask hwseq_mask
= {
450 HWSEQ_DCE11_MASK_SH_LIST(_MASK
),
453 static struct dce_hwseq
*dce110_hwseq_create(
454 struct dc_context
*ctx
)
456 struct dce_hwseq
*hws
= dm_alloc(sizeof(struct dce_hwseq
));
460 hws
->regs
= ASIC_REV_IS_STONEY(ctx
->asic_id
.hw_internal_rev
) ?
461 &hwseq_stoney_reg
: &hwseq_cz_reg
;
462 hws
->shifts
= &hwseq_shift
;
463 hws
->masks
= &hwseq_mask
;
464 hws
->wa
.blnd_crtc_trigger
= true;
469 static const struct resource_create_funcs res_create_funcs
= {
470 .read_dce_straps
= read_dce_straps
,
471 .create_audio
= create_audio
,
472 .create_stream_encoder
= dce110_stream_encoder_create
,
473 .create_hwseq
= dce110_hwseq_create
,
476 #define mi_inst_regs(id) { \
477 MI_DCE11_REG_LIST(id), \
478 .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
480 static const struct dce_mem_input_registers mi_regs
[] = {
486 static const struct dce_mem_input_shift mi_shifts
= {
487 MI_DCE11_MASK_SH_LIST(__SHIFT
),
488 .ENABLE
= MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
491 static const struct dce_mem_input_mask mi_masks
= {
492 MI_DCE11_MASK_SH_LIST(_MASK
),
493 .ENABLE
= MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
496 static struct mem_input
*dce110_mem_input_create(
497 struct dc_context
*ctx
,
499 const struct dce110_mem_input_reg_offsets
*offset
)
501 struct dce110_mem_input
*mem_input110
=
502 dm_alloc(sizeof(struct dce110_mem_input
));
507 if (dce110_mem_input_construct(mem_input110
, ctx
, inst
, offset
)) {
508 struct mem_input
*mi
= &mem_input110
->base
;
510 mi
->regs
= &mi_regs
[inst
];
511 mi
->shifts
= &mi_shifts
;
512 mi
->masks
= &mi_masks
;
513 mi
->wa
.single_head_rdreq_dmif_limit
= 3;
518 dm_free(mem_input110
);
522 static void dce110_transform_destroy(struct transform
**xfm
)
524 dm_free(TO_DCE_TRANSFORM(*xfm
));
528 static struct transform
*dce110_transform_create(
529 struct dc_context
*ctx
,
532 struct dce_transform
*transform
=
533 dm_alloc(sizeof(struct dce_transform
));
538 if (dce_transform_construct(transform
, ctx
, inst
,
539 &xfm_regs
[inst
], &xfm_shift
, &xfm_mask
))
540 return &transform
->base
;
547 static struct input_pixel_processor
*dce110_ipp_create(
548 struct dc_context
*ctx
,
550 const struct dce110_ipp_reg_offsets
*offsets
)
552 struct dce110_ipp
*ipp
=
553 dm_alloc(sizeof(struct dce110_ipp
));
558 if (dce110_ipp_construct(ipp
, ctx
, inst
, offsets
))
566 struct link_encoder
*dce110_link_encoder_create(
567 const struct encoder_init_data
*enc_init_data
)
569 struct dce110_link_encoder
*enc110
=
570 dm_alloc(sizeof(struct dce110_link_encoder
));
575 if (dce110_link_encoder_construct(
578 &link_enc_regs
[enc_init_data
->transmitter
],
579 &link_enc_aux_regs
[enc_init_data
->channel
- 1],
580 &link_enc_hpd_regs
[enc_init_data
->hpd_source
])) {
582 enc110
->base
.features
.ycbcr420_supported
= false;
583 enc110
->base
.features
.max_hdmi_pixel_clock
= 594000;
584 return &enc110
->base
;
592 static struct output_pixel_processor
*dce110_opp_create(
593 struct dc_context
*ctx
,
595 const struct dce110_opp_reg_offsets
*offsets
)
597 struct dce110_opp
*opp
=
598 dm_alloc(sizeof(struct dce110_opp
));
603 if (dce110_opp_construct(opp
,
612 struct clock_source
*dce110_clock_source_create(
613 struct dc_context
*ctx
,
614 struct dc_bios
*bios
,
615 enum clock_source_id id
,
616 const struct dce110_clk_src_regs
*regs
,
619 struct dce110_clk_src
*clk_src
=
620 dm_alloc(sizeof(struct dce110_clk_src
));
625 if (dce110_clk_src_construct(clk_src
, ctx
, bios
, id
,
626 regs
, &cs_shift
, &cs_mask
)) {
627 clk_src
->base
.dp_clk_src
= dp_clk_src
;
628 return &clk_src
->base
;
635 void dce110_clock_source_destroy(struct clock_source
**clk_src
)
637 struct dce110_clk_src
*dce110_clk_src
;
642 dce110_clk_src
= TO_DCE110_CLK_SRC(*clk_src
);
644 if (dce110_clk_src
->dp_ss_params
)
645 dm_free(dce110_clk_src
->dp_ss_params
);
647 if (dce110_clk_src
->hdmi_ss_params
)
648 dm_free(dce110_clk_src
->hdmi_ss_params
);
650 if (dce110_clk_src
->dvi_ss_params
)
651 dm_free(dce110_clk_src
->dvi_ss_params
);
653 dm_free(dce110_clk_src
);
657 static void destruct(struct dce110_resource_pool
*pool
)
661 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
662 if (pool
->base
.opps
[i
] != NULL
)
663 dce110_opp_destroy(&pool
->base
.opps
[i
]);
665 if (pool
->base
.transforms
[i
] != NULL
)
666 dce110_transform_destroy(&pool
->base
.transforms
[i
]);
668 if (pool
->base
.ipps
[i
] != NULL
)
669 dce110_ipp_destroy(&pool
->base
.ipps
[i
]);
671 if (pool
->base
.mis
[i
] != NULL
) {
672 dm_free(TO_DCE110_MEM_INPUT(pool
->base
.mis
[i
]));
673 pool
->base
.mis
[i
] = NULL
;
676 if (pool
->base
.timing_generators
[i
] != NULL
) {
677 dm_free(DCE110TG_FROM_TG(pool
->base
.timing_generators
[i
]));
678 pool
->base
.timing_generators
[i
] = NULL
;
682 for (i
= 0; i
< pool
->base
.stream_enc_count
; i
++) {
683 if (pool
->base
.stream_enc
[i
] != NULL
)
684 dm_free(DCE110STRENC_FROM_STRENC(pool
->base
.stream_enc
[i
]));
687 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
688 if (pool
->base
.clock_sources
[i
] != NULL
) {
689 dce110_clock_source_destroy(&pool
->base
.clock_sources
[i
]);
693 if (pool
->base
.dp_clock_source
!= NULL
)
694 dce110_clock_source_destroy(&pool
->base
.dp_clock_source
);
696 for (i
= 0; i
< pool
->base
.audio_count
; i
++) {
697 if (pool
->base
.audios
[i
] != NULL
) {
698 dce_aud_destroy(&pool
->base
.audios
[i
]);
702 if (pool
->base
.display_clock
!= NULL
) {
703 dal_display_clock_destroy(&pool
->base
.display_clock
);
706 if (pool
->base
.irqs
!= NULL
) {
707 dal_irq_service_destroy(&pool
->base
.irqs
);
712 static void get_pixel_clock_parameters(
713 const struct pipe_ctx
*pipe_ctx
,
714 struct pixel_clk_params
*pixel_clk_params
)
716 const struct core_stream
*stream
= pipe_ctx
->stream
;
718 /*TODO: is this halved for YCbCr 420? in that case we might want to move
719 * the pixel clock normalization for hdmi up to here instead of doing it
720 * in pll_adjust_pix_clk
722 pixel_clk_params
->requested_pix_clk
= stream
->public.timing
.pix_clk_khz
;
723 pixel_clk_params
->encoder_object_id
= stream
->sink
->link
->link_enc
->id
;
724 pixel_clk_params
->signal_type
= pipe_ctx
->stream
->signal
;
725 pixel_clk_params
->controller_id
= pipe_ctx
->pipe_idx
+ 1;
726 /* TODO: un-hardcode*/
727 pixel_clk_params
->requested_sym_clk
= LINK_RATE_LOW
*
728 LINK_RATE_REF_FREQ_IN_KHZ
;
729 pixel_clk_params
->flags
.ENABLE_SS
= 0;
730 pixel_clk_params
->color_depth
=
731 stream
->public.timing
.display_color_depth
;
732 pixel_clk_params
->flags
.DISPLAY_BLANKED
= 1;
733 pixel_clk_params
->flags
.SUPPORT_YCBCR420
= (stream
->public.timing
.pixel_encoding
==
734 PIXEL_ENCODING_YCBCR420
);
737 void dce110_resource_build_bit_depth_reduction_params(
738 const struct core_stream
*stream
,
739 struct bit_depth_reduction_params
*fmt_bit_depth
)
741 memset(fmt_bit_depth
, 0, sizeof(*fmt_bit_depth
));
743 /*TODO: Need to un-hardcode, refer to function with same name
744 * in dal2 hw_sequencer*/
746 fmt_bit_depth
->flags
.TRUNCATE_ENABLED
= 0;
747 fmt_bit_depth
->flags
.SPATIAL_DITHER_ENABLED
= 0;
748 fmt_bit_depth
->flags
.FRAME_MODULATION_ENABLED
= 0;
750 /* Diagnostics need consistent CRC of the image, that means
751 * dithering should not be enabled for Diagnostics. */
752 if (IS_DIAG_DC(stream
->ctx
->dce_environment
) == false) {
753 switch (stream
->public.timing
.display_color_depth
) {
754 case COLOR_DEPTH_666
:
755 fmt_bit_depth
->flags
.SPATIAL_DITHER_ENABLED
= 1;
756 fmt_bit_depth
->flags
.SPATIAL_DITHER_DEPTH
= 0;
758 case COLOR_DEPTH_888
:
759 fmt_bit_depth
->flags
.SPATIAL_DITHER_ENABLED
= 1;
760 fmt_bit_depth
->flags
.SPATIAL_DITHER_DEPTH
= 1;
762 case COLOR_DEPTH_101010
:
763 fmt_bit_depth
->flags
.SPATIAL_DITHER_ENABLED
= 1;
764 fmt_bit_depth
->flags
.SPATIAL_DITHER_DEPTH
= 2;
769 fmt_bit_depth
->flags
.RGB_RANDOM
= 1;
770 fmt_bit_depth
->flags
.HIGHPASS_RANDOM
= 1;
771 fmt_bit_depth
->flags
.TRUNCATE_ENABLED
= 1;
772 fmt_bit_depth
->flags
.TRUNCATE_DEPTH
= 2;
778 enum dc_status
dce110_resource_build_pipe_hw_param(struct pipe_ctx
*pipe_ctx
)
780 get_pixel_clock_parameters(pipe_ctx
, &pipe_ctx
->pix_clk_params
);
781 pipe_ctx
->clock_source
->funcs
->get_pix_clk_dividers(
782 pipe_ctx
->clock_source
,
783 &pipe_ctx
->pix_clk_params
,
784 &pipe_ctx
->pll_settings
);
785 dce110_resource_build_bit_depth_reduction_params(pipe_ctx
->stream
,
786 &pipe_ctx
->stream
->bit_depth_params
);
787 pipe_ctx
->stream
->clamping
.pixel_encoding
= pipe_ctx
->stream
->public.timing
.pixel_encoding
;
792 static bool is_surface_pixel_format_supported(struct pipe_ctx
*pipe_ctx
, unsigned int underlay_idx
)
794 if (pipe_ctx
->pipe_idx
!= underlay_idx
)
796 if (!pipe_ctx
->surface
)
798 if (pipe_ctx
->surface
->public.format
< SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
)
803 static enum dc_status
validate_mapped_resource(
804 const struct core_dc
*dc
,
805 struct validate_context
*context
)
807 enum dc_status status
= DC_OK
;
810 for (i
= 0; i
< context
->target_count
; i
++) {
811 struct core_target
*target
= context
->targets
[i
];
813 for (j
= 0; j
< target
->public.stream_count
; j
++) {
814 struct core_stream
*stream
=
815 DC_STREAM_TO_CORE(target
->public.streams
[j
]);
816 struct core_link
*link
= stream
->sink
->link
;
818 if (resource_is_stream_unchanged(dc
->current_context
, stream
))
821 for (k
= 0; k
< MAX_PIPES
; k
++) {
822 struct pipe_ctx
*pipe_ctx
=
823 &context
->res_ctx
.pipe_ctx
[k
];
825 if (context
->res_ctx
.pipe_ctx
[k
].stream
!= stream
)
828 if (!is_surface_pixel_format_supported(pipe_ctx
,
829 context
->res_ctx
.pool
->underlay_pipe_index
))
830 return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED
;
832 if (!pipe_ctx
->tg
->funcs
->validate_timing(
833 pipe_ctx
->tg
, &stream
->public.timing
))
834 return DC_FAIL_CONTROLLER_VALIDATE
;
836 status
= dce110_resource_build_pipe_hw_param(pipe_ctx
);
841 if (!link
->link_enc
->funcs
->validate_output_with_stream(
844 return DC_FAIL_ENC_VALIDATE
;
846 /* TODO: validate audio ASIC caps, encoder */
848 status
= dc_link_validate_mode_timing(stream
,
850 &stream
->public.timing
);
855 resource_build_info_frame(pipe_ctx
);
857 /* do not need to validate non root pipes */
866 enum dc_status
dce110_validate_bandwidth(
867 const struct core_dc
*dc
,
868 struct validate_context
*context
)
870 enum dc_status result
= DC_ERROR_UNEXPECTED
;
873 dc
->ctx
->logger
, LOG_BANDWIDTH_CALCS
,
881 context
->res_ctx
.pipe_ctx
,
882 context
->res_ctx
.pool
->pipe_count
,
883 &context
->bw_results
))
884 result
= DC_FAIL_BANDWIDTH_VALIDATE
;
888 if (result
== DC_FAIL_BANDWIDTH_VALIDATE
)
889 dm_logger_write(dc
->ctx
->logger
, LOG_BANDWIDTH_VALIDATION
,
890 "%s: %dx%d@%d Bandwidth validation failed!\n",
892 context
->targets
[0]->public.streams
[0]->timing
.h_addressable
,
893 context
->targets
[0]->public.streams
[0]->timing
.v_addressable
,
894 context
->targets
[0]->public.streams
[0]->timing
.pix_clk_khz
);
896 if (memcmp(&dc
->current_context
->bw_results
,
897 &context
->bw_results
, sizeof(context
->bw_results
))) {
898 struct log_entry log_entry
;
902 LOG_BANDWIDTH_CALCS
);
903 dm_logger_append(&log_entry
, "%s: finish,\n"
904 "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
905 "stutMark_b: %d stutMark_a: %d\n",
907 context
->bw_results
.nbp_state_change_wm_ns
[0].b_mark
,
908 context
->bw_results
.nbp_state_change_wm_ns
[0].a_mark
,
909 context
->bw_results
.urgent_wm_ns
[0].b_mark
,
910 context
->bw_results
.urgent_wm_ns
[0].a_mark
,
911 context
->bw_results
.stutter_exit_wm_ns
[0].b_mark
,
912 context
->bw_results
.stutter_exit_wm_ns
[0].a_mark
);
913 dm_logger_append(&log_entry
,
914 "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
915 "stutMark_b: %d stutMark_a: %d\n",
916 context
->bw_results
.nbp_state_change_wm_ns
[1].b_mark
,
917 context
->bw_results
.nbp_state_change_wm_ns
[1].a_mark
,
918 context
->bw_results
.urgent_wm_ns
[1].b_mark
,
919 context
->bw_results
.urgent_wm_ns
[1].a_mark
,
920 context
->bw_results
.stutter_exit_wm_ns
[1].b_mark
,
921 context
->bw_results
.stutter_exit_wm_ns
[1].a_mark
);
922 dm_logger_append(&log_entry
,
923 "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
924 "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n",
925 context
->bw_results
.nbp_state_change_wm_ns
[2].b_mark
,
926 context
->bw_results
.nbp_state_change_wm_ns
[2].a_mark
,
927 context
->bw_results
.urgent_wm_ns
[2].b_mark
,
928 context
->bw_results
.urgent_wm_ns
[2].a_mark
,
929 context
->bw_results
.stutter_exit_wm_ns
[2].b_mark
,
930 context
->bw_results
.stutter_exit_wm_ns
[2].a_mark
,
931 context
->bw_results
.stutter_mode_enable
);
932 dm_logger_append(&log_entry
,
933 "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n"
934 "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n",
935 context
->bw_results
.cpuc_state_change_enable
,
936 context
->bw_results
.cpup_state_change_enable
,
937 context
->bw_results
.nbp_state_change_enable
,
938 context
->bw_results
.all_displays_in_sync
,
939 context
->bw_results
.dispclk_khz
,
940 context
->bw_results
.required_sclk
,
941 context
->bw_results
.required_sclk_deep_sleep
,
942 context
->bw_results
.required_yclk
,
943 context
->bw_results
.blackout_recovery_time_us
);
944 dm_logger_close(&log_entry
);
949 static bool dce110_validate_surface_sets(
950 const struct dc_validation_set set
[],
955 for (i
= 0; i
< set_count
; i
++) {
956 if (set
[i
].surface_count
== 0)
959 if (set
[i
].surface_count
> 2)
962 if (set
[i
].surfaces
[0]->src_rect
.width
963 != set
[i
].target
->streams
[0]->src
.width
964 || set
[i
].surfaces
[0]->src_rect
.height
965 != set
[i
].target
->streams
[0]->src
.height
)
967 if (set
[i
].surfaces
[0]->format
968 >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
)
971 if (set
[i
].surface_count
== 2) {
972 if (set
[i
].surfaces
[1]->format
973 < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
)
975 if (set
[i
].surfaces
[1]->src_rect
.width
> 1920
976 || set
[i
].surfaces
[1]->src_rect
.height
> 1080)
979 if (set
[i
].target
->streams
[0]->timing
.pixel_encoding
!= PIXEL_ENCODING_RGB
)
987 enum dc_status
dce110_validate_with_context(
988 const struct core_dc
*dc
,
989 const struct dc_validation_set set
[],
991 struct validate_context
*context
)
993 struct dc_context
*dc_ctx
= dc
->ctx
;
994 enum dc_status result
= DC_ERROR_UNEXPECTED
;
997 if (!dce110_validate_surface_sets(set
, set_count
))
998 return DC_FAIL_SURFACE_VALIDATE
;
1000 context
->res_ctx
.pool
= dc
->res_pool
;
1002 for (i
= 0; i
< set_count
; i
++) {
1003 context
->targets
[i
] = DC_TARGET_TO_CORE(set
[i
].target
);
1004 dc_target_retain(&context
->targets
[i
]->public);
1005 context
->target_count
++;
1008 result
= resource_map_pool_resources(dc
, context
);
1010 if (result
== DC_OK
)
1011 result
= resource_map_clock_resources(dc
, context
);
1013 if (!resource_validate_attach_surfaces(
1014 set
, set_count
, dc
->current_context
, context
)) {
1015 DC_ERROR("Failed to attach surface to target!\n");
1016 return DC_FAIL_ATTACH_SURFACES
;
1019 if (result
== DC_OK
)
1020 result
= validate_mapped_resource(dc
, context
);
1022 if (result
== DC_OK
)
1023 result
= resource_build_scaling_params_for_context(dc
, context
);
1025 if (result
== DC_OK
)
1026 result
= dce110_validate_bandwidth(dc
, context
);
1031 enum dc_status
dce110_validate_guaranteed(
1032 const struct core_dc
*dc
,
1033 const struct dc_target
*dc_target
,
1034 struct validate_context
*context
)
1036 enum dc_status result
= DC_ERROR_UNEXPECTED
;
1038 context
->res_ctx
.pool
= dc
->res_pool
;
1040 context
->targets
[0] = DC_TARGET_TO_CORE(dc_target
);
1041 dc_target_retain(&context
->targets
[0]->public);
1042 context
->target_count
++;
1044 result
= resource_map_pool_resources(dc
, context
);
1046 if (result
== DC_OK
)
1047 result
= resource_map_clock_resources(dc
, context
);
1049 if (result
== DC_OK
)
1050 result
= validate_mapped_resource(dc
, context
);
1052 if (result
== DC_OK
) {
1053 validate_guaranteed_copy_target(
1054 context
, dc
->public.caps
.max_targets
);
1055 result
= resource_build_scaling_params_for_context(dc
, context
);
1058 if (result
== DC_OK
)
1059 result
= dce110_validate_bandwidth(dc
, context
);
1064 static struct pipe_ctx
*dce110_acquire_idle_pipe_for_layer(
1065 struct resource_context
*res_ctx
,
1066 struct core_stream
*stream
)
1068 unsigned int underlay_idx
= res_ctx
->pool
->underlay_pipe_index
;
1069 struct pipe_ctx
*pipe_ctx
= &res_ctx
->pipe_ctx
[underlay_idx
];
1071 if (res_ctx
->pipe_ctx
[underlay_idx
].stream
) {
1075 pipe_ctx
->tg
= res_ctx
->pool
->timing_generators
[underlay_idx
];
1076 pipe_ctx
->mi
= res_ctx
->pool
->mis
[underlay_idx
];
1077 /*pipe_ctx->ipp = res_ctx->pool->ipps[underlay_idx];*/
1078 pipe_ctx
->xfm
= res_ctx
->pool
->transforms
[underlay_idx
];
1079 pipe_ctx
->opp
= res_ctx
->pool
->opps
[underlay_idx
];
1080 pipe_ctx
->dis_clk
= res_ctx
->pool
->display_clock
;
1081 pipe_ctx
->pipe_idx
= underlay_idx
;
1083 pipe_ctx
->stream
= stream
;
1089 static void dce110_destroy_resource_pool(struct resource_pool
**pool
)
1091 struct dce110_resource_pool
*dce110_pool
= TO_DCE110_RES_POOL(*pool
);
1093 destruct(dce110_pool
);
1094 dm_free(dce110_pool
);
1099 static const struct resource_funcs dce110_res_pool_funcs
= {
1100 .destroy
= dce110_destroy_resource_pool
,
1101 .link_enc_create
= dce110_link_encoder_create
,
1102 .validate_with_context
= dce110_validate_with_context
,
1103 .validate_guaranteed
= dce110_validate_guaranteed
,
1104 .validate_bandwidth
= dce110_validate_bandwidth
,
1105 .acquire_idle_pipe_for_layer
= dce110_acquire_idle_pipe_for_layer
,
1106 .build_bit_depth_reduction_params
=
1107 dce110_resource_build_bit_depth_reduction_params
1110 static void underlay_create(struct dc_context
*ctx
, struct resource_pool
*pool
)
1112 struct dce110_timing_generator
*dce110_tgv
= dm_alloc(sizeof (*dce110_tgv
));
1113 struct dce_transform
*dce110_xfmv
= dm_alloc(sizeof (*dce110_xfmv
));
1114 struct dce110_mem_input
*dce110_miv
= dm_alloc(sizeof (*dce110_miv
));
1115 struct dce110_opp
*dce110_oppv
= dm_alloc(sizeof (*dce110_oppv
));
1117 dce110_opp_v_construct(dce110_oppv
, ctx
);
1118 dce110_timing_generator_v_construct(dce110_tgv
, ctx
);
1119 dce110_mem_input_v_construct(dce110_miv
, ctx
);
1120 dce110_transform_v_construct(dce110_xfmv
, ctx
);
1122 pool
->opps
[pool
->pipe_count
] = &dce110_oppv
->base
;
1123 pool
->timing_generators
[pool
->pipe_count
] = &dce110_tgv
->base
;
1124 pool
->mis
[pool
->pipe_count
] = &dce110_miv
->base
;
1125 pool
->transforms
[pool
->pipe_count
] = &dce110_xfmv
->base
;
1128 /* update the public caps to indicate an underlay is available */
1129 ctx
->dc
->caps
.max_slave_planes
= 1;
1130 ctx
->dc
->caps
.max_slave_planes
= 1;
1133 static void bw_calcs_data_update_from_pplib(struct core_dc
*dc
)
1135 struct dm_pp_clock_levels clks
= {0};
1138 dm_pp_get_clock_levels_by_type(
1140 DM_PP_CLOCK_TYPE_ENGINE_CLK
,
1142 /* convert all the clock fro kHz to fix point mHz */
1143 dc
->bw_vbios
.high_sclk
= bw_frc_to_fixed(
1144 clks
.clocks_in_khz
[clks
.num_levels
-1], 1000);
1145 dc
->bw_vbios
.mid1_sclk
= bw_frc_to_fixed(
1146 clks
.clocks_in_khz
[clks
.num_levels
/8], 1000);
1147 dc
->bw_vbios
.mid2_sclk
= bw_frc_to_fixed(
1148 clks
.clocks_in_khz
[clks
.num_levels
*2/8], 1000);
1149 dc
->bw_vbios
.mid3_sclk
= bw_frc_to_fixed(
1150 clks
.clocks_in_khz
[clks
.num_levels
*3/8], 1000);
1151 dc
->bw_vbios
.mid4_sclk
= bw_frc_to_fixed(
1152 clks
.clocks_in_khz
[clks
.num_levels
*4/8], 1000);
1153 dc
->bw_vbios
.mid5_sclk
= bw_frc_to_fixed(
1154 clks
.clocks_in_khz
[clks
.num_levels
*5/8], 1000);
1155 dc
->bw_vbios
.mid6_sclk
= bw_frc_to_fixed(
1156 clks
.clocks_in_khz
[clks
.num_levels
*6/8], 1000);
1157 dc
->bw_vbios
.low_sclk
= bw_frc_to_fixed(
1158 clks
.clocks_in_khz
[0], 1000);
1159 dc
->sclk_lvls
= clks
;
1161 /*do display clock*/
1162 dm_pp_get_clock_levels_by_type(
1164 DM_PP_CLOCK_TYPE_DISPLAY_CLK
,
1166 dc
->bw_vbios
.high_voltage_max_dispclk
= bw_frc_to_fixed(
1167 clks
.clocks_in_khz
[clks
.num_levels
-1], 1000);
1168 dc
->bw_vbios
.mid_voltage_max_dispclk
= bw_frc_to_fixed(
1169 clks
.clocks_in_khz
[clks
.num_levels
>>1], 1000);
1170 dc
->bw_vbios
.low_voltage_max_dispclk
= bw_frc_to_fixed(
1171 clks
.clocks_in_khz
[0], 1000);
1174 dm_pp_get_clock_levels_by_type(
1176 DM_PP_CLOCK_TYPE_MEMORY_CLK
,
1179 dc
->bw_vbios
.low_yclk
= bw_frc_to_fixed(
1180 clks
.clocks_in_khz
[0] * MEMORY_TYPE_MULTIPLIER
, 1000);
1181 dc
->bw_vbios
.mid_yclk
= bw_frc_to_fixed(
1182 clks
.clocks_in_khz
[clks
.num_levels
>>1] * MEMORY_TYPE_MULTIPLIER
,
1184 dc
->bw_vbios
.high_yclk
= bw_frc_to_fixed(
1185 clks
.clocks_in_khz
[clks
.num_levels
-1] * MEMORY_TYPE_MULTIPLIER
,
1189 enum clocks_state
dce110_resource_convert_clock_state_pp_to_dc(
1190 enum dm_pp_clocks_state pp_clock_state
)
1192 enum clocks_state dc_clocks_state
= CLOCKS_STATE_INVALID
;
1194 switch (pp_clock_state
) {
1195 case DM_PP_CLOCKS_STATE_INVALID
:
1196 dc_clocks_state
= CLOCKS_STATE_INVALID
;
1198 case DM_PP_CLOCKS_STATE_ULTRA_LOW
:
1199 dc_clocks_state
= CLOCKS_STATE_ULTRA_LOW
;
1201 case DM_PP_CLOCKS_STATE_LOW
:
1202 dc_clocks_state
= CLOCKS_STATE_LOW
;
1204 case DM_PP_CLOCKS_STATE_NOMINAL
:
1205 dc_clocks_state
= CLOCKS_STATE_NOMINAL
;
1207 case DM_PP_CLOCKS_STATE_PERFORMANCE
:
1208 dc_clocks_state
= CLOCKS_STATE_PERFORMANCE
;
1210 case DM_PP_CLOCKS_DPM_STATE_LEVEL_4
:
1211 dc_clocks_state
= CLOCKS_DPM_STATE_LEVEL_4
;
1213 case DM_PP_CLOCKS_DPM_STATE_LEVEL_5
:
1214 dc_clocks_state
= CLOCKS_DPM_STATE_LEVEL_5
;
1216 case DM_PP_CLOCKS_DPM_STATE_LEVEL_6
:
1217 dc_clocks_state
= CLOCKS_DPM_STATE_LEVEL_6
;
1219 case DM_PP_CLOCKS_DPM_STATE_LEVEL_7
:
1220 dc_clocks_state
= CLOCKS_DPM_STATE_LEVEL_7
;
1223 dc_clocks_state
= CLOCKS_STATE_INVALID
;
1227 return dc_clocks_state
;
1230 const struct resource_caps
*dce110_resource_cap(
1231 struct hw_asic_id
*asic_id
)
1233 if (ASIC_REV_IS_STONEY(asic_id
->hw_internal_rev
))
1234 return &stoney_resource_cap
;
1236 return &carrizo_resource_cap
;
1239 static bool construct(
1240 uint8_t num_virtual_links
,
1242 struct dce110_resource_pool
*pool
,
1243 struct hw_asic_id asic_id
)
1246 struct dc_context
*ctx
= dc
->ctx
;
1247 struct firmware_info info
;
1249 struct dm_pp_static_clock_info static_clk_info
= {0};
1251 ctx
->dc_bios
->regs
= &bios_regs
;
1253 pool
->base
.res_cap
= dce110_resource_cap(&ctx
->asic_id
);
1254 pool
->base
.funcs
= &dce110_res_pool_funcs
;
1256 /*************************************************
1257 * Resource + asic cap harcoding *
1258 *************************************************/
1260 pool
->base
.pipe_count
= pool
->base
.res_cap
->num_timing_generator
;
1261 pool
->base
.underlay_pipe_index
= pool
->base
.pipe_count
;
1263 dc
->public.caps
.max_downscale_ratio
= 150;
1264 dc
->public.caps
.i2c_speed_in_khz
= 100;
1266 /*************************************************
1267 * Create resources *
1268 *************************************************/
1272 if ((bp
->funcs
->get_firmware_info(bp
, &info
) == BP_RESULT_OK
) &&
1273 info
.external_clock_source_frequency_for_dp
!= 0) {
1274 pool
->base
.dp_clock_source
=
1275 dce110_clock_source_create(ctx
, bp
, CLOCK_SOURCE_ID_EXTERNAL
, NULL
, true);
1277 pool
->base
.clock_sources
[0] =
1278 dce110_clock_source_create(ctx
, bp
, CLOCK_SOURCE_ID_PLL0
,
1279 &clk_src_regs
[0], false);
1280 pool
->base
.clock_sources
[1] =
1281 dce110_clock_source_create(ctx
, bp
, CLOCK_SOURCE_ID_PLL1
,
1282 &clk_src_regs
[1], false);
1284 pool
->base
.clk_src_count
= 2;
1286 /* TODO: find out if CZ support 3 PLLs */
1289 if (pool
->base
.dp_clock_source
== NULL
) {
1290 dm_error("DC: failed to create dp clock source!\n");
1291 BREAK_TO_DEBUGGER();
1292 goto res_create_fail
;
1295 for (i
= 0; i
< pool
->base
.clk_src_count
; i
++) {
1296 if (pool
->base
.clock_sources
[i
] == NULL
) {
1297 dm_error("DC: failed to create clock sources!\n");
1298 BREAK_TO_DEBUGGER();
1299 goto res_create_fail
;
1303 pool
->base
.display_clock
= dal_display_clock_dce110_create(ctx
);
1304 if (pool
->base
.display_clock
== NULL
) {
1305 dm_error("DC: failed to create display clock!\n");
1306 BREAK_TO_DEBUGGER();
1307 goto res_create_fail
;
1310 /* get static clock information for PPLIB or firmware, save
1313 if (dm_pp_get_static_clocks(ctx
, &static_clk_info
)) {
1314 enum clocks_state max_clocks_state
=
1315 dce110_resource_convert_clock_state_pp_to_dc(
1316 static_clk_info
.max_clocks_state
);
1318 pool
->base
.display_clock
->funcs
->store_max_clocks_state(
1319 pool
->base
.display_clock
, max_clocks_state
);
1323 struct irq_service_init_data init_data
;
1324 init_data
.ctx
= dc
->ctx
;
1325 pool
->base
.irqs
= dal_irq_service_dce110_create(&init_data
);
1326 if (!pool
->base
.irqs
)
1327 goto res_create_fail
;
1330 for (i
= 0; i
< pool
->base
.pipe_count
; i
++) {
1331 pool
->base
.timing_generators
[i
] = dce110_timing_generator_create(
1332 ctx
, i
, &dce110_tg_offsets
[i
]);
1333 if (pool
->base
.timing_generators
[i
] == NULL
) {
1334 BREAK_TO_DEBUGGER();
1335 dm_error("DC: failed to create tg!\n");
1336 goto res_create_fail
;
1339 pool
->base
.mis
[i
] = dce110_mem_input_create(ctx
, i
,
1340 &dce110_mi_reg_offsets
[i
]);
1341 if (pool
->base
.mis
[i
] == NULL
) {
1342 BREAK_TO_DEBUGGER();
1344 "DC: failed to create memory input!\n");
1345 goto res_create_fail
;
1348 pool
->base
.ipps
[i
] = dce110_ipp_create(ctx
, i
, &dce110_ipp_reg_offsets
[i
]);
1349 if (pool
->base
.ipps
[i
] == NULL
) {
1350 BREAK_TO_DEBUGGER();
1352 "DC: failed to create input pixel processor!\n");
1353 goto res_create_fail
;
1356 pool
->base
.transforms
[i
] = dce110_transform_create(ctx
, i
);
1357 if (pool
->base
.transforms
[i
] == NULL
) {
1358 BREAK_TO_DEBUGGER();
1360 "DC: failed to create transform!\n");
1361 goto res_create_fail
;
1364 pool
->base
.opps
[i
] = dce110_opp_create(ctx
, i
, &dce110_opp_reg_offsets
[i
]);
1365 if (pool
->base
.opps
[i
] == NULL
) {
1366 BREAK_TO_DEBUGGER();
1368 "DC: failed to create output pixel processor!\n");
1369 goto res_create_fail
;
1373 underlay_create(ctx
, &pool
->base
);
1375 if (!resource_construct(num_virtual_links
, dc
, &pool
->base
,
1377 goto res_create_fail
;
1379 /* Create hardware sequencer */
1380 if (!dce110_hw_sequencer_construct(dc
))
1381 goto res_create_fail
;
1383 if (ASIC_REV_IS_STONEY(ctx
->asic_id
.hw_internal_rev
))
1384 bw_calcs_init(&dc
->bw_dceip
, &dc
->bw_vbios
, BW_CALCS_VERSION_STONEY
);
1386 bw_calcs_init(&dc
->bw_dceip
, &dc
->bw_vbios
, BW_CALCS_VERSION_CARRIZO
);
1388 bw_calcs_data_update_from_pplib(dc
);
1397 struct resource_pool
*dce110_create_resource_pool(
1398 uint8_t num_virtual_links
,
1400 struct hw_asic_id asic_id
)
1402 struct dce110_resource_pool
*pool
=
1403 dm_alloc(sizeof(struct dce110_resource_pool
));
1408 if (construct(num_virtual_links
, dc
, pool
, asic_id
))
1411 BREAK_TO_DEBUGGER();