summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-02-14 02:29:54 +0400
committerAlex Deucher <alexander.deucher@amd.com>2013-06-28 03:16:25 +0400
commit65171944173dbdc3112e1f799388381e5c65fac3 (patch)
treeede30756cdbd497b0f06c0c4e0a596881fa2d42c
parent58653abdd22427f2b4f2ec9930cadcbeb8832a73 (diff)
downloadlinux-65171944173dbdc3112e1f799388381e5c65fac3.tar.xz
drm/radeon: update radeon_atom_get_voltage_table() for SI
SI uses a new atom table revision. Required for DPM on SI. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/cypress_dpm.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c90
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h1
4 files changed, 69 insertions, 28 deletions
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c
index 7108580d30e1..c7cb19e8fdbe 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -1478,7 +1478,7 @@ int cypress_construct_voltage_tables(struct radeon_device *rdev)
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
int ret;
- ret = radeon_atom_get_voltage_table(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
+ ret = radeon_atom_get_voltage_table(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0,
&eg_pi->vddc_voltage_table);
if (ret)
return ret;
@@ -1488,7 +1488,7 @@ int cypress_construct_voltage_tables(struct radeon_device *rdev)
&eg_pi->vddc_voltage_table);
if (eg_pi->vddci_control) {
- ret = radeon_atom_get_voltage_table(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI,
+ ret = radeon_atom_get_voltage_table(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0,
&eg_pi->vddci_voltage_table);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index fdc36e8219fa..c43b54bb93a7 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -242,7 +242,7 @@ int radeon_atom_get_min_voltage(struct radeon_device *rdev,
int radeon_atom_get_max_voltage(struct radeon_device *rdev,
u8 voltage_type, u16 *max_voltage);
int radeon_atom_get_voltage_table(struct radeon_device *rdev,
- u8 voltage_type,
+ u8 voltage_type, u8 voltage_mode,
struct atom_voltage_table *voltage_table);
bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
u8 voltage_type, u8 voltage_mode);
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 0da95eb77d8e..830c5580532d 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -3372,7 +3372,7 @@ int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,
}
int radeon_atom_get_voltage_table(struct radeon_device *rdev,
- u8 voltage_type,
+ u8 voltage_type, u8 voltage_mode,
struct atom_voltage_table *voltage_table)
{
int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
@@ -3386,41 +3386,81 @@ int radeon_atom_get_voltage_table(struct radeon_device *rdev,
voltage_info = (union voltage_object_info *)
(rdev->mode_info.atom_context->bios + data_offset);
- switch (crev) {
+ switch (frev) {
case 1:
- DRM_ERROR("old table version %d, %d\n", frev, crev);
- return -EINVAL;
case 2:
- num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
- sizeof(ATOM_VOLTAGE_OBJECT_INFO_V2);
+ switch (crev) {
+ case 1:
+ DRM_ERROR("old table version %d, %d\n", frev, crev);
+ return -EINVAL;
+ case 2:
+ num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+ sizeof(ATOM_VOLTAGE_OBJECT_INFO_V2);
- for (i = 0; i < num_indices; i++) {
- if (voltage_info->v2.asVoltageObj[i].ucVoltageType == voltage_type) {
- ATOM_VOLTAGE_FORMULA_V2 *formula =
- &voltage_info->v2.asVoltageObj[i].asFormula;
- if (formula->ucNumOfVoltageEntries > MAX_VOLTAGE_ENTRIES)
- return -EINVAL;
- for (j = 0; j < formula->ucNumOfVoltageEntries; j++) {
- voltage_table->entries[j].value =
- le16_to_cpu(formula->asVIDAdjustEntries[j].usVoltageValue);
- ret = radeon_atom_get_voltage_gpio_settings(rdev,
- voltage_table->entries[j].value,
- voltage_type,
- &voltage_table->entries[j].smio_low,
- &voltage_table->mask_low);
- if (ret)
- return ret;
+ for (i = 0; i < num_indices; i++) {
+ if (voltage_info->v2.asVoltageObj[i].ucVoltageType == voltage_type) {
+ ATOM_VOLTAGE_FORMULA_V2 *formula =
+ &voltage_info->v2.asVoltageObj[i].asFormula;
+ if (formula->ucNumOfVoltageEntries > MAX_VOLTAGE_ENTRIES)
+ return -EINVAL;
+ for (j = 0; j < formula->ucNumOfVoltageEntries; j++) {
+ voltage_table->entries[j].value =
+ le16_to_cpu(formula->asVIDAdjustEntries[j].usVoltageValue);
+ ret = radeon_atom_get_voltage_gpio_settings(rdev,
+ voltage_table->entries[j].value,
+ voltage_type,
+ &voltage_table->entries[j].smio_low,
+ &voltage_table->mask_low);
+ if (ret)
+ return ret;
+ }
+ voltage_table->count = formula->ucNumOfVoltageEntries;
+ return 0;
}
- voltage_table->count = formula->ucNumOfVoltageEntries;
- return 0;
}
+ break;
+ default:
+ DRM_ERROR("unknown voltage object table\n");
+ return -EINVAL;
+ }
+ break;
+ case 3:
+ switch (crev) {
+ case 1:
+ num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+ sizeof(ATOM_VOLTAGE_OBJECT_INFO_V3_1);
+
+ for (i = 0; i < num_indices; i++) {
+ if ((voltage_info->v3.asVoltageObj[i].asGpioVoltageObj.sHeader.ucVoltageType ==
+ voltage_type) &&
+ (voltage_info->v3.asVoltageObj[i].asGpioVoltageObj.sHeader.ucVoltageMode ==
+ voltage_mode)) {
+ ATOM_GPIO_VOLTAGE_OBJECT_V3 *gpio =
+ &voltage_info->v3.asVoltageObj[i].asGpioVoltageObj;
+ if (gpio->ucGpioEntryNum > MAX_VOLTAGE_ENTRIES)
+ return -EINVAL;
+ for (j = 0; j < gpio->ucGpioEntryNum; j++) {
+ voltage_table->entries[j].value =
+ le16_to_cpu(gpio->asVolGpioLut[j].usVoltageValue);
+ voltage_table->entries[j].smio_low =
+ le32_to_cpu(gpio->asVolGpioLut[j].ulVoltageId);
+ }
+ voltage_table->mask_low = le32_to_cpu(gpio->ulGpioMaskVal);
+ voltage_table->count = gpio->ucGpioEntryNum;
+ voltage_table->phase_delay = gpio->ucPhaseDelay;
+ return 0;
+ }
+ }
+ break;
+ default:
+ DRM_ERROR("unknown voltage object table\n");
+ return -EINVAL;
}
break;
default:
DRM_ERROR("unknown voltage object table\n");
return -EINVAL;
}
-
}
return -EINVAL;
}
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index e5ea915993d9..7cc13ba8cdc7 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -597,6 +597,7 @@ struct atom_voltage_table
{
u32 count;
u32 mask_low;
+ u32 phase_delay;
struct atom_voltage_table_entry entries[MAX_VOLTAGE_ENTRIES];
};