0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include "resource.h"
0028 #include "clk_mgr.h"
0029 #include "dc_link_dp.h"
0030 #include "dchubbub.h"
0031 #include "dcn20/dcn20_resource.h"
0032 #include "dcn21/dcn21_resource.h"
0033 #include "clk_mgr/dcn21/rn_clk_mgr.h"
0034
0035 #include "dcn20_fpu.h"
0036
0037 #define DC_LOGGER_INIT(logger)
0038
0039 #ifndef MAX
0040 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
0041 #endif
0042 #ifndef MIN
0043 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
0044 #endif
0045
0046
0047 #define LPDDR_MEM_RETRAIN_LATENCY 4.977
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 struct _vcs_dpi_ip_params_st dcn2_0_ip = {
0083 .odm_capable = 1,
0084 .gpuvm_enable = 0,
0085 .hostvm_enable = 0,
0086 .gpuvm_max_page_table_levels = 4,
0087 .hostvm_max_page_table_levels = 4,
0088 .hostvm_cached_page_table_levels = 0,
0089 .pte_group_size_bytes = 2048,
0090 .num_dsc = 6,
0091 .rob_buffer_size_kbytes = 168,
0092 .det_buffer_size_kbytes = 164,
0093 .dpte_buffer_size_in_pte_reqs_luma = 84,
0094 .pde_proc_buffer_size_64k_reqs = 48,
0095 .dpp_output_buffer_pixels = 2560,
0096 .opp_output_buffer_lines = 1,
0097 .pixel_chunk_size_kbytes = 8,
0098 .pte_chunk_size_kbytes = 2,
0099 .meta_chunk_size_kbytes = 2,
0100 .writeback_chunk_size_kbytes = 2,
0101 .line_buffer_size_bits = 789504,
0102 .is_line_buffer_bpp_fixed = 0,
0103 .line_buffer_fixed_bpp = 0,
0104 .dcc_supported = true,
0105 .max_line_buffer_lines = 12,
0106 .writeback_luma_buffer_size_kbytes = 12,
0107 .writeback_chroma_buffer_size_kbytes = 8,
0108 .writeback_chroma_line_buffer_width_pixels = 4,
0109 .writeback_max_hscl_ratio = 1,
0110 .writeback_max_vscl_ratio = 1,
0111 .writeback_min_hscl_ratio = 1,
0112 .writeback_min_vscl_ratio = 1,
0113 .writeback_max_hscl_taps = 12,
0114 .writeback_max_vscl_taps = 12,
0115 .writeback_line_buffer_luma_buffer_size = 0,
0116 .writeback_line_buffer_chroma_buffer_size = 14643,
0117 .cursor_buffer_size = 8,
0118 .cursor_chunk_size = 2,
0119 .max_num_otg = 6,
0120 .max_num_dpp = 6,
0121 .max_num_wb = 1,
0122 .max_dchub_pscl_bw_pix_per_clk = 4,
0123 .max_pscl_lb_bw_pix_per_clk = 2,
0124 .max_lb_vscl_bw_pix_per_clk = 4,
0125 .max_vscl_hscl_bw_pix_per_clk = 4,
0126 .max_hscl_ratio = 8,
0127 .max_vscl_ratio = 8,
0128 .hscl_mults = 4,
0129 .vscl_mults = 4,
0130 .max_hscl_taps = 8,
0131 .max_vscl_taps = 8,
0132 .dispclk_ramp_margin_percent = 1,
0133 .underscan_factor = 1.10,
0134 .min_vblank_lines = 32,
0135 .dppclk_delay_subtotal = 77,
0136 .dppclk_delay_scl_lb_only = 16,
0137 .dppclk_delay_scl = 50,
0138 .dppclk_delay_cnvc_formatter = 8,
0139 .dppclk_delay_cnvc_cursor = 6,
0140 .dispclk_delay_subtotal = 87,
0141 .dcfclk_cstate_latency = 10,
0142 .max_inter_dcn_tile_repeaters = 8,
0143 .xfc_supported = true,
0144 .xfc_fill_bw_overhead_percent = 10.0,
0145 .xfc_fill_constant_bytes = 0,
0146 .number_of_cursors = 1,
0147 };
0148
0149 struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = {
0150 .odm_capable = 1,
0151 .gpuvm_enable = 0,
0152 .hostvm_enable = 0,
0153 .gpuvm_max_page_table_levels = 4,
0154 .hostvm_max_page_table_levels = 4,
0155 .hostvm_cached_page_table_levels = 0,
0156 .num_dsc = 5,
0157 .rob_buffer_size_kbytes = 168,
0158 .det_buffer_size_kbytes = 164,
0159 .dpte_buffer_size_in_pte_reqs_luma = 84,
0160 .dpte_buffer_size_in_pte_reqs_chroma = 42,
0161 .dpp_output_buffer_pixels = 2560,
0162 .opp_output_buffer_lines = 1,
0163 .pixel_chunk_size_kbytes = 8,
0164 .pte_enable = 1,
0165 .max_page_table_levels = 4,
0166 .pte_chunk_size_kbytes = 2,
0167 .meta_chunk_size_kbytes = 2,
0168 .writeback_chunk_size_kbytes = 2,
0169 .line_buffer_size_bits = 789504,
0170 .is_line_buffer_bpp_fixed = 0,
0171 .line_buffer_fixed_bpp = 0,
0172 .dcc_supported = true,
0173 .max_line_buffer_lines = 12,
0174 .writeback_luma_buffer_size_kbytes = 12,
0175 .writeback_chroma_buffer_size_kbytes = 8,
0176 .writeback_chroma_line_buffer_width_pixels = 4,
0177 .writeback_max_hscl_ratio = 1,
0178 .writeback_max_vscl_ratio = 1,
0179 .writeback_min_hscl_ratio = 1,
0180 .writeback_min_vscl_ratio = 1,
0181 .writeback_max_hscl_taps = 12,
0182 .writeback_max_vscl_taps = 12,
0183 .writeback_line_buffer_luma_buffer_size = 0,
0184 .writeback_line_buffer_chroma_buffer_size = 14643,
0185 .cursor_buffer_size = 8,
0186 .cursor_chunk_size = 2,
0187 .max_num_otg = 5,
0188 .max_num_dpp = 5,
0189 .max_num_wb = 1,
0190 .max_dchub_pscl_bw_pix_per_clk = 4,
0191 .max_pscl_lb_bw_pix_per_clk = 2,
0192 .max_lb_vscl_bw_pix_per_clk = 4,
0193 .max_vscl_hscl_bw_pix_per_clk = 4,
0194 .max_hscl_ratio = 8,
0195 .max_vscl_ratio = 8,
0196 .hscl_mults = 4,
0197 .vscl_mults = 4,
0198 .max_hscl_taps = 8,
0199 .max_vscl_taps = 8,
0200 .dispclk_ramp_margin_percent = 1,
0201 .underscan_factor = 1.10,
0202 .min_vblank_lines = 32,
0203 .dppclk_delay_subtotal = 77,
0204 .dppclk_delay_scl_lb_only = 16,
0205 .dppclk_delay_scl = 50,
0206 .dppclk_delay_cnvc_formatter = 8,
0207 .dppclk_delay_cnvc_cursor = 6,
0208 .dispclk_delay_subtotal = 87,
0209 .dcfclk_cstate_latency = 10,
0210 .max_inter_dcn_tile_repeaters = 8,
0211 .xfc_supported = true,
0212 .xfc_fill_bw_overhead_percent = 10.0,
0213 .xfc_fill_constant_bytes = 0,
0214 .ptoi_supported = 0,
0215 .number_of_cursors = 1,
0216 };
0217
0218 struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
0219
0220 .clock_limits = {
0221 {
0222 .state = 0,
0223 .dcfclk_mhz = 560.0,
0224 .fabricclk_mhz = 560.0,
0225 .dispclk_mhz = 513.0,
0226 .dppclk_mhz = 513.0,
0227 .phyclk_mhz = 540.0,
0228 .socclk_mhz = 560.0,
0229 .dscclk_mhz = 171.0,
0230 .dram_speed_mts = 8960.0,
0231 },
0232 {
0233 .state = 1,
0234 .dcfclk_mhz = 694.0,
0235 .fabricclk_mhz = 694.0,
0236 .dispclk_mhz = 642.0,
0237 .dppclk_mhz = 642.0,
0238 .phyclk_mhz = 600.0,
0239 .socclk_mhz = 694.0,
0240 .dscclk_mhz = 214.0,
0241 .dram_speed_mts = 11104.0,
0242 },
0243 {
0244 .state = 2,
0245 .dcfclk_mhz = 875.0,
0246 .fabricclk_mhz = 875.0,
0247 .dispclk_mhz = 734.0,
0248 .dppclk_mhz = 734.0,
0249 .phyclk_mhz = 810.0,
0250 .socclk_mhz = 875.0,
0251 .dscclk_mhz = 245.0,
0252 .dram_speed_mts = 14000.0,
0253 },
0254 {
0255 .state = 3,
0256 .dcfclk_mhz = 1000.0,
0257 .fabricclk_mhz = 1000.0,
0258 .dispclk_mhz = 1100.0,
0259 .dppclk_mhz = 1100.0,
0260 .phyclk_mhz = 810.0,
0261 .socclk_mhz = 1000.0,
0262 .dscclk_mhz = 367.0,
0263 .dram_speed_mts = 16000.0,
0264 },
0265 {
0266 .state = 4,
0267 .dcfclk_mhz = 1200.0,
0268 .fabricclk_mhz = 1200.0,
0269 .dispclk_mhz = 1284.0,
0270 .dppclk_mhz = 1284.0,
0271 .phyclk_mhz = 810.0,
0272 .socclk_mhz = 1200.0,
0273 .dscclk_mhz = 428.0,
0274 .dram_speed_mts = 16000.0,
0275 },
0276
0277 {
0278 .state = 5,
0279 .dcfclk_mhz = 1200.0,
0280 .fabricclk_mhz = 1200.0,
0281 .dispclk_mhz = 1284.0,
0282 .dppclk_mhz = 1284.0,
0283 .phyclk_mhz = 810.0,
0284 .socclk_mhz = 1200.0,
0285 .dscclk_mhz = 428.0,
0286 .dram_speed_mts = 16000.0,
0287 },
0288 },
0289 .num_states = 5,
0290 .sr_exit_time_us = 8.6,
0291 .sr_enter_plus_exit_time_us = 10.9,
0292 .urgent_latency_us = 4.0,
0293 .urgent_latency_pixel_data_only_us = 4.0,
0294 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
0295 .urgent_latency_vm_data_only_us = 4.0,
0296 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
0297 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
0298 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
0299 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
0300 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
0301 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
0302 .max_avg_sdp_bw_use_normal_percent = 40.0,
0303 .max_avg_dram_bw_use_normal_percent = 40.0,
0304 .writeback_latency_us = 12.0,
0305 .ideal_dram_bw_after_urgent_percent = 40.0,
0306 .max_request_size_bytes = 256,
0307 .dram_channel_width_bytes = 2,
0308 .fabric_datapath_to_dcn_data_return_bytes = 64,
0309 .dcn_downspread_percent = 0.5,
0310 .downspread_percent = 0.38,
0311 .dram_page_open_time_ns = 50.0,
0312 .dram_rw_turnaround_time_ns = 17.5,
0313 .dram_return_buffer_per_channel_bytes = 8192,
0314 .round_trip_ping_latency_dcfclk_cycles = 131,
0315 .urgent_out_of_order_return_per_channel_bytes = 256,
0316 .channel_interleave_bytes = 256,
0317 .num_banks = 8,
0318 .num_chans = 16,
0319 .vmm_page_size_bytes = 4096,
0320 .dram_clock_change_latency_us = 404.0,
0321 .dummy_pstate_latency_us = 5.0,
0322 .writeback_dram_clock_change_latency_us = 23.0,
0323 .return_bus_width_bytes = 64,
0324 .dispclk_dppclk_vco_speed_mhz = 3850,
0325 .xfc_bus_transport_time_us = 20,
0326 .xfc_xbuf_latency_tolerance_us = 4,
0327 .use_urgent_burst_bw = 0
0328 };
0329
0330 struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = {
0331 .clock_limits = {
0332 {
0333 .state = 0,
0334 .dcfclk_mhz = 560.0,
0335 .fabricclk_mhz = 560.0,
0336 .dispclk_mhz = 513.0,
0337 .dppclk_mhz = 513.0,
0338 .phyclk_mhz = 540.0,
0339 .socclk_mhz = 560.0,
0340 .dscclk_mhz = 171.0,
0341 .dram_speed_mts = 8960.0,
0342 },
0343 {
0344 .state = 1,
0345 .dcfclk_mhz = 694.0,
0346 .fabricclk_mhz = 694.0,
0347 .dispclk_mhz = 642.0,
0348 .dppclk_mhz = 642.0,
0349 .phyclk_mhz = 600.0,
0350 .socclk_mhz = 694.0,
0351 .dscclk_mhz = 214.0,
0352 .dram_speed_mts = 11104.0,
0353 },
0354 {
0355 .state = 2,
0356 .dcfclk_mhz = 875.0,
0357 .fabricclk_mhz = 875.0,
0358 .dispclk_mhz = 734.0,
0359 .dppclk_mhz = 734.0,
0360 .phyclk_mhz = 810.0,
0361 .socclk_mhz = 875.0,
0362 .dscclk_mhz = 245.0,
0363 .dram_speed_mts = 14000.0,
0364 },
0365 {
0366 .state = 3,
0367 .dcfclk_mhz = 1000.0,
0368 .fabricclk_mhz = 1000.0,
0369 .dispclk_mhz = 1100.0,
0370 .dppclk_mhz = 1100.0,
0371 .phyclk_mhz = 810.0,
0372 .socclk_mhz = 1000.0,
0373 .dscclk_mhz = 367.0,
0374 .dram_speed_mts = 16000.0,
0375 },
0376 {
0377 .state = 4,
0378 .dcfclk_mhz = 1200.0,
0379 .fabricclk_mhz = 1200.0,
0380 .dispclk_mhz = 1284.0,
0381 .dppclk_mhz = 1284.0,
0382 .phyclk_mhz = 810.0,
0383 .socclk_mhz = 1200.0,
0384 .dscclk_mhz = 428.0,
0385 .dram_speed_mts = 16000.0,
0386 },
0387
0388 {
0389 .state = 5,
0390 .dcfclk_mhz = 1200.0,
0391 .fabricclk_mhz = 1200.0,
0392 .dispclk_mhz = 1284.0,
0393 .dppclk_mhz = 1284.0,
0394 .phyclk_mhz = 810.0,
0395 .socclk_mhz = 1200.0,
0396 .dscclk_mhz = 428.0,
0397 .dram_speed_mts = 16000.0,
0398 },
0399 },
0400 .num_states = 5,
0401 .sr_exit_time_us = 11.6,
0402 .sr_enter_plus_exit_time_us = 13.9,
0403 .urgent_latency_us = 4.0,
0404 .urgent_latency_pixel_data_only_us = 4.0,
0405 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
0406 .urgent_latency_vm_data_only_us = 4.0,
0407 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
0408 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
0409 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
0410 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
0411 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
0412 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
0413 .max_avg_sdp_bw_use_normal_percent = 40.0,
0414 .max_avg_dram_bw_use_normal_percent = 40.0,
0415 .writeback_latency_us = 12.0,
0416 .ideal_dram_bw_after_urgent_percent = 40.0,
0417 .max_request_size_bytes = 256,
0418 .dram_channel_width_bytes = 2,
0419 .fabric_datapath_to_dcn_data_return_bytes = 64,
0420 .dcn_downspread_percent = 0.5,
0421 .downspread_percent = 0.38,
0422 .dram_page_open_time_ns = 50.0,
0423 .dram_rw_turnaround_time_ns = 17.5,
0424 .dram_return_buffer_per_channel_bytes = 8192,
0425 .round_trip_ping_latency_dcfclk_cycles = 131,
0426 .urgent_out_of_order_return_per_channel_bytes = 256,
0427 .channel_interleave_bytes = 256,
0428 .num_banks = 8,
0429 .num_chans = 8,
0430 .vmm_page_size_bytes = 4096,
0431 .dram_clock_change_latency_us = 404.0,
0432 .dummy_pstate_latency_us = 5.0,
0433 .writeback_dram_clock_change_latency_us = 23.0,
0434 .return_bus_width_bytes = 64,
0435 .dispclk_dppclk_vco_speed_mhz = 3850,
0436 .xfc_bus_transport_time_us = 20,
0437 .xfc_xbuf_latency_tolerance_us = 4,
0438 .use_urgent_burst_bw = 0
0439 };
0440
0441 struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 };
0442
0443 struct _vcs_dpi_ip_params_st dcn2_1_ip = {
0444 .odm_capable = 1,
0445 .gpuvm_enable = 1,
0446 .hostvm_enable = 1,
0447 .gpuvm_max_page_table_levels = 1,
0448 .hostvm_max_page_table_levels = 4,
0449 .hostvm_cached_page_table_levels = 2,
0450 .num_dsc = 3,
0451 .rob_buffer_size_kbytes = 168,
0452 .det_buffer_size_kbytes = 164,
0453 .dpte_buffer_size_in_pte_reqs_luma = 44,
0454 .dpte_buffer_size_in_pte_reqs_chroma = 42,
0455 .dpp_output_buffer_pixels = 2560,
0456 .opp_output_buffer_lines = 1,
0457 .pixel_chunk_size_kbytes = 8,
0458 .pte_enable = 1,
0459 .max_page_table_levels = 4,
0460 .pte_chunk_size_kbytes = 2,
0461 .meta_chunk_size_kbytes = 2,
0462 .min_meta_chunk_size_bytes = 256,
0463 .writeback_chunk_size_kbytes = 2,
0464 .line_buffer_size_bits = 789504,
0465 .is_line_buffer_bpp_fixed = 0,
0466 .line_buffer_fixed_bpp = 0,
0467 .dcc_supported = true,
0468 .max_line_buffer_lines = 12,
0469 .writeback_luma_buffer_size_kbytes = 12,
0470 .writeback_chroma_buffer_size_kbytes = 8,
0471 .writeback_chroma_line_buffer_width_pixels = 4,
0472 .writeback_max_hscl_ratio = 1,
0473 .writeback_max_vscl_ratio = 1,
0474 .writeback_min_hscl_ratio = 1,
0475 .writeback_min_vscl_ratio = 1,
0476 .writeback_max_hscl_taps = 12,
0477 .writeback_max_vscl_taps = 12,
0478 .writeback_line_buffer_luma_buffer_size = 0,
0479 .writeback_line_buffer_chroma_buffer_size = 14643,
0480 .cursor_buffer_size = 8,
0481 .cursor_chunk_size = 2,
0482 .max_num_otg = 4,
0483 .max_num_dpp = 4,
0484 .max_num_wb = 1,
0485 .max_dchub_pscl_bw_pix_per_clk = 4,
0486 .max_pscl_lb_bw_pix_per_clk = 2,
0487 .max_lb_vscl_bw_pix_per_clk = 4,
0488 .max_vscl_hscl_bw_pix_per_clk = 4,
0489 .max_hscl_ratio = 4,
0490 .max_vscl_ratio = 4,
0491 .hscl_mults = 4,
0492 .vscl_mults = 4,
0493 .max_hscl_taps = 8,
0494 .max_vscl_taps = 8,
0495 .dispclk_ramp_margin_percent = 1,
0496 .underscan_factor = 1.10,
0497 .min_vblank_lines = 32,
0498 .dppclk_delay_subtotal = 77,
0499 .dppclk_delay_scl_lb_only = 16,
0500 .dppclk_delay_scl = 50,
0501 .dppclk_delay_cnvc_formatter = 8,
0502 .dppclk_delay_cnvc_cursor = 6,
0503 .dispclk_delay_subtotal = 87,
0504 .dcfclk_cstate_latency = 10,
0505 .max_inter_dcn_tile_repeaters = 8,
0506
0507 .xfc_supported = false,
0508 .xfc_fill_bw_overhead_percent = 10.0,
0509 .xfc_fill_constant_bytes = 0,
0510 .ptoi_supported = 0,
0511 .number_of_cursors = 1,
0512 };
0513
0514 struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
0515 .clock_limits = {
0516 {
0517 .state = 0,
0518 .dcfclk_mhz = 400.0,
0519 .fabricclk_mhz = 400.0,
0520 .dispclk_mhz = 600.0,
0521 .dppclk_mhz = 400.00,
0522 .phyclk_mhz = 600.0,
0523 .socclk_mhz = 278.0,
0524 .dscclk_mhz = 205.67,
0525 .dram_speed_mts = 1600.0,
0526 },
0527 {
0528 .state = 1,
0529 .dcfclk_mhz = 464.52,
0530 .fabricclk_mhz = 800.0,
0531 .dispclk_mhz = 654.55,
0532 .dppclk_mhz = 626.09,
0533 .phyclk_mhz = 600.0,
0534 .socclk_mhz = 278.0,
0535 .dscclk_mhz = 205.67,
0536 .dram_speed_mts = 1600.0,
0537 },
0538 {
0539 .state = 2,
0540 .dcfclk_mhz = 514.29,
0541 .fabricclk_mhz = 933.0,
0542 .dispclk_mhz = 757.89,
0543 .dppclk_mhz = 685.71,
0544 .phyclk_mhz = 600.0,
0545 .socclk_mhz = 278.0,
0546 .dscclk_mhz = 287.67,
0547 .dram_speed_mts = 1866.0,
0548 },
0549 {
0550 .state = 3,
0551 .dcfclk_mhz = 576.00,
0552 .fabricclk_mhz = 1067.0,
0553 .dispclk_mhz = 847.06,
0554 .dppclk_mhz = 757.89,
0555 .phyclk_mhz = 600.0,
0556 .socclk_mhz = 715.0,
0557 .dscclk_mhz = 318.334,
0558 .dram_speed_mts = 2134.0,
0559 },
0560 {
0561 .state = 4,
0562 .dcfclk_mhz = 626.09,
0563 .fabricclk_mhz = 1200.0,
0564 .dispclk_mhz = 900.00,
0565 .dppclk_mhz = 847.06,
0566 .phyclk_mhz = 810.0,
0567 .socclk_mhz = 953.0,
0568 .dscclk_mhz = 489.0,
0569 .dram_speed_mts = 2400.0,
0570 },
0571 {
0572 .state = 5,
0573 .dcfclk_mhz = 685.71,
0574 .fabricclk_mhz = 1333.0,
0575 .dispclk_mhz = 1028.57,
0576 .dppclk_mhz = 960.00,
0577 .phyclk_mhz = 810.0,
0578 .socclk_mhz = 278.0,
0579 .dscclk_mhz = 287.67,
0580 .dram_speed_mts = 2666.0,
0581 },
0582 {
0583 .state = 6,
0584 .dcfclk_mhz = 757.89,
0585 .fabricclk_mhz = 1467.0,
0586 .dispclk_mhz = 1107.69,
0587 .dppclk_mhz = 1028.57,
0588 .phyclk_mhz = 810.0,
0589 .socclk_mhz = 715.0,
0590 .dscclk_mhz = 318.334,
0591 .dram_speed_mts = 3200.0,
0592 },
0593 {
0594 .state = 7,
0595 .dcfclk_mhz = 847.06,
0596 .fabricclk_mhz = 1600.0,
0597 .dispclk_mhz = 1395.0,
0598 .dppclk_mhz = 1285.00,
0599 .phyclk_mhz = 1325.0,
0600 .socclk_mhz = 953.0,
0601 .dscclk_mhz = 489.0,
0602 .dram_speed_mts = 4266.0,
0603 },
0604
0605 {
0606 .state = 8,
0607 .dcfclk_mhz = 847.06,
0608 .fabricclk_mhz = 1600.0,
0609 .dispclk_mhz = 1395.0,
0610 .dppclk_mhz = 1285.0,
0611 .phyclk_mhz = 1325.0,
0612 .socclk_mhz = 953.0,
0613 .dscclk_mhz = 489.0,
0614 .dram_speed_mts = 4266.0,
0615 },
0616
0617 },
0618
0619 .sr_exit_time_us = 12.5,
0620 .sr_enter_plus_exit_time_us = 17.0,
0621 .urgent_latency_us = 4.0,
0622 .urgent_latency_pixel_data_only_us = 4.0,
0623 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
0624 .urgent_latency_vm_data_only_us = 4.0,
0625 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
0626 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
0627 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
0628 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
0629 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
0630 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
0631 .max_avg_sdp_bw_use_normal_percent = 60.0,
0632 .max_avg_dram_bw_use_normal_percent = 100.0,
0633 .writeback_latency_us = 12.0,
0634 .max_request_size_bytes = 256,
0635 .dram_channel_width_bytes = 4,
0636 .fabric_datapath_to_dcn_data_return_bytes = 32,
0637 .dcn_downspread_percent = 0.5,
0638 .downspread_percent = 0.38,
0639 .dram_page_open_time_ns = 50.0,
0640 .dram_rw_turnaround_time_ns = 17.5,
0641 .dram_return_buffer_per_channel_bytes = 8192,
0642 .round_trip_ping_latency_dcfclk_cycles = 128,
0643 .urgent_out_of_order_return_per_channel_bytes = 4096,
0644 .channel_interleave_bytes = 256,
0645 .num_banks = 8,
0646 .num_chans = 4,
0647 .vmm_page_size_bytes = 4096,
0648 .dram_clock_change_latency_us = 23.84,
0649 .return_bus_width_bytes = 64,
0650 .dispclk_dppclk_vco_speed_mhz = 3600,
0651 .xfc_bus_transport_time_us = 4,
0652 .xfc_xbuf_latency_tolerance_us = 4,
0653 .use_urgent_burst_bw = 1,
0654 .num_states = 8
0655 };
0656
0657 struct wm_table ddr4_wm_table_gs = {
0658 .entries = {
0659 {
0660 .wm_inst = WM_A,
0661 .wm_type = WM_TYPE_PSTATE_CHG,
0662 .pstate_latency_us = 11.72,
0663 .sr_exit_time_us = 7.09,
0664 .sr_enter_plus_exit_time_us = 8.14,
0665 .valid = true,
0666 },
0667 {
0668 .wm_inst = WM_B,
0669 .wm_type = WM_TYPE_PSTATE_CHG,
0670 .pstate_latency_us = 11.72,
0671 .sr_exit_time_us = 10.12,
0672 .sr_enter_plus_exit_time_us = 11.48,
0673 .valid = true,
0674 },
0675 {
0676 .wm_inst = WM_C,
0677 .wm_type = WM_TYPE_PSTATE_CHG,
0678 .pstate_latency_us = 11.72,
0679 .sr_exit_time_us = 10.12,
0680 .sr_enter_plus_exit_time_us = 11.48,
0681 .valid = true,
0682 },
0683 {
0684 .wm_inst = WM_D,
0685 .wm_type = WM_TYPE_PSTATE_CHG,
0686 .pstate_latency_us = 11.72,
0687 .sr_exit_time_us = 10.12,
0688 .sr_enter_plus_exit_time_us = 11.48,
0689 .valid = true,
0690 },
0691 }
0692 };
0693
0694 struct wm_table lpddr4_wm_table_gs = {
0695 .entries = {
0696 {
0697 .wm_inst = WM_A,
0698 .wm_type = WM_TYPE_PSTATE_CHG,
0699 .pstate_latency_us = 11.65333,
0700 .sr_exit_time_us = 5.32,
0701 .sr_enter_plus_exit_time_us = 6.38,
0702 .valid = true,
0703 },
0704 {
0705 .wm_inst = WM_B,
0706 .wm_type = WM_TYPE_PSTATE_CHG,
0707 .pstate_latency_us = 11.65333,
0708 .sr_exit_time_us = 9.82,
0709 .sr_enter_plus_exit_time_us = 11.196,
0710 .valid = true,
0711 },
0712 {
0713 .wm_inst = WM_C,
0714 .wm_type = WM_TYPE_PSTATE_CHG,
0715 .pstate_latency_us = 11.65333,
0716 .sr_exit_time_us = 9.89,
0717 .sr_enter_plus_exit_time_us = 11.24,
0718 .valid = true,
0719 },
0720 {
0721 .wm_inst = WM_D,
0722 .wm_type = WM_TYPE_PSTATE_CHG,
0723 .pstate_latency_us = 11.65333,
0724 .sr_exit_time_us = 9.748,
0725 .sr_enter_plus_exit_time_us = 11.102,
0726 .valid = true,
0727 },
0728 }
0729 };
0730
0731 struct wm_table lpddr4_wm_table_with_disabled_ppt = {
0732 .entries = {
0733 {
0734 .wm_inst = WM_A,
0735 .wm_type = WM_TYPE_PSTATE_CHG,
0736 .pstate_latency_us = 11.65333,
0737 .sr_exit_time_us = 8.32,
0738 .sr_enter_plus_exit_time_us = 9.38,
0739 .valid = true,
0740 },
0741 {
0742 .wm_inst = WM_B,
0743 .wm_type = WM_TYPE_PSTATE_CHG,
0744 .pstate_latency_us = 11.65333,
0745 .sr_exit_time_us = 9.82,
0746 .sr_enter_plus_exit_time_us = 11.196,
0747 .valid = true,
0748 },
0749 {
0750 .wm_inst = WM_C,
0751 .wm_type = WM_TYPE_PSTATE_CHG,
0752 .pstate_latency_us = 11.65333,
0753 .sr_exit_time_us = 9.89,
0754 .sr_enter_plus_exit_time_us = 11.24,
0755 .valid = true,
0756 },
0757 {
0758 .wm_inst = WM_D,
0759 .wm_type = WM_TYPE_PSTATE_CHG,
0760 .pstate_latency_us = 11.65333,
0761 .sr_exit_time_us = 9.748,
0762 .sr_enter_plus_exit_time_us = 11.102,
0763 .valid = true,
0764 },
0765 }
0766 };
0767
0768 struct wm_table ddr4_wm_table_rn = {
0769 .entries = {
0770 {
0771 .wm_inst = WM_A,
0772 .wm_type = WM_TYPE_PSTATE_CHG,
0773 .pstate_latency_us = 11.72,
0774 .sr_exit_time_us = 11.90,
0775 .sr_enter_plus_exit_time_us = 12.80,
0776 .valid = true,
0777 },
0778 {
0779 .wm_inst = WM_B,
0780 .wm_type = WM_TYPE_PSTATE_CHG,
0781 .pstate_latency_us = 11.72,
0782 .sr_exit_time_us = 13.18,
0783 .sr_enter_plus_exit_time_us = 14.30,
0784 .valid = true,
0785 },
0786 {
0787 .wm_inst = WM_C,
0788 .wm_type = WM_TYPE_PSTATE_CHG,
0789 .pstate_latency_us = 11.72,
0790 .sr_exit_time_us = 13.18,
0791 .sr_enter_plus_exit_time_us = 14.30,
0792 .valid = true,
0793 },
0794 {
0795 .wm_inst = WM_D,
0796 .wm_type = WM_TYPE_PSTATE_CHG,
0797 .pstate_latency_us = 11.72,
0798 .sr_exit_time_us = 13.18,
0799 .sr_enter_plus_exit_time_us = 14.30,
0800 .valid = true,
0801 },
0802 }
0803 };
0804
0805 struct wm_table ddr4_1R_wm_table_rn = {
0806 .entries = {
0807 {
0808 .wm_inst = WM_A,
0809 .wm_type = WM_TYPE_PSTATE_CHG,
0810 .pstate_latency_us = 11.72,
0811 .sr_exit_time_us = 13.90,
0812 .sr_enter_plus_exit_time_us = 14.80,
0813 .valid = true,
0814 },
0815 {
0816 .wm_inst = WM_B,
0817 .wm_type = WM_TYPE_PSTATE_CHG,
0818 .pstate_latency_us = 11.72,
0819 .sr_exit_time_us = 13.90,
0820 .sr_enter_plus_exit_time_us = 14.80,
0821 .valid = true,
0822 },
0823 {
0824 .wm_inst = WM_C,
0825 .wm_type = WM_TYPE_PSTATE_CHG,
0826 .pstate_latency_us = 11.72,
0827 .sr_exit_time_us = 13.90,
0828 .sr_enter_plus_exit_time_us = 14.80,
0829 .valid = true,
0830 },
0831 {
0832 .wm_inst = WM_D,
0833 .wm_type = WM_TYPE_PSTATE_CHG,
0834 .pstate_latency_us = 11.72,
0835 .sr_exit_time_us = 13.90,
0836 .sr_enter_plus_exit_time_us = 14.80,
0837 .valid = true,
0838 },
0839 }
0840 };
0841
0842 struct wm_table lpddr4_wm_table_rn = {
0843 .entries = {
0844 {
0845 .wm_inst = WM_A,
0846 .wm_type = WM_TYPE_PSTATE_CHG,
0847 .pstate_latency_us = 11.65333,
0848 .sr_exit_time_us = 7.32,
0849 .sr_enter_plus_exit_time_us = 8.38,
0850 .valid = true,
0851 },
0852 {
0853 .wm_inst = WM_B,
0854 .wm_type = WM_TYPE_PSTATE_CHG,
0855 .pstate_latency_us = 11.65333,
0856 .sr_exit_time_us = 9.82,
0857 .sr_enter_plus_exit_time_us = 11.196,
0858 .valid = true,
0859 },
0860 {
0861 .wm_inst = WM_C,
0862 .wm_type = WM_TYPE_PSTATE_CHG,
0863 .pstate_latency_us = 11.65333,
0864 .sr_exit_time_us = 9.89,
0865 .sr_enter_plus_exit_time_us = 11.24,
0866 .valid = true,
0867 },
0868 {
0869 .wm_inst = WM_D,
0870 .wm_type = WM_TYPE_PSTATE_CHG,
0871 .pstate_latency_us = 11.65333,
0872 .sr_exit_time_us = 9.748,
0873 .sr_enter_plus_exit_time_us = 11.102,
0874 .valid = true,
0875 },
0876 }
0877 };
0878
0879 void dcn20_populate_dml_writeback_from_context(struct dc *dc,
0880 struct resource_context *res_ctx,
0881 display_e2e_pipe_params_st *pipes)
0882 {
0883 int pipe_cnt, i;
0884
0885 dc_assert_fp_enabled();
0886
0887 for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
0888 struct dc_writeback_info *wb_info = &res_ctx->pipe_ctx[i].stream->writeback_info[0];
0889
0890 if (!res_ctx->pipe_ctx[i].stream)
0891 continue;
0892
0893
0894 pipes[pipe_cnt].dout.wb_enable = (wb_info->wb_enabled == true) ? 1 : 0;
0895 pipes[pipe_cnt].dout.num_active_wb++;
0896 pipes[pipe_cnt].dout.wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_height;
0897 pipes[pipe_cnt].dout.wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_width;
0898 pipes[pipe_cnt].dout.wb.wb_dst_width = wb_info->dwb_params.dest_width;
0899 pipes[pipe_cnt].dout.wb.wb_dst_height = wb_info->dwb_params.dest_height;
0900 pipes[pipe_cnt].dout.wb.wb_htaps_luma = 1;
0901 pipes[pipe_cnt].dout.wb.wb_vtaps_luma = 1;
0902 pipes[pipe_cnt].dout.wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;
0903 pipes[pipe_cnt].dout.wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;
0904 pipes[pipe_cnt].dout.wb.wb_hratio = 1.0;
0905 pipes[pipe_cnt].dout.wb.wb_vratio = 1.0;
0906 if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {
0907 if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)
0908 pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_8;
0909 else
0910 pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_10;
0911 } else {
0912 pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_444_32;
0913 }
0914
0915 pipe_cnt++;
0916 }
0917 }
0918
0919 void dcn20_fpu_set_wb_arb_params(struct mcif_arb_params *wb_arb_params,
0920 struct dc_state *context,
0921 display_e2e_pipe_params_st *pipes,
0922 int pipe_cnt, int i)
0923 {
0924 int k;
0925
0926 dc_assert_fp_enabled();
0927
0928 for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) {
0929 wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
0930 wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
0931 }
0932 wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000);
0933 }
0934
0935 static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
0936 {
0937 int i;
0938 for (i = 0; i < dc->res_pool->pipe_count; i++) {
0939 if (!context->res_ctx.pipe_ctx[i].stream)
0940 continue;
0941 if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
0942 return true;
0943 }
0944 return false;
0945 }
0946
0947 static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struct dc_state *context)
0948 {
0949 int plane_count;
0950 int i;
0951 unsigned int optimized_min_dst_y_next_start_us;
0952
0953 plane_count = 0;
0954 optimized_min_dst_y_next_start_us = 0;
0955 for (i = 0; i < dc->res_pool->pipe_count; i++) {
0956 if (context->res_ctx.pipe_ctx[i].plane_state)
0957 plane_count++;
0958 }
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969 if (plane_count == 0)
0970 return DCN_ZSTATE_SUPPORT_ALLOW;
0971 else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) {
0972 struct dc_link *link = context->streams[0]->sink->link;
0973 struct dc_stream_status *stream_status = &context->stream_status[0];
0974
0975 if (dc_extended_blank_supported(dc)) {
0976 for (i = 0; i < dc->res_pool->pipe_count; i++) {
0977 if (context->res_ctx.pipe_ctx[i].stream == context->streams[0]
0978 && context->res_ctx.pipe_ctx[i].stream->adjust.v_total_min == context->res_ctx.pipe_ctx[i].stream->adjust.v_total_max
0979 && context->res_ctx.pipe_ctx[i].stream->adjust.v_total_min > context->res_ctx.pipe_ctx[i].stream->timing.v_total) {
0980 optimized_min_dst_y_next_start_us =
0981 context->res_ctx.pipe_ctx[i].dlg_regs.optimized_min_dst_y_next_start_us;
0982 break;
0983 }
0984 }
0985 }
0986
0987 if (link->link_index != 0 || stream_status->plane_count > 1)
0988 return DCN_ZSTATE_SUPPORT_DISALLOW;
0989
0990 if (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || optimized_min_dst_y_next_start_us > 5000)
0991 return DCN_ZSTATE_SUPPORT_ALLOW;
0992 else if (link->psr_settings.psr_version == DC_PSR_VERSION_1 && !dc->debug.disable_psr)
0993 return DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY;
0994 else
0995 return DCN_ZSTATE_SUPPORT_DISALLOW;
0996 } else
0997 return DCN_ZSTATE_SUPPORT_DISALLOW;
0998 }
0999
1000 void dcn20_calculate_dlg_params(
1001 struct dc *dc, struct dc_state *context,
1002 display_e2e_pipe_params_st *pipes,
1003 int pipe_cnt,
1004 int vlevel)
1005 {
1006 int i, pipe_idx;
1007
1008 dc_assert_fp_enabled();
1009
1010
1011 dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);
1012
1013 context->bw_ctx.bw.dcn.clk.dispclk_khz = context->bw_ctx.dml.vba.DISPCLK * 1000;
1014 context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000;
1015 context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000;
1016 context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16;
1017
1018 if (dc->debug.min_dram_clk_khz > context->bw_ctx.bw.dcn.clk.dramclk_khz)
1019 context->bw_ctx.bw.dcn.clk.dramclk_khz = dc->debug.min_dram_clk_khz;
1020
1021 context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000;
1022 context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000;
1023 context->bw_ctx.bw.dcn.clk.p_state_change_support =
1024 context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]
1025 != dm_dram_clock_change_unsupported;
1026
1027
1028
1029
1030 context->bw_ctx.bw.dcn.clk.p_state_change_support |= context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching;
1031
1032 context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
1033
1034 context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context);
1035
1036 if (context->bw_ctx.bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz)
1037 context->bw_ctx.bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz;
1038
1039 for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
1040 if (!context->res_ctx.pipe_ctx[i].stream)
1041 continue;
1042 pipes[pipe_idx].pipe.dest.vstartup_start = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
1043 pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
1044 pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
1045 pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
1046 if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
1047
1048 context->res_ctx.pipe_ctx[i].det_buffer_size_kb = 0;
1049 context->res_ctx.pipe_ctx[i].unbounded_req = false;
1050 } else {
1051 context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes;
1052 context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode;
1053 }
1054 if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
1055 context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
1056 context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =
1057 pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
1058 context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest;
1059 pipe_idx++;
1060 }
1061
1062 context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz;
1063 context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz;
1064 context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz * 1000;
1065 context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz * 1000;
1066
1067 context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes
1068 - context->bw_ctx.dml.ip.det_buffer_size_kbytes * pipe_idx;
1069
1070 for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
1071 bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2;
1072
1073 if (!context->res_ctx.pipe_ctx[i].stream)
1074 continue;
1075
1076 if (dc->ctx->dce_version == DCN_VERSION_2_01)
1077 cstate_en = false;
1078
1079 context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml,
1080 &context->res_ctx.pipe_ctx[i].dlg_regs,
1081 &context->res_ctx.pipe_ctx[i].ttu_regs,
1082 pipes,
1083 pipe_cnt,
1084 pipe_idx,
1085 cstate_en,
1086 context->bw_ctx.bw.dcn.clk.p_state_change_support,
1087 false, false, true);
1088
1089 context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,
1090 &context->res_ctx.pipe_ctx[i].rq_regs,
1091 &pipes[pipe_idx].pipe);
1092 pipe_idx++;
1093 }
1094 context->bw_ctx.bw.dcn.clk.zstate_support = decide_zstate_support(dc, context);
1095 }
1096
1097 static void swizzle_to_dml_params(
1098 enum swizzle_mode_values swizzle,
1099 unsigned int *sw_mode)
1100 {
1101 switch (swizzle) {
1102 case DC_SW_LINEAR:
1103 *sw_mode = dm_sw_linear;
1104 break;
1105 case DC_SW_4KB_S:
1106 *sw_mode = dm_sw_4kb_s;
1107 break;
1108 case DC_SW_4KB_S_X:
1109 *sw_mode = dm_sw_4kb_s_x;
1110 break;
1111 case DC_SW_4KB_D:
1112 *sw_mode = dm_sw_4kb_d;
1113 break;
1114 case DC_SW_4KB_D_X:
1115 *sw_mode = dm_sw_4kb_d_x;
1116 break;
1117 case DC_SW_64KB_S:
1118 *sw_mode = dm_sw_64kb_s;
1119 break;
1120 case DC_SW_64KB_S_X:
1121 *sw_mode = dm_sw_64kb_s_x;
1122 break;
1123 case DC_SW_64KB_S_T:
1124 *sw_mode = dm_sw_64kb_s_t;
1125 break;
1126 case DC_SW_64KB_D:
1127 *sw_mode = dm_sw_64kb_d;
1128 break;
1129 case DC_SW_64KB_D_X:
1130 *sw_mode = dm_sw_64kb_d_x;
1131 break;
1132 case DC_SW_64KB_D_T:
1133 *sw_mode = dm_sw_64kb_d_t;
1134 break;
1135 case DC_SW_64KB_R_X:
1136 *sw_mode = dm_sw_64kb_r_x;
1137 break;
1138 case DC_SW_VAR_S:
1139 *sw_mode = dm_sw_var_s;
1140 break;
1141 case DC_SW_VAR_S_X:
1142 *sw_mode = dm_sw_var_s_x;
1143 break;
1144 case DC_SW_VAR_D:
1145 *sw_mode = dm_sw_var_d;
1146 break;
1147 case DC_SW_VAR_D_X:
1148 *sw_mode = dm_sw_var_d_x;
1149 break;
1150 case DC_SW_VAR_R_X:
1151 *sw_mode = dm_sw_var_r_x;
1152 break;
1153 default:
1154 ASSERT(0);
1155 break;
1156 }
1157 }
1158
1159 int dcn20_populate_dml_pipes_from_context(
1160 struct dc *dc,
1161 struct dc_state *context,
1162 display_e2e_pipe_params_st *pipes,
1163 bool fast_validate)
1164 {
1165 int pipe_cnt, i;
1166 bool synchronized_vblank = true;
1167 struct resource_context *res_ctx = &context->res_ctx;
1168
1169 dc_assert_fp_enabled();
1170
1171 for (i = 0, pipe_cnt = -1; i < dc->res_pool->pipe_count; i++) {
1172 if (!res_ctx->pipe_ctx[i].stream)
1173 continue;
1174
1175 if (pipe_cnt < 0) {
1176 pipe_cnt = i;
1177 continue;
1178 }
1179
1180 if (res_ctx->pipe_ctx[pipe_cnt].stream == res_ctx->pipe_ctx[i].stream)
1181 continue;
1182
1183 if (dc->debug.disable_timing_sync ||
1184 (!resource_are_streams_timing_synchronizable(
1185 res_ctx->pipe_ctx[pipe_cnt].stream,
1186 res_ctx->pipe_ctx[i].stream) &&
1187 !resource_are_vblanks_synchronizable(
1188 res_ctx->pipe_ctx[pipe_cnt].stream,
1189 res_ctx->pipe_ctx[i].stream))) {
1190 synchronized_vblank = false;
1191 break;
1192 }
1193 }
1194
1195 for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1196 struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing;
1197 unsigned int v_total;
1198 unsigned int front_porch;
1199 int output_bpc;
1200 struct audio_check aud_check = {0};
1201
1202 if (!res_ctx->pipe_ctx[i].stream)
1203 continue;
1204
1205 v_total = timing->v_total;
1206 front_porch = timing->v_front_porch;
1207
1208
1209
1210
1211
1212
1213 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
1214
1215 pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC;
1216
1217 pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h;
1218 if (res_ctx->pipe_ctx[i].stream->use_dynamic_meta) {
1219 pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = true;
1220
1221 pipes[pipe_cnt].pipe.src.dynamic_metadata_lines_before_active =
1222 (v_total - timing->v_addressable
1223 - timing->v_border_top - timing->v_border_bottom) / 2;
1224
1225 pipes[pipe_cnt].pipe.src.dynamic_metadata_xmit_bytes =
1226 dc_is_dp_signal(res_ctx->pipe_ctx[i].stream->signal) ? 36 : 32;
1227 }
1228 pipes[pipe_cnt].pipe.src.dcc = false;
1229 pipes[pipe_cnt].pipe.src.dcc_rate = 1;
1230 pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;
1231 pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch;
1232 pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start
1233 - timing->h_addressable
1234 - timing->h_border_left
1235 - timing->h_border_right;
1236 pipes[pipe_cnt].pipe.dest.vblank_start = v_total - front_porch;
1237 pipes[pipe_cnt].pipe.dest.vblank_end = pipes[pipe_cnt].pipe.dest.vblank_start
1238 - timing->v_addressable
1239 - timing->v_border_top
1240 - timing->v_border_bottom;
1241 pipes[pipe_cnt].pipe.dest.htotal = timing->h_total;
1242 pipes[pipe_cnt].pipe.dest.vtotal = v_total;
1243 pipes[pipe_cnt].pipe.dest.hactive =
1244 timing->h_addressable + timing->h_border_left + timing->h_border_right;
1245 pipes[pipe_cnt].pipe.dest.vactive =
1246 timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
1247 pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE;
1248 pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0;
1249 if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
1250 pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2;
1251 pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst;
1252 pipes[pipe_cnt].dout.dp_lanes = 4;
1253 if (res_ctx->pipe_ctx[i].stream->link)
1254 pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_na;
1255 pipes[pipe_cnt].dout.is_virtual = 0;
1256 pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;
1257 pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;
1258 switch (get_num_odm_splits(&res_ctx->pipe_ctx[i])) {
1259 case 1:
1260 pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1;
1261 break;
1262 case 3:
1263 pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1;
1264 break;
1265 default:
1266 pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled;
1267 }
1268 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
1269 if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state
1270 == res_ctx->pipe_ctx[i].plane_state) {
1271 struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].top_pipe;
1272 int split_idx = 0;
1273
1274 while (first_pipe->top_pipe && first_pipe->top_pipe->plane_state
1275 == res_ctx->pipe_ctx[i].plane_state) {
1276 first_pipe = first_pipe->top_pipe;
1277 split_idx++;
1278 }
1279
1280 if (split_idx == 0)
1281 pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
1282 else if (split_idx == 1)
1283 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
1284 else if (split_idx == 2)
1285 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].top_pipe->pipe_idx;
1286 } else if (res_ctx->pipe_ctx[i].prev_odm_pipe) {
1287 struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].prev_odm_pipe;
1288
1289 while (first_pipe->prev_odm_pipe)
1290 first_pipe = first_pipe->prev_odm_pipe;
1291 pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
1292 }
1293
1294 switch (res_ctx->pipe_ctx[i].stream->signal) {
1295 case SIGNAL_TYPE_DISPLAY_PORT_MST:
1296 case SIGNAL_TYPE_DISPLAY_PORT:
1297 pipes[pipe_cnt].dout.output_type = dm_dp;
1298 break;
1299 case SIGNAL_TYPE_EDP:
1300 pipes[pipe_cnt].dout.output_type = dm_edp;
1301 break;
1302 case SIGNAL_TYPE_HDMI_TYPE_A:
1303 case SIGNAL_TYPE_DVI_SINGLE_LINK:
1304 case SIGNAL_TYPE_DVI_DUAL_LINK:
1305 pipes[pipe_cnt].dout.output_type = dm_hdmi;
1306 break;
1307 default:
1308
1309 pipes[pipe_cnt].dout.is_virtual = 1;
1310 pipes[pipe_cnt].dout.output_type = dm_dp;
1311 pipes[pipe_cnt].dout.dp_lanes = 4;
1312 pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_hbr2;
1313 }
1314
1315 switch (res_ctx->pipe_ctx[i].stream->timing.display_color_depth) {
1316 case COLOR_DEPTH_666:
1317 output_bpc = 6;
1318 break;
1319 case COLOR_DEPTH_888:
1320 output_bpc = 8;
1321 break;
1322 case COLOR_DEPTH_101010:
1323 output_bpc = 10;
1324 break;
1325 case COLOR_DEPTH_121212:
1326 output_bpc = 12;
1327 break;
1328 case COLOR_DEPTH_141414:
1329 output_bpc = 14;
1330 break;
1331 case COLOR_DEPTH_161616:
1332 output_bpc = 16;
1333 break;
1334 case COLOR_DEPTH_999:
1335 output_bpc = 9;
1336 break;
1337 case COLOR_DEPTH_111111:
1338 output_bpc = 11;
1339 break;
1340 default:
1341 output_bpc = 8;
1342 break;
1343 }
1344
1345 switch (res_ctx->pipe_ctx[i].stream->timing.pixel_encoding) {
1346 case PIXEL_ENCODING_RGB:
1347 case PIXEL_ENCODING_YCBCR444:
1348 pipes[pipe_cnt].dout.output_format = dm_444;
1349 pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
1350 break;
1351 case PIXEL_ENCODING_YCBCR420:
1352 pipes[pipe_cnt].dout.output_format = dm_420;
1353 pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2;
1354 break;
1355 case PIXEL_ENCODING_YCBCR422:
1356 if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC &&
1357 !res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.ycbcr422_simple)
1358 pipes[pipe_cnt].dout.output_format = dm_n422;
1359 else
1360 pipes[pipe_cnt].dout.output_format = dm_s422;
1361 pipes[pipe_cnt].dout.output_bpp = output_bpc * 2;
1362 break;
1363 default:
1364 pipes[pipe_cnt].dout.output_format = dm_444;
1365 pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
1366 }
1367
1368 if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC)
1369 pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0;
1370
1371
1372 pipes[pipe_cnt].dout.dsc_input_bpc = 12;
1373
1374 get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check);
1375 pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000;
1376
1377
1378
1379
1380 if (res_ctx->pipe_ctx[i].plane_state &&
1381 (res_ctx->pipe_ctx[i].plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ||
1382 res_ctx->pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM))
1383 pipes[pipe_cnt].pipe.src.num_cursors = 0;
1384 else
1385 pipes[pipe_cnt].pipe.src.num_cursors = dc->dml.ip.number_of_cursors;
1386
1387 pipes[pipe_cnt].pipe.src.cur0_src_width = 256;
1388 pipes[pipe_cnt].pipe.src.cur0_bpp = dm_cur_32bit;
1389
1390 if (!res_ctx->pipe_ctx[i].plane_state) {
1391 pipes[pipe_cnt].pipe.src.is_hsplit = pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
1392 pipes[pipe_cnt].pipe.src.source_scan = dm_horz;
1393 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_0;
1394 pipes[pipe_cnt].pipe.src.sw_mode = dm_sw_4kb_s;
1395 pipes[pipe_cnt].pipe.src.macro_tile_size = dm_64k_tile;
1396 pipes[pipe_cnt].pipe.src.viewport_width = timing->h_addressable;
1397 if (pipes[pipe_cnt].pipe.src.viewport_width > 1920)
1398 pipes[pipe_cnt].pipe.src.viewport_width = 1920;
1399 pipes[pipe_cnt].pipe.src.viewport_height = timing->v_addressable;
1400 if (pipes[pipe_cnt].pipe.src.viewport_height > 1080)
1401 pipes[pipe_cnt].pipe.src.viewport_height = 1080;
1402 pipes[pipe_cnt].pipe.src.surface_height_y = pipes[pipe_cnt].pipe.src.viewport_height;
1403 pipes[pipe_cnt].pipe.src.surface_width_y = pipes[pipe_cnt].pipe.src.viewport_width;
1404 pipes[pipe_cnt].pipe.src.surface_height_c = pipes[pipe_cnt].pipe.src.viewport_height;
1405 pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width;
1406 pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 255) / 256) * 256;
1407 pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
1408 pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width;
1409 pipes[pipe_cnt].pipe.dest.recout_height = pipes[pipe_cnt].pipe.src.viewport_height;
1410 pipes[pipe_cnt].pipe.dest.full_recout_width = pipes[pipe_cnt].pipe.dest.recout_width;
1411 pipes[pipe_cnt].pipe.dest.full_recout_height = pipes[pipe_cnt].pipe.dest.recout_height;
1412 pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
1413 pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = 1.0;
1414 pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = 1.0;
1415 pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable = 0;
1416 pipes[pipe_cnt].pipe.scale_taps.htaps = 1;
1417 pipes[pipe_cnt].pipe.scale_taps.vtaps = 1;
1418 pipes[pipe_cnt].pipe.dest.vtotal_min = v_total;
1419 pipes[pipe_cnt].pipe.dest.vtotal_max = v_total;
1420
1421 if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) {
1422 pipes[pipe_cnt].pipe.src.viewport_width /= 2;
1423 pipes[pipe_cnt].pipe.dest.recout_width /= 2;
1424 } else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) {
1425 pipes[pipe_cnt].pipe.src.viewport_width /= 4;
1426 pipes[pipe_cnt].pipe.dest.recout_width /= 4;
1427 }
1428 } else {
1429 struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state;
1430 struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data;
1431
1432 pipes[pipe_cnt].pipe.src.immediate_flip = pln->flip_immediate;
1433 pipes[pipe_cnt].pipe.src.is_hsplit = (res_ctx->pipe_ctx[i].bottom_pipe && res_ctx->pipe_ctx[i].bottom_pipe->plane_state == pln)
1434 || (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state == pln)
1435 || pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
1436
1437
1438 if (pln->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE ||
1439 pln->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) {
1440 pipes[pipe_cnt].pipe.src.is_hsplit = false;
1441 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
1442 }
1443
1444 pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
1445 || pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
1446 switch (pln->rotation) {
1447 case ROTATION_ANGLE_0:
1448 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_0;
1449 break;
1450 case ROTATION_ANGLE_90:
1451 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_90;
1452 break;
1453 case ROTATION_ANGLE_180:
1454 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_180;
1455 break;
1456 case ROTATION_ANGLE_270:
1457 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_270;
1458 break;
1459 default:
1460 break;
1461 }
1462 pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
1463 pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
1464 pipes[pipe_cnt].pipe.src.viewport_x_y = scl->viewport.x;
1465 pipes[pipe_cnt].pipe.src.viewport_x_c = scl->viewport_c.x;
1466 pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
1467 pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
1468 pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
1469 pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
1470 pipes[pipe_cnt].pipe.src.viewport_width_max = pln->src_rect.width;
1471 pipes[pipe_cnt].pipe.src.viewport_height_max = pln->src_rect.height;
1472 pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
1473 pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
1474 pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
1475 pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height;
1476 if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA
1477 || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
1478 pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
1479 pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
1480 pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
1481 pipes[pipe_cnt].pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c;
1482 } else {
1483 pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
1484 pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
1485 }
1486 pipes[pipe_cnt].pipe.src.dcc = pln->dcc.enable;
1487 pipes[pipe_cnt].pipe.dest.recout_width = scl->recout.width;
1488 pipes[pipe_cnt].pipe.dest.recout_height = scl->recout.height;
1489 pipes[pipe_cnt].pipe.dest.full_recout_height = scl->recout.height;
1490 pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width;
1491 if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1)
1492 pipes[pipe_cnt].pipe.dest.full_recout_width *= 2;
1493 else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1)
1494 pipes[pipe_cnt].pipe.dest.full_recout_width *= 4;
1495 else {
1496 struct pipe_ctx *split_pipe = res_ctx->pipe_ctx[i].bottom_pipe;
1497
1498 while (split_pipe && split_pipe->plane_state == pln) {
1499 pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
1500 split_pipe = split_pipe->bottom_pipe;
1501 }
1502 split_pipe = res_ctx->pipe_ctx[i].top_pipe;
1503 while (split_pipe && split_pipe->plane_state == pln) {
1504 pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
1505 split_pipe = split_pipe->top_pipe;
1506 }
1507 }
1508
1509 pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
1510 pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = (double) scl->ratios.horz.value / (1ULL<<32);
1511 pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio_c = (double) scl->ratios.horz_c.value / (1ULL<<32);
1512 pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = (double) scl->ratios.vert.value / (1ULL<<32);
1513 pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio_c = (double) scl->ratios.vert_c.value / (1ULL<<32);
1514 pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable =
1515 scl->ratios.vert.value != dc_fixpt_one.value
1516 || scl->ratios.horz.value != dc_fixpt_one.value
1517 || scl->ratios.vert_c.value != dc_fixpt_one.value
1518 || scl->ratios.horz_c.value != dc_fixpt_one.value
1519 || dc->debug.always_scale;
1520 pipes[pipe_cnt].pipe.scale_taps.htaps = scl->taps.h_taps;
1521 pipes[pipe_cnt].pipe.scale_taps.htaps_c = scl->taps.h_taps_c;
1522 pipes[pipe_cnt].pipe.scale_taps.vtaps = scl->taps.v_taps;
1523 pipes[pipe_cnt].pipe.scale_taps.vtaps_c = scl->taps.v_taps_c;
1524
1525 pipes[pipe_cnt].pipe.src.macro_tile_size =
1526 swizzle_mode_to_macro_tile_size(pln->tiling_info.gfx9.swizzle);
1527 swizzle_to_dml_params(pln->tiling_info.gfx9.swizzle,
1528 &pipes[pipe_cnt].pipe.src.sw_mode);
1529
1530 switch (pln->format) {
1531 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
1532 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
1533 pipes[pipe_cnt].pipe.src.source_format = dm_420_8;
1534 break;
1535 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
1536 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
1537 pipes[pipe_cnt].pipe.src.source_format = dm_420_10;
1538 break;
1539 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
1540 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
1541 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
1542 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
1543 pipes[pipe_cnt].pipe.src.source_format = dm_444_64;
1544 break;
1545 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
1546 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
1547 pipes[pipe_cnt].pipe.src.source_format = dm_444_16;
1548 break;
1549 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
1550 pipes[pipe_cnt].pipe.src.source_format = dm_444_8;
1551 break;
1552 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
1553 pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha;
1554 break;
1555 default:
1556 pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
1557 break;
1558 }
1559 }
1560
1561 pipe_cnt++;
1562 }
1563
1564
1565 dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes);
1566
1567 return pipe_cnt;
1568 }
1569
1570 void dcn20_calculate_wm(
1571 struct dc *dc, struct dc_state *context,
1572 display_e2e_pipe_params_st *pipes,
1573 int *out_pipe_cnt,
1574 int *pipe_split_from,
1575 int vlevel,
1576 bool fast_validate)
1577 {
1578 int pipe_cnt, i, pipe_idx;
1579
1580 dc_assert_fp_enabled();
1581
1582 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1583 if (!context->res_ctx.pipe_ctx[i].stream)
1584 continue;
1585
1586 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
1587 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
1588
1589 if (pipe_split_from[i] < 0) {
1590 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
1591 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
1592 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
1593 pipes[pipe_cnt].pipe.dest.odm_combine =
1594 context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];
1595 else
1596 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
1597 pipe_idx++;
1598 } else {
1599 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
1600 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
1601 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
1602 pipes[pipe_cnt].pipe.dest.odm_combine =
1603 context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];
1604 else
1605 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
1606 }
1607
1608 if (dc->config.forced_clocks) {
1609 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
1610 pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
1611 }
1612 if (dc->debug.min_disp_clk_khz > pipes[pipe_cnt].clks_cfg.dispclk_mhz * 1000)
1613 pipes[pipe_cnt].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
1614 if (dc->debug.min_dpp_clk_khz > pipes[pipe_cnt].clks_cfg.dppclk_mhz * 1000)
1615 pipes[pipe_cnt].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
1616
1617 pipe_cnt++;
1618 }
1619
1620 if (pipe_cnt != pipe_idx) {
1621 if (dc->res_pool->funcs->populate_dml_pipes)
1622 pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
1623 context, pipes, fast_validate);
1624 else
1625 pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
1626 context, pipes, fast_validate);
1627 }
1628
1629 *out_pipe_cnt = pipe_cnt;
1630
1631 pipes[0].clks_cfg.voltage = vlevel;
1632 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
1633 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
1634
1635
1636 if (vlevel < 1) {
1637 pipes[0].clks_cfg.voltage = 1;
1638 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
1639 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
1640 }
1641 context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1642 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1643 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1644 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1645 context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1646 context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1647 context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1648 context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1649
1650 if (vlevel < 2) {
1651 pipes[0].clks_cfg.voltage = 2;
1652 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
1653 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
1654 }
1655 context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1656 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1657 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1658 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1659 context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1660 context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1661 context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1662
1663 if (vlevel < 3) {
1664 pipes[0].clks_cfg.voltage = 3;
1665 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
1666 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
1667 }
1668 context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1669 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1670 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1671 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1672 context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1673 context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1674 context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1675
1676 pipes[0].clks_cfg.voltage = vlevel;
1677 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
1678 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
1679 context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1680 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1681 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1682 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1683 context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1684 context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1685 context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
1686 }
1687
1688 void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
1689 struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
1690 {
1691 int num_calculated_states = 0;
1692 int min_dcfclk = 0;
1693 int i;
1694
1695 dc_assert_fp_enabled();
1696
1697 if (num_states == 0)
1698 return;
1699
1700 memset(bb->clock_limits, 0, sizeof(bb->clock_limits));
1701
1702 if (dc->bb_overrides.min_dcfclk_mhz > 0) {
1703 min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
1704 } else {
1705 if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))
1706 min_dcfclk = 310;
1707 else
1708
1709
1710 min_dcfclk = 506;
1711 }
1712
1713 for (i = 0; i < num_states; i++) {
1714 int min_fclk_required_by_uclk;
1715 bb->clock_limits[i].state = i;
1716 bb->clock_limits[i].dram_speed_mts = uclk_states[i] * 16 / 1000;
1717
1718
1719 min_fclk_required_by_uclk = div_u64(((unsigned long long)uclk_states[i]) * 1080,
1720 1000000);
1721
1722 bb->clock_limits[i].fabricclk_mhz = (min_fclk_required_by_uclk < min_dcfclk) ?
1723 min_dcfclk : min_fclk_required_by_uclk;
1724
1725 bb->clock_limits[i].socclk_mhz = (bb->clock_limits[i].fabricclk_mhz > max_clocks->socClockInKhz / 1000) ?
1726 max_clocks->socClockInKhz / 1000 : bb->clock_limits[i].fabricclk_mhz;
1727
1728 bb->clock_limits[i].dcfclk_mhz = (bb->clock_limits[i].fabricclk_mhz > max_clocks->dcfClockInKhz / 1000) ?
1729 max_clocks->dcfClockInKhz / 1000 : bb->clock_limits[i].fabricclk_mhz;
1730
1731 bb->clock_limits[i].dispclk_mhz = max_clocks->displayClockInKhz / 1000;
1732 bb->clock_limits[i].dppclk_mhz = max_clocks->displayClockInKhz / 1000;
1733 bb->clock_limits[i].dscclk_mhz = max_clocks->displayClockInKhz / (1000 * 3);
1734
1735 bb->clock_limits[i].phyclk_mhz = max_clocks->phyClockInKhz / 1000;
1736
1737 num_calculated_states++;
1738 }
1739
1740 bb->clock_limits[num_calculated_states - 1].socclk_mhz = max_clocks->socClockInKhz / 1000;
1741 bb->clock_limits[num_calculated_states - 1].fabricclk_mhz = max_clocks->socClockInKhz / 1000;
1742 bb->clock_limits[num_calculated_states - 1].dcfclk_mhz = max_clocks->dcfClockInKhz / 1000;
1743
1744 bb->num_states = num_calculated_states;
1745
1746
1747 memcpy(&bb->clock_limits[num_calculated_states], &bb->clock_limits[num_calculated_states - 1], sizeof(struct _vcs_dpi_voltage_scaling_st));
1748 bb->clock_limits[num_calculated_states].state = bb->num_states;
1749 }
1750
1751 void dcn20_cap_soc_clocks(
1752 struct _vcs_dpi_soc_bounding_box_st *bb,
1753 struct pp_smu_nv_clock_table max_clocks)
1754 {
1755 int i;
1756
1757 dc_assert_fp_enabled();
1758
1759
1760 for (i = 0; i < bb->num_states; i++) {
1761 if ((bb->clock_limits[i].dcfclk_mhz > (max_clocks.dcfClockInKhz / 1000))
1762 && max_clocks.dcfClockInKhz != 0)
1763 bb->clock_limits[i].dcfclk_mhz = (max_clocks.dcfClockInKhz / 1000);
1764
1765 if ((bb->clock_limits[i].dram_speed_mts > (max_clocks.uClockInKhz / 1000) * 16)
1766 && max_clocks.uClockInKhz != 0)
1767 bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
1768
1769 if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000))
1770 && max_clocks.fabricClockInKhz != 0)
1771 bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000);
1772
1773 if ((bb->clock_limits[i].dispclk_mhz > (max_clocks.displayClockInKhz / 1000))
1774 && max_clocks.displayClockInKhz != 0)
1775 bb->clock_limits[i].dispclk_mhz = (max_clocks.displayClockInKhz / 1000);
1776
1777 if ((bb->clock_limits[i].dppclk_mhz > (max_clocks.dppClockInKhz / 1000))
1778 && max_clocks.dppClockInKhz != 0)
1779 bb->clock_limits[i].dppclk_mhz = (max_clocks.dppClockInKhz / 1000);
1780
1781 if ((bb->clock_limits[i].phyclk_mhz > (max_clocks.phyClockInKhz / 1000))
1782 && max_clocks.phyClockInKhz != 0)
1783 bb->clock_limits[i].phyclk_mhz = (max_clocks.phyClockInKhz / 1000);
1784
1785 if ((bb->clock_limits[i].socclk_mhz > (max_clocks.socClockInKhz / 1000))
1786 && max_clocks.socClockInKhz != 0)
1787 bb->clock_limits[i].socclk_mhz = (max_clocks.socClockInKhz / 1000);
1788
1789 if ((bb->clock_limits[i].dscclk_mhz > (max_clocks.dscClockInKhz / 1000))
1790 && max_clocks.dscClockInKhz != 0)
1791 bb->clock_limits[i].dscclk_mhz = (max_clocks.dscClockInKhz / 1000);
1792 }
1793
1794
1795 for (i = bb->num_states - 1; i > 1; i--) {
1796 bool duplicate = true;
1797
1798 if (bb->clock_limits[i-1].dcfclk_mhz != bb->clock_limits[i].dcfclk_mhz)
1799 duplicate = false;
1800 if (bb->clock_limits[i-1].dispclk_mhz != bb->clock_limits[i].dispclk_mhz)
1801 duplicate = false;
1802 if (bb->clock_limits[i-1].dppclk_mhz != bb->clock_limits[i].dppclk_mhz)
1803 duplicate = false;
1804 if (bb->clock_limits[i-1].dram_speed_mts != bb->clock_limits[i].dram_speed_mts)
1805 duplicate = false;
1806 if (bb->clock_limits[i-1].dscclk_mhz != bb->clock_limits[i].dscclk_mhz)
1807 duplicate = false;
1808 if (bb->clock_limits[i-1].fabricclk_mhz != bb->clock_limits[i].fabricclk_mhz)
1809 duplicate = false;
1810 if (bb->clock_limits[i-1].phyclk_mhz != bb->clock_limits[i].phyclk_mhz)
1811 duplicate = false;
1812 if (bb->clock_limits[i-1].socclk_mhz != bb->clock_limits[i].socclk_mhz)
1813 duplicate = false;
1814
1815 if (duplicate)
1816 bb->num_states--;
1817 }
1818 }
1819
1820 void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
1821 {
1822 dc_assert_fp_enabled();
1823
1824 if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
1825 && dc->bb_overrides.sr_exit_time_ns) {
1826 bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
1827 }
1828
1829 if ((int)(bb->sr_enter_plus_exit_time_us * 1000)
1830 != dc->bb_overrides.sr_enter_plus_exit_time_ns
1831 && dc->bb_overrides.sr_enter_plus_exit_time_ns) {
1832 bb->sr_enter_plus_exit_time_us =
1833 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
1834 }
1835
1836 if ((int)(bb->urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
1837 && dc->bb_overrides.urgent_latency_ns) {
1838 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
1839 }
1840
1841 if ((int)(bb->dram_clock_change_latency_us * 1000)
1842 != dc->bb_overrides.dram_clock_change_latency_ns
1843 && dc->bb_overrides.dram_clock_change_latency_ns) {
1844 bb->dram_clock_change_latency_us =
1845 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
1846 }
1847
1848 if ((int)(bb->dummy_pstate_latency_us * 1000)
1849 != dc->bb_overrides.dummy_clock_change_latency_ns
1850 && dc->bb_overrides.dummy_clock_change_latency_ns) {
1851 bb->dummy_pstate_latency_us =
1852 dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0;
1853 }
1854 }
1855
1856 static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *context,
1857 bool fast_validate)
1858 {
1859 bool out = false;
1860
1861 BW_VAL_TRACE_SETUP();
1862
1863 int vlevel = 0;
1864 int pipe_split_from[MAX_PIPES];
1865 int pipe_cnt = 0;
1866 display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
1867 DC_LOGGER_INIT(dc->ctx->logger);
1868
1869 BW_VAL_TRACE_COUNT();
1870
1871 out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
1872
1873 if (pipe_cnt == 0)
1874 goto validate_out;
1875
1876 if (!out)
1877 goto validate_fail;
1878
1879 BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1880
1881 if (fast_validate) {
1882 BW_VAL_TRACE_SKIP(fast);
1883 goto validate_out;
1884 }
1885
1886 dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
1887 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
1888
1889 BW_VAL_TRACE_END_WATERMARKS();
1890
1891 goto validate_out;
1892
1893 validate_fail:
1894 DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
1895 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
1896
1897 BW_VAL_TRACE_SKIP(fail);
1898 out = false;
1899
1900 validate_out:
1901 kfree(pipes);
1902
1903 BW_VAL_TRACE_FINISH();
1904
1905 return out;
1906 }
1907
1908 bool dcn20_validate_bandwidth_fp(struct dc *dc,
1909 struct dc_state *context,
1910 bool fast_validate)
1911 {
1912 bool voltage_supported = false;
1913 bool full_pstate_supported = false;
1914 bool dummy_pstate_supported = false;
1915 double p_state_latency_us;
1916
1917 dc_assert_fp_enabled();
1918
1919 p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;
1920 context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support =
1921 dc->debug.disable_dram_clock_change_vactive_support;
1922 context->bw_ctx.dml.soc.allow_dram_clock_one_display_vactive =
1923 dc->debug.enable_dram_clock_change_one_display_vactive;
1924
1925
1926 ASSERT(context != dc->current_state);
1927
1928 if (fast_validate) {
1929 return dcn20_validate_bandwidth_internal(dc, context, true);
1930 }
1931
1932
1933 voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
1934 full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
1935
1936 if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 ||
1937 (voltage_supported && full_pstate_supported)) {
1938 context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported;
1939 goto restore_dml_state;
1940 }
1941
1942
1943 context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
1944
1945 voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
1946 dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
1947
1948 if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) {
1949 context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
1950 goto restore_dml_state;
1951 }
1952
1953
1954 ASSERT(false);
1955
1956 restore_dml_state:
1957 context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;
1958 return voltage_supported;
1959 }
1960
1961 void dcn20_fpu_set_wm_ranges(int i,
1962 struct pp_smu_wm_range_sets *ranges,
1963 struct _vcs_dpi_soc_bounding_box_st *loaded_bb)
1964 {
1965 dc_assert_fp_enabled();
1966
1967 ranges->reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
1968 ranges->reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;
1969 }
1970
1971 void dcn20_fpu_adjust_dppclk(struct vba_vars_st *v,
1972 int vlevel,
1973 int max_mpc_comb,
1974 int pipe_idx,
1975 bool is_validating_bw)
1976 {
1977 dc_assert_fp_enabled();
1978
1979 if (is_validating_bw)
1980 v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] *= 2;
1981 else
1982 v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2;
1983 }
1984
1985 int dcn21_populate_dml_pipes_from_context(struct dc *dc,
1986 struct dc_state *context,
1987 display_e2e_pipe_params_st *pipes,
1988 bool fast_validate)
1989 {
1990 uint32_t pipe_cnt;
1991 int i;
1992
1993 dc_assert_fp_enabled();
1994
1995 pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
1996
1997 for (i = 0; i < pipe_cnt; i++) {
1998
1999 pipes[i].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
2000 pipes[i].pipe.src.gpuvm = 1;
2001 }
2002
2003 return pipe_cnt;
2004 }
2005
2006 static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
2007 {
2008 int i;
2009
2010 if (dc->bb_overrides.sr_exit_time_ns) {
2011 for (i = 0; i < WM_SET_COUNT; i++) {
2012 dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =
2013 dc->bb_overrides.sr_exit_time_ns / 1000.0;
2014 }
2015 }
2016
2017 if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {
2018 for (i = 0; i < WM_SET_COUNT; i++) {
2019 dc->clk_mgr->bw_params->wm_table.entries[i].sr_enter_plus_exit_time_us =
2020 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
2021 }
2022 }
2023
2024 if (dc->bb_overrides.urgent_latency_ns) {
2025 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
2026 }
2027
2028 if (dc->bb_overrides.dram_clock_change_latency_ns) {
2029 for (i = 0; i < WM_SET_COUNT; i++) {
2030 dc->clk_mgr->bw_params->wm_table.entries[i].pstate_latency_us =
2031 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
2032 }
2033 }
2034 }
2035
2036 static void calculate_wm_set_for_vlevel(int vlevel,
2037 struct wm_range_table_entry *table_entry,
2038 struct dcn_watermarks *wm_set,
2039 struct display_mode_lib *dml,
2040 display_e2e_pipe_params_st *pipes,
2041 int pipe_cnt)
2042 {
2043 double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
2044
2045 ASSERT(vlevel < dml->soc.num_states);
2046
2047 pipes[0].clks_cfg.voltage = vlevel;
2048 pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
2049 pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
2050
2051 dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
2052 dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
2053 dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
2054
2055 wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
2056 wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
2057 wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
2058 wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
2059 wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
2060 wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
2061 wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
2062 wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
2063 dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
2064 }
2065
2066 static void dcn21_calculate_wm(struct dc *dc, struct dc_state *context,
2067 display_e2e_pipe_params_st *pipes,
2068 int *out_pipe_cnt,
2069 int *pipe_split_from,
2070 int vlevel_req,
2071 bool fast_validate)
2072 {
2073 int pipe_cnt, i, pipe_idx;
2074 int vlevel, vlevel_max;
2075 struct wm_range_table_entry *table_entry;
2076 struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
2077
2078 ASSERT(bw_params);
2079
2080 patch_bounding_box(dc, &context->bw_ctx.dml.soc);
2081
2082 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
2083 if (!context->res_ctx.pipe_ctx[i].stream)
2084 continue;
2085
2086 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
2087 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb];
2088
2089 if (pipe_split_from[i] < 0) {
2090 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
2091 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
2092 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
2093 pipes[pipe_cnt].pipe.dest.odm_combine =
2094 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx];
2095 else
2096 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
2097 pipe_idx++;
2098 } else {
2099 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
2100 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
2101 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
2102 pipes[pipe_cnt].pipe.dest.odm_combine =
2103 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]];
2104 else
2105 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
2106 }
2107 pipe_cnt++;
2108 }
2109
2110 if (pipe_cnt != pipe_idx) {
2111 if (dc->res_pool->funcs->populate_dml_pipes)
2112 pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
2113 context, pipes, fast_validate);
2114 else
2115 pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
2116 context, pipes, fast_validate);
2117 }
2118
2119 *out_pipe_cnt = pipe_cnt;
2120
2121 vlevel_max = bw_params->clk_table.num_entries - 1;
2122
2123
2124
2125 table_entry = &bw_params->wm_table.entries[WM_D];
2126 if (table_entry->wm_type == WM_TYPE_RETRAINING)
2127 vlevel = 0;
2128 else
2129 vlevel = vlevel_max;
2130 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
2131 &context->bw_ctx.dml, pipes, pipe_cnt);
2132
2133 table_entry = &bw_params->wm_table.entries[WM_C];
2134 vlevel = MIN(MAX(vlevel_req, 3), vlevel_max);
2135 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
2136 &context->bw_ctx.dml, pipes, pipe_cnt);
2137
2138 table_entry = &bw_params->wm_table.entries[WM_B];
2139 vlevel = MIN(MAX(vlevel_req, 2), vlevel_max);
2140 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
2141 &context->bw_ctx.dml, pipes, pipe_cnt);
2142
2143
2144 table_entry = &bw_params->wm_table.entries[WM_A];
2145 vlevel = MIN(vlevel_req, vlevel_max);
2146 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
2147 &context->bw_ctx.dml, pipes, pipe_cnt);
2148 }
2149
2150 bool dcn21_validate_bandwidth_fp(struct dc *dc,
2151 struct dc_state *context,
2152 bool fast_validate)
2153 {
2154 bool out = false;
2155
2156 BW_VAL_TRACE_SETUP();
2157
2158 int vlevel = 0;
2159 int pipe_split_from[MAX_PIPES];
2160 int pipe_cnt = 0;
2161 display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
2162 DC_LOGGER_INIT(dc->ctx->logger);
2163
2164 BW_VAL_TRACE_COUNT();
2165
2166 dc_assert_fp_enabled();
2167
2168
2169 ASSERT(context != dc->current_state);
2170
2171 out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
2172
2173 if (pipe_cnt == 0)
2174 goto validate_out;
2175
2176 if (!out)
2177 goto validate_fail;
2178
2179 BW_VAL_TRACE_END_VOLTAGE_LEVEL();
2180
2181 if (fast_validate) {
2182 BW_VAL_TRACE_SKIP(fast);
2183 goto validate_out;
2184 }
2185
2186 dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
2187 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
2188
2189 BW_VAL_TRACE_END_WATERMARKS();
2190
2191 goto validate_out;
2192
2193 validate_fail:
2194 DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
2195 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
2196
2197 BW_VAL_TRACE_SKIP(fail);
2198 out = false;
2199
2200 validate_out:
2201 kfree(pipes);
2202
2203 BW_VAL_TRACE_FINISH();
2204
2205 return out;
2206 }
2207
2208 static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_limit_table *clk_table, unsigned int high_voltage_lvl)
2209 {
2210 struct _vcs_dpi_voltage_scaling_st low_pstate_lvl;
2211 int i;
2212
2213 low_pstate_lvl.state = 1;
2214 low_pstate_lvl.dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
2215 low_pstate_lvl.fabricclk_mhz = clk_table->entries[0].fclk_mhz;
2216 low_pstate_lvl.socclk_mhz = clk_table->entries[0].socclk_mhz;
2217 low_pstate_lvl.dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
2218
2219 low_pstate_lvl.dispclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dispclk_mhz;
2220 low_pstate_lvl.dppclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dppclk_mhz;
2221 low_pstate_lvl.dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[high_voltage_lvl].dram_bw_per_chan_gbps;
2222 low_pstate_lvl.dscclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dscclk_mhz;
2223 low_pstate_lvl.dtbclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dtbclk_mhz;
2224 low_pstate_lvl.phyclk_d18_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_d18_mhz;
2225 low_pstate_lvl.phyclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_mhz;
2226
2227 for (i = clk_table->num_entries; i > 1; i--)
2228 clk_table->entries[i] = clk_table->entries[i-1];
2229 clk_table->entries[1] = clk_table->entries[0];
2230 clk_table->num_entries++;
2231
2232 return low_pstate_lvl;
2233 }
2234
2235 void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
2236 {
2237 struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
2238 struct clk_limit_table *clk_table = &bw_params->clk_table;
2239 unsigned int i, closest_clk_lvl = 0, k = 0;
2240 int j;
2241
2242 dc_assert_fp_enabled();
2243
2244 dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
2245 dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
2246 dcn2_1_soc.num_chans = bw_params->num_channels;
2247
2248 ASSERT(clk_table->num_entries);
2249
2250 memcpy(&dcn2_1_soc._clock_tmp, &dcn2_1_soc.clock_limits,
2251 sizeof(dcn2_1_soc.clock_limits));
2252
2253 for (i = 0; i < clk_table->num_entries; i++) {
2254
2255 for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
2256 if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
2257 closest_clk_lvl = j;
2258 break;
2259 }
2260 }
2261
2262
2263 if (i == 1)
2264 k++;
2265
2266 dcn2_1_soc._clock_tmp[k].state = k;
2267 dcn2_1_soc._clock_tmp[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
2268 dcn2_1_soc._clock_tmp[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
2269 dcn2_1_soc._clock_tmp[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
2270 dcn2_1_soc._clock_tmp[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
2271
2272 dcn2_1_soc._clock_tmp[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
2273 dcn2_1_soc._clock_tmp[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
2274 dcn2_1_soc._clock_tmp[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
2275 dcn2_1_soc._clock_tmp[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
2276 dcn2_1_soc._clock_tmp[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
2277 dcn2_1_soc._clock_tmp[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
2278 dcn2_1_soc._clock_tmp[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
2279
2280 k++;
2281 }
2282
2283 memcpy(&dcn2_1_soc.clock_limits, &dcn2_1_soc._clock_tmp,
2284 sizeof(dcn2_1_soc.clock_limits));
2285
2286 if (clk_table->num_entries) {
2287 dcn2_1_soc.num_states = clk_table->num_entries + 1;
2288
2289 dcn2_1_soc.clock_limits[1] = construct_low_pstate_lvl(clk_table, closest_clk_lvl);
2290
2291 dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
2292 dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
2293 }
2294
2295 dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
2296 }
2297
2298 void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params)
2299 {
2300 dc_assert_fp_enabled();
2301
2302 bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY;
2303 bw_params->wm_table.entries[WM_D].wm_inst = WM_D;
2304 bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING;
2305 bw_params->wm_table.entries[WM_D].valid = true;
2306 }
2307
2308 void dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc,
2309 struct resource_context *res_ctx,
2310 display_e2e_pipe_params_st *pipes)
2311 {
2312 int pipe_cnt, i, j;
2313 double max_calc_writeback_dispclk;
2314 double writeback_dispclk;
2315 struct writeback_st dout_wb;
2316
2317 dc_assert_fp_enabled();
2318
2319 for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
2320 struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream;
2321
2322 if (!stream)
2323 continue;
2324 max_calc_writeback_dispclk = 0;
2325
2326
2327 pipes[pipe_cnt].dout.wb_enable = 0;
2328 pipes[pipe_cnt].dout.num_active_wb = 0;
2329 for (j = 0; j < stream->num_wb_info; j++) {
2330 struct dc_writeback_info *wb_info = &stream->writeback_info[j];
2331
2332 if (wb_info->wb_enabled && wb_info->writeback_source_plane &&
2333 (wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) {
2334 pipes[pipe_cnt].dout.wb_enable = 1;
2335 pipes[pipe_cnt].dout.num_active_wb++;
2336 dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ?
2337 wb_info->dwb_params.cnv_params.crop_height :
2338 wb_info->dwb_params.cnv_params.src_height;
2339 dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ?
2340 wb_info->dwb_params.cnv_params.crop_width :
2341 wb_info->dwb_params.cnv_params.src_width;
2342 dout_wb.wb_dst_width = wb_info->dwb_params.dest_width;
2343 dout_wb.wb_dst_height = wb_info->dwb_params.dest_height;
2344 dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps;
2345 dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps;
2346 dout_wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;
2347 dout_wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;
2348 dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ?
2349 (double)wb_info->dwb_params.cnv_params.crop_width /
2350 (double)wb_info->dwb_params.dest_width :
2351 (double)wb_info->dwb_params.cnv_params.src_width /
2352 (double)wb_info->dwb_params.dest_width;
2353 dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ?
2354 (double)wb_info->dwb_params.cnv_params.crop_height /
2355 (double)wb_info->dwb_params.dest_height :
2356 (double)wb_info->dwb_params.cnv_params.src_height /
2357 (double)wb_info->dwb_params.dest_height;
2358 if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {
2359 if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)
2360 dout_wb.wb_pixel_format = dm_420_8;
2361 else
2362 dout_wb.wb_pixel_format = dm_420_10;
2363 } else
2364 dout_wb.wb_pixel_format = dm_444_32;
2365
2366
2367
2368
2369
2370 writeback_dispclk = CalculateWriteBackDISPCLK(
2371 dout_wb.wb_pixel_format,
2372 pipes[pipe_cnt].pipe.dest.pixel_rate_mhz,
2373 dout_wb.wb_hratio,
2374 dout_wb.wb_vratio,
2375 dout_wb.wb_htaps_luma,
2376 dout_wb.wb_vtaps_luma,
2377 dout_wb.wb_htaps_chroma,
2378 dout_wb.wb_vtaps_chroma,
2379 dout_wb.wb_dst_width,
2380 pipes[pipe_cnt].pipe.dest.htotal,
2381 2);
2382
2383 if (writeback_dispclk > max_calc_writeback_dispclk) {
2384 max_calc_writeback_dispclk = writeback_dispclk;
2385 pipes[pipe_cnt].dout.wb = dout_wb;
2386 }
2387 }
2388 }
2389
2390 pipe_cnt++;
2391 }
2392
2393 }