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 "dm_services.h"
27
28#include "link_encoder.h"
29#include "stream_encoder.h"
30
31#include "resource.h"
32#include "include/irq_service_interface.h"
33#include "dce110/dce110_resource.h"
34#include "dce110/dce110_timing_generator.h"
35
36#include "irq/dce110/irq_service_dce110.h"
37#include "dce/dce_mem_input.h"
38#include "dce/dce_transform.h"
39#include "dce/dce_link_encoder.h"
40#include "dce/dce_stream_encoder.h"
41#include "dce/dce_audio.h"
42#include "dce/dce_opp.h"
43#include "dce/dce_ipp.h"
44#include "dce/dce_clock_source.h"
45
46#include "dce/dce_hwseq.h"
47#include "dce112/dce112_hwseq.h"
48#include "dce/dce_abm.h"
49#include "dce/dce_dmcu.h"
50#include "dce/dce_aux.h"
51#include "dce/dce_i2c.h"
52#include "dce/dce_panel_cntl.h"
53
54#include "reg_helper.h"
55
56#include "dce/dce_11_2_d.h"
57#include "dce/dce_11_2_sh_mask.h"
58
59#include "dce100/dce100_resource.h"
60#include "dce112_resource.h"
61
62#define DC_LOGGER				\
63		dc->ctx->logger
64
65#ifndef mmDP_DPHY_INTERNAL_CTRL
66	#define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
67	#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
68	#define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
69	#define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
70	#define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
71	#define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
72	#define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
73	#define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
74	#define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
75	#define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
76#endif
77
78#ifndef mmBIOS_SCRATCH_2
79	#define mmBIOS_SCRATCH_2 0x05CB
80	#define mmBIOS_SCRATCH_3 0x05CC
81	#define mmBIOS_SCRATCH_6 0x05CF
82#endif
83
84#ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
85	#define mmDP_DPHY_BS_SR_SWAP_CNTL                       0x4ADC
86	#define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL                   0x4ADC
87	#define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL                   0x4BDC
88	#define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL                   0x4CDC
89	#define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL                   0x4DDC
90	#define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL                   0x4EDC
91	#define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL                   0x4FDC
92	#define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL                   0x54DC
93#endif
94
95#ifndef mmDP_DPHY_FAST_TRAINING
96	#define mmDP_DPHY_FAST_TRAINING                         0x4ABC
97	#define mmDP0_DP_DPHY_FAST_TRAINING                     0x4ABC
98	#define mmDP1_DP_DPHY_FAST_TRAINING                     0x4BBC
99	#define mmDP2_DP_DPHY_FAST_TRAINING                     0x4CBC
100	#define mmDP3_DP_DPHY_FAST_TRAINING                     0x4DBC
101	#define mmDP4_DP_DPHY_FAST_TRAINING                     0x4EBC
102	#define mmDP5_DP_DPHY_FAST_TRAINING                     0x4FBC
103	#define mmDP6_DP_DPHY_FAST_TRAINING                     0x54BC
104#endif
105
106enum dce112_clk_src_array_id {
107	DCE112_CLK_SRC_PLL0,
108	DCE112_CLK_SRC_PLL1,
109	DCE112_CLK_SRC_PLL2,
110	DCE112_CLK_SRC_PLL3,
111	DCE112_CLK_SRC_PLL4,
112	DCE112_CLK_SRC_PLL5,
113
114	DCE112_CLK_SRC_TOTAL
115};
116
117static const struct dce110_timing_generator_offsets dce112_tg_offsets[] = {
118	{
119		.crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
120		.dcp =  (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
121	},
122	{
123		.crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
124		.dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
125	},
126	{
127		.crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
128		.dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
129	},
130	{
131		.crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
132		.dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
133	},
134	{
135		.crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
136		.dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
137	},
138	{
139		.crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
140		.dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
141	}
142};
143
144/* set register offset */
145#define SR(reg_name)\
146	.reg_name = mm ## reg_name
147
148/* set register offset with instance */
149#define SRI(reg_name, block, id)\
150	.reg_name = mm ## block ## id ## _ ## reg_name
151
152static const struct dce_dmcu_registers dmcu_regs = {
153		DMCU_DCE110_COMMON_REG_LIST()
154};
155
156static const struct dce_dmcu_shift dmcu_shift = {
157		DMCU_MASK_SH_LIST_DCE110(__SHIFT)
158};
159
160static const struct dce_dmcu_mask dmcu_mask = {
161		DMCU_MASK_SH_LIST_DCE110(_MASK)
162};
163
164static const struct dce_abm_registers abm_regs = {
165		ABM_DCE110_COMMON_REG_LIST()
166};
167
168static const struct dce_abm_shift abm_shift = {
169		ABM_MASK_SH_LIST_DCE110(__SHIFT)
170};
171
172static const struct dce_abm_mask abm_mask = {
173		ABM_MASK_SH_LIST_DCE110(_MASK)
174};
175
176static const struct dce110_aux_registers_shift aux_shift = {
177	DCE_AUX_MASK_SH_LIST(__SHIFT)
178};
179
180static const struct dce110_aux_registers_mask aux_mask = {
181	DCE_AUX_MASK_SH_LIST(_MASK)
182};
183
184#define ipp_regs(id)\
185[id] = {\
186		IPP_DCE110_REG_LIST_DCE_BASE(id)\
187}
188
189static const struct dce_ipp_registers ipp_regs[] = {
190		ipp_regs(0),
191		ipp_regs(1),
192		ipp_regs(2),
193		ipp_regs(3),
194		ipp_regs(4),
195		ipp_regs(5)
196};
197
198static const struct dce_ipp_shift ipp_shift = {
199		IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
200};
201
202static const struct dce_ipp_mask ipp_mask = {
203		IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
204};
205
206#define transform_regs(id)\
207[id] = {\
208		XFM_COMMON_REG_LIST_DCE110(id)\
209}
210
211static const struct dce_transform_registers xfm_regs[] = {
212		transform_regs(0),
213		transform_regs(1),
214		transform_regs(2),
215		transform_regs(3),
216		transform_regs(4),
217		transform_regs(5)
218};
219
220static const struct dce_transform_shift xfm_shift = {
221		XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
222};
223
224static const struct dce_transform_mask xfm_mask = {
225		XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
226};
227
228#define aux_regs(id)\
229[id] = {\
230	AUX_REG_LIST(id)\
231}
232
233static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
234		aux_regs(0),
235		aux_regs(1),
236		aux_regs(2),
237		aux_regs(3),
238		aux_regs(4),
239		aux_regs(5)
240};
241
242static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
243	{ DCE_PANEL_CNTL_REG_LIST() }
244};
245
246static const struct dce_panel_cntl_shift panel_cntl_shift = {
247	DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
248};
249
250static const struct dce_panel_cntl_mask panel_cntl_mask = {
251	DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
252};
253
254#define hpd_regs(id)\
255[id] = {\
256	HPD_REG_LIST(id)\
257}
258
259static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
260		hpd_regs(0),
261		hpd_regs(1),
262		hpd_regs(2),
263		hpd_regs(3),
264		hpd_regs(4),
265		hpd_regs(5)
266};
267
268#define link_regs(id)\
269[id] = {\
270	LE_DCE110_REG_LIST(id)\
271}
272
273static const struct dce110_link_enc_registers link_enc_regs[] = {
274	link_regs(0),
275	link_regs(1),
276	link_regs(2),
277	link_regs(3),
278	link_regs(4),
279	link_regs(5),
280	link_regs(6),
281};
282
283#define stream_enc_regs(id)\
284[id] = {\
285	SE_COMMON_REG_LIST(id),\
286	.TMDS_CNTL = 0,\
287}
288
289static const struct dce110_stream_enc_registers stream_enc_regs[] = {
290	stream_enc_regs(0),
291	stream_enc_regs(1),
292	stream_enc_regs(2),
293	stream_enc_regs(3),
294	stream_enc_regs(4),
295	stream_enc_regs(5)
296};
297
298static const struct dce_stream_encoder_shift se_shift = {
299		SE_COMMON_MASK_SH_LIST_DCE112(__SHIFT)
300};
301
302static const struct dce_stream_encoder_mask se_mask = {
303		SE_COMMON_MASK_SH_LIST_DCE112(_MASK)
304};
305
306#define opp_regs(id)\
307[id] = {\
308	OPP_DCE_112_REG_LIST(id),\
309}
310
311static const struct dce_opp_registers opp_regs[] = {
312	opp_regs(0),
313	opp_regs(1),
314	opp_regs(2),
315	opp_regs(3),
316	opp_regs(4),
317	opp_regs(5)
318};
319
320static const struct dce_opp_shift opp_shift = {
321	OPP_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
322};
323
324static const struct dce_opp_mask opp_mask = {
325	OPP_COMMON_MASK_SH_LIST_DCE_112(_MASK)
326};
327
328#define aux_engine_regs(id)\
329[id] = {\
330	AUX_COMMON_REG_LIST(id), \
331	.AUX_RESET_MASK = 0 \
332}
333
334static const struct dce110_aux_registers aux_engine_regs[] = {
335		aux_engine_regs(0),
336		aux_engine_regs(1),
337		aux_engine_regs(2),
338		aux_engine_regs(3),
339		aux_engine_regs(4),
340		aux_engine_regs(5)
341};
342
343#define audio_regs(id)\
344[id] = {\
345	AUD_COMMON_REG_LIST(id)\
346}
347
348static const struct dce_audio_registers audio_regs[] = {
349	audio_regs(0),
350	audio_regs(1),
351	audio_regs(2),
352	audio_regs(3),
353	audio_regs(4),
354	audio_regs(5)
355};
356
357static const struct dce_audio_shift audio_shift = {
358		AUD_COMMON_MASK_SH_LIST(__SHIFT)
359};
360
361static const struct dce_audio_mask audio_mask = {
362		AUD_COMMON_MASK_SH_LIST(_MASK)
363};
364
365#define clk_src_regs(index, id)\
366[index] = {\
367	CS_COMMON_REG_LIST_DCE_112(id),\
368}
369
370static const struct dce110_clk_src_regs clk_src_regs[] = {
371	clk_src_regs(0, A),
372	clk_src_regs(1, B),
373	clk_src_regs(2, C),
374	clk_src_regs(3, D),
375	clk_src_regs(4, E),
376	clk_src_regs(5, F)
377};
378
379static const struct dce110_clk_src_shift cs_shift = {
380		CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
381};
382
383static const struct dce110_clk_src_mask cs_mask = {
384		CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)
385};
386
387static const struct bios_registers bios_regs = {
388	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
389	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
390};
391
392static const struct resource_caps polaris_10_resource_cap = {
393		.num_timing_generator = 6,
394		.num_audio = 6,
395		.num_stream_encoder = 6,
396		.num_pll = 8, /* why 8? 6 combo PHY PLL + 2 regular PLLs? */
397		.num_ddc = 6,
398};
399
400static const struct resource_caps polaris_11_resource_cap = {
401		.num_timing_generator = 5,
402		.num_audio = 5,
403		.num_stream_encoder = 5,
404		.num_pll = 8, /* why 8? 6 combo PHY PLL + 2 regular PLLs? */
405		.num_ddc = 5,
406};
407
408static const struct dc_plane_cap plane_cap = {
409	.type = DC_PLANE_TYPE_DCE_RGB,
410
411	.pixel_format_support = {
412			.argb8888 = true,
413			.nv12 = false,
414			.fp16 = true
415	},
416
417	.max_upscale_factor = {
418			.argb8888 = 16000,
419			.nv12 = 1,
420			.fp16 = 1
421	},
422
423	.max_downscale_factor = {
424			.argb8888 = 250,
425			.nv12 = 1,
426			.fp16 = 1
427	},
428	64,
429	64
430};
431
432static const struct dc_debug_options debug_defaults = {
433		.enable_legacy_fast_update = true,
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 0x4819
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	case TRANSMITTER_UNIPHY_B:
454		return 1;
455	case TRANSMITTER_UNIPHY_C:
456		return 2;
457	case TRANSMITTER_UNIPHY_D:
458		return 3;
459	case TRANSMITTER_UNIPHY_E:
460		return 4;
461	case TRANSMITTER_UNIPHY_F:
462		return 5;
463	case TRANSMITTER_UNIPHY_G:
464		return 6;
465	default:
466		ASSERT(0);
467		return 0;
468	}
469}
470
471static void read_dce_straps(
472	struct dc_context *ctx,
473	struct resource_straps *straps)
474{
475	REG_GET_2(CC_DC_HDMI_STRAPS,
476			HDMI_DISABLE, &straps->hdmi_disable,
477			AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
478
479	REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
480}
481
482static struct audio *create_audio(
483		struct dc_context *ctx, unsigned int inst)
484{
485	return dce_audio_create(ctx, inst,
486			&audio_regs[inst], &audio_shift, &audio_mask);
487}
488
489
490static struct timing_generator *dce112_timing_generator_create(
491		struct dc_context *ctx,
492		uint32_t instance,
493		const struct dce110_timing_generator_offsets *offsets)
494{
495	struct dce110_timing_generator *tg110 =
496		kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
497
498	if (!tg110)
499		return NULL;
500
501	dce110_timing_generator_construct(tg110, ctx, instance, offsets);
502	return &tg110->base;
503}
504
505static struct stream_encoder *dce112_stream_encoder_create(
506	enum engine_id eng_id,
507	struct dc_context *ctx)
508{
509	struct dce110_stream_encoder *enc110 =
510		kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
511
512	if (!enc110)
513		return NULL;
514
515	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
516					&stream_enc_regs[eng_id],
517					&se_shift, &se_mask);
518	return &enc110->base;
519}
520
521#define SRII(reg_name, block, id)\
522	.reg_name[id] = mm ## block ## id ## _ ## reg_name
523
524static const struct dce_hwseq_registers hwseq_reg = {
525		HWSEQ_DCE112_REG_LIST()
526};
527
528static const struct dce_hwseq_shift hwseq_shift = {
529		HWSEQ_DCE112_MASK_SH_LIST(__SHIFT)
530};
531
532static const struct dce_hwseq_mask hwseq_mask = {
533		HWSEQ_DCE112_MASK_SH_LIST(_MASK)
534};
535
536static struct dce_hwseq *dce112_hwseq_create(
537	struct dc_context *ctx)
538{
539	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
540
541	if (hws) {
542		hws->ctx = ctx;
543		hws->regs = &hwseq_reg;
544		hws->shifts = &hwseq_shift;
545		hws->masks = &hwseq_mask;
546	}
547	return hws;
548}
549
550static const struct resource_create_funcs res_create_funcs = {
551	.read_dce_straps = read_dce_straps,
552	.create_audio = create_audio,
553	.create_stream_encoder = dce112_stream_encoder_create,
554	.create_hwseq = dce112_hwseq_create,
555};
556
557#define mi_inst_regs(id) { MI_DCE11_2_REG_LIST(id) }
558static const struct dce_mem_input_registers mi_regs[] = {
559		mi_inst_regs(0),
560		mi_inst_regs(1),
561		mi_inst_regs(2),
562		mi_inst_regs(3),
563		mi_inst_regs(4),
564		mi_inst_regs(5),
565};
566
567static const struct dce_mem_input_shift mi_shifts = {
568		MI_DCE11_2_MASK_SH_LIST(__SHIFT)
569};
570
571static const struct dce_mem_input_mask mi_masks = {
572		MI_DCE11_2_MASK_SH_LIST(_MASK)
573};
574
575static struct mem_input *dce112_mem_input_create(
576	struct dc_context *ctx,
577	uint32_t inst)
578{
579	struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
580					       GFP_KERNEL);
581
582	if (!dce_mi) {
583		BREAK_TO_DEBUGGER();
584		return NULL;
585	}
586
587	dce112_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
588	return &dce_mi->base;
589}
590
591static void dce112_transform_destroy(struct transform **xfm)
592{
593	kfree(TO_DCE_TRANSFORM(*xfm));
594	*xfm = NULL;
595}
596
597static struct transform *dce112_transform_create(
598	struct dc_context *ctx,
599	uint32_t inst)
600{
601	struct dce_transform *transform =
602		kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
603
604	if (!transform)
605		return NULL;
606
607	dce_transform_construct(transform, ctx, inst,
608				&xfm_regs[inst], &xfm_shift, &xfm_mask);
609	transform->lb_memory_size = 0x1404; /*5124*/
610	return &transform->base;
611}
612
613static const struct encoder_feature_support link_enc_feature = {
614		.max_hdmi_deep_color = COLOR_DEPTH_121212,
615		.max_hdmi_pixel_clock = 600000,
616		.hdmi_ycbcr420_supported = true,
617		.dp_ycbcr420_supported = false,
618		.flags.bits.IS_HBR2_CAPABLE = true,
619		.flags.bits.IS_HBR3_CAPABLE = true,
620		.flags.bits.IS_TPS3_CAPABLE = true,
621		.flags.bits.IS_TPS4_CAPABLE = true
622};
623
624static struct link_encoder *dce112_link_encoder_create(
625	struct dc_context *ctx,
626	const struct encoder_init_data *enc_init_data)
627{
628	struct dce110_link_encoder *enc110 =
629		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
630	int link_regs_id;
631
632	if (!enc110)
633		return NULL;
634
635	link_regs_id =
636		map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
637
638	dce110_link_encoder_construct(enc110,
639				      enc_init_data,
640				      &link_enc_feature,
641				      &link_enc_regs[link_regs_id],
642				      &link_enc_aux_regs[enc_init_data->channel - 1],
643				      &link_enc_hpd_regs[enc_init_data->hpd_source]);
644	return &enc110->base;
645}
646
647static struct panel_cntl *dce112_panel_cntl_create(const struct panel_cntl_init_data *init_data)
648{
649	struct dce_panel_cntl *panel_cntl =
650		kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
651
652	if (!panel_cntl)
653		return NULL;
654
655	dce_panel_cntl_construct(panel_cntl,
656			init_data,
657			&panel_cntl_regs[init_data->inst],
658			&panel_cntl_shift,
659			&panel_cntl_mask);
660
661	return &panel_cntl->base;
662}
663
664static struct input_pixel_processor *dce112_ipp_create(
665	struct dc_context *ctx, uint32_t inst)
666{
667	struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
668
669	if (!ipp) {
670		BREAK_TO_DEBUGGER();
671		return NULL;
672	}
673
674	dce_ipp_construct(ipp, ctx, inst,
675			&ipp_regs[inst], &ipp_shift, &ipp_mask);
676	return &ipp->base;
677}
678
679static struct output_pixel_processor *dce112_opp_create(
680	struct dc_context *ctx,
681	uint32_t inst)
682{
683	struct dce110_opp *opp =
684		kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
685
686	if (!opp)
687		return NULL;
688
689	dce110_opp_construct(opp,
690			     ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
691	return &opp->base;
692}
693
694static struct dce_aux *dce112_aux_engine_create(
695	struct dc_context *ctx,
696	uint32_t inst)
697{
698	struct aux_engine_dce110 *aux_engine =
699		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
700
701	if (!aux_engine)
702		return NULL;
703
704	dce110_aux_engine_construct(aux_engine, ctx, inst,
705				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
706				    &aux_engine_regs[inst],
707					&aux_mask,
708					&aux_shift,
709					ctx->dc->caps.extended_aux_timeout_support);
710
711	return &aux_engine->base;
712}
713#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
714
715static const struct dce_i2c_registers i2c_hw_regs[] = {
716		i2c_inst_regs(1),
717		i2c_inst_regs(2),
718		i2c_inst_regs(3),
719		i2c_inst_regs(4),
720		i2c_inst_regs(5),
721		i2c_inst_regs(6),
722};
723
724static const struct dce_i2c_shift i2c_shifts = {
725		I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
726};
727
728static const struct dce_i2c_mask i2c_masks = {
729		I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
730};
731
732static struct dce_i2c_hw *dce112_i2c_hw_create(
733	struct dc_context *ctx,
734	uint32_t inst)
735{
736	struct dce_i2c_hw *dce_i2c_hw =
737		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
738
739	if (!dce_i2c_hw)
740		return NULL;
741
742	dce112_i2c_hw_construct(dce_i2c_hw, ctx, inst,
743				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
744
745	return dce_i2c_hw;
746}
747static struct clock_source *dce112_clock_source_create(
748	struct dc_context *ctx,
749	struct dc_bios *bios,
750	enum clock_source_id id,
751	const struct dce110_clk_src_regs *regs,
752	bool dp_clk_src)
753{
754	struct dce110_clk_src *clk_src =
755		kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
756
757	if (!clk_src)
758		return NULL;
759
760	if (dce112_clk_src_construct(clk_src, ctx, bios, id,
761			regs, &cs_shift, &cs_mask)) {
762		clk_src->base.dp_clk_src = dp_clk_src;
763		return &clk_src->base;
764	}
765
766	kfree(clk_src);
767	BREAK_TO_DEBUGGER();
768	return NULL;
769}
770
771static void dce112_clock_source_destroy(struct clock_source **clk_src)
772{
773	kfree(TO_DCE110_CLK_SRC(*clk_src));
774	*clk_src = NULL;
775}
776
777static void dce112_resource_destruct(struct dce110_resource_pool *pool)
778{
779	unsigned int i;
780
781	for (i = 0; i < pool->base.pipe_count; i++) {
782		if (pool->base.opps[i] != NULL)
783			dce110_opp_destroy(&pool->base.opps[i]);
784
785		if (pool->base.transforms[i] != NULL)
786			dce112_transform_destroy(&pool->base.transforms[i]);
787
788		if (pool->base.ipps[i] != NULL)
789			dce_ipp_destroy(&pool->base.ipps[i]);
790
791		if (pool->base.mis[i] != NULL) {
792			kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
793			pool->base.mis[i] = NULL;
794		}
795
796		if (pool->base.timing_generators[i] != NULL) {
797			kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
798			pool->base.timing_generators[i] = NULL;
799		}
800	}
801
802	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
803		if (pool->base.engines[i] != NULL)
804			dce110_engine_destroy(&pool->base.engines[i]);
805		if (pool->base.hw_i2cs[i] != NULL) {
806			kfree(pool->base.hw_i2cs[i]);
807			pool->base.hw_i2cs[i] = NULL;
808		}
809		if (pool->base.sw_i2cs[i] != NULL) {
810			kfree(pool->base.sw_i2cs[i]);
811			pool->base.sw_i2cs[i] = NULL;
812		}
813	}
814
815	for (i = 0; i < pool->base.stream_enc_count; i++) {
816		if (pool->base.stream_enc[i] != NULL)
817			kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
818	}
819
820	for (i = 0; i < pool->base.clk_src_count; i++) {
821		if (pool->base.clock_sources[i] != NULL) {
822			dce112_clock_source_destroy(&pool->base.clock_sources[i]);
823		}
824	}
825
826	if (pool->base.dp_clock_source != NULL)
827		dce112_clock_source_destroy(&pool->base.dp_clock_source);
828
829	for (i = 0; i < pool->base.audio_count; i++)	{
830		if (pool->base.audios[i] != NULL) {
831			dce_aud_destroy(&pool->base.audios[i]);
832		}
833	}
834
835	if (pool->base.abm != NULL)
836		dce_abm_destroy(&pool->base.abm);
837
838	if (pool->base.dmcu != NULL)
839		dce_dmcu_destroy(&pool->base.dmcu);
840
841	if (pool->base.irqs != NULL) {
842		dal_irq_service_destroy(&pool->base.irqs);
843	}
844}
845
846static struct clock_source *find_matching_pll(
847		struct resource_context *res_ctx,
848		const struct resource_pool *pool,
849		const struct dc_stream_state *const stream)
850{
851	switch (stream->link->link_enc->transmitter) {
852	case TRANSMITTER_UNIPHY_A:
853		return pool->clock_sources[DCE112_CLK_SRC_PLL0];
854	case TRANSMITTER_UNIPHY_B:
855		return pool->clock_sources[DCE112_CLK_SRC_PLL1];
856	case TRANSMITTER_UNIPHY_C:
857		return pool->clock_sources[DCE112_CLK_SRC_PLL2];
858	case TRANSMITTER_UNIPHY_D:
859		return pool->clock_sources[DCE112_CLK_SRC_PLL3];
860	case TRANSMITTER_UNIPHY_E:
861		return pool->clock_sources[DCE112_CLK_SRC_PLL4];
862	case TRANSMITTER_UNIPHY_F:
863		return pool->clock_sources[DCE112_CLK_SRC_PLL5];
864	default:
865		return NULL;
866	}
867
868	return NULL;
869}
870
871static enum dc_status build_mapped_resource(
872		const struct dc *dc,
873		struct dc_state *context,
874		struct dc_stream_state *stream)
875{
876	struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream);
877
878	if (!pipe_ctx)
879		return DC_ERROR_UNEXPECTED;
880
881	dce110_resource_build_pipe_hw_param(pipe_ctx);
882
883	resource_build_info_frame(pipe_ctx);
884
885	return DC_OK;
886}
887
888bool dce112_validate_bandwidth(
889	struct dc *dc,
890	struct dc_state *context,
891	bool fast_validate)
892{
893	bool result = false;
894
895	DC_LOG_BANDWIDTH_CALCS(
896		"%s: start",
897		__func__);
898
899	if (bw_calcs(
900			dc->ctx,
901			dc->bw_dceip,
902			dc->bw_vbios,
903			context->res_ctx.pipe_ctx,
904			dc->res_pool->pipe_count,
905			&context->bw_ctx.bw.dce))
906		result = true;
907
908	if (!result)
909		DC_LOG_BANDWIDTH_VALIDATION(
910			"%s: Bandwidth validation failed!",
911			__func__);
912
913	if (memcmp(&dc->current_state->bw_ctx.bw.dce,
914			&context->bw_ctx.bw.dce, sizeof(context->bw_ctx.bw.dce))) {
915
916		DC_LOG_BANDWIDTH_CALCS(
917			"%s: finish,\n"
918			"nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
919			"stutMark_b: %d stutMark_a: %d\n"
920			"nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
921			"stutMark_b: %d stutMark_a: %d\n"
922			"nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
923			"stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n"
924			"cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n"
925			"sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n"
926			,
927			__func__,
928			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].b_mark,
929			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].a_mark,
930			context->bw_ctx.bw.dce.urgent_wm_ns[0].b_mark,
931			context->bw_ctx.bw.dce.urgent_wm_ns[0].a_mark,
932			context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].b_mark,
933			context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].a_mark,
934			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].b_mark,
935			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].a_mark,
936			context->bw_ctx.bw.dce.urgent_wm_ns[1].b_mark,
937			context->bw_ctx.bw.dce.urgent_wm_ns[1].a_mark,
938			context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].b_mark,
939			context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].a_mark,
940			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].b_mark,
941			context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].a_mark,
942			context->bw_ctx.bw.dce.urgent_wm_ns[2].b_mark,
943			context->bw_ctx.bw.dce.urgent_wm_ns[2].a_mark,
944			context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].b_mark,
945			context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].a_mark,
946			context->bw_ctx.bw.dce.stutter_mode_enable,
947			context->bw_ctx.bw.dce.cpuc_state_change_enable,
948			context->bw_ctx.bw.dce.cpup_state_change_enable,
949			context->bw_ctx.bw.dce.nbp_state_change_enable,
950			context->bw_ctx.bw.dce.all_displays_in_sync,
951			context->bw_ctx.bw.dce.dispclk_khz,
952			context->bw_ctx.bw.dce.sclk_khz,
953			context->bw_ctx.bw.dce.sclk_deep_sleep_khz,
954			context->bw_ctx.bw.dce.yclk_khz,
955			context->bw_ctx.bw.dce.blackout_recovery_time_us);
956	}
957	return result;
958}
959
960enum dc_status resource_map_phy_clock_resources(
961		const struct dc *dc,
962		struct dc_state *context,
963		struct dc_stream_state *stream)
964{
965
966	/* acquire new resources */
967	struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(
968			&context->res_ctx, stream);
969
970	if (!pipe_ctx)
971		return DC_ERROR_UNEXPECTED;
972
973	if (dc_is_dp_signal(pipe_ctx->stream->signal)
974		|| dc_is_virtual_signal(pipe_ctx->stream->signal))
975		pipe_ctx->clock_source =
976				dc->res_pool->dp_clock_source;
977	else {
978		if (stream && stream->link && stream->link->link_enc)
979			pipe_ctx->clock_source = find_matching_pll(
980				&context->res_ctx, dc->res_pool,
981				stream);
982	}
983
984	if (pipe_ctx->clock_source == NULL)
985		return DC_NO_CLOCK_SOURCE_RESOURCE;
986
987	resource_reference_clock_source(
988		&context->res_ctx,
989		dc->res_pool,
990		pipe_ctx->clock_source);
991
992	return DC_OK;
993}
994
995static bool dce112_validate_surface_sets(
996		struct dc_state *context)
997{
998	int i;
999
1000	for (i = 0; i < context->stream_count; i++) {
1001		if (context->stream_status[i].plane_count == 0)
1002			continue;
1003
1004		if (context->stream_status[i].plane_count > 1)
1005			return false;
1006
1007		if (context->stream_status[i].plane_states[0]->format
1008				>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
1009			return false;
1010	}
1011
1012	return true;
1013}
1014
1015enum dc_status dce112_add_stream_to_ctx(
1016		struct dc *dc,
1017		struct dc_state *new_ctx,
1018		struct dc_stream_state *dc_stream)
1019{
1020	enum dc_status result;
1021
1022	result = resource_map_pool_resources(dc, new_ctx, dc_stream);
1023
1024	if (result == DC_OK)
1025		result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
1026
1027
1028	if (result == DC_OK)
1029		result = build_mapped_resource(dc, new_ctx, dc_stream);
1030
1031	return result;
1032}
1033
1034static enum dc_status dce112_validate_global(
1035		struct dc *dc,
1036		struct dc_state *context)
1037{
1038	if (!dce112_validate_surface_sets(context))
1039		return DC_FAIL_SURFACE_VALIDATE;
1040
1041	return DC_OK;
1042}
1043
1044static void dce112_destroy_resource_pool(struct resource_pool **pool)
1045{
1046	struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
1047
1048	dce112_resource_destruct(dce110_pool);
1049	kfree(dce110_pool);
1050	*pool = NULL;
1051}
1052
1053static const struct resource_funcs dce112_res_pool_funcs = {
1054	.destroy = dce112_destroy_resource_pool,
1055	.link_enc_create = dce112_link_encoder_create,
1056	.panel_cntl_create = dce112_panel_cntl_create,
1057	.validate_bandwidth = dce112_validate_bandwidth,
1058	.validate_plane = dce100_validate_plane,
1059	.add_stream_to_ctx = dce112_add_stream_to_ctx,
1060	.validate_global = dce112_validate_global,
1061	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
1062};
1063
1064static void bw_calcs_data_update_from_pplib(struct dc *dc)
1065{
1066	struct dm_pp_clock_levels_with_latency eng_clks = {0};
1067	struct dm_pp_clock_levels_with_latency mem_clks = {0};
1068	struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
1069	struct dm_pp_clock_levels clks = {0};
1070	int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
1071
1072	if (dc->bw_vbios && dc->bw_vbios->memory_type == bw_def_hbm)
1073		memory_type_multiplier = MEMORY_TYPE_HBM;
1074
1075	/*do system clock  TODO PPLIB: after PPLIB implement,
1076	 * then remove old way
1077	 */
1078	if (!dm_pp_get_clock_levels_by_type_with_latency(
1079			dc->ctx,
1080			DM_PP_CLOCK_TYPE_ENGINE_CLK,
1081			&eng_clks)) {
1082
1083		/* This is only for temporary */
1084		dm_pp_get_clock_levels_by_type(
1085				dc->ctx,
1086				DM_PP_CLOCK_TYPE_ENGINE_CLK,
1087				&clks);
1088		/* convert all the clock fro kHz to fix point mHz */
1089		dc->bw_vbios->high_sclk = bw_frc_to_fixed(
1090				clks.clocks_in_khz[clks.num_levels-1], 1000);
1091		dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
1092				clks.clocks_in_khz[clks.num_levels/8], 1000);
1093		dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
1094				clks.clocks_in_khz[clks.num_levels*2/8], 1000);
1095		dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
1096				clks.clocks_in_khz[clks.num_levels*3/8], 1000);
1097		dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
1098				clks.clocks_in_khz[clks.num_levels*4/8], 1000);
1099		dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
1100				clks.clocks_in_khz[clks.num_levels*5/8], 1000);
1101		dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
1102				clks.clocks_in_khz[clks.num_levels*6/8], 1000);
1103		dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
1104				clks.clocks_in_khz[0], 1000);
1105
1106		/*do memory clock*/
1107		dm_pp_get_clock_levels_by_type(
1108				dc->ctx,
1109				DM_PP_CLOCK_TYPE_MEMORY_CLK,
1110				&clks);
1111
1112		dc->bw_vbios->low_yclk = bw_frc_to_fixed(
1113			clks.clocks_in_khz[0] * memory_type_multiplier, 1000);
1114		dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
1115			clks.clocks_in_khz[clks.num_levels>>1] * memory_type_multiplier,
1116			1000);
1117		dc->bw_vbios->high_yclk = bw_frc_to_fixed(
1118			clks.clocks_in_khz[clks.num_levels-1] * memory_type_multiplier,
1119			1000);
1120
1121		return;
1122	}
1123
1124	/* convert all the clock fro kHz to fix point mHz  TODO: wloop data */
1125	dc->bw_vbios->high_sclk = bw_frc_to_fixed(
1126		eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);
1127	dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
1128		eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);
1129	dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
1130		eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);
1131	dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
1132		eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);
1133	dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
1134		eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);
1135	dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
1136		eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);
1137	dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
1138		eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);
1139	dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
1140			eng_clks.data[0].clocks_in_khz, 1000);
1141
1142	/*do memory clock*/
1143	dm_pp_get_clock_levels_by_type_with_latency(
1144			dc->ctx,
1145			DM_PP_CLOCK_TYPE_MEMORY_CLK,
1146			&mem_clks);
1147
1148	/* we don't need to call PPLIB for validation clock since they
1149	 * also give us the highest sclk and highest mclk (UMA clock).
1150	 * ALSO always convert UMA clock (from PPLIB)  to YCLK (HW formula):
1151	 * YCLK = UMACLK*m_memoryTypeMultiplier
1152	 */
1153	dc->bw_vbios->low_yclk = bw_frc_to_fixed(
1154		mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000);
1155	dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
1156		mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier,
1157		1000);
1158	dc->bw_vbios->high_yclk = bw_frc_to_fixed(
1159		mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier,
1160		1000);
1161
1162	/* Now notify PPLib/SMU about which Watermarks sets they should select
1163	 * depending on DPM state they are in. And update BW MGR GFX Engine and
1164	 * Memory clock member variables for Watermarks calculations for each
1165	 * Watermark Set
1166	 */
1167	clk_ranges.num_wm_sets = 4;
1168	clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;
1169	clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =
1170			eng_clks.data[0].clocks_in_khz;
1171	clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =
1172			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
1173	clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz =
1174			mem_clks.data[0].clocks_in_khz;
1175	clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =
1176			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
1177
1178	clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;
1179	clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =
1180			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
1181	/* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1182	clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;
1183	clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz =
1184			mem_clks.data[0].clocks_in_khz;
1185	clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =
1186			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
1187
1188	clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;
1189	clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =
1190			eng_clks.data[0].clocks_in_khz;
1191	clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =
1192			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
1193	clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz =
1194			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
1195	/* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1196	clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;
1197
1198	clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;
1199	clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =
1200			eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
1201	/* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1202	clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;
1203	clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz =
1204			mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
1205	/* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1206	clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;
1207
1208	/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1209	dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
1210}
1211
1212static const struct resource_caps *dce112_resource_cap(
1213	struct hw_asic_id *asic_id)
1214{
1215	if (ASIC_REV_IS_POLARIS11_M(asic_id->hw_internal_rev) ||
1216	    ASIC_REV_IS_POLARIS12_V(asic_id->hw_internal_rev))
1217		return &polaris_11_resource_cap;
1218	else
1219		return &polaris_10_resource_cap;
1220}
1221
1222static bool dce112_resource_construct(
1223	uint8_t num_virtual_links,
1224	struct dc *dc,
1225	struct dce110_resource_pool *pool)
1226{
1227	unsigned int i;
1228	struct dc_context *ctx = dc->ctx;
1229
1230	ctx->dc_bios->regs = &bios_regs;
1231
1232	pool->base.res_cap = dce112_resource_cap(&ctx->asic_id);
1233	pool->base.funcs = &dce112_res_pool_funcs;
1234
1235	/*************************************************
1236	 *  Resource + asic cap harcoding                *
1237	 *************************************************/
1238	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1239	pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1240	pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
1241	dc->caps.max_downscale_ratio = 200;
1242	dc->caps.i2c_speed_in_khz = 100;
1243	dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/
1244	dc->caps.max_cursor_size = 128;
1245	dc->caps.min_horizontal_blanking_period = 80;
1246	dc->caps.dual_link_dvi = true;
1247	dc->caps.extended_aux_timeout_support = false;
1248	dc->debug = debug_defaults;
1249
1250	/*************************************************
1251	 *  Create resources                             *
1252	 *************************************************/
1253
1254	pool->base.clock_sources[DCE112_CLK_SRC_PLL0] =
1255			dce112_clock_source_create(
1256				ctx, ctx->dc_bios,
1257				CLOCK_SOURCE_COMBO_PHY_PLL0,
1258				&clk_src_regs[0], false);
1259	pool->base.clock_sources[DCE112_CLK_SRC_PLL1] =
1260			dce112_clock_source_create(
1261				ctx, ctx->dc_bios,
1262				CLOCK_SOURCE_COMBO_PHY_PLL1,
1263				&clk_src_regs[1], false);
1264	pool->base.clock_sources[DCE112_CLK_SRC_PLL2] =
1265			dce112_clock_source_create(
1266				ctx, ctx->dc_bios,
1267				CLOCK_SOURCE_COMBO_PHY_PLL2,
1268				&clk_src_regs[2], false);
1269	pool->base.clock_sources[DCE112_CLK_SRC_PLL3] =
1270			dce112_clock_source_create(
1271				ctx, ctx->dc_bios,
1272				CLOCK_SOURCE_COMBO_PHY_PLL3,
1273				&clk_src_regs[3], false);
1274	pool->base.clock_sources[DCE112_CLK_SRC_PLL4] =
1275			dce112_clock_source_create(
1276				ctx, ctx->dc_bios,
1277				CLOCK_SOURCE_COMBO_PHY_PLL4,
1278				&clk_src_regs[4], false);
1279	pool->base.clock_sources[DCE112_CLK_SRC_PLL5] =
1280			dce112_clock_source_create(
1281				ctx, ctx->dc_bios,
1282				CLOCK_SOURCE_COMBO_PHY_PLL5,
1283				&clk_src_regs[5], false);
1284	pool->base.clk_src_count = DCE112_CLK_SRC_TOTAL;
1285
1286	pool->base.dp_clock_source =  dce112_clock_source_create(
1287		ctx, ctx->dc_bios,
1288		CLOCK_SOURCE_ID_DP_DTO, &clk_src_regs[0], true);
1289
1290
1291	for (i = 0; i < pool->base.clk_src_count; i++) {
1292		if (pool->base.clock_sources[i] == NULL) {
1293			dm_error("DC: failed to create clock sources!\n");
1294			BREAK_TO_DEBUGGER();
1295			goto res_create_fail;
1296		}
1297	}
1298
1299	pool->base.dmcu = dce_dmcu_create(ctx,
1300			&dmcu_regs,
1301			&dmcu_shift,
1302			&dmcu_mask);
1303	if (pool->base.dmcu == NULL) {
1304		dm_error("DC: failed to create dmcu!\n");
1305		BREAK_TO_DEBUGGER();
1306		goto res_create_fail;
1307	}
1308
1309	pool->base.abm = dce_abm_create(ctx,
1310			&abm_regs,
1311			&abm_shift,
1312			&abm_mask);
1313	if (pool->base.abm == NULL) {
1314		dm_error("DC: failed to create abm!\n");
1315		BREAK_TO_DEBUGGER();
1316		goto res_create_fail;
1317	}
1318
1319	{
1320		struct irq_service_init_data init_data;
1321		init_data.ctx = dc->ctx;
1322		pool->base.irqs = dal_irq_service_dce110_create(&init_data);
1323		if (!pool->base.irqs)
1324			goto res_create_fail;
1325	}
1326
1327	for (i = 0; i < pool->base.pipe_count; i++) {
1328		pool->base.timing_generators[i] =
1329				dce112_timing_generator_create(
1330					ctx,
1331					i,
1332					&dce112_tg_offsets[i]);
1333		if (pool->base.timing_generators[i] == NULL) {
1334			BREAK_TO_DEBUGGER();
1335			dm_error("DC: failed to create tg!\n");
1336			goto res_create_fail;
1337		}
1338
1339		pool->base.mis[i] = dce112_mem_input_create(ctx, i);
1340		if (pool->base.mis[i] == NULL) {
1341			BREAK_TO_DEBUGGER();
1342			dm_error(
1343				"DC: failed to create memory input!\n");
1344			goto res_create_fail;
1345		}
1346
1347		pool->base.ipps[i] = dce112_ipp_create(ctx, i);
1348		if (pool->base.ipps[i] == NULL) {
1349			BREAK_TO_DEBUGGER();
1350			dm_error(
1351				"DC:failed to create input pixel processor!\n");
1352			goto res_create_fail;
1353		}
1354
1355		pool->base.transforms[i] = dce112_transform_create(ctx, i);
1356		if (pool->base.transforms[i] == NULL) {
1357			BREAK_TO_DEBUGGER();
1358			dm_error(
1359				"DC: failed to create transform!\n");
1360			goto res_create_fail;
1361		}
1362
1363		pool->base.opps[i] = dce112_opp_create(
1364			ctx,
1365			i);
1366		if (pool->base.opps[i] == NULL) {
1367			BREAK_TO_DEBUGGER();
1368			dm_error(
1369				"DC:failed to create output pixel processor!\n");
1370			goto res_create_fail;
1371		}
1372	}
1373
1374	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1375		pool->base.engines[i] = dce112_aux_engine_create(ctx, i);
1376		if (pool->base.engines[i] == NULL) {
1377			BREAK_TO_DEBUGGER();
1378			dm_error(
1379				"DC:failed to create aux engine!!\n");
1380			goto res_create_fail;
1381		}
1382		pool->base.hw_i2cs[i] = dce112_i2c_hw_create(ctx, i);
1383		if (pool->base.hw_i2cs[i] == NULL) {
1384			BREAK_TO_DEBUGGER();
1385			dm_error(
1386				"DC:failed to create i2c engine!!\n");
1387			goto res_create_fail;
1388		}
1389		pool->base.sw_i2cs[i] = NULL;
1390	}
1391
1392	if (!resource_construct(num_virtual_links, dc, &pool->base,
1393			  &res_create_funcs))
1394		goto res_create_fail;
1395
1396	dc->caps.max_planes =  pool->base.pipe_count;
1397
1398	for (i = 0; i < dc->caps.max_planes; ++i)
1399		dc->caps.planes[i] = plane_cap;
1400
1401	/* Create hardware sequencer */
1402	dce112_hw_sequencer_construct(dc);
1403
1404	bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
1405
1406	bw_calcs_data_update_from_pplib(dc);
1407
1408	return true;
1409
1410res_create_fail:
1411	dce112_resource_destruct(pool);
1412	return false;
1413}
1414
1415struct resource_pool *dce112_create_resource_pool(
1416	uint8_t num_virtual_links,
1417	struct dc *dc)
1418{
1419	struct dce110_resource_pool *pool =
1420		kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1421
1422	if (!pool)
1423		return NULL;
1424
1425	if (dce112_resource_construct(num_virtual_links, dc, pool))
1426		return &pool->base;
1427
1428	kfree(pool);
1429	BREAK_TO_DEBUGGER();
1430	return NULL;
1431}
1432