0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include "amdgpu.h"
0026 #include "cikd.h"
0027 #include "kv_dpm.h"
0028
0029 #include "smu/smu_7_0_0_d.h"
0030 #include "smu/smu_7_0_0_sh_mask.h"
0031
0032 int amdgpu_kv_notify_message_to_smu(struct amdgpu_device *adev, u32 id)
0033 {
0034 u32 i;
0035 u32 tmp = 0;
0036
0037 WREG32(mmSMC_MESSAGE_0, id & SMC_MESSAGE_0__SMC_MSG_MASK);
0038
0039 for (i = 0; i < adev->usec_timeout; i++) {
0040 if ((RREG32(mmSMC_RESP_0) & SMC_RESP_0__SMC_RESP_MASK) != 0)
0041 break;
0042 udelay(1);
0043 }
0044 tmp = RREG32(mmSMC_RESP_0) & SMC_RESP_0__SMC_RESP_MASK;
0045
0046 if (tmp != 1) {
0047 if (tmp == 0xFF)
0048 return -EINVAL;
0049 else if (tmp == 0xFE)
0050 return -EINVAL;
0051 }
0052
0053 return 0;
0054 }
0055
0056 int amdgpu_kv_dpm_get_enable_mask(struct amdgpu_device *adev, u32 *enable_mask)
0057 {
0058 int ret;
0059
0060 ret = amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_SCLKDPM_GetEnabledMask);
0061
0062 if (ret == 0)
0063 *enable_mask = RREG32_SMC(ixSMC_SYSCON_MSG_ARG_0);
0064
0065 return ret;
0066 }
0067
0068 int amdgpu_kv_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
0069 PPSMC_Msg msg, u32 parameter)
0070 {
0071
0072 WREG32(mmSMC_MSG_ARG_0, parameter);
0073
0074 return amdgpu_kv_notify_message_to_smu(adev, msg);
0075 }
0076
0077 static int kv_set_smc_sram_address(struct amdgpu_device *adev,
0078 u32 smc_address, u32 limit)
0079 {
0080 if (smc_address & 3)
0081 return -EINVAL;
0082 if ((smc_address + 3) > limit)
0083 return -EINVAL;
0084
0085 WREG32(mmSMC_IND_INDEX_0, smc_address);
0086 WREG32_P(mmSMC_IND_ACCESS_CNTL, 0,
0087 ~SMC_IND_ACCESS_CNTL__AUTO_INCREMENT_IND_0_MASK);
0088
0089 return 0;
0090 }
0091
0092 int amdgpu_kv_read_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
0093 u32 *value, u32 limit)
0094 {
0095 int ret;
0096
0097 ret = kv_set_smc_sram_address(adev, smc_address, limit);
0098 if (ret)
0099 return ret;
0100
0101 *value = RREG32(mmSMC_IND_DATA_0);
0102 return 0;
0103 }
0104
0105 int amdgpu_kv_smc_dpm_enable(struct amdgpu_device *adev, bool enable)
0106 {
0107 if (enable)
0108 return amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_DPM_Enable);
0109 else
0110 return amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_DPM_Disable);
0111 }
0112
0113 int amdgpu_kv_smc_bapm_enable(struct amdgpu_device *adev, bool enable)
0114 {
0115 if (enable)
0116 return amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_EnableBAPM);
0117 else
0118 return amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_DisableBAPM);
0119 }
0120
0121 int amdgpu_kv_copy_bytes_to_smc(struct amdgpu_device *adev,
0122 u32 smc_start_address,
0123 const u8 *src, u32 byte_count, u32 limit)
0124 {
0125 int ret;
0126 u32 data, original_data, addr, extra_shift, t_byte, count, mask;
0127
0128 if ((smc_start_address + byte_count) > limit)
0129 return -EINVAL;
0130
0131 addr = smc_start_address;
0132 t_byte = addr & 3;
0133
0134
0135 if (t_byte != 0) {
0136 addr -= t_byte;
0137
0138 ret = kv_set_smc_sram_address(adev, addr, limit);
0139 if (ret)
0140 return ret;
0141
0142 original_data = RREG32(mmSMC_IND_DATA_0);
0143
0144 data = 0;
0145 mask = 0;
0146 count = 4;
0147 while (count > 0) {
0148 if (t_byte > 0) {
0149 mask = (mask << 8) | 0xff;
0150 t_byte--;
0151 } else if (byte_count > 0) {
0152 data = (data << 8) + *src++;
0153 byte_count--;
0154 mask <<= 8;
0155 } else {
0156 data <<= 8;
0157 mask = (mask << 8) | 0xff;
0158 }
0159 count--;
0160 }
0161
0162 data |= original_data & mask;
0163
0164 ret = kv_set_smc_sram_address(adev, addr, limit);
0165 if (ret)
0166 return ret;
0167
0168 WREG32(mmSMC_IND_DATA_0, data);
0169
0170 addr += 4;
0171 }
0172
0173 while (byte_count >= 4) {
0174
0175 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
0176
0177 ret = kv_set_smc_sram_address(adev, addr, limit);
0178 if (ret)
0179 return ret;
0180
0181 WREG32(mmSMC_IND_DATA_0, data);
0182
0183 src += 4;
0184 byte_count -= 4;
0185 addr += 4;
0186 }
0187
0188
0189 if (byte_count > 0) {
0190 data = 0;
0191
0192 ret = kv_set_smc_sram_address(adev, addr, limit);
0193 if (ret)
0194 return ret;
0195
0196 original_data = RREG32(mmSMC_IND_DATA_0);
0197
0198 extra_shift = 8 * (4 - byte_count);
0199
0200 while (byte_count > 0) {
0201
0202 data = (data << 8) + *src++;
0203 byte_count--;
0204 }
0205
0206 data <<= extra_shift;
0207
0208 data |= (original_data & ~((~0UL) << extra_shift));
0209
0210 ret = kv_set_smc_sram_address(adev, addr, limit);
0211 if (ret)
0212 return ret;
0213
0214 WREG32(mmSMC_IND_DATA_0, data);
0215 }
0216 return 0;
0217 }
0218