diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/si.c')
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index ef683653f0b..3240a3d64f3 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -2126,15 +2126,13 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2126 | return radeon_ring_test_lockup(rdev, ring); | 2126 | return radeon_ring_test_lockup(rdev, ring); |
2127 | } | 2127 | } |
2128 | 2128 | ||
2129 | static int si_gpu_soft_reset(struct radeon_device *rdev) | 2129 | static void si_gpu_soft_reset_gfx(struct radeon_device *rdev) |
2130 | { | 2130 | { |
2131 | struct evergreen_mc_save save; | ||
2132 | u32 grbm_reset = 0; | 2131 | u32 grbm_reset = 0; |
2133 | 2132 | ||
2134 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | 2133 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) |
2135 | return 0; | 2134 | return; |
2136 | 2135 | ||
2137 | dev_info(rdev->dev, "GPU softreset \n"); | ||
2138 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 2136 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", |
2139 | RREG32(GRBM_STATUS)); | 2137 | RREG32(GRBM_STATUS)); |
2140 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", | 2138 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", |
@@ -2145,10 +2143,7 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) | |||
2145 | RREG32(GRBM_STATUS_SE1)); | 2143 | RREG32(GRBM_STATUS_SE1)); |
2146 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2144 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
2147 | RREG32(SRBM_STATUS)); | 2145 | RREG32(SRBM_STATUS)); |
2148 | evergreen_mc_stop(rdev, &save); | 2146 | |
2149 | if (radeon_mc_wait_for_idle(rdev)) { | ||
2150 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2151 | } | ||
2152 | /* Disable CP parsing/prefetching */ | 2147 | /* Disable CP parsing/prefetching */ |
2153 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); | 2148 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); |
2154 | 2149 | ||
@@ -2173,8 +2168,7 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) | |||
2173 | udelay(50); | 2168 | udelay(50); |
2174 | WREG32(GRBM_SOFT_RESET, 0); | 2169 | WREG32(GRBM_SOFT_RESET, 0); |
2175 | (void)RREG32(GRBM_SOFT_RESET); | 2170 | (void)RREG32(GRBM_SOFT_RESET); |
2176 | /* Wait a little for things to settle down */ | 2171 | |
2177 | udelay(50); | ||
2178 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 2172 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", |
2179 | RREG32(GRBM_STATUS)); | 2173 | RREG32(GRBM_STATUS)); |
2180 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", | 2174 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", |
@@ -2185,13 +2179,75 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) | |||
2185 | RREG32(GRBM_STATUS_SE1)); | 2179 | RREG32(GRBM_STATUS_SE1)); |
2186 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2180 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
2187 | RREG32(SRBM_STATUS)); | 2181 | RREG32(SRBM_STATUS)); |
2182 | } | ||
2183 | |||
2184 | static void si_gpu_soft_reset_dma(struct radeon_device *rdev) | ||
2185 | { | ||
2186 | u32 tmp; | ||
2187 | |||
2188 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
2189 | return; | ||
2190 | |||
2191 | dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n", | ||
2192 | RREG32(DMA_STATUS_REG)); | ||
2193 | |||
2194 | /* dma0 */ | ||
2195 | tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); | ||
2196 | tmp &= ~DMA_RB_ENABLE; | ||
2197 | WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); | ||
2198 | |||
2199 | /* dma1 */ | ||
2200 | tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); | ||
2201 | tmp &= ~DMA_RB_ENABLE; | ||
2202 | WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); | ||
2203 | |||
2204 | /* Reset dma */ | ||
2205 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); | ||
2206 | RREG32(SRBM_SOFT_RESET); | ||
2207 | udelay(50); | ||
2208 | WREG32(SRBM_SOFT_RESET, 0); | ||
2209 | |||
2210 | dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n", | ||
2211 | RREG32(DMA_STATUS_REG)); | ||
2212 | } | ||
2213 | |||
2214 | static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | ||
2215 | { | ||
2216 | struct evergreen_mc_save save; | ||
2217 | |||
2218 | if (reset_mask == 0) | ||
2219 | return 0; | ||
2220 | |||
2221 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
2222 | |||
2223 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
2224 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR)); | ||
2225 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
2226 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); | ||
2227 | |||
2228 | evergreen_mc_stop(rdev, &save); | ||
2229 | if (radeon_mc_wait_for_idle(rdev)) { | ||
2230 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2231 | } | ||
2232 | |||
2233 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
2234 | si_gpu_soft_reset_gfx(rdev); | ||
2235 | |||
2236 | if (reset_mask & RADEON_RESET_DMA) | ||
2237 | si_gpu_soft_reset_dma(rdev); | ||
2238 | |||
2239 | /* Wait a little for things to settle down */ | ||
2240 | udelay(50); | ||
2241 | |||
2188 | evergreen_mc_resume(rdev, &save); | 2242 | evergreen_mc_resume(rdev, &save); |
2189 | return 0; | 2243 | return 0; |
2190 | } | 2244 | } |
2191 | 2245 | ||
2192 | int si_asic_reset(struct radeon_device *rdev) | 2246 | int si_asic_reset(struct radeon_device *rdev) |
2193 | { | 2247 | { |
2194 | return si_gpu_soft_reset(rdev); | 2248 | return si_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
2249 | RADEON_RESET_COMPUTE | | ||
2250 | RADEON_RESET_DMA)); | ||
2195 | } | 2251 | } |
2196 | 2252 | ||
2197 | /* MC */ | 2253 | /* MC */ |