]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
drm/amd/display: RV stereo support
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / amd / display / dc / dcn10 / dcn10_resource.c
1 /*
2 * Copyright 2016 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 #include "dc.h"
28
29 #include "resource.h"
30 #include "include/irq_service_interface.h"
31 #include "dcn10/dcn10_resource.h"
32
33 #include "dcn10/dcn10_ipp.h"
34 #include "dcn10/dcn10_mpc.h"
35 #include "irq/dcn10/irq_service_dcn10.h"
36 #include "dcn10/dcn10_transform.h"
37 #include "dcn10/dcn10_timing_generator.h"
38 #include "dcn10/dcn10_hw_sequencer.h"
39 #include "dce110/dce110_hw_sequencer.h"
40 #include "dcn10/dcn10_opp.h"
41 #include "dce/dce_link_encoder.h"
42 #include "dce/dce_stream_encoder.h"
43 #include "dce/dce_clocks.h"
44 #include "dce/dce_clock_source.h"
45 #include "dcn10/dcn10_mem_input.h"
46 #include "dce/dce_audio.h"
47 #include "dce/dce_hwseq.h"
48 #include "../virtual/virtual_stream_encoder.h"
49 #include "dce110/dce110_resource.h"
50
51 #include "vega10/soc15ip.h"
52
53 #include "raven1/DCN/dcn_1_0_offset.h"
54 #include "raven1/DCN/dcn_1_0_sh_mask.h"
55
56 #include "raven1/NBIO/nbio_7_0_offset.h"
57
58 #include "raven1/MMHUB/mmhub_9_1_offset.h"
59 #include "raven1/MMHUB/mmhub_9_1_sh_mask.h"
60
61 #include "reg_helper.h"
62 #include "dce/dce_abm.h"
63 #include "dce/dce_dmcu.h"
64
65 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
66 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
67 #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
68 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
69 #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
70 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
71 #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
72 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
73 #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
74 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
75 #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
76 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f
77 #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
78 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f
79 #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
80 #endif
81
82
83 enum dcn10_clk_src_array_id {
84 DCN10_CLK_SRC_PLL0,
85 DCN10_CLK_SRC_PLL1,
86 DCN10_CLK_SRC_PLL2,
87 DCN10_CLK_SRC_PLL3,
88 DCN10_CLK_SRC_TOTAL
89 };
90
91 /* begin *********************
92 * macros to expend register list macro defined in HW object header file */
93
94 /* DCN */
95 #define BASE_INNER(seg) \
96 DCE_BASE__INST0_SEG ## seg
97
98 #define BASE(seg) \
99 BASE_INNER(seg)
100
101 #define SR(reg_name)\
102 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
103 mm ## reg_name
104
105 #define SRI(reg_name, block, id)\
106 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
107 mm ## block ## id ## _ ## reg_name
108
109
110 #define SRII(reg_name, block, id)\
111 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
112 mm ## block ## id ## _ ## reg_name
113
114 /* NBIO */
115 #define NBIO_BASE_INNER(seg) \
116 NBIF_BASE__INST0_SEG ## seg
117
118 #define NBIO_BASE(seg) \
119 NBIO_BASE_INNER(seg)
120
121 #define NBIO_SR(reg_name)\
122 .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
123 mm ## reg_name
124
125 /* MMHUB */
126 #define MMHUB_BASE_INNER(seg) \
127 MMHUB_BASE__INST0_SEG ## seg
128
129 #define MMHUB_BASE(seg) \
130 MMHUB_BASE_INNER(seg)
131
132 #define MMHUB_SR(reg_name)\
133 .reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) + \
134 mm ## reg_name
135
136 /* macros to expend register list macro defined in HW object header file
137 * end *********************/
138
139 static const struct dce_disp_clk_registers disp_clk_regs = {
140 CLK_DCN10_REG_LIST()
141 };
142
143 static const struct dce_disp_clk_shift disp_clk_shift = {
144 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
145 };
146
147 static const struct dce_disp_clk_mask disp_clk_mask = {
148 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
149 };
150
151 static const struct dce_dmcu_registers dmcu_regs = {
152 DMCU_DCN10_REG_LIST()
153 };
154
155 static const struct dce_dmcu_shift dmcu_shift = {
156 DMCU_MASK_SH_LIST_DCN10(__SHIFT)
157 };
158
159 static const struct dce_dmcu_mask dmcu_mask = {
160 DMCU_MASK_SH_LIST_DCN10(_MASK)
161 };
162
163 static const struct dce_abm_registers abm_regs = {
164 ABM_DCN10_REG_LIST(0)
165 };
166
167 static const struct dce_abm_shift abm_shift = {
168 ABM_MASK_SH_LIST_DCN10(__SHIFT)
169 };
170
171 static const struct dce_abm_mask abm_mask = {
172 ABM_MASK_SH_LIST_DCN10(_MASK)
173 };
174
175 #define stream_enc_regs(id)\
176 [id] = {\
177 SE_DCN_REG_LIST(id),\
178 .TMDS_CNTL = 0,\
179 .AFMT_AVI_INFO0 = 0,\
180 .AFMT_AVI_INFO1 = 0,\
181 .AFMT_AVI_INFO2 = 0,\
182 .AFMT_AVI_INFO3 = 0,\
183 }
184
185 static const struct dce110_stream_enc_registers stream_enc_regs[] = {
186 stream_enc_regs(0),
187 stream_enc_regs(1),
188 stream_enc_regs(2),
189 stream_enc_regs(3),
190 };
191
192 static const struct dce_stream_encoder_shift se_shift = {
193 SE_COMMON_MASK_SH_LIST_DCN10(__SHIFT)
194 };
195
196 static const struct dce_stream_encoder_mask se_mask = {
197 SE_COMMON_MASK_SH_LIST_DCN10(_MASK),
198 .AFMT_GENERIC0_UPDATE = 0,
199 .AFMT_GENERIC2_UPDATE = 0,
200 .DP_DYN_RANGE = 0,
201 .DP_YCBCR_RANGE = 0,
202 .HDMI_AVI_INFO_SEND = 0,
203 .HDMI_AVI_INFO_CONT = 0,
204 .HDMI_AVI_INFO_LINE = 0,
205 .DP_SEC_AVI_ENABLE = 0,
206 .AFMT_AVI_INFO_VERSION = 0
207 };
208
209 #define audio_regs(id)\
210 [id] = {\
211 AUD_COMMON_REG_LIST(id)\
212 }
213
214 static const struct dce_audio_registers audio_regs[] = {
215 audio_regs(0),
216 audio_regs(1),
217 audio_regs(2),
218 audio_regs(3),
219 };
220
221 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
222 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
223 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
224 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
225
226 static const struct dce_audio_shift audio_shift = {
227 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
228 };
229
230 static const struct dce_aduio_mask audio_mask = {
231 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
232 };
233
234 #define aux_regs(id)\
235 [id] = {\
236 AUX_REG_LIST(id)\
237 }
238
239 static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
240 aux_regs(0),
241 aux_regs(1),
242 aux_regs(2),
243 aux_regs(3),
244 aux_regs(4),
245 aux_regs(5)
246 };
247
248 #define hpd_regs(id)\
249 [id] = {\
250 HPD_REG_LIST(id)\
251 }
252
253 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
254 hpd_regs(0),
255 hpd_regs(1),
256 hpd_regs(2),
257 hpd_regs(3),
258 hpd_regs(4),
259 hpd_regs(5)
260 };
261
262 #define link_regs(id)\
263 [id] = {\
264 LE_DCN10_REG_LIST(id), \
265 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
266 }
267
268 static const struct dce110_link_enc_registers link_enc_regs[] = {
269 link_regs(0),
270 link_regs(1),
271 link_regs(2),
272 link_regs(3),
273 link_regs(4),
274 link_regs(5),
275 link_regs(6),
276 };
277
278 #define ipp_regs(id)\
279 [id] = {\
280 IPP_DCN10_REG_LIST(id),\
281 }
282
283 static const struct dcn10_ipp_registers ipp_regs[] = {
284 ipp_regs(0),
285 ipp_regs(1),
286 ipp_regs(2),
287 ipp_regs(3),
288 };
289
290 static const struct dcn10_ipp_shift ipp_shift = {
291 IPP_DCN10_MASK_SH_LIST(__SHIFT)
292 };
293
294 static const struct dcn10_ipp_mask ipp_mask = {
295 IPP_DCN10_MASK_SH_LIST(_MASK),
296 };
297
298 #define opp_regs(id)\
299 [id] = {\
300 OPP_DCN10_REG_LIST(id),\
301 }
302
303 static const struct dcn10_opp_registers opp_regs[] = {
304 opp_regs(0),
305 opp_regs(1),
306 opp_regs(2),
307 opp_regs(3),
308 };
309
310 static const struct dcn10_opp_shift opp_shift = {
311 OPP_DCN10_MASK_SH_LIST(__SHIFT)
312 };
313
314 static const struct dcn10_opp_mask opp_mask = {
315 OPP_DCN10_MASK_SH_LIST(_MASK),
316 };
317
318 #define tf_regs(id)\
319 [id] = {\
320 TF_REG_LIST_DCN(id),\
321 }
322
323 static const struct dcn_transform_registers tf_regs[] = {
324 tf_regs(0),
325 tf_regs(1),
326 tf_regs(2),
327 tf_regs(3),
328 };
329
330 static const struct dcn_transform_shift tf_shift = {
331 TF_REG_LIST_SH_MASK_DCN(__SHIFT)
332 };
333
334 static const struct dcn_transform_mask tf_mask = {
335 TF_REG_LIST_SH_MASK_DCN(_MASK),
336 };
337
338
339 #define mpcc_regs(id)\
340 [id] = {\
341 MPCC_COMMON_REG_LIST_DCN1_0(id),\
342 MPC_COMMON_REG_LIST_DCN1_0(0),\
343 MPC_COMMON_REG_LIST_DCN1_0(1),\
344 MPC_COMMON_REG_LIST_DCN1_0(2),\
345 MPC_COMMON_REG_LIST_DCN1_0(3),\
346 }
347
348 static const struct dcn_mpcc_registers mpcc_regs[] = {
349 mpcc_regs(0),
350 mpcc_regs(1),
351 mpcc_regs(2),
352 mpcc_regs(3),
353 };
354
355 static const struct dcn_mpcc_shift mpcc_shift = {
356 MPCC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
357 };
358
359 static const struct dcn_mpcc_mask mpcc_mask = {
360 MPCC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),
361 };
362
363 #define tg_regs(id)\
364 [id] = {TG_COMMON_REG_LIST_DCN1_0(id)}
365
366 static const struct dcn_tg_registers tg_regs[] = {
367 tg_regs(0),
368 tg_regs(1),
369 tg_regs(2),
370 tg_regs(3),
371 };
372
373 static const struct dcn_tg_shift tg_shift = {
374 TG_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
375 };
376
377 static const struct dcn_tg_mask tg_mask = {
378 TG_COMMON_MASK_SH_LIST_DCN1_0(_MASK)
379 };
380
381
382 static const struct bios_registers bios_regs = {
383 NBIO_SR(BIOS_SCRATCH_6)
384 };
385
386 #define mi_regs(id)\
387 [id] = {\
388 MI_DCN10_REG_LIST(id)\
389 }
390
391
392 static const struct dcn_mi_registers mi_regs[] = {
393 mi_regs(0),
394 mi_regs(1),
395 mi_regs(2),
396 mi_regs(3),
397 };
398
399 static const struct dcn_mi_shift mi_shift = {
400 MI_DCN10_MASK_SH_LIST(__SHIFT)
401 };
402
403 static const struct dcn_mi_mask mi_mask = {
404 MI_DCN10_MASK_SH_LIST(_MASK)
405 };
406
407 #define clk_src_regs(index, pllid)\
408 [index] = {\
409 CS_COMMON_REG_LIST_DCN1_0(index, pllid),\
410 }
411
412 static const struct dce110_clk_src_regs clk_src_regs[] = {
413 clk_src_regs(0, A),
414 clk_src_regs(1, B),
415 clk_src_regs(2, C),
416 clk_src_regs(3, D)
417 };
418
419 static const struct dce110_clk_src_shift cs_shift = {
420 CS_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
421 };
422
423 static const struct dce110_clk_src_mask cs_mask = {
424 CS_COMMON_MASK_SH_LIST_DCN1_0(_MASK)
425 };
426
427
428 static const struct resource_caps res_cap = {
429 .num_timing_generator = 4,
430 .num_video_plane = 4,
431 .num_audio = 4,
432 .num_stream_encoder = 4,
433 .num_pll = 4,
434 };
435
436 static const struct dc_debug debug_defaults_drv = {
437 .disable_dcc = false,
438 .disable_dmcu = true,
439 .force_abm_enable = false,
440 .timing_trace = false,
441 .clock_trace = true,
442 .disable_pplib_clock_request = true,
443 .disable_pplib_wm_range = false,
444 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
445 .use_dml_wm = false,
446 .use_max_voltage = false
447 #endif
448 };
449
450 static const struct dc_debug debug_defaults_diags = {
451 .disable_dmcu = true,
452 .force_abm_enable = false,
453 .timing_trace = true,
454 .clock_trace = true,
455 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
456 .disable_pplib_clock_request = true,
457 .disable_pplib_wm_range = true,
458 .use_dml_wm = false,
459 .use_max_voltage = false
460 #endif
461 };
462
463 static void dcn10_transform_destroy(struct transform **xfm)
464 {
465 dm_free(TO_DCN10_TRANSFORM(*xfm));
466 *xfm = NULL;
467 }
468
469 static struct transform *dcn10_transform_create(
470 struct dc_context *ctx,
471 uint32_t inst)
472 {
473 struct dcn10_transform *transform =
474 dm_alloc(sizeof(struct dcn10_transform));
475
476 if (!transform)
477 return NULL;
478
479 if (dcn10_transform_construct(transform, ctx,
480 &tf_regs[inst], &tf_shift, &tf_mask))
481 return &transform->base;
482
483 BREAK_TO_DEBUGGER();
484 dm_free(transform);
485 return NULL;
486 }
487
488 static struct input_pixel_processor *dcn10_ipp_create(
489 struct dc_context *ctx, uint32_t inst)
490 {
491 struct dcn10_ipp *ipp =
492 dm_alloc(sizeof(struct dcn10_ipp));
493
494 if (!ipp) {
495 BREAK_TO_DEBUGGER();
496 return NULL;
497 }
498
499 dcn10_ipp_construct(ipp, ctx, inst,
500 &ipp_regs[inst], &ipp_shift, &ipp_mask);
501 return &ipp->base;
502 }
503
504
505 static struct output_pixel_processor *dcn10_opp_create(
506 struct dc_context *ctx, uint32_t inst)
507 {
508 struct dcn10_opp *opp =
509 dm_alloc(sizeof(struct dcn10_opp));
510
511 if (!opp) {
512 BREAK_TO_DEBUGGER();
513 return NULL;
514 }
515
516 dcn10_opp_construct(opp, ctx, inst,
517 &opp_regs[inst], &opp_shift, &opp_mask);
518 return &opp->base;
519 }
520
521 static struct mpcc *dcn10_mpcc_create(
522 struct dc_context *ctx,
523 int inst)
524 {
525 struct dcn10_mpcc *mpcc10 = dm_alloc(sizeof(struct dcn10_mpcc));
526
527 if (!mpcc10)
528 return NULL;
529
530 dcn10_mpcc_construct(mpcc10, ctx,
531 &mpcc_regs[inst],
532 &mpcc_shift,
533 &mpcc_mask,
534 inst);
535
536 return &mpcc10->base;
537 }
538
539 static struct timing_generator *dcn10_timing_generator_create(
540 struct dc_context *ctx,
541 uint32_t instance)
542 {
543 struct dcn10_timing_generator *tgn10 =
544 dm_alloc(sizeof(struct dcn10_timing_generator));
545
546 if (!tgn10)
547 return NULL;
548
549 tgn10->base.inst = instance;
550 tgn10->base.ctx = ctx;
551
552 tgn10->tg_regs = &tg_regs[instance];
553 tgn10->tg_shift = &tg_shift;
554 tgn10->tg_mask = &tg_mask;
555
556 dcn10_timing_generator_init(tgn10);
557
558 return &tgn10->base;
559 }
560
561 static const struct encoder_feature_support link_enc_feature = {
562 .max_hdmi_deep_color = COLOR_DEPTH_121212,
563 .max_hdmi_pixel_clock = 600000,
564 .ycbcr420_supported = true,
565 .flags.bits.IS_HBR2_CAPABLE = true,
566 .flags.bits.IS_HBR3_CAPABLE = true,
567 .flags.bits.IS_TPS3_CAPABLE = true,
568 .flags.bits.IS_TPS4_CAPABLE = true,
569 .flags.bits.IS_YCBCR_CAPABLE = true
570 };
571
572 struct link_encoder *dcn10_link_encoder_create(
573 const struct encoder_init_data *enc_init_data)
574 {
575 struct dce110_link_encoder *enc110 =
576 dm_alloc(sizeof(struct dce110_link_encoder));
577
578 if (!enc110)
579 return NULL;
580
581 if (dce110_link_encoder_construct(
582 enc110,
583 enc_init_data,
584 &link_enc_feature,
585 &link_enc_regs[enc_init_data->transmitter],
586 &link_enc_aux_regs[enc_init_data->channel - 1],
587 &link_enc_hpd_regs[enc_init_data->hpd_source])) {
588
589 return &enc110->base;
590 }
591
592 BREAK_TO_DEBUGGER();
593 dm_free(enc110);
594 return NULL;
595 }
596
597 struct clock_source *dcn10_clock_source_create(
598 struct dc_context *ctx,
599 struct dc_bios *bios,
600 enum clock_source_id id,
601 const struct dce110_clk_src_regs *regs,
602 bool dp_clk_src)
603 {
604 struct dce110_clk_src *clk_src =
605 dm_alloc(sizeof(struct dce110_clk_src));
606
607 if (!clk_src)
608 return NULL;
609
610 if (dce110_clk_src_construct(clk_src, ctx, bios, id,
611 regs, &cs_shift, &cs_mask)) {
612 clk_src->base.dp_clk_src = dp_clk_src;
613 return &clk_src->base;
614 }
615
616 BREAK_TO_DEBUGGER();
617 return NULL;
618 }
619
620 static void read_dce_straps(
621 struct dc_context *ctx,
622 struct resource_straps *straps)
623 {
624 /* TODO: Registers are missing */
625 /*REG_GET_2(CC_DC_HDMI_STRAPS,
626 HDMI_DISABLE, &straps->hdmi_disable,
627 AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
628
629 REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);*/
630 }
631
632 static struct audio *create_audio(
633 struct dc_context *ctx, unsigned int inst)
634 {
635 return dce_audio_create(ctx, inst,
636 &audio_regs[inst], &audio_shift, &audio_mask);
637 }
638
639 static struct stream_encoder *dcn10_stream_encoder_create(
640 enum engine_id eng_id,
641 struct dc_context *ctx)
642 {
643 struct dce110_stream_encoder *enc110 =
644 dm_alloc(sizeof(struct dce110_stream_encoder));
645
646 if (!enc110)
647 return NULL;
648
649 if (dce110_stream_encoder_construct(
650 enc110, ctx, ctx->dc_bios, eng_id,
651 &stream_enc_regs[eng_id], &se_shift, &se_mask))
652 return &enc110->base;
653
654 BREAK_TO_DEBUGGER();
655 dm_free(enc110);
656 return NULL;
657 }
658
659 static const struct dce_hwseq_registers hwseq_reg = {
660 HWSEQ_DCN1_REG_LIST()
661 };
662
663 static const struct dce_hwseq_shift hwseq_shift = {
664 HWSEQ_DCN1_MASK_SH_LIST(__SHIFT)
665 };
666
667 static const struct dce_hwseq_mask hwseq_mask = {
668 HWSEQ_DCN1_MASK_SH_LIST(_MASK)
669 };
670
671 static struct dce_hwseq *dcn10_hwseq_create(
672 struct dc_context *ctx)
673 {
674 struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq));
675
676 if (hws) {
677 hws->ctx = ctx;
678 hws->regs = &hwseq_reg;
679 hws->shifts = &hwseq_shift;
680 hws->masks = &hwseq_mask;
681 }
682 return hws;
683 }
684
685 static const struct resource_create_funcs res_create_funcs = {
686 .read_dce_straps = read_dce_straps,
687 .create_audio = create_audio,
688 .create_stream_encoder = dcn10_stream_encoder_create,
689 .create_hwseq = dcn10_hwseq_create,
690 };
691
692 static const struct resource_create_funcs res_create_maximus_funcs = {
693 .read_dce_straps = NULL,
694 .create_audio = NULL,
695 .create_stream_encoder = NULL,
696 .create_hwseq = dcn10_hwseq_create,
697 };
698
699 void dcn10_clock_source_destroy(struct clock_source **clk_src)
700 {
701 dm_free(TO_DCE110_CLK_SRC(*clk_src));
702 *clk_src = NULL;
703 }
704
705 static void destruct(struct dcn10_resource_pool *pool)
706 {
707 unsigned int i;
708
709 for (i = 0; i < pool->base.stream_enc_count; i++) {
710 if (pool->base.stream_enc[i] != NULL) {
711 /* TODO: free dcn version of stream encoder once implemented
712 * rather than using virtual stream encoder
713 */
714 dm_free(pool->base.stream_enc[i]);
715 pool->base.stream_enc[i] = NULL;
716 }
717 }
718
719 for (i = 0; i < pool->base.pipe_count; i++) {
720 if (pool->base.opps[i] != NULL)
721 pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
722
723 if (pool->base.transforms[i] != NULL)
724 dcn10_transform_destroy(&pool->base.transforms[i]);
725
726 if (pool->base.ipps[i] != NULL)
727 pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
728
729 if (pool->base.mis[i] != NULL) {
730 dm_free(TO_DCN10_MEM_INPUT(pool->base.mis[i]));
731 pool->base.mis[i] = NULL;
732 }
733
734 if (pool->base.irqs != NULL) {
735 dal_irq_service_destroy(&pool->base.irqs);
736 }
737
738 if (pool->base.timing_generators[i] != NULL) {
739 dm_free(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
740 pool->base.timing_generators[i] = NULL;
741 }
742
743 if (pool->base.mpcc[i] != NULL) {
744 dm_free(TO_DCN10_MPCC(pool->base.mpcc[i]));
745 pool->base.mpcc[i] = NULL;
746 }
747 }
748
749 for (i = 0; i < pool->base.stream_enc_count; i++) {
750 if (pool->base.stream_enc[i] != NULL)
751 dm_free(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
752 }
753
754 for (i = 0; i < pool->base.audio_count; i++) {
755 if (pool->base.audios[i])
756 dce_aud_destroy(&pool->base.audios[i]);
757 }
758
759 for (i = 0; i < pool->base.clk_src_count; i++) {
760 if (pool->base.clock_sources[i] != NULL) {
761 dcn10_clock_source_destroy(&pool->base.clock_sources[i]);
762 pool->base.clock_sources[i] = NULL;
763 }
764 }
765
766 if (pool->base.dp_clock_source != NULL) {
767 dcn10_clock_source_destroy(&pool->base.dp_clock_source);
768 pool->base.dp_clock_source = NULL;
769 }
770
771 if (pool->base.abm != NULL)
772 dce_abm_destroy(&pool->base.abm);
773
774 if (pool->base.dmcu != NULL)
775 dce_dmcu_destroy(&pool->base.dmcu);
776
777 if (pool->base.display_clock != NULL)
778 dce_disp_clk_destroy(&pool->base.display_clock);
779 }
780
781 static struct mem_input *dcn10_mem_input_create(
782 struct dc_context *ctx,
783 uint32_t inst)
784 {
785 struct dcn10_mem_input *mem_inputn10 =
786 dm_alloc(sizeof(struct dcn10_mem_input));
787
788 if (!mem_inputn10)
789 return NULL;
790
791 if (dcn10_mem_input_construct(mem_inputn10, ctx, inst,
792 &mi_regs[inst], &mi_shift, &mi_mask))
793 return &mem_inputn10->base;
794
795 BREAK_TO_DEBUGGER();
796 dm_free(mem_inputn10);
797 return NULL;
798 }
799
800 static void get_pixel_clock_parameters(
801 const struct pipe_ctx *pipe_ctx,
802 struct pixel_clk_params *pixel_clk_params)
803 {
804 const struct core_stream *stream = pipe_ctx->stream;
805 pixel_clk_params->requested_pix_clk = stream->public.timing.pix_clk_khz;
806 pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id;
807 pixel_clk_params->signal_type = pipe_ctx->stream->signal;
808 pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1;
809 /* TODO: un-hardcode*/
810 pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
811 LINK_RATE_REF_FREQ_IN_KHZ;
812 pixel_clk_params->flags.ENABLE_SS = 0;
813 pixel_clk_params->color_depth =
814 stream->public.timing.display_color_depth;
815 pixel_clk_params->flags.DISPLAY_BLANKED = 1;
816 pixel_clk_params->pixel_encoding = stream->public.timing.pixel_encoding;
817
818 if (stream->public.timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
819 pixel_clk_params->color_depth = COLOR_DEPTH_888;
820
821 if (stream->public.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
822 pixel_clk_params->requested_pix_clk /= 2;
823
824 }
825
826 static void build_clamping_params(struct core_stream *stream)
827 {
828 stream->clamping.clamping_level = CLAMPING_FULL_RANGE;
829 stream->clamping.c_depth = stream->public.timing.display_color_depth;
830 stream->clamping.pixel_encoding = stream->public.timing.pixel_encoding;
831 }
832
833 static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
834 {
835
836 get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->pix_clk_params);
837
838 pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
839 pipe_ctx->clock_source,
840 &pipe_ctx->pix_clk_params,
841 &pipe_ctx->pll_settings);
842
843 pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->public.timing.pixel_encoding;
844
845 resource_build_bit_depth_reduction_params(pipe_ctx->stream,
846 &pipe_ctx->stream->bit_depth_params);
847 build_clamping_params(pipe_ctx->stream);
848
849 return DC_OK;
850 }
851
852 static enum dc_status validate_mapped_resource(
853 const struct core_dc *dc,
854 struct validate_context *context,
855 struct validate_context *old_context)
856 {
857 enum dc_status status = DC_OK;
858 uint8_t i, j;
859
860 for (i = 0; i < context->stream_count; i++) {
861 struct core_stream *stream = context->streams[i];
862 struct core_link *link = stream->sink->link;
863
864 if (old_context && resource_is_stream_unchanged(old_context, stream)) {
865 if (stream != NULL && old_context->streams[i] != NULL) {
866 /* todo: shouldn't have to copy missing parameter here */
867 resource_build_bit_depth_reduction_params(stream,
868 &stream->bit_depth_params);
869 stream->clamping.pixel_encoding =
870 stream->public.timing.pixel_encoding;
871
872 resource_build_bit_depth_reduction_params(stream,
873 &stream->bit_depth_params);
874 build_clamping_params(stream);
875
876 continue;
877 }
878 }
879
880 for (j = 0; j < dc->res_pool->pipe_count ; j++) {
881 struct pipe_ctx *pipe_ctx =
882 &context->res_ctx.pipe_ctx[j];
883
884 if (context->res_ctx.pipe_ctx[j].stream != stream)
885 continue;
886
887
888 if (!pipe_ctx->tg->funcs->validate_timing(
889 pipe_ctx->tg, &stream->public.timing))
890 return DC_FAIL_CONTROLLER_VALIDATE;
891
892 status = build_pipe_hw_param(pipe_ctx);
893
894 if (status != DC_OK)
895 return status;
896
897 if (!link->link_enc->funcs->validate_output_with_stream(
898 link->link_enc, pipe_ctx))
899 return DC_FAIL_ENC_VALIDATE;
900
901 /* TODO: validate audio ASIC caps, encoder */
902
903 status = dc_link_validate_mode_timing(
904 stream, link, &stream->public.timing);
905
906 if (status != DC_OK)
907 return status;
908
909
910 /* do not need to validate non root pipes */
911 break;
912 }
913 }
914
915 return DC_OK;
916 }
917
918 enum dc_status dcn10_validate_with_context(
919 const struct core_dc *dc,
920 const struct dc_validation_set set[],
921 int set_count,
922 struct validate_context *context,
923 struct validate_context *old_context)
924 {
925 enum dc_status result = DC_OK;
926 int i;
927
928 if (set_count == 0)
929 return result;
930
931 for (i = 0; i < set_count; i++) {
932 context->streams[i] = DC_STREAM_TO_CORE(set[i].stream);
933 dc_stream_retain(&context->streams[i]->public);
934 context->stream_count++;
935 }
936
937 result = resource_map_pool_resources(dc, context, old_context);
938 if (result != DC_OK)
939 return result;
940
941 result = resource_map_phy_clock_resources(dc, context, old_context);
942 if (result != DC_OK)
943 return result;
944
945 result = validate_mapped_resource(dc, context, old_context);
946 if (result != DC_OK)
947 return result;
948
949 if (!resource_validate_attach_surfaces(set, set_count,
950 old_context, context, dc->res_pool))
951 return DC_FAIL_ATTACH_SURFACES;
952
953 result = resource_build_scaling_params_for_context(dc, context);
954 if (result != DC_OK)
955 return result;
956
957 if (!dcn_validate_bandwidth(dc, context))
958 return DC_FAIL_BANDWIDTH_VALIDATE;
959
960 return result;
961 }
962
963 enum dc_status dcn10_validate_guaranteed(
964 const struct core_dc *dc,
965 const struct dc_stream *dc_stream,
966 struct validate_context *context)
967 {
968 enum dc_status result = DC_ERROR_UNEXPECTED;
969
970 context->streams[0] = DC_STREAM_TO_CORE(dc_stream);
971 dc_stream_retain(&context->streams[0]->public);
972 context->stream_count++;
973
974 result = resource_map_pool_resources(dc, context, NULL);
975
976 if (result == DC_OK)
977 result = resource_map_phy_clock_resources(dc, context, NULL);
978
979 if (result == DC_OK)
980 result = validate_mapped_resource(dc, context, NULL);
981
982 if (result == DC_OK) {
983 validate_guaranteed_copy_streams(
984 context, dc->public.caps.max_streams);
985 result = resource_build_scaling_params_for_context(dc, context);
986 }
987 if (result == DC_OK && !dcn_validate_bandwidth(dc, context))
988 return DC_FAIL_BANDWIDTH_VALIDATE;
989
990 return result;
991 }
992
993 static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
994 struct validate_context *context,
995 const struct resource_pool *pool,
996 struct core_stream *stream)
997 {
998 struct resource_context *res_ctx = &context->res_ctx;
999 struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream);
1000 struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool);
1001
1002 if (!head_pipe)
1003 ASSERT(0);
1004
1005 if (!idle_pipe)
1006 return false;
1007
1008 idle_pipe->stream = head_pipe->stream;
1009 idle_pipe->tg = head_pipe->tg;
1010
1011 idle_pipe->mpcc = pool->mpcc[idle_pipe->pipe_idx];
1012 idle_pipe->mi = pool->mis[idle_pipe->pipe_idx];
1013 idle_pipe->ipp = pool->ipps[idle_pipe->pipe_idx];
1014 idle_pipe->xfm = pool->transforms[idle_pipe->pipe_idx];
1015 idle_pipe->opp = pool->opps[idle_pipe->pipe_idx];
1016
1017 return idle_pipe;
1018 }
1019
1020 enum dcc_control {
1021 dcc_control__256_256_xxx,
1022 dcc_control__128_128_xxx,
1023 dcc_control__256_64_64,
1024 };
1025
1026 enum segment_order {
1027 segment_order__na,
1028 segment_order__contiguous,
1029 segment_order__non_contiguous,
1030 };
1031
1032 static bool dcc_support_pixel_format(
1033 enum surface_pixel_format format,
1034 unsigned int *bytes_per_element)
1035 {
1036 /* DML: get_bytes_per_element */
1037 switch (format) {
1038 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
1039 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
1040 *bytes_per_element = 2;
1041 return true;
1042 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
1043 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
1044 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
1045 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
1046 *bytes_per_element = 4;
1047 return true;
1048 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
1049 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
1050 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
1051 *bytes_per_element = 8;
1052 return true;
1053 default:
1054 return false;
1055 }
1056 }
1057
1058 static bool dcc_support_swizzle(
1059 enum swizzle_mode_values swizzle,
1060 unsigned int bytes_per_element,
1061 enum segment_order *segment_order_horz,
1062 enum segment_order *segment_order_vert)
1063 {
1064 bool standard_swizzle = false;
1065 bool display_swizzle = false;
1066
1067 switch (swizzle) {
1068 case DC_SW_4KB_S:
1069 case DC_SW_64KB_S:
1070 case DC_SW_VAR_S:
1071 case DC_SW_4KB_S_X:
1072 case DC_SW_64KB_S_X:
1073 case DC_SW_VAR_S_X:
1074 standard_swizzle = true;
1075 break;
1076 case DC_SW_4KB_D:
1077 case DC_SW_64KB_D:
1078 case DC_SW_VAR_D:
1079 case DC_SW_4KB_D_X:
1080 case DC_SW_64KB_D_X:
1081 case DC_SW_VAR_D_X:
1082 display_swizzle = true;
1083 break;
1084 default:
1085 break;
1086 }
1087
1088 if (bytes_per_element == 1 && standard_swizzle) {
1089 *segment_order_horz = segment_order__contiguous;
1090 *segment_order_vert = segment_order__na;
1091 return true;
1092 }
1093 if (bytes_per_element == 2 && standard_swizzle) {
1094 *segment_order_horz = segment_order__non_contiguous;
1095 *segment_order_vert = segment_order__contiguous;
1096 return true;
1097 }
1098 if (bytes_per_element == 4 && standard_swizzle) {
1099 *segment_order_horz = segment_order__non_contiguous;
1100 *segment_order_vert = segment_order__contiguous;
1101 return true;
1102 }
1103 if (bytes_per_element == 8 && standard_swizzle) {
1104 *segment_order_horz = segment_order__na;
1105 *segment_order_vert = segment_order__contiguous;
1106 return true;
1107 }
1108 if (bytes_per_element == 8 && display_swizzle) {
1109 *segment_order_horz = segment_order__contiguous;
1110 *segment_order_vert = segment_order__non_contiguous;
1111 return true;
1112 }
1113
1114 return false;
1115 }
1116
1117 static void get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height,
1118 unsigned int bytes_per_element)
1119 {
1120 /* copied from DML. might want to refactor DML to leverage from DML */
1121 /* DML : get_blk256_size */
1122 if (bytes_per_element == 1) {
1123 *blk256_width = 16;
1124 *blk256_height = 16;
1125 } else if (bytes_per_element == 2) {
1126 *blk256_width = 16;
1127 *blk256_height = 8;
1128 } else if (bytes_per_element == 4) {
1129 *blk256_width = 8;
1130 *blk256_height = 8;
1131 } else if (bytes_per_element == 8) {
1132 *blk256_width = 8;
1133 *blk256_height = 4;
1134 }
1135 }
1136
1137 static void det_request_size(
1138 unsigned int height,
1139 unsigned int width,
1140 unsigned int bpe,
1141 bool *req128_horz_wc,
1142 bool *req128_vert_wc)
1143 {
1144 unsigned int detile_buf_size = 164 * 1024; /* 164KB for DCN1.0 */
1145
1146 unsigned int blk256_height = 0;
1147 unsigned int blk256_width = 0;
1148 unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
1149
1150 get_blk256_size(&blk256_width, &blk256_height, bpe);
1151
1152 swath_bytes_horz_wc = height * blk256_height * bpe;
1153 swath_bytes_vert_wc = width * blk256_width * bpe;
1154
1155 *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ?
1156 false : /* full 256B request */
1157 true; /* half 128b request */
1158
1159 *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ?
1160 false : /* full 256B request */
1161 true; /* half 128b request */
1162 }
1163
1164 static bool get_dcc_compression_cap(const struct dc *dc,
1165 const struct dc_dcc_surface_param *input,
1166 struct dc_surface_dcc_cap *output)
1167 {
1168 /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */
1169 enum dcc_control dcc_control;
1170 unsigned int bpe;
1171 enum segment_order segment_order_horz, segment_order_vert;
1172 bool req128_horz_wc, req128_vert_wc;
1173
1174 memset(output, 0, sizeof(*output));
1175
1176 if (dc->debug.disable_dcc)
1177 return false;
1178
1179 if (!dcc_support_pixel_format(input->format,
1180 &bpe))
1181 return false;
1182
1183 if (!dcc_support_swizzle(input->swizzle_mode, bpe,
1184 &segment_order_horz, &segment_order_vert))
1185 return false;
1186
1187 det_request_size(input->surface_size.height, input->surface_size.width,
1188 bpe, &req128_horz_wc, &req128_vert_wc);
1189
1190 if (!req128_horz_wc && !req128_vert_wc) {
1191 dcc_control = dcc_control__256_256_xxx;
1192 } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) {
1193 if (!req128_horz_wc)
1194 dcc_control = dcc_control__256_256_xxx;
1195 else if (segment_order_horz == segment_order__contiguous)
1196 dcc_control = dcc_control__128_128_xxx;
1197 else
1198 dcc_control = dcc_control__256_64_64;
1199 } else if (input->scan == SCAN_DIRECTION_VERTICAL) {
1200 if (!req128_vert_wc)
1201 dcc_control = dcc_control__256_256_xxx;
1202 else if (segment_order_vert == segment_order__contiguous)
1203 dcc_control = dcc_control__128_128_xxx;
1204 else
1205 dcc_control = dcc_control__256_64_64;
1206 } else {
1207 if ((req128_horz_wc &&
1208 segment_order_horz == segment_order__non_contiguous) ||
1209 (req128_vert_wc &&
1210 segment_order_vert == segment_order__non_contiguous))
1211 /* access_dir not known, must use most constraining */
1212 dcc_control = dcc_control__256_64_64;
1213 else
1214 /* reg128 is true for either horz and vert
1215 * but segment_order is contiguous
1216 */
1217 dcc_control = dcc_control__128_128_xxx;
1218 }
1219
1220 switch (dcc_control) {
1221 case dcc_control__256_256_xxx:
1222 output->grph.rgb.max_uncompressed_blk_size = 256;
1223 output->grph.rgb.max_compressed_blk_size = 256;
1224 output->grph.rgb.independent_64b_blks = false;
1225 break;
1226 case dcc_control__128_128_xxx:
1227 output->grph.rgb.max_uncompressed_blk_size = 128;
1228 output->grph.rgb.max_compressed_blk_size = 128;
1229 output->grph.rgb.independent_64b_blks = false;
1230 break;
1231 case dcc_control__256_64_64:
1232 output->grph.rgb.max_uncompressed_blk_size = 256;
1233 output->grph.rgb.max_compressed_blk_size = 64;
1234 output->grph.rgb.independent_64b_blks = true;
1235 break;
1236 }
1237 output->capable = true;
1238 output->const_color_support = false;
1239
1240 return true;
1241 }
1242
1243
1244 static void dcn10_destroy_resource_pool(struct resource_pool **pool)
1245 {
1246 struct dcn10_resource_pool *dcn10_pool = TO_DCN10_RES_POOL(*pool);
1247
1248 destruct(dcn10_pool);
1249 dm_free(dcn10_pool);
1250 *pool = NULL;
1251 }
1252
1253
1254 static struct dc_cap_funcs cap_funcs = {
1255 .get_dcc_compression_cap = get_dcc_compression_cap
1256 };
1257
1258 static struct resource_funcs dcn10_res_pool_funcs = {
1259 .destroy = dcn10_destroy_resource_pool,
1260 .link_enc_create = dcn10_link_encoder_create,
1261 .validate_with_context = dcn10_validate_with_context,
1262 .validate_guaranteed = dcn10_validate_guaranteed,
1263 .validate_bandwidth = dcn_validate_bandwidth,
1264 .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
1265 };
1266
1267 static bool construct(
1268 uint8_t num_virtual_links,
1269 struct core_dc *dc,
1270 struct dcn10_resource_pool *pool)
1271 {
1272 int i;
1273 struct dc_context *ctx = dc->ctx;
1274
1275 ctx->dc_bios->regs = &bios_regs;
1276
1277 pool->base.res_cap = &res_cap;
1278 pool->base.funcs = &dcn10_res_pool_funcs;
1279
1280 /*
1281 * TODO fill in from actual raven resource when we create
1282 * more than virtual encoder
1283 */
1284
1285 /*************************************************
1286 * Resource + asic cap harcoding *
1287 *************************************************/
1288 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1289
1290 /* TODO: Hardcode to correct number of functional controllers */
1291 pool->base.pipe_count = 4;
1292 dc->public.caps.max_downscale_ratio = 200;
1293 dc->public.caps.i2c_speed_in_khz = 100;
1294 dc->public.caps.max_cursor_size = 256;
1295
1296 dc->public.caps.max_slave_planes = 1;
1297
1298 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
1299 dc->public.debug = debug_defaults_drv;
1300 else
1301 dc->public.debug = debug_defaults_diags;
1302
1303 /*************************************************
1304 * Create resources *
1305 *************************************************/
1306
1307 pool->base.clock_sources[DCN10_CLK_SRC_PLL0] =
1308 dcn10_clock_source_create(ctx, ctx->dc_bios,
1309 CLOCK_SOURCE_COMBO_PHY_PLL0,
1310 &clk_src_regs[0], false);
1311 pool->base.clock_sources[DCN10_CLK_SRC_PLL1] =
1312 dcn10_clock_source_create(ctx, ctx->dc_bios,
1313 CLOCK_SOURCE_COMBO_PHY_PLL1,
1314 &clk_src_regs[1], false);
1315 pool->base.clock_sources[DCN10_CLK_SRC_PLL2] =
1316 dcn10_clock_source_create(ctx, ctx->dc_bios,
1317 CLOCK_SOURCE_COMBO_PHY_PLL2,
1318 &clk_src_regs[2], false);
1319 pool->base.clock_sources[DCN10_CLK_SRC_PLL3] =
1320 dcn10_clock_source_create(ctx, ctx->dc_bios,
1321 CLOCK_SOURCE_COMBO_PHY_PLL3,
1322 &clk_src_regs[3], false);
1323
1324 pool->base.clk_src_count = DCN10_CLK_SRC_TOTAL;
1325
1326 pool->base.dp_clock_source =
1327 dcn10_clock_source_create(ctx, ctx->dc_bios,
1328 CLOCK_SOURCE_ID_DP_DTO,
1329 /* todo: not reuse phy_pll registers */
1330 &clk_src_regs[0], true);
1331
1332 for (i = 0; i < pool->base.clk_src_count; i++) {
1333 if (pool->base.clock_sources[i] == NULL) {
1334 dm_error("DC: failed to create clock sources!\n");
1335 BREAK_TO_DEBUGGER();
1336 goto clock_source_create_fail;
1337 }
1338 }
1339
1340 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
1341 pool->base.display_clock = dce120_disp_clk_create(ctx,
1342 &disp_clk_regs,
1343 &disp_clk_shift,
1344 &disp_clk_mask);
1345 if (pool->base.display_clock == NULL) {
1346 dm_error("DC: failed to create display clock!\n");
1347 BREAK_TO_DEBUGGER();
1348 goto disp_clk_create_fail;
1349 }
1350 }
1351
1352 pool->base.dmcu = dcn10_dmcu_create(ctx,
1353 &dmcu_regs,
1354 &dmcu_shift,
1355 &dmcu_mask);
1356 if (pool->base.dmcu == NULL) {
1357 dm_error("DC: failed to create dmcu!\n");
1358 BREAK_TO_DEBUGGER();
1359 goto res_create_fail;
1360 }
1361
1362 pool->base.abm = dce_abm_create(ctx,
1363 &abm_regs,
1364 &abm_shift,
1365 &abm_mask);
1366 if (pool->base.abm == NULL) {
1367 dm_error("DC: failed to create abm!\n");
1368 BREAK_TO_DEBUGGER();
1369 goto res_create_fail;
1370 }
1371
1372 dml_init_instance(&dc->dml, DML_PROJECT_RAVEN1);
1373 dc->dcn_ip = dcn10_ip_defaults;
1374 dc->dcn_soc = dcn10_soc_defaults;
1375 if (!dc->public.debug.disable_pplib_clock_request)
1376 dcn_bw_update_from_pplib(dc);
1377 dcn_bw_sync_calcs_and_dml(dc);
1378 if (!dc->public.debug.disable_pplib_wm_range)
1379 dcn_bw_notify_pplib_of_wm_ranges(dc);
1380
1381 {
1382 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
1383 struct irq_service_init_data init_data;
1384 init_data.ctx = dc->ctx;
1385 pool->base.irqs = dal_irq_service_dcn10_create(&init_data);
1386 if (!pool->base.irqs)
1387 goto irqs_create_fail;
1388 #endif
1389 }
1390
1391 /* mem input -> ipp -> transform -> opp -> TG */
1392 for (i = 0; i < pool->base.pipe_count; i++) {
1393 pool->base.mis[i] = dcn10_mem_input_create(ctx, i);
1394 if (pool->base.mis[i] == NULL) {
1395 BREAK_TO_DEBUGGER();
1396 dm_error(
1397 "DC: failed to create memory input!\n");
1398 goto mi_create_fail;
1399 }
1400
1401 pool->base.ipps[i] = dcn10_ipp_create(ctx, i);
1402 if (pool->base.ipps[i] == NULL) {
1403 BREAK_TO_DEBUGGER();
1404 dm_error(
1405 "DC: failed to create input pixel processor!\n");
1406 goto ipp_create_fail;
1407 }
1408
1409 pool->base.transforms[i] = dcn10_transform_create(ctx, i);
1410 if (pool->base.transforms[i] == NULL) {
1411 BREAK_TO_DEBUGGER();
1412 dm_error(
1413 "DC: failed to create transform!\n");
1414 goto transform_create_fail;
1415 }
1416
1417 pool->base.opps[i] = dcn10_opp_create(ctx, i);
1418 if (pool->base.opps[i] == NULL) {
1419 BREAK_TO_DEBUGGER();
1420 dm_error(
1421 "DC: failed to create output pixel processor!\n");
1422 goto opp_create_fail;
1423 }
1424
1425 pool->base.timing_generators[i] = dcn10_timing_generator_create(
1426 ctx, i);
1427 if (pool->base.timing_generators[i] == NULL) {
1428 BREAK_TO_DEBUGGER();
1429 dm_error("DC: failed to create tg!\n");
1430 goto otg_create_fail;
1431 }
1432 pool->base.mpcc[i] = dcn10_mpcc_create(ctx, i);
1433 if (pool->base.mpcc[i] == NULL) {
1434 BREAK_TO_DEBUGGER();
1435 dm_error("DC: failed to create mpcc!\n");
1436 goto mpcc_create_fail;
1437 }
1438 }
1439
1440 if (!resource_construct(num_virtual_links, dc, &pool->base,
1441 (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
1442 &res_create_funcs : &res_create_maximus_funcs)))
1443 goto res_create_fail;
1444
1445 dcn10_hw_sequencer_construct(dc);
1446 dc->public.caps.max_surfaces = pool->base.pipe_count;
1447
1448 dc->public.cap_funcs = cap_funcs;
1449
1450 return true;
1451
1452 disp_clk_create_fail:
1453 mpcc_create_fail:
1454 otg_create_fail:
1455 opp_create_fail:
1456 transform_create_fail:
1457 ipp_create_fail:
1458 mi_create_fail:
1459 irqs_create_fail:
1460 res_create_fail:
1461 clock_source_create_fail:
1462
1463 destruct(pool);
1464
1465 return false;
1466 }
1467
1468 struct resource_pool *dcn10_create_resource_pool(
1469 uint8_t num_virtual_links,
1470 struct core_dc *dc)
1471 {
1472 struct dcn10_resource_pool *pool =
1473 dm_alloc(sizeof(struct dcn10_resource_pool));
1474
1475 if (!pool)
1476 return NULL;
1477
1478 if (construct(num_virtual_links, dc, pool))
1479 return &pool->base;
1480
1481 BREAK_TO_DEBUGGER();
1482 return NULL;
1483 }