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