Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
   1/*
   2 * Copyright 2012-15 Advanced Micro Devices, Inc.
   3 *
   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:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  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.
  21 *
  22 * Authors: AMD
  23 *
  24 */
  25
  26#include "dce/dce_8_0_d.h"
  27#include "dce/dce_8_0_sh_mask.h"
  28
  29#include "dm_services.h"
  30
  31#include "link_encoder.h"
  32#include "stream_encoder.h"
  33
  34#include "resource.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_mem_input.h"
  41#include "dce/dce_link_encoder.h"
  42#include "dce/dce_stream_encoder.h"
  43#include "dce/dce_mem_input.h"
  44#include "dce/dce_ipp.h"
  45#include "dce/dce_transform.h"
  46#include "dce/dce_opp.h"
  47#include "dce/dce_clocks.h"
  48#include "dce/dce_clock_source.h"
  49#include "dce/dce_audio.h"
  50#include "dce/dce_hwseq.h"
  51#include "dce80/dce80_hw_sequencer.h"
  52#include "dce100/dce100_resource.h"
  53
  54#include "reg_helper.h"
  55
  56#include "dce/dce_dmcu.h"
  57#include "dce/dce_abm.h"
  58/* TODO remove this include */
  59
  60#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
  61#include "gmc/gmc_7_1_d.h"
  62#include "gmc/gmc_7_1_sh_mask.h"
  63#endif
  64
  65#ifndef mmDP_DPHY_INTERNAL_CTRL
  66#define mmDP_DPHY_INTERNAL_CTRL                         0x1CDE
  67#define mmDP0_DP_DPHY_INTERNAL_CTRL                     0x1CDE
  68#define mmDP1_DP_DPHY_INTERNAL_CTRL                     0x1FDE
  69#define mmDP2_DP_DPHY_INTERNAL_CTRL                     0x42DE
  70#define mmDP3_DP_DPHY_INTERNAL_CTRL                     0x45DE
  71#define mmDP4_DP_DPHY_INTERNAL_CTRL                     0x48DE
  72#define mmDP5_DP_DPHY_INTERNAL_CTRL                     0x4BDE
  73#define mmDP6_DP_DPHY_INTERNAL_CTRL                     0x4EDE
  74#endif
  75
  76
  77#ifndef mmBIOS_SCRATCH_2
  78	#define mmBIOS_SCRATCH_2 0x05CB
  79	#define mmBIOS_SCRATCH_6 0x05CF
  80#endif
  81
  82#ifndef mmDP_DPHY_FAST_TRAINING
  83	#define mmDP_DPHY_FAST_TRAINING                         0x1CCE
  84	#define mmDP0_DP_DPHY_FAST_TRAINING                     0x1CCE
  85	#define mmDP1_DP_DPHY_FAST_TRAINING                     0x1FCE
  86	#define mmDP2_DP_DPHY_FAST_TRAINING                     0x42CE
  87	#define mmDP3_DP_DPHY_FAST_TRAINING                     0x45CE
  88	#define mmDP4_DP_DPHY_FAST_TRAINING                     0x48CE
  89	#define mmDP5_DP_DPHY_FAST_TRAINING                     0x4BCE
  90	#define mmDP6_DP_DPHY_FAST_TRAINING                     0x4ECE
  91#endif
  92
  93
  94#ifndef mmHPD_DC_HPD_CONTROL
  95	#define mmHPD_DC_HPD_CONTROL                            0x189A
  96	#define mmHPD0_DC_HPD_CONTROL                           0x189A
  97	#define mmHPD1_DC_HPD_CONTROL                           0x18A2
  98	#define mmHPD2_DC_HPD_CONTROL                           0x18AA
  99	#define mmHPD3_DC_HPD_CONTROL                           0x18B2
 100	#define mmHPD4_DC_HPD_CONTROL                           0x18BA
 101	#define mmHPD5_DC_HPD_CONTROL                           0x18C2
 102#endif
 103
 104#define DCE11_DIG_FE_CNTL 0x4a00
 105#define DCE11_DIG_BE_CNTL 0x4a47
 106#define DCE11_DP_SEC 0x4ac3
 107
 108static const struct dce110_timing_generator_offsets dce80_tg_offsets[] = {
 109		{
 110			.crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
 111			.dcp =  (mmGRPH_CONTROL - mmGRPH_CONTROL),
 112			.dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL
 113					- mmDPG_WATERMARK_MASK_CONTROL),
 114		},
 115		{
 116			.crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
 117			.dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
 118			.dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
 119					- mmDPG_WATERMARK_MASK_CONTROL),
 120		},
 121		{
 122			.crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
 123			.dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
 124			.dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
 125					- mmDPG_WATERMARK_MASK_CONTROL),
 126		},
 127		{
 128			.crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
 129			.dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
 130			.dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL
 131					- mmDPG_WATERMARK_MASK_CONTROL),
 132		},
 133		{
 134			.crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
 135			.dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
 136			.dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL
 137					- mmDPG_WATERMARK_MASK_CONTROL),
 138		},
 139		{
 140			.crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
 141			.dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
 142			.dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL
 143					- mmDPG_WATERMARK_MASK_CONTROL),
 144		}
 145};
 146
 147/* set register offset */
 148#define SR(reg_name)\
 149	.reg_name = mm ## reg_name
 150
 151/* set register offset with instance */
 152#define SRI(reg_name, block, id)\
 153	.reg_name = mm ## block ## id ## _ ## reg_name
 154
 155
 156static const struct dce_disp_clk_registers disp_clk_regs = {
 157		CLK_COMMON_REG_LIST_DCE_BASE()
 158};
 159
 160static const struct dce_disp_clk_shift disp_clk_shift = {
 161		CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 162};
 163
 164static const struct dce_disp_clk_mask disp_clk_mask = {
 165		CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 166};
 167
 168#define ipp_regs(id)\
 169[id] = {\
 170		IPP_COMMON_REG_LIST_DCE_BASE(id)\
 171}
 172
 173static const struct dce_ipp_registers ipp_regs[] = {
 174		ipp_regs(0),
 175		ipp_regs(1),
 176		ipp_regs(2),
 177		ipp_regs(3),
 178		ipp_regs(4),
 179		ipp_regs(5)
 180};
 181
 182static const struct dce_ipp_shift ipp_shift = {
 183		IPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 184};
 185
 186static const struct dce_ipp_mask ipp_mask = {
 187		IPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 188};
 189
 190#define transform_regs(id)\
 191[id] = {\
 192		XFM_COMMON_REG_LIST_DCE80(id)\
 193}
 194
 195static const struct dce_transform_registers xfm_regs[] = {
 196		transform_regs(0),
 197		transform_regs(1),
 198		transform_regs(2),
 199		transform_regs(3),
 200		transform_regs(4),
 201		transform_regs(5)
 202};
 203
 204static const struct dce_transform_shift xfm_shift = {
 205		XFM_COMMON_MASK_SH_LIST_DCE80(__SHIFT)
 206};
 207
 208static const struct dce_transform_mask xfm_mask = {
 209		XFM_COMMON_MASK_SH_LIST_DCE80(_MASK)
 210};
 211
 212#define aux_regs(id)\
 213[id] = {\
 214	AUX_REG_LIST(id)\
 215}
 216
 217static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
 218	aux_regs(0),
 219	aux_regs(1),
 220	aux_regs(2),
 221	aux_regs(3),
 222	aux_regs(4),
 223	aux_regs(5)
 224};
 225
 226#define hpd_regs(id)\
 227[id] = {\
 228	HPD_REG_LIST(id)\
 229}
 230
 231static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
 232		hpd_regs(0),
 233		hpd_regs(1),
 234		hpd_regs(2),
 235		hpd_regs(3),
 236		hpd_regs(4),
 237		hpd_regs(5)
 238};
 239
 240#define link_regs(id)\
 241[id] = {\
 242	LE_DCE80_REG_LIST(id)\
 243}
 244
 245static const struct dce110_link_enc_registers link_enc_regs[] = {
 246	link_regs(0),
 247	link_regs(1),
 248	link_regs(2),
 249	link_regs(3),
 250	link_regs(4),
 251	link_regs(5),
 252	link_regs(6),
 253};
 254
 255#define stream_enc_regs(id)\
 256[id] = {\
 257	SE_COMMON_REG_LIST_DCE_BASE(id),\
 258	.AFMT_CNTL = 0,\
 259}
 260
 261static const struct dce110_stream_enc_registers stream_enc_regs[] = {
 262	stream_enc_regs(0),
 263	stream_enc_regs(1),
 264	stream_enc_regs(2),
 265	stream_enc_regs(3),
 266	stream_enc_regs(4),
 267	stream_enc_regs(5),
 268	stream_enc_regs(6)
 269};
 270
 271static const struct dce_stream_encoder_shift se_shift = {
 272		SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT)
 273};
 274
 275static const struct dce_stream_encoder_mask se_mask = {
 276		SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK)
 277};
 278
 279#define opp_regs(id)\
 280[id] = {\
 281	OPP_DCE_80_REG_LIST(id),\
 282}
 283
 284static const struct dce_opp_registers opp_regs[] = {
 285	opp_regs(0),
 286	opp_regs(1),
 287	opp_regs(2),
 288	opp_regs(3),
 289	opp_regs(4),
 290	opp_regs(5)
 291};
 292
 293static const struct dce_opp_shift opp_shift = {
 294	OPP_COMMON_MASK_SH_LIST_DCE_80(__SHIFT)
 295};
 296
 297static const struct dce_opp_mask opp_mask = {
 298	OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK)
 299};
 300
 301#define audio_regs(id)\
 302[id] = {\
 303	AUD_COMMON_REG_LIST(id)\
 304}
 305
 306static const struct dce_audio_registers audio_regs[] = {
 307	audio_regs(0),
 308	audio_regs(1),
 309	audio_regs(2),
 310	audio_regs(3),
 311	audio_regs(4),
 312	audio_regs(5),
 313	audio_regs(6),
 314};
 315
 316static const struct dce_audio_shift audio_shift = {
 317		AUD_COMMON_MASK_SH_LIST(__SHIFT)
 318};
 319
 320static const struct dce_aduio_mask audio_mask = {
 321		AUD_COMMON_MASK_SH_LIST(_MASK)
 322};
 323
 324#define clk_src_regs(id)\
 325[id] = {\
 326	CS_COMMON_REG_LIST_DCE_80(id),\
 327}
 328
 329
 330static const struct dce110_clk_src_regs clk_src_regs[] = {
 331	clk_src_regs(0),
 332	clk_src_regs(1),
 333	clk_src_regs(2)
 334};
 335
 336static const struct dce110_clk_src_shift cs_shift = {
 337		CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 338};
 339
 340static const struct dce110_clk_src_mask cs_mask = {
 341		CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 342};
 343
 344static const struct bios_registers bios_regs = {
 345	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 346};
 347
 348static const struct resource_caps res_cap = {
 349		.num_timing_generator = 6,
 350		.num_audio = 6,
 351		.num_stream_encoder = 6,
 352		.num_pll = 3,
 353};
 354
 355static const struct resource_caps res_cap_81 = {
 356		.num_timing_generator = 4,
 357		.num_audio = 7,
 358		.num_stream_encoder = 7,
 359		.num_pll = 3,
 360};
 361
 362static const struct resource_caps res_cap_83 = {
 363		.num_timing_generator = 2,
 364		.num_audio = 6,
 365		.num_stream_encoder = 6,
 366		.num_pll = 2,
 367};
 368
 369static const struct dce_dmcu_registers dmcu_regs = {
 370		DMCU_DCE80_REG_LIST()
 371};
 372
 373static const struct dce_dmcu_shift dmcu_shift = {
 374		DMCU_MASK_SH_LIST_DCE80(__SHIFT)
 375};
 376
 377static const struct dce_dmcu_mask dmcu_mask = {
 378		DMCU_MASK_SH_LIST_DCE80(_MASK)
 379};
 380static const struct dce_abm_registers abm_regs = {
 381		ABM_DCE110_COMMON_REG_LIST()
 382};
 383
 384static const struct dce_abm_shift abm_shift = {
 385		ABM_MASK_SH_LIST_DCE110(__SHIFT)
 386};
 387
 388static const struct dce_abm_mask abm_mask = {
 389		ABM_MASK_SH_LIST_DCE110(_MASK)
 390};
 391
 392#define CTX  ctx
 393#define REG(reg) mm ## reg
 394
 395#ifndef mmCC_DC_HDMI_STRAPS
 396#define mmCC_DC_HDMI_STRAPS 0x1918
 397#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
 398#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
 399#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
 400#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
 401#endif
 402
 403static void read_dce_straps(
 404	struct dc_context *ctx,
 405	struct resource_straps *straps)
 406{
 407	REG_GET_2(CC_DC_HDMI_STRAPS,
 408			HDMI_DISABLE, &straps->hdmi_disable,
 409			AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
 410
 411	REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
 412}
 413
 414static struct audio *create_audio(
 415		struct dc_context *ctx, unsigned int inst)
 416{
 417	return dce_audio_create(ctx, inst,
 418			&audio_regs[inst], &audio_shift, &audio_mask);
 419}
 420
 421static struct timing_generator *dce80_timing_generator_create(
 422		struct dc_context *ctx,
 423		uint32_t instance,
 424		const struct dce110_timing_generator_offsets *offsets)
 425{
 426	struct dce110_timing_generator *tg110 =
 427		kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
 428
 429	if (!tg110)
 430		return NULL;
 431
 432	dce80_timing_generator_construct(tg110, ctx, instance, offsets);
 433	return &tg110->base;
 434}
 435
 436static struct output_pixel_processor *dce80_opp_create(
 437	struct dc_context *ctx,
 438	uint32_t inst)
 439{
 440	struct dce110_opp *opp =
 441		kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
 442
 443	if (!opp)
 444		return NULL;
 445
 446	dce110_opp_construct(opp,
 447			     ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 448	return &opp->base;
 449}
 450
 451static struct stream_encoder *dce80_stream_encoder_create(
 452	enum engine_id eng_id,
 453	struct dc_context *ctx)
 454{
 455	struct dce110_stream_encoder *enc110 =
 456		kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
 457
 458	if (!enc110)
 459		return NULL;
 460
 461	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 462					&stream_enc_regs[eng_id],
 463					&se_shift, &se_mask);
 464	return &enc110->base;
 465}
 466
 467#define SRII(reg_name, block, id)\
 468	.reg_name[id] = mm ## block ## id ## _ ## reg_name
 469
 470static const struct dce_hwseq_registers hwseq_reg = {
 471		HWSEQ_DCE8_REG_LIST()
 472};
 473
 474static const struct dce_hwseq_shift hwseq_shift = {
 475		HWSEQ_DCE8_MASK_SH_LIST(__SHIFT)
 476};
 477
 478static const struct dce_hwseq_mask hwseq_mask = {
 479		HWSEQ_DCE8_MASK_SH_LIST(_MASK)
 480};
 481
 482static struct dce_hwseq *dce80_hwseq_create(
 483	struct dc_context *ctx)
 484{
 485	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 486
 487	if (hws) {
 488		hws->ctx = ctx;
 489		hws->regs = &hwseq_reg;
 490		hws->shifts = &hwseq_shift;
 491		hws->masks = &hwseq_mask;
 492	}
 493	return hws;
 494}
 495
 496static const struct resource_create_funcs res_create_funcs = {
 497	.read_dce_straps = read_dce_straps,
 498	.create_audio = create_audio,
 499	.create_stream_encoder = dce80_stream_encoder_create,
 500	.create_hwseq = dce80_hwseq_create,
 501};
 502
 503#define mi_inst_regs(id) { \
 504	MI_DCE8_REG_LIST(id), \
 505	.MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
 506}
 507static const struct dce_mem_input_registers mi_regs[] = {
 508		mi_inst_regs(0),
 509		mi_inst_regs(1),
 510		mi_inst_regs(2),
 511		mi_inst_regs(3),
 512		mi_inst_regs(4),
 513		mi_inst_regs(5),
 514};
 515
 516static const struct dce_mem_input_shift mi_shifts = {
 517		MI_DCE8_MASK_SH_LIST(__SHIFT),
 518		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
 519};
 520
 521static const struct dce_mem_input_mask mi_masks = {
 522		MI_DCE8_MASK_SH_LIST(_MASK),
 523		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
 524};
 525
 526static struct mem_input *dce80_mem_input_create(
 527	struct dc_context *ctx,
 528	uint32_t inst)
 529{
 530	struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
 531					       GFP_KERNEL);
 532
 533	if (!dce_mi) {
 534		BREAK_TO_DEBUGGER();
 535		return NULL;
 536	}
 537
 538	dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
 539	dce_mi->wa.single_head_rdreq_dmif_limit = 2;
 540	return &dce_mi->base;
 541}
 542
 543static void dce80_transform_destroy(struct transform **xfm)
 544{
 545	kfree(TO_DCE_TRANSFORM(*xfm));
 546	*xfm = NULL;
 547}
 548
 549static struct transform *dce80_transform_create(
 550	struct dc_context *ctx,
 551	uint32_t inst)
 552{
 553	struct dce_transform *transform =
 554		kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
 555
 556	if (!transform)
 557		return NULL;
 558
 559	dce_transform_construct(transform, ctx, inst,
 560				&xfm_regs[inst], &xfm_shift, &xfm_mask);
 561	transform->prescaler_on = false;
 562	return &transform->base;
 563}
 564
 565static const struct encoder_feature_support link_enc_feature = {
 566		.max_hdmi_deep_color = COLOR_DEPTH_121212,
 567		.max_hdmi_pixel_clock = 297000,
 568		.flags.bits.IS_HBR2_CAPABLE = true,
 569		.flags.bits.IS_TPS3_CAPABLE = true,
 570		.flags.bits.IS_YCBCR_CAPABLE = true
 571};
 572
 573struct link_encoder *dce80_link_encoder_create(
 574	const struct encoder_init_data *enc_init_data)
 575{
 576	struct dce110_link_encoder *enc110 =
 577		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 578
 579	if (!enc110)
 580		return NULL;
 581
 582	dce110_link_encoder_construct(enc110,
 583				      enc_init_data,
 584				      &link_enc_feature,
 585				      &link_enc_regs[enc_init_data->transmitter],
 586				      &link_enc_aux_regs[enc_init_data->channel - 1],
 587				      &link_enc_hpd_regs[enc_init_data->hpd_source]);
 588	return &enc110->base;
 589}
 590
 591struct clock_source *dce80_clock_source_create(
 592	struct dc_context *ctx,
 593	struct dc_bios *bios,
 594	enum clock_source_id id,
 595	const struct dce110_clk_src_regs *regs,
 596	bool dp_clk_src)
 597{
 598	struct dce110_clk_src *clk_src =
 599		kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
 600
 601	if (!clk_src)
 602		return NULL;
 603
 604	if (dce110_clk_src_construct(clk_src, ctx, bios, id,
 605			regs, &cs_shift, &cs_mask)) {
 606		clk_src->base.dp_clk_src = dp_clk_src;
 607		return &clk_src->base;
 608	}
 609
 610	BREAK_TO_DEBUGGER();
 611	return NULL;
 612}
 613
 614void dce80_clock_source_destroy(struct clock_source **clk_src)
 615{
 616	kfree(TO_DCE110_CLK_SRC(*clk_src));
 617	*clk_src = NULL;
 618}
 619
 620static struct input_pixel_processor *dce80_ipp_create(
 621	struct dc_context *ctx, uint32_t inst)
 622{
 623	struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
 624
 625	if (!ipp) {
 626		BREAK_TO_DEBUGGER();
 627		return NULL;
 628	}
 629
 630	dce_ipp_construct(ipp, ctx, inst,
 631			&ipp_regs[inst], &ipp_shift, &ipp_mask);
 632	return &ipp->base;
 633}
 634
 635static void destruct(struct dce110_resource_pool *pool)
 636{
 637	unsigned int i;
 638
 639	for (i = 0; i < pool->base.pipe_count; i++) {
 640		if (pool->base.opps[i] != NULL)
 641			dce110_opp_destroy(&pool->base.opps[i]);
 642
 643		if (pool->base.transforms[i] != NULL)
 644			dce80_transform_destroy(&pool->base.transforms[i]);
 645
 646		if (pool->base.ipps[i] != NULL)
 647			dce_ipp_destroy(&pool->base.ipps[i]);
 648
 649		if (pool->base.mis[i] != NULL) {
 650			kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
 651			pool->base.mis[i] = NULL;
 652		}
 653
 654		if (pool->base.timing_generators[i] != NULL)	{
 655			kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
 656			pool->base.timing_generators[i] = NULL;
 657		}
 658	}
 659
 660	for (i = 0; i < pool->base.stream_enc_count; i++) {
 661		if (pool->base.stream_enc[i] != NULL)
 662			kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 663	}
 664
 665	for (i = 0; i < pool->base.clk_src_count; i++) {
 666		if (pool->base.clock_sources[i] != NULL) {
 667			dce80_clock_source_destroy(&pool->base.clock_sources[i]);
 668		}
 669	}
 670
 671	if (pool->base.abm != NULL)
 672			dce_abm_destroy(&pool->base.abm);
 673
 674	if (pool->base.dmcu != NULL)
 675			dce_dmcu_destroy(&pool->base.dmcu);
 676
 677	if (pool->base.dp_clock_source != NULL)
 678		dce80_clock_source_destroy(&pool->base.dp_clock_source);
 679
 680	for (i = 0; i < pool->base.audio_count; i++)	{
 681		if (pool->base.audios[i] != NULL) {
 682			dce_aud_destroy(&pool->base.audios[i]);
 683		}
 684	}
 685
 686	if (pool->base.display_clock != NULL)
 687		dce_disp_clk_destroy(&pool->base.display_clock);
 688
 689	if (pool->base.irqs != NULL) {
 690		dal_irq_service_destroy(&pool->base.irqs);
 691	}
 692}
 693
 694static enum dc_status build_mapped_resource(
 695		const struct dc *dc,
 696		struct dc_state *context,
 697		struct dc_stream_state *stream)
 698{
 699	struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
 700
 701	if (!pipe_ctx)
 702		return DC_ERROR_UNEXPECTED;
 703
 704	dce110_resource_build_pipe_hw_param(pipe_ctx);
 705
 706	resource_build_info_frame(pipe_ctx);
 707
 708	return DC_OK;
 709}
 710
 711bool dce80_validate_bandwidth(
 712	struct dc *dc,
 713	struct dc_state *context)
 714{
 715	/* TODO implement when needed but for now hardcode max value*/
 716	context->bw.dce.dispclk_khz = 681000;
 717	context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER;
 718
 719	return true;
 720}
 721
 722static bool dce80_validate_surface_sets(
 723		struct dc_state *context)
 724{
 725	int i;
 726
 727	for (i = 0; i < context->stream_count; i++) {
 728		if (context->stream_status[i].plane_count == 0)
 729			continue;
 730
 731		if (context->stream_status[i].plane_count > 1)
 732			return false;
 733
 734		if (context->stream_status[i].plane_states[0]->format
 735				>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 736			return false;
 737	}
 738
 739	return true;
 740}
 741
 742enum dc_status dce80_validate_global(
 743		struct dc *dc,
 744		struct dc_state *context)
 745{
 746	if (!dce80_validate_surface_sets(context))
 747		return DC_FAIL_SURFACE_VALIDATE;
 748
 749	return DC_OK;
 750}
 751
 752enum dc_status dce80_validate_guaranteed(
 753		struct dc *dc,
 754		struct dc_stream_state *dc_stream,
 755		struct dc_state *context)
 756{
 757	enum dc_status result = DC_ERROR_UNEXPECTED;
 758
 759	context->streams[0] = dc_stream;
 760	dc_stream_retain(context->streams[0]);
 761	context->stream_count++;
 762
 763	result = resource_map_pool_resources(dc, context, dc_stream);
 764
 765	if (result == DC_OK)
 766		result = resource_map_clock_resources(dc, context, dc_stream);
 767
 768	if (result == DC_OK)
 769		result = build_mapped_resource(dc, context, dc_stream);
 770
 771	if (result == DC_OK) {
 772		validate_guaranteed_copy_streams(
 773				context, dc->caps.max_streams);
 774		result = resource_build_scaling_params_for_context(dc, context);
 775	}
 776
 777	if (result == DC_OK)
 778		result = dce80_validate_bandwidth(dc, context);
 779
 780	return result;
 781}
 782
 783static void dce80_destroy_resource_pool(struct resource_pool **pool)
 784{
 785	struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
 786
 787	destruct(dce110_pool);
 788	kfree(dce110_pool);
 789	*pool = NULL;
 790}
 791
 792static const struct resource_funcs dce80_res_pool_funcs = {
 793	.destroy = dce80_destroy_resource_pool,
 794	.link_enc_create = dce80_link_encoder_create,
 795	.validate_guaranteed = dce80_validate_guaranteed,
 796	.validate_bandwidth = dce80_validate_bandwidth,
 797	.validate_plane = dce100_validate_plane,
 798	.add_stream_to_ctx = dce100_add_stream_to_ctx,
 799	.validate_global = dce80_validate_global
 800};
 801
 802static bool dce80_construct(
 803	uint8_t num_virtual_links,
 804	struct dc *dc,
 805	struct dce110_resource_pool *pool)
 806{
 807	unsigned int i;
 808	struct dc_context *ctx = dc->ctx;
 809	struct dc_firmware_info info;
 810	struct dc_bios *bp;
 811	struct dm_pp_static_clock_info static_clk_info = {0};
 812
 813	ctx->dc_bios->regs = &bios_regs;
 814
 815	pool->base.res_cap = &res_cap;
 816	pool->base.funcs = &dce80_res_pool_funcs;
 817
 818
 819	/*************************************************
 820	 *  Resource + asic cap harcoding                *
 821	 *************************************************/
 822	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
 823	pool->base.pipe_count = res_cap.num_timing_generator;
 824	pool->base.timing_generator_count = res_cap.num_timing_generator;
 825	dc->caps.max_downscale_ratio = 200;
 826	dc->caps.i2c_speed_in_khz = 40;
 827	dc->caps.max_cursor_size = 128;
 828	dc->caps.dual_link_dvi = true;
 829
 830	/*************************************************
 831	 *  Create resources                             *
 832	 *************************************************/
 833
 834	bp = ctx->dc_bios;
 835
 836	if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
 837		info.external_clock_source_frequency_for_dp != 0) {
 838		pool->base.dp_clock_source =
 839				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
 840
 841		pool->base.clock_sources[0] =
 842				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
 843		pool->base.clock_sources[1] =
 844				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
 845		pool->base.clock_sources[2] =
 846				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
 847		pool->base.clk_src_count = 3;
 848
 849	} else {
 850		pool->base.dp_clock_source =
 851				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
 852
 853		pool->base.clock_sources[0] =
 854				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
 855		pool->base.clock_sources[1] =
 856				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
 857		pool->base.clk_src_count = 2;
 858	}
 859
 860	if (pool->base.dp_clock_source == NULL) {
 861		dm_error("DC: failed to create dp clock source!\n");
 862		BREAK_TO_DEBUGGER();
 863		goto res_create_fail;
 864	}
 865
 866	for (i = 0; i < pool->base.clk_src_count; i++) {
 867		if (pool->base.clock_sources[i] == NULL) {
 868			dm_error("DC: failed to create clock sources!\n");
 869			BREAK_TO_DEBUGGER();
 870			goto res_create_fail;
 871		}
 872	}
 873
 874	pool->base.display_clock = dce_disp_clk_create(ctx,
 875			&disp_clk_regs,
 876			&disp_clk_shift,
 877			&disp_clk_mask);
 878	if (pool->base.display_clock == NULL) {
 879		dm_error("DC: failed to create display clock!\n");
 880		BREAK_TO_DEBUGGER();
 881		goto res_create_fail;
 882	}
 883
 884	pool->base.dmcu = dce_dmcu_create(ctx,
 885			&dmcu_regs,
 886			&dmcu_shift,
 887			&dmcu_mask);
 888	if (pool->base.dmcu == NULL) {
 889		dm_error("DC: failed to create dmcu!\n");
 890		BREAK_TO_DEBUGGER();
 891		goto res_create_fail;
 892	}
 893
 894	pool->base.abm = dce_abm_create(ctx,
 895			&abm_regs,
 896			&abm_shift,
 897			&abm_mask);
 898	if (pool->base.abm == NULL) {
 899		dm_error("DC: failed to create abm!\n");
 900		BREAK_TO_DEBUGGER();
 901		goto res_create_fail;
 902	}
 903	if (dm_pp_get_static_clocks(ctx, &static_clk_info))
 904		pool->base.display_clock->max_clks_state =
 905					static_clk_info.max_clocks_state;
 906
 907	{
 908		struct irq_service_init_data init_data;
 909		init_data.ctx = dc->ctx;
 910		pool->base.irqs = dal_irq_service_dce80_create(&init_data);
 911		if (!pool->base.irqs)
 912			goto res_create_fail;
 913	}
 914
 915	for (i = 0; i < pool->base.pipe_count; i++) {
 916		pool->base.timing_generators[i] = dce80_timing_generator_create(
 917				ctx, i, &dce80_tg_offsets[i]);
 918		if (pool->base.timing_generators[i] == NULL) {
 919			BREAK_TO_DEBUGGER();
 920			dm_error("DC: failed to create tg!\n");
 921			goto res_create_fail;
 922		}
 923
 924		pool->base.mis[i] = dce80_mem_input_create(ctx, i);
 925		if (pool->base.mis[i] == NULL) {
 926			BREAK_TO_DEBUGGER();
 927			dm_error("DC: failed to create memory input!\n");
 928			goto res_create_fail;
 929		}
 930
 931		pool->base.ipps[i] = dce80_ipp_create(ctx, i);
 932		if (pool->base.ipps[i] == NULL) {
 933			BREAK_TO_DEBUGGER();
 934			dm_error("DC: failed to create input pixel processor!\n");
 935			goto res_create_fail;
 936		}
 937
 938		pool->base.transforms[i] = dce80_transform_create(ctx, i);
 939		if (pool->base.transforms[i] == NULL) {
 940			BREAK_TO_DEBUGGER();
 941			dm_error("DC: failed to create transform!\n");
 942			goto res_create_fail;
 943		}
 944
 945		pool->base.opps[i] = dce80_opp_create(ctx, i);
 946		if (pool->base.opps[i] == NULL) {
 947			BREAK_TO_DEBUGGER();
 948			dm_error("DC: failed to create output pixel processor!\n");
 949			goto res_create_fail;
 950		}
 951	}
 952
 953	dc->caps.max_planes =  pool->base.pipe_count;
 954
 955	if (!resource_construct(num_virtual_links, dc, &pool->base,
 956			&res_create_funcs))
 957		goto res_create_fail;
 958
 959	/* Create hardware sequencer */
 960	dce80_hw_sequencer_construct(dc);
 961
 962	return true;
 963
 964res_create_fail:
 965	destruct(pool);
 966	return false;
 967}
 968
 969struct resource_pool *dce80_create_resource_pool(
 970	uint8_t num_virtual_links,
 971	struct dc *dc)
 972{
 973	struct dce110_resource_pool *pool =
 974		kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
 975
 976	if (!pool)
 977		return NULL;
 978
 979	if (dce80_construct(num_virtual_links, dc, pool))
 980		return &pool->base;
 981
 982	BREAK_TO_DEBUGGER();
 983	return NULL;
 984}
 985
 986static bool dce81_construct(
 987	uint8_t num_virtual_links,
 988	struct dc *dc,
 989	struct dce110_resource_pool *pool)
 990{
 991	unsigned int i;
 992	struct dc_context *ctx = dc->ctx;
 993	struct dc_firmware_info info;
 994	struct dc_bios *bp;
 995	struct dm_pp_static_clock_info static_clk_info = {0};
 996
 997	ctx->dc_bios->regs = &bios_regs;
 998
 999	pool->base.res_cap = &res_cap_81;
1000	pool->base.funcs = &dce80_res_pool_funcs;
1001
1002
1003	/*************************************************
1004	 *  Resource + asic cap harcoding                *
1005	 *************************************************/
1006	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1007	pool->base.pipe_count = res_cap_81.num_timing_generator;
1008	pool->base.timing_generator_count = res_cap_81.num_timing_generator;
1009	dc->caps.max_downscale_ratio = 200;
1010	dc->caps.i2c_speed_in_khz = 40;
1011	dc->caps.max_cursor_size = 128;
1012	dc->caps.is_apu = true;
1013
1014	/*************************************************
1015	 *  Create resources                             *
1016	 *************************************************/
1017
1018	bp = ctx->dc_bios;
1019
1020	if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
1021		info.external_clock_source_frequency_for_dp != 0) {
1022		pool->base.dp_clock_source =
1023				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1024
1025		pool->base.clock_sources[0] =
1026				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
1027		pool->base.clock_sources[1] =
1028				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1029		pool->base.clock_sources[2] =
1030				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1031		pool->base.clk_src_count = 3;
1032
1033	} else {
1034		pool->base.dp_clock_source =
1035				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
1036
1037		pool->base.clock_sources[0] =
1038				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1039		pool->base.clock_sources[1] =
1040				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1041		pool->base.clk_src_count = 2;
1042	}
1043
1044	if (pool->base.dp_clock_source == NULL) {
1045		dm_error("DC: failed to create dp clock source!\n");
1046		BREAK_TO_DEBUGGER();
1047		goto res_create_fail;
1048	}
1049
1050	for (i = 0; i < pool->base.clk_src_count; i++) {
1051		if (pool->base.clock_sources[i] == NULL) {
1052			dm_error("DC: failed to create clock sources!\n");
1053			BREAK_TO_DEBUGGER();
1054			goto res_create_fail;
1055		}
1056	}
1057
1058	pool->base.display_clock = dce_disp_clk_create(ctx,
1059			&disp_clk_regs,
1060			&disp_clk_shift,
1061			&disp_clk_mask);
1062	if (pool->base.display_clock == NULL) {
1063		dm_error("DC: failed to create display clock!\n");
1064		BREAK_TO_DEBUGGER();
1065		goto res_create_fail;
1066	}
1067
1068	pool->base.dmcu = dce_dmcu_create(ctx,
1069			&dmcu_regs,
1070			&dmcu_shift,
1071			&dmcu_mask);
1072	if (pool->base.dmcu == NULL) {
1073		dm_error("DC: failed to create dmcu!\n");
1074		BREAK_TO_DEBUGGER();
1075		goto res_create_fail;
1076	}
1077
1078	pool->base.abm = dce_abm_create(ctx,
1079			&abm_regs,
1080			&abm_shift,
1081			&abm_mask);
1082	if (pool->base.abm == NULL) {
1083		dm_error("DC: failed to create abm!\n");
1084		BREAK_TO_DEBUGGER();
1085		goto res_create_fail;
1086	}
1087
1088	if (dm_pp_get_static_clocks(ctx, &static_clk_info))
1089		pool->base.display_clock->max_clks_state =
1090					static_clk_info.max_clocks_state;
1091
1092	{
1093		struct irq_service_init_data init_data;
1094		init_data.ctx = dc->ctx;
1095		pool->base.irqs = dal_irq_service_dce80_create(&init_data);
1096		if (!pool->base.irqs)
1097			goto res_create_fail;
1098	}
1099
1100	for (i = 0; i < pool->base.pipe_count; i++) {
1101		pool->base.timing_generators[i] = dce80_timing_generator_create(
1102				ctx, i, &dce80_tg_offsets[i]);
1103		if (pool->base.timing_generators[i] == NULL) {
1104			BREAK_TO_DEBUGGER();
1105			dm_error("DC: failed to create tg!\n");
1106			goto res_create_fail;
1107		}
1108
1109		pool->base.mis[i] = dce80_mem_input_create(ctx, i);
1110		if (pool->base.mis[i] == NULL) {
1111			BREAK_TO_DEBUGGER();
1112			dm_error("DC: failed to create memory input!\n");
1113			goto res_create_fail;
1114		}
1115
1116		pool->base.ipps[i] = dce80_ipp_create(ctx, i);
1117		if (pool->base.ipps[i] == NULL) {
1118			BREAK_TO_DEBUGGER();
1119			dm_error("DC: failed to create input pixel processor!\n");
1120			goto res_create_fail;
1121		}
1122
1123		pool->base.transforms[i] = dce80_transform_create(ctx, i);
1124		if (pool->base.transforms[i] == NULL) {
1125			BREAK_TO_DEBUGGER();
1126			dm_error("DC: failed to create transform!\n");
1127			goto res_create_fail;
1128		}
1129
1130		pool->base.opps[i] = dce80_opp_create(ctx, i);
1131		if (pool->base.opps[i] == NULL) {
1132			BREAK_TO_DEBUGGER();
1133			dm_error("DC: failed to create output pixel processor!\n");
1134			goto res_create_fail;
1135		}
1136	}
1137
1138	dc->caps.max_planes =  pool->base.pipe_count;
1139
1140	if (!resource_construct(num_virtual_links, dc, &pool->base,
1141			&res_create_funcs))
1142		goto res_create_fail;
1143
1144	/* Create hardware sequencer */
1145	dce80_hw_sequencer_construct(dc);
1146
1147	return true;
1148
1149res_create_fail:
1150	destruct(pool);
1151	return false;
1152}
1153
1154struct resource_pool *dce81_create_resource_pool(
1155	uint8_t num_virtual_links,
1156	struct dc *dc)
1157{
1158	struct dce110_resource_pool *pool =
1159		kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1160
1161	if (!pool)
1162		return NULL;
1163
1164	if (dce81_construct(num_virtual_links, dc, pool))
1165		return &pool->base;
1166
1167	BREAK_TO_DEBUGGER();
1168	return NULL;
1169}
1170
1171static bool dce83_construct(
1172	uint8_t num_virtual_links,
1173	struct dc *dc,
1174	struct dce110_resource_pool *pool)
1175{
1176	unsigned int i;
1177	struct dc_context *ctx = dc->ctx;
1178	struct dc_firmware_info info;
1179	struct dc_bios *bp;
1180	struct dm_pp_static_clock_info static_clk_info = {0};
1181
1182	ctx->dc_bios->regs = &bios_regs;
1183
1184	pool->base.res_cap = &res_cap_83;
1185	pool->base.funcs = &dce80_res_pool_funcs;
1186
1187
1188	/*************************************************
1189	 *  Resource + asic cap harcoding                *
1190	 *************************************************/
1191	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1192	pool->base.pipe_count = res_cap_83.num_timing_generator;
1193	pool->base.timing_generator_count = res_cap_83.num_timing_generator;
1194	dc->caps.max_downscale_ratio = 200;
1195	dc->caps.i2c_speed_in_khz = 40;
1196	dc->caps.max_cursor_size = 128;
1197	dc->caps.is_apu = true;
1198
1199	/*************************************************
1200	 *  Create resources                             *
1201	 *************************************************/
1202
1203	bp = ctx->dc_bios;
1204
1205	if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
1206		info.external_clock_source_frequency_for_dp != 0) {
1207		pool->base.dp_clock_source =
1208				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1209
1210		pool->base.clock_sources[0] =
1211				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], false);
1212		pool->base.clock_sources[1] =
1213				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false);
1214		pool->base.clk_src_count = 2;
1215
1216	} else {
1217		pool->base.dp_clock_source =
1218				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], true);
1219
1220		pool->base.clock_sources[0] =
1221				dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false);
1222		pool->base.clk_src_count = 1;
1223	}
1224
1225	if (pool->base.dp_clock_source == NULL) {
1226		dm_error("DC: failed to create dp clock source!\n");
1227		BREAK_TO_DEBUGGER();
1228		goto res_create_fail;
1229	}
1230
1231	for (i = 0; i < pool->base.clk_src_count; i++) {
1232		if (pool->base.clock_sources[i] == NULL) {
1233			dm_error("DC: failed to create clock sources!\n");
1234			BREAK_TO_DEBUGGER();
1235			goto res_create_fail;
1236		}
1237	}
1238
1239	pool->base.display_clock = dce_disp_clk_create(ctx,
1240			&disp_clk_regs,
1241			&disp_clk_shift,
1242			&disp_clk_mask);
1243	if (pool->base.display_clock == NULL) {
1244		dm_error("DC: failed to create display clock!\n");
1245		BREAK_TO_DEBUGGER();
1246		goto res_create_fail;
1247	}
1248
1249	pool->base.dmcu = dce_dmcu_create(ctx,
1250			&dmcu_regs,
1251			&dmcu_shift,
1252			&dmcu_mask);
1253	if (pool->base.dmcu == NULL) {
1254		dm_error("DC: failed to create dmcu!\n");
1255		BREAK_TO_DEBUGGER();
1256		goto res_create_fail;
1257	}
1258
1259	pool->base.abm = dce_abm_create(ctx,
1260			&abm_regs,
1261			&abm_shift,
1262			&abm_mask);
1263	if (pool->base.abm == NULL) {
1264		dm_error("DC: failed to create abm!\n");
1265		BREAK_TO_DEBUGGER();
1266		goto res_create_fail;
1267	}
1268
1269	if (dm_pp_get_static_clocks(ctx, &static_clk_info))
1270		pool->base.display_clock->max_clks_state =
1271					static_clk_info.max_clocks_state;
1272
1273	{
1274		struct irq_service_init_data init_data;
1275		init_data.ctx = dc->ctx;
1276		pool->base.irqs = dal_irq_service_dce80_create(&init_data);
1277		if (!pool->base.irqs)
1278			goto res_create_fail;
1279	}
1280
1281	for (i = 0; i < pool->base.pipe_count; i++) {
1282		pool->base.timing_generators[i] = dce80_timing_generator_create(
1283				ctx, i, &dce80_tg_offsets[i]);
1284		if (pool->base.timing_generators[i] == NULL) {
1285			BREAK_TO_DEBUGGER();
1286			dm_error("DC: failed to create tg!\n");
1287			goto res_create_fail;
1288		}
1289
1290		pool->base.mis[i] = dce80_mem_input_create(ctx, i);
1291		if (pool->base.mis[i] == NULL) {
1292			BREAK_TO_DEBUGGER();
1293			dm_error("DC: failed to create memory input!\n");
1294			goto res_create_fail;
1295		}
1296
1297		pool->base.ipps[i] = dce80_ipp_create(ctx, i);
1298		if (pool->base.ipps[i] == NULL) {
1299			BREAK_TO_DEBUGGER();
1300			dm_error("DC: failed to create input pixel processor!\n");
1301			goto res_create_fail;
1302		}
1303
1304		pool->base.transforms[i] = dce80_transform_create(ctx, i);
1305		if (pool->base.transforms[i] == NULL) {
1306			BREAK_TO_DEBUGGER();
1307			dm_error("DC: failed to create transform!\n");
1308			goto res_create_fail;
1309		}
1310
1311		pool->base.opps[i] = dce80_opp_create(ctx, i);
1312		if (pool->base.opps[i] == NULL) {
1313			BREAK_TO_DEBUGGER();
1314			dm_error("DC: failed to create output pixel processor!\n");
1315			goto res_create_fail;
1316		}
1317	}
1318
1319	dc->caps.max_planes =  pool->base.pipe_count;
1320
1321	if (!resource_construct(num_virtual_links, dc, &pool->base,
1322			&res_create_funcs))
1323		goto res_create_fail;
1324
1325	/* Create hardware sequencer */
1326	dce80_hw_sequencer_construct(dc);
1327
1328	return true;
1329
1330res_create_fail:
1331	destruct(pool);
1332	return false;
1333}
1334
1335struct resource_pool *dce83_create_resource_pool(
1336	uint8_t num_virtual_links,
1337	struct dc *dc)
1338{
1339	struct dce110_resource_pool *pool =
1340		kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1341
1342	if (!pool)
1343		return NULL;
1344
1345	if (dce83_construct(num_virtual_links, dc, pool))
1346		return &pool->base;
1347
1348	BREAK_TO_DEBUGGER();
1349	return NULL;
1350}