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