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 "radeon.h"
0025 #include "sumod.h"
0026 #include "sumo_dpm.h"
0027 #include "ppsmc.h"
0028
0029 #define SUMO_SMU_SERVICE_ROUTINE_PG_INIT 1
0030 #define SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY 27
0031 #define SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20 20
0032
0033 static void sumo_send_msg_to_smu(struct radeon_device *rdev, u32 id)
0034 {
0035 u32 gfx_int_req;
0036 int i;
0037
0038 for (i = 0; i < rdev->usec_timeout; i++) {
0039 if (RREG32(GFX_INT_STATUS) & INT_DONE)
0040 break;
0041 udelay(1);
0042 }
0043
0044 gfx_int_req = SERV_INDEX(id) | INT_REQ;
0045 WREG32(GFX_INT_REQ, gfx_int_req);
0046
0047 for (i = 0; i < rdev->usec_timeout; i++) {
0048 if (RREG32(GFX_INT_REQ) & INT_REQ)
0049 break;
0050 udelay(1);
0051 }
0052
0053 for (i = 0; i < rdev->usec_timeout; i++) {
0054 if (RREG32(GFX_INT_STATUS) & INT_ACK)
0055 break;
0056 udelay(1);
0057 }
0058
0059 for (i = 0; i < rdev->usec_timeout; i++) {
0060 if (RREG32(GFX_INT_STATUS) & INT_DONE)
0061 break;
0062 udelay(1);
0063 }
0064
0065 gfx_int_req &= ~INT_REQ;
0066 WREG32(GFX_INT_REQ, gfx_int_req);
0067 }
0068
0069 void sumo_initialize_m3_arb(struct radeon_device *rdev)
0070 {
0071 struct sumo_power_info *pi = sumo_get_pi(rdev);
0072 u32 i;
0073
0074 if (!pi->enable_dynamic_m3_arbiter)
0075 return;
0076
0077 for (i = 0; i < NUMBER_OF_M3ARB_PARAM_SETS; i++)
0078 WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
0079 pi->sys_info.csr_m3_arb_cntl_default[i]);
0080
0081 for (; i < NUMBER_OF_M3ARB_PARAM_SETS * 2; i++)
0082 WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
0083 pi->sys_info.csr_m3_arb_cntl_uvd[i % NUMBER_OF_M3ARB_PARAM_SETS]);
0084
0085 for (; i < NUMBER_OF_M3ARB_PARAM_SETS * 3; i++)
0086 WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
0087 pi->sys_info.csr_m3_arb_cntl_fs3d[i % NUMBER_OF_M3ARB_PARAM_SETS]);
0088 }
0089
0090 static bool sumo_is_alt_vddnb_supported(struct radeon_device *rdev)
0091 {
0092 struct sumo_power_info *pi = sumo_get_pi(rdev);
0093 bool return_code = false;
0094
0095 if (!pi->enable_alt_vddnb)
0096 return return_code;
0097
0098 if ((rdev->family == CHIP_SUMO) || (rdev->family == CHIP_SUMO2)) {
0099 if (pi->fw_version >= 0x00010C00)
0100 return_code = true;
0101 }
0102
0103 return return_code;
0104 }
0105
0106 void sumo_smu_notify_alt_vddnb_change(struct radeon_device *rdev,
0107 bool powersaving, bool force_nbps1)
0108 {
0109 u32 param = 0;
0110
0111 if (!sumo_is_alt_vddnb_supported(rdev))
0112 return;
0113
0114 if (powersaving)
0115 param |= 1;
0116
0117 if (force_nbps1)
0118 param |= 2;
0119
0120 WREG32_RCU(RCU_ALTVDDNB_NOTIFY, param);
0121
0122 sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY);
0123 }
0124
0125 void sumo_smu_pg_init(struct radeon_device *rdev)
0126 {
0127 sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_PG_INIT);
0128 }
0129
0130 static u32 sumo_power_of_4(u32 unit)
0131 {
0132 u32 ret = 1;
0133 u32 i;
0134
0135 for (i = 0; i < unit; i++)
0136 ret *= 4;
0137
0138 return ret;
0139 }
0140
0141 void sumo_enable_boost_timer(struct radeon_device *rdev)
0142 {
0143 struct sumo_power_info *pi = sumo_get_pi(rdev);
0144 u32 period, unit, timer_value;
0145 u32 xclk = radeon_get_xclk(rdev);
0146
0147 unit = (RREG32_RCU(RCU_LCLK_SCALING_CNTL) & LCLK_SCALING_TIMER_PRESCALER_MASK)
0148 >> LCLK_SCALING_TIMER_PRESCALER_SHIFT;
0149
0150 period = 100 * (xclk / 100 / sumo_power_of_4(unit));
0151
0152 timer_value = (period << 16) | (unit << 4);
0153
0154 WREG32_RCU(RCU_GNB_PWR_REP_TIMER_CNTL, timer_value);
0155 WREG32_RCU(RCU_BOOST_MARGIN, pi->sys_info.sclk_dpm_boost_margin);
0156 WREG32_RCU(RCU_THROTTLE_MARGIN, pi->sys_info.sclk_dpm_throttle_margin);
0157 WREG32_RCU(GNB_TDP_LIMIT, pi->sys_info.gnb_tdp_limit);
0158 WREG32_RCU(RCU_SclkDpmTdpLimitPG, pi->sys_info.sclk_dpm_tdp_limit_pg);
0159
0160 sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20);
0161 }
0162
0163 void sumo_set_tdp_limit(struct radeon_device *rdev, u32 index, u32 tdp_limit)
0164 {
0165 u32 regoffset = 0;
0166 u32 shift = 0;
0167 u32 mask = 0xFFF;
0168 u32 sclk_dpm_tdp_limit;
0169
0170 switch (index) {
0171 case 0:
0172 regoffset = RCU_SclkDpmTdpLimit01;
0173 shift = 16;
0174 break;
0175 case 1:
0176 regoffset = RCU_SclkDpmTdpLimit01;
0177 shift = 0;
0178 break;
0179 case 2:
0180 regoffset = RCU_SclkDpmTdpLimit23;
0181 shift = 16;
0182 break;
0183 case 3:
0184 regoffset = RCU_SclkDpmTdpLimit23;
0185 shift = 0;
0186 break;
0187 case 4:
0188 regoffset = RCU_SclkDpmTdpLimit47;
0189 shift = 16;
0190 break;
0191 case 7:
0192 regoffset = RCU_SclkDpmTdpLimit47;
0193 shift = 0;
0194 break;
0195 default:
0196 break;
0197 }
0198
0199 sclk_dpm_tdp_limit = RREG32_RCU(regoffset);
0200 sclk_dpm_tdp_limit &= ~(mask << shift);
0201 sclk_dpm_tdp_limit |= (tdp_limit << shift);
0202 WREG32_RCU(regoffset, sclk_dpm_tdp_limit);
0203 }
0204
0205 void sumo_boost_state_enable(struct radeon_device *rdev, bool enable)
0206 {
0207 u32 boost_disable = RREG32_RCU(RCU_GPU_BOOST_DISABLE);
0208
0209 boost_disable &= 0xFFFFFFFE;
0210 boost_disable |= (enable ? 0 : 1);
0211 WREG32_RCU(RCU_GPU_BOOST_DISABLE, boost_disable);
0212 }
0213
0214 u32 sumo_get_running_fw_version(struct radeon_device *rdev)
0215 {
0216 return RREG32_RCU(RCU_FW_VERSION);
0217 }
0218