drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c- Extension
.c- Size
- 14670 bytes
- Lines
- 382
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
resource.hclk_mgr.hdcn20/dcn20_resource.hdcn303/dcn303_resource.hdml/dcn20/dcn20_fpu.hdcn303_fpu.h
Detected Declarations
function dcn303_get_optimal_dcfclk_fclk_for_uclkfunction dcn303_fpu_update_bw_bounding_boxfunction dcn303_fpu_init_soc_bounding_box
Annotated Snippet
if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
num_dcfclk_sta_targets++;
} else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
for (i = 0; i < num_dcfclk_sta_targets; i++) {
if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
dcfclk_sta_targets[i] = max_dcfclk_mhz;
break;
}
}
/* Update size of array since we "removed" duplicates */
num_dcfclk_sta_targets = i + 1;
}
num_uclk_states = bw_params->clk_table.num_entries;
/* Calculate optimal dcfclk for each uclk */
for (i = 0; i < num_uclk_states; i++) {
dcn303_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
&optimal_dcfclk_for_uclk[i], NULL);
if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz)
optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
}
/* Calculate optimal uclk for each dcfclk sta target */
for (i = 0; i < num_dcfclk_sta_targets; i++) {
for (j = 0; j < num_uclk_states; j++) {
if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
optimal_uclk_for_dcfclk_sta_targets[i] =
bw_params->clk_table.entries[j].memclk_mhz * 16;
break;
} else {
/* condition where (dcfclk_sta_targets[i] >= optimal_dcfclk_for_uclk[j]):
* This is required for dcn303 because it just so happens that the memory
* bandwidth is low enough such that all the optimal DCFCLK for each UCLK
* is lower than the smallest DCFCLK STA target. In this case we need to
* populate the optimal UCLK for each DCFCLK STA target to be the max UCLK.
*/
if (j == num_uclk_states - 1) {
optimal_uclk_for_dcfclk_sta_targets[i] =
bw_params->clk_table.entries[j].memclk_mhz * 16;
}
}
}
}
i = 0;
j = 0;
/* create the final dcfclk and uclk table */
while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
} else {
if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
dram_speed_mts[num_states++] =
bw_params->clk_table.entries[j++].memclk_mhz * 16;
} else {
j = num_uclk_states;
}
}
}
while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
}
while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
}
/* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
* MAX_NUM_DPM_LVL is 8.
* dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
* DC__VOLTAGE_STATES is 40.
*/
if (num_states > MAX_NUM_DPM_LVL) {
ASSERT(0);
return;
}
dcn3_03_soc.num_states = num_states;
for (i = 0; i < dcn3_03_soc.num_states; i++) {
dcn3_03_soc.clock_limits[i].state = i;
dcn3_03_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
dcn3_03_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
Annotation
- Immediate include surface: `resource.h`, `clk_mgr.h`, `dcn20/dcn20_resource.h`, `dcn303/dcn303_resource.h`, `dml/dcn20/dcn20_fpu.h`, `dcn303_fpu.h`.
- Detected declarations: `function dcn303_get_optimal_dcfclk_fclk_for_uclk`, `function dcn303_fpu_update_bw_bounding_box`, `function dcn303_fpu_init_soc_bounding_box`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.