diff options
| author | Alex Deucher <alexander.deucher@amd.com> | 2011-11-04 10:09:43 -0400 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2011-11-11 14:16:05 +0000 | 
| commit | 8f3f1c9a22a6420e28c2d3eff59b832893bc8efc (patch) | |
| tree | fff750d9ccf699b3607ca473791c9e5820e1a7c5 /drivers | |
| parent | bbe26ffe9ffd231de7cf88c4361f1939858e8594 (diff) | |
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: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 118 | 
2 files changed, 82 insertions, 39 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 41f7cd26515b..fc5a1d642cb5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -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; diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 08d0b94332e6..d2d179267af3 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -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,17 +2389,31 @@ 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)); -		for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { -			clock_info = (union pplib_clock_info *) -				(mode_info->atom_context->bios + data_offset + -				 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + -				 (power_state->v1.ucClockStateIndices[j] * -				  power_info->pplib.ucClockInfoSize)); -			valid = radeon_atombios_parse_pplib_clock_info(rdev, -								       state_index, mode_index, -								       clock_info); -			if (valid) -				mode_index++; +		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 + +					 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + +					 (power_state->v1.ucClockStateIndices[j] * +					  power_info->pplib.ucClockInfoSize)); +				valid = radeon_atombios_parse_pplib_clock_info(rdev, +									       state_index, mode_index, +									       clock_info); +				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) { @@ -2456,18 +2482,32 @@ 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]; -		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { -			clock_array_index = power_state->v2.clockInfoIndex[j]; -			/* XXX this might be an inagua bug... */ -			if (clock_array_index >= clock_info_array->ucNumEntries) -				continue; -			clock_info = (union pplib_clock_info *) -				&clock_info_array->clockInfo[clock_array_index]; -			valid = radeon_atombios_parse_pplib_clock_info(rdev, -								       state_index, mode_index, -								       clock_info); -			if (valid) -				mode_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... */ +				if (clock_array_index >= clock_info_array->ucNumEntries) +					continue; +				clock_info = (union pplib_clock_info *) +					&clock_info_array->clockInfo[clock_array_index]; +				valid = radeon_atombios_parse_pplib_clock_info(rdev, +									       state_index, mode_index, +									       clock_info); +				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) { @@ -2524,19 +2564,23 @@ 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) { -			/* add the default mode */ -			rdev->pm.power_state[state_index].type = -				POWER_STATE_TYPE_DEFAULT; -			rdev->pm.power_state[state_index].num_clock_modes = 1; -			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; -			rdev->pm.power_state[state_index].default_clock_mode = -				&rdev->pm.power_state[state_index].clock_info[0]; -			rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; -			rdev->pm.power_state[state_index].pcie_lanes = 16; -			rdev->pm.default_power_state_index = state_index; -			rdev->pm.power_state[state_index].flags = 0; -			state_index++; +			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; +				rdev->pm.power_state[state_index].num_clock_modes = 1; +				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; +				rdev->pm.power_state[state_index].default_clock_mode = +					&rdev->pm.power_state[state_index].clock_info[0]; +				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; +				rdev->pm.power_state[state_index].pcie_lanes = 16; +				rdev->pm.default_power_state_index = state_index; +				rdev->pm.power_state[state_index].flags = 0; +				state_index++; +			}  		}  	}  | 
