From 65171944173dbdc3112e1f799388381e5c65fac3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 13 Feb 2013 17:29:54 -0500 Subject: 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 --- drivers/gpu/drm/radeon/cypress_dpm.c | 4 +- drivers/gpu/drm/radeon/radeon.h | 2 +- drivers/gpu/drm/radeon/radeon_atombios.c | 90 +++++++++++++++++++++++--------- drivers/gpu/drm/radeon/radeon_mode.h | 1 + 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 7108580d30e..c7cb19e8fdb 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 fdc36e8219f..c43b54bb93a 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 0da95eb77d8..830c5580532 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 e5ea915993d..7cc13ba8cdc 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]; }; -- cgit v1.2.3-70-g09d2