diff options
Diffstat (limited to 'drivers/gpu/drm/radeon')
33 files changed, 449 insertions, 346 deletions
diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig index 5982321be4d5..1c02d23f6fcc 100644 --- a/drivers/gpu/drm/radeon/Kconfig +++ b/drivers/gpu/drm/radeon/Kconfig | |||
@@ -1,10 +1,14 @@ | |||
1 | config DRM_RADEON_KMS | 1 | config DRM_RADEON_KMS |
2 | bool "Enable modesetting on radeon by default" | 2 | bool "Enable modesetting on radeon by default - NEW DRIVER" |
3 | depends on DRM_RADEON | 3 | depends on DRM_RADEON |
4 | help | 4 | help |
5 | Choose this option if you want kernel modesetting enabled by default, | 5 | Choose this option if you want kernel modesetting enabled by default. |
6 | and you have a new enough userspace to support this. Running old | 6 | |
7 | userspaces with this enabled will cause pain. | 7 | This is a completely new driver. It's only part of the existing drm |
8 | for compatibility reasons. It requires an entirely different graphics | ||
9 | stack above it and works very differently from the old drm stack. | ||
10 | i.e. don't enable this unless you know what you are doing it may | ||
11 | cause issues or bugs compared to the previous userspace driver stack. | ||
8 | 12 | ||
9 | When kernel modesetting is enabled the IOCTL of radeon/drm | 13 | When kernel modesetting is enabled the IOCTL of radeon/drm |
10 | driver are considered as invalid and an error message is printed | 14 | driver are considered as invalid and an error message is printed |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index e3b44562d265..7f152f66f196 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <asm/unaligned.h> | ||
27 | 28 | ||
28 | #define ATOM_DEBUG | 29 | #define ATOM_DEBUG |
29 | 30 | ||
@@ -212,7 +213,9 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, | |||
212 | case ATOM_ARG_PS: | 213 | case ATOM_ARG_PS: |
213 | idx = U8(*ptr); | 214 | idx = U8(*ptr); |
214 | (*ptr)++; | 215 | (*ptr)++; |
215 | val = le32_to_cpu(ctx->ps[idx]); | 216 | /* get_unaligned_le32 avoids unaligned accesses from atombios |
217 | * tables, noticed on a DEC Alpha. */ | ||
218 | val = get_unaligned_le32((u32 *)&ctx->ps[idx]); | ||
216 | if (print) | 219 | if (print) |
217 | DEBUG("PS[0x%02X,0x%04X]", idx, val); | 220 | DEBUG("PS[0x%02X,0x%04X]", idx, val); |
218 | break; | 221 | break; |
@@ -640,7 +643,7 @@ static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg) | |||
640 | uint8_t count = U8((*ptr)++); | 643 | uint8_t count = U8((*ptr)++); |
641 | SDEBUG(" count: %d\n", count); | 644 | SDEBUG(" count: %d\n", count); |
642 | if (arg == ATOM_UNIT_MICROSEC) | 645 | if (arg == ATOM_UNIT_MICROSEC) |
643 | schedule_timeout_uninterruptible(usecs_to_jiffies(count)); | 646 | udelay(count); |
644 | else | 647 | else |
645 | schedule_timeout_uninterruptible(msecs_to_jiffies(count)); | 648 | schedule_timeout_uninterruptible(msecs_to_jiffies(count)); |
646 | } | 649 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 3eb0ca5b3d73..99915a682d59 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -332,11 +332,13 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | |||
332 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; | 332 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; |
333 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); | 333 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); |
334 | unsigned char *base; | 334 | unsigned char *base; |
335 | int retry_count = 0; | ||
335 | 336 | ||
336 | memset(&args, 0, sizeof(args)); | 337 | memset(&args, 0, sizeof(args)); |
337 | 338 | ||
338 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; | 339 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; |
339 | 340 | ||
341 | retry: | ||
340 | memcpy(base, req_bytes, num_bytes); | 342 | memcpy(base, req_bytes, num_bytes); |
341 | 343 | ||
342 | args.lpAuxRequest = 0; | 344 | args.lpAuxRequest = 0; |
@@ -347,10 +349,12 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | |||
347 | 349 | ||
348 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 350 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
349 | 351 | ||
350 | if (args.ucReplyStatus) { | 352 | if (args.ucReplyStatus && !args.ucDataOutLen) { |
351 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n", | 353 | if (args.ucReplyStatus == 0x20 && retry_count++ < 10) |
354 | goto retry; | ||
355 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", | ||
352 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], | 356 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], |
353 | chan->rec.i2c_id, args.ucReplyStatus); | 357 | chan->rec.i2c_id, args.ucReplyStatus, retry_count); |
354 | return false; | 358 | return false; |
355 | } | 359 | } |
356 | 360 | ||
@@ -468,7 +472,7 @@ void radeon_dp_set_link_config(struct drm_connector *connector, | |||
468 | struct radeon_connector *radeon_connector; | 472 | struct radeon_connector *radeon_connector; |
469 | struct radeon_connector_atom_dig *dig_connector; | 473 | struct radeon_connector_atom_dig *dig_connector; |
470 | 474 | ||
471 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) || | 475 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) && |
472 | (connector->connector_type != DRM_MODE_CONNECTOR_eDP)) | 476 | (connector->connector_type != DRM_MODE_CONNECTOR_eDP)) |
473 | return; | 477 | return; |
474 | 478 | ||
@@ -583,7 +587,7 @@ void dp_link_train(struct drm_encoder *encoder, | |||
583 | u8 train_set[4]; | 587 | u8 train_set[4]; |
584 | int i; | 588 | int i; |
585 | 589 | ||
586 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) || | 590 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) && |
587 | (connector->connector_type != DRM_MODE_CONNECTOR_eDP)) | 591 | (connector->connector_type != DRM_MODE_CONNECTOR_eDP)) |
588 | return; | 592 | return; |
589 | 593 | ||
@@ -596,21 +600,14 @@ void dp_link_train(struct drm_encoder *encoder, | |||
596 | return; | 600 | return; |
597 | dig_connector = radeon_connector->con_priv; | 601 | dig_connector = radeon_connector->con_priv; |
598 | 602 | ||
599 | if (ASIC_IS_DCE32(rdev)) { | 603 | if (dig->dig_encoder) |
600 | if (dig->dig_block) | 604 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; |
601 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | 605 | else |
602 | else | 606 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; |
603 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; | 607 | if (dig_connector->linkb) |
604 | if (dig_connector->linkb) | 608 | enc_id |= ATOM_DP_CONFIG_LINK_B; |
605 | enc_id |= ATOM_DP_CONFIG_LINK_B; | 609 | else |
606 | else | 610 | enc_id |= ATOM_DP_CONFIG_LINK_A; |
607 | enc_id |= ATOM_DP_CONFIG_LINK_A; | ||
608 | } else { | ||
609 | if (dig_connector->linkb) | ||
610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER | ATOM_DP_CONFIG_LINK_B; | ||
611 | else | ||
612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER | ATOM_DP_CONFIG_LINK_A; | ||
613 | } | ||
614 | 611 | ||
615 | memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 612 | memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
616 | if (dig_connector->dp_clock == 270000) | 613 | if (dig_connector->dp_clock == 270000) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 11c9a3fe6810..c0d4650cdb79 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -354,11 +354,17 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) | |||
354 | return RREG32(RADEON_CRTC2_CRNT_FRAME); | 354 | return RREG32(RADEON_CRTC2_CRNT_FRAME); |
355 | } | 355 | } |
356 | 356 | ||
357 | /* Who ever call radeon_fence_emit should call ring_lock and ask | ||
358 | * for enough space (today caller are ib schedule and buffer move) */ | ||
357 | void r100_fence_ring_emit(struct radeon_device *rdev, | 359 | void r100_fence_ring_emit(struct radeon_device *rdev, |
358 | struct radeon_fence *fence) | 360 | struct radeon_fence *fence) |
359 | { | 361 | { |
360 | /* Who ever call radeon_fence_emit should call ring_lock and ask | 362 | /* We have to make sure that caches are flushed before |
361 | * for enough space (today caller are ib schedule and buffer move) */ | 363 | * CPU might read something from VRAM. */ |
364 | radeon_ring_write(rdev, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); | ||
365 | radeon_ring_write(rdev, RADEON_RB3D_DC_FLUSH_ALL); | ||
366 | radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); | ||
367 | radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL); | ||
362 | /* Wait until IDLE & CLEAN */ | 368 | /* Wait until IDLE & CLEAN */ |
363 | radeon_ring_write(rdev, PACKET0(0x1720, 0)); | 369 | radeon_ring_write(rdev, PACKET0(0x1720, 0)); |
364 | radeon_ring_write(rdev, (1 << 16) | (1 << 17)); | 370 | radeon_ring_write(rdev, (1 << 16) | (1 << 17)); |
@@ -3369,7 +3375,6 @@ int r100_suspend(struct radeon_device *rdev) | |||
3369 | 3375 | ||
3370 | void r100_fini(struct radeon_device *rdev) | 3376 | void r100_fini(struct radeon_device *rdev) |
3371 | { | 3377 | { |
3372 | r100_suspend(rdev); | ||
3373 | r100_cp_fini(rdev); | 3378 | r100_cp_fini(rdev); |
3374 | r100_wb_fini(rdev); | 3379 | r100_wb_fini(rdev); |
3375 | r100_ib_fini(rdev); | 3380 | r100_ib_fini(rdev); |
@@ -3481,13 +3486,12 @@ int r100_init(struct radeon_device *rdev) | |||
3481 | if (r) { | 3486 | if (r) { |
3482 | /* Somethings want wront with the accel init stop accel */ | 3487 | /* Somethings want wront with the accel init stop accel */ |
3483 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 3488 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
3484 | r100_suspend(rdev); | ||
3485 | r100_cp_fini(rdev); | 3489 | r100_cp_fini(rdev); |
3486 | r100_wb_fini(rdev); | 3490 | r100_wb_fini(rdev); |
3487 | r100_ib_fini(rdev); | 3491 | r100_ib_fini(rdev); |
3492 | radeon_irq_kms_fini(rdev); | ||
3488 | if (rdev->flags & RADEON_IS_PCI) | 3493 | if (rdev->flags & RADEON_IS_PCI) |
3489 | r100_pci_gart_fini(rdev); | 3494 | r100_pci_gart_fini(rdev); |
3490 | radeon_irq_kms_fini(rdev); | ||
3491 | rdev->accel_working = false; | 3495 | rdev->accel_working = false; |
3492 | } | 3496 | } |
3493 | return 0; | 3497 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 0051d11b907c..43b55a030b4d 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -506,11 +506,14 @@ void r300_vram_info(struct radeon_device *rdev) | |||
506 | 506 | ||
507 | /* DDR for all card after R300 & IGP */ | 507 | /* DDR for all card after R300 & IGP */ |
508 | rdev->mc.vram_is_ddr = true; | 508 | rdev->mc.vram_is_ddr = true; |
509 | |||
509 | tmp = RREG32(RADEON_MEM_CNTL); | 510 | tmp = RREG32(RADEON_MEM_CNTL); |
510 | if (tmp & R300_MEM_NUM_CHANNELS_MASK) { | 511 | tmp &= R300_MEM_NUM_CHANNELS_MASK; |
511 | rdev->mc.vram_width = 128; | 512 | switch (tmp) { |
512 | } else { | 513 | case 0: rdev->mc.vram_width = 64; break; |
513 | rdev->mc.vram_width = 64; | 514 | case 1: rdev->mc.vram_width = 128; break; |
515 | case 2: rdev->mc.vram_width = 256; break; | ||
516 | default: rdev->mc.vram_width = 128; break; | ||
514 | } | 517 | } |
515 | 518 | ||
516 | r100_vram_init_sizes(rdev); | 519 | r100_vram_init_sizes(rdev); |
@@ -1327,7 +1330,6 @@ int r300_suspend(struct radeon_device *rdev) | |||
1327 | 1330 | ||
1328 | void r300_fini(struct radeon_device *rdev) | 1331 | void r300_fini(struct radeon_device *rdev) |
1329 | { | 1332 | { |
1330 | r300_suspend(rdev); | ||
1331 | r100_cp_fini(rdev); | 1333 | r100_cp_fini(rdev); |
1332 | r100_wb_fini(rdev); | 1334 | r100_wb_fini(rdev); |
1333 | r100_ib_fini(rdev); | 1335 | r100_ib_fini(rdev); |
@@ -1418,15 +1420,15 @@ int r300_init(struct radeon_device *rdev) | |||
1418 | if (r) { | 1420 | if (r) { |
1419 | /* Somethings want wront with the accel init stop accel */ | 1421 | /* Somethings want wront with the accel init stop accel */ |
1420 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 1422 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
1421 | r300_suspend(rdev); | ||
1422 | r100_cp_fini(rdev); | 1423 | r100_cp_fini(rdev); |
1423 | r100_wb_fini(rdev); | 1424 | r100_wb_fini(rdev); |
1424 | r100_ib_fini(rdev); | 1425 | r100_ib_fini(rdev); |
1426 | radeon_irq_kms_fini(rdev); | ||
1425 | if (rdev->flags & RADEON_IS_PCIE) | 1427 | if (rdev->flags & RADEON_IS_PCIE) |
1426 | rv370_pcie_gart_fini(rdev); | 1428 | rv370_pcie_gart_fini(rdev); |
1427 | if (rdev->flags & RADEON_IS_PCI) | 1429 | if (rdev->flags & RADEON_IS_PCI) |
1428 | r100_pci_gart_fini(rdev); | 1430 | r100_pci_gart_fini(rdev); |
1429 | radeon_irq_kms_fini(rdev); | 1431 | radeon_agp_fini(rdev); |
1430 | rdev->accel_working = false; | 1432 | rdev->accel_working = false; |
1431 | } | 1433 | } |
1432 | return 0; | 1434 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 4526faaacca8..d9373246c97f 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -389,16 +389,15 @@ int r420_init(struct radeon_device *rdev) | |||
389 | if (r) { | 389 | if (r) { |
390 | /* Somethings want wront with the accel init stop accel */ | 390 | /* Somethings want wront with the accel init stop accel */ |
391 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 391 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
392 | r420_suspend(rdev); | ||
393 | r100_cp_fini(rdev); | 392 | r100_cp_fini(rdev); |
394 | r100_wb_fini(rdev); | 393 | r100_wb_fini(rdev); |
395 | r100_ib_fini(rdev); | 394 | r100_ib_fini(rdev); |
395 | radeon_irq_kms_fini(rdev); | ||
396 | if (rdev->flags & RADEON_IS_PCIE) | 396 | if (rdev->flags & RADEON_IS_PCIE) |
397 | rv370_pcie_gart_fini(rdev); | 397 | rv370_pcie_gart_fini(rdev); |
398 | if (rdev->flags & RADEON_IS_PCI) | 398 | if (rdev->flags & RADEON_IS_PCI) |
399 | r100_pci_gart_fini(rdev); | 399 | r100_pci_gart_fini(rdev); |
400 | radeon_agp_fini(rdev); | 400 | radeon_agp_fini(rdev); |
401 | radeon_irq_kms_fini(rdev); | ||
402 | rdev->accel_working = false; | 401 | rdev->accel_working = false; |
403 | } | 402 | } |
404 | return 0; | 403 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 9a189072f2b9..ddf5731eba0d 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -294,13 +294,12 @@ int r520_init(struct radeon_device *rdev) | |||
294 | if (r) { | 294 | if (r) { |
295 | /* Somethings want wront with the accel init stop accel */ | 295 | /* Somethings want wront with the accel init stop accel */ |
296 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 296 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
297 | rv515_suspend(rdev); | ||
298 | r100_cp_fini(rdev); | 297 | r100_cp_fini(rdev); |
299 | r100_wb_fini(rdev); | 298 | r100_wb_fini(rdev); |
300 | r100_ib_fini(rdev); | 299 | r100_ib_fini(rdev); |
300 | radeon_irq_kms_fini(rdev); | ||
301 | rv370_pcie_gart_fini(rdev); | 301 | rv370_pcie_gart_fini(rdev); |
302 | radeon_agp_fini(rdev); | 302 | radeon_agp_fini(rdev); |
303 | radeon_irq_kms_fini(rdev); | ||
304 | rdev->accel_working = false; | 303 | rdev->accel_working = false; |
305 | } | 304 | } |
306 | return 0; | 305 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index da9aa3c31bcf..2ffcf5a03551 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1654,6 +1654,12 @@ void r600_ring_init(struct radeon_device *rdev, unsigned ring_size) | |||
1654 | rdev->cp.align_mask = 16 - 1; | 1654 | rdev->cp.align_mask = 16 - 1; |
1655 | } | 1655 | } |
1656 | 1656 | ||
1657 | void r600_cp_fini(struct radeon_device *rdev) | ||
1658 | { | ||
1659 | r600_cp_stop(rdev); | ||
1660 | radeon_ring_fini(rdev); | ||
1661 | } | ||
1662 | |||
1657 | 1663 | ||
1658 | /* | 1664 | /* |
1659 | * GPU scratch registers helpers function. | 1665 | * GPU scratch registers helpers function. |
@@ -1788,23 +1794,24 @@ void r600_fence_ring_emit(struct radeon_device *rdev, | |||
1788 | radeon_ring_write(rdev, RB_INT_STAT); | 1794 | radeon_ring_write(rdev, RB_INT_STAT); |
1789 | } | 1795 | } |
1790 | 1796 | ||
1791 | int r600_copy_dma(struct radeon_device *rdev, | ||
1792 | uint64_t src_offset, | ||
1793 | uint64_t dst_offset, | ||
1794 | unsigned num_pages, | ||
1795 | struct radeon_fence *fence) | ||
1796 | { | ||
1797 | /* FIXME: implement */ | ||
1798 | return 0; | ||
1799 | } | ||
1800 | |||
1801 | int r600_copy_blit(struct radeon_device *rdev, | 1797 | int r600_copy_blit(struct radeon_device *rdev, |
1802 | uint64_t src_offset, uint64_t dst_offset, | 1798 | uint64_t src_offset, uint64_t dst_offset, |
1803 | unsigned num_pages, struct radeon_fence *fence) | 1799 | unsigned num_pages, struct radeon_fence *fence) |
1804 | { | 1800 | { |
1805 | r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); | 1801 | int r; |
1802 | |||
1803 | mutex_lock(&rdev->r600_blit.mutex); | ||
1804 | rdev->r600_blit.vb_ib = NULL; | ||
1805 | r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); | ||
1806 | if (r) { | ||
1807 | if (rdev->r600_blit.vb_ib) | ||
1808 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); | ||
1809 | mutex_unlock(&rdev->r600_blit.mutex); | ||
1810 | return r; | ||
1811 | } | ||
1806 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); | 1812 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); |
1807 | r600_blit_done_copy(rdev, fence); | 1813 | r600_blit_done_copy(rdev, fence); |
1814 | mutex_unlock(&rdev->r600_blit.mutex); | ||
1808 | return 0; | 1815 | return 0; |
1809 | } | 1816 | } |
1810 | 1817 | ||
@@ -1860,26 +1867,25 @@ int r600_startup(struct radeon_device *rdev) | |||
1860 | return r; | 1867 | return r; |
1861 | } | 1868 | } |
1862 | r600_gpu_init(rdev); | 1869 | r600_gpu_init(rdev); |
1863 | 1870 | r = r600_blit_init(rdev); | |
1864 | if (!rdev->r600_blit.shader_obj) { | 1871 | if (r) { |
1865 | r = r600_blit_init(rdev); | 1872 | r600_blit_fini(rdev); |
1873 | rdev->asic->copy = NULL; | ||
1874 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
1875 | } | ||
1876 | /* pin copy shader into vram */ | ||
1877 | if (rdev->r600_blit.shader_obj) { | ||
1878 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
1879 | if (unlikely(r != 0)) | ||
1880 | return r; | ||
1881 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
1882 | &rdev->r600_blit.shader_gpu_addr); | ||
1883 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
1866 | if (r) { | 1884 | if (r) { |
1867 | DRM_ERROR("radeon: failed blitter (%d).\n", r); | 1885 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); |
1868 | return r; | 1886 | return r; |
1869 | } | 1887 | } |
1870 | } | 1888 | } |
1871 | |||
1872 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
1873 | if (unlikely(r != 0)) | ||
1874 | return r; | ||
1875 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
1876 | &rdev->r600_blit.shader_gpu_addr); | ||
1877 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
1878 | if (r) { | ||
1879 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | ||
1880 | return r; | ||
1881 | } | ||
1882 | |||
1883 | /* Enable IRQ */ | 1889 | /* Enable IRQ */ |
1884 | r = r600_irq_init(rdev); | 1890 | r = r600_irq_init(rdev); |
1885 | if (r) { | 1891 | if (r) { |
@@ -1944,6 +1950,13 @@ int r600_resume(struct radeon_device *rdev) | |||
1944 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | 1950 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); |
1945 | return r; | 1951 | return r; |
1946 | } | 1952 | } |
1953 | |||
1954 | r = r600_audio_init(rdev); | ||
1955 | if (r) { | ||
1956 | DRM_ERROR("radeon: audio resume failed\n"); | ||
1957 | return r; | ||
1958 | } | ||
1959 | |||
1947 | return r; | 1960 | return r; |
1948 | } | 1961 | } |
1949 | 1962 | ||
@@ -1951,6 +1964,7 @@ int r600_suspend(struct radeon_device *rdev) | |||
1951 | { | 1964 | { |
1952 | int r; | 1965 | int r; |
1953 | 1966 | ||
1967 | r600_audio_fini(rdev); | ||
1954 | /* FIXME: we should wait for ring to be empty */ | 1968 | /* FIXME: we should wait for ring to be empty */ |
1955 | r600_cp_stop(rdev); | 1969 | r600_cp_stop(rdev); |
1956 | rdev->cp.ready = false; | 1970 | rdev->cp.ready = false; |
@@ -2055,9 +2069,11 @@ int r600_init(struct radeon_device *rdev) | |||
2055 | rdev->accel_working = true; | 2069 | rdev->accel_working = true; |
2056 | r = r600_startup(rdev); | 2070 | r = r600_startup(rdev); |
2057 | if (r) { | 2071 | if (r) { |
2058 | r600_suspend(rdev); | 2072 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
2073 | r600_cp_fini(rdev); | ||
2059 | r600_wb_fini(rdev); | 2074 | r600_wb_fini(rdev); |
2060 | radeon_ring_fini(rdev); | 2075 | r600_irq_fini(rdev); |
2076 | radeon_irq_kms_fini(rdev); | ||
2061 | r600_pcie_gart_fini(rdev); | 2077 | r600_pcie_gart_fini(rdev); |
2062 | rdev->accel_working = false; | 2078 | rdev->accel_working = false; |
2063 | } | 2079 | } |
@@ -2083,20 +2099,17 @@ int r600_init(struct radeon_device *rdev) | |||
2083 | 2099 | ||
2084 | void r600_fini(struct radeon_device *rdev) | 2100 | void r600_fini(struct radeon_device *rdev) |
2085 | { | 2101 | { |
2086 | /* Suspend operations */ | ||
2087 | r600_suspend(rdev); | ||
2088 | |||
2089 | r600_audio_fini(rdev); | 2102 | r600_audio_fini(rdev); |
2090 | r600_blit_fini(rdev); | 2103 | r600_blit_fini(rdev); |
2104 | r600_cp_fini(rdev); | ||
2105 | r600_wb_fini(rdev); | ||
2091 | r600_irq_fini(rdev); | 2106 | r600_irq_fini(rdev); |
2092 | radeon_irq_kms_fini(rdev); | 2107 | radeon_irq_kms_fini(rdev); |
2093 | radeon_ring_fini(rdev); | ||
2094 | r600_wb_fini(rdev); | ||
2095 | r600_pcie_gart_fini(rdev); | 2108 | r600_pcie_gart_fini(rdev); |
2109 | radeon_agp_fini(rdev); | ||
2096 | radeon_gem_fini(rdev); | 2110 | radeon_gem_fini(rdev); |
2097 | radeon_fence_driver_fini(rdev); | 2111 | radeon_fence_driver_fini(rdev); |
2098 | radeon_clocks_fini(rdev); | 2112 | radeon_clocks_fini(rdev); |
2099 | radeon_agp_fini(rdev); | ||
2100 | radeon_bo_fini(rdev); | 2113 | radeon_bo_fini(rdev); |
2101 | radeon_atombios_fini(rdev); | 2114 | radeon_atombios_fini(rdev); |
2102 | kfree(rdev->bios); | 2115 | kfree(rdev->bios); |
@@ -2900,3 +2913,18 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) | |||
2900 | return 0; | 2913 | return 0; |
2901 | #endif | 2914 | #endif |
2902 | } | 2915 | } |
2916 | |||
2917 | /** | ||
2918 | * r600_ioctl_wait_idle - flush host path cache on wait idle ioctl | ||
2919 | * rdev: radeon device structure | ||
2920 | * bo: buffer object struct which userspace is waiting for idle | ||
2921 | * | ||
2922 | * Some R6XX/R7XX doesn't seems to take into account HDP flush performed | ||
2923 | * through ring buffer, this leads to corruption in rendering, see | ||
2924 | * http://bugzilla.kernel.org/show_bug.cgi?id=15186 to avoid this we | ||
2925 | * directly perform HDP flush by writing register through MMIO. | ||
2926 | */ | ||
2927 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | ||
2928 | { | ||
2929 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
2930 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 99e2c3891a7d..0dcb6904c4ff 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | 36 | static int r600_audio_chipset_supported(struct radeon_device *rdev) |
37 | { | 37 | { |
38 | return rdev->family >= CHIP_R600 | 38 | return (rdev->family >= CHIP_R600 && rdev->family < CHIP_RV710) |
39 | || rdev->family == CHIP_RS600 | 39 | || rdev->family == CHIP_RS600 |
40 | || rdev->family == CHIP_RS690 | 40 | || rdev->family == CHIP_RS690 |
41 | || rdev->family == CHIP_RS740; | 41 | || rdev->family == CHIP_RS740; |
@@ -261,7 +261,6 @@ void r600_audio_fini(struct radeon_device *rdev) | |||
261 | if (!r600_audio_chipset_supported(rdev)) | 261 | if (!r600_audio_chipset_supported(rdev)) |
262 | return; | 262 | return; |
263 | 263 | ||
264 | WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000); | ||
265 | |||
266 | del_timer(&rdev->audio_timer); | 264 | del_timer(&rdev->audio_timer); |
265 | WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000); | ||
267 | } | 266 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 2bedce477a97..446b765ac72a 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -449,6 +449,7 @@ int r600_blit_init(struct radeon_device *rdev) | |||
449 | u32 packet2s[16]; | 449 | u32 packet2s[16]; |
450 | int num_packet2s = 0; | 450 | int num_packet2s = 0; |
451 | 451 | ||
452 | mutex_init(&rdev->r600_blit.mutex); | ||
452 | rdev->r600_blit.state_offset = 0; | 453 | rdev->r600_blit.state_offset = 0; |
453 | 454 | ||
454 | if (rdev->family >= CHIP_RV770) | 455 | if (rdev->family >= CHIP_RV770) |
@@ -542,9 +543,6 @@ int r600_vb_ib_get(struct radeon_device *rdev) | |||
542 | void r600_vb_ib_put(struct radeon_device *rdev) | 543 | void r600_vb_ib_put(struct radeon_device *rdev) |
543 | { | 544 | { |
544 | radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); | 545 | radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); |
545 | mutex_lock(&rdev->ib_pool.mutex); | ||
546 | list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs); | ||
547 | mutex_unlock(&rdev->ib_pool.mutex); | ||
548 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); | 546 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); |
549 | } | 547 | } |
550 | 548 | ||
@@ -557,7 +555,8 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) | |||
557 | int dwords_per_loop = 76, num_loops; | 555 | int dwords_per_loop = 76, num_loops; |
558 | 556 | ||
559 | r = r600_vb_ib_get(rdev); | 557 | r = r600_vb_ib_get(rdev); |
560 | WARN_ON(r); | 558 | if (r) |
559 | return r; | ||
561 | 560 | ||
562 | /* set_render_target emits 2 extra dwords on rv6xx */ | 561 | /* set_render_target emits 2 extra dwords on rv6xx */ |
563 | if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) | 562 | if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) |
@@ -583,7 +582,8 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) | |||
583 | ring_size += 5; /* done copy */ | 582 | ring_size += 5; /* done copy */ |
584 | ring_size += 7; /* fence emit for done copy */ | 583 | ring_size += 7; /* fence emit for done copy */ |
585 | r = radeon_ring_lock(rdev, ring_size); | 584 | r = radeon_ring_lock(rdev, ring_size); |
586 | WARN_ON(r); | 585 | if (r) |
586 | return r; | ||
587 | 587 | ||
588 | set_default_state(rdev); /* 14 */ | 588 | set_default_state(rdev); /* 14 */ |
589 | set_shaders(rdev); /* 26 */ | 589 | set_shaders(rdev); /* 26 */ |
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 6d5a711c2e91..75bcf35a0931 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
@@ -1428,9 +1428,12 @@ static void r700_gfx_init(struct drm_device *dev, | |||
1428 | 1428 | ||
1429 | gb_tiling_config |= R600_BANK_SWAPS(1); | 1429 | gb_tiling_config |= R600_BANK_SWAPS(1); |
1430 | 1430 | ||
1431 | backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, | 1431 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740) |
1432 | dev_priv->r600_max_backends, | 1432 | backend_map = 0x28; |
1433 | (0xff << dev_priv->r600_max_backends) & 0xff); | 1433 | else |
1434 | backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, | ||
1435 | dev_priv->r600_max_backends, | ||
1436 | (0xff << dev_priv->r600_max_backends) & 0xff); | ||
1434 | gb_tiling_config |= R600_BACKEND_MAP(backend_map); | 1437 | gb_tiling_config |= R600_BACKEND_MAP(backend_map); |
1435 | 1438 | ||
1436 | cc_gc_shader_pipe_config = | 1439 | cc_gc_shader_pipe_config = |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f7df1a7e4413..c0356bb193e5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -96,6 +96,7 @@ extern int radeon_audio; | |||
96 | * symbol; | 96 | * symbol; |
97 | */ | 97 | */ |
98 | #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ | 98 | #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ |
99 | /* RADEON_IB_POOL_SIZE must be a power of 2 */ | ||
99 | #define RADEON_IB_POOL_SIZE 16 | 100 | #define RADEON_IB_POOL_SIZE 16 |
100 | #define RADEON_DEBUGFS_MAX_NUM_FILES 32 | 101 | #define RADEON_DEBUGFS_MAX_NUM_FILES 32 |
101 | #define RADEONFB_CONN_LIMIT 4 | 102 | #define RADEONFB_CONN_LIMIT 4 |
@@ -363,11 +364,12 @@ void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev); | |||
363 | */ | 364 | */ |
364 | struct radeon_ib { | 365 | struct radeon_ib { |
365 | struct list_head list; | 366 | struct list_head list; |
366 | unsigned long idx; | 367 | unsigned idx; |
367 | uint64_t gpu_addr; | 368 | uint64_t gpu_addr; |
368 | struct radeon_fence *fence; | 369 | struct radeon_fence *fence; |
369 | uint32_t *ptr; | 370 | uint32_t *ptr; |
370 | uint32_t length_dw; | 371 | uint32_t length_dw; |
372 | bool free; | ||
371 | }; | 373 | }; |
372 | 374 | ||
373 | /* | 375 | /* |
@@ -377,10 +379,9 @@ struct radeon_ib { | |||
377 | struct radeon_ib_pool { | 379 | struct radeon_ib_pool { |
378 | struct mutex mutex; | 380 | struct mutex mutex; |
379 | struct radeon_bo *robj; | 381 | struct radeon_bo *robj; |
380 | struct list_head scheduled_ibs; | ||
381 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; | 382 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; |
382 | bool ready; | 383 | bool ready; |
383 | DECLARE_BITMAP(alloc_bm, RADEON_IB_POOL_SIZE); | 384 | unsigned head_id; |
384 | }; | 385 | }; |
385 | 386 | ||
386 | struct radeon_cp { | 387 | struct radeon_cp { |
@@ -416,6 +417,7 @@ struct r600_ih { | |||
416 | }; | 417 | }; |
417 | 418 | ||
418 | struct r600_blit { | 419 | struct r600_blit { |
420 | struct mutex mutex; | ||
419 | struct radeon_bo *shader_obj; | 421 | struct radeon_bo *shader_obj; |
420 | u64 shader_gpu_addr; | 422 | u64 shader_gpu_addr; |
421 | u32 vs_offset, ps_offset; | 423 | u32 vs_offset, ps_offset; |
@@ -660,6 +662,13 @@ struct radeon_asic { | |||
660 | void (*hpd_fini)(struct radeon_device *rdev); | 662 | void (*hpd_fini)(struct radeon_device *rdev); |
661 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 663 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
662 | void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 664 | void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
665 | /* ioctl hw specific callback. Some hw might want to perform special | ||
666 | * operation on specific ioctl. For instance on wait idle some hw | ||
667 | * might want to perform and HDP flush through MMIO as it seems that | ||
668 | * some R6XX/R7XX hw doesn't take HDP flush into account if programmed | ||
669 | * through ring. | ||
670 | */ | ||
671 | void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo); | ||
663 | }; | 672 | }; |
664 | 673 | ||
665 | /* | 674 | /* |
@@ -1142,6 +1151,7 @@ extern bool r600_card_posted(struct radeon_device *rdev); | |||
1142 | extern void r600_cp_stop(struct radeon_device *rdev); | 1151 | extern void r600_cp_stop(struct radeon_device *rdev); |
1143 | extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size); | 1152 | extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size); |
1144 | extern int r600_cp_resume(struct radeon_device *rdev); | 1153 | extern int r600_cp_resume(struct radeon_device *rdev); |
1154 | extern void r600_cp_fini(struct radeon_device *rdev); | ||
1145 | extern int r600_count_pipe_bits(uint32_t val); | 1155 | extern int r600_count_pipe_bits(uint32_t val); |
1146 | extern int r600_gart_clear_page(struct radeon_device *rdev, int i); | 1156 | extern int r600_gart_clear_page(struct radeon_device *rdev, int i); |
1147 | extern int r600_mc_wait_for_idle(struct radeon_device *rdev); | 1157 | extern int r600_mc_wait_for_idle(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index c9ad7f5cc1ac..c0681a5556dc 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -133,13 +133,6 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
133 | bool is_v3; | 133 | bool is_v3; |
134 | int ret; | 134 | int ret; |
135 | 135 | ||
136 | if (rdev->ddev->agp->agp_info.aper_size < 32) { | ||
137 | dev_warn(rdev->dev, "AGP aperture to small (%dM) " | ||
138 | "need at least 32M, disabling AGP\n", | ||
139 | rdev->ddev->agp->agp_info.aper_size); | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | |||
143 | /* Acquire AGP. */ | 136 | /* Acquire AGP. */ |
144 | if (!rdev->ddev->agp->acquired) { | 137 | if (!rdev->ddev->agp->acquired) { |
145 | ret = drm_agp_acquire(rdev->ddev); | 138 | ret = drm_agp_acquire(rdev->ddev); |
@@ -151,9 +144,19 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
151 | 144 | ||
152 | ret = drm_agp_info(rdev->ddev, &info); | 145 | ret = drm_agp_info(rdev->ddev, &info); |
153 | if (ret) { | 146 | if (ret) { |
147 | drm_agp_release(rdev->ddev); | ||
154 | DRM_ERROR("Unable to get AGP info: %d\n", ret); | 148 | DRM_ERROR("Unable to get AGP info: %d\n", ret); |
155 | return ret; | 149 | return ret; |
156 | } | 150 | } |
151 | |||
152 | if (rdev->ddev->agp->agp_info.aper_size < 32) { | ||
153 | drm_agp_release(rdev->ddev); | ||
154 | dev_warn(rdev->dev, "AGP aperture too small (%zuM) " | ||
155 | "need at least 32M, disabling AGP\n", | ||
156 | rdev->ddev->agp->agp_info.aper_size); | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | |||
157 | mode.mode = info.mode; | 160 | mode.mode = info.mode; |
158 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | 161 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; |
159 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); | 162 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); |
@@ -228,6 +231,7 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
228 | ret = drm_agp_enable(rdev->ddev, mode); | 231 | ret = drm_agp_enable(rdev->ddev, mode); |
229 | if (ret) { | 232 | if (ret) { |
230 | DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); | 233 | DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); |
234 | drm_agp_release(rdev->ddev); | ||
231 | return ret; | 235 | return ret; |
232 | } | 236 | } |
233 | 237 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f2fbd2e4e9df..05ee1aeac3fd 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -117,6 +117,7 @@ static struct radeon_asic r100_asic = { | |||
117 | .hpd_fini = &r100_hpd_fini, | 117 | .hpd_fini = &r100_hpd_fini, |
118 | .hpd_sense = &r100_hpd_sense, | 118 | .hpd_sense = &r100_hpd_sense, |
119 | .hpd_set_polarity = &r100_hpd_set_polarity, | 119 | .hpd_set_polarity = &r100_hpd_set_polarity, |
120 | .ioctl_wait_idle = NULL, | ||
120 | }; | 121 | }; |
121 | 122 | ||
122 | 123 | ||
@@ -176,6 +177,7 @@ static struct radeon_asic r300_asic = { | |||
176 | .hpd_fini = &r100_hpd_fini, | 177 | .hpd_fini = &r100_hpd_fini, |
177 | .hpd_sense = &r100_hpd_sense, | 178 | .hpd_sense = &r100_hpd_sense, |
178 | .hpd_set_polarity = &r100_hpd_set_polarity, | 179 | .hpd_set_polarity = &r100_hpd_set_polarity, |
180 | .ioctl_wait_idle = NULL, | ||
179 | }; | 181 | }; |
180 | 182 | ||
181 | /* | 183 | /* |
@@ -219,6 +221,7 @@ static struct radeon_asic r420_asic = { | |||
219 | .hpd_fini = &r100_hpd_fini, | 221 | .hpd_fini = &r100_hpd_fini, |
220 | .hpd_sense = &r100_hpd_sense, | 222 | .hpd_sense = &r100_hpd_sense, |
221 | .hpd_set_polarity = &r100_hpd_set_polarity, | 223 | .hpd_set_polarity = &r100_hpd_set_polarity, |
224 | .ioctl_wait_idle = NULL, | ||
222 | }; | 225 | }; |
223 | 226 | ||
224 | 227 | ||
@@ -267,6 +270,7 @@ static struct radeon_asic rs400_asic = { | |||
267 | .hpd_fini = &r100_hpd_fini, | 270 | .hpd_fini = &r100_hpd_fini, |
268 | .hpd_sense = &r100_hpd_sense, | 271 | .hpd_sense = &r100_hpd_sense, |
269 | .hpd_set_polarity = &r100_hpd_set_polarity, | 272 | .hpd_set_polarity = &r100_hpd_set_polarity, |
273 | .ioctl_wait_idle = NULL, | ||
270 | }; | 274 | }; |
271 | 275 | ||
272 | 276 | ||
@@ -323,6 +327,7 @@ static struct radeon_asic rs600_asic = { | |||
323 | .hpd_fini = &rs600_hpd_fini, | 327 | .hpd_fini = &rs600_hpd_fini, |
324 | .hpd_sense = &rs600_hpd_sense, | 328 | .hpd_sense = &rs600_hpd_sense, |
325 | .hpd_set_polarity = &rs600_hpd_set_polarity, | 329 | .hpd_set_polarity = &rs600_hpd_set_polarity, |
330 | .ioctl_wait_idle = NULL, | ||
326 | }; | 331 | }; |
327 | 332 | ||
328 | 333 | ||
@@ -370,6 +375,7 @@ static struct radeon_asic rs690_asic = { | |||
370 | .hpd_fini = &rs600_hpd_fini, | 375 | .hpd_fini = &rs600_hpd_fini, |
371 | .hpd_sense = &rs600_hpd_sense, | 376 | .hpd_sense = &rs600_hpd_sense, |
372 | .hpd_set_polarity = &rs600_hpd_set_polarity, | 377 | .hpd_set_polarity = &rs600_hpd_set_polarity, |
378 | .ioctl_wait_idle = NULL, | ||
373 | }; | 379 | }; |
374 | 380 | ||
375 | 381 | ||
@@ -421,6 +427,7 @@ static struct radeon_asic rv515_asic = { | |||
421 | .hpd_fini = &rs600_hpd_fini, | 427 | .hpd_fini = &rs600_hpd_fini, |
422 | .hpd_sense = &rs600_hpd_sense, | 428 | .hpd_sense = &rs600_hpd_sense, |
423 | .hpd_set_polarity = &rs600_hpd_set_polarity, | 429 | .hpd_set_polarity = &rs600_hpd_set_polarity, |
430 | .ioctl_wait_idle = NULL, | ||
424 | }; | 431 | }; |
425 | 432 | ||
426 | 433 | ||
@@ -463,6 +470,7 @@ static struct radeon_asic r520_asic = { | |||
463 | .hpd_fini = &rs600_hpd_fini, | 470 | .hpd_fini = &rs600_hpd_fini, |
464 | .hpd_sense = &rs600_hpd_sense, | 471 | .hpd_sense = &rs600_hpd_sense, |
465 | .hpd_set_polarity = &rs600_hpd_set_polarity, | 472 | .hpd_set_polarity = &rs600_hpd_set_polarity, |
473 | .ioctl_wait_idle = NULL, | ||
466 | }; | 474 | }; |
467 | 475 | ||
468 | /* | 476 | /* |
@@ -504,6 +512,7 @@ void r600_hpd_fini(struct radeon_device *rdev); | |||
504 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 512 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
505 | void r600_hpd_set_polarity(struct radeon_device *rdev, | 513 | void r600_hpd_set_polarity(struct radeon_device *rdev, |
506 | enum radeon_hpd_id hpd); | 514 | enum radeon_hpd_id hpd); |
515 | extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo); | ||
507 | 516 | ||
508 | static struct radeon_asic r600_asic = { | 517 | static struct radeon_asic r600_asic = { |
509 | .init = &r600_init, | 518 | .init = &r600_init, |
@@ -538,6 +547,7 @@ static struct radeon_asic r600_asic = { | |||
538 | .hpd_fini = &r600_hpd_fini, | 547 | .hpd_fini = &r600_hpd_fini, |
539 | .hpd_sense = &r600_hpd_sense, | 548 | .hpd_sense = &r600_hpd_sense, |
540 | .hpd_set_polarity = &r600_hpd_set_polarity, | 549 | .hpd_set_polarity = &r600_hpd_set_polarity, |
550 | .ioctl_wait_idle = r600_ioctl_wait_idle, | ||
541 | }; | 551 | }; |
542 | 552 | ||
543 | /* | 553 | /* |
@@ -582,6 +592,7 @@ static struct radeon_asic rv770_asic = { | |||
582 | .hpd_fini = &r600_hpd_fini, | 592 | .hpd_fini = &r600_hpd_fini, |
583 | .hpd_sense = &r600_hpd_sense, | 593 | .hpd_sense = &r600_hpd_sense, |
584 | .hpd_set_polarity = &r600_hpd_set_polarity, | 594 | .hpd_set_polarity = &r600_hpd_set_polarity, |
595 | .ioctl_wait_idle = r600_ioctl_wait_idle, | ||
585 | }; | 596 | }; |
586 | 597 | ||
587 | #endif | 598 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index fa82ca74324e..4d8831548a5f 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -206,6 +206,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
206 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 206 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
207 | } | 207 | } |
208 | 208 | ||
209 | /* Asrock RS600 board lists the DVI port as HDMI */ | ||
210 | if ((dev->pdev->device == 0x7941) && | ||
211 | (dev->pdev->subsystem_vendor == 0x1849) && | ||
212 | (dev->pdev->subsystem_device == 0x7941)) { | ||
213 | if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) && | ||
214 | (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) | ||
215 | *connector_type = DRM_MODE_CONNECTOR_DVID; | ||
216 | } | ||
217 | |||
209 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ | 218 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ |
210 | if ((dev->pdev->device == 0x7941) && | 219 | if ((dev->pdev->device == 0x7941) && |
211 | (dev->pdev->subsystem_vendor == 0x147b) && | 220 | (dev->pdev->subsystem_vendor == 0x147b) && |
@@ -287,6 +296,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
287 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 296 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
288 | } | 297 | } |
289 | 298 | ||
299 | /* XFX Pine Group device rv730 reports no VGA DDC lines | ||
300 | * even though they are wired up to record 0x93 | ||
301 | */ | ||
302 | if ((dev->pdev->device == 0x9498) && | ||
303 | (dev->pdev->subsystem_vendor == 0x1682) && | ||
304 | (dev->pdev->subsystem_device == 0x2452)) { | ||
305 | struct radeon_device *rdev = dev->dev_private; | ||
306 | *i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93); | ||
307 | } | ||
290 | return true; | 308 | return true; |
291 | } | 309 | } |
292 | 310 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 4ddfd4b5bc51..7932dc4d6b90 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -65,31 +65,42 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | |||
65 | if (r) { | 65 | if (r) { |
66 | goto out_cleanup; | 66 | goto out_cleanup; |
67 | } | 67 | } |
68 | start_jiffies = jiffies; | 68 | |
69 | for (i = 0; i < n; i++) { | 69 | /* r100 doesn't have dma engine so skip the test */ |
70 | r = radeon_fence_create(rdev, &fence); | 70 | if (rdev->asic->copy_dma) { |
71 | if (r) { | 71 | |
72 | goto out_cleanup; | 72 | start_jiffies = jiffies; |
73 | for (i = 0; i < n; i++) { | ||
74 | r = radeon_fence_create(rdev, &fence); | ||
75 | if (r) { | ||
76 | goto out_cleanup; | ||
77 | } | ||
78 | |||
79 | r = radeon_copy_dma(rdev, saddr, daddr, | ||
80 | size / RADEON_GPU_PAGE_SIZE, fence); | ||
81 | |||
82 | if (r) { | ||
83 | goto out_cleanup; | ||
84 | } | ||
85 | r = radeon_fence_wait(fence, false); | ||
86 | if (r) { | ||
87 | goto out_cleanup; | ||
88 | } | ||
89 | radeon_fence_unref(&fence); | ||
73 | } | 90 | } |
74 | r = radeon_copy_dma(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence); | 91 | end_jiffies = jiffies; |
75 | if (r) { | 92 | time = end_jiffies - start_jiffies; |
76 | goto out_cleanup; | 93 | time = jiffies_to_msecs(time); |
94 | if (time > 0) { | ||
95 | i = ((n * size) >> 10) / time; | ||
96 | printk(KERN_INFO "radeon: dma %u bo moves of %ukb from" | ||
97 | " %d to %d in %lums (%ukb/ms %ukb/s %uM/s)\n", | ||
98 | n, size >> 10, | ||
99 | sdomain, ddomain, time, | ||
100 | i, i * 1000, (i * 1000) / 1024); | ||
77 | } | 101 | } |
78 | r = radeon_fence_wait(fence, false); | ||
79 | if (r) { | ||
80 | goto out_cleanup; | ||
81 | } | ||
82 | radeon_fence_unref(&fence); | ||
83 | } | ||
84 | end_jiffies = jiffies; | ||
85 | time = end_jiffies - start_jiffies; | ||
86 | time = jiffies_to_msecs(time); | ||
87 | if (time > 0) { | ||
88 | i = ((n * size) >> 10) / time; | ||
89 | printk(KERN_INFO "radeon: dma %u bo moves of %ukb from %d to %d" | ||
90 | " in %lums (%ukb/ms %ukb/s %uM/s)\n", n, size >> 10, | ||
91 | sdomain, ddomain, time, i, i * 1000, (i * 1000) / 1024); | ||
92 | } | 102 | } |
103 | |||
93 | start_jiffies = jiffies; | 104 | start_jiffies = jiffies; |
94 | for (i = 0; i < n; i++) { | 105 | for (i = 0; i < n; i++) { |
95 | r = radeon_fence_create(rdev, &fence); | 106 | r = radeon_fence_create(rdev, &fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 579c8920e081..e7b19440102e 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -971,8 +971,7 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
971 | lvds->native_mode.vdisplay); | 971 | lvds->native_mode.vdisplay); |
972 | 972 | ||
973 | lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); | 973 | lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); |
974 | if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0) | 974 | lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000); |
975 | lvds->panel_vcc_delay = 2000; | ||
976 | 975 | ||
977 | lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24); | 976 | lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24); |
978 | lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf; | 977 | lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 55266416fa47..65f81942f399 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -580,16 +580,18 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect | |||
580 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 580 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
581 | struct drm_encoder *encoder; | 581 | struct drm_encoder *encoder; |
582 | struct drm_encoder_helper_funcs *encoder_funcs; | 582 | struct drm_encoder_helper_funcs *encoder_funcs; |
583 | bool dret; | 583 | bool dret = false; |
584 | enum drm_connector_status ret = connector_status_disconnected; | 584 | enum drm_connector_status ret = connector_status_disconnected; |
585 | 585 | ||
586 | encoder = radeon_best_single_encoder(connector); | 586 | encoder = radeon_best_single_encoder(connector); |
587 | if (!encoder) | 587 | if (!encoder) |
588 | ret = connector_status_disconnected; | 588 | ret = connector_status_disconnected; |
589 | 589 | ||
590 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | 590 | if (radeon_connector->ddc_bus) { |
591 | dret = radeon_ddc_probe(radeon_connector); | 591 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); |
592 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | 592 | dret = radeon_ddc_probe(radeon_connector); |
593 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
594 | } | ||
593 | if (dret) { | 595 | if (dret) { |
594 | if (radeon_connector->edid) { | 596 | if (radeon_connector->edid) { |
595 | kfree(radeon_connector->edid); | 597 | kfree(radeon_connector->edid); |
@@ -740,11 +742,13 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
740 | struct drm_mode_object *obj; | 742 | struct drm_mode_object *obj; |
741 | int i; | 743 | int i; |
742 | enum drm_connector_status ret = connector_status_disconnected; | 744 | enum drm_connector_status ret = connector_status_disconnected; |
743 | bool dret; | 745 | bool dret = false; |
744 | 746 | ||
745 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | 747 | if (radeon_connector->ddc_bus) { |
746 | dret = radeon_ddc_probe(radeon_connector); | 748 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); |
747 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | 749 | dret = radeon_ddc_probe(radeon_connector); |
750 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
751 | } | ||
748 | if (dret) { | 752 | if (dret) { |
749 | if (radeon_connector->edid) { | 753 | if (radeon_connector->edid) { |
750 | kfree(radeon_connector->edid); | 754 | kfree(radeon_connector->edid); |
@@ -776,7 +780,7 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
776 | * connected and the DVI port disconnected. If the edid doesn't | 780 | * connected and the DVI port disconnected. If the edid doesn't |
777 | * say HDMI, vice versa. | 781 | * say HDMI, vice versa. |
778 | */ | 782 | */ |
779 | if (radeon_connector->shared_ddc && connector_status_connected) { | 783 | if (radeon_connector->shared_ddc && (ret == connector_status_connected)) { |
780 | struct drm_device *dev = connector->dev; | 784 | struct drm_device *dev = connector->dev; |
781 | struct drm_connector *list_connector; | 785 | struct drm_connector *list_connector; |
782 | struct radeon_connector *list_radeon_connector; | 786 | struct radeon_connector *list_radeon_connector; |
@@ -1056,8 +1060,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1056 | return; | 1060 | return; |
1057 | } | 1061 | } |
1058 | if (radeon_connector->ddc_bus && i2c_bus->valid) { | 1062 | if (radeon_connector->ddc_bus && i2c_bus->valid) { |
1059 | if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus, | 1063 | if (radeon_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) { |
1060 | sizeof(struct radeon_i2c_bus_rec)) == 0) { | ||
1061 | radeon_connector->shared_ddc = true; | 1064 | radeon_connector->shared_ddc = true; |
1062 | shared_ddc = true; | 1065 | shared_ddc = true; |
1063 | } | 1066 | } |
@@ -1343,7 +1346,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1343 | radeon_connector->dac_load_detect = false; | 1346 | radeon_connector->dac_load_detect = false; |
1344 | drm_connector_attach_property(&radeon_connector->base, | 1347 | drm_connector_attach_property(&radeon_connector->base, |
1345 | rdev->mode_info.load_detect_property, | 1348 | rdev->mode_info.load_detect_property, |
1346 | 1); | 1349 | radeon_connector->dac_load_detect); |
1347 | drm_connector_attach_property(&radeon_connector->base, | 1350 | drm_connector_attach_property(&radeon_connector->base, |
1348 | rdev->mode_info.tv_std_property, | 1351 | rdev->mode_info.tv_std_property, |
1349 | radeon_combios_get_tv_info(rdev)); | 1352 | radeon_combios_get_tv_info(rdev)); |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 1496cb8658ef..e9d085021c1f 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -86,7 +86,7 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
86 | &p->validated); | 86 | &p->validated); |
87 | } | 87 | } |
88 | } | 88 | } |
89 | return radeon_bo_list_validate(&p->validated, p->ib->fence); | 89 | return radeon_bo_list_validate(&p->validated); |
90 | } | 90 | } |
91 | 91 | ||
92 | int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | 92 | int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) |
@@ -189,12 +189,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
189 | { | 189 | { |
190 | unsigned i; | 190 | unsigned i; |
191 | 191 | ||
192 | if (error) { | 192 | if (!error && parser->ib) { |
193 | radeon_bo_list_unvalidate(&parser->validated, | 193 | radeon_bo_list_fence(&parser->validated, parser->ib->fence); |
194 | parser->ib->fence); | ||
195 | } else { | ||
196 | radeon_bo_list_unreserve(&parser->validated); | ||
197 | } | 194 | } |
195 | radeon_bo_list_unreserve(&parser->validated); | ||
198 | for (i = 0; i < parser->nrelocs; i++) { | 196 | for (i = 0; i < parser->nrelocs; i++) { |
199 | if (parser->relocs[i].gobj) { | 197 | if (parser->relocs[i].gobj) { |
200 | mutex_lock(&parser->rdev->ddev->struct_mutex); | 198 | mutex_lock(&parser->rdev->ddev->struct_mutex); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 6a92f994cc26..7e17a362b54b 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -278,7 +278,7 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
278 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); | 278 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); |
279 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | 279 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) |
280 | DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); | 280 | DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); |
281 | if (radeon_connector->ddc_bus) | 281 | if (radeon_connector->ddc_bus) { |
282 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 282 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
283 | radeon_connector->ddc_bus->rec.mask_clk_reg, | 283 | radeon_connector->ddc_bus->rec.mask_clk_reg, |
284 | radeon_connector->ddc_bus->rec.mask_data_reg, | 284 | radeon_connector->ddc_bus->rec.mask_data_reg, |
@@ -288,6 +288,15 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
288 | radeon_connector->ddc_bus->rec.en_data_reg, | 288 | radeon_connector->ddc_bus->rec.en_data_reg, |
289 | radeon_connector->ddc_bus->rec.y_clk_reg, | 289 | radeon_connector->ddc_bus->rec.y_clk_reg, |
290 | radeon_connector->ddc_bus->rec.y_data_reg); | 290 | radeon_connector->ddc_bus->rec.y_data_reg); |
291 | } else { | ||
292 | if (connector->connector_type == DRM_MODE_CONNECTOR_VGA || | ||
293 | connector->connector_type == DRM_MODE_CONNECTOR_DVII || | ||
294 | connector->connector_type == DRM_MODE_CONNECTOR_DVID || | ||
295 | connector->connector_type == DRM_MODE_CONNECTOR_DVIA || | ||
296 | connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || | ||
297 | connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) | ||
298 | DRM_INFO(" DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n"); | ||
299 | } | ||
291 | DRM_INFO(" Encoders:\n"); | 300 | DRM_INFO(" Encoders:\n"); |
292 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 301 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
293 | radeon_encoder = to_radeon_encoder(encoder); | 302 | radeon_encoder = to_radeon_encoder(encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index e13785282a82..c57ad606504d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -106,9 +106,10 @@ | |||
106 | * 1.29- R500 3D cmd buffer support | 106 | * 1.29- R500 3D cmd buffer support |
107 | * 1.30- Add support for occlusion queries | 107 | * 1.30- Add support for occlusion queries |
108 | * 1.31- Add support for num Z pipes from GET_PARAM | 108 | * 1.31- Add support for num Z pipes from GET_PARAM |
109 | * 1.32- fixes for rv740 setup | ||
109 | */ | 110 | */ |
110 | #define DRIVER_MAJOR 1 | 111 | #define DRIVER_MAJOR 1 |
111 | #define DRIVER_MINOR 31 | 112 | #define DRIVER_MINOR 32 |
112 | #define DRIVER_PATCHLEVEL 0 | 113 | #define DRIVER_PATCHLEVEL 0 |
113 | 114 | ||
114 | enum radeon_cp_microcode_version { | 115 | enum radeon_cp_microcode_version { |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 82eb551970b9..3c91724457ca 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -156,6 +156,26 @@ radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t | |||
156 | return ret; | 156 | return ret; |
157 | } | 157 | } |
158 | 158 | ||
159 | static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | ||
160 | { | ||
161 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
162 | switch (radeon_encoder->encoder_id) { | ||
163 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
164 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
165 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
166 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
167 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
168 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
169 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
170 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
171 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
172 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
173 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
174 | return true; | ||
175 | default: | ||
176 | return false; | ||
177 | } | ||
178 | } | ||
159 | void | 179 | void |
160 | radeon_link_encoder_connector(struct drm_device *dev) | 180 | radeon_link_encoder_connector(struct drm_device *dev) |
161 | { | 181 | { |
@@ -202,7 +222,7 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
202 | 222 | ||
203 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 223 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
204 | radeon_connector = to_radeon_connector(connector); | 224 | radeon_connector = to_radeon_connector(connector); |
205 | if (radeon_encoder->devices & radeon_connector->devices) | 225 | if (radeon_encoder->active_device & radeon_connector->devices) |
206 | return connector; | 226 | return connector; |
207 | } | 227 | } |
208 | return NULL; | 228 | return NULL; |
@@ -676,31 +696,11 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
676 | 696 | ||
677 | memset(&args, 0, sizeof(args)); | 697 | memset(&args, 0, sizeof(args)); |
678 | 698 | ||
679 | if (ASIC_IS_DCE32(rdev)) { | 699 | if (dig->dig_encoder) |
680 | if (dig->dig_block) | 700 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); |
681 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | 701 | else |
682 | else | 702 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); |
683 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | 703 | num = dig->dig_encoder + 1; |
684 | num = dig->dig_block + 1; | ||
685 | } else { | ||
686 | switch (radeon_encoder->encoder_id) { | ||
687 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
688 | /* XXX doesn't really matter which dig encoder we pick as long as it's | ||
689 | * not already in use | ||
690 | */ | ||
691 | if (dig_connector->linkb) | ||
692 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
693 | else | ||
694 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
695 | num = 1; | ||
696 | break; | ||
697 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
698 | /* Only dig2 encoder can drive LVTMA */ | ||
699 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
700 | num = 2; | ||
701 | break; | ||
702 | } | ||
703 | } | ||
704 | 704 | ||
705 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 705 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); |
706 | 706 | ||
@@ -822,7 +822,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
822 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 822 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
823 | } | 823 | } |
824 | if (ASIC_IS_DCE32(rdev)) { | 824 | if (ASIC_IS_DCE32(rdev)) { |
825 | if (dig->dig_block) | 825 | if (dig->dig_encoder == 1) |
826 | args.v2.acConfig.ucEncoderSel = 1; | 826 | args.v2.acConfig.ucEncoderSel = 1; |
827 | if (dig_connector->linkb) | 827 | if (dig_connector->linkb) |
828 | args.v2.acConfig.ucLinkSel = 1; | 828 | args.v2.acConfig.ucLinkSel = 1; |
@@ -849,17 +849,16 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
849 | args.v2.acConfig.fCoherentMode = 1; | 849 | args.v2.acConfig.fCoherentMode = 1; |
850 | } | 850 | } |
851 | } else { | 851 | } else { |
852 | |||
852 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | 853 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; |
853 | 854 | ||
855 | if (dig->dig_encoder) | ||
856 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
857 | else | ||
858 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
859 | |||
854 | switch (radeon_encoder->encoder_id) { | 860 | switch (radeon_encoder->encoder_id) { |
855 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 861 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
856 | /* XXX doesn't really matter which dig encoder we pick as long as it's | ||
857 | * not already in use | ||
858 | */ | ||
859 | if (dig_connector->linkb) | ||
860 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
861 | else | ||
862 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
863 | if (rdev->flags & RADEON_IS_IGP) { | 862 | if (rdev->flags & RADEON_IS_IGP) { |
864 | if (radeon_encoder->pixel_clock > 165000) { | 863 | if (radeon_encoder->pixel_clock > 165000) { |
865 | if (dig_connector->igp_lane_info & 0x3) | 864 | if (dig_connector->igp_lane_info & 0x3) |
@@ -878,10 +877,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
878 | } | 877 | } |
879 | } | 878 | } |
880 | break; | 879 | break; |
881 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
882 | /* Only dig2 encoder can drive LVTMA */ | ||
883 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
884 | break; | ||
885 | } | 880 | } |
886 | 881 | ||
887 | if (radeon_encoder->pixel_clock > 165000) | 882 | if (radeon_encoder->pixel_clock > 165000) |
@@ -1046,6 +1041,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1046 | union crtc_sourc_param args; | 1041 | union crtc_sourc_param args; |
1047 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); | 1042 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); |
1048 | uint8_t frev, crev; | 1043 | uint8_t frev, crev; |
1044 | struct radeon_encoder_atom_dig *dig; | ||
1049 | 1045 | ||
1050 | memset(&args, 0, sizeof(args)); | 1046 | memset(&args, 0, sizeof(args)); |
1051 | 1047 | ||
@@ -1109,40 +1105,16 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1109 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 1105 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
1110 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1106 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1111 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1107 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1112 | if (ASIC_IS_DCE32(rdev)) { | 1108 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1113 | if (radeon_crtc->crtc_id) | 1109 | dig = radeon_encoder->enc_priv; |
1114 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1110 | if (dig->dig_encoder) |
1115 | else | 1111 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
1116 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1112 | else |
1117 | } else { | 1113 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; |
1118 | struct drm_connector *connector; | ||
1119 | struct radeon_connector *radeon_connector; | ||
1120 | struct radeon_connector_atom_dig *dig_connector; | ||
1121 | |||
1122 | connector = radeon_get_connector_for_encoder(encoder); | ||
1123 | if (!connector) | ||
1124 | return; | ||
1125 | radeon_connector = to_radeon_connector(connector); | ||
1126 | if (!radeon_connector->con_priv) | ||
1127 | return; | ||
1128 | dig_connector = radeon_connector->con_priv; | ||
1129 | |||
1130 | /* XXX doesn't really matter which dig encoder we pick as long as it's | ||
1131 | * not already in use | ||
1132 | */ | ||
1133 | if (dig_connector->linkb) | ||
1134 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1135 | else | ||
1136 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
1137 | } | ||
1138 | break; | 1114 | break; |
1139 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | 1115 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
1140 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | 1116 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; |
1141 | break; | 1117 | break; |
1142 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1143 | /* Only dig2 encoder can drive LVTMA */ | ||
1144 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1145 | break; | ||
1146 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1118 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
1147 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | 1119 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
1148 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | 1120 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
@@ -1202,6 +1174,47 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, | |||
1202 | } | 1174 | } |
1203 | } | 1175 | } |
1204 | 1176 | ||
1177 | static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | ||
1178 | { | ||
1179 | struct drm_device *dev = encoder->dev; | ||
1180 | struct radeon_device *rdev = dev->dev_private; | ||
1181 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1182 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1183 | struct drm_encoder *test_encoder; | ||
1184 | struct radeon_encoder_atom_dig *dig; | ||
1185 | uint32_t dig_enc_in_use = 0; | ||
1186 | /* on DCE32 and encoder can driver any block so just crtc id */ | ||
1187 | if (ASIC_IS_DCE32(rdev)) { | ||
1188 | return radeon_crtc->crtc_id; | ||
1189 | } | ||
1190 | |||
1191 | /* on DCE3 - LVTMA can only be driven by DIGB */ | ||
1192 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
1193 | struct radeon_encoder *radeon_test_encoder; | ||
1194 | |||
1195 | if (encoder == test_encoder) | ||
1196 | continue; | ||
1197 | |||
1198 | if (!radeon_encoder_is_digital(test_encoder)) | ||
1199 | continue; | ||
1200 | |||
1201 | radeon_test_encoder = to_radeon_encoder(test_encoder); | ||
1202 | dig = radeon_test_encoder->enc_priv; | ||
1203 | |||
1204 | if (dig->dig_encoder >= 0) | ||
1205 | dig_enc_in_use |= (1 << dig->dig_encoder); | ||
1206 | } | ||
1207 | |||
1208 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) { | ||
1209 | if (dig_enc_in_use & 0x2) | ||
1210 | DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n"); | ||
1211 | return 1; | ||
1212 | } | ||
1213 | if (!(dig_enc_in_use & 1)) | ||
1214 | return 0; | ||
1215 | return 1; | ||
1216 | } | ||
1217 | |||
1205 | static void | 1218 | static void |
1206 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | 1219 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, |
1207 | struct drm_display_mode *mode, | 1220 | struct drm_display_mode *mode, |
@@ -1214,12 +1227,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1214 | 1227 | ||
1215 | if (radeon_encoder->active_device & | 1228 | if (radeon_encoder->active_device & |
1216 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { | 1229 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { |
1217 | if (radeon_encoder->enc_priv) { | 1230 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
1218 | struct radeon_encoder_atom_dig *dig; | 1231 | if (dig) |
1219 | 1232 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); | |
1220 | dig = radeon_encoder->enc_priv; | ||
1221 | dig->dig_block = radeon_crtc->crtc_id; | ||
1222 | } | ||
1223 | } | 1233 | } |
1224 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1234 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
1225 | 1235 | ||
@@ -1379,7 +1389,13 @@ static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | |||
1379 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | 1389 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) |
1380 | { | 1390 | { |
1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1391 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1392 | struct radeon_encoder_atom_dig *dig; | ||
1382 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 1393 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1394 | |||
1395 | if (radeon_encoder_is_digital(encoder)) { | ||
1396 | dig = radeon_encoder->enc_priv; | ||
1397 | dig->dig_encoder = -1; | ||
1398 | } | ||
1383 | radeon_encoder->active_device = 0; | 1399 | radeon_encoder->active_device = 0; |
1384 | } | 1400 | } |
1385 | 1401 | ||
@@ -1436,6 +1452,7 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | |||
1436 | 1452 | ||
1437 | /* coherent mode by default */ | 1453 | /* coherent mode by default */ |
1438 | dig->coherent_mode = true; | 1454 | dig->coherent_mode = true; |
1455 | dig->dig_encoder = -1; | ||
1439 | 1456 | ||
1440 | return dig; | 1457 | return dig; |
1441 | } | 1458 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 3ba213d1b06c..d71e346e9ab5 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -248,7 +248,7 @@ int radeonfb_create(struct drm_device *dev, | |||
248 | if (ret) | 248 | if (ret) |
249 | goto out_unref; | 249 | goto out_unref; |
250 | 250 | ||
251 | memset_io(fbptr, 0xff, aligned_size); | 251 | memset_io(fbptr, 0x0, aligned_size); |
252 | 252 | ||
253 | strcpy(info->fix.id, "radeondrmfb"); | 253 | strcpy(info->fix.id, "radeondrmfb"); |
254 | 254 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 0e1325e18534..db8e9a355a01 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -308,6 +308,9 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
308 | } | 308 | } |
309 | robj = gobj->driver_private; | 309 | robj = gobj->driver_private; |
310 | r = radeon_bo_wait(robj, NULL, false); | 310 | r = radeon_bo_wait(robj, NULL, false); |
311 | /* callback hw specific functions if any */ | ||
312 | if (robj->rdev->asic->ioctl_wait_idle) | ||
313 | robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); | ||
311 | mutex_lock(&dev->struct_mutex); | 314 | mutex_lock(&dev->struct_mutex); |
312 | drm_gem_object_unreference(gobj); | 315 | drm_gem_object_unreference(gobj); |
313 | mutex_unlock(&dev->struct_mutex); | 316 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 96b851f92f4c..e81b2aeb6a8f 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -299,7 +299,7 @@ struct radeon_atom_ss { | |||
299 | struct radeon_encoder_atom_dig { | 299 | struct radeon_encoder_atom_dig { |
300 | /* atom dig */ | 300 | /* atom dig */ |
301 | bool coherent_mode; | 301 | bool coherent_mode; |
302 | int dig_block; | 302 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ |
303 | /* atom lvds */ | 303 | /* atom lvds */ |
304 | uint32_t lvds_misc; | 304 | uint32_t lvds_misc; |
305 | uint16_t panel_pwr_delay; | 305 | uint16_t panel_pwr_delay; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index d72a71bff218..f1da370928eb 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -306,11 +306,10 @@ void radeon_bo_list_unreserve(struct list_head *head) | |||
306 | } | 306 | } |
307 | } | 307 | } |
308 | 308 | ||
309 | int radeon_bo_list_validate(struct list_head *head, void *fence) | 309 | int radeon_bo_list_validate(struct list_head *head) |
310 | { | 310 | { |
311 | struct radeon_bo_list *lobj; | 311 | struct radeon_bo_list *lobj; |
312 | struct radeon_bo *bo; | 312 | struct radeon_bo *bo; |
313 | struct radeon_fence *old_fence = NULL; | ||
314 | int r; | 313 | int r; |
315 | 314 | ||
316 | r = radeon_bo_list_reserve(head); | 315 | r = radeon_bo_list_reserve(head); |
@@ -334,32 +333,27 @@ int radeon_bo_list_validate(struct list_head *head, void *fence) | |||
334 | } | 333 | } |
335 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); | 334 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); |
336 | lobj->tiling_flags = bo->tiling_flags; | 335 | lobj->tiling_flags = bo->tiling_flags; |
337 | if (fence) { | ||
338 | old_fence = (struct radeon_fence *)bo->tbo.sync_obj; | ||
339 | bo->tbo.sync_obj = radeon_fence_ref(fence); | ||
340 | bo->tbo.sync_obj_arg = NULL; | ||
341 | } | ||
342 | if (old_fence) { | ||
343 | radeon_fence_unref(&old_fence); | ||
344 | } | ||
345 | } | 336 | } |
346 | return 0; | 337 | return 0; |
347 | } | 338 | } |
348 | 339 | ||
349 | void radeon_bo_list_unvalidate(struct list_head *head, void *fence) | 340 | void radeon_bo_list_fence(struct list_head *head, void *fence) |
350 | { | 341 | { |
351 | struct radeon_bo_list *lobj; | 342 | struct radeon_bo_list *lobj; |
352 | struct radeon_fence *old_fence; | 343 | struct radeon_bo *bo; |
353 | 344 | struct radeon_fence *old_fence = NULL; | |
354 | if (fence) | 345 | |
355 | list_for_each_entry(lobj, head, list) { | 346 | list_for_each_entry(lobj, head, list) { |
356 | old_fence = to_radeon_fence(lobj->bo->tbo.sync_obj); | 347 | bo = lobj->bo; |
357 | if (old_fence == fence) { | 348 | spin_lock(&bo->tbo.lock); |
358 | lobj->bo->tbo.sync_obj = NULL; | 349 | old_fence = (struct radeon_fence *)bo->tbo.sync_obj; |
359 | radeon_fence_unref(&old_fence); | 350 | bo->tbo.sync_obj = radeon_fence_ref(fence); |
360 | } | 351 | bo->tbo.sync_obj_arg = NULL; |
352 | spin_unlock(&bo->tbo.lock); | ||
353 | if (old_fence) { | ||
354 | radeon_fence_unref(&old_fence); | ||
361 | } | 355 | } |
362 | radeon_bo_list_unreserve(head); | 356 | } |
363 | } | 357 | } |
364 | 358 | ||
365 | int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | 359 | int radeon_bo_fbdev_mmap(struct radeon_bo *bo, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index a02f18011ad1..7ab43de1e244 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -156,8 +156,8 @@ extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj, | |||
156 | struct list_head *head); | 156 | struct list_head *head); |
157 | extern int radeon_bo_list_reserve(struct list_head *head); | 157 | extern int radeon_bo_list_reserve(struct list_head *head); |
158 | extern void radeon_bo_list_unreserve(struct list_head *head); | 158 | extern void radeon_bo_list_unreserve(struct list_head *head); |
159 | extern int radeon_bo_list_validate(struct list_head *head, void *fence); | 159 | extern int radeon_bo_list_validate(struct list_head *head); |
160 | extern void radeon_bo_list_unvalidate(struct list_head *head, void *fence); | 160 | extern void radeon_bo_list_fence(struct list_head *head, void *fence); |
161 | extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | 161 | extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, |
162 | struct vm_area_struct *vma); | 162 | struct vm_area_struct *vma); |
163 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, | 163 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 4d12b2d17b4d..6579eb4c1f28 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -41,68 +41,55 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib) | |||
41 | { | 41 | { |
42 | struct radeon_fence *fence; | 42 | struct radeon_fence *fence; |
43 | struct radeon_ib *nib; | 43 | struct radeon_ib *nib; |
44 | unsigned long i; | 44 | int r = 0, i, c; |
45 | int r = 0; | ||
46 | 45 | ||
47 | *ib = NULL; | 46 | *ib = NULL; |
48 | r = radeon_fence_create(rdev, &fence); | 47 | r = radeon_fence_create(rdev, &fence); |
49 | if (r) { | 48 | if (r) { |
50 | DRM_ERROR("failed to create fence for new IB\n"); | 49 | dev_err(rdev->dev, "failed to create fence for new IB\n"); |
51 | return r; | 50 | return r; |
52 | } | 51 | } |
53 | mutex_lock(&rdev->ib_pool.mutex); | 52 | mutex_lock(&rdev->ib_pool.mutex); |
54 | i = find_first_zero_bit(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); | 53 | for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) { |
55 | if (i < RADEON_IB_POOL_SIZE) { | 54 | i &= (RADEON_IB_POOL_SIZE - 1); |
56 | set_bit(i, rdev->ib_pool.alloc_bm); | 55 | if (rdev->ib_pool.ibs[i].free) { |
57 | rdev->ib_pool.ibs[i].length_dw = 0; | 56 | nib = &rdev->ib_pool.ibs[i]; |
58 | *ib = &rdev->ib_pool.ibs[i]; | 57 | break; |
59 | mutex_unlock(&rdev->ib_pool.mutex); | 58 | } |
60 | goto out; | ||
61 | } | 59 | } |
62 | if (list_empty(&rdev->ib_pool.scheduled_ibs)) { | 60 | if (nib == NULL) { |
63 | /* we go do nothings here */ | 61 | /* This should never happen, it means we allocated all |
62 | * IB and haven't scheduled one yet, return EBUSY to | ||
63 | * userspace hoping that on ioctl recall we get better | ||
64 | * luck | ||
65 | */ | ||
66 | dev_err(rdev->dev, "no free indirect buffer !\n"); | ||
64 | mutex_unlock(&rdev->ib_pool.mutex); | 67 | mutex_unlock(&rdev->ib_pool.mutex); |
65 | DRM_ERROR("all IB allocated none scheduled.\n"); | 68 | radeon_fence_unref(&fence); |
66 | r = -EINVAL; | 69 | return -EBUSY; |
67 | goto out; | ||
68 | } | 70 | } |
69 | /* get the first ib on the scheduled list */ | 71 | rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1); |
70 | nib = list_entry(rdev->ib_pool.scheduled_ibs.next, | 72 | nib->free = false; |
71 | struct radeon_ib, list); | 73 | if (nib->fence) { |
72 | if (nib->fence == NULL) { | ||
73 | /* we go do nothings here */ | ||
74 | mutex_unlock(&rdev->ib_pool.mutex); | 74 | mutex_unlock(&rdev->ib_pool.mutex); |
75 | DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx); | 75 | r = radeon_fence_wait(nib->fence, false); |
76 | r = -EINVAL; | 76 | if (r) { |
77 | goto out; | 77 | dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n", |
78 | } | 78 | nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw); |
79 | mutex_unlock(&rdev->ib_pool.mutex); | 79 | mutex_lock(&rdev->ib_pool.mutex); |
80 | 80 | nib->free = true; | |
81 | r = radeon_fence_wait(nib->fence, false); | 81 | mutex_unlock(&rdev->ib_pool.mutex); |
82 | if (r) { | 82 | radeon_fence_unref(&fence); |
83 | DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx, | 83 | return r; |
84 | (unsigned long)nib->gpu_addr, nib->length_dw); | 84 | } |
85 | DRM_ERROR("radeon: GPU lockup detected, fail to get a IB\n"); | 85 | mutex_lock(&rdev->ib_pool.mutex); |
86 | goto out; | ||
87 | } | 86 | } |
88 | radeon_fence_unref(&nib->fence); | 87 | radeon_fence_unref(&nib->fence); |
89 | 88 | nib->fence = fence; | |
90 | nib->length_dw = 0; | 89 | nib->length_dw = 0; |
91 | |||
92 | /* scheduled list is accessed here */ | ||
93 | mutex_lock(&rdev->ib_pool.mutex); | ||
94 | list_del(&nib->list); | ||
95 | INIT_LIST_HEAD(&nib->list); | ||
96 | mutex_unlock(&rdev->ib_pool.mutex); | 90 | mutex_unlock(&rdev->ib_pool.mutex); |
97 | |||
98 | *ib = nib; | 91 | *ib = nib; |
99 | out: | 92 | return 0; |
100 | if (r) { | ||
101 | radeon_fence_unref(&fence); | ||
102 | } else { | ||
103 | (*ib)->fence = fence; | ||
104 | } | ||
105 | return r; | ||
106 | } | 93 | } |
107 | 94 | ||
108 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | 95 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) |
@@ -113,19 +100,10 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | |||
113 | if (tmp == NULL) { | 100 | if (tmp == NULL) { |
114 | return; | 101 | return; |
115 | } | 102 | } |
116 | mutex_lock(&rdev->ib_pool.mutex); | 103 | if (!tmp->fence->emited) |
117 | if (!list_empty(&tmp->list) && !radeon_fence_signaled(tmp->fence)) { | ||
118 | /* IB is scheduled & not signaled don't do anythings */ | ||
119 | mutex_unlock(&rdev->ib_pool.mutex); | ||
120 | return; | ||
121 | } | ||
122 | list_del(&tmp->list); | ||
123 | INIT_LIST_HEAD(&tmp->list); | ||
124 | if (tmp->fence) | ||
125 | radeon_fence_unref(&tmp->fence); | 104 | radeon_fence_unref(&tmp->fence); |
126 | 105 | mutex_lock(&rdev->ib_pool.mutex); | |
127 | tmp->length_dw = 0; | 106 | tmp->free = true; |
128 | clear_bit(tmp->idx, rdev->ib_pool.alloc_bm); | ||
129 | mutex_unlock(&rdev->ib_pool.mutex); | 107 | mutex_unlock(&rdev->ib_pool.mutex); |
130 | } | 108 | } |
131 | 109 | ||
@@ -135,7 +113,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | |||
135 | 113 | ||
136 | if (!ib->length_dw || !rdev->cp.ready) { | 114 | if (!ib->length_dw || !rdev->cp.ready) { |
137 | /* TODO: Nothings in the ib we should report. */ | 115 | /* TODO: Nothings in the ib we should report. */ |
138 | DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx); | 116 | DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); |
139 | return -EINVAL; | 117 | return -EINVAL; |
140 | } | 118 | } |
141 | 119 | ||
@@ -148,7 +126,8 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | |||
148 | radeon_ring_ib_execute(rdev, ib); | 126 | radeon_ring_ib_execute(rdev, ib); |
149 | radeon_fence_emit(rdev, ib->fence); | 127 | radeon_fence_emit(rdev, ib->fence); |
150 | mutex_lock(&rdev->ib_pool.mutex); | 128 | mutex_lock(&rdev->ib_pool.mutex); |
151 | list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs); | 129 | /* once scheduled IB is considered free and protected by the fence */ |
130 | ib->free = true; | ||
152 | mutex_unlock(&rdev->ib_pool.mutex); | 131 | mutex_unlock(&rdev->ib_pool.mutex); |
153 | radeon_ring_unlock_commit(rdev); | 132 | radeon_ring_unlock_commit(rdev); |
154 | return 0; | 133 | return 0; |
@@ -164,7 +143,6 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
164 | if (rdev->ib_pool.robj) | 143 | if (rdev->ib_pool.robj) |
165 | return 0; | 144 | return 0; |
166 | /* Allocate 1M object buffer */ | 145 | /* Allocate 1M object buffer */ |
167 | INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs); | ||
168 | r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, | 146 | r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, |
169 | true, RADEON_GEM_DOMAIN_GTT, | 147 | true, RADEON_GEM_DOMAIN_GTT, |
170 | &rdev->ib_pool.robj); | 148 | &rdev->ib_pool.robj); |
@@ -195,9 +173,9 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
195 | rdev->ib_pool.ibs[i].ptr = ptr + offset; | 173 | rdev->ib_pool.ibs[i].ptr = ptr + offset; |
196 | rdev->ib_pool.ibs[i].idx = i; | 174 | rdev->ib_pool.ibs[i].idx = i; |
197 | rdev->ib_pool.ibs[i].length_dw = 0; | 175 | rdev->ib_pool.ibs[i].length_dw = 0; |
198 | INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].list); | 176 | rdev->ib_pool.ibs[i].free = true; |
199 | } | 177 | } |
200 | bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); | 178 | rdev->ib_pool.head_id = 0; |
201 | rdev->ib_pool.ready = true; | 179 | rdev->ib_pool.ready = true; |
202 | DRM_INFO("radeon: ib pool ready.\n"); | 180 | DRM_INFO("radeon: ib pool ready.\n"); |
203 | if (radeon_debugfs_ib_init(rdev)) { | 181 | if (radeon_debugfs_ib_init(rdev)) { |
@@ -214,7 +192,6 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
214 | return; | 192 | return; |
215 | } | 193 | } |
216 | mutex_lock(&rdev->ib_pool.mutex); | 194 | mutex_lock(&rdev->ib_pool.mutex); |
217 | bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); | ||
218 | if (rdev->ib_pool.robj) { | 195 | if (rdev->ib_pool.robj) { |
219 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); | 196 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); |
220 | if (likely(r == 0)) { | 197 | if (likely(r == 0)) { |
@@ -363,7 +340,7 @@ static int radeon_debugfs_ib_info(struct seq_file *m, void *data) | |||
363 | if (ib == NULL) { | 340 | if (ib == NULL) { |
364 | return 0; | 341 | return 0; |
365 | } | 342 | } |
366 | seq_printf(m, "IB %04lu\n", ib->idx); | 343 | seq_printf(m, "IB %04u\n", ib->idx); |
367 | seq_printf(m, "IB fence %p\n", ib->fence); | 344 | seq_printf(m, "IB fence %p\n", ib->fence); |
368 | seq_printf(m, "IB size %05u dwords\n", ib->length_dw); | 345 | seq_printf(m, "IB size %05u dwords\n", ib->length_dw); |
369 | for (i = 0; i < ib->length_dw; i++) { | 346 | for (i = 0; i < ib->length_dw; i++) { |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 9f5418983e2a..287fcebfb4e6 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -223,15 +223,31 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | int rs400_mc_wait_for_idle(struct radeon_device *rdev) | ||
227 | { | ||
228 | unsigned i; | ||
229 | uint32_t tmp; | ||
230 | |||
231 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
232 | /* read MC_STATUS */ | ||
233 | tmp = RREG32(0x0150); | ||
234 | if (tmp & (1 << 2)) { | ||
235 | return 0; | ||
236 | } | ||
237 | DRM_UDELAY(1); | ||
238 | } | ||
239 | return -1; | ||
240 | } | ||
241 | |||
226 | void rs400_gpu_init(struct radeon_device *rdev) | 242 | void rs400_gpu_init(struct radeon_device *rdev) |
227 | { | 243 | { |
228 | /* FIXME: HDP same place on rs400 ? */ | 244 | /* FIXME: HDP same place on rs400 ? */ |
229 | r100_hdp_reset(rdev); | 245 | r100_hdp_reset(rdev); |
230 | /* FIXME: is this correct ? */ | 246 | /* FIXME: is this correct ? */ |
231 | r420_pipes_init(rdev); | 247 | r420_pipes_init(rdev); |
232 | if (r300_mc_wait_for_idle(rdev)) { | 248 | if (rs400_mc_wait_for_idle(rdev)) { |
233 | printk(KERN_WARNING "Failed to wait MC idle while " | 249 | printk(KERN_WARNING "rs400: Failed to wait MC idle while " |
234 | "programming pipes. Bad things might happen.\n"); | 250 | "programming pipes. Bad things might happen. %08x\n", RREG32(0x150)); |
235 | } | 251 | } |
236 | } | 252 | } |
237 | 253 | ||
@@ -370,8 +386,8 @@ void rs400_mc_program(struct radeon_device *rdev) | |||
370 | r100_mc_stop(rdev, &save); | 386 | r100_mc_stop(rdev, &save); |
371 | 387 | ||
372 | /* Wait for mc idle */ | 388 | /* Wait for mc idle */ |
373 | if (r300_mc_wait_for_idle(rdev)) | 389 | if (rs400_mc_wait_for_idle(rdev)) |
374 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); | 390 | dev_warn(rdev->dev, "rs400: Wait MC idle timeout before updating MC.\n"); |
375 | WREG32(R_000148_MC_FB_LOCATION, | 391 | WREG32(R_000148_MC_FB_LOCATION, |
376 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | | 392 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | |
377 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); | 393 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); |
@@ -448,7 +464,6 @@ int rs400_suspend(struct radeon_device *rdev) | |||
448 | 464 | ||
449 | void rs400_fini(struct radeon_device *rdev) | 465 | void rs400_fini(struct radeon_device *rdev) |
450 | { | 466 | { |
451 | rs400_suspend(rdev); | ||
452 | r100_cp_fini(rdev); | 467 | r100_cp_fini(rdev); |
453 | r100_wb_fini(rdev); | 468 | r100_wb_fini(rdev); |
454 | r100_ib_fini(rdev); | 469 | r100_ib_fini(rdev); |
@@ -527,7 +542,6 @@ int rs400_init(struct radeon_device *rdev) | |||
527 | if (r) { | 542 | if (r) { |
528 | /* Somethings want wront with the accel init stop accel */ | 543 | /* Somethings want wront with the accel init stop accel */ |
529 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 544 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
530 | rs400_suspend(rdev); | ||
531 | r100_cp_fini(rdev); | 545 | r100_cp_fini(rdev); |
532 | r100_wb_fini(rdev); | 546 | r100_wb_fini(rdev); |
533 | r100_ib_fini(rdev); | 547 | r100_ib_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index d5255751e7b3..c3818562a13e 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -610,7 +610,6 @@ int rs600_suspend(struct radeon_device *rdev) | |||
610 | 610 | ||
611 | void rs600_fini(struct radeon_device *rdev) | 611 | void rs600_fini(struct radeon_device *rdev) |
612 | { | 612 | { |
613 | rs600_suspend(rdev); | ||
614 | r100_cp_fini(rdev); | 613 | r100_cp_fini(rdev); |
615 | r100_wb_fini(rdev); | 614 | r100_wb_fini(rdev); |
616 | r100_ib_fini(rdev); | 615 | r100_ib_fini(rdev); |
@@ -689,7 +688,6 @@ int rs600_init(struct radeon_device *rdev) | |||
689 | if (r) { | 688 | if (r) { |
690 | /* Somethings want wront with the accel init stop accel */ | 689 | /* Somethings want wront with the accel init stop accel */ |
691 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 690 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
692 | rs600_suspend(rdev); | ||
693 | r100_cp_fini(rdev); | 691 | r100_cp_fini(rdev); |
694 | r100_wb_fini(rdev); | 692 | r100_wb_fini(rdev); |
695 | r100_ib_fini(rdev); | 693 | r100_ib_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index cd31da913771..06e2771aee5a 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -676,7 +676,6 @@ int rs690_suspend(struct radeon_device *rdev) | |||
676 | 676 | ||
677 | void rs690_fini(struct radeon_device *rdev) | 677 | void rs690_fini(struct radeon_device *rdev) |
678 | { | 678 | { |
679 | rs690_suspend(rdev); | ||
680 | r100_cp_fini(rdev); | 679 | r100_cp_fini(rdev); |
681 | r100_wb_fini(rdev); | 680 | r100_wb_fini(rdev); |
682 | r100_ib_fini(rdev); | 681 | r100_ib_fini(rdev); |
@@ -756,7 +755,6 @@ int rs690_init(struct radeon_device *rdev) | |||
756 | if (r) { | 755 | if (r) { |
757 | /* Somethings want wront with the accel init stop accel */ | 756 | /* Somethings want wront with the accel init stop accel */ |
758 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 757 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
759 | rs690_suspend(rdev); | ||
760 | r100_cp_fini(rdev); | 758 | r100_cp_fini(rdev); |
761 | r100_wb_fini(rdev); | 759 | r100_wb_fini(rdev); |
762 | r100_ib_fini(rdev); | 760 | r100_ib_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 62756717b044..0e1e6b8632b8 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -537,7 +537,6 @@ void rv515_set_safe_registers(struct radeon_device *rdev) | |||
537 | 537 | ||
538 | void rv515_fini(struct radeon_device *rdev) | 538 | void rv515_fini(struct radeon_device *rdev) |
539 | { | 539 | { |
540 | rv515_suspend(rdev); | ||
541 | r100_cp_fini(rdev); | 540 | r100_cp_fini(rdev); |
542 | r100_wb_fini(rdev); | 541 | r100_wb_fini(rdev); |
543 | r100_ib_fini(rdev); | 542 | r100_ib_fini(rdev); |
@@ -615,13 +614,12 @@ int rv515_init(struct radeon_device *rdev) | |||
615 | if (r) { | 614 | if (r) { |
616 | /* Somethings want wront with the accel init stop accel */ | 615 | /* Somethings want wront with the accel init stop accel */ |
617 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 616 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
618 | rv515_suspend(rdev); | ||
619 | r100_cp_fini(rdev); | 617 | r100_cp_fini(rdev); |
620 | r100_wb_fini(rdev); | 618 | r100_wb_fini(rdev); |
621 | r100_ib_fini(rdev); | 619 | r100_ib_fini(rdev); |
620 | radeon_irq_kms_fini(rdev); | ||
622 | rv370_pcie_gart_fini(rdev); | 621 | rv370_pcie_gart_fini(rdev); |
623 | radeon_agp_fini(rdev); | 622 | radeon_agp_fini(rdev); |
624 | radeon_irq_kms_fini(rdev); | ||
625 | rdev->accel_working = false; | 623 | rdev->accel_working = false; |
626 | } | 624 | } |
627 | return 0; | 625 | return 0; |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 55f6ffc4e58b..03021674d097 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -549,9 +549,12 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
549 | 549 | ||
550 | gb_tiling_config |= BANK_SWAPS(1); | 550 | gb_tiling_config |= BANK_SWAPS(1); |
551 | 551 | ||
552 | backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes, | 552 | if (rdev->family == CHIP_RV740) |
553 | rdev->config.rv770.max_backends, | 553 | backend_map = 0x28; |
554 | (0xff << rdev->config.rv770.max_backends) & 0xff); | 554 | else |
555 | backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes, | ||
556 | rdev->config.rv770.max_backends, | ||
557 | (0xff << rdev->config.rv770.max_backends) & 0xff); | ||
555 | gb_tiling_config |= BACKEND_MAP(backend_map); | 558 | gb_tiling_config |= BACKEND_MAP(backend_map); |
556 | 559 | ||
557 | cc_gc_shader_pipe_config = | 560 | cc_gc_shader_pipe_config = |
@@ -887,26 +890,25 @@ static int rv770_startup(struct radeon_device *rdev) | |||
887 | return r; | 890 | return r; |
888 | } | 891 | } |
889 | rv770_gpu_init(rdev); | 892 | rv770_gpu_init(rdev); |
890 | 893 | r = r600_blit_init(rdev); | |
891 | if (!rdev->r600_blit.shader_obj) { | 894 | if (r) { |
892 | r = r600_blit_init(rdev); | 895 | r600_blit_fini(rdev); |
896 | rdev->asic->copy = NULL; | ||
897 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
898 | } | ||
899 | /* pin copy shader into vram */ | ||
900 | if (rdev->r600_blit.shader_obj) { | ||
901 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
902 | if (unlikely(r != 0)) | ||
903 | return r; | ||
904 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
905 | &rdev->r600_blit.shader_gpu_addr); | ||
906 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
893 | if (r) { | 907 | if (r) { |
894 | DRM_ERROR("radeon: failed blitter (%d).\n", r); | 908 | DRM_ERROR("failed to pin blit object %d\n", r); |
895 | return r; | 909 | return r; |
896 | } | 910 | } |
897 | } | 911 | } |
898 | |||
899 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
900 | if (unlikely(r != 0)) | ||
901 | return r; | ||
902 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
903 | &rdev->r600_blit.shader_gpu_addr); | ||
904 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
905 | if (r) { | ||
906 | DRM_ERROR("failed to pin blit object %d\n", r); | ||
907 | return r; | ||
908 | } | ||
909 | |||
910 | /* Enable IRQ */ | 912 | /* Enable IRQ */ |
911 | r = r600_irq_init(rdev); | 913 | r = r600_irq_init(rdev); |
912 | if (r) { | 914 | if (r) { |
@@ -1066,9 +1068,11 @@ int rv770_init(struct radeon_device *rdev) | |||
1066 | rdev->accel_working = true; | 1068 | rdev->accel_working = true; |
1067 | r = rv770_startup(rdev); | 1069 | r = rv770_startup(rdev); |
1068 | if (r) { | 1070 | if (r) { |
1069 | rv770_suspend(rdev); | 1071 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
1072 | r600_cp_fini(rdev); | ||
1070 | r600_wb_fini(rdev); | 1073 | r600_wb_fini(rdev); |
1071 | radeon_ring_fini(rdev); | 1074 | r600_irq_fini(rdev); |
1075 | radeon_irq_kms_fini(rdev); | ||
1072 | rv770_pcie_gart_fini(rdev); | 1076 | rv770_pcie_gart_fini(rdev); |
1073 | rdev->accel_working = false; | 1077 | rdev->accel_working = false; |
1074 | } | 1078 | } |
@@ -1090,13 +1094,11 @@ int rv770_init(struct radeon_device *rdev) | |||
1090 | 1094 | ||
1091 | void rv770_fini(struct radeon_device *rdev) | 1095 | void rv770_fini(struct radeon_device *rdev) |
1092 | { | 1096 | { |
1093 | rv770_suspend(rdev); | ||
1094 | |||
1095 | r600_blit_fini(rdev); | 1097 | r600_blit_fini(rdev); |
1098 | r600_cp_fini(rdev); | ||
1099 | r600_wb_fini(rdev); | ||
1096 | r600_irq_fini(rdev); | 1100 | r600_irq_fini(rdev); |
1097 | radeon_irq_kms_fini(rdev); | 1101 | radeon_irq_kms_fini(rdev); |
1098 | radeon_ring_fini(rdev); | ||
1099 | r600_wb_fini(rdev); | ||
1100 | rv770_pcie_gart_fini(rdev); | 1102 | rv770_pcie_gart_fini(rdev); |
1101 | radeon_gem_fini(rdev); | 1103 | radeon_gem_fini(rdev); |
1102 | radeon_fence_driver_fini(rdev); | 1104 | radeon_fence_driver_fini(rdev); |