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

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
...@@ -784,8 +784,7 @@ struct radeon_pm_clock_info { ...@@ -784,8 +784,7 @@ struct radeon_pm_clock_info {
struct radeon_power_state { struct radeon_power_state {
enum radeon_pm_state_type type; enum radeon_pm_state_type type;
/* XXX: use a define for num clock modes */ struct radeon_pm_clock_info *clock_info;
struct radeon_pm_clock_info clock_info[8];
/* number of valid clock modes in this power state */ /* number of valid clock modes in this power state */
int num_clock_modes; int num_clock_modes;
struct radeon_pm_clock_info *default_clock_mode; struct radeon_pm_clock_info *default_clock_mode;
......
...@@ -1999,6 +1999,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) ...@@ -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; rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
switch (frev) { switch (frev) {
case 1: 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].num_clock_modes = 1;
rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->pm.power_state[state_index].clock_info[0].mclk =
le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); 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) ...@@ -2035,6 +2039,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
state_index++; state_index++;
break; break;
case 2: 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].num_clock_modes = 1;
rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->pm.power_state[state_index].clock_info[0].mclk =
le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); 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) ...@@ -2072,6 +2080,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
state_index++; state_index++;
break; break;
case 3: 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].num_clock_modes = 1;
rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->pm.power_state[state_index].clock_info[0].mclk =
le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); 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 ...@@ -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.default_power_state_index = state_index;
rdev->pm.power_state[state_index].default_clock_mode = rdev->pm.power_state[state_index].default_clock_mode =
&rdev->pm.power_state[state_index].clock_info[mode_index - 1]; &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 */ /* 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_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; 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) ...@@ -2377,17 +2389,31 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
(power_state->v1.ucNonClockStateIndex * (power_state->v1.ucNonClockStateIndex *
power_info->pplib.ucNonClockSize)); power_info->pplib.ucNonClockSize));
for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
clock_info = (union pplib_clock_info *) ((power_info->pplib.ucStateEntrySize - 1) ?
(mode_info->atom_context->bios + data_offset + (power_info->pplib.ucStateEntrySize - 1) : 1),
le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + GFP_KERNEL);
(power_state->v1.ucClockStateIndices[j] * if (!rdev->pm.power_state[i].clock_info)
power_info->pplib.ucClockInfoSize)); return state_index;
valid = radeon_atombios_parse_pplib_clock_info(rdev, if (power_info->pplib.ucStateEntrySize - 1) {
state_index, mode_index, for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
clock_info); clock_info = (union pplib_clock_info *)
if (valid) (mode_info->atom_context->bios + data_offset +
mode_index++; 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; rdev->pm.power_state[state_index].num_clock_modes = mode_index;
if (mode_index) { if (mode_index) {
...@@ -2456,18 +2482,32 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) ...@@ -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_array_index = i; /* power_state->v2.nonClockInfoIndex */
non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
&non_clock_info_array->nonClockInfo[non_clock_array_index]; &non_clock_info_array->nonClockInfo[non_clock_array_index];
for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
clock_array_index = power_state->v2.clockInfoIndex[j]; (power_state->v2.ucNumDPMLevels ?
/* XXX this might be an inagua bug... */ power_state->v2.ucNumDPMLevels : 1),
if (clock_array_index >= clock_info_array->ucNumEntries) GFP_KERNEL);
continue; if (!rdev->pm.power_state[i].clock_info)
clock_info = (union pplib_clock_info *) return state_index;
&clock_info_array->clockInfo[clock_array_index]; if (power_state->v2.ucNumDPMLevels) {
valid = radeon_atombios_parse_pplib_clock_info(rdev, for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
state_index, mode_index, clock_array_index = power_state->v2.clockInfoIndex[j];
clock_info); /* XXX this might be an inagua bug... */
if (valid) if (clock_array_index >= clock_info_array->ucNumEntries)
mode_index++; 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; rdev->pm.power_state[state_index].num_clock_modes = mode_index;
if (mode_index) { if (mode_index) {
...@@ -2524,19 +2564,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) ...@@ -2524,19 +2564,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
} else { } else {
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
if (rdev->pm.power_state) { if (rdev->pm.power_state) {
/* add the default mode */ rdev->pm.power_state[0].clock_info =
rdev->pm.power_state[state_index].type = kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
POWER_STATE_TYPE_DEFAULT; if (rdev->pm.power_state[0].clock_info) {
rdev->pm.power_state[state_index].num_clock_modes = 1; /* add the default mode */
rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; rdev->pm.power_state[state_index].type =
rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; POWER_STATE_TYPE_DEFAULT;
rdev->pm.power_state[state_index].default_clock_mode = rdev->pm.power_state[state_index].num_clock_modes = 1;
&rdev->pm.power_state[state_index].clock_info[0]; rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
rdev->pm.power_state[state_index].pcie_lanes = 16; rdev->pm.power_state[state_index].default_clock_mode =
rdev->pm.default_power_state_index = state_index; &rdev->pm.power_state[state_index].clock_info[0];
rdev->pm.power_state[state_index].flags = 0; rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
state_index++; 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++;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment