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