Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2016 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #include <linux/pci.h>
0025 
0026 #include "smumgr.h"
0027 #include "smu10_inc.h"
0028 #include "soc15_common.h"
0029 #include "smu10_smumgr.h"
0030 #include "ppatomctrl.h"
0031 #include "rv_ppsmc.h"
0032 #include "smu10_driver_if.h"
0033 #include "smu10.h"
0034 #include "pp_debug.h"
0035 
0036 
0037 #define BUFFER_SIZE                 80000
0038 #define MAX_STRING_SIZE             15
0039 #define BUFFER_SIZETWO              131072
0040 
0041 #define MP0_Public                  0x03800000
0042 #define MP0_SRAM                    0x03900000
0043 #define MP1_Public                  0x03b00000
0044 #define MP1_SRAM                    0x03c00004
0045 
0046 #define smnMP1_FIRMWARE_FLAGS       0x3010028
0047 
0048 
0049 static uint32_t smu10_wait_for_response(struct pp_hwmgr *hwmgr)
0050 {
0051     struct amdgpu_device *adev = hwmgr->adev;
0052     uint32_t reg;
0053 
0054     reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
0055 
0056     phm_wait_for_register_unequal(hwmgr, reg,
0057             0, MP1_C2PMSG_90__CONTENT_MASK);
0058 
0059     return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
0060 }
0061 
0062 static int smu10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
0063         uint16_t msg)
0064 {
0065     struct amdgpu_device *adev = hwmgr->adev;
0066 
0067     WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);
0068 
0069     return 0;
0070 }
0071 
0072 static uint32_t smu10_read_arg_from_smc(struct pp_hwmgr *hwmgr)
0073 {
0074     struct amdgpu_device *adev = hwmgr->adev;
0075 
0076     return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
0077 }
0078 
0079 static int smu10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
0080 {
0081     struct amdgpu_device *adev = hwmgr->adev;
0082 
0083     smu10_wait_for_response(hwmgr);
0084 
0085     WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
0086 
0087     smu10_send_msg_to_smc_without_waiting(hwmgr, msg);
0088 
0089     if (smu10_wait_for_response(hwmgr) == 0)
0090         dev_err(adev->dev, "Failed to send Message %x.\n", msg);
0091 
0092     return 0;
0093 }
0094 
0095 
0096 static int smu10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
0097         uint16_t msg, uint32_t parameter)
0098 {
0099     struct amdgpu_device *adev = hwmgr->adev;
0100 
0101     smu10_wait_for_response(hwmgr);
0102 
0103     WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
0104 
0105     WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter);
0106 
0107     smu10_send_msg_to_smc_without_waiting(hwmgr, msg);
0108 
0109 
0110     if (smu10_wait_for_response(hwmgr) == 0)
0111         dev_err(adev->dev, "Failed to send Message %x.\n", msg);
0112 
0113     return 0;
0114 }
0115 
0116 static int smu10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
0117         uint8_t *table, int16_t table_id)
0118 {
0119     struct smu10_smumgr *priv =
0120             (struct smu10_smumgr *)(hwmgr->smu_backend);
0121     struct amdgpu_device *adev = hwmgr->adev;
0122 
0123     PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
0124             "Invalid SMU Table ID!", return -EINVAL;);
0125     PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
0126             "Invalid SMU Table version!", return -EINVAL;);
0127     PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
0128             "Invalid SMU Table Length!", return -EINVAL;);
0129     smum_send_msg_to_smc_with_parameter(hwmgr,
0130             PPSMC_MSG_SetDriverDramAddrHigh,
0131             upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
0132             NULL);
0133     smum_send_msg_to_smc_with_parameter(hwmgr,
0134             PPSMC_MSG_SetDriverDramAddrLow,
0135             lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
0136             NULL);
0137     smum_send_msg_to_smc_with_parameter(hwmgr,
0138             PPSMC_MSG_TransferTableSmu2Dram,
0139             priv->smu_tables.entry[table_id].table_id,
0140             NULL);
0141 
0142     amdgpu_asic_invalidate_hdp(adev, NULL);
0143 
0144     memcpy(table, (uint8_t *)priv->smu_tables.entry[table_id].table,
0145             priv->smu_tables.entry[table_id].size);
0146 
0147     return 0;
0148 }
0149 
0150 static int smu10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
0151         uint8_t *table, int16_t table_id)
0152 {
0153     struct smu10_smumgr *priv =
0154             (struct smu10_smumgr *)(hwmgr->smu_backend);
0155     struct amdgpu_device *adev = hwmgr->adev;
0156 
0157     PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
0158             "Invalid SMU Table ID!", return -EINVAL;);
0159     PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
0160             "Invalid SMU Table version!", return -EINVAL;);
0161     PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
0162             "Invalid SMU Table Length!", return -EINVAL;);
0163 
0164     memcpy(priv->smu_tables.entry[table_id].table, table,
0165             priv->smu_tables.entry[table_id].size);
0166 
0167     amdgpu_asic_flush_hdp(adev, NULL);
0168 
0169     smum_send_msg_to_smc_with_parameter(hwmgr,
0170             PPSMC_MSG_SetDriverDramAddrHigh,
0171             upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
0172             NULL);
0173     smum_send_msg_to_smc_with_parameter(hwmgr,
0174             PPSMC_MSG_SetDriverDramAddrLow,
0175             lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
0176             NULL);
0177     smum_send_msg_to_smc_with_parameter(hwmgr,
0178             PPSMC_MSG_TransferTableDram2Smu,
0179             priv->smu_tables.entry[table_id].table_id,
0180             NULL);
0181 
0182     return 0;
0183 }
0184 
0185 static int smu10_verify_smc_interface(struct pp_hwmgr *hwmgr)
0186 {
0187     uint32_t smc_driver_if_version;
0188 
0189     smum_send_msg_to_smc(hwmgr,
0190             PPSMC_MSG_GetDriverIfVersion,
0191             &smc_driver_if_version);
0192 
0193     if ((smc_driver_if_version != SMU10_DRIVER_IF_VERSION) &&
0194         (smc_driver_if_version != SMU10_DRIVER_IF_VERSION + 1)) {
0195         pr_err("Attempt to read SMC IF Version Number Failed!\n");
0196         return -EINVAL;
0197     }
0198 
0199     return 0;
0200 }
0201 
0202 static int smu10_smu_fini(struct pp_hwmgr *hwmgr)
0203 {
0204     struct smu10_smumgr *priv =
0205             (struct smu10_smumgr *)(hwmgr->smu_backend);
0206 
0207     if (priv) {
0208         amdgpu_bo_free_kernel(&priv->smu_tables.entry[SMU10_WMTABLE].handle,
0209                     &priv->smu_tables.entry[SMU10_WMTABLE].mc_addr,
0210                     &priv->smu_tables.entry[SMU10_WMTABLE].table);
0211         amdgpu_bo_free_kernel(&priv->smu_tables.entry[SMU10_CLOCKTABLE].handle,
0212                     &priv->smu_tables.entry[SMU10_CLOCKTABLE].mc_addr,
0213                     &priv->smu_tables.entry[SMU10_CLOCKTABLE].table);
0214         kfree(hwmgr->smu_backend);
0215         hwmgr->smu_backend = NULL;
0216     }
0217 
0218     return 0;
0219 }
0220 
0221 static int smu10_start_smu(struct pp_hwmgr *hwmgr)
0222 {
0223     struct amdgpu_device *adev = hwmgr->adev;
0224 
0225     smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion, &hwmgr->smu_version);
0226     adev->pm.fw_version = hwmgr->smu_version >> 8;
0227 
0228     if (!(adev->apu_flags & AMD_APU_IS_RAVEN2) &&
0229         (adev->apu_flags & AMD_APU_IS_RAVEN) &&
0230         adev->pm.fw_version < 0x1e45)
0231         adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
0232 
0233     if (smu10_verify_smc_interface(hwmgr))
0234         return -EINVAL;
0235 
0236     return 0;
0237 }
0238 
0239 static int smu10_smu_init(struct pp_hwmgr *hwmgr)
0240 {
0241     struct smu10_smumgr *priv;
0242     int r;
0243 
0244     priv = kzalloc(sizeof(struct smu10_smumgr), GFP_KERNEL);
0245 
0246     if (!priv)
0247         return -ENOMEM;
0248 
0249     hwmgr->smu_backend = priv;
0250 
0251     /* allocate space for watermarks table */
0252     r = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
0253             sizeof(Watermarks_t),
0254             PAGE_SIZE,
0255             AMDGPU_GEM_DOMAIN_VRAM,
0256             &priv->smu_tables.entry[SMU10_WMTABLE].handle,
0257             &priv->smu_tables.entry[SMU10_WMTABLE].mc_addr,
0258             &priv->smu_tables.entry[SMU10_WMTABLE].table);
0259 
0260     if (r)
0261         goto err0;
0262 
0263     priv->smu_tables.entry[SMU10_WMTABLE].version = 0x01;
0264     priv->smu_tables.entry[SMU10_WMTABLE].size = sizeof(Watermarks_t);
0265     priv->smu_tables.entry[SMU10_WMTABLE].table_id = TABLE_WATERMARKS;
0266 
0267     /* allocate space for watermarks table */
0268     r = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
0269             sizeof(DpmClocks_t),
0270             PAGE_SIZE,
0271             AMDGPU_GEM_DOMAIN_VRAM,
0272             &priv->smu_tables.entry[SMU10_CLOCKTABLE].handle,
0273             &priv->smu_tables.entry[SMU10_CLOCKTABLE].mc_addr,
0274             &priv->smu_tables.entry[SMU10_CLOCKTABLE].table);
0275 
0276     if (r)
0277         goto err1;
0278 
0279     priv->smu_tables.entry[SMU10_CLOCKTABLE].version = 0x01;
0280     priv->smu_tables.entry[SMU10_CLOCKTABLE].size = sizeof(DpmClocks_t);
0281     priv->smu_tables.entry[SMU10_CLOCKTABLE].table_id = TABLE_DPMCLOCKS;
0282 
0283     return 0;
0284 
0285 err1:
0286     amdgpu_bo_free_kernel(&priv->smu_tables.entry[SMU10_WMTABLE].handle,
0287                 &priv->smu_tables.entry[SMU10_WMTABLE].mc_addr,
0288                 &priv->smu_tables.entry[SMU10_WMTABLE].table);
0289 err0:
0290     kfree(priv);
0291     return -EINVAL;
0292 }
0293 
0294 static int smu10_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t table_id, bool rw)
0295 {
0296     int ret;
0297 
0298     if (rw)
0299         ret = smu10_copy_table_from_smc(hwmgr, table, table_id);
0300     else
0301         ret = smu10_copy_table_to_smc(hwmgr, table, table_id);
0302 
0303     return ret;
0304 }
0305 
0306 
0307 const struct pp_smumgr_func smu10_smu_funcs = {
0308     .name = "smu10_smu",
0309     .smu_init = &smu10_smu_init,
0310     .smu_fini = &smu10_smu_fini,
0311     .start_smu = &smu10_start_smu,
0312     .request_smu_load_specific_fw = NULL,
0313     .send_msg_to_smc = &smu10_send_msg_to_smc,
0314     .send_msg_to_smc_with_parameter = &smu10_send_msg_to_smc_with_parameter,
0315     .download_pptable_settings = NULL,
0316     .upload_pptable_settings = NULL,
0317     .get_argument = smu10_read_arg_from_smc,
0318     .smc_table_manager = smu10_smc_table_manager,
0319 };
0320 
0321