cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dce110_resource.c (40768B)


      1/*
      2 * Copyright 2012-15 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include <linux/slab.h>
     27
     28#include "dm_services.h"
     29
     30#include "link_encoder.h"
     31#include "stream_encoder.h"
     32
     33#include "resource.h"
     34#include "dce110/dce110_resource.h"
     35#include "include/irq_service_interface.h"
     36#include "dce/dce_audio.h"
     37#include "dce110/dce110_timing_generator.h"
     38#include "irq/dce110/irq_service_dce110.h"
     39#include "dce110/dce110_timing_generator_v.h"
     40#include "dce/dce_link_encoder.h"
     41#include "dce/dce_stream_encoder.h"
     42#include "dce/dce_mem_input.h"
     43#include "dce110/dce110_mem_input_v.h"
     44#include "dce/dce_ipp.h"
     45#include "dce/dce_transform.h"
     46#include "dce110/dce110_transform_v.h"
     47#include "dce/dce_opp.h"
     48#include "dce110/dce110_opp_v.h"
     49#include "dce/dce_clock_source.h"
     50#include "dce/dce_hwseq.h"
     51#include "dce110/dce110_hw_sequencer.h"
     52#include "dce/dce_aux.h"
     53#include "dce/dce_abm.h"
     54#include "dce/dce_dmcu.h"
     55#include "dce/dce_i2c.h"
     56#include "dce/dce_panel_cntl.h"
     57
     58#define DC_LOGGER \
     59		dc->ctx->logger
     60
     61#include "dce110/dce110_compressor.h"
     62
     63#include "reg_helper.h"
     64
     65#include "dce/dce_11_0_d.h"
     66#include "dce/dce_11_0_sh_mask.h"
     67
     68#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
     69#include "gmc/gmc_8_2_d.h"
     70#include "gmc/gmc_8_2_sh_mask.h"
     71#endif
     72
     73#ifndef mmDP_DPHY_INTERNAL_CTRL
     74	#define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
     75	#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
     76	#define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
     77	#define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
     78	#define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
     79	#define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
     80	#define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
     81	#define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
     82	#define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
     83	#define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
     84#endif
     85
     86#ifndef mmBIOS_SCRATCH_2
     87	#define mmBIOS_SCRATCH_2 0x05CB
     88	#define mmBIOS_SCRATCH_3 0x05CC
     89	#define mmBIOS_SCRATCH_6 0x05CF
     90#endif
     91
     92#ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
     93	#define mmDP_DPHY_BS_SR_SWAP_CNTL                       0x4ADC
     94	#define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL                   0x4ADC
     95	#define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL                   0x4BDC
     96	#define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL                   0x4CDC
     97	#define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL                   0x4DDC
     98	#define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL                   0x4EDC
     99	#define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL                   0x4FDC
    100	#define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL                   0x54DC
    101#endif
    102
    103#ifndef mmDP_DPHY_FAST_TRAINING
    104	#define mmDP_DPHY_FAST_TRAINING                         0x4ABC
    105	#define mmDP0_DP_DPHY_FAST_TRAINING                     0x4ABC
    106	#define mmDP1_DP_DPHY_FAST_TRAINING                     0x4BBC
    107	#define mmDP2_DP_DPHY_FAST_TRAINING                     0x4CBC
    108	#define mmDP3_DP_DPHY_FAST_TRAINING                     0x4DBC
    109	#define mmDP4_DP_DPHY_FAST_TRAINING                     0x4EBC
    110	#define mmDP5_DP_DPHY_FAST_TRAINING                     0x4FBC
    111	#define mmDP6_DP_DPHY_FAST_TRAINING                     0x54BC
    112#endif
    113
    114#ifndef DPHY_RX_FAST_TRAINING_CAPABLE
    115	#define DPHY_RX_FAST_TRAINING_CAPABLE 0x1
    116#endif
    117
    118static const struct dce110_timing_generator_offsets dce110_tg_offsets[] = {
    119	{
    120		.crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
    121		.dcp =  (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
    122	},
    123	{
    124		.crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
    125		.dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
    126	},
    127	{
    128		.crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
    129		.dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
    130	},
    131	{
    132		.crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
    133		.dcp =  (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
    134	},
    135	{
    136		.crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
    137		.dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
    138	},
    139	{
    140		.crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
    141		.dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
    142	}
    143};
    144
    145/* set register offset */
    146#define SR(reg_name)\
    147	.reg_name = mm ## reg_name
    148
    149/* set register offset with instance */
    150#define SRI(reg_name, block, id)\
    151	.reg_name = mm ## block ## id ## _ ## reg_name
    152
    153static const struct dce_dmcu_registers dmcu_regs = {
    154		DMCU_DCE110_COMMON_REG_LIST()
    155};
    156
    157static const struct dce_dmcu_shift dmcu_shift = {
    158		DMCU_MASK_SH_LIST_DCE110(__SHIFT)
    159};
    160
    161static const struct dce_dmcu_mask dmcu_mask = {
    162		DMCU_MASK_SH_LIST_DCE110(_MASK)
    163};
    164
    165static const struct dce_abm_registers abm_regs = {
    166		ABM_DCE110_COMMON_REG_LIST()
    167};
    168
    169static const struct dce_abm_shift abm_shift = {
    170		ABM_MASK_SH_LIST_DCE110(__SHIFT)
    171};
    172
    173static const struct dce_abm_mask abm_mask = {
    174		ABM_MASK_SH_LIST_DCE110(_MASK)
    175};
    176
    177#define ipp_regs(id)\
    178[id] = {\
    179		IPP_DCE110_REG_LIST_DCE_BASE(id)\
    180}
    181
    182static const struct dce_ipp_registers ipp_regs[] = {
    183		ipp_regs(0),
    184		ipp_regs(1),
    185		ipp_regs(2)
    186};
    187
    188static const struct dce_ipp_shift ipp_shift = {
    189		IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
    190};
    191
    192static const struct dce_ipp_mask ipp_mask = {
    193		IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
    194};
    195
    196#define transform_regs(id)\
    197[id] = {\
    198		XFM_COMMON_REG_LIST_DCE110(id)\
    199}
    200
    201static const struct dce_transform_registers xfm_regs[] = {
    202		transform_regs(0),
    203		transform_regs(1),
    204		transform_regs(2)
    205};
    206
    207static const struct dce_transform_shift xfm_shift = {
    208		XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
    209};
    210
    211static const struct dce_transform_mask xfm_mask = {
    212		XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
    213};
    214
    215#define aux_regs(id)\
    216[id] = {\
    217	AUX_REG_LIST(id)\
    218}
    219
    220static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
    221		aux_regs(0),
    222		aux_regs(1),
    223		aux_regs(2),
    224		aux_regs(3),
    225		aux_regs(4),
    226		aux_regs(5)
    227};
    228
    229#define hpd_regs(id)\
    230[id] = {\
    231	HPD_REG_LIST(id)\
    232}
    233
    234static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
    235		hpd_regs(0),
    236		hpd_regs(1),
    237		hpd_regs(2),
    238		hpd_regs(3),
    239		hpd_regs(4),
    240		hpd_regs(5)
    241};
    242
    243
    244#define link_regs(id)\
    245[id] = {\
    246	LE_DCE110_REG_LIST(id)\
    247}
    248
    249static const struct dce110_link_enc_registers link_enc_regs[] = {
    250	link_regs(0),
    251	link_regs(1),
    252	link_regs(2),
    253	link_regs(3),
    254	link_regs(4),
    255	link_regs(5),
    256	link_regs(6),
    257};
    258
    259#define stream_enc_regs(id)\
    260[id] = {\
    261	SE_COMMON_REG_LIST(id),\
    262	.TMDS_CNTL = 0,\
    263}
    264
    265static const struct dce110_stream_enc_registers stream_enc_regs[] = {
    266	stream_enc_regs(0),
    267	stream_enc_regs(1),
    268	stream_enc_regs(2)
    269};
    270
    271static const struct dce_stream_encoder_shift se_shift = {
    272		SE_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
    273};
    274
    275static const struct dce_stream_encoder_mask se_mask = {
    276		SE_COMMON_MASK_SH_LIST_DCE110(_MASK)
    277};
    278
    279static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
    280	{ DCE_PANEL_CNTL_REG_LIST() }
    281};
    282
    283static const struct dce_panel_cntl_shift panel_cntl_shift = {
    284	DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
    285};
    286
    287static const struct dce_panel_cntl_mask panel_cntl_mask = {
    288	DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
    289};
    290
    291static const struct dce110_aux_registers_shift aux_shift = {
    292	DCE_AUX_MASK_SH_LIST(__SHIFT)
    293};
    294
    295static const struct dce110_aux_registers_mask aux_mask = {
    296	DCE_AUX_MASK_SH_LIST(_MASK)
    297};
    298
    299#define opp_regs(id)\
    300[id] = {\
    301	OPP_DCE_110_REG_LIST(id),\
    302}
    303
    304static const struct dce_opp_registers opp_regs[] = {
    305	opp_regs(0),
    306	opp_regs(1),
    307	opp_regs(2),
    308	opp_regs(3),
    309	opp_regs(4),
    310	opp_regs(5)
    311};
    312
    313static const struct dce_opp_shift opp_shift = {
    314	OPP_COMMON_MASK_SH_LIST_DCE_110(__SHIFT)
    315};
    316
    317static const struct dce_opp_mask opp_mask = {
    318	OPP_COMMON_MASK_SH_LIST_DCE_110(_MASK)
    319};
    320
    321#define aux_engine_regs(id)\
    322[id] = {\
    323	AUX_COMMON_REG_LIST(id), \
    324	.AUX_RESET_MASK = 0 \
    325}
    326
    327static const struct dce110_aux_registers aux_engine_regs[] = {
    328		aux_engine_regs(0),
    329		aux_engine_regs(1),
    330		aux_engine_regs(2),
    331		aux_engine_regs(3),
    332		aux_engine_regs(4),
    333		aux_engine_regs(5)
    334};
    335
    336#define audio_regs(id)\
    337[id] = {\
    338	AUD_COMMON_REG_LIST(id)\
    339}
    340
    341static const struct dce_audio_registers audio_regs[] = {
    342	audio_regs(0),
    343	audio_regs(1),
    344	audio_regs(2),
    345	audio_regs(3),
    346	audio_regs(4),
    347	audio_regs(5),
    348	audio_regs(6),
    349};
    350
    351static const struct dce_audio_shift audio_shift = {
    352		AUD_COMMON_MASK_SH_LIST(__SHIFT)
    353};
    354
    355static const struct dce_audio_mask audio_mask = {
    356		AUD_COMMON_MASK_SH_LIST(_MASK)
    357};
    358
    359/* AG TBD Needs to be reduced back to 3 pipes once dce10 hw sequencer implemented. */
    360
    361
    362#define clk_src_regs(id)\
    363[id] = {\
    364	CS_COMMON_REG_LIST_DCE_100_110(id),\
    365}
    366
    367static const struct dce110_clk_src_regs clk_src_regs[] = {
    368	clk_src_regs(0),
    369	clk_src_regs(1),
    370	clk_src_regs(2)
    371};
    372
    373static const struct dce110_clk_src_shift cs_shift = {
    374		CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
    375};
    376
    377static const struct dce110_clk_src_mask cs_mask = {
    378		CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
    379};
    380
    381static const struct bios_registers bios_regs = {
    382	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
    383	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
    384};
    385
    386static const struct resource_caps carrizo_resource_cap = {
    387		.num_timing_generator = 3,
    388		.num_video_plane = 1,
    389		.num_audio = 3,
    390		.num_stream_encoder = 3,
    391		.num_pll = 2,
    392		.num_ddc = 3,
    393};
    394
    395static const struct resource_caps stoney_resource_cap = {
    396		.num_timing_generator = 2,
    397		.num_video_plane = 1,
    398		.num_audio = 3,
    399		.num_stream_encoder = 3,
    400		.num_pll = 2,
    401		.num_ddc = 3,
    402};
    403
    404static const struct dc_plane_cap plane_cap = {
    405		.type = DC_PLANE_TYPE_DCE_RGB,
    406		.blends_with_below = true,
    407		.blends_with_above = true,
    408		.per_pixel_alpha = 1,
    409
    410		.pixel_format_support = {
    411				.argb8888 = true,
    412				.nv12 = false,
    413				.fp16 = true
    414		},
    415
    416		.max_upscale_factor = {
    417				.argb8888 = 16000,
    418				.nv12 = 1,
    419				.fp16 = 1
    420		},
    421
    422		.max_downscale_factor = {
    423				.argb8888 = 250,
    424				.nv12 = 1,
    425				.fp16 = 1
    426		},
    427		64,
    428		64
    429};
    430
    431static const struct dc_plane_cap underlay_plane_cap = {
    432		.type = DC_PLANE_TYPE_DCE_UNDERLAY,
    433		.blends_with_above = true,
    434		.per_pixel_alpha = 1,
    435
    436		.pixel_format_support = {
    437				.argb8888 = false,
    438				.nv12 = true,
    439				.fp16 = false
    440		},
    441
    442		.max_upscale_factor = {
    443				.argb8888 = 1,
    444				.nv12 = 16000,
    445				.fp16 = 1
    446		},
    447
    448		.max_downscale_factor = {
    449				.argb8888 = 1,
    450				.nv12 = 250,
    451				.fp16 = 1
    452		},
    453		64,
    454		64
    455};
    456
    457#define CTX  ctx
    458#define REG(reg) mm ## reg
    459
    460#ifndef mmCC_DC_HDMI_STRAPS
    461#define mmCC_DC_HDMI_STRAPS 0x4819
    462#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
    463#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
    464#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
    465#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
    466#endif
    467
    468static int map_transmitter_id_to_phy_instance(
    469	enum transmitter transmitter)
    470{
    471	switch (transmitter) {
    472	case TRANSMITTER_UNIPHY_A:
    473		return 0;
    474	case TRANSMITTER_UNIPHY_B:
    475		return 1;
    476	case TRANSMITTER_UNIPHY_C:
    477		return 2;
    478	case TRANSMITTER_UNIPHY_D:
    479		return 3;
    480	case TRANSMITTER_UNIPHY_E:
    481		return 4;
    482	case TRANSMITTER_UNIPHY_F:
    483		return 5;
    484	case TRANSMITTER_UNIPHY_G:
    485		return 6;
    486	default:
    487		ASSERT(0);
    488		return 0;
    489	}
    490}
    491
    492static void read_dce_straps(
    493	struct dc_context *ctx,
    494	struct resource_straps *straps)
    495{
    496	REG_GET_2(CC_DC_HDMI_STRAPS,
    497			HDMI_DISABLE, &straps->hdmi_disable,
    498			AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
    499
    500	REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
    501}
    502
    503static struct audio *create_audio(
    504		struct dc_context *ctx, unsigned int inst)
    505{
    506	return dce_audio_create(ctx, inst,
    507			&audio_regs[inst], &audio_shift, &audio_mask);
    508}
    509
    510static struct timing_generator *dce110_timing_generator_create(
    511		struct dc_context *ctx,
    512		uint32_t instance,
    513		const struct dce110_timing_generator_offsets *offsets)
    514{
    515	struct dce110_timing_generator *tg110 =
    516		kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
    517
    518	if (!tg110)
    519		return NULL;
    520
    521	dce110_timing_generator_construct(tg110, ctx, instance, offsets);
    522	return &tg110->base;
    523}
    524
    525static struct stream_encoder *dce110_stream_encoder_create(
    526	enum engine_id eng_id,
    527	struct dc_context *ctx)
    528{
    529	struct dce110_stream_encoder *enc110 =
    530		kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
    531
    532	if (!enc110)
    533		return NULL;
    534
    535	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
    536					&stream_enc_regs[eng_id],
    537					&se_shift, &se_mask);
    538	return &enc110->base;
    539}
    540
    541#define SRII(reg_name, block, id)\
    542	.reg_name[id] = mm ## block ## id ## _ ## reg_name
    543
    544static const struct dce_hwseq_registers hwseq_stoney_reg = {
    545		HWSEQ_ST_REG_LIST()
    546};
    547
    548static const struct dce_hwseq_registers hwseq_cz_reg = {
    549		HWSEQ_CZ_REG_LIST()
    550};
    551
    552static const struct dce_hwseq_shift hwseq_shift = {
    553		HWSEQ_DCE11_MASK_SH_LIST(__SHIFT),
    554};
    555
    556static const struct dce_hwseq_mask hwseq_mask = {
    557		HWSEQ_DCE11_MASK_SH_LIST(_MASK),
    558};
    559
    560static struct dce_hwseq *dce110_hwseq_create(
    561	struct dc_context *ctx)
    562{
    563	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
    564
    565	if (hws) {
    566		hws->ctx = ctx;
    567		hws->regs = ASIC_REV_IS_STONEY(ctx->asic_id.hw_internal_rev) ?
    568				&hwseq_stoney_reg : &hwseq_cz_reg;
    569		hws->shifts = &hwseq_shift;
    570		hws->masks = &hwseq_mask;
    571		hws->wa.blnd_crtc_trigger = true;
    572	}
    573	return hws;
    574}
    575
    576static const struct resource_create_funcs res_create_funcs = {
    577	.read_dce_straps = read_dce_straps,
    578	.create_audio = create_audio,
    579	.create_stream_encoder = dce110_stream_encoder_create,
    580	.create_hwseq = dce110_hwseq_create,
    581};
    582
    583#define mi_inst_regs(id) { \
    584	MI_DCE11_REG_LIST(id), \
    585	.MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
    586}
    587static const struct dce_mem_input_registers mi_regs[] = {
    588		mi_inst_regs(0),
    589		mi_inst_regs(1),
    590		mi_inst_regs(2),
    591};
    592
    593static const struct dce_mem_input_shift mi_shifts = {
    594		MI_DCE11_MASK_SH_LIST(__SHIFT),
    595		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
    596};
    597
    598static const struct dce_mem_input_mask mi_masks = {
    599		MI_DCE11_MASK_SH_LIST(_MASK),
    600		.ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
    601};
    602
    603
    604static struct mem_input *dce110_mem_input_create(
    605	struct dc_context *ctx,
    606	uint32_t inst)
    607{
    608	struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
    609					       GFP_KERNEL);
    610
    611	if (!dce_mi) {
    612		BREAK_TO_DEBUGGER();
    613		return NULL;
    614	}
    615
    616	dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
    617	dce_mi->wa.single_head_rdreq_dmif_limit = 3;
    618	return &dce_mi->base;
    619}
    620
    621static void dce110_transform_destroy(struct transform **xfm)
    622{
    623	kfree(TO_DCE_TRANSFORM(*xfm));
    624	*xfm = NULL;
    625}
    626
    627static struct transform *dce110_transform_create(
    628	struct dc_context *ctx,
    629	uint32_t inst)
    630{
    631	struct dce_transform *transform =
    632		kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
    633
    634	if (!transform)
    635		return NULL;
    636
    637	dce_transform_construct(transform, ctx, inst,
    638				&xfm_regs[inst], &xfm_shift, &xfm_mask);
    639	return &transform->base;
    640}
    641
    642static struct input_pixel_processor *dce110_ipp_create(
    643	struct dc_context *ctx, uint32_t inst)
    644{
    645	struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
    646
    647	if (!ipp) {
    648		BREAK_TO_DEBUGGER();
    649		return NULL;
    650	}
    651
    652	dce_ipp_construct(ipp, ctx, inst,
    653			&ipp_regs[inst], &ipp_shift, &ipp_mask);
    654	return &ipp->base;
    655}
    656
    657static const struct encoder_feature_support link_enc_feature = {
    658		.max_hdmi_deep_color = COLOR_DEPTH_121212,
    659		.max_hdmi_pixel_clock = 300000,
    660		.flags.bits.IS_HBR2_CAPABLE = true,
    661		.flags.bits.IS_TPS3_CAPABLE = true
    662};
    663
    664static struct link_encoder *dce110_link_encoder_create(
    665	const struct encoder_init_data *enc_init_data)
    666{
    667	struct dce110_link_encoder *enc110 =
    668		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
    669	int link_regs_id;
    670
    671	if (!enc110)
    672		return NULL;
    673
    674	link_regs_id =
    675		map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
    676
    677	dce110_link_encoder_construct(enc110,
    678				      enc_init_data,
    679				      &link_enc_feature,
    680				      &link_enc_regs[link_regs_id],
    681				      &link_enc_aux_regs[enc_init_data->channel - 1],
    682				      &link_enc_hpd_regs[enc_init_data->hpd_source]);
    683	return &enc110->base;
    684}
    685
    686static struct panel_cntl *dce110_panel_cntl_create(const struct panel_cntl_init_data *init_data)
    687{
    688	struct dce_panel_cntl *panel_cntl =
    689		kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
    690
    691	if (!panel_cntl)
    692		return NULL;
    693
    694	dce_panel_cntl_construct(panel_cntl,
    695			init_data,
    696			&panel_cntl_regs[init_data->inst],
    697			&panel_cntl_shift,
    698			&panel_cntl_mask);
    699
    700	return &panel_cntl->base;
    701}
    702
    703static struct output_pixel_processor *dce110_opp_create(
    704	struct dc_context *ctx,
    705	uint32_t inst)
    706{
    707	struct dce110_opp *opp =
    708		kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
    709
    710	if (!opp)
    711		return NULL;
    712
    713	dce110_opp_construct(opp,
    714			     ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
    715	return &opp->base;
    716}
    717
    718static struct dce_aux *dce110_aux_engine_create(
    719	struct dc_context *ctx,
    720	uint32_t inst)
    721{
    722	struct aux_engine_dce110 *aux_engine =
    723		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
    724
    725	if (!aux_engine)
    726		return NULL;
    727
    728	dce110_aux_engine_construct(aux_engine, ctx, inst,
    729				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
    730				    &aux_engine_regs[inst],
    731					&aux_mask,
    732					&aux_shift,
    733					ctx->dc->caps.extended_aux_timeout_support);
    734
    735	return &aux_engine->base;
    736}
    737#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
    738
    739static const struct dce_i2c_registers i2c_hw_regs[] = {
    740		i2c_inst_regs(1),
    741		i2c_inst_regs(2),
    742		i2c_inst_regs(3),
    743		i2c_inst_regs(4),
    744		i2c_inst_regs(5),
    745		i2c_inst_regs(6),
    746};
    747
    748static const struct dce_i2c_shift i2c_shifts = {
    749		I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
    750};
    751
    752static const struct dce_i2c_mask i2c_masks = {
    753		I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
    754};
    755
    756static struct dce_i2c_hw *dce110_i2c_hw_create(
    757	struct dc_context *ctx,
    758	uint32_t inst)
    759{
    760	struct dce_i2c_hw *dce_i2c_hw =
    761		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
    762
    763	if (!dce_i2c_hw)
    764		return NULL;
    765
    766	dce100_i2c_hw_construct(dce_i2c_hw, ctx, inst,
    767				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
    768
    769	return dce_i2c_hw;
    770}
    771static struct clock_source *dce110_clock_source_create(
    772	struct dc_context *ctx,
    773	struct dc_bios *bios,
    774	enum clock_source_id id,
    775	const struct dce110_clk_src_regs *regs,
    776	bool dp_clk_src)
    777{
    778	struct dce110_clk_src *clk_src =
    779		kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
    780
    781	if (!clk_src)
    782		return NULL;
    783
    784	if (dce110_clk_src_construct(clk_src, ctx, bios, id,
    785			regs, &cs_shift, &cs_mask)) {
    786		clk_src->base.dp_clk_src = dp_clk_src;
    787		return &clk_src->base;
    788	}
    789
    790	kfree(clk_src);
    791	BREAK_TO_DEBUGGER();
    792	return NULL;
    793}
    794
    795static void dce110_clock_source_destroy(struct clock_source **clk_src)
    796{
    797	struct dce110_clk_src *dce110_clk_src;
    798
    799	if (!clk_src)
    800		return;
    801
    802	dce110_clk_src = TO_DCE110_CLK_SRC(*clk_src);
    803
    804	kfree(dce110_clk_src->dp_ss_params);
    805	kfree(dce110_clk_src->hdmi_ss_params);
    806	kfree(dce110_clk_src->dvi_ss_params);
    807
    808	kfree(dce110_clk_src);
    809	*clk_src = NULL;
    810}
    811
    812static void dce110_resource_destruct(struct dce110_resource_pool *pool)
    813{
    814	unsigned int i;
    815
    816	for (i = 0; i < pool->base.pipe_count; i++) {
    817		if (pool->base.opps[i] != NULL)
    818			dce110_opp_destroy(&pool->base.opps[i]);
    819
    820		if (pool->base.transforms[i] != NULL)
    821			dce110_transform_destroy(&pool->base.transforms[i]);
    822
    823		if (pool->base.ipps[i] != NULL)
    824			dce_ipp_destroy(&pool->base.ipps[i]);
    825
    826		if (pool->base.mis[i] != NULL) {
    827			kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
    828			pool->base.mis[i] = NULL;
    829		}
    830
    831		if (pool->base.timing_generators[i] != NULL)	{
    832			kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
    833			pool->base.timing_generators[i] = NULL;
    834		}
    835	}
    836
    837	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
    838		if (pool->base.engines[i] != NULL)
    839			dce110_engine_destroy(&pool->base.engines[i]);
    840		if (pool->base.hw_i2cs[i] != NULL) {
    841			kfree(pool->base.hw_i2cs[i]);
    842			pool->base.hw_i2cs[i] = NULL;
    843		}
    844		if (pool->base.sw_i2cs[i] != NULL) {
    845			kfree(pool->base.sw_i2cs[i]);
    846			pool->base.sw_i2cs[i] = NULL;
    847		}
    848	}
    849
    850	for (i = 0; i < pool->base.stream_enc_count; i++) {
    851		if (pool->base.stream_enc[i] != NULL)
    852			kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
    853	}
    854
    855	for (i = 0; i < pool->base.clk_src_count; i++) {
    856		if (pool->base.clock_sources[i] != NULL) {
    857			dce110_clock_source_destroy(&pool->base.clock_sources[i]);
    858		}
    859	}
    860
    861	if (pool->base.dp_clock_source != NULL)
    862		dce110_clock_source_destroy(&pool->base.dp_clock_source);
    863
    864	for (i = 0; i < pool->base.audio_count; i++)	{
    865		if (pool->base.audios[i] != NULL) {
    866			dce_aud_destroy(&pool->base.audios[i]);
    867		}
    868	}
    869
    870	if (pool->base.abm != NULL)
    871		dce_abm_destroy(&pool->base.abm);
    872
    873	if (pool->base.dmcu != NULL)
    874		dce_dmcu_destroy(&pool->base.dmcu);
    875
    876	if (pool->base.irqs != NULL) {
    877		dal_irq_service_destroy(&pool->base.irqs);
    878	}
    879}
    880
    881
    882static void get_pixel_clock_parameters(
    883	const struct pipe_ctx *pipe_ctx,
    884	struct pixel_clk_params *pixel_clk_params)
    885{
    886	const struct dc_stream_state *stream = pipe_ctx->stream;
    887
    888	/*TODO: is this halved for YCbCr 420? in that case we might want to move
    889	 * the pixel clock normalization for hdmi up to here instead of doing it
    890	 * in pll_adjust_pix_clk
    891	 */
    892	pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
    893	pixel_clk_params->encoder_object_id = stream->link->link_enc->id;
    894	pixel_clk_params->signal_type = pipe_ctx->stream->signal;
    895	pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
    896	/* TODO: un-hardcode*/
    897	pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
    898						LINK_RATE_REF_FREQ_IN_KHZ;
    899	pixel_clk_params->flags.ENABLE_SS = 0;
    900	pixel_clk_params->color_depth =
    901		stream->timing.display_color_depth;
    902	pixel_clk_params->flags.DISPLAY_BLANKED = 1;
    903	pixel_clk_params->flags.SUPPORT_YCBCR420 = (stream->timing.pixel_encoding ==
    904			PIXEL_ENCODING_YCBCR420);
    905	pixel_clk_params->pixel_encoding = stream->timing.pixel_encoding;
    906	if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) {
    907		pixel_clk_params->color_depth = COLOR_DEPTH_888;
    908	}
    909	if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
    910		pixel_clk_params->requested_pix_clk_100hz  = pixel_clk_params->requested_pix_clk_100hz / 2;
    911	}
    912	if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
    913		pixel_clk_params->requested_pix_clk_100hz *= 2;
    914
    915}
    916
    917void dce110_resource_build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
    918{
    919	get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->stream_res.pix_clk_params);
    920	pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
    921		pipe_ctx->clock_source,
    922		&pipe_ctx->stream_res.pix_clk_params,
    923		&pipe_ctx->pll_settings);
    924	resource_build_bit_depth_reduction_params(pipe_ctx->stream,
    925			&pipe_ctx->stream->bit_depth_params);
    926	pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->timing.pixel_encoding;
    927}
    928
    929static bool is_surface_pixel_format_supported(struct pipe_ctx *pipe_ctx, unsigned int underlay_idx)
    930{
    931	if (pipe_ctx->pipe_idx != underlay_idx)
    932		return true;
    933	if (!pipe_ctx->plane_state)
    934		return false;
    935	if (pipe_ctx->plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
    936		return false;
    937	return true;
    938}
    939
    940static enum dc_status build_mapped_resource(
    941		const struct dc *dc,
    942		struct dc_state *context,
    943		struct dc_stream_state *stream)
    944{
    945	struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
    946
    947	if (!pipe_ctx)
    948		return DC_ERROR_UNEXPECTED;
    949
    950	if (!is_surface_pixel_format_supported(pipe_ctx,
    951			dc->res_pool->underlay_pipe_index))
    952		return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED;
    953
    954	dce110_resource_build_pipe_hw_param(pipe_ctx);
    955
    956	/* TODO: validate audio ASIC caps, encoder */
    957
    958	resource_build_info_frame(pipe_ctx);
    959
    960	return DC_OK;
    961}
    962
    963static bool dce110_validate_bandwidth(
    964	struct dc *dc,
    965	struct dc_state *context,
    966	bool fast_validate)
    967{
    968	bool result = false;
    969
    970	DC_LOG_BANDWIDTH_CALCS(
    971		"%s: start",
    972		__func__);
    973
    974	if (bw_calcs(
    975			dc->ctx,
    976			dc->bw_dceip,
    977			dc->bw_vbios,
    978			context->res_ctx.pipe_ctx,
    979			dc->res_pool->pipe_count,
    980			&context->bw_ctx.bw.dce))
    981		result =  true;
    982
    983	if (!result)
    984		DC_LOG_BANDWIDTH_VALIDATION("%s: %dx%d@%d Bandwidth validation failed!\n",
    985			__func__,
    986			context->streams[0]->timing.h_addressable,
    987			context->streams[0]->timing.v_addressable,
    988			context->streams[0]->timing.pix_clk_100hz / 10);
    989
    990	if (memcmp(&dc->current_state->bw_ctx.bw.dce,
    991			&context->bw_ctx.bw.dce, sizeof(context->bw_ctx.bw.dce))) {
    992
    993		DC_LOG_BANDWIDTH_CALCS(
    994			"%s: finish,\n"
    995			"nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
    996			"stutMark_b: %d stutMark_a: %d\n"
    997			"nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
    998			"stutMark_b: %d stutMark_a: %d\n"
    999			"nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
   1000			"stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n"
   1001			"cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n"
   1002			"sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n"
   1003			,
   1004			__func__,
   1005			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].b_mark,
   1006			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].a_mark,
   1007			context->bw_ctx.bw.dce.urgent_wm_ns[0].b_mark,
   1008			context->bw_ctx.bw.dce.urgent_wm_ns[0].a_mark,
   1009			context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].b_mark,
   1010			context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].a_mark,
   1011			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].b_mark,
   1012			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].a_mark,
   1013			context->bw_ctx.bw.dce.urgent_wm_ns[1].b_mark,
   1014			context->bw_ctx.bw.dce.urgent_wm_ns[1].a_mark,
   1015			context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].b_mark,
   1016			context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].a_mark,
   1017			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].b_mark,
   1018			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].a_mark,
   1019			context->bw_ctx.bw.dce.urgent_wm_ns[2].b_mark,
   1020			context->bw_ctx.bw.dce.urgent_wm_ns[2].a_mark,
   1021			context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].b_mark,
   1022			context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].a_mark,
   1023			context->bw_ctx.bw.dce.stutter_mode_enable,
   1024			context->bw_ctx.bw.dce.cpuc_state_change_enable,
   1025			context->bw_ctx.bw.dce.cpup_state_change_enable,
   1026			context->bw_ctx.bw.dce.nbp_state_change_enable,
   1027			context->bw_ctx.bw.dce.all_displays_in_sync,
   1028			context->bw_ctx.bw.dce.dispclk_khz,
   1029			context->bw_ctx.bw.dce.sclk_khz,
   1030			context->bw_ctx.bw.dce.sclk_deep_sleep_khz,
   1031			context->bw_ctx.bw.dce.yclk_khz,
   1032			context->bw_ctx.bw.dce.blackout_recovery_time_us);
   1033	}
   1034	return result;
   1035}
   1036
   1037static enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state,
   1038					    struct dc_caps *caps)
   1039{
   1040	if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) ||
   1041	    ((plane_state->dst_rect.height * 2) < plane_state->src_rect.height))
   1042		return DC_FAIL_SURFACE_VALIDATE;
   1043
   1044	return DC_OK;
   1045}
   1046
   1047static bool dce110_validate_surface_sets(
   1048		struct dc_state *context)
   1049{
   1050	int i, j;
   1051
   1052	for (i = 0; i < context->stream_count; i++) {
   1053		if (context->stream_status[i].plane_count == 0)
   1054			continue;
   1055
   1056		if (context->stream_status[i].plane_count > 2)
   1057			return false;
   1058
   1059		for (j = 0; j < context->stream_status[i].plane_count; j++) {
   1060			struct dc_plane_state *plane =
   1061				context->stream_status[i].plane_states[j];
   1062
   1063			/* underlay validation */
   1064			if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
   1065
   1066				if ((plane->src_rect.width > 1920 ||
   1067					plane->src_rect.height > 1080))
   1068					return false;
   1069
   1070				/* we don't have the logic to support underlay
   1071				 * only yet so block the use case where we get
   1072				 * NV12 plane as top layer
   1073				 */
   1074				if (j == 0)
   1075					return false;
   1076
   1077				/* irrespective of plane format,
   1078				 * stream should be RGB encoded
   1079				 */
   1080				if (context->streams[i]->timing.pixel_encoding
   1081						!= PIXEL_ENCODING_RGB)
   1082					return false;
   1083
   1084			}
   1085
   1086		}
   1087	}
   1088
   1089	return true;
   1090}
   1091
   1092static enum dc_status dce110_validate_global(
   1093		struct dc *dc,
   1094		struct dc_state *context)
   1095{
   1096	if (!dce110_validate_surface_sets(context))
   1097		return DC_FAIL_SURFACE_VALIDATE;
   1098
   1099	return DC_OK;
   1100}
   1101
   1102static enum dc_status dce110_add_stream_to_ctx(
   1103		struct dc *dc,
   1104		struct dc_state *new_ctx,
   1105		struct dc_stream_state *dc_stream)
   1106{
   1107	enum dc_status result = DC_ERROR_UNEXPECTED;
   1108
   1109	result = resource_map_pool_resources(dc, new_ctx, dc_stream);
   1110
   1111	if (result == DC_OK)
   1112		result = resource_map_clock_resources(dc, new_ctx, dc_stream);
   1113
   1114
   1115	if (result == DC_OK)
   1116		result = build_mapped_resource(dc, new_ctx, dc_stream);
   1117
   1118	return result;
   1119}
   1120
   1121static struct pipe_ctx *dce110_acquire_underlay(
   1122		struct dc_state *context,
   1123		const struct resource_pool *pool,
   1124		struct dc_stream_state *stream)
   1125{
   1126	struct dc *dc = stream->ctx->dc;
   1127	struct dce_hwseq *hws = dc->hwseq;
   1128	struct resource_context *res_ctx = &context->res_ctx;
   1129	unsigned int underlay_idx = pool->underlay_pipe_index;
   1130	struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[underlay_idx];
   1131
   1132	if (res_ctx->pipe_ctx[underlay_idx].stream)
   1133		return NULL;
   1134
   1135	pipe_ctx->stream_res.tg = pool->timing_generators[underlay_idx];
   1136	pipe_ctx->plane_res.mi = pool->mis[underlay_idx];
   1137	/*pipe_ctx->plane_res.ipp = res_ctx->pool->ipps[underlay_idx];*/
   1138	pipe_ctx->plane_res.xfm = pool->transforms[underlay_idx];
   1139	pipe_ctx->stream_res.opp = pool->opps[underlay_idx];
   1140	pipe_ctx->pipe_idx = underlay_idx;
   1141
   1142	pipe_ctx->stream = stream;
   1143
   1144	if (!dc->current_state->res_ctx.pipe_ctx[underlay_idx].stream) {
   1145		struct tg_color black_color = {0};
   1146		struct dc_bios *dcb = dc->ctx->dc_bios;
   1147
   1148		hws->funcs.enable_display_power_gating(
   1149				dc,
   1150				pipe_ctx->stream_res.tg->inst,
   1151				dcb, PIPE_GATING_CONTROL_DISABLE);
   1152
   1153		/*
   1154		 * This is for powering on underlay, so crtc does not
   1155		 * need to be enabled
   1156		 */
   1157
   1158		pipe_ctx->stream_res.tg->funcs->program_timing(pipe_ctx->stream_res.tg,
   1159				&stream->timing,
   1160				0,
   1161				0,
   1162				0,
   1163				0,
   1164				pipe_ctx->stream->signal,
   1165				false);
   1166
   1167		pipe_ctx->stream_res.tg->funcs->enable_advanced_request(
   1168				pipe_ctx->stream_res.tg,
   1169				true,
   1170				&stream->timing);
   1171
   1172		pipe_ctx->plane_res.mi->funcs->allocate_mem_input(pipe_ctx->plane_res.mi,
   1173				stream->timing.h_total,
   1174				stream->timing.v_total,
   1175				stream->timing.pix_clk_100hz / 10,
   1176				context->stream_count);
   1177
   1178		color_space_to_black_color(dc,
   1179				COLOR_SPACE_YCBCR601, &black_color);
   1180		pipe_ctx->stream_res.tg->funcs->set_blank_color(
   1181				pipe_ctx->stream_res.tg,
   1182				&black_color);
   1183	}
   1184
   1185	return pipe_ctx;
   1186}
   1187
   1188static void dce110_destroy_resource_pool(struct resource_pool **pool)
   1189{
   1190	struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
   1191
   1192	dce110_resource_destruct(dce110_pool);
   1193	kfree(dce110_pool);
   1194	*pool = NULL;
   1195}
   1196
   1197struct stream_encoder *dce110_find_first_free_match_stream_enc_for_link(
   1198		struct resource_context *res_ctx,
   1199		const struct resource_pool *pool,
   1200		struct dc_stream_state *stream)
   1201{
   1202	int i;
   1203	int j = -1;
   1204	struct dc_link *link = stream->link;
   1205
   1206	for (i = 0; i < pool->stream_enc_count; i++) {
   1207		if (!res_ctx->is_stream_enc_acquired[i] &&
   1208				pool->stream_enc[i]) {
   1209			/* Store first available for MST second display
   1210			 * in daisy chain use case
   1211			 */
   1212			j = i;
   1213			if (pool->stream_enc[i]->id ==
   1214					link->link_enc->preferred_engine)
   1215				return pool->stream_enc[i];
   1216		}
   1217	}
   1218
   1219	/*
   1220	 * For CZ and later, we can allow DIG FE and BE to differ for all display types
   1221	 */
   1222
   1223	if (j >= 0)
   1224		return pool->stream_enc[j];
   1225
   1226	return NULL;
   1227}
   1228
   1229
   1230static const struct resource_funcs dce110_res_pool_funcs = {
   1231	.destroy = dce110_destroy_resource_pool,
   1232	.link_enc_create = dce110_link_encoder_create,
   1233	.panel_cntl_create = dce110_panel_cntl_create,
   1234	.validate_bandwidth = dce110_validate_bandwidth,
   1235	.validate_plane = dce110_validate_plane,
   1236	.acquire_idle_pipe_for_layer = dce110_acquire_underlay,
   1237	.add_stream_to_ctx = dce110_add_stream_to_ctx,
   1238	.validate_global = dce110_validate_global,
   1239	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
   1240};
   1241
   1242static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool)
   1243{
   1244	struct dce110_timing_generator *dce110_tgv = kzalloc(sizeof(*dce110_tgv),
   1245							     GFP_KERNEL);
   1246	struct dce_transform *dce110_xfmv = kzalloc(sizeof(*dce110_xfmv),
   1247						    GFP_KERNEL);
   1248	struct dce_mem_input *dce110_miv = kzalloc(sizeof(*dce110_miv),
   1249						   GFP_KERNEL);
   1250	struct dce110_opp *dce110_oppv = kzalloc(sizeof(*dce110_oppv),
   1251						 GFP_KERNEL);
   1252
   1253	if (!dce110_tgv || !dce110_xfmv || !dce110_miv || !dce110_oppv) {
   1254		kfree(dce110_tgv);
   1255		kfree(dce110_xfmv);
   1256		kfree(dce110_miv);
   1257		kfree(dce110_oppv);
   1258		return false;
   1259	}
   1260
   1261	dce110_opp_v_construct(dce110_oppv, ctx);
   1262
   1263	dce110_timing_generator_v_construct(dce110_tgv, ctx);
   1264	dce110_mem_input_v_construct(dce110_miv, ctx);
   1265	dce110_transform_v_construct(dce110_xfmv, ctx);
   1266
   1267	pool->opps[pool->pipe_count] = &dce110_oppv->base;
   1268	pool->timing_generators[pool->pipe_count] = &dce110_tgv->base;
   1269	pool->mis[pool->pipe_count] = &dce110_miv->base;
   1270	pool->transforms[pool->pipe_count] = &dce110_xfmv->base;
   1271	pool->pipe_count++;
   1272
   1273	/* update the public caps to indicate an underlay is available */
   1274	ctx->dc->caps.max_slave_planes = 1;
   1275	ctx->dc->caps.max_slave_yuv_planes = 1;
   1276	ctx->dc->caps.max_slave_rgb_planes = 0;
   1277
   1278	return true;
   1279}
   1280
   1281static void bw_calcs_data_update_from_pplib(struct dc *dc)
   1282{
   1283	struct dm_pp_clock_levels clks = {0};
   1284
   1285	/*do system clock*/
   1286	dm_pp_get_clock_levels_by_type(
   1287			dc->ctx,
   1288			DM_PP_CLOCK_TYPE_ENGINE_CLK,
   1289			&clks);
   1290	/* convert all the clock fro kHz to fix point mHz */
   1291	dc->bw_vbios->high_sclk = bw_frc_to_fixed(
   1292			clks.clocks_in_khz[clks.num_levels-1], 1000);
   1293	dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
   1294			clks.clocks_in_khz[clks.num_levels/8], 1000);
   1295	dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
   1296			clks.clocks_in_khz[clks.num_levels*2/8], 1000);
   1297	dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
   1298			clks.clocks_in_khz[clks.num_levels*3/8], 1000);
   1299	dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
   1300			clks.clocks_in_khz[clks.num_levels*4/8], 1000);
   1301	dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
   1302			clks.clocks_in_khz[clks.num_levels*5/8], 1000);
   1303	dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
   1304			clks.clocks_in_khz[clks.num_levels*6/8], 1000);
   1305	dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
   1306			clks.clocks_in_khz[0], 1000);
   1307	dc->sclk_lvls = clks;
   1308
   1309	/*do display clock*/
   1310	dm_pp_get_clock_levels_by_type(
   1311			dc->ctx,
   1312			DM_PP_CLOCK_TYPE_DISPLAY_CLK,
   1313			&clks);
   1314	dc->bw_vbios->high_voltage_max_dispclk = bw_frc_to_fixed(
   1315			clks.clocks_in_khz[clks.num_levels-1], 1000);
   1316	dc->bw_vbios->mid_voltage_max_dispclk  = bw_frc_to_fixed(
   1317			clks.clocks_in_khz[clks.num_levels>>1], 1000);
   1318	dc->bw_vbios->low_voltage_max_dispclk  = bw_frc_to_fixed(
   1319			clks.clocks_in_khz[0], 1000);
   1320
   1321	/*do memory clock*/
   1322	dm_pp_get_clock_levels_by_type(
   1323			dc->ctx,
   1324			DM_PP_CLOCK_TYPE_MEMORY_CLK,
   1325			&clks);
   1326
   1327	dc->bw_vbios->low_yclk = bw_frc_to_fixed(
   1328		clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER_CZ, 1000);
   1329	dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
   1330		clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER_CZ,
   1331		1000);
   1332	dc->bw_vbios->high_yclk = bw_frc_to_fixed(
   1333		clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER_CZ,
   1334		1000);
   1335}
   1336
   1337static const struct resource_caps *dce110_resource_cap(
   1338	struct hw_asic_id *asic_id)
   1339{
   1340	if (ASIC_REV_IS_STONEY(asic_id->hw_internal_rev))
   1341		return &stoney_resource_cap;
   1342	else
   1343		return &carrizo_resource_cap;
   1344}
   1345
   1346static bool dce110_resource_construct(
   1347	uint8_t num_virtual_links,
   1348	struct dc *dc,
   1349	struct dce110_resource_pool *pool,
   1350	struct hw_asic_id asic_id)
   1351{
   1352	unsigned int i;
   1353	struct dc_context *ctx = dc->ctx;
   1354	struct dc_bios *bp;
   1355
   1356	ctx->dc_bios->regs = &bios_regs;
   1357
   1358	pool->base.res_cap = dce110_resource_cap(&ctx->asic_id);
   1359	pool->base.funcs = &dce110_res_pool_funcs;
   1360
   1361	/*************************************************
   1362	 *  Resource + asic cap harcoding                *
   1363	 *************************************************/
   1364
   1365	pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
   1366	pool->base.underlay_pipe_index = pool->base.pipe_count;
   1367	pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
   1368	dc->caps.max_downscale_ratio = 150;
   1369	dc->caps.i2c_speed_in_khz = 40;
   1370	dc->caps.i2c_speed_in_khz_hdcp = 40;
   1371	dc->caps.max_cursor_size = 128;
   1372	dc->caps.min_horizontal_blanking_period = 80;
   1373	dc->caps.is_apu = true;
   1374	dc->caps.extended_aux_timeout_support = false;
   1375
   1376	/*************************************************
   1377	 *  Create resources                             *
   1378	 *************************************************/
   1379
   1380	bp = ctx->dc_bios;
   1381
   1382	if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
   1383		pool->base.dp_clock_source =
   1384				dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
   1385
   1386		pool->base.clock_sources[0] =
   1387				dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0,
   1388						&clk_src_regs[0], false);
   1389		pool->base.clock_sources[1] =
   1390				dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1,
   1391						&clk_src_regs[1], false);
   1392
   1393		pool->base.clk_src_count = 2;
   1394
   1395		/* TODO: find out if CZ support 3 PLLs */
   1396	}
   1397
   1398	if (pool->base.dp_clock_source == NULL) {
   1399		dm_error("DC: failed to create dp clock source!\n");
   1400		BREAK_TO_DEBUGGER();
   1401		goto res_create_fail;
   1402	}
   1403
   1404	for (i = 0; i < pool->base.clk_src_count; i++) {
   1405		if (pool->base.clock_sources[i] == NULL) {
   1406			dm_error("DC: failed to create clock sources!\n");
   1407			BREAK_TO_DEBUGGER();
   1408			goto res_create_fail;
   1409		}
   1410	}
   1411
   1412	pool->base.dmcu = dce_dmcu_create(ctx,
   1413			&dmcu_regs,
   1414			&dmcu_shift,
   1415			&dmcu_mask);
   1416	if (pool->base.dmcu == NULL) {
   1417		dm_error("DC: failed to create dmcu!\n");
   1418		BREAK_TO_DEBUGGER();
   1419		goto res_create_fail;
   1420	}
   1421
   1422	pool->base.abm = dce_abm_create(ctx,
   1423			&abm_regs,
   1424			&abm_shift,
   1425			&abm_mask);
   1426	if (pool->base.abm == NULL) {
   1427		dm_error("DC: failed to create abm!\n");
   1428		BREAK_TO_DEBUGGER();
   1429		goto res_create_fail;
   1430	}
   1431
   1432	{
   1433		struct irq_service_init_data init_data;
   1434		init_data.ctx = dc->ctx;
   1435		pool->base.irqs = dal_irq_service_dce110_create(&init_data);
   1436		if (!pool->base.irqs)
   1437			goto res_create_fail;
   1438	}
   1439
   1440	for (i = 0; i < pool->base.pipe_count; i++) {
   1441		pool->base.timing_generators[i] = dce110_timing_generator_create(
   1442				ctx, i, &dce110_tg_offsets[i]);
   1443		if (pool->base.timing_generators[i] == NULL) {
   1444			BREAK_TO_DEBUGGER();
   1445			dm_error("DC: failed to create tg!\n");
   1446			goto res_create_fail;
   1447		}
   1448
   1449		pool->base.mis[i] = dce110_mem_input_create(ctx, i);
   1450		if (pool->base.mis[i] == NULL) {
   1451			BREAK_TO_DEBUGGER();
   1452			dm_error(
   1453				"DC: failed to create memory input!\n");
   1454			goto res_create_fail;
   1455		}
   1456
   1457		pool->base.ipps[i] = dce110_ipp_create(ctx, i);
   1458		if (pool->base.ipps[i] == NULL) {
   1459			BREAK_TO_DEBUGGER();
   1460			dm_error(
   1461				"DC: failed to create input pixel processor!\n");
   1462			goto res_create_fail;
   1463		}
   1464
   1465		pool->base.transforms[i] = dce110_transform_create(ctx, i);
   1466		if (pool->base.transforms[i] == NULL) {
   1467			BREAK_TO_DEBUGGER();
   1468			dm_error(
   1469				"DC: failed to create transform!\n");
   1470			goto res_create_fail;
   1471		}
   1472
   1473		pool->base.opps[i] = dce110_opp_create(ctx, i);
   1474		if (pool->base.opps[i] == NULL) {
   1475			BREAK_TO_DEBUGGER();
   1476			dm_error(
   1477				"DC: failed to create output pixel processor!\n");
   1478			goto res_create_fail;
   1479		}
   1480	}
   1481
   1482	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
   1483		pool->base.engines[i] = dce110_aux_engine_create(ctx, i);
   1484		if (pool->base.engines[i] == NULL) {
   1485			BREAK_TO_DEBUGGER();
   1486			dm_error(
   1487				"DC:failed to create aux engine!!\n");
   1488			goto res_create_fail;
   1489		}
   1490		pool->base.hw_i2cs[i] = dce110_i2c_hw_create(ctx, i);
   1491		if (pool->base.hw_i2cs[i] == NULL) {
   1492			BREAK_TO_DEBUGGER();
   1493			dm_error(
   1494				"DC:failed to create i2c engine!!\n");
   1495			goto res_create_fail;
   1496		}
   1497		pool->base.sw_i2cs[i] = NULL;
   1498	}
   1499
   1500	if (dc->config.fbc_support)
   1501		dc->fbc_compressor = dce110_compressor_create(ctx);
   1502
   1503	if (!underlay_create(ctx, &pool->base))
   1504		goto res_create_fail;
   1505
   1506	if (!resource_construct(num_virtual_links, dc, &pool->base,
   1507			&res_create_funcs))
   1508		goto res_create_fail;
   1509
   1510	/* Create hardware sequencer */
   1511	dce110_hw_sequencer_construct(dc);
   1512
   1513	dc->caps.max_planes =  pool->base.pipe_count;
   1514
   1515	for (i = 0; i < pool->base.underlay_pipe_index; ++i)
   1516		dc->caps.planes[i] = plane_cap;
   1517
   1518	dc->caps.planes[pool->base.underlay_pipe_index] = underlay_plane_cap;
   1519
   1520	bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
   1521
   1522	bw_calcs_data_update_from_pplib(dc);
   1523
   1524	return true;
   1525
   1526res_create_fail:
   1527	dce110_resource_destruct(pool);
   1528	return false;
   1529}
   1530
   1531struct resource_pool *dce110_create_resource_pool(
   1532	uint8_t num_virtual_links,
   1533	struct dc *dc,
   1534	struct hw_asic_id asic_id)
   1535{
   1536	struct dce110_resource_pool *pool =
   1537		kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
   1538
   1539	if (!pool)
   1540		return NULL;
   1541
   1542	if (dce110_resource_construct(num_virtual_links, dc, pool, asic_id))
   1543		return &pool->base;
   1544
   1545	kfree(pool);
   1546	BREAK_TO_DEBUGGER();
   1547	return NULL;
   1548}