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 "common_baco.h"
0025
0026
0027 static bool baco_wait_register(struct pp_hwmgr *hwmgr, u32 reg, u32 mask, u32 value)
0028 {
0029 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0030 u32 timeout = 5000, data;
0031
0032 do {
0033 msleep(1);
0034 data = RREG32(reg);
0035 timeout--;
0036 } while (value != (data & mask) && (timeout != 0));
0037
0038 if (timeout == 0)
0039 return false;
0040
0041 return true;
0042 }
0043
0044 static bool baco_cmd_handler(struct pp_hwmgr *hwmgr, u32 command, u32 reg, u32 mask,
0045 u32 shift, u32 value, u32 timeout)
0046 {
0047 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0048 u32 data;
0049 bool ret = true;
0050
0051 switch (command) {
0052 case CMD_WRITE:
0053 WREG32(reg, value << shift);
0054 break;
0055 case CMD_READMODIFYWRITE:
0056 data = RREG32(reg);
0057 data = (data & (~mask)) | (value << shift);
0058 WREG32(reg, data);
0059 break;
0060 case CMD_WAITFOR:
0061 ret = baco_wait_register(hwmgr, reg, mask, value);
0062 break;
0063 case CMD_DELAY_MS:
0064 if (timeout)
0065
0066 msleep(timeout);
0067 break;
0068 case CMD_DELAY_US:
0069 if (timeout)
0070
0071 udelay(timeout);
0072 break;
0073
0074 default:
0075 dev_warn(adev->dev, "Invalid BACO command.\n");
0076 ret = false;
0077 }
0078
0079 return ret;
0080 }
0081
0082 bool baco_program_registers(struct pp_hwmgr *hwmgr,
0083 const struct baco_cmd_entry *entry,
0084 const u32 array_size)
0085 {
0086 u32 i, reg = 0;
0087
0088 for (i = 0; i < array_size; i++) {
0089 if ((entry[i].cmd == CMD_WRITE) ||
0090 (entry[i].cmd == CMD_READMODIFYWRITE) ||
0091 (entry[i].cmd == CMD_WAITFOR))
0092 reg = entry[i].reg_offset;
0093 if (!baco_cmd_handler(hwmgr, entry[i].cmd, reg, entry[i].mask,
0094 entry[i].shift, entry[i].val, entry[i].timeout))
0095 return false;
0096 }
0097
0098 return true;
0099 }
0100
0101 bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr,
0102 const struct soc15_baco_cmd_entry *entry,
0103 const u32 array_size)
0104 {
0105 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0106 u32 i, reg = 0;
0107
0108 for (i = 0; i < array_size; i++) {
0109 if ((entry[i].cmd == CMD_WRITE) ||
0110 (entry[i].cmd == CMD_READMODIFYWRITE) ||
0111 (entry[i].cmd == CMD_WAITFOR))
0112 reg = adev->reg_offset[entry[i].hwip][entry[i].inst][entry[i].seg]
0113 + entry[i].reg_offset;
0114 if (!baco_cmd_handler(hwmgr, entry[i].cmd, reg, entry[i].mask,
0115 entry[i].shift, entry[i].val, entry[i].timeout))
0116 return false;
0117 }
0118
0119 return true;
0120 }