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