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