drivers/gpu/drm/radeon/rv770_smc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/rv770_smc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/radeon/rv770_smc.c
Extension
.c
Size
15417 bytes
Lines
620
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

while (byte_count > 0) {
			/* SMC address space is BE */
			data = (data << 8) + *src++;
			byte_count--;
		}

		data <<= extra_shift;

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

		ret = rv770_set_smc_sram_address(rdev, addr, limit);
		if (ret)
			goto done;

		WREG32(SMC_SRAM_DATA, data);
	}

done:
	spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);

	return ret;
}

static int rv770_program_interrupt_vectors(struct radeon_device *rdev,
					   u32 smc_first_vector, const u8 *src,
					   u32 byte_count)
{
	u32 tmp, i;

	if (byte_count % 4)
		return -EINVAL;

	if (smc_first_vector < FIRST_SMC_INT_VECT_REG) {
		tmp = FIRST_SMC_INT_VECT_REG - smc_first_vector;

		if (tmp > byte_count)
			return 0;

		byte_count -= tmp;
		src += tmp;
		smc_first_vector = FIRST_SMC_INT_VECT_REG;
	}

	for (i = 0; i < byte_count; i += 4) {
		/* SMC address space is BE */
		tmp = (src[i] << 24) | (src[i + 1] << 16) | (src[i + 2] << 8) | src[i + 3];

		WREG32(SMC_ISR_FFD8_FFDB + i, tmp);
	}

	return 0;
}

void rv770_start_smc(struct radeon_device *rdev)
{
	WREG32_P(SMC_IO, SMC_RST_N, ~SMC_RST_N);
}

void rv770_reset_smc(struct radeon_device *rdev)
{
	WREG32_P(SMC_IO, 0, ~SMC_RST_N);
}

void rv770_stop_smc_clock(struct radeon_device *rdev)
{
	WREG32_P(SMC_IO, 0, ~SMC_CLK_EN);
}

void rv770_start_smc_clock(struct radeon_device *rdev)
{
	WREG32_P(SMC_IO, SMC_CLK_EN, ~SMC_CLK_EN);
}

bool rv770_is_smc_running(struct radeon_device *rdev)
{
	u32 tmp;

	tmp = RREG32(SMC_IO);

	if ((tmp & SMC_RST_N) && (tmp & SMC_CLK_EN))
		return true;
	else
		return false;
}

PPSMC_Result rv770_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg)
{
	u32 tmp;
	int i;
	PPSMC_Result result;

Annotation

Implementation Notes