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>
This commit is contained in:
parent
bbe26ffe9f
commit
8f3f1c9a22
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
} 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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue