diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/rv770.c')
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4dfead8cee33..645aa1fd7611 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -42,6 +42,40 @@ | |||
42 | static void rv770_gpu_init(struct radeon_device *rdev); | 42 | static void rv770_gpu_init(struct radeon_device *rdev); |
43 | void rv770_fini(struct radeon_device *rdev); | 43 | void rv770_fini(struct radeon_device *rdev); |
44 | 44 | ||
45 | u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | ||
46 | { | ||
47 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
48 | u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); | ||
49 | |||
50 | /* Lock the graphics update lock */ | ||
51 | tmp |= AVIVO_D1GRPH_UPDATE_LOCK; | ||
52 | WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
53 | |||
54 | /* update the scanout addresses */ | ||
55 | if (radeon_crtc->crtc_id) { | ||
56 | WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
57 | WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
58 | } else { | ||
59 | WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
60 | WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
61 | } | ||
62 | WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
63 | (u32)crtc_base); | ||
64 | WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
65 | (u32)crtc_base); | ||
66 | |||
67 | /* Wait for update_pending to go high. */ | ||
68 | while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); | ||
69 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | ||
70 | |||
71 | /* Unlock the lock, so double-buffering can take place inside vblank */ | ||
72 | tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; | ||
73 | WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
74 | |||
75 | /* Return current update_pending status: */ | ||
76 | return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; | ||
77 | } | ||
78 | |||
45 | /* get temperature in millidegrees */ | 79 | /* get temperature in millidegrees */ |
46 | u32 rv770_get_temp(struct radeon_device *rdev) | 80 | u32 rv770_get_temp(struct radeon_device *rdev) |
47 | { | 81 | { |
@@ -489,6 +523,49 @@ static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev, | |||
489 | return backend_map; | 523 | return backend_map; |
490 | } | 524 | } |
491 | 525 | ||
526 | static void rv770_program_channel_remap(struct radeon_device *rdev) | ||
527 | { | ||
528 | u32 tcp_chan_steer, mc_shared_chremap, tmp; | ||
529 | bool force_no_swizzle; | ||
530 | |||
531 | switch (rdev->family) { | ||
532 | case CHIP_RV770: | ||
533 | case CHIP_RV730: | ||
534 | force_no_swizzle = false; | ||
535 | break; | ||
536 | case CHIP_RV710: | ||
537 | case CHIP_RV740: | ||
538 | default: | ||
539 | force_no_swizzle = true; | ||
540 | break; | ||
541 | } | ||
542 | |||
543 | tmp = RREG32(MC_SHARED_CHMAP); | ||
544 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
545 | case 0: | ||
546 | case 1: | ||
547 | default: | ||
548 | /* default mapping */ | ||
549 | mc_shared_chremap = 0x00fac688; | ||
550 | break; | ||
551 | case 2: | ||
552 | case 3: | ||
553 | if (force_no_swizzle) | ||
554 | mc_shared_chremap = 0x00fac688; | ||
555 | else | ||
556 | mc_shared_chremap = 0x00bbc298; | ||
557 | break; | ||
558 | } | ||
559 | |||
560 | if (rdev->family == CHIP_RV740) | ||
561 | tcp_chan_steer = 0x00ef2a60; | ||
562 | else | ||
563 | tcp_chan_steer = 0x00fac688; | ||
564 | |||
565 | WREG32(TCP_CHAN_STEER, tcp_chan_steer); | ||
566 | WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); | ||
567 | } | ||
568 | |||
492 | static void rv770_gpu_init(struct radeon_device *rdev) | 569 | static void rv770_gpu_init(struct radeon_device *rdev) |
493 | { | 570 | { |
494 | int i, j, num_qd_pipes; | 571 | int i, j, num_qd_pipes; |
@@ -688,6 +765,8 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
688 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | 765 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); |
689 | WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | 766 | WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); |
690 | 767 | ||
768 | rv770_program_channel_remap(rdev); | ||
769 | |||
691 | WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); | 770 | WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); |
692 | WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); | 771 | WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); |
693 | WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); | 772 | WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); |
@@ -956,6 +1035,45 @@ static void rv770_vram_scratch_fini(struct radeon_device *rdev) | |||
956 | radeon_bo_unref(&rdev->vram_scratch.robj); | 1035 | radeon_bo_unref(&rdev->vram_scratch.robj); |
957 | } | 1036 | } |
958 | 1037 | ||
1038 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | ||
1039 | { | ||
1040 | u64 size_bf, size_af; | ||
1041 | |||
1042 | if (mc->mc_vram_size > 0xE0000000) { | ||
1043 | /* leave room for at least 512M GTT */ | ||
1044 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
1045 | mc->real_vram_size = 0xE0000000; | ||
1046 | mc->mc_vram_size = 0xE0000000; | ||
1047 | } | ||
1048 | if (rdev->flags & RADEON_IS_AGP) { | ||
1049 | size_bf = mc->gtt_start; | ||
1050 | size_af = 0xFFFFFFFF - mc->gtt_end + 1; | ||
1051 | if (size_bf > size_af) { | ||
1052 | if (mc->mc_vram_size > size_bf) { | ||
1053 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
1054 | mc->real_vram_size = size_bf; | ||
1055 | mc->mc_vram_size = size_bf; | ||
1056 | } | ||
1057 | mc->vram_start = mc->gtt_start - mc->mc_vram_size; | ||
1058 | } else { | ||
1059 | if (mc->mc_vram_size > size_af) { | ||
1060 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
1061 | mc->real_vram_size = size_af; | ||
1062 | mc->mc_vram_size = size_af; | ||
1063 | } | ||
1064 | mc->vram_start = mc->gtt_end; | ||
1065 | } | ||
1066 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | ||
1067 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | ||
1068 | mc->mc_vram_size >> 20, mc->vram_start, | ||
1069 | mc->vram_end, mc->real_vram_size >> 20); | ||
1070 | } else { | ||
1071 | radeon_vram_location(rdev, &rdev->mc, 0); | ||
1072 | rdev->mc.gtt_base_align = 0; | ||
1073 | radeon_gtt_location(rdev, mc); | ||
1074 | } | ||
1075 | } | ||
1076 | |||
959 | int rv770_mc_init(struct radeon_device *rdev) | 1077 | int rv770_mc_init(struct radeon_device *rdev) |
960 | { | 1078 | { |
961 | u32 tmp; | 1079 | u32 tmp; |
@@ -996,7 +1114,7 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
996 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 1114 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
997 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 1115 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
998 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 1116 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; |
999 | r600_vram_gtt_location(rdev, &rdev->mc); | 1117 | r700_vram_gtt_location(rdev, &rdev->mc); |
1000 | radeon_update_bandwidth_info(rdev); | 1118 | radeon_update_bandwidth_info(rdev); |
1001 | 1119 | ||
1002 | return 0; | 1120 | return 0; |