diff options
| author | Alex Deucher <alexander.deucher@amd.com> | 2013-09-03 19:00:09 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2013-09-11 11:44:29 -0400 |
| commit | 0a5b7b0bd97a212f5d8d28c5011b04a45dfb006e (patch) | |
| tree | ac0d7f0e8a81cec0db2a1d4b9e19d4fe1ece0918 | |
| parent | fe78118c4603ab91b88907eaabe4a1ca03a9f220 (diff) | |
drm/radeon: add spinlocks for indirect register accesss
This adds spinlocks to protect access to other
indirect register apertures. These indirect spaces are
used pretty infrequently and we haven't had an reported
problems, but better safe than sorry.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
| -rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/dce6_afmt.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r420.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 69 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rs400.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rs600.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rs690.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rv515.c | 8 |
11 files changed, 155 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 07aa13deaa15..e521d4c6676f 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -122,20 +122,27 @@ int kv_get_temp(struct radeon_device *rdev) | |||
| 122 | */ | 122 | */ |
| 123 | u32 cik_pciep_rreg(struct radeon_device *rdev, u32 reg) | 123 | u32 cik_pciep_rreg(struct radeon_device *rdev, u32 reg) |
| 124 | { | 124 | { |
| 125 | unsigned long flags; | ||
| 125 | u32 r; | 126 | u32 r; |
| 126 | 127 | ||
| 128 | spin_lock_irqsave(&rdev->pciep_idx_lock, flags); | ||
| 127 | WREG32(PCIE_INDEX, reg); | 129 | WREG32(PCIE_INDEX, reg); |
| 128 | (void)RREG32(PCIE_INDEX); | 130 | (void)RREG32(PCIE_INDEX); |
| 129 | r = RREG32(PCIE_DATA); | 131 | r = RREG32(PCIE_DATA); |
| 132 | spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags); | ||
| 130 | return r; | 133 | return r; |
| 131 | } | 134 | } |
| 132 | 135 | ||
| 133 | void cik_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) | 136 | void cik_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) |
| 134 | { | 137 | { |
| 138 | unsigned long flags; | ||
| 139 | |||
| 140 | spin_lock_irqsave(&rdev->pciep_idx_lock, flags); | ||
| 135 | WREG32(PCIE_INDEX, reg); | 141 | WREG32(PCIE_INDEX, reg); |
| 136 | (void)RREG32(PCIE_INDEX); | 142 | (void)RREG32(PCIE_INDEX); |
| 137 | WREG32(PCIE_DATA, v); | 143 | WREG32(PCIE_DATA, v); |
| 138 | (void)RREG32(PCIE_DATA); | 144 | (void)RREG32(PCIE_DATA); |
| 145 | spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags); | ||
| 139 | } | 146 | } |
| 140 | 147 | ||
| 141 | static const u32 spectre_rlc_save_restore_register_list[] = | 148 | static const u32 spectre_rlc_save_restore_register_list[] = |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 3853dda797dd..85a69d2ea3d2 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
| @@ -28,22 +28,30 @@ | |||
| 28 | static u32 dce6_endpoint_rreg(struct radeon_device *rdev, | 28 | static u32 dce6_endpoint_rreg(struct radeon_device *rdev, |
| 29 | u32 block_offset, u32 reg) | 29 | u32 block_offset, u32 reg) |
| 30 | { | 30 | { |
| 31 | unsigned long flags; | ||
| 31 | u32 r; | 32 | u32 r; |
| 32 | 33 | ||
| 34 | spin_lock_irqsave(&rdev->end_idx_lock, flags); | ||
| 33 | WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); | 35 | WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); |
| 34 | r = RREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset); | 36 | r = RREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset); |
| 37 | spin_unlock_irqrestore(&rdev->end_idx_lock, flags); | ||
| 38 | |||
| 35 | return r; | 39 | return r; |
| 36 | } | 40 | } |
| 37 | 41 | ||
| 38 | static void dce6_endpoint_wreg(struct radeon_device *rdev, | 42 | static void dce6_endpoint_wreg(struct radeon_device *rdev, |
| 39 | u32 block_offset, u32 reg, u32 v) | 43 | u32 block_offset, u32 reg, u32 v) |
| 40 | { | 44 | { |
| 45 | unsigned long flags; | ||
| 46 | |||
| 47 | spin_lock_irqsave(&rdev->end_idx_lock, flags); | ||
| 41 | if (ASIC_IS_DCE8(rdev)) | 48 | if (ASIC_IS_DCE8(rdev)) |
| 42 | WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); | 49 | WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); |
| 43 | else | 50 | else |
| 44 | WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, | 51 | WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, |
| 45 | AZ_ENDPOINT_REG_WRITE_EN | AZ_ENDPOINT_REG_INDEX(reg)); | 52 | AZ_ENDPOINT_REG_WRITE_EN | AZ_ENDPOINT_REG_INDEX(reg)); |
| 46 | WREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset, v); | 53 | WREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset, v); |
| 54 | spin_unlock_irqrestore(&rdev->end_idx_lock, flags); | ||
| 47 | } | 55 | } |
| 48 | 56 | ||
| 49 | #define RREG32_ENDPOINT(block, reg) dce6_endpoint_rreg(rdev, (block), (reg)) | 57 | #define RREG32_ENDPOINT(block, reg) dce6_endpoint_rreg(rdev, (block), (reg)) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 9fc61dd68bc0..24175717307b 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -2853,21 +2853,28 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev) | |||
| 2853 | 2853 | ||
| 2854 | uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg) | 2854 | uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg) |
| 2855 | { | 2855 | { |
| 2856 | unsigned long flags; | ||
| 2856 | uint32_t data; | 2857 | uint32_t data; |
| 2857 | 2858 | ||
| 2859 | spin_lock_irqsave(&rdev->pll_idx_lock, flags); | ||
| 2858 | WREG8(RADEON_CLOCK_CNTL_INDEX, reg & 0x3f); | 2860 | WREG8(RADEON_CLOCK_CNTL_INDEX, reg & 0x3f); |
| 2859 | r100_pll_errata_after_index(rdev); | 2861 | r100_pll_errata_after_index(rdev); |
| 2860 | data = RREG32(RADEON_CLOCK_CNTL_DATA); | 2862 | data = RREG32(RADEON_CLOCK_CNTL_DATA); |
| 2861 | r100_pll_errata_after_data(rdev); | 2863 | r100_pll_errata_after_data(rdev); |
| 2864 | spin_unlock_irqrestore(&rdev->pll_idx_lock, flags); | ||
| 2862 | return data; | 2865 | return data; |
| 2863 | } | 2866 | } |
| 2864 | 2867 | ||
| 2865 | void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | 2868 | void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) |
| 2866 | { | 2869 | { |
| 2870 | unsigned long flags; | ||
| 2871 | |||
| 2872 | spin_lock_irqsave(&rdev->pll_idx_lock, flags); | ||
| 2867 | WREG8(RADEON_CLOCK_CNTL_INDEX, ((reg & 0x3f) | RADEON_PLL_WR_EN)); | 2873 | WREG8(RADEON_CLOCK_CNTL_INDEX, ((reg & 0x3f) | RADEON_PLL_WR_EN)); |
| 2868 | r100_pll_errata_after_index(rdev); | 2874 | r100_pll_errata_after_index(rdev); |
| 2869 | WREG32(RADEON_CLOCK_CNTL_DATA, v); | 2875 | WREG32(RADEON_CLOCK_CNTL_DATA, v); |
| 2870 | r100_pll_errata_after_data(rdev); | 2876 | r100_pll_errata_after_data(rdev); |
| 2877 | spin_unlock_irqrestore(&rdev->pll_idx_lock, flags); | ||
| 2871 | } | 2878 | } |
| 2872 | 2879 | ||
| 2873 | static void r100_set_safe_registers(struct radeon_device *rdev) | 2880 | static void r100_set_safe_registers(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 4e796ecf9ea4..6edf2b3a52b4 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
| @@ -160,18 +160,25 @@ void r420_pipes_init(struct radeon_device *rdev) | |||
| 160 | 160 | ||
| 161 | u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg) | 161 | u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg) |
| 162 | { | 162 | { |
| 163 | unsigned long flags; | ||
| 163 | u32 r; | 164 | u32 r; |
| 164 | 165 | ||
| 166 | spin_lock_irqsave(&rdev->mc_idx_lock, flags); | ||
| 165 | WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg)); | 167 | WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg)); |
| 166 | r = RREG32(R_0001FC_MC_IND_DATA); | 168 | r = RREG32(R_0001FC_MC_IND_DATA); |
| 169 | spin_unlock_irqrestore(&rdev->mc_idx_lock, flags); | ||
| 167 | return r; | 170 | return r; |
| 168 | } | 171 | } |
| 169 | 172 | ||
| 170 | void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v) | 173 | void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v) |
| 171 | { | 174 | { |
| 175 | unsigned long flags; | ||
| 176 | |||
| 177 | spin_lock_irqsave(&rdev->mc_idx_lock, flags); | ||
| 172 | WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg) | | 178 | WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg) | |
| 173 | S_0001F8_MC_IND_WR_EN(1)); | 179 | S_0001F8_MC_IND_WR_EN(1)); |
| 174 | WREG32(R_0001FC_MC_IND_DATA, v); | 180 | WREG32(R_0001FC_MC_IND_DATA, v); |
| 181 | spin_unlock_irqrestore(&rdev->mc_idx_lock, flags); | ||
| 175 | } | 182 | } |
| 176 | 183 | ||
| 177 | static void r420_debugfs(struct radeon_device *rdev) | 184 | static void r420_debugfs(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index ea4d3734e6d9..11cd99e3cbb5 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -1045,20 +1045,27 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev) | |||
| 1045 | 1045 | ||
| 1046 | uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg) | 1046 | uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg) |
| 1047 | { | 1047 | { |
| 1048 | unsigned long flags; | ||
| 1048 | uint32_t r; | 1049 | uint32_t r; |
| 1049 | 1050 | ||
| 1051 | spin_lock_irqsave(&rdev->mc_idx_lock, flags); | ||
| 1050 | WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg)); | ||
