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

          Line data    Source code
       1             : /*
       2             :  * Copyright 2016 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             : 
      24             : #include <linux/pci.h>
      25             : 
      26             : #include "smumgr.h"
      27             : #include "vega10_inc.h"
      28             : #include "soc15_common.h"
      29             : #include "vega10_smumgr.h"
      30             : #include "vega10_hwmgr.h"
      31             : #include "vega10_ppsmc.h"
      32             : #include "smu9_driver_if.h"
      33             : #include "smu9_smumgr.h"
      34             : #include "ppatomctrl.h"
      35             : #include "pp_debug.h"
      36             : 
      37             : 
      38           0 : static int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
      39             :                 uint8_t *table, int16_t table_id)
      40             : {
      41           0 :         struct vega10_smumgr *priv = hwmgr->smu_backend;
      42           0 :         struct amdgpu_device *adev = hwmgr->adev;
      43             : 
      44           0 :         PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
      45             :                         "Invalid SMU Table ID!", return -EINVAL);
      46           0 :         PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
      47             :                         "Invalid SMU Table version!", return -EINVAL);
      48           0 :         PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
      49             :                         "Invalid SMU Table Length!", return -EINVAL);
      50           0 :         smum_send_msg_to_smc_with_parameter(hwmgr,
      51             :                         PPSMC_MSG_SetDriverDramAddrHigh,
      52           0 :                         upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
      53             :                         NULL);
      54           0 :         smum_send_msg_to_smc_with_parameter(hwmgr,
      55             :                         PPSMC_MSG_SetDriverDramAddrLow,
      56           0 :                         lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
      57             :                         NULL);
      58           0 :         smum_send_msg_to_smc_with_parameter(hwmgr,
      59             :                         PPSMC_MSG_TransferTableSmu2Dram,
      60             :                         priv->smu_tables.entry[table_id].table_id,
      61             :                         NULL);
      62             : 
      63           0 :         amdgpu_asic_invalidate_hdp(adev, NULL);
      64             : 
      65           0 :         memcpy(table, priv->smu_tables.entry[table_id].table,
      66           0 :                         priv->smu_tables.entry[table_id].size);
      67             : 
      68           0 :         return 0;
      69             : }
      70             : 
      71           0 : static int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
      72             :                 uint8_t *table, int16_t table_id)
      73             : {
      74           0 :         struct vega10_smumgr *priv = hwmgr->smu_backend;
      75           0 :         struct amdgpu_device *adev = hwmgr->adev;
      76             : 
      77             :         /* under sriov, vbios or hypervisor driver
      78             :          * has already copy table to smc so here only skip it
      79             :          */
      80           0 :         if (!hwmgr->not_vf)
      81             :                 return 0;
      82             : 
      83           0 :         PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
      84             :                         "Invalid SMU Table ID!", return -EINVAL);
      85           0 :         PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
      86             :                         "Invalid SMU Table version!", return -EINVAL);
      87           0 :         PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
      88             :                         "Invalid SMU Table Length!", return -EINVAL);
      89             : 
      90           0 :         memcpy(priv->smu_tables.entry[table_id].table, table,
      91             :                         priv->smu_tables.entry[table_id].size);
      92             : 
      93           0 :         amdgpu_asic_flush_hdp(adev, NULL);
      94             : 
      95           0 :         smum_send_msg_to_smc_with_parameter(hwmgr,
      96             :                         PPSMC_MSG_SetDriverDramAddrHigh,
      97           0 :                         upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
      98             :                         NULL);
      99           0 :         smum_send_msg_to_smc_with_parameter(hwmgr,
     100             :                         PPSMC_MSG_SetDriverDramAddrLow,
     101           0 :                         lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
     102             :                         NULL);
     103           0 :         smum_send_msg_to_smc_with_parameter(hwmgr,
     104             :                         PPSMC_MSG_TransferTableDram2Smu,
     105             :                         priv->smu_tables.entry[table_id].table_id,
     106             :                         NULL);
     107             : 
     108           0 :         return 0;
     109             : }
     110             : 
     111           0 : int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
     112             :                                bool enable, uint32_t feature_mask)
     113             : {
     114           0 :         int msg = enable ? PPSMC_MSG_EnableSmuFeatures :
     115             :                         PPSMC_MSG_DisableSmuFeatures;
     116             : 
     117             :         /* VF has no permission to change smu feature due
     118             :          * to security concern even under pp one vf mode
     119             :          * it still can't do it. For vega10, the smu in
     120             :          * vbios will enable the appropriate features.
     121             :          * */
     122           0 :         if (!hwmgr->not_vf)
     123             :                 return 0;
     124             : 
     125           0 :         return smum_send_msg_to_smc_with_parameter(hwmgr,
     126             :                         msg, feature_mask, NULL);
     127             : }
     128             : 
     129           0 : int vega10_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
     130             :                             uint64_t *features_enabled)
     131             : {
     132             :         uint32_t enabled_features;
     133             : 
     134           0 :         if (features_enabled == NULL)
     135             :                 return -EINVAL;
     136             : 
     137           0 :         smum_send_msg_to_smc(hwmgr,
     138             :                         PPSMC_MSG_GetEnabledSmuFeatures,
     139             :                         &enabled_features);
     140           0 :         *features_enabled = enabled_features;
     141             : 
     142           0 :         return 0;
     143             : }
     144             : 
     145           0 : static bool vega10_is_dpm_running(struct pp_hwmgr *hwmgr)
     146             : {
     147           0 :         uint64_t features_enabled = 0;
     148             : 
     149           0 :         vega10_get_enabled_smc_features(hwmgr, &features_enabled);
     150             : 
     151           0 :         if (features_enabled & SMC_DPM_FEATURES)
     152             :                 return true;
     153             :         else
     154           0 :                 return false;
     155             : }
     156             : 
     157           0 : static int vega10_set_tools_address(struct pp_hwmgr *hwmgr)
     158             : {
     159           0 :         struct vega10_smumgr *priv = hwmgr->smu_backend;
     160             : 
     161           0 :         if (priv->smu_tables.entry[TOOLSTABLE].mc_addr) {
     162           0 :                 smum_send_msg_to_smc_with_parameter(hwmgr,
     163             :                                 PPSMC_MSG_SetToolsDramAddrHigh,
     164           0 :                                 upper_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr),
     165             :                                 NULL);
     166           0 :                 smum_send_msg_to_smc_with_parameter(hwmgr,
     167             :                                 PPSMC_MSG_SetToolsDramAddrLow,
     168           0 :                                 lower_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr),
     169             :                                 NULL);
     170             :         }
     171           0 :         return 0;
     172             : }
     173             : 
     174           0 : static int vega10_verify_smc_interface(struct pp_hwmgr *hwmgr)
     175             : {
     176             :         uint32_t smc_driver_if_version;
     177           0 :         struct amdgpu_device *adev = hwmgr->adev;
     178             :         uint32_t dev_id;
     179             :         uint32_t rev_id;
     180             : 
     181           0 :         PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr,
     182             :                         PPSMC_MSG_GetDriverIfVersion,
     183             :                         &smc_driver_if_version),
     184             :                         "Attempt to get SMC IF Version Number Failed!",
     185             :                         return -EINVAL);
     186             : 
     187           0 :         dev_id = adev->pdev->device;
     188           0 :         rev_id = adev->pdev->revision;
     189             : 
     190           0 :         if (!((dev_id == 0x687f) &&
     191           0 :                 ((rev_id == 0xc0) ||
     192           0 :                 (rev_id == 0xc1) ||
     193           0 :                 (rev_id == 0xc3)))) {
     194           0 :                 if (smc_driver_if_version != SMU9_DRIVER_IF_VERSION) {
     195           0 :                         pr_err("Your firmware(0x%x) doesn't match SMU9_DRIVER_IF_VERSION(0x%x). Please update your firmware!\n",
     196             :                                smc_driver_if_version, SMU9_DRIVER_IF_VERSION);
     197           0 :                         return -EINVAL;
     198             :                 }
     199             :         }
     200             : 
     201             :         return 0;
     202             : }
     203             : 
     204           0 : static int vega10_smu_init(struct pp_hwmgr *hwmgr)
     205             : {
     206             :         struct vega10_smumgr *priv;
     207             :         unsigned long tools_size;
     208             :         int ret;
     209           0 :         struct cgs_firmware_info info = {0};
     210             : 
     211           0 :         ret = cgs_get_firmware_info(hwmgr->device,
     212             :                                         CGS_UCODE_ID_SMU,
     213             :                                         &info);
     214           0 :         if (ret || !info.kptr)
     215             :                 return -EINVAL;
     216             : 
     217           0 :         priv = kzalloc(sizeof(struct vega10_smumgr), GFP_KERNEL);
     218             : 
     219           0 :         if (!priv)
     220             :                 return -ENOMEM;
     221             : 
     222           0 :         hwmgr->smu_backend = priv;
     223             : 
     224             :         /* allocate space for pptable */
     225           0 :         ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
     226             :                         sizeof(PPTable_t),
     227             :                         PAGE_SIZE,
     228             :                         AMDGPU_GEM_DOMAIN_VRAM,
     229             :                         &priv->smu_tables.entry[PPTABLE].handle,
     230           0 :                         &priv->smu_tables.entry[PPTABLE].mc_addr,
     231             :                         &priv->smu_tables.entry[PPTABLE].table);
     232           0 :         if (ret)
     233             :                 goto free_backend;
     234             : 
     235           0 :         priv->smu_tables.entry[PPTABLE].version = 0x01;
     236           0 :         priv->smu_tables.entry[PPTABLE].size = sizeof(PPTable_t);
     237           0 :         priv->smu_tables.entry[PPTABLE].table_id = TABLE_PPTABLE;
     238             : 
     239             :         /* allocate space for watermarks table */
     240           0 :         ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
     241             :                         sizeof(Watermarks_t),
     242             :                         PAGE_SIZE,
     243             :                         AMDGPU_GEM_DOMAIN_VRAM,
     244             :                         &priv->smu_tables.entry[WMTABLE].handle,
     245           0 :                         &priv->smu_tables.entry[WMTABLE].mc_addr,
     246             :                         &priv->smu_tables.entry[WMTABLE].table);
     247             : 
     248           0 :         if (ret)
     249             :                 goto err0;
     250             : 
     251           0 :         priv->smu_tables.entry[WMTABLE].version = 0x01;
     252           0 :         priv->smu_tables.entry[WMTABLE].size = sizeof(Watermarks_t);
     253           0 :         priv->smu_tables.entry[WMTABLE].table_id = TABLE_WATERMARKS;
     254             : 
     255             :         /* allocate space for AVFS table */
     256           0 :         ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
     257             :                         sizeof(AvfsTable_t),
     258             :                         PAGE_SIZE,
     259             :                         AMDGPU_GEM_DOMAIN_VRAM,
     260             :                         &priv->smu_tables.entry[AVFSTABLE].handle,
     261           0 :                         &priv->smu_tables.entry[AVFSTABLE].mc_addr,
     262             :                         &priv->smu_tables.entry[AVFSTABLE].table);
     263             : 
     264           0 :         if (ret)
     265             :                 goto err1;
     266             : 
     267           0 :         priv->smu_tables.entry[AVFSTABLE].version = 0x01;
     268           0 :         priv->smu_tables.entry[AVFSTABLE].size = sizeof(AvfsTable_t);
     269           0 :         priv->smu_tables.entry[AVFSTABLE].table_id = TABLE_AVFS;
     270             : 
     271           0 :         tools_size = 0x19000;
     272             :         if (tools_size) {
     273           0 :                 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
     274             :                                 tools_size,
     275             :                                 PAGE_SIZE,
     276             :                                 AMDGPU_GEM_DOMAIN_VRAM,
     277             :                                 &priv->smu_tables.entry[TOOLSTABLE].handle,
     278           0 :                                 &priv->smu_tables.entry[TOOLSTABLE].mc_addr,
     279             :                                 &priv->smu_tables.entry[TOOLSTABLE].table);
     280           0 :                 if (ret)
     281             :                         goto err2;
     282           0 :                 priv->smu_tables.entry[TOOLSTABLE].version = 0x01;
     283           0 :                 priv->smu_tables.entry[TOOLSTABLE].size = tools_size;
     284           0 :                 priv->smu_tables.entry[TOOLSTABLE].table_id = TABLE_PMSTATUSLOG;
     285             :         }
     286             : 
     287             :         /* allocate space for AVFS Fuse table */
     288           0 :         ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
     289             :                         sizeof(AvfsFuseOverride_t),
     290             :                         PAGE_SIZE,
     291             :                         AMDGPU_GEM_DOMAIN_VRAM,
     292             :                         &priv->smu_tables.entry[AVFSFUSETABLE].handle,
     293           0 :                         &priv->smu_tables.entry[AVFSFUSETABLE].mc_addr,
     294             :                         &priv->smu_tables.entry[AVFSFUSETABLE].table);
     295           0 :         if (ret)
     296             :                 goto err3;
     297             : 
     298           0 :         priv->smu_tables.entry[AVFSFUSETABLE].version = 0x01;
     299           0 :         priv->smu_tables.entry[AVFSFUSETABLE].size = sizeof(AvfsFuseOverride_t);
     300           0 :         priv->smu_tables.entry[AVFSFUSETABLE].table_id = TABLE_AVFS_FUSE_OVERRIDE;
     301             : 
     302             : 
     303           0 :         return 0;
     304             : 
     305             : err3:
     306           0 :         if (priv->smu_tables.entry[TOOLSTABLE].table)
     307           0 :                 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TOOLSTABLE].handle,
     308             :                                 &priv->smu_tables.entry[TOOLSTABLE].mc_addr,
     309             :                                 &priv->smu_tables.entry[TOOLSTABLE].table);
     310             : err2:
     311           0 :         amdgpu_bo_free_kernel(&priv->smu_tables.entry[AVFSTABLE].handle,
     312             :                                 &priv->smu_tables.entry[AVFSTABLE].mc_addr,
     313             :                                 &priv->smu_tables.entry[AVFSTABLE].table);
     314             : err1:
     315           0 :         amdgpu_bo_free_kernel(&priv->smu_tables.entry[WMTABLE].handle,
     316             :                                 &priv->smu_tables.entry[WMTABLE].mc_addr,
     317             :                                 &priv->smu_tables.entry[WMTABLE].table);
     318             : err0:
     319           0 :         amdgpu_bo_free_kernel(&priv->smu_tables.entry[PPTABLE].handle,
     320             :                         &priv->smu_tables.entry[PPTABLE].mc_addr,
     321             :                         &priv->smu_tables.entry[PPTABLE].table);
     322             : free_backend:
     323           0 :         kfree(hwmgr->smu_backend);
     324             : 
     325           0 :         return -EINVAL;
     326             : }
     327             : 
     328           0 : static int vega10_smu_fini(struct pp_hwmgr *hwmgr)
     329             : {
     330           0 :         struct vega10_smumgr *priv = hwmgr->smu_backend;
     331             : 
     332           0 :         if (priv) {
     333           0 :                 amdgpu_bo_free_kernel(&priv->smu_tables.entry[PPTABLE].handle,
     334           0 :                                 &priv->smu_tables.entry[PPTABLE].mc_addr,
     335             :                                 &priv->smu_tables.entry[PPTABLE].table);
     336           0 :                 amdgpu_bo_free_kernel(&priv->smu_tables.entry[WMTABLE].handle,
     337           0 :                                         &priv->smu_tables.entry[WMTABLE].mc_addr,
     338             :                                         &priv->smu_tables.entry[WMTABLE].table);
     339           0 :                 amdgpu_bo_free_kernel(&priv->smu_tables.entry[AVFSTABLE].handle,
     340           0 :                                         &priv->smu_tables.entry[AVFSTABLE].mc_addr,
     341             :                                         &priv->smu_tables.entry[AVFSTABLE].table);
     342           0 :                 if (priv->smu_tables.entry[TOOLSTABLE].table)
     343           0 :                         amdgpu_bo_free_kernel(&priv->smu_tables.entry[TOOLSTABLE].handle,
     344           0 :                                         &priv->smu_tables.entry[TOOLSTABLE].mc_addr,
     345             :                                         &priv->smu_tables.entry[TOOLSTABLE].table);
     346           0 :                 amdgpu_bo_free_kernel(&priv->smu_tables.entry[AVFSFUSETABLE].handle,
     347           0 :                                         &priv->smu_tables.entry[AVFSFUSETABLE].mc_addr,
     348             :                                         &priv->smu_tables.entry[AVFSFUSETABLE].table);
     349           0 :                 kfree(hwmgr->smu_backend);
     350           0 :                 hwmgr->smu_backend = NULL;
     351             :         }
     352           0 :         return 0;
     353             : }
     354             : 
     355           0 : static int vega10_start_smu(struct pp_hwmgr *hwmgr)
     356             : {
     357           0 :         if (!smu9_is_smc_ram_running(hwmgr))
     358             :                 return -EINVAL;
     359             : 
     360           0 :         PP_ASSERT_WITH_CODE(!vega10_verify_smc_interface(hwmgr),
     361             :                         "Failed to verify SMC interface!",
     362             :                         return -EINVAL);
     363             : 
     364           0 :         vega10_set_tools_address(hwmgr);
     365             : 
     366           0 :         return 0;
     367             : }
     368             : 
     369           0 : static int vega10_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table,
     370             :                                     uint16_t table_id, bool rw)
     371             : {
     372             :         int ret;
     373             : 
     374           0 :         if (rw)
     375           0 :                 ret = vega10_copy_table_from_smc(hwmgr, table, table_id);
     376             :         else
     377           0 :                 ret = vega10_copy_table_to_smc(hwmgr, table, table_id);
     378             : 
     379           0 :         return ret;
     380             : }
     381             : 
     382             : const struct pp_smumgr_func vega10_smu_funcs = {
     383             :         .name = "vega10_smu",
     384             :         .smu_init = &vega10_smu_init,
     385             :         .smu_fini = &vega10_smu_fini,
     386             :         .start_smu = &vega10_start_smu,
     387             :         .request_smu_load_specific_fw = NULL,
     388             :         .send_msg_to_smc = &smu9_send_msg_to_smc,
     389             :         .send_msg_to_smc_with_parameter = &smu9_send_msg_to_smc_with_parameter,
     390             :         .download_pptable_settings = NULL,
     391             :         .upload_pptable_settings = NULL,
     392             :         .is_dpm_running = vega10_is_dpm_running,
     393             :         .get_argument = smu9_get_argument,
     394             :         .smc_table_manager = vega10_smc_table_manager,
     395             : };

Generated by: LCOV version 1.14