drm/amd/display: Add renoir hw_seq
[linux-2.6-block.git] / drivers / gpu / drm / amd / display / dc / dcn21 / dcn21_resource.c
CommitLineData
6f4e6361
BL
1/*
2* Copyright 2018 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 "dcn20/dcn20_resource.h"
32
33#include "clk_mgr.h"
34#include "dcn10/dcn10_hubp.h"
35#include "dcn10/dcn10_ipp.h"
36#include "dcn20/dcn20_hubbub.h"
37#include "dcn20/dcn20_mpc.h"
38#include "dcn20/dcn20_hubp.h"
39#include "dcn21_hubp.h"
40#include "irq/dcn21/irq_service_dcn21.h"
41#include "dcn20/dcn20_dpp.h"
42#include "dcn20/dcn20_optc.h"
c0fb59a4 43#include "dcn21/dcn21_hwseq.h"
6f4e6361
BL
44#include "dce110/dce110_hw_sequencer.h"
45#include "dcn20/dcn20_opp.h"
46#include "dcn20/dcn20_dsc.h"
47#include "dcn20/dcn20_link_encoder.h"
48#include "dcn20/dcn20_stream_encoder.h"
49#include "dce/dce_clock_source.h"
50#include "dce/dce_audio.h"
51#include "dce/dce_hwseq.h"
52#include "virtual/virtual_stream_encoder.h"
53#include "dce110/dce110_resource.h"
54#include "dml/display_mode_vba.h"
55#include "dcn20/dcn20_dccg.h"
56#include "dcn21_hubbub.h"
57#include "dcn10/dcn10_resource.h"
58
59#include "dcn20/dcn20_dwb.h"
60#include "dcn20/dcn20_mmhubbub.h"
61
62#include "renoir_ip_offset.h"
63#include "dcn/dcn_2_1_0_offset.h"
64#include "dcn/dcn_2_1_0_sh_mask.h"
65
66#include "nbio/nbio_7_0_offset.h"
67
68#include "mmhub/mmhub_2_0_0_offset.h"
69#include "mmhub/mmhub_2_0_0_sh_mask.h"
70
71#include "reg_helper.h"
72#include "dce/dce_abm.h"
73#include "dce/dce_dmcu.h"
74#include "dce/dce_aux.h"
75#include "dce/dce_i2c.h"
76#include "dcn21_resource.h"
77#include "vm_helper.h"
78#include "dcn20/dcn20_vmid.h"
79
80#define SOC_BOUNDING_BOX_VALID false
81#define DC_LOGGER_INIT(logger)
82
83
84struct _vcs_dpi_ip_params_st dcn2_1_ip = {
85 .gpuvm_enable = 0,
86 .hostvm_enable = 0,
87 .gpuvm_max_page_table_levels = 1,
88 .hostvm_max_page_table_levels = 4,
89 .hostvm_cached_page_table_levels = 2,
90#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
91 .num_dsc = 3,
92#else
93 .num_dsc = 0,
94#endif
95 .rob_buffer_size_kbytes = 168,
96 .det_buffer_size_kbytes = 164,
97 .dpte_buffer_size_in_pte_reqs_luma = 44,
98 .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
99 .dpp_output_buffer_pixels = 2560,
100 .opp_output_buffer_lines = 1,
101 .pixel_chunk_size_kbytes = 8,
102 .pte_enable = 1,
103 .max_page_table_levels = 4,
104 .pte_chunk_size_kbytes = 2,
105 .meta_chunk_size_kbytes = 2,
106 .writeback_chunk_size_kbytes = 2,
107 .line_buffer_size_bits = 789504,
108 .is_line_buffer_bpp_fixed = 0,
109 .line_buffer_fixed_bpp = 0,
110 .dcc_supported = true,
111 .max_line_buffer_lines = 12,
112 .writeback_luma_buffer_size_kbytes = 12,
113 .writeback_chroma_buffer_size_kbytes = 8,
114 .writeback_chroma_line_buffer_width_pixels = 4,
115 .writeback_max_hscl_ratio = 1,
116 .writeback_max_vscl_ratio = 1,
117 .writeback_min_hscl_ratio = 1,
118 .writeback_min_vscl_ratio = 1,
119 .writeback_max_hscl_taps = 12,
120 .writeback_max_vscl_taps = 12,
121 .writeback_line_buffer_luma_buffer_size = 0,
122 .writeback_line_buffer_chroma_buffer_size = 14643,
123 .cursor_buffer_size = 8,
124 .cursor_chunk_size = 2,
125 .max_num_otg = 4,
126 .max_num_dpp = 4,
127 .max_num_wb = 1,
128 .max_dchub_pscl_bw_pix_per_clk = 4,
129 .max_pscl_lb_bw_pix_per_clk = 2,
130 .max_lb_vscl_bw_pix_per_clk = 4,
131 .max_vscl_hscl_bw_pix_per_clk = 4,
132 .max_hscl_ratio = 4,
133 .max_vscl_ratio = 4,
134 .hscl_mults = 4,
135 .vscl_mults = 4,
136 .max_hscl_taps = 8,
137 .max_vscl_taps = 8,
138 .dispclk_ramp_margin_percent = 1,
139 .underscan_factor = 1.10,
140 .min_vblank_lines = 32, //
141 .dppclk_delay_subtotal = 77, //
142 .dppclk_delay_scl_lb_only = 16,
143 .dppclk_delay_scl = 50,
144 .dppclk_delay_cnvc_formatter = 8,
145 .dppclk_delay_cnvc_cursor = 6,
146 .dispclk_delay_subtotal = 87, //
147 .dcfclk_cstate_latency = 10, // SRExitTime
148 .max_inter_dcn_tile_repeaters = 8,
149
150 .xfc_supported = false,
151 .xfc_fill_bw_overhead_percent = 10.0,
152 .xfc_fill_constant_bytes = 0,
153 .ptoi_supported = 0
154};
155
156struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
157 .clock_limits = {
158 {
159 .state = 0,
160 .dcfclk_mhz = 304.0,
161 .fabricclk_mhz = 600.0,
162 .dispclk_mhz = 618.0,
163 .dppclk_mhz = 440.0,
164 .phyclk_mhz = 600.0,
165 .socclk_mhz = 278.0,
166 .dscclk_mhz = 205.67,
167 .dram_speed_mts = 1600.0,
168 },
169 {
170 .state = 1,
171 .dcfclk_mhz = 304.0,
172 .fabricclk_mhz = 600.0,
173 .dispclk_mhz = 618.0,
174 .dppclk_mhz = 618.0,
175 .phyclk_mhz = 600.0,
176 .socclk_mhz = 278.0,
177 .dscclk_mhz = 205.67,
178 .dram_speed_mts = 1600.0,
179 },
180 {
181 .state = 2,
182 .dcfclk_mhz = 608.0,
183 .fabricclk_mhz = 1066.0,
184 .dispclk_mhz = 888.0,
185 .dppclk_mhz = 888.0,
186 .phyclk_mhz = 810.0,
187 .socclk_mhz = 278.0,
188 .dscclk_mhz = 287.67,
189 .dram_speed_mts = 2133.0,
190 },
191 {
192 .state = 3,
193 .dcfclk_mhz = 676.0,
194 .fabricclk_mhz = 1600.0,
195 .dispclk_mhz = 1015.0,
196 .dppclk_mhz = 1015.0,
197 .phyclk_mhz = 810.0,
198 .socclk_mhz = 715.0,
199 .dscclk_mhz = 318.334,
200 .dram_speed_mts = 4266.0,
201 },
202 {
203 .state = 4,
204 .dcfclk_mhz = 810.0,
205 .fabricclk_mhz = 1600.0,
206 .dispclk_mhz = 1015.0,
207 .dppclk_mhz = 1015.0,
208 .phyclk_mhz = 810.0,
209 .socclk_mhz = 953.0,
210 .dscclk_mhz = 318.334,
211 .dram_speed_mts = 4266.0,
212 },
213 /*Extra state, no dispclk ramping*/
214 {
215 .state = 5,
216 .dcfclk_mhz = 810.0,
217 .fabricclk_mhz = 1600.0,
218 .dispclk_mhz = 1015.0,
219 .dppclk_mhz = 1015.0,
220 .phyclk_mhz = 810.0,
221 .socclk_mhz = 953.0,
222 .dscclk_mhz = 318.334,
223 .dram_speed_mts = 4266.0,
224 },
225
226 },
227
228 .sr_exit_time_us = 9.0,
229 .sr_enter_plus_exit_time_us = 11.0,
230 .urgent_latency_us = 4.0,
231 .urgent_latency_pixel_data_only_us = 4.0,
232 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
233 .urgent_latency_vm_data_only_us = 4.0,
234 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
235 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
236 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
237 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
238 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
239 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
240 .max_avg_sdp_bw_use_normal_percent = 60.0,
241 .max_avg_dram_bw_use_normal_percent = 100.0,
242 .writeback_latency_us = 12.0,
243 .max_request_size_bytes = 256,
244 .dram_channel_width_bytes = 4,
245 .fabric_datapath_to_dcn_data_return_bytes = 32,
246 .dcn_downspread_percent = 0.5,
247 .downspread_percent = 0.5,
248 .dram_page_open_time_ns = 50.0,
249 .dram_rw_turnaround_time_ns = 17.5,
250 .dram_return_buffer_per_channel_bytes = 8192,
251 .round_trip_ping_latency_dcfclk_cycles = 128,
252 .urgent_out_of_order_return_per_channel_bytes = 4096,
253 .channel_interleave_bytes = 256,
254 .num_banks = 8,
255 .num_chans = 4,
256 .vmm_page_size_bytes = 4096,
257 .dram_clock_change_latency_us = 23.84,
258 .return_bus_width_bytes = 64,
259 .dispclk_dppclk_vco_speed_mhz = 3550,
260 .xfc_bus_transport_time_us = 4,
261 .xfc_xbuf_latency_tolerance_us = 4,
262 .use_urgent_burst_bw = 1,
263 .num_states = 5
264};
265
266#ifndef MAX
267#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
268#endif
269#ifndef MIN
270#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
271#endif
272
273/* begin *********************
274 * macros to expend register list macro defined in HW object header file */
275
276/* DCN */
277/* TODO awful hack. fixup dcn20_dwb.h */
278#undef BASE_INNER
279#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
280
281#define BASE(seg) BASE_INNER(seg)
282
283#define SR(reg_name)\
284 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
285 mm ## reg_name
286
287#define SRI(reg_name, block, id)\
288 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
289 mm ## block ## id ## _ ## reg_name
290
291#define SRIR(var_name, reg_name, block, id)\
292 .var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
293 mm ## block ## id ## _ ## reg_name
294
295#define SRII(reg_name, block, id)\
296 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
297 mm ## block ## id ## _ ## reg_name
298
299#define DCCG_SRII(reg_name, block, id)\
300 .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
301 mm ## block ## id ## _ ## reg_name
302
303/* NBIO */
304#define NBIO_BASE_INNER(seg) \
305 NBIF0_BASE__INST0_SEG ## seg
306
307#define NBIO_BASE(seg) \
308 NBIO_BASE_INNER(seg)
309
310#define NBIO_SR(reg_name)\
311 .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
312 mm ## reg_name
313
314/* MMHUB */
315#define MMHUB_BASE_INNER(seg) \
316 MMHUB_BASE__INST0_SEG ## seg
317
318#define MMHUB_BASE(seg) \
319 MMHUB_BASE_INNER(seg)
320
321#define MMHUB_SR(reg_name)\
322 .reg_name = MMHUB_BASE(mmMM ## reg_name ## _BASE_IDX) + \
323 mmMM ## reg_name
324
325#define clk_src_regs(index, pllid)\
326[index] = {\
327 CS_COMMON_REG_LIST_DCN2_1(index, pllid),\
328}
329
330static const struct dce110_clk_src_regs clk_src_regs[] = {
331 clk_src_regs(0, A),
332 clk_src_regs(1, B),
333 clk_src_regs(2, C),
334 clk_src_regs(3, D),
335 clk_src_regs(4, E),
336};
337
338static const struct dce110_clk_src_shift cs_shift = {
339 CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
340};
341
342static const struct dce110_clk_src_mask cs_mask = {
343 CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
344};
345
346static const struct bios_registers bios_regs = {
347 NBIO_SR(BIOS_SCRATCH_3),
348 NBIO_SR(BIOS_SCRATCH_6)
349};
350
c0fb59a4
BL
351static const struct dce_dmcu_registers dmcu_regs = {
352 DMCU_DCN10_REG_LIST()
353};
354
355static const struct dce_dmcu_shift dmcu_shift = {
356 DMCU_MASK_SH_LIST_DCN10(__SHIFT)
357};
358
359static const struct dce_dmcu_mask dmcu_mask = {
360 DMCU_MASK_SH_LIST_DCN10(_MASK)
361};
362
363static const struct dce_abm_registers abm_regs = {
364 ABM_DCN20_REG_LIST()
365};
366
367static const struct dce_abm_shift abm_shift = {
368 ABM_MASK_SH_LIST_DCN20(__SHIFT)
369};
370
371static const struct dce_abm_mask abm_mask = {
372 ABM_MASK_SH_LIST_DCN20(_MASK)
373};
374
6f4e6361
BL
375#ifdef CONFIG_DRM_AMD_DC_DMUB
376static const struct dcn21_dmcub_registers dmcub_regs = {
377 DMCUB_REG_LIST_DCN()
378};
379
380static const struct dcn21_dmcub_shift dmcub_shift = {
381 DMCUB_COMMON_MASK_SH_LIST_BASE(__SHIFT)
382};
383
384static const struct dcn21_dmcub_mask dmcub_mask = {
385 DMCUB_COMMON_MASK_SH_LIST_BASE(_MASK)
386};
387#endif
388
389#define audio_regs(id)\
390[id] = {\
391 AUD_COMMON_REG_LIST(id)\
392}
393
394static const struct dce_audio_registers audio_regs[] = {
395 audio_regs(0),
396 audio_regs(1),
397 audio_regs(2),
398 audio_regs(3),
399 audio_regs(4),
400 audio_regs(5),
401};
402
403#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
404 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
405 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
406 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
407
408static const struct dce_audio_shift audio_shift = {
409 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
410};
411
412static const struct dce_audio_mask audio_mask = {
413 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
414};
415
416static const struct dccg_registers dccg_regs = {
417 DCCG_COMMON_REG_LIST_DCN_BASE()
418};
419
420static const struct dccg_shift dccg_shift = {
421 DCCG_MASK_SH_LIST_DCN2(__SHIFT)
422};
423
424static const struct dccg_mask dccg_mask = {
425 DCCG_MASK_SH_LIST_DCN2(_MASK)
426};
427
428#define opp_regs(id)\
429[id] = {\
430 OPP_REG_LIST_DCN20(id),\
431}
432
433static const struct dcn20_opp_registers opp_regs[] = {
434 opp_regs(0),
435 opp_regs(1),
436 opp_regs(2),
437 opp_regs(3),
438 opp_regs(4),
439 opp_regs(5),
440};
441
442static const struct dcn20_opp_shift opp_shift = {
443 OPP_MASK_SH_LIST_DCN20(__SHIFT)
444};
445
446static const struct dcn20_opp_mask opp_mask = {
447 OPP_MASK_SH_LIST_DCN20(_MASK)
448};
449
450#define tg_regs(id)\
451[id] = {TG_COMMON_REG_LIST_DCN2_0(id)}
452
453static const struct dcn_optc_registers tg_regs[] = {
454 tg_regs(0),
455 tg_regs(1),
456 tg_regs(2),
457 tg_regs(3)
458};
459
460static const struct dcn_optc_shift tg_shift = {
461 TG_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
462};
463
464static const struct dcn_optc_mask tg_mask = {
465 TG_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
466};
467
468static const struct dcn20_mpc_registers mpc_regs = {
469 MPC_REG_LIST_DCN2_0(0),
470 MPC_REG_LIST_DCN2_0(1),
471 MPC_REG_LIST_DCN2_0(2),
472 MPC_REG_LIST_DCN2_0(3),
473 MPC_REG_LIST_DCN2_0(4),
474 MPC_REG_LIST_DCN2_0(5),
475 MPC_OUT_MUX_REG_LIST_DCN2_0(0),
476 MPC_OUT_MUX_REG_LIST_DCN2_0(1),
477 MPC_OUT_MUX_REG_LIST_DCN2_0(2),
478 MPC_OUT_MUX_REG_LIST_DCN2_0(3)
479};
480
481static const struct dcn20_mpc_shift mpc_shift = {
482 MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
483};
484
485static const struct dcn20_mpc_mask mpc_mask = {
486 MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
487};
488
489#define hubp_regs(id)\
490[id] = {\
491 HUBP_REG_LIST_DCN21(id)\
492}
493
494static const struct dcn_hubp2_registers hubp_regs[] = {
495 hubp_regs(0),
496 hubp_regs(1),
497 hubp_regs(2),
498 hubp_regs(3)
499};
500
501static const struct dcn_hubp2_shift hubp_shift = {
502 HUBP_MASK_SH_LIST_DCN21(__SHIFT)
503};
504
505static const struct dcn_hubp2_mask hubp_mask = {
506 HUBP_MASK_SH_LIST_DCN21(_MASK)
507};
508
509static const struct dcn_hubbub_registers hubbub_reg = {
510 HUBBUB_REG_LIST_DCN21()
511};
512
513static const struct dcn_hubbub_shift hubbub_shift = {
514 HUBBUB_MASK_SH_LIST_DCN21(__SHIFT)
515};
516
517static const struct dcn_hubbub_mask hubbub_mask = {
518 HUBBUB_MASK_SH_LIST_DCN21(_MASK)
519};
520
521
522#define vmid_regs(id)\
523[id] = {\
524 DCN20_VMID_REG_LIST(id)\
525}
526
527static const struct dcn_vmid_registers vmid_regs[] = {
528 vmid_regs(0),
529 vmid_regs(1),
530 vmid_regs(2),
531 vmid_regs(3),
532 vmid_regs(4),
533 vmid_regs(5),
534 vmid_regs(6),
535 vmid_regs(7),
536 vmid_regs(8),
537 vmid_regs(9),
538 vmid_regs(10),
539 vmid_regs(11),
540 vmid_regs(12),
541 vmid_regs(13),
542 vmid_regs(14),
543 vmid_regs(15)
544};
545
546static const struct dcn20_vmid_shift vmid_shifts = {
547 DCN20_VMID_MASK_SH_LIST(__SHIFT)
548};
549
550static const struct dcn20_vmid_mask vmid_masks = {
551 DCN20_VMID_MASK_SH_LIST(_MASK)
552};
553
554#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
555#define dsc_regsDCN20(id)\
556[id] = {\
557 DSC_REG_LIST_DCN20(id)\
558}
559
560static const struct dcn20_dsc_registers dsc_regs[] = {
561 dsc_regsDCN20(0),
562 dsc_regsDCN20(1),
563 dsc_regsDCN20(2),
564 dsc_regsDCN20(3),
565 dsc_regsDCN20(4),
566 dsc_regsDCN20(5)
567};
568
569static const struct dcn20_dsc_shift dsc_shift = {
570 DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
571};
572
573static const struct dcn20_dsc_mask dsc_mask = {
574 DSC_REG_LIST_SH_MASK_DCN20(_MASK)
575};
576#endif
577
578#define ipp_regs(id)\
579[id] = {\
580 IPP_REG_LIST_DCN20(id),\
581}
582
583static const struct dcn10_ipp_registers ipp_regs[] = {
584 ipp_regs(0),
585 ipp_regs(1),
586 ipp_regs(2),
587 ipp_regs(3),
588};
589
590static const struct dcn10_ipp_shift ipp_shift = {
591 IPP_MASK_SH_LIST_DCN20(__SHIFT)
592};
593
594static const struct dcn10_ipp_mask ipp_mask = {
595 IPP_MASK_SH_LIST_DCN20(_MASK),
596};
597
598#define opp_regs(id)\
599[id] = {\
600 OPP_REG_LIST_DCN20(id),\
601}
602
603
604#define aux_engine_regs(id)\
605[id] = {\
606 AUX_COMMON_REG_LIST0(id), \
607 .AUXN_IMPCAL = 0, \
608 .AUXP_IMPCAL = 0, \
609 .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
610}
611
612static const struct dce110_aux_registers aux_engine_regs[] = {
613 aux_engine_regs(0),
614 aux_engine_regs(1),
615 aux_engine_regs(2),
616 aux_engine_regs(3),
617 aux_engine_regs(4),
618};
619
620#define tf_regs(id)\
621[id] = {\
622 TF_REG_LIST_DCN20(id),\
623}
624
625static const struct dcn2_dpp_registers tf_regs[] = {
626 tf_regs(0),
627 tf_regs(1),
628 tf_regs(2),
629 tf_regs(3),
630};
631
632static const struct dcn2_dpp_shift tf_shift = {
633 TF_REG_LIST_SH_MASK_DCN20(__SHIFT)
634};
635
636static const struct dcn2_dpp_mask tf_mask = {
637 TF_REG_LIST_SH_MASK_DCN20(_MASK)
638};
639
640#define stream_enc_regs(id)\
641[id] = {\
642 SE_DCN2_REG_LIST(id)\
643}
644
645static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
646 stream_enc_regs(0),
647 stream_enc_regs(1),
648 stream_enc_regs(2),
649 stream_enc_regs(3),
650 stream_enc_regs(4),
651};
652
8276dd87 653static const struct dce110_aux_registers_shift aux_shift = {
654 DCN_AUX_MASK_SH_LIST(__SHIFT)
655};
656
657static const struct dce110_aux_registers_mask aux_mask = {
658 DCN_AUX_MASK_SH_LIST(_MASK)
659};
660
6f4e6361
BL
661static const struct dcn10_stream_encoder_shift se_shift = {
662 SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT)
663};
664
665static const struct dcn10_stream_encoder_mask se_mask = {
666 SE_COMMON_MASK_SH_LIST_DCN20(_MASK)
667};
668
44e149bb
AD
669static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
670
6f4e6361
BL
671static struct input_pixel_processor *dcn21_ipp_create(
672 struct dc_context *ctx, uint32_t inst)
673{
674 struct dcn10_ipp *ipp =
675 kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL);
676
677 if (!ipp) {
678 BREAK_TO_DEBUGGER();
679 return NULL;
680 }
681
682 dcn20_ipp_construct(ipp, ctx, inst,
683 &ipp_regs[inst], &ipp_shift, &ipp_mask);
684 return &ipp->base;
685}
686
687static struct dpp *dcn21_dpp_create(
688 struct dc_context *ctx,
689 uint32_t inst)
690{
691 struct dcn20_dpp *dpp =
692 kzalloc(sizeof(struct dcn20_dpp), GFP_KERNEL);
693
694 if (!dpp)
695 return NULL;
696
697 if (dpp2_construct(dpp, ctx, inst,
698 &tf_regs[inst], &tf_shift, &tf_mask))
699 return &dpp->base;
700
701 BREAK_TO_DEBUGGER();
702 kfree(dpp);
703 return NULL;
704}
705
706static struct dce_aux *dcn21_aux_engine_create(
707 struct dc_context *ctx,
708 uint32_t inst)
709{
710 struct aux_engine_dce110 *aux_engine =
711 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
712
713 if (!aux_engine)
714 return NULL;
715
716 dce110_aux_engine_construct(aux_engine, ctx, inst,
717 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
8276dd87 718 &aux_engine_regs[inst],
719 &aux_mask,
f6040a43 720 &aux_shift,
721 ctx->dc->caps.extended_aux_timeout_support);
6f4e6361
BL
722
723 return &aux_engine->base;
724}
725
726#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
727
728static const struct dce_i2c_registers i2c_hw_regs[] = {
729 i2c_inst_regs(1),
730 i2c_inst_regs(2),
731 i2c_inst_regs(3),
732 i2c_inst_regs(4),
733 i2c_inst_regs(5),
734};
735
736static const struct dce_i2c_shift i2c_shifts = {
737 I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT)
738};
739
740static const struct dce_i2c_mask i2c_masks = {
741 I2C_COMMON_MASK_SH_LIST_DCN2(_MASK)
742};
743
744struct dce_i2c_hw *dcn21_i2c_hw_create(
745 struct dc_context *ctx,
746 uint32_t inst)
747{
748 struct dce_i2c_hw *dce_i2c_hw =
749 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
750
751 if (!dce_i2c_hw)
752 return NULL;
753
754 dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
755 &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
756
757 return dce_i2c_hw;
758}
759
760static const struct resource_caps res_cap_rn = {
761 .num_timing_generator = 4,
762 .num_opp = 4,
763 .num_video_plane = 4,
b356843e 764 .num_audio = 4, // 4 audio endpoints. 4 audio streams
6f4e6361
BL
765 .num_stream_encoder = 5,
766 .num_pll = 5, // maybe 3 because the last two used for USB-c
767 .num_dwb = 1,
768 .num_ddc = 5,
769#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
770 .num_dsc = 3,
771#endif
772};
773
774#ifdef DIAGS_BUILD
775static const struct resource_caps res_cap_rn_FPGA_4pipe = {
776 .num_timing_generator = 4,
777 .num_opp = 4,
778 .num_video_plane = 4,
779 .num_audio = 7,
780 .num_stream_encoder = 4,
781 .num_pll = 4,
782 .num_dwb = 1,
783 .num_ddc = 4,
784 .num_dsc = 0,
785};
786
787static const struct resource_caps res_cap_rn_FPGA_2pipe_dsc = {
788 .num_timing_generator = 2,
789 .num_opp = 2,
790 .num_video_plane = 2,
791 .num_audio = 7,
792 .num_stream_encoder = 2,
793 .num_pll = 4,
794 .num_dwb = 1,
795 .num_ddc = 4,
796#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
797 .num_dsc = 2,
798#endif
799};
800#endif
801
802static const struct dc_plane_cap plane_cap = {
803 .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
804 .blends_with_above = true,
805 .blends_with_below = true,
806 .per_pixel_alpha = true,
807
808 .pixel_format_support = {
809 .argb8888 = true,
810 .nv12 = true,
811 .fp16 = true
812 },
813
814 .max_upscale_factor = {
815 .argb8888 = 16000,
816 .nv12 = 16000,
817 .fp16 = 16000
818 },
819
820 .max_downscale_factor = {
821 .argb8888 = 250,
822 .nv12 = 250,
823 .fp16 = 250
824 }
825};
826
827static const struct dc_debug_options debug_defaults_drv = {
828 .disable_dmcu = true,
829 .force_abm_enable = false,
830 .timing_trace = false,
831 .clock_trace = true,
832 .disable_pplib_clock_request = true,
833 .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
834 .force_single_disp_pipe_split = true,
835 .disable_dcc = DCC_ENABLE,
836 .vsr_support = true,
837 .performance_trace = false,
838 .max_downscale_src_width = 5120,/*upto 5K*/
839 .disable_pplib_wm_range = false,
840 .scl_reset_length10 = true,
841 .sanity_checks = true,
57133a28 842 .disable_48mhz_pwrdwn = false,
6f4e6361
BL
843};
844
845static const struct dc_debug_options debug_defaults_diags = {
846 .disable_dmcu = true,
847 .force_abm_enable = false,
848 .timing_trace = true,
849 .clock_trace = true,
850 .disable_dpp_power_gate = true,
851 .disable_hubp_power_gate = true,
852 .disable_clock_gate = true,
853 .disable_pplib_clock_request = true,
854 .disable_pplib_wm_range = true,
855 .disable_stutter = true,
856 .disable_48mhz_pwrdwn = true,
857};
858
859enum dcn20_clk_src_array_id {
860 DCN20_CLK_SRC_PLL0,
861 DCN20_CLK_SRC_PLL1,
862 DCN20_CLK_SRC_TOTAL_DCN21
863};
864
865static void destruct(struct dcn21_resource_pool *pool)
866{
867 unsigned int i;
868
869 for (i = 0; i < pool->base.stream_enc_count; i++) {
870 if (pool->base.stream_enc[i] != NULL) {
871 kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
872 pool->base.stream_enc[i] = NULL;
873 }
874 }
875
876#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
877 for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
878 if (pool->base.dscs[i] != NULL)
879 dcn20_dsc_destroy(&pool->base.dscs[i]);
880 }
881#endif
882
883 if (pool->base.mpc != NULL) {
884 kfree(TO_DCN20_MPC(pool->base.mpc));
885 pool->base.mpc = NULL;
886 }
887 if (pool->base.hubbub != NULL) {
888 kfree(pool->base.hubbub);
889 pool->base.hubbub = NULL;
890 }
891 for (i = 0; i < pool->base.pipe_count; i++) {
892 if (pool->base.dpps[i] != NULL)
893 dcn20_dpp_destroy(&pool->base.dpps[i]);
894
895 if (pool->base.ipps[i] != NULL)
896 pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
897
898 if (pool->base.hubps[i] != NULL) {
899 kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
900 pool->base.hubps[i] = NULL;
901 }
902
903 if (pool->base.irqs != NULL) {
904 dal_irq_service_destroy(&pool->base.irqs);
905 }
906 }
907
908 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
909 if (pool->base.engines[i] != NULL)
910 dce110_engine_destroy(&pool->base.engines[i]);
911 if (pool->base.hw_i2cs[i] != NULL) {
912 kfree(pool->base.hw_i2cs[i]);
913 pool->base.hw_i2cs[i] = NULL;
914 }
915 if (pool->base.sw_i2cs[i] != NULL) {
916 kfree(pool->base.sw_i2cs[i]);
917 pool->base.sw_i2cs[i] = NULL;
918 }
919 }
920
921 for (i = 0; i < pool->base.res_cap->num_opp; i++) {
922 if (pool->base.opps[i] != NULL)
923 pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
924 }
925
926 for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
927 if (pool->base.timing_generators[i] != NULL) {
928 kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
929 pool->base.timing_generators[i] = NULL;
930 }
931 }
932
933 for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
934 if (pool->base.dwbc[i] != NULL) {
935 kfree(TO_DCN20_DWBC(pool->base.dwbc[i]));
936 pool->base.dwbc[i] = NULL;
937 }
938 if (pool->base.mcif_wb[i] != NULL) {
939 kfree(TO_DCN20_MMHUBBUB(pool->base.mcif_wb[i]));
940 pool->base.mcif_wb[i] = NULL;
941 }
942 }
943
944 for (i = 0; i < pool->base.audio_count; i++) {
945 if (pool->base.audios[i])
946 dce_aud_destroy(&pool->base.audios[i]);
947 }
948
949 for (i = 0; i < pool->base.clk_src_count; i++) {
950 if (pool->base.clock_sources[i] != NULL) {
951 dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
952 pool->base.clock_sources[i] = NULL;
953 }
954 }
955
956 if (pool->base.dp_clock_source != NULL) {
957 dcn20_clock_source_destroy(&pool->base.dp_clock_source);
958 pool->base.dp_clock_source = NULL;
959 }
960
961
962 if (pool->base.abm != NULL)
963 dce_abm_destroy(&pool->base.abm);
964
965 if (pool->base.dmcu != NULL)
966 dce_dmcu_destroy(&pool->base.dmcu);
967
968#ifdef CONFIG_DRM_AMD_DC_DMUB
969 if (pool->base.dmcub != NULL)
970 dcn21_dmcub_destroy(&pool->base.dmcub);
971#endif
972
973 if (pool->base.dccg != NULL)
974 dcn_dccg_destroy(&pool->base.dccg);
975
976 if (pool->base.pp_smu != NULL)
44e149bb 977 dcn21_pp_smu_destroy(&pool->base.pp_smu);
6f4e6361
BL
978}
979
980
981static void calculate_wm_set_for_vlevel(
982 int vlevel,
983 struct wm_range_table_entry *table_entry,
984 struct dcn_watermarks *wm_set,
985 struct display_mode_lib *dml,
986 display_e2e_pipe_params_st *pipes,
987 int pipe_cnt)
988{
989 double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
990
991 ASSERT(vlevel < dml->soc.num_states);
992 /* only pipe 0 is read for voltage and dcf/soc clocks */
993 pipes[0].clks_cfg.voltage = vlevel;
994 pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
995 pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
996
997 dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
998
999 wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
1000 wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
1001 wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
1002 wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
1003 wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
1004#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
1005 wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
1006 wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
1007#endif
1008 dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
1009
1010}
1011
1012void dcn21_calculate_wm(
1013 struct dc *dc, struct dc_state *context,
1014 display_e2e_pipe_params_st *pipes,
1015 int *out_pipe_cnt,
1016 int *pipe_split_from,
1017 int vlevel_req)
1018{
1019 int pipe_cnt, i, pipe_idx;
1020 int vlevel, vlevel_max;
1021 struct wm_range_table_entry *table_entry;
1022 struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
1023
1024 ASSERT(bw_params);
1025
1026 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1027 if (!context->res_ctx.pipe_ctx[i].stream)
1028 continue;
1029
1030 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
1031 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb];
1032
1033 if (pipe_split_from[i] < 0) {
1034 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
1035 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
1036 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
1037 pipes[pipe_cnt].pipe.dest.odm_combine =
1038 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx];
1039 else
1040 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
1041 pipe_idx++;
1042 } else {
1043 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
1044 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
1045 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
1046 pipes[pipe_cnt].pipe.dest.odm_combine =
1047 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]];
1048 else
1049 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
1050 }
1051 pipe_cnt++;
1052 }
1053
1054 if (pipe_cnt != pipe_idx) {
1055 if (dc->res_pool->funcs->populate_dml_pipes)
1056 pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
1057 &context->res_ctx, pipes);
1058 else
1059 pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
1060 &context->res_ctx, pipes);
1061 }
1062
1063 *out_pipe_cnt = pipe_cnt;
1064
1065 vlevel_max = bw_params->clk_table.num_entries - 1;
1066
1067
1068 /* WM Set D */
1069 table_entry = &bw_params->wm_table.entries[WM_D];
1070 if (table_entry->wm_type == WM_TYPE_RETRAINING)
1071 vlevel = 0;
1072 else
1073 vlevel = vlevel_max;
1074 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
1075 &context->bw_ctx.dml, pipes, pipe_cnt);
1076 /* WM Set C */
1077 table_entry = &bw_params->wm_table.entries[WM_C];
1078 vlevel = MIN(MAX(vlevel_req, 2), vlevel_max);
1079 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
1080 &context->bw_ctx.dml, pipes, pipe_cnt);
1081 /* WM Set B */
1082 table_entry = &bw_params->wm_table.entries[WM_B];
1083 vlevel = MIN(MAX(vlevel_req, 1), vlevel_max);
1084 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
1085 &context->bw_ctx.dml, pipes, pipe_cnt);
1086
1087 /* WM Set A */
1088 table_entry = &bw_params->wm_table.entries[WM_A];
1089 vlevel = MIN(vlevel_req, vlevel_max);
1090 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
1091 &context->bw_ctx.dml, pipes, pipe_cnt);
1092}
1093
1094
1095bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context,
1096 bool fast_validate)
1097{
1098 bool out = false;
1099
1100 BW_VAL_TRACE_SETUP();
1101
1102 int vlevel = 0;
1103 int pipe_split_from[MAX_PIPES];
1104 int pipe_cnt = 0;
1105 display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
1106 DC_LOGGER_INIT(dc->ctx->logger);
1107
1108 BW_VAL_TRACE_COUNT();
1109
1110 out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel);
1111
1112 if (pipe_cnt == 0)
1113 goto validate_out;
1114
1115 if (!out)
1116 goto validate_fail;
1117
1118 BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1119
1120 if (fast_validate) {
1121 BW_VAL_TRACE_SKIP(fast);
1122 goto validate_out;
1123 }
1124
1125 dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel);
1126 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
1127
1128 BW_VAL_TRACE_END_WATERMARKS();
1129
1130 goto validate_out;
1131
1132validate_fail:
1133 DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
1134 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
1135
1136 BW_VAL_TRACE_SKIP(fail);
1137 out = false;
1138
1139validate_out:
1140 kfree(pipes);
1141
1142 BW_VAL_TRACE_FINISH();
1143
1144 return out;
1145}
1146static void dcn21_destroy_resource_pool(struct resource_pool **pool)
1147{
1148 struct dcn21_resource_pool *dcn21_pool = TO_DCN21_RES_POOL(*pool);
1149
1150 destruct(dcn21_pool);
1151 kfree(dcn21_pool);
1152 *pool = NULL;
1153}
1154
1155static struct clock_source *dcn21_clock_source_create(
1156 struct dc_context *ctx,
1157 struct dc_bios *bios,
1158 enum clock_source_id id,
1159 const struct dce110_clk_src_regs *regs,
1160 bool dp_clk_src)
1161{
1162 struct dce110_clk_src *clk_src =
1163 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
1164
1165 if (!clk_src)
1166 return NULL;
1167
1168 if (dcn20_clk_src_construct(clk_src, ctx, bios, id,
1169 regs, &cs_shift, &cs_mask)) {
1170 clk_src->base.dp_clk_src = dp_clk_src;
1171 return &clk_src->base;
1172 }
1173
1174 BREAK_TO_DEBUGGER();
1175 return NULL;
1176}
1177
1178static struct hubp *dcn21_hubp_create(
1179 struct dc_context *ctx,
1180 uint32_t inst)
1181{
1182 struct dcn21_hubp *hubp21 =
1183 kzalloc(sizeof(struct dcn21_hubp), GFP_KERNEL);
1184
1185 if (!hubp21)
1186 return NULL;
1187
1188 if (hubp21_construct(hubp21, ctx, inst,
1189 &hubp_regs[inst], &hubp_shift, &hubp_mask))
1190 return &hubp21->base;
1191
1192 BREAK_TO_DEBUGGER();
1193 kfree(hubp21);
1194 return NULL;
1195}
1196
1197static struct hubbub *dcn21_hubbub_create(struct dc_context *ctx)
1198{
1199 int i;
1200
1201 struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub),
1202 GFP_KERNEL);
1203
1204 if (!hubbub)
1205 return NULL;
1206
1207 hubbub21_construct(hubbub, ctx,
1208 &hubbub_reg,
1209 &hubbub_shift,
1210 &hubbub_mask);
1211
1212 for (i = 0; i < res_cap_rn.num_vmid; i++) {
1213 struct dcn20_vmid *vmid = &hubbub->vmid[i];
1214
1215 vmid->ctx = ctx;
1216
1217 vmid->regs = &vmid_regs[i];
1218 vmid->shifts = &vmid_shifts;
1219 vmid->masks = &vmid_masks;
1220 }
1221
1222 return &hubbub->base;
1223}
1224
1225struct output_pixel_processor *dcn21_opp_create(
1226 struct dc_context *ctx, uint32_t inst)
1227{
1228 struct dcn20_opp *opp =
1229 kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
1230
1231 if (!opp) {
1232 BREAK_TO_DEBUGGER();
1233 return NULL;
1234 }
1235
1236 dcn20_opp_construct(opp, ctx, inst,
1237 &opp_regs[inst], &opp_shift, &opp_mask);
1238 return &opp->base;
1239}
1240
1241struct timing_generator *dcn21_timing_generator_create(
1242 struct dc_context *ctx,
1243 uint32_t instance)
1244{
1245 struct optc *tgn10 =
1246 kzalloc(sizeof(struct optc), GFP_KERNEL);
1247
1248 if (!tgn10)
1249 return NULL;
1250
1251 tgn10->base.inst = instance;
1252 tgn10->base.ctx = ctx;
1253
1254 tgn10->tg_regs = &tg_regs[instance];
1255 tgn10->tg_shift = &tg_shift;
1256 tgn10->tg_mask = &tg_mask;
1257
1258 dcn20_timing_generator_init(tgn10);
1259
1260 return &tgn10->base;
1261}
1262
1263struct mpc *dcn21_mpc_create(struct dc_context *ctx)
1264{
1265 struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc),
1266 GFP_KERNEL);
1267
1268 if (!mpc20)
1269 return NULL;
1270
1271 dcn20_mpc_construct(mpc20, ctx,
1272 &mpc_regs,
1273 &mpc_shift,
1274 &mpc_mask,
1275 6);
1276
1277 return &mpc20->base;
1278}
1279
1280static void read_dce_straps(
1281 struct dc_context *ctx,
1282 struct resource_straps *straps)
1283{
1284 generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX),
1285 FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
1286
1287}
1288
1289#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1290
1291struct display_stream_compressor *dcn21_dsc_create(
1292 struct dc_context *ctx, uint32_t inst)
1293{
1294 struct dcn20_dsc *dsc =
1295 kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
1296
1297 if (!dsc) {
1298 BREAK_TO_DEBUGGER();
1299 return NULL;
1300 }
1301
1302 dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
1303 return &dsc->base;
1304}
1305#endif
1306
1307static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
1308{
1309 struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
1310 struct clk_limit_table *clk_table = &bw_params->clk_table;
1311 int i;
1312
1313 dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
1314 dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
1315 dcn2_1_soc.num_chans = bw_params->num_channels;
6f4e6361
BL
1316
1317 for (i = 0; i < clk_table->num_entries; i++) {
1318
1319 dcn2_1_soc.clock_limits[i].state = i;
1320 dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
1321 dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
1322 dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
1323 /* This is probably wrong, TODO: find correct calculation */
1324 dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000;
6f4e6361 1325 }
976035dd
DL
1326 dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i];
1327 dcn2_1_soc.num_states = i;
6f4e6361
BL
1328}
1329
1330/* Temporary Place holder until we can get them from fuse */
1331static struct dpm_clocks dummy_clocks = {
1332 .DcfClocks = {
1333 {.Freq = 400, .Vol = 1},
1334 {.Freq = 483, .Vol = 1},
1335 {.Freq = 602, .Vol = 1},
1336 {.Freq = 738, .Vol = 1} },
1337 .SocClocks = {
1338 {.Freq = 300, .Vol = 1},
1339 {.Freq = 400, .Vol = 1},
1340 {.Freq = 400, .Vol = 1},
1341 {.Freq = 400, .Vol = 1} },
1342 .FClocks = {
1343 {.Freq = 400, .Vol = 1},
1344 {.Freq = 800, .Vol = 1},
1345 {.Freq = 1067, .Vol = 1},
1346 {.Freq = 1600, .Vol = 1} },
1347 .MemClocks = {
1348 {.Freq = 800, .Vol = 1},
1349 {.Freq = 1600, .Vol = 1},
1350 {.Freq = 1067, .Vol = 1},
1351 {.Freq = 1600, .Vol = 1} },
1352
1353};
1354
976035dd 1355static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp,
6f4e6361
BL
1356 struct pp_smu_wm_range_sets *ranges)
1357{
1358 return PP_SMU_RESULT_OK;
1359}
1360
976035dd 1361static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp,
6f4e6361
BL
1362 struct dpm_clocks *clock_table)
1363{
1364 *clock_table = dummy_clocks;
1365 return PP_SMU_RESULT_OK;
1366}
1367
976035dd 1368static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx)
6f4e6361
BL
1369{
1370 struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
1371
a51894f0
EY
1372 if (!pp_smu)
1373 return pp_smu;
6f4e6361 1374
a51894f0
EY
1375 if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
1376 pp_smu->ctx.ver = PP_SMU_VER_RN;
1377 pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table;
1378 pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges;
1379 } else {
1380
1381 dm_pp_get_funcs(ctx, pp_smu);
1382
1383 if (pp_smu->ctx.ver != PP_SMU_VER_RN)
1384 pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs));
1385 }
6f4e6361
BL
1386
1387 return pp_smu;
1388}
1389
976035dd 1390static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
6f4e6361
BL
1391{
1392 if (pp_smu && *pp_smu) {
1393 kfree(*pp_smu);
1394 *pp_smu = NULL;
1395 }
1396}
1397
1398static struct audio *dcn21_create_audio(
1399 struct dc_context *ctx, unsigned int inst)
1400{
1401 return dce_audio_create(ctx, inst,
1402 &audio_regs[inst], &audio_shift, &audio_mask);
1403}
1404
1405static struct dc_cap_funcs cap_funcs = {
1406 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
1407};
1408
1409struct stream_encoder *dcn21_stream_encoder_create(
1410 enum engine_id eng_id,
1411 struct dc_context *ctx)
1412{
1413 struct dcn10_stream_encoder *enc1 =
1414 kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
1415
1416 if (!enc1)
1417 return NULL;
1418
1419 dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id,
1420 &stream_enc_regs[eng_id],
1421 &se_shift, &se_mask);
1422
1423 return &enc1->base;
1424}
1425
1426static const struct dce_hwseq_registers hwseq_reg = {
1427 HWSEQ_DCN21_REG_LIST()
1428};
1429
1430static const struct dce_hwseq_shift hwseq_shift = {
1431 HWSEQ_DCN21_MASK_SH_LIST(__SHIFT)
1432};
1433
1434static const struct dce_hwseq_mask hwseq_mask = {
1435 HWSEQ_DCN21_MASK_SH_LIST(_MASK)
1436};
1437
1438static struct dce_hwseq *dcn21_hwseq_create(
1439 struct dc_context *ctx)
1440{
1441 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
1442
1443 if (hws) {
1444 hws->ctx = ctx;
1445 hws->regs = &hwseq_reg;
1446 hws->shifts = &hwseq_shift;
1447 hws->masks = &hwseq_mask;
1448 }
1449 return hws;
1450}
1451
1452static const struct resource_create_funcs res_create_funcs = {
1453 .read_dce_straps = read_dce_straps,
1454 .create_audio = dcn21_create_audio,
1455 .create_stream_encoder = dcn21_stream_encoder_create,
1456 .create_hwseq = dcn21_hwseq_create,
1457};
1458
1459static const struct resource_create_funcs res_create_maximus_funcs = {
1460 .read_dce_straps = NULL,
1461 .create_audio = NULL,
1462 .create_stream_encoder = NULL,
1463 .create_hwseq = dcn21_hwseq_create,
1464};
1465
c0fb59a4
BL
1466#define CTX ctx
1467
1468#define REG(reg_name) \
1469 (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
1470
1471static uint32_t read_pipe_fuses(struct dc_context *ctx)
1472{
1473 uint32_t value = REG_READ(CC_DC_PIPE_DIS);
1474 /* RV1 support max 4 pipes */
1475 value = value & 0xf;
1476 return value;
1477}
1478
6f4e6361
BL
1479static struct resource_funcs dcn21_res_pool_funcs = {
1480 .destroy = dcn21_destroy_resource_pool,
1481 .link_enc_create = dcn20_link_encoder_create,
1482 .validate_bandwidth = dcn21_validate_bandwidth,
1483 .add_stream_to_ctx = dcn20_add_stream_to_ctx,
1484 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
1485 .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
1486 .populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
1487 .get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
1488 .set_mcif_arb_params = dcn20_set_mcif_arb_params,
1489 .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
1490 .update_bw_bounding_box = update_bw_bounding_box
1491};
1492
1493static bool construct(
1494 uint8_t num_virtual_links,
1495 struct dc *dc,
1496 struct dcn21_resource_pool *pool)
1497{
c0fb59a4 1498 int i, j;
6f4e6361
BL
1499 struct dc_context *ctx = dc->ctx;
1500 struct irq_service_init_data init_data;
c0fb59a4 1501 uint32_t pipe_fuses = read_pipe_fuses(ctx);
6f4e6361
BL
1502
1503 ctx->dc_bios->regs = &bios_regs;
1504
1505 pool->base.res_cap = &res_cap_rn;
1506#ifdef DIAGS_BUILD
1507 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
1508 //pool->base.res_cap = &res_cap_nv10_FPGA_2pipe_dsc;
1509 pool->base.res_cap = &res_cap_rn_FPGA_4pipe;
1510#endif
1511
1512 pool->base.funcs = &dcn21_res_pool_funcs;
1513
1514 /*************************************************
1515 * Resource + asic cap harcoding *
1516 *************************************************/
1517 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1518
c0fb59a4
BL
1519 /* max pipe num for ASIC before check pipe fuses */
1520 pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1521
6f4e6361
BL
1522 dc->caps.max_downscale_ratio = 200;
1523 dc->caps.i2c_speed_in_khz = 100;
1524 dc->caps.max_cursor_size = 256;
1525 dc->caps.dmdata_alloc_size = 2048;
1526 dc->caps.hw_3d_lut = true;
1527
1528 dc->caps.max_slave_planes = 1;
1529 dc->caps.post_blend_color_processing = true;
1530 dc->caps.force_dp_tps4_for_cp2520 = true;
f6040a43 1531 dc->caps.extended_aux_timeout_support = true;
6f4e6361
BL
1532
1533 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
1534 dc->debug = debug_defaults_drv;
1535 else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
1536 pool->base.pipe_count = 4;
1537 dc->debug = debug_defaults_diags;
1538 } else
1539 dc->debug = debug_defaults_diags;
1540
1541 // Init the vm_helper
1542 if (dc->vm_helper)
1543 vm_helper_init(dc->vm_helper, 16);
1544
1545 /*************************************************
1546 * Create resources *
1547 *************************************************/
1548
1549 pool->base.clock_sources[DCN20_CLK_SRC_PLL0] =
1550 dcn21_clock_source_create(ctx, ctx->dc_bios,
1551 CLOCK_SOURCE_COMBO_PHY_PLL0,
1552 &clk_src_regs[0], false);
1553 pool->base.clock_sources[DCN20_CLK_SRC_PLL1] =
1554 dcn21_clock_source_create(ctx, ctx->dc_bios,
1555 CLOCK_SOURCE_COMBO_PHY_PLL1,
1556 &clk_src_regs[1], false);
1557
1558 pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21;
1559
1560 /* todo: not reuse phy_pll registers */
1561 pool->base.dp_clock_source =
1562 dcn21_clock_source_create(ctx, ctx->dc_bios,
1563 CLOCK_SOURCE_ID_DP_DTO,
1564 &clk_src_regs[0], true);
1565
1566 for (i = 0; i < pool->base.clk_src_count; i++) {
1567 if (pool->base.clock_sources[i] == NULL) {
1568 dm_error("DC: failed to create clock sources!\n");
1569 BREAK_TO_DEBUGGER();
1570 goto create_fail;
1571 }
1572 }
1573
1574 pool->base.dccg = dccg2_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
1575 if (pool->base.dccg == NULL) {
1576 dm_error("DC: failed to create dccg!\n");
1577 BREAK_TO_DEBUGGER();
1578 goto create_fail;
1579 }
1580
c0fb59a4
BL
1581 pool->base.dmcu = dcn20_dmcu_create(ctx,
1582 &dmcu_regs,
1583 &dmcu_shift,
1584 &dmcu_mask);
1585 if (pool->base.dmcu == NULL) {
1586 dm_error("DC: failed to create dmcu!\n");
1587 BREAK_TO_DEBUGGER();
1588 goto create_fail;
1589 }
1590
1591 pool->base.abm = dce_abm_create(ctx,
1592 &abm_regs,
1593 &abm_shift,
1594 &abm_mask);
1595 if (pool->base.abm == NULL) {
1596 dm_error("DC: failed to create abm!\n");
1597 BREAK_TO_DEBUGGER();
1598 goto create_fail;
1599 }
1600
6f4e6361
BL
1601#ifdef CONFIG_DRM_AMD_DC_DMUB
1602 pool->base.dmcub = dcn21_dmcub_create(ctx,
1603 &dmcub_regs,
1604 &dmcub_shift,
1605 &dmcub_mask);
1606 if (pool->base.dmcub == NULL) {
1607 dm_error("DC: failed to create dmcub!\n");
1608 BREAK_TO_DEBUGGER();
1609 goto create_fail;
1610 }
1611#endif
1612
1613 pool->base.pp_smu = dcn21_pp_smu_create(ctx);
1614
1615 dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
1616
1617 init_data.ctx = dc->ctx;
1618 pool->base.irqs = dal_irq_service_dcn21_create(&init_data);
1619 if (!pool->base.irqs)
1620 goto create_fail;
1621
c0fb59a4 1622 j = 0;
6f4e6361
BL
1623 /* mem input -> ipp -> dpp -> opp -> TG */
1624 for (i = 0; i < pool->base.pipe_count; i++) {
c0fb59a4
BL
1625 /* if pipe is disabled, skip instance of HW pipe,
1626 * i.e, skip ASIC register instance
1627 */
1628 if ((pipe_fuses & (1 << i)) != 0)
1629 continue;
1630
6f4e6361
BL
1631 pool->base.hubps[i] = dcn21_hubp_create(ctx, i);
1632 if (pool->base.hubps[i] == NULL) {
1633 BREAK_TO_DEBUGGER();
1634 dm_error(
1635 "DC: failed to create memory input!\n");
1636 goto create_fail;
1637 }
1638
1639 pool->base.ipps[i] = dcn21_ipp_create(ctx, i);
1640 if (pool->base.ipps[i] == NULL) {
1641 BREAK_TO_DEBUGGER();
1642 dm_error(
1643 "DC: failed to create input pixel processor!\n");
1644 goto create_fail;
1645 }
1646
1647 pool->base.dpps[i] = dcn21_dpp_create(ctx, i);
1648 if (pool->base.dpps[i] == NULL) {
1649 BREAK_TO_DEBUGGER();
1650 dm_error(
1651 "DC: failed to create dpps!\n");
1652 goto create_fail;
1653 }
c0fb59a4
BL
1654
1655 pool->base.opps[i] = dcn21_opp_create(ctx, i);
1656 if (pool->base.opps[i] == NULL) {
1657 BREAK_TO_DEBUGGER();
1658 dm_error(
1659 "DC: failed to create output pixel processor!\n");
1660 goto create_fail;
1661 }
1662
1663 pool->base.timing_generators[i] = dcn21_timing_generator_create(
1664 ctx, i);
1665 if (pool->base.timing_generators[i] == NULL) {
1666 BREAK_TO_DEBUGGER();
1667 dm_error("DC: failed to create tg!\n");
1668 goto create_fail;
1669 }
1670 j++;
6f4e6361
BL
1671 }
1672
1673 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1674 pool->base.engines[i] = dcn21_aux_engine_create(ctx, i);
1675 if (pool->base.engines[i] == NULL) {
1676 BREAK_TO_DEBUGGER();
1677 dm_error(
1678 "DC:failed to create aux engine!!\n");
1679 goto create_fail;
1680 }
1681 pool->base.hw_i2cs[i] = dcn21_i2c_hw_create(ctx, i);
1682 if (pool->base.hw_i2cs[i] == NULL) {
1683 BREAK_TO_DEBUGGER();
1684 dm_error(
1685 "DC:failed to create hw i2c!!\n");
1686 goto create_fail;
1687 }
1688 pool->base.sw_i2cs[i] = NULL;
1689 }
1690
c0fb59a4
BL
1691 pool->base.timing_generator_count = j;
1692 pool->base.pipe_count = j;
1693 pool->base.mpcc_count = j;
6f4e6361
BL
1694
1695 pool->base.mpc = dcn21_mpc_create(ctx);
1696 if (pool->base.mpc == NULL) {
1697 BREAK_TO_DEBUGGER();
1698 dm_error("DC: failed to create mpc!\n");
1699 goto create_fail;
1700 }
1701
1702 pool->base.hubbub = dcn21_hubbub_create(ctx);
1703 if (pool->base.hubbub == NULL) {
1704 BREAK_TO_DEBUGGER();
1705 dm_error("DC: failed to create hubbub!\n");
1706 goto create_fail;
1707 }
1708
1709#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1710 for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
1711 pool->base.dscs[i] = dcn21_dsc_create(ctx, i);
1712 if (pool->base.dscs[i] == NULL) {
1713 BREAK_TO_DEBUGGER();
1714 dm_error("DC: failed to create display stream compressor %d!\n", i);
1715 goto create_fail;
1716 }
1717 }
1718#endif
1719
1720 if (!dcn20_dwbc_create(ctx, &pool->base)) {
1721 BREAK_TO_DEBUGGER();
1722 dm_error("DC: failed to create dwbc!\n");
1723 goto create_fail;
1724 }
1725 if (!dcn20_mmhubbub_create(ctx, &pool->base)) {
1726 BREAK_TO_DEBUGGER();
1727 dm_error("DC: failed to create mcif_wb!\n");
1728 goto create_fail;
1729 }
1730
1731 if (!resource_construct(num_virtual_links, dc, &pool->base,
1732 (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
1733 &res_create_funcs : &res_create_maximus_funcs)))
1734 goto create_fail;
1735
c0fb59a4 1736 dcn21_hw_sequencer_construct(dc);
6f4e6361
BL
1737
1738 dc->caps.max_planes = pool->base.pipe_count;
1739
1740 for (i = 0; i < dc->caps.max_planes; ++i)
1741 dc->caps.planes[i] = plane_cap;
1742
1743 dc->cap_funcs = cap_funcs;
1744
1745 return true;
1746
1747create_fail:
1748
1749 destruct(pool);
1750
1751 return false;
1752}
1753
1754struct resource_pool *dcn21_create_resource_pool(
1755 const struct dc_init_data *init_data,
1756 struct dc *dc)
1757{
1758 struct dcn21_resource_pool *pool =
1759 kzalloc(sizeof(struct dcn21_resource_pool), GFP_KERNEL);
1760
1761 if (!pool)
1762 return NULL;
1763
1764 if (construct(init_data->num_virtual_links, dc, pool))
1765 return &pool->base;
1766
1767 BREAK_TO_DEBUGGER();
1768 kfree(pool);
1769 return NULL;
1770}