brintos

brintos / linux-shallow public Read only

0
0
Text · 32.7 KiB · 621825a Raw
1289 lines · c
1/*2* Copyright 2012-15 Advanced Micro Devices, Inc.cls3*4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR21 * OTHER DEALINGS IN THE SOFTWARE.22 *23 * Authors: AMD24 *25 */26 27#include "dm_services.h"28 29 30#include "stream_encoder.h"31#include "resource.h"32#include "include/irq_service_interface.h"33#include "dce120_resource.h"34 35#include "dce112/dce112_resource.h"36 37#include "dce110/dce110_resource.h"38#include "virtual/virtual_stream_encoder.h"39#include "dce120/dce120_timing_generator.h"40#include "irq/dce120/irq_service_dce120.h"41#include "dce/dce_opp.h"42#include "dce/dce_clock_source.h"43#include "dce/dce_ipp.h"44#include "dce/dce_mem_input.h"45#include "dce/dce_panel_cntl.h"46 47#include "dce110/dce110_hwseq.h"48#include "dce120/dce120_hwseq.h"49#include "dce/dce_transform.h"50#include "clk_mgr.h"51#include "dce/dce_audio.h"52#include "dce/dce_link_encoder.h"53#include "dce/dce_stream_encoder.h"54#include "dce/dce_hwseq.h"55#include "dce/dce_abm.h"56#include "dce/dce_dmcu.h"57#include "dce/dce_aux.h"58#include "dce/dce_i2c.h"59 60#include "dce/dce_12_0_offset.h"61#include "dce/dce_12_0_sh_mask.h"62#include "soc15_hw_ip.h"63#include "vega10_ip_offset.h"64#include "nbio/nbio_6_1_offset.h"65#include "mmhub/mmhub_1_0_offset.h"66#include "mmhub/mmhub_1_0_sh_mask.h"67#include "reg_helper.h"68 69#include "dce100/dce100_resource.h"70 71#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL72	#define mmDP0_DP_DPHY_INTERNAL_CTRL		0x210f73	#define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX	274	#define mmDP1_DP_DPHY_INTERNAL_CTRL		0x220f75	#define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX	276	#define mmDP2_DP_DPHY_INTERNAL_CTRL		0x230f77	#define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX	278	#define mmDP3_DP_DPHY_INTERNAL_CTRL		0x240f79	#define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX	280	#define mmDP4_DP_DPHY_INTERNAL_CTRL		0x250f81	#define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX	282	#define mmDP5_DP_DPHY_INTERNAL_CTRL		0x260f83	#define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX	284	#define mmDP6_DP_DPHY_INTERNAL_CTRL		0x270f85	#define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX	286#endif87 88enum dce120_clk_src_array_id {89	DCE120_CLK_SRC_PLL0,90	DCE120_CLK_SRC_PLL1,91	DCE120_CLK_SRC_PLL2,92	DCE120_CLK_SRC_PLL3,93	DCE120_CLK_SRC_PLL4,94	DCE120_CLK_SRC_PLL5,95 96	DCE120_CLK_SRC_TOTAL97};98 99static const struct dce110_timing_generator_offsets dce120_tg_offsets[] = {100	{101		.crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),102	},103	{104		.crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),105	},106	{107		.crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),108	},109	{110		.crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),111	},112	{113		.crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),114	},115	{116		.crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),117	}118};119 120/* begin *********************121 * macros to expend register list macro defined in HW object header file */122 123#define BASE_INNER(seg) \124	DCE_BASE__INST0_SEG ## seg125 126#define NBIO_BASE_INNER(seg) \127	NBIF_BASE__INST0_SEG ## seg128 129#define NBIO_BASE(seg) \130	NBIO_BASE_INNER(seg)131 132/* compile time expand base address. */133#define BASE(seg) \134	BASE_INNER(seg)135 136#define SR(reg_name)\137		.reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \138					mm ## reg_name139 140#define SRI(reg_name, block, id)\141	.reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \142					mm ## block ## id ## _ ## reg_name143 144/* MMHUB */145#define MMHUB_BASE_INNER(seg) \146	MMHUB_BASE__INST0_SEG ## seg147 148#define MMHUB_BASE(seg) \149	MMHUB_BASE_INNER(seg)150 151#define MMHUB_SR(reg_name)\152		.reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) +  \153					mm ## reg_name154 155/* macros to expend register list macro defined in HW object header file156 * end *********************/157 158 159static const struct dce_dmcu_registers dmcu_regs = {160		DMCU_DCE110_COMMON_REG_LIST()161};162 163static const struct dce_dmcu_shift dmcu_shift = {164		DMCU_MASK_SH_LIST_DCE110(__SHIFT)165};166 167static const struct dce_dmcu_mask dmcu_mask = {168		DMCU_MASK_SH_LIST_DCE110(_MASK)169};170 171static const struct dce_abm_registers abm_regs = {172		ABM_DCE110_COMMON_REG_LIST()173};174 175static const struct dce_abm_shift abm_shift = {176		ABM_MASK_SH_LIST_DCE110(__SHIFT)177};178 179static const struct dce_abm_mask abm_mask = {180		ABM_MASK_SH_LIST_DCE110(_MASK)181};182 183#define ipp_regs(id)\184[id] = {\185		IPP_DCE110_REG_LIST_DCE_BASE(id)\186}187 188static const struct dce_ipp_registers ipp_regs[] = {189		ipp_regs(0),190		ipp_regs(1),191		ipp_regs(2),192		ipp_regs(3),193		ipp_regs(4),194		ipp_regs(5)195};196 197static const struct dce_ipp_shift ipp_shift = {198		IPP_DCE120_MASK_SH_LIST_SOC_BASE(__SHIFT)199};200 201static const struct dce_ipp_mask ipp_mask = {202		IPP_DCE120_MASK_SH_LIST_SOC_BASE(_MASK)203};204 205#define transform_regs(id)\206[id] = {\207		XFM_COMMON_REG_LIST_DCE110(id)\208}209 210static const struct dce_transform_registers xfm_regs[] = {211		transform_regs(0),212		transform_regs(1),213		transform_regs(2),214		transform_regs(3),215		transform_regs(4),216		transform_regs(5)217};218 219static const struct dce_transform_shift xfm_shift = {220		XFM_COMMON_MASK_SH_LIST_SOC_BASE(__SHIFT)221};222 223static const struct dce_transform_mask xfm_mask = {224		XFM_COMMON_MASK_SH_LIST_SOC_BASE(_MASK)225};226 227#define aux_regs(id)\228[id] = {\229	AUX_REG_LIST(id)\230}231 232static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {233		aux_regs(0),234		aux_regs(1),235		aux_regs(2),236		aux_regs(3),237		aux_regs(4),238		aux_regs(5)239};240 241#define hpd_regs(id)\242[id] = {\243	HPD_REG_LIST(id)\244}245 246static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {247		hpd_regs(0),248		hpd_regs(1),249		hpd_regs(2),250		hpd_regs(3),251		hpd_regs(4),252		hpd_regs(5)253};254 255#define link_regs(id)\256[id] = {\257	LE_DCE120_REG_LIST(id), \258	SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \259}260 261static const struct dce110_link_enc_registers link_enc_regs[] = {262	link_regs(0),263	link_regs(1),264	link_regs(2),265	link_regs(3),266	link_regs(4),267	link_regs(5),268	link_regs(6),269};270 271 272#define stream_enc_regs(id)\273[id] = {\274	SE_COMMON_REG_LIST(id),\275	.TMDS_CNTL = 0,\276}277 278static const struct dce110_stream_enc_registers stream_enc_regs[] = {279	stream_enc_regs(0),280	stream_enc_regs(1),281	stream_enc_regs(2),282	stream_enc_regs(3),283	stream_enc_regs(4),284	stream_enc_regs(5)285};286 287static const struct dce_stream_encoder_shift se_shift = {288		SE_COMMON_MASK_SH_LIST_DCE120(__SHIFT)289};290 291static const struct dce_stream_encoder_mask se_mask = {292		SE_COMMON_MASK_SH_LIST_DCE120(_MASK)293};294 295static const struct dce_panel_cntl_registers panel_cntl_regs[] = {296	{ DCE_PANEL_CNTL_REG_LIST() }297};298 299static const struct dce_panel_cntl_shift panel_cntl_shift = {300	DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)301};302 303static const struct dce_panel_cntl_mask panel_cntl_mask = {304	DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)305};306 307static const struct dce110_aux_registers_shift aux_shift = {308	DCE12_AUX_MASK_SH_LIST(__SHIFT)309};310 311static const struct dce110_aux_registers_mask aux_mask = {312	DCE12_AUX_MASK_SH_LIST(_MASK)313};314 315#define opp_regs(id)\316[id] = {\317	OPP_DCE_120_REG_LIST(id),\318}319 320static const struct dce_opp_registers opp_regs[] = {321	opp_regs(0),322	opp_regs(1),323	opp_regs(2),324	opp_regs(3),325	opp_regs(4),326	opp_regs(5)327};328 329static const struct dce_opp_shift opp_shift = {330	OPP_COMMON_MASK_SH_LIST_DCE_120(__SHIFT)331};332 333static const struct dce_opp_mask opp_mask = {334	OPP_COMMON_MASK_SH_LIST_DCE_120(_MASK)335};336 #define aux_engine_regs(id)\337[id] = {\338	AUX_COMMON_REG_LIST(id), \339	.AUX_RESET_MASK = 0 \340}341 342static const struct dce110_aux_registers aux_engine_regs[] = {343		aux_engine_regs(0),344		aux_engine_regs(1),345		aux_engine_regs(2),346		aux_engine_regs(3),347		aux_engine_regs(4),348		aux_engine_regs(5)349};350 351#define audio_regs(id)\352[id] = {\353	AUD_COMMON_REG_LIST(id)\354}355 356static const struct dce_audio_registers audio_regs[] = {357	audio_regs(0),358	audio_regs(1),359	audio_regs(2),360	audio_regs(3),361	audio_regs(4),362	audio_regs(5),363	audio_regs(6),364};365 366#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\367		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\368		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\369		AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)370 371static const struct dce_audio_shift audio_shift = {372		DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)373};374 375static const struct dce_audio_mask audio_mask = {376		DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)377};378 379static int map_transmitter_id_to_phy_instance(380	enum transmitter transmitter)381{382	switch (transmitter) {383	case TRANSMITTER_UNIPHY_A:384		return 0;385	case TRANSMITTER_UNIPHY_B:386		return 1;387	case TRANSMITTER_UNIPHY_C:388		return 2;389	case TRANSMITTER_UNIPHY_D:390		return 3;391	case TRANSMITTER_UNIPHY_E:392		return 4;393	case TRANSMITTER_UNIPHY_F:394		return 5;395	case TRANSMITTER_UNIPHY_G:396		return 6;397	default:398		ASSERT(0);399		return 0;400	}401}402 403#define clk_src_regs(index, id)\404[index] = {\405	CS_COMMON_REG_LIST_DCE_112(id),\406}407 408static const struct dce110_clk_src_regs clk_src_regs[] = {409	clk_src_regs(0, A),410	clk_src_regs(1, B),411	clk_src_regs(2, C),412	clk_src_regs(3, D),413	clk_src_regs(4, E),414	clk_src_regs(5, F)415};416 417static const struct dce110_clk_src_shift cs_shift = {418		CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)419};420 421static const struct dce110_clk_src_mask cs_mask = {422		CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)423};424 425static struct output_pixel_processor *dce120_opp_create(426	struct dc_context *ctx,427	uint32_t inst)428{429	struct dce110_opp *opp =430		kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);431 432	if (!opp)433		return NULL;434 435	dce110_opp_construct(opp,436			     ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);437	return &opp->base;438}439static struct dce_aux *dce120_aux_engine_create(440	struct dc_context *ctx,441	uint32_t inst)442{443	struct aux_engine_dce110 *aux_engine =444		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);445 446	if (!aux_engine)447		return NULL;448 449	dce110_aux_engine_construct(aux_engine, ctx, inst,450				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,451				    &aux_engine_regs[inst],452					&aux_mask,453					&aux_shift,454					ctx->dc->caps.extended_aux_timeout_support);455 456	return &aux_engine->base;457}458#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }459 460static const struct dce_i2c_registers i2c_hw_regs[] = {461		i2c_inst_regs(1),462		i2c_inst_regs(2),463		i2c_inst_regs(3),464		i2c_inst_regs(4),465		i2c_inst_regs(5),466		i2c_inst_regs(6),467};468 469static const struct dce_i2c_shift i2c_shifts = {470		I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)471};472 473static const struct dce_i2c_mask i2c_masks = {474		I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)475};476 477static struct dce_i2c_hw *dce120_i2c_hw_create(478	struct dc_context *ctx,479	uint32_t inst)480{481	struct dce_i2c_hw *dce_i2c_hw =482		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);483 484	if (!dce_i2c_hw)485		return NULL;486 487	dce112_i2c_hw_construct(dce_i2c_hw, ctx, inst,488				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);489 490	return dce_i2c_hw;491}492static const struct bios_registers bios_regs = {493	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3 + NBIO_BASE(mmBIOS_SCRATCH_3_BASE_IDX),494	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX)495};496 497static const struct resource_caps res_cap = {498		.num_timing_generator = 6,499		.num_audio = 7,500		.num_stream_encoder = 6,501		.num_pll = 6,502		.num_ddc = 6,503};504 505static const struct dc_plane_cap plane_cap = {506	.type = DC_PLANE_TYPE_DCE_RGB,507 508	.pixel_format_support = {509			.argb8888 = true,510			.nv12 = false,511			.fp16 = true512	},513 514	.max_upscale_factor = {515			.argb8888 = 16000,516			.nv12 = 1,517			.fp16 = 1518	},519 520	.max_downscale_factor = {521			.argb8888 = 250,522			.nv12 = 1,523			.fp16 = 1524	}525};526 527static const struct dc_debug_options debug_defaults = {528		.disable_clock_gate = true,529		.enable_legacy_fast_update = true,530};531 532static struct clock_source *dce120_clock_source_create(533	struct dc_context *ctx,534	struct dc_bios *bios,535	enum clock_source_id id,536	const struct dce110_clk_src_regs *regs,537	bool dp_clk_src)538{539	struct dce110_clk_src *clk_src =540		kzalloc(sizeof(*clk_src), GFP_KERNEL);541 542	if (!clk_src)543		return NULL;544 545	if (dce112_clk_src_construct(clk_src, ctx, bios, id,546				     regs, &cs_shift, &cs_mask)) {547		clk_src->base.dp_clk_src = dp_clk_src;548		return &clk_src->base;549	}550 551	kfree(clk_src);552	BREAK_TO_DEBUGGER();553	return NULL;554}555 556static void dce120_clock_source_destroy(struct clock_source **clk_src)557{558	kfree(TO_DCE110_CLK_SRC(*clk_src));559	*clk_src = NULL;560}561 562 563static bool dce120_hw_sequencer_create(struct dc *dc)564{565	/* All registers used by dce11.2 match those in dce11 in offset and566	 * structure567	 */568	dce120_hw_sequencer_construct(dc);569 570	/*TODO	Move to separate file and Override what is needed */571 572	return true;573}574 575static struct timing_generator *dce120_timing_generator_create(576		struct dc_context *ctx,577		uint32_t instance,578		const struct dce110_timing_generator_offsets *offsets)579{580	struct dce110_timing_generator *tg110 =581		kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);582 583	if (!tg110)584		return NULL;585 586	dce120_timing_generator_construct(tg110, ctx, instance, offsets);587	return &tg110->base;588}589 590static void dce120_transform_destroy(struct transform **xfm)591{592	kfree(TO_DCE_TRANSFORM(*xfm));593	*xfm = NULL;594}595 596static void dce120_resource_destruct(struct dce110_resource_pool *pool)597{598	unsigned int i;599 600	for (i = 0; i < pool->base.pipe_count; i++) {601		if (pool->base.opps[i] != NULL)602			dce110_opp_destroy(&pool->base.opps[i]);603 604		if (pool->base.transforms[i] != NULL)605			dce120_transform_destroy(&pool->base.transforms[i]);606 607		if (pool->base.ipps[i] != NULL)608			dce_ipp_destroy(&pool->base.ipps[i]);609 610		if (pool->base.mis[i] != NULL) {611			kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));612			pool->base.mis[i] = NULL;613		}614 615		if (pool->base.irqs != NULL) {616			dal_irq_service_destroy(&pool->base.irqs);617		}618 619		if (pool->base.timing_generators[i] != NULL) {620			kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));621			pool->base.timing_generators[i] = NULL;622		}623	}624 625	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {626		if (pool->base.engines[i] != NULL)627			dce110_engine_destroy(&pool->base.engines[i]);628		if (pool->base.hw_i2cs[i] != NULL) {629			kfree(pool->base.hw_i2cs[i]);630			pool->base.hw_i2cs[i] = NULL;631		}632		if (pool->base.sw_i2cs[i] != NULL) {633			kfree(pool->base.sw_i2cs[i]);634			pool->base.sw_i2cs[i] = NULL;635		}636	}637 638	for (i = 0; i < pool->base.audio_count; i++) {639		if (pool->base.audios[i])640			dce_aud_destroy(&pool->base.audios[i]);641	}642 643	for (i = 0; i < pool->base.stream_enc_count; i++) {644		if (pool->base.stream_enc[i] != NULL)645			kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));646	}647 648	for (i = 0; i < pool->base.clk_src_count; i++) {649		if (pool->base.clock_sources[i] != NULL)650			dce120_clock_source_destroy(651				&pool->base.clock_sources[i]);652	}653 654	if (pool->base.dp_clock_source != NULL)655		dce120_clock_source_destroy(&pool->base.dp_clock_source);656 657	if (pool->base.abm != NULL)658		dce_abm_destroy(&pool->base.abm);659 660	if (pool->base.dmcu != NULL)661		dce_dmcu_destroy(&pool->base.dmcu);662}663 664static void read_dce_straps(665	struct dc_context *ctx,666	struct resource_straps *straps)667{668	uint32_t reg_val = dm_read_reg_soc15(ctx, mmCC_DC_MISC_STRAPS, 0);669 670	straps->audio_stream_number = get_reg_field_value(reg_val,671							  CC_DC_MISC_STRAPS,672							  AUDIO_STREAM_NUMBER);673	straps->hdmi_disable = get_reg_field_value(reg_val,674						   CC_DC_MISC_STRAPS,675						   HDMI_DISABLE);676 677	reg_val = dm_read_reg_soc15(ctx, mmDC_PINSTRAPS, 0);678	straps->dc_pinstraps_audio = get_reg_field_value(reg_val,679							 DC_PINSTRAPS,680							 DC_PINSTRAPS_AUDIO);681}682 683static struct audio *create_audio(684		struct dc_context *ctx, unsigned int inst)685{686	return dce_audio_create(ctx, inst,687			&audio_regs[inst], &audio_shift, &audio_mask);688}689 690static const struct encoder_feature_support link_enc_feature = {691		.max_hdmi_deep_color = COLOR_DEPTH_121212,692		.max_hdmi_pixel_clock = 600000,693		.hdmi_ycbcr420_supported = true,694		.dp_ycbcr420_supported = false,695		.flags.bits.IS_HBR2_CAPABLE = true,696		.flags.bits.IS_HBR3_CAPABLE = true,697		.flags.bits.IS_TPS3_CAPABLE = true,698		.flags.bits.IS_TPS4_CAPABLE = true,699};700 701static struct link_encoder *dce120_link_encoder_create(702	struct dc_context *ctx,703	const struct encoder_init_data *enc_init_data)704{705	struct dce110_link_encoder *enc110 =706		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);707	int link_regs_id;708 709	if (!enc110)710		return NULL;711 712	link_regs_id =713		map_transmitter_id_to_phy_instance(enc_init_data->transmitter);714 715	dce110_link_encoder_construct(enc110,716				      enc_init_data,717				      &link_enc_feature,718				      &link_enc_regs[link_regs_id],719				      &link_enc_aux_regs[enc_init_data->channel - 1],720				      &link_enc_hpd_regs[enc_init_data->hpd_source]);721 722	return &enc110->base;723}724 725static struct panel_cntl *dce120_panel_cntl_create(const struct panel_cntl_init_data *init_data)726{727	struct dce_panel_cntl *panel_cntl =728		kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);729 730	if (!panel_cntl)731		return NULL;732 733	dce_panel_cntl_construct(panel_cntl,734			init_data,735			&panel_cntl_regs[init_data->inst],736			&panel_cntl_shift,737			&panel_cntl_mask);738 739	return &panel_cntl->base;740}741 742static struct input_pixel_processor *dce120_ipp_create(743	struct dc_context *ctx, uint32_t inst)744{745	struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);746 747	if (!ipp) {748		BREAK_TO_DEBUGGER();749		return NULL;750	}751 752	dce_ipp_construct(ipp, ctx, inst,753			&ipp_regs[inst], &ipp_shift, &ipp_mask);754	return &ipp->base;755}756 757static struct stream_encoder *dce120_stream_encoder_create(758	enum engine_id eng_id,759	struct dc_context *ctx)760{761	struct dce110_stream_encoder *enc110 =762		kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);763 764	if (!enc110)765		return NULL;766 767	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,768					&stream_enc_regs[eng_id],769					&se_shift, &se_mask);770	return &enc110->base;771}772 773#define SRII(reg_name, block, id)\774	.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \775					mm ## block ## id ## _ ## reg_name776 777static const struct dce_hwseq_registers hwseq_reg = {778		HWSEQ_DCE120_REG_LIST()779};780 781static const struct dce_hwseq_shift hwseq_shift = {782		HWSEQ_DCE12_MASK_SH_LIST(__SHIFT)783};784 785static const struct dce_hwseq_mask hwseq_mask = {786		HWSEQ_DCE12_MASK_SH_LIST(_MASK)787};788 789/* HWSEQ regs for VG20 */790static const struct dce_hwseq_registers dce121_hwseq_reg = {791		HWSEQ_VG20_REG_LIST()792};793 794static const struct dce_hwseq_shift dce121_hwseq_shift = {795		HWSEQ_VG20_MASK_SH_LIST(__SHIFT)796};797 798static const struct dce_hwseq_mask dce121_hwseq_mask = {799		HWSEQ_VG20_MASK_SH_LIST(_MASK)800};801 802static struct dce_hwseq *dce120_hwseq_create(803	struct dc_context *ctx)804{805	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);806 807	if (hws) {808		hws->ctx = ctx;809		hws->regs = &hwseq_reg;810		hws->shifts = &hwseq_shift;811		hws->masks = &hwseq_mask;812	}813	return hws;814}815 816static struct dce_hwseq *dce121_hwseq_create(817	struct dc_context *ctx)818{819	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);820 821	if (hws) {822		hws->ctx = ctx;823		hws->regs = &dce121_hwseq_reg;824		hws->shifts = &dce121_hwseq_shift;825		hws->masks = &dce121_hwseq_mask;826	}827	return hws;828}829 830static const struct resource_create_funcs res_create_funcs = {831	.read_dce_straps = read_dce_straps,832	.create_audio = create_audio,833	.create_stream_encoder = dce120_stream_encoder_create,834	.create_hwseq = dce120_hwseq_create,835};836 837static const struct resource_create_funcs dce121_res_create_funcs = {838	.read_dce_straps = read_dce_straps,839	.create_audio = create_audio,840	.create_stream_encoder = dce120_stream_encoder_create,841	.create_hwseq = dce121_hwseq_create,842};843 844 845#define mi_inst_regs(id) { MI_DCE12_REG_LIST(id) }846static const struct dce_mem_input_registers mi_regs[] = {847		mi_inst_regs(0),848		mi_inst_regs(1),849		mi_inst_regs(2),850		mi_inst_regs(3),851		mi_inst_regs(4),852		mi_inst_regs(5),853};854 855static const struct dce_mem_input_shift mi_shifts = {856		MI_DCE12_MASK_SH_LIST(__SHIFT)857};858 859static const struct dce_mem_input_mask mi_masks = {860		MI_DCE12_MASK_SH_LIST(_MASK)861};862 863static struct mem_input *dce120_mem_input_create(864	struct dc_context *ctx,865	uint32_t inst)866{867	struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),868					       GFP_KERNEL);869 870	if (!dce_mi) {871		BREAK_TO_DEBUGGER();872		return NULL;873	}874 875	dce120_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);876	return &dce_mi->base;877}878 879static struct transform *dce120_transform_create(880	struct dc_context *ctx,881	uint32_t inst)882{883	struct dce_transform *transform =884		kzalloc(sizeof(struct dce_transform), GFP_KERNEL);885 886	if (!transform)887		return NULL;888 889	dce_transform_construct(transform, ctx, inst,890				&xfm_regs[inst], &xfm_shift, &xfm_mask);891	transform->lb_memory_size = 0x1404; /*5124*/892	return &transform->base;893}894 895static void dce120_destroy_resource_pool(struct resource_pool **pool)896{897	struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);898 899	dce120_resource_destruct(dce110_pool);900	kfree(dce110_pool);901	*pool = NULL;902}903 904static const struct resource_funcs dce120_res_pool_funcs = {905	.destroy = dce120_destroy_resource_pool,906	.link_enc_create = dce120_link_encoder_create,907	.panel_cntl_create = dce120_panel_cntl_create,908	.validate_bandwidth = dce112_validate_bandwidth,909	.validate_plane = dce100_validate_plane,910	.add_stream_to_ctx = dce112_add_stream_to_ctx,911	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link912};913 914static void bw_calcs_data_update_from_pplib(struct dc *dc)915{916	struct dm_pp_clock_levels_with_latency eng_clks = {0};917	struct dm_pp_clock_levels_with_latency mem_clks = {0};918	struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};919	int i;920	unsigned int clk;921	unsigned int latency;922	/*original logic in dal3*/923	int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;924 925	/*do system clock*/926	if (!dm_pp_get_clock_levels_by_type_with_latency(927				dc->ctx,928				DM_PP_CLOCK_TYPE_ENGINE_CLK,929				&eng_clks) || eng_clks.num_levels == 0) {930 931		eng_clks.num_levels = 8;932		clk = 300000;933 934		for (i = 0; i < eng_clks.num_levels; i++) {935			eng_clks.data[i].clocks_in_khz = clk;936			clk += 100000;937		}938	}939 940	/* convert all the clock fro kHz to fix point mHz  TODO: wloop data */941	dc->bw_vbios->high_sclk = bw_frc_to_fixed(942		eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);943	dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(944		eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);945	dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(946		eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);947	dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(948		eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);949	dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(950		eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);951	dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(952		eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);953	dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(954		eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);955	dc->bw_vbios->low_sclk  = bw_frc_to_fixed(956			eng_clks.data[0].clocks_in_khz, 1000);957 958	/*do memory clock*/959	if (!dm_pp_get_clock_levels_by_type_with_latency(960			dc->ctx,961			DM_PP_CLOCK_TYPE_MEMORY_CLK,962			&mem_clks) || mem_clks.num_levels == 0) {963 964		mem_clks.num_levels = 3;965		clk = 250000;966		latency = 45;967 968		for (i = 0; i < eng_clks.num_levels; i++) {969			mem_clks.data[i].clocks_in_khz = clk;970			mem_clks.data[i].latency_in_us = latency;971			clk += 500000;972			latency -= 5;973		}974 975	}976 977	/* we don't need to call PPLIB for validation clock since they978	 * also give us the highest sclk and highest mclk (UMA clock).979	 * ALSO always convert UMA clock (from PPLIB)  to YCLK (HW formula):980	 * YCLK = UMACLK*m_memoryTypeMultiplier981	 */982	if (dc->bw_vbios->memory_type == bw_def_hbm)983		memory_type_multiplier = MEMORY_TYPE_HBM;984 985	dc->bw_vbios->low_yclk = bw_frc_to_fixed(986		mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000);987	dc->bw_vbios->mid_yclk = bw_frc_to_fixed(988		mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier,989		1000);990	dc->bw_vbios->high_yclk = bw_frc_to_fixed(991		mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier,992		1000);993 994	/* Now notify PPLib/SMU about which Watermarks sets they should select995	 * depending on DPM state they are in. And update BW MGR GFX Engine and996	 * Memory clock member variables for Watermarks calculations for each997	 * Watermark Set998	 */999	clk_ranges.num_wm_sets = 4;1000	clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;1001	clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =1002			eng_clks.data[0].clocks_in_khz;1003	clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =1004			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;1005	clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz =1006			mem_clks.data[0].clocks_in_khz;1007	clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =1008			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;1009 1010	clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;1011	clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =1012			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;1013	/* 5 GHz instead of data[7].clockInKHz to cover Overdrive */1014	clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;1015	clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz =1016			mem_clks.data[0].clocks_in_khz;1017	clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =1018			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;1019 1020	clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;1021	clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =1022			eng_clks.data[0].clocks_in_khz;1023	clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =1024			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;1025	clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz =1026			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;1027	/* 5 GHz instead of data[2].clockInKHz to cover Overdrive */1028	clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;1029 1030	clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;1031	clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =1032			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;1033	/* 5 GHz instead of data[7].clockInKHz to cover Overdrive */1034	clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;1035	clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz =1036			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;1037	/* 5 GHz instead of data[2].clockInKHz to cover Overdrive */1038	clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;1039 1040	/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */1041	dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);1042}1043 1044static uint32_t read_pipe_fuses(struct dc_context *ctx)1045{1046	uint32_t value = dm_read_reg_soc15(ctx, mmCC_DC_PIPE_DIS, 0);1047	/* VG20 support max 6 pipes */1048	value = value & 0x3f;1049	return value;1050}1051 1052static bool dce120_resource_construct(1053	uint8_t num_virtual_links,1054	struct dc *dc,1055	struct dce110_resource_pool *pool)1056{1057	unsigned int i;1058	int j;1059	struct dc_context *ctx = dc->ctx;1060	struct irq_service_init_data irq_init_data;1061	static const struct resource_create_funcs *res_funcs;1062	bool is_vg20 = ASICREV_IS_VEGA20_P(ctx->asic_id.hw_internal_rev);1063	uint32_t pipe_fuses = 0;1064 1065	ctx->dc_bios->regs = &bios_regs;1066 1067	pool->base.res_cap = &res_cap;1068	pool->base.funcs = &dce120_res_pool_funcs;1069 1070	/* TODO: Fill more data from GreenlandAsicCapability.cpp */1071	pool->base.pipe_count = res_cap.num_timing_generator;1072	pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;1073	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;1074 1075	dc->caps.max_downscale_ratio = 200;1076	dc->caps.i2c_speed_in_khz = 100;1077	dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/1078	dc->caps.max_cursor_size = 128;1079	dc->caps.min_horizontal_blanking_period = 80;1080	dc->caps.dual_link_dvi = true;1081	dc->caps.psp_setup_panel_mode = true;1082	dc->caps.extended_aux_timeout_support = false;1083	dc->debug = debug_defaults;1084 1085	/*************************************************1086	 *  Create resources                             *1087	 *************************************************/1088 1089	pool->base.clock_sources[DCE120_CLK_SRC_PLL0] =1090			dce120_clock_source_create(ctx, ctx->dc_bios,1091				CLOCK_SOURCE_COMBO_PHY_PLL0,1092				&clk_src_regs[0], false);1093	pool->base.clock_sources[DCE120_CLK_SRC_PLL1] =1094			dce120_clock_source_create(ctx, ctx->dc_bios,1095				CLOCK_SOURCE_COMBO_PHY_PLL1,1096				&clk_src_regs[1], false);1097	pool->base.clock_sources[DCE120_CLK_SRC_PLL2] =1098			dce120_clock_source_create(ctx, ctx->dc_bios,1099				CLOCK_SOURCE_COMBO_PHY_PLL2,1100				&clk_src_regs[2], false);1101	pool->base.clock_sources[DCE120_CLK_SRC_PLL3] =1102			dce120_clock_source_create(ctx, ctx->dc_bios,1103				CLOCK_SOURCE_COMBO_PHY_PLL3,1104				&clk_src_regs[3], false);1105	pool->base.clock_sources[DCE120_CLK_SRC_PLL4] =1106			dce120_clock_source_create(ctx, ctx->dc_bios,1107				CLOCK_SOURCE_COMBO_PHY_PLL4,1108				&clk_src_regs[4], false);1109	pool->base.clock_sources[DCE120_CLK_SRC_PLL5] =1110			dce120_clock_source_create(ctx, ctx->dc_bios,1111				CLOCK_SOURCE_COMBO_PHY_PLL5,1112				&clk_src_regs[5], false);1113	pool->base.clk_src_count = DCE120_CLK_SRC_TOTAL;1114 1115	pool->base.dp_clock_source =1116			dce120_clock_source_create(ctx, ctx->dc_bios,1117				CLOCK_SOURCE_ID_DP_DTO,1118				&clk_src_regs[0], true);1119 1120	for (i = 0; i < pool->base.clk_src_count; i++) {1121		if (pool->base.clock_sources[i] == NULL) {1122			dm_error("DC: failed to create clock sources!\n");1123			BREAK_TO_DEBUGGER();1124			goto clk_src_create_fail;1125		}1126	}1127 1128	pool->base.dmcu = dce_dmcu_create(ctx,1129			&dmcu_regs,1130			&dmcu_shift,1131			&dmcu_mask);1132	if (pool->base.dmcu == NULL) {1133		dm_error("DC: failed to create dmcu!\n");1134		BREAK_TO_DEBUGGER();1135		goto res_create_fail;1136	}1137 1138	pool->base.abm = dce_abm_create(ctx,1139			&abm_regs,1140			&abm_shift,1141			&abm_mask);1142	if (pool->base.abm == NULL) {1143		dm_error("DC: failed to create abm!\n");1144		BREAK_TO_DEBUGGER();1145		goto res_create_fail;1146	}1147 1148 1149	irq_init_data.ctx = dc->ctx;1150	pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data);1151	if (!pool->base.irqs)1152		goto irqs_create_fail;1153 1154	/* VG20: Pipe harvesting enabled, retrieve valid pipe fuses */1155	if (is_vg20)1156		pipe_fuses = read_pipe_fuses(ctx);1157 1158	/* index to valid pipe resource */1159	j = 0;1160	for (i = 0; i < pool->base.pipe_count; i++) {1161		if (is_vg20) {1162			if ((pipe_fuses & (1 << i)) != 0) {1163				dm_error("DC: skip invalid pipe %d!\n", i);1164				continue;1165			}1166		}1167 1168		pool->base.timing_generators[j] =1169				dce120_timing_generator_create(1170					ctx,1171					i,1172					&dce120_tg_offsets[i]);1173		if (pool->base.timing_generators[j] == NULL) {1174			BREAK_TO_DEBUGGER();1175			dm_error("DC: failed to create tg!\n");1176			goto controller_create_fail;1177		}1178 1179		pool->base.mis[j] = dce120_mem_input_create(ctx, i);1180 1181		if (pool->base.mis[j] == NULL) {1182			BREAK_TO_DEBUGGER();1183			dm_error(1184				"DC: failed to create memory input!\n");1185			goto controller_create_fail;1186		}1187 1188		pool->base.ipps[j] = dce120_ipp_create(ctx, i);1189		if (pool->base.ipps[i] == NULL) {1190			BREAK_TO_DEBUGGER();1191			dm_error(1192				"DC: failed to create input pixel processor!\n");1193			goto controller_create_fail;1194		}1195 1196		pool->base.transforms[j] = dce120_transform_create(ctx, i);1197		if (pool->base.transforms[i] == NULL) {1198			BREAK_TO_DEBUGGER();1199			dm_error(1200				"DC: failed to create transform!\n");1201			goto res_create_fail;1202		}1203 1204		pool->base.opps[j] = dce120_opp_create(1205			ctx,1206			i);1207		if (pool->base.opps[j] == NULL) {1208			BREAK_TO_DEBUGGER();1209			dm_error(1210				"DC: failed to create output pixel processor!\n");1211		}1212 1213		/* check next valid pipe */1214		j++;1215	}1216 1217	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {1218		pool->base.engines[i] = dce120_aux_engine_create(ctx, i);1219		if (pool->base.engines[i] == NULL) {1220			BREAK_TO_DEBUGGER();1221			dm_error(1222				"DC:failed to create aux engine!!\n");1223			goto res_create_fail;1224		}1225		pool->base.hw_i2cs[i] = dce120_i2c_hw_create(ctx, i);1226		if (pool->base.hw_i2cs[i] == NULL) {1227			BREAK_TO_DEBUGGER();1228			dm_error(1229				"DC:failed to create i2c engine!!\n");1230			goto res_create_fail;1231		}1232		pool->base.sw_i2cs[i] = NULL;1233	}1234 1235	/* valid pipe num */1236	pool->base.pipe_count = j;1237	pool->base.timing_generator_count = j;1238 1239	if (is_vg20)1240		res_funcs = &dce121_res_create_funcs;1241	else1242		res_funcs = &res_create_funcs;1243 1244	if (!resource_construct(num_virtual_links, dc, &pool->base, res_funcs))1245		goto res_create_fail;1246 1247	/* Create hardware sequencer */1248	if (!dce120_hw_sequencer_create(dc))1249		goto controller_create_fail;1250 1251	dc->caps.max_planes =  pool->base.pipe_count;1252 1253	for (i = 0; i < dc->caps.max_planes; ++i)1254		dc->caps.planes[i] = plane_cap;1255 1256	bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);1257 1258	bw_calcs_data_update_from_pplib(dc);1259 1260	return true;1261 1262irqs_create_fail:1263controller_create_fail:1264clk_src_create_fail:1265res_create_fail:1266 1267	dce120_resource_destruct(pool);1268 1269	return false;1270}1271 1272struct resource_pool *dce120_create_resource_pool(1273	uint8_t num_virtual_links,1274	struct dc *dc)1275{1276	struct dce110_resource_pool *pool =1277		kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);1278 1279	if (!pool)1280		return NULL;1281 1282	if (dce120_resource_construct(num_virtual_links, dc, pool))1283		return &pool->base;1284 1285	kfree(pool);1286	BREAK_TO_DEBUGGER();1287	return NULL;1288}1289