1 /*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.cls
3 *
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Authors: AMD
24  *
25  */
26 
27 #include "dm_services.h"
28 
29 
30 #include "stream_encoder.h"
31 #include "resource.h"
32 #include "include/irq_service_interface.h"
33 #include "dce120_resource.h"
34 #include "dce112/dce112_resource.h"
35 
36 #include "dce110/dce110_resource.h"
37 #include "../virtual/virtual_stream_encoder.h"
38 #include "dce120_timing_generator.h"
39 #include "irq/dce120/irq_service_dce120.h"
40 #include "dce/dce_opp.h"
41 #include "dce/dce_clock_source.h"
42 #include "dce/dce_clocks.h"
43 #include "dce120_ipp.h"
44 #include "dce110/dce110_mem_input.h"
45 #include "dce120/dce120_mem_input.h"
46 
47 #include "dce110/dce110_hw_sequencer.h"
48 #include "dce120/dce120_hw_sequencer.h"
49 #include "dce/dce_transform.h"
50 
51 #include "dce/dce_audio.h"
52 #include "dce/dce_link_encoder.h"
53 #include "dce/dce_stream_encoder.h"
54 #include "dce/dce_hwseq.h"
55 #include "dce/dce_abm.h"
56 #include "dce/dce_dmcu.h"
57 
58 #include "vega10/DC/dce_12_0_offset.h"
59 #include "vega10/DC/dce_12_0_sh_mask.h"
60 #include "vega10/soc15ip.h"
61 #include "vega10/NBIO/nbio_6_1_offset.h"
62 #include "reg_helper.h"
63 
64 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
65 	#define mmDP0_DP_DPHY_INTERNAL_CTRL		0x210f
66 	#define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
67 	#define mmDP1_DP_DPHY_INTERNAL_CTRL		0x220f
68 	#define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
69 	#define mmDP2_DP_DPHY_INTERNAL_CTRL		0x230f
70 	#define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
71 	#define mmDP3_DP_DPHY_INTERNAL_CTRL		0x240f
72 	#define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
73 	#define mmDP4_DP_DPHY_INTERNAL_CTRL		0x250f
74 	#define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
75 	#define mmDP5_DP_DPHY_INTERNAL_CTRL		0x260f
76 	#define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
77 	#define mmDP6_DP_DPHY_INTERNAL_CTRL		0x270f
78 	#define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
79 #endif
80 
81 enum dce120_clk_src_array_id {
82 	DCE120_CLK_SRC_PLL0,
83 	DCE120_CLK_SRC_PLL1,
84 	DCE120_CLK_SRC_PLL2,
85 	DCE120_CLK_SRC_PLL3,
86 	DCE120_CLK_SRC_PLL4,
87 	DCE120_CLK_SRC_PLL5,
88 
89 	DCE120_CLK_SRC_TOTAL
90 };
91 
92 static const struct dce110_timing_generator_offsets dce120_tg_offsets[] = {
93 	{
94 		.crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
95 	},
96 	{
97 		.crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
98 	},
99 	{
100 		.crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
101 	},
102 	{
103 		.crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
104 	},
105 	{
106 		.crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
107 	},
108 	{
109 		.crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
110 	}
111 };
112 
113 /* begin *********************
114  * macros to expend register list macro defined in HW object header file */
115 
116 #define BASE_INNER(seg) \
117 	DCE_BASE__INST0_SEG ## seg
118 
119 #define NBIO_BASE_INNER(seg) \
120 	NBIF_BASE__INST0_SEG ## seg
121 
122 #define NBIO_BASE(seg) \
123 	NBIO_BASE_INNER(seg)
124 
125 /* compile time expand base address. */
126 #define BASE(seg) \
127 	BASE_INNER(seg)
128 
129 #define SR(reg_name)\
130 		.reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \
131 					mm ## reg_name
132 
133 #define SRI(reg_name, block, id)\
134 	.reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
135 					mm ## block ## id ## _ ## reg_name
136 
137 /* macros to expend register list macro defined in HW object header file
138  * end *********************/
139 
140 
141 static const struct dce_disp_clk_registers disp_clk_regs = {
142 		CLK_COMMON_REG_LIST_DCE_BASE()
143 };
144 
145 static const struct dce_disp_clk_shift disp_clk_shift = {
146 		CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
147 };
148 
149 static const struct dce_disp_clk_mask disp_clk_mask = {
150 		CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
151 };
152 
153 static const struct dce_dmcu_registers dmcu_regs = {
154 		DMCU_DCE110_COMMON_REG_LIST()
155 };
156 
157 static const struct dce_dmcu_shift dmcu_shift = {
158 		DMCU_MASK_SH_LIST_DCE110(__SHIFT)
159 };
160 
161 static const struct dce_dmcu_mask dmcu_mask = {
162 		DMCU_MASK_SH_LIST_DCE110(_MASK)
163 };
164 
165 static const struct dce_abm_registers abm_regs = {
166 		ABM_DCE110_COMMON_REG_LIST()
167 };
168 
169 static const struct dce_abm_shift abm_shift = {
170 		ABM_MASK_SH_LIST_DCE110(__SHIFT)
171 };
172 
173 static const struct dce_abm_mask abm_mask = {
174 		ABM_MASK_SH_LIST_DCE110(_MASK)
175 };
176 
177 #define transform_regs(id)\
178 [id] = {\
179 		XFM_COMMON_REG_LIST_DCE110(id)\
180 }
181 
182 static const struct dce_transform_registers xfm_regs[] = {
183 		transform_regs(0),
184 		transform_regs(1),
185 		transform_regs(2),
186 		transform_regs(3),
187 		transform_regs(4),
188 		transform_regs(5)
189 };
190 
191 static const struct dce_transform_shift xfm_shift = {
192 		XFM_COMMON_MASK_SH_LIST_SOC_BASE(__SHIFT)
193 };
194 
195 static const struct dce_transform_mask xfm_mask = {
196 		XFM_COMMON_MASK_SH_LIST_SOC_BASE(_MASK)
197 };
198 
199 #define aux_regs(id)\
200 [id] = {\
201 	AUX_REG_LIST(id)\
202 }
203 
204 static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
205 		aux_regs(0),
206 		aux_regs(1),
207 		aux_regs(2),
208 		aux_regs(3),
209 		aux_regs(4),
210 		aux_regs(5)
211 };
212 
213 #define hpd_regs(id)\
214 [id] = {\
215 	HPD_REG_LIST(id)\
216 }
217 
218 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
219 		hpd_regs(0),
220 		hpd_regs(1),
221 		hpd_regs(2),
222 		hpd_regs(3),
223 		hpd_regs(4),
224 		hpd_regs(5)
225 };
226 
227 #define link_regs(id)\
228 [id] = {\
229 	LE_DCE120_REG_LIST(id), \
230 	SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
231 }
232 
233 static const struct dce110_link_enc_registers link_enc_regs[] = {
234 	link_regs(0),
235 	link_regs(1),
236 	link_regs(2),
237 	link_regs(3),
238 	link_regs(4),
239 	link_regs(5),
240 	link_regs(6),
241 };
242 
243 
244 #define stream_enc_regs(id)\
245 [id] = {\
246 	SE_COMMON_REG_LIST(id),\
247 	.TMDS_CNTL = 0,\
248 }
249 
250 static const struct dce110_stream_enc_registers stream_enc_regs[] = {
251 	stream_enc_regs(0),
252 	stream_enc_regs(1),
253 	stream_enc_regs(2),
254 	stream_enc_regs(3),
255 	stream_enc_regs(4),
256 	stream_enc_regs(5)
257 };
258 
259 static const struct dce_stream_encoder_shift se_shift = {
260 		SE_COMMON_MASK_SH_LIST_DCE120(__SHIFT)
261 };
262 
263 static const struct dce_stream_encoder_mask se_mask = {
264 		SE_COMMON_MASK_SH_LIST_DCE120(_MASK)
265 };
266 
267 #define opp_regs(id)\
268 [id] = {\
269 	OPP_DCE_120_REG_LIST(id),\
270 }
271 
272 static const struct dce_opp_registers opp_regs[] = {
273 	opp_regs(0),
274 	opp_regs(1),
275 	opp_regs(2),
276 	opp_regs(3),
277 	opp_regs(4),
278 	opp_regs(5)
279 };
280 
281 static const struct dce_opp_shift opp_shift = {
282 	OPP_COMMON_MASK_SH_LIST_DCE_120(__SHIFT)
283 };
284 
285 static const struct dce_opp_mask opp_mask = {
286 	OPP_COMMON_MASK_SH_LIST_DCE_120(_MASK)
287 };
288 
289 #define audio_regs(id)\
290 [id] = {\
291 	AUD_COMMON_REG_LIST(id)\
292 }
293 
294 static struct dce_audio_registers audio_regs[] = {
295 	audio_regs(0),
296 	audio_regs(1),
297 	audio_regs(2),
298 	audio_regs(3),
299 	audio_regs(4),
300 	audio_regs(5)
301 };
302 
303 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
304 		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
305 		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
306 		AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
307 
308 static const struct dce_audio_shift audio_shift = {
309 		DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
310 };
311 
312 static const struct dce_aduio_mask audio_mask = {
313 		DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
314 };
315 
316 #define clk_src_regs(index, id)\
317 [index] = {\
318 	CS_COMMON_REG_LIST_DCE_112(id),\
319 }
320 
321 static const struct dce110_clk_src_regs clk_src_regs[] = {
322 	clk_src_regs(0, A),
323 	clk_src_regs(1, B),
324 	clk_src_regs(2, C),
325 	clk_src_regs(3, D),
326 	clk_src_regs(4, E),
327 	clk_src_regs(5, F)
328 };
329 
330 static const struct dce110_clk_src_shift cs_shift = {
331 		CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
332 };
333 
334 static const struct dce110_clk_src_mask cs_mask = {
335 		CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)
336 };
337 
338 struct output_pixel_processor *dce120_opp_create(
339 	struct dc_context *ctx,
340 	uint32_t inst)
341 {
342 	struct dce110_opp *opp =
343 		dm_alloc(sizeof(struct dce110_opp));
344 
345 	if (!opp)
346 		return NULL;
347 
348 	if (dce110_opp_construct(opp,
349 			ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask))
350 		return &opp->base;
351 
352 	BREAK_TO_DEBUGGER();
353 	dm_free(opp);
354 	return NULL;
355 }
356 
357 static const struct dce110_ipp_reg_offsets dce120_ipp_reg_offsets[] = {
358 	{
359 		.dcp_offset = (mmDCP0_CUR_CONTROL - mmDCP0_CUR_CONTROL),
360 	},
361 	{
362 		.dcp_offset = (mmDCP1_CUR_CONTROL - mmDCP0_CUR_CONTROL),
363 	},
364 	{
365 		.dcp_offset = (mmDCP2_CUR_CONTROL - mmDCP0_CUR_CONTROL),
366 	},
367 	{
368 		.dcp_offset = (mmDCP3_CUR_CONTROL - mmDCP0_CUR_CONTROL),
369 	},
370 	{
371 		.dcp_offset = (mmDCP4_CUR_CONTROL - mmDCP0_CUR_CONTROL),
372 	},
373 	{
374 		.dcp_offset = (mmDCP5_CUR_CONTROL - mmDCP0_CUR_CONTROL),
375 	}
376 };
377 
378 static const struct dce110_mem_input_reg_offsets dce120_mi_reg_offsets[] = {
379 	{
380 		.dcp = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
381 		.dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL
382 				- mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
383 		.pipe = (mmPIPE0_DMIF_BUFFER_CONTROL
384 				- mmPIPE0_DMIF_BUFFER_CONTROL),
385 	},
386 	{
387 		.dcp = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
388 		.dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
389 				- mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
390 		.pipe = (mmPIPE1_DMIF_BUFFER_CONTROL
391 				- mmPIPE0_DMIF_BUFFER_CONTROL),
392 	},
393 	{
394 		.dcp = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
395 		.dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
396 				- mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
397 		.pipe = (mmPIPE2_DMIF_BUFFER_CONTROL
398 				- mmPIPE0_DMIF_BUFFER_CONTROL),
399 	},
400 	{
401 		.dcp = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
402 		.dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL
403 				- mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
404 		.pipe = (mmPIPE3_DMIF_BUFFER_CONTROL
405 				- mmPIPE0_DMIF_BUFFER_CONTROL),
406 	},
407 	{
408 		.dcp = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
409 		.dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL
410 				- mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
411 		.pipe = (mmPIPE4_DMIF_BUFFER_CONTROL
412 				- mmPIPE0_DMIF_BUFFER_CONTROL),
413 	},
414 	{
415 		.dcp = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
416 		.dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL
417 				- mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
418 		.pipe = (mmPIPE5_DMIF_BUFFER_CONTROL
419 				- mmPIPE0_DMIF_BUFFER_CONTROL),
420 	}
421 };
422 
423 static const struct bios_registers bios_regs = {
424 	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX)
425 };
426 
427 static const struct resource_caps res_cap = {
428 		.num_timing_generator = 3,
429 		.num_audio = 7,
430 		.num_stream_encoder = 6,
431 		.num_pll = 6,
432 };
433 
434 static const struct dc_debug debug_defaults = {
435 		.disable_clock_gate = true,
436 };
437 
438 struct clock_source *dce120_clock_source_create(
439 	struct dc_context *ctx,
440 	struct dc_bios *bios,
441 	enum clock_source_id id,
442 	const struct dce110_clk_src_regs *regs,
443 	bool dp_clk_src)
444 {
445 	struct dce110_clk_src *clk_src =
446 		dm_alloc(sizeof(struct dce110_clk_src));
447 
448 	if (!clk_src)
449 		return NULL;
450 
451 	if (dce110_clk_src_construct(clk_src, ctx, bios, id,
452 			regs, &cs_shift, &cs_mask)) {
453 		clk_src->base.dp_clk_src = dp_clk_src;
454 		return &clk_src->base;
455 	}
456 
457 	BREAK_TO_DEBUGGER();
458 	return NULL;
459 }
460 
461 void dce120_clock_source_destroy(struct clock_source **clk_src)
462 {
463 	dm_free(TO_DCE110_CLK_SRC(*clk_src));
464 	*clk_src = NULL;
465 }
466 
467 
468 bool dce120_hw_sequencer_create(struct core_dc *dc)
469 {
470 	/* All registers used by dce11.2 match those in dce11 in offset and
471 	 * structure
472 	 */
473 	dce120_hw_sequencer_construct(dc);
474 
475 	/*TODO	Move to separate file and Override what is needed */
476 
477 	return true;
478 }
479 
480 static struct timing_generator *dce120_timing_generator_create(
481 		struct dc_context *ctx,
482 		uint32_t instance,
483 		const struct dce110_timing_generator_offsets *offsets)
484 {
485 	struct dce110_timing_generator *tg110 =
486 		dm_alloc(sizeof(struct dce110_timing_generator));
487 
488 	if (!tg110)
489 		return NULL;
490 
491 	if (dce120_timing_generator_construct(tg110, ctx, instance, offsets))
492 		return &tg110->base;
493 
494 	BREAK_TO_DEBUGGER();
495 	dm_free(tg110);
496 	return NULL;
497 }
498 
499 static void dce120_ipp_destroy(struct input_pixel_processor **ipp)
500 {
501 	dm_free(TO_DCE110_IPP(*ipp));
502 	*ipp = NULL;
503 }
504 
505 static void dce120_transform_destroy(struct transform **xfm)
506 {
507 	dm_free(TO_DCE_TRANSFORM(*xfm));
508 	*xfm = NULL;
509 }
510 
511 static void destruct(struct dce110_resource_pool *pool)
512 {
513 	unsigned int i;
514 
515 	for (i = 0; i < pool->base.pipe_count; i++) {
516 		if (pool->base.opps[i] != NULL)
517 			dce110_opp_destroy(&pool->base.opps[i]);
518 
519 		if (pool->base.transforms[i] != NULL)
520 			dce120_transform_destroy(&pool->base.transforms[i]);
521 
522 		if (pool->base.ipps[i] != NULL)
523 			dce120_ipp_destroy(&pool->base.ipps[i]);
524 
525 		if (pool->base.mis[i] != NULL) {
526 			dm_free(TO_DCE110_MEM_INPUT(pool->base.mis[i]));
527 			pool->base.mis[i] = NULL;
528 		}
529 
530 		if (pool->base.irqs != NULL) {
531 			dal_irq_service_destroy(&pool->base.irqs);
532 		}
533 
534 		if (pool->base.timing_generators[i] != NULL) {
535 			dm_free(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
536 			pool->base.timing_generators[i] = NULL;
537 		}
538 	}
539 
540 	for (i = 0; i < pool->base.audio_count; i++) {
541 		if (pool->base.audios[i])
542 			dce_aud_destroy(&pool->base.audios[i]);
543 	}
544 
545 	for (i = 0; i < pool->base.stream_enc_count; i++) {
546 		if (pool->base.stream_enc[i] != NULL)
547 			dm_free(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
548 	}
549 
550 	for (i = 0; i < pool->base.clk_src_count; i++) {
551 		if (pool->base.clock_sources[i] != NULL)
552 			dce120_clock_source_destroy(
553 				&pool->base.clock_sources[i]);
554 	}
555 
556 	if (pool->base.dp_clock_source != NULL)
557 		dce120_clock_source_destroy(&pool->base.dp_clock_source);
558 
559 	if (pool->base.abm != NULL)
560 		dce_abm_destroy(&pool->base.abm);
561 
562 	if (pool->base.dmcu != NULL)
563 		dce_dmcu_destroy(&pool->base.dmcu);
564 
565 	if (pool->base.display_clock != NULL)
566 		dce_disp_clk_destroy(&pool->base.display_clock);
567 }
568 
569 static void read_dce_straps(
570 	struct dc_context *ctx,
571 	struct resource_straps *straps)
572 {
573 	/* TODO: Registers are missing */
574 	/*REG_GET_2(CC_DC_HDMI_STRAPS,
575 			HDMI_DISABLE, &straps->hdmi_disable,
576 			AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
577 
578 	REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);*/
579 }
580 
581 static struct audio *create_audio(
582 		struct dc_context *ctx, unsigned int inst)
583 {
584 	return dce_audio_create(ctx, inst,
585 			&audio_regs[inst], &audio_shift, &audio_mask);
586 }
587 
588 static const struct encoder_feature_support link_enc_feature = {
589 		.max_hdmi_deep_color = COLOR_DEPTH_121212,
590 		.max_hdmi_pixel_clock = 600000,
591 		.ycbcr420_supported = true,
592 		.flags.bits.IS_HBR2_CAPABLE = true,
593 		.flags.bits.IS_HBR3_CAPABLE = true,
594 		.flags.bits.IS_TPS3_CAPABLE = true,
595 		.flags.bits.IS_TPS4_CAPABLE = true,
596 		.flags.bits.IS_YCBCR_CAPABLE = true
597 };
598 
599 struct link_encoder *dce120_link_encoder_create(
600 	const struct encoder_init_data *enc_init_data)
601 {
602 	struct dce110_link_encoder *enc110 =
603 		dm_alloc(sizeof(struct dce110_link_encoder));
604 
605 	if (!enc110)
606 		return NULL;
607 
608 	if (dce110_link_encoder_construct(
609 			enc110,
610 			enc_init_data,
611 			&link_enc_feature,
612 			&link_enc_regs[enc_init_data->transmitter],
613 			&link_enc_aux_regs[enc_init_data->channel - 1],
614 			&link_enc_hpd_regs[enc_init_data->hpd_source])) {
615 
616 		return &enc110->base;
617 	}
618 
619 	BREAK_TO_DEBUGGER();
620 	dm_free(enc110);
621 	return NULL;
622 }
623 
624 static struct input_pixel_processor *dce120_ipp_create(
625 	struct dc_context *ctx,
626 	uint32_t inst,
627 	const struct dce110_ipp_reg_offsets *offset)
628 {
629 	struct dce110_ipp *ipp = dm_alloc(sizeof(struct dce110_ipp));
630 
631 	if (!ipp)
632 		return NULL;
633 
634 	if (dce120_ipp_construct(ipp, ctx, inst, offset))
635 		return &ipp->base;
636 
637 	BREAK_TO_DEBUGGER();
638 	dm_free(ipp);
639 	return NULL;
640 }
641 
642 static struct stream_encoder *dce120_stream_encoder_create(
643 	enum engine_id eng_id,
644 	struct dc_context *ctx)
645 {
646 	struct dce110_stream_encoder *enc110 =
647 		dm_alloc(sizeof(struct dce110_stream_encoder));
648 
649 	if (!enc110)
650 		return NULL;
651 
652 	if (dce110_stream_encoder_construct(
653 			enc110, ctx, ctx->dc_bios, eng_id,
654 			&stream_enc_regs[eng_id], &se_shift, &se_mask))
655 		return &enc110->base;
656 
657 	BREAK_TO_DEBUGGER();
658 	dm_free(enc110);
659 	return NULL;
660 }
661 
662 #define SRII(reg_name, block, id)\
663 	.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
664 					mm ## block ## id ## _ ## reg_name
665 
666 static const struct dce_hwseq_registers hwseq_reg = {
667 		HWSEQ_DCE112_REG_LIST()
668 };
669 
670 static const struct dce_hwseq_shift hwseq_shift = {
671 		HWSEQ_DCE12_MASK_SH_LIST(__SHIFT)
672 };
673 
674 static const struct dce_hwseq_mask hwseq_mask = {
675 		HWSEQ_DCE12_MASK_SH_LIST(_MASK)
676 };
677 
678 static struct dce_hwseq *dce120_hwseq_create(
679 	struct dc_context *ctx)
680 {
681 	struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq));
682 
683 	if (hws) {
684 		hws->ctx = ctx;
685 		hws->regs = &hwseq_reg;
686 		hws->shifts = &hwseq_shift;
687 		hws->masks = &hwseq_mask;
688 	}
689 	return hws;
690 }
691 
692 static const struct resource_create_funcs res_create_funcs = {
693 	.read_dce_straps = read_dce_straps,
694 	.create_audio = create_audio,
695 	.create_stream_encoder = dce120_stream_encoder_create,
696 	.create_hwseq = dce120_hwseq_create,
697 };
698 
699 #define mi_inst_regs(id) { MI_DCE12_REG_LIST(id) }
700 static const struct dce_mem_input_registers mi_regs[] = {
701 		mi_inst_regs(0),
702 		mi_inst_regs(1),
703 		mi_inst_regs(2),
704 		mi_inst_regs(3),
705 		mi_inst_regs(4),
706 		mi_inst_regs(5),
707 };
708 
709 static const struct dce_mem_input_shift mi_shifts = {
710 		MI_DCE12_MASK_SH_LIST(__SHIFT)
711 };
712 
713 static const struct dce_mem_input_mask mi_masks = {
714 		MI_DCE12_MASK_SH_LIST(_MASK)
715 };
716 
717 static struct mem_input *dce120_mem_input_create(
718 	struct dc_context *ctx,
719 	uint32_t inst,
720 	const struct dce110_mem_input_reg_offsets *offset)
721 {
722 	struct dce110_mem_input *mem_input110 =
723 		dm_alloc(sizeof(struct dce110_mem_input));
724 
725 	if (!mem_input110)
726 		return NULL;
727 
728 	if (dce120_mem_input_construct(mem_input110, ctx, inst, offset)) {
729 		struct mem_input *mi = &mem_input110->base;
730 
731 		mi->regs = &mi_regs[inst];
732 		mi->shifts = &mi_shifts;
733 		mi->masks = &mi_masks;
734 		return mi;
735 	}
736 
737 	BREAK_TO_DEBUGGER();
738 	dm_free(mem_input110);
739 	return NULL;
740 }
741 
742 static struct transform *dce120_transform_create(
743 	struct dc_context *ctx,
744 	uint32_t inst)
745 {
746 	struct dce_transform *transform =
747 		dm_alloc(sizeof(struct dce_transform));
748 
749 	if (!transform)
750 		return NULL;
751 
752 	if (dce_transform_construct(transform, ctx, inst,
753 			&xfm_regs[inst], &xfm_shift, &xfm_mask)) {
754 		transform->lb_memory_size = 0x1404; /*5124*/
755 		return &transform->base;
756 	}
757 
758 	BREAK_TO_DEBUGGER();
759 	dm_free(transform);
760 	return NULL;
761 }
762 
763 static void dce120_destroy_resource_pool(struct resource_pool **pool)
764 {
765 	struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
766 
767 	destruct(dce110_pool);
768 	dm_free(dce110_pool);
769 	*pool = NULL;
770 }
771 
772 static const struct resource_funcs dce120_res_pool_funcs = {
773 	.destroy = dce120_destroy_resource_pool,
774 	.link_enc_create = dce120_link_encoder_create,
775 	.validate_with_context = dce112_validate_with_context,
776 	.validate_guaranteed = dce112_validate_guaranteed,
777 	.validate_bandwidth = dce112_validate_bandwidth
778 };
779 
780 static void bw_calcs_data_update_from_pplib(struct core_dc *dc)
781 {
782 	struct dm_pp_clock_levels_with_latency eng_clks = {0};
783 	struct dm_pp_clock_levels_with_latency mem_clks = {0};
784 	struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
785 	int i;
786 	unsigned int clk;
787 	unsigned int latency;
788 
789 	/*do system clock*/
790 	if (!dm_pp_get_clock_levels_by_type_with_latency(
791 				dc->ctx,
792 				DM_PP_CLOCK_TYPE_ENGINE_CLK,
793 				&eng_clks) || eng_clks.num_levels == 0) {
794 
795 		eng_clks.num_levels = 8;
796 		clk = 300000;
797 
798 		for (i = 0; i < eng_clks.num_levels; i++) {
799 			eng_clks.data[i].clocks_in_khz = clk;
800 			clk += 100000;
801 		}
802 	}
803 
804 	/* convert all the clock fro kHz to fix point mHz  TODO: wloop data */
805 	dc->bw_vbios.high_sclk = bw_frc_to_fixed(
806 		eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);
807 	dc->bw_vbios.mid1_sclk  = bw_frc_to_fixed(
808 		eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);
809 	dc->bw_vbios.mid2_sclk  = bw_frc_to_fixed(
810 		eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);
811 	dc->bw_vbios.mid3_sclk  = bw_frc_to_fixed(
812 		eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);
813 	dc->bw_vbios.mid4_sclk  = bw_frc_to_fixed(
814 		eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);
815 	dc->bw_vbios.mid5_sclk  = bw_frc_to_fixed(
816 		eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);
817 	dc->bw_vbios.mid6_sclk  = bw_frc_to_fixed(
818 		eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);
819 	dc->bw_vbios.low_sclk  = bw_frc_to_fixed(
820 			eng_clks.data[0].clocks_in_khz, 1000);
821 
822 	/*do memory clock*/
823 	if (!dm_pp_get_clock_levels_by_type_with_latency(
824 			dc->ctx,
825 			DM_PP_CLOCK_TYPE_MEMORY_CLK,
826 			&mem_clks) || mem_clks.num_levels == 0) {
827 
828 		mem_clks.num_levels = 3;
829 		clk = 250000;
830 		latency = 45;
831 
832 		for (i = 0; i < eng_clks.num_levels; i++) {
833 			mem_clks.data[i].clocks_in_khz = clk;
834 			mem_clks.data[i].latency_in_us = latency;
835 			clk += 500000;
836 			latency -= 5;
837 		}
838 
839 	}
840 
841 	/* we don't need to call PPLIB for validation clock since they
842 	 * also give us the highest sclk and highest mclk (UMA clock).
843 	 * ALSO always convert UMA clock (from PPLIB)  to YCLK (HW formula):
844 	 * YCLK = UMACLK*m_memoryTypeMultiplier
845 	 */
846 	dc->bw_vbios.low_yclk = bw_frc_to_fixed(
847 		mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, 1000);
848 	dc->bw_vbios.mid_yclk = bw_frc_to_fixed(
849 		mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER,
850 		1000);
851 	dc->bw_vbios.high_yclk = bw_frc_to_fixed(
852 		mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER,
853 		1000);
854 
855 	/* Now notify PPLib/SMU about which Watermarks sets they should select
856 	 * depending on DPM state they are in. And update BW MGR GFX Engine and
857 	 * Memory clock member variables for Watermarks calculations for each
858 	 * Watermark Set
859 	 */
860 	clk_ranges.num_wm_sets = 4;
861 	clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;
862 	clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =
863 			eng_clks.data[0].clocks_in_khz;
864 	clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =
865 			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
866 	clk_ranges.wm_clk_ranges[0].wm_min_memg_clk_in_khz =
867 			mem_clks.data[0].clocks_in_khz;
868 	clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =
869 			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
870 
871 	clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;
872 	clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =
873 			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
874 	/* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
875 	clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;
876 	clk_ranges.wm_clk_ranges[1].wm_min_memg_clk_in_khz =
877 			mem_clks.data[0].clocks_in_khz;
878 	clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =
879 			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
880 
881 	clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;
882 	clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =
883 			eng_clks.data[0].clocks_in_khz;
884 	clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =
885 			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
886 	clk_ranges.wm_clk_ranges[2].wm_min_memg_clk_in_khz =
887 			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
888 	/* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
889 	clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;
890 
891 	clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;
892 	clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =
893 			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
894 	/* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
895 	clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;
896 	clk_ranges.wm_clk_ranges[3].wm_min_memg_clk_in_khz =
897 			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
898 	/* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
899 	clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;
900 
901 	/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
902 	dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
903 }
904 
905 static bool construct(
906 	uint8_t num_virtual_links,
907 	struct core_dc *dc,
908 	struct dce110_resource_pool *pool)
909 {
910 	unsigned int i;
911 	struct dc_context *ctx = dc->ctx;
912 	struct irq_service_init_data irq_init_data;
913 
914 	ctx->dc_bios->regs = &bios_regs;
915 
916 	pool->base.res_cap = &res_cap;
917 	pool->base.funcs = &dce120_res_pool_funcs;
918 
919 	/* TODO: Fill more data from GreenlandAsicCapability.cpp */
920 	pool->base.pipe_count = 6;
921 	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
922 
923 	dc->public.caps.max_downscale_ratio = 200;
924 	dc->public.caps.i2c_speed_in_khz = 100;
925 	dc->public.caps.max_cursor_size = 128;
926 	dc->public.debug = debug_defaults;
927 
928 	/*************************************************
929 	 *  Create resources                             *
930 	 *************************************************/
931 
932 	pool->base.clock_sources[DCE120_CLK_SRC_PLL0] =
933 			dce120_clock_source_create(ctx, ctx->dc_bios,
934 				CLOCK_SOURCE_COMBO_PHY_PLL0,
935 				&clk_src_regs[0], false);
936 	pool->base.clock_sources[DCE120_CLK_SRC_PLL1] =
937 			dce120_clock_source_create(ctx, ctx->dc_bios,
938 				CLOCK_SOURCE_COMBO_PHY_PLL1,
939 				&clk_src_regs[1], false);
940 	pool->base.clock_sources[DCE120_CLK_SRC_PLL2] =
941 			dce120_clock_source_create(ctx, ctx->dc_bios,
942 				CLOCK_SOURCE_COMBO_PHY_PLL2,
943 				&clk_src_regs[2], false);
944 	pool->base.clock_sources[DCE120_CLK_SRC_PLL3] =
945 			dce120_clock_source_create(ctx, ctx->dc_bios,
946 				CLOCK_SOURCE_COMBO_PHY_PLL3,
947 				&clk_src_regs[3], false);
948 	pool->base.clock_sources[DCE120_CLK_SRC_PLL4] =
949 			dce120_clock_source_create(ctx, ctx->dc_bios,
950 				CLOCK_SOURCE_COMBO_PHY_PLL4,
951 				&clk_src_regs[4], false);
952 	pool->base.clock_sources[DCE120_CLK_SRC_PLL5] =
953 			dce120_clock_source_create(ctx, ctx->dc_bios,
954 				CLOCK_SOURCE_COMBO_PHY_PLL5,
955 				&clk_src_regs[5], false);
956 	pool->base.clk_src_count = DCE120_CLK_SRC_TOTAL;
957 
958 	pool->base.dp_clock_source =
959 			dce120_clock_source_create(ctx, ctx->dc_bios,
960 				CLOCK_SOURCE_ID_DP_DTO,
961 				&clk_src_regs[0], true);
962 
963 	for (i = 0; i < pool->base.clk_src_count; i++) {
964 		if (pool->base.clock_sources[i] == NULL) {
965 			dm_error("DC: failed to create clock sources!\n");
966 			BREAK_TO_DEBUGGER();
967 			goto clk_src_create_fail;
968 		}
969 	}
970 
971 	pool->base.display_clock = dce120_disp_clk_create(ctx,
972 			&disp_clk_regs,
973 			&disp_clk_shift,
974 			&disp_clk_mask);
975 	if (pool->base.display_clock == NULL) {
976 		dm_error("DC: failed to create display clock!\n");
977 		BREAK_TO_DEBUGGER();
978 		goto disp_clk_create_fail;
979 	}
980 
981 	pool->base.dmcu = dce_dmcu_create(ctx,
982 			&dmcu_regs,
983 			&dmcu_shift,
984 			&dmcu_mask);
985 	if (pool->base.dmcu == NULL) {
986 		dm_error("DC: failed to create dmcu!\n");
987 		BREAK_TO_DEBUGGER();
988 		goto res_create_fail;
989 	}
990 
991 	pool->base.abm = dce_abm_create(ctx,
992 			&abm_regs,
993 			&abm_shift,
994 			&abm_mask);
995 	if (pool->base.abm == NULL) {
996 		dm_error("DC: failed to create abm!\n");
997 		BREAK_TO_DEBUGGER();
998 		goto res_create_fail;
999 	}
1000 
1001 	irq_init_data.ctx = dc->ctx;
1002 	pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data);
1003 	if (!pool->base.irqs)
1004 		goto irqs_create_fail;
1005 
1006 	for (i = 0; i < pool->base.pipe_count; i++) {
1007 		pool->base.timing_generators[i] =
1008 				dce120_timing_generator_create(
1009 					ctx,
1010 					i,
1011 					&dce120_tg_offsets[i]);
1012 		if (pool->base.timing_generators[i] == NULL) {
1013 			BREAK_TO_DEBUGGER();
1014 			dm_error("DC: failed to create tg!\n");
1015 			goto controller_create_fail;
1016 		}
1017 
1018 		pool->base.mis[i] = dce120_mem_input_create(ctx,
1019 				i, &dce120_mi_reg_offsets[i]);
1020 
1021 		if (pool->base.mis[i] == NULL) {
1022 			BREAK_TO_DEBUGGER();
1023 			dm_error(
1024 				"DC: failed to create memory input!\n");
1025 			goto controller_create_fail;
1026 		}
1027 
1028 		pool->base.ipps[i] = dce120_ipp_create(ctx, i,
1029 				&dce120_ipp_reg_offsets[i]);
1030 		if (pool->base.ipps[i] == NULL) {
1031 			BREAK_TO_DEBUGGER();
1032 			dm_error(
1033 				"DC: failed to create input pixel processor!\n");
1034 			goto controller_create_fail;
1035 		}
1036 
1037 		pool->base.transforms[i] = dce120_transform_create(ctx, i);
1038 		if (pool->base.transforms[i] == NULL) {
1039 			BREAK_TO_DEBUGGER();
1040 			dm_error(
1041 				"DC: failed to create transform!\n");
1042 			goto res_create_fail;
1043 		}
1044 
1045 		pool->base.opps[i] = dce120_opp_create(
1046 			ctx,
1047 			i);
1048 		if (pool->base.opps[i] == NULL) {
1049 			BREAK_TO_DEBUGGER();
1050 			dm_error(
1051 				"DC: failed to create output pixel processor!\n");
1052 		}
1053 	}
1054 
1055 	if (!resource_construct(num_virtual_links, dc, &pool->base,
1056 			 &res_create_funcs))
1057 		goto res_create_fail;
1058 
1059 	/* Create hardware sequencer */
1060 	if (!dce120_hw_sequencer_create(dc))
1061 		goto controller_create_fail;
1062 
1063 	bw_calcs_init(&dc->bw_dceip, &dc->bw_vbios, dc->ctx->asic_id);
1064 
1065 	bw_calcs_data_update_from_pplib(dc);
1066 
1067 	return true;
1068 
1069 irqs_create_fail:
1070 controller_create_fail:
1071 disp_clk_create_fail:
1072 clk_src_create_fail:
1073 res_create_fail:
1074 
1075 	destruct(pool);
1076 
1077 	return false;
1078 }
1079 
1080 struct resource_pool *dce120_create_resource_pool(
1081 	uint8_t num_virtual_links,
1082 	struct core_dc *dc)
1083 {
1084 	struct dce110_resource_pool *pool =
1085 		dm_alloc(sizeof(struct dce110_resource_pool));
1086 
1087 	if (!pool)
1088 		return NULL;
1089 
1090 	if (construct(num_virtual_links, dc, pool))
1091 		return &pool->base;
1092 
1093 	BREAK_TO_DEBUGGER();
1094 	return NULL;
1095 }
1096