Linux Audio

Check our new training course

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