/* * Retrieve an argument from SMC. * @param smumgr the address of the powerplay hardware manager. * @param arg pointer to store the argument from SMC. * @return Always return 0. */ int vega10_read_arg_from_smc(struct pp_smumgr *smumgr, uint32_t *arg) { uint32_t reg; reg = soc15_get_register_offset(MP1_HWID, 0, mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82); *arg = cgs_read_register(smumgr->device, reg); return 0; }
/* power off a tile/block within ACP */ static int acp_suspend_tile(void *cgs_dev, int tile) { u32 val = 0; u32 count = 0; if ((tile < ACP_TILE_P1) || (tile > ACP_TILE_DSP2)) { pr_err("Invalid ACP tile : %d to suspend\n", tile); return -1; } val = cgs_read_register(cgs_dev, mmACP_PGFSM_READ_REG_0 + tile); val &= ACP_TILE_ON_MASK; if (val == 0x0) { val = cgs_read_register(cgs_dev, mmACP_PGFSM_RETAIN_REG); val = val | (1 << tile); cgs_write_register(cgs_dev, mmACP_PGFSM_RETAIN_REG, val); cgs_write_register(cgs_dev, mmACP_PGFSM_CONFIG_REG, 0x500 + tile); count = ACP_TIMEOUT_LOOP; while (true) { val = cgs_read_register(cgs_dev, mmACP_PGFSM_READ_REG_0 + tile); val = val & ACP_TILE_ON_MASK; if (val == ACP_TILE_OFF_MASK) break; if (--count == 0) { pr_err("Timeout reading ACP PGFSM status\n"); return -ETIMEDOUT; } udelay(100); } val = cgs_read_register(cgs_dev, mmACP_PGFSM_RETAIN_REG); val |= ACP_TILE_OFF_RETAIN_REG_MASK; cgs_write_register(cgs_dev, mmACP_PGFSM_RETAIN_REG, val); } return 0; }
/* power on a tile/block within ACP */ static int acp_resume_tile(void *cgs_dev, int tile) { u32 val = 0; u32 count = 0; if ((tile < ACP_TILE_P1) || (tile > ACP_TILE_DSP2)) { pr_err("Invalid ACP tile to resume\n"); return -1; } val = cgs_read_register(cgs_dev, mmACP_PGFSM_READ_REG_0 + tile); val = val & ACP_TILE_ON_MASK; if (val != 0x0) { cgs_write_register(cgs_dev, mmACP_PGFSM_CONFIG_REG, 0x600 + tile); count = ACP_TIMEOUT_LOOP; while (true) { val = cgs_read_register(cgs_dev, mmACP_PGFSM_READ_REG_0 + tile); val = val & ACP_TILE_ON_MASK; if (val == 0x0) break; if (--count == 0) { pr_err("Timeout reading ACP PGFSM status\n"); return -ETIMEDOUT; } udelay(100); } val = cgs_read_register(cgs_dev, mmACP_PGFSM_RETAIN_REG); if (tile == ACP_TILE_P1) val = val & (ACP_TILE_P1_MASK); else if (tile == ACP_TILE_P2) val = val & (ACP_TILE_P2_MASK); cgs_write_register(cgs_dev, mmACP_PGFSM_RETAIN_REG, val); } return 0; }
static int rv_thermal_get_temperature(struct pp_hwmgr *hwmgr) { uint32_t reg_offset = soc15_get_register_offset(THM_HWID, 0, mmTHM_TCON_CUR_TMP_BASE_IDX, mmTHM_TCON_CUR_TMP); uint32_t reg_value = cgs_read_register(hwmgr->device, reg_offset); int cur_temp = (reg_value & THM_TCON_CUR_TMP__CUR_TEMP_MASK) >> THM_TCON_CUR_TMP__CUR_TEMP__SHIFT; if (cur_temp & THM_TCON_CUR_TMP__CUR_TEMP_RANGE_SEL_MASK) cur_temp = ((cur_temp / 8) - 49) * PP_TEMPERATURE_UNITS_PER_CENTIGRADES; else cur_temp = (cur_temp / 8) * PP_TEMPERATURE_UNITS_PER_CENTIGRADES; return cur_temp; }
/* * Check if SMC has responded to previous message. * * @param smumgr the address of the powerplay hardware manager. * @return TRUE SMC has responded, FALSE otherwise. */ static uint32_t vega10_wait_for_response(struct pp_smumgr *smumgr) { uint32_t reg; if (!vega10_is_smc_ram_running(smumgr)) return -EINVAL; reg = soc15_get_register_offset(MP1_HWID, 0, mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90); smum_wait_for_register_unequal(smumgr, reg, 0, MP1_C2PMSG_90__CONTENT_MASK); return cgs_read_register(smumgr->device, reg); }
uint32_t dm_read_reg_func( const struct dc_context *ctx, uint32_t address, const char *func_name) { uint32_t value; #ifdef DM_CHECK_ADDR_0 if (address == 0) { DC_ERR("invalid register read; address = 0\n"); return 0; } #endif value = cgs_read_register(ctx->cgs_device, address); trace_amdgpu_dc_rreg(&ctx->perf_trace->read_count, address, value); return value; }
static bool vega10_is_smc_ram_running(struct pp_smumgr *smumgr) { uint32_t mp1_fw_flags, reg; reg = soc15_get_register_offset(NBIF_HWID, 0, mmPCIE_INDEX2_BASE_IDX, mmPCIE_INDEX2); cgs_write_register(smumgr->device, reg, (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); reg = soc15_get_register_offset(NBIF_HWID, 0, mmPCIE_DATA2_BASE_IDX, mmPCIE_DATA2); mp1_fw_flags = cgs_read_register(smumgr->device, reg); if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) return true; return false; }
/* * Returns once the part of the register indicated by the mask has * reached the given value. */ int smum_wait_on_register(struct pp_smumgr *smumgr, uint32_t index, uint32_t value, uint32_t mask) { uint32_t i; uint32_t cur_value; if (smumgr == NULL || smumgr->device == NULL) return -EINVAL; for (i = 0; i < smumgr->usec_timeout; i++) { cur_value = cgs_read_register(smumgr->device, index); if ((cur_value & mask) == (value & mask)) break; udelay(1); } /* timeout means wrong logic*/ if (i == smumgr->usec_timeout) return -1; return 0; }
int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr, uint32_t index, uint32_t value, uint32_t mask) { uint32_t i; uint32_t cur_value; if (hwmgr == NULL || hwmgr->device == NULL) { printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!"); return -EINVAL; } for (i = 0; i < hwmgr->usec_timeout; i++) { cur_value = cgs_read_register(hwmgr->device, index); if ((cur_value & mask) != (value & mask)) break; udelay(1); } /* timeout means wrong logic*/ if (i == hwmgr->usec_timeout) return -1; return 0; }
int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr, uint32_t index, uint32_t value, uint32_t mask) { uint32_t i; uint32_t cur_value; if (hwmgr == NULL || hwmgr->device == NULL) return -EINVAL; for (i = 0; i < hwmgr->usec_timeout; i++) { cur_value = cgs_read_register(hwmgr->device, index); if ((cur_value & mask) != (value & mask)) break; udelay(1); } /* timeout means wrong logic */ if (i == hwmgr->usec_timeout) return -ETIME; return 0; }