File Index
Files and directories
Sign in
FILE

dce120_resource.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c C
   1/*
   2* Copyright 2012-15 Advanced Micro Devices, Inc.cls
   3*
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining a
   6 * copy of this software and associated documentation files (the "Software"),
   7 * to deal in the Software without restriction, including without limitation
   8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9 * and/or sell copies of the Software, and to permit persons to whom the
  10 * Software is furnished to do so, subject to the following conditions:
  11 *
  12 * The above copyright notice and this permission notice shall be included in
  13 * all copies or substantial portions of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21 * OTHER DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors: AMD
  24 *
  25 */
  26
  27#include "dm_services.h"
  28
  29
  30#include "stream_encoder.h"
  31#include "resource.h"
  32#include "include/irq_service_interface.h"
  33#include "dce120_resource.h"
  34
  35#include "dce112/dce112_resource.h"
  36
  37#include "dce110/dce110_resource.h"
  38#include "virtual/virtual_stream_encoder.h"
  39#include "dce120/dce120_timing_generator.h"
  40#include "irq/dce120/irq_service_dce120.h"
  41#include "dce/dce_opp.h"
  42#include "dce/dce_clock_source.h"
  43#include "dce/dce_ipp.h"
  44#include "dce/dce_mem_input.h"
  45#include "dce/dce_panel_cntl.h"
  46
  47#include "dce110/dce110_hwseq.h"
  48#include "dce120/dce120_hwseq.h"
  49#include "dce/dce_transform.h"
  50#include "clk_mgr.h"
  51#include "dce/dce_audio.h"
  52#include "dce/dce_link_encoder.h"
  53#include "dce/dce_stream_encoder.h"
  54#include "dce/dce_hwseq.h"
  55#include "dce/dce_abm.h"
  56#include "dce/dce_dmcu.h"
  57#include "dce/dce_aux.h"
  58#include "dce/dce_i2c.h"
  59
  60#include "dce/dce_12_0_offset.h"
  61#include "dce/dce_12_0_sh_mask.h"
  62#include "soc15_hw_ip.h"
  63#include "vega10_ip_offset.h"
  64#include "nbio/nbio_6_1_offset.h"
  65#include "mmhub/mmhub_1_0_offset.h"
  66#include "mmhub/mmhub_1_0_sh_mask.h"
  67#include "reg_helper.h"
  68
  69#include "dce100/dce100_resource.h"
  70#include "link_service.h"
  71
  72#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
  73	#define mmDP0_DP_DPHY_INTERNAL_CTRL		0x210f
  74	#define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
  75	#define mmDP1_DP_DPHY_INTERNAL_CTRL		0x220f
  76	#define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
  77	#define mmDP2_DP_DPHY_INTERNAL_CTRL		0x230f
  78	#define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
  79	#define mmDP3_DP_DPHY_INTERNAL_CTRL		0x240f
  80	#define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
  81	#define mmDP4_DP_DPHY_INTERNAL_CTRL		0x250f
  82	#define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
  83	#define mmDP5_DP_DPHY_INTERNAL_CTRL		0x260f
  84	#define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
  85	#define mmDP6_DP_DPHY_INTERNAL_CTRL		0x270f
  86	#define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
  87#endif
  88
  89enum dce120_clk_src_array_id {
  90	DCE120_CLK_SRC_PLL0,
  91	DCE120_CLK_SRC_PLL1,
  92	DCE120_CLK_SRC_PLL2,
  93	DCE120_CLK_SRC_PLL3,
  94	DCE120_CLK_SRC_PLL4,
  95	DCE120_CLK_SRC_PLL5,
  96
  97	DCE120_CLK_SRC_TOTAL
  98};
  99
 100static const struct dce110_timing_generator_offsets dce120_tg_offsets[] = {
 101	{
 102		.crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 103	},
 104	{
 105		.crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 106	},
 107	{
 108		.crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 109	},
 110	{
 111		.crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 112	},
 113	{
 114		.crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 115	},
 116	{
 117		.crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
 118	}
 119};
 120
 121/* begin *********************
 122 * macros to expend register list macro defined in HW object header file */
 123
 124#define BASE_INNER(seg) \
 125	DCE_BASE__INST0_SEG ## seg
 126
 127#define NBIO_BASE_INNER(seg) \
 128	NBIF_BASE__INST0_SEG ## seg
 129
 130#define NBIO_BASE(seg) \
 131	NBIO_BASE_INNER(seg)
 132
 133/* compile time expand base address. */
 134#define BASE(seg) \
 135	BASE_INNER(seg)
 136
 137#define SR(reg_name)\
 138		.reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \
 139					mm ## reg_name
 140
 141#define SRI(reg_name, block, id)\
 142	.reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
 143					mm ## block ## id ## _ ## reg_name
 144
 145/* MMHUB */
 146#define MMHUB_BASE_INNER(seg) \
 147	MMHUB_BASE__INST0_SEG ## seg
 148
 149#define MMHUB_BASE(seg) \
 150	MMHUB_BASE_INNER(seg)
 151
 152#define MMHUB_SR(reg_name)\
 153		.reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) +  \
 154					mm ## reg_name
 155
 156/* macros to expend register list macro defined in HW object header file
 157 * end *********************/
 158
 159
 160static const struct dce_dmcu_registers dmcu_regs = {
 161		DMCU_DCE110_COMMON_REG_LIST()
 162};
 163
 164static const struct dce_dmcu_shift dmcu_shift = {
 165		DMCU_MASK_SH_LIST_DCE110(__SHIFT)
 166};
 167
 168static const struct dce_dmcu_mask dmcu_mask = {
 169		DMCU_MASK_SH_LIST_DCE110(_MASK)
 170};
 171
 172static const struct dce_abm_registers abm_regs = {
 173		ABM_DCE110_COMMON_REG_LIST()
 174};
 175
 176static const struct dce_abm_shift abm_shift = {
 177		ABM_MASK_SH_LIST_DCE110(__SHIFT)
 178};
 179
 180static const struct dce_abm_mask abm_mask = {
 181		ABM_MASK_SH_LIST_DCE110(_MASK)
 182};
 183
 184#define ipp_regs(id)\
 185[id] = {\
 186		IPP_DCE110_REG_LIST_DCE_BASE(id)\
 187}
 188
 189static const struct dce_ipp_registers ipp_regs[] = {
 190		ipp_regs(0),
 191		ipp_regs(1),
 192		ipp_regs(2),
 193		ipp_regs(3),
 194		ipp_regs(4),
 195		ipp_regs(5)
 196};
 197
 198static const struct dce_ipp_shift ipp_shift = {
 199		IPP_DCE120_MASK_SH_LIST_SOC_BASE(__SHIFT)
 200};
 201
 202static const struct dce_ipp_mask ipp_mask = {
 203		IPP_DCE120_MASK_SH_LIST_SOC_BASE(_MASK)
 204};
 205
 206#define transform_regs(id)\
 207[id] = {\
 208		XFM_COMMON_REG_LIST_DCE110(id)\
 209}
 210
 211static const struct dce_transform_registers xfm_regs[] = {
 212		transform_regs(0),
 213		transform_regs(1),
 214		transform_regs(2),
 215		transform_regs(3),
 216		transform_regs(4),
 217		transform_regs(5)
 218};
 219
 220static const struct dce_transform_shift xfm_shift = {
 221		XFM_COMMON_MASK_SH_LIST_SOC_BASE(__SHIFT)
 222};
 223
 224static const struct dce_transform_mask xfm_mask = {
 225		XFM_COMMON_MASK_SH_LIST_SOC_BASE(_MASK)
 226};
 227
 228#define aux_regs(id)\
 229[id] = {\
 230	AUX_REG_LIST(id)\
 231}
 232
 233static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
 234		aux_regs(0),
 235		aux_regs(1),
 236		aux_regs(2),
 237		aux_regs(3),
 238		aux_regs(4),
 239		aux_regs(5)
 240};
 241
 242#define hpd_regs(id)\
 243[id] = {\
 244	HPD_REG_LIST(id)\
 245}
 246
 247static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
 248		hpd_regs(0),
 249		hpd_regs(1),
 250		hpd_regs(2),
 251		hpd_regs(3),
 252		hpd_regs(4),
 253		hpd_regs(5)
 254};
 255
 256#define link_regs(id)\
 257[id] = {\
 258	LE_DCE120_REG_LIST(id), \
 259	SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
 260}
 261
 262static const struct dce110_link_enc_registers link_enc_regs[] = {
 263	link_regs(0),
 264	link_regs(1),
 265	link_regs(2),
 266	link_regs(3),
 267	link_regs(4),
 268	link_regs(5),
 269	link_regs(6),
 270};
 271
 272
 273#define stream_enc_regs(id)\
 274[id] = {\
 275	SE_COMMON_REG_LIST(id),\
 276	.TMDS_CNTL = 0,\
 277}
 278
 279static const struct dce110_stream_enc_registers stream_enc_regs[] = {
 280	stream_enc_regs(0),
 281	stream_enc_regs(1),
 282	stream_enc_regs(2),
 283	stream_enc_regs(3),
 284	stream_enc_regs(4),
 285	stream_enc_regs(5)
 286};
 287
 288static const struct dce_stream_encoder_shift se_shift = {
 289		SE_COMMON_MASK_SH_LIST_DCE120(__SHIFT)
 290};
 291
 292static const struct dce_stream_encoder_mask se_mask = {
 293		SE_COMMON_MASK_SH_LIST_DCE120(_MASK)
 294};
 295
 296static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
 297	{ DCE_PANEL_CNTL_REG_LIST() }
 298};
 299
 300static const struct dce_panel_cntl_shift panel_cntl_shift = {
 301	DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
 302};
 303
 304static const struct dce_panel_cntl_mask panel_cntl_mask = {
 305	DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
 306};
 307
 308static const struct dce110_aux_registers_shift aux_shift = {
 309	DCE12_AUX_MASK_SH_LIST(__SHIFT)
 310};
 311
 312static const struct dce110_aux_registers_mask aux_mask = {
 313	DCE12_AUX_MASK_SH_LIST(_MASK)
 314};
 315
 316#define opp_regs(id)\
 317[id] = {\
 318	OPP_DCE_120_REG_LIST(id),\
 319}
 320
 321static const struct dce_opp_registers opp_regs[] = {
 322	opp_regs(0),
 323	opp_regs(1),
 324	opp_regs(2),
 325	opp_regs(3),
 326	opp_regs(4),
 327	opp_regs(5)
 328};
 329
 330static const struct dce_opp_shift opp_shift = {
 331	OPP_COMMON_MASK_SH_LIST_DCE_120(__SHIFT)
 332};
 333
 334static const struct dce_opp_mask opp_mask = {
 335	OPP_COMMON_MASK_SH_LIST_DCE_120(_MASK)
 336};
 337 #define aux_engine_regs(id)\
 338[id] = {\
 339	AUX_COMMON_REG_LIST(id), \
 340	.AUX_RESET_MASK = 0 \
 341}
 342
 343static const struct dce110_aux_registers aux_engine_regs[] = {
 344		aux_engine_regs(0),
 345		aux_engine_regs(1),
 346		aux_engine_regs(2),
 347		aux_engine_regs(3),
 348		aux_engine_regs(4),
 349		aux_engine_regs(5)
 350};
 351
 352#define audio_regs(id)\
 353[id] = {\
 354	AUD_COMMON_REG_LIST(id)\
 355}
 356
 357static const struct dce_audio_registers audio_regs[] = {
 358	audio_regs(0),
 359	audio_regs(1),
 360	audio_regs(2),
 361	audio_regs(3),
 362	audio_regs(4),
 363	audio_regs(5),
 364	audio_regs(6),
 365};
 366
 367#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
 368		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
 369		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
 370		AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
 371
 372static const struct dce_audio_shift audio_shift = {
 373		DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
 374};
 375
 376static const struct dce_audio_mask audio_mask = {
 377		DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
 378};
 379
 380static int map_transmitter_id_to_phy_instance(
 381	enum transmitter transmitter)
 382{
 383	switch (transmitter) {
 384	case TRANSMITTER_UNIPHY_A:
 385		return 0;
 386	case TRANSMITTER_UNIPHY_B:
 387		return 1;
 388	case TRANSMITTER_UNIPHY_C:
 389		return 2;
 390	case TRANSMITTER_UNIPHY_D:
 391		return 3;
 392	case TRANSMITTER_UNIPHY_E:
 393		return 4;
 394	case TRANSMITTER_UNIPHY_F:
 395		return 5;
 396	case TRANSMITTER_UNIPHY_G:
 397		return 6;
 398	default:
 399		ASSERT(0);
 400		return 0;
 401	}
 402}
 403
 404#define clk_src_regs(index, id)\
 405[index] = {\
 406	CS_COMMON_REG_LIST_DCE_112(id),\
 407}
 408
 409static const struct dce110_clk_src_regs clk_src_regs[] = {
 410	clk_src_regs(0, A),
 411	clk_src_regs(1, B),
 412	clk_src_regs(2, C),
 413	clk_src_regs(3, D),
 414	clk_src_regs(4, E),
 415	clk_src_regs(5, F)
 416};
 417
 418static const struct dce110_clk_src_shift cs_shift = {
 419		CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
 420};
 421
 422static const struct dce110_clk_src_mask cs_mask = {
 423		CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)
 424};
 425
 426static struct output_pixel_processor *dce120_opp_create(
 427	struct dc_context *ctx,
 428	uint32_t inst)
 429{
 430	struct dce110_opp *opp =
 431		kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
 432
 433	if (!opp)
 434		return NULL;
 435
 436	dce110_opp_construct(opp,
 437			     ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 438	return &opp->base;
 439}
 440static struct dce_aux *dce120_aux_engine_create(
 441	struct dc_context *ctx,
 442	uint32_t inst)
 443{
 444	struct aux_engine_dce110 *aux_engine =
 445		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
 446
 447	if (!aux_engine)
 448		return NULL;
 449
 450	dce110_aux_engine_construct(aux_engine, ctx, inst,
 451				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 452				    &aux_engine_regs[inst],
 453					&aux_mask,
 454					&aux_shift,
 455					ctx->dc->caps.extended_aux_timeout_support);
 456
 457	return &aux_engine->base;
 458}
 459#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
 460
 461static const struct dce_i2c_registers i2c_hw_regs[] = {
 462		i2c_inst_regs(1),
 463		i2c_inst_regs(2),
 464		i2c_inst_regs(3),
 465		i2c_inst_regs(4),
 466		i2c_inst_regs(5),
 467		i2c_inst_regs(6),
 468};
 469
 470static const struct dce_i2c_shift i2c_shifts = {
 471		I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 472};
 473
 474static const struct dce_i2c_mask i2c_masks = {
 475		I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
 476};
 477
 478static struct dce_i2c_hw *dce120_i2c_hw_create(
 479	struct dc_context *ctx,
 480	uint32_t inst)
 481{
 482	struct dce_i2c_hw *dce_i2c_hw =
 483		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
 484
 485	if (!dce_i2c_hw)
 486		return NULL;
 487
 488	dce112_i2c_hw_construct(dce_i2c_hw, ctx, inst,
 489				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
 490
 491	return dce_i2c_hw;
 492}
 493static const struct bios_registers bios_regs = {
 494	.BIOS_SCRATCH_0 = mmBIOS_SCRATCH_0 + NBIO_BASE(mmBIOS_SCRATCH_0_BASE_IDX),
 495	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3 + NBIO_BASE(mmBIOS_SCRATCH_3_BASE_IDX),
 496	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX)
 497};
 498
 499static const struct resource_caps res_cap = {
 500		.num_timing_generator = 6,
 501		.num_audio = 7,
 502		.num_stream_encoder = 6,
 503		.num_pll = 6,
 504		.num_ddc = 6,
 505};
 506
 507static const struct dc_plane_cap plane_cap = {
 508	.type = DC_PLANE_TYPE_DCE_RGB,
 509
 510	.pixel_format_support = {
 511			.argb8888 = true,
 512			.nv12 = false,
 513			.fp16 = true
 514	},
 515
 516	.max_upscale_factor = {
 517			.argb8888 = 16000,
 518			.nv12 = 1,
 519			.fp16 = 1
 520	},
 521
 522	.max_downscale_factor = {
 523			.argb8888 = 250,
 524			.nv12 = 1,
 525			.fp16 = 1
 526	}
 527};
 528
 529static const struct dc_debug_options debug_defaults = {
 530	.disable_clock_gate = true,
 531};
 532
 533static const struct dc_check_config config_defaults = {
 534	.enable_legacy_fast_update = true,
 535};
 536
 537static struct clock_source *dce120_clock_source_create(
 538	struct dc_context *ctx,
 539	struct dc_bios *bios,
 540	enum clock_source_id id,
 541	const struct dce110_clk_src_regs *regs,
 542	bool dp_clk_src)
 543{
 544	struct dce110_clk_src *clk_src =
 545		kzalloc(sizeof(*clk_src), GFP_KERNEL);
 546
 547	if (!clk_src)
 548		return NULL;
 549
 550	if (dce112_clk_src_construct(clk_src, ctx, bios, id,
 551				     regs, &cs_shift, &cs_mask)) {
 552		clk_src->base.dp_clk_src = dp_clk_src;
 553		return &clk_src->base;
 554	}
 555
 556	kfree(clk_src);
 557	BREAK_TO_DEBUGGER();
 558	return NULL;
 559}
 560
 561static void dce120_clock_source_destroy(struct clock_source **clk_src)
 562{
 563	kfree(TO_DCE110_CLK_SRC(*clk_src));
 564	*clk_src = NULL;
 565}
 566
 567
 568static bool dce120_hw_sequencer_create(struct dc *dc)
 569{
 570	/* All registers used by dce11.2 match those in dce11 in offset and
 571	 * structure
 572	 */
 573	dce120_hw_sequencer_construct(dc);
 574
 575	/*TODO	Move to separate file and Override what is needed */
 576
 577	return true;
 578}
 579
 580static struct timing_generator *dce120_timing_generator_create(
 581		struct dc_context *ctx,
 582		uint32_t instance,
 583		const struct dce110_timing_generator_offsets *offsets)
 584{
 585	struct dce110_timing_generator *tg110 =
 586		kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
 587
 588	if (!tg110)
 589		return NULL;
 590
 591	dce120_timing_generator_construct(tg110, ctx, instance, offsets);
 592	return &tg110->base;
 593}
 594
 595static void dce120_transform_destroy(struct transform **xfm)
 596{
 597	kfree(TO_DCE_TRANSFORM(*xfm));
 598	*xfm = NULL;
 599}
 600
 601static void dce120_resource_destruct(struct dce110_resource_pool *pool)
 602{
 603	unsigned int i;
 604
 605	for (i = 0; i < pool->base.pipe_count; i++) {
 606		if (pool->base.opps[i] != NULL)
 607			dce110_opp_destroy(&pool->base.opps[i]);
 608
 609		if (pool->base.transforms[i] != NULL)
 610			dce120_transform_destroy(&pool->base.transforms[i]);
 611
 612		if (pool->base.ipps[i] != NULL)
 613			dce_ipp_destroy(&pool->base.ipps[i]);
 614
 615		if (pool->base.mis[i] != NULL) {
 616			kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
 617			pool->base.mis[i] = NULL;
 618		}
 619
 620		if (pool->base.irqs != NULL) {
 621			dal_irq_service_destroy(&pool->base.irqs);
 622		}
 623
 624		if (pool->base.timing_generators[i] != NULL) {
 625			kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
 626			pool->base.timing_generators[i] = NULL;
 627		}
 628	}
 629
 630	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
 631		if (pool->base.engines[i] != NULL)
 632			dce110_engine_destroy(&pool->base.engines[i]);
 633		if (pool->base.hw_i2cs[i] != NULL) {
 634			kfree(pool->base.hw_i2cs[i]);
 635			pool->base.hw_i2cs[i] = NULL;
 636		}
 637		if (pool->base.sw_i2cs[i] != NULL) {
 638			kfree(pool->base.sw_i2cs[i]);
 639			pool->base.sw_i2cs[i] = NULL;
 640		}
 641	}
 642
 643	for (i = 0; i < pool->base.audio_count; i++) {
 644		if (pool->base.audios[i])
 645			dce_aud_destroy(&pool->base.audios[i]);
 646	}
 647
 648	for (i = 0; i < pool->base.stream_enc_count; i++) {
 649		if (pool->base.stream_enc[i] != NULL)
 650			kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 651	}
 652
 653	for (i = 0; i < pool->base.clk_src_count; i++) {
 654		if (pool->base.clock_sources[i] != NULL)
 655			dce120_clock_source_destroy(
 656				&pool->base.clock_sources[i]);
 657	}
 658
 659	if (pool->base.dp_clock_source != NULL)
 660		dce120_clock_source_destroy(&pool->base.dp_clock_source);
 661
 662	if (pool->base.abm != NULL)
 663		dce_abm_destroy(&pool->base.abm);
 664
 665	if (pool->base.dmcu != NULL)
 666		dce_dmcu_destroy(&pool->base.dmcu);
 667
 668	if (pool->base.oem_device != NULL) {
 669		struct dc *dc = pool->base.oem_device->ctx->dc;
 670
 671		dc->link_srv->destroy_ddc_service(&pool->base.oem_device);
 672	}
 673}
 674
 675static void read_dce_straps(
 676	struct dc_context *ctx,
 677	struct resource_straps *straps)
 678{
 679	uint32_t reg_val = dm_read_reg_soc15(ctx, mmCC_DC_MISC_STRAPS, 0);
 680
 681	straps->audio_stream_number = get_reg_field_value(reg_val,
 682							  CC_DC_MISC_STRAPS,
 683							  AUDIO_STREAM_NUMBER);
 684	straps->hdmi_disable = get_reg_field_value(reg_val,
 685						   CC_DC_MISC_STRAPS,
 686						   HDMI_DISABLE);
 687
 688	reg_val = dm_read_reg_soc15(ctx, mmDC_PINSTRAPS, 0);
 689	straps->dc_pinstraps_audio = get_reg_field_value(reg_val,
 690							 DC_PINSTRAPS,
 691							 DC_PINSTRAPS_AUDIO);
 692}
 693
 694static struct audio *create_audio(
 695		struct dc_context *ctx, unsigned int inst)
 696{
 697	return dce_audio_create(ctx, inst,
 698			&audio_regs[inst], &audio_shift, &audio_mask);
 699}
 700
 701static const struct encoder_feature_support link_enc_feature = {
 702		.max_hdmi_deep_color = COLOR_DEPTH_121212,
 703		.max_hdmi_pixel_clock = 600000,
 704		.hdmi_ycbcr420_supported = true,
 705		.dp_ycbcr420_supported = false,
 706		.flags.bits.IS_HBR2_CAPABLE = true,
 707		.flags.bits.IS_HBR3_CAPABLE = true,
 708		.flags.bits.IS_TPS3_CAPABLE = true,
 709		.flags.bits.IS_TPS4_CAPABLE = true,
 710};
 711
 712static struct link_encoder *dce120_link_encoder_create(
 713	struct dc_context *ctx,
 714	const struct encoder_init_data *enc_init_data)
 715{
 716	struct dce110_link_encoder *enc110 =
 717		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 718	int link_regs_id;
 719
 720	if (!enc110)
 721		return NULL;
 722
 723	link_regs_id =
 724		map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
 725
 726	dce110_link_encoder_construct(enc110,
 727				      enc_init_data,
 728				      &link_enc_feature,
 729				      &link_enc_regs[link_regs_id],
 730				      &link_enc_aux_regs[enc_init_data->channel - 1],
 731				      enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
 732				      NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
 733
 734	return &enc110->base;
 735}
 736
 737static struct panel_cntl *dce120_panel_cntl_create(const struct panel_cntl_init_data *init_data)
 738{
 739	struct dce_panel_cntl *panel_cntl =
 740		kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
 741
 742	if (!panel_cntl)
 743		return NULL;
 744
 745	dce_panel_cntl_construct(panel_cntl,
 746			init_data,
 747			&panel_cntl_regs[init_data->inst],
 748			&panel_cntl_shift,
 749			&panel_cntl_mask);
 750
 751	return &panel_cntl->base;
 752}
 753
 754static struct input_pixel_processor *dce120_ipp_create(
 755	struct dc_context *ctx, uint32_t inst)
 756{
 757	struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
 758
 759	if (!ipp) {
 760		BREAK_TO_DEBUGGER();
 761		return NULL;
 762	}
 763
 764	dce_ipp_construct(ipp, ctx, inst,
 765			&ipp_regs[inst], &ipp_shift, &ipp_mask);
 766	return &ipp->base;
 767}
 768
 769static struct stream_encoder *dce120_stream_encoder_create(
 770	enum engine_id eng_id,
 771	struct dc_context *ctx)
 772{
 773	struct dce110_stream_encoder *enc110 =
 774		kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
 775
 776	if (!enc110)
 777		return NULL;
 778
 779	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 780					&stream_enc_regs[eng_id],
 781					&se_shift, &se_mask);
 782	return &enc110->base;
 783}
 784
 785#define SRII(reg_name, block, id)\
 786	.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
 787					mm ## block ## id ## _ ## reg_name
 788
 789static const struct dce_hwseq_registers hwseq_reg = {
 790		HWSEQ_DCE120_REG_LIST()
 791};
 792
 793static const struct dce_hwseq_shift hwseq_shift = {
 794		HWSEQ_DCE12_MASK_SH_LIST(__SHIFT)
 795};
 796
 797static const struct dce_hwseq_mask hwseq_mask = {
 798		HWSEQ_DCE12_MASK_SH_LIST(_MASK)
 799};
 800
 801/* HWSEQ regs for VG20 */
 802static const struct dce_hwseq_registers dce121_hwseq_reg = {
 803		HWSEQ_VG20_REG_LIST()
 804};
 805
 806static const struct dce_hwseq_shift dce121_hwseq_shift = {
 807		HWSEQ_VG20_MASK_SH_LIST(__SHIFT)
 808};
 809
 810static const struct dce_hwseq_mask dce121_hwseq_mask = {
 811		HWSEQ_VG20_MASK_SH_LIST(_MASK)
 812};
 813
 814static struct dce_hwseq *dce120_hwseq_create(
 815	struct dc_context *ctx)
 816{
 817	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 818
 819	if (hws) {
 820		hws->ctx = ctx;
 821		hws->regs = &hwseq_reg;
 822		hws->shifts = &hwseq_shift;
 823		hws->masks = &hwseq_mask;
 824	}
 825	return hws;
 826}
 827
 828static struct dce_hwseq *dce121_hwseq_create(
 829	struct dc_context *ctx)
 830{
 831	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 832
 833	if (hws) {
 834		hws->ctx = ctx;
 835		hws->regs = &dce121_hwseq_reg;
 836		hws->shifts = &dce121_hwseq_shift;
 837		hws->masks = &dce121_hwseq_mask;
 838	}
 839	return hws;
 840}
 841
 842static const struct resource_create_funcs res_create_funcs = {
 843	.read_dce_straps = read_dce_straps,
 844	.create_audio = create_audio,
 845	.create_stream_encoder = dce120_stream_encoder_create,
 846	.create_hwseq = dce120_hwseq_create,
 847};
 848
 849static const struct resource_create_funcs dce121_res_create_funcs = {
 850	.read_dce_straps = read_dce_straps,
 851	.create_audio = create_audio,
 852	.create_stream_encoder = dce120_stream_encoder_create,
 853	.create_hwseq = dce121_hwseq_create,
 854};
 855
 856
 857#define mi_inst_regs(id) { MI_DCE12_REG_LIST(id) }
 858static const struct dce_mem_input_registers mi_regs[] = {
 859		mi_inst_regs(0),
 860		mi_inst_regs(1),
 861		mi_inst_regs(2),
 862		mi_inst_regs(3),
 863		mi_inst_regs(4),
 864		mi_inst_regs(5),
 865};
 866
 867static const struct dce_mem_input_shift mi_shifts = {
 868		MI_DCE12_MASK_SH_LIST(__SHIFT)
 869};
 870
 871static const struct dce_mem_input_mask mi_masks = {
 872		MI_DCE12_MASK_SH_LIST(_MASK)
 873};
 874
 875static struct mem_input *dce120_mem_input_create(
 876	struct dc_context *ctx,
 877	uint32_t inst)
 878{
 879	struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
 880					       GFP_KERNEL);
 881
 882	if (!dce_mi) {
 883		BREAK_TO_DEBUGGER();
 884		return NULL;
 885	}
 886
 887	dce120_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
 888	return &dce_mi->base;
 889}
 890
 891static struct transform *dce120_transform_create(
 892	struct dc_context *ctx,
 893	uint32_t inst)
 894{
 895	struct dce_transform *transform =
 896		kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
 897
 898	if (!transform)
 899		return NULL;
 900
 901	dce_transform_construct(transform, ctx, inst,
 902				&xfm_regs[inst], &xfm_shift, &xfm_mask);
 903	transform->lb_memory_size = 0x1404; /*5124*/
 904	return &transform->base;
 905}
 906
 907static void dce120_destroy_resource_pool(struct resource_pool **pool)
 908{
 909	struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
 910
 911	dce120_resource_destruct(dce110_pool);
 912	kfree(dce110_pool);
 913	*pool = NULL;
 914}
 915
 916static const struct resource_funcs dce120_res_pool_funcs = {
 917	.destroy = dce120_destroy_resource_pool,
 918	.link_enc_create = dce120_link_encoder_create,
 919	.panel_cntl_create = dce120_panel_cntl_create,
 920	.validate_bandwidth = dce112_validate_bandwidth,
 921	.validate_plane = dce100_validate_plane,
 922	.add_stream_to_ctx = dce112_add_stream_to_ctx,
 923	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
 924};
 925
 926static void bw_calcs_data_update_from_pplib(struct dc *dc)
 927{
 928	struct dm_pp_clock_levels_with_latency eng_clks = {0};
 929	struct dm_pp_clock_levels_with_latency mem_clks = {0};
 930	struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
 931	int i;
 932	unsigned int clk;
 933	unsigned int latency;
 934	/*original logic in dal3*/
 935	int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
 936
 937	/*do system clock*/
 938	if (!dm_pp_get_clock_levels_by_type_with_latency(
 939				dc->ctx,
 940				DM_PP_CLOCK_TYPE_ENGINE_CLK,
 941				&eng_clks) || eng_clks.num_levels == 0) {
 942
 943		eng_clks.num_levels = 8;
 944		clk = 300000;
 945
 946		for (i = 0; i < eng_clks.num_levels; i++) {
 947			eng_clks.data[i].clocks_in_khz = clk;
 948			clk += 100000;
 949		}
 950	}
 951
 952	/* convert all the clock fro kHz to fix point mHz  TODO: wloop data */
 953	dc->bw_vbios->high_sclk = bw_frc_to_fixed(
 954		eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);
 955	dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
 956		eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);
 957	dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
 958		eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);
 959	dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
 960		eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);
 961	dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
 962		eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);
 963	dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
 964		eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);
 965	dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
 966		eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);
 967	dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
 968			eng_clks.data[0].clocks_in_khz, 1000);
 969
 970	/*do memory clock*/
 971	if (!dm_pp_get_clock_levels_by_type_with_latency(
 972			dc->ctx,
 973			DM_PP_CLOCK_TYPE_MEMORY_CLK,
 974			&mem_clks) || mem_clks.num_levels == 0) {
 975
 976		mem_clks.num_levels = 3;
 977		clk = 250000;
 978		latency = 45;
 979
 980		for (i = 0; i < eng_clks.num_levels; i++) {
 981			mem_clks.data[i].clocks_in_khz = clk;
 982			mem_clks.data[i].latency_in_us = latency;
 983			clk += 500000;
 984			latency -= 5;
 985		}
 986
 987	}
 988
 989	/* we don't need to call PPLIB for validation clock since they
 990	 * also give us the highest sclk and highest mclk (UMA clock).
 991	 * ALSO always convert UMA clock (from PPLIB)  to YCLK (HW formula):
 992	 * YCLK = UMACLK*m_memoryTypeMultiplier
 993	 */
 994	if (dc->bw_vbios->memory_type == bw_def_hbm)
 995		memory_type_multiplier = MEMORY_TYPE_HBM;
 996
 997	dc->bw_vbios->low_yclk = bw_frc_to_fixed(
 998		(int64_t)mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000);
 999	dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
1000		(int64_t)mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier,
1001		1000);
1002	dc->bw_vbios->high_yclk = bw_frc_to_fixed(
1003		(int64_t)mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier,
1004		1000);
1005
1006	/* Now notify PPLib/SMU about which Watermarks sets they should select
1007	 * depending on DPM state they are in. And update BW MGR GFX Engine and
1008	 * Memory clock member variables for Watermarks calculations for each
1009	 * Watermark Set
1010	 */
1011	clk_ranges.num_wm_sets = 4;
1012	clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;
1013	clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =
1014			eng_clks.data[0].clocks_in_khz;
1015	clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =
1016			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
1017	clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz =
1018			mem_clks.data[0].clocks_in_khz;
1019	clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =
1020			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
1021
1022	clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;
1023	clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =
1024			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
1025	/* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1026	clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;
1027	clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz =
1028			mem_clks.data[0].clocks_in_khz;
1029	clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =
1030			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
1031
1032	clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;
1033	clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =
1034			eng_clks.data[0].clocks_in_khz;
1035	clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =
1036			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
1037	clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz =
1038			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
1039	/* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1040	clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;
1041
1042	clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;
1043	clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =
1044			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
1045	/* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1046	clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;
1047	clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz =
1048			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
1049	/* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1050	clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;
1051
1052	/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1053	dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
1054}
1055
1056static uint32_t read_pipe_fuses(struct dc_context *ctx)
1057{
1058	uint32_t value = dm_read_reg_soc15(ctx, mmCC_DC_PIPE_DIS, 0);
1059	/* VG20 support max 6 pipes */
1060	value = value & 0x3f;
1061	return value;
1062}
1063
1064static bool dce120_resource_construct(
1065	uint8_t num_virtual_links,
1066	struct dc *dc,
1067	struct dce110_resource_pool *pool)
1068{
1069	struct ddc_service_init_data ddc_init_data = {0};
1070	unsigned int i;
1071	int j;
1072	struct dc_context *ctx = dc->ctx;
1073	struct irq_service_init_data irq_init_data;
1074	static const struct resource_create_funcs *res_funcs;
1075	bool is_vg20 = ASICREV_IS_VEGA20_P(ctx->asic_id.hw_internal_rev);
1076	uint32_t pipe_fuses = 0;
1077
1078	ctx->dc_bios->regs = &bios_regs;
1079
1080	pool->base.res_cap = &res_cap;
1081	pool->base.funcs = &dce120_res_pool_funcs;
1082
1083	/* TODO: Fill more data from GreenlandAsicCapability.cpp */
1084	pool->base.pipe_count = res_cap.num_timing_generator;
1085	pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
1086	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1087
1088	dc->caps.max_downscale_ratio = 200;
1089	dc->caps.i2c_speed_in_khz = 100;
1090	dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/
1091	dc->caps.max_cursor_size = 128;
1092	dc->caps.min_horizontal_blanking_period = 80;
1093	dc->caps.dual_link_dvi = true;
1094	dc->caps.psp_setup_panel_mode = true;
1095	dc->caps.extended_aux_timeout_support = false;
1096	dc->debug = debug_defaults;
1097	dc->check_config = config_defaults;
1098
1099	/*************************************************
1100	 *  Create resources                             *
1101	 *************************************************/
1102
1103	pool->base.clock_sources[DCE120_CLK_SRC_PLL0] =
1104			dce120_clock_source_create(ctx, ctx->dc_bios,
1105				CLOCK_SOURCE_COMBO_PHY_PLL0,
1106				&clk_src_regs[0], false);
1107	pool->base.clock_sources[DCE120_CLK_SRC_PLL1] =
1108			dce120_clock_source_create(ctx, ctx->dc_bios,
1109				CLOCK_SOURCE_COMBO_PHY_PLL1,
1110				&clk_src_regs[1], false);
1111	pool->base.clock_sources[DCE120_CLK_SRC_PLL2] =
1112			dce120_clock_source_create(ctx, ctx->dc_bios,
1113				CLOCK_SOURCE_COMBO_PHY_PLL2,
1114				&clk_src_regs[2], false);
1115	pool->base.clock_sources[DCE120_CLK_SRC_PLL3] =
1116			dce120_clock_source_create(ctx, ctx->dc_bios,
1117				CLOCK_SOURCE_COMBO_PHY_PLL3,
1118				&clk_src_regs[3], false);
1119	pool->base.clock_sources[DCE120_CLK_SRC_PLL4] =
1120			dce120_clock_source_create(ctx, ctx->dc_bios,
1121				CLOCK_SOURCE_COMBO_PHY_PLL4,
1122				&clk_src_regs[4], false);
1123	pool->base.clock_sources[DCE120_CLK_SRC_PLL5] =
1124			dce120_clock_source_create(ctx, ctx->dc_bios,
1125				CLOCK_SOURCE_COMBO_PHY_PLL5,
1126				&clk_src_regs[5], false);
1127	pool->base.clk_src_count = DCE120_CLK_SRC_TOTAL;
1128
1129	pool->base.dp_clock_source =
1130			dce120_clock_source_create(ctx, ctx->dc_bios,
1131				CLOCK_SOURCE_ID_DP_DTO,
1132				&clk_src_regs[0], true);
1133
1134	for (i = 0; i < pool->base.clk_src_count; i++) {
1135		if (pool->base.clock_sources[i] == NULL) {
1136			dm_error("DC: failed to create clock sources!\n");
1137			BREAK_TO_DEBUGGER();
1138			goto clk_src_create_fail;
1139		}
1140	}
1141
1142	pool->base.dmcu = dce_dmcu_create(ctx,
1143			&dmcu_regs,
1144			&dmcu_shift,
1145			&dmcu_mask);
1146	if (pool->base.dmcu == NULL) {
1147		dm_error("DC: failed to create dmcu!\n");
1148		BREAK_TO_DEBUGGER();
1149		goto res_create_fail;
1150	}
1151
1152	pool->base.abm = dce_abm_create(ctx,
1153			&abm_regs,
1154			&abm_shift,
1155			&abm_mask);
1156	if (pool->base.abm == NULL) {
1157		dm_error("DC: failed to create abm!\n");
1158		BREAK_TO_DEBUGGER();
1159		goto res_create_fail;
1160	}
1161
1162
1163	irq_init_data.ctx = dc->ctx;
1164	pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data);
1165	if (!pool->base.irqs)
1166		goto irqs_create_fail;
1167
1168	/* VG20: Pipe harvesting enabled, retrieve valid pipe fuses */
1169	if (is_vg20)
1170		pipe_fuses = read_pipe_fuses(ctx);
1171
1172	/* index to valid pipe resource */
1173	j = 0;
1174	for (i = 0; i < pool->base.pipe_count; i++) {
1175		if (is_vg20) {
1176			if ((pipe_fuses & (1 << i)) != 0) {
1177				dm_error("DC: skip invalid pipe %d!\n", i);
1178				continue;
1179			}
1180		}
1181
1182		pool->base.timing_generators[j] =
1183				dce120_timing_generator_create(
1184					ctx,
1185					i,
1186					&dce120_tg_offsets[i]);
1187		if (pool->base.timing_generators[j] == NULL) {
1188			BREAK_TO_DEBUGGER();
1189			dm_error("DC: failed to create tg!\n");
1190			goto controller_create_fail;
1191		}
1192
1193		pool->base.mis[j] = dce120_mem_input_create(ctx, i);
1194
1195		if (pool->base.mis[j] == NULL) {
1196			BREAK_TO_DEBUGGER();
1197			dm_error(
1198				"DC: failed to create memory input!\n");
1199			goto controller_create_fail;
1200		}
1201
1202		pool->base.ipps[j] = dce120_ipp_create(ctx, i);
1203		if (pool->base.ipps[i] == NULL) {
1204			BREAK_TO_DEBUGGER();
1205			dm_error(
1206				"DC: failed to create input pixel processor!\n");
1207			goto controller_create_fail;
1208		}
1209
1210		pool->base.transforms[j] = dce120_transform_create(ctx, i);
1211		if (pool->base.transforms[i] == NULL) {
1212			BREAK_TO_DEBUGGER();
1213			dm_error(
1214				"DC: failed to create transform!\n");
1215			goto res_create_fail;
1216		}
1217
1218		pool->base.opps[j] = dce120_opp_create(
1219			ctx,
1220			i);
1221		if (pool->base.opps[j] == NULL) {
1222			BREAK_TO_DEBUGGER();
1223			dm_error(
1224				"DC: failed to create output pixel processor!\n");
1225		}
1226
1227		/* check next valid pipe */
1228		j++;
1229	}
1230
1231	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1232		pool->base.engines[i] = dce120_aux_engine_create(ctx, i);
1233		if (pool->base.engines[i] == NULL) {
1234			BREAK_TO_DEBUGGER();
1235			dm_error(
1236				"DC:failed to create aux engine!!\n");
1237			goto res_create_fail;
1238		}
1239		pool->base.hw_i2cs[i] = dce120_i2c_hw_create(ctx, i);
1240		if (pool->base.hw_i2cs[i] == NULL) {
1241			BREAK_TO_DEBUGGER();
1242			dm_error(
1243				"DC:failed to create i2c engine!!\n");
1244			goto res_create_fail;
1245		}
1246		pool->base.sw_i2cs[i] = NULL;
1247	}
1248
1249	/* valid pipe num */
1250	pool->base.pipe_count = j;
1251	pool->base.timing_generator_count = j;
1252
1253	if (is_vg20)
1254		res_funcs = &dce121_res_create_funcs;
1255	else
1256		res_funcs = &res_create_funcs;
1257
1258	if (!resource_construct(num_virtual_links, dc, &pool->base, res_funcs))
1259		goto res_create_fail;
1260
1261	/* Create hardware sequencer */
1262	if (!dce120_hw_sequencer_create(dc))
1263		goto controller_create_fail;
1264
1265	dc->caps.max_planes =  pool->base.pipe_count;
1266
1267	for (i = 0; i < dc->caps.max_planes; ++i)
1268		dc->caps.planes[i] = plane_cap;
1269
1270	bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
1271
1272	bw_calcs_data_update_from_pplib(dc);
1273
1274	if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
1275		ddc_init_data.ctx = dc->ctx;
1276		ddc_init_data.link = NULL;
1277		ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
1278		ddc_init_data.id.enum_id = 0;
1279		ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
1280		pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data);
1281	}
1282
1283	return true;
1284
1285irqs_create_fail:
1286controller_create_fail:
1287clk_src_create_fail:
1288res_create_fail:
1289
1290	dce120_resource_destruct(pool);
1291
1292	return false;
1293}
1294
1295struct resource_pool *dce120_create_resource_pool(
1296	uint8_t num_virtual_links,
1297	struct dc *dc)
1298{
1299	struct dce110_resource_pool *pool =
1300		kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1301
1302	if (!pool)
1303		return NULL;
1304
1305	if (dce120_resource_construct(num_virtual_links, dc, pool))
1306		return &pool->base;
1307
1308	kfree(pool);
1309	BREAK_TO_DEBUGGER();
1310	return NULL;
1311}
~/ Read-only file preview.