0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
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
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
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