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 "dce/dce_8_0_d.h"
27 #include "dce/dce_8_0_sh_mask.h"
29 #include "dm_services.h"
31 #include "link_encoder.h"
32 #include "stream_encoder.h"
35 #include "include/irq_service_interface.h"
36 #include "irq/dce80/irq_service_dce80.h"
37 #include "dce110/dce110_timing_generator.h"
38 #include "dce110/dce110_resource.h"
39 #include "dce80/dce80_timing_generator.h"
40 #include "dce/dce_clk_mgr.h"
41 #include "dce/dce_mem_input.h"
42 #include "dce/dce_link_encoder.h"
43 #include "dce/dce_stream_encoder.h"
44 #include "dce/dce_ipp.h"
45 #include "dce/dce_transform.h"
46 #include "dce/dce_opp.h"
47 #include "dce/dce_clock_source.h"
48 #include "dce/dce_audio.h"
49 #include "dce/dce_hwseq.h"
50 #include "dce80/dce80_hw_sequencer.h"
51 #include "dce100/dce100_resource.h"
53 #include "reg_helper.h"
55 #include "dce/dce_dmcu.h"
56 #include "dce/dce_aux.h"
57 #include "dce/dce_abm.h"
58 #include "dce/dce_i2c.h"
59 /* TODO remove this include */
61 #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
62 #include "gmc/gmc_7_1_d.h"
63 #include "gmc/gmc_7_1_sh_mask.h"
66 #ifndef mmDP_DPHY_INTERNAL_CTRL
67 #define mmDP_DPHY_INTERNAL_CTRL 0x1CDE
68 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x1CDE
69 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x1FDE
70 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x42DE
71 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x45DE
72 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x48DE
73 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4BDE
74 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x4EDE
78 #ifndef mmBIOS_SCRATCH_2
79 #define mmBIOS_SCRATCH_2 0x05CB
80 #define mmBIOS_SCRATCH_6 0x05CF
83 #ifndef mmDP_DPHY_FAST_TRAINING
84 #define mmDP_DPHY_FAST_TRAINING 0x1CCE
85 #define mmDP0_DP_DPHY_FAST_TRAINING 0x1CCE
86 #define mmDP1_DP_DPHY_FAST_TRAINING 0x1FCE
87 #define mmDP2_DP_DPHY_FAST_TRAINING 0x42CE
88 #define mmDP3_DP_DPHY_FAST_TRAINING 0x45CE
89 #define mmDP4_DP_DPHY_FAST_TRAINING 0x48CE
90 #define mmDP5_DP_DPHY_FAST_TRAINING 0x4BCE
91 #define mmDP6_DP_DPHY_FAST_TRAINING 0x4ECE
95 #ifndef mmHPD_DC_HPD_CONTROL
96 #define mmHPD_DC_HPD_CONTROL 0x189A
97 #define mmHPD0_DC_HPD_CONTROL 0x189A
98 #define mmHPD1_DC_HPD_CONTROL 0x18A2
99 #define mmHPD2_DC_HPD_CONTROL 0x18AA
100 #define mmHPD3_DC_HPD_CONTROL 0x18B2
101 #define mmHPD4_DC_HPD_CONTROL 0x18BA
102 #define mmHPD5_DC_HPD_CONTROL 0x18C2
105 #define DCE11_DIG_FE_CNTL 0x4a00
106 #define DCE11_DIG_BE_CNTL 0x4a47
107 #define DCE11_DP_SEC 0x4ac3
109 static const struct dce110_timing_generator_offsets dce80_tg_offsets[] = {
111 .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
112 .dcp = (mmGRPH_CONTROL - mmGRPH_CONTROL),
113 .dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL
114 - mmDPG_WATERMARK_MASK_CONTROL),
117 .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
118 .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
119 .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
120 - mmDPG_WATERMARK_MASK_CONTROL),
123 .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
124 .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
125 .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
126 - mmDPG_WATERMARK_MASK_CONTROL),
129 .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
130 .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
131 .dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL
132 - mmDPG_WATERMARK_MASK_CONTROL),
135 .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
136 .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
137 .dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL
138 - mmDPG_WATERMARK_MASK_CONTROL),
141 .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
142 .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
143 .dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL
144 - mmDPG_WATERMARK_MASK_CONTROL),
148 /* set register offset */
149 #define SR(reg_name)\
150 .reg_name = mm ## reg_name
152 /* set register offset with instance */
153 #define SRI(reg_name, block, id)\
154 .reg_name = mm ## block ## id ## _ ## reg_name
157 static const struct clk_mgr_registers disp_clk_regs = {
158 CLK_COMMON_REG_LIST_DCE_BASE()
161 static const struct clk_mgr_shift disp_clk_shift = {
162 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
165 static const struct clk_mgr_mask disp_clk_mask = {
166 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
169 #define ipp_regs(id)\
171 IPP_COMMON_REG_LIST_DCE_BASE(id)\
174 static const struct dce_ipp_registers ipp_regs[] = {
183 static const struct dce_ipp_shift ipp_shift = {
184 IPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
187 static const struct dce_ipp_mask ipp_mask = {
188 IPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
191 #define transform_regs(id)\
193 XFM_COMMON_REG_LIST_DCE80(id)\
196 static const struct dce_transform_registers xfm_regs[] = {
205 static const struct dce_transform_shift xfm_shift = {
206 XFM_COMMON_MASK_SH_LIST_DCE80(__SHIFT)
209 static const struct dce_transform_mask xfm_mask = {
210 XFM_COMMON_MASK_SH_LIST_DCE80(_MASK)
213 #define aux_regs(id)\
218 static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
227 #define hpd_regs(id)\
232 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
241 #define link_regs(id)\
243 LE_DCE80_REG_LIST(id)\
246 static const struct dce110_link_enc_registers link_enc_regs[] = {
256 #define stream_enc_regs(id)\
258 SE_COMMON_REG_LIST_DCE_BASE(id),\
262 static const struct dce110_stream_enc_registers stream_enc_regs[] = {
272 static const struct dce_stream_encoder_shift se_shift = {
273 SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT)
276 static const struct dce_stream_encoder_mask se_mask = {
277 SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK)
280 #define opp_regs(id)\
282 OPP_DCE_80_REG_LIST(id),\
285 static const struct dce_opp_registers opp_regs[] = {
294 static const struct dce_opp_shift opp_shift = {
295 OPP_COMMON_MASK_SH_LIST_DCE_80(__SHIFT)
298 static const struct dce_opp_mask opp_mask = {
299 OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK)
302 #define aux_engine_regs(id)\
304 AUX_COMMON_REG_LIST(id), \
305 .AUX_RESET_MASK = 0 \
308 static const struct dce110_aux_registers aux_engine_regs[] = {
317 #define audio_regs(id)\
319 AUD_COMMON_REG_LIST(id)\
322 static const struct dce_audio_registers audio_regs[] = {
332 static const struct dce_audio_shift audio_shift = {
333 AUD_COMMON_MASK_SH_LIST(__SHIFT)
336 static const struct dce_aduio_mask audio_mask = {
337 AUD_COMMON_MASK_SH_LIST(_MASK)
340 #define clk_src_regs(id)\
342 CS_COMMON_REG_LIST_DCE_80(id),\
346 static const struct dce110_clk_src_regs clk_src_regs[] = {
352 static const struct dce110_clk_src_shift cs_shift = {
353 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
356 static const struct dce110_clk_src_mask cs_mask = {
357 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
360 static const struct bios_registers bios_regs = {
361 .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
364 static const struct resource_caps res_cap = {
365 .num_timing_generator = 6,
367 .num_stream_encoder = 6,
372 static const struct resource_caps res_cap_81 = {
373 .num_timing_generator = 4,
375 .num_stream_encoder = 7,
380 static const struct resource_caps res_cap_83 = {
381 .num_timing_generator = 2,
383 .num_stream_encoder = 6,
388 static const struct dce_dmcu_registers dmcu_regs = {
389 DMCU_DCE80_REG_LIST()
392 static const struct dce_dmcu_shift dmcu_shift = {
393 DMCU_MASK_SH_LIST_DCE80(__SHIFT)
396 static const struct dce_dmcu_mask dmcu_mask = {
397 DMCU_MASK_SH_LIST_DCE80(_MASK)
399 static const struct dce_abm_registers abm_regs = {
400 ABM_DCE110_COMMON_REG_LIST()
403 static const struct dce_abm_shift abm_shift = {
404 ABM_MASK_SH_LIST_DCE110(__SHIFT)
407 static const struct dce_abm_mask abm_mask = {
408 ABM_MASK_SH_LIST_DCE110(_MASK)
412 #define REG(reg) mm ## reg
414 #ifndef mmCC_DC_HDMI_STRAPS
415 #define mmCC_DC_HDMI_STRAPS 0x1918
416 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
417 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
418 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
419 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
422 static void read_dce_straps(
423 struct dc_context *ctx,
424 struct resource_straps *straps)
426 REG_GET_2(CC_DC_HDMI_STRAPS,
427 HDMI_DISABLE, &straps->hdmi_disable,
428 AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
430 REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
433 static struct audio *create_audio(
434 struct dc_context *ctx, unsigned int inst)
436 return dce_audio_create(ctx, inst,
437 &audio_regs[inst], &audio_shift, &audio_mask);
440 static struct timing_generator *dce80_timing_generator_create(
441 struct dc_context *ctx,
443 const struct dce110_timing_generator_offsets *offsets)
445 struct dce110_timing_generator *tg110 =
446 kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
451 dce80_timing_generator_construct(tg110, ctx, instance, offsets);
455 static struct output_pixel_processor *dce80_opp_create(
456 struct dc_context *ctx,
459 struct dce110_opp *opp =
460 kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
465 dce110_opp_construct(opp,
466 ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
470 struct aux_engine *dce80_aux_engine_create(
471 struct dc_context *ctx,
474 struct aux_engine_dce110 *aux_engine =
475 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
480 dce110_aux_engine_construct(aux_engine, ctx, inst,
481 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
482 &aux_engine_regs[inst]);
484 return &aux_engine->base;
486 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
488 static const struct dce_i2c_registers i2c_hw_regs[] = {
497 static const struct dce_i2c_shift i2c_shifts = {
498 I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
501 static const struct dce_i2c_mask i2c_masks = {
502 I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
505 struct dce_i2c_hw *dce80_i2c_hw_create(
506 struct dc_context *ctx,
509 struct dce_i2c_hw *dce_i2c_hw =
510 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
515 dce_i2c_hw_construct(dce_i2c_hw, ctx, inst,
516 &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
521 struct dce_i2c_sw *dce80_i2c_sw_create(
522 struct dc_context *ctx)
524 struct dce_i2c_sw *dce_i2c_sw =
525 kzalloc(sizeof(struct dce_i2c_sw), GFP_KERNEL);
530 dce_i2c_sw_construct(dce_i2c_sw, ctx);
534 static struct stream_encoder *dce80_stream_encoder_create(
535 enum engine_id eng_id,
536 struct dc_context *ctx)
538 struct dce110_stream_encoder *enc110 =
539 kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
544 dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
545 &stream_enc_regs[eng_id],
546 &se_shift, &se_mask);
547 return &enc110->base;
550 #define SRII(reg_name, block, id)\
551 .reg_name[id] = mm ## block ## id ## _ ## reg_name
553 static const struct dce_hwseq_registers hwseq_reg = {
554 HWSEQ_DCE8_REG_LIST()
557 static const struct dce_hwseq_shift hwseq_shift = {
558 HWSEQ_DCE8_MASK_SH_LIST(__SHIFT)
561 static const struct dce_hwseq_mask hwseq_mask = {
562 HWSEQ_DCE8_MASK_SH_LIST(_MASK)
565 static struct dce_hwseq *dce80_hwseq_create(
566 struct dc_context *ctx)
568 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
572 hws->regs = &hwseq_reg;
573 hws->shifts = &hwseq_shift;
574 hws->masks = &hwseq_mask;
579 static const struct resource_create_funcs res_create_funcs = {
580 .read_dce_straps = read_dce_straps,
581 .create_audio = create_audio,
582 .create_stream_encoder = dce80_stream_encoder_create,
583 .create_hwseq = dce80_hwseq_create,
586 #define mi_inst_regs(id) { \
587 MI_DCE8_REG_LIST(id), \
588 .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
590 static const struct dce_mem_input_registers mi_regs[] = {
599 static const struct dce_mem_input_shift mi_shifts = {
600 MI_DCE8_MASK_SH_LIST(__SHIFT),
601 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
604 static const struct dce_mem_input_mask mi_masks = {
605 MI_DCE8_MASK_SH_LIST(_MASK),
606 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
609 static struct mem_input *dce80_mem_input_create(
610 struct dc_context *ctx,
613 struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
621 dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
622 dce_mi->wa.single_head_rdreq_dmif_limit = 2;
623 return &dce_mi->base;
626 static void dce80_transform_destroy(struct transform **xfm)
628 kfree(TO_DCE_TRANSFORM(*xfm));
632 static struct transform *dce80_transform_create(
633 struct dc_context *ctx,
636 struct dce_transform *transform =
637 kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
642 dce_transform_construct(transform, ctx, inst,
643 &xfm_regs[inst], &xfm_shift, &xfm_mask);
644 transform->prescaler_on = false;
645 return &transform->base;
648 static const struct encoder_feature_support link_enc_feature = {
649 .max_hdmi_deep_color = COLOR_DEPTH_121212,
650 .max_hdmi_pixel_clock = 297000,
651 .flags.bits.IS_HBR2_CAPABLE = true,
652 .flags.bits.IS_TPS3_CAPABLE = true
655 struct link_encoder *dce80_link_encoder_create(
656 const struct encoder_init_data *enc_init_data)
658 struct dce110_link_encoder *enc110 =
659 kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
664 dce110_link_encoder_construct(enc110,
667 &link_enc_regs[enc_init_data->transmitter],
668 &link_enc_aux_regs[enc_init_data->channel - 1],
669 &link_enc_hpd_regs[enc_init_data->hpd_source]);
670 return &enc110->base;
673 struct clock_source *dce80_clock_source_create(
674 struct dc_context *ctx,
675 struct dc_bios *bios,
676 enum clock_source_id id,
677 const struct dce110_clk_src_regs *regs,
680 struct dce110_clk_src *clk_src =
681 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
686 if (dce110_clk_src_construct(clk_src, ctx, bios, id,
687 regs, &cs_shift, &cs_mask)) {
688 clk_src->base.dp_clk_src = dp_clk_src;
689 return &clk_src->base;
696 void dce80_clock_source_destroy(struct clock_source **clk_src)
698 kfree(TO_DCE110_CLK_SRC(*clk_src));
702 static struct input_pixel_processor *dce80_ipp_create(
703 struct dc_context *ctx, uint32_t inst)
705 struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
712 dce_ipp_construct(ipp, ctx, inst,
713 &ipp_regs[inst], &ipp_shift, &ipp_mask);
717 static void destruct(struct dce110_resource_pool *pool)
721 for (i = 0; i < pool->base.pipe_count; i++) {
722 if (pool->base.opps[i] != NULL)
723 dce110_opp_destroy(&pool->base.opps[i]);
725 if (pool->base.transforms[i] != NULL)
726 dce80_transform_destroy(&pool->base.transforms[i]);
728 if (pool->base.ipps[i] != NULL)
729 dce_ipp_destroy(&pool->base.ipps[i]);
731 if (pool->base.mis[i] != NULL) {
732 kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
733 pool->base.mis[i] = NULL;
736 if (pool->base.timing_generators[i] != NULL) {
737 kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
738 pool->base.timing_generators[i] = NULL;
742 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
743 if (pool->base.engines[i] != NULL)
744 dce110_engine_destroy(&pool->base.engines[i]);
745 if (pool->base.hw_i2cs[i] != NULL) {
746 kfree(pool->base.hw_i2cs[i]);
747 pool->base.hw_i2cs[i] = NULL;
749 if (pool->base.sw_i2cs[i] != NULL) {
750 kfree(pool->base.sw_i2cs[i]);
751 pool->base.sw_i2cs[i] = NULL;
755 for (i = 0; i < pool->base.stream_enc_count; i++) {
756 if (pool->base.stream_enc[i] != NULL)
757 kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
760 for (i = 0; i < pool->base.clk_src_count; i++) {
761 if (pool->base.clock_sources[i] != NULL) {
762 dce80_clock_source_destroy(&pool->base.clock_sources[i]);
766 if (pool->base.abm != NULL)
767 dce_abm_destroy(&pool->base.abm);
769 if (pool->base.dmcu != NULL)
770 dce_dmcu_destroy(&pool->base.dmcu);
772 if (pool->base.dp_clock_source != NULL)
773 dce80_clock_source_destroy(&pool->base.dp_clock_source);
775 for (i = 0; i < pool->base.audio_count; i++) {
776 if (pool->base.audios[i] != NULL) {
777 dce_aud_destroy(&pool->base.audios[i]);
781 if (pool->base.clk_mgr != NULL)
782 dce_clk_mgr_destroy(&pool->base.clk_mgr);
784 if (pool->base.irqs != NULL) {
785 dal_irq_service_destroy(&pool->base.irqs);
789 bool dce80_validate_bandwidth(
791 struct dc_state *context)
794 bool at_least_one_pipe = false;
796 for (i = 0; i < dc->res_pool->pipe_count; i++) {
797 if (context->res_ctx.pipe_ctx[i].stream)
798 at_least_one_pipe = true;
801 if (at_least_one_pipe) {
802 /* TODO implement when needed but for now hardcode max value*/
803 context->bw.dce.dispclk_khz = 681000;
804 context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ;
806 context->bw.dce.dispclk_khz = 0;
807 context->bw.dce.yclk_khz = 0;
813 static bool dce80_validate_surface_sets(
814 struct dc_state *context)
818 for (i = 0; i < context->stream_count; i++) {
819 if (context->stream_status[i].plane_count == 0)
822 if (context->stream_status[i].plane_count > 1)
825 if (context->stream_status[i].plane_states[0]->format
826 >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
833 enum dc_status dce80_validate_global(
835 struct dc_state *context)
837 if (!dce80_validate_surface_sets(context))
838 return DC_FAIL_SURFACE_VALIDATE;
843 static void dce80_destroy_resource_pool(struct resource_pool **pool)
845 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
847 destruct(dce110_pool);
852 static const struct resource_funcs dce80_res_pool_funcs = {
853 .destroy = dce80_destroy_resource_pool,
854 .link_enc_create = dce80_link_encoder_create,
855 .validate_bandwidth = dce80_validate_bandwidth,
856 .validate_plane = dce100_validate_plane,
857 .add_stream_to_ctx = dce100_add_stream_to_ctx,
858 .validate_global = dce80_validate_global
861 static bool dce80_construct(
862 uint8_t num_virtual_links,
864 struct dce110_resource_pool *pool)
867 struct dc_context *ctx = dc->ctx;
868 struct dc_firmware_info info;
871 ctx->dc_bios->regs = &bios_regs;
873 pool->base.res_cap = &res_cap;
874 pool->base.funcs = &dce80_res_pool_funcs;
877 /*************************************************
878 * Resource + asic cap harcoding *
879 *************************************************/
880 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
881 pool->base.pipe_count = res_cap.num_timing_generator;
882 pool->base.timing_generator_count = res_cap.num_timing_generator;
883 dc->caps.max_downscale_ratio = 200;
884 dc->caps.i2c_speed_in_khz = 40;
885 dc->caps.max_cursor_size = 128;
886 dc->caps.dual_link_dvi = true;
888 /*************************************************
890 *************************************************/
894 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
895 info.external_clock_source_frequency_for_dp != 0) {
896 pool->base.dp_clock_source =
897 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
899 pool->base.clock_sources[0] =
900 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
901 pool->base.clock_sources[1] =
902 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
903 pool->base.clock_sources[2] =
904 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
905 pool->base.clk_src_count = 3;
908 pool->base.dp_clock_source =
909 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
911 pool->base.clock_sources[0] =
912 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
913 pool->base.clock_sources[1] =
914 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
915 pool->base.clk_src_count = 2;
918 if (pool->base.dp_clock_source == NULL) {
919 dm_error("DC: failed to create dp clock source!\n");
921 goto res_create_fail;
924 for (i = 0; i < pool->base.clk_src_count; i++) {
925 if (pool->base.clock_sources[i] == NULL) {
926 dm_error("DC: failed to create clock sources!\n");
928 goto res_create_fail;
932 pool->base.clk_mgr = dce_clk_mgr_create(ctx,
936 if (pool->base.clk_mgr == NULL) {
937 dm_error("DC: failed to create display clock!\n");
939 goto res_create_fail;
942 pool->base.dmcu = dce_dmcu_create(ctx,
946 if (pool->base.dmcu == NULL) {
947 dm_error("DC: failed to create dmcu!\n");
949 goto res_create_fail;
952 pool->base.abm = dce_abm_create(ctx,
956 if (pool->base.abm == NULL) {
957 dm_error("DC: failed to create abm!\n");
959 goto res_create_fail;
963 struct irq_service_init_data init_data;
964 init_data.ctx = dc->ctx;
965 pool->base.irqs = dal_irq_service_dce80_create(&init_data);
966 if (!pool->base.irqs)
967 goto res_create_fail;
970 for (i = 0; i < pool->base.pipe_count; i++) {
971 pool->base.timing_generators[i] = dce80_timing_generator_create(
972 ctx, i, &dce80_tg_offsets[i]);
973 if (pool->base.timing_generators[i] == NULL) {
975 dm_error("DC: failed to create tg!\n");
976 goto res_create_fail;
979 pool->base.mis[i] = dce80_mem_input_create(ctx, i);
980 if (pool->base.mis[i] == NULL) {
982 dm_error("DC: failed to create memory input!\n");
983 goto res_create_fail;
986 pool->base.ipps[i] = dce80_ipp_create(ctx, i);
987 if (pool->base.ipps[i] == NULL) {
989 dm_error("DC: failed to create input pixel processor!\n");
990 goto res_create_fail;
993 pool->base.transforms[i] = dce80_transform_create(ctx, i);
994 if (pool->base.transforms[i] == NULL) {
996 dm_error("DC: failed to create transform!\n");
997 goto res_create_fail;
1000 pool->base.opps[i] = dce80_opp_create(ctx, i);
1001 if (pool->base.opps[i] == NULL) {
1002 BREAK_TO_DEBUGGER();
1003 dm_error("DC: failed to create output pixel processor!\n");
1004 goto res_create_fail;
1008 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1009 pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
1010 if (pool->base.engines[i] == NULL) {
1011 BREAK_TO_DEBUGGER();
1013 "DC:failed to create aux engine!!\n");
1014 goto res_create_fail;
1016 pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
1017 if (pool->base.hw_i2cs[i] == NULL) {
1018 BREAK_TO_DEBUGGER();
1020 "DC:failed to create i2c engine!!\n");
1021 goto res_create_fail;
1023 pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
1024 if (pool->base.sw_i2cs[i] == NULL) {
1025 BREAK_TO_DEBUGGER();
1027 "DC:failed to create sw i2c!!\n");
1028 goto res_create_fail;
1032 dc->caps.max_planes = pool->base.pipe_count;
1033 dc->caps.disable_dp_clk_share = true;
1035 if (!resource_construct(num_virtual_links, dc, &pool->base,
1037 goto res_create_fail;
1039 /* Create hardware sequencer */
1040 dce80_hw_sequencer_construct(dc);
1049 struct resource_pool *dce80_create_resource_pool(
1050 uint8_t num_virtual_links,
1053 struct dce110_resource_pool *pool =
1054 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1059 if (dce80_construct(num_virtual_links, dc, pool))
1062 BREAK_TO_DEBUGGER();
1066 static bool dce81_construct(
1067 uint8_t num_virtual_links,
1069 struct dce110_resource_pool *pool)
1072 struct dc_context *ctx = dc->ctx;
1073 struct dc_firmware_info info;
1076 ctx->dc_bios->regs = &bios_regs;
1078 pool->base.res_cap = &res_cap_81;
1079 pool->base.funcs = &dce80_res_pool_funcs;
1082 /*************************************************
1083 * Resource + asic cap harcoding *
1084 *************************************************/
1085 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1086 pool->base.pipe_count = res_cap_81.num_timing_generator;
1087 pool->base.timing_generator_count = res_cap_81.num_timing_generator;
1088 dc->caps.max_downscale_ratio = 200;
1089 dc->caps.i2c_speed_in_khz = 40;
1090 dc->caps.max_cursor_size = 128;
1091 dc->caps.is_apu = true;
1093 /*************************************************
1094 * Create resources *
1095 *************************************************/
1099 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
1100 info.external_clock_source_frequency_for_dp != 0) {
1101 pool->base.dp_clock_source =
1102 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1104 pool->base.clock_sources[0] =
1105 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
1106 pool->base.clock_sources[1] =
1107 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1108 pool->base.clock_sources[2] =
1109 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1110 pool->base.clk_src_count = 3;
1113 pool->base.dp_clock_source =
1114 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
1116 pool->base.clock_sources[0] =
1117 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1118 pool->base.clock_sources[1] =
1119 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1120 pool->base.clk_src_count = 2;
1123 if (pool->base.dp_clock_source == NULL) {
1124 dm_error("DC: failed to create dp clock source!\n");
1125 BREAK_TO_DEBUGGER();
1126 goto res_create_fail;
1129 for (i = 0; i < pool->base.clk_src_count; i++) {
1130 if (pool->base.clock_sources[i] == NULL) {
1131 dm_error("DC: failed to create clock sources!\n");
1132 BREAK_TO_DEBUGGER();
1133 goto res_create_fail;
1137 pool->base.clk_mgr = dce_clk_mgr_create(ctx,
1141 if (pool->base.clk_mgr == NULL) {
1142 dm_error("DC: failed to create display clock!\n");
1143 BREAK_TO_DEBUGGER();
1144 goto res_create_fail;
1147 pool->base.dmcu = dce_dmcu_create(ctx,
1151 if (pool->base.dmcu == NULL) {
1152 dm_error("DC: failed to create dmcu!\n");
1153 BREAK_TO_DEBUGGER();
1154 goto res_create_fail;
1157 pool->base.abm = dce_abm_create(ctx,
1161 if (pool->base.abm == NULL) {
1162 dm_error("DC: failed to create abm!\n");
1163 BREAK_TO_DEBUGGER();
1164 goto res_create_fail;
1168 struct irq_service_init_data init_data;
1169 init_data.ctx = dc->ctx;
1170 pool->base.irqs = dal_irq_service_dce80_create(&init_data);
1171 if (!pool->base.irqs)
1172 goto res_create_fail;
1175 for (i = 0; i < pool->base.pipe_count; i++) {
1176 pool->base.timing_generators[i] = dce80_timing_generator_create(
1177 ctx, i, &dce80_tg_offsets[i]);
1178 if (pool->base.timing_generators[i] == NULL) {
1179 BREAK_TO_DEBUGGER();
1180 dm_error("DC: failed to create tg!\n");
1181 goto res_create_fail;
1184 pool->base.mis[i] = dce80_mem_input_create(ctx, i);
1185 if (pool->base.mis[i] == NULL) {
1186 BREAK_TO_DEBUGGER();
1187 dm_error("DC: failed to create memory input!\n");
1188 goto res_create_fail;
1191 pool->base.ipps[i] = dce80_ipp_create(ctx, i);
1192 if (pool->base.ipps[i] == NULL) {
1193 BREAK_TO_DEBUGGER();
1194 dm_error("DC: failed to create input pixel processor!\n");
1195 goto res_create_fail;
1198 pool->base.transforms[i] = dce80_transform_create(ctx, i);
1199 if (pool->base.transforms[i] == NULL) {
1200 BREAK_TO_DEBUGGER();
1201 dm_error("DC: failed to create transform!\n");
1202 goto res_create_fail;
1205 pool->base.opps[i] = dce80_opp_create(ctx, i);
1206 if (pool->base.opps[i] == NULL) {
1207 BREAK_TO_DEBUGGER();
1208 dm_error("DC: failed to create output pixel processor!\n");
1209 goto res_create_fail;
1213 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1214 pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
1215 if (pool->base.engines[i] == NULL) {
1216 BREAK_TO_DEBUGGER();
1218 "DC:failed to create aux engine!!\n");
1219 goto res_create_fail;
1221 pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
1222 if (pool->base.hw_i2cs[i] == NULL) {
1223 BREAK_TO_DEBUGGER();
1225 "DC:failed to create i2c engine!!\n");
1226 goto res_create_fail;
1228 pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
1229 if (pool->base.sw_i2cs[i] == NULL) {
1230 BREAK_TO_DEBUGGER();
1232 "DC:failed to create sw i2c!!\n");
1233 goto res_create_fail;
1237 dc->caps.max_planes = pool->base.pipe_count;
1238 dc->caps.disable_dp_clk_share = true;
1240 if (!resource_construct(num_virtual_links, dc, &pool->base,
1242 goto res_create_fail;
1244 /* Create hardware sequencer */
1245 dce80_hw_sequencer_construct(dc);
1254 struct resource_pool *dce81_create_resource_pool(
1255 uint8_t num_virtual_links,
1258 struct dce110_resource_pool *pool =
1259 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1264 if (dce81_construct(num_virtual_links, dc, pool))
1267 BREAK_TO_DEBUGGER();
1271 static bool dce83_construct(
1272 uint8_t num_virtual_links,
1274 struct dce110_resource_pool *pool)
1277 struct dc_context *ctx = dc->ctx;
1278 struct dc_firmware_info info;
1281 ctx->dc_bios->regs = &bios_regs;
1283 pool->base.res_cap = &res_cap_83;
1284 pool->base.funcs = &dce80_res_pool_funcs;
1287 /*************************************************
1288 * Resource + asic cap harcoding *
1289 *************************************************/
1290 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1291 pool->base.pipe_count = res_cap_83.num_timing_generator;
1292 pool->base.timing_generator_count = res_cap_83.num_timing_generator;
1293 dc->caps.max_downscale_ratio = 200;
1294 dc->caps.i2c_speed_in_khz = 40;
1295 dc->caps.max_cursor_size = 128;
1296 dc->caps.is_apu = true;
1298 /*************************************************
1299 * Create resources *
1300 *************************************************/
1304 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
1305 info.external_clock_source_frequency_for_dp != 0) {
1306 pool->base.dp_clock_source =
1307 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1309 pool->base.clock_sources[0] =
1310 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], false);
1311 pool->base.clock_sources[1] =
1312 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false);
1313 pool->base.clk_src_count = 2;
1316 pool->base.dp_clock_source =
1317 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], true);
1319 pool->base.clock_sources[0] =
1320 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false);
1321 pool->base.clk_src_count = 1;
1324 if (pool->base.dp_clock_source == NULL) {
1325 dm_error("DC: failed to create dp clock source!\n");
1326 BREAK_TO_DEBUGGER();
1327 goto res_create_fail;
1330 for (i = 0; i < pool->base.clk_src_count; i++) {
1331 if (pool->base.clock_sources[i] == NULL) {
1332 dm_error("DC: failed to create clock sources!\n");
1333 BREAK_TO_DEBUGGER();
1334 goto res_create_fail;
1338 pool->base.clk_mgr = dce_clk_mgr_create(ctx,
1342 if (pool->base.clk_mgr == NULL) {
1343 dm_error("DC: failed to create display clock!\n");
1344 BREAK_TO_DEBUGGER();
1345 goto res_create_fail;
1348 pool->base.dmcu = dce_dmcu_create(ctx,
1352 if (pool->base.dmcu == NULL) {
1353 dm_error("DC: failed to create dmcu!\n");
1354 BREAK_TO_DEBUGGER();
1355 goto res_create_fail;
1358 pool->base.abm = dce_abm_create(ctx,
1362 if (pool->base.abm == NULL) {
1363 dm_error("DC: failed to create abm!\n");
1364 BREAK_TO_DEBUGGER();
1365 goto res_create_fail;
1369 struct irq_service_init_data init_data;
1370 init_data.ctx = dc->ctx;
1371 pool->base.irqs = dal_irq_service_dce80_create(&init_data);
1372 if (!pool->base.irqs)
1373 goto res_create_fail;
1376 for (i = 0; i < pool->base.pipe_count; i++) {
1377 pool->base.timing_generators[i] = dce80_timing_generator_create(
1378 ctx, i, &dce80_tg_offsets[i]);
1379 if (pool->base.timing_generators[i] == NULL) {
1380 BREAK_TO_DEBUGGER();
1381 dm_error("DC: failed to create tg!\n");
1382 goto res_create_fail;
1385 pool->base.mis[i] = dce80_mem_input_create(ctx, i);
1386 if (pool->base.mis[i] == NULL) {
1387 BREAK_TO_DEBUGGER();
1388 dm_error("DC: failed to create memory input!\n");
1389 goto res_create_fail;
1392 pool->base.ipps[i] = dce80_ipp_create(ctx, i);
1393 if (pool->base.ipps[i] == NULL) {
1394 BREAK_TO_DEBUGGER();
1395 dm_error("DC: failed to create input pixel processor!\n");
1396 goto res_create_fail;
1399 pool->base.transforms[i] = dce80_transform_create(ctx, i);
1400 if (pool->base.transforms[i] == NULL) {
1401 BREAK_TO_DEBUGGER();
1402 dm_error("DC: failed to create transform!\n");
1403 goto res_create_fail;
1406 pool->base.opps[i] = dce80_opp_create(ctx, i);
1407 if (pool->base.opps[i] == NULL) {
1408 BREAK_TO_DEBUGGER();
1409 dm_error("DC: failed to create output pixel processor!\n");
1410 goto res_create_fail;
1414 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1415 pool->base.engines[i] = dce80_aux_engine_create(ctx, i);
1416 if (pool->base.engines[i] == NULL) {
1417 BREAK_TO_DEBUGGER();
1419 "DC:failed to create aux engine!!\n");
1420 goto res_create_fail;
1422 pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i);
1423 if (pool->base.hw_i2cs[i] == NULL) {
1424 BREAK_TO_DEBUGGER();
1426 "DC:failed to create i2c engine!!\n");
1427 goto res_create_fail;
1429 pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx);
1430 if (pool->base.sw_i2cs[i] == NULL) {
1431 BREAK_TO_DEBUGGER();
1433 "DC:failed to create sw i2c!!\n");
1434 goto res_create_fail;
1438 dc->caps.max_planes = pool->base.pipe_count;
1439 dc->caps.disable_dp_clk_share = true;
1441 if (!resource_construct(num_virtual_links, dc, &pool->base,
1443 goto res_create_fail;
1445 /* Create hardware sequencer */
1446 dce80_hw_sequencer_construct(dc);
1455 struct resource_pool *dce83_create_resource_pool(
1456 uint8_t num_virtual_links,
1459 struct dce110_resource_pool *pool =
1460 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1465 if (dce83_construct(num_virtual_links, dc, pool))
1468 BREAK_TO_DEBUGGER();