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