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

Commit 0975b162 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms: dynamically allocate power state space

We previously used a static array, but some new systems
had more states then we had array space, so dynamically
allocate space based on the number of states in the vbios.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=33851



Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 87364760
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -812,8 +812,7 @@ struct radeon_pm {
	fixed20_12		sclk;
	fixed20_12		mclk;
	fixed20_12		needed_bandwidth;
	/* XXX: use a define for num power modes */
	struct radeon_power_state power_state[8];
	struct radeon_power_state *power_state;
	/* number of valid power states */
	int                     num_power_states;
	int                     current_power_state_index;
+27 −13
Original line number Diff line number Diff line
@@ -1977,6 +1977,9 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
	num_modes = power_info->info.ucNumOfPowerModeEntries;
	if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
		num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL);
	if (!rdev->pm.power_state)
		return state_index;
	/* last mode is usually default, array is low to high */
	for (i = 0; i < num_modes; i++) {
		rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
@@ -2328,6 +2331,10 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);

	radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
				       power_info->pplib.ucNumStates, GFP_KERNEL);
	if (!rdev->pm.power_state)
		return state_index;
	/* first mode is usually default, followed by low to high */
	for (i = 0; i < power_info->pplib.ucNumStates; i++) {
		mode_index = 0;
@@ -2408,6 +2415,10 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
	non_clock_info_array = (struct NonClockInfoArray *)
		(mode_info->atom_context->bios + data_offset +
		 power_info->pplib.usNonClockInfoArrayOffset);
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
				       state_array->ucNumEntries, GFP_KERNEL);
	if (!rdev->pm.power_state)
		return state_index;
	for (i = 0; i < state_array->ucNumEntries; i++) {
		mode_index = 0;
		power_state = (union pplib_power_state *)&state_array->states[i];
@@ -2481,6 +2492,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
			break;
		}
	} else {
		rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
		if (rdev->pm.power_state) {
			/* add the default mode */
			rdev->pm.power_state[state_index].type =
				POWER_STATE_TYPE_DEFAULT;
@@ -2495,6 +2508,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
			rdev->pm.power_state[state_index].flags = 0;
			state_index++;
		}
	}

	rdev->pm.num_power_states = state_index;

+11 −0
Original line number Diff line number Diff line
@@ -2442,6 +2442,17 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)

	rdev->pm.default_power_state_index = -1;

	/* allocate 2 power states */
	rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL);
	if (!rdev->pm.power_state) {
		rdev->pm.default_power_state_index = state_index;
		rdev->pm.num_power_states = 0;

		rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
		rdev->pm.current_clock_mode_index = 0;
		return;
	}

	if (rdev->flags & RADEON_IS_MOBILITY) {
		offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
		if (offset) {
+3 −0
Original line number Diff line number Diff line
@@ -646,6 +646,9 @@ void radeon_pm_fini(struct radeon_device *rdev)
#endif
	}

	if (rdev->pm.power_state)
		kfree(rdev->pm.power_state);

	radeon_hwmon_fini(rdev);
}