Line data Source code
1 : /*
2 : * Copyright 2012-15 Advanced Micro Devices, Inc.cls
3 : *
4 : *
5 : * Permission is hereby granted, free of charge, to any person obtaining a
6 : * copy of this software and associated documentation files (the "Software"),
7 : * to deal in the Software without restriction, including without limitation
8 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 : * and/or sell copies of the Software, and to permit persons to whom the
10 : * Software is furnished to do so, subject to the following conditions:
11 : *
12 : * The above copyright notice and this permission notice shall be included in
13 : * all copies or substantial portions of the Software.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 : * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 : * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 : * OTHER DEALINGS IN THE SOFTWARE.
22 : *
23 : * Authors: AMD
24 : *
25 : */
26 :
27 : #include "dm_services.h"
28 :
29 :
30 : #include "stream_encoder.h"
31 : #include "resource.h"
32 : #include "include/irq_service_interface.h"
33 : #include "dce120_resource.h"
34 :
35 : #include "dce112/dce112_resource.h"
36 :
37 : #include "dce110/dce110_resource.h"
38 : #include "../virtual/virtual_stream_encoder.h"
39 : #include "dce120_timing_generator.h"
40 : #include "irq/dce120/irq_service_dce120.h"
41 : #include "dce/dce_opp.h"
42 : #include "dce/dce_clock_source.h"
43 : #include "dce/dce_ipp.h"
44 : #include "dce/dce_mem_input.h"
45 : #include "dce/dce_panel_cntl.h"
46 :
47 : #include "dce110/dce110_hw_sequencer.h"
48 : #include "dce120/dce120_hw_sequencer.h"
49 : #include "dce/dce_transform.h"
50 : #include "clk_mgr.h"
51 : #include "dce/dce_audio.h"
52 : #include "dce/dce_link_encoder.h"
53 : #include "dce/dce_stream_encoder.h"
54 : #include "dce/dce_hwseq.h"
55 : #include "dce/dce_abm.h"
56 : #include "dce/dce_dmcu.h"
57 : #include "dce/dce_aux.h"
58 : #include "dce/dce_i2c.h"
59 :
60 : #include "dce/dce_12_0_offset.h"
61 : #include "dce/dce_12_0_sh_mask.h"
62 : #include "soc15_hw_ip.h"
63 : #include "vega10_ip_offset.h"
64 : #include "nbio/nbio_6_1_offset.h"
65 : #include "mmhub/mmhub_1_0_offset.h"
66 : #include "mmhub/mmhub_1_0_sh_mask.h"
67 : #include "reg_helper.h"
68 :
69 : #include "dce100/dce100_resource.h"
70 :
71 : #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
72 : #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
73 : #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
74 : #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f
75 : #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
76 : #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f
77 : #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
78 : #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f
79 : #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
80 : #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f
81 : #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
82 : #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f
83 : #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
84 : #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f
85 : #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
86 : #endif
87 :
88 : enum dce120_clk_src_array_id {
89 : DCE120_CLK_SRC_PLL0,
90 : DCE120_CLK_SRC_PLL1,
91 : DCE120_CLK_SRC_PLL2,
92 : DCE120_CLK_SRC_PLL3,
93 : DCE120_CLK_SRC_PLL4,
94 : DCE120_CLK_SRC_PLL5,
95 :
96 : DCE120_CLK_SRC_TOTAL
97 : };
98 :
99 : static const struct dce110_timing_generator_offsets dce120_tg_offsets[] = {
100 : {
101 : .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
102 : },
103 : {
104 : .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
105 : },
106 : {
107 : .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
108 : },
109 : {
110 : .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
111 : },
112 : {
113 : .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
114 : },
115 : {
116 : .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC0_CRTC_CONTROL),
117 : }
118 : };
119 :
120 : /* begin *********************
121 : * macros to expend register list macro defined in HW object header file */
122 :
123 : #define BASE_INNER(seg) \
124 : DCE_BASE__INST0_SEG ## seg
125 :
126 : #define NBIO_BASE_INNER(seg) \
127 : NBIF_BASE__INST0_SEG ## seg
128 :
129 : #define NBIO_BASE(seg) \
130 : NBIO_BASE_INNER(seg)
131 :
132 : /* compile time expand base address. */
133 : #define BASE(seg) \
134 : BASE_INNER(seg)
135 :
136 : #define SR(reg_name)\
137 : .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
138 : mm ## reg_name
139 :
140 : #define SRI(reg_name, block, id)\
141 : .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
142 : mm ## block ## id ## _ ## reg_name
143 :
144 : /* MMHUB */
145 : #define MMHUB_BASE_INNER(seg) \
146 : MMHUB_BASE__INST0_SEG ## seg
147 :
148 : #define MMHUB_BASE(seg) \
149 : MMHUB_BASE_INNER(seg)
150 :
151 : #define MMHUB_SR(reg_name)\
152 : .reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) + \
153 : mm ## reg_name
154 :
155 : /* macros to expend register list macro defined in HW object header file
156 : * end *********************/
157 :
158 :
159 : static const struct dce_dmcu_registers dmcu_regs = {
160 : DMCU_DCE110_COMMON_REG_LIST()
161 : };
162 :
163 : static const struct dce_dmcu_shift dmcu_shift = {
164 : DMCU_MASK_SH_LIST_DCE110(__SHIFT)
165 : };
166 :
167 : static const struct dce_dmcu_mask dmcu_mask = {
168 : DMCU_MASK_SH_LIST_DCE110(_MASK)
169 : };
170 :
171 : static const struct dce_abm_registers abm_regs = {
172 : ABM_DCE110_COMMON_REG_LIST()
173 : };
174 :
175 : static const struct dce_abm_shift abm_shift = {
176 : ABM_MASK_SH_LIST_DCE110(__SHIFT)
177 : };
178 :
179 : static const struct dce_abm_mask abm_mask = {
180 : ABM_MASK_SH_LIST_DCE110(_MASK)
181 : };
182 :
183 : #define ipp_regs(id)\
184 : [id] = {\
185 : IPP_DCE110_REG_LIST_DCE_BASE(id)\
186 : }
187 :
188 : static const struct dce_ipp_registers ipp_regs[] = {
189 : ipp_regs(0),
190 : ipp_regs(1),
191 : ipp_regs(2),
192 : ipp_regs(3),
193 : ipp_regs(4),
194 : ipp_regs(5)
195 : };
196 :
197 : static const struct dce_ipp_shift ipp_shift = {
198 : IPP_DCE120_MASK_SH_LIST_SOC_BASE(__SHIFT)
199 : };
200 :
201 : static const struct dce_ipp_mask ipp_mask = {
202 : IPP_DCE120_MASK_SH_LIST_SOC_BASE(_MASK)
203 : };
204 :
205 : #define transform_regs(id)\
206 : [id] = {\
207 : XFM_COMMON_REG_LIST_DCE110(id)\
208 : }
209 :
210 : static const struct dce_transform_registers xfm_regs[] = {
211 : transform_regs(0),
212 : transform_regs(1),
213 : transform_regs(2),
214 : transform_regs(3),
215 : transform_regs(4),
216 : transform_regs(5)
217 : };
218 :
219 : static const struct dce_transform_shift xfm_shift = {
220 : XFM_COMMON_MASK_SH_LIST_SOC_BASE(__SHIFT)
221 : };
222 :
223 : static const struct dce_transform_mask xfm_mask = {
224 : XFM_COMMON_MASK_SH_LIST_SOC_BASE(_MASK)
225 : };
226 :
227 : #define aux_regs(id)\
228 : [id] = {\
229 : AUX_REG_LIST(id)\
230 : }
231 :
232 : static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
233 : aux_regs(0),
234 : aux_regs(1),
235 : aux_regs(2),
236 : aux_regs(3),
237 : aux_regs(4),
238 : aux_regs(5)
239 : };
240 :
241 : #define hpd_regs(id)\
242 : [id] = {\
243 : HPD_REG_LIST(id)\
244 : }
245 :
246 : static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
247 : hpd_regs(0),
248 : hpd_regs(1),
249 : hpd_regs(2),
250 : hpd_regs(3),
251 : hpd_regs(4),
252 : hpd_regs(5)
253 : };
254 :
255 : #define link_regs(id)\
256 : [id] = {\
257 : LE_DCE120_REG_LIST(id), \
258 : SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
259 : }
260 :
261 : static const struct dce110_link_enc_registers link_enc_regs[] = {
262 : link_regs(0),
263 : link_regs(1),
264 : link_regs(2),
265 : link_regs(3),
266 : link_regs(4),
267 : link_regs(5),
268 : link_regs(6),
269 : };
270 :
271 :
272 : #define stream_enc_regs(id)\
273 : [id] = {\
274 : SE_COMMON_REG_LIST(id),\
275 : .TMDS_CNTL = 0,\
276 : }
277 :
278 : static const struct dce110_stream_enc_registers stream_enc_regs[] = {
279 : stream_enc_regs(0),
280 : stream_enc_regs(1),
281 : stream_enc_regs(2),
282 : stream_enc_regs(3),
283 : stream_enc_regs(4),
284 : stream_enc_regs(5)
285 : };
286 :
287 : static const struct dce_stream_encoder_shift se_shift = {
288 : SE_COMMON_MASK_SH_LIST_DCE120(__SHIFT)
289 : };
290 :
291 : static const struct dce_stream_encoder_mask se_mask = {
292 : SE_COMMON_MASK_SH_LIST_DCE120(_MASK)
293 : };
294 :
295 : static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
296 : { DCE_PANEL_CNTL_REG_LIST() }
297 : };
298 :
299 : static const struct dce_panel_cntl_shift panel_cntl_shift = {
300 : DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
301 : };
302 :
303 : static const struct dce_panel_cntl_mask panel_cntl_mask = {
304 : DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
305 : };
306 :
307 : static const struct dce110_aux_registers_shift aux_shift = {
308 : DCE12_AUX_MASK_SH_LIST(__SHIFT)
309 : };
310 :
311 : static const struct dce110_aux_registers_mask aux_mask = {
312 : DCE12_AUX_MASK_SH_LIST(_MASK)
313 : };
314 :
315 : #define opp_regs(id)\
316 : [id] = {\
317 : OPP_DCE_120_REG_LIST(id),\
318 : }
319 :
320 : static const struct dce_opp_registers opp_regs[] = {
321 : opp_regs(0),
322 : opp_regs(1),
323 : opp_regs(2),
324 : opp_regs(3),
325 : opp_regs(4),
326 : opp_regs(5)
327 : };
328 :
329 : static const struct dce_opp_shift opp_shift = {
330 : OPP_COMMON_MASK_SH_LIST_DCE_120(__SHIFT)
331 : };
332 :
333 : static const struct dce_opp_mask opp_mask = {
334 : OPP_COMMON_MASK_SH_LIST_DCE_120(_MASK)
335 : };
336 : #define aux_engine_regs(id)\
337 : [id] = {\
338 : AUX_COMMON_REG_LIST(id), \
339 : .AUX_RESET_MASK = 0 \
340 : }
341 :
342 : static const struct dce110_aux_registers aux_engine_regs[] = {
343 : aux_engine_regs(0),
344 : aux_engine_regs(1),
345 : aux_engine_regs(2),
346 : aux_engine_regs(3),
347 : aux_engine_regs(4),
348 : aux_engine_regs(5)
349 : };
350 :
351 : #define audio_regs(id)\
352 : [id] = {\
353 : AUD_COMMON_REG_LIST(id)\
354 : }
355 :
356 : static const struct dce_audio_registers audio_regs[] = {
357 : audio_regs(0),
358 : audio_regs(1),
359 : audio_regs(2),
360 : audio_regs(3),
361 : audio_regs(4),
362 : audio_regs(5)
363 : };
364 :
365 : #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
366 : SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
367 : SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
368 : AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
369 :
370 : static const struct dce_audio_shift audio_shift = {
371 : DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
372 : };
373 :
374 : static const struct dce_audio_mask audio_mask = {
375 : DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
376 : };
377 :
378 0 : static int map_transmitter_id_to_phy_instance(
379 : enum transmitter transmitter)
380 : {
381 0 : switch (transmitter) {
382 : case TRANSMITTER_UNIPHY_A:
383 : return 0;
384 : case TRANSMITTER_UNIPHY_B:
385 0 : return 1;
386 : case TRANSMITTER_UNIPHY_C:
387 0 : return 2;
388 : case TRANSMITTER_UNIPHY_D:
389 0 : return 3;
390 : case TRANSMITTER_UNIPHY_E:
391 0 : return 4;
392 : case TRANSMITTER_UNIPHY_F:
393 0 : return 5;
394 : case TRANSMITTER_UNIPHY_G:
395 0 : return 6;
396 : default:
397 0 : ASSERT(0);
398 : return 0;
399 : }
400 : }
401 :
402 : #define clk_src_regs(index, id)\
403 : [index] = {\
404 : CS_COMMON_REG_LIST_DCE_112(id),\
405 : }
406 :
407 : static const struct dce110_clk_src_regs clk_src_regs[] = {
408 : clk_src_regs(0, A),
409 : clk_src_regs(1, B),
410 : clk_src_regs(2, C),
411 : clk_src_regs(3, D),
412 : clk_src_regs(4, E),
413 : clk_src_regs(5, F)
414 : };
415 :
416 : static const struct dce110_clk_src_shift cs_shift = {
417 : CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
418 : };
419 :
420 : static const struct dce110_clk_src_mask cs_mask = {
421 : CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)
422 : };
423 :
424 0 : static struct output_pixel_processor *dce120_opp_create(
425 : struct dc_context *ctx,
426 : uint32_t inst)
427 : {
428 0 : struct dce110_opp *opp =
429 : kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
430 :
431 0 : if (!opp)
432 : return NULL;
433 :
434 0 : dce110_opp_construct(opp,
435 : ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
436 0 : return &opp->base;
437 : }
438 0 : static struct dce_aux *dce120_aux_engine_create(
439 : struct dc_context *ctx,
440 : uint32_t inst)
441 : {
442 0 : struct aux_engine_dce110 *aux_engine =
443 : kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
444 :
445 0 : if (!aux_engine)
446 : return NULL;
447 :
448 0 : dce110_aux_engine_construct(aux_engine, ctx, inst,
449 : SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
450 : &aux_engine_regs[inst],
451 : &aux_mask,
452 : &aux_shift,
453 0 : ctx->dc->caps.extended_aux_timeout_support);
454 :
455 0 : return &aux_engine->base;
456 : }
457 : #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
458 :
459 : static const struct dce_i2c_registers i2c_hw_regs[] = {
460 : i2c_inst_regs(1),
461 : i2c_inst_regs(2),
462 : i2c_inst_regs(3),
463 : i2c_inst_regs(4),
464 : i2c_inst_regs(5),
465 : i2c_inst_regs(6),
466 : };
467 :
468 : static const struct dce_i2c_shift i2c_shifts = {
469 : I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
470 : };
471 :
472 : static const struct dce_i2c_mask i2c_masks = {
473 : I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
474 : };
475 :
476 0 : static struct dce_i2c_hw *dce120_i2c_hw_create(
477 : struct dc_context *ctx,
478 : uint32_t inst)
479 : {
480 0 : struct dce_i2c_hw *dce_i2c_hw =
481 : kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
482 :
483 0 : if (!dce_i2c_hw)
484 : return NULL;
485 :
486 0 : dce112_i2c_hw_construct(dce_i2c_hw, ctx, inst,
487 : &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
488 :
489 0 : return dce_i2c_hw;
490 : }
491 : static const struct bios_registers bios_regs = {
492 : .BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3 + NBIO_BASE(mmBIOS_SCRATCH_3_BASE_IDX),
493 : .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX)
494 : };
495 :
496 : static const struct resource_caps res_cap = {
497 : .num_timing_generator = 6,
498 : .num_audio = 7,
499 : .num_stream_encoder = 6,
500 : .num_pll = 6,
501 : .num_ddc = 6,
502 : };
503 :
504 : static const struct dc_plane_cap plane_cap = {
505 : .type = DC_PLANE_TYPE_DCE_RGB,
506 :
507 : .pixel_format_support = {
508 : .argb8888 = true,
509 : .nv12 = false,
510 : .fp16 = true
511 : },
512 :
513 : .max_upscale_factor = {
514 : .argb8888 = 16000,
515 : .nv12 = 1,
516 : .fp16 = 1
517 : },
518 :
519 : .max_downscale_factor = {
520 : .argb8888 = 250,
521 : .nv12 = 1,
522 : .fp16 = 1
523 : }
524 : };
525 :
526 : static const struct dc_debug_options debug_defaults = {
527 : .disable_clock_gate = true,
528 : };
529 :
530 0 : static struct clock_source *dce120_clock_source_create(
531 : struct dc_context *ctx,
532 : struct dc_bios *bios,
533 : enum clock_source_id id,
534 : const struct dce110_clk_src_regs *regs,
535 : bool dp_clk_src)
536 : {
537 0 : struct dce110_clk_src *clk_src =
538 : kzalloc(sizeof(*clk_src), GFP_KERNEL);
539 :
540 0 : if (!clk_src)
541 : return NULL;
542 :
543 0 : if (dce112_clk_src_construct(clk_src, ctx, bios, id,
544 : regs, &cs_shift, &cs_mask)) {
545 0 : clk_src->base.dp_clk_src = dp_clk_src;
546 0 : return &clk_src->base;
547 : }
548 :
549 0 : kfree(clk_src);
550 0 : BREAK_TO_DEBUGGER();
551 0 : return NULL;
552 : }
553 :
554 : static void dce120_clock_source_destroy(struct clock_source **clk_src)
555 : {
556 0 : kfree(TO_DCE110_CLK_SRC(*clk_src));
557 0 : *clk_src = NULL;
558 : }
559 :
560 :
561 : static bool dce120_hw_sequencer_create(struct dc *dc)
562 : {
563 : /* All registers used by dce11.2 match those in dce11 in offset and
564 : * structure
565 : */
566 0 : dce120_hw_sequencer_construct(dc);
567 :
568 : /*TODO Move to separate file and Override what is needed */
569 :
570 : return true;
571 : }
572 :
573 0 : static struct timing_generator *dce120_timing_generator_create(
574 : struct dc_context *ctx,
575 : uint32_t instance,
576 : const struct dce110_timing_generator_offsets *offsets)
577 : {
578 0 : struct dce110_timing_generator *tg110 =
579 : kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
580 :
581 0 : if (!tg110)
582 : return NULL;
583 :
584 0 : dce120_timing_generator_construct(tg110, ctx, instance, offsets);
585 0 : return &tg110->base;
586 : }
587 :
588 : static void dce120_transform_destroy(struct transform **xfm)
589 : {
590 0 : kfree(TO_DCE_TRANSFORM(*xfm));
591 0 : *xfm = NULL;
592 : }
593 :
594 0 : static void dce120_resource_destruct(struct dce110_resource_pool *pool)
595 : {
596 : unsigned int i;
597 :
598 0 : for (i = 0; i < pool->base.pipe_count; i++) {
599 0 : if (pool->base.opps[i] != NULL)
600 0 : dce110_opp_destroy(&pool->base.opps[i]);
601 :
602 0 : if (pool->base.transforms[i] != NULL)
603 0 : dce120_transform_destroy(&pool->base.transforms[i]);
604 :
605 0 : if (pool->base.ipps[i] != NULL)
606 0 : dce_ipp_destroy(&pool->base.ipps[i]);
607 :
608 0 : if (pool->base.mis[i] != NULL) {
609 0 : kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
610 0 : pool->base.mis[i] = NULL;
611 : }
612 :
613 0 : if (pool->base.irqs != NULL) {
614 0 : dal_irq_service_destroy(&pool->base.irqs);
615 : }
616 :
617 0 : if (pool->base.timing_generators[i] != NULL) {
618 0 : kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
619 0 : pool->base.timing_generators[i] = NULL;
620 : }
621 : }
622 :
623 0 : for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
624 0 : if (pool->base.engines[i] != NULL)
625 0 : dce110_engine_destroy(&pool->base.engines[i]);
626 0 : if (pool->base.hw_i2cs[i] != NULL) {
627 0 : kfree(pool->base.hw_i2cs[i]);
628 0 : pool->base.hw_i2cs[i] = NULL;
629 : }
630 0 : if (pool->base.sw_i2cs[i] != NULL) {
631 0 : kfree(pool->base.sw_i2cs[i]);
632 0 : pool->base.sw_i2cs[i] = NULL;
633 : }
634 : }
635 :
636 0 : for (i = 0; i < pool->base.audio_count; i++) {
637 0 : if (pool->base.audios[i])
638 0 : dce_aud_destroy(&pool->base.audios[i]);
639 : }
640 :
641 0 : for (i = 0; i < pool->base.stream_enc_count; i++) {
642 0 : if (pool->base.stream_enc[i] != NULL)
643 0 : kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
644 : }
645 :
646 0 : for (i = 0; i < pool->base.clk_src_count; i++) {
647 0 : if (pool->base.clock_sources[i] != NULL)
648 0 : dce120_clock_source_destroy(
649 : &pool->base.clock_sources[i]);
650 : }
651 :
652 0 : if (pool->base.dp_clock_source != NULL)
653 0 : dce120_clock_source_destroy(&pool->base.dp_clock_source);
654 :
655 0 : if (pool->base.abm != NULL)
656 0 : dce_abm_destroy(&pool->base.abm);
657 :
658 0 : if (pool->base.dmcu != NULL)
659 0 : dce_dmcu_destroy(&pool->base.dmcu);
660 0 : }
661 :
662 0 : static void read_dce_straps(
663 : struct dc_context *ctx,
664 : struct resource_straps *straps)
665 : {
666 0 : uint32_t reg_val = dm_read_reg_soc15(ctx, mmCC_DC_MISC_STRAPS, 0);
667 :
668 0 : straps->audio_stream_number = get_reg_field_value(reg_val,
669 : CC_DC_MISC_STRAPS,
670 : AUDIO_STREAM_NUMBER);
671 0 : straps->hdmi_disable = get_reg_field_value(reg_val,
672 : CC_DC_MISC_STRAPS,
673 : HDMI_DISABLE);
674 :
675 0 : reg_val = dm_read_reg_soc15(ctx, mmDC_PINSTRAPS, 0);
676 0 : straps->dc_pinstraps_audio = get_reg_field_value(reg_val,
677 : DC_PINSTRAPS,
678 : DC_PINSTRAPS_AUDIO);
679 0 : }
680 :
681 0 : static struct audio *create_audio(
682 : struct dc_context *ctx, unsigned int inst)
683 : {
684 0 : return dce_audio_create(ctx, inst,
685 : &audio_regs[inst], &audio_shift, &audio_mask);
686 : }
687 :
688 : static const struct encoder_feature_support link_enc_feature = {
689 : .max_hdmi_deep_color = COLOR_DEPTH_121212,
690 : .max_hdmi_pixel_clock = 600000,
691 : .hdmi_ycbcr420_supported = true,
692 : .dp_ycbcr420_supported = false,
693 : .flags.bits.IS_HBR2_CAPABLE = true,
694 : .flags.bits.IS_HBR3_CAPABLE = true,
695 : .flags.bits.IS_TPS3_CAPABLE = true,
696 : .flags.bits.IS_TPS4_CAPABLE = true,
697 : };
698 :
699 0 : static struct link_encoder *dce120_link_encoder_create(
700 : struct dc_context *ctx,
701 : const struct encoder_init_data *enc_init_data)
702 : {
703 0 : struct dce110_link_encoder *enc110 =
704 : kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
705 : int link_regs_id;
706 :
707 0 : if (!enc110)
708 : return NULL;
709 :
710 0 : link_regs_id =
711 0 : map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
712 :
713 0 : dce110_link_encoder_construct(enc110,
714 : enc_init_data,
715 : &link_enc_feature,
716 : &link_enc_regs[link_regs_id],
717 0 : &link_enc_aux_regs[enc_init_data->channel - 1],
718 0 : &link_enc_hpd_regs[enc_init_data->hpd_source]);
719 :
720 0 : return &enc110->base;
721 : }
722 :
723 0 : static struct panel_cntl *dce120_panel_cntl_create(const struct panel_cntl_init_data *init_data)
724 : {
725 0 : struct dce_panel_cntl *panel_cntl =
726 : kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
727 :
728 0 : if (!panel_cntl)
729 : return NULL;
730 :
731 0 : dce_panel_cntl_construct(panel_cntl,
732 : init_data,
733 0 : &panel_cntl_regs[init_data->inst],
734 : &panel_cntl_shift,
735 : &panel_cntl_mask);
736 :
737 0 : return &panel_cntl->base;
738 : }
739 :
740 0 : static struct input_pixel_processor *dce120_ipp_create(
741 : struct dc_context *ctx, uint32_t inst)
742 : {
743 0 : struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
744 :
745 0 : if (!ipp) {
746 0 : BREAK_TO_DEBUGGER();
747 0 : return NULL;
748 : }
749 :
750 0 : dce_ipp_construct(ipp, ctx, inst,
751 : &ipp_regs[inst], &ipp_shift, &ipp_mask);
752 0 : return &ipp->base;
753 : }
754 :
755 0 : static struct stream_encoder *dce120_stream_encoder_create(
756 : enum engine_id eng_id,
757 : struct dc_context *ctx)
758 : {
759 0 : struct dce110_stream_encoder *enc110 =
760 : kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
761 :
762 0 : if (!enc110)
763 : return NULL;
764 :
765 0 : dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
766 : &stream_enc_regs[eng_id],
767 : &se_shift, &se_mask);
768 0 : return &enc110->base;
769 : }
770 :
771 : #define SRII(reg_name, block, id)\
772 : .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
773 : mm ## block ## id ## _ ## reg_name
774 :
775 : static const struct dce_hwseq_registers hwseq_reg = {
776 : HWSEQ_DCE120_REG_LIST()
777 : };
778 :
779 : static const struct dce_hwseq_shift hwseq_shift = {
780 : HWSEQ_DCE12_MASK_SH_LIST(__SHIFT)
781 : };
782 :
783 : static const struct dce_hwseq_mask hwseq_mask = {
784 : HWSEQ_DCE12_MASK_SH_LIST(_MASK)
785 : };
786 :
787 : /* HWSEQ regs for VG20 */
788 : static const struct dce_hwseq_registers dce121_hwseq_reg = {
789 : HWSEQ_VG20_REG_LIST()
790 : };
791 :
792 : static const struct dce_hwseq_shift dce121_hwseq_shift = {
793 : HWSEQ_VG20_MASK_SH_LIST(__SHIFT)
794 : };
795 :
796 : static const struct dce_hwseq_mask dce121_hwseq_mask = {
797 : HWSEQ_VG20_MASK_SH_LIST(_MASK)
798 : };
799 :
800 0 : static struct dce_hwseq *dce120_hwseq_create(
801 : struct dc_context *ctx)
802 : {
803 0 : struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
804 :
805 0 : if (hws) {
806 0 : hws->ctx = ctx;
807 0 : hws->regs = &hwseq_reg;
808 0 : hws->shifts = &hwseq_shift;
809 0 : hws->masks = &hwseq_mask;
810 : }
811 0 : return hws;
812 : }
813 :
814 0 : static struct dce_hwseq *dce121_hwseq_create(
815 : struct dc_context *ctx)
816 : {
817 0 : struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
818 :
819 0 : if (hws) {
820 0 : hws->ctx = ctx;
821 0 : hws->regs = &dce121_hwseq_reg;
822 0 : hws->shifts = &dce121_hwseq_shift;
823 0 : hws->masks = &dce121_hwseq_mask;
824 : }
825 0 : return hws;
826 : }
827 :
828 : static const struct resource_create_funcs res_create_funcs = {
829 : .read_dce_straps = read_dce_straps,
830 : .create_audio = create_audio,
831 : .create_stream_encoder = dce120_stream_encoder_create,
832 : .create_hwseq = dce120_hwseq_create,
833 : };
834 :
835 : static const struct resource_create_funcs dce121_res_create_funcs = {
836 : .read_dce_straps = read_dce_straps,
837 : .create_audio = create_audio,
838 : .create_stream_encoder = dce120_stream_encoder_create,
839 : .create_hwseq = dce121_hwseq_create,
840 : };
841 :
842 :
843 : #define mi_inst_regs(id) { MI_DCE12_REG_LIST(id) }
844 : static const struct dce_mem_input_registers mi_regs[] = {
845 : mi_inst_regs(0),
846 : mi_inst_regs(1),
847 : mi_inst_regs(2),
848 : mi_inst_regs(3),
849 : mi_inst_regs(4),
850 : mi_inst_regs(5),
851 : };
852 :
853 : static const struct dce_mem_input_shift mi_shifts = {
854 : MI_DCE12_MASK_SH_LIST(__SHIFT)
855 : };
856 :
857 : static const struct dce_mem_input_mask mi_masks = {
858 : MI_DCE12_MASK_SH_LIST(_MASK)
859 : };
860 :
861 0 : static struct mem_input *dce120_mem_input_create(
862 : struct dc_context *ctx,
863 : uint32_t inst)
864 : {
865 0 : struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
866 : GFP_KERNEL);
867 :
868 0 : if (!dce_mi) {
869 0 : BREAK_TO_DEBUGGER();
870 0 : return NULL;
871 : }
872 :
873 0 : dce120_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
874 0 : return &dce_mi->base;
875 : }
876 :
877 0 : static struct transform *dce120_transform_create(
878 : struct dc_context *ctx,
879 : uint32_t inst)
880 : {
881 0 : struct dce_transform *transform =
882 : kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
883 :
884 0 : if (!transform)
885 : return NULL;
886 :
887 0 : dce_transform_construct(transform, ctx, inst,
888 : &xfm_regs[inst], &xfm_shift, &xfm_mask);
889 0 : transform->lb_memory_size = 0x1404; /*5124*/
890 0 : return &transform->base;
891 : }
892 :
893 0 : static void dce120_destroy_resource_pool(struct resource_pool **pool)
894 : {
895 0 : struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
896 :
897 0 : dce120_resource_destruct(dce110_pool);
898 0 : kfree(dce110_pool);
899 0 : *pool = NULL;
900 0 : }
901 :
902 : static const struct resource_funcs dce120_res_pool_funcs = {
903 : .destroy = dce120_destroy_resource_pool,
904 : .link_enc_create = dce120_link_encoder_create,
905 : .panel_cntl_create = dce120_panel_cntl_create,
906 : .validate_bandwidth = dce112_validate_bandwidth,
907 : .validate_plane = dce100_validate_plane,
908 : .add_stream_to_ctx = dce112_add_stream_to_ctx,
909 : .find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
910 : };
911 :
912 0 : static void bw_calcs_data_update_from_pplib(struct dc *dc)
913 : {
914 0 : struct dm_pp_clock_levels_with_latency eng_clks = {0};
915 0 : struct dm_pp_clock_levels_with_latency mem_clks = {0};
916 0 : struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
917 : int i;
918 : unsigned int clk;
919 : unsigned int latency;
920 : /*original logic in dal3*/
921 0 : int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
922 :
923 : /*do system clock*/
924 0 : if (!dm_pp_get_clock_levels_by_type_with_latency(
925 0 : dc->ctx,
926 : DM_PP_CLOCK_TYPE_ENGINE_CLK,
927 0 : &eng_clks) || eng_clks.num_levels == 0) {
928 :
929 0 : eng_clks.num_levels = 8;
930 0 : clk = 300000;
931 :
932 0 : for (i = 0; i < eng_clks.num_levels; i++) {
933 0 : eng_clks.data[i].clocks_in_khz = clk;
934 0 : clk += 100000;
935 : }
936 : }
937 :
938 : /* convert all the clock fro kHz to fix point mHz TODO: wloop data */
939 0 : dc->bw_vbios->high_sclk = bw_frc_to_fixed(
940 0 : eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);
941 0 : dc->bw_vbios->mid1_sclk = bw_frc_to_fixed(
942 0 : eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);
943 0 : dc->bw_vbios->mid2_sclk = bw_frc_to_fixed(
944 0 : eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);
945 0 : dc->bw_vbios->mid3_sclk = bw_frc_to_fixed(
946 0 : eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);
947 0 : dc->bw_vbios->mid4_sclk = bw_frc_to_fixed(
948 0 : eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);
949 0 : dc->bw_vbios->mid5_sclk = bw_frc_to_fixed(
950 0 : eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);
951 0 : dc->bw_vbios->mid6_sclk = bw_frc_to_fixed(
952 0 : eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);
953 0 : dc->bw_vbios->low_sclk = bw_frc_to_fixed(
954 0 : eng_clks.data[0].clocks_in_khz, 1000);
955 :
956 : /*do memory clock*/
957 0 : if (!dm_pp_get_clock_levels_by_type_with_latency(
958 0 : dc->ctx,
959 : DM_PP_CLOCK_TYPE_MEMORY_CLK,
960 0 : &mem_clks) || mem_clks.num_levels == 0) {
961 :
962 0 : mem_clks.num_levels = 3;
963 0 : clk = 250000;
964 0 : latency = 45;
965 :
966 0 : for (i = 0; i < eng_clks.num_levels; i++) {
967 0 : mem_clks.data[i].clocks_in_khz = clk;
968 0 : mem_clks.data[i].latency_in_us = latency;
969 0 : clk += 500000;
970 0 : latency -= 5;
971 : }
972 :
973 : }
974 :
975 : /* we don't need to call PPLIB for validation clock since they
976 : * also give us the highest sclk and highest mclk (UMA clock).
977 : * ALSO always convert UMA clock (from PPLIB) to YCLK (HW formula):
978 : * YCLK = UMACLK*m_memoryTypeMultiplier
979 : */
980 0 : if (dc->bw_vbios->memory_type == bw_def_hbm)
981 0 : memory_type_multiplier = MEMORY_TYPE_HBM;
982 :
983 0 : dc->bw_vbios->low_yclk = bw_frc_to_fixed(
984 0 : mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000);
985 0 : dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
986 0 : mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier,
987 : 1000);
988 0 : dc->bw_vbios->high_yclk = bw_frc_to_fixed(
989 0 : mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier,
990 : 1000);
991 :
992 : /* Now notify PPLib/SMU about which Watermarks sets they should select
993 : * depending on DPM state they are in. And update BW MGR GFX Engine and
994 : * Memory clock member variables for Watermarks calculations for each
995 : * Watermark Set
996 : */
997 0 : clk_ranges.num_wm_sets = 4;
998 0 : clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;
999 0 : clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =
1000 0 : eng_clks.data[0].clocks_in_khz;
1001 0 : clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =
1002 0 : eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
1003 0 : clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz =
1004 0 : mem_clks.data[0].clocks_in_khz;
1005 0 : clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =
1006 0 : mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
1007 :
1008 0 : clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;
1009 0 : clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =
1010 : eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
1011 : /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1012 0 : clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;
1013 0 : clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz =
1014 : mem_clks.data[0].clocks_in_khz;
1015 0 : clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =
1016 : mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
1017 :
1018 0 : clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;
1019 0 : clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =
1020 : eng_clks.data[0].clocks_in_khz;
1021 0 : clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =
1022 : eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
1023 0 : clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz =
1024 : mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
1025 : /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1026 0 : clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;
1027 :
1028 0 : clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;
1029 0 : clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =
1030 : eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
1031 : /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
1032 0 : clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;
1033 0 : clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz =
1034 : mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
1035 : /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
1036 0 : clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;
1037 :
1038 : /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1039 0 : dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
1040 0 : }
1041 :
1042 : static uint32_t read_pipe_fuses(struct dc_context *ctx)
1043 : {
1044 0 : uint32_t value = dm_read_reg_soc15(ctx, mmCC_DC_PIPE_DIS, 0);
1045 : /* VG20 support max 6 pipes */
1046 0 : value = value & 0x3f;
1047 : return value;
1048 : }
1049 :
1050 0 : static bool dce120_resource_construct(
1051 : uint8_t num_virtual_links,
1052 : struct dc *dc,
1053 : struct dce110_resource_pool *pool)
1054 : {
1055 : unsigned int i;
1056 : int j;
1057 0 : struct dc_context *ctx = dc->ctx;
1058 : struct irq_service_init_data irq_init_data;
1059 : static const struct resource_create_funcs *res_funcs;
1060 0 : bool is_vg20 = ASICREV_IS_VEGA20_P(ctx->asic_id.hw_internal_rev);
1061 : uint32_t pipe_fuses;
1062 :
1063 0 : ctx->dc_bios->regs = &bios_regs;
1064 :
1065 0 : pool->base.res_cap = &res_cap;
1066 0 : pool->base.funcs = &dce120_res_pool_funcs;
1067 :
1068 : /* TODO: Fill more data from GreenlandAsicCapability.cpp */
1069 0 : pool->base.pipe_count = res_cap.num_timing_generator;
1070 0 : pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
1071 0 : pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1072 :
1073 0 : dc->caps.max_downscale_ratio = 200;
1074 0 : dc->caps.i2c_speed_in_khz = 100;
1075 0 : dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/
1076 0 : dc->caps.max_cursor_size = 128;
1077 0 : dc->caps.min_horizontal_blanking_period = 80;
1078 0 : dc->caps.dual_link_dvi = true;
1079 0 : dc->caps.psp_setup_panel_mode = true;
1080 0 : dc->caps.extended_aux_timeout_support = false;
1081 0 : dc->debug = debug_defaults;
1082 :
1083 : /*************************************************
1084 : * Create resources *
1085 : *************************************************/
1086 :
1087 0 : pool->base.clock_sources[DCE120_CLK_SRC_PLL0] =
1088 0 : dce120_clock_source_create(ctx, ctx->dc_bios,
1089 : CLOCK_SOURCE_COMBO_PHY_PLL0,
1090 : &clk_src_regs[0], false);
1091 0 : pool->base.clock_sources[DCE120_CLK_SRC_PLL1] =
1092 0 : dce120_clock_source_create(ctx, ctx->dc_bios,
1093 : CLOCK_SOURCE_COMBO_PHY_PLL1,
1094 : &clk_src_regs[1], false);
1095 0 : pool->base.clock_sources[DCE120_CLK_SRC_PLL2] =
1096 0 : dce120_clock_source_create(ctx, ctx->dc_bios,
1097 : CLOCK_SOURCE_COMBO_PHY_PLL2,
1098 : &clk_src_regs[2], false);
1099 0 : pool->base.clock_sources[DCE120_CLK_SRC_PLL3] =
1100 0 : dce120_clock_source_create(ctx, ctx->dc_bios,
1101 : CLOCK_SOURCE_COMBO_PHY_PLL3,
1102 : &clk_src_regs[3], false);
1103 0 : pool->base.clock_sources[DCE120_CLK_SRC_PLL4] =
1104 0 : dce120_clock_source_create(ctx, ctx->dc_bios,
1105 : CLOCK_SOURCE_COMBO_PHY_PLL4,
1106 : &clk_src_regs[4], false);
1107 0 : pool->base.clock_sources[DCE120_CLK_SRC_PLL5] =
1108 0 : dce120_clock_source_create(ctx, ctx->dc_bios,
1109 : CLOCK_SOURCE_COMBO_PHY_PLL5,
1110 : &clk_src_regs[5], false);
1111 0 : pool->base.clk_src_count = DCE120_CLK_SRC_TOTAL;
1112 :
1113 0 : pool->base.dp_clock_source =
1114 0 : dce120_clock_source_create(ctx, ctx->dc_bios,
1115 : CLOCK_SOURCE_ID_DP_DTO,
1116 : &clk_src_regs[0], true);
1117 :
1118 0 : for (i = 0; i < pool->base.clk_src_count; i++) {
1119 0 : if (pool->base.clock_sources[i] == NULL) {
1120 0 : dm_error("DC: failed to create clock sources!\n");
1121 0 : BREAK_TO_DEBUGGER();
1122 0 : goto clk_src_create_fail;
1123 : }
1124 : }
1125 :
1126 0 : pool->base.dmcu = dce_dmcu_create(ctx,
1127 : &dmcu_regs,
1128 : &dmcu_shift,
1129 : &dmcu_mask);
1130 0 : if (pool->base.dmcu == NULL) {
1131 0 : dm_error("DC: failed to create dmcu!\n");
1132 0 : BREAK_TO_DEBUGGER();
1133 0 : goto res_create_fail;
1134 : }
1135 :
1136 0 : pool->base.abm = dce_abm_create(ctx,
1137 : &abm_regs,
1138 : &abm_shift,
1139 : &abm_mask);
1140 0 : if (pool->base.abm == NULL) {
1141 0 : dm_error("DC: failed to create abm!\n");
1142 0 : BREAK_TO_DEBUGGER();
1143 0 : goto res_create_fail;
1144 : }
1145 :
1146 :
1147 0 : irq_init_data.ctx = dc->ctx;
1148 0 : pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data);
1149 0 : if (!pool->base.irqs)
1150 : goto irqs_create_fail;
1151 :
1152 : /* VG20: Pipe harvesting enabled, retrieve valid pipe fuses */
1153 0 : if (is_vg20)
1154 0 : pipe_fuses = read_pipe_fuses(ctx);
1155 :
1156 : /* index to valid pipe resource */
1157 0 : j = 0;
1158 0 : for (i = 0; i < pool->base.pipe_count; i++) {
1159 0 : if (is_vg20) {
1160 0 : if ((pipe_fuses & (1 << i)) != 0) {
1161 0 : dm_error("DC: skip invalid pipe %d!\n", i);
1162 0 : continue;
1163 : }
1164 : }
1165 :
1166 0 : pool->base.timing_generators[j] =
1167 0 : dce120_timing_generator_create(
1168 : ctx,
1169 : i,
1170 : &dce120_tg_offsets[i]);
1171 0 : if (pool->base.timing_generators[j] == NULL) {
1172 0 : BREAK_TO_DEBUGGER();
1173 0 : dm_error("DC: failed to create tg!\n");
1174 0 : goto controller_create_fail;
1175 : }
1176 :
1177 0 : pool->base.mis[j] = dce120_mem_input_create(ctx, i);
1178 :
1179 0 : if (pool->base.mis[j] == NULL) {
1180 0 : BREAK_TO_DEBUGGER();
1181 0 : dm_error(
1182 : "DC: failed to create memory input!\n");
1183 0 : goto controller_create_fail;
1184 : }
1185 :
1186 0 : pool->base.ipps[j] = dce120_ipp_create(ctx, i);
1187 0 : if (pool->base.ipps[i] == NULL) {
1188 0 : BREAK_TO_DEBUGGER();
1189 0 : dm_error(
1190 : "DC: failed to create input pixel processor!\n");
1191 0 : goto controller_create_fail;
1192 : }
1193 :
1194 0 : pool->base.transforms[j] = dce120_transform_create(ctx, i);
1195 0 : if (pool->base.transforms[i] == NULL) {
1196 0 : BREAK_TO_DEBUGGER();
1197 0 : dm_error(
1198 : "DC: failed to create transform!\n");
1199 0 : goto res_create_fail;
1200 : }
1201 :
1202 0 : pool->base.opps[j] = dce120_opp_create(
1203 : ctx,
1204 : i);
1205 0 : if (pool->base.opps[j] == NULL) {
1206 0 : BREAK_TO_DEBUGGER();
1207 0 : dm_error(
1208 : "DC: failed to create output pixel processor!\n");
1209 : }
1210 :
1211 : /* check next valid pipe */
1212 0 : j++;
1213 : }
1214 :
1215 0 : for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1216 0 : pool->base.engines[i] = dce120_aux_engine_create(ctx, i);
1217 0 : if (pool->base.engines[i] == NULL) {
1218 0 : BREAK_TO_DEBUGGER();
1219 0 : dm_error(
1220 : "DC:failed to create aux engine!!\n");
1221 0 : goto res_create_fail;
1222 : }
1223 0 : pool->base.hw_i2cs[i] = dce120_i2c_hw_create(ctx, i);
1224 0 : if (pool->base.hw_i2cs[i] == NULL) {
1225 0 : BREAK_TO_DEBUGGER();
1226 0 : dm_error(
1227 : "DC:failed to create i2c engine!!\n");
1228 0 : goto res_create_fail;
1229 : }
1230 0 : pool->base.sw_i2cs[i] = NULL;
1231 : }
1232 :
1233 : /* valid pipe num */
1234 0 : pool->base.pipe_count = j;
1235 0 : pool->base.timing_generator_count = j;
1236 :
1237 0 : if (is_vg20)
1238 0 : res_funcs = &dce121_res_create_funcs;
1239 : else
1240 0 : res_funcs = &res_create_funcs;
1241 :
1242 0 : if (!resource_construct(num_virtual_links, dc, &pool->base, res_funcs))
1243 : goto res_create_fail;
1244 :
1245 : /* Create hardware sequencer */
1246 0 : if (!dce120_hw_sequencer_create(dc))
1247 : goto controller_create_fail;
1248 :
1249 0 : dc->caps.max_planes = pool->base.pipe_count;
1250 :
1251 0 : for (i = 0; i < dc->caps.max_planes; ++i)
1252 0 : dc->caps.planes[i] = plane_cap;
1253 :
1254 0 : bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
1255 :
1256 0 : bw_calcs_data_update_from_pplib(dc);
1257 :
1258 0 : return true;
1259 :
1260 : irqs_create_fail:
1261 : controller_create_fail:
1262 : clk_src_create_fail:
1263 : res_create_fail:
1264 :
1265 0 : dce120_resource_destruct(pool);
1266 :
1267 0 : return false;
1268 : }
1269 :
1270 0 : struct resource_pool *dce120_create_resource_pool(
1271 : uint8_t num_virtual_links,
1272 : struct dc *dc)
1273 : {
1274 0 : struct dce110_resource_pool *pool =
1275 : kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1276 :
1277 0 : if (!pool)
1278 : return NULL;
1279 :
1280 0 : if (dce120_resource_construct(num_virtual_links, dc, pool))
1281 0 : return &pool->base;
1282 :
1283 0 : kfree(pool);
1284 0 : BREAK_TO_DEBUGGER();
1285 0 : return NULL;
1286 : }
|