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