drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
Extension
.c
Size
36926 bytes
Lines
935
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.

Dependency Surface

Detected Declarations

Annotated Snippet

while (entry->net_bw_in_kbytes_sec > table[index].net_bw_in_kbytes_sec) {
			index++;
			if (index >= *num_entries)
				break;
		}

		for (i = *num_entries; i > index; i--)
			table[i] = table[i - 1];

		table[index] = *entry;
		(*num_entries)++;
	}
}

static void remove_entry_from_table_at_index(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries,
		unsigned int index)
{
	unsigned int i;

	if (*num_entries == 0)
		return;

	for (i = index; i < *num_entries - 1; i++) {
		table[i] = table[i + 1];
	}
	memset(&table[--(*num_entries)], 0, sizeof(struct _vcs_dpi_voltage_scaling_st));
}

static void swap_table_entries(struct _vcs_dpi_voltage_scaling_st *first_entry,
		struct _vcs_dpi_voltage_scaling_st *second_entry)
{
	struct _vcs_dpi_voltage_scaling_st temp_entry = *first_entry;
	*first_entry = *second_entry;
	*second_entry = temp_entry;
}

/*
 * sort_entries_with_same_bw - Sort entries sharing the same bandwidth by DCFCLK
 */
static void sort_entries_with_same_bw(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries)
{
	unsigned int start_index = 0;
	unsigned int end_index = 0;
	unsigned int current_bw = 0;

	for (unsigned int i = 0; i + 1 < *num_entries; i++) {
		if (table[i].net_bw_in_kbytes_sec == table[i+1].net_bw_in_kbytes_sec) {
			current_bw = (unsigned int)table[i].net_bw_in_kbytes_sec;
			start_index = i;
			end_index = ++i;

			while ((i + 1 < *num_entries) && (table[i+1].net_bw_in_kbytes_sec == current_bw))
				end_index = ++i;
		}

		if (start_index != end_index) {
			for (unsigned int j = start_index; j < end_index; j++) {
				for (unsigned int k = start_index; k < end_index; k++) {
					if (table[k].dcfclk_mhz > table[k+1].dcfclk_mhz)
						swap_table_entries(&table[k], &table[k+1]);
				}
			}
		}

		start_index = 0;
		end_index = 0;

	}
}

/*
 * remove_inconsistent_entries - Ensure entries with the same bandwidth have MEMCLK and FCLK monotonically increasing
 *                               and remove entries that do not follow this order
 */
static void remove_inconsistent_entries(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries)
{
	for (unsigned int i = 0; i + 1 < *num_entries; i++) {
		if (table[i].net_bw_in_kbytes_sec == table[i+1].net_bw_in_kbytes_sec) {
			if ((table[i].dram_speed_mts > table[i+1].dram_speed_mts) ||
				(table[i].fabricclk_mhz > table[i+1].fabricclk_mhz))
				remove_entry_from_table_at_index(table, num_entries, i);
		}
	}
}

/*
 * override_max_clk_values - Overwrite the max clock frequencies with the max DC mode timings
 * Input:
 *	max_clk_limit - struct containing the desired clock timings
 * Output:

Annotation

Implementation Notes