|
@@ -274,8 +274,8 @@ static const u8 cayman_smc_int_vectors[] =
|
|
0x08, 0x72, 0x08, 0x72
|
|
0x08, 0x72, 0x08, 0x72
|
|
};
|
|
};
|
|
|
|
|
|
-int rv770_set_smc_sram_address(struct radeon_device *rdev,
|
|
|
|
- u16 smc_address, u16 limit)
|
|
|
|
|
|
+static int rv770_set_smc_sram_address(struct radeon_device *rdev,
|
|
|
|
+ u16 smc_address, u16 limit)
|
|
{
|
|
{
|
|
u32 addr;
|
|
u32 addr;
|
|
|
|
|
|
@@ -296,9 +296,10 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
|
|
u16 smc_start_address, const u8 *src,
|
|
u16 smc_start_address, const u8 *src,
|
|
u16 byte_count, u16 limit)
|
|
u16 byte_count, u16 limit)
|
|
{
|
|
{
|
|
|
|
+ unsigned long flags;
|
|
u32 data, original_data, extra_shift;
|
|
u32 data, original_data, extra_shift;
|
|
u16 addr;
|
|
u16 addr;
|
|
- int ret;
|
|
|
|
|
|
+ int ret = 0;
|
|
|
|
|
|
if (smc_start_address & 3)
|
|
if (smc_start_address & 3)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -307,13 +308,14 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
|
|
|
|
|
|
addr = smc_start_address;
|
|
addr = smc_start_address;
|
|
|
|
|
|
|
|
+ spin_lock_irqsave(&rdev->smc_idx_lock, flags);
|
|
while (byte_count >= 4) {
|
|
while (byte_count >= 4) {
|
|
/* SMC address space is BE */
|
|
/* SMC address space is BE */
|
|
data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
|
|
data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
|
|
|
|
|
|
ret = rv770_set_smc_sram_address(rdev, addr, limit);
|
|
ret = rv770_set_smc_sram_address(rdev, addr, limit);
|
|
if (ret)
|
|
if (ret)
|
|
- return ret;
|
|
|
|
|
|
+ goto done;
|
|
|
|
|
|
WREG32(SMC_SRAM_DATA, data);
|
|
WREG32(SMC_SRAM_DATA, data);
|
|
|
|
|
|
@@ -328,7 +330,7 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
|
|
|
|
|
|
ret = rv770_set_smc_sram_address(rdev, addr, limit);
|
|
ret = rv770_set_smc_sram_address(rdev, addr, limit);
|
|
if (ret)
|
|
if (ret)
|
|
- return ret;
|
|
|
|
|
|
+ goto done;
|
|
|
|
|
|
original_data = RREG32(SMC_SRAM_DATA);
|
|
original_data = RREG32(SMC_SRAM_DATA);
|
|
|
|
|
|
@@ -346,12 +348,15 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
|
|
|
|
|
|
ret = rv770_set_smc_sram_address(rdev, addr, limit);
|
|
ret = rv770_set_smc_sram_address(rdev, addr, limit);
|
|
if (ret)
|
|
if (ret)
|
|
- return ret;
|
|
|
|
|
|
+ goto done;
|
|
|
|
|
|
WREG32(SMC_SRAM_DATA, data);
|
|
WREG32(SMC_SRAM_DATA, data);
|
|
}
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+done:
|
|
|
|
+ spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static int rv770_program_interrupt_vectors(struct radeon_device *rdev,
|
|
static int rv770_program_interrupt_vectors(struct radeon_device *rdev,
|
|
@@ -461,12 +466,15 @@ PPSMC_Result rv770_wait_for_smc_inactive(struct radeon_device *rdev)
|
|
|
|
|
|
static void rv770_clear_smc_sram(struct radeon_device *rdev, u16 limit)
|
|
static void rv770_clear_smc_sram(struct radeon_device *rdev, u16 limit)
|
|
{
|
|
{
|
|
|
|
+ unsigned long flags;
|
|
u16 i;
|
|
u16 i;
|
|
|
|
|
|
|
|
+ spin_lock_irqsave(&rdev->smc_idx_lock, flags);
|
|
for (i = 0; i < limit; i += 4) {
|
|
for (i = 0; i < limit; i += 4) {
|
|
rv770_set_smc_sram_address(rdev, i, limit);
|
|
rv770_set_smc_sram_address(rdev, i, limit);
|
|
WREG32(SMC_SRAM_DATA, 0);
|
|
WREG32(SMC_SRAM_DATA, 0);
|
|
}
|
|
}
|
|
|
|
+ spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
int rv770_load_smc_ucode(struct radeon_device *rdev,
|
|
int rv770_load_smc_ucode(struct radeon_device *rdev,
|
|
@@ -595,27 +603,29 @@ int rv770_load_smc_ucode(struct radeon_device *rdev,
|
|
int rv770_read_smc_sram_dword(struct radeon_device *rdev,
|
|
int rv770_read_smc_sram_dword(struct radeon_device *rdev,
|
|
u16 smc_address, u32 *value, u16 limit)
|
|
u16 smc_address, u32 *value, u16 limit)
|
|
{
|
|
{
|
|
|
|
+ unsigned long flags;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
|
|
+ spin_lock_irqsave(&rdev->smc_idx_lock, flags);
|
|
ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
|
|
ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
|
|
- if (ret)
|
|
|
|
- return ret;
|
|
|
|
-
|
|
|
|
- *value = RREG32(SMC_SRAM_DATA);
|
|
|
|
|
|
+ if (ret == 0)
|
|
|
|
+ *value = RREG32(SMC_SRAM_DATA);
|
|
|
|
+ spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
int rv770_write_smc_sram_dword(struct radeon_device *rdev,
|
|
int rv770_write_smc_sram_dword(struct radeon_device *rdev,
|
|
u16 smc_address, u32 value, u16 limit)
|
|
u16 smc_address, u32 value, u16 limit)
|
|
{
|
|
{
|
|
|
|
+ unsigned long flags;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
|
|
+ spin_lock_irqsave(&rdev->smc_idx_lock, flags);
|
|
ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
|
|
ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
|
|
- if (ret)
|
|
|
|
- return ret;
|
|
|
|
|
|
+ if (ret == 0)
|
|
|
|
+ WREG32(SMC_SRAM_DATA, value);
|
|
|
|
+ spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
|
|
|
|
|
|
- WREG32(SMC_SRAM_DATA, value);
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
|
|
+ return ret;
|
|
}
|
|
}
|