Loading drivers/gpu/drm/radeon/radeon.h +3 −0 Original line number Diff line number Diff line Loading @@ -317,6 +317,9 @@ int radeon_atom_get_voltage_table(struct radeon_device *rdev, struct atom_voltage_table *voltage_table); bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev, u8 voltage_type, u8 voltage_mode); int radeon_atom_get_svi2_info(struct radeon_device *rdev, u8 voltage_type, u8 *svd_gpio_id, u8 *svc_gpio_id); void radeon_atom_update_memory_dll(struct radeon_device *rdev, u32 mem_clock); void radeon_atom_set_ac_timing(struct radeon_device *rdev, Loading drivers/gpu/drm/radeon/radeon_atombios.c +44 −0 Original line number Diff line number Diff line Loading @@ -3397,6 +3397,50 @@ radeon_atom_is_voltage_gpio(struct radeon_device *rdev, return false; } int radeon_atom_get_svi2_info(struct radeon_device *rdev, 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 (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, &frev, &crev, &data_offset)) { voltage_info = (union voltage_object_info *) (rdev->mode_info.atom_context->bios + data_offset); switch (frev) { case 3: switch (crev) { case 1: voltage_object = (union voltage_object *) atom_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; } int radeon_atom_get_max_voltage(struct radeon_device *rdev, u8 voltage_type, u16 *max_voltage) { Loading drivers/gpu/drm/radeon/si_dpm.c +108 −44 Original line number Diff line number Diff line Loading @@ -3812,6 +3812,27 @@ void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev, voltage_table->count = max_voltage_steps; } static int si_get_svi2_voltage_table(struct radeon_device *rdev, struct radeon_clock_voltage_dependency_table *voltage_dependency_table, struct atom_voltage_table *voltage_table) { u32 i; if (voltage_dependency_table == NULL) return -EINVAL; voltage_table->mask_low = 0; voltage_table->phase_delay = 0; voltage_table->count = voltage_dependency_table->count; for (i = 0; i < voltage_table->count; i++) { voltage_table->entries[i].value = voltage_dependency_table->entries[i].v; voltage_table->entries[i].smio_low = 0; } return 0; } static int si_construct_voltage_tables(struct radeon_device *rdev) { struct rv7xx_power_info *pi = rv770_get_pi(rdev); Loading @@ -3819,6 +3840,7 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) struct si_power_info *si_pi = si_get_pi(rdev); int ret; if (pi->voltage_control) { ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table); if (ret) Loading @@ -3828,6 +3850,15 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) si_trim_voltage_table_to_fit_state_table(rdev, SISLANDS_MAX_NO_VREG_STEPS, &eg_pi->vddc_voltage_table); } else if (si_pi->voltage_control_svi2) { ret = si_get_svi2_voltage_table(rdev, &rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, &eg_pi->vddc_voltage_table); if (ret) return ret; } else { return -EINVAL; } if (eg_pi->vddci_control) { ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDCI, Loading @@ -3840,6 +3871,13 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) SISLANDS_MAX_NO_VREG_STEPS, &eg_pi->vddci_voltage_table); } if (si_pi->vddci_control_svi2) { ret = si_get_svi2_voltage_table(rdev, &rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, &eg_pi->vddci_voltage_table); if (ret) return ret; } if (pi->mvdd_control) { ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_MVDDC, Loading Loading @@ -3893,6 +3931,14 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev, struct si_power_info *si_pi = si_get_pi(rdev); u8 i; if (si_pi->voltage_control_svi2) { si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc, si_pi->svc_gpio_id); si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd, si_pi->svd_gpio_id); si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_plat_type, 2); } else { if (eg_pi->vddc_voltage_table.count) { si_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table); table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] = Loading Loading @@ -3935,6 +3981,7 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev, si_pi->vddc_phase_shed_control = false; } } } return 0; } Loading Loading @@ -5798,16 +5845,17 @@ int si_dpm_enable(struct radeon_device *rdev) { struct rv7xx_power_info *pi = rv770_get_pi(rdev); struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); struct si_power_info *si_pi = si_get_pi(rdev); struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; int ret; if (si_is_smc_running(rdev)) return -EINVAL; if (pi->voltage_control) if (pi->voltage_control || si_pi->voltage_control_svi2) si_enable_voltage_control(rdev, true); if (pi->mvdd_control) si_get_mvdd_configuration(rdev); if (pi->voltage_control) { if (pi->voltage_control || si_pi->voltage_control_svi2) { ret = si_construct_voltage_tables(rdev); if (ret) { DRM_ERROR("si_construct_voltage_tables failed\n"); Loading Loading @@ -6406,16 +6454,32 @@ int si_dpm_init(struct radeon_device *rdev) ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold; pi->voltage_control = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_GPIO_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_GPIO_LUT); if (!pi->voltage_control) { si_pi->voltage_control_svi2 = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_SVID2); if (si_pi->voltage_control_svi2) radeon_atom_get_svi2_info(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &si_pi->svd_gpio_id, &si_pi->svc_gpio_id); } pi->mvdd_control = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, VOLTAGE_OBJ_GPIO_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, VOLTAGE_OBJ_GPIO_LUT); eg_pi->vddci_control = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, VOLTAGE_OBJ_GPIO_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, VOLTAGE_OBJ_GPIO_LUT); if (!eg_pi->vddci_control) si_pi->vddci_control_svi2 = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, VOLTAGE_OBJ_SVID2); si_pi->vddc_phase_shed_control = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); rv770_get_engine_memory_ss(rdev); Loading drivers/gpu/drm/radeon/si_dpm.h +5 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,8 @@ struct si_power_info { bool vddc_phase_shed_control; bool pspp_notify_required; bool sclk_deep_sleep_above_low; bool voltage_control_svi2; bool vddci_control_svi2; /* smc offsets */ u32 sram_end; u32 state_table_start; Loading @@ -192,6 +194,9 @@ struct si_power_info { SMC_SIslands_MCRegisters smc_mc_reg_table; SISLANDS_SMC_STATETABLE smc_statetable; PP_SIslands_PAPMParameters papm_parm; /* SVI2 */ u8 svd_gpio_id; u8 svc_gpio_id; }; #define SISLANDS_INITIAL_STATE_ARB_INDEX 0 Loading drivers/gpu/drm/radeon/sislands_smc.h +3 −0 Original line number Diff line number Diff line Loading @@ -241,6 +241,9 @@ typedef struct SISLANDS_SMC_STATETABLE SISLANDS_SMC_STATETABLE; #define SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width 0xF4 #define SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen 0xFC #define SI_SMC_SOFT_REGISTER_vr_hot_gpio 0x100 #define SI_SMC_SOFT_REGISTER_svi_rework_plat_type 0x118 #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd 0x11c #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc 0x120 #define SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16 #define SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 32 Loading Loading
drivers/gpu/drm/radeon/radeon.h +3 −0 Original line number Diff line number Diff line Loading @@ -317,6 +317,9 @@ int radeon_atom_get_voltage_table(struct radeon_device *rdev, struct atom_voltage_table *voltage_table); bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev, u8 voltage_type, u8 voltage_mode); int radeon_atom_get_svi2_info(struct radeon_device *rdev, u8 voltage_type, u8 *svd_gpio_id, u8 *svc_gpio_id); void radeon_atom_update_memory_dll(struct radeon_device *rdev, u32 mem_clock); void radeon_atom_set_ac_timing(struct radeon_device *rdev, Loading
drivers/gpu/drm/radeon/radeon_atombios.c +44 −0 Original line number Diff line number Diff line Loading @@ -3397,6 +3397,50 @@ radeon_atom_is_voltage_gpio(struct radeon_device *rdev, return false; } int radeon_atom_get_svi2_info(struct radeon_device *rdev, 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 (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, &frev, &crev, &data_offset)) { voltage_info = (union voltage_object_info *) (rdev->mode_info.atom_context->bios + data_offset); switch (frev) { case 3: switch (crev) { case 1: voltage_object = (union voltage_object *) atom_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; } int radeon_atom_get_max_voltage(struct radeon_device *rdev, u8 voltage_type, u16 *max_voltage) { Loading
drivers/gpu/drm/radeon/si_dpm.c +108 −44 Original line number Diff line number Diff line Loading @@ -3812,6 +3812,27 @@ void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev, voltage_table->count = max_voltage_steps; } static int si_get_svi2_voltage_table(struct radeon_device *rdev, struct radeon_clock_voltage_dependency_table *voltage_dependency_table, struct atom_voltage_table *voltage_table) { u32 i; if (voltage_dependency_table == NULL) return -EINVAL; voltage_table->mask_low = 0; voltage_table->phase_delay = 0; voltage_table->count = voltage_dependency_table->count; for (i = 0; i < voltage_table->count; i++) { voltage_table->entries[i].value = voltage_dependency_table->entries[i].v; voltage_table->entries[i].smio_low = 0; } return 0; } static int si_construct_voltage_tables(struct radeon_device *rdev) { struct rv7xx_power_info *pi = rv770_get_pi(rdev); Loading @@ -3819,6 +3840,7 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) struct si_power_info *si_pi = si_get_pi(rdev); int ret; if (pi->voltage_control) { ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table); if (ret) Loading @@ -3828,6 +3850,15 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) si_trim_voltage_table_to_fit_state_table(rdev, SISLANDS_MAX_NO_VREG_STEPS, &eg_pi->vddc_voltage_table); } else if (si_pi->voltage_control_svi2) { ret = si_get_svi2_voltage_table(rdev, &rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, &eg_pi->vddc_voltage_table); if (ret) return ret; } else { return -EINVAL; } if (eg_pi->vddci_control) { ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDCI, Loading @@ -3840,6 +3871,13 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) SISLANDS_MAX_NO_VREG_STEPS, &eg_pi->vddci_voltage_table); } if (si_pi->vddci_control_svi2) { ret = si_get_svi2_voltage_table(rdev, &rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, &eg_pi->vddci_voltage_table); if (ret) return ret; } if (pi->mvdd_control) { ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_MVDDC, Loading Loading @@ -3893,6 +3931,14 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev, struct si_power_info *si_pi = si_get_pi(rdev); u8 i; if (si_pi->voltage_control_svi2) { si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc, si_pi->svc_gpio_id); si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd, si_pi->svd_gpio_id); si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_plat_type, 2); } else { if (eg_pi->vddc_voltage_table.count) { si_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table); table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] = Loading Loading @@ -3935,6 +3981,7 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev, si_pi->vddc_phase_shed_control = false; } } } return 0; } Loading Loading @@ -5798,16 +5845,17 @@ int si_dpm_enable(struct radeon_device *rdev) { struct rv7xx_power_info *pi = rv770_get_pi(rdev); struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); struct si_power_info *si_pi = si_get_pi(rdev); struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; int ret; if (si_is_smc_running(rdev)) return -EINVAL; if (pi->voltage_control) if (pi->voltage_control || si_pi->voltage_control_svi2) si_enable_voltage_control(rdev, true); if (pi->mvdd_control) si_get_mvdd_configuration(rdev); if (pi->voltage_control) { if (pi->voltage_control || si_pi->voltage_control_svi2) { ret = si_construct_voltage_tables(rdev); if (ret) { DRM_ERROR("si_construct_voltage_tables failed\n"); Loading Loading @@ -6406,16 +6454,32 @@ int si_dpm_init(struct radeon_device *rdev) ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold; pi->voltage_control = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_GPIO_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_GPIO_LUT); if (!pi->voltage_control) { si_pi->voltage_control_svi2 = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_SVID2); if (si_pi->voltage_control_svi2) radeon_atom_get_svi2_info(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &si_pi->svd_gpio_id, &si_pi->svc_gpio_id); } pi->mvdd_control = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, VOLTAGE_OBJ_GPIO_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, VOLTAGE_OBJ_GPIO_LUT); eg_pi->vddci_control = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, VOLTAGE_OBJ_GPIO_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, VOLTAGE_OBJ_GPIO_LUT); if (!eg_pi->vddci_control) si_pi->vddci_control_svi2 = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, VOLTAGE_OBJ_SVID2); si_pi->vddc_phase_shed_control = radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); rv770_get_engine_memory_ss(rdev); Loading
drivers/gpu/drm/radeon/si_dpm.h +5 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,8 @@ struct si_power_info { bool vddc_phase_shed_control; bool pspp_notify_required; bool sclk_deep_sleep_above_low; bool voltage_control_svi2; bool vddci_control_svi2; /* smc offsets */ u32 sram_end; u32 state_table_start; Loading @@ -192,6 +194,9 @@ struct si_power_info { SMC_SIslands_MCRegisters smc_mc_reg_table; SISLANDS_SMC_STATETABLE smc_statetable; PP_SIslands_PAPMParameters papm_parm; /* SVI2 */ u8 svd_gpio_id; u8 svc_gpio_id; }; #define SISLANDS_INITIAL_STATE_ARB_INDEX 0 Loading
drivers/gpu/drm/radeon/sislands_smc.h +3 −0 Original line number Diff line number Diff line Loading @@ -241,6 +241,9 @@ typedef struct SISLANDS_SMC_STATETABLE SISLANDS_SMC_STATETABLE; #define SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width 0xF4 #define SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen 0xFC #define SI_SMC_SOFT_REGISTER_vr_hot_gpio 0x100 #define SI_SMC_SOFT_REGISTER_svi_rework_plat_type 0x118 #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd 0x11c #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc 0x120 #define SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16 #define SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 32 Loading