File Index
Files and directories
Sign in
FILE

dce60_resource.c

File preview with syntax highlighting.

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