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 "clk_mgr.h"
0028 #include "resource.h"
0029 #include "dcn321_fpu.h"
0030 #include "dcn32/dcn32_resource.h"
0031 #include "dcn321/dcn321_resource.h"
0032
0033 #define DCN3_2_DEFAULT_DET_SIZE 256
0034
0035 struct _vcs_dpi_ip_params_st dcn3_21_ip = {
0036 .gpuvm_enable = 0,
0037 .gpuvm_max_page_table_levels = 4,
0038 .hostvm_enable = 0,
0039 .rob_buffer_size_kbytes = 128,
0040 .det_buffer_size_kbytes = DCN3_2_DEFAULT_DET_SIZE,
0041 .config_return_buffer_size_in_kbytes = 1280,
0042 .compressed_buffer_segment_size_in_kbytes = 64,
0043 .meta_fifo_size_in_kentries = 22,
0044 .zero_size_buffer_entries = 512,
0045 .compbuf_reserved_space_64b = 256,
0046 .compbuf_reserved_space_zs = 64,
0047 .dpp_output_buffer_pixels = 2560,
0048 .opp_output_buffer_lines = 1,
0049 .pixel_chunk_size_kbytes = 8,
0050 .alpha_pixel_chunk_size_kbytes = 4,
0051 .min_pixel_chunk_size_bytes = 1024,
0052 .dcc_meta_buffer_size_bytes = 6272,
0053 .meta_chunk_size_kbytes = 2,
0054 .min_meta_chunk_size_bytes = 256,
0055 .writeback_chunk_size_kbytes = 8,
0056 .ptoi_supported = false,
0057 .num_dsc = 4,
0058 .maximum_dsc_bits_per_component = 12,
0059 .maximum_pixels_per_line_per_dsc_unit = 6016,
0060 .dsc422_native_support = true,
0061 .is_line_buffer_bpp_fixed = true,
0062 .line_buffer_fixed_bpp = 57,
0063 .line_buffer_size_bits = 1171920,
0064 .max_line_buffer_lines = 32,
0065 .writeback_interface_buffer_size_kbytes = 90,
0066 .max_num_dpp = 4,
0067 .max_num_otg = 4,
0068 .max_num_hdmi_frl_outputs = 1,
0069 .max_num_wb = 1,
0070 .max_dchub_pscl_bw_pix_per_clk = 4,
0071 .max_pscl_lb_bw_pix_per_clk = 2,
0072 .max_lb_vscl_bw_pix_per_clk = 4,
0073 .max_vscl_hscl_bw_pix_per_clk = 4,
0074 .max_hscl_ratio = 6,
0075 .max_vscl_ratio = 6,
0076 .max_hscl_taps = 8,
0077 .max_vscl_taps = 8,
0078 .dpte_buffer_size_in_pte_reqs_luma = 64,
0079 .dpte_buffer_size_in_pte_reqs_chroma = 34,
0080 .dispclk_ramp_margin_percent = 1,
0081 .max_inter_dcn_tile_repeaters = 8,
0082 .cursor_buffer_size = 16,
0083 .cursor_chunk_size = 2,
0084 .writeback_line_buffer_buffer_size = 0,
0085 .writeback_min_hscl_ratio = 1,
0086 .writeback_min_vscl_ratio = 1,
0087 .writeback_max_hscl_ratio = 1,
0088 .writeback_max_vscl_ratio = 1,
0089 .writeback_max_hscl_taps = 1,
0090 .writeback_max_vscl_taps = 1,
0091 .dppclk_delay_subtotal = 47,
0092 .dppclk_delay_scl = 50,
0093 .dppclk_delay_scl_lb_only = 16,
0094 .dppclk_delay_cnvc_formatter = 28,
0095 .dppclk_delay_cnvc_cursor = 6,
0096 .dispclk_delay_subtotal = 125,
0097 .dynamic_metadata_vm_enabled = false,
0098 .odm_combine_4to1_supported = false,
0099 .dcc_supported = true,
0100 .max_num_dp2p0_outputs = 2,
0101 .max_num_dp2p0_streams = 4,
0102 };
0103
0104 struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
0105 .clock_limits = {
0106 {
0107 .state = 0,
0108 .dcfclk_mhz = 1564.0,
0109 .fabricclk_mhz = 400.0,
0110 .dispclk_mhz = 2150.0,
0111 .dppclk_mhz = 2150.0,
0112 .phyclk_mhz = 810.0,
0113 .phyclk_d18_mhz = 667.0,
0114 .phyclk_d32_mhz = 625.0,
0115 .socclk_mhz = 1200.0,
0116 .dscclk_mhz = 716.667,
0117 .dram_speed_mts = 1600.0,
0118 .dtbclk_mhz = 1564.0,
0119 },
0120 },
0121 .num_states = 1,
0122 .sr_exit_time_us = 12.36,
0123 .sr_enter_plus_exit_time_us = 16.72,
0124 .sr_exit_z8_time_us = 285.0,
0125 .sr_enter_plus_exit_z8_time_us = 320,
0126 .writeback_latency_us = 12.0,
0127 .round_trip_ping_latency_dcfclk_cycles = 263,
0128 .urgent_latency_pixel_data_only_us = 4.0,
0129 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
0130 .urgent_latency_vm_data_only_us = 4.0,
0131 .fclk_change_latency_us = 20,
0132 .usr_retraining_latency_us = 2,
0133 .smn_latency_us = 2,
0134 .mall_allocated_for_dcn_mbytes = 64,
0135 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
0136 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
0137 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
0138 .pct_ideal_sdp_bw_after_urgent = 100.0,
0139 .pct_ideal_fabric_bw_after_urgent = 67.0,
0140 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 20.0,
0141 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
0142 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
0143 .pct_ideal_dram_bw_after_urgent_strobe = 67.0,
0144 .max_avg_sdp_bw_use_normal_percent = 80.0,
0145 .max_avg_fabric_bw_use_normal_percent = 60.0,
0146 .max_avg_dram_bw_use_normal_strobe_percent = 50.0,
0147 .max_avg_dram_bw_use_normal_percent = 15.0,
0148 .num_chans = 8,
0149 .dram_channel_width_bytes = 2,
0150 .fabric_datapath_to_dcn_data_return_bytes = 64,
0151 .return_bus_width_bytes = 64,
0152 .downspread_percent = 0.38,
0153 .dcn_downspread_percent = 0.5,
0154 .dram_clock_change_latency_us = 400,
0155 .dispclk_dppclk_vco_speed_mhz = 4300.0,
0156 .do_urgent_latency_adjustment = true,
0157 .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
0158 .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
0159 };
0160
0161 static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry)
0162 {
0163 if (entry->dcfclk_mhz > 0) {
0164 float bw_on_sdp = entry->dcfclk_mhz * dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 100);
0165
0166 entry->fabricclk_mhz = bw_on_sdp / (dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_fabric_bw_after_urgent / 100));
0167 entry->dram_speed_mts = bw_on_sdp / (dcn3_21_soc.num_chans *
0168 dcn3_21_soc.dram_channel_width_bytes * ((float)dcn3_21_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only / 100));
0169 } else if (entry->fabricclk_mhz > 0) {
0170 float bw_on_fabric = entry->fabricclk_mhz * dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_fabric_bw_after_urgent / 100);
0171
0172 entry->dcfclk_mhz = bw_on_fabric / (dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 100));
0173 entry->dram_speed_mts = bw_on_fabric / (dcn3_21_soc.num_chans *
0174 dcn3_21_soc.dram_channel_width_bytes * ((float)dcn3_21_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only / 100));
0175 } else if (entry->dram_speed_mts > 0) {
0176 float bw_on_dram = entry->dram_speed_mts * dcn3_21_soc.num_chans *
0177 dcn3_21_soc.dram_channel_width_bytes * ((float)dcn3_21_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only / 100);
0178
0179 entry->fabricclk_mhz = bw_on_dram / (dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_fabric_bw_after_urgent / 100));
0180 entry->dcfclk_mhz = bw_on_dram / (dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 100));
0181 }
0182 }
0183
0184 static float calculate_net_bw_in_kbytes_sec(struct _vcs_dpi_voltage_scaling_st *entry)
0185 {
0186 float memory_bw_kbytes_sec;
0187 float fabric_bw_kbytes_sec;
0188 float sdp_bw_kbytes_sec;
0189 float limiting_bw_kbytes_sec;
0190
0191 memory_bw_kbytes_sec = entry->dram_speed_mts * dcn3_21_soc.num_chans *
0192 dcn3_21_soc.dram_channel_width_bytes * ((float)dcn3_21_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only / 100);
0193
0194 fabric_bw_kbytes_sec = entry->fabricclk_mhz * dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_fabric_bw_after_urgent / 100);
0195
0196 sdp_bw_kbytes_sec = entry->dcfclk_mhz * dcn3_21_soc.return_bus_width_bytes * ((float)dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 100);
0197
0198 limiting_bw_kbytes_sec = memory_bw_kbytes_sec;
0199
0200 if (fabric_bw_kbytes_sec < limiting_bw_kbytes_sec)
0201 limiting_bw_kbytes_sec = fabric_bw_kbytes_sec;
0202
0203 if (sdp_bw_kbytes_sec < limiting_bw_kbytes_sec)
0204 limiting_bw_kbytes_sec = sdp_bw_kbytes_sec;
0205
0206 return limiting_bw_kbytes_sec;
0207 }
0208
0209 void dcn321_insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table,
0210 unsigned int *num_entries,
0211 struct _vcs_dpi_voltage_scaling_st *entry)
0212 {
0213 int i = 0;
0214 int index = 0;
0215 float net_bw_of_new_state = 0;
0216
0217 dc_assert_fp_enabled();
0218
0219 get_optimal_ntuple(entry);
0220
0221 if (*num_entries == 0) {
0222 table[0] = *entry;
0223 (*num_entries)++;
0224 } else {
0225 net_bw_of_new_state = calculate_net_bw_in_kbytes_sec(entry);
0226 while (net_bw_of_new_state > calculate_net_bw_in_kbytes_sec(&table[index])) {
0227 index++;
0228 if (index >= *num_entries)
0229 break;
0230 }
0231
0232 for (i = *num_entries; i > index; i--)
0233 table[i] = table[i - 1];
0234
0235 table[index] = *entry;
0236 (*num_entries)++;
0237 }
0238 }
0239
0240 static void remove_entry_from_table_at_index(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries,
0241 unsigned int index)
0242 {
0243 int i;
0244
0245 if (*num_entries == 0)
0246 return;
0247
0248 for (i = index; i < *num_entries - 1; i++) {
0249 table[i] = table[i + 1];
0250 }
0251 memset(&table[--(*num_entries)], 0, sizeof(struct _vcs_dpi_voltage_scaling_st));
0252 }
0253
0254 static int build_synthetic_soc_states(struct clk_bw_params *bw_params,
0255 struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries)
0256 {
0257 int i, j;
0258 struct _vcs_dpi_voltage_scaling_st entry = {0};
0259
0260 unsigned int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0,
0261 max_phyclk_mhz = 0, max_dtbclk_mhz = 0, max_fclk_mhz = 0, max_uclk_mhz = 0;
0262
0263 unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299;
0264
0265 static const unsigned int num_dcfclk_stas = 5;
0266 unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 1324, 1564};
0267
0268 unsigned int num_uclk_dpms = 0;
0269 unsigned int num_fclk_dpms = 0;
0270 unsigned int num_dcfclk_dpms = 0;
0271
0272 for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
0273 if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
0274 max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
0275 if (bw_params->clk_table.entries[i].fclk_mhz > max_fclk_mhz)
0276 max_fclk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
0277 if (bw_params->clk_table.entries[i].memclk_mhz > max_uclk_mhz)
0278 max_uclk_mhz = bw_params->clk_table.entries[i].memclk_mhz;
0279 if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
0280 max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
0281 if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
0282 max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
0283 if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
0284 max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
0285 if (bw_params->clk_table.entries[i].dtbclk_mhz > max_dtbclk_mhz)
0286 max_dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
0287
0288 if (bw_params->clk_table.entries[i].memclk_mhz > 0)
0289 num_uclk_dpms++;
0290 if (bw_params->clk_table.entries[i].fclk_mhz > 0)
0291 num_fclk_dpms++;
0292 if (bw_params->clk_table.entries[i].dcfclk_mhz > 0)
0293 num_dcfclk_dpms++;
0294 }
0295
0296 if (!max_dcfclk_mhz || !max_dispclk_mhz || !max_dtbclk_mhz)
0297 return -1;
0298
0299 if (max_dppclk_mhz == 0)
0300 max_dppclk_mhz = max_dispclk_mhz;
0301
0302 if (max_fclk_mhz == 0)
0303 max_fclk_mhz = max_dcfclk_mhz * dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / dcn3_21_soc.pct_ideal_fabric_bw_after_urgent;
0304
0305 if (max_phyclk_mhz == 0)
0306 max_phyclk_mhz = dcn3_21_soc.clock_limits[0].phyclk_mhz;
0307
0308 *num_entries = 0;
0309 entry.dispclk_mhz = max_dispclk_mhz;
0310 entry.dscclk_mhz = max_dispclk_mhz / 3;
0311 entry.dppclk_mhz = max_dppclk_mhz;
0312 entry.dtbclk_mhz = max_dtbclk_mhz;
0313 entry.phyclk_mhz = max_phyclk_mhz;
0314 entry.phyclk_d18_mhz = dcn3_21_soc.clock_limits[0].phyclk_d18_mhz;
0315 entry.phyclk_d32_mhz = dcn3_21_soc.clock_limits[0].phyclk_d32_mhz;
0316
0317
0318 for (i = 0; i < num_dcfclk_stas; i++) {
0319 entry.dcfclk_mhz = dcfclk_sta_targets[i];
0320 entry.fabricclk_mhz = 0;
0321 entry.dram_speed_mts = 0;
0322
0323 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
0324 }
0325
0326
0327 entry.dcfclk_mhz = max_dcfclk_mhz;
0328 entry.fabricclk_mhz = 0;
0329 entry.dram_speed_mts = 0;
0330
0331 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
0332
0333
0334 for (i = 0; i < num_uclk_dpms; i++) {
0335 entry.dcfclk_mhz = 0;
0336 entry.fabricclk_mhz = 0;
0337 entry.dram_speed_mts = bw_params->clk_table.entries[i].memclk_mhz * 16;
0338
0339 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
0340 }
0341
0342
0343 if (num_fclk_dpms > 2) {
0344 for (i = 0; i < num_fclk_dpms; i++) {
0345 entry.dcfclk_mhz = 0;
0346 entry.fabricclk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
0347 entry.dram_speed_mts = 0;
0348
0349 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
0350 }
0351 }
0352
0353 else {
0354 entry.dcfclk_mhz = 0;
0355 entry.fabricclk_mhz = max_fclk_mhz;
0356 entry.dram_speed_mts = 0;
0357
0358 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry);
0359 }
0360
0361
0362
0363
0364
0365
0366 for (i = *num_entries - 1; i >= 0 ; i--) {
0367 if (table[i].dcfclk_mhz > max_dcfclk_mhz ||
0368 table[i].fabricclk_mhz > max_fclk_mhz ||
0369 table[i].dram_speed_mts > max_uclk_mhz * 16)
0370 remove_entry_from_table_at_index(table, num_entries, i);
0371 }
0372
0373
0374
0375
0376
0377
0378
0379 for (i = *num_entries - 1; i >= 0 ; i--) {
0380 for (j = 0; j < num_uclk_dpms; j++) {
0381 if (bw_params->clk_table.entries[j].memclk_mhz * 16 >= table[i].dram_speed_mts) {
0382 table[i].dram_speed_mts = bw_params->clk_table.entries[j].memclk_mhz * 16;
0383 break;
0384 }
0385 }
0386 }
0387
0388
0389 if (num_fclk_dpms > 2) {
0390 for (i = *num_entries - 1; i >= 0 ; i--) {
0391 for (j = 0; j < num_fclk_dpms; j++) {
0392 if (bw_params->clk_table.entries[j].fclk_mhz >= table[i].fabricclk_mhz) {
0393 table[i].fabricclk_mhz = bw_params->clk_table.entries[j].fclk_mhz;
0394 break;
0395 }
0396 }
0397 }
0398 }
0399
0400 else {
0401 for (i = *num_entries - 1; i >= 0 ; i--) {
0402 if (table[i].fabricclk_mhz < min_fclk_mhz) {
0403 table[i].fabricclk_mhz = min_fclk_mhz;
0404 break;
0405 }
0406 }
0407 }
0408
0409
0410 for (i = *num_entries - 1; i >= 0 ; i--) {
0411 if (table[i].dcfclk_mhz < min_dcfclk_mhz) {
0412 table[i].dcfclk_mhz = min_dcfclk_mhz;
0413 break;
0414 }
0415 }
0416
0417
0418 i = 0;
0419 while (i < *num_entries - 1) {
0420 if (table[i].dcfclk_mhz == table[i + 1].dcfclk_mhz &&
0421 table[i].fabricclk_mhz == table[i + 1].fabricclk_mhz &&
0422 table[i].dram_speed_mts == table[i + 1].dram_speed_mts)
0423 remove_entry_from_table_at_index(table, num_entries, i + 1);
0424 else
0425 i++;
0426 }
0427
0428
0429 for (i = *num_entries - 1; i >= 0 ; i--) {
0430 table[i].state = i;
0431 }
0432
0433 return 0;
0434 }
0435
0436 static void dcn321_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
0437 unsigned int *optimal_dcfclk,
0438 unsigned int *optimal_fclk)
0439 {
0440 double bw_from_dram, bw_from_dram1, bw_from_dram2;
0441
0442 bw_from_dram1 = uclk_mts * dcn3_21_soc.num_chans *
0443 dcn3_21_soc.dram_channel_width_bytes * (dcn3_21_soc.max_avg_dram_bw_use_normal_percent / 100);
0444 bw_from_dram2 = uclk_mts * dcn3_21_soc.num_chans *
0445 dcn3_21_soc.dram_channel_width_bytes * (dcn3_21_soc.max_avg_sdp_bw_use_normal_percent / 100);
0446
0447 bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
0448
0449 if (optimal_fclk)
0450 *optimal_fclk = bw_from_dram /
0451 (dcn3_21_soc.fabric_datapath_to_dcn_data_return_bytes * (dcn3_21_soc.max_avg_sdp_bw_use_normal_percent / 100));
0452
0453 if (optimal_dcfclk)
0454 *optimal_dcfclk = bw_from_dram /
0455 (dcn3_21_soc.return_bus_width_bytes * (dcn3_21_soc.max_avg_sdp_bw_use_normal_percent / 100));
0456 }
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469 void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
0470 {
0471 dc_assert_fp_enabled();
0472 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
0473
0474 dcn3_21_ip.clamp_min_dcfclk = dc->config.clamp_min_dcfclk;
0475
0476
0477 if ((int)(dcn3_21_soc.sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
0478 && dc->bb_overrides.sr_exit_time_ns) {
0479 dcn3_21_soc.sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
0480 }
0481
0482 if ((int)(dcn3_21_soc.sr_enter_plus_exit_time_us * 1000)
0483 != dc->bb_overrides.sr_enter_plus_exit_time_ns
0484 && dc->bb_overrides.sr_enter_plus_exit_time_ns) {
0485 dcn3_21_soc.sr_enter_plus_exit_time_us =
0486 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
0487 }
0488
0489 if ((int)(dcn3_21_soc.urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
0490 && dc->bb_overrides.urgent_latency_ns) {
0491 dcn3_21_soc.urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
0492 }
0493
0494 if ((int)(dcn3_21_soc.dram_clock_change_latency_us * 1000)
0495 != dc->bb_overrides.dram_clock_change_latency_ns
0496 && dc->bb_overrides.dram_clock_change_latency_ns) {
0497 dcn3_21_soc.dram_clock_change_latency_us =
0498 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
0499 }
0500
0501 if ((int)(dcn3_21_soc.fclk_change_latency_us * 1000)
0502 != dc->bb_overrides.fclk_clock_change_latency_ns
0503 && dc->bb_overrides.fclk_clock_change_latency_ns) {
0504 dcn3_21_soc.fclk_change_latency_us =
0505 dc->bb_overrides.fclk_clock_change_latency_ns / 1000;
0506 }
0507
0508 if ((int)(dcn3_21_soc.dummy_pstate_latency_us * 1000)
0509 != dc->bb_overrides.dummy_clock_change_latency_ns
0510 && dc->bb_overrides.dummy_clock_change_latency_ns) {
0511 dcn3_21_soc.dummy_pstate_latency_us =
0512 dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0;
0513 }
0514
0515
0516 if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
0517 struct bp_soc_bb_info bb_info = {0};
0518
0519 if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
0520 if (bb_info.dram_clock_change_latency_100ns > 0)
0521 dcn3_21_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
0522
0523 if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
0524 dcn3_21_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
0525
0526 if (bb_info.dram_sr_exit_latency_100ns > 0)
0527 dcn3_21_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
0528 }
0529 }
0530
0531
0532 if (dc->ctx->dc_bios->vram_info.num_chans)
0533 dcn3_21_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
0534
0535 if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
0536 dcn3_21_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
0537
0538 }
0539
0540
0541 dcn3_21_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
0542 dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
0543
0544
0545 if ((!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) && (bw_params->clk_table.entries[0].memclk_mhz)) {
0546 if (dc->debug.use_legacy_soc_bb_mechanism) {
0547 unsigned int i = 0, j = 0, num_states = 0;
0548
0549 unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
0550 unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
0551 unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
0552 unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
0553
0554 unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {615, 906, 1324, 1564};
0555 unsigned int num_dcfclk_sta_targets = 4, num_uclk_states = 0;
0556 unsigned int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
0557
0558 for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
0559 if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
0560 max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
0561 if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
0562 max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
0563 if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
0564 max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
0565 if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
0566 max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
0567 }
0568 if (!max_dcfclk_mhz)
0569 max_dcfclk_mhz = dcn3_21_soc.clock_limits[0].dcfclk_mhz;
0570 if (!max_dispclk_mhz)
0571 max_dispclk_mhz = dcn3_21_soc.clock_limits[0].dispclk_mhz;
0572 if (!max_dppclk_mhz)
0573 max_dppclk_mhz = dcn3_21_soc.clock_limits[0].dppclk_mhz;
0574 if (!max_phyclk_mhz)
0575 max_phyclk_mhz = dcn3_21_soc.clock_limits[0].phyclk_mhz;
0576
0577 if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
0578
0579 dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
0580 num_dcfclk_sta_targets++;
0581 } else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
0582
0583 for (i = 0; i < num_dcfclk_sta_targets; i++) {
0584 if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
0585 dcfclk_sta_targets[i] = max_dcfclk_mhz;
0586 break;
0587 }
0588 }
0589
0590 num_dcfclk_sta_targets = i + 1;
0591 }
0592
0593 num_uclk_states = bw_params->clk_table.num_entries;
0594
0595
0596 for (i = 0; i < num_uclk_states; i++) {
0597 dcn321_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
0598 &optimal_dcfclk_for_uclk[i], NULL);
0599 if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) {
0600 optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
0601 }
0602 }
0603
0604
0605 for (i = 0; i < num_dcfclk_sta_targets; i++) {
0606 for (j = 0; j < num_uclk_states; j++) {
0607 if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
0608 optimal_uclk_for_dcfclk_sta_targets[i] =
0609 bw_params->clk_table.entries[j].memclk_mhz * 16;
0610 break;
0611 }
0612 }
0613 }
0614
0615 i = 0;
0616 j = 0;
0617
0618 while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
0619 if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) {
0620 dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
0621 dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
0622 } else {
0623 if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
0624 dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
0625 dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
0626 } else {
0627 j = num_uclk_states;
0628 }
0629 }
0630 }
0631
0632 while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
0633 dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
0634 dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
0635 }
0636
0637 while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
0638 optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
0639 dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
0640 dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
0641 }
0642
0643 dcn3_21_soc.num_states = num_states;
0644 for (i = 0; i < dcn3_21_soc.num_states; i++) {
0645 dcn3_21_soc.clock_limits[i].state = i;
0646 dcn3_21_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
0647 dcn3_21_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
0648
0649
0650 dcn3_21_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
0651 dcn3_21_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
0652 dcn3_21_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz;
0653 dcn3_21_soc.clock_limits[i].dscclk_mhz = max_dispclk_mhz / 3;
0654
0655
0656 if (i > 0) {
0657 if (!bw_params->clk_table.entries[i].dtbclk_mhz) {
0658 dcn3_21_soc.clock_limits[i].dtbclk_mhz = dcn3_21_soc.clock_limits[i-1].dtbclk_mhz;
0659 } else {
0660 dcn3_21_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
0661 }
0662 } else if (bw_params->clk_table.entries[i].dtbclk_mhz) {
0663 dcn3_21_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
0664 }
0665
0666 if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0)
0667 dcn3_21_soc.clock_limits[i].socclk_mhz = dcn3_21_soc.clock_limits[i-1].socclk_mhz;
0668 else
0669 dcn3_21_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz;
0670
0671 if (!dram_speed_mts[i] && i > 0)
0672 dcn3_21_soc.clock_limits[i].dram_speed_mts = dcn3_21_soc.clock_limits[i-1].dram_speed_mts;
0673 else
0674 dcn3_21_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
0675
0676
0677
0678 dcn3_21_soc.clock_limits[i].phyclk_d18_mhz = dcn3_21_soc.clock_limits[0].phyclk_d18_mhz;
0679 dcn3_21_soc.clock_limits[i].phyclk_d32_mhz = dcn3_21_soc.clock_limits[0].phyclk_d32_mhz;
0680 }
0681 } else {
0682 build_synthetic_soc_states(bw_params, dcn3_21_soc.clock_limits, &dcn3_21_soc.num_states);
0683 }
0684
0685
0686 dml_init_instance(&dc->dml, &dcn3_21_soc, &dcn3_21_ip, DML_PROJECT_DCN32);
0687 if (dc->current_state)
0688 dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_21_soc, &dcn3_21_ip, DML_PROJECT_DCN32);
0689 }
0690 }
0691