Ejemplo n.º 1
0
int ci_copy_bytes_to_smc(struct radeon_device *rdev,
			 u32 smc_start_address,
			 const u8 *src, u32 byte_count, u32 limit)
{
	u32 data, original_data;
	u32 addr;
	u32 extra_shift;
	int ret;

	if (smc_start_address & 3)
		return -EINVAL;
	if ((smc_start_address + byte_count) > limit)
		return -EINVAL;

	addr = smc_start_address;

	while (byte_count >= 4) {
		/* SMC address space is BE */
		data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];

		ret = ci_set_smc_sram_address(rdev, addr, limit);
		if (ret)
			return ret;

		WREG32(SMC_IND_DATA_0, data);

		src += 4;
		byte_count -= 4;
		addr += 4;
	}

	/* RMW for the final bytes */
	if (byte_count > 0) {
		data = 0;

		ret = ci_set_smc_sram_address(rdev, addr, limit);
		if (ret)
			return ret;

		original_data = RREG32(SMC_IND_DATA_0);

		extra_shift = 8 * (4 - byte_count);

		while (byte_count > 0) {
			data = (data << 8) + *src++;
			byte_count--;
		}

		data <<= extra_shift;

		data |= (original_data & ~((~0UL) << extra_shift));

		ret = ci_set_smc_sram_address(rdev, addr, limit);
		if (ret)
			return ret;

		WREG32(SMC_IND_DATA_0, data);
	}
	return 0;
}
Ejemplo n.º 2
0
int ci_read_smc_sram_dword(struct radeon_device *rdev,
			   u32 smc_address, u32 *value, u32 limit)
{
	int ret;

	ret = ci_set_smc_sram_address(rdev, smc_address, limit);
	if (ret)
		return ret;

	*value = RREG32(SMC_IND_DATA_0);
	return 0;
}
Ejemplo n.º 3
0
int ci_write_smc_sram_dword(struct radeon_device *rdev,
			    u32 smc_address, u32 value, u32 limit)
{
	int ret;

	ret = ci_set_smc_sram_address(rdev, smc_address, limit);
	if (ret)
		return ret;

	WREG32(SMC_IND_DATA_0, value);
	return 0;
}
Ejemplo n.º 4
0
int ci_write_smc_sram_dword(struct radeon_device *rdev,
			    u32 smc_address, u32 value, u32 limit)
{
	int ret;

	spin_lock(&rdev->smc_idx_lock);
	ret = ci_set_smc_sram_address(rdev, smc_address, limit);
	if (ret == 0)
		WREG32(SMC_IND_DATA_0, value);
	spin_unlock(&rdev->smc_idx_lock);

	return ret;
}
Ejemplo n.º 5
0
int ci_write_smc_sram_dword(struct radeon_device *rdev,
			    u32 smc_address, u32 value, u32 limit)
{
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&rdev->smc_idx_lock, flags);
	ret = ci_set_smc_sram_address(rdev, smc_address, limit);
	if (ret == 0)
		WREG32(SMC_IND_DATA_0, value);
	spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);

	return ret;
}