Ejemplo n.º 1
0
/*
 * 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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/*
 * 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);
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
/*
 * 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;
}
Ejemplo n.º 9
0
Archivo: hwmgr.c Proyecto: 020gzh/linux
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;
}
Ejemplo n.º 10
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;
}