File Index
Files and directories
Sign in
FILE

dce100_resource.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c C
   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 "dm_services.h"
  27
  28#include "link_encoder.h"
  29#include "stream_encoder.h"
  30
  31#include "resource.h"
  32#include "clk_mgr.h"
  33#include "include/irq_service_interface.h"
  34#include "virtual/virtual_stream_encoder.h"
  35#include "dce110/dce110_resource.h"
  36#include "dce110/dce110_timing_generator.h"
  37#include "irq/dce110/irq_service_dce110.h"
  38#include "dce/dce_link_encoder.h"
  39#include "dce/dce_stream_encoder.h"
  40#include "dce/dce_mem_input.h"
  41#include "dce/dce_ipp.h"
  42#include "dce/dce_transform.h"
  43#include "dce/dce_opp.h"
  44#include "dce/dce_clock_source.h"
  45#include "dce/dce_audio.h"
  46#include "dce/dce_hwseq.h"
  47#include "dce100/dce100_hwseq.h"
  48#include "dce/dce_panel_cntl.h"
  49
  50#include "reg_helper.h"
  51
  52#include "dce/dce_10_0_d.h"
  53#include "dce/dce_10_0_sh_mask.h"
  54
  55#include "dce/dce_dmcu.h"
  56#include "dce/dce_aux.h"
  57#include "dce/dce_abm.h"
  58#include "dce/dce_i2c.h"
  59
  60#include "dce100_resource.h"
  61
  62#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
  63#include "gmc/gmc_8_2_d.h"
  64#include "gmc/gmc_8_2_sh_mask.h"
  65#endif
  66
  67#ifndef mmDP_DPHY_INTERNAL_CTRL
  68	#define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
  69	#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
  70	#define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
  71	#define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
  72	#define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
  73	#define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
  74	#define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
  75	#define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
  76	#define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
  77	#define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
  78#endif
  79
  80#ifndef mmBIOS_SCRATCH_2
  81	#define mmBIOS_SCRATCH_0 0x05C9
  82	#define mmBIOS_SCRATCH_2 0x05CB
  83	#define mmBIOS_SCRATCH_3 0x05CC
  84	#define mmBIOS_SCRATCH_6 0x05CF
  85#endif
  86
  87#ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
  88	#define mmDP_DPHY_BS_SR_SWAP_CNTL                       0x4ADC
  89	#define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL                   0x4ADC
  90	#define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL                   0x4BDC
  91	#define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL                   0x4CDC
  92	#define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL                   0x4DDC
  93	#define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL                   0x4EDC
  94	#define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL                   0x4FDC
  95	#define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL                   0x54DC
  96#endif
  97
  98#ifndef mmDP_DPHY_FAST_TRAINING
  99	#define mmDP_DPHY_FAST_TRAINING                         0x4ABC
 100	#define mmDP0_DP_DPHY_FAST_TRAINING                     0x4ABC
 101	#define mmDP1_DP_DPHY_FAST_TRAINING                     0x4BBC
 102	#define mmDP2_DP_DPHY_FAST_TRAINING                     0x4CBC
 103	#define mmDP3_DP_DPHY_FAST_TRAINING                     0x4DBC
 104	#define mmDP4_DP_DPHY_FAST_TRAINING                     0x4EBC
 105	#define mmDP5_DP_DPHY_FAST_TRAINING                     0x4FBC
 106	#define mmDP6_DP_DPHY_FAST_TRAINING                     0x54BC
 107#endif
 108
 109static const struct dce110_timing_generator_offsets dce100_tg_offsets[] = {
 110	{
 111		.crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
 112		.dcp =  (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
 113	},
 114	{
 115		.crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
 116		.dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
 117	},
 118	{
 119		.crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
 120		.dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
 121	},
 122	{
 123		.crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
 124		.dcp =  (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
 125	},
 126	{
 127		.crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
 128		.dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
 129	},
 130	{
 131		.crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
 132		.dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
 133	}
 134};
 135
 136/* set register offset */
 137#define SR(reg_name)\
 138	.reg_name = mm ## reg_name
 139
 140/* set register offset with instance */
 141#define SRI(reg_name, block, id)\
 142	.reg_name = mm ## block ## id ## _ ## reg_name
 143
 144#define ipp_regs(id)\
 145[id] = {\
 146		IPP_DCE100_REG_LIST_DCE_BASE(id)\
 147}
 148
 149static const struct dce_ipp_registers ipp_regs[] = {
 150		ipp_regs(0),
 151		ipp_regs(1),
 152		ipp_regs(2),
 153		ipp_regs(3),
 154		ipp_regs(4),
 155		ipp_regs(5)
 156};
 157
 158static const struct dce_ipp_shift ipp_shift = {
 159		IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 160};
 161
 162static const struct dce_ipp_mask ipp_mask = {
 163		IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 164};
 165
 166#define transform_regs(id)\
 167[id] = {\
 168		XFM_COMMON_REG_LIST_DCE100(id)\
 169}
 170
 171static const struct dce_transform_registers xfm_regs[] = {
 172		transform_regs(0),
 173		transform_regs(1),
 174		transform_regs(2),
 175		transform_regs(3),
 176		transform_regs(4),
 177		transform_regs(5)
 178};
 179
 180static const struct dce_transform_shift xfm_shift = {
 181		XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 182};
 183
 184static const struct dce_transform_mask xfm_mask = {
 185		XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
 186};
 187
 188#define aux_regs(id)\
 189[id] = {\
 190	AUX_REG_LIST(id)\
 191}
 192
 193static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
 194		aux_regs(0),
 195		aux_regs(1),
 196		aux_regs(2),
 197		aux_regs(3),
 198		aux_regs(4),
 199		aux_regs(5)
 200};
 201
 202#define hpd_regs(id)\
 203[id] = {\
 204	HPD_REG_LIST(id)\
 205}
 206
 207static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
 208		hpd_regs(0),
 209		hpd_regs(1),
 210		hpd_regs(2),
 211		hpd_regs(3),
 212		hpd_regs(4),
 213		hpd_regs(5)
 214};
 215
 216#define link_regs(id)\
 217[id] = {\
 218	LE_DCE100_REG_LIST(id)\
 219}
 220
 221static const struct dce110_link_enc_registers link_enc_regs[] = {
 222	link_regs(0),
 223	link_regs(1),
 224	link_regs(2),
 225	link_regs(3),
 226	link_regs(4),
 227	link_regs(5),
 228	link_regs(6),
 229	{ .DAC_ENABLE = mmDAC_ENABLE },
 230};
 231
 232#define stream_enc_regs(id)\
 233[id] = {\
 234	SE_COMMON_REG_LIST_DCE_BASE(id),\
 235	.AFMT_CNTL = 0,\
 236}
 237
 238static const struct dce110_stream_enc_registers stream_enc_regs[] = {
 239	stream_enc_regs(0),
 240	stream_enc_regs(1),
 241	stream_enc_regs(2),
 242	stream_enc_regs(3),
 243	stream_enc_regs(4),
 244	stream_enc_regs(5),
 245	stream_enc_regs(6),
 246	{SR(DAC_SOURCE_SELECT),} /* DACA */
 247};
 248
 249static const struct dce_stream_encoder_shift se_shift = {
 250		SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT)
 251};
 252
 253static const struct dce_stream_encoder_mask se_mask = {
 254		SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK)
 255};
 256
 257static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
 258	{ DCE_PANEL_CNTL_REG_LIST() }
 259};
 260
 261static const struct dce_panel_cntl_shift panel_cntl_shift = {
 262	DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
 263};
 264
 265static const struct dce_panel_cntl_mask panel_cntl_mask = {
 266	DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
 267};
 268
 269#define opp_regs(id)\
 270[id] = {\
 271	OPP_DCE_100_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_100(__SHIFT)
 285};
 286
 287static const struct dce_opp_mask opp_mask = {
 288	OPP_COMMON_MASK_SH_LIST_DCE_100(_MASK)
 289};
 290#define aux_engine_regs(id)\
 291[id] = {\
 292	AUX_COMMON_REG_LIST(id), \
 293	.AUX_RESET_MASK = 0 \
 294}
 295
 296static const struct dce110_aux_registers aux_engine_regs[] = {
 297		aux_engine_regs(0),
 298		aux_engine_regs(1),
 299		aux_engine_regs(2),
 300		aux_engine_regs(3),
 301		aux_engine_regs(4),
 302		aux_engine_regs(5)
 303};
 304
 305#define audio_regs(id)\
 306[id] = {\
 307	AUD_COMMON_REG_LIST(id)\
 308}
 309
 310static const struct dce_audio_registers audio_regs[] = {
 311	audio_regs(0),
 312	audio_regs(1),
 313	audio_regs(2),
 314	audio_regs(3),
 315	audio_regs(4),
 316	audio_regs(5),
 317	audio_regs(6),
 318};
 319
 320static const struct dce_audio_shift audio_shift = {
 321		AUD_COMMON_MASK_SH_LIST(__SHIFT)
 322};
 323
 324static const struct dce_audio_mask audio_mask = {
 325		AUD_COMMON_MASK_SH_LIST(_MASK)
 326};
 327
 328#define clk_src_regs(id)\
 329[id] = {\
 330	CS_COMMON_REG_LIST_DCE_100_110(id),\
 331}
 332
 333static const struct dce110_clk_src_regs clk_src_regs[] = {
 334	clk_src_regs(0),
 335	clk_src_regs(1),
 336	clk_src_regs(2)
 337};
 338
 339static const struct dce110_clk_src_shift cs_shift = {
 340		CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 341};
 342
 343static const struct dce110_clk_src_mask cs_mask = {
 344		CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 345};
 346
 347static const struct dce_dmcu_registers dmcu_regs = {
 348		DMCU_DCE110_COMMON_REG_LIST()
 349};
 350
 351static const struct dce_dmcu_shift dmcu_shift = {
 352		DMCU_MASK_SH_LIST_DCE110(__SHIFT)
 353};
 354
 355static const struct dce_dmcu_mask dmcu_mask = {
 356		DMCU_MASK_SH_LIST_DCE110(_MASK)
 357};
 358
 359static const struct dce_abm_registers abm_regs = {
 360		ABM_DCE110_COMMON_REG_LIST()
 361};
 362
 363static const struct dce_abm_shift abm_shift = {
 364		ABM_MASK_SH_LIST_DCE110(__SHIFT)
 365};
 366
 367static const struct dce_abm_mask abm_mask = {
 368		ABM_MASK_SH_LIST_DCE110(_MASK)
 369};
 370
 371#define DCFE_MEM_PWR_CTRL_REG_BASE 0x1b03
 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 dc_plane_cap plane_cap = {
 389	.type = DC_PLANE_TYPE_DCE_RGB,
 390
 391	.pixel_format_support = {
 392			.argb8888 = true,
 393			.nv12 = false,
 394			.fp16 = true
 395	},
 396
 397	.max_upscale_factor = {
 398			.argb8888 = 16000,
 399			.nv12 = 1,
 400			.fp16 = 1
 401	},
 402
 403	.max_downscale_factor = {
 404			.argb8888 = 250,
 405			.nv12 = 1,
 406			.fp16 = 1
 407	}
 408};
 409
 410static const struct dc_debug_options debug_defaults = { 0 };
 411
 412static const struct dc_check_config config_defaults = {
 413	.enable_legacy_fast_update = true,
 414};
 415
 416#define CTX  ctx
 417#define REG(reg) mm ## reg
 418
 419#ifndef mmCC_DC_HDMI_STRAPS
 420#define mmCC_DC_HDMI_STRAPS 0x1918
 421#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
 422#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
 423#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
 424#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
 425#endif
 426
 427static int map_transmitter_id_to_phy_instance(
 428	enum transmitter transmitter)
 429{
 430	switch (transmitter) {
 431	case TRANSMITTER_UNIPHY_A:
 432		return 0;
 433	case TRANSMITTER_UNIPHY_B:
 434		return 1;
 435	case TRANSMITTER_UNIPHY_C:
 436		return 2;
 437	case TRANSMITTER_UNIPHY_D:
 438		return 3;
 439	case TRANSMITTER_UNIPHY_E:
 440		return 4;
 441	case TRANSMITTER_UNIPHY_F:
 442		return 5;
 443	case TRANSMITTER_UNIPHY_G:
 444		return 6;
 445	default:
 446		ASSERT(0);
 447		return 0;
 448	}
 449}
 450
 451static void read_dce_straps(
 452	struct dc_context *ctx,
 453	struct resource_straps *straps)
 454{
 455	REG_GET_2(CC_DC_HDMI_STRAPS,
 456			HDMI_DISABLE, &straps->hdmi_disable,
 457			AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
 458
 459	REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
 460}
 461
 462static struct audio *create_audio(
 463		struct dc_context *ctx, unsigned int inst)
 464{
 465	return dce_audio_create(ctx, inst,
 466			&audio_regs[inst], &audio_shift, &audio_mask);
 467}
 468
 469static struct timing_generator *dce100_timing_generator_create(
 470		struct dc_context *ctx,
 471		uint32_t instance,
 472		const struct dce110_timing_generator_offsets *offsets)
 473{
 474	struct dce110_timing_generator *tg110 =
 475		kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
 476
 477	if (!tg110)
 478		return NULL;
 479
 480	dce110_timing_generator_construct(tg110, ctx, instance, offsets);
 481	return &tg110->base;
 482}
 483
 484static struct stream_encoder *dce100_stream_encoder_create(
 485	enum engine_id eng_id,
 486	struct dc_context *ctx)
 487{
 488	struct dce110_stream_encoder *enc110 =
 489		kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
 490
 491	if (!enc110)
 492		return NULL;
 493
 494	if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) {
 495		dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 496			&stream_enc_regs[eng_id], &se_shift, &se_mask);
 497		return &enc110->base;
 498	}
 499
 500	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 501					&stream_enc_regs[eng_id], &se_shift, &se_mask);
 502	return &enc110->base;
 503}
 504
 505#define SRII(reg_name, block, id)\
 506	.reg_name[id] = mm ## block ## id ## _ ## reg_name
 507
 508static const struct dce_hwseq_registers hwseq_reg = {
 509		HWSEQ_DCE10_REG_LIST()
 510};
 511
 512static const struct dce_hwseq_shift hwseq_shift = {
 513		HWSEQ_DCE10_MASK_SH_LIST(__SHIFT)
 514};
 515
 516static const struct dce_hwseq_mask hwseq_mask = {
 517		HWSEQ_DCE10_MASK_SH_LIST(_MASK)
 518};
 519
 520static struct dce_hwseq *dce100_hwseq_create(
 521	struct dc_context *ctx)
 522{
 523	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 524
 525	if (hws) {
 526		hws->ctx = ctx;
 527		hws->regs = &hwseq_reg;
 528		hws->shifts = &hwseq_shift;
 529		hws->masks = &hwseq_mask;
 530	}
 531	return hws;
 532}
 533
 534static const struct resource_create_funcs res_create_funcs = {
 535	.read_dce_straps = read_dce_straps,
 536	.create_audio = create_audio,
 537	.create_stream_encoder = dce100_stream_encoder_create,
 538	.create_hwseq = dce100_hwseq_create,
 539};
 540
 541#define mi_inst_regs(id) { \
 542	MI_DCE8_REG_LIST(id), \
 543	.MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
 544}
 545static const struct dce_mem_input_registers mi_regs[] = {
 546		mi_inst_regs(0),
 547		mi_inst_regs(1),
 548		mi_inst_regs(2),
 549		mi_inst_regs(3),
 550		mi_inst_regs(4),
 551		mi_inst_regs(5),
 552};
 553
 554static const struct dce_mem_input_shift mi_shifts = {
 555		MI_DCE8_MASK_SH_LIST(__SHIFT),
 556		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
 557};
 558
 559static const struct dce_mem_input_mask mi_masks = {
 560		MI_DCE8_MASK_SH_LIST(_MASK),
 561		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
 562};
 563
 564static const struct dce110_aux_registers_shift aux_shift = {
 565	DCE10_AUX_MASK_SH_LIST(__SHIFT)
 566};
 567
 568static const struct dce110_aux_registers_mask aux_mask = {
 569	DCE10_AUX_MASK_SH_LIST(_MASK)
 570};
 571
 572static struct mem_input *dce100_mem_input_create(
 573	struct dc_context *ctx,
 574	uint32_t inst)
 575{
 576	struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
 577					       GFP_KERNEL);
 578
 579	if (!dce_mi) {
 580		BREAK_TO_DEBUGGER();
 581		return NULL;
 582	}
 583
 584	dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
 585	dce_mi->wa.single_head_rdreq_dmif_limit = 2;
 586	return &dce_mi->base;
 587}
 588
 589static void dce100_transform_destroy(struct transform **xfm)
 590{
 591	kfree(TO_DCE_TRANSFORM(*xfm));
 592	*xfm = NULL;
 593}
 594
 595static struct transform *dce100_transform_create(
 596	struct dc_context *ctx,
 597	uint32_t inst)
 598{
 599	struct dce_transform *transform =
 600		kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
 601
 602	if (!transform)
 603		return NULL;
 604
 605	dce_transform_construct(transform, ctx, inst,
 606				&xfm_regs[inst], &xfm_shift, &xfm_mask);
 607	return &transform->base;
 608}
 609
 610static struct input_pixel_processor *dce100_ipp_create(
 611	struct dc_context *ctx, uint32_t inst)
 612{
 613	struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
 614
 615	if (!ipp) {
 616		BREAK_TO_DEBUGGER();
 617		return NULL;
 618	}
 619
 620	dce_ipp_construct(ipp, ctx, inst,
 621			&ipp_regs[inst], &ipp_shift, &ipp_mask);
 622	return &ipp->base;
 623}
 624
 625static const struct encoder_feature_support link_enc_feature = {
 626		.max_hdmi_deep_color = COLOR_DEPTH_121212,
 627		.max_hdmi_pixel_clock = 300000,
 628		.flags.bits.IS_HBR2_CAPABLE = true,
 629		.flags.bits.IS_TPS3_CAPABLE = true
 630};
 631
 632static struct link_encoder *dce100_link_encoder_create(
 633	struct dc_context *ctx,
 634	const struct encoder_init_data *enc_init_data)
 635{
 636	struct dce110_link_encoder *enc110 =
 637		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 638	int link_regs_id;
 639
 640	if (!enc110)
 641		return NULL;
 642
 643	if (enc_init_data->connector.id == CONNECTOR_ID_VGA &&
 644	    enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) {
 645		dce110_link_encoder_construct(enc110,
 646			enc_init_data,
 647			&link_enc_feature,
 648			&link_enc_regs[ENGINE_ID_DACA],
 649			NULL,
 650			NULL);
 651		return &enc110->base;
 652	}
 653
 654	link_regs_id =
 655		map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
 656
 657	dce110_link_encoder_construct(enc110,
 658				      enc_init_data,
 659				      &link_enc_feature,
 660				      &link_enc_regs[link_regs_id],
 661				      &link_enc_aux_regs[enc_init_data->channel - 1],
 662				      enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
 663				      NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
 664	return &enc110->base;
 665}
 666
 667static struct panel_cntl *dce100_panel_cntl_create(const struct panel_cntl_init_data *init_data)
 668{
 669	struct dce_panel_cntl *panel_cntl =
 670		kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
 671
 672	if (!panel_cntl)
 673		return NULL;
 674
 675	dce_panel_cntl_construct(panel_cntl,
 676			init_data,
 677			&panel_cntl_regs[init_data->inst],
 678			&panel_cntl_shift,
 679			&panel_cntl_mask);
 680
 681	return &panel_cntl->base;
 682}
 683
 684static struct output_pixel_processor *dce100_opp_create(
 685	struct dc_context *ctx,
 686	uint32_t inst)
 687{
 688	struct dce110_opp *opp =
 689		kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
 690
 691	if (!opp)
 692		return NULL;
 693
 694	dce110_opp_construct(opp,
 695			     ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 696	return &opp->base;
 697}
 698
 699static struct dce_aux *dce100_aux_engine_create(
 700	struct dc_context *ctx,
 701	uint32_t inst)
 702{
 703	struct aux_engine_dce110 *aux_engine =
 704		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
 705
 706	if (!aux_engine)
 707		return NULL;
 708
 709	dce110_aux_engine_construct(aux_engine, ctx, inst,
 710				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 711				    &aux_engine_regs[inst],
 712					&aux_mask,
 713					&aux_shift,
 714					ctx->dc->caps.extended_aux_timeout_support);
 715
 716	return &aux_engine->base;
 717}
 718#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
 719
 720static const struct dce_i2c_registers i2c_hw_regs[] = {
 721		i2c_inst_regs(1),
 722		i2c_inst_regs(2),
 723		i2c_inst_regs(3),
 724		i2c_inst_regs(4),
 725		i2c_inst_regs(5),
 726		i2c_inst_regs(6),
 727};
 728
 729static const struct dce_i2c_shift i2c_shifts = {
 730		I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
 731};
 732
 733static const struct dce_i2c_mask i2c_masks = {
 734		I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
 735};
 736
 737static struct dce_i2c_hw *dce100_i2c_hw_create(
 738	struct dc_context *ctx,
 739	uint32_t inst)
 740{
 741	struct dce_i2c_hw *dce_i2c_hw =
 742		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
 743
 744	if (!dce_i2c_hw)
 745		return NULL;
 746
 747	dce100_i2c_hw_construct(dce_i2c_hw, ctx, inst,
 748				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
 749
 750	return dce_i2c_hw;
 751}
 752static struct clock_source *dce100_clock_source_create(
 753	struct dc_context *ctx,
 754	struct dc_bios *bios,
 755	enum clock_source_id id,
 756	const struct dce110_clk_src_regs *regs,
 757	bool dp_clk_src)
 758{
 759	struct dce110_clk_src *clk_src =
 760		kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
 761
 762	if (!clk_src)
 763		return NULL;
 764
 765	if (dce110_clk_src_construct(clk_src, ctx, bios, id,
 766			regs, &cs_shift, &cs_mask)) {
 767		clk_src->base.dp_clk_src = dp_clk_src;
 768		return &clk_src->base;
 769	}
 770
 771	kfree(clk_src);
 772	BREAK_TO_DEBUGGER();
 773	return NULL;
 774}
 775
 776static void dce100_clock_source_destroy(struct clock_source **clk_src)
 777{
 778	kfree(TO_DCE110_CLK_SRC(*clk_src));
 779	*clk_src = NULL;
 780}
 781
 782static void dce100_resource_destruct(struct dce110_resource_pool *pool)
 783{
 784	unsigned int i;
 785
 786	for (i = 0; i < pool->base.pipe_count; i++) {
 787		if (pool->base.opps[i] != NULL)
 788			dce110_opp_destroy(&pool->base.opps[i]);
 789
 790		if (pool->base.transforms[i] != NULL)
 791			dce100_transform_destroy(&pool->base.transforms[i]);
 792
 793		if (pool->base.ipps[i] != NULL)
 794			dce_ipp_destroy(&pool->base.ipps[i]);
 795
 796		if (pool->base.mis[i] != NULL) {
 797			kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
 798			pool->base.mis[i] = NULL;
 799		}
 800
 801		if (pool->base.timing_generators[i] != NULL)	{
 802			kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
 803			pool->base.timing_generators[i] = NULL;
 804		}
 805	}
 806
 807	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
 808		if (pool->base.engines[i] != NULL)
 809			dce110_engine_destroy(&pool->base.engines[i]);
 810		if (pool->base.hw_i2cs[i] != NULL) {
 811			kfree(pool->base.hw_i2cs[i]);
 812			pool->base.hw_i2cs[i] = NULL;
 813		}
 814		if (pool->base.sw_i2cs[i] != NULL) {
 815			kfree(pool->base.sw_i2cs[i]);
 816			pool->base.sw_i2cs[i] = NULL;
 817		}
 818	}
 819
 820	for (i = 0; i < pool->base.stream_enc_count; i++) {
 821		if (pool->base.stream_enc[i] != NULL)
 822			kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 823	}
 824
 825	for (i = 0; i < pool->base.clk_src_count; i++) {
 826		if (pool->base.clock_sources[i] != NULL)
 827			dce100_clock_source_destroy(&pool->base.clock_sources[i]);
 828	}
 829
 830	if (pool->base.dp_clock_source != NULL)
 831		dce100_clock_source_destroy(&pool->base.dp_clock_source);
 832
 833	for (i = 0; i < pool->base.audio_count; i++)	{
 834		if (pool->base.audios[i] != NULL)
 835			dce_aud_destroy(&pool->base.audios[i]);
 836	}
 837
 838	if (pool->base.abm != NULL)
 839				dce_abm_destroy(&pool->base.abm);
 840
 841	if (pool->base.dmcu != NULL)
 842			dce_dmcu_destroy(&pool->base.dmcu);
 843
 844	if (pool->base.irqs != NULL)
 845		dal_irq_service_destroy(&pool->base.irqs);
 846}
 847
 848static enum dc_status build_mapped_resource(
 849		const struct dc  *dc,
 850		struct dc_state *context,
 851		struct dc_stream_state *stream)
 852{
 853	struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream);
 854
 855	if (!pipe_ctx)
 856		return DC_ERROR_UNEXPECTED;
 857
 858	dce110_resource_build_pipe_hw_param(pipe_ctx);
 859
 860	resource_build_info_frame(pipe_ctx);
 861
 862	return DC_OK;
 863}
 864
 865enum dc_status dce100_validate_bandwidth(
 866	struct dc  *dc,
 867	struct dc_state *context,
 868	enum dc_validate_mode validate_mode)
 869{
 870	int i;
 871	bool at_least_one_pipe = false;
 872	struct dc_stream_state *stream = NULL;
 873	const uint32_t max_pix_clk_khz = max(dc->clk_mgr->clks.max_supported_dispclk_khz, 400000);
 874
 875	for (i = 0; i < dc->res_pool->pipe_count; i++) {
 876		stream = context->res_ctx.pipe_ctx[i].stream;
 877		if (stream) {
 878			at_least_one_pipe = true;
 879
 880			if (stream->timing.pix_clk_100hz >= max_pix_clk_khz * 10)
 881				return DC_FAIL_BANDWIDTH_VALIDATE;
 882		}
 883	}
 884
 885	if (at_least_one_pipe) {
 886		/* TODO implement when needed but for now hardcode max value*/
 887		context->bw_ctx.bw.dce.dispclk_khz = 681000;
 888		context->bw_ctx.bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ;
 889	} else {
 890		/* On DCE 6.0 and 6.4 the PLL0 is both the display engine clock and
 891		 * the DP clock, and shouldn't be turned off. Just select the display
 892		 * clock value from its low power mode.
 893		 */
 894		if (dc->ctx->dce_version == DCE_VERSION_6_0 ||
 895			dc->ctx->dce_version == DCE_VERSION_6_4)
 896			context->bw_ctx.bw.dce.dispclk_khz = 352000;
 897		else
 898			context->bw_ctx.bw.dce.dispclk_khz = 0;
 899
 900		context->bw_ctx.bw.dce.yclk_khz = 0;
 901	}
 902
 903	return DC_OK;
 904}
 905
 906static bool dce100_validate_surface_sets(
 907		struct dc_state *context)
 908{
 909	int i;
 910
 911	for (i = 0; i < context->stream_count; i++) {
 912		if (context->stream_status[i].plane_count == 0)
 913			continue;
 914
 915		if (context->stream_status[i].plane_count > 1)
 916			return false;
 917
 918		if (context->stream_status[i].plane_states[0]->format
 919				>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 920			return false;
 921	}
 922
 923	return true;
 924}
 925
 926enum dc_status dce100_validate_global(
 927		struct dc  *dc,
 928		struct dc_state *context)
 929{
 930	if (!dce100_validate_surface_sets(context))
 931		return DC_FAIL_SURFACE_VALIDATE;
 932
 933	return DC_OK;
 934}
 935
 936enum dc_status dce100_add_stream_to_ctx(
 937		struct dc *dc,
 938		struct dc_state *new_ctx,
 939		struct dc_stream_state *dc_stream)
 940{
 941	enum dc_status result = DC_ERROR_UNEXPECTED;
 942
 943	result = resource_map_pool_resources(dc, new_ctx, dc_stream);
 944
 945	if (result == DC_OK)
 946		result = resource_map_clock_resources(dc, new_ctx, dc_stream);
 947
 948	if (result == DC_OK)
 949		result = build_mapped_resource(dc, new_ctx, dc_stream);
 950
 951	return result;
 952}
 953
 954static void dce100_destroy_resource_pool(struct resource_pool **pool)
 955{
 956	struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
 957
 958	dce100_resource_destruct(dce110_pool);
 959	kfree(dce110_pool);
 960	*pool = NULL;
 961}
 962
 963enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
 964{
 965
 966	if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 967		return DC_OK;
 968
 969	return DC_FAIL_SURFACE_VALIDATE;
 970}
 971
 972struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link(
 973		struct resource_context *res_ctx,
 974		const struct resource_pool *pool,
 975		struct dc_stream_state *stream)
 976{
 977	int i;
 978	int j = -1;
 979	struct dc_link *link = stream->link;
 980	enum engine_id preferred_engine = link->link_enc->preferred_engine;
 981
 982	/* Prefer analog engine if the link encoder has one.
 983	 * Otherwise, it's an external encoder.
 984	 */
 985	if (dc_is_rgb_signal(stream->signal) && link->link_enc->analog_engine != ENGINE_ID_UNKNOWN)
 986		preferred_engine = link->link_enc->analog_engine;
 987
 988	for (i = 0; i < pool->stream_enc_count; i++) {
 989		if (!res_ctx->is_stream_enc_acquired[i] &&
 990				pool->stream_enc[i]) {
 991			/* Store first available for MST second display
 992			 * in daisy chain use case
 993			 */
 994			j = i;
 995			if (pool->stream_enc[i]->id == preferred_engine)
 996				return pool->stream_enc[i];
 997		}
 998	}
 999
1000	/*
1001	 * below can happen in cases when stream encoder is acquired:
1002	 * 1) for second MST display in chain, so preferred engine already
1003	 * acquired;
1004	 * 2) for another link, which preferred engine already acquired by any
1005	 * MST configuration.
1006	 *
1007	 * If signal is of DP type and preferred engine not found, return last available
1008	 *
1009	 * TODO - This is just a patch up and a generic solution is
1010	 * required for non DP connectors.
1011	 */
1012
1013	if (j >= 0 && link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT)
1014		return pool->stream_enc[j];
1015
1016	return NULL;
1017}
1018
1019static const struct resource_funcs dce100_res_pool_funcs = {
1020	.destroy = dce100_destroy_resource_pool,
1021	.link_enc_create = dce100_link_encoder_create,
1022	.panel_cntl_create = dce100_panel_cntl_create,
1023	.validate_bandwidth = dce100_validate_bandwidth,
1024	.validate_plane = dce100_validate_plane,
1025	.add_stream_to_ctx = dce100_add_stream_to_ctx,
1026	.validate_global = dce100_validate_global,
1027	.find_first_free_match_stream_enc_for_link = dce100_find_first_free_match_stream_enc_for_link
1028};
1029
1030static bool dce100_resource_construct(
1031	uint8_t num_virtual_links,
1032	struct dc  *dc,
1033	struct dce110_resource_pool *pool)
1034{
1035	unsigned int i;
1036	struct dc_context *ctx = dc->ctx;
1037	struct dc_bios *bp;
1038
1039	ctx->dc_bios->regs = &bios_regs;
1040
1041	pool->base.res_cap = &res_cap;
1042	pool->base.funcs = &dce100_res_pool_funcs;
1043	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1044
1045	bp = ctx->dc_bios;
1046
1047	if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
1048		pool->base.dp_clock_source =
1049				dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1050
1051		pool->base.clock_sources[0] =
1052				dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
1053		pool->base.clock_sources[1] =
1054				dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1055		pool->base.clock_sources[2] =
1056				dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1057		pool->base.clk_src_count = 3;
1058
1059	} else {
1060		pool->base.dp_clock_source =
1061				dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
1062
1063		pool->base.clock_sources[0] =
1064				dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
1065		pool->base.clock_sources[1] =
1066				dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
1067		pool->base.clk_src_count = 2;
1068	}
1069
1070	if (pool->base.dp_clock_source == NULL) {
1071		dm_error("DC: failed to create dp clock source!\n");
1072		BREAK_TO_DEBUGGER();
1073		goto res_create_fail;
1074	}
1075
1076	for (i = 0; i < pool->base.clk_src_count; i++) {
1077		if (pool->base.clock_sources[i] == NULL) {
1078			dm_error("DC: failed to create clock sources!\n");
1079			BREAK_TO_DEBUGGER();
1080			goto res_create_fail;
1081		}
1082	}
1083
1084	pool->base.dmcu = dce_dmcu_create(ctx,
1085			&dmcu_regs,
1086			&dmcu_shift,
1087			&dmcu_mask);
1088	if (pool->base.dmcu == NULL) {
1089		dm_error("DC: failed to create dmcu!\n");
1090		BREAK_TO_DEBUGGER();
1091		goto res_create_fail;
1092	}
1093
1094	pool->base.abm = dce_abm_create(ctx,
1095				&abm_regs,
1096				&abm_shift,
1097				&abm_mask);
1098	if (pool->base.abm == NULL) {
1099		dm_error("DC: failed to create abm!\n");
1100		BREAK_TO_DEBUGGER();
1101		goto res_create_fail;
1102	}
1103
1104	{
1105		struct irq_service_init_data init_data;
1106		init_data.ctx = dc->ctx;
1107		pool->base.irqs = dal_irq_service_dce110_create(&init_data);
1108		if (!pool->base.irqs)
1109			goto res_create_fail;
1110	}
1111
1112	/*************************************************
1113	*  Resource + asic cap harcoding                *
1114	*************************************************/
1115	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1116	pool->base.pipe_count = res_cap.num_timing_generator;
1117	pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
1118	dc->caps.max_downscale_ratio = 200;
1119	dc->caps.i2c_speed_in_khz = 40;
1120	dc->caps.i2c_speed_in_khz_hdcp = 40;
1121	dc->caps.max_cursor_size = 128;
1122	dc->caps.min_horizontal_blanking_period = 80;
1123	dc->caps.dual_link_dvi = true;
1124	dc->caps.disable_dp_clk_share = true;
1125	dc->caps.extended_aux_timeout_support = false;
1126	dc->debug = debug_defaults;
1127	dc->check_config = config_defaults;
1128
1129	for (i = 0; i < pool->base.pipe_count; i++) {
1130		pool->base.timing_generators[i] =
1131			dce100_timing_generator_create(
1132				ctx,
1133				i,
1134				&dce100_tg_offsets[i]);
1135		if (pool->base.timing_generators[i] == NULL) {
1136			BREAK_TO_DEBUGGER();
1137			dm_error("DC: failed to create tg!\n");
1138			goto res_create_fail;
1139		}
1140
1141		pool->base.mis[i] = dce100_mem_input_create(ctx, i);
1142		if (pool->base.mis[i] == NULL) {
1143			BREAK_TO_DEBUGGER();
1144			dm_error(
1145				"DC: failed to create memory input!\n");
1146			goto res_create_fail;
1147		}
1148
1149		pool->base.ipps[i] = dce100_ipp_create(ctx, i);
1150		if (pool->base.ipps[i] == NULL) {
1151			BREAK_TO_DEBUGGER();
1152			dm_error(
1153				"DC: failed to create input pixel processor!\n");
1154			goto res_create_fail;
1155		}
1156
1157		pool->base.transforms[i] = dce100_transform_create(ctx, i);
1158		if (pool->base.transforms[i] == NULL) {
1159			BREAK_TO_DEBUGGER();
1160			dm_error(
1161				"DC: failed to create transform!\n");
1162			goto res_create_fail;
1163		}
1164
1165		pool->base.opps[i] = dce100_opp_create(ctx, i);
1166		if (pool->base.opps[i] == NULL) {
1167			BREAK_TO_DEBUGGER();
1168			dm_error(
1169				"DC: failed to create output pixel processor!\n");
1170			goto res_create_fail;
1171		}
1172	}
1173
1174	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1175		pool->base.engines[i] = dce100_aux_engine_create(ctx, i);
1176		if (pool->base.engines[i] == NULL) {
1177			BREAK_TO_DEBUGGER();
1178			dm_error(
1179				"DC:failed to create aux engine!!\n");
1180			goto res_create_fail;
1181		}
1182		pool->base.hw_i2cs[i] = dce100_i2c_hw_create(ctx, i);
1183		if (pool->base.hw_i2cs[i] == NULL) {
1184			BREAK_TO_DEBUGGER();
1185			dm_error(
1186				"DC:failed to create i2c engine!!\n");
1187			goto res_create_fail;
1188		}
1189		pool->base.sw_i2cs[i] = NULL;
1190	}
1191
1192	dc->caps.max_planes =  pool->base.pipe_count;
1193
1194	for (i = 0; i < dc->caps.max_planes; ++i)
1195		dc->caps.planes[i] = plane_cap;
1196
1197	if (!resource_construct(num_virtual_links, dc, &pool->base,
1198			&res_create_funcs))
1199		goto res_create_fail;
1200
1201	/* Create hardware sequencer */
1202	dce100_hw_sequencer_construct(dc);
1203	return true;
1204
1205res_create_fail:
1206	dce100_resource_destruct(pool);
1207
1208	return false;
1209}
1210
1211struct resource_pool *dce100_create_resource_pool(
1212	uint8_t num_virtual_links,
1213	struct dc  *dc)
1214{
1215	struct dce110_resource_pool *pool =
1216		kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1217
1218	if (!pool)
1219		return NULL;
1220
1221	if (dce100_resource_construct(num_virtual_links, dc, pool))
1222		return &pool->base;
1223
1224	kfree(pool);
1225	BREAK_TO_DEBUGGER();
1226	return NULL;
1227}
1228
~/ Read-only file preview.