Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f3f1c9a authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms/pm: switch to dynamically allocating clock mode array



On newer chips the number of clock modes per power state varies.

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent bbe26ffe
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -784,8 +784,7 @@ struct radeon_pm_clock_info {

struct radeon_power_state {
	enum radeon_pm_state_type type;
	/* XXX: use a define for num clock modes */
	struct radeon_pm_clock_info clock_info[8];
	struct radeon_pm_clock_info *clock_info;
	/* number of valid clock modes in this power state */
	int num_clock_modes;
	struct radeon_pm_clock_info *default_clock_mode;
+81 −37
Original line number Diff line number Diff line
@@ -1999,6 +1999,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
		rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
		switch (frev) {
		case 1:
			rdev->pm.power_state[state_index].clock_info =
				kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
			if (!rdev->pm.power_state[state_index].clock_info)
				return state_index;
			rdev->pm.power_state[state_index].num_clock_modes = 1;
			rdev->pm.power_state[state_index].clock_info[0].mclk =
				le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
@@ -2035,6 +2039,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
			state_index++;
			break;
		case 2:
			rdev->pm.power_state[state_index].clock_info =
				kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
			if (!rdev->pm.power_state[state_index].clock_info)
				return state_index;
			rdev->pm.power_state[state_index].num_clock_modes = 1;
			rdev->pm.power_state[state_index].clock_info[0].mclk =
				le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
@@ -2072,6 +2080,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
			state_index++;
			break;
		case 3:
			rdev->pm.power_state[state_index].clock_info =
				kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
			if (!rdev->pm.power_state[state_index].clock_info)
				return state_index;
			rdev->pm.power_state[state_index].num_clock_modes = 1;
			rdev->pm.power_state[state_index].clock_info[0].mclk =
				le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
@@ -2257,7 +2269,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
		rdev->pm.default_power_state_index = state_index;
		rdev->pm.power_state[state_index].default_clock_mode =
			&rdev->pm.power_state[state_index].clock_info[mode_index - 1];
		if (ASIC_IS_DCE5(rdev)) {
		if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) {
			/* NI chips post without MC ucode, so default clocks are strobe mode only */
			rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
			rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
@@ -2377,6 +2389,13 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
			 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
			 (power_state->v1.ucNonClockStateIndex *
			  power_info->pplib.ucNonClockSize));
		rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
							     ((power_info->pplib.ucStateEntrySize - 1) ?
							      (power_info->pplib.ucStateEntrySize - 1) : 1),
							     GFP_KERNEL);
		if (!rdev->pm.power_state[i].clock_info)
			return state_index;
		if (power_info->pplib.ucStateEntrySize - 1) {
			for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
				clock_info = (union pplib_clock_info *)
					(mode_info->atom_context->bios + data_offset +
@@ -2389,6 +2408,13 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
				if (valid)
					mode_index++;
			}
		} else {
			rdev->pm.power_state[state_index].clock_info[0].mclk =
				rdev->clock.default_mclk;
			rdev->pm.power_state[state_index].clock_info[0].sclk =
				rdev->clock.default_sclk;
			mode_index++;
		}
		rdev->pm.power_state[state_index].num_clock_modes = mode_index;
		if (mode_index) {
			radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
@@ -2456,6 +2482,13 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
		non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
			&non_clock_info_array->nonClockInfo[non_clock_array_index];
		rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
							     (power_state->v2.ucNumDPMLevels ?
							      power_state->v2.ucNumDPMLevels : 1),
							     GFP_KERNEL);
		if (!rdev->pm.power_state[i].clock_info)
			return state_index;
		if (power_state->v2.ucNumDPMLevels) {
			for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
				clock_array_index = power_state->v2.clockInfoIndex[j];
				/* XXX this might be an inagua bug... */
@@ -2469,6 +2502,13 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
				if (valid)
					mode_index++;
			}
		} else {
			rdev->pm.power_state[state_index].clock_info[0].mclk =
				rdev->clock.default_mclk;
			rdev->pm.power_state[state_index].clock_info[0].sclk =
				rdev->clock.default_sclk;
			mode_index++;
		}
		rdev->pm.power_state[state_index].num_clock_modes = mode_index;
		if (mode_index) {
			radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
@@ -2524,6 +2564,9 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
	} else {
		rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
		if (rdev->pm.power_state) {
			rdev->pm.power_state[0].clock_info =
				kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
			if (rdev->pm.power_state[0].clock_info) {
				/* add the default mode */
				rdev->pm.power_state[state_index].type =
					POWER_STATE_TYPE_DEFAULT;
@@ -2539,6 +2582,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
				state_index++;
			}
		}
	}

	rdev->pm.num_power_states = state_index;