Commit c42656f8 authored by Dmytro Laktyushkin's avatar Dmytro Laktyushkin Committed by Alex Deucher
Browse files

drm/amd/display: Fix dcn21 num_states



[Why]
DML expects num_states to exclude the duplicate state.

[How]
Set num_states to correct value to prevent array off-by-one error.  Also
refactor max clock level code for diags.

Signed-off-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Signed-off-by: default avatarGeorge Shen <george.shen@amd.com>
Reviewed-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 00755bb7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3343,7 +3343,7 @@ void dcn20_cap_soc_clocks(
void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
		struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
{
	struct _vcs_dpi_voltage_scaling_st calculated_states[MAX_CLOCK_LIMIT_STATES];
	struct _vcs_dpi_voltage_scaling_st calculated_states[DC__VOLTAGE_STATES];
	int i;
	int num_calculated_states = 0;
	int min_dcfclk = 0;
+12 −25
Original line number Diff line number Diff line
@@ -300,7 +300,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
	.xfc_bus_transport_time_us = 4,
	.xfc_xbuf_latency_tolerance_us = 4,
	.use_urgent_burst_bw = 1,
	.num_states = 9
	.num_states = 8
};

#ifndef MAX
@@ -1377,21 +1377,8 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
	unsigned int i, j, k;
	int closest_clk_lvl;

	// diags does not retrieve proper values from SMU
	// cap states to 5 and make state 5 the max state
	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) || IS_DIAG_DC(dc->ctx->dce_environment)) {
		dcn2_1_soc.num_states = 5;

		dcn2_1_soc.clock_limits[5].state = 5;
		dcn2_1_soc.clock_limits[5].dcfclk_mhz = 810.0;
		dcn2_1_soc.clock_limits[5].fabricclk_mhz = 1600.0;
		dcn2_1_soc.clock_limits[5].dispclk_mhz = 1395.0;
		dcn2_1_soc.clock_limits[5].dppclk_mhz = 1285.0;
		dcn2_1_soc.clock_limits[5].phyclk_mhz = 1325.0;
		dcn2_1_soc.clock_limits[5].socclk_mhz = 953.0;
		dcn2_1_soc.clock_limits[5].dscclk_mhz = 489.0;
		dcn2_1_soc.clock_limits[5].dram_speed_mts = 4266.0;
	} else {
	// Default clock levels are used for diags, which may lead to overclocking.
	if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) {
		dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
		dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
		dcn2_1_soc.num_chans = bw_params->num_channels;
@@ -1404,16 +1391,16 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
		dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;

		/*
		 * Other levels: find cloest DCN clocks that fit the given clock limit using dcfclk
		 * as indicater
		 * Other levels: find closest DCN clocks that fit the given clock limit using dcfclk
		 * as indicator
		 */

		closest_clk_lvl = -1;
		/* index currently being filled */
		k = 1;
		for (i = 1; i < clk_table->num_entries; i++) {
			/* loop backwards, skip duplicate state, +1 because SMU has precision issue */
			for (j = dcn2_1_soc.num_states - 2; j >= k; j--) {
			/* loop backwards, skip duplicate state*/
			for (j = dcn2_1_soc.num_states - 1; j >= k; j--) {
				if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
					closest_clk_lvl = j;
					break;
@@ -1438,12 +1425,12 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
				k++;
			}
		}
		dcn2_1_soc.num_states = k;
	}

	/* duplicate last level */
		dcn2_1_soc.clock_limits[k] = dcn2_1_soc.clock_limits[k - 1];
		dcn2_1_soc.clock_limits[k].state = k;
		dcn2_1_soc.num_states = k + 1;
	}
	dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
	dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;

	dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
}
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@
#define DC__PRESENT 1
#define DC__PRESENT__1 1
#define DC__NUM_DPP 4
#define DC__VOLTAGE_STATES 7
#define DC__VOLTAGE_STATES 9
#define DC__NUM_DPP__4 1
#define DC__NUM_DPP__0_PRESENT 1
#define DC__NUM_DPP__1_PRESENT 1
+4 −3
Original line number Diff line number Diff line
@@ -22,11 +22,12 @@
 * Authors: AMD
 *
 */

#include "dc_features.h"

#ifndef __DISPLAY_MODE_STRUCTS_H__
#define __DISPLAY_MODE_STRUCTS_H__

#define MAX_CLOCK_LIMIT_STATES 9

typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st;
typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st;
typedef struct _vcs_dpi_ip_params_st ip_params_st;
@@ -68,7 +69,7 @@ struct _vcs_dpi_voltage_scaling_st {
};

struct _vcs_dpi_soc_bounding_box_st {
	struct _vcs_dpi_voltage_scaling_st clock_limits[MAX_CLOCK_LIMIT_STATES];
	struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
	unsigned int num_states;
	double sr_exit_time_us;
	double sr_enter_plus_exit_time_us;