brintos

brintos / linux-shallow public Read only

0
0
Text · 12.9 KiB · 4fbecb5 Raw
240 lines · c
1// SPDX-License-Identifier: MIT2//3// Copyright 2024 Advanced Micro Devices, Inc.4 5#include "dcn401_fpu.h"6#include "dcn401/dcn401_resource.h"7// We need this includes for WATERMARKS_* defines8#include "clk_mgr/dcn401/dcn401_smu14_driver_if.h"9#include "link.h"10 11#define DC_LOGGER_INIT(logger)12 13void dcn401_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)14{15	/* defaults */16	double pstate_latency_us = clk_mgr->ctx->dc->dml.soc.dram_clock_change_latency_us;17	double fclk_change_latency_us = clk_mgr->ctx->dc->dml.soc.fclk_change_latency_us;18	double sr_exit_time_us = clk_mgr->ctx->dc->dml.soc.sr_exit_time_us;19	double sr_enter_plus_exit_time_us = clk_mgr->ctx->dc->dml.soc.sr_enter_plus_exit_time_us;20	/* For min clocks use as reported by PM FW and report those as min */21	uint16_t min_uclk_mhz			= clk_mgr->bw_params->clk_table.entries[0].memclk_mhz;22	uint16_t min_dcfclk_mhz			= clk_mgr->bw_params->clk_table.entries[0].dcfclk_mhz;23	uint16_t setb_min_uclk_mhz		= min_uclk_mhz;24	uint16_t dcfclk_mhz_for_the_second_state = clk_mgr->ctx->dc->dml.soc.clock_limits[2].dcfclk_mhz;25 26	dc_assert_fp_enabled();27 28	/* For Set B ranges use min clocks state 2 when available, and report those to PM FW */29	if (dcfclk_mhz_for_the_second_state)30		clk_mgr->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = dcfclk_mhz_for_the_second_state;31	else32		clk_mgr->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = clk_mgr->bw_params->clk_table.entries[0].dcfclk_mhz;33 34	if (clk_mgr->bw_params->clk_table.entries[2].memclk_mhz)35		setb_min_uclk_mhz = clk_mgr->bw_params->clk_table.entries[2].memclk_mhz;36 37	/* Set A - Normal - default values */38	clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid = true;39	clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us = pstate_latency_us;40	clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us = fclk_change_latency_us;41	clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us = sr_exit_time_us;42	clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;43	clk_mgr->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE;44	clk_mgr->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_dcfclk = min_dcfclk_mhz;45	clk_mgr->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_dcfclk = 0xFFFF;46	clk_mgr->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_uclk = min_uclk_mhz;47	clk_mgr->bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_uclk = 0xFFFF;48 49	/* Set B - Performance - higher clocks, using DPM[2] DCFCLK and UCLK */50	clk_mgr->bw_params->wm_table.nv_entries[WM_B].valid = true;51	clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us = pstate_latency_us;52	clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.fclk_change_latency_us = fclk_change_latency_us;53	clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us = sr_exit_time_us;54	clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;55	clk_mgr->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.wm_type = WATERMARKS_CLOCK_RANGE;56	clk_mgr->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_dcfclk = 0xFFFF;57	clk_mgr->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_uclk = setb_min_uclk_mhz;58	clk_mgr->bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_uclk = 0xFFFF;59 60	/* Set C - Dummy P-State - P-State latency set to "dummy p-state" value */61	/* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */62	if (clk_mgr->ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) {63		clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid = true;64		clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 50;65		clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us;66		clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us;67		clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;68		clk_mgr->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.wm_type = WATERMARKS_DUMMY_PSTATE;69		clk_mgr->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_dcfclk = min_dcfclk_mhz;70		clk_mgr->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_dcfclk = 0xFFFF;71		clk_mgr->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;72		clk_mgr->bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;73		clk_mgr->bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->bw_params->clk_table.entries[0].memclk_mhz * 16;74		clk_mgr->bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 50;75		clk_mgr->bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->bw_params->clk_table.entries[1].memclk_mhz * 16;76		clk_mgr->bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9;77		clk_mgr->bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->bw_params->clk_table.entries[2].memclk_mhz * 16;78		clk_mgr->bw_params->dummy_pstate_table[2].dummy_pstate_latency_us = 8;79		clk_mgr->bw_params->dummy_pstate_table[3].dram_speed_mts = clk_mgr->bw_params->clk_table.entries[3].memclk_mhz * 16;80		clk_mgr->bw_params->dummy_pstate_table[3].dummy_pstate_latency_us = 5;81	}82	/* Set D - MALL - SR enter and exit time specific to MALL, TBD after bringup or later phase for now use DRAM values / 2 */83	/* For MALL DRAM clock change latency is N/A, for watermak calculations use lowest value dummy P state latency */84	clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid = true;85	clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = clk_mgr->bw_params->dummy_pstate_table[3].dummy_pstate_latency_us;86	clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.fclk_change_latency_us = fclk_change_latency_us;87	clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = sr_exit_time_us / 2; // TBD88	clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us / 2; // TBD89	clk_mgr->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL;90	clk_mgr->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = min_dcfclk_mhz;91	clk_mgr->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF;92	clk_mgr->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz;93	clk_mgr->bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF;94}95 96/*97 * dcn401_update_bw_bounding_box98 *99 * This would override some dcn4_01 ip_or_soc initial parameters hardcoded from100 * spreadsheet with actual values as per dGPU SKU:101 * - with passed few options from dc->config102 * - with dentist_vco_frequency from Clk Mgr (currently hardcoded, but might103 *   need to get it from PM FW)104 * - with passed latency values (passed in ns units) in dc-> bb override for105 *   debugging purposes106 * - with passed latencies from VBIOS (in 100_ns units) if available for107 *   certain dGPU SKU108 * - with number of DRAM channels from VBIOS (which differ for certain dGPU SKU109 *   of the same ASIC)110 * - clocks levels with passed clk_table entries from Clk Mgr as reported by PM111 *   FW for different clocks (which might differ for certain dGPU SKU of the112 *   same ASIC)113 */114void dcn401_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)115{116	dc_assert_fp_enabled();117 118	/* Override from passed dc->bb_overrides if available*/119	if (dc->bb_overrides.sr_exit_time_ns)120		dc->dml2_options.bbox_overrides.sr_exit_latency_us =121				dc->bb_overrides.sr_exit_time_ns / 1000.0;122 123	if (dc->bb_overrides.sr_enter_plus_exit_time_ns)124		dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us =125			dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;126 127	if (dc->bb_overrides.urgent_latency_ns)128		dc->dml2_options.bbox_overrides.urgent_latency_us =129				dc->bb_overrides.urgent_latency_ns / 1000.0;130 131	if (dc->bb_overrides.dram_clock_change_latency_ns)132		dc->dml2_options.bbox_overrides.dram_clock_change_latency_us =133			dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;134 135	if (dc->bb_overrides.fclk_clock_change_latency_ns)136		dc->dml2_options.bbox_overrides.fclk_change_latency_us =137			dc->bb_overrides.fclk_clock_change_latency_ns / 1000;138 139	/* Override from VBIOS if VBIOS bb_info available */140	if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {141		struct bp_soc_bb_info bb_info = {0};142		if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {143			if (bb_info.dram_clock_change_latency_100ns > 0)144				dc->dml2_options.bbox_overrides.dram_clock_change_latency_us =145					bb_info.dram_clock_change_latency_100ns * 10;146 147			if (bb_info.dram_sr_enter_exit_latency_100ns > 0)148				dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us =149					bb_info.dram_sr_enter_exit_latency_100ns * 10;150 151			if (bb_info.dram_sr_exit_latency_100ns > 0)152				dc->dml2_options.bbox_overrides.sr_exit_latency_us =153					bb_info.dram_sr_exit_latency_100ns * 10;154		}155	}156 157	/* Override from VBIOS for num_chan */158	if (dc->ctx->dc_bios->vram_info.num_chans) {159		dc->dml2_options.bbox_overrides.dram_num_chan =160				dc->ctx->dc_bios->vram_info.num_chans;161 162	}163 164	if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)165		dc->dml2_options.bbox_overrides.dram_chanel_width_bytes =166				dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;167 168	dc->dml2_options.bbox_overrides.disp_pll_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;169	dc->dml2_options.bbox_overrides.xtalclk_mhz = dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency / 1000.0;170	dc->dml2_options.bbox_overrides.dchub_refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;171	dc->dml2_options.bbox_overrides.dprefclk_mhz = dc->clk_mgr->dprefclk_khz / 1000.0;172 173	if (dc->clk_mgr->bw_params->clk_table.num_entries > 1) {174		unsigned int i = 0;175 176		dc->dml2_options.bbox_overrides.clks_table.num_states = dc->clk_mgr->bw_params->clk_table.num_entries;177 178		dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels =179			dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels;180 181		dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_fclk_levels =182			dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_fclk_levels;183 184		dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_memclk_levels =185			dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels;186 187		dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_socclk_levels =188			dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_socclk_levels;189 190		dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dtbclk_levels =191			dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels;192 193		dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dispclk_levels =194			dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;195 196		dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dppclk_levels =197			dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dppclk_levels;198 199		for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels; i++) {200			if (dc->clk_mgr->bw_params->clk_table.entries[i].dcfclk_mhz)201				dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz =202					dc->clk_mgr->bw_params->clk_table.entries[i].dcfclk_mhz;203		}204 205		for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_fclk_levels; i++) {206			if (dc->clk_mgr->bw_params->clk_table.entries[i].fclk_mhz)207				dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].fclk_mhz =208					dc->clk_mgr->bw_params->clk_table.entries[i].fclk_mhz;209		}210 211		for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels; i++) {212			if (dc->clk_mgr->bw_params->clk_table.entries[i].memclk_mhz)213				dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz =214					dc->clk_mgr->bw_params->clk_table.entries[i].memclk_mhz;215		}216 217		for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_socclk_levels; i++) {218			if (dc->clk_mgr->bw_params->clk_table.entries[i].socclk_mhz)219				dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].socclk_mhz =220					dc->clk_mgr->bw_params->clk_table.entries[i].socclk_mhz;221		}222 223		for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels; i++) {224			if (dc->clk_mgr->bw_params->clk_table.entries[i].dtbclk_mhz)225				dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dtbclk_mhz =226					dc->clk_mgr->bw_params->clk_table.entries[i].dtbclk_mhz;227		}228 229		for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels; i++) {230			if (dc->clk_mgr->bw_params->clk_table.entries[i].dispclk_mhz) {231				dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dispclk_mhz =232					dc->clk_mgr->bw_params->clk_table.entries[i].dispclk_mhz;233				dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dppclk_mhz =234					dc->clk_mgr->bw_params->clk_table.entries[i].dispclk_mhz;235			}236		}237	}238}239 240