Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2016 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #include "ppatomfwctrl.h"
0025 #include "atomfirmware.h"
0026 #include "atom.h"
0027 #include "pp_debug.h"
0028 
0029 static const union atom_voltage_object_v4 *pp_atomfwctrl_lookup_voltage_type_v4(
0030         const struct atom_voltage_objects_info_v4_1 *voltage_object_info_table,
0031         uint8_t voltage_type, uint8_t voltage_mode)
0032 {
0033     unsigned int size = le16_to_cpu(
0034             voltage_object_info_table->table_header.structuresize);
0035     unsigned int offset =
0036             offsetof(struct atom_voltage_objects_info_v4_1, voltage_object[0]);
0037     unsigned long start = (unsigned long)voltage_object_info_table;
0038 
0039     while (offset < size) {
0040         const union atom_voltage_object_v4 *voltage_object =
0041             (const union atom_voltage_object_v4 *)(start + offset);
0042 
0043         if (voltage_type == voltage_object->gpio_voltage_obj.header.voltage_type &&
0044             voltage_mode == voltage_object->gpio_voltage_obj.header.voltage_mode)
0045             return voltage_object;
0046 
0047         offset += le16_to_cpu(voltage_object->gpio_voltage_obj.header.object_size);
0048 
0049     }
0050 
0051     return NULL;
0052 }
0053 
0054 static struct atom_voltage_objects_info_v4_1 *pp_atomfwctrl_get_voltage_info_table(
0055         struct pp_hwmgr *hwmgr)
0056 {
0057     const void *table_address;
0058     uint16_t idx;
0059 
0060     idx = GetIndexIntoMasterDataTable(voltageobject_info);
0061     table_address = smu_atom_get_data_table(hwmgr->adev,
0062                         idx, NULL, NULL, NULL);
0063 
0064     PP_ASSERT_WITH_CODE(table_address,
0065             "Error retrieving BIOS Table Address!",
0066             return NULL);
0067 
0068     return (struct atom_voltage_objects_info_v4_1 *)table_address;
0069 }
0070 
0071 /*
0072  * Returns TRUE if the given voltage type is controlled by GPIO pins.
0073  * voltage_type is one of SET_VOLTAGE_TYPE_ASIC_VDDC, SET_VOLTAGE_TYPE_ASIC_MVDDC, SET_VOLTAGE_TYPE_ASIC_MVDDQ.
0074  * voltage_mode is one of ATOM_SET_VOLTAGE, ATOM_SET_VOLTAGE_PHASE
0075  */
0076 bool pp_atomfwctrl_is_voltage_controlled_by_gpio_v4(struct pp_hwmgr *hwmgr,
0077         uint8_t voltage_type, uint8_t voltage_mode)
0078 {
0079     struct atom_voltage_objects_info_v4_1 *voltage_info =
0080             (struct atom_voltage_objects_info_v4_1 *)
0081             pp_atomfwctrl_get_voltage_info_table(hwmgr);
0082     bool ret;
0083 
0084     /* If we cannot find the table do NOT try to control this voltage. */
0085     PP_ASSERT_WITH_CODE(voltage_info,
0086             "Could not find Voltage Table in BIOS.",
0087             return false);
0088 
0089     ret = (pp_atomfwctrl_lookup_voltage_type_v4(voltage_info,
0090             voltage_type, voltage_mode)) ? true : false;
0091 
0092     return ret;
0093 }
0094 
0095 int pp_atomfwctrl_get_voltage_table_v4(struct pp_hwmgr *hwmgr,
0096         uint8_t voltage_type, uint8_t voltage_mode,
0097         struct pp_atomfwctrl_voltage_table *voltage_table)
0098 {
0099     struct atom_voltage_objects_info_v4_1 *voltage_info =
0100             (struct atom_voltage_objects_info_v4_1 *)
0101             pp_atomfwctrl_get_voltage_info_table(hwmgr);
0102     const union atom_voltage_object_v4 *voltage_object;
0103     unsigned int i;
0104     int result = 0;
0105 
0106     PP_ASSERT_WITH_CODE(voltage_info,
0107             "Could not find Voltage Table in BIOS.",
0108             return -1);
0109 
0110     voltage_object = pp_atomfwctrl_lookup_voltage_type_v4(voltage_info,
0111             voltage_type, voltage_mode);
0112 
0113     if (!voltage_object)
0114         return -1;
0115 
0116     voltage_table->count = 0;
0117     if (voltage_mode == VOLTAGE_OBJ_GPIO_LUT) {
0118         PP_ASSERT_WITH_CODE(
0119                 (voltage_object->gpio_voltage_obj.gpio_entry_num <=
0120                 PP_ATOMFWCTRL_MAX_VOLTAGE_ENTRIES),
0121                 "Too many voltage entries!",
0122                 result = -1);
0123 
0124         if (!result) {
0125             for (i = 0; i < voltage_object->gpio_voltage_obj.
0126                             gpio_entry_num; i++) {
0127                 voltage_table->entries[i].value =
0128                         le16_to_cpu(voltage_object->gpio_voltage_obj.
0129                         voltage_gpio_lut[i].voltage_level_mv);
0130                 voltage_table->entries[i].smio_low =
0131                         le32_to_cpu(voltage_object->gpio_voltage_obj.
0132                         voltage_gpio_lut[i].voltage_gpio_reg_val);
0133             }
0134             voltage_table->count =
0135                     voltage_object->gpio_voltage_obj.gpio_entry_num;
0136             voltage_table->mask_low =
0137                     le32_to_cpu(
0138                     voltage_object->gpio_voltage_obj.gpio_mask_val);
0139             voltage_table->phase_delay =
0140                     voltage_object->gpio_voltage_obj.phase_delay_us;
0141         }
0142     } else if (voltage_mode == VOLTAGE_OBJ_SVID2) {
0143         voltage_table->psi1_enable =
0144             (voltage_object->svid2_voltage_obj.loadline_psi1 & 0x20) >> 5;
0145         voltage_table->psi0_enable =
0146             voltage_object->svid2_voltage_obj.psi0_enable & 0x1;
0147         voltage_table->max_vid_step =
0148             voltage_object->svid2_voltage_obj.maxvstep;
0149         voltage_table->telemetry_offset =
0150             voltage_object->svid2_voltage_obj.telemetry_offset;
0151         voltage_table->telemetry_slope =
0152             voltage_object->svid2_voltage_obj.telemetry_gain;
0153     } else
0154         PP_ASSERT_WITH_CODE(false,
0155                 "Unsupported Voltage Object Mode!",
0156                 result = -1);
0157 
0158     return result;
0159 }
0160 
0161  
0162 static struct atom_gpio_pin_lut_v2_1 *pp_atomfwctrl_get_gpio_lookup_table(
0163         struct pp_hwmgr *hwmgr)
0164 {
0165     const void *table_address;
0166     uint16_t idx;
0167 
0168     idx = GetIndexIntoMasterDataTable(gpio_pin_lut);
0169     table_address = smu_atom_get_data_table(hwmgr->adev,
0170             idx, NULL, NULL, NULL);
0171     PP_ASSERT_WITH_CODE(table_address,
0172             "Error retrieving BIOS Table Address!",
0173             return NULL);
0174 
0175     return (struct atom_gpio_pin_lut_v2_1 *)table_address;
0176 }
0177 
0178 static bool pp_atomfwctrl_lookup_gpio_pin(
0179         struct atom_gpio_pin_lut_v2_1 *gpio_lookup_table,
0180         const uint32_t pin_id,
0181         struct pp_atomfwctrl_gpio_pin_assignment *gpio_pin_assignment)
0182 {
0183     unsigned int size = le16_to_cpu(
0184             gpio_lookup_table->table_header.structuresize);
0185     unsigned int offset =
0186             offsetof(struct atom_gpio_pin_lut_v2_1, gpio_pin[0]);
0187     unsigned long start = (unsigned long)gpio_lookup_table;
0188 
0189     while (offset < size) {
0190         const struct  atom_gpio_pin_assignment *pin_assignment =
0191                 (const struct  atom_gpio_pin_assignment *)(start + offset);
0192 
0193         if (pin_id == pin_assignment->gpio_id)  {
0194             gpio_pin_assignment->uc_gpio_pin_bit_shift =
0195                     pin_assignment->gpio_bitshift;
0196             gpio_pin_assignment->us_gpio_pin_aindex =
0197                     le16_to_cpu(pin_assignment->data_a_reg_index);
0198             return true;
0199         }
0200         offset += offsetof(struct atom_gpio_pin_assignment, gpio_id) + 1;
0201     }
0202     return false;
0203 }
0204 
0205 /*
0206  * Returns TRUE if the given pin id find in lookup table.
0207  */
0208 bool pp_atomfwctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr,
0209         const uint32_t pin_id,
0210         struct pp_atomfwctrl_gpio_pin_assignment *gpio_pin_assignment)
0211 {
0212     bool ret = false;
0213     struct atom_gpio_pin_lut_v2_1 *gpio_lookup_table =
0214             pp_atomfwctrl_get_gpio_lookup_table(hwmgr);
0215 
0216     /* If we cannot find the table do NOT try to control this voltage. */
0217     PP_ASSERT_WITH_CODE(gpio_lookup_table,
0218             "Could not find GPIO lookup Table in BIOS.",
0219             return false);
0220 
0221     ret = pp_atomfwctrl_lookup_gpio_pin(gpio_lookup_table,
0222             pin_id, gpio_pin_assignment);
0223 
0224     return ret;
0225 }
0226 
0227 /*
0228  * Enter to SelfRefresh mode.
0229  * @param hwmgr
0230  */
0231 int pp_atomfwctrl_enter_self_refresh(struct pp_hwmgr *hwmgr)
0232 {
0233     /* 0 - no action
0234      * 1 - leave power to video memory always on
0235      */
0236     return 0;
0237 }
0238 
0239 /** pp_atomfwctrl_get_gpu_pll_dividers_vega10().
0240  *
0241  * @param hwmgr       input parameter: pointer to HwMgr
0242  * @param clock_type  input parameter: Clock type: 1 - GFXCLK, 2 - UCLK, 0 - All other clocks
0243  * @param clock_value input parameter: Clock
0244  * @param dividers    output parameter:Clock dividers
0245  */
0246 int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr,
0247         uint32_t clock_type, uint32_t clock_value,
0248         struct pp_atomfwctrl_clock_dividers_soc15 *dividers)
0249 {
0250     struct amdgpu_device *adev = hwmgr->adev;
0251     struct compute_gpu_clock_input_parameter_v1_8 pll_parameters;
0252     struct compute_gpu_clock_output_parameter_v1_8 *pll_output;
0253     uint32_t idx;
0254 
0255     pll_parameters.gpuclock_10khz = (uint32_t)clock_value;
0256     pll_parameters.gpu_clock_type = clock_type;
0257 
0258     idx = GetIndexIntoMasterCmdTable(computegpuclockparam);
0259 
0260     if (amdgpu_atom_execute_table(
0261         adev->mode_info.atom_context, idx, (uint32_t *)&pll_parameters))
0262         return -EINVAL;
0263 
0264     pll_output = (struct compute_gpu_clock_output_parameter_v1_8 *)
0265             &pll_parameters;
0266     dividers->ulClock = le32_to_cpu(pll_output->gpuclock_10khz);
0267     dividers->ulDid = le32_to_cpu(pll_output->dfs_did);
0268     dividers->ulPll_fb_mult = le32_to_cpu(pll_output->pll_fb_mult);
0269     dividers->ulPll_ss_fbsmult = le32_to_cpu(pll_output->pll_ss_fbsmult);
0270     dividers->usPll_ss_slew_frac = le16_to_cpu(pll_output->pll_ss_slew_frac);
0271     dividers->ucPll_ss_enable = pll_output->pll_ss_enable;
0272 
0273     return 0;
0274 }
0275 
0276 int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
0277         struct pp_atomfwctrl_avfs_parameters *param)
0278 {
0279     uint16_t idx;
0280     uint8_t format_revision, content_revision;
0281 
0282     struct atom_asic_profiling_info_v4_1 *profile;
0283     struct atom_asic_profiling_info_v4_2 *profile_v4_2;
0284 
0285     idx = GetIndexIntoMasterDataTable(asic_profiling_info);
0286     profile = (struct atom_asic_profiling_info_v4_1 *)
0287             smu_atom_get_data_table(hwmgr->adev,
0288                     idx, NULL, NULL, NULL);
0289 
0290     if (!profile)
0291         return -1;
0292 
0293     format_revision = ((struct atom_common_table_header *)profile)->format_revision;
0294     content_revision = ((struct atom_common_table_header *)profile)->content_revision;
0295 
0296     if (format_revision == 4 && content_revision == 1) {
0297         param->ulMaxVddc = le32_to_cpu(profile->maxvddc);
0298         param->ulMinVddc = le32_to_cpu(profile->minvddc);
0299         param->ulMeanNsigmaAcontant0 =
0300                 le32_to_cpu(profile->avfs_meannsigma_acontant0);
0301         param->ulMeanNsigmaAcontant1 =
0302                 le32_to_cpu(profile->avfs_meannsigma_acontant1);
0303         param->ulMeanNsigmaAcontant2 =
0304                 le32_to_cpu(profile->avfs_meannsigma_acontant2);
0305         param->usMeanNsigmaDcTolSigma =
0306                 le16_to_cpu(profile->avfs_meannsigma_dc_tol_sigma);
0307         param->usMeanNsigmaPlatformMean =
0308                 le16_to_cpu(profile->avfs_meannsigma_platform_mean);
0309         param->usMeanNsigmaPlatformSigma =
0310                 le16_to_cpu(profile->avfs_meannsigma_platform_sigma);
0311         param->ulGbVdroopTableCksoffA0 =
0312                 le32_to_cpu(profile->gb_vdroop_table_cksoff_a0);
0313         param->ulGbVdroopTableCksoffA1 =
0314                 le32_to_cpu(profile->gb_vdroop_table_cksoff_a1);
0315         param->ulGbVdroopTableCksoffA2 =
0316                 le32_to_cpu(profile->gb_vdroop_table_cksoff_a2);
0317         param->ulGbVdroopTableCksonA0 =
0318                 le32_to_cpu(profile->gb_vdroop_table_ckson_a0);
0319         param->ulGbVdroopTableCksonA1 =
0320                 le32_to_cpu(profile->gb_vdroop_table_ckson_a1);
0321         param->ulGbVdroopTableCksonA2 =
0322                 le32_to_cpu(profile->gb_vdroop_table_ckson_a2);
0323         param->ulGbFuseTableCksoffM1 =
0324                 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1);
0325         param->ulGbFuseTableCksoffM2 =
0326                 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m2);
0327         param->ulGbFuseTableCksoffB =
0328                 le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b);
0329         param->ulGbFuseTableCksonM1 =
0330                 le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1);
0331         param->ulGbFuseTableCksonM2 =
0332                 le32_to_cpu(profile->avfsgb_fuse_table_ckson_m2);
0333         param->ulGbFuseTableCksonB =
0334                 le32_to_cpu(profile->avfsgb_fuse_table_ckson_b);
0335 
0336         param->ucEnableGbVdroopTableCkson =
0337                 profile->enable_gb_vdroop_table_ckson;
0338         param->ucEnableGbFuseTableCkson =
0339                 profile->enable_gb_fuse_table_ckson;
0340         param->usPsmAgeComfactor =
0341                 le16_to_cpu(profile->psm_age_comfactor);
0342 
0343         param->ulDispclk2GfxclkM1 =
0344                 le32_to_cpu(profile->dispclk2gfxclk_a);
0345         param->ulDispclk2GfxclkM2 =
0346                 le32_to_cpu(profile->dispclk2gfxclk_b);
0347         param->ulDispclk2GfxclkB =
0348                 le32_to_cpu(profile->dispclk2gfxclk_c);
0349         param->ulDcefclk2GfxclkM1 =
0350                 le32_to_cpu(profile->dcefclk2gfxclk_a);
0351         param->ulDcefclk2GfxclkM2 =
0352                 le32_to_cpu(profile->dcefclk2gfxclk_b);
0353         param->ulDcefclk2GfxclkB =
0354                 le32_to_cpu(profile->dcefclk2gfxclk_c);
0355         param->ulPixelclk2GfxclkM1 =
0356                 le32_to_cpu(profile->pixclk2gfxclk_a);
0357         param->ulPixelclk2GfxclkM2 =
0358                 le32_to_cpu(profile->pixclk2gfxclk_b);
0359         param->ulPixelclk2GfxclkB =
0360                 le32_to_cpu(profile->pixclk2gfxclk_c);
0361         param->ulPhyclk2GfxclkM1 =
0362                 le32_to_cpu(profile->phyclk2gfxclk_a);
0363         param->ulPhyclk2GfxclkM2 =
0364                 le32_to_cpu(profile->phyclk2gfxclk_b);
0365         param->ulPhyclk2GfxclkB =
0366                 le32_to_cpu(profile->phyclk2gfxclk_c);
0367         param->ulAcgGbVdroopTableA0           = 0;
0368         param->ulAcgGbVdroopTableA1           = 0;
0369         param->ulAcgGbVdroopTableA2           = 0;
0370         param->ulAcgGbFuseTableM1             = 0;
0371         param->ulAcgGbFuseTableM2             = 0;
0372         param->ulAcgGbFuseTableB              = 0;
0373         param->ucAcgEnableGbVdroopTable       = 0;
0374         param->ucAcgEnableGbFuseTable         = 0;
0375     } else if (format_revision == 4 && content_revision == 2) {
0376         profile_v4_2 = (struct atom_asic_profiling_info_v4_2 *)profile;
0377         param->ulMaxVddc = le32_to_cpu(profile_v4_2->maxvddc);
0378         param->ulMinVddc = le32_to_cpu(profile_v4_2->minvddc);
0379         param->ulMeanNsigmaAcontant0 =
0380                 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant0);
0381         param->ulMeanNsigmaAcontant1 =
0382                 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant1);
0383         param->ulMeanNsigmaAcontant2 =
0384                 le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant2);
0385         param->usMeanNsigmaDcTolSigma =
0386                 le16_to_cpu(profile_v4_2->avfs_meannsigma_dc_tol_sigma);
0387         param->usMeanNsigmaPlatformMean =
0388                 le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_mean);
0389         param->usMeanNsigmaPlatformSigma =
0390                 le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_sigma);
0391         param->ulGbVdroopTableCksoffA0 =
0392                 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a0);
0393         param->ulGbVdroopTableCksoffA1 =
0394                 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a1);
0395         param->ulGbVdroopTableCksoffA2 =
0396                 le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a2);
0397         param->ulGbVdroopTableCksonA0 =
0398                 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a0);
0399         param->ulGbVdroopTableCksonA1 =
0400                 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a1);
0401         param->ulGbVdroopTableCksonA2 =
0402                 le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a2);
0403         param->ulGbFuseTableCksoffM1 =
0404                 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m1);
0405         param->ulGbFuseTableCksoffM2 =
0406                 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m2);
0407         param->ulGbFuseTableCksoffB =
0408                 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_b);
0409         param->ulGbFuseTableCksonM1 =
0410                 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m1);
0411         param->ulGbFuseTableCksonM2 =
0412                 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m2);
0413         param->ulGbFuseTableCksonB =
0414                 le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_b);
0415 
0416         param->ucEnableGbVdroopTableCkson =
0417                 profile_v4_2->enable_gb_vdroop_table_ckson;
0418         param->ucEnableGbFuseTableCkson =
0419                 profile_v4_2->enable_gb_fuse_table_ckson;
0420         param->usPsmAgeComfactor =
0421                 le16_to_cpu(profile_v4_2->psm_age_comfactor);
0422 
0423         param->ulDispclk2GfxclkM1 =
0424                 le32_to_cpu(profile_v4_2->dispclk2gfxclk_a);
0425         param->ulDispclk2GfxclkM2 =
0426                 le32_to_cpu(profile_v4_2->dispclk2gfxclk_b);
0427         param->ulDispclk2GfxclkB =
0428                 le32_to_cpu(profile_v4_2->dispclk2gfxclk_c);
0429         param->ulDcefclk2GfxclkM1 =
0430                 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_a);
0431         param->ulDcefclk2GfxclkM2 =
0432                 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_b);
0433         param->ulDcefclk2GfxclkB =
0434                 le32_to_cpu(profile_v4_2->dcefclk2gfxclk_c);
0435         param->ulPixelclk2GfxclkM1 =
0436                 le32_to_cpu(profile_v4_2->pixclk2gfxclk_a);
0437         param->ulPixelclk2GfxclkM2 =
0438                 le32_to_cpu(profile_v4_2->pixclk2gfxclk_b);
0439         param->ulPixelclk2GfxclkB =
0440                 le32_to_cpu(profile_v4_2->pixclk2gfxclk_c);
0441         param->ulPhyclk2GfxclkM1 =
0442                 le32_to_cpu(profile->phyclk2gfxclk_a);
0443         param->ulPhyclk2GfxclkM2 =
0444                 le32_to_cpu(profile_v4_2->phyclk2gfxclk_b);
0445         param->ulPhyclk2GfxclkB =
0446                 le32_to_cpu(profile_v4_2->phyclk2gfxclk_c);
0447         param->ulAcgGbVdroopTableA0 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a0);
0448         param->ulAcgGbVdroopTableA1 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a1);
0449         param->ulAcgGbVdroopTableA2 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a2);
0450         param->ulAcgGbFuseTableM1 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m1);
0451         param->ulAcgGbFuseTableM2 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m2);
0452         param->ulAcgGbFuseTableB = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_b);
0453         param->ucAcgEnableGbVdroopTable = le32_to_cpu(profile_v4_2->enable_acg_gb_vdroop_table);
0454         param->ucAcgEnableGbFuseTable = le32_to_cpu(profile_v4_2->enable_acg_gb_fuse_table);
0455     } else {
0456         pr_info("Invalid VBIOS AVFS ProfilingInfo Revision!\n");
0457         return -EINVAL;
0458     }
0459 
0460     return 0;
0461 }
0462 
0463 int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,
0464         struct pp_atomfwctrl_gpio_parameters *param)
0465 {
0466     struct atom_smu_info_v3_1 *info;
0467     uint16_t idx;
0468 
0469     idx = GetIndexIntoMasterDataTable(smu_info);
0470     info = (struct atom_smu_info_v3_1 *)
0471         smu_atom_get_data_table(hwmgr->adev,
0472                 idx, NULL, NULL, NULL);
0473 
0474     if (!info) {
0475         pr_info("Error retrieving BIOS smu_info Table Address!");
0476         return -1;
0477     }
0478 
0479     param->ucAcDcGpio       = info->ac_dc_gpio_bit;
0480     param->ucAcDcPolarity   = info->ac_dc_polarity;
0481     param->ucVR0HotGpio     = info->vr0hot_gpio_bit;
0482     param->ucVR0HotPolarity = info->vr0hot_polarity;
0483     param->ucVR1HotGpio     = info->vr1hot_gpio_bit;
0484     param->ucVR1HotPolarity = info->vr1hot_polarity;
0485     param->ucFwCtfGpio      = info->fw_ctf_gpio_bit;
0486     param->ucFwCtfPolarity  = info->fw_ctf_polarity;
0487 
0488     return 0;
0489 }
0490 
0491 int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr,
0492                            uint8_t clk_id, uint8_t syspll_id,
0493                            uint32_t *frequency)
0494 {
0495     struct amdgpu_device *adev = hwmgr->adev;
0496     struct atom_get_smu_clock_info_parameters_v3_1   parameters;
0497     struct atom_get_smu_clock_info_output_parameters_v3_1 *output;
0498     uint32_t ix;
0499 
0500     parameters.clk_id = clk_id;
0501     parameters.syspll_id = syspll_id;
0502     parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ;
0503     parameters.dfsdid = 0;
0504 
0505     ix = GetIndexIntoMasterCmdTable(getsmuclockinfo);
0506 
0507     if (amdgpu_atom_execute_table(
0508         adev->mode_info.atom_context, ix, (uint32_t *)&parameters))
0509         return -EINVAL;
0510 
0511     output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)&parameters;
0512     *frequency = le32_to_cpu(output->atom_smu_outputclkfreq.smu_clock_freq_hz) / 10000;
0513 
0514     return 0;
0515 }
0516 
0517 static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr,
0518             struct pp_atomfwctrl_bios_boot_up_values *boot_values,
0519             struct atom_firmware_info_v3_2 *fw_info)
0520 {
0521     uint32_t frequency = 0;
0522 
0523     boot_values->ulRevision = fw_info->firmware_revision;
0524     boot_values->ulGfxClk   = fw_info->bootup_sclk_in10khz;
0525     boot_values->ulUClk     = fw_info->bootup_mclk_in10khz;
0526     boot_values->usVddc     = fw_info->bootup_vddc_mv;
0527     boot_values->usVddci    = fw_info->bootup_vddci_mv;
0528     boot_values->usMvddc    = fw_info->bootup_mvddc_mv;
0529     boot_values->usVddGfx   = fw_info->bootup_vddgfx_mv;
0530     boot_values->ucCoolingID = fw_info->coolingsolution_id;
0531     boot_values->ulSocClk   = 0;
0532     boot_values->ulDCEFClk   = 0;
0533 
0534     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, SMU11_SYSPLL0_ID, &frequency))
0535         boot_values->ulSocClk   = frequency;
0536 
0537     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, SMU11_SYSPLL0_ID, &frequency))
0538         boot_values->ulDCEFClk  = frequency;
0539 
0540     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, SMU11_SYSPLL0_ID, &frequency))
0541         boot_values->ulEClk     = frequency;
0542 
0543     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, SMU11_SYSPLL0_ID, &frequency))
0544         boot_values->ulVClk     = frequency;
0545 
0546     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, SMU11_SYSPLL0_ID, &frequency))
0547         boot_values->ulDClk     = frequency;
0548 
0549     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL1_0_FCLK_ID, SMU11_SYSPLL1_2_ID, &frequency))
0550         boot_values->ulFClk     = frequency;
0551 }
0552 
0553 static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr,
0554             struct pp_atomfwctrl_bios_boot_up_values *boot_values,
0555             struct atom_firmware_info_v3_1 *fw_info)
0556 {
0557     uint32_t frequency = 0;
0558 
0559     boot_values->ulRevision = fw_info->firmware_revision;
0560     boot_values->ulGfxClk   = fw_info->bootup_sclk_in10khz;
0561     boot_values->ulUClk     = fw_info->bootup_mclk_in10khz;
0562     boot_values->usVddc     = fw_info->bootup_vddc_mv;
0563     boot_values->usVddci    = fw_info->bootup_vddci_mv;
0564     boot_values->usMvddc    = fw_info->bootup_mvddc_mv;
0565     boot_values->usVddGfx   = fw_info->bootup_vddgfx_mv;
0566     boot_values->ucCoolingID = fw_info->coolingsolution_id;
0567     boot_values->ulSocClk   = 0;
0568     boot_values->ulDCEFClk   = 0;
0569 
0570     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, 0, &frequency))
0571         boot_values->ulSocClk   = frequency;
0572 
0573     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, 0, &frequency))
0574         boot_values->ulDCEFClk  = frequency;
0575 
0576     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, 0, &frequency))
0577         boot_values->ulEClk     = frequency;
0578 
0579     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, 0, &frequency))
0580         boot_values->ulVClk     = frequency;
0581 
0582     if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, 0, &frequency))
0583         boot_values->ulDClk     = frequency;
0584 }
0585 
0586 int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
0587             struct pp_atomfwctrl_bios_boot_up_values *boot_values)
0588 {
0589     struct atom_firmware_info_v3_2 *fwinfo_3_2;
0590     struct atom_firmware_info_v3_1 *fwinfo_3_1;
0591     struct atom_common_table_header *info = NULL;
0592     uint16_t ix;
0593 
0594     ix = GetIndexIntoMasterDataTable(firmwareinfo);
0595     info = (struct atom_common_table_header *)
0596         smu_atom_get_data_table(hwmgr->adev,
0597                 ix, NULL, NULL, NULL);
0598 
0599     if (!info) {
0600         pr_info("Error retrieving BIOS firmwareinfo!");
0601         return -EINVAL;
0602     }
0603 
0604     if ((info->format_revision == 3) && (info->content_revision == 2)) {
0605         fwinfo_3_2 = (struct atom_firmware_info_v3_2 *)info;
0606         pp_atomfwctrl_copy_vbios_bootup_values_3_2(hwmgr,
0607                 boot_values, fwinfo_3_2);
0608     } else if ((info->format_revision == 3) && (info->content_revision == 1)) {
0609         fwinfo_3_1 = (struct atom_firmware_info_v3_1 *)info;
0610         pp_atomfwctrl_copy_vbios_bootup_values_3_1(hwmgr,
0611                 boot_values, fwinfo_3_1);
0612     } else {
0613         pr_info("Fw info table revision does not match!");
0614         return -EINVAL;
0615     }
0616 
0617     return 0;
0618 }
0619 
0620 int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,
0621         struct pp_atomfwctrl_smc_dpm_parameters *param)
0622 {
0623     struct atom_smc_dpm_info_v4_1 *info;
0624     uint16_t ix;
0625 
0626     ix = GetIndexIntoMasterDataTable(smc_dpm_info);
0627     info = (struct atom_smc_dpm_info_v4_1 *)
0628         smu_atom_get_data_table(hwmgr->adev,
0629                 ix, NULL, NULL, NULL);
0630     if (!info) {
0631         pr_info("Error retrieving BIOS Table Address!");
0632         return -EINVAL;
0633     }
0634 
0635     param->liquid1_i2c_address = info->liquid1_i2c_address;
0636     param->liquid2_i2c_address = info->liquid2_i2c_address;
0637     param->vr_i2c_address = info->vr_i2c_address;
0638     param->plx_i2c_address = info->plx_i2c_address;
0639 
0640     param->liquid_i2c_linescl = info->liquid_i2c_linescl;
0641     param->liquid_i2c_linesda = info->liquid_i2c_linesda;
0642     param->vr_i2c_linescl = info->vr_i2c_linescl;
0643     param->vr_i2c_linesda = info->vr_i2c_linesda;
0644 
0645     param->plx_i2c_linescl = info->plx_i2c_linescl;
0646     param->plx_i2c_linesda = info->plx_i2c_linesda;
0647     param->vrsensorpresent = info->vrsensorpresent;
0648     param->liquidsensorpresent = info->liquidsensorpresent;
0649 
0650     param->maxvoltagestepgfx = info->maxvoltagestepgfx;
0651     param->maxvoltagestepsoc = info->maxvoltagestepsoc;
0652 
0653     param->vddgfxvrmapping = info->vddgfxvrmapping;
0654     param->vddsocvrmapping = info->vddsocvrmapping;
0655     param->vddmem0vrmapping = info->vddmem0vrmapping;
0656     param->vddmem1vrmapping = info->vddmem1vrmapping;
0657 
0658     param->gfxulvphasesheddingmask = info->gfxulvphasesheddingmask;
0659     param->soculvphasesheddingmask = info->soculvphasesheddingmask;
0660 
0661     param->gfxmaxcurrent = info->gfxmaxcurrent;
0662     param->gfxoffset = info->gfxoffset;
0663     param->padding_telemetrygfx = info->padding_telemetrygfx;
0664 
0665     param->socmaxcurrent = info->socmaxcurrent;
0666     param->socoffset = info->socoffset;
0667     param->padding_telemetrysoc = info->padding_telemetrysoc;
0668 
0669     param->mem0maxcurrent = info->mem0maxcurrent;
0670     param->mem0offset = info->mem0offset;
0671     param->padding_telemetrymem0 = info->padding_telemetrymem0;
0672 
0673     param->mem1maxcurrent = info->mem1maxcurrent;
0674     param->mem1offset = info->mem1offset;
0675     param->padding_telemetrymem1 = info->padding_telemetrymem1;
0676 
0677     param->acdcgpio = info->acdcgpio;
0678     param->acdcpolarity = info->acdcpolarity;
0679     param->vr0hotgpio = info->vr0hotgpio;
0680     param->vr0hotpolarity = info->vr0hotpolarity;
0681 
0682     param->vr1hotgpio = info->vr1hotgpio;
0683     param->vr1hotpolarity = info->vr1hotpolarity;
0684     param->padding1 = info->padding1;
0685     param->padding2 = info->padding2;
0686 
0687     param->ledpin0 = info->ledpin0;
0688     param->ledpin1 = info->ledpin1;
0689     param->ledpin2 = info->ledpin2;
0690 
0691     param->pllgfxclkspreadenabled = info->pllgfxclkspreadenabled;
0692     param->pllgfxclkspreadpercent = info->pllgfxclkspreadpercent;
0693     param->pllgfxclkspreadfreq = info->pllgfxclkspreadfreq;
0694 
0695     param->uclkspreadenabled = info->uclkspreadenabled;
0696     param->uclkspreadpercent = info->uclkspreadpercent;
0697     param->uclkspreadfreq = info->uclkspreadfreq;
0698 
0699     param->socclkspreadenabled = info->socclkspreadenabled;
0700     param->socclkspreadpercent = info->socclkspreadpercent;
0701     param->socclkspreadfreq = info->socclkspreadfreq;
0702 
0703     param->acggfxclkspreadenabled = info->acggfxclkspreadenabled;
0704     param->acggfxclkspreadpercent = info->acggfxclkspreadpercent;
0705     param->acggfxclkspreadfreq = info->acggfxclkspreadfreq;
0706 
0707     param->Vr2_I2C_address = info->Vr2_I2C_address;
0708 
0709     return 0;
0710 }