diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-01-18 19:36:20 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-01-31 16:24:54 -0500 |
commit | 014bb209214d8dce9698efea71c68d20ba477abc (patch) | |
tree | 66640ef4a7ade13c0543abf37b37d06335eeb8dc | |
parent | 168757ea854b7dd8eac3962753ed75a542ebca92 (diff) |
drm/radeon: use status regs to determine what to reset (si)
When we attempt the reset the GPU, look at the status registers
to determine what blocks need to be reset.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 154 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 12 |
2 files changed, 132 insertions, 34 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 64841553f9ef..7a8ca728f36f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -62,6 +62,7 @@ extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa | |||
62 | extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); | 62 | extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); |
63 | extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev); | 63 | extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev); |
64 | extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); | 64 | extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); |
65 | extern bool evergreen_is_display_hung(struct radeon_device *rdev); | ||
65 | 66 | ||
66 | /* get temperature in millidegrees */ | 67 | /* get temperature in millidegrees */ |
67 | int si_get_temp(struct radeon_device *rdev) | 68 | int si_get_temp(struct radeon_device *rdev) |
@@ -2127,21 +2128,89 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2127 | return radeon_ring_test_lockup(rdev, ring); | 2128 | return radeon_ring_test_lockup(rdev, ring); |
2128 | } | 2129 | } |
2129 | 2130 | ||
2130 | static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | 2131 | static u32 si_gpu_check_soft_reset(struct radeon_device *rdev) |
2131 | { | 2132 | { |
2132 | struct evergreen_mc_save save; | 2133 | u32 reset_mask = 0; |
2133 | u32 grbm_soft_reset = 0, srbm_soft_reset = 0; | ||
2134 | u32 tmp; | 2134 | u32 tmp; |
2135 | int ret = 0; | ||
2136 | 2135 | ||
2137 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | 2136 | /* GRBM_STATUS */ |
2138 | reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP); | 2137 | tmp = RREG32(GRBM_STATUS); |
2138 | if (tmp & (PA_BUSY | SC_BUSY | | ||
2139 | BCI_BUSY | SX_BUSY | | ||
2140 | TA_BUSY | VGT_BUSY | | ||
2141 | DB_BUSY | CB_BUSY | | ||
2142 | GDS_BUSY | SPI_BUSY | | ||
2143 | IA_BUSY | IA_BUSY_NO_DMA)) | ||
2144 | reset_mask |= RADEON_RESET_GFX; | ||
2145 | |||
2146 | if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING | | ||
2147 | CP_BUSY | CP_COHERENCY_BUSY)) | ||
2148 | reset_mask |= RADEON_RESET_CP; | ||
2149 | |||
2150 | if (tmp & GRBM_EE_BUSY) | ||
2151 | reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP; | ||
2152 | |||
2153 | /* GRBM_STATUS2 */ | ||
2154 | tmp = RREG32(GRBM_STATUS2); | ||
2155 | if (tmp & (RLC_RQ_PENDING | RLC_BUSY)) | ||
2156 | reset_mask |= RADEON_RESET_RLC; | ||
2157 | |||
2158 | /* DMA_STATUS_REG 0 */ | ||
2159 | tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET); | ||
2160 | if (!(tmp & DMA_IDLE)) | ||
2161 | reset_mask |= RADEON_RESET_DMA; | ||
2162 | |||
2163 | /* DMA_STATUS_REG 1 */ | ||
2164 | tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET); | ||
2165 | if (!(tmp & DMA_IDLE)) | ||
2166 | reset_mask |= RADEON_RESET_DMA1; | ||
2167 | |||
2168 | /* SRBM_STATUS2 */ | ||
2169 | tmp = RREG32(SRBM_STATUS2); | ||
2170 | if (tmp & DMA_BUSY) | ||
2171 | reset_mask |= RADEON_RESET_DMA; | ||
2172 | |||
2173 | if (tmp & DMA1_BUSY) | ||
2174 | reset_mask |= RADEON_RESET_DMA1; | ||
2175 | |||
2176 | /* SRBM_STATUS */ | ||
2177 | tmp = RREG32(SRBM_STATUS); | ||
2178 | |||
2179 | if (tmp & IH_BUSY) | ||
2180 | reset_mask |= RADEON_RESET_IH; | ||
2181 | |||
2182 | if (tmp & SEM_BUSY) | ||
2183 | reset_mask |= RADEON_RESET_SEM; | ||
2184 | |||
2185 | if (tmp & GRBM_RQ_PENDING) | ||
2186 | reset_mask |= RADEON_RESET_GRBM; | ||
2187 | |||
2188 | if (tmp & VMC_BUSY) | ||
2189 | reset_mask |= RADEON_RESET_VMC; | ||
2139 | 2190 | ||
2140 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | 2191 | if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY | |
2141 | reset_mask &= ~RADEON_RESET_DMA; | 2192 | MCC_BUSY | MCD_BUSY)) |
2193 | reset_mask |= RADEON_RESET_MC; | ||
2194 | |||
2195 | if (evergreen_is_display_hung(rdev)) | ||
2196 | reset_mask |= RADEON_RESET_DISPLAY; | ||
2197 | |||
2198 | /* VM_L2_STATUS */ | ||
2199 | tmp = RREG32(VM_L2_STATUS); | ||
2200 | if (tmp & L2_BUSY) | ||
2201 | reset_mask |= RADEON_RESET_VMC; | ||
2202 | |||
2203 | return reset_mask; | ||
2204 | } | ||
2205 | |||
2206 | static void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | ||
2207 | { | ||
2208 | struct evergreen_mc_save save; | ||
2209 | u32 grbm_soft_reset = 0, srbm_soft_reset = 0; | ||
2210 | u32 tmp; | ||
2142 | 2211 | ||
2143 | if (reset_mask == 0) | 2212 | if (reset_mask == 0) |
2144 | return 0; | 2213 | return; |
2145 | 2214 | ||
2146 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | 2215 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); |
2147 | 2216 | ||
@@ -2151,8 +2220,6 @@ static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | |||
2151 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | 2220 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", |
2152 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); | 2221 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); |
2153 | 2222 | ||
2154 | r600_set_bios_scratch_engine_hung(rdev, true); | ||
2155 | |||
2156 | evergreen_mc_stop(rdev, &save); | 2223 | evergreen_mc_stop(rdev, &save); |
2157 | if (evergreen_mc_wait_for_idle(rdev)) { | 2224 | if (evergreen_mc_wait_for_idle(rdev)) { |
2158 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | 2225 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); |
@@ -2166,7 +2233,8 @@ static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | |||
2166 | tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); | 2233 | tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); |
2167 | tmp &= ~DMA_RB_ENABLE; | 2234 | tmp &= ~DMA_RB_ENABLE; |
2168 | WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); | 2235 | WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); |
2169 | 2236 | } | |
2237 | if (reset_mask & RADEON_RESET_DMA1) { | ||
2170 | /* dma1 */ | 2238 | /* dma1 */ |
2171 | tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); | 2239 | tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); |
2172 | tmp &= ~DMA_RB_ENABLE; | 2240 | tmp &= ~DMA_RB_ENABLE; |
@@ -2195,7 +2263,31 @@ static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | |||
2195 | } | 2263 | } |
2196 | 2264 | ||
2197 | if (reset_mask & RADEON_RESET_DMA) | 2265 | if (reset_mask & RADEON_RESET_DMA) |
2198 | srbm_soft_reset |= SOFT_RESET_DMA | SOFT_RESET_DMA1; | 2266 | srbm_soft_reset |= SOFT_RESET_DMA; |
2267 | |||
2268 | if (reset_mask & RADEON_RESET_DMA1) | ||
2269 | srbm_soft_reset |= SOFT_RESET_DMA1; | ||
2270 | |||
2271 | if (reset_mask & RADEON_RESET_DISPLAY) | ||
2272 | srbm_soft_reset |= SOFT_RESET_DC; | ||
2273 | |||
2274 | if (reset_mask & RADEON_RESET_RLC) | ||
2275 | grbm_soft_reset |= SOFT_RESET_RLC; | ||
2276 | |||
2277 | if (reset_mask & RADEON_RESET_SEM) | ||
2278 | srbm_soft_reset |= SOFT_RESET_SEM; | ||
2279 | |||
2280 | if (reset_mask & RADEON_RESET_IH) | ||
2281 | srbm_soft_reset |= SOFT_RESET_IH; | ||
2282 | |||
2283 | if (reset_mask & RADEON_RESET_GRBM) | ||
2284 | srbm_soft_reset |= SOFT_RESET_GRBM; | ||
2285 | |||
2286 | if (reset_mask & RADEON_RESET_VMC) | ||
2287 | srbm_soft_reset |= SOFT_RESET_VMC; | ||
2288 | |||
2289 | if (reset_mask & RADEON_RESET_MC) | ||
2290 | srbm_soft_reset |= SOFT_RESET_MC; | ||
2199 | 2291 | ||
2200 | if (grbm_soft_reset) { | 2292 | if (grbm_soft_reset) { |
2201 | tmp = RREG32(GRBM_SOFT_RESET); | 2293 | tmp = RREG32(GRBM_SOFT_RESET); |
@@ -2231,32 +2323,26 @@ static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | |||
2231 | evergreen_mc_resume(rdev, &save); | 2323 | evergreen_mc_resume(rdev, &save); |
2232 | udelay(50); | 2324 | udelay(50); |
2233 | 2325 | ||
2234 | #if 0 | ||
2235 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) { | ||
2236 | if (RREG32(GRBM_STATUS) & GUI_ACTIVE) | ||
2237 | ret = -EAGAIN; | ||
2238 | } | ||
2239 | |||
2240 | if (reset_mask & RADEON_RESET_DMA) { | ||
2241 | if (!(RREG32(DMA_STATUS_REG) & DMA_IDLE)) | ||
2242 | ret = -EAGAIN; | ||
2243 | } | ||
2244 | #endif | ||
2245 | |||
2246 | if (!ret) | ||
2247 | r600_set_bios_scratch_engine_hung(rdev, false); | ||
2248 | |||
2249 | evergreen_print_gpu_status_regs(rdev); | 2326 | evergreen_print_gpu_status_regs(rdev); |
2250 | |||
2251 | return 0; | ||
2252 | } | 2327 | } |
2253 | 2328 | ||
2254 | int si_asic_reset(struct radeon_device *rdev) | 2329 | int si_asic_reset(struct radeon_device *rdev) |
2255 | { | 2330 | { |
2256 | return si_gpu_soft_reset(rdev, (RADEON_RESET_GFX | | 2331 | u32 reset_mask; |
2257 | RADEON_RESET_COMPUTE | | 2332 | |
2258 | RADEON_RESET_DMA | | 2333 | reset_mask = si_gpu_check_soft_reset(rdev); |
2259 | RADEON_RESET_CP)); | 2334 | |
2335 | if (reset_mask) | ||
2336 | r600_set_bios_scratch_engine_hung(rdev, true); | ||
2337 | |||
2338 | si_gpu_soft_reset(rdev, reset_mask); | ||
2339 | |||
2340 | reset_mask = si_gpu_check_soft_reset(rdev); | ||
2341 | |||
2342 | if (!reset_mask) | ||
2343 | r600_set_bios_scratch_engine_hung(rdev, false); | ||
2344 | |||
2345 | return 0; | ||
2260 | } | 2346 | } |
2261 | 2347 | ||
2262 | /* MC */ | 2348 | /* MC */ |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 76b5911585f1..07fc455e35ae 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -61,6 +61,14 @@ | |||
61 | #define DMIF_ADDR_CONFIG 0xBD4 | 61 | #define DMIF_ADDR_CONFIG 0xBD4 |
62 | 62 | ||
63 | #define SRBM_STATUS 0xE50 | 63 | #define SRBM_STATUS 0xE50 |
64 | #define GRBM_RQ_PENDING (1 << 5) | ||
65 | #define VMC_BUSY (1 << 8) | ||
66 | #define MCB_BUSY (1 << 9) | ||
67 | #define MCB_NON_DISPLAY_BUSY (1 << 10) | ||
68 | #define MCC_BUSY (1 << 11) | ||
69 | #define MCD_BUSY (1 << 12) | ||
70 | #define SEM_BUSY (1 << 14) | ||
71 | #define IH_BUSY (1 << 17) | ||
64 | 72 | ||
65 | #define SRBM_SOFT_RESET 0x0E60 | 73 | #define SRBM_SOFT_RESET 0x0E60 |
66 | #define SOFT_RESET_BIF (1 << 1) | 74 | #define SOFT_RESET_BIF (1 << 1) |
@@ -81,6 +89,10 @@ | |||
81 | #define CC_SYS_RB_BACKEND_DISABLE 0xe80 | 89 | #define CC_SYS_RB_BACKEND_DISABLE 0xe80 |
82 | #define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84 | 90 | #define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84 |
83 | 91 | ||
92 | #define SRBM_STATUS2 0x0EC4 | ||
93 | #define DMA_BUSY (1 << 5) | ||
94 | #define DMA1_BUSY (1 << 6) | ||
95 | |||
84 | #define VM_L2_CNTL 0x1400 | 96 | #define VM_L2_CNTL 0x1400 |
85 | #define ENABLE_L2_CACHE (1 << 0) | 97 | #define ENABLE_L2_CACHE (1 << 0) |
86 | #define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) | 98 | #define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) |