1519 lines · c
1/*2 * Copyright 2020 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "dcn302/dcn302_init.h"27#include "dcn302_resource.h"28#include "dcn302/dcn302_dccg.h"29#include "irq/dcn302/irq_service_dcn302.h"30 31#include "dcn30/dcn30_dio_link_encoder.h"32#include "dcn30/dcn30_dio_stream_encoder.h"33#include "dcn30/dcn30_dwb.h"34#include "dcn30/dcn30_dpp.h"35#include "dcn30/dcn30_hubbub.h"36#include "dcn30/dcn30_hubp.h"37#include "dcn30/dcn30_mmhubbub.h"38#include "dcn30/dcn30_mpc.h"39#include "dcn30/dcn30_opp.h"40#include "dcn30/dcn30_optc.h"41#include "dcn30/dcn30_resource.h"42 43#include "dcn20/dcn20_dsc.h"44#include "dcn20/dcn20_resource.h"45 46#include "dml/dcn30/dcn30_fpu.h"47 48#include "dcn10/dcn10_resource.h"49 50#include "link.h"51#include "dce/dce_abm.h"52#include "dce/dce_audio.h"53#include "dce/dce_aux.h"54#include "dce/dce_clock_source.h"55#include "dce/dce_hwseq.h"56#include "dce/dce_i2c_hw.h"57#include "dce/dce_panel_cntl.h"58#include "dce/dmub_abm.h"59#include "dce/dmub_psr.h"60#include "clk_mgr.h"61 62#include "hw_sequencer_private.h"63#include "reg_helper.h"64#include "resource.h"65#include "vm_helper.h"66 67#include "dml/dcn302/dcn302_fpu.h"68 69#include "dimgrey_cavefish_ip_offset.h"70#include "dcn/dcn_3_0_2_offset.h"71#include "dcn/dcn_3_0_2_sh_mask.h"72#include "dpcs/dpcs_3_0_0_offset.h"73#include "dpcs/dpcs_3_0_0_sh_mask.h"74#include "nbio/nbio_7_4_offset.h"75#include "amdgpu_socbb.h"76 77#define DC_LOGGER \78 dc->ctx->logger79#define DC_LOGGER_INIT(logger)80 81static const struct dc_debug_options debug_defaults_drv = {82 .disable_dmcu = true,83 .force_abm_enable = false,84 .timing_trace = false,85 .clock_trace = true,86 .disable_pplib_clock_request = true,87 .pipe_split_policy = MPC_SPLIT_DYNAMIC,88 .force_single_disp_pipe_split = false,89 .disable_dcc = DCC_ENABLE,90 .vsr_support = true,91 .performance_trace = false,92 .max_downscale_src_width = 7680,/*upto 8K*/93 .disable_pplib_wm_range = false,94 .scl_reset_length10 = true,95 .sanity_checks = false,96 .underflow_assert_delay_us = 0xFFFFFFFF,97 .dwb_fi_phase = -1, // -1 = disable,98 .dmub_command_table = true,99 .use_max_lb = true,100 .exit_idle_opt_for_cursor_updates = true,101 .enable_legacy_fast_update = false,102 .using_dml2 = false,103};104 105static const struct dc_panel_config panel_config_defaults = {106 .psr = {107 .disable_psr = false,108 .disallow_psrsu = false,109 .disallow_replay = false,110 },111};112 113enum dcn302_clk_src_array_id {114 DCN302_CLK_SRC_PLL0,115 DCN302_CLK_SRC_PLL1,116 DCN302_CLK_SRC_PLL2,117 DCN302_CLK_SRC_PLL3,118 DCN302_CLK_SRC_PLL4,119 DCN302_CLK_SRC_TOTAL120};121 122static const struct resource_caps res_cap_dcn302 = {123 .num_timing_generator = 5,124 .num_opp = 5,125 .num_video_plane = 5,126 .num_audio = 5,127 .num_stream_encoder = 5,128 .num_dwb = 1,129 .num_ddc = 5,130 .num_vmid = 16,131 .num_mpc_3dlut = 2,132 .num_dsc = 5,133};134 135static const struct dc_plane_cap plane_cap = {136 .type = DC_PLANE_TYPE_DCN_UNIVERSAL,137 .per_pixel_alpha = true,138 .pixel_format_support = {139 .argb8888 = true,140 .nv12 = true,141 .fp16 = true,142 .p010 = true,143 .ayuv = false,144 },145 .max_upscale_factor = {146 .argb8888 = 16000,147 .nv12 = 16000,148 .fp16 = 16000149 },150 /* 6:1 downscaling ratio: 1000/6 = 166.666 */151 .max_downscale_factor = {152 .argb8888 = 167,153 .nv12 = 167,154 .fp16 = 167155 },156 16,157 16158};159 160/* NBIO */161#define NBIO_BASE_INNER(seg) \162 NBIO_BASE__INST0_SEG ## seg163 164#define NBIO_BASE(seg) \165 NBIO_BASE_INNER(seg)166 167#define NBIO_SR(reg_name)\168 .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \169 mm ## reg_name170 171/* DCN */172#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg173 174#define BASE(seg) BASE_INNER(seg)175 176#define SR(reg_name)\177 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name178 179#define SF(reg_name, field_name, post_fix)\180 .field_name = reg_name ## __ ## field_name ## post_fix181 182#define SRI(reg_name, block, id)\183 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + mm ## block ## id ## _ ## reg_name184 185#define SRI2(reg_name, block, id)\186 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name187 188#define SRII(reg_name, block, id)\189 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \190 mm ## block ## id ## _ ## reg_name191 192#define DCCG_SRII(reg_name, block, id)\193 .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \194 mm ## block ## id ## _ ## reg_name195 196#define VUPDATE_SRII(reg_name, block, id)\197 .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \198 mm ## reg_name ## _ ## block ## id199 200#define SRII_DWB(reg_name, temp_name, block, id)\201 .reg_name[id] = BASE(mm ## block ## id ## _ ## temp_name ## _BASE_IDX) + \202 mm ## block ## id ## _ ## temp_name203 204#define SF_DWB2(reg_name, block, id, field_name, post_fix) \205 .field_name = reg_name ## __ ## field_name ## post_fix206 207#define SRII_MPC_RMU(reg_name, block, id)\208 .RMU##_##reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \209 mm ## block ## id ## _ ## reg_name210 211static const struct dcn_hubbub_registers hubbub_reg = {212 HUBBUB_REG_LIST_DCN30(0)213};214 215static const struct dcn_hubbub_shift hubbub_shift = {216 HUBBUB_MASK_SH_LIST_DCN30(__SHIFT)217};218 219static const struct dcn_hubbub_mask hubbub_mask = {220 HUBBUB_MASK_SH_LIST_DCN30(_MASK)221};222 223#define vmid_regs(id)\224 [id] = { DCN20_VMID_REG_LIST(id) }225 226static const struct dcn_vmid_registers vmid_regs[] = {227 vmid_regs(0),228 vmid_regs(1),229 vmid_regs(2),230 vmid_regs(3),231 vmid_regs(4),232 vmid_regs(5),233 vmid_regs(6),234 vmid_regs(7),235 vmid_regs(8),236 vmid_regs(9),237 vmid_regs(10),238 vmid_regs(11),239 vmid_regs(12),240 vmid_regs(13),241 vmid_regs(14),242 vmid_regs(15)243};244 245static const struct dcn20_vmid_shift vmid_shifts = {246 DCN20_VMID_MASK_SH_LIST(__SHIFT)247};248 249static const struct dcn20_vmid_mask vmid_masks = {250 DCN20_VMID_MASK_SH_LIST(_MASK)251};252 253static struct hubbub *dcn302_hubbub_create(struct dc_context *ctx)254{255 int i;256 257 struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), GFP_KERNEL);258 259 if (!hubbub3)260 return NULL;261 262 hubbub3_construct(hubbub3, ctx, &hubbub_reg, &hubbub_shift, &hubbub_mask);263 264 for (i = 0; i < res_cap_dcn302.num_vmid; i++) {265 struct dcn20_vmid *vmid = &hubbub3->vmid[i];266 267 vmid->ctx = ctx;268 269 vmid->regs = &vmid_regs[i];270 vmid->shifts = &vmid_shifts;271 vmid->masks = &vmid_masks;272 }273 274 return &hubbub3->base;275}276 277#define vpg_regs(id)\278 [id] = { VPG_DCN3_REG_LIST(id) }279 280static const struct dcn30_vpg_registers vpg_regs[] = {281 vpg_regs(0),282 vpg_regs(1),283 vpg_regs(2),284 vpg_regs(3),285 vpg_regs(4),286 vpg_regs(5)287};288 289static const struct dcn30_vpg_shift vpg_shift = {290 DCN3_VPG_MASK_SH_LIST(__SHIFT)291};292 293static const struct dcn30_vpg_mask vpg_mask = {294 DCN3_VPG_MASK_SH_LIST(_MASK)295};296 297static struct vpg *dcn302_vpg_create(struct dc_context *ctx, uint32_t inst)298{299 struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL);300 301 if (!vpg3)302 return NULL;303 304 vpg3_construct(vpg3, ctx, inst, &vpg_regs[inst], &vpg_shift, &vpg_mask);305 306 return &vpg3->base;307}308 309#define afmt_regs(id)\310 [id] = { AFMT_DCN3_REG_LIST(id) }311 312static const struct dcn30_afmt_registers afmt_regs[] = {313 afmt_regs(0),314 afmt_regs(1),315 afmt_regs(2),316 afmt_regs(3),317 afmt_regs(4),318 afmt_regs(5)319};320 321static const struct dcn30_afmt_shift afmt_shift = {322 DCN3_AFMT_MASK_SH_LIST(__SHIFT)323};324 325static const struct dcn30_afmt_mask afmt_mask = {326 DCN3_AFMT_MASK_SH_LIST(_MASK)327};328 329static struct afmt *dcn302_afmt_create(struct dc_context *ctx, uint32_t inst)330{331 struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL);332 333 if (!afmt3)334 return NULL;335 336 afmt3_construct(afmt3, ctx, inst, &afmt_regs[inst], &afmt_shift, &afmt_mask);337 338 return &afmt3->base;339}340 341#define audio_regs(id)\342 [id] = { AUD_COMMON_REG_LIST(id) }343 344static const struct dce_audio_registers audio_regs[] = {345 audio_regs(0),346 audio_regs(1),347 audio_regs(2),348 audio_regs(3),349 audio_regs(4),350 audio_regs(5),351 audio_regs(6)352};353 354#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\355 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\356 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\357 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)358 359static const struct dce_audio_shift audio_shift = {360 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)361};362 363static const struct dce_audio_mask audio_mask = {364 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)365};366 367static struct audio *dcn302_create_audio(struct dc_context *ctx, unsigned int inst)368{369 return dce_audio_create(ctx, inst, &audio_regs[inst], &audio_shift, &audio_mask);370}371 372#define stream_enc_regs(id)\373 [id] = { SE_DCN3_REG_LIST(id) }374 375static const struct dcn10_stream_enc_registers stream_enc_regs[] = {376 stream_enc_regs(0),377 stream_enc_regs(1),378 stream_enc_regs(2),379 stream_enc_regs(3),380 stream_enc_regs(4)381};382 383static const struct dcn10_stream_encoder_shift se_shift = {384 SE_COMMON_MASK_SH_LIST_DCN30(__SHIFT)385};386 387static const struct dcn10_stream_encoder_mask se_mask = {388 SE_COMMON_MASK_SH_LIST_DCN30(_MASK)389};390 391static struct stream_encoder *dcn302_stream_encoder_create(enum engine_id eng_id, struct dc_context *ctx)392{393 struct dcn10_stream_encoder *enc1;394 struct vpg *vpg;395 struct afmt *afmt;396 int vpg_inst;397 int afmt_inst;398 399 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */400 if (eng_id <= ENGINE_ID_DIGE) {401 vpg_inst = eng_id;402 afmt_inst = eng_id;403 } else404 return NULL;405 406 enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);407 vpg = dcn302_vpg_create(ctx, vpg_inst);408 afmt = dcn302_afmt_create(ctx, afmt_inst);409 410 if (!enc1 || !vpg || !afmt) {411 kfree(enc1);412 kfree(vpg);413 kfree(afmt);414 return NULL;415 }416 417 dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, &stream_enc_regs[eng_id],418 &se_shift, &se_mask);419 420 return &enc1->base;421}422 423#define clk_src_regs(index, pllid)\424 [index] = { CS_COMMON_REG_LIST_DCN3_02(index, pllid) }425 426static const struct dce110_clk_src_regs clk_src_regs[] = {427 clk_src_regs(0, A),428 clk_src_regs(1, B),429 clk_src_regs(2, C),430 clk_src_regs(3, D),431 clk_src_regs(4, E)432};433 434static const struct dce110_clk_src_shift cs_shift = {435 CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)436};437 438static const struct dce110_clk_src_mask cs_mask = {439 CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)440};441 442static struct clock_source *dcn302_clock_source_create(struct dc_context *ctx, struct dc_bios *bios,443 enum clock_source_id id, const struct dce110_clk_src_regs *regs, bool dp_clk_src)444{445 struct dce110_clk_src *clk_src = kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);446 447 if (!clk_src)448 return NULL;449 450 if (dcn3_clk_src_construct(clk_src, ctx, bios, id, regs, &cs_shift, &cs_mask)) {451 clk_src->base.dp_clk_src = dp_clk_src;452 return &clk_src->base;453 }454 455 kfree(clk_src);456 BREAK_TO_DEBUGGER();457 return NULL;458}459 460static const struct dce_hwseq_registers hwseq_reg = {461 HWSEQ_DCN302_REG_LIST()462};463 464static const struct dce_hwseq_shift hwseq_shift = {465 HWSEQ_DCN302_MASK_SH_LIST(__SHIFT)466};467 468static const struct dce_hwseq_mask hwseq_mask = {469 HWSEQ_DCN302_MASK_SH_LIST(_MASK)470};471 472static struct dce_hwseq *dcn302_hwseq_create(struct dc_context *ctx)473{474 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);475 476 if (hws) {477 hws->ctx = ctx;478 hws->regs = &hwseq_reg;479 hws->shifts = &hwseq_shift;480 hws->masks = &hwseq_mask;481 }482 return hws;483}484 485#define hubp_regs(id)\486 [id] = { HUBP_REG_LIST_DCN30(id) }487 488static const struct dcn_hubp2_registers hubp_regs[] = {489 hubp_regs(0),490 hubp_regs(1),491 hubp_regs(2),492 hubp_regs(3),493 hubp_regs(4)494};495 496static const struct dcn_hubp2_shift hubp_shift = {497 HUBP_MASK_SH_LIST_DCN30(__SHIFT)498};499 500static const struct dcn_hubp2_mask hubp_mask = {501 HUBP_MASK_SH_LIST_DCN30(_MASK)502};503 504static struct hubp *dcn302_hubp_create(struct dc_context *ctx, uint32_t inst)505{506 struct dcn20_hubp *hubp2 = kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);507 508 if (!hubp2)509 return NULL;510 511 if (hubp3_construct(hubp2, ctx, inst, &hubp_regs[inst], &hubp_shift, &hubp_mask))512 return &hubp2->base;513 514 BREAK_TO_DEBUGGER();515 kfree(hubp2);516 return NULL;517}518 519#define dpp_regs(id)\520 [id] = { DPP_REG_LIST_DCN30(id) }521 522static const struct dcn3_dpp_registers dpp_regs[] = {523 dpp_regs(0),524 dpp_regs(1),525 dpp_regs(2),526 dpp_regs(3),527 dpp_regs(4)528};529 530static const struct dcn3_dpp_shift tf_shift = {531 DPP_REG_LIST_SH_MASK_DCN30(__SHIFT)532};533 534static const struct dcn3_dpp_mask tf_mask = {535 DPP_REG_LIST_SH_MASK_DCN30(_MASK)536};537 538static struct dpp *dcn302_dpp_create(struct dc_context *ctx, uint32_t inst)539{540 struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);541 542 if (!dpp)543 return NULL;544 545 if (dpp3_construct(dpp, ctx, inst, &dpp_regs[inst], &tf_shift, &tf_mask))546 return &dpp->base;547 548 BREAK_TO_DEBUGGER();549 kfree(dpp);550 return NULL;551}552 553#define opp_regs(id)\554 [id] = { OPP_REG_LIST_DCN30(id) }555 556static const struct dcn20_opp_registers opp_regs[] = {557 opp_regs(0),558 opp_regs(1),559 opp_regs(2),560 opp_regs(3),561 opp_regs(4)562};563 564static const struct dcn20_opp_shift opp_shift = {565 OPP_MASK_SH_LIST_DCN20(__SHIFT)566};567 568static const struct dcn20_opp_mask opp_mask = {569 OPP_MASK_SH_LIST_DCN20(_MASK)570};571 572static struct output_pixel_processor *dcn302_opp_create(struct dc_context *ctx, uint32_t inst)573{574 struct dcn20_opp *opp = kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);575 576 if (!opp) {577 BREAK_TO_DEBUGGER();578 return NULL;579 }580 581 dcn20_opp_construct(opp, ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);582 return &opp->base;583}584 585#define optc_regs(id)\586 [id] = { OPTC_COMMON_REG_LIST_DCN3_0(id) }587 588static const struct dcn_optc_registers optc_regs[] = {589 optc_regs(0),590 optc_regs(1),591 optc_regs(2),592 optc_regs(3),593 optc_regs(4)594};595 596static const struct dcn_optc_shift optc_shift = {597 OPTC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)598};599 600static const struct dcn_optc_mask optc_mask = {601 OPTC_COMMON_MASK_SH_LIST_DCN30(_MASK)602};603 604static struct timing_generator *dcn302_timing_generator_create(struct dc_context *ctx, uint32_t instance)605{606 struct optc *tgn10 = kzalloc(sizeof(struct optc), GFP_KERNEL);607 608 if (!tgn10)609 return NULL;610 611 tgn10->base.inst = instance;612 tgn10->base.ctx = ctx;613 614 tgn10->tg_regs = &optc_regs[instance];615 tgn10->tg_shift = &optc_shift;616 tgn10->tg_mask = &optc_mask;617 618 dcn30_timing_generator_init(tgn10);619 620 return &tgn10->base;621}622 623static const struct dcn30_mpc_registers mpc_regs = {624 MPC_REG_LIST_DCN3_0(0),625 MPC_REG_LIST_DCN3_0(1),626 MPC_REG_LIST_DCN3_0(2),627 MPC_REG_LIST_DCN3_0(3),628 MPC_REG_LIST_DCN3_0(4),629 MPC_OUT_MUX_REG_LIST_DCN3_0(0),630 MPC_OUT_MUX_REG_LIST_DCN3_0(1),631 MPC_OUT_MUX_REG_LIST_DCN3_0(2),632 MPC_OUT_MUX_REG_LIST_DCN3_0(3),633 MPC_OUT_MUX_REG_LIST_DCN3_0(4),634 MPC_RMU_GLOBAL_REG_LIST_DCN3AG,635 MPC_RMU_REG_LIST_DCN3AG(0),636 MPC_RMU_REG_LIST_DCN3AG(1),637 MPC_RMU_REG_LIST_DCN3AG(2),638 MPC_DWB_MUX_REG_LIST_DCN3_0(0),639};640 641static const struct dcn30_mpc_shift mpc_shift = {642 MPC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)643};644 645static const struct dcn30_mpc_mask mpc_mask = {646 MPC_COMMON_MASK_SH_LIST_DCN30(_MASK)647};648 649static struct mpc *dcn302_mpc_create(struct dc_context *ctx, int num_mpcc, int num_rmu)650{651 struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), GFP_KERNEL);652 653 if (!mpc30)654 return NULL;655 656 dcn30_mpc_construct(mpc30, ctx, &mpc_regs, &mpc_shift, &mpc_mask, num_mpcc, num_rmu);657 658 return &mpc30->base;659}660 661#define dsc_regsDCN20(id)\662[id] = { DSC_REG_LIST_DCN20(id) }663 664static const struct dcn20_dsc_registers dsc_regs[] = {665 dsc_regsDCN20(0),666 dsc_regsDCN20(1),667 dsc_regsDCN20(2),668 dsc_regsDCN20(3),669 dsc_regsDCN20(4)670};671 672static const struct dcn20_dsc_shift dsc_shift = {673 DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)674};675 676static const struct dcn20_dsc_mask dsc_mask = {677 DSC_REG_LIST_SH_MASK_DCN20(_MASK)678};679 680static struct display_stream_compressor *dcn302_dsc_create(struct dc_context *ctx, uint32_t inst)681{682 struct dcn20_dsc *dsc = kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);683 684 if (!dsc) {685 BREAK_TO_DEBUGGER();686 return NULL;687 }688 689 dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);690 return &dsc->base;691}692 693#define dwbc_regs_dcn3(id)\694[id] = { DWBC_COMMON_REG_LIST_DCN30(id) }695 696static const struct dcn30_dwbc_registers dwbc30_regs[] = {697 dwbc_regs_dcn3(0)698};699 700static const struct dcn30_dwbc_shift dwbc30_shift = {701 DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)702};703 704static const struct dcn30_dwbc_mask dwbc30_mask = {705 DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)706};707 708static bool dcn302_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)709{710 int i;711 uint32_t pipe_count = pool->res_cap->num_dwb;712 713 for (i = 0; i < pipe_count; i++) {714 struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), GFP_KERNEL);715 716 if (!dwbc30) {717 dm_error("DC: failed to create dwbc30!\n");718 return false;719 }720 721 dcn30_dwbc_construct(dwbc30, ctx, &dwbc30_regs[i], &dwbc30_shift, &dwbc30_mask, i);722 723 pool->dwbc[i] = &dwbc30->base;724 }725 return true;726}727 728#define mcif_wb_regs_dcn3(id)\729[id] = { MCIF_WB_COMMON_REG_LIST_DCN30(id) }730 731static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = {732 mcif_wb_regs_dcn3(0)733};734 735static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {736 MCIF_WB_COMMON_MASK_SH_LIST_DCN30(__SHIFT)737};738 739static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {740 MCIF_WB_COMMON_MASK_SH_LIST_DCN30(_MASK)741};742 743static bool dcn302_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)744{745 int i;746 uint32_t pipe_count = pool->res_cap->num_dwb;747 748 for (i = 0; i < pipe_count; i++) {749 struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), GFP_KERNEL);750 751 if (!mcif_wb30) {752 dm_error("DC: failed to create mcif_wb30!\n");753 return false;754 }755 756 dcn30_mmhubbub_construct(mcif_wb30, ctx, &mcif_wb30_regs[i], &mcif_wb30_shift, &mcif_wb30_mask, i);757 758 pool->mcif_wb[i] = &mcif_wb30->base;759 }760 return true;761}762 763#define aux_engine_regs(id)\764[id] = {\765 AUX_COMMON_REG_LIST0(id), \766 .AUXN_IMPCAL = 0, \767 .AUXP_IMPCAL = 0, \768 .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \769}770 771static const struct dce110_aux_registers aux_engine_regs[] = {772 aux_engine_regs(0),773 aux_engine_regs(1),774 aux_engine_regs(2),775 aux_engine_regs(3),776 aux_engine_regs(4)777};778 779static const struct dce110_aux_registers_shift aux_shift = {780 DCN_AUX_MASK_SH_LIST(__SHIFT)781};782 783static const struct dce110_aux_registers_mask aux_mask = {784 DCN_AUX_MASK_SH_LIST(_MASK)785};786 787static struct dce_aux *dcn302_aux_engine_create(struct dc_context *ctx, uint32_t inst)788{789 struct aux_engine_dce110 *aux_engine = kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);790 791 if (!aux_engine)792 return NULL;793 794 dce110_aux_engine_construct(aux_engine, ctx, inst, SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,795 &aux_engine_regs[inst], &aux_mask, &aux_shift, ctx->dc->caps.extended_aux_timeout_support);796 797 return &aux_engine->base;798}799 800#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }801 802static const struct dce_i2c_registers i2c_hw_regs[] = {803 i2c_inst_regs(1),804 i2c_inst_regs(2),805 i2c_inst_regs(3),806 i2c_inst_regs(4),807 i2c_inst_regs(5)808};809 810static const struct dce_i2c_shift i2c_shifts = {811 I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT)812};813 814static const struct dce_i2c_mask i2c_masks = {815 I2C_COMMON_MASK_SH_LIST_DCN2(_MASK)816};817 818static struct dce_i2c_hw *dcn302_i2c_hw_create(struct dc_context *ctx, uint32_t inst)819{820 struct dce_i2c_hw *dce_i2c_hw = kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);821 822 if (!dce_i2c_hw)823 return NULL;824 825 dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst, &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);826 827 return dce_i2c_hw;828}829 830static const struct encoder_feature_support link_enc_feature = {831 .max_hdmi_deep_color = COLOR_DEPTH_121212,832 .max_hdmi_pixel_clock = 600000,833 .hdmi_ycbcr420_supported = true,834 .dp_ycbcr420_supported = true,835 .fec_supported = true,836 .flags.bits.IS_HBR2_CAPABLE = true,837 .flags.bits.IS_HBR3_CAPABLE = true,838 .flags.bits.IS_TPS3_CAPABLE = true,839 .flags.bits.IS_TPS4_CAPABLE = true840};841 842#define link_regs(id, phyid)\843 [id] = {\844 LE_DCN3_REG_LIST(id), \845 UNIPHY_DCN2_REG_LIST(phyid), \846 DPCS_DCN2_REG_LIST(id), \847 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \848 }849 850static const struct dcn10_link_enc_registers link_enc_regs[] = {851 link_regs(0, A),852 link_regs(1, B),853 link_regs(2, C),854 link_regs(3, D),855 link_regs(4, E)856};857 858static const struct dcn10_link_enc_shift le_shift = {859 LINK_ENCODER_MASK_SH_LIST_DCN30(__SHIFT),860 DPCS_DCN2_MASK_SH_LIST(__SHIFT)861};862 863static const struct dcn10_link_enc_mask le_mask = {864 LINK_ENCODER_MASK_SH_LIST_DCN30(_MASK),865 DPCS_DCN2_MASK_SH_LIST(_MASK)866};867 868#define aux_regs(id)\869 [id] = { DCN2_AUX_REG_LIST(id) }870 871static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {872 aux_regs(0),873 aux_regs(1),874 aux_regs(2),875 aux_regs(3),876 aux_regs(4)877};878 879#define hpd_regs(id)\880 [id] = { HPD_REG_LIST(id) }881 882static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {883 hpd_regs(0),884 hpd_regs(1),885 hpd_regs(2),886 hpd_regs(3),887 hpd_regs(4)888};889 890static struct link_encoder *dcn302_link_encoder_create(891 struct dc_context *ctx,892 const struct encoder_init_data *enc_init_data)893{894 struct dcn20_link_encoder *enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);895 896 if (!enc20)897 return NULL;898 899 dcn30_link_encoder_construct(enc20, enc_init_data, &link_enc_feature,900 &link_enc_regs[enc_init_data->transmitter], &link_enc_aux_regs[enc_init_data->channel - 1],901 &link_enc_hpd_regs[enc_init_data->hpd_source], &le_shift, &le_mask);902 903 return &enc20->enc10.base;904}905 906static const struct dce_panel_cntl_registers panel_cntl_regs[] = {907 { DCN_PANEL_CNTL_REG_LIST() }908};909 910static const struct dce_panel_cntl_shift panel_cntl_shift = {911 DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)912};913 914static const struct dce_panel_cntl_mask panel_cntl_mask = {915 DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)916};917 918static struct panel_cntl *dcn302_panel_cntl_create(const struct panel_cntl_init_data *init_data)919{920 struct dce_panel_cntl *panel_cntl = kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);921 922 if (!panel_cntl)923 return NULL;924 925 dce_panel_cntl_construct(panel_cntl, init_data, &panel_cntl_regs[init_data->inst],926 &panel_cntl_shift, &panel_cntl_mask);927 928 return &panel_cntl->base;929}930 931static void read_dce_straps(struct dc_context *ctx, struct resource_straps *straps)932{933 generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX),934 FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);935}936 937static const struct resource_create_funcs res_create_funcs = {938 .read_dce_straps = read_dce_straps,939 .create_audio = dcn302_create_audio,940 .create_stream_encoder = dcn302_stream_encoder_create,941 .create_hwseq = dcn302_hwseq_create,942};943 944static bool is_soc_bounding_box_valid(struct dc *dc)945{946 uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev;947 948 if (ASICREV_IS_DIMGREY_CAVEFISH_P(hw_internal_rev))949 return true;950 951 return false;952}953 954static bool init_soc_bounding_box(struct dc *dc, struct resource_pool *pool)955{956 struct _vcs_dpi_soc_bounding_box_st *loaded_bb = &dcn3_02_soc;957 struct _vcs_dpi_ip_params_st *loaded_ip = &dcn3_02_ip;958 959 DC_LOGGER_INIT(dc->ctx->logger);960 961 if (!is_soc_bounding_box_valid(dc)) {962 DC_LOG_ERROR("%s: not valid soc bounding box\n", __func__);963 return false;964 }965 966 loaded_ip->max_num_otg = pool->pipe_count;967 loaded_ip->max_num_dpp = pool->pipe_count;968 loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk;969 DC_FP_START();970 dcn20_patch_bounding_box(dc, loaded_bb);971 DC_FP_END();972 973 if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {974 struct bp_soc_bb_info bb_info = { 0 };975 976 if (dc->ctx->dc_bios->funcs->get_soc_bb_info(977 dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {978 979 DC_FP_START();980 dcn302_fpu_init_soc_bounding_box(bb_info);981 DC_FP_END();982 }983 }984 985 return true;986}987 988static void dcn302_resource_destruct(struct resource_pool *pool)989{990 unsigned int i;991 992 for (i = 0; i < pool->stream_enc_count; i++) {993 if (pool->stream_enc[i] != NULL) {994 if (pool->stream_enc[i]->vpg != NULL) {995 kfree(DCN30_VPG_FROM_VPG(pool->stream_enc[i]->vpg));996 pool->stream_enc[i]->vpg = NULL;997 }998 if (pool->stream_enc[i]->afmt != NULL) {999 kfree(DCN30_AFMT_FROM_AFMT(pool->stream_enc[i]->afmt));1000 pool->stream_enc[i]->afmt = NULL;1001 }1002 kfree(DCN10STRENC_FROM_STRENC(pool->stream_enc[i]));1003 pool->stream_enc[i] = NULL;1004 }1005 }1006 1007 for (i = 0; i < pool->res_cap->num_dsc; i++) {1008 if (pool->dscs[i] != NULL)1009 dcn20_dsc_destroy(&pool->dscs[i]);1010 }1011 1012 if (pool->mpc != NULL) {1013 kfree(TO_DCN20_MPC(pool->mpc));1014 pool->mpc = NULL;1015 }1016 1017 if (pool->hubbub != NULL) {1018 kfree(pool->hubbub);1019 pool->hubbub = NULL;1020 }1021 1022 for (i = 0; i < pool->pipe_count; i++) {1023 if (pool->dpps[i] != NULL) {1024 kfree(TO_DCN20_DPP(pool->dpps[i]));1025 pool->dpps[i] = NULL;1026 }1027 1028 if (pool->hubps[i] != NULL) {1029 kfree(TO_DCN20_HUBP(pool->hubps[i]));1030 pool->hubps[i] = NULL;1031 }1032 1033 if (pool->irqs != NULL)1034 dal_irq_service_destroy(&pool->irqs);1035 }1036 1037 for (i = 0; i < pool->res_cap->num_ddc; i++) {1038 if (pool->engines[i] != NULL)1039 dce110_engine_destroy(&pool->engines[i]);1040 if (pool->hw_i2cs[i] != NULL) {1041 kfree(pool->hw_i2cs[i]);1042 pool->hw_i2cs[i] = NULL;1043 }1044 if (pool->sw_i2cs[i] != NULL) {1045 kfree(pool->sw_i2cs[i]);1046 pool->sw_i2cs[i] = NULL;1047 }1048 }1049 1050 for (i = 0; i < pool->res_cap->num_opp; i++) {1051 if (pool->opps[i] != NULL)1052 pool->opps[i]->funcs->opp_destroy(&pool->opps[i]);1053 }1054 1055 for (i = 0; i < pool->res_cap->num_timing_generator; i++) {1056 if (pool->timing_generators[i] != NULL) {1057 kfree(DCN10TG_FROM_TG(pool->timing_generators[i]));1058 pool->timing_generators[i] = NULL;1059 }1060 }1061 1062 for (i = 0; i < pool->res_cap->num_dwb; i++) {1063 if (pool->dwbc[i] != NULL) {1064 kfree(TO_DCN30_DWBC(pool->dwbc[i]));1065 pool->dwbc[i] = NULL;1066 }1067 if (pool->mcif_wb[i] != NULL) {1068 kfree(TO_DCN30_MMHUBBUB(pool->mcif_wb[i]));1069 pool->mcif_wb[i] = NULL;1070 }1071 }1072 1073 for (i = 0; i < pool->audio_count; i++) {1074 if (pool->audios[i])1075 dce_aud_destroy(&pool->audios[i]);1076 }1077 1078 for (i = 0; i < pool->clk_src_count; i++) {1079 if (pool->clock_sources[i] != NULL)1080 dcn20_clock_source_destroy(&pool->clock_sources[i]);1081 }1082 1083 if (pool->dp_clock_source != NULL)1084 dcn20_clock_source_destroy(&pool->dp_clock_source);1085 1086 for (i = 0; i < pool->res_cap->num_mpc_3dlut; i++) {1087 if (pool->mpc_lut[i] != NULL) {1088 dc_3dlut_func_release(pool->mpc_lut[i]);1089 pool->mpc_lut[i] = NULL;1090 }1091 if (pool->mpc_shaper[i] != NULL) {1092 dc_transfer_func_release(pool->mpc_shaper[i]);1093 pool->mpc_shaper[i] = NULL;1094 }1095 }1096 1097 for (i = 0; i < pool->pipe_count; i++) {1098 if (pool->multiple_abms[i] != NULL)1099 dce_abm_destroy(&pool->multiple_abms[i]);1100 }1101 1102 if (pool->psr != NULL)1103 dmub_psr_destroy(&pool->psr);1104 1105 if (pool->dccg != NULL)1106 dcn_dccg_destroy(&pool->dccg);1107 1108 if (pool->oem_device != NULL) {1109 struct dc *dc = pool->oem_device->ctx->dc;1110 1111 dc->link_srv->destroy_ddc_service(&pool->oem_device);1112 }1113}1114 1115static void dcn302_destroy_resource_pool(struct resource_pool **pool)1116{1117 dcn302_resource_destruct(*pool);1118 kfree(*pool);1119 *pool = NULL;1120}1121 1122void dcn302_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)1123{1124 DC_FP_START();1125 dcn302_fpu_update_bw_bounding_box(dc, bw_params);1126 DC_FP_END();1127}1128 1129static void dcn302_get_panel_config_defaults(struct dc_panel_config *panel_config)1130{1131 *panel_config = panel_config_defaults;1132}1133 1134static struct resource_funcs dcn302_res_pool_funcs = {1135 .destroy = dcn302_destroy_resource_pool,1136 .link_enc_create = dcn302_link_encoder_create,1137 .panel_cntl_create = dcn302_panel_cntl_create,1138 .validate_bandwidth = dcn30_validate_bandwidth,1139 .calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,1140 .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,1141 .populate_dml_pipes = dcn30_populate_dml_pipes_from_context,1142 .acquire_free_pipe_as_secondary_dpp_pipe = dcn20_acquire_free_pipe_for_layer,1143 .release_pipe = dcn20_release_pipe,1144 .add_stream_to_ctx = dcn30_add_stream_to_ctx,1145 .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,1146 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,1147 .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,1148 .set_mcif_arb_params = dcn30_set_mcif_arb_params,1149 .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,1150 .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut,1151 .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,1152 .update_bw_bounding_box = dcn302_update_bw_bounding_box,1153 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,1154 .get_panel_config_defaults = dcn302_get_panel_config_defaults,1155};1156 1157static struct dc_cap_funcs cap_funcs = {1158 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap1159};1160 1161static const struct bios_registers bios_regs = {1162 NBIO_SR(BIOS_SCRATCH_3),1163 NBIO_SR(BIOS_SCRATCH_6)1164};1165 1166static const struct dccg_registers dccg_regs = {1167 DCCG_REG_LIST_DCN3_02()1168};1169 1170static const struct dccg_shift dccg_shift = {1171 DCCG_MASK_SH_LIST_DCN3_02(__SHIFT)1172};1173 1174static const struct dccg_mask dccg_mask = {1175 DCCG_MASK_SH_LIST_DCN3_02(_MASK)1176};1177 1178#define abm_regs(id)\1179 [id] = { ABM_DCN302_REG_LIST(id) }1180 1181static const struct dce_abm_registers abm_regs[] = {1182 abm_regs(0),1183 abm_regs(1),1184 abm_regs(2),1185 abm_regs(3),1186 abm_regs(4)1187};1188 1189static const struct dce_abm_shift abm_shift = {1190 ABM_MASK_SH_LIST_DCN30(__SHIFT)1191};1192 1193static const struct dce_abm_mask abm_mask = {1194 ABM_MASK_SH_LIST_DCN30(_MASK)1195};1196 1197static bool dcn302_resource_construct(1198 uint8_t num_virtual_links,1199 struct dc *dc,1200 struct resource_pool *pool)1201{1202 int i;1203 struct dc_context *ctx = dc->ctx;1204 struct irq_service_init_data init_data;1205 struct ddc_service_init_data ddc_init_data = {0};1206 1207 ctx->dc_bios->regs = &bios_regs;1208 1209 pool->res_cap = &res_cap_dcn302;1210 1211 pool->funcs = &dcn302_res_pool_funcs;1212 1213 /*************************************************1214 * Resource + asic cap harcoding *1215 *************************************************/1216 pool->underlay_pipe_index = NO_UNDERLAY_PIPE;1217 pool->pipe_count = pool->res_cap->num_timing_generator;1218 pool->mpcc_count = pool->res_cap->num_timing_generator;1219 dc->caps.max_downscale_ratio = 600;1220 dc->caps.i2c_speed_in_khz = 100;1221 dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.4 w/a applied by derfault*/1222 dc->caps.max_cursor_size = 256;1223 dc->caps.min_horizontal_blanking_period = 80;1224 dc->caps.dmdata_alloc_size = 2048;1225 dc->caps.mall_size_per_mem_channel = 4;1226 /* total size = mall per channel * num channels * 1024 * 1024 */1227 dc->caps.mall_size_total = dc->caps.mall_size_per_mem_channel * dc->ctx->dc_bios->vram_info.num_chans * 1048576;1228 dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8;1229 dc->caps.max_slave_planes = 2;1230 dc->caps.max_slave_yuv_planes = 2;1231 dc->caps.max_slave_rgb_planes = 2;1232 dc->caps.post_blend_color_processing = true;1233 dc->caps.force_dp_tps4_for_cp2520 = true;1234 dc->caps.extended_aux_timeout_support = true;1235 dc->caps.dmcub_support = true;1236 dc->caps.max_v_total = (1 << 15) - 1;1237 1238 /* Color pipeline capabilities */1239 dc->caps.color.dpp.dcn_arch = 1;1240 dc->caps.color.dpp.input_lut_shared = 0;1241 dc->caps.color.dpp.icsc = 1;1242 dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr1243 dc->caps.color.dpp.dgam_rom_caps.srgb = 1;1244 dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;1245 dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;1246 dc->caps.color.dpp.dgam_rom_caps.pq = 1;1247 dc->caps.color.dpp.dgam_rom_caps.hlg = 1;1248 dc->caps.color.dpp.post_csc = 1;1249 dc->caps.color.dpp.gamma_corr = 1;1250 dc->caps.color.dpp.dgam_rom_for_yuv = 0;1251 1252 dc->caps.color.dpp.hw_3d_lut = 1;1253 dc->caps.color.dpp.ogam_ram = 1;1254 // no OGAM ROM on DCN31255 dc->caps.color.dpp.ogam_rom_caps.srgb = 0;1256 dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;1257 dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;1258 dc->caps.color.dpp.ogam_rom_caps.pq = 0;1259 dc->caps.color.dpp.ogam_rom_caps.hlg = 0;1260 dc->caps.color.dpp.ocsc = 0;1261 1262 dc->caps.color.mpc.gamut_remap = 1;1263 dc->caps.color.mpc.num_3dluts = pool->res_cap->num_mpc_3dlut; //31264 dc->caps.color.mpc.ogam_ram = 1;1265 dc->caps.color.mpc.ogam_rom_caps.srgb = 0;1266 dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;1267 dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;1268 dc->caps.color.mpc.ogam_rom_caps.pq = 0;1269 dc->caps.color.mpc.ogam_rom_caps.hlg = 0;1270 dc->caps.color.mpc.ocsc = 1;1271 1272 dc->caps.dp_hdmi21_pcon_support = true;1273 1274 /* read VBIOS LTTPR caps */1275 if (ctx->dc_bios->funcs->get_lttpr_caps) {1276 enum bp_result bp_query_result;1277 uint8_t is_vbios_lttpr_enable = 0;1278 1279 bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);1280 dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;1281 }1282 1283 if (ctx->dc_bios->funcs->get_lttpr_interop) {1284 enum bp_result bp_query_result;1285 uint8_t is_vbios_interop_enabled = 0;1286 1287 bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios,1288 &is_vbios_interop_enabled);1289 dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled;1290 }1291 1292 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)1293 dc->debug = debug_defaults_drv;1294 1295 // Init the vm_helper1296 if (dc->vm_helper)1297 vm_helper_init(dc->vm_helper, 16);1298 1299 /*************************************************1300 * Create resources *1301 *************************************************/1302 1303 /* Clock Sources for Pixel Clock*/1304 pool->clock_sources[DCN302_CLK_SRC_PLL0] =1305 dcn302_clock_source_create(ctx, ctx->dc_bios,1306 CLOCK_SOURCE_COMBO_PHY_PLL0,1307 &clk_src_regs[0], false);1308 pool->clock_sources[DCN302_CLK_SRC_PLL1] =1309 dcn302_clock_source_create(ctx, ctx->dc_bios,1310 CLOCK_SOURCE_COMBO_PHY_PLL1,1311 &clk_src_regs[1], false);1312 pool->clock_sources[DCN302_CLK_SRC_PLL2] =1313 dcn302_clock_source_create(ctx, ctx->dc_bios,1314 CLOCK_SOURCE_COMBO_PHY_PLL2,1315 &clk_src_regs[2], false);1316 pool->clock_sources[DCN302_CLK_SRC_PLL3] =1317 dcn302_clock_source_create(ctx, ctx->dc_bios,1318 CLOCK_SOURCE_COMBO_PHY_PLL3,1319 &clk_src_regs[3], false);1320 pool->clock_sources[DCN302_CLK_SRC_PLL4] =1321 dcn302_clock_source_create(ctx, ctx->dc_bios,1322 CLOCK_SOURCE_COMBO_PHY_PLL4,1323 &clk_src_regs[4], false);1324 1325 pool->clk_src_count = DCN302_CLK_SRC_TOTAL;1326 1327 /* todo: not reuse phy_pll registers */1328 pool->dp_clock_source =1329 dcn302_clock_source_create(ctx, ctx->dc_bios,1330 CLOCK_SOURCE_ID_DP_DTO,1331 &clk_src_regs[0], true);1332 1333 for (i = 0; i < pool->clk_src_count; i++) {1334 if (pool->clock_sources[i] == NULL) {1335 dm_error("DC: failed to create clock sources!\n");1336 BREAK_TO_DEBUGGER();1337 goto create_fail;1338 }1339 }1340 1341 /* DCCG */1342 pool->dccg = dccg30_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);1343 if (pool->dccg == NULL) {1344 dm_error("DC: failed to create dccg!\n");1345 BREAK_TO_DEBUGGER();1346 goto create_fail;1347 }1348 1349 /* PP Lib and SMU interfaces */1350 init_soc_bounding_box(dc, pool);1351 1352 /* DML */1353 dml_init_instance(&dc->dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30);1354 1355 /* IRQ */1356 init_data.ctx = dc->ctx;1357 pool->irqs = dal_irq_service_dcn302_create(&init_data);1358 if (!pool->irqs)1359 goto create_fail;1360 1361 /* HUBBUB */1362 pool->hubbub = dcn302_hubbub_create(ctx);1363 if (pool->hubbub == NULL) {1364 BREAK_TO_DEBUGGER();1365 dm_error("DC: failed to create hubbub!\n");1366 goto create_fail;1367 }1368 1369 /* HUBPs, DPPs, OPPs and TGs */1370 for (i = 0; i < pool->pipe_count; i++) {1371 pool->hubps[i] = dcn302_hubp_create(ctx, i);1372 if (pool->hubps[i] == NULL) {1373 BREAK_TO_DEBUGGER();1374 dm_error("DC: failed to create hubps!\n");1375 goto create_fail;1376 }1377 1378 pool->dpps[i] = dcn302_dpp_create(ctx, i);1379 if (pool->dpps[i] == NULL) {1380 BREAK_TO_DEBUGGER();1381 dm_error("DC: failed to create dpps!\n");1382 goto create_fail;1383 }1384 }1385 1386 for (i = 0; i < pool->res_cap->num_opp; i++) {1387 pool->opps[i] = dcn302_opp_create(ctx, i);1388 if (pool->opps[i] == NULL) {1389 BREAK_TO_DEBUGGER();1390 dm_error("DC: failed to create output pixel processor!\n");1391 goto create_fail;1392 }1393 }1394 1395 for (i = 0; i < pool->res_cap->num_timing_generator; i++) {1396 pool->timing_generators[i] = dcn302_timing_generator_create(ctx, i);1397 if (pool->timing_generators[i] == NULL) {1398 BREAK_TO_DEBUGGER();1399 dm_error("DC: failed to create tg!\n");1400 goto create_fail;1401 }1402 }1403 pool->timing_generator_count = i;1404 1405 /* PSR */1406 pool->psr = dmub_psr_create(ctx);1407 if (pool->psr == NULL) {1408 dm_error("DC: failed to create psr!\n");1409 BREAK_TO_DEBUGGER();1410 goto create_fail;1411 }1412 1413 /* ABMs */1414 for (i = 0; i < pool->res_cap->num_timing_generator; i++) {1415 pool->multiple_abms[i] = dmub_abm_create(ctx, &abm_regs[i], &abm_shift, &abm_mask);1416 if (pool->multiple_abms[i] == NULL) {1417 dm_error("DC: failed to create abm for pipe %d!\n", i);1418 BREAK_TO_DEBUGGER();1419 goto create_fail;1420 }1421 }1422 1423 /* MPC and DSC */1424 pool->mpc = dcn302_mpc_create(ctx, pool->mpcc_count, pool->res_cap->num_mpc_3dlut);1425 if (pool->mpc == NULL) {1426 BREAK_TO_DEBUGGER();1427 dm_error("DC: failed to create mpc!\n");1428 goto create_fail;1429 }1430 1431 for (i = 0; i < pool->res_cap->num_dsc; i++) {1432 pool->dscs[i] = dcn302_dsc_create(ctx, i);1433 if (pool->dscs[i] == NULL) {1434 BREAK_TO_DEBUGGER();1435 dm_error("DC: failed to create display stream compressor %d!\n", i);1436 goto create_fail;1437 }1438 }1439 1440 /* DWB and MMHUBBUB */1441 if (!dcn302_dwbc_create(ctx, pool)) {1442 BREAK_TO_DEBUGGER();1443 dm_error("DC: failed to create dwbc!\n");1444 goto create_fail;1445 }1446 1447 if (!dcn302_mmhubbub_create(ctx, pool)) {1448 BREAK_TO_DEBUGGER();1449 dm_error("DC: failed to create mcif_wb!\n");1450 goto create_fail;1451 }1452 1453 /* AUX and I2C */1454 for (i = 0; i < pool->res_cap->num_ddc; i++) {1455 pool->engines[i] = dcn302_aux_engine_create(ctx, i);1456 if (pool->engines[i] == NULL) {1457 BREAK_TO_DEBUGGER();1458 dm_error("DC:failed to create aux engine!!\n");1459 goto create_fail;1460 }1461 pool->hw_i2cs[i] = dcn302_i2c_hw_create(ctx, i);1462 if (pool->hw_i2cs[i] == NULL) {1463 BREAK_TO_DEBUGGER();1464 dm_error("DC:failed to create hw i2c!!\n");1465 goto create_fail;1466 }1467 pool->sw_i2cs[i] = NULL;1468 }1469 1470 /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */1471 if (!resource_construct(num_virtual_links, dc, pool,1472 &res_create_funcs))1473 goto create_fail;1474 1475 /* HW Sequencer and Plane caps */1476 dcn302_hw_sequencer_construct(dc);1477 1478 dc->caps.max_planes = pool->pipe_count;1479 1480 for (i = 0; i < dc->caps.max_planes; ++i)1481 dc->caps.planes[i] = plane_cap;1482 1483 dc->cap_funcs = cap_funcs;1484 1485 if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {1486 ddc_init_data.ctx = dc->ctx;1487 ddc_init_data.link = NULL;1488 ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;1489 ddc_init_data.id.enum_id = 0;1490 ddc_init_data.id.type = OBJECT_TYPE_GENERIC;1491 pool->oem_device = dc->link_srv->create_ddc_service(&ddc_init_data);1492 } else {1493 pool->oem_device = NULL;1494 }1495 1496 return true;1497 1498create_fail:1499 1500 dcn302_resource_destruct(pool);1501 1502 return false;1503}1504 1505struct resource_pool *dcn302_create_resource_pool(const struct dc_init_data *init_data, struct dc *dc)1506{1507 struct resource_pool *pool = kzalloc(sizeof(struct resource_pool), GFP_KERNEL);1508 1509 if (!pool)1510 return NULL;1511 1512 if (dcn302_resource_construct(init_data->num_virtual_links, dc, pool))1513 return pool;1514 1515 BREAK_TO_DEBUGGER();1516 kfree(pool);1517 return NULL;1518}1519