diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-01-03 13:15:30 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-01-03 21:29:35 -0500 |
commit | 06bc6df0df52bf8d08247ded2f4d98966d5a046b (patch) | |
tree | 30eba03cd9f9da531759e8908ea141b2471d5a62 /drivers/gpu/drm/radeon/si.c | |
parent | 271d6fed6580c0a7af9b74b9aa90d8a62bdb326d (diff) |
drm/radeon: switch to a finer grained reset for SI (v2)
No change in functionality as we currently set all the reset
flags.
v2: fix typo
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/si.c')
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 99 |
1 files changed, 65 insertions, 34 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 4bf17334927a..3240a3d64f30 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; | 2131 | u32 grbm_reset = 0; |
2132 | u32 grbm_reset = 0, tmp; | ||
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,36 +2143,10 @@ 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 | dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n", | ||
2149 | RREG32(DMA_STATUS_REG)); | ||
2150 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
2151 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR)); | ||
2152 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
2153 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); | ||
2154 | 2146 | ||
2155 | evergreen_mc_stop(rdev, &save); | ||
2156 | if (radeon_mc_wait_for_idle(rdev)) { | ||
2157 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2158 | } | ||
2159 | /* Disable CP parsing/prefetching */ | 2147 | /* Disable CP parsing/prefetching */ |
2160 | 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); |
2161 | 2149 | ||
2162 | /* dma0 */ | ||
2163 | tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); | ||
2164 | tmp &= ~DMA_RB_ENABLE; | ||
2165 | WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); | ||
2166 | |||
2167 | /* dma1 */ | ||
2168 | tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); | ||
2169 | tmp &= ~DMA_RB_ENABLE; | ||
2170 | WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); | ||
2171 | |||
2172 | /* Reset dma */ | ||
2173 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); | ||
2174 | RREG32(SRBM_SOFT_RESET); | ||
2175 | udelay(50); | ||
2176 | WREG32(SRBM_SOFT_RESET, 0); | ||
2177 | |||
2178 | /* reset all the gfx blocks */ | 2150 | /* reset all the gfx blocks */ |
2179 | grbm_reset = (SOFT_RESET_CP | | 2151 | grbm_reset = (SOFT_RESET_CP | |
2180 | SOFT_RESET_CB | | 2152 | SOFT_RESET_CB | |
@@ -2196,8 +2168,7 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) | |||
2196 | udelay(50); | 2168 | udelay(50); |
2197 | WREG32(GRBM_SOFT_RESET, 0); | 2169 | WREG32(GRBM_SOFT_RESET, 0); |
2198 | (void)RREG32(GRBM_SOFT_RESET); | 2170 | (void)RREG32(GRBM_SOFT_RESET); |
2199 | /* Wait a little for things to settle down */ | 2171 | |
2200 | udelay(50); | ||
2201 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 2172 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", |
2202 | RREG32(GRBM_STATUS)); | 2173 | RREG32(GRBM_STATUS)); |
2203 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", | 2174 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", |
@@ -2208,15 +2179,75 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) | |||
2208 | RREG32(GRBM_STATUS_SE1)); | 2179 | RREG32(GRBM_STATUS_SE1)); |
2209 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2180 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
2210 | 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 | |||
2211 | dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n", | 2191 | dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n", |
2212 | RREG32(DMA_STATUS_REG)); | 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 | |||
2213 | evergreen_mc_resume(rdev, &save); | 2242 | evergreen_mc_resume(rdev, &save); |
2214 | return 0; | 2243 | return 0; |
2215 | } | 2244 | } |
2216 | 2245 | ||
2217 | int si_asic_reset(struct radeon_device *rdev) | 2246 | int si_asic_reset(struct radeon_device *rdev) |
2218 | { | 2247 | { |
2219 | return si_gpu_soft_reset(rdev); | 2248 | return si_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
2249 | RADEON_RESET_COMPUTE | | ||
2250 | RADEON_RESET_DMA)); | ||
2220 | } | 2251 | } |
2221 | 2252 | ||
2222 | /* MC */ | 2253 | /* MC */ |