LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/pm/powerplay/hwmgr - process_pptables_v1_0.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 639 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 22 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2015 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  */
      23             : #include "pp_debug.h"
      24             : #include <linux/module.h>
      25             : #include <linux/slab.h>
      26             : 
      27             : #include "process_pptables_v1_0.h"
      28             : #include "ppatomctrl.h"
      29             : #include "atombios.h"
      30             : #include "hwmgr.h"
      31             : #include "cgs_common.h"
      32             : #include "pptable_v1_0.h"
      33             : 
      34             : /**
      35             :  * set_hw_cap - Private Function used during initialization.
      36             :  * @hwmgr: Pointer to the hardware manager.
      37             :  * @setIt: A flag indication if the capability should be set (TRUE) or reset (FALSE).
      38             :  * @cap: Which capability to set/reset.
      39             :  */
      40             : static void set_hw_cap(struct pp_hwmgr *hwmgr, bool setIt, enum phm_platform_caps cap)
      41             : {
      42           0 :         if (setIt)
      43           0 :                 phm_cap_set(hwmgr->platform_descriptor.platformCaps, cap);
      44             :         else
      45           0 :                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, cap);
      46             : }
      47             : 
      48             : 
      49             : /**
      50             :  * set_platform_caps - Private Function used during initialization.
      51             :  * @hwmgr: Pointer to the hardware manager.
      52             :  * @powerplay_caps: the bit array (from BIOS) of capability bits.
      53             :  * Exception:  the current implementation always returns 1.
      54             :  */
      55           0 : static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
      56             : {
      57           0 :         PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE16____),
      58             :                 "ATOM_PP_PLATFORM_CAP_ASPM_L1 is not supported!", continue);
      59           0 :         PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE64____),
      60             :                 "ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY is not supported!", continue);
      61           0 :         PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE512____),
      62             :                 "ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL is not supported!", continue);
      63           0 :         PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE1024____),
      64             :                 "ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 is not supported!", continue);
      65           0 :         PP_ASSERT_WITH_CODE((~powerplay_caps & ____RETIRE2048____),
      66             :                 "ATOM_PP_PLATFORM_CAP_HTLINKCONTROL is not supported!", continue);
      67             : 
      68           0 :         set_hw_cap(
      69             :                         hwmgr,
      70           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_POWERPLAY),
      71             :                         PHM_PlatformCaps_PowerPlaySupport
      72             :                   );
      73             : 
      74           0 :         set_hw_cap(
      75             :                         hwmgr,
      76           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_SBIOSPOWERSOURCE),
      77             :                         PHM_PlatformCaps_BiosPowerSourceControl
      78             :                   );
      79             : 
      80           0 :         set_hw_cap(
      81             :                         hwmgr,
      82           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_HARDWAREDC),
      83             :                         PHM_PlatformCaps_AutomaticDCTransition
      84             :                   );
      85             : 
      86           0 :         set_hw_cap(
      87             :                         hwmgr,
      88           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_MVDD_CONTROL),
      89             :                         PHM_PlatformCaps_EnableMVDDControl
      90             :                   );
      91             : 
      92           0 :         set_hw_cap(
      93             :                         hwmgr,
      94           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_VDDCI_CONTROL),
      95             :                         PHM_PlatformCaps_ControlVDDCI
      96             :                   );
      97             : 
      98           0 :         set_hw_cap(
      99             :                         hwmgr,
     100           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_VDDGFX_CONTROL),
     101             :                         PHM_PlatformCaps_ControlVDDGFX
     102             :                   );
     103             : 
     104           0 :         set_hw_cap(
     105             :                         hwmgr,
     106           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_BACO),
     107             :                         PHM_PlatformCaps_BACO
     108             :                   );
     109             : 
     110           0 :         set_hw_cap(
     111             :                         hwmgr,
     112           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_CAP_DISABLE_VOLTAGE_ISLAND),
     113             :                         PHM_PlatformCaps_DisableVoltageIsland
     114             :                   );
     115             : 
     116           0 :         set_hw_cap(
     117             :                         hwmgr,
     118           0 :                         0 != (powerplay_caps & ATOM_TONGA_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL),
     119             :                         PHM_PlatformCaps_CombinePCCWithThermalSignal
     120             :                   );
     121             : 
     122           0 :         set_hw_cap(
     123             :                         hwmgr,
     124           0 :                         0 != (powerplay_caps & ATOM_TONGA_PLATFORM_LOAD_POST_PRODUCTION_FIRMWARE),
     125             :                         PHM_PlatformCaps_LoadPostProductionFirmware
     126             :                   );
     127             : 
     128           0 :         return 0;
     129             : }
     130             : 
     131             : /*
     132             :  * Private Function to get the PowerPlay Table Address.
     133             :  */
     134           0 : static const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
     135             : {
     136           0 :         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
     137             : 
     138             :         u16 size;
     139             :         u8 frev, crev;
     140           0 :         void *table_address = (void *)hwmgr->soft_pp_table;
     141             : 
     142           0 :         if (!table_address) {
     143           0 :                 table_address = (ATOM_Tonga_POWERPLAYTABLE *)
     144           0 :                                 smu_atom_get_data_table(hwmgr->adev,
     145             :                                                 index, &size, &frev, &crev);
     146           0 :                 hwmgr->soft_pp_table = table_address;        /*Cache the result in RAM.*/
     147           0 :                 hwmgr->soft_pp_table_size = size;
     148             :         }
     149             : 
     150           0 :         return table_address;
     151             : }
     152             : 
     153           0 : static int get_vddc_lookup_table(
     154             :                 struct pp_hwmgr *hwmgr,
     155             :                 phm_ppt_v1_voltage_lookup_table **lookup_table,
     156             :                 const ATOM_Tonga_Voltage_Lookup_Table *vddc_lookup_pp_tables,
     157             :                 uint32_t max_levels
     158             :                 )
     159             : {
     160             :         uint32_t i;
     161             :         phm_ppt_v1_voltage_lookup_table *table;
     162             :         phm_ppt_v1_voltage_lookup_record *record;
     163             :         ATOM_Tonga_Voltage_Lookup_Record *atom_record;
     164             : 
     165           0 :         PP_ASSERT_WITH_CODE((0 != vddc_lookup_pp_tables->ucNumEntries),
     166             :                 "Invalid CAC Leakage PowerPlay Table!", return 1);
     167             : 
     168           0 :         table = kzalloc(struct_size(table, entries, max_levels), GFP_KERNEL);
     169           0 :         if (!table)
     170             :                 return -ENOMEM;
     171             : 
     172           0 :         table->count = vddc_lookup_pp_tables->ucNumEntries;
     173             : 
     174           0 :         for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++) {
     175           0 :                 record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     176             :                                         phm_ppt_v1_voltage_lookup_record,
     177             :                                         entries, table, i);
     178           0 :                 atom_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     179             :                                         ATOM_Tonga_Voltage_Lookup_Record,
     180             :                                         entries, vddc_lookup_pp_tables, i);
     181           0 :                 record->us_calculated = 0;
     182           0 :                 record->us_vdd = le16_to_cpu(atom_record->usVdd);
     183           0 :                 record->us_cac_low = le16_to_cpu(atom_record->usCACLow);
     184           0 :                 record->us_cac_mid = le16_to_cpu(atom_record->usCACMid);
     185           0 :                 record->us_cac_high = le16_to_cpu(atom_record->usCACHigh);
     186             :         }
     187             : 
     188           0 :         *lookup_table = table;
     189             : 
     190             :         return 0;
     191             : }
     192             : 
     193             : /**
     194             :  * get_platform_power_management_table - Private Function used during initialization.
     195             :  * Initialize Platform Power Management Parameter table
     196             :  * @hwmgr: Pointer to the hardware manager.
     197             :  * @atom_ppm_table: Pointer to PPM table in VBIOS
     198             :  */
     199           0 : static int get_platform_power_management_table(
     200             :                 struct pp_hwmgr *hwmgr,
     201             :                 ATOM_Tonga_PPM_Table *atom_ppm_table)
     202             : {
     203           0 :         struct phm_ppm_table *ptr = kzalloc(sizeof(ATOM_Tonga_PPM_Table), GFP_KERNEL);
     204           0 :         struct phm_ppt_v1_information *pp_table_information =
     205             :                 (struct phm_ppt_v1_information *)(hwmgr->pptable);
     206             : 
     207           0 :         if (NULL == ptr)
     208             :                 return -ENOMEM;
     209             : 
     210             :         ptr->ppm_design
     211           0 :                 = atom_ppm_table->ucPpmDesign;
     212             :         ptr->cpu_core_number
     213           0 :                 = le16_to_cpu(atom_ppm_table->usCpuCoreNumber);
     214             :         ptr->platform_tdp
     215           0 :                 = le32_to_cpu(atom_ppm_table->ulPlatformTDP);
     216             :         ptr->small_ac_platform_tdp
     217           0 :                 = le32_to_cpu(atom_ppm_table->ulSmallACPlatformTDP);
     218             :         ptr->platform_tdc
     219           0 :                 = le32_to_cpu(atom_ppm_table->ulPlatformTDC);
     220             :         ptr->small_ac_platform_tdc
     221           0 :                 = le32_to_cpu(atom_ppm_table->ulSmallACPlatformTDC);
     222             :         ptr->apu_tdp
     223           0 :                 = le32_to_cpu(atom_ppm_table->ulApuTDP);
     224             :         ptr->dgpu_tdp
     225           0 :                 = le32_to_cpu(atom_ppm_table->ulDGpuTDP);
     226             :         ptr->dgpu_ulv_power
     227           0 :                 = le32_to_cpu(atom_ppm_table->ulDGpuUlvPower);
     228             :         ptr->tj_max
     229           0 :                 = le32_to_cpu(atom_ppm_table->ulTjmax);
     230             : 
     231           0 :         pp_table_information->ppm_parameter_table = ptr;
     232             : 
     233             :         return 0;
     234             : }
     235             : 
     236             : /**
     237             :  * init_dpm_2_parameters - Private Function used during initialization.
     238             :  * Initialize TDP limits for DPM2
     239             :  * @hwmgr: Pointer to the hardware manager.
     240             :  * @powerplay_table: Pointer to the PowerPlay Table.
     241             :  */
     242           0 : static int init_dpm_2_parameters(
     243             :                 struct pp_hwmgr *hwmgr,
     244             :                 const ATOM_Tonga_POWERPLAYTABLE *powerplay_table
     245             :                 )
     246             : {
     247           0 :         int result = 0;
     248           0 :         struct phm_ppt_v1_information *pp_table_information = (struct phm_ppt_v1_information *)(hwmgr->pptable);
     249             :         ATOM_Tonga_PPM_Table *atom_ppm_table;
     250           0 :         uint32_t disable_ppm = 0;
     251           0 :         uint32_t disable_power_control = 0;
     252             : 
     253           0 :         pp_table_information->us_ulv_voltage_offset =
     254           0 :                 le16_to_cpu(powerplay_table->usUlvVoltageOffset);
     255             : 
     256           0 :         pp_table_information->ppm_parameter_table = NULL;
     257           0 :         pp_table_information->vddc_lookup_table = NULL;
     258           0 :         pp_table_information->vddgfx_lookup_table = NULL;
     259             :         /* TDP limits */
     260           0 :         hwmgr->platform_descriptor.TDPODLimit =
     261           0 :                 le16_to_cpu(powerplay_table->usPowerControlLimit);
     262           0 :         hwmgr->platform_descriptor.TDPAdjustment = 0;
     263           0 :         hwmgr->platform_descriptor.VidAdjustment = 0;
     264           0 :         hwmgr->platform_descriptor.VidAdjustmentPolarity = 0;
     265           0 :         hwmgr->platform_descriptor.VidMinLimit = 0;
     266           0 :         hwmgr->platform_descriptor.VidMaxLimit = 1500000;
     267           0 :         hwmgr->platform_descriptor.VidStep = 6250;
     268             : 
     269           0 :         disable_power_control = 0;
     270             :         if (0 == disable_power_control) {
     271             :                 /* enable TDP overdrive (PowerControl) feature as well if supported */
     272           0 :                 if (hwmgr->platform_descriptor.TDPODLimit != 0)
     273           0 :                         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
     274             :                         PHM_PlatformCaps_PowerControl);
     275             :         }
     276             : 
     277           0 :         if (0 != powerplay_table->usVddcLookupTableOffset) {
     278           0 :                 const ATOM_Tonga_Voltage_Lookup_Table *pVddcCACTable =
     279           0 :                         (ATOM_Tonga_Voltage_Lookup_Table *)(((unsigned long)powerplay_table) +
     280           0 :                         le16_to_cpu(powerplay_table->usVddcLookupTableOffset));
     281             : 
     282           0 :                 result = get_vddc_lookup_table(hwmgr,
     283           0 :                         &pp_table_information->vddc_lookup_table, pVddcCACTable, 16);
     284             :         }
     285             : 
     286           0 :         if (0 != powerplay_table->usVddgfxLookupTableOffset) {
     287           0 :                 const ATOM_Tonga_Voltage_Lookup_Table *pVddgfxCACTable =
     288           0 :                         (ATOM_Tonga_Voltage_Lookup_Table *)(((unsigned long)powerplay_table) +
     289           0 :                         le16_to_cpu(powerplay_table->usVddgfxLookupTableOffset));
     290             : 
     291           0 :                 result = get_vddc_lookup_table(hwmgr,
     292           0 :                         &pp_table_information->vddgfx_lookup_table, pVddgfxCACTable, 16);
     293             :         }
     294             : 
     295           0 :         disable_ppm = 0;
     296             :         if (0 == disable_ppm) {
     297           0 :                 atom_ppm_table = (ATOM_Tonga_PPM_Table *)
     298           0 :                         (((unsigned long)powerplay_table) + le16_to_cpu(powerplay_table->usPPMTableOffset));
     299             : 
     300           0 :                 if (0 != powerplay_table->usPPMTableOffset) {
     301           0 :                         if (get_platform_power_management_table(hwmgr, atom_ppm_table) == 0) {
     302           0 :                                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
     303             :                                         PHM_PlatformCaps_EnablePlatformPowerManagement);
     304             :                         }
     305             :                 }
     306             :         }
     307             : 
     308           0 :         return result;
     309             : }
     310             : 
     311           0 : static int get_valid_clk(
     312             :                 struct pp_hwmgr *hwmgr,
     313             :                 struct phm_clock_array **clk_table,
     314             :                 phm_ppt_v1_clock_voltage_dependency_table const *clk_volt_pp_table
     315             :                 )
     316             : {
     317             :         uint32_t i;
     318             :         struct phm_clock_array *table;
     319             :         phm_ppt_v1_clock_voltage_dependency_record *dep_record;
     320             : 
     321           0 :         PP_ASSERT_WITH_CODE((0 != clk_volt_pp_table->count),
     322             :                 "Invalid PowerPlay Table!", return -1);
     323             : 
     324           0 :         table = kzalloc(struct_size(table, values, clk_volt_pp_table->count),
     325             :                         GFP_KERNEL);
     326           0 :         if (!table)
     327             :                 return -ENOMEM;
     328             : 
     329           0 :         table->count = (uint32_t)clk_volt_pp_table->count;
     330             : 
     331           0 :         for (i = 0; i < table->count; i++) {
     332           0 :                 dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     333             :                                 phm_ppt_v1_clock_voltage_dependency_record,
     334             :                                 entries, clk_volt_pp_table, i);
     335           0 :                 table->values[i] = (uint32_t)dep_record->clk;
     336             :         }
     337           0 :         *clk_table = table;
     338             : 
     339             :         return 0;
     340             : }
     341             : 
     342           0 : static int get_hard_limits(
     343             :                 struct pp_hwmgr *hwmgr,
     344             :                 struct phm_clock_and_voltage_limits *limits,
     345             :                 ATOM_Tonga_Hard_Limit_Table const *limitable
     346             :                 )
     347             : {
     348           0 :         PP_ASSERT_WITH_CODE((0 != limitable->ucNumEntries), "Invalid PowerPlay Table!", return -1);
     349             : 
     350             :         /* currently we always take entries[0] parameters */
     351           0 :         limits->sclk = le32_to_cpu(limitable->entries[0].ulSCLKLimit);
     352           0 :         limits->mclk = le32_to_cpu(limitable->entries[0].ulMCLKLimit);
     353           0 :         limits->vddc = le16_to_cpu(limitable->entries[0].usVddcLimit);
     354           0 :         limits->vddci = le16_to_cpu(limitable->entries[0].usVddciLimit);
     355           0 :         limits->vddgfx = le16_to_cpu(limitable->entries[0].usVddgfxLimit);
     356             : 
     357             :         return 0;
     358             : }
     359             : 
     360           0 : static int get_mclk_voltage_dependency_table(
     361             :                 struct pp_hwmgr *hwmgr,
     362             :                 phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_mclk_dep_table,
     363             :                 ATOM_Tonga_MCLK_Dependency_Table const *mclk_dep_table
     364             :                 )
     365             : {
     366             :         uint32_t i;
     367             :         phm_ppt_v1_clock_voltage_dependency_table *mclk_table;
     368             :         phm_ppt_v1_clock_voltage_dependency_record *mclk_table_record;
     369             :         ATOM_Tonga_MCLK_Dependency_Record *mclk_dep_record;
     370             : 
     371           0 :         PP_ASSERT_WITH_CODE((0 != mclk_dep_table->ucNumEntries),
     372             :                 "Invalid PowerPlay Table!", return -1);
     373             : 
     374           0 :         mclk_table = kzalloc(struct_size(mclk_table, entries, mclk_dep_table->ucNumEntries),
     375             :                              GFP_KERNEL);
     376           0 :         if (!mclk_table)
     377             :                 return -ENOMEM;
     378             : 
     379           0 :         mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries;
     380             : 
     381           0 :         for (i = 0; i < mclk_dep_table->ucNumEntries; i++) {
     382           0 :                 mclk_table_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     383             :                                         phm_ppt_v1_clock_voltage_dependency_record,
     384             :                                                 entries, mclk_table, i);
     385           0 :                 mclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     386             :                                         ATOM_Tonga_MCLK_Dependency_Record,
     387             :                                                 entries, mclk_dep_table, i);
     388           0 :                 mclk_table_record->vddInd = mclk_dep_record->ucVddcInd;
     389           0 :                 mclk_table_record->vdd_offset = le16_to_cpu(mclk_dep_record->usVddgfxOffset);
     390           0 :                 mclk_table_record->vddci = le16_to_cpu(mclk_dep_record->usVddci);
     391           0 :                 mclk_table_record->mvdd = le16_to_cpu(mclk_dep_record->usMvdd);
     392           0 :                 mclk_table_record->clk = le32_to_cpu(mclk_dep_record->ulMclk);
     393             :         }
     394             : 
     395           0 :         *pp_tonga_mclk_dep_table = mclk_table;
     396             : 
     397             :         return 0;
     398             : }
     399             : 
     400           0 : static int get_sclk_voltage_dependency_table(
     401             :                 struct pp_hwmgr *hwmgr,
     402             :                 phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table,
     403             :                 PPTable_Generic_SubTable_Header const  *sclk_dep_table
     404             :                 )
     405             : {
     406             :         uint32_t i;
     407             :         phm_ppt_v1_clock_voltage_dependency_table *sclk_table;
     408             :         phm_ppt_v1_clock_voltage_dependency_record *sclk_table_record;
     409             : 
     410           0 :         if (sclk_dep_table->ucRevId < 1) {
     411           0 :                 const ATOM_Tonga_SCLK_Dependency_Table *tonga_table =
     412             :                             (ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table;
     413             :                 ATOM_Tonga_SCLK_Dependency_Record *sclk_dep_record;
     414             : 
     415           0 :                 PP_ASSERT_WITH_CODE((0 != tonga_table->ucNumEntries),
     416             :                         "Invalid PowerPlay Table!", return -1);
     417             : 
     418           0 :                 sclk_table = kzalloc(struct_size(sclk_table, entries, tonga_table->ucNumEntries),
     419             :                                      GFP_KERNEL);
     420           0 :                 if (!sclk_table)
     421             :                         return -ENOMEM;
     422             : 
     423           0 :                 sclk_table->count = (uint32_t)tonga_table->ucNumEntries;
     424             : 
     425           0 :                 for (i = 0; i < tonga_table->ucNumEntries; i++) {
     426           0 :                         sclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     427             :                                                 ATOM_Tonga_SCLK_Dependency_Record,
     428             :                                                 entries, tonga_table, i);
     429           0 :                         sclk_table_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     430             :                                                 phm_ppt_v1_clock_voltage_dependency_record,
     431             :                                                 entries, sclk_table, i);
     432           0 :                         sclk_table_record->vddInd = sclk_dep_record->ucVddInd;
     433           0 :                         sclk_table_record->vdd_offset = le16_to_cpu(sclk_dep_record->usVddcOffset);
     434           0 :                         sclk_table_record->clk = le32_to_cpu(sclk_dep_record->ulSclk);
     435           0 :                         sclk_table_record->cks_enable =
     436           0 :                                 (((sclk_dep_record->ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0;
     437           0 :                         sclk_table_record->cks_voffset = (sclk_dep_record->ucCKSVOffsetandDisable & 0x7F);
     438             :                 }
     439             :         } else {
     440           0 :                 const ATOM_Polaris_SCLK_Dependency_Table *polaris_table =
     441             :                             (ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table;
     442             :                 ATOM_Polaris_SCLK_Dependency_Record *sclk_dep_record;
     443             : 
     444           0 :                 PP_ASSERT_WITH_CODE((0 != polaris_table->ucNumEntries),
     445             :                         "Invalid PowerPlay Table!", return -1);
     446             : 
     447           0 :                 sclk_table = kzalloc(struct_size(sclk_table, entries, polaris_table->ucNumEntries),
     448             :                                      GFP_KERNEL);
     449           0 :                 if (!sclk_table)
     450             :                         return -ENOMEM;
     451             : 
     452           0 :                 sclk_table->count = (uint32_t)polaris_table->ucNumEntries;
     453             : 
     454           0 :                 for (i = 0; i < polaris_table->ucNumEntries; i++) {
     455           0 :                         sclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     456             :                                                 ATOM_Polaris_SCLK_Dependency_Record,
     457             :                                                 entries, polaris_table, i);
     458           0 :                         sclk_table_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     459             :                                                 phm_ppt_v1_clock_voltage_dependency_record,
     460             :                                                 entries, sclk_table, i);
     461           0 :                         sclk_table_record->vddInd = sclk_dep_record->ucVddInd;
     462           0 :                         sclk_table_record->vdd_offset = le16_to_cpu(sclk_dep_record->usVddcOffset);
     463           0 :                         sclk_table_record->clk = le32_to_cpu(sclk_dep_record->ulSclk);
     464           0 :                         sclk_table_record->cks_enable =
     465           0 :                                 (((sclk_dep_record->ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0;
     466           0 :                         sclk_table_record->cks_voffset = (sclk_dep_record->ucCKSVOffsetandDisable & 0x7F);
     467           0 :                         sclk_table_record->sclk_offset = le32_to_cpu(sclk_dep_record->ulSclkOffset);
     468             :                 }
     469             :         }
     470           0 :         *pp_tonga_sclk_dep_table = sclk_table;
     471             : 
     472             :         return 0;
     473             : }
     474             : 
     475           0 : static int get_pcie_table(
     476             :                 struct pp_hwmgr *hwmgr,
     477             :                 phm_ppt_v1_pcie_table **pp_tonga_pcie_table,
     478             :                 PPTable_Generic_SubTable_Header const *ptable
     479             :                 )
     480             : {
     481             :         uint32_t i, pcie_count;
     482             :         phm_ppt_v1_pcie_table *pcie_table;
     483           0 :         struct phm_ppt_v1_information *pp_table_information =
     484             :                 (struct phm_ppt_v1_information *)(hwmgr->pptable);
     485             :         phm_ppt_v1_pcie_record *pcie_record;
     486             : 
     487           0 :         if (ptable->ucRevId < 1) {
     488           0 :                 const ATOM_Tonga_PCIE_Table *atom_pcie_table = (ATOM_Tonga_PCIE_Table *)ptable;
     489             :                 ATOM_Tonga_PCIE_Record *atom_pcie_record;
     490             : 
     491           0 :                 PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0),
     492             :                         "Invalid PowerPlay Table!", return -1);
     493             : 
     494           0 :                 pcie_table = kzalloc(struct_size(pcie_table, entries,
     495             :                                                  atom_pcie_table->ucNumEntries),
     496             :                                      GFP_KERNEL);
     497           0 :                 if (!pcie_table)
     498             :                         return -ENOMEM;
     499             : 
     500             :                 /*
     501             :                 * Make sure the number of pcie entries are less than or equal to sclk dpm levels.
     502             :                 * Since first PCIE entry is for ULV, #pcie has to be <= SclkLevel + 1.
     503             :                 */
     504           0 :                 pcie_count = (pp_table_information->vdd_dep_on_sclk->count) + 1;
     505           0 :                 if ((uint32_t)atom_pcie_table->ucNumEntries <= pcie_count)
     506             :                         pcie_count = (uint32_t)atom_pcie_table->ucNumEntries;
     507             :                 else
     508           0 :                         pr_err("Number of Pcie Entries exceed the number of SCLK Dpm Levels! Disregarding the excess entries...\n");
     509             : 
     510           0 :                 pcie_table->count = pcie_count;
     511           0 :                 for (i = 0; i < pcie_count; i++) {
     512           0 :                         pcie_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     513             :                                                 phm_ppt_v1_pcie_record,
     514             :                                                 entries, pcie_table, i);
     515           0 :                         atom_pcie_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     516             :                                                 ATOM_Tonga_PCIE_Record,
     517             :                                                 entries, atom_pcie_table, i);
     518           0 :                         pcie_record->gen_speed = atom_pcie_record->ucPCIEGenSpeed;
     519           0 :                         pcie_record->lane_width = le16_to_cpu(atom_pcie_record->usPCIELaneWidth);
     520             :                 }
     521             : 
     522           0 :                 *pp_tonga_pcie_table = pcie_table;
     523             :         } else {
     524             :                 /* Polaris10/Polaris11 and newer. */
     525           0 :                 const ATOM_Polaris10_PCIE_Table *atom_pcie_table = (ATOM_Polaris10_PCIE_Table *)ptable;
     526             :                 ATOM_Polaris10_PCIE_Record *atom_pcie_record;
     527             : 
     528           0 :                 PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0),
     529             :                         "Invalid PowerPlay Table!", return -1);
     530             : 
     531           0 :                 pcie_table = kzalloc(struct_size(pcie_table, entries,
     532             :                                                  atom_pcie_table->ucNumEntries),
     533             :                                      GFP_KERNEL);
     534           0 :                 if (!pcie_table)
     535             :                         return -ENOMEM;
     536             : 
     537             :                 /*
     538             :                 * Make sure the number of pcie entries are less than or equal to sclk dpm levels.
     539             :                 * Since first PCIE entry is for ULV, #pcie has to be <= SclkLevel + 1.
     540             :                 */
     541           0 :                 pcie_count = (pp_table_information->vdd_dep_on_sclk->count) + 1;
     542           0 :                 if ((uint32_t)atom_pcie_table->ucNumEntries <= pcie_count)
     543             :                         pcie_count = (uint32_t)atom_pcie_table->ucNumEntries;
     544             :                 else
     545           0 :                         pr_err("Number of Pcie Entries exceed the number of SCLK Dpm Levels! Disregarding the excess entries...\n");
     546             : 
     547           0 :                 pcie_table->count = pcie_count;
     548             : 
     549           0 :                 for (i = 0; i < pcie_count; i++) {
     550           0 :                         pcie_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     551             :                                                 phm_ppt_v1_pcie_record,
     552             :                                                 entries, pcie_table, i);
     553           0 :                         atom_pcie_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     554             :                                                 ATOM_Polaris10_PCIE_Record,
     555             :                                                 entries, atom_pcie_table, i);
     556           0 :                         pcie_record->gen_speed = atom_pcie_record->ucPCIEGenSpeed;
     557           0 :                         pcie_record->lane_width = le16_to_cpu(atom_pcie_record->usPCIELaneWidth);
     558           0 :                         pcie_record->pcie_sclk = le32_to_cpu(atom_pcie_record->ulPCIE_Sclk);
     559             :                 }
     560             : 
     561           0 :                 *pp_tonga_pcie_table = pcie_table;
     562             :         }
     563             : 
     564             :         return 0;
     565             : }
     566             : 
     567           0 : static int get_cac_tdp_table(
     568             :                 struct pp_hwmgr *hwmgr,
     569             :                 struct phm_cac_tdp_table **cac_tdp_table,
     570             :                 const PPTable_Generic_SubTable_Header * table
     571             :                 )
     572             : {
     573             :         uint32_t table_size;
     574             :         struct phm_cac_tdp_table *tdp_table;
     575             : 
     576           0 :         table_size = sizeof(uint32_t) + sizeof(struct phm_cac_tdp_table);
     577           0 :         tdp_table = kzalloc(table_size, GFP_KERNEL);
     578             : 
     579           0 :         if (NULL == tdp_table)
     580             :                 return -ENOMEM;
     581             : 
     582           0 :         hwmgr->dyn_state.cac_dtp_table = kzalloc(table_size, GFP_KERNEL);
     583             : 
     584           0 :         if (NULL == hwmgr->dyn_state.cac_dtp_table) {
     585           0 :                 kfree(tdp_table);
     586             :                 return -ENOMEM;
     587             :         }
     588             : 
     589           0 :         if (table->ucRevId < 3) {
     590           0 :                 const ATOM_Tonga_PowerTune_Table *tonga_table =
     591             :                         (ATOM_Tonga_PowerTune_Table *)table;
     592           0 :                 tdp_table->usTDP = le16_to_cpu(tonga_table->usTDP);
     593           0 :                 tdp_table->usConfigurableTDP =
     594           0 :                         le16_to_cpu(tonga_table->usConfigurableTDP);
     595           0 :                 tdp_table->usTDC = le16_to_cpu(tonga_table->usTDC);
     596           0 :                 tdp_table->usBatteryPowerLimit =
     597           0 :                         le16_to_cpu(tonga_table->usBatteryPowerLimit);
     598           0 :                 tdp_table->usSmallPowerLimit =
     599           0 :                         le16_to_cpu(tonga_table->usSmallPowerLimit);
     600           0 :                 tdp_table->usLowCACLeakage =
     601           0 :                         le16_to_cpu(tonga_table->usLowCACLeakage);
     602           0 :                 tdp_table->usHighCACLeakage =
     603           0 :                         le16_to_cpu(tonga_table->usHighCACLeakage);
     604           0 :                 tdp_table->usMaximumPowerDeliveryLimit =
     605           0 :                         le16_to_cpu(tonga_table->usMaximumPowerDeliveryLimit);
     606           0 :                 tdp_table->usDefaultTargetOperatingTemp =
     607           0 :                         le16_to_cpu(tonga_table->usTjMax);
     608           0 :                 tdp_table->usTargetOperatingTemp =
     609             :                         le16_to_cpu(tonga_table->usTjMax); /*Set the initial temp to the same as default */
     610           0 :                 tdp_table->usPowerTuneDataSetID =
     611           0 :                         le16_to_cpu(tonga_table->usPowerTuneDataSetID);
     612           0 :                 tdp_table->usSoftwareShutdownTemp =
     613           0 :                         le16_to_cpu(tonga_table->usSoftwareShutdownTemp);
     614           0 :                 tdp_table->usClockStretchAmount =
     615           0 :                         le16_to_cpu(tonga_table->usClockStretchAmount);
     616           0 :         } else if (table->ucRevId < 4) {   /* Fiji and newer */
     617           0 :                 const ATOM_Fiji_PowerTune_Table *fijitable =
     618             :                         (ATOM_Fiji_PowerTune_Table *)table;
     619           0 :                 tdp_table->usTDP = le16_to_cpu(fijitable->usTDP);
     620           0 :                 tdp_table->usConfigurableTDP = le16_to_cpu(fijitable->usConfigurableTDP);
     621           0 :                 tdp_table->usTDC = le16_to_cpu(fijitable->usTDC);
     622           0 :                 tdp_table->usBatteryPowerLimit = le16_to_cpu(fijitable->usBatteryPowerLimit);
     623           0 :                 tdp_table->usSmallPowerLimit = le16_to_cpu(fijitable->usSmallPowerLimit);
     624           0 :                 tdp_table->usLowCACLeakage = le16_to_cpu(fijitable->usLowCACLeakage);
     625           0 :                 tdp_table->usHighCACLeakage = le16_to_cpu(fijitable->usHighCACLeakage);
     626           0 :                 tdp_table->usMaximumPowerDeliveryLimit =
     627           0 :                         le16_to_cpu(fijitable->usMaximumPowerDeliveryLimit);
     628           0 :                 tdp_table->usDefaultTargetOperatingTemp =
     629           0 :                         le16_to_cpu(fijitable->usTjMax);
     630           0 :                 tdp_table->usTargetOperatingTemp =
     631             :                         le16_to_cpu(fijitable->usTjMax); /*Set the initial temp to the same as default */
     632           0 :                 tdp_table->usPowerTuneDataSetID =
     633           0 :                         le16_to_cpu(fijitable->usPowerTuneDataSetID);
     634           0 :                 tdp_table->usSoftwareShutdownTemp =
     635           0 :                         le16_to_cpu(fijitable->usSoftwareShutdownTemp);
     636           0 :                 tdp_table->usClockStretchAmount =
     637           0 :                         le16_to_cpu(fijitable->usClockStretchAmount);
     638           0 :                 tdp_table->usTemperatureLimitHotspot =
     639           0 :                         le16_to_cpu(fijitable->usTemperatureLimitHotspot);
     640           0 :                 tdp_table->usTemperatureLimitLiquid1 =
     641           0 :                         le16_to_cpu(fijitable->usTemperatureLimitLiquid1);
     642           0 :                 tdp_table->usTemperatureLimitLiquid2 =
     643           0 :                         le16_to_cpu(fijitable->usTemperatureLimitLiquid2);
     644           0 :                 tdp_table->usTemperatureLimitVrVddc =
     645           0 :                         le16_to_cpu(fijitable->usTemperatureLimitVrVddc);
     646           0 :                 tdp_table->usTemperatureLimitVrMvdd =
     647           0 :                         le16_to_cpu(fijitable->usTemperatureLimitVrMvdd);
     648           0 :                 tdp_table->usTemperatureLimitPlx =
     649           0 :                         le16_to_cpu(fijitable->usTemperatureLimitPlx);
     650           0 :                 tdp_table->ucLiquid1_I2C_address =
     651           0 :                         fijitable->ucLiquid1_I2C_address;
     652           0 :                 tdp_table->ucLiquid2_I2C_address =
     653           0 :                         fijitable->ucLiquid2_I2C_address;
     654           0 :                 tdp_table->ucLiquid_I2C_Line =
     655           0 :                         fijitable->ucLiquid_I2C_Line;
     656           0 :                 tdp_table->ucVr_I2C_address = fijitable->ucVr_I2C_address;
     657           0 :                 tdp_table->ucVr_I2C_Line = fijitable->ucVr_I2C_Line;
     658           0 :                 tdp_table->ucPlx_I2C_address = fijitable->ucPlx_I2C_address;
     659           0 :                 tdp_table->ucPlx_I2C_Line = fijitable->ucPlx_I2C_Line;
     660             :         } else {
     661           0 :                 const ATOM_Polaris_PowerTune_Table *polaristable =
     662             :                         (ATOM_Polaris_PowerTune_Table *)table;
     663           0 :                 tdp_table->usTDP = le16_to_cpu(polaristable->usTDP);
     664           0 :                 tdp_table->usConfigurableTDP = le16_to_cpu(polaristable->usConfigurableTDP);
     665           0 :                 tdp_table->usTDC = le16_to_cpu(polaristable->usTDC);
     666           0 :                 tdp_table->usBatteryPowerLimit = le16_to_cpu(polaristable->usBatteryPowerLimit);
     667           0 :                 tdp_table->usSmallPowerLimit = le16_to_cpu(polaristable->usSmallPowerLimit);
     668           0 :                 tdp_table->usLowCACLeakage = le16_to_cpu(polaristable->usLowCACLeakage);
     669           0 :                 tdp_table->usHighCACLeakage = le16_to_cpu(polaristable->usHighCACLeakage);
     670           0 :                 tdp_table->usMaximumPowerDeliveryLimit =
     671           0 :                         le16_to_cpu(polaristable->usMaximumPowerDeliveryLimit);
     672           0 :                 tdp_table->usDefaultTargetOperatingTemp =
     673           0 :                         le16_to_cpu(polaristable->usTjMax);
     674           0 :                 tdp_table->usTargetOperatingTemp =
     675             :                         le16_to_cpu(polaristable->usTjMax); /*Set the initial temp to the same as default */
     676           0 :                 tdp_table->usPowerTuneDataSetID =
     677           0 :                         le16_to_cpu(polaristable->usPowerTuneDataSetID);
     678           0 :                 tdp_table->usSoftwareShutdownTemp =
     679           0 :                         le16_to_cpu(polaristable->usSoftwareShutdownTemp);
     680           0 :                 tdp_table->usClockStretchAmount =
     681           0 :                         le16_to_cpu(polaristable->usClockStretchAmount);
     682           0 :                 tdp_table->usTemperatureLimitHotspot =
     683           0 :                         le16_to_cpu(polaristable->usTemperatureLimitHotspot);
     684           0 :                 tdp_table->usTemperatureLimitLiquid1 =
     685           0 :                         le16_to_cpu(polaristable->usTemperatureLimitLiquid1);
     686           0 :                 tdp_table->usTemperatureLimitLiquid2 =
     687           0 :                         le16_to_cpu(polaristable->usTemperatureLimitLiquid2);
     688           0 :                 tdp_table->usTemperatureLimitVrVddc =
     689           0 :                         le16_to_cpu(polaristable->usTemperatureLimitVrVddc);
     690           0 :                 tdp_table->usTemperatureLimitVrMvdd =
     691           0 :                         le16_to_cpu(polaristable->usTemperatureLimitVrMvdd);
     692           0 :                 tdp_table->usTemperatureLimitPlx =
     693           0 :                         le16_to_cpu(polaristable->usTemperatureLimitPlx);
     694           0 :                 tdp_table->ucLiquid1_I2C_address =
     695           0 :                         polaristable->ucLiquid1_I2C_address;
     696           0 :                 tdp_table->ucLiquid2_I2C_address =
     697           0 :                         polaristable->ucLiquid2_I2C_address;
     698           0 :                 tdp_table->ucLiquid_I2C_Line =
     699           0 :                         polaristable->ucLiquid_I2C_Line;
     700           0 :                 tdp_table->ucVr_I2C_address = polaristable->ucVr_I2C_address;
     701           0 :                 tdp_table->ucVr_I2C_Line = polaristable->ucVr_I2C_Line;
     702           0 :                 tdp_table->ucPlx_I2C_address = polaristable->ucPlx_I2C_address;
     703           0 :                 tdp_table->ucPlx_I2C_Line = polaristable->ucPlx_I2C_Line;
     704           0 :                 tdp_table->usBoostPowerLimit = polaristable->usBoostPowerLimit;
     705           0 :                 tdp_table->ucCKS_LDO_REFSEL = polaristable->ucCKS_LDO_REFSEL;
     706           0 :                 tdp_table->ucHotSpotOnly = polaristable->ucHotSpotOnly;
     707             :         }
     708             : 
     709           0 :         *cac_tdp_table = tdp_table;
     710             : 
     711             :         return 0;
     712             : }
     713             : 
     714           0 : static int get_mm_clock_voltage_table(
     715             :                 struct pp_hwmgr *hwmgr,
     716             :                 phm_ppt_v1_mm_clock_voltage_dependency_table **tonga_mm_table,
     717             :                 const ATOM_Tonga_MM_Dependency_Table * mm_dependency_table
     718             :                 )
     719             : {
     720             :         uint32_t i;
     721             :         const ATOM_Tonga_MM_Dependency_Record *mm_dependency_record;
     722             :         phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table;
     723             :         phm_ppt_v1_mm_clock_voltage_dependency_record *mm_table_record;
     724             : 
     725           0 :         PP_ASSERT_WITH_CODE((0 != mm_dependency_table->ucNumEntries),
     726             :                 "Invalid PowerPlay Table!", return -1);
     727           0 :         mm_table = kzalloc(struct_size(mm_table, entries, mm_dependency_table->ucNumEntries),
     728             :                            GFP_KERNEL);
     729           0 :         if (!mm_table)
     730             :                 return -ENOMEM;
     731             : 
     732           0 :         mm_table->count = mm_dependency_table->ucNumEntries;
     733             : 
     734           0 :         for (i = 0; i < mm_dependency_table->ucNumEntries; i++) {
     735           0 :                 mm_dependency_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     736             :                                                 ATOM_Tonga_MM_Dependency_Record,
     737             :                                                 entries, mm_dependency_table, i);
     738           0 :                 mm_table_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
     739             :                                         phm_ppt_v1_mm_clock_voltage_dependency_record,
     740             :                                         entries, mm_table, i);
     741           0 :                 mm_table_record->vddcInd = mm_dependency_record->ucVddcInd;
     742           0 :                 mm_table_record->vddgfx_offset = le16_to_cpu(mm_dependency_record->usVddgfxOffset);
     743           0 :                 mm_table_record->aclk = le32_to_cpu(mm_dependency_record->ulAClk);
     744           0 :                 mm_table_record->samclock = le32_to_cpu(mm_dependency_record->ulSAMUClk);
     745           0 :                 mm_table_record->eclk = le32_to_cpu(mm_dependency_record->ulEClk);
     746           0 :                 mm_table_record->vclk = le32_to_cpu(mm_dependency_record->ulVClk);
     747           0 :                 mm_table_record->dclk = le32_to_cpu(mm_dependency_record->ulDClk);
     748             :         }
     749             : 
     750           0 :         *tonga_mm_table = mm_table;
     751             : 
     752             :         return 0;
     753             : }
     754             : 
     755           0 : static int get_gpio_table(struct pp_hwmgr *hwmgr,
     756             :                 struct phm_ppt_v1_gpio_table **pp_tonga_gpio_table,
     757             :                 const ATOM_Tonga_GPIO_Table *atom_gpio_table)
     758             : {
     759             :         uint32_t table_size;
     760             :         struct phm_ppt_v1_gpio_table *pp_gpio_table;
     761           0 :         struct phm_ppt_v1_information *pp_table_information =
     762             :                         (struct phm_ppt_v1_information *)(hwmgr->pptable);
     763             : 
     764           0 :         table_size = sizeof(struct phm_ppt_v1_gpio_table);
     765           0 :         pp_gpio_table = kzalloc(table_size, GFP_KERNEL);
     766           0 :         if (!pp_gpio_table)
     767             :                 return -ENOMEM;
     768             : 
     769           0 :         if (pp_table_information->vdd_dep_on_sclk->count <
     770           0 :                         atom_gpio_table->ucVRHotTriggeredSclkDpmIndex)
     771           0 :                 PP_ASSERT_WITH_CODE(false,
     772             :                                 "SCLK DPM index for VRHot cannot exceed the total sclk level count!",);
     773             :         else
     774           0 :                 pp_gpio_table->vrhot_triggered_sclk_dpm_index =
     775             :                                 atom_gpio_table->ucVRHotTriggeredSclkDpmIndex;
     776             : 
     777           0 :         *pp_tonga_gpio_table = pp_gpio_table;
     778             : 
     779             :         return 0;
     780             : }
     781             : /**
     782             :  * init_clock_voltage_dependency - Private Function used during initialization.
     783             :  * Initialize clock voltage dependency
     784             :  * @hwmgr: Pointer to the hardware manager.
     785             :  * @powerplay_table: Pointer to the PowerPlay Table.
     786             :  */
     787           0 : static int init_clock_voltage_dependency(
     788             :                 struct pp_hwmgr *hwmgr,
     789             :                 const ATOM_Tonga_POWERPLAYTABLE *powerplay_table
     790             :                 )
     791             : {
     792           0 :         int result = 0;
     793           0 :         struct phm_ppt_v1_information *pp_table_information =
     794             :                 (struct phm_ppt_v1_information *)(hwmgr->pptable);
     795             : 
     796           0 :         const ATOM_Tonga_MM_Dependency_Table *mm_dependency_table =
     797           0 :                 (const ATOM_Tonga_MM_Dependency_Table *)(((unsigned long) powerplay_table) +
     798           0 :                 le16_to_cpu(powerplay_table->usMMDependencyTableOffset));
     799           0 :         const PPTable_Generic_SubTable_Header *pPowerTuneTable =
     800           0 :                 (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
     801           0 :                 le16_to_cpu(powerplay_table->usPowerTuneTableOffset));
     802           0 :         const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
     803           0 :                 (const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) +
     804           0 :                 le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
     805           0 :         const PPTable_Generic_SubTable_Header *sclk_dep_table =
     806           0 :                 (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
     807           0 :                 le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));
     808           0 :         const ATOM_Tonga_Hard_Limit_Table *pHardLimits =
     809           0 :                 (const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) +
     810           0 :                 le16_to_cpu(powerplay_table->usHardLimitTableOffset));
     811           0 :         const PPTable_Generic_SubTable_Header *pcie_table =
     812           0 :                 (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
     813           0 :                 le16_to_cpu(powerplay_table->usPCIETableOffset));
     814           0 :         const ATOM_Tonga_GPIO_Table *gpio_table =
     815           0 :                 (const ATOM_Tonga_GPIO_Table *)(((unsigned long) powerplay_table) +
     816           0 :                 le16_to_cpu(powerplay_table->usGPIOTableOffset));
     817             : 
     818           0 :         pp_table_information->vdd_dep_on_sclk = NULL;
     819           0 :         pp_table_information->vdd_dep_on_mclk = NULL;
     820           0 :         pp_table_information->mm_dep_table = NULL;
     821           0 :         pp_table_information->pcie_table = NULL;
     822           0 :         pp_table_information->gpio_table = NULL;
     823             : 
     824           0 :         if (powerplay_table->usMMDependencyTableOffset != 0)
     825           0 :                 result = get_mm_clock_voltage_table(hwmgr,
     826           0 :                 &pp_table_information->mm_dep_table, mm_dependency_table);
     827             : 
     828           0 :         if (result == 0 && powerplay_table->usPowerTuneTableOffset != 0)
     829           0 :                 result = get_cac_tdp_table(hwmgr,
     830             :                 &pp_table_information->cac_dtp_table, pPowerTuneTable);
     831             : 
     832           0 :         if (result == 0 && powerplay_table->usSclkDependencyTableOffset != 0)
     833           0 :                 result = get_sclk_voltage_dependency_table(hwmgr,
     834           0 :                 &pp_table_information->vdd_dep_on_sclk, sclk_dep_table);
     835             : 
     836           0 :         if (result == 0 && powerplay_table->usMclkDependencyTableOffset != 0)
     837           0 :                 result = get_mclk_voltage_dependency_table(hwmgr,
     838           0 :                 &pp_table_information->vdd_dep_on_mclk, mclk_dep_table);
     839             : 
     840           0 :         if (result == 0 && powerplay_table->usPCIETableOffset != 0)
     841           0 :                 result = get_pcie_table(hwmgr,
     842           0 :                 &pp_table_information->pcie_table, pcie_table);
     843             : 
     844           0 :         if (result == 0 && powerplay_table->usHardLimitTableOffset != 0)
     845           0 :                 result = get_hard_limits(hwmgr,
     846             :                 &pp_table_information->max_clock_voltage_on_dc, pHardLimits);
     847             : 
     848           0 :         hwmgr->dyn_state.max_clock_voltage_on_dc.sclk =
     849           0 :                 pp_table_information->max_clock_voltage_on_dc.sclk;
     850           0 :         hwmgr->dyn_state.max_clock_voltage_on_dc.mclk =
     851           0 :                 pp_table_information->max_clock_voltage_on_dc.mclk;
     852           0 :         hwmgr->dyn_state.max_clock_voltage_on_dc.vddc =
     853           0 :                 pp_table_information->max_clock_voltage_on_dc.vddc;
     854           0 :         hwmgr->dyn_state.max_clock_voltage_on_dc.vddci =
     855           0 :                 pp_table_information->max_clock_voltage_on_dc.vddci;
     856             : 
     857           0 :         if (result == 0 && (NULL != pp_table_information->vdd_dep_on_mclk)
     858           0 :                 && (0 != pp_table_information->vdd_dep_on_mclk->count))
     859           0 :                 result = get_valid_clk(hwmgr, &pp_table_information->valid_mclk_values,
     860             :                 pp_table_information->vdd_dep_on_mclk);
     861             : 
     862           0 :         if (result == 0 && (NULL != pp_table_information->vdd_dep_on_sclk)
     863           0 :                 && (0 != pp_table_information->vdd_dep_on_sclk->count))
     864           0 :                 result = get_valid_clk(hwmgr, &pp_table_information->valid_sclk_values,
     865             :                 pp_table_information->vdd_dep_on_sclk);
     866             : 
     867           0 :         if (!result && gpio_table)
     868           0 :                 result = get_gpio_table(hwmgr, &pp_table_information->gpio_table,
     869             :                                 gpio_table);
     870             : 
     871           0 :         return result;
     872             : }
     873             : 
     874             : /**
     875             :  * init_over_drive_limits - Retrieves the (signed) Overdrive limits from VBIOS.
     876             :  * The max engine clock, memory clock and max temperature come from the firmware info table.
     877             :  *
     878             :  * The information is placed into the platform descriptor.
     879             :  *
     880             :  * @hwmgr: source of the VBIOS table and owner of the platform descriptor to be updated.
     881             :  * @powerplay_table: the address of the PowerPlay table.
     882             :  *
     883             :  * Return: 1 as long as the firmware info table was present and of a supported version.
     884             :  */
     885             : static int init_over_drive_limits(
     886             :                 struct pp_hwmgr *hwmgr,
     887             :                 const ATOM_Tonga_POWERPLAYTABLE *powerplay_table)
     888             : {
     889           0 :         hwmgr->platform_descriptor.overdriveLimit.engineClock =
     890           0 :                 le32_to_cpu(powerplay_table->ulMaxODEngineClock);
     891           0 :         hwmgr->platform_descriptor.overdriveLimit.memoryClock =
     892           0 :                 le32_to_cpu(powerplay_table->ulMaxODMemoryClock);
     893             : 
     894           0 :         hwmgr->platform_descriptor.minOverdriveVDDC = 0;
     895           0 :         hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
     896           0 :         hwmgr->platform_descriptor.overdriveVDDCStep = 0;
     897             : 
     898             :         return 0;
     899             : }
     900             : 
     901             : /**
     902             :  * init_thermal_controller - Private Function used during initialization.
     903             :  * Inspect the PowerPlay table for obvious signs of corruption.
     904             :  * @hwmgr: Pointer to the hardware manager.
     905             :  * @powerplay_table: Pointer to the PowerPlay Table.
     906             :  * Exception:  This implementation always returns 1.
     907             :  */
     908           0 : static int init_thermal_controller(
     909             :                 struct pp_hwmgr *hwmgr,
     910             :                 const ATOM_Tonga_POWERPLAYTABLE *powerplay_table
     911             :                 )
     912             : {
     913             :         const PPTable_Generic_SubTable_Header *fan_table;
     914             :         ATOM_Tonga_Thermal_Controller *thermal_controller;
     915             : 
     916           0 :         thermal_controller = (ATOM_Tonga_Thermal_Controller *)
     917           0 :                 (((unsigned long)powerplay_table) +
     918           0 :                 le16_to_cpu(powerplay_table->usThermalControllerOffset));
     919           0 :         PP_ASSERT_WITH_CODE((0 != powerplay_table->usThermalControllerOffset),
     920             :                 "Thermal controller table not set!", return -1);
     921             : 
     922           0 :         hwmgr->thermal_controller.ucType = thermal_controller->ucType;
     923           0 :         hwmgr->thermal_controller.ucI2cLine = thermal_controller->ucI2cLine;
     924           0 :         hwmgr->thermal_controller.ucI2cAddress = thermal_controller->ucI2cAddress;
     925             : 
     926           0 :         hwmgr->thermal_controller.fanInfo.bNoFan =
     927           0 :                 (0 != (thermal_controller->ucFanParameters & ATOM_TONGA_PP_FANPARAMETERS_NOFAN));
     928             : 
     929           0 :         hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
     930           0 :                 thermal_controller->ucFanParameters &
     931             :                 ATOM_TONGA_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
     932             : 
     933             :         hwmgr->thermal_controller.fanInfo.ulMinRPM
     934           0 :                 = thermal_controller->ucFanMinRPM * 100UL;
     935             :         hwmgr->thermal_controller.fanInfo.ulMaxRPM
     936           0 :                 = thermal_controller->ucFanMaxRPM * 100UL;
     937             : 
     938           0 :         set_hw_cap(
     939             :                         hwmgr,
     940             :                         ATOM_TONGA_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
     941             :                         PHM_PlatformCaps_ThermalController
     942             :                   );
     943             : 
     944           0 :         if (0 == powerplay_table->usFanTableOffset) {
     945           0 :                 hwmgr->thermal_controller.use_hw_fan_control = 1;
     946           0 :                 return 0;
     947             :         }
     948             : 
     949           0 :         fan_table = (const PPTable_Generic_SubTable_Header *)
     950           0 :                 (((unsigned long)powerplay_table) +
     951           0 :                 le16_to_cpu(powerplay_table->usFanTableOffset));
     952             : 
     953             :         PP_ASSERT_WITH_CODE((0 != powerplay_table->usFanTableOffset),
     954             :                 "Fan table not set!", return -1);
     955           0 :         PP_ASSERT_WITH_CODE((0 < fan_table->ucRevId),
     956             :                 "Unsupported fan table format!", return -1);
     957             : 
     958             :         hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay
     959           0 :                 = 100000;
     960           0 :         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
     961             :                 PHM_PlatformCaps_MicrocodeFanControl);
     962             : 
     963           0 :         if (fan_table->ucRevId < 8) {
     964           0 :                 const ATOM_Tonga_Fan_Table *tonga_fan_table =
     965             :                         (ATOM_Tonga_Fan_Table *)fan_table;
     966             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst
     967           0 :                         = tonga_fan_table->ucTHyst;
     968             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMin
     969           0 :                         = le16_to_cpu(tonga_fan_table->usTMin);
     970             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMed
     971           0 :                         = le16_to_cpu(tonga_fan_table->usTMed);
     972             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTHigh
     973           0 :                         = le16_to_cpu(tonga_fan_table->usTHigh);
     974             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin
     975           0 :                         = le16_to_cpu(tonga_fan_table->usPWMMin);
     976             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed
     977           0 :                         = le16_to_cpu(tonga_fan_table->usPWMMed);
     978             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh
     979           0 :                         = le16_to_cpu(tonga_fan_table->usPWMHigh);
     980             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMax
     981           0 :                         = 10900;                  /* hard coded */
     982             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMax
     983           0 :                         = le16_to_cpu(tonga_fan_table->usTMax);
     984             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucFanControlMode
     985           0 :                         = tonga_fan_table->ucFanControlMode;
     986             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanPWM
     987           0 :                         = le16_to_cpu(tonga_fan_table->usFanPWMMax);
     988             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity
     989           0 :                         = 4836;
     990             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity
     991           0 :                         = le16_to_cpu(tonga_fan_table->usFanOutputSensitivity);
     992             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanRPM
     993           0 :                         = le16_to_cpu(tonga_fan_table->usFanRPMMax);
     994             :                 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit
     995           0 :                         = (le32_to_cpu(tonga_fan_table->ulMinFanSCLKAcousticLimit) / 100); /* PPTable stores it in 10Khz unit for 2 decimal places.  SMC wants MHz. */
     996             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucTargetTemperature
     997           0 :                         = tonga_fan_table->ucTargetTemperature;
     998             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit
     999           0 :                         = tonga_fan_table->ucMinimumPWMLimit;
    1000           0 :         } else if (fan_table->ucRevId == 8) {
    1001           0 :                 const ATOM_Fiji_Fan_Table *fiji_fan_table =
    1002             :                         (ATOM_Fiji_Fan_Table *)fan_table;
    1003             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst
    1004           0 :                         = fiji_fan_table->ucTHyst;
    1005             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMin
    1006           0 :                         = le16_to_cpu(fiji_fan_table->usTMin);
    1007             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMed
    1008           0 :                         = le16_to_cpu(fiji_fan_table->usTMed);
    1009             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTHigh
    1010           0 :                         = le16_to_cpu(fiji_fan_table->usTHigh);
    1011             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin
    1012           0 :                         = le16_to_cpu(fiji_fan_table->usPWMMin);
    1013             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed
    1014           0 :                         = le16_to_cpu(fiji_fan_table->usPWMMed);
    1015             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh
    1016           0 :                         = le16_to_cpu(fiji_fan_table->usPWMHigh);
    1017             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMax
    1018           0 :                         = le16_to_cpu(fiji_fan_table->usTMax);
    1019             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucFanControlMode
    1020           0 :                         = fiji_fan_table->ucFanControlMode;
    1021             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanPWM
    1022           0 :                         = le16_to_cpu(fiji_fan_table->usFanPWMMax);
    1023             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity
    1024           0 :                         = 4836;
    1025             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity
    1026           0 :                         = le16_to_cpu(fiji_fan_table->usFanOutputSensitivity);
    1027             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanRPM
    1028           0 :                         = le16_to_cpu(fiji_fan_table->usFanRPMMax);
    1029             :                 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit
    1030           0 :                         = (le32_to_cpu(fiji_fan_table->ulMinFanSCLKAcousticLimit) / 100); /* PPTable stores it in 10Khz unit for 2 decimal places.  SMC wants MHz. */
    1031             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucTargetTemperature
    1032           0 :                         = fiji_fan_table->ucTargetTemperature;
    1033             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit
    1034           0 :                         = fiji_fan_table->ucMinimumPWMLimit;
    1035             : 
    1036             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge
    1037           0 :                         = le16_to_cpu(fiji_fan_table->usFanGainEdge);
    1038             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot
    1039           0 :                         = le16_to_cpu(fiji_fan_table->usFanGainHotspot);
    1040             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid
    1041           0 :                         = le16_to_cpu(fiji_fan_table->usFanGainLiquid);
    1042             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc
    1043           0 :                         = le16_to_cpu(fiji_fan_table->usFanGainVrVddc);
    1044             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd
    1045           0 :                         = le16_to_cpu(fiji_fan_table->usFanGainVrMvdd);
    1046             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx
    1047           0 :                         = le16_to_cpu(fiji_fan_table->usFanGainPlx);
    1048             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm
    1049           0 :                         = le16_to_cpu(fiji_fan_table->usFanGainHbm);
    1050           0 :         } else if (fan_table->ucRevId >= 9) {
    1051           0 :                 const ATOM_Polaris_Fan_Table *polaris_fan_table =
    1052             :                         (ATOM_Polaris_Fan_Table *)fan_table;
    1053             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst
    1054           0 :                         = polaris_fan_table->ucTHyst;
    1055             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMin
    1056           0 :                         = le16_to_cpu(polaris_fan_table->usTMin);
    1057             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMed
    1058           0 :                         = le16_to_cpu(polaris_fan_table->usTMed);
    1059             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTHigh
    1060           0 :                         = le16_to_cpu(polaris_fan_table->usTHigh);
    1061             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin
    1062           0 :                         = le16_to_cpu(polaris_fan_table->usPWMMin);
    1063             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed
    1064           0 :                         = le16_to_cpu(polaris_fan_table->usPWMMed);
    1065             :                 hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh
    1066           0 :                         = le16_to_cpu(polaris_fan_table->usPWMHigh);
    1067             :                 hwmgr->thermal_controller.advanceFanControlParameters.usTMax
    1068           0 :                         = le16_to_cpu(polaris_fan_table->usTMax);
    1069             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucFanControlMode
    1070           0 :                         = polaris_fan_table->ucFanControlMode;
    1071             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanPWM
    1072           0 :                         = le16_to_cpu(polaris_fan_table->usFanPWMMax);
    1073             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity
    1074           0 :                         = 4836;
    1075             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity
    1076           0 :                         = le16_to_cpu(polaris_fan_table->usFanOutputSensitivity);
    1077             :                 hwmgr->thermal_controller.advanceFanControlParameters.usDefaultMaxFanRPM
    1078           0 :                         = le16_to_cpu(polaris_fan_table->usFanRPMMax);
    1079             :                 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit
    1080           0 :                         = (le32_to_cpu(polaris_fan_table->ulMinFanSCLKAcousticLimit) / 100); /* PPTable stores it in 10Khz unit for 2 decimal places.  SMC wants MHz. */
    1081             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucTargetTemperature
    1082           0 :                         = polaris_fan_table->ucTargetTemperature;
    1083             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit
    1084           0 :                         = polaris_fan_table->ucMinimumPWMLimit;
    1085             : 
    1086             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainEdge
    1087           0 :                         = le16_to_cpu(polaris_fan_table->usFanGainEdge);
    1088             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHotspot
    1089           0 :                         = le16_to_cpu(polaris_fan_table->usFanGainHotspot);
    1090             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainLiquid
    1091           0 :                         = le16_to_cpu(polaris_fan_table->usFanGainLiquid);
    1092             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrVddc
    1093           0 :                         = le16_to_cpu(polaris_fan_table->usFanGainVrVddc);
    1094             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainVrMvdd
    1095           0 :                         = le16_to_cpu(polaris_fan_table->usFanGainVrMvdd);
    1096             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainPlx
    1097           0 :                         = le16_to_cpu(polaris_fan_table->usFanGainPlx);
    1098             :                 hwmgr->thermal_controller.advanceFanControlParameters.usFanGainHbm
    1099           0 :                         = le16_to_cpu(polaris_fan_table->usFanGainHbm);
    1100             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucEnableZeroRPM
    1101           0 :                         = le16_to_cpu(polaris_fan_table->ucEnableZeroRPM);
    1102             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucFanStopTemperature
    1103           0 :                         = le16_to_cpu(polaris_fan_table->ucFanStopTemperature);
    1104             :                 hwmgr->thermal_controller.advanceFanControlParameters.ucFanStartTemperature
    1105           0 :                         = le16_to_cpu(polaris_fan_table->ucFanStartTemperature);
    1106             :         }
    1107             : 
    1108             :         return 0;
    1109             : }
    1110             : 
    1111             : /**
    1112             :  * check_powerplay_tables - Private Function used during initialization.
    1113             :  * Inspect the PowerPlay table for obvious signs of corruption.
    1114             :  * @hwmgr: Pointer to the hardware manager.
    1115             :  * @powerplay_table: Pointer to the PowerPlay Table.
    1116             :  * Exception:  2 if the powerplay table is incorrect.
    1117             :  */
    1118           0 : static int check_powerplay_tables(
    1119             :                 struct pp_hwmgr *hwmgr,
    1120             :                 const ATOM_Tonga_POWERPLAYTABLE *powerplay_table
    1121             :                 )
    1122             : {
    1123             :         const ATOM_Tonga_State_Array *state_arrays;
    1124             : 
    1125           0 :         state_arrays = (ATOM_Tonga_State_Array *)(((unsigned long)powerplay_table) +
    1126           0 :                 le16_to_cpu(powerplay_table->usStateArrayOffset));
    1127             : 
    1128           0 :         PP_ASSERT_WITH_CODE((ATOM_Tonga_TABLE_REVISION_TONGA <=
    1129             :                 powerplay_table->sHeader.ucTableFormatRevision),
    1130             :                 "Unsupported PPTable format!", return -1);
    1131           0 :         PP_ASSERT_WITH_CODE((0 != powerplay_table->usStateArrayOffset),
    1132             :                 "State table is not set!", return -1);
    1133           0 :         PP_ASSERT_WITH_CODE((0 < powerplay_table->sHeader.usStructureSize),
    1134             :                 "Invalid PowerPlay Table!", return -1);
    1135           0 :         PP_ASSERT_WITH_CODE((0 < state_arrays->ucNumEntries),
    1136             :                 "Invalid PowerPlay Table!", return -1);
    1137             : 
    1138             :         return 0;
    1139             : }
    1140             : 
    1141           0 : static int pp_tables_v1_0_initialize(struct pp_hwmgr *hwmgr)
    1142             : {
    1143           0 :         int result = 0;
    1144             :         const ATOM_Tonga_POWERPLAYTABLE *powerplay_table;
    1145             : 
    1146           0 :         hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v1_information), GFP_KERNEL);
    1147             : 
    1148           0 :         PP_ASSERT_WITH_CODE((NULL != hwmgr->pptable),
    1149             :                             "Failed to allocate hwmgr->pptable!", return -ENOMEM);
    1150             : 
    1151           0 :         powerplay_table = get_powerplay_table(hwmgr);
    1152             : 
    1153           0 :         PP_ASSERT_WITH_CODE((NULL != powerplay_table),
    1154             :                 "Missing PowerPlay Table!", return -1);
    1155             : 
    1156           0 :         result = check_powerplay_tables(hwmgr, powerplay_table);
    1157             : 
    1158           0 :         PP_ASSERT_WITH_CODE((result == 0),
    1159             :                             "check_powerplay_tables failed", return result);
    1160             : 
    1161           0 :         result = set_platform_caps(hwmgr,
    1162           0 :                                    le32_to_cpu(powerplay_table->ulPlatformCaps));
    1163             : 
    1164           0 :         PP_ASSERT_WITH_CODE((result == 0),
    1165             :                             "set_platform_caps failed", return result);
    1166             : 
    1167           0 :         result = init_thermal_controller(hwmgr, powerplay_table);
    1168             : 
    1169           0 :         PP_ASSERT_WITH_CODE((result == 0),
    1170             :                             "init_thermal_controller failed", return result);
    1171             : 
    1172           0 :         result = init_over_drive_limits(hwmgr, powerplay_table);
    1173             : 
    1174             :         PP_ASSERT_WITH_CODE((result == 0),
    1175             :                             "init_over_drive_limits failed", return result);
    1176             : 
    1177           0 :         result = init_clock_voltage_dependency(hwmgr, powerplay_table);
    1178             : 
    1179           0 :         PP_ASSERT_WITH_CODE((result == 0),
    1180             :                             "init_clock_voltage_dependency failed", return result);
    1181             : 
    1182           0 :         result = init_dpm_2_parameters(hwmgr, powerplay_table);
    1183             : 
    1184           0 :         PP_ASSERT_WITH_CODE((result == 0),
    1185             :                             "init_dpm_2_parameters failed", return result);
    1186             : 
    1187             :         return result;
    1188             : }
    1189             : 
    1190           0 : static int pp_tables_v1_0_uninitialize(struct pp_hwmgr *hwmgr)
    1191             : {
    1192           0 :         struct phm_ppt_v1_information *pp_table_information =
    1193             :                 (struct phm_ppt_v1_information *)(hwmgr->pptable);
    1194             : 
    1195           0 :         kfree(pp_table_information->vdd_dep_on_sclk);
    1196           0 :         pp_table_information->vdd_dep_on_sclk = NULL;
    1197             : 
    1198           0 :         kfree(pp_table_information->vdd_dep_on_mclk);
    1199           0 :         pp_table_information->vdd_dep_on_mclk = NULL;
    1200             : 
    1201           0 :         kfree(pp_table_information->valid_mclk_values);
    1202           0 :         pp_table_information->valid_mclk_values = NULL;
    1203             : 
    1204           0 :         kfree(pp_table_information->valid_sclk_values);
    1205           0 :         pp_table_information->valid_sclk_values = NULL;
    1206             : 
    1207           0 :         kfree(pp_table_information->vddc_lookup_table);
    1208           0 :         pp_table_information->vddc_lookup_table = NULL;
    1209             : 
    1210           0 :         kfree(pp_table_information->vddgfx_lookup_table);
    1211           0 :         pp_table_information->vddgfx_lookup_table = NULL;
    1212             : 
    1213           0 :         kfree(pp_table_information->mm_dep_table);
    1214           0 :         pp_table_information->mm_dep_table = NULL;
    1215             : 
    1216           0 :         kfree(pp_table_information->cac_dtp_table);
    1217           0 :         pp_table_information->cac_dtp_table = NULL;
    1218             : 
    1219           0 :         kfree(hwmgr->dyn_state.cac_dtp_table);
    1220           0 :         hwmgr->dyn_state.cac_dtp_table = NULL;
    1221             : 
    1222           0 :         kfree(pp_table_information->ppm_parameter_table);
    1223           0 :         pp_table_information->ppm_parameter_table = NULL;
    1224             : 
    1225           0 :         kfree(pp_table_information->pcie_table);
    1226           0 :         pp_table_information->pcie_table = NULL;
    1227             : 
    1228           0 :         kfree(pp_table_information->gpio_table);
    1229           0 :         pp_table_information->gpio_table = NULL;
    1230             : 
    1231           0 :         kfree(hwmgr->pptable);
    1232           0 :         hwmgr->pptable = NULL;
    1233             : 
    1234           0 :         return 0;
    1235             : }
    1236             : 
    1237             : const struct pp_table_func pptable_v1_0_funcs = {
    1238             :         .pptable_init = pp_tables_v1_0_initialize,
    1239             :         .pptable_fini = pp_tables_v1_0_uninitialize,
    1240             : };
    1241             : 
    1242           0 : int get_number_of_powerplay_table_entries_v1_0(struct pp_hwmgr *hwmgr)
    1243             : {
    1244             :         ATOM_Tonga_State_Array const *state_arrays;
    1245           0 :         const ATOM_Tonga_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
    1246             : 
    1247           0 :         PP_ASSERT_WITH_CODE((NULL != pp_table),
    1248             :                         "Missing PowerPlay Table!", return -1);
    1249           0 :         PP_ASSERT_WITH_CODE((pp_table->sHeader.ucTableFormatRevision >=
    1250             :                         ATOM_Tonga_TABLE_REVISION_TONGA),
    1251             :                         "Incorrect PowerPlay table revision!", return -1);
    1252             : 
    1253           0 :         state_arrays = (ATOM_Tonga_State_Array *)(((unsigned long)pp_table) +
    1254           0 :                         le16_to_cpu(pp_table->usStateArrayOffset));
    1255             : 
    1256           0 :         return (uint32_t)(state_arrays->ucNumEntries);
    1257             : }
    1258             : 
    1259             : /*
    1260             :  * Private function to convert flags stored in the BIOS to software flags in PowerPlay.
    1261             :  */
    1262           0 : static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr,
    1263             :                 uint16_t classification, uint16_t classification2)
    1264             : {
    1265           0 :         uint32_t result = 0;
    1266             : 
    1267           0 :         if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT)
    1268           0 :                 result |= PP_StateClassificationFlag_Boot;
    1269             : 
    1270           0 :         if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL)
    1271           0 :                 result |= PP_StateClassificationFlag_Thermal;
    1272             : 
    1273           0 :         if (classification & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
    1274           0 :                 result |= PP_StateClassificationFlag_LimitedPowerSource;
    1275             : 
    1276           0 :         if (classification & ATOM_PPLIB_CLASSIFICATION_REST)
    1277           0 :                 result |= PP_StateClassificationFlag_Rest;
    1278             : 
    1279           0 :         if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED)
    1280           0 :                 result |= PP_StateClassificationFlag_Forced;
    1281             : 
    1282           0 :         if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI)
    1283           0 :                 result |= PP_StateClassificationFlag_ACPI;
    1284             : 
    1285           0 :         if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
    1286           0 :                 result |= PP_StateClassificationFlag_LimitedPowerSource_2;
    1287             : 
    1288           0 :         return result;
    1289             : }
    1290             : 
    1291             : static int ppt_get_num_of_vce_state_table_entries_v1_0(struct pp_hwmgr *hwmgr)
    1292             : {
    1293           0 :         const ATOM_Tonga_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
    1294             :         const ATOM_Tonga_VCE_State_Table *vce_state_table;
    1295             : 
    1296             : 
    1297           0 :         if (pp_table == NULL)
    1298             :                 return 0;
    1299             : 
    1300           0 :         vce_state_table = (void *)pp_table +
    1301           0 :                         le16_to_cpu(pp_table->usVCEStateTableOffset);
    1302             : 
    1303           0 :         return vce_state_table->ucNumEntries;
    1304             : }
    1305             : 
    1306           0 : static int ppt_get_vce_state_table_entry_v1_0(struct pp_hwmgr *hwmgr, uint32_t i,
    1307             :                 struct amd_vce_state *vce_state, void **clock_info, uint32_t *flag)
    1308             : {
    1309             :         const ATOM_Tonga_VCE_State_Record *vce_state_record;
    1310             :         ATOM_Tonga_SCLK_Dependency_Record *sclk_dep_record;
    1311             :         ATOM_Tonga_MCLK_Dependency_Record *mclk_dep_record;
    1312             :         ATOM_Tonga_MM_Dependency_Record *mm_dep_record;
    1313           0 :         const ATOM_Tonga_POWERPLAYTABLE *pptable = get_powerplay_table(hwmgr);
    1314           0 :         const ATOM_Tonga_VCE_State_Table *vce_state_table = (ATOM_Tonga_VCE_State_Table *)(((unsigned long)pptable)
    1315           0 :                                                           + le16_to_cpu(pptable->usVCEStateTableOffset));
    1316           0 :         const ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = (ATOM_Tonga_SCLK_Dependency_Table *)(((unsigned long)pptable)
    1317           0 :                                                           + le16_to_cpu(pptable->usSclkDependencyTableOffset));
    1318           0 :         const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = (ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long)pptable)
    1319           0 :                                                           + le16_to_cpu(pptable->usMclkDependencyTableOffset));
    1320           0 :         const ATOM_Tonga_MM_Dependency_Table *mm_dep_table = (ATOM_Tonga_MM_Dependency_Table *)(((unsigned long)pptable)
    1321           0 :                                                           + le16_to_cpu(pptable->usMMDependencyTableOffset));
    1322             : 
    1323           0 :         PP_ASSERT_WITH_CODE((i < vce_state_table->ucNumEntries),
    1324             :                          "Requested state entry ID is out of range!",
    1325             :                          return -EINVAL);
    1326             : 
    1327           0 :         vce_state_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
    1328             :                                         ATOM_Tonga_VCE_State_Record,
    1329             :                                         entries, vce_state_table, i);
    1330           0 :         sclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
    1331             :                                         ATOM_Tonga_SCLK_Dependency_Record,
    1332             :                                         entries, sclk_dep_table,
    1333             :                                         vce_state_record->ucSCLKIndex);
    1334           0 :         mm_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
    1335             :                                         ATOM_Tonga_MM_Dependency_Record,
    1336             :                                         entries, mm_dep_table,
    1337             :                                         vce_state_record->ucVCEClockIndex);
    1338           0 :         *flag = vce_state_record->ucFlag;
    1339             : 
    1340           0 :         vce_state->evclk = le32_to_cpu(mm_dep_record->ulEClk);
    1341           0 :         vce_state->ecclk = le32_to_cpu(mm_dep_record->ulEClk);
    1342           0 :         vce_state->sclk = le32_to_cpu(sclk_dep_record->ulSclk);
    1343             : 
    1344           0 :         if (vce_state_record->ucMCLKIndex >= mclk_dep_table->ucNumEntries)
    1345           0 :                 mclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
    1346             :                                         ATOM_Tonga_MCLK_Dependency_Record,
    1347             :                                         entries, mclk_dep_table,
    1348             :                                         mclk_dep_table->ucNumEntries - 1);
    1349             :         else
    1350           0 :                 mclk_dep_record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
    1351             :                                         ATOM_Tonga_MCLK_Dependency_Record,
    1352             :                                         entries, mclk_dep_table,
    1353             :                                         vce_state_record->ucMCLKIndex);
    1354             : 
    1355           0 :         vce_state->mclk = le32_to_cpu(mclk_dep_record->ulMclk);
    1356             :         return 0;
    1357             : }
    1358             : 
    1359             : /**
    1360             :  * get_powerplay_table_entry_v1_0 - Create a Power State out of an entry in the PowerPlay table.
    1361             :  * This function is called by the hardware back-end.
    1362             :  * @hwmgr: Pointer to the hardware manager.
    1363             :  * @entry_index: The index of the entry to be extracted from the table.
    1364             :  * @power_state: The address of the PowerState instance being created.
    1365             :  * @call_back_func: The function to call into to fill power state
    1366             :  * Return: -1 if the entry cannot be retrieved.
    1367             :  */
    1368           0 : int get_powerplay_table_entry_v1_0(struct pp_hwmgr *hwmgr,
    1369             :                 uint32_t entry_index, struct pp_power_state *power_state,
    1370             :                 int (*call_back_func)(struct pp_hwmgr *, void *,
    1371             :                                 struct pp_power_state *, void *, uint32_t))
    1372             : {
    1373           0 :         int result = 0;
    1374             :         const ATOM_Tonga_State_Array *state_arrays;
    1375             :         const ATOM_Tonga_State *state_entry;
    1376           0 :         const ATOM_Tonga_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr);
    1377             :         int i, j;
    1378           0 :         uint32_t flags = 0;
    1379             : 
    1380           0 :         PP_ASSERT_WITH_CODE((NULL != pp_table), "Missing PowerPlay Table!", return -1;);
    1381           0 :         power_state->classification.bios_index = entry_index;
    1382             : 
    1383           0 :         if (pp_table->sHeader.ucTableFormatRevision >=
    1384             :                         ATOM_Tonga_TABLE_REVISION_TONGA) {
    1385           0 :                 state_arrays = (ATOM_Tonga_State_Array *)(((unsigned long)pp_table) +
    1386           0 :                                 le16_to_cpu(pp_table->usStateArrayOffset));
    1387             : 
    1388           0 :                 PP_ASSERT_WITH_CODE((0 < pp_table->usStateArrayOffset),
    1389             :                                 "Invalid PowerPlay Table State Array Offset.", return -1);
    1390           0 :                 PP_ASSERT_WITH_CODE((0 < state_arrays->ucNumEntries),
    1391             :                                 "Invalid PowerPlay Table State Array.", return -1);
    1392           0 :                 PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries),
    1393             :                                 "Invalid PowerPlay Table State Array Entry.", return -1);
    1394             : 
    1395           0 :                 state_entry = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
    1396             :                                                 ATOM_Tonga_State, entries,
    1397             :                                                 state_arrays, entry_index);
    1398             : 
    1399           0 :                 result = call_back_func(hwmgr, (void *)state_entry, power_state,
    1400             :                                 (void *)pp_table,
    1401             :                                 make_classification_flags(hwmgr,
    1402           0 :                                         le16_to_cpu(state_entry->usClassification),
    1403           0 :                                         le16_to_cpu(state_entry->usClassification2)));
    1404             :         }
    1405             : 
    1406           0 :         if (!result && (power_state->classification.flags &
    1407             :                         PP_StateClassificationFlag_Boot))
    1408           0 :                 result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware));
    1409             : 
    1410           0 :         hwmgr->num_vce_state_tables = i = ppt_get_num_of_vce_state_table_entries_v1_0(hwmgr);
    1411             : 
    1412           0 :         if ((i != 0) && (i <= AMD_MAX_VCE_LEVELS)) {
    1413           0 :                 for (j = 0; j < i; j++)
    1414           0 :                         ppt_get_vce_state_table_entry_v1_0(hwmgr, j, &(hwmgr->vce_states[j]), NULL, &flags);
    1415             :         }
    1416             : 
    1417             :         return result;
    1418             : }
    1419             : 

Generated by: LCOV version 1.14