drm/amdgpu: add si dpm support in amdgpu_atombios
v2: renamed _atom_ to _atombios_ for consistency added ulClockParams to _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 and _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 to avoid build break Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
da69c16144
commit
9139d731fd
@ -978,6 +978,48 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
|
||||
return -EINVAL;
|
||||
|
||||
switch (crev) {
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
/* r6xx, r7xx, evergreen, ni, si.
|
||||
* TODO: add support for asic_type <= CHIP_RV770*/
|
||||
if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
|
||||
args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
|
||||
|
||||
amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
|
||||
dividers->post_div = args.v3.ucPostDiv;
|
||||
dividers->enable_post_div = (args.v3.ucCntlFlag &
|
||||
ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
|
||||
dividers->enable_dithen = (args.v3.ucCntlFlag &
|
||||
ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
|
||||
dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
|
||||
dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
|
||||
dividers->ref_div = args.v3.ucRefDiv;
|
||||
dividers->vco_mode = (args.v3.ucCntlFlag &
|
||||
ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
|
||||
} else {
|
||||
/* for SI we use ComputeMemoryClockParam for memory plls */
|
||||
if (adev->asic_type >= CHIP_TAHITI)
|
||||
return -EINVAL;
|
||||
args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
|
||||
if (strobe_mode)
|
||||
args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
|
||||
|
||||
amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
|
||||
dividers->post_div = args.v5.ucPostDiv;
|
||||
dividers->enable_post_div = (args.v5.ucCntlFlag &
|
||||
ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
|
||||
dividers->enable_dithen = (args.v5.ucCntlFlag &
|
||||
ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
|
||||
dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);
|
||||
dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);
|
||||
dividers->ref_div = args.v5.ucRefDiv;
|
||||
dividers->vco_mode = (args.v5.ucCntlFlag &
|
||||
ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
/* fusion */
|
||||
args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */
|
||||
@ -1122,6 +1164,32 @@ void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
|
||||
amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
|
||||
u16 *vddc, u16 *vddci, u16 *mvdd)
|
||||
{
|
||||
struct amdgpu_mode_info *mode_info = &adev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
|
||||
u8 frev, crev;
|
||||
u16 data_offset;
|
||||
union firmware_info *firmware_info;
|
||||
|
||||
*vddc = 0;
|
||||
*vddci = 0;
|
||||
*mvdd = 0;
|
||||
|
||||
if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
firmware_info =
|
||||
(union firmware_info *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
*vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
|
||||
if ((frev == 2) && (crev >= 2)) {
|
||||
*vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
|
||||
*mvdd = le16_to_cpu(firmware_info->info_22.usBootUpMVDDCVoltage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
union set_voltage {
|
||||
struct _SET_VOLTAGE_PS_ALLOCATION alloc;
|
||||
struct _SET_VOLTAGE_PARAMETERS v1;
|
||||
@ -1129,6 +1197,52 @@ union set_voltage {
|
||||
struct _SET_VOLTAGE_PARAMETERS_V1_3 v3;
|
||||
};
|
||||
|
||||
int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
|
||||
u16 voltage_id, u16 *voltage)
|
||||
{
|
||||
union set_voltage args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
|
||||
u8 frev, crev;
|
||||
|
||||
if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
|
||||
return -EINVAL;
|
||||
|
||||
switch (crev) {
|
||||
case 1:
|
||||
return -EINVAL;
|
||||
case 2:
|
||||
args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE;
|
||||
args.v2.ucVoltageMode = 0;
|
||||
args.v2.usVoltageLevel = 0;
|
||||
|
||||
amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
|
||||
*voltage = le16_to_cpu(args.v2.usVoltageLevel);
|
||||
break;
|
||||
case 3:
|
||||
args.v3.ucVoltageType = voltage_type;
|
||||
args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL;
|
||||
args.v3.usVoltageLevel = cpu_to_le16(voltage_id);
|
||||
|
||||
amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
|
||||
*voltage = le16_to_cpu(args.v3.usVoltageLevel);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
|
||||
u16 *voltage,
|
||||
u16 leakage_idx)
|
||||
{
|
||||
return amdgpu_atombios_get_max_vddc(adev, VOLTAGE_TYPE_VDDC, leakage_idx, voltage);
|
||||
}
|
||||
|
||||
void amdgpu_atombios_set_voltage(struct amdgpu_device *adev,
|
||||
u16 voltage_level,
|
||||
u8 voltage_type)
|
||||
@ -1349,6 +1463,50 @@ static ATOM_VOLTAGE_OBJECT_V3 *amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOL
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
|
||||
u8 voltage_type,
|
||||
u8 *svd_gpio_id, u8 *svc_gpio_id)
|
||||
{
|
||||
int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
|
||||
u8 frev, crev;
|
||||
u16 data_offset, size;
|
||||
union voltage_object_info *voltage_info;
|
||||
union voltage_object *voltage_object = NULL;
|
||||
|
||||
if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
|
||||
&frev, &crev, &data_offset)) {
|
||||
voltage_info = (union voltage_object_info *)
|
||||
(adev->mode_info.atom_context->bios + data_offset);
|
||||
|
||||
switch (frev) {
|
||||
case 3:
|
||||
switch (crev) {
|
||||
case 1:
|
||||
voltage_object = (union voltage_object *)
|
||||
amdgpu_atombios_lookup_voltage_object_v3(&voltage_info->v3,
|
||||
voltage_type,
|
||||
VOLTAGE_OBJ_SVID2);
|
||||
if (voltage_object) {
|
||||
*svd_gpio_id = voltage_object->v3.asSVID2Obj.ucSVDGpioId;
|
||||
*svc_gpio_id = voltage_object->v3.asSVID2Obj.ucSVCGpioId;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("unknown voltage object table\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("unknown voltage object table\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
amdgpu_atombios_is_voltage_gpio(struct amdgpu_device *adev,
|
||||
u8 voltage_type, u8 voltage_mode)
|
||||
|
@ -208,5 +208,19 @@ void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev);
|
||||
void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev);
|
||||
|
||||
void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
|
||||
|
||||
int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
|
||||
u16 voltage_id, u16 *voltage);
|
||||
int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
|
||||
u16 *voltage,
|
||||
u16 leakage_idx);
|
||||
void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
|
||||
u16 *vddc, u16 *vddci, u16 *mvdd);
|
||||
int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
|
||||
u8 clock_type,
|
||||
u32 clock,
|
||||
bool strobe_mode,
|
||||
struct atom_clock_dividers *dividers);
|
||||
int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
|
||||
u8 voltage_type,
|
||||
u8 *svd_gpio_id, u8 *svc_gpio_id);
|
||||
#endif
|
||||
|
@ -494,6 +494,7 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3
|
||||
union
|
||||
{
|
||||
ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter
|
||||
ULONG ulClockParams; //ULONG access for BE
|
||||
ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter
|
||||
};
|
||||
UCHAR ucRefDiv; //Output Parameter
|
||||
@ -526,6 +527,7 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5
|
||||
union
|
||||
{
|
||||
ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter
|
||||
ULONG ulClockParams; //ULONG access for BE
|
||||
ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter
|
||||
};
|
||||
UCHAR ucRefDiv; //Output Parameter
|
||||
|
Loading…
Reference in New Issue
Block a user