aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/rv770_smc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/rv770_smc.c')
-rw-r--r--drivers/gpu/drm/radeon/rv770_smc.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/rv770_smc.c b/drivers/gpu/drm/radeon/rv770_smc.c
index ab95da570215..b2a224407365 100644
--- a/drivers/gpu/drm/radeon/rv770_smc.c
+++ b/drivers/gpu/drm/radeon/rv770_smc.c
@@ -274,8 +274,8 @@ static const u8 cayman_smc_int_vectors[] =
274 0x08, 0x72, 0x08, 0x72 274 0x08, 0x72, 0x08, 0x72
275}; 275};
276 276
277int rv770_set_smc_sram_address(struct radeon_device *rdev, 277static int rv770_set_smc_sram_address(struct radeon_device *rdev,
278 u16 smc_address, u16 limit) 278 u16 smc_address, u16 limit)
279{ 279{
280 u32 addr; 280 u32 addr;
281 281
@@ -296,9 +296,10 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
296 u16 smc_start_address, const u8 *src, 296 u16 smc_start_address, const u8 *src,
297 u16 byte_count, u16 limit) 297 u16 byte_count, u16 limit)
298{ 298{
299 unsigned long flags;
299 u32 data, original_data, extra_shift; 300 u32 data, original_data, extra_shift;
300 u16 addr; 301 u16 addr;
301 int ret; 302 int ret = 0;
302 303
303 if (smc_start_address & 3) 304 if (smc_start_address & 3)
304 return -EINVAL; 305 return -EINVAL;
@@ -307,13 +308,14 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
307 308
308 addr = smc_start_address; 309 addr = smc_start_address;
309 310
311 spin_lock_irqsave(&rdev->smc_idx_lock, flags);
310 while (byte_count >= 4) { 312 while (byte_count >= 4) {
311 /* SMC address space is BE */ 313 /* SMC address space is BE */
312 data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; 314 data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
313 315
314 ret = rv770_set_smc_sram_address(rdev, addr, limit); 316 ret = rv770_set_smc_sram_address(rdev, addr, limit);
315 if (ret) 317 if (ret)
316 return ret; 318 goto done;
317 319
318 WREG32(SMC_SRAM_DATA, data); 320 WREG32(SMC_SRAM_DATA, data);
319 321
@@ -328,7 +330,7 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
328 330
329 ret = rv770_set_smc_sram_address(rdev, addr, limit); 331 ret = rv770_set_smc_sram_address(rdev, addr, limit);
330 if (ret) 332 if (ret)
331 return ret; 333 goto done;
332 334
333 original_data = RREG32(SMC_SRAM_DATA); 335 original_data = RREG32(SMC_SRAM_DATA);
334 336
@@ -346,12 +348,15 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
346 348
347 ret = rv770_set_smc_sram_address(rdev, addr, limit); 349 ret = rv770_set_smc_sram_address(rdev, addr, limit);
348 if (ret) 350 if (ret)
349 return ret; 351 goto done;
350 352
351 WREG32(SMC_SRAM_DATA, data); 353 WREG32(SMC_SRAM_DATA, data);
352 } 354 }
353 355
354 return 0; 356done:
357 spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
358
359 return ret;
355} 360}
356 361
357static int rv770_program_interrupt_vectors(struct radeon_device *rdev, 362static int rv770_program_interrupt_vectors(struct radeon_device *rdev,
@@ -461,12 +466,15 @@ PPSMC_Result rv770_wait_for_smc_inactive(struct radeon_device *rdev)
461 466
462static void rv770_clear_smc_sram(struct radeon_device *rdev, u16 limit) 467static void rv770_clear_smc_sram(struct radeon_device *rdev, u16 limit)
463{ 468{
469 unsigned long flags;
464 u16 i; 470 u16 i;
465 471
472 spin_lock_irqsave(&rdev->smc_idx_lock, flags);
466 for (i = 0; i < limit; i += 4) { 473 for (i = 0; i < limit; i += 4) {
467 rv770_set_smc_sram_address(rdev, i, limit); 474 rv770_set_smc_sram_address(rdev, i, limit);
468 WREG32(SMC_SRAM_DATA, 0); 475 WREG32(SMC_SRAM_DATA, 0);
469 } 476 }
477 spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
470} 478}
471 479
472int rv770_load_smc_ucode(struct radeon_device *rdev, 480int rv770_load_smc_ucode(struct radeon_device *rdev,
@@ -595,27 +603,29 @@ int rv770_load_smc_ucode(struct radeon_device *rdev,
595int rv770_read_smc_sram_dword(struct radeon_device *rdev, 603int rv770_read_smc_sram_dword(struct radeon_device *rdev,
596 u16 smc_address, u32 *value, u16 limit) 604 u16 smc_address, u32 *value, u16 limit)
597{ 605{
606 unsigned long flags;
598 int ret; 607 int ret;
599 608
609 spin_lock_irqsave(&rdev->smc_idx_lock, flags);
600 ret = rv770_set_smc_sram_address(rdev, smc_address, limit); 610 ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
601 if (ret) 611 if (ret == 0)
602 return ret; 612 *value = RREG32(SMC_SRAM_DATA);
603 613 spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
604 *value = RREG32(SMC_SRAM_DATA);
605 614
606 return 0; 615 return ret;
607} 616}
608 617
609int rv770_write_smc_sram_dword(struct radeon_device *rdev, 618int rv770_write_smc_sram_dword(struct radeon_device *rdev,
610 u16 smc_address, u32 value, u16 limit) 619 u16 smc_address, u32 value, u16 limit)
611{ 620{
621 unsigned long flags;
612 int ret; 622 int ret;
613 623
624 spin_lock_irqsave(&rdev->smc_idx_lock, flags);
614 ret = rv770_set_smc_sram_address(rdev, smc_address, limit); 625 ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
615 if (ret) 626 if (ret == 0)
616 return ret; 627 WREG32(SMC_SRAM_DATA, value);
628 spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
617 629
618 WREG32(SMC_SRAM_DATA, value); 630 return ret;
619
620 return 0;
621} 631}