]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blobdiff - drivers/gpu/drm/radeon/rv770_smc.c
Merge tag 'jfs-3.12' of git://github.com/kleikamp/linux-shaggy
[mirror_ubuntu-eoan-kernel.git] / drivers / gpu / drm / radeon / rv770_smc.c
index ab95da570215b7c68895be5bbe7765dd92ea758a..b2a224407365da6750572c30309466c025fb57ee 100644 (file)
@@ -274,8 +274,8 @@ static const u8 cayman_smc_int_vectors[] =
        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;
 
@@ -296,9 +296,10 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
                            u16 smc_start_address, const u8 *src,
                            u16 byte_count, u16 limit)
 {
+       unsigned long flags;
        u32 data, original_data, extra_shift;
        u16 addr;
-       int ret;
+       int ret = 0;
 
        if (smc_start_address & 3)
                return -EINVAL;
@@ -307,13 +308,14 @@ int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
 
        addr = smc_start_address;
 
+       spin_lock_irqsave(&rdev->smc_idx_lock, flags);
        while (byte_count >= 4) {
                /* SMC address space is BE */
                data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 
                ret = rv770_set_smc_sram_address(rdev, addr, limit);
                if (ret)
-                       return ret;
+                       goto done;
 
                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);
                if (ret)
-                       return ret;
+                       goto done;
 
                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);
                if (ret)
-                       return ret;
+                       goto done;
 
                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,
@@ -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)
 {
+       unsigned long flags;
        u16 i;
 
+       spin_lock_irqsave(&rdev->smc_idx_lock, flags);
        for (i = 0;  i < limit; i += 4) {
                rv770_set_smc_sram_address(rdev, i, limit);
                WREG32(SMC_SRAM_DATA, 0);
        }
+       spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 }
 
 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,
                              u16 smc_address, u32 *value, u16 limit)
 {
+       unsigned long flags;
        int ret;
 
+       spin_lock_irqsave(&rdev->smc_idx_lock, flags);
        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,
                               u16 smc_address, u32 value, u16 limit)
 {
+       unsigned long flags;
        int ret;
 
+       spin_lock_irqsave(&rdev->smc_idx_lock, flags);
        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;
 }