Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1/*
   2* Copyright 2016 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 "dm_services.h"
  29#include "dc.h"
  30
  31#include "dcn10_init.h"
  32
  33#include "resource.h"
  34#include "include/irq_service_interface.h"
  35#include "dcn10_resource.h"
  36#include "dcn10_ipp.h"
  37#include "dcn10_mpc.h"
  38#include "irq/dcn10/irq_service_dcn10.h"
  39#include "dcn10_dpp.h"
  40#include "dcn10_optc.h"
  41#include "dcn10_hw_sequencer.h"
  42#include "dce110/dce110_hw_sequencer.h"
  43#include "dcn10_opp.h"
  44#include "dcn10_link_encoder.h"
  45#include "dcn10_stream_encoder.h"
  46#include "dce/dce_clock_source.h"
  47#include "dce/dce_audio.h"
  48#include "dce/dce_hwseq.h"
  49#include "virtual/virtual_stream_encoder.h"
  50#include "dce110/dce110_resource.h"
  51#include "dce112/dce112_resource.h"
  52#include "dcn10_hubp.h"
  53#include "dcn10_hubbub.h"
  54#include "dce/dce_panel_cntl.h"
  55
  56#include "soc15_hw_ip.h"
  57#include "vega10_ip_offset.h"
  58
  59#include "dcn/dcn_1_0_offset.h"
  60#include "dcn/dcn_1_0_sh_mask.h"
  61
  62#include "nbio/nbio_7_0_offset.h"
  63
  64#include "mmhub/mmhub_9_1_offset.h"
  65#include "mmhub/mmhub_9_1_sh_mask.h"
  66
  67#include "reg_helper.h"
  68#include "dce/dce_abm.h"
  69#include "dce/dce_dmcu.h"
  70#include "dce/dce_aux.h"
  71#include "dce/dce_i2c.h"
  72
  73const struct _vcs_dpi_ip_params_st dcn1_0_ip = {
  74	.rob_buffer_size_kbytes = 64,
  75	.det_buffer_size_kbytes = 164,
  76	.dpte_buffer_size_in_pte_reqs_luma = 42,
  77	.dpp_output_buffer_pixels = 2560,
  78	.opp_output_buffer_lines = 1,
  79	.pixel_chunk_size_kbytes = 8,
  80	.pte_enable = 1,
  81	.pte_chunk_size_kbytes = 2,
  82	.meta_chunk_size_kbytes = 2,
  83	.writeback_chunk_size_kbytes = 2,
  84	.line_buffer_size_bits = 589824,
  85	.max_line_buffer_lines = 12,
  86	.IsLineBufferBppFixed = 0,
  87	.LineBufferFixedBpp = -1,
  88	.writeback_luma_buffer_size_kbytes = 12,
  89	.writeback_chroma_buffer_size_kbytes = 8,
  90	.max_num_dpp = 4,
  91	.max_num_wb = 2,
  92	.max_dchub_pscl_bw_pix_per_clk = 4,
  93	.max_pscl_lb_bw_pix_per_clk = 2,
  94	.max_lb_vscl_bw_pix_per_clk = 4,
  95	.max_vscl_hscl_bw_pix_per_clk = 4,
  96	.max_hscl_ratio = 4,
  97	.max_vscl_ratio = 4,
  98	.hscl_mults = 4,
  99	.vscl_mults = 4,
 100	.max_hscl_taps = 8,
 101	.max_vscl_taps = 8,
 102	.dispclk_ramp_margin_percent = 1,
 103	.underscan_factor = 1.10,
 104	.min_vblank_lines = 14,
 105	.dppclk_delay_subtotal = 90,
 106	.dispclk_delay_subtotal = 42,
 107	.dcfclk_cstate_latency = 10,
 108	.max_inter_dcn_tile_repeaters = 8,
 109	.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0,
 110	.bug_forcing_LC_req_same_size_fixed = 0,
 111};
 112
 113const struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc = {
 114	.sr_exit_time_us = 9.0,
 115	.sr_enter_plus_exit_time_us = 11.0,
 116	.urgent_latency_us = 4.0,
 117	.writeback_latency_us = 12.0,
 118	.ideal_dram_bw_after_urgent_percent = 80.0,
 119	.max_request_size_bytes = 256,
 120	.downspread_percent = 0.5,
 121	.dram_page_open_time_ns = 50.0,
 122	.dram_rw_turnaround_time_ns = 17.5,
 123	.dram_return_buffer_per_channel_bytes = 8192,
 124	.round_trip_ping_latency_dcfclk_cycles = 128,
 125	.urgent_out_of_order_return_per_channel_bytes = 256,
 126	.channel_interleave_bytes = 256,
 127	.num_banks = 8,
 128	.num_chans = 2,
 129	.vmm_page_size_bytes = 4096,
 130	.dram_clock_change_latency_us = 17.0,
 131	.writeback_dram_clock_change_latency_us = 23.0,
 132	.return_bus_width_bytes = 64,
 133};
 134
 135#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
 136	#define mmDP0_DP_DPHY_INTERNAL_CTRL		0x210f
 137	#define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
 138	#define mmDP1_DP_DPHY_INTERNAL_CTRL		0x220f
 139	#define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
 140	#define mmDP2_DP_DPHY_INTERNAL_CTRL		0x230f
 141	#define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
 142	#define mmDP3_DP_DPHY_INTERNAL_CTRL		0x240f
 143	#define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
 144	#define mmDP4_DP_DPHY_INTERNAL_CTRL		0x250f
 145	#define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
 146	#define mmDP5_DP_DPHY_INTERNAL_CTRL		0x260f
 147	#define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
 148	#define mmDP6_DP_DPHY_INTERNAL_CTRL		0x270f
 149	#define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
 150#endif
 151
 152
 153enum dcn10_clk_src_array_id {
 154	DCN10_CLK_SRC_PLL0,
 155	DCN10_CLK_SRC_PLL1,
 156	DCN10_CLK_SRC_PLL2,
 157	DCN10_CLK_SRC_PLL3,
 158	DCN10_CLK_SRC_TOTAL,
 159	DCN101_CLK_SRC_TOTAL = DCN10_CLK_SRC_PLL3
 160};
 161
 162/* begin *********************
 163 * macros to expend register list macro defined in HW object header file */
 164
 165/* DCN */
 166#define BASE_INNER(seg) \
 167	DCE_BASE__INST0_SEG ## seg
 168
 169#define BASE(seg) \
 170	BASE_INNER(seg)
 171
 172#define SR(reg_name)\
 173		.reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \
 174					mm ## reg_name
 175
 176#define SRI(reg_name, block, id)\
 177	.reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
 178					mm ## block ## id ## _ ## reg_name
 179
 180
 181#define SRII(reg_name, block, id)\
 182	.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
 183					mm ## block ## id ## _ ## reg_name
 184
 185#define VUPDATE_SRII(reg_name, block, id)\
 186	.reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \
 187					mm ## reg_name ## 0 ## _ ## block ## id
 188
 189/* set field/register/bitfield name */
 190#define SFRB(field_name, reg_name, bitfield, post_fix)\
 191	.field_name = reg_name ## __ ## bitfield ## post_fix
 192
 193/* NBIO */
 194#define NBIO_BASE_INNER(seg) \
 195	NBIF_BASE__INST0_SEG ## seg
 196
 197#define NBIO_BASE(seg) \
 198	NBIO_BASE_INNER(seg)
 199
 200#define NBIO_SR(reg_name)\
 201		.reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) +  \
 202					mm ## reg_name
 203
 204/* MMHUB */
 205#define MMHUB_BASE_INNER(seg) \
 206	MMHUB_BASE__INST0_SEG ## seg
 207
 208#define MMHUB_BASE(seg) \
 209	MMHUB_BASE_INNER(seg)
 210
 211#define MMHUB_SR(reg_name)\
 212		.reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) +  \
 213					mm ## reg_name
 214
 215/* macros to expend register list macro defined in HW object header file
 216 * end *********************/
 217
 218
 219static const struct dce_dmcu_registers dmcu_regs = {
 220		DMCU_DCN10_REG_LIST()
 221};
 222
 223static const struct dce_dmcu_shift dmcu_shift = {
 224		DMCU_MASK_SH_LIST_DCN10(__SHIFT)
 225};
 226
 227static const struct dce_dmcu_mask dmcu_mask = {
 228		DMCU_MASK_SH_LIST_DCN10(_MASK)
 229};
 230
 231static const struct dce_abm_registers abm_regs = {
 232		ABM_DCN10_REG_LIST(0)
 233};
 234
 235static const struct dce_abm_shift abm_shift = {
 236		ABM_MASK_SH_LIST_DCN10(__SHIFT)
 237};
 238
 239static const struct dce_abm_mask abm_mask = {
 240		ABM_MASK_SH_LIST_DCN10(_MASK)
 241};
 242
 243#define stream_enc_regs(id)\
 244[id] = {\
 245	SE_DCN_REG_LIST(id)\
 246}
 247
 248static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
 249	stream_enc_regs(0),
 250	stream_enc_regs(1),
 251	stream_enc_regs(2),
 252	stream_enc_regs(3),
 253};
 254
 255static const struct dcn10_stream_encoder_shift se_shift = {
 256		SE_COMMON_MASK_SH_LIST_DCN10(__SHIFT)
 257};
 258
 259static const struct dcn10_stream_encoder_mask se_mask = {
 260		SE_COMMON_MASK_SH_LIST_DCN10(_MASK)
 261};
 262
 263#define audio_regs(id)\
 264[id] = {\
 265		AUD_COMMON_REG_LIST(id)\
 266}
 267
 268static const struct dce_audio_registers audio_regs[] = {
 269	audio_regs(0),
 270	audio_regs(1),
 271	audio_regs(2),
 272	audio_regs(3),
 273};
 274
 275#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
 276		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
 277		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
 278		AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
 279
 280static const struct dce_audio_shift audio_shift = {
 281		DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
 282};
 283
 284static const struct dce_audio_mask audio_mask = {
 285		DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
 286};
 287
 288#define aux_regs(id)\
 289[id] = {\
 290	AUX_REG_LIST(id)\
 291}
 292
 293static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
 294		aux_regs(0),
 295		aux_regs(1),
 296		aux_regs(2),
 297		aux_regs(3)
 298};
 299
 300#define hpd_regs(id)\
 301[id] = {\
 302	HPD_REG_LIST(id)\
 303}
 304
 305static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
 306		hpd_regs(0),
 307		hpd_regs(1),
 308		hpd_regs(2),
 309		hpd_regs(3)
 310};
 311
 312#define link_regs(id)\
 313[id] = {\
 314	LE_DCN10_REG_LIST(id), \
 315	SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
 316}
 317
 318static const struct dcn10_link_enc_registers link_enc_regs[] = {
 319	link_regs(0),
 320	link_regs(1),
 321	link_regs(2),
 322	link_regs(3)
 323};
 324
 325static const struct dcn10_link_enc_shift le_shift = {
 326		LINK_ENCODER_MASK_SH_LIST_DCN10(__SHIFT)
 327};
 328
 329static const struct dcn10_link_enc_mask le_mask = {
 330		LINK_ENCODER_MASK_SH_LIST_DCN10(_MASK)
 331};
 332
 333static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
 334	{ DCN_PANEL_CNTL_REG_LIST() }
 335};
 336
 337static const struct dce_panel_cntl_shift panel_cntl_shift = {
 338	DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
 339};
 340
 341static const struct dce_panel_cntl_mask panel_cntl_mask = {
 342	DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
 343};
 344
 345static const struct dce110_aux_registers_shift aux_shift = {
 346	DCN10_AUX_MASK_SH_LIST(__SHIFT)
 347};
 348
 349static const struct dce110_aux_registers_mask aux_mask = {
 350	DCN10_AUX_MASK_SH_LIST(_MASK)
 351};
 352
 353#define ipp_regs(id)\
 354[id] = {\
 355	IPP_REG_LIST_DCN10(id),\
 356}
 357
 358static const struct dcn10_ipp_registers ipp_regs[] = {
 359	ipp_regs(0),
 360	ipp_regs(1),
 361	ipp_regs(2),
 362	ipp_regs(3),
 363};
 364
 365static const struct dcn10_ipp_shift ipp_shift = {
 366		IPP_MASK_SH_LIST_DCN10(__SHIFT)
 367};
 368
 369static const struct dcn10_ipp_mask ipp_mask = {
 370		IPP_MASK_SH_LIST_DCN10(_MASK),
 371};
 372
 373#define opp_regs(id)\
 374[id] = {\
 375	OPP_REG_LIST_DCN10(id),\
 376}
 377
 378static const struct dcn10_opp_registers opp_regs[] = {
 379	opp_regs(0),
 380	opp_regs(1),
 381	opp_regs(2),
 382	opp_regs(3),
 383};
 384
 385static const struct dcn10_opp_shift opp_shift = {
 386		OPP_MASK_SH_LIST_DCN10(__SHIFT)
 387};
 388
 389static const struct dcn10_opp_mask opp_mask = {
 390		OPP_MASK_SH_LIST_DCN10(_MASK),
 391};
 392
 393#define aux_engine_regs(id)\
 394[id] = {\
 395	AUX_COMMON_REG_LIST(id), \
 396	.AUX_RESET_MASK = 0 \
 397}
 398
 399static const struct dce110_aux_registers aux_engine_regs[] = {
 400		aux_engine_regs(0),
 401		aux_engine_regs(1),
 402		aux_engine_regs(2),
 403		aux_engine_regs(3),
 404		aux_engine_regs(4),
 405		aux_engine_regs(5)
 406};
 407
 408#define tf_regs(id)\
 409[id] = {\
 410	TF_REG_LIST_DCN10(id),\
 411}
 412
 413static const struct dcn_dpp_registers tf_regs[] = {
 414	tf_regs(0),
 415	tf_regs(1),
 416	tf_regs(2),
 417	tf_regs(3),
 418};
 419
 420static const struct dcn_dpp_shift tf_shift = {
 421	TF_REG_LIST_SH_MASK_DCN10(__SHIFT),
 422	TF_DEBUG_REG_LIST_SH_DCN10
 423
 424};
 425
 426static const struct dcn_dpp_mask tf_mask = {
 427	TF_REG_LIST_SH_MASK_DCN10(_MASK),
 428	TF_DEBUG_REG_LIST_MASK_DCN10
 429};
 430
 431static const struct dcn_mpc_registers mpc_regs = {
 432		MPC_COMMON_REG_LIST_DCN1_0(0),
 433		MPC_COMMON_REG_LIST_DCN1_0(1),
 434		MPC_COMMON_REG_LIST_DCN1_0(2),
 435		MPC_COMMON_REG_LIST_DCN1_0(3),
 436		MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(0),
 437		MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(1),
 438		MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(2),
 439		MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(3)
 440};
 441
 442static const struct dcn_mpc_shift mpc_shift = {
 443	MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\
 444	SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT)
 445};
 446
 447static const struct dcn_mpc_mask mpc_mask = {
 448	MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\
 449	SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK)
 450};
 451
 452#define tg_regs(id)\
 453[id] = {TG_COMMON_REG_LIST_DCN1_0(id)}
 454
 455static const struct dcn_optc_registers tg_regs[] = {
 456	tg_regs(0),
 457	tg_regs(1),
 458	tg_regs(2),
 459	tg_regs(3),
 460};
 461
 462static const struct dcn_optc_shift tg_shift = {
 463	TG_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
 464};
 465
 466static const struct dcn_optc_mask tg_mask = {
 467	TG_COMMON_MASK_SH_LIST_DCN1_0(_MASK)
 468};
 469
 470static const struct bios_registers bios_regs = {
 471		NBIO_SR(BIOS_SCRATCH_3),
 472		NBIO_SR(BIOS_SCRATCH_6)
 473};
 474
 475#define hubp_regs(id)\
 476[id] = {\
 477	HUBP_REG_LIST_DCN10(id)\
 478}
 479
 480static const struct dcn_mi_registers hubp_regs[] = {
 481	hubp_regs(0),
 482	hubp_regs(1),
 483	hubp_regs(2),
 484	hubp_regs(3),
 485};
 486
 487static const struct dcn_mi_shift hubp_shift = {
 488		HUBP_MASK_SH_LIST_DCN10(__SHIFT)
 489};
 490
 491static const struct dcn_mi_mask hubp_mask = {
 492		HUBP_MASK_SH_LIST_DCN10(_MASK)
 493};
 494
 495static const struct dcn_hubbub_registers hubbub_reg = {
 496		HUBBUB_REG_LIST_DCN10(0)
 497};
 498
 499static const struct dcn_hubbub_shift hubbub_shift = {
 500		HUBBUB_MASK_SH_LIST_DCN10(__SHIFT)
 501};
 502
 503static const struct dcn_hubbub_mask hubbub_mask = {
 504		HUBBUB_MASK_SH_LIST_DCN10(_MASK)
 505};
 506
 507static int map_transmitter_id_to_phy_instance(
 508	enum transmitter transmitter)
 509{
 510	switch (transmitter) {
 511	case TRANSMITTER_UNIPHY_A:
 512		return 0;
 513	break;
 514	case TRANSMITTER_UNIPHY_B:
 515		return 1;
 516	break;
 517	case TRANSMITTER_UNIPHY_C:
 518		return 2;
 519	break;
 520	case TRANSMITTER_UNIPHY_D:
 521		return 3;
 522	break;
 523	default:
 524		ASSERT(0);
 525		return 0;
 526	}
 527}
 528
 529#define clk_src_regs(index, pllid)\
 530[index] = {\
 531	CS_COMMON_REG_LIST_DCN1_0(index, pllid),\
 532}
 533
 534static const struct dce110_clk_src_regs clk_src_regs[] = {
 535	clk_src_regs(0, A),
 536	clk_src_regs(1, B),
 537	clk_src_regs(2, C),
 538	clk_src_regs(3, D)
 539};
 540
 541static const struct dce110_clk_src_shift cs_shift = {
 542		CS_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
 543};
 544
 545static const struct dce110_clk_src_mask cs_mask = {
 546		CS_COMMON_MASK_SH_LIST_DCN1_0(_MASK)
 547};
 548
 549static const struct resource_caps res_cap = {
 550		.num_timing_generator = 4,
 551		.num_opp = 4,
 552		.num_video_plane = 4,
 553		.num_audio = 4,
 554		.num_stream_encoder = 4,
 555		.num_pll = 4,
 556		.num_ddc = 4,
 557};
 558
 559static const struct resource_caps rv2_res_cap = {
 560		.num_timing_generator = 3,
 561		.num_opp = 3,
 562		.num_video_plane = 3,
 563		.num_audio = 3,
 564		.num_stream_encoder = 3,
 565		.num_pll = 3,
 566		.num_ddc = 4,
 567};
 568
 569static const struct dc_plane_cap plane_cap = {
 570	.type = DC_PLANE_TYPE_DCN_UNIVERSAL,
 571	.blends_with_above = true,
 572	.blends_with_below = true,
 573	.per_pixel_alpha = true,
 574
 575	.pixel_format_support = {
 576			.argb8888 = true,
 577			.nv12 = true,
 578			.fp16 = true,
 579			.p010 = true
 580	},
 581
 582	.max_upscale_factor = {
 583			.argb8888 = 16000,
 584			.nv12 = 16000,
 585			.fp16 = 1
 586	},
 587
 588	.max_downscale_factor = {
 589			.argb8888 = 250,
 590			.nv12 = 250,
 591			.fp16 = 1
 592	}
 593};
 594
 595static const struct dc_debug_options debug_defaults_drv = {
 596		.sanity_checks = true,
 597		.disable_dmcu = false,
 598		.force_abm_enable = false,
 599		.timing_trace = false,
 600		.clock_trace = true,
 601
 602		/* raven smu dones't allow 0 disp clk,
 603		 * smu min disp clk limit is 50Mhz
 604		 * keep min disp clk 100Mhz avoid smu hang
 605		 */
 606		.min_disp_clk_khz = 100000,
 607
 608		.disable_pplib_clock_request = false,
 609		.disable_pplib_wm_range = false,
 610		.pplib_wm_report_mode = WM_REPORT_DEFAULT,
 611		.pipe_split_policy = MPC_SPLIT_DYNAMIC,
 612		.force_single_disp_pipe_split = true,
 613		.disable_dcc = DCC_ENABLE,
 614		.voltage_align_fclk = true,
 615		.disable_stereo_support = true,
 616		.vsr_support = true,
 617		.performance_trace = false,
 618		.az_endpoint_mute_only = true,
 619		.recovery_enabled = false, /*enable this by default after testing.*/
 620		.max_downscale_src_width = 3840,
 621		.underflow_assert_delay_us = 0xFFFFFFFF,
 622};
 623
 624static const struct dc_debug_options debug_defaults_diags = {
 625		.disable_dmcu = false,
 626		.force_abm_enable = false,
 627		.timing_trace = true,
 628		.clock_trace = true,
 629		.disable_stutter = true,
 630		.disable_pplib_clock_request = true,
 631		.disable_pplib_wm_range = true,
 632		.underflow_assert_delay_us = 0xFFFFFFFF,
 633};
 634
 635static void dcn10_dpp_destroy(struct dpp **dpp)
 636{
 637	kfree(TO_DCN10_DPP(*dpp));
 638	*dpp = NULL;
 639}
 640
 641static struct dpp *dcn10_dpp_create(
 642	struct dc_context *ctx,
 643	uint32_t inst)
 644{
 645	struct dcn10_dpp *dpp =
 646		kzalloc(sizeof(struct dcn10_dpp), GFP_KERNEL);
 647
 648	if (!dpp)
 649		return NULL;
 650
 651	dpp1_construct(dpp, ctx, inst,
 652		       &tf_regs[inst], &tf_shift, &tf_mask);
 653	return &dpp->base;
 654}
 655
 656static struct input_pixel_processor *dcn10_ipp_create(
 657	struct dc_context *ctx, uint32_t inst)
 658{
 659	struct dcn10_ipp *ipp =
 660		kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL);
 661
 662	if (!ipp) {
 663		BREAK_TO_DEBUGGER();
 664		return NULL;
 665	}
 666
 667	dcn10_ipp_construct(ipp, ctx, inst,
 668			&ipp_regs[inst], &ipp_shift, &ipp_mask);
 669	return &ipp->base;
 670}
 671
 672
 673static struct output_pixel_processor *dcn10_opp_create(
 674	struct dc_context *ctx, uint32_t inst)
 675{
 676	struct dcn10_opp *opp =
 677		kzalloc(sizeof(struct dcn10_opp), GFP_KERNEL);
 678
 679	if (!opp) {
 680		BREAK_TO_DEBUGGER();
 681		return NULL;
 682	}
 683
 684	dcn10_opp_construct(opp, ctx, inst,
 685			&opp_regs[inst], &opp_shift, &opp_mask);
 686	return &opp->base;
 687}
 688
 689struct dce_aux *dcn10_aux_engine_create(
 690	struct dc_context *ctx,
 691	uint32_t inst)
 692{
 693	struct aux_engine_dce110 *aux_engine =
 694		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
 695
 696	if (!aux_engine)
 697		return NULL;
 698
 699	dce110_aux_engine_construct(aux_engine, ctx, inst,
 700				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 701				    &aux_engine_regs[inst],
 702					&aux_mask,
 703					&aux_shift,
 704					ctx->dc->caps.extended_aux_timeout_support);
 705
 706	return &aux_engine->base;
 707}
 708#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
 709
 710static const struct dce_i2c_registers i2c_hw_regs[] = {
 711		i2c_inst_regs(1),
 712		i2c_inst_regs(2),
 713		i2c_inst_regs(3),
 714		i2c_inst_regs(4),
 715		i2c_inst_regs(5),
 716		i2c_inst_regs(6),
 717};
 718
 719static const struct dce_i2c_shift i2c_shifts = {
 720		I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
 721};
 722
 723static const struct dce_i2c_mask i2c_masks = {
 724		I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
 725};
 726
 727struct dce_i2c_hw *dcn10_i2c_hw_create(
 728	struct dc_context *ctx,
 729	uint32_t inst)
 730{
 731	struct dce_i2c_hw *dce_i2c_hw =
 732		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
 733
 734	if (!dce_i2c_hw)
 735		return NULL;
 736
 737	dcn1_i2c_hw_construct(dce_i2c_hw, ctx, inst,
 738				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
 739
 740	return dce_i2c_hw;
 741}
 742static struct mpc *dcn10_mpc_create(struct dc_context *ctx)
 743{
 744	struct dcn10_mpc *mpc10 = kzalloc(sizeof(struct dcn10_mpc),
 745					  GFP_KERNEL);
 746
 747	if (!mpc10)
 748		return NULL;
 749
 750	dcn10_mpc_construct(mpc10, ctx,
 751			&mpc_regs,
 752			&mpc_shift,
 753			&mpc_mask,
 754			4);
 755
 756	return &mpc10->base;
 757}
 758
 759static struct hubbub *dcn10_hubbub_create(struct dc_context *ctx)
 760{
 761	struct dcn10_hubbub *dcn10_hubbub = kzalloc(sizeof(struct dcn10_hubbub),
 762					  GFP_KERNEL);
 763
 764	if (!dcn10_hubbub)
 765		return NULL;
 766
 767	hubbub1_construct(&dcn10_hubbub->base, ctx,
 768			&hubbub_reg,
 769			&hubbub_shift,
 770			&hubbub_mask);
 771
 772	return &dcn10_hubbub->base;
 773}
 774
 775static struct timing_generator *dcn10_timing_generator_create(
 776		struct dc_context *ctx,
 777		uint32_t instance)
 778{
 779	struct optc *tgn10 =
 780		kzalloc(sizeof(struct optc), GFP_KERNEL);
 781
 782	if (!tgn10)
 783		return NULL;
 784
 785	tgn10->base.inst = instance;
 786	tgn10->base.ctx = ctx;
 787
 788	tgn10->tg_regs = &tg_regs[instance];
 789	tgn10->tg_shift = &tg_shift;
 790	tgn10->tg_mask = &tg_mask;
 791
 792	dcn10_timing_generator_init(tgn10);
 793
 794	return &tgn10->base;
 795}
 796
 797static const struct encoder_feature_support link_enc_feature = {
 798		.max_hdmi_deep_color = COLOR_DEPTH_121212,
 799		.max_hdmi_pixel_clock = 600000,
 800		.hdmi_ycbcr420_supported = true,
 801		.dp_ycbcr420_supported = false,
 802		.flags.bits.IS_HBR2_CAPABLE = true,
 803		.flags.bits.IS_HBR3_CAPABLE = true,
 804		.flags.bits.IS_TPS3_CAPABLE = true,
 805		.flags.bits.IS_TPS4_CAPABLE = true
 806};
 807
 808struct link_encoder *dcn10_link_encoder_create(
 809	const struct encoder_init_data *enc_init_data)
 810{
 811	struct dcn10_link_encoder *enc10 =
 812		kzalloc(sizeof(struct dcn10_link_encoder), GFP_KERNEL);
 813	int link_regs_id;
 814
 815	if (!enc10)
 816		return NULL;
 817
 818	link_regs_id =
 819		map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
 820
 821	dcn10_link_encoder_construct(enc10,
 822				      enc_init_data,
 823				      &link_enc_feature,
 824				      &link_enc_regs[link_regs_id],
 825				      &link_enc_aux_regs[enc_init_data->channel - 1],
 826				      &link_enc_hpd_regs[enc_init_data->hpd_source],
 827				      &le_shift,
 828				      &le_mask);
 829
 830	return &enc10->base;
 831}
 832
 833static struct panel_cntl *dcn10_panel_cntl_create(const struct panel_cntl_init_data *init_data)
 834{
 835	struct dce_panel_cntl *panel_cntl =
 836		kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
 837
 838	if (!panel_cntl)
 839		return NULL;
 840
 841	dce_panel_cntl_construct(panel_cntl,
 842			init_data,
 843			&panel_cntl_regs[init_data->inst],
 844			&panel_cntl_shift,
 845			&panel_cntl_mask);
 846
 847	return &panel_cntl->base;
 848}
 849
 850struct clock_source *dcn10_clock_source_create(
 851	struct dc_context *ctx,
 852	struct dc_bios *bios,
 853	enum clock_source_id id,
 854	const struct dce110_clk_src_regs *regs,
 855	bool dp_clk_src)
 856{
 857	struct dce110_clk_src *clk_src =
 858		kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
 859
 860	if (!clk_src)
 861		return NULL;
 862
 863	if (dce112_clk_src_construct(clk_src, ctx, bios, id,
 864			regs, &cs_shift, &cs_mask)) {
 865		clk_src->base.dp_clk_src = dp_clk_src;
 866		return &clk_src->base;
 867	}
 868
 869	kfree(clk_src);
 870	BREAK_TO_DEBUGGER();
 871	return NULL;
 872}
 873
 874static void read_dce_straps(
 875	struct dc_context *ctx,
 876	struct resource_straps *straps)
 877{
 878	generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX),
 879		FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
 880}
 881
 882static struct audio *create_audio(
 883		struct dc_context *ctx, unsigned int inst)
 884{
 885	return dce_audio_create(ctx, inst,
 886			&audio_regs[inst], &audio_shift, &audio_mask);
 887}
 888
 889static struct stream_encoder *dcn10_stream_encoder_create(
 890	enum engine_id eng_id,
 891	struct dc_context *ctx)
 892{
 893	struct dcn10_stream_encoder *enc1 =
 894		kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
 895
 896	if (!enc1)
 897		return NULL;
 898
 899	dcn10_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id,
 900					&stream_enc_regs[eng_id],
 901					&se_shift, &se_mask);
 902	return &enc1->base;
 903}
 904
 905static const struct dce_hwseq_registers hwseq_reg = {
 906		HWSEQ_DCN1_REG_LIST()
 907};
 908
 909static const struct dce_hwseq_shift hwseq_shift = {
 910		HWSEQ_DCN1_MASK_SH_LIST(__SHIFT)
 911};
 912
 913static const struct dce_hwseq_mask hwseq_mask = {
 914		HWSEQ_DCN1_MASK_SH_LIST(_MASK)
 915};
 916
 917static struct dce_hwseq *dcn10_hwseq_create(
 918	struct dc_context *ctx)
 919{
 920	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
 921
 922	if (hws) {
 923		hws->ctx = ctx;
 924		hws->regs = &hwseq_reg;
 925		hws->shifts = &hwseq_shift;
 926		hws->masks = &hwseq_mask;
 927		hws->wa.DEGVIDCN10_253 = true;
 928		hws->wa.false_optc_underflow = true;
 929		hws->wa.DEGVIDCN10_254 = true;
 930	}
 931	return hws;
 932}
 933
 934static const struct resource_create_funcs res_create_funcs = {
 935	.read_dce_straps = read_dce_straps,
 936	.create_audio = create_audio,
 937	.create_stream_encoder = dcn10_stream_encoder_create,
 938	.create_hwseq = dcn10_hwseq_create,
 939};
 940
 941static const struct resource_create_funcs res_create_maximus_funcs = {
 942	.read_dce_straps = NULL,
 943	.create_audio = NULL,
 944	.create_stream_encoder = NULL,
 945	.create_hwseq = dcn10_hwseq_create,
 946};
 947
 948void dcn10_clock_source_destroy(struct clock_source **clk_src)
 949{
 950	kfree(TO_DCE110_CLK_SRC(*clk_src));
 951	*clk_src = NULL;
 952}
 953
 954static struct pp_smu_funcs *dcn10_pp_smu_create(struct dc_context *ctx)
 955{
 956	struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
 957
 958	if (!pp_smu)
 959		return pp_smu;
 960
 961	dm_pp_get_funcs(ctx, pp_smu);
 962	return pp_smu;
 963}
 964
 965static void dcn10_resource_destruct(struct dcn10_resource_pool *pool)
 966{
 967	unsigned int i;
 968
 969	for (i = 0; i < pool->base.stream_enc_count; i++) {
 970		if (pool->base.stream_enc[i] != NULL) {
 971			kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
 972			pool->base.stream_enc[i] = NULL;
 973		}
 974	}
 975
 976	if (pool->base.mpc != NULL) {
 977		kfree(TO_DCN10_MPC(pool->base.mpc));
 978		pool->base.mpc = NULL;
 979	}
 980
 981	if (pool->base.hubbub != NULL) {
 982		kfree(pool->base.hubbub);
 983		pool->base.hubbub = NULL;
 984	}
 985
 986	for (i = 0; i < pool->base.pipe_count; i++) {
 987		if (pool->base.opps[i] != NULL)
 988			pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
 989
 990		if (pool->base.dpps[i] != NULL)
 991			dcn10_dpp_destroy(&pool->base.dpps[i]);
 992
 993		if (pool->base.ipps[i] != NULL)
 994			pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
 995
 996		if (pool->base.hubps[i] != NULL) {
 997			kfree(TO_DCN10_HUBP(pool->base.hubps[i]));
 998			pool->base.hubps[i] = NULL;
 999		}
1000
1001		if (pool->base.irqs != NULL) {
1002			dal_irq_service_destroy(&pool->base.irqs);
1003		}
1004
1005		if (pool->base.timing_generators[i] != NULL)	{
1006			kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
1007			pool->base.timing_generators[i] = NULL;
1008		}
1009	}
1010
1011	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1012		if (pool->base.engines[i] != NULL)
1013			dce110_engine_destroy(&pool->base.engines[i]);
1014		if (pool->base.hw_i2cs[i] != NULL) {
1015			kfree(pool->base.hw_i2cs[i]);
1016			pool->base.hw_i2cs[i] = NULL;
1017		}
1018		if (pool->base.sw_i2cs[i] != NULL) {
1019			kfree(pool->base.sw_i2cs[i]);
1020			pool->base.sw_i2cs[i] = NULL;
1021		}
1022	}
1023
1024	for (i = 0; i < pool->base.audio_count; i++) {
1025		if (pool->base.audios[i])
1026			dce_aud_destroy(&pool->base.audios[i]);
1027	}
1028
1029	for (i = 0; i < pool->base.clk_src_count; i++) {
1030		if (pool->base.clock_sources[i] != NULL) {
1031			dcn10_clock_source_destroy(&pool->base.clock_sources[i]);
1032			pool->base.clock_sources[i] = NULL;
1033		}
1034	}
1035
1036	if (pool->base.dp_clock_source != NULL) {
1037		dcn10_clock_source_destroy(&pool->base.dp_clock_source);
1038		pool->base.dp_clock_source = NULL;
1039	}
1040
1041	if (pool->base.abm != NULL)
1042		dce_abm_destroy(&pool->base.abm);
1043
1044	if (pool->base.dmcu != NULL)
1045		dce_dmcu_destroy(&pool->base.dmcu);
1046
1047	kfree(pool->base.pp_smu);
1048}
1049
1050static struct hubp *dcn10_hubp_create(
1051	struct dc_context *ctx,
1052	uint32_t inst)
1053{
1054	struct dcn10_hubp *hubp1 =
1055		kzalloc(sizeof(struct dcn10_hubp), GFP_KERNEL);
1056
1057	if (!hubp1)
1058		return NULL;
1059
1060	dcn10_hubp_construct(hubp1, ctx, inst,
1061			     &hubp_regs[inst], &hubp_shift, &hubp_mask);
1062	return &hubp1->base;
1063}
1064
1065static void get_pixel_clock_parameters(
1066	const struct pipe_ctx *pipe_ctx,
1067	struct pixel_clk_params *pixel_clk_params)
1068{
1069	const struct dc_stream_state *stream = pipe_ctx->stream;
1070	pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
1071	pixel_clk_params->encoder_object_id = stream->link->link_enc->id;
1072	pixel_clk_params->signal_type = pipe_ctx->stream->signal;
1073	pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
1074	/* TODO: un-hardcode*/
1075	pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
1076		LINK_RATE_REF_FREQ_IN_KHZ;
1077	pixel_clk_params->flags.ENABLE_SS = 0;
1078	pixel_clk_params->color_depth =
1079		stream->timing.display_color_depth;
1080	pixel_clk_params->flags.DISPLAY_BLANKED = 1;
1081	pixel_clk_params->pixel_encoding = stream->timing.pixel_encoding;
1082
1083	if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
1084		pixel_clk_params->color_depth = COLOR_DEPTH_888;
1085
1086	if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
1087		pixel_clk_params->requested_pix_clk_100hz  /= 2;
1088	if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
1089		pixel_clk_params->requested_pix_clk_100hz *= 2;
1090
1091}
1092
1093static void build_clamping_params(struct dc_stream_state *stream)
1094{
1095	stream->clamping.clamping_level = CLAMPING_FULL_RANGE;
1096	stream->clamping.c_depth = stream->timing.display_color_depth;
1097	stream->clamping.pixel_encoding = stream->timing.pixel_encoding;
1098}
1099
1100static void build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
1101{
1102
1103	get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->stream_res.pix_clk_params);
1104
1105	pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
1106		pipe_ctx->clock_source,
1107		&pipe_ctx->stream_res.pix_clk_params,
1108		&pipe_ctx->pll_settings);
1109
1110	pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->timing.pixel_encoding;
1111
1112	resource_build_bit_depth_reduction_params(pipe_ctx->stream,
1113					&pipe_ctx->stream->bit_depth_params);
1114	build_clamping_params(pipe_ctx->stream);
1115}
1116
1117static enum dc_status build_mapped_resource(
1118		const struct dc *dc,
1119		struct dc_state *context,
1120		struct dc_stream_state *stream)
1121{
1122	struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
1123
1124	if (!pipe_ctx)
1125		return DC_ERROR_UNEXPECTED;
1126
1127	build_pipe_hw_param(pipe_ctx);
1128	return DC_OK;
1129}
1130
1131enum dc_status dcn10_add_stream_to_ctx(
1132		struct dc *dc,
1133		struct dc_state *new_ctx,
1134		struct dc_stream_state *dc_stream)
1135{
1136	enum dc_status result = DC_ERROR_UNEXPECTED;
1137
1138	result = resource_map_pool_resources(dc, new_ctx, dc_stream);
1139
1140	if (result == DC_OK)
1141		result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
1142
1143
1144	if (result == DC_OK)
1145		result = build_mapped_resource(dc, new_ctx, dc_stream);
1146
1147	return result;
1148}
1149
1150static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
1151		struct dc_state *context,
1152		const struct resource_pool *pool,
1153		struct dc_stream_state *stream)
1154{
1155	struct resource_context *res_ctx = &context->res_ctx;
1156	struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream);
1157	struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool, head_pipe);
1158
1159	if (!head_pipe) {
1160		ASSERT(0);
1161		return NULL;
1162	}
1163
1164	if (!idle_pipe)
1165		return NULL;
1166
1167	idle_pipe->stream = head_pipe->stream;
1168	idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
1169	idle_pipe->stream_res.abm = head_pipe->stream_res.abm;
1170	idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
1171
1172	idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
1173	idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
1174	idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
1175	idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst;
1176
1177	return idle_pipe;
1178}
1179
1180static bool dcn10_get_dcc_compression_cap(const struct dc *dc,
1181		const struct dc_dcc_surface_param *input,
1182		struct dc_surface_dcc_cap *output)
1183{
1184	return dc->res_pool->hubbub->funcs->get_dcc_compression_cap(
1185			dc->res_pool->hubbub,
1186			input,
1187			output);
1188}
1189
1190static void dcn10_destroy_resource_pool(struct resource_pool **pool)
1191{
1192	struct dcn10_resource_pool *dcn10_pool = TO_DCN10_RES_POOL(*pool);
1193
1194	dcn10_resource_destruct(dcn10_pool);
1195	kfree(dcn10_pool);
1196	*pool = NULL;
1197}
1198
1199static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
1200{
1201	if (plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
1202			&& caps->max_video_width != 0
1203			&& plane_state->src_rect.width > caps->max_video_width)
1204		return DC_FAIL_SURFACE_VALIDATE;
1205
1206	return DC_OK;
1207}
1208
1209static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *context)
1210{
1211	int i, j;
1212	bool video_down_scaled = false;
1213	bool video_large = false;
1214	bool desktop_large = false;
1215	bool dcc_disabled = false;
1216	bool mpo_enabled = false;
1217
1218	for (i = 0; i < context->stream_count; i++) {
1219		if (context->stream_status[i].plane_count == 0)
1220			continue;
1221
1222		if (context->stream_status[i].plane_count > 2)
1223			return DC_FAIL_UNSUPPORTED_1;
1224
1225		if (context->stream_status[i].plane_count > 1)
1226			mpo_enabled = true;
1227
1228		for (j = 0; j < context->stream_status[i].plane_count; j++) {
1229			struct dc_plane_state *plane =
1230				context->stream_status[i].plane_states[j];
1231
1232
1233			if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
1234
1235				if (plane->src_rect.width > plane->dst_rect.width ||
1236						plane->src_rect.height > plane->dst_rect.height)
1237					video_down_scaled = true;
1238
1239				if (plane->src_rect.width >= 3840)
1240					video_large = true;
1241
1242			} else {
1243				if (plane->src_rect.width >= 3840)
1244					desktop_large = true;
1245				if (!plane->dcc.enable)
1246					dcc_disabled = true;
1247			}
1248		}
1249	}
1250
1251	/* Disable MPO in multi-display configurations. */
1252	if (context->stream_count > 1 && mpo_enabled)
1253		return DC_FAIL_UNSUPPORTED_1;
1254
1255	/*
1256	 * Workaround: On DCN10 there is UMC issue that causes underflow when
1257	 * playing 4k video on 4k desktop with video downscaled and single channel
1258	 * memory
1259	 */
1260	if (video_large && desktop_large && video_down_scaled && dcc_disabled &&
1261			dc->dcn_soc->number_of_channels == 1)
1262		return DC_FAIL_SURFACE_VALIDATE;
1263
1264	return DC_OK;
1265}
1266
1267static enum dc_status dcn10_patch_unknown_plane_state(struct dc_plane_state *plane_state)
1268{
1269	enum dc_status result = DC_OK;
1270
1271	enum surface_pixel_format surf_pix_format = plane_state->format;
1272	unsigned int bpp = resource_pixel_format_to_bpp(surf_pix_format);
1273
1274	enum swizzle_mode_values swizzle = DC_SW_LINEAR;
1275
1276	if (bpp == 64)
1277		swizzle = DC_SW_64KB_D;
1278	else
1279		swizzle = DC_SW_64KB_S;
1280
1281	plane_state->tiling_info.gfx9.swizzle = swizzle;
1282	return result;
1283}
1284
1285struct stream_encoder *dcn10_find_first_free_match_stream_enc_for_link(
1286		struct resource_context *res_ctx,
1287		const struct resource_pool *pool,
1288		struct dc_stream_state *stream)
1289{
1290	int i;
1291	int j = -1;
1292	struct dc_link *link = stream->link;
1293
1294	for (i = 0; i < pool->stream_enc_count; i++) {
1295		if (!res_ctx->is_stream_enc_acquired[i] &&
1296				pool->stream_enc[i]) {
1297			/* Store first available for MST second display
1298			 * in daisy chain use case
1299			 */
1300			j = i;
1301			if (pool->stream_enc[i]->id ==
1302					link->link_enc->preferred_engine)
1303				return pool->stream_enc[i];
1304		}
1305	}
1306
1307	/*
1308	 * For CZ and later, we can allow DIG FE and BE to differ for all display types
1309	 */
1310
1311	if (j >= 0)
1312		return pool->stream_enc[j];
1313
1314	return NULL;
1315}
1316
1317static const struct dc_cap_funcs cap_funcs = {
1318	.get_dcc_compression_cap = dcn10_get_dcc_compression_cap
1319};
1320
1321static const struct resource_funcs dcn10_res_pool_funcs = {
1322	.destroy = dcn10_destroy_resource_pool,
1323	.link_enc_create = dcn10_link_encoder_create,
1324	.panel_cntl_create = dcn10_panel_cntl_create,
1325	.validate_bandwidth = dcn_validate_bandwidth,
1326	.acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
1327	.validate_plane = dcn10_validate_plane,
1328	.validate_global = dcn10_validate_global,
1329	.add_stream_to_ctx = dcn10_add_stream_to_ctx,
1330	.patch_unknown_plane_state = dcn10_patch_unknown_plane_state,
1331	.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link
1332};
1333
1334static uint32_t read_pipe_fuses(struct dc_context *ctx)
1335{
1336	uint32_t value = dm_read_reg_soc15(ctx, mmCC_DC_PIPE_DIS, 0);
1337	/* RV1 support max 4 pipes */
1338	value = value & 0xf;
1339	return value;
1340}
1341
1342static bool dcn10_resource_construct(
1343	uint8_t num_virtual_links,
1344	struct dc *dc,
1345	struct dcn10_resource_pool *pool)
1346{
1347	int i;
1348	int j;
1349	struct dc_context *ctx = dc->ctx;
1350	uint32_t pipe_fuses = read_pipe_fuses(ctx);
1351
1352	ctx->dc_bios->regs = &bios_regs;
1353
1354	if (ctx->dce_version == DCN_VERSION_1_01)
1355		pool->base.res_cap = &rv2_res_cap;
1356	else
1357		pool->base.res_cap = &res_cap;
1358	pool->base.funcs = &dcn10_res_pool_funcs;
1359
1360	/*
1361	 * TODO fill in from actual raven resource when we create
1362	 * more than virtual encoder
1363	 */
1364
1365	/*************************************************
1366	 *  Resource + asic cap harcoding                *
1367	 *************************************************/
1368	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1369
1370	/* max pipe num for ASIC before check pipe fuses */
1371	pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1372
1373	if (dc->ctx->dce_version == DCN_VERSION_1_01)
1374		pool->base.pipe_count = 3;
1375	dc->caps.max_video_width = 3840;
1376	dc->caps.max_downscale_ratio = 200;
1377	dc->caps.i2c_speed_in_khz = 100;
1378	dc->caps.max_cursor_size = 256;
1379	dc->caps.max_slave_planes = 1;
1380	dc->caps.is_apu = true;
1381	dc->caps.post_blend_color_processing = false;
1382	dc->caps.extended_aux_timeout_support = false;
1383
1384	/* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
1385	dc->caps.force_dp_tps4_for_cp2520 = true;
1386
1387	/* Color pipeline capabilities */
1388	dc->caps.color.dpp.dcn_arch = 1;
1389	dc->caps.color.dpp.input_lut_shared = 1;
1390	dc->caps.color.dpp.icsc = 1;
1391	dc->caps.color.dpp.dgam_ram = 1;
1392	dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
1393	dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
1394	dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0;
1395	dc->caps.color.dpp.dgam_rom_caps.pq = 0;
1396	dc->caps.color.dpp.dgam_rom_caps.hlg = 0;
1397	dc->caps.color.dpp.post_csc = 0;
1398	dc->caps.color.dpp.gamma_corr = 0;
1399
1400	dc->caps.color.dpp.hw_3d_lut = 0;
1401	dc->caps.color.dpp.ogam_ram = 1; // RGAM on DCN1
1402	dc->caps.color.dpp.ogam_rom_caps.srgb = 1;
1403	dc->caps.color.dpp.ogam_rom_caps.bt2020 = 1;
1404	dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
1405	dc->caps.color.dpp.ogam_rom_caps.pq = 0;
1406	dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
1407	dc->caps.color.dpp.ocsc = 1;
1408
1409	/* no post-blend color operations */
1410	dc->caps.color.mpc.gamut_remap = 0;
1411	dc->caps.color.mpc.num_3dluts = 0;
1412	dc->caps.color.mpc.shared_3d_lut = 0;
1413	dc->caps.color.mpc.ogam_ram = 0;
1414	dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
1415	dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
1416	dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
1417	dc->caps.color.mpc.ogam_rom_caps.pq = 0;
1418	dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
1419	dc->caps.color.mpc.ocsc = 0;
1420
1421	if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
1422		dc->debug = debug_defaults_drv;
1423	else
1424		dc->debug = debug_defaults_diags;
1425
1426	/*************************************************
1427	 *  Create resources                             *
1428	 *************************************************/
1429
1430	pool->base.clock_sources[DCN10_CLK_SRC_PLL0] =
1431			dcn10_clock_source_create(ctx, ctx->dc_bios,
1432				CLOCK_SOURCE_COMBO_PHY_PLL0,
1433				&clk_src_regs[0], false);
1434	pool->base.clock_sources[DCN10_CLK_SRC_PLL1] =
1435			dcn10_clock_source_create(ctx, ctx->dc_bios,
1436				CLOCK_SOURCE_COMBO_PHY_PLL1,
1437				&clk_src_regs[1], false);
1438	pool->base.clock_sources[DCN10_CLK_SRC_PLL2] =
1439			dcn10_clock_source_create(ctx, ctx->dc_bios,
1440				CLOCK_SOURCE_COMBO_PHY_PLL2,
1441				&clk_src_regs[2], false);
1442
1443	if (dc->ctx->dce_version == DCN_VERSION_1_0) {
1444		pool->base.clock_sources[DCN10_CLK_SRC_PLL3] =
1445				dcn10_clock_source_create(ctx, ctx->dc_bios,
1446					CLOCK_SOURCE_COMBO_PHY_PLL3,
1447					&clk_src_regs[3], false);
1448	}
1449
1450	pool->base.clk_src_count = DCN10_CLK_SRC_TOTAL;
1451
1452	if (dc->ctx->dce_version == DCN_VERSION_1_01)
1453		pool->base.clk_src_count = DCN101_CLK_SRC_TOTAL;
1454
1455	pool->base.dp_clock_source =
1456			dcn10_clock_source_create(ctx, ctx->dc_bios,
1457				CLOCK_SOURCE_ID_DP_DTO,
1458				/* todo: not reuse phy_pll registers */
1459				&clk_src_regs[0], true);
1460
1461	for (i = 0; i < pool->base.clk_src_count; i++) {
1462		if (pool->base.clock_sources[i] == NULL) {
1463			dm_error("DC: failed to create clock sources!\n");
1464			BREAK_TO_DEBUGGER();
1465			goto fail;
1466		}
1467	}
1468
1469	pool->base.dmcu = dcn10_dmcu_create(ctx,
1470			&dmcu_regs,
1471			&dmcu_shift,
1472			&dmcu_mask);
1473	if (pool->base.dmcu == NULL) {
1474		dm_error("DC: failed to create dmcu!\n");
1475		BREAK_TO_DEBUGGER();
1476		goto fail;
1477	}
1478
1479	pool->base.abm = dce_abm_create(ctx,
1480			&abm_regs,
1481			&abm_shift,
1482			&abm_mask);
1483	if (pool->base.abm == NULL) {
1484		dm_error("DC: failed to create abm!\n");
1485		BREAK_TO_DEBUGGER();
1486		goto fail;
1487	}
1488
1489	dml_init_instance(&dc->dml, &dcn1_0_soc, &dcn1_0_ip, DML_PROJECT_RAVEN1);
1490	memcpy(dc->dcn_ip, &dcn10_ip_defaults, sizeof(dcn10_ip_defaults));
1491	memcpy(dc->dcn_soc, &dcn10_soc_defaults, sizeof(dcn10_soc_defaults));
1492
1493	if (dc->ctx->dce_version == DCN_VERSION_1_01) {
1494		struct dcn_soc_bounding_box *dcn_soc = dc->dcn_soc;
1495		struct dcn_ip_params *dcn_ip = dc->dcn_ip;
1496		struct display_mode_lib *dml = &dc->dml;
1497
1498		dml->ip.max_num_dpp = 3;
1499		/* TODO how to handle 23.84? */
1500		dcn_soc->dram_clock_change_latency = 23;
1501		dcn_ip->max_num_dpp = 3;
1502	}
1503	if (ASICREV_IS_RV1_F0(dc->ctx->asic_id.hw_internal_rev)) {
1504		dc->dcn_soc->urgent_latency = 3;
1505		dc->debug.disable_dmcu = true;
1506		dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 41.60f;
1507	}
1508
1509
1510	dc->dcn_soc->number_of_channels = dc->ctx->asic_id.vram_width / ddr4_dram_width;
1511	ASSERT(dc->dcn_soc->number_of_channels < 3);
1512	if (dc->dcn_soc->number_of_channels == 0)/*old sbios bug*/
1513		dc->dcn_soc->number_of_channels = 2;
1514
1515	if (dc->dcn_soc->number_of_channels == 1) {
1516		dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 19.2f;
1517		dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = 17.066f;
1518		dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = 14.933f;
1519		dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = 12.8f;
1520		if (ASICREV_IS_RV1_F0(dc->ctx->asic_id.hw_internal_rev)) {
1521			dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 20.80f;
1522		}
1523	}
1524
1525	pool->base.pp_smu = dcn10_pp_smu_create(ctx);
1526
1527	/*
1528	 * Right now SMU/PPLIB and DAL all have the AZ D3 force PME notification *
1529	 * implemented. So AZ D3 should work.For issue 197007.                   *
1530	 */
1531	if (pool->base.pp_smu != NULL
1532			&& pool->base.pp_smu->rv_funcs.set_pme_wa_enable != NULL)
1533		dc->debug.az_endpoint_mute_only = false;
1534
1535	if (!dc->debug.disable_pplib_clock_request)
1536		dcn_bw_update_from_pplib(dc);
1537	dcn_bw_sync_calcs_and_dml(dc);
1538	if (!dc->debug.disable_pplib_wm_range) {
1539		dc->res_pool = &pool->base;
1540		dcn_bw_notify_pplib_of_wm_ranges(dc);
1541	}
1542
1543	{
1544		struct irq_service_init_data init_data;
1545		init_data.ctx = dc->ctx;
1546		pool->base.irqs = dal_irq_service_dcn10_create(&init_data);
1547		if (!pool->base.irqs)
1548			goto fail;
1549	}
1550
1551	/* index to valid pipe resource  */
1552	j = 0;
1553	/* mem input -> ipp -> dpp -> opp -> TG */
1554	for (i = 0; i < pool->base.pipe_count; i++) {
1555		/* if pipe is disabled, skip instance of HW pipe,
1556		 * i.e, skip ASIC register instance
1557		 */
1558		if ((pipe_fuses & (1 << i)) != 0)
1559			continue;
1560
1561		pool->base.hubps[j] = dcn10_hubp_create(ctx, i);
1562		if (pool->base.hubps[j] == NULL) {
1563			BREAK_TO_DEBUGGER();
1564			dm_error(
1565				"DC: failed to create memory input!\n");
1566			goto fail;
1567		}
1568
1569		pool->base.ipps[j] = dcn10_ipp_create(ctx, i);
1570		if (pool->base.ipps[j] == NULL) {
1571			BREAK_TO_DEBUGGER();
1572			dm_error(
1573				"DC: failed to create input pixel processor!\n");
1574			goto fail;
1575		}
1576
1577		pool->base.dpps[j] = dcn10_dpp_create(ctx, i);
1578		if (pool->base.dpps[j] == NULL) {
1579			BREAK_TO_DEBUGGER();
1580			dm_error(
1581				"DC: failed to create dpp!\n");
1582			goto fail;
1583		}
1584
1585		pool->base.opps[j] = dcn10_opp_create(ctx, i);
1586		if (pool->base.opps[j] == NULL) {
1587			BREAK_TO_DEBUGGER();
1588			dm_error(
1589				"DC: failed to create output pixel processor!\n");
1590			goto fail;
1591		}
1592
1593		pool->base.timing_generators[j] = dcn10_timing_generator_create(
1594				ctx, i);
1595		if (pool->base.timing_generators[j] == NULL) {
1596			BREAK_TO_DEBUGGER();
1597			dm_error("DC: failed to create tg!\n");
1598			goto fail;
1599		}
1600		/* check next valid pipe */
1601		j++;
1602	}
1603
1604	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1605		pool->base.engines[i] = dcn10_aux_engine_create(ctx, i);
1606		if (pool->base.engines[i] == NULL) {
1607			BREAK_TO_DEBUGGER();
1608			dm_error(
1609				"DC:failed to create aux engine!!\n");
1610			goto fail;
1611		}
1612		pool->base.hw_i2cs[i] = dcn10_i2c_hw_create(ctx, i);
1613		if (pool->base.hw_i2cs[i] == NULL) {
1614			BREAK_TO_DEBUGGER();
1615			dm_error(
1616				"DC:failed to create hw i2c!!\n");
1617			goto fail;
1618		}
1619		pool->base.sw_i2cs[i] = NULL;
1620	}
1621
1622	/* valid pipe num */
1623	pool->base.pipe_count = j;
1624	pool->base.timing_generator_count = j;
1625
1626	/* within dml lib, it is hard code to 4. If ASIC pipe is fused,
1627	 * the value may be changed
1628	 */
1629	dc->dml.ip.max_num_dpp = pool->base.pipe_count;
1630	dc->dcn_ip->max_num_dpp = pool->base.pipe_count;
1631
1632	pool->base.mpc = dcn10_mpc_create(ctx);
1633	if (pool->base.mpc == NULL) {
1634		BREAK_TO_DEBUGGER();
1635		dm_error("DC: failed to create mpc!\n");
1636		goto fail;
1637	}
1638
1639	pool->base.hubbub = dcn10_hubbub_create(ctx);
1640	if (pool->base.hubbub == NULL) {
1641		BREAK_TO_DEBUGGER();
1642		dm_error("DC: failed to create hubbub!\n");
1643		goto fail;
1644	}
1645
1646	if (!resource_construct(num_virtual_links, dc, &pool->base,
1647			(!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
1648			&res_create_funcs : &res_create_maximus_funcs)))
1649			goto fail;
1650
1651	dcn10_hw_sequencer_construct(dc);
1652	dc->caps.max_planes =  pool->base.pipe_count;
1653
1654	for (i = 0; i < dc->caps.max_planes; ++i)
1655		dc->caps.planes[i] = plane_cap;
1656
1657	dc->cap_funcs = cap_funcs;
1658
1659	return true;
1660
1661fail:
1662
1663	dcn10_resource_destruct(pool);
1664
1665	return false;
1666}
1667
1668struct resource_pool *dcn10_create_resource_pool(
1669		const struct dc_init_data *init_data,
1670		struct dc *dc)
1671{
1672	struct dcn10_resource_pool *pool =
1673		kzalloc(sizeof(struct dcn10_resource_pool), GFP_KERNEL);
1674
1675	if (!pool)
1676		return NULL;
1677
1678	if (dcn10_resource_construct(init_data->num_virtual_links, dc, pool))
1679		return &pool->base;
1680
1681	kfree(pool);
1682	BREAK_TO_DEBUGGER();
1683	return NULL;
1684}