diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-10 14:04:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-10 14:04:36 -0500 |
commit | 1a464cbb3d483f2f195b614cffa4aa1b910a0440 (patch) | |
tree | af57dee6436532dbb546b8670e9e1f6910d489b5 /drivers/gpu/drm/radeon/r600.c | |
parent | dbe950f201a8edd353b0bd9079e8d536ee4ce37c (diff) | |
parent | 095f979a539245a46b9e5d600ec9c720b4d928e5 (diff) |
Merge branch 'drm-core-next' of git://people.freedesktop.org/~airlied/linux
* 'drm-core-next' of git://people.freedesktop.org/~airlied/linux: (307 commits)
drm/nouveau/pm: fix build with HWMON off
gma500: silence gcc warnings in mid_get_vbt_data()
drm/ttm: fix condition (and vs or)
drm/radeon: double lock typo in radeon_vm_bo_rmv()
drm/radeon: use after free in radeon_vm_bo_add()
drm/sis|via: don't return stack garbage from free_mem ioctl
drm/radeon/kms: remove pointless CS flags priority struct
drm/radeon/kms: check if vm is supported in VA ioctl
drm: introduce drm_can_sleep and use in intel/radeon drivers. (v2)
radeon: Fix disabling PCI bus mastering on big endian hosts.
ttm: fix agp since ttm tt rework
agp: Fix multi-line warning message whitespace
drm/ttm/dma: Fix accounting error when calling ttm_mem_global_free_page and don't try to free freed pages.
drm/ttm/dma: Only call set_pages_array_wb when the page is not in WB pool.
drm/radeon/kms: sync across multiple rings when doing bo moves v3
drm/radeon/kms: Add support for multi-ring sync in CS ioctl (v2)
drm/radeon: GPU virtual memory support v22
drm: make DRM_UNLOCKED ioctls with their own mutex
drm: no need to hold global mutex for static data
drm/radeon/benchmark: common modes sweep ignores 640x480@32
...
Fix up trivial conflicts in radeon/evergreen.c and vmwgfx/vmwgfx_kms.c
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 273 |
1 files changed, 136 insertions, 137 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 9cdda0b3b081..4f08e5e6ee9d 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1344,7 +1344,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
1344 | return 0; | 1344 | return 0; |
1345 | } | 1345 | } |
1346 | 1346 | ||
1347 | bool r600_gpu_is_lockup(struct radeon_device *rdev) | 1347 | bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) |
1348 | { | 1348 | { |
1349 | u32 srbm_status; | 1349 | u32 srbm_status; |
1350 | u32 grbm_status; | 1350 | u32 grbm_status; |
@@ -1361,19 +1361,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev) | |||
1361 | grbm_status = RREG32(R_008010_GRBM_STATUS); | 1361 | grbm_status = RREG32(R_008010_GRBM_STATUS); |
1362 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); | 1362 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); |
1363 | if (!G_008010_GUI_ACTIVE(grbm_status)) { | 1363 | if (!G_008010_GUI_ACTIVE(grbm_status)) { |
1364 | r100_gpu_lockup_update(lockup, &rdev->cp); | 1364 | r100_gpu_lockup_update(lockup, ring); |
1365 | return false; | 1365 | return false; |
1366 | } | 1366 | } |
1367 | /* force CP activities */ | 1367 | /* force CP activities */ |
1368 | r = radeon_ring_lock(rdev, 2); | 1368 | r = radeon_ring_lock(rdev, ring, 2); |
1369 | if (!r) { | 1369 | if (!r) { |
1370 | /* PACKET2 NOP */ | 1370 | /* PACKET2 NOP */ |
1371 | radeon_ring_write(rdev, 0x80000000); | 1371 | radeon_ring_write(ring, 0x80000000); |
1372 | radeon_ring_write(rdev, 0x80000000); | 1372 | radeon_ring_write(ring, 0x80000000); |
1373 | radeon_ring_unlock_commit(rdev); | 1373 | radeon_ring_unlock_commit(rdev, ring); |
1374 | } | 1374 | } |
1375 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); | 1375 | ring->rptr = RREG32(ring->rptr_reg); |
1376 | return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); | 1376 | return r100_gpu_cp_is_lockup(rdev, lockup, ring); |
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | int r600_asic_reset(struct radeon_device *rdev) | 1379 | int r600_asic_reset(struct radeon_device *rdev) |
@@ -2144,27 +2144,28 @@ static int r600_cp_load_microcode(struct radeon_device *rdev) | |||
2144 | 2144 | ||
2145 | int r600_cp_start(struct radeon_device *rdev) | 2145 | int r600_cp_start(struct radeon_device *rdev) |
2146 | { | 2146 | { |
2147 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
2147 | int r; | 2148 | int r; |
2148 | uint32_t cp_me; | 2149 | uint32_t cp_me; |
2149 | 2150 | ||
2150 | r = radeon_ring_lock(rdev, 7); | 2151 | r = radeon_ring_lock(rdev, ring, 7); |
2151 | if (r) { | 2152 | if (r) { |
2152 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | 2153 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); |
2153 | return r; | 2154 | return r; |
2154 | } | 2155 | } |
2155 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); | 2156 | radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); |
2156 | radeon_ring_write(rdev, 0x1); | 2157 | radeon_ring_write(ring, 0x1); |
2157 | if (rdev->family >= CHIP_RV770) { | 2158 | if (rdev->family >= CHIP_RV770) { |
2158 | radeon_ring_write(rdev, 0x0); | 2159 | radeon_ring_write(ring, 0x0); |
2159 | radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); | 2160 | radeon_ring_write(ring, rdev->config.rv770.max_hw_contexts - 1); |
2160 | } else { | 2161 | } else { |
2161 | radeon_ring_write(rdev, 0x3); | 2162 | radeon_ring_write(ring, 0x3); |
2162 | radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1); | 2163 | radeon_ring_write(ring, rdev->config.r600.max_hw_contexts - 1); |
2163 | } | 2164 | } |
2164 | radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); | 2165 | radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); |
2165 | radeon_ring_write(rdev, 0); | 2166 | radeon_ring_write(ring, 0); |
2166 | radeon_ring_write(rdev, 0); | 2167 | radeon_ring_write(ring, 0); |
2167 | radeon_ring_unlock_commit(rdev); | 2168 | radeon_ring_unlock_commit(rdev, ring); |
2168 | 2169 | ||
2169 | cp_me = 0xff; | 2170 | cp_me = 0xff; |
2170 | WREG32(R_0086D8_CP_ME_CNTL, cp_me); | 2171 | WREG32(R_0086D8_CP_ME_CNTL, cp_me); |
@@ -2173,6 +2174,7 @@ int r600_cp_start(struct radeon_device *rdev) | |||
2173 | 2174 | ||
2174 | int r600_cp_resume(struct radeon_device *rdev) | 2175 | int r600_cp_resume(struct radeon_device *rdev) |
2175 | { | 2176 | { |
2177 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
2176 | u32 tmp; | 2178 | u32 tmp; |
2177 | u32 rb_bufsz; | 2179 | u32 rb_bufsz; |
2178 | int r; | 2180 | int r; |
@@ -2184,13 +2186,13 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2184 | WREG32(GRBM_SOFT_RESET, 0); | 2186 | WREG32(GRBM_SOFT_RESET, 0); |
2185 | 2187 | ||
2186 | /* Set ring buffer size */ | 2188 | /* Set ring buffer size */ |
2187 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); | 2189 | rb_bufsz = drm_order(ring->ring_size / 8); |
2188 | tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; | 2190 | tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; |
2189 | #ifdef __BIG_ENDIAN | 2191 | #ifdef __BIG_ENDIAN |
2190 | tmp |= BUF_SWAP_32BIT; | 2192 | tmp |= BUF_SWAP_32BIT; |
2191 | #endif | 2193 | #endif |
2192 | WREG32(CP_RB_CNTL, tmp); | 2194 | WREG32(CP_RB_CNTL, tmp); |
2193 | WREG32(CP_SEM_WAIT_TIMER, 0x4); | 2195 | WREG32(CP_SEM_WAIT_TIMER, 0x0); |
2194 | 2196 | ||
2195 | /* Set the write pointer delay */ | 2197 | /* Set the write pointer delay */ |
2196 | WREG32(CP_RB_WPTR_DELAY, 0); | 2198 | WREG32(CP_RB_WPTR_DELAY, 0); |
@@ -2198,8 +2200,8 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2198 | /* Initialize the ring buffer's read and write pointers */ | 2200 | /* Initialize the ring buffer's read and write pointers */ |
2199 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); | 2201 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); |
2200 | WREG32(CP_RB_RPTR_WR, 0); | 2202 | WREG32(CP_RB_RPTR_WR, 0); |
2201 | rdev->cp.wptr = 0; | 2203 | ring->wptr = 0; |
2202 | WREG32(CP_RB_WPTR, rdev->cp.wptr); | 2204 | WREG32(CP_RB_WPTR, ring->wptr); |
2203 | 2205 | ||
2204 | /* set the wb address whether it's enabled or not */ | 2206 | /* set the wb address whether it's enabled or not */ |
2205 | WREG32(CP_RB_RPTR_ADDR, | 2207 | WREG32(CP_RB_RPTR_ADDR, |
@@ -2217,42 +2219,36 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2217 | mdelay(1); | 2219 | mdelay(1); |
2218 | WREG32(CP_RB_CNTL, tmp); | 2220 | WREG32(CP_RB_CNTL, tmp); |
2219 | 2221 | ||
2220 | WREG32(CP_RB_BASE, rdev->cp.gpu_addr >> 8); | 2222 | WREG32(CP_RB_BASE, ring->gpu_addr >> 8); |
2221 | WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); | 2223 | WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); |
2222 | 2224 | ||
2223 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | 2225 | ring->rptr = RREG32(CP_RB_RPTR); |
2224 | 2226 | ||
2225 | r600_cp_start(rdev); | 2227 | r600_cp_start(rdev); |
2226 | rdev->cp.ready = true; | 2228 | ring->ready = true; |
2227 | r = radeon_ring_test(rdev); | 2229 | r = radeon_ring_test(rdev, ring); |
2228 | if (r) { | 2230 | if (r) { |
2229 | rdev->cp.ready = false; | 2231 | ring->ready = false; |
2230 | return r; | 2232 | return r; |
2231 | } | 2233 | } |
2232 | return 0; | 2234 | return 0; |
2233 | } | 2235 | } |
2234 | 2236 | ||
2235 | void r600_cp_commit(struct radeon_device *rdev) | 2237 | void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size) |
2236 | { | ||
2237 | WREG32(CP_RB_WPTR, rdev->cp.wptr); | ||
2238 | (void)RREG32(CP_RB_WPTR); | ||
2239 | } | ||
2240 | |||
2241 | void r600_ring_init(struct radeon_device *rdev, unsigned ring_size) | ||
2242 | { | 2238 | { |
2243 | u32 rb_bufsz; | 2239 | u32 rb_bufsz; |
2244 | 2240 | ||
2245 | /* Align ring size */ | 2241 | /* Align ring size */ |
2246 | rb_bufsz = drm_order(ring_size / 8); | 2242 | rb_bufsz = drm_order(ring_size / 8); |
2247 | ring_size = (1 << (rb_bufsz + 1)) * 4; | 2243 | ring_size = (1 << (rb_bufsz + 1)) * 4; |
2248 | rdev->cp.ring_size = ring_size; | 2244 | ring->ring_size = ring_size; |
2249 | rdev->cp.align_mask = 16 - 1; | 2245 | ring->align_mask = 16 - 1; |
2250 | } | 2246 | } |
2251 | 2247 | ||
2252 | void r600_cp_fini(struct radeon_device *rdev) | 2248 | void r600_cp_fini(struct radeon_device *rdev) |
2253 | { | 2249 | { |
2254 | r600_cp_stop(rdev); | 2250 | r600_cp_stop(rdev); |
2255 | radeon_ring_fini(rdev); | 2251 | radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); |
2256 | } | 2252 | } |
2257 | 2253 | ||
2258 | 2254 | ||
@@ -2271,11 +2267,11 @@ void r600_scratch_init(struct radeon_device *rdev) | |||
2271 | } | 2267 | } |
2272 | } | 2268 | } |
2273 | 2269 | ||
2274 | int r600_ring_test(struct radeon_device *rdev) | 2270 | int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) |
2275 | { | 2271 | { |
2276 | uint32_t scratch; | 2272 | uint32_t scratch; |
2277 | uint32_t tmp = 0; | 2273 | uint32_t tmp = 0; |
2278 | unsigned i; | 2274 | unsigned i, ridx = radeon_ring_index(rdev, ring); |
2279 | int r; | 2275 | int r; |
2280 | 2276 | ||
2281 | r = radeon_scratch_get(rdev, &scratch); | 2277 | r = radeon_scratch_get(rdev, &scratch); |
@@ -2284,16 +2280,16 @@ int r600_ring_test(struct radeon_device *rdev) | |||
2284 | return r; | 2280 | return r; |
2285 | } | 2281 | } |
2286 | WREG32(scratch, 0xCAFEDEAD); | 2282 | WREG32(scratch, 0xCAFEDEAD); |
2287 | r = radeon_ring_lock(rdev, 3); | 2283 | r = radeon_ring_lock(rdev, ring, 3); |
2288 | if (r) { | 2284 | if (r) { |
2289 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | 2285 | DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ridx, r); |
2290 | radeon_scratch_free(rdev, scratch); | 2286 | radeon_scratch_free(rdev, scratch); |
2291 | return r; | 2287 | return r; |
2292 | } | 2288 | } |
2293 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2289 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
2294 | radeon_ring_write(rdev, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | 2290 | radeon_ring_write(ring, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); |
2295 | radeon_ring_write(rdev, 0xDEADBEEF); | 2291 | radeon_ring_write(ring, 0xDEADBEEF); |
2296 | radeon_ring_unlock_commit(rdev); | 2292 | radeon_ring_unlock_commit(rdev, ring); |
2297 | for (i = 0; i < rdev->usec_timeout; i++) { | 2293 | for (i = 0; i < rdev->usec_timeout; i++) { |
2298 | tmp = RREG32(scratch); | 2294 | tmp = RREG32(scratch); |
2299 | if (tmp == 0xDEADBEEF) | 2295 | if (tmp == 0xDEADBEEF) |
@@ -2301,10 +2297,10 @@ int r600_ring_test(struct radeon_device *rdev) | |||
2301 | DRM_UDELAY(1); | 2297 | DRM_UDELAY(1); |
2302 | } | 2298 | } |
2303 | if (i < rdev->usec_timeout) { | 2299 | if (i < rdev->usec_timeout) { |
2304 | DRM_INFO("ring test succeeded in %d usecs\n", i); | 2300 | DRM_INFO("ring test on %d succeeded in %d usecs\n", ridx, i); |
2305 | } else { | 2301 | } else { |
2306 | DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n", | 2302 | DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n", |
2307 | scratch, tmp); | 2303 | ridx, scratch, tmp); |
2308 | r = -EINVAL; | 2304 | r = -EINVAL; |
2309 | } | 2305 | } |
2310 | radeon_scratch_free(rdev, scratch); | 2306 | radeon_scratch_free(rdev, scratch); |
@@ -2314,49 +2310,63 @@ int r600_ring_test(struct radeon_device *rdev) | |||
2314 | void r600_fence_ring_emit(struct radeon_device *rdev, | 2310 | void r600_fence_ring_emit(struct radeon_device *rdev, |
2315 | struct radeon_fence *fence) | 2311 | struct radeon_fence *fence) |
2316 | { | 2312 | { |
2313 | struct radeon_ring *ring = &rdev->ring[fence->ring]; | ||
2314 | |||
2317 | if (rdev->wb.use_event) { | 2315 | if (rdev->wb.use_event) { |
2318 | u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + | 2316 | u64 addr = rdev->fence_drv[fence->ring].gpu_addr; |
2319 | (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); | ||
2320 | /* flush read cache over gart */ | 2317 | /* flush read cache over gart */ |
2321 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 2318 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
2322 | radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | | 2319 | radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | |
2323 | PACKET3_VC_ACTION_ENA | | 2320 | PACKET3_VC_ACTION_ENA | |
2324 | PACKET3_SH_ACTION_ENA); | 2321 | PACKET3_SH_ACTION_ENA); |
2325 | radeon_ring_write(rdev, 0xFFFFFFFF); | 2322 | radeon_ring_write(ring, 0xFFFFFFFF); |
2326 | radeon_ring_write(rdev, 0); | 2323 | radeon_ring_write(ring, 0); |
2327 | radeon_ring_write(rdev, 10); /* poll interval */ | 2324 | radeon_ring_write(ring, 10); /* poll interval */ |
2328 | /* EVENT_WRITE_EOP - flush caches, send int */ | 2325 | /* EVENT_WRITE_EOP - flush caches, send int */ |
2329 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); | 2326 | radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); |
2330 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); | 2327 | radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); |
2331 | radeon_ring_write(rdev, addr & 0xffffffff); | 2328 | radeon_ring_write(ring, addr & 0xffffffff); |
2332 | radeon_ring_write(rdev, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); | 2329 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); |
2333 | radeon_ring_write(rdev, fence->seq); | 2330 | radeon_ring_write(ring, fence->seq); |
2334 | radeon_ring_write(rdev, 0); | 2331 | radeon_ring_write(ring, 0); |
2335 | } else { | 2332 | } else { |
2336 | /* flush read cache over gart */ | 2333 | /* flush read cache over gart */ |
2337 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 2334 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
2338 | radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | | 2335 | radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | |
2339 | PACKET3_VC_ACTION_ENA | | 2336 | PACKET3_VC_ACTION_ENA | |
2340 | PACKET3_SH_ACTION_ENA); | 2337 | PACKET3_SH_ACTION_ENA); |
2341 | radeon_ring_write(rdev, 0xFFFFFFFF); | 2338 | radeon_ring_write(ring, 0xFFFFFFFF); |
2342 | radeon_ring_write(rdev, 0); | 2339 | radeon_ring_write(ring, 0); |
2343 | radeon_ring_write(rdev, 10); /* poll interval */ | 2340 | radeon_ring_write(ring, 10); /* poll interval */ |
2344 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); | 2341 | radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE, 0)); |
2345 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); | 2342 | radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); |
2346 | /* wait for 3D idle clean */ | 2343 | /* wait for 3D idle clean */ |
2347 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2344 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
2348 | radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | 2345 | radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); |
2349 | radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); | 2346 | radeon_ring_write(ring, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); |
2350 | /* Emit fence sequence & fire IRQ */ | 2347 | /* Emit fence sequence & fire IRQ */ |
2351 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2348 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
2352 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | 2349 | radeon_ring_write(ring, ((rdev->fence_drv[fence->ring].scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); |
2353 | radeon_ring_write(rdev, fence->seq); | 2350 | radeon_ring_write(ring, fence->seq); |
2354 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ | 2351 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ |
2355 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); | 2352 | radeon_ring_write(ring, PACKET0(CP_INT_STATUS, 0)); |
2356 | radeon_ring_write(rdev, RB_INT_STAT); | 2353 | radeon_ring_write(ring, RB_INT_STAT); |
2357 | } | 2354 | } |
2358 | } | 2355 | } |
2359 | 2356 | ||
2357 | void r600_semaphore_ring_emit(struct radeon_device *rdev, | ||
2358 | struct radeon_ring *ring, | ||
2359 | struct radeon_semaphore *semaphore, | ||
2360 | bool emit_wait) | ||
2361 | { | ||
2362 | uint64_t addr = semaphore->gpu_addr; | ||
2363 | unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; | ||
2364 | |||
2365 | radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); | ||
2366 | radeon_ring_write(ring, addr & 0xffffffff); | ||
2367 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); | ||
2368 | } | ||
2369 | |||
2360 | int r600_copy_blit(struct radeon_device *rdev, | 2370 | int r600_copy_blit(struct radeon_device *rdev, |
2361 | uint64_t src_offset, | 2371 | uint64_t src_offset, |
2362 | uint64_t dst_offset, | 2372 | uint64_t dst_offset, |
@@ -2409,6 +2419,7 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg) | |||
2409 | 2419 | ||
2410 | int r600_startup(struct radeon_device *rdev) | 2420 | int r600_startup(struct radeon_device *rdev) |
2411 | { | 2421 | { |
2422 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
2412 | int r; | 2423 | int r; |
2413 | 2424 | ||
2414 | /* enable pcie gen2 link */ | 2425 | /* enable pcie gen2 link */ |
@@ -2447,6 +2458,12 @@ int r600_startup(struct radeon_device *rdev) | |||
2447 | if (r) | 2458 | if (r) |
2448 | return r; | 2459 | return r; |
2449 | 2460 | ||
2461 | r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); | ||
2462 | if (r) { | ||
2463 | dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); | ||
2464 | return r; | ||
2465 | } | ||
2466 | |||
2450 | /* Enable IRQ */ | 2467 | /* Enable IRQ */ |
2451 | r = r600_irq_init(rdev); | 2468 | r = r600_irq_init(rdev); |
2452 | if (r) { | 2469 | if (r) { |
@@ -2456,7 +2473,10 @@ int r600_startup(struct radeon_device *rdev) | |||
2456 | } | 2473 | } |
2457 | r600_irq_set(rdev); | 2474 | r600_irq_set(rdev); |
2458 | 2475 | ||
2459 | r = radeon_ring_init(rdev, rdev->cp.ring_size); | 2476 | r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, |
2477 | R600_CP_RB_RPTR, R600_CP_RB_WPTR, | ||
2478 | 0, 0xfffff, RADEON_CP_PACKET2); | ||
2479 | |||
2460 | if (r) | 2480 | if (r) |
2461 | return r; | 2481 | return r; |
2462 | r = r600_cp_load_microcode(rdev); | 2482 | r = r600_cp_load_microcode(rdev); |
@@ -2466,6 +2486,17 @@ int r600_startup(struct radeon_device *rdev) | |||
2466 | if (r) | 2486 | if (r) |
2467 | return r; | 2487 | return r; |
2468 | 2488 | ||
2489 | r = radeon_ib_pool_start(rdev); | ||
2490 | if (r) | ||
2491 | return r; | ||
2492 | |||
2493 | r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); | ||
2494 | if (r) { | ||
2495 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | ||
2496 | rdev->accel_working = false; | ||
2497 | return r; | ||
2498 | } | ||
2499 | |||
2469 | return 0; | 2500 | return 0; |
2470 | } | 2501 | } |
2471 | 2502 | ||
@@ -2494,18 +2525,13 @@ int r600_resume(struct radeon_device *rdev) | |||
2494 | /* post card */ | 2525 | /* post card */ |
2495 | atom_asic_init(rdev->mode_info.atom_context); | 2526 | atom_asic_init(rdev->mode_info.atom_context); |
2496 | 2527 | ||
2528 | rdev->accel_working = true; | ||
2497 | r = r600_startup(rdev); | 2529 | r = r600_startup(rdev); |
2498 | if (r) { | 2530 | if (r) { |
2499 | DRM_ERROR("r600 startup failed on resume\n"); | 2531 | DRM_ERROR("r600 startup failed on resume\n"); |
2500 | return r; | 2532 | return r; |
2501 | } | 2533 | } |
2502 | 2534 | ||
2503 | r = r600_ib_test(rdev); | ||
2504 | if (r) { | ||
2505 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | ||
2506 | return r; | ||
2507 | } | ||
2508 | |||
2509 | r = r600_audio_init(rdev); | 2535 | r = r600_audio_init(rdev); |
2510 | if (r) { | 2536 | if (r) { |
2511 | DRM_ERROR("radeon: audio resume failed\n"); | 2537 | DRM_ERROR("radeon: audio resume failed\n"); |
@@ -2518,13 +2544,14 @@ int r600_resume(struct radeon_device *rdev) | |||
2518 | int r600_suspend(struct radeon_device *rdev) | 2544 | int r600_suspend(struct radeon_device *rdev) |
2519 | { | 2545 | { |
2520 | r600_audio_fini(rdev); | 2546 | r600_audio_fini(rdev); |
2547 | radeon_ib_pool_suspend(rdev); | ||
2548 | r600_blit_suspend(rdev); | ||
2521 | /* FIXME: we should wait for ring to be empty */ | 2549 | /* FIXME: we should wait for ring to be empty */ |
2522 | r600_cp_stop(rdev); | 2550 | r600_cp_stop(rdev); |
2523 | rdev->cp.ready = false; | 2551 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
2524 | r600_irq_suspend(rdev); | 2552 | r600_irq_suspend(rdev); |
2525 | radeon_wb_disable(rdev); | 2553 | radeon_wb_disable(rdev); |
2526 | r600_pcie_gart_disable(rdev); | 2554 | r600_pcie_gart_disable(rdev); |
2527 | r600_blit_suspend(rdev); | ||
2528 | 2555 | ||
2529 | return 0; | 2556 | return 0; |
2530 | } | 2557 | } |
@@ -2595,8 +2622,8 @@ int r600_init(struct radeon_device *rdev) | |||
2595 | if (r) | 2622 | if (r) |
2596 | return r; | 2623 | return r; |
2597 | 2624 | ||
2598 | rdev->cp.ring_obj = NULL; | 2625 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; |
2599 | r600_ring_init(rdev, 1024 * 1024); | 2626 | r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); |
2600 | 2627 | ||
2601 | rdev->ih.ring_obj = NULL; | 2628 | rdev->ih.ring_obj = NULL; |
2602 | r600_ih_ring_init(rdev, 64 * 1024); | 2629 | r600_ih_ring_init(rdev, 64 * 1024); |
@@ -2605,30 +2632,24 @@ int r600_init(struct radeon_device *rdev) | |||
2605 | if (r) | 2632 | if (r) |
2606 | return r; | 2633 | return r; |
2607 | 2634 | ||
2635 | r = radeon_ib_pool_init(rdev); | ||
2608 | rdev->accel_working = true; | 2636 | rdev->accel_working = true; |
2637 | if (r) { | ||
2638 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
2639 | rdev->accel_working = false; | ||
2640 | } | ||
2641 | |||
2609 | r = r600_startup(rdev); | 2642 | r = r600_startup(rdev); |
2610 | if (r) { | 2643 | if (r) { |
2611 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 2644 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
2612 | r600_cp_fini(rdev); | 2645 | r600_cp_fini(rdev); |
2613 | r600_irq_fini(rdev); | 2646 | r600_irq_fini(rdev); |
2614 | radeon_wb_fini(rdev); | 2647 | radeon_wb_fini(rdev); |
2648 | r100_ib_fini(rdev); | ||
2615 | radeon_irq_kms_fini(rdev); | 2649 | radeon_irq_kms_fini(rdev); |
2616 | r600_pcie_gart_fini(rdev); | 2650 | r600_pcie_gart_fini(rdev); |
2617 | rdev->accel_working = false; | 2651 | rdev->accel_working = false; |
2618 | } | 2652 | } |
2619 | if (rdev->accel_working) { | ||
2620 | r = radeon_ib_pool_init(rdev); | ||
2621 | if (r) { | ||
2622 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | ||
2623 | rdev->accel_working = false; | ||
2624 | } else { | ||
2625 | r = r600_ib_test(rdev); | ||
2626 | if (r) { | ||
2627 | dev_err(rdev->dev, "IB test failed (%d).\n", r); | ||
2628 | rdev->accel_working = false; | ||
2629 | } | ||
2630 | } | ||
2631 | } | ||
2632 | 2653 | ||
2633 | r = r600_audio_init(rdev); | 2654 | r = r600_audio_init(rdev); |
2634 | if (r) | 2655 | if (r) |
@@ -2643,12 +2664,13 @@ void r600_fini(struct radeon_device *rdev) | |||
2643 | r600_cp_fini(rdev); | 2664 | r600_cp_fini(rdev); |
2644 | r600_irq_fini(rdev); | 2665 | r600_irq_fini(rdev); |
2645 | radeon_wb_fini(rdev); | 2666 | radeon_wb_fini(rdev); |
2646 | radeon_ib_pool_fini(rdev); | 2667 | r100_ib_fini(rdev); |
2647 | radeon_irq_kms_fini(rdev); | 2668 | radeon_irq_kms_fini(rdev); |
2648 | r600_pcie_gart_fini(rdev); | 2669 | r600_pcie_gart_fini(rdev); |
2649 | r600_vram_scratch_fini(rdev); | 2670 | r600_vram_scratch_fini(rdev); |
2650 | radeon_agp_fini(rdev); | 2671 | radeon_agp_fini(rdev); |
2651 | radeon_gem_fini(rdev); | 2672 | radeon_gem_fini(rdev); |
2673 | radeon_semaphore_driver_fini(rdev); | ||
2652 | radeon_fence_driver_fini(rdev); | 2674 | radeon_fence_driver_fini(rdev); |
2653 | radeon_bo_fini(rdev); | 2675 | radeon_bo_fini(rdev); |
2654 | radeon_atombios_fini(rdev); | 2676 | radeon_atombios_fini(rdev); |
@@ -2662,18 +2684,20 @@ void r600_fini(struct radeon_device *rdev) | |||
2662 | */ | 2684 | */ |
2663 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 2685 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
2664 | { | 2686 | { |
2687 | struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; | ||
2688 | |||
2665 | /* FIXME: implement */ | 2689 | /* FIXME: implement */ |
2666 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 2690 | radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
2667 | radeon_ring_write(rdev, | 2691 | radeon_ring_write(ring, |
2668 | #ifdef __BIG_ENDIAN | 2692 | #ifdef __BIG_ENDIAN |
2669 | (2 << 0) | | 2693 | (2 << 0) | |
2670 | #endif | 2694 | #endif |
2671 | (ib->gpu_addr & 0xFFFFFFFC)); | 2695 | (ib->gpu_addr & 0xFFFFFFFC)); |
2672 | radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); | 2696 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); |
2673 | radeon_ring_write(rdev, ib->length_dw); | 2697 | radeon_ring_write(ring, ib->length_dw); |
2674 | } | 2698 | } |
2675 | 2699 | ||
2676 | int r600_ib_test(struct radeon_device *rdev) | 2700 | int r600_ib_test(struct radeon_device *rdev, int ring) |
2677 | { | 2701 | { |
2678 | struct radeon_ib *ib; | 2702 | struct radeon_ib *ib; |
2679 | uint32_t scratch; | 2703 | uint32_t scratch; |
@@ -2687,7 +2711,7 @@ int r600_ib_test(struct radeon_device *rdev) | |||
2687 | return r; | 2711 | return r; |
2688 | } | 2712 | } |
2689 | WREG32(scratch, 0xCAFEDEAD); | 2713 | WREG32(scratch, 0xCAFEDEAD); |
2690 | r = radeon_ib_get(rdev, &ib); | 2714 | r = radeon_ib_get(rdev, ring, &ib, 256); |
2691 | if (r) { | 2715 | if (r) { |
2692 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); | 2716 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); |
2693 | return r; | 2717 | return r; |
@@ -2728,7 +2752,7 @@ int r600_ib_test(struct radeon_device *rdev) | |||
2728 | DRM_UDELAY(1); | 2752 | DRM_UDELAY(1); |
2729 | } | 2753 | } |
2730 | if (i < rdev->usec_timeout) { | 2754 | if (i < rdev->usec_timeout) { |
2731 | DRM_INFO("ib test succeeded in %u usecs\n", i); | 2755 | DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib->fence->ring, i); |
2732 | } else { | 2756 | } else { |
2733 | DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", | 2757 | DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", |
2734 | scratch, tmp); | 2758 | scratch, tmp); |
@@ -3075,7 +3099,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3075 | hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3099 | hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3076 | } | 3100 | } |
3077 | 3101 | ||
3078 | if (rdev->irq.sw_int) { | 3102 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { |
3079 | DRM_DEBUG("r600_irq_set: sw int\n"); | 3103 | DRM_DEBUG("r600_irq_set: sw int\n"); |
3080 | cp_int_cntl |= RB_INT_ENABLE; | 3104 | cp_int_cntl |= RB_INT_ENABLE; |
3081 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 3105 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
@@ -3459,11 +3483,11 @@ restart_ih: | |||
3459 | case 177: /* CP_INT in IB1 */ | 3483 | case 177: /* CP_INT in IB1 */ |
3460 | case 178: /* CP_INT in IB2 */ | 3484 | case 178: /* CP_INT in IB2 */ |
3461 | DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); | 3485 | DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); |
3462 | radeon_fence_process(rdev); | 3486 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
3463 | break; | 3487 | break; |
3464 | case 181: /* CP EOP event */ | 3488 | case 181: /* CP EOP event */ |
3465 | DRM_DEBUG("IH: CP EOP\n"); | 3489 | DRM_DEBUG("IH: CP EOP\n"); |
3466 | radeon_fence_process(rdev); | 3490 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
3467 | break; | 3491 | break; |
3468 | case 233: /* GUI IDLE */ | 3492 | case 233: /* GUI IDLE */ |
3469 | DRM_DEBUG("IH: GUI idle\n"); | 3493 | DRM_DEBUG("IH: GUI idle\n"); |
@@ -3496,30 +3520,6 @@ restart_ih: | |||
3496 | */ | 3520 | */ |
3497 | #if defined(CONFIG_DEBUG_FS) | 3521 | #if defined(CONFIG_DEBUG_FS) |
3498 | 3522 | ||
3499 | static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data) | ||
3500 | { | ||
3501 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
3502 | struct drm_device *dev = node->minor->dev; | ||
3503 | struct radeon_device *rdev = dev->dev_private; | ||
3504 | unsigned count, i, j; | ||
3505 | |||
3506 | radeon_ring_free_size(rdev); | ||
3507 | count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw; | ||
3508 | seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); | ||
3509 | seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR)); | ||
3510 | seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR)); | ||
3511 | seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr); | ||
3512 | seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr); | ||
3513 | seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); | ||
3514 | seq_printf(m, "%u dwords in ring\n", count); | ||
3515 | i = rdev->cp.rptr; | ||
3516 | for (j = 0; j <= count; j++) { | ||
3517 | seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); | ||
3518 | i = (i + 1) & rdev->cp.ptr_mask; | ||
3519 | } | ||
3520 | return 0; | ||
3521 | } | ||
3522 | |||
3523 | static int r600_debugfs_mc_info(struct seq_file *m, void *data) | 3523 | static int r600_debugfs_mc_info(struct seq_file *m, void *data) |
3524 | { | 3524 | { |
3525 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 3525 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -3533,7 +3533,6 @@ static int r600_debugfs_mc_info(struct seq_file *m, void *data) | |||
3533 | 3533 | ||
3534 | static struct drm_info_list r600_mc_info_list[] = { | 3534 | static struct drm_info_list r600_mc_info_list[] = { |
3535 | {"r600_mc_info", r600_debugfs_mc_info, 0, NULL}, | 3535 | {"r600_mc_info", r600_debugfs_mc_info, 0, NULL}, |
3536 | {"r600_ring_info", r600_debugfs_cp_ring_info, 0, NULL}, | ||
3537 | }; | 3536 | }; |
3538 | #endif | 3537 | #endif |
3539 | 3538 | ||